diff --git a/apps/openstacknetworking/api/src/main/java/org/onosproject/openstacknetworking/AbstractVmHandler.java b/apps/openstacknetworking/api/src/main/java/org/onosproject/openstacknetworking/AbstractVmHandler.java
index 58b89a6..a373ff0 100644
--- a/apps/openstacknetworking/api/src/main/java/org/onosproject/openstacknetworking/AbstractVmHandler.java
+++ b/apps/openstacknetworking/api/src/main/java/org/onosproject/openstacknetworking/AbstractVmHandler.java
@@ -25,6 +25,9 @@
 import org.onosproject.net.host.HostEvent;
 import org.onosproject.net.host.HostListener;
 import org.onosproject.net.host.HostService;
+import org.onosproject.openstackinterface.OpenstackInterfaceService;
+import org.onosproject.openstackinterface.OpenstackRouter;
+import org.onosproject.openstackinterface.OpenstackSubnet;
 import org.slf4j.Logger;
 
 import java.util.Objects;
@@ -50,6 +53,7 @@
     protected CoreService coreService;
     protected MastershipService mastershipService;
     protected HostService hostService;
+    protected OpenstackInterfaceService openstackService;
 
     protected HostListener hostListener = new InternalHostListener();
 
@@ -57,6 +61,7 @@
         ServiceDirectory services = new DefaultServiceDirectory();
         coreService = services.get(CoreService.class);
         mastershipService = services.get(MastershipService.class);
+        openstackService = services.get(OpenstackInterfaceService.class);
         hostService = services.get(HostService.class);
         hostService.addListener(hostListener);
 
@@ -107,6 +112,28 @@
                 .findFirst();
     }
 
+    protected Set<Host> getHosts(OpenstackSubnet osSubnet) {
+        return Tools.stream(hostService.getHosts())
+                .filter(host -> host.annotations().value(SUBNET_ID).equals(osSubnet.id()))
+                .collect(Collectors.toSet());
+    }
+
+    protected Optional<OpenstackRouter> getRouter(Host host) {
+        return openstackService.routers().stream()
+                .filter(router -> routableSubNets(router.id()).stream()
+                        .filter(subnet -> subnet.id().equals(host.annotations().value(SUBNET_ID)))
+                        .findAny().isPresent())
+                .findAny();
+    }
+
+    protected Set<OpenstackSubnet> routableSubNets(String osRouterId) {
+        return openstackService.ports().stream()
+                .filter(p -> p.deviceOwner().equals(DEVICE_OWNER_ROUTER_INTERFACE) &&
+                        p.deviceId().equals(osRouterId))
+                .map(p -> openstackService.subnet(p.fixedIps().keySet().stream().findFirst().get()))
+                .collect(Collectors.toSet());
+    }
+
     protected Ip4Address getIp(Host host) {
         return host.ipAddresses().stream().findFirst().get().getIp4Address();
     }
diff --git a/apps/openstacknetworking/api/src/main/java/org/onosproject/openstacknetworking/RulePopulatorUtil.java b/apps/openstacknetworking/api/src/main/java/org/onosproject/openstacknetworking/RulePopulatorUtil.java
index d220b8c..3326417 100644
--- a/apps/openstacknetworking/api/src/main/java/org/onosproject/openstacknetworking/RulePopulatorUtil.java
+++ b/apps/openstacknetworking/api/src/main/java/org/onosproject/openstacknetworking/RulePopulatorUtil.java
@@ -21,8 +21,8 @@
 import org.onosproject.net.DeviceId;
 import org.onosproject.net.behaviour.ExtensionTreatmentResolver;
 import org.onosproject.net.device.DeviceService;
-import org.onosproject.net.flow.DefaultTrafficTreatment;
 import org.onosproject.net.flow.TrafficSelector;
+import org.onosproject.net.flow.TrafficTreatment;
 import org.onosproject.net.flow.instructions.ExtensionPropertyException;
 import org.onosproject.net.flow.instructions.ExtensionTreatment;
 import org.onosproject.net.flowobjective.DefaultForwardingObjective;
@@ -74,29 +74,36 @@
     }
 
     /**
-     * Removes flow rules with the supplied information.
+     * Adds flow rules with the supplied information.
      *
      * @param flowObjectiveService flow objective service
      * @param appId application id
      * @param deviceId device id to remove this flow rule
      * @param selector traffic selector
+     * @param treatment traffic treatment
      * @param flag flag
      * @param priority priority
+     * @param install populate flows if true, remove them otherwise
      */
-    public static void removeRule(FlowObjectiveService flowObjectiveService,
-                           ApplicationId appId,
-                           DeviceId deviceId,
-                           TrafficSelector selector,
-                           ForwardingObjective.Flag flag,
-                           int priority) {
-        ForwardingObjective fo = DefaultForwardingObjective.builder()
+    public static void setRule(FlowObjectiveService flowObjectiveService,
+                               ApplicationId appId,
+                               DeviceId deviceId,
+                               TrafficSelector selector,
+                               TrafficTreatment treatment,
+                               ForwardingObjective.Flag flag,
+                               int priority,
+                               boolean install) {
+        ForwardingObjective.Builder foBuilder = DefaultForwardingObjective.builder()
                 .withSelector(selector)
-                .withTreatment(DefaultTrafficTreatment.builder().build())
+                .withTreatment(treatment)
                 .withFlag(flag)
                 .withPriority(priority)
-                .fromApp(appId)
-                .remove();
+                .fromApp(appId);
 
-        flowObjectiveService.forward(deviceId, fo);
+        if (install) {
+            flowObjectiveService.forward(deviceId, foBuilder.add());
+        } else {
+            flowObjectiveService.forward(deviceId, foBuilder.remove());
+        }
     }
 }
diff --git a/apps/openstacknetworking/routing/src/main/java/org/onosproject/openstacknetworking/routing/OpenstackFloatingIpManager.java b/apps/openstacknetworking/routing/src/main/java/org/onosproject/openstacknetworking/routing/OpenstackFloatingIpManager.java
index b3990e1..7b7f778 100644
--- a/apps/openstacknetworking/routing/src/main/java/org/onosproject/openstacknetworking/routing/OpenstackFloatingIpManager.java
+++ b/apps/openstacknetworking/routing/src/main/java/org/onosproject/openstacknetworking/routing/OpenstackFloatingIpManager.java
@@ -263,29 +263,32 @@
                     .matchIPDst(floatingIp.toIpPrefix())
                     .matchInPort(nodeService.tunnelPort(deviceId).get());
 
-            RulePopulatorUtil.removeRule(
+            RulePopulatorUtil.setRule(
                     flowObjectiveService,
                     appId,
                     deviceId,
                     sOutgoingBuilder.build(),
+                    DefaultTrafficTreatment.builder().build(),
                     ForwardingObjective.Flag.VERSATILE,
-                    FLOATING_RULE_PRIORITY);
+                    FLOATING_RULE_PRIORITY, false);
 
-            RulePopulatorUtil.removeRule(
+            RulePopulatorUtil.setRule(
                     flowObjectiveService,
                     appId,
                     deviceId,
                     sIncomingBuilder.build(),
+                    DefaultTrafficTreatment.builder().build(),
                     ForwardingObjective.Flag.VERSATILE,
-                    FLOATING_RULE_PRIORITY);
+                    FLOATING_RULE_PRIORITY, false);
 
-            RulePopulatorUtil.removeRule(
+            RulePopulatorUtil.setRule(
                     flowObjectiveService,
                     appId,
                     deviceId,
                     sForTrafficFromVmBuilder.build(),
+                    DefaultTrafficTreatment.builder().build(),
                     ForwardingObjective.Flag.VERSATILE,
-                    FLOATING_RULE_FOR_TRAFFIC_FROM_VM_PRIORITY);
+                    FLOATING_RULE_FOR_TRAFFIC_FROM_VM_PRIORITY, false);
         });
     }
 
