Resolved the OF10 to OF13 transition issues during devstack bootup. 56/4756/3
authorMadhu Venugopal <mavenugo@gmail.com>
Sat, 25 Jan 2014 02:29:30 +0000 (18:29 -0800)
committerGerrit Code Review <gerrit@opendaylight.org>
Sat, 25 Jan 2014 13:52:11 +0000 (13:52 +0000)
Change-Id: I9f449655096de60e9747c7c5a269db1bb8e14ab9
Signed-off-by: Madhu Venugopal <mavenugo@gmail.com>
neutron/src/main/java/org/opendaylight/ovsdb/neutron/InternalNetworkManager.java
neutron/src/main/java/org/opendaylight/ovsdb/neutron/SouthboundHandler.java
neutron/src/main/java/org/opendaylight/ovsdb/neutron/provider/OF13ProviderManager.java
ovsdb/src/main/java/org/opendaylight/ovsdb/plugin/ConnectionService.java

index a1e128b65ea291c4355e461d3b48ee03ca49b0a0..82430f2279984d221d1bd6441d425c106b95411e 100644 (file)
@@ -158,9 +158,11 @@ public class InternalNetworkManager {
             bridgeUUID = statusWithUuid.getUuid().toString();
             Port port = new Port();
             port.setName(bridgeName);
-            ovsdbTable.insertRow(node, Port.NAME.getName(), bridgeUUID, port);
+            Status status = ovsdbTable.insertRow(node, Port.NAME.getName(), bridgeUUID, port);
+            logger.debug("addInternalBridge : Inserting Bridge {} with protocols {} and status {}", bridgeUUID, protocols, status);
         } else {
-            ovsdbTable.updateRow(node, Bridge.NAME.getName(), null, bridgeUUID, bridge);
+            Status status = ovsdbTable.updateRow(node, Bridge.NAME.getName(), null, bridgeUUID, bridge);
+            logger.debug("addInternalBridge : Updating Bridge {} with protocols {} and status {}", bridgeUUID, protocols, status);
         }
 
         IConnectionServiceInternal connectionService = (IConnectionServiceInternal)ServiceHelper.getGlobalInstance(IConnectionServiceInternal.class, this);
index 7f38f7a7413bb869d152a0c9362cba78ba7286b9..24a06cdd5a71c24739080aa9aff7fcbb4de9af1f 100644 (file)
@@ -9,6 +9,7 @@
  */
 package org.opendaylight.ovsdb.neutron;
 
+import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -39,10 +40,12 @@ public class SouthboundHandler extends BaseHandler implements OVSDBInventoryList
     //private Thread eventThread;
     private ExecutorService eventHandler;
     private BlockingQueue<SouthboundEvent> events;
