Improvement in fabric.p4 and bng.p4

- fabric.p4 now supports double tagged hosts
- bng.p4 now only manages PPPoE termination
- bng_ingress moved at the end of the fabric pipeline

Change-Id: Iff62238fde9ec6ddf7311312a98c041e3ab3aa8d
diff --git a/pipelines/fabric/src/test/java/org/onosproject/pipelines/fabric/pipeliner/FabricFilteringPipelinerTest.java b/pipelines/fabric/src/test/java/org/onosproject/pipelines/fabric/pipeliner/FabricFilteringPipelinerTest.java
index 3bdab99..dbb2bd4 100644
--- a/pipelines/fabric/src/test/java/org/onosproject/pipelines/fabric/pipeliner/FabricFilteringPipelinerTest.java
+++ b/pipelines/fabric/src/test/java/org/onosproject/pipelines/fabric/pipeliner/FabricFilteringPipelinerTest.java
@@ -31,6 +31,7 @@
 import org.onosproject.net.flow.TrafficSelector;
 import org.onosproject.net.flow.TrafficTreatment;
 import org.onosproject.net.flow.criteria.Criteria;
+import org.onosproject.net.flow.criteria.PiCriterion;
 import org.onosproject.net.flowobjective.DefaultFilteringObjective;
 import org.onosproject.net.flowobjective.FilteringObjective;
 import org.onosproject.net.flowobjective.ObjectiveError;
@@ -45,6 +46,8 @@
  */
 public class FabricFilteringPipelinerTest extends FabricPipelinerTest {
 
+    public static final byte[] ONE = {1};
+    public static final byte[] ZERO = {0};
     private FilteringObjectiveTranslator translator;
 
     @Before
@@ -67,6 +70,7 @@
         FlowRule inportFlowRuleExpected =
                 buildExpectedVlanInPortRule(PORT_1,
                                             VlanId.NONE,
+                                            VlanId.NONE,
                                             VLAN_100,
                                             FabricConstants.FABRIC_INGRESS_FILTERING_INGRESS_PORT_VLAN);
 
@@ -128,6 +132,7 @@
         FlowRule inportFlowRuleExpected =
                 buildExpectedVlanInPortRule(PORT_1,
                                             VlanId.NONE,
+                                            VlanId.NONE,
                                             VLAN_100,
                                             FabricConstants.FABRIC_INGRESS_FILTERING_INGRESS_PORT_VLAN);
 
@@ -173,6 +178,7 @@
         FlowRule inportFlowRuleExpected =
                 buildExpectedVlanInPortRule(PORT_1,
                                             VlanId.NONE,
+                                            VlanId.NONE,
                                             VLAN_100,
                                             FabricConstants.FABRIC_INGRESS_FILTERING_INGRESS_PORT_VLAN);
 
@@ -204,6 +210,7 @@
         FlowRule flowRuleExpected =
                 buildExpectedVlanInPortRule(PORT_1,
                                             VlanId.NONE,
+                                            VlanId.NONE,
                                             VLAN_100,
                                             FabricConstants.FABRIC_INGRESS_FILTERING_INGRESS_PORT_VLAN);
 
@@ -234,7 +241,7 @@
 
         TrafficSelector.Builder selector = DefaultTrafficSelector.builder()
                 .matchInPort(PORT_1)
-                .matchPi(VLAN_INVALID);
+                .matchPi(buildPiCriterionVlan(null, null));
         PiAction piAction = PiAction.builder()
                     .withId(FabricConstants.FABRIC_INGRESS_FILTERING_DENY)
                     .build();
@@ -287,6 +294,48 @@
         assertError(ObjectiveError.BADPARAMS, result2);
     }
 
