Search in sources :

Example 6 with HostLocation

use of org.onosproject.net.HostLocation in project onos by opennetworkinglab.

the class DistributedDhcpRelayStoreTest method testPutAndRemoveRecord.

/**
 * Puts and removes a record, should received UPDATED and REMOVED event.
 */
@Test
public void testPutAndRemoveRecord() {
    // dhcp request, no IP
    HostId hostId = HostId.hostId(MAC, VLAN_ID);
    DhcpRecord record = new DhcpRecord(hostId);
    record.addLocation(new HostLocation(CP, System.currentTimeMillis()));
    record.setDirectlyConnected(true);
    record.nextHop(GW_MAC);
    record.ip4Status(DHCPREQUEST);
    CompletableFuture<DhcpRelayStoreEvent> recordComplete = new CompletableFuture<>();
    store.setDelegate(recordComplete::complete);
    store.updateDhcpRecord(HOST_ID, record);
    DhcpRelayStoreEvent event = recordComplete.join();
    assertEquals(record, event.subject());
    assertEquals(DhcpRelayStoreEvent.Type.UPDATED, event.type());
    DhcpRecord recordInStore = store.getDhcpRecord(HOST_ID).orElse(null);
    assertNotNull(recordInStore);
    assertEquals(record, recordInStore);
    Collection<DhcpRecord> recordsInStore = store.getDhcpRecords();
    assertEquals(1, recordsInStore.size());
    assertEquals(record, recordsInStore.iterator().next());
    // dhcp request, with IP
    record = new DhcpRecord(hostId);
    record.addLocation(new HostLocation(CP, System.currentTimeMillis()));
    record.setDirectlyConnected(true);
    record.ip4Address(IP);
    record.nextHop(GW_MAC);
    record.ip4Status(DHCPREQUEST);
    recordComplete = new CompletableFuture<>();
    store.setDelegate(recordComplete::complete);
    store.updateDhcpRecord(HOST_ID, record);
    event = recordComplete.join();
    DhcpRecord subject = event.subject();
    assertEquals(record.locations(), subject.locations());
    assertEquals(record.vlanId(), subject.vlanId());
    assertEquals(record.macAddress(), subject.macAddress());
    assertEquals(record.ip4Address(), subject.ip4Address());
    assertEquals(record.nextHop(), subject.nextHop());
    assertEquals(record.ip4Status(), subject.ip4Status());
    assertEquals(record.ip6Address(), subject.ip6Address());
    assertEquals(record.ip6Status(), subject.ip6Status());
    assertEquals(record.directlyConnected(), subject.directlyConnected());
    assertEquals(DhcpRelayStoreEvent.Type.UPDATED, event.type());
    recordInStore = store.getDhcpRecord(HOST_ID).orElse(null);
    assertNotNull(recordInStore);
    assertEquals(record.locations(), recordInStore.locations());
    assertEquals(record.vlanId(), recordInStore.vlanId());
    assertEquals(record.macAddress(), recordInStore.macAddress());
    assertEquals(record.ip4Address(), recordInStore.ip4Address());
    assertEquals(record.nextHop(), recordInStore.nextHop());
    assertEquals(record.ip4Status(), recordInStore.ip4Status());
    assertEquals(record.ip6Address(), recordInStore.ip6Address());
    assertEquals(record.ip6Status(), recordInStore.ip6Status());
    assertEquals(record.directlyConnected(), recordInStore.directlyConnected());
    recordsInStore = store.getDhcpRecords();
    assertEquals(1, recordsInStore.size());
    // removes record
    recordComplete = new CompletableFuture<>();
    store.setDelegate(recordComplete::complete);
    DhcpRecord removedRecord = store.removeDhcpRecord(HOST_ID).orElse(null);
    assertEquals(record.locations(), removedRecord.locations());
    assertEquals(record.vlanId(), removedRecord.vlanId());
    assertEquals(record.macAddress(), removedRecord.macAddress());
    assertEquals(record.ip4Address(), removedRecord.ip4Address());
    assertEquals(record.nextHop(), removedRecord.nextHop());
    assertEquals(record.ip4Status(), removedRecord.ip4Status());
    assertEquals(record.ip6Address(), removedRecord.ip6Address());
    assertEquals(record.ip6Status(), removedRecord.ip6Status());
    assertEquals(record.directlyConnected(), removedRecord.directlyConnected());
    event = recordComplete.join();
    assertEquals(record, event.subject());
    assertEquals(DhcpRelayStoreEvent.Type.REMOVED, event.type());
    recordInStore = store.getDhcpRecord(HOST_ID).orElse(null);
    assertNull(recordInStore);
    recordsInStore = store.getDhcpRecords();
    assertEquals(0, recordsInStore.size());
}
Also used : CompletableFuture(java.util.concurrent.CompletableFuture) HostLocation(org.onosproject.net.HostLocation) HostId(org.onosproject.net.HostId) Test(org.junit.Test)

