Refactor: resolve code smells of openstacknetworking impl pkgs #1

Change-Id: Iea25b4793067d9555ab1075dbeab9cf81e841b6e
diff --git a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingArpHandler.java b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingArpHandler.java
index be7616b..a373ab3 100644
--- a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingArpHandler.java
+++ b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingArpHandler.java
@@ -82,6 +82,7 @@
 import java.util.concurrent.ExecutorService;
 import java.util.stream.Collectors;
 
+import static java.util.Objects.requireNonNull;
 import static java.util.concurrent.Executors.newSingleThreadExecutor;
 import static org.onlab.util.Tools.groupedThreads;
 import static org.onosproject.openstacknetworking.api.Constants.ARP_BROADCAST_MODE;
@@ -208,7 +209,7 @@
     }
 
     @Modified
-    void modified(ComponentContext context) {
+    protected void modified(ComponentContext context) {
         log.info("Modified");
     }
 
@@ -406,7 +407,7 @@
                         }
                     });
                     finalGws.remove(gateway);
-                    if (completedGws.size() >= 1) {
+                    if (!completedGws.isEmpty()) {
                         osRouterAdminService.floatingIps().forEach(fip -> {
                             if (fip.getPortId() != null) {
                                 setFloatingIpArpRule(fip, fip.getPortId(),
@@ -487,11 +488,14 @@
             if (install) {
                 preCommitPortService.subscribePreCommit(instPort.portId(),
                         OPENSTACK_PORT_PRE_REMOVE, this.getClass().getName());
-                log.info("Subscribed the port {} on listening pre-remove event", instPort.portId());
+                log.info("Subscribed the port {} on listening pre-remove event",
+                                                                instPort.portId());
             } else {
                 preCommitPortService.unsubscribePreCommit(instPort.portId(),
-                        OPENSTACK_PORT_PRE_REMOVE, instancePortService, this.getClass().getName());
-                log.info("Unsubscribed the port {} on listening pre-remove event", instPort.portId());
+                        OPENSTACK_PORT_PRE_REMOVE, instancePortService,
+                                                        this.getClass().getName());
+                log.info("Unsubscribed the port {} on listening pre-remove event",
+                                                                instPort.portId());
             }
 
             setArpRule(fip, targetMac, gw, install);
@@ -607,24 +611,10 @@
             switch (event.type()) {
                 case OPENSTACK_PORT_CREATED:
                 case OPENSTACK_PORT_UPDATED:
-                    eventExecutor.execute(() -> {
-
-                        if (!isRelevantHelper() || ipAddress == null) {
-                            return;
-                        }
-
-                        setFakeGatewayArpRuleByExternalIp(ipAddress, true);
-                    });
+                    eventExecutor.execute(() -> processPortCreation(ipAddress));
                     break;
                 case OPENSTACK_PORT_REMOVED:
-                    eventExecutor.execute(() -> {
-
-                        if (!isRelevantHelper() || ipAddress == null) {
-                            return;
-                        }
-
-                        setFakeGatewayArpRuleByExternalIp(ipAddress, false);
-                    });
+                    eventExecutor.execute(() -> processPortRemoval(ipAddress));
                     break;
                 default:
                     // do nothing
@@ -632,6 +622,22 @@
             }
         }
 
+        private void processPortCreation(IpAddress ipAddress) {
+            if (!isRelevantHelper() || ipAddress == null) {
+                return;
+            }
+
+            setFakeGatewayArpRuleByExternalIp(ipAddress, true);
+        }
+
+        private void processPortRemoval(IpAddress ipAddress) {
+            if (!isRelevantHelper() || ipAddress == null) {
+                return;
+            }
+
+            setFakeGatewayArpRuleByExternalIp(ipAddress, false);
+        }
+
         private IpAddress externalIp(Port port) {
             IP ip = port.getFixedIps().stream().findAny().orElse(null);
 
@@ -655,74 +661,32 @@
 
         @Override
         public void event(OpenstackRouterEvent event) {
-
-            Set<OpenstackNode> completedGws = osNodeService.completeNodes(GATEWAY);
-
             switch (event.type()) {
                 case OPENSTACK_ROUTER_CREATED:
                     // add a router with external gateway
                 case OPENSTACK_ROUTER_GATEWAY_ADDED:
                     // add a gateway manually after adding a router
-                    eventExecutor.execute(() -> {
-
-                        if (!isRelevantHelper()) {
-                            return;
-                        }
-
-                        // add a router with external gateway
-                        setFakeGatewayArpRuleByRouter(event.subject(), true);
-                    });
+                    eventExecutor.execute(() -> processRouterGwCreation(event));
                     break;
                 case OPENSTACK_ROUTER_REMOVED:
                     // remove a router with external gateway
                 case OPENSTACK_ROUTER_GATEWAY_REMOVED:
                     // remove a gateway from an existing router
-                    eventExecutor.execute(() -> {
-
-                        if (!isRelevantHelper()) {
-                            return;
-                        }
-
-                        setFakeGatewayArpRuleByRouter(event.subject(), false);
-                    });
+                    eventExecutor.execute(() -> processRouterGwRemoval(event));
                     break;
                 case OPENSTACK_FLOATING_IP_CREATED:
                     // during floating IP creation, if the floating IP is
                     // associated with any port of VM, then we will set
                     // floating IP related ARP rules to gateway node
                 case OPENSTACK_FLOATING_IP_ASSOCIATED:
-                    eventExecutor.execute(() -> {
-
-                        if (!isRelevantHelper()) {
-                            return;
-                        }
-
-                        if (getValidPortId(event) == null) {
-                            return;
-                        }
-                        // associate a floating IP with an existing VM
-                        setFloatingIpArpRule(event.floatingIp(),
-                                getValidPortId(event), completedGws, true);
-                    });
+                    eventExecutor.execute(() -> processFloatingIpCreation(event));
                     break;
                 case OPENSTACK_FLOATING_IP_REMOVED:
                     // during floating IP deletion, if the floating IP is
                     // still associated with any port of VM, then we will
                     // remove floating IP related ARP rules from gateway node
                 case OPENSTACK_FLOATING_IP_DISASSOCIATED:
-                    eventExecutor.execute(() -> {
-
-                        if (!isRelevantHelper()) {
-                            return;
-                        }
-
-                        if (getValidPortId(event) == null) {
-                            return;
-                        }
-                        // disassociate a floating IP with an existing VM
-                        setFloatingIpArpRule(event.floatingIp(),
-                                getValidPortId(event), completedGws, false);
-                    });
+                    eventExecutor.execute(() -> processFloatingIpRemoval(event));
                     break;
                 default:
                     // do nothing for the other events
@@ -730,6 +694,55 @@
             }
         }
 
+        private void processRouterGwCreation(OpenstackRouterEvent event) {
+            if (!isRelevantHelper()) {
+                return;
+            }
+
+            // add a router with external gateway
+            setFakeGatewayArpRuleByRouter(event.subject(), true);
+        }
+
+        private void processRouterGwRemoval(OpenstackRouterEvent event) {
+            if (!isRelevantHelper()) {
+                return;
+            }
+
+            setFakeGatewayArpRuleByRouter(event.subject(), false);
+        }
+
+        private void processFloatingIpCreation(OpenstackRouterEvent event) {
+            if (!isRelevantHelper()) {
+                return;
+            }
+
+            if (getValidPortId(event) == null) {
+                return;
+            }
+
+            Set<OpenstackNode> completedGws = osNodeService.completeNodes(GATEWAY);
+
+            // associate a floating IP with an existing VM
+            setFloatingIpArpRule(event.floatingIp(),
+                    getValidPortId(event), completedGws, true);
+        }
+
+        private void processFloatingIpRemoval(OpenstackRouterEvent event) {
+            if (!isRelevantHelper()) {
+                return;
+            }
+
+            if (getValidPortId(event) == null) {
+                return;
+            }
+
+            Set<OpenstackNode> completedGws = osNodeService.completeNodes(GATEWAY);
+
+            // disassociate a floating IP with an existing VM
+            setFloatingIpArpRule(event.floatingIp(),
+                    getValidPortId(event), completedGws, false);
+        }
+
         private String getValidPortId(OpenstackRouterEvent event) {
             NetFloatingIP osFip = event.floatingIp();
             String portId = osFip.getPortId();
@@ -755,83 +768,91 @@
         @Override
         public void event(InstancePortEvent event) {
             InstancePort instPort = event.subject();
-
             switch (event.type()) {
                 case OPENSTACK_INSTANCE_PORT_DETECTED:
-                    eventExecutor.execute(() -> {
-
-                        if (!isRelevantHelper()) {
-                            return;
-                        }
-
-                        osRouterAdminService.floatingIps().stream()
-                                .filter(f -> f.getPortId() != null)
-                                .filter(f -> f.getPortId().equals(instPort.portId()))
-                                .forEach(f -> setFloatingIpArpRule(f, instPort.portId(),
-                                        osNodeService.completeNodes(GATEWAY), true));
-                    });
+                    eventExecutor.execute(() ->
+                                processInstanceDetection(event, instPort));
 
                     break;
                 case OPENSTACK_INSTANCE_MIGRATION_STARTED:
-                    eventExecutor.execute(() -> {
-
-                        if (!isRelevantHelper()) {
-                            return;
-                        }
-
-                        NetFloatingIP fip = associatedFloatingIp(instPort,
-                                            osRouterAdminService.floatingIps());
-
-                        if (osNodeService.completeNodes(GATEWAY).size() == 1) {
-                            return;
-                        }
-
-                        if (fip != null && isAssociatedWithVM(osNetworkService, fip)) {
-                            setFloatingIpArpRuleWithPortEvent(fip, event.subject(),
-                                    osNodeService.completeNodes(GATEWAY), true);
-                        }
-                    });
+                    eventExecutor.execute(() ->
+                                processInstanceMigrationStart(event, instPort));
 
                     break;
                 case OPENSTACK_INSTANCE_MIGRATION_ENDED:
-                    eventExecutor.execute(() -> {
-
-                        if (!isRelevantHelper()) {
-                            return;
-                        }
-
-                        NetFloatingIP fip = associatedFloatingIp(instPort,
-                                            osRouterAdminService.floatingIps());
-                        Set<OpenstackNode> gateways = osNodeService.completeNodes(GATEWAY);
-
-                        InstancePort revisedInstPort = swapStaleLocation(event.subject());
-
-                        if (gateways.size() == 1) {
-                            return;
-                        }
-
-                        if (fip != null && isAssociatedWithVM(osNetworkService, fip)) {
-                            DeviceId newDeviceId = event.subject().deviceId();
-                            DeviceId oldDeviceId = revisedInstPort.deviceId();
-
-                            OpenstackNode oldGw =
-                                    getGwByComputeDevId(gateways, oldDeviceId);
-                            OpenstackNode newGw =
-                                    getGwByComputeDevId(gateways, newDeviceId);
-
-                            if (oldGw != null && oldGw.equals(newGw)) {
-                                return;
-                            }
-
-                            setFloatingIpArpRuleWithPortEvent(fip,
-                                        revisedInstPort, gateways, false);
-                        }
-                    });
+                    eventExecutor.execute(() ->
+                                processInstanceMigrationEnd(event, instPort));
                     break;
                 default:
                     break;
             }
         }
+
+        private void processInstanceDetection(InstancePortEvent event,
+                                              InstancePort instPort) {
+            if (!isRelevantHelper()) {
+                return;
+            }
+
+            osRouterAdminService.floatingIps().stream()
+                    .filter(f -> f.getPortId() != null)
+                    .filter(f -> f.getPortId().equals(instPort.portId()))
+                    .forEach(f -> setFloatingIpArpRule(f, instPort.portId(),
+                            osNodeService.completeNodes(GATEWAY), true));
+        }
+
+        private void processInstanceMigrationStart(InstancePortEvent event,
+                                                   InstancePort instPort) {
+            if (!isRelevantHelper()) {
+                return;
+            }
+
+            NetFloatingIP fip = associatedFloatingIp(instPort,
+                    osRouterAdminService.floatingIps());
+
+            if (osNodeService.completeNodes(GATEWAY).size() == 1) {
+                return;
+            }
+
+            if (fip != null && isAssociatedWithVM(osNetworkService, fip)) {
+                setFloatingIpArpRuleWithPortEvent(fip, event.subject(),
+                        osNodeService.completeNodes(GATEWAY), true);
+            }
+        }
+
+        private void processInstanceMigrationEnd(InstancePortEvent event,
+                                                 InstancePort instPort) {
+            if (!isRelevantHelper()) {
+                return;
+            }
+
+            NetFloatingIP fip = associatedFloatingIp(instPort,
+                    osRouterAdminService.floatingIps());
+            Set<OpenstackNode> gateways = osNodeService.completeNodes(GATEWAY);
+
+            InstancePort revisedInstPort = swapStaleLocation(event.subject());
+
+            if (gateways.size() == 1) {
+                return;
+            }
+
+            if (fip != null && isAssociatedWithVM(osNetworkService, fip)) {
+                DeviceId newDeviceId = event.subject().deviceId();
+                DeviceId oldDeviceId = revisedInstPort.deviceId();
+
+                OpenstackNode oldGw =
+                        getGwByComputeDevId(gateways, oldDeviceId);
+                OpenstackNode newGw =
+                        getGwByComputeDevId(gateways, newDeviceId);
+
+                if (oldGw != null && oldGw.equals(newGw)) {
+                    return;
+                }
+
+                setFloatingIpArpRuleWithPortEvent(fip,
+                        revisedInstPort, gateways, false);
+            }
+        }
     }
 
     private class InternalNodeEventListener implements OpenstackNodeListener {
@@ -850,38 +871,44 @@
             OpenstackNode osNode = event.subject();
             switch (event.type()) {
                 case OPENSTACK_NODE_COMPLETE:
-                    eventExecutor.execute(() -> {
-                        if (!isRelevantHelper()) {
-                            return;
-                        }
-                        setDefaultArpRule(osNode, true);
-                        setFloatingIpArpRuleForGateway(osNode, true);
-                        sendGratuitousArpToSwitch(event.subject(), true);
-                    });
+                    eventExecutor.execute(() -> processNodeCompletion(event, osNode));
                     break;
                 case OPENSTACK_NODE_INCOMPLETE:
-                    eventExecutor.execute(() -> {
-                        if (!isRelevantHelper()) {
-                            return;
-                        }
-                        setDefaultArpRule(osNode, false);
-                        setFloatingIpArpRuleForGateway(osNode, false);
-                        sendGratuitousArpToSwitch(event.subject(), false);
-                    });
+                    eventExecutor.execute(() -> processNodeIncompletion(event, osNode));
                     break;
                 case OPENSTACK_NODE_REMOVED:
-                    eventExecutor.execute(() -> {
-                        if (!isRelevantHelper()) {
-                            return;
-                        }
-                        sendGratuitousArpToSwitch(event.subject(), false);
-                    });
+                    eventExecutor.execute(() -> processNodeRemoval(event));
                     break;
                 default:
                     break;
             }
         }
 
+        private void processNodeCompletion(OpenstackNodeEvent event, OpenstackNode node) {
+            if (!isRelevantHelper()) {
+                return;
+            }
+            setDefaultArpRule(node, true);
+            setFloatingIpArpRuleForGateway(node, true);
+            sendGratuitousArpToSwitch(event.subject(), true);
+        }
+
+        private void processNodeIncompletion(OpenstackNodeEvent event, OpenstackNode node) {
+            if (!isRelevantHelper()) {
+                return;
+            }
+            setDefaultArpRule(node, false);
+            setFloatingIpArpRuleForGateway(node, false);
+            sendGratuitousArpToSwitch(event.subject(), false);
+        }
+
+        private void processNodeRemoval(OpenstackNodeEvent event) {
+            if (!isRelevantHelper()) {
+                return;
+            }
+            sendGratuitousArpToSwitch(event.subject(), false);
+        }
+
         private void sendGratuitousArpToSwitch(OpenstackNode gatewayNode,
                                                boolean isCompleteCase) {
             Set<OpenstackNode> completeGws =
@@ -912,7 +939,7 @@
         private boolean isGwSelectedByComputeNode(Set<OpenstackNode> gws,
                                                   OpenstackNode computeNode,
                                                   OpenstackNode gwNode) {
-            return getGwByComputeDevId(gws, computeNode.intgBridge())
+            return requireNonNull(getGwByComputeDevId(gws, computeNode.intgBridge()))
                     .intgBridge().equals(gwNode.intgBridge());
         }
 
diff --git a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingFloatingIpHandler.java b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingFloatingIpHandler.java
index c122213..075d974 100644
--- a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingFloatingIpHandler.java
+++ b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingFloatingIpHandler.java
@@ -101,6 +101,8 @@
     private static final String ERR_FLOW = "Failed set flows for floating IP %s: ";
     private static final String ERR_UNSUPPORTED_NET_TYPE = "Unsupported network type %s";
 
+    private static final String NO_EXT_PEER_ROUTER_MSG = "no external peer router found";
+
     @Reference(cardinality = ReferenceCardinality.MANDATORY)
     protected CoreService coreService;
 
@@ -186,7 +188,7 @@
         ExternalPeerRouter externalPeerRouter = externalPeerRouterForNetwork(osNet,
                 osNetworkService, osRouterAdminService);
         if (externalPeerRouter == null) {
-            final String errorFormat = ERR_FLOW + "no external peer router found";
+            final String errorFormat = ERR_FLOW + NO_EXT_PEER_ROUTER_MSG;
             throw new IllegalStateException(errorFormat);
         }
 
@@ -250,11 +252,9 @@
                 }
             } else {
                 if (!completedGws.contains(gateway)) {
-                    if (completedGws.size() >= 1) {
-                        if (fip.getPortId() != null) {
-                            setDownstreamExternalRulesHelper(fip, osNet, instPort, router,
+                    if (!completedGws.isEmpty() && fip.getPortId() != null) {
+                        setDownstreamExternalRulesHelper(fip, osNet, instPort, router,
                                     ImmutableSet.copyOf(finalGws), true);
-                        }
                     }
                 } else {
                     log.warn("Detected node should NOT be included in completed gateway set");
@@ -299,7 +299,7 @@
                     setComputeNodeToGatewayHelper(instPort, osNet,
                             ImmutableSet.copyOf(finalGws), false);
                     finalGws.remove(gateway);
-                    if (completedGws.size() >= 1) {
+                    if (!completedGws.isEmpty()) {
                         setComputeNodeToGatewayHelper(instPort, osNet,
                                 ImmutableSet.copyOf(finalGws), true);
                     }
@@ -521,8 +521,8 @@
         ExternalPeerRouter externalPeerRouter =
                 externalPeerRouterForNetwork(osNet, osNetworkService, osRouterAdminService);
         if (externalPeerRouter == null) {
-            log.error("Failed to process GARP packet for floating ip {} " +
-                                        "because no external peer router found");
+            log.error("Failed to process GARP packet for floating ip {}, because " +
+                                                            NO_EXT_PEER_ROUTER_MSG);
             return;
         }
 
@@ -561,93 +561,91 @@
         public void event(OpenstackRouterEvent event) {
             switch (event.type()) {
                 case OPENSTACK_FLOATING_IP_ASSOCIATED:
-                    eventExecutor.execute(() -> {
-
-                        if (!isRelevantHelper()) {
-                            return;
-                        }
-
-                        NetFloatingIP osFip = event.floatingIp();
-                        if (instancePortService.instancePort(osFip.getPortId()) != null) {
-                            associateFloatingIp(osFip);
-                            log.info("Associated floating IP {}:{}",
-                                    osFip.getFloatingIpAddress(),
-                                    osFip.getFixedIpAddress());
-                        }
-                    });
+                    eventExecutor.execute(() -> processFloatingIpAssociation(event));
                     break;
                 case OPENSTACK_FLOATING_IP_DISASSOCIATED:
-                    eventExecutor.execute(() -> {
-
-                        if (!isRelevantHelper()) {
-                            return;
-                        }
-
-                        NetFloatingIP osFip = event.floatingIp();
-                        if (instancePortService.instancePort(event.portId()) != null) {
-                            disassociateFloatingIp(osFip, event.portId());
-                            log.info("Disassociated floating IP {}:{}",
-                                    osFip.getFloatingIpAddress(),
-                                    osFip.getFixedIpAddress());
-                        }
-                    });
+                    eventExecutor.execute(() -> processFloatingIpDisassociation(event));
                     break;
                 case OPENSTACK_FLOATING_IP_CREATED:
-                    eventExecutor.execute(() -> {
-
-                        if (!isRelevantHelper()) {
-                            return;
-                        }
-
-                        NetFloatingIP osFip = event.floatingIp();
-                        String portId = osFip.getPortId();
-                        if (!Strings.isNullOrEmpty(portId) &&
-                                instancePortService.instancePort(portId) != null) {
-                            associateFloatingIp(event.floatingIp());
-                        }
-                        log.info("Created floating IP {}", osFip.getFloatingIpAddress());
-                    });
+                    eventExecutor.execute(() -> processFloatingIpCreation(event));
                     break;
                 case OPENSTACK_FLOATING_IP_REMOVED:
-                    eventExecutor.execute(() -> {
-
-                        if (!isRelevantHelper()) {
-                            return;
-                        }
-
-                        NetFloatingIP osFip = event.floatingIp();
-                        String portId = osFip.getPortId();
-                        if (!Strings.isNullOrEmpty(osFip.getPortId())) {
-                            // in case the floating IP is not associated with any port due to
-                            // port removal, we simply do not execute floating IP disassociation
-                            if (osNetworkService.port(portId) != null &&
-                                    instancePortService.instancePort(portId) != null) {
-                                disassociateFloatingIp(osFip, portId);
-                            }
-
-                            // since we skip floating IP disassociation, we need to
-                            // manually unsubscribe the port pre-remove event
-                            preCommitPortService.unsubscribePreCommit(osFip.getPortId(),
-                                    OPENSTACK_PORT_PRE_REMOVE, instancePortService,
-                                    this.getClass().getName());
-                            log.info("Unsubscribed the port {} on listening pre-remove event",
-                                     osFip.getPortId());
-                        }
-                        log.info("Removed floating IP {}", osFip.getFloatingIpAddress());
-                    });
+                    eventExecutor.execute(() -> processFloatingIpRemoval(event));
                     break;
                 case OPENSTACK_FLOATING_IP_UPDATED:
-                case OPENSTACK_ROUTER_CREATED:
-                case OPENSTACK_ROUTER_UPDATED:
-                case OPENSTACK_ROUTER_REMOVED:
-                case OPENSTACK_ROUTER_INTERFACE_ADDED:
-                case OPENSTACK_ROUTER_INTERFACE_UPDATED:
-                case OPENSTACK_ROUTER_INTERFACE_REMOVED:
                 default:
                     // do nothing for the other events
                     break;
             }
         }
+
+        private void processFloatingIpAssociation(OpenstackRouterEvent event) {
+            if (!isRelevantHelper()) {
+                return;
+            }
+
+            NetFloatingIP osFip = event.floatingIp();
+            if (instancePortService.instancePort(osFip.getPortId()) != null) {
+                associateFloatingIp(osFip);
+                log.info("Associated floating IP {}:{}",
+                                                    osFip.getFloatingIpAddress(),
+                                                    osFip.getFixedIpAddress());
+            }
+        }
+
+        private void processFloatingIpDisassociation(OpenstackRouterEvent event) {
+            if (!isRelevantHelper()) {
+                return;
+            }
+
+            NetFloatingIP osFip = event.floatingIp();
+            if (instancePortService.instancePort(event.portId()) != null) {
+                disassociateFloatingIp(osFip, event.portId());
+                log.info("Disassociated floating IP {}:{}",
+                                                    osFip.getFloatingIpAddress(),
+                                                    osFip.getFixedIpAddress());
+            }
+        }
+
+        private void processFloatingIpCreation(OpenstackRouterEvent event) {
+            if (!isRelevantHelper()) {
+                return;
+            }
+
+            NetFloatingIP osFip = event.floatingIp();
+            String portId = osFip.getPortId();
+            if (!Strings.isNullOrEmpty(portId) &&
+                    instancePortService.instancePort(portId) != null) {
+                associateFloatingIp(event.floatingIp());
+            }
+            log.info("Created floating IP {}", osFip.getFloatingIpAddress());
+        }
+
+        private void processFloatingIpRemoval(OpenstackRouterEvent event) {
+            if (!isRelevantHelper()) {
+                return;
+            }
+
+            NetFloatingIP osFip = event.floatingIp();
+            String portId = osFip.getPortId();
+            if (!Strings.isNullOrEmpty(osFip.getPortId())) {
+                // in case the floating IP is not associated with any port due to
+                // port removal, we simply do not execute floating IP disassociation
+                if (osNetworkService.port(portId) != null &&
+                        instancePortService.instancePort(portId) != null) {
+                    disassociateFloatingIp(osFip, portId);
+                }
+
+                // since we skip floating IP disassociation, we need to
+                // manually unsubscribe the port pre-remove event
+                preCommitPortService.unsubscribePreCommit(osFip.getPortId(),
+                        OPENSTACK_PORT_PRE_REMOVE, instancePortService,
+                        this.getClass().getName());
+                log.info("Unsubscribed the port {} on listening pre-remove event",
+                        osFip.getPortId());
+            }
+            log.info("Removed floating IP {}", osFip.getFloatingIpAddress());
+        }
     }
 
     private class InternalNodeListener implements OpenstackNodeListener {
@@ -666,83 +664,85 @@
 
             switch (event.type()) {
                 case OPENSTACK_NODE_COMPLETE:
-                    eventExecutor.execute(() -> {
-
-                        if (!isRelevantHelper()) {
-                            return;
-                        }
-
-                        for (NetFloatingIP fip : osRouterAdminService.floatingIps()) {
-
-                            if (Strings.isNullOrEmpty(fip.getPortId())) {
-                                continue;
-                            }
-
-                            Port osPort = osNetworkService.port(fip.getPortId());
-                            InstancePort instPort = instancePortService.instancePort(fip.getPortId());
-
-                            // we check both Openstack Port and Instance Port
-                            if (osPort == null || instPort == null) {
-                                continue;
-                            }
-
-                            setFloatingIpRules(fip, instPort, event.subject(), true);
-                        }
-                    });
+                    eventExecutor.execute(() -> processNodeCompletion(event));
                     break;
                 case OPENSTACK_NODE_INCOMPLETE:
-                    eventExecutor.execute(() -> {
-
-                        if (!isRelevantHelper()) {
-                            return;
-                        }
-
-                        for (NetFloatingIP fip : osRouterAdminService.floatingIps()) {
-                            if (Strings.isNullOrEmpty(fip.getPortId())) {
-                                continue;
-                            }
-                            Port osPort = osNetworkService.port(fip.getPortId());
-                            if (osPort == null) {
-                                log.warn("Failed to set floating IP {}", fip.getId());
-                                continue;
-                            }
-                            Network osNet = osNetworkService.network(osPort.getNetworkId());
-                            if (osNet == null) {
-                                final String errorFormat = ERR_FLOW + "no network(%s) exists";
-                                final String error = String.format(errorFormat,
-                                        fip.getFloatingIpAddress(),
-                                        osPort.getNetworkId());
-                                throw new IllegalStateException(error);
-                            }
-                            MacAddress srcMac = MacAddress.valueOf(osPort.getMacAddress());
-                            log.trace("Mac address of openstack port: {}", srcMac);
-                            InstancePort instPort = instancePortService.instancePort(srcMac);
-
-                            if (instPort == null) {
-                                final String errorFormat = ERR_FLOW + "no host(MAC:%s) found";
-                                final String error = String.format(errorFormat,
-                                        fip.getFloatingIpAddress(), srcMac);
-                                throw new IllegalStateException(error);
-                            }
-
-                            ExternalPeerRouter externalPeerRouter = externalPeerRouterForNetwork(osNet,
-                                    osNetworkService, osRouterAdminService);
-                            if (externalPeerRouter == null) {
-                                final String errorFormat = ERR_FLOW + "no external peer router found";
-                                throw new IllegalStateException(errorFormat);
-                            }
-
-                            updateComputeNodeRules(instPort, osNet, event.subject(), false);
-                            updateGatewayNodeRules(fip, instPort, osNet,
-                                    externalPeerRouter, event.subject(), false);
-                        }
-                    });
+                    eventExecutor.execute(() -> processNodeIncompletion(event));
                     break;
                 default:
                     // do nothing
                     break;
             }
         }
+
+        private void processNodeCompletion(OpenstackNodeEvent event) {
+            if (!isRelevantHelper()) {
+                return;
+            }
+
+            for (NetFloatingIP fip : osRouterAdminService.floatingIps()) {
+
+                if (Strings.isNullOrEmpty(fip.getPortId())) {
+                    continue;
+                }
+
+                Port osPort = osNetworkService.port(fip.getPortId());
+                InstancePort instPort = instancePortService.instancePort(fip.getPortId());
+
+                // we check both Openstack Port and Instance Port
+                if (osPort == null || instPort == null) {
+                    continue;
+                }
+
+                setFloatingIpRules(fip, instPort, event.subject(), true);
+            }
+        }
+
+        private void processNodeIncompletion(OpenstackNodeEvent event) {
+            if (!isRelevantHelper()) {
+                return;
+            }
+
+            for (NetFloatingIP fip : osRouterAdminService.floatingIps()) {
+                if (Strings.isNullOrEmpty(fip.getPortId())) {
+                    continue;
+                }
+                Port osPort = osNetworkService.port(fip.getPortId());
+                if (osPort == null) {
+                    log.warn("Failed to set floating IP {}", fip.getId());
+                    continue;
+                }
+                Network osNet = osNetworkService.network(osPort.getNetworkId());
+                if (osNet == null) {
+                    final String errorFormat = ERR_FLOW + "no network(%s) exists";
+                    final String error = String.format(errorFormat,
+                            fip.getFloatingIpAddress(),
+                            osPort.getNetworkId());
+                    throw new IllegalStateException(error);
+                }
+                MacAddress srcMac = MacAddress.valueOf(osPort.getMacAddress());
+                log.trace("Mac address of openstack port: {}", srcMac);
+                InstancePort instPort = instancePortService.instancePort(srcMac);
+
+                if (instPort == null) {
+                    final String errorFormat = ERR_FLOW + "no host(MAC:%s) found";
+                    final String error = String.format(errorFormat,
+                            fip.getFloatingIpAddress(), srcMac);
+                    throw new IllegalStateException(error);
+                }
+
+                ExternalPeerRouter externalPeerRouter = externalPeerRouterForNetwork(osNet,
+                        osNetworkService, osRouterAdminService);
+                if (externalPeerRouter == null) {
+                    final String errorFormat = ERR_FLOW + NO_EXT_PEER_ROUTER_MSG;
+                    throw new IllegalStateException(errorFormat);
+                }
+
+                updateComputeNodeRules(instPort, osNet, event.subject(), false);
+                updateGatewayNodeRules(fip, instPort, osNet,
+                        externalPeerRouter, event.subject(), false);
+            }
+        }
     }
 
     private class InternalInstancePortListener implements InstancePortListener {
@@ -767,129 +767,128 @@
 
         @Override
         public void event(InstancePortEvent event) {
-            InstancePort instPort = event.subject();
-
             switch (event.type()) {
                 case OPENSTACK_INSTANCE_PORT_DETECTED:
-
-                    eventExecutor.execute(() -> {
-
-                        if (!isRelevantHelper(event)) {
-                            return;
-                        }
-
-                        if (instPort != null && instPort.portId() != null) {
-                            osRouterAdminService.floatingIps().stream()
-                                    .filter(f -> f.getPortId() != null)
-                                    .filter(f -> f.getPortId().equals(instPort.portId()))
-                                    .forEach(f -> setFloatingIpRules(f,
-                                            instPort, null, true));
-                        }
-                    });
+                    eventExecutor.execute(() -> processInstancePortDetection(event));
                     break;
-
                 case OPENSTACK_INSTANCE_MIGRATION_STARTED:
-
-                    eventExecutor.execute(() -> {
-
-                        if (!isRelevantHelper(event)) {
-                            return;
-                        }
-
-                        Set<OpenstackNode> gateways = osNodeService.completeNodes(GATEWAY);
-                        Set<NetFloatingIP> ips = osRouterAdminService.floatingIps();
-                        NetFloatingIP fip = associatedFloatingIp(event.subject(), ips);
-
-                        if (fip == null) {
-                            return;
-                        }
-
-                        Port osPort = osNetworkService.port(fip.getPortId());
-                        Network osNet = osNetworkService.network(osPort.getNetworkId());
-                        ExternalPeerRouter externalPeerRouter = externalPeerRouterForNetwork(osNet,
-                                osNetworkService, osRouterAdminService);
-
-                        if (externalPeerRouter == null) {
-                            final String errorFormat = ERR_FLOW + "no external peer router found";
-                            throw new IllegalStateException(errorFormat);
-                        }
-
-                        // since DownstreamExternal rules should only be placed in
-                        // corresponding gateway node, we need to install new rule to
-                        // the corresponding gateway node
-                        setDownstreamExternalRulesHelper(fip, osNet,
-                                event.subject(), externalPeerRouter, gateways, true);
-
-                        // since ComputeNodeToGateway rules should only be placed in
-                        // corresponding compute node, we need to install new rule to
-                        // the target compute node, and remove rules from original node
-                        setComputeNodeToGatewayHelper(event.subject(), osNet, gateways, true);
-                    });
+                    eventExecutor.execute(() -> processInstanceMigrationStart(event));
                     break;
                 case OPENSTACK_INSTANCE_MIGRATION_ENDED:
-
-                    eventExecutor.execute(() -> {
-
-                        if (!isRelevantHelper(event)) {
-                            return;
-                        }
-
-                        InstancePort oldInstPort = swapStaleLocation(event.subject());
-
-                        Set<NetFloatingIP> ips = osRouterAdminService.floatingIps();
-                        NetFloatingIP fip = associatedFloatingIp(oldInstPort, ips);
-
-                        if (fip == null) {
-                            return;
-                        }
-
-                        Set<OpenstackNode> gateways = osNodeService.completeNodes(GATEWAY);
-                        Port osPort = osNetworkService.port(fip.getPortId());
-                        Network osNet = osNetworkService.network(osPort.getNetworkId());
-                        ExternalPeerRouter externalPeerRouter = externalPeerRouterForNetwork(osNet,
-                                osNetworkService, osRouterAdminService);
-
-                        if (externalPeerRouter == null) {
-                            final String errorFormat = ERR_FLOW + "no external peer router found";
-                            throw new IllegalStateException(errorFormat);
-                        }
-
-                        // We need to remove the old ComputeNodeToGateway rules from
-                        // original compute node
-                        setComputeNodeToGatewayHelper(oldInstPort, osNet, gateways, false);
-
-                        // If we only have one gateway, we simply do not remove any
-                        // flow rules from either gateway or compute node
-                        if (gateways.size() == 1) {
-                            return;
-                        }
-
-                        // Checks whether the destination compute node's device id
-                        // has identical gateway hash or not
-                        // if it is true, we simply do not remove the rules, as
-                        // it has been overwritten at port detention event
-                        // if it is false, we will remove the rules
-                        DeviceId newDeviceId = event.subject().deviceId();
-                        DeviceId oldDeviceId = oldInstPort.deviceId();
-
-                        OpenstackNode oldGateway = getGwByComputeDevId(gateways, oldDeviceId);
-                        OpenstackNode newGateway = getGwByComputeDevId(gateways, newDeviceId);
-
-                        if (oldGateway != null && oldGateway.equals(newGateway)) {
-                            return;
-                        }
-
-                        // Since DownstreamExternal rules should only be placed in
-                        // corresponding gateway node, we need to remove old rule from
-                        // the corresponding gateway node
-                        setDownstreamExternalRulesHelper(fip, osNet, oldInstPort,
-                                externalPeerRouter, gateways, false);
-                    });
+                    eventExecutor.execute(() -> processInstanceMigrationEnd(event));
                     break;
                 default:
                     break;
             }
         }
+
+        private void processInstancePortDetection(InstancePortEvent event) {
+            if (!isRelevantHelper(event)) {
+                return;
+            }
+
+            InstancePort instPort = event.subject();
+
+            if (instPort != null && instPort.portId() != null) {
+                osRouterAdminService.floatingIps().stream()
+                        .filter(f -> f.getPortId() != null)
+                        .filter(f -> f.getPortId().equals(instPort.portId()))
+                        .forEach(f -> setFloatingIpRules(f,
+                                instPort, null, true));
+            }
+        }
+
+        private void processInstanceMigrationStart(InstancePortEvent event) {
+            if (!isRelevantHelper(event)) {
+                return;
+            }
+
+            Set<OpenstackNode> gateways = osNodeService.completeNodes(GATEWAY);
+            Set<NetFloatingIP> ips = osRouterAdminService.floatingIps();
+            NetFloatingIP fip = associatedFloatingIp(event.subject(), ips);
+
+            if (fip == null) {
+                return;
+            }
+
+            Port osPort = osNetworkService.port(fip.getPortId());
+            Network osNet = osNetworkService.network(osPort.getNetworkId());
+            ExternalPeerRouter externalPeerRouter = externalPeerRouterForNetwork(osNet,
+                    osNetworkService, osRouterAdminService);
+
+            if (externalPeerRouter == null) {
+                final String errorFormat = ERR_FLOW + NO_EXT_PEER_ROUTER_MSG;
+                throw new IllegalStateException(errorFormat);
+            }
+
+            // since DownstreamExternal rules should only be placed in
+            // corresponding gateway node, we need to install new rule to
+            // the corresponding gateway node
+            setDownstreamExternalRulesHelper(fip, osNet,
+                    event.subject(), externalPeerRouter, gateways, true);
+
+            // since ComputeNodeToGateway rules should only be placed in
+            // corresponding compute node, we need to install new rule to
+            // the target compute node, and remove rules from original node
+            setComputeNodeToGatewayHelper(event.subject(), osNet, gateways, true);
+        }
+
+        private void processInstanceMigrationEnd(InstancePortEvent event) {
+            if (!isRelevantHelper(event)) {
+                return;
+            }
+
+            InstancePort oldInstPort = swapStaleLocation(event.subject());
+
+            Set<NetFloatingIP> ips = osRouterAdminService.floatingIps();
+            NetFloatingIP fip = associatedFloatingIp(oldInstPort, ips);
+
+            if (fip == null) {
+                return;
+            }
+
+            Set<OpenstackNode> gateways = osNodeService.completeNodes(GATEWAY);
+            Port osPort = osNetworkService.port(fip.getPortId());
+            Network osNet = osNetworkService.network(osPort.getNetworkId());
+            ExternalPeerRouter externalPeerRouter = externalPeerRouterForNetwork(osNet,
+                    osNetworkService, osRouterAdminService);
+
+            if (externalPeerRouter == null) {
+                final String errorFormat = ERR_FLOW + NO_EXT_PEER_ROUTER_MSG;
+                throw new IllegalStateException(errorFormat);
+            }
+
+            // We need to remove the old ComputeNodeToGateway rules from
+            // original compute node
+            setComputeNodeToGatewayHelper(oldInstPort, osNet, gateways, false);
+
+            // If we only have one gateway, we simply do not remove any
+            // flow rules from either gateway or compute node
+            if (gateways.size() == 1) {
+                return;
+            }
+
+            // Checks whether the destination compute node's device id
+            // has identical gateway hash or not
+            // if it is true, we simply do not remove the rules, as
+            // it has been overwritten at port detention event
+            // if it is false, we will remove the rules
+            DeviceId newDeviceId = event.subject().deviceId();
+            DeviceId oldDeviceId = oldInstPort.deviceId();
+
+            OpenstackNode oldGateway = getGwByComputeDevId(gateways, oldDeviceId);
+            OpenstackNode newGateway = getGwByComputeDevId(gateways, newDeviceId);
+
+            if (oldGateway != null && oldGateway.equals(newGateway)) {
+                return;
+            }
+
+            // Since DownstreamExternal rules should only be placed in
+            // corresponding gateway node, we need to remove old rule from
+            // the corresponding gateway node
+            setDownstreamExternalRulesHelper(fip, osNet, oldInstPort,
+                    externalPeerRouter, gateways, false);
+        }
     }
 
     private class InternalOpenstackNetworkListener implements OpenstackNetworkListener {
@@ -900,23 +899,19 @@
 
         @Override
         public void event(OpenstackNetworkEvent event) {
-            switch (event.type()) {
-                case OPENSTACK_PORT_PRE_REMOVE:
-                    eventExecutor.execute(() -> {
+            if (event.type() == OPENSTACK_PORT_PRE_REMOVE) {
+                eventExecutor.execute(() -> {
 
-                        if (!isRelevantHelper()) {
-                            return;
-                        }
+                    if (!isRelevantHelper()) {
+                        return;
+                    }
 
-                        processPortPreRemove(event);
-                    });
-                    break;
-                default:
-                    break;
+                    processPortPreRemoval(event);
+                });
             }
         }
 
-        private void processPortPreRemove(OpenstackNetworkEvent event) {
+        private void processPortPreRemoval(OpenstackNetworkEvent event) {
             InstancePort instPort = instancePortService.instancePort(
                                                         event.port().getId());
             if (instPort == null) {
diff --git a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingHandler.java b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingHandler.java
index a76961b..c366178 100644
--- a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingHandler.java
+++ b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingHandler.java
@@ -120,6 +120,8 @@
     private static final String MSG_DISABLED = "Disabled ";
     private static final String ERR_UNSUPPORTED_NET_TYPE = "Unsupported network type";
 
+    private static final int VM_PREFIX = 32;
+
     /** Use Stateful SNAT for source NATing. */
     private boolean useStatefulSnat = USE_STATEFUL_SNAT_DEFAULT;
 
@@ -362,12 +364,12 @@
                                 .filter(port -> port.state() == ACTIVE)
                                 .forEach(port -> setRulesForSnatIngressRule(gwNode.intgBridge(),
                                     Long.parseLong(osNet.getProviderSegID()),
-                                    IpPrefix.valueOf(port.ipAddress(), 32),
+                                    IpPrefix.valueOf(port.ipAddress(), VM_PREFIX),
                                     port.deviceId(),
                                     install));
 
                         setOvsNatIngressRule(gwNode.intgBridge(),
-                                IpPrefix.valueOf(natAddress, 32),
+                                IpPrefix.valueOf(natAddress, VM_PREFIX),
                                 Constants.DEFAULT_EXTERNAL_ROUTER_MAC, install);
                         setOvsNatEgressRule(gwNode.intgBridge(),
                                 natAddress, Long.parseLong(osNet.getProviderSegID()),
@@ -425,9 +427,10 @@
     }
 
     private void setGatewayIcmp(Subnet osSubnet, Router osRouter, boolean install) {
-        OpenstackNode sourceNatGateway = osNodeService.completeNodes(GATEWAY).stream().findFirst().orElse(null);
+        OpenstackNode srcNatGw = osNodeService.completeNodes(GATEWAY)
+                                         .stream().findFirst().orElse(null);
 
-        if (sourceNatGateway == null) {
+        if (srcNatGw == null) {
             return;
         }
 
@@ -437,38 +440,19 @@
         }
 
         // take ICMP request to a subnet gateway through gateway node group
-        Network network = osNetworkAdminService.network(osSubnet.getNetworkId());
+        Network net = osNetworkAdminService.network(osSubnet.getNetworkId());
         Set<Subnet> routableSubnets = routableSubnets(osRouter, osSubnet.getId());
 
-        switch (network.getNetworkType()) {
+        switch (net.getNetworkType()) {
             case VXLAN:
-                osNodeService.completeNodes(COMPUTE).stream()
-                        .filter(cNode -> cNode.dataIp() != null)
-                        .forEach(cNode -> setRulesToGatewayWithRoutableSubnets(
-                                cNode,
-                                sourceNatGateway,
-                                network.getProviderSegID(),
-                                osSubnet,
-                                routableSubnets,
-                                NetworkMode.VXLAN,
-                                install));
+                setGatewayIcmpForVxlan(osSubnet, srcNatGw, net, routableSubnets, install);
                 break;
             case VLAN:
-                osNodeService.completeNodes(COMPUTE).stream()
-                        .filter(cNode -> cNode.vlanPortNum() != null)
-                        .forEach(cNode -> setRulesToGatewayWithRoutableSubnets(
-                                cNode,
-                                sourceNatGateway,
-                                network.getProviderSegID(),
-                                osSubnet,
-                                routableSubnets,
-                                NetworkMode.VLAN,
-                                install));
+                setGatewayIcmpForVlan(osSubnet, srcNatGw, net, routableSubnets, install);
                 break;
             default:
-                final String error = String.format("%s %s",
-                        ERR_UNSUPPORTED_NET_TYPE,
-                        network.getNetworkType().toString());
+                final String error = String.format("%s %s", ERR_UNSUPPORTED_NET_TYPE,
+                                                            net.getNetworkType().toString());
                 throw new IllegalStateException(error);
         }
 
@@ -483,6 +467,40 @@
         log.debug(updateStr + "ICMP to {}", osSubnet.getGateway());
     }
 
+    private void setGatewayIcmpForVxlan(Subnet osSubnet,
+                                        OpenstackNode srcNatGw,
+                                        Network network,
+                                        Set<Subnet> routableSubnets,
+                                        boolean install) {
+        osNodeService.completeNodes(COMPUTE).stream()
+                .filter(cNode -> cNode.dataIp() != null)
+                .forEach(cNode -> setRulesToGatewayWithRoutableSubnets(
+                        cNode,
+                        srcNatGw,
+                        network.getProviderSegID(),
+                        osSubnet,
+                        routableSubnets,
+                        NetworkMode.VXLAN,
+                        install));
+    }
+
+    private void setGatewayIcmpForVlan(Subnet osSubnet,
+                                       OpenstackNode srcNatGw,
+                                       Network network,
+                                       Set<Subnet> routableSubnets,
+                                       boolean install) {
+        osNodeService.completeNodes(COMPUTE).stream()
+                .filter(cNode -> cNode.vlanPortNum() != null)
+                .forEach(cNode -> setRulesToGatewayWithRoutableSubnets(
+                        cNode,
+                        srcNatGw,
+                        network.getProviderSegID(),
+                        osSubnet,
+                        routableSubnets,
+                        NetworkMode.VLAN,
+                        install));
+    }
+
     private void setInternalRoutes(Router osRouter, Subnet updatedSubnet, boolean install) {
         Network updatedNetwork = osNetworkAdminService.network(updatedSubnet.getNetworkId());
         Set<Subnet> routableSubnets = routableSubnets(osRouter, updatedSubnet.getId());
@@ -565,107 +583,129 @@
                 install);
     }
 
-    private void setInternalRouterRules(DeviceId deviceId, String srcSegmentId, String dstSegmentId,
+    private void setInternalRouterRules(DeviceId deviceId, String srcSegId, String dstSegId,
                                         IpPrefix srcSubnet, IpPrefix dstSubnet,
                                         NetworkType networkType, boolean install) {
-        TrafficSelector selector;
-        TrafficTreatment treatment;
+
         switch (networkType) {
             case VXLAN:
-                selector = DefaultTrafficSelector.builder()
-                        .matchEthType(Ethernet.TYPE_IPV4)
-                        .matchTunnelId(Long.parseLong(srcSegmentId))
-                        .matchIPSrc(srcSubnet.getIp4Prefix())
-                        .matchIPDst(dstSubnet.getIp4Prefix())
-                        .build();
-
-                treatment = DefaultTrafficTreatment.builder()
-                        .setTunnelId(Long.parseLong(dstSegmentId))
-                        .transition(STAT_OUTBOUND_TABLE)
-                        .build();
-
-                osFlowRuleService.setRule(
-                        appId,
-                        deviceId,
-                        selector,
-                        treatment,
-                        PRIORITY_INTERNAL_ROUTING_RULE,
-                        ROUTING_TABLE,
-                        install);
-
-                selector = DefaultTrafficSelector.builder()
-                        .matchEthType(Ethernet.TYPE_IPV4)
-                        .matchTunnelId(Long.parseLong(dstSegmentId))
-                        .matchIPSrc(srcSubnet.getIp4Prefix())
-                        .matchIPDst(dstSubnet.getIp4Prefix())
-                        .build();
-
-                treatment = DefaultTrafficTreatment.builder()
-                        .setTunnelId(Long.parseLong(dstSegmentId))
-                        .transition(STAT_OUTBOUND_TABLE)
-                        .build();
-
-                osFlowRuleService.setRule(
-                        appId,
-                        deviceId,
-                        selector,
-                        treatment,
-                        PRIORITY_INTERNAL_ROUTING_RULE,
-                        ROUTING_TABLE,
-                        install);
+                setInternalRouterRulesForVxlan(deviceId, srcSegId, dstSegId,
+                                                srcSubnet, dstSubnet, install);
                 break;
             case VLAN:
-                selector = DefaultTrafficSelector.builder()
-                        .matchEthType(Ethernet.TYPE_IPV4)
-                        .matchVlanId(VlanId.vlanId(srcSegmentId))
-                        .matchIPSrc(srcSubnet.getIp4Prefix())
-                        .matchIPDst(dstSubnet.getIp4Prefix())
-                        .build();
-
-                treatment = DefaultTrafficTreatment.builder()
-                        .setVlanId(VlanId.vlanId(dstSegmentId))
-                        .transition(STAT_OUTBOUND_TABLE)
-                        .build();
-
-                osFlowRuleService.setRule(
-                        appId,
-                        deviceId,
-                        selector,
-                        treatment,
-                        PRIORITY_INTERNAL_ROUTING_RULE,
-                        ROUTING_TABLE,
-                        install);
-
-                selector = DefaultTrafficSelector.builder()
-                        .matchEthType(Ethernet.TYPE_IPV4)
-                        .matchVlanId(VlanId.vlanId(dstSegmentId))
-                        .matchIPSrc(srcSubnet.getIp4Prefix())
-                        .matchIPDst(dstSubnet.getIp4Prefix())
-                        .build();
-
-                treatment = DefaultTrafficTreatment.builder()
-                        .setVlanId(VlanId.vlanId(dstSegmentId))
-                        .transition(STAT_OUTBOUND_TABLE)
-                        .build();
-
-                osFlowRuleService.setRule(
-                        appId,
-                        deviceId,
-                        selector,
-                        treatment,
-                        PRIORITY_INTERNAL_ROUTING_RULE,
-                        ROUTING_TABLE,
-                        install);
+                setInternalRouterRulesForVlan(deviceId, srcSegId, dstSegId,
+                                                srcSubnet, dstSubnet, install);
                 break;
             default:
-                final String error = String.format("%s %s",
-                        ERR_UNSUPPORTED_NET_TYPE,
-                        networkType.toString());
+                final String error = String.format("%s %s", ERR_UNSUPPORTED_NET_TYPE,
+                                                            networkType.toString());
                 throw new IllegalStateException(error);
         }
 
     }
 
+    private void setInternalRouterRulesForVxlan(DeviceId deviceId,
+                                                String srcSegmentId,
+                                                String dstSegmentId,
+                                                IpPrefix srcSubnet,
+                                                IpPrefix dstSubnet,
+                                                boolean install) {
+        TrafficSelector selector;
+        TrafficTreatment treatment;
+        selector = DefaultTrafficSelector.builder()
+                .matchEthType(Ethernet.TYPE_IPV4)
+                .matchTunnelId(Long.parseLong(srcSegmentId))
+                .matchIPSrc(srcSubnet.getIp4Prefix())
+                .matchIPDst(dstSubnet.getIp4Prefix())
+                .build();
+
+        treatment = DefaultTrafficTreatment.builder()
+                .setTunnelId(Long.parseLong(dstSegmentId))
+                .transition(STAT_OUTBOUND_TABLE)
+                .build();
+
+        osFlowRuleService.setRule(
+                appId,
+                deviceId,
+                selector,
+                treatment,
+                PRIORITY_INTERNAL_ROUTING_RULE,
+                ROUTING_TABLE,
+                install);
+
+        selector = DefaultTrafficSelector.builder()
+                .matchEthType(Ethernet.TYPE_IPV4)
+                .matchTunnelId(Long.parseLong(dstSegmentId))
+                .matchIPSrc(srcSubnet.getIp4Prefix())
+                .matchIPDst(dstSubnet.getIp4Prefix())
+                .build();
+
+        treatment = DefaultTrafficTreatment.builder()
+                .setTunnelId(Long.parseLong(dstSegmentId))
+                .transition(STAT_OUTBOUND_TABLE)
+                .build();
+
+        osFlowRuleService.setRule(
+                appId,
+                deviceId,
+                selector,
+                treatment,
+                PRIORITY_INTERNAL_ROUTING_RULE,
+                ROUTING_TABLE,
+                install);
+    }
+
+    private void setInternalRouterRulesForVlan(DeviceId deviceId,
+                                               String srcSegmentId,
+                                               String dstSegmentId,
+                                               IpPrefix srcSubnet,
+                                               IpPrefix dstSubnet,
+                                               boolean install) {
+        TrafficSelector selector;
+        TrafficTreatment treatment;
+        selector = DefaultTrafficSelector.builder()
+                .matchEthType(Ethernet.TYPE_IPV4)
+                .matchVlanId(VlanId.vlanId(srcSegmentId))
+                .matchIPSrc(srcSubnet.getIp4Prefix())
+                .matchIPDst(dstSubnet.getIp4Prefix())
+                .build();
+
+        treatment = DefaultTrafficTreatment.builder()
+                .setVlanId(VlanId.vlanId(dstSegmentId))
+                .transition(STAT_OUTBOUND_TABLE)
+                .build();
+
+        osFlowRuleService.setRule(
+                appId,
+                deviceId,
+                selector,
+                treatment,
+                PRIORITY_INTERNAL_ROUTING_RULE,
+                ROUTING_TABLE,
+                install);
+
+        selector = DefaultTrafficSelector.builder()
+                .matchEthType(Ethernet.TYPE_IPV4)
+                .matchVlanId(VlanId.vlanId(dstSegmentId))
+                .matchIPSrc(srcSubnet.getIp4Prefix())
+                .matchIPDst(dstSubnet.getIp4Prefix())
+                .build();
+
+        treatment = DefaultTrafficTreatment.builder()
+                .setVlanId(VlanId.vlanId(dstSegmentId))
+                .transition(STAT_OUTBOUND_TABLE)
+                .build();
+
+        osFlowRuleService.setRule(
+                appId,
+                deviceId,
+                selector,
+                treatment,
+                PRIORITY_INTERNAL_ROUTING_RULE,
+                ROUTING_TABLE,
+                install);
+    }
+
     private void setRulesToGateway(OpenstackNode osNode, String segmentId, IpPrefix srcSubnet,
                                    NetworkType networkType, boolean install) {
         OpenstackNode sourceNatGateway = osNodeService.completeNodes(GATEWAY).stream().findFirst().orElse(null);
@@ -959,74 +999,22 @@
         public void event(OpenstackRouterEvent event) {
             switch (event.type()) {
                 case OPENSTACK_ROUTER_CREATED:
-                    log.debug("Router(name:{}, ID:{}) is created",
-                            event.subject().getName(),
-                            event.subject().getId());
-                    eventExecutor.execute(() -> {
-
-                        if (!isRelevantHelper()) {
-                            return;
-                        }
-
-                        routerUpdated(event.subject());
-                    });
+                    eventExecutor.execute(() -> processRouterCreation(event));
                     break;
                 case OPENSTACK_ROUTER_UPDATED:
-                    log.debug("Router(name:{}, ID:{}) is updated",
-                            event.subject().getName(),
-                            event.subject().getId());
-                    eventExecutor.execute(() -> {
-
-                        if (!isRelevantHelper()) {
-                            return;
-                        }
-
-                        routerUpdated(event.subject());
-                    });
+                    eventExecutor.execute(() -> processRouterUpdate(event));
                     break;
                 case OPENSTACK_ROUTER_REMOVED:
-                    log.debug("Router(name:{}, ID:{}) is removed",
-                            event.subject().getName(),
-                            event.subject().getId());
-                    eventExecutor.execute(() -> {
-
-                        if (!isRelevantHelper()) {
-                            return;
-                        }
-
-                        routerRemove(event.subject());
-                    });
+                    eventExecutor.execute(() -> processRouterRemoval(event));
                     break;
                 case OPENSTACK_ROUTER_INTERFACE_ADDED:
-                    log.debug("Router interface {} added to router {}",
-                            event.routerIface().getPortId(),
-                            event.routerIface().getId());
-                    eventExecutor.execute(() -> {
-
-                        if (!isRelevantHelper()) {
-                            return;
-                        }
-
-                        routerIfaceAdded(event.subject(), event.routerIface());
-                    });
+                    eventExecutor.execute(() -> processRouterIntfCreation(event));
                     break;
                 case OPENSTACK_ROUTER_INTERFACE_UPDATED:
-                    log.debug("Router interface {} on {} updated",
-                            event.routerIface().getPortId(),
-                            event.routerIface().getId());
+                    eventExecutor.execute(() -> processRouterIntfUpdate(event));
                     break;
                 case OPENSTACK_ROUTER_INTERFACE_REMOVED:
-                    log.debug("Router interface {} removed from router {}",
-                            event.routerIface().getPortId(),
-                            event.routerIface().getId());
-                    eventExecutor.execute(() -> {
-
-                        if (!isRelevantHelper()) {
-                            return;
-                        }
-
-                        routerIfaceRemoved(event.subject(), event.routerIface());
-                    });
+                    eventExecutor.execute(() -> processRouterIntfRemoval(event));
                     break;
                 case OPENSTACK_ROUTER_GATEWAY_ADDED:
                     log.debug("Router external gateway {} added",
@@ -1046,6 +1034,72 @@
                     break;
             }
         }
+
+        private void processRouterCreation(OpenstackRouterEvent event) {
+            if (!isRelevantHelper()) {
+                return;
+            }
+
+            log.debug("Router(name:{}, ID:{}) is created",
+                                                    event.subject().getName(),
+                                                    event.subject().getId());
+
+            routerUpdated(event.subject());
+        }
+
+        private void processRouterUpdate(OpenstackRouterEvent event) {
+            if (!isRelevantHelper()) {
+                return;
+            }
+
+            log.debug("Router(name:{}, ID:{}) is updated",
+                                                    event.subject().getName(),
+                                                    event.subject().getId());
+
+            routerUpdated(event.subject());
+        }
+
+        private void processRouterRemoval(OpenstackRouterEvent event) {
+            if (!isRelevantHelper()) {
+                return;
+            }
+
+            log.debug("Router(name:{}, ID:{}) is removed",
+                                                    event.subject().getName(),
+                                                    event.subject().getId());
+
+            routerRemove(event.subject());
+        }
+
+        private void processRouterIntfCreation(OpenstackRouterEvent event) {
+            if (!isRelevantHelper()) {
+                return;
+            }
+
+            log.debug("Router interface {} added to router {}",
+                                                    event.routerIface().getPortId(),
+                                                    event.routerIface().getId());
+
+            routerIfaceAdded(event.subject(), event.routerIface());
+        }
+
+        private void processRouterIntfUpdate(OpenstackRouterEvent event) {
+            log.debug("Router interface {} on {} updated",
+                                                    event.routerIface().getPortId(),
+                                                    event.routerIface().getId());
+        }
+
+        private void processRouterIntfRemoval(OpenstackRouterEvent event) {
+            if (!isRelevantHelper()) {
+                return;
+            }
+
+            log.debug("Router interface {} removed from router {}",
+                                                    event.routerIface().getPortId(),
+                                                    event.routerIface().getId());
+
+            routerIfaceRemoved(event.subject(), event.routerIface());
+        }
     }
 
     private class InternalNodeEventListener implements OpenstackNodeListener {
@@ -1057,20 +1111,16 @@
         @Override
         public void event(OpenstackNodeEvent event) {
             OpenstackNode osNode = event.subject();
-
             switch (event.type()) {
                 case OPENSTACK_NODE_COMPLETE:
                 case OPENSTACK_NODE_INCOMPLETE:
                 case OPENSTACK_NODE_UPDATED:
                 case OPENSTACK_NODE_REMOVED:
                     eventExecutor.execute(() -> {
-                        log.info("Reconfigure routers for {}", osNode.hostname());
-
                         if (!isRelevantHelper()) {
                             return;
                         }
-
-                        reconfigureRouters();
+                        reconfigureRouters(osNode);
                     });
                     break;
                 case OPENSTACK_NODE_CREATED:
@@ -1079,13 +1129,14 @@
             }
         }
 
-        private void reconfigureRouters() {
+        private void reconfigureRouters(OpenstackNode osNode) {
             osRouterService.routers().forEach(osRouter -> {
                 routerUpdated(osRouter);
                 osRouterService.routerInterfaces(osRouter.getId()).forEach(iface -> {
                     routerIfaceAdded(osRouter, iface);
                 });
             });
+            log.info("Reconfigure routers for {}", osNode.hostname());
         }
     }
 
@@ -1101,66 +1152,76 @@
             switch (event.type()) {
                 case OPENSTACK_INSTANCE_PORT_DETECTED:
                 case OPENSTACK_INSTANCE_PORT_UPDATED:
-                    log.info("RoutingHandler: Instance port detected MAC:{} IP:{}",
-                                                            instPort.macAddress(),
-                                                            instPort.ipAddress());
-
-                    eventExecutor.execute(() -> {
-
-                        if (!isRelevantHelper(event)) {
-                            return;
-                        }
-
-                        instPortDetected(event.subject());
-                    });
-
+                    eventExecutor.execute(() ->
+                                processInstancePortDetection(event, instPort));
                     break;
                 case OPENSTACK_INSTANCE_PORT_VANISHED:
-                    log.info("RoutingHandler: Instance port vanished MAC:{} IP:{}",
-                                                            instPort.macAddress(),
-                                                            instPort.ipAddress());
-
-                    eventExecutor.execute(() -> {
-
-                        if (!isRelevantHelper(event)) {
-                            return;
-                        }
-
-                        instPortRemoved(event.subject());
-                    });
-
+                    eventExecutor.execute(() ->
+                                processInstancePortRemoval(event, instPort));
                     break;
                 case OPENSTACK_INSTANCE_MIGRATION_STARTED:
-                    log.info("RoutingHandler: Migration started for MAC:{} IP:{}",
-                                                            instPort.macAddress(),
-                                                            instPort.ipAddress());
-
-                    eventExecutor.execute(() -> {
-
-                        if (!isRelevantHelper(event)) {
-                            return;
-                        }
-
-                        instPortDetected(instPort);
-                    });
-
+                    eventExecutor.execute(() ->
+                                processInstanceMigrationStart(event, instPort));
                     break;
                 case OPENSTACK_INSTANCE_MIGRATION_ENDED:
-                    log.info("RoutingHandler: Migration finished for MAC:{} IP:{}",
-                                                            instPort.macAddress(),
-                                                            instPort.ipAddress());
-                    eventExecutor.execute(() -> {
-                        // TODO: need to reconfigure rules to point to update VM
-                    });
-
+                    eventExecutor.execute(() ->
+                                processInstanceMigrationEnd(event, instPort));
                     break;
                 default:
                     break;
             }
         }
 
+        private void processInstancePortDetection(InstancePortEvent event,
+                                                  InstancePort instPort) {
+            if (!isRelevantHelper(event)) {
+                return;
+            }
+
+            log.info("RoutingHandler: Instance port detected MAC:{} IP:{}",
+                                                    instPort.macAddress(),
+                                                    instPort.ipAddress());
+
+            instPortDetected(event.subject());
+        }
+
+        private void processInstancePortRemoval(InstancePortEvent event,
+                                                InstancePort instPort) {
+            if (!isRelevantHelper(event)) {
+                return;
+            }
+
+            log.info("RoutingHandler: Instance port vanished MAC:{} IP:{}",
+                                                    instPort.macAddress(),
+                                                    instPort.ipAddress());
+
+            instPortRemoved(event.subject());
+        }
+
+        private void processInstanceMigrationStart(InstancePortEvent event,
+                                                   InstancePort instPort) {
+            if (!isRelevantHelper(event)) {
+                return;
+            }
+
+            log.info("RoutingHandler: Migration started for MAC:{} IP:{}",
+                                                    instPort.macAddress(),
+                                                    instPort.ipAddress());
+
+            instPortDetected(instPort);
+        }
+
+        private void processInstanceMigrationEnd(InstancePortEvent event,
+                                                 InstancePort instPort) {
+            log.info("RoutingHandler: Migration finished for MAC:{} IP:{}",
+                                                    instPort.macAddress(),
+                                                    instPort.ipAddress());
+            // TODO: need to reconfigure rules to point to update VM
+        }
+
         private void instPortDetected(InstancePort instPort) {
-            if (osNetworkAdminService.network(instPort.networkId()).getNetworkType() == FLAT) {
+            Network network = osNetworkAdminService.network(instPort.networkId());
+            if (network.getNetworkType() == FLAT) {
                 return;
             }
 
@@ -1168,15 +1229,15 @@
                 osNodeService.completeNodes(GATEWAY)
                         .forEach(gwNode -> setRulesForSnatIngressRule(
                                 gwNode.intgBridge(),
-                                Long.parseLong(osNetworkAdminService
-                                        .network(instPort.networkId()).getProviderSegID()),
-                                IpPrefix.valueOf(instPort.ipAddress(), 32),
+                                Long.parseLong(network.getProviderSegID()),
+                                IpPrefix.valueOf(instPort.ipAddress(), VM_PREFIX),
                                 instPort.deviceId(), true));
             }
         }
 
         private void instPortRemoved(InstancePort instPort) {
-            if (osNetworkAdminService.network(instPort.networkId()).getNetworkType() == FLAT) {
+            Network network = osNetworkAdminService.network(instPort.networkId());
+            if (network.getNetworkType() == FLAT) {
                 return;
             }
 
@@ -1184,9 +1245,8 @@
                 osNodeService.completeNodes(GATEWAY)
                         .forEach(gwNode -> setRulesForSnatIngressRule(
                                 gwNode.intgBridge(),
-                                Long.parseLong(osNetworkAdminService
-                                        .network(instPort.networkId()).getProviderSegID()),
-                                IpPrefix.valueOf(instPort.ipAddress(), 32),
+                                Long.parseLong(network.getProviderSegID()),
+                                IpPrefix.valueOf(instPort.ipAddress(), VM_PREFIX),
                                 instPort.deviceId(), false));
             }
         }
diff --git a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackSecurityGroupHandler.java b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackSecurityGroupHandler.java
index 3a28831..f42b073 100644
--- a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackSecurityGroupHandler.java
+++ b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackSecurityGroupHandler.java
@@ -106,6 +106,7 @@
 import static org.onosproject.openstacknetworking.api.Constants.PRIORITY_CT_DROP_RULE;
 import static org.onosproject.openstacknetworking.api.Constants.PRIORITY_CT_HOOK_RULE;
 import static org.onosproject.openstacknetworking.api.Constants.PRIORITY_CT_RULE;
+import static org.onosproject.openstacknetworking.api.OpenstackNetworkEvent.Type.OPENSTACK_PORT_PRE_REMOVE;
 import static org.onosproject.openstacknetworking.impl.OsgiPropertyConstants.USE_SECURITY_GROUP;
 import static org.onosproject.openstacknetworking.impl.OsgiPropertyConstants.USE_SECURITY_GROUP_DEFAULT;
 import static org.onosproject.openstacknetworking.util.OpenstackNetworkingUtil.swapStaleLocation;
@@ -130,7 +131,16 @@
 
     private static final int VM_IP_PREFIX = 32;
 
-    /** Apply OpenStack security group rule for VM traffic. */
+    private static final String STR_ZERO = "0";
+    private static final String STR_ONE = "1";
+    private static final String STR_NULL = "null";
+    private static final String STR_PADDING = "0000000000000000";
+    private static final int MASK_BEGIN_IDX = 0;
+    private static final int MASK_MAX_IDX = 16;
+    private static final int MASK_RADIX = 2;
+    private static final int PORT_RADIX = 16;
+
+    // Apply OpenStack security group rule for VM traffic.
     private boolean useSecurityGroup = USE_SECURITY_GROUP_DEFAULT;
 
     @Reference(cardinality = ReferenceCardinality.MANDATORY)
@@ -324,35 +334,6 @@
         }
     }
 
-    private void setSecurityGroupRules(InstancePort instPort,
-                                       Port port, boolean install) {
-
-        if (!install) {
-            Port rmvPort = removedOsPortStore.asJavaMap().get(instPort.portId());
-            if (port == null && rmvPort == null) {
-                return;
-            }
-
-            if (port == null) {
-                port = rmvPort;
-            }
-        }
-
-        final Port finalPort = port;
-
-        port.getSecurityGroups().forEach(sgId -> {
-            SecurityGroup sg = securityGroupService.securityGroup(sgId);
-            if (sg == null) {
-                log.error("Security Group Not Found : {}", sgId);
-                return;
-            }
-            sg.getRules().forEach(sgRule ->
-                    updateSecurityGroupRule(instPort, finalPort, sgRule, install));
-            final String action = install ? "Installed " : "Removed ";
-            log.debug(action + "security group rule ID : " + sgId);
-        });
-    }
-
     private void updateSecurityGroupRule(InstancePort instPort, Port port,
                                          SecurityGroupRule sgRule, boolean install) {
 
@@ -372,8 +353,8 @@
                                 new NeutronSecurityGroupRule
                                         .SecurityGroupRuleConcreteBuilder()
                                         .from(sgRule)
-                                        .direction(sgRule.getDirection().toUpperCase()
-                                                .equals(EGRESS) ? INGRESS : EGRESS)
+                                        .direction(sgRule.getDirection()
+                                                .equalsIgnoreCase(EGRESS) ? INGRESS : EGRESS)
                                         .build();
                         populateSecurityGroupRule(rSgRule, instPort,
                                 rInstPort.ipAddress().toIpPrefix(), install);
@@ -408,7 +389,7 @@
         TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
 
         int aclTable;
-        if (sgRule.getDirection().toUpperCase().equals(EGRESS)) {
+        if (sgRule.getDirection().equalsIgnoreCase(EGRESS)) {
             aclTable = ACL_EGRESS_TABLE;
             tBuilder.transition(ACL_RECIRC_TABLE);
         } else {
@@ -551,14 +532,14 @@
                             sgRule.getPortRangeMax());
             portRangeMatchMap.forEach((key, value) -> {
 
-                if (sgRule.getProtocol().toUpperCase().equals(PROTO_TCP)) {
-                    if (sgRule.getDirection().toUpperCase().equals(EGRESS)) {
+                if (sgRule.getProtocol().equalsIgnoreCase(PROTO_TCP)) {
+                    if (sgRule.getDirection().equalsIgnoreCase(EGRESS)) {
                         sBuilder.matchTcpSrcMasked(key, value);
                     } else {
                         sBuilder.matchTcpDstMasked(key, value);
                     }
-                } else if (sgRule.getProtocol().toUpperCase().equals(PROTO_UDP)) {
-                    if (sgRule.getDirection().toUpperCase().equals(EGRESS)) {
+                } else if (sgRule.getProtocol().equalsIgnoreCase(PROTO_UDP)) {
+                    if (sgRule.getDirection().equalsIgnoreCase(EGRESS)) {
                         sBuilder.matchUdpSrcMasked(key, value);
                     } else {
                         sBuilder.matchUdpDstMasked(key, value);
@@ -603,7 +584,7 @@
     private void buildMatchDirection(TrafficSelector.Builder sBuilder,
                                      String direction,
                                      Ip4Address vmIp) {
-        if (direction.toUpperCase().equals(EGRESS)) {
+        if (direction.equalsIgnoreCase(EGRESS)) {
             sBuilder.matchIPSrc(IpPrefix.valueOf(vmIp, VM_IP_PREFIX));
         } else {
             sBuilder.matchIPDst(IpPrefix.valueOf(vmIp, VM_IP_PREFIX));
@@ -613,8 +594,8 @@
     private void buildMatchEthType(TrafficSelector.Builder sBuilder, String etherType) {
         // Either IpSrc or IpDst (or both) is set by default, and we need to set EthType as IPv4.
         sBuilder.matchEthType(Ethernet.TYPE_IPV4);
-        if (etherType != null && !Objects.equals(etherType, "null") &&
-                !etherType.toUpperCase().equals(ETHTYPE_IPV4)) {
+        if (etherType != null && !Objects.equals(etherType, STR_NULL) &&
+                !etherType.equalsIgnoreCase(ETHTYPE_IPV4)) {
             log.debug("EthType {} is not supported yet in Security Group", etherType);
         }
     }
@@ -623,7 +604,7 @@
                                     IpPrefix remoteIpPrefix, String direction) {
         if (remoteIpPrefix != null &&
                 !remoteIpPrefix.getIp4Prefix().equals(IP_PREFIX_ANY)) {
-            if (direction.toUpperCase().equals(EGRESS)) {
+            if (direction.equalsIgnoreCase(EGRESS)) {
                 sBuilder.matchIPDst(remoteIpPrefix);
             } else {
                 sBuilder.matchIPSrc(remoteIpPrefix);
@@ -652,14 +633,14 @@
                                 String protocol, String direction,
                                 int portMin, int portMax) {
         if (portMin > 0 && portMax > 0 && portMin == portMax) {
-            if (protocol.toUpperCase().equals(PROTO_TCP)) {
-                if (direction.toUpperCase().equals(EGRESS)) {
+            if (protocol.equalsIgnoreCase(PROTO_TCP)) {
+                if (direction.equalsIgnoreCase(EGRESS)) {
                     sBuilder.matchTcpSrc(TpPort.tpPort(portMax));
                 } else {
                     sBuilder.matchTcpDst(TpPort.tpPort(portMax));
                 }
-            } else if (protocol.toUpperCase().equals(PROTO_UDP)) {
-                if (direction.toUpperCase().equals(EGRESS)) {
+            } else if (protocol.equalsIgnoreCase(PROTO_UDP)) {
+                if (direction.equalsIgnoreCase(EGRESS)) {
                     sBuilder.matchUdpSrc(TpPort.tpPort(portMax));
                 } else {
                     sBuilder.matchUdpDst(TpPort.tpPort(portMax));
@@ -725,26 +706,28 @@
     }
 
     private int binLower(String binStr, int bits) {
-        StringBuilder outBin = new StringBuilder(binStr.substring(0, 16 - bits));
+        StringBuilder outBin = new StringBuilder(
+                        binStr.substring(MASK_BEGIN_IDX, MASK_MAX_IDX - bits));
         for (int i = 0; i < bits; i++) {
-            outBin.append("0");
+            outBin.append(STR_ZERO);
         }
 
-        return Integer.parseInt(outBin.toString(), 2);
+        return Integer.parseInt(outBin.toString(), MASK_RADIX);
     }
 
     private int binHigher(String binStr, int bits) {
-        StringBuilder outBin = new StringBuilder(binStr.substring(0, 16 - bits));
+        StringBuilder outBin = new StringBuilder(
+                        binStr.substring(MASK_BEGIN_IDX, MASK_MAX_IDX - bits));
         for (int i = 0; i < bits; i++) {
-            outBin.append("1");
+            outBin.append(STR_ONE);
         }
 
-        return Integer.parseInt(outBin.toString(), 2);
+        return Integer.parseInt(outBin.toString(), MASK_RADIX);
     }
 
     private int testMasks(String binStr, int start, int end) {
-        int mask = 0;
-        for (; mask <= 16; mask++) {
+        int mask = MASK_BEGIN_IDX;
+        for (; mask <= MASK_MAX_IDX; mask++) {
             int maskStart = binLower(binStr, mask);
             int maskEnd = binHigher(binStr, mask);
             if (maskStart < start || maskEnd > end) {
@@ -785,7 +768,7 @@
         Map<TpPort, TpPort> portMaskMap = Maps.newHashMap();
         while (processing) {
             String minStr = Integer.toBinaryString(start);
-            String binStrMinPadded = "0000000000000000".substring(minStr.length()) + minStr;
+            String binStrMinPadded = STR_PADDING.substring(minStr.length()) + minStr;
 
             int mask = testMasks(binStrMinPadded, start, portMax);
             int maskStart = binLower(binStrMinPadded, mask);
@@ -793,7 +776,7 @@
 
             log.debug("start : {} port/mask = {} / {} ", start, getMask(mask), maskStart);
             portMaskMap.put(TpPort.tpPort(maskStart), TpPort.tpPort(
-                    Integer.parseInt(Objects.requireNonNull(getMask(mask)), 16)));
+                    Integer.parseInt(Objects.requireNonNull(getMask(mask)), PORT_RADIX)));
 
             start = maskEnd + 1;
             if (start > portMax) {
@@ -817,52 +800,57 @@
 
         @Override
         public void event(InstancePortEvent event) {
-            InstancePort instPort = event.subject();
             switch (event.type()) {
                 case OPENSTACK_INSTANCE_PORT_UPDATED:
                 case OPENSTACK_INSTANCE_PORT_DETECTED:
                 case OPENSTACK_INSTANCE_MIGRATION_STARTED:
-                    eventExecutor.execute(() -> {
-
-                        if (!isRelevantHelper(event)) {
-                            return;
-                        }
-
-                        installSecurityGroupRules(event, instPort);
-                        setAclRecircRules(instPort, true);
-                    });
+                    eventExecutor.execute(() -> processInstanceMigrationStart(event));
                     break;
                 case OPENSTACK_INSTANCE_PORT_VANISHED:
-                    eventExecutor.execute(() -> {
-
-                        if (!isRelevantHelper(event)) {
-                            return;
-                        }
-
-                        Port osPort = removedOsPortStore.asJavaMap().get(instPort.portId());
-                        setSecurityGroupRules(instPort, osPort, false);
-                        removedOsPortStore.remove(instPort.portId());
-                        setAclRecircRules(instPort, false);
-                    });
+                    eventExecutor.execute(() -> processInstancePortVanish(event));
                     break;
                 case OPENSTACK_INSTANCE_MIGRATION_ENDED:
-                    eventExecutor.execute(() -> {
-
-                        if (!isRelevantHelper(event)) {
-                            return;
-                        }
-
-                        InstancePort revisedInstPort = swapStaleLocation(instPort);
-                        Port port = osNetService.port(instPort.portId());
-                        setSecurityGroupRules(revisedInstPort, port, false);
-                        setAclRecircRules(revisedInstPort, false);
-                    });
+                    eventExecutor.execute(() -> processInstanceMigrationEnd(event));
                     break;
                 default:
                     break;
             }
         }
 
+        private void processInstanceMigrationStart(InstancePortEvent event) {
+            if (!isRelevantHelper(event)) {
+                return;
+            }
+
+            InstancePort instPort = event.subject();
+            installSecurityGroupRules(event, instPort);
+            setAclRecircRules(instPort, true);
+        }
+
+        private void processInstancePortVanish(InstancePortEvent event) {
+            if (!isRelevantHelper(event)) {
+                return;
+            }
+
+            InstancePort instPort = event.subject();
+            Port osPort = removedOsPortStore.asJavaMap().get(instPort.portId());
+            setSecurityGroupRules(instPort, osPort, false);
+            removedOsPortStore.remove(instPort.portId());
+            setAclRecircRules(instPort, false);
+        }
+
+        private void processInstanceMigrationEnd(InstancePortEvent event) {
+            if (!isRelevantHelper(event)) {
+                return;
+            }
+
+            InstancePort instPort = event.subject();
+            InstancePort revisedInstPort = swapStaleLocation(instPort);
+            Port port = osNetService.port(instPort.portId());
+            setSecurityGroupRules(revisedInstPort, port, false);
+            setAclRecircRules(revisedInstPort, false);
+        }
+
         private void installSecurityGroupRules(InstancePortEvent event,
                                                InstancePort instPort) {
             log.debug("Instance port detected/updated MAC:{} IP:{}",
@@ -873,6 +861,36 @@
                             osNetService.port(event.subject().portId()), true));
         }
 
+        private void setSecurityGroupRules(InstancePort instPort,
+                                           Port port, boolean install) {
+            Port osPort = port;
+
+            if (!install) {
+                Port rmvPort = removedOsPortStore.asJavaMap().get(instPort.portId());
+                if (osPort == null && rmvPort == null) {
+                    return;
+                }
+
+                if (port == null) {
+                    osPort = rmvPort;
+                }
+            }
+
+            final Port finalPort = osPort;
+
+            osPort.getSecurityGroups().forEach(sgId -> {
+                SecurityGroup sg = securityGroupService.securityGroup(sgId);
+                if (sg == null) {
+                    log.error("Security Group {} not found", sgId);
+                    return;
+                }
+                sg.getRules().forEach(sgRule ->
+                        updateSecurityGroupRule(instPort, finalPort, sgRule, install));
+                final String action = install ? "Installed " : "Removed ";
+                log.debug(action + "Security Group Rule ID : " + sgId);
+            });
+        }
+
         private void setAclRecircRules(InstancePort instPort, boolean install) {
             TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder();
 
@@ -932,24 +950,20 @@
         @Override
         public void event(OpenstackNetworkEvent event) {
             log.debug("openstack port event received {}", event);
-            Port osPort = event.port();
 
-            switch (event.type()) {
-                case OPENSTACK_PORT_PRE_REMOVE:
-                    eventExecutor.execute(() -> {
-
-                        if (!isRelevantHelper(event)) {
-                            return;
-                        }
-
-                        removedOsPortStore.put(osPort.getId(), osPort);
-                    });
-                    break;
-                default:
-                    // do nothing for the other events
-                    break;
+            if (event.type() == OPENSTACK_PORT_PRE_REMOVE) {
+                eventExecutor.execute(() -> processPortPreRemove(event));
             }
         }
+
+        private void processPortPreRemove(OpenstackNetworkEvent event) {
+            if (!isRelevantHelper(event)) {
+                return;
+            }
+
+            Port osPort = event.port();
+            removedOsPortStore.put(osPort.getId(), osPort);
+        }
     }
 
     private class InternalOpenstackNetworkListener implements OpenstackNetworkListener {
@@ -981,48 +995,49 @@
         @Override
         public void event(OpenstackNetworkEvent event) {
             log.debug("security group event received {}", event);
-            Port osPort = event.port();
 
             switch (event.type()) {
                 case OPENSTACK_PORT_SECURITY_GROUP_ADDED:
-                    eventExecutor.execute(() -> {
-
-                        if (!isRelevantHelper(event)) {
-                            return;
-                        }
-
-                        InstancePort instPort = instancePortService.instancePort(osPort.getId());
-                        SecurityGroup osSg = securityGroupService.securityGroup(event.securityGroupId());
-
-                        osSg.getRules().forEach(sgRule -> {
-                            updateSecurityGroupRule(instPort, osPort, sgRule, true);
-                        });
-                        log.info("Added security group {} to port {}",
-                                event.securityGroupId(), event.port().getId());
-                    });
+                    eventExecutor.execute(() -> processPortSgAdd(event));
                     break;
                 case OPENSTACK_PORT_SECURITY_GROUP_REMOVED:
-                    eventExecutor.execute(() -> {
-
-                        if (!isRelevantHelper(event)) {
-                            return;
-                        }
-
-                        InstancePort instPort = instancePortService.instancePort(osPort.getId());
-                        SecurityGroup osSg = securityGroupService.securityGroup(event.securityGroupId());
-
-                        osSg.getRules().forEach(sgRule -> {
-                            updateSecurityGroupRule(instPort, osPort, sgRule, false);
-                        });
-                        log.info("Removed security group {} from port {}",
-                                event.securityGroupId(), event.port().getId());
-                    });
+                    eventExecutor.execute(() -> processPortSgRemove(event));
                     break;
                 default:
                     // do nothing for the other events
                     break;
             }
         }
+
+        private void processPortSgAdd(OpenstackNetworkEvent event) {
+            if (!isRelevantHelper(event)) {
+                return;
+            }
+
+            InstancePort instPort = instancePortService.instancePort(event.port().getId());
+            SecurityGroup osSg = securityGroupService.securityGroup(event.securityGroupId());
+
+            osSg.getRules().forEach(sgRule -> {
+                updateSecurityGroupRule(instPort, event.port(), sgRule, true);
+            });
+            log.info("Added security group {} to port {}",
+                    event.securityGroupId(), event.port().getId());
+        }
+
+        private void processPortSgRemove(OpenstackNetworkEvent event) {
+            if (!isRelevantHelper(event)) {
+                return;
+            }
+
+            InstancePort instPort = instancePortService.instancePort(event.port().getId());
+            SecurityGroup osSg = securityGroupService.securityGroup(event.securityGroupId());
+
+            osSg.getRules().forEach(sgRule -> {
+                updateSecurityGroupRule(instPort, event.port(), sgRule, false);
+            });
+            log.info("Removed security group {} from port {}",
+                    event.securityGroupId(), event.port().getId());
+        }
     }
 
     private class InternalSecurityGroupListener implements OpenstackSecurityGroupListener {
@@ -1040,31 +1055,10 @@
         public void event(OpenstackSecurityGroupEvent event) {
             switch (event.type()) {
                 case OPENSTACK_SECURITY_GROUP_RULE_CREATED:
-                    SecurityGroupRule sgRuleToAdd = event.securityGroupRule();
-                    eventExecutor.execute(() -> {
-
-                        if (!isRelevantHelper()) {
-                            return;
-                        }
-
-                        securityGroupRuleAdded(sgRuleToAdd);
-                        log.info("Applied new security group rule {} to ports",
-                                sgRuleToAdd.getId());
-                    });
+                    eventExecutor.execute(() -> processSgRuleCreate(event));
                     break;
-
                 case OPENSTACK_SECURITY_GROUP_RULE_REMOVED:
-                    SecurityGroupRule sgRuleToRemove = event.securityGroupRule();
-                    eventExecutor.execute(() -> {
-
-                        if (!isRelevantHelper()) {
-                            return;
-                        }
-
-                        securityGroupRuleRemoved(sgRuleToRemove);
-                        log.info("Removed security group rule {} from ports",
-                                sgRuleToRemove.getId());
-                    });
+                    eventExecutor.execute(() -> processSgRuleRemove(event));
                     break;
                 case OPENSTACK_SECURITY_GROUP_REMOVED:
                 case OPENSTACK_SECURITY_GROUP_CREATED:
@@ -1073,6 +1067,26 @@
                     break;
             }
         }
+
+        private void processSgRuleCreate(OpenstackSecurityGroupEvent event) {
+            if (!isRelevantHelper()) {
+                return;
+            }
+
+            SecurityGroupRule sgRuleToAdd = event.securityGroupRule();
+            securityGroupRuleAdded(sgRuleToAdd);
+            log.info("Applied new security group rule {} to ports", sgRuleToAdd.getId());
+        }
+
+        private void processSgRuleRemove(OpenstackSecurityGroupEvent event) {
+            if (!isRelevantHelper()) {
+                return;
+            }
+
+            SecurityGroupRule sgRuleToRemove = event.securityGroupRule();
+            securityGroupRuleRemoved(sgRuleToRemove);
+            log.info("Removed security group rule {} from ports", sgRuleToRemove.getId());
+        }
     }
 
     private class InternalNodeListener implements OpenstackNodeListener {
@@ -1090,14 +1104,7 @@
         public void event(OpenstackNodeEvent event) {
             switch (event.type()) {
                 case OPENSTACK_NODE_COMPLETE:
-                    eventExecutor.execute(() -> {
-
-                        if (!isRelevantHelper()) {
-                            return;
-                        }
-
-                        OpenstackSecurityGroupHandler.this.resetSecurityGroupRules();
-                    });
+                    eventExecutor.execute(this::processNodeComplete);
                     break;
                 case OPENSTACK_NODE_CREATED:
                 case OPENSTACK_NODE_REMOVED:
@@ -1107,5 +1114,13 @@
                     break;
             }
         }
+
+        private void processNodeComplete() {
+            if (!isRelevantHelper()) {
+                return;
+            }
+
+            OpenstackSecurityGroupHandler.this.resetSecurityGroupRules();
+        }
     }
 }
\ No newline at end of file
diff --git a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackSwitchingHandler.java b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackSwitchingHandler.java
index 9bd06ef..31750d44e 100644
--- a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackSwitchingHandler.java
+++ b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackSwitchingHandler.java
@@ -89,12 +89,14 @@
  * virtual instances in the same network.
  */
 @Component(immediate = true)
-public final class OpenstackSwitchingHandler {
+public class OpenstackSwitchingHandler {
 
     private final Logger log = getLogger(getClass());
 
     private static final String ARP_MODE = "arpMode";
-    private static final String ERR_SET_FLOWS_VNI = "Failed to set flows for %s: Failed to get VNI for %s";
+    private static final String ERR_SET_FLOWS_VNI = "Failed to set flows for " +
+                                                    "%s: Failed to get VNI for %s";
+    private static final String STR_NONE = "<none>";
 
     @Reference(cardinality = ReferenceCardinality.MANDATORY)
     protected CoreService coreService;
@@ -139,7 +141,7 @@
     private NodeId localNodeId;
 
     @Activate
-    void activate() {
+    protected void activate() {
         appId = coreService.registerApplication(OPENSTACK_NETWORKING_APP_ID);
         localNodeId = clusterService.getLocalNode().id();
         instancePortService.addListener(instancePortListener);
@@ -149,7 +151,7 @@
     }
 
     @Deactivate
-    void deactivate() {
+    protected void deactivate() {
         osNetworkService.removeListener(osNetworkListener);
         instancePortService.removeListener(instancePortListener);
         eventExecutor.shutdown();
@@ -157,81 +159,6 @@
         log.info("Stopped");
     }
 
-    /**
-     * Configures L2 forwarding rules.
-     * Currently, SONA supports Flat, VXLAN and VLAN modes.
-     *
-     * @param instPort instance port object
-     * @param install install flag, add the rule if true, remove it otherwise
-     */
-    private void setNetworkRules(InstancePort instPort, boolean install) {
-        NetworkType type = osNetworkService.network(instPort.networkId()).getNetworkType();
-        switch (type) {
-            case VXLAN:
-                setTunnelTagIpFlowRules(instPort, install);
-                setForwardingRulesForVxlan(instPort, install);
-
-                if (ARP_BROADCAST_MODE.equals(getArpMode())) {
-                    setTunnelTagArpFlowRules(instPort, install);
-                }
-
-                break;
-            case VLAN:
-                setVlanTagIpFlowRules(instPort, install);
-                setForwardingRulesForVlan(instPort, install);
-
-                if (ARP_BROADCAST_MODE.equals(getArpMode())) {
-                    setVlanTagArpFlowRules(instPort, install);
-                }
-
-                break;
-            case FLAT:
-                setFlatJumpRules(instPort, install);
-                setDownstreamRulesForFlat(instPort, install);
-                setUpstreamRulesForFlat(instPort, install);
-                break;
-            default:
-                log.warn("Unsupported network tunnel type {}", type.name());
-                break;
-        }
-    }
-
-    /**
-     * Removes virtual port.
-     *
-     * @param instPort instance port
-     */
-    private void removeVportRules(InstancePort instPort) {
-        NetworkType type = osNetworkService.network(instPort.networkId()).getNetworkType();
-
-        switch (type) {
-            case VXLAN:
-                setTunnelTagIpFlowRules(instPort, false);
-
-                if (ARP_BROADCAST_MODE.equals(getArpMode())) {
-                    setTunnelTagArpFlowRules(instPort, false);
-                }
-
-                break;
-            case VLAN:
-                setVlanTagIpFlowRules(instPort, false);
-
-                if (ARP_BROADCAST_MODE.equals(getArpMode())) {
-                    setVlanTagArpFlowRules(instPort, false);
-                }
-
-                break;
-            case FLAT:
-                setFlatJumpRules(instPort, false);
-                setUpstreamRulesForFlat(instPort, false);
-                setDownstreamRulesForFlat(instPort, false);
-                break;
-            default:
-                log.warn("Unsupported network type {}", type.name());
-                break;
-        }
-    }
-
     private void setFlatJumpRules(InstancePort port, boolean install) {
         TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
         selector.matchInPort(port.portNumber());
@@ -657,7 +584,7 @@
         if (osNet == null || Strings.isNullOrEmpty(osNet.getProviderSegID())) {
             final String error =
                     String.format(ERR_SET_FLOWS_VNI,
-                        instPort, osNet == null ? "<none>" : osNet.getName());
+                        instPort, osNet == null ? STR_NONE : osNet.getName());
             throw new IllegalStateException(error);
         }
 
@@ -675,7 +602,7 @@
         if (osNet == null || Strings.isNullOrEmpty(osNet.getProviderSegID())) {
             final String error =
                     String.format(ERR_SET_FLOWS_VNI,
-                        instPort, osNet == null ? "<none>" : osNet.getName());
+                        instPort, osNet == null ? STR_NONE : osNet.getName());
             throw new IllegalStateException(error);
         }
         return Long.valueOf(osNet.getProviderSegID());
@@ -709,89 +636,196 @@
                 case OPENSTACK_INSTANCE_PORT_UPDATED:
                 case OPENSTACK_INSTANCE_MIGRATION_STARTED:
                 case OPENSTACK_INSTANCE_RESTARTED:
-
-                    if (event.type() == OPENSTACK_INSTANCE_MIGRATION_STARTED) {
-                        log.info("SwitchingHandler: Migration started at MAC:{} IP:{}",
-                                                        instPort.macAddress(),
-                                                        instPort.ipAddress());
-                    } else {
-                        log.info("SwitchingHandler: Instance port detected MAC:{} IP:{}",
-                                                        instPort.macAddress(),
-                                                        instPort.ipAddress());
-                    }
-
-                    eventExecutor.execute(() -> {
-
-                        if (!isRelevantHelper(event)) {
-                            return;
-                        }
-
-                        instPortDetected(instPort);
-
-                        Port osPort = osNetworkService.port(instPort.portId());
-
-                        if (osPort != null) {
-                            setPortBlockRules(instPort, !osPort.isAdminStateUp());
-                        }
-                    });
-
+                    eventExecutor.execute(() ->
+                                    processInstanceDetection(event, instPort));
                     break;
                 case OPENSTACK_INSTANCE_TERMINATED:
-                    log.info("SwitchingHandler: Instance port terminated MAC:{} IP:{}",
-                                                        instPort.macAddress(),
-                                                        instPort.ipAddress());
-                    eventExecutor.execute(() -> {
-
-                        if (!isRelevantHelper(event)) {
-                            return;
-                        }
-
-                        removeVportRules(instPort);
-                    });
-
+                    eventExecutor.execute(() ->
+                                    processInstanceTermination(event, instPort));
                     break;
                 case OPENSTACK_INSTANCE_PORT_VANISHED:
-                    log.info("SwitchingHandler: Instance port vanished MAC:{} IP:{}",
-                                                        instPort.macAddress(),
-                                                        instPort.ipAddress());
-
-                    eventExecutor.execute(() -> {
-
-                        if (!isRelevantHelper(event)) {
-                            return;
-                        }
-
-                        instPortRemoved(instPort);
-
-                        Port osPort = osNetworkService.port(instPort.portId());
-
-                        if (osPort != null) {
-                            setPortBlockRules(instPort, false);
-                        }
-                    });
-
+                    eventExecutor.execute(() ->
+                                    processInstanceRemoval(event, instPort));
                     break;
                 case OPENSTACK_INSTANCE_MIGRATION_ENDED:
-                    log.info("SwitchingHandler: Migration finished for MAC:{} IP:{}",
-                                                        instPort.macAddress(),
-                                                        instPort.ipAddress());
-
-                    InstancePort revisedInstPort = swapStaleLocation(instPort);
-                    eventExecutor.execute(() -> {
-
-                        if (!isRelevantHelper(event)) {
-                            return;
-                        }
-
-                        removeVportRules(revisedInstPort);
-                    });
-
+                    eventExecutor.execute(() ->
+                                    processInstanceMigrationEnd(event, instPort));
                     break;
                 default:
                     break;
             }
         }
 
+        private void processInstanceDetection(InstancePortEvent event,
+                                              InstancePort instPort) {
+            if (!isRelevantHelper(event)) {
+                return;
+            }
+
+            if (event.type() == OPENSTACK_INSTANCE_MIGRATION_STARTED) {
+                log.info("SwitchingHandler: Migration started at MAC:{} IP:{}",
+                                                        instPort.macAddress(),
+                                                        instPort.ipAddress());
+            } else {
+                log.info("SwitchingHandler: Instance port detected MAC:{} IP:{}",
+                                                        instPort.macAddress(),
+                                                        instPort.ipAddress());
+            }
+
+            instPortDetected(instPort);
+
+            Port osPort = osNetworkService.port(instPort.portId());
+
+            if (osPort != null) {
+                setPortBlockRules(instPort, !osPort.isAdminStateUp());
+            }
+        }
+
+        private void processInstanceTermination(InstancePortEvent event,
+                                                InstancePort instPort) {
+            if (!isRelevantHelper(event)) {
+                return;
+            }
+
+            log.info("SwitchingHandler: Instance port terminated MAC:{} IP:{}",
+                                                        instPort.macAddress(),
+                                                        instPort.ipAddress());
+
+            removeVportRules(instPort);
+        }
+
+        private void processInstanceRemoval(InstancePortEvent event,
+                                            InstancePort instPort) {
+            if (!isRelevantHelper(event)) {
+                return;
+            }
+
+            log.info("SwitchingHandler: Instance port vanished MAC:{} IP:{}",
+                                                        instPort.macAddress(),
+                                                        instPort.ipAddress());
+
+            instPortRemoved(instPort);
+
+            Port osPort = osNetworkService.port(instPort.portId());
+
+            if (osPort != null) {
+                setPortBlockRules(instPort, false);
+            }
+        }
+
+        private void processInstanceMigrationEnd(InstancePortEvent event,
+                                                 InstancePort instPort) {
+            if (!isRelevantHelper(event)) {
+                return;
+            }
+
+            log.info("SwitchingHandler: Migration finished for MAC:{} IP:{}",
+                                                        instPort.macAddress(),
+                                                        instPort.ipAddress());
+
+            InstancePort revisedInstPort = swapStaleLocation(instPort);
+
+            removeVportRules(revisedInstPort);
+        }
+
+        /**
+         * Configures L2 forwarding rules.
+         * Currently, SONA supports Flat, VXLAN and VLAN modes.
+         *
+         * @param instPort instance port object
+         * @param install install flag, add the rule if true, remove it otherwise
+         */
+        private void setNetworkRules(InstancePort instPort, boolean install) {
+            Network network = osNetworkService.network(instPort.networkId());
+            NetworkType type = network.getNetworkType();
+
+            switch (type) {
+                case VXLAN:
+                    setNetworkRulesForVxlan(instPort, install);
+                    break;
+                case VLAN:
+                    setNetworkRulesForVlan(instPort, install);
+                    break;
+                case FLAT:
+                    setNetworkRulesForFlat(instPort, install);
+                    break;
+                default:
+                    log.warn("Unsupported network tunnel type {}", type.name());
+                    break;
+            }
+        }
+
+        private void setNetworkRulesForVxlan(InstancePort instPort, boolean install) {
+            setTunnelTagIpFlowRules(instPort, install);
+            setForwardingRulesForVxlan(instPort, install);
+
+            if (ARP_BROADCAST_MODE.equals(getArpMode())) {
+                setTunnelTagArpFlowRules(instPort, install);
+            }
+        }
+
+        private void setNetworkRulesForVlan(InstancePort instPort, boolean install) {
+            setVlanTagIpFlowRules(instPort, install);
+            setForwardingRulesForVlan(instPort, install);
+
+            if (ARP_BROADCAST_MODE.equals(getArpMode())) {
+                setVlanTagArpFlowRules(instPort, install);
+            }
+        }
+
+        private void setNetworkRulesForFlat(InstancePort instPort, boolean install) {
+            setFlatJumpRules(instPort, install);
+            setDownstreamRulesForFlat(instPort, install);
+            setUpstreamRulesForFlat(instPort, install);
+        }
+
+        /**
+         * Removes virtual port related flow rules.
+         *
+         * @param instPort instance port
+         */
+        private void removeVportRules(InstancePort instPort) {
+            Network network = osNetworkService.network(instPort.networkId());
+            NetworkType type = network.getNetworkType();
+
+            switch (type) {
+                case VXLAN:
+                    removeVportRulesForVxlan(instPort);
+                    break;
+                case VLAN:
+                    removeVportRulesForVlan(instPort);
+                    break;
+                case FLAT:
+                    removeVportRulesForFlat(instPort);
+                    break;
+                default:
+                    log.warn("Unsupported network type {}", type.name());
+                    break;
+            }
+        }
+
+        private void removeVportRulesForVxlan(InstancePort instPort) {
+            setTunnelTagIpFlowRules(instPort, false);
+
+            if (ARP_BROADCAST_MODE.equals(getArpMode())) {
+                setTunnelTagArpFlowRules(instPort, false);
+            }
+        }
+
+        private void removeVportRulesForVlan(InstancePort instPort) {
+            setVlanTagIpFlowRules(instPort, false);
+
+            if (ARP_BROADCAST_MODE.equals(getArpMode())) {
+                setVlanTagArpFlowRules(instPort, false);
+            }
+        }
+
+        private void removeVportRulesForFlat(InstancePort instPort) {
+            setFlatJumpRules(instPort, false);
+            setUpstreamRulesForFlat(instPort, false);
+            setDownstreamRulesForFlat(instPort, false);
+        }
+
         private void instPortDetected(InstancePort instPort) {
             setNetworkRules(instPort, true);
             // TODO add something else if needed
@@ -816,64 +850,66 @@
 
         @Override
         public void event(OpenstackNetworkEvent event) {
-
-            boolean isNwAdminStateUp = event.subject().isAdminStateUp();
-            boolean isPortAdminStateUp = event.port().isAdminStateUp();
-
-            String portId = event.port().getId();
-
             switch (event.type()) {
                 case OPENSTACK_NETWORK_CREATED:
                 case OPENSTACK_NETWORK_UPDATED:
-                    eventExecutor.execute(() -> {
-
-                        if (!isRelevantHelper()) {
-                            return;
-                        }
-
-                        setNetworkBlockRules(event.subject(), !isNwAdminStateUp);
-                    });
+                    eventExecutor.execute(() -> processNetworkAddition(event));
                     break;
                 case OPENSTACK_NETWORK_REMOVED:
-                    eventExecutor.execute(() -> {
-
-                        if (!isRelevantHelper()) {
-                            return;
-                        }
-
-                        setNetworkBlockRules(event.subject(), false);
-                    });
+                    eventExecutor.execute(() -> processNetworkRemoval(event));
                     break;
                 case OPENSTACK_PORT_CREATED:
                 case OPENSTACK_PORT_UPDATED:
-                    eventExecutor.execute(() -> {
-
-                        if (!isRelevantHelper()) {
-                            return;
-                        }
-
-                        InstancePort instPort = instancePortService.instancePort(portId);
-                        if (instPort != null) {
-                            setPortBlockRules(instPort, !isPortAdminStateUp);
-                        }
-                    });
+                    eventExecutor.execute(() -> processPortAddition(event));
                     break;
                 case OPENSTACK_PORT_REMOVED:
-                    eventExecutor.execute(() -> {
-
-                        if (!isRelevantHelper()) {
-                            return;
-                        }
-
-                        InstancePort instPort = instancePortService.instancePort(portId);
-                        if (instPort != null) {
-                            setPortBlockRules(instPort, false);
-                        }
-                    });
+                    eventExecutor.execute(() -> processPortRemoval(event));
                     break;
                 default:
                     break;
             }
         }
+
+        private void processNetworkAddition(OpenstackNetworkEvent event) {
+            if (!isRelevantHelper()) {
+                return;
+            }
+
+            boolean isNwAdminStateUp = event.subject().isAdminStateUp();
+            setNetworkBlockRules(event.subject(), !isNwAdminStateUp);
+        }
+
+        private void processNetworkRemoval(OpenstackNetworkEvent event) {
+            if (!isRelevantHelper()) {
+                return;
+            }
+
+            setNetworkBlockRules(event.subject(), false);
+        }
+
+        private void processPortAddition(OpenstackNetworkEvent event) {
+            if (!isRelevantHelper()) {
+                return;
+            }
+
+            boolean isPortAdminStateUp = event.port().isAdminStateUp();
+            String portId = event.port().getId();
+            InstancePort instPort = instancePortService.instancePort(portId);
+            if (instPort != null) {
+                setPortBlockRules(instPort, !isPortAdminStateUp);
+            }
+        }
+
+        private void processPortRemoval(OpenstackNetworkEvent event) {
+            if (!isRelevantHelper()) {
+                return;
+            }
+
+            String portId = event.port().getId();
+            InstancePort instPort = instancePortService.instancePort(portId);
+            if (instPort != null) {
+                setPortBlockRules(instPort, false);
+            }
+        }
     }
 }