2 * Copyright (c) 2015 - 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
9 package org.opendaylight.ovsdb.utils.southbound.utils;
11 import java.math.BigInteger;
12 import java.net.Inet4Address;
13 import java.net.Inet6Address;
14 import java.net.InetAddress;
15 import java.net.NetworkInterface;
16 import java.net.UnknownHostException;
17 import java.security.InvalidParameterException;
18 import java.util.ArrayList;
19 import java.util.Collections;
20 import java.util.Enumeration;
21 import java.util.HashMap;
22 import java.util.List;
25 import java.util.regex.Matcher;
26 import java.util.regex.Pattern;
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 import com.google.common.collect.ImmutableBiMap;
111 public class SouthboundUtils {
112 private static final Logger LOG = LoggerFactory.getLogger(SouthboundUtils.class);
113 private static final int OVSDB_UPDATE_TIMEOUT = 1000;
114 public static final TopologyId OVSDB_TOPOLOGY_ID = new TopologyId(new Uri("ovsdb:1"));
115 private final MdsalUtils mdsalUtils;
116 public static final String OPENFLOW_CONNECTION_PROTOCOL = "tcp";
117 public static short OPENFLOW_PORT = 6653;
118 public static final String OVSDB_URI_PREFIX = "ovsdb";
119 public static final String BRIDGE_URI_PREFIX = "bridge";
120 private static final String DISABLE_IN_BAND = "disable-in-band";
121 private static final String PATCH_PORT_TYPE = "patch";
122 // External ID key used for mapping between an OVSDB port and an interface name
123 private static final String EXTERNAL_INTERFACE_ID_KEY = "iface-id";
125 private static final String FORMAT = "(\\d+)\\.(\\d+)\\.(\\d+)";
126 private static final Pattern PATTERN = Pattern.compile(FORMAT);
129 public SouthboundUtils(MdsalUtils mdsalUtils) {
130 this.mdsalUtils = mdsalUtils;
133 public static final ImmutableBiMap<String, Class<? extends InterfaceTypeBase>> OVSDB_INTERFACE_TYPE_MAP
134 = new ImmutableBiMap.Builder<String, Class<? extends InterfaceTypeBase>>()
135 .put("internal", InterfaceTypeInternal.class)
136 .put("vxlan", InterfaceTypeVxlan.class)
137 .put("vxlan-gpe", InterfaceTypeVxlanGpe.class)
138 .put("patch", InterfaceTypePatch.class)
139 .put("system", InterfaceTypeSystem.class)
140 .put("tap", InterfaceTypeTap.class)
141 .put("geneve", InterfaceTypeGeneve.class)
142 .put("gre", InterfaceTypeGre.class)
143 .put("ipsec_gre", InterfaceTypeIpsecGre.class)
144 .put("gre64", InterfaceTypeGre64.class)
145 .put("ipsec_gre64", InterfaceTypeIpsecGre64.class)
146 .put("lisp", InterfaceTypeLisp.class)
147 .put("dpdk", InterfaceTypeDpdk.class)
148 .put("dpdkr", InterfaceTypeDpdkr.class)
149 .put("dpdkvhost", InterfaceTypeDpdkvhost.class)
150 .put("dpdkvhostuser", InterfaceTypeDpdkvhostuser.class)
151 .put("dpdkvhostuserclient", InterfaceTypeDpdkvhostuserclient.class)
154 public static final ImmutableBiMap<Class<? extends OvsdbBridgeProtocolBase>,String> OVSDB_PROTOCOL_MAP
155 = new ImmutableBiMap.Builder<Class<? extends OvsdbBridgeProtocolBase>,String>()
156 .put(OvsdbBridgeProtocolOpenflow10.class,"OpenFlow10")
157 .put(OvsdbBridgeProtocolOpenflow11.class,"OpenFlow11")
158 .put(OvsdbBridgeProtocolOpenflow12.class,"OpenFlow12")
159 .put(OvsdbBridgeProtocolOpenflow13.class,"OpenFlow13")
160 .put(OvsdbBridgeProtocolOpenflow14.class,"OpenFlow14")
161 .put(OvsdbBridgeProtocolOpenflow15.class,"OpenFlow15")
164 private static final ImmutableBiMap<Class<? extends OvsdbFailModeBase>,String> OVSDB_FAIL_MODE_MAP
165 = new ImmutableBiMap.Builder<Class<? extends OvsdbFailModeBase>,String>()
166 .put(OvsdbFailModeStandalone.class,"standalone")
167 .put(OvsdbFailModeSecure.class,"secure")
170 public static NodeId createNodeId(IpAddress ip, PortNumber port) {
171 String uriString = OVSDB_URI_PREFIX + "://"
172 + String.valueOf(ip.getValue()) + ":" + port.getValue();
173 Uri uri = new Uri(uriString);
174 return new NodeId(uri);
177 public static Node createNode(ConnectionInfo key) {
178 NodeBuilder nodeBuilder = new NodeBuilder();
179 nodeBuilder.setNodeId(createNodeId(key.getRemoteIp(), key.getRemotePort()));
180 nodeBuilder.addAugmentation(OvsdbNodeAugmentation.class, createOvsdbAugmentation(key));
181 return nodeBuilder.build();
184 public static OvsdbNodeAugmentation createOvsdbAugmentation(ConnectionInfo key) {
185 OvsdbNodeAugmentationBuilder ovsdbNodeBuilder = new OvsdbNodeAugmentationBuilder();
186 ovsdbNodeBuilder.setConnectionInfo(key);
187 return ovsdbNodeBuilder.build();
190 public static InstanceIdentifier<Node> createInstanceIdentifier(NodeId nodeId) {
191 return InstanceIdentifier
192 .create(NetworkTopology.class)
193 .child(Topology.class, new TopologyKey(OVSDB_TOPOLOGY_ID))
194 .child(Node.class,new NodeKey(nodeId));
197 public static InstanceIdentifier<Node> createInstanceIdentifier(NodeKey ovsdbNodeKey, String bridgeName) {
198 return createInstanceIdentifier(createManagedNodeId(ovsdbNodeKey.getNodeId(), bridgeName));
201 public static NodeId createManagedNodeId(NodeId ovsdbNodeId, String bridgeName) {
202 return new NodeId(ovsdbNodeId.getValue()
203 + "/" + BRIDGE_URI_PREFIX + "/" + bridgeName);
206 public static InstanceIdentifier<Node> createInstanceIdentifier(ConnectionInfo key) {
207 return createInstanceIdentifier(key.getRemoteIp(), key.getRemotePort());
210 public static InstanceIdentifier<Node> createInstanceIdentifier(IpAddress ip, PortNumber port) {
211 InstanceIdentifier<Node> path = InstanceIdentifier
212 .create(NetworkTopology.class)
213 .child(Topology.class, new TopologyKey(OVSDB_TOPOLOGY_ID))
214 .child(Node.class,createNodeKey(ip,port));
215 LOG.debug("Created ovsdb path: {}",path);
219 public static InstanceIdentifier<Node> createInstanceIdentifier(ConnectionInfo key,OvsdbBridgeName bridgeName) {
220 return createInstanceIdentifier(createManagedNodeId(key, bridgeName));
223 public static InstanceIdentifier<Node> createInstanceIdentifier(ConnectionInfo key, String bridgeName) {
224 return createInstanceIdentifier(key, new OvsdbBridgeName(bridgeName));
227 public InstanceIdentifier<TerminationPoint> createTerminationPointInstanceIdentifier(Node node, String portName){
229 InstanceIdentifier<TerminationPoint> terminationPointPath = InstanceIdentifier
230 .create(NetworkTopology.class)
231 .child(Topology.class, new TopologyKey(OVSDB_TOPOLOGY_ID))
232 .child(Node.class,node.getKey())
233 .child(TerminationPoint.class, new TerminationPointKey(new TpId(portName)));
235 LOG.debug("Termination point InstanceIdentifier generated : {}",terminationPointPath);
236 return terminationPointPath;
239 public static NodeKey createNodeKey(IpAddress ip, PortNumber port) {
240 return new NodeKey(createNodeId(ip, port));
243 public static NodeId createManagedNodeId(ConnectionInfo key, OvsdbBridgeName bridgeName) {
244 return createManagedNodeId(key.getRemoteIp(), key.getRemotePort(), bridgeName);
247 public static NodeId createManagedNodeId(IpAddress ip, PortNumber port, OvsdbBridgeName bridgeName) {
248 return new NodeId(createNodeId(ip,port).getValue()
249 + "/" + BRIDGE_URI_PREFIX + "/" + bridgeName.getValue());
252 public static NodeId createManagedNodeId(InstanceIdentifier<Node> iid) {
253 NodeKey nodeKey = iid.firstKeyOf(Node.class);
254 return nodeKey.getNodeId();
257 public ConnectionInfo getConnectionInfo(Node ovsdbNode) {
258 ConnectionInfo connectionInfo = null;
259 OvsdbNodeAugmentation ovsdbNodeAugmentation = extractOvsdbNode(ovsdbNode);
260 if (ovsdbNodeAugmentation != null) {
261 connectionInfo = ovsdbNodeAugmentation.getConnectionInfo();
263 return connectionInfo;
266 public OvsdbNodeAugmentation extractOvsdbNode(Node node) {
267 return node.getAugmentation(OvsdbNodeAugmentation.class);
270 public static IpAddress createIpAddress(InetAddress address) {
272 if (address instanceof Inet4Address) {
273 ip = createIpAddress((Inet4Address)address);
274 } else if (address instanceof Inet6Address) {
275 ip = createIpAddress((Inet6Address)address);
280 public static IpAddress createIpAddress(Inet4Address address) {
281 return IetfInetUtil.INSTANCE.ipAddressFor(address);
284 public static IpAddress createIpAddress(Inet6Address address) {
285 Ipv6Address ipv6 = new Ipv6Address(address.getHostAddress());
286 return new IpAddress(ipv6);
289 public static ConnectionInfo getConnectionInfo(final String addressStr, final String portStr) {
290 InetAddress inetAddress = null;
292 inetAddress = InetAddress.getByName(addressStr);
293 } catch (UnknownHostException e) {
294 LOG.warn("Could not allocate InetAddress", e);
297 IpAddress address = createIpAddress(inetAddress);
298 PortNumber port = new PortNumber(Integer.parseInt(portStr));
300 LOG.info("connectionInfo: {}", new ConnectionInfoBuilder()
301 .setRemoteIp(address)
304 return new ConnectionInfoBuilder()
305 .setRemoteIp(address)
310 public static String connectionInfoToString(final ConnectionInfo connectionInfo) {
311 return String.valueOf(
312 connectionInfo.getRemoteIp().getValue()) + ":" + connectionInfo.getRemotePort().getValue();
315 public boolean addOvsdbNode(final ConnectionInfo connectionInfo) {
316 return addOvsdbNode(connectionInfo, OVSDB_UPDATE_TIMEOUT);
319 public boolean addOvsdbNode(final ConnectionInfo connectionInfo, long timeout) {
320 boolean result = mdsalUtils.put(LogicalDatastoreType.CONFIGURATION,
321 createInstanceIdentifier(connectionInfo),
322 createNode(connectionInfo));
325 Thread.sleep(timeout);
326 } catch (InterruptedException e) {
327 LOG.warn("Interrupted while waiting after adding OVSDB node {}",
328 connectionInfoToString(connectionInfo), e);
334 public Node getOvsdbNode(final ConnectionInfo connectionInfo) {
335 return mdsalUtils.read(LogicalDatastoreType.OPERATIONAL,
336 createInstanceIdentifier(connectionInfo));
339 public boolean deleteOvsdbNode(final ConnectionInfo connectionInfo) {
340 return deleteOvsdbNode(connectionInfo, OVSDB_UPDATE_TIMEOUT);
343 public boolean deleteOvsdbNode(final ConnectionInfo connectionInfo, long timeout) {
344 boolean result = mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION,
345 createInstanceIdentifier(connectionInfo));
348 Thread.sleep(timeout);
349 } catch (InterruptedException e) {
350 LOG.warn("Interrupted while waiting after deleting OVSDB node {}",
351 connectionInfoToString(connectionInfo), e);
357 public Node connectOvsdbNode(final ConnectionInfo connectionInfo) {
358 return connectOvsdbNode(connectionInfo, OVSDB_UPDATE_TIMEOUT);
361 public Node connectOvsdbNode(final ConnectionInfo connectionInfo, long timeout) {
362 addOvsdbNode(connectionInfo, timeout);
363 Node node = getOvsdbNode(connectionInfo);
364 LOG.info("Connected to {}", connectionInfoToString(connectionInfo));
368 public boolean disconnectOvsdbNode(final ConnectionInfo connectionInfo) {
369 return disconnectOvsdbNode(connectionInfo, OVSDB_UPDATE_TIMEOUT);
372 public boolean disconnectOvsdbNode(final ConnectionInfo connectionInfo, long timeout) {
373 deleteOvsdbNode(connectionInfo, timeout);
374 LOG.info("Disconnected from {}", connectionInfoToString(connectionInfo));
378 public List<ControllerEntry> createControllerEntry(String controllerTarget) {
379 List<ControllerEntry> controllerEntriesList = new ArrayList<>();
380 controllerEntriesList.add(new ControllerEntryBuilder()
381 .setTarget(new Uri(controllerTarget))
383 return controllerEntriesList;
387 * Extract the <code>store</code> type data store contents for the particular bridge identified by
388 * <code>bridgeName</code>.
390 * @param connectionInfo address for the node
391 * @param bridgeName name of the bridge
392 * @param store defined by the <code>LogicalDatastoreType</code> enumeration
393 * @return <code>store</code> type data store contents
395 public OvsdbBridgeAugmentation getBridge(ConnectionInfo connectionInfo, String bridgeName,
396 LogicalDatastoreType store) {
397 OvsdbBridgeAugmentation ovsdbBridgeAugmentation = null;
398 Node bridgeNode = getBridgeNode(connectionInfo, bridgeName, store);
399 if (bridgeNode != null) {
400 ovsdbBridgeAugmentation = bridgeNode.getAugmentation(OvsdbBridgeAugmentation.class);
402 return ovsdbBridgeAugmentation;
406 * extract the <code>LogicalDataStoreType.OPERATIONAL</code> type data store contents for the particular bridge
407 * identified by <code>bridgeName</code>
409 * @param connectionInfo address for the node
410 * @param bridgeName name of the bridge
411 * @see <code>NetvirtIT.getBridge(ConnectionInfo, String, LogicalDatastoreType)</code>
412 * @return <code>LogicalDatastoreType.OPERATIONAL</code> type data store contents
414 public OvsdbBridgeAugmentation getBridge(ConnectionInfo connectionInfo, String bridgeName) {
415 return getBridge(connectionInfo, bridgeName, LogicalDatastoreType.OPERATIONAL);
419 * Extract the node contents from <code>store</code> type data store for the
420 * bridge identified by <code>bridgeName</code>.
422 * @param connectionInfo address for the node
423 * @param bridgeName name of the bridge
424 * @param store defined by the <code>LogicalDatastoreType</code> enumeration
425 * @return <code>store</code> type data store contents
427 public Node getBridgeNode(ConnectionInfo connectionInfo, String bridgeName, LogicalDatastoreType store) {
428 InstanceIdentifier<Node> bridgeIid = createInstanceIdentifier(connectionInfo, new OvsdbBridgeName(bridgeName));
429 return mdsalUtils.read(store, bridgeIid);
432 public Node getBridgeNode(Node node, String bridgeName) {
433 OvsdbBridgeAugmentation bridge = extractBridgeAugmentation(node);
434 if (bridge != null && bridge.getBridgeName().getValue().equals(bridgeName)) {
437 return readBridgeNode(node, bridgeName);
441 public Node readBridgeNode(Node node, String name) {
442 Node ovsdbNode = node;
443 if (extractNodeAugmentation(ovsdbNode) == null) {
444 ovsdbNode = readOvsdbNode(node);
445 if (ovsdbNode == null) {
449 Node bridgeNode = null;
450 ConnectionInfo connectionInfo = getConnectionInfo(ovsdbNode);
451 if (connectionInfo != null) {
452 InstanceIdentifier<Node> bridgeIid =
453 createInstanceIdentifier(node.getKey(), name);
454 bridgeNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, bridgeIid);
459 public OvsdbNodeAugmentation extractNodeAugmentation(Node node) {
460 return node.getAugmentation(OvsdbNodeAugmentation.class);
463 public OvsdbBridgeAugmentation extractBridgeAugmentation(Node node) {
467 return node.getAugmentation(OvsdbBridgeAugmentation.class);
470 public Node readOvsdbNode(Node bridgeNode) {
471 Node ovsdbNode = null;
472 OvsdbBridgeAugmentation bridgeAugmentation = extractBridgeAugmentation(bridgeNode);
473 if (bridgeAugmentation != null) {
474 InstanceIdentifier<Node> ovsdbNodeIid =
475 (InstanceIdentifier<Node>) bridgeAugmentation.getManagedBy().getValue();
476 ovsdbNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, ovsdbNodeIid);
478 LOG.debug("readOvsdbNode: Provided node is not a bridge node : {}",bridgeNode);
483 public boolean deleteBridge(final ConnectionInfo connectionInfo, final String bridgeName) {
484 return deleteBridge(connectionInfo, bridgeName, OVSDB_UPDATE_TIMEOUT);
487 public boolean deleteBridge(final ConnectionInfo connectionInfo, final String bridgeName, long timeout) {
488 boolean result = mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION,
489 createInstanceIdentifier(connectionInfo, new OvsdbBridgeName(bridgeName)));
492 Thread.sleep(timeout);
493 } catch (InterruptedException e) {
494 LOG.warn("Interrupted while waiting after deleting bridge {}", bridgeName, e);
500 public List<ProtocolEntry> createMdsalProtocols() {
501 List<ProtocolEntry> protocolList = new ArrayList<>();
502 ImmutableBiMap<String, Class<? extends OvsdbBridgeProtocolBase>> mapper =
503 OVSDB_PROTOCOL_MAP.inverse();
504 protocolList.add(new ProtocolEntryBuilder().setProtocol(mapper.get("OpenFlow13")).build());
508 public boolean addBridge(final ConnectionInfo connectionInfo, InstanceIdentifier<Node> bridgeIid,
509 final String bridgeName, NodeId bridgeNodeId, final boolean setProtocolEntries,
510 final Class<? extends OvsdbFailModeBase> failMode, final boolean setManagedBy,
511 final Class<? extends DatapathTypeBase> dpType,
512 final List<BridgeExternalIds> externalIds,
513 final List<ControllerEntry> controllerEntries,
514 final List<BridgeOtherConfigs> otherConfigs,
515 final String dpid) throws InterruptedException {
516 return addBridge(connectionInfo, bridgeIid, bridgeName, bridgeNodeId, setProtocolEntries, failMode,
517 setManagedBy, dpType, externalIds, controllerEntries, otherConfigs, dpid);
521 * base method for adding test bridges. Other helper methods used to create bridges should utilize this method.
523 * @param connectionInfo
524 * @param bridgeIid if passed null, one is created
525 * @param bridgeName cannot be null
526 * @param bridgeNodeId if passed null, one is created based on <code>bridgeIid</code>
527 * @param setProtocolEntries toggles whether default protocol entries are set for the bridge
528 * @param failMode toggles whether default fail mode is set for the bridge
529 * @param setManagedBy toggles whether to setManagedBy for the bridge
530 * @param dpType if passed null, this parameter is ignored
531 * @param externalIds if passed null, this parameter is ignored
532 * @param otherConfig if passed null, this parameter is ignored
533 * @return success of bridge addition
534 * @throws InterruptedException
536 public boolean addBridge(final ConnectionInfo connectionInfo, InstanceIdentifier<Node> bridgeIid,
537 final String bridgeName, NodeId bridgeNodeId, final boolean setProtocolEntries,
538 final Class<? extends OvsdbFailModeBase> failMode, final boolean setManagedBy,
539 final Class<? extends DatapathTypeBase> dpType,
540 final List<BridgeExternalIds> externalIds,
541 final List<ControllerEntry> controllerEntries,
542 final List<BridgeOtherConfigs> otherConfigs,
543 final String dpid, long timeout) throws InterruptedException {
545 NodeBuilder bridgeNodeBuilder = new NodeBuilder();
546 if (bridgeIid == null) {
547 bridgeIid = createInstanceIdentifier(connectionInfo, new OvsdbBridgeName(bridgeName));
549 if (bridgeNodeId == null) {
550 bridgeNodeId = createManagedNodeId(bridgeIid);
552 bridgeNodeBuilder.setNodeId(bridgeNodeId);
553 OvsdbBridgeAugmentationBuilder ovsdbBridgeAugmentationBuilder = new OvsdbBridgeAugmentationBuilder();
554 ovsdbBridgeAugmentationBuilder.setBridgeName(new OvsdbBridgeName(bridgeName));
555 if (setProtocolEntries) {
556 ovsdbBridgeAugmentationBuilder.setProtocolEntry(createMdsalProtocols());
558 if (failMode != null) {
559 ovsdbBridgeAugmentationBuilder.setFailMode(failMode);
562 setManagedBy(ovsdbBridgeAugmentationBuilder, connectionInfo);
564 if (dpType != null) {
565 ovsdbBridgeAugmentationBuilder.setDatapathType(dpType);
567 if (externalIds != null) {
568 ovsdbBridgeAugmentationBuilder.setBridgeExternalIds(externalIds);
570 if (controllerEntries != null) {
571 ovsdbBridgeAugmentationBuilder.setControllerEntry(controllerEntries);
573 if (otherConfigs != null) {
574 ovsdbBridgeAugmentationBuilder.setBridgeOtherConfigs(otherConfigs);
576 if (dpid != null && !dpid.isEmpty()) {
577 DatapathId datapathId = new DatapathId(dpid);
578 ovsdbBridgeAugmentationBuilder.setDatapathId(datapathId);
580 bridgeNodeBuilder.addAugmentation(OvsdbBridgeAugmentation.class, ovsdbBridgeAugmentationBuilder.build());
581 LOG.debug("Built with the intent to store bridge data {}",
582 ovsdbBridgeAugmentationBuilder.toString());
583 boolean result = mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION,
584 bridgeIid, bridgeNodeBuilder.build());
586 Thread.sleep(OVSDB_UPDATE_TIMEOUT);
592 * Set the controllers of an existing bridge node
593 * @param ovsdbNode where the bridge is
594 * @param bridgeName Name of the bridge
595 * @param controllers controller strings
596 * @return success if the write to md-sal was successful
598 public boolean setBridgeController(Node ovsdbNode, String bridgeName, List<String> controllers) {
599 return setBridgeController(ovsdbNode, bridgeName, controllers, null, null);
602 * Set the controllers of an existing bridge node
603 * @param ovsdbNode where the bridge is
604 * @param bridgeName Name of the bridge
605 * @param controllers controller strings
606 * @param maxBackoff Max backoff in milliseconds
607 * @param inactivityProbe inactivity probe in milliseconds
608 * @return success if the write to md-sal was successful
610 public boolean setBridgeController(Node ovsdbNode, String bridgeName, List<String> controllers,
611 Long maxBackoff, Long inactivityProbe) {
612 LOG.debug("setBridgeController: ovsdbNode: {}, bridgeNode: {}, controller(s): {}",
613 ovsdbNode, bridgeName, controllers);
615 InstanceIdentifier<Node> bridgeNodeIid = createInstanceIdentifier(ovsdbNode.getKey(), bridgeName);
616 Node bridgeNode = mdsalUtils.read(LogicalDatastoreType.CONFIGURATION, bridgeNodeIid);
617 if (bridgeNode == null) {
618 LOG.info("setBridgeController could not find bridge in configuration {}", bridgeNodeIid);
622 OvsdbBridgeAugmentation bridgeAug = extractBridgeAugmentation(bridgeNode);
624 //Only add controller entries that do not already exist on this bridge
625 List<ControllerEntry> existingControllerEntries = bridgeAug.getControllerEntry();
626 List<ControllerEntry> newControllerEntries = new ArrayList<>();
627 if(existingControllerEntries != null) {
629 for (ControllerEntry newEntry : createControllerEntries(controllers, maxBackoff, inactivityProbe)) {
630 for (ControllerEntry existingEntry : existingControllerEntries) {
631 if (newEntry.getTarget().equals(existingEntry.getTarget())) {
632 continue NEW_ENTRY_LOOP;
635 newControllerEntries.add(newEntry);
638 newControllerEntries = createControllerEntries(controllers,maxBackoff, inactivityProbe);
641 if(newControllerEntries.isEmpty()) {
645 NodeBuilder nodeBuilder = new NodeBuilder(bridgeNode);
646 OvsdbBridgeAugmentationBuilder augBuilder = new OvsdbBridgeAugmentationBuilder(bridgeAug);
648 augBuilder.setControllerEntry(newControllerEntries);
649 nodeBuilder.addAugmentation(OvsdbBridgeAugmentation.class, augBuilder.build());
650 InstanceIdentifier<Node> bridgeIid = createInstanceIdentifier(ovsdbNode.getKey(), bridgeName);
651 return mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION, bridgeIid, nodeBuilder.build());
654 public boolean addBridge(Node ovsdbNode, String bridgeName, List<String> controllersStr,
655 final Class<? extends DatapathTypeBase> dpType, String mac) {
656 return addBridge(ovsdbNode, bridgeName, controllersStr, dpType, mac, null, null);
659 public boolean addBridge(Node ovsdbNode, String bridgeName, List<String> controllersStr,
660 final Class<? extends DatapathTypeBase> dpType, String mac,
661 Long maxBackoff, Long inactivityProbe) {
662 List<BridgeOtherConfigs> otherConfigs = new ArrayList<>();
664 BridgeOtherConfigsBuilder macOtherConfigBuilder = new BridgeOtherConfigsBuilder();
665 macOtherConfigBuilder.setBridgeOtherConfigKey("hwaddr");
666 macOtherConfigBuilder.setBridgeOtherConfigValue(mac);
667 otherConfigs.add(macOtherConfigBuilder.build());
670 return addBridge(ovsdbNode, bridgeName, controllersStr, dpType, otherConfigs, null, null);
673 public boolean addBridge(Node ovsdbNode, String bridgeName, List<String> controllersStr,
674 final Class<? extends DatapathTypeBase> dpType,
675 List<BridgeOtherConfigs> otherConfigs,
676 Long maxBackoff, Long inactivityProbe) {
679 LOG.info("addBridge: node: {}, bridgeName: {}, controller(s): {}", ovsdbNode, bridgeName, controllersStr);
680 ConnectionInfo connectionInfo = getConnectionInfo(ovsdbNode);
681 if (connectionInfo != null) {
682 NodeBuilder bridgeNodeBuilder = new NodeBuilder();
683 InstanceIdentifier<Node> bridgeIid = createInstanceIdentifier(ovsdbNode.getKey(), bridgeName);
684 NodeId bridgeNodeId = createManagedNodeId(bridgeIid);
685 bridgeNodeBuilder.setNodeId(bridgeNodeId);
686 OvsdbBridgeAugmentationBuilder ovsdbBridgeAugmentationBuilder = new OvsdbBridgeAugmentationBuilder();
687 ovsdbBridgeAugmentationBuilder.setControllerEntry(createControllerEntries(
688 controllersStr, maxBackoff, inactivityProbe));
689 ovsdbBridgeAugmentationBuilder.setBridgeName(new OvsdbBridgeName(bridgeName));
690 ovsdbBridgeAugmentationBuilder.setProtocolEntry(createMdsalProtocols());
691 ovsdbBridgeAugmentationBuilder.setFailMode( OVSDB_FAIL_MODE_MAP.inverse().get("secure"));
692 // TODO: Currently netvirt relies on this function to set disabled-in-band=true. However,
693 // TODO (cont): a better design would be to have netvirt pass that in. That way this function
694 // TODO (cont): can take a null otherConfigs to erase other_configs.
695 if (otherConfigs == null) {
696 otherConfigs = new ArrayList<>();
698 BridgeOtherConfigsBuilder bridgeOtherConfigsBuilder = new BridgeOtherConfigsBuilder();
699 bridgeOtherConfigsBuilder.setBridgeOtherConfigKey(DISABLE_IN_BAND);
700 bridgeOtherConfigsBuilder.setBridgeOtherConfigValue("true");
701 otherConfigs.add(bridgeOtherConfigsBuilder.build());
702 ovsdbBridgeAugmentationBuilder.setBridgeOtherConfigs(otherConfigs);
703 setManagedByForBridge(ovsdbBridgeAugmentationBuilder, ovsdbNode.getKey());
704 if (dpType != null) {
705 ovsdbBridgeAugmentationBuilder.setDatapathType(dpType);
707 if (isOvsdbNodeDpdk(ovsdbNode)) {
708 ovsdbBridgeAugmentationBuilder.setDatapathType(DatapathTypeNetdev.class);
710 bridgeNodeBuilder.addAugmentation(OvsdbBridgeAugmentation.class, ovsdbBridgeAugmentationBuilder.build());
712 Node node = bridgeNodeBuilder.build();
713 result = mdsalUtils.put(LogicalDatastoreType.CONFIGURATION, bridgeIid, node);
714 LOG.info("addBridge: result: {}", result);
716 throw new InvalidParameterException("Could not find ConnectionInfo");
722 private void setManagedBy(final OvsdbBridgeAugmentationBuilder ovsdbBridgeAugmentationBuilder,
723 final ConnectionInfo connectionInfo) {
724 InstanceIdentifier<Node> connectionNodePath = createInstanceIdentifier(connectionInfo);
725 ovsdbBridgeAugmentationBuilder.setManagedBy(new OvsdbNodeRef(connectionNodePath));
728 public boolean addTerminationPoint(
729 Node bridgeNode, String portName, String type, Map<String, String> options,
730 Map<String, String> externalIds) {
731 return addTerminationPoint(bridgeNode, portName, type, options, externalIds, null);
734 public boolean addTerminationPoint(
735 Node bridgeNode, String portName, String type, Map<String, String> options, Map<String, String> externalIds,
737 InstanceIdentifier<TerminationPoint> tpIid = createTerminationPointInstanceIdentifier(bridgeNode, portName);
738 OvsdbTerminationPointAugmentationBuilder tpAugmentationBuilder = new OvsdbTerminationPointAugmentationBuilder();
740 tpAugmentationBuilder.setName(portName);
741 tpAugmentationBuilder.setOfport(ofPort);
743 tpAugmentationBuilder.setInterfaceType(OVSDB_INTERFACE_TYPE_MAP.get(type));
746 if (options != null && options.size() > 0) {
747 List<Options> optionsList = new ArrayList<>();
748 for (Map.Entry<String, String> entry : options.entrySet()) {
749 OptionsBuilder optionsBuilder = new OptionsBuilder();
750 optionsBuilder.setKey(new OptionsKey(entry.getKey()));
751 optionsBuilder.setOption(entry.getKey());
752 optionsBuilder.setValue(entry.getValue());
753 optionsList.add(optionsBuilder.build());
755 tpAugmentationBuilder.setOptions(optionsList);
758 if (externalIds != null && externalIds.size() > 0) {
759 List<InterfaceExternalIds> externalIdsList = new ArrayList<>();
760 for (Map.Entry<String, String> entry : externalIds.entrySet()) {
761 InterfaceExternalIdsBuilder interfaceExternalIdsBuilder = new InterfaceExternalIdsBuilder();
762 interfaceExternalIdsBuilder.setKey(new InterfaceExternalIdsKey(entry.getKey()));
763 interfaceExternalIdsBuilder.setExternalIdKey(entry.getKey());
764 interfaceExternalIdsBuilder.setExternalIdValue(entry.getValue());
765 externalIdsList.add(interfaceExternalIdsBuilder.build());
767 tpAugmentationBuilder.setInterfaceExternalIds(externalIdsList);
770 TerminationPointBuilder tpBuilder = new TerminationPointBuilder();
771 tpBuilder.setKey(InstanceIdentifier.keyOf(tpIid));
772 tpBuilder.addAugmentation(OvsdbTerminationPointAugmentation.class, tpAugmentationBuilder.build());
773 /* TODO SB_MIGRATION should this be merge or mdsalUtils.put */
774 return mdsalUtils.put(LogicalDatastoreType.CONFIGURATION, tpIid, tpBuilder.build());
777 public Boolean addTerminationPoint(Node bridgeNode, String portName, String type) {
778 return addTerminationPoint(bridgeNode, portName, type, Collections.EMPTY_MAP, null);
781 public Boolean addTerminationPoint(Node bridgeNode, String bridgeName, String portName,
782 String type, Map<String, String> options) {
783 InstanceIdentifier<TerminationPoint> tpIid = createTerminationPointInstanceIdentifier(
784 bridgeNode, portName);
785 OvsdbTerminationPointAugmentationBuilder tpAugmentationBuilder = new OvsdbTerminationPointAugmentationBuilder();
787 tpAugmentationBuilder.setName(portName);
789 tpAugmentationBuilder.setInterfaceType(OVSDB_INTERFACE_TYPE_MAP.get(type));
792 List<Options> optionsList = new ArrayList<>();
793 for (Map.Entry<String, String> entry : options.entrySet()) {
794 OptionsBuilder optionsBuilder = new OptionsBuilder();
795 optionsBuilder.setKey(new OptionsKey(entry.getKey()));
796 optionsBuilder.setOption(entry.getKey());
797 optionsBuilder.setValue(entry.getValue());
798 optionsList.add(optionsBuilder.build());
800 tpAugmentationBuilder.setOptions(optionsList);
802 TerminationPointBuilder tpBuilder = new TerminationPointBuilder();
803 tpBuilder.setKey(InstanceIdentifier.keyOf(tpIid));
804 tpBuilder.addAugmentation(OvsdbTerminationPointAugmentation.class, tpAugmentationBuilder.build());
805 /* TODO SB_MIGRATION should this be merge or mdsalUtils.put */
806 return mdsalUtils.put(LogicalDatastoreType.CONFIGURATION, tpIid, tpBuilder.build());
809 public Boolean addTerminationPoint(Node bridgeNode, String bridgeName, String portName, String type) {
810 InstanceIdentifier<TerminationPoint> tpIid = createTerminationPointInstanceIdentifier(bridgeNode, portName);
811 OvsdbTerminationPointAugmentationBuilder tpAugmentationBuilder =
812 new OvsdbTerminationPointAugmentationBuilder();
814 tpAugmentationBuilder.setName(portName);
816 tpAugmentationBuilder.setInterfaceType(OVSDB_INTERFACE_TYPE_MAP.get(type));
818 TerminationPointBuilder tpBuilder = new TerminationPointBuilder();
819 tpBuilder.setKey(InstanceIdentifier.keyOf(tpIid));
820 tpBuilder.addAugmentation(OvsdbTerminationPointAugmentation.class, tpAugmentationBuilder.build());
821 return mdsalUtils.put(LogicalDatastoreType.CONFIGURATION, tpIid, tpBuilder.build());
824 public Boolean addPatchTerminationPoint(Node node, String bridgeName, String portName, String peerPortName) {
825 Map<String, String> option = new HashMap<>();
826 option.put("peer", peerPortName);
827 return addTerminationPoint(node, bridgeName, portName, PATCH_PORT_TYPE, option);
830 private String getControllerIPAddress() {
831 String addressString = ConfigProperties.getProperty(this.getClass(), "ovsdb.controller.address");
832 if (addressString != null) {
834 if (InetAddress.getByName(addressString) != null) {
835 return addressString;
837 } catch (UnknownHostException e) {
838 LOG.error("Host {} is invalid", addressString, e);
842 addressString = ConfigProperties.getProperty(this.getClass(), "of.address");
843 if (addressString != null) {
845 if (InetAddress.getByName(addressString) != null) {
846 return addressString;
848 } catch (UnknownHostException e) {
849 LOG.error("Host {} is invalid", addressString, e);
856 private short getControllerOFPort() {
857 short openFlowPort = OPENFLOW_PORT;
858 String portString = ConfigProperties.getProperty(this.getClass(), "of.listenPort");
859 if (portString != null) {
861 openFlowPort = Short.parseShort(portString);
862 } catch (NumberFormatException e) {
863 LOG.warn("Invalid port:{}, use default({})", portString,
870 public List<String> getControllersFromOvsdbNode(Node node) {
871 List<String> controllersStr = new ArrayList<>();
873 String controllerIpStr = getControllerIPAddress();
874 if (controllerIpStr != null) {
875 // If codepath makes it here, the ip address to be used was explicitly provided.
876 // Being so, also fetch openflowPort provided via ConfigProperties.
877 controllersStr.add(OPENFLOW_CONNECTION_PROTOCOL
878 + ":" + controllerIpStr + ":" + getControllerOFPort());
880 // Check if ovsdb node has manager entries
881 OvsdbNodeAugmentation ovsdbNodeAugmentation = extractOvsdbNode(node);
882 if (ovsdbNodeAugmentation != null) {
883 List<ManagerEntry> managerEntries = ovsdbNodeAugmentation.getManagerEntry();
884 if (managerEntries != null && !managerEntries.isEmpty()) {
885 for (ManagerEntry managerEntry : managerEntries) {
886 if (managerEntry == null || managerEntry.getTarget() == null) {
889 String[] tokens = managerEntry.getTarget().getValue().split(":");
890 if (tokens.length == 3 && tokens[0].equalsIgnoreCase("tcp")) {
891 controllersStr.add(OPENFLOW_CONNECTION_PROTOCOL
892 + ":" + tokens[1] + ":" + getControllerOFPort());
893 } else if (tokens[0].equalsIgnoreCase("ptcp")) {
894 ConnectionInfo connectionInfo = ovsdbNodeAugmentation.getConnectionInfo();
895 if (connectionInfo != null && connectionInfo.getLocalIp() != null) {
896 controllerIpStr = String.valueOf(connectionInfo.getLocalIp().getValue());
897 controllersStr.add(OPENFLOW_CONNECTION_PROTOCOL
898 + ":" + controllerIpStr + ":" + OPENFLOW_PORT);
900 LOG.warn("Ovsdb Node does not contain connection info: {}", node);
903 LOG.trace("Skipping manager entry {} for node {}",
904 managerEntry.getTarget(), node.getNodeId().getValue());
908 LOG.warn("Ovsdb Node does not contain manager entries : {}", node);
913 if (controllersStr.isEmpty()) {
914 // Neither user provided ip nor ovsdb node has manager entries. Lets use local machine ip address.
915 LOG.debug("Use local machine ip address as a OpenFlow Controller ip address");
916 controllerIpStr = getLocalControllerHostIpAddress();
917 if (controllerIpStr != null) {
918 controllersStr.add(OPENFLOW_CONNECTION_PROTOCOL
919 + ":" + controllerIpStr + ":" + OPENFLOW_PORT);
923 if (controllersStr.isEmpty()) {
924 LOG.warn("Failed to determine OpenFlow controller ip address");
925 } else if (LOG.isDebugEnabled()) {
926 controllerIpStr = "";
927 for (String currControllerIpStr : controllersStr) {
928 controllerIpStr += " " + currControllerIpStr;
930 LOG.debug("Found {} OpenFlow Controller(s) :{}", controllersStr.size(), controllerIpStr);
933 return controllersStr;
936 private String getLocalControllerHostIpAddress() {
937 String ipaddress = null;
939 for (Enumeration<NetworkInterface> ifaces = NetworkInterface.getNetworkInterfaces(); ifaces.hasMoreElements();){
940 NetworkInterface iface = ifaces.nextElement();
942 for (Enumeration<InetAddress> inetAddrs = iface.getInetAddresses(); inetAddrs.hasMoreElements();) {
943 InetAddress inetAddr = inetAddrs.nextElement();
944 if (!inetAddr.isLoopbackAddress() && inetAddr.isSiteLocalAddress()) {
945 ipaddress = inetAddr.getHostAddress();
950 }catch (Exception e){
951 LOG.warn("Exception while fetching local host ip address ", e);
956 public long getDataPathId(Node node) {
958 String datapathId = getDatapathId(node);
959 if (datapathId != null) {
960 dpid = new BigInteger(datapathId.replaceAll(":", ""), 16).longValue();
965 public String getDataPathIdStr(final Node node) {
967 long dpId = getDataPathId(node);
969 return String.valueOf(dpId);
976 public String getDatapathId(Node node) {
977 OvsdbBridgeAugmentation ovsdbBridgeAugmentation = node.getAugmentation(OvsdbBridgeAugmentation.class);
978 return getDatapathId(ovsdbBridgeAugmentation);
981 public String getDatapathId(OvsdbBridgeAugmentation ovsdbBridgeAugmentation) {
982 String datapathId = null;
983 if (ovsdbBridgeAugmentation != null && ovsdbBridgeAugmentation.getDatapathId() != null) {
984 datapathId = ovsdbBridgeAugmentation.getDatapathId().getValue();
989 public String extractBridgeName(Node node) {
990 return node.getAugmentation(OvsdbBridgeAugmentation.class).getBridgeName().getValue();
993 public boolean isBridgeOnOvsdbNode(Node ovsdbNode, String bridgeName) {
994 boolean found = false;
995 OvsdbNodeAugmentation ovsdbNodeAugmentation = extractNodeAugmentation(ovsdbNode);
996 if (ovsdbNodeAugmentation != null) {
997 List<ManagedNodeEntry> managedNodes = ovsdbNodeAugmentation.getManagedNodeEntry();
998 if (managedNodes != null) {
999 for (ManagedNodeEntry managedNode : managedNodes) {
1000 InstanceIdentifier<?> bridgeIid = managedNode.getBridgeRef().getValue();
1001 if (bridgeIid.toString().contains(bridgeName)) {
1011 public OvsdbBridgeAugmentation getBridgeFromConfig(Node node, String bridge) {
1012 OvsdbBridgeAugmentation ovsdbBridgeAugmentation = null;
1013 InstanceIdentifier<Node> bridgeIid =
1014 createInstanceIdentifier(node.getKey(), bridge);
1015 Node bridgeNode = mdsalUtils.read(LogicalDatastoreType.CONFIGURATION, bridgeIid);
1016 if (bridgeNode != null) {
1017 ovsdbBridgeAugmentation = bridgeNode.getAugmentation(OvsdbBridgeAugmentation.class);
1019 return ovsdbBridgeAugmentation;
1022 private void setManagedByForBridge(OvsdbBridgeAugmentationBuilder ovsdbBridgeAugmentationBuilder,
1023 NodeKey ovsdbNodeKey) {
1024 InstanceIdentifier<Node> connectionNodePath = createInstanceIdentifier(ovsdbNodeKey.getNodeId());
1025 ovsdbBridgeAugmentationBuilder.setManagedBy(new OvsdbNodeRef(connectionNodePath));
1028 public boolean isOvsdbNodeDpdk(Node ovsdbNode) {
1029 boolean found = false;
1030 OvsdbNodeAugmentation ovsdbNodeAugmentation = extractNodeAugmentation(ovsdbNode);
1031 if (ovsdbNodeAugmentation != null) {
1032 List<InterfaceTypeEntry> ifTypes = ovsdbNodeAugmentation.getInterfaceTypeEntry();
1033 if (ifTypes != null) {
1034 for (InterfaceTypeEntry ifType : ifTypes) {
1035 if (ifType.getInterfaceType().equals(InterfaceTypeDpdk.class)) {
1045 private List<ControllerEntry> createControllerEntries(List<String> controllersStr,
1046 Long maxBackoff, Long inactivityProbe) {
1047 List<ControllerEntry> controllerEntries = new ArrayList<>();
1048 if (controllersStr != null) {
1049 for (String controllerStr : controllersStr) {
1050 ControllerEntryBuilder controllerEntryBuilder = new ControllerEntryBuilder();
1051 controllerEntryBuilder.setTarget(new Uri(controllerStr));
1052 if (maxBackoff != null) {
1053 controllerEntryBuilder.setMaxBackoff(maxBackoff);
1055 if (inactivityProbe != null) {
1056 controllerEntryBuilder.setInactivityProbe(inactivityProbe);
1058 controllerEntries.add(controllerEntryBuilder.build());
1061 return controllerEntries;
1064 public OvsdbTerminationPointAugmentation extractTerminationPointAugmentation(Node bridgeNode, String portName) {
1065 if (bridgeNode.getAugmentation(OvsdbBridgeAugmentation.class) != null) {
1066 List<OvsdbTerminationPointAugmentation> tpAugmentations = extractTerminationPointAugmentations(bridgeNode);
1067 for (OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation : tpAugmentations) {
1068 if (ovsdbTerminationPointAugmentation.getName().equals(portName)) {
1069 return ovsdbTerminationPointAugmentation;
1076 public List<OvsdbTerminationPointAugmentation> extractTerminationPointAugmentations( Node node ) {
1077 List<OvsdbTerminationPointAugmentation> tpAugmentations = new ArrayList<>();
1079 LOG.error("extractTerminationPointAugmentations: Node value is null");
1080 return Collections.emptyList();
1082 List<TerminationPoint> terminationPoints = node.getTerminationPoint();
1083 if(terminationPoints != null && !terminationPoints.isEmpty()){
1084 for(TerminationPoint tp : terminationPoints){
1085 OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation =
1086 tp.getAugmentation(OvsdbTerminationPointAugmentation.class);
1087 if (ovsdbTerminationPointAugmentation != null) {
1088 tpAugmentations.add(ovsdbTerminationPointAugmentation);
1092 return tpAugmentations;
1096 * Extract the <code>OvsdbTerminationPointAugmentation</code> for the particular <code>node</code> identified by
1097 * <code>portName</code>.
1103 public OvsdbTerminationPointAugmentation getTerminationPointOfBridge(Node node, String portName) {
1104 OvsdbTerminationPointAugmentation tpAugmentation = extractTerminationPointAugmentation(node,portName);
1105 if(tpAugmentation == null){
1106 List<OvsdbTerminationPointAugmentation> tpAugmentations = readTerminationPointAugmentations(node);
1107 if(tpAugmentations != null){
1108 for(OvsdbTerminationPointAugmentation ovsdbTpAugmentation : tpAugmentations){
1109 if(ovsdbTpAugmentation.getName().equals(portName)){
1110 return ovsdbTpAugmentation;
1115 return tpAugmentation;
1119 * read the list of <code>OvsdbTerminationPointAugmentation</code> for the particular <code>node</code>.
1124 public List<OvsdbTerminationPointAugmentation> readTerminationPointAugmentations(Node node) {
1126 LOG.error("readTerminationPointAugmentations: Node value is null");
1127 return Collections.emptyList();
1129 Node operNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, InstanceIdentifier
1130 .create(NetworkTopology.class)
1131 .child(Topology.class, new TopologyKey(OVSDB_TOPOLOGY_ID))
1132 .child(Node.class, new NodeKey(node.getNodeId())));
1133 if (operNode != null) {
1134 return extractTerminationPointAugmentations(operNode);
1136 return new ArrayList<>();
1140 * Get all OVSDB nodes from topology.
1141 * @return a list of nodes or null if the topology could not found
1143 public List<Node> getOvsdbNodes() {
1144 InstanceIdentifier<Topology> inst = InstanceIdentifier.create(NetworkTopology.class).child(Topology.class,
1145 new TopologyKey(OVSDB_TOPOLOGY_ID));
1146 Topology topology = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, inst);
1147 return topology != null ? topology.getNode() : null;
1151 * Get OpenvSwitch other-config by key.
1152 * @param node OVSDB node
1153 * @param key key to extract from other-config
1154 * @return the value for key or null if key not found
1156 public String getOpenvswitchOtherConfig(Node node, String key) {
1157 OvsdbNodeAugmentation ovsdbNode = node.getAugmentation(OvsdbNodeAugmentation.class);
1158 if (ovsdbNode == null) {
1159 Node nodeFromReadOvsdbNode = readOvsdbNode(node);
1160 if (nodeFromReadOvsdbNode != null) {
1161 ovsdbNode = nodeFromReadOvsdbNode.getAugmentation(OvsdbNodeAugmentation.class);
1165 if (ovsdbNode != null && ovsdbNode.getOpenvswitchOtherConfigs() != null) {
1166 for (OpenvswitchOtherConfigs openvswitchOtherConfigs : ovsdbNode.getOpenvswitchOtherConfigs()) {
1167 if (openvswitchOtherConfigs.getOtherConfigKey().equals(key)) {
1168 return openvswitchOtherConfigs.getOtherConfigValue();
1176 public static TerminationPoint getTerminationPointByExternalId(final Node bridgeNode, final String interfaceName) {
1177 if (bridgeNode.getTerminationPoint() != null) {
1178 for (TerminationPoint tp : bridgeNode.getTerminationPoint()) {
1179 OvsdbTerminationPointAugmentation ovsdbTp = tp.getAugmentation(OvsdbTerminationPointAugmentation.class);
1180 String externalIdValue = getExternalInterfaceIdValue(ovsdbTp);
1181 if (externalIdValue != null && externalIdValue.equals(interfaceName)) {
1182 LOG.debug("Found matching termination point with iface-id {} on bridgeNode {}, returning tp {}",
1183 interfaceName, bridgeNode, tp);
1191 // This utility shouldn't be called often, as it reads all OVSDB nodes each time - not good for scale
1192 public Node getNodeByTerminationPointExternalId(final String interfaceName) {
1193 List<Node> nodes = getOvsdbNodes();
1194 if (nodes != null) {
1195 for (Node node : nodes) {
1196 TerminationPoint tp = getTerminationPointByExternalId(node, interfaceName);
1205 public static String getExternalInterfaceIdValue(final OvsdbTerminationPointAugmentation ovsdbTp) {
1206 if (ovsdbTp != null) {
1207 List<InterfaceExternalIds> ifaceExtIds = ovsdbTp.getInterfaceExternalIds();
1208 if (ifaceExtIds != null) {
1209 for (InterfaceExternalIds entry : ifaceExtIds) {
1210 if (entry.getExternalIdKey().equals(EXTERNAL_INTERFACE_ID_KEY)) {
1211 return entry.getExternalIdValue();
1219 public String getDatapathIdFromNodeInstanceId(InstanceIdentifier<Node> nodeInstanceId) {
1220 Node node = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, nodeInstanceId);
1221 String dpId = node != null ? getDataPathIdStr(node) : null;
1228 public static boolean compareDbVersionToMinVersion(final String dbVersion, final String minVersion) {
1229 final Matcher dbVersionMatcher = PATTERN.matcher(dbVersion);
1230 final Matcher minVersionMatcher = PATTERN.matcher(minVersion);
1231 LOG.debug("dbVersion {}, minVersion {}", dbVersion, minVersion);
1232 if (!dbVersionMatcher.find()){
1233 LOG.error("Invalid DB version format {}", dbVersion);
1236 if (!minVersionMatcher.find()){
1237 LOG.error("Invalid Min DB version format {}", minVersion);
1241 if (dbVersion != null && !dbVersion.isEmpty() && minVersion != null
1242 && !minVersion.isEmpty()) {
1243 if (Integer.valueOf(dbVersionMatcher.group(1)).equals(Integer.valueOf(minVersionMatcher.group(1))) &&
1244 Integer.valueOf(dbVersionMatcher.group(2)).equals(Integer.valueOf(minVersionMatcher.group(2))) &&
1245 Integer.valueOf(dbVersionMatcher.group(3)).equals(Integer.valueOf(minVersionMatcher.group(3)))) {
1249 if (Integer.valueOf(dbVersionMatcher.group(1)).intValue() > Integer.valueOf(minVersionMatcher.group(1)).intValue()) {
1253 if (Integer.valueOf(dbVersionMatcher.group(1)).intValue() < Integer.valueOf(minVersionMatcher.group(1)).intValue()) {
1257 // major version is equal
1258 if (Integer.valueOf(dbVersionMatcher.group(2)).intValue() > Integer.valueOf(minVersionMatcher.group(2)).intValue()) {
1261 if (Integer.valueOf(dbVersionMatcher.group(2)).intValue() < Integer.valueOf(minVersionMatcher.group(2)).intValue()) {
1265 if (Integer.valueOf(dbVersionMatcher.group(3)).intValue() > Integer.valueOf(minVersionMatcher.group(3)).intValue()) {