Initial support GRE tunnel at SONA

Change-Id: I86536a3ed23d8df45e1dc4033c3068a4dfc9ec73
diff --git a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackNetworkManager.java b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackNetworkManager.java
index d08ea96..e7cda54 100644
--- a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackNetworkManager.java
+++ b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackNetworkManager.java
@@ -396,6 +396,11 @@
                         .filter(n -> n.getNetworkType() == NetworkType.VXLAN)
                         .map(IdEntity::getId).collect(Collectors.toSet());
                 break;
+            case "GRE" :
+                networkIds = networks.stream()
+                        .filter(n -> n.getNetworkType() == NetworkType.GRE)
+                        .map(IdEntity::getId).collect(Collectors.toSet());
+                break;
             case "VLAN" :
                 networkIds = networks.stream()
                         .filter(n -> n.getNetworkType() == NetworkType.VLAN)
diff --git a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingFloatingIpHandler.java b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingFloatingIpHandler.java
index 1c838de..10abe3b 100644
--- a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingFloatingIpHandler.java
+++ b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingFloatingIpHandler.java
@@ -28,6 +28,7 @@
 import org.onosproject.core.ApplicationId;
 import org.onosproject.core.CoreService;
 import org.onosproject.net.DeviceId;
+import org.onosproject.net.PortNumber;
 import org.onosproject.net.device.DeviceService;
 import org.onosproject.net.flow.DefaultTrafficSelector;
 import org.onosproject.net.flow.DefaultTrafficTreatment;
@@ -87,6 +88,7 @@
 import static org.onosproject.openstacknetworking.util.OpenstackNetworkingUtil.isAssociatedWithVM;
 import static org.onosproject.openstacknetworking.util.OpenstackNetworkingUtil.processGarpPacketForFloatingIp;
 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.GATEWAY;
 
@@ -338,17 +340,23 @@
 
         switch (osNet.getNetworkType()) {
             case VXLAN:
-                if (osNodeService.node(instPort.deviceId()).tunnelPortNum() == null) {
+            case GRE:
+                PortNumber portNum = tunnelPortNumByNetId(instPort.networkId(),
+                        osNetworkService, osNodeService.node(instPort.deviceId()));
+
+                if (portNum == null) {
                     log.warn(ERR_FLOW + "no tunnel port");
                     return;
                 }
+
                 sBuilder.matchTunnelId(Long.parseLong(osNet.getProviderSegID()));
+
                 tBuilder.extension(buildExtension(
                         deviceService,
                         instPort.deviceId(),
                         selectedGatewayNode.dataIp().getIp4Address()),
                         instPort.deviceId())
-                        .setOutput(osNodeService.node(instPort.deviceId()).tunnelPortNum());
+                        .setOutput(portNum);
                 break;
             case VLAN:
                 if (osNodeService.node(instPort.deviceId()).vlanPortNum() == null) {
@@ -389,6 +397,11 @@
             final String error = String.format(errorFormat, floatingIp, cNode.hostname());
             throw new IllegalStateException(error);
         }
+        if (osNet.getNetworkType() == NetworkType.GRE && cNode.dataIp() == null) {
+            final String errorFormat = ERR_FLOW + "GRE mode is not ready for %s";
+            final String error = String.format(errorFormat, floatingIp, cNode.hostname());
+            throw new IllegalStateException(error);
+        }
         if (osNet.getNetworkType() == NetworkType.VLAN && cNode.vlanIntf() == null) {
             final String errorFormat = ERR_FLOW + "VLAN mode is not ready for %s";
             final String error = String.format(errorFormat, floatingIp, cNode.hostname());
@@ -421,13 +434,16 @@
 
         switch (osNet.getNetworkType()) {
             case VXLAN:
+            case GRE:
+                PortNumber portNum = tunnelPortNumByNetId(instPort.networkId(),
+                        osNetworkService, selectedGatewayNode);
                 externalTreatmentBuilder.setTunnelId(Long.valueOf(osNet.getProviderSegID()))
                         .extension(buildExtension(
                                 deviceService,
                                 selectedGatewayNode.intgBridge(),
                                 cNode.dataIp().getIp4Address()),
                                 selectedGatewayNode.intgBridge())
-                        .setOutput(selectedGatewayNode.tunnelPortNum());
+                        .setOutput(portNum);
                 break;
             case VLAN:
                 externalTreatmentBuilder.pushVlan()
@@ -461,6 +477,7 @@
 
         switch (osNet.getNetworkType()) {
             case VXLAN:
+            case GRE:
                 sBuilder.matchTunnelId(Long.valueOf(osNet.getProviderSegID()));
                 break;
             case VLAN:
diff --git a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingHandler.java b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingHandler.java
index b5ba85e..bde5efe 100644
--- a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingHandler.java
+++ b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingHandler.java
@@ -54,7 +54,6 @@
 import org.onosproject.openstacknetworking.api.OpenstackRouterService;
 import org.onosproject.openstacknetworking.util.RulePopulatorUtil;
 import org.onosproject.openstacknode.api.OpenstackNode;
-import org.onosproject.openstacknode.api.OpenstackNode.NetworkMode;
 import org.onosproject.openstacknode.api.OpenstackNodeEvent;
 import org.onosproject.openstacknode.api.OpenstackNodeListener;
 import org.onosproject.openstacknode.api.OpenstackNodeService;
@@ -98,6 +97,7 @@
 import static org.onosproject.openstacknetworking.api.InstancePort.State.ACTIVE;
 import static org.onosproject.openstacknetworking.impl.OsgiPropertyConstants.USE_STATEFUL_SNAT;
 import static org.onosproject.openstacknetworking.impl.OsgiPropertyConstants.USE_STATEFUL_SNAT_DEFAULT;
+import static org.onosproject.openstacknetworking.util.OpenstackNetworkingUtil.tunnelPortNumByNetType;
 import static org.onosproject.openstacknetworking.util.RulePopulatorUtil.buildExtension;
 import static org.onosproject.openstacknode.api.OpenstackNode.NodeType.COMPUTE;
 import static org.onosproject.openstacknode.api.OpenstackNode.NodeType.GATEWAY;
@@ -374,6 +374,7 @@
                                     Long.parseLong(osNet.getProviderSegID()),
                                     IpPrefix.valueOf(port.ipAddress(), VM_PREFIX),
                                     port.deviceId(),
+                                    osNet.getNetworkType(),
                                     install));
 
                         setOvsNatIngressRule(gwNode.intgBridge(),
@@ -456,6 +457,9 @@
             case VXLAN:
                 setGatewayIcmpForVxlan(osSubnet, srcNatGw, net, routableSubnets, install);
                 break;
+            case GRE:
+                setGatewayIcmpForGre(osSubnet, srcNatGw, net, routableSubnets, install);
+                break;
             case VLAN:
                 setGatewayIcmpForVlan(osSubnet, srcNatGw, net, routableSubnets, install);
                 break;
@@ -489,7 +493,24 @@
                         network.getProviderSegID(),
                         osSubnet,
                         routableSubnets,
-                        NetworkMode.VXLAN,
+                        NetworkType.VXLAN,
+                        install));
+    }
+
+    private void setGatewayIcmpForGre(Subnet osSubnet,
+                                      OpenstackNode srcNatGw,
+                                      Network network,
+                                      Set<Subnet> routableSubnets,
+                                      boolean install) {
+        osNodeService.completeNodes(COMPUTE).stream()
+                .filter(cNode -> cNode.dataIp() != null)
+                .forEach(cNode -> setRulesToGatewayWithRoutableSubnets(
+                        cNode,
+                        srcNatGw,
+                        network.getProviderSegID(),
+                        osSubnet,
+                        routableSubnets,
+                        NetworkType.GRE,
                         install));
     }
 
@@ -506,7 +527,7 @@
                         network.getProviderSegID(),
                         osSubnet,
                         routableSubnets,
-                        NetworkMode.VLAN,
+                        NetworkType.VLAN,
                         install));
     }
 
