[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: I2ad2c100e933e6c22a7e728f8991967d17ede4c9
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 be3d269..6e0a379 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
@@ -910,12 +910,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,
@@ -1028,10 +1028,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 fffa2fb..75df9b0 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
@@ -104,6 +104,21 @@
                                    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);
+
+    /**
      * Assemble the Userdata Classifier table rules.
      * Match: subnet ip prefix and destination ip.
      * Action: add flow rule to specific ip for userdata.
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 030c783..c41aafe 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
@@ -194,6 +194,30 @@
     }
 
     @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());
+        }
+    }
+
+    @Override
     public void programUserdataClassifierRules(DeviceId deviceId,
                                                IpPrefix ipPrefix,
                                                IpAddress dstIp,