diff --git a/BUCK b/BUCK
new file mode 100644
index 0000000..2a7d8ca
--- /dev/null
+++ b/BUCK
@@ -0,0 +1,40 @@
+# app builds but is currently non functional. It needs transitive runtime
+# dependencies.
+
+COMPILE_DEPS = [
+    '//lib:CORE_DEPS',
+    '//lib:org.apache.karaf.shell.console',
+    '//lib:javax.ws.rs-api',
+    '//lib:jsch',
+    '//utils/rest:onlab-rest',
+    '//cli:onos-cli',
+    '//core/store/serializers:onos-core-serializers',
+    '//apps/dhcp/api:onos-apps-dhcp-api',
+    '//apps/xosclient:onos-apps-xosclient',
+    '//apps/cordconfig:onos-apps-cordconfig',
+    '//protocols/ovsdb/api:onos-protocols-ovsdb-api',
+    '//protocols/ovsdb/rfc:onos-protocols-ovsdb-rfc',
+]
+
+BUNDLES = [
+    '//apps/cordvtn:onos-apps-cordvtn',
+]
+
+EXCLUDED_BUNDLES = [
+    '//lib:jsch',
+]
+
+osgi_jar_with_tests (
+    deps = COMPILE_DEPS,
+    web_context = '/onos/cordvtn',
+)
+
+onos_app (
+    title = 'CORD VTN REST API',
+    category = 'Traffic Steering',
+    url = 'http://onosproject.org',
+    included_bundles = BUNDLES,
+    excluded_bundles = EXCLUDED_BUNDLES,
+    description = 'APIs for interacting with the CORD VTN application.',
+    required_apps = [ 'org.onosproject.cord-config', 'org.onosproject.xosclient', 'org.onosproject.dhcp', 'org.onosproject.ovsdb' ],
+)
diff --git a/app.xml b/app.xml
new file mode 100644
index 0000000..17583ce
--- /dev/null
+++ b/app.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ 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.
+  -->
+<app name="org.onosproject.cordvtn" origin="ON.Lab" version="${project.version}"
+        category="Traffic Steering" url="http://onosproject.org" title="CORD Virtual Tenant Network"
+        featuresRepo="mvn:${project.groupId}/${project.artifactId}/${project.version}/xml/features"
+        features="${project.artifactId}"
+        apps="org.onosproject.ovsdb-base,org.onosproject.dhcp,org.onosproject.xosclient,org.onosproject.cord-config">
+    <description>${project.description}</description>
+    <artifact>mvn:${project.groupId}/onos-app-cordvtn/${project.version}</artifact>
+</app>
diff --git a/features.xml b/features.xml
new file mode 100644
index 0000000..1425b03
--- /dev/null
+++ b/features.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<!--
+  ~ 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.
+  -->
+<features xmlns="http://karaf.apache.org/xmlns/features/v1.2.0" name="${project.artifactId}-${project.version}">
+    <feature name="${project.artifactId}" version="${project.version}" description="${project.description}">
+        <feature>onos-api</feature>
+        <bundle>mvn:${project.groupId}/onos-app-cordvtn/${project.version}</bundle>
+        <bundle>wrap:mvn:com.jcraft/jsch/0.1.53$Bundle-SymbolicName=jsch&amp;Bundle-Version=0.1.53</bundle>
+    </feature>
+</features>
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..fa6e068
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,148 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Copyright 2015-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.
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.onosproject</groupId>
+        <artifactId>onos-apps</artifactId>
+        <version>1.7.0-SNAPSHOT</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+
+    <artifactId>onos-app-cordvtn</artifactId>
+    <packaging>bundle</packaging>
+
+    <description>Virtual tenant network service for CORD</description>
+
+    <properties>
+        <web.context>/onos/cordvtn</web.context>
+        <api.version>1.0.0</api.version>
+        <api.title>CORD VTN REST API</api.title>
+        <api.description>
+            APIs for interacting with the CORD VTN application.
+        </api.description>
+        <api.package>org.onosproject.cordvtn.rest</api.package>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.compendium</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onos-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onos-core-serializers</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onos-ovsdb-api</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onos-cli</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.karaf.shell</groupId>
+            <artifactId>org.apache.karaf.shell.console</artifactId>
+            <version>3.0.5</version>
+        </dependency>
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onos-rest</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onlab-rest</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>javax.ws.rs</groupId>
+            <artifactId>javax.ws.rs-api</artifactId>
+            <version>2.0.1</version>
+        </dependency>
+        <dependency>
+            <groupId>org.glassfish.jersey.containers</groupId>
+            <artifactId>jersey-container-servlet</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.fasterxml.jackson.core</groupId>
+            <artifactId>jackson-databind</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.fasterxml.jackson.core</groupId>
+            <artifactId>jackson-annotations</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onos-app-dhcp-api</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onos-app-xos-client</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onos-cord-config</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>com.jcraft</groupId>
+            <artifactId>jsch</artifactId>
+            <version>0.1.53</version>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-bundle-plugin</artifactId>
+                <extensions>true</extensions>
+                <configuration>
+                    <instructions>
+                        <_wab>src/main/webapp/</_wab>
+                        <Include-Resource>
+                            WEB-INF/classes/apidoc/swagger.json=target/swagger.json,
+                            {maven-resources}
+                        </Include-Resource>
+                        <Bundle-SymbolicName>
+                            ${project.groupId}.${project.artifactId}
+                        </Bundle-SymbolicName>
+                        <Import-Package>
+                            *,org.glassfish.jersey.servlet
+                        </Import-Package>
+                        <Web-ContextPath>${web.context}</Web-ContextPath>
+                    </instructions>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>
diff --git a/src/main/java/org/onosproject/cordvtn/api/ConnectionHandler.java b/src/main/java/org/onosproject/cordvtn/api/ConnectionHandler.java
new file mode 100644
index 0000000..5676221
--- /dev/null
+++ b/src/main/java/org/onosproject/cordvtn/api/ConnectionHandler.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2015-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.cordvtn.api;
+
+/**
+ * Entity capable of handling a subject connected and disconnected situation.
+ */
+public interface ConnectionHandler<T> {
+
+    /**
+     * Processes the connected subject.
+     *
+     * @param subject subject
+     */
+    void connected(T subject);
+
+    /**
+     * Processes the disconnected subject.
+     *
+     * @param subject subject.
+     */
+    void disconnected(T subject);
+}
diff --git a/src/main/java/org/onosproject/cordvtn/api/CordVtnConfig.java b/src/main/java/org/onosproject/cordvtn/api/CordVtnConfig.java
new file mode 100644
index 0000000..be097ce
--- /dev/null
+++ b/src/main/java/org/onosproject/cordvtn/api/CordVtnConfig.java
@@ -0,0 +1,254 @@
+/*
+ * Copyright 2015-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.cordvtn.api;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
+import org.onlab.packet.Ip4Address;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.IpPrefix;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.TpPort;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.config.Config;
+import org.onosproject.xosclient.api.OpenStackAccess;
+import org.onosproject.xosclient.api.XosAccess;
+import org.slf4j.Logger;
+
+import java.util.Map;
+import java.util.Set;
+
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * Configuration object for CordVtn service.
+ */
+public class CordVtnConfig extends Config<ApplicationId> {
+
+    protected final Logger log = getLogger(getClass());
+
+    public static final String PRIVATE_GATEWAY_MAC = "privateGatewayMac";
+    public static final String PUBLIC_GATEWAYS = "publicGateways";
+    public static final String GATEWAY_IP = "gatewayIp";
+    public static final String GATEWAY_MAC = "gatewayMac";
+    public static final String LOCAL_MANAGEMENT_IP = "localManagementIp";
+    public static final String MANAGEMENT_IP = "managementIpRange";
+    public static final String OVSDB_PORT = "ovsdbPort";
+
+    public static final String CORDVTN_NODES = "nodes";
+    public static final String HOSTNAME = "hostname";
+    public static final String HOST_MANAGEMENT_IP = "hostManagementIp";
+    public static final String DATA_PLANE_IP = "dataPlaneIp";
+    public static final String DATA_PLANE_INTF = "dataPlaneIntf";
+    public static final String BRIDGE_ID = "bridgeId";
+
+    public static final String SSH = "ssh";
+    public static final String SSH_PORT = "sshPort";
+    public static final String SSH_USER = "sshUser";
+    public static final String SSH_KEY_FILE = "sshKeyFile";
+
+    public static final String OPENSTACK = "openstack";
+    public static final String XOS = "xos";
+
+    public static final String ENDPOINT = "endpoint";
+    public static final String TENANT = "tenant";
+    public static final String USER = "user";
+    public static final String PASSWORD = "password";
+
+    /**
+     * Returns the set of nodes read from network config.
+     *
+     * @return set of CordVtnNodeConfig or empty set
+     */
+    public Set<CordVtnNode> cordVtnNodes() {
+
+        Set<CordVtnNode> nodes = Sets.newHashSet();
+
+        JsonNode cordvtnNodes = object.get(CORDVTN_NODES);
+        if (cordvtnNodes == null) {
+            log.debug("No CORD VTN nodes found");
+            return nodes;
+        }
+
+        JsonNode sshNode = object.get(SSH);
+        if (sshNode == null) {
+            log.warn("SSH information not found");
+            return nodes;
+        }
+
+        for (JsonNode cordvtnNode : cordvtnNodes) {
+            try {
+                NetworkAddress hostMgmt = NetworkAddress.valueOf(getConfig(cordvtnNode, HOST_MANAGEMENT_IP));
+                NetworkAddress localMgmt = NetworkAddress.valueOf(getConfig(object, LOCAL_MANAGEMENT_IP));
+                if (hostMgmt.prefix().contains(localMgmt.prefix()) ||
+                        localMgmt.prefix().contains(hostMgmt.prefix())) {
+                    log.error("hostMamt and localMgmt cannot be overlapped, skip this node");
+                    continue;
+                }
+
+                Ip4Address hostMgmtIp = hostMgmt.ip().getIp4Address();
+                SshAccessInfo sshInfo = new SshAccessInfo(
+                        hostMgmtIp,
+                        TpPort.tpPort(Integer.parseInt(getConfig(sshNode, SSH_PORT))),
+                        getConfig(sshNode, SSH_USER), getConfig(sshNode, SSH_KEY_FILE));
+
+                String hostname = getConfig(cordvtnNode, HOSTNAME);
+                CordVtnNode newNode = new CordVtnNode(
+                        hostname, hostMgmt, localMgmt,
+                        NetworkAddress.valueOf(getConfig(cordvtnNode, DATA_PLANE_IP)),
+                        TpPort.tpPort(Integer.parseInt(getConfig(object, OVSDB_PORT))),
+                        sshInfo,
+                        DeviceId.deviceId(getConfig(cordvtnNode, BRIDGE_ID)),
+                        getConfig(cordvtnNode, DATA_PLANE_INTF),
+                        CordVtnNodeState.noState());
+
+                nodes.add(newNode);
+            } catch (IllegalArgumentException | NullPointerException e) {
+                log.error("{}", e);
+            }
+        }
+
+        return nodes;
+    }
+
+    /**
+     * Returns value of a given path. If the path is missing, show log and return
+     * null.
+     *
+     * @param path path
+     * @return value or null
+     */
+    private String getConfig(JsonNode jsonNode, String path) {
+        jsonNode = jsonNode.path(path);
+
+        if (jsonNode.isMissingNode()) {
+            log.error("{} is not configured", path);
+            return null;
+        } else {
+            return jsonNode.asText();
+        }
+    }
+
+    /**
+     * Returns private network gateway MAC address.
+     *
+     * @return mac address, or null
+     */
+    public MacAddress privateGatewayMac() {
+        JsonNode jsonNode = object.get(PRIVATE_GATEWAY_MAC);
+        if (jsonNode == null) {
+            return null;
+        }
+
+        try {
+            return MacAddress.valueOf(jsonNode.asText());
+        } catch (IllegalArgumentException e) {
+            log.error("Wrong MAC address format {}", jsonNode.asText());
+            return null;
+        }
+    }
+
+    /**
+     * Returns public network gateway IP and MAC address pairs.
+     *
+     * @return map of ip and mac address
+     */
+    public Map<IpAddress, MacAddress> publicGateways() {
+        JsonNode jsonNodes = object.get(PUBLIC_GATEWAYS);
+        if (jsonNodes == null) {
+            return Maps.newHashMap();
+        }
+
+        Map<IpAddress, MacAddress> publicGateways = Maps.newHashMap();
+        jsonNodes.forEach(jsonNode -> {
+            try {
+                publicGateways.put(
+                        IpAddress.valueOf(jsonNode.path(GATEWAY_IP).asText()),
+                        MacAddress.valueOf(jsonNode.path(GATEWAY_MAC).asText()));
+            } catch (IllegalArgumentException | NullPointerException e) {
+                log.error("Wrong address format {}", e.toString());
+            }
+        });
+
+        return publicGateways;
+    }
+
+    /**
+     * Returns management IP address range.
+     *
+     * @return management network ip prefix, or null
+     */
+    public IpPrefix managementIpRange() {
+        JsonNode jsonNode = object.get(MANAGEMENT_IP);
+        if (jsonNode == null) {
+            return null;
+        }
+
+        try {
+            return IpPrefix.valueOf(jsonNode.asText());
+        } catch (IllegalArgumentException e) {
+            log.error("{}:{} wrong address format", MANAGEMENT_IP, jsonNode);
+            return null;
+        }
+    }
+
+    /**
+     * Returns XOS access information.
+     *
+     * @return XOS access, or null
+     */
+    public XosAccess xosAccess() {
+        JsonNode jsonNode = object.get(XOS);
+        if (jsonNode == null) {
+            return null;
+        }
+
+        try {
+            return new XosAccess(getConfig(jsonNode, ENDPOINT),
+                                 getConfig(jsonNode, USER),
+                                 getConfig(jsonNode, PASSWORD));
+        } catch (NullPointerException e) {
+            log.error("Failed to get XOS access");
+            return null;
+        }
+    }
+
+    /**
+     * Returns OpenStack API access information.
+     *
+     * @return openstack access
+     */
+    public OpenStackAccess openstackAccess() {
+        JsonNode jsonNode = object.get(OPENSTACK);
+        if (jsonNode == null) {
+            log.error("Failed to get OpenStack configurations");
+            return null;
+        }
+
+        try {
+            return new OpenStackAccess(
+                    jsonNode.path(ENDPOINT).asText(),
+                    jsonNode.path(TENANT).asText(),
+                    jsonNode.path(USER).asText(),
+                    jsonNode.path(PASSWORD).asText());
+        } catch (IllegalArgumentException | NullPointerException e) {
+            log.error("Failed to get OpenStack configurations");
+            return null;
+        }
+    }
+}
diff --git a/src/main/java/org/onosproject/cordvtn/api/CordVtnNode.java b/src/main/java/org/onosproject/cordvtn/api/CordVtnNode.java
new file mode 100644
index 0000000..c63a9e4
--- /dev/null
+++ b/src/main/java/org/onosproject/cordvtn/api/CordVtnNode.java
@@ -0,0 +1,220 @@
+/*
+ * Copyright 2015-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.cordvtn.api;
+
+import com.google.common.base.MoreObjects;
+import org.onlab.packet.TpPort;
+import org.onosproject.net.DeviceId;
+
+import java.util.Comparator;
+import java.util.Objects;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Representation of a compute infrastructure node for CORD VTN service.
+ */
+public final class CordVtnNode {
+
+    private final String hostname;
+    private final NetworkAddress hostMgmtIp;
+    private final NetworkAddress localMgmtIp;
+    private final NetworkAddress dpIp;
+    private final TpPort ovsdbPort;
+    private final SshAccessInfo sshInfo;
+    private final DeviceId bridgeId;
+    private final String dpIntf;
+    private final CordVtnNodeState state;
+
+    public static final Comparator<CordVtnNode> CORDVTN_NODE_COMPARATOR =
+            (node1, node2) -> node1.hostname().compareTo(node2.hostname());
+
+    /**
+     * Creates a new node.
+     *
+     * @param hostname hostname
+     * @param hostMgmtIp host management network address
+     * @param localMgmtIp local management network address
+     * @param dpIp data plane network address
+     * @param ovsdbPort port number for OVSDB connection
+     * @param sshInfo SSH access information
+     * @param bridgeId integration bridge identifier
+     * @param dpIntf data plane interface name
+     * @param state cordvtn node state
+     */
+    public CordVtnNode(String hostname, NetworkAddress hostMgmtIp, NetworkAddress localMgmtIp,
+                       NetworkAddress dpIp, TpPort ovsdbPort, SshAccessInfo sshInfo,
+                       DeviceId bridgeId, String dpIntf, CordVtnNodeState state) {
+        this.hostname = checkNotNull(hostname, "hostname cannot be null");
+        this.hostMgmtIp = checkNotNull(hostMgmtIp, "hostMgmtIp cannot be null");
+        this.localMgmtIp = checkNotNull(localMgmtIp, "localMgmtIp cannot be null");
+        this.dpIp = checkNotNull(dpIp, "dpIp cannot be null");
+        this.ovsdbPort = checkNotNull(ovsdbPort, "ovsdbPort cannot be null");
+        this.sshInfo = checkNotNull(sshInfo, "sshInfo cannot be null");
+        this.bridgeId = checkNotNull(bridgeId, "bridgeId cannot be null");
+        this.dpIntf = checkNotNull(dpIntf, "dpIntf cannot be null");
+        this.state = state;
+    }
+
+    /**
+     * Returns cordvtn node with new state.
+     *
+     * @param node cordvtn node
+     * @param state cordvtn node init state
+     * @return cordvtn node
+     */
+    public static CordVtnNode getUpdatedNode(CordVtnNode node, CordVtnNodeState state) {
+        return new CordVtnNode(node.hostname,
+                               node.hostMgmtIp, node.localMgmtIp, node.dpIp,
+                               node.ovsdbPort,
+                               node.sshInfo,
+                               node.bridgeId,
+                               node.dpIntf, state);
+    }
+
+    /**
+     * Returns the hostname.
+     *
+     * @return hostname
+     */
+    public String hostname() {
+        return this.hostname;
+    }
+
+    /**
+     * Returns the host management network address.
+     *
+     * @return network address
+     */
+    public NetworkAddress hostMgmtIp() {
+        return this.hostMgmtIp;
+    }
+
+    /**
+     * Returns the local management network address.
+     *
+     * @return network address
+     */
+    public NetworkAddress localMgmtIp() {
+        return this.localMgmtIp;
+    }
+
+    /**
+     * Returns the data plane network address.
+     *
+     * @return network address
+     */
+    public NetworkAddress dpIp() {
+        return this.dpIp;
+    }
+
+    /**
+     * Returns the port number used for OVSDB connection.
+     *
+     * @return port number
+     */
+    public TpPort ovsdbPort() {
+        return this.ovsdbPort;
+    }
+
+    /**
+     * Returns the SSH access information.
+     *
+     * @return ssh access information
+     */
+    public SshAccessInfo sshInfo() {
+        return this.sshInfo;
+    }
+
+    /**
+     * Returns the identifier of the integration bridge.
+     *
+     * @return device id
+     */
+    public DeviceId intBrId() {
+        return this.bridgeId;
+    }
+
+    /**
+     * Returns the identifier of the OVSDB device.
+     *
+     * @return device id
+     */
+    public DeviceId ovsdbId() {
+        return DeviceId.deviceId("ovsdb:" + this.hostMgmtIp.ip().toString());
+    }
+
+    /**
+     * Returns data plane interface name.
+     *
+     * @return data plane interface name
+     */
+    public String dpIntf() {
+        return this.dpIntf;
+    }
+
+    /**
+     * Returns the state of the node.
+     *
+     * @return state
+     */
+    public CordVtnNodeState state() {
+        return this.state;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+
+        if (obj instanceof CordVtnNode) {
+            CordVtnNode that = (CordVtnNode) obj;
+            if (Objects.equals(hostname, that.hostname) &&
+                    Objects.equals(hostMgmtIp, that.hostMgmtIp) &&
+                    Objects.equals(localMgmtIp, that.localMgmtIp) &&
+                    Objects.equals(dpIp, that.dpIp) &&
+                    Objects.equals(ovsdbPort, that.ovsdbPort) &&
+                    Objects.equals(sshInfo, that.sshInfo) &&
+                    Objects.equals(bridgeId, that.bridgeId) &&
+                    Objects.equals(dpIntf, that.dpIntf)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(hostname, hostMgmtIp, localMgmtIp, dpIp,
+                            ovsdbPort, sshInfo, bridgeId, dpIntf);
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass())
+                .add("hostname", hostname)
+                .add("hostMgmtIp", hostMgmtIp)
+                .add("localMgmtIp", localMgmtIp)
+                .add("dpIp", dpIp)
+                .add("port", ovsdbPort)
+                .add("sshInfo", sshInfo)
+                .add("bridgeId", bridgeId)
+                .add("dpIntf", dpIntf)
+                .add("state", state)
+                .toString();
+    }
+}
diff --git a/src/main/java/org/onosproject/cordvtn/api/CordVtnNodeState.java b/src/main/java/org/onosproject/cordvtn/api/CordVtnNodeState.java
new file mode 100644
index 0000000..1121390
--- /dev/null
+++ b/src/main/java/org/onosproject/cordvtn/api/CordVtnNodeState.java
@@ -0,0 +1,30 @@
+/*
+ * 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.cordvtn.api;
+
+/**
+ * Entity that defines possible init state of the cordvtn node.
+ */
+public interface CordVtnNodeState {
+    /**
+     * Returns null for no state.
+     *
+     * @return null
+     */
+    static CordVtnNodeState noState() {
+        return null;
+    }
+}
diff --git a/src/main/java/org/onosproject/cordvtn/api/CordVtnService.java b/src/main/java/org/onosproject/cordvtn/api/CordVtnService.java
new file mode 100644
index 0000000..1a8849e
--- /dev/null
+++ b/src/main/java/org/onosproject/cordvtn/api/CordVtnService.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2015-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.cordvtn.api;
+
+import org.onosproject.xosclient.api.VtnServiceId;
+
+/**
+ * Service for provisioning overlay virtual networks on compute nodes.
+ */
+public interface CordVtnService {
+
+    String CORDVTN_APP_ID = "org.onosproject.cordvtn";
+
+    /**
+     * Creates dependencies for a given tenant service.
+     *
+     * @param tServiceId id of the service which has a dependency
+     * @param pServiceId id of the service which provide dependency
+     * @param isBidirectional true to enable bidirectional connectivity between two services
+     */
+    void createServiceDependency(VtnServiceId tServiceId, VtnServiceId pServiceId,
+                                 boolean isBidirectional);
+
+    /**
+     * Removes all dependencies from a given tenant service.
+     *
+     * @param tServiceId id of the service which has a dependency
+     * @param pServiceId id of the service which provide dependency
+     */
+    void removeServiceDependency(VtnServiceId tServiceId, VtnServiceId pServiceId);
+}
diff --git a/src/main/java/org/onosproject/cordvtn/api/Instance.java b/src/main/java/org/onosproject/cordvtn/api/Instance.java
new file mode 100644
index 0000000..83c7c08
--- /dev/null
+++ b/src/main/java/org/onosproject/cordvtn/api/Instance.java
@@ -0,0 +1,169 @@
+/*
+ * 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.cordvtn.api;
+
+import com.google.common.base.Strings;
+import org.onlab.packet.Ip4Address;
+import org.onlab.packet.MacAddress;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.Host;
+import org.onosproject.net.PortNumber;
+import org.onosproject.xosclient.api.VtnPortId;
+import org.onosproject.xosclient.api.VtnService;
+import org.onosproject.xosclient.api.VtnServiceId;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Provides methods to help to handle network service instance.
+ */
+public final class Instance {
+
+    public static final String SERVICE_ID = "serviceId";
+    public static final String SERVICE_TYPE = "serviceType";
+    public static final String PORT_ID = "vtnPortId";
+    public static final String CREATE_TIME = "createTime";
+    public static final String NESTED_INSTANCE = "nestedInstance";
+    public static final String TRUE = "true";
+
+    private final Host host;
+
+    /**
+     * Default constructor.
+     *
+     * @param instance host object of this instance
+     */
+    private Instance(Host instance) {
+        this.host = instance;
+    }
+
+    /**
+     * Returns host object of this instance.
+     *
+     * @return host
+     */
+    public Host host() {
+        return this.host;
+    }
+
+    /**
+     * Returns new instance.
+     *
+     * @param host host object of this instance
+     * @return instance
+     */
+    public static Instance of(Host host) {
+        checkNotNull(host);
+        checkArgument(!Strings.isNullOrEmpty(host.annotations().value(SERVICE_ID)));
+        checkArgument(!Strings.isNullOrEmpty(host.annotations().value(SERVICE_TYPE)));
+        checkArgument(!Strings.isNullOrEmpty(host.annotations().value(PORT_ID)));
+        checkArgument(!Strings.isNullOrEmpty(host.annotations().value(CREATE_TIME)));
+
+        return new Instance(host);
+    }
+
+    /**
+     * Returns service ID of a given host.
+     *
+     * @return vtn service id
+     */
+    public VtnServiceId serviceId() {
+        String serviceId = host.annotations().value(SERVICE_ID);
+        return VtnServiceId.of(serviceId);
+    }
+
+    /**
+     * Returns service type of a given host.
+     *
+     * @return vtn service type
+     */
+    public VtnService.ServiceType serviceType() {
+        String serviceType = host.annotations().value(SERVICE_TYPE);
+        return VtnService.ServiceType.valueOf(serviceType);
+    }
+
+    /**
+     * Returns port ID of a given host.
+     *
+     * @return vtn port id
+     */
+    public VtnPortId portId() {
+        String portId = host.annotations().value(PORT_ID);
+        return VtnPortId.of(portId);
+    }
+
+    /**
+     * Returns if the instance is nested container or not.
+     *
+     * @return true if it's nested container; false otherwise
+     */
+    public boolean isNestedInstance() {
+        return host.annotations().value(NESTED_INSTANCE) != null;
+    }
+
+    /**
+     * Returns MAC address of this instance.
+     *
+     * @return mac address
+     */
+    public MacAddress mac() {
+        return host.mac();
+    }
+
+    /**
+     * Returns IP address of this instance.
+     *
+     * @return ip address
+     */
+    public Ip4Address ipAddress() {
+        // assume all instance has only one IP address, and only IP4 is supported now
+        return host.ipAddresses().stream().findFirst().get().getIp4Address();
+    }
+
+    /**
+     * Returns device ID of this host.
+     *
+     * @return device id
+     */
+    public DeviceId deviceId() {
+        return host.location().deviceId();
+    }
+
+    /**
+     * Returns the port number where this host is.
+     *
+     * @return port number
+     */
+    public PortNumber portNumber() {
+        return host.location().port();
+    }
+
+    /**
+     * Returns annotation value with a given key.
+     *
+     * @param annotationKey annotation key
+     * @return annotation value
+     */
+    public String getAnnotation(String annotationKey) {
+        return host.annotations().value(annotationKey);
+    }
+
+    @Override
+    public String toString() {
+        return host.toString();
+    }
+}
diff --git a/src/main/java/org/onosproject/cordvtn/api/InstanceHandler.java b/src/main/java/org/onosproject/cordvtn/api/InstanceHandler.java
new file mode 100644
index 0000000..3e5be2f
--- /dev/null
+++ b/src/main/java/org/onosproject/cordvtn/api/InstanceHandler.java
@@ -0,0 +1,36 @@
+/*
+ * 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.cordvtn.api;
+
+/**
+ * Handles service instance detection and removal.
+ */
+public interface InstanceHandler {
+
+    /**
+     * Handles newly detected instance.
+     *
+     * @param instance instance
+     */
+    void instanceDetected(Instance instance);
+
+    /**
+     * Handles removed instance.
+     *
+     * @param instance instance
+     */
+    void instanceRemoved(Instance instance);
+}
diff --git a/src/main/java/org/onosproject/cordvtn/api/NetworkAddress.java b/src/main/java/org/onosproject/cordvtn/api/NetworkAddress.java
new file mode 100644
index 0000000..23c7318
--- /dev/null
+++ b/src/main/java/org/onosproject/cordvtn/api/NetworkAddress.java
@@ -0,0 +1,114 @@
+/*
+ * 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.cordvtn.api;
+
+import com.google.common.base.MoreObjects;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.IpPrefix;
+
+import java.util.Objects;
+
+import static com.google.common.base.Preconditions.checkArgument;
+
+/**
+ * Representation of a network address, which consists of IP address and prefix.
+ */
+public final class NetworkAddress {
+    private final IpAddress ip;
+    private final IpPrefix prefix;
+
+    /**
+     * Constructor for a given IP address and prefix.
+     *
+     * @param ip ip address
+     * @param prefix ip prefix
+     */
+    public NetworkAddress(IpAddress ip, IpPrefix prefix) {
+        this.ip = ip;
+        this.prefix = prefix;
+    }
+
+    /**
+     * Converts a CIDR notation string into a network address.
+     *
+     * @param cidr cidr
+     * @return network address
+     * @throws IllegalArgumentException if the cidr is not valid
+     */
+    public static NetworkAddress valueOf(String cidr) {
+        checkArgument(cidr.contains("/"));
+
+        IpAddress ipAddress = IpAddress.valueOf(cidr.split("/")[0]);
+        IpPrefix ipPrefix = IpPrefix.valueOf(cidr);
+
+        return new NetworkAddress(ipAddress, ipPrefix);
+    }
+
+    /**
+     * Returns the IP address value of the network address.
+     *
+     * @return ip address
+     */
+    public IpAddress ip() {
+        return this.ip;
+    }
+
+    /**
+     * Returns the IP prefix value of the network address.
+     *
+     * @return ip prefix
+     */
+    public IpPrefix prefix() {
+        return this.prefix;
+    }
+
+    /**
+     * Converts a network address to a CIDR notation.
+     *
+     * @return cidr notation string
+     */
+    public String cidr() {
+        return ip.toString() + "/" + prefix.prefixLength();
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+
+        if (obj instanceof NetworkAddress) {
+            NetworkAddress that = (NetworkAddress) obj;
+            if (Objects.equals(ip, that.ip) && Objects.equals(prefix, that.prefix)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(ip, prefix);
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass())
+                .add("IpAddress", ip)
+                .add("IpPrefix", prefix)
+                .toString();
+    }
+}
diff --git a/src/main/java/org/onosproject/cordvtn/api/SshAccessInfo.java b/src/main/java/org/onosproject/cordvtn/api/SshAccessInfo.java
new file mode 100644
index 0000000..7679348
--- /dev/null
+++ b/src/main/java/org/onosproject/cordvtn/api/SshAccessInfo.java
@@ -0,0 +1,119 @@
+/*
+ * 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.cordvtn.api;
+
+import com.google.common.base.MoreObjects;
+import org.onlab.packet.Ip4Address;
+import org.onlab.packet.TpPort;
+
+import java.util.Objects;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Representation of SSH access information.
+ */
+public final class SshAccessInfo {
+
+    private final Ip4Address remoteIp;
+    private final TpPort port;
+    private final String user;
+    private final String privateKey;
+
+    /**
+     * Creates a new SSH access information.
+     *
+     * @param remoteIp ssh remote ip address
+     * @param port ssh port number
+     * @param user user name
+     * @param privateKey path of ssh private key
+     */
+    public SshAccessInfo(Ip4Address remoteIp, TpPort port, String user, String privateKey) {
+        this.remoteIp = checkNotNull(remoteIp);
+        this.port = checkNotNull(port);
+        this.user = checkNotNull(user);
+        this.privateKey = checkNotNull(privateKey);
+    }
+
+    /**
+     * Returns the remote IP address.
+     *
+     * @return ip address
+     */
+    public Ip4Address remoteIp() {
+        return this.remoteIp;
+    }
+
+    /**
+     * Returns the port number.
+     *
+     * @return ssh port
+     */
+    public TpPort port() {
+        return this.port;
+    }
+
+    /**
+     * Returns the user name.
+     *
+     * @return user name
+     */
+    public String user() {
+        return this.user;
+    }
+
+    /**
+     * Returns the private key path.
+     *
+     * @return privateKey
+     */
+    public String privateKey() {
+        return privateKey;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+
+        if (obj instanceof SshAccessInfo) {
+            SshAccessInfo that = (SshAccessInfo) obj;
+            if (Objects.equals(remoteIp, that.remoteIp) &&
+                    Objects.equals(port, that.port) &&
+                    Objects.equals(user, that.user) &&
+                    Objects.equals(privateKey, that.privateKey)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(remoteIp, port, user, privateKey);
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass())
+                .add("remoteIp", remoteIp)
+                .add("port", port)
+                .add("user", user)
+                .add("privateKey", privateKey)
+                .toString();
+    }
+}
diff --git a/src/main/java/org/onosproject/cordvtn/api/package-info.java b/src/main/java/org/onosproject/cordvtn/api/package-info.java
new file mode 100644
index 0000000..7d41963
--- /dev/null
+++ b/src/main/java/org/onosproject/cordvtn/api/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * 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.
+ */
+
+/**
+ * API for CORD VTN application.
+ */
+package org.onosproject.cordvtn.api;
\ No newline at end of file
diff --git a/src/main/java/org/onosproject/cordvtn/cli/CordVtnFlushRules.java b/src/main/java/org/onosproject/cordvtn/cli/CordVtnFlushRules.java
new file mode 100644
index 0000000..228d06c
--- /dev/null
+++ b/src/main/java/org/onosproject/cordvtn/cli/CordVtnFlushRules.java
@@ -0,0 +1,36 @@
+/*
+ * 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.cordvtn.cli;
+
+import org.apache.karaf.shell.commands.Command;
+import org.onosproject.cli.AbstractShellCommand;
+import org.onosproject.cordvtn.impl.CordVtnPipeline;
+
+/**
+ * Deletes nodes from the service.
+ */
+@Command(scope = "onos", name = "cordvtn-flush-rules",
+        description = "Flush flow rules installed by CORD VTN")
+public class CordVtnFlushRules extends AbstractShellCommand {
+
+    @Override
+    protected void execute() {
+        CordVtnPipeline pipeline = AbstractShellCommand.get(CordVtnPipeline.class);
+        pipeline.flushRules();
+        print("Successfully flushed");
+    }
+}
diff --git a/src/main/java/org/onosproject/cordvtn/cli/CordVtnNodeCheckCommand.java b/src/main/java/org/onosproject/cordvtn/cli/CordVtnNodeCheckCommand.java
new file mode 100644
index 0000000..782003e
--- /dev/null
+++ b/src/main/java/org/onosproject/cordvtn/cli/CordVtnNodeCheckCommand.java
@@ -0,0 +1,74 @@
+/*
+ * 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.cordvtn.cli;
+
+import org.apache.karaf.shell.commands.Argument;
+import org.apache.karaf.shell.commands.Command;
+import org.onosproject.cli.AbstractShellCommand;
+import org.onosproject.cordvtn.api.CordVtnNode;
+import org.onosproject.cordvtn.impl.CordVtnNodeManager;
+import org.onosproject.net.Device;
+import org.onosproject.net.device.DeviceService;
+import org.onosproject.net.driver.DriverService;
+
+/**
+ * Checks detailed node init state.
+ */
+@Command(scope = "onos", name = "cordvtn-node-check",
+        description = "Shows detailed node init state")
+public class CordVtnNodeCheckCommand extends AbstractShellCommand {
+
+    @Argument(index = 0, name = "hostname", description = "Hostname",
+            required = true, multiValued = false)
+    private String hostname = null;
+
+    @Override
+    protected void execute() {
+        CordVtnNodeManager nodeManager = AbstractShellCommand.get(CordVtnNodeManager.class);
+        DeviceService deviceService = AbstractShellCommand.get(DeviceService.class);
+
+        CordVtnNode node = nodeManager.getNodes()
+                .stream()
+                .filter(n -> n.hostname().equals(hostname))
+                .findFirst()
+                .orElse(null);
+
+        if (node == null) {
+            print("Cannot find %s from registered nodes", hostname);
+            return;
+        }
+
+        print(nodeManager.checkNodeInitState(node));
+
+        print("%n[DEBUG]");
+        Device device = deviceService.getDevice(node.intBrId());
+        String driver = get(DriverService.class).getDriver(device.id()).name();
+        print("%s available=%s driver=%s %s",
+              device.id(),
+              deviceService.isAvailable(device.id()),
+              driver,
+              device.annotations());
+
+        deviceService.getPorts(node.intBrId()).forEach(port -> {
+            Object portIsEnabled = port.isEnabled() ? "enabled" : "disabled";
+            print("port=%s state=%s %s",
+                  port.number(),
+                  portIsEnabled,
+                  port.annotations());
+        });
+    }
+}
diff --git a/src/main/java/org/onosproject/cordvtn/cli/CordVtnNodeDeleteCommand.java b/src/main/java/org/onosproject/cordvtn/cli/CordVtnNodeDeleteCommand.java
new file mode 100644
index 0000000..c3b49e1
--- /dev/null
+++ b/src/main/java/org/onosproject/cordvtn/cli/CordVtnNodeDeleteCommand.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2015-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.cordvtn.cli;
+
+import org.apache.karaf.shell.commands.Argument;
+import org.apache.karaf.shell.commands.Command;
+import org.onosproject.cli.AbstractShellCommand;
+import org.onosproject.cordvtn.impl.CordVtnNodeManager;
+import org.onosproject.cordvtn.api.CordVtnNode;
+
+import java.util.NoSuchElementException;
+
+/**
+ * Deletes nodes from the service.
+ */
+@Command(scope = "onos", name = "cordvtn-node-delete",
+        description = "Deletes nodes from CORD VTN service")
+public class CordVtnNodeDeleteCommand extends AbstractShellCommand {
+
+    @Argument(index = 0, name = "hostnames", description = "Hostname(s)",
+            required = true, multiValued = true)
+    private String[] hostnames = null;
+
+    @Override
+    protected void execute() {
+        CordVtnNodeManager nodeManager = AbstractShellCommand.get(CordVtnNodeManager.class);
+
+        for (String hostname : hostnames) {
+            CordVtnNode node;
+            try {
+                node = nodeManager.getNodes()
+                        .stream()
+                        .filter(n -> n.hostname().equals(hostname))
+                        .findFirst().get();
+            } catch (NoSuchElementException e) {
+                print("Unable to find %s", hostname);
+                continue;
+            }
+
+            nodeManager.deleteNode(node);
+        }
+    }
+}
diff --git a/src/main/java/org/onosproject/cordvtn/cli/CordVtnNodeInitCommand.java b/src/main/java/org/onosproject/cordvtn/cli/CordVtnNodeInitCommand.java
new file mode 100644
index 0000000..b47ec7d
--- /dev/null
+++ b/src/main/java/org/onosproject/cordvtn/cli/CordVtnNodeInitCommand.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2015-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.cordvtn.cli;
+
+import org.apache.karaf.shell.commands.Argument;
+import org.apache.karaf.shell.commands.Command;
+import org.onosproject.cli.AbstractShellCommand;
+import org.onosproject.cordvtn.impl.CordVtnNodeManager;
+import org.onosproject.cordvtn.api.CordVtnNode;
+
+import java.util.NoSuchElementException;
+
+/**
+ * Initializes nodes for CordVtn service.
+ */
+@Command(scope = "onos", name = "cordvtn-node-init",
+        description = "Initializes nodes for CORD VTN service")
+public class CordVtnNodeInitCommand extends AbstractShellCommand {
+
+    @Argument(index = 0, name = "hostnames", description = "Hostname(s)",
+            required = true, multiValued = true)
+    private String[] hostnames = null;
+
+    @Override
+    protected void execute() {
+        CordVtnNodeManager nodeManager = AbstractShellCommand.get(CordVtnNodeManager.class);
+
+        for (String hostname : hostnames) {
+            CordVtnNode node;
+            try {
+                node = nodeManager.getNodes()
+                        .stream()
+                        .filter(n -> n.hostname().equals(hostname))
+                        .findFirst().get();
+            } catch (NoSuchElementException e) {
+                print("Unable to find %s", hostname);
+                continue;
+            }
+
+            nodeManager.addOrUpdateNode(node);
+        }
+    }
+}
diff --git a/src/main/java/org/onosproject/cordvtn/cli/CordVtnNodeListCommand.java b/src/main/java/org/onosproject/cordvtn/cli/CordVtnNodeListCommand.java
new file mode 100644
index 0000000..a6e4039
--- /dev/null
+++ b/src/main/java/org/onosproject/cordvtn/cli/CordVtnNodeListCommand.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2015-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.cordvtn.cli;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import org.apache.karaf.shell.commands.Command;
+import org.onosproject.cli.AbstractShellCommand;
+import org.onosproject.cordvtn.impl.CordVtnNodeManager;
+import org.onosproject.cordvtn.api.CordVtnNode;
+
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Lists all nodes registered to the service.
+ */
+@Command(scope = "onos", name = "cordvtn-nodes",
+        description = "Lists all nodes registered in CORD VTN service")
+public class CordVtnNodeListCommand extends AbstractShellCommand {
+
+    private static final String COMPLETE = "COMPLETE";
+    private static final String INCOMPLETE = "INCOMPLETE";
+
+    @Override
+    protected void execute() {
+        CordVtnNodeManager nodeManager = AbstractShellCommand.get(CordVtnNodeManager.class);
+        List<CordVtnNode> nodes = nodeManager.getNodes();
+        Collections.sort(nodes, CordVtnNode.CORDVTN_NODE_COMPARATOR);
+
+        if (outputJson()) {
+            print("%s", json(nodeManager, nodes));
+        } else {
+            for (CordVtnNode node : nodes) {
+                print("hostname=%s, hostMgmtIp=%s, dpIp=%s, br-int=%s, dpIntf=%s, init=%s",
+                      node.hostname(),
+                      node.hostMgmtIp().cidr(),
+                      node.dpIp().cidr(),
+                      node.intBrId().toString(),
+                      node.dpIntf(),
+                      getState(nodeManager, node));
+            }
+            print("Total %s nodes", nodeManager.getNodeCount());
+        }
+    }
+
+    private JsonNode json(CordVtnNodeManager nodeManager, List<CordVtnNode> nodes) {
+        ObjectMapper mapper = new ObjectMapper();
+        ArrayNode result = mapper.createArrayNode();
+        for (CordVtnNode node : nodes) {
+            result.add(mapper.createObjectNode()
+                               .put("hostname", node.hostname())
+                               .put("hostManagementIp", node.hostMgmtIp().cidr())
+                               .put("dataPlaneIp", node.dpIp().cidr())
+                               .put("bridgeId", node.intBrId().toString())
+                               .put("dataPlaneInterface", node.dpIntf())
+                               .put("init", getState(nodeManager, node)));
+        }
+        return result;
+    }
+
+    private String getState(CordVtnNodeManager nodeManager, CordVtnNode node) {
+        return nodeManager.isNodeInitComplete(node) ? COMPLETE : INCOMPLETE;
+    }
+}
diff --git a/src/main/java/org/onosproject/cordvtn/cli/package-info.java b/src/main/java/org/onosproject/cordvtn/cli/package-info.java
new file mode 100644
index 0000000..f5c69a1
--- /dev/null
+++ b/src/main/java/org/onosproject/cordvtn/cli/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2015-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.
+ */
+
+/**
+ * Console commands to manage OVSDB nodes for cordvtn.
+ */
+package org.onosproject.cordvtn.cli;
\ No newline at end of file
diff --git a/src/main/java/org/onosproject/cordvtn/impl/CordVtn.java b/src/main/java/org/onosproject/cordvtn/impl/CordVtn.java
new file mode 100644
index 0000000..efa0e4a
--- /dev/null
+++ b/src/main/java/org/onosproject/cordvtn/impl/CordVtn.java
@@ -0,0 +1,410 @@
+/*
+ * Copyright 2015-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.cordvtn.impl;
+
+import com.google.common.collect.Lists;
+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;
+import org.apache.felix.scr.annotations.Deactivate;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.apache.felix.scr.annotations.Service;
+import org.onlab.packet.Ethernet;
+import org.onlab.packet.Ip4Address;
+import org.onlab.packet.Ip4Prefix;
+import org.onosproject.cordvtn.api.CordVtnNode;
+import org.onosproject.cordvtn.api.CordVtnService;
+import org.onosproject.cordvtn.api.Instance;
+import org.onosproject.core.DefaultGroupId;
+import org.onosproject.core.GroupId;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.Host;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.flow.DefaultFlowRule;
+import org.onosproject.net.flow.DefaultTrafficSelector;
+import org.onosproject.net.flow.DefaultTrafficTreatment;
+import org.onosproject.net.flow.FlowRule;
+import org.onosproject.net.flow.TrafficSelector;
+import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.flow.instructions.ExtensionTreatment;
+import org.onosproject.net.group.DefaultGroupDescription;
+import org.onosproject.net.group.DefaultGroupKey;
+import org.onosproject.net.group.Group;
+import org.onosproject.net.group.GroupBucket;
+import org.onosproject.net.group.GroupBuckets;
+import org.onosproject.net.group.GroupDescription;
+import org.onosproject.net.group.GroupKey;
+import org.onosproject.net.group.GroupService;
+import org.onosproject.net.host.HostEvent;
+import org.onosproject.net.host.HostListener;
+import org.onosproject.xosclient.api.VtnService;
+import org.onosproject.xosclient.api.VtnServiceId;
+import org.slf4j.Logger;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import static java.util.concurrent.Executors.newSingleThreadScheduledExecutor;
+import static org.onlab.util.Tools.groupedThreads;
+import static org.onosproject.cordvtn.impl.CordVtnPipeline.*;
+import static org.onosproject.net.group.DefaultGroupBucket.createSelectGroupBucket;
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * Provisions service dependency capabilities between network services.
+ */
+@Component(immediate = true)
+@Service
+public class CordVtn extends CordVtnInstanceHandler implements CordVtnService {
+
+    protected final Logger log = getLogger(getClass());
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected GroupService groupService;
+
+    @Activate
+    protected void activate() {
+        eventExecutor = newSingleThreadScheduledExecutor(groupedThreads("onos/cordvtn", "event-handler"));
+        hostListener = new InternalHostListener();
+        super.activate();
+    }
+
+    @Deactivate
+    protected void deactivate() {
+        super.deactivate();
+    }
+
+    @Override
+    public void createServiceDependency(VtnServiceId tServiceId, VtnServiceId pServiceId,
+                                        boolean isBidirectional) {
+        VtnService tService = getVtnService(tServiceId);
+        VtnService pService = getVtnService(pServiceId);
+
+        if (tService == null || pService == null) {
+            log.error("Failed to create dependency between {} and {}",
+                      tServiceId, pServiceId);
+            return;
+        }
+
+        log.info("Created dependency between {} and {}", tService.name(), pService.name());
+        serviceDependencyRules(tService, pService, isBidirectional, true);
+    }
+
+    @Override
+    public void removeServiceDependency(VtnServiceId tServiceId, VtnServiceId pServiceId) {
+        VtnService tService = getVtnService(tServiceId);
+        VtnService pService = getVtnService(pServiceId);
+
+        if (tService == null || pService == null) {
+            log.error("Failed to remove dependency between {} and {}",
+                      tServiceId, pServiceId);
+            return;
+        }
+
+        log.info("Removed dependency between {} and {}", tService.name(), pService.name());
+        serviceDependencyRules(tService, pService, true, false);
+    }
+
+    @Override
+    public void instanceDetected(Instance instance) {
+        VtnService service = getVtnService(instance.serviceId());
+        if (service == null) {
+            return;
+        }
+
+        // TODO get bidirectional information from XOS once XOS supports
+        service.tenantServices().stream().forEach(
+                tServiceId -> createServiceDependency(tServiceId, service.id(), true));
+        service.providerServices().stream().forEach(
+                pServiceId -> createServiceDependency(service.id(), pServiceId, true));
+
+        updateProviderServiceInstances(service);
+    }
+
+    @Override
+    public void instanceRemoved(Instance instance) {
+        VtnService service = getVtnService(instance.serviceId());
+        if (service == null) {
+            return;
+        }
+
+        if (!service.providerServices().isEmpty()) {
+            removeInstanceFromTenantService(instance, service);
+        }
+        if (!service.tenantServices().isEmpty()) {
+            updateProviderServiceInstances(service);
+        }
+    }
+
+    private void updateProviderServiceInstances(VtnService service) {
+        GroupKey groupKey = getGroupKey(service.id());
+
+        Set<DeviceId> devices = nodeManager.completeNodes().stream()
+                .map(CordVtnNode::intBrId)
+                .collect(Collectors.toSet());
+
+        for (DeviceId deviceId : devices) {
+            Group group = groupService.getGroup(deviceId, groupKey);
+            if (group == null) {
+                log.trace("No group exists for service {} in {}", service.id(), deviceId);
+                continue;
+            }
+
+            List<GroupBucket> oldBuckets = group.buckets().buckets();
+            List<GroupBucket> newBuckets = getServiceGroupBuckets(
+                    deviceId, service.vni(), getInstances(service.id())).buckets();
+
+            if (oldBuckets.equals(newBuckets)) {
+                continue;
+            }
+
+            List<GroupBucket> bucketsToRemove = Lists.newArrayList(oldBuckets);
+            bucketsToRemove.removeAll(newBuckets);
+            if (!bucketsToRemove.isEmpty()) {
+                groupService.removeBucketsFromGroup(
+                        deviceId,
+                        groupKey,
+                        new GroupBuckets(bucketsToRemove),
+                        groupKey, appId);
+            }
+
+            List<GroupBucket> bucketsToAdd = Lists.newArrayList(newBuckets);
+            bucketsToAdd.removeAll(oldBuckets);
+            if (!bucketsToAdd.isEmpty()) {
+                groupService.addBucketsToGroup(
+                        deviceId,
+                        groupKey,
+                        new GroupBuckets(bucketsToAdd),
+                        groupKey, appId);
+            }
+        }
+    }
+
+    private void removeInstanceFromTenantService(Instance instance, VtnService service) {
+        service.providerServices().stream().forEach(pServiceId -> {
+            Map<DeviceId, Set<PortNumber>> inPorts = Maps.newHashMap();
+            Map<DeviceId, GroupId> outGroups = Maps.newHashMap();
+
+            inPorts.put(instance.deviceId(), Sets.newHashSet(instance.portNumber()));
+            outGroups.put(instance.deviceId(), getGroupId(pServiceId, instance.deviceId()));
+
+            inServiceRule(inPorts, outGroups, false);
+        });
+    }
+
+    private void serviceDependencyRules(VtnService tService, VtnService pService,
+                                       boolean isBidirectional, boolean install) {
+        Map<DeviceId, GroupId> outGroups = Maps.newHashMap();
+        Map<DeviceId, Set<PortNumber>> inPorts = Maps.newHashMap();
+
+        nodeManager.completeNodes().stream().forEach(node -> {
+            DeviceId deviceId = node.intBrId();
+            GroupId groupId = createServiceGroup(deviceId, pService);
+            outGroups.put(deviceId, groupId);
+
+            Set<PortNumber> tServiceInstances = getInstances(tService.id())
+                    .stream()
+                    .filter(instance -> instance.deviceId().equals(deviceId))
+                    .map(Instance::portNumber)
+                    .collect(Collectors.toSet());
+            inPorts.put(deviceId, tServiceInstances);
+        });
+
+        Ip4Prefix srcRange = tService.subnet().getIp4Prefix();
+        Ip4Prefix dstRange = pService.subnet().getIp4Prefix();
+
+        indirectAccessRule(srcRange, pService.serviceIp().getIp4Address(), outGroups, install);
+        directAccessRule(srcRange, dstRange, install);
+        if (isBidirectional) {
+            directAccessRule(dstRange, srcRange, install);
+        }
+        inServiceRule(inPorts, outGroups, install);
+    }
+
+    private void indirectAccessRule(Ip4Prefix srcRange, Ip4Address serviceIp,
+                                    Map<DeviceId, GroupId> outGroups, boolean install) {
+        TrafficSelector selector = DefaultTrafficSelector.builder()
+                .matchEthType(Ethernet.TYPE_IPV4)
+                .matchIPSrc(srcRange)
+                .matchIPDst(serviceIp.toIpPrefix())
+                .build();
+
+        for (Map.Entry<DeviceId, GroupId> outGroup : outGroups.entrySet()) {
+            TrafficTreatment treatment = DefaultTrafficTreatment.builder()
+                    .group(outGroup.getValue())
+                    .build();
+
+            FlowRule flowRule = DefaultFlowRule.builder()
+                    .fromApp(appId)
+                    .withSelector(selector)
+                    .withTreatment(treatment)
+                    .withPriority(PRIORITY_HIGH)
+                    .forDevice(outGroup.getKey())
+                    .forTable(TABLE_ACCESS_TYPE)
+                    .makePermanent()
+                    .build();
+
+            pipeline.processFlowRule(install, flowRule);
+        }
+    }
+
+    private void directAccessRule(Ip4Prefix srcRange, Ip4Prefix dstRange, boolean install) {
+        TrafficSelector selector = DefaultTrafficSelector.builder()
+                .matchEthType(Ethernet.TYPE_IPV4)
+                .matchIPSrc(srcRange)
+                .matchIPDst(dstRange)
+                .build();
+
+        TrafficTreatment treatment = DefaultTrafficTreatment.builder()
+                .transition(TABLE_DST_IP)
+                .build();
+
+        nodeManager.completeNodes().stream().forEach(node -> {
+            DeviceId deviceId = node.intBrId();
+            FlowRule flowRuleDirect = DefaultFlowRule.builder()
+                    .fromApp(appId)
+                    .withSelector(selector)
+                    .withTreatment(treatment)
+                    .withPriority(PRIORITY_DEFAULT)
+                    .forDevice(deviceId)
+                    .forTable(TABLE_ACCESS_TYPE)
+                    .makePermanent()
+                    .build();
+
+            pipeline.processFlowRule(install, flowRuleDirect);
+        });
+    }
+
+    private void inServiceRule(Map<DeviceId, Set<PortNumber>> inPorts,
+                               Map<DeviceId, GroupId> outGroups, boolean install) {
+        for (Map.Entry<DeviceId, Set<PortNumber>> entry : inPorts.entrySet()) {
+            Set<PortNumber> ports = entry.getValue();
+            DeviceId deviceId = entry.getKey();
+
+            GroupId groupId = outGroups.get(deviceId);
+            if (groupId == null) {
+                continue;
+            }
+
+            ports.stream().forEach(port -> {
+                TrafficSelector selector = DefaultTrafficSelector.builder()
+                        .matchInPort(port)
+                        .build();
+
+                TrafficTreatment treatment = DefaultTrafficTreatment.builder()
+                        .group(groupId)
+                        .build();
+
+                FlowRule flowRule = DefaultFlowRule.builder()
+                        .fromApp(appId)
+                        .withSelector(selector)
+                        .withTreatment(treatment)
+                        .withPriority(PRIORITY_DEFAULT)
+                        .forDevice(deviceId)
+                        .forTable(TABLE_IN_SERVICE)
+                        .makePermanent()
+                        .build();
+
+                pipeline.processFlowRule(install, flowRule);
+            });
+        }
+    }
+
+    private GroupId getGroupId(VtnServiceId serviceId, DeviceId deviceId) {
+        return new DefaultGroupId(Objects.hash(serviceId, deviceId));
+    }
+
+    private GroupKey getGroupKey(VtnServiceId serviceId) {
+        return new DefaultGroupKey(serviceId.id().getBytes());
+    }
+
+    private GroupId createServiceGroup(DeviceId deviceId, VtnService service) {
+        GroupKey groupKey = getGroupKey(service.id());
+        Group group = groupService.getGroup(deviceId, groupKey);
+        GroupId groupId = getGroupId(service.id(), deviceId);
+
+        if (group != null) {
+            log.debug("Group {} is already exist in {}", service.id(), deviceId);
+            return groupId;
+        }
+
+        GroupBuckets buckets = getServiceGroupBuckets(
+                deviceId, service.vni(), getInstances(service.id()));
+        GroupDescription groupDescription = new DefaultGroupDescription(
+                deviceId,
+                GroupDescription.Type.SELECT,
+                buckets,
+                groupKey,
+                groupId.id(),
+                appId);
+
+        groupService.addGroup(groupDescription);
+        return groupId;
+    }
+
+    private GroupBuckets getServiceGroupBuckets(DeviceId deviceId, long tunnelId,
+                                                Set<Instance> instances) {
+        List<GroupBucket> buckets = Lists.newArrayList();
+        instances.stream().forEach(instance -> {
+            Ip4Address tunnelIp = nodeManager.dpIp(instance.deviceId()).getIp4Address();
+            TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
+
+            if (deviceId.equals(instance.deviceId())) {
+                tBuilder.setEthDst(instance.mac())
+                        .setOutput(instance.portNumber());
+            } else {
+                ExtensionTreatment tunnelDst =
+                        pipeline.tunnelDstTreatment(deviceId, tunnelIp);
+                tBuilder.setEthDst(instance.mac())
+                        .extension(tunnelDst, deviceId)
+                        .setTunnelId(tunnelId)
+                        .setOutput(nodeManager.tunnelPort(instance.deviceId()));
+            }
+            buckets.add(createSelectGroupBucket(tBuilder.build()));
+        });
+        return new GroupBuckets(buckets);
+    }
+
+    private class InternalHostListener implements HostListener {
+
+        @Override
+        public void event(HostEvent event) {
+            Host host = event.subject();
+            if (!mastershipService.isLocalMaster(host.location().deviceId())) {
+                // do not allow to proceed without mastership
+                return;
+            }
+
+            Instance instance = Instance.of(host);
+            switch (event.type()) {
+                case HOST_UPDATED:
+                case HOST_ADDED:
+                    eventExecutor.execute(() -> instanceDetected(instance));
+                    break;
+                case HOST_REMOVED:
+                    eventExecutor.execute(() -> instanceRemoved(instance));
+                    break;
+                default:
+                    break;
+            }
+        }
+    }
+}
diff --git a/src/main/java/org/onosproject/cordvtn/impl/CordVtnArpProxy.java b/src/main/java/org/onosproject/cordvtn/impl/CordVtnArpProxy.java
new file mode 100644
index 0000000..8200fcc
--- /dev/null
+++ b/src/main/java/org/onosproject/cordvtn/impl/CordVtnArpProxy.java
@@ -0,0 +1,244 @@
+/*
+ * 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.cordvtn.impl;
+
+import com.google.common.collect.Maps;
+import org.onlab.packet.ARP;
+import org.onlab.packet.EthType;
+import org.onlab.packet.Ethernet;
+import org.onlab.packet.Ip4Address;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.MacAddress;
+import org.onosproject.cordvtn.api.Instance;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.net.Host;
+import org.onosproject.net.flow.DefaultTrafficSelector;
+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.PacketContext;
+import org.onosproject.net.packet.PacketPriority;
+import org.onosproject.net.packet.PacketService;
+import org.slf4j.Logger;
+
+import java.nio.ByteBuffer;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * Handles ARP requests for virtual network service IPs.
+ */
+public class CordVtnArpProxy {
+    protected final Logger log = getLogger(getClass());
+
+    private final ApplicationId appId;
+    private final PacketService packetService;
+    private final HostService hostService;
+
+    private final Map<Ip4Address, MacAddress> gateways = Maps.newConcurrentMap();
+
+    /**
+     * Default constructor.
+     *
+     * @param appId application id
+     * @param packetService packet service
+     * @param hostService host service reference
+     */
+    public CordVtnArpProxy(ApplicationId appId, PacketService packetService, HostService hostService) {
+        this.appId = appId;
+        this.packetService = packetService;
+        this.hostService = hostService;
+    }
+
+    /**
+     * Requests ARP packet.
+     */
+    public void requestPacket() {
+        TrafficSelector selector = DefaultTrafficSelector.builder()
+                .matchEthType(EthType.EtherType.ARP.ethType().toShort())
+                .build();
+
+        packetService.requestPackets(selector,
+                                     PacketPriority.CONTROL,
+                                     appId,
+                                     Optional.empty());
+    }
+
+    /**
+     * Cancels ARP packet.
+     */
+    public void cancelPacket() {
+        TrafficSelector selector = DefaultTrafficSelector.builder()
+                .matchEthType(EthType.EtherType.ARP.ethType().toShort())
+                .build();
+
+        packetService.cancelPackets(selector,
+                                    PacketPriority.CONTROL,
+                                    appId,
+                                    Optional.empty());
+    }
+
+    /**
+     * Adds a given gateway IP and MAC address to this ARP proxy.
+     *
+     * @param gatewayIp gateway ip address
+     * @param gatewayMac gateway mac address
+     */
+    public void addGateway(IpAddress gatewayIp, MacAddress gatewayMac) {
+        checkNotNull(gatewayIp);
+        checkNotNull(gatewayMac);
+        gateways.put(gatewayIp.getIp4Address(), gatewayMac);
+    }
+
+    /**
+     * Removes a given service IP address from this ARP proxy.
+     *
+     * @param gatewayIp gateway ip address
+     */
+    public void removeGateway(IpAddress gatewayIp) {
+        checkNotNull(gatewayIp);
+        gateways.remove(gatewayIp.getIp4Address());
+    }
+
+    /**
+     * Emits ARP reply with fake MAC address for a given ARP request.
+     * It only handles requests for the registered service IPs, and the other
+     * requests can be handled by other ARP handlers like openstackSwitching or
+     * proxyArp, for example.
+     *
+     * @param context packet context
+     * @param ethPacket ethernet packet
+     */
+    public void processArpPacket(PacketContext context, Ethernet ethPacket) {
+        ARP arpPacket = (ARP) ethPacket.getPayload();
+        if (arpPacket.getOpCode() != ARP.OP_REQUEST) {
+           return;
+        }
+
+        Ip4Address targetIp = Ip4Address.valueOf(arpPacket.getTargetProtocolAddress());
+
+        MacAddress gatewayMac = gateways.get(targetIp);
+        MacAddress replyMac = gatewayMac != null ? gatewayMac : getMacFromHostService(targetIp);
+
+        if (replyMac.equals(MacAddress.NONE)) {
+            log.debug("Failed to find MAC for {}", targetIp.toString());
+            context.block();
+            return;
+        }
+
+        log.trace("Send ARP reply for {} with {}", targetIp.toString(), replyMac.toString());
+        Ethernet ethReply = ARP.buildArpReply(
+                targetIp,
+                replyMac,
+                ethPacket);
+
+        TrafficTreatment treatment = DefaultTrafficTreatment.builder()
+                .setOutput(context.inPacket().receivedFrom().port())
+                .build();
+
+        packetService.emit(new DefaultOutboundPacket(
+                context.inPacket().receivedFrom().deviceId(),
+                treatment,
+                ByteBuffer.wrap(ethReply.serialize())));
+
+        context.block();
+    }
+
+    /**
+     * Emits gratuitous ARP when a gateway mac address has been changed.
+     *
+     * @param gatewayIp gateway ip address to update MAC
+     * @param instances set of instances to send gratuitous ARP packet
+     */
+    public void sendGratuitousArpForGateway(IpAddress gatewayIp, Set<Instance> instances) {
+        MacAddress gatewayMac = gateways.get(gatewayIp.getIp4Address());
+        if (gatewayMac == null) {
+            log.debug("Gateway {} is not registered to ARP proxy", gatewayIp.toString());
+            return;
+        }
+
+        Ethernet ethArp = buildGratuitousArp(gatewayIp.getIp4Address(), gatewayMac);
+        instances.stream().forEach(instance -> {
+            TrafficTreatment treatment = DefaultTrafficTreatment.builder()
+                    .setOutput(instance.portNumber())
+                    .build();
+
+            packetService.emit(new DefaultOutboundPacket(
+                    instance.deviceId(),
+                    treatment,
+                    ByteBuffer.wrap(ethArp.serialize())));
+        });
+    }
+
+    /**
+     * Builds gratuitous ARP packet with a given IP and MAC address.
+     *
+     * @param ip ip address for TPA and SPA
+     * @param mac new mac address
+     * @return ethernet packet
+     */
+    private Ethernet buildGratuitousArp(IpAddress ip, MacAddress mac) {
+        Ethernet eth = new Ethernet();
+
+        eth.setEtherType(Ethernet.TYPE_ARP);
+        eth.setSourceMACAddress(mac);
+        eth.setDestinationMACAddress(MacAddress.BROADCAST);
+
+        ARP arp = new ARP();
+        arp.setOpCode(ARP.OP_REQUEST);
+        arp.setHardwareType(ARP.HW_TYPE_ETHERNET);
+        arp.setHardwareAddressLength((byte) Ethernet.DATALAYER_ADDRESS_LENGTH);
+        arp.setProtocolType(ARP.PROTO_TYPE_IP);
+        arp.setProtocolAddressLength((byte) Ip4Address.BYTE_LENGTH);
+
+        arp.setSenderHardwareAddress(mac.toBytes());
+        arp.setTargetHardwareAddress(MacAddress.BROADCAST.toBytes());
+        arp.setSenderProtocolAddress(ip.getIp4Address().toOctets());
+        arp.setTargetProtocolAddress(ip.getIp4Address().toOctets());
+
+        eth.setPayload(arp);
+        return eth;
+    }
+
+    /**
+     * Returns MAC address of a host with a given target IP address by asking to
+     * host service. It does not support overlapping IP.
+     *
+     * @param targetIp target ip
+     * @return mac address, or NONE mac address if it fails to find the mac
+     */
+    private MacAddress getMacFromHostService(IpAddress targetIp) {
+        checkNotNull(targetIp);
+
+        Host host = hostService.getHostsByIp(targetIp)
+                .stream()
+                .findFirst()
+                .orElse(null);
+
+        if (host != null) {
+            log.trace("Found MAC from host service for {}", targetIp.toString());
+            return host.mac();
+        } else {
+            return MacAddress.NONE;
+        }
+    }
+}
diff --git a/src/main/java/org/onosproject/cordvtn/impl/CordVtnInstanceHandler.java b/src/main/java/org/onosproject/cordvtn/impl/CordVtnInstanceHandler.java
new file mode 100644
index 0000000..197f8df
--- /dev/null
+++ b/src/main/java/org/onosproject/cordvtn/impl/CordVtnInstanceHandler.java
@@ -0,0 +1,536 @@
+/*
+ * 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.cordvtn.impl;
+
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.onlab.packet.Ethernet;
+import org.onlab.packet.Ip4Address;
+import org.onlab.packet.Ip4Prefix;
+import org.onosproject.cordvtn.api.CordVtnConfig;
+import org.onosproject.cordvtn.api.CordVtnNode;
+import org.onosproject.cordvtn.api.CordVtnService;
+import org.onosproject.cordvtn.api.Instance;
+import org.onosproject.cordvtn.api.InstanceHandler;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreService;
+import org.onosproject.mastership.MastershipService;
+import org.onosproject.net.Host;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.config.NetworkConfigEvent;
+import org.onosproject.net.config.NetworkConfigListener;
+import org.onosproject.net.config.NetworkConfigRegistry;
+import org.onosproject.net.flow.DefaultFlowRule;
+import org.onosproject.net.flow.DefaultTrafficSelector;
+import org.onosproject.net.flow.DefaultTrafficTreatment;
+import org.onosproject.net.flow.FlowRule;
+import org.onosproject.net.flow.TrafficSelector;
+import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.flow.instructions.ExtensionTreatment;
+import org.onosproject.net.host.HostEvent;
+import org.onosproject.net.host.HostListener;
+import org.onosproject.net.host.HostService;
+import org.onosproject.xosclient.api.OpenStackAccess;
+import org.onosproject.xosclient.api.VtnService;
+import org.onosproject.xosclient.api.VtnServiceApi;
+import org.onosproject.xosclient.api.VtnServiceId;
+import org.onosproject.xosclient.api.XosAccess;
+import org.onosproject.xosclient.api.XosClientService;
+import org.slf4j.Logger;
+
+import java.util.Objects;
+import java.util.Set;
+import java.util.concurrent.ExecutorService;
+import java.util.stream.Collectors;
+import java.util.stream.StreamSupport;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.onosproject.cordvtn.impl.CordVtnPipeline.*;
+import static org.onosproject.xosclient.api.VtnService.NetworkType.MANAGEMENT;
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * Provides default virtual network connectivity for service instances.
+ */
+@Component(immediate = true)
+public abstract class CordVtnInstanceHandler implements InstanceHandler {
+
+    protected final Logger log = getLogger(getClass());
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected CoreService coreService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected MastershipService mastershipService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected NetworkConfigRegistry configRegistry;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected HostService hostService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected XosClientService xosClient;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected CordVtnNodeManager nodeManager;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected CordVtnPipeline pipeline;
+
+    protected static final String OPENSTACK_ACCESS_ERROR = "OpenStack access is not configured";
+    protected static final String XOS_ACCESS_ERROR = "XOS access is not configured";
+
+    protected XosAccess xosAccess = null;
+    protected OpenStackAccess osAccess = null;
+    protected ApplicationId appId;
+    protected VtnService.ServiceType serviceType;
+    protected ExecutorService eventExecutor;
+
+    protected HostListener hostListener = new InternalHostListener();
+    protected NetworkConfigListener configListener = new InternalConfigListener();
+
+    protected void activate() {
+        // sub class should set service type and event executor in its activate method
+        appId = coreService.registerApplication(CordVtnService.CORDVTN_APP_ID);
+
+        hostService.addListener(hostListener);
+        configRegistry.addListener(configListener);
+
+        log.info("Started");
+    }
+
+    protected void deactivate() {
+        hostService.removeListener(hostListener);
+        configRegistry.removeListener(configListener);
+        eventExecutor.shutdown();
+
+        log.info("Stopped");
+    }
+
+    @Override
+    public void instanceDetected(Instance instance) {
+        log.info("Instance is detected {}", instance);
+
+        VtnService service = getVtnService(instance.serviceId());
+        if (service == null) {
+            log.warn("Failed to get VtnService for {}", instance);
+            return;
+        }
+
+        if (service.networkType().equals(MANAGEMENT)) {
+            managementNetworkRules(instance, service, true);
+        }
+
+        defaultConnectionRules(instance, service, true);
+    }
+
+    @Override
+    public void instanceRemoved(Instance instance) {
+        log.info("Instance is removed {}", instance);
+
+        VtnService service = getVtnService(instance.serviceId());
+        if (service == null) {
+            log.warn("Failed to get VtnService for {}", instance);
+            return;
+        }
+
+        if (service.networkType().equals(MANAGEMENT)) {
+            managementNetworkRules(instance, service, false);
+        }
+
+        // TODO check if any stale management network rules are
+        defaultConnectionRules(instance, service, false);
+    }
+
+    protected VtnService getVtnService(VtnServiceId serviceId) {
+        checkNotNull(osAccess, OPENSTACK_ACCESS_ERROR);
+        checkNotNull(xosAccess, XOS_ACCESS_ERROR);
+
+        // TODO remove openstack access when XOS provides all information
+        VtnServiceApi serviceApi = xosClient.getClient(xosAccess).vtnService();
+        VtnService service = serviceApi.service(serviceId, osAccess);
+        if (service == null) {
+            log.warn("Failed to get VtnService for {}", serviceId);
+        }
+        return service;
+    }
+
+    protected Set<Instance> getInstances(VtnServiceId serviceId) {
+        return StreamSupport.stream(hostService.getHosts().spliterator(), false)
+                .filter(host -> Objects.equals(
+                        serviceId.id(),
+                        host.annotations().value(Instance.SERVICE_ID)))
+                .map(Instance::of)
+                .collect(Collectors.toSet());
+    }
+
+    private void defaultConnectionRules(Instance instance, VtnService service, boolean install) {
+        long vni = service.vni();
+        Ip4Prefix serviceIpRange = service.subnet().getIp4Prefix();
+
+        inPortRule(instance, install);
+        dstIpRule(instance, vni, install);
+        tunnelInRule(instance, vni, install);
+
+        if (install) {
+            directAccessRule(serviceIpRange, serviceIpRange, true);
+            serviceIsolationRule(serviceIpRange, true);
+        } else if (getInstances(service.id()).isEmpty()) {
+            directAccessRule(serviceIpRange, serviceIpRange, false);
+            serviceIsolationRule(serviceIpRange, false);
+        }
+    }
+
+    private void managementNetworkRules(Instance instance, VtnService service, boolean install) {
+
+        managementPerInstanceRule(instance, install);
+        if (install) {
+            managementBaseRule(instance, service, true);
+        } else if (!hostService.getConnectedHosts(instance.deviceId()).stream()
+                .filter(host -> Instance.of(host).serviceId().equals(service.id()))
+                .findAny()
+                .isPresent()) {
+            managementBaseRule(instance, service, false);
+        }
+    }
+
+    private void managementBaseRule(Instance instance, VtnService service, boolean install) {
+        TrafficSelector selector = DefaultTrafficSelector.builder()
+                .matchEthType(Ethernet.TYPE_ARP)
+                .matchArpTpa(service.serviceIp().getIp4Address())
+                .build();
+
+        TrafficTreatment treatment = DefaultTrafficTreatment.builder()
+                .setOutput(PortNumber.LOCAL)
+                .build();
+
+        FlowRule flowRule = DefaultFlowRule.builder()
+                .fromApp(appId)
+                .withSelector(selector)
+                .withTreatment(treatment)
+                .withPriority(PRIORITY_MANAGEMENT)
+                .forDevice(instance.deviceId())
+                .forTable(TABLE_ZERO)
+                .makePermanent()
+                .build();
+
+        pipeline.processFlowRule(install, flowRule);
+
+        selector = DefaultTrafficSelector.builder()
+                .matchInPort(PortNumber.LOCAL)
+                .matchEthType(Ethernet.TYPE_IPV4)
+                .matchIPDst(service.subnet())
+                .build();
+
+        treatment = DefaultTrafficTreatment.builder()
+                .transition(TABLE_DST_IP)
+                .build();
+
+        flowRule = DefaultFlowRule.builder()
+                .fromApp(appId)
+                .withSelector(selector)
+                .withTreatment(treatment)
+                .withPriority(PRIORITY_MANAGEMENT)
+                .forDevice(instance.deviceId())
+                .forTable(TABLE_ZERO)
+                .makePermanent()
+                .build();
+
+        pipeline.processFlowRule(install, flowRule);
+
+        selector = DefaultTrafficSelector.builder()
+                .matchEthType(Ethernet.TYPE_IPV4)
+                .matchIPDst(service.serviceIp().toIpPrefix())
+                .build();
+
+        treatment = DefaultTrafficTreatment.builder()
+                .setOutput(PortNumber.LOCAL)
+                .build();
+
+        flowRule = DefaultFlowRule.builder()
+                .fromApp(appId)
+                .withSelector(selector)
+                .withTreatment(treatment)
+                .withPriority(PRIORITY_MANAGEMENT)
+                .forDevice(instance.deviceId())
+                .forTable(TABLE_ACCESS_TYPE)
+                .makePermanent()
+                .build();
+
+        pipeline.processFlowRule(install, flowRule);
+    }
+
+    private void managementPerInstanceRule(Instance instance, boolean install) {
+        TrafficSelector selector = DefaultTrafficSelector.builder()
+                .matchInPort(PortNumber.LOCAL)
+                .matchEthType(Ethernet.TYPE_ARP)
+                .matchArpTpa(instance.ipAddress().getIp4Address())
+                .build();
+
+        TrafficTreatment treatment = DefaultTrafficTreatment.builder()
+                .setOutput(instance.portNumber())
+                .build();
+
+        FlowRule flowRule = DefaultFlowRule.builder()
+                .fromApp(appId)
+                .withSelector(selector)
+                .withTreatment(treatment)
+                .withPriority(PRIORITY_MANAGEMENT)
+                .forDevice(instance.deviceId())
+                .forTable(TABLE_ZERO)
+                .makePermanent()
+                .build();
+
+        pipeline.processFlowRule(install, flowRule);
+    }
+
+    private void inPortRule(Instance instance, boolean install) {
+        TrafficSelector selector = DefaultTrafficSelector.builder()
+                .matchInPort(instance.portNumber())
+                .matchEthType(Ethernet.TYPE_IPV4)
+                .matchIPSrc(instance.ipAddress().toIpPrefix())
+                .build();
+
+        TrafficTreatment treatment = DefaultTrafficTreatment.builder()
+                .transition(TABLE_ACCESS_TYPE)
+                .build();
+
+
+        FlowRule flowRule = DefaultFlowRule.builder()
+                .fromApp(appId)
+                .withSelector(selector)
+                .withTreatment(treatment)
+                .withPriority(PRIORITY_DEFAULT)
+                .forDevice(instance.deviceId())
+                .forTable(TABLE_IN_PORT)
+                .makePermanent()
+                .build();
+
+        pipeline.processFlowRule(install, flowRule);
+
+        selector = DefaultTrafficSelector.builder()
+                .matchInPort(instance.portNumber())
+                .build();
+
+        treatment = DefaultTrafficTreatment.builder()
+                .transition(TABLE_IN_SERVICE)
+                .build();
+
+        flowRule = DefaultFlowRule.builder()
+                .fromApp(appId)
+                .withSelector(selector)
+                .withTreatment(treatment)
+                .withPriority(PRIORITY_LOW)
+                .forDevice(instance.deviceId())
+                .forTable(TABLE_IN_PORT)
+                .makePermanent()
+                .build();
+
+        pipeline.processFlowRule(install, flowRule);
+    }
+
+    private void dstIpRule(Instance instance, long vni, boolean install) {
+        Ip4Address tunnelIp = nodeManager.dpIp(instance.deviceId()).getIp4Address();
+
+        TrafficSelector selector = DefaultTrafficSelector.builder()
+                .matchEthType(Ethernet.TYPE_IPV4)
+                .matchIPDst(instance.ipAddress().toIpPrefix())
+                .build();
+
+        TrafficTreatment treatment = DefaultTrafficTreatment.builder()
+                .setEthDst(instance.mac())
+                .setOutput(instance.portNumber())
+                .build();
+
+        FlowRule flowRule = DefaultFlowRule.builder()
+                .fromApp(appId)
+                .withSelector(selector)
+                .withTreatment(treatment)
+                .withPriority(PRIORITY_DEFAULT)
+                .forDevice(instance.deviceId())
+                .forTable(TABLE_DST_IP)
+                .makePermanent()
+                .build();
+
+        pipeline.processFlowRule(install, flowRule);
+
+        for (CordVtnNode node : nodeManager.completeNodes()) {
+            if (node.intBrId().equals(instance.deviceId())) {
+                continue;
+            }
+
+            ExtensionTreatment tunnelDst = pipeline.tunnelDstTreatment(node.intBrId(), tunnelIp);
+            if (tunnelDst == null) {
+                continue;
+            }
+
+            treatment = DefaultTrafficTreatment.builder()
+                    .setEthDst(instance.mac())
+                    .setTunnelId(vni)
+                    .extension(tunnelDst, node.intBrId())
+                    .setOutput(nodeManager.tunnelPort(node.intBrId()))
+                    .build();
+
+            flowRule = DefaultFlowRule.builder()
+                    .fromApp(appId)
+                    .withSelector(selector)
+                    .withTreatment(treatment)
+                    .withPriority(PRIORITY_DEFAULT)
+                    .forDevice(node.intBrId())
+                    .forTable(TABLE_DST_IP)
+                    .makePermanent()
+                    .build();
+
+            pipeline.processFlowRule(install, flowRule);
+        }
+    }
+
+    private void tunnelInRule(Instance instance, long vni, boolean install) {
+        TrafficSelector selector = DefaultTrafficSelector.builder()
+                .matchTunnelId(vni)
+                .matchEthDst(instance.mac())
+                .build();
+
+        TrafficTreatment treatment = DefaultTrafficTreatment.builder()
+                .setOutput(instance.portNumber())
+                .build();
+
+        FlowRule flowRule = DefaultFlowRule.builder()
+                .fromApp(appId)
+                .withSelector(selector)
+                .withTreatment(treatment)
+                .withPriority(PRIORITY_DEFAULT)
+                .forDevice(instance.deviceId())
+                .forTable(TABLE_TUNNEL_IN)
+                .makePermanent()
+                .build();
+
+        pipeline.processFlowRule(install, flowRule);
+    }
+
+    private void directAccessRule(Ip4Prefix srcRange, Ip4Prefix dstRange, boolean install) {
+        TrafficSelector selector = DefaultTrafficSelector.builder()
+                .matchEthType(Ethernet.TYPE_IPV4)
+                .matchIPSrc(srcRange)
+                .matchIPDst(dstRange)
+                .build();
+
+        TrafficTreatment treatment = DefaultTrafficTreatment.builder()
+                .transition(TABLE_DST_IP)
+                .build();
+
+
+        nodeManager.completeNodes().stream().forEach(node -> {
+            FlowRule flowRuleDirect = DefaultFlowRule.builder()
+                    .fromApp(appId)
+                    .withSelector(selector)
+                    .withTreatment(treatment)
+                    .withPriority(PRIORITY_DEFAULT)
+                    .forDevice(node.intBrId())
+                    .forTable(TABLE_ACCESS_TYPE)
+                    .makePermanent()
+                    .build();
+
+            pipeline.processFlowRule(install, flowRuleDirect);
+        });
+    }
+
+    private void serviceIsolationRule(Ip4Prefix dstRange, boolean install) {
+        TrafficSelector selector = DefaultTrafficSelector.builder()
+                .matchEthType(Ethernet.TYPE_IPV4)
+                .matchIPDst(dstRange)
+                .build();
+
+        TrafficTreatment treatment = DefaultTrafficTreatment.builder()
+                .drop()
+                .build();
+
+        nodeManager.completeNodes().stream().forEach(node -> {
+            FlowRule flowRuleDirect = DefaultFlowRule.builder()
+                    .fromApp(appId)
+                    .withSelector(selector)
+                    .withTreatment(treatment)
+                    .withPriority(PRIORITY_LOW)
+                    .forDevice(node.intBrId())
+                    .forTable(TABLE_ACCESS_TYPE)
+                    .makePermanent()
+                    .build();
+
+            pipeline.processFlowRule(install, flowRuleDirect);
+        });
+    }
+
+    protected void readConfiguration() {
+        CordVtnConfig config = configRegistry.getConfig(appId, CordVtnConfig.class);
+        if (config == null) {
+            log.debug("No configuration found");
+            return;
+        }
+        osAccess = config.openstackAccess();
+        xosAccess = config.xosAccess();
+    }
+
+    public class InternalHostListener implements HostListener {
+
+        @Override
+        public void event(HostEvent event) {
+            Host host = event.subject();
+            if (!mastershipService.isLocalMaster(host.location().deviceId())) {
+                // do not allow to proceed without mastership
+                return;
+            }
+
+            Instance instance = Instance.of(host);
+            if (!Objects.equals(instance.serviceType(), serviceType)) {
+                // not my service instance, do nothing
+                return;
+            }
+
+            switch (event.type()) {
+                case HOST_UPDATED:
+                case HOST_ADDED:
+                    eventExecutor.execute(() -> instanceDetected(instance));
+                    break;
+                case HOST_REMOVED:
+                    eventExecutor.execute(() -> instanceRemoved(instance));
+                    break;
+                default:
+                    break;
+            }
+        }
+    }
+
+    public class InternalConfigListener implements NetworkConfigListener {
+
+        @Override
+        public void event(NetworkConfigEvent event) {
+            if (!event.configClass().equals(CordVtnConfig.class)) {
+                return;
+            }
+
+            switch (event.type()) {
+                case CONFIG_ADDED:
+                case CONFIG_UPDATED:
+                    readConfiguration();
+                    break;
+                default:
+                    break;
+            }
+        }
+    }
+}
diff --git a/src/main/java/org/onosproject/cordvtn/impl/CordVtnInstanceManager.java b/src/main/java/org/onosproject/cordvtn/impl/CordVtnInstanceManager.java
new file mode 100644
index 0000000..3ca7361
--- /dev/null
+++ b/src/main/java/org/onosproject/cordvtn/impl/CordVtnInstanceManager.java
@@ -0,0 +1,438 @@
+/*
+ * Copyright 2015-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.cordvtn.impl;
+
+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;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.apache.felix.scr.annotations.Service;
+import org.onlab.packet.Ethernet;
+import org.onlab.packet.Ip4Address;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.VlanId;
+import org.onosproject.cordvtn.api.CordVtnConfig;
+import org.onosproject.cordvtn.api.CordVtnService;
+import org.onosproject.cordvtn.api.Instance;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreService;
+import org.onosproject.dhcp.DhcpService;
+import org.onosproject.dhcp.IpAssignment;
+import org.onosproject.mastership.MastershipService;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DefaultAnnotations;
+import org.onosproject.net.Host;
+import org.onosproject.net.HostId;
+import org.onosproject.net.HostLocation;
+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.basics.SubjectFactories;
+import org.onosproject.net.device.DeviceService;
+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.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.xosclient.api.OpenStackAccess;
+import org.onosproject.xosclient.api.VtnPort;
+import org.onosproject.xosclient.api.VtnPortApi;
+import org.onosproject.xosclient.api.VtnService;
+import org.onosproject.xosclient.api.VtnServiceApi;
+import org.onosproject.xosclient.api.VtnServiceId;
+import org.onosproject.xosclient.api.XosAccess;
+import org.onosproject.xosclient.api.XosClientService;
+import org.slf4j.Logger;
+
+import java.util.Date;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+import java.util.concurrent.ExecutorService;
+import java.util.stream.Collectors;
+import java.util.stream.StreamSupport;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static java.util.concurrent.Executors.newSingleThreadScheduledExecutor;
+import static org.onlab.util.Tools.groupedThreads;
+import static org.onosproject.cordvtn.api.Instance.*;
+import static org.onosproject.dhcp.IpAssignment.AssignmentStatus.Option_RangeNotEnforced;
+import static org.onosproject.xosclient.api.VtnService.NetworkType.MANAGEMENT;
+import static org.onosproject.xosclient.api.VtnService.NetworkType.PRIVATE;
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * Adds or removes instances to network services.
+ */
+@Component(immediate = true)
+@Service(value = CordVtnInstanceManager.class)
+public class CordVtnInstanceManager extends AbstractProvider implements HostProvider {
+
+    protected final Logger log = getLogger(getClass());
+
+    private static final String XOS_ACCESS_ERROR = "XOS access is not configured";
+    private static final String OPENSTACK_ACCESS_ERROR = "OpenStack access is not configured";
+    private static final Ip4Address DEFAULT_DNS = Ip4Address.valueOf("8.8.8.8");
+    private static final int DHCP_INFINITE_LEASE = -1;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected CoreService coreService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected NetworkConfigRegistry configRegistry;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected HostProviderRegistry hostProviderRegistry;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected DeviceService deviceService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected HostService hostService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected PacketService packetService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected DhcpService dhcpService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected MastershipService mastershipService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected XosClientService xosClient;
+
+    private final ConfigFactory configFactory =
+            new ConfigFactory(SubjectFactories.APP_SUBJECT_FACTORY, CordVtnConfig.class, "cordvtn") {
+                @Override
+                public CordVtnConfig createConfig() {
+                    return new CordVtnConfig();
+                }
+            };
+
+    private final ExecutorService eventExecutor =
+            newSingleThreadScheduledExecutor(groupedThreads("onos/cordvtn-instance", "event-handler"));
+    private final PacketProcessor packetProcessor = new InternalPacketProcessor();
+    private final HostListener hostListener = new InternalHostListener();
+    private final NetworkConfigListener configListener = new InternalConfigListener();
+
+    private ApplicationId appId;
+    private HostProviderService hostProvider;
+    private CordVtnArpProxy arpProxy; // TODO make it a component service
+    private MacAddress privateGatewayMac = MacAddress.NONE;
+    private XosAccess xosAccess = null;
+    private OpenStackAccess osAccess = null;
+
+    /**
+     * Creates an cordvtn host location provider.
+     */
+    public CordVtnInstanceManager() {
+        super(new ProviderId("host", CordVtnService.CORDVTN_APP_ID));
+    }
+
+    @Activate
+    protected void activate() {
+        appId = coreService.registerApplication(CordVtnService.CORDVTN_APP_ID);
+
+        arpProxy = new CordVtnArpProxy(appId, packetService, hostService);
+        packetService.addProcessor(packetProcessor, PacketProcessor.director(0));
+        arpProxy.requestPacket();
+
+        hostService.addListener(hostListener);
+        hostProvider = hostProviderRegistry.register(this);
+
+        configRegistry.registerConfigFactory(configFactory);
+        configRegistry.addListener(configListener);
+
+        log.info("Started");
+    }
+
+    @Deactivate
+    protected void deactivate() {
+        hostProviderRegistry.unregister(this);
+        hostService.removeListener(hostListener);
+
+        packetService.removeProcessor(packetProcessor);
+
+        configRegistry.unregisterConfigFactory(configFactory);
+        configRegistry.removeListener(configListener);
+
+        eventExecutor.shutdown();
+        log.info("Stopped");
+    }
+
+    @Override
+    public void triggerProbe(Host host) {
+        /*
+         * Note: In CORD deployment, we assume that all hosts are configured.
+         * Therefore no probe is required.
+         */
+    }
+
+    /**
+     * Adds a service instance at a given connect point.
+     *
+     * @param connectPoint connect point of the instance
+     */
+    public void addInstance(ConnectPoint connectPoint) {
+        Port port = deviceService.getPort(connectPoint.deviceId(), connectPoint.port());
+        if (port == null) {
+            log.debug("No port found from {}", connectPoint);
+            return;
+        }
+
+        VtnPort vtnPort = getVtnPort(port.annotations().value("portName"));
+        if (vtnPort == null) {
+            return;
+        }
+
+        VtnService vtnService = getVtnService(vtnPort.serviceId());
+        if (vtnService == null) {
+            return;
+        }
+
+        // Added CREATE_TIME intentionally to trigger HOST_UPDATED event for the
+        // existing instances.
+        DefaultAnnotations.Builder annotations = DefaultAnnotations.builder()
+                .set(SERVICE_TYPE, vtnService.serviceType().toString())
+                .set(SERVICE_ID, vtnPort.serviceId().id())
+                .set(PORT_ID, vtnPort.id().id())
+                .set(CREATE_TIME, String.valueOf(System.currentTimeMillis()));
+
+        HostDescription hostDesc = new DefaultHostDescription(
+                vtnPort.mac(),
+                VlanId.NONE,
+                new HostLocation(connectPoint, System.currentTimeMillis()),
+                Sets.newHashSet(vtnPort.ip()),
+                annotations.build());
+
+        HostId hostId = HostId.hostId(vtnPort.mac());
+        hostProvider.hostDetected(hostId, hostDesc, false);
+    }
+
+    /**
+     * Adds a service instance with given host ID and host description.
+     *
+     * @param hostId host id
+     * @param description host description
+     */
+    public void addInstance(HostId hostId, HostDescription description) {
+        hostProvider.hostDetected(hostId, description, false);
+    }
+
+    /**
+     * Removes a service instance from a given connect point.
+     *
+     * @param connectPoint connect point
+     */
+    public void removeInstance(ConnectPoint connectPoint) {
+        hostService.getConnectedHosts(connectPoint)
+                .stream()
+                .forEach(host -> hostProvider.hostVanished(host.id()));
+    }
+
+    /**
+     * Removes service instance with given host ID.
+     *
+     * @param hostId host id
+     */
+    public void removeInstance(HostId hostId) {
+        hostProvider.hostVanished(hostId);
+    }
+
+    private void instanceDetected(Instance instance) {
+        VtnService service = getVtnService(instance.serviceId());
+        if (service == null) {
+            return;
+        }
+
+        if (service.networkType().equals(PRIVATE)) {
+            arpProxy.addGateway(service.serviceIp(), privateGatewayMac);
+            arpProxy.sendGratuitousArpForGateway(service.serviceIp(), Sets.newHashSet(instance));
+        }
+        if (!instance.isNestedInstance()) {
+            registerDhcpLease(instance, service);
+        }
+    }
+
+    private void instanceRemoved(Instance instance) {
+        VtnService service = getVtnService(instance.serviceId());
+        if (service == null) {
+            return;
+        }
+
+        if (service.networkType().equals(PRIVATE) && getInstances(service.id()).isEmpty()) {
+            arpProxy.removeGateway(service.serviceIp());
+        }
+
+        if (!instance.isNestedInstance()) {
+            dhcpService.removeStaticMapping(instance.mac());
+        }
+    }
+
+    private void registerDhcpLease(Instance instance, VtnService service) {
+        Ip4Address broadcast = Ip4Address.makeMaskedAddress(
+                instance.ipAddress(),
+                service.subnet().prefixLength());
+
+        IpAssignment.Builder ipBuilder = IpAssignment.builder()
+                .ipAddress(instance.ipAddress())
+                .leasePeriod(DHCP_INFINITE_LEASE)
+                .timestamp(new Date())
+                .subnetMask(Ip4Address.makeMaskPrefix(service.subnet().prefixLength()))
+                .broadcast(broadcast)
+                .domainServer(DEFAULT_DNS)
+                .assignmentStatus(Option_RangeNotEnforced);
+
+        if (service.networkType() != MANAGEMENT) {
+            ipBuilder = ipBuilder.routerAddress(service.serviceIp().getIp4Address());
+        }
+
+        log.debug("Set static DHCP mapping for {} {}", instance.mac(), instance.ipAddress());
+        dhcpService.setStaticMapping(instance.mac(), ipBuilder.build());
+    }
+
+    private VtnService getVtnService(VtnServiceId serviceId) {
+        checkNotNull(osAccess, OPENSTACK_ACCESS_ERROR);
+        checkNotNull(xosAccess, XOS_ACCESS_ERROR);
+
+        // TODO remove openstack access when XOS provides all information
+        VtnServiceApi serviceApi = xosClient.getClient(xosAccess).vtnService();
+        VtnService service = serviceApi.service(serviceId, osAccess);
+        if (service == null) {
+            log.warn("Failed to get VtnService for {}", serviceId);
+        }
+        return service;
+    }
+
+    private VtnPort getVtnPort(String portName) {
+        checkNotNull(osAccess, OPENSTACK_ACCESS_ERROR);
+        checkNotNull(xosAccess, XOS_ACCESS_ERROR);
+
+        // TODO remove openstack access when XOS provides all information
+        VtnPortApi portApi = xosClient.getClient(xosAccess).vtnPort();
+        VtnPort vtnPort = portApi.vtnPort(portName, osAccess);
+        if (vtnPort == null) {
+            log.warn("Failed to get port information of {}", portName);
+        }
+        return vtnPort;
+    }
+
+    private Set<Instance> getInstances(VtnServiceId serviceId) {
+        return StreamSupport.stream(hostService.getHosts().spliterator(), false)
+                .filter(host -> Objects.equals(
+                        serviceId.id(),
+                        host.annotations().value(Instance.SERVICE_ID)))
+                .map(Instance::of)
+                .collect(Collectors.toSet());
+    }
+
+    private void readConfiguration() {
+        CordVtnConfig config = configRegistry.getConfig(appId, CordVtnConfig.class);
+        if (config == null) {
+            log.debug("No configuration found");
+            return;
+        }
+
+        log.info("Load CORD-VTN configurations");
+
+        xosAccess = config.xosAccess();
+        osAccess = config.openstackAccess();
+        privateGatewayMac = config.privateGatewayMac();
+
+        Map<IpAddress, MacAddress> publicGateways = config.publicGateways();
+        publicGateways.entrySet()
+                .stream()
+                .forEach(entry -> {
+                    arpProxy.addGateway(entry.getKey(), entry.getValue());
+                    log.debug("Added public gateway IP {}, MAC {}",
+                              entry.getKey(), entry.getValue());
+                });
+        // TODO notice gateway MAC change to VMs holds this gateway IP
+    }
+
+    private class InternalHostListener implements HostListener {
+
+        @Override
+        public void event(HostEvent event) {
+            Host host = event.subject();
+            if (!mastershipService.isLocalMaster(host.location().deviceId())) {
+                // do not allow to proceed without mastership
+                return;
+            }
+
+            Instance instance = Instance.of(host);
+            switch (event.type()) {
+                case HOST_UPDATED:
+                case HOST_ADDED:
+                    eventExecutor.execute(() -> instanceDetected(instance));
+                    break;
+                case HOST_REMOVED:
+                    eventExecutor.execute(() -> instanceRemoved(instance));
+                    break;
+                default:
+                    break;
+            }
+        }
+    }
+
+    private class InternalPacketProcessor implements PacketProcessor {
+
+        @Override
+        public void process(PacketContext context) {
+            if (context.isHandled()) {
+                return;
+            }
+            Ethernet ethPacket = context.inPacket().parsed();
+            if (ethPacket == null || ethPacket.getEtherType() != Ethernet.TYPE_ARP) {
+                return;
+            }
+            arpProxy.processArpPacket(context, ethPacket);
+        }
+    }
+
+    private class InternalConfigListener implements NetworkConfigListener {
+
+        @Override
+        public void event(NetworkConfigEvent event) {
+            if (!event.configClass().equals(CordVtnConfig.class)) {
+                return;
+            }
+
+            switch (event.type()) {
+                case CONFIG_ADDED:
+                case CONFIG_UPDATED:
+                    readConfiguration();
+                    break;
+                default:
+                    break;
+            }
+        }
+    }
+}
diff --git a/src/main/java/org/onosproject/cordvtn/impl/CordVtnNodeManager.java b/src/main/java/org/onosproject/cordvtn/impl/CordVtnNodeManager.java
new file mode 100644
index 0000000..7fa6c5c
--- /dev/null
+++ b/src/main/java/org/onosproject/cordvtn/impl/CordVtnNodeManager.java
@@ -0,0 +1,1029 @@
+/*
+ * 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.cordvtn.impl;
+
+import com.google.common.collect.Sets;
+import com.jcraft.jsch.Session;
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Deactivate;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.apache.felix.scr.annotations.Service;
+import org.onlab.packet.IpAddress;
+import org.onlab.util.ItemNotFoundException;
+import org.onlab.util.KryoNamespace;
+import org.onosproject.cluster.ClusterService;
+import org.onosproject.cluster.LeadershipService;
+import org.onosproject.cluster.NodeId;
+import org.onosproject.cordvtn.api.ConnectionHandler;
+import org.onosproject.cordvtn.api.CordVtnConfig;
+import org.onosproject.cordvtn.api.CordVtnNode;
+import org.onosproject.cordvtn.api.CordVtnNodeState;
+import org.onosproject.cordvtn.api.CordVtnService;
+import org.onosproject.cordvtn.api.NetworkAddress;
+import org.onosproject.cordvtn.api.SshAccessInfo;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreService;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DefaultAnnotations;
+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.BridgeConfig;
+import org.onosproject.net.behaviour.BridgeName;
+import org.onosproject.net.behaviour.ControllerInfo;
+import org.onosproject.net.behaviour.DefaultTunnelDescription;
+import org.onosproject.net.behaviour.TunnelConfig;
+import org.onosproject.net.behaviour.TunnelDescription;
+import org.onosproject.net.behaviour.TunnelName;
+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.DeviceAdminService;
+import org.onosproject.net.device.DeviceEvent;
+import org.onosproject.net.device.DeviceListener;
+import org.onosproject.net.device.DeviceService;
+import org.onosproject.net.host.HostService;
+import org.onosproject.ovsdb.controller.OvsdbClientService;
+import org.onosproject.ovsdb.controller.OvsdbController;
+import org.onosproject.ovsdb.controller.OvsdbNodeId;
+import org.onosproject.store.serializers.KryoNamespaces;
+import org.onosproject.store.service.ConsistentMap;
+import org.onosproject.store.service.MapEvent;
+import org.onosproject.store.service.MapEventListener;
+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;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+import java.util.concurrent.ExecutorService;
+import java.util.stream.Collectors;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static java.util.concurrent.Executors.newSingleThreadScheduledExecutor;
+import static org.onlab.util.Tools.groupedThreads;
+import static org.onosproject.cordvtn.impl.CordVtnPipeline.DEFAULT_TUNNEL;
+import static org.onosproject.cordvtn.impl.RemoteIpCommandUtil.*;
+import static org.onosproject.net.Device.Type.SWITCH;
+import static org.onosproject.net.behaviour.TunnelDescription.Type.VXLAN;
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * Reads node information from the network config file and handles the config
+ * update events.
+ * Only a leader controller performs the node addition or deletion.
+ */
+@Component(immediate = true)
+@Service(value = CordVtnNodeManager.class)
+public class CordVtnNodeManager {
+
+    protected final Logger log = getLogger(getClass());
+
+    private static final KryoNamespace.Builder NODE_SERIALIZER = KryoNamespace.newBuilder()
+            .register(KryoNamespaces.API)
+            .register(CordVtnNode.class)
+            .register(NodeState.class)
+            .register(SshAccessInfo.class)
+            .register(NetworkAddress.class);
+
+    private static final String DEFAULT_BRIDGE = "br-int";
+    private static final String VPORT_PREFIX = "tap";
+    private static final String OK = "OK";
+    private static final String NO = "NO";
+
+    private static final Map<String, String> DEFAULT_TUNNEL_OPTIONS = new HashMap<String, String>() {
+        {
+            put("key", "flow");
+            put("remote_ip", "flow");
+        }
+    };
+    private static final int DPID_BEGIN = 3;
+    private static final int OFPORT = 6653;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected CoreService coreService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected NetworkConfigRegistry configRegistry;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected NetworkConfigService configService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected StorageService storageService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected DeviceAdminService adminService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected OvsdbController controller;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected ClusterService clusterService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected DeviceService deviceService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected HostService hostService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected LeadershipService leadershipService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected CordVtnInstanceManager instanceManager;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected CordVtnPipeline pipeline;
+
+    private final ExecutorService eventExecutor =
+            newSingleThreadScheduledExecutor(groupedThreads("onos/cordvtn-node", "event-handler"));
+
+    private final NetworkConfigListener configListener = new InternalConfigListener();
+    private final DeviceListener deviceListener = new InternalDeviceListener();
+    private final MapEventListener<String, CordVtnNode> nodeStoreListener = new InternalMapListener();
+
+    private final OvsdbHandler ovsdbHandler = new OvsdbHandler();
+    private final BridgeHandler bridgeHandler = new BridgeHandler();
+
+    private ConsistentMap<String, CordVtnNode> nodeStore;
+    private ApplicationId appId;
+    private NodeId localNodeId;
+
+    private enum NodeState implements CordVtnNodeState {
+
+        INIT {
+            @Override
+            public void process(CordVtnNodeManager nodeManager, CordVtnNode node) {
+                if (!nodeManager.isOvsdbConnected(node)) {
+                    nodeManager.connectOvsdb(node);
+                } else {
+                    nodeManager.createIntegrationBridge(node);
+                }
+            }
+        },
+        BRIDGE_CREATED {
+            @Override
+            public void process(CordVtnNodeManager nodeManager, CordVtnNode node) {
+                if (!nodeManager.isOvsdbConnected(node)) {
+                    nodeManager.connectOvsdb(node);
+                } else {
+                    nodeManager.createTunnelInterface(node);
+                    nodeManager.addDataPlaneInterface(node);
+                }
+            }
+        },
+        PORTS_ADDED {
+            @Override
+            public void process(CordVtnNodeManager nodeManager, CordVtnNode node) {
+                nodeManager.setIpAddress(node);
+            }
+        },
+        COMPLETE {
+            @Override
+            public void process(CordVtnNodeManager nodeManager, CordVtnNode node) {
+                nodeManager.postInit(node);
+            }
+        },
+        INCOMPLETE {
+            @Override
+            public void process(CordVtnNodeManager nodeManager, CordVtnNode node) {
+            }
+        };
+
+        public abstract void process(CordVtnNodeManager nodeManager, CordVtnNode node);
+    }
+
+    @Activate
+    protected void activate() {
+        appId = coreService.getAppId(CordVtnService.CORDVTN_APP_ID);
+
+        localNodeId = clusterService.getLocalNode().id();
+        leadershipService.runForLeadership(appId.name());
+
+        nodeStore = storageService.<String, CordVtnNode>consistentMapBuilder()
+                .withSerializer(Serializer.using(NODE_SERIALIZER.build()))
+                .withName("cordvtn-nodestore")
+                .withApplicationId(appId)
+                .build();
+
+        nodeStore.addListener(nodeStoreListener);
+        deviceService.addListener(deviceListener);
+        configService.addListener(configListener);
+
+        log.info("Started");
+    }
+
+    @Deactivate
+    protected void deactivate() {
+        configService.removeListener(configListener);
+        deviceService.removeListener(deviceListener);
+        nodeStore.removeListener(nodeStoreListener);
+
+        leadershipService.withdraw(appId.name());
+        eventExecutor.shutdown();
+
+        log.info("Stopped");
+    }
+
+    /**
+     * Adds or updates a new node to the service.
+     *
+     * @param node cordvtn node
+     */
+    public void addOrUpdateNode(CordVtnNode node) {
+        checkNotNull(node);
+        nodeStore.put(node.hostname(), CordVtnNode.getUpdatedNode(node, getNodeState(node)));
+    }
+
+    /**
+     * Deletes a node from the service.
+     *
+     * @param node cordvtn node
+     */
+    public void deleteNode(CordVtnNode node) {
+        checkNotNull(node);
+
+        if (isOvsdbConnected(node)) {
+            disconnectOvsdb(node);
+        }
+
+        nodeStore.remove(node.hostname());
+    }
+
+    /**
+     * Returns node initialization state.
+     *
+     * @param node cordvtn node
+     * @return true if initial node setup is completed, otherwise false
+     */
+    public boolean isNodeInitComplete(CordVtnNode node) {
+        checkNotNull(node);
+        return nodeStore.containsKey(node.hostname()) && getNodeState(node).equals(NodeState.COMPLETE);
+    }
+
+    /**
+     * Returns detailed node initialization state.
+     *
+     * @param node cordvtn node
+     * @return string including detailed node init state
+     */
+    public String checkNodeInitState(CordVtnNode node) {
+        checkNotNull(node);
+
+        if (!nodeStore.containsKey(node.hostname())) {
+            log.warn("Node {} does not exist, add node first", node.hostname());
+            return null;
+        }
+
+        Session session = connect(node.sshInfo());
+        if (session == null) {
+            log.debug("Failed to SSH to {}", node.hostname());
+            return null;
+        }
+
+        Set<IpAddress> intBrIps = getCurrentIps(session, DEFAULT_BRIDGE);
+        String result = String.format(
+                "Current state : %s%n" +
+                        "br-int created and connected to ONOS : %s (%s)%n" +
+                        "VXLAN interface added to br-int : %s%n" +
+                        "Data plane interface is added to br-int and enabled : %s (%s)%n" +
+                        "IP flushed from data plane interface : %s (%s)%n" +
+                        "Data plane IP added to br-int : %s (%s)%n" +
+                        "Local management IP added to br-int : %s (%s)",
+                node.state(),
+                isBrIntCreated(node) ? OK : NO, node.intBrId(),
+                isTunnelIntfCreated(node) ? OK : NO,
+                isDataPlaneIntfAdded(node) ? OK : NO, node.dpIntf(),
+                isInterfaceUp(session, node.dpIntf()) &&
+                        getCurrentIps(session, node.dpIntf()).isEmpty() ? OK : NO, node.dpIntf(),
+                intBrIps.contains(node.dpIp().ip()) ? OK : NO, node.dpIp().cidr(),
+                intBrIps.contains(node.localMgmtIp().ip()) ? OK : NO, node.localMgmtIp().cidr());
+
+        disconnect(session);
+
+        return result;
+    }
+
+    /**
+     * Returns the number of the nodes known to the service.
+     *
+     * @return number of nodes
+     */
+    public int getNodeCount() {
+        return nodeStore.size();
+    }
+
+    /**
+     * Returns all nodes known to the service.
+     *
+     * @return list of nodes
+     */
+    public List<CordVtnNode> getNodes() {
+        return nodeStore.values().stream().map(Versioned::value).collect(Collectors.toList());
+    }
+
+    /**
+     * Returns all nodes in complete state.
+     *
+     * @return set of nodes
+     */
+    public Set<CordVtnNode> completeNodes() {
+        return getNodes().stream().filter(this::isNodeInitComplete).collect(Collectors.toSet());
+    }
+
+    /**
+     * Returns physical data plane port number of a given device.
+     *
+     * @param deviceId integration bridge device id
+     * @return port number; null otherwise
+     */
+    public PortNumber dpPort(DeviceId deviceId) {
+        CordVtnNode node = nodeByBridgeId(deviceId);
+        if (node == null) {
+            log.warn("Failed to get node for {}", deviceId);
+            return null;
+        }
+        Port port = deviceService.getPorts(deviceId).stream()
+                .filter(p -> portName(p).contains(node.dpIntf()) &&
+                        p.isEnabled())
+                .findFirst().orElse(null);
+
+        return port == null ? null : port.number();
+    }
+
+    /**
+     * Returns physical data plane IP address of a given device.
+     *
+     * @param deviceId integration bridge device id
+     * @return ip address; null otherwise
+     */
+    public IpAddress dpIp(DeviceId deviceId) {
+        CordVtnNode node = nodeByBridgeId(deviceId);
+        if (node == null) {
+            log.warn("Failed to get node for {}", deviceId);
+            return null;
+        }
+        return node.dpIp().ip();
+    }
+
+    /**
+     * Returns tunnel port number of a given device.
+     *
+     * @param deviceId integration bridge device id
+     * @return port number
+     */
+    public PortNumber tunnelPort(DeviceId deviceId) {
+        Port port = deviceService.getPorts(deviceId).stream()
+                .filter(p -> portName(p).contains(DEFAULT_TUNNEL))
+                .findFirst().orElse(null);
+
+        return port == null ? null : port.number();
+    }
+
+    /**
+     * Returns if current node state saved in nodeStore is COMPLETE or not.
+     *
+     * @param node cordvtn node
+     * @return true if it's complete state, otherwise false
+     */
+    private boolean isNodeStateComplete(CordVtnNode node) {
+        checkNotNull(node);
+
+        // the state saved in nodeStore can be wrong if IP address settings are changed
+        // after the node init has been completed since there's no way to detect it
+        // getNodeState and checkNodeInitState always return correct answer but can be slow
+        Versioned<CordVtnNode> versionedNode = nodeStore.get(node.hostname());
+        CordVtnNodeState state = versionedNode.value().state();
+        return state != null && state.equals(NodeState.COMPLETE);
+    }
+
+    /**
+     * Initiates node to serve virtual tenant network.
+     *
+     * @param node cordvtn node
+     */
+    private void initNode(CordVtnNode node) {
+        checkNotNull(node);
+
+        NodeState state = (NodeState) node.state();
+        log.debug("Processing node: {} state: {}", node.hostname(), state);
+
+        state.process(this, node);
+    }
+
+    /**
+     * Performs tasks after node initialization.
+     * It disconnects unnecessary OVSDB connection and installs initial flow
+     * rules on the device.
+     *
+     * @param node cordvtn node
+     */
+    private void postInit(CordVtnNode node) {
+        disconnectOvsdb(node);
+        pipeline.initPipeline(node, dpPort(node.intBrId()), tunnelPort(node.intBrId()));
+
+        deviceService.getPorts(node.intBrId()).stream()
+                .filter(port -> portName(port).startsWith(VPORT_PREFIX) &&
+                        port.isEnabled())
+                .forEach(port -> instanceManager.addInstance(connectPoint(port)));
+
+        hostService.getHosts().forEach(host -> {
+            if (deviceService.getPort(host.location().deviceId(),
+                                      host.location().port()) == null) {
+                instanceManager.removeInstance(connectPoint(host));
+            }
+        });
+
+        log.info("Finished init {}", node.hostname());
+    }
+
+    /**
+     * 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.debug("Changed {} state: {}", node.hostname(), newState);
+        nodeStore.put(node.hostname(), CordVtnNode.getUpdatedNode(node, newState));
+    }
+
+    /**
+     * Checks current state of a given cordvtn node and returns it.
+     *
+     * @param node cordvtn node
+     * @return node state
+     */
+    private NodeState getNodeState(CordVtnNode node) {
+        checkNotNull(node);
+
+        if (isBrIntCreated(node) && isTunnelIntfCreated(node) &&
+                isDataPlaneIntfAdded(node) && isIpAddressSet(node)) {
+            return NodeState.COMPLETE;
+        } else if (isDataPlaneIntfAdded(node) && isTunnelIntfCreated(node)) {
+            return NodeState.PORTS_ADDED;
+        } else if (isBrIntCreated(node)) {
+            return NodeState.BRIDGE_CREATED;
+        } else {
+            return NodeState.INIT;
+        }
+    }
+
+    /**
+     * Returns connection state of OVSDB server for a given node.
+     *
+     * @param node cordvtn node
+     * @return true if it is connected, false otherwise
+     */
+    private boolean isOvsdbConnected(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 connectOvsdb(CordVtnNode node) {
+        checkNotNull(node);
+
+        if (!nodeStore.containsKey(node.hostname())) {
+            log.warn("Node {} does not exist", node.hostname());
+            return;
+        }
+
+        if (!isOvsdbConnected(node)) {
+            controller.connect(node.hostMgmtIp().ip(), node.ovsdbPort());
+        }
+    }
+
+    /**
+     * Disconnects OVSDB server for a given node.
+     *
+     * @param node cordvtn node
+     */
+    private void disconnectOvsdb(CordVtnNode node) {
+        checkNotNull(node);
+
+        if (!nodeStore.containsKey(node.hostname())) {
+            log.warn("Node {} does not exist", node.hostname());
+            return;
+        }
+
+        if (isOvsdbConnected(node)) {
+            OvsdbClientService ovsdbClient = getOvsdbClient(node);
+            ovsdbClient.disconnect();
+        }
+    }
+
+    /**
+     * 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(node.hostMgmtIp().ip(), node.ovsdbPort().toInt()));
+        if (ovsdbClient == null) {
+            log.trace("Couldn't find OVSDB client for {}", node.hostname());
+        }
+        return ovsdbClient;
+    }
+
+    /**
+     * Creates an integration bridge for a given node.
+     *
+     * @param node cordvtn node
+     */
+    private void createIntegrationBridge(CordVtnNode node) {
+        if (isBrIntCreated(node)) {
+            return;
+        }
+
+        List<ControllerInfo> controllers = new ArrayList<>();
+        Sets.newHashSet(clusterService.getNodes()).stream()
+                .forEach(controller -> {
+                    ControllerInfo ctrlInfo = new ControllerInfo(controller.ip(), OFPORT, "tcp");
+                    controllers.add(ctrlInfo);
+                });
+
+        String dpid = node.intBrId().toString().substring(DPID_BEGIN);
+
+        try {
+            Device device = deviceService.getDevice(node.ovsdbId());
+            if (device.is(BridgeConfig.class)) {
+                BridgeConfig bridgeConfig =  device.as(BridgeConfig.class);
+                bridgeConfig.addBridge(BridgeName.bridgeName(DEFAULT_BRIDGE), dpid, controllers);
+            } else {
+                log.warn("The bridging behaviour is not supported in device {}", device.id());
+            }
+        } catch (ItemNotFoundException e) {
+            log.warn("Failed to create integration bridge on {}", node.hostname());
+        }
+    }
+
+    /**
+     * Creates tunnel interface to the integration bridge for a given node.
+     *
+     * @param node cordvtn node
+     */
+    private void createTunnelInterface(CordVtnNode node) {
+        if (isTunnelIntfCreated(node)) {
+            return;
+        }
+
+        DefaultAnnotations.Builder optionBuilder = DefaultAnnotations.builder();
+        for (String key : DEFAULT_TUNNEL_OPTIONS.keySet()) {
+            optionBuilder.set(key, DEFAULT_TUNNEL_OPTIONS.get(key));
+        }
+
+        TunnelDescription description = new DefaultTunnelDescription(
+                null, null, VXLAN, TunnelName.tunnelName(DEFAULT_TUNNEL),
+                optionBuilder.build());
+
+        try {
+            Device device = deviceService.getDevice(node.ovsdbId());
+            if (device.is(TunnelConfig.class)) {
+                TunnelConfig tunnelConfig =  device.as(TunnelConfig.class);
+                tunnelConfig.createTunnelInterface(BridgeName.bridgeName(DEFAULT_BRIDGE), description);
+            } else {
+                log.warn("The tunneling behaviour is not supported in device {}", device.id());
+            }
+        } catch (ItemNotFoundException e) {
+            log.warn("Failed to create tunnel interface on {}", node.hostname());
+        }
+    }
+
+    /**
+     * Adds data plane interface to a given node.
+     *
+     * @param node cordvtn node
+     */
+    private void addDataPlaneInterface(CordVtnNode node) {
+        if (isDataPlaneIntfAdded(node)) {
+            return;
+        }
+
+        Session session = connect(node.sshInfo());
+        if (session == null) {
+            log.debug("Failed to SSH to {}", node.hostname());
+            return;
+        }
+
+        if (!isInterfaceUp(session, node.dpIntf())) {
+            log.warn("Interface {} is not available", node.dpIntf());
+            return;
+        }
+        disconnect(session);
+
+        try {
+            Device device = deviceService.getDevice(node.ovsdbId());
+            if (device.is(BridgeConfig.class)) {
+                BridgeConfig bridgeConfig =  device.as(BridgeConfig.class);
+                bridgeConfig.addPort(BridgeName.bridgeName(DEFAULT_BRIDGE), node.dpIntf());
+            } else {
+                log.warn("The bridging behaviour is not supported in device {}", device.id());
+            }
+        } catch (ItemNotFoundException e) {
+            log.warn("Failed to add {} on {}", node.dpIntf(), node.hostname());
+        }
+    }
+
+    /**
+     * Flushes IP address from data plane interface and adds data plane IP address
+     * to integration bridge.
+     *
+     * @param node cordvtn node
+     */
+    private void setIpAddress(CordVtnNode node) {
+        Session session = connect(node.sshInfo());
+        if (session == null) {
+            log.debug("Failed to SSH to {}", node.hostname());
+            return;
+        }
+
+        getCurrentIps(session, DEFAULT_BRIDGE).stream()
+                .filter(ip -> !ip.equals(node.localMgmtIp().ip()))
+                .filter(ip -> !ip.equals(node.dpIp().ip()))
+                .forEach(ip -> deleteIp(session, ip, DEFAULT_BRIDGE));
+
+        boolean result = flushIp(session, node.dpIntf()) &&
+                setInterfaceUp(session, node.dpIntf()) &&
+                addIp(session, node.dpIp(), DEFAULT_BRIDGE) &&
+                addIp(session, node.localMgmtIp(), DEFAULT_BRIDGE) &&
+                setInterfaceUp(session, DEFAULT_BRIDGE);
+
+        disconnect(session);
+
+        if (result) {
+            setNodeState(node, NodeState.COMPLETE);
+        }
+    }
+
+    /**
+     * Checks if integration bridge exists and available.
+     *
+     * @param node cordvtn node
+     * @return true if the bridge is available, false otherwise
+     */
+    private boolean isBrIntCreated(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 isTunnelIntfCreated(CordVtnNode node) {
+        return deviceService.getPorts(node.intBrId())
+                    .stream()
+                    .filter(p -> portName(p).contains(DEFAULT_TUNNEL) &&
+                            p.isEnabled())
+                    .findAny().isPresent();
+    }
+
+    /**
+     * Checks if data plane interface exists.
+     *
+     * @param node cordvtn node
+     * @return true if the interface exists, false otherwise
+     */
+    private boolean isDataPlaneIntfAdded(CordVtnNode node) {
+        return deviceService.getPorts(node.intBrId())
+                    .stream()
+                    .filter(p -> portName(p).contains(node.dpIntf()) &&
+                            p.isEnabled())
+                    .findAny().isPresent();
+    }
+
+    /**
+     * Checks if the IP addresses are correctly set.
+     *
+     * @param node cordvtn node
+     * @return true if the IP is set, false otherwise
+     */
+    private boolean isIpAddressSet(CordVtnNode node) {
+        Session session = connect(node.sshInfo());
+        if (session == null) {
+            log.debug("Failed to SSH to {}", node.hostname());
+            return false;
+        }
+
+        Set<IpAddress> intBrIps = getCurrentIps(session, DEFAULT_BRIDGE);
+        boolean result = getCurrentIps(session, node.dpIntf()).isEmpty() &&
+                isInterfaceUp(session, node.dpIntf()) &&
+                intBrIps.contains(node.dpIp().ip()) &&
+                intBrIps.contains(node.localMgmtIp().ip()) &&
+                isInterfaceUp(session, DEFAULT_BRIDGE);
+
+        disconnect(session);
+        return result;
+    }
+
+    /**
+     * Returns connect point of a given port.
+     *
+     * @param port port
+     * @return connect point
+     */
+    private ConnectPoint connectPoint(Port port) {
+        return new ConnectPoint(port.element().id(), port.number());
+    }
+
+    /**
+     * Returns connect point of a given host.
+     *
+     * @param host host
+     * @return connect point
+     */
+    private ConnectPoint connectPoint(Host host) {
+        return new ConnectPoint(host.location().deviceId(), host.location().port());
+    }
+
+    /**
+     * 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 nodeByOvsdbId(DeviceId ovsdbId) {
+        return getNodes().stream()
+                .filter(node -> node.ovsdbId().equals(ovsdbId))
+                .findFirst().orElse(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 nodeByBridgeId(DeviceId bridgeId) {
+        return getNodes().stream()
+                .filter(node -> node.intBrId().equals(bridgeId))
+                .findFirst().orElse(null);
+    }
+
+    /**
+     * Returns port name.
+     *
+     * @param port port
+     * @return port name
+     */
+    private String portName(Port port) {
+        return port.annotations().value("portName");
+    }
+
+    private class OvsdbHandler implements ConnectionHandler<Device> {
+
+        @Override
+        public void connected(Device device) {
+            CordVtnNode node = nodeByOvsdbId(device.id());
+            if (node != null) {
+                setNodeState(node, getNodeState(node));
+            } else {
+                log.debug("{} is detected on unregistered node, ignore it.", device.id());
+            }
+        }
+
+        @Override
+        public void disconnected(Device device) {
+            if (!deviceService.isAvailable(device.id())) {
+                log.debug("Device {} is disconnected", device.id());
+                adminService.removeDevice(device.id());
+            }
+        }
+    }
+
+    private class BridgeHandler implements ConnectionHandler<Device> {
+
+        @Override
+        public void connected(Device device) {
+            CordVtnNode node = nodeByBridgeId(device.id());
+            if (node != null) {
+                setNodeState(node, getNodeState(node));
+            } else {
+                log.debug("{} is detected on unregistered node, ignore it.", device.id());
+            }
+        }
+
+        @Override
+        public void disconnected(Device device) {
+            CordVtnNode node = nodeByBridgeId(device.id());
+            if (node != null) {
+                log.debug("Integration Bridge is disconnected from {}", node.hostname());
+                setNodeState(node, NodeState.INCOMPLETE);
+            }
+        }
+
+        /**
+         * Handles port added situation.
+         * If the added port is tunnel or data plane interface, proceed to the remaining
+         * node initialization. Otherwise, do nothing.
+         *
+         * @param port port
+         */
+        public void portAdded(Port port) {
+            CordVtnNode node = nodeByBridgeId((DeviceId) port.element().id());
+            String portName = portName(port);
+
+            if (node == null) {
+                log.debug("{} is added to unregistered node, ignore it.", portName);
+                return;
+            }
+
+            log.info("Port {} is added to {}", portName, node.hostname());
+
+            if (portName.startsWith(VPORT_PREFIX)) {
+                if (isNodeStateComplete(node)) {
+                    instanceManager.addInstance(connectPoint(port));
+                } else {
+                    log.debug("VM is detected on incomplete node, ignore it.", portName);
+                }
+            } else if (portName.contains(DEFAULT_TUNNEL) || portName.equals(node.dpIntf())) {
+                setNodeState(node, getNodeState(node));
+            }
+        }
+
+        /**
+         * Handles port removed situation.
+         * If the removed port is tunnel or data plane interface, proceed to the remaining
+         * node initialization.Others, do nothing.
+         *
+         * @param port port
+         */
+        public void portRemoved(Port port) {
+            CordVtnNode node = nodeByBridgeId((DeviceId) port.element().id());
+            String portName = portName(port);
+
+            if (node == null) {
+                return;
+            }
+
+            log.info("Port {} is removed from {}", portName, node.hostname());
+
+            if (portName.startsWith(VPORT_PREFIX)) {
+                if (isNodeStateComplete(node)) {
+                    instanceManager.removeInstance(connectPoint(port));
+                } else {
+                    log.debug("VM is vanished from incomplete node, ignore it.", portName);
+                }
+            } else if (portName.contains(DEFAULT_TUNNEL) || portName.equals(node.dpIntf())) {
+                setNodeState(node, NodeState.INCOMPLETE);
+            }
+        }
+    }
+
+    private class InternalDeviceListener implements DeviceListener {
+
+        @Override
+        public void event(DeviceEvent event) {
+
+            NodeId leaderNodeId = leadershipService.getLeader(appId.name());
+            if (!Objects.equals(localNodeId, leaderNodeId)) {
+                // do not allow to proceed without leadership
+                return;
+            }
+
+            Device device = event.subject();
+            ConnectionHandler<Device> handler =
+                    (device.type().equals(SWITCH) ? bridgeHandler : ovsdbHandler);
+
+            switch (event.type()) {
+                case PORT_ADDED:
+                    eventExecutor.execute(() -> bridgeHandler.portAdded(event.port()));
+                    break;
+                case PORT_UPDATED:
+                    if (!event.port().isEnabled()) {
+                        eventExecutor.execute(() -> bridgeHandler.portRemoved(event.port()));
+                    }
+                    break;
+                case DEVICE_ADDED:
+                case DEVICE_AVAILABILITY_CHANGED:
+                    if (deviceService.isAvailable(device.id())) {
+                        eventExecutor.execute(() -> handler.connected(device));
+                    } else {
+                        eventExecutor.execute(() -> handler.disconnected(device));
+                    }
+                    break;
+                default:
+                    break;
+            }
+        }
+    }
+
+    /**
+     * Reads cordvtn nodes from config file.
+     */
+    private void readConfiguration() {
+        CordVtnConfig config = configRegistry.getConfig(appId, CordVtnConfig.class);
+        if (config == null) {
+            log.debug("No configuration found");
+            return;
+        }
+        config.cordVtnNodes().forEach(this::addOrUpdateNode);
+    }
+
+    private class InternalConfigListener implements NetworkConfigListener {
+
+        @Override
+        public void event(NetworkConfigEvent event) {
+            NodeId leaderNodeId = leadershipService.getLeader(appId.name());
+            if (!Objects.equals(localNodeId, leaderNodeId)) {
+                // do not allow to proceed without leadership
+                return;
+            }
+
+            if (!event.configClass().equals(CordVtnConfig.class)) {
+                return;
+            }
+
+            switch (event.type()) {
+                case CONFIG_ADDED:
+                case CONFIG_UPDATED:
+                    eventExecutor.execute(CordVtnNodeManager.this::readConfiguration);
+                    break;
+                default:
+                    break;
+            }
+        }
+    }
+
+    private class InternalMapListener implements MapEventListener<String, CordVtnNode> {
+
+        @Override
+        public void event(MapEvent<String, CordVtnNode> event) {
+            NodeId leaderNodeId = leadershipService.getLeader(appId.name());
+            if (!Objects.equals(localNodeId, leaderNodeId)) {
+                // do not allow to proceed without leadership
+                return;
+            }
+
+            CordVtnNode oldNode;
+            CordVtnNode newNode;
+
+            switch (event.type()) {
+                case UPDATE:
+                    oldNode = event.oldValue().value();
+                    newNode = event.newValue().value();
+
+                    log.info("Reloaded {}", newNode.hostname());
+                    if (!newNode.equals(oldNode)) {
+                        log.debug("New node: {}", newNode);
+                    }
+                    // performs init procedure even if the node is not changed
+                    // for robustness since it's no harm to run init procedure
+                    // multiple times
+                    eventExecutor.execute(() -> initNode(newNode));
+                    break;
+                case INSERT:
+                    newNode = event.newValue().value();
+                    log.info("Added {}", newNode.hostname());
+                    eventExecutor.execute(() -> initNode(newNode));
+                    break;
+                case REMOVE:
+                    oldNode = event.oldValue().value();
+                    log.info("Removed {}", oldNode.hostname());
+                    break;
+                default:
+                    break;
+            }
+        }
+    }
+}
diff --git a/src/main/java/org/onosproject/cordvtn/impl/CordVtnPipeline.java b/src/main/java/org/onosproject/cordvtn/impl/CordVtnPipeline.java
new file mode 100644
index 0000000..4abbcf0
--- /dev/null
+++ b/src/main/java/org/onosproject/cordvtn/impl/CordVtnPipeline.java
@@ -0,0 +1,409 @@
+/*
+ * 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.cordvtn.impl;
+
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Deactivate;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.apache.felix.scr.annotations.Service;
+import org.onlab.packet.Ethernet;
+import org.onlab.packet.IPv4;
+import org.onlab.packet.Ip4Address;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.TpPort;
+import org.onlab.packet.VlanId;
+import org.onlab.util.ItemNotFoundException;
+import org.onosproject.cordvtn.api.CordVtnNode;
+import org.onosproject.cordvtn.api.CordVtnService;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreService;
+import org.onosproject.net.Device;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.behaviour.ExtensionTreatmentResolver;
+import org.onosproject.net.device.DeviceService;
+import org.onosproject.net.flow.DefaultFlowRule;
+import org.onosproject.net.flow.DefaultTrafficSelector;
+import org.onosproject.net.flow.DefaultTrafficTreatment;
+import org.onosproject.net.flow.FlowRule;
+import org.onosproject.net.flow.FlowRuleOperations;
+import org.onosproject.net.flow.FlowRuleOperationsContext;
+import org.onosproject.net.flow.FlowRuleService;
+import org.onosproject.net.flow.TrafficSelector;
+import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.flow.instructions.ExtensionPropertyException;
+import org.onosproject.net.flow.instructions.ExtensionTreatment;
+import org.slf4j.Logger;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.onosproject.net.flow.instructions.ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_SET_TUNNEL_DST;
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * Provides CORD VTN pipeline.
+ */
+@Component(immediate = true)
+@Service(value = CordVtnPipeline.class)
+public final class CordVtnPipeline {
+
+    protected final Logger log = getLogger(getClass());
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected CoreService coreService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected FlowRuleService flowRuleService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected DeviceService deviceService;
+
+    // tables
+    public static final int TABLE_ZERO = 0;
+    public static final int TABLE_IN_PORT = 1;
+    public static final int TABLE_ACCESS_TYPE = 2;
+    public static final int TABLE_IN_SERVICE = 3;
+    public static final int TABLE_DST_IP = 4;
+    public static final int TABLE_TUNNEL_IN = 5;
+    public static final int TABLE_VLAN = 6;
+
+    // priorities
+    public static final int PRIORITY_MANAGEMENT = 55000;
+    public static final int PRIORITY_HIGH = 50000;
+    public static final int PRIORITY_DEFAULT = 5000;
+    public static final int PRIORITY_LOW = 4000;
+    public static final int PRIORITY_ZERO = 0;
+
+    public static final int VXLAN_UDP_PORT = 4789;
+    public static final VlanId VLAN_WAN = VlanId.vlanId((short) 500);
+    public static final String DEFAULT_TUNNEL = "vxlan";
+    private static final String PORT_NAME = "portName";
+
+    private ApplicationId appId;
+
+    @Activate
+    protected void activate() {
+        appId = coreService.registerApplication(CordVtnService.CORDVTN_APP_ID);
+        log.info("Started");
+    }
+
+    @Deactivate
+    protected void deactivate() {
+        log.info("Stopped");
+    }
+
+    /**
+     * Flush flows installed by this application.
+     */
+    public void flushRules() {
+        flowRuleService.getFlowRulesById(appId).forEach(flowRule -> processFlowRule(false, flowRule));
+    }
+
+    /**
+     * Installs table miss rule to a give device.
+     *
+     * @param node cordvtn node
+     * @param dpPort data plane port number
+     * @param tunnelPort tunnel port number
+     */
+    public void initPipeline(CordVtnNode node, PortNumber dpPort, PortNumber tunnelPort) {
+        checkNotNull(node);
+
+        processTableZero(node.intBrId(), dpPort, node.dpIp().ip());
+        processInPortTable(node.intBrId(), tunnelPort, dpPort);
+        processAccessTypeTable(node.intBrId(), dpPort);
+        processVlanTable(node.intBrId(), dpPort);
+    }
+
+    private void processTableZero(DeviceId deviceId, PortNumber dpPort, IpAddress dpIp) {
+        // take vxlan packet out onto the physical port
+        TrafficSelector selector = DefaultTrafficSelector.builder()
+                .matchInPort(PortNumber.LOCAL)
+                .build();
+
+        TrafficTreatment treatment = DefaultTrafficTreatment.builder()
+                .setOutput(dpPort)
+                .build();
+
+        FlowRule flowRule = DefaultFlowRule.builder()
+                .fromApp(appId)
+                .withSelector(selector)
+                .withTreatment(treatment)
+                .withPriority(PRIORITY_HIGH)
+                .forDevice(deviceId)
+                .forTable(TABLE_ZERO)
+                .makePermanent()
+                .build();
+
+        processFlowRule(true, flowRule);
+
+        // take a vxlan encap'd packet through the Linux stack
+        selector = DefaultTrafficSelector.builder()
+                .matchInPort(dpPort)
+                .matchEthType(Ethernet.TYPE_IPV4)
+                .matchIPProtocol(IPv4.PROTOCOL_UDP)
+                .matchUdpDst(TpPort.tpPort(VXLAN_UDP_PORT))
+                .build();
+
+        treatment = DefaultTrafficTreatment.builder()
+                .setOutput(PortNumber.LOCAL)
+                .build();
+
+        flowRule = DefaultFlowRule.builder()
+                .fromApp(appId)
+                .withSelector(selector)
+                .withTreatment(treatment)
+                .withPriority(PRIORITY_HIGH)
+                .forDevice(deviceId)
+                .forTable(TABLE_ZERO)
+                .makePermanent()
+                .build();
+
+        processFlowRule(true, flowRule);
+
+        // take a packet to the data plane ip through Linux stack
+        selector = DefaultTrafficSelector.builder()
+                .matchInPort(dpPort)
+                .matchEthType(Ethernet.TYPE_IPV4)
+                .matchIPDst(dpIp.toIpPrefix())
+                .build();
+
+        treatment = DefaultTrafficTreatment.builder()
+                .setOutput(PortNumber.LOCAL)
+                .build();
+
+        flowRule = DefaultFlowRule.builder()
+                .fromApp(appId)
+                .withSelector(selector)
+                .withTreatment(treatment)
+                .withPriority(PRIORITY_HIGH)
+                .forDevice(deviceId)
+                .forTable(TABLE_ZERO)
+                .makePermanent()
+                .build();
+
+        processFlowRule(true, flowRule);
+
+        // take an arp packet from physical through Linux stack
+        selector = DefaultTrafficSelector.builder()
+                .matchInPort(dpPort)
+                .matchEthType(Ethernet.TYPE_ARP)
+                .matchArpTpa(dpIp.getIp4Address())
+                .build();
+
+        treatment = DefaultTrafficTreatment.builder()
+                .setOutput(PortNumber.LOCAL)
+                .build();
+
+        flowRule = DefaultFlowRule.builder()
+                .fromApp(appId)
+                .withSelector(selector)
+                .withTreatment(treatment)
+                .withPriority(PRIORITY_HIGH)
+                .forDevice(deviceId)
+                .forTable(TABLE_ZERO)
+                .makePermanent()
+                .build();
+
+        processFlowRule(true, flowRule);
+
+        // take all else to the next table
+        selector = DefaultTrafficSelector.builder()
+                .build();
+
+        treatment = DefaultTrafficTreatment.builder()
+                .transition(TABLE_IN_PORT)
+                .build();
+
+        flowRule = DefaultFlowRule.builder()
+                .fromApp(appId)
+                .withSelector(selector)
+                .withTreatment(treatment)
+                .withPriority(PRIORITY_ZERO)
+                .forDevice(deviceId)
+                .forTable(TABLE_ZERO)
+                .makePermanent()
+                .build();
+
+        processFlowRule(true, flowRule);
+
+        // take all vlan tagged packet to the VLAN table
+        selector = DefaultTrafficSelector.builder()
+                .matchVlanId(VlanId.ANY)
+                .build();
+
+        treatment = DefaultTrafficTreatment.builder()
+                .transition(TABLE_VLAN)
+                .build();
+
+        flowRule = DefaultFlowRule.builder()
+                .fromApp(appId)
+                .withSelector(selector)
+                .withTreatment(treatment)
+                .withPriority(PRIORITY_MANAGEMENT)
+                .forDevice(deviceId)
+                .forTable(TABLE_ZERO)
+                .makePermanent()
+                .build();
+
+        processFlowRule(true, flowRule);
+    }
+
+    private void processInPortTable(DeviceId deviceId, PortNumber tunnelPort, PortNumber dpPort) {
+        checkNotNull(tunnelPort);
+
+        TrafficSelector selector = DefaultTrafficSelector.builder()
+                .matchInPort(tunnelPort)
+                .build();
+
+        TrafficTreatment treatment = DefaultTrafficTreatment.builder()
+                .transition(TABLE_TUNNEL_IN)
+                .build();
+
+        FlowRule flowRule = DefaultFlowRule.builder()
+                .fromApp(appId)
+                .withSelector(selector)
+                .withTreatment(treatment)
+                .withPriority(PRIORITY_DEFAULT)
+                .forDevice(deviceId)
+                .forTable(TABLE_IN_PORT)
+                .makePermanent()
+                .build();
+
+        processFlowRule(true, flowRule);
+
+        selector = DefaultTrafficSelector.builder()
+                .matchInPort(dpPort)
+                .build();
+
+        treatment = DefaultTrafficTreatment.builder()
+                .transition(TABLE_DST_IP)
+                .build();
+
+        flowRule = DefaultFlowRule.builder()
+                .fromApp(appId)
+                .withSelector(selector)
+                .withTreatment(treatment)
+                .withPriority(PRIORITY_DEFAULT)
+                .forDevice(deviceId)
+                .forTable(TABLE_IN_PORT)
+                .makePermanent()
+                .build();
+
+        processFlowRule(true, flowRule);
+    }
+
+    private void processAccessTypeTable(DeviceId deviceId, PortNumber dpPort) {
+        TrafficSelector selector = DefaultTrafficSelector.builder()
+                .build();
+
+        TrafficTreatment treatment = DefaultTrafficTreatment.builder()
+                .setOutput(dpPort)
+                .build();
+
+        FlowRule flowRule = DefaultFlowRule.builder()
+                .fromApp(appId)
+                .withSelector(selector)
+                .withTreatment(treatment)
+                .withPriority(PRIORITY_ZERO)
+                .forDevice(deviceId)
+                .forTable(TABLE_ACCESS_TYPE)
+                .makePermanent()
+                .build();
+
+        processFlowRule(true, flowRule);
+    }
+
+    private void processVlanTable(DeviceId deviceId, PortNumber dpPort) {
+        // for traffic going out to WAN, strip vid 500 and take through data plane interface
+        TrafficSelector selector = DefaultTrafficSelector.builder()
+                .matchVlanId(VLAN_WAN)
+                .build();
+
+        TrafficTreatment treatment = DefaultTrafficTreatment.builder()
+                .popVlan()
+                .setOutput(dpPort)
+                .build();
+
+        FlowRule flowRule = DefaultFlowRule.builder()
+                .fromApp(appId)
+                .withSelector(selector)
+                .withTreatment(treatment)
+                .withPriority(PRIORITY_DEFAULT)
+                .forDevice(deviceId)
+                .forTable(TABLE_VLAN)
+                .makePermanent()
+                .build();
+
+        processFlowRule(true, flowRule);
+
+        selector = DefaultTrafficSelector.builder()
+                .matchVlanId(VLAN_WAN)
+                .matchEthType(Ethernet.TYPE_ARP)
+                .build();
+
+        treatment = DefaultTrafficTreatment.builder()
+                .setOutput(PortNumber.CONTROLLER)
+                .build();
+
+        flowRule = DefaultFlowRule.builder()
+                .fromApp(appId)
+                .withSelector(selector)
+                .withTreatment(treatment)
+                .withPriority(PRIORITY_HIGH)
+                .forDevice(deviceId)
+                .forTable(TABLE_VLAN)
+                .makePermanent()
+                .build();
+
+        processFlowRule(true, flowRule);
+    }
+
+    public void processFlowRule(boolean install, FlowRule rule) {
+        FlowRuleOperations.Builder oBuilder = FlowRuleOperations.builder();
+        oBuilder = install ? oBuilder.add(rule) : oBuilder.remove(rule);
+
+        flowRuleService.apply(oBuilder.build(new FlowRuleOperationsContext() {
+            @Override
+            public void onError(FlowRuleOperations ops) {
+                log.error(String.format("Failed %s, %s", ops.toString(), rule.toString()));
+            }
+        }));
+    }
+
+    public ExtensionTreatment tunnelDstTreatment(DeviceId deviceId, Ip4Address remoteIp) {
+        try {
+            Device device = deviceService.getDevice(deviceId);
+
+            if (device.is(ExtensionTreatmentResolver.class)) {
+                ExtensionTreatmentResolver resolver = device.as(ExtensionTreatmentResolver.class);
+                ExtensionTreatment treatment =
+                        resolver.getExtensionInstruction(NICIRA_SET_TUNNEL_DST.type());
+                treatment.setPropertyValue("tunnelDst", remoteIp);
+                return treatment;
+            } else {
+                log.warn("The extension treatment resolving behaviour is not supported in device {}",
+                         device.id().toString());
+                return null;
+            }
+        } catch (ItemNotFoundException | UnsupportedOperationException |
+                ExtensionPropertyException e) {
+            log.error("Failed to get extension instruction {}", deviceId);
+            return null;
+        }
+    }
+}
diff --git a/src/main/java/org/onosproject/cordvtn/impl/RemoteIpCommandUtil.java b/src/main/java/org/onosproject/cordvtn/impl/RemoteIpCommandUtil.java
new file mode 100644
index 0000000..c09e3a0
--- /dev/null
+++ b/src/main/java/org/onosproject/cordvtn/impl/RemoteIpCommandUtil.java
@@ -0,0 +1,243 @@
+/*
+ * 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.cordvtn.impl;
+
+import com.google.common.collect.Sets;
+import com.google.common.io.CharStreams;
+import com.jcraft.jsch.Channel;
+import com.jcraft.jsch.ChannelExec;
+import com.jcraft.jsch.JSch;
+import com.jcraft.jsch.JSchException;
+import com.jcraft.jsch.Session;
+import org.onlab.packet.IpAddress;
+import org.onosproject.cordvtn.api.NetworkAddress;
+import org.onosproject.cordvtn.api.SshAccessInfo;
+import org.slf4j.Logger;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.Set;
+import java.util.regex.Pattern;
+import java.util.stream.Collectors;
+
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * {@code RemoteIpCommandUtil} provides methods to help execute Linux IP commands to a remote server.
+ * It opens individual exec channels for each command. User can create a session with {@code connect}
+ * method and then execute a series commands. After done with all commands, the session must be closed
+ * explicitly by calling {@code disconnect}.
+ */
+public final class RemoteIpCommandUtil {
+
+    protected static final Logger log = getLogger(RemoteIpCommandUtil.class);
+
+    private static final String STRICT_HOST_CHECKING = "StrictHostKeyChecking";
+    private static final String DEFAULT_STRICT_HOST_CHECKING = "no";
+    private static final int DEFAULT_SESSION_TIMEOUT = 60000; // milliseconds
+
+    private static final String IP_PATTERN = "^([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\." +
+            "([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\." +
+            "([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\." +
+            "([01]?\\d\\d?|2[0-4]\\d|25[0-5])$";
+
+    private static final String IP_ADDR_SHOW = "sudo ip addr show %s";
+    private static final String IP_ADDR_FLUSH = "sudo ip addr flush %s";
+    private static final String IP_ADDR_ADD = "sudo ip addr add %s dev %s";
+    private static final String IP_ADDR_DELETE = "sudo ip addr delete %s dev %s";
+    private static final String IP_LINK_SHOW = "sudo ip link show %s";
+    private static final String IP_LINK_UP = "sudo ip link set %s up";
+
+    /**
+     * Default constructor.
+     */
+    private RemoteIpCommandUtil() {
+    }
+
+    /**
+     * Adds a given IP address to a given device.
+     *
+     * @param session ssh connection
+     * @param ip network address
+     * @param device device name to assign the ip address
+     * @return true if the command succeeds, or false
+     */
+    public static boolean addIp(Session session, NetworkAddress ip, String device) {
+        if (session == null || !session.isConnected()) {
+            return false;
+        }
+
+        executeCommand(session, String.format(IP_ADDR_ADD, ip.cidr(), device));
+        Set<IpAddress> result = getCurrentIps(session, device);
+        return result.contains(ip.ip());
+    }
+
+    /**
+     * Removes the IP address from a given device.
+     *
+     * @param session ssh connection
+     * @param ip ip address
+     * @param device device name
+     * @return true if the command succeeds, or false
+     */
+    public static boolean deleteIp(Session session, IpAddress ip, String device) {
+        if (session == null || !session.isConnected()) {
+            return false;
+        }
+
+        executeCommand(session, String.format(IP_ADDR_DELETE, ip, device));
+        Set<IpAddress> result = getCurrentIps(session, device);
+        return !result.contains(ip);
+    }
+
+    /**
+     * Removes all IP address on a given device.
+     *
+     * @param session ssh connection
+     * @param device device name
+     * @return true if the command succeeds, or false
+     */
+    public static boolean flushIp(Session session, String device) {
+        if (session == null || !session.isConnected()) {
+            return false;
+        }
+
+        executeCommand(session, String.format(IP_ADDR_FLUSH, device));
+        return getCurrentIps(session, device).isEmpty();
+    }
+
+    /**
+     * Returns a set of IP address that a given device has.
+     *
+     * @param session ssh connection
+     * @param device device name
+     * @return set of IP prefix or empty set
+     */
+    public static Set<IpAddress> getCurrentIps(Session session, String device) {
+        if (session == null || !session.isConnected()) {
+            return Sets.newHashSet();
+        }
+
+        String output = executeCommand(session, String.format(IP_ADDR_SHOW, device));
+        Set<IpAddress> result = Pattern.compile(" |/")
+                .splitAsStream(output)
+                .filter(s -> s.matches(IP_PATTERN))
+                .map(IpAddress::valueOf)
+                .collect(Collectors.toSet());
+
+        return result;
+    }
+
+    /**
+     * Sets link state up for a given device.
+     *
+     * @param session ssh connection
+     * @param device device name
+     * @return true if the command succeeds, or false
+     */
+    public static boolean setInterfaceUp(Session session, String device) {
+        if (session == null || !session.isConnected()) {
+            return false;
+        }
+
+        executeCommand(session, String.format(IP_LINK_UP, device));
+        return isInterfaceUp(session, device);
+    }
+
+    /**
+     * Checks if a given interface is up or not.
+     *
+     * @param session ssh connection
+     * @param device device name
+     * @return true if the interface is up, or false
+     */
+    public static boolean isInterfaceUp(Session session, String device) {
+        if (session == null || !session.isConnected()) {
+            return false;
+        }
+
+        String output = executeCommand(session, String.format(IP_LINK_SHOW, device));
+        return output != null && output.contains("UP");
+    }
+
+    /**
+     * Creates a new session with a given access information.
+     *
+     * @param sshInfo information to ssh to the remove server
+     * @return ssh session, or null
+     */
+    public static Session connect(SshAccessInfo sshInfo) {
+        try {
+            JSch jsch = new JSch();
+            jsch.addIdentity(sshInfo.privateKey());
+
+            Session session = jsch.getSession(sshInfo.user(),
+                                      sshInfo.remoteIp().toString(),
+                                      sshInfo.port().toInt());
+            session.setConfig(STRICT_HOST_CHECKING, DEFAULT_STRICT_HOST_CHECKING);
+            session.connect(DEFAULT_SESSION_TIMEOUT);
+
+            return session;
+        } catch (JSchException e) {
+            log.debug("Failed to connect to {} due to {}", sshInfo.toString(), e.toString());
+            return null;
+        }
+    }
+
+    /**
+     * Closes a connection.
+     *
+     * @param session session
+     */
+    public static void disconnect(Session session) {
+        if (session.isConnected()) {
+            session.disconnect();
+        }
+    }
+
+    /**
+     * Executes a given command. It opens exec channel for the command and closes
+     * the channel when it's done.
+     *
+     * @param session ssh connection to a remote server
+     * @param command command to execute
+     * @return command output string if the command succeeds, or null
+     */
+    private static String executeCommand(Session session, String command) {
+        if (session == null || !session.isConnected()) {
+            return null;
+        }
+
+        log.trace("Execute command {} to {}", command, session.getHost());
+
+        try {
+            Channel channel = session.openChannel("exec");
+            ((ChannelExec) channel).setCommand(command);
+            channel.setInputStream(null);
+            InputStream output = channel.getInputStream();
+
+            channel.connect();
+            String result = CharStreams.toString(new InputStreamReader(output));
+            channel.disconnect();
+
+            return result;
+        } catch (JSchException | IOException e) {
+            log.debug("Failed to execute command {} due to {}", command, e.toString());
+            return null;
+        }
+    }
+}
diff --git a/src/main/java/org/onosproject/cordvtn/impl/package-info.java b/src/main/java/org/onosproject/cordvtn/impl/package-info.java
new file mode 100644
index 0000000..fcc52ff
--- /dev/null
+++ b/src/main/java/org/onosproject/cordvtn/impl/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * 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.
+ */
+
+/**
+ * Implementation for CORD VTN application.
+ */
+package org.onosproject.cordvtn.impl;
\ No newline at end of file
diff --git a/src/main/java/org/onosproject/cordvtn/impl/service/DummyInstanceHandler.java b/src/main/java/org/onosproject/cordvtn/impl/service/DummyInstanceHandler.java
new file mode 100644
index 0000000..ee78218
--- /dev/null
+++ b/src/main/java/org/onosproject/cordvtn/impl/service/DummyInstanceHandler.java
@@ -0,0 +1,57 @@
+/*
+ * 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.cordvtn.impl.service;
+
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Component;
+
+import org.apache.felix.scr.annotations.Deactivate;
+import org.onosproject.cordvtn.api.Instance;
+import org.onosproject.cordvtn.api.InstanceHandler;
+import org.onosproject.cordvtn.impl.CordVtnInstanceHandler;
+import org.onosproject.xosclient.api.VtnService;
+
+import static java.util.concurrent.Executors.newSingleThreadScheduledExecutor;
+import static org.onlab.util.Tools.groupedThreads;
+
+/**
+ * Provides network connectivity for dummy service instances.
+ */
+@Component(immediate = true)
+public class DummyInstanceHandler extends CordVtnInstanceHandler implements InstanceHandler {
+
+    @Activate
+    protected void activate() {
+        serviceType = VtnService.ServiceType.DUMMY;
+        eventExecutor = newSingleThreadScheduledExecutor(groupedThreads("onos/cordvtn-dummy", "event-handler"));
+        super.activate();
+    }
+
+    @Deactivate
+    protected void deactivate() {
+        super.deactivate();
+    }
+
+    @Override
+    public void instanceDetected(Instance instance) {
+        super.instanceDetected(instance);
+    }
+
+    @Override
+    public void instanceRemoved(Instance instance) {
+        super.instanceRemoved(instance);
+    }
+}
diff --git a/src/main/java/org/onosproject/cordvtn/impl/service/OltAgentInstanceHandler.java b/src/main/java/org/onosproject/cordvtn/impl/service/OltAgentInstanceHandler.java
new file mode 100644
index 0000000..eaec689
--- /dev/null
+++ b/src/main/java/org/onosproject/cordvtn/impl/service/OltAgentInstanceHandler.java
@@ -0,0 +1,176 @@
+/*
+ * 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.cordvtn.impl.service;
+
+import com.google.common.collect.Maps;
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Deactivate;
+import org.onlab.packet.Ethernet;
+import org.onlab.packet.IpPrefix;
+import org.onosproject.cordconfig.access.AccessAgentConfig;
+import org.onosproject.cordconfig.access.AccessAgentData;
+import org.onosproject.cordvtn.api.CordVtnConfig;
+import org.onosproject.cordvtn.api.Instance;
+import org.onosproject.cordvtn.api.InstanceHandler;
+import org.onosproject.cordvtn.impl.CordVtnInstanceHandler;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.config.ConfigFactory;
+import org.onosproject.net.config.NetworkConfigEvent;
+import org.onosproject.net.config.NetworkConfigListener;
+import org.onosproject.net.config.basics.SubjectFactories;
+import org.onosproject.net.flow.DefaultFlowRule;
+import org.onosproject.net.flow.DefaultTrafficSelector;
+import org.onosproject.net.flow.DefaultTrafficTreatment;
+import org.onosproject.net.flow.FlowRule;
+import org.onosproject.net.flow.TrafficSelector;
+import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.xosclient.api.VtnService;
+
+import java.util.Map;
+import java.util.Set;
+
+import static java.util.concurrent.Executors.newSingleThreadScheduledExecutor;
+import static org.onlab.util.Tools.groupedThreads;
+import static org.onosproject.cordvtn.impl.CordVtnPipeline.PRIORITY_MANAGEMENT;
+import static org.onosproject.cordvtn.impl.CordVtnPipeline.TABLE_ACCESS_TYPE;
+
+/**
+ * Provides network connectivity for OLT agent instances.
+ */
+@Component(immediate = true)
+public class OltAgentInstanceHandler extends CordVtnInstanceHandler implements InstanceHandler {
+
+    private static final Class<AccessAgentConfig> CONFIG_CLASS = AccessAgentConfig.class;
+    private ConfigFactory<DeviceId, AccessAgentConfig> configFactory =
+            new ConfigFactory<DeviceId, AccessAgentConfig>(
+                    SubjectFactories.DEVICE_SUBJECT_FACTORY, CONFIG_CLASS, "accessAgent") {
+                @Override
+                public AccessAgentConfig createConfig() {
+                    return new AccessAgentConfig();
+                }
+            };
+
+    private Map<DeviceId, AccessAgentData> oltAgentData = Maps.newConcurrentMap();
+    private IpPrefix mgmtIpRange = null;
+
+    @Activate
+    protected void activate() {
+        eventExecutor = newSingleThreadScheduledExecutor(groupedThreads("onos/cordvtn-olt", "event-handler"));
+        serviceType = VtnService.ServiceType.OLT_AGENT;
+
+        configRegistry.registerConfigFactory(configFactory);
+        configListener = new InternalConfigListener();
+
+        super.activate();
+    }
+
+    @Deactivate
+    protected void deactivate() {
+        super.deactivate();
+    }
+
+    @Override
+    public void instanceDetected(Instance instance) {
+        log.info("OLT agent instance detected {}", instance);
+
+        managementAccessRule(instance.deviceId(), true);
+        // TODO implement
+    }
+
+    @Override
+    public void instanceRemoved(Instance instance) {
+        log.info("OLT agent instance removed {}", instance);
+
+        if (getInstances(instance.serviceId()).isEmpty()) {
+            nodeManager.completeNodes().stream().forEach(node ->
+                managementAccessRule(node.intBrId(), false));
+        }
+
+        // TODO implement
+    }
+
+    private void managementAccessRule(DeviceId deviceId, boolean install) {
+        // TODO remove this rule after long term management network is done
+        if (mgmtIpRange != null) {
+            TrafficSelector selector = DefaultTrafficSelector.builder()
+                    .matchEthType(Ethernet.TYPE_IPV4)
+                    .matchIPDst(mgmtIpRange)
+                    .build();
+
+            TrafficTreatment treatment = DefaultTrafficTreatment.builder()
+                    .setOutput(PortNumber.LOCAL)
+                    .build();
+
+            FlowRule flowRule = DefaultFlowRule.builder()
+                    .fromApp(appId)
+                    .withSelector(selector)
+                    .withTreatment(treatment)
+                    .withPriority(PRIORITY_MANAGEMENT)
+                    .forDevice(deviceId)
+                    .forTable(TABLE_ACCESS_TYPE)
+                    .makePermanent()
+                    .build();
+
+            pipeline.processFlowRule(install, flowRule);
+        }
+    }
+
+    private void readAccessAgentConfig() {
+
+        Set<DeviceId> deviceSubjects = configRegistry.getSubjects(DeviceId.class, CONFIG_CLASS);
+        deviceSubjects.stream().forEach(subject -> {
+            AccessAgentConfig config = configRegistry.getConfig(subject, CONFIG_CLASS);
+            if (config != null) {
+                oltAgentData.put(subject, config.getAgent());
+            }
+        });
+    }
+
+    @Override
+    protected void readConfiguration() {
+        CordVtnConfig config = configRegistry.getConfig(appId, CordVtnConfig.class);
+        if (config == null) {
+            log.debug("No configuration found");
+            return;
+        }
+
+        osAccess = config.openstackAccess();
+        xosAccess = config.xosAccess();
+        mgmtIpRange = config.managementIpRange();
+    }
+
+    public class InternalConfigListener implements NetworkConfigListener {
+
+        @Override
+        public void event(NetworkConfigEvent event) {
+
+            switch (event.type()) {
+                case CONFIG_UPDATED:
+                case CONFIG_ADDED:
+                    if (event.configClass().equals(CordVtnConfig.class)) {
+                        readConfiguration();
+                    } else if (event.configClass().equals(CONFIG_CLASS)) {
+                        readAccessAgentConfig();
+                    }
+                    break;
+                default:
+                    break;
+            }
+        }
+    }
+}
diff --git a/src/main/java/org/onosproject/cordvtn/impl/service/VsgInstanceHandler.java b/src/main/java/org/onosproject/cordvtn/impl/service/VsgInstanceHandler.java
new file mode 100644
index 0000000..f60f72b
--- /dev/null
+++ b/src/main/java/org/onosproject/cordvtn/impl/service/VsgInstanceHandler.java
@@ -0,0 +1,379 @@
+/*
+ * 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.cordvtn.impl.service;
+
+import com.google.common.base.Strings;
+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;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.apache.felix.scr.annotations.Service;
+import org.onlab.packet.Ethernet;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.IpPrefix;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.VlanId;
+import org.onosproject.cordvtn.api.Instance;
+import org.onosproject.cordvtn.api.InstanceHandler;
+import org.onosproject.cordvtn.impl.CordVtnInstanceHandler;
+import org.onosproject.cordvtn.impl.CordVtnInstanceManager;
+import org.onosproject.net.DefaultAnnotations;
+import org.onosproject.net.HostId;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.flow.DefaultFlowRule;
+import org.onosproject.net.flow.DefaultTrafficSelector;
+import org.onosproject.net.flow.DefaultTrafficTreatment;
+import org.onosproject.net.flow.FlowRule;
+import org.onosproject.net.flow.FlowRuleService;
+import org.onosproject.net.flow.TrafficSelector;
+import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.flow.criteria.Criterion;
+import org.onosproject.net.flow.criteria.IPCriterion;
+import org.onosproject.net.flow.instructions.Instruction;
+import org.onosproject.net.flow.instructions.Instructions;
+import org.onosproject.net.flow.instructions.L2ModificationInstruction;
+import org.onosproject.net.host.DefaultHostDescription;
+import org.onosproject.net.host.HostDescription;
+import org.onosproject.xosclient.api.VtnPort;
+import org.onosproject.xosclient.api.VtnPortApi;
+import org.onosproject.xosclient.api.VtnPortId;
+import org.onosproject.xosclient.api.VtnService;
+
+import java.util.Map;
+import java.util.Set;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static java.util.concurrent.Executors.newSingleThreadScheduledExecutor;
+import static org.onlab.util.Tools.groupedThreads;
+import static org.onosproject.cordvtn.api.Instance.*;
+import static org.onosproject.cordvtn.impl.CordVtnPipeline.*;
+import static org.onosproject.net.flow.criteria.Criterion.Type.IPV4_DST;
+import static org.onosproject.net.flow.instructions.L2ModificationInstruction.L2SubType.VLAN_PUSH;
+
+/**
+ * Provides network connectivity for vSG instances.
+ */
+@Component(immediate = true)
+@Service(value = VsgInstanceHandler.class)
+public final class VsgInstanceHandler extends CordVtnInstanceHandler implements InstanceHandler {
+
+    private static final String STAG = "stag";
+    private static final String VSG_VM = "vsgVm";
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected FlowRuleService flowRuleService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected CordVtnInstanceManager instanceManager;
+
+    @Activate
+    protected void activate() {
+        serviceType = VtnService.ServiceType.VSG;
+        eventExecutor = newSingleThreadScheduledExecutor(groupedThreads("onos/cordvtn-vsg", "event-handler"));
+        super.activate();
+    }
+
+    @Deactivate
+    protected void deactivate() {
+        super.deactivate();
+    }
+
+    @Override
+    public void instanceDetected(Instance instance) {
+        if (isVsgContainer(instance)) {
+            log.info("vSG container detected {}", instance);
+
+            // find vsg vm for this vsg container
+            String vsgVmId = instance.getAnnotation(VSG_VM);
+            if (Strings.isNullOrEmpty(vsgVmId)) {
+                log.warn("Failed to find VSG VM for {}", instance);
+                return;
+            }
+
+            Instance vsgVm = Instance.of(hostService.getHost(HostId.hostId(vsgVmId)));
+            VtnPort vtnPort = getVtnPort(vsgVm);
+            if (vtnPort == null || getStag(vtnPort) == null) {
+                return;
+            }
+
+            populateVsgRules(vsgVm, getStag(vtnPort),
+                             nodeManager.dpPort(vsgVm.deviceId()),
+                             vtnPort.addressPairs().keySet(),
+                             true);
+
+        } else {
+            VtnPort vtnPort = getVtnPort(instance);
+            if (vtnPort == null || getStag(vtnPort) == null) {
+                return;
+            }
+
+            vtnPort.addressPairs().entrySet().stream()
+                    .forEach(pair -> addVsgContainer(
+                            instance,
+                            pair.getKey(),
+                            pair.getValue(),
+                            getStag(vtnPort).toString()
+                    ));
+            super.instanceDetected(instance);
+        }
+    }
+
+    @Override
+    public void instanceRemoved(Instance instance) {
+        if (isVsgContainer(instance)) {
+            log.info("vSG container vanished {}", instance);
+
+            // find vsg vm for this vsg container
+            String vsgVmId = instance.getAnnotation(VSG_VM);
+            if (Strings.isNullOrEmpty(vsgVmId)) {
+                log.warn("Failed to find VSG VM for {}", instance);
+                return;
+            }
+
+            Instance vsgVm = Instance.of(hostService.getHost(HostId.hostId(vsgVmId)));
+            VtnPort vtnPort = getVtnPort(vsgVm);
+            if (vtnPort == null || getStag(vtnPort) == null) {
+                return;
+            }
+
+            populateVsgRules(vsgVm, getStag(vtnPort),
+                             nodeManager.dpPort(vsgVm.deviceId()),
+                             vtnPort.addressPairs().keySet(),
+                             false);
+
+        } else {
+            // TODO remove vsg vm related rules
+            super.instanceRemoved(instance);
+        }
+    }
+
+    /**
+     * Updates set of vSGs in a given vSG VM.
+     *
+     * @param vsgVmId vsg vm host id
+     * @param stag stag
+     * @param vsgInstances full set of vsg wan ip and mac address pairs in this vsg vm
+     */
+    public void updateVsgInstances(HostId vsgVmId, String stag, Map<IpAddress, MacAddress> vsgInstances) {
+        if (hostService.getHost(vsgVmId) == null) {
+            log.debug("vSG VM {} is not added yet, ignore this update", vsgVmId);
+            return;
+        }
+
+        Instance vsgVm = Instance.of(hostService.getHost(vsgVmId));
+        if (vsgVm == null) {
+            log.warn("Failed to find existing vSG VM for STAG: {}", stag);
+            return;
+        }
+
+        log.info("Updates vSGs in {} with STAG: {}", vsgVm, stag);
+
+        // adds vSGs in the address pair
+        vsgInstances.entrySet().stream()
+                .filter(addr -> hostService.getHostsByMac(addr.getValue()).isEmpty())
+                .forEach(addr -> addVsgContainer(
+                        vsgVm,
+                        addr.getKey(),
+                        addr.getValue(),
+                        stag));
+
+        // removes vSGs not listed in the address pair
+        hostService.getConnectedHosts(vsgVm.host().location()).stream()
+                .filter(host -> !host.mac().equals(vsgVm.mac()))
+                .filter(host -> !vsgInstances.values().contains(host.mac()))
+                .forEach(host -> {
+                    log.info("Removed vSG {}", host.toString());
+                    instanceManager.removeInstance(host.id());
+                });
+    }
+
+    private boolean isVsgContainer(Instance instance) {
+        return !Strings.isNullOrEmpty(instance.host().annotations().value(STAG));
+    }
+
+    private void addVsgContainer(Instance vsgVm, IpAddress vsgWanIp, MacAddress vsgMac,
+                                 String stag) {
+        HostId hostId = HostId.hostId(vsgMac);
+        DefaultAnnotations.Builder annotations = DefaultAnnotations.builder()
+                .set(SERVICE_TYPE, vsgVm.serviceType().toString())
+                .set(SERVICE_ID, vsgVm.serviceId().id())
+                .set(PORT_ID, vsgVm.portId().id())
+                .set(NESTED_INSTANCE, TRUE)
+                .set(STAG, stag)
+                .set(VSG_VM, vsgVm.host().id().toString())
+                .set(CREATE_TIME, String.valueOf(System.currentTimeMillis()));
+
+        HostDescription hostDesc = new DefaultHostDescription(
+                vsgMac,
+                VlanId.NONE,
+                vsgVm.host().location(),
+                Sets.newHashSet(vsgWanIp),
+                annotations.build());
+
+        instanceManager.addInstance(hostId, hostDesc);
+    }
+
+    private void populateVsgRules(Instance vsgVm, VlanId stag, PortNumber dpPort,
+                                  Set<IpAddress> vsgWanIps, boolean install) {
+        // for traffics with s-tag, strip the tag and take through the vSG VM
+        TrafficSelector selector = DefaultTrafficSelector.builder()
+                .matchInPort(dpPort)
+                .matchVlanId(stag)
+                .build();
+
+        TrafficTreatment treatment = DefaultTrafficTreatment.builder()
+                .setOutput(vsgVm.portNumber())
+                .build();
+
+        FlowRule flowRule = DefaultFlowRule.builder()
+                .fromApp(appId)
+                .withSelector(selector)
+                .withTreatment(treatment)
+                .withPriority(PRIORITY_DEFAULT)
+                .forDevice(vsgVm.deviceId())
+                .forTable(TABLE_VLAN)
+                .makePermanent()
+                .build();
+
+        pipeline.processFlowRule(install, flowRule);
+
+        // for traffics with customer vlan, tag with the service vlan based on input port with
+        // lower priority to avoid conflict with WAN tag
+        selector = DefaultTrafficSelector.builder()
+                .matchInPort(vsgVm.portNumber())
+                .matchVlanId(stag)
+                .build();
+
+        treatment = DefaultTrafficTreatment.builder()
+                .setOutput(dpPort)
+                .build();
+
+        flowRule = DefaultFlowRule.builder()
+                .fromApp(appId)
+                .withSelector(selector)
+                .withTreatment(treatment)
+                .withPriority(PRIORITY_DEFAULT)
+                .forDevice(vsgVm.deviceId())
+                .forTable(TABLE_VLAN)
+                .makePermanent()
+                .build();
+
+        pipeline.processFlowRule(install, flowRule);
+
+        // for traffic coming from WAN, tag 500 and take through the vSG VM
+        // based on destination ip
+        vsgWanIps.stream().forEach(ip -> {
+            TrafficSelector downstream = DefaultTrafficSelector.builder()
+                    .matchEthType(Ethernet.TYPE_IPV4)
+                    .matchIPDst(ip.toIpPrefix())
+                    .build();
+
+            TrafficTreatment downstreamTreatment = DefaultTrafficTreatment.builder()
+                    .pushVlan()
+                    .setVlanId(VLAN_WAN)
+                    .setEthDst(vsgVm.mac())
+                    .setOutput(vsgVm.portNumber())
+                    .build();
+
+            FlowRule downstreamFlowRule = DefaultFlowRule.builder()
+                    .fromApp(appId)
+                    .withSelector(downstream)
+                    .withTreatment(downstreamTreatment)
+                    .withPriority(PRIORITY_DEFAULT)
+                    .forDevice(vsgVm.deviceId())
+                    .forTable(TABLE_DST_IP)
+                    .makePermanent()
+                    .build();
+
+            pipeline.processFlowRule(install, downstreamFlowRule);
+        });
+
+        // remove downstream flow rules for the vSG not shown in vsgWanIps
+        for (FlowRule rule : flowRuleService.getFlowRulesById(appId)) {
+            if (!rule.deviceId().equals(vsgVm.deviceId())) {
+                continue;
+            }
+            PortNumber output = getOutputFromTreatment(rule);
+            if (output == null || !output.equals(vsgVm.portNumber()) ||
+                    !isVlanPushFromTreatment(rule)) {
+                continue;
+            }
+
+            IpPrefix dstIp = getDstIpFromSelector(rule);
+            if (dstIp != null && !vsgWanIps.contains(dstIp.address())) {
+                pipeline.processFlowRule(false, rule);
+            }
+        }
+    }
+
+    private VtnPort getVtnPort(Instance instance) {
+        checkNotNull(osAccess, OPENSTACK_ACCESS_ERROR);
+        checkNotNull(xosAccess, XOS_ACCESS_ERROR);
+
+        VtnPortId vtnPortId = instance.portId();
+        VtnPortApi portApi = xosClient.getClient(xosAccess).vtnPort();
+        VtnPort vtnPort = portApi.vtnPort(vtnPortId, osAccess);
+        if (vtnPort == null) {
+            log.warn("Failed to get port information of {}", instance);
+            return null;
+        }
+        return vtnPort;
+    }
+
+    // TODO get stag from XOS when XOS provides it, extract if from port name for now
+    private VlanId getStag(VtnPort vtnPort) {
+        checkNotNull(vtnPort);
+
+        String portName = vtnPort.name();
+        if (portName != null && portName.startsWith(STAG)) {
+            return VlanId.vlanId(portName.split("-")[1]);
+        } else {
+            return null;
+        }
+    }
+
+    private PortNumber getOutputFromTreatment(FlowRule flowRule) {
+        Instruction instruction = flowRule.treatment().allInstructions().stream()
+                .filter(inst -> inst instanceof Instructions.OutputInstruction)
+                .findFirst()
+                .orElse(null);
+        if (instruction == null) {
+            return null;
+        }
+        return ((Instructions.OutputInstruction) instruction).port();
+    }
+
+    private IpPrefix getDstIpFromSelector(FlowRule flowRule) {
+        Criterion criterion = flowRule.selector().getCriterion(IPV4_DST);
+        if (criterion != null && criterion instanceof IPCriterion) {
+            IPCriterion ip = (IPCriterion) criterion;
+            return ip.ip();
+        } else {
+            return null;
+        }
+    }
+
+    private boolean isVlanPushFromTreatment(FlowRule flowRule) {
+        Instruction instruction = flowRule.treatment().allInstructions().stream()
+                .filter(inst -> inst instanceof L2ModificationInstruction)
+                .filter(inst -> ((L2ModificationInstruction) inst).subtype().equals(VLAN_PUSH))
+                .findAny()
+                .orElse(null);
+        return instruction != null;
+    }
+}
diff --git a/src/main/java/org/onosproject/cordvtn/impl/service/package-info.java b/src/main/java/org/onosproject/cordvtn/impl/service/package-info.java
new file mode 100644
index 0000000..035b012
--- /dev/null
+++ b/src/main/java/org/onosproject/cordvtn/impl/service/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * 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.
+ */
+
+/**
+ * Implementation of instance handlers for various network services.
+ */
+package org.onosproject.cordvtn.impl.service;
\ No newline at end of file
diff --git a/src/main/java/org/onosproject/cordvtn/rest/CordVtnWebApplication.java b/src/main/java/org/onosproject/cordvtn/rest/CordVtnWebApplication.java
new file mode 100644
index 0000000..e1193df
--- /dev/null
+++ b/src/main/java/org/onosproject/cordvtn/rest/CordVtnWebApplication.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2015-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.cordvtn.rest;
+
+import org.onlab.rest.AbstractWebApplication;
+
+import java.util.Set;
+
+/**
+ * CORD VTN Web application.
+ */
+public class CordVtnWebApplication extends AbstractWebApplication {
+    @Override
+    public Set<Class<?>> getClasses() {
+        return getClasses(ServiceDependencyWebResource.class,
+                          NeutronMl2NetworksWebResource.class,
+                          NeutronMl2SubnetsWebResource.class,
+                          NeutronMl2PortsWebResource.class);
+    }
+}
diff --git a/src/main/java/org/onosproject/cordvtn/rest/NeutronMl2NetworksWebResource.java b/src/main/java/org/onosproject/cordvtn/rest/NeutronMl2NetworksWebResource.java
new file mode 100644
index 0000000..ebb3be4
--- /dev/null
+++ b/src/main/java/org/onosproject/cordvtn/rest/NeutronMl2NetworksWebResource.java
@@ -0,0 +1,65 @@
+/*
+ * 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.cordvtn.rest;
+
+import org.onosproject.rest.AbstractWebResource;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import java.io.InputStream;
+
+/**
+ * Dummy Neutron ML2 mechanism driver.
+ * It just returns OK for networks resource requests.
+ */
+@Path("networks")
+public class NeutronMl2NetworksWebResource extends AbstractWebResource {
+    protected final Logger log = LoggerFactory.getLogger(getClass());
+    private static final String NETWORKS_MESSAGE = "Received networks %s";
+
+    @POST
+    @Consumes(MediaType.APPLICATION_JSON)
+    @Produces(MediaType.APPLICATION_JSON)
+    public Response createNetwork(InputStream input) {
+        log.trace(String.format(NETWORKS_MESSAGE, "create"));
+        return Response.status(Response.Status.OK).build();
+    }
+
+    @PUT
+    @Path("{id}")
+    @Consumes(MediaType.APPLICATION_JSON)
+    @Produces(MediaType.APPLICATION_JSON)
+    public Response updateNetwork(@PathParam("id") String id, InputStream input) {
+        log.trace(String.format(NETWORKS_MESSAGE, "update"));
+        return Response.status(Response.Status.OK).build();
+    }
+
+    @DELETE
+    @Path("{id}")
+    public Response deleteNetwork(@PathParam("id") String id) {
+        log.trace(String.format(NETWORKS_MESSAGE, "delete"));
+        return Response.noContent().build();
+    }
+}
diff --git a/src/main/java/org/onosproject/cordvtn/rest/NeutronMl2PortsWebResource.java b/src/main/java/org/onosproject/cordvtn/rest/NeutronMl2PortsWebResource.java
new file mode 100644
index 0000000..bf8d79d
--- /dev/null
+++ b/src/main/java/org/onosproject/cordvtn/rest/NeutronMl2PortsWebResource.java
@@ -0,0 +1,116 @@
+/*
+ * 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.cordvtn.rest;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.google.common.collect.Maps;
+import org.onlab.osgi.DefaultServiceDirectory;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.MacAddress;
+import org.onosproject.cordvtn.impl.service.VsgInstanceHandler;
+import org.onosproject.net.HostId;
+import org.onosproject.rest.AbstractWebResource;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import java.io.InputStream;
+import java.util.Map;
+
+
+/**
+ * Dummy Neutron ML2 mechanism driver.
+ * It just returns OK for ports resource requests except for the port update.
+ */
+@Path("ports")
+public class NeutronMl2PortsWebResource extends AbstractWebResource {
+    protected final Logger log = LoggerFactory.getLogger(getClass());
+    private static final String PORTS_MESSAGE = "Received ports %s";
+
+    private static final String PORT = "port";
+    private static final String DEVICE_ID = "device_id";
+    private static final String NAME = "name";
+    private static final String MAC_ADDRESS = "mac_address";
+    private static final String ADDRESS_PAIRS = "allowed_address_pairs";
+    private static final String IP_ADDERSS = "ip_address";
+    private static final String STAG_PREFIX = "stag-";
+    private static final int STAG_BEGIN_INDEX = 5;
+
+    private final VsgInstanceHandler service = DefaultServiceDirectory.getService(VsgInstanceHandler.class);
+
+    @POST
+    @Consumes(MediaType.APPLICATION_JSON)
+    @Produces(MediaType.APPLICATION_JSON)
+    public Response createPorts(InputStream input) {
+        log.trace(String.format(PORTS_MESSAGE, "create"));
+        return Response.status(Response.Status.OK).build();
+    }
+
+    @PUT
+    @Path("{id}")
+    @Consumes(MediaType.APPLICATION_JSON)
+    @Produces(MediaType.APPLICATION_JSON)
+    public Response updatePorts(@PathParam("id") String id, InputStream input) {
+        log.debug(String.format(PORTS_MESSAGE, "update"));
+
+        // TODO get vSG updates from XOS to CORD VTN service directly
+        try {
+            ObjectMapper mapper = new ObjectMapper();
+            JsonNode jsonNode = mapper.readTree(input).get(PORT);
+            log.trace("{}", jsonNode.toString());
+
+            String deviceId = jsonNode.path(DEVICE_ID).asText();
+            String name = jsonNode.path(NAME).asText();
+            if (deviceId.isEmpty() || name.isEmpty() || !name.startsWith(STAG_PREFIX)) {
+                // ignore all updates other than allowed address pairs
+                return Response.status(Response.Status.OK).build();
+            }
+
+            // this is allowed address pairs updates
+            MacAddress mac = MacAddress.valueOf(jsonNode.path(MAC_ADDRESS).asText());
+            Map<IpAddress, MacAddress> vsgInstances = Maps.newHashMap();
+            jsonNode.path(ADDRESS_PAIRS).forEach(addrPair -> {
+                IpAddress pairIp = IpAddress.valueOf(addrPair.path(IP_ADDERSS).asText());
+                MacAddress pairMac = MacAddress.valueOf(addrPair.path(MAC_ADDRESS).asText());
+                vsgInstances.put(pairIp, pairMac);
+            });
+
+            service.updateVsgInstances(HostId.hostId(mac),
+                                       name.substring(STAG_BEGIN_INDEX),
+                                       vsgInstances);
+        } catch (Exception e) {
+            return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
+        }
+
+        return Response.status(Response.Status.OK).build();
+    }
+
+    @Path("{id}")
+    @DELETE
+    public Response deletePorts(@PathParam("id") String id) {
+        log.trace(String.format(PORTS_MESSAGE, "delete"));
+        return Response.noContent().build();
+    }
+}
diff --git a/src/main/java/org/onosproject/cordvtn/rest/NeutronMl2SubnetsWebResource.java b/src/main/java/org/onosproject/cordvtn/rest/NeutronMl2SubnetsWebResource.java
new file mode 100644
index 0000000..c6b9544
--- /dev/null
+++ b/src/main/java/org/onosproject/cordvtn/rest/NeutronMl2SubnetsWebResource.java
@@ -0,0 +1,67 @@
+/*
+ * 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.cordvtn.rest;
+
+import org.onosproject.rest.AbstractWebResource;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import java.io.InputStream;
+
+/**
+ * Dummy Neutron ML2 mechanism driver.
+ * It just returns OK for subnets resource requests.
+ */
+@Path("subnets")
+public class NeutronMl2SubnetsWebResource extends AbstractWebResource {
+    protected final Logger log = LoggerFactory.getLogger(getClass());
+    private static final String SUBNETS_MESSAGE = "Received subnets %s";
+
+    @POST
+    @Consumes(MediaType.APPLICATION_JSON)
+    @Produces(MediaType.APPLICATION_JSON)
+    public Response createSubnet(InputStream input) {
+        log.trace(String.format(SUBNETS_MESSAGE, "create"));
+        return Response.status(Response.Status.OK).build();
+    }
+
+
+    @PUT
+    @Path("{id}")
+    @Produces(MediaType.APPLICATION_JSON)
+    @Consumes(MediaType.APPLICATION_JSON)
+    public Response updateSubnet(@PathParam("id") String id, InputStream input) {
+        log.trace(String.format(SUBNETS_MESSAGE, "update"));
+        return Response.status(Response.Status.OK).build();
+
+    }
+
+    @DELETE
+    @Path("{id}")
+    public Response deleteSubnet(@PathParam("id") String id) {
+        log.trace(String.format(SUBNETS_MESSAGE, "delete"));
+        return Response.noContent().build();
+    }
+}
diff --git a/src/main/java/org/onosproject/cordvtn/rest/ServiceDependencyWebResource.java b/src/main/java/org/onosproject/cordvtn/rest/ServiceDependencyWebResource.java
new file mode 100644
index 0000000..f7ddf96
--- /dev/null
+++ b/src/main/java/org/onosproject/cordvtn/rest/ServiceDependencyWebResource.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright 2015-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.cordvtn.rest;
+
+import org.onosproject.cordvtn.api.CordVtnService;
+import org.onosproject.rest.AbstractWebResource;
+import org.onosproject.xosclient.api.VtnServiceId;
+
+import javax.ws.rs.DELETE;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+
+/**
+ * Manages service dependency.
+ */
+@Path("service-dependency")
+public class ServiceDependencyWebResource extends AbstractWebResource {
+
+    private final CordVtnService service = get(CordVtnService.class);
+    private static final String BIDIRECTION = "b";
+
+    /**
+     * Creates service dependencies with unidirectional access between the services.
+     *
+     * @param tServiceId tenant service id
+     * @param pServiceId provider service id
+     * @return 200 OK
+     */
+    @POST
+    @Path("{tenantServiceId}/{providerServiceId}")
+    @Produces(MediaType.APPLICATION_JSON)
+    public Response createServiceDependency(@PathParam("tenantServiceId") String tServiceId,
+                                            @PathParam("providerServiceId") String pServiceId) {
+        service.createServiceDependency(VtnServiceId.of(tServiceId),
+                                        VtnServiceId.of(pServiceId),
+                                        false);
+        return Response.status(Response.Status.OK).build();
+    }
+
+    /**
+     * Creates service dependencies with an access type extension between the services.
+     *
+     * @param tServiceId tenant service id
+     * @param pServiceId provider service id
+     * @param direction b for bidirectional access, otherwise unidirectional access
+     * @return 200 OK
+     */
+    @POST
+    @Path("{tenantServiceId}/{providerServiceId}/{direction}")
+    @Produces(MediaType.APPLICATION_JSON)
+    public Response createServiceDependency(@PathParam("tenantServiceId") String tServiceId,
+                                            @PathParam("providerServiceId") String pServiceId,
+                                            @PathParam("direction") String direction) {
+        service.createServiceDependency(VtnServiceId.of(tServiceId),
+                                        VtnServiceId.of(pServiceId),
+                                        direction.equals(BIDIRECTION));
+        return Response.status(Response.Status.OK).build();
+    }
+
+    /**
+     * Removes service dependencies.
+     *
+     * @param tServiceId tenant service id
+     * @param pServiceId provider service id
+     * @return 204 NO CONTENT
+     */
+    @DELETE
+    @Path("{tenantServiceId}/{providerServiceId}")
+    public Response removeServiceDependency(@PathParam("tenantServiceId") String tServiceId,
+                                            @PathParam("providerServiceId") String pServiceId) {
+        service.removeServiceDependency(VtnServiceId.of(tServiceId), VtnServiceId.of(pServiceId));
+        return Response.noContent().build();
+    }
+}
diff --git a/src/main/java/org/onosproject/cordvtn/rest/package-info.java b/src/main/java/org/onosproject/cordvtn/rest/package-info.java
new file mode 100644
index 0000000..0b7e606
--- /dev/null
+++ b/src/main/java/org/onosproject/cordvtn/rest/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2015-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.
+ */
+
+/**
+ * REST APIs for CORD VTN.
+ */
+package org.onosproject.cordvtn.rest;
\ No newline at end of file
diff --git a/src/main/resources/OSGI-INF/blueprint/shell-config.xml b/src/main/resources/OSGI-INF/blueprint/shell-config.xml
new file mode 100644
index 0000000..07704ce
--- /dev/null
+++ b/src/main/resources/OSGI-INF/blueprint/shell-config.xml
@@ -0,0 +1,35 @@
+<!--
+  ~ Copyright 2015-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.
+  -->
+<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
+
+    <command-bundle xmlns="http://karaf.apache.org/xmlns/shell/v1.1.0">
+        <command>
+            <action class="org.onosproject.cordvtn.cli.CordVtnNodeListCommand"/>
+        </command>
+        <command>
+            <action class="org.onosproject.cordvtn.cli.CordVtnNodeDeleteCommand"/>
+        </command>
+        <command>
+            <action class="org.onosproject.cordvtn.cli.CordVtnNodeInitCommand"/>
+        </command>
+        <command>
+            <action class="org.onosproject.cordvtn.cli.CordVtnNodeCheckCommand"/>
+        </command>
+        <command>
+            <action class="org.onosproject.cordvtn.cli.CordVtnFlushRules"/>
+        </command>
+    </command-bundle>
+</blueprint>
diff --git a/src/main/webapp/WEB-INF/web.xml b/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 0000000..37aea15
--- /dev/null
+++ b/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Copyright 2015-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.
+  -->
+<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xmlns="http://java.sun.com/xml/ns/javaee"
+         xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
+         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
+         id="ONOS" version="2.5">
+    <display-name>CORD VTN REST API v1.0</display-name>
+
+    <security-constraint>
+        <web-resource-collection>
+            <web-resource-name>Secured</web-resource-name>
+            <url-pattern>/*</url-pattern>
+        </web-resource-collection>
+        <auth-constraint>
+            <role-name>admin</role-name>
+        </auth-constraint>
+    </security-constraint>
+
+    <security-role>
+        <role-name>admin</role-name>
+    </security-role>
+
+    <login-config>
+        <auth-method>BASIC</auth-method>
+        <realm-name>karaf</realm-name>
+    </login-config>
+
+    <servlet>
+        <servlet-name>JAX-RS Service</servlet-name>
+        <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
+        <init-param>
+            <param-name>javax.ws.rs.Application</param-name>
+            <param-value>org.onosproject.cordvtn.rest.CordVtnWebApplication</param-value>
+        </init-param>
+        <load-on-startup>1</load-on-startup>
+    </servlet>
+
+    <servlet-mapping>
+        <servlet-name>JAX-RS Service</servlet-name>
+        <url-pattern>/*</url-pattern>
+    </servlet-mapping>
+</web-app>
