diff --git a/BUCK b/BUCK
index 07e1fc0..2a7d8ca 100644
--- a/BUCK
+++ b/BUCK
@@ -11,6 +11,7 @@
     '//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',
 ]
@@ -35,5 +36,5 @@
     included_bundles = BUNDLES,
     excluded_bundles = EXCLUDED_BUNDLES,
     description = 'APIs for interacting with the CORD VTN application.',
-    required_apps = [ 'org.onosproject.xosclient', 'org.onosproject.dhcp', 'org.onosproject.ovsdb' ],
+    required_apps = [ 'org.onosproject.cord-config', 'org.onosproject.xosclient', 'org.onosproject.dhcp', 'org.onosproject.ovsdb' ],
 )
diff --git a/app.xml b/app.xml
index 7e8f409..17583ce 100644
--- a/app.xml
+++ b/app.xml
@@ -18,7 +18,7 @@
         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">
+        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/pom.xml b/pom.xml
index f2338f8..fa6e068 100644
--- a/pom.xml
+++ b/pom.xml
@@ -108,6 +108,11 @@
             <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>
diff --git a/src/main/java/org/onosproject/cordvtn/api/CordVtnConfig.java b/src/main/java/org/onosproject/cordvtn/api/CordVtnConfig.java
index b50d6fc..be097ce 100644
--- a/src/main/java/org/onosproject/cordvtn/api/CordVtnConfig.java
+++ b/src/main/java/org/onosproject/cordvtn/api/CordVtnConfig.java
@@ -20,6 +20,7 @@
 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;
@@ -46,6 +47,7 @@
     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";
@@ -187,6 +189,25 @@
     }
 
     /**
+     * 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
diff --git a/src/main/java/org/onosproject/cordvtn/api/CordVtnService.java b/src/main/java/org/onosproject/cordvtn/api/CordVtnService.java
index bd25b0f..1a8849e 100644
--- a/src/main/java/org/onosproject/cordvtn/api/CordVtnService.java
+++ b/src/main/java/org/onosproject/cordvtn/api/CordVtnService.java
@@ -15,14 +15,8 @@
  */
 package org.onosproject.cordvtn.api;
 
-import org.onlab.packet.IpAddress;
-import org.onlab.packet.MacAddress;
-import org.onosproject.net.ConnectPoint;
-import org.onosproject.net.HostId;
 import org.onosproject.xosclient.api.VtnServiceId;
 
-import java.util.Map;
-
 /**
  * Service for provisioning overlay virtual networks on compute nodes.
  */
@@ -31,21 +25,6 @@
     String CORDVTN_APP_ID = "org.onosproject.cordvtn";
 
     /**
-     * Adds a new VM on a given node and connect point.
-     *
-     * @param node cordvtn node
-     * @param connectPoint connect point
-     */
-    void addServiceVm(CordVtnNode node, ConnectPoint connectPoint);
-
-    /**
-     * Removes a VM from a given node and connect point.
-     *
-     * @param connectPoint connect point
-     */
-    void removeServiceVm(ConnectPoint connectPoint);
-
-    /**
      * Creates dependencies for a given tenant service.
      *
      * @param tServiceId id of the service which has a dependency
@@ -62,14 +41,4 @@
      * @param pServiceId id of the service which provide dependency
      */
     void removeServiceDependency(VtnServiceId tServiceId, VtnServiceId pServiceId);
-
-    /**
-     * Updates virtual service gateways.
-     *
-     * @param vSgHost host id of vSG host
-     * @param serviceVlan service vlan id
-     * @param vSgs map of ip and mac address of vSGs running in this vSG host
-     */
-    void updateVirtualSubscriberGateways(HostId vSgHost, String serviceVlan,
-                                         Map<IpAddress, MacAddress> vSgs);
 }
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/cli/CordVtnFlushRules.java b/src/main/java/org/onosproject/cordvtn/cli/CordVtnFlushRules.java
index f428ea4..228d06c 100644
--- a/src/main/java/org/onosproject/cordvtn/cli/CordVtnFlushRules.java
+++ b/src/main/java/org/onosproject/cordvtn/cli/CordVtnFlushRules.java
@@ -18,7 +18,7 @@
 
 import org.apache.karaf.shell.commands.Command;
 import org.onosproject.cli.AbstractShellCommand;
-import org.onosproject.cordvtn.impl.CordVtnNodeManager;
+import org.onosproject.cordvtn.impl.CordVtnPipeline;
 
 /**
  * Deletes nodes from the service.
@@ -29,8 +29,8 @@
 
     @Override
     protected void execute() {
-        CordVtnNodeManager nodeManager = AbstractShellCommand.get(CordVtnNodeManager.class);
-        nodeManager.flushRules();
+        CordVtnPipeline pipeline = AbstractShellCommand.get(CordVtnPipeline.class);
+        pipeline.flushRules();
         print("Successfully flushed");
     }
 }
diff --git a/src/main/java/org/onosproject/cordvtn/impl/CordVtn.java b/src/main/java/org/onosproject/cordvtn/impl/CordVtn.java
index cfcdc4b..efa0e4a 100644
--- a/src/main/java/org/onosproject/cordvtn/impl/CordVtn.java
+++ b/src/main/java/org/onosproject/cordvtn/impl/CordVtn.java
@@ -15,7 +15,6 @@
  */
 package org.onosproject.cordvtn.impl;
 
-import com.google.common.base.Strings;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
 import com.google.common.collect.Sets;
@@ -27,210 +26,77 @@
 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.onlab.packet.Ip4Prefix;
 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.dhcp.DhcpService;
-import org.onosproject.mastership.MastershipService;
-import org.onosproject.net.ConnectPoint;
-import org.onosproject.net.DefaultAnnotations;
+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.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.flow.FlowRuleService;
+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.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.VtnPortId;
 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.List;
 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.impl.CordVtnPipeline.*;
+import static org.onosproject.net.group.DefaultGroupBucket.createSelectGroupBucket;
 import static org.slf4j.LoggerFactory.getLogger;
 
 /**
- * Provisions virtual tenant networks with service chaining capability
- * in OpenStack environment.
+ * Provisions service dependency capabilities between network services.
  */
 @Component(immediate = true)
 @Service
