Inter-connect k8s and openstack intg bridge, kbr-ex and kbr-router

Change-Id: Id7d3c874e8b267252ca387b1ca6f67b9f9bc5116
diff --git a/apps/k8s-node/api/src/main/java/org/onosproject/k8snode/api/Constants.java b/apps/k8s-node/api/src/main/java/org/onosproject/k8snode/api/Constants.java
index 82b63cb..59a5715 100644
--- a/apps/k8s-node/api/src/main/java/org/onosproject/k8snode/api/Constants.java
+++ b/apps/k8s-node/api/src/main/java/org/onosproject/k8snode/api/Constants.java
@@ -23,19 +23,23 @@
     private Constants() {
     }
 
+    public static final String OS_INTEGRATION_BRIDGE = "br-int";
     public static final String INTEGRATION_BRIDGE = "kbr-int";
     public static final String EXTERNAL_BRIDGE = "kbr-ex";
     public static final String LOCAL_BRIDGE = "kbr-local";
     public static final String TUNNEL_BRIDGE = "kbr-tun";
-    public static final String EXTERNAL_ROUTER = "kbr-router";
+    public static final String ROUTER_BRIDGE = "kbr-router";
     public static final String INTEGRATION_TO_EXTERNAL_BRIDGE = "int-ex";
     public static final String PHYSICAL_EXTERNAL_BRIDGE = "ex-int";
     public static final String INTEGRATION_TO_LOCAL_BRIDGE = "int-local";
     public static final String LOCAL_TO_INTEGRATION_BRIDGE = "local-int";
     public static final String EXTERNAL_TO_ROUTER = "ex-router";
     public static final String ROUTER_TO_EXTERNAL = "router-ex";
+    public static final String ROUTER = "router";
     public static final String INTEGRATION_TO_TUN_BRIDGE = "int-tun";
     public static final String TUN_TO_INTEGRATION_BRIDGE = "tun-int";
+    public static final String OS_TO_K8S_BRIDGE = "os-k8s";
+    public static final String K8S_TO_OS_BRIDGE = "k8s-os";
     public static final String VXLAN_TUNNEL = "vxlan";
     public static final String GRE_TUNNEL = "gre";
     public static final String GENEVE_TUNNEL = "geneve";
@@ -50,4 +54,5 @@
     public static final int DEFAULT_SEGMENT_ID = 100;
     public static final String DEFAULT_EXTERNAL_GATEWAY_MAC = "fa:00:00:00:00:01";
     public static final String DEFAULT_EXTERNAL_BRIDGE_MAC = "fa:00:00:00:00:02";
+    public static final String DEFAULT_INTG_BRIDGE_MAC = "fa:00:00:00:00:03";
 }
diff --git a/apps/k8s-node/api/src/main/java/org/onosproject/k8snode/api/DefaultK8sHost.java b/apps/k8s-node/api/src/main/java/org/onosproject/k8snode/api/DefaultK8sHost.java
index e961910..a6e4d0e 100644
--- a/apps/k8s-node/api/src/main/java/org/onosproject/k8snode/api/DefaultK8sHost.java
+++ b/apps/k8s-node/api/src/main/java/org/onosproject/k8snode/api/DefaultK8sHost.java
@@ -35,6 +35,7 @@
     private final Set<String> nodeNames;
     private final K8sHostState state;
     private final Set<K8sTunnelBridge> tunBridges;
+    private final Set<K8sRouterBridge> routerBridges;
 
     private static final String NOT_NULL_MSG = "Host % cannot be null";
 
@@ -47,13 +48,16 @@
      * @param nodeNames     node names
      * @param state         host state
      * @param tunBridges    a set of tunnel bridges
+     * @param routerBridges a set of router bridges
      */
     protected DefaultK8sHost(IpAddress hostIp, Set<String> nodeNames,
-                             K8sHostState state, Set<K8sTunnelBridge> tunBridges) {
+                             K8sHostState state, Set<K8sTunnelBridge> tunBridges,
+                             Set<K8sRouterBridge> routerBridges) {
         this.hostIp = hostIp;
         this.nodeNames = nodeNames;
         this.state = state;
         this.tunBridges = tunBridges;
+        this.routerBridges = routerBridges;
     }
 
     @Override
@@ -82,12 +86,18 @@
     }
 
     @Override
