diff --git a/apps/cordvtn/src/main/java/org/onosproject/cordvtn/CordService.java b/apps/cordvtn/src/main/java/org/onosproject/cordvtn/CordService.java
index 2e4a59e..0d09bb3 100644
--- a/apps/cordvtn/src/main/java/org/onosproject/cordvtn/CordService.java
+++ b/apps/cordvtn/src/main/java/org/onosproject/cordvtn/CordService.java
@@ -18,8 +18,18 @@
 import com.google.common.base.MoreObjects;
 import org.onlab.packet.IpAddress;
 import org.onlab.packet.IpPrefix;
+import org.onosproject.net.Host;
+import org.onosproject.openstackswitching.OpenstackNetwork;
+import org.onosproject.openstackswitching.OpenstackSubnet;
 
+import java.util.Map;
 import java.util.Objects;
+import java.util.Set;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.onosproject.cordvtn.CordService.ServiceType.*;
+import static org.onosproject.cordvtn.CordService.ServiceType.PRIVATE;
+import static org.onosproject.cordvtn.CordService.ServiceType.PUBLIC_INDIRECT;
 
 public final class CordService {
 
@@ -36,23 +46,25 @@
     private final ServiceType serviceType;
     private final IpPrefix serviceIpRange;
     private final IpAddress serviceIp;
+    private final Map<Host, IpAddress> hosts;
+    private final Set<CordServiceId> tenantServices;
 
     /**
      * Default constructor.
      *
-     * @param id service id, which is identical to OpenStack network id
-     * @param segmentationId segmentation id, which is identical to VNI
-     * @param serviceType service type
-     * @param serviceIpRange service ip range
-     * @param serviceIp service ip
+     * @param vNet OpenStack network
+     * @param hosts host and tunnel ip map
+     * @param tenantServices list of tenant service ids
      */
-    public CordService(CordServiceId id, long segmentationId, ServiceType serviceType,
-                   IpPrefix serviceIpRange, IpAddress serviceIp) {
-        this.id = id;
-        this.segmentationId = segmentationId;
-        this.serviceType = serviceType;
-        this.serviceIpRange = serviceIpRange;
-        this.serviceIp = serviceIp;
+    public CordService(OpenstackNetwork vNet, OpenstackSubnet subnet,
+                       Map<Host, IpAddress> hosts, Set<CordServiceId> tenantServices) {
+        this.id = CordServiceId.of(vNet.id());
+        this.segmentationId = Long.parseLong(vNet.segmentId());
+        this.serviceType = getServiceType(vNet.name());
+        this.serviceIpRange = IpPrefix.valueOf(subnet.cidr());
+        this.serviceIp = IpAddress.valueOf(subnet.gatewayIp());
+        this.hosts = hosts;
+        this.tenantServices = tenantServices;
     }
 
     /**
@@ -100,6 +112,24 @@
         return serviceIp;
     }
 
+    /**
+     * Returns hosts associated with this service.
+     *
+     * @return list of hosts
+     */
+    public Map<Host, IpAddress> hosts() {
+        return hosts;
+    }
+
+    /**
+     * Returns tenant service IDs.
+     *
+     * @return list of tenant service id
+     */
+    public Set<CordServiceId> tenantServices() {
+        return tenantServices;
+    }
+
     @Override
     public int hashCode() {
         return Objects.hash(id);
@@ -125,6 +155,33 @@
                 .add("serviceType", serviceType)
                 .add("serviceIpRange", serviceIpRange)
                 .add("serviceIp", serviceIp)
+                .add("tenantServices", tenantServices)
                 .toString();
     }
+
+    /**
+     * Returns network type from network name.
+     * It assumes that network name contains network type.
+     *
+     * @param netName network name
+     * @return network type, or null if it doesn't match any type
+     */
+    private ServiceType getServiceType(String netName) {
+        checkNotNull(netName);
+
+        String name = netName.toUpperCase();
+        if (name.contains(PRIVATE_DIRECT.toString())) {
+            return PRIVATE_DIRECT;
+        } else if (name.contains(PRIVATE_INDIRECT.toString())) {
+            return PRIVATE_INDIRECT;
+        } else if (name.contains(PUBLIC_DIRECT.toString())) {
+            return PUBLIC_DIRECT;
+        } else if (name.contains(PUBLIC_INDIRECT.toString())) {
+            return PUBLIC_INDIRECT;
+        } else if (name.contains(PRIVATE.toString())) {
+            return PRIVATE;
+        } else {
+            return null;
+        }
+    }
 }
diff --git a/apps/cordvtn/src/main/java/org/onosproject/cordvtn/CordVtn.java b/apps/cordvtn/src/main/java/org/onosproject/cordvtn/CordVtn.java
index d1ff7f0..d119a5a 100644
--- a/apps/cordvtn/src/main/java/org/onosproject/cordvtn/CordVtn.java
+++ b/apps/cordvtn/src/main/java/org/onosproject/cordvtn/CordVtn.java
@@ -15,7 +15,6 @@
  */
 package org.onosproject.cordvtn;
 
-import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
 import com.google.common.collect.Sets;
 import org.apache.felix.scr.annotations.Activate;
@@ -24,21 +23,23 @@
 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.Ip4Address;
 import org.onlab.util.ItemNotFoundException;
 import org.onlab.packet.IpAddress;
 import org.onlab.util.KryoNamespace;
 import org.onosproject.cluster.ClusterService;
 import org.onosproject.core.ApplicationId;
 import org.onosproject.core.CoreService;
+import org.onosproject.mastership.MastershipService;
 import org.onosproject.net.DefaultAnnotations;
 import org.onosproject.net.Device;
 import org.onosproject.net.DeviceId;
 import org.onosproject.net.Host;
 import org.onosproject.net.HostId;
 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.ConnectPoint;
 import org.onosproject.net.behaviour.ControllerInfo;
 import org.onosproject.net.behaviour.DefaultTunnelDescription;
 import org.onosproject.net.behaviour.TunnelConfig;
@@ -50,12 +51,14 @@
 import org.onosproject.net.device.DeviceService;
 import org.onosproject.net.driver.DriverHandler;
 import org.onosproject.net.driver.DriverService;
-import org.onosproject.net.flowobjective.FlowObjectiveService;
+import org.onosproject.net.flow.FlowRuleService;
+import org.onosproject.net.group.GroupService;
 import org.onosproject.net.host.HostEvent;
 import org.onosproject.net.host.HostListener;
 import org.onosproject.net.host.HostService;
 import org.onosproject.openstackswitching.OpenstackNetwork;
 import org.onosproject.openstackswitching.OpenstackPort;
+import org.onosproject.openstackswitching.OpenstackSubnet;
 import org.onosproject.openstackswitching.OpenstackSwitchingService;
 import org.onosproject.ovsdb.controller.OvsdbClientService;
 import org.onosproject.ovsdb.controller.OvsdbController;
@@ -71,6 +74,7 @@
 import java.util.List;
 import java.util.Map;
 import java.util.NoSuchElementException;
+import java.util.Objects;
 import java.util.Set;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
@@ -99,6 +103,7 @@
             .register(NodeState.class);
     private static final String DEFAULT_BRIDGE = "br-int";
     private static final String VPORT_PREFIX = "tap";
+    private static final String GWPORT_PREFIX = "qr-";
     private static final String DEFAULT_TUNNEL = "vxlan";
     private static final Map<String, String> DEFAULT_TUNNEL_OPTIONS = new HashMap<String, String>() {
         {
@@ -128,7 +133,7 @@
     protected DeviceAdminService adminService;
 
     @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
-    protected FlowObjectiveService flowObjectiveService;
+    protected FlowRuleService flowRuleService;
 
     @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
     protected OvsdbController controller;
@@ -137,6 +142,12 @@
     protected ClusterService clusterService;
 
     @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected MastershipService mastershipService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected GroupService groupService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
     protected OpenstackSwitchingService openstackService;
 
     private final ExecutorService eventExecutor = Executors
@@ -149,8 +160,9 @@
     private final BridgeHandler bridgeHandler = new BridgeHandler();
     private final VmHandler vmHandler = new VmHandler();
 
+    private ApplicationId appId;
     private ConsistentMap<CordVtnNode, NodeState> nodeStore;
-    private Map<HostId, String> hostNetworkMap = Maps.newHashMap();
+    private Map<HostId, OpenstackNetwork> hostNetMap = Maps.newHashMap();
     private CordVtnRuleInstaller ruleInstaller;
 
     private enum NodeState {
@@ -198,15 +210,20 @@
 
     @Activate
     protected void activate() {
-        ApplicationId appId = coreService.registerApplication("org.onosproject.cordvtn");
+        appId = coreService.registerApplication("org.onosproject.cordvtn");
         nodeStore = storageService.<CordVtnNode, NodeState>consistentMapBuilder()
                 .withSerializer(Serializer.using(NODE_SERIALIZER.build()))
                 .withName("cordvtn-nodestore")
                 .withApplicationId(appId)
                 .build();
 
-        ruleInstaller = new CordVtnRuleInstaller(appId, flowObjectiveService,
-                                                 driverService, DEFAULT_TUNNEL);
+        ruleInstaller = new CordVtnRuleInstaller(appId, flowRuleService,
+                                                 deviceService,
+                                                 driverService,
+                                                 groupService,
+                                                 mastershipService,
+                                                 DEFAULT_TUNNEL);
+
         deviceService.addListener(deviceListener);
         hostService.addListener(hostListener);
 
@@ -277,19 +294,29 @@
     }
 
     @Override
-    public void createServiceDependency(CordServiceId tenantCordServiceId,
-                                        CordServiceId providerCordServiceId) {
-        CordService tenantService = getCordService(tenantCordServiceId);
-        CordService providerService = getCordService(providerCordServiceId);
+    public void createServiceDependency(CordServiceId tServiceId, CordServiceId pServiceId) {
+        CordService tService = getCordService(tServiceId);
+        CordService pService = getCordService(pServiceId);
 
-        // TODO populate flow rules to create service dependency
+        if (tService == null || pService == null) {
+            log.error("Failed to create CordService for {}", tServiceId.id());
+            return;
+        }
+
+        ruleInstaller.populateServiceDependencyRules(tService, pService);
     }
 
     @Override
-    public void removeServiceDependency(CordServiceId tenantCordServiceId) {
-        CordService tenantService = getCordService(tenantCordServiceId);
+    public void removeServiceDependency(CordServiceId tServiceId, CordServiceId pServiceId) {
+        CordService tService = getCordService(tServiceId);
+        CordService pService = getCordService(pServiceId);
 
-        //TODO uninstall flow rules to remove service dependency
+        if (tService == null || pService == null) {
+            log.error("Failed to create CordService for {}", tServiceId.id());
+            return;
+        }
+
+        ruleInstaller.removeServiceDependencyRules(tService, pService);
     }
 
     /**
@@ -352,21 +379,13 @@
      * @param node cordvtn node
      */
     private void postInit(CordVtnNode node) {
+        log.info("Initializing {}", node.hostname());
         disconnect(node);
 
-        Set<OpenstackNetwork> vNets = Sets.newHashSet();
+        ruleInstaller.init(node.intBrId(), getTunnelPort(node.intBrId()));
         hostService.getConnectedHosts(node.intBrId())
                 .stream()
-                .forEach(host -> {
-                    OpenstackNetwork vNet = getOpenstackNetworkByHost(host);
-                    if (vNet != null) {
-                        log.info("VM {} is detected", host.id());
-
-                        hostNetworkMap.put(host.id(), vNet.id());
-                        vNets.add(vNet);
-                    }
-                });
-        vNets.stream().forEach(this::installFlowRules);
+                .forEach(vmHandler::connected);
     }
 
     /**
@@ -558,14 +577,14 @@
      * Returns tunnel port of the device.
      *
      * @param bridgeId device id
-     * @return port, null if no tunnel port exists on a given device
+     * @return port number, null if no tunnel port exists on a given device
      */
-    private Port getTunnelPort(DeviceId bridgeId) {
+    private PortNumber getTunnelPort(DeviceId bridgeId) {
         try {
             return deviceService.getPorts(bridgeId).stream()
                     .filter(p -> p.annotations().value("portName").contains(DEFAULT_TUNNEL)
                             && p.isEnabled())
-                    .findFirst().get();
+                    .findFirst().get().number();
         } catch (NoSuchElementException e) {
             return null;
         }
@@ -577,67 +596,17 @@
      * @param bridgeId device id
      * @return ip address, null if no such device exists
      */
-    private IpAddress getRemoteIp(DeviceId bridgeId) {
+    private Ip4Address getRemoteIp(DeviceId bridgeId) {
         CordVtnNode node = getNodeByBridgeId(bridgeId);
         if (node != null) {
             // TODO get data plane IP for tunneling
-            return node.ovsdbIp();
+            return node.ovsdbIp().getIp4Address();
         } else {
             return null;
         }
     }
 
     /**
-     * Returns destination information of all ports associated with a given
-     * OpenStack network. Output of the destination information is set to local
-     * port or tunnel port according to a given device id.
-     *
-     * @param deviceId device id to install flow rules
-     * @param vNet OpenStack network
-     * @return list of flow information, empty list if no flow information exists
-     */
-    private List<DestinationInfo> getSameNetworkPortsInfo(DeviceId deviceId, OpenstackNetwork vNet) {
-        List<DestinationInfo> dstInfos = Lists.newArrayList();
-        long tunnelId = Long.valueOf(vNet.segmentId());
-
-        for (OpenstackPort vPort : openstackService.ports(vNet.id())) {
-            ConnectPoint cp = getConnectPoint(vPort);
-            if (cp == null) {
-                log.debug("Couldn't find connection point for OpenStack port {}", vPort.id());
-                continue;
-            }
-
-            DestinationInfo.Builder dBuilder = cp.deviceId().equals(deviceId) ?
-                    DestinationInfo.builder(deviceService.getPort(cp.deviceId(), cp.port())) :
-                    DestinationInfo.builder(getTunnelPort(deviceId))
-                            .setRemoteIp(getRemoteIp(cp.deviceId()));
-
-            dBuilder.setMac(vPort.macAddress())
-                    .setTunnelId(tunnelId);
-            dstInfos.add(dBuilder.build());
-        }
-        return dstInfos;
-    }
-
-    /**
-     * Returns local ports associated with a given OpenStack network.
-     *
-     * @param bridgeId device id
-     * @param vNet OpenStack network
-     * @return port list, empty list if no port exists
-     */
-    private List<Port> getLocalSameNetworkPorts(DeviceId bridgeId, OpenstackNetwork vNet) {
-        List<Port> ports = new ArrayList<>();
-        openstackService.ports(vNet.id()).stream().forEach(port -> {
-            ConnectPoint cp = getConnectPoint(port);
-            if (cp != null && cp.deviceId().equals(bridgeId)) {
-                ports.add(deviceService.getPort(cp.deviceId(), cp.port()));
-            }
-        });
-        return ports;
-    }
-
-    /**
      * Returns OpenStack port associated with a given host.
      *
      * @param host host
@@ -646,6 +615,10 @@
     private OpenstackPort getOpenstackPortByHost(Host host) {
         Port port = deviceService.getPort(host.location().deviceId(),
                                           host.location().port());
+        if (port == null) {
+            log.debug("Failed to get port for {}", host.id());
+            return null;
+        }
         return openstackService.port(port);
     }
 
@@ -665,6 +638,44 @@
     }
 
     /**
+     * Returns hosts associated with a given OpenStack network.
+     *
+     * @param vNet openstack network
+     * @return set of hosts
+     */
+    private Set<Host> getHostsWithOpenstackNetwork(OpenstackNetwork vNet) {
+        checkNotNull(vNet);
+
+        return openstackService.ports(vNet.id()).stream()
+                .filter(port -> port.deviceOwner().contains("compute"))
+                .map(port -> hostService.getHostsByMac(port.macAddress())
+                        .stream()
+                        .findFirst()
+                        .orElse(null))
+                .collect(Collectors.toSet());
+    }
+
+    /**
+     * Returns host IP assigned by OpenStack.
+     *
+     * @param host host
+     * @return IPv4 prefix, or null if it fails to get IP from OpenStack
+     */
+    private IpAddress getHostIpFromOpenstack(Host host) {
+        OpenstackPort vPort = getOpenstackPortByHost(host);
+
+        if (vPort == null || vPort.fixedIps().isEmpty()) {
+            log.error("Failed to get VM IP for {}", host.id());
+            return null;
+        }
+        // Assumes there's only one fixed IP is assigned to a port
+        return (Ip4Address) vPort.fixedIps().values()
+                .stream()
+                .findFirst()
+                .orElse(null);
+    }
+
+    /**
      * Returns port name with OpenStack port information.
      *
      * @param vPort OpenStack port
@@ -676,27 +687,20 @@
     }
 
     /**
-     * Returns connect point of a given OpenStack port.
-     * It assumes there's only one physical port associated with an OpenStack port.
+     * Returns if the host is gateway interface.
+     * This codes should be removed after adding proxy arp for the gateway.
      *
-     * @param vPort openstack port
-     * @return connect point, null if no such port exists
+     * @param host host
+     * @return true if the host is gateway
      */
-    private ConnectPoint getConnectPoint(OpenstackPort vPort) {
-        try {
-            Host host = hostService.getHostsByMac(vPort.macAddress())
-                    .stream()
-                    .findFirst()
-                    .get();
-            return new ConnectPoint(host.location().deviceId(), host.location().port());
-        } catch (NoSuchElementException e) {
-            log.debug("Not a valid host with {}", vPort.macAddress());
-            return null;
-        }
+    private boolean isGateway(Host host) {
+        Port port = deviceService.getPort(host.location().deviceId(),
+                                          host.location().port());
+        return port.annotations().value("portName").contains(GWPORT_PREFIX);
     }
 
     /**
-     * Returns OpenStack network associated with a given CORD service.
+     * Returns CordService by service ID.
      *
      * @param serviceId service id
      * @return cord service, or null if it fails to get network from OpenStack
@@ -708,73 +712,52 @@
             return null;
         }
 
-        // TODO create CordService with network/subnet information from Neutron
-        return null;
+        OpenstackSubnet subnet = vNet.subnets().stream()
+                .findFirst()
+                .orElse(null);
+        if (subnet == null) {
+            log.warn("Couldn't find OpenStack subnet for service {}", serviceId.id());
+            return null;
+        }
+
+        Set<CordServiceId> tServices = Sets.newHashSet();
+        // TODO get tenant services from XOS
+
+        Map<Host, IpAddress> hosts = getHostsWithOpenstackNetwork(vNet)
+                .stream()
+                .collect(Collectors.toMap(host -> host,
+                                          host -> getRemoteIp(host.location().deviceId())));
+
+        return new CordService(vNet, subnet, hosts, tServices);
     }
 
     /**
-     * Installs flow rules for a given OpenStack network.
+     * Returns CordService by OpenStack network.
      *
      * @param vNet OpenStack network
+     * @return cord service
      */
-    private void installFlowRules(OpenstackNetwork vNet) {
-        checkNotNull(vNet, "Tenant network should not be null");
+    private CordService getCordService(OpenstackNetwork vNet) {
+        checkNotNull(vNet);
 
-        for (Device device : deviceService.getAvailableDevices(SWITCH)) {
-            List<DestinationInfo> dstInfos = getSameNetworkPortsInfo(device.id(), vNet);
-
-            for (Port inPort : getLocalSameNetworkPorts(device.id(), vNet)) {
-                List<DestinationInfo> localInInfos = dstInfos.stream()
-                        .filter(info -> !info.output().equals(inPort))
-                        .collect(Collectors.toList());
-                ruleInstaller.installFlowRulesLocalIn(device.id(), inPort, localInInfos);
-            }
-
-            Port tunPort = getTunnelPort(device.id());
-            List<DestinationInfo> tunnelInInfos = dstInfos.stream()
-                    .filter(info -> !info.output().equals(tunPort))
-                    .collect(Collectors.toList());
-            ruleInstaller.installFlowRulesTunnelIn(device.id(), tunPort, tunnelInInfos);
+        CordServiceId serviceId = CordServiceId.of(vNet.id());
+        OpenstackSubnet subnet = vNet.subnets().stream()
+                .findFirst()
+                .orElse(null);
+        if (subnet == null) {
+            log.warn("Couldn't find OpenStack subnet for service {}", serviceId);
+            return null;
         }
-    }
 
-    /**
-     * Uninstalls flow rules associated with a given host for a given OpenStack network.
-     *
-     * @param vNet OpenStack network
-     * @param host removed host
-     */
-    private void uninstallFlowRules(OpenstackNetwork vNet, Host host) {
-        checkNotNull(vNet, "Tenant network should not be null");
+        Set<CordServiceId> tServices = Sets.newHashSet();
+        // TODO get tenant services from XOS
 
-        Port removedPort = deviceService.getPort(host.location().deviceId(),
-                                                 host.location().port());
+        Map<Host, IpAddress> hosts = getHostsWithOpenstackNetwork(vNet)
+                .stream()
+                .collect(Collectors.toMap(host -> host,
+                                          host -> getRemoteIp(host.location().deviceId())));
 
-        for (Device device : deviceService.getAvailableDevices(SWITCH)) {
-            List<DestinationInfo> dstInfos = getSameNetworkPortsInfo(device.id(), vNet);
-
-            for (Port inPort : getLocalSameNetworkPorts(device.id(), vNet)) {
-                List<DestinationInfo> localInInfos = Lists.newArrayList(
-                        DestinationInfo.builder(getTunnelPort(device.id()))
-                                .setTunnelId(Long.valueOf(vNet.segmentId()))
-                                .setMac(host.mac())
-                                .setRemoteIp(getRemoteIp(host.location().deviceId()))
-                                .build());
-                ruleInstaller.uninstallFlowRules(device.id(), inPort, localInInfos);
-            }
-
-            if (device.id().equals(host.location().deviceId())) {
-                Port tunPort = getTunnelPort(device.id());
-                List<DestinationInfo> tunnelInInfo = Lists.newArrayList(
-                        DestinationInfo.builder(removedPort)
-                                .setTunnelId(Long.valueOf(vNet.segmentId()))
-                                .setMac(host.mac())
-                                .build());
-
-                ruleInstaller.uninstallFlowRules(device.id(), tunPort, tunnelInInfo);
-                ruleInstaller.uninstallFlowRules(device.id(), removedPort, dstInfos);
-            }
-        }
+        return new CordService(vNet, subnet, hosts, tServices);
     }
 
     private class InternalDeviceListener implements DeviceListener {
@@ -873,6 +856,7 @@
          * @param port port
          */
         public void portAdded(Port port) {
+            // TODO add host by updating network config
             if (!port.annotations().value("portName").contains(DEFAULT_TUNNEL)) {
                 return;
             }
@@ -891,6 +875,7 @@
          * @param port port
          */
         public void portRemoved(Port port) {
+            // TODO remove host by updating network config
             if (!port.annotations().value("portName").contains(DEFAULT_TUNNEL)) {
                 return;
             }
@@ -907,8 +892,13 @@
 
         @Override
         public void connected(Host host) {
+            // TODO remove check gateway here after applying network config host provider
+            if (isGateway(host)) {
+                return;
+            }
+
             CordVtnNode node = getNodeByBridgeId(host.location().deviceId());
-            if (node == null || !getNodeState(node).equals(NodeState.COMPLETE)) {
+            if (node == null || !Objects.equals(getNodeState(node), NodeState.COMPLETE)) {
                 // do nothing for the host on unregistered or unprepared device
                 return;
             }
@@ -918,29 +908,43 @@
                 return;
             }
 
-            log.info("VM {} is detected", host.id());
+            // TODO host ip should be set in host information after applying network config host provider
+            IpAddress hostIp = getHostIpFromOpenstack(host);
+            if (hostIp == null) {
+                log.error("Failed to get host IP of {}", host.id());
+                return;
+            }
 
-            hostNetworkMap.put(host.id(), vNet.id());
-            installFlowRules(vNet);
+            log.info("VM {} is detected", host.id());
+            hostNetMap.put(host.id(), vNet);
+
+            ruleInstaller.populateBasicConnectionRules(
+                    host,
+                    hostIp,
+                    checkNotNull(getRemoteIp(host.location().deviceId())).getIp4Address(),
+                    vNet);
+
+            // TODO add new VM to related service group if exists
         }
 
         @Override
         public void disconnected(Host host) {
             CordVtnNode node = getNodeByBridgeId(host.location().deviceId());
-            if (node == null || !getNodeState(node).equals(NodeState.COMPLETE)) {
+            if (node == null || !Objects.equals(getNodeState(node), NodeState.COMPLETE)) {
                 // do nothing for the host on unregistered or unprepared device
                 return;
             }
 
-            OpenstackNetwork vNet = openstackService.network(hostNetworkMap.get(host.id()));
+            OpenstackNetwork vNet = hostNetMap.get(host.id());
             if (vNet == null) {
                 return;
             }
 
             log.info("VM {} is vanished", host.id());
+            ruleInstaller.removeBasicConnectionRules(host);
 
-            uninstallFlowRules(vNet, host);
-            hostNetworkMap.remove(host.id());
+            // TODO remove the VM from related service group if exists
+            hostNetMap.remove(host.id());
         }
     }
 }
diff --git a/apps/cordvtn/src/main/java/org/onosproject/cordvtn/CordVtnRuleInstaller.java b/apps/cordvtn/src/main/java/org/onosproject/cordvtn/CordVtnRuleInstaller.java
index 9e22997..4e044e1 100644
--- a/apps/cordvtn/src/main/java/org/onosproject/cordvtn/CordVtnRuleInstaller.java
+++ b/apps/cordvtn/src/main/java/org/onosproject/cordvtn/CordVtnRuleInstaller.java
@@ -15,195 +15,859 @@
  */
 package org.onosproject.cordvtn;
 
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import org.onlab.packet.Ethernet;
 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.util.ItemNotFoundException;
 import org.onosproject.core.ApplicationId;
+import org.onosproject.core.DefaultGroupId;
+import org.onosproject.core.GroupId;
+import org.onosproject.mastership.MastershipService;
+import org.onosproject.net.Device;
 import org.onosproject.net.DeviceId;
-import org.onosproject.net.Port;
+import org.onosproject.net.Host;
+import org.onosproject.net.PortNumber;
 import org.onosproject.net.behaviour.ExtensionTreatmentResolver;
+import org.onosproject.net.device.DeviceService;
 import org.onosproject.net.driver.DefaultDriverData;
 import org.onosproject.net.driver.DefaultDriverHandler;
 import org.onosproject.net.driver.Driver;
 import org.onosproject.net.driver.DriverHandler;
 import org.onosproject.net.driver.DriverService;
+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.EthCriterion;
+import org.onosproject.net.flow.criteria.IPCriterion;
+import org.onosproject.net.flow.criteria.PortCriterion;
 import org.onosproject.net.flow.instructions.ExtensionPropertyException;
 import org.onosproject.net.flow.instructions.ExtensionTreatment;
-import org.onosproject.net.flowobjective.DefaultForwardingObjective;
-import org.onosproject.net.flowobjective.FlowObjectiveService;
-import org.onosproject.net.flowobjective.ForwardingObjective;
+import org.onosproject.net.flow.instructions.Instruction;
+import org.onosproject.net.flow.instructions.Instructions;
+import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModEtherInstruction;
+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.openstackswitching.OpenstackNetwork;
+import org.onosproject.openstackswitching.OpenstackSubnet;
 import org.slf4j.Logger;
 
 import java.util.List;
+import java.util.Map;
+import java.util.NoSuchElementException;
+import java.util.Objects;
+import java.util.Set;
+import java.util.stream.Collectors;
 
-import static com.google.common.base.Preconditions.checkArgument;
 import static com.google.common.base.Preconditions.checkNotNull;
+import static org.onosproject.net.Device.Type.SWITCH;
+import static org.onosproject.net.flow.criteria.Criterion.Type.IN_PORT;
+import static org.onosproject.net.flow.criteria.Criterion.Type.IPV4_DST;
+import static org.onosproject.net.flow.criteria.Criterion.Type.IPV4_SRC;
 import static org.onosproject.net.flow.instructions.ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_SET_TUNNEL_DST;
+import static org.onosproject.net.flow.instructions.L2ModificationInstruction.L2SubType.ETH_DST;
 import static org.slf4j.LoggerFactory.getLogger;
 
 /**
- * Populates rules for virtual tenant network.
+ * Populates rules for CORD VTN service.
  */
-public final class CordVtnRuleInstaller {
+public class CordVtnRuleInstaller {
+
     protected final Logger log = getLogger(getClass());
 
+    private static final int TABLE_IN_PORT = 0;
+    private static final int TABLE_ACCESS_TYPE = 1;
+    private static final int TABLE_IN_SERVICE = 2;
+    private static final int TABLE_DST_IP = 3;
+    private static final int TABLE_TUNNEL_IN = 4;
+
     private static final int DEFAULT_PRIORITY = 5000;
+    private static final int LOWER_PRIORITY = 4000;
+    private static final int LOWEST_PRIORITY = 0;
 
     private final ApplicationId appId;
-    private final FlowObjectiveService flowObjectiveService;
+    private final FlowRuleService flowRuleService;
+    private final DeviceService deviceService;
     private final DriverService driverService;
+    private final GroupService groupService;
+    private final MastershipService mastershipService;
     private final String tunnelType;
 
     /**
-     * Creates a new rule installer.
+     * Creates a new rule populator.
      *
      * @param appId application id
-     * @param flowObjectiveService flow objective service
+     * @param flowRuleService flow rule service
+     * @param deviceService device service
      * @param driverService driver service
      * @param tunnelType tunnel type
      */
     public CordVtnRuleInstaller(ApplicationId appId,
-                                FlowObjectiveService flowObjectiveService,
+                                FlowRuleService flowRuleService,
+                                DeviceService deviceService,
                                 DriverService driverService,
+                                GroupService groupService,
+                                MastershipService mastershipService,
                                 String tunnelType) {
         this.appId = appId;
-        this.flowObjectiveService = flowObjectiveService;
+        this.flowRuleService = flowRuleService;
+        this.deviceService = deviceService;
         this.driverService = driverService;
+        this.groupService = groupService;
+        this.mastershipService = mastershipService;
         this.tunnelType = checkNotNull(tunnelType);
     }
 
     /**
-     * Installs flow rules for tunnel in traffic.
+     * Installs table miss rule to a give device.
      *
-     * @param deviceId device id to install flow rules
-     * @param inPort in port
-     * @param dstInfos list of destination info
+     * @param deviceId device id to install the rules
+     * @param tunnelPort tunnel port number of the device
      */
-    public void installFlowRulesTunnelIn(DeviceId deviceId, Port inPort, List<DestinationInfo> dstInfos) {
-        dstInfos.stream().forEach(dstInfo -> {
-            ForwardingObjective.Builder fBuilder = vtnRulesSameNode(inPort, dstInfo);
-            if (fBuilder != null) {
-                flowObjectiveService.forward(deviceId, fBuilder.add());
-            }
-        });
+    public void init(DeviceId deviceId, PortNumber tunnelPort) {
+        // default is drop packets which can be accomplished without
+        // a table miss entry for all table.
+        populateTunnelInPortRule(deviceId, tunnelPort);
+        processAccessTypeTable(deviceId);
     }
 
     /**
-     * Installs flow rules for local in traffic.
+     * Populates basic rules that connect a VM to the other VMs in the system.
      *
-     * @param deviceId device id to install flow rules
-     * @param inPort in port
-     * @param dstInfos list of destination info
+     * @param host host
+     * @param hostIp host ip
+     * @param tunnelIp tunnel ip
+     * @param vNet openstack network
      */
-    public void installFlowRulesLocalIn(DeviceId deviceId, Port inPort, List<DestinationInfo> dstInfos) {
-        dstInfos.stream().forEach(dstInfo -> {
-            ForwardingObjective.Builder fBuilder = isTunnelPort(dstInfo.output()) ?
-                    vtnRulesRemoteNode(deviceId, inPort, dstInfo) : vtnRulesSameNode(inPort, dstInfo);
+    public void populateBasicConnectionRules(Host host, IpAddress hostIp, IpAddress tunnelIp,
+                                             OpenstackNetwork vNet) {
+        // TODO we can get host ip from host.ip() after applying NetworkConfig host provider
+        checkNotNull(host);
+        checkNotNull(vNet);
 
-            if (fBuilder != null) {
-                flowObjectiveService.forward(deviceId, fBuilder.add());
-            }
-        });
-    }
-
-    /**
-     * Uninstalls flow rules associated with a given port from a given device.
-     *
-     * @param deviceId device id
-     * @param inPort port associated with removed host
-     * @param dstInfos list of destination info
-     */
-    public void uninstallFlowRules(DeviceId deviceId, Port inPort, List<DestinationInfo> dstInfos) {
-        dstInfos.stream().forEach(dstInfo -> {
-            ForwardingObjective.Builder fBuilder = isTunnelPort(dstInfo.output()) ?
-                    vtnRulesRemoteNode(deviceId, inPort, dstInfo) : vtnRulesSameNode(inPort, dstInfo);
-
-            if (fBuilder != null) {
-                flowObjectiveService.forward(deviceId, fBuilder.remove());
-            }
-        });
-    }
-
-    /**
-     * Returns forwarding objective builder to provision basic virtual tenant network.
-     * This method cares for the traffics whose source and destination device is the same.
-     *
-     * @param inPort in port
-     * @param dstInfo destination information
-     * @return forwarding objective builder
-     */
-    private ForwardingObjective.Builder vtnRulesSameNode(Port inPort, DestinationInfo dstInfo) {
-        checkArgument(inPort.element().id().equals(dstInfo.output().element().id()));
-
-        TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder();
-        TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
-
-        sBuilder.matchInPort(inPort.number())
-                .matchEthDst(dstInfo.mac());
-        if (isTunnelPort(inPort)) {
-            sBuilder.matchTunnelId(dstInfo.tunnelId());
+        DeviceId deviceId = host.location().deviceId();
+        if (!mastershipService.isLocalMaster(deviceId)) {
+            return;
         }
 
-        tBuilder.setOutput(dstInfo.output().number());
+        PortNumber inPort = host.location().port();
+        MacAddress dstMac = host.mac();
+        long tunnelId = Long.parseLong(vNet.segmentId());
 
-        return DefaultForwardingObjective.builder()
-                .withSelector(sBuilder.build())
-                .withTreatment(tBuilder.build())
-                .withPriority(DEFAULT_PRIORITY)
-                .withFlag(ForwardingObjective.Flag.VERSATILE)
-                .fromApp(appId)
-                .makePermanent();
+        OpenstackSubnet subnet = vNet.subnets().stream()
+                .findFirst()
+                .orElse(null);
+
+        if (subnet == null) {
+            log.error("Failed to get subnet for {}", host.id());
+            return;
+        }
+
+        populateLocalInPortRule(deviceId, inPort, hostIp);
+        populateDirectAccessRule(Ip4Prefix.valueOf(subnet.cidr()), Ip4Prefix.valueOf(subnet.cidr()));
+        populateDstIpRule(deviceId, inPort, dstMac, hostIp, tunnelId, tunnelIp);
+        populateTunnelInRule(deviceId, inPort, dstMac, tunnelId);
     }
 
     /**
-     * Returns forwarding objective builder to provision basic virtual tenant network.
-     * This method cares for the traffics whose source and destination is not the same.
+     * Populates service dependency rules.
      *
-     * @param deviceId device id to install flow rules
-     * @param inPort in port
-     * @param dstInfo destination information
-     * @return forwarding objective, or null if it fails to build it
+     * @param tService tenant cord service
+     * @param pService provider cord service
      */
-    private ForwardingObjective.Builder vtnRulesRemoteNode(DeviceId deviceId, Port inPort, DestinationInfo dstInfo) {
-        checkArgument(isTunnelPort(dstInfo.output()));
+    public void populateServiceDependencyRules(CordService tService, CordService pService) {
+        checkNotNull(tService);
+        checkNotNull(pService);
 
-        TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder();
-        TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
+        Ip4Prefix srcRange = tService.serviceIpRange().getIp4Prefix();
+        Ip4Prefix dstRange = pService.serviceIpRange().getIp4Prefix();
+        Ip4Address serviceIp = pService.serviceIp().getIp4Address();
 
-        ExtensionTreatment extTreatment =
-                getTunnelDstInstruction(deviceId, dstInfo.remoteIp().getIp4Address());
-        if (extTreatment == null) {
+        Map<DeviceId, GroupId> outGroups = Maps.newHashMap();
+        Map<DeviceId, Set<PortNumber>> inPorts = Maps.newHashMap();
+
+        for (Device device : deviceService.getAvailableDevices(SWITCH)) {
+            GroupId groupId = createServiceGroup(device.id(), pService);
+            outGroups.put(device.id(), groupId);
+
+            Set<PortNumber> vms = tService.hosts().keySet()
+                    .stream()
+                    .filter(host -> host.location().deviceId().equals(device.id()))
+                    .map(host -> host.location().port())
+                    .collect(Collectors.toSet());
+            inPorts.put(device.id(), vms);
+        }
+
+        populateIndirectAccessRule(srcRange, serviceIp, outGroups);
+        populateDirectAccessRule(srcRange, dstRange);
+        populateInServiceRule(inPorts, outGroups);
+    }
+
+    /**
+     * Removes basic rules related to a given flow information.
+     *
+     * @param host host to be removed
+     */
+    public void removeBasicConnectionRules(Host host) {
+        checkNotNull(host);
+
+        DeviceId deviceId = host.location().deviceId();
+        MacAddress mac = host.mac();
+        PortNumber port = host.location().port();
+        IpAddress ip = host.ipAddresses().stream().findFirst().orElse(null);
+
+        if (!mastershipService.isLocalMaster(deviceId)) {
+            return;
+        }
+
+        for (FlowRule flowRule : flowRuleService.getFlowRulesById(appId)) {
+            if (flowRule.deviceId().equals(deviceId)) {
+                PortNumber inPort = getInPort(flowRule);
+                if (inPort != null && inPort.equals(port)) {
+                    processFlowRule(false, flowRule);
+                    continue;
+                }
+            }
+
+            MacAddress dstMac = getDstMacFromTreatment(flowRule);
+            if (dstMac != null && dstMac.equals(mac)) {
+                processFlowRule(false, flowRule);
+                continue;
+            }
+
+            dstMac = getDstMacFromSelector(flowRule);
+            if (dstMac != null && dstMac.equals(mac)) {
+                processFlowRule(false, flowRule);
+                continue;
+            }
+
+            IpPrefix dstIp = getDstIpFromSelector(flowRule);
+            if (dstIp != null && dstIp.equals(ip.toIpPrefix())) {
+                processFlowRule(false, flowRule);
+            }
+
+        }
+
+        // TODO uninstall same network access rule in access table if no vm exists in the network
+    }
+
+    /**
+     * Removes service dependency rules.
+     *
+     * @param tService tenant cord service
+     * @param pService provider cord service
+     */
+    public void removeServiceDependencyRules(CordService tService, CordService pService) {
+        checkNotNull(tService);
+        checkNotNull(pService);
+
+        Ip4Prefix srcRange = tService.serviceIpRange().getIp4Prefix();
+        Ip4Prefix dstRange = pService.serviceIpRange().getIp4Prefix();
+        IpPrefix serviceIp = pService.serviceIp().toIpPrefix();
+
+        Map<DeviceId, GroupId> outGroups = Maps.newHashMap();
+        GroupKey groupKey = new DefaultGroupKey(pService.id().id().getBytes());
+
+        deviceService.getAvailableDevices(SWITCH).forEach(device -> {
+            Group group = groupService.getGroup(device.id(), groupKey);
+            if (group != null) {
+                outGroups.put(device.id(), group.id());
+            }
+        });
+
+        for (FlowRule flowRule : flowRuleService.getFlowRulesById(appId)) {
+            IpPrefix dstIp = getDstIpFromSelector(flowRule);
+            IpPrefix srcIp = getSrcIpFromSelector(flowRule);
+
+            if (dstIp != null && dstIp.equals(serviceIp)) {
+                processFlowRule(false, flowRule);
+                continue;
+            }
+
+            if (dstIp != null && srcIp != null) {
+                if (dstIp.equals(dstRange) && srcIp.equals(srcRange)) {
+                    processFlowRule(false, flowRule);
+                    continue;
+                }
+
+                if (dstIp.equals(srcRange) && srcIp.equals(dstRange)) {
+                    processFlowRule(false, flowRule);
+                    continue;
+                }
+            }
+
+            GroupId groupId = getGroupIdFromTreatment(flowRule);
+            if (groupId != null && groupId.equals(outGroups.get(flowRule.deviceId()))) {
+                processFlowRule(false, flowRule);
+            }
+        }
+
+        // TODO remove the group if it is not in use
+    }
+
+    /**
+     * 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, CordService 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.segmentationId(), service.hosts());
+        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, Map<Host, IpAddress> hosts) {
+        List<GroupBucket> buckets = Lists.newArrayList();
+
+        for (Map.Entry<Host, IpAddress> entry : hosts.entrySet()) {
+            Host host = entry.getKey();
+            Ip4Address remoteIp = entry.getValue().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, remoteIp);
+                if (tunnelDst == null) {
+                    continue;
+                }
+
+                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(CordServiceId 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(CordServiceId serviceId) {
+        return new DefaultGroupKey(serviceId.id().getBytes());
+    }
+
+    /**
+     * Forward table miss rules in ACCESS_TYPE table to IN_SERVICE table.
+     *
+     * @param deviceId device id
+     */
+    private void processAccessTypeTable(DeviceId deviceId) {
+        TrafficSelector selector = DefaultTrafficSelector.builder()
+                .build();
+
+        TrafficTreatment treatment = DefaultTrafficTreatment.builder()
+                .transition(TABLE_IN_SERVICE)
+                .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 rules for tunnel flows in port in IN_PORT table.
+     * All flows from tunnel port are forwarded to TUNNEL_ID table.
+     *
+     * @param deviceId device id to install the rules
+     * @param tunnelPort tunnel port
+     */
+    private void populateTunnelInPortRule(DeviceId deviceId, PortNumber tunnelPort) {
+        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);
+    }
+
+    /**
+     * 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
+     */
+    private void populateLocalInPortRule(DeviceId deviceId, PortNumber inPort, IpAddress srcIp) {
+        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(true, 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(LOWER_PRIORITY)
+                .forDevice(deviceId)
+                .forTable(TABLE_IN_PORT)
+                .makePermanent()
+                .build();
+
+        processFlowRule(true, 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
+     */
+    private void populateDirectAccessRule(Ip4Prefix srcRange, Ip4Prefix dstRange) {
+        TrafficSelector selector = DefaultTrafficSelector.builder()
+                .matchEthType(Ethernet.TYPE_IPV4)
+                .matchIPSrc(srcRange)
+                .matchIPDst(dstRange)
+                .build();
+        TrafficTreatment treatment = DefaultTrafficTreatment.builder()
+                .transition(TABLE_DST_IP)
+                .build();
+
+        for (Device device : deviceService.getAvailableDevices(SWITCH)) {
+            FlowRule flowRuleDirect = DefaultFlowRule.builder()
+                    .fromApp(appId)
+                    .withSelector(selector)
+                    .withTreatment(treatment)
+                    .withPriority(LOWER_PRIORITY)
+                    .forDevice(device.id())
+                    .forTable(TABLE_ACCESS_TYPE)
+                    .makePermanent()
+                    .build();
+
+            processFlowRule(true, 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
+     */
+    private void populateIndirectAccessRule(Ip4Prefix srcRange, Ip4Address serviceIp,
+                                            Map<DeviceId, GroupId> outGroups) {
+        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(DEFAULT_PRIORITY)
+                    .forDevice(outGroup.getKey())
+                    .forTable(TABLE_ACCESS_TYPE)
+                    .makePermanent()
+                    .build();
+
+            processFlowRule(true, 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
+     */
+    private void populateInServiceRule(Map<DeviceId, Set<PortNumber>> inPorts, Map<DeviceId, GroupId> outGroups) {
+        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(true, 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
+     */
+    private void populateDstIpRule(DeviceId deviceId, PortNumber inPort, MacAddress dstMac,
+                                   IpAddress dstIp, long tunnelId, IpAddress tunnelIp) {
+        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(true, flowRule);
+
+        for (Device device : deviceService.getAvailableDevices(SWITCH)) {
+            if (device.id().equals(deviceId)) {
+                continue;
+            }
+
+            ExtensionTreatment tunnelDst = getTunnelDst(device.id(), tunnelIp.getIp4Address());
+            if (tunnelDst == null) {
+                continue;
+            }
+
+            treatment = DefaultTrafficTreatment.builder()
+                    .setEthDst(dstMac)
+                    .setTunnelId(tunnelId)
+                    .extension(tunnelDst, device.id())
+                    .setOutput(getTunnelPort(device.id()))
+                    .build();
+
+            flowRule = DefaultFlowRule.builder()
+                    .fromApp(appId)
+                    .withSelector(selector)
+                    .withTreatment(treatment)
+                    .withPriority(DEFAULT_PRIORITY)
+                    .forDevice(device.id())
+                    .forTable(TABLE_DST_IP)
+                    .makePermanent()
+                    .build();
+
+            processFlowRule(true, flowRule);
+        }
+    }
+
+    /**
+     * Populates flow rules for TUNNEL_ID table.
+     *
+     * @param deviceId device id
+     * @param inPort in port
+     * @param mac mac address
+     * @param tunnelId tunnel id
+     */
+    private void populateTunnelInRule(DeviceId deviceId, PortNumber inPort, MacAddress mac, long tunnelId) {
+        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(true, 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) {
+        try {
+            return deviceService.getPorts(deviceId).stream()
+                    .filter(p -> p.annotations().value("portName").contains(tunnelType))
+                    .findFirst().get().number();
+        } catch (NoSuchElementException e) {
+            return null;
+        }
+    }
+
+    /**
+     * Returns the inport from a given flow rule if the rule contains the match of it.
+     *
+     * @param flowRule flow rule
+     * @return port number, or null if the rule doesn't have inport match
+     */
+    private PortNumber getInPort(FlowRule flowRule) {
+        Criterion criterion = flowRule.selector().getCriterion(IN_PORT);
+        if (criterion != null && criterion instanceof PortCriterion) {
+            PortCriterion port = (PortCriterion) criterion;
+            return port.port();
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * Returns the destination mac address from a given flow rule if the rule
+     * contains the instruction of it.
+     *
+     * @param flowRule flow rule
+     * @return mac address, or null if the rule doesn't have destination mac instruction
+     */
+    private MacAddress getDstMacFromTreatment(FlowRule flowRule) {
+        Instruction instruction = flowRule.treatment().allInstructions().stream()
+                .filter(inst -> inst instanceof ModEtherInstruction &&
+                        ((ModEtherInstruction) inst).subtype().equals(ETH_DST))
+                .findFirst()
+                .orElse(null);
+
+        if (instruction == null) {
             return null;
         }
 
-        sBuilder.matchInPort(inPort.number())
-                .matchEthDst(dstInfo.mac());
-
-        tBuilder.extension(extTreatment, deviceId)
-                .setTunnelId(dstInfo.tunnelId())
-                .setOutput(dstInfo.output().number());
-
-        return DefaultForwardingObjective.builder()
-                .withSelector(sBuilder.build())
-                .withTreatment(tBuilder.build())
-                .withPriority(DEFAULT_PRIORITY)
-                .withFlag(ForwardingObjective.Flag.VERSATILE)
-                .fromApp(appId)
-                .makePermanent();
+        return ((ModEtherInstruction) instruction).mac();
     }
 
     /**
-     * Checks if a given port is tunnel interface or not.
-     * It assumes the tunnel interface contains tunnelType string in its name.
+     * Returns the destination mac address from a given flow rule if the rule
+     * contains the match of it.
      *
-     * @param port port
-     * @return true if the port is tunnel interface, false otherwise.
+     * @param flowRule flow rule
+     * @return mac address, or null if the rule doesn't have destination mac match
      */
-    private boolean isTunnelPort(Port port) {
-        return port.annotations().value("portName").contains(tunnelType);
+    private MacAddress getDstMacFromSelector(FlowRule flowRule) {
+        Criterion criterion = flowRule.selector().getCriterion(Criterion.Type.ETH_DST);
+        if (criterion != null && criterion instanceof EthCriterion) {
+            EthCriterion eth = (EthCriterion) criterion;
+            return eth.mac();
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * 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 source 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 getSrcIpFromSelector(FlowRule flowRule) {
+        Criterion criterion = flowRule.selector().getCriterion(IPV4_SRC);
+        if (criterion != null && criterion instanceof IPCriterion) {
+            IPCriterion ip = (IPCriterion) criterion;
+            return ip.ip();
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * Returns the group ID from a given flow rule if the rule contains the
+     * treatment of it.
+     *
+     * @param flowRule flow rule
+     * @return group id, or null if the rule doesn't have group instruction
+     */
+    private GroupId getGroupIdFromTreatment(FlowRule flowRule) {
+        Instruction instruction = flowRule.treatment().allInstructions().stream()
+                .filter(inst -> inst instanceof Instructions.GroupInstruction)
+                .findFirst()
+                .orElse(null);
+
+        if (instruction == null) {
+            return null;
+        }
+
+        return ((Instructions.GroupInstruction) instruction).groupId();
     }
 
     /**
@@ -213,19 +877,23 @@
      * @param remoteIp tunnel destination address
      * @return extension treatment or null if it fails to get instruction
      */
-    private ExtensionTreatment getTunnelDstInstruction(DeviceId deviceId, Ip4Address remoteIp) {
+    private ExtensionTreatment getTunnelDst(DeviceId deviceId, Ip4Address remoteIp) {
         try {
             Driver driver = driverService.getDriver(deviceId);
-            DriverHandler handler = new DefaultDriverHandler(new DefaultDriverData(driver, deviceId));
-            ExtensionTreatmentResolver resolver =  handler.behaviour(ExtensionTreatmentResolver.class);
+            DefaultDriverData driverData = new DefaultDriverData(driver, deviceId);
+            DriverHandler handler = new DefaultDriverHandler(driverData);
+            ExtensionTreatmentResolver resolver = handler.behaviour(ExtensionTreatmentResolver.class);
 
-            ExtensionTreatment treatment = resolver.getExtensionInstruction(NICIRA_SET_TUNNEL_DST.type());
+            ExtensionTreatment treatment =
+                    resolver.getExtensionInstruction(NICIRA_SET_TUNNEL_DST.type());
             treatment.setPropertyValue("tunnelDst", remoteIp);
 
             return treatment;
-        } catch (ItemNotFoundException | UnsupportedOperationException | ExtensionPropertyException e) {
-            log.error("Failed to get extension instruction to set tunnel dst {}", deviceId);
+        } catch (ItemNotFoundException | UnsupportedOperationException |
+                ExtensionPropertyException e) {
+            log.error("Failed to get extension instruction {}", deviceId);
             return null;
         }
     }
 }
+
diff --git a/apps/cordvtn/src/main/java/org/onosproject/cordvtn/CordVtnService.java b/apps/cordvtn/src/main/java/org/onosproject/cordvtn/CordVtnService.java
index 29b4525..2c3c23b 100644
--- a/apps/cordvtn/src/main/java/org/onosproject/cordvtn/CordVtnService.java
+++ b/apps/cordvtn/src/main/java/org/onosproject/cordvtn/CordVtnService.java
@@ -69,15 +69,16 @@
     /**
      * Creates dependencies for a given tenant service.
      *
-     * @param tenantCordServiceId id of the service which has a dependency
-     * @param providerCordServiceId id of the service which provide dependency
+     * @param tServiceId id of the service which has a dependency
+     * @param pServiceId id of the service which provide dependency
      */
-    void createServiceDependency(CordServiceId tenantCordServiceId, CordServiceId providerCordServiceId);
+    void createServiceDependency(CordServiceId tServiceId, CordServiceId pServiceId);
 
     /**
      * Removes all dependencies from a given tenant service.
      *
-     * @param tenantCordServiceId id of the service which has a dependency
+     * @param tServiceId id of the service which has a dependency
+     * @param pServiceId id of the service which provide dependency
      */
-    void removeServiceDependency(CordServiceId tenantCordServiceId);
+    void removeServiceDependency(CordServiceId tServiceId, CordServiceId pServiceId);
 }
diff --git a/apps/cordvtn/src/main/java/org/onosproject/cordvtn/DestinationInfo.java b/apps/cordvtn/src/main/java/org/onosproject/cordvtn/DestinationInfo.java
deleted file mode 100644
index 290cc17..0000000
--- a/apps/cordvtn/src/main/java/org/onosproject/cordvtn/DestinationInfo.java
+++ /dev/null
@@ -1,190 +0,0 @@
-/*
- * Copyright 2014-2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onosproject.cordvtn;
-
-import org.onlab.packet.IpAddress;
-import org.onlab.packet.MacAddress;
-import org.onosproject.net.Port;
-
-import java.util.List;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-/**
- * Contains destination information.
- */
-public final class DestinationInfo {
-
-    private final Port output;
-    private final List<IpAddress> ip;
-    private final MacAddress mac;
-    private final IpAddress remoteIp;
-    private final long tunnelId;
-
-    /**
-     * Creates a new destination information.
-     *
-     * @param output output port
-     * @param ip destination ip address
-     * @param mac destination mac address
-     * @param remoteIp tunnel remote ip address
-     * @param tunnelId segment id
-     */
-    public DestinationInfo(Port output, List<IpAddress> ip, MacAddress mac,
-                           IpAddress remoteIp, long tunnelId) {
-        this.output = checkNotNull(output);
-        this.ip = ip;
-        this.mac = mac;
-        this.remoteIp = remoteIp;
-        this.tunnelId = tunnelId;
-    }
-
-    /**
-     * Returns output port.
-     *
-     * @return port
-     */
-    public Port output() {
-        return output;
-    }
-
-    /**
-     * Returns destination ip addresses.
-     *
-     * @return list of ip address
-     */
-    public List<IpAddress> ip() {
-        return ip;
-    }
-
-    /**
-     * Returns destination mac address.
-     *
-     * @return mac address
-     */
-    public MacAddress mac() {
-        return mac;
-    }
-
-    /**
-     * Returns tunnel remote ip address.
-     *
-     * @return ip address
-     */
-    public IpAddress remoteIp() {
-        return remoteIp;
-    }
-
-    /**
-     * Returns tunnel id.
-     *
-     * @return tunnel id
-     */
-    public long tunnelId() {
-        return tunnelId;
-    }
-
-    /**
-     * Returns a new destination info builder.
-     *
-     * @return destination info builder
-     */
-    public static DestinationInfo.Builder builder(Port output) {
-        return new Builder(output);
-    }
-
-    /**
-     * DestinationInfo builder class.
-     */
-    public static final class Builder {
-
-        private final Port output;
-        private List<IpAddress> ip;
-        private MacAddress mac;
-        private IpAddress remoteIp;
-        private long tunnelId;
-
-        /**
-         * Creates a new destination information builder.
-         *
-         * @param output output port
-         */
-        public Builder(Port output) {
-            this.output = checkNotNull(output, "Output port cannot be null");
-        }
-
-        /**
-         * Sets the destination ip address.
-         *
-         * @param ip ip address
-         * @return destination info builder
-         */
-        public Builder setIp(List<IpAddress> ip) {
-            this.ip = checkNotNull(ip, "IP cannot be null");
-            return this;
-        }
-
-        /**
-         * Sets the destination mac address.
-         *
-         * @param mac mac address
-         * @return destination info builder
-         */
-        public Builder setMac(MacAddress mac) {
-            this.mac = checkNotNull(mac, "MAC address cannot be null");
-            return this;
-        }
-
-        /**
-         * Sets the tunnel remote ip address.
-         *
-         * @param remoteIp ip address
-         * @return destination info builder
-         */
-        public Builder setRemoteIp(IpAddress remoteIp) {
-            this.remoteIp = checkNotNull(remoteIp, "Remote IP address cannot be null");
-            return this;
-        }
-
-        /**
-         * Sets the tunnel id.
-         *
-         * @param tunnelId tunnel id
-         * @return destination info builder
-         */
-        public Builder setTunnelId(long tunnelId) {
-            this.tunnelId = checkNotNull(tunnelId, "Tunnel ID cannot be null");
-            return this;
-        }
-
-        /**
-         * Build a destination information.
-         *
-         * @return destination info object
-         */
-        public DestinationInfo build() {
-            return new DestinationInfo(this);
-        }
-    }
-
-    private DestinationInfo(Builder builder) {
-        output = builder.output;
-        ip = builder.ip;
-        mac = builder.mac;
-        remoteIp = builder.remoteIp;
-        tunnelId = builder.tunnelId;
-    }
-}
diff --git a/apps/cordvtn/src/main/java/org/onosproject/cordvtn/rest/ServiceDependencyWebResource.java b/apps/cordvtn/src/main/java/org/onosproject/cordvtn/rest/ServiceDependencyWebResource.java
index d2c5567..c5d1ded 100644
--- a/apps/cordvtn/src/main/java/org/onosproject/cordvtn/rest/ServiceDependencyWebResource.java
+++ b/apps/cordvtn/src/main/java/org/onosproject/cordvtn/rest/ServiceDependencyWebResource.java
@@ -58,14 +58,16 @@
     /**
      * Removes service dependencies.
      *
-     * @param serviceId service id
+     * @param tServiceId tenant service id
+     * @param pServiceId provider service id
      * @return 200 OK, or 400 Bad Request
      */
     @DELETE
-    @Path("{serviceId}")
+    @Path("{tenantServiceId}/{providerServiceId}")
     @Produces(MediaType.APPLICATION_JSON)
-    public Response removeServiceDependency(@PathParam("serviceId") String serviceId) {
-        service.removeServiceDependency(CordServiceId.of(serviceId));
+    public Response removeServiceDependency(@PathParam("tenantServiceId") String tServiceId,
+                                            @PathParam("providerServiceId") String pServiceId) {
+        service.removeServiceDependency(CordServiceId.of(tServiceId), CordServiceId.of(pServiceId));
         return Response.status(Response.Status.OK).build();
     }
 
