Saurav Das
Committed by Gerrit Code Review

CORD-45 CORD-394

Bugfix in group store - group delete state updated correctly.
SR app no longer deletes buckets in existing groups - workaround for OFDPA bug.
Instead it invalidates the entire group, thereby forcing new group creation.
Also incorporating Charles' changes to remove state from group and flow stores,
and the SR app when device goes offline.

Change-Id: I162d3fb6bf709a8f02b01b8d57e131c2bac9b46b
...@@ -561,4 +561,9 @@ public class DefaultRoutingHandler { ...@@ -561,4 +561,9 @@ public class DefaultRoutingHandler {
561 statusLock.unlock(); 561 statusLock.unlock();
562 } 562 }
563 } 563 }
564 +
565 + public void purgeEcmpGraph(DeviceId deviceId) {
566 + currentEcmpSpgMap.remove(deviceId);
567 + updatedEcmpSpgMap.remove(deviceId);
568 + }
564 } 569 }
......
...@@ -30,6 +30,7 @@ import org.onlab.packet.Ip4Prefix; ...@@ -30,6 +30,7 @@ import org.onlab.packet.Ip4Prefix;
30 import org.onlab.packet.IpAddress; 30 import org.onlab.packet.IpAddress;
31 import org.onlab.packet.IpPrefix; 31 import org.onlab.packet.IpPrefix;
32 import org.onlab.util.KryoNamespace; 32 import org.onlab.util.KryoNamespace;
33 +import org.onosproject.cfg.ComponentConfigService;
33 import org.onosproject.core.ApplicationId; 34 import org.onosproject.core.ApplicationId;
34 import org.onosproject.core.CoreService; 35 import org.onosproject.core.CoreService;
35 import org.onosproject.event.Event; 36 import org.onosproject.event.Event;
...@@ -139,6 +140,9 @@ public class SegmentRoutingManager implements SegmentRoutingService { ...@@ -139,6 +140,9 @@ public class SegmentRoutingManager implements SegmentRoutingService {
139 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) 140 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
140 protected NetworkConfigRegistry cfgService; 141 protected NetworkConfigRegistry cfgService;
141 142
143 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
144 + protected ComponentConfigService compCfgService;
145 +
142 protected ArpHandler arpHandler = null; 146 protected ArpHandler arpHandler = null;
143 protected IcmpHandler icmpHandler = null; 147 protected IcmpHandler icmpHandler = null;
144 protected IpHandler ipHandler = null; 148 protected IpHandler ipHandler = null;
...@@ -323,6 +327,11 @@ public class SegmentRoutingManager implements SegmentRoutingService { ...@@ -323,6 +327,11 @@ public class SegmentRoutingManager implements SegmentRoutingService {
323 .withTimestampProvider((k, v) -> new WallClockTimestamp()) 327 .withTimestampProvider((k, v) -> new WallClockTimestamp())
324 .build(); 328 .build();
325 329
330 + compCfgService.preSetProperty("org.onosproject.net.group.impl.GroupManager",
331 + "purgeOnDisconnection", "true");
332 + compCfgService.preSetProperty("org.onosproject.net.flow.impl.FlowRuleManager",
333 + "purgeOnDisconnection", "true");
334 +
326 processor = new InternalPacketProcessor(); 335 processor = new InternalPacketProcessor();
327 linkListener = new InternalLinkListener(); 336 linkListener = new InternalLinkListener();
328 deviceListener = new InternalDeviceListener(); 337 deviceListener = new InternalDeviceListener();
...@@ -676,15 +685,11 @@ public class SegmentRoutingManager implements SegmentRoutingService { ...@@ -676,15 +685,11 @@ public class SegmentRoutingManager implements SegmentRoutingService {
676 log.info("Processing device event {} for available device {}", 685 log.info("Processing device event {} for available device {}",
677 event.type(), ((Device) event.subject()).id()); 686 event.type(), ((Device) event.subject()).id());
678 processDeviceAdded((Device) event.subject()); 687 processDeviceAdded((Device) event.subject());
679 - } /* else { 688 + } else {
680 - if (event.type() == DeviceEvent.Type.DEVICE_AVAILABILITY_CHANGED) { 689 + log.info("Processing device event {} for unavailable device {}",
681 - // availability changed and not available - dev gone 690 + event.type(), ((Device) event.subject()).id());
682 - DefaultGroupHandler groupHandler = groupHandlerMap.get(deviceId); 691 + processDeviceRemoved((Device) event.subject());
683 - if (groupHandler != null) { 692 + }
684 - groupHandler.removeAllGroups();
685 - }
686 - }
687 - }*/
688 } else if (event.type() == DeviceEvent.Type.PORT_REMOVED) { 693 } else if (event.type() == DeviceEvent.Type.PORT_REMOVED) {
689 processPortRemoved((Device) event.subject(), 694 processPortRemoved((Device) event.subject(),
690 ((DeviceEvent) event).port()); 695 ((DeviceEvent) event).port());
...@@ -793,6 +798,42 @@ public class SegmentRoutingManager implements SegmentRoutingService { ...@@ -793,6 +798,42 @@ public class SegmentRoutingManager implements SegmentRoutingService {
793 netcfgHandler.initVRouters(device.id()); 798 netcfgHandler.initVRouters(device.id());
794 } 799 }
795 800
801 + private void processDeviceRemoved(Device device) {
802 + nsNextObjStore.entrySet().stream()
803 + .filter(entry -> entry.getKey().deviceId().equals(device.id()))
804 + .forEach(entry -> {
805 + nsNextObjStore.remove(entry.getKey());
806 + });
807 +
808 + subnetNextObjStore.entrySet().stream()
809 + .filter(entry -> entry.getKey().deviceId().equals(device.id()))
810 + .forEach(entry -> {
811 + subnetNextObjStore.remove(entry.getKey());
812 + });
813 +
814 + portNextObjStore.entrySet().stream()
815 + .filter(entry -> entry.getKey().deviceId().equals(device.id()))
816 + .forEach(entry -> {
817 + portNextObjStore.remove(entry.getKey());
818 + });
819 +
820 + xConnectNextObjStore.entrySet().stream()
821 + .filter(entry -> entry.getKey().deviceId().equals(device.id()))
822 + .forEach(entry -> {
823 + xConnectNextObjStore.remove(entry.getKey());
824 + });
825 +
826 + subnetVidStore.entrySet().stream()
827 + .filter(entry -> entry.getKey().deviceId().equals(device.id()))
828 + .forEach(entry -> {
829 + subnetVidStore.remove(entry.getKey());
830 + });
831 +
832 + groupHandlerMap.remove(device.id());
833 +
834 + defaultRoutingHandler.purgeEcmpGraph(device.id());
835 + }
836 +
796 private void processPortRemoved(Device device, Port port) { 837 private void processPortRemoved(Device device, Port port) {
797 log.debug("Port {} was removed", port.toString()); 838 log.debug("Port {} was removed", port.toString());
798 DefaultGroupHandler groupHandler = groupHandlerMap.get(device.id()); 839 DefaultGroupHandler groupHandler = groupHandlerMap.get(device.id());
......
...@@ -288,6 +288,7 @@ public class DefaultGroupHandler { ...@@ -288,6 +288,7 @@ public class DefaultGroupHandler {
288 return; 288 return;
289 } 289 }
290 290
291 + @SuppressWarnings("unused")
291 MacAddress dstMac; 292 MacAddress dstMac;
292 try { 293 try {
293 dstMac = deviceConfig.getDeviceMac(portDeviceMap.get(port)); 294 dstMac = deviceConfig.getDeviceMac(portDeviceMap.get(port));
...@@ -312,9 +313,17 @@ public class DefaultGroupHandler { ...@@ -312,9 +313,17 @@ public class DefaultGroupHandler {
312 log.debug("portDown: nsNextObjStore contents for device {}:{}", 313 log.debug("portDown: nsNextObjStore contents for device {}:{}",
313 deviceId, nsSet); 314 deviceId, nsSet);
314 for (NeighborSet ns : nsSet) { 315 for (NeighborSet ns : nsSet) {
315 - Integer nextId = nsNextObjStore. 316 + NeighborSetNextObjectiveStoreKey nsStoreKey =
316 - get(new NeighborSetNextObjectiveStoreKey(deviceId, ns)); 317 + new NeighborSetNextObjectiveStoreKey(deviceId, ns);
318 + Integer nextId = nsNextObjStore.get(nsStoreKey);
317 if (nextId != null && isMaster) { 319 if (nextId != null && isMaster) {
320 + // XXX This is a workaround for BUG (CORD-611) in current switches.
321 + // Should be temporary because this workaround prevents correct
322 + // functionality in LAG recovery.
323 + log.info("**portDown port:{} in device {}: Invalidating nextId {}",
324 + port, deviceId, nextId);
325 + nsNextObjStore.remove(nsStoreKey);
326 + /*
318 log.info("**portDown in device {}: Removing Bucket " 327 log.info("**portDown in device {}: Removing Bucket "
319 + "with Port {} to next object id {}", 328 + "with Port {} to next object id {}",
320 deviceId, 329 deviceId,
...@@ -341,7 +350,7 @@ public class DefaultGroupHandler { ...@@ -341,7 +350,7 @@ public class DefaultGroupHandler {
341 removeFromExisting(new SRNextObjectiveContext(deviceId)); 350 removeFromExisting(new SRNextObjectiveContext(deviceId));
342 351
343 flowObjectiveService.next(deviceId, nextObjective); 352 flowObjectiveService.next(deviceId, nextObjective);
344 - 353 + */
345 // the removal of a bucket may actually change the neighborset 354 // the removal of a bucket may actually change the neighborset
346 // update the global store 355 // update the global store
347 /* 356 /*
......
...@@ -769,6 +769,9 @@ public class DistributedGroupStore ...@@ -769,6 +769,9 @@ public class DistributedGroupStore
769 existing.state()); 769 existing.state());
770 synchronized (existing) { 770 synchronized (existing) {
771 existing.setState(GroupState.PENDING_DELETE); 771 existing.setState(GroupState.PENDING_DELETE);
772 + getGroupStoreKeyMap().
773 + put(new GroupStoreKeyMapKey(existing.deviceId(), existing.appCookie()),
774 + existing);
772 } 775 }
773 log.debug("deleteGroupDescriptionInternal: in device {} issuing GROUP_REMOVE_REQUESTED", 776 log.debug("deleteGroupDescriptionInternal: in device {} issuing GROUP_REMOVE_REQUESTED",
774 deviceId); 777 deviceId);
......