+    public Set<K8sRouterBridge> routerBridges() {
+        return ImmutableSet.copyOf(routerBridges);
+    }
+
+    @Override
     public K8sHost updateState(K8sHostState newState) {
         return new Builder()
                 .hostIp(hostIp)
                 .nodeNames(nodeNames)
                 .state(newState)
                 .tunBridges(tunBridges)
+                .routerBridges(routerBridges)
                 .build();
     }
 
@@ -98,6 +108,7 @@
                 .nodeNames(nodeNames)
                 .state(state)
                 .tunBridges(tunBridges)
+                .routerBridges(routerBridges)
                 .build();
     }
 
@@ -113,12 +124,13 @@
         return Objects.equals(hostIp, that.hostIp) &&
                 Objects.equals(nodeNames, that.nodeNames) &&
                 state == that.state &&
-                Objects.equals(tunBridges, that.tunBridges);
+                Objects.equals(tunBridges, that.tunBridges) &&
+                Objects.equals(routerBridges, that.routerBridges);
     }
 
     @Override
     public int hashCode() {
-        return Objects.hash(hostIp, nodeNames, state);
+        return Objects.hash(hostIp, nodeNames, state, tunBridges, routerBridges);
     }
 
     @Override
@@ -128,6 +140,7 @@
                 .add("nodeNames", nodeNames)
                 .add("state", state)
                 .add("tunBridges", tunBridges)
+                .add("routerBridges", routerBridges)
                 .toString();
     }
 
@@ -146,6 +159,7 @@
         private Set<String> nodeNames;
         private K8sHostState state;
         private Set<K8sTunnelBridge> tunBridges;
+        private Set<K8sRouterBridge> routerBridges;
 
         // private constructor not intended to use from external
         private Builder() {
@@ -164,7 +178,11 @@
                 tunBridges = new HashSet<>();
             }
 
-            return new DefaultK8sHost(hostIp, nodeNames, state, tunBridges);
+            if (routerBridges == null) {
+                routerBridges = new HashSet<>();
+            }
+
+            return new DefaultK8sHost(hostIp, nodeNames, state, tunBridges, routerBridges);
         }
 
         @Override
@@ -190,5 +208,11 @@
             this.tunBridges = tunBridges;
             return this;
         }
+
+        @Override
+        public Builder routerBridges(Set<K8sRouterBridge> routerBridges) {
+            this.routerBridges = routerBridges;
+            return this;
+        }
     }
 }
diff --git a/apps/k8s-node/api/src/main/java/org/onosproject/k8snode/api/DefaultK8sNode.java b/apps/k8s-node/api/src/main/java/org/onosproject/k8snode/api/DefaultK8sNode.java
index 6bb2001..09f4097 100644
--- a/apps/k8s-node/api/src/main/java/org/onosproject/k8snode/api/DefaultK8sNode.java
+++ b/apps/k8s-node/api/src/main/java/org/onosproject/k8snode/api/DefaultK8sNode.java
@@ -34,16 +34,22 @@
 import static org.onosproject.k8snode.api.Constants.DEFAULT_CLUSTER_NAME;
 import static org.onosproject.k8snode.api.Constants.DEFAULT_EXTERNAL_BRIDGE_MAC;
 import static org.onosproject.k8snode.api.Constants.DEFAULT_EXTERNAL_GATEWAY_MAC;
+import static org.onosproject.k8snode.api.Constants.DEFAULT_INTG_BRIDGE_MAC;
 import static org.onosproject.k8snode.api.Constants.EXTERNAL_BRIDGE;
+import static org.onosproject.k8snode.api.Constants.EXTERNAL_TO_ROUTER;
 import static org.onosproject.k8snode.api.Constants.GENEVE_TUNNEL;
 import static org.onosproject.k8snode.api.Constants.GRE_TUNNEL;
 import static org.onosproject.k8snode.api.Constants.INTEGRATION_BRIDGE;
 import static org.onosproject.k8snode.api.Constants.INTEGRATION_TO_EXTERNAL_BRIDGE;
 import static org.onosproject.k8snode.api.Constants.INTEGRATION_TO_LOCAL_BRIDGE;
 import static org.onosproject.k8snode.api.Constants.INTEGRATION_TO_TUN_BRIDGE;
+import static org.onosproject.k8snode.api.Constants.K8S_TO_OS_BRIDGE;
 import static org.onosproject.k8snode.api.Constants.LOCAL_BRIDGE;
 import static org.onosproject.k8snode.api.Constants.LOCAL_TO_INTEGRATION_BRIDGE;
