Search in sources :

Example 21 with ConnectPoint

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

the class McastHandler method initInternal.

private void initInternal() {
    srManager.multicastRouteService.getRoutes().forEach(mcastRoute -> {
        lastMcastChange.set(Instant.now());
        log.debug("Init group {}", mcastRoute.group());
        if (!mcastUtils.isLeader(mcastRoute.group())) {
            log.debug("Skip {} due to lack of leadership", mcastRoute.group());
            return;
        }
        McastRouteData mcastRouteData = srManager.multicastRouteService.routeData(mcastRoute);
        // For each source process the mcast tree
        srManager.multicastRouteService.sources(mcastRoute).forEach(source -> {
            McastPathStoreKey pathStoreKey = new McastPathStoreKey(mcastRoute.group(), source);
            Collection<? extends List<Link>> storedPaths = Versioned.valueOrElse(mcastPathStore.get(pathStoreKey), Lists.newArrayList());
            Map<ConnectPoint, List<ConnectPoint>> mcastPaths = buildMcastPaths(storedPaths, mcastRoute.group(), source);
            // Get all the sinks and process them
            Set<ConnectPoint> sinks = processSinksToBeAdded(source, mcastRoute.group(), mcastRouteData.sinks());
            // Filter out all the working sinks, we do not want to move them
            // TODO we need a better way to distinguish flows coming from different sources
            sinks = sinks.stream().filter(sink -> !mcastPaths.containsKey(sink) || !isSinkForSource(mcastRoute.group(), sink, source)).collect(Collectors.toSet());
            if (sinks.isEmpty()) {
                log.debug("Skip {} for source {} nothing to do", mcastRoute.group(), source);
                return;
            }
            Map<ConnectPoint, List<Path>> mcasTree = mcastUtils.computeSinkMcastTree(mcastRoute.group(), source.deviceId(), sinks);
            mcasTree.forEach((sink, paths) -> processSinkAddedInternal(source, sink, mcastRoute.group(), null));
        });
    });
}
Also used : McastRouteData(org.onosproject.mcast.api.McastRouteData) List(java.util.List) ConnectPoint(org.onosproject.net.ConnectPoint) Link(org.onosproject.net.Link)

Example 22 with ConnectPoint

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

the class McastHandler method processSinksToBeAdded.

/**
 * Process all the sinks related to a mcast group and return
 * the ones to be processed.
 *
 * @param source the source connect point
 * @param mcastIp the group address
 * @param sinks the sinks to be evaluated
 * @return the set of the sinks to be processed
 */
