use of org.onosproject.net.Host in project trellis-control by opennetworkinglab.
the class RouteHandler method processHostMovedEvent.
void processHostMovedEvent(HostEvent event) {
log.info("processHostMovedEvent {}", event);
MacAddress hostMac = event.subject().mac();
VlanId hostVlanId = event.subject().vlan();
Set<ConnectPoint> prevLocations = event.prevSubject().locations().stream().map(h -> (ConnectPoint) h).collect(Collectors.toSet());
Set<ConnectPoint> newLocations = event.subject().locations().stream().map(h -> (ConnectPoint) h).collect(Collectors.toSet());
List<Set<IpPrefix>> batchedSubnets = srManager.deviceConfiguration.getBatchedSubnets(event.subject().id());
Set<DeviceId> newDeviceIds = newLocations.stream().map(ConnectPoint::deviceId).collect(Collectors.toSet());
// Set of deviceIDs of the previous locations where the host was connected
// Used to determine if host moved to different connect points
// on same device or moved to a different device altogether
Set<DeviceId> oldDeviceIds = prevLocations.stream().map(ConnectPoint::deviceId).collect(Collectors.toSet());
// and only when the no. of routes with the host as next-hop is not zero
if (!batchedSubnets.isEmpty()) {
// For each new location, if NextObj exists for the host, update with new location ..
Sets.difference(newLocations, prevLocations).forEach(newLocation -> {
// NOTE: that we use the nexthop vlanId to retrieve the nextId
// while the vlanId used to program the L3 unicast chain
// is derived from the port configuration. In case of
// a tagged interface we use host vlanId. Host vlan should
// be part of the tags configured for that port. See the
// code in DefaultGroupHandler.updateL3UcastGroupBucket
int nextId = srManager.getMacVlanNextObjectiveId(newLocation.deviceId(), hostMac, hostVlanId, null, false);
if (nextId != -1) {
// Update the nextId group bucket
log.debug("HostMoved. NextId exists, update L3 Ucast Group Bucket {}, {}, {} --> {}", newLocation, hostMac, hostVlanId, nextId);
srManager.updateMacVlanTreatment(newLocation.deviceId(), hostMac, hostVlanId, newLocation.port(), nextId);
} else {
log.debug("HostMoved. NextId does not exist for this location {}, host {}/{}", newLocation, hostMac, hostVlanId);
}
});
}
batchedSubnets.forEach(subnets -> {
log.debug("HostMoved. populateSubnet {}, {}", newLocations, subnets);
srManager.defaultRoutingHandler.populateSubnet(newLocations, subnets);
subnets.forEach(prefix -> {
// For each old location
Sets.difference(prevLocations, newLocations).forEach(prevLocation -> {
// Otherwise, do not remove and let the adding part update the old flow
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.
// If spine exists,
// populateSubnet above will update the flow to point to its pair device via spine.
// If spine does not exist,
// processSingleLeafPair below will update the flow to point to its pair device via pair port.
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(), false);
});
// For each new location, add all new IPs.
Sets.difference(newLocations, prevLocations).forEach(newLocation -> {
log.debug("HostMoved. addSubnet {}, {}", newLocation, prefix);
srManager.deviceConfiguration.addSubnet(newLocation, prefix);
// its a new connect point, not a move from an existing device, populateRoute
if (!oldDeviceIds.contains(newLocation.deviceId())) {
log.debug("HostMoved. populateRoute {}, {}, {}, {}", newLocation, prefix, hostMac, hostVlanId);
srManager.defaultRoutingHandler.populateRoute(newLocation.deviceId(), prefix, hostMac, hostVlanId, newLocation.port(), false);
}
});
newLocations.forEach(location -> {
processSingleLeafPairIfNeeded(newLocations, location, prefix, hostVlanId);
});
});
});
}
use of org.onosproject.net.Host in project trellis-control by opennetworkinglab.
the class HostHandlerTest method testHostUpdated.
@Test
public void testHostUpdated() {
Host host1 = new DefaultHost(PROVIDER_ID, HOST_ID_UNTAGGED, HOST_MAC, HOST_VLAN_UNTAGGED, Sets.newHashSet(HOST_LOC11), Sets.newHashSet(HOST_IP11), false);
Host host2 = new DefaultHost(PROVIDER_ID, HOST_ID_UNTAGGED, HOST_MAC, HOST_VLAN_UNTAGGED, Sets.newHashSet(HOST_LOC11), Sets.newHashSet(HOST_IP21), false);
Host host3 = new DefaultHost(PROVIDER_ID, HOST_ID_UNTAGGED, HOST_MAC, HOST_VLAN_UNTAGGED, Sets.newHashSet(HOST_LOC11), Sets.newHashSet(HOST_IP12), false);
// Add a host
// Expect: add one new routing rule. Add one new bridging rule.
hostHandler.processHostAddedEvent(new HostEvent(HostEvent.Type.HOST_ADDED, host1));
assertEquals(1, ROUTING_TABLE.size());
assertNotNull(ROUTING_TABLE.get(new MockRoutingTableKey(DEV1, HOST_IP11.toIpPrefix())));
assertNull(ROUTING_TABLE.get(new MockRoutingTableKey(DEV1, HOST_IP21.toIpPrefix())));
assertNull(ROUTING_TABLE.get(new MockRoutingTableKey(DEV1, HOST_IP12.toIpPrefix())));
assertEquals(1, BRIDGING_TABLE.size());
assertNotNull(BRIDGING_TABLE.get(new MockBridgingTableKey(HOST_LOC11.deviceId(), HOST_MAC, INTF_VLAN_UNTAGGED)));
// Update the host IP to same subnet
// Expect: update routing rule with new IP. No change to bridging rule.
hostHandler.processHostUpdatedEvent(new HostEvent(HostEvent.Type.HOST_UPDATED, host3, host1));
assertEquals(1, ROUTING_TABLE.size());
assertNull(ROUTING_TABLE.get(new MockRoutingTableKey(DEV1, HOST_IP11.toIpPrefix())));
assertNull(ROUTING_TABLE.get(new MockRoutingTableKey(DEV1, HOST_IP21.toIpPrefix())));
assertNotNull(ROUTING_TABLE.get(new MockRoutingTableKey(DEV1, HOST_IP12.toIpPrefix())));
assertEquals(1, BRIDGING_TABLE.size());
assertNotNull(BRIDGING_TABLE.get(new MockBridgingTableKey(DEV1, HOST_MAC, INTF_VLAN_UNTAGGED)));
// Update the host IP to different subnet
// Expect: Remove routing rule. No change to bridging rule.
hostHandler.processHostUpdatedEvent(new HostEvent(HostEvent.Type.HOST_UPDATED, host2, host3));
assertEquals(0, ROUTING_TABLE.size());
assertEquals(1, BRIDGING_TABLE.size());
assertNotNull(BRIDGING_TABLE.get(new MockBridgingTableKey(DEV1, HOST_MAC, INTF_VLAN_UNTAGGED)));
}
use of org.onosproject.net.Host in project trellis-control by opennetworkinglab.
the class HostHandlerTest method testHostRemoved.
@Test
public void testHostRemoved() {
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)));
// 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());
}
use of org.onosproject.net.Host in project trellis-control by opennetworkinglab.
the class HostHandlerTest method testDualHomingSingleLocationFail.
@Test
public void testDualHomingSingleLocationFail() {
Host host1 = new DefaultHost(PROVIDER_ID, HOST_ID_UNTAGGED, HOST_MAC, HOST_VLAN_UNTAGGED, Sets.newHashSet(HOST_LOC31, HOST_LOC41), Sets.newHashSet(HOST_IP11, HOST_IP12), false);
Host host2 = new DefaultHost(PROVIDER_ID, HOST_ID_UNTAGGED, HOST_MAC, HOST_VLAN_UNTAGGED, Sets.newHashSet(HOST_LOC31), Sets.newHashSet(HOST_IP11, HOST_IP12), false);
// Add a host
// Expect: add four new routing rules, two new bridging rules
hostHandler.processHostAddedEvent(new HostEvent(HostEvent.Type.HOST_ADDED, host1));
assertEquals(4, ROUTING_TABLE.size());
assertEquals(P1, ROUTING_TABLE.get(new MockRoutingTableKey(DEV3, HOST_IP11.toIpPrefix())).portNumber);
assertEquals(P1, ROUTING_TABLE.get(new MockRoutingTableKey(DEV3, HOST_IP12.toIpPrefix())).portNumber);
assertEquals(P1, ROUTING_TABLE.get(new MockRoutingTableKey(DEV4, HOST_IP11.toIpPrefix())).portNumber);
assertEquals(P1, ROUTING_TABLE.get(new MockRoutingTableKey(DEV4, HOST_IP12.toIpPrefix())).portNumber);
assertEquals(2, BRIDGING_TABLE.size());
assertEquals(P1, BRIDGING_TABLE.get(new MockBridgingTableKey(DEV3, HOST_MAC, INTF_VLAN_UNTAGGED)).portNumber);
assertEquals(P1, BRIDGING_TABLE.get(new MockBridgingTableKey(DEV4, HOST_MAC, INTF_VLAN_UNTAGGED)).portNumber);
// Host becomes single-homed
// Expect: redirect flows from host location to pair link
hostHandler.processHostMovedEvent(new HostEvent(HostEvent.Type.HOST_MOVED, host2, host1));
assertEquals(4, ROUTING_TABLE.size());
assertEquals(P1, ROUTING_TABLE.get(new MockRoutingTableKey(DEV3, HOST_IP11.toIpPrefix())).portNumber);
assertEquals(P1, ROUTING_TABLE.get(new MockRoutingTableKey(DEV3, HOST_IP12.toIpPrefix())).portNumber);
assertEquals(P9, ROUTING_TABLE.get(new MockRoutingTableKey(DEV4, HOST_IP11.toIpPrefix())).portNumber);
assertEquals(P9, ROUTING_TABLE.get(new MockRoutingTableKey(DEV4, HOST_IP12.toIpPrefix())).portNumber);
assertEquals(2, BRIDGING_TABLE.size());
assertEquals(P1, BRIDGING_TABLE.get(new MockBridgingTableKey(DEV3, HOST_MAC, INTF_VLAN_UNTAGGED)).portNumber);
assertEquals(P9, BRIDGING_TABLE.get(new MockBridgingTableKey(DEV4, HOST_MAC, INTF_VLAN_UNTAGGED)).portNumber);
// Host becomes dual-homed again
// Expect: Redirect flows from pair link back to host location
hostHandler.processHostMovedEvent(new HostEvent(HostEvent.Type.HOST_MOVED, host1, host2));
assertEquals(4, ROUTING_TABLE.size());
assertEquals(P1, ROUTING_TABLE.get(new MockRoutingTableKey(DEV3, HOST_IP11.toIpPrefix())).portNumber);
assertEquals(P1, ROUTING_TABLE.get(new MockRoutingTableKey(DEV3, HOST_IP12.toIpPrefix())).portNumber);
assertEquals(P1, ROUTING_TABLE.get(new MockRoutingTableKey(DEV4, HOST_IP11.toIpPrefix())).portNumber);
assertEquals(P1, ROUTING_TABLE.get(new MockRoutingTableKey(DEV4, HOST_IP12.toIpPrefix())).portNumber);
assertEquals(2, BRIDGING_TABLE.size());
assertEquals(P1, BRIDGING_TABLE.get(new MockBridgingTableKey(DEV3, HOST_MAC, INTF_VLAN_UNTAGGED)).portNumber);
assertEquals(P1, BRIDGING_TABLE.get(new MockBridgingTableKey(DEV4, HOST_MAC, INTF_VLAN_UNTAGGED)).portNumber);
}
use of org.onosproject.net.Host in project trellis-control by opennetworkinglab.
the class HostHandlerTest method testHostProbing.
@Test
public void testHostProbing() {
// Case: [1A/1, 1B/1] -> [1A/2, 1B/1]
// Expect: DISCOVER probe should be sent to every port on 1B that has the same VLAN as 1A/2
// VERIFY probe should be sent to 1B/1
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));
hostHandler.srManager.probingService = createMock(HostProbingService.class);
hostHandler.srManager.probingService.probeHost(host2, CP41, ProbeMode.DISCOVER);
expectLastCall();
hostHandler.srManager.probingService.probeHost(host2, CP42, ProbeMode.DISCOVER);
expectLastCall();
hostHandler.srManager.probingService.probeHost(host2, CP41, ProbeMode.VERIFY);
expectLastCall();
replay(hostHandler.srManager.probingService);
hostHandler.processHostMovedEvent(new HostEvent(HostEvent.Type.HOST_MOVED, host2, host1));
verify(hostHandler.srManager.probingService);
}
Aggregations