Match VLAN_VID in TMAC table for mcast flows

Matching VLAN_VID in TMAC table is mandatory on QMX switches
XGS switches support optional VLAN_VID matching so this patch is effective for both platforms

In addition,
- Take native vlan into account when assigning VLAN for untagged multicast traffic
- Fix a bug that puts wrong eth_type in TMAC table

Change-Id: I19caf2d6d69096a96b75cb528b6ed37b28d7d988
diff --git a/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/McastHandler.java b/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/McastHandler.java
index bbbbc3c..a51d2f4 100644
--- a/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/McastHandler.java
+++ b/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/McastHandler.java
@@ -774,7 +774,7 @@
         }
         // Reuse unicast VLAN if the port has subnet configured
         if (cp != null) {
-            VlanId untaggedVlan = srManager.getUntaggedVlanId(cp);
+            VlanId untaggedVlan = srManager.getInternalVlanId(cp);
             return (untaggedVlan != null) ? untaggedVlan : INTERNAL_VLAN;
         }
         // Use DEFAULT_VLAN if none of the above matches
diff --git a/drivers/default/src/main/java/org/onosproject/driver/pipeline/ofdpa/CpqdOfdpa2Pipeline.java b/drivers/default/src/main/java/org/onosproject/driver/pipeline/ofdpa/CpqdOfdpa2Pipeline.java
index 9f2e84c..c5698a4 100644
--- a/drivers/default/src/main/java/org/onosproject/driver/pipeline/ofdpa/CpqdOfdpa2Pipeline.java
+++ b/drivers/default/src/main/java/org/onosproject/driver/pipeline/ofdpa/CpqdOfdpa2Pipeline.java
@@ -326,7 +326,7 @@
 
         // Multicast MAC
         if (ethCriterion.mask() != null) {
-            return processMcastEthDstFilter(ethCriterion, applicationId);
+            return processMcastEthDstFilter(ethCriterion, assignedVlan, applicationId);
         }
 
         //handling untagged packets via assigned VLAN
diff --git a/drivers/default/src/main/java/org/onosproject/driver/pipeline/ofdpa/CpqdOfdpa2VlanPipeline.java b/drivers/default/src/main/java/org/onosproject/driver/pipeline/ofdpa/CpqdOfdpa2VlanPipeline.java
index 8a41015..701b76e 100644
--- a/drivers/default/src/main/java/org/onosproject/driver/pipeline/ofdpa/CpqdOfdpa2VlanPipeline.java
+++ b/drivers/default/src/main/java/org/onosproject/driver/pipeline/ofdpa/CpqdOfdpa2VlanPipeline.java
@@ -98,7 +98,7 @@
 
         // Multicast MAC
         if (ethCriterion.mask() != null) {
-            return processMcastEthDstFilter(ethCriterion, applicationId);
+            return processMcastEthDstFilter(ethCriterion, assignedVlan, applicationId);
         }
 
         //handling untagged packets via assigned VLAN
diff --git a/drivers/default/src/main/java/org/onosproject/driver/pipeline/ofdpa/Ofdpa2Pipeline.java b/drivers/default/src/main/java/org/onosproject/driver/pipeline/ofdpa/Ofdpa2Pipeline.java
index b123acc..e00d5fc 100644
--- a/drivers/default/src/main/java/org/onosproject/driver/pipeline/ofdpa/Ofdpa2Pipeline.java
+++ b/drivers/default/src/main/java/org/onosproject/driver/pipeline/ofdpa/Ofdpa2Pipeline.java
@@ -93,6 +93,8 @@
 
 import static java.util.concurrent.Executors.newScheduledThreadPool;
 import static org.onlab.packet.MacAddress.BROADCAST;
+import static org.onlab.packet.MacAddress.IPV4_MULTICAST;
+import static org.onlab.packet.MacAddress.IPV6_MULTICAST;
 import static org.onlab.packet.MacAddress.NONE;
 import static org.onlab.util.Tools.groupedThreads;
 import static org.onosproject.driver.pipeline.ofdpa.OfdpaGroupHandlerUtility.*;
