CORD-1719 Cleanup old flows properly if the switch moves to a inexistent location
Change-Id: I8ffe970aaa9cec9ac3d4c266e460538bfd07c4fc
diff --git a/src/main/java/org/onosproject/segmentrouting/HostHandler.java b/src/main/java/org/onosproject/segmentrouting/HostHandler.java
index f8428a7..5029b30 100644
--- a/src/main/java/org/onosproject/segmentrouting/HostHandler.java
+++ b/src/main/java/org/onosproject/segmentrouting/HostHandler.java
@@ -50,6 +50,8 @@
* Handles host-related events.
*/
public class HostHandler {
+ private static final String NOT_MASTER = "Current instance is not the master of {}. Ignore.";
+
private static final Logger log = LoggerFactory.getLogger(HostHandler.class);
protected final SegmentRoutingManager srManager;
private HostService hostService;
@@ -85,6 +87,11 @@
void processHostAddedAtLocation(Host host, HostLocation location) {
checkArgument(host.locations().contains(location), "{} is not a location of {}", location, host);
+ if (!isMasterOf(location)) {
+ log.debug(NOT_MASTER, location);
+ return;
+ }
+
MacAddress mac = host.mac();
VlanId vlanId = host.vlan();
Set<HostLocation> locations = host.locations();
@@ -108,7 +115,7 @@
Set<IpAddress> ips = host.ipAddresses();
log.info("Host {}/{} is removed from {}", hostMac, hostVlanId, locations);
- locations.forEach(location -> {
+ locations.stream().filter(this::isMasterOf).forEach(location -> {
processBridgingRule(location.deviceId(), location.port(), hostMac, hostVlanId, true);
ips.forEach(ip ->
processRoutingRule(location.deviceId(), location.port(), hostMac, hostVlanId, ip, true)
@@ -143,7 +150,8 @@
.collect(Collectors.toSet());
// For each old location
- Sets.difference(prevLocations, newLocations).forEach(prevLocation -> {
+ Sets.difference(prevLocations, newLocations).stream().filter(this::isMasterOf)
+ .forEach(prevLocation -> {
// Remove routing rules for old IPs
Sets.difference(prevIps, newIps).forEach(ip ->
processRoutingRule(prevLocation.deviceId(), prevLocation.port(), hostMac, hostVlanId,
@@ -203,7 +211,8 @@
});
// For each new location, add all new IPs.
- Sets.difference(newLocations, prevLocations).forEach(newLocation -> {
+ Sets.difference(newLocations, prevLocations).stream().filter(this::isMasterOf)
+ .forEach(newLocation -> {
processBridgingRule(newLocation.deviceId(), newLocation.port(), hostMac, hostVlanId, false);
newIps.forEach(ip ->
processRoutingRule(newLocation.deviceId(), newLocation.port(), hostMac, hostVlanId,
@@ -212,7 +221,8 @@
});
// For each unchanged location, add new IPs and remove old IPs.
- Sets.intersection(newLocations, prevLocations).forEach(unchangedLocation -> {
+ Sets.intersection(newLocations, prevLocations).stream().filter(this::isMasterOf)
+ .forEach(unchangedLocation -> {
Sets.difference(prevIps, newIps).forEach(ip ->
processRoutingRule(unchangedLocation.deviceId(), unchangedLocation.port(), hostMac,
hostVlanId, ip, true)
@@ -233,7 +243,7 @@
Set<IpAddress> newIps = event.subject().ipAddresses();
log.info("Host {}/{} is updated", mac, vlanId);
- locations.forEach(location -> {
+ locations.stream().filter(this::isMasterOf).forEach(location -> {
Sets.difference(prevIps, newIps).forEach(ip ->
processRoutingRule(location.deviceId(), location.port(), mac, vlanId, ip, true)
);
@@ -373,4 +383,15 @@
srManager.routingRulePopulator.populateRoute(deviceId, ip.toIpPrefix(), mac, vlanId, port);
}
}
+
+ /**
+ * Determine if current instance is the master of given connect point.
+ *
+ * @param cp connect point
+ * @return true if current instance is the master of given connect point
+ */
+ private boolean isMasterOf(ConnectPoint cp) {
+ log.debug(NOT_MASTER, cp);
+ return srManager.mastershipService.isLocalMaster(cp.deviceId());
+ }
}