@@ -598,7 +619,8 @@
 
         switch (networkType) {
             case VXLAN:
-                setInternalRouterRulesForVxlan(deviceId, srcSegId, dstSegId,
+            case GRE:
+                setInternalRouterRulesForTunnel(deviceId, srcSegId, dstSegId,
                                                 srcSubnet, dstSubnet, install);
                 break;
             case VLAN:
@@ -613,12 +635,12 @@
 
     }
 
-    private void setInternalRouterRulesForVxlan(DeviceId deviceId,
-                                                String srcSegmentId,
-                                                String dstSegmentId,
-                                                IpPrefix srcSubnet,
-                                                IpPrefix dstSubnet,
-                                                boolean install) {
+    private void setInternalRouterRulesForTunnel(DeviceId deviceId,
+                                                 String srcSegmentId,
+                                                 String dstSegmentId,
+                                                 IpPrefix srcSubnet,
+                                                 IpPrefix dstSubnet,
+                                                 boolean install) {
         TrafficSelector selector;
         TrafficTreatment treatment;
         selector = DefaultTrafficSelector.builder()
@@ -734,6 +756,7 @@
 
         switch (networkType) {
             case VXLAN:
+            case GRE:
                 sBuilder.matchTunnelId(Long.parseLong(segmentId));
                 break;
             case VLAN:
@@ -750,12 +773,14 @@
 
         switch (networkType) {
             case VXLAN:
+            case GRE:
+                PortNumber portNum = tunnelPortNumByNetType(networkType.name(), osNode);
                 tBuilder.extension(buildExtension(
                                 deviceService,
                                 osNode.intgBridge(),
                                 sourceNatGateway.dataIp().getIp4Address()),
                                 osNode.intgBridge())
-                        .setOutput(osNode.tunnelPortNum());
+                        .setOutput(portNum);
                 break;
 
             case VLAN:
@@ -780,6 +805,7 @@
                                             Long vni,
                                             IpPrefix destVmIp,
                                             DeviceId dstDeviceId,
+                                            NetworkType networkType,
                                             boolean install) {
 
         TrafficSelector selector = DefaultTrafficSelector.builder()
@@ -787,6 +813,9 @@
                 .matchIPDst(destVmIp)
                 .build();
 
+        PortNumber portNum = tunnelPortNumByNetType(networkType.name(),
+                                                    osNodeService.node(deviceId));
+
         TrafficTreatment treatment = DefaultTrafficTreatment.builder()
                 .setTunnelId(vni)
                 .extension(buildExtension(
@@ -794,7 +823,7 @@
                         deviceId,
                         osNodeService.node(dstDeviceId).dataIp().getIp4Address()),
                         deviceId)
-                .setOutput(osNodeService.node(deviceId).tunnelPortNum())
+                .setOutput(portNum)
                 .build();
 
         osFlowRuleService.setRule(
@@ -812,21 +841,21 @@
                                                       String segmentId,
                                                       Subnet updatedSubnet,
                                                       Set<Subnet> routableSubnets,
-                                                      NetworkMode networkMode,
+                                                      NetworkType networkType,
                                                       boolean install) {
         //At first we install flow rules to gateway with segId and gatewayIp of updated subnet
         setRulesToGatewayWithDstIp(osNode, sourceNatGateway, segmentId,
-                IpAddress.valueOf(updatedSubnet.getGateway()), networkMode, install);
+                IpAddress.valueOf(updatedSubnet.getGateway()), networkType, install);
 
         routableSubnets.forEach(subnet -> {
             setRulesToGatewayWithDstIp(osNode, sourceNatGateway,
                     segmentId, IpAddress.valueOf(subnet.getGateway()),
-                    networkMode, install);
+                    networkType, install);
 
             Network network = osNetworkAdminService.network(subnet.getNetworkId());
             setRulesToGatewayWithDstIp(osNode, sourceNatGateway,
                     network.getProviderSegID(), IpAddress.valueOf(updatedSubnet.getGateway()),
-                    networkMode, install);
+                    networkType, install);
         });
     }
 
@@ -834,7 +863,7 @@
                                             OpenstackNode sourceNatGateway,
                                             String segmentId,
                                             IpAddress dstIp,
-                                            NetworkMode networkMode,
+                                            NetworkType networkType,
                                             boolean install) {
         TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder()
                 .matchEthType(Ethernet.TYPE_IPV4)
@@ -842,17 +871,20 @@
 
         TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
 
-        switch (networkMode) {
+        switch (networkType) {
             case VXLAN:
+            case GRE:
                 sBuilder.matchTunnelId(Long.parseLong(segmentId));
+
+                PortNumber portNum = tunnelPortNumByNetType(networkType.name(), osNode);
+
                 tBuilder.extension(buildExtension(
                         deviceService,
                         osNode.intgBridge(),
                         sourceNatGateway.dataIp().getIp4Address()),
                         osNode.intgBridge())
-                        .setOutput(osNode.tunnelPortNum());
+                        .setOutput(portNum);
                 break;
-
             case VLAN:
                 sBuilder.matchVlanId(VlanId.vlanId(segmentId));
                 tBuilder.setOutput(osNode.vlanPortNum());
@@ -952,6 +984,7 @@
 
         switch (networkType) {
             case VXLAN:
+            case GRE:
                 sBuilder.matchTunnelId(Long.parseLong(segmentId));
                 break;
             case VLAN:
@@ -991,6 +1024,7 @@
 
         switch (networkType) {
             case VXLAN:
+            case GRE:
                 sBuilder.matchTunnelId(Long.parseLong(segmentId));
                 break;
             case VLAN:
@@ -1264,7 +1298,7 @@
                                 gwNode.intgBridge(),
                                 Long.parseLong(network.getProviderSegID()),
                                 IpPrefix.valueOf(instPort.ipAddress(), VM_PREFIX),
-                                instPort.deviceId(), true));
+                                instPort.deviceId(), network.getNetworkType(), true));
             }
         }
 