Example 7 with HostLocation

use of org.onosproject.net.HostLocation 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);
    }
}
Also used : HostLocation(org.onosproject.net.HostLocation) K8sNetworkingUtil.existingContainerPortByName(org.onosproject.k8snetworking.util.K8sNetworkingUtil.existingContainerPortByName) CoreService(org.onosproject.core.CoreService) DeviceService(org.onosproject.net.device.DeviceService) LoggerFactory(org.slf4j.LoggerFactory) Tools.groupedThreads(org.onlab.util.Tools.groupedThreads) K8sNodeListener(org.onosproject.k8snode.api.K8sNodeListener) K8sNetworkListener(org.onosproject.k8snetworking.api.K8sNetworkListener) ConnectPoint(org.onosproject.net.ConnectPoint) HostProviderService(org.onosproject.net.host.HostProviderService) Port(org.onosproject.net.Port) PORT_MAC(org.onosproject.net.AnnotationKeys.PORT_MAC) K8sNetworkingUtil.isContainer(org.onosproject.k8snetworking.util.K8sNetworkingUtil.isContainer) MastershipService(org.onosproject.mastership.MastershipService) ANNOTATION_CREATE_TIME(org.onosproject.k8snetworking.api.Constants.ANNOTATION_CREATE_TIME) ImmutableSet(com.google.common.collect.ImmutableSet) Device(org.onosproject.net.Device) Deactivate(org.osgi.service.component.annotations.Deactivate) Set(java.util.Set) Collectors(java.util.stream.Collectors) Executors(java.util.concurrent.Executors) GENEVE(org.onosproject.k8snetworking.api.Constants.GENEVE) DeviceEvent(org.onosproject.net.device.DeviceEvent) K8sNetworkAdminService(org.onosproject.k8snetworking.api.K8sNetworkAdminService) DeviceId(org.onosproject.net.DeviceId) HostDescription(org.onosproject.net.host.HostDescription) INIT(org.onosproject.k8snode.api.K8sNodeState.INIT) HostProviderRegistry(org.onosproject.net.host.HostProviderRegistry) Tools(org.onlab.util.Tools) Host(org.onosproject.net.Host) PORT_NAME(org.onosproject.net.AnnotationKeys.PORT_NAME) GRE(org.onosproject.k8snetworking.api.Constants.GRE) HostService(org.onosproject.net.host.HostService) Strings(com.google.common.base.Strings) DefaultHostDescription(org.onosproject.net.host.DefaultHostDescription) Component(org.osgi.service.component.annotations.Component) ANNOTATION_PORT_ID(org.onosproject.k8snetworking.api.Constants.ANNOTATION_PORT_ID) ANNOTATION_NETWORK_ID(org.onosproject.k8snetworking.api.Constants.ANNOTATION_NETWORK_ID) K8sNetworkEvent(org.onosproject.k8snetworking.api.K8sNetworkEvent) K8sPort(org.onosproject.k8snetworking.api.K8sPort) K8sNodeEvent(org.onosproject.k8snode.api.K8sNodeEvent) Activate(org.osgi.service.component.annotations.Activate) K8sNode(org.onosproject.k8snode.api.K8sNode) HostId(org.onosproject.net.HostId) ExecutorService(java.util.concurrent.ExecutorService) K8S_NETWORKING_APP_ID(org.onosproject.k8snetworking.api.Constants.K8S_NETWORKING_APP_ID) AbstractProvider(org.onosproject.net.provider.AbstractProvider) DeviceListener(org.onosproject.net.device.DeviceListener) Logger(org.slf4j.Logger) HostProvider(org.onosproject.net.host.HostProvider) VXLAN(org.onosproject.k8snetworking.api.Constants.VXLAN) VlanId(org.onlab.packet.VlanId) K8sHostService(org.onosproject.k8snode.api.K8sHostService) ProviderId(org.onosproject.net.provider.ProviderId) ANNOTATION_SEGMENT_ID(org.onosproject.k8snetworking.api.Constants.ANNOTATION_SEGMENT_ID) ReferenceCardinality(org.osgi.service.component.annotations.ReferenceCardinality) DefaultAnnotations(org.onosproject.net.DefaultAnnotations) K8sNetworkingUtil.existingContainerPortByMac(org.onosproject.k8snetworking.util.K8sNetworkingUtil.existingContainerPortByMac) K8sNetwork(org.onosproject.k8snetworking.api.K8sNetwork) K8sNetworkingUtil.allK8sDevices(org.onosproject.k8snetworking.util.K8sNetworkingUtil.allK8sDevices) MacAddress(org.onlab.packet.MacAddress) K8sNodeService(org.onosproject.k8snode.api.K8sNodeService) Reference(org.osgi.service.component.annotations.Reference) DefaultHostDescription(org.onosproject.net.host.DefaultHostDescription) DefaultAnnotations(org.onosproject.net.DefaultAnnotations) Host(org.onosproject.net.Host) MacAddress(org.onlab.packet.MacAddress) HostId(org.onosproject.net.HostId) ConnectPoint(org.onosproject.net.ConnectPoint) HostDescription(org.onosproject.net.host.HostDescription) DefaultHostDescription(org.onosproject.net.host.DefaultHostDescription) K8sNetwork(org.onosproject.k8snetworking.api.K8sNetwork) HostLocation(org.onosproject.net.HostLocation) K8sPort(org.onosproject.k8snetworking.api.K8sPort)

