CORD-1622 CORD-1624 Add IPv6 mutlicast in McastHandler and OFDPA2.0 Drivers

Change-Id: Ibbb402b62999b39f8aea2cd236b959fc61fb94ac
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 95dcfa1..9f2e84c 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
@@ -18,6 +18,7 @@
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableSet;
 import org.onlab.packet.Ethernet;
+import org.onlab.packet.IpAddress;
 import org.onlab.packet.IpPrefix;
 import org.onlab.packet.VlanId;
 import org.onosproject.core.ApplicationId;
@@ -491,10 +492,30 @@
                         + " in dev:{}", fwd.id(), fwd.nextId(), deviceId);
             }
         } else if (ethType.ethType().toShort() == Ethernet.TYPE_IPV6) {
-            if (buildIpv6Selector(filteredSelector, fwd) < 0) {
-                return Collections.emptyList();
+            IpPrefix ipv6Dst = ((IPCriterion) selector.getCriterion(Criterion.Type.IPV6_DST)).ip();
+            if (ipv6Dst.isMulticast()) {
+                if (ipv6Dst.prefixLength() != IpAddress.INET6_BIT_LENGTH) {
+                    log.debug("Multicast specific IPv6 forwarding objective can only be /128");
+                    fail(fwd, ObjectiveError.BADPARAMS);
+                    return ImmutableSet.of();
+                }
+                VlanId assignedVlan = readVlanFromSelector(fwd.meta());
+                if (assignedVlan == null) {
+                    log.debug("VLAN ID required by multicast specific fwd obj is missing. Abort.");
+                    fail(fwd, ObjectiveError.BADPARAMS);
+                    return ImmutableSet.of();
+                }
+                filteredSelector.matchVlanId(assignedVlan);
+                filteredSelector.matchEthType(Ethernet.TYPE_IPV6).matchIPv6Dst(ipv6Dst);
+                forTableId = MULTICAST_ROUTING_TABLE;
+                log.debug("processing IPv6 multicast specific forwarding objective {} -> next:{}"
+                        + " in dev:{}", fwd.id(), fwd.nextId(), deviceId);
+            } else {
+                if (buildIpv6Selector(filteredSelector, fwd) < 0) {
+                    return Collections.emptyList();
+                }
+                forTableId = UNICAST_ROUTING_TABLE;
             }
-            forTableId = UNICAST_ROUTING_TABLE;
         } else {
             filteredSelector
                 .matchEthType(Ethernet.MPLS_UNICAST)