Code ReOrganization and Re-Architecture changes
[ovsdb.git] / neutron / src / main / java / org / opendaylight / ovsdb / neutron / provider / OF13ProviderManager.java
index 5176095f1b7febe1ac04c7043b1c3d3a4453aeb5..561039fae43859bba85a919ef3f86352af99684d 100644 (file)
@@ -20,12 +20,14 @@ import java.util.concurrent.Future;
 
 import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
 import org.opendaylight.controller.md.sal.common.api.data.DataModification;
+import org.opendaylight.controller.networkconfig.neutron.NeutronNetwork;
 import org.opendaylight.controller.sal.binding.api.data.DataBrokerService;
 import org.opendaylight.controller.sal.core.Node;
 import org.opendaylight.controller.sal.utils.HexEncode;
 import org.opendaylight.controller.sal.utils.ServiceHelper;
 import org.opendaylight.controller.sal.utils.Status;
 import org.opendaylight.controller.sal.utils.StatusCode;
+import org.opendaylight.controller.switchmanager.ISwitchManager;
 import org.opendaylight.ovsdb.lib.notation.OvsDBMap;
 import org.opendaylight.ovsdb.lib.notation.OvsDBSet;
 import org.opendaylight.ovsdb.lib.notation.UUID;
@@ -45,6 +47,7 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.DecNwTtlCaseBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.DropActionCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.OutputActionCase;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.OutputActionCaseBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetFieldCaseBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetNwDstActionCaseBuilder;
@@ -73,8 +76,10 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.ta
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Instructions;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.InstructionsBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.ApplyActionsCase;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.ApplyActionsCaseBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.GoToTableCaseBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.apply.actions._case.ApplyActionsBuilder;
@@ -167,7 +172,7 @@ class OF13ProviderManager extends ProviderNetworkManager {
             String bridgeUUID = null;
             String tunnelBridgeName = AdminConfigManager.getManager().getIntegrationBridgeName();
             OVSDBConfigService ovsdbTable = (OVSDBConfigService)ServiceHelper.getGlobalInstance(OVSDBConfigService.class, this);
-            Map<String, org.opendaylight.ovsdb.lib.table.internal.Table<?>> bridgeTable = ovsdbTable.getRows(node, Bridge.NAME.getName());
+            Map<String, org.opendaylight.ovsdb.lib.table.Table<?>> bridgeTable = ovsdbTable.getRows(node, Bridge.NAME.getName());
             if (bridgeTable != null) {
                 for (String uuid : bridgeTable.keySet()) {
                     Bridge bridge = (Bridge)bridgeTable.get(uuid);
@@ -234,16 +239,7 @@ class OF13ProviderManager extends ProviderNetworkManager {
         }
     }
 
-    private void programLocalIngressTunnelBridgeRules(Node node, Long dpid, String segmentationId, String attachedMac, long tunnelOFPort, long localPort) {
-        /*
-         * Table(0) Rule #2
-         * ----------------
-         * Match: Ingress Port, Tunnel ID
-         * Action: GOTO Local Table (10)
-         */
-
-         writeTunnelIn(dpid, TABLE_0_DEFAULT_INGRESS, TABLE_2_LOCAL_FORWARD, segmentationId, tunnelOFPort);
-
+    private void programLocalBridgeRules(Node node, Long dpid, String segmentationId, String attachedMac, long localPort) {
          /*
          * Table(0) Rule #3
          * ----------------
@@ -261,93 +257,152 @@ class OF13ProviderManager extends ProviderNetworkManager {
          */
 
          writeDropSrcIface(dpid, localPort);
-    }
 
-    private void programRemoteEgressTunnelBridgeRules(Node node, Long dpid, String segmentationId, String attachedMac, long tunnelOFPort, long localPort) {
-        /*
-         * Table(1) Rule #1
-         * ----------------
-         * Match: Drop any remaining Ingress Local VM Packets
-         * Action: Drop w/ a low priority
-         * -------------------------------------------
-         * table=1,tun_id=0x5,dl_dst=00:00:00:00:00:08 \
-         * actions=output:11,goto_table:2
-         */
-
-        writeTunnelOut(dpid, TABLE_1_ISOLATE_TENANT, TABLE_2_LOCAL_FORWARD, segmentationId, tunnelOFPort, attachedMac);
+         /*
+          * Table(2) Rule #1
+          * ----------------
+          * Match: Match TunID and Destination DL/dMAC Addr
+          * Action: Output Port
+          * table=2,tun_id=0x5,dl_dst=00:00:00:00:00:01 actions=output:2
+          */
 
-        /*
-         * Table(1) Rule #2
-         * ----------------
-         * Match: Match Tunnel ID and L2 ::::FF:FF Flooding
-         * Action: Flood to selected destination TEPs
-         * -------------------------------------------
-         * table=1,priority=16384,tun_id=0x5,dl_dst=ff:ff:ff:ff:ff:ff \
-         * actions=output:10,output:11,goto_table:2
-         */
+          writeLocalUcastOut(dpid, TABLE_2_LOCAL_FORWARD, segmentationId, localPort, attachedMac);
 
-        writeTunnelFloodOut(dpid, TABLE_1_ISOLATE_TENANT, TABLE_2_LOCAL_FORWARD, segmentationId, tunnelOFPort);
+         /*
+          * Table(2) Rule #2
+          * ----------------
+          * Match: Tunnel ID and dMAC (::::FF:FF)
+          * table=2,priority=16384,tun_id=0x5,dl_dst=ff:ff:ff:ff:ff:ff \
+          * actions=output:2,3,4,5
+          */
+
+          writeLocalBcastOut(dpid, TABLE_2_LOCAL_FORWARD, segmentationId, localPort);
+
+          /*
+           * TODO : Optimize the following 2 writes to be restricted only for the very first port known in a segment.
+           */
+          /*
+           * Table(1) Rule #3
+           * ----------------
+           * Match:  Any remaining Ingress Local VM Packets
+           * Action: Drop w/ a low priority
+           * -------------------------------------------
+           * table=1,priority=8192,tun_id=0x5 actions=goto_table:2
+           */
+
+           writeTunnelMiss(dpid, TABLE_1_ISOLATE_TENANT, TABLE_2_LOCAL_FORWARD, segmentationId);
+
+          /*
+           * Table(2) Rule #3
+           * ----------------
+           * Match: Any Remaining Flows w/a TunID
+           * Action: Drop w/ a low priority
+           * table=2,priority=8192,tun_id=0x5 actions=drop
+           */
+
+           writeLocalTableMiss(dpid, TABLE_2_LOCAL_FORWARD, segmentationId);
+    }
 
+    private void programLocalIngressTunnelBridgeRules(Node node, Long dpid, String segmentationId, String attachedMac, long tunnelOFPort, long localPort) {
         /*
-         * Table(2) Rule #1
+         * Table(0) Rule #2
          * ----------------
-         * Match: Match TunID and Destination DL/dMAC Addr
-         * Action: Output Port
-         * table=2,tun_id=0x5,dl_dst=00:00:00:00:00:01 actions=output:2
+         * Match: Ingress Port, Tunnel ID
+         * Action: GOTO Local Table (10)
          */
 
-         writeLocalUcastOut(dpid, TABLE_2_LOCAL_FORWARD, segmentationId, localPort, attachedMac);
+         writeTunnelIn(dpid, TABLE_0_DEFAULT_INGRESS, TABLE_2_LOCAL_FORWARD, segmentationId, tunnelOFPort);
 
-        /*
-         * Table(2) Rule #2
-         * ----------------
-         * Match: Tunnel ID and dMAC (::::FF:FF)
-         * table=2,priority=16384,tun_id=0x5,dl_dst=ff:ff:ff:ff:ff:ff \
-         * actions=output:2,3,4,5
-         */
+         /*
+          * Table(1) Rule #2
+          * ----------------
+          * Match: Match Tunnel ID and L2 ::::FF:FF Flooding
+          * Action: Flood to selected destination TEPs
+          * -------------------------------------------
+          * table=1,priority=16384,tun_id=0x5,dl_dst=ff:ff:ff:ff:ff:ff \
+          * actions=output:10,output:11,goto_table:2
+          */
+
+         writeTunnelFloodOut(dpid, TABLE_1_ISOLATE_TENANT, TABLE_2_LOCAL_FORWARD, segmentationId, tunnelOFPort);
 
-         writeLocalBcastOut(dpid, TABLE_2_LOCAL_FORWARD, segmentationId, localPort);
     }
 
-    private void programFloodEgressTunnelBridgeRules(Long dpid, String segmentationId) {
+    private void programRemoteEgressTunnelBridgeRules(Node node, Long dpid, String segmentationId, String attachedMac, long tunnelOFPort, long localPort) {
         /*
-         * Table(1) Rule #3
+         * Table(1) Rule #1
          * ----------------
-         * Match:  Any remaining Ingress Local VM Packets
+         * Match: Drop any remaining Ingress Local VM Packets
          * Action: Drop w/ a low priority
          * -------------------------------------------
-         * table=1,priority=8192,tun_id=0x5 actions=goto_table:2
-         */
-
-         writeTunnelMiss(dpid, TABLE_1_ISOLATE_TENANT, TABLE_2_LOCAL_FORWARD, segmentationId);
-
-        /*
-         * Table(2) Rule #3
-         * ----------------
-         * Match: Any Remaining Flows w/a TunID
-         * Action: Drop w/ a low priority
-         * table=2,priority=8192,tun_id=0x5 actions=drop
+         * table=1,tun_id=0x5,dl_dst=00:00:00:00:00:08 \
+         * actions=output:11,goto_table:2
          */
 
-         writeLocalTableMiss(dpid, TABLE_2_LOCAL_FORWARD, segmentationId);
+        writeTunnelOut(dpid, TABLE_1_ISOLATE_TENANT, TABLE_2_LOCAL_FORWARD, segmentationId, tunnelOFPort, attachedMac);
     }
 
-    private void programTunnelRules (String tunnelType, String segmentationId, InetAddress dst, Node node,
-            Interface intf, boolean local) {
+    private Long getIntegrationBridgeOFDPID (Node node) {
         try {
-
             String bridgeName = AdminConfigManager.getManager().getIntegrationBridgeName();
             String brIntId = this.getInternalBridgeUUID(node, bridgeName);
             if (brIntId == null) {
                 logger.error("Unable to spot Bridge Identifier for {} in {}", bridgeName, node);
-                return;
+                return 0L;
             }
 
             OVSDBConfigService ovsdbTable = (OVSDBConfigService) ServiceHelper.getGlobalInstance(OVSDBConfigService.class, this);
             Bridge bridge = (Bridge) ovsdbTable.getRow(node, Bridge.NAME.getName(), brIntId);
             Set<String> dpids = bridge.getDatapath_id();
-            if (dpids == null || dpids.size() == 0) return;
-            Long dpid = Long.valueOf(HexEncode.stringToLong((String) dpids.toArray()[0]));
+            if (dpids == null || dpids.size() == 0) return 0L;
+            return Long.valueOf(HexEncode.stringToLong((String) dpids.toArray()[0]));
+        } catch (Exception e) {
+            logger.error("Error finding Integration Bridge's OF DPID", e);
+            return 0L;
+        }
+    }
+    private void programLocalRules (String tunnelType, String segmentationId, Node node, Interface intf) {
+        try {
+            Long dpid = this.getIntegrationBridgeOFDPID(node);
+            if (dpid == 0L) {
+                logger.debug("Openflow Datapath-ID not set for the integration bridge in {}", node);
+                return;
+            }
+
+            Set<BigInteger> of_ports = intf.getOfport();
+            if (of_ports == null || of_ports.size() <= 0) {
+                logger.error("Could NOT Identify OF value for port {} on {}", intf.getName(), node);
+                return;
+            }
+            long localPort = ((BigInteger)of_ports.toArray()[0]).longValue();
+
+            Map<String, String> externalIds = intf.getExternal_ids();
+            if (externalIds == null) {
+                logger.error("No external_ids seen in {}", intf);
+                return;
+            }
+
+            String attachedMac = externalIds.get(TenantNetworkManager.EXTERNAL_ID_VM_MAC);
+            if (attachedMac == null) {
+                logger.error("No AttachedMac seen in {}", intf);
+                return;
+            }
+
+            programLocalBridgeRules(node, dpid, segmentationId, attachedMac, localPort);
+        } catch (Exception e) {
+            logger.error("Exception in programming Local Rules for "+intf+" on "+node, e);
+        }
+    }
+
+    private void programTunnelRules (String tunnelType, String segmentationId, InetAddress dst, Node node,
+            Interface intf, boolean local) {
+        try {
+
+            Long dpid = this.getIntegrationBridgeOFDPID(node);
+            if (dpid == 0L) {
+                logger.debug("Openflow Datapath-ID not set for the integration bridge in {}", node);
+                return;
+            }
+            OVSDBConfigService ovsdbTable = (OVSDBConfigService) ServiceHelper.getGlobalInstance(OVSDBConfigService.class, this);
 
             Set<BigInteger> of_ports = intf.getOfport();
             if (of_ports == null || of_ports.size() <= 0) {
@@ -368,9 +423,9 @@ class OF13ProviderManager extends ProviderNetworkManager {
                 return;
             }
 
-            Map<String, org.opendaylight.ovsdb.lib.table.internal.Table<?>> intfs = ovsdbTable.getRows(node, Interface.NAME.getName());
+            Map<String, org.opendaylight.ovsdb.lib.table.Table<?>> intfs = ovsdbTable.getRows(node, Interface.NAME.getName());
             if (intfs != null) {
-                for (org.opendaylight.ovsdb.lib.table.internal.Table<?> row : intfs.values()) {
+                for (org.opendaylight.ovsdb.lib.table.Table<?> row : intfs.values()) {
                     Interface tunIntf = (Interface)row;
                     if (tunIntf.getName().equals(this.getTunnelName(tunnelType, dst))) {
                         of_ports = tunIntf.getOfport();
@@ -390,7 +445,6 @@ class OF13ProviderManager extends ProviderNetworkManager {
                             programRemoteEgressTunnelBridgeRules(node, dpid, segmentationId, attachedMac, tunnelOFPort, localPort);
                         }
                         programLocalIngressTunnelBridgeRules(node, dpid, segmentationId, attachedMac, tunnelOFPort, localPort);
-                        programFloodEgressTunnelBridgeRules(dpid, segmentationId);
                         return;
                     }
                 }
@@ -402,18 +456,43 @@ class OF13ProviderManager extends ProviderNetworkManager {
 
     @Override
     public Status handleInterfaceUpdate(String tunnelType, String tunnelKey, Node srcNode, Interface intf) {
-        Status status = getTunnelReadinessStatus(srcNode, tunnelKey);
-        if (!status.isSuccess()) return status;
+        ISwitchManager switchManager = (ISwitchManager) ServiceHelper.getInstance(ISwitchManager.class, "default", this);
+        if (switchManager == null) {
+            logger.error("Unable to identify SwitchManager");
+        } else {
+            Long dpid = this.getIntegrationBridgeOFDPID(srcNode);
+            if (dpid == 0L) {
+                logger.debug("Openflow Datapath-ID not set for the integration bridge in {}", srcNode);
+                return new Status(StatusCode.NOTFOUND);
+            }
+            Set<Node> ofNodes = switchManager.getNodes();
+            boolean ofNodeFound = false;
+            if (ofNodes != null) {
+                for (Node ofNode : ofNodes) {
+                    if (ofNode.toString().contains(dpid+"")) {
+                        logger.debug("Identified the Openflow node via toString {}", ofNode);
+                        ofNodeFound = true;
+                        break;
+                    }
+                }
+            } else {
+                logger.error("Unable to find any Node from SwitchManager");
+            }
+            if (!ofNodeFound) {
+                logger.error("Unable to find OF Node for {} with update {} on node {}", dpid, intf, srcNode);
+                return new Status(StatusCode.NOTFOUND);
+            }
+        }
 
         IConnectionServiceInternal connectionService = (IConnectionServiceInternal)ServiceHelper.getGlobalInstance(IConnectionServiceInternal.class, this);
         List<Node> nodes = connectionService.getNodes();
         nodes.remove(srcNode);
+        this.programLocalRules(tunnelType, tunnelKey, srcNode, intf);
+
         for (Node dstNode : nodes) {
-            status = getTunnelReadinessStatus(dstNode, tunnelKey);
-            if (!status.isSuccess()) continue;
             InetAddress src = AdminConfigManager.getManager().getTunnelEndPoint(srcNode);
             InetAddress dst = AdminConfigManager.getManager().getTunnelEndPoint(dstNode);
-            status = addTunnelPort(srcNode, tunnelType, src, dst);
+            Status status = addTunnelPort(srcNode, tunnelType, src, dst);
             if (status.isSuccess()) {
                 this.programTunnelRules(tunnelType, tunnelKey, dst, srcNode, intf, true);
             }
@@ -422,18 +501,47 @@ class OF13ProviderManager extends ProviderNetworkManager {
                 this.programTunnelRules(tunnelType, tunnelKey, src, dstNode, intf, false);
             }
         }
+
         return new Status(StatusCode.SUCCESS);
     }
 
+    private Status triggerInterfaceUpdates(Node node) {
+        try {
+            OVSDBConfigService ovsdbTable = (OVSDBConfigService)ServiceHelper.getGlobalInstance(OVSDBConfigService.class, this);
+            Map<String, org.opendaylight.ovsdb.lib.table.Table<?>> intfs = ovsdbTable.getRows(node, Interface.NAME.getName());
+            if (intfs != null) {
+                for (org.opendaylight.ovsdb.lib.table.Table<?> row : intfs.values()) {
+                    Interface intf = (Interface)row;
+                    NeutronNetwork network = TenantNetworkManager.getManager().getTenantNetworkForInterface(intf);
+                    logger.debug("Trigger Interface update for {}", intf);
+                    if (network != null) {
+                        this.handleInterfaceUpdate(network.getProviderNetworkType(), network.getProviderSegmentationID(), node, intf);
+                    }
+                }
+            }
+        } catch (Exception e) {
+            logger.error("Error Triggering the lost interface updates for "+ node, e);
+            return new Status(StatusCode.INTERNALERROR, e.getLocalizedMessage());
+        }
+        return new Status(StatusCode.SUCCESS);
+    }
     @Override
     public Status handleInterfaceUpdate(String tunnelType, String tunnelKey) {
         // TODO Auto-generated method stub
         return null;
     }
 
+    @Override
+    public Status handleInterfaceDelete(String tunnelType, String tunnelKey, Node source, Interface intf,
+            boolean isLastInstanceOnNode) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
     @Override
     public void initializeFlowRules(Node node) {
         this.initializeFlowRules(node, AdminConfigManager.getManager().getIntegrationBridgeName());
+        this.triggerInterfaceUpdates(node);
     }
 
     /**
@@ -441,40 +549,20 @@ class OF13ProviderManager extends ProviderNetworkManager {
      * @param bridgeName
      */
     private void initializeFlowRules(Node node, String bridgeName) {
-
-        // TODO : 3 second sleep hack is to make sure the OF connection is established.
-        // Correct fix is to check the MD-SAL inventory before proceeding and listen
-        // to Inventory update for processing.
-        try {
-            Thread.sleep(3000);
-        } catch (InterruptedException e1) {
-            logger.error("Sleep Thread interrupted ",e1);
-        }
-
-        String brIntId = this.getInternalBridgeUUID(node, bridgeName);
-        if (brIntId == null) {
-            logger.error("Failed to initialize Flow Rules for {}", node);
+        Long dpid = this.getIntegrationBridgeOFDPID(node);
+        if (dpid == 0L) {
+            logger.debug("Openflow Datapath-ID not set for the integration bridge in {}", node);
             return;
         }
 
-        try {
-            OVSDBConfigService ovsdbTable = (OVSDBConfigService) ServiceHelper.getGlobalInstance(OVSDBConfigService.class, this);
-            Bridge bridge = (Bridge) ovsdbTable.getRow(node, Bridge.NAME.getName(), brIntId);
-            Set<String> dpids = bridge.getDatapath_id();
-            if (dpids == null || dpids.size() == 0) return;
-            Long dpid = Long.valueOf(HexEncode.stringToLong((String) dpids.toArray()[0]));
-
-            /*
-             * Table(0) Rule #1
-             * ----------------
-             * Match: LLDP (0x88CCL)
-             * Action: Packet_In to Controller Reserved Port
-             */
+        /*
+         * Table(0) Rule #1
+         * ----------------
+         * Match: LLDP (0x88CCL)
+         * Action: Packet_In to Controller Reserved Port
+         */
 
-             writeLLDPRule(dpid);
-        } catch (Exception e) {
-            logger.error("Failed to initialize Flow Rules for " + node.toString()+ " Bridge "+bridgeName, e);
-        }
+         writeLLDPRule(dpid);
     }
 
     /*
@@ -506,6 +594,8 @@ class OF13ProviderManager extends ProviderNetworkManager {
 
         // Call the InstructionBuilder Methods Containing Actions
         createSendToControllerInstructions(ib);
+        ib.setOrder(0);
+        ib.setKey(new InstructionKey(0));
         instructions.add(ib.build());
 
         // Add InstructionBuilder to the Instruction(s)Builder List
@@ -514,12 +604,13 @@ class OF13ProviderManager extends ProviderNetworkManager {
         // Add InstructionsBuilder to FlowBuilder
         flowBuilder.setInstructions(isb.build());
 
-        flowBuilder.setId(new FlowId("10"));
-        FlowKey key = new FlowKey(new FlowId(String.valueOf((long) 110)));
+        String flowId = "LLDP";
+        flowBuilder.setId(new FlowId(flowId));
+        FlowKey key = new FlowKey(new FlowId(flowId));
         flowBuilder.setBarrier(true);
         flowBuilder.setTableId((short) 0);
         flowBuilder.setKey(key);
-        flowBuilder.setFlowName("LLDP_" + nodeName);
+        flowBuilder.setFlowName(flowId);
         flowBuilder.setHardTimeout(0);
         flowBuilder.setIdleTimeout(0);
         writeFlow(flowBuilder, nodeBuilder);
@@ -554,6 +645,8 @@ class OF13ProviderManager extends ProviderNetworkManager {
 
         // Call the InstructionBuilder Methods Containing Actions
         createGotoTableInstructions(ib, goToTableId);
+        ib.setOrder(0);
+        ib.setKey(new InstructionKey(0));
         instructions.add(ib.build());
 
         // Add InstructionBuilder to the Instruction(s)Builder List
@@ -562,13 +655,15 @@ class OF13ProviderManager extends ProviderNetworkManager {
         // Add InstructionsBuilder to FlowBuilder
         flowBuilder.setInstructions(isb.build());
 
+        String flowId = "TunnelIn_"+segmentationId+"_"+ofPort;
         // Add Flow Attributes
-        flowBuilder.setId(new FlowId("20"));
-        FlowKey key = new FlowKey(new FlowId(String.valueOf((long) 120)));
+        flowBuilder.setId(new FlowId(flowId));
+        FlowKey key = new FlowKey(new FlowId(flowId));
+        flowBuilder.setStrict(true);
         flowBuilder.setBarrier(false);
         flowBuilder.setTableId(writeTable);
         flowBuilder.setKey(key);
-        flowBuilder.setFlowName("TUNIN_" + nodeName);
+        flowBuilder.setFlowName(flowId);
         flowBuilder.setHardTimeout(0);
         flowBuilder.setIdleTimeout(0);
         writeFlow(flowBuilder, nodeBuilder);
@@ -595,6 +690,18 @@ class OF13ProviderManager extends ProviderNetworkManager {
         // TODO Broken In_Port Match
         flowBuilder.setMatch(createInPortMatch(matchBuilder, dpidLong, inPort).build());
 
+        String flowId = "LocalMac_"+segmentationId+"_"+inPort+"_"+attachedMac;
+        // Add Flow Attributes
+        flowBuilder.setId(new FlowId(flowId));
+        FlowKey key = new FlowKey(new FlowId(flowId));
+        flowBuilder.setStrict(true);
+        flowBuilder.setBarrier(false);
+        flowBuilder.setTableId(writeTable);
+        flowBuilder.setKey(key);
+        flowBuilder.setFlowName(flowId);
+        flowBuilder.setHardTimeout(0);
+        flowBuilder.setIdleTimeout(0);
+
         // Instantiate the Builders for the OF Actions and Instructions
         InstructionBuilder ib = new InstructionBuilder();
         InstructionsBuilder isb = new InstructionsBuilder();
@@ -604,9 +711,13 @@ class OF13ProviderManager extends ProviderNetworkManager {
 
         // GOTO Instuctions Need to be added first to the List
         createGotoTableInstructions(ib, goToTableId);
+        ib.setOrder(0);
+        ib.setKey(new InstructionKey(0));
         instructions.add(ib.build());
         // TODO Broken SetTunID
         createSetTunnelIdInstructions(ib, new BigInteger(segmentationId));
+        ib.setOrder(1);
+        ib.setKey(new InstructionKey(1));
         instructions.add(ib.build());
 
         // Add InstructionBuilder to the Instruction(s)Builder List
@@ -615,15 +726,6 @@ class OF13ProviderManager extends ProviderNetworkManager {
         // Add InstructionsBuilder to FlowBuilder
         flowBuilder.setInstructions(isb.build());
 
-        // Add Flow Attributes
-        flowBuilder.setId(new FlowId("30"));
-        FlowKey key = new FlowKey(new FlowId(String.valueOf((long) 130)));
-        flowBuilder.setBarrier(false);
-        flowBuilder.setTableId(writeTable);
-        flowBuilder.setKey(key);
-        flowBuilder.setFlowName("LOCALSMAC_" + nodeName);
-        flowBuilder.setHardTimeout(0);
-        flowBuilder.setIdleTimeout(0);
         writeFlow(flowBuilder, nodeBuilder);
     }
 
@@ -655,6 +757,8 @@ class OF13ProviderManager extends ProviderNetworkManager {
 
         // Call the InstructionBuilder Methods Containing Actions
         createDropInstructions(ib);
+        ib.setOrder(0);
+        ib.setKey(new InstructionKey(0));
         instructions.add(ib.build());
 
         // Add InstructionBuilder to the Instruction(s)Builder List
@@ -663,13 +767,15 @@ class OF13ProviderManager extends ProviderNetworkManager {
         // Add InstructionsBuilder to FlowBuilder
         flowBuilder.setInstructions(isb.build());
 
+        String flowId = "DropFilter_"+inPort;
         // Add Flow Attributes
-        flowBuilder.setId(new FlowId("40"));
-        FlowKey key = new FlowKey(new FlowId(String.valueOf((long) 140)));
+        flowBuilder.setId(new FlowId(flowId));
+        FlowKey key = new FlowKey(new FlowId(flowId));
+        flowBuilder.setStrict(true);
         flowBuilder.setBarrier(false);
         flowBuilder.setTableId((short) 0);
         flowBuilder.setKey(key);
-        flowBuilder.setFlowName("LOCALDROP_" + nodeName);
+        flowBuilder.setFlowName(flowId);
         flowBuilder.setPriority(8192);
         flowBuilder.setHardTimeout(0);
         flowBuilder.setIdleTimeout(0);
@@ -696,6 +802,17 @@ class OF13ProviderManager extends ProviderNetworkManager {
         flowBuilder.setMatch(createTunnelIDMatch(matchBuilder, new BigInteger(segmentationId)).build());
         flowBuilder.setMatch(createDestEthMatch(matchBuilder, new MacAddress(attachedMac), null).build());
 
+        String flowId = "TunnelOut_"+segmentationId+"_"+OFPortOut+"_"+attachedMac;
+        // Add Flow Attributes
+        flowBuilder.setId(new FlowId(flowId));
+        FlowKey key = new FlowKey(new FlowId(flowId));
+        flowBuilder.setStrict(true);
+        flowBuilder.setBarrier(false);
+        flowBuilder.setTableId(writeTable);
+        flowBuilder.setKey(key);
+        flowBuilder.setFlowName(flowId);
+        flowBuilder.setHardTimeout(0);
+        flowBuilder.setIdleTimeout(0);
         // Instantiate the Builders for the OF Actions and Instructions
         InstructionBuilder ib = new InstructionBuilder();
         InstructionsBuilder isb = new InstructionsBuilder();
@@ -705,9 +822,13 @@ class OF13ProviderManager extends ProviderNetworkManager {
 
         // GOTO Instuctions
         createGotoTableInstructions(ib, goToTableId);
+        ib.setOrder(0);
+        ib.setKey(new InstructionKey(0));
         instructions.add(ib.build());
         // Set the Output Port/Iface
         createOutputPortInstructions(ib, dpidLong, OFPortOut);
+        ib.setOrder(1);
+        ib.setKey(new InstructionKey(1));
         instructions.add(ib.build());
 
         // Add InstructionBuilder to the Instruction(s)Builder List
@@ -716,15 +837,6 @@ class OF13ProviderManager extends ProviderNetworkManager {
         // Add InstructionsBuilder to FlowBuilder
         flowBuilder.setInstructions(isb.build());
 
-        // Add Flow Attributes
-        flowBuilder.setId(new FlowId("50"));
-        FlowKey key = new FlowKey(new FlowId(String.valueOf((long) 150)));
-        flowBuilder.setBarrier(false);
-        flowBuilder.setTableId(writeTable);
-        flowBuilder.setKey(key);
-        flowBuilder.setFlowName("TUNOUT_" + nodeName);
-        flowBuilder.setHardTimeout(0);
-        flowBuilder.setIdleTimeout(0);
         writeFlow(flowBuilder, nodeBuilder);
     }
 
@@ -748,21 +860,42 @@ class OF13ProviderManager extends ProviderNetworkManager {
         // Match TunnelID
         flowBuilder.setMatch(createTunnelIDMatch(matchBuilder, new BigInteger(segmentationId)).build());
         // Match DMAC
-        byte[] mask = new byte[] { (byte) 1, 0, 0, 0, 0, 0 };
-        flowBuilder.setMatch(createDestEthMatch(matchBuilder, new MacAddress("01:00:00:00:00:00"), mask).build());
 
+        flowBuilder.setMatch(createDestEthMatch(matchBuilder, new MacAddress("01:00:00:00:00:00"), new MacAddress("01:00:00:00:00:00")).build());
+
+        String flowId = "TunnelFloodOut_"+segmentationId;
+        // Add Flow Attributes
+        flowBuilder.setId(new FlowId(flowId));
+        FlowKey key = new FlowKey(new FlowId(flowId));
+        flowBuilder.setBarrier(true);
+        flowBuilder.setTableId(writeTable);
+        flowBuilder.setKey(key);
+        flowBuilder.setPriority(16384);
+        flowBuilder.setFlowName(flowId);
+        flowBuilder.setHardTimeout(0);
+        flowBuilder.setIdleTimeout(0);
+
+        Flow flow = this.getFlow(flowBuilder, nodeBuilder);
         // Instantiate the Builders for the OF Actions and Instructions
         InstructionBuilder ib = new InstructionBuilder();
         InstructionsBuilder isb = new InstructionsBuilder();
-
-        // Instructions List Stores Individual Instructions
         List<Instruction> instructions = new ArrayList<Instruction>();
-
+        List<Instruction> existingInstructions = null;
+        if (flow != null) {
+            Instructions ins = flow.getInstructions();
+            if (ins != null) {
+                existingInstructions = ins.getInstruction();
+            }
+        }
         // GOTO Instuction
         createGotoTableInstructions(ib, localTable);
+        ib.setOrder(0);
+        ib.setKey(new InstructionKey(0));
         instructions.add(ib.build());
         // Set the Output Port/Iface
-        createOutputPortInstructions(ib, dpidLong, OFPortOut);
+        createOutputPortInstructions(ib, dpidLong, OFPortOut, existingInstructions);
+        ib.setOrder(1);
+        ib.setKey(new InstructionKey(1));
         instructions.add(ib.build());
 
         // Add InstructionBuilder to the Instruction(s)Builder List
@@ -771,16 +904,6 @@ class OF13ProviderManager extends ProviderNetworkManager {
         // Add InstructionsBuilder to FlowBuilder
         flowBuilder.setInstructions(isb.build());
 
-        // Add Flow Attributes
-        flowBuilder.setId(new FlowId("60"));
-        FlowKey key = new FlowKey(new FlowId(String.valueOf((long) 160)));
-        flowBuilder.setBarrier(true);
-        flowBuilder.setTableId(writeTable);
-        flowBuilder.setKey(key);
-        flowBuilder.setPriority(16384);
-        flowBuilder.setFlowName("TUNFLOODOUT_" + nodeName);
-        flowBuilder.setHardTimeout(0);
-        flowBuilder.setIdleTimeout(0);
         writeFlow(flowBuilder, nodeBuilder);
     }
 
@@ -811,6 +934,8 @@ class OF13ProviderManager extends ProviderNetworkManager {
 
         // Call the InstructionBuilder Methods Containing Actions
         createGotoTableInstructions(ib, goToTableId);
+        ib.setOrder(0);
+        ib.setKey(new InstructionKey(0));
         instructions.add(ib.build());
 
         // Add InstructionBuilder to the Instruction(s)Builder List
@@ -819,14 +944,16 @@ class OF13ProviderManager extends ProviderNetworkManager {
         // Add InstructionsBuilder to FlowBuilder
         flowBuilder.setInstructions(isb.build());
 
+        String flowId = "TunnelMiss_"+segmentationId;
         // Add Flow Attributes
-        flowBuilder.setId(new FlowId("70"));
-        FlowKey key = new FlowKey(new FlowId(String.valueOf((long) 170)));
+        flowBuilder.setId(new FlowId(flowId));
+        FlowKey key = new FlowKey(new FlowId(flowId));
+        flowBuilder.setStrict(true);
         flowBuilder.setBarrier(false);
         flowBuilder.setTableId(writeTable);
         flowBuilder.setKey(key);
         flowBuilder.setPriority(8192);
-        flowBuilder.setFlowName("TUNMISS_" + nodeName);
+        flowBuilder.setFlowName(flowId);
         flowBuilder.setHardTimeout(0);
         flowBuilder.setIdleTimeout(0);
         writeFlow(flowBuilder, nodeBuilder);
@@ -851,6 +978,18 @@ class OF13ProviderManager extends ProviderNetworkManager {
         flowBuilder.setMatch(createTunnelIDMatch(matchBuilder, new BigInteger(segmentationId)).build());
         flowBuilder.setMatch(createDestEthMatch(matchBuilder, new MacAddress(attachedMac), null).build());
 
+        String flowId = "UcastOut_"+segmentationId+"_"+localPort+"_"+attachedMac;
+        // Add Flow Attributes
+        flowBuilder.setId(new FlowId(flowId));
+        FlowKey key = new FlowKey(new FlowId(flowId));
+        flowBuilder.setStrict(true);
+        flowBuilder.setBarrier(false);
+        flowBuilder.setTableId(writeTable);
+        flowBuilder.setKey(key);
+        flowBuilder.setFlowName(flowId);
+        flowBuilder.setHardTimeout(0);
+        flowBuilder.setIdleTimeout(0);
+
         // Instantiate the Builders for the OF Actions and Instructions
         InstructionBuilder ib = new InstructionBuilder();
         InstructionsBuilder isb = new InstructionsBuilder();
@@ -860,6 +999,8 @@ class OF13ProviderManager extends ProviderNetworkManager {
 
         // Set the Output Port/Iface
         createOutputPortInstructions(ib, dpidLong, localPort);
+        ib.setOrder(0);
+        ib.setKey(new InstructionKey(0));
         instructions.add(ib.build());
 
         // Add InstructionBuilder to the Instruction(s)Builder List
@@ -867,16 +1008,6 @@ class OF13ProviderManager extends ProviderNetworkManager {
 
         // Add InstructionsBuilder to FlowBuilder
         flowBuilder.setInstructions(isb.build());
-
-        // Add Flow Attributes
-        flowBuilder.setId(new FlowId("80"));
-        FlowKey key = new FlowKey(new FlowId(String.valueOf((long) 180)));
-        flowBuilder.setBarrier(false);
-        flowBuilder.setTableId(writeTable);
-        flowBuilder.setKey(key);
-        flowBuilder.setFlowName("LOCALHOSTUCAST_" + nodeName);
-        flowBuilder.setHardTimeout(0);
-        flowBuilder.setIdleTimeout(0);
         writeFlow(flowBuilder, nodeBuilder);
     }
 
@@ -897,18 +1028,37 @@ class OF13ProviderManager extends ProviderNetworkManager {
 
         // Create the OF Match using MatchBuilder
         flowBuilder.setMatch(createTunnelIDMatch(matchBuilder, new BigInteger(segmentationId)).build());
-        byte[] mask = new byte[] { (byte) 1, 0, 0, 0, 0, 0 };
-        flowBuilder.setMatch(createDestEthMatch(matchBuilder, new MacAddress("01:00:00:00:00:00"), mask).build());
+        flowBuilder.setMatch(createDestEthMatch(matchBuilder, new MacAddress("01:00:00:00:00:00"), new MacAddress("01:00:00:00:00:00")).build());
 
+        String flowId = "BcastOut_"+segmentationId;
+        // Add Flow Attributes
+        flowBuilder.setId(new FlowId(flowId));
+        FlowKey key = new FlowKey(new FlowId(flowId));
+        flowBuilder.setStrict(true);
+        flowBuilder.setBarrier(false);
+        flowBuilder.setTableId(writeTable);
+        flowBuilder.setKey(key);
+        flowBuilder.setPriority(16384);
+        flowBuilder.setFlowName(flowId);
+        flowBuilder.setHardTimeout(0);
+        flowBuilder.setIdleTimeout(0);
+        Flow flow = this.getFlow(flowBuilder, nodeBuilder);
         // Instantiate the Builders for the OF Actions and Instructions
         InstructionBuilder ib = new InstructionBuilder();
         InstructionsBuilder isb = new InstructionsBuilder();
-
-        // Instructions List Stores Individual Instructions
         List<Instruction> instructions = new ArrayList<Instruction>();
+        List<Instruction> existingInstructions = null;
+        if (flow != null) {
+            Instructions ins = flow.getInstructions();
+            if (ins != null) {
+                existingInstructions = ins.getInstruction();
+            }
+        }
 
         // Broken OutPort TODO: localPort needs to be a list of Ports)
-        createOutputPortInstructions(ib, dpidLong, localPort);
+        createOutputPortInstructions(ib, dpidLong, localPort, existingInstructions);
+        ib.setOrder(0);
+        ib.setKey(new InstructionKey(0));
         instructions.add(ib.build());
 
         // Add InstructionBuilder to the Instruction(s)Builder List
@@ -917,16 +1067,6 @@ class OF13ProviderManager extends ProviderNetworkManager {
         // Add InstructionsBuilder to FlowBuilder
         flowBuilder.setInstructions(isb.build());
 
-        // Add Flow Attributes
-        flowBuilder.setId(new FlowId("90"));
-        FlowKey key = new FlowKey(new FlowId(String.valueOf((long) 190)));
-        flowBuilder.setBarrier(false);
-        flowBuilder.setTableId(writeTable);
-        flowBuilder.setKey(key);
-        flowBuilder.setPriority(16384);
-        flowBuilder.setFlowName("LOCALHOSTBCAST_" + nodeName);
-        flowBuilder.setHardTimeout(0);
-        flowBuilder.setIdleTimeout(0);
         writeFlow(flowBuilder, nodeBuilder);
     }
 
@@ -957,6 +1097,8 @@ class OF13ProviderManager extends ProviderNetworkManager {
 
         // Call the InstructionBuilder Methods Containing Actions
         createDropInstructions(ib);
+        ib.setOrder(0);
+        ib.setKey(new InstructionKey(0));
         instructions.add(ib.build());
 
         // Add InstructionBuilder to the Instruction(s)Builder List
@@ -965,19 +1107,41 @@ class OF13ProviderManager extends ProviderNetworkManager {
         // Add InstructionsBuilder to FlowBuilder
         flowBuilder.setInstructions(isb.build());
 
+        String flowId = "LocalTableMiss_"+segmentationId;
         // Add Flow Attributes
-        flowBuilder.setId(new FlowId("100"));
-        FlowKey key = new FlowKey(new FlowId(String.valueOf((long) 200)));
+        flowBuilder.setId(new FlowId(flowId));
+        FlowKey key = new FlowKey(new FlowId(flowId));
+        flowBuilder.setStrict(true);
         flowBuilder.setBarrier(false);
         flowBuilder.setTableId(writeTable);
         flowBuilder.setKey(key);
         flowBuilder.setPriority(8192);
-        flowBuilder.setFlowName("TUNMISS_" + nodeName);
+        flowBuilder.setFlowName(flowId);
         flowBuilder.setHardTimeout(0);
         flowBuilder.setIdleTimeout(0);
         writeFlow(flowBuilder, nodeBuilder);
     }
 
+    private Flow getFlow(FlowBuilder flowBuilder, NodeBuilder nodeBuilder) {
+        IMDSALConsumer mdsalConsumer = (IMDSALConsumer) ServiceHelper.getInstance(IMDSALConsumer.class, "default", this);
+        if (mdsalConsumer == null) {
+            logger.error("ERROR finding MDSAL Service. Its possible that writeFlow is called too soon ?");
+            return null;
+        }
+
+        dataBrokerService = mdsalConsumer.getDataBrokerService();
+
+        if (dataBrokerService == null) {
+            logger.error("ERROR finding reference for DataBrokerService. Please check out the MD-SAL support on the Controller.");
+            return null;
+        }
+
+        InstanceIdentifier<Flow> path1 = InstanceIdentifier.builder(Nodes.class).child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory
+                .rev130819.nodes.Node.class, nodeBuilder.getKey()).augmentation(FlowCapableNode.class).child(Table.class,
+                new TableKey(flowBuilder.getTableId())).child(Flow.class, flowBuilder.getKey()).build();
+        return (Flow)dataBrokerService.readConfigurationData(path1);
+    }
+
     private void writeFlow(FlowBuilder flowBuilder, NodeBuilder nodeBuilder) {
         IMDSALConsumer mdsalConsumer = (IMDSALConsumer) ServiceHelper.getInstance(IMDSALConsumer.class, "default", this);
         if (mdsalConsumer == null) {
@@ -1003,6 +1167,7 @@ class OF13ProviderManager extends ProviderNetworkManager {
         try {
             RpcResult<TransactionStatus> result = commitFuture.get();
             TransactionStatus status = result.getResult();
+            logger.debug("Transaction Status "+status.toString()+" for Flow "+flowBuilder.getFlowName());
         } catch (InterruptedException e) {
             logger.error(e.getMessage(), e);
         } catch (ExecutionException e) {
@@ -1091,7 +1256,7 @@ class OF13ProviderManager extends ProviderNetworkManager {
      * @return matchBuilder Map MatchBuilder Object with a match
      */
 
-    protected static MatchBuilder createDestEthMatch(MatchBuilder matchBuilder, MacAddress dMacAddr, byte[] mask) {
+    protected static MatchBuilder createDestEthMatch(MatchBuilder matchBuilder, MacAddress dMacAddr, MacAddress mask) {
 
         EthernetMatchBuilder ethernetMatch = new EthernetMatchBuilder();
         EthernetDestinationBuilder ethDestinationBuilder = new EthernetDestinationBuilder();
@@ -1277,8 +1442,6 @@ class OF13ProviderManager extends ProviderNetworkManager {
 
         // Wrap our Apply Action in an Instruction
         ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
-        ib.setOrder(0);
-        ib.setKey(new InstructionKey(0));
 
         return ib;
     }
@@ -1302,8 +1465,8 @@ class OF13ProviderManager extends ProviderNetworkManager {
         oab.setOutputNodeConnector(ncid);
 
         ab.setAction(new OutputActionCaseBuilder().setOutputAction(oab.build()).build());
-        ab.setOrder(5);
-        ab.setKey(new ActionKey(5));
+        ab.setOrder(0);
+        ab.setKey(new ActionKey(0));
         actionList.add(ab.build());
 
         // Create an Apply Action
@@ -1314,6 +1477,58 @@ class OF13ProviderManager extends ProviderNetworkManager {
         return ib;
     }
 
+    /**
+     * Create Output Port Instruction
+     *
+     * @param ib       Map InstructionBuilder without any instructions
+     * @param dpidLong Long the datapath ID of a switch/node
+     * @param port     Long representing a port on a switch/node
+     * @return ib InstructionBuilder Map with instructions
+     */
+    protected static InstructionBuilder createOutputPortInstructions(InstructionBuilder ib, Long dpidLong, Long port , List<Instruction> instructions) {
+
+        NodeConnectorId ncid = new NodeConnectorId("openflow:" + dpidLong + ":" + port);
+        logger.debug("createOutputPortInstructions() Node Connector ID is - Type=openflow: DPID={} port={} existingInstructions={}", dpidLong, port, instructions);
+
+        List<Action> actionList = new ArrayList<Action>();
+        ActionBuilder ab = new ActionBuilder();
+
+        List<Action> existingActions = null;
+        if (instructions != null) {
+            for (Instruction in : instructions) {
+                if (in.getInstruction() instanceof ApplyActionsCase) {
+                    existingActions = (((ApplyActionsCase) in.getInstruction()).getApplyActions().getAction());
+                    actionList.addAll(existingActions);
+                }
+            }
+        }
+
+        OutputActionBuilder oab = new OutputActionBuilder();
+        oab.setOutputNodeConnector(ncid);
+        ab.setAction(new OutputActionCaseBuilder().setOutputAction(oab.build()).build());
+        ab.setOrder(0);
+        ab.setKey(new ActionKey(0));
+        Action newAction = ab.build();
+        boolean addNew = true;
+        for (Action action : actionList) {
+            if (action.getAction() instanceof OutputActionCase) {
+                OutputActionCase opAction = (OutputActionCase)action.getAction();
+                if (opAction.getOutputAction().getOutputNodeConnector().equals(new Uri(ncid))) {
+                    addNew = false;
+                    break;
+                }
+            }
+        }
+        if (addNew) actionList.add(newAction);
+
+        // Create an Apply Action
+        ApplyActionsBuilder aab = new ApplyActionsBuilder();
+        aab.setAction(actionList);
+        ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
+
+        return ib;
+    }
+
     /**
      * Create Set Vlan ID Instruction
      *
@@ -1363,8 +1578,6 @@ class OF13ProviderManager extends ProviderNetworkManager {
 
         // Wrap our Apply Action in an Instruction
         ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
-        ib.setOrder(0);
-        ib.setKey(new InstructionKey(0));
 
         return ib;
     }
@@ -1450,8 +1663,6 @@ class OF13ProviderManager extends ProviderNetworkManager {
 
         // Wrap our Apply Action in an Instruction
         ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
-        ib.setOrder(0);
-        ib.setKey(new InstructionKey(0));
 
         return ib;
     }
@@ -1470,8 +1681,6 @@ class OF13ProviderManager extends ProviderNetworkManager {
 
         // Wrap our Apply Action in an InstructionBuilder
         ib.setInstruction(new GoToTableCaseBuilder().setGoToTable(gttb.build()).build());
-        ib.setOrder(0);
-        ib.setKey(new InstructionKey(0));
 
         return ib;
     }
@@ -1500,8 +1709,6 @@ class OF13ProviderManager extends ProviderNetworkManager {
         aab.setAction(actionList);
 
         // Wrap the Apply Action in an InstructionBuilder and return
-        ib.setOrder(0);
-        ib.setKey(new InstructionKey(0));
         ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
 
         return ib;
@@ -1532,7 +1739,6 @@ class OF13ProviderManager extends ProviderNetworkManager {
 
         ApplyActionsBuilder aab = new ApplyActionsBuilder();
         aab.setAction(actionList);
-        ib.setKey(new InstructionKey(1));
         ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
 
         return ib;
@@ -1563,7 +1769,6 @@ class OF13ProviderManager extends ProviderNetworkManager {
 
         ApplyActionsBuilder aab = new ApplyActionsBuilder();
         aab.setAction(actionList);
-        ib.setKey(new InstructionKey(1));
         ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
 
         return ib;
@@ -1594,7 +1799,6 @@ class OF13ProviderManager extends ProviderNetworkManager {
 
         ApplyActionsBuilder aab = new ApplyActionsBuilder();
         aab.setAction(actionList);
-        ib.setKey(new InstructionKey(1));
         ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
 
         return ib;
@@ -1625,7 +1829,6 @@ class OF13ProviderManager extends ProviderNetworkManager {
 
         ApplyActionsBuilder aab = new ApplyActionsBuilder();
         aab.setAction(actionList);
-        ib.setKey(new InstructionKey(1));
         ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
 
         return ib;
@@ -1657,7 +1860,6 @@ class OF13ProviderManager extends ProviderNetworkManager {
         aab.setAction(actionList);
 
         // Wrap our Apply Action in an Instruction
-        ib.setKey(new InstructionKey(0));
         ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
 
         return ib;
@@ -1687,7 +1889,6 @@ class OF13ProviderManager extends ProviderNetworkManager {
         aab.setAction(actionList);
 
         // Wrap our Apply Action in an Instruction
-        ib.setKey(new InstructionKey(1));
         ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
 
         return ib;
@@ -1715,8 +1916,6 @@ class OF13ProviderManager extends ProviderNetworkManager {
 
         // Wrap our Apply Action in an Instruction
         ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
-        ib.setKey(new InstructionKey(0));
-        ib.setOrder(0);
 
         return ib;
     }
@@ -1814,6 +2013,18 @@ class OF13ProviderManager extends ProviderNetworkManager {
 
     @Override
     public void initializeOFFlowRules(Node openflowNode) {
+        IConnectionServiceInternal connectionService = (IConnectionServiceInternal)ServiceHelper.getGlobalInstance(IConnectionServiceInternal.class, this);
+        List<Node> ovsNodes = connectionService.getNodes();
+        if (ovsNodes == null) return;
+        for (Node ovsNode : ovsNodes) {
+            Long dpid = this.getIntegrationBridgeOFDPID(ovsNode);
+            logger.debug("Compare openflowNode to OVS br-int node {} vs {}", openflowNode.getID(), dpid);
+            String openflowID = ""+openflowNode.getID();
+            if (openflowID.contains(""+dpid)) {
+                this.initializeFlowRules(ovsNode, AdminConfigManager.getManager().getIntegrationBridgeName());
+                this.triggerInterfaceUpdates(ovsNode);
+            }
+        }
     }
 
     private NodeBuilder createNodeBuilder(String nodeId) {
@@ -1828,4 +2039,4 @@ class OF13ProviderManager extends ProviderNetworkManager {
         return InstanceIdentifier.builder(Nodes.class).child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node.class,
                 node.getKey()).toInstance();
     }
-}
\ No newline at end of file
+}