Resume the use of ICMP type/code in OFDPA driver

Change-Id: Iecbeae69046deeec760cba5f12181ae84d86b1d0
diff --git a/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/RoutingRulePopulator.java b/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/RoutingRulePopulator.java
index a76e966..6dd60e9 100644
--- a/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/RoutingRulePopulator.java
+++ b/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/RoutingRulePopulator.java
@@ -16,6 +16,7 @@
 package org.onosproject.segmentrouting;
 
 import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
 import org.onlab.packet.EthType;
 import org.onlab.packet.Ethernet;
 import org.onlab.packet.IPv6;
@@ -68,7 +69,10 @@
 import static com.google.common.base.Preconditions.checkNotNull;
 import static org.onlab.packet.Ethernet.TYPE_ARP;
 import static org.onlab.packet.Ethernet.TYPE_IPV6;
+import static org.onlab.packet.ICMP6.NEIGHBOR_ADVERTISEMENT;
 import static org.onlab.packet.ICMP6.NEIGHBOR_SOLICITATION;
+import static org.onlab.packet.ICMP6.ROUTER_ADVERTISEMENT;
+import static org.onlab.packet.ICMP6.ROUTER_SOLICITATION;
 import static org.onlab.packet.IPv6.PROTOCOL_ICMP6;
 import static org.onosproject.segmentrouting.SegmentRoutingManager.INTERNAL_VLAN;
 
@@ -999,15 +1003,16 @@
         srManager.flowObjectiveService.forward(deviceId, fwdObj);
 
         // We punt all NDP packets towards the controller.
-        fwdObj = ndpFwdObjective(null, true, ARP_NDP_PRIORITY)
-                .add(new ObjectiveContext() {
-                    @Override
-                    public void onError(Objective objective, ObjectiveError error) {
-                        log.warn("Failed to install forwarding objective to punt NDP to {}: {}",
-                                 deviceId, error);
-                    }
-                });
-        srManager.flowObjectiveService.forward(deviceId, fwdObj);
+        ndpFwdObjective(null, true, ARP_NDP_PRIORITY).forEach(builder -> {
+             ForwardingObjective obj = builder.add(new ObjectiveContext() {
+                @Override
+                public void onError(Objective objective, ObjectiveError error) {
+                    log.warn("Failed to install forwarding objective to punt NDP to {}: {}",
+                            deviceId, error);
+                }
+            });
+            srManager.flowObjectiveService.forward(deviceId, obj);
+        });
 
         srManager.getPairLocalPorts(deviceId).ifPresent(port -> {
             ForwardingObjective pairFwdObj;
@@ -1023,15 +1028,16 @@
             srManager.flowObjectiveService.forward(deviceId, pairFwdObj);
 
             // Do not punt NDP packets from pair port
-            pairFwdObj = ndpFwdObjective(port, false, PacketPriority.CONTROL.priorityValue() + 1)
-                    .add(new ObjectiveContext() {
-                        @Override
-                        public void onError(Objective objective, ObjectiveError error) {
-                            log.warn("Failed to install forwarding objective to ignore ARP to {}: {}",
-                                    deviceId, error);
-                        }
-                    });
-            srManager.flowObjectiveService.forward(deviceId, pairFwdObj);
+            ndpFwdObjective(port, false, PacketPriority.CONTROL.priorityValue() + 1).forEach(builder -> {
+                ForwardingObjective obj = builder.add(new ObjectiveContext() {
+                    @Override
+                    public void onError(Objective objective, ObjectiveError error) {
+                        log.warn("Failed to install forwarding objective to ignore ARP to {}: {}",
+                                deviceId, error);
+                    }
+                });
+                srManager.flowObjectiveService.forward(deviceId, obj);
+            });
 
             // Do not forward DAD packets from pair port
             pairFwdObj = dad6FwdObjective(port, PacketPriority.CONTROL.priorityValue() + 2)
@@ -1071,20 +1077,28 @@
         return fwdObjBuilder(sBuilder.build(), tBuilder.build(), priority);
     }
 
-    private ForwardingObjective.Builder ndpFwdObjective(PortNumber port, boolean punt, int priority) {
-        TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder();
-        sBuilder.matchEthType(TYPE_IPV6)
-                .matchIPProtocol(PROTOCOL_ICMP6)
-                .matchIcmpv6Type(NEIGHBOR_SOLICITATION);
-        if (port != null) {
-            sBuilder.matchInPort(port);
-        }
+    private Set<ForwardingObjective.Builder> ndpFwdObjective(PortNumber port, boolean punt, int priority) {
+        Set<ForwardingObjective.Builder> result = Sets.newHashSet();
 
-        TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
-        if (punt) {
-            tBuilder.punt();
-        }
-        return fwdObjBuilder(sBuilder.build(), tBuilder.build(), priority);
+        Lists.newArrayList(NEIGHBOR_SOLICITATION, NEIGHBOR_ADVERTISEMENT, ROUTER_SOLICITATION, ROUTER_ADVERTISEMENT)
+                .forEach(type -> {
+                    TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder();
+                    sBuilder.matchEthType(TYPE_IPV6)
+                            .matchIPProtocol(PROTOCOL_ICMP6)
+                            .matchIcmpv6Type(type);
+                    if (port != null) {
+                        sBuilder.matchInPort(port);
+                    }
+
+                    TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
+                    if (punt) {
+                        tBuilder.punt();
+                    }
+
+                    result.add(fwdObjBuilder(sBuilder.build(), tBuilder.build(), priority));
+                });
+
+        return result;
     }
 
     private ForwardingObjective.Builder dad6FwdObjective(PortNumber port, int priority) {
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 fdefb88..a1cd29a 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
@@ -1008,14 +1008,12 @@
                 } else {
                     sbuilder.matchVlanId(vlanId);
                 }
-            } else if (criterion instanceof Icmpv6TypeCriterion ||
-                    criterion instanceof Icmpv6CodeCriterion) {
-                /*
-                 * We silenty discard these criterions, our current
-                 * OFDPA platform does not support these matches on
-                 * the ACL table.
-                 */
-                log.warn("ICMPv6 Type and ICMPv6 Code are not supported");
+            } else if (criterion instanceof Icmpv6TypeCriterion) {
+                byte icmpv6Type = (byte) ((Icmpv6TypeCriterion) criterion).icmpv6Type();
+                sbuilder.matchIcmpv6Type(icmpv6Type);
+            } else if (criterion instanceof Icmpv6CodeCriterion) {
+                byte icmpv6Code = (byte) ((Icmpv6CodeCriterion) criterion).icmpv6Code();
+                sbuilder.matchIcmpv6Type(icmpv6Code);
             } else if (criterion instanceof TcpPortCriterion || criterion instanceof UdpPortCriterion) {
                 // FIXME: QMX switches do not support L4 dst port matching in ACL table.
                 // Currently L4 dst port matching is only used by DHCP relay feature