use of org.onosproject.net.host.HostDescription in project onos by opennetworkinglab.
the class K8sSwitchingHostProvider method processPortAdded.
/**
* Processes port addition event.
*
* @param port port object used in ONOS
*/
private void processPortAdded(Port port) {
K8sPort k8sPort = portToK8sPortByName(port);
if (k8sPort == null) {
k8sPort = portToK8sPortByMac(port);
if (k8sPort == null) {
log.warn(ERR_ADD_HOST + "Kubernetes port for {} not found", port);
return;
}
}
K8sNetwork k8sNet = k8sNetworkService.network(k8sPort.networkId());
if (k8sNet == null) {
log.warn(ERR_ADD_HOST + "Kubernetes network {} not found", k8sPort.networkId());
return;
}
MacAddress mac = k8sPort.macAddress();
HostId hostId = HostId.hostId(mac);
// connect point is the combination of switch ID with port number where
// the host is attached to
ConnectPoint connectPoint = new ConnectPoint(port.element().id(), port.number());
long createTime = System.currentTimeMillis();
// update k8s port number by referring to ONOS port number
k8sNetworkService.updatePort(k8sPort.updatePortNumber(port.number()).updateState(K8sPort.State.ACTIVE));
// we check whether the host already attached to same locations
Host host = hostService.getHost(hostId);
// build host annotations to include a set of meta info from neutron
DefaultAnnotations.Builder annotations = DefaultAnnotations.builder().set(ANNOTATION_NETWORK_ID, k8sPort.networkId()).set(ANNOTATION_PORT_ID, k8sPort.portId()).set(ANNOTATION_CREATE_TIME, String.valueOf(createTime)).set(ANNOTATION_SEGMENT_ID, k8sNet.segmentId());
HostDescription hostDesc = new DefaultHostDescription(mac, VlanId.NONE, new HostLocation(connectPoint, createTime), ImmutableSet.of(k8sPort.ipAddress()), annotations.build());
if (host != null) {
Set<HostLocation> locations = host.locations().stream().filter(l -> l.deviceId().equals(connectPoint.deviceId())).filter(l -> l.port().equals(connectPoint.port())).collect(Collectors.toSet());
// therefore, we simply add this into the location list
if (locations.isEmpty()) {
hostProviderService.addLocationToHost(hostId, new HostLocation(connectPoint, createTime));
}
// the hostDetected method invocation in turn triggers host Update event
if (locations.size() == 1) {
hostProviderService.hostDetected(hostId, hostDesc, false);
}
} else {
hostProviderService.hostDetected(hostId, hostDesc, false);
}
}
use of org.onosproject.net.host.HostDescription in project onos by opennetworkinglab.
the class Dhcp4HandlerImpl method handleDhcpAck.
/**
* Send the DHCP ack to the requester host.
* Modify Host or Route store according to the type of DHCP.
*
* @param ethernetPacketAck the packet
* @param dhcpPayload the DHCP data
*/
private void handleDhcpAck(Ethernet ethernetPacketAck, DHCP dhcpPayload) {
Optional<Interface> outInterface = getClientInterface(ethernetPacketAck, dhcpPayload);
if (!outInterface.isPresent()) {
log.warn("Can't find output interface for dhcp: {}", dhcpPayload);
return;
}
Interface outIface = outInterface.get();
ConnectPoint location = outIface.connectPoint();
if (!location.port().hasName()) {
location = translateSwitchPort(location);
}
HostLocation hostLocation = new HostLocation(location, System.currentTimeMillis());
MacAddress macAddress = MacAddress.valueOf(dhcpPayload.getClientHardwareAddress());
VlanId vlanId = getVlanIdFromRelayAgentOption(dhcpPayload);
if (vlanId == null) {
vlanId = outIface.vlan();
}
HostId hostId = HostId.hostId(macAddress, vlanId);
Ip4Address ip = Ip4Address.valueOf(dhcpPayload.getYourIPAddress());
if (directlyConnected(dhcpPayload)) {
// Add to host store if it connect to network directly
Set<IpAddress> ips = Sets.newHashSet(ip);
Host host = hostService.getHost(hostId);
Set<HostLocation> hostLocations = Sets.newHashSet(hostLocation);
if (host != null) {
// Dual homing support:
// if host exists, use old locations and new location
hostLocations.addAll(host.locations());
}
HostDescription desc = new DefaultHostDescription(macAddress, vlanId, hostLocations, ips, false);
// Add IP address when dhcp server give the host new ip address
providerService.hostDetected(hostId, desc, false);
} else {
// Add to route store if it does not connect to network directly
// Get gateway host IP according to host mac address
// TODO: remove relay store here
DhcpRecord record = dhcpRelayStore.getDhcpRecord(hostId).orElse(null);
if (record == null) {
log.warn("Can't find DHCP record of host {}", hostId);
return;
}
MacAddress gwMac = record.nextHop().orElse(null);
if (gwMac == null) {
log.warn("Can't find gateway mac address from record {}", record);
return;
}
HostId gwHostId = HostId.hostId(gwMac, record.vlanId());
Host gwHost = hostService.getHost(gwHostId);
if (gwHost == null) {
log.warn("Can't find gateway host {}", gwHostId);
return;
}
Ip4Address nextHopIp = gwHost.ipAddresses().stream().filter(IpAddress::isIp4).map(IpAddress::getIp4Address).findFirst().orElse(null);
if (nextHopIp == null) {
log.warn("Can't find IP address of gateway {}", gwHost);
return;
}
Route route = new Route(Route.Source.DHCP, ip.toIpPrefix(), nextHopIp);
routeStore.replaceRoute(route);
}
}
use of org.onosproject.net.host.HostDescription in project onos by opennetworkinglab.
the class DhcpRelayManagerTest method relayDhcp6WithoutAgentInfo.
/**
* Relay a DHCP6 packet without relay option
* Note: Should add new host to host store after dhcp ack.
*/
@Test
public void relayDhcp6WithoutAgentInfo() {
replay(mockHostProviderService);
// send request
packetService.processPacket(new TestDhcp6RequestPacketContext(DHCP6.MsgType.REQUEST.value(), CLIENT_MAC, CLIENT_VLAN, CLIENT_CP, INTERFACE_IP_V6.ipAddress().getIp6Address(), 0));
verify(mockHostProviderService);
reset(mockHostProviderService);
assertAfter(PKT_PROCESSING_MS, () -> assertEquals(0, mockRouteStore.routes.size()));
Capture<HostDescription> capturedHostDesc = newCapture();
mockHostProviderService.hostDetected(eq(HostId.hostId(CLIENT_MAC, CLIENT_VLAN)), capture(capturedHostDesc), eq(false));
replay(mockHostProviderService);
// send reply
packetService.processPacket(new TestDhcp6ReplyPacketContext(DHCP6.MsgType.REPLY.value(), CLIENT_CP, CLIENT_MAC, CLIENT_VLAN, INTERFACE_IP_V6.ipAddress().getIp6Address(), 0, false, CLIENT_VLAN));
assertAfter(PKT_PROCESSING_MS, () -> verify(mockHostProviderService));
assertAfter(PKT_PROCESSING_MS, () -> assertEquals(0, mockRouteStore.routes.size()));
HostDescription host = capturedHostDesc.getValue();
assertAfter(PKT_PROCESSING_MS, () -> assertEquals(CLIENT_VLAN, host.vlan()));
assertAfter(PKT_PROCESSING_MS, () -> assertEquals(CLIENT_CP.deviceId(), host.location().elementId()));
assertAfter(PKT_PROCESSING_MS, () -> assertEquals(CLIENT_CP.port(), host.location().port()));
assertAfter(PKT_PROCESSING_MS, () -> assertEquals(1, host.ipAddress().size()));
assertAfter(PKT_PROCESSING_MS, () -> assertEquals(IP_FOR_CLIENT_V6, host.ipAddress().iterator().next()));
// send release
packetService.processPacket(new TestDhcp6RequestPacketContext(DHCP6.MsgType.RELEASE.value(), CLIENT_MAC, CLIENT_VLAN, CLIENT_CP, INTERFACE_IP_V6.ipAddress().getIp6Address(), 0));
assertAfter(PKT_PROCESSING_MS, () -> assertNull(manager.hostService.getHost(HostId.hostId(CLIENT_MAC, CLIENT_VLAN))));
}
use of org.onosproject.net.host.HostDescription in project onos by opennetworkinglab.
the class DhcpRelayManagerTest method testDhcp4DualHome.
@Test
public void testDhcp4DualHome() {
PacketContext packetContext = new TestDhcpAckPacketContext(CLIENT_DH_CP, CLIENT_MAC, CLIENT_VLAN, INTERFACE_IP.ipAddress().getIp4Address(), false);
reset(manager.hostService);
expect(manager.hostService.getHost(CLIENT_HOST_ID)).andReturn(EXISTS_HOST).anyTimes();
Capture<HostDescription> capturedHostDesc = newCapture();
mockHostProviderService.hostDetected(eq(CLIENT_HOST_ID), capture(capturedHostDesc), eq(false));
replay(mockHostProviderService, manager.hostService);
packetService.processPacket(packetContext);
assertAfter(PKT_PROCESSING_MS, () -> verify(mockHostProviderService));
assertAfter(PKT_PROCESSING_MS, () -> assertTrue(capturedHostDesc.hasCaptured()));
HostDescription hostDesc = capturedHostDesc.getValue();
Set<HostLocation> hostLocations = hostDesc.locations();
assertAfter(PKT_PROCESSING_MS, () -> assertEquals(2, hostLocations.size()));
assertAfter(PKT_PROCESSING_MS, () -> assertTrue(hostLocations.contains(CLIENT_LOCATION)));
assertAfter(PKT_PROCESSING_MS, () -> assertTrue(hostLocations.contains(CLIENT_DH_LOCATION)));
}
use of org.onosproject.net.host.HostDescription in project onos by opennetworkinglab.
the class OpenstackSwitchingHostProvider method processPortAdded.
/**
* Processes port addition event.
* Once a port addition event is detected, it tries to create a host instance
* with openstack augmented host information such as networkId, portId,
* createTime, segmentId and notifies to host provider.
*
* @param port port object used in ONOS
*/
void processPortAdded(Port port) {
// TODO check the node state is COMPLETE
org.openstack4j.model.network.Port osPort = osNetworkService.port(port);
if (osPort == null) {
log.warn(ERR_ADD_HOST + "OpenStack port for {} not found", port);
return;
}
Network osNet = osNetworkService.network(osPort.getNetworkId());
if (osNet == null) {
log.warn(ERR_ADD_HOST + "OpenStack network {} not found", osPort.getNetworkId());
return;
}
if (osPort.getFixedIps().isEmpty()) {
log.warn(ERR_ADD_HOST + "no fixed IP for port {}", osPort.getId());
return;
}
MacAddress mac = MacAddress.valueOf(osPort.getMacAddress());
HostId hostId = HostId.hostId(mac);
/* typically one openstack port should only be bound to one fix IP address;
however, openstack4j binds multiple fixed IPs to one port, this might
be a defect of openstack4j implementation */
// TODO: we need to find a way to bind multiple ports from multiple
// openstack networks into one host sooner or later
Set<IpAddress> fixedIps = osPort.getFixedIps().stream().map(ip -> IpAddress.valueOf(ip.getIpAddress())).collect(Collectors.toSet());
// connect point is the combination of switch ID with port number where
// the host is attached to
ConnectPoint connectPoint = new ConnectPoint(port.element().id(), port.number());
long createTime = System.currentTimeMillis();
// we check whether the host already attached to same locations
Host host = hostService.getHost(hostId);
// build host annotations to include a set of meta info from neutron
DefaultAnnotations.Builder annotations = DefaultAnnotations.builder().set(ANNOTATION_NETWORK_ID, osPort.getNetworkId()).set(ANNOTATION_PORT_ID, osPort.getId()).set(ANNOTATION_CREATE_TIME, String.valueOf(createTime));
// FLAT typed network does not require segment ID
Type netType = osNetworkService.networkType(osNet.getId());
if (netType != FLAT) {
annotations.set(ANNOTATION_SEGMENT_ID, osNet.getProviderSegID());
}
// build host description object
HostDescription hostDesc = new DefaultHostDescription(mac, VlanId.NONE, new HostLocation(connectPoint, createTime), fixedIps, annotations.build());
if (host != null) {
Set<HostLocation> locations = host.locations().stream().filter(l -> l.deviceId().equals(connectPoint.deviceId())).filter(l -> l.port().equals(connectPoint.port())).collect(Collectors.toSet());
// therefore, we simply add this into the location list
if (locations.isEmpty()) {
hostProviderService.addLocationToHost(hostId, new HostLocation(connectPoint, createTime));
}
// the hostDetected method invocation in turn triggers host Update event
if (locations.size() == 1) {
hostProviderService.hostDetected(hostId, hostDesc, false);
}
} else {
hostProviderService.hostDetected(hostId, hostDesc, false);
}
}
Aggregations