Internal Vlan deletion and Tunnel Deletion cleanup 33/4833/1
authorMadhu Venugopal <mavenugo@gmail.com>
Sun, 26 Jan 2014 23:02:17 +0000 (15:02 -0800)
committerMadhu Venugopal <mavenugo@gmail.com>
Sun, 26 Jan 2014 23:02:17 +0000 (15:02 -0800)
Change-Id: Ib5ba447ac95ca5f733095ea774a318490b3aa4f5
Signed-off-by: Madhu Venugopal <mavenugo@gmail.com>
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/TenantNetworkManager.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 e0d76771ec149381194eed5f0a56eab667f662e7..868189706587bad9c8a27d4dce7c669f499da237 100644 (file)
 
 package org.opendaylight.ovsdb.neutron;
 
+import java.math.BigInteger;
+import java.util.LinkedList;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
 import org.opendaylight.controller.sal.core.Node;
 import org.opendaylight.controller.sal.utils.ServiceHelper;
 import org.opendaylight.ovsdb.lib.notation.UUID;
@@ -21,12 +27,6 @@ import org.opendaylight.ovsdb.plugin.OVSDBConfigService;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import java.math.BigInteger;
-import java.util.LinkedList;
-import java.util.Map;
-import java.util.concurrent.ConcurrentMap;
-import java.util.concurrent.ConcurrentHashMap;
-
 public class NodeConfiguration {
     static final Logger logger = LoggerFactory.getLogger(NodeConfiguration.class);
     private static final int MAX_VLAN = 4096;
@@ -104,6 +104,16 @@ public class NodeConfiguration {
         return mappedVlan;
     }
 
+    public int reclaimInternalVlan (String networkId) {
+        Integer mappedVlan = tenantVlanMap.get(networkId);
+        if (mappedVlan != null) {
+            tenantVlanMap.remove(mappedVlan);
+            internalVlans.add(mappedVlan);
+            return mappedVlan;
+        }
+        return 0;
+    }
+
     public void internalVlanInUse (int vlan) {
         internalVlans.remove(vlan);
     }
index d0cd642efb344b4cae773bf64e791cd768bd78f6..dc8267bcc02832efbd8c0e6adb685e614a6db3c7 100644 (file)
@@ -13,13 +13,12 @@ import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
-import java.util.concurrent.ExecutorService;
 import java.util.concurrent.BlockingQueue;
 import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 import java.util.concurrent.LinkedBlockingQueue;
 
-import org.opendaylight.controller.networkconfig.neutron.NeutronPort;
 import org.opendaylight.controller.networkconfig.neutron.NeutronNetwork;
 import org.opendaylight.controller.sal.core.Node;
 import org.opendaylight.controller.sal.core.NodeConnector;
@@ -164,23 +163,23 @@ public class SouthboundHandler extends BaseHandler implements OVSDBInventoryList
                                   SouthboundEvent.Action action) {
         if (action == SouthboundEvent.Action.DELETE) {
             if (Interface.NAME.getName().equalsIgnoreCase(tableName)) {
-                Interface intf = (Interface)row;
-                NeutronNetwork network = TenantNetworkManager.getManager().getTenantNetworkForInterface(intf);
+                Interface deletedIntf = (Interface)row;
+                NeutronNetwork network = TenantNetworkManager.getManager().getTenantNetworkForInterface(deletedIntf);
                 if (network != null && !network.getRouterExternal()) {
-                    List<NeutronPort> ports = network.getPortsOnNetwork();
-                    if (ports != null) {
-                        int novaCounter = 0;
-                        for (NeutronPort port : ports) {
-                            String portOwner = port.getDeviceOwner();
-                            if (portOwner.equalsIgnoreCase("compute:nova")) novaCounter++;
-                        }
-                        /*
-                         * Make sure we don't delete the tunnel unless there are no more
-                         * compute nodes using it
-                         */
-                        if (novaCounter<=1) {
-                            this.deleteTunnels(node, uuid, intf);
+                    try {
+                        ConcurrentMap<String, Table<?>> interfaces = this.ovsdbConfigService.getRows(node, Interface.NAME.getName());
+                        if (interfaces != null) {
+                            boolean isLastInstanceOnNode = true;
+                            for (String intfUUID : interfaces.keySet()) {
+                                if (intfUUID.equals(uuid)) continue;
+                                Interface intf = (Interface) interfaces.get(intfUUID);
+                                NeutronNetwork neutronNetwork = TenantNetworkManager.getManager().getTenantNetworkForInterface(intf);
+                                if (neutronNetwork != null && neutronNetwork.equals(network)) isLastInstanceOnNode = false;
+                            }
+                            this.handleInterfaceDelete(node, uuid, deletedIntf, isLastInstanceOnNode);
                         }
+                    } catch (Exception e) {
+                        logger.error("Error fetching Interface Rows for node " + node, e);
                     }
                 }
             }
@@ -244,15 +243,18 @@ public class SouthboundHandler extends BaseHandler implements OVSDBInventoryList
                     network.getProviderSegmentationID(), node, intf);
         }
     }
-    private void deleteTunnels (Node node, String uuid, Interface intf) {
+    private void handleInterfaceDelete (Node node, String uuid, Interface intf, boolean isLastInstanceOnNode) {
         if (AdminConfigManager.getManager().getTunnelEndPoint(node) == null) {
             logger.error("Tunnel end-point configuration missing. Please configure it in Open_vSwitch Table");
             return;
         }
         NeutronNetwork network = TenantNetworkManager.getManager().getTenantNetworkForInterface(intf);
         if (network != null) {
-            ProviderNetworkManager.getManager().deleteTunnels(network.getProviderNetworkType(),
-                    network.getProviderSegmentationID(), node, intf);
+            if (isLastInstanceOnNode) {
+                TenantNetworkManager.getManager().reclaimTennantNetworkInternalVlan(node, uuid, network);
+            }
+            ProviderNetworkManager.getManager().handleInterfaceDelete(network.getProviderNetworkType(),
+                    network.getProviderSegmentationID(), node, intf, isLastInstanceOnNode);
         }
     }
 
index 5a23385f2df23c1e4649828fb96ffea938a1fa29..0ce6a400f238173713e26450f4d5ebbbbafa1af9 100644 (file)
@@ -37,6 +37,7 @@ import org.opendaylight.ovsdb.lib.table.Open_vSwitch;
 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.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -90,6 +91,40 @@ public class TenantNetworkManager {
         return nodeConfigurationCache.get(nodeUuid);
     }
 
+    public void reclaimTennantNetworkInternalVlan(Node node, String portUUID, NeutronNetwork network) {
+        String nodeUuid = getNodeUUID(node);
+        if (nodeUuid == null) {
+            logger.error("Unable to get UUID for Node {}", node);
+            return;
+        }
+
+        NodeConfiguration nodeConfiguration = nodeConfigurationCache.get(nodeUuid);
+
+        // Cache miss
+        if (nodeConfiguration == null)
+        {
+            logger.error("Configuration data unavailable for Node {} ", node);
+            return;
+        }
+
+        int vlan = nodeConfiguration.reclaimInternalVlan(network.getID());
+        if (vlan <= 0) {
+            logger.error("Unable to get an internalVlan for Network {}", network);
+            return;
+        }
+        logger.debug("Removed Vlan {} on {}", vlan, portUUID);
+    }
+
+    public void networkCreated (String networkId) {
+        IConnectionServiceInternal connectionService = (IConnectionServiceInternal)ServiceHelper.getGlobalInstance(IConnectionServiceInternal.class, this);
+        List<Node> nodes = connectionService.getNodes();
+
+        for (Node node : nodes) {
+            this.networkCreated(node, networkId);
+        }
+
+    }
+
     private String getNodeUUID(Node node) {
         String nodeUuid = new String();
         OVSDBConfigService ovsdbConfigService = (OVSDBConfigService)ServiceHelper.getGlobalInstance(OVSDBConfigService.class, this);
index fd9b5a3fe310eeac25a98ce47fde0bc351717eab..cf3743e4ad00a1c70868efd97a63db90bb14c42e 100644 (file)
@@ -467,22 +467,25 @@ class OF10ProviderManager extends ProviderNetworkManager {
     }
 
     @Override
-    public Status deleteTunnels(String tunnelType, String tunnelKey, Node srcNode, Interface intf) {
+    public Status handleInterfaceDelete(String tunnelType, String tunnelKey, Node srcNode, Interface intf, boolean isLastInstanceOnNode) {
+        Status status = new Status(StatusCode.SUCCESS);
+
         IConnectionServiceInternal connectionService = (IConnectionServiceInternal)ServiceHelper.getGlobalInstance(IConnectionServiceInternal.class, this);
         List<Node> nodes = connectionService.getNodes();
         nodes.remove(srcNode);
         for (Node dstNode : nodes) {
-            Status status;
             InetAddress src = AdminConfigManager.getManager().getTunnelEndPoint(srcNode);
             InetAddress dst = AdminConfigManager.getManager().getTunnelEndPoint(dstNode);
             this.removeTunnelRules(tunnelType, tunnelKey, dst, srcNode, intf, true);
-            status = deleteTunnelPort(srcNode, tunnelType, src, dst, tunnelKey);
+            if (isLastInstanceOnNode) {
+                status = deleteTunnelPort(srcNode, tunnelType, src, dst, tunnelKey);
+            }
             this.removeTunnelRules(tunnelType, tunnelKey, src, dstNode, intf, false);
-            if (status.isSuccess()) {
+            if (status.isSuccess() && isLastInstanceOnNode) {
                 deleteTunnelPort(dstNode, tunnelType, dst, src, tunnelKey);
             }
         }
-        return new Status(StatusCode.SUCCESS);
+        return status;
     }
 
     private String getTunnelName(String tunnelType, String key, InetAddress dst) {
@@ -629,7 +632,7 @@ class OF10ProviderManager extends ProviderNetworkManager {
             String tunnelPortUUID = this.getTunnelPortUuid(node, portName, bridgeUUID);
             Status status = ovsdbTable.deleteRow(node, Port.NAME.getName(), tunnelPortUUID);
             if (!status.isSuccess()) {
-                logger.error("Failed to delete Tunnel port {} in {}", portName, bridgeUUID);
+                logger.error("Failed to delete Tunnel port {} in {} status : {}", portName, bridgeUUID, status);
                 return status;
             }
 
index 34876e8a8ac3bcb24a8099c2378ba88360c32956..3581e89f5b1b6d7b34b91cc2fe779b9635766d64 100644 (file)
@@ -533,7 +533,8 @@ class OF13ProviderManager extends ProviderNetworkManager {
     }
 
     @Override
-    public Status deleteTunnels(String tunnelType, String tunnelKey, Node source, Interface intf) {
+    public Status handleInterfaceDelete(String tunnelType, String tunnelKey, Node source, Interface intf,
+            boolean isLastInstanceOnNode) {
         // TODO Auto-generated method stub
         return null;
     }
index 641f77092cc18e2f226ea5795ac9e86792e1059c..0a8ccd1cedaeaab281f86c3b60748a23dd645591 100644 (file)
@@ -56,7 +56,7 @@ 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 deleteTunnels(String tunnelType, String tunnelKey, Node source, Interface intf);
+    public abstract Status handleInterfaceDelete(String tunnelType, String tunnelKey, 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