[SDFAB-102] Backport changes required for policies to fabric.p4 (Redirect)
Change-Id: I357c908d31abad9c3f8d74723d937ea948e54808
diff --git a/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/pipeliner/NextObjectiveTranslator.java b/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/pipeliner/NextObjectiveTranslator.java
index 8ecffb2..47b7ef6 100644
--- a/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/pipeliner/NextObjectiveTranslator.java
+++ b/pipelines/fabric/impl/src/main/java/org/onosproject/pipelines/fabric/impl/behaviour/pipeliner/NextObjectiveTranslator.java
@@ -17,6 +17,7 @@
package org.onosproject.pipelines.fabric.impl.behaviour.pipeliner;
import com.google.common.collect.Lists;
+import org.onlab.packet.MplsLabel;
import org.onlab.packet.VlanId;
import org.onosproject.net.DeviceId;
import org.onosproject.net.PortNumber;
@@ -28,6 +29,7 @@
import org.onosproject.net.flow.criteria.PiCriterion;
import org.onosproject.net.flow.criteria.VlanIdCriterion;
import org.onosproject.net.flow.instructions.Instruction;
+import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModMplsLabelInstruction;
import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModVlanIdInstruction;
import org.onosproject.net.flowobjective.DefaultNextTreatment;
import org.onosproject.net.flowobjective.NextObjective;
@@ -57,6 +59,7 @@
import java.util.stream.Collectors;
import static java.lang.String.format;
+import static org.onosproject.net.flow.instructions.L2ModificationInstruction.L2SubType.MPLS_LABEL;
import static org.onosproject.net.flow.instructions.L2ModificationInstruction.L2SubType.VLAN_ID;
import static org.onosproject.net.flow.instructions.L2ModificationInstruction.L2SubType.VLAN_POP;
import static org.onosproject.pipelines.fabric.impl.behaviour.FabricUtils.criterion;
@@ -103,13 +106,55 @@
}
if (!isGroupModifyOp(obj)) {
- // Generate next VLAN rules.
+ // Generate next MPLS and VLAN rules.
+ nextMpls(obj, resultBuilder);
nextVlan(obj, resultBuilder);
}
return resultBuilder.build();
}
+ private void nextMpls(NextObjective obj,
+ ObjectiveTranslation.Builder resultBuilder)
+ throws FabricPipelinerException {
+ // Next objective can contain only one mpls push and one mpls label
+ // instruction. Pipeliner does not support other configurations.
+
+ final List<List<ModMplsLabelInstruction>> mplsInstructions = defaultNextTreatments(
+ obj.nextTreatments(), false).stream()
+ .map(defaultNextTreatment -> l2Instructions(defaultNextTreatment.treatment(), MPLS_LABEL)
+ .stream().map(v -> (ModMplsLabelInstruction) v)
+ .collect(Collectors.toList()))
+ .filter(l -> !l.isEmpty())
+ .collect(Collectors.toList());
+
+ if (mplsInstructions.isEmpty()) {
+ // No need to apply next mpls table
+ return;
+ }
+
+ // We expect one mpls label for each treatment and the label has to be the same
+ final Set<MplsLabel> mplsLabels = mplsInstructions.stream()
+ .flatMap(Collection::stream)
+ .map(ModMplsLabelInstruction::label)
+ .collect(Collectors.toSet());
+ if (obj.nextTreatments().size() != mplsInstructions.size() ||
+ mplsLabels.size() != 1) {
+ throw new FabricPipelinerException(
+ "Inconsistent MPLS_LABEL instructions, cannot process " +
+ "next_mpls rule. It is required that all " +
+ "treatments have the same MPLS_LABEL instructions.");
+ }
+ final TrafficSelector selector = nextIdSelector(obj.id());
+ final TrafficTreatment treatment = DefaultTrafficTreatment.builder()
+ .setMpls(mplsLabels.iterator().next())
+ .build();
+
+ resultBuilder.addFlowRule(flowRule(
+ obj, FabricConstants.FABRIC_INGRESS_PRE_NEXT_NEXT_MPLS,
+ selector, treatment));
+ }
+
private void nextVlan(NextObjective obj,
ObjectiveTranslation.Builder resultBuilder)
throws FabricPipelinerException {
@@ -169,7 +214,7 @@
final TrafficTreatment treatment = treatmentBuilder.build();
resultBuilder.addFlowRule(flowRule(
- obj, FabricConstants.FABRIC_INGRESS_NEXT_NEXT_VLAN,
+ obj, FabricConstants.FABRIC_INGRESS_PRE_NEXT_NEXT_VLAN,
selector, treatment));
}
@@ -258,7 +303,7 @@
if (obj.meta() != null && obj.meta().getCriterion(Criterion.Type.VLAN_VID) != null) {
egressVlan(outPort, obj, popVlanInst, resultBuilder);
} else {
- log.warn("NextObjective {} is trying to program {} without {} information",
+ log.debug("NextObjective {} is trying to program {} without {} information",
obj, FabricConstants.FABRIC_EGRESS_EGRESS_NEXT_EGRESS_VLAN,
obj.meta() == null ? "metadata" : "vlanId");
}