[ONOS-4502]Fix the bug about the different tenant and the same
subnet.With different tenants and the same subnets, only one of the
subnets can ping external network well.

Change-Id: I309675136923095a02ca3a2fac1d7bb32396402a
diff --git a/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/manager/impl/VtnManager.java b/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/manager/impl/VtnManager.java
index f360afc..fffae08 100644
--- a/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/manager/impl/VtnManager.java
+++ b/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/manager/impl/VtnManager.java
@@ -878,12 +878,12 @@
                 .programL3InPortClassifierRules(h.location().deviceId(),
                                                 h.location().port(), h.mac(),
                                                 srcVmGwMac, l3vni, operation);
+        classifierService.programArpClassifierRules(h.location().deviceId(),
+                                                    h.location().port(), srcGwIp,
+                                                    network.segmentationId(),
+                                                    operation);
         // Arp rules
         if (operation == Objective.Operation.ADD) {
-            classifierService.programArpClassifierRules(h.location().deviceId(),
-                                                        srcGwIp,
-                                                        network.segmentationId(),
-                                                        operation);
             DriverHandler handler = driverService.createHandler(h.location().deviceId());
             arpService.programArpRules(handler, h.location().deviceId(), srcGwIp,
                                        network.segmentationId(), srcVmGwMac,
@@ -995,10 +995,10 @@
                                      fGwMac, exPortMac,
                                      floatingIp.floatingIp(),
                                      fipNetwork.segmentationId(), operation);
+        classifierService.programArpClassifierRules(deviceId, host.location().port(),
+                                                    dstVmGwIp, vmNetwork.segmentationId(),
+                                                    operation);
         if (operation == Objective.Operation.ADD) {
-            classifierService.programArpClassifierRules(deviceId, dstVmGwIp,
-                                                        vmNetwork.segmentationId(),
-                                                        operation);
             arpService.programArpRules(handler, deviceId, dstVmGwIp,
                                        vmNetwork.segmentationId(), dstVmGwMac,
                                        operation);
diff --git a/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/table/ClassifierService.java b/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/table/ClassifierService.java
index 69e951a..963e589 100644
--- a/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/table/ClassifierService.java
+++ b/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/table/ClassifierService.java
@@ -102,4 +102,19 @@
                                    SegmentationId actionVni,
                                    Objective.Operation type);
 
+    /**
+     * Assemble the Arp Classifier table rules.
+     * Match: arp type and destination ip.
+     * Action: set vnid and go to ARP Table(10).
+     *
+     * @param deviceId Device Id
+     * @param inPort the ingress port of the host
+     * @param dstIp source gateway ip
+     * @param actionVni the vni of the source network (l2vni)
+     * @param type the operation type of the flow rules
+     */
+    void programArpClassifierRules(DeviceId deviceId, PortNumber inPort,
+                                   IpAddress dstIp, SegmentationId actionVni,
+                                   Objective.Operation type);
+
 }
diff --git a/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/table/impl/ClassifierServiceImpl.java b/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/table/impl/ClassifierServiceImpl.java
index 512a155..0f67a2f 100644
--- a/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/table/impl/ClassifierServiceImpl.java
+++ b/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/table/impl/ClassifierServiceImpl.java
@@ -193,4 +193,28 @@
         }
     }
 
+    @Override
+    public void programArpClassifierRules(DeviceId deviceId, PortNumber inPort,
+                                          IpAddress dstIp,
+                                          SegmentationId actionVni,
+                                          Objective.Operation type) {
+        TrafficSelector selector = DefaultTrafficSelector.builder()
+                .matchInPort(inPort).matchEthType(ETH_TYPE.ethType().toShort())
+                .matchArpTpa(Ip4Address.valueOf(dstIp.toString())).build();
+        TrafficTreatment treatment = DefaultTrafficTreatment.builder()
+                .setTunnelId(Long.parseLong(actionVni.segmentationId()))
+                .build();
+        ForwardingObjective.Builder objective = DefaultForwardingObjective
+                .builder().withTreatment(treatment).withSelector(selector)
+                .fromApp(appId).withFlag(Flag.SPECIFIC)
+                .withPriority(ARP_CLASSIFIER_PRIORITY);
+        if (type.equals(Objective.Operation.ADD)) {
+            log.debug("ArpClassifierRules-->ADD");
+            flowObjectiveService.forward(deviceId, objective.add());
+        } else {
+            log.debug("ArpClassifierRules-->REMOVE");
+            flowObjectiveService.forward(deviceId, objective.remove());
+        }
+    }
+
 }