--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2013 Hewlett-Packard Development Company, L.P.
+ * All rights reserved. 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
+ *
+ * Contributors:
+ * Dave Tucker (HP) - Replace tenantVlanMap with a per Node cache
+ *******************************************************************************/
+
+package org.opendaylight.ovsdb.neutron;
+
+import org.opendaylight.controller.sal.core.Node;
+import org.opendaylight.controller.sal.utils.ServiceHelper;
+import org.opendaylight.ovsdb.lib.notation.UUID;
+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.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;
+ private java.util.Queue<Integer> internalVlans = new LinkedList<>();
+ private ConcurrentMap<String, Integer> tenantVlanMap = new ConcurrentHashMap<>();
+
+ public NodeConfiguration(Node node) {
+ for (int i = 1; i < MAX_VLAN ; i++) {
+ internalVlans.add(i);
+ }
+
+ initializeNodeConfiguration(node);
+ }
+
+
+ private void initializeNodeConfiguration(Node node) {
+
+ int vlan = 0;
+ String networkId = new String();
+ OVSDBConfigService ovsdbTable = (OVSDBConfigService) ServiceHelper.getGlobalInstance(OVSDBConfigService.class, this);
+
+ try {
+ Map<String, Table<?>> portRows = ovsdbTable.getRows(node, Port.NAME.getName());
+
+ if (portRows == null){
+ logger.info("Interface table is null for Node {}", node);
+ return;
+ }
+
+ for (Table<?> row : portRows.values()) {
+ Port port = (Port)row;
+
+ BigInteger[] tags = port.getTag().toArray(new BigInteger[0]);
+ if (tags.length == 1)
+ {
+ //There is only one tag here
+ vlan = tags[0].intValue();
+ }
+ else {
+ logger.debug("This port has more {} interfaces", tags.length);
+ continue;
+ }
+
+ for (UUID ifaceId : port.getInterfaces()) {
+ Interface iface = (Interface)ovsdbTable.getRow(node, Interface.NAME.getName(), ifaceId.toString());
+
+ if (iface == null) {
+ logger.error("Interface table is null for Po");
+ continue;
+ }
+
+ networkId = TenantNetworkManager.getManager().getTenantNetworkForInterface(iface).getNetworkUUID();
+
+ if (networkId != null) break;
+ }
+
+ if (vlan != 0 && networkId != null) {
+
+ this.internalVlanInUse(vlan);
+ this.tenantVlanMap.put(networkId, vlan);
+
+ }
+ }
+ }
+ catch (Exception e) {
+ logger.error("Error getting Port table for Node {}: {}", node, e);
+ }
+ }
+
+ public int assignInternalVlan (String networkId) {
+ Integer mappedVlan = tenantVlanMap.get(networkId);
+ if (mappedVlan != null) return mappedVlan;
+ mappedVlan = internalVlans.poll();
+ if (mappedVlan != null) tenantVlanMap.put(networkId, mappedVlan);
+ return mappedVlan;
+ }
+
+ public void internalVlanInUse (int vlan) {
+ internalVlans.remove(vlan);
+ }
+
+ public int getInternalVlan (String networkId) {
+ Integer vlan = tenantVlanMap.get(networkId);
+ if (vlan == null) return 0;
+ return vlan.intValue();
+ }
+
+}
/*
- * Copyright (C) 2013 Red Hat, Inc.
+ * Copyright (C) 2013 Red Hat, Inc. and others...
*
* 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
+ * Authors : Madhu Venugopal, Brent Salisbury, Dave Tucker
*/
package org.opendaylight.ovsdb.neutron;
import java.math.BigInteger;
import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.LinkedList;
import java.util.List;
import java.util.Map;
-import java.util.Queue;
import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
import org.opendaylight.controller.containermanager.ContainerConfig;
import org.opendaylight.controller.containermanager.ContainerFlowConfig;
import org.opendaylight.ovsdb.lib.notation.UUID;
import org.opendaylight.ovsdb.lib.table.Bridge;
import org.opendaylight.ovsdb.lib.table.Interface;
+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;
public class TenantNetworkManager {
static final Logger logger = LoggerFactory.getLogger(TenantNetworkManager.class);
- private static final int MAX_VLAN = 4096;
public static final String EXTERNAL_ID_VM_ID = "vm-id";
public static final String EXTERNAL_ID_INTERFACE_ID = "iface-id";
public static final String EXTERNAL_ID_VM_MAC = "attached-mac";
private static TenantNetworkManager tenantHelper = new TenantNetworkManager();
- private Queue<Integer> internalVlans = new LinkedList<Integer>();
- private Map<String, Integer> tenantVlanMap = new HashMap<String, Integer>();
+ private ConcurrentMap<String, NodeConfiguration> nodeConfigurationCache = new ConcurrentHashMap<>();
+
private boolean enableContainer = false;
private TenantNetworkManager() {
- for (int i = 1; i < MAX_VLAN ; i++) {
- internalVlans.add(i);
- }
String isTenantContainer = System.getProperty("TenantIsContainer");
if (isTenantContainer != null && isTenantContainer.equalsIgnoreCase("true")) {
enableContainer = true;
return tenantHelper;
}
- private int assignInternalVlan (String networkId) {
- Integer mappedVlan = tenantVlanMap.get(networkId);
- if (mappedVlan != null) return mappedVlan;
- mappedVlan = internalVlans.poll();
- if (mappedVlan != null) tenantVlanMap.put(networkId, mappedVlan);
- return mappedVlan;
- }
+ public int getInternalVlan(Node node, String networkId) {
+ String nodeUuid = getNodeUUID(node);
+ if (nodeUuid == null) {
+ logger.error("Unable to get UUID for Node {}", node);
+ return 0;
+ }
- public void internalVlanInUse (int vlan) {
- internalVlans.remove(vlan);
- }
+ NodeConfiguration nodeConfiguration = nodeConfigurationCache.get(nodeUuid);
- public int getInternalVlan (String networkId) {
- Integer vlan = tenantVlanMap.get(networkId);
+ if (nodeConfiguration == null) {
+ nodeConfiguration = addNodeConfigurationToCache(node);
+ }
+ Integer vlan = nodeConfiguration.getInternalVlan(networkId);
if (vlan == null) return 0;
return vlan.intValue();
}
- public int networkCreated (String networkId) {
- int internalVlan = this.assignInternalVlan(networkId);
+ private NodeConfiguration addNodeConfigurationToCache(Node node) {
+ NodeConfiguration nodeConfiguration = new NodeConfiguration(node);
+ String nodeUuid = getNodeUUID(node);
+ if (nodeUuid == null) {
+ logger.error("Cannot get Node UUID for Node {}", node);
+ return null;
+ }
+ this.nodeConfigurationCache.put(nodeUuid, nodeConfiguration);
+ return nodeConfigurationCache.get(nodeUuid);
+ }
+
+ 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);
+ try {
+ Map<String, Table<?>> ovsTable = ovsdbConfigService.getRows(node, Open_vSwitch.NAME.getName());
+ nodeUuid = (String)ovsTable.keySet().toArray()[0];
+ }
+ catch (Exception e) {
+ logger.error("Unable to get the Open_vSwitch table for Node {}: {}", node, e);
+ }
+
+ return nodeUuid;
+ }
+
+ public int networkCreated (Node node, String networkId) {
+ String nodeUuid = getNodeUUID(node);
+ if (nodeUuid == null) {
+ logger.error("Unable to get UUID for Node {}", node);
+ return 0;
+ }
+
+ NodeConfiguration nodeConfiguration = nodeConfigurationCache.get(nodeUuid);
+
+ // Cache miss
+ if (nodeConfiguration == null)
+ {
+ nodeConfiguration = addNodeConfigurationToCache(node);
+ }
+
+ int internalVlan = nodeConfiguration.assignInternalVlan(networkId);
if (enableContainer && internalVlan != 0) {
IContainerManager containerManager = (IContainerManager)ServiceHelper.getGlobalInstance(IContainerManager.class, this);
if (containerManager == null) {
return false;
}
if (ProviderNetworkManager.getManager().hasPerTenantTunneling()) {
- int internalVlan = this.getInternalVlan(networkId);
+ String nodeUuid = getNodeUUID(node);
+ if (nodeUuid == null) {
+ logger.debug("Unable to get UUID for Node {}", node);
+ return false;
+ }
+
+ NodeConfiguration nodeConfiguration = nodeConfigurationCache.get(nodeUuid);
+
+ // Cache miss
+ if (nodeConfiguration == null)
+ {
+ logger.error("Configuration data unavailable for Node {} ", node);
+ return false;
+ }
+
+ int internalVlan = nodeConfiguration.getInternalVlan(networkId);
if (internalVlan == 0) {
logger.debug("No InternalVlan provisioned for Tenant Network {}",networkId);
return false;
Map<String, String> externalIds = intf.getExternal_ids();
if (externalIds != null && externalIds.get(EXTERNAL_ID_INTERFACE_ID) != null) {
if (this.isInterfacePresentInTenantNetwork(externalIds.get(EXTERNAL_ID_INTERFACE_ID), networkId)) {
- logger.debug("Tenant Network {} with Segmenation-id {} is present in Node {} / Interface {}",
+ logger.debug("Tenant Network {} with Segmentation-id {} is present in Node {} / Interface {}",
networkId, segmentationId, node, intf);
return true;
}
}
public void programTenantNetworkInternalVlan(Node node, String portUUID, NeutronNetwork network) {
- int vlan = this.getInternalVlan(network.getID());
+
+ 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.getInternalVlan(network.getID());
logger.debug("Programming Vlan {} on {}", vlan, portUUID);
if (vlan <= 0) {
logger.error("Unable to get an internalVlan for Network {}", network);