OpenstackRouting refactoring

- Replace OpenstackPortInfo with HostService
- Replace OpenstackRoutingConfig with OpenstackNodeService
  (Remove OpenstackRoutingConfig)
- Rebased with 10330 (existing_vm)
- Added initialization process using OpenstackNodeListener

Change-Id: If2ce8eb86d242a7180c9154e1a0f1668b266bf1c
diff --git a/apps/openstacknetworking/switching/src/main/java/org/onosproject/openstacknetworking/switching/Constants.java b/apps/openstacknetworking/api/src/main/java/org/onosproject/openstacknetworking/Constants.java
similarity index 78%
rename from apps/openstacknetworking/switching/src/main/java/org/onosproject/openstacknetworking/switching/Constants.java
rename to apps/openstacknetworking/api/src/main/java/org/onosproject/openstacknetworking/Constants.java
index b173f29..54334b9 100644
--- a/apps/openstacknetworking/switching/src/main/java/org/onosproject/openstacknetworking/switching/Constants.java
+++ b/apps/openstacknetworking/api/src/main/java/org/onosproject/openstacknetworking/Constants.java
@@ -13,14 +13,15 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.onosproject.openstacknetworking.switching;
+package org.onosproject.openstacknetworking;
 
 import org.onlab.packet.Ip4Address;
 import org.onlab.packet.Ip4Prefix;
 import org.onlab.packet.IpPrefix;
+import org.onlab.packet.MacAddress;
 
 /**
- * Provides constants used in OpenStack node services.
+ * Provides constants used in OpenStackSwitching.
  */
 public final class Constants {
 
@@ -33,9 +34,11 @@
     public static final String PORTNAME_PREFIX_ROUTER = "qr-";
     public static final String PORTNAME_PREFIX_TUNNEL = "vxlan";
 
-    // TODO remove this
-    public static final String ROUTER_INTERFACE = "network:router_interface";
-    public static final String DEVICE_OWNER_GATEWAY = "network:router_gateway";
+    public static final MacAddress GATEWAY_MAC = MacAddress.valueOf("1f:1f:1f:1f:1f:1f");
+
+    // TODO: Please change these valuses following the way vrouter is implemented
+    public static final MacAddress GW_EXT_INT_MAC = MacAddress.valueOf("56:e6:30:a6:8c:e5");
+    public static final MacAddress PHY_ROUTER_MAC = MacAddress.valueOf("00:00:00:00:01:01");
 
     public static final Ip4Address DNS_SERVER_IP = Ip4Address.valueOf("8.8.8.8");
     public static final IpPrefix IP_PREFIX_ANY = Ip4Prefix.valueOf("0.0.0.0/0");
@@ -51,4 +54,5 @@
     public static final int SWITCHING_RULE_PRIORITY = 30000;
     public static final int TUNNELTAG_RULE_PRIORITY = 30000;
     public static final int ACL_RULE_PRIORITY = 30000;
+
 }
\ No newline at end of file
diff --git a/apps/openstacknetworking/api/src/main/java/org/onosproject/openstacknetworking/OpenstackPortInfo.java b/apps/openstacknetworking/api/src/main/java/org/onosproject/openstacknetworking/OpenstackPortInfo.java
deleted file mode 100644
index b40b865..0000000
--- a/apps/openstacknetworking/api/src/main/java/org/onosproject/openstacknetworking/OpenstackPortInfo.java
+++ /dev/null
@@ -1,206 +0,0 @@
-/*
- * Copyright 2016-present 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.openstacknetworking;
-
-import org.onlab.packet.Ip4Address;
-import org.onlab.packet.MacAddress;
-import org.onosproject.net.DeviceId;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-/**
- * Contains OpenstackPort Information.
- */
-// TODO remove this
-public final class OpenstackPortInfo {
-    private final Ip4Address hostIp;
-    private final MacAddress hostMac;
-    private final DeviceId deviceId;
-    private final long vni;
-    private final Ip4Address gatewayIP;
-    private final String networkId;
-
-    /**
-     * Returns OpenstackPortInfo reference.
-     *
-     * @param hostIp host IP address
-     * @param hostMac host MAC address
-     * @param deviceId device ID
-     * @param vni  tunnel ID
-     * @param gatewayIP gateway IP address
-     * @param networkId network identifier
-     */
-    public OpenstackPortInfo(Ip4Address hostIp, MacAddress hostMac, DeviceId deviceId, long vni,
-                             Ip4Address gatewayIP, String networkId) {
-        this.hostIp = hostIp;
-        this.hostMac = hostMac;
-        this.deviceId = deviceId;
-        this.vni = vni;
-        this.gatewayIP = gatewayIP;
-        this.networkId = networkId;
-    }
-
-    /**
-     * Returns IP address of the port.
-     *
-     * @return IP address
-     */
-    public Ip4Address ip() {
-        return hostIp;
-    }
-
-    /**
-     * Returns MAC address of the port.
-     *
-     * @return MAC address
-     */
-    public MacAddress mac() {
-        return hostMac;
-    }
-
-    /**
-     * Returns device ID.
-     *
-     * @return device ID
-     */
-    public DeviceId deviceId() {
-        return deviceId;
-    }
-
-    /**
-     * Returns tunnel ID.
-     *
-     * @return tunnel ID
-     */
-    public long vni() {
-        return vni;
-    }
-
-    /**
-     * Returns gateway IP address.
-     *
-     * @return gateway IP address
-     */
-    public Ip4Address gatewayIP() {
-        return gatewayIP;
-    }
-
-    /**
-     * Returns network ID.
-     *
-     * @return network ID
-     */
-    public String networkId() {
-        return  networkId;
-    }
-
-    /**
-     * Returns the builder of the OpenstackPortInfo.
-     *
-     * @return OpenstackPortInfo builder reference
-     */
-    public static OpenstackPortInfo.Builder builder() {
-        return new Builder();
-    }
-
-    /**
-     * Represents the OpenstackPortInfo Builder.
-     *
-     */
-    public static final class Builder {
-        private Ip4Address hostIp;
-        private MacAddress hostMac;
-        private DeviceId deviceId;
-        private long vni;
-        private Ip4Address gatewayIP;
-        private String networkId;
-
-        /**
-         * Sets the IP address of the port.
-         *
-         * @param gatewayIP gateway IP
-         * @return Builder reference
-         */
-        public Builder setGatewayIP(Ip4Address gatewayIP) {
-            this.gatewayIP = checkNotNull(gatewayIP, "gatewayIP cannot be null");
-            return this;
-        }
-
-        /**
-         * Sets the network ID.
-         *
-         * @param networkId network id
-         * @return Builder reference
-         */
-        public Builder setNetworkId(String networkId) {
-            this.networkId = checkNotNull(networkId, "networkId cannot be null");
-            return this;
-        }
-
-        /**
-         * Sets the host IP address of the port.
-         *
-         * @param hostIp host IP address
-         * @return Builder reference
-         */
-        public Builder setHostIp(Ip4Address hostIp) {
-            this.hostIp = checkNotNull(hostIp, "hostIp cannot be null");
-            return this;
-        }
-
-        /**
-         * Sets the host MAC address of the port.
-         *
-         * @param hostMac host MAC address
-         * @return Builder reference
-         */
-        public Builder setHostMac(MacAddress hostMac) {
-            this.hostMac = checkNotNull(hostMac, "hostMac cannot be bull");
-            return this;
-        }
-
-        /**
-         * Sets the device ID.
-         *
-         * @param deviceId device ID
-         * @return Builder reference
-         */
-        public Builder setDeviceId(DeviceId deviceId) {
-            this.deviceId = checkNotNull(deviceId, "deviceId cannot be null");
-            return this;
-        }
-
-        /**
-         * Sets the tunnel ID.
-         *
-         * @param vni tunnel ID
-         * @return Builder reference
-         */
-        public Builder setVni(long vni) {
-            this.vni = checkNotNull(vni, "vni cannot be null");
-            return this;
-        }
-
-        /**
-         * Builds the OpenstackPortInfo reference.
-         *
-         * @return OpenstackPortInfo reference
-         */
-        public OpenstackPortInfo build() {
-            return new OpenstackPortInfo(hostIp, hostMac, deviceId, vni, gatewayIP, networkId);
-        }
-    }
-}
diff --git a/apps/openstacknetworking/api/src/main/java/org/onosproject/openstacknetworking/OpenstackRoutingService.java b/apps/openstacknetworking/api/src/main/java/org/onosproject/openstacknetworking/OpenstackRoutingService.java
index 7fe75b4..6b04bfe 100644
--- a/apps/openstacknetworking/api/src/main/java/org/onosproject/openstacknetworking/OpenstackRoutingService.java
+++ b/apps/openstacknetworking/api/src/main/java/org/onosproject/openstacknetworking/OpenstackRoutingService.java
@@ -85,8 +85,8 @@
      *
      * @param portId Deleted vm
      * @param portInfo stored information about deleted vm
-     */
     void checkDisassociatedFloatingIp(String portId, OpenstackPortInfo portInfo);
+    */
 
     /**
      * Returns network id for routerInterface.
diff --git a/apps/openstacknetworking/api/src/main/java/org/onosproject/openstacknetworking/OpenstackSwitchingService.java b/apps/openstacknetworking/api/src/main/java/org/onosproject/openstacknetworking/OpenstackSwitchingService.java
deleted file mode 100644
index c9f32ab..0000000
--- a/apps/openstacknetworking/api/src/main/java/org/onosproject/openstacknetworking/OpenstackSwitchingService.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright 2016-present 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.openstacknetworking;
-
-import java.util.Map;
-
-/**
- * Handles port management REST API from Openstack for VMs.
- */
-// TODO remove this
-public interface OpenstackSwitchingService {
-
-    /**
-     * Retruns OpenstackPortInfo map.
-     *
-     * @return OpenstackPortInfo map
-     */
-    // TODO remove this
-    Map<String, OpenstackPortInfo> openstackPortInfo();
-}
diff --git a/apps/openstacknetworking/routing/pom.xml b/apps/openstacknetworking/routing/pom.xml
index cc4f7d0..06a6d7e 100644
--- a/apps/openstacknetworking/routing/pom.xml
+++ b/apps/openstacknetworking/routing/pom.xml
@@ -68,6 +68,11 @@
             <artifactId>onos-scalablegateway</artifactId>
             <version>${project.version}</version>
         </dependency>
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onos-app-openstacknode</artifactId>
+            <version>${project.version}</version>
+        </dependency>
     </dependencies>
 </project>
 