diff --git a/apps/openstacknetworking/routing/src/main/java/org/onosproject/openstacknetworking/routing/OpenstackRoutingManager.java b/apps/openstacknetworking/routing/src/main/java/org/onosproject/openstacknetworking/routing/OpenstackRoutingManager.java
index c8ce876..f7989bd 100644
--- a/apps/openstacknetworking/routing/src/main/java/org/onosproject/openstacknetworking/routing/OpenstackRoutingManager.java
+++ b/apps/openstacknetworking/routing/src/main/java/org/onosproject/openstacknetworking/routing/OpenstackRoutingManager.java
@@ -15,7 +15,6 @@
  */
 package org.onosproject.openstacknetworking.routing;
 
-import com.google.common.collect.ImmutableSet;
 import org.apache.felix.scr.annotations.Activate;
 import org.apache.felix.scr.annotations.Component;
 import org.apache.felix.scr.annotations.Deactivate;
@@ -25,10 +24,11 @@
 import org.onlab.packet.Ethernet;
 import org.onlab.packet.IPv4;
 import org.onlab.packet.Ip4Address;
+import org.onlab.packet.IpAddress;
 import org.onlab.packet.IpPrefix;
-import org.onlab.packet.MacAddress;
 import org.onlab.util.Tools;
 import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreService;
 import org.onosproject.core.GroupId;
 import org.onosproject.net.DeviceId;
 import org.onosproject.net.Host;
@@ -38,12 +38,10 @@
 import org.onosproject.net.flow.DefaultTrafficTreatment;
 import org.onosproject.net.flow.TrafficSelector;
 import org.onosproject.net.flow.TrafficTreatment;
-import org.onosproject.net.flowobjective.DefaultForwardingObjective;
 import org.onosproject.net.flowobjective.FlowObjectiveService;
 import org.onosproject.net.flowobjective.ForwardingObjective;
 import org.onosproject.openstackinterface.OpenstackInterfaceService;
 import org.onosproject.openstackinterface.OpenstackNetwork;
-import org.onosproject.openstackinterface.OpenstackPort;
 import org.onosproject.openstackinterface.OpenstackRouter;
 import org.onosproject.openstackinterface.OpenstackRouterInterface;
 import org.onosproject.openstackinterface.OpenstackSubnet;
@@ -62,7 +60,6 @@
 
 import java.util.HashMap;
 import java.util.Map;
-import java.util.Objects;
 import java.util.Optional;
 import java.util.Set;
 import java.util.concurrent.ExecutorService;
@@ -85,9 +82,6 @@
     protected FlowObjectiveService flowObjectiveService;
 
     @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
-    protected DeviceService deviceService;
-
-    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
     protected OpenstackInterfaceService openstackService;
 
     @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
@@ -96,6 +90,12 @@
     @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
     protected ScalableGatewayService gatewayService;
 
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected CoreService coreService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected DeviceService deviceService;
+
     private final ExecutorService eventExecutor = newSingleThreadScheduledExecutor(
             groupedThreads(this.getClass().getSimpleName(), "event-handler", log));
     private final InternalNodeListener nodeListener = new InternalNodeListener();
@@ -111,37 +111,56 @@
 
     @Deactivate
     protected void deactivate() {
+        super.deactivate();
         nodeService.removeListener(nodeListener);
         log.info("stopped");
     }
 
     @Override