-public class CordVtn extends AbstractProvider implements CordVtnService, HostProvider {
+public class CordVtn extends CordVtnInstanceHandler implements CordVtnService {
 
     protected final Logger log = getLogger(getClass());
 
     @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 FlowRuleService flowRuleService;
-
-    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
-    protected PacketService packetService;
-
-    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
-    protected MastershipService mastershipService;
-
-    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
     protected GroupService groupService;
 
-    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
-    protected DhcpService dhcpService;
-
-    @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 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 String DEFAULT_TUNNEL = "vxlan";
-    private static final String SERVICE_ID = "serviceId";
-    private static final String PORT_ID = "vtnPortId";
-    private static final String DATA_PLANE_IP = "dataPlaneIp";
-    private static final String DATA_PLANE_INTF = "dataPlaneIntf";
-    private static final String S_TAG = "stag";
-    private static final String VSG_HOST_ID = "vsgHostId";
-    private static final String CREATE_TIME = "createTime";
-
-    private static final Ip4Address DEFAULT_DNS = Ip4Address.valueOf("8.8.8.8");
-
-    private final ExecutorService eventExecutor =
-            newSingleThreadScheduledExecutor(groupedThreads("onos/cordvtn", "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 CordVtnRuleInstaller ruleInstaller;
-    private CordVtnArpProxy arpProxy;
-
-    private volatile XosAccess xosAccess = null;
-    private volatile OpenStackAccess osAccess = null;
-    private volatile MacAddress privateGatewayMac = MacAddress.NONE;
-
-    /**
-     * Creates an cordvtn host location provider.
-     */
-    public CordVtn() {
-        super(new ProviderId("host", CORDVTN_APP_ID));
-    }
-
     @Activate
     protected void activate() {
-        appId = coreService.registerApplication(CordVtnService.CORDVTN_APP_ID);
-        ruleInstaller = new CordVtnRuleInstaller(appId, flowRuleService,
-                                                 deviceService,
-                                                 groupService,
-                                                 hostService,
-                                                 configRegistry,
-                                                 DEFAULT_TUNNEL);
-
-        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");
+        eventExecutor = newSingleThreadScheduledExecutor(groupedThreads("onos/cordvtn", "event-handler"));
+        hostListener = new InternalHostListener();
+        super.activate();
     }
 
     @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.
-         */
+        super.deactivate();
     }
 
     @Override
     public void createServiceDependency(VtnServiceId tServiceId, VtnServiceId pServiceId,
                                         boolean isBidirectional) {
-        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 tService = serviceApi.service(tServiceId, osAccess);
-        VtnService pService = serviceApi.service(pServiceId, osAccess);
+        VtnService tService = getVtnService(tServiceId);
+        VtnService pService = getVtnService(pServiceId);
 
         if (tService == null || pService == null) {
             log.error("Failed to create dependency between {} and {}",
@@ -239,18 +105,13 @@
         }
 
         log.info("Created dependency between {} and {}", tService.name(), pService.name());
-        ruleInstaller.populateServiceDependencyRules(tService, pService, isBidirectional, true);
+        serviceDependencyRules(tService, pService, isBidirectional, true);
     }
 
     @Override
     public void removeServiceDependency(VtnServiceId tServiceId, VtnServiceId pServiceId) {
-        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 tService = serviceApi.service(tServiceId, osAccess);
-        VtnService pService = serviceApi.service(pServiceId, osAccess);
+        VtnService tService = getVtnService(tServiceId);
+        VtnService pService = getVtnService(pServiceId);
 
         if (tService == null || pService == null) {
             log.error("Failed to remove dependency between {} and {}",
@@ -259,427 +120,267 @@
         }
 
         log.info("Removed dependency between {} and {}", tService.name(), pService.name());
-        ruleInstaller.populateServiceDependencyRules(tService, pService, true, false);
+        serviceDependencyRules(tService, pService, true, false);
     }
 
     @Override
-    public void addServiceVm(CordVtnNode node, ConnectPoint connectPoint) {
-        checkNotNull(osAccess, OPENSTACK_ACCESS_ERROR);
-        checkNotNull(xosAccess, XOS_ACCESS_ERROR);
-
-        Port port = deviceService.getPort(connectPoint.deviceId(), connectPoint.port());
-        String portName = port.annotations().value("portName");
-
-        // 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);
+    public void instanceDetected(Instance instance) {
+        VtnService service = getVtnService(instance.serviceId());
+        if (service == null) {
             return;
         }
 
-        // Added CREATE_TIME intentionally to trigger HOST_UPDATED event for the
-        // existing instances.
-        DefaultAnnotations.Builder annotations = DefaultAnnotations.builder()
-                .set(SERVICE_ID, vtnPort.serviceId().id())
-                .set(PORT_ID, vtnPort.id().id())
-                .set(DATA_PLANE_IP, node.dpIp().ip().toString())
-                .set(DATA_PLANE_INTF, node.dpIntf())
-                .set(CREATE_TIME, String.valueOf(System.currentTimeMillis()));
+        // 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));
 
-        // TODO address service specific task in a separate package
-        String serviceVlan = getServiceVlan(vtnPort);
-        if (!Strings.isNullOrEmpty(serviceVlan)) {
-            annotations.set(S_TAG, serviceVlan);
-        }
-
-        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);
+        updateProviderServiceInstances(service);
     }
 
     @Override
-    public void removeServiceVm(ConnectPoint connectPoint) {
-        hostService.getConnectedHosts(connectPoint)
-                .stream()
-                .forEach(host -> hostProvider.hostVanished(host.id()));
-    }
-
-    @Override
-    // TODO address service specific task in a separate package
-    public void updateVirtualSubscriberGateways(HostId vSgHostId, String serviceVlan,
-                                                Map<IpAddress, MacAddress> vSgs) {
-        Host vSgHost = hostService.getHost(vSgHostId);
-        if (vSgHost == null || !vSgHost.annotations().value(S_TAG).equals(serviceVlan)) {
-            log.debug("Invalid vSG updates for {}", serviceVlan);
+    public void instanceRemoved(Instance instance) {
+        VtnService service = getVtnService(instance.serviceId());
+        if (service == null) {
             return;
         }
 
-        log.info("Updates vSGs in {} with {}", vSgHost.id(), vSgs.toString());
-        vSgs.entrySet().stream()
-                .filter(entry -> hostService.getHostsByMac(entry.getValue()).isEmpty())
-                .forEach(entry -> addVirtualSubscriberGateway(
-                        vSgHost,
-                        entry.getKey(),
-                        entry.getValue(),
-                        serviceVlan));
-
-        hostService.getConnectedHosts(vSgHost.location()).stream()
-                .filter(host -> !host.mac().equals(vSgHost.mac()))
-                .filter(host -> !vSgs.values().contains(host.mac()))
-                .forEach(host -> {
-                    log.info("Removed vSG {}", host.toString());
-                    hostProvider.hostVanished(host.id());
-                });
-    }
-
-    /**
-     * Adds virtual subscriber gateway to the system.
-     *
-     * @param vSgHost host virtual machine of this vSG
-     * @param vSgIp vSG ip address
-     * @param vSgMac vSG mac address
-     * @param serviceVlan service vlan
-     */
-    // TODO address service specific task in a separate package
-    private void addVirtualSubscriberGateway(Host vSgHost, IpAddress vSgIp, MacAddress vSgMac,
-                                             String serviceVlan) {
-        log.info("vSG with IP({}) MAC({}) added", vSgIp.toString(), vSgMac.toString());
-
-        HostId hostId = HostId.hostId(vSgMac);
-        DefaultAnnotations.Builder annotations = DefaultAnnotations.builder()
-                .set(S_TAG, serviceVlan)
-                .set(VSG_HOST_ID, vSgHost.id().toString())
-                .set(CREATE_TIME, String.valueOf(System.currentTimeMillis()));
-
-        HostDescription hostDesc = new DefaultHostDescription(
-                vSgMac,
-                VlanId.NONE,
-                vSgHost.location(),
-                Sets.newHashSet(vSgIp),
-                annotations.build());
-
-        hostProvider.hostDetected(hostId, hostDesc, false);
-    }
-
-    /**
-     * Returns public ip addresses of vSGs running inside a give vSG host.
-     *
-     * @param vSgHost vSG host
-     * @return map of ip and mac address, or empty map
-     */
-    // TODO address service specific task in a separate package
-    private Map<IpAddress, MacAddress> getSubscriberGateways(Host vSgHost) {
-        checkNotNull(osAccess, OPENSTACK_ACCESS_ERROR);
-        checkNotNull(xosAccess, XOS_ACCESS_ERROR);
-
-        String vtnPortId = vSgHost.annotations().value(PORT_ID);
-        String sTag = vSgHost.annotations().value(S_TAG);
-
-        if (Strings.isNullOrEmpty(vtnPortId) || Strings.isNullOrEmpty(sTag)) {
-            log.warn("PORT_ID and S_TAG is not set, ignore {}", vSgHost);
-            return Maps.newHashMap();
+        if (!service.providerServices().isEmpty()) {
+            removeInstanceFromTenantService(instance, service);
         }
-
-        // TODO remove openstack access when XOS provides all information
-        VtnPortApi portApi = xosClient.getClient(xosAccess).vtnPort();
-        VtnPort vtnPort = portApi.vtnPort(VtnPortId.of(vtnPortId), osAccess);
-        if (vtnPort == null) {
-            log.warn("Failed to get port information of {}", vSgHost);
-            return Maps.newHashMap();
-        }
-
-        if (!sTag.equals(getServiceVlan(vtnPort))) {
-            log.error("Host({}) s-tag does not match with VTN port s-tag", vSgHost);
-            return Maps.newHashMap();
-        }
-        return vtnPort.addressPairs();
-    }
-
-    /**
-     * Returns s-tag from a given VTN port.
-     *
-     * @param vtnPort vtn port
-     * @return s-tag string
-     */
-    // TODO address service specific task in a separate package
-    private String getServiceVlan(VtnPort vtnPort) {
-        checkNotNull(vtnPort);
-
-        String portName = vtnPort.name();
-        if (portName != null && portName.startsWith(S_TAG)) {
-            return portName.split("-")[1];
-        } else {
-            return null;
+        if (!service.tenantServices().isEmpty()) {
+            updateProviderServiceInstances(service);
         }
     }
 
-    /**
-     * Returns instances with a given network service.
-     *
-     * @param serviceId service id
-     * @return set of hosts
-     */
-    private Set<Host> getInstances(VtnServiceId serviceId) {
-        return StreamSupport.stream(hostService.getHosts().spliterator(), false)
-                .filter(host -> Objects.equals(
-                        serviceId.id(),
-                        host.annotations().value(SERVICE_ID)))
+    private void updateProviderServiceInstances(VtnService service) {
+        GroupKey groupKey = getGroupKey(service.id());
+
+        Set<DeviceId> devices = nodeManager.completeNodes().stream()
+                .map(CordVtnNode::intBrId)
                 .collect(Collectors.toSet());
-    }
 
-    /**
-     * Registers static DHCP lease for a given host.
-     *
-     * @param host host
-     * @param service cord service
-     */
-    private void registerDhcpLease(Host host, VtnService service) {
-        List<Ip4Address> options = Lists.newArrayList();
-        options.add(Ip4Address.makeMaskPrefix(service.subnet().prefixLength()));
-        options.add(service.serviceIp().getIp4Address());
-        options.add(service.serviceIp().getIp4Address());
-        options.add(DEFAULT_DNS);
-
-        log.debug("Set static DHCP mapping for {}", host.mac());
-        dhcpService.setStaticMapping(host.mac(),
-                                     host.ipAddresses().stream().findFirst().get().getIp4Address(),
-                                     true,
-                                     options);
-    }
-
-    /**
-     * Handles VM detected situation.
-     *
-     * @param host host
-     */
-    private void serviceVmAdded(Host host) {
-        checkNotNull(osAccess, OPENSTACK_ACCESS_ERROR);
-        checkNotNull(xosAccess, XOS_ACCESS_ERROR);
-
-        // TODO address service specific task in a separate package
-        String serviceVlan = host.annotations().value(S_TAG);
-        if (serviceVlan != null) {
-            virtualSubscriberGatewayAdded(host, serviceVlan);
-        }
-
-        String serviceId = host.annotations().value(SERVICE_ID);
-        if (Strings.isNullOrEmpty(serviceId)) {
-            // ignore this host, it is not a service instance
-            return;
-        }
-
-        log.info("Instance is detected {}", host);
-
-        // TODO remove openstack access when XOS provides all information
-        VtnServiceApi serviceApi = xosClient.getClient(xosAccess).vtnService();
-        VtnService service = serviceApi.service(VtnServiceId.of(serviceId), osAccess);
-        if (service == null) {
-            log.warn("Failed to get VtnService for {}", serviceId);
-            return;
-        }
-
-        switch (service.networkType()) {
-            case MANAGEMENT:
-                ruleInstaller.populateManagementNetworkRules(host, service);
-                break;
-            case PRIVATE:
-                arpProxy.addGateway(service.serviceIp(), privateGatewayMac);
-            case PUBLIC:
-            default:
-                // 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));
-
-                ruleInstaller.updateProviderServiceGroup(service);
-                // sends gratuitous ARP here for the case of adding existing VMs
-                // when ONOS or cordvtn app is restarted
-                arpProxy.sendGratuitousArpForGateway(service.serviceIp(), Sets.newHashSet(host));
-                break;
-        }
-
-        registerDhcpLease(host, service);
-        ruleInstaller.populateBasicConnectionRules(host, service, true);
-    }
-
-    /**
-     * Handles VM removed situation.
-     *
-     * @param host host
-     */
-    private void serviceVmRemoved(Host host) {
-        checkNotNull(osAccess, OPENSTACK_ACCESS_ERROR);
-        checkNotNull(xosAccess, XOS_ACCESS_ERROR);
-
-        // TODO address service specific task in a separate package
-        if (host.annotations().value(S_TAG) != null) {
-            virtualSubscriberGatewayRemoved(host);
-        }
-
-        String serviceId = host.annotations().value(SERVICE_ID);
-        if (Strings.isNullOrEmpty(serviceId)) {
-            // ignore this host, it is not a service instance
-            return;
-        }
-
-        log.info("Instance is vanished {}", host);
-
-        // TODO remove openstack access when XOS provides all information
-        VtnServiceApi vtnServiceApi = xosClient.getClient(xosAccess).vtnService();
-        VtnService service = vtnServiceApi.service(VtnServiceId.of(serviceId), osAccess);
-        if (service == null) {
-            log.warn("Failed to get VtnService for {}", serviceId);
-            return;
-        }
-
-        // TODO need to consider the case that the service is removed also
-        switch (service.networkType()) {
-            case MANAGEMENT:
-                break;
-            case PRIVATE:
-                if (getInstances(VtnServiceId.of(serviceId)).isEmpty()) {
-                    arpProxy.removeGateway(service.serviceIp());
-                }
-            case PUBLIC:
-            default:
-                if (!service.tenantServices().isEmpty()) {
-                    ruleInstaller.updateProviderServiceGroup(service);
-                }
-                if (!service.providerServices().isEmpty()) {
-                    ruleInstaller.updateTenantServiceVm(host, service);
-                }
-                break;
-        }
-
-        dhcpService.removeStaticMapping(host.mac());
-        ruleInstaller.populateBasicConnectionRules(host, service, false);
-    }
-
-
-    /**
-     * Handles virtual subscriber gateway VM or container.
-     *
-     * @param host new host with stag, it can be vsg VM or vsg
-     * @param serviceVlan service vlan
-     */
-    // TODO address service specific task in a separate package
-    private void virtualSubscriberGatewayAdded(Host host, String serviceVlan) {
-        Map<IpAddress, MacAddress> vSgs;
-        Host vSgHost;
-
-        String vSgHostId = host.annotations().value(VSG_HOST_ID);
-        if (vSgHostId == null) {
-            log.info("vSG VM detected {}", host.id());
-
-            vSgHost = host;
-            vSgs = getSubscriberGateways(vSgHost);
-            vSgs.entrySet().stream().forEach(entry -> addVirtualSubscriberGateway(
-                    vSgHost,
-                    entry.getKey(),
-                    entry.getValue(),
-                    serviceVlan));
-        } else {
-            vSgHost = hostService.getHost(HostId.hostId(vSgHostId));
-            if (vSgHost == null) {
-                return;
+        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;
             }
 
-            log.info("vSG detected {}", host.id());
-            vSgs = getSubscriberGateways(vSgHost);
-        }
+            List<GroupBucket> oldBuckets = group.buckets().buckets();
+            List<GroupBucket> newBuckets = getServiceGroupBuckets(
+                    deviceId, service.vni(), getInstances(service.id())).buckets();
 
-        ruleInstaller.populateSubscriberGatewayRules(vSgHost, vSgs.keySet());
-    }
-
-    /**
-     * Handles virtual subscriber gateway removed.
-     *
-     * @param vSg vsg host to remove
-     */
-    // TODO address service specific task in a separate package
-    private void virtualSubscriberGatewayRemoved(Host vSg) {
-        String vSgHostId = vSg.annotations().value(VSG_HOST_ID);
-        if (vSgHostId == null) {
-            return;
-        }
-
-        Host vSgHost = hostService.getHost(HostId.hostId(vSgHostId));
-        if (vSgHost == null) {
-            return;
-        }
-
-        log.info("vSG removed {}", vSg.id());
-        Map<IpAddress, MacAddress> vSgs = getSubscriberGateways(vSgHost);
-        ruleInstaller.populateSubscriberGatewayRules(vSgHost, vSgs.keySet());
-    }
-
-    /**
-     * Sets service network gateway MAC address and sends out gratuitous ARP to all
-     * VMs to update the gateway MAC address.
-     *
-     * @param newMac mac address to update
-     */
-    private void setPrivateGatewayMac(MacAddress newMac) {
-        checkNotNull(osAccess, OPENSTACK_ACCESS_ERROR);
-        checkNotNull(xosAccess, XOS_ACCESS_ERROR);
-
-        if (newMac == null || newMac.equals(privateGatewayMac)) {
-            // no updates, do nothing
-            return;
-        }
-
-        privateGatewayMac = newMac;
-        log.debug("Set service gateway MAC address to {}", privateGatewayMac.toString());
-
-        VtnServiceApi vtnServiceApi = xosClient.getClient(xosAccess).vtnService();
-        vtnServiceApi.services().stream().forEach(serviceId -> {
-            VtnService service = vtnServiceApi.service(serviceId, osAccess);
-            if (service != null) {
-                arpProxy.addGateway(service.serviceIp(), privateGatewayMac);
-                arpProxy.sendGratuitousArpForGateway(service.serviceIp(), getInstances(serviceId));
+            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);
         });
     }
 
-    /**
-     * Sets public gateway MAC address.
-     *
-     * @param publicGateways gateway ip and mac address pairs
-     */
-    private void setPublicGatewayMac(Map<IpAddress, MacAddress> publicGateways) {
-        publicGateways.entrySet()
-                .stream()
-                .forEach(entry -> {
-                    arpProxy.addGateway(entry.getKey(), entry.getValue());
-                    log.debug("Added public gateway IP {}, MAC {}",
-                              entry.getKey().toString(), entry.getValue().toString());
-                });
-        // TODO notice gateway MAC change to VMs holds this gateway IP
+    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);
     }
 
-    /**
-     * Updates configurations.
-     */
-    private void readConfiguration() {
-        CordVtnConfig config = configRegistry.getConfig(appId, CordVtnConfig.class);
-        if (config == null) {
-            log.debug("No configuration found");
-            return;
+    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;
         }
 
-        xosAccess = config.xosAccess();
-        osAccess = config.openstackAccess();
+        GroupBuckets buckets = getServiceGroupBuckets(
+                deviceId, service.vni(), getInstances(service.id()));
+        GroupDescription groupDescription = new DefaultGroupDescription(
+                deviceId,
+                GroupDescription.Type.SELECT,
+                buckets,
+                groupKey,
+                groupId.id(),
+                appId);
 
-        setPrivateGatewayMac(config.privateGatewayMac());
-        setPublicGatewayMac(config.publicGateways());
+        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 {
@@ -692,50 +393,14 @@
                 return;
             }
 
+            Instance instance = Instance.of(host);
             switch (event.type()) {
                 case HOST_UPDATED:
                 case HOST_ADDED:
-                    eventExecutor.execute(() -> serviceVmAdded(host));
+                    eventExecutor.execute(() -> instanceDetected(instance));
                     break;
                 case HOST_REMOVED:
-                    eventExecutor.execute(() -> serviceVmRemoved(host));
-                    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:
-                    log.info("Network configuration changed");
-                    eventExecutor.execute(CordVtn.this::readConfiguration);
+                    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
index c0b1d61..8200fcc 100644
--- a/src/main/java/org/onosproject/cordvtn/impl/CordVtnArpProxy.java
+++ b/src/main/java/org/onosproject/cordvtn/impl/CordVtnArpProxy.java
@@ -22,6 +22,7 @@
 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;
@@ -166,9 +167,9 @@
      * Emits gratuitous ARP when a gateway mac address has been changed.
      *
      * @param gatewayIp gateway ip address to update MAC
-     * @param hosts set of hosts to send gratuitous ARP packet
+     * @param instances set of instances to send gratuitous ARP packet
      */
-    public void sendGratuitousArpForGateway(IpAddress gatewayIp, Set<Host> hosts) {
+    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());
@@ -176,13 +177,13 @@
         }
 
         Ethernet ethArp = buildGratuitousArp(gatewayIp.getIp4Address(), gatewayMac);
-        hosts.stream().forEach(host -> {
+        instances.stream().forEach(instance -> {
             TrafficTreatment treatment = DefaultTrafficTreatment.builder()
-                    .setOutput(host.location().port())
+                    .setOutput(instance.portNumber())
                     .build();
 
             packetService.emit(new DefaultOutboundPacket(
-                    host.location().deviceId(),
+                    instance.deviceId(),
                     treatment,
                     ByteBuffer.wrap(ethArp.serialize())));
         });
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..4b85c27
--- /dev/null
+++ b/src/main/java/org/onosproject/cordvtn/impl/CordVtnInstanceManager.java
@@ -0,0 +1,428 @@
+/*
+ * 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.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.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.List;
+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.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");
+
+    @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) {
+        List<Ip4Address> options = Lists.newArrayList();
+        options.add(Ip4Address.makeMaskPrefix(service.subnet().prefixLength()));
+        options.add(service.serviceIp().getIp4Address());
+        options.add(service.serviceIp().getIp4Address());
+        options.add(DEFAULT_DNS);
+
+        log.debug("Set static DHCP mapping for {} {}", instance.mac(), instance.ipAddress());
+        dhcpService.setStaticMapping(instance.mac(),
+                                     instance.ipAddress(),
+                                     true,
+                                     options);
+    }
+
+    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
index a3e7bd4..7fa6c5c 100644
--- a/src/main/java/org/onosproject/cordvtn/impl/CordVtnNodeManager.java
+++ b/src/main/java/org/onosproject/cordvtn/impl/CordVtnNodeManager.java
@@ -44,6 +44,7 @@
 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;
@@ -59,8 +60,6 @@
 import org.onosproject.net.device.DeviceEvent;
 import org.onosproject.net.device.DeviceListener;
 import org.onosproject.net.device.DeviceService;
-import org.onosproject.net.flow.FlowRuleService;
-import org.onosproject.net.group.GroupService;
 import org.onosproject.net.host.HostService;
 import org.onosproject.ovsdb.controller.OvsdbClientService;
 import org.onosproject.ovsdb.controller.OvsdbController;
@@ -86,6 +85,7 @@
 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;
@@ -110,7 +110,6 @@
             .register(NetworkAddress.class);
 
     private static final String DEFAULT_BRIDGE = "br-int";
-    private static final String DEFAULT_TUNNEL = "vxlan";
     private static final String VPORT_PREFIX = "tap";
     private static final String OK = "OK";
     private static final String NO = "NO";
@@ -152,19 +151,16 @@
     protected HostService hostService;
 
     @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
-    protected FlowRuleService flowRuleService;
-
-    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
     protected LeadershipService leadershipService;
 
     @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
-    protected GroupService groupService;
+    protected CordVtnInstanceManager instanceManager;
 
     @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
-    protected CordVtnService cordVtnService;
+    protected CordVtnPipeline pipeline;
 
     private final ExecutorService eventExecutor =
-            newSingleThreadScheduledExecutor(groupedThreads("onos/cordvtncfg", "event-handler"));
+            newSingleThreadScheduledExecutor(groupedThreads("onos/cordvtn-node", "event-handler"));
 
     private final NetworkConfigListener configListener = new InternalConfigListener();
     private final DeviceListener deviceListener = new InternalDeviceListener();
@@ -174,7 +170,6 @@
     private final BridgeHandler bridgeHandler = new BridgeHandler();
 
     private ConsistentMap<String, CordVtnNode> nodeStore;
-    private CordVtnRuleInstaller ruleInstaller;
     private ApplicationId appId;
     private NodeId localNodeId;
 
@@ -225,6 +220,7 @@
     @Activate
     protected void activate() {
         appId = coreService.getAppId(CordVtnService.CORDVTN_APP_ID);
+
         localNodeId = clusterService.getLocalNode().id();
         leadershipService.runForLeadership(appId.name());
 
@@ -234,13 +230,6 @@
                 .withApplicationId(appId)
                 .build();
 
-        ruleInstaller = new CordVtnRuleInstaller(appId, flowRuleService,
-                                                 deviceService,
-                                                 groupService,
-                                                 hostService,
-                                                 configRegistry,
-                                                 DEFAULT_TUNNEL);
-
         nodeStore.addListener(nodeStoreListener);
         deviceService.addListener(deviceListener);
         configService.addListener(configListener);
@@ -286,20 +275,6 @@
     }
 
     /**
-     * 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);
-    }
-
-    /**
      * Returns node initialization state.
      *
      * @param node cordvtn node
@@ -311,30 +286,6 @@
     }
 
     /**
-     * Flush flows installed by cordvtn.
-     */
-    public void flushRules() {
-        ruleInstaller.flushRules();
-    }
-
-    /**
-     * 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);
-    }
-
-    /**
      * Returns detailed node initialization state.
      *
      * @param node cordvtn node
@@ -392,33 +343,122 @@
      * @return list of nodes
      */
     public List<CordVtnNode> getNodes() {
-        return nodeStore.values().stream()
-                .map(Versioned::value)
-                .collect(Collectors.toList());
+        return nodeStore.values().stream().map(Versioned::value).collect(Collectors.toList());
     }
 
     /**
-     * Returns cordvtn node associated with a given OVSDB device.
+     * Returns all nodes in complete state.
      *
-     * @param ovsdbId OVSDB device id
-     * @return cordvtn node, null if it fails to find the node
+     * @return set of nodes
      */
-    private CordVtnNode getNodeByOvsdbId(DeviceId ovsdbId) {
-        return getNodes().stream()
-                .filter(node -> node.ovsdbId().equals(ovsdbId))
-                .findFirst().orElse(null);
+    public Set<CordVtnNode> completeNodes() {
+        return getNodes().stream().filter(this::isNodeInitComplete).collect(Collectors.toSet());
     }
 
     /**
-     * Returns cordvtn node associated with a given integration bridge.
+     * Returns physical data plane port number of a given device.
      *
-     * @param bridgeId device id of integration bridge
-     * @return cordvtn node, null if it fails to find the node
+     * @param deviceId integration bridge device id
+     * @return port number; null otherwise
      */
-    private CordVtnNode getNodeByBridgeId(DeviceId bridgeId) {
-        return getNodes().stream()
-                .filter(node -> node.intBrId().equals(bridgeId))
+    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());
     }
 
     /**
@@ -456,45 +496,6 @@
     }
 
     /**
-     * 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);
-
-        ruleInstaller.init(node.intBrId(), node.dpIntf(), node.dpIp().ip());
-
-        // add existing hosts to the service
-        deviceService.getPorts(node.intBrId()).stream()
-                .filter(port -> getPortName(port).startsWith(VPORT_PREFIX) &&
-                        port.isEnabled())
-                .forEach(port -> cordVtnService.addServiceVm(node, getConnectPoint(port)));
-
-        // remove stale hosts from the service
-        hostService.getHosts().forEach(host -> {
-            Port port = deviceService.getPort(host.location().deviceId(), host.location().port());
-            if (port == null) {
-                cordVtnService.removeServiceVm(getConnectPoint(host));
-            }
-        });
-
-        log.info("Finished init {}", node.hostname());
-    }
-
-    /**
-     * Returns port name.
-     *
-     * @param port port
-     * @return port name
-     */
-    private String getPortName(Port port) {
-        return port.annotations().value("portName");
-    }
-
-    /**
      * Returns connection state of OVSDB server for a given node.
      *
      * @param node cordvtn node
@@ -587,7 +588,7 @@
                 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().toString());
+                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());
@@ -619,7 +620,7 @@
                 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().toString());
+                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());
@@ -654,7 +655,7 @@
                 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().toString());
+                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());
@@ -712,7 +713,7 @@
     private boolean isTunnelIntfCreated(CordVtnNode node) {
         return deviceService.getPorts(node.intBrId())
                     .stream()
-                    .filter(p -> getPortName(p).contains(DEFAULT_TUNNEL) &&
+                    .filter(p -> portName(p).contains(DEFAULT_TUNNEL) &&
                             p.isEnabled())
                     .findAny().isPresent();
     }
@@ -726,7 +727,7 @@
     private boolean isDataPlaneIntfAdded(CordVtnNode node) {
         return deviceService.getPorts(node.intBrId())
                     .stream()
-                    .filter(p -> getPortName(p).contains(node.dpIntf()) &&
+                    .filter(p -> portName(p).contains(node.dpIntf()) &&
                             p.isEnabled())
                     .findAny().isPresent();
     }
@@ -761,7 +762,7 @@
      * @param port port
      * @return connect point
      */
-    private ConnectPoint getConnectPoint(Port port) {
+    private ConnectPoint connectPoint(Port port) {
         return new ConnectPoint(port.element().id(), port.number());
     }
 
@@ -771,15 +772,49 @@
      * @param host host
      * @return connect point
      */
-    private ConnectPoint getConnectPoint(Host host) {
+    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 = getNodeByOvsdbId(device.id());
+            CordVtnNode node = nodeByOvsdbId(device.id());
             if (node != null) {
                 setNodeState(node, getNodeState(node));
             } else {
@@ -800,7 +835,7 @@
 
         @Override
         public void connected(Device device) {
-            CordVtnNode node = getNodeByBridgeId(device.id());
+            CordVtnNode node = nodeByBridgeId(device.id());
             if (node != null) {
                 setNodeState(node, getNodeState(node));
             } else {
@@ -810,7 +845,7 @@
 
         @Override
         public void disconnected(Device device) {
-            CordVtnNode node = getNodeByBridgeId(device.id());
+            CordVtnNode node = nodeByBridgeId(device.id());
             if (node != null) {
                 log.debug("Integration Bridge is disconnected from {}", node.hostname());
                 setNodeState(node, NodeState.INCOMPLETE);
@@ -825,8 +860,8 @@
          * @param port port
          */
         public void portAdded(Port port) {
-            CordVtnNode node = getNodeByBridgeId((DeviceId) port.element().id());
-            String portName = getPortName(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);
@@ -837,7 +872,7 @@
 
             if (portName.startsWith(VPORT_PREFIX)) {
                 if (isNodeStateComplete(node)) {
-                    cordVtnService.addServiceVm(node, getConnectPoint(port));
+                    instanceManager.addInstance(connectPoint(port));
                 } else {
                     log.debug("VM is detected on incomplete node, ignore it.", portName);
                 }
@@ -854,8 +889,8 @@
          * @param port port
          */
         public void portRemoved(Port port) {
-            CordVtnNode node = getNodeByBridgeId((DeviceId) port.element().id());
-            String portName = getPortName(port);
+            CordVtnNode node = nodeByBridgeId((DeviceId) port.element().id());
+            String portName = portName(port);
 
             if (node == null) {
                 return;
@@ -865,7 +900,7 @@
 
             if (portName.startsWith(VPORT_PREFIX)) {
                 if (isNodeStateComplete(node)) {
-                    cordVtnService.removeServiceVm(getConnectPoint(port));
+                    instanceManager.removeInstance(connectPoint(port));
                 } else {
                     log.debug("VM is vanished from incomplete node, ignore it.", portName);
                 }
@@ -922,7 +957,6 @@
             log.debug("No configuration found");
             return;
         }
-
         config.cordVtnNodes().forEach(this::addOrUpdateNode);
     }
 
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/CordVtnRuleInstaller.java b/src/main/java/org/onosproject/cordvtn/impl/CordVtnRuleInstaller.java
deleted file mode 100644
index e2be9a6..0000000
--- a/src/main/java/org/onosproject/cordvtn/impl/CordVtnRuleInstaller.java
+++ /dev/null
@@ -1,1387 +0,0 @@
-/*
- * 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.onlab.packet.Ethernet;
-import org.onlab.packet.IPv4;
-import org.onlab.packet.Ip4Address;
-import org.onlab.packet.Ip4Prefix;
-import org.onlab.packet.IpAddress;
-import org.onlab.packet.IpPrefix;
-import org.onlab.packet.MacAddress;
-import org.onlab.packet.TpPort;
-import org.onlab.packet.VlanId;
-import org.onlab.util.ItemNotFoundException;
-import org.onosproject.cordvtn.api.CordVtnConfig;
-import org.onosproject.cordvtn.api.CordVtnNode;
-import org.onosproject.core.ApplicationId;
-import org.onosproject.core.DefaultGroupId;
-import org.onosproject.core.GroupId;
-import org.onosproject.net.Device;
-import org.onosproject.net.DeviceId;
-import org.onosproject.net.Host;
-import org.onosproject.net.Port;
-import org.onosproject.net.PortNumber;
-import org.onosproject.net.behaviour.ExtensionTreatmentResolver;
-import org.onosproject.net.config.NetworkConfigRegistry;
-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.criteria.Criterion;
-import org.onosproject.net.flow.criteria.IPCriterion;
-import org.onosproject.net.flow.instructions.ExtensionPropertyException;
-import org.onosproject.net.flow.instructions.ExtensionTreatment;
-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.group.DefaultGroupBucket;
-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.HostService;
-import org.onosproject.xosclient.api.VtnService;
-import org.onosproject.xosclient.api.VtnServiceId;
-import org.slf4j.Logger;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Set;
-import java.util.stream.Collectors;
-import java.util.stream.StreamSupport;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-import static org.onosproject.net.flow.criteria.Criterion.Type.IPV4_DST;
-import static org.onosproject.net.flow.instructions.ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_SET_TUNNEL_DST;
-import static org.onosproject.net.flow.instructions.L2ModificationInstruction.L2SubType.VLAN_PUSH;
-import static org.slf4j.LoggerFactory.getLogger;
-
-/**
- * Populates rules for CORD VTN service.
- */
-public class CordVtnRuleInstaller {
-
-    protected final Logger log = getLogger(getClass());
-
-    private static final int TABLE_FIRST = 0;
-    private static final int TABLE_IN_PORT = 1;
-    private static final int TABLE_ACCESS_TYPE = 2;
-    private static final int TABLE_IN_SERVICE = 3;
-    private static final int TABLE_DST_IP = 4;
-    private static final int TABLE_TUNNEL_IN = 5;
-    private static final int TABLE_Q_IN_Q = 6;
-
-    private static final int MANAGEMENT_PRIORITY = 55000;
-    private static final int VSG_PRIORITY = 55000;
-    private static final int HIGH_PRIORITY = 50000;
-    private static final int DEFAULT_PRIORITY = 5000;
-    private static final int LOW_PRIORITY = 4000;
-    private static final int LOWEST_PRIORITY = 0;
-
-    private static final int VXLAN_UDP_PORT = 4789;
-    private static final VlanId VLAN_WAN = VlanId.vlanId((short) 500);
-
-    private static final String PORT_NAME = "portName";
-    private static final String DATA_PLANE_INTF = "dataPlaneIntf";
-    private static final String DATA_PLANE_IP = "dataPlaneIp";
-    private static final String S_TAG = "stag";
-    private static final String SERVICE_ID = "serviceId";
-
-    private final ApplicationId appId;
-    private final FlowRuleService flowRuleService;
-    private final DeviceService deviceService;
-    private final GroupService groupService;
-    private final HostService hostService;
-    private final NetworkConfigRegistry configRegistry;
-    private final String tunnelType;
-
-    /**
-     * Creates a new rule populator.
-     *
-     * @param appId application id
-     * @param flowRuleService flow rule service
-     * @param deviceService device service
-     * @param groupService group service
-     * @param configRegistry config registry
-     * @param tunnelType tunnel type
-     */
-    public CordVtnRuleInstaller(ApplicationId appId,
-                                FlowRuleService flowRuleService,
-                                DeviceService deviceService,
-                                GroupService groupService,
-                                HostService hostService,
-                                NetworkConfigRegistry configRegistry,
-                                String tunnelType) {
-        this.appId = appId;
-        this.flowRuleService = flowRuleService;
-        this.deviceService = deviceService;
-        this.groupService = groupService;
-        this.hostService = hostService;
-        this.configRegistry = configRegistry;
-        this.tunnelType = checkNotNull(tunnelType);
-    }
-
-    /**
-     * Installs table miss rule to a give device.
-     *
-     * @param deviceId device id to install the rules
-     * @param dpIntf data plane interface name
-     * @param dpIp data plane ip address
-     */
-    public void init(DeviceId deviceId, String dpIntf, IpAddress dpIp) {
-        // default is drop packets which can be accomplished without
-        // a table miss entry for all table.
-        PortNumber tunnelPort = getTunnelPort(deviceId);
-        PortNumber dpPort = getDpPort(deviceId, dpIntf);
-
-        processFirstTable(deviceId, dpPort, dpIp);
-        processInPortTable(deviceId, tunnelPort, dpPort);
-        processAccessTypeTable(deviceId, dpPort);
-        processQInQTable(deviceId, dpPort);
-    }
-
-    /**
-     * Flush flows installed by this application.
-     */
-    public void flushRules() {
-        flowRuleService.getFlowRulesById(appId).forEach(flowRule -> processFlowRule(false, flowRule));
-    }
-
-    /**
-     * Populates basic rules that connect a VM to the other VMs in the system.
-     *
-     * @param host host
-     * @param service cord service
-     * @param install true to install or false to remove
-     */
-    public void populateBasicConnectionRules(Host host, VtnService service, boolean install) {
-        checkNotNull(host);
-        checkNotNull(service);
-
-        DeviceId deviceId = host.location().deviceId();
-        PortNumber inPort = host.location().port();
-        MacAddress dstMac = host.mac();
-        IpAddress hostIp = host.ipAddresses().stream().findFirst().get();
-
-        long tunnelId = service.vni();
-        Ip4Prefix serviceIpRange = service.subnet().getIp4Prefix();
-
-        populateLocalInPortRule(deviceId, inPort, hostIp, install);
-        populateDstIpRule(deviceId, inPort, dstMac, hostIp, tunnelId, getTunnelIp(host), install);
-        populateTunnelInRule(deviceId, inPort, dstMac, tunnelId, install);
-
-        if (install) {
-            populateDirectAccessRule(serviceIpRange, serviceIpRange, true);
-            populateServiceIsolationRule(serviceIpRange, true);
-        } else if (getInstances(service.id()).isEmpty()) {
-            // removes network related rules only if there's no hosts left in this network
-            populateDirectAccessRule(serviceIpRange, serviceIpRange, false);
-            populateServiceIsolationRule(serviceIpRange, false);
-        }
-    }
-
-    /**
-     * Creates provider service group and populates service dependency rules.
-     *
-     * @param tService tenant cord service
-     * @param pService provider cord service
-     * @param isBidirectional true to enable bidirectional connection between two services
-     * @param install true to install or false to remove
-     */
-    public void populateServiceDependencyRules(VtnService tService, VtnService pService,
-                                               boolean isBidirectional, boolean install) {
-        checkNotNull(tService);
-        checkNotNull(pService);
-
-        Ip4Prefix srcRange = tService.subnet().getIp4Prefix();
-        Ip4Prefix dstRange = pService.subnet().getIp4Prefix();
-        Ip4Address serviceIp = pService.serviceIp().getIp4Address();
-
-        Map<DeviceId, GroupId> outGroups = Maps.newHashMap();
-        Map<DeviceId, Set<PortNumber>> inPorts = Maps.newHashMap();
-
-        getVirtualSwitches().stream().forEach(deviceId -> {
-            GroupId groupId = createServiceGroup(deviceId, pService);
-            outGroups.put(deviceId, groupId);
-
-            Set<PortNumber> tServiceVms = getInstances(tService.id())
-                    .stream()
-                    .filter(host -> host.location().deviceId().equals(deviceId))
-                    .map(host -> host.location().port())
-                    .collect(Collectors.toSet());
-            inPorts.put(deviceId, tServiceVms);
-        });
-
-        populateIndirectAccessRule(srcRange, serviceIp, outGroups, install);
-        populateDirectAccessRule(srcRange, dstRange, install);
-        if (isBidirectional) {
-            populateDirectAccessRule(dstRange, srcRange, install);
-        }
-        populateInServiceRule(inPorts, outGroups, install);
-    }
-
-    /**
-     * Updates group buckets for a given service to all devices.
-     *
-     * @param service cord service
-     */
-    public void updateProviderServiceGroup(VtnService service) {
-        checkNotNull(service);
-
-        GroupKey groupKey = getGroupKey(service.id());
-
-        for (DeviceId deviceId : getVirtualSwitches()) {
-            Group group = groupService.getGroup(deviceId, groupKey);
-            if (group == null) {
-                log.trace("No group exists for service {} in {}, do nothing.", 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 = new ArrayList<>(oldBuckets);
-            bucketsToRemove.removeAll(newBuckets);
-            if (!bucketsToRemove.isEmpty()) {
-                groupService.removeBucketsFromGroup(
-                        deviceId,
-                        groupKey,
-                        new GroupBuckets(bucketsToRemove),
-                        groupKey, appId);
-            }
-
-            List<GroupBucket> bucketsToAdd = new ArrayList<>(newBuckets);
-            bucketsToAdd.removeAll(oldBuckets);
-            if (!bucketsToAdd.isEmpty()) {
-                groupService.addBucketsToGroup(
-                        deviceId,
-                        groupKey,
-                        new GroupBuckets(bucketsToAdd),
-                        groupKey, appId);
-            }
-        }
-    }
-
-    /**
-     * Updates tenant service indirect access rules when VM is created or removed.
-     *
-     * @param host removed vm
-     * @param service tenant service
-     */
-    public void updateTenantServiceVm(Host host, VtnService service) {
-        checkNotNull(host);
-        checkNotNull(service);
-
-        DeviceId deviceId = host.location().deviceId();
-        PortNumber inPort = host.location().port();
-
-        service.providerServices().stream().forEach(pServiceId -> {
-            Map<DeviceId, Set<PortNumber>> inPorts = Maps.newHashMap();
-            Map<DeviceId, GroupId> outGroups = Maps.newHashMap();
-
-            inPorts.put(deviceId, Sets.newHashSet(inPort));
-            outGroups.put(deviceId, getGroupId(pServiceId, deviceId));
-
-            populateInServiceRule(inPorts, outGroups, false);
-        });
-    }
-
-    /**
-     * Populates flow rules for management network access.
-     *
-     * @param host host which has management network interface
-     * @param mService management network service
-     */
-    public void populateManagementNetworkRules(Host host, VtnService mService) {
-        checkNotNull(mService);
-
-        DeviceId deviceId = host.location().deviceId();
-        IpAddress hostIp = host.ipAddresses().stream().findFirst().get();
-
-        TrafficSelector selector = DefaultTrafficSelector.builder()
-                .matchEthType(Ethernet.TYPE_ARP)
-                .matchArpTpa(mService.serviceIp().getIp4Address())
-                .build();
-
-        TrafficTreatment treatment = DefaultTrafficTreatment.builder()
-                .setOutput(PortNumber.LOCAL)
-                .build();
-
-        FlowRule flowRule = DefaultFlowRule.builder()
-                .fromApp(appId)
-                .withSelector(selector)
-                .withTreatment(treatment)
-                .withPriority(MANAGEMENT_PRIORITY)
-                .forDevice(deviceId)
-                .forTable(TABLE_FIRST)
-                .makePermanent()
-                .build();
-
-        processFlowRule(true, flowRule);
-
-        selector = DefaultTrafficSelector.builder()
-                .matchInPort(PortNumber.LOCAL)
-                .matchEthType(Ethernet.TYPE_ARP)
-                .matchArpTpa(hostIp.getIp4Address())
-                .build();
-
-        treatment = DefaultTrafficTreatment.builder()
-                .setOutput(host.location().port())
-                .build();
-
-        flowRule = DefaultFlowRule.builder()
-                .fromApp(appId)
-                .withSelector(selector)
-                .withTreatment(treatment)
-                .withPriority(MANAGEMENT_PRIORITY)
-                .forDevice(deviceId)
-                .forTable(TABLE_FIRST)
-                .makePermanent()
-                .build();
-
-        processFlowRule(true, flowRule);
-
-        selector = DefaultTrafficSelector.builder()
-                .matchInPort(PortNumber.LOCAL)
-                .matchEthType(Ethernet.TYPE_IPV4)
-                .matchIPDst(mService.subnet())
-                .build();
-
-        treatment = DefaultTrafficTreatment.builder()
-                .transition(TABLE_DST_IP)
-                .build();
-
-        flowRule = DefaultFlowRule.builder()
-                .fromApp(appId)
-                .withSelector(selector)
-                .withTreatment(treatment)
-                .withPriority(MANAGEMENT_PRIORITY)
-                .forDevice(deviceId)
-                .forTable(TABLE_FIRST)
-                .makePermanent()
-                .build();
-
-        processFlowRule(true, flowRule);
-
-        selector = DefaultTrafficSelector.builder()
-                .matchEthType(Ethernet.TYPE_IPV4)
-                .matchIPDst(mService.serviceIp().toIpPrefix())
-                .build();
-
-        treatment = DefaultTrafficTreatment.builder()
-                .setOutput(PortNumber.LOCAL)
-                .build();
-
-        flowRule = DefaultFlowRule.builder()
-                .fromApp(appId)
-                .withSelector(selector)
-                .withTreatment(treatment)
-                .withPriority(MANAGEMENT_PRIORITY)
-                .forDevice(deviceId)
-                .forTable(TABLE_ACCESS_TYPE)
-                .makePermanent()
-                .build();
-
-        processFlowRule(true, flowRule);
-    }
-
-    /**
-     * Populates rules for vSG VM.
-     *
-     * @param vSgHost vSG host
-     * @param vSgIps set of ip addresses of vSGs running inside the vSG VM
-     */
-    public void populateSubscriberGatewayRules(Host vSgHost, Set<IpAddress> vSgIps) {
-        VlanId serviceVlan = getServiceVlan(vSgHost);
-        PortNumber dpPort = getDpPort(vSgHost);
-
-        if (serviceVlan == null || dpPort == null) {
-            log.warn("Failed to populate rules for vSG VM {}", vSgHost.id());
-            return;
-        }
-
-        // for traffics with s-tag, strip the tag and take through the vSG VM
-        TrafficSelector selector = DefaultTrafficSelector.builder()
-                .matchInPort(dpPort)
-                .matchVlanId(serviceVlan)
-                .build();
-
-        TrafficTreatment treatment = DefaultTrafficTreatment.builder()
-                .setOutput(vSgHost.location().port())
-                .build();
-
-        FlowRule flowRule = DefaultFlowRule.builder()
-                .fromApp(appId)
-                .withSelector(selector)
-                .withTreatment(treatment)
-                .withPriority(DEFAULT_PRIORITY)
-                .forDevice(vSgHost.location().deviceId())
-                .forTable(TABLE_Q_IN_Q)
-                .makePermanent()
-                .build();
-
-        processFlowRule(true, 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(vSgHost.location().port())
-                .matchVlanId(serviceVlan)
-                .build();
-
-        treatment = DefaultTrafficTreatment.builder()
-                .setOutput(dpPort)
-                .build();
-
-        flowRule = DefaultFlowRule.builder()
-                .fromApp(appId)
-                .withSelector(selector)
-                .withTreatment(treatment)
-                .withPriority(DEFAULT_PRIORITY)
-                .forDevice(vSgHost.location().deviceId())
-                .forTable(TABLE_Q_IN_Q)
-                .makePermanent()
-                .build();
-
-        processFlowRule(true, flowRule);
-
-        // for traffic coming from WAN, tag 500 and take through the vSG VM
-        // based on destination ip
-        vSgIps.stream().forEach(ip -> {
-            TrafficSelector downstream = DefaultTrafficSelector.builder()
-                    .matchEthType(Ethernet.TYPE_IPV4)
-                    .matchIPDst(ip.toIpPrefix())
-                    .build();
-
-            TrafficTreatment downstreamTreatment = DefaultTrafficTreatment.builder()
-                    .pushVlan()
-                    .setVlanId(VLAN_WAN)
-                    .setEthDst(vSgHost.mac())
-                    .setOutput(vSgHost.location().port())
-                    .build();
-
-            FlowRule downstreamFlowRule = DefaultFlowRule.builder()
-                    .fromApp(appId)
-                    .withSelector(downstream)
-                    .withTreatment(downstreamTreatment)
-                    .withPriority(DEFAULT_PRIORITY)
-                    .forDevice(vSgHost.location().deviceId())
-                    .forTable(TABLE_DST_IP)
-                    .makePermanent()
-                    .build();
-
-            processFlowRule(true, downstreamFlowRule);
-        });
-
-        // remove downstream flow rules for the vSG not shown in vSgIps
-        for (FlowRule rule : flowRuleService.getFlowRulesById(appId)) {
-            if (!rule.deviceId().equals(vSgHost.location().deviceId())) {
-                continue;
-            }
-            PortNumber output = getOutputFromTreatment(rule);
-            if (output == null || !output.equals(vSgHost.location().port()) ||
-                    !isVlanPushFromTreatment(rule)) {
-                continue;
-            }
-
-            IpPrefix dstIp = getDstIpFromSelector(rule);
-            if (dstIp != null && !vSgIps.contains(dstIp.address())) {
-                processFlowRule(false, rule);
-            }
-        }
-    }
-
-    /**
-     * Populates default rules on the first table.
-     * It includes the rules for shuttling vxlan-encapped packets between ovs and
-     * linux stack,and external network connectivity.
-     *
-     * @param deviceId device id
-     * @param dpPort data plane interface port number
-     * @param dpIp data plane ip address
-     */
-    private void processFirstTable(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(HIGH_PRIORITY)
-                .forDevice(deviceId)
-                .forTable(TABLE_FIRST)
-                .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(HIGH_PRIORITY)
-                .forDevice(deviceId)
-                .forTable(TABLE_FIRST)
-                .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(HIGH_PRIORITY)
-                .forDevice(deviceId)
-                .forTable(TABLE_FIRST)
-                .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(HIGH_PRIORITY)
-                .forDevice(deviceId)
-                .forTable(TABLE_FIRST)
-                .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(LOWEST_PRIORITY)
-                .forDevice(deviceId)
-                .forTable(TABLE_FIRST)
-                .makePermanent()
-                .build();
-
-        processFlowRule(true, flowRule);
-
-        // take all vlan tagged packet to the Q_IN_Q table
-        selector = DefaultTrafficSelector.builder()
-                .matchVlanId(VlanId.ANY)
-                .build();
-
-        treatment = DefaultTrafficTreatment.builder()
-                .transition(TABLE_Q_IN_Q)
-                .build();
-
-        flowRule = DefaultFlowRule.builder()
-                .fromApp(appId)
-                .withSelector(selector)
-                .withTreatment(treatment)
-                .withPriority(VSG_PRIORITY)
-                .forDevice(deviceId)
-                .forTable(TABLE_FIRST)
-                .makePermanent()
-                .build();
-
-        processFlowRule(true, flowRule);
-    }
-
-    /**
-     * Forward table miss packets in ACCESS_TYPE table to data plane port.
-     *
-     * @param deviceId device id
-     * @param dpPort data plane interface port number
-     */
-    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(LOWEST_PRIORITY)
-                .forDevice(deviceId)
-                .forTable(TABLE_ACCESS_TYPE)
-                .makePermanent()
-                .build();
-
-        processFlowRule(true, flowRule);
-    }
-
-    /**
-     * Populates default rules for IN_PORT table.
-     * All packets from tunnel port are forwarded to TUNNEL_ID table and all packets
-     * from data plane interface port to ACCESS_TYPE table.
-     *
-     * @param deviceId device id to install the rules
-     * @param tunnelPort tunnel port number
-     * @param dpPort data plane interface port number
-     */
-    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(DEFAULT_PRIORITY)
-                .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(DEFAULT_PRIORITY)
-                .forDevice(deviceId)
-                .forTable(TABLE_IN_PORT)
-                .makePermanent()
-                .build();
-
-        processFlowRule(true, flowRule);
-    }
-
-    /**
-     * Populates default rules for Q_IN_Q table.
-     *
-     * @param deviceId device id
-     * @param dpPort data plane interface port number
-     */
-    private void processQInQTable(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(DEFAULT_PRIORITY)
-                .forDevice(deviceId)
-                .forTable(TABLE_Q_IN_Q)
-                .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(HIGH_PRIORITY)
-                .forDevice(deviceId)
-                .forTable(TABLE_Q_IN_Q)
-                .makePermanent()
-                .build();
-
-        processFlowRule(true, flowRule);
-    }
-
-    /**
-     * Populates rules for local in port in IN_PORT table.
-     * Flows from a given in port, whose source IP is service IP transition
-     * to DST_TYPE table. Other flows transition to IN_SERVICE table.
-     *
-     * @param deviceId device id to install the rules
-     * @param inPort in port
-     * @param srcIp source ip
-     * @param install true to install or false to remove
-     */
-    private void populateLocalInPortRule(DeviceId deviceId, PortNumber inPort, IpAddress srcIp,
-                                         boolean install) {
-        TrafficSelector selector = DefaultTrafficSelector.builder()
-                .matchInPort(inPort)
-                .matchEthType(Ethernet.TYPE_IPV4)
-                .matchIPSrc(srcIp.toIpPrefix())
-                .build();
-
-        TrafficTreatment treatment = DefaultTrafficTreatment.builder()
-                .transition(TABLE_ACCESS_TYPE)
-                .build();
-
-
-        FlowRule flowRule = DefaultFlowRule.builder()
-                .fromApp(appId)
-                .withSelector(selector)
-                .withTreatment(treatment)
-                .withPriority(DEFAULT_PRIORITY)
-                .forDevice(deviceId)
-                .forTable(TABLE_IN_PORT)
-                .makePermanent()
-                .build();
-
-        processFlowRule(install, flowRule);
-
-        selector = DefaultTrafficSelector.builder()
-                .matchInPort(inPort)
-                .build();
-
-        treatment = DefaultTrafficTreatment.builder()
-                .transition(TABLE_IN_SERVICE)
-                .build();
-
-        flowRule = DefaultFlowRule.builder()
-                .fromApp(appId)
-                .withSelector(selector)
-                .withTreatment(treatment)
-                .withPriority(LOW_PRIORITY)
-                .forDevice(deviceId)
-                .forTable(TABLE_IN_PORT)
-                .makePermanent()
-                .build();
-
-        processFlowRule(install, flowRule);
-    }
-
-    /**
-     * Populates direct VM access rules for ACCESS_TYPE table.
-     * These rules are installed to all devices.
-     *
-     * @param srcRange source ip range
-     * @param dstRange destination ip range
-     * @param install true to install or false to remove
-     */
-    private void populateDirectAccessRule(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();
-
-
-        getVirtualSwitches().stream().forEach(deviceId -> {
-            FlowRule flowRuleDirect = DefaultFlowRule.builder()
-                    .fromApp(appId)
-                    .withSelector(selector)
-                    .withTreatment(treatment)
-                    .withPriority(DEFAULT_PRIORITY)
-                    .forDevice(deviceId)
-                    .forTable(TABLE_ACCESS_TYPE)
-                    .makePermanent()
-                    .build();
-
-            processFlowRule(install, flowRuleDirect);
-        });
-    }
-
-    /**
-     * Populates drop rules that does not match any direct access rules but has
-     * destination to a different service network in ACCESS_TYPE table.
-     *
-     * @param dstRange destination ip range
-     * @param install true to install or false to remove
-     */
-    private void populateServiceIsolationRule(Ip4Prefix dstRange, boolean install) {
-        TrafficSelector selector = DefaultTrafficSelector.builder()
-                .matchEthType(Ethernet.TYPE_IPV4)
-                .matchIPDst(dstRange)
-                .build();
-
-        TrafficTreatment treatment = DefaultTrafficTreatment.builder()
-                .drop()
-                .build();
-
-        getVirtualSwitches().stream().forEach(deviceId -> {
-            FlowRule flowRuleDirect = DefaultFlowRule.builder()
-                    .fromApp(appId)
-                    .withSelector(selector)
-                    .withTreatment(treatment)
-                    .withPriority(LOW_PRIORITY)
-                    .forDevice(deviceId)
-                    .forTable(TABLE_ACCESS_TYPE)
-                    .makePermanent()
-                    .build();
-
-            processFlowRule(install, flowRuleDirect);
-        });
-    }
-
-    /**
-     * Populates indirect service access rules for ACCESS_TYPE table.
-     * These rules are installed to all devices.
-     *
-     * @param srcRange source range
-     * @param serviceIp service ip
-     * @param outGroups list of output group
-     * @param install true to install or false to remove
-     */
-    private void populateIndirectAccessRule(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(HIGH_PRIORITY)
-                    .forDevice(outGroup.getKey())
-                    .forTable(TABLE_ACCESS_TYPE)
-                    .makePermanent()
-                    .build();
-
-            processFlowRule(install, flowRule);
-        }
-    }
-
-    /**
-     * Populates flow rules for IN_SERVICE table.
-     *
-     * @param inPorts list of inports related to the service for each device
-     * @param outGroups set of output groups
-     * @param install true to install or false to remove
-     */
-    private void populateInServiceRule(Map<DeviceId, Set<PortNumber>> inPorts,
-                                       Map<DeviceId, GroupId> outGroups, boolean install) {
-        checkNotNull(inPorts);
-        checkNotNull(outGroups);
-
-        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(DEFAULT_PRIORITY)
-                        .forDevice(deviceId)
-                        .forTable(TABLE_IN_SERVICE)
-                        .makePermanent()
-                        .build();
-
-                processFlowRule(install, flowRule);
-            });
-        }
-    }
-
-    /**
-     * Populates flow rules for DST_IP table.
-     *
-     * @param deviceId device id
-     * @param inPort in port
-     * @param dstMac mac address
-     * @param dstIp destination ip
-     * @param tunnelId tunnel id
-     * @param tunnelIp tunnel remote ip
-     * @param install true to install or false to remove
-     */
-    private void populateDstIpRule(DeviceId deviceId, PortNumber inPort, MacAddress dstMac,
-                                   IpAddress dstIp, long tunnelId, IpAddress tunnelIp,
-                                   boolean install) {
-        TrafficSelector selector = DefaultTrafficSelector.builder()
-                .matchEthType(Ethernet.TYPE_IPV4)
-                .matchIPDst(dstIp.toIpPrefix())
-                .build();
-
-        TrafficTreatment treatment = DefaultTrafficTreatment.builder()
-                .setEthDst(dstMac)
-                .setOutput(inPort)
-                .build();
-
-        FlowRule flowRule = DefaultFlowRule.builder()
-                .fromApp(appId)
-                .withSelector(selector)
-                .withTreatment(treatment)
-                .withPriority(DEFAULT_PRIORITY)
-                .forDevice(deviceId)
-                .forTable(TABLE_DST_IP)
-                .makePermanent()
-                .build();
-
-        processFlowRule(install, flowRule);
-
-        for (DeviceId vSwitchId : getVirtualSwitches()) {
-            if (vSwitchId.equals(deviceId)) {
-                continue;
-            }
-
-            ExtensionTreatment tunnelDst = getTunnelDst(vSwitchId, tunnelIp.getIp4Address());
-            if (tunnelDst == null) {
-                continue;
-            }
-
-            treatment = DefaultTrafficTreatment.builder()
-                    .setEthDst(dstMac)
-                    .setTunnelId(tunnelId)
-                    .extension(tunnelDst, vSwitchId)
-                    .setOutput(getTunnelPort(vSwitchId))
-                    .build();
-
-            flowRule = DefaultFlowRule.builder()
-                    .fromApp(appId)
-                    .withSelector(selector)
-                    .withTreatment(treatment)
-                    .withPriority(DEFAULT_PRIORITY)
-                    .forDevice(vSwitchId)
-                    .forTable(TABLE_DST_IP)
-                    .makePermanent()
-                    .build();
-
-            processFlowRule(install, flowRule);
-        }
-    }
-
-    /**
-     * Populates flow rules for TUNNEL_ID table.
-     *
-     * @param deviceId device id
-     * @param inPort in port
-     * @param mac mac address
-     * @param tunnelId tunnel id
-     * @param install true to install or false to remove
-     */
-    private void populateTunnelInRule(DeviceId deviceId, PortNumber inPort, MacAddress mac,
-                                      long tunnelId, boolean install) {
-        TrafficSelector selector = DefaultTrafficSelector.builder()
-                .matchTunnelId(tunnelId)
-                .matchEthDst(mac)
-                .build();
-
-        TrafficTreatment treatment = DefaultTrafficTreatment.builder()
-                .setOutput(inPort)
-                .build();
-
-        FlowRule flowRule = DefaultFlowRule.builder()
-                .fromApp(appId)
-                .withSelector(selector)
-                .withTreatment(treatment)
-                .withPriority(DEFAULT_PRIORITY)
-                .forDevice(deviceId)
-                .forTable(TABLE_TUNNEL_IN)
-                .makePermanent()
-                .build();
-
-        processFlowRule(install, flowRule);
-    }
-
-    /**
-     * Installs or uninstall a given rule.
-     *
-     * @param install true to install, false to uninstall
-     * @param rule rule
-     */
-    private 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()));
-            }
-        }));
-    }
-
-    /**
-     * Returns tunnel port of the device.
-     *
-     * @param deviceId device id
-     * @return tunnel port number, or null if no tunnel port exists on a given device
-     */
-    private PortNumber getTunnelPort(DeviceId deviceId) {
-        Port port = deviceService.getPorts(deviceId).stream()
-                .filter(p -> p.annotations().value(PORT_NAME).contains(tunnelType))
-                .findFirst().orElse(null);
-
-        return port == null ? null : port.number();
-    }
-
-    /**
-     * Returns data plane interface port name of a given device.
-     *
-     * @param deviceId device id
-     * @param dpIntf data plane interface port name
-     * @return data plane interface port number, or null if no such port exists
-     */
-    private PortNumber getDpPort(DeviceId deviceId, String dpIntf) {
-        Port port = deviceService.getPorts(deviceId).stream()
-                .filter(p -> p.annotations().value(PORT_NAME).contains(dpIntf) &&
-                        p.isEnabled())
-                .findFirst().orElse(null);
-
-        return port == null ? null : port.number();
-    }
-
-    /** Returns data plane interface port number of a given host.
-     *
-     * @param host host
-     * @return port number, or null
-     */
-    private PortNumber getDpPort(Host host) {
-        String portName = host.annotations().value(DATA_PLANE_INTF);
-        return portName == null ? null : getDpPort(host.location().deviceId(), portName);
-    }
-
-    /**
-     * Returns service vlan from a given host.
-     *
-     * @param host host
-     * @return vlan id, or null
-     */
-    private VlanId getServiceVlan(Host host) {
-        String serviceVlan = host.annotations().value(S_TAG);
-        return serviceVlan == null ? null : VlanId.vlanId(Short.parseShort(serviceVlan));
-    }
-
-    /**
-     * Returns IP address for tunneling for a given host.
-     *
-     * @param host host
-     * @return ip address, or null
-     */
-    private IpAddress getTunnelIp(Host host) {
-        String ip = host.annotations().value(DATA_PLANE_IP);
-        return ip == null ? null : IpAddress.valueOf(ip);
-    }
-
-
-    /**
-     * Returns the destination IP from a given flow rule if the rule contains
-     * the match of it.
-     *
-     * @param flowRule flow rule
-     * @return ip prefix, or null if the rule doesn't have ip match
-     */
-    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;
-        }
-    }
-
-    /**
-     * Returns the output port number from a given flow rule.
-     *
-     * @param flowRule flow rule
-     * @return port number, or null if the rule does not have output instruction
-     */
-    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();
-    }
-
-    /**
-     * Returns if a given flow rule has vlan push instruction or not.
-     *
-     * @param flowRule flow rule
-     * @return true if it includes vlan push, or false
-     */
-    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;
-    }
-
-    /**
-     * Creates a new group for a given service.
-     *
-     * @param deviceId device id to create a group
-     * @param service cord service
-     * @return group id, or null if it fails to create
-     */
-    private GroupId createServiceGroup(DeviceId deviceId, VtnService service) {
-        checkNotNull(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;
-    }
-
-    /**
-     * Returns group buckets for a given device.
-     *
-     * @param deviceId device id
-     * @param tunnelId tunnel id
-     * @param hosts list of host
-     * @return group buckets
-     */
-    private GroupBuckets getServiceGroupBuckets(DeviceId deviceId, long tunnelId,
-                                                Set<Host> hosts) {
-        List<GroupBucket> buckets = Lists.newArrayList();
-
-        hosts.stream().forEach(host -> {
-            Ip4Address tunnelIp = getTunnelIp(host).getIp4Address();
-            DeviceId hostDevice = host.location().deviceId();
-
-            TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment
-                    .builder()
-                    .setEthDst(host.mac());
-            if (deviceId.equals(hostDevice)) {
-                tBuilder.setOutput(host.location().port());
-            } else {
-                ExtensionTreatment tunnelDst = getTunnelDst(deviceId, tunnelIp);
-                tBuilder.extension(tunnelDst, deviceId)
-                        .setTunnelId(tunnelId)
-                        .setOutput(getTunnelPort(hostDevice));
-            }
-            buckets.add(DefaultGroupBucket.createSelectGroupBucket(tBuilder.build()));
-        });
-
-        return new GroupBuckets(buckets);
-    }
-
-    /**
-     * Returns globally unique group ID.
-     *
-     * @param serviceId service id
-     * @param deviceId device id
-     * @return group id
-     */
-    private GroupId getGroupId(VtnServiceId serviceId, DeviceId deviceId) {
-        return new DefaultGroupId(Objects.hash(serviceId, deviceId));
-    }
-
-    /**
-     * Returns group key of a service.
-     *
-     * @param serviceId service id
-     * @return group key
-     */
-    private GroupKey getGroupKey(VtnServiceId serviceId) {
-        return new DefaultGroupKey(serviceId.id().getBytes());
-    }
-
-    /**
-     * Returns extension instruction to set tunnel destination.
-     *
-     * @param deviceId device id
-     * @param remoteIp tunnel destination address
-     * @return extension treatment or null if it fails to get instruction
-     */
-    private ExtensionTreatment getTunnelDst(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;
-        }
-    }
-
-    /**
-     * Returns integration bridges configured in the system.
-     *
-     * @return set of device ids
-     */
-    private Set<DeviceId> getVirtualSwitches() {
-        CordVtnConfig config = configRegistry.getConfig(appId, CordVtnConfig.class);
-        if (config == null) {
-            log.debug("No configuration found for {}", appId.name());
-            return Sets.newHashSet();
-        }
-
-        return config.cordVtnNodes().stream()
-                .map(CordVtnNode::intBrId).collect(Collectors.toSet());
-    }
-
-    /**
-     * Returns instances with a given network service.
-     *
-     * @param serviceId service id
-     * @return set of hosts
-     */
-    private Set<Host> getInstances(VtnServiceId serviceId) {
-        return StreamSupport.stream(hostService.getHosts().spliterator(), false)
-                .filter(host -> Objects.equals(
-                        serviceId.id(),
-                        host.annotations().value(SERVICE_ID)))
-                .collect(Collectors.toSet());
-    }
-}
-
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/NeutronMl2PortsWebResource.java b/src/main/java/org/onosproject/cordvtn/rest/NeutronMl2PortsWebResource.java
index 17d48a5..bf8d79d 100644
--- a/src/main/java/org/onosproject/cordvtn/rest/NeutronMl2PortsWebResource.java
+++ b/src/main/java/org/onosproject/cordvtn/rest/NeutronMl2PortsWebResource.java
@@ -18,9 +18,10 @@
 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.api.CordVtnService;
+import org.onosproject.cordvtn.impl.service.VsgInstanceHandler;
 import org.onosproject.net.HostId;
 import org.onosproject.rest.AbstractWebResource;
 import org.slf4j.Logger;
@@ -57,7 +58,7 @@
     private static final String STAG_PREFIX = "stag-";
     private static final int STAG_BEGIN_INDEX = 5;
 
-    private final CordVtnService service = get(CordVtnService.class);
+    private final VsgInstanceHandler service = DefaultServiceDirectory.getService(VsgInstanceHandler.class);
 
     @POST
     @Consumes(MediaType.APPLICATION_JSON)
@@ -74,6 +75,7 @@
     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);
@@ -88,17 +90,16 @@
 
             // this is allowed address pairs updates
             MacAddress mac = MacAddress.valueOf(jsonNode.path(MAC_ADDRESS).asText());
-            Map<IpAddress, MacAddress> vSgs = Maps.newHashMap();
+            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());
-                vSgs.put(pairIp, pairMac);
+                vsgInstances.put(pairIp, pairMac);
             });
 
-            service.updateVirtualSubscriberGateways(
-                    HostId.hostId(mac),
-                    name.substring(STAG_BEGIN_INDEX),
-                    vSgs);
+            service.updateVsgInstances(HostId.hostId(mac),
+                                       name.substring(STAG_BEGIN_INDEX),
+                                       vsgInstances);
         } catch (Exception e) {
             return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
         }
