Support distributed virtual router (DVR) at kubernetes

Change-Id: I6dfa1ad0d2161443e37fa80901d5ababbec6f74e
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 c32f766..b6382d7 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
@@ -48,4 +48,6 @@
     public static final String DEFAULT_CONFIG_MODE = "NORMAL";
 
     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";
 }
diff --git a/apps/k8s-node/api/src/main/java/org/onosproject/k8snode/api/DefaultK8sApiConfig.java b/apps/k8s-node/api/src/main/java/org/onosproject/k8snode/api/DefaultK8sApiConfig.java
index cbc62e6..9c372b1 100644
--- a/apps/k8s-node/api/src/main/java/org/onosproject/k8snode/api/DefaultK8sApiConfig.java
+++ b/apps/k8s-node/api/src/main/java/org/onosproject/k8snode/api/DefaultK8sApiConfig.java
@@ -51,11 +51,13 @@
     private final String clientCertData;
     private final String clientKeyData;
     private final Set<HostNodesInfo> infos;
+    private final boolean dvr;
 
     private DefaultK8sApiConfig(String clusterName, int segmentId, IpPrefix extNetworkCidr,
                                 Scheme scheme, IpAddress ipAddress, int port,
                                 Mode mode, State state, String token, String caCertData,
-                                String clientCertData, String clientKeyData, Set<HostNodesInfo> infos) {
+                                String clientCertData, String clientKeyData,
+                                Set<HostNodesInfo> infos, boolean dvr) {
         this.clusterName = clusterName;
         this.segmentId = segmentId;
         this.extNetworkCidr = extNetworkCidr;
@@ -69,6 +71,7 @@
         this.clientCertData = clientCertData;
         this.clientKeyData = clientKeyData;
         this.infos = infos;
+        this.dvr = dvr;
     }
 
     @Override
@@ -132,6 +135,7 @@
                 .clientCertData(clientCertData)
                 .clientKeyData(clientKeyData)
                 .infos(infos)
+                .dvr(dvr)
                 .build();
     }
 
@@ -161,6 +165,11 @@
     }
 
     @Override
+    public boolean dvr() {
+        return dvr;
+    }
+
+    @Override
     public boolean equals(Object o) {
         if (this == o) {
             return true;
@@ -181,13 +190,14 @@
                 caCertData.equals(that.caCertData) &&
                 clientCertData.equals(that.clientCertData) &&
                 clientKeyData.equals(that.clientKeyData) &&
-                infos.equals(that.infos);
+                infos.equals(that.infos) &&
+                dvr == that.dvr;
     }
 
     @Override
     public int hashCode() {
-        return Objects.hash(clusterName, segmentId, extNetworkCidr, scheme, ipAddress,
-                port, mode, state, token, caCertData, clientCertData, clientKeyData, infos);
+        return Objects.hash(clusterName, segmentId, extNetworkCidr, scheme, ipAddress, port,
+                mode, state, token, caCertData, clientCertData, clientKeyData, infos, dvr);
     }
 
     @Override
@@ -206,6 +216,7 @@
                 .add("clientCertData", clientCertData)
                 .add("clientKeyData", clientKeyData)
                 .add("infos", infos)
+                .add("dvr", dvr)
                 .toString();
     }
 
@@ -233,6 +244,7 @@
         private String clientCertData;
         private String clientKeyData;
         private Set<HostNodesInfo> infos;
+        private boolean dvr;
 
         @Override
         public K8sApiConfig build() {
@@ -259,7 +271,7 @@
             }
 
             return new DefaultK8sApiConfig(clusterName, segmentId, extNetworkCidr, scheme, ipAddress,
-                    port, mode, state, token, caCertData, clientCertData, clientKeyData, infos);
+                    port, mode, state, token, caCertData, clientCertData, clientKeyData, infos, dvr);
         }
 
         @Override
@@ -339,5 +351,11 @@
             this.infos = infos;
             return this;
         }
+
+        @Override
+        public K8sApiConfig.Builder dvr(boolean dvr) {
+            this.dvr = dvr;
+            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 4e430a3..551a339 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
@@ -32,6 +32,8 @@
 
 import static com.google.common.base.Preconditions.checkArgument;
 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.EXTERNAL_BRIDGE;
 import static org.onosproject.k8snode.api.Constants.GENEVE_TUNNEL;
 import static org.onosproject.k8snode.api.Constants.GRE_TUNNEL;
@@ -414,6 +416,14 @@
     }
 
     @Override
+    public PortNumber extIntfPortNum() {
+        if (this.extIntf == null) {
+            return null;
+        }
+        return portNumber(extBridge, extIntf());
+    }
+
+    @Override
     public MacAddress intgBridgeMac() {
         return macAddress(intgBridge, intgBridgeName());
     }
@@ -425,7 +435,11 @@
 
     @Override
     public MacAddress extBridgeMac() {
-        return macAddress(extBridge, extBridgeName());
+        if (MacAddress.valueOf(DEFAULT_EXTERNAL_GATEWAY_MAC).equals(extGatewayMac())) {
+            return MacAddress.valueOf(DEFAULT_EXTERNAL_BRIDGE_MAC);
+        } else {
+            return macAddress(extBridge, extBridgeName());
+        }
     }
 
     @Override
diff --git a/apps/k8s-node/api/src/main/java/org/onosproject/k8snode/api/K8sApiConfig.java b/apps/k8s-node/api/src/main/java/org/onosproject/k8snode/api/K8sApiConfig.java
index d01f3a2..900290c 100644
--- a/apps/k8s-node/api/src/main/java/org/onosproject/k8snode/api/K8sApiConfig.java
+++ b/apps/k8s-node/api/src/main/java/org/onosproject/k8snode/api/K8sApiConfig.java
@@ -174,6 +174,13 @@
     Set<HostNodesInfo> infos();
 
     /**
+     * Returns the distributed virtual router flag value.
+     *
+     * @return true if it supports DVR, false otherwise
+     */
+    boolean dvr();
+
+    /**
      * Builder of new API config entity.
      */
     interface Builder {
@@ -288,5 +295,13 @@
          * @return kubernetes API config builder
          */
         Builder infos(Set<HostNodesInfo> infos);
+
+        /**
+         * Returns kubernetes API server config builder with supplied DVR flag.
+         *
+         * @param dvr distributed virtual router flag
+         * @return kubernetes API config builder
+         */
+        Builder dvr(boolean dvr);
     }
 }
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 e443880..632f7d2 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
@@ -413,6 +413,13 @@
     PortNumber extBridgePortNum();
 
     /**
+     * Returns the external interface (attached to external bridge) port number.
+     *
+     * @return port number, null if the port does ont exist
+     */
+    PortNumber extIntfPortNum();
+
+    /**
      * Returns the integration bridge's MAC address.
      *
      * @return MAC address; null if the MAC address does not exist