Search in sources :

Example 51 with Path

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

the class MyTunnelApp method provisionTunnel.

/**
 * Provisions a tunnel between the given source and destination host with
 * the given tunnel ID. The tunnel is established using a randomly picked
 * shortest path based on the given topology snapshot.
 *
 * @param tunId   tunnel ID
 * @param srcHost tunnel source host
 * @param dstHost tunnel destination host
 * @param topo    topology snapshot
 */
private void provisionTunnel(int tunId, Host srcHost, Host dstHost, Topology topo) {
    // Get all shortest paths between switches connected to source and
    // destination hosts.
    DeviceId srcSwitch = srcHost.location().deviceId();
    DeviceId dstSwitch = dstHost.location().deviceId();
    List<Link> pathLinks;
    if (srcSwitch.equals(dstSwitch)) {
        // Source and dest hosts are connected to the same switch.
        pathLinks = Collections.emptyList();
    } else {
        // Compute shortest path.
        Set<Path> allPaths = topologyService.getPaths(topo, srcSwitch, dstSwitch);
        if (allPaths.size() == 0) {
            log.warn("No paths between {} and {}", srcHost.id(), dstHost.id());
            return;
        }
        // If many shortest paths are available, pick a random one.
        pathLinks = pickRandomPath(allPaths).links();
    }
    // Tunnel ingress rules.
    for (IpAddress dstIpAddr : dstHost.ipAddresses()) {
        // In ONOS discovered hosts can have multiple IP addresses.
        // Insert tunnel ingress rule for each IP address.
        // Next switches will forward based only on tunnel ID.
        insertTunnelIngressRule(srcSwitch, dstIpAddr, tunId);
    }
    // last one.
    for (Link link : pathLinks) {
        DeviceId sw = link.src().deviceId();
        PortNumber port = link.src().port();
        insertTunnelForwardRule(sw, port, tunId, false);
    }
    // Tunnel egress rule.
    PortNumber egressSwitchPort = dstHost.location().port();
    insertTunnelForwardRule(dstSwitch, egressSwitchPort, tunId, true);
    log.info("** Completed provisioning of tunnel {} (srcHost={} dstHost={})", tunId, srcHost.id(), dstHost.id());
}
Also used : Path(org.onosproject.net.Path) DeviceId(org.onosproject.net.DeviceId) IpAddress(org.onlab.packet.IpAddress) PortNumber(org.onosproject.net.PortNumber) Link(org.onosproject.net.Link)

Example 52 with Path

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

the class MyTunnelApp method pickRandomPath.

private Path pickRandomPath(Set<Path> paths) {
    int item = new Random().nextInt(paths.size());
    List<Path> pathList = Lists.newArrayList(paths);
    return pathList.get(item);
}
Also used : Path(org.onosproject.net.Path) Random(java.util.Random)

Example 53 with Path

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

the class OpticalConnectivityIntentCompiler method compile.

