Initial support GRE tunnel at SONA

Change-Id: I86536a3ed23d8df45e1dc4033c3068a4dfc9ec73
diff --git a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackSwitchingArpHandler.java b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackSwitchingArpHandler.java
index 4a19309..3670390 100644
--- a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackSwitchingArpHandler.java
+++ b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackSwitchingArpHandler.java
@@ -91,6 +91,7 @@
 import static org.onosproject.openstacknetworking.impl.OsgiPropertyConstants.GATEWAY_MAC_DEFAULT;
 import static org.onosproject.openstacknetworking.util.OpenstackNetworkingUtil.getPropertyValue;
 import static org.onosproject.openstacknetworking.util.OpenstackNetworkingUtil.swapStaleLocation;
+import static org.onosproject.openstacknetworking.util.OpenstackNetworkingUtil.tunnelPortNumByNetId;
 import static org.onosproject.openstacknetworking.util.RulePopulatorUtil.buildExtension;
 import static org.onosproject.openstacknode.api.OpenstackNode.NodeType.COMPUTE;
 
@@ -309,7 +310,8 @@
             if (NetworkType.VLAN == network.getNetworkType()) {
                 sBuilder.matchVlanId(VlanId.vlanId(network.getProviderSegID()));
                 tBuilder.popVlan();
-            } else if (NetworkType.VXLAN == network.getNetworkType()) {
+            } else if (NetworkType.VXLAN == network.getNetworkType() ||
+                       NetworkType.GRE == network.getNetworkType()) {
                 // do not remove fake gateway ARP rules, if there is another gateway
                 // which has the same subnet that to be removed
                 // this only occurs if we have duplicated subnets associated with
@@ -373,7 +375,8 @@
 
         switch (type) {
             case VXLAN:
-                setRemoteArpRequestRuleForVxlan(port, install);
+            case GRE:
+                setRemoteArpRequestRuleForTunnel(port, install);
                 break;
             case VLAN:
                 setArpRequestRuleForVlan(port, install);
@@ -396,6 +399,9 @@
             case VXLAN:
                 setArpReplyRuleForVxlan(port, install);
                 break;
+            case GRE:
+                setArpReplyRuleForGre(port, install);
+                break;
             case VLAN:
                 setArpReplyRuleForVlan(port, install);
                 break;
@@ -410,7 +416,7 @@
      * @param port      instance port
      * @param install   installation flag
      */
-    private void setRemoteArpRequestRuleForVxlan(InstancePort port, boolean install) {
+    private void setRemoteArpRequestRuleForTunnel(InstancePort port, boolean install) {
 
         OpenstackNode localNode = osNodeService.node(port.deviceId());
 
@@ -423,7 +429,7 @@
                 .matchTunnelId(Long.valueOf(segId))
                 .build();
 
-        setRemoteArpTreatmentForVxlan(selector, port, localNode, install);
+        setRemoteArpTreatmentForTunnel(selector, port, localNode, install);
     }
 
     /**
@@ -469,7 +475,23 @@
         TrafficSelector selector = getArpReplySelectorForVxlan(port);
 
         setLocalArpReplyTreatmentForVxlan(selector, port, install);
-        setRemoteArpTreatmentForVxlan(selector, port, localNode, install);
+        setRemoteArpTreatmentForTunnel(selector, port, localNode, install);
+    }
+
+    /**
+     * Installs flow rules to match ARP reply packets only for GRE.
+     *
+     * @param port      instance port
+     * @param install   installation flag
+     */
+    private void setArpReplyRuleForGre(InstancePort port, boolean install) {
+
+        OpenstackNode localNode = osNodeService.node(port.deviceId());
+
+        TrafficSelector selector = getArpReplySelectorForGre(port);
+
+        setLocalArpReplyTreatmentForGre(selector, port, install);
+        setRemoteArpTreatmentForTunnel(selector, port, localNode, install);
     }
 
     /**
@@ -492,6 +514,11 @@
     }
 
     // a helper method
+    private TrafficSelector getArpReplySelectorForGre(InstancePort port) {
+        return getArpReplySelectorForVnet(port, NetworkType.GRE);
+    }
+
+    // a helper method
     private TrafficSelector getArpReplySelectorForVlan(InstancePort port) {
         return getArpReplySelectorForVnet(port, NetworkType.VLAN);
     }
@@ -523,6 +550,13 @@
     }
 
     // a helper method
+    private void setLocalArpReplyTreatmentForGre(TrafficSelector selector,
+                                                 InstancePort port,
+                                                 boolean install) {
+        setLocalArpReplyTreatmentForVnet(selector, port, NetworkType.GRE, install);
+    }
+
+    // a helper method
     private void setLocalArpReplyTreatmentForVlan(TrafficSelector selector,
                                                   InstancePort port,
                                                   boolean install) {
@@ -574,20 +608,24 @@
     }
 
     // a helper method
-    private void setRemoteArpTreatmentForVxlan(TrafficSelector selector,
-                                               InstancePort port,
-                                               OpenstackNode localNode,
-                                               boolean install) {
+    private void setRemoteArpTreatmentForTunnel(TrafficSelector selector,
+                                                InstancePort port,
+                                                OpenstackNode localNode,
+                                                boolean install) {
         for (OpenstackNode remoteNode : osNodeService.completeNodes(COMPUTE)) {
             if (!remoteNode.intgBridge().equals(port.deviceId())) {
+
+                PortNumber portNum = tunnelPortNumByNetId(port.networkId(),
+                        osNetworkService, remoteNode);
+
                 TrafficTreatment treatmentToRemote = DefaultTrafficTreatment.builder()
-                        .extension(buildExtension(
-                                deviceService,
-                                remoteNode.intgBridge(),
-                                localNode.dataIp().getIp4Address()),
-                                remoteNode.intgBridge())
-                        .setOutput(remoteNode.tunnelPortNum())
-                        .build();
+                .extension(buildExtension(
+                        deviceService,
+                        remoteNode.intgBridge(),
+                        localNode.dataIp().getIp4Address()),
+                        remoteNode.intgBridge())
+                .setOutput(portNum)
+                .build();
 
                 osFlowRuleService.setRule(
                         appId,