[ONOS-7285][ONOS-7263] VLAN support by fabric.p4
Change-Id: I9ea460bca2698eb74f0d4988830a1e7cc7bc2768
diff --git a/pipelines/fabric/src/main/java/org/onosproject/pipelines/fabric/FabricTreatmentInterpreter.java b/pipelines/fabric/src/main/java/org/onosproject/pipelines/fabric/FabricTreatmentInterpreter.java
index 3dc2f41..3be56bb 100644
--- a/pipelines/fabric/src/main/java/org/onosproject/pipelines/fabric/FabricTreatmentInterpreter.java
+++ b/pipelines/fabric/src/main/java/org/onosproject/pipelines/fabric/FabricTreatmentInterpreter.java
@@ -50,6 +50,13 @@
final class FabricTreatmentInterpreter {
private static final Logger log = getLogger(FabricTreatmentInterpreter.class);
private static final String INVALID_TREATMENT = "Invalid treatment for %s block: %s";
+ private static final PiAction NOP = PiAction.builder()
+ .withId(FabricConstants.ACT_NOP_ID)
+ .build();
+
+ private static final PiAction POP_VLAN = PiAction.builder()
+ .withId(FabricConstants.ACT_FABRICEGRESS_EGRESS_NEXT_POP_VLAN_ID)
+ .build();
// Hide default constructor
protected FabricTreatmentInterpreter() {
@@ -72,9 +79,7 @@
Instruction noActInst = Instructions.createNoAction();
if (instructions.isEmpty() || instructions.contains(noActInst)) {
// nop
- return PiAction.builder()
- .withId(FabricConstants.ACT_NOP_ID)
- .build();
+ return NOP;
}
L2ModificationInstruction.ModVlanHeaderInstruction pushVlanInst = null;
@@ -159,17 +164,16 @@
* output
* set_vlan_output
* l3_routing
+ * l3_routing_vlan
* mpls_routing_v4
*
- * Unsupported, using PiAction directly:
- * set_next_type
- *
* Unsupported, need to find a way to implement it
* mpls_routing_v6
*/
public static PiAction mapNextTreatment(TrafficTreatment treatment)
throws PiInterpreterException {
+ // TODO: refactor this method
List<Instruction> insts = treatment.allInstructions();
OutputInstruction outInst = null;
ModEtherInstruction modEthDstInst = null;
@@ -195,8 +199,6 @@
case MPLS_LABEL:
modMplsInst = (ModMplsLabelInstruction) l2Inst;
break;
- case VLAN_PUSH:
- break;
default:
log.warn("Unsupported l2 instruction sub type: {}", l2Inst.subtype());
break;
@@ -212,8 +214,23 @@
}
if (outInst == null) {
- throw new PiInterpreterException(format(INVALID_TREATMENT, "next", treatment));
+ // for vlan_meta table only
+ if (modVlanIdInst != null) {
+ // set_vlan
+ VlanId vlanId = modVlanIdInst.vlanId();
+ PiActionParam newVlanParam =
+ new PiActionParam(FabricConstants.ACT_PRM_NEW_VLAN_ID_ID,
+ ImmutableByteSequence.copyFrom(vlanId.toShort()));
+ // set_vlan_output
+ return PiAction.builder()
+ .withId(FabricConstants.ACT_FABRICINGRESS_NEXT_SET_VLAN_ID)
+ .withParameter(newVlanParam)
+ .build();
+ } else {
+ throw new PiInterpreterException(format(INVALID_TREATMENT, "next", treatment));
+ }
}
+
short portNum = (short) outInst.port().toLong();
PiActionParam portNumParam = new PiActionParam(FabricConstants.ACT_PRM_PORT_NUM_ID,
ImmutableByteSequence.copyFrom(portNum));
@@ -267,15 +284,39 @@
}
}
- // L3 routing
- return PiAction.builder()
- .withId(FabricConstants.ACT_FABRICINGRESS_NEXT_L3_ROUTING_ID)
- .withParameters(ImmutableList.of(portNumParam,
- srcMacParam,
- dstMacParam))
- .build();
+ if (modVlanIdInst != null) {
+ VlanId vlanId = modVlanIdInst.vlanId();
+ PiActionParam vlanParam =
+ new PiActionParam(FabricConstants.ACT_PRM_NEW_VLAN_ID_ID,
+ ImmutableByteSequence.copyFrom(vlanId.toShort()));
+ // L3 routing and set VLAN
+ return PiAction.builder()
+ .withId(FabricConstants.ACT_FABRICINGRESS_NEXT_L3_ROUTING_VLAN_ID)
+ .withParameters(ImmutableList.of(srcMacParam, dstMacParam, portNumParam, vlanParam))
+ .build();
+ } else {
+ // L3 routing
+ return PiAction.builder()
+ .withId(FabricConstants.ACT_FABRICINGRESS_NEXT_L3_ROUTING_ID)
+ .withParameters(ImmutableList.of(portNumParam,
+ srcMacParam,
+ dstMacParam))
+ .build();
+ }
}
throw new PiInterpreterException(format(INVALID_TREATMENT, "next", treatment));
}
+
+ public static PiAction mapEgressNextTreatment(TrafficTreatment treatment) {
+ // Pop VLAN action for now, may add new action to this control block in the future.
+ return treatment.allInstructions()
+ .stream()
+ .filter(inst -> inst.type() == Instruction.Type.L2MODIFICATION)
+ .map(inst -> (L2ModificationInstruction) inst)
+ .filter(inst -> inst.subtype() == L2ModificationInstruction.L2SubType.VLAN_POP)
+ .findFirst()
+ .map(inst -> POP_VLAN)
+ .orElse(NOP);
+ }
}