Add support for vlan tenant isolation to ovsdb using OpenFlow 1.0. 04/6004/10
authorSam Hague <shague@redhat.com>
Tue, 6 May 2014 21:45:56 +0000 (17:45 -0400)
committerSam Hague <shague@redhat.com>
Tue, 6 May 2014 21:45:56 +0000 (17:45 -0400)
This is an initial push of the changes needed to support vlan tenant isolation.
Ignore the logger's with shague in them since they are for my debugging and will go away.

This is using OF 1.0. Hsin-Yi has the 1.3 task.

The br-eth for vlan and br-tun for tunnels has been combined to br-net. A single patch port
connects br-net to br-int.

Functions to parse the physical interface name from the provider_mappings have been added.

Signed-off-by: Sam Hague <shague@redhat.com>
Change-Id: I369165f4f92665242e033454b49a5ee6a4ea0381

neutron/pom.xml
neutron/src/main/java/org/opendaylight/ovsdb/neutron/AdminConfigManager.java
neutron/src/main/java/org/opendaylight/ovsdb/neutron/InternalNetworkManager.java
neutron/src/main/java/org/opendaylight/ovsdb/neutron/NetworkHandler.java
neutron/src/main/java/org/opendaylight/ovsdb/neutron/NodeConfiguration.java
neutron/src/main/java/org/opendaylight/ovsdb/neutron/SouthboundHandler.java
neutron/src/main/java/org/opendaylight/ovsdb/neutron/provider/OF10ProviderManager.java
neutron/src/main/java/org/opendaylight/ovsdb/neutron/provider/OF13ProviderManager.java
neutron/src/main/java/org/opendaylight/ovsdb/neutron/provider/ProviderNetworkManager.java

index 76de14650fc44bd1124c83c9171120ccd72c0c49..b1db746f231dbac9934e5dc53c59e22ea454f770 100644 (file)
@@ -9,7 +9,7 @@
     </parent>
 
     <artifactId>ovsdb.neutron</artifactId>
-    <version>0.5.1-SNAPSHOT</version>
+    <version>0.7.0-SNAPSHOT</version>
     <packaging>bundle</packaging>
 
     <scm>
index eecaf0eccf54680fb5bc0332dc2335340741ba67..eaf00ebd8c3a3ef2755d53b63f326b2cb97e91d8 100644 (file)
@@ -5,7 +5,7 @@
  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
  * and is available at http://www.eclipse.org/legal/epl-v10.html
  *
- * Authors : Madhu Venugopal, Brent Salisbury
+ * Authors : Madhu Venugopal, Brent Salisbury, Sam Hague
  */
 package org.opendaylight.ovsdb.neutron;
 