private Set<ConnectPoint> processSinksToBeAdded(ConnectPoint source, IpAddress mcastIp, Map<HostId, Set<ConnectPoint>> sinks) {
    final Set<ConnectPoint> sinksToBeProcessed = Sets.newHashSet();
    log.debug("Processing sinks to be added for Multicast group {}, source {}", mcastIp, source);
    sinks.forEach(((hostId, connectPoints) -> {
        // add all connect points that are not tied with any host
        if (Objects.equal(HostId.NONE, hostId)) {
            sinksToBeProcessed.addAll(connectPoints);
            return;
        }
        // If it has more than 2 locations
        if (connectPoints.size() > 2 || connectPoints.size() == 0) {
            log.debug("Skip {} since sink {} has {} locations", mcastIp, hostId, connectPoints.size());
            return;
        }
        // If it has one location, just use it
        if (connectPoints.size() == 1) {
            sinksToBeProcessed.add(connectPoints.stream().findFirst().orElse(null));
            return;
        }
        // We prefer to reuse existing flows
        ConnectPoint sinkToBeProcessed = connectPoints.stream().filter(connectPoint -> {
            if (!isSinkForGroup(mcastIp, connectPoint, source)) {
                return false;
            }
            if (!isSinkReachable(mcastIp, connectPoint, source)) {
                return false;
            }
            ConnectPoint other = connectPoints.stream().filter(remaining -> !remaining.equals(connectPoint)).findFirst().orElse(null);
            // We are already serving the sink
            return !isSinkForSource(mcastIp, other, source);
        }).findFirst().orElse(null);
        if (sinkToBeProcessed != null) {
            sinksToBeProcessed.add(sinkToBeProcessed);
            return;
        }
        // Otherwise we prefer to reuse existing egresses
        Set<DeviceId> egresses = getDevice(mcastIp, EGRESS, source);
        sinkToBeProcessed = connectPoints.stream().filter(connectPoint -> {
            if (!egresses.contains(connectPoint.deviceId())) {
                return false;
            }
            if (!isSinkReachable(mcastIp, connectPoint, source)) {
                return false;
            }
            ConnectPoint other = connectPoints.stream().filter(remaining -> !remaining.equals(connectPoint)).findFirst().orElse(null);
            return !isSinkForSource(mcastIp, other, source);
        }).findFirst().orElse(null);
        if (sinkToBeProcessed != null) {
            sinksToBeProcessed.add(sinkToBeProcessed);
            return;
        }
        // Otherwise we prefer a location co-located with the source (if it exists)
        sinkToBeProcessed = connectPoints.stream().filter(connectPoint -> connectPoint.deviceId().equals(source.deviceId())).findFirst().orElse(null);
        if (sinkToBeProcessed != null) {
            sinksToBeProcessed.add(sinkToBeProcessed);
            return;
        }
        // Finally, we randomly pick a new location if it is reachable
        sinkToBeProcessed = connectPoints.stream().filter(connectPoint -> {
            if (!isSinkReachable(mcastIp, connectPoint, source)) {
                return false;
            }
            ConnectPoint other = connectPoints.stream().filter(remaining -> !remaining.equals(connectPoint)).findFirst().orElse(null);
            return !isSinkForSource(mcastIp, other, source);
        }).findFirst().orElse(null);
        if (sinkToBeProcessed != null) {
            sinksToBeProcessed.add(sinkToBeProcessed);
        }
    }));
    return sinksToBeProcessed;
}
Also used : ConsistentMap(org.onosproject.store.service.ConsistentMap) CoreService(org.onosproject.core.CoreService) PortNumber(org.onosproject.net.PortNumber) LoggerFactory(org.slf4j.LoggerFactory) Tools.groupedThreads(org.onlab.util.Tools.groupedThreads) ForwardingObjective(org.onosproject.net.flowobjective.ForwardingObjective) ConsistentMultimap(org.onosproject.store.service.ConsistentMultimap) Link(org.onosproject.net.Link) SINKS_REMOVED(org.onosproject.mcast.api.McastEvent.Type.SINKS_REMOVED) ConnectPoint(org.onosproject.net.ConnectPoint) HashMultimap(com.google.common.collect.HashMultimap) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Executors.newScheduledThreadPool(java.util.concurrent.Executors.newScheduledThreadPool) McastEvent(org.onosproject.mcast.api.McastEvent) Port(org.onosproject.net.Port) Map(java.util.Map) ApplicationId(org.onosproject.core.ApplicationId) NextObjective(org.onosproject.net.flowobjective.NextObjective) SOURCES_ADDED(org.onosproject.mcast.api.McastEvent.Type.SOURCES_ADDED) INGRESS(org.onosproject.segmentrouting.mcast.McastRole.INGRESS) KryoNamespaces(org.onosproject.store.serializers.KryoNamespaces) SOURCES_REMOVED(org.onosproject.mcast.api.McastEvent.Type.SOURCES_REMOVED) Objects(com.google.common.base.Objects) ROUTE_ADDED(org.onosproject.mcast.api.McastEvent.Type.ROUTE_ADDED) NodeId(org.onosproject.cluster.NodeId) Serializer(org.onosproject.store.service.Serializer) ImmutableSet(com.google.common.collect.ImmutableSet) Device(org.onosproject.net.Device) Collection(java.util.Collection) Set(java.util.Set) Instant(java.time.Instant) Collectors(java.util.stream.Collectors) Sets(com.google.common.collect.Sets) SINKS_ADDED(org.onosproject.mcast.api.McastEvent.Type.SINKS_ADDED) Versioned(org.onosproject.store.service.Versioned) List(java.util.List) ObjectiveContext(org.onosproject.net.flowobjective.ObjectiveContext) Entry(java.util.Map.Entry) Optional(java.util.Optional) Path(org.onosproject.net.Path) DeviceId(org.onosproject.net.DeviceId) McastRouteUpdate(org.onosproject.mcast.api.McastRouteUpdate) ROUTE_REMOVED(org.onosproject.mcast.api.McastEvent.Type.ROUTE_REMOVED) Multimap(com.google.common.collect.Multimap) KryoNamespace(org.onlab.util.KryoNamespace) AtomicReference(java.util.concurrent.atomic.AtomicReference) Lists(com.google.common.collect.Lists) TRANSIT(org.onosproject.segmentrouting.mcast.McastRole.TRANSIT) ScheduledExecutorService(java.util.concurrent.ScheduledExecutorService) HostId(org.onosproject.net.HostId) DefaultObjectiveContext(org.onosproject.net.flowobjective.DefaultObjectiveContext) IpAddress(org.onlab.packet.IpAddress) SegmentRoutingManager(org.onosproject.segmentrouting.SegmentRoutingManager) McastRouteData(org.onosproject.mcast.api.McastRouteData) Logger(org.slf4j.Logger) EGRESS(org.onosproject.segmentrouting.mcast.McastRole.EGRESS) Iterator(java.util.Iterator) VlanId(org.onlab.packet.VlanId) Maps(com.google.common.collect.Maps) McastRoute(org.onosproject.mcast.api.McastRoute) TimeUnit(java.util.concurrent.TimeUnit) DistributedSet(org.onosproject.store.service.DistributedSet) Comparator(java.util.Comparator) Collections(java.util.Collections) ImmutableSet(com.google.common.collect.ImmutableSet) Set(java.util.Set) DistributedSet(org.onosproject.store.service.DistributedSet) ConnectPoint(org.onosproject.net.ConnectPoint)