+import static org.onosproject.k8snode.api.Constants.OS_TO_K8S_BRIDGE;
 import static org.onosproject.k8snode.api.Constants.PHYSICAL_EXTERNAL_BRIDGE;
+import static org.onosproject.k8snode.api.Constants.ROUTER;
+import static org.onosproject.k8snode.api.Constants.ROUTER_TO_EXTERNAL;
 import static org.onosproject.k8snode.api.Constants.TUNNEL_BRIDGE;
 import static org.onosproject.k8snode.api.Constants.TUN_TO_INTEGRATION_BRIDGE;
 import static org.onosproject.k8snode.api.Constants.VXLAN_TUNNEL;
@@ -445,6 +451,63 @@
     }
 
     @Override
+    public PortNumber routerToExtPortNum() {
+        if (mode() == PASSTHROUGH) {
+            K8sHostService hostService =
+                    DefaultServiceDirectory.getService(K8sHostService.class);
+            Port port = null;
+            for (K8sHost host : hostService.hosts()) {
+                if (host.nodeNames().contains(hostname())) {
+                    for (K8sRouterBridge bridge : host.routerBridges()) {
+                        if (bridge.segmentId() == segmentId()) {
+                            port = port(bridge.deviceId(), routerToExtPatchPortName());
+                        }
+                    }
+                }
+            }
+
+            if (port == null) {
+                return null;
+            } else {
+                return port.number();
+            }
+        }
+
+        return null;
+    }
+
+    @Override
+    public PortNumber extToRouterPortNum() {
+        return portNumber(extBridge, extToRouterPatchPortName());
+    }
+
+    @Override
+    public PortNumber routerPortNum() {
+        if (mode() == PASSTHROUGH) {
+            K8sHostService hostService =
+                    DefaultServiceDirectory.getService(K8sHostService.class);
+            Port port = null;
+            for (K8sHost host : hostService.hosts()) {
+                if (host.nodeNames().contains(hostname())) {
+                    for (K8sRouterBridge bridge : host.routerBridges()) {
+                        if (bridge.segmentId() == segmentId()) {
+                            port = port(bridge.deviceId(), routerPortName());
+                        }
+                    }
+                }
+            }
+
+            if (port == null) {
+                return null;
+            } else {
+                return port.number();
+            }
+        }
+
+        return null;
+    }
+
+    @Override
     public PortNumber extBridgePortNum() {
         return PortNumber.LOCAL;
     }
@@ -459,7 +522,11 @@
 
     @Override
     public MacAddress intgBridgeMac() {
-        return macAddress(intgBridge, intgBridgeName());
+        if (mode == PASSTHROUGH) {
+            return MacAddress.valueOf(DEFAULT_INTG_BRIDGE_MAC);
+        } else {
+            return macAddress(intgBridge, intgBridgeName());
+        }
     }
 
     @Override
@@ -523,6 +590,24 @@
     }
 
     @Override