+    /**
+     * Test the mapping between EtherType and conditions.
+     */
+    @Test
+    public void testMappingEthType() {
+        PiCriterion expectedMappingDefault = PiCriterion.builder()
+                .matchExact(FabricConstants.HDR_IS_MPLS, ZERO)
+                .matchExact(FabricConstants.HDR_IS_IPV4, ZERO)
+                .matchExact(FabricConstants.HDR_IS_IPV6, ZERO)
+                .build();
+        PiCriterion expectedMappingIpv6 = PiCriterion.builder()
+                .matchExact(FabricConstants.HDR_IS_MPLS, ZERO)
+                .matchExact(FabricConstants.HDR_IS_IPV4, ZERO)
+                .matchExact(FabricConstants.HDR_IS_IPV6, ONE)
+                .build();
+        PiCriterion expectedMappingIpv4 = PiCriterion.builder()
+                .matchExact(FabricConstants.HDR_IS_MPLS, ZERO)
+                .matchExact(FabricConstants.HDR_IS_IPV4, ONE)
+                .matchExact(FabricConstants.HDR_IS_IPV6, ZERO)
+                .build();
+        PiCriterion expectedMappingMpls = PiCriterion.builder()
+                .matchExact(FabricConstants.HDR_IS_MPLS, ONE)
+                .matchExact(FabricConstants.HDR_IS_IPV4, ZERO)
+                .matchExact(FabricConstants.HDR_IS_IPV6, ZERO)
+                .build();
+
+
+        PiCriterion actualMappingIpv6 = FilteringObjectiveTranslator.mapEthTypeFwdClassifier(Ethernet.TYPE_IPV6);
+        assertEquals(expectedMappingIpv6, actualMappingIpv6);
+
+        PiCriterion actualMappingIpv4 = FilteringObjectiveTranslator.mapEthTypeFwdClassifier(Ethernet.TYPE_IPV4);
+        assertEquals(expectedMappingIpv4, actualMappingIpv4);
+
+        PiCriterion actualMappingMpls = FilteringObjectiveTranslator.mapEthTypeFwdClassifier(Ethernet.MPLS_UNICAST);
+        assertEquals(expectedMappingMpls, actualMappingMpls);
+
+        PiCriterion actualMapping = FilteringObjectiveTranslator.mapEthTypeFwdClassifier(Ethernet.TYPE_ARP);
+        assertEquals(expectedMappingDefault, actualMapping);
+
+
+    }
+
     /* Utilities */
 
     private void assertError(ObjectiveError error, ObjectiveTranslation actualTranslation) {
@@ -314,22 +363,23 @@
         return builder.add();
     }
 
-    private FlowRule buildExpectedVlanInPortRule(PortNumber inPort, VlanId vlanId,
+    private FlowRule buildExpectedVlanInPortRule(PortNumber inPort,
+                                                 VlanId vlanId,
+                                                 VlanId innerVlanId,
                                                  VlanId internalVlan,
                                                  TableId tableId) {
 
         TrafficSelector.Builder selector = DefaultTrafficSelector.builder()
                 .matchInPort(inPort);
         PiAction piAction;
-        if (vlanId == null || vlanId.equals(VlanId.NONE)) {
-            selector.matchPi(VLAN_INVALID);
+        selector.matchPi(buildPiCriterionVlan(vlanId, innerVlanId));
+        if (!vlanValid(vlanId)) {
             piAction = PiAction.builder()
                     .withId(FabricConstants.FABRIC_INGRESS_FILTERING_PERMIT_WITH_INTERNAL_VLAN)
                     .withParameter(new PiActionParam(
                             FabricConstants.VLAN_ID, internalVlan.toShort()))
                     .build();
         } else {
-            selector.matchPi(VLAN_VALID);
             selector.matchVlanId(vlanId);
             piAction = PiAction.builder()
                     .withId(FabricConstants.FABRIC_INGRESS_FILTERING_PERMIT)
@@ -348,6 +398,18 @@
                 .build();
     }
 
+    private boolean vlanValid(VlanId vlanId) {
+        return (vlanId != null && !vlanId.equals(VlanId.NONE));
+    }
+
+    private PiCriterion buildPiCriterionVlan(VlanId vlanId,
+                                             VlanId innerVlanId) {
+        PiCriterion.Builder piCriterionBuilder = PiCriterion.builder()
+                .matchExact(FabricConstants.HDR_VLAN_IS_VALID,
+                            vlanValid(vlanId) ? ONE : ZERO);
+        return piCriterionBuilder.build();
+    }
+
     private FlowRule buildExpectedFwdClassifierRule(PortNumber inPort,
                                                     MacAddress dstMac,
                                                     MacAddress dstMacMask,
@@ -355,7 +417,7 @@
                                                     byte fwdClass) {
         TrafficSelector.Builder sbuilder = DefaultTrafficSelector.builder()
                 .matchInPort(inPort)
-                .matchEthType(ethType);
+                .matchPi(FilteringObjectiveTranslator.mapEthTypeFwdClassifier(ethType));
         if (dstMacMask != null) {
             sbuilder.matchEthDstMasked(dstMac, dstMacMask);
         } else {