Merge "Removed the tunnelEndpoint cache Tunnel Endpoint address is now pulled directl...
[netvirt.git] / neutron / src / main / java / org / opendaylight / ovsdb / neutron / InternalNetworkManager.java
index 51404d3ed62e8d65e07d3d052b4225f2cc7d751f..a1e128b65ea291c4355e461d3b48ee03ca49b0a0 100644 (file)
@@ -1,10 +1,16 @@
+/*
+ * Copyright (C) 2013 Red Hat, Inc.
+ *
+ * This program and the accompanying materials are made available under the
+ * 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
+ */
 package org.opendaylight.ovsdb.neutron;
 
-import java.util.List;
 import java.util.Map;
 
-import org.opendaylight.controller.networkconfig.neutron.INeutronNetworkCRUD;
-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;
@@ -16,8 +22,10 @@ import org.opendaylight.ovsdb.lib.table.Bridge;
 import org.opendaylight.ovsdb.lib.table.Interface;
 import org.opendaylight.ovsdb.lib.table.Port;
 import org.opendaylight.ovsdb.lib.table.internal.Table;
+import org.opendaylight.ovsdb.neutron.provider.ProviderNetworkManager;
 import org.opendaylight.ovsdb.plugin.IConnectionServiceInternal;
 import org.opendaylight.ovsdb.plugin.OVSDBConfigService;
