Fix for the issue: CM routes pointing to spine instead of pg pod after updating netcfg.
DualHomed subnets add and remove issues addressed.
Change-Id: I41c333923e2f2170834d1c83485a418b893f44da
diff --git a/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/DefaultRoutingHandler.java b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/DefaultRoutingHandler.java
index 8a2e353..b4aaec8 100644
--- a/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/DefaultRoutingHandler.java
+++ b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/DefaultRoutingHandler.java
@@ -1303,6 +1303,26 @@
return checkJobs(futures);
}
+ /**
+ * Revoke rules of given subnets in the given switches.
+ *
+ * @param targetSwitches switched from which subnets to be removed
+ * @param subnets subnet bring removed
+ * @return true if succeed
+ */
+ protected boolean revokeSubnet(Set<DeviceId> targetSwitches, Set<IpPrefix> subnets) {
+ List<Future<Boolean>> futures = Lists.newArrayList();
+ for (DeviceId targetSw : targetSwitches) {
+ if (shouldProgram(targetSw)) {
+ futures.add(routePopulators.submit(new RevokeSubnet(targetSw, subnets)));
+ } else {
+ futures.add(CompletableFuture.completedFuture(true));
+ }
+ }
+ // check the execution of each job
+ return checkJobs(futures);
+ }
+
private final class RevokeSubnet implements PickyCallable<Boolean> {
private DeviceId targetSw;
private Set<IpPrefix> subnets;
diff --git a/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/SegmentRoutingManager.java b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/SegmentRoutingManager.java
index d121cff..6d2b8cc 100644
--- a/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/SegmentRoutingManager.java
+++ b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/SegmentRoutingManager.java
@@ -2222,10 +2222,37 @@
.map(InterfaceIpAddress::subnetAddress)
.collect(Collectors.toSet());
- defaultRoutingHandler.revokeSubnet(
- ipPrefixSet.stream()
- .filter(ipPrefix -> !deviceIpPrefixSet.contains(ipPrefix))
- .collect(Collectors.toSet()));
+ Set<IpPrefix> subnetsToBeRevoked = ipPrefixSet.stream()
+ .filter(ipPrefix -> !deviceIpPrefixSet.contains(ipPrefix))
+ .collect(Collectors.toSet());
+
+ // Check if any of the subnets to be revoked is configured in the pairDevice.
+ // If any, repopulate the subnet with pairDevice connectPoint instead of revoking.
+ Optional<DeviceId> pairDevice = getPairDeviceId(cp.deviceId());
+ if (pairDevice.isPresent()) {
+ Set<IpPrefix> pairDeviceIpPrefix = getDeviceSubnetMap().get(pairDevice.get());
+
+ Set<IpPrefix> subnetsExistingInPairDevice = subnetsToBeRevoked.stream()
+ .filter(ipPrefix -> pairDeviceIpPrefix.contains(ipPrefix))
+ .collect(Collectors.toSet());
+
+ // Update the subnets existing in pair device with pair device connect point.
+ if (!subnetsExistingInPairDevice.isEmpty()) {
+ // PortNumber of connect point is not relevant in populate subnet and hence providing as ANY.
+ ConnectPoint pairDeviceCp = new ConnectPoint(pairDevice.get(), PortNumber.ANY);
+ log.debug("Updating the subnets: {} with pairDevice connectPoint as it exists in the Pair device: {}",
+ subnetsExistingInPairDevice, pairDeviceCp);
+ defaultRoutingHandler.populateSubnet(Collections.singleton(pairDeviceCp), subnetsExistingInPairDevice);
+ }
+
+ // Remove only the subnets that are not configured in the pairDevice.
+ subnetsToBeRevoked = Sets.difference(subnetsToBeRevoked, subnetsExistingInPairDevice);
+ }
+
+ if (!subnetsToBeRevoked.isEmpty()) {
+ log.debug("Removing subnets for connectPoint: {}, subnets: {}", cp, subnetsToBeRevoked);
+ defaultRoutingHandler.revokeSubnet(subnetsToBeRevoked);
+ }
// 2. Interface IP punts
// Remove IP punts for old Intf address
@@ -2259,12 +2286,56 @@
Set<IpPrefix> deviceIpPrefixSet = deviceIntfIpAddrs.stream()
.map(InterfaceIpAddress::subnetAddress)
.collect(Collectors.toSet());
+ Set<IpPrefix> subnetsToBePopulated = ipPrefixSet.stream()
+ .filter(ipPrefix -> !deviceIpPrefixSet.contains(ipPrefix))
+ .collect(Collectors.toSet());
- defaultRoutingHandler.populateSubnet(
- Collections.singleton(cp),
- ipPrefixSet.stream()
- .filter(ipPrefix -> !deviceIpPrefixSet.contains(ipPrefix))
- .collect(Collectors.toSet()));
+ if (!subnetsToBePopulated.isEmpty()) {
+ log.debug("Adding subnets for connectPoint: {}, subnets: {}", cp, subnetsToBePopulated);
+
+ // check if pair-device has the same subnet configured?
+ Optional<DeviceId> pairDevice = getPairDeviceId(cp.deviceId());
+ if (pairDevice.isPresent()) {
+ Set<IpPrefix> pairDeviceIpPrefix = getDeviceSubnetMap().get(pairDevice.get());
+
+ Set<IpPrefix> subnetsToBePopulatedAsDualHomed = subnetsToBePopulated.stream()
+ .filter(ipPrefix -> pairDeviceIpPrefix.contains(ipPrefix))
+ .collect(Collectors.toSet());
+ Set<IpPrefix> subnetsToBePopulatedAsSingleHomed = Sets.difference(subnetsToBePopulated,
+ subnetsToBePopulatedAsDualHomed);
+
+ if (!subnetsToBePopulatedAsSingleHomed.isEmpty()) {
+ defaultRoutingHandler.populateSubnet(
+ Collections.singleton(cp),
+ subnetsToBePopulatedAsSingleHomed);
+ }
+
+ if (!subnetsToBePopulatedAsDualHomed.isEmpty()) {
+ Set<ConnectPoint> cpts = new HashSet<>();
+ cpts.add(cp);
+ // As Subnets is DualHomed adding the pairDevice also as ConnectPoint.
+ // PortNumber of connect point is not relevant in populate subnet and hence providing as ANY.
+ ConnectPoint pairCp = new ConnectPoint(pairDevice.get(), PortNumber.ANY);
+ cpts.add(pairCp);
+
+ log.debug("Adding DualHomed subnets for connectPoint: {} and its pair device: {}, subnets: {}",
+ cp, pairCp, subnetsToBePopulatedAsDualHomed);
+
+ // populating the subnets as DualHomed
+ defaultRoutingHandler.populateSubnet(
+ cpts,
+ subnetsToBePopulated);
+
+ // revoking the subnets populated in the device as it is now Dualhomed.
+ defaultRoutingHandler.revokeSubnet(Collections.singleton(cp.deviceId()),
+ subnetsToBePopulatedAsDualHomed);
+ }
+ } else {
+ defaultRoutingHandler.populateSubnet(
+ Collections.singleton(cp),
+ subnetsToBePopulated);
+ }
+ }
// 2. Interface IP punts
// Add IP punts for new Intf address