use of org.onosproject.net.Link in project onos by opennetworkinglab.
the class PathCompiler method compile.
/**
* Compiles an intent down to flows.
*
* @param creator how to create the flows
* @param intent intent to process
* @param flows list of generated flows
* @param devices list of devices that correspond to the flows
*/
public void compile(PathCompilerCreateFlow<T> creator, PathIntent intent, List<T> flows, List<DeviceId> devices) {
// Note: right now recompile is not considered
// TODO: implement recompile behavior
List<Link> links = intent.path().links();
Optional<EncapsulationConstraint> encapConstraint = intent.constraints().stream().filter(constraint -> constraint instanceof EncapsulationConstraint).map(x -> (EncapsulationConstraint) x).findAny();
// if no encapsulation or is involved only a single switch use the default behaviour
if (!encapConstraint.isPresent() || links.size() == 2) {
for (int i = 0; i < links.size() - 1; i++) {
ConnectPoint ingress = links.get(i).dst();
ConnectPoint egress = links.get(i + 1).src();
creator.createFlow(intent.selector(), intent.treatment(), ingress, egress, intent.priority(), isLast(links, i), flows, devices);
}
return;
}
encapConstraint.map(EncapsulationConstraint::encapType).map(type -> {
switch(type) {
case VLAN:
manageVlanEncap(creator, flows, devices, intent);
break;
case MPLS:
manageMplsEncap(creator, flows, devices, intent);
break;
default:
}
return 0;
});
}
use of org.onosproject.net.Link in project onos by opennetworkinglab.
the class PointToPointIntentCompiler method createSinglePathIntent.
private List<Intent> createSinglePathIntent(ConnectPoint ingressPoint, ConnectPoint egressPoint, PointToPointIntent intent, List<Intent> installable) {
List<Link> links = new ArrayList<>();
Path onlyPath = getPathOrException(intent, ingressPoint.deviceId(), egressPoint.deviceId());
List<Intent> reusableIntents = null;
if (installable != null) {
reusableIntents = filterInvalidSubIntents(installable, intent);
if (reusableIntents.size() == installable.size()) {
// all old paths are still viable
return installable;
}
}
// return the intents that comprise it.
if (reusableIntents != null && reusableIntents.size() > 1) {
return reusableIntents;
} else {
// Allocate bandwidth if a bandwidth constraint is set
allocateIntentBandwidth(intent, onlyPath);
links.add(createEdgeLink(ingressPoint, true));
links.addAll(onlyPath.links());
links.add(createEdgeLink(egressPoint, false));
return asList(createPathIntent(new DefaultPath(PID, links, onlyPath.weight(), onlyPath.annotations()), intent, PathIntent.ProtectionType.PRIMARY));
}
}
use of org.onosproject.net.Link in project onos by opennetworkinglab.
the class PointToPointIntentCompiler method pathAvailable.
/**
* Checks suggested path availability.
* It checks:
* - single links availability;
* - that first and last device of the path are coherent with ingress and egress devices;
* - links contiguity.
*
* @param intent Intent with suggested path to check
* @return true if the suggested path is available
*/
private boolean pathAvailable(PointToPointIntent intent) {
// Check links availability
List<Link> suggestedPath = intent.suggestedPath();
for (Link link : suggestedPath) {
if (!(link instanceof EdgeLink) && !linkService.getLinks(link.src()).contains(link)) {
return false;
}
}
// Check that first and last device of the path are intent ingress and egress devices
if (!suggestedPath.get(0).src().deviceId().equals(intent.filteredIngressPoint().connectPoint().deviceId())) {
return false;
}
if (!suggestedPath.get(suggestedPath.size() - 1).dst().deviceId().equals(intent.filteredEgressPoint().connectPoint().deviceId())) {
return false;
}
// Check contiguity
List<Pair<Link, Link>> linkPairs = IntStream.range(0, suggestedPath.size() - 1).mapToObj(i -> Pair.of(suggestedPath.get(i), suggestedPath.get(i + 1))).collect(Collectors.toList());
for (Pair<Link, Link> linkPair : linkPairs) {
if (!linkPair.getKey().dst().deviceId().equals(linkPair.getValue().src().deviceId())) {
return false;
}
}
return true;
}
use of org.onosproject.net.Link in project onos by opennetworkinglab.
the class PointToPointIntentCompiler method createProtectedIntent.
// FIXME: Compatibility with EncapsulationConstraint
private List<Intent> createProtectedIntent(ConnectPoint ingressPoint, ConnectPoint egressPoint, PointToPointIntent intent, List<Intent> installable) {
log.trace("createProtectedIntent");
DisjointPath path = getDisjointPath(intent, ingressPoint.deviceId(), egressPoint.deviceId());
List<Intent> reusableIntents = null;
if (installable != null) {
reusableIntents = filterInvalidSubIntents(installable, intent);
if (reusableIntents.size() == installable.size()) {
// all old paths are still viable
return installable;
}
}
List<Intent> intentList = new ArrayList<>();
// primary path intent
List<Link> links = new ArrayList<>();
links.addAll(path.links());
links.add(createEdgeLink(egressPoint, false));
// backup path intent
List<Link> backupLinks = new ArrayList<>();
backupLinks.addAll(path.backup().links());
backupLinks.add(createEdgeLink(egressPoint, false));
/*
* One of the old paths is still entirely intact. This old path has
* already been made primary, so we must add a backup path intent
* and modify the failover group treatment accordingly.
*/
if (reusableIntents != null && reusableIntents.size() > 1) {
/*
* Ensures that the egress port on source device is different than
* that of existing path so that failover group will be useful
* (would not be useful if both output ports in group bucket were
* the same). Does not necessarily ensure that the new backup path
* is entirely disjoint from the old path.
*/
PortNumber primaryPort = getPrimaryPort(intent);
if (primaryPort != null && !links.get(0).src().port().equals(primaryPort)) {
reusableIntents.add(createPathIntent(new DefaultPath(PID, links, path.weight(), path.annotations()), intent, PathIntent.ProtectionType.BACKUP));
updateFailoverGroup(intent, links);
return reusableIntents;
} else {
reusableIntents.add(createPathIntent(new DefaultPath(PID, backupLinks, path.backup().weight(), path.backup().annotations()), intent, PathIntent.ProtectionType.BACKUP));
updateFailoverGroup(intent, backupLinks);
return reusableIntents;
}
}
intentList.add(createPathIntent(new DefaultPath(PID, links, path.weight(), path.annotations()), intent, PathIntent.ProtectionType.PRIMARY));
intentList.add(createPathIntent(new DefaultPath(PID, backupLinks, path.backup().weight(), path.backup().annotations()), intent, PathIntent.ProtectionType.BACKUP));
// add contents appropriately.
if (groupService.getGroup(ingressPoint.deviceId(), makeGroupKey(intent.id())) == null) {
// manufactured fast failover flow rule intent
createFailoverTreatmentGroup(path.links(), path.backup().links(), intent);
FlowRuleIntent frIntent = new FlowRuleIntent(intent.appId(), intent.key(), createFailoverFlowRules(intent), asList(ingressPoint.deviceId()), PathIntent.ProtectionType.FAILOVER, intent.resourceGroup());
intentList.add(frIntent);
} else {
updateFailoverGroup(intent, links);
updateFailoverGroup(intent, backupLinks);
}
return intentList;
}
use of org.onosproject.net.Link in project onos by opennetworkinglab.
the class SinglePointToMultiPointIntentCompiler method compile.
@Override
public List<Intent> compile(SinglePointToMultiPointIntent intent, List<Intent> installable) {
Set<Link> links = new HashSet<>();
final boolean allowMissingPaths = intentAllowsPartialFailure(intent);
boolean hasPaths = false;
boolean missingSomePaths = false;
for (ConnectPoint egressPoint : intent.egressPoints()) {
if (egressPoint.deviceId().equals(intent.ingressPoint().deviceId())) {
// devices are the same.
if (deviceService.isAvailable(egressPoint.deviceId())) {
hasPaths = true;
} else {
missingSomePaths = true;
}
continue;
}
Path path = getPath(intent, intent.ingressPoint().deviceId(), egressPoint.deviceId());
if (path != null) {
hasPaths = true;
links.addAll(path.links());
} else {
missingSomePaths = true;
}
}
// Allocate bandwidth if a bandwidth constraint is set
ConnectPoint ingressCP = intent.filteredIngressPoint().connectPoint();
List<ConnectPoint> egressCPs = intent.filteredEgressPoints().stream().map(fcp -> fcp.connectPoint()).collect(Collectors.toList());
List<ConnectPoint> pathCPs = links.stream().flatMap(l -> Stream.of(l.src(), l.dst())).collect(Collectors.toList());
pathCPs.add(ingressCP);
pathCPs.addAll(egressCPs);
allocateBandwidth(intent, pathCPs);
if (!hasPaths) {
throw new IntentException("Cannot find any path between ingress and egress points.");
} else if (!allowMissingPaths && missingSomePaths) {
throw new IntentException("Missing some paths between ingress and egress points.");
}
Intent result = LinkCollectionIntent.builder().appId(intent.appId()).key(intent.key()).selector(intent.selector()).treatment(intent.treatment()).links(links).filteredIngressPoints(ImmutableSet.of(intent.filteredIngressPoint())).filteredEgressPoints(intent.filteredEgressPoints()).priority(intent.priority()).applyTreatmentOnEgress(true).constraints(intent.constraints()).resourceGroup(intent.resourceGroup()).build();
return Collections.singletonList(result);
}
Aggregations