2 * Copyright (C) 2013 Red Hat, Inc. and others...
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 * Authors : Madhu Venugopal, Brent Salisbury, Dave Tucker
10 package org.opendaylight.ovsdb.openstack.netvirt.impl;
12 import org.opendaylight.neutron.spi.INeutronNetworkCRUD;
13 import org.opendaylight.neutron.spi.INeutronPortCRUD;
14 import org.opendaylight.neutron.spi.NeutronNetwork;
15 import org.opendaylight.neutron.spi.NeutronPort;
16 import org.opendaylight.ovsdb.lib.notation.OvsdbSet;
17 import org.opendaylight.ovsdb.lib.notation.Row;
18 import org.opendaylight.ovsdb.openstack.netvirt.api.Constants;
19 import org.opendaylight.ovsdb.openstack.netvirt.api.NetworkingProviderManager;
20 import org.opendaylight.ovsdb.openstack.netvirt.api.TenantNetworkManager;
21 import org.opendaylight.ovsdb.openstack.netvirt.api.VlanConfigurationCache;
22 import org.opendaylight.ovsdb.plugin.api.OvsdbConfigurationService;
23 import org.opendaylight.ovsdb.plugin.api.OvsdbConnectionService;
24 import org.opendaylight.ovsdb.schema.openvswitch.Interface;
25 import org.opendaylight.ovsdb.schema.openvswitch.Port;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
28 import com.google.common.base.Preconditions;
29 import org.slf4j.Logger;
30 import org.slf4j.LoggerFactory;
32 import java.util.List;
35 public class TenantNetworkManagerImpl implements TenantNetworkManager {
36 static final Logger logger = LoggerFactory.getLogger(TenantNetworkManagerImpl.class);
38 // The implementation for each of these services is resolved by the OSGi Service Manager
39 private volatile NetworkingProviderManager networkingProviderManager;
40 private volatile OvsdbConfigurationService ovsdbConfigurationService;
41 private volatile OvsdbConnectionService connectionService;
42 private volatile INeutronNetworkCRUD neutronNetworkCache;
43 private volatile INeutronPortCRUD neutronPortCache;
44 private volatile VlanConfigurationCache vlanConfigurationCache;
46 public TenantNetworkManagerImpl() {
50 public int getInternalVlan(Node node, String networkId) {
51 Integer vlan = vlanConfigurationCache.getInternalVlan(node, networkId);
52 if (vlan == null) return 0;
57 public void reclaimInternalVlan(Node node, String portUUID, NeutronNetwork network) {
58 int vlan = vlanConfigurationCache.reclaimInternalVlan(node, network.getID());
60 logger.debug("Unable to get an internalVlan for Network {}", network);
63 logger.debug("Removed Vlan {} on {}", vlan, portUUID);
67 public void programInternalVlan(Node node, String portUUID, NeutronNetwork network) {
68 Preconditions.checkNotNull(ovsdbConfigurationService);
70 int vlan = vlanConfigurationCache.getInternalVlan(node, network.getID());
71 logger.debug("Programming Vlan {} on {}", vlan, portUUID);
73 logger.debug("Unable to get an internalVlan for Network {}", network);
77 Port port = ovsdbConfigurationService.createTypedRow(node, Port.class);
79 ovsdbConfigurationService.updateRow(node, port.getSchema().getName(), null, portUUID, port.getRow());
83 public boolean isTenantNetworkPresentInNode(Node node, String segmentationId) {
84 Preconditions.checkNotNull(ovsdbConfigurationService);
86 String networkId = this.getNetworkId(segmentationId);
87 if (networkId == null) {
88 logger.debug("Tenant Network not found with Segmenation-id {}",segmentationId);
91 if (networkingProviderManager.getProvider(node).hasPerTenantTunneling()) {
92 int internalVlan = vlanConfigurationCache.getInternalVlan(node, networkId);
93 if (internalVlan == 0) {
94 logger.debug("No InternalVlan provisioned for Tenant Network {}",networkId);
101 // Vlan Tag based identification
102 Map<String, Row> portTable = ovsdbConfigService.getRows(node, Port.NAME.getName());
103 if (portTable == null) {
104 logger.debug("Port table is null for Node {} ", node);
108 for (Row row : portTable.values()) {
109 Port port = (Port)row;
110 Set<BigInteger> tags = port.getTag();
111 if (tags.contains(internalVlan)) {
112 logger.debug("Tenant Network {} with Segmenation-id {} is present in Node {} / Port {}",
113 networkId, segmentationId, node, port);
118 // External-id based more accurate VM Location identification
119 Map<String, Row> ifTable = ovsdbConfigurationService.getRows(node, ovsdbConfigurationService.getTableName(node, Interface.class));
120 if (ifTable == null) {
121 logger.debug("Interface table is null for Node {} ", node);
125 for (Row row : ifTable.values()) {
126 Interface intf = ovsdbConfigurationService.getTypedRow(node, Interface.class, row);
127 Map<String, String> externalIds = intf.getExternalIdsColumn().getData();
128 if (externalIds != null && externalIds.get(Constants.EXTERNAL_ID_INTERFACE_ID) != null) {
129 if (this.isInterfacePresentInTenantNetwork(externalIds.get(Constants.EXTERNAL_ID_INTERFACE_ID), networkId)) {
130 logger.debug("Tenant Network {} with Segmentation-id {} is present in Node {} / Interface {}",
131 networkId, segmentationId, node, intf);
137 } catch (Exception e) {
138 logger.error("Error while trying to determine if network is present on node", e);
142 logger.debug("Tenant Network {} with Segmenation-id {} is NOT present in Node {}",
143 networkId, segmentationId, node);
149 public String getNetworkId(String segmentationId) {
150 List <NeutronNetwork> networks = neutronNetworkCache.getAllNetworks();
151 for (NeutronNetwork network : networks) {
152 if (network.getProviderSegmentationID().equalsIgnoreCase(segmentationId)) return network.getNetworkUUID();
158 public NeutronNetwork getTenantNetwork(Interface intf) {
159 logger.trace("getTenantNetwork for {}", intf);
160 if (intf == null) return null;
161 Map<String, String> externalIds = intf.getExternalIdsColumn().getData();
162 logger.trace("externalIds {}", externalIds);
163 if (externalIds == null) return null;
164 String neutronPortId = externalIds.get(Constants.EXTERNAL_ID_INTERFACE_ID);
165 if (neutronPortId == null) return null;
166 NeutronPort neutronPort = neutronPortCache.getPort(neutronPortId);
167 logger.trace("neutronPort {}", neutronPort);
168 if (neutronPort == null) return null;
169 NeutronNetwork neutronNetwork = neutronNetworkCache.getNetwork(neutronPort.getNetworkUUID());
170 logger.debug("{} mapped to {}", intf, neutronNetwork);
171 return neutronNetwork;
175 public void networkCreated (String networkId) {
176 List<Node> nodes = connectionService.getNodes();
178 for (Node node : nodes) {
179 this.networkCreated(node, networkId);
185 public int networkCreated (Node node, String networkId) {
186 return vlanConfigurationCache.assignInternalVlan(node, networkId);
190 public void networkDeleted(String id) {
191 //ToDo: Delete? This method does nothing how we dropped container support...
194 private boolean isInterfacePresentInTenantNetwork (String portId, String networkId) {
195 NeutronPort neutronPort = neutronPortCache.getPort(portId);
196 return neutronPort != null && neutronPort.getNetworkUUID().equalsIgnoreCase(networkId);