+    List<Node> nodeCache;
 
     void init() {
         eventHandler = Executors.newSingleThreadExecutor();
         this.events = new LinkedBlockingQueue<SouthboundEvent>();
+        nodeCache = new ArrayList<>();
     }
 
     void start() {
@@ -243,9 +246,14 @@ public class SouthboundHandler extends BaseHandler implements OVSDBInventoryList
 
     @Override
     public void notifyNode(Node node, UpdateType type, Map<String, Property> propMap) {
-        if (node.getType().equals(Node.NodeIDType.OPENFLOW) && type.equals(UpdateType.ADDED)) {
-            logger.debug("OpenFlow node {} added. Initialize Basic flows", node);
+        logger.debug("Node {} update {} from Controller's inventory Service", node, type);
+
+        // Add the Node Type check back once the Consistency issue is resolved between MD-SAL and AD-SAL
+        if (!type.equals(UpdateType.REMOVED) && !nodeCache.contains(node)) {
+            nodeCache.add(node);
             ProviderNetworkManager.getManager().initializeOFFlowRules(node);
+        } else if (type.equals(UpdateType.REMOVED)){
+            nodeCache.remove(node);
         }
     }
 
index ced0b8f865964dce2caa32fa946ff103c9aae9c3..5a0f420cc7c5825d6c3af50ffb3c5627533b4384 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;
@@ -251,7 +253,9 @@ class OF13ProviderManager extends ProviderNetworkManager {
          * Action: Drop w/ a low priority
          */
 
-         writeDropSrcIface(dpid, localPort);
+         // TODO : Drop flows causing problems with other existing flows. Commenting them out for now till it is fixed.
+
+         // writeDropSrcIface(dpid, localPort);
 
          /*
           * Table(2) Rule #1
@@ -295,7 +299,8 @@ class OF13ProviderManager extends ProviderNetworkManager {
            * table=2,priority=8192,tun_id=0x5 actions=drop
            */
 
-           writeLocalTableMiss(dpid, TABLE_2_LOCAL_FORWARD, segmentationId);
+           // TODO : Drop flows causing problems with other existing flows. Commenting them out for now till it is fixed.
+           // writeLocalTableMiss(dpid, TABLE_2_LOCAL_FORWARD, segmentationId);
     }
 
     private void programLocalIngressTunnelBridgeRules(Node node, Long dpid, String segmentationId, String attachedMac, long tunnelOFPort, long localPort) {
@@ -335,21 +340,32 @@ class OF13ProviderManager extends ProviderNetworkManager {
         writeTunnelFloodOut(dpid, TABLE_1_ISOLATE_TENANT, TABLE_2_LOCAL_FORWARD, segmentationId, tunnelOFPort);
     }
 
-    private void programLocalRules (String tunnelType, String segmentationId, Node node, Interface intf) {
+    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) {
@@ -380,18 +396,12 @@ class OF13ProviderManager extends ProviderNetworkManager {
             Interface intf, boolean local) {
         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);
+            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);
-            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]));
 
             Set<BigInteger> of_ports = intf.getOfport();
             if (of_ports == null || of_ports.size() <= 0) {
@@ -445,10 +455,39 @@ class OF13ProviderManager extends ProviderNetworkManager {
 
     @Override
     public Status handleInterfaceUpdate(String tunnelType, String tunnelKey, Node srcNode, Interface intf) {
+        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.info("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 status = getTunnelReadinessStatus(dstNode, tunnelKey);
             if (!status.isSuccess()) continue;
@@ -463,9 +502,30 @@ 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.internal.Table<?>> intfs = ovsdbTable.getRows(node, Interface.NAME.getName());
+            if (intfs != null) {
+                for (org.opendaylight.ovsdb.lib.table.internal.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
@@ -475,6 +535,7 @@ class OF13ProviderManager extends ProviderNetworkManager {
     @Override
     public void initializeFlowRules(Node node) {
         this.initializeFlowRules(node, AdminConfigManager.getManager().getIntegrationBridgeName());
+        this.triggerInterfaceUpdates(node);
     }
 
     /**
@@ -482,40 +543,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);
     }
 
     /*
@@ -1865,6 +1906,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 = (String)openflowNode.getID();
+            if (openflowID.contains(""+dpid)) {
+                this.initializeFlowRules(ovsNode, AdminConfigManager.getManager().getIntegrationBridgeName());
+                this.triggerInterfaceUpdates(ovsNode);
+            }
+        }
     }
 
     private NodeBuilder createNodeBuilder(String nodeId) {
index 6f88ce6776d398966ee4c8e5e180ede7c40bd1d5..ff0cbf88be8fa6410250f549630b5b87b8ce329e 100644 (file)
@@ -56,6 +56,7 @@ import org.opendaylight.ovsdb.lib.message.MonitorRequestBuilder;
 import org.opendaylight.ovsdb.lib.message.OvsdbRPC;
 import org.opendaylight.ovsdb.lib.message.TableUpdates;
 import org.opendaylight.ovsdb.lib.message.UpdateNotification;
+import org.opendaylight.ovsdb.lib.notation.OvsDBSet;
 import org.opendaylight.ovsdb.lib.table.Bridge;
 import org.opendaylight.ovsdb.lib.table.Controller;
 import org.opendaylight.ovsdb.lib.table.Open_vSwitch;
@@ -478,17 +479,26 @@ public class ConnectionService implements IPluginInConnectionService, IConnectio
             return false;
         }
 
-        if (connection != null) {
-            List<InetAddress> ofControllerAddrs = this.getControllerIPAddresses(connection);
-            short ofControllerPort = getControllerOFPort();
-            for (InetAddress ofControllerAddress : ofControllerAddrs) {
-                String newController = "tcp:"+ofControllerAddress.getHostAddress()+":"+ofControllerPort;
-                Controller controllerRow = new Controller();
-                controllerRow.setTarget(newController);
-                OVSDBConfigService ovsdbTable = (OVSDBConfigService)ServiceHelper.getGlobalInstance(OVSDBConfigService.class, this);
-                if (ovsdbTable != null) {
-                    ovsdbTable.insertRow(node, Controller.NAME.getName(), bridgeUUID, controllerRow);
-                }
+        OVSDBConfigService ovsdbTable = (OVSDBConfigService)ServiceHelper.getGlobalInstance(OVSDBConfigService.class, this);
+        OvsDBSet<String> protocols = new OvsDBSet<String>();
+        if (Boolean.getBoolean("OF1.3_Provider")) {
+            protocols.add("OpenFlow13");
+        } else {
+            protocols.add("OpenFlow10");
+        }
+        Bridge bridge = new Bridge();
+        bridge.setProtocols(protocols);
+        Status status = ovsdbTable.updateRow(node, Bridge.NAME.getName(), null, bridgeUUID, bridge);
+        logger.info("Bridge {} updated to {} with Status {}", bridgeUUID, protocols.toArray()[0], status);
+
+        List<InetAddress> ofControllerAddrs = this.getControllerIPAddresses(connection);
+        short ofControllerPort = getControllerOFPort();
+        for (InetAddress ofControllerAddress : ofControllerAddrs) {
+            String newController = "tcp:"+ofControllerAddress.getHostAddress()+":"+ofControllerPort;
+            Controller controllerRow = new Controller();
+            controllerRow.setTarget(newController);
+            if (ovsdbTable != null) {
+                ovsdbTable.insertRow(node, Controller.NAME.getName(), bridgeUUID, controllerRow);
             }
         }
         return true;