use of org.onosproject.net.intent.PathIntent 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);
}
}
}
Aggregations