Example 8 with HostLocation

use of org.onosproject.net.HostLocation 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);
    }
}
Also used : DefaultHostDescription(org.onosproject.net.host.DefaultHostDescription) Ip4Address(org.onlab.packet.Ip4Address) Host(org.onosproject.net.Host) DhcpRecord(org.onosproject.dhcprelay.store.DhcpRecord) MacAddress(org.onlab.packet.MacAddress) HostId(org.onosproject.net.HostId) ConnectPoint(org.onosproject.net.ConnectPoint) HostDescription(org.onosproject.net.host.HostDescription) DefaultHostDescription(org.onosproject.net.host.DefaultHostDescription) HostLocation(org.onosproject.net.HostLocation) InterfaceIpAddress(org.onosproject.net.host.InterfaceIpAddress) IpAddress(org.onlab.packet.IpAddress) Interface(org.onosproject.net.intf.Interface) VlanId(org.onlab.packet.VlanId) Route(org.onosproject.routeservice.Route)

Example 9 with HostLocation

use of org.onosproject.net.HostLocation in project onos by opennetworkinglab.

the class Dhcp6HandlerImpl method removeHostOrRoute.

/**
 * remove host or route and update dhcp relay record attributes.
 *
 * @param directConnFlag  flag to show that packet is from directly connected client
 * @param location  client side connect point
 * @param dhcp6Packet the dhcp6 payload
 * @param clientPacket client's ethernet packet
 * @param clientIpv6 client's Ipv6 packet
 * @param clientInterface client interfaces
 */
