Search in sources :

Example 46 with HostLocation

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

the class Dhcp6HandlerImpl method addHostOrRoute.

/**
 * add host or route and update dhcp relay record.
 *
 * @param directConnFlag  flag to show that packet is from directly connected client
 * @param location  client side connect point
 * @param dhcp6Relay the dhcp6 payload
 * @param embeddedDhcp6 the dhcp6 payload within relay
 * @param srcMac client gw/host macAddress
 * @param clientInterface client interface
 * @param vlanIdInUse vlanid encoded in the interface id Option
 */
private void addHostOrRoute(boolean directConnFlag, ConnectPoint location, DHCP6 dhcp6Relay, DHCP6 embeddedDhcp6, MacAddress srcMac, Interface clientInterface, VlanId vlanIdInUse) {
    log.debug("addHostOrRoute entered.");
    VlanId vlanId;
    if (clientInterface.vlanTagged().isEmpty()) {
        vlanId = clientInterface.vlan();
    } else {
        // might be multiple vlan in same interface
        vlanId = vlanIdInUse;
    }
    if (vlanId == null) {
        vlanId = VlanId.NONE;
    }
    Boolean isMsgReply = Dhcp6HandlerUtil.isDhcp6Reply(dhcp6Relay);
    MacAddress leafClientMac;
    Byte leafMsgType;
    Dhcp6ClientIdOption clientIdOption = Dhcp6HandlerUtil.extractClientId(directConnFlag, embeddedDhcp6);
    if (clientIdOption != null) {
        log.debug("CLIENTID option found {}", clientIdOption);
        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. No DhcpRelay Record created.");
        // 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(HostId.hostId(leafClientMac, vlanId));
    } else {
        record = record.clone();
    }
    IpAddressInfo ipInfo;
    PdPrefixInfo pdInfo = null;
    if (directConnFlag) {
        // Add to host store if it connect to network directly
        ipInfo = extractIpAddress(embeddedDhcp6);
        if (ipInfo != null) {
            if (isMsgReply) {
                Set<IpAddress> ips = Sets.newHashSet(ipInfo.ip6Address);
                HostId hostId = HostId.hostId(srcMac, vlanId);
                Host host = hostService.getHost(hostId);
                HostLocation hostLocation = new HostLocation(clientInterface.connectPoint(), System.currentTimeMillis());
                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(srcMac, vlanId, hostLocations, ips, false);
                log.debug("adding Host for directly connected.");
                log.debug("client mac {} client vlan {} hostlocation {}", HexString.toHexString(srcMac.toBytes(), ":"), vlanId, hostLocation.toString());
                // Replace the ip when dhcp server give the host new ip address
                providerService.hostDetected(hostId, desc, false);
            }
        } else {
            log.warn("ipAddress not found. Do not add Host {} for directly connected.", HostId.hostId(srcMac, vlanId).toString());
        }
        leafMsgType = embeddedDhcp6.getMsgType();
    } else {
        // Add to route store if it does not connect 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(embeddedDhcp6);
        ipInfo = extractIpAddress(leafDhcp);
        if (ipInfo == null) {
            log.debug("ip is null");
        } else {
            if (isMsgReply) {
                Route routeForIP = new Route(Route.Source.DHCP, ipInfo.ip6Address.toIpPrefix(), nextHopIp);
                log.debug("adding Route of 128 address for indirectly connected.");
                routeStore.replaceRoute(routeForIP);
            }
        }
        pdInfo = extractPrefix(leafDhcp);
        if (pdInfo == null) {
            log.debug("ipPrefix is null ");
        } else {
            if (isMsgReply) {
                Route routeForPrefix = new Route(Route.Source.DHCP, pdInfo.pdPrefix, nextHopIp);
                log.debug("adding Route of PD for indirectly connected.");
                routeStore.replaceRoute(routeForPrefix);
                if (this.dhcpFpmEnabled) {
                    FpmRecord fpmRecord = new FpmRecord(pdInfo.pdPrefix, nextHopIp, FpmRecord.Type.DHCP_RELAY);
                    dhcpFpmPrefixStore.addFpmRecord(pdInfo.pdPrefix, fpmRecord);
                }
            }
        }
        leafMsgType = leafDhcp.getMsgType();
    }
    if (leafMsgType == DHCP6.MsgType.RELEASE.value() || (leafMsgType == DHCP6.MsgType.REPLY.value()) && ipInfo == null) {
        log.warn("DHCP6 RELEASE/REPLY(null ip) from Server. MsgType {}", leafMsgType);
    // return;
    }
    record.addLocation(new HostLocation(location, System.currentTimeMillis()));
    if (leafMsgType == DHCP6.MsgType.REPLY.value()) {
        if (ipInfo != null) {
            log.debug("IP6 address is being stored into dhcp-relay store.");
            log.debug("Client IP6 address {}", HexString.toHexString(ipInfo.ip6Address.toOctets(), ":"));
            record.ip6Address(ipInfo.ip6Address);
            record.updateAddrPrefTime(ipInfo.prefTime);
            record.updateLastIp6Update();
        } else {
            log.debug("IP6 address is not returned from server. Maybe only PD is returned.");
        }
        if (pdInfo != null) {
            log.debug("IP6 PD address {}", HexString.toHexString(pdInfo.pdPrefix.address().toOctets(), ":"));
            record.pdPrefix(pdInfo.pdPrefix);
            record.updatePdPrefTime(pdInfo.prefTime);
            record.updateLastPdUpdate();
        } else {
            log.debug("IP6 PD address is not returned from server. Maybe only IPAddress is returned.");
        }
    }
    record.getV6Counters().incrementCounter(Dhcp6HandlerUtil.getMsgTypeStr(leafMsgType));
    record.ip6Status(DHCP6.MsgType.getType(leafMsgType));
    record.setDirectlyConnected(directConnFlag);
    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 : DefaultHostDescription(org.onosproject.net.host.DefaultHostDescription) DhcpRecord(org.onosproject.dhcprelay.store.DhcpRecord) Host(org.onosproject.net.Host) MacAddress(org.onlab.packet.MacAddress) HostId(org.onosproject.net.HostId) HostDescription(org.onosproject.net.host.HostDescription) DefaultHostDescription(org.onosproject.net.host.DefaultHostDescription) HostLocation(org.onosproject.net.HostLocation) FpmRecord(org.onosproject.routing.fpm.api.FpmRecord) 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 47 with HostLocation

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

the class DhcpRelayManagerTest method testDhcp6DualHome.

@Test
public void testDhcp6DualHome() {
    PacketContext packetContext = new TestDhcp6ReplyPacketContext(DHCP6.MsgType.REPLY.value(), CLIENT_DH_CP, CLIENT_MAC, CLIENT_VLAN, INTERFACE_IP_V6.ipAddress().getIp6Address(), 0, false, CLIENT_VLAN);
    reset(manager.hostService);
    expect(manager.hostService.getHostsByIp(CLIENT_LL_IP_V6)).andReturn(ImmutableSet.of(EXISTS_HOST)).anyTimes();
    // FIXME: currently DHCPv6 has a bug, we can't get correct vlan of client......
    // XXX: The vlan relied from DHCP6 handler might be wrong, do hack here
    HostId hostId = HostId.hostId(CLIENT_MAC, VlanId.NONE);
    expect(manager.hostService.getHost(hostId)).andReturn(EXISTS_HOST).anyTimes();
    // XXX: sometimes this will work, sometimes not
    expect(manager.hostService.getHost(CLIENT_HOST_ID)).andReturn(EXISTS_HOST).anyTimes();
    Capture<HostDescription> capturedHostDesc = newCapture();
    // XXX: also a hack here
    mockHostProviderService.hostDetected(eq(hostId), capture(capturedHostDesc), eq(false));
    expectLastCall().anyTimes();
    mockHostProviderService.hostDetected(eq(CLIENT_HOST_ID), capture(capturedHostDesc), eq(false));
    expectLastCall().anyTimes();
    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)));
}
Also used : HostLocation(org.onosproject.net.HostLocation) PacketContext(org.onosproject.net.packet.PacketContext) HostId(org.onosproject.net.HostId) HostDescription(org.onosproject.net.host.HostDescription) Test(org.junit.Test)

