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.controller.networkconfig.neutron.INeutronNetworkCRUD;
13 import org.opendaylight.controller.networkconfig.neutron.INeutronPortCRUD;
14 import org.opendaylight.controller.networkconfig.neutron.NeutronNetwork;
15 import org.opendaylight.controller.networkconfig.neutron.NeutronPort;
16 import org.opendaylight.controller.sal.core.Node;
17 import org.opendaylight.ovsdb.lib.notation.OvsdbSet;
18 import org.opendaylight.ovsdb.lib.notation.Row;
19 import org.opendaylight.ovsdb.openstack.netvirt.api.Constants;
20 import org.opendaylight.ovsdb.openstack.netvirt.api.NetworkingProviderManager;
21 import org.opendaylight.ovsdb.openstack.netvirt.api.TenantNetworkManager;
22 import org.opendaylight.ovsdb.openstack.netvirt.api.VlanConfigurationCache;
23 import org.opendaylight.ovsdb.plugin.api.OvsdbConfigurationService;
24 import org.opendaylight.ovsdb.plugin.api.OvsdbConnectionService;
25 import org.opendaylight.ovsdb.schema.openvswitch.Interface;
26 import org.opendaylight.ovsdb.schema.openvswitch.Port;
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);
78 OvsdbSet<Long> tags = new OvsdbSet<>();
79 tags.add((long) vlan);
81 ovsdbConfigurationService.updateRow(node, port.getSchema().getName(), null, portUUID, port.getRow());
85 public boolean isTenantNetworkPresentInNode(Node node, String segmentationId) {
86 Preconditions.checkNotNull(ovsdbConfigurationService);
88 String networkId = this.getNetworkId(segmentationId);
89 if (networkId == null) {
90 logger.debug("Tenant Network not found with Segmenation-id {}",segmentationId);
93 if (networkingProviderManager.getProvider(node).hasPerTenantTunneling()) {
94 int internalVlan = vlanConfigurationCache.getInternalVlan(node, networkId);
95 if (internalVlan == 0) {
96 logger.debug("No InternalVlan provisioned for Tenant Network {}",networkId);
103 // Vlan Tag based identification
104 Map<String, Row> portTable = ovsdbConfigService.getRows(node, Port.NAME.getName());
105 if (portTable == null) {
106 logger.debug("Port table is null for Node {} ", node);
110 for (Row row : portTable.values()) {
111 Port port = (Port)row;
112 Set<BigInteger> tags = port.getTag();
113 if (tags.contains(internalVlan)) {
114 logger.debug("Tenant Network {} with Segmenation-id {} is present in Node {} / Port {}",
115 networkId, segmentationId, node, port);
120 // External-id based more accurate VM Location identification
121 Map<String, Row> ifTable = ovsdbConfigurationService.getRows(node, ovsdbConfigurationService.getTableName(node, Interface.class));
122 if (ifTable == null) {
123 logger.debug("Interface table is null for Node {} ", node);
127 for (Row row : ifTable.values()) {
128 Interface intf = ovsdbConfigurationService.getTypedRow(node, Interface.class, row);
129 Map<String, String> externalIds = intf.getExternalIdsColumn().getData();
130 if (externalIds != null && externalIds.get(Constants.EXTERNAL_ID_INTERFACE_ID) != null) {
131 if (this.isInterfacePresentInTenantNetwork(externalIds.get(Constants.EXTERNAL_ID_INTERFACE_ID), networkId)) {
132 logger.debug("Tenant Network {} with Segmentation-id {} is present in Node {} / Interface {}",
133 networkId, segmentationId, node, intf);
139 } catch (Exception e) {
140 logger.error("Error while trying to determine if network is present on node", e);
144 logger.debug("Tenant Network {} with Segmenation-id {} is NOT present in Node {}",
145 networkId, segmentationId, node);
151 public String getNetworkId(String segmentationId) {
152 List <NeutronNetwork> networks = neutronNetworkCache.getAllNetworks();
153 for (NeutronNetwork network : networks) {
154 if (network.getProviderSegmentationID().equalsIgnoreCase(segmentationId)) return network.getNetworkUUID();
160 public NeutronNetwork getTenantNetwork(Interface intf) {
161 logger.trace("getTenantNetwork for {}", intf);
162 if (intf == null) return null;
163 Map<String, String> externalIds = intf.getExternalIdsColumn().getData();
164 logger.trace("externalIds {}", externalIds);
165 if (externalIds == null) return null;
166 String neutronPortId = externalIds.get(Constants.EXTERNAL_ID_INTERFACE_ID);
167 if (neutronPortId == null) return null;
168 NeutronPort neutronPort = neutronPortCache.getPort(neutronPortId);
169 logger.trace("neutronPort {}", neutronPort);
170 if (neutronPort == null) return null;
171 NeutronNetwork neutronNetwork = neutronNetworkCache.getNetwork(neutronPort.getNetworkUUID());
172 logger.debug("{} mapped to {}", intf, neutronNetwork);
173 return neutronNetwork;
177 public void networkCreated (String networkId) {
178 List<Node> nodes = connectionService.getNodes();
180 for (Node node : nodes) {
181 this.networkCreated(node, networkId);
187 public int networkCreated (Node node, String networkId) {
188 return vlanConfigurationCache.assignInternalVlan(node, networkId);
192 public void networkDeleted(String id) {
193 //ToDo: Delete? This method does nothing how we dropped container support...
196 private boolean isInterfacePresentInTenantNetwork (String portId, String networkId) {
197 NeutronPort neutronPort = neutronPortCache.getPort(portId);
198 return neutronPort != null && neutronPort.getNetworkUUID().equalsIgnoreCase(networkId);