@Override
public List<Intent> compile(OpticalConnectivityIntent intent, List<Intent> installable) {
    // Check if source and destination are optical OCh ports
    ConnectPoint src = intent.getSrc();
    ConnectPoint dst = intent.getDst();
    checkArgument(deviceService.getPort(src.deviceId(), src.port()) instanceof OchPort);
    checkArgument(deviceService.getPort(dst.deviceId(), dst.port()) instanceof OchPort);
    List<Resource> resources = new LinkedList<>();
    log.debug("Compiling optical connectivity intent between {} and {}", src, dst);
    // Release of intent resources here is only a temporary solution for handling the
    // case of recompiling due to intent restoration (when intent state is FAILED).
    // TODO: try to release intent resources in IntentManager.
    resourceService.release(intent.key());
    // Check OCh port availability
    // If ports are not available, compilation fails
    // Else add port to resource reservation list
    Resource srcPortResource = Resources.discrete(src.deviceId(), src.port()).resource();
    Resource dstPortResource = Resources.discrete(dst.deviceId(), dst.port()).resource();
    if (!Stream.of(srcPortResource, dstPortResource).allMatch(resourceService::isAvailable)) {
        log.error("Ports for the intent are not available. Intent: {}", intent);
        throw new OpticalIntentCompilationException("Ports for the intent are not available. Intent: " + intent);
    }
    resources.add(srcPortResource);
    resources.add(dstPortResource);
    // If there is a suggestedPath, use this path without further checking, otherwise trigger path computation
    Stream<Path> paths;
    if (intent.suggestedPath().isPresent()) {
        paths = Stream.of(intent.suggestedPath().get());
    } else {
        paths = getOpticalPaths(intent);
    }
    // Find first path that has the required resources
    Optional<Map.Entry<Path, List<OchSignal>>> found = paths.map(path -> Maps.immutableEntry(path, findFirstAvailableLambda(intent, path))).filter(entry -> !entry.getValue().isEmpty()).filter(entry -> convertToResources(entry.getKey(), entry.getValue()).stream().allMatch(resourceService::isAvailable)).findFirst();
    // Allocate resources and create optical path intent
    if (found.isPresent()) {
        log.debug("Suitable lightpath FOUND for intent {}", intent);
        resources.addAll(convertToResources(found.get().getKey(), found.get().getValue()));
        allocateResources(intent, resources);
        OchSignal ochSignal = OchSignal.toFixedGrid(found.get().getValue(), ChannelSpacing.CHL_50GHZ);
        return ImmutableList.of(createIntent(intent, found.get().getKey(), ochSignal));
    } else {
        log.error("Unable to find suitable lightpath for intent {}", intent);
        throw new OpticalIntentCompilationException("Unable to find suitable lightpath for intent " + intent);
    }
}
Also used : Path(org.onosproject.net.Path) DefaultPath(org.onosproject.net.DefaultPath) DefaultOchSignalComparator(org.onosproject.net.DefaultOchSignalComparator) DeviceService(org.onosproject.net.device.DeviceService) LoggerFactory(org.slf4j.LoggerFactory) TopologyService(org.onosproject.net.topology.TopologyService) Link(org.onosproject.net.Link) ResourceService(org.onosproject.net.resource.ResourceService) ConnectPoint(org.onosproject.net.ConnectPoint) Preconditions.checkArgument(com.google.common.base.Preconditions.checkArgument) Topology(org.onosproject.net.topology.Topology) Port(org.onosproject.net.Port) Map(java.util.Map) OchPort(org.onosproject.net.optical.OchPort) DefaultLink(org.onosproject.net.DefaultLink) OchSignalType(org.onosproject.net.OchSignalType) ImmutableSet(com.google.common.collect.ImmutableSet) Resources(org.onosproject.net.resource.Resources) Deactivate(org.osgi.service.component.annotations.Deactivate) OpticalPathIntent(org.onosproject.net.intent.OpticalPathIntent) Collection(java.util.Collection) Set(java.util.Set) Resource(org.onosproject.net.resource.Resource) Collectors(java.util.stream.Collectors) Sets(com.google.common.collect.Sets) ResourceAllocation(org.onosproject.net.resource.ResourceAllocation) List(java.util.List) Stream(java.util.stream.Stream) Annotations(org.onosproject.net.Annotations) IntentCompiler(org.onosproject.net.intent.IntentCompiler) Optional(java.util.Optional) Path(org.onosproject.net.Path) ChannelSpacing(org.onosproject.net.ChannelSpacing) DeviceId(org.onosproject.net.DeviceId) IntStream(java.util.stream.IntStream) GridType(org.onosproject.net.GridType) TopologyEdge(org.onosproject.net.topology.TopologyEdge) AnnotationKeys(org.onosproject.net.AnnotationKeys) ArrayList(java.util.ArrayList) Component(org.osgi.service.component.annotations.Component) ImmutableList(com.google.common.collect.ImmutableList) DefaultPath(org.onosproject.net.DefaultPath) Intent(org.onosproject.net.intent.Intent) Activate(org.osgi.service.component.annotations.Activate) LinkedList(java.util.LinkedList) Logger(org.slf4j.Logger) IntentExtensionService(org.onosproject.net.intent.IntentExtensionService) ProviderId(org.onosproject.net.provider.ProviderId) Maps(com.google.common.collect.Maps) OchSignal(org.onosproject.net.OchSignal) ReferenceCardinality(org.osgi.service.component.annotations.ReferenceCardinality) DefaultAnnotations(org.onosproject.net.DefaultAnnotations) Weight(org.onlab.graph.Weight) OpticalDeviceServiceView.opticalView(org.onosproject.net.optical.device.OpticalDeviceServiceView.opticalView) LinkWeigher(org.onosproject.net.topology.LinkWeigher) Reference(org.osgi.service.component.annotations.Reference) ScalarWeight(org.onlab.graph.ScalarWeight) OpticalConnectivityIntent(org.onosproject.net.intent.OpticalConnectivityIntent) Collections(java.util.Collections) Resource(org.onosproject.net.resource.Resource) OchSignal(org.onosproject.net.OchSignal) ConnectPoint(org.onosproject.net.ConnectPoint) OchPort(org.onosproject.net.optical.OchPort) LinkedList(java.util.LinkedList)

