Route is not populated correctly when next hop moves
When the next hop moves from [1A,1B] to [1A],
there should be a route on 1B pointing to 1A via spines
Change-Id: I817414fb4e9edf29357fdb5e55675537ff5f0cac
(cherry picked from commit 53eae194a8b66287855483359309597e8df2efa9)
diff --git a/app/src/main/java/org/onosproject/segmentrouting/RouteHandler.java b/app/src/main/java/org/onosproject/segmentrouting/RouteHandler.java
index 8790d93..40cdf53 100644
--- a/app/src/main/java/org/onosproject/segmentrouting/RouteHandler.java
+++ b/app/src/main/java/org/onosproject/segmentrouting/RouteHandler.java
@@ -249,14 +249,23 @@
Sets.difference(prevLocations, newLocations).forEach(prevLocation -> {
// Remove flows for unchanged IPs only when the host moves from a switch to another.
// Otherwise, do not remove and let the adding part update the old flow
- if (!newDeviceIds.contains(prevLocation.deviceId())) {
- log.debug("HostMoved. removeSubnet {}, {}", prevLocation, prefix);
- srManager.deviceConfiguration.removeSubnet(prevLocation, prefix);
-
- log.debug("HostMoved. revokeRoute {}, {}, {}, {}", prevLocation, prefix, hostMac, hostVlanId);
- srManager.defaultRoutingHandler.revokeRoute(prevLocation.deviceId(), prefix,
- hostMac, hostVlanId, prevLocation.port());
+ if (newDeviceIds.contains(prevLocation.deviceId())) {
+ return;
}
+
+ log.debug("HostMoved. removeSubnet {}, {}", prevLocation, prefix);
+ srManager.deviceConfiguration.removeSubnet(prevLocation, prefix);
+
+ // Do not remove flow from a device if the route is still reachable via its pair device.
+ // populateSubnet will update the flow to point to its pair device via spine.
+ DeviceId pairDeviceId = srManager.getPairDeviceId(prevLocation.deviceId()).orElse(null);
+ if (newLocations.stream().anyMatch(n -> n.deviceId().equals(pairDeviceId))) {
+ return;
+ }
+
+ log.debug("HostMoved. revokeRoute {}, {}, {}, {}", prevLocation, prefix, hostMac, hostVlanId);
+ srManager.defaultRoutingHandler.revokeRoute(prevLocation.deviceId(), prefix,
+ hostMac, hostVlanId, prevLocation.port());
});
// For each new location, add all new IPs.
diff --git a/app/src/test/java/org/onosproject/segmentrouting/RouteHandlerTest.java b/app/src/test/java/org/onosproject/segmentrouting/RouteHandlerTest.java
index 7804e68..494b9ec 100644
--- a/app/src/test/java/org/onosproject/segmentrouting/RouteHandlerTest.java
+++ b/app/src/test/java/org/onosproject/segmentrouting/RouteHandlerTest.java
@@ -414,7 +414,8 @@
HostEvent he = new HostEvent(HostEvent.Type.HOST_MOVED, H3S, H3D);
routeHandler.processHostMovedEvent(he);
- assertEquals(1, ROUTING_TABLE.size());
+ // We do not remove the route on CP2. Instead, we let the subnet population overrides it
+ assertEquals(2, ROUTING_TABLE.size());
MockRoutingTableValue rtv1 = ROUTING_TABLE.get(new MockRoutingTableKey(CP1.deviceId(), P1));
assertEquals(M3, rtv1.macAddress);
assertEquals(V3, rtv1.vlanId);