Example 48 with HostLocation

use of org.onosproject.net.HostLocation in project trellis-control by opennetworkinglab.

the class HostHandler method processHostMovedEventInternal.

private void processHostMovedEventInternal(HostEvent event) {
    // This method will be called when one of the following value has changed:
    // (1) locations (2) auxLocations or (3) both locations and auxLocations.
    // We only need to proceed when effectiveLocation has changed.
    Set<HostLocation> newLocations = effectiveLocations(event.subject());
    Set<HostLocation> prevLocations = effectiveLocations(event.prevSubject());
    if (newLocations.equals(prevLocations)) {
        log.info("effectiveLocations of {} has not changed. Skipping {}", event.subject().id(), event);
        return;
    }
    Host host = event.subject();
    Host prevHost = event.prevSubject();
    MacAddress hostMac = host.mac();
    VlanId hostVlanId = host.vlan();
    Set<IpAddress> prevIps = prevHost.ipAddresses();
    Set<IpAddress> newIps = host.ipAddresses();
    EthType hostTpid = host.tpid();
    boolean doubleTaggedHost = isDoubleTaggedHost(host);
    log.info("Host {}/{} is moved from {} to {}", hostMac, hostVlanId, prevLocations, newLocations);
    Set<DeviceId> newDeviceIds = newLocations.stream().map(HostLocation::deviceId).collect(Collectors.toSet());
    // For each old location
    Sets.difference(prevLocations, newLocations).forEach(prevLocation -> {
        // Remove routing rules for old IPs
        Sets.difference(prevIps, newIps).forEach(ip -> {
            if (doubleTaggedHost) {
                processDoubleTaggedRoutingRule(prevLocation.deviceId(), prevLocation.port(), hostMac, host.innerVlan(), hostVlanId, hostTpid, ip, true);
            } else {
                processRoutingRule(prevLocation.deviceId(), prevLocation.port(), hostMac, hostVlanId, ip, true);
            }
        });
        // Redirect the flows to pair link if configured
        // Note: Do not continue removing any rule
        Optional<DeviceId> pairDeviceId = srManager.getPairDeviceId(prevLocation.deviceId());
        Optional<PortNumber> pairLocalPort = srManager.getPairLocalPort(prevLocation.deviceId());
        if (pairDeviceId.isPresent() && pairLocalPort.isPresent() && newLocations.stream().anyMatch(location -> location.deviceId().equals(pairDeviceId.get())) && newLocations.stream().noneMatch(location -> location.deviceId().equals(prevLocation.deviceId()))) {
            // NOTE: Since the pairLocalPort is trunk port, use assigned vlan of original port
            // when the host is untagged
            VlanId vlanId = Optional.ofNullable(srManager.getInternalVlanId(prevLocation)).orElse(hostVlanId);
            processBridgingRule(prevLocation.deviceId(), pairLocalPort.get(), hostMac, vlanId, false);
            newIps.forEach(ip -> processRoutingRule(prevLocation.deviceId(), pairLocalPort.get(), hostMac, vlanId, ip, false));
            return;
        }
        // Otherwise, do not remove and let the adding part update the old flow
        if (!newDeviceIds.contains(prevLocation.deviceId())) {
            processBridgingRule(prevLocation.deviceId(), prevLocation.port(), hostMac, hostVlanId, true);
            Sets.intersection(prevIps, newIps).forEach(ip -> {
                if (doubleTaggedHost) {
                    processDoubleTaggedRoutingRule(prevLocation.deviceId(), prevLocation.port(), hostMac, host.innerVlan(), hostVlanId, hostTpid, ip, true);
                } else {
                    processRoutingRule(prevLocation.deviceId(), prevLocation.port(), hostMac, hostVlanId, ip, true);
                }
            });
        }
        // Otherwise, do not remove and let the adding part update the old flow
        if (newLocations.stream().noneMatch(newLocation -> {
            VlanId oldAssignedVlan = srManager.getInternalVlanId(prevLocation);
            VlanId newAssignedVlan = srManager.getInternalVlanId(newLocation);
            // Host is tagged and the new location has the host vlan in vlan-tagged
            return srManager.interfaceService.getTaggedVlanId(newLocation).contains(hostVlanId) || (oldAssignedVlan != null && newAssignedVlan != null && // Host is untagged and the new location has the same assigned vlan
            oldAssignedVlan.equals(newAssignedVlan));
        })) {
            processBridgingRule(prevLocation.deviceId(), prevLocation.port(), hostMac, hostVlanId, true);
        }
        // Remove routing rules for unchanged IPs if none of the subnet of new location contains
        // the IP. Otherwise, do not remove and let the adding part update the old flow
        Sets.intersection(prevIps, newIps).forEach(ip -> {
            if (newLocations.stream().noneMatch(newLocation -> srManager.deviceConfiguration.inSameSubnet(newLocation, ip))) {
                if (doubleTaggedHost) {
                    processDoubleTaggedRoutingRule(prevLocation.deviceId(), prevLocation.port(), hostMac, host.innerVlan(), hostVlanId, hostTpid, ip, true);
                } else {
                    processRoutingRule(prevLocation.deviceId(), prevLocation.port(), hostMac, hostVlanId, ip, true);
                }
            }
        });
    });
    // For each new location, add all new IPs.
    Sets.difference(newLocations, prevLocations).forEach(newLocation -> {
        processBridgingRule(newLocation.deviceId(), newLocation.port(), hostMac, hostVlanId, false);
        newIps.forEach(ip -> {
            if (doubleTaggedHost) {
                processDoubleTaggedRoutingRule(newLocation.deviceId(), newLocation.port(), hostMac, host.innerVlan(), hostVlanId, hostTpid, ip, false);
            } else {
                processRoutingRule(newLocation.deviceId(), newLocation.port(), hostMac, hostVlanId, ip, false);
            }
        });
        // But will also cover [1A/x] -> [1A/y] -> [1A/y, 1B/y]
        if (srManager.activeProbing) {
            srManager.getPairDeviceId(newLocation.deviceId()).ifPresent(pairDeviceId -> srManager.getPairLocalPort(pairDeviceId).ifPresent(pairRemotePort -> probe(host, newLocation, pairDeviceId, pairRemotePort)));
        }
    });
    // For each unchanged location, add new IPs and remove old IPs.
    Sets.intersection(newLocations, prevLocations).forEach(unchangedLocation -> {
        Sets.difference(prevIps, newIps).forEach(ip -> {
            if (doubleTaggedHost) {
                processDoubleTaggedRoutingRule(unchangedLocation.deviceId(), unchangedLocation.port(), hostMac, host.innerVlan(), hostVlanId, hostTpid, ip, true);
            } else {
                processRoutingRule(unchangedLocation.deviceId(), unchangedLocation.port(), hostMac, hostVlanId, ip, true);
            }
        });
        Sets.difference(newIps, prevIps).forEach(ip -> {
            if (doubleTaggedHost) {
                processDoubleTaggedRoutingRule(unchangedLocation.deviceId(), unchangedLocation.port(), hostMac, host.innerVlan(), hostVlanId, hostTpid, ip, false);
            } else {
                processRoutingRule(unchangedLocation.deviceId(), unchangedLocation.port(), hostMac, hostVlanId, ip, false);
            }
        });
        // Verify existing location and see if it is still valid
        srManager.probingService.probeHost(host, unchangedLocation, ProbeMode.VERIFY);
    });
    // ensure dual-homed host locations have viable uplinks
    if (newLocations.size() > prevLocations.size() || srManager.singleHomedDown) {
        newLocations.forEach(loc -> {
            if (srManager.shouldProgram(loc.deviceId())) {
                srManager.linkHandler.checkUplinksForHost(loc);
            }
        });
    }
}
Also used : HostLocation(org.onosproject.net.HostLocation) Tools(org.onlab.util.Tools) Host(org.onosproject.net.Host) PredictableExecutor(org.onlab.util.PredictableExecutor) PortNumber(org.onosproject.net.PortNumber) LoggerFactory(org.slf4j.LoggerFactory) Tools.groupedThreads(org.onlab.util.Tools.groupedThreads) CompletableFuture(java.util.concurrent.CompletableFuture) HostService(org.onosproject.net.host.HostService) ConnectPoint(org.onosproject.net.ConnectPoint) HashSet(java.util.HashSet) Preconditions.checkArgument(com.google.common.base.Preconditions.checkArgument) Lists(com.google.common.collect.Lists) PhasedRecoveryService(org.onosproject.segmentrouting.phasedrecovery.api.PhasedRecoveryService) HostEvent(org.onosproject.net.host.HostEvent) IpAddress(org.onlab.packet.IpAddress) Logger(org.slf4j.Logger) VlanId(org.onlab.packet.VlanId) Set(java.util.Set) Phase(org.onosproject.segmentrouting.phasedrecovery.api.Phase) ProbeMode(org.onosproject.net.host.ProbeMode) Collectors(java.util.stream.Collectors) Sets(com.google.common.collect.Sets) ExecutionException(java.util.concurrent.ExecutionException) TimeUnit(java.util.concurrent.TimeUnit) EthType(org.onlab.packet.EthType) List(java.util.List) Objective(org.onosproject.net.flowobjective.Objective) Optional(java.util.Optional) MacAddress(org.onlab.packet.MacAddress) DeviceId(org.onosproject.net.DeviceId) IpPrefix(org.onlab.packet.IpPrefix) DeviceId(org.onosproject.net.DeviceId) Host(org.onosproject.net.Host) MacAddress(org.onlab.packet.MacAddress) EthType(org.onlab.packet.EthType) HostLocation(org.onosproject.net.HostLocation) IpAddress(org.onlab.packet.IpAddress) PortNumber(org.onosproject.net.PortNumber) VlanId(org.onlab.packet.VlanId)

