Send probes when host moves
Majorly for the 2nd step of [1A/x, 1B/x] -> [1A/x, 1B/y] -> [1A/y, 1B/y]
But will also cover [1A/x] -> [1A/y] -> [1A/y, 1B/y]
When receiving probe for 1A/y in [1A/x, 1B/y] state, simply replace 1A/x with 1A/y instead of creating a transient 3rd locaiton
Change-Id: I058a265bbe5019d4305aa09d70e095fec0d7e429
diff --git a/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/HostHandler.java b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/HostHandler.java
index fecdd30..f71c1d0 100644
--- a/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/HostHandler.java
+++ b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/HostHandler.java
@@ -46,7 +46,6 @@
*/
public class HostHandler {
private static final Logger log = LoggerFactory.getLogger(HostHandler.class);
- static final int HOST_MOVED_DELAY_MS = 1000;
protected final SegmentRoutingManager srManager;
private HostService hostService;
@@ -170,20 +169,16 @@
}
void processHostMovedEvent(HostEvent event) {
- Set<HostLocation> prevLocations = event.prevSubject().locations();
- Set<IpAddress> prevIps = event.prevSubject().ipAddresses();
- Set<HostLocation> newLocations = event.subject().locations();
- Set<IpAddress> newIps = event.subject().ipAddresses();
-
- processHostMoved(event.subject(), prevLocations, prevIps, newLocations, newIps);
- }
-
- private void processHostMoved(Host host, Set<HostLocation> prevLocations, Set<IpAddress> prevIps,
- Set<HostLocation> newLocations, Set<IpAddress> newIps) {
+ Host host = event.subject();
MacAddress hostMac = host.mac();
VlanId hostVlanId = host.vlan();
+ Set<HostLocation> prevLocations = event.prevSubject().locations();
+ Set<IpAddress> prevIps = event.prevSubject().ipAddresses();
+ Set<HostLocation> newLocations = host.locations();
+ Set<IpAddress> newIps = host.ipAddresses();
EthType hostTpid = host.tpid();
boolean doubleTaggedHost = isDoubleTaggedHost(host);
+
log.info("Host {}/{} is moved from {} to {}", hostMac, hostVlanId, prevLocations, newLocations);
Set<DeviceId> newDeviceIds = newLocations.stream().map(HostLocation::deviceId)
.collect(Collectors.toSet());
@@ -275,6 +270,17 @@
ip, false);
}
});
+
+ // Probe on pair device when host move
+ // Majorly for the 2nd step of [1A/x, 1B/x] -> [1A/x, 1B/y] -> [1A/y, 1B/y]
+ // But will also cover [1A/x] -> [1A/y] -> [1A/y, 1B/y]
+ if (srManager.activeProbing) {
+ srManager.getPairDeviceId(newLocation.deviceId()).ifPresent(pairDeviceId ->
+ srManager.getPairLocalPort(pairDeviceId).ifPresent(pairRemotePort ->
+ probe(host, newLocation, pairDeviceId, pairRemotePort)
+ )
+ );
+ }
});
// For each unchanged location, add new IPs and remove old IPs.
diff --git a/apps/segmentrouting/app/src/test/java/org/onosproject/segmentrouting/HostHandlerTest.java b/apps/segmentrouting/app/src/test/java/org/onosproject/segmentrouting/HostHandlerTest.java
index ea44703..26420ac 100644
--- a/apps/segmentrouting/app/src/test/java/org/onosproject/segmentrouting/HostHandlerTest.java
+++ b/apps/segmentrouting/app/src/test/java/org/onosproject/segmentrouting/HostHandlerTest.java
@@ -455,6 +455,9 @@
Sets.newHashSet(HOST_LOC11, HOST_LOC21), Sets.newHashSet(HOST_IP13, HOST_IP14), false);
Host host4 = new DefaultHost(PROVIDER_ID, HOST_ID_UNTAGGED, HOST_MAC, HOST_VLAN_UNTAGGED,
Sets.newHashSet(HOST_LOC11, HOST_LOC22), Sets.newHashSet(HOST_IP12, HOST_IP13), false);
+ Host host5 = new DefaultHost(PROVIDER_ID, HOST_ID_UNTAGGED, HOST_MAC, HOST_VLAN_UNTAGGED,
+ Sets.newHashSet(HOST_LOC12, HOST_LOC21), Sets.newHashSet(HOST_IP11, HOST_IP12), false);
+
// Add a host with IP11, IP12 and LOC11, LOC21
// Expect: 4 routing rules and 2 bridging rules
@@ -468,9 +471,21 @@
assertEquals(P1, BRIDGING_TABLE.get(new MockBridgingTableKey(DEV1, HOST_MAC, INTF_VLAN_UNTAGGED)).portNumber);
assertEquals(P1, BRIDGING_TABLE.get(new MockBridgingTableKey(DEV2, HOST_MAC, INTF_VLAN_UNTAGGED)).portNumber);
+ // Move the host to LOC12, LOC21 and keep the IP
+ // Expect: 4 routing rules and 2 bridging rules all at the new location
+ hostHandler.processHostMovedEvent(new HostEvent(HostEvent.Type.HOST_MOVED, host5, host1));
+ assertEquals(4, ROUTING_TABLE.size());
+ assertEquals(P2, ROUTING_TABLE.get(new MockRoutingTableKey(DEV1, HOST_IP11.toIpPrefix())).portNumber);
+ assertEquals(P2, ROUTING_TABLE.get(new MockRoutingTableKey(DEV1, HOST_IP12.toIpPrefix())).portNumber);
+ assertEquals(P1, ROUTING_TABLE.get(new MockRoutingTableKey(DEV2, HOST_IP11.toIpPrefix())).portNumber);
+ assertEquals(P1, ROUTING_TABLE.get(new MockRoutingTableKey(DEV2, HOST_IP12.toIpPrefix())).portNumber);
+ assertEquals(2, BRIDGING_TABLE.size());
+ assertEquals(P2, BRIDGING_TABLE.get(new MockBridgingTableKey(DEV1, HOST_MAC, INTF_VLAN_UNTAGGED)).portNumber);
+ assertEquals(P1, BRIDGING_TABLE.get(new MockBridgingTableKey(DEV2, HOST_MAC, INTF_VLAN_UNTAGGED)).portNumber);
+
// Move the host to LOC12, LOC22 and keep the IP
// Expect: 4 routing rules and 2 bridging rules all at the new location
- hostHandler.processHostMovedEvent(new HostEvent(HostEvent.Type.HOST_MOVED, host2, host1));
+ hostHandler.processHostMovedEvent(new HostEvent(HostEvent.Type.HOST_MOVED, host2, host5));
assertEquals(4, ROUTING_TABLE.size());
assertEquals(P2, ROUTING_TABLE.get(new MockRoutingTableKey(DEV1, HOST_IP11.toIpPrefix())).portNumber);
assertEquals(P2, ROUTING_TABLE.get(new MockRoutingTableKey(DEV1, HOST_IP12.toIpPrefix())).portNumber);
diff --git a/core/store/dist/src/main/java/org/onosproject/store/host/impl/DistributedHostStore.java b/core/store/dist/src/main/java/org/onosproject/store/host/impl/DistributedHostStore.java
index b9f7a7d..aa811ba 100644
--- a/core/store/dist/src/main/java/org/onosproject/store/host/impl/DistributedHostStore.java
+++ b/core/store/dist/src/main/java/org/onosproject/store/host/impl/DistributedHostStore.java
@@ -336,12 +336,15 @@
checkState(Objects.equals(hostId.vlanId(), existingHost.vlan()),
"Existing and new VLANs differ.");
- Set<HostLocation> locations = new HashSet<>(existingHost.locations());
- locations.add(location);
+ // Move within the same switch
+ // Simply replace old location that is on the same device
+ Set<HostLocation> newLocations = Sets.newHashSet(location);
+ existingHost.locations().stream().filter(loc -> !loc.deviceId().equals(location.deviceId()))
+ .forEach(newLocations::add);
return new DefaultHost(existingHost.providerId(),
hostId, existingHost.mac(), existingHost.vlan(),
- locations, existingHost.ipAddresses(),
+ newLocations, existingHost.ipAddresses(),
existingHost.configured(), existingHost.annotations());
}
return null;