+    public String intgEntryPortName() {
+        if (mode == PASSTHROUGH) {
+            return k8sToOsIntgPatchPortName();
+        } else {
+            return intgBridgeName();
+        }
+    }
+
+    @Override
+    public PortNumber intgEntryPortNum() {
+        if (mode == PASSTHROUGH) {
+            return portNumber(intgBridge, k8sToOsIntgPatchPortName());
+        } else {
+            return intgBridgePortNum();
+        }
+    }
+
+    @Override
     public String extBridgeName() {
         if (mode == PASSTHROUGH) {
             return EXTERNAL_BRIDGE + "-" + uniqueString(5);
@@ -640,6 +725,51 @@
     }
 
     @Override
+    public String k8sToOsIntgPatchPortName() {
+        if (mode == PASSTHROUGH) {
+            return K8S_TO_OS_BRIDGE + "-" + uniqueString(5);
+        } else {
+            return K8S_TO_OS_BRIDGE;
+        }
+    }
+
+    @Override
+    public String osToK8sIntgPatchPortName() {
+        if (mode == PASSTHROUGH) {
+            return OS_TO_K8S_BRIDGE + "-" + uniqueString(5);
+        } else {
+            return OS_TO_K8S_BRIDGE;
+        }
+    }
+
+    @Override
+    public String routerToExtPatchPortName() {
+        if (mode == PASSTHROUGH) {
+            return ROUTER_TO_EXTERNAL + "-" + uniqueString(5);
+        } else {
+            return ROUTER_TO_EXTERNAL;
+        }
+    }
+
+    @Override
+    public String extToRouterPatchPortName() {
+        if (mode == PASSTHROUGH) {
+            return EXTERNAL_TO_ROUTER + "-" + uniqueString(5);
+        } else {
+            return EXTERNAL_TO_ROUTER;
+        }
+    }
+
+    @Override
+    public String routerPortName() {
+        if (mode == PASSTHROUGH) {
+            return ROUTER + "-" + segmentId();
+        } else {
+            return ROUTER;
+        }
+    }
+
+    @Override
     public boolean equals(Object obj) {
         if (this == obj) {
             return true;
diff --git a/apps/k8s-node/api/src/main/java/org/onosproject/k8snode/api/K8sBridge.java b/apps/k8s-node/api/src/main/java/org/onosproject/k8snode/api/K8sBridge.java
new file mode 100644
index 0000000..7659689
--- /dev/null
+++ b/apps/k8s-node/api/src/main/java/org/onosproject/k8snode/api/K8sBridge.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2020-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.k8snode.api;
+
+import org.onosproject.net.DeviceId;
+
+/**
+ * K8s bridge interface.
+ */
+public interface K8sBridge {
+
+    /**
+     * Returns device identifier.
+     *
+     * @return device identifier
+     */
+    DeviceId deviceId();
+
+    /**
+     * Return the datapath identifier.
+     *
+     * @return datapath identifier
+     */
+    String dpid();
+
+    /**
+     * Returns bridge name.
+     *
+     * @return bridge name
+     */
+    String name();
+}
diff --git a/apps/k8s-node/api/src/main/java/org/onosproject/k8snode/api/K8sHost.java b/apps/k8s-node/api/src/main/java/org/onosproject/k8snode/api/K8sHost.java
index 2eeb9c1..ab33cfe 100644
--- a/apps/k8s-node/api/src/main/java/org/onosproject/k8snode/api/K8sHost.java
+++ b/apps/k8s-node/api/src/main/java/org/onosproject/k8snode/api/K8sHost.java
@@ -62,6 +62,13 @@
     Set<K8sTunnelBridge> tunBridges();
 
     /**
+     * Returns the set of router bridges belong to the host.
+     *
+     * @return a set of router bridges
+     */
+    Set<K8sRouterBridge> routerBridges();
+
+    /**
      * Returns new kubernetes host instance with given state.
      *
      * @param newState updated state
@@ -120,5 +127,13 @@
          * @return kubernetes host builder
          */
         Builder tunBridges(Set<K8sTunnelBridge> tunBridges);
+
+        /**
+         * Returns kubernetes host builder with supplied router bridges set.
+         *
+         * @param routerBridges router bridges
+         * @return kubernetes host builder
+         */
+        Builder routerBridges(Set<K8sRouterBridge> routerBridges);
     }
 }
diff --git a/apps/k8s-node/api/src/main/java/org/onosproject/k8snode/api/K8sNode.java b/apps/k8s-node/api/src/main/java/org/onosproject/k8snode/api/K8sNode.java
index 632f7d2..9b695eb 100644
--- a/apps/k8s-node/api/src/main/java/org/onosproject/k8snode/api/K8sNode.java
+++ b/apps/k8s-node/api/src/main/java/org/onosproject/k8snode/api/K8sNode.java
@@ -245,6 +245,20 @@
     String intgBridgeName();
 
     /**
+     * Returns the entry port name of integration bridge.
+     *
+     * @return entry port name
+     */
+    String intgEntryPortName();
+
+    /**
+     * Return the port number of integration bridge's entry port.
+     *
+     * @return port number
+     */
+    PortNumber intgEntryPortNum();
+
+    /**
      * Returns external bridge name.
      *
      * @return external bridge name
@@ -336,6 +350,41 @@
     String tunToIntgPatchPortName();
 
     /**
+     * Returns kubernetes to openstack integration patch port name.
+     *
+     * @return kubernetes to openstack integration patch port name
+     */
+    String k8sToOsIntgPatchPortName();
+
+    /**
+     * Returns openstack to kubernetes integration patch port name.
+     *
+     * @return openstack to kubernetes integration patch port name
+     */
+    String osToK8sIntgPatchPortName();
+
+    /**
+     * Returns router to external bridge patch port name.
+     *
+     * @return router to external bridge patch port name
+     */
+    String routerToExtPatchPortName();
+
+    /**
+     * Returns external to router bridge patch port name.
+     *
+     * @return external to router bridge patch port name
+     */
+    String extToRouterPatchPortName();
+
+    /**
+     * Returns router part name.
+     *
+     * @return router port name
+     */
+    String routerPortName();
+
+    /**
      * Returns the GRE tunnel port number.
      *
      * @return GRE port number; null if the GRE tunnel port does not exist
@@ -406,6 +455,27 @@
     PortNumber tunToIntgPortNum();
 
     /**
+     * Returns the router to external bridge patch port number.
+     *
+     * @return patch port number
+     */
+    PortNumber routerToExtPortNum();
+
+    /**
+     * Returns the external to router bridge patch port number.
+     *
+     * @return patch port number
+     */
+    PortNumber extToRouterPortNum();
+
+    /**
+     * Returns the router port number.
+     *
+     * @return router port number
+     */
+    PortNumber routerPortNum();
+
+    /**
      * Returns the external bridge to router port number.
      *
      * @return port number, null if the port does not exist
diff --git a/apps/k8s-node/api/src/main/java/org/onosproject/k8snode/api/K8sRouterBridge.java b/apps/k8s-node/api/src/main/java/org/onosproject/k8snode/api/K8sRouterBridge.java
new file mode 100644
index 0000000..7e5b472
--- /dev/null
+++ b/apps/k8s-node/api/src/main/java/org/onosproject/k8snode/api/K8sRouterBridge.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright 2020-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.k8snode.api;
+
+import com.google.common.base.MoreObjects;
+import com.google.common.base.Strings;
+import org.onosproject.net.DeviceId;
+
+import java.util.Objects;
+
+import static org.onosproject.k8snode.api.Constants.ROUTER_BRIDGE;
+
+/**
+ * K8s router bridge.
+ */
+public class K8sRouterBridge implements K8sBridge {
+
+    private static final String OF_PREFIX = "of:";
+
+    private final int segmentId;
+
+    /**
+     * Default constructor.
+     *
+     * @param segmentId  segment identifier
+     */
+    public K8sRouterBridge(int segmentId) {
+        this.segmentId = segmentId;
+    }
+
+    /**
+     * Returns segment ID.
+     *
+     * @return segment ID
+     */
+    public int segmentId() {
+        return segmentId;
+    }
+
+    @Override
+    public DeviceId deviceId() {
+        return DeviceId.deviceId(dpid());
+    }
+
+    @Override
+    public String dpid() {
+        return genDpidFromName(name());
+    }
+
+    @Override
+    public String name() {
+        return ROUTER_BRIDGE + "-" + segmentId;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+        K8sRouterBridge that = (K8sRouterBridge) o;
+        return segmentId == that.segmentId;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(segmentId);
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(this)
+                .add("segmentId", segmentId)
+                .toString();
+    }
+
+    private String genDpidFromName(String name) {
+        if (name != null) {
+            String hexString = Integer.toHexString(name.hashCode());
+            return OF_PREFIX + Strings.padStart(hexString, 16, '0');
+        }
+
+        return null;
+    }
+}
diff --git a/apps/k8s-node/api/src/main/java/org/onosproject/k8snode/api/K8sTunnelBridge.java b/apps/k8s-node/api/src/main/java/org/onosproject/k8snode/api/K8sTunnelBridge.java
index 50d155e..510c9b7 100644
--- a/apps/k8s-node/api/src/main/java/org/onosproject/k8snode/api/K8sTunnelBridge.java
+++ b/apps/k8s-node/api/src/main/java/org/onosproject/k8snode/api/K8sTunnelBridge.java
@@ -29,7 +29,7 @@
 /**
  * K8s tunnel bridge.
  */
-public class K8sTunnelBridge {
+public class K8sTunnelBridge implements K8sBridge {
 
     private static final String OF_PREFIX = "of:";
 
@@ -44,11 +44,7 @@
         this.tunnelId = tunnelId;
     }
 
-    /**
-     * Returns device identifier.
-     *
-     * @return device identifier
-     */
+    @Override
     public DeviceId deviceId() {
         return DeviceId.deviceId(dpid());
     }
@@ -62,20 +58,12 @@
         return tunnelId;
     }
 
-    /**
-     * Return the datapath identifier.
-     *
-     * @return datapath identifier
-     */
+    @Override
     public String dpid() {
         return genDpidFromName(name());
     }
 
-    /**
-     * Returns bridge name.
-     *
-     * @return bridge name
-     */
+    @Override
     public String name() {
         return TUNNEL_BRIDGE + "-" + tunnelId;
     }