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 brInt = configurationService.getIntegrationBridgeName();
60 final String brExt = configurationService.getExternalBridgeName();
61 final String portNameInt = configurationService.getPatchPortName(new ImmutablePair<>(brInt, brExt));
62 final String portNameExt = configurationService.getPatchPortName(new ImmutablePair<>(brExt, brInt));
63 Long ofPort = port.getOfport();
64 String macAddress = neutronPort.getMacAddress();
65 final Long dpIdInt = getDpidForIntegrationBridge(envNode, portNameInt);
66 final Long dpIdExt = getDpidForExternalBridge();
67 Long patchIntPort = getPatchPort(dpIdInt, portNameInt);
68 Long patchExtPort = getPatchPort(dpIdExt, portNameExt);
69 Preconditions.checkNotNull(dpIdInt);
70 Preconditions.checkNotNull(dpIdExt);
71 Preconditions.checkNotNull(portNameInt);
72 vlanResponderProvider.programProviderNetworkOutput(dpIdInt, ofPort, patchIntPort, macAddress, write);
73 vlanResponderProvider.programProviderNetworkPopVlan(dpIdInt, network.getProviderSegmentationID(),
74 ofPort, patchIntPort, macAddress, vlanProviderCache, write);
75 vlanResponderProvider.programProviderNetworkPushVlan(dpIdExt, network.getProviderSegmentationID(),
76 patchExtPort, macAddress, vlanProviderCache, write);
77 vlanResponderProvider.programProviderNetworkDrop(dpIdExt, patchExtPort, vlanProviderCache, write);
78 } catch(Exception e) {
79 LOG.error("programProviderNetworkFlow:Error while writing a flows. Caused due to, " + e.getMessage());
83 private Long getPatchPort(final Long dpId, final String portName) {
84 final Long dpidPrimitive = dpId;
85 for (Node node : nodeCacheManager.getBridgeNodes()) {
86 if (dpidPrimitive == southbound.getDataPathId(node)) {
87 final OvsdbTerminationPointAugmentation terminationPointOfBridge =
88 southbound.getTerminationPointOfBridge(node, portName);
89 return (terminationPointOfBridge == null) ? null : terminationPointOfBridge.getOfport();
95 private void populateVLANProviderCaches() {
97 * Rebuild the cache in case of a restart.
99 if (this.isCachePopulationDone || this.neutronPortCache == null
100 || this.neutronNetworkCache == null) {
103 this.isCachePopulationDone = true;
104 Set<String> lstMacAddress;
105 List<NeutronPort> neutronPorts = neutronPortCache.getAllPorts();
106 for (NeutronPort neutronPort : neutronPorts) {
107 if (neutronPort != null && neutronPort.getDeviceOwner().equalsIgnoreCase(Constants.OWNER_ROUTER_GATEWAY)) {
108 final String macAddress = neutronPort.getMacAddress();
109 final String networkUUID = neutronPort.getNetworkUUID();
110 NeutronNetwork neutronNetwork = neutronNetworkCache.getNetwork(networkUUID);
111 if (neutronNetwork == null) {
112 neutronNetwork = neutronL3Adapter.getNetworkFromCleanupCache(networkUUID);
114 final String providerSegmentationId = neutronNetwork != null ?
115 neutronNetwork.getProviderSegmentationID() : null;
116 LOG.debug("In populateVLANProviderCaches macAddress:" + macAddress +
117 "providerSegmentationId:" + providerSegmentationId);
118 if (providerSegmentationId == null || providerSegmentationId.isEmpty()
119 || macAddress == null || macAddress.isEmpty()) {
122 if (vlanProviderCache != null && !vlanProviderCache.isEmpty() &&
123 vlanProviderCache.containsKey(providerSegmentationId)) {
124 lstMacAddress = vlanProviderCache.get(providerSegmentationId);
126 lstMacAddress = new HashSet<>();
127 vlanProviderCache.put(providerSegmentationId, lstMacAddress);
129 lstMacAddress.add(macAddress);
135 public void setDependencies(final ServiceReference serviceReference) {
136 vlanResponderProvider =
137 (VlanResponderProvider) ServiceHelper.getGlobalInstance(VlanResponderProvider.class, this);
138 configurationService =
139 (ConfigurationService) ServiceHelper.getGlobalInstance(ConfigurationService.class, this);
141 (Southbound) ServiceHelper.getGlobalInstance(Southbound.class, this);
143 (NodeCacheManager) ServiceHelper.getGlobalInstance(NodeCacheManager.class, this);
145 (NeutronL3Adapter) ServiceHelper.getGlobalInstance(NeutronL3Adapter.class, this);
149 public void setDependencies(final Object impl) {
150 if (impl instanceof VlanResponderProvider) {
151 vlanResponderProvider = (VlanResponderProvider)impl;
152 } else if (impl instanceof INeutronNetworkCRUD) {
153 neutronNetworkCache = (INeutronNetworkCRUD)impl;
154 } else if (impl instanceof INeutronPortCRUD) {
155 neutronPortCache = (INeutronPortCRUD)impl;
157 populateVLANProviderCaches();
160 private Long getDpidForIntegrationBridge(Node node, final String portName) {
161 if (southbound.getBridgeName(node).equals(configurationService.getIntegrationBridgeName())) {
162 TerminationPoint tp = southbound.readTerminationPoint(node, null, portName);
164 final long dpid = southbound.getDataPathId(node);
171 private Long getDpidForExternalBridge() {
172 List<Long> dpids = nodeCacheManager.getBridgeDpids(configurationService.getExternalBridgeName());