diff --git a/apps/openstacknetworking/routing/src/main/java/org/onosproject/openstacknetworking/routing/OpenstackFloatingIPHandler.java b/apps/openstacknetworking/routing/src/main/java/org/onosproject/openstacknetworking/routing/OpenstackFloatingIPHandler.java
index 073a47f..3d1c013 100644
--- a/apps/openstacknetworking/routing/src/main/java/org/onosproject/openstacknetworking/routing/OpenstackFloatingIPHandler.java
+++ b/apps/openstacknetworking/routing/src/main/java/org/onosproject/openstacknetworking/routing/OpenstackFloatingIPHandler.java
@@ -15,34 +15,39 @@
  */
 package org.onosproject.openstacknetworking.routing;
 
+import org.onosproject.net.Host;
 import org.onosproject.openstackinterface.OpenstackFloatingIP;
-import org.onosproject.openstacknetworking.OpenstackPortInfo;
 
 /**
  * Handle FloatingIP Event for Managing Flow Rules In Openstack Nodes.
  */
 public class OpenstackFloatingIPHandler implements Runnable {
 
+    public enum Action {
+        ASSOCIATE,
+        DISSASSOCIATE
+    }
+
     private final OpenstackFloatingIP floatingIP;
     private final OpenstackRoutingRulePopulator rulePopulator;
-    private boolean associate;
-    private final OpenstackPortInfo portInfo;
+    private final Host host;
+    private final Action action;
+
 
     OpenstackFloatingIPHandler(OpenstackRoutingRulePopulator rulePopulator,
-                               OpenstackFloatingIP openstackFloatingIP, boolean associate, OpenstackPortInfo portInfo) {
+                               OpenstackFloatingIP openstackFloatingIP, Action action, Host host) {
         this.floatingIP = openstackFloatingIP;
         this.rulePopulator = rulePopulator;
-        this.associate = associate;
-        this.portInfo = portInfo;
+        this.action = action;
+        this.host = host;
     }
 
     @Override
     public void run() {
-        if (associate) {
+        if (action == Action.ASSOCIATE) {
             rulePopulator.populateFloatingIpRules(floatingIP);
         } else {
-            rulePopulator.removeFloatingIpRules(floatingIP, portInfo);
+            rulePopulator.removeFloatingIpRules(floatingIP, host);
         }
-
     }
 }
diff --git a/apps/openstacknetworking/routing/src/main/java/org/onosproject/openstacknetworking/routing/OpenstackIcmpHandler.java b/apps/openstacknetworking/routing/src/main/java/org/onosproject/openstacknetworking/routing/OpenstackIcmpHandler.java
index 9678598..8b3339b 100644
--- a/apps/openstacknetworking/routing/src/main/java/org/onosproject/openstacknetworking/routing/OpenstackIcmpHandler.java
+++ b/apps/openstacknetworking/routing/src/main/java/org/onosproject/openstacknetworking/routing/OpenstackIcmpHandler.java
@@ -20,9 +20,11 @@
 import org.onlab.packet.ICMP;
 import org.onlab.packet.IPv4;
 import org.onlab.packet.Ip4Address;
+import org.onlab.packet.IpAddress;
 import org.onlab.packet.MacAddress;
 import org.onosproject.core.ApplicationId;
 import org.onosproject.net.DeviceId;
+import org.onosproject.net.Host;
 import org.onosproject.net.Port;
 import org.onosproject.net.PortNumber;
 import org.onosproject.net.device.DeviceService;
@@ -30,16 +32,17 @@
 import org.onosproject.net.flow.DefaultTrafficTreatment;
 import org.onosproject.net.flow.TrafficSelector;
 import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.host.HostService;
 import org.onosproject.net.packet.DefaultOutboundPacket;
 import org.onosproject.net.packet.OutboundPacket;
 import org.onosproject.net.packet.PacketContext;
 import org.onosproject.net.packet.PacketPriority;
 import org.onosproject.net.packet.PacketService;
+import org.onosproject.openstacknetworking.Constants;
 import org.onosproject.openstackinterface.OpenstackInterfaceService;
 import org.onosproject.openstackinterface.OpenstackPort;
-import org.onosproject.openstacknetworking.OpenstackNetworkingConfig;
-import org.onosproject.openstacknetworking.OpenstackPortInfo;
-import org.onosproject.openstacknetworking.OpenstackSwitchingService;
+import org.onosproject.openstacknode.OpenstackNode;
+import org.onosproject.openstacknode.OpenstackNodeService;
 import org.onosproject.scalablegateway.api.ScalableGatewayService;
 import org.slf4j.Logger;
 
@@ -58,37 +61,39 @@
 public class OpenstackIcmpHandler {
     protected final Logger log = getLogger(getClass());
 
-    private final PacketService packetService;
-    private final DeviceService deviceService;
-    private final Map<String, OpenstackPortInfo> icmpInfoMap = Maps.newHashMap();
-    private final OpenstackSwitchingService openstackSwitchingService;
-    private final OpenstackInterfaceService openstackService;
-    private final ScalableGatewayService gatewayService;
-    private final OpenstackNetworkingConfig config;
-    private static final MacAddress GATEWAY_MAC = MacAddress.valueOf("1f:1f:1f:1f:1f:1f");
+
     private static final String NETWORK_ROUTER_INTERFACE = "network:router_interface";
     private static final String PORTNAME = "portName";
     private static final String NETWORK_ROUTER_GATEWAY = "network:router_gateway";
     private static final String NETWORK_FLOATING_IP = "network:floatingip";
-    private static final String EXTERNAL_NODE_NULL = "There is no external node about this deviceId []";
+
+    private final PacketService packetService;
+    private final DeviceService deviceService;
+    private final ScalableGatewayService gatewayService;
+    private final HostService hostService;
+    private final Map<String, Host> icmpInfoMap = Maps.newHashMap();
+    private final OpenstackInterfaceService openstackService;
+    private final OpenstackNodeService nodeService;
+
     /**
      * Default constructor.
      *
      * @param packetService             packet service
      * @param deviceService             device service
      * @param openstackService          openstackInterface service
-     * @param config                    openstackRoutingConfig
-     * @param openstackSwitchingService openstackSwitching service
-     * @param gatewayService scalable gateway service
      */
-    OpenstackIcmpHandler(PacketService packetService, DeviceService deviceService,
-                         OpenstackInterfaceService openstackService, OpenstackNetworkingConfig config,
-                         OpenstackSwitchingService openstackSwitchingService, ScalableGatewayService gatewayService) {
+    OpenstackIcmpHandler(PacketService packetService,
+                         DeviceService deviceService,
+                         HostService hostService,
+                         OpenstackInterfaceService openstackService,
+                         OpenstackNodeService nodeService,
+                         ScalableGatewayService gatewayService
+                         ) {
         this.packetService = packetService;
         this.deviceService = deviceService;
+        this.hostService = hostService;
         this.openstackService = checkNotNull(openstackService);
-        this.config = checkNotNull(config);
-        this.openstackSwitchingService = checkNotNull(openstackSwitchingService);
+        this.nodeService = nodeService;
         this.gatewayService = gatewayService;
     }
 
@@ -103,13 +108,20 @@
                 .matchIPProtocol(IPv4.PROTOCOL_ICMP)
                 .build();
 
-        Map<DeviceId, PortNumber> externalInfoMap = getExternalInfo();
+       // TODO: Return the correct gateway node
+        Optional<OpenstackNode> gwNode =  nodeService.nodes().stream()
+                .filter(n -> n.type().equals(OpenstackNodeService.NodeType.GATEWAY))
+                .findFirst();
 
-        externalInfoMap.keySet().forEach(deviceId ->
-                packetService.requestPackets(icmpSelector,
-                        PacketPriority.CONTROL,
-                        appId,
-                        Optional.of(deviceId)));
+        if (!gwNode.isPresent()) {
+            log.warn("No Gateway is defined.");
+            return;
+        }
+
+        packetService.requestPackets(icmpSelector,
+                PacketPriority.CONTROL,
+                appId,
+                Optional.of(gwNode.get().intBridge()));
     }
 
     /**
@@ -135,11 +147,13 @@
         if (icmp.getIcmpType() == ICMP.TYPE_ECHO_REQUEST) {
             //TODO: Considers icmp between internal subnets which are belonged to the same router.
 
-            OpenstackPortInfo openstackPortInfo =
-                    getOpenstackPortInfo(Ip4Address.valueOf(ipPacket.getSourceAddress()), ethernet.getSourceMAC());
+            //OpenstackPortInfo openstackPortInfo =
+            //        getOpenstackPortInfo(Ip4Address.valueOf(ipPacket.getSourceAddress()), ethernet.getSourceMAC());
 
             //checkNotNull(openstackPortInfo, "openstackPortInfo can not be null");
+            /* XXX Is this handling ICMP to gateway ?????
             if (requestToOpenstackRoutingNetwork(ipPacket.getDestinationAddress())) {
+                Host host =
                 if (openstackPortInfo == null) {
                     if (config.gatewayBridgeId().equals(context.inPacket().receivedFrom().deviceId().toString())) {
                          if (portNumber.equals(getPortForAnnotationPortName(deviceId,
@@ -151,15 +165,23 @@
                     }
                     return;
                 } else {
-                    processIcmpPacketSentToGateway(ipPacket, icmp, openstackPortInfo);
+                    processIcmpPacketSentToGateway(ipPacket, icmp, host);
                     return;
                 }
             }
+            */
 
-            if (ipPacket.getDestinationAddress() == openstackPortInfo.gatewayIP().toInt()) {
-                processIcmpPacketSentToGateway(ipPacket, icmp, openstackPortInfo);
+            Optional<Host> host = hostService.getHostsByMac(ethernet.getSourceMAC()).stream().findFirst();
+            if (!host.isPresent()) {
+                log.warn("No host found for MAC {}", ethernet.getSourceMAC());
+                return;
+            }
+
+            IpAddress gatewayIp = IpAddress.valueOf(host.get().annotations().value(Constants.GATEWAY_IP));
+            if (ipPacket.getDestinationAddress() == gatewayIp.getIp4Address().toInt()) {
+                processIcmpPacketSentToGateway(ipPacket, icmp, host.get());
             } else {
-                Ip4Address pNatIpAddress = pNatIpForPort(openstackPortInfo);
+                Ip4Address pNatIpAddress = pNatIpForPort(host.get());
                 checkNotNull(pNatIpAddress, "pNatIpAddress can not be null");
 
                 sendRequestPacketToExt(ipPacket, icmp, deviceId, pNatIpAddress);
@@ -167,7 +189,7 @@
                 String icmpInfoKey = String.valueOf(icmpId)
                         .concat(String.valueOf(pNatIpAddress.toInt()))
                         .concat(String.valueOf(ipPacket.getDestinationAddress()));
-                icmpInfoMap.putIfAbsent(icmpInfoKey, openstackPortInfo);
+                icmpInfoMap.putIfAbsent(icmpInfoKey, host.get());
             }
         } else if (icmp.getIcmpType() == ICMP.TYPE_ECHO_REPLY) {
             String icmpInfoKey = String.valueOf(icmpId)
@@ -190,7 +212,8 @@
         icmpRequestIpv4.setPayload(icmpRequest);
         Ethernet icmpResponseEth = new Ethernet();
         icmpResponseEth.setEtherType(Ethernet.TYPE_IPV4)
-                .setSourceMACAddress(config.gatewayExternalInterfaceMac())
+                // TODO: Get the correct GW MAC
+                .setSourceMACAddress(Constants.GW_EXT_INT_MAC)
                 .setDestinationMACAddress(destMac).setPayload(icmpRequestIpv4);
         TrafficTreatment treatment = DefaultTrafficTreatment.builder().setOutput(portNumber).build();
         OutboundPacket packet = new DefaultOutboundPacket(deviceId,
@@ -199,13 +222,14 @@
     }
 
     private void processIcmpPacketSentToGateway(IPv4 icmpRequestIpv4, ICMP icmpRequest,
-                                                OpenstackPortInfo openstackPortInfo) {
+                                                Host host) {
         icmpRequest.setChecksum((short) 0);
         icmpRequest.setIcmpType(ICMP.TYPE_ECHO_REPLY)
                 .resetChecksum();
 
+        Ip4Address ipAddress = host.ipAddresses().stream().findAny().get().getIp4Address();
         icmpRequestIpv4.setSourceAddress(icmpRequestIpv4.getDestinationAddress())
-                .setDestinationAddress(openstackPortInfo.ip().toInt())
+                .setDestinationAddress(ipAddress.toInt())
                 .resetChecksum();
 
         icmpRequestIpv4.setPayload(icmpRequest);
@@ -213,11 +237,11 @@
         Ethernet icmpResponseEth = new Ethernet();
 
         icmpResponseEth.setEtherType(Ethernet.TYPE_IPV4)
-                .setSourceMACAddress(GATEWAY_MAC)
-                .setDestinationMACAddress(openstackPortInfo.mac())
+                .setSourceMACAddress(Constants.GATEWAY_MAC)
+                .setDestinationMACAddress(host.mac())
                 .setPayload(icmpRequestIpv4);
 
-        sendResponsePacketToHost(icmpResponseEth, openstackPortInfo);
+        sendResponsePacketToHost(icmpResponseEth, host);
     }
 
     private void sendRequestPacketToExt(IPv4 icmpRequestIpv4, ICMP icmpRequest, DeviceId deviceId,
@@ -230,19 +254,27 @@
         Ethernet icmpRequestEth = new Ethernet();
 
         icmpRequestEth.setEtherType(Ethernet.TYPE_IPV4)
+                // TODO: Get the correct one - Scalable Gateway ...
+                .setSourceMACAddress(Constants.GW_EXT_INT_MAC)
+                .setDestinationMACAddress(Constants.PHY_ROUTER_MAC)
                 .setPayload(icmpRequestIpv4);
 
-        TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
+        // TODO: Return the correct gateway node
+        Optional<OpenstackNode> gwNode =  nodeService.nodes().stream()
+                .filter(n -> n.type().equals(OpenstackNodeService.NodeType.GATEWAY))
+                .findFirst();
 
-        Map<DeviceId, PortNumber> externalInforMap = getExternalInfo();
-
-        if (externalInforMap.size() == 0 || !externalInforMap.containsKey(deviceId)) {
-            log.error(EXTERNAL_NODE_NULL, deviceId.toString());
+        if (!gwNode.isPresent()) {
+            log.warn("No Gateway is defined.");
             return;
         }
-        tBuilder.setOutput(externalInforMap.get(deviceId));
 
-        TrafficTreatment treatment = tBuilder.build();
+        TrafficTreatment treatment = DefaultTrafficTreatment.builder()
+                // FIXME: please double check this.
+                .setOutput(getPortForAnnotationPortName(gwNode.get().intBridge(),
+                        // FIXME: please double check this.
+                        org.onosproject.openstacknode.Constants.PATCH_INTG_BRIDGE))
+                .build();
 
         OutboundPacket packet = new DefaultOutboundPacket(deviceId,
                 treatment, ByteBuffer.wrap(icmpRequestEth.serialize()));
@@ -251,59 +283,45 @@
     }
 
     private void processResponsePacketFromExternalToHost(IPv4 icmpResponseIpv4, ICMP icmpResponse,
-                                                         OpenstackPortInfo openstackPortInfo) {
+                                                         Host host) {
         icmpResponse.resetChecksum();
 
-        icmpResponseIpv4.setDestinationAddress(openstackPortInfo.ip().toInt())
+        Ip4Address ipAddress = host.ipAddresses().stream().findFirst().get().getIp4Address();
+        icmpResponseIpv4.setDestinationAddress(ipAddress.toInt())
                 .resetChecksum();
         icmpResponseIpv4.setPayload(icmpResponse);
 
         Ethernet icmpResponseEth = new Ethernet();
 
         icmpResponseEth.setEtherType(Ethernet.TYPE_IPV4)
-                .setSourceMACAddress(GATEWAY_MAC)
-                .setDestinationMACAddress(openstackPortInfo.mac())
+                .setSourceMACAddress(Constants.GATEWAY_MAC)
+                .setDestinationMACAddress(host.mac())
                 .setPayload(icmpResponseIpv4);
 
-        sendResponsePacketToHost(icmpResponseEth, openstackPortInfo);
+        sendResponsePacketToHost(icmpResponseEth, host);
     }
 
-    private void sendResponsePacketToHost(Ethernet icmpResponseEth, OpenstackPortInfo openstackPortInfo) {
-        Map.Entry<String, OpenstackPortInfo> entry = openstackSwitchingService.openstackPortInfo().entrySet().stream()
-                .filter(e -> e.getValue().mac().equals(openstackPortInfo.mac()))
-                .findAny().orElse(null);
-
-        if (entry == null) {
-            return;
-        }
+    private void sendResponsePacketToHost(Ethernet icmpResponseEth, Host host) {
 
         TrafficTreatment treatment = DefaultTrafficTreatment.builder()
-                .setOutput(getPortForAnnotationPortName(openstackPortInfo.deviceId(), entry.getKey()))
+                .setOutput(host.location().port())
                 .build();
 
-        OutboundPacket packet = new DefaultOutboundPacket(openstackPortInfo.deviceId(),
+        OutboundPacket packet = new DefaultOutboundPacket(host.location().deviceId(),
                 treatment, ByteBuffer.wrap(icmpResponseEth.serialize()));
 
         packetService.emit(packet);
     }
 
-    private OpenstackPortInfo getOpenstackPortInfo(Ip4Address sourceIp, MacAddress sourceMac) {
-        checkNotNull(openstackSwitchingService.openstackPortInfo(), "openstackportinfo collection can not be null");
-
-        return openstackSwitchingService.openstackPortInfo().values()
-                .stream().filter(p -> p.ip().equals(sourceIp) && p.mac().equals(sourceMac))
-                .findAny().orElse(null);
-    }
-
     private short getIcmpId(ICMP icmp) {
         return ByteBuffer.wrap(icmp.serialize(), 4, 2).getShort();
     }
 
-    private Ip4Address pNatIpForPort(OpenstackPortInfo openstackPortInfo) {
+    private Ip4Address pNatIpForPort(Host host) {
 
         OpenstackPort openstackPort = openstackService.ports().stream()
                 .filter(p -> p.deviceOwner().equals(NETWORK_ROUTER_INTERFACE) &&
-                        p.networkId().equals(openstackPortInfo.networkId()))
+                        p.networkId().equals(host.annotations().value(Constants.NETWORK_ID)))
                 .findAny().orElse(null);
 
         checkNotNull(openstackPort, "openstackPort can not be null");
diff --git a/apps/openstacknetworking/routing/src/main/java/org/onosproject/openstacknetworking/routing/OpenstackPnatHandler.java b/apps/openstacknetworking/routing/src/main/java/org/onosproject/openstacknetworking/routing/OpenstackPnatHandler.java
index 3f11e6c..ce33e9e 100644
--- a/apps/openstacknetworking/routing/src/main/java/org/onosproject/openstacknetworking/routing/OpenstackPnatHandler.java
+++ b/apps/openstacknetworking/routing/src/main/java/org/onosproject/openstacknetworking/routing/OpenstackPnatHandler.java
@@ -32,7 +32,6 @@
 import org.onosproject.openstackinterface.OpenstackInterfaceService;
 import org.onosproject.openstackinterface.OpenstackPort;
 import org.onosproject.openstackinterface.OpenstackRouter;
-import org.onosproject.openstacknetworking.OpenstackNetworkingConfig;
 import org.onosproject.scalablegateway.api.GatewayNode;
 import org.onosproject.scalablegateway.api.ScalableGatewayService;
 import org.slf4j.Logger;
@@ -52,25 +51,21 @@
     volatile PacketContext context;
     private final Logger log = LoggerFactory.getLogger(getClass());
 
-    protected PacketService packetService;
-
     private final OpenstackRoutingRulePopulator rulePopulator;
     private final int portNum;
     private final OpenstackPort openstackPort;
     private final Port port;
-    private OpenstackNetworkingConfig config;
 
     private static final String DEVICE_OWNER_ROUTER_INTERFACE = "network:router_interface";
     private static final String EXTERNAL_PORT_NULL = "There is no external port in this deviceId []";
 
     OpenstackPnatHandler(OpenstackRoutingRulePopulator rulePopulator, PacketContext context,
-                         int portNum, OpenstackPort openstackPort, Port port, OpenstackNetworkingConfig config) {
+                         int portNum, OpenstackPort openstackPort, Port port) {
         this.rulePopulator = checkNotNull(rulePopulator);
         this.context = checkNotNull(context);
         this.portNum = checkNotNull(portNum);
         this.openstackPort = checkNotNull(openstackPort);
         this.port = checkNotNull(port);
-        this.config = checkNotNull(config);
     }
 
     @Override
@@ -149,6 +144,7 @@
         iPacket.resetChecksum();
         iPacket.setParent(ethernet);
         ethernet.setPayload(iPacket);
+
         ScalableGatewayService gatewayService = getService(ScalableGatewayService.class);
         GatewayNode gatewayNode = gatewayService.getGatewayNode(deviceId);
         if (gatewayNode.getGatewayExternalInterfaceNames().size() == 0) {
@@ -159,7 +155,6 @@
 
         ethernet.resetChecksum();
 
-
         packetService.emit(new DefaultOutboundPacket(deviceId, treatment.build(),
                 ByteBuffer.wrap(ethernet.serialize())));
     }
diff --git a/apps/openstacknetworking/routing/src/main/java/org/onosproject/openstacknetworking/routing/OpenstackRoutingArpHandler.java b/apps/openstacknetworking/routing/src/main/java/org/onosproject/openstacknetworking/routing/OpenstackRoutingArpHandler.java
index 9e23b5d..2c9a304 100644
--- a/apps/openstacknetworking/routing/src/main/java/org/onosproject/openstacknetworking/routing/OpenstackRoutingArpHandler.java
+++ b/apps/openstacknetworking/routing/src/main/java/org/onosproject/openstacknetworking/routing/OpenstackRoutingArpHandler.java
@@ -34,8 +34,9 @@
 import org.onosproject.net.packet.PacketService;
 import org.onosproject.openstackinterface.OpenstackInterfaceService;
 import org.onosproject.openstackinterface.OpenstackPort;
-import org.onosproject.openstacknetworking.OpenstackNetworkingConfig;
 import org.onosproject.scalablegateway.api.ScalableGatewayService;
+import org.onosproject.openstacknetworking.Constants;
+import org.onosproject.openstacknode.OpenstackNodeService;
 import org.slf4j.Logger;
 
 import java.nio.ByteBuffer;
@@ -53,23 +54,24 @@
 
     private final PacketService packetService;
     private final OpenstackInterfaceService openstackService;
-    private final OpenstackNetworkingConfig config;
     private final ScalableGatewayService gatewayService;
+    private final OpenstackNodeService nodeService;
     private static final String NETWORK_ROUTER_GATEWAY = "network:router_gateway";
     private static final String NETWORK_FLOATING_IP = "network:floatingip";
 
     /**
      * Default constructor.
-     *  @param packetService packet service
+     *
+     * @param packetService packet service
      * @param openstackService openstackInterface service
-     * @param config openstackRoutingConfig
-     * @param gatewayService
+     * @param gatewayService gateway service
+     * @param nodeService openstackNodeService
      */
     OpenstackRoutingArpHandler(PacketService packetService, OpenstackInterfaceService openstackService,
-                               OpenstackNetworkingConfig config, ScalableGatewayService gatewayService) {
+                               OpenstackNodeService nodeService, ScalableGatewayService gatewayService) {
         this.packetService = packetService;
         this.openstackService = checkNotNull(openstackService);
-        this.config = checkNotNull(config);
+        this.nodeService = nodeService;
         this.gatewayService = gatewayService;
     }
 
@@ -118,7 +120,8 @@
         if (getTargetMacForTargetIp(targetIp.getIp4Address()) == MacAddress.NONE) {
                 return;
         }
-        MacAddress targetMac = MacAddress.valueOf(config.gatewayExternalInterfaceMac());
+        // FIXME: Set the correct gateway
+        MacAddress targetMac = Constants.GW_EXT_INT_MAC;
 
         Ethernet ethReply = ARP.buildArpReply(targetIp.getIp4Address(),
                 targetMac, ethernet);
diff --git a/apps/openstacknetworking/routing/src/main/java/org/onosproject/openstacknetworking/routing/OpenstackRoutingManager.java b/apps/openstacknetworking/routing/src/main/java/org/onosproject/openstacknetworking/routing/OpenstackRoutingManager.java
index 6da1523..1e0b9fd 100644
--- a/apps/openstacknetworking/routing/src/main/java/org/onosproject/openstacknetworking/routing/OpenstackRoutingManager.java
+++ b/apps/openstacknetworking/routing/src/main/java/org/onosproject/openstacknetworking/routing/OpenstackRoutingManager.java
@@ -16,6 +16,7 @@
 package org.onosproject.openstacknetworking.routing;
 
 import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
 import org.apache.felix.scr.annotations.Activate;
 import org.apache.felix.scr.annotations.Component;
 import org.apache.felix.scr.annotations.Deactivate;
@@ -25,38 +26,47 @@
 import org.onlab.packet.Ethernet;
 import org.onlab.packet.IPv4;
 import org.onlab.packet.Ip4Address;
+import org.onlab.packet.IpAddress;
 import org.onlab.packet.MacAddress;
 import org.onlab.packet.UDP;
 import org.onlab.util.KryoNamespace;
 import org.onosproject.core.ApplicationId;
 import org.onosproject.core.CoreService;
+import org.onosproject.mastership.MastershipService;
+import org.onosproject.net.DefaultAnnotations;
 import org.onosproject.net.DeviceId;
+import org.onosproject.net.Host;
 import org.onosproject.net.Port;
-import org.onosproject.net.config.ConfigFactory;
-import org.onosproject.net.config.NetworkConfigEvent;
-import org.onosproject.net.config.NetworkConfigListener;
-import org.onosproject.net.config.NetworkConfigRegistry;
-import org.onosproject.net.config.NetworkConfigService;
-import org.onosproject.net.device.DeviceEvent;
-import org.onosproject.net.device.DeviceListener;
 import org.onosproject.net.device.DeviceService;
 import org.onosproject.net.driver.DriverService;
 import org.onosproject.net.flowobjective.FlowObjectiveService;
+import org.onosproject.net.host.DefaultHostDescription;
+import org.onosproject.net.host.HostDescription;
+import org.onosproject.net.host.HostEvent;
+import org.onosproject.net.host.HostListener;
+import org.onosproject.net.host.HostProvider;
+import org.onosproject.net.host.HostProviderRegistry;
+import org.onosproject.net.host.HostProviderService;
+import org.onosproject.net.host.HostService;
 import org.onosproject.net.packet.InboundPacket;
 import org.onosproject.net.packet.PacketContext;
 import org.onosproject.net.packet.PacketProcessor;
 import org.onosproject.net.packet.PacketService;
+import org.onosproject.net.provider.AbstractProvider;
+import org.onosproject.net.provider.ProviderId;
 import org.onosproject.openstackinterface.OpenstackFloatingIP;
 import org.onosproject.openstackinterface.OpenstackInterfaceService;
 import org.onosproject.openstackinterface.OpenstackPort;
 import org.onosproject.openstackinterface.OpenstackRouter;
 import org.onosproject.openstackinterface.OpenstackRouterInterface;
-import org.onosproject.openstacknetworking.OpenstackNetworkingConfig;
-import org.onosproject.openstacknetworking.OpenstackPortInfo;
 import org.onosproject.openstacknetworking.OpenstackRoutingService;
-import org.onosproject.openstacknetworking.OpenstackSubjectFactories;
-import org.onosproject.openstacknetworking.OpenstackSwitchingService;
 import org.onosproject.scalablegateway.api.ScalableGatewayService;
+import org.onosproject.openstacknetworking.routing.OpenstackFloatingIPHandler.Action;
+import org.onosproject.openstacknetworking.Constants;
+import org.onosproject.openstacknode.OpenstackNode;
+import org.onosproject.openstacknode.OpenstackNodeEvent;
+import org.onosproject.openstacknode.OpenstackNodeListener;
+import org.onosproject.openstacknode.OpenstackNodeService;
 import org.onosproject.store.serializers.KryoNamespaces;
 import org.onosproject.store.service.ConsistentMap;
 import org.onosproject.store.service.Serializer;
@@ -66,8 +76,8 @@
 
 import java.util.Collection;
 import java.util.List;
-import java.util.Map;
 import java.util.Optional;
+import java.util.Set;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 import java.util.stream.Collectors;
@@ -97,31 +107,35 @@
     protected OpenstackInterfaceService openstackService;
 
     @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
-    protected OpenstackSwitchingService openstackSwitchingService;
-
-    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
     protected FlowObjectiveService flowObjectiveService;
 
     @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
     protected DriverService driverService;
 
     @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
-    protected NetworkConfigService configService;
-
-    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
-    protected NetworkConfigRegistry configRegistry;
-
-    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
     protected StorageService storageService;
 
     @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected HostService hostService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected HostProviderRegistry hostProviderRegistry;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
     protected ScalableGatewayService gatewayService;
 
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected OpenstackNodeService nodeService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected MastershipService mastershipService;
+
     private ApplicationId appId;
     private ConsistentMap<Integer, String> tpPortNumMap; // Map<PortNum, allocated VM`s Mac & destionation Ip address>
     private ConsistentMap<String, OpenstackFloatingIP> floatingIpMap; // Map<FloatingIp`s Id, FloatingIp object>
     // Map<RouterInterface`s portId, Corresponded port`s network id>
     private ConsistentMap<String, String> routerInterfaceMap;
+    private static final ProviderId PID = new ProviderId("of", "org.onosproject.openstackroutering", true);
     private static final String APP_ID = "org.onosproject.openstackrouting";
     private static final String PORT_NAME = "portName";
     private static final String PORTNAME_PREFIX_VM = "tap";
@@ -134,18 +148,6 @@
     private static final int TP_PORT_MINIMUM_NUM = 1024;
     private static final int TP_PORT_MAXIMUM_NUM = 65535;
 
-    private final ConfigFactory configFactory =
-            new ConfigFactory(OpenstackSubjectFactories.USER_DEFINED_SUBJECT_FACTORY, OpenstackNetworkingConfig.class,
-                    "config") {
-                @Override
-                public OpenstackNetworkingConfig createConfig() {
-                    return new OpenstackNetworkingConfig();
-                }
-            };
-
-    private final NetworkConfigListener configListener = new InternalConfigListener();
-
-    private OpenstackNetworkingConfig config;
     private static final KryoNamespace.Builder FLOATING_IP_SERIALIZER = KryoNamespace.newBuilder()
             .register(KryoNamespaces.API)
             .register(OpenstackFloatingIP.FloatingIpStatus.class)
@@ -158,7 +160,8 @@
             .register(KryoNamespaces.API);
 
     private InternalPacketProcessor internalPacketProcessor = new InternalPacketProcessor();
-    private InternalDeviceListener internalDeviceListener = new InternalDeviceListener();
+    private InternalHostListener internalHostListener = new InternalHostListener();
+    private InternalOpenstackNodeListener internalNodeListener = new InternalOpenstackNodeListener();
     private ExecutorService l3EventExecutorService =
             Executors.newSingleThreadExecutor(groupedThreads("onos/openstackrouting", "L3-event"));
     private ExecutorService icmpEventExecutorService =
@@ -168,15 +171,16 @@
     private OpenstackIcmpHandler openstackIcmpHandler;
     private OpenstackRoutingArpHandler openstackArpHandler;
     private OpenstackRoutingRulePopulator rulePopulator;
-    private Map<DeviceId, Ip4Address> computeNodeMap;
+
+    private HostProviderService hostProviderService;
+    private final HostProvider hostProvider = new InternalHostProvider();
 
     @Activate
     protected void activate() {
         appId = coreService.registerApplication(APP_ID);
-        packetService.addProcessor(internalPacketProcessor, PacketProcessor.director(1));
-        configRegistry.registerConfigFactory(configFactory);
-        configService.addListener(configListener);
-        deviceService.addListener(internalDeviceListener);
+        hostService.addListener(internalHostListener);
+        nodeService.addListener(internalNodeListener);
+        hostProviderService = hostProviderRegistry.register(hostProvider);
 
         floatingIpMap = storageService.<String, OpenstackFloatingIP>consistentMapBuilder()
                 .withSerializer(Serializer.using(FLOATING_IP_SERIALIZER.build()))
@@ -194,15 +198,15 @@
                 .withApplicationId(appId)
                 .build();
 
-        readConfiguration();
-
         log.info("started");
     }
 
     @Deactivate
     protected void deactivate() {
         packetService.removeProcessor(internalPacketProcessor);
-        deviceService.removeListener(internalDeviceListener);
+        hostService.removeListener(internalHostListener);
+        nodeService.removeListener(internalNodeListener);
+
         l3EventExecutorService.shutdown();
         icmpEventExecutorService.shutdown();
         arpEventExecutorService.shutdown();
@@ -228,20 +232,27 @@
         }
         if (openstackFloatingIp.portId() == null || openstackFloatingIp.portId().equals("null")) {
             OpenstackFloatingIP floatingIp = floatingIpMap.get(openstackFloatingIp.id()).value();
-            OpenstackPortInfo portInfo = openstackSwitchingService.openstackPortInfo()
-                    .get(PORTNAME_PREFIX_VM.concat(floatingIp.portId().substring(0, 11)));
-            if (portInfo == null) {
-                log.warn("There`s no portInfo information about portId {}", floatingIp.portId());
+            // XXX When the VM has been removed, host information has been removed or not ???
+            Optional<Host> host = hostService.getHostsByIp(openstackFloatingIp.fixedIpAddress().getIp4Address())
+                    .stream()
+                    .findFirst();
+            if (!host.isPresent()) {
+                log.warn("No Host info with the VM IP the Floating IP address {} is found",
+                        openstackFloatingIp.floatingIpAddress());
                 return;
             }
             l3EventExecutorService.execute(
-                    new OpenstackFloatingIPHandler(rulePopulator, floatingIp, false, portInfo));
+                    new OpenstackFloatingIPHandler(rulePopulator, floatingIp, Action.DISSASSOCIATE, host.get()));
             floatingIpMap.replace(floatingIp.id(), openstackFloatingIp);
+            registerFloatingIpToHostService(openstackFloatingIp, Action.DISSASSOCIATE);
         } else {
             floatingIpMap.put(openstackFloatingIp.id(), openstackFloatingIp);
             l3EventExecutorService.execute(
-                    new OpenstackFloatingIPHandler(rulePopulator, openstackFloatingIp, true, null));
+                    new OpenstackFloatingIPHandler(rulePopulator, openstackFloatingIp, Action.ASSOCIATE, null));
+            registerFloatingIpToHostService(openstackFloatingIp, Action.ASSOCIATE);
         }
+
+
     }
 
     @Override
@@ -356,6 +367,10 @@
 
     private void removeL3RulesForRouterInterface(OpenstackRouterInterface routerInterface, OpenstackRouter router,
                                                  List<OpenstackRouterInterface> newList) {
+        if (!routerInterfaceMap.containsKey(routerInterface.portId())) {
+            log.warn("No router interface information found for {}", routerInterface.portId());
+            return;
+        }
         openstackService.ports(routerInterfaceMap.get(routerInterface.portId()).value()).forEach(p -> {
                     Ip4Address vmIp = (Ip4Address) p.fixedIps().values().toArray()[0];
                     if (newList == null) {
@@ -368,6 +383,7 @@
         );
     }
 
+    /*
     @Override
     public void checkDisassociatedFloatingIp(String portId, OpenstackPortInfo portInfo) {
         if (floatingIpMap.size() < 1) {
@@ -393,6 +409,7 @@
             log.warn("portInfo is null as timing issue between ovs port update event and openstack deletePort event");
         }
     }
+    */
 
     @Override
     public String networkIdForRouterInterface(String portId) {
@@ -445,6 +462,11 @@
         @Override
         public void process(PacketContext context) {
 
+            DeviceId senderDeviceId = context.inPacket().receivedFrom().deviceId();
+            if (!nodeService.routerBridge(senderDeviceId).isPresent()) {
+                log.warn("No router bridge for {} is found.", senderDeviceId);
+                return;
+            }
             if (context.isHandled()) {
                 return;
             } else if (!checkGatewayNode(context.inPacket().receivedFrom().deviceId())) {
@@ -482,7 +504,8 @@
                             OpenstackPort openstackPort = getOpenstackPort(ethernet.getSourceMAC(),
                                     Ip4Address.valueOf(iPacket.getSourceAddress()));
                             l3EventExecutorService.execute(new OpenstackPnatHandler(rulePopulator, context,
-                                    portNum, openstackPort, port, config));
+                                    portNum, openstackPort, port));
+
                         } else {
                             log.warn("There`s no external interface");
                         }
@@ -602,75 +625,166 @@
         return null;
     }
 
-    private void readConfiguration() {
-        config = configService.getConfig("openstacknetworking", OpenstackNetworkingConfig.class);
-        if (config == null) {
-            log.error("No configuration found");
+    private Optional<OpenstackPort> getRouterInterfacePort(String networkId) {
+
+        return openstackService.ports()
+                .stream()
+                .filter(p -> p.deviceOwner().equals(DEVICE_OWNER_ROUTER_INTERFACE)
+                        && p.networkId().equals(networkId))
+                .findAny();
+    }
+
+    // TODO: Remove the function and the related codes when vRouter is running on different ONOS instance.
+    private void registerFloatingIpToHostService(OpenstackFloatingIP openstackFloatingIp, Action action) {
+
+        Optional<Host> hostOptional = hostService.getHostsByIp(openstackFloatingIp.fixedIpAddress())
+                .stream()
+                .findFirst();
+        if (!hostOptional.isPresent()) {
+            log.warn("No host with IP {} is registered and cannot add the floating IP. ",
+                    openstackFloatingIp.floatingIpAddress());
             return;
         }
 
-        rulePopulator = new OpenstackRoutingRulePopulator(appId, openstackService, flowObjectiveService,
-                deviceService, driverService, config, gatewayService);
-        openstackIcmpHandler = new OpenstackIcmpHandler(packetService, deviceService,
-                openstackService, config, openstackSwitchingService, gatewayService);
-        openstackArpHandler = new OpenstackRoutingArpHandler(packetService, openstackService,
-                config, gatewayService);
-        openstackIcmpHandler.requestPacket(appId);
-        openstackArpHandler.requestPacket(appId);
+        Host host = hostOptional.get();
+        Set<IpAddress> ipAddresses = Sets.newHashSet();
+        if (action == Action.ASSOCIATE) {
+            ipAddresses.add(openstackFloatingIp.floatingIpAddress());
+        }
 
-        openstackService.floatingIps().stream()
-                .forEach(f -> floatingIpMap.put(f.id(), f));
+        HostDescription hostDescription =
+                new DefaultHostDescription(host.mac(), host.vlan(), host.location(), ipAddresses,
+                        (DefaultAnnotations) host.annotations());
 
-        reloadInitL3Rules();
-
-        log.info("OpenstackRouting configured");
+        hostProviderService.hostDetected(host.id(), hostDescription, false);
     }
 
-    private class InternalConfigListener implements NetworkConfigListener {
+    private class InternalHostListener implements HostListener {
 
-        @Override
-        public void event(NetworkConfigEvent event) {
-            if (!event.configClass().equals(OpenstackNetworkingConfig.class)) {
+        private void hostDetected(Host host) {
+
+            String portId = host.annotations().value(Constants.PORT_ID);
+            OpenstackPort openstackPort = openstackService.port(portId);
+            if (openstackPort == null) {
+                log.warn("No OpenstackPort information found from OpenStack for port ID {}", portId);
                 return;
             }
 
-            if (event.type().equals(NetworkConfigEvent.Type.CONFIG_ADDED) ||
-                    event.type().equals(NetworkConfigEvent.Type.CONFIG_UPDATED)) {
-                l3EventExecutorService.execute(OpenstackRoutingManager.this::readConfiguration);
+            Optional<OpenstackPort> routerPort = getRouterInterfacePort(openstackPort.networkId());
+            if (routerPort.isPresent()) {
+                OpenstackRouterInterface routerInterface = portToRouterInterface(routerPort.get());
+                l3EventExecutorService.execute(() ->
+                        setL3Connection(getOpenstackRouter(routerInterface.id()), openstackPort));
+
+            }
+        }
+
+        private void hostRemoved(Host host) {
+            String portId = host.annotations().value(Constants.PORT_ID);
+            OpenstackPort openstackPort = openstackService.port(portId);
+            if (openstackPort == null) {
+                log.warn("No OpenstackPort information found from OpenStack for port ID {}", portId);
+                return;
+            }
+
+            Optional<OpenstackPort> routerPort = getRouterInterfacePort(openstackPort.networkId());
+            if (routerPort.isPresent()) {
+                OpenstackRouterInterface routerInterface = portToRouterInterface(routerPort.get());
+                IpAddress ipAddress = host.ipAddresses().stream().findFirst().get();
+                l3EventExecutorService.execute(() -> rulePopulator.removeL3Rules(ipAddress.getIp4Address(),
+                        getL3ConnectionList(host.annotations().value(Constants.NETWORK_ID),
+                                getOpenstackRouterInterface(getOpenstackRouter(routerInterface.id())))));
+            }
+        }
+
+        private boolean isValidHost(Host host) {
+            return !host.ipAddresses().isEmpty() &&
+                    host.annotations().value(Constants.VXLAN_ID) != null &&
+                    host.annotations().value(Constants.NETWORK_ID) != null &&
+                    host.annotations().value(Constants.TENANT_ID) != null &&
+                    host.annotations().value(Constants.PORT_ID) != null;
+        }
+
+        @Override
+        public void event(HostEvent event) {
+            Host host = event.subject();
+            if (!mastershipService.isLocalMaster(host.location().deviceId())) {
+                // do not allow to proceed without mastership
+                return;
+            }
+
+            if (!isValidHost(host)) {
+                log.debug("Invalid host event, ignore it {}", host);
+                return;
+            }
+
+            switch (event.type()) {
+                case HOST_UPDATED:
+                case HOST_ADDED:
+                    l3EventExecutorService.execute(() -> hostDetected(host));
+                    break;
+                case HOST_REMOVED:
+                    l3EventExecutorService.execute(() -> hostRemoved(host));
+                    break;
+                default:
+                    break;
             }
         }
     }
 
-    private class InternalDeviceListener implements DeviceListener {
+    private class InternalOpenstackNodeListener implements OpenstackNodeListener {
+
+        private void nodeComplete() {
+
+            rulePopulator = new OpenstackRoutingRulePopulator(appId, openstackService, flowObjectiveService,
+                    deviceService, driverService, nodeService, gatewayService);
+            openstackIcmpHandler = new OpenstackIcmpHandler(packetService, deviceService, hostService,
+                    openstackService, nodeService, gatewayService);
+            openstackArpHandler = new OpenstackRoutingArpHandler(packetService, openstackService, nodeService,
+                    gatewayService);
+
+            // Packet handlers must be started AFTER all initialization processes.
+            packetService.addProcessor(internalPacketProcessor, PacketProcessor.director(1));
+
+            openstackIcmpHandler.requestPacket(appId);
+            openstackArpHandler.requestPacket(appId);
+
+            openstackService.floatingIps().stream()
+                    .forEach(f -> floatingIpMap.put(f.id(), f));
+
+            reloadInitL3Rules();
+        }
 
         @Override
-        public void event(DeviceEvent deviceEvent) {
-            if (deviceEvent.type() == DeviceEvent.Type.PORT_UPDATED) {
-                Port port = deviceEvent.port();
-                OpenstackPortInfo portInfo = openstackSwitchingService.openstackPortInfo()
-                        .get(port.annotations().value(PORT_NAME));
-                OpenstackPort openstackPort = openstackService.port(port);
-                OpenstackPort interfacePort = openstackService.ports()
-                        .stream()
-                        .filter(p -> p.deviceOwner().equals(DEVICE_OWNER_ROUTER_INTERFACE)
-                                && p.networkId().equals(openstackPort.networkId()))
-                        .findAny()
-                        .orElse(null);
-                if (portInfo == null && openstackPort == null) {
-                    log.warn("As delete event timing issue between routing and switching, Can`t delete L3 rules");
-                    return;
-                }
-                if ((port.isEnabled()) && (interfacePort != null)) {
-                    OpenstackRouterInterface routerInterface = portToRouterInterface(interfacePort);
-                    l3EventExecutorService.execute(() ->
-                            setL3Connection(getOpenstackRouter(routerInterface.id()), openstackPort));
-                } else if (interfacePort != null) {
-                    OpenstackRouterInterface routerInterface = portToRouterInterface(interfacePort);
-                    l3EventExecutorService.execute(() -> rulePopulator.removeL3Rules(portInfo.ip(),
-                            getL3ConnectionList(portInfo.networkId(),
-                                    getOpenstackRouterInterface(getOpenstackRouter(routerInterface.id())))));
-                }
+        public void event(OpenstackNodeEvent event) {
+            OpenstackNode node = event.node();
+
+            switch (event.type()) {
+                case COMPLETE:
+                    log.info("COMPLETE node {} detected", node.hostname());
+                    l3EventExecutorService.execute(() -> nodeComplete());
+                    break;
+                case INCOMPLETE:
+                    break;
+                default:
+                    break;
             }
+
+        }
+    }
+
+    private class InternalHostProvider extends AbstractProvider implements HostProvider {
+
+        /**
+         * Creates a provider with the supplier identifier.
+         */
+        protected InternalHostProvider() {
+            super(PID);
+        }
+
+        @Override
+        public void triggerProbe(Host host) {
+            // nothing to do
         }
     }
 
diff --git a/apps/openstacknetworking/routing/src/main/java/org/onosproject/openstacknetworking/routing/OpenstackRoutingRulePopulator.java b/apps/openstacknetworking/routing/src/main/java/org/onosproject/openstacknetworking/routing/OpenstackRoutingRulePopulator.java
index 57444d0..e448241 100644
--- a/apps/openstacknetworking/routing/src/main/java/org/onosproject/openstacknetworking/routing/OpenstackRoutingRulePopulator.java
+++ b/apps/openstacknetworking/routing/src/main/java/org/onosproject/openstacknetworking/routing/OpenstackRoutingRulePopulator.java
@@ -29,6 +29,7 @@
 import org.onosproject.core.GroupId;
 import org.onosproject.net.Device;
 import org.onosproject.net.DeviceId;
+import org.onosproject.net.Host;
 import org.onosproject.net.Port;
 import org.onosproject.net.PortNumber;
 import org.onosproject.net.behaviour.ExtensionTreatmentResolver;
@@ -54,14 +55,16 @@
 import org.onosproject.openstackinterface.OpenstackRouterInterface;
 import org.onosproject.openstackinterface.OpenstackSubnet;
 import org.onosproject.openstackinterface.OpenstackFloatingIP;
-import org.onosproject.openstacknetworking.OpenstackNetworkingConfig;
-import org.onosproject.openstacknetworking.OpenstackPortInfo;
+import org.onosproject.openstacknetworking.Constants;
 import org.onosproject.openstacknetworking.OpenstackRoutingService;
 import org.onosproject.scalablegateway.api.ScalableGatewayService;
+import org.onosproject.openstacknode.OpenstackNode;
+import org.onosproject.openstacknode.OpenstackNodeService;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import java.util.List;
+import java.util.Optional;
 import java.util.stream.StreamSupport;
 
 import static com.google.common.base.Preconditions.checkNotNull;
@@ -79,8 +82,8 @@
     private final OpenstackInterfaceService openstackService;
     private final DeviceService deviceService;
     private final DriverService driverService;
-    private final OpenstackNetworkingConfig config;
     private final ScalableGatewayService gatewayService;
+    private final OpenstackNodeService nodeService;
 
     private static final String PORTNAME_PREFIX_TUNNEL = "vxlan";
     private static final String PORTNAME = "portName";
@@ -95,7 +98,6 @@
     private static final int PNAT_RULE_PRIORITY = 26000;
     private static final int PNAT_TIMEOUT = 120;
     private static final int PREFIX_LENGTH = 32;
-    private static final MacAddress GATEWAYMAC = MacAddress.valueOf("1f:1f:1f:1f:1f:1f");
 
     private InboundPacket inboundPacket;
     private OpenstackPort openstackPort;
@@ -111,20 +113,22 @@
      * @param flowObjectiveService FlowObjectiveService
      * @param deviceService DeviceService
      * @param driverService DriverService
-     * @param config Configuration for openstack environment
      * @param gatewayService scalable gateway service
      */
-    public OpenstackRoutingRulePopulator(ApplicationId appId, OpenstackInterfaceService openstackService,
-                                         FlowObjectiveService flowObjectiveService, DeviceService deviceService,
-                                         DriverService driverService, OpenstackNetworkingConfig config,
+    public OpenstackRoutingRulePopulator(ApplicationId appId,
+                                         OpenstackInterfaceService openstackService,
+                                         FlowObjectiveService flowObjectiveService,
+                                         DeviceService deviceService,
+                                         DriverService driverService,
+                                         OpenstackNodeService nodeService,
                                          ScalableGatewayService gatewayService) {
         this.appId = appId;
         this.flowObjectiveService = flowObjectiveService;
         this.openstackService = checkNotNull(openstackService);
         this.deviceService = deviceService;
         this.driverService = driverService;
-        this.config = config;
         this.gatewayService = gatewayService;
+        this.nodeService = nodeService;
     }
 
     /**
@@ -201,7 +205,8 @@
 
     private Port getPortOfExternalInterface() {
         return deviceService.getPorts(getGatewayNode().id()).stream()
-                .filter(p -> p.annotations().value(PORTNAME).equals(config.gatewayExternalInterfaceName()))
+                .filter(p -> p.annotations().value(PORTNAME)
+                        .equals(org.onosproject.openstacknode.Constants.PATCH_INTG_BRIDGE))
                 .findAny().orElse(null);
     }
 
@@ -239,7 +244,8 @@
 
         getGatewayNodeList().forEach(node -> {
             DeviceId deviceId = node.id();
-            tBuilder.extension(buildNiciraExtenstion(deviceId, getHostIpfromOpenstackPort(openstackPort)), deviceId)
+            tBuilder.extension(buildNiciraExtenstion(deviceId,
+                    getHostIpfromOpenstackPort(openstackPort).getIp4Address()), deviceId)
                     .setOutput(getTunnelPort(deviceId));
 
             ForwardingObjective fo = DefaultForwardingObjective.builder()
@@ -262,9 +268,16 @@
         return devices;
     }
 
-    private Ip4Address getHostIpfromOpenstackPort(OpenstackPort openstackPort) {
+    private IpAddress getHostIpfromOpenstackPort(OpenstackPort openstackPort) {
         Device device = getDevicefromOpenstackPort(openstackPort);
-        return config.nodes().get(device.id());
+
+        Optional<IpAddress> ipAddress = nodeService.dataIp(device.id());
+        if (!ipAddress.isPresent()) {
+            log.warn("No IP address found for device {}", device.id());
+            return null;
+        }
+
+        return ipAddress.get();
     }
 
     private Device getDevicefromOpenstackPort(OpenstackPort openstackPort) {
@@ -349,7 +362,7 @@
 
         sBuilder.matchEthType(Ethernet.TYPE_IPV4)
                 .matchTunnelId(vni)
-                .matchEthDst(GATEWAYMAC);
+                .matchEthDst(Constants.GATEWAY_MAC);
         tBuilder.setOutput(PortNumber.CONTROLLER);
 
         ForwardingObjective fo = DefaultForwardingObjective.builder()
@@ -365,7 +378,7 @@
 
     private void populateComputeNodeRules(long vni) {
         StreamSupport.stream(deviceService.getDevices().spliterator(), false)
-                .filter(d -> !checkGatewayNode(d.id()))
+                .filter(d -> isTypeOf(d.id(), OpenstackNodeService.NodeType.COMPUTE))
                 .forEach(d -> populateRuleToGatewayBySgw(d.id(),
                         gatewayService.getGroupIdForGatewayLoadBalance(d.id()), vni));
     }
@@ -376,7 +389,8 @@
 
         sBuilder.matchEthType(Ethernet.TYPE_IPV4)
                 .matchTunnelId(vni)
-                .matchEthDst(GATEWAYMAC);
+                .matchEthDst(Constants.GATEWAY_MAC);
+
         tBuilder.group(groupId);
 
         ForwardingObjective fo = DefaultForwardingObjective.builder()
@@ -390,14 +404,15 @@
         flowObjectiveService.forward(deviceId, fo);
     }
 
+    /*
     private void populateRuleToGateway(DeviceId deviceId, Device gatewayDevice, long vni) {
         TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder();
         TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
 
         sBuilder.matchEthType(Ethernet.TYPE_IPV4)
                 .matchTunnelId(vni)
-                .matchEthDst(GATEWAYMAC);
-        tBuilder.extension(buildNiciraExtenstion(deviceId, config.nodes().get(gatewayDevice.id())), deviceId)
+                .matchEthDst(Constants.GATEWAY_MAC);
+        tBuilder.extension(buildNiciraExtenstion(deviceId, nodeService.nodes().get(gatewayDevice.id())), deviceId)
                 .setOutput(getTunnelPort(deviceId));
 
         ForwardingObjective fo = DefaultForwardingObjective.builder()
@@ -410,13 +425,36 @@
 
         flowObjectiveService.forward(deviceId, fo);
     }
+    */
 
     private Device getGatewayNode() {
-        return checkNotNull(deviceService.getDevice(DeviceId.deviceId(config.gatewayBridgeId())));
+
+        // TODO Return the correct gateway node
+        Optional<OpenstackNode> gwNode =  nodeService.nodes().stream()
+                .filter(n -> n.type().equals(OpenstackNodeService.NodeType.GATEWAY))
+                .findFirst();
+
+        if (!gwNode.isPresent()) {
+            log.warn("No Gateway is defined.");
+            return null;
+        }
+
+        return deviceService.getDevice(gwNode.get().intBridge());
     }
 
-    private boolean checkGatewayNode(DeviceId deviceId) {
-        return gatewayService.getGatewayDeviceIds().stream().anyMatch(dId -> dId.equals(deviceId));
+    private boolean isTypeOf(DeviceId deviceId, OpenstackNodeService.NodeType type) {
+
+        Optional<OpenstackNode> node = nodeService.nodes().stream()
+                .filter(n -> n.intBridge().equals(deviceId) ||
+                        (n.routerBridge().isPresent() && n.routerBridge().get().equals(deviceId)))
+                .filter(n -> n.type().equals(type))
+                .findFirst();
+
+        if (node.isPresent()) {
+            return true;
+        }
+
+        return false;
     }
 
     private long getVni(String netId) {
@@ -433,11 +471,11 @@
         TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder();
         sBuilder.matchEthType(Ethernet.TYPE_IPV4)
                 .matchTunnelId(getVni(openstackSubnet.networkId()))
-                .matchEthDst(GATEWAYMAC);
+                .matchEthDst(Constants.GATEWAY_MAC);
 
         StreamSupport.stream(deviceService.getDevices().spliterator(), false)
                 .forEach(d -> {
-                    ForwardingObjective.Flag flag = checkGatewayNode(d.id()) ?
+                    ForwardingObjective.Flag flag = isTypeOf(d.id(), OpenstackNodeService.NodeType.GATEWAY) ?
                             ForwardingObjective.Flag.VERSATILE :
                             ForwardingObjective.Flag.SPECIFIC;
                     removeRule(d.id(), sBuilder, flag, ROUTING_RULE_PRIORITY);
@@ -474,33 +512,35 @@
     }
 
     private void populateFloatingIpIncomingRules(OpenstackFloatingIP floatingIP, OpenstackPort port) {
-        DeviceId portDeviceId = getDevicefromOpenstackPort(port).id();
-
         TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder();
         TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
 
         sBuilder.matchEthType(Ethernet.TYPE_IPV4)
                 .matchIPDst(IpPrefix.valueOf(floatingIP.floatingIpAddress(), PREFIX_LENGTH));
 
-        getGatewayNodeList().forEach(device -> {
-            DeviceId deviceId = device.id();
-            tBuilder.setEthSrc(GATEWAYMAC)
-                    .setEthDst(port.macAddress())
-                    .setIpDst(floatingIP.fixedIpAddress())
-                    .setTunnelId(getVni(port.networkId()))
-                    .extension(buildNiciraExtenstion(deviceId, config.nodes().get(portDeviceId)), deviceId)
-                    .setOutput(getTunnelPort(deviceId));
+        DeviceId gatewayDeviceId = DeviceId.deviceId(port.deviceId());
+        Optional<IpAddress> ipAddress = nodeService.dataIp(gatewayDeviceId);
+        if (!ipAddress.isPresent()) {
+            log.warn("No IP address found for device {}", port.deviceId());
+            return;
+        }
+        tBuilder.setEthSrc(Constants.GATEWAY_MAC)
+                .setEthDst(port.macAddress())
+                .setIpDst(floatingIP.fixedIpAddress())
+                .setTunnelId(getVni(port.networkId()))
+                .extension(buildNiciraExtenstion(gatewayDeviceId,
+                        ipAddress.get().getIp4Address()), gatewayDeviceId)
+                .setOutput(getTunnelPort(gatewayDeviceId));
 
-            ForwardingObjective fo = DefaultForwardingObjective.builder()
-                    .withSelector(sBuilder.build())
-                    .withTreatment(tBuilder.build())
-                    .withFlag(ForwardingObjective.Flag.VERSATILE)
-                    .withPriority(FLOATING_RULE_PRIORITY)
-                    .fromApp(appId)
-                    .add();
+        ForwardingObjective fo = DefaultForwardingObjective.builder()
+                .withSelector(sBuilder.build())
+                .withTreatment(tBuilder.build())
+                .withFlag(ForwardingObjective.Flag.VERSATILE)
+                .withPriority(FLOATING_RULE_PRIORITY)
+                .fromApp(appId)
+                .add();
 
-            flowObjectiveService.forward(deviceId, fo);
-        });
+        flowObjectiveService.forward(getGatewayNode().id(), fo);
     }
 
     private void populateFloatingIpOutgoingRules(OpenstackFloatingIP floatingIP, OpenstackPort port) {
@@ -514,6 +554,8 @@
         getGatewayNodeList().forEach(device -> {
             DeviceId deviceId = device.id();
             tBuilder.setIpSrc(floatingIP.floatingIpAddress())
+                    .setEthSrc(Constants.GW_EXT_INT_MAC)
+                    .setEthDst(Constants.PHY_ROUTER_MAC)
                     .setOutput(getExternalPortNum(deviceId));
 
             ForwardingObjective fo = DefaultForwardingObjective.builder()
@@ -535,19 +577,20 @@
     /**
      * Removes flow rules for floating ip configuration.
      *
-     * @param floatingIP Corresponding floating ip information
-     * @param portInfo stored information about deleted vm
+     * @param floatingIp Corresponding floating ip information
+     * @param host host information for vm to remove
      */
-    public void removeFloatingIpRules(OpenstackFloatingIP floatingIP, OpenstackPortInfo portInfo) {
+    public void removeFloatingIpRules(OpenstackFloatingIP floatingIp, Host host) {
         TrafficSelector.Builder sOutgoingBuilder = DefaultTrafficSelector.builder();
         TrafficSelector.Builder sIncomingBuilder = DefaultTrafficSelector.builder();
 
+        // XXX FloatingIp.tenant_id() == host.vxlan_id ???
         sOutgoingBuilder.matchEthType(Ethernet.TYPE_IPV4)
-                .matchTunnelId(portInfo.vni())
-                .matchIPSrc(IpPrefix.valueOf(portInfo.ip(), PREFIX_LENGTH));
+                .matchTunnelId(Integer.parseInt(host.annotations().value(Constants.VXLAN_ID)))
+                .matchIPSrc(IpPrefix.valueOf(floatingIp.fixedIpAddress(), PREFIX_LENGTH));
 
         sIncomingBuilder.matchEthType(Ethernet.TYPE_IPV4)
-                .matchIPDst(IpPrefix.valueOf(floatingIP.floatingIpAddress(), PREFIX_LENGTH));
+                .matchIPDst(IpPrefix.valueOf(floatingIp.floatingIpAddress(), PREFIX_LENGTH));
 
         getGatewayNodeList().forEach(device -> {
             removeRule(device.id(), sOutgoingBuilder, ForwardingObjective.Flag.VERSATILE, FLOATING_RULE_PRIORITY);
@@ -580,8 +623,9 @@
             populateL3RulestoSameNode(vmIp, openstackPort, port, device, vni);
 
             deviceService.getAvailableDevices().forEach(d -> {
-                if (!d.equals(device) && !checkGatewayNode(d.id())) {
-                    populateL3RulestoDifferentNode(vmIp, vni, d.id(), getHostIpfromOpenstackPort(openstackPort));
+                if (!d.equals(device) && !d.equals(getGatewayNode())) {
+                    populateL3RulestoDifferentNode(vmIp, vni, d.id(),
+                            getHostIpfromOpenstackPort(openstackPort).getIp4Address());
                 }
             });
 
@@ -654,7 +698,7 @@
         OpenstackRoutingService routingService = getService(OpenstackRoutingService.class);
 
         deviceService.getAvailableDevices().forEach(d -> {
-            if (!checkGatewayNode(d.id())) {
+            if (isTypeOf(d.id(), OpenstackNodeService.NodeType.COMPUTE)) {
                 routerInterfaces.forEach(routerInterface -> {
                     String networkId = routingService.networkIdForRouterInterface(routerInterface.portId());
                     long vni = getVni(networkId);
diff --git a/apps/openstacknetworking/switching/src/main/java/org/onosproject/openstacknetworking/switching/AbstractVmHandler.java b/apps/openstacknetworking/switching/src/main/java/org/onosproject/openstacknetworking/switching/AbstractVmHandler.java
index 9bf2baa..d7b7a8a 100644
--- a/apps/openstacknetworking/switching/src/main/java/org/onosproject/openstacknetworking/switching/AbstractVmHandler.java
+++ b/apps/openstacknetworking/switching/src/main/java/org/onosproject/openstacknetworking/switching/AbstractVmHandler.java
@@ -26,6 +26,7 @@
 import org.onosproject.net.host.HostEvent;
 import org.onosproject.net.host.HostListener;
 import org.onosproject.net.host.HostService;
+import org.onosproject.openstacknetworking.Constants;
 import org.slf4j.Logger;
 
 import java.util.Objects;
@@ -36,7 +37,7 @@
 
 import static java.util.concurrent.Executors.newSingleThreadScheduledExecutor;
 import static org.onlab.util.Tools.groupedThreads;
-import static org.onosproject.openstacknetworking.switching.Constants.*;
+import static org.onosproject.openstacknetworking.Constants.*;
 import static org.slf4j.LoggerFactory.getLogger;
 
 /**
diff --git a/apps/openstacknetworking/switching/src/main/java/org/onosproject/openstacknetworking/switching/OpenstackArpHandler.java b/apps/openstacknetworking/switching/src/main/java/org/onosproject/openstacknetworking/switching/OpenstackArpHandler.java
index c855403..c31bfd9 100644
--- a/apps/openstacknetworking/switching/src/main/java/org/onosproject/openstacknetworking/switching/OpenstackArpHandler.java
+++ b/apps/openstacknetworking/switching/src/main/java/org/onosproject/openstacknetworking/switching/OpenstackArpHandler.java
@@ -48,7 +48,7 @@
 import java.util.Set;
 
 import static com.google.common.base.Preconditions.checkNotNull;
-import static org.onosproject.openstacknetworking.switching.Constants.*;
+import static org.onosproject.openstacknetworking.Constants.*;
 
 /**
  * Handles ARP packet from VMs.
diff --git a/apps/openstacknetworking/switching/src/main/java/org/onosproject/openstacknetworking/switching/OpenstackSecurityGroupRulePopulator.java b/apps/openstacknetworking/switching/src/main/java/org/onosproject/openstacknetworking/switching/OpenstackSecurityGroupRulePopulator.java
index 7477404..b963988 100644
--- a/apps/openstacknetworking/switching/src/main/java/org/onosproject/openstacknetworking/switching/OpenstackSecurityGroupRulePopulator.java
+++ b/apps/openstacknetworking/switching/src/main/java/org/onosproject/openstacknetworking/switching/OpenstackSecurityGroupRulePopulator.java
@@ -50,7 +50,7 @@
 import java.util.Set;
 import java.util.stream.Collectors;
 
-import static org.onosproject.openstacknetworking.switching.Constants.*;
+import static org.onosproject.openstacknetworking.Constants.*;
 
 /**
  * Populates flows rules for Security Groups of VMs.
diff --git a/apps/openstacknetworking/switching/src/main/java/org/onosproject/openstacknetworking/switching/OpenstackSwitchingManager.java b/apps/openstacknetworking/switching/src/main/java/org/onosproject/openstacknetworking/switching/OpenstackSwitchingManager.java
index 5388e9b..55fce2c 100644
--- a/apps/openstacknetworking/switching/src/main/java/org/onosproject/openstacknetworking/switching/OpenstackSwitchingManager.java
+++ b/apps/openstacknetworking/switching/src/main/java/org/onosproject/openstacknetworking/switching/OpenstackSwitchingManager.java
@@ -16,7 +16,6 @@
 package org.onosproject.openstacknetworking.switching;
 
 import com.google.common.base.Strings;
-import com.google.common.collect.Maps;
 import com.google.common.collect.Sets;
 import org.apache.felix.scr.annotations.Activate;
 import org.apache.felix.scr.annotations.Component;
@@ -27,7 +26,6 @@
 import org.onlab.packet.Ip4Address;
 import org.onlab.packet.IpPrefix;
 import org.onlab.packet.VlanId;
-import org.onlab.util.Tools;
 import org.onosproject.core.CoreService;
 import org.onosproject.dhcp.DhcpService;
 import org.onosproject.dhcp.IpAssignment;
@@ -54,8 +52,6 @@
 import org.onosproject.openstackinterface.OpenstackNetwork;
 import org.onosproject.openstackinterface.OpenstackPort;
 import org.onosproject.openstackinterface.OpenstackSubnet;
-import org.onosproject.openstacknetworking.OpenstackPortInfo;
-import org.onosproject.openstacknetworking.OpenstackSwitchingService;
 import org.onosproject.openstacknode.OpenstackNode;
 import org.onosproject.openstacknode.OpenstackNodeEvent;
 import org.onosproject.openstacknode.OpenstackNodeListener;
@@ -64,7 +60,6 @@
 import org.slf4j.LoggerFactory;
 
 import java.util.Date;
-import java.util.Map;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 
@@ -74,7 +69,7 @@
 import static com.google.common.base.Preconditions.checkArgument;
 import static com.google.common.base.Preconditions.checkNotNull;
 import static org.onosproject.net.AnnotationKeys.PORT_NAME;
-import static org.onosproject.openstacknetworking.switching.Constants.*;
+import static org.onosproject.openstacknetworking.Constants.*;
 
 @Service
 @Component(immediate = true)
@@ -82,7 +77,7 @@
  * Populates forwarding rules for VMs created by Openstack.
  */
 public final class OpenstackSwitchingManager extends AbstractProvider
-        implements OpenstackSwitchingService, HostProvider {
+        implements HostProvider {
 
     private final Logger log = LoggerFactory.getLogger(getClass());
 
@@ -153,41 +148,6 @@
         // no probe is required
     }
 
-    @Override
-    // TODO remove this and openstackPortInfo
-    public Map<String, OpenstackPortInfo> openstackPortInfo() {
-        Map<String, OpenstackPortInfo> portInfoMap = Maps.newHashMap();
-
-        Tools.stream(hostService.getHosts()).filter(this::isValidHost).forEach(host -> {
-            Port port = deviceService.getPort(
-                    host.location().deviceId(),
-                    host.location().port());
-
-            OpenstackPortInfo portInfo = OpenstackPortInfo.builder()
-                    .setDeviceId(host.location().deviceId())
-                    .setHostMac(host.mac())
-                    .setNetworkId(host.annotations().value(NETWORK_ID))
-                    .setGatewayIP(Ip4Address.valueOf(host.annotations().value(GATEWAY_IP)))
-                    .setVni(Long.valueOf(host.annotations().value(VXLAN_ID)))
-                    .setHostIp(host.ipAddresses().stream().findFirst().get().getIp4Address())
-                    .build();
-
-            portInfoMap.put(port.annotations().value(PORT_NAME), portInfo);
-        });
-
-        return portInfoMap;
-    }
-
-    // TODO remove this and openstackPortInfo
-    private boolean isValidHost(Host host) {
-        return !host.ipAddresses().isEmpty() &&
-                host.annotations().value(VXLAN_ID) != null &&
-                host.annotations().value(NETWORK_ID) != null &&
-                host.annotations().value(TENANT_ID) != null &&
-                host.annotations().value(GATEWAY_IP) != null &&
-                host.annotations().value(PORT_ID) != null;
-    }
-
     private void processPortAdded(Port port) {
         // TODO check the node state is COMPLETE
         OpenstackPort osPort = openstackService.port(port);
diff --git a/apps/openstacknetworking/switching/src/main/java/org/onosproject/openstacknetworking/switching/OpenstackSwitchingRulePopulator.java b/apps/openstacknetworking/switching/src/main/java/org/onosproject/openstacknetworking/switching/OpenstackSwitchingRulePopulator.java
index 732be7d..b3707a8 100644
--- a/apps/openstacknetworking/switching/src/main/java/org/onosproject/openstacknetworking/switching/OpenstackSwitchingRulePopulator.java
+++ b/apps/openstacknetworking/switching/src/main/java/org/onosproject/openstacknetworking/switching/OpenstackSwitchingRulePopulator.java
@@ -47,7 +47,7 @@
 import java.util.Optional;
 
 import static org.onosproject.net.flow.instructions.ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_SET_TUNNEL_DST;
-import static org.onosproject.openstacknetworking.switching.Constants.*;
+import static org.onosproject.openstacknetworking.Constants.*;
 
 /**
  * Populates switching flow rules.
diff --git a/apps/scalablegateway/src/main/java/org/onosproject/scalablegateway/impl/ScalableGatewayManager.java b/apps/scalablegateway/src/main/java/org/onosproject/scalablegateway/impl/ScalableGatewayManager.java
index 8b75335..383684e 100644
--- a/apps/scalablegateway/src/main/java/org/onosproject/scalablegateway/impl/ScalableGatewayManager.java
+++ b/apps/scalablegateway/src/main/java/org/onosproject/scalablegateway/impl/ScalableGatewayManager.java
@@ -50,6 +50,7 @@
 import org.onosproject.scalablegateway.api.ScalableGatewayService;
 
 import java.util.List;
+import java.util.Optional;
 
 import org.onosproject.store.serializers.KryoNamespaces;
 import org.onosproject.store.service.ConsistentMap;
@@ -128,7 +129,6 @@
         deviceService.addListener(internalDeviceListener);
 
         selectGroupHandler = new SelectGroupHandler(groupService, deviceService, driverService, appId);
-        readConfiguration();
 
         gatewayNodeMap = storageService.<DeviceId, GatewayNode>consistentMapBuilder()
                 .withSerializer(Serializer.using(GATEWAYNODE_SERIALIZER.build()))
@@ -165,13 +165,17 @@
     }
 
     private PortNumber findPortNumFromPortName(DeviceId gatewayDeviceId, String name) {
-        Port port = deviceService.getPorts(gatewayDeviceId)
+        Optional<Port> port = deviceService.getPorts(gatewayDeviceId)
                 .stream()
                 .filter(p -> p.annotations().value(PORT_NAME).equals(name))
-                .iterator()
-                .next();
-        return checkNotNull(port, PORT_CAN_NOT_BE_NULL).number();
+                .findFirst();
 
+        if (!port.isPresent()) {
+            log.error("Cannot find port {} in gateway device {}", name, gatewayDeviceId);
+            return null;
+        }
+
+        return port.get().number();
     }
 
     @Override