Added trunks code to go with the model.
[netvirt.git] / openstack / net-virt / src / main / java / org / opendaylight / ovsdb / openstack / netvirt / impl / TenantNetworkManagerImpl.java
1 /*
2  * Copyright (C) 2013 Red Hat, Inc. and others...
3  *
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
7  *
8  * Authors : Madhu Venugopal, Brent Salisbury, Dave Tucker
9  */
10 package org.opendaylight.ovsdb.openstack.netvirt.impl;
11
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;
27
28 import com.google.common.base.Preconditions;
29 import org.slf4j.Logger;
30 import org.slf4j.LoggerFactory;
31
32 import java.util.List;
33 import java.util.Map;
34
35 public class TenantNetworkManagerImpl implements TenantNetworkManager {
36     static final Logger logger = LoggerFactory.getLogger(TenantNetworkManagerImpl.class);
37
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;
45
46     public TenantNetworkManagerImpl() {
47     }
48
49     @Override
50     public int getInternalVlan(Node node, String networkId) {
51         Integer vlan = vlanConfigurationCache.getInternalVlan(node, networkId);
52         if (vlan == null) return 0;
53         return vlan;
54     }
55
56     @Override
57     public void reclaimInternalVlan(Node node, String portUUID, NeutronNetwork network) {
58         int vlan = vlanConfigurationCache.reclaimInternalVlan(node, network.getID());
59         if (vlan <= 0) {
60             logger.debug("Unable to get an internalVlan for Network {}", network);
61             return;
62         }
63         logger.debug("Removed Vlan {} on {}", vlan, portUUID);
64     }
65
66     @Override
67     public void programInternalVlan(Node node, String portUUID, NeutronNetwork network) {
68         Preconditions.checkNotNull(ovsdbConfigurationService);
69
70         int vlan = vlanConfigurationCache.getInternalVlan(node, network.getID());
71         logger.debug("Programming Vlan {} on {}", vlan, portUUID);
72         if (vlan <= 0) {
73             logger.debug("Unable to get an internalVlan for Network {}", network);
74             return;
75         }
76
77         Port port = ovsdbConfigurationService.createTypedRow(node, Port.class);
78         port.setTag(vlan);
79         ovsdbConfigurationService.updateRow(node, port.getSchema().getName(), null, portUUID, port.getRow());
80     }
81
82     @Override
83     public boolean isTenantNetworkPresentInNode(Node node, String segmentationId) {
84         Preconditions.checkNotNull(ovsdbConfigurationService);
85
86         String networkId = this.getNetworkId(segmentationId);
87         if (networkId == null) {
88             logger.debug("Tenant Network not found with Segmenation-id {}",segmentationId);
89             return false;
90         }
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);
95                 return false;
96             }
97         }
98
99         try {
100             /*
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);
105                 return false;
106             }
107
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);
114                     return true;
115                 }
116             }
117              */
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);
122                 return false;
123             }
124
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);
132                         return true;
133                     }
134                 }
135             }
136
137         } catch (Exception e) {
138             logger.error("Error while trying to determine if network is present on node", e);
139             return false;
140         }
141
142         logger.debug("Tenant Network {} with Segmenation-id {} is NOT present in Node {}",
143                 networkId, segmentationId, node);
144
145         return false;
146     }
147
148     @Override
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();
153         }
154         return null;
155     }
156
157     @Override
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;
172     }
173
174     @Override
175     public void networkCreated (String networkId) {
176         List<Node> nodes = connectionService.getNodes();
177
178         for (Node node : nodes) {
179             this.networkCreated(node, networkId);
180         }
181
182     }
183
184     @Override
185     public int networkCreated (Node node, String networkId) {
186         return vlanConfigurationCache.assignInternalVlan(node, networkId);
187     }
188
189     @Override
190     public void networkDeleted(String id) {
191         //ToDo: Delete? This method does nothing how we dropped container support...
192     }
193
194     private boolean isInterfacePresentInTenantNetwork (String portId, String networkId) {
195         NeutronPort neutronPort = neutronPortCache.getPort(portId);
196         return neutronPort != null && neutronPort.getNetworkUUID().equalsIgnoreCase(networkId);
197     }
198
199 }