Saurav Das
Committed by Gerrit Code Review

Adding Device Listiner to BgpRouter so that filtering rules are sent to the

driver only after the device is available.

Change-Id: I377402b87cee6c02c087efbcc4f0cff4f19e1ca3
...@@ -20,6 +20,7 @@ import com.google.common.collect.HashMultimap; ...@@ -20,6 +20,7 @@ import com.google.common.collect.HashMultimap;
20 import com.google.common.collect.Maps; 20 import com.google.common.collect.Maps;
21 import com.google.common.collect.Multimap; 21 import com.google.common.collect.Multimap;
22 import com.google.common.collect.Multiset; 22 import com.google.common.collect.Multiset;
23 +
23 import org.apache.felix.scr.annotations.Activate; 24 import org.apache.felix.scr.annotations.Activate;
24 import org.apache.felix.scr.annotations.Component; 25 import org.apache.felix.scr.annotations.Component;
25 import org.apache.felix.scr.annotations.Deactivate; 26 import org.apache.felix.scr.annotations.Deactivate;
...@@ -28,18 +29,18 @@ import org.apache.felix.scr.annotations.ReferenceCardinality; ...@@ -28,18 +29,18 @@ import org.apache.felix.scr.annotations.ReferenceCardinality;
28 import org.onlab.packet.Ethernet; 29 import org.onlab.packet.Ethernet;
29 import org.onlab.packet.Ip4Address; 30 import org.onlab.packet.Ip4Address;
30 import org.onlab.packet.Ip4Prefix; 31 import org.onlab.packet.Ip4Prefix;
31 -import org.onlab.packet.Ip6Address;
32 import org.onlab.packet.IpAddress; 32 import org.onlab.packet.IpAddress;
33 import org.onlab.packet.IpPrefix; 33 import org.onlab.packet.IpPrefix;
34 import org.onlab.packet.MacAddress; 34 import org.onlab.packet.MacAddress;
35 -import org.onlab.util.KryoNamespace;
36 import org.onosproject.config.NetworkConfigService; 35 import org.onosproject.config.NetworkConfigService;
37 import org.onosproject.core.ApplicationId; 36 import org.onosproject.core.ApplicationId;
38 import org.onosproject.core.CoreService; 37 import org.onosproject.core.CoreService;
39 import org.onosproject.net.DeviceId; 38 import org.onosproject.net.DeviceId;
39 +import org.onosproject.net.device.DeviceEvent;
40 +import org.onosproject.net.device.DeviceListener;
41 +import org.onosproject.net.device.DeviceService;
40 import org.onosproject.net.flow.DefaultTrafficSelector; 42 import org.onosproject.net.flow.DefaultTrafficSelector;
41 import org.onosproject.net.flow.DefaultTrafficTreatment; 43 import org.onosproject.net.flow.DefaultTrafficTreatment;
42 -import org.onosproject.net.flow.FlowRuleService;
43 import org.onosproject.net.flow.TrafficSelector; 44 import org.onosproject.net.flow.TrafficSelector;
44 import org.onosproject.net.flow.TrafficTreatment; 45 import org.onosproject.net.flow.TrafficTreatment;
45 import org.onosproject.net.flow.criteria.Criteria; 46 import org.onosproject.net.flow.criteria.Criteria;
...@@ -50,7 +51,9 @@ import org.onosproject.net.flowobjective.FilteringObjective; ...@@ -50,7 +51,9 @@ import org.onosproject.net.flowobjective.FilteringObjective;
50 import org.onosproject.net.flowobjective.FlowObjectiveService; 51 import org.onosproject.net.flowobjective.FlowObjectiveService;
51 import org.onosproject.net.flowobjective.ForwardingObjective; 52 import org.onosproject.net.flowobjective.ForwardingObjective;
52 import org.onosproject.net.flowobjective.NextObjective; 53 import org.onosproject.net.flowobjective.NextObjective;
53 -import org.onosproject.net.group.GroupService; 54 +import org.onosproject.net.flowobjective.Objective;
55 +import org.onosproject.net.flowobjective.ObjectiveContext;
56 +import org.onosproject.net.flowobjective.ObjectiveError;
54 import org.onosproject.net.packet.PacketService; 57 import org.onosproject.net.packet.PacketService;
55 import org.onosproject.routing.FibEntry; 58 import org.onosproject.routing.FibEntry;
56 import org.onosproject.routing.FibListener; 59 import org.onosproject.routing.FibListener;
...@@ -87,19 +90,19 @@ public class BgpRouter { ...@@ -87,19 +90,19 @@ public class BgpRouter {
87 protected CoreService coreService; 90 protected CoreService coreService;
88 91
89 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) 92 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
90 - protected FlowRuleService flowService; 93 + protected RoutingService routingService;
91 94
92 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) 95 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
93 - protected GroupService groupService; 96 + protected RoutingConfigurationService configService;
94 97
95 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) 98 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
96 - protected RoutingService routingService; 99 + protected PacketService packetService;
97 100
98 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) 101 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
99 - protected RoutingConfigurationService configService; 102 + protected FlowObjectiveService flowObjectiveService;
100 103
101 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) 104 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
102 - protected PacketService packetService; 105 + protected DeviceService deviceService;
103 106
104 // 107 //
105 // NOTE: Unused reference - needed to guarantee that the 108 // NOTE: Unused reference - needed to guarantee that the
...@@ -130,57 +133,32 @@ public class BgpRouter { ...@@ -130,57 +133,32 @@ public class BgpRouter {
130 // learned from config 133 // learned from config
131 private DeviceId ctrlDeviceId; 134 private DeviceId ctrlDeviceId;
132 135
133 - //private final GroupListener groupListener = new InternalGroupListener(); 136 + // Responsible for handling BGP traffic (encapsulated within OF messages)
134 - 137 + // between the data-plane switch and the Quagga VM using a control plane OVS.
135 private TunnellingConnectivityManager connectivityManager; 138 private TunnellingConnectivityManager connectivityManager;
136 139
140 + private DeviceListener deviceListener;
137 private IcmpHandler icmpHandler; 141 private IcmpHandler icmpHandler;
138 142
139 - private KryoNamespace appKryo = new KryoNamespace.Builder()
140 - .register(IpAddress.Version.class)
141 - .register(IpAddress.class)
142 - .register(Ip4Address.class)
143 - .register(Ip6Address.class)
144 - .register(byte[].class)
145 - .register(NextHopGroupKey.class)
146 - .build();
147 -
148 -
149 - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
150 - protected FlowObjectiveService flowObjectiveService;
151 -
152 @Activate 143 @Activate
153 protected void activate() { 144 protected void activate() {
154 appId = coreService.registerApplication(BGP_ROUTER_APP); 145 appId = coreService.registerApplication(BGP_ROUTER_APP);
155 getDeviceConfiguration(configService.getBgpSpeakers()); 146 getDeviceConfiguration(configService.getBgpSpeakers());
156 147
157 - //groupService.addListener(groupListener);
158 -
159 - processIntfFilters(true, configService.getInterfaces());
160 -
161 connectivityManager = new TunnellingConnectivityManager(appId, 148 connectivityManager = new TunnellingConnectivityManager(appId,
162 configService, 149 configService,
163 packetService, 150 packetService,
164 flowObjectiveService); 151 flowObjectiveService);
165 152
166 icmpHandler = new IcmpHandler(configService, packetService); 153 icmpHandler = new IcmpHandler(configService, packetService);
167 - 154 + deviceListener = new InnerDeviceListener();
168 routingService.addFibListener(new InternalFibListener()); 155 routingService.addFibListener(new InternalFibListener());
169 routingService.start(); 156 routingService.start();
170 - 157 + deviceService.addListener(deviceListener);
171 connectivityManager.start(); 158 connectivityManager.start();
172 -
173 icmpHandler.start(); 159 icmpHandler.start();
174 160
175 log.info("BgpRouter started"); 161 log.info("BgpRouter started");
176 -
177 - delay(1000);
178 -
179 - FibEntry fibEntry = new FibEntry(Ip4Prefix.valueOf("10.1.0.0/16"),
180 - Ip4Address.valueOf("192.168.10.1"),
181 - MacAddress.valueOf("DE:AD:BE:EF:FE:ED"));
182 - FibUpdate fibUpdate = new FibUpdate(FibUpdate.Type.UPDATE, fibEntry);
183 - updateFibEntry(Collections.singletonList(fibUpdate));
184 } 162 }
185 163
186 @Deactivate 164 @Deactivate
...@@ -188,10 +166,8 @@ public class BgpRouter { ...@@ -188,10 +166,8 @@ public class BgpRouter {
188 routingService.stop(); 166 routingService.stop();
189 connectivityManager.stop(); 167 connectivityManager.stop();
190 icmpHandler.stop(); 168 icmpHandler.stop();
191 - processIntfFilters(false, configService.getInterfaces()); 169 + deviceService.removeListener(deviceListener);
192 - 170 + //processIntfFilters(false, configService.getInterfaces()); //TODO necessary?
193 - //groupService.removeListener(groupListener);
194 -
195 log.info("BgpRouter stopped"); 171 log.info("BgpRouter stopped");
196 } 172 }
197 173
...@@ -225,17 +201,6 @@ public class BgpRouter { ...@@ -225,17 +201,6 @@ public class BgpRouter {
225 Integer nextId; 201 Integer nextId;
226 synchronized (pendingUpdates) { 202 synchronized (pendingUpdates) {
227 nextId = nextHops.get(entry.nextHopIp()); 203 nextId = nextHops.get(entry.nextHopIp());
228 -
229 - /*
230 - group = groupService.getGroup(deviceId,
231 - new DefaultGroupKey(
232 - appKryo.serialize(nextHop.group())));
233 -
234 - if (group == null) {
235 - log.debug("Adding pending flow {}", update.entry());
236 - pendingUpdates.put(nextHop.group(), update.entry());
237 - continue;
238 - }*/
239 } 204 }
240 205
241 toInstall.put(update.entry(), nextId); 206 toInstall.put(update.entry(), nextId);
...@@ -251,7 +216,7 @@ public class BgpRouter { ...@@ -251,7 +216,7 @@ public class BgpRouter {
251 Integer nextId = entry.getValue(); 216 Integer nextId = entry.getValue();
252 217
253 flowObjectiveService.forward(deviceId, 218 flowObjectiveService.forward(deviceId,
254 - generateRibFlowRule(fibEntry.prefix(), nextId).add()); 219 + generateRibForwardingObj(fibEntry.prefix(), nextId).add());
255 log.trace("Sending forwarding objective {} -> nextId:{}", fibEntry, nextId); 220 log.trace("Sending forwarding objective {} -> nextId:{}", fibEntry, nextId);
256 } 221 }
257 222
...@@ -263,20 +228,21 @@ public class BgpRouter { ...@@ -263,20 +228,21 @@ public class BgpRouter {
263 FibEntry entry = update.entry(); 228 FibEntry entry = update.entry();
264 Integer nextId = nextHops.get(entry.nextHopIp()); 229 Integer nextId = nextHops.get(entry.nextHopIp());
265 230
266 - /*Group group = deleteNextHop(entry.prefix()); 231 + /* Group group = deleteNextHop(entry.prefix());
267 if (group == null) { 232 if (group == null) {
268 log.warn("Group not found when deleting {}", entry); 233 log.warn("Group not found when deleting {}", entry);
269 return; 234 return;
270 }*/ 235 }*/
271 236
272 flowObjectiveService.forward(deviceId, 237 flowObjectiveService.forward(deviceId,
273 - generateRibFlowRule(entry.prefix(), nextId).remove()); 238 + generateRibForwardingObj(entry.prefix(), nextId).remove());
274 239
275 } 240 }
276 241
277 } 242 }
278 243
279 - private ForwardingObjective.Builder generateRibFlowRule(IpPrefix prefix, Integer nextId) { 244 + private ForwardingObjective.Builder generateRibForwardingObj(IpPrefix prefix,
245 + Integer nextId) {
280 TrafficSelector selector = DefaultTrafficSelector.builder() 246 TrafficSelector selector = DefaultTrafficSelector.builder()
281 .matchEthType(Ethernet.TYPE_IPV4) 247 .matchEthType(Ethernet.TYPE_IPV4)
282 .matchIPDst(prefix) 248 .matchIPDst(prefix)
...@@ -293,8 +259,6 @@ public class BgpRouter { ...@@ -293,8 +259,6 @@ public class BgpRouter {
293 .withFlag(ForwardingObjective.Flag.SPECIFIC); 259 .withFlag(ForwardingObjective.Flag.SPECIFIC);
294 260
295 return fwdBuilder; 261 return fwdBuilder;
296 -
297 -
298 } 262 }
299 263
300 private synchronized void addNextHop(FibEntry entry) { 264 private synchronized void addNextHop(FibEntry entry) {
...@@ -328,24 +292,10 @@ public class BgpRouter { ...@@ -328,24 +292,10 @@ public class BgpRouter {
328 .addTreatment(treatment) 292 .addTreatment(treatment)
329 .withType(NextObjective.Type.SIMPLE) 293 .withType(NextObjective.Type.SIMPLE)
330 .fromApp(appId) 294 .fromApp(appId)
331 - .add(); 295 + .add(); // TODO add callbacks
332 296
333 flowObjectiveService.next(deviceId, nextObjective); 297 flowObjectiveService.next(deviceId, nextObjective);
334 298
335 - /*
336 - GroupBucket bucket = DefaultGroupBucket.createIndirectGroupBucket(treatment);
337 -
338 - GroupDescription groupDescription
339 - = new DefaultGroupDescription(deviceId,
340 - GroupDescription.Type.INDIRECT,
341 - new GroupBuckets(Collections
342 - .singletonList(bucket)),
343 - new DefaultGroupKey(appKryo.serialize(groupKey)),
344 - appId);
345 -
346 - groupService.addGroup(groupDescription);
347 - */
348 -
349 nextHops.put(nextHop.ip(), nextId); 299 nextHops.put(nextHop.ip(), nextId);
350 300
351 } 301 }
...@@ -366,7 +316,7 @@ public class BgpRouter { ...@@ -366,7 +316,7 @@ public class BgpRouter {
366 serialize(nextHop.group()))); 316 serialize(nextHop.group())));
367 317
368 // FIXME disabling group deletes for now until we verify the logic is OK 318 // FIXME disabling group deletes for now until we verify the logic is OK
369 - *//*if (nextHopsCount.remove(nextHopIp, 1) <= 1) { 319 + if (nextHopsCount.remove(nextHopIp, 1) <= 1) {
370 // There was one or less next hops, so there are now none 320 // There was one or less next hops, so there are now none
371 321
372 log.debug("removing group for next hop {}", nextHop); 322 log.debug("removing group for next hop {}", nextHop);
...@@ -376,7 +326,7 @@ public class BgpRouter { ...@@ -376,7 +326,7 @@ public class BgpRouter {
376 groupService.removeGroup(deviceId, 326 groupService.removeGroup(deviceId,
377 new DefaultGroupKey(appKryo.build().serialize(nextHop.group())), 327 new DefaultGroupKey(appKryo.build().serialize(nextHop.group())),
378 appId); 328 appId);
379 - }*//* 329 + }
380 330
381 return group; 331 return group;
382 }*/ 332 }*/
...@@ -402,31 +352,63 @@ public class BgpRouter { ...@@ -402,31 +352,63 @@ public class BgpRouter {
402 .forEach(ipaddr -> fob.addCondition( 352 .forEach(ipaddr -> fob.addCondition(
403 Criteria.matchIPDst(ipaddr.subnetAddress()))); 353 Criteria.matchIPDst(ipaddr.subnetAddress())));
404 fob.permit().fromApp(appId); 354 fob.permit().fromApp(appId);
405 - flowObjectiveService.filter(deviceId, fob.add()); 355 + flowObjectiveService.filter(
356 + deviceId,
357 + fob.add(new ObjectiveContext() {
358 + @Override
359 + public void onSuccess(Objective objective) {
360 + log.info("Successfully installed interface based "
361 + + "filtering objcetives");
362 + }
363 +
364 + @Override
365 + public void onError(Objective objective,
366 + ObjectiveError error) {
367 + log.error("Failed to install interface filters {}: {}",
368 + objective, error);
369 + // TODO something more than just logging
370 + }
371 + }));
406 } 372 }
407 } 373 }
408 374
409 - /* private class InternalGroupListener implements GroupListener { 375 + // Triggers driver setup when a device is (re)detected.
410 - 376 + private class InnerDeviceListener implements DeviceListener {
411 @Override 377 @Override
412 - public void event(GroupEvent event) { 378 + public void event(DeviceEvent event) {
413 - Group group = event.subject(); 379 + switch (event.type()) {
414 - 380 + case DEVICE_ADDED:
415 - if (event.type() == GroupEvent.Type.GROUP_ADDED || 381 + case DEVICE_AVAILABILITY_CHANGED:
416 - event.type() == GroupEvent.Type.GROUP_UPDATED) { 382 + if (deviceService.isAvailable(event.subject().id())) {
417 - synchronized (pendingUpdates) { 383 + log.info("Device connected {}", event.subject().id());
418 - 384 + processIntfFilters(true, configService.getInterfaces());
419 - NextHopGroupKey nhGroupKey = 385 +
420 - appKryo.deserialize(group.appCookie().key()); 386 + /* For test only - will be removed before Cardinal release */
421 - Map<FibEntry, Group> entriesToInstall = 387 + delay(1000);
422 - pendingUpdates.removeAll(nhGroupKey) 388 + FibEntry fibEntry = new FibEntry(Ip4Prefix.valueOf("10.1.0.0/16"),
423 - .stream() 389 + Ip4Address.valueOf("192.168.10.1"),
424 - .collect(Collectors 390 + MacAddress.valueOf("DE:AD:BE:EF:FE:ED"));
425 - .toMap(e -> e, e -> group)); 391 + FibUpdate fibUpdate = new FibUpdate(FibUpdate.Type.UPDATE, fibEntry);
426 - 392 + updateFibEntry(Collections.singletonList(fibUpdate));
427 - installFlows(entriesToInstall); 393 + }
428 - } 394 + break;
395 +
396 + // TODO other cases
397 + case DEVICE_UPDATED:
398 + break;
399 + case DEVICE_REMOVED:
400 + break;
401 + case DEVICE_SUSPENDED:
402 + break;
403 + case PORT_ADDED:
404 + break;
405 + case PORT_UPDATED:
406 + break;
407 + case PORT_REMOVED:
408 + break;
409 + default:
410 + break;
429 } 411 }
430 } 412 }
431 - }*/ 413 + }
432 } 414 }
......
...@@ -67,7 +67,7 @@ import static org.onlab.util.Tools.groupedThreads; ...@@ -67,7 +67,7 @@ import static org.onlab.util.Tools.groupedThreads;
67 @Service 67 @Service
68 public class FlowObjectiveManager implements FlowObjectiveService { 68 public class FlowObjectiveManager implements FlowObjectiveService {
69 69
70 - public static final int INSTALL_RETRY_ATTEMPTS = 10; 70 + public static final int INSTALL_RETRY_ATTEMPTS = 5;
71 public static final long INSTALL_RETRY_INTERVAL = 1000; // ms 71 public static final long INSTALL_RETRY_INTERVAL = 1000; // ms
72 72
73 private final Logger log = LoggerFactory.getLogger(getClass()); 73 private final Logger log = LoggerFactory.getLogger(getClass());
......
...@@ -270,7 +270,7 @@ public class OVSCorsaPipeline extends AbstractHandlerBehaviour implements Pipeli ...@@ -270,7 +270,7 @@ public class OVSCorsaPipeline extends AbstractHandlerBehaviour implements Pipeli
270 Criteria.IPProtocolCriterion ipProto = (Criteria.IPProtocolCriterion) selector 270 Criteria.IPProtocolCriterion ipProto = (Criteria.IPProtocolCriterion) selector
271 .getCriterion(Criterion.Type.IP_PROTO); 271 .getCriterion(Criterion.Type.IP_PROTO);
272 if (ipSrc != null) { 272 if (ipSrc != null) {
273 - log.warn("Driver currently does not currently handle matching Src IP"); 273 + log.warn("Driver does not currently handle matching Src IP");
274 fail(fwd, ObjectiveError.UNSUPPORTED); 274 fail(fwd, ObjectiveError.UNSUPPORTED);
275 return Collections.emptySet(); 275 return Collections.emptySet();
276 } 276 }
...@@ -797,7 +797,8 @@ public class OVSCorsaPipeline extends AbstractHandlerBehaviour implements Pipeli ...@@ -797,7 +797,8 @@ public class OVSCorsaPipeline extends AbstractHandlerBehaviour implements Pipeli
797 } 797 }
798 pass(obj); 798 pass(obj);
799 pendingGroups.invalidate(key); 799 pendingGroups.invalidate(key);
800 - log.info("Heard back from group service for group {}", obj.id()); 800 + log.info("Heard back from group service for group {}. "
801 + + "Applying pending forwarding objectives", obj.id());
801 flowObjectiveStore.putNextGroup(obj.id(), new CorsaGroup(key)); 802 flowObjectiveStore.putNextGroup(obj.id(), new CorsaGroup(key));
802 }); 803 });
803 } 804 }
......