Delete prefix from sr-device-subnet when the next hop host is removed
Change-Id: I440897a531b69dd7bbe771eff69728bbff9a2513
diff --git a/app/src/main/java/org/onosproject/segmentrouting/HostHandler.java b/app/src/main/java/org/onosproject/segmentrouting/HostHandler.java
index 4c56db5..1690522 100644
--- a/app/src/main/java/org/onosproject/segmentrouting/HostHandler.java
+++ b/app/src/main/java/org/onosproject/segmentrouting/HostHandler.java
@@ -171,6 +171,16 @@
processRoutingRule(pairDeviceId.get(), pairLocalPort.get(), hostMac, vlanId,
ip, true));
}
+
+ // Delete prefix from sr-device-subnet when the next hop host is removed
+ srManager.routeService.getRouteTables().forEach(tableId -> {
+ srManager.routeService.getRoutes(tableId).forEach(routeInfo -> {
+ if (routeInfo.allRoutes().stream().anyMatch(rr -> ips.contains(rr.nextHop()))) {
+ log.debug("HostRemoved. removeSubnet {}, {}", location, routeInfo.prefix());
+ srManager.deviceConfiguration.removeSubnet(location, routeInfo.prefix());
+ }
+ });
+ });
});
}
diff --git a/app/src/test/java/org/onosproject/segmentrouting/HostHandlerTest.java b/app/src/test/java/org/onosproject/segmentrouting/HostHandlerTest.java
index 30462fb..f3f49ae 100644
--- a/app/src/test/java/org/onosproject/segmentrouting/HostHandlerTest.java
+++ b/app/src/test/java/org/onosproject/segmentrouting/HostHandlerTest.java
@@ -21,6 +21,7 @@
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
+import org.easymock.EasyMock;
import org.junit.Before;
import org.junit.Test;
import org.onlab.packet.IpAddress;
@@ -42,6 +43,11 @@
import org.onosproject.net.host.HostEvent;
import org.onosproject.net.host.InterfaceIpAddress;
import org.onosproject.net.provider.ProviderId;
+import org.onosproject.routeservice.ResolvedRoute;
+import org.onosproject.routeservice.Route;
+import org.onosproject.routeservice.RouteInfo;
+import org.onosproject.routeservice.RouteService;
+import org.onosproject.routeservice.RouteTableId;
import org.onosproject.segmentrouting.config.DeviceConfiguration;
import org.onosproject.segmentrouting.config.SegmentRoutingDeviceConfig;
import org.onosproject.store.service.StorageService;
@@ -51,8 +57,12 @@
import java.util.Set;
import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.createNiceMock;
import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.expectLastCall;
import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.reset;
+import static org.easymock.EasyMock.verify;
import static org.junit.Assert.*;
/**r
@@ -223,6 +233,11 @@
srManager.probingService = mockLocationProbingService;
srManager.linkHandler = new MockLinkHandler(srManager);
+ // Not important for most of the HostHandler test case. Simply return an empty set here
+ srManager.routeService = createNiceMock(RouteService.class);
+ expect(srManager.routeService.getRouteTables()).andReturn(Sets.newHashSet()).anyTimes();
+ replay(srManager.routeService);
+
hostHandler = new HostHandler(srManager);
ROUTING_TABLE.clear();
@@ -867,4 +882,56 @@
assertNull(hostHandler.vlanForPairPort(VlanId.NONE, CP51));
assertNull(hostHandler.vlanForPairPort(INTF_VLAN_UNTAGGED, CP51));
}
+
+ @Test
+ public void testHostRemovedWithRouteRemoved() throws Exception {
+ Host subject = new DefaultHost(PROVIDER_ID, HOST_ID_UNTAGGED, HOST_MAC, HOST_VLAN_UNTAGGED,
+ Sets.newHashSet(HOST_LOC11), Sets.newHashSet(HOST_IP11), false);
+
+ // Add a host
+ // Expect: add one routing rule and one bridging rule
+ hostHandler.processHostAddedEvent(new HostEvent(HostEvent.Type.HOST_ADDED, subject));
+ assertEquals(1, ROUTING_TABLE.size());
+ assertNotNull(ROUTING_TABLE.get(new MockRoutingTableKey(DEV1, HOST_IP11.toIpPrefix())));
+ assertEquals(1, BRIDGING_TABLE.size());
+ assertNotNull(BRIDGING_TABLE.get(new MockBridgingTableKey(DEV1, HOST_MAC, INTF_VLAN_UNTAGGED)));
+
+ IpPrefix prefix = IpPrefix.valueOf("55.55.55.0/24");
+
+ // Setting up mock route service
+ RouteService routeService = hostHandler.srManager.routeService;
+ reset(routeService);
+
+ IpAddress nextHopIp2 = IpAddress.valueOf("20.0.0.1");
+ MacAddress nextHopMac2 = MacAddress.valueOf("00:22:33:44:55:66");
+ VlanId nextHopVlan2 = VlanId.NONE;
+
+ Route r1 = new Route(Route.Source.STATIC, prefix, HOST_IP11);
+ ResolvedRoute rr1 = new ResolvedRoute(r1, HOST_MAC, VlanId.NONE);
+ Route r2 = new Route(Route.Source.STATIC, prefix, nextHopIp2);
+ ResolvedRoute rr2 = new ResolvedRoute(r2, nextHopMac2, nextHopVlan2);
+ RouteInfo routeInfo = new RouteInfo(prefix, rr1, Sets.newHashSet(rr1, rr2));
+ RouteTableId routeTableId = new RouteTableId("ipv4");
+
+ expect(routeService.getRouteTables()).andReturn(Sets.newHashSet(routeTableId));
+ expect(routeService.getRoutes(routeTableId)).andReturn(Sets.newHashSet(routeInfo));
+ replay(routeService);
+
+ // Setting up mock device configuration
+ hostHandler.srManager.deviceConfiguration = EasyMock.createNiceMock(DeviceConfiguration.class);
+ DeviceConfiguration deviceConfiguration = hostHandler.srManager.deviceConfiguration;
+ expect(deviceConfiguration.inSameSubnet(CP11, HOST_IP11)).andReturn(true);
+ deviceConfiguration.removeSubnet(CP11, prefix);
+ expectLastCall();
+ replay(deviceConfiguration);
+
+ // Remove the host
+ // Expect: add the routing rule and the bridging rule
+ hostHandler.processHostRemovedEvent(new HostEvent(HostEvent.Type.HOST_REMOVED, subject));
+ assertEquals(0, ROUTING_TABLE.size());
+ assertEquals(0, BRIDGING_TABLE.size());
+
+ // Expect: subnet is removed from device config
+ verify(deviceConfiguration);
+ }
}