Use new PacketService to request ARP with duplication

Change-Id: Id005772b0a69629ad3fb532d16a398d170234d88
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 2f07c05..28fd5ec 100644
--- a/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/RoutingRulePopulator.java
+++ b/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/RoutingRulePopulator.java
@@ -26,6 +26,7 @@
 import org.onosproject.net.ConnectPoint;
 import org.onosproject.net.flowobjective.DefaultObjectiveContext;
 import org.onosproject.net.flowobjective.ObjectiveContext;
+import org.onosproject.net.packet.PacketPriority;
 import org.onosproject.segmentrouting.DefaultRoutingHandler.PortFilterInfo;
 import org.onosproject.segmentrouting.config.DeviceConfigNotFoundException;
 import org.onosproject.segmentrouting.config.DeviceConfiguration;
@@ -51,6 +52,7 @@
 import java.util.ArrayList;
 import java.util.HashSet;
 import java.util.List;
+import java.util.Optional;
 import java.util.Set;
 import java.util.concurrent.atomic.AtomicLong;
 
@@ -623,27 +625,16 @@
                       deviceId);
             return;
         }
-        ForwardingObjective.Builder puntIp = DefaultForwardingObjective.builder();
         Set<Ip4Address> allIps = new HashSet<>(config.getPortIPs(deviceId));
         allIps.add(routerIp);
         for (Ip4Address ipaddr : allIps) {
-            TrafficSelector.Builder sbuilder = DefaultTrafficSelector.builder();
-            TrafficTreatment.Builder tbuilder = DefaultTrafficTreatment.builder();
-            sbuilder.matchEthType(Ethernet.TYPE_IPV4);
-            sbuilder.matchIPDst(IpPrefix.valueOf(ipaddr,
-                                                 IpPrefix.MAX_INET_MASK_LENGTH));
-            tbuilder.setOutput(PortNumber.CONTROLLER);
-            puntIp.withSelector(sbuilder.build());
-            puntIp.withTreatment(tbuilder.build());
-            puntIp.withFlag(Flag.VERSATILE)
-                .withPriority(SegmentRoutingService.HIGHEST_PRIORITY)
-                .makePermanent()
-                .fromApp(srManager.appId);
-            ObjectiveContext context = new DefaultObjectiveContext(
-                    (objective) -> log.debug("IP punt rule for {} populated", ipaddr),
-                    (objective, error) ->
-                            log.warn("Failed to populate IP punt rule for {}: {}", ipaddr, error));
-            srManager.flowObjectiveService.forward(deviceId, puntIp.add(context));
+            TrafficSelector.Builder sbuilder = DefaultTrafficSelector.builder()
+                    .matchEthType(Ethernet.TYPE_IPV4)
+                    .matchIPDst(IpPrefix.valueOf(ipaddr, IpPrefix.MAX_INET_MASK_LENGTH));
+            Optional<DeviceId> optDeviceId = Optional.of(deviceId);
+
+            srManager.packetService.requestPackets(sbuilder.build(),
+                    PacketPriority.CONTROL, srManager.appId, optDeviceId);
         }
     }
 
diff --git a/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/SegmentRoutingManager.java b/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/SegmentRoutingManager.java
index dd2f5e8..84c5190 100644
--- a/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/SegmentRoutingManager.java
+++ b/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/SegmentRoutingManager.java
@@ -351,10 +351,13 @@
         multicastRouteService.addListener(mcastListener);
         cordConfigService.addListener(cordConfigListener);
 
-        // Request ARP packet-in
+        /* Request ARP packet-in.
+         * Copy flag set to true since in cross-connect case we still want to
+         * forward ARP packet to the flood group.
+         */
         TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
         selector.matchEthType(Ethernet.TYPE_ARP);
-        packetService.requestPackets(selector.build(), PacketPriority.CONTROL, appId, Optional.empty());
+        packetService.requestPackets(selector.build(), PacketPriority.CONTROL, appId, true);
 
         cfgListener.configureNetwork();
 
diff --git a/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/SegmentRoutingService.java b/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/SegmentRoutingService.java
index d8d155e..7375b98 100644
--- a/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/SegmentRoutingService.java
+++ b/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/SegmentRoutingService.java
@@ -27,11 +27,6 @@
  */
 public interface SegmentRoutingService {
     /**
-     * Highest flow priority.
-     */
-    int HIGHEST_PRIORITY = 0xffff;
-
-    /**
      * VLAN cross-connect priority.
      */
     int XCONNECT_PRIORITY = 1000;
diff --git a/drivers/default/src/main/java/org/onosproject/driver/pipeline/CpqdOfdpa2Pipeline.java b/drivers/default/src/main/java/org/onosproject/driver/pipeline/CpqdOfdpa2Pipeline.java
index ff2d720..50e7184 100644
--- a/drivers/default/src/main/java/org/onosproject/driver/pipeline/CpqdOfdpa2Pipeline.java
+++ b/drivers/default/src/main/java/org/onosproject/driver/pipeline/CpqdOfdpa2Pipeline.java
@@ -677,6 +677,9 @@
                     log.warn("Cannot process instruction in versatile fwd {}", ins);
                 }
             }
+            if (fwd.treatment().clearedDeferred()) {
+                ttBuilder.wipeDeferred();
+            }
         }
         if (fwd.nextId() != null) {
             // overide case
diff --git a/drivers/default/src/main/java/org/onosproject/driver/pipeline/Ofdpa2Pipeline.java b/drivers/default/src/main/java/org/onosproject/driver/pipeline/Ofdpa2Pipeline.java
index c0ae6a5..a6a9d4e 100644
--- a/drivers/default/src/main/java/org/onosproject/driver/pipeline/Ofdpa2Pipeline.java
+++ b/drivers/default/src/main/java/org/onosproject/driver/pipeline/Ofdpa2Pipeline.java
@@ -762,6 +762,9 @@
                     log.warn("Cannot process instruction in versatile fwd {}", ins);
                 }
             }
+            if (fwd.treatment().clearedDeferred()) {
+                ttBuilder.wipeDeferred();
+            }
         }
         if (fwd.nextId() != null) {
             // overide case