[ONOS-3585] Add the cli of setting external port name.

Change-Id: I71833063c8e3f27fff7d69499cd3d24fd5537274
diff --git a/apps/vtn/vtnmgr/pom.xml b/apps/vtn/vtnmgr/pom.xml
index 03e6670..4b360c2 100644
--- a/apps/vtn/vtnmgr/pom.xml
+++ b/apps/vtn/vtnmgr/pom.xml
@@ -49,5 +49,9 @@
             <artifactId>onos-app-vtn-rsc</artifactId>
             <version>${project.version}</version>
         </dependency>
+        <dependency>
+            <groupId>org.apache.karaf.shell</groupId>
+            <artifactId>org.apache.karaf.shell.console</artifactId>
+        </dependency>
     </dependencies>
 </project>
diff --git a/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/cli/VtnCommand.java b/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/cli/VtnCommand.java
new file mode 100644
index 0000000..92900f2
--- /dev/null
+++ b/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/cli/VtnCommand.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * 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.vtn.cli;
+
+import org.apache.karaf.shell.commands.Command;
+import org.apache.karaf.shell.commands.Option;
+import org.onosproject.cli.AbstractShellCommand;
+import org.onosproject.vtn.manager.impl.VTNManager;
+
+/**
+ * Supports for updating the external gateway virtualPort.
+ */
+@Command(scope = "onos", name = "externalportname-set",
+        description = "Supports for setting the external port name.")
+public class VtnCommand extends AbstractShellCommand {
+
+    @Option(name = "-n", aliases = "--name", description = "external port name.", required = true,
+            multiValued = false)
+    String exPortName = "";
+
+    @Override
+    protected void execute() {
+        VTNManager.setExPortName(exPortName);
+    }
+}
diff --git a/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/cli/package-info.java b/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/cli/package-info.java
new file mode 100644
index 0000000..7368244
--- /dev/null
+++ b/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/cli/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * 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.
+ */
+
+/**
+ * VTN application that applies configuration and flows to the device.
+ */
+package org.onosproject.vtn.cli;
diff --git a/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/manager/impl/VTNManager.java b/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/manager/impl/VTNManager.java
index 5b137c8..95a320f 100644
--- a/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/manager/impl/VTNManager.java
+++ b/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/manager/impl/VTNManager.java
@@ -26,6 +26,7 @@
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
 import java.util.stream.Collectors;
 
 import org.apache.felix.scr.annotations.Activate;
@@ -84,8 +85,12 @@
 import org.onosproject.vtn.table.L2ForwardService;
 import org.onosproject.vtn.table.L3ForwardService;
 import org.onosproject.vtn.table.SnatService;
+import org.onosproject.vtn.table.impl.ArpServiceImpl;
 import org.onosproject.vtn.table.impl.ClassifierServiceImpl;
+import org.onosproject.vtn.table.impl.DnatServiceImpl;
 import org.onosproject.vtn.table.impl.L2ForwardServiceImpl;
+import org.onosproject.vtn.table.impl.L3ForwardServiceImpl;
+import org.onosproject.vtn.table.impl.SnatServiceImpl;
 import org.onosproject.vtn.util.DataPathIdGenerator;
 import org.onosproject.vtn.util.VtnConfig;
 import org.onosproject.vtn.util.VtnData;
@@ -94,9 +99,6 @@
 import org.onosproject.vtnrsc.DefaultVirtualPort;
 import org.onosproject.vtnrsc.FixedIp;
 import org.onosproject.vtnrsc.FloatingIp;
-import org.onosproject.vtnrsc.Router;
-import org.onosproject.vtnrsc.RouterGateway;
-import org.onosproject.vtnrsc.RouterId;
 import org.onosproject.vtnrsc.RouterInterface;
 import org.onosproject.vtnrsc.SecurityGroup;
 import org.onosproject.vtnrsc.SegmentationId;
@@ -110,7 +112,6 @@
 import org.onosproject.vtnrsc.event.VtnRscEventFeedback;
 import org.onosproject.vtnrsc.event.VtnRscListener;
 import org.onosproject.vtnrsc.floatingip.FloatingIpService;
-import org.onosproject.vtnrsc.router.RouterService;
 import org.onosproject.vtnrsc.routerinterface.RouterInterfaceService;
 import org.onosproject.vtnrsc.service.VtnRscService;
 import org.onosproject.vtnrsc.subnet.SubnetService;
@@ -173,9 +174,6 @@
     protected FloatingIpService floatingIpService;
 
     @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
-    protected RouterService routerService;
-
-    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
     protected RouterInterfaceService routerInterfaceService;
 
     private ApplicationId appId;
@@ -190,10 +188,10 @@
     private final DeviceListener deviceListener = new InnerDeviceListener();
     private final VtnRscListener l3EventListener = new VtnL3EventListener();
 
+    private static String exPortName = "eth0";
     private static final String IFACEID = "ifaceid";
     private static final String CONTROLLER_IP_KEY = "ipaddress";
     public static final String DRIVER_NAME = "onosfw";
-    private static final String EX_PORT_NAME = "eth0";
     private static final String VIRTUALPORT = "vtn-virtual-port";
     private static final String SWITCHES_OF_CONTROLLER = "switchesOfController";
     private static final String SWITCH_OF_LOCAL_HOST_PORTS = "switchOfLocalHostPorts";
@@ -215,9 +213,14 @@
         appId = coreService.registerApplication(APP_ID);
         classifierService = new ClassifierServiceImpl(appId);
         l2ForwardService = new L2ForwardServiceImpl(appId);