@@ -1280,7 +1314,7 @@
                                 gwNode.intgBridge(),
                                 Long.parseLong(network.getProviderSegID()),
                                 IpPrefix.valueOf(instPort.ipAddress(), VM_PREFIX),
-                                instPort.deviceId(), false));
+                                instPort.deviceId(), network.getNetworkType(), false));
             }
         }
     }
diff --git a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingIcmpHandler.java b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingIcmpHandler.java
index edb871d..41c973e 100644
--- a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingIcmpHandler.java
+++ b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingIcmpHandler.java
@@ -103,6 +103,7 @@
     private static final String ERR_DUPLICATE = " already exists";
 
     private static final String VXLAN = "VXLAN";
+    private static final String GRE = "GRE";
     private static final String VLAN = "VLAN";
 
     @Reference(cardinality = ReferenceCardinality.MANDATORY)
@@ -517,6 +518,7 @@
 
             switch (osNetworkService.networkType(netId)) {
                 case VXLAN:
+                case GRE:
                     tBuilder.setTunnelId(Long.valueOf(segId));
                     break;
                 case VLAN:
@@ -538,4 +540,5 @@
             return ((ICMPEcho) icmp.getPayload()).getIdentifier();
         }
     }
+
 }
diff --git a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingSnatHandler.java b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingSnatHandler.java
index e493bd2..1f0f874 100644
--- a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingSnatHandler.java
+++ b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingSnatHandler.java
@@ -27,6 +27,7 @@
 import org.onosproject.core.ApplicationId;
 import org.onosproject.core.CoreService;
 import org.onosproject.net.DeviceId;
+import org.onosproject.net.PortNumber;
 import org.onosproject.net.device.DeviceService;
 import org.onosproject.net.flow.DefaultTrafficSelector;
 import org.onosproject.net.flow.DefaultTrafficTreatment;
@@ -76,6 +77,7 @@
 import static org.onosproject.openstacknetworking.api.Constants.PRIORITY_SNAT_RULE;
 import static org.onosproject.openstacknetworking.util.OpenstackNetworkingUtil.externalIpFromSubnet;
 import static org.onosproject.openstacknetworking.util.OpenstackNetworkingUtil.externalPeerRouterFromSubnet;
+import static org.onosproject.openstacknetworking.util.OpenstackNetworkingUtil.tunnelPortNumByNetType;
 import static org.onosproject.openstacknode.api.OpenstackNode.NodeType.GATEWAY;
 import static org.slf4j.LoggerFactory.getLogger;
 
