Search in sources :

Example 26 with DeviceId

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

the class McastHandler method recoverFailure.

/**
 * General failure recovery procedure.
 *
 * @param mcastIp the group to recover
 * @param failedElement the failed element
 */
private void recoverFailure(IpAddress mcastIp, Object failedElement) {
    // Do not proceed if we are not the leaders
    if (!mcastUtils.isLeader(mcastIp)) {
        log.debug("Skip {} due to lack of leadership", mcastIp);
        return;
    }
    // Skip if it is not an infra failure
    Set<DeviceId> transitDevices = getDevice(mcastIp, TRANSIT);
    if (!mcastUtils.isInfraFailure(transitDevices, failedElement)) {
        log.debug("Skip {} not an infrastructure failure", mcastIp);
        return;
    }
    // Do not proceed if the sources of this group are missing
    Set<ConnectPoint> sources = getSources(mcastIp);
    if (sources.isEmpty()) {
        log.warn("Missing sources for group {}", mcastIp);
        return;
    }
    // Get all the paths, affected paths, good links and good devices
    Set<List<Link>> storedPaths = getStoredPaths(mcastIp);
    Set<List<Link>> affectedPaths = mcastUtils.getAffectedPaths(storedPaths, failedElement);
    Set<Link> goodLinks = Sets.newHashSet();
    Map<DeviceId, Set<DeviceId>> goodDevicesBySource = Maps.newHashMap();
    Map<DeviceId, Set<ConnectPoint>> processedSourcesByEgress = Maps.newHashMap();
    Sets.difference(storedPaths, affectedPaths).forEach(goodPath -> {
        goodLinks.addAll(goodPath);
        DeviceId srcDevice = goodPath.get(0).src().deviceId();
        Set<DeviceId> goodDevices = Sets.newHashSet();
        goodPath.forEach(link -> goodDevices.add(link.src().deviceId()));
        goodDevicesBySource.compute(srcDevice, (k, v) -> {
            v = v == null ? Sets.newHashSet() : v;
            v.addAll(goodDevices);
            return v;
        });
    });
    affectedPaths.forEach(affectedPath -> {
        // TODO remove
        log.info("Good links {}", goodLinks);
        // TODO remove
        log.info("Good devices {}", goodDevicesBySource);
        // TODO trace
        log.info("Healing the path {}", affectedPath);
        DeviceId srcDevice = affectedPath.get(0).src().deviceId();
        DeviceId dstDevice = affectedPath.get(affectedPath.size() - 1).dst().deviceId();
        // Fix in one shot multiple sources
        Set<ConnectPoint> affectedSources = sources.stream().filter(device -> device.deviceId().equals(srcDevice)).collect(Collectors.toSet());
        Set<ConnectPoint> processedSources = processedSourcesByEgress.getOrDefault(dstDevice, Collections.emptySet());
        Optional<Path> alternativePath = getPath(srcDevice, dstDevice, mcastIp, null);
        // If an alternative is possible go ahead
        if (alternativePath.isPresent()) {
            // TODO trace
            log.info("Alternative path {}", alternativePath.get().links());
        } else {
            // Otherwise try to come up with an alternative
            // TODO trace
            log.info("No alternative path");
            Set<ConnectPoint> notAffectedSources = Sets.difference(sources, affectedSources);
            Set<ConnectPoint> remainingSources = Sets.difference(notAffectedSources, processedSources);
            alternativePath = recoverSinks(dstDevice, mcastIp, affectedSources, remainingSources);
            processedSourcesByEgress.compute(dstDevice, (k, v) -> {
                v = v == null ? Sets.newHashSet() : v;
                v.addAll(affectedSources);
                return v;
            });
        }
        // Recover from the failure if possible
        Optional<Path> finalPath = alternativePath;
        affectedSources.forEach(affectedSource -> {
            // Update the mcastPath store
            McastPathStoreKey mcastPathStoreKey = new McastPathStoreKey(mcastIp, affectedSource);
            // Verify if there are local sinks
            Set<DeviceId> localSinks = getSinks(mcastIp, srcDevice, affectedSource).stream().map(ConnectPoint::deviceId).collect(Collectors.toSet());
            Set<DeviceId> goodDevices = goodDevicesBySource.compute(affectedSource.deviceId(), (k, v) -> {
                v = v == null ? Sets.newHashSet() : v;
                v.addAll(localSinks);
                return v;
            });
            // TODO remove
            log.info("Good devices {}", goodDevicesBySource);
            Collection<? extends List<Link>> storedPathsBySource = Versioned.valueOrElse(mcastPathStore.get(mcastPathStoreKey), Lists.newArrayList());
            Optional<? extends List<Link>> storedPath = storedPathsBySource.stream().filter(path -> path.equals(affectedPath)).findFirst();
            // Remove bad links
            affectedPath.forEach(affectedLink -> {
                DeviceId affectedDevice = affectedLink.src().deviceId();
                // If there is overlap with good paths - skip it
                if (!goodLinks.contains(affectedLink)) {
                    removePortFromDevice(affectedDevice, affectedLink.src().port(), mcastIp, mcastUtils.assignedVlan(affectedDevice.equals(affectedSource.deviceId()) ? affectedSource : null));
                }
                // Remove role on the affected links if last
                if (!goodDevices.contains(affectedDevice)) {
                    mcastRoleStore.remove(new McastRoleStoreKey(mcastIp, affectedDevice, affectedSource));
                }
            });
            // trying with the original object as workaround
            if (storedPath.isPresent()) {
                mcastPathStore.remove(mcastPathStoreKey, storedPath.get());
            } else {
                log.warn("Unable to find the corresponding path - trying removeal");
                mcastPathStore.remove(mcastPathStoreKey, affectedPath);
            }
            // Program new links
            if (finalPath.isPresent()) {
                List<Link> links = finalPath.get().links();
                installPath(mcastIp, affectedSource, links);
                mcastPathStore.put(mcastPathStoreKey, links);
                links.forEach(link -> goodDevices.add(link.src().deviceId()));
                goodDevicesBySource.compute(srcDevice, (k, v) -> {
                    v = v == null ? Sets.newHashSet() : v;
                    v.addAll(goodDevices);
                    return v;
                });
                goodLinks.addAll(finalPath.get().links());
            }
        });
    });
}
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) Path(org.onosproject.net.Path) ImmutableSet(com.google.common.collect.ImmutableSet) Set(java.util.Set) DistributedSet(org.onosproject.store.service.DistributedSet) DeviceId(org.onosproject.net.DeviceId) ConnectPoint(org.onosproject.net.ConnectPoint) List(java.util.List) Link(org.onosproject.net.Link)

