diff --git a/src/main/java/org/onosproject/cordvtn/CordService.java b/src/main/java/org/onosproject/cordvtn/CordService.java
index 2e4a59e..0d09bb3 100644
--- a/src/main/java/org/onosproject/cordvtn/CordService.java
+++ b/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/src/main/java/org/onosproject/cordvtn/CordVtn.java b/src/main/java/org/onosproject/cordvtn/CordVtn.java
index d1ff7f0..d119a5a 100644
--- a/src/main/java/org/onosproject/cordvtn/CordVtn.java
+++ b/src/main/java/org/onosproject/cordvtn/CordVtn.java
@@ -15,7 +15,6 @@
  */
 package org.onosproject.cordvtn;
 
-import com.google.common.collect.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/src/main/java/org/onosproject/cordvtn/CordVtnRuleInstaller.java b/src/main/java/org/onosproject/cordvtn/CordVtnRuleInstaller.java
index 9e22997..4e044e1 100644
--- a/src/main/java/org/onosproject/cordvtn/CordVtnRuleInstaller.java
+++ b/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/src/main/java/org/onosproject/cordvtn/CordVtnService.java b/src/main/java/org/onosproject/cordvtn/CordVtnService.java
index 29b4525..2c3c23b 100644
--- a/src/main/java/org/onosproject/cordvtn/CordVtnService.java
+++ b/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/src/main/java/org/onosproject/cordvtn/DestinationInfo.java b/src/main/java/org/onosproject/cordvtn/DestinationInfo.java
deleted file mode 100644
index 290cc17..0000000
--- a/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/src/main/java/org/onosproject/cordvtn/rest/ServiceDependencyWebResource.java b/src/main/java/org/onosproject/cordvtn/rest/ServiceDependencyWebResource.java
index d2c5567..c5d1ded 100644
--- a/src/main/java/org/onosproject/cordvtn/rest/ServiceDependencyWebResource.java
+++ b/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();
     }
 
