diff --git a/src/main/java/org/onosproject/cordvtn/CordVtn.java b/src/main/java/org/onosproject/cordvtn/CordVtn.java
index e15bc76..c3bf77c 100644
--- a/src/main/java/org/onosproject/cordvtn/CordVtn.java
+++ b/src/main/java/org/onosproject/cordvtn/CordVtn.java
@@ -15,7 +15,6 @@
  */
 package org.onosproject.cordvtn;
 
-import com.google.common.collect.Collections2;
 import com.google.common.collect.Sets;
 import org.apache.felix.scr.annotations.Activate;
 import org.apache.felix.scr.annotations.Component;
@@ -32,6 +31,7 @@
 import org.onosproject.net.Device;
 import org.onosproject.net.DeviceId;
 import org.onosproject.net.Host;
+import org.onosproject.net.Port;
 import org.onosproject.net.behaviour.BridgeConfig;
 import org.onosproject.net.behaviour.BridgeName;
 import org.onosproject.net.behaviour.ControllerInfo;
@@ -39,6 +39,7 @@
 import org.onosproject.net.behaviour.TunnelConfig;
 import org.onosproject.net.behaviour.TunnelDescription;
 import org.onosproject.net.behaviour.TunnelName;
+import org.onosproject.net.device.DeviceAdminService;
 import org.onosproject.net.device.DeviceEvent;
 import org.onosproject.net.device.DeviceListener;
 import org.onosproject.net.device.DeviceService;
@@ -54,7 +55,6 @@
 import org.onosproject.store.service.ConsistentMap;
 import org.onosproject.store.service.Serializer;
 import org.onosproject.store.service.StorageService;
-import org.onosproject.store.service.Versioned;
 import org.slf4j.Logger;
 
 import java.util.ArrayList;
@@ -84,7 +84,8 @@
     private static final int NUM_THREADS = 1;
     private static final KryoNamespace.Builder NODE_SERIALIZER = KryoNamespace.newBuilder()
             .register(KryoNamespaces.API)