@@ -275,6 +277,7 @@
 
         switch (networkType) {
             case VXLAN:
+            case GRE:
                 tBuilder.setTunnelId(Long.parseLong(segmentId));
                 break;
             case VLAN:
@@ -328,11 +331,13 @@
                 DefaultTrafficTreatment.builder(tBuilder.build());
         switch (networkType) {
             case VXLAN:
+            case GRE:
+                PortNumber portNum = tunnelPortNumByNetType(networkType.name(), gNode);
                 tmpBuilder.extension(RulePopulatorUtil.buildExtension(
                         deviceService,
                         gNode.intgBridge(),
                         srcNode.dataIp().getIp4Address()), gNode.intgBridge())
-                        .setOutput(gNode.tunnelPortNum());
+                        .setOutput(portNum);
                 break;
             case VLAN:
                 tmpBuilder.setOutput(gNode.vlanPortNum());
@@ -364,6 +369,7 @@
 
         switch (networkType) {
             case VXLAN:
+            case GRE:
                 sBuilder.matchTunnelId(Long.parseLong(segmentId));
                 break;
             case VLAN:
diff --git a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackSecurityGroupHandler.java b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackSecurityGroupHandler.java
index 1788cfb..d162920 100644
--- a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackSecurityGroupHandler.java
+++ b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackSecurityGroupHandler.java
@@ -218,6 +218,7 @@
     private static final IpPrefix IP_PREFIX_ANY = Ip4Prefix.valueOf("0.0.0.0/0");
 
     private static final String VXLAN = "VXLAN";
+    private static final String GRE = "GRE";
     private static final String VLAN = "VLAN";
 
     // We expose pipeline structure to SONA application considering removing pipeline soon.
@@ -585,7 +586,7 @@
 
         if (VLAN.equals(netType)) {
             sBuilder.matchVlanId(VlanId.vlanId(segId));
-        } else if (VXLAN.equals(netType)) {
+        } else if (VXLAN.equals(netType) || GRE.equals(netType)) {
             sBuilder.matchTunnelId(Long.valueOf(segId));
         } else {
             log.warn("Cannot tag the VID due to lack of support of virtual network type {}", netType);
@@ -911,6 +912,7 @@
 
             switch (netType) {
                 case VXLAN:
+                case GRE:
                     sBuilder.matchTunnelId(Long.valueOf(segId));
                     break;
                 case VLAN:
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,
diff --git a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackSwitchingHandler.java b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackSwitchingHandler.java
index 31750d44e..7988375 100644
--- a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackSwitchingHandler.java
+++ b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackSwitchingHandler.java
@@ -79,6 +79,7 @@
 import static org.onosproject.openstacknetworking.api.InstancePortEvent.Type.OPENSTACK_INSTANCE_MIGRATION_STARTED;
 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;
 import static org.slf4j.LoggerFactory.getLogger;
@@ -292,7 +293,7 @@
      * @param instPort instance port object
      * @param install install flag, add the rule if true, remove it otherwise
      */
-    private void setForwardingRulesForVxlan(InstancePort instPort, boolean install) {
+    private void setForwardingRulesForTunnel(InstancePort instPort, boolean install) {
         // switching rules for the instPorts in the same node
         TrafficSelector selector = DefaultTrafficSelector.builder()
                 // TODO: need to handle IPv6 in near future
@@ -326,13 +327,15 @@
         osNodeService.completeNodes(COMPUTE).stream()
                 .filter(remoteNode -> !remoteNode.intgBridge().equals(localNode.intgBridge()))
                 .forEach(remoteNode -> {
+                    PortNumber portNum = tunnelPortNumByNetId(instPort.networkId(),
+                            osNetworkService, remoteNode);
                     TrafficTreatment treatmentToRemote = DefaultTrafficTreatment.builder()
                             .extension(buildExtension(
                                     deviceService,
                                     remoteNode.intgBridge(),
                                     localNode.dataIp().getIp4Address()),
                                     remoteNode.intgBridge())
-                            .setOutput(remoteNode.tunnelPortNum())
+                            .setOutput(portNum)
                             .build();
 
                     osFlowRuleService.setRule(
@@ -408,7 +411,7 @@
     }
 
     /**
-     * Configures the flow rule which is for using VXLAN to tag the packet
+     * Configures the flow rule which is for using VXLAN/GRE to tag the packet
      * based on the in_port number of a virtual instance.
      * Note that this rule will be inserted in vTag table.
      *
@@ -493,10 +496,11 @@
 
         // TODO: we block a network traffic by referring to segment ID for now
         // we might need to find a better way to block the traffic of a network
-        // in case the segment ID is overlapped in different types network (VXLAN, VLAN)
+        // in case the segment ID is overlapped in different types network (VXLAN, GRE, VLAN)
         switch (type) {
             case VXLAN:
-                setNetworkBlockRulesForVxlan(network.getProviderSegID(), install);
+            case GRE:
+                setNetworkBlockRulesForTunnel(network.getProviderSegID(), install);
                 break;
             case VLAN:
                 setNetworkBlockRulesForVlan(network.getProviderSegID(), install);
@@ -509,7 +513,7 @@
         }
     }
 
-    private void setNetworkBlockRulesForVxlan(String segmentId, boolean install) {
+    private void setNetworkBlockRulesForTunnel(String segmentId, boolean install) {
         TrafficSelector selector = DefaultTrafficSelector.builder()
                 .matchTunnelId(Long.valueOf(segmentId))
                 .build();
@@ -595,7 +599,7 @@
      * Obtains the VNI from the given instance port.
      *
      * @param instPort instance port object
-     * @return VXLAN Network Identifier (VNI)
+     * @return Virtual Network Identifier (VNI)
      */
     private Long getVni(InstancePort instPort) {
         Network osNet = osNetworkService.network(instPort.networkId());
@@ -730,7 +734,7 @@
 
         /**
          * Configures L2 forwarding rules.
-         * Currently, SONA supports Flat, VXLAN and VLAN modes.
+         * Currently, SONA supports Flat, VXLAN, GRE and VLAN modes.
          *
          * @param instPort instance port object
          * @param install install flag, add the rule if true, remove it otherwise
@@ -741,7 +745,8 @@
 
             switch (type) {
                 case VXLAN:
-                    setNetworkRulesForVxlan(instPort, install);
+                case GRE:
+                    setNetworkRulesForTunnel(instPort, install);
                     break;
                 case VLAN:
                     setNetworkRulesForVlan(instPort, install);
@@ -755,9 +760,9 @@
             }
         }
 
-        private void setNetworkRulesForVxlan(InstancePort instPort, boolean install) {
+        private void setNetworkRulesForTunnel(InstancePort instPort, boolean install) {
             setTunnelTagIpFlowRules(instPort, install);
-            setForwardingRulesForVxlan(instPort, install);
+            setForwardingRulesForTunnel(instPort, install);
 
             if (ARP_BROADCAST_MODE.equals(getArpMode())) {
                 setTunnelTagArpFlowRules(instPort, install);
@@ -790,7 +795,8 @@
 
             switch (type) {
                 case VXLAN:
-                    removeVportRulesForVxlan(instPort);
+                case GRE:
+                    removeVportRulesForTunnel(instPort);
                     break;
                 case VLAN:
                     removeVportRulesForVlan(instPort);
@@ -804,7 +810,7 @@
             }
         }
 
-        private void removeVportRulesForVxlan(InstancePort instPort) {
+        private void removeVportRulesForTunnel(InstancePort instPort) {
             setTunnelTagIpFlowRules(instPort, false);
 
             if (ARP_BROADCAST_MODE.equals(getArpMode())) {
diff --git a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/util/OpenstackNetworkingUtil.java b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/util/OpenstackNetworkingUtil.java
index a6e9915..66d1f2a 100644
--- a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/util/OpenstackNetworkingUtil.java
+++ b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/util/OpenstackNetworkingUtil.java
@@ -50,6 +50,7 @@
 import org.onlab.packet.VlanId;
 import org.onosproject.cfg.ConfigProperty;
 import org.onosproject.net.DeviceId;
+import org.onosproject.net.PortNumber;
 import org.onosproject.net.device.DeviceService;
 import org.onosproject.net.flow.DefaultTrafficTreatment;
 import org.onosproject.net.flow.TrafficTreatment;
@@ -155,6 +156,7 @@
     private static final String ERR_FLOW = "Failed set flows for floating IP %s: ";
 
     private static final String VXLAN = "VXLAN";
+    private static final String GRE = "GRE";
     private static final String VLAN = "VLAN";
     private static final String DL_DST = "dl_dst=";
     private static final String NW_DST = "nw_dst=";
@@ -768,6 +770,7 @@
 
             String modifiedDstIp = dstIp;
             if (osNetService.networkType(srcInstancePort.networkId()).equals(VXLAN) ||
+                    osNetService.networkType(srcInstancePort.networkId()).equals(GRE) ||
                     osNetService.networkType(srcInstancePort.networkId()).equals(VLAN)) {
                 if (srcIp.equals(dstIp)) {
                     modifiedDstIp = osNetService.gatewayIp(srcInstancePort.portId());
@@ -795,6 +798,7 @@
                     .append(COMMA);
 
             if (osNetService.networkType(srcInstancePort.networkId()).equals(VXLAN) ||
+                    osNetService.networkType(srcInstancePort.networkId()).equals(GRE) ||
                     osNetService.networkType(srcInstancePort.networkId()).equals(VLAN)) {
                 requestStringBuilder.append(TUN_ID)
                         .append(osNetService.segmentId(srcInstancePort.networkId()))
@@ -1045,6 +1049,44 @@
                 .findAny().get().getIpAddress());
     }
 
+    /**
+     * Returns the tunnel port number with specified net ID and openstack node.
+     *
+     * @param netId network ID
+     * @param netService network service
+     * @param osNode openstack node
+     * @return tunnel port number
+     */
+    public static PortNumber tunnelPortNumByNetId(String netId,
+                                                  OpenstackNetworkService netService,
+                                                  OpenstackNode osNode) {
+        String netType = netService.networkType(netId);
+
+        if (netType == null) {
+            return null;
+        }
+
+        return tunnelPortNumByNetType(netType, osNode);
+    }
+
+    /**
+     * Returns the tunnel port number with specified net type and openstack node.
+     *
+     * @param netType network type
+     * @param osNode openstack node
+     * @return tunnel port number
+     */
+    public static PortNumber tunnelPortNumByNetType(String netType, OpenstackNode osNode) {
+        switch (netType) {
+            case VXLAN:
+                return osNode.vxlanTunnelPortNum();
+            case GRE:
+                return osNode.greTunnelPortNum();
+            default:
+                return null;
+        }
+    }
+
     private static Router getRouterFromSubnet(Subnet subnet,
                                               OpenstackRouterService osRouterService) {
         RouterInterface osRouterIface = osRouterService.routerInterfaces().stream()
diff --git a/apps/openstacknode/api/src/main/java/org/onosproject/openstacknode/api/Constants.java b/apps/openstacknode/api/src/main/java/org/onosproject/openstacknode/api/Constants.java
index b7ca1f5..0422c65 100644
--- a/apps/openstacknode/api/src/main/java/org/onosproject/openstacknode/api/Constants.java
+++ b/apps/openstacknode/api/src/main/java/org/onosproject/openstacknode/api/Constants.java
@@ -26,7 +26,8 @@
     public static final String INTEGRATION_BRIDGE = "br-int";
     public static final String TUNNEL_BRIDGE = "br-tun";
     public static final String ROUTER_BRIDGE = "br-router";
-    public static final String DEFAULT_TUNNEL = "vxlan";
+    public static final String VXLAN_TUNNEL = "vxlan";
+    public static final String GRE_TUNNEL = "gre";
     public static final String PATCH_INTG_BRIDGE = "patch-intg";
     public static final String PATCH_ROUT_BRIDGE = "patch-rout";
     public static final String GATEWAY = "GATEWAY";
diff --git a/apps/openstacknode/api/src/main/java/org/onosproject/openstacknode/api/DefaultOpenstackNode.java b/apps/openstacknode/api/src/main/java/org/onosproject/openstacknode/api/DefaultOpenstackNode.java
index ca4734e..1ea5942 100644
--- a/apps/openstacknode/api/src/main/java/org/onosproject/openstacknode/api/DefaultOpenstackNode.java
+++ b/apps/openstacknode/api/src/main/java/org/onosproject/openstacknode/api/DefaultOpenstackNode.java
@@ -35,7 +35,8 @@
 import static com.google.common.base.Preconditions.checkArgument;
 import static org.onosproject.net.AnnotationKeys.PORT_MAC;
 import static org.onosproject.net.AnnotationKeys.PORT_NAME;
-import static org.onosproject.openstacknode.api.Constants.DEFAULT_TUNNEL;
+import static org.onosproject.openstacknode.api.Constants.GRE_TUNNEL;
+import static org.onosproject.openstacknode.api.Constants.VXLAN_TUNNEL;
 import static org.onosproject.openstacknode.api.Constants.PATCH_INTG_BRIDGE;
 
 /**
@@ -185,15 +186,26 @@
         return port != null ? port.number() : null;
 
     }
+
     @Override
-    public PortNumber tunnelPortNum() {
+    public PortNumber vxlanTunnelPortNum() {
+        return tunnelPortNum(VXLAN_TUNNEL);
+    }
+
+    @Override
+    public PortNumber greTunnelPortNum() {
+        return tunnelPortNum(GRE_TUNNEL);
+
+    }
+
+    private PortNumber tunnelPortNum(String tunnelType) {
         if (dataIp == null) {
             return null;
         }
         DeviceService deviceService = DefaultServiceDirectory.getService(DeviceService.class);
         Port port = deviceService.getPorts(intgBridge).stream()
                 .filter(p -> p.isEnabled() &&
-                        Objects.equals(p.annotations().value(PORT_NAME), DEFAULT_TUNNEL))
+                        Objects.equals(p.annotations().value(PORT_NAME), tunnelType))
                 .findAny().orElse(null);
         return port != null ? port.number() : null;
     }
diff --git a/apps/openstacknode/api/src/main/java/org/onosproject/openstacknode/api/OpenstackNode.java b/apps/openstacknode/api/src/main/java/org/onosproject/openstacknode/api/OpenstackNode.java
index a2000ee..63f8ef2 100644
--- a/apps/openstacknode/api/src/main/java/org/onosproject/openstacknode/api/OpenstackNode.java
+++ b/apps/openstacknode/api/src/main/java/org/onosproject/openstacknode/api/OpenstackNode.java
@@ -30,16 +30,6 @@
 public interface OpenstackNode {
 
     /**
-     * List of valid network modes.
-     * This includes both physical and virtual network types.
-     */
-    enum NetworkMode {
-        VXLAN,
-        VLAN,
-        FLAT
-    }
-
-    /**
      * List of valid node types.
      */
     enum NodeType {
@@ -105,11 +95,18 @@
     NodeState state();
 
     /**
-     * Returns the tunnel port number.
+     * Returns the GRE tunnel port number.
      *
-     * @return port number; null if tunnel port does not exist
+     * @return GRE port number; null if the GRE tunnel port does not exist
      */
-    PortNumber tunnelPortNum();
+    PortNumber greTunnelPortNum();
+
+    /**
+     * Returns the VXLAN tunnel port number.
+     *
+     * @return VXLAN port number; null if tunnel port does not exist
+     */
+    PortNumber vxlanTunnelPortNum();
 
     /**
      * Returns the vlan port number.
diff --git a/apps/openstacknode/api/src/test/java/org/onosproject/openstacknode/api/OpenstackNodeAdapter.java b/apps/openstacknode/api/src/test/java/org/onosproject/openstacknode/api/OpenstackNodeAdapter.java
index d625a05..451139e 100644
--- a/apps/openstacknode/api/src/test/java/org/onosproject/openstacknode/api/OpenstackNodeAdapter.java
+++ b/apps/openstacknode/api/src/test/java/org/onosproject/openstacknode/api/OpenstackNodeAdapter.java
@@ -69,7 +69,12 @@
     }
 
     @Override
-    public PortNumber tunnelPortNum() {
+    public PortNumber greTunnelPortNum() {
+        return null;
+    }
+
+    @Override
+    public PortNumber vxlanTunnelPortNum() {
         return null;
     }
 
diff --git a/apps/openstacknode/app/src/main/java/org/onosproject/openstacknode/cli/OpenstackNodeCheckCommand.java b/apps/openstacknode/app/src/main/java/org/onosproject/openstacknode/cli/OpenstackNodeCheckCommand.java
index 88321c3..1ff9169 100644
--- a/apps/openstacknode/app/src/main/java/org/onosproject/openstacknode/cli/OpenstackNodeCheckCommand.java
+++ b/apps/openstacknode/app/src/main/java/org/onosproject/openstacknode/cli/OpenstackNodeCheckCommand.java
@@ -31,7 +31,8 @@
 import org.openstack4j.api.OSClient;
 
 import static org.onosproject.net.AnnotationKeys.PORT_NAME;
-import static org.onosproject.openstacknode.api.Constants.DEFAULT_TUNNEL;
+import static org.onosproject.openstacknode.api.Constants.GRE_TUNNEL;
+import static org.onosproject.openstacknode.api.Constants.VXLAN_TUNNEL;
 import static org.onosproject.openstacknode.api.Constants.INTEGRATION_BRIDGE;
 import static org.onosproject.openstacknode.api.OpenstackNode.NodeType.CONTROLLER;
 import static org.onosproject.openstacknode.api.OpenstackNode.NodeType.GATEWAY;
@@ -93,7 +94,8 @@
                         deviceService.isAvailable(device.id()),
                         device.annotations());
                 if (osNode.dataIp() != null) {
-                    printPortState(deviceService, osNode.intgBridge(), DEFAULT_TUNNEL);
+                    printPortState(deviceService, osNode.intgBridge(), VXLAN_TUNNEL);
+                    printPortState(deviceService, osNode.intgBridge(), GRE_TUNNEL);
                 }
                 if (osNode.vlanIntf() != null) {
                     printPortState(deviceService, osNode.intgBridge(), osNode.vlanIntf());
diff --git a/apps/openstacknode/app/src/main/java/org/onosproject/openstacknode/impl/DefaultOpenstackNodeHandler.java b/apps/openstacknode/app/src/main/java/org/onosproject/openstacknode/impl/DefaultOpenstackNodeHandler.java
index aaf48fa..c6e9395 100644
--- a/apps/openstacknode/app/src/main/java/org/onosproject/openstacknode/impl/DefaultOpenstackNodeHandler.java
+++ b/apps/openstacknode/app/src/main/java/org/onosproject/openstacknode/impl/DefaultOpenstackNodeHandler.java
@@ -57,6 +57,7 @@
 import org.onosproject.ovsdb.rfc.notation.OvsdbSet;
 import org.onosproject.ovsdb.rfc.table.Interface;
 import org.openstack4j.api.OSClient;
+import org.openstack4j.model.network.NetworkType;
 import org.osgi.service.component.ComponentContext;
 import org.osgi.service.component.annotations.Activate;
 import org.osgi.service.component.annotations.Component;
@@ -79,7 +80,8 @@
 import static org.onlab.packet.TpPort.tpPort;
 import static org.onlab.util.Tools.groupedThreads;
 import static org.onosproject.net.AnnotationKeys.PORT_NAME;
-import static org.onosproject.openstacknode.api.Constants.DEFAULT_TUNNEL;
+import static org.onosproject.openstacknode.api.Constants.GRE_TUNNEL;
+import static org.onosproject.openstacknode.api.Constants.VXLAN_TUNNEL;
 import static org.onosproject.openstacknode.api.Constants.INTEGRATION_BRIDGE;
 import static org.onosproject.openstacknode.api.Constants.TUNNEL_BRIDGE;
 import static org.onosproject.openstacknode.api.DpdkConfig.DatapathType.NETDEV;
@@ -223,8 +225,13 @@
             }
 
             if (osNode.dataIp() != null &&
-                    !isIntfEnabled(osNode, DEFAULT_TUNNEL)) {
-                createTunnelInterface(osNode);
+                    !isIntfEnabled(osNode, VXLAN_TUNNEL)) {
+                createVxlanTunnelInterface(osNode);
+            }
+
+            if (osNode.dataIp() != null &&
+                    !isIntfEnabled(osNode, GRE_TUNNEL)) {
+                createGreTunnelInterface(osNode);
             }
 
             if (osNode.dpdkConfig() != null && osNode.dpdkConfig().dpdkIntfs() != null) {
@@ -339,12 +346,31 @@
     }
 
     /**
+     * Creates a VXLAN tunnel interface in a given openstack node.
+     *
+     * @param osNode openstack node
+     */
+    private void createVxlanTunnelInterface(OpenstackNode osNode) {
+        createTunnelInterface(osNode, NetworkType.VXLAN, VXLAN_TUNNEL);
+    }
+
+    /**
+     * Creates a GRE tunnel interface in a given openstack node.
+     *
+     * @param osNode openstack node
+     */
+    private void createGreTunnelInterface(OpenstackNode osNode) {
+        createTunnelInterface(osNode, NetworkType.GRE, GRE_TUNNEL);
+    }
+
+    /**
      * Creates a tunnel interface in a given openstack node.
      *
      * @param osNode openstack node
      */
-    private void createTunnelInterface(OpenstackNode osNode) {
-        if (isIntfEnabled(osNode, DEFAULT_TUNNEL)) {
+    private void createTunnelInterface(OpenstackNode osNode,
+                                       NetworkType type, String intfName) {
+        if (isIntfEnabled(osNode, intfName)) {
             return;
         }
 
@@ -354,16 +380,41 @@
             return;
         }
 
-        TunnelDescription tunnelDesc = DefaultTunnelDescription.builder()
-                .deviceId(INTEGRATION_BRIDGE)
-                .ifaceName(DEFAULT_TUNNEL)
-                .type(TunnelDescription.Type.VXLAN)
-                .remote(TunnelEndPoints.flowTunnelEndpoint())
-                .key(TunnelKeys.flowTunnelKey())
-                .build();
+        TunnelDescription tunnelDesc = buildTunnelDesc(type, intfName);
 
         InterfaceConfig ifaceConfig = device.as(InterfaceConfig.class);
-        ifaceConfig.addTunnelMode(DEFAULT_TUNNEL, tunnelDesc);
+        ifaceConfig.addTunnelMode(intfName, tunnelDesc);
+    }
+
+    /**
+     * Builds tunnel description according to the network type.
+     *
+     * @param type network type
+     * @return tunnel description
+     */
+    private TunnelDescription buildTunnelDesc(NetworkType type, String intfName) {
+        if (type ==  NetworkType.VXLAN || type == NetworkType.GRE) {
+            TunnelDescription.Builder tdBuilder =
+                    DefaultTunnelDescription.builder()
+                    .deviceId(INTEGRATION_BRIDGE)
+                    .ifaceName(intfName)
+                    .remote(TunnelEndPoints.flowTunnelEndpoint())
+                    .key(TunnelKeys.flowTunnelKey());
+
+            switch (type) {
+                case VXLAN:
+                    tdBuilder.type(TunnelDescription.Type.VXLAN);
+                    break;
+                case GRE:
+                    tdBuilder.type(TunnelDescription.Type.GRE);
+                    break;
+                default:
+                    return null;
+            }
+
+            return tdBuilder.build();
+        }
+        return null;
     }
 
     /**
@@ -403,7 +454,11 @@
                 return initStateDone;
             case DEVICE_CREATED:
                 if (osNode.dataIp() != null &&
-                        !isIntfEnabled(osNode, DEFAULT_TUNNEL)) {
+                        !isIntfEnabled(osNode, VXLAN_TUNNEL)) {
+                    return false;
+                }
+                if (osNode.dataIp() != null &&
+                        !isIntfEnabled(osNode, GRE_TUNNEL)) {
                     return false;
                 }
                 if (osNode.vlanIntf() != null &&
@@ -761,7 +816,8 @@
                         Port port = event.port();
                         String portName = port.annotations().value(PORT_NAME);
                         if (osNode.state() == DEVICE_CREATED && (
-                                Objects.equals(portName, DEFAULT_TUNNEL) ||
+                                Objects.equals(portName, VXLAN_TUNNEL) ||
+                                Objects.equals(portName, GRE_TUNNEL) ||
                                 Objects.equals(portName, osNode.vlanIntf()) ||
                                 Objects.equals(portName, osNode.uplinkPort()) ||
                                         containsPhyIntf(osNode, portName)) ||
@@ -788,7 +844,8 @@
                         Port port = event.port();
                         String portName = port.annotations().value(PORT_NAME);
                         if (osNode.state() == COMPLETE && (
-                                Objects.equals(portName, DEFAULT_TUNNEL) ||
+                                Objects.equals(portName, VXLAN_TUNNEL) ||
+                                Objects.equals(portName, GRE_TUNNEL) ||
                                 Objects.equals(portName, osNode.vlanIntf()) ||
                                 Objects.equals(portName, osNode.uplinkPort()) ||
                                         containsPhyIntf(osNode, portName)) ||
diff --git a/apps/openstacknode/app/src/test/java/org/onosproject/openstacknode/impl/DefaultOpenstackNodeHandlerTest.java b/apps/openstacknode/app/src/test/java/org/onosproject/openstacknode/impl/DefaultOpenstackNodeHandlerTest.java
index ad5ab65..3224a4b 100644
--- a/apps/openstacknode/app/src/test/java/org/onosproject/openstacknode/impl/DefaultOpenstackNodeHandlerTest.java
+++ b/apps/openstacknode/app/src/test/java/org/onosproject/openstacknode/impl/DefaultOpenstackNodeHandlerTest.java
@@ -99,7 +99,7 @@
 import static org.onosproject.net.device.DeviceEvent.Type.DEVICE_AVAILABILITY_CHANGED;
 import static org.onosproject.net.device.DeviceEvent.Type.PORT_ADDED;
 import static org.onosproject.net.device.DeviceEvent.Type.PORT_REMOVED;
-import static org.onosproject.openstacknode.api.Constants.DEFAULT_TUNNEL;
+import static org.onosproject.openstacknode.api.Constants.VXLAN_TUNNEL;
 import static org.onosproject.openstacknode.api.Constants.INTEGRATION_BRIDGE;
 import static org.onosproject.openstacknode.api.Constants.PATCH_INTG_BRIDGE;
 import static org.onosproject.openstacknode.api.Constants.PATCH_ROUT_BRIDGE;
@@ -369,7 +369,7 @@
         assertEquals(ERR_STATE_NOT_MATCH, COMPLETE,
                 testNodeManager.node(COMPUTE_3_HOSTNAME).state());
         TEST_DEVICE_SERVICE.removePort(COMPUTE_3_INTG_DEVICE, createPort(
-                COMPUTE_3_INTG_DEVICE, DEFAULT_TUNNEL));
+                COMPUTE_3_INTG_DEVICE, VXLAN_TUNNEL));
         assertEquals(ERR_STATE_NOT_MATCH, INCOMPLETE,
                 testNodeManager.node(COMPUTE_3_HOSTNAME).state());
 
@@ -523,7 +523,7 @@
         }
 
         @Override
-        public PortNumber tunnelPortNum() {
+        public PortNumber vxlanTunnelPortNum() {
             return PortNumber.portNumber(1);
         }