Example 49 with HostLocation

use of org.onosproject.net.HostLocation in project trellis-control by opennetworkinglab.

the class HostHandler method processHostUpdatedEventInternal.

private void processHostUpdatedEventInternal(HostEvent event) {
    Host host = event.subject();
    MacAddress hostMac = host.mac();
    VlanId hostVlanId = host.vlan();
    EthType hostTpid = host.tpid();
    Set<HostLocation> locations = effectiveLocations(host);
    Set<IpAddress> prevIps = event.prevSubject().ipAddresses();
    Set<IpAddress> newIps = host.ipAddresses();
    log.info("Host {}/{} is updated", hostMac, hostVlanId);
    locations.forEach(location -> {
        Sets.difference(prevIps, newIps).forEach(ip -> {
            if (isDoubleTaggedHost(host)) {
                processDoubleTaggedRoutingRule(location.deviceId(), location.port(), hostMac, host.innerVlan(), hostVlanId, hostTpid, ip, true);
            } else {
                processRoutingRule(location.deviceId(), location.port(), hostMac, hostVlanId, ip, true);
            }
        });
        Sets.difference(newIps, prevIps).forEach(ip -> {
            if (isDoubleTaggedHost(host)) {
                processDoubleTaggedRoutingRule(location.deviceId(), location.port(), hostMac, host.innerVlan(), hostVlanId, hostTpid, ip, false);
            } else {
                processRoutingRule(location.deviceId(), location.port(), hostMac, hostVlanId, ip, false);
            }
        });
    });
    // Use the pair link temporarily before the second location of a dual-homed host shows up.
    // This do not affect single-homed hosts since the flow will be blocked in
    // processBridgingRule or processRoutingRule due to VLAN or IP mismatch respectively
    locations.forEach(location -> srManager.getPairDeviceId(location.deviceId()).ifPresent(pairDeviceId -> {
        if (locations.stream().noneMatch(l -> l.deviceId().equals(pairDeviceId))) {
            Set<IpAddress> ipsToAdd = Sets.difference(newIps, prevIps);
            Set<IpAddress> ipsToRemove = Sets.difference(prevIps, newIps);
            srManager.getPairLocalPort(pairDeviceId).ifPresent(pairRemotePort -> {
                // NOTE: Since the pairLocalPort is trunk port, use assigned vlan of original port
                // when the host is untagged
                VlanId vlanId = vlanForPairPort(hostVlanId, location);
                if (vlanId == null) {
                    return;
                }
                ipsToRemove.forEach(ip -> processRoutingRule(pairDeviceId, pairRemotePort, hostMac, vlanId, ip, true));
                ipsToAdd.forEach(ip -> processRoutingRule(pairDeviceId, pairRemotePort, hostMac, vlanId, ip, false));
                if (srManager.activeProbing) {
                    probe(host, location, pairDeviceId, pairRemotePort);
                }
            });
        }
    }));
}
Also used : HostLocation(org.onosproject.net.HostLocation) Tools(org.onlab.util.Tools) Host(org.onosproject.net.Host) PredictableExecutor(org.onlab.util.PredictableExecutor) PortNumber(org.onosproject.net.PortNumber) LoggerFactory(org.slf4j.LoggerFactory) Tools.groupedThreads(org.onlab.util.Tools.groupedThreads) CompletableFuture(java.util.concurrent.CompletableFuture) HostService(org.onosproject.net.host.HostService) ConnectPoint(org.onosproject.net.ConnectPoint) HashSet(java.util.HashSet) Preconditions.checkArgument(com.google.common.base.Preconditions.checkArgument) Lists(com.google.common.collect.Lists) PhasedRecoveryService(org.onosproject.segmentrouting.phasedrecovery.api.PhasedRecoveryService) HostEvent(org.onosproject.net.host.HostEvent) IpAddress(org.onlab.packet.IpAddress) Logger(org.slf4j.Logger) VlanId(org.onlab.packet.VlanId) Set(java.util.Set) Phase(org.onosproject.segmentrouting.phasedrecovery.api.Phase) ProbeMode(org.onosproject.net.host.ProbeMode) Collectors(java.util.stream.Collectors) Sets(com.google.common.collect.Sets) ExecutionException(java.util.concurrent.ExecutionException) TimeUnit(java.util.concurrent.TimeUnit) EthType(org.onlab.packet.EthType) List(java.util.List) Objective(org.onosproject.net.flowobjective.Objective) Optional(java.util.Optional) MacAddress(org.onlab.packet.MacAddress) DeviceId(org.onosproject.net.DeviceId) IpPrefix(org.onlab.packet.IpPrefix) EthType(org.onlab.packet.EthType) HashSet(java.util.HashSet) Set(java.util.Set) HostLocation(org.onosproject.net.HostLocation) Host(org.onosproject.net.Host) IpAddress(org.onlab.packet.IpAddress) MacAddress(org.onlab.packet.MacAddress) VlanId(org.onlab.packet.VlanId)

