2 * Copyright (c) 2016 NEC Corporation and others. All rights reserved.
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
9 package org.opendaylight.netvirt.openstack.netvirt;
11 import java.util.HashSet;
12 import java.util.List;
15 import java.util.concurrent.ConcurrentHashMap;
17 import org.apache.commons.lang3.tuple.ImmutablePair;
18 import org.opendaylight.netvirt.openstack.netvirt.api.ConfigurationService;
19 import org.opendaylight.netvirt.openstack.netvirt.api.Constants;
20 import org.opendaylight.netvirt.openstack.netvirt.api.NodeCacheManager;
21 import org.opendaylight.netvirt.openstack.netvirt.api.VlanResponderProvider;
22 import org.opendaylight.netvirt.openstack.netvirt.api.Southbound;
23 import org.opendaylight.netvirt.openstack.netvirt.impl.NeutronL3Adapter;
24 import org.opendaylight.netvirt.openstack.netvirt.translator.NeutronNetwork;
25 import org.opendaylight.netvirt.openstack.netvirt.translator.NeutronPort;
26 import org.opendaylight.netvirt.openstack.netvirt.translator.Neutron_IPs;
27 import org.opendaylight.netvirt.openstack.netvirt.translator.crud.INeutronNetworkCRUD;
28 import org.opendaylight.netvirt.openstack.netvirt.translator.crud.INeutronPortCRUD;
29 import org.opendaylight.netvirt.utils.servicehelper.ServiceHelper;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbTerminationPointAugmentation;
31 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
32 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint;
33 import org.osgi.framework.ServiceReference;
34 import org.slf4j.Logger;
35 import org.slf4j.LoggerFactory;
37 import com.google.common.base.Preconditions;
40 * This class is used to add the flows when l3 is disabled in the ODL.
42 public class VLANProvider implements ConfigInterface {
43 private final Logger LOG = LoggerFactory.getLogger(VLANProvider.class);
45 // The implementation for each of these services is resolved by the OSGi Service Manager
46 private volatile ConfigurationService configurationService;
47 private volatile NodeCacheManager nodeCacheManager;
48 private volatile VlanResponderProvider vlanResponderProvider;
49 private volatile INeutronNetworkCRUD neutronNetworkCache;
50 private volatile INeutronPortCRUD neutronPortCache;
51 private Southbound southbound;
52 private volatile NeutronL3Adapter neutronL3Adapter;
53 private Map<String, Set<String>> vlanProviderCache = new ConcurrentHashMap<>();
54 private volatile boolean isCachePopulationDone = false;
56 public void programProviderNetworkFlow(Node envNode, OvsdbTerminationPointAugmentation port, NeutronNetwork network,
57 NeutronPort neutronPort, Boolean write) {
59 final String brExt = configurationService.getExternalBridgeName();
60 final String portNameInt = getPatchPortName(brExt);
61 final String portNameExt = Constants.PATCH_PORT_TO_INTEGRATION_BRIDGE_NAME;
62 Long ofPort = port.getOfport();
63 String macAddress = neutronPort.getMacAddress();
64 final Long dpIdInt = getDpidForIntegrationBridge(envNode, portNameInt);
65 final Long dpIdExt = getDpidForExternalBridge();
66 Long patchIntPort = getPatchPort(dpIdInt, portNameInt);
67 Long patchExtPort = getPatchPort(dpIdExt, portNameExt);
68 Preconditions.checkNotNull(dpIdInt);
69 Preconditions.checkNotNull(dpIdExt);
70 Preconditions.checkNotNull(portNameInt);
71 vlanResponderProvider.programProviderNetworkRulesInternal(dpIdInt, network.getProviderSegmentationID(), ofPort,
72 patchIntPort, macAddress, vlanProviderCache, write);
74 vlanResponderProvider.programProviderNetworkRulesExternal(dpIdExt, network.getProviderSegmentationID(),
75 patchExtPort, macAddress, vlanProviderCache, write);
76 } catch(Exception e) {
77 LOG.error("programProviderNetworkFlow:Error while writing a flows. Caused due to, " + e.getMessage());
82 * Construct patch port name based on external bridge name
84 * @param brExt String representing an External bridge.
85 * @return the string portNameExt.
87 public static String getPatchPortName(String brExt) {
88 String portNameExt = null;
89 if (brExt.contains("-")) {
90 String[] brExt_Ex = brExt.split("-");
91 portNameExt = Constants.MULTIPLE_NETWORK_L3_PATCH.concat("-").concat(brExt_Ex[1]);
93 portNameExt = Constants.MULTIPLE_NETWORK_L3_PATCH.concat("-").concat(brExt);
98 private Long getPatchPort(final Long dpId, final String portName) {
99 final Long dpidPrimitive = dpId;
100 for (Node node : nodeCacheManager.getBridgeNodes()) {
101 if (dpidPrimitive == southbound.getDataPathId(node)) {
102 final OvsdbTerminationPointAugmentation terminationPointOfBridge =
103 southbound.getTerminationPointOfBridge(node, portName);
104 return (terminationPointOfBridge == null) ? null : terminationPointOfBridge.getOfport();
110 private void populateVLANProviderCaches() {
112 * Rebuild the cache in case of a restart.
114 if (this.isCachePopulationDone || this.neutronPortCache == null
115 || this.neutronNetworkCache == null) {
118 this.isCachePopulationDone = true;
119 Set<String> lstMacAddress;
120 List<NeutronPort> neutronPorts = neutronPortCache.getAllPorts();
121 for (NeutronPort neutronPort : neutronPorts) {
122 if (neutronPort != null && neutronPort.getDeviceOwner().equalsIgnoreCase(Constants.OWNER_ROUTER_GATEWAY)) {
123 final String macAddress = neutronPort.getMacAddress();
124 final String networkUUID = neutronPort.getNetworkUUID();
125 NeutronNetwork neutronNetwork = neutronNetworkCache.getNetwork(networkUUID);
126 if (neutronNetwork == null) {
127 neutronNetwork = neutronL3Adapter.getNetworkFromCleanupCache(networkUUID);
129 final String providerSegmentationId = neutronNetwork != null ?
130 neutronNetwork.getProviderSegmentationID() : null;
131 LOG.debug("In populateVLANProviderCaches macAddress:" + macAddress +
132 "providerSegmentationId:" + providerSegmentationId);
133 if (providerSegmentationId == null || providerSegmentationId.isEmpty()
134 || macAddress == null || macAddress.isEmpty()) {
137 if (vlanProviderCache != null && !vlanProviderCache.isEmpty() &&
138 vlanProviderCache.containsKey(providerSegmentationId)) {
139 lstMacAddress = vlanProviderCache.get(providerSegmentationId);
141 lstMacAddress = new HashSet<>();
142 vlanProviderCache.put(providerSegmentationId, lstMacAddress);
144 lstMacAddress.add(macAddress);
150 public void setDependencies(final ServiceReference serviceReference) {
151 vlanResponderProvider =
152 (VlanResponderProvider) ServiceHelper.getGlobalInstance(VlanResponderProvider.class, this);
153 configurationService =
154 (ConfigurationService) ServiceHelper.getGlobalInstance(ConfigurationService.class, this);
156 (Southbound) ServiceHelper.getGlobalInstance(Southbound.class, this);
158 (NodeCacheManager) ServiceHelper.getGlobalInstance(NodeCacheManager.class, this);
160 (NeutronL3Adapter) ServiceHelper.getGlobalInstance(NeutronL3Adapter.class, this);
164 public void setDependencies(final Object impl) {
165 if (impl instanceof VlanResponderProvider) {
166 vlanResponderProvider = (VlanResponderProvider)impl;
167 } else if (impl instanceof INeutronNetworkCRUD) {
168 neutronNetworkCache = (INeutronNetworkCRUD)impl;
169 } else if (impl instanceof INeutronPortCRUD) {
170 neutronPortCache = (INeutronPortCRUD)impl;
172 populateVLANProviderCaches();
175 private Long getDpidForIntegrationBridge(Node node, final String portName) {
176 if (southbound.getBridgeName(node).equals(configurationService.getIntegrationBridgeName())) {
177 TerminationPoint tp = southbound.readTerminationPoint(node, null, portName);
179 final long dpid = southbound.getDataPathId(node);
186 private Long getDpidForExternalBridge() {
187 List<Long> dpids = nodeCacheManager.getBridgeDpids(configurationService.getExternalBridgeName());