Example 23 with ConnectPoint

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

the class McastHandler method processPortUpdateInternal.

private void processPortUpdateInternal(Device affectedDevice, Port affectedPort) {
    // Clean the filtering obj store. Edge port case.
    lastMcastChange.set(Instant.now());
    ConnectPoint portDown = new ConnectPoint(affectedDevice.id(), affectedPort.number());
    if (!affectedPort.isEnabled()) {
        log.info("Processing port down {}", portDown);
        updateFilterObjStoreByPort(portDown);
    }
}
Also used : ConnectPoint(org.onosproject.net.ConnectPoint)

Example 24 with ConnectPoint

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

the class DefaultGroupHandler method updateL3UcastGroupBucket.

/**
 * Updates the next objective for the given nextId .
 *
 * @param hostMac mac of host for which Next obj is to be updated.
 * @param hostVlanId vlan of host for which Next obj is to be updated.
 * @param port port with which to update the Next Obj.
 * @param nextId of Next Obj which needs to be updated.
 */
public void updateL3UcastGroupBucket(MacAddress hostMac, VlanId hostVlanId, PortNumber port, int nextId) {
    MacAddress deviceMac;
    try {
        deviceMac = deviceConfig.getDeviceMac(deviceId);
    } catch (DeviceConfigNotFoundException e) {
        log.warn(e.getMessage() + " in updateL3UcastGroupBucket");
        return;
    }
    ConnectPoint connectPoint = new ConnectPoint(deviceId, port);
    VlanId untaggedVlan = srManager.interfaceService.getUntaggedVlanId(connectPoint);
    Set<VlanId> taggedVlans = srManager.interfaceService.getTaggedVlanId(connectPoint);
    VlanId nativeVlan = srManager.interfaceService.getNativeVlanId(connectPoint);
    TrafficSelector.Builder mbuilder = DefaultTrafficSelector.builder();
    TrafficTreatment.Builder tbuilder = DefaultTrafficTreatment.builder().deferred().setEthDst(hostMac).setEthSrc(deviceMac).setOutput(port);
    if (taggedVlans.contains(hostVlanId)) {
        mbuilder.matchVlanId(hostVlanId);
        tbuilder.setVlanId(hostVlanId);
    } else if (hostVlanId.equals(VlanId.NONE)) {
        if (untaggedVlan != null) {
            mbuilder.matchVlanId(untaggedVlan);
            tbuilder.popVlan();
        } else if (nativeVlan != null) {
            mbuilder.matchVlanId(nativeVlan);
            tbuilder.popVlan();
        } else {
            log.warn("Untagged nexthop {}/{} is not allowed on {} without untagged or native vlan", hostMac, hostVlanId, connectPoint);
            return;
        }
    } else {
        log.warn("Tagged nexthop {}/{} is not allowed on {} without VLAN listed" + " in tagged vlan", hostMac, hostVlanId, connectPoint);
        return;
    }
    log.debug(" update L3Ucast : deviceMac {}, port {}, host {}/{}, nextid {}, Treatment {} Meta {}", deviceMac, port, hostMac, hostVlanId, nextId, tbuilder.build(), mbuilder.build());
    NextObjective.Builder nextObjBuilder = DefaultNextObjective.builder().withId(nextId).withType(NextObjective.Type.SIMPLE).fromApp(appId).addTreatment(tbuilder.build()).withMeta(mbuilder.build());
    ObjectiveContext context = new DefaultObjectiveContext((objective) -> log.debug(" NextId {} successfully updated host {} vlan {} with port {}", nextId, hostMac, hostVlanId, port), (objective, error) -> {
        log.warn(" NextId {} failed to update host {} vlan {} with port {}, error : {}", nextId, hostMac, hostVlanId, port, error);
        srManager.invalidateNextObj(objective.id());
    });
    NextObjective nextObj = nextObjBuilder.modify(context);
    flowObjectiveService.next(deviceId, nextObj);
}
Also used : DefaultNextObjective(org.onosproject.net.flowobjective.DefaultNextObjective) NextObjective(org.onosproject.net.flowobjective.NextObjective) MacAddress(org.onlab.packet.MacAddress) DefaultTrafficTreatment(org.onosproject.net.flow.DefaultTrafficTreatment) TrafficTreatment(org.onosproject.net.flow.TrafficTreatment) ConnectPoint(org.onosproject.net.ConnectPoint) DeviceConfigNotFoundException(org.onosproject.segmentrouting.config.DeviceConfigNotFoundException) DefaultObjectiveContext(org.onosproject.net.flowobjective.DefaultObjectiveContext) ObjectiveContext(org.onosproject.net.flowobjective.ObjectiveContext) DefaultObjectiveContext(org.onosproject.net.flowobjective.DefaultObjectiveContext) TrafficSelector(org.onosproject.net.flow.TrafficSelector) DefaultTrafficSelector(org.onosproject.net.flow.DefaultTrafficSelector) VlanId(org.onlab.packet.VlanId)