@@ -637,7 +639,7 @@
 
         // Multicast MAC
         if (ethCriterion.mask() != null) {
-            return processMcastEthDstFilter(ethCriterion, applicationId);
+            return processMcastEthDstFilter(ethCriterion, assignedVlan, applicationId);
         }
 
         //handling untagged packets via assigned VLAN
@@ -870,37 +872,47 @@
     }
 
     protected List<FlowRule> processMcastEthDstFilter(EthCriterion ethCriterion,
+                                                      VlanId assignedVlan,
                                                       ApplicationId applicationId) {
         ImmutableList.Builder<FlowRule> builder = ImmutableList.builder();
         TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
         TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
-        selector.matchEthType(Ethernet.TYPE_IPV4);
-        selector.matchEthDstMasked(ethCriterion.mac(), ethCriterion.mask());
-        treatment.transition(MULTICAST_ROUTING_TABLE);
-        FlowRule rule = DefaultFlowRule.builder()
-                .forDevice(deviceId)
-                .withSelector(selector.build())
-                .withTreatment(treatment.build())
-                .withPriority(DEFAULT_PRIORITY)
-                .fromApp(applicationId)
-                .makePermanent()
-                .forTable(TMAC_TABLE).build();
-        builder.add(rule);
+        FlowRule rule;
 
-        selector = DefaultTrafficSelector.builder();
-        treatment = DefaultTrafficTreatment.builder();
-        selector.matchEthType(Ethernet.TYPE_IPV6);
-        selector.matchEthDstMasked(ethCriterion.mac(), ethCriterion.mask());
-        treatment.transition(MULTICAST_ROUTING_TABLE);
-        rule = DefaultFlowRule.builder()
-                .forDevice(deviceId)
-                .withSelector(selector.build())
-                .withTreatment(treatment.build())
-                .withPriority(DEFAULT_PRIORITY)
-                .fromApp(applicationId)
-                .makePermanent()
-                .forTable(TMAC_TABLE).build();
-        return builder.add(rule).build();
+        if (IPV4_MULTICAST.equals(ethCriterion.mac())) {
+            selector.matchEthType(Ethernet.TYPE_IPV4);
+            selector.matchEthDstMasked(ethCriterion.mac(), ethCriterion.mask());
+            selector.matchVlanId(assignedVlan);
+            treatment.transition(MULTICAST_ROUTING_TABLE);
+            rule = DefaultFlowRule.builder()
+                    .forDevice(deviceId)
+                    .withSelector(selector.build())
+                    .withTreatment(treatment.build())
+                    .withPriority(DEFAULT_PRIORITY)
+                    .fromApp(applicationId)
+                    .makePermanent()
+                    .forTable(TMAC_TABLE).build();
+            builder.add(rule);
+        }
+
+        if (IPV6_MULTICAST.equals(ethCriterion.mac())) {
+            selector = DefaultTrafficSelector.builder();
+            treatment = DefaultTrafficTreatment.builder();
+            selector.matchEthType(Ethernet.TYPE_IPV6);
+            selector.matchEthDstMasked(ethCriterion.mac(), ethCriterion.mask());
+            selector.matchVlanId(assignedVlan);
+            treatment.transition(MULTICAST_ROUTING_TABLE);
+            rule = DefaultFlowRule.builder()
+                    .forDevice(deviceId)
+                    .withSelector(selector.build())
+                    .withTreatment(treatment.build())
+                    .withPriority(DEFAULT_PRIORITY)
+                    .fromApp(applicationId)
+                    .makePermanent()
+                    .forTable(TMAC_TABLE).build();
+            builder.add(rule);
+        }
+        return builder.build();
     }
 
     private Collection<FlowRule> processForward(ForwardingObjective fwd) {