Example 27 with DeviceId

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

the class McastHandler method getSinks.

/**
 * Gets sink(s) of given multicast group.
 *
 * @param mcastIp multicast IP
 * @return set of connect point or empty set if not found
 */
private Set<ConnectPoint> getSinks(IpAddress mcastIp, DeviceId device, ConnectPoint source) {
    McastPathStoreKey pathStoreKey = new McastPathStoreKey(mcastIp, source);
    Collection<? extends List<Link>> storedPaths = Versioned.valueOrElse(mcastPathStore.get(pathStoreKey), Lists.newArrayList());
    VlanId assignedVlan = mcastUtils.assignedVlan(device.equals(source.deviceId()) ? source : null);
    McastStoreKey mcastStoreKey = new McastStoreKey(mcastIp, device, assignedVlan);
    NextObjective nextObjective = Versioned.valueOrNull(mcastNextObjStore.get(mcastStoreKey));
    ImmutableSet.Builder<ConnectPoint> cpBuilder = ImmutableSet.builder();
    if (nextObjective != null) {
        Set<PortNumber> outputPorts = mcastUtils.getPorts(nextObjective.next());
        outputPorts.forEach(portNumber -> cpBuilder.add(new ConnectPoint(device, portNumber)));
    }
    Set<ConnectPoint> egressCp = cpBuilder.build();
    return egressCp.stream().filter(connectPoint -> !mcastUtils.isInfraPort(connectPoint, storedPaths)).collect(Collectors.toSet());
}
Also used : NextObjective(org.onosproject.net.flowobjective.NextObjective) 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) ConnectPoint(org.onosproject.net.ConnectPoint) ImmutableSet(com.google.common.collect.ImmutableSet) PortNumber(org.onosproject.net.PortNumber) Link(org.onosproject.net.Link) VlanId(org.onlab.packet.VlanId)

Example 28 with DeviceId

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

the class McastHandler method buildMcastPaths.

/**
 * Build the mcast paths.
 *
 * @param storedPaths mcast tree
 * @param mcastIp the group ip
 * @param source the source
 */
private Map<ConnectPoint, List<ConnectPoint>> buildMcastPaths(Collection<? extends List<Link>> storedPaths, IpAddress mcastIp, ConnectPoint source) {
    Map<ConnectPoint, List<ConnectPoint>> mcastTree = Maps.newHashMap();
    // Local sinks
    Set<ConnectPoint> localSinks = getSinks(mcastIp, source.deviceId(), source);
    localSinks.forEach(localSink -> mcastTree.put(localSink, Lists.newArrayList(localSink, source)));
    // Remote sinks
    storedPaths.forEach(path -> {
        List<Link> links = path;
        DeviceId egressDevice = links.get(links.size() - 1).dst().deviceId();
        Set<ConnectPoint> remoteSinks = getSinks(mcastIp, egressDevice, source);
        List<ConnectPoint> connectPoints = Lists.newArrayList(source);
        links.forEach(link -> {
            connectPoints.add(link.src());
            connectPoints.add(link.dst());
        });
        Collections.reverse(connectPoints);
        remoteSinks.forEach(remoteSink -> {
            List<ConnectPoint> finalPath = Lists.newArrayList(connectPoints);
            finalPath.add(0, remoteSink);
            mcastTree.put(remoteSink, finalPath);
        });
    });
    return mcastTree;
}
Also used : DeviceId(org.onosproject.net.DeviceId) List(java.util.List) ConnectPoint(org.onosproject.net.ConnectPoint) Link(org.onosproject.net.Link)