private void removeHostOrRoute(boolean directConnFlag, ConnectPoint location, DHCP6 dhcp6Packet, Ethernet clientPacket, IPv6 clientIpv6, Interface clientInterface) {
    log.debug("removeHostOrRoute  enters {}", dhcp6Packet);
    VlanId vlanId = clientInterface.vlan();
    // could be gw or host
    MacAddress srcMac = clientPacket.getSourceMAC();
    MacAddress leafClientMac;
    byte leafMsgType;
    log.debug("client mac {} client vlan {}", HexString.toHexString(srcMac.toBytes(), ":"), vlanId);
    Dhcp6ClientIdOption clientIdOption = Dhcp6HandlerUtil.extractClientId(directConnFlag, dhcp6Packet);
    if (clientIdOption != null) {
        if ((clientIdOption.getDuid().getDuidType() == Dhcp6Duid.DuidType.DUID_LLT) || (clientIdOption.getDuid().getDuidType() == Dhcp6Duid.DuidType.DUID_LL)) {
            leafClientMac = MacAddress.valueOf(clientIdOption.getDuid().getLinkLayerAddress());
        } else {
            log.warn("Link-Layer Address not supported in CLIENTID option. No DhcpRelay Record created.");
            // dhcpRelayCountersStore.incrementCounter(gCount, DhcpRelayCounters.NO_LINKLOCAL_FAIL);
            return;
        }
    } else {
        log.warn("CLIENTID option NOT found. Don't create DhcpRelay Record.");
        // dhcpRelayCountersStore.incrementCounter(gCount, DhcpRelayCounters.NO_CLIENTID_FAIL);
        return;
    }
    HostId leafHostId = HostId.hostId(leafClientMac, vlanId);
    DhcpRecord record = dhcpRelayStore.getDhcpRecord(leafHostId).orElse(null);
    if (record == null) {
        record = new DhcpRecord(leafHostId);
    } else {
        record = record.clone();
    }
    Boolean isMsgRelease = Dhcp6HandlerUtil.isDhcp6Release(dhcp6Packet);
    IpAddressInfo ipInfo;
    PdPrefixInfo pdInfo = null;
    if (directConnFlag) {
        // Add to host store if it is connected to network directly
        ipInfo = extractIpAddress(dhcp6Packet);
        if (ipInfo != null) {
            if (isMsgRelease) {
                HostId hostId = HostId.hostId(srcMac, vlanId);
                log.debug("remove Host {} ip for directly connected.", hostId.toString());
                providerService.removeIpFromHost(hostId, ipInfo.ip6Address);
            }
        } else {
            log.debug("ipAddress not found. Do not remove Host {} for directly connected.", HostId.hostId(srcMac, vlanId).toString());
        }
        leafMsgType = dhcp6Packet.getMsgType();
    } else {
        // Remove from route store if it is not connected to network directly
        // pick out the first link-local ip address
        IpAddress nextHopIp = getFirstIpByHost(directConnFlag, srcMac, vlanId);
        if (nextHopIp == null) {
            log.warn("Can't find link-local IP address of gateway mac {} vlanId {}", srcMac, vlanId);
            // dhcpRelayCountersStore.incrementCounter(gCount, DhcpRelayCounters.NO_LINKLOCAL_GW);
            return;
        }
        DHCP6 leafDhcp = Dhcp6HandlerUtil.getDhcp6Leaf(dhcp6Packet);
        ipInfo = extractIpAddress(leafDhcp);
        if (ipInfo == null) {
            log.debug("ip is null");
        } else {
            if (isMsgRelease) {
                Route routeForIP = new Route(Route.Source.DHCP, ipInfo.ip6Address.toIpPrefix(), nextHopIp);
                log.debug("removing route of 128 address for indirectly connected.");
                log.debug("128 ip {}, nexthop {}", HexString.toHexString(ipInfo.ip6Address.toOctets(), ":"), HexString.toHexString(nextHopIp.toOctets(), ":"));
                routeStore.removeRoute(routeForIP);
            }
        }
        pdInfo = extractPrefix(leafDhcp);
        if (pdInfo == null) {
            log.debug("ipPrefix is null ");
        } else {
            if (isMsgRelease) {
                Route routeForPrefix = new Route(Route.Source.DHCP, pdInfo.pdPrefix, nextHopIp);
                log.debug("removing route of PD for indirectly connected.");
                log.debug("pd ip {}, nexthop {}", HexString.toHexString(pdInfo.pdPrefix.address().toOctets(), ":"), HexString.toHexString(nextHopIp.toOctets(), ":"));
                routeStore.removeRoute(routeForPrefix);
                if (this.dhcpFpmEnabled) {
                    dhcpFpmPrefixStore.removeFpmRecord(pdInfo.pdPrefix);
                }
            }
        }
        leafMsgType = leafDhcp.getMsgType();
    }
    if (isMsgRelease) {
        log.debug("DHCP6 RELEASE msg.");
        if (record != null) {
            if (ipInfo != null) {
                log.debug("DhcpRelay Record ip6Address is set to null.");
                record.ip6Address(null);
            }
            if (pdInfo != null) {
                log.debug("DhcpRelay Record pdPrefix is set to null.");
            }
            if (!record.ip6Address().isPresent() && !record.pdPrefix().isPresent()) {
                log.warn("IP6 address and IP6 PD both are null. Remove record.");
            // do not remove a record. Let timer task handler it.
            // dhcpRelayStore.removeDhcpRecord(HostId.hostId(leafClientMac, vlanId));
            }
        }
    }
    if (record != null) {
        record.getV6Counters().incrementCounter(Dhcp6HandlerUtil.getMsgTypeStr(leafMsgType));
        record.addLocation(new HostLocation(location, System.currentTimeMillis()));
        record.ip6Status(DHCP6.MsgType.getType(leafMsgType));
        record.setDirectlyConnected(directConnFlag);
        if (!directConnFlag) {
            // Update gateway mac address if the host is not directly connected
            record.nextHop(srcMac);
        }
        record.updateLastSeen();
    }
    dhcpRelayStore.updateDhcpRecord(leafHostId, record);
/*
        // TODO Use AtomicInteger for the counters
        try {
            recordSemaphore.acquire();
            try {
                dhcpRelayCountersStore.incrementCounter(gCount, Dhcp6HandlerUtil.getMsgTypeStr(leafMsgType));
            } finally {
                // calling release() after a successful acquire()
                recordSemaphore.release();
            }
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
        */
}
Also used : DhcpRecord(org.onosproject.dhcprelay.store.DhcpRecord) MacAddress(org.onlab.packet.MacAddress) HostId(org.onosproject.net.HostId) HostLocation(org.onosproject.net.HostLocation) IpAddress(org.onlab.packet.IpAddress) DHCP6(org.onlab.packet.DHCP6) VlanId(org.onlab.packet.VlanId) Route(org.onosproject.routeservice.Route) Dhcp6ClientIdOption(org.onlab.packet.dhcp.Dhcp6ClientIdOption)

