2 * Copyright (c) 2015, 2018 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
9 package org.opendaylight.ovsdb.utils.southbound.utils;
11 import com.google.common.collect.ImmutableBiMap;
12 import java.math.BigInteger;
13 import java.net.Inet4Address;
14 import java.net.Inet6Address;
15 import java.net.InetAddress;
16 import java.net.UnknownHostException;
17 import java.security.InvalidParameterException;
18 import java.util.ArrayList;
19 import java.util.Collections;
20 import java.util.HashMap;
21 import java.util.List;
22 import java.util.Locale;
24 import java.util.regex.Matcher;
25 import java.util.regex.Pattern;
26 import java.util.stream.Collectors;
27 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
28 import org.opendaylight.ovsdb.utils.config.ConfigProperties;
29 import org.opendaylight.ovsdb.utils.mdsal.utils.MdsalUtils;
30 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IetfInetUtil;
31 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
32 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Address;
33 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.PortNumber;
34 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Uri;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.DatapathId;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.DatapathTypeBase;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.DatapathTypeNetdev;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.InterfaceTypeBase;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.InterfaceTypeDpdk;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.InterfaceTypeDpdkr;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.InterfaceTypeDpdkvhost;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.InterfaceTypeDpdkvhostuser;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.InterfaceTypeDpdkvhostuserclient;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.InterfaceTypeGeneve;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.InterfaceTypeGre;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.InterfaceTypeGre64;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.InterfaceTypeInternal;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.InterfaceTypeIpsecGre;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.InterfaceTypeIpsecGre64;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.InterfaceTypeLisp;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.InterfaceTypePatch;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.InterfaceTypeSystem;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.InterfaceTypeTap;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.InterfaceTypeVxlan;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.InterfaceTypeVxlanGpe;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentation;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentationBuilder;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeName;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeProtocolBase;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeProtocolOpenflow10;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeProtocolOpenflow11;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeProtocolOpenflow12;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeProtocolOpenflow13;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeProtocolOpenflow14;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeProtocolOpenflow15;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbFailModeBase;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbFailModeSecure;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbFailModeStandalone;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbNodeAugmentation;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbNodeAugmentationBuilder;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbNodeRef;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbTerminationPointAugmentation;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbTerminationPointAugmentationBuilder;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.BridgeExternalIds;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.BridgeOtherConfigs;
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.BridgeOtherConfigsBuilder;
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ControllerEntry;
78 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ControllerEntryBuilder;
79 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ProtocolEntry;
80 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ProtocolEntryBuilder;
81 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.ConnectionInfo;
82 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.ConnectionInfoBuilder;
83 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.InterfaceTypeEntry;
84 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.ManagedNodeEntry;
85 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.ManagerEntry;
86 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.OpenvswitchOtherConfigs;
87 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceExternalIds;
88 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceExternalIdsBuilder;
89 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceExternalIdsKey;
90 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.Options;
91 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.OptionsBuilder;
92 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.OptionsKey;
93 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
94 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
95 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId;
96 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TpId;
97 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
98 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
99 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
100 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeBuilder;
101 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
102 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint;
103 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointBuilder;
104 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointKey;
105 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
106 import org.slf4j.Logger;
107 import org.slf4j.LoggerFactory;
109 public class SouthboundUtils {
110 private static final Logger LOG = LoggerFactory.getLogger(SouthboundUtils.class);
111 private static final int OVSDB_UPDATE_TIMEOUT = 1000;
112 public static final TopologyId OVSDB_TOPOLOGY_ID = new TopologyId(new Uri("ovsdb:1"));
113 private final MdsalUtils mdsalUtils;
114 public static final String OPENFLOW_CONNECTION_PROTOCOL = "tcp";
115 public static final String OPENFLOW_SECURE_PROTOCOL = "ssl";
116 public static final short OPENFLOW_PORT = 6653;
117 public static final String OVSDB_URI_PREFIX = "ovsdb";
118 public static final String BRIDGE_URI_PREFIX = "bridge";
119 private static final String DISABLE_IN_BAND = "disable-in-band";
120 private static final String PATCH_PORT_TYPE = "patch";
121 // External ID key used for mapping between an OVSDB port and an interface name
122 private static final String EXTERNAL_INTERFACE_ID_KEY = "iface-id";
124 private static final String FORMAT = "(\\d+)\\.(\\d+)\\.(\\d+)";
125 private static final Pattern PATTERN = Pattern.compile(FORMAT);
128 public SouthboundUtils(MdsalUtils mdsalUtils) {
129 this.mdsalUtils = mdsalUtils;
132 public static final ImmutableBiMap<String, Class<? extends InterfaceTypeBase>> OVSDB_INTERFACE_TYPE_MAP
133 = new ImmutableBiMap.Builder<String, Class<? extends InterfaceTypeBase>>()
134 .put("internal", InterfaceTypeInternal.class)
135 .put("vxlan", InterfaceTypeVxlan.class)
136 .put("vxlan-gpe", InterfaceTypeVxlanGpe.class)
137 .put("patch", InterfaceTypePatch.class)
138 .put("system", InterfaceTypeSystem.class)
139 .put("tap", InterfaceTypeTap.class)
140 .put("geneve", InterfaceTypeGeneve.class)
141 .put("gre", InterfaceTypeGre.class)
142 .put("ipsec_gre", InterfaceTypeIpsecGre.class)
143 .put("gre64", InterfaceTypeGre64.class)
144 .put("ipsec_gre64", InterfaceTypeIpsecGre64.class)
145 .put("lisp", InterfaceTypeLisp.class)
146 .put("dpdk", InterfaceTypeDpdk.class)
147 .put("dpdkr", InterfaceTypeDpdkr.class)
148 .put("dpdkvhost", InterfaceTypeDpdkvhost.class)
149 .put("dpdkvhostuser", InterfaceTypeDpdkvhostuser.class)
150 .put("dpdkvhostuserclient", InterfaceTypeDpdkvhostuserclient.class)
153 public static final ImmutableBiMap<Class<? extends OvsdbBridgeProtocolBase>,String> OVSDB_PROTOCOL_MAP
154 = new ImmutableBiMap.Builder<Class<? extends OvsdbBridgeProtocolBase>,String>()
155 .put(OvsdbBridgeProtocolOpenflow10.class,"OpenFlow10")
156 .put(OvsdbBridgeProtocolOpenflow11.class,"OpenFlow11")
157 .put(OvsdbBridgeProtocolOpenflow12.class,"OpenFlow12")
158 .put(OvsdbBridgeProtocolOpenflow13.class,"OpenFlow13")
159 .put(OvsdbBridgeProtocolOpenflow14.class,"OpenFlow14")
160 .put(OvsdbBridgeProtocolOpenflow15.class,"OpenFlow15")
163 private static final ImmutableBiMap<Class<? extends OvsdbFailModeBase>,String> OVSDB_FAIL_MODE_MAP
164 = new ImmutableBiMap.Builder<Class<? extends OvsdbFailModeBase>,String>()
165 .put(OvsdbFailModeStandalone.class,"standalone")
166 .put(OvsdbFailModeSecure.class,"secure")
169 public static NodeId createNodeId(IpAddress ip, PortNumber port) {
170 String uriString = OVSDB_URI_PREFIX + "://" + ip.stringValue() + ":" + port.getValue();
171 Uri uri = new Uri(uriString);
172 return new NodeId(uri);
175 public static Node createNode(ConnectionInfo key) {
176 NodeBuilder nodeBuilder = new NodeBuilder();
177 nodeBuilder.setNodeId(createNodeId(key.getRemoteIp(), key.getRemotePort()));
178 nodeBuilder.addAugmentation(OvsdbNodeAugmentation.class, createOvsdbAugmentation(key));
179 return nodeBuilder.build();
182 public static OvsdbNodeAugmentation createOvsdbAugmentation(ConnectionInfo key) {
183 OvsdbNodeAugmentationBuilder ovsdbNodeBuilder = new OvsdbNodeAugmentationBuilder();
184 ovsdbNodeBuilder.setConnectionInfo(key);
185 return ovsdbNodeBuilder.build();
188 public static InstanceIdentifier<Node> createInstanceIdentifier(NodeId nodeId) {
189 return InstanceIdentifier
190 .create(NetworkTopology.class)
191 .child(Topology.class, new TopologyKey(OVSDB_TOPOLOGY_ID))
192 .child(Node.class,new NodeKey(nodeId));
195 public static InstanceIdentifier<Node> createInstanceIdentifier(NodeKey ovsdbNodeKey, String bridgeName) {
196 return createInstanceIdentifier(createManagedNodeId(ovsdbNodeKey.getNodeId(), bridgeName));
199 public static InstanceIdentifier<Node> createInstanceIdentifier(ConnectionInfo key) {
200 return createInstanceIdentifier(key.getRemoteIp(), key.getRemotePort());
203 public static InstanceIdentifier<Node> createInstanceIdentifier(IpAddress ip, PortNumber port) {
204 InstanceIdentifier<Node> path = InstanceIdentifier
205 .create(NetworkTopology.class)
206 .child(Topology.class, new TopologyKey(OVSDB_TOPOLOGY_ID))
207 .child(Node.class,createNodeKey(ip,port));
208 LOG.debug("Created ovsdb path: {}",path);
212 public static InstanceIdentifier<Node> createInstanceIdentifier(ConnectionInfo key, OvsdbBridgeName bridgeName) {
213 return createInstanceIdentifier(createManagedNodeId(key, bridgeName));
216 public static InstanceIdentifier<Node> createInstanceIdentifier(ConnectionInfo key, String bridgeName) {
217 return createInstanceIdentifier(key, new OvsdbBridgeName(bridgeName));
220 public InstanceIdentifier<TerminationPoint> createTerminationPointInstanceIdentifier(Node node, String portName) {
222 InstanceIdentifier<TerminationPoint> terminationPointPath = InstanceIdentifier
223 .create(NetworkTopology.class)
224 .child(Topology.class, new TopologyKey(OVSDB_TOPOLOGY_ID))
225 .child(Node.class,node.key())
226 .child(TerminationPoint.class, new TerminationPointKey(new TpId(portName)));
228 LOG.debug("Termination point InstanceIdentifier generated : {}",terminationPointPath);
229 return terminationPointPath;
232 public static NodeKey createNodeKey(IpAddress ip, PortNumber port) {
233 return new NodeKey(createNodeId(ip, port));
236 public static NodeId createManagedNodeId(NodeId ovsdbNodeId, String bridgeName) {
237 return new NodeId(ovsdbNodeId.getValue()
238 + "/" + BRIDGE_URI_PREFIX + "/" + bridgeName);
241 public static NodeId createManagedNodeId(ConnectionInfo key, OvsdbBridgeName bridgeName) {
242 return createManagedNodeId(key.getRemoteIp(), key.getRemotePort(), bridgeName);
245 public static NodeId createManagedNodeId(IpAddress ip, PortNumber port, OvsdbBridgeName bridgeName) {
246 return new NodeId(createNodeId(ip,port).getValue()
247 + "/" + BRIDGE_URI_PREFIX + "/" + bridgeName.getValue());
250 public static NodeId createManagedNodeId(InstanceIdentifier<Node> iid) {
251 NodeKey nodeKey = iid.firstKeyOf(Node.class);
252 return nodeKey.getNodeId();
255 public OvsdbNodeAugmentation extractOvsdbNode(Node node) {
256 return node.augmentation(OvsdbNodeAugmentation.class);
259 public static IpAddress createIpAddress(InetAddress address) {
261 if (address instanceof Inet4Address) {
262 ip = createIpAddress((Inet4Address)address);
263 } else if (address instanceof Inet6Address) {
264 ip = createIpAddress((Inet6Address)address);
269 public static IpAddress createIpAddress(Inet4Address address) {
270 return IetfInetUtil.INSTANCE.ipAddressFor(address);
273 public static IpAddress createIpAddress(Inet6Address address) {
274 Ipv6Address ipv6 = new Ipv6Address(address.getHostAddress());
275 return new IpAddress(ipv6);
278 public ConnectionInfo getConnectionInfo(Node ovsdbNode) {
279 ConnectionInfo connectionInfo = null;
280 OvsdbNodeAugmentation ovsdbNodeAugmentation = extractOvsdbNode(ovsdbNode);
281 if (ovsdbNodeAugmentation != null) {
282 connectionInfo = ovsdbNodeAugmentation.getConnectionInfo();
284 return connectionInfo;
287 public static ConnectionInfo getConnectionInfo(final String addressStr, final String portStr) {
288 InetAddress inetAddress = null;
290 inetAddress = InetAddress.getByName(addressStr);
291 } catch (UnknownHostException e) {
292 LOG.warn("Could not allocate InetAddress", e);
295 IpAddress address = createIpAddress(inetAddress);
296 PortNumber port = new PortNumber(Integer.parseInt(portStr));
298 LOG.info("connectionInfo: {}", new ConnectionInfoBuilder()
299 .setRemoteIp(address)
302 return new ConnectionInfoBuilder()
303 .setRemoteIp(address)
308 public static String connectionInfoToString(final ConnectionInfo connectionInfo) {
309 return connectionInfo.getRemoteIp().stringValue() + ":" + connectionInfo.getRemotePort().getValue();
312 public boolean addOvsdbNode(final ConnectionInfo connectionInfo) {
313 return addOvsdbNode(connectionInfo, OVSDB_UPDATE_TIMEOUT);
316 public boolean addOvsdbNode(final ConnectionInfo connectionInfo, long timeout) {
317 boolean result = mdsalUtils.put(LogicalDatastoreType.CONFIGURATION,
318 createInstanceIdentifier(connectionInfo),
319 createNode(connectionInfo));
322 Thread.sleep(timeout);
323 } catch (InterruptedException e) {
324 LOG.warn("Interrupted while waiting after adding OVSDB node {}",
325 connectionInfoToString(connectionInfo), e);
331 public Node getOvsdbNode(final ConnectionInfo connectionInfo) {
332 return mdsalUtils.read(LogicalDatastoreType.OPERATIONAL,
333 createInstanceIdentifier(connectionInfo));
336 public boolean deleteOvsdbNode(final ConnectionInfo connectionInfo) {
337 return deleteOvsdbNode(connectionInfo, OVSDB_UPDATE_TIMEOUT);
340 public boolean deleteOvsdbNode(final ConnectionInfo connectionInfo, long timeout) {
341 boolean result = mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION,
342 createInstanceIdentifier(connectionInfo));
345 Thread.sleep(timeout);
346 } catch (InterruptedException e) {
347 LOG.warn("Interrupted while waiting after deleting OVSDB node {}",
348 connectionInfoToString(connectionInfo), e);
354 public Node connectOvsdbNode(final ConnectionInfo connectionInfo) {
355 return connectOvsdbNode(connectionInfo, OVSDB_UPDATE_TIMEOUT);
358 public Node connectOvsdbNode(final ConnectionInfo connectionInfo, long timeout) {
359 addOvsdbNode(connectionInfo, timeout);
360 Node node = getOvsdbNode(connectionInfo);
361 LOG.info("Connected to {}", connectionInfoToString(connectionInfo));
365 public boolean disconnectOvsdbNode(final ConnectionInfo connectionInfo) {
366 return disconnectOvsdbNode(connectionInfo, OVSDB_UPDATE_TIMEOUT);
369 public boolean disconnectOvsdbNode(final ConnectionInfo connectionInfo, long timeout) {
370 deleteOvsdbNode(connectionInfo, timeout);
371 LOG.info("Disconnected from {}", connectionInfoToString(connectionInfo));
375 public List<ControllerEntry> createControllerEntry(String controllerTarget) {
376 List<ControllerEntry> controllerEntriesList = new ArrayList<>();
377 controllerEntriesList.add(new ControllerEntryBuilder()
378 .setTarget(new Uri(controllerTarget))
380 return controllerEntriesList;
384 * Extract the <code>store</code> type data store contents for the particular bridge identified by
385 * <code>bridgeName</code>.
387 * @param connectionInfo address for the node
388 * @param bridgeName name of the bridge
389 * @param store defined by the <code>LogicalDatastoreType</code> enumeration
390 * @return <code>store</code> type data store contents
392 public OvsdbBridgeAugmentation getBridge(ConnectionInfo connectionInfo, String bridgeName,
393 LogicalDatastoreType store) {
394 OvsdbBridgeAugmentation ovsdbBridgeAugmentation = null;
395 Node bridgeNode = getBridgeNode(connectionInfo, bridgeName, store);
396 if (bridgeNode != null) {
397 ovsdbBridgeAugmentation = bridgeNode.augmentation(OvsdbBridgeAugmentation.class);
399 return ovsdbBridgeAugmentation;
403 * Extract the <code>LogicalDataStoreType.OPERATIONAL</code> type data store contents for the particular bridge
404 * identified by <code>bridgeName</code>.
406 * @param connectionInfo address for the node
407 * @param bridgeName name of the bridge
408 * @see <code>NetvirtIT.getBridge(ConnectionInfo, String, LogicalDatastoreType)</code>
409 * @return <code>LogicalDatastoreType.OPERATIONAL</code> type data store contents
411 public OvsdbBridgeAugmentation getBridge(ConnectionInfo connectionInfo, String bridgeName) {
412 return getBridge(connectionInfo, bridgeName, LogicalDatastoreType.OPERATIONAL);
416 * Extract the node contents from <code>store</code> type data store for the
417 * bridge identified by <code>bridgeName</code>.
419 * @param connectionInfo address for the node
420 * @param bridgeName name of the bridge
421 * @param store defined by the <code>LogicalDatastoreType</code> enumeration
422 * @return <code>store</code> type data store contents
424 public Node getBridgeNode(ConnectionInfo connectionInfo, String bridgeName, LogicalDatastoreType store) {
425 InstanceIdentifier<Node> bridgeIid = createInstanceIdentifier(connectionInfo, new OvsdbBridgeName(bridgeName));
426 return mdsalUtils.read(store, bridgeIid);
429 public Node getBridgeNode(Node node, String bridgeName) {
430 OvsdbBridgeAugmentation bridge = extractBridgeAugmentation(node);
431 if (bridge != null && bridge.getBridgeName().getValue().equals(bridgeName)) {
434 return readBridgeNode(node, bridgeName);
438 public Node readBridgeNode(Node node, String name) {
439 Node ovsdbNode = node;
440 if (extractNodeAugmentation(ovsdbNode) == null) {
441 ovsdbNode = readOvsdbNode(node);
442 if (ovsdbNode == null) {
446 Node bridgeNode = null;
447 ConnectionInfo connectionInfo = getConnectionInfo(ovsdbNode);
448 if (connectionInfo != null) {
449 InstanceIdentifier<Node> bridgeIid =
450 createInstanceIdentifier(node.key(), name);
451 bridgeNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, bridgeIid);
456 public OvsdbNodeAugmentation extractNodeAugmentation(Node node) {
457 return node.augmentation(OvsdbNodeAugmentation.class);
460 public OvsdbBridgeAugmentation extractBridgeAugmentation(Node node) {
464 return node.augmentation(OvsdbBridgeAugmentation.class);
467 public Node readOvsdbNode(Node bridgeNode) {
468 Node ovsdbNode = null;
469 OvsdbBridgeAugmentation bridgeAugmentation = extractBridgeAugmentation(bridgeNode);
470 if (bridgeAugmentation != null) {
471 InstanceIdentifier<Node> ovsdbNodeIid =
472 (InstanceIdentifier<Node>) bridgeAugmentation.getManagedBy().getValue();
473 ovsdbNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, ovsdbNodeIid);
475 LOG.debug("readOvsdbNode: Provided node is not a bridge node : {}",bridgeNode);
480 public boolean deleteBridge(final ConnectionInfo connectionInfo, final String bridgeName) {
481 return deleteBridge(connectionInfo, bridgeName, OVSDB_UPDATE_TIMEOUT);
484 public boolean deleteBridge(final ConnectionInfo connectionInfo, final String bridgeName, long timeout) {
485 boolean result = mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION,
486 createInstanceIdentifier(connectionInfo, new OvsdbBridgeName(bridgeName)));
489 Thread.sleep(timeout);
490 } catch (InterruptedException e) {
491 LOG.warn("Interrupted while waiting after deleting bridge {}", bridgeName, e);
497 public List<ProtocolEntry> createMdsalProtocols() {
498 List<ProtocolEntry> protocolList = new ArrayList<>();
499 ImmutableBiMap<String, Class<? extends OvsdbBridgeProtocolBase>> mapper =
500 OVSDB_PROTOCOL_MAP.inverse();
501 protocolList.add(new ProtocolEntryBuilder().setProtocol(mapper.get("OpenFlow13")).build());
506 * base method for adding test bridges. Other helper methods used to create bridges should utilize this method.
508 * @param connectionInfo
509 * @param bridgeIid if passed null, one is created
510 * @param bridgeName cannot be null
511 * @param bridgeNodeId if passed null, one is created based on <code>bridgeIid</code>
512 * @param setProtocolEntries toggles whether default protocol entries are set for the bridge
513 * @param failMode toggles whether default fail mode is set for the bridge
514 * @param setManagedBy toggles whether to setManagedBy for the bridge
515 * @param dpType if passed null, this parameter is ignored
516 * @param externalIds if passed null, this parameter is ignored
517 * @param otherConfig if passed null, this parameter is ignored
518 * @return success of bridge addition
519 * @throws InterruptedException
521 public boolean addBridge(final ConnectionInfo connectionInfo, InstanceIdentifier<Node> bridgeIid,
522 final String bridgeName, NodeId bridgeNodeId, final boolean setProtocolEntries,
523 final Class<? extends OvsdbFailModeBase> failMode, final boolean setManagedBy,
524 final Class<? extends DatapathTypeBase> dpType,
525 final List<BridgeExternalIds> externalIds,
526 final List<ControllerEntry> controllerEntries,
527 final List<BridgeOtherConfigs> otherConfigs,
528 final String dpid, long timeout) throws InterruptedException {
530 NodeBuilder bridgeNodeBuilder = new NodeBuilder();
531 if (bridgeIid == null) {
532 bridgeIid = createInstanceIdentifier(connectionInfo, new OvsdbBridgeName(bridgeName));
534 if (bridgeNodeId == null) {
535 bridgeNodeId = createManagedNodeId(bridgeIid);
537 bridgeNodeBuilder.setNodeId(bridgeNodeId);
538 OvsdbBridgeAugmentationBuilder ovsdbBridgeAugmentationBuilder = new OvsdbBridgeAugmentationBuilder();
539 ovsdbBridgeAugmentationBuilder.setBridgeName(new OvsdbBridgeName(bridgeName));
540 if (setProtocolEntries) {
541 ovsdbBridgeAugmentationBuilder.setProtocolEntry(createMdsalProtocols());
543 if (failMode != null) {
544 ovsdbBridgeAugmentationBuilder.setFailMode(failMode);
547 setManagedBy(ovsdbBridgeAugmentationBuilder, connectionInfo);
549 if (dpType != null) {
550 ovsdbBridgeAugmentationBuilder.setDatapathType(dpType);
552 if (externalIds != null) {
553 ovsdbBridgeAugmentationBuilder.setBridgeExternalIds(externalIds);
555 if (controllerEntries != null) {
556 ovsdbBridgeAugmentationBuilder.setControllerEntry(controllerEntries);
558 if (otherConfigs != null) {
559 ovsdbBridgeAugmentationBuilder.setBridgeOtherConfigs(otherConfigs);
561 if (dpid != null && !dpid.isEmpty()) {
562 DatapathId datapathId = new DatapathId(dpid);
563 ovsdbBridgeAugmentationBuilder.setDatapathId(datapathId);
565 bridgeNodeBuilder.addAugmentation(OvsdbBridgeAugmentation.class, ovsdbBridgeAugmentationBuilder.build());
566 LOG.debug("Built with the intent to store bridge data {}",
567 ovsdbBridgeAugmentationBuilder.toString());
568 boolean result = mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION,
569 bridgeIid, bridgeNodeBuilder.build());
571 Thread.sleep(OVSDB_UPDATE_TIMEOUT);
576 public boolean addBridge(Node ovsdbNode, String bridgeName, List<String> controllersStr,
577 final Class<? extends DatapathTypeBase> dpType, String mac) {
578 return addBridge(ovsdbNode, bridgeName, controllersStr, dpType, mac, null, null);
581 public boolean addBridge(Node ovsdbNode, String bridgeName, List<String> controllersStr,
582 final Class<? extends DatapathTypeBase> dpType, String mac,
583 Long maxBackoff, Long inactivityProbe) {
584 List<BridgeOtherConfigs> otherConfigs = new ArrayList<>();
586 BridgeOtherConfigsBuilder macOtherConfigBuilder = new BridgeOtherConfigsBuilder();
587 macOtherConfigBuilder.setBridgeOtherConfigKey("hwaddr");
588 macOtherConfigBuilder.setBridgeOtherConfigValue(mac);
589 otherConfigs.add(macOtherConfigBuilder.build());
592 return addBridge(ovsdbNode, bridgeName, controllersStr, dpType, otherConfigs, null, null);
595 public boolean addBridge(Node ovsdbNode, String bridgeName, List<String> controllersStr,
596 final Class<? extends DatapathTypeBase> dpType,
597 List<BridgeOtherConfigs> otherConfigs,
598 Long maxBackoff, Long inactivityProbe) {
601 LOG.info("addBridge: node: {}, bridgeName: {}, controller(s): {}", ovsdbNode, bridgeName, controllersStr);
602 ConnectionInfo connectionInfo = getConnectionInfo(ovsdbNode);
603 if (connectionInfo != null) {
604 NodeBuilder bridgeNodeBuilder = new NodeBuilder();
605 InstanceIdentifier<Node> bridgeIid = createInstanceIdentifier(ovsdbNode.key(), bridgeName);
606 NodeId bridgeNodeId = createManagedNodeId(bridgeIid);
607 bridgeNodeBuilder.setNodeId(bridgeNodeId);
608 OvsdbBridgeAugmentationBuilder ovsdbBridgeAugmentationBuilder = new OvsdbBridgeAugmentationBuilder();
609 ovsdbBridgeAugmentationBuilder.setControllerEntry(createControllerEntries(
610 controllersStr, maxBackoff, inactivityProbe));
611 ovsdbBridgeAugmentationBuilder.setBridgeName(new OvsdbBridgeName(bridgeName));
612 ovsdbBridgeAugmentationBuilder.setProtocolEntry(createMdsalProtocols());
613 ovsdbBridgeAugmentationBuilder.setFailMode(OVSDB_FAIL_MODE_MAP.inverse().get("secure"));
614 // TODO: Currently netvirt relies on this function to set disabled-in-band=true. However,
615 // TODO (cont): a better design would be to have netvirt pass that in. That way this function
616 // TODO (cont): can take a null otherConfigs to erase other_configs.
617 if (otherConfigs == null) {
618 otherConfigs = new ArrayList<>();
620 BridgeOtherConfigsBuilder bridgeOtherConfigsBuilder = new BridgeOtherConfigsBuilder();
621 bridgeOtherConfigsBuilder.setBridgeOtherConfigKey(DISABLE_IN_BAND);
622 bridgeOtherConfigsBuilder.setBridgeOtherConfigValue("true");
623 otherConfigs.add(bridgeOtherConfigsBuilder.build());
624 ovsdbBridgeAugmentationBuilder.setBridgeOtherConfigs(otherConfigs);
625 setManagedByForBridge(ovsdbBridgeAugmentationBuilder, ovsdbNode.key());
626 if (dpType != null) {
627 ovsdbBridgeAugmentationBuilder.setDatapathType(dpType);
629 if (isOvsdbNodeDpdk(ovsdbNode)) {
630 ovsdbBridgeAugmentationBuilder.setDatapathType(DatapathTypeNetdev.class);
632 bridgeNodeBuilder.addAugmentation(OvsdbBridgeAugmentation.class, ovsdbBridgeAugmentationBuilder.build());
634 Node node = bridgeNodeBuilder.build();
635 result = mdsalUtils.put(LogicalDatastoreType.CONFIGURATION, bridgeIid, node);
636 LOG.info("addBridge: result: {}", result);
638 throw new InvalidParameterException("Could not find ConnectionInfo");
644 * Set the controllers of an existing bridge node.
646 * @param ovsdbNode where the bridge is
647 * @param bridgeName Name of the bridge
648 * @param controllers controller strings
649 * @return success if the write to md-sal was successful
651 public boolean setBridgeController(Node ovsdbNode, String bridgeName, List<String> controllers) {
652 return setBridgeController(ovsdbNode, bridgeName, controllers, null, null);
656 * Set the controllers of an existing bridge node.
658 * @param ovsdbNode where the bridge is
659 * @param bridgeName Name of the bridge
660 * @param controllers controller strings
661 * @param maxBackoff Max backoff in milliseconds
662 * @param inactivityProbe inactivity probe in milliseconds
663 * @return success if the write to md-sal was successful
665 public boolean setBridgeController(Node ovsdbNode, String bridgeName, List<String> controllers,
666 Long maxBackoff, Long inactivityProbe) {
667 LOG.debug("setBridgeController: ovsdbNode: {}, bridgeNode: {}, controller(s): {}",
668 ovsdbNode, bridgeName, controllers);
670 InstanceIdentifier<Node> bridgeNodeIid = createInstanceIdentifier(ovsdbNode.key(), bridgeName);
671 Node bridgeNode = mdsalUtils.read(LogicalDatastoreType.CONFIGURATION, bridgeNodeIid);
672 if (bridgeNode == null) {
673 LOG.info("setBridgeController could not find bridge in configuration {}", bridgeNodeIid);
677 OvsdbBridgeAugmentation bridgeAug = extractBridgeAugmentation(bridgeNode);
679 //Only add controller entries that do not already exist on this bridge
680 List<ControllerEntry> existingControllerEntries = bridgeAug.getControllerEntry();
681 List<ControllerEntry> newControllerEntries = new ArrayList<>();
682 if (existingControllerEntries != null) {
684 for (ControllerEntry newEntry : createControllerEntries(controllers, maxBackoff, inactivityProbe)) {
685 for (ControllerEntry existingEntry : existingControllerEntries) {
686 if (newEntry.getTarget().equals(existingEntry.getTarget())) {
687 continue NEW_ENTRY_LOOP;
690 newControllerEntries.add(newEntry);
693 newControllerEntries = createControllerEntries(controllers,maxBackoff, inactivityProbe);
696 if (newControllerEntries.isEmpty()) {
700 NodeBuilder nodeBuilder = new NodeBuilder(bridgeNode);
701 OvsdbBridgeAugmentationBuilder augBuilder = new OvsdbBridgeAugmentationBuilder(bridgeAug);
703 augBuilder.setControllerEntry(newControllerEntries);
704 nodeBuilder.addAugmentation(OvsdbBridgeAugmentation.class, augBuilder.build());
705 InstanceIdentifier<Node> bridgeIid = createInstanceIdentifier(ovsdbNode.key(), bridgeName);
706 return mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION, bridgeIid, nodeBuilder.build());
709 private void setManagedBy(final OvsdbBridgeAugmentationBuilder ovsdbBridgeAugmentationBuilder,
710 final ConnectionInfo connectionInfo) {
711 InstanceIdentifier<Node> connectionNodePath = createInstanceIdentifier(connectionInfo);
712 ovsdbBridgeAugmentationBuilder.setManagedBy(new OvsdbNodeRef(connectionNodePath));
715 public boolean addTerminationPoint(
716 Node bridgeNode, String portName, String type, Map<String, String> options,
717 Map<String, String> externalIds) {
718 return addTerminationPoint(bridgeNode, portName, type, options, externalIds, null);
721 public boolean addTerminationPoint(
722 Node bridgeNode, String portName, String type, Map<String, String> options, Map<String, String> externalIds,
724 OvsdbTerminationPointAugmentationBuilder tpAugmentationBuilder = new OvsdbTerminationPointAugmentationBuilder();
726 tpAugmentationBuilder.setName(portName);
727 tpAugmentationBuilder.setOfport(ofPort);
729 tpAugmentationBuilder.setInterfaceType(OVSDB_INTERFACE_TYPE_MAP.get(type));
732 if (options != null && options.size() > 0) {
733 List<Options> optionsList = new ArrayList<>();
734 for (Map.Entry<String, String> entry : options.entrySet()) {
735 OptionsBuilder optionsBuilder = new OptionsBuilder();
736 optionsBuilder.withKey(new OptionsKey(entry.getKey()));
737 optionsBuilder.setOption(entry.getKey());
738 optionsBuilder.setValue(entry.getValue());
739 optionsList.add(optionsBuilder.build());
741 tpAugmentationBuilder.setOptions(optionsList);
744 if (externalIds != null && externalIds.size() > 0) {
745 List<InterfaceExternalIds> externalIdsList = new ArrayList<>();
746 for (Map.Entry<String, String> entry : externalIds.entrySet()) {
747 InterfaceExternalIdsBuilder interfaceExternalIdsBuilder = new InterfaceExternalIdsBuilder();
748 interfaceExternalIdsBuilder.withKey(new InterfaceExternalIdsKey(entry.getKey()));
749 interfaceExternalIdsBuilder.setExternalIdKey(entry.getKey());
750 interfaceExternalIdsBuilder.setExternalIdValue(entry.getValue());
751 externalIdsList.add(interfaceExternalIdsBuilder.build());
753 tpAugmentationBuilder.setInterfaceExternalIds(externalIdsList);
756 TerminationPointBuilder tpBuilder = new TerminationPointBuilder();
757 InstanceIdentifier<TerminationPoint> tpIid = createTerminationPointInstanceIdentifier(bridgeNode, portName);
758 tpBuilder.withKey(InstanceIdentifier.keyOf(tpIid));
759 tpBuilder.addAugmentation(OvsdbTerminationPointAugmentation.class, tpAugmentationBuilder.build());
760 /* TODO SB_MIGRATION should this be merge or mdsalUtils.put */
761 return mdsalUtils.put(LogicalDatastoreType.CONFIGURATION, tpIid, tpBuilder.build());
764 public Boolean addTerminationPoint(Node bridgeNode, String portName, String type) {
765 return addTerminationPoint(bridgeNode, portName, type, Collections.EMPTY_MAP, null);
768 public Boolean addTerminationPoint(Node bridgeNode, String bridgeName, String portName,
769 String type, Map<String, String> options) {
770 OvsdbTerminationPointAugmentationBuilder tpAugmentationBuilder = new OvsdbTerminationPointAugmentationBuilder();
772 tpAugmentationBuilder.setName(portName);
774 tpAugmentationBuilder.setInterfaceType(OVSDB_INTERFACE_TYPE_MAP.get(type));
777 List<Options> optionsList = new ArrayList<>();
778 for (Map.Entry<String, String> entry : options.entrySet()) {
779 OptionsBuilder optionsBuilder = new OptionsBuilder();
780 optionsBuilder.withKey(new OptionsKey(entry.getKey()));
781 optionsBuilder.setOption(entry.getKey());
782 optionsBuilder.setValue(entry.getValue());
783 optionsList.add(optionsBuilder.build());
785 tpAugmentationBuilder.setOptions(optionsList);
787 TerminationPointBuilder tpBuilder = new TerminationPointBuilder();
788 InstanceIdentifier<TerminationPoint> tpIid = createTerminationPointInstanceIdentifier(bridgeNode, portName);
789 tpBuilder.withKey(InstanceIdentifier.keyOf(tpIid));
790 tpBuilder.addAugmentation(OvsdbTerminationPointAugmentation.class, tpAugmentationBuilder.build());
791 /* TODO SB_MIGRATION should this be merge or mdsalUtils.put */
792 return mdsalUtils.put(LogicalDatastoreType.CONFIGURATION, tpIid, tpBuilder.build());
795 public Boolean addTerminationPoint(Node bridgeNode, String bridgeName, String portName, String type) {
796 InstanceIdentifier<TerminationPoint> tpIid = createTerminationPointInstanceIdentifier(bridgeNode, portName);
797 OvsdbTerminationPointAugmentationBuilder tpAugmentationBuilder =
798 new OvsdbTerminationPointAugmentationBuilder();
800 tpAugmentationBuilder.setName(portName);
802 tpAugmentationBuilder.setInterfaceType(OVSDB_INTERFACE_TYPE_MAP.get(type));
804 TerminationPointBuilder tpBuilder = new TerminationPointBuilder();
805 tpBuilder.withKey(InstanceIdentifier.keyOf(tpIid));
806 tpBuilder.addAugmentation(OvsdbTerminationPointAugmentation.class, tpAugmentationBuilder.build());
807 return mdsalUtils.put(LogicalDatastoreType.CONFIGURATION, tpIid, tpBuilder.build());
810 public Boolean addPatchTerminationPoint(Node node, String bridgeName, String portName, String peerPortName) {
811 Map<String, String> option = new HashMap<>();
812 option.put("peer", peerPortName);
813 return addTerminationPoint(node, bridgeName, portName, PATCH_PORT_TYPE, option);
816 private String getControllerIPAddress() {
817 String addressString = ConfigProperties.getProperty(this.getClass(), "ovsdb.controller.address");
818 if (addressString != null) {
820 if (InetAddress.getByName(addressString) != null) {
821 return addressString;
823 } catch (UnknownHostException e) {
824 LOG.error("Host {} is invalid", addressString, e);
828 addressString = ConfigProperties.getProperty(this.getClass(), "of.address");
829 if (addressString != null) {
831 if (InetAddress.getByName(addressString) != null) {
832 return addressString;
834 } catch (UnknownHostException e) {
835 LOG.error("Host {} is invalid", addressString, e);
842 private short getControllerOFPort() {
843 short openFlowPort = OPENFLOW_PORT;
844 String portString = ConfigProperties.getProperty(this.getClass(), "of.listenPort");
845 if (portString != null) {
847 openFlowPort = Short.parseShort(portString);
848 } catch (NumberFormatException e) {
849 LOG.warn("Invalid port:{}, use default({})", portString,
856 public List<String> getControllersFromOvsdbNode(Node node) {
857 List<String> controllersStr = new ArrayList<>();
859 String controllerIpStr = getControllerIPAddress();
860 if (controllerIpStr != null) {
861 // If codepath makes it here, the ip address to be used was explicitly provided.
862 // Being so, also fetch openflowPort provided via ConfigProperties.
863 controllersStr.add(OPENFLOW_CONNECTION_PROTOCOL
864 + ":" + controllerIpStr + ":" + getControllerOFPort());
866 // Check if ovsdb node has manager entries
867 OvsdbNodeAugmentation ovsdbNodeAugmentation = extractOvsdbNode(node);
868 if (ovsdbNodeAugmentation != null) {
869 List<ManagerEntry> managerEntries = ovsdbNodeAugmentation.getManagerEntry();
870 if (managerEntries != null && !managerEntries.isEmpty()) {
871 for (ManagerEntry managerEntry : managerEntries) {
872 if (managerEntry == null || managerEntry.getTarget() == null) {
875 String managerStr = managerEntry.getTarget().getValue().toLowerCase(Locale.ROOT);
876 int firstColonIdx = managerStr.indexOf(':');
877 int lastColonIdx = managerStr.lastIndexOf(':');
878 if (lastColonIdx <= firstColonIdx) {
881 controllerIpStr = managerStr.substring(firstColonIdx + 1, lastColonIdx);
882 if (managerStr.startsWith(("tcp"))) {
883 controllersStr.add(OPENFLOW_CONNECTION_PROTOCOL + ":" + controllerIpStr + ":"
884 + getControllerOFPort());
885 } else if (managerStr.startsWith(("ssl"))) {
886 controllersStr.add(OPENFLOW_SECURE_PROTOCOL + ":" + controllerIpStr + ":"
887 + getControllerOFPort());
888 } else if (managerStr.startsWith(("ptcp"))) {
889 ConnectionInfo connectionInfo = ovsdbNodeAugmentation.getConnectionInfo();
890 if (connectionInfo != null && connectionInfo.getLocalIp() != null) {
891 controllerIpStr = connectionInfo.getLocalIp().stringValue();
892 controllersStr.add(OPENFLOW_CONNECTION_PROTOCOL
893 + ":" + controllerIpStr + ":" + OPENFLOW_PORT);
895 LOG.warn("Ovsdb Node does not contain connection info: {}", node);
897 } else if (managerStr.startsWith(("pssl"))) {
898 ConnectionInfo connectionInfo = ovsdbNodeAugmentation.getConnectionInfo();
899 if (connectionInfo != null && connectionInfo.getLocalIp() != null) {
900 controllerIpStr = connectionInfo.getLocalIp().stringValue();
901 controllersStr.add(OPENFLOW_SECURE_PROTOCOL
902 + ":" + controllerIpStr + ":" + OPENFLOW_PORT);
904 LOG.warn("Ovsdb Node does not contain connection info: {}", node);
907 LOG.trace("Skipping manager entry {} for node {}",
908 managerEntry.getTarget(), node.getNodeId().getValue());
912 LOG.warn("Ovsdb Node does not contain manager entries : {}", node);
917 if (controllersStr.isEmpty()) {
918 LOG.warn("Failed to determine OpenFlow controller ip address");
919 } else if (LOG.isDebugEnabled()) {
920 LOG.debug("Found {} OpenFlow Controller(s) :{}", controllersStr.size(),
921 controllersStr.stream().collect(Collectors.joining(" ")));
923 return controllersStr;
926 public long getDataPathId(Node node) {
928 String datapathId = getDatapathId(node);
929 if (datapathId != null) {
930 dpid = new BigInteger(datapathId.replaceAll(":", ""), 16).longValue();
935 public String getDataPathIdStr(final Node node) {
937 long dpId = getDataPathId(node);
939 return String.valueOf(dpId);
946 public String getDatapathId(Node node) {
947 OvsdbBridgeAugmentation ovsdbBridgeAugmentation = node.augmentation(OvsdbBridgeAugmentation.class);
948 return getDatapathId(ovsdbBridgeAugmentation);
951 public String getDatapathId(OvsdbBridgeAugmentation ovsdbBridgeAugmentation) {
952 String datapathId = null;
953 if (ovsdbBridgeAugmentation != null && ovsdbBridgeAugmentation.getDatapathId() != null) {
954 datapathId = ovsdbBridgeAugmentation.getDatapathId().getValue();
959 public String extractBridgeName(Node node) {
960 return node.augmentation(OvsdbBridgeAugmentation.class).getBridgeName().getValue();
963 public boolean isBridgeOnOvsdbNode(Node ovsdbNode, String bridgeName) {
964 boolean found = false;
965 OvsdbNodeAugmentation ovsdbNodeAugmentation = extractNodeAugmentation(ovsdbNode);
966 if (ovsdbNodeAugmentation != null) {
967 List<ManagedNodeEntry> managedNodes = ovsdbNodeAugmentation.getManagedNodeEntry();
968 if (managedNodes != null) {
969 for (ManagedNodeEntry managedNode : managedNodes) {
970 InstanceIdentifier<?> bridgeIid = managedNode.getBridgeRef().getValue();
971 if (bridgeIid.toString().contains(bridgeName)) {
981 public OvsdbBridgeAugmentation getBridgeFromConfig(Node node, String bridge) {
982 OvsdbBridgeAugmentation ovsdbBridgeAugmentation = null;
983 InstanceIdentifier<Node> bridgeIid =
984 createInstanceIdentifier(node.key(), bridge);
985 Node bridgeNode = mdsalUtils.read(LogicalDatastoreType.CONFIGURATION, bridgeIid);
986 if (bridgeNode != null) {
987 ovsdbBridgeAugmentation = bridgeNode.augmentation(OvsdbBridgeAugmentation.class);
989 return ovsdbBridgeAugmentation;
992 private void setManagedByForBridge(OvsdbBridgeAugmentationBuilder ovsdbBridgeAugmentationBuilder,
993 NodeKey ovsdbNodeKey) {
994 InstanceIdentifier<Node> connectionNodePath = createInstanceIdentifier(ovsdbNodeKey.getNodeId());
995 ovsdbBridgeAugmentationBuilder.setManagedBy(new OvsdbNodeRef(connectionNodePath));
998 public boolean isOvsdbNodeDpdk(Node ovsdbNode) {
999 boolean found = false;
1000 OvsdbNodeAugmentation ovsdbNodeAugmentation = extractNodeAugmentation(ovsdbNode);
1001 if (ovsdbNodeAugmentation != null) {
1002 List<InterfaceTypeEntry> ifTypes = ovsdbNodeAugmentation.getInterfaceTypeEntry();
1003 if (ifTypes != null) {
1004 for (InterfaceTypeEntry ifType : ifTypes) {
1005 if (ifType.getInterfaceType().equals(InterfaceTypeDpdk.class)) {
1015 private List<ControllerEntry> createControllerEntries(List<String> controllersStr,
1016 Long maxBackoff, Long inactivityProbe) {
1017 List<ControllerEntry> controllerEntries = new ArrayList<>();
1018 if (controllersStr != null) {
1019 for (String controllerStr : controllersStr) {
1020 ControllerEntryBuilder controllerEntryBuilder = new ControllerEntryBuilder();
1021 controllerEntryBuilder.setTarget(new Uri(controllerStr));
1022 if (maxBackoff != null) {
1023 controllerEntryBuilder.setMaxBackoff(maxBackoff);
1025 if (inactivityProbe != null) {
1026 controllerEntryBuilder.setInactivityProbe(inactivityProbe);
1028 controllerEntries.add(controllerEntryBuilder.build());
1031 return controllerEntries;
1034 public OvsdbTerminationPointAugmentation extractTerminationPointAugmentation(Node bridgeNode, String portName) {
1035 if (bridgeNode.augmentation(OvsdbBridgeAugmentation.class) != null) {
1036 List<OvsdbTerminationPointAugmentation> tpAugmentations = extractTerminationPointAugmentations(bridgeNode);
1037 for (OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation : tpAugmentations) {
1038 if (ovsdbTerminationPointAugmentation.getName().equals(portName)) {
1039 return ovsdbTerminationPointAugmentation;
1046 public List<OvsdbTerminationPointAugmentation> extractTerminationPointAugmentations(Node node) {
1047 List<OvsdbTerminationPointAugmentation> tpAugmentations = new ArrayList<>();
1049 LOG.error("extractTerminationPointAugmentations: Node value is null");
1050 return Collections.emptyList();
1052 List<TerminationPoint> terminationPoints = node.getTerminationPoint();
1053 if (terminationPoints != null && !terminationPoints.isEmpty()) {
1054 for (TerminationPoint tp : terminationPoints) {
1055 OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation =
1056 tp.augmentation(OvsdbTerminationPointAugmentation.class);
1057 if (ovsdbTerminationPointAugmentation != null) {
1058 tpAugmentations.add(ovsdbTerminationPointAugmentation);
1062 return tpAugmentations;
1066 * Extract the <code>OvsdbTerminationPointAugmentation</code> for the particular <code>node</code> identified by
1067 * <code>portName</code>.
1069 public OvsdbTerminationPointAugmentation getTerminationPointOfBridge(Node node, String portName) {
1070 OvsdbTerminationPointAugmentation tpAugmentation = extractTerminationPointAugmentation(node,portName);
1071 if (tpAugmentation == null) {
1072 List<OvsdbTerminationPointAugmentation> tpAugmentations = readTerminationPointAugmentations(node);
1073 if (tpAugmentations != null) {
1074 for (OvsdbTerminationPointAugmentation ovsdbTpAugmentation : tpAugmentations) {
1075 if (ovsdbTpAugmentation.getName().equals(portName)) {
1076 return ovsdbTpAugmentation;
1081 return tpAugmentation;
1085 * Read the list of <code>OvsdbTerminationPointAugmentation</code> for the particular <code>node</code>.
1087 public List<OvsdbTerminationPointAugmentation> readTerminationPointAugmentations(Node node) {
1089 LOG.error("readTerminationPointAugmentations: Node value is null");
1090 return Collections.emptyList();
1092 Node operNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, InstanceIdentifier
1093 .create(NetworkTopology.class)
1094 .child(Topology.class, new TopologyKey(OVSDB_TOPOLOGY_ID))
1095 .child(Node.class, new NodeKey(node.getNodeId())));
1096 if (operNode != null) {
1097 return extractTerminationPointAugmentations(operNode);
1099 return new ArrayList<>();
1103 * Get all OVSDB nodes from topology.
1104 * @return a list of nodes or null if the topology could not found
1106 public List<Node> getOvsdbNodes() {
1107 InstanceIdentifier<Topology> inst = InstanceIdentifier.create(NetworkTopology.class).child(Topology.class,
1108 new TopologyKey(OVSDB_TOPOLOGY_ID));
1109 Topology topology = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, inst);
1110 return topology != null ? topology.getNode() : null;
1114 * Get OpenvSwitch other-config by key.
1115 * @param node OVSDB node
1116 * @param key key to extract from other-config
1117 * @return the value for key or null if key not found
1119 public String getOpenvswitchOtherConfig(Node node, String key) {
1120 OvsdbNodeAugmentation ovsdbNode = node.augmentation(OvsdbNodeAugmentation.class);
1121 if (ovsdbNode == null) {
1122 Node nodeFromReadOvsdbNode = readOvsdbNode(node);
1123 if (nodeFromReadOvsdbNode != null) {
1124 ovsdbNode = nodeFromReadOvsdbNode.augmentation(OvsdbNodeAugmentation.class);
1128 if (ovsdbNode != null && ovsdbNode.getOpenvswitchOtherConfigs() != null) {
1129 for (OpenvswitchOtherConfigs openvswitchOtherConfigs : ovsdbNode.getOpenvswitchOtherConfigs()) {
1130 if (openvswitchOtherConfigs.getOtherConfigKey().equals(key)) {
1131 return openvswitchOtherConfigs.getOtherConfigValue();
1139 public static TerminationPoint getTerminationPointByExternalId(final Node bridgeNode, final String interfaceName) {
1140 if (bridgeNode.getTerminationPoint() != null) {
1141 for (TerminationPoint tp : bridgeNode.getTerminationPoint()) {
1142 OvsdbTerminationPointAugmentation ovsdbTp = tp.augmentation(OvsdbTerminationPointAugmentation.class);
1143 String externalIdValue = getExternalInterfaceIdValue(ovsdbTp);
1144 if (externalIdValue != null && externalIdValue.equals(interfaceName)) {
1145 LOG.debug("Found matching termination point with iface-id {} on bridgeNode {}, returning tp {}",
1146 interfaceName, bridgeNode, tp);
1154 // This utility shouldn't be called often, as it reads all OVSDB nodes each time - not good for scale
1155 public Node getNodeByTerminationPointExternalId(final String interfaceName) {
1156 List<Node> nodes = getOvsdbNodes();
1157 if (nodes != null) {
1158 for (Node node : nodes) {
1159 TerminationPoint tp = getTerminationPointByExternalId(node, interfaceName);
1168 public static String getExternalInterfaceIdValue(final OvsdbTerminationPointAugmentation ovsdbTp) {
1169 if (ovsdbTp != null) {
1170 List<InterfaceExternalIds> ifaceExtIds = ovsdbTp.getInterfaceExternalIds();
1171 if (ifaceExtIds != null) {
1172 for (InterfaceExternalIds entry : ifaceExtIds) {
1173 if (entry.getExternalIdKey().equals(EXTERNAL_INTERFACE_ID_KEY)) {
1174 return entry.getExternalIdValue();
1182 public String getDatapathIdFromNodeInstanceId(InstanceIdentifier<Node> nodeInstanceId) {
1183 Node node = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, nodeInstanceId);
1184 String dpId = node != null ? getDataPathIdStr(node) : null;
1191 public static boolean compareDbVersionToMinVersion(final String dbVersion, final String minVersion) {
1192 final Matcher dbVersionMatcher = PATTERN.matcher(dbVersion);
1193 final Matcher minVersionMatcher = PATTERN.matcher(minVersion);
1194 LOG.debug("dbVersion {}, minVersion {}", dbVersion, minVersion);
1195 if (!dbVersionMatcher.find()) {
1196 LOG.error("Invalid DB version format {}", dbVersion);
1199 if (!minVersionMatcher.find()) {
1200 LOG.error("Invalid Min DB version format {}", minVersion);
1204 if (dbVersion != null && !dbVersion.isEmpty() && minVersion != null && !minVersion.isEmpty()) {
1205 final int dbVersionMatch1 = Integer.parseInt(dbVersionMatcher.group(1));
1206 final int dbVersionMatch2 = Integer.parseInt(dbVersionMatcher.group(2));
1207 final int dbVersionMatch3 = Integer.parseInt(dbVersionMatcher.group(3));
1208 final int minVersionMatch1 = Integer.parseInt(minVersionMatcher.group(1));
1209 final int minVersionMatch2 = Integer.parseInt(minVersionMatcher.group(2));
1210 final int minVersionMatch3 = Integer.parseInt(minVersionMatcher.group(3));
1211 if (dbVersionMatch1 == minVersionMatch1 && dbVersionMatch2 == minVersionMatch2
1212 && dbVersionMatch3 == minVersionMatch3) {
1216 if (dbVersionMatch1 > minVersionMatch1) {
1220 if (dbVersionMatch1 < minVersionMatch1) {
1224 // major version is equal
1225 if (dbVersionMatch2 > minVersionMatch2) {
1229 if (dbVersionMatch2 < minVersionMatch2) {
1233 if (dbVersionMatch3 > minVersionMatch3) {