[ONOS-7863] Initial support GENEVE tunnel at SONA

Change-Id: Ia85d32e8068c22d59082dceccc0d911f8acb5f02
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 e78d0e6..8decf3a 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
@@ -28,6 +28,7 @@
     public static final String ROUTER_BRIDGE = "br-router";
     public static final String VXLAN_TUNNEL = "vxlan";
     public static final String GRE_TUNNEL = "gre";
+    public static final String GENEVE_TUNNEL = "geneve";
     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 1ea5942..5d79f7d 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,6 +35,7 @@
 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.GENEVE_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;
@@ -193,6 +194,11 @@
     }
 
     @Override
+    public PortNumber geneveTunnelPortNum() {
+        return tunnelPortNum(GENEVE_TUNNEL);
+    }
+
+    @Override
     public PortNumber greTunnelPortNum() {
         return tunnelPortNum(GRE_TUNNEL);
 
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 63f8ef2..2578eb8 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
@@ -109,6 +109,13 @@
     PortNumber vxlanTunnelPortNum();
 
     /**
+     * Returns the GENEVE tunnel port number.
+     *
+     * @return GENEVE port number; null if the GRE tunnel port does not exist
+     */
+    PortNumber geneveTunnelPortNum();
+
+    /**
      * Returns the vlan port number.
      *
      * @return port number; null if vlan port does not exist
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 451139e..79a2048 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
@@ -79,6 +79,11 @@
     }
 
     @Override
+    public PortNumber geneveTunnelPortNum() {
+        return null;
+    }
+
+    @Override
     public PortNumber vlanPortNum() {
         return null;
     }
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 1b93499..c2c3d57 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
@@ -79,6 +79,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.GENEVE;
+import static org.onosproject.openstacknode.api.Constants.GENEVE_TUNNEL;
 import static org.onosproject.openstacknode.api.Constants.GRE;
 import static org.onosproject.openstacknode.api.Constants.GRE_TUNNEL;
 import static org.onosproject.openstacknode.api.Constants.INTEGRATION_BRIDGE;
@@ -235,6 +237,11 @@
                 createGreTunnelInterface(osNode);
             }
 
+            if (osNode.dataIp() != null &&
+                    !isIntfEnabled(osNode, GENEVE_TUNNEL)) {
+                createGeneveTunnelInterface(osNode);
+            }
+
             if (osNode.dpdkConfig() != null && osNode.dpdkConfig().dpdkIntfs() != null) {
                 osNode.dpdkConfig().dpdkIntfs().stream()
                         .filter(dpdkintf -> dpdkintf.deviceName().equals(TUNNEL_BRIDGE))
@@ -260,7 +267,7 @@
                             osNode.vlanIntf(), deviceService, true);
             }
         } catch (Exception e) {
-            log.error("Exception occurred because of {}", e.toString());
+            log.error("Exception occurred because of {}", e);
         }
     }
 
@@ -365,6 +372,15 @@
     }
 
     /**
+     * Creates a GENEVE tunnel interface in a given openstack node.
+     *
+     * @param osNode openstack node
+     */
+    private void createGeneveTunnelInterface(OpenstackNode osNode) {
+        createTunnelInterface(osNode, GENEVE, GENEVE_TUNNEL);
+    }
+
+    /**
      * Creates a tunnel interface in a given openstack node.
      *
      * @param osNode openstack node
@@ -394,7 +410,7 @@
      * @return tunnel description
      */
     private TunnelDescription buildTunnelDesc(String type, String intfName) {
-        if (VXLAN.equals(type) || GRE.equals(type)) {
+        if (VXLAN.equals(type) || GRE.equals(type) || GENEVE.equals(type)) {
             TunnelDescription.Builder tdBuilder =
                     DefaultTunnelDescription.builder()
                     .deviceId(INTEGRATION_BRIDGE)
@@ -409,6 +425,9 @@
                 case GRE:
                     tdBuilder.type(TunnelDescription.Type.GRE);
                     break;
+                case GENEVE:
+                    tdBuilder.type(TunnelDescription.Type.GENEVE);
+                    break;
                 default:
                     return null;
             }
@@ -462,6 +481,10 @@
                         !isIntfEnabled(osNode, GRE_TUNNEL)) {
                     return false;
                 }
+                if (osNode.dataIp() != null &&
+                        !isIntfEnabled(osNode, GENEVE_TUNNEL)) {
+                    return false;
+                }
                 if (osNode.vlanIntf() != null &&
                         !isIntfEnabled(osNode, osNode.vlanIntf())) {
                     return false;
@@ -819,6 +842,7 @@
                         if (osNode.state() == DEVICE_CREATED && (
                                 Objects.equals(portName, VXLAN_TUNNEL) ||
                                 Objects.equals(portName, GRE_TUNNEL) ||
+                                Objects.equals(portName, GENEVE_TUNNEL) ||
                                 Objects.equals(portName, osNode.vlanIntf()) ||
                                 Objects.equals(portName, osNode.uplinkPort()) ||
                                         containsPhyIntf(osNode, portName)) ||
@@ -847,6 +871,7 @@
                         if (osNode.state() == COMPLETE && (
                                 Objects.equals(portName, VXLAN_TUNNEL) ||
                                 Objects.equals(portName, GRE_TUNNEL) ||
+                                Objects.equals(portName, GENEVE_TUNNEL) ||
                                 Objects.equals(portName, osNode.vlanIntf()) ||
                                 Objects.equals(portName, osNode.uplinkPort()) ||
                                         containsPhyIntf(osNode, portName)) ||