@@ -24,42 +24,50 @@ public class AdminConfigManager {
     static final Logger logger = LoggerFactory.getLogger(AdminConfigManager.class);
 
     private String integrationBridgeName;
-    private String tunnelBridgeName;
+    private String networkBridgeName;
     private String externalBridgeName;
     private String tunnelEndpointConfigName;
     private String patchToIntegration;
-    private String patchToTunnel;
+    private String patchToNetwork;
+    private String providerMappingsConfigName;
+    private String providerMappings;
 
     // Refer to /etc/quantum/plugins/openvswitch/ovs_quantum_plugin.ini
     private static String DEFAULT_TUNNEL_ENDPOINT_CONFIG_STRING = "local_ip";
     private static String DEFAULT_INTEGRATION_BRIDGENAME = "br-int";
-    private static String DEFAULT_TUNNEL_BRIDGENAME = "br-tun";
+    private static String DEFAULT_NETWORK_BRIDGENAME = "br-net";
     private static String DEFAULT_EXTERNAL_BRIDGENAME = "br-ex";
     private static String DEFAULT_PATCH_TO_INTEGRATION = "patch-int";
-    private static String DEFAULT_PATCH_TO_TUNNEL = "patch-tun";
+    private static String DEFAULT_PATCH_TO_NETWORK = "patch-net";
     private static String CONFIG_TUNNEL_ENDPOINT_CONFIG = "tunnel_endpoint_config_string";
     private static String CONFIG_INTEGRATION_BRIDGENAME = "integration_bridge";
-    private static String CONFIG_TUNNEL_BRIDGENAME = "tunnel_bridge";
+    private static String CONFIG_NETWORK_BRIDGENAME = "network_bridge";
     private static String CONFIG_EXTERNAL_BRIDGENAME = "external_bridge";
     private static String CONFIG_PATCH_TO_INTEGRATION = "patch-int";
-    private static String CONFIG_PATCH_TO_TUNNEL = "patch-tun";
+    private static String CONFIG_PATCH_TO_NETWORK = "patch-net";
+    private static String DEFAULT_PROVIDER_MAPPINGS_CONFIG_STRING = "provider_mappings";
+    private static String CONFIG_PROVIDER_MAPPINGS_CONFIG = "provider_mappings_config_string";
+    private static String CONFIG_PROVIDER_MAPPINGS = "provider_mappings";
 
     private static AdminConfigManager adminConfiguration = new AdminConfigManager();
 
     private AdminConfigManager() {
         tunnelEndpointConfigName = System.getProperty(CONFIG_TUNNEL_ENDPOINT_CONFIG);
         integrationBridgeName = System.getProperty(CONFIG_INTEGRATION_BRIDGENAME);
-        tunnelBridgeName = System.getProperty(CONFIG_TUNNEL_BRIDGENAME);
+        networkBridgeName = System.getProperty(CONFIG_NETWORK_BRIDGENAME);
         externalBridgeName = System.getProperty(CONFIG_EXTERNAL_BRIDGENAME);
         patchToIntegration = System.getProperty(CONFIG_PATCH_TO_INTEGRATION);
-        patchToTunnel = System.getProperty(CONFIG_PATCH_TO_TUNNEL);
+        patchToNetwork = System.getProperty(CONFIG_PATCH_TO_NETWORK);
+        providerMappingsConfigName = System.getProperty(CONFIG_PROVIDER_MAPPINGS_CONFIG);
+        providerMappings = System.getProperty(CONFIG_PROVIDER_MAPPINGS);
 
         if (tunnelEndpointConfigName == null) tunnelEndpointConfigName = DEFAULT_TUNNEL_ENDPOINT_CONFIG_STRING;
         if (integrationBridgeName == null) integrationBridgeName = DEFAULT_INTEGRATION_BRIDGENAME;
-        if (tunnelBridgeName == null) tunnelBridgeName = DEFAULT_TUNNEL_BRIDGENAME;
+        if (networkBridgeName == null) networkBridgeName = DEFAULT_NETWORK_BRIDGENAME;
         if (externalBridgeName == null) externalBridgeName = DEFAULT_EXTERNAL_BRIDGENAME;
         if (patchToIntegration == null) patchToIntegration = DEFAULT_PATCH_TO_INTEGRATION;
-        if (patchToTunnel == null) patchToTunnel = DEFAULT_PATCH_TO_TUNNEL;
+        if (patchToNetwork == null) patchToNetwork  = DEFAULT_PATCH_TO_NETWORK;
+        if (providerMappingsConfigName == null) providerMappingsConfigName = DEFAULT_PROVIDER_MAPPINGS_CONFIG_STRING;
     }
 
     public static AdminConfigManager getManager() {
@@ -74,12 +82,10 @@ public class AdminConfigManager {
         this.integrationBridgeName = integrationBridgeName;
     }
 
-    public String getTunnelBridgeName() {
-        return tunnelBridgeName;
-    }
+    public String getNetworkBridgeName() { return networkBridgeName; }
 
-    public void setTunnelBridgeName(String tunnelBridgeName) {
-        this.tunnelBridgeName = tunnelBridgeName;
+    public void setNetworkBridgeName(String networkBridgeName) {
+        this.networkBridgeName = networkBridgeName;
     }
 
     public String getExternalBridgeName() {
@@ -98,12 +104,10 @@ public class AdminConfigManager {
         this.patchToIntegration = patchToIntegration;
     }
 
-    public String getPatchToTunnel() {
-        return patchToTunnel;
-    }
+    public String getPatchToNetwork() { return patchToNetwork; }
 
-    public void setPatchToTunnel(String patchToTunnel) {
-        this.patchToTunnel = patchToTunnel;
+    public void setPatchToNetwork(String patchToNetwork) {
+        this.patchToNetwork = patchToNetwork;
     }
 
     public InetAddress getTunnelEndPoint(Node node) {
@@ -145,6 +149,65 @@ public class AdminConfigManager {
         return address;
     }
 
+
+    /*
+     * Return the physical interface mapped to the given neutron physical network.
+     * Provider mappings will be of the following format:
+     * provider_mappings=physnet1:eth1[,physnet2:eth2]
+     */
+      public String getPhysicalInterfaceName (Node node, String physicalNetwork) {
+        String phyIf = null;
+
+        try {
+            OVSDBConfigService ovsdbConfig = (OVSDBConfigService) ServiceHelper.getGlobalInstance(OVSDBConfigService.class, this);
+            Map<String, Table<?>> ovsTable = ovsdbConfig.getRows(node, Open_vSwitch.NAME.getName());
+
+            if (ovsTable == null) {
+                logger.error("Open_vSwitch table is null for Node {} ", node);
+                return null;
+            }
+
+            // Loop through all the Open_vSwitch rows looking for the first occurrence of other_config.
+            // The specification does not restrict the number of rows so we choose the first we find.
+            for (Table<?> row : ovsTable.values()) {
+                String providerMaps;
+                Open_vSwitch ovsRow = (Open_vSwitch) row;
+                Map<String, String> configs = ovsRow.getOther_config();
+
+                if (configs == null) {
+                    logger.debug("Open_vSwitch table is null for Node {} ", node);
+                    continue;
+                }
+
+                providerMaps = configs.get(providerMappingsConfigName);
+                if (providerMaps == null) {
+                    providerMaps = providerMappings;
+                }
+
+                if (providerMaps != null) {
+                    for (String map : providerMaps.split(",")) {
+                        String[] pair = map.split(":");
+                        if (pair[0].equals(physicalNetwork)) {
+                            phyIf = pair[1];
+                            break;
+                        }
+                    }
+                }
+                break;
+            }
+        } catch (Exception e) {
+            logger.error("Unable to find physical interface for Node: {}, Network {}",
+                    node, physicalNetwork, e);
+        }
+
+        if (phyIf == null) {
+            logger.error("Physical interface not found for Node: {}, Network {}",
+                    node, physicalNetwork);
+        }
+
+        return phyIf;
+    }
+
     public boolean isInterested (String tableName) {
         return tableName.equalsIgnoreCase(Open_vSwitch.NAME.getName());
     }
index 82430f2279984d221d1bd6441d425c106b95411e..97dfeaeb8ac18f0f2deef9b18163a8052586d71b 100644 (file)
@@ -5,12 +5,13 @@
  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
  * and is available at http://www.eclipse.org/legal/epl-v10.html
  *
- * Authors : Madhu Venugopal, Brent Salisbury
+ * Authors : Madhu Venugopal, Brent Salisbury, Sam Hague
  */
 package org.opendaylight.ovsdb.neutron;
 
 import java.util.Map;
 
+import org.opendaylight.controller.networkconfig.neutron.NeutronNetwork;
 import org.opendaylight.controller.sal.core.Node;
 import org.opendaylight.controller.sal.utils.ServiceHelper;
 import org.opendaylight.controller.sal.utils.Status;
@@ -30,11 +31,11 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 /**
- * OpenStack Neutron with the OpenVswitch data plan relies on a typical OVS bridge configurations that
+ * OpenStack Neutron with the OpenvSwitch data plan relies on a typical OVS bridge configurations that
  * consists of br-int (Integration Bridge), br-tun (Tunnel bridge), br-ex (External bridge).
  *
  * In DevStack like setups, the br-tun is not automatically created on the controller nodes.
- * Hence this class attempts to bring all the nodes to be elibible for OpenStack operations.
+ * Hence this class attempts to bring all the nodes to be eligible for OpenStack operations.
  *
  */
 public class InternalNetworkManager {
@@ -65,6 +66,24 @@ public class InternalNetworkManager {
         return null;
     }
 
+    public Bridge getInternalBridge (Node node, String bridgeName) {
+        try {
+            OVSDBConfigService ovsdbTable = (OVSDBConfigService) ServiceHelper.getGlobalInstance(OVSDBConfigService.class, this);
+            Map<String, Table<?>> bridgeTable = ovsdbTable.getRows(node, Bridge.NAME.getName());
+            if (bridgeTable != null) {
+                for (String key : bridgeTable.keySet()) {
+                    Bridge bridge = (Bridge) bridgeTable.get(key);
+                    if (bridge.getName().equals(bridgeName)) {
+                        return bridge;
+                    }
+                }
+            }
+        } catch (Exception e) {
+            logger.error("Error getting Bridge Identifier for {} / {}", node, bridgeName, e);
+        }
+        return null;
+    }
+
     public boolean isInternalNetworkNeutronReady(Node node) {
         if (this.getInternalBridgeUUID(node, AdminConfigManager.getManager().getIntegrationBridgeName()) != null) {
             return true;
@@ -77,106 +96,314 @@ public class InternalNetworkManager {
         if (!this.isInternalNetworkNeutronReady(node)) {
             return false;
         }
-        if (this.getInternalBridgeUUID(node, AdminConfigManager.getManager().getTunnelBridgeName()) != null) {
+        if (this.getInternalBridgeUUID(node, AdminConfigManager.getManager().getNetworkBridgeName()) != null) {
             return true;
         } else {
             return false;
         }
     }
 
+    public boolean isPortOnBridge (Node node, Bridge bridge, String portName) {
+        OVSDBConfigService ovsdbTable = (OVSDBConfigService) ServiceHelper.getGlobalInstance(OVSDBConfigService.class, this);
+
+        for (UUID portsUUID : bridge.getPorts()) {
+            try {
+                Port port = (Port) ovsdbTable.getRow(node, Port.NAME.getName(), portsUUID.toString());
+                if ((port != null) && port.getName().equalsIgnoreCase(portName)) {
+                    return true;
+                }
+            } catch (Exception e) {
+                logger.error("Error getting port {} for bridge domain {}/{}", portsUUID, node, bridge.getName(), e);
+            }
+        }
+
+        return false;
+    }
+
+    public boolean isNetworkPatchCreated (Node node, Bridge intBridge, Bridge netBridge) {
+        boolean isPatchCreated = false;
+
+        String portName = AdminConfigManager.getManager().getPatchToNetwork();
+        if (isPortOnBridge(node, intBridge, portName)) {
+            portName = AdminConfigManager.getManager().getPatchToIntegration();
+            if (isPortOnBridge(node, netBridge, portName)) {
+                isPatchCreated = true;
+            }
+        }
+
+        return isPatchCreated;
+    }
+
+    /* Determine if internal network is ready for tunnel network types.
+     * - OF 1.0 requires br-int, br-net and a patch connecting them.
+     * - OF 1.3 requires br-int.
+     */
+    public boolean isInternalNetworkTunnelReady (Node node) {
+        /* Is br-int created? */
+        Bridge intBridge = this.getInternalBridge(node, AdminConfigManager.getManager().getIntegrationBridgeName());
+        if (intBridge == null) {
+            return false;
+        }
+
+        if (ProviderNetworkManager.getManager().hasPerTenantTunneling()) {
+            /* Is br-net created? */
+            Bridge netBridge = this.getInternalBridge(node, AdminConfigManager.getManager().getNetworkBridgeName());
+            if (netBridge == null) {
+                return false;
+            }
+
+            if (!isNetworkPatchCreated(node, intBridge, netBridge)) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /* Determine if internal network is ready for vlan network types.
+     * - OF 1.0 requires br-int, br-net, a patch connecting them and
+     * physical device added to br-net.
+     * - OF 1.3 requires br-int and physical device added to br-int.
+     */
+    public boolean isInternalNetworkVlanReady (Node node, NeutronNetwork network) {
+        /* is br-int created */
+        Bridge intBridge = this.getInternalBridge(node, AdminConfigManager.getManager().getIntegrationBridgeName());
+        if (intBridge == null) {
+            logger.trace("shague isInternalNetworkVlanReady: node: {}, br-int missing", node);
+            return false;
+        }
+
+        if (ProviderNetworkManager.getManager().hasPerTenantTunneling()) {
+            /* is br-net created? */
+            Bridge netBridge = this.getInternalBridge(node, AdminConfigManager.getManager().getNetworkBridgeName());
+
+            if (netBridge == null) {
+                logger.trace("shague isInternalNetworkVlanReady: node: {}, br-net missing", node);
+                return false;
+            }
+
+            if (!isNetworkPatchCreated(node, intBridge, netBridge)) {
+                logger.trace("shague isInternalNetworkVlanReady: node: {}, patch missing", node);
+                return false;
+            }
+
+            /* Check if physical device is added to br-net. */
+            String phyNetName = AdminConfigManager.getManager().getPhysicalInterfaceName(node, network.getProviderPhysicalNetwork());
+            if (isPortOnBridge(node, netBridge, phyNetName)) {
+                return true;
+            }
+        } else {
+            /* Check if physical device is added to br-int. */
+            String phyNetName = AdminConfigManager.getManager().getPhysicalInterfaceName(node, network.getProviderPhysicalNetwork());
+            if (isPortOnBridge(node, intBridge, phyNetName)) {
+                return true;
+            }
+        }
+
+        logger.trace("shague isInternalNetworkVlanReady: node: {}, eth missing", node);
+        return false;
+    }
+
     /*
-     * Lets create these if not already present :
+     * Create the integration bridge.
      *
        Bridge br-int
-            Port patch-tun
-                Interface patch-tun
-                    type: patch
-                    options: {peer=patch-int}
             Port br-int
                 Interface br-int
                     type: internal
-      Bridge br-tun
-            Port patch-int
-                Interface patch-int
-                    type: patch
-                    options: {peer=patch-tun}
-            Port br-tun
-                Interface br-tun
-                    type: internal
      */
-    public void createInternalNetworkForOverlay(Node node) throws Exception {
-        String brTun = AdminConfigManager.getManager().getTunnelBridgeName();
+    public void createIntegrationBridge (Node node) throws Exception {
         String brInt = AdminConfigManager.getManager().getIntegrationBridgeName();
-        String patchInt = AdminConfigManager.getManager().getPatchToIntegration();
-        String patchTun = AdminConfigManager.getManager().getPatchToTunnel();
 
-        Status status = this.addInternalBridge(node, brInt, patchTun, patchInt);
-        if (!status.isSuccess()) logger.debug("Integration Bridge Creation Status : "+status.toString());
-        if (ProviderNetworkManager.getManager().hasPerTenantTunneling()) {
-            status = this.addInternalBridge(node, brTun, patchInt, patchTun);
-            if (!status.isSuccess()) logger.debug("Tunnel Bridge Creation Status : "+status.toString());
+        Status status = this.addInternalBridge(node, brInt, null, null);
+        if (!status.isSuccess()) {
+            logger.debug("Integration Bridge Creation Status: {}", status);
         }
     }
 
     /*
-     * Lets create these if not already present :
+     * Create complete network for all network types and OpenFlow versions.
      *
+       OF 1.0 vlan:
+       Bridge br-int
+            Port patch-net
+                Interface patch-net
+                    type: patch
+                    options: {peer=patch-int}
+            Port br-int
+                Interface br-int
+                    type: internal
+       Bridge br-net
+            Port "eth1"
+                Interface "eth1"
+            Port patch-int
+                Interface patch-int
+                    type: patch
+                    options: {peer=patch-net}
+            Port br-net
+                Interface br-net
+                    type: internal
+
+       OF 1.0 tunnel:
+       Bridge br-int
+            Port patch-net
+                Interface patch-net
+                    type: patch
+                    options: {peer=patch-int}
+            Port br-int
+                Interface br-int
+                    type: internal
+       Bridge "br-net"
+            Port patch-int
+                Interface patch-int
+                    type: patch
+                    options: {peer=patch-net}
+            Port br-net
+                Interface br-net
+                    type: internal
+
+       OF 1.3 vlan:
+       Bridge br-int
+            Port "eth1"
+                Interface "eth1"
+            Port br-int
+                Interface br-int
+                    type: internal
+
+       OF 1.3 tunnel:
        Bridge br-int
             Port br-int
                 Interface br-int
                     type: internal
      */
-    public void createInternalNetworkForNeutron(Node node) throws Exception {
-        String brInt = AdminConfigManager.getManager().getIntegrationBridgeName();
+    public boolean createNetNetwork (Node node, NeutronNetwork network) throws Exception {
+        Status status;
 
-        Status status = this.addInternalBridge(node, brInt, null, null);
-        if (!status.isSuccess()) logger.debug("Integration Bridge Creation Status : "+status.toString());
-    }
+        logger.debug("createNetNetwork: node: {}, network type: {}", node, network.getProviderNetworkType());
 
-    private Status addInternalBridge (Node node, String bridgeName, String localPathName, String remotePatchName) throws Exception {
-        OVSDBConfigService ovsdbTable = (OVSDBConfigService)ServiceHelper.getGlobalInstance(OVSDBConfigService.class, this);
+        if (ProviderNetworkManager.getManager().hasPerTenantTunneling()) { /* indicates OF 1.0 */
+            String brInt = AdminConfigManager.getManager().getIntegrationBridgeName();
+            String brNet = AdminConfigManager.getManager().getNetworkBridgeName();
+            String patchNet = AdminConfigManager.getManager().getPatchToNetwork();
+            String patchInt = AdminConfigManager.getManager().getPatchToIntegration();
 
-        String bridgeUUID = this.getInternalBridgeUUID(node, bridgeName);
-        Bridge bridge = new Bridge();
-        OvsDBSet<String> failMode = new OvsDBSet<String>();
-        failMode.add("secure");
-        bridge.setFail_mode(failMode);
+            status = this.addInternalBridge(node, brInt, patchNet, patchInt);
+            if (!status.isSuccess()) {
+                logger.debug("{} Bridge Creation Status: {}", brInt, status);
+                return false;
+            }
+            status = this.addInternalBridge(node, brNet, patchInt, patchNet);
+            if (!status.isSuccess()) {
+                logger.debug("{} Bridge Creation Status: {}", brNet, status);
+                return false;
+            }
 
-        OvsDBSet<String> protocols = new OvsDBSet<String>();
-        if (!ProviderNetworkManager.getManager().hasPerTenantTunneling()) {
-            protocols.add("OpenFlow13");
+            /* For vlan network types add physical port to br-net. */
+            if (network.getProviderNetworkType().equalsIgnoreCase("vlan")) {
+                String phyNetName = AdminConfigManager.getManager().getPhysicalInterfaceName(node, network.getProviderPhysicalNetwork());
+                status = addPortToBridge(node, brNet, phyNetName);
+                if (!status.isSuccess()) {
+                    logger.debug("Add Port {} to Bridge {} Status: {}", phyNetName, brNet, status);
+                    return false;
+                }
+            }
         } else {
-            protocols.add("OpenFlow10");
+            String brInt = AdminConfigManager.getManager().getIntegrationBridgeName();
+            status = this.addInternalBridge(node, brInt, null, null);
+            if (!status.isSuccess()) {
+                logger.debug("{} Bridge Creation Status: {}", brInt, status);
+                return false;
+            }
+
+            /* For vlan network types add physical port to br-int. */
+            if (network.getProviderNetworkType().equalsIgnoreCase("vlan")) {
+                String phyNetName = AdminConfigManager.getManager().getPhysicalInterfaceName(node, network.getProviderPhysicalNetwork());
+                status = addPortToBridge(node, brInt, phyNetName);
+                if (!status.isSuccess()) {
+                    logger.debug("Add Port {} to Bridge {} Status: {}", phyNetName, brInt, status);
+                    return false;
+                }
+            }
         }
-        bridge.setProtocols(protocols);
 
+        logger.debug("createNetNetwork: node: {}, status: success", node);
+        return true;
+    }
+
+    private Status addPortToBridge (Node node, String bridgeName, String portName) throws Exception {
+        logger.debug("addPortToBridge: Adding port: {} to Bridge {}, Node {}", portName, bridgeName, node);
+        OVSDBConfigService ovsdbTable = (OVSDBConfigService)ServiceHelper.getGlobalInstance(OVSDBConfigService.class, this);
+
+        String bridgeUUID = this.getInternalBridgeUUID(node, bridgeName);
         if (bridgeUUID == null) {
-            bridge.setName(bridgeName);
+            logger.error("addPortToBridge: Could not find Bridge {} in Node {}", bridgeName, node);
+            return new Status(StatusCode.NOTFOUND, "Could not find "+bridgeName+" in "+node);
+        }
 
-            StatusWithUuid statusWithUuid = ovsdbTable.insertRow(node, Bridge.NAME.getName(), null, bridge);
-            if (!statusWithUuid.isSuccess()) return statusWithUuid;
-            bridgeUUID = statusWithUuid.getUuid().toString();
-            Port port = new Port();
-            port.setName(bridgeName);
-            Status status = ovsdbTable.insertRow(node, Port.NAME.getName(), bridgeUUID, port);
-            logger.debug("addInternalBridge : Inserting Bridge {} with protocols {} and status {}", bridgeUUID, protocols, status);
+        /* Check if the port already exists. */
+        Bridge bridge = (Bridge)ovsdbTable.getRow(node, Bridge.NAME.getName(), bridgeUUID);
+        if (bridge != null) {
+            if (isPortOnBridge(node, bridge, portName)) {
+                logger.debug("addPortToBridge: Port {} already in Bridge {}, Node {}", portName, bridgeName, node);
+                return new Status(StatusCode.SUCCESS);
+            }
         } else {
-            Status status = ovsdbTable.updateRow(node, Bridge.NAME.getName(), null, bridgeUUID, bridge);
-            logger.debug("addInternalBridge : Updating Bridge {} with protocols {} and status {}", bridgeUUID, protocols, status);
+            logger.error("addPortToBridge: Could not find Port {} in Bridge {}, Node {}", portName, bridgeName, node);
+            return new Status(StatusCode.NOTFOUND, "Could not find "+portName+" in "+bridgeName);
         }
 
-        IConnectionServiceInternal connectionService = (IConnectionServiceInternal)ServiceHelper.getGlobalInstance(IConnectionServiceInternal.class, this);
-        connectionService.setOFController(node, bridgeUUID);
+        Port port = new Port();
+        port.setName(portName);
+        StatusWithUuid statusWithUuid = ovsdbTable.insertRow(node, Port.NAME.getName(), bridgeUUID, port);
+        if (!statusWithUuid.isSuccess()) {
+            logger.error("addPortToBridge: Failed to add Port {} in Bridge {}, Node {}", portName, bridgeName, node);
+            return statusWithUuid;
+        }
 
-        if (localPathName != null && remotePatchName != null && ProviderNetworkManager.getManager().hasPerTenantTunneling()) {
-            return addPatchPort(node, bridgeUUID, localPathName, remotePatchName);
+        String portUUID = statusWithUuid.getUuid().toString();
+        String interfaceUUID = null;
+        int timeout = 6;
+        while ((interfaceUUID == null) && (timeout > 0)) {
+            port = (Port)ovsdbTable.getRow(node, Port.NAME.getName(), portUUID);
+            OvsDBSet<UUID> interfaces = port.getInterfaces();
+            if (interfaces == null || interfaces.size() == 0) {
+                // Wait for the OVSDB update to sync up the Local cache.
+                Thread.sleep(500);
+                timeout--;
+                continue;
+            }
+            interfaceUUID = interfaces.toArray()[0].toString();
+            Interface intf = (Interface)ovsdbTable.getRow(node, Interface.NAME.getName(), interfaceUUID);
+            if (intf == null) {
+                interfaceUUID = null;
+            }
         }
+
+        if (interfaceUUID == null) {
+            logger.error("addPortToBridge: Cannot identify Interface for port {}/{}", portName, portUUID);
+            return new Status(StatusCode.INTERNALERROR);
+        }
+
         return new Status(StatusCode.SUCCESS);
     }
 
-    private Status addPatchPort (Node node, String bridgeUUID, String portName, String patchName) throws Exception {
+    private Status addPatchPort (Node node, String bridgeUUID, String portName, String peerPortName) throws Exception {
         OVSDBConfigService ovsdbTable = (OVSDBConfigService)ServiceHelper.getGlobalInstance(OVSDBConfigService.class, this);
 
+        logger.debug("addPatchPort: node: {}, bridgeUUID: {}, port: {}, peer: {}",
+                node, bridgeUUID, portName, peerPortName);
+
+        /* Check if the port already exists. */
+        Bridge bridge = (Bridge)ovsdbTable.getRow(node, Bridge.NAME.getName(), bridgeUUID);
+        if (bridge != null) {
+            if (isPortOnBridge(node, bridge, portName)) {
+                logger.debug("addPatchPort: Port {} already in Bridge, Node {}", portName, node);
+                return new Status(StatusCode.SUCCESS);
+            }
+        } else {
+            logger.error("addPatchPort: Could not find Port {} in Bridge, Node {}", portName, node);
+            return new Status(StatusCode.NOTFOUND, "Could not find "+portName+" in Bridge");
+        }
+
         Port patchPort = new Port();
         patchPort.setName(portName);
         // Create patch port and interface
@@ -203,20 +430,94 @@ public class InternalNetworkManager {
             return new Status(StatusCode.INTERNALERROR);
         }
 
-        Interface tunInterface = new Interface();
-        tunInterface.setType("patch");
+        Interface intf = new Interface();
+        intf.setType("patch");
         OvsDBMap<String, String> options = new OvsDBMap<String, String>();
-        options.put("peer", patchName);
-        tunInterface.setOptions(options);
-        return ovsdbTable.updateRow(node, Interface.NAME.getName(), patchPortUUID, interfaceUUID, tunInterface);
+        options.put("peer", peerPortName);
+        intf.setOptions(options);
+        return ovsdbTable.updateRow(node, Interface.NAME.getName(), patchPortUUID, interfaceUUID, intf);
+    }
+
+    private Status addInternalBridge (Node node, String bridgeName, String localPatchName, String remotePatchName) throws Exception {
+        OVSDBConfigService ovsdbTable = (OVSDBConfigService)ServiceHelper.getGlobalInstance(OVSDBConfigService.class, this);
+
+        String bridgeUUID = this.getInternalBridgeUUID(node, bridgeName);
+        Bridge bridge = new Bridge();
+        OvsDBSet<String> failMode = new OvsDBSet<String>();
+        failMode.add("secure");
+        bridge.setFail_mode(failMode);
+
+        OvsDBSet<String> protocols = new OvsDBSet<String>();
+        if (!ProviderNetworkManager.getManager().hasPerTenantTunneling()) {
+            protocols.add("OpenFlow13");
+        } else {
+            protocols.add("OpenFlow10");
+        }
+        bridge.setProtocols(protocols);
+
+        if (bridgeUUID == null) {
+            bridge.setName(bridgeName);
+
+            StatusWithUuid statusWithUuid = ovsdbTable.insertRow(node, Bridge.NAME.getName(), null, bridge);
+            if (!statusWithUuid.isSuccess()) return statusWithUuid;
+            bridgeUUID = statusWithUuid.getUuid().toString();
+            Port port = new Port();
+            port.setName(bridgeName);
+            Status status = ovsdbTable.insertRow(node, Port.NAME.getName(), bridgeUUID, port);
+            logger.debug("addInternalBridge: Inserting Bridge {} {} with protocols {} and status {}",
+                    bridgeName, bridgeUUID, protocols, status);
+        } else {
+            Status status = ovsdbTable.updateRow(node, Bridge.NAME.getName(), null, bridgeUUID, bridge);
+            logger.debug("addInternalBridge: Updating Bridge {} {} with protocols {} and status {}",
+                    bridgeName, bridgeUUID, protocols, status);
+        }
+
+        IConnectionServiceInternal connectionService = (IConnectionServiceInternal)ServiceHelper.getGlobalInstance(IConnectionServiceInternal.class, this);
+        connectionService.setOFController(node, bridgeUUID);
+
+        if (localPatchName != null && remotePatchName != null && ProviderNetworkManager.getManager().hasPerTenantTunneling()) {
+            return addPatchPort(node, bridgeUUID, localPatchName, remotePatchName);
+        }
+        return new Status(StatusCode.SUCCESS);
     }
 
     public void prepareInternalNetwork(Node node) {
         try {
-            this.createInternalNetworkForOverlay(node);
+            this.createIntegrationBridge(node);
         } catch (Exception e) {
             logger.error("Error creating internal network "+node.toString(), e);
         }
         ProviderNetworkManager.getManager().initializeFlowRules(node);
     }
-}
+
+    /*
+     * Check if the full network setup is available. If not, create it.
+     */
+    public boolean checkAndCreateNetwork (Node node, NeutronNetwork network) {
+        boolean isCreated = false;
+        if (network.getProviderNetworkType().equalsIgnoreCase("vlan")) {
+            if (!InternalNetworkManager.getManager().isInternalNetworkVlanReady(node, network)) {
+                try {
+                    isCreated = InternalNetworkManager.getManager().createNetNetwork(node, network);
+                } catch (Exception e) {
+                    logger.error("Error creating internal net network ", node, e);
+                }
+            } else {
+                isCreated = true;
+            }
+        } else if (network.getProviderNetworkType().equalsIgnoreCase("vxlan") ||
+                network.getProviderNetworkType().equalsIgnoreCase("gre")) {
+            if (!InternalNetworkManager.getManager().isInternalNetworkTunnelReady(node)) {
+                try {
+                    isCreated = InternalNetworkManager.getManager().createNetNetwork(node, network);
+                } catch (Exception e) {
+                    logger.error("Error creating internal net network ", node, e);
+                }
+            } else {
+                isCreated = true;
+            }
+        }
+
+        return isCreated;
+    }
+}
\ No newline at end of file
index 33fce3de65ff94c6b0b29e0e6266aa4c8c59fd2c..40097c8d20a25b6f6e378d5160315112ab9c5aba 100644 (file)
@@ -61,7 +61,7 @@ public class NetworkHandler extends BaseHandler
     @Override
     public void neutronNetworkCreated(NeutronNetwork network) {
         int result = HttpURLConnection.HTTP_BAD_REQUEST;
-
+        logger.trace("neutronNetworkCreated: network: {}", network);
         result = canCreateNetwork(network);
         if (result != HttpURLConnection.HTTP_CREATED) {
             logger.debug("Network creation failed {} ", result);
@@ -83,6 +83,7 @@ public class NetworkHandler extends BaseHandler
     @Override
     public int canUpdateNetwork(NeutronNetwork delta,
                                 NeutronNetwork original) {
+        logger.trace("canUpdateNetwork: network delta {} --- original {}", delta, original);
         return HttpURLConnection.HTTP_OK;
     }
 
@@ -93,6 +94,7 @@ public class NetworkHandler extends BaseHandler
      */
     @Override
     public void neutronNetworkUpdated(NeutronNetwork network) {
+        logger.trace("neutronNetworkUpdated: network: {}", network);
         return;
     }
 
@@ -117,6 +119,7 @@ public class NetworkHandler extends BaseHandler
     public void neutronNetworkDeleted(NeutronNetwork network) {
 
         int result = canDeleteNetwork(network);
+        logger.trace("canDeleteNetwork: network: {}", network);
         if  (result != HttpURLConnection.HTTP_OK) {
             logger.error(" deleteNetwork validation failed for result - {} ",
                     result);
index 868189706587bad9c8a27d4dce7c669f499da237..04b1f9625a742664d4be456bcbb7fe9b69655417 100644 (file)
@@ -43,7 +43,6 @@ public class NodeConfiguration {
 
 
     private void initializeNodeConfiguration(Node node) {
-
         int vlan = 0;
         String networkId = new String();
         OVSDBConfigService ovsdbTable = (OVSDBConfigService) ServiceHelper.getGlobalInstance(OVSDBConfigService.class, this);
@@ -66,7 +65,7 @@ public class NodeConfiguration {
                     vlan = tags[0].intValue();
                 }
                 else {
-                   logger.debug("This port has more {} interfaces", tags.length);
+                   logger.debug("This port ({}) has {} tags", port.getName(), tags.length);
                    continue;
                 }
 
@@ -88,6 +87,8 @@ public class NodeConfiguration {
                     this.internalVlanInUse(vlan);
                     this.tenantVlanMap.put(networkId, vlan);
 
+                } else {
+                    logger.debug("Node: {} initialized without a vlan", node);
                 }
             }
         }
@@ -96,6 +97,10 @@ public class NodeConfiguration {
         }
     }
 
+    /*
+     * Return the currently mapped internal vlan or get the next
+     * free internal vlan from the available pool and map it to the networkId.
+     */
     public int assignInternalVlan (String networkId) {
         Integer mappedVlan = tenantVlanMap.get(networkId);
         if (mappedVlan != null) return mappedVlan;
@@ -104,6 +109,9 @@ public class NodeConfiguration {
         return mappedVlan;
     }
 
+    /*
+     * Return the mapped internal vlan to the available pool.
+     */
     public int reclaimInternalVlan (String networkId) {
         Integer mappedVlan = tenantVlanMap.get(networkId);
         if (mappedVlan != null) {
@@ -114,10 +122,16 @@ public class NodeConfiguration {
         return 0;
     }
 
+    /*
+     * Remove the internal vlan from the available pool.
+     */
     public void internalVlanInUse (int vlan) {
         internalVlans.remove(vlan);
     }
 
+    /*
+     * Return a vlan from the mapped pool keyed by the networkId.
+     */
     public int getInternalVlan (String networkId) {
         Integer vlan = tenantVlanMap.get(networkId);
         if (vlan == null) return 0;
index 2efdb2b16c3b5c4ef760fabde3d35235d2ab07c6..a722fd61522f21f5db6f9a1f448b1ba71b899c0d 100644 (file)
@@ -5,7 +5,7 @@
  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
  * and is available at http://www.eclipse.org/legal/epl-v10.html
  *
- * Authors : Madhu Venugopal, Brent Salisbury
+ * Authors : Madhu Venugopal, Brent Salisbury, Sam Hague
  */
 package org.opendaylight.ovsdb.neutron;
 
@@ -105,7 +105,7 @@ public class SouthboundHandler extends BaseHandler implements OVSDBInventoryList
 
     @Override
     public void rowUpdated(Node node, String tableName, String uuid, Table<?> oldRow, Table<?> newRow) {
-        if (this.isUpdateOfInterest(oldRow, newRow)) {
+        if (this.isUpdateOfInterest(node, oldRow, newRow)) {
             this.enqueueEvent(new SouthboundEvent(node, tableName, uuid, newRow, SouthboundEvent.Action.UPDATE));
         }
     }
@@ -115,7 +115,7 @@ public class SouthboundHandler extends BaseHandler implements OVSDBInventoryList
      * (Especially stats update are fast and furious).
      */
 
-    private boolean isUpdateOfInterest(Table<?> oldRow, Table<?> newRow) {
+    private boolean isUpdateOfInterest(Node node, Table<?> oldRow, Table<?> newRow) {
         if (oldRow == null) return true;
         if (newRow.getTableName().equals(Interface.NAME)) {
             // We are NOT interested in Stats only updates
@@ -123,7 +123,7 @@ public class SouthboundHandler extends BaseHandler implements OVSDBInventoryList
             if (oldIntf.getName() == null && oldIntf.getExternal_ids() == null && oldIntf.getMac() == null &&
                 oldIntf.getOfport() == null && oldIntf.getOptions() == null && oldIntf.getOther_config() == null &&
                 oldIntf.getType() == null) {
-                logger.trace("IGNORING Interface Update : "+newRow.toString());
+                logger.trace("IGNORING Interface Update: node {}, row: {}", node, newRow);
                 return false;
             }
         } else if (newRow.getTableName().equals(Port.NAME)) {
@@ -131,7 +131,7 @@ public class SouthboundHandler extends BaseHandler implements OVSDBInventoryList
             Port oldPort = (Port)oldRow;
             if (oldPort.getName() == null && oldPort.getExternal_ids() == null && oldPort.getMac() == null &&
                 oldPort.getInterfaces() == null && oldPort.getTag() == null && oldPort.getTrunks() == null) {
-                logger.trace("IGNORING Port Update : "+newRow.toString());
+                logger.trace("IGNORING Port Update: node {}, row: {}", node, newRow);
                 return false;
             }
         } else if (newRow.getTableName().equals(Open_vSwitch.NAME)) {
@@ -156,7 +156,6 @@ public class SouthboundHandler extends BaseHandler implements OVSDBInventoryList
         } catch (InterruptedException e) {
             logger.error("Thread was interrupted while trying to enqueue event ", e);
         }
-
     }
 
     public void processNodeUpdate(Node node, SouthboundEvent.Action action) {
@@ -169,7 +168,7 @@ public class SouthboundHandler extends BaseHandler implements OVSDBInventoryList
                                   Object context, SouthboundEvent.Action action) {
         if (action == SouthboundEvent.Action.DELETE) {
             if (Interface.NAME.getName().equalsIgnoreCase(tableName)) {
-                logger.debug("processRowUpdate: {} Deleted node: {}, uuid: {}, row: {}", tableName,node, uuid, row);
+                logger.debug("processRowUpdate: {} Deleted node: {}, uuid: {}, row: {}", tableName, node, uuid, row);
                 Interface deletedIntf = (Interface)row;
                 NeutronNetwork network = null;
                 if (context == null) {
@@ -202,13 +201,13 @@ public class SouthboundHandler extends BaseHandler implements OVSDBInventoryList
             }
         }
         else if (Interface.NAME.getName().equalsIgnoreCase(tableName)) {
-            logger.debug("{} Added / Updated {} , {}, {}", tableName, node, uuid, row);
+            logger.debug("processRowUpdate: {} Added / Updated node: {}, uuid: {}, row: {}", tableName, node, uuid, row);
             Interface intf = (Interface)row;
             NeutronNetwork network = TenantNetworkManager.getManager().getTenantNetworkForInterface(intf);
             if (network != null && !network.getRouterExternal()) {
                 if (ProviderNetworkManager.getManager().hasPerTenantTunneling()) {
                     int vlan = TenantNetworkManager.getManager().networkCreated(node, network.getID());
-                    logger.trace("Neutron Network {} Created with Internal Vlan : {}", network.toString(), vlan);
+                    logger.trace("Neutron Network {}:{} Created with Internal Vlan: {}", network.getNetworkUUID(), network.getNetworkName(), vlan);
 
                     String portUUID = this.getPortIdForInterface(node, uuid, intf);
                     if (portUUID != null) {
@@ -218,7 +217,7 @@ public class SouthboundHandler extends BaseHandler implements OVSDBInventoryList
                 this.handleInterfaceUpdate(node, uuid, intf);
             }
         } else if (Port.NAME.getName().equalsIgnoreCase(tableName)) {
-            logger.debug("{} Added / Updated {} , {}, {}", tableName, node, uuid, row);
+            logger.debug("processRowUpdate: {} Added / Updated node: {}, uuid: {}, row: {}", tableName, node, uuid, row);
             Port port = (Port)row;
             Set<UUID> interfaceUUIDs = port.getInterfaces();
             for (UUID intfUUID : interfaceUUIDs) {
@@ -228,13 +227,15 @@ public class SouthboundHandler extends BaseHandler implements OVSDBInventoryList
                     NeutronNetwork network = TenantNetworkManager.getManager().getTenantNetworkForInterface(intf);
                     if (network != null && !network.getRouterExternal()) {
                         TenantNetworkManager.getManager().programTenantNetworkInternalVlan(node, uuid, network);
+                    } else {
+                        logger.trace("ignore update because there is not a neutron network.");
                     }
                 } catch (Exception e) {
                     logger.error("Failed to process row update", e);
                 }
             }
         } else if (Open_vSwitch.NAME.getName().equalsIgnoreCase(tableName)) {
-            logger.debug("{} Added / Updated {} , {}, {}", tableName, node, uuid, row);
+            logger.debug("processRowUpdate: {} Added / Updated node: {}, uuid: {}, row: {}", tableName, node, uuid, row);
             try {
                 ConcurrentMap<String, Table<?>> interfaces = this.ovsdbConfigService.getRows(node, Interface.NAME.getName());
                 if (interfaces != null) {
@@ -250,33 +251,34 @@ public class SouthboundHandler extends BaseHandler implements OVSDBInventoryList
     }
 
     private void handleInterfaceUpdate (Node node, String uuid, Interface intf) {
-        if (AdminConfigManager.getManager().getTunnelEndPoint(node) == null) {
-            logger.error("Tunnel end-point configuration missing. Please configure it in Open_vSwitch Table");
-            return;
-        }
+        logger.debug("handleInterfaceUpdate: node: {}, uuid: {}", node, uuid);
         NeutronNetwork network = TenantNetworkManager.getManager().getTenantNetworkForInterface(intf);
         if (network != null) {
-            ProviderNetworkManager.getManager().handleInterfaceUpdate(network.getProviderNetworkType(),
-                    network.getProviderSegmentationID(), node, intf);
+            if (InternalNetworkManager.getManager().checkAndCreateNetwork(node, network)) {
+                ProviderNetworkManager.getManager().handleInterfaceUpdate(network, node, intf);
+            }
         }
     }
+
     private void handleInterfaceDelete (Node node, String uuid, Interface intf, boolean isLastInstanceOnNode,
                                         NeutronNetwork network) {
+        logger.debug("handleInterfaceDelete: node: {}, uuid: {}, isLastInstanceOnNode: {}, interface: {}",
+                node, uuid, isLastInstanceOnNode, intf);
+
         if (intf.getType().equalsIgnoreCase("vxlan") || intf.getType().equalsIgnoreCase("gre")) {
             /* delete tunnel interfaces */
-            logger.debug("handlerInterfaceDelete: intf {}", intf);
-            ProviderNetworkManager.getManager().handleInterfaceDelete(intf.getType(),
-                                                null, node, intf, isLastInstanceOnNode);
+            ProviderNetworkManager.getManager().handleInterfaceDelete(intf.getType(), null, node, intf, isLastInstanceOnNode);
         } else if (network != null) {
-            if (AdminConfigManager.getManager().getTunnelEndPoint(node) == null) {
-                logger.error("Tunnel end-point configuration missing. Please configure it in Open_vSwitch Table");
-                return;
+            if (!network.getProviderNetworkType().equalsIgnoreCase("vlan")) { /* vlan doesn't need a tunnel endpoint */
+                if (AdminConfigManager.getManager().getTunnelEndPoint(node) == null) {
+                    logger.error("Tunnel end-point configuration missing. Please configure it in Open_vSwitch Table");
+                    return;
+                }
             }
             if (isLastInstanceOnNode & ProviderNetworkManager.getManager().hasPerTenantTunneling()) {
                 TenantNetworkManager.getManager().reclaimTennantNetworkInternalVlan(node, uuid, network);
             }
-            ProviderNetworkManager.getManager().handleInterfaceDelete(network.getProviderNetworkType(),
-                                              network.getProviderSegmentationID(), node, intf, isLastInstanceOnNode);
+            ProviderNetworkManager.getManager().handleInterfaceDelete(network.getProviderNetworkType(), network, node, intf, isLastInstanceOnNode);
         }
     }
 
@@ -290,7 +292,7 @@ public class SouthboundHandler extends BaseHandler implements OVSDBInventoryList
                 logger.trace("Scanning Port {} to identify interface : {} ",port, uuid);
                 for (UUID intfUUID : interfaceUUIDs) {
                     if (intfUUID.toString().equalsIgnoreCase(uuid)) {
-                        logger.trace("Found Interafce {} -> {}", uuid, portUUID);
+                        logger.trace("Found Interface {} -> {}", uuid, portUUID);
                         return portUUID;
                     }
                 }
@@ -303,7 +305,7 @@ public class SouthboundHandler extends BaseHandler implements OVSDBInventoryList
 
     @Override
     public void notifyNode(Node node, UpdateType type, Map<String, Property> propMap) {
-        logger.debug("Node {} update {} from Controller's inventory Service", node, type);
+        logger.debug("notifyNode: 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)) {
index 7131677c526018200f8dcf6bb5eaa5ca7bf980fe..c5050e344bd82d928ae2daaf3c3eb619f53e51b9 100644 (file)
@@ -5,7 +5,7 @@
  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
  * and is available at http://www.eclipse.org/legal/epl-v10.html
  *
- * Authors : Madhu Venugopal, Brent Salisbury
+ * Authors : Madhu Venugopal, Brent Salisbury, Sam Hague
  */
 package org.opendaylight.ovsdb.neutron.provider;
 
@@ -18,6 +18,7 @@ import java.util.Set;
 
 import org.opendaylight.controller.forwardingrulesmanager.FlowConfig;
 import org.opendaylight.controller.forwardingrulesmanager.IForwardingRulesManager;
+import org.opendaylight.controller.networkconfig.neutron.NeutronNetwork;
 import org.opendaylight.controller.sal.action.ActionType;
 import org.opendaylight.controller.sal.core.Node;
 import org.opendaylight.controller.sal.utils.EtherTypes;
@@ -48,7 +49,8 @@ class OF10ProviderManager extends ProviderNetworkManager {
     private static final Logger logger = LoggerFactory.getLogger(OF10ProviderManager.class);
     private static final int INGRESS_TUNNEL_FLOW_PRIORITY = 100;
     private static final int EGRESS_TUNNEL_FLOW_PRIORITY = 100;
-    private static final int FLOOD_TUNNEL_FLOW_PRIORITY = 1;
+    private static final int DROP_FLOW_PRIORITY = 10;
+    private static final int FLOOD_TUNNEL_FLOW_PRIORITY = 50;
 
     @Override
     public boolean hasPerTenantTunneling() {
@@ -68,8 +70,21 @@ class OF10ProviderManager extends ProviderNetworkManager {
         }
 
         if (!TenantNetworkManager.getManager().isTenantNetworkPresentInNode(node, tunnelKey)) {
-            logger.debug(node+" has no VM corresponding to segment "+ tunnelKey);
-            return new Status(StatusCode.NOTACCEPTABLE, node+" has no VM corresponding to segment "+ tunnelKey);
+            logger.debug(node+" has no network corresponding to segment "+ tunnelKey);
+            return new Status(StatusCode.NOTACCEPTABLE, node+" has no network corresponding to segment "+ tunnelKey);
+        }
+        return new Status(StatusCode.SUCCESS);
+    }
+
+    private Status getVlanReadinessStatus (Node node, String segmentationId) {
+        if (!InternalNetworkManager.getManager().isInternalNetworkOverlayReady(node)) {
+            logger.warn("{} is not Overlay ready. It might be an OpenStack Controller Node", node);
+            return new Status(StatusCode.NOTACCEPTABLE, node+" is not Overlay ready");
+        }
+
+        if (!TenantNetworkManager.getManager().isTenantNetworkPresentInNode(node, segmentationId)) {
+            logger.debug(node+" has no network corresponding to segment "+ segmentationId);
+            return new Status(StatusCode.NOTACCEPTABLE, node+" has no network corresponding to segment "+ segmentationId);
         }
         return new Status(StatusCode.SUCCESS);
     }
@@ -80,14 +95,14 @@ class OF10ProviderManager extends ProviderNetworkManager {
      * and rewrite the Corresponding internal Vlan and pass it on to br-int via the patch port.
      */
     private void programLocalIngressTunnelBridgeRules(Node node, int tunnelOFPort, int internalVlan, int patchPort) {
-        String brIntId = InternalNetworkManager.getManager().getInternalBridgeUUID(node, AdminConfigManager.getManager().getTunnelBridgeName());
-        if (brIntId == null) {
+        String brNetId = InternalNetworkManager.getManager().getInternalBridgeUUID(node, AdminConfigManager.getManager().getNetworkBridgeName());
+        if (brNetId == null) {
             logger.error("Failed to initialize Flow Rules for {}", node);
             return;
         }
         try {
             OVSDBConfigService ovsdbTable = (OVSDBConfigService)ServiceHelper.getGlobalInstance(OVSDBConfigService.class, this);
-            Bridge bridge = (Bridge) ovsdbTable.getRow(node, Bridge.NAME.getName(), brIntId);
+            Bridge bridge = (Bridge) ovsdbTable.getRow(node, Bridge.NAME.getName(), brNetId);
             Set<String> dpids = bridge.getDatapath_id();
             if (dpids == null || dpids.size() ==  0) return;
             Long dpidLong = Long.valueOf(HexEncode.stringToLong((String)dpids.toArray()[0]));
@@ -111,14 +126,14 @@ class OF10ProviderManager extends ProviderNetworkManager {
     }
 
     private void removeLocalIngressTunnelBridgeRules(Node node, int tunnelOFPort, int internalVlan, int patchPort) {
-        String brIntId = InternalNetworkManager.getManager().getInternalBridgeUUID(node, AdminConfigManager.getManager().getTunnelBridgeName());
-        if (brIntId == null) {
+        String brNetId = InternalNetworkManager.getManager().getInternalBridgeUUID(node, AdminConfigManager.getManager().getNetworkBridgeName());
+        if (brNetId == null) {
             logger.error("Failed to remove Flow Rules for {}", node);
             return;
         }
         try {
             OVSDBConfigService ovsdbTable = (OVSDBConfigService)ServiceHelper.getGlobalInstance(OVSDBConfigService.class, this);
-            Bridge bridge = (Bridge) ovsdbTable.getRow(node, Bridge.NAME.getName(), brIntId);
+            Bridge bridge = (Bridge) ovsdbTable.getRow(node, Bridge.NAME.getName(), brNetId);
             Set<String> dpids = bridge.getDatapath_id();
             if (dpids == null || dpids.size() ==  0) return;
             Long dpidLong = Long.valueOf(HexEncode.stringToLong((String)dpids.toArray()[0]));
@@ -141,14 +156,14 @@ class OF10ProviderManager extends ProviderNetworkManager {
      */
     private void programRemoteEgressTunnelBridgeRules(Node node, int patchPort, String attachedMac,
             int internalVlan, int tunnelOFPort) {
-        String brIntId = InternalNetworkManager.getManager().getInternalBridgeUUID(node, AdminConfigManager.getManager().getTunnelBridgeName());
-        if (brIntId == null) {
+        String brNetId = InternalNetworkManager.getManager().getInternalBridgeUUID(node, AdminConfigManager.getManager().getNetworkBridgeName());
+        if (brNetId == null) {
             logger.error("Failed to initialize Flow Rules for {}", node);
             return;
         }
         try {
             OVSDBConfigService ovsdbTable = (OVSDBConfigService)ServiceHelper.getGlobalInstance(OVSDBConfigService.class, this);
-            Bridge bridge = (Bridge) ovsdbTable.getRow(node, Bridge.NAME.getName(), brIntId);
+            Bridge bridge = (Bridge) ovsdbTable.getRow(node, Bridge.NAME.getName(), brNetId);
             Set<String> dpids = bridge.getDatapath_id();
             if (dpids == null || dpids.size() ==  0) return;
             Long dpidLong = Long.valueOf(HexEncode.stringToLong((String)dpids.toArray()[0]));
@@ -175,14 +190,14 @@ class OF10ProviderManager extends ProviderNetworkManager {
 
     private void removeRemoteEgressTunnelBridgeRules(Node node, int patchPort, String attachedMac,
             int internalVlan, int tunnelOFPort) {
-        String brIntId = InternalNetworkManager.getManager().getInternalBridgeUUID(node, AdminConfigManager.getManager().getTunnelBridgeName());
-        if (brIntId == null) {
+        String brNetId = InternalNetworkManager.getManager().getInternalBridgeUUID(node, AdminConfigManager.getManager().getNetworkBridgeName());
+        if (brNetId == null) {
             logger.error("Failed to initialize Flow Rules for {}", node);
             return;
         }
         try {
             OVSDBConfigService ovsdbTable = (OVSDBConfigService)ServiceHelper.getGlobalInstance(OVSDBConfigService.class, this);
-            Bridge bridge = (Bridge) ovsdbTable.getRow(node, Bridge.NAME.getName(), brIntId);
+            Bridge bridge = (Bridge) ovsdbTable.getRow(node, Bridge.NAME.getName(), brNetId);
             Set<String> dpids = bridge.getDatapath_id();
             if (dpids == null || dpids.size() ==  0) return;
             Long dpidLong = Long.valueOf(HexEncode.stringToLong((String)dpids.toArray()[0]));
@@ -203,14 +218,14 @@ class OF10ProviderManager extends ProviderNetworkManager {
      * Also perform the Strip-Vlan action.
      */
     private void programFloodEgressTunnelBridgeRules(Node node, int patchPort, int internalVlan, int tunnelOFPort) {
-        String brIntId = InternalNetworkManager.getManager().getInternalBridgeUUID(node, AdminConfigManager.getManager().getTunnelBridgeName());
-        if (brIntId == null) {
+        String brNetId = InternalNetworkManager.getManager().getInternalBridgeUUID(node, AdminConfigManager.getManager().getNetworkBridgeName());
+        if (brNetId == null) {
             logger.error("Failed to initialize Flow Rules for {}", node);
             return;
         }
         try {
             OVSDBConfigService ovsdbTable = (OVSDBConfigService)ServiceHelper.getGlobalInstance(OVSDBConfigService.class, this);
-            Bridge bridge = (Bridge) ovsdbTable.getRow(node, Bridge.NAME.getName(), brIntId);
+            Bridge bridge = (Bridge) ovsdbTable.getRow(node, Bridge.NAME.getName(), brNetId);
             Set<String> dpids = bridge.getDatapath_id();
             if (dpids == null || dpids.size() ==  0) return;
             Long dpidLong = Long.valueOf(HexEncode.stringToLong((String)dpids.toArray()[0]));
@@ -257,14 +272,14 @@ class OF10ProviderManager extends ProviderNetworkManager {
     }
 
     private void removeFloodEgressTunnelBridgeRules(Node node, int patchPort, int internalVlan, int tunnelOFPort) {
-        String brIntId = InternalNetworkManager.getManager().getInternalBridgeUUID(node, AdminConfigManager.getManager().getTunnelBridgeName());
-        if (brIntId == null) {
+        String brNetId = InternalNetworkManager.getManager().getInternalBridgeUUID(node, AdminConfigManager.getManager().getNetworkBridgeName());
+        if (brNetId == null) {
             logger.error("Failed to remove Flow Rules for {}", node);
             return;
         }
         try {
             OVSDBConfigService ovsdbTable = (OVSDBConfigService)ServiceHelper.getGlobalInstance(OVSDBConfigService.class, this);
-            Bridge bridge = (Bridge) ovsdbTable.getRow(node, Bridge.NAME.getName(), brIntId);
+            Bridge bridge = (Bridge) ovsdbTable.getRow(node, Bridge.NAME.getName(), brNetId);
             Set<String> dpids = bridge.getDatapath_id();
             if (dpids == null || dpids.size() ==  0) return;
             Long dpidLong = Long.valueOf(HexEncode.stringToLong((String)dpids.toArray()[0]));
@@ -293,7 +308,7 @@ class OF10ProviderManager extends ProviderNetworkManager {
                                      Interface intf, boolean local) {
         String networkId = TenantNetworkManager.getManager().getNetworkIdForSegmentationId(segmentationId);
         if (networkId == null) {
-            logger.debug("Tenant Network not found with Segmenation-id {}",segmentationId);
+            logger.debug("Tenant Network not found with Segmentation-id {}", segmentationId);
             return;
         }
         int internalVlan = TenantNetworkManager.getManager().getInternalVlan(node, networkId);
@@ -369,7 +384,7 @@ class OF10ProviderManager extends ProviderNetworkManager {
             Interface intf, boolean local) {
         String networkId = TenantNetworkManager.getManager().getNetworkIdForSegmentationId(segmentationId);
         if (networkId == null) {
-            logger.debug("Tenant Network not found with Segmenation-id {}",segmentationId);
+            logger.debug("Tenant Network not found with Segmentation-id {}",segmentationId);
             return;
         }
         int internalVlan = TenantNetworkManager.getManager().getInternalVlan(node,networkId);
@@ -441,38 +456,347 @@ class OF10ProviderManager extends ProviderNetworkManager {
         }
     }
 
+    private String getIntModVlanFlowName (int inOFPort, String fromVlan, String toVlan) {
+        return "int_mod_"+inOFPort+"_"+fromVlan+"_"+toVlan;
+    }
+
+    private String getIntDropFlowName (int inOFPort) {
+        return "int_drop_"+inOFPort;
+    }
+
+    private String getNetModVlanFlowName (int inOFPort, String fromVlan, String toVlan) {
+        return "net_mod_"+inOFPort+"_"+fromVlan+"_"+toVlan;
+    }
+
+    private String getNetDropFlowName (int inOFPort) {
+        return "net_drop_"+inOFPort;
+    }
+
+    private String getNetFwdFlowName (int inOFPort, int outOFPort, String vlan) {
+        return "net_fwd_"+vlan+"_"+inOFPort+"_"+outOFPort;
+    }
+
+    private void deleteRule (Node node, Node ofNode, String flowName) {
+        logger.debug("deleteRule: node: {} / {}, flowName: {}", node, ofNode, flowName);
+
+        try {
+            this.deleteStaticFlow(ofNode, flowName);
+        } catch (Exception e) {
+            logger.error("deleteRule: Failed to delete Flow Rule for {} / {}", node, ofNode, e);
+        }
+    }
+
+    /* in_port=p actions=drop */
+    private void programDropRule (Node node, Node ofNode, int inOFPort, String flowName) {
+        logger.debug("programDropRule: node: {} / {}, inOfPort: {}, flowName: {}",
+                node, ofNode, inOFPort, flowName);
+
+        try {
+            FlowConfig flow = new FlowConfig();
+            flow.setName(flowName);
+            flow.setNode(ofNode);
+            flow.setInstallInHw(true);
+            flow.setPriority(DROP_FLOW_PRIORITY+"");
+            flow.setIngressPort(inOFPort+"");
+            List<String> actions = new ArrayList<String>();
+            actions.add(ActionType.DROP+"");
+            flow.setActions(actions);
+            Status status = this.addStaticFlow(ofNode, flow);
+            logger.debug("programDropRule: Flow Programming Status {} for Flow {} on {} / {}",
+                    status, flow, node, ofNode);
+        } catch (Exception e) {
+            logger.error("programDropRule: Failed to initialize Flow Rules for {} / {}", node, ofNode, e);
+        }
+    }
+
+    /* in_port=p2,dl_vlan=v actions=mod_vlan_vid,[NORMAL|output:p2] */
+    private void programModVlanRule (Node node, Node ofNode, int inOFPort, int outOFPort, String fromVlan,
+                                     String toVlan, String flowName) {
+        logger.debug("programModVlanRule: node: {} / {}, inOfPort: {}, fromVlan: {}, toVlan: {}, flowName: {}",
+                node, ofNode, inOFPort, fromVlan, toVlan, flowName);
+
+        try {
+            FlowConfig flow = new FlowConfig();
+            flow.setName(flowName);
+            flow.setNode(ofNode);
+            flow.setInstallInHw(true);
+            flow.setPriority(INGRESS_TUNNEL_FLOW_PRIORITY+"");
+            flow.setIngressPort(inOFPort+"");
+            flow.setVlanId(fromVlan);
+            List<String> actions = new ArrayList<String>();
+            actions.add(ActionType.SET_VLAN_ID+"="+toVlan);
+            if (outOFPort == -1) {
+                actions.add(ActionType.HW_PATH.toString());
+            } else {
+                actions.add(ActionType.OUTPUT.toString()+"="+outOFPort);
+            }
+            flow.setActions(actions);
+            Status status = this.addStaticFlow(ofNode, flow);
+            logger.debug("programModVlanRule: Flow Programming Status {} for Flow {} on {} / {}",
+                    status, flow, node, ofNode);
+        } catch (Exception e) {
+            logger.error("programModVlanRule: Failed to initialize Flow Rule for {} / {}", node, ofNode, e);
+        }
+    }
+
+    /* in_port=p1,dl_vlan=v actions=output:p2 */
+    private void programForwardRule (Node node, Node ofNode, int inOFPort, int outOFPort, String vlan, String flowName) {
+        logger.debug("programModVlanRule: node: {} / {}, inOfPort: {}, outOFPort: {}, flowName: {}",
+                node, ofNode, inOFPort, outOFPort, flowName);
+
+        try {
+            FlowConfig flow = new FlowConfig();
+            flow.setName(flowName);
+            flow.setNode(ofNode);
+            flow.setInstallInHw(true);
+            flow.setPriority(EGRESS_TUNNEL_FLOW_PRIORITY + "");
+            flow.setIngressPort(inOFPort + "");
+            flow.setVlanId(vlan);
+            List<String> actions = new ArrayList<String>();
+            actions.add(ActionType.OUTPUT.toString()+"="+outOFPort);
+            flow.setActions(actions);
+            Status status = this.addStaticFlow(ofNode, flow);
+            logger.debug("programForwardRule: Flow Programming Status {} for Flow {} on {} / {}",
+                    status, flow, node, ofNode);
+        } catch (Exception e) {
+            logger.error("programForwardRule: Failed to initialize Flow Rules for {} / {}", node, ofNode, e);
+        }
+    }
+
+    public int getOFPort (Node node, String portName) {
+        int ofPort = -1;
+        try {
+            OVSDBConfigService ovsdbTable = (OVSDBConfigService)ServiceHelper.getGlobalInstance(OVSDBConfigService.class, this);
+            Map<String, Table<?>> intfs = ovsdbTable.getRows(node, Interface.NAME.getName());
+            if (intfs != null) {
+                for (Table<?> row : intfs.values()) {
+                    Interface intf = (Interface)row;
+                    if (intf.getName().equalsIgnoreCase(portName)) {
+                        Set<BigInteger> of_ports = intf.getOfport();
+                        if (of_ports == null || of_ports.size() <= 0) {
+                            logger.error("Could not identify patch port {} on {}", portName, node);
+                            continue;
+                        }
+                        ofPort = Long.valueOf(((BigInteger)of_ports.toArray()[0]).longValue()).intValue();
+                        logger.debug("Identified port {} -> OF ({}) on {}", portName, ofPort, node);
+                        break;
+                    }
+                }
+            }
+        } catch (Exception e) {
+            logger.error("", e);
+        }
+
+        return ofPort;
+    }
+
+    /*
+     * Transient class to return all the vlan network data needed for flow programming.
+     */
+    public class vlanNet {
+        public int patchIntOfPort;
+        public int patchNetOfPort;
+        public int physicalOfPort;
+        public int internalVlan;
+
+        public vlanNet (NeutronNetwork network, Node node, Interface intf) {
+            patchIntOfPort = -1;
+            patchNetOfPort = -1;
+            physicalOfPort = -1;
+            internalVlan = 0;
+
+            initializeVlanNet(network, node, intf);
+        }
+
+        public boolean isValid () {
+            if ((patchIntOfPort != -1) && (patchNetOfPort != -1) && (physicalOfPort != -1) && (internalVlan != -1)) {
+                return true;
+            } else {
+                return false;
+            }
+        }
+
+        public int getPatchIntOfPort () {
+            return patchIntOfPort;
+        }
+
+        public int getPatchNetOfPort () {
+            return patchNetOfPort;
+        }
+
+        public int getphysicalOfPort () {
+            return physicalOfPort;
+        }
+
+        public int getInternalVlan () {
+            return internalVlan;
+        }
+
+        public void initializeVlanNet (NeutronNetwork network, Node node, Interface intf) {
+            internalVlan = TenantNetworkManager.getManager().getInternalVlan(node, network.getNetworkUUID());
+            if (internalVlan == 0) {
+                logger.debug("No InternalVlan provisioned for Tenant Network {}", network.getNetworkUUID());
+                return;
+            }
+
+            /* Get ofports for patch ports and physical interface. */
+            String patchToNetworkName = AdminConfigManager.getManager().getPatchToNetwork();
+            String patchToIntegrationName = AdminConfigManager.getManager().getPatchToIntegration();
+            String physNetName = AdminConfigManager.getManager().getPhysicalInterfaceName(node, network.getProviderPhysicalNetwork());
+
+            patchIntOfPort = getOFPort(node, patchToNetworkName);
+            if (patchIntOfPort == -1) {
+                logger.error("Cannot identify {} interface on {}", patchToNetworkName, node);
+                return;
+            }
+
+            patchNetOfPort = getOFPort(node, patchToIntegrationName);
+            if (patchNetOfPort == -1) {
+                logger.error("Cannot identify {} interface on {}", patchToIntegrationName, node);
+                return;
+            }
+
+            physicalOfPort = getOFPort(node, physNetName);
+            if (physicalOfPort == -1) {
+                logger.error("Cannot identify {} interface on {}", physNetName, node);
+                return;
+            }
+        }
+    }
+
+    private Node getOFNode (Node node, String bridgeName) {
+        String brUUID = InternalNetworkManager.getManager().getInternalBridgeUUID(node, bridgeName);
+        if (brUUID == null) {
+            logger.error("getOFNode: Unable to find {} UUID on node {}", bridgeName, node);
+            return null;
+        }
+
+        try {
+            OVSDBConfigService ovsdbTable = (OVSDBConfigService)ServiceHelper.getGlobalInstance(OVSDBConfigService.class, this);
+            Bridge bridge = (Bridge) ovsdbTable.getRow(node, Bridge.NAME.getName(), brUUID);
+            Set<String> dpids = bridge.getDatapath_id();
+            if (dpids == null || dpids.size() ==  0) {
+                return null;
+            }
+            Long dpidLong = Long.valueOf(HexEncode.stringToLong((String)dpids.toArray()[0]));
+            Node ofNode = new Node(Node.NodeIDType.OPENFLOW, dpidLong);
+            return ofNode;
+        } catch (Exception e) {
+            logger.error("deleteRule: Failed to delete Flow Rule for {}", node, e);
+        }
+
+        return null;
+    }
+
+    /*
+     * Vlan isolation uses a patch port between br-int and br-net. Anything received on one end of
+     * the patch is piped to the other end of the patch so the incoming packets from the network would
+     * arrive untouched at the patch port on br-int.
+     *
+     * Program OF1.0 Flow rules on br-net in the ingress direction from the network
+     * and egress direction towards the network.
+     * The logic is to simply match on the incoming patch OF-Port and internal vlan,
+     * rewrite the internal vlan to the external vlan and forward out the physical port.
+     * There is also a flow to match the externally tagged packets from the physical port
+     * rewrite the external tag to the internal tag and forward to the patch port.
+     *
+     * priority=100,in_port=1,dl_vlan=1 actions=mod_vlan_vid:2001,output:2
+     * priority=100,in_port=2,dl_vlan=2001 actions=mod_vlan_vid:1actions=output:1
+     */
+
+    private void programVlanRules (NeutronNetwork network, Node node, Interface intf) {
+        vlanNet vlanNet = new vlanNet(network, node, intf);
+        if (vlanNet.isValid()) {
+            String netBrName = AdminConfigManager.getManager().getNetworkBridgeName();
+            String intModVlanFlowName = getIntModVlanFlowName(vlanNet.getPatchNetOfPort(), network.getProviderSegmentationID(), vlanNet.getInternalVlan()+"");
+            String netModVlanFlowName = getNetModVlanFlowName(vlanNet.getPatchNetOfPort(), vlanNet.getInternalVlan()+"", network.getProviderSegmentationID());
+
+            Node netOFNode = getOFNode(node, netBrName);
+            if (netOFNode == null) {
+                logger.error("Unable to find {} ofNode, Failed to initialize Flow Rules for {}", netBrName, node);
+                return;
+            }
+
+            /* Program flows on br-net */
+            deleteRule(node, netOFNode, "NORMAL");
+            programModVlanRule(node, netOFNode, vlanNet.getPatchNetOfPort(), vlanNet.getphysicalOfPort(),
+                    vlanNet.getInternalVlan()+"", network.getProviderSegmentationID(), intModVlanFlowName);
+            programModVlanRule(node, netOFNode, vlanNet.getphysicalOfPort(), vlanNet.getPatchNetOfPort(),
+                    network.getProviderSegmentationID(), vlanNet.getInternalVlan()+"", netModVlanFlowName);
+        }
+    }
+
+    private void removeVlanRules (NeutronNetwork network, Node node, Interface intf) {
+        vlanNet vlanNet = new vlanNet(network, node, intf);
+        if (vlanNet.isValid()) {
+            String netBrName = AdminConfigManager.getManager().getNetworkBridgeName();
+            String intModVlanFlowName = getIntModVlanFlowName(vlanNet.getPatchNetOfPort(), network.getProviderSegmentationID(), vlanNet.getInternalVlan()+"");
+            String netModVlanFlowName = getNetModVlanFlowName(vlanNet.getPatchNetOfPort(), vlanNet.getInternalVlan()+"", network.getProviderSegmentationID());
+
+            Node netOFNode = getOFNode(node, netBrName);
+            if (netOFNode == null) {
+                logger.error("Unable to find {} ofNode, Failed to initialize Flow Rules for {}", netBrName, node);
+                return;
+            }
+
+            deleteRule(node, netOFNode, intModVlanFlowName);
+            deleteRule(node, netOFNode, netModVlanFlowName);
+        }
+    }
+
     @Override
-    public Status handleInterfaceUpdate(String tunnelType, String tunnelKey, Node srcNode, Interface intf) {
-        Status status = getTunnelReadinessStatus(srcNode, tunnelKey);
-        if (!status.isSuccess()) return status;
+    public Status handleInterfaceUpdate(NeutronNetwork network, Node srcNode, Interface intf) {
+        logger.debug("handleInterfaceUpdate: networkType: {}, segmentationId: {}, srcNode: {}, intf: {}",
+                     network.getProviderNetworkType(), network.getProviderSegmentationID(), srcNode, intf.getName());
 
-        IConnectionServiceInternal connectionService = (IConnectionServiceInternal)ServiceHelper.getGlobalInstance(IConnectionServiceInternal.class, this);
-        List<Node> nodes = connectionService.getNodes();
-        nodes.remove(srcNode);
-        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, tunnelKey);
-            if (status.isSuccess()) {
-                this.programTunnelRules(tunnelType, tunnelKey, dst, srcNode, intf, true);
+        if (network.getProviderNetworkType().equalsIgnoreCase("vlan")) {
+            Status status = getVlanReadinessStatus(srcNode, network.getProviderSegmentationID());
+            if (!status.isSuccess()) {
+                return status;
+            } else {
+                this.programVlanRules(network, srcNode, intf);
+                return new Status(StatusCode.SUCCESS);
             }
-            addTunnelPort(dstNode, tunnelType, dst, src, tunnelKey);
-            if (status.isSuccess()) {
-                this.programTunnelRules(tunnelType, tunnelKey, src, dstNode, intf, false);
+        } else if (network.getProviderNetworkType().equalsIgnoreCase("vxlan") ||
+                   network.getProviderNetworkType().equalsIgnoreCase("gre")) {
+            Status status = getTunnelReadinessStatus(srcNode, network.getProviderSegmentationID());
+            if (!status.isSuccess()) return status;
+
+            IConnectionServiceInternal connectionService = (IConnectionServiceInternal)ServiceHelper.getGlobalInstance(IConnectionServiceInternal.class, this);
+            List<Node> nodes = connectionService.getNodes();
+            nodes.remove(srcNode);
+            for (Node dstNode : nodes) {
+                status = getTunnelReadinessStatus(dstNode, network.getProviderSegmentationID());
+                if (!status.isSuccess()) continue;
+                InetAddress src = AdminConfigManager.getManager().getTunnelEndPoint(srcNode);
+                InetAddress dst = AdminConfigManager.getManager().getTunnelEndPoint(dstNode);
+                status = addTunnelPort(srcNode, network.getProviderNetworkType(), src, dst, network.getProviderSegmentationID());
+                if (status.isSuccess()) {
+                    this.programTunnelRules(network.getProviderNetworkType(), network.getProviderSegmentationID(), dst, srcNode, intf, true);
+                }
+                addTunnelPort(dstNode, network.getProviderNetworkType(), dst, src, network.getProviderSegmentationID());
+                if (status.isSuccess()) {
+                    this.programTunnelRules(network.getProviderNetworkType(), network.getProviderSegmentationID(), src, dstNode, intf, false);
+                }
             }
+            return new Status(StatusCode.SUCCESS);
+        } else {
+            return new Status(StatusCode.BADREQUEST);
         }
-        return new Status(StatusCode.SUCCESS);
     }
 
     @Override
-    public Status handleInterfaceDelete(String tunnelType, String tunnelKey, Node srcNode, Interface intf, boolean isLastInstanceOnNode) {
+    public Status handleInterfaceDelete(String tunnelType, NeutronNetwork network, Node srcNode, Interface intf, boolean isLastInstanceOnNode) {
         Status status = new Status(StatusCode.SUCCESS);
-        logger.debug("handleInterfaceDelete: networkType: {}, segmentationId: {}, srcNode: {}, intf:{}",
-                     tunnelType, tunnelKey, srcNode,
-                     intf.getName(), isLastInstanceOnNode);
-        if (intf.getType().equalsIgnoreCase("vxlan") || intf.getType().equalsIgnoreCase("gre")) {
+        logger.debug("handleInterfaceDelete: srcNode: {}, networkType: {}, intf: {}, type: {}, isLast: {}",
+                srcNode, (network != null) ? network.getProviderNetworkType() : "",
+                intf.getName(), intf.getType(), isLastInstanceOnNode);
+
+        if ((network != null) && network.getProviderNetworkType().equalsIgnoreCase("vlan")) {
+            if (isLastInstanceOnNode) {
+                this.removeVlanRules(network, srcNode, intf);
+            }
+        } else if (intf.getType().equalsIgnoreCase("vxlan") || intf.getType().equalsIgnoreCase("gre")) {
             /* Delete tunnel port */
             try {
                 OvsDBMap<String, String> options = intf.getOptions();
@@ -491,16 +815,17 @@ class OF10ProviderManager extends ProviderNetworkManager {
             for (Node dstNode : nodes) {
                 InetAddress src = AdminConfigManager.getManager().getTunnelEndPoint(srcNode);
                 InetAddress dst = AdminConfigManager.getManager().getTunnelEndPoint(dstNode);
-                this.removeTunnelRules(tunnelType, tunnelKey, dst, srcNode, intf, true);
+                this.removeTunnelRules(network.getProviderNetworkType(), network.getProviderSegmentationID(), dst, srcNode, intf, true);
                 if (isLastInstanceOnNode) {
-                    status = deleteTunnelPort(srcNode, tunnelType, src, dst, tunnelKey);
+                    status = deleteTunnelPort(srcNode, network.getProviderNetworkType(), src, dst, network.getProviderSegmentationID());
                 }
-                this.removeTunnelRules(tunnelType, tunnelKey, src, dstNode, intf, false);
+                this.removeTunnelRules(network.getProviderNetworkType(), network.getProviderSegmentationID(), src, dstNode, intf, false);
                 if (status.isSuccess() && isLastInstanceOnNode) {
-                    deleteTunnelPort(dstNode, tunnelType, dst, src, tunnelKey);
+                    deleteTunnelPort(dstNode, network.getProviderNetworkType(), dst, src, network.getProviderSegmentationID());
                 }
             }
         }
+
         return status;
     }
 
@@ -556,7 +881,7 @@ class OF10ProviderManager extends ProviderNetworkManager {
     private Status addTunnelPort (Node node, String tunnelType, InetAddress src, InetAddress dst, String key) {
         try {
             String bridgeUUID = null;
-            String tunnelBridgeName = AdminConfigManager.getManager().getTunnelBridgeName();
+            String tunnelBridgeName = AdminConfigManager.getManager().getNetworkBridgeName();
             OVSDBConfigService ovsdbTable = (OVSDBConfigService)ServiceHelper.getGlobalInstance(OVSDBConfigService.class, this);
             Map<String, Table<?>> bridgeTable = ovsdbTable.getRows(node, Bridge.NAME.getName());
             if (bridgeTable != null) {
@@ -628,7 +953,7 @@ class OF10ProviderManager extends ProviderNetworkManager {
     private Status deleteTunnelPort (Node node, String tunnelType, InetAddress src, InetAddress dst, String key) {
         try {
             String bridgeUUID = null;
-            String tunnelBridgeName = AdminConfigManager.getManager().getTunnelBridgeName();
+            String tunnelBridgeName = AdminConfigManager.getManager().getNetworkBridgeName();
             OVSDBConfigService ovsdbTable = (OVSDBConfigService)ServiceHelper.getGlobalInstance(OVSDBConfigService.class, this);
             Map<String, Table<?>> bridgeTable = ovsdbTable.getRows(node, Bridge.NAME.getName());
             if (bridgeTable != null) {
@@ -665,7 +990,7 @@ class OF10ProviderManager extends ProviderNetworkManager {
         IConnectionServiceInternal connectionService = (IConnectionServiceInternal)ServiceHelper.getGlobalInstance(IConnectionServiceInternal.class, this);
         List<Node> nodes = connectionService.getNodes();
         for (Node srcNode : nodes) {
-            this.handleInterfaceUpdate(tunnelType, tunnelKey, srcNode, null);
+            this.handleInterfaceUpdate(null, srcNode, null);
         }
         return new Status(StatusCode.SUCCESS);
     }
@@ -673,7 +998,6 @@ class OF10ProviderManager extends ProviderNetworkManager {
     @Override
     public void initializeFlowRules(Node node) {
         this.initializeFlowRules(node, AdminConfigManager.getManager().getIntegrationBridgeName());
-        this.initializeFlowRules(node, AdminConfigManager.getManager().getTunnelBridgeName());
         this.initializeFlowRules(node, AdminConfigManager.getManager().getExternalBridgeName());
     }
 
@@ -766,7 +1090,7 @@ class OF10ProviderManager extends ProviderNetworkManager {
         IForwardingRulesManager frm = (IForwardingRulesManager) ServiceHelper.getInstance(
                 IForwardingRulesManager.class, "default", this);
         if (frm.getStaticFlow(flowName, ofNode) == null) {
-            logger.debug("Flow doese not exist {} on {}. Skipping deletion.", flowName, ofNode);
+            logger.debug("Flow does not exist {} on {}. Skipping deletion.", flowName, ofNode);
             return new Status(StatusCode.SUCCESS);
         }
         return frm.removeStaticFlow(flowName,ofNode);
index 1f864e0d78b84208172c32f7fdadb54c1e6b3605..084adf08c0b1d5956d266d3906e880dc3881e60b 100644 (file)
@@ -720,7 +720,7 @@ class OF13ProviderManager extends ProviderNetworkManager {
     }
 
     @Override
-    public Status handleInterfaceUpdate(String tunnelType, String tunnelKey, Node srcNode, Interface intf) {
+    public Status handleInterfaceUpdate(NeutronNetwork network, Node srcNode, Interface intf) {
         ISwitchManager switchManager = (ISwitchManager) ServiceHelper.getInstance(ISwitchManager.class, "default", this);
         if (switchManager == null) {
             logger.error("Unable to identify SwitchManager");
@@ -752,18 +752,18 @@ class OF13ProviderManager extends ProviderNetworkManager {
         IConnectionServiceInternal connectionService = (IConnectionServiceInternal)ServiceHelper.getGlobalInstance(IConnectionServiceInternal.class, this);
         List<Node> nodes = connectionService.getNodes();
         nodes.remove(srcNode);
-        this.programLocalRules(tunnelType, tunnelKey, srcNode, intf);
+        this.programLocalRules(network.getProviderNetworkType(), network.getProviderSegmentationID(), srcNode, intf);
 
         for (Node dstNode : nodes) {
             InetAddress src = AdminConfigManager.getManager().getTunnelEndPoint(srcNode);
             InetAddress dst = AdminConfigManager.getManager().getTunnelEndPoint(dstNode);
-            Status status = addTunnelPort(srcNode, tunnelType, src, dst);
+            Status status = addTunnelPort(srcNode, network.getProviderNetworkType(), src, dst);
             if (status.isSuccess()) {
-                this.programTunnelRules(tunnelType, tunnelKey, dst, srcNode, intf, true);
+                this.programTunnelRules(network.getProviderNetworkType(), network.getProviderSegmentationID(), dst, srcNode, intf, true);
             }
-            addTunnelPort(dstNode, tunnelType, dst, src);
+            addTunnelPort(dstNode, network.getProviderNetworkType(), dst, src);
             if (status.isSuccess()) {
-                this.programTunnelRules(tunnelType, tunnelKey, src, dstNode, intf, false);
+                this.programTunnelRules(network.getProviderNetworkType(), network.getProviderSegmentationID(), src, dstNode, intf, false);
             }
         }
 
@@ -780,7 +780,7 @@ class OF13ProviderManager extends ProviderNetworkManager {
                     NeutronNetwork network = TenantNetworkManager.getManager().getTenantNetworkForInterface(intf);
                     logger.debug("Trigger Interface update for {}", intf);
                     if (network != null) {
-                        this.handleInterfaceUpdate(network.getProviderNetworkType(), network.getProviderSegmentationID(), node, intf);
+                        this.handleInterfaceUpdate(network, node, intf);
                     }
                 }
             }
@@ -797,7 +797,7 @@ class OF13ProviderManager extends ProviderNetworkManager {
     }
 
     @Override
-    public Status handleInterfaceDelete(String tunnelType, String tunnelKey, Node srcNode, Interface intf,
+    public Status handleInterfaceDelete(String tunnelType, NeutronNetwork network, Node srcNode, Interface intf,
             boolean isLastInstanceOnNode) {
         Status status = new Status(StatusCode.SUCCESS);
         IConnectionServiceInternal connectionService = (IConnectionServiceInternal)ServiceHelper.getGlobalInstance(IConnectionServiceInternal.class, this);
@@ -817,7 +817,7 @@ class OF13ProviderManager extends ProviderNetworkManager {
              }
         } else {
             /* delete all other interfaces */
-            this.removeLocalRules(tunnelType, tunnelKey,
+            this.removeLocalRules(tunnelType, network.getProviderSegmentationID(),
                                   srcNode, intf);
 
             if (tunnelType.equalsIgnoreCase("gre")
@@ -826,10 +826,10 @@ class OF13ProviderManager extends ProviderNetworkManager {
                     InetAddress src = AdminConfigManager.getManager().getTunnelEndPoint(srcNode);
                     InetAddress dst = AdminConfigManager.getManager().getTunnelEndPoint(dstNode);
                     logger.info("Remove tunnel rules for interface " + intf.getName() + " on srcNode" + srcNode.getNodeIDString());
-                    this.removeTunnelRules(tunnelType, tunnelKey,
+                    this.removeTunnelRules(tunnelType, network.getProviderSegmentationID(),
                                            dst, srcNode, intf, true, isLastInstanceOnNode);
                     logger.info("Remove tunnel rules for interface " + intf.getName() + " on dstNode" + dstNode.getNodeIDString());
-                    this.removeTunnelRules(tunnelType, tunnelKey,
+                    this.removeTunnelRules(tunnelType, network.getProviderSegmentationID(),
                                            src, dstNode, intf, false, isLastInstanceOnNode);
                 }
             }
index 8340a20bef9a9abde358404e29817e91d8664e6c..7bb3ae765743ba05f6d7073998bf1978297d7f60 100644 (file)
@@ -11,6 +11,7 @@ package org.opendaylight.ovsdb.neutron.provider;
 
 import java.util.Map;
 
+import org.opendaylight.controller.networkconfig.neutron.NeutronNetwork;
 import org.opendaylight.controller.sal.core.Node;
 import org.opendaylight.controller.sal.utils.ServiceHelper;
 import org.opendaylight.controller.sal.utils.Status;
@@ -61,8 +62,8 @@ public abstract class ProviderNetworkManager {
 
     public abstract boolean hasPerTenantTunneling();
     public abstract Status handleInterfaceUpdate(String tunnelType, String tunnelKey);
-    public abstract Status handleInterfaceUpdate(String tunnelType, String tunnelKey, Node source, Interface intf);
-    public abstract Status handleInterfaceDelete(String tunnelType, String tunnelKey, Node source, Interface intf, boolean isLastInstanceOnNode);
+    public abstract Status handleInterfaceUpdate(NeutronNetwork network, Node source, Interface intf);
+    public abstract Status handleInterfaceDelete(String tunnelType, NeutronNetwork network, Node source, Interface intf, boolean isLastInstanceOnNode);
     /*
      * Initialize the Flow rules given the OVSDB node.
      * This method provides a set of common functionalities to initialize the Flow rules of an OVSDB node