+    protected void hostDetected(Host host) {
+        // Installs forwarding flow rules to VMs in different nodes and different subnets
+        // that are connected via a router
+        Optional<OpenstackRouter> routerOfTheHost = getRouter(host);
+
+        if (!routerOfTheHost.isPresent()) {
+            return;
+        }
+
+        routableSubNets(routerOfTheHost.get().id()).stream()
+                .filter(subnet -> !subnet.id().equals(host.annotations().value(SUBNET_ID)))
+                .forEach(subnet -> setForwardingRulesAmongHostsInDifferentCnodes(host, getHosts(subnet), true));
+    }
+
+    @Override
+    protected void hostRemoved(Host host) {
+        // Removes forwarding flow rules to VMs in different nodes and different subnets
+        // that are connected via a router
+        Optional<OpenstackRouter> routerOfTheHost = getRouter(host);
+        if (!routerOfTheHost.isPresent()) {
+            return;
+        }
+
+        routableSubNets(routerOfTheHost.get().id()).stream()
+                .filter(subnet -> !subnet.id().equals(host.annotations().value(SUBNET_ID)))
+                .forEach(subnet -> setForwardingRulesAmongHostsInDifferentCnodes(host, getHosts(subnet), false));
+    }
+
+    @Override
     public void createRouter(OpenstackRouter osRouter) {
     }
 
     @Override
     public void updateRouter(OpenstackRouter osRouter) {
         if (osRouter.gatewayExternalInfo().externalFixedIps().size() > 0) {
-            openstackService.ports().stream()
-                    .filter(osPort -> osPort.deviceOwner().equals(DEVICE_OWNER_ROUTER_INTERFACE) &&
-                            osPort.deviceId().equals(osRouter.id()))
-                    .forEach(osPort -> {
-                        String subnetId = osPort.fixedIps().keySet().stream().findFirst().get();
-                        setExternalConnection(osRouter, subnetId);
-                    });
+            routableSubNets(osRouter.id()).stream()
+                    .forEach(subnet -> setExternalConnection(osRouter, subnet, true));
 
             log.info("Connected external gateway {} to router {}",
                      osRouter.gatewayExternalInfo().externalFixedIps(),
                      osRouter.name());
         } else {
-            openstackService.ports().stream()
-                    .filter(osPort -> osPort.deviceOwner().equals(DEVICE_OWNER_ROUTER_INTERFACE) &&
-                            osPort.deviceId().equals(osRouter.id()))
-                    .forEach(osPort -> {
-                        String subnetId = osPort.fixedIps().keySet().stream().findFirst().get();
-                        OpenstackSubnet osSubNet = openstackService.subnet(subnetId);
-                        unsetExternalConnection(osRouter, osPort.networkId(), osSubNet.cidr());
-                    });
+            routableSubNets(osRouter.id()).stream()
+                    .forEach(subnet -> setExternalConnection(osRouter, subnet, false));
 
             log.info("Disconnected external gateway from router {}",
                      osRouter.name());
@@ -150,309 +169,163 @@
 
     @Override
     public void removeRouter(String osRouterId) {
-        // TODO implement this
+        // Nothing to do
+        // All interfaces need to be removed before the router is removed,
+        // and all related flow rues are removed when the interfaces are removed.
     }
 
     @Override
-    public void addRouterInterface(OpenstackRouterInterface routerIface) {
-        OpenstackRouter osRouter = openstackRouter(routerIface.id());
-        OpenstackPort osPort = openstackService.port(routerIface.portId());
-        if (osRouter == null || osPort == null) {
-            log.warn("Failed to add router interface {}", routerIface);
+    public void addRouterInterface(OpenstackRouterInterface routerIfaceAdded) {
+        OpenstackRouter osRouter = openstackRouter(routerIfaceAdded.id());
+        OpenstackSubnet osSubnetAdded = openstackService.subnet(routerIfaceAdded.subnetId());
+        if (osRouter == null || osSubnetAdded == null) {
+            log.warn("Failed to add router interface {}", routerIfaceAdded);
             return;
         }
-
-        setGatewayIcmp(Ip4Address.valueOf(openstackService.subnet(routerIface.subnetId()).gatewayIp()));
-
-        setRoutes(osRouter, Optional.empty());
-        if (osRouter.gatewayExternalInfo().externalFixedIps().size() > 0) {
-            String subnetId = osPort.fixedIps().keySet().stream().findFirst().get();
-            setExternalConnection(osRouter, subnetId);
-        }
-        log.info("Connected {} to router {}", osPort.fixedIps(), osRouter.name());
+        handleRouterInterfaces(osRouter, osSubnetAdded);
     }
 
     @Override
     public void removeRouterInterface(OpenstackRouterInterface routerIface) {
         OpenstackRouter osRouter = openstackService.router(routerIface.id());
+        OpenstackSubnet osSubnetRemoved = openstackService.subnet(routerIface.subnetId());
         if (osRouter == null) {
             log.warn("Failed to remove router interface {}", routerIface);
             return;
         }
+        handleRouterInterfacesRemoved(osRouter, osSubnetRemoved);
 
-        OpenstackSubnet osSubnet = openstackService.subnet(routerIface.subnetId());
-        OpenstackNetwork osNet = openstackService.network(osSubnet.networkId());
+        log.info("Disconnected {} from router {}", osSubnetRemoved.cidr(), osRouter.name());
+    }
 
-        unsetGatewayIcmp(Ip4Address.valueOf(openstackService.subnet(routerIface.subnetId()).gatewayIp()));
+    private void handleRouterInterfaces(OpenstackRouter osRouter, OpenstackSubnet osSubnetAdded) {
+        OpenstackNetwork osNetworkAdded = openstackService.network(osSubnetAdded.networkId());
+        if (osNetworkAdded == null) {  // in case of external network subnet
+            return;
+        }
 
-        unsetRoutes(osRouter, osSubnet);
+        // Sets flow rules for routing among subnets connected to a router.
+        setRoutesAmongSubnets(osRouter, osSubnetAdded, true);
 
+        // Sets flow rules for forwarding "packets going to external networks" to gateway nodes.
         if (osRouter.gatewayExternalInfo().externalFixedIps().size() > 0) {
-            unsetExternalConnection(osRouter, osNet.id(), osSubnet.cidr());
-        }
-        log.info("Disconnected {} from router {}", osSubnet.cidr(), osRouter.name());
-    }
-
-    private void setGatewayIcmp(Ip4Address gatewayIp) {
-        if (gatewayIp == null) {
-            return;
-        }
-        gatewayService.getGatewayDeviceIds().forEach(deviceId -> populateGatewayIcmpRule(gatewayIp, deviceId));
-    }
-
-    private void populateGatewayIcmpRule(Ip4Address gatewayIp, DeviceId deviceId) {
-        TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder();
-        TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
-
-        sBuilder.matchEthType(Ethernet.TYPE_IPV4)
-                .matchIPProtocol(IPv4.PROTOCOL_ICMP)
-                .matchIPDst(gatewayIp.toIpPrefix());
-
-        tBuilder.setOutput(PortNumber.CONTROLLER);
-
-        ForwardingObjective fo = DefaultForwardingObjective.builder()
-                .withSelector(sBuilder.build())
-                .withTreatment(tBuilder.build())
-                .withPriority(GATEWAY_ICMP_PRIORITY)
-                .withFlag(ForwardingObjective.Flag.VERSATILE)
-                .fromApp(appId)
-                .add();
-
-        flowObjectiveService.forward(deviceId, fo);
-    }
-
-    private void unsetGatewayIcmp(Ip4Address gatewayIp) {
-        if (gatewayIp == null) {
-            return;
-        }
-        gatewayService.getGatewayDeviceIds().forEach(deviceId -> {
-            removeGatewayIcmpRule(gatewayIp, deviceId);
-        });
-    }
-
-    private void removeGatewayIcmpRule(Ip4Address gatewayIp, DeviceId deviceId) {
-        TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder();
-
-        sBuilder.matchEthType(Ethernet.TYPE_IPV4)
-                .matchIPProtocol(IPv4.PROTOCOL_ICMP)
-                .matchIPDst(gatewayIp.toIpPrefix());
-
-        RulePopulatorUtil.removeRule(flowObjectiveService, appId, deviceId, sBuilder.build(),
-                ForwardingObjective.Flag.VERSATILE, GATEWAY_ICMP_PRIORITY);
-
-    }
-    private void setExternalConnection(OpenstackRouter osRouter, String osSubNetId) {
-        if (!osRouter.gatewayExternalInfo().isEnablePnat()) {
-            log.debug("Source NAT is disabled");
-            return;
+            setExternalConnection(osRouter, osSubnetAdded, true);
         }
 
-        OpenstackSubnet osSubNet = openstackService.subnet(osSubNetId);
-        OpenstackNetwork osNet = openstackService.network(osSubNet.networkId());
-        populateExternalRules(osNet, osSubNet);
+        // Sets flow rules to handle ping to the virtual gateway.
+        Ip4Address vGatewayIp = Ip4Address.valueOf(osSubnetAdded.gatewayIp());
+        gatewayService.getGatewayDeviceIds()
+                .forEach(deviceId -> setGatewayIcmpRule(vGatewayIp, deviceId, true));
+
+        // Sets east-west routing rules for VMs in different Cnode to Switching Table.
+        setForwardingRulesForEastWestRouting(osRouter, osSubnetAdded, true);
+
     }
 
-    private void unsetExternalConnection(OpenstackRouter osRouter, String osNetId, String subNetCidr) {
-        if (!osRouter.gatewayExternalInfo().isEnablePnat()) {
-            log.debug("Source NAT is disabled");
-            return;
+    private void handleRouterInterfacesRemoved(OpenstackRouter osRouter, OpenstackSubnet osSubnetRemoved) {
+
+        // Removes flow rules for routing among subnets connected to a router.
+        setRoutesAmongSubnets(osRouter, osSubnetRemoved, false);
+
+        // Removes flow rules for forwarding "packets going to external networks" to gateway nodes.
+        if (osRouter.gatewayExternalInfo().externalFixedIps().size() > 0) {
+            setExternalConnection(osRouter, osSubnetRemoved, false);
         }
 
-        // FIXME router interface is subnet specific, not network
-        OpenstackNetwork osNet = openstackService.network(osNetId);
-        removeExternalRules(osNet, subNetCidr);
+        // Removes flow rules to handle ping to the virtual gateway.
+        Ip4Address vGatewayIp = Ip4Address.valueOf(osSubnetRemoved.gatewayIp());
+        gatewayService.getGatewayDeviceIds()
+                .forEach(deviceId -> setGatewayIcmpRule(vGatewayIp, deviceId, false));
+
+        // Removes east-west routing rules for VMs in different Cnode to Switching Table.
+        setForwardingRulesForEastWestRouting(osRouter, osSubnetRemoved, false);
+
+        // Resets east-west routing rules for VMs in different Cnode to Switching Table.
+        routableSubNets(osRouter.id()).stream()
+                .forEach(subnet -> setForwardingRulesForEastWestRouting(osRouter, subnet, true));
     }
 
-    private void setRoutes(OpenstackRouter osRouter, Optional<Host> host) {
+    private void setRoutesAmongSubnets(OpenstackRouter osRouter, OpenstackSubnet osSubnetAdded, boolean install) {
         Set<OpenstackSubnet> routableSubNets = routableSubNets(osRouter.id());
         if (routableSubNets.size() < 2) {
             // no other subnet interface is connected to this router, do nothing
             return;
         }
 
-        Set<String> routableSubNetIds = routableSubNets.stream()
-                .map(OpenstackSubnet::id)
-                .collect(Collectors.toSet());
-
-        if (host.isPresent()) {
-            if (!routableSubNetIds.contains(host.get().annotations().value(SUBNET_ID))) {
-                // subnet of host is not connected to this router, do nothing.
-                return;
-            }
-        }
-
-        Set<Host> hosts = host.isPresent() ? ImmutableSet.of(host.get()) :
-                Tools.stream(hostService.getHosts())
-                        .filter(h -> routableSubNetIds.contains(h.annotations().value(SUBNET_ID)))
-                        .collect(Collectors.toSet());
-
-        hosts.forEach(h -> populateRoutingRules(h, routableSubNets));
-    }
-
-    private void unsetRoutes(OpenstackRouter osRouter, OpenstackSubnet osSubNet) {
-        Set<OpenstackSubnet> routableSubNets = routableSubNets(osRouter.id());
-        Tools.stream(hostService.getHosts())
-                .filter(h -> Objects.equals(
-                        h.annotations().value(NETWORK_ID), osSubNet.id()))
-                .forEach(h -> removeRoutingRules(h, routableSubNets));
-
-        routableSubNets.forEach(n -> {
-            Tools.stream(hostService.getHosts())
-                    .filter(h -> Objects.equals(
-                            h.annotations().value(SUBNET_ID),
-                            n.id()))
-                    .forEach(h -> removeRoutingRules(h, ImmutableSet.of(osSubNet)));
-            log.debug("Removed between {} to {}", n.name(), osSubNet.name());
-        });
-    }
-
-    private OpenstackRouter openstackRouter(String routerId) {
-        return openstackService.routers().stream().filter(r ->
-                r.id().equals(routerId)).iterator().next();
-    }
-
-    private Optional<OpenstackPort> routerIfacePort(String osNetId, String osSubNetId) {
-        // FIXME router interface is subnet specific, not network
-        return openstackService.ports().stream()
-                .filter(p -> p.deviceOwner().equals(DEVICE_OWNER_ROUTER_INTERFACE) &&
-                        p.networkId().equals(osNetId) &&
-                        p.fixedIps().containsKey(osSubNetId))
-                .findAny();
-    }
-
-    private Set<OpenstackSubnet> routableSubNets(String osRouterId) {
-        return openstackService.ports().stream()
-                .filter(p -> p.deviceOwner().equals(DEVICE_OWNER_ROUTER_INTERFACE) &&
-                        p.deviceId().equals(osRouterId))
-                .map(p -> openstackService.subnet(p.fixedIps().keySet().stream().findFirst().get()))
-                .collect(Collectors.toSet());
-    }
-
-    private void populateExternalRules(OpenstackNetwork osNet, OpenstackSubnet osSubNet) {
-        populateCnodeToGateway(Long.valueOf(osNet.segmentId()), osSubNet.cidr());
-        populateGatewayToController(Long.valueOf(osNet.segmentId()), osSubNet.cidr());
-    }
-
-    private void removeExternalRules(OpenstackNetwork osNet, String subNetCidr) {
-        TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder();
-        sBuilder.matchEthType(Ethernet.TYPE_IPV4)
-                .matchTunnelId(Long.valueOf(osNet.segmentId()))
-                .matchIPSrc(IpPrefix.valueOf(subNetCidr))
-                .matchEthDst(Constants.DEFAULT_GATEWAY_MAC);
-
-        nodeService.completeNodes().forEach(node -> {
-            ForwardingObjective.Flag flag = node.type().equals(GATEWAY) ?
-                    ForwardingObjective.Flag.VERSATILE :
-                    ForwardingObjective.Flag.SPECIFIC;
-
-            RulePopulatorUtil.removeRule(
-                    flowObjectiveService,
-                    appId,
-                    node.intBridge(),
-                    sBuilder.build(),
-                    flag,
-                    ROUTING_RULE_PRIORITY);
-        });
-    }
-
-    private void populateRoutingRules(Host host, Set<OpenstackSubnet> osSubNets) {
-        String osSubNetId = host.annotations().value(SUBNET_ID);
-        if (osSubNetId == null) {
-            return;
-        }
-
-        DeviceId localDevice = host.location().deviceId();
-        PortNumber localPort = host.location().port();
-        if (!nodeService.dataIp(localDevice).isPresent()) {
-            log.warn("Failed to populate L3 rules");
-            return;
-        }
-
         Map<String, String> vniMap = new HashMap<>();
         openstackService.networks().forEach(n -> vniMap.put(n.id(), n.segmentId()));
 
-        // TODO improve pipeline, do we have to install access rules between networks
-        // for every single VMs?
-        osSubNets.stream().filter(osSubNet -> !osSubNet.id().equals(osSubNetId)).forEach(osSubNet -> {
-            populateRoutingRulestoSameNode(
-                    host.ipAddresses().stream().findFirst().get().getIp4Address(),
-                    host.mac(),
-                    localPort, localDevice,
-                    Long.valueOf(vniMap.get(osSubNet.networkId())),
-                    osSubNet.cidr());
-
-            nodeService.completeNodes().stream()
-                    .filter(node -> node.type().equals(COMPUTE))
-                    .filter(node -> !node.intBridge().equals(localDevice))
-                    .forEach(node -> populateRoutingRulestoDifferentNode(
-                            host.ipAddresses().stream().findFirst().get().getIp4Address(),
-                            Long.valueOf(vniMap.get(osSubNet.networkId())),
-                            node.intBridge(),
-                            nodeService.dataIp(localDevice).get().getIp4Address(),
-                            osSubNet.cidr()));
-        });
+        routableSubNets.stream()
+                .filter(subnet -> !subnet.id().equals(osSubnetAdded.id()))
+                .filter(subnet -> vniMap.get(subnet.networkId()) != null)
+                .forEach(subnet -> nodeService.completeNodes().stream()
+                        .filter(node -> node.type().equals(COMPUTE))
+                        .forEach(node -> {
+                                setRoutingRules(node.intBridge(),
+                                        Integer.parseInt(vniMap.get(subnet.networkId())),
+                                        Integer.parseInt(vniMap.get(osSubnetAdded.networkId())),
+                                        subnet, osSubnetAdded, install);
+                                setRoutingRules(node.intBridge(),
+                                        Integer.parseInt(vniMap.get(osSubnetAdded.networkId())),
+                                        Integer.parseInt(vniMap.get(subnet.networkId())),
+                                        osSubnetAdded, subnet, install);
+                                }
+                        ));
     }
 
-    private void removeRoutingRules(Host host, Set<OpenstackSubnet> osSubNets) {
-        String osSubNetId = host.annotations().value(SUBNET_ID);
-        if (osSubNetId == null) {
-            return;
-        }
+    private void setRoutingRules(DeviceId deviceId, int srcVni, int dstVni,
+                                 OpenstackSubnet subnetSrc, OpenstackSubnet subnetDst, boolean install) {
 
-        Map<String, String> vniMap = new HashMap<>();
-        openstackService.networks().forEach(n -> vniMap.put(n.id(), n.segmentId()));
-
-        osSubNets.stream().filter(osSubNet -> !osSubNet.id().equals(osSubNetId)).forEach(osSubNet -> {
-            TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder();
-            sBuilder.matchEthType(Ethernet.TYPE_IPV4)
-                    .matchIPDst(host.ipAddresses().stream().findFirst().get().toIpPrefix())
-                    .matchIPSrc(IpPrefix.valueOf(osSubNet.cidr()))
-                    .matchTunnelId(Long.valueOf(vniMap.get(osSubNet.networkId())));
-
-            nodeService.completeNodes().stream()
-                    .filter(node -> node.type().equals(COMPUTE))
-                    .forEach(node -> RulePopulatorUtil.removeRule(
-                            flowObjectiveService,
-                            appId,
-                            node.intBridge(),
-                            sBuilder.build(),
-                            ForwardingObjective.Flag.SPECIFIC,
-                            EW_ROUTING_RULE_PRIORITY));
-        });
-        log.debug("Removed routing rule from {} to {}", host, osSubNets);
-    }
-
-    private void populateGatewayToController(long vni, String subNetCidr) {
         TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder();
         TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
 
         sBuilder.matchEthType(Ethernet.TYPE_IPV4)
-                .matchTunnelId(vni)
-                .matchIPSrc(IpPrefix.valueOf(subNetCidr))
-                .matchEthDst(Constants.DEFAULT_GATEWAY_MAC);
-        tBuilder.setOutput(PortNumber.CONTROLLER);
+                .matchTunnelId(srcVni)
+                .matchIPSrc(IpPrefix.valueOf(subnetSrc.cidr()))
+                .matchIPDst(IpPrefix.valueOf(subnetDst.cidr()));
 
-        ForwardingObjective fo = DefaultForwardingObjective.builder()
-                .withSelector(sBuilder.build())
-                .withTreatment(tBuilder.build())
-                .withFlag(ForwardingObjective.Flag.VERSATILE)
-                .withPriority(ROUTING_RULE_PRIORITY)
-                .fromApp(appId)
-                .add();
+        tBuilder.setTunnelId(dstVni);
 
-        gatewayService.getGatewayDeviceIds().forEach(deviceId -> flowObjectiveService.forward(deviceId, fo));
+        RulePopulatorUtil.setRule(flowObjectiveService, appId, deviceId, sBuilder.build(),
+                tBuilder.build(), ForwardingObjective.Flag.SPECIFIC, EW_ROUTING_RULE_PRIORITY, install);
+
+        // Flow rules for destination is in different subnet and different node,
+        // because VNI is converted to destination VNI in the source VM node.
+        sBuilder = DefaultTrafficSelector.builder();
+        tBuilder = DefaultTrafficTreatment.builder();
+
+        sBuilder.matchEthType(Ethernet.TYPE_IPV4)
+                .matchTunnelId(dstVni)
+                .matchIPSrc(IpPrefix.valueOf(subnetSrc.cidr()))
+                .matchIPDst(IpPrefix.valueOf(subnetDst.cidr()));
+
+        tBuilder.setTunnelId(dstVni);
+
+        RulePopulatorUtil.setRule(flowObjectiveService, appId, deviceId, sBuilder.build(),
+                tBuilder.build(), ForwardingObjective.Flag.SPECIFIC, EW_ROUTING_RULE_PRIORITY, install);
     }
 
-    private void populateCnodeToGateway(long vni, String subnetCidr) {
+    private void setExternalConnection(OpenstackRouter osRouter, OpenstackSubnet osSubNet, boolean install) {
+        if (!osRouter.gatewayExternalInfo().isEnablePnat()) {
+            log.debug("Source NAT is disabled");
+            return;
+        }
+
+        //OpenstackSubnet osSubNet = openstackService.subnet(osSubNetId);
+        OpenstackNetwork osNet = openstackService.network(osSubNet.networkId());
+
         nodeService.completeNodes().stream()
                 .filter(node -> node.type().equals(COMPUTE))
-                .forEach(node -> populateRuleToGateway(
+                .forEach(node -> setRulesToGateway(
                         node.intBridge(),
                         gatewayService.getGatewayGroupId(node.intBridge()),
-                        vni, subnetCidr));
+                        Long.valueOf(osNet.segmentId()), osSubNet.cidr(), install));
+
+        // Is this for PNAT ??
+        setRulesForGatewayToController(Long.valueOf(osNet.segmentId()), osSubNet.cidr(), install);
     }
 
-    private void populateRuleToGateway(DeviceId deviceId, GroupId groupId, long vni, String cidr) {
+    private void setRulesToGateway(DeviceId deviceId, GroupId groupId, long vni, String cidr, boolean install) {
         TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder();
         TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
 
@@ -462,133 +335,119 @@
                 .matchEthDst(Constants.DEFAULT_GATEWAY_MAC);
 
         tBuilder.group(groupId);
-        ForwardingObjective fo = DefaultForwardingObjective.builder()
-                .withSelector(sBuilder.build())
-                .withTreatment(tBuilder.build())
-                .withFlag(ForwardingObjective.Flag.SPECIFIC)
-                .withPriority(ROUTING_RULE_PRIORITY)
-                .fromApp(appId)
-                .add();
 
-        flowObjectiveService.forward(deviceId, fo);
+        RulePopulatorUtil.setRule(flowObjectiveService, appId, deviceId, sBuilder.build(),
+                tBuilder.build(), ForwardingObjective.Flag.SPECIFIC, ROUTING_RULE_PRIORITY, install);
     }
 
-    private void populateRoutingRulestoDifferentNode(Ip4Address vmIp, long vni,
-                                                     DeviceId deviceId, Ip4Address hostIp,
-                                                     String cidr) {
+    private void setRulesForGatewayToController(long vni, String subNetCidr, boolean install) {
         TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder();
         TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
 
         sBuilder.matchEthType(Ethernet.TYPE_IPV4)
                 .matchTunnelId(vni)
-                .matchIPSrc(IpPrefix.valueOf(cidr))
-                .matchIPDst(vmIp.toIpPrefix());
-        tBuilder.extension(buildExtension(deviceService, deviceId, hostIp), deviceId)
-                .setOutput(nodeService.tunnelPort(deviceId).get());
+                .matchIPSrc(IpPrefix.valueOf(subNetCidr))
+                .matchEthDst(Constants.DEFAULT_GATEWAY_MAC);
+        tBuilder.setOutput(PortNumber.CONTROLLER);
 
-        ForwardingObjective fo = DefaultForwardingObjective.builder()
-                .withSelector(sBuilder.build())
-                .withTreatment(tBuilder.build())
-                .withPriority(EW_ROUTING_RULE_PRIORITY)
-                .withFlag(ForwardingObjective.Flag.SPECIFIC)
-                .fromApp(appId)
-                .add();
-
-        flowObjectiveService.forward(deviceId, fo);
+        gatewayService.getGatewayDeviceIds().forEach(deviceId ->
+                RulePopulatorUtil.setRule(flowObjectiveService, appId, deviceId, sBuilder.build(),
+                        tBuilder.build(), ForwardingObjective.Flag.VERSATILE, ROUTING_RULE_PRIORITY, install));
     }
 
-    private void populateRoutingRulestoSameNode(Ip4Address vmIp, MacAddress vmMac,
-                                                PortNumber port, DeviceId deviceId, long vni,
-                                                String cidr) {
+    private void setGatewayIcmpRule(Ip4Address gatewayIp, DeviceId deviceId, boolean install) {
         TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder();
         TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
 
-        // FIXME: we need to check the VNI of the dest IP also just in case...
         sBuilder.matchEthType(Ethernet.TYPE_IPV4)
-                .matchIPDst(vmIp.toIpPrefix())
-                .matchIPSrc(IpPrefix.valueOf(cidr))
-                .matchTunnelId(vni);
+                .matchIPProtocol(IPv4.PROTOCOL_ICMP)
+                .matchIPDst(gatewayIp.toIpPrefix());
 
-        tBuilder.setEthDst(vmMac)
-                .setOutput(port);
+        tBuilder.setOutput(PortNumber.CONTROLLER);
 
-        ForwardingObjective fo = DefaultForwardingObjective.builder()
-                .withSelector(sBuilder.build())
-                .withTreatment(tBuilder.build())
-                .withPriority(EW_ROUTING_RULE_PRIORITY)
-                .withFlag(ForwardingObjective.Flag.SPECIFIC)
-                .fromApp(appId)
-                .add();
-
-        flowObjectiveService.forward(deviceId, fo);
+        RulePopulatorUtil.setRule(flowObjectiveService, appId, deviceId, sBuilder.build(),
+                tBuilder.build(), ForwardingObjective.Flag.VERSATILE, GATEWAY_ICMP_PRIORITY, install);
     }
 
-    private void reloadRoutingRules() {
-        eventExecutor.execute(() -> openstackService.ports().stream()
-                .filter(osPort -> osPort.deviceOwner().equals(DEVICE_OWNER_ROUTER_INTERFACE))
-                .forEach(osPort -> {
-                    OpenstackRouter osRouter = openstackRouter(osPort.deviceId());
+    private void setForwardingRulesForEastWestRouting(OpenstackRouter router, OpenstackSubnet subnetAdded,
+                                                      boolean install) {
 
-                    setGatewayIcmp(Ip4Address.valueOf(openstackService
-                            .subnet(osPort.fixedIps().keySet().stream().findAny().get()).gatewayIp()));
+        Set<OpenstackSubnet> subnets = routableSubNets(router.id());
 
-                    setRoutes(osRouter, Optional.empty());
-                    if (osRouter.gatewayExternalInfo().externalFixedIps().size() > 0) {
-                        String subnetId = osPort.fixedIps().keySet().stream().findFirst().get();
-                        setExternalConnection(osRouter, subnetId);
+        Set<Host> hosts = Tools.stream(hostService.getHosts())
+                .filter(h -> getVni(h).equals(openstackService.network(subnetAdded.networkId()).segmentId()))
+                .collect(Collectors.toSet());
+
+        subnets.stream()
+                .filter(subnet -> !subnet.id().equals(subnetAdded.id()))
+                .forEach(subnet -> getHosts(subnet)
+                        .forEach(h -> setForwardingRulesAmongHostsInDifferentCnodes(h, hosts, install)));
+    }
+
+    private void setForwardingRulesAmongHostsInDifferentCnodes(Host host, Set<Host> remoteHosts, boolean install) {
+        Ip4Address localVmIp = getIp(host);
+        DeviceId localDeviceId = host.location().deviceId();
+        Optional<IpAddress> localDataIp = nodeService.dataIp(localDeviceId);
+
+        if (!localDataIp.isPresent()) {
+            log.debug("Failed to get data IP for device {}",
+                    host.location().deviceId());
+            return;
+        }
+
+        remoteHosts.stream()
+                .filter(remoteHost -> !host.location().deviceId().equals(remoteHost.location().deviceId()))
+                .forEach(remoteVm -> {
+                    Optional<IpAddress> remoteDataIp = nodeService.dataIp(remoteVm.location().deviceId());
+                    if (remoteDataIp.isPresent()) {
+                        setVxLanFlowRule(getVni(remoteVm),
+                                localDeviceId,
+                                remoteDataIp.get().getIp4Address(),
+                                getIp(remoteVm), install);
+
+                        setVxLanFlowRule(getVni(host),
+                                remoteVm.location().deviceId(),
+                                localDataIp.get().getIp4Address(),
+                                localVmIp, install);
                     }
-                }));
+                });
     }
 
-    @Override
-    protected void hostDetected(Host host) {
-        String osNetId = host.annotations().value(NETWORK_ID);
-        String osSubNetId = host.annotations().value(SUBNET_ID);
-        Optional<OpenstackPort> routerIface = routerIfacePort(osNetId, osSubNetId);
-        if (!routerIface.isPresent()) {
+    private void setVxLanFlowRule(String vni, DeviceId deviceId, Ip4Address remoteIp,
+                                  Ip4Address vmIp, boolean install) {
+        Optional<PortNumber> tunnelPort = nodeService.tunnelPort(deviceId);
+        if (!tunnelPort.isPresent()) {
+            log.warn("Failed to get tunnel port from {}", deviceId);
             return;
         }
-        eventExecutor.execute(() -> setRoutes(
-                openstackRouter(routerIface.get().deviceId()),
-                Optional.of(host)));
+
+        TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder();
+        TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
+
+        sBuilder.matchEthType(Ethernet.TYPE_IPV4)
+                .matchTunnelId(Long.parseLong(vni))
+                .matchIPDst(vmIp.toIpPrefix());
+        tBuilder.extension(buildExtension(deviceService, deviceId, remoteIp), deviceId)
+                .setOutput(tunnelPort.get());
+
+        RulePopulatorUtil.setRule(flowObjectiveService, appId, deviceId, sBuilder.build(),
+                tBuilder.build(), ForwardingObjective.Flag.SPECIFIC, SWITCHING_RULE_PRIORITY, install);
     }
 
-    @Override
-    protected void hostRemoved(Host host) {
-        String osNetId = host.annotations().value(NETWORK_ID);
-        String osSubNetId = host.annotations().value(SUBNET_ID);
-        Optional<OpenstackPort> routerIface = routerIfacePort(osNetId, osSubNetId);
-        if (!routerIface.isPresent()) {
-            return;
-        }
-        Set<OpenstackSubnet> routableSubNets = routableSubNets(routerIface.get().deviceId());
-        eventExecutor.execute(() -> removeRoutingRules(host, routableSubNets));
+
+    private OpenstackRouter openstackRouter(String routerId) {
+        return openstackService.routers().stream().filter(r ->
+                r.id().equals(routerId)).iterator().next();
     }
 
     @Override
     public void reinstallVmFlow(Host host) {
-        if (host == null) {
-            hostService.getHosts().forEach(h -> {
-                hostDetected(h);
-                log.info("Re-Install data plane flow of virtual machine {}", h);
-            });
-        } else {
-            hostDetected(host);
-            log.info("Re-Install data plane flow of virtual machine {}", host);
-        }
+        // TODO: implements later
     }
 
     @Override
     public void purgeVmFlow(Host host) {
-        if (host == null) {
-            hostService.getHosts().forEach(h -> {
-                hostRemoved(h);
-                log.info("Purge data plane flow of virtual machine {}", h);
-            });
-        } else {
-            hostRemoved(host);
-            log.info("Purge data plane flow of virtual machine {}", host);
-        }
+        // TODO: implements later
     }
 
     private class InternalNodeListener implements OpenstackNodeListener {
@@ -599,6 +458,7 @@
 
             switch (event.type()) {
                 case COMPLETE:
+                case INCOMPLETE:
                     log.info("COMPLETE node {} detected", node.hostname());
                     eventExecutor.execute(() -> {
                         if (node.type() == GATEWAY) {
@@ -609,23 +469,13 @@
                                     .build();
                             gatewayService.addGatewayNode(gnode);
                         }
-                        reloadRoutingRules();
                     });
+                    openstackService.routers().stream()
+                            .forEach(router -> routableSubNets(router.id()).stream()
+                                        .forEach(subnet -> handleRouterInterfaces(router, subnet)));
                     break;
                 case INIT:
                 case DEVICE_CREATED:
-                case INCOMPLETE:
-                    eventExecutor.execute(() -> {
-                        if (node.type() == GATEWAY) {
-                            GatewayNode gnode = GatewayNode.builder()
-                                    .gatewayDeviceId(node.intBridge())
-                                    .dataIpAddress(node.dataIp().getIp4Address())
-                                    .uplinkIntf(node.externalPortName().get())
-                                    .build();
-                            gatewayService.deleteGatewayNode(gnode);
-                        }
-                        reloadRoutingRules();
-                    });
                 default:
                     break;
             }
diff --git a/apps/openstacknetworking/switching/src/main/java/org/onosproject/openstacknetworking/switching/OpenstackSwitchingManager.java b/apps/openstacknetworking/switching/src/main/java/org/onosproject/openstacknetworking/switching/OpenstackSwitchingManager.java
index db324d7..b66ffa2 100644
--- a/apps/openstacknetworking/switching/src/main/java/org/onosproject/openstacknetworking/switching/OpenstackSwitchingManager.java
+++ b/apps/openstacknetworking/switching/src/main/java/org/onosproject/openstacknetworking/switching/OpenstackSwitchingManager.java
@@ -119,7 +119,11 @@
                 .matchIPDst(getIp(host).toIpPrefix())
                 .matchTunnelId(Long.valueOf(getVni(host)));
 
-        tBuilder.setOutput(host.location().port());
+        // Destination setting is required for routing cases.
+        // We do not believe the rule would not degrade the forwarding performance.
+        // But, if it does, we need to move the rule in a separate routing table.
+        tBuilder.setEthDst(host.mac())
+                .setOutput(host.location().port());
 
         ForwardingObjective fo = DefaultForwardingObjective.builder()
                 .withSelector(sBuilder.build())
diff --git a/drivers/default/src/main/java/org/onosproject/driver/pipeline/OpenstackPipeline.java b/drivers/default/src/main/java/org/onosproject/driver/pipeline/OpenstackPipeline.java
index 038b949..91e5b12 100644
--- a/drivers/default/src/main/java/org/onosproject/driver/pipeline/OpenstackPipeline.java
+++ b/drivers/default/src/main/java/org/onosproject/driver/pipeline/OpenstackPipeline.java
@@ -17,6 +17,7 @@
 
 import org.onlab.osgi.ServiceDirectory;
 import org.onlab.packet.Ethernet;
+import org.onlab.packet.MacAddress;
 import org.onosproject.core.ApplicationId;
 import org.onosproject.core.CoreService;
 import org.onosproject.net.DeviceId;
@@ -33,7 +34,11 @@
 import org.onosproject.net.flow.TrafficTreatment;
 import org.onosproject.net.flow.criteria.Criterion;
 import org.onosproject.net.flow.criteria.EthTypeCriterion;
+import org.onosproject.net.flow.criteria.IPCriterion;
+import org.onosproject.net.flow.criteria.PortCriterion;
+import org.onosproject.net.flow.criteria.TunnelIdCriterion;
 import org.onosproject.net.flow.criteria.UdpPortCriterion;
+import org.onosproject.net.flow.instructions.Instruction;
 import org.onosproject.net.flowobjective.FilteringObjective;
 import org.onosproject.net.flowobjective.FlowObjectiveStore;
 import org.onosproject.net.flowobjective.ForwardingObjective;
@@ -42,9 +47,7 @@
 import org.onosproject.net.flowobjective.ObjectiveError;
 import org.slf4j.Logger;
 
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Objects;
+import java.util.Optional;
 
 import static org.slf4j.LoggerFactory.getLogger;
 
@@ -62,14 +65,20 @@
     protected ApplicationId appId;
     protected FlowRuleService flowRuleService;
 
-    protected static final int VNI_TABLE = 0;
-    protected static final int FORWARDING_TABLE = 1;
-    protected static final int ACL_TABLE = 2;
+    protected static final int SRC_VNI_TABLE = 0;
+    protected static final int ACL_TABLE = 1;
+    protected static final int CT_TABLE = 2;
+    protected static final int JUMP_TABLE = 3;
+    protected static final int ROUTING_TABLE = 4;
+    protected static final int FORWARDING_TABLE = 5;
+    protected static final int DUMMY_TABLE = 10;
+    protected static final int LAST_TABLE = FORWARDING_TABLE;
 
     private static final int DROP_PRIORITY = 0;
+    private static final int HIGH_PRIORITY = 30000;
     private static final int TIME_OUT = 0;
     private static final int DHCP_SERVER_PORT = 67;
-    private static final int DHCP_CLIENT_PORT = 68;
+    private static final String VIRTUAL_GATEWAY_MAC = "fe:00:00:00:00:02";
 
 
     @Override
@@ -100,102 +109,110 @@
 
     @Override
     public void forward(ForwardingObjective forwardingObjective) {
-        Collection<FlowRule> rules;
-        FlowRuleOperations.Builder flowOpsBuilder = FlowRuleOperations.builder();
+        FlowRule flowRule;
 
-        rules = processForward(forwardingObjective);
-
-        switch (forwardingObjective.op()) {
-            case ADD:
-                rules.stream()
-                        .filter(Objects::nonNull)
-                        .forEach(flowOpsBuilder::add);
+        switch (forwardingObjective.flag()) {
+            case SPECIFIC:
+                flowRule = processSpecific(forwardingObjective);
                 break;
-            case REMOVE:
-                rules.stream()
-                        .filter(Objects::nonNull)
-                        .forEach(flowOpsBuilder::remove);
+            case VERSATILE:
+                flowRule = processVersatile(forwardingObjective);
                 break;
             default:
                 fail(forwardingObjective, ObjectiveError.UNKNOWN);
-                log.warn("Unknown forwarding type {}");
+                log.warn("Unknown forwarding flag {}", forwardingObjective.flag());
+                return;
         }
 
-        flowRuleService.apply(flowOpsBuilder.build(new FlowRuleOperationsContext() {
-            @Override
-            public void onSuccess(FlowRuleOperations ops) {
-                pass(forwardingObjective);
-            }
+        if (forwardingObjective.op().equals(Objective.Operation.ADD)) {
+            applyRules(true, flowRule);
+        } else {
+            applyRules(false, flowRule);
+        }
 
-            @Override
-            public void onError(FlowRuleOperations ops) {
-                fail(forwardingObjective, ObjectiveError.FLOWINSTALLATIONFAILED);
-            }
-        }));
     }
 
     private void initializePipeline() {
-        processVniTable(true);
-        processForwardingTable(true);
-        processAclTable(true);
+        connectTables(SRC_VNI_TABLE, ACL_TABLE); // Table 0 -> Table 1
+        //FIXME CT table needs to be reconstructed using OVS 2.5 connection tracking feature.
+        connectTables(CT_TABLE, JUMP_TABLE);  // Table 2 -> Table 3
+        setUpTableMissEntry(ACL_TABLE);
+        setupJumpTable();
     }
 
-    private void processVniTable(boolean install) {
+    private void connectTables(int fromTable, int toTable) {
         TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
         TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
 
+        treatment.transition(toTable);
+
+        FlowRule flowRule = DefaultFlowRule.builder()
+                .forDevice(deviceId)
+                .withSelector(selector.build())
+                .withTreatment(treatment.build())
+                .withPriority(DROP_PRIORITY)
+                .fromApp(appId)
+                .makePermanent()
+                .forTable(fromTable)
+                .build();
+
+        applyRules(true, flowRule);
+    }
+
+    private void setUpTableMissEntry(int table) {
+        TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
+        TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
+
+        treatment.drop();
+
+        FlowRule flowRule = DefaultFlowRule.builder()
+                .forDevice(deviceId)
+                .withSelector(selector.build())
+                .withTreatment(treatment.build())
+                .withPriority(DROP_PRIORITY)
+                .fromApp(appId)
+                .makePermanent()
+                .forTable(table)
+                .build();
+
+        applyRules(true, flowRule);
+    }
+
+    private void setupJumpTable() {
+        TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
+        TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
+
+        selector.matchEthDst(MacAddress.valueOf(VIRTUAL_GATEWAY_MAC));
+        treatment.transition(ROUTING_TABLE);
+
+        FlowRule flowRule = DefaultFlowRule.builder()
+                .forDevice(deviceId)
+                .withSelector(selector.build())
+                .withTreatment(treatment.build())
+                .withPriority(HIGH_PRIORITY)
+                .fromApp(appId)
+                .makePermanent()
+                .forTable(JUMP_TABLE)
+                .build();
+
+        applyRules(true, flowRule);
+
+        selector = DefaultTrafficSelector.builder();
+        treatment = DefaultTrafficTreatment.builder();
+
         treatment.transition(FORWARDING_TABLE);
 
-        FlowRule flowRule = DefaultFlowRule.builder()
+        flowRule = DefaultFlowRule.builder()
                 .forDevice(deviceId)
                 .withSelector(selector.build())
                 .withTreatment(treatment.build())
                 .withPriority(DROP_PRIORITY)
                 .fromApp(appId)
                 .makePermanent()
-                .forTable(VNI_TABLE)
+                .forTable(JUMP_TABLE)
                 .build();
 
-        applyRules(install, flowRule);
-    }
-
-    private void processForwardingTable(boolean install) {
-        TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
-        TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
-
-        treatment.drop();
-
-        FlowRule flowRule = DefaultFlowRule.builder()
-                .forDevice(deviceId)
-                .withSelector(selector.build())
-                .withTreatment(treatment.build())
-                .withPriority(DROP_PRIORITY)
-                .fromApp(appId)
-                .makePermanent()
-                .forTable(FORWARDING_TABLE)
-                .build();
-
-        applyRules(install, flowRule);
-    }
-
-    private void processAclTable(boolean install) {
-        TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
-        TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
-
-        treatment.wipeDeferred();
-        treatment.drop();
-
-        FlowRule flowRule = DefaultFlowRule.builder()
-                .forDevice(deviceId)
-                .withSelector(selector.build())
-                .withTreatment(treatment.build())
-                .withPriority(DROP_PRIORITY)
-                .fromApp(appId)
-                .makePermanent()
-                .forTable(ACL_TABLE)
-                .build();
-
-        applyRules(install, flowRule);
+        applyRules(true, flowRule);
     }
 
     private void applyRules(boolean install, FlowRule flowRule) {
@@ -216,20 +233,7 @@
         }));
     }
 
-    private Collection<FlowRule> processForward(ForwardingObjective forwardingObjective) {
-        switch (forwardingObjective.flag()) {
-            case SPECIFIC:
-                return processSpecific(forwardingObjective);
-            case VERSATILE:
-                return processVersatile(forwardingObjective);
-            default:
-                fail(forwardingObjective, ObjectiveError.UNKNOWN);
-                log.warn("Unknown forwarding flag {}", forwardingObjective.flag());
-        }
-        return Collections.emptySet();
-    }
-
-    private Collection<FlowRule> processVersatile(ForwardingObjective forwardingObjective) {
+    private FlowRule processVersatile(ForwardingObjective forwardingObjective) {
         log.debug("Processing versatile forwarding objective");
 
         FlowRule.Builder ruleBuilder = DefaultFlowRule.builder()
@@ -253,25 +257,39 @@
         if (ethCriterion != null) {
             if (ethCriterion.ethType().toShort() == Ethernet.TYPE_ARP ||
                     ethCriterion.ethType().toShort() == Ethernet.TYPE_LLDP) {
-                ruleBuilder.forTable(VNI_TABLE);
-                return Collections.singletonList(ruleBuilder.build());
+                ruleBuilder.forTable(SRC_VNI_TABLE);
+                return ruleBuilder.build();
             } else if (udpPortCriterion != null && udpPortCriterion.udpPort().toInt() == DHCP_SERVER_PORT) {
-                ruleBuilder.forTable(VNI_TABLE);
-                return Collections.singletonList(ruleBuilder.build());
+                ruleBuilder.forTable(SRC_VNI_TABLE);
+                return ruleBuilder.build();
             }
         }
-        return Collections.emptySet();
+
+        return null;
     }
 
-    private Collection<FlowRule> processSpecific(ForwardingObjective forwardingObjective) {
+    private FlowRule processSpecific(ForwardingObjective forwardingObjective) {
         log.debug("Processing specific forwarding objective");
 
+        TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
+
+
+        Optional<Instruction> group = forwardingObjective.treatment().immediate().stream()
+                .filter(i -> i.type() == Instruction.Type.GROUP).findAny();
+        int tableType = tableType(forwardingObjective);
+        if (tableType != LAST_TABLE && !group.isPresent()) {
+            treatment.transition(nextTable(tableType));
+        }
+        forwardingObjective.treatment().allInstructions().stream()
+                .filter(i -> i.type() != Instruction.Type.NOACTION).forEach(treatment::add);
+
         FlowRule.Builder ruleBuilder = DefaultFlowRule.builder()
                 .forDevice(deviceId)
                 .withSelector(forwardingObjective.selector())
-                .withTreatment(forwardingObjective.treatment())
+                .withTreatment(treatment.build())
                 .withPriority(forwardingObjective.priority())
-                .fromApp(forwardingObjective.appId());
+                .fromApp(forwardingObjective.appId())
+                .forTable(tableType);
 
         if (forwardingObjective.permanent()) {
             ruleBuilder.makePermanent();
@@ -279,30 +297,41 @@
             ruleBuilder.makeTemporary(TIME_OUT);
         }
 
-        //VNI Table Rule
-        if (forwardingObjective.selector().getCriterion(Criterion.Type.IN_PORT) != null) {
-            TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
-            forwardingObjective.treatment().allInstructions().forEach(tBuilder::add);
-            tBuilder.transition(FORWARDING_TABLE);
-            ruleBuilder.withTreatment(tBuilder.build());
-            ruleBuilder.forTable(VNI_TABLE);
-        } else if (forwardingObjective.selector().getCriterion(Criterion.Type.TUNNEL_ID) != null) {
-            TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
-            tBuilder.deferred();
-            forwardingObjective.treatment().allInstructions().forEach(tBuilder::add);
-            tBuilder.transition(ACL_TABLE);
-            ruleBuilder.withTreatment(tBuilder.build());
-            ruleBuilder.forTable(FORWARDING_TABLE);
-        } else {
-            ruleBuilder.forTable(ACL_TABLE);
-        }
-
-        return Collections.singletonList(ruleBuilder.build());
+        return ruleBuilder.build();
     }
 
+    int tableType(ForwardingObjective fo) {
 
-    private void pass(Objective obj) {
-        obj.context().ifPresent(context -> context.onSuccess(obj));
+        IPCriterion ipSrc = (IPCriterion) fo.selector().getCriterion(Criterion.Type.IPV4_SRC);
+        IPCriterion ipDst = (IPCriterion) fo.selector().getCriterion(Criterion.Type.IPV4_DST);
+        TunnelIdCriterion tunnelId =
+                (TunnelIdCriterion) fo.selector().getCriterion(Criterion.Type.TUNNEL_ID);
+        PortCriterion inPort = (PortCriterion) fo.selector().getCriterion(Criterion.Type.IN_PORT);
+        Optional<Instruction> output = fo.treatment().immediate().stream()
+                .filter(i -> i.type() == Instruction.Type.OUTPUT).findAny();
+        Optional<Instruction> group = fo.treatment().immediate().stream()
+                .filter(i -> i.type() == Instruction.Type.GROUP).findAny();
+
+        // TODO: Add the Connection Tracking Table
+        if (inPort != null) {
+            return SRC_VNI_TABLE;
+        } else if (output.isPresent()) {
+            return FORWARDING_TABLE;
+        } else if ((ipSrc != null && ipSrc.ip().prefixLength() == 32 &&
+                ipDst != null && ipDst.ip().prefixLength() == 32) ||
+                (ipSrc != null && ipSrc.ip().prefixLength() == 32 && ipDst == null) ||
+                (ipDst != null && ipDst.ip().prefixLength() == 32 && ipSrc == null)) {
+            return ACL_TABLE;
+        } else if ((tunnelId != null && ipSrc != null && ipDst != null) || group.isPresent()) {
+            return ROUTING_TABLE;
+        }
+
+        return DUMMY_TABLE;
+    }
+
+    int nextTable(int baseTable) {
+
+        return baseTable + 1;
     }
 
     private void fail(Objective obj, ObjectiveError error) {
