2 * Copyright (c) 2015 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.util.ArrayList;
18 import java.util.Enumeration;
19 import java.util.List;
22 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
23 import org.opendaylight.ovsdb.utils.config.ConfigProperties;
24 import org.opendaylight.ovsdb.utils.mdsal.utils.MdsalUtils;
25 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IetfInetUtil;
26 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
27 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6Address;
28 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.PortNumber;
29 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.DatapathId;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.DatapathTypeBase;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.InterfaceTypeBase;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.InterfaceTypeDpdk;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.InterfaceTypeDpdkr;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.InterfaceTypeDpdkvhost;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.InterfaceTypeDpdkvhostuser;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.InterfaceTypeGeneve;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.InterfaceTypeGre;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.InterfaceTypeGre64;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.InterfaceTypeInternal;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.InterfaceTypeIpsecGre;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.InterfaceTypeIpsecGre64;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.InterfaceTypeLisp;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.InterfaceTypePatch;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.InterfaceTypeSystem;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.InterfaceTypeTap;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.InterfaceTypeVxlan;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.InterfaceTypeVxlanGpe;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentation;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentationBuilder;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeName;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeProtocolBase;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeProtocolOpenflow10;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeProtocolOpenflow11;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeProtocolOpenflow12;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeProtocolOpenflow13;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeProtocolOpenflow14;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeProtocolOpenflow15;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbFailModeBase;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbNodeAugmentation;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbNodeAugmentationBuilder;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbNodeRef;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbTerminationPointAugmentation;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbTerminationPointAugmentationBuilder;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.BridgeExternalIds;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.BridgeOtherConfigs;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ControllerEntry;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ControllerEntryBuilder;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ProtocolEntry;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ProtocolEntryBuilder;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.ConnectionInfo;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.ConnectionInfoBuilder;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.ManagerEntry;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceExternalIds;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceExternalIdsBuilder;
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceExternalIdsKey;
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.Options;
78 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.OptionsBuilder;
79 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.OptionsKey;
80 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
81 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
82 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId;
83 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TpId;
84 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
85 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
86 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
87 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeBuilder;
88 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
89 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint;
90 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointBuilder;
91 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointKey;
92 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
93 import org.slf4j.Logger;
94 import org.slf4j.LoggerFactory;
96 import com.google.common.collect.ImmutableBiMap;
98 public class SouthboundUtils {
99 private static final Logger LOG = LoggerFactory.getLogger(SouthboundUtils.class);
100 private static final int OVSDB_UPDATE_TIMEOUT = 1000;
101 public static final TopologyId OVSDB_TOPOLOGY_ID = new TopologyId(new Uri("ovsdb:1"));
102 private final MdsalUtils mdsalUtils;
103 public static final String OPENFLOW_CONNECTION_PROTOCOL = "tcp";
104 public static short OPENFLOW_PORT = 6653;
105 public static final String OVSDB_URI_PREFIX = "ovsdb";
106 public static final String BRIDGE_URI_PREFIX = "bridge";
108 public SouthboundUtils(MdsalUtils mdsalUtils) {
109 this.mdsalUtils = mdsalUtils;
112 public static final ImmutableBiMap<String, Class<? extends InterfaceTypeBase>> OVSDB_INTERFACE_TYPE_MAP
113 = new ImmutableBiMap.Builder<String, Class<? extends InterfaceTypeBase>>()
114 .put("internal", InterfaceTypeInternal.class)
115 .put("vxlan", InterfaceTypeVxlan.class)
116 .put("vxlan-gpe", InterfaceTypeVxlanGpe.class)
117 .put("patch", InterfaceTypePatch.class)
118 .put("system", InterfaceTypeSystem.class)
119 .put("tap", InterfaceTypeTap.class)
120 .put("geneve", InterfaceTypeGeneve.class)
121 .put("gre", InterfaceTypeGre.class)
122 .put("ipsec_gre", InterfaceTypeIpsecGre.class)
123 .put("gre64", InterfaceTypeGre64.class)
124 .put("ipsec_gre64", InterfaceTypeIpsecGre64.class)
125 .put("lisp", InterfaceTypeLisp.class)
126 .put("dpdk", InterfaceTypeDpdk.class)
127 .put("dpdkr", InterfaceTypeDpdkr.class)
128 .put("dpdkvhost", InterfaceTypeDpdkvhost.class)
129 .put("dpdkvhostuser", InterfaceTypeDpdkvhostuser.class)
132 public static final ImmutableBiMap<Class<? extends OvsdbBridgeProtocolBase>,String> OVSDB_PROTOCOL_MAP
133 = new ImmutableBiMap.Builder<Class<? extends OvsdbBridgeProtocolBase>,String>()
134 .put(OvsdbBridgeProtocolOpenflow10.class,"OpenFlow10")
135 .put(OvsdbBridgeProtocolOpenflow11.class,"OpenFlow11")
136 .put(OvsdbBridgeProtocolOpenflow12.class,"OpenFlow12")
137 .put(OvsdbBridgeProtocolOpenflow13.class,"OpenFlow13")
138 .put(OvsdbBridgeProtocolOpenflow14.class,"OpenFlow14")
139 .put(OvsdbBridgeProtocolOpenflow15.class,"OpenFlow15")
142 public static NodeId createNodeId(IpAddress ip, PortNumber port) {
143 String uriString = OVSDB_URI_PREFIX + "://"
144 + String.valueOf(ip.getValue()) + ":" + port.getValue();
145 Uri uri = new Uri(uriString);
146 return new NodeId(uri);
149 public static Node createNode(ConnectionInfo key) {
150 NodeBuilder nodeBuilder = new NodeBuilder();
151 nodeBuilder.setNodeId(createNodeId(key.getRemoteIp(), key.getRemotePort()));
152 nodeBuilder.addAugmentation(OvsdbNodeAugmentation.class, createOvsdbAugmentation(key));
153 return nodeBuilder.build();
156 public static OvsdbNodeAugmentation createOvsdbAugmentation(ConnectionInfo key) {
157 OvsdbNodeAugmentationBuilder ovsdbNodeBuilder = new OvsdbNodeAugmentationBuilder();
158 ovsdbNodeBuilder.setConnectionInfo(key);
159 return ovsdbNodeBuilder.build();
162 public static InstanceIdentifier<Node> createInstanceIdentifier(NodeId nodeId) {
163 return InstanceIdentifier
164 .create(NetworkTopology.class)
165 .child(Topology.class, new TopologyKey(OVSDB_TOPOLOGY_ID))
166 .child(Node.class,new NodeKey(nodeId));
169 public static InstanceIdentifier<Node> createInstanceIdentifier(NodeKey ovsdbNodeKey, String bridgeName) {
170 return createInstanceIdentifier(createManagedNodeId(ovsdbNodeKey.getNodeId(), bridgeName));
173 public static NodeId createManagedNodeId(NodeId ovsdbNodeId, String bridgeName) {
174 return new NodeId(ovsdbNodeId.getValue()
175 + "/" + BRIDGE_URI_PREFIX + "/" + bridgeName);
178 public static InstanceIdentifier<Node> createInstanceIdentifier(ConnectionInfo key) {
179 return createInstanceIdentifier(key.getRemoteIp(), key.getRemotePort());
182 public static InstanceIdentifier<Node> createInstanceIdentifier(IpAddress ip, PortNumber port) {
183 InstanceIdentifier<Node> path = InstanceIdentifier
184 .create(NetworkTopology.class)
185 .child(Topology.class, new TopologyKey(OVSDB_TOPOLOGY_ID))
186 .child(Node.class,createNodeKey(ip,port));
187 LOG.debug("Created ovsdb path: {}",path);
191 public static InstanceIdentifier<Node> createInstanceIdentifier(ConnectionInfo key,OvsdbBridgeName bridgeName) {
192 return createInstanceIdentifier(createManagedNodeId(key, bridgeName));
195 public static InstanceIdentifier<Node> createInstanceIdentifier(ConnectionInfo key, String bridgeName) {
196 return createInstanceIdentifier(key, new OvsdbBridgeName(bridgeName));
199 public InstanceIdentifier<TerminationPoint> createTerminationPointInstanceIdentifier(Node node, String portName){
201 InstanceIdentifier<TerminationPoint> terminationPointPath = InstanceIdentifier
202 .create(NetworkTopology.class)
203 .child(Topology.class, new TopologyKey(OVSDB_TOPOLOGY_ID))
204 .child(Node.class,node.getKey())
205 .child(TerminationPoint.class, new TerminationPointKey(new TpId(portName)));
207 LOG.debug("Termination point InstanceIdentifier generated : {}",terminationPointPath);
208 return terminationPointPath;
211 public static NodeKey createNodeKey(IpAddress ip, PortNumber port) {
212 return new NodeKey(createNodeId(ip, port));
215 public static NodeId createManagedNodeId(ConnectionInfo key, OvsdbBridgeName bridgeName) {
216 return createManagedNodeId(key.getRemoteIp(), key.getRemotePort(), bridgeName);
219 public static NodeId createManagedNodeId(IpAddress ip, PortNumber port, OvsdbBridgeName bridgeName) {
220 return new NodeId(createNodeId(ip,port).getValue()
221 + "/" + BRIDGE_URI_PREFIX + "/" + bridgeName.getValue());
224 public static NodeId createManagedNodeId(InstanceIdentifier<Node> iid) {
225 NodeKey nodeKey = iid.firstKeyOf(Node.class);
226 return nodeKey.getNodeId();
229 public ConnectionInfo getConnectionInfo(Node ovsdbNode) {
230 ConnectionInfo connectionInfo = null;
231 OvsdbNodeAugmentation ovsdbNodeAugmentation = extractOvsdbNode(ovsdbNode);
232 if (ovsdbNodeAugmentation != null) {
233 connectionInfo = ovsdbNodeAugmentation.getConnectionInfo();
235 return connectionInfo;
238 public OvsdbNodeAugmentation extractOvsdbNode(Node node) {
239 return node.getAugmentation(OvsdbNodeAugmentation.class);
242 public static IpAddress createIpAddress(InetAddress address) {
244 if (address instanceof Inet4Address) {
245 ip = createIpAddress((Inet4Address)address);
246 } else if (address instanceof Inet6Address) {
247 ip = createIpAddress((Inet6Address)address);
252 public static IpAddress createIpAddress(Inet4Address address) {
253 return IetfInetUtil.INSTANCE.ipAddressFor(address);
256 public static IpAddress createIpAddress(Inet6Address address) {
257 Ipv6Address ipv6 = new Ipv6Address(address.getHostAddress());
258 return new IpAddress(ipv6);
261 public static ConnectionInfo getConnectionInfo(final String addressStr, final String portStr) {
262 InetAddress inetAddress = null;
264 inetAddress = InetAddress.getByName(addressStr);
265 } catch (UnknownHostException e) {
266 LOG.warn("Could not allocate InetAddress", e);
269 IpAddress address = createIpAddress(inetAddress);
270 PortNumber port = new PortNumber(Integer.parseInt(portStr));
272 LOG.info("connectionInfo: {}", new ConnectionInfoBuilder()
273 .setRemoteIp(address)
276 return new ConnectionInfoBuilder()
277 .setRemoteIp(address)
282 public static String connectionInfoToString(final ConnectionInfo connectionInfo) {
283 return String.valueOf(
284 connectionInfo.getRemoteIp().getValue()) + ":" + connectionInfo.getRemotePort().getValue();
287 public boolean addOvsdbNode(final ConnectionInfo connectionInfo) {
288 return addOvsdbNode(connectionInfo, OVSDB_UPDATE_TIMEOUT);
291 public boolean addOvsdbNode(final ConnectionInfo connectionInfo, long timeout) {
292 boolean result = mdsalUtils.put(LogicalDatastoreType.CONFIGURATION,
293 createInstanceIdentifier(connectionInfo),
294 createNode(connectionInfo));
297 Thread.sleep(timeout);
298 } catch (InterruptedException e) {
299 LOG.warn("Interrupted while waiting after adding OVSDB node {}",
300 connectionInfoToString(connectionInfo), e);
306 public Node getOvsdbNode(final ConnectionInfo connectionInfo) {
307 return mdsalUtils.read(LogicalDatastoreType.OPERATIONAL,
308 createInstanceIdentifier(connectionInfo));
311 public boolean deleteOvsdbNode(final ConnectionInfo connectionInfo) {
312 return deleteOvsdbNode(connectionInfo, OVSDB_UPDATE_TIMEOUT);
315 public boolean deleteOvsdbNode(final ConnectionInfo connectionInfo, long timeout) {
316 boolean result = mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION,
317 createInstanceIdentifier(connectionInfo));
320 Thread.sleep(timeout);
321 } catch (InterruptedException e) {
322 LOG.warn("Interrupted while waiting after deleting OVSDB node {}",
323 connectionInfoToString(connectionInfo), e);
329 public Node connectOvsdbNode(final ConnectionInfo connectionInfo) {
330 return connectOvsdbNode(connectionInfo, OVSDB_UPDATE_TIMEOUT);
333 public Node connectOvsdbNode(final ConnectionInfo connectionInfo, long timeout) {
334 addOvsdbNode(connectionInfo, timeout);
335 Node node = getOvsdbNode(connectionInfo);
336 LOG.info("Connected to {}", connectionInfoToString(connectionInfo));
340 public boolean disconnectOvsdbNode(final ConnectionInfo connectionInfo) {
341 return disconnectOvsdbNode(connectionInfo, OVSDB_UPDATE_TIMEOUT);
344 public boolean disconnectOvsdbNode(final ConnectionInfo connectionInfo, long timeout) {
345 deleteOvsdbNode(connectionInfo, timeout);
346 LOG.info("Disconnected from {}", connectionInfoToString(connectionInfo));
350 public List<ControllerEntry> createControllerEntry(String controllerTarget) {
351 List<ControllerEntry> controllerEntriesList = new ArrayList<>();
352 controllerEntriesList.add(new ControllerEntryBuilder()
353 .setTarget(new Uri(controllerTarget))
355 return controllerEntriesList;
359 * Extract the <code>store</code> type data store contents for the particular bridge identified by
360 * <code>bridgeName</code>.
362 * @param connectionInfo address for the node
363 * @param bridgeName name of the bridge
364 * @param store defined by the <code>LogicalDatastoreType</code> enumeration
365 * @return <code>store</code> type data store contents
367 public OvsdbBridgeAugmentation getBridge(ConnectionInfo connectionInfo, String bridgeName,
368 LogicalDatastoreType store) {
369 OvsdbBridgeAugmentation ovsdbBridgeAugmentation = null;
370 Node bridgeNode = getBridgeNode(connectionInfo, bridgeName, store);
371 if (bridgeNode != null) {
372 ovsdbBridgeAugmentation = bridgeNode.getAugmentation(OvsdbBridgeAugmentation.class);
374 return ovsdbBridgeAugmentation;
378 * extract the <code>LogicalDataStoreType.OPERATIONAL</code> type data store contents for the particular bridge
379 * identified by <code>bridgeName</code>
381 * @param connectionInfo address for the node
382 * @param bridgeName name of the bridge
383 * @see <code>NetvirtIT.getBridge(ConnectionInfo, String, LogicalDatastoreType)</code>
384 * @return <code>LogicalDatastoreType.OPERATIONAL</code> type data store contents
386 public OvsdbBridgeAugmentation getBridge(ConnectionInfo connectionInfo, String bridgeName) {
387 return getBridge(connectionInfo, bridgeName, LogicalDatastoreType.OPERATIONAL);
391 * Extract the node contents from <code>store</code> type data store for the
392 * bridge identified by <code>bridgeName</code>.
394 * @param connectionInfo address for the node
395 * @param bridgeName name of the bridge
396 * @param store defined by the <code>LogicalDatastoreType</code> enumeration
397 * @return <code>store</code> type data store contents
399 public Node getBridgeNode(ConnectionInfo connectionInfo, String bridgeName, LogicalDatastoreType store) {
400 InstanceIdentifier<Node> bridgeIid = createInstanceIdentifier(connectionInfo, new OvsdbBridgeName(bridgeName));
401 return mdsalUtils.read(store, bridgeIid);
404 public Node getBridgeNode(Node node, String bridgeName) {
405 OvsdbBridgeAugmentation bridge = extractBridgeAugmentation(node);
406 if (bridge != null && bridge.getBridgeName().getValue().equals(bridgeName)) {
409 return readBridgeNode(node, bridgeName);
413 public Node readBridgeNode(Node node, String name) {
414 Node ovsdbNode = node;
415 if (extractNodeAugmentation(ovsdbNode) == null) {
416 ovsdbNode = readOvsdbNode(node);
417 if (ovsdbNode == null) {
421 Node bridgeNode = null;
422 ConnectionInfo connectionInfo = getConnectionInfo(ovsdbNode);
423 if (connectionInfo != null) {
424 InstanceIdentifier<Node> bridgeIid =
425 createInstanceIdentifier(node.getKey(), name);
426 bridgeNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, bridgeIid);
431 public OvsdbNodeAugmentation extractNodeAugmentation(Node node) {
432 return node.getAugmentation(OvsdbNodeAugmentation.class);
435 public OvsdbBridgeAugmentation extractBridgeAugmentation(Node node) {
439 return node.getAugmentation(OvsdbBridgeAugmentation.class);
442 public Node readOvsdbNode(Node bridgeNode) {
443 Node ovsdbNode = null;
444 OvsdbBridgeAugmentation bridgeAugmentation = extractBridgeAugmentation(bridgeNode);
445 if (bridgeAugmentation != null) {
446 InstanceIdentifier<Node> ovsdbNodeIid =
447 (InstanceIdentifier<Node>) bridgeAugmentation.getManagedBy().getValue();
448 ovsdbNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, ovsdbNodeIid);
450 LOG.debug("readOvsdbNode: Provided node is not a bridge node : {}",bridgeNode);
455 public boolean deleteBridge(final ConnectionInfo connectionInfo, final String bridgeName) {
456 return deleteBridge(connectionInfo, bridgeName, OVSDB_UPDATE_TIMEOUT);
459 public boolean deleteBridge(final ConnectionInfo connectionInfo, final String bridgeName, long timeout) {
460 boolean result = mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION,
461 createInstanceIdentifier(connectionInfo, new OvsdbBridgeName(bridgeName)));
464 Thread.sleep(timeout);
465 } catch (InterruptedException e) {
466 LOG.warn("Interrupted while waiting after deleting bridge {}", bridgeName, e);
472 public List<ProtocolEntry> createMdsalProtocols() {
473 List<ProtocolEntry> protocolList = new ArrayList<>();
474 ImmutableBiMap<String, Class<? extends OvsdbBridgeProtocolBase>> mapper =
475 OVSDB_PROTOCOL_MAP.inverse();
476 protocolList.add(new ProtocolEntryBuilder().setProtocol(mapper.get("OpenFlow13")).build());
480 public boolean addBridge(final ConnectionInfo connectionInfo, InstanceIdentifier<Node> bridgeIid,
481 final String bridgeName, NodeId bridgeNodeId, final boolean setProtocolEntries,
482 final Class<? extends OvsdbFailModeBase> failMode, final boolean setManagedBy,
483 final Class<? extends DatapathTypeBase> dpType,
484 final List<BridgeExternalIds> externalIds,
485 final List<ControllerEntry> controllerEntries,
486 final List<BridgeOtherConfigs> otherConfigs,
487 final String dpid) throws InterruptedException {
488 return addBridge(connectionInfo, bridgeIid, bridgeName, bridgeNodeId, setProtocolEntries, failMode,
489 setManagedBy, dpType, externalIds, controllerEntries, otherConfigs, dpid);
493 * base method for adding test bridges. Other helper methods used to create bridges should utilize this method.
495 * @param connectionInfo
496 * @param bridgeIid if passed null, one is created
497 * @param bridgeName cannot be null
498 * @param bridgeNodeId if passed null, one is created based on <code>bridgeIid</code>
499 * @param setProtocolEntries toggles whether default protocol entries are set for the bridge
500 * @param failMode toggles whether default fail mode is set for the bridge
501 * @param setManagedBy toggles whether to setManagedBy for the bridge
502 * @param dpType if passed null, this parameter is ignored
503 * @param externalIds if passed null, this parameter is ignored
504 * @param otherConfig if passed null, this parameter is ignored
505 * @return success of bridge addition
506 * @throws InterruptedException
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, long timeout) throws InterruptedException {
517 NodeBuilder bridgeNodeBuilder = new NodeBuilder();
518 if (bridgeIid == null) {
519 bridgeIid = createInstanceIdentifier(connectionInfo, new OvsdbBridgeName(bridgeName));
521 if (bridgeNodeId == null) {
522 bridgeNodeId = createManagedNodeId(bridgeIid);
524 bridgeNodeBuilder.setNodeId(bridgeNodeId);
525 OvsdbBridgeAugmentationBuilder ovsdbBridgeAugmentationBuilder = new OvsdbBridgeAugmentationBuilder();
526 ovsdbBridgeAugmentationBuilder.setBridgeName(new OvsdbBridgeName(bridgeName));
527 if (setProtocolEntries) {
528 ovsdbBridgeAugmentationBuilder.setProtocolEntry(createMdsalProtocols());
530 if (failMode != null) {
531 ovsdbBridgeAugmentationBuilder.setFailMode(failMode);
534 setManagedBy(ovsdbBridgeAugmentationBuilder, connectionInfo);
536 if (dpType != null) {
537 ovsdbBridgeAugmentationBuilder.setDatapathType(dpType);
539 if (externalIds != null) {
540 ovsdbBridgeAugmentationBuilder.setBridgeExternalIds(externalIds);
542 if (controllerEntries != null) {
543 ovsdbBridgeAugmentationBuilder.setControllerEntry(controllerEntries);
545 if (otherConfigs != null) {
546 ovsdbBridgeAugmentationBuilder.setBridgeOtherConfigs(otherConfigs);
548 if (dpid != null && !dpid.isEmpty()) {
549 DatapathId datapathId = new DatapathId(dpid);
550 ovsdbBridgeAugmentationBuilder.setDatapathId(datapathId);
552 bridgeNodeBuilder.addAugmentation(OvsdbBridgeAugmentation.class, ovsdbBridgeAugmentationBuilder.build());
553 LOG.debug("Built with the intent to store bridge data {}",
554 ovsdbBridgeAugmentationBuilder.toString());
555 boolean result = mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION,
556 bridgeIid, bridgeNodeBuilder.build());
558 Thread.sleep(OVSDB_UPDATE_TIMEOUT);
563 private void setManagedBy(final OvsdbBridgeAugmentationBuilder ovsdbBridgeAugmentationBuilder,
564 final ConnectionInfo connectionInfo) {
565 InstanceIdentifier<Node> connectionNodePath = createInstanceIdentifier(connectionInfo);
566 ovsdbBridgeAugmentationBuilder.setManagedBy(new OvsdbNodeRef(connectionNodePath));
569 public boolean addTerminationPoint(
570 Node bridgeNode, String portName, String type, Map<String, String> options,
571 Map<String, String> externalIds) {
572 return addTerminationPoint(bridgeNode, portName, type, options, externalIds, null);
575 public boolean addTerminationPoint(
576 Node bridgeNode, String portName, String type, Map<String, String> options, Map<String, String> externalIds,
578 InstanceIdentifier<TerminationPoint> tpIid = createTerminationPointInstanceIdentifier(bridgeNode, portName);
579 OvsdbTerminationPointAugmentationBuilder tpAugmentationBuilder = new OvsdbTerminationPointAugmentationBuilder();
581 tpAugmentationBuilder.setName(portName);
582 tpAugmentationBuilder.setOfport(ofPort);
584 tpAugmentationBuilder.setInterfaceType(OVSDB_INTERFACE_TYPE_MAP.get(type));
587 if (options != null && options.size() > 0) {
588 List<Options> optionsList = new ArrayList<>();
589 for (Map.Entry<String, String> entry : options.entrySet()) {
590 OptionsBuilder optionsBuilder = new OptionsBuilder();
591 optionsBuilder.setKey(new OptionsKey(entry.getKey()));
592 optionsBuilder.setOption(entry.getKey());
593 optionsBuilder.setValue(entry.getValue());
594 optionsList.add(optionsBuilder.build());
596 tpAugmentationBuilder.setOptions(optionsList);
599 if (externalIds != null && externalIds.size() > 0) {
600 List<InterfaceExternalIds> externalIdsList = new ArrayList<>();
601 for (Map.Entry<String, String> entry : externalIds.entrySet()) {
602 InterfaceExternalIdsBuilder interfaceExternalIdsBuilder = new InterfaceExternalIdsBuilder();
603 interfaceExternalIdsBuilder.setKey(new InterfaceExternalIdsKey(entry.getKey()));
604 interfaceExternalIdsBuilder.setExternalIdKey(entry.getKey());
605 interfaceExternalIdsBuilder.setExternalIdValue(entry.getValue());
606 externalIdsList.add(interfaceExternalIdsBuilder.build());
608 tpAugmentationBuilder.setInterfaceExternalIds(externalIdsList);
611 TerminationPointBuilder tpBuilder = new TerminationPointBuilder();
612 tpBuilder.setKey(InstanceIdentifier.keyOf(tpIid));
613 tpBuilder.addAugmentation(OvsdbTerminationPointAugmentation.class, tpAugmentationBuilder.build());
614 /* TODO SB_MIGRATION should this be merge or mdsalUtils.put */
615 return mdsalUtils.put(LogicalDatastoreType.CONFIGURATION, tpIid, tpBuilder.build());
618 public Boolean addTerminationPoint(Node bridgeNode, String portName, String type) {
619 return addTerminationPoint(bridgeNode, portName, type, null, null);
622 private String getControllerIPAddress() {
623 String addressString = ConfigProperties.getProperty(this.getClass(), "ovsdb.controller.address");
624 if (addressString != null) {
626 if (InetAddress.getByName(addressString) != null) {
627 return addressString;
629 } catch (UnknownHostException e) {
630 LOG.error("Host {} is invalid", addressString, e);
634 addressString = ConfigProperties.getProperty(this.getClass(), "of.address");
635 if (addressString != null) {
637 if (InetAddress.getByName(addressString) != null) {
638 return addressString;
640 } catch (UnknownHostException e) {
641 LOG.error("Host {} is invalid", addressString, e);
648 private short getControllerOFPort() {
649 short openFlowPort = OPENFLOW_PORT;
650 String portString = ConfigProperties.getProperty(this.getClass(), "of.listenPort");
651 if (portString != null) {
653 openFlowPort = Short.parseShort(portString);
654 } catch (NumberFormatException e) {
655 LOG.warn("Invalid port:{}, use default({})", portString,
662 public List<String> getControllersFromOvsdbNode(Node node) {
663 List<String> controllersStr = new ArrayList<>();
665 String controllerIpStr = getControllerIPAddress();
666 if (controllerIpStr != null) {
667 // If codepath makes it here, the ip address to be used was explicitly provided.
668 // Being so, also fetch openflowPort provided via ConfigProperties.
669 controllersStr.add(OPENFLOW_CONNECTION_PROTOCOL
670 + ":" + controllerIpStr + ":" + getControllerOFPort());
672 // Check if ovsdb node has manager entries
673 OvsdbNodeAugmentation ovsdbNodeAugmentation = extractOvsdbNode(node);
674 if (ovsdbNodeAugmentation != null) {
675 List<ManagerEntry> managerEntries = ovsdbNodeAugmentation.getManagerEntry();
676 if (managerEntries != null && !managerEntries.isEmpty()) {
677 for (ManagerEntry managerEntry : managerEntries) {
678 if (managerEntry == null || managerEntry.getTarget() == null) {
681 String[] tokens = managerEntry.getTarget().getValue().split(":");
682 if (tokens.length == 3 && tokens[0].equalsIgnoreCase("tcp")) {
683 controllersStr.add(OPENFLOW_CONNECTION_PROTOCOL
684 + ":" + tokens[1] + ":" + getControllerOFPort());
685 } else if (tokens[0].equalsIgnoreCase("ptcp")) {
686 ConnectionInfo connectionInfo = ovsdbNodeAugmentation.getConnectionInfo();
687 if (connectionInfo != null && connectionInfo.getLocalIp() != null) {
688 controllerIpStr = String.valueOf(connectionInfo.getLocalIp().getValue());
689 controllersStr.add(OPENFLOW_CONNECTION_PROTOCOL
690 + ":" + controllerIpStr + ":" + OPENFLOW_PORT);
692 LOG.warn("Ovsdb Node does not contain connection info: {}", node);
695 LOG.trace("Skipping manager entry {} for node {}",
696 managerEntry.getTarget(), node.getNodeId().getValue());
700 LOG.warn("Ovsdb Node does not contain manager entries : {}", node);
705 if (controllersStr.isEmpty()) {
706 // Neither user provided ip nor ovsdb node has manager entries. Lets use local machine ip address.
707 LOG.debug("Use local machine ip address as a OpenFlow Controller ip address");
708 controllerIpStr = getLocalControllerHostIpAddress();
709 if (controllerIpStr != null) {
710 controllersStr.add(OPENFLOW_CONNECTION_PROTOCOL
711 + ":" + controllerIpStr + ":" + OPENFLOW_PORT);
715 if (controllersStr.isEmpty()) {
716 LOG.warn("Failed to determine OpenFlow controller ip address");
717 } else if (LOG.isDebugEnabled()) {
718 controllerIpStr = "";
719 for (String currControllerIpStr : controllersStr) {
720 controllerIpStr += " " + currControllerIpStr;
722 LOG.debug("Found {} OpenFlow Controller(s) :{}", controllersStr.size(), controllerIpStr);
725 return controllersStr;
728 private String getLocalControllerHostIpAddress() {
729 String ipaddress = null;
731 for (Enumeration<NetworkInterface> ifaces = NetworkInterface.getNetworkInterfaces(); ifaces.hasMoreElements();){
732 NetworkInterface iface = ifaces.nextElement();
734 for (Enumeration<InetAddress> inetAddrs = iface.getInetAddresses(); inetAddrs.hasMoreElements();) {
735 InetAddress inetAddr = inetAddrs.nextElement();
736 if (!inetAddr.isLoopbackAddress() && inetAddr.isSiteLocalAddress()) {
737 ipaddress = inetAddr.getHostAddress();
742 }catch (Exception e){
743 LOG.warn("Exception while fetching local host ip address ", e);
748 public long getDataPathId(Node node) {
750 String datapathId = getDatapathId(node);
751 if (datapathId != null) {
752 dpid = new BigInteger(datapathId.replaceAll(":", ""), 16).longValue();
757 public String getDatapathId(Node node) {
758 OvsdbBridgeAugmentation ovsdbBridgeAugmentation = node.getAugmentation(OvsdbBridgeAugmentation.class);
759 return getDatapathId(ovsdbBridgeAugmentation);
762 public String getDatapathId(OvsdbBridgeAugmentation ovsdbBridgeAugmentation) {
763 String datapathId = null;
764 if (ovsdbBridgeAugmentation != null && ovsdbBridgeAugmentation.getDatapathId() != null) {
765 datapathId = ovsdbBridgeAugmentation.getDatapathId().getValue();