Example 54 with Path

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

the class OpticalConnectivityIntentCompiler method getOpticalPaths.

/**
 * Calculates optical paths in WDM topology.
 *
 * @param intent optical connectivity intent
 * @return set of paths in WDM topology
 */
private Stream<Path> getOpticalPaths(OpticalConnectivityIntent intent) {
    // Route in WDM topology
    Topology topology = topologyService.currentTopology();
    // TODO: refactor with LinkWeigher class Implementation
    LinkWeigher weight = new LinkWeigher() {

        @Override
        public Weight getInitialWeight() {
            return ScalarWeight.toWeight(0.0);
        }

        @Override
        public Weight getNonViableWeight() {
            return ScalarWeight.NON_VIABLE_WEIGHT;
        }

        /**
         * @param edge edge to be weighed
         * @return the metric retrieved from the annotations otherwise 1
         */
        @Override
        public Weight weight(TopologyEdge edge) {
            log.debug("Link {} metric {}", edge.link(), edge.link().annotations().value("metric"));
            // Disregard inactive or non-optical links
            if (edge.link().state() == Link.State.INACTIVE) {
                return ScalarWeight.toWeight(-1);
            }
            if (edge.link().type() != Link.Type.OPTICAL) {
                return ScalarWeight.toWeight(-1);
            }
            // Adhere to static port mappings
            DeviceId srcDeviceId = edge.link().src().deviceId();
            if (srcDeviceId.equals(intent.getSrc().deviceId())) {
                ConnectPoint srcStaticPort = staticPort(intent.getSrc());
                if (srcStaticPort != null) {
                    return ScalarWeight.toWeight(srcStaticPort.equals(edge.link().src()) ? 1 : -1);
                }
            }
            DeviceId dstDeviceId = edge.link().dst().deviceId();
            if (dstDeviceId.equals(intent.getDst().deviceId())) {
                ConnectPoint dstStaticPort = staticPort(intent.getDst());
                if (dstStaticPort != null) {
                    return ScalarWeight.toWeight(dstStaticPort.equals(edge.link().dst()) ? 1 : -1);
                }
            }
            Annotations annotations = edge.link().annotations();
            if (annotations != null && annotations.value("metric") != null && !annotations.value("metric").isEmpty()) {
                double metric = Double.parseDouble(annotations.value("metric"));
                return ScalarWeight.toWeight(metric);
            } else {
                return ScalarWeight.toWeight(1);
            }
        }
    };
    ConnectPoint start = intent.getSrc();
    ConnectPoint end = intent.getDst();
    // 0 hop case
    if (start.deviceId().equals(end.deviceId())) {
        log.debug("install optical intent for 0 hop i.e srcDeviceId=dstDeviceId");
        DefaultLink defaultLink = DefaultLink.builder().providerId(PROVIDER_ID).src(start).dst(end).state(Link.State.ACTIVE).type(Link.Type.DIRECT).isExpected(true).build();
        List<Link> links = ImmutableList.<Link>builder().add(defaultLink).build();
        Annotations annotations = DefaultAnnotations.builder().build();
        DefaultPath defaultPath = new DefaultPath(PROVIDER_ID, links, null, annotations);
        return ImmutableList.<Path>builder().add(defaultPath).build().stream();
    }
    // head link's src port should be same as intent src port and tail link dst port
    // should be same as intent dst port in the path.
    Stream<Path> paths = topologyService.getKShortestPaths(topology, start.deviceId(), end.deviceId(), weight).filter(p -> p.links().get(0).src().port().equals(start.port()) && p.links().get(p.links().size() - 1).dst().port().equals(end.port()));
    if (log.isDebugEnabled()) {
        return paths.map(path -> {
            // no-op map stage to add debug logging
            log.debug("Candidate path: {}", path.links().stream().map(lk -> lk.src() + "-" + lk.dst()).collect(Collectors.toList()));
            return path;
        });
    }
    return paths;
}
Also used : Path(org.onosproject.net.Path) DefaultPath(org.onosproject.net.DefaultPath) DefaultLink(org.onosproject.net.DefaultLink) DeviceId(org.onosproject.net.DeviceId) Topology(org.onosproject.net.topology.Topology) TopologyEdge(org.onosproject.net.topology.TopologyEdge) ConnectPoint(org.onosproject.net.ConnectPoint) Annotations(org.onosproject.net.Annotations) DefaultAnnotations(org.onosproject.net.DefaultAnnotations) LinkWeigher(org.onosproject.net.topology.LinkWeigher) DefaultPath(org.onosproject.net.DefaultPath) Link(org.onosproject.net.Link) DefaultLink(org.onosproject.net.DefaultLink)