Example 10 with HostLocation

use of org.onosproject.net.HostLocation in project onos by opennetworkinglab.

the class Dhcp6HandlerUtil method processLQ6PacketFromServer.

/**
 * process the LQ reply packet from dhcp server.
 *
 * @param defaultServerInfoList default server list
 * @param indirectServerInfoList default indirect server list
 * @param serverInterface server interface
 * @param interfaceService interface service
 * @param hostService host service
 * @param context packet context
 * @param receivedPacket server ethernet packet
 * @param recevingInterfaces set of server side interfaces
 * @return a packet ready to be sent to relevant output interface
 */
public static InternalPacket processLQ6PacketFromServer(List<DhcpServerInfo> defaultServerInfoList, List<DhcpServerInfo> indirectServerInfoList, Interface serverInterface, InterfaceService interfaceService, HostService hostService, PacketContext context, Ethernet receivedPacket, Set<Interface> recevingInterfaces) {
    // get dhcp6 header.
    Ethernet etherReply = (Ethernet) receivedPacket.clone();
    IPv6 ipv6Packet = (IPv6) etherReply.getPayload();
    UDP udpPacket = (UDP) ipv6Packet.getPayload();
    DHCP6 lq6Reply = (DHCP6) udpPacket.getPayload();
    // TODO: refactor
    ConnectPoint receivedFrom = context.inPacket().receivedFrom();
    DeviceId receivedFromDevice = receivedFrom.deviceId();
    DhcpServerInfo serverInfo;
    Ip6Address dhcpServerIp = null;
    ConnectPoint dhcpServerConnectPoint = null;
    MacAddress dhcpConnectMac = null;
    VlanId dhcpConnectVlan = null;
    Ip6Address dhcpGatewayIp = null;
    // todo: refactor
    Ip6Address indirectDhcpServerIp = null;
    ConnectPoint indirectDhcpServerConnectPoint = null;
    MacAddress indirectDhcpConnectMac = null;
    VlanId indirectDhcpConnectVlan = null;
    Ip6Address indirectDhcpGatewayIp = null;
    Ip6Address indirectRelayAgentIpFromCfg = null;
    if (!defaultServerInfoList.isEmpty()) {
        serverInfo = defaultServerInfoList.get(0);
        dhcpConnectMac = serverInfo.getDhcpConnectMac().orElse(null);
        dhcpGatewayIp = serverInfo.getDhcpGatewayIp6().orElse(null);
        dhcpServerIp = serverInfo.getDhcpServerIp6().orElse(null);
        dhcpServerConnectPoint = serverInfo.getDhcpServerConnectPoint().orElse(null);
        dhcpConnectVlan = serverInfo.getDhcpConnectVlan().orElse(null);
    }
    if (!indirectServerInfoList.isEmpty()) {
        serverInfo = indirectServerInfoList.get(0);
        indirectDhcpConnectMac = serverInfo.getDhcpConnectMac().orElse(null);
        indirectDhcpGatewayIp = serverInfo.getDhcpGatewayIp6().orElse(null);
        indirectDhcpServerIp = serverInfo.getDhcpServerIp6().orElse(null);
        indirectDhcpServerConnectPoint = serverInfo.getDhcpServerConnectPoint().orElse(null);
        indirectDhcpConnectVlan = serverInfo.getDhcpConnectVlan().orElse(null);
        indirectRelayAgentIpFromCfg = serverInfo.getRelayAgentIp6(receivedFromDevice).orElse(null);
    }
    Boolean directConnFlag = directlyConnected(lq6Reply);
    ConnectPoint inPort = context.inPacket().receivedFrom();
    if ((directConnFlag || indirectDhcpServerIp == null) && !inPort.equals(dhcpServerConnectPoint)) {
        log.warn("Receiving port {} is not the same as server connect point {} for direct or indirect-null", inPort, dhcpServerConnectPoint);
        return null;
    }
    if (!directConnFlag && indirectDhcpServerIp != null && !inPort.equals(indirectDhcpServerConnectPoint)) {
        log.warn("Receiving port {} is not the same as server connect point {} for indirect", inPort, indirectDhcpServerConnectPoint);
        return null;
    }
    Ip6Address nextHopIP = Ip6Address.valueOf(ipv6Packet.getDestinationAddress());
    // use hosts store to find out the next hop mac and connection point
    Set<Host> hosts = hostService.getHostsByIp(nextHopIP);
    Host host;
    if (!hosts.isEmpty()) {
        host = hosts.iterator().next();
    } else {
        log.warn("Host {} is not in store", nextHopIP);
        return null;
    }
    HostLocation hl = host.location();
    // iterator().next());
    String clientConnectionPointStr = hl.toString();
    ConnectPoint clientConnectionPoint = ConnectPoint.deviceConnectPoint(clientConnectionPointStr);
    VlanId originalPacketVlanId = VlanId.vlanId(etherReply.getVlanID());
    Interface iface;
    iface = interfaceService.getInterfacesByPort(clientConnectionPoint).stream().filter(iface1 -> interfaceContainsVlan(iface1, originalPacketVlanId)).findFirst().orElse(null);
    etherReply.setSourceMACAddress(iface.mac());
    etherReply.setDestinationMACAddress(host.mac());
    // workaround for a bug where core sends src port as 547 (server)
    udpPacket.setDestinationPort(UDP.DHCP_V6_SERVER_PORT);
    udpPacket.setPayload(lq6Reply);
    udpPacket.resetChecksum();
    ipv6Packet.setPayload(udpPacket);
    etherReply.setPayload(ipv6Packet);
    return InternalPacket.internalPacket(etherReply, clientConnectionPoint);
}
Also used : UDP(org.onlab.packet.UDP) HostLocation(org.onosproject.net.HostLocation) Host(org.onosproject.net.Host) Interface(org.onosproject.net.intf.Interface) LoggerFactory(org.slf4j.LoggerFactory) InterfaceService(org.onosproject.net.intf.InterfaceService) HostService(org.onosproject.net.host.HostService) Dhcp6ClientIdOption(org.onlab.packet.dhcp.Dhcp6ClientIdOption) Dhcp6RelayOption(org.onlab.packet.dhcp.Dhcp6RelayOption) ConnectPoint(org.onosproject.net.ConnectPoint) ArrayList(java.util.ArrayList) Ethernet(org.onlab.packet.Ethernet) DhcpRelayCounters(org.onosproject.dhcprelay.store.DhcpRelayCounters) IpAddress(org.onlab.packet.IpAddress) BasePacket(org.onlab.packet.BasePacket) DhcpServerInfo(org.onosproject.dhcprelay.api.DhcpServerInfo) Ip6Address(org.onlab.packet.Ip6Address) Logger(org.slf4j.Logger) VlanId(org.onlab.packet.VlanId) Preconditions.checkNotNull(com.google.common.base.Preconditions.checkNotNull) Dhcp6Option(org.onlab.packet.dhcp.Dhcp6Option) Set(java.util.Set) MsgType(org.onlab.packet.DHCP6.MsgType) InterfaceIpAddress(org.onosproject.net.host.InterfaceIpAddress) UDP(org.onlab.packet.UDP) IPv6(org.onlab.packet.IPv6) DHCP6(org.onlab.packet.DHCP6) List(java.util.List) HexString(org.onlab.util.HexString) PacketContext(org.onosproject.net.packet.PacketContext) MacAddress(org.onlab.packet.MacAddress) DeviceId(org.onosproject.net.DeviceId) IPv6(org.onlab.packet.IPv6) DeviceId(org.onosproject.net.DeviceId) Host(org.onosproject.net.Host) HexString(org.onlab.util.HexString) MacAddress(org.onlab.packet.MacAddress) ConnectPoint(org.onosproject.net.ConnectPoint) Ip6Address(org.onlab.packet.Ip6Address) Ethernet(org.onlab.packet.Ethernet) HostLocation(org.onosproject.net.HostLocation) DHCP6(org.onlab.packet.DHCP6) DhcpServerInfo(org.onosproject.dhcprelay.api.DhcpServerInfo) VlanId(org.onlab.packet.VlanId) Interface(org.onosproject.net.intf.Interface)

Aggregations

HostLocation (org.onosproject.net.HostLocation)52 IpAddress (org.onlab.packet.IpAddress)29 MacAddress (org.onlab.packet.MacAddress)25 VlanId (org.onlab.packet.VlanId)22 HostId (org.onosproject.net.HostId)22 Host (org.onosproject.net.Host)19 ConnectPoint (org.onosproject.net.ConnectPoint)15 Test (org.junit.Test)14 DefaultHost (org.onosproject.net.DefaultHost)14 DeviceId (org.onosproject.net.DeviceId)12 HostDescription (org.onosproject.net.host.HostDescription)11 ProviderId (org.onosproject.net.provider.ProviderId)11 Set (java.util.Set)10 DefaultHostDescription (org.onosproject.net.host.DefaultHostDescription)10 Logger (org.slf4j.Logger)8 ImmutableSet (com.google.common.collect.ImmutableSet)7 Collectors (java.util.stream.Collectors)7 PortNumber (org.onosproject.net.PortNumber)7 DeviceEvent (org.onosproject.net.device.DeviceEvent)7 HostService (org.onosproject.net.host.HostService)7