+import org.opendaylight.ovsdb.plugin.StatusWithUuid;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -31,6 +39,8 @@ import org.slf4j.LoggerFactory;
  */
 public class InternalNetworkManager {
     static final Logger logger = LoggerFactory.getLogger(InternalNetworkManager.class);
+    private static final int LLDP_PRIORITY = 1000;
+    private static final int NORMAL_PRIORITY = 0;
 
     private static InternalNetworkManager internalNetwork = new InternalNetworkManager();
     private InternalNetworkManager() {
@@ -40,96 +50,143 @@ public class InternalNetworkManager {
         return internalNetwork;
     }
 
-    public boolean isInternalNetworkNeutronReady(Node node) throws Exception {
-        OVSDBConfigService ovsdbTable = (OVSDBConfigService)ServiceHelper.getGlobalInstance(OVSDBConfigService.class, this);
-        Map<String, Table<?>> bridgeTable = ovsdbTable.getRows(node, Bridge.NAME.getName());
-        if (bridgeTable != null) {
-            for (Table<?> row : bridgeTable.values()) {
-                Bridge bridge = (Bridge)row;
-                if (bridge.getName().equals(AdminConfigManager.getManager().getIntegrationBridgeName())) return true;
+    public String getInternalBridgeUUID (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) return null;
+            for (String key : bridgeTable.keySet()) {
+                Bridge bridge = (Bridge)bridgeTable.get(key);
+                if (bridge.getName().equals(bridgeName)) return key;
             }
+        } catch (Exception e) {
+            logger.error("Error getting Bridge Identifier for {} / {}", node, bridgeName, e);
         }
-        return false;
+        return null;
     }
 
-    public boolean isInternalNetworkOverlayReady(Node node) throws Exception {
-        OVSDBConfigService ovsdbTable = (OVSDBConfigService)ServiceHelper.getGlobalInstance(OVSDBConfigService.class, this);
-        Map<String, Table<?>> bridgeTable = ovsdbTable.getRows(node, Bridge.NAME.getName());
-        if (bridgeTable != null) {
-            for (Table<?> row : bridgeTable.values()) {
-                Bridge bridge = (Bridge)row;
-                if (bridge.getName().equals(AdminConfigManager.getManager().getTunnelBridgeName())) return true;
-            }
+    public boolean isInternalNetworkNeutronReady(Node node) {
+        if (this.getInternalBridgeUUID(node, AdminConfigManager.getManager().getIntegrationBridgeName()) != null) {
+            return true;
+        } else {
+            return false;
         }
-        return false;
     }
 
-    public Status createInternalNetworkForOverlay(Node node) throws Exception {
-        if (!isInternalNetworkNeutronReady(node)) {
-            logger.error("Integration Bridge is not available in Node {}", node);
-            return new Status(StatusCode.NOTACCEPTABLE, "Integration Bridge is not avaialble in Node " + node);
+    public boolean isInternalNetworkOverlayReady(Node node) {
+        if (!this.isInternalNetworkNeutronReady(node)) {
+            return false;
+        }
+        if (this.getInternalBridgeUUID(node, AdminConfigManager.getManager().getTunnelBridgeName()) != null) {
+            return true;
+        } else {
+            return false;
         }
-        if (isInternalNetworkOverlayReady(node)) {
-            logger.error("Network Overlay Bridge is already present in Node {}", node);
-            return new Status(StatusCode.NOTACCEPTABLE, "Network Overlay Bridge is already present in Node " + node);
+    }
+
+    /*
+     * Lets create these if not already present :
+     *
+       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();
+        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());
         }
+    }
 
-        /*
-         * Lets create this :
-         *
-         * Bridge br-tun
-                Port patch-int
-                    Interface patch-int
-                        type: patch
-                        options: {peer=patch-tun}
-                Port br-tun
-                    Interface br-tun
-                        type: internal
-         */
+    /*
+     * Lets create these if not already present :
+     *
+       Bridge br-int
+            Port br-int
+                Interface br-int
+                    type: internal
+     */
+    public void createInternalNetworkForNeutron(Node node) throws Exception {
+        String brInt = AdminConfigManager.getManager().getIntegrationBridgeName();
+
+        Status status = this.addInternalBridge(node, brInt, null, null);
+        if (!status.isSuccess()) logger.debug("Integration Bridge Creation Status : "+status.toString());
+    }
 
+    private Status addInternalBridge (Node node, String bridgeName, String localPathName, String remotePatchName) throws Exception {
         OVSDBConfigService ovsdbTable = (OVSDBConfigService)ServiceHelper.getGlobalInstance(OVSDBConfigService.class, this);
-        Bridge brTun = new Bridge();
-        brTun.setName(AdminConfigManager.getManager().getTunnelBridgeName());
-        // Create br-tun bridge
-        Status status = ovsdbTable.insertRow(node, Bridge.NAME.getName(), null, brTun);
-        if (!status.isSuccess()) return status;
-        String bridgeUUID = status.getDescription();
-
-        Port port = new Port();
-        port.setName(brTun.getName());
-        status = ovsdbTable.insertRow(node, Port.NAME.getName(), bridgeUUID, port);
-
-        status = addPatchPort(node, bridgeUUID, "patch-int", "patch-tun");
-        if (!status.isSuccess()) return status;
-
-        // Create the corresponding patch-tun port in br-int
-        Map<String, Table<?>> bridges = ovsdbTable.getRows(node, Bridge.NAME.getName());
-        for (String brIntUUID : bridges.keySet()) {
-            Bridge brInt = (Bridge) bridges.get(brIntUUID);
-            if (brInt.getName().equalsIgnoreCase(AdminConfigManager.getManager().getIntegrationBridgeName())) {
-                return addPatchPort(node, brIntUUID, "patch-tun", "patch-int");
-            }
+
+        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);
+            ovsdbTable.insertRow(node, Port.NAME.getName(), bridgeUUID, port);
+        } else {
+            ovsdbTable.updateRow(node, Bridge.NAME.getName(), null, bridgeUUID, bridge);
         }
 
-        return status;
+        IConnectionServiceInternal connectionService = (IConnectionServiceInternal)ServiceHelper.getGlobalInstance(IConnectionServiceInternal.class, this);
+        connectionService.setOFController(node, bridgeUUID);
+
+        if (localPathName != null && remotePatchName != null && ProviderNetworkManager.getManager().hasPerTenantTunneling()) {
+            return addPatchPort(node, bridgeUUID, localPathName, remotePatchName);
+        }
+        return new Status(StatusCode.SUCCESS);
     }
 
     private Status addPatchPort (Node node, String bridgeUUID, String portName, String patchName) throws Exception {
-        Status status = null;
         OVSDBConfigService ovsdbTable = (OVSDBConfigService)ServiceHelper.getGlobalInstance(OVSDBConfigService.class, this);
 
         Port patchPort = new Port();
         patchPort.setName(portName);
-        // Create patch-int port and interface
-        status = ovsdbTable.insertRow(node, Port.NAME.getName(), bridgeUUID, patchPort);
-        if (!status.isSuccess()) return status;
+        // Create patch port and interface
+        StatusWithUuid statusWithUuid = ovsdbTable.insertRow(node, Port.NAME.getName(), bridgeUUID, patchPort);
+        if (!statusWithUuid.isSuccess()) return statusWithUuid;
 
-        String patchPortUUID = status.getDescription();
+        String patchPortUUID = statusWithUuid.getUuid().toString();
 
         String interfaceUUID = null;
         int timeout = 6;
         while ((interfaceUUID == null) && (timeout > 0)) {
-            patchPort = (Port)ovsdbTable.getRow(node, Port.NAME.getName(), status.getDescription());
+            patchPort = (Port)ovsdbTable.getRow(node, Port.NAME.getName(), patchPortUUID);
             OvsDBSet<UUID> interfaces = patchPort.getInterfaces();
             if (interfaces == null || interfaces.size() == 0) {
                 // Wait for the OVSDB update to sync up the Local cache.
@@ -149,50 +206,15 @@ public class InternalNetworkManager {
         OvsDBMap<String, String> options = new OvsDBMap<String, String>();
         options.put("peer", patchName);
         tunInterface.setOptions(options);
-        status = ovsdbTable.updateRow(node, Interface.NAME.getName(), patchPortUUID, interfaceUUID, tunInterface);
-
-        return status;
-    }
-
-    private void prepareInternalNetwork (NeutronNetwork network, Node node) {
-        // vlan, vxlan, and gre
-        if (network.getProviderNetworkType().equalsIgnoreCase("gre") ||
-                network.getProviderNetworkType().equalsIgnoreCase("vxlan") ||
-                network.getProviderNetworkType().equalsIgnoreCase("vlan")) {
-
-            try {
-                if (!this.isInternalNetworkOverlayReady(node)) {
-                    this.createInternalNetworkForOverlay(node);
-                }
-            } catch (Exception e) {
-                e.printStackTrace();
-            }
-        } else {
-            try {
-                if (!this.isInternalNetworkNeutronReady(node)) {
-                    // TODO : FILL IN
-                    // this.createInternalNetworkForNeutron(node);
-                }
-            } catch (Exception e) {
-                e.printStackTrace();
-            }
-        }
-    }
-
-    public void prepareInternalNetwork(NeutronNetwork network) {
-        IConnectionServiceInternal connectionService = (IConnectionServiceInternal)ServiceHelper.getGlobalInstance(IConnectionServiceInternal.class, this);
-        List<Node> nodes = connectionService.getNodes();
-        for (Node node : nodes) {
-            prepareInternalNetwork(network, node);
-        }
+        return ovsdbTable.updateRow(node, Interface.NAME.getName(), patchPortUUID, interfaceUUID, tunInterface);
     }
 
     public void prepareInternalNetwork(Node node) {
-        INeutronNetworkCRUD neutronNetworkService = (INeutronNetworkCRUD)ServiceHelper.getGlobalInstance(INeutronNetworkCRUD.class, this);
-        List <NeutronNetwork> networks = neutronNetworkService.getAllNetworks();
-        for (NeutronNetwork network : networks) {
-            prepareInternalNetwork(network, node);
+        try {
+            this.createInternalNetworkForOverlay(node);
+        } catch (Exception e) {
+            logger.error("Error creating internal network "+node.toString(), e);
         }
+        ProviderNetworkManager.getManager().initializeFlowRules(node);
     }
-
 }