Example 50 with HostLocation

use of org.onosproject.net.HostLocation in project trellis-control by opennetworkinglab.

the class HostHandler method processHostAddedAtLocation.

List<CompletableFuture<Objective>> processHostAddedAtLocation(Host host, HostLocation location) {
    checkArgument(effectiveLocations(host).contains(location), "{} is not a location of {}", location, host);
    MacAddress hostMac = host.mac();
    VlanId hostVlanId = host.vlan();
    Set<HostLocation> locations = effectiveLocations(host);
    Set<IpAddress> ips = host.ipAddresses();
    log.info("Host {}/{} is added at {}", hostMac, hostVlanId, locations);
    List<CompletableFuture<Objective>> objectiveFutures = Lists.newArrayList();
    // TODO Phased recovery does not trace double tagged hosts
    if (isDoubleTaggedHost(host)) {
        ips.forEach(ip -> processDoubleTaggedRoutingRule(location.deviceId(), location.port(), hostMac, host.innerVlan(), hostVlanId, host.tpid(), ip, false));
    } else {
        objectiveFutures.add(processBridgingRule(location.deviceId(), location.port(), hostMac, hostVlanId, false));
        ips.forEach(ip -> objectiveFutures.add(processRoutingRule(location.deviceId(), location.port(), hostMac, hostVlanId, ip, false)));
    }
    // Use the pair link temporarily before the second location of a dual-homed host shows up.
    // This do not affect single-homed hosts since the flow will be blocked in
    // processBridgingRule or processRoutingRule due to VLAN or IP mismatch respectively
    srManager.getPairDeviceId(location.deviceId()).ifPresent(pairDeviceId -> {
        if (effectiveLocations(host).stream().noneMatch(l -> l.deviceId().equals(pairDeviceId))) {
            srManager.getPairLocalPort(pairDeviceId).ifPresent(pairRemotePort -> {
                // NOTE: Since the pairLocalPort is trunk port, use assigned vlan of original port
                // when the host is untagged
                VlanId vlanId = vlanForPairPort(hostVlanId, location);
                if (vlanId == null) {
                    return;
                }
                objectiveFutures.add(processBridgingRule(pairDeviceId, pairRemotePort, hostMac, vlanId, false));
                ips.forEach(ip -> objectiveFutures.add(processRoutingRule(pairDeviceId, pairRemotePort, hostMac, vlanId, ip, false)));
                if (srManager.activeProbing) {
                    probe(host, location, pairDeviceId, pairRemotePort);
                }
            });
        }
    });
    // 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(location.deviceId(), hostMac, hostVlanId, null, false);
    if (nextId != -1) {
        log.debug(" Updating next objective for device {}, host {}/{}, port {}, nextid {}", location.deviceId(), hostMac, hostVlanId, location.port(), nextId);
        srManager.updateMacVlanTreatment(location.deviceId(), hostMac, hostVlanId, location.port(), nextId);
    }
    log.debug("{} objectiveFutures for {}", objectiveFutures.size(), location);
    return objectiveFutures;
}
Also used : CompletableFuture(java.util.concurrent.CompletableFuture) HostLocation(org.onosproject.net.HostLocation) IpAddress(org.onlab.packet.IpAddress) MacAddress(org.onlab.packet.MacAddress) VlanId(org.onlab.packet.VlanId) ConnectPoint(org.onosproject.net.ConnectPoint)

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