2 * Copyright (c) 2016, 2017 Red Hat, Inc. 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
8 package org.opendaylight.netvirt.elan.internal;
10 import com.google.common.base.Splitter;
11 import com.google.common.base.Strings;
12 import java.util.ArrayList;
13 import java.util.Collection;
14 import java.util.Collections;
15 import java.util.HashMap;
16 import java.util.List;
18 import java.util.Optional;
19 import java.util.Random;
20 import javax.inject.Inject;
21 import javax.inject.Singleton;
22 import org.eclipse.jdt.annotation.Nullable;
23 import org.opendaylight.genius.datastoreutils.SingleTransactionDataBroker;
24 import org.opendaylight.genius.interfacemanager.globals.IfmConstants;
25 import org.opendaylight.genius.interfacemanager.interfaces.IInterfaceManager;
26 import org.opendaylight.genius.itm.globals.ITMConstants;
27 import org.opendaylight.genius.mdsalutil.MDSALUtil;
28 import org.opendaylight.mdsal.binding.api.DataBroker;
29 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
30 import org.opendaylight.mdsal.common.api.TransactionCommitFailedException;
31 import org.opendaylight.ovsdb.utils.southbound.utils.SouthboundUtils;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.config.rev150710.ElanConfig;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.DatapathId;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.DatapathTypeBase;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.DatapathTypeNetdev;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentation;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbNodeAugmentation;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.BridgeOtherConfigs;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.BridgeOtherConfigsBuilder;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.ManagedNodeEntry;
41 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
42 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
43 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
44 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
45 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
46 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeBuilder;
47 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
48 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
49 import org.opendaylight.yangtools.yang.common.Uint32;
50 import org.opendaylight.yangtools.yang.common.Uint64;
51 import org.slf4j.Logger;
52 import org.slf4j.LoggerFactory;
55 * This class provides functions for creating bridges via OVSDB, specifically the br-int bridge.
58 // Checkstyle expects the first sentence to end with a period, question marks don’t count
59 @SuppressWarnings("checkstyle:SummaryJavadoc")
60 public class ElanBridgeManager {
61 private static final Logger LOG = LoggerFactory.getLogger(ElanBridgeManager.class);
63 public static final String PROVIDER_MAPPINGS_KEY = "provider_mappings";
64 private static final String INTEGRATION_BRIDGE = "br-int";
65 private static final String INT_SIDE_PATCH_PORT_SUFFIX = "-patch";
66 private static final String EX_SIDE_PATCH_PORT_SUFFIX = "-int-patch";
67 private static final String OTHER_CONFIG_PARAMETERS_DELIMITER = ",";
68 private static final String OTHER_CONFIG_KEY_VALUE_DELIMITER = ":";
69 private static final int MAX_LINUX_INTERFACE_NAME_LENGTH = 15;
70 private static final String OTHER_CONFIG_DATAPATH_ID = "datapath-id";
71 private static final String OTHER_CONFIG_HWADDR = "hwaddr";
72 private static final String OTHER_CONFIG_DISABLE_IN_BAND = "disable-in-band";
74 private final DataBroker dataBroker;
75 private final IInterfaceManager interfaceManager;
76 private final SouthboundUtils southboundUtils;
77 private final Random random;
78 private final Uint32 maxBackoff;
79 private final Uint32 inactivityProbe;
83 * Construct a new ElanBridgeManager.
84 * @param elanConfig the elan configuration
85 * @param interfaceManager InterfaceManager
86 * @param southboundUtils southboutUtils
87 * @param dataBroker DataBroker
90 public ElanBridgeManager(ElanConfig elanConfig, IInterfaceManager interfaceManager,
91 SouthboundUtils southboundUtils, DataBroker dataBroker) {
92 //TODO: ClusterAware!!!??
93 this.dataBroker = dataBroker;
94 this.interfaceManager = interfaceManager;
95 this.southboundUtils = southboundUtils;
96 this.random = new Random(System.currentTimeMillis());
97 this.maxBackoff = elanConfig.getControllerMaxBackoff() != null
98 ? elanConfig.getControllerMaxBackoff() : Uint32.valueOf(1000);
99 this.inactivityProbe = elanConfig.getControllerInactivityProbe() != null
100 ? elanConfig.getControllerInactivityProbe() : Uint32.ZERO;
104 * Is OVS running in userspace mode?
105 * @return true if the ovsdb.userspace.enabled variable is set to true
107 public boolean isUserSpaceEnabled() {
108 final String enabledPropertyStr = System.getProperty("ovsdb.userspace.enabled", "no");
109 return enabledPropertyStr != null && enabledPropertyStr.equalsIgnoreCase("yes");
113 * Is the Node object an OVSDB node.
114 * @param node unidentified node object
115 * @return true if the Node is an OVSDB node
117 public boolean isOvsdbNode(Node node) {
118 return southboundUtils.extractNodeAugmentation(node) != null;
122 * Is this Node the integration bridge (br-int).
123 * @param node unidentified noe object
124 * @return true if the Node is a bridge and it is the integration bridge
126 public boolean isIntegrationBridge(Node node) {
127 if (!isBridgeNode(node)) {
131 String bridgeName = southboundUtils.extractBridgeName(node);
132 if (bridgeName == null) {
136 return bridgeName.equals(INTEGRATION_BRIDGE);
140 * Is this node a bridge.
141 * @param node unidentified node object
142 * @return true if this node is a bridge
144 public boolean isBridgeNode(Node node) {
145 return southboundUtils.extractBridgeAugmentation(node) != null;
149 * Advance the "preperation" of the OVSDB node. This re-entrant method advances the state of an OVSDB
150 * node towards the prepared state where all bridges and patch ports are created and active. This method
151 * should be invoked for the OVSDB node and the integration bridge node BUT IT IS SAFE TO INVOKE IT ON ANY NODE.
153 * @param generateIntBridgeMac whether or not the int bridge's mac should be set to a random value
155 @SuppressWarnings("checkstyle:IllegalCatch")
156 public void processNodePrep(Node node, boolean generateIntBridgeMac) {
157 if (isOvsdbNode(node)) {
158 if (southboundUtils.readBridgeNode(node, INTEGRATION_BRIDGE) == null) {
159 LOG.debug("OVSDB node in operational does not have br-int, create one {}", node.getNodeId().getValue());
161 createIntegrationBridgeConfig(node, generateIntBridgeMac);
162 } catch (RuntimeException e) {
163 LOG.error("Error creating bridge on {}", node, e);
169 //Assume "node" is a bridge node, extract the OVSDB node from operational
170 Node ovsdbNode = southboundUtils.readOvsdbNode(node);
171 if (ovsdbNode == null) {
172 LOG.error("Node is neither bridge nor ovsdb {}", node);
176 if (isIntegrationBridge(node)) {
177 prepareIntegrationBridge(ovsdbNode, node);
182 public void handleNewProviderNetBridges(Node originalNode, Node updatedNode) {
183 if (!isOvsdbNode(updatedNode)) {
187 List<ManagedNodeEntry> originalManagedNodes = new ArrayList<>(getManagedNodeEntries(originalNode));
188 List<ManagedNodeEntry> updatedManagedNodes = new ArrayList<>(getManagedNodeEntries(updatedNode));
190 updatedManagedNodes.removeAll(originalManagedNodes);
191 if (updatedManagedNodes.isEmpty()) {
194 LOG.debug("handleNewProviderNetBridges checking if any of these are provider nets {}", updatedManagedNodes);
196 Node brInt = southboundUtils.readBridgeNode(updatedNode, INTEGRATION_BRIDGE);
198 LOG.info("handleNewProviderNetBridges, br-int not found");
202 Collection<String> providerVals = getOpenvswitchOtherConfigMap(updatedNode, PROVIDER_MAPPINGS_KEY).values();
203 for (ManagedNodeEntry nodeEntry : updatedManagedNodes) {
204 String bridgeName = nodeEntry.getBridgeRef().getValue().firstKeyOf(Node.class).getNodeId().getValue();
205 bridgeName = bridgeName.substring(bridgeName.lastIndexOf('/') + 1);
206 if (bridgeName.equals(INTEGRATION_BRIDGE)) {
209 if (providerVals.contains(bridgeName)) {
210 patchBridgeToBrInt(brInt, southboundUtils.readBridgeNode(updatedNode, bridgeName), bridgeName);
218 private List<ManagedNodeEntry> getManagedNodeEntries(Node node) {
219 OvsdbNodeAugmentation ovsdbNode = southboundUtils.extractNodeAugmentation(node);
220 if (ovsdbNode == null) {
224 return new ArrayList<>(ovsdbNode.nonnullManagedNodeEntry().values());
227 private void prepareIntegrationBridge(Node ovsdbNode, Node brIntNode) {
228 if (southboundUtils.getBridgeFromConfig(ovsdbNode, INTEGRATION_BRIDGE) == null) {
229 LOG.debug("br-int in operational but not config, copying into config");
230 copyBridgeToConfig(brIntNode);
233 Map<String, String> providerMappings = getOpenvswitchOtherConfigMap(ovsdbNode, PROVIDER_MAPPINGS_KEY);
235 for (String value : providerMappings.values()) {
236 if (southboundUtils.extractTerminationPointAugmentation(brIntNode, value) != null) {
237 LOG.debug("prepareIntegrationBridge: port {} already exists on {}", value, INTEGRATION_BRIDGE);
241 Node exBridgeNode = southboundUtils.readBridgeNode(ovsdbNode, value);
242 if (exBridgeNode != null) {
243 LOG.debug("prepareIntegrationBridge: bridge {} found. Patching to {}", value, INTEGRATION_BRIDGE);
244 patchBridgeToBrInt(brIntNode, exBridgeNode, value);
246 LOG.debug("prepareIntegrationBridge: adding interface {} to {}", value, INTEGRATION_BRIDGE);
247 if (!addPortToBridge(brIntNode, INTEGRATION_BRIDGE, value)) {
248 LOG.error("Failed to add {} port to {}", value, brIntNode);
254 if (!addControllerToBridge(ovsdbNode, INTEGRATION_BRIDGE)) {
255 LOG.error("Failed to set controller to existing integration bridge {}", brIntNode);
260 private void copyBridgeToConfig(Node brIntNode) {
261 NodeBuilder bridgeNodeBuilder = new NodeBuilder(brIntNode);
262 bridgeNodeBuilder.setTerminationPoint(Collections.emptyMap());
263 InstanceIdentifier<Node> brNodeIid = SouthboundUtils.createInstanceIdentifier(brIntNode.getNodeId());
265 SingleTransactionDataBroker.syncUpdate(dataBroker, LogicalDatastoreType.CONFIGURATION,
266 brNodeIid, bridgeNodeBuilder.build());
267 } catch (TransactionCommitFailedException e) {
268 LOG.error("Failed to copy Bridge {} to config", brNodeIid, e);
272 private void patchBridgeToBrInt(Node intBridgeNode, Node exBridgeNode, String physnetBridgeName) {
274 String portNameInt = getIntSidePatchPortName(physnetBridgeName);
275 String portNameExt = getExSidePatchPortName(physnetBridgeName);
276 if (!addPatchPort(intBridgeNode, INTEGRATION_BRIDGE, portNameInt, portNameExt)) {
277 LOG.error("Failed to add patch port {} to {}", portNameInt, intBridgeNode);
281 if (!addPatchPort(exBridgeNode, physnetBridgeName, portNameExt, portNameInt)) {
282 LOG.error("Failed to add patch port {} to {}", portNameExt, exBridgeNode);
287 private boolean createIntegrationBridgeConfig(Node ovsdbNode, boolean generateIntBridgeMac) {
288 // Make sure iface-type exist in Open_vSwitch table prior to br-int creation
289 // in order to allow mixed topology of both DPDK and non-DPDK OVS nodes
290 if (!ifaceTypesExist(ovsdbNode)) {
291 LOG.debug("Skipping integration bridge creation as if-types has not been initialized");
295 LOG.debug("ElanBridgeManager.createIntegrationBridgeConfig, skipping if exists");
296 if (!addBridge(ovsdbNode, INTEGRATION_BRIDGE,
297 generateIntBridgeMac ? generateRandomMac() : null)) {
298 LOG.warn("Integration Bridge Creation failed");
304 private boolean ifaceTypesExist(Node ovsdbNode) {
305 OvsdbNodeAugmentation ovsdbNodeAugmentation = southboundUtils.extractNodeAugmentation(ovsdbNode);
306 return ovsdbNodeAugmentation != null && ovsdbNodeAugmentation.getInterfaceTypeEntry() != null
307 && !ovsdbNodeAugmentation.getInterfaceTypeEntry().isEmpty();
311 * Add a bridge to the OVSDB node but check that it does not exist in the
312 * CONFIGURATION. If it already exists in OPERATIONAL, update it with all
313 * configurable parameters but make sure to maintain the same datapath-id.
315 * @param ovsdbNode Which OVSDB node
316 * @param bridgeName Name of the bridge
317 * @param mac mac address to set on the bridge or null
318 * @return true if no errors occurred
320 public boolean addBridge(Node ovsdbNode, String bridgeName, @Nullable String mac) {
322 if (southboundUtils.getBridgeFromConfig(ovsdbNode, bridgeName) == null) {
323 Class<? extends DatapathTypeBase> dpType = null;
324 if (isUserSpaceEnabled()) {
325 dpType = DatapathTypeNetdev.class;
328 List<BridgeOtherConfigs> otherConfigs = buildBridgeOtherConfigs(ovsdbNode, bridgeName, mac);
330 rv = southboundUtils.addBridge(ovsdbNode, bridgeName,
331 southboundUtils.getControllersFromOvsdbNode(ovsdbNode), dpType, otherConfigs,
332 maxBackoff, inactivityProbe);
337 private List<BridgeOtherConfigs> buildBridgeOtherConfigs(Node ovsdbNode, String bridgeName, String mac) {
338 // First attempt to extract the bridge augmentation from operational...
339 Node bridgeNode = southboundUtils.getBridgeNode(ovsdbNode, bridgeName);
340 OvsdbBridgeAugmentation bridgeAug = null;
341 if (bridgeNode != null) {
342 bridgeAug = southboundUtils.extractBridgeAugmentation(bridgeNode);
345 // ...if present, it means this bridge already exists and we need to take
346 // care not to change the datapath id. We do this by explicitly setting
347 // other_config:datapath-id to the value reported in the augmentation.
348 List<BridgeOtherConfigs> otherConfigs;
349 if (bridgeAug != null) {
350 DatapathId dpId = bridgeAug.getDatapathId();
352 otherConfigs = new ArrayList<>(bridgeAug.nonnullBridgeOtherConfigs().values());
353 if (otherConfigs == null) {
354 otherConfigs = new ArrayList<>();
357 if (otherConfigs.stream().noneMatch(otherConfig ->
358 otherConfig.getBridgeOtherConfigKey().equals(OTHER_CONFIG_DATAPATH_ID))) {
359 String dpIdVal = dpId.getValue().replace(":", "");
360 otherConfigs.add(new BridgeOtherConfigsBuilder()
361 .setBridgeOtherConfigKey(OTHER_CONFIG_DATAPATH_ID)
362 .setBridgeOtherConfigValue(dpIdVal).build());
365 otherConfigs = new ArrayList<>();
368 otherConfigs = new ArrayList<>();
370 otherConfigs.add(new BridgeOtherConfigsBuilder()
371 .setBridgeOtherConfigKey(OTHER_CONFIG_HWADDR)
372 .setBridgeOtherConfigValue(mac).build());
375 //ovsdb always adds disableInBand=true, so no need to add this default value here.
376 /*if (otherConfigs.stream().noneMatch(otherConfig ->
377 otherConfig.getBridgeOtherConfigKey().equals(OTHER_CONFIG_DISABLE_IN_BAND))) {
378 otherConfigs.add(new BridgeOtherConfigsBuilder()
379 .setBridgeOtherConfigKey(OTHER_CONFIG_DISABLE_IN_BAND)
380 .setBridgeOtherConfigValue("true").build());
386 private boolean addControllerToBridge(Node ovsdbNode,String bridgeName) {
387 return southboundUtils.setBridgeController(ovsdbNode,
388 bridgeName, southboundUtils.getControllersFromOvsdbNode(ovsdbNode),
389 maxBackoff, inactivityProbe);
395 public Map<String, String> getOpenvswitchOtherConfigMap(Node node, String key) {
396 String otherConfigVal = southboundUtils.getOpenvswitchOtherConfig(node, key);
397 return getMultiValueMap(otherConfigVal);
401 * Get the OVS node physical interface name from provider mappings.
402 * @param node OVSDB node
403 * @param physicalNetworkName name of physical network
404 * @return physical network name
407 public String getProviderMappingValue(Node node, String physicalNetworkName) {
408 Map<String, String> providerMappings = getOpenvswitchOtherConfigMap(node, PROVIDER_MAPPINGS_KEY);
409 String providerMappingValue = providerMappings.get(physicalNetworkName);
410 if (providerMappingValue == null) {
411 LOG.trace("Physical network {} not found in {}", physicalNetworkName, PROVIDER_MAPPINGS_KEY);
414 return providerMappingValue;
418 * Get the name of the port in br-int for the given provider-mapping value. This is either a patch port to a bridge
419 * with providerMappingValue - patch-<providerMappingValue> or simply a port with the same name as
420 * providerMappingValue
421 * @param bridgeNode br-int Node
422 * @param providerMappingValue this is the last part of provider_mappings=net_name:THIS
423 * @return the name of the port on br-int
425 public String getIntBridgePortNameFor(Node bridgeNode, String providerMappingValue) {
426 String res = providerMappingValue;
427 Node managingNode = southboundUtils.readOvsdbNode(bridgeNode);
428 if (managingNode != null && southboundUtils.isBridgeOnOvsdbNode(managingNode, providerMappingValue)) {
429 res = getIntSidePatchPortName(providerMappingValue);
436 * Get the name of the patch-port which is patched to the bridge containing
437 * interfaceName. Patch port name is truncated to the maximum allowed characters
439 * @param interfaceName The external interface
440 * @return interface name
442 public String getIntSidePatchPortName(String interfaceName) {
443 String patchPortName = interfaceName + INT_SIDE_PATCH_PORT_SUFFIX;
444 if (patchPortName.length() <= MAX_LINUX_INTERFACE_NAME_LENGTH) {
445 return patchPortName;
448 LOG.debug("Patch port {} exceeds maximum allowed length. Truncating to {} characters",
449 patchPortName, MAX_LINUX_INTERFACE_NAME_LENGTH);
450 return patchPortName.substring(0, MAX_LINUX_INTERFACE_NAME_LENGTH - 1);
453 private static String getExSidePatchPortName(String physicalInterfaceName) {
454 return physicalInterfaceName + EX_SIDE_PATCH_PORT_SUFFIX;
458 * Add a port to a bridge.
459 * @param node the bridge node
460 * @param bridgeName name of the bridge
461 * @param portName name of port to add
462 * @return true if successful in writing to mdsal
464 public boolean addPortToBridge(Node node, String bridgeName, String portName) {
467 if (southboundUtils.extractTerminationPointAugmentation(node, portName) == null) {
468 rv = southboundUtils.addTerminationPoint(node, bridgeName, portName, null);
471 LOG.debug("addPortToBridge: node: {}, bridge: {}, portname: {} status: success",
472 node.getNodeId().getValue(), bridgeName, portName);
474 LOG.error("addPortToBridge: node: {}, bridge: {}, portname: {} status: FAILED",
475 node.getNodeId().getValue(), bridgeName, portName);
478 LOG.trace("addPortToBridge: node: {}, bridge: {}, portname: {} status: not_needed",
479 node.getNodeId().getValue(), bridgeName, portName);
486 * Add a patch port to a bridge.
487 * @param node the bridge node
488 * @param bridgeName name of the bridge
489 * @param portName name of the port
490 * @param peerPortName name of the port's peer (the other side)
491 * @return true if successful
493 public boolean addPatchPort(Node node, String bridgeName, String portName, String peerPortName) {
496 if (southboundUtils.extractTerminationPointAugmentation(node, portName) == null) {
497 rv = southboundUtils.addPatchTerminationPoint(node, bridgeName, portName, peerPortName);
500 LOG.info("addPatchPort: node: {}, bridge: {}, portname: {} peer: {} status: success",
501 node.getNodeId().getValue(), bridgeName, portName, peerPortName);
503 LOG.error("addPatchPort: node: {}, bridge: {}, portname: {} peer: {} status: FAILED",
504 node.getNodeId().getValue(), bridgeName, portName, peerPortName);
507 LOG.trace("addPatchPort: node: {}, bridge: {}, portname: {} peer: {} status: not_needed",
508 node.getNodeId().getValue(), bridgeName, portName, peerPortName);
514 public Optional<Uint64> getDpIdFromManagerNodeId(String managerNodeId) {
515 InstanceIdentifier<Node> identifier = getIntegrationBridgeIdentifier(managerNodeId);
516 OvsdbBridgeAugmentation integrationBridgeAugmentation = interfaceManager.getOvsdbBridgeForNodeIid(identifier);
517 if (integrationBridgeAugmentation == null) {
518 LOG.debug("Failed to get OvsdbBridgeAugmentation for node {}", managerNodeId);
519 return Optional.empty();
522 return Optional.ofNullable(integrationBridgeAugmentation.getDatapathId())
523 .map(datapathId -> MDSALUtil.getDpnId(datapathId.getValue()));
526 private static InstanceIdentifier<Node> getIntegrationBridgeIdentifier(String managerNodeId) {
527 NodeId brNodeId = new NodeId(
528 managerNodeId + "/" + ITMConstants.BRIDGE_URI_PREFIX + "/" + ITMConstants.DEFAULT_BRIDGE_NAME);
529 return InstanceIdentifier.create(NetworkTopology.class)
530 .child(Topology.class, new TopologyKey(IfmConstants.OVSDB_TOPOLOGY_ID))
531 .child(Node.class, new NodeKey(brNodeId));
534 private String generateRandomMac() {
535 byte[] macBytes = new byte[6];
536 random.nextBytes(macBytes);
537 macBytes[0] &= 0xfc; //the two low bits of the first byte need to be zero
539 StringBuilder stringBuilder = new StringBuilder();
543 stringBuilder.append(String.format("%02x", macBytes[index++]));
547 stringBuilder.append(':');
550 return stringBuilder.toString();
553 private static Map<String, String> getMultiValueMap(String multiKeyValueStr) {
554 if (Strings.isNullOrEmpty(multiKeyValueStr)) {
555 return Collections.emptyMap();
558 Map<String, String> valueMap = new HashMap<>();
559 Splitter splitter = Splitter.on(OTHER_CONFIG_PARAMETERS_DELIMITER);
560 for (String keyValue : splitter.split(multiKeyValueStr)) {
561 String[] split = keyValue.split(OTHER_CONFIG_KEY_VALUE_DELIMITER, 2);
562 if (split.length == 2) {
563 valueMap.put(split[0], split[1]);
574 private Node getBridgeNode(Uint64 dpId) {
575 Map<NodeKey, Node> ovsdbNodes = southboundUtils.getOvsdbNodes();
576 if (null == ovsdbNodes) {
577 LOG.debug("Could not find any (?) ovsdb nodes");
581 for (Node node : ovsdbNodes.values()) {
582 if (!isIntegrationBridge(node)) {
586 long nodeDpid = southboundUtils.getDataPathId(node);
587 if (dpId.equals(Uint64.valueOf(nodeDpid))) {
596 public String getProviderInterfaceName(Uint64 dpId, String physicalNetworkName) {
599 brNode = getBridgeNode(dpId);
600 if (brNode == null) {
601 LOG.debug("Could not find bridge node for {}", dpId);
605 return getProviderInterfaceName(brNode, physicalNetworkName);
609 public String getProviderInterfaceName(Node bridgeNode, String physicalNetworkName) {
610 if (physicalNetworkName == null) {
614 String providerMappingValue = getProviderMappingValue(bridgeNode, physicalNetworkName);
615 if (providerMappingValue == null) {
616 LOG.trace("No provider mapping found for physicalNetworkName {} node {}", physicalNetworkName,
617 bridgeNode.getNodeId().getValue());
621 long dataPathId = southboundUtils.getDataPathId(bridgeNode);
622 if (dataPathId < 1) {
623 LOG.info("No DatapathID for node {} with physicalNetworkName {}",
624 bridgeNode.getNodeId().getValue(), physicalNetworkName);
628 String portName = getIntBridgePortNameFor(bridgeNode, providerMappingValue);
629 String dpIdStr = String.valueOf(dataPathId);
630 return interfaceManager.getPortNameForInterface(dpIdStr, portName);
633 public boolean hasDatapathID(Node node) {
634 return southboundUtils.getDataPathId(node) > 0;
637 public boolean isBridgeOnOvsdbNode(Node ovsdbNode, String bridgename) {
638 return southboundUtils.isBridgeOnOvsdbNode(ovsdbNode, bridgename);
641 public String getIntegrationBridgeName() {
642 return INTEGRATION_BRIDGE;
645 public Uint64 getDatapathId(Node node) {
646 return Uint64.valueOf(southboundUtils.getDataPathId(node));