[ONOS-5134] VM cannot access to another VM with floating IP

Change-Id: I300d410994361de505558bfcdeb732a8a6c14b91
diff --git a/apps/openstacknetworking/api/src/main/java/org/onosproject/openstacknetworking/Constants.java b/apps/openstacknetworking/api/src/main/java/org/onosproject/openstacknetworking/Constants.java
index df1d031..fa64015 100644
--- a/apps/openstacknetworking/api/src/main/java/org/onosproject/openstacknetworking/Constants.java
+++ b/apps/openstacknetworking/api/src/main/java/org/onosproject/openstacknetworking/Constants.java
@@ -62,7 +62,8 @@
 
     public static final int GATEWAY_ICMP_PRIORITY = 43000;
     public static final int ROUTING_RULE_PRIORITY = 25000;
-    public static final int FLOATING_RULE_PRIORITY = 42000;
+    public static final int FLOATING_RULE_FOR_TRAFFIC_FROM_VM_PRIORITY = 42000;
+    public static final int FLOATING_RULE_PRIORITY = 41000;
     public static final int PNAT_RULE_PRIORITY = 26000;
     public static final int PNAT_TIMEOUT = 120;
 }
\ No newline at end of file
diff --git a/apps/openstacknetworking/routing/src/main/java/org/onosproject/openstacknetworking/routing/OpenstackFloatingIpManager.java b/apps/openstacknetworking/routing/src/main/java/org/onosproject/openstacknetworking/routing/OpenstackFloatingIpManager.java
index 2e218bd..1de2455 100644
--- a/apps/openstacknetworking/routing/src/main/java/org/onosproject/openstacknetworking/routing/OpenstackFloatingIpManager.java
+++ b/apps/openstacknetworking/routing/src/main/java/org/onosproject/openstacknetworking/routing/OpenstackFloatingIpManager.java
@@ -30,6 +30,7 @@
 import org.onosproject.core.CoreService;
 import org.onosproject.net.DeviceId;
 import org.onosproject.net.Host;
+import org.onosproject.net.PortNumber;
 import org.onosproject.net.device.DeviceService;
 import org.onosproject.net.flow.DefaultTrafficSelector;
 import org.onosproject.net.flow.DefaultTrafficTreatment;
@@ -231,6 +232,11 @@
                 .matchIPDst(floatingIp.toIpPrefix());
 
         gatewayService.getGatewayDeviceIds().stream().forEach(deviceId -> {
+            TrafficSelector.Builder sForTrafficFromVmBuilder = DefaultTrafficSelector.builder()
+                    .matchEthType(Ethernet.TYPE_IPV4)
+                    .matchIPDst(floatingIp.toIpPrefix())
+                    .matchInPort(nodeService.tunnelPort(deviceId).get());
+
             RulePopulatorUtil.removeRule(
                     flowObjectiveService,
                     appId,
@@ -246,6 +252,14 @@
                     sIncomingBuilder.build(),
                     ForwardingObjective.Flag.VERSATILE,
                     FLOATING_RULE_PRIORITY);
+
+            RulePopulatorUtil.removeRule(
+                    flowObjectiveService,
+                    appId,
+                    deviceId,
+                    sForTrafficFromVmBuilder.build(),
+                    ForwardingObjective.Flag.VERSATILE,
+                    FLOATING_RULE_FOR_TRAFFIC_FROM_VM_PRIORITY);
         });
     }
 
@@ -259,13 +273,13 @@
             return;
         }
 
-        TrafficSelector selector = DefaultTrafficSelector.builder()
+        TrafficSelector selectorForTrafficFromExternal = DefaultTrafficSelector.builder()
                 .matchEthType(Ethernet.TYPE_IPV4)
                 .matchIPDst(floatingIp.toIpPrefix())
                 .build();
 
         gatewayService.getGatewayDeviceIds().stream().forEach(gnodeId -> {
-            TrafficTreatment treatment =  DefaultTrafficTreatment.builder()
+            TrafficTreatment treatmentForTrafficFromExternal =  DefaultTrafficTreatment.builder()
                     .setEthSrc(Constants.DEFAULT_GATEWAY_MAC)
                     .setEthDst(associatedVm.mac())
                     .setIpDst(associatedVm.ipAddresses().stream().findFirst().get())
@@ -275,15 +289,43 @@
                     .setOutput(nodeService.tunnelPort(gnodeId).get())
                     .build();
 
-            ForwardingObjective fo = DefaultForwardingObjective.builder()
-                    .withSelector(selector)
-                    .withTreatment(treatment)
+            ForwardingObjective forwardingObjectiveForTrafficFromExternal = DefaultForwardingObjective.builder()
+                    .withSelector(selectorForTrafficFromExternal)
+                    .withTreatment(treatmentForTrafficFromExternal)
                     .withFlag(ForwardingObjective.Flag.VERSATILE)
                     .withPriority(FLOATING_RULE_PRIORITY)
                     .fromApp(appId)
                     .add();
 
-            flowObjectiveService.forward(gnodeId, fo);
+            flowObjectiveService.forward(gnodeId, forwardingObjectiveForTrafficFromExternal);
+
+
+            TrafficSelector selectorForTrafficFromVm = DefaultTrafficSelector.builder()
+                    .matchEthType(Ethernet.TYPE_IPV4)
+                    .matchIPDst(floatingIp.toIpPrefix())
+                    .matchInPort(nodeService.tunnelPort(gnodeId).get())
+                    .build();
+
+            TrafficTreatment treatmentForTrafficFromVm = DefaultTrafficTreatment.builder()
+                    .setEthSrc(Constants.DEFAULT_GATEWAY_MAC)
+                    .setEthDst(associatedVm.mac())
+                    .setIpDst(associatedVm.ipAddresses().stream().findFirst().get())
+                    .setTunnelId(Long.valueOf(associatedVm.annotations().value(VXLAN_ID)))
+                    .extension(buildExtension(deviceService, gnodeId, dataIp.get().getIp4Address()),
+                            gnodeId)
+                    .setOutput(PortNumber.IN_PORT)
+                    .build();
+
+            ForwardingObjective forwardingObjectiveForTrafficFromVm = DefaultForwardingObjective.builder()
+                    .withSelector(selectorForTrafficFromVm)
+                    .withTreatment(treatmentForTrafficFromVm)
+                    .withFlag(ForwardingObjective.Flag.VERSATILE)
+                    .withPriority(FLOATING_RULE_FOR_TRAFFIC_FROM_VM_PRIORITY)
+                    .fromApp(appId)
+                    .add();
+
+            flowObjectiveService.forward(gnodeId, forwardingObjectiveForTrafficFromVm);
+
         });
     }