2 * Copyright (c) 2015 - 2016 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;
24 import java.util.Optional;
26 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
27 import org.opendaylight.ovsdb.utils.config.ConfigProperties;
28 import org.opendaylight.ovsdb.utils.mdsal.utils.MdsalUtils;
29 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IetfInetUtil;
30 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
31 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Address;
32 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.PortNumber;
33 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Uri;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.DatapathId;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.DatapathTypeBase;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.DatapathTypeNetdev;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.InterfaceTypeBase;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.InterfaceTypeDpdk;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.InterfaceTypeDpdkr;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.InterfaceTypeDpdkvhost;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.InterfaceTypeDpdkvhostuser;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.InterfaceTypeGeneve;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.InterfaceTypeGre;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.InterfaceTypeGre64;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.InterfaceTypeInternal;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.InterfaceTypeIpsecGre;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.InterfaceTypeIpsecGre64;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.InterfaceTypeLisp;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.InterfaceTypePatch;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.InterfaceTypeSystem;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.InterfaceTypeTap;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.InterfaceTypeVxlan;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.InterfaceTypeVxlanGpe;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentation;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentationBuilder;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeName;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeProtocolBase;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeProtocolOpenflow10;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeProtocolOpenflow11;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeProtocolOpenflow12;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeProtocolOpenflow13;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeProtocolOpenflow14;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeProtocolOpenflow15;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbFailModeBase;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbFailModeSecure;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbFailModeStandalone;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbNodeAugmentation;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbNodeAugmentationBuilder;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbNodeRef;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbTerminationPointAugmentation;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbTerminationPointAugmentationBuilder;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.BridgeExternalIds;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.BridgeOtherConfigs;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.BridgeOtherConfigsBuilder;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ControllerEntry;
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ControllerEntryBuilder;
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ProtocolEntry;
78 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ProtocolEntryBuilder;
79 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.ConnectionInfo;
80 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.ConnectionInfoBuilder;
81 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.InterfaceTypeEntry;
82 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.ManagedNodeEntry;
83 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.ManagerEntry;
84 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.OpenvswitchOtherConfigs;
85 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceExternalIds;
86 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceExternalIdsBuilder;
87 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceExternalIdsKey;
88 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.Options;
89 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.OptionsBuilder;
90 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.OptionsKey;
91 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
92 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
93 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId;
94 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TpId;
95 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
96 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
97 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
98 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeBuilder;
99 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
100 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint;
101 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointBuilder;
102 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointKey;
103 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
104 import org.slf4j.Logger;
105 import org.slf4j.LoggerFactory;
107 import com.google.common.collect.ImmutableBiMap;
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 short OPENFLOW_PORT = 6653;
116 public static final String OVSDB_URI_PREFIX = "ovsdb";
117 public static final String BRIDGE_URI_PREFIX = "bridge";
118 private static final String DISABLE_IN_BAND = "disable-in-band";
119 private static final String PATCH_PORT_TYPE = "patch";
120 // External ID key used for mapping between an OVSDB port and an interface name
121 private static final String EXTERNAL_INTERFACE_ID_KEY = "iface-id";
123 public SouthboundUtils(MdsalUtils mdsalUtils) {
124 this.mdsalUtils = mdsalUtils;
127 public static final ImmutableBiMap<String, Class<? extends InterfaceTypeBase>> OVSDB_INTERFACE_TYPE_MAP
128 = new ImmutableBiMap.Builder<String, Class<? extends InterfaceTypeBase>>()
129 .put("internal", InterfaceTypeInternal.class)
130 .put("vxlan", InterfaceTypeVxlan.class)
131 .put("vxlan-gpe", InterfaceTypeVxlanGpe.class)
132 .put("patch", InterfaceTypePatch.class)
133 .put("system", InterfaceTypeSystem.class)
134 .put("tap", InterfaceTypeTap.class)
135 .put("geneve", InterfaceTypeGeneve.class)
136 .put("gre", InterfaceTypeGre.class)
137 .put("ipsec_gre", InterfaceTypeIpsecGre.class)
138 .put("gre64", InterfaceTypeGre64.class)
139 .put("ipsec_gre64", InterfaceTypeIpsecGre64.class)
140 .put("lisp", InterfaceTypeLisp.class)
141 .put("dpdk", InterfaceTypeDpdk.class)
142 .put("dpdkr", InterfaceTypeDpdkr.class)
143 .put("dpdkvhost", InterfaceTypeDpdkvhost.class)
144 .put("dpdkvhostuser", InterfaceTypeDpdkvhostuser.class)
147 public static final ImmutableBiMap<Class<? extends OvsdbBridgeProtocolBase>,String> OVSDB_PROTOCOL_MAP
148 = new ImmutableBiMap.Builder<Class<? extends OvsdbBridgeProtocolBase>,String>()
149 .put(OvsdbBridgeProtocolOpenflow10.class,"OpenFlow10")
150 .put(OvsdbBridgeProtocolOpenflow11.class,"OpenFlow11")
151 .put(OvsdbBridgeProtocolOpenflow12.class,"OpenFlow12")
152 .put(OvsdbBridgeProtocolOpenflow13.class,"OpenFlow13")
153 .put(OvsdbBridgeProtocolOpenflow14.class,"OpenFlow14")
154 .put(OvsdbBridgeProtocolOpenflow15.class,"OpenFlow15")
157 private static final ImmutableBiMap<Class<? extends OvsdbFailModeBase>,String> OVSDB_FAIL_MODE_MAP
158 = new ImmutableBiMap.Builder<Class<? extends OvsdbFailModeBase>,String>()
159 .put(OvsdbFailModeStandalone.class,"standalone")
160 .put(OvsdbFailModeSecure.class,"secure")
163 public static NodeId createNodeId(IpAddress ip, PortNumber port) {
164 String uriString = OVSDB_URI_PREFIX + "://"
165 + String.valueOf(ip.getValue()) + ":" + port.getValue();
166 Uri uri = new Uri(uriString);
167 return new NodeId(uri);
170 public static Node createNode(ConnectionInfo key) {
171 NodeBuilder nodeBuilder = new NodeBuilder();
172 nodeBuilder.setNodeId(createNodeId(key.getRemoteIp(), key.getRemotePort()));
173 nodeBuilder.addAugmentation(OvsdbNodeAugmentation.class, createOvsdbAugmentation(key));
174 return nodeBuilder.build();
177 public static OvsdbNodeAugmentation createOvsdbAugmentation(ConnectionInfo key) {
178 OvsdbNodeAugmentationBuilder ovsdbNodeBuilder = new OvsdbNodeAugmentationBuilder();
179 ovsdbNodeBuilder.setConnectionInfo(key);
180 return ovsdbNodeBuilder.build();
183 public static InstanceIdentifier<Node> createInstanceIdentifier(NodeId nodeId) {
184 return InstanceIdentifier
185 .create(NetworkTopology.class)
186 .child(Topology.class, new TopologyKey(OVSDB_TOPOLOGY_ID))
187 .child(Node.class,new NodeKey(nodeId));
190 public static InstanceIdentifier<Node> createInstanceIdentifier(NodeKey ovsdbNodeKey, String bridgeName) {
191 return createInstanceIdentifier(createManagedNodeId(ovsdbNodeKey.getNodeId(), bridgeName));
194 public static NodeId createManagedNodeId(NodeId ovsdbNodeId, String bridgeName) {
195 return new NodeId(ovsdbNodeId.getValue()
196 + "/" + BRIDGE_URI_PREFIX + "/" + 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.getKey())
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(ConnectionInfo key, OvsdbBridgeName bridgeName) {
237 return createManagedNodeId(key.getRemoteIp(), key.getRemotePort(), bridgeName);
240 public static NodeId createManagedNodeId(IpAddress ip, PortNumber port, OvsdbBridgeName bridgeName) {
241 return new NodeId(createNodeId(ip,port).getValue()
242 + "/" + BRIDGE_URI_PREFIX + "/" + bridgeName.getValue());
245 public static NodeId createManagedNodeId(InstanceIdentifier<Node> iid) {
246 NodeKey nodeKey = iid.firstKeyOf(Node.class);
247 return nodeKey.getNodeId();
250 public ConnectionInfo getConnectionInfo(Node ovsdbNode) {
251 ConnectionInfo connectionInfo = null;
252 OvsdbNodeAugmentation ovsdbNodeAugmentation = extractOvsdbNode(ovsdbNode);
253 if (ovsdbNodeAugmentation != null) {
254 connectionInfo = ovsdbNodeAugmentation.getConnectionInfo();
256 return connectionInfo;
259 public OvsdbNodeAugmentation extractOvsdbNode(Node node) {
260 return node.getAugmentation(OvsdbNodeAugmentation.class);
263 public static IpAddress createIpAddress(InetAddress address) {
265 if (address instanceof Inet4Address) {
266 ip = createIpAddress((Inet4Address)address);
267 } else if (address instanceof Inet6Address) {
268 ip = createIpAddress((Inet6Address)address);
273 public static IpAddress createIpAddress(Inet4Address address) {
274 return IetfInetUtil.INSTANCE.ipAddressFor(address);
277 public static IpAddress createIpAddress(Inet6Address address) {
278 Ipv6Address ipv6 = new Ipv6Address(address.getHostAddress());
279 return new IpAddress(ipv6);
282 public static ConnectionInfo getConnectionInfo(final String addressStr, final String portStr) {
283 InetAddress inetAddress = null;
285 inetAddress = InetAddress.getByName(addressStr);
286 } catch (UnknownHostException e) {
287 LOG.warn("Could not allocate InetAddress", e);
290 IpAddress address = createIpAddress(inetAddress);
291 PortNumber port = new PortNumber(Integer.parseInt(portStr));
293 LOG.info("connectionInfo: {}", new ConnectionInfoBuilder()
294 .setRemoteIp(address)
297 return new ConnectionInfoBuilder()
298 .setRemoteIp(address)
303 public static String connectionInfoToString(final ConnectionInfo connectionInfo) {
304 return String.valueOf(
305 connectionInfo.getRemoteIp().getValue()) + ":" + connectionInfo.getRemotePort().getValue();
308 public boolean addOvsdbNode(final ConnectionInfo connectionInfo) {
309 return addOvsdbNode(connectionInfo, OVSDB_UPDATE_TIMEOUT);
312 public boolean addOvsdbNode(final ConnectionInfo connectionInfo, long timeout) {
313 boolean result = mdsalUtils.put(LogicalDatastoreType.CONFIGURATION,
314 createInstanceIdentifier(connectionInfo),
315 createNode(connectionInfo));
318 Thread.sleep(timeout);
319 } catch (InterruptedException e) {
320 LOG.warn("Interrupted while waiting after adding OVSDB node {}",
321 connectionInfoToString(connectionInfo), e);
327 public Node getOvsdbNode(final ConnectionInfo connectionInfo) {
328 return mdsalUtils.read(LogicalDatastoreType.OPERATIONAL,
329 createInstanceIdentifier(connectionInfo));
332 public boolean deleteOvsdbNode(final ConnectionInfo connectionInfo) {
333 return deleteOvsdbNode(connectionInfo, OVSDB_UPDATE_TIMEOUT);
336 public boolean deleteOvsdbNode(final ConnectionInfo connectionInfo, long timeout) {
337 boolean result = mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION,
338 createInstanceIdentifier(connectionInfo));
341 Thread.sleep(timeout);
342 } catch (InterruptedException e) {
343 LOG.warn("Interrupted while waiting after deleting OVSDB node {}",
344 connectionInfoToString(connectionInfo), e);
350 public Node connectOvsdbNode(final ConnectionInfo connectionInfo) {
351 return connectOvsdbNode(connectionInfo, OVSDB_UPDATE_TIMEOUT);
354 public Node connectOvsdbNode(final ConnectionInfo connectionInfo, long timeout) {
355 addOvsdbNode(connectionInfo, timeout);
356 Node node = getOvsdbNode(connectionInfo);
357 LOG.info("Connected to {}", connectionInfoToString(connectionInfo));
361 public boolean disconnectOvsdbNode(final ConnectionInfo connectionInfo) {
362 return disconnectOvsdbNode(connectionInfo, OVSDB_UPDATE_TIMEOUT);
365 public boolean disconnectOvsdbNode(final ConnectionInfo connectionInfo, long timeout) {
366 deleteOvsdbNode(connectionInfo, timeout);
367 LOG.info("Disconnected from {}", connectionInfoToString(connectionInfo));
371 public List<ControllerEntry> createControllerEntry(String controllerTarget) {
372 List<ControllerEntry> controllerEntriesList = new ArrayList<>();
373 controllerEntriesList.add(new ControllerEntryBuilder()
374 .setTarget(new Uri(controllerTarget))
376 return controllerEntriesList;
380 * Extract the <code>store</code> type data store contents for the particular bridge identified by
381 * <code>bridgeName</code>.
383 * @param connectionInfo address for the node
384 * @param bridgeName name of the bridge
385 * @param store defined by the <code>LogicalDatastoreType</code> enumeration
386 * @return <code>store</code> type data store contents
388 public OvsdbBridgeAugmentation getBridge(ConnectionInfo connectionInfo, String bridgeName,
389 LogicalDatastoreType store) {
390 OvsdbBridgeAugmentation ovsdbBridgeAugmentation = null;
391 Node bridgeNode = getBridgeNode(connectionInfo, bridgeName, store);
392 if (bridgeNode != null) {
393 ovsdbBridgeAugmentation = bridgeNode.getAugmentation(OvsdbBridgeAugmentation.class);
395 return ovsdbBridgeAugmentation;
399 * extract the <code>LogicalDataStoreType.OPERATIONAL</code> type data store contents for the particular bridge
400 * identified by <code>bridgeName</code>
402 * @param connectionInfo address for the node
403 * @param bridgeName name of the bridge
404 * @see <code>NetvirtIT.getBridge(ConnectionInfo, String, LogicalDatastoreType)</code>
405 * @return <code>LogicalDatastoreType.OPERATIONAL</code> type data store contents
407 public OvsdbBridgeAugmentation getBridge(ConnectionInfo connectionInfo, String bridgeName) {
408 return getBridge(connectionInfo, bridgeName, LogicalDatastoreType.OPERATIONAL);
412 * Extract the node contents from <code>store</code> type data store for the
413 * bridge identified by <code>bridgeName</code>.
415 * @param connectionInfo address for the node
416 * @param bridgeName name of the bridge
417 * @param store defined by the <code>LogicalDatastoreType</code> enumeration
418 * @return <code>store</code> type data store contents
420 public Node getBridgeNode(ConnectionInfo connectionInfo, String bridgeName, LogicalDatastoreType store) {
421 InstanceIdentifier<Node> bridgeIid = createInstanceIdentifier(connectionInfo, new OvsdbBridgeName(bridgeName));
422 return mdsalUtils.read(store, bridgeIid);
425 public Node getBridgeNode(Node node, String bridgeName) {
426 OvsdbBridgeAugmentation bridge = extractBridgeAugmentation(node);
427 if (bridge != null && bridge.getBridgeName().getValue().equals(bridgeName)) {
430 return readBridgeNode(node, bridgeName);
434 public Node readBridgeNode(Node node, String name) {
435 Node ovsdbNode = node;
436 if (extractNodeAugmentation(ovsdbNode) == null) {
437 ovsdbNode = readOvsdbNode(node);
438 if (ovsdbNode == null) {
442 Node bridgeNode = null;
443 ConnectionInfo connectionInfo = getConnectionInfo(ovsdbNode);
444 if (connectionInfo != null) {
445 InstanceIdentifier<Node> bridgeIid =
446 createInstanceIdentifier(node.getKey(), name);
447 bridgeNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, bridgeIid);
452 public OvsdbNodeAugmentation extractNodeAugmentation(Node node) {
453 return node.getAugmentation(OvsdbNodeAugmentation.class);
456 public OvsdbBridgeAugmentation extractBridgeAugmentation(Node node) {
460 return node.getAugmentation(OvsdbBridgeAugmentation.class);
463 public Node readOvsdbNode(Node bridgeNode) {
464 Node ovsdbNode = null;
465 OvsdbBridgeAugmentation bridgeAugmentation = extractBridgeAugmentation(bridgeNode);
466 if (bridgeAugmentation != null) {
467 InstanceIdentifier<Node> ovsdbNodeIid =
468 (InstanceIdentifier<Node>) bridgeAugmentation.getManagedBy().getValue();
469 ovsdbNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, ovsdbNodeIid);
471 LOG.debug("readOvsdbNode: Provided node is not a bridge node : {}",bridgeNode);
476 public boolean deleteBridge(final ConnectionInfo connectionInfo, final String bridgeName) {
477 return deleteBridge(connectionInfo, bridgeName, OVSDB_UPDATE_TIMEOUT);
480 public boolean deleteBridge(final ConnectionInfo connectionInfo, final String bridgeName, long timeout) {
481 boolean result = mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION,
482 createInstanceIdentifier(connectionInfo, new OvsdbBridgeName(bridgeName)));
485 Thread.sleep(timeout);
486 } catch (InterruptedException e) {
487 LOG.warn("Interrupted while waiting after deleting bridge {}", bridgeName, e);
493 public List<ProtocolEntry> createMdsalProtocols() {
494 List<ProtocolEntry> protocolList = new ArrayList<>();
495 ImmutableBiMap<String, Class<? extends OvsdbBridgeProtocolBase>> mapper =
496 OVSDB_PROTOCOL_MAP.inverse();
497 protocolList.add(new ProtocolEntryBuilder().setProtocol(mapper.get("OpenFlow13")).build());
501 public boolean addBridge(final ConnectionInfo connectionInfo, InstanceIdentifier<Node> bridgeIid,
502 final String bridgeName, NodeId bridgeNodeId, final boolean setProtocolEntries,
503 final Class<? extends OvsdbFailModeBase> failMode, final boolean setManagedBy,
504 final Class<? extends DatapathTypeBase> dpType,
505 final List<BridgeExternalIds> externalIds,
506 final List<ControllerEntry> controllerEntries,
507 final List<BridgeOtherConfigs> otherConfigs,
508 final String dpid) throws InterruptedException {
509 return addBridge(connectionInfo, bridgeIid, bridgeName, bridgeNodeId, setProtocolEntries, failMode,
510 setManagedBy, dpType, externalIds, controllerEntries, otherConfigs, dpid);
514 * base method for adding test bridges. Other helper methods used to create bridges should utilize this method.
516 * @param connectionInfo
517 * @param bridgeIid if passed null, one is created
518 * @param bridgeName cannot be null
519 * @param bridgeNodeId if passed null, one is created based on <code>bridgeIid</code>
520 * @param setProtocolEntries toggles whether default protocol entries are set for the bridge
521 * @param failMode toggles whether default fail mode is set for the bridge
522 * @param setManagedBy toggles whether to setManagedBy for the bridge
523 * @param dpType if passed null, this parameter is ignored
524 * @param externalIds if passed null, this parameter is ignored
525 * @param otherConfig if passed null, this parameter is ignored
526 * @return success of bridge addition
527 * @throws InterruptedException
529 public boolean addBridge(final ConnectionInfo connectionInfo, InstanceIdentifier<Node> bridgeIid,
530 final String bridgeName, NodeId bridgeNodeId, final boolean setProtocolEntries,
531 final Class<? extends OvsdbFailModeBase> failMode, final boolean setManagedBy,
532 final Class<? extends DatapathTypeBase> dpType,
533 final List<BridgeExternalIds> externalIds,
534 final List<ControllerEntry> controllerEntries,
535 final List<BridgeOtherConfigs> otherConfigs,
536 final String dpid, long timeout) throws InterruptedException {
538 NodeBuilder bridgeNodeBuilder = new NodeBuilder();
539 if (bridgeIid == null) {
540 bridgeIid = createInstanceIdentifier(connectionInfo, new OvsdbBridgeName(bridgeName));
542 if (bridgeNodeId == null) {
543 bridgeNodeId = createManagedNodeId(bridgeIid);
545 bridgeNodeBuilder.setNodeId(bridgeNodeId);
546 OvsdbBridgeAugmentationBuilder ovsdbBridgeAugmentationBuilder = new OvsdbBridgeAugmentationBuilder();
547 ovsdbBridgeAugmentationBuilder.setBridgeName(new OvsdbBridgeName(bridgeName));
548 if (setProtocolEntries) {
549 ovsdbBridgeAugmentationBuilder.setProtocolEntry(createMdsalProtocols());
551 if (failMode != null) {
552 ovsdbBridgeAugmentationBuilder.setFailMode(failMode);
555 setManagedBy(ovsdbBridgeAugmentationBuilder, connectionInfo);
557 if (dpType != null) {
558 ovsdbBridgeAugmentationBuilder.setDatapathType(dpType);
560 if (externalIds != null) {
561 ovsdbBridgeAugmentationBuilder.setBridgeExternalIds(externalIds);
563 if (controllerEntries != null) {
564 ovsdbBridgeAugmentationBuilder.setControllerEntry(controllerEntries);
566 if (otherConfigs != null) {
567 ovsdbBridgeAugmentationBuilder.setBridgeOtherConfigs(otherConfigs);
569 if (dpid != null && !dpid.isEmpty()) {
570 DatapathId datapathId = new DatapathId(dpid);
571 ovsdbBridgeAugmentationBuilder.setDatapathId(datapathId);
573 bridgeNodeBuilder.addAugmentation(OvsdbBridgeAugmentation.class, ovsdbBridgeAugmentationBuilder.build());
574 LOG.debug("Built with the intent to store bridge data {}",
575 ovsdbBridgeAugmentationBuilder.toString());
576 boolean result = mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION,
577 bridgeIid, bridgeNodeBuilder.build());
579 Thread.sleep(OVSDB_UPDATE_TIMEOUT);
585 * Set the controllers of an existing bridge node
586 * @param ovsdbNode where the bridge is
587 * @param bridgeName Name of the bridge
588 * @param controllers controller strings
589 * @return success if the write to md-sal was successful
591 public boolean setBridgeController(Node ovsdbNode, String bridgeName, List<String> controllers) {
592 LOG.debug("setBridgeController: ovsdbNode: {}, bridgeNode: {}, controller(s): {}",
593 ovsdbNode, bridgeName, controllers);
595 InstanceIdentifier<Node> bridgeNodeIid = createInstanceIdentifier(ovsdbNode.getKey(), bridgeName);
596 Node bridgeNode = mdsalUtils.read(LogicalDatastoreType.CONFIGURATION, bridgeNodeIid);
597 if (bridgeNode == null) {
598 LOG.info("setBridgeController could not find bridge in configuration {}", bridgeNodeIid);
602 OvsdbBridgeAugmentation bridgeAug = extractBridgeAugmentation(bridgeNode);
604 //Only add controller entries that do not already exist on this bridge
605 List<ControllerEntry> existingControllerEntries = bridgeAug.getControllerEntry();
606 List<ControllerEntry> newControllerEntries = new ArrayList<>();
607 if(existingControllerEntries != null) {
609 for (ControllerEntry newEntry : createControllerEntries(controllers)) {
610 for (ControllerEntry existingEntry : existingControllerEntries) {
611 if (newEntry.getTarget().equals(existingEntry.getTarget())) {
612 continue NEW_ENTRY_LOOP;
615 newControllerEntries.add(newEntry);
618 newControllerEntries = createControllerEntries(controllers);
621 if(newControllerEntries.isEmpty()) {
625 NodeBuilder nodeBuilder = new NodeBuilder(bridgeNode);
626 OvsdbBridgeAugmentationBuilder augBuilder = new OvsdbBridgeAugmentationBuilder(bridgeAug);
628 augBuilder.setControllerEntry(newControllerEntries);
629 nodeBuilder.addAugmentation(OvsdbBridgeAugmentation.class, augBuilder.build());
630 InstanceIdentifier<Node> bridgeIid = createInstanceIdentifier(ovsdbNode.getKey(), bridgeName);
631 return mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION, bridgeIid, nodeBuilder.build());
634 public boolean addBridge(Node ovsdbNode, String bridgeName, List<String> controllersStr,
635 final Class<? extends DatapathTypeBase> dpType, String mac) {
638 LOG.info("addBridge: node: {}, bridgeName: {}, controller(s): {}", ovsdbNode, bridgeName, controllersStr);
639 ConnectionInfo connectionInfo = getConnectionInfo(ovsdbNode);
640 if (connectionInfo != null) {
641 NodeBuilder bridgeNodeBuilder = new NodeBuilder();
642 InstanceIdentifier<Node> bridgeIid = createInstanceIdentifier(ovsdbNode.getKey(), bridgeName);
643 NodeId bridgeNodeId = createManagedNodeId(bridgeIid);
644 bridgeNodeBuilder.setNodeId(bridgeNodeId);
645 OvsdbBridgeAugmentationBuilder ovsdbBridgeAugmentationBuilder = new OvsdbBridgeAugmentationBuilder();
646 ovsdbBridgeAugmentationBuilder.setControllerEntry(createControllerEntries(controllersStr));
647 ovsdbBridgeAugmentationBuilder.setBridgeName(new OvsdbBridgeName(bridgeName));
648 ovsdbBridgeAugmentationBuilder.setProtocolEntry(createMdsalProtocols());
649 ovsdbBridgeAugmentationBuilder.setFailMode( OVSDB_FAIL_MODE_MAP.inverse().get("secure"));
650 BridgeOtherConfigsBuilder bridgeOtherConfigsBuilder = new BridgeOtherConfigsBuilder();
651 bridgeOtherConfigsBuilder.setBridgeOtherConfigKey(DISABLE_IN_BAND);
652 bridgeOtherConfigsBuilder.setBridgeOtherConfigValue("true");
653 List<BridgeOtherConfigs> bridgeOtherConfigsList = new ArrayList<>();
654 bridgeOtherConfigsList.add(bridgeOtherConfigsBuilder.build());
656 BridgeOtherConfigsBuilder macOtherConfigBuilder = new BridgeOtherConfigsBuilder();
657 macOtherConfigBuilder.setBridgeOtherConfigKey("hwaddr");
658 macOtherConfigBuilder.setBridgeOtherConfigValue(mac);
659 bridgeOtherConfigsList.add(macOtherConfigBuilder.build());
661 ovsdbBridgeAugmentationBuilder.setBridgeOtherConfigs(bridgeOtherConfigsList);
662 setManagedByForBridge(ovsdbBridgeAugmentationBuilder, ovsdbNode.getKey());
663 if (dpType != null) {
664 ovsdbBridgeAugmentationBuilder.setDatapathType(dpType);
666 if (isOvsdbNodeDpdk(ovsdbNode)) {
667 ovsdbBridgeAugmentationBuilder.setDatapathType(DatapathTypeNetdev.class);
669 bridgeNodeBuilder.addAugmentation(OvsdbBridgeAugmentation.class, ovsdbBridgeAugmentationBuilder.build());
671 Node node = bridgeNodeBuilder.build();
672 result = mdsalUtils.put(LogicalDatastoreType.CONFIGURATION, bridgeIid, node);
673 LOG.info("addBridge: result: {}", result);
675 throw new InvalidParameterException("Could not find ConnectionInfo");
681 private void setManagedBy(final OvsdbBridgeAugmentationBuilder ovsdbBridgeAugmentationBuilder,
682 final ConnectionInfo connectionInfo) {
683 InstanceIdentifier<Node> connectionNodePath = createInstanceIdentifier(connectionInfo);
684 ovsdbBridgeAugmentationBuilder.setManagedBy(new OvsdbNodeRef(connectionNodePath));
687 public boolean addTerminationPoint(
688 Node bridgeNode, String portName, String type, Map<String, String> options,
689 Map<String, String> externalIds) {
690 return addTerminationPoint(bridgeNode, portName, type, options, externalIds, null);
693 public boolean addTerminationPoint(
694 Node bridgeNode, String portName, String type, Map<String, String> options, Map<String, String> externalIds,
696 InstanceIdentifier<TerminationPoint> tpIid = createTerminationPointInstanceIdentifier(bridgeNode, portName);
697 OvsdbTerminationPointAugmentationBuilder tpAugmentationBuilder = new OvsdbTerminationPointAugmentationBuilder();
699 tpAugmentationBuilder.setName(portName);
700 tpAugmentationBuilder.setOfport(ofPort);
702 tpAugmentationBuilder.setInterfaceType(OVSDB_INTERFACE_TYPE_MAP.get(type));
705 if (options != null && options.size() > 0) {
706 List<Options> optionsList = new ArrayList<>();
707 for (Map.Entry<String, String> entry : options.entrySet()) {
708 OptionsBuilder optionsBuilder = new OptionsBuilder();
709 optionsBuilder.setKey(new OptionsKey(entry.getKey()));
710 optionsBuilder.setOption(entry.getKey());
711 optionsBuilder.setValue(entry.getValue());
712 optionsList.add(optionsBuilder.build());
714 tpAugmentationBuilder.setOptions(optionsList);
717 if (externalIds != null && externalIds.size() > 0) {
718 List<InterfaceExternalIds> externalIdsList = new ArrayList<>();
719 for (Map.Entry<String, String> entry : externalIds.entrySet()) {
720 InterfaceExternalIdsBuilder interfaceExternalIdsBuilder = new InterfaceExternalIdsBuilder();
721 interfaceExternalIdsBuilder.setKey(new InterfaceExternalIdsKey(entry.getKey()));
722 interfaceExternalIdsBuilder.setExternalIdKey(entry.getKey());
723 interfaceExternalIdsBuilder.setExternalIdValue(entry.getValue());
724 externalIdsList.add(interfaceExternalIdsBuilder.build());
726 tpAugmentationBuilder.setInterfaceExternalIds(externalIdsList);
729 TerminationPointBuilder tpBuilder = new TerminationPointBuilder();
730 tpBuilder.setKey(InstanceIdentifier.keyOf(tpIid));
731 tpBuilder.addAugmentation(OvsdbTerminationPointAugmentation.class, tpAugmentationBuilder.build());
732 /* TODO SB_MIGRATION should this be merge or mdsalUtils.put */
733 return mdsalUtils.put(LogicalDatastoreType.CONFIGURATION, tpIid, tpBuilder.build());
736 public Boolean addTerminationPoint(Node bridgeNode, String portName, String type) {
737 return addTerminationPoint(bridgeNode, portName, type, Collections.EMPTY_MAP, null);
740 public Boolean addTerminationPoint(Node bridgeNode, String bridgeName, String portName,
741 String type, Map<String, String> options) {
742 InstanceIdentifier<TerminationPoint> tpIid = createTerminationPointInstanceIdentifier(
743 bridgeNode, portName);
744 OvsdbTerminationPointAugmentationBuilder tpAugmentationBuilder = new OvsdbTerminationPointAugmentationBuilder();
746 tpAugmentationBuilder.setName(portName);
748 tpAugmentationBuilder.setInterfaceType(OVSDB_INTERFACE_TYPE_MAP.get(type));
751 List<Options> optionsList = new ArrayList<>();
752 for (Map.Entry<String, String> entry : options.entrySet()) {
753 OptionsBuilder optionsBuilder = new OptionsBuilder();
754 optionsBuilder.setKey(new OptionsKey(entry.getKey()));
755 optionsBuilder.setOption(entry.getKey());
756 optionsBuilder.setValue(entry.getValue());
757 optionsList.add(optionsBuilder.build());
759 tpAugmentationBuilder.setOptions(optionsList);
761 TerminationPointBuilder tpBuilder = new TerminationPointBuilder();
762 tpBuilder.setKey(InstanceIdentifier.keyOf(tpIid));
763 tpBuilder.addAugmentation(OvsdbTerminationPointAugmentation.class, tpAugmentationBuilder.build());
764 /* TODO SB_MIGRATION should this be merge or mdsalUtils.put */
765 return mdsalUtils.put(LogicalDatastoreType.CONFIGURATION, tpIid, tpBuilder.build());
768 public Boolean addTerminationPoint(Node bridgeNode, String bridgeName, String portName, String type) {
769 InstanceIdentifier<TerminationPoint> tpIid = createTerminationPointInstanceIdentifier(bridgeNode, portName);
770 OvsdbTerminationPointAugmentationBuilder tpAugmentationBuilder =
771 new OvsdbTerminationPointAugmentationBuilder();
773 tpAugmentationBuilder.setName(portName);
775 tpAugmentationBuilder.setInterfaceType(OVSDB_INTERFACE_TYPE_MAP.get(type));
777 TerminationPointBuilder tpBuilder = new TerminationPointBuilder();
778 tpBuilder.setKey(InstanceIdentifier.keyOf(tpIid));
779 tpBuilder.addAugmentation(OvsdbTerminationPointAugmentation.class, tpAugmentationBuilder.build());
780 return mdsalUtils.put(LogicalDatastoreType.CONFIGURATION, tpIid, tpBuilder.build());
783 public Boolean addPatchTerminationPoint(Node node, String bridgeName, String portName, String peerPortName) {
784 Map<String, String> option = new HashMap<>();
785 option.put("peer", peerPortName);
786 return addTerminationPoint(node, bridgeName, portName, PATCH_PORT_TYPE, option);
789 private String getControllerIPAddress() {
790 String addressString = ConfigProperties.getProperty(this.getClass(), "ovsdb.controller.address");
791 if (addressString != null) {
793 if (InetAddress.getByName(addressString) != null) {
794 return addressString;
796 } catch (UnknownHostException e) {
797 LOG.error("Host {} is invalid", addressString, e);
801 addressString = ConfigProperties.getProperty(this.getClass(), "of.address");
802 if (addressString != null) {
804 if (InetAddress.getByName(addressString) != null) {
805 return addressString;
807 } catch (UnknownHostException e) {
808 LOG.error("Host {} is invalid", addressString, e);
815 private short getControllerOFPort() {
816 short openFlowPort = OPENFLOW_PORT;
817 String portString = ConfigProperties.getProperty(this.getClass(), "of.listenPort");
818 if (portString != null) {
820 openFlowPort = Short.parseShort(portString);
821 } catch (NumberFormatException e) {
822 LOG.warn("Invalid port:{}, use default({})", portString,
829 public List<String> getControllersFromOvsdbNode(Node node) {
830 List<String> controllersStr = new ArrayList<>();
832 String controllerIpStr = getControllerIPAddress();
833 if (controllerIpStr != null) {
834 // If codepath makes it here, the ip address to be used was explicitly provided.
835 // Being so, also fetch openflowPort provided via ConfigProperties.
836 controllersStr.add(OPENFLOW_CONNECTION_PROTOCOL
837 + ":" + controllerIpStr + ":" + getControllerOFPort());
839 // Check if ovsdb node has manager entries
840 OvsdbNodeAugmentation ovsdbNodeAugmentation = extractOvsdbNode(node);
841 if (ovsdbNodeAugmentation != null) {
842 List<ManagerEntry> managerEntries = ovsdbNodeAugmentation.getManagerEntry();
843 if (managerEntries != null && !managerEntries.isEmpty()) {
844 for (ManagerEntry managerEntry : managerEntries) {
845 if (managerEntry == null || managerEntry.getTarget() == null) {
848 String[] tokens = managerEntry.getTarget().getValue().split(":");
849 if (tokens.length == 3 && tokens[0].equalsIgnoreCase("tcp")) {
850 controllersStr.add(OPENFLOW_CONNECTION_PROTOCOL
851 + ":" + tokens[1] + ":" + getControllerOFPort());
852 } else if (tokens[0].equalsIgnoreCase("ptcp")) {
853 ConnectionInfo connectionInfo = ovsdbNodeAugmentation.getConnectionInfo();
854 if (connectionInfo != null && connectionInfo.getLocalIp() != null) {
855 controllerIpStr = String.valueOf(connectionInfo.getLocalIp().getValue());
856 controllersStr.add(OPENFLOW_CONNECTION_PROTOCOL
857 + ":" + controllerIpStr + ":" + OPENFLOW_PORT);
859 LOG.warn("Ovsdb Node does not contain connection info: {}", node);
862 LOG.trace("Skipping manager entry {} for node {}",
863 managerEntry.getTarget(), node.getNodeId().getValue());
867 LOG.warn("Ovsdb Node does not contain manager entries : {}", node);
872 if (controllersStr.isEmpty()) {
873 // Neither user provided ip nor ovsdb node has manager entries. Lets use local machine ip address.
874 LOG.debug("Use local machine ip address as a OpenFlow Controller ip address");
875 controllerIpStr = getLocalControllerHostIpAddress();
876 if (controllerIpStr != null) {
877 controllersStr.add(OPENFLOW_CONNECTION_PROTOCOL
878 + ":" + controllerIpStr + ":" + OPENFLOW_PORT);
882 if (controllersStr.isEmpty()) {
883 LOG.warn("Failed to determine OpenFlow controller ip address");
884 } else if (LOG.isDebugEnabled()) {
885 controllerIpStr = "";
886 for (String currControllerIpStr : controllersStr) {
887 controllerIpStr += " " + currControllerIpStr;
889 LOG.debug("Found {} OpenFlow Controller(s) :{}", controllersStr.size(), controllerIpStr);
892 return controllersStr;
895 private String getLocalControllerHostIpAddress() {
896 String ipaddress = null;
898 for (Enumeration<NetworkInterface> ifaces = NetworkInterface.getNetworkInterfaces(); ifaces.hasMoreElements();){
899 NetworkInterface iface = ifaces.nextElement();
901 for (Enumeration<InetAddress> inetAddrs = iface.getInetAddresses(); inetAddrs.hasMoreElements();) {
902 InetAddress inetAddr = inetAddrs.nextElement();
903 if (!inetAddr.isLoopbackAddress() && inetAddr.isSiteLocalAddress()) {
904 ipaddress = inetAddr.getHostAddress();
909 }catch (Exception e){
910 LOG.warn("Exception while fetching local host ip address ", e);
915 public long getDataPathId(Node node) {
917 String datapathId = getDatapathId(node);
918 if (datapathId != null) {
919 dpid = new BigInteger(datapathId.replaceAll(":", ""), 16).longValue();
924 public String getDataPathIdStr(final Node node) {
926 long dpId = getDataPathId(node);
928 return String.valueOf(dpId);
935 public String getDatapathId(Node node) {
936 OvsdbBridgeAugmentation ovsdbBridgeAugmentation = node.getAugmentation(OvsdbBridgeAugmentation.class);
937 return getDatapathId(ovsdbBridgeAugmentation);
940 public String getDatapathId(OvsdbBridgeAugmentation ovsdbBridgeAugmentation) {
941 String datapathId = null;
942 if (ovsdbBridgeAugmentation != null && ovsdbBridgeAugmentation.getDatapathId() != null) {
943 datapathId = ovsdbBridgeAugmentation.getDatapathId().getValue();
948 public String extractBridgeName(Node node) {
949 return node.getAugmentation(OvsdbBridgeAugmentation.class).getBridgeName().getValue();
952 public boolean isBridgeOnOvsdbNode(Node ovsdbNode, String bridgeName) {
953 boolean found = false;
954 OvsdbNodeAugmentation ovsdbNodeAugmentation = extractNodeAugmentation(ovsdbNode);
955 if (ovsdbNodeAugmentation != null) {
956 List<ManagedNodeEntry> managedNodes = ovsdbNodeAugmentation.getManagedNodeEntry();
957 if (managedNodes != null) {
958 for (ManagedNodeEntry managedNode : managedNodes) {
959 InstanceIdentifier<?> bridgeIid = managedNode.getBridgeRef().getValue();
960 if (bridgeIid.toString().contains(bridgeName)) {
970 public OvsdbBridgeAugmentation getBridgeFromConfig(Node node, String bridge) {
971 OvsdbBridgeAugmentation ovsdbBridgeAugmentation = null;
972 InstanceIdentifier<Node> bridgeIid =
973 createInstanceIdentifier(node.getKey(), bridge);
974 Node bridgeNode = mdsalUtils.read(LogicalDatastoreType.CONFIGURATION, bridgeIid);
975 if (bridgeNode != null) {
976 ovsdbBridgeAugmentation = bridgeNode.getAugmentation(OvsdbBridgeAugmentation.class);
978 return ovsdbBridgeAugmentation;
981 private void setManagedByForBridge(OvsdbBridgeAugmentationBuilder ovsdbBridgeAugmentationBuilder,
982 NodeKey ovsdbNodeKey) {
983 InstanceIdentifier<Node> connectionNodePath = createInstanceIdentifier(ovsdbNodeKey.getNodeId());
984 ovsdbBridgeAugmentationBuilder.setManagedBy(new OvsdbNodeRef(connectionNodePath));
987 public boolean isOvsdbNodeDpdk(Node ovsdbNode) {
988 boolean found = false;
989 OvsdbNodeAugmentation ovsdbNodeAugmentation = extractNodeAugmentation(ovsdbNode);
990 if (ovsdbNodeAugmentation != null) {
991 List<InterfaceTypeEntry> ifTypes = ovsdbNodeAugmentation.getInterfaceTypeEntry();
992 if (ifTypes != null) {
993 for (InterfaceTypeEntry ifType : ifTypes) {
994 if (ifType.getInterfaceType().equals(InterfaceTypeDpdk.class)) {
1004 private List<ControllerEntry> createControllerEntries(List<String> controllersStr) {
1005 List<ControllerEntry> controllerEntries = new ArrayList<>();
1006 if (controllersStr != null) {
1007 for (String controllerStr : controllersStr) {
1008 ControllerEntryBuilder controllerEntryBuilder = new ControllerEntryBuilder();
1009 controllerEntryBuilder.setTarget(new Uri(controllerStr));
1010 controllerEntries.add(controllerEntryBuilder.build());
1013 return controllerEntries;
1016 public OvsdbTerminationPointAugmentation extractTerminationPointAugmentation(Node bridgeNode, String portName) {
1017 if (bridgeNode.getAugmentation(OvsdbBridgeAugmentation.class) != null) {
1018 List<OvsdbTerminationPointAugmentation> tpAugmentations = extractTerminationPointAugmentations(bridgeNode);
1019 for (OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation : tpAugmentations) {
1020 if (ovsdbTerminationPointAugmentation.getName().equals(portName)) {
1021 return ovsdbTerminationPointAugmentation;
1028 public List<OvsdbTerminationPointAugmentation> extractTerminationPointAugmentations( Node node ) {
1029 List<OvsdbTerminationPointAugmentation> tpAugmentations = new ArrayList<>();
1031 LOG.error("extractTerminationPointAugmentations: Node value is null");
1032 return Collections.<OvsdbTerminationPointAugmentation>emptyList();
1034 List<TerminationPoint> terminationPoints = node.getTerminationPoint();
1035 if(terminationPoints != null && !terminationPoints.isEmpty()){
1036 for(TerminationPoint tp : terminationPoints){
1037 OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation =
1038 tp.getAugmentation(OvsdbTerminationPointAugmentation.class);
1039 if (ovsdbTerminationPointAugmentation != null) {
1040 tpAugmentations.add(ovsdbTerminationPointAugmentation);
1044 return tpAugmentations;
1048 * Extract the <code>OvsdbTerminationPointAugmentation</code> for the particular <code>node</code> identified by
1049 * <code>portName</code>.
1055 public OvsdbTerminationPointAugmentation getTerminationPointOfBridge(Node node, String portName) {
1056 OvsdbTerminationPointAugmentation tpAugmentation = extractTerminationPointAugmentation(node,portName);
1057 if(tpAugmentation == null){
1058 List<OvsdbTerminationPointAugmentation> tpAugmentations = readTerminationPointAugmentations(node);
1059 if(tpAugmentations != null){
1060 for(OvsdbTerminationPointAugmentation ovsdbTpAugmentation : tpAugmentations){
1061 if(ovsdbTpAugmentation.getName().equals(portName)){
1062 return ovsdbTpAugmentation;
1067 return tpAugmentation;
1071 * read the list of <code>OvsdbTerminationPointAugmentation</code> for the particular <code>node</code>.
1076 public List<OvsdbTerminationPointAugmentation> readTerminationPointAugmentations(Node node) {
1078 LOG.error("readTerminationPointAugmentations: Node value is null");
1079 return Collections.<OvsdbTerminationPointAugmentation>emptyList();
1081 Node operNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, InstanceIdentifier
1082 .create(NetworkTopology.class)
1083 .child(Topology.class, new TopologyKey(OVSDB_TOPOLOGY_ID))
1084 .child(Node.class, new NodeKey(node.getNodeId())));
1085 if (operNode != null) {
1086 return extractTerminationPointAugmentations(operNode);
1088 return new ArrayList<>();
1092 * Get all OVSDB nodes from topology.
1093 * @return a list of nodes or null if the topology could not found
1095 public List<Node> getOvsdbNodes() {
1096 InstanceIdentifier<Topology> inst = InstanceIdentifier.create(NetworkTopology.class).child(Topology.class,
1097 new TopologyKey(OVSDB_TOPOLOGY_ID));
1098 Topology topology = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, inst);
1099 return topology != null ? topology.getNode() : null;
1103 * Get OpenvSwitch other-config by key.
1104 * @param node OVSDB node
1105 * @param key key to extract from other-config
1106 * @return the value for key or null if key not found
1108 public String getOpenvswitchOtherConfig(Node node, String key) {
1109 OvsdbNodeAugmentation ovsdbNode = node.getAugmentation(OvsdbNodeAugmentation.class);
1110 if (ovsdbNode == null) {
1111 Node nodeFromReadOvsdbNode = readOvsdbNode(node);
1112 if (nodeFromReadOvsdbNode != null) {
1113 ovsdbNode = nodeFromReadOvsdbNode.getAugmentation(OvsdbNodeAugmentation.class);
1117 if (ovsdbNode != null && ovsdbNode.getOpenvswitchOtherConfigs() != null) {
1118 for (OpenvswitchOtherConfigs openvswitchOtherConfigs : ovsdbNode.getOpenvswitchOtherConfigs()) {
1119 if (openvswitchOtherConfigs.getOtherConfigKey().equals(key)) {
1120 return openvswitchOtherConfigs.getOtherConfigValue();
1128 public static TerminationPoint getTerminationPointByExternalId(final Node bridgeNode, final String interfaceName) {
1129 if (bridgeNode.getTerminationPoint() != null) {
1130 for (TerminationPoint tp : bridgeNode.getTerminationPoint()) {
1131 OvsdbTerminationPointAugmentation ovsdbTp = tp.getAugmentation(OvsdbTerminationPointAugmentation.class);
1132 String externalIdValue = getExternalInterfaceIdValue(ovsdbTp);
1133 if (externalIdValue != null && externalIdValue.equals(interfaceName)) {
1134 LOG.debug("Found matching termination point with iface-id {} on bridgeNode {}, returning tp {}",
1135 interfaceName, bridgeNode, tp);
1143 // This utility shouldn't be called often, as it reads all OVSDB nodes each time - not good for scale
1144 public Node getNodeByTerminationPointExternalId(final String interfaceName) {
1145 List<Node> nodes = getOvsdbNodes();
1146 if (nodes != null) {
1147 for (Node node : nodes) {
1148 TerminationPoint tp = getTerminationPointByExternalId(node, interfaceName);
1157 public static String getExternalInterfaceIdValue(final OvsdbTerminationPointAugmentation ovsdbTp) {
1158 if (ovsdbTp != null) {
1159 List<InterfaceExternalIds> ifaceExtIds = ovsdbTp.getInterfaceExternalIds();
1160 if (ifaceExtIds != null) {
1161 for (InterfaceExternalIds entry : ifaceExtIds) {
1162 if (entry.getExternalIdKey().equals(EXTERNAL_INTERFACE_ID_KEY)) {
1163 return entry.getExternalIdValue();
1171 public String getDatapathIdFromNodeInstanceId(InstanceIdentifier<Node> nodeInstanceId) {
1172 Node node = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, nodeInstanceId);
1173 String dpId = node != null ? getDataPathIdStr(node) : null;