-            .register(DefaultOvsdbNode.class);
+            .register(CordVtnNode.class)
+            .register(NodeState.class);
     private static final String DEFAULT_BRIDGE_NAME = "br-int";
     private static final String DEFAULT_TUNNEL = "vxlan";
     private static final Map<String, String> DEFAULT_TUNNEL_OPTIONS = new HashMap<String, String>() {
@@ -112,6 +113,9 @@
     protected DriverService driverService;
 
     @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected DeviceAdminService adminService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
     protected OvsdbController controller;
 
     @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
@@ -127,12 +131,55 @@
     private final BridgeHandler bridgeHandler = new BridgeHandler();
     private final VmHandler vmHandler = new VmHandler();
 
-    private ConsistentMap<DeviceId, OvsdbNode> nodeStore;
+    private ConsistentMap<CordVtnNode, NodeState> nodeStore;
+
+    private enum NodeState {
+
+        INIT {
+            @Override
+            public void process(CordVtn cordVtn, CordVtnNode node) {
+                cordVtn.connect(node);
+            }
+        },
+        OVSDB_CONNECTED {
+            @Override
+            public void process(CordVtn cordVtn, CordVtnNode node) {
+                if (!cordVtn.getOvsdbConnectionState(node)) {
+                    cordVtn.connect(node);
+                } else {
+                    cordVtn.createIntegrationBridge(node);
+                }
+            }
+        },
+        BRIDGE_CREATED {
+            @Override
+            public void process(CordVtn cordVtn, CordVtnNode node) {
+                if (!cordVtn.getOvsdbConnectionState(node)) {
+                    cordVtn.connect(node);
+                } else {
+                    cordVtn.createTunnelInterface(node);
+                }
+            }
+        },
+        COMPLETE {
+            @Override
+            public void process(CordVtn cordVtn, CordVtnNode node) {
+                cordVtn.postInit(node);
+            }
+        },
+        INCOMPLETE {
+            @Override
+            public void process(CordVtn cordVtn, CordVtnNode node) {
+            }
+        };
+
+        public abstract void process(CordVtn cordVtn, CordVtnNode node);
+    }
 
     @Activate
     protected void activate() {
         ApplicationId appId = coreService.registerApplication("org.onosproject.cordvtn");
-        nodeStore = storageService.<DeviceId, OvsdbNode>consistentMapBuilder()
+        nodeStore = storageService.<CordVtnNode, NodeState>consistentMapBuilder()
                 .withSerializer(Serializer.using(NODE_SERIALIZER.build()))
                 .withName("cordvtn-nodestore")
                 .withApplicationId(appId)
@@ -156,79 +203,22 @@
     }
 
     @Override
-    public void addNode(OvsdbNode ovsdb) {
-        checkNotNull(ovsdb);
+    public void addNode(CordVtnNode node) {
+        checkNotNull(node);
 
-        nodeStore.putIfAbsent(ovsdb.deviceId(), ovsdb);
-
-        if (isNodeConnected(ovsdb)) {
-            init(ovsdb);
-        } else {
-            connect(ovsdb);
-        }
+        nodeStore.putIfAbsent(node, checkNodeState(node));
+        initNode(node);
     }
 
     @Override
-    public void deleteNode(OvsdbNode ovsdb) {
-        checkNotNull(ovsdb);
+    public void deleteNode(CordVtnNode node) {
+        checkNotNull(node);
 
-        if (deviceService.getDevice(ovsdb.deviceId()) != null) {
-            if (deviceService.isAvailable(ovsdb.deviceId())) {
-                log.warn("Cannot delete connected node {}", ovsdb.host());
-                return;
-            }
-        }
-        nodeStore.remove(ovsdb.deviceId());
-    }
-
-    @Override
-    public void connect(OvsdbNode ovsdb) {
-        checkNotNull(ovsdb);
-
-        if (!nodeStore.containsKey(ovsdb.deviceId())) {
-            log.warn("Node {} does not exist", ovsdb.host());
-            return;
+        if (getOvsdbConnectionState(node)) {
+            disconnect(node);
         }
 
-        if (!isNodeConnected(ovsdb)) {
-            controller.connect(ovsdb.ip(), ovsdb.port());
-        }
-    }
-
-    @Override
-    public void disconnect(OvsdbNode ovsdb) {
-        checkNotNull(ovsdb);
-
-        if (!nodeStore.containsKey(ovsdb.deviceId())) {
-            log.warn("Node {} does not exist", ovsdb.host());
-            return;
-        }
-
-        if (isNodeConnected(ovsdb)) {
-            OvsdbClientService ovsdbClient = getOvsdbClient(ovsdb);
-            ovsdbClient.disconnect();
-        }
-    }
-
-    private void init(OvsdbNode ovsdb) {
-        checkNotNull(ovsdb);
-
-        if (!nodeStore.containsKey(ovsdb.deviceId())) {
-            log.warn("Node {} does not exist", ovsdb.host());
-            return;
-        }
-
-        if (!isNodeConnected(ovsdb)) {
-            log.warn("Node {} is not connected", ovsdb.host());
-            return;
-        }
-
-        if (deviceService.getDevice(ovsdb.intBrId()) == null ||
-                !deviceService.isAvailable(ovsdb.intBrId())) {
-            createIntegrationBridge(ovsdb);
-        } else if (!checkVxlanInterface(ovsdb)) {
-            createVxlanInterface(ovsdb);
-        }
+        nodeStore.remove(node);
     }
 
     @Override
@@ -237,64 +227,248 @@
     }
 
     @Override
-    public OvsdbNode getNode(DeviceId deviceId) {
-        Versioned<OvsdbNode> ovsdb = nodeStore.get(deviceId);
-        if (ovsdb != null) {
-            return ovsdb.value();
-        } else {
+    public List<CordVtnNode> getNodes() {
+        List<CordVtnNode> nodes = new ArrayList<>();
+        nodes.addAll(nodeStore.keySet());
+        return nodes;
+    }
+
+    @Override
+    public void initNode(CordVtnNode node) {
+        checkNotNull(node);
+
+        if (!nodeStore.containsKey(node)) {
+            log.warn("Node {} does not exist, add node first", node.hostname());
+            return;
+        }
+
+        NodeState state = getNodeState(node);
+        if (state == null) {
+            return;
+        } else if (state.equals(NodeState.INCOMPLETE)) {
+            state = checkNodeState(node);
+        }
+
+        state.process(this, node);
+    }
+
+    @Override
+    public boolean getNodeInitState(CordVtnNode node) {
+        checkNotNull(node);
+
+        NodeState state = getNodeState(node);
+        return state != null && state.equals(NodeState.COMPLETE);
+    }
+
+    /**
+     * Returns state of a given cordvtn node.
+     *
+     * @param node cordvtn node
+     * @return node state, or null if no such node exists
+     */
+    private NodeState getNodeState(CordVtnNode node) {
+        checkNotNull(node);
+
+        try {
+            return nodeStore.get(node).value();
+        } catch (NullPointerException e) {
+            log.error("Failed to get state of {}", node.hostname());
             return null;
         }
     }
 
-    @Override
-    public List<OvsdbNode> getNodes() {
-        List<OvsdbNode> ovsdbs = new ArrayList<>();
-        ovsdbs.addAll(Collections2.transform(nodeStore.values(), Versioned::value));
-        return ovsdbs;
+    /**
+     * Sets a new state for a given cordvtn node.
+     *
+     * @param node cordvtn node
+     * @param newState new node state
+     */
+    private void setNodeState(CordVtnNode node, NodeState newState) {
+        checkNotNull(node);
+
+        log.info("Changed {} state: {}", node.hostname(), newState.toString());
+
+        nodeStore.put(node, newState);
+        newState.process(this, node);
     }
 
-    @Override
-    public boolean isNodeConnected(OvsdbNode ovsdb) {
-        checkNotNull(ovsdb);
+    /**
+     * Checks current state of a given cordvtn node and returns it.
+     *
+     * @param node cordvtn node
+     * @return node state
+     */
+    private NodeState checkNodeState(CordVtnNode node) {
+        checkNotNull(node);
 
-        OvsdbClientService ovsdbClient = getOvsdbClient(ovsdb);
-        if (ovsdbClient == null) {
-            return false;
+        if (checkIntegrationBridge(node) && checkTunnelInterface(node)) {
+            return NodeState.COMPLETE;
+        } else if (checkIntegrationBridge(node)) {
+            return NodeState.BRIDGE_CREATED;
+        } else if (getOvsdbConnectionState(node)) {
+            return NodeState.OVSDB_CONNECTED;
         } else {
-            return ovsdbClient.isConnected();
+            return NodeState.INIT;
         }
     }
 
-    private OvsdbClientService getOvsdbClient(OvsdbNode ovsdb) {
-        checkNotNull(ovsdb);
+    /**
+     * Performs tasks after node initialization.
+     *
+     * @param node cordvtn node
+     */
+    private void postInit(CordVtnNode node) {
+        disconnect(node);
+    }
+
+    /**
+     * Returns connection state of OVSDB server for a given node.
+     *
+     * @param node cordvtn node
+     * @return true if it is connected, false otherwise
+     */
+    private boolean getOvsdbConnectionState(CordVtnNode node) {
+        checkNotNull(node);
+
+        OvsdbClientService ovsdbClient = getOvsdbClient(node);
+        return deviceService.isAvailable(node.ovsdbId()) &&
+                ovsdbClient != null && ovsdbClient.isConnected();
+    }
+
+    /**
+     * Connects to OVSDB server for a given node.
+     *
+     * @param node cordvtn node
+     */
+    private void connect(CordVtnNode node) {
+        checkNotNull(node);
+
+        if (!nodeStore.containsKey(node)) {
+            log.warn("Node {} does not exist", node.hostname());
+            return;
+        }
+
+        if (!getOvsdbConnectionState(node)) {
+            // FIXME remove existing OVSDB device to work around OVSDB device re-connect issue
+            if (deviceService.getDevice(node.ovsdbId()) != null) {
+                adminService.removeDevice(node.ovsdbId());
+            }
+            controller.connect(node.ovsdbIp(), node.ovsdbPort());
+        }
+    }
+
+    /**
+     * Disconnects OVSDB server for a given node.
+     *
+     * @param node cordvtn node
+     */
+    private void disconnect(CordVtnNode node) {
+        checkNotNull(node);
+
+        if (!nodeStore.containsKey(node)) {
+            log.warn("Node {} does not exist", node.hostname());
+            return;
+        }
+
+        if (getOvsdbConnectionState(node)) {
+            OvsdbClientService ovsdbClient = getOvsdbClient(node);
+            ovsdbClient.disconnect();
+        }
+
+        // FIXME remove existing OVSDB device to work around OVSDB device re-connect issue
+        if (deviceService.getDevice(node.ovsdbId()) != null) {
+            adminService.removeDevice(node.ovsdbId());
+        }
+    }
+
+    /**
+     * Returns cordvtn node associated with a given OVSDB device.
+     *
+     * @param ovsdbId OVSDB device id
+     * @return cordvtn node, null if it fails to find the node
+     */
+    private CordVtnNode getNodeByOvsdbId(DeviceId ovsdbId) {
+        try {
+            return getNodes().stream()
+                    .filter(node -> node.ovsdbId().equals(ovsdbId))
+                    .findFirst().get();
+        } catch (NoSuchElementException e) {
+            log.debug("Couldn't find node information for {}", ovsdbId);
+            return null;
+        }
+    }
+
+    /**
+     * Returns cordvtn node associated with a given integration bridge.
+     *
+     * @param bridgeId device id of integration bridge
+     * @return cordvtn node, null if it fails to find the node
+     */
+    private CordVtnNode getNodeByBridgeId(DeviceId bridgeId) {
+        try {
+            return getNodes().stream()
+                    .filter(node -> node.intBrId().equals(bridgeId))
+                    .findFirst().get();
+        } catch (NoSuchElementException e) {
+            log.debug("Couldn't find node information for {}", bridgeId);
+            return null;
+        }
+    }
+
+    /**
+     * Returns OVSDB client for a given node.
+     *
+     * @param node cordvtn node
+     * @return OVSDB client, or null if it fails to get OVSDB client
+     */
+    private OvsdbClientService getOvsdbClient(CordVtnNode node) {
+        checkNotNull(node);
 
         OvsdbClientService ovsdbClient = controller.getOvsdbClient(
-                new OvsdbNodeId(ovsdb.ip(), ovsdb.port().toInt()));
+                new OvsdbNodeId(node.ovsdbIp(), node.ovsdbPort().toInt()));
         if (ovsdbClient == null) {
-            log.debug("Couldn't find ovsdb client for {}", ovsdb.host());
+            log.debug("Couldn't find OVSDB client for {}", node.hostname());
         }
         return ovsdbClient;
     }
 
-    private void createIntegrationBridge(OvsdbNode ovsdb) {
+    /**
+     * Creates an integration bridge for a given node.
+     *
+     * @param node cordvtn node
+     */
+    private void createIntegrationBridge(CordVtnNode node) {
+        if (checkIntegrationBridge(node)) {
+            return;
+        }
+
         List<ControllerInfo> controllers = new ArrayList<>();
         Sets.newHashSet(clusterService.getNodes())
                 .forEach(controller -> {
                     ControllerInfo ctrlInfo = new ControllerInfo(controller.ip(), OFPORT, "tcp");
                     controllers.add(ctrlInfo);
                 });
-        String dpid = ovsdb.intBrId().toString().substring(DPID_BEGIN);
+        String dpid = node.intBrId().toString().substring(DPID_BEGIN);
 
         try {
-            DriverHandler handler = driverService.createHandler(ovsdb.deviceId());
+            DriverHandler handler = driverService.createHandler(node.ovsdbId());
             BridgeConfig bridgeConfig =  handler.behaviour(BridgeConfig.class);
             bridgeConfig.addBridge(BridgeName.bridgeName(DEFAULT_BRIDGE_NAME), dpid, controllers);
         } catch (ItemNotFoundException e) {
-            log.warn("Failed to create integration bridge on {}", ovsdb.deviceId());
+            log.warn("Failed to create integration bridge on {}", node.ovsdbId());
         }
     }
 
-    private void createVxlanInterface(OvsdbNode ovsdb) {
+    /**
+     * Creates tunnel interface to the integration bridge for a given node.
+     *
+     * @param node cordvtn node
+     */
+    private void createTunnelInterface(CordVtnNode node) {
+        if (checkTunnelInterface(node)) {
+            return;
+        }
+
         DefaultAnnotations.Builder optionBuilder = DefaultAnnotations.builder();
         for (String key : DEFAULT_TUNNEL_OPTIONS.keySet()) {
             optionBuilder.set(key, DEFAULT_TUNNEL_OPTIONS.get(key));
@@ -304,38 +478,63 @@
                                              TunnelName.tunnelName(DEFAULT_TUNNEL),
                                              optionBuilder.build());
         try {
-            DriverHandler handler = driverService.createHandler(ovsdb.deviceId());
+            DriverHandler handler = driverService.createHandler(node.ovsdbId());
             TunnelConfig tunnelConfig =  handler.behaviour(TunnelConfig.class);
             tunnelConfig.createTunnelInterface(BridgeName.bridgeName(DEFAULT_BRIDGE_NAME), description);
         } catch (ItemNotFoundException e) {
-            log.warn("Failed to create VXLAN interface on {}", ovsdb.deviceId());
+            log.warn("Failed to create tunnel interface on {}", node.ovsdbId());
         }
     }
 
-    private boolean checkVxlanInterface(OvsdbNode ovsdb) {
+    /**
+     * Checks if integration bridge exists and available.
+     *
+     * @param node cordvtn node
+     * @return true if the bridge is available, false otherwise
+     */
+    private boolean checkIntegrationBridge(CordVtnNode node) {
+        return (deviceService.getDevice(node.intBrId()) != null
+                && deviceService.isAvailable(node.intBrId()));
+    }
+
+    /**
+     * Checks if tunnel interface exists.
+     *
+     * @param node cordvtn node
+     * @return true if the interface exists, false otherwise
+     */
+    private boolean checkTunnelInterface(CordVtnNode node) {
         try {
-            DriverHandler handler = driverService.createHandler(ovsdb.deviceId());
-            BridgeConfig bridgeConfig = handler.behaviour(BridgeConfig.class);
-            bridgeConfig.getPorts().stream()
-                    .filter(p -> p.annotations().value("portName").equals(DEFAULT_TUNNEL))
+            deviceService.getPorts(node.intBrId())
+                    .stream()
+                    .filter(p -> p.annotations().value("portName").contains(DEFAULT_TUNNEL)
+                            && p.isEnabled())
                     .findAny().get();
-        } catch (ItemNotFoundException | NoSuchElementException e) {
+            return true;
+        } catch (NoSuchElementException e) {
             return false;
         }
-        return true;
     }
 
     private class InternalDeviceListener implements DeviceListener {
 
         @Override
         public void event(DeviceEvent event) {
+
             Device device = event.subject();
-            ConnectionHandler handler = (device.type() == SWITCH ? bridgeHandler : ovsdbHandler);
+            ConnectionHandler<Device> handler =
+                    (device.type().equals(SWITCH) ? bridgeHandler : ovsdbHandler);
 
             switch (event.type()) {
-                case DEVICE_ADDED:
-                    eventExecutor.submit(() -> handler.connected(device));
+                case PORT_ADDED:
+                    eventExecutor.submit(() -> bridgeHandler.portAdded(event.port()));
                     break;
+                case PORT_UPDATED:
+                    if (!event.port().isEnabled()) {
+                        eventExecutor.submit(() -> bridgeHandler.portRemoved(event.port()));
+                    }
+                    break;
+                case DEVICE_ADDED:
                 case DEVICE_AVAILABILITY_CHANGED:
                     if (deviceService.isAvailable(device.id())) {
                         eventExecutor.submit(() -> handler.connected(device));
@@ -372,17 +571,15 @@
 
         @Override
         public void connected(Device device) {
-            log.info("Ovsdb {} is connected", device.id());
-
-            OvsdbNode ovsdb = getNode(device.id());
-            if (ovsdb != null) {
-                init(ovsdb);
+            CordVtnNode node = getNodeByOvsdbId(device.id());
+            if (node != null) {
+                setNodeState(node, checkNodeState(node));
             }
         }
 
         @Override
         public void disconnected(Device device) {
-            log.warn("Ovsdb {} is disconnected", device.id());
+            log.info("OVSDB {} is disconnected", device.id());
         }
     }
 
@@ -390,26 +587,56 @@
 
         @Override
         public void connected(Device device) {
-            log.info("Integration Bridge {} is detected", device.id());
-
-            OvsdbNode ovsdb;
-            try {
-                ovsdb = getNodes().stream()
-                        .filter(node -> node.intBrId().equals(device.id()))
-                        .findFirst().get();
-            } catch (NoSuchElementException e) {
-                log.warn("Couldn't find OVSDB associated with {}", device.id());
-                return;
-            }
-
-            if (!checkVxlanInterface(ovsdb)) {
-                createVxlanInterface(ovsdb);
+            CordVtnNode node = getNodeByBridgeId(device.id());
+            if (node != null) {
+                setNodeState(node, checkNodeState(node));
             }
         }
 
         @Override
         public void disconnected(Device device) {
-            log.info("Integration Bridge {} is vanished", device.id());
+            CordVtnNode node = getNodeByBridgeId(device.id());
+            if (node != null) {
+                log.info("Integration Bridge is disconnected from {}", node.hostname());
+                setNodeState(node, NodeState.INCOMPLETE);
+            }
+        }
+
+        /**
+         * Handles port added situation.
+         * If the added port is tunnel port, proceed remaining node initialization.
+         * Otherwise, do nothing.
+         *
+         * @param port port
+         */
+        public void portAdded(Port port) {
+            if (!port.annotations().value("portName").contains(DEFAULT_TUNNEL)) {
+                return;
+            }
+
+            CordVtnNode node = getNodeByBridgeId((DeviceId) port.element().id());
+            if (node != null) {
+                setNodeState(node, checkNodeState(node));
+            }
+        }
+
+        /**
+         * Handles port removed situation.
+         * If the removed port is tunnel port, proceed remaining node initialization.
+         * Others, do nothing.
+         *
+         * @param port port
+         */
+        public void portRemoved(Port port) {
+            if (!port.annotations().value("portName").contains(DEFAULT_TUNNEL)) {
+                return;
+            }
+
+            CordVtnNode node = getNodeByBridgeId((DeviceId) port.element().id());
+            if (node != null) {
+                log.info("Tunnel interface is removed from {}", node.hostname());
+                setNodeState(node, NodeState.INCOMPLETE);
+            }
         }
     }
 