Example 25 with ConnectPoint

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

the class LinkHandler method updateHostPorts.

/**
 * Administratively enables or disables edge ports if the link that was
 * added or removed was the only uplink port from an edge device. Edge ports
 * that belong to dual-homed hosts are always processed. In addition,
 * single-homed host ports are optionally processed depending on the
 * singleHomedDown property.
 *
 * @param link the link to be processed
 * @param added true if link was added, false if link was removed
 */
private void updateHostPorts(Link link, boolean added) {
    // Topology has only a single pair of leaves
    if (srManager.getInfraDeviceIds().isEmpty()) {
        log.debug("No spine configured. Not updating edge port for {} {}", link, added ? "add" : "remove");
        return;
    }
    DeviceConfiguration devConfig = srManager.deviceConfiguration;
    if (added) {
        try {
            if (!devConfig.isEdgeDevice(link.src().deviceId()) || devConfig.isEdgeDevice(link.dst().deviceId())) {
                return;
            }
        } catch (DeviceConfigNotFoundException e) {
            log.warn("Unable to determine if link is a valid uplink" + e.getMessage());
        }
        // re-enable previously disabled ports on this edge-device if any
        Set<PortNumber> p = downedPortStore.remove(link.src().deviceId());
        if (p != null) {
            log.warn("Link src {} --> dst {} added is an edge-device uplink, " + "enabling dual homed ports if any: {}", link.src().deviceId(), link.dst().deviceId(), (p.isEmpty()) ? "no ports" : p);
            p.forEach(pnum -> srManager.deviceAdminService.changePortState(link.src().deviceId(), pnum, true));
        }
    } else {
        // If the device does not have a pair device - skip
        DeviceId dev = link.src().deviceId();
        if (getPairDeviceIdOrNull(dev) == null) {
            log.info("Device {} does not have pair device " + "not disabling access port", dev);
            return;
        }
        // Verify if last uplink
        if (!lastUplink(link)) {
            return;
        }
        // find dual homed hosts on this dev to disable
        Set<PortNumber> dp = srManager.hostHandler.getDualHomedHostPorts(dev);
        log.warn("Link src {} --> dst {} removed was the last uplink, " + "disabling  dual homed ports:  {}", dev, link.dst().deviceId(), (dp.isEmpty()) ? "no ports" : dp);
        dp.forEach(pnum -> srManager.deviceAdminService.changePortState(dev, pnum, false));
        if (srManager.singleHomedDown) {
            // get all configured ports and down them if they haven't already
            // been downed
            srManager.deviceService.getPorts(dev).stream().filter(p -> p.isEnabled() && !dp.contains(p.number())).filter(p -> srManager.interfaceService.isConfigured(new ConnectPoint(dev, p.number()))).filter(p -> !srManager.deviceConfiguration.isPairLocalPort(dev, p.number())).forEach(p -> {
                log.warn("Last uplink gone src {} -> dst {} .. removing " + "configured port {}", p.number());
                srManager.deviceAdminService.changePortState(dev, p.number(), false);
                dp.add(p.number());
            });
        }
        if (!dp.isEmpty()) {
            // update global store
            Set<PortNumber> p = downedPortStore.get(dev);
            if (p == null) {
                p = dp;
            } else {
                p.addAll(dp);
            }
            downedPortStore.put(link.src().deviceId(), p);
        }
    }
}
Also used : DeviceConfigNotFoundException(org.onosproject.segmentrouting.config.DeviceConfigNotFoundException) Logger(org.slf4j.Logger) HostLocation(org.onosproject.net.HostLocation) Device(org.onosproject.net.Device) ImmutableMap(com.google.common.collect.ImmutableMap) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) PortNumber(org.onosproject.net.PortNumber) LoggerFactory(org.slf4j.LoggerFactory) Set(java.util.Set) EventuallyConsistentMapBuilder(org.onosproject.store.service.EventuallyConsistentMapBuilder) WallClockTimestamp(org.onosproject.store.service.WallClockTimestamp) Collectors(java.util.stream.Collectors) Link(org.onosproject.net.Link) Sets(com.google.common.collect.Sets) ConnectPoint(org.onosproject.net.ConnectPoint) List(java.util.List) ImmutableList(com.google.common.collect.ImmutableList) DefaultGroupHandler(org.onosproject.segmentrouting.grouphandler.DefaultGroupHandler) Map(java.util.Map) Entry(java.util.Map.Entry) LinkService(org.onosproject.net.link.LinkService) EventuallyConsistentMap(org.onosproject.store.service.EventuallyConsistentMap) DeviceId(org.onosproject.net.DeviceId) DeviceId(org.onosproject.net.DeviceId) PortNumber(org.onosproject.net.PortNumber) ConnectPoint(org.onosproject.net.ConnectPoint) DeviceConfigNotFoundException(org.onosproject.segmentrouting.config.DeviceConfigNotFoundException)

Aggregations

ConnectPoint (org.onosproject.net.ConnectPoint)536 Test (org.junit.Test)149 DeviceId (org.onosproject.net.DeviceId)125 FilteredConnectPoint (org.onosproject.net.FilteredConnectPoint)91 Link (org.onosproject.net.Link)88 Set (java.util.Set)86 PortNumber (org.onosproject.net.PortNumber)86 TrafficTreatment (org.onosproject.net.flow.TrafficTreatment)83 VlanId (org.onlab.packet.VlanId)78 TrafficSelector (org.onosproject.net.flow.TrafficSelector)75 DefaultTrafficTreatment (org.onosproject.net.flow.DefaultTrafficTreatment)72 Logger (org.slf4j.Logger)71 Port (org.onosproject.net.Port)70 List (java.util.List)69 Ethernet (org.onlab.packet.Ethernet)69 DeviceService (org.onosproject.net.device.DeviceService)67 Collectors (java.util.stream.Collectors)66 MacAddress (org.onlab.packet.MacAddress)64 DefaultTrafficSelector (org.onosproject.net.flow.DefaultTrafficSelector)64 Intent (org.onosproject.net.intent.Intent)62