use of org.onosproject.net.intent.IntentCompilationException in project onos by opennetworkinglab.
the class LinkCollectionCompiler method getDomainIntents.
/**
* Creates the domain intents that the {@link LinkCollectionIntent} contains.
*
* @param intent the link collection intent
* @param domainService the domain service
* @return the resulting list of domain intents
*/
protected List<Intent> getDomainIntents(LinkCollectionIntent intent, DomainService domainService) {
ImmutableList.Builder<Intent> intentList = ImmutableList.builder();
// TODO: support multi point to multi point
if (intent.filteredIngressPoints().size() != 1 || intent.filteredEgressPoints().size() != 1) {
log.warn("Multiple ingress or egress ports not supported!");
return intentList.build();
}
ImmutableList.Builder<Link> domainLinks = ImmutableList.builder();
// get the initial ingress connection point
FilteredConnectPoint ingress = intent.filteredIngressPoints().iterator().next();
FilteredConnectPoint egress;
DeviceId currentDevice = ingress.connectPoint().deviceId();
// the current domain (or LOCAL)
DomainId currentDomain = domainService.getDomain(currentDevice);
// if we entered a domain store the domain ingress
FilteredConnectPoint domainIngress = LOCAL.equals(currentDomain) ? null : ingress;
// this is necessary because a set is not sorted by default
for (int i = 0; i < intent.links().size(); i++) {
// find the next link
List<Link> nextLinks = getEgressLinks(intent.links(), currentDevice);
// no matching link exists
if (nextLinks.isEmpty()) {
throw new IntentCompilationException("No matching link starting at " + ingress.connectPoint().deviceId());
}
// get the first link
Link nextLink = nextLinks.get(0);
ingress = new FilteredConnectPoint(nextLink.src());
egress = new FilteredConnectPoint(nextLink.dst());
// query the domain for the domain of the link's destination
DomainId dstDomain = domainService.getDomain(egress.connectPoint().deviceId());
if (!currentDomain.equals(dstDomain)) {
// we are leaving the current domain or LOCAL
log.debug("Domain transition from {} to {}.", currentDomain, dstDomain);
if (!LOCAL.equals(currentDomain)) {
// add the domain intent to the intent list
intentList.add(createDomainP2PIntent(intent, domainIngress, ingress, domainLinks.build()));
// TODO: might end up with an unused builder
// reset domain links builder
domainLinks = ImmutableList.builder();
}
// update current domain (might be LOCAL)
currentDomain = dstDomain;
// update the domain's ingress
domainIngress = LOCAL.equals(currentDomain) ? null : egress;
} else {
if (!LOCAL.equals(currentDomain)) {
// we are staying in the same domain, store the traversed link
domainLinks.add(nextLink);
log.debug("{} belongs to the same domain.", egress.connectPoint().deviceId());
}
}
currentDevice = egress.connectPoint().deviceId();
}
// get the egress point
egress = intent.filteredEgressPoints().iterator().next();
// still inside a domain?
if (!LOCAL.equals(currentDomain) && currentDomain.equals(domainService.getDomain(egress.connectPoint().deviceId()))) {
// add intent
intentList.add(createDomainP2PIntent(intent, domainIngress, egress, domainLinks.build()));
}
return intentList.build();
}
use of org.onosproject.net.intent.IntentCompilationException in project onos by opennetworkinglab.
the class PathCompiler method manageVlanEncap.
/**
* Creates the flow rules for the path intent using VLAN
* encapsulation.
*
* @param creator the flowrules creator
* @param flows the list of flows to fill
* @param devices the devices on the path
* @param intent the PathIntent to compile
*/
private void manageVlanEncap(PathCompilerCreateFlow<T> creator, List<T> flows, List<DeviceId> devices, PathIntent intent) {
Set<Link> linksSet = Sets.newConcurrentHashSet();
for (int i = 1; i <= intent.path().links().size() - 2; i++) {
linksSet.add(intent.path().links().get(i));
}
Map<LinkKey, Identifier<?>> vlanIds = labelAllocator.assignLabelToLinks(linksSet, intent.key(), EncapsulationType.VLAN);
Iterator<Link> links = intent.path().links().iterator();
Link srcLink = links.next();
Link link = links.next();
// Ingress traffic
VlanId vlanId = (VlanId) vlanIds.get(linkKey(link));
if (vlanId == null) {
throw new IntentCompilationException(ERROR_VLAN + link);
}
VlanId prevVlanId = vlanId;
Optional<VlanIdCriterion> vlanCriterion = intent.selector().criteria().stream().filter(criterion -> criterion.type() == Criterion.Type.VLAN_VID).map(criterion -> (VlanIdCriterion) criterion).findAny();
// Push VLAN if selector does not include VLAN
TrafficTreatment.Builder treatBuilder = DefaultTrafficTreatment.builder();
if (!vlanCriterion.isPresent()) {
treatBuilder.pushVlan();
}
// Tag the traffic with the new encapsulation VLAN
treatBuilder.setVlanId(vlanId);
creator.createFlow(intent.selector(), treatBuilder.build(), srcLink.dst(), link.src(), intent.priority(), true, flows, devices);
ConnectPoint prev = link.dst();
while (links.hasNext()) {
link = links.next();
if (links.hasNext()) {
// Transit traffic
VlanId egressVlanId = (VlanId) vlanIds.get(linkKey(link));
if (egressVlanId == null) {
throw new IntentCompilationException(ERROR_VLAN + link);
}
TrafficSelector transitSelector = DefaultTrafficSelector.builder().matchInPort(prev.port()).matchVlanId(prevVlanId).build();
TrafficTreatment.Builder transitTreat = DefaultTrafficTreatment.builder();
// Set the new vlanId only if the previous one is different
if (!prevVlanId.equals(egressVlanId)) {
transitTreat.setVlanId(egressVlanId);
}
creator.createFlow(transitSelector, transitTreat.build(), prev, link.src(), intent.priority(), true, flows, devices);
/* For the next hop we have to remember
* the previous egress VLAN id and the egress
* node
*/
prevVlanId = egressVlanId;
prev = link.dst();
} else {
// Egress traffic
TrafficSelector egressSelector = DefaultTrafficSelector.builder().matchInPort(prev.port()).matchVlanId(prevVlanId).build();
TrafficTreatment.Builder egressTreat = DefaultTrafficTreatment.builder(intent.treatment());
Optional<L2ModificationInstruction.ModVlanIdInstruction> modVlanIdInstruction = intent.treatment().allInstructions().stream().filter(instruction -> instruction instanceof L2ModificationInstruction.ModVlanIdInstruction).map(x -> (L2ModificationInstruction.ModVlanIdInstruction) x).findAny();
Optional<L2ModificationInstruction.ModVlanHeaderInstruction> popVlanInstruction = intent.treatment().allInstructions().stream().filter(instruction -> instruction instanceof L2ModificationInstruction.ModVlanHeaderInstruction).map(x -> (L2ModificationInstruction.ModVlanHeaderInstruction) x).findAny();
if (!modVlanIdInstruction.isPresent() && !popVlanInstruction.isPresent()) {
if (vlanCriterion.isPresent()) {
egressTreat.setVlanId(vlanCriterion.get().vlanId());
} else {
egressTreat.popVlan();
}
}
creator.createFlow(egressSelector, egressTreat.build(), prev, link.src(), intent.priority(), true, flows, devices);
}
}
}
use of org.onosproject.net.intent.IntentCompilationException in project onos by opennetworkinglab.
the class PathCompiler method manageMplsEncap.
/**
* Creates the flow rules for the path intent using MPLS
* encapsulation.
*
* @param creator the flowrules creator
* @param flows the list of flows to fill
* @param devices the devices on the path
* @param intent the PathIntent to compile
*/
private void manageMplsEncap(PathCompilerCreateFlow<T> creator, List<T> flows, List<DeviceId> devices, PathIntent intent) {
Set<Link> linksSet = Sets.newConcurrentHashSet();
for (int i = 1; i <= intent.path().links().size() - 2; i++) {
linksSet.add(intent.path().links().get(i));
}
Map<LinkKey, Identifier<?>> mplsLabels = labelAllocator.assignLabelToLinks(linksSet, intent.key(), EncapsulationType.MPLS);
Iterator<Link> links = intent.path().links().iterator();
Link srcLink = links.next();
Link link = links.next();
// List of flow rules to be installed
// Ingress traffic
MplsLabel mplsLabel = (MplsLabel) mplsLabels.get(linkKey(link));
if (mplsLabel == null) {
throw new IntentCompilationException(ERROR_MPLS + link);
}
MplsLabel prevMplsLabel = mplsLabel;
Optional<MplsCriterion> mplsCriterion = intent.selector().criteria().stream().filter(criterion -> criterion.type() == Criterion.Type.MPLS_LABEL).map(criterion -> (MplsCriterion) criterion).findAny();
// Push MPLS if selector does not include MPLS
TrafficTreatment.Builder treatBuilder = DefaultTrafficTreatment.builder();
if (!mplsCriterion.isPresent()) {
treatBuilder.pushMpls();
}
// Tag the traffic with the new encapsulation MPLS label
treatBuilder.setMpls(mplsLabel);
creator.createFlow(intent.selector(), treatBuilder.build(), srcLink.dst(), link.src(), intent.priority(), true, flows, devices);
ConnectPoint prev = link.dst();
while (links.hasNext()) {
link = links.next();
if (links.hasNext()) {
// Transit traffic
MplsLabel transitMplsLabel = (MplsLabel) mplsLabels.get(linkKey(link));
if (transitMplsLabel == null) {
throw new IntentCompilationException(ERROR_MPLS + link);
}
TrafficSelector transitSelector = DefaultTrafficSelector.builder().matchInPort(prev.port()).matchEthType(Ethernet.MPLS_UNICAST).matchMplsLabel(prevMplsLabel).build();
TrafficTreatment.Builder transitTreat = DefaultTrafficTreatment.builder();
// Set the new MPLS label only if the previous one is different
if (!prevMplsLabel.equals(transitMplsLabel)) {
transitTreat.setMpls(transitMplsLabel);
}
creator.createFlow(transitSelector, transitTreat.build(), prev, link.src(), intent.priority(), true, flows, devices);
prevMplsLabel = transitMplsLabel;
prev = link.dst();
} else {
TrafficSelector.Builder egressSelector = DefaultTrafficSelector.builder().matchInPort(prev.port()).matchEthType(Ethernet.MPLS_UNICAST).matchMplsLabel(prevMplsLabel);
TrafficTreatment.Builder egressTreat = DefaultTrafficTreatment.builder(intent.treatment());
// than selector needs to match any VlanId
for (Instruction instruct : intent.treatment().allInstructions()) {
if (instruct instanceof L2ModificationInstruction) {
L2ModificationInstruction l2Mod = (L2ModificationInstruction) instruct;
if (l2Mod.subtype() == L2ModificationInstruction.L2SubType.VLAN_PUSH) {
break;
}
if (l2Mod.subtype() == L2ModificationInstruction.L2SubType.VLAN_POP || l2Mod.subtype() == L2ModificationInstruction.L2SubType.VLAN_ID) {
egressSelector.matchVlanId(VlanId.ANY);
}
}
}
if (mplsCriterion.isPresent()) {
egressTreat.setMpls(mplsCriterion.get().label());
} else {
egressTreat.popMpls(getEthType(intent.selector()));
}
creator.createFlow(egressSelector.build(), egressTreat.build(), prev, link.src(), intent.priority(), true, flows, devices);
}
}
}
use of org.onosproject.net.intent.IntentCompilationException in project onos by opennetworkinglab.
the class PointToPointIntentCompiler method waitForGroup.
/**
* Waits for specified group to appear until timeout.
*
* @param deviceId {@link DeviceId}
* @param groupKey {@link GroupKey} to wait for.
* @param timeout timeout
* @param unit unit of timeout
* @return {@link Group}
* @throws IntentCompilationException on any error.
*/
private Group waitForGroup(DeviceId deviceId, GroupKey groupKey, long timeout, TimeUnit unit) {
Group group = groupService.getGroup(deviceId, groupKey);
if (group != null) {
return group;
}
final CompletableFuture<Group> future = new CompletableFuture<>();
final GroupListener listener = event -> {
if (event.subject().deviceId() == deviceId && event.subject().appCookie().equals(groupKey)) {
future.complete(event.subject());
return;
}
};
groupService.addListener(listener);
try {
group = groupService.getGroup(deviceId, groupKey);
if (group != null) {
return group;
}
return future.get(timeout, unit);
} catch (InterruptedException e) {
log.debug("Interrupted", e);
Thread.currentThread().interrupt();
throw new IntentCompilationException("Interrupted", e);
} catch (ExecutionException e) {
log.debug("ExecutionException", e);
throw new IntentCompilationException("ExecutionException caught", e);
} catch (TimeoutException e) {
// one last try
group = groupService.getGroup(deviceId, groupKey);
if (group != null) {
return group;
} else {
log.debug("Timeout", e);
throw new IntentCompilationException("Timeout", e);
}
} finally {
groupService.removeListener(listener);
}
}
Aggregations