Eliminate redundant flow programming when host moves
When a host moves from [1A/1, 1B/1] to [1A/2, 1B/1], there is no need to program the pair link flow first.
Also update unit tests to verify this behavior.
Change-Id: I97c7ee5f0db891226c7ed477f5f05af5d6c1faa8
diff --git a/app/src/main/java/org/onosproject/segmentrouting/HostHandler.java b/app/src/main/java/org/onosproject/segmentrouting/HostHandler.java
index ae35f7b..eee9900 100644
--- a/app/src/main/java/org/onosproject/segmentrouting/HostHandler.java
+++ b/app/src/main/java/org/onosproject/segmentrouting/HostHandler.java
@@ -216,8 +216,9 @@
// Note: Do not continue removing any rule
Optional<DeviceId> pairDeviceId = srManager.getPairDeviceId(prevLocation.deviceId());
Optional<PortNumber> pairLocalPort = srManager.getPairLocalPort(prevLocation.deviceId());
- if (pairDeviceId.isPresent() && pairLocalPort.isPresent() && newLocations.stream()
- .anyMatch(location -> location.deviceId().equals(pairDeviceId.get()))) {
+ if (pairDeviceId.isPresent() && pairLocalPort.isPresent() &&
+ newLocations.stream().anyMatch(location -> location.deviceId().equals(pairDeviceId.get())) &&
+ newLocations.stream().noneMatch(location -> location.deviceId().equals(prevLocation.deviceId()))) {
// NOTE: Since the pairLocalPort is trunk port, use assigned vlan of original port
// when the host is untagged
VlanId vlanId = Optional.ofNullable(srManager.getInternalVlanId(prevLocation)).orElse(hostVlanId);
diff --git a/app/src/test/java/org/onosproject/segmentrouting/HostHandlerTest.java b/app/src/test/java/org/onosproject/segmentrouting/HostHandlerTest.java
index fd263bf..f72c264 100644
--- a/app/src/test/java/org/onosproject/segmentrouting/HostHandlerTest.java
+++ b/app/src/test/java/org/onosproject/segmentrouting/HostHandlerTest.java
@@ -548,6 +548,30 @@
}
@Test
+ public void testDualHomedHostMoveTransient() {
+ Host host1 = new DefaultHost(PROVIDER_ID, HOST_ID_UNTAGGED, HOST_MAC, HOST_VLAN_UNTAGGED,
+ Sets.newHashSet(HOST_LOC31, HOST_LOC41), Sets.newHashSet(HOST_IP11), false);
+ Host host2 = new DefaultHost(PROVIDER_ID, HOST_ID_UNTAGGED, HOST_MAC, HOST_VLAN_UNTAGGED,
+ Sets.newHashSet(HOST_LOC32, HOST_LOC41), Sets.newHashSet(HOST_IP11), false);
+ hostHandler.processHostAddedEvent(new HostEvent(HostEvent.Type.HOST_ADDED, host1));
+
+ // Mock DefaultRoutingHandler
+ DefaultRoutingHandler mockDefaultRoutingHandler = createMock(DefaultRoutingHandler.class);
+ hostHandler.srManager.defaultRoutingHandler = mockDefaultRoutingHandler;
+
+ // Host moved from [1A/1, 1B/1] to [1A/2, 1B/1]
+ // We should expect only one bridging flow and one routing flow programmed on 1A
+ mockDefaultRoutingHandler.populateBridging(DEV3, P2, HOST_MAC, HOST_VLAN_UNTAGGED);
+ expectLastCall().times(1);
+ mockDefaultRoutingHandler.populateRoute(DEV3, HOST_IP11.toIpPrefix(), HOST_MAC, HOST_VLAN_UNTAGGED, P2);
+ expectLastCall().times(1);
+ replay(mockDefaultRoutingHandler);
+
+ hostHandler.processHostMovedEvent(new HostEvent(HostEvent.Type.HOST_MOVED, host2, host1));
+ verify(mockDefaultRoutingHandler);
+ }
+
+ @Test
public void testHostMoveToInvalidLocation() {
Host host1 = new DefaultHost(PROVIDER_ID, HOST_ID_UNTAGGED, HOST_MAC, HOST_VLAN_UNTAGGED,
Sets.newHashSet(HOST_LOC11), Sets.newHashSet(HOST_IP11), false);