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());
}
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);
}
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);
}
}
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;
}
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());
}
}
}
}
}
Aggregations