Example 29 with DeviceId

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

the class McastHandler method removePortFromDevice.

/**
 * Removes a port from given multicast group on given device.
 * This involves the update of L3 multicast group and multicast routing
 * table entry.
 *
 * @param deviceId device ID
 * @param port port to be added
 * @param mcastIp multicast group
 * @param assignedVlan assigned VLAN ID
 * @return true if this is the last sink on this device
 */
private boolean removePortFromDevice(DeviceId deviceId, PortNumber port, IpAddress mcastIp, VlanId assignedVlan) {
    // TODO trace
    log.info("Removing {} on {}/{} and vlan {}", mcastIp, deviceId, port, assignedVlan);
    McastStoreKey mcastStoreKey = new McastStoreKey(mcastIp, deviceId, assignedVlan);
    // This device is not serving this multicast group
    if (!mcastNextObjStore.containsKey(mcastStoreKey)) {
        return true;
    }
    NextObjective nextObj = mcastNextObjStore.get(mcastStoreKey).value();
    Set<PortNumber> existingPorts = mcastUtils.getPorts(nextObj.next());
    // This port does not serve this multicast group
    if (!existingPorts.contains(port)) {
        if (!existingPorts.isEmpty()) {
            log.debug("{} is not serving {} on port {}. Abort.", deviceId, mcastIp, port);
            return false;
        }
        return true;
    }
    // Copy and modify the ImmutableSet
    existingPorts = Sets.newHashSet(existingPorts);
    existingPorts.remove(port);
    NextObjective newNextObj;
    ObjectiveContext context;
    ForwardingObjective fwdObj;
    if (existingPorts.isEmpty()) {
        context = new DefaultObjectiveContext((objective) -> log.debug("Successfully remove {} on {}/{}, vlan {}", mcastIp, deviceId, port.toLong(), assignedVlan), (objective, error) -> log.warn("Failed to remove {} on {}/{}, vlan {}: {}", mcastIp, deviceId, port.toLong(), assignedVlan, error));
        fwdObj = mcastUtils.fwdObjBuilder(mcastIp, assignedVlan, nextObj.id()).remove(context);
        if (!srManager.deviceConfiguration().isConfigured(deviceId)) {
            log.debug("skip forward flowobjective removal for device: {}", deviceId);
        } else {
            srManager.flowObjectiveService.forward(deviceId, fwdObj);
        }
        mcastNextObjStore.remove(mcastStoreKey);
    } else {
        // Here we store the next objective with the remaining port
        newNextObj = mcastUtils.nextObjBuilder(mcastIp, assignedVlan, existingPorts, nextObj.id()).removeFromExisting();
        mcastNextObjStore.put(mcastStoreKey, newNextObj);
        // Let's modify the next objective removing the bucket
        newNextObj = mcastUtils.nextObjBuilder(mcastIp, assignedVlan, ImmutableSet.of(port), nextObj.id()).removeFromExisting();
        if (!srManager.deviceConfiguration().isConfigured(deviceId)) {
            log.debug("skip next flowobjective update for device: {}", deviceId);
        } else {
            // no need to update the flow here since we have updated the next objective + group
            // the existing flow will keep pointing to the updated nextobj
            srManager.flowObjectiveService.next(deviceId, newNextObj);
        }
    }
    return existingPorts.isEmpty();
}
Also used : NextObjective(org.onosproject.net.flowobjective.NextObjective) 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) DefaultObjectiveContext(org.onosproject.net.flowobjective.DefaultObjectiveContext) ObjectiveContext(org.onosproject.net.flowobjective.ObjectiveContext) DefaultObjectiveContext(org.onosproject.net.flowobjective.DefaultObjectiveContext) ForwardingObjective(org.onosproject.net.flowobjective.ForwardingObjective) PortNumber(org.onosproject.net.PortNumber)

Example 30 with DeviceId

use of org.onosproject.net.DeviceId 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)

Aggregations

DeviceId (org.onosproject.net.DeviceId)782 List (java.util.List)178 PortNumber (org.onosproject.net.PortNumber)170 Collectors (java.util.stream.Collectors)152 ConnectPoint (org.onosproject.net.ConnectPoint)152 Set (java.util.Set)138 DeviceService (org.onosproject.net.device.DeviceService)122 DefaultTrafficTreatment (org.onosproject.net.flow.DefaultTrafficTreatment)118 ArrayList (java.util.ArrayList)115 VlanId (org.onlab.packet.VlanId)115 Logger (org.slf4j.Logger)114 Collections (java.util.Collections)109 DefaultTrafficSelector (org.onosproject.net.flow.DefaultTrafficSelector)109 Device (org.onosproject.net.Device)107 Collection (java.util.Collection)106 Test (org.junit.Test)104 CoreService (org.onosproject.core.CoreService)103 FlowRule (org.onosproject.net.flow.FlowRule)101 ImmutableSet (com.google.common.collect.ImmutableSet)99 TrafficTreatment (org.onosproject.net.flow.TrafficTreatment)96