+        arpService = new ArpServiceImpl(appId);
+        l3ForwardService = new L3ForwardServiceImpl(appId);
+        snatService = new SnatServiceImpl(appId);
+        dnatService = new DnatServiceImpl(appId);
 
         deviceService.addListener(deviceListener);
         hostService.addListener(hostListener);
+        vtnRscService.addListener(l3EventListener);
 
         KryoNamespace.Builder serializer = KryoNamespace.newBuilder()
                                 .register(KryoNamespaces.API)
@@ -307,7 +310,7 @@
             config.driver(DRIVER_NAME);
             configService.applyConfig(deviceId, BasicDeviceConfig.class, config.node());
             // Add Bridge
-            VtnConfig.applyBridgeConfig(handler, dpid, EX_PORT_NAME);
+            VtnConfig.applyBridgeConfig(handler, dpid, exPortName);
             log.info("A new ovs is created in node {}", localIp.toString());
             switchesOfController.put(localIp, true);
         }
@@ -471,6 +474,28 @@
         if (virtualPort == null) {
             virtualPort = VtnData.getPort(vPortStore, virtualPortId);
         }
+        Iterator<FixedIp> fixip = virtualPort.fixedIps().iterator();
+        SubnetId subnetId = null;
+        if (fixip.hasNext()) {
+            subnetId = fixip.next().subnetId();
+        }
+        if (subnetId != null) {
+            Map<HostId, Host> hosts = new ConcurrentHashMap();
+            if (hostsOfSubnet.get(subnetId) != null) {
+                hosts = hostsOfSubnet.get(subnetId);
+            }
+            if (type == Objective.Operation.ADD) {
+                hosts.put(host.id(), host);
+                hostsOfSubnet.put(subnetId, hosts);
+            } else if (type == Objective.Operation.REMOVE) {
+                hosts.remove(host.id());
+                if (hosts.size() != 0) {
+                    hostsOfSubnet.put(subnetId, hosts);
+                } else {
+                    hostsOfSubnet.remove(subnetId);
+                }
+            }
+        }
 
         Iterable<Device> devices = deviceService.getAvailableDevices();
         PortNumber inPort = host.location().port();
@@ -887,15 +912,8 @@
         List gwIpMac = getGwIpAndMac(vmPort);
         IpAddress dstVmGwIp = (IpAddress) gwIpMac.get(0);
         MacAddress dstVmGwMac = (MacAddress) gwIpMac.get(1);
-        FixedIp fixedGwIp = getGwFixedIp(floatingIp);
-        MacAddress fGwMac = null;
-        if (fixedGwIp != null) {
-            VirtualPort gwPort = virtualPortService.getPort(fixedGwIp);
-            if (gwPort == null) {
-                gwPort = VtnData.getPort(vPortStore, fixedGwIp);
-            }
-            fGwMac = gwPort.macAddress();
-        }
+        List fGwIpMac = getGwIpAndMac(fipPort);
+        MacAddress fGwMac = (MacAddress) fGwIpMac.get(1);
         TenantNetwork vmNetwork = tenantNetworkService
                 .getNetwork(vmPort.networkId());
         TenantNetwork fipNetwork = tenantNetworkService
@@ -947,7 +965,7 @@
         Port exPort = null;
         for (Port port : ports) {
             String portName = port.annotations().value(AnnotationKeys.PORT_NAME);
-            if (portName != null && portName.equals(EX_PORT_NAME)) {
+            if (portName != null && portName.equals(exPortName)) {
                 exPort = port;
                 break;
             }
@@ -977,21 +995,6 @@
         return list;
     }
 
-    private FixedIp getGwFixedIp(FloatingIp floatingIp) {
-        RouterId routerId = floatingIp.routerId();
-        Router router = routerService.getRouter(routerId);
-        RouterGateway routerGateway = router.externalGatewayInfo();
-        Iterable<FixedIp> externalFixedIps = routerGateway.externalFixedIps();
-        FixedIp fixedGwIp = null;
-        if (externalFixedIps != null) {
-            Iterator<FixedIp> exFixedIps = externalFixedIps.iterator();
-            if (exFixedIps.hasNext()) {
-                fixedGwIp = exFixedIps.next();
-            }
-        }
-        return fixedGwIp;
-    }
-
     private void applyHostMonitoredL3Rules(Host host,
                                            Objective.Operation operation) {
         String ifaceId = host.annotations().value(IFACEID);
@@ -1060,4 +1063,8 @@
                                    l3vni, exPort, operation);
         }
     }
+
+    public static void setExPortName(String name) {
+        exPortName = name;
+    }
 }
diff --git a/apps/vtn/vtnmgr/src/main/resources/OSGI-INF/blueprint/shell-config.xml b/apps/vtn/vtnmgr/src/main/resources/OSGI-INF/blueprint/shell-config.xml
new file mode 100644
index 0000000..ecc6de0
--- /dev/null
+++ b/apps/vtn/vtnmgr/src/main/resources/OSGI-INF/blueprint/shell-config.xml
@@ -0,0 +1,23 @@
+<!--
+  ~ Copyright 2015 Open Networking Laboratory
+  ~
+  ~ 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.
+  -->
+<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
+
+  <command-bundle xmlns="http://karaf.apache.org/xmlns/shell/v1.1.0">
+    <command>
+      <action class="org.onosproject.vtn.cli.VtnCommand"/>
+    </command>
+  </command-bundle>
+</blueprint>