Support tenant overlay network mode at kubevirt networking

Change-Id: Ife40e40e3ee5e342ac8b90ddea6eb81744ace18a
diff --git a/apps/kubevirt-networking/api/src/main/java/org/onosproject/kubevirtnetworking/api/Constants.java b/apps/kubevirt-networking/api/src/main/java/org/onosproject/kubevirtnetworking/api/Constants.java
index 599a615..85b520c 100644
--- a/apps/kubevirt-networking/api/src/main/java/org/onosproject/kubevirtnetworking/api/Constants.java
+++ b/apps/kubevirt-networking/api/src/main/java/org/onosproject/kubevirtnetworking/api/Constants.java
@@ -31,6 +31,9 @@
     public static final MacAddress DEFAULT_GATEWAY_MAC =
                         MacAddress.valueOf(DEFAULT_GATEWAY_MAC_STR);
 
+    public static final String TENANT_TO_TUNNEL_PREFIX = "i-to-t-";
+    public static final String TUNNEL_TO_TENANT_PREFIX = "t-to-i-";
+
     // flow table index
     public static final int STAT_INBOUND_TABLE = 0;
     public static final int VTAP_INBOUND_TABLE = 1;
@@ -54,11 +57,19 @@
     // tenant integration bridge flow table index
     public static final int TENANT_INBOUND_TABLE = 0;
     public static final int TENANT_DHCP_TABLE = 5;
+    public static final int TENANT_ARP_TABLE = 30;
+    public static final int TENANT_ICMP_TABLE = 35;
     public static final int TENANT_FORWARDING_TABLE = 80;
 
+    // tunnel bridge flow table index
+    public static final int TUNNEL_DEFAULT_TABLE = 0;
+
     // flow rule priority
-    public static final int PRIORITY_SWITCHING_RULE = 30000;
+    public static final int PRIORITY_ICMP_RULE = 43000;
+    public static final int PRIORITY_FORWARDING_RULE = 30000;
     public static final int PRIORITY_DHCP_RULE = 42000;
+    public static final int PRIORITY_ARP_GATEWAY_RULE = 41000;
+    public static final int PRIORITY_TUNNEL_RULE = 31000;
 
     // CLI item length
     public static final int CLI_ID_LENGTH = 30;
diff --git a/apps/kubevirt-networking/api/src/main/java/org/onosproject/kubevirtnetworking/api/DefaultKubevirtNetwork.java b/apps/kubevirt-networking/api/src/main/java/org/onosproject/kubevirtnetworking/api/DefaultKubevirtNetwork.java
index 6c0bf8b..251ec0d 100644
--- a/apps/kubevirt-networking/api/src/main/java/org/onosproject/kubevirtnetworking/api/DefaultKubevirtNetwork.java
+++ b/apps/kubevirt-networking/api/src/main/java/org/onosproject/kubevirtnetworking/api/DefaultKubevirtNetwork.java
@@ -18,18 +18,24 @@
 import com.google.common.base.MoreObjects;
 import com.google.common.base.Strings;
 import com.google.common.collect.ImmutableSet;
+import org.onlab.osgi.DefaultServiceDirectory;
 import org.onlab.packet.IpAddress;
 import org.onosproject.net.DeviceId;
+import org.onosproject.net.Port;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.device.DeviceService;
 
 import java.util.HashSet;
 import java.util.Objects;
 import java.util.Set;
 
 import static com.google.common.base.Preconditions.checkArgument;
+import static org.onosproject.kubevirtnetworking.api.Constants.TUNNEL_TO_TENANT_PREFIX;
 import static org.onosproject.kubevirtnetworking.api.KubevirtNetwork.Type.FLAT;
 import static org.onosproject.kubevirtnetworking.api.KubevirtNetwork.Type.GENEVE;
 import static org.onosproject.kubevirtnetworking.api.KubevirtNetwork.Type.GRE;
 import static org.onosproject.kubevirtnetworking.api.KubevirtNetwork.Type.VXLAN;
+import static org.onosproject.net.AnnotationKeys.PORT_NAME;
 
 /**
  * Default implementation class of kubevirt network.
@@ -159,6 +165,17 @@
     }
 
     @Override
+    public PortNumber tunnelToTenantPort(DeviceId deviceId) {
+        String portName = TUNNEL_TO_TENANT_PREFIX + segmentIdHex(segmentId);
+        Port port = port(deviceId, portName);
+        if (port == null) {
+            return null;
+        } else {
+            return port.number();
+        }
+    }
+
+    @Override
     public boolean equals(Object o) {
         if (this == o) {
             return true;
@@ -197,6 +214,14 @@
                 .toString();
     }
 
+    private Port port(DeviceId deviceId, String portName) {
+        DeviceService deviceService = DefaultServiceDirectory.getService(DeviceService.class);
+        return deviceService.getPorts(deviceId).stream()
+                .filter(p -> p.isEnabled() &&
+                        Objects.equals(p.annotations().value(PORT_NAME), portName))
+                .findAny().orElse(null);
+    }
+
     private String segmentIdHex(String segIdStr) {
         int segId = Integer.parseInt(segIdStr);
         return String.format("%06x", segId).toLowerCase();
diff --git a/apps/kubevirt-networking/api/src/main/java/org/onosproject/kubevirtnetworking/api/KubevirtNetwork.java b/apps/kubevirt-networking/api/src/main/java/org/onosproject/kubevirtnetworking/api/KubevirtNetwork.java
index 3c99544..90c39df 100644
--- a/apps/kubevirt-networking/api/src/main/java/org/onosproject/kubevirtnetworking/api/KubevirtNetwork.java
+++ b/apps/kubevirt-networking/api/src/main/java/org/onosproject/kubevirtnetworking/api/KubevirtNetwork.java
@@ -17,6 +17,7 @@
 
 import org.onlab.packet.IpAddress;
 import org.onosproject.net.DeviceId;
+import org.onosproject.net.PortNumber;
 
 import java.util.Set;
 
@@ -138,6 +139,14 @@
     DeviceId tenantDeviceId(String hostname);
 
     /**
+     * Returns the tunnel to tenant port number.
+     *
+     * @param deviceId device identifier
+     * @return port number
+     */
+    PortNumber tunnelToTenantPort(DeviceId deviceId);
+
+    /**
      * Builder of new network.
      */
     interface Builder {