Example 55 with Path

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

the class ReactiveForwarding method backTrackBadNodes.

// Backtracks from link down event to remove flows that lead to blackhole
private void backTrackBadNodes(Set<Path> shortestPaths, DeviceId dstId, SrcDstPair sd) {
    for (Path p : shortestPaths) {
        List<Link> pathLinks = p.links();
        for (int i = 0; i < pathLinks.size(); i = i + 1) {
            Link curLink = pathLinks.get(i);
            DeviceId curDevice = curLink.src().deviceId();
            // skipping the first link because this link's src has already been pruned beforehand
            if (i != 0) {
                cleanFlowRules(sd, curDevice);
            }
            Set<Path> pathsFromCurDevice = topologyService.getPaths(topologyService.currentTopology(), curDevice, dstId);
            if (pickForwardPathIfPossible(pathsFromCurDevice, curLink.src().port()) != null) {
                break;
            } else {
                if (i + 1 == pathLinks.size()) {
                    cleanFlowRules(sd, curLink.dst().deviceId());
                }
            }
        }
    }
}
Also used : Path(org.onosproject.net.Path) DeviceId(org.onosproject.net.DeviceId) Link(org.onosproject.net.Link) ConnectPoint(org.onosproject.net.ConnectPoint)

Aggregations

Path (org.onosproject.net.Path)60 DeviceId (org.onosproject.net.DeviceId)27 DefaultPath (org.onosproject.net.DefaultPath)24 Link (org.onosproject.net.Link)23 DisjointPath (org.onosproject.net.DisjointPath)22 ConnectPoint (org.onosproject.net.ConnectPoint)18 Test (org.junit.Test)16 ImmutableSet (com.google.common.collect.ImmutableSet)12 ArrayList (java.util.ArrayList)11 List (java.util.List)11 Set (java.util.Set)11 Collectors (java.util.stream.Collectors)10 DefaultLink (org.onosproject.net.DefaultLink)10 Intent (org.onosproject.net.intent.Intent)10 Collections (java.util.Collections)9 Topology (org.onosproject.net.topology.Topology)8 Logger (org.slf4j.Logger)8 Stream (java.util.stream.Stream)7 ScalarWeight (org.onlab.graph.ScalarWeight)7 HostId (org.onosproject.net.HostId)7