1 package org.opendaylight.ovsdb.neutron;
6 import org.opendaylight.controller.networkconfig.neutron.INeutronNetworkCRUD;
7 import org.opendaylight.controller.networkconfig.neutron.NeutronNetwork;
8 import org.opendaylight.controller.sal.core.Node;
9 import org.opendaylight.controller.sal.utils.ServiceHelper;
10 import org.opendaylight.controller.sal.utils.Status;
11 import org.opendaylight.controller.sal.utils.StatusCode;
12 import org.opendaylight.ovsdb.lib.notation.OvsDBMap;
13 import org.opendaylight.ovsdb.lib.notation.OvsDBSet;
14 import org.opendaylight.ovsdb.lib.notation.UUID;
15 import org.opendaylight.ovsdb.lib.table.Bridge;
16 import org.opendaylight.ovsdb.lib.table.Interface;
17 import org.opendaylight.ovsdb.lib.table.Port;
18 import org.opendaylight.ovsdb.lib.table.internal.Table;
19 import org.opendaylight.ovsdb.plugin.IConnectionServiceInternal;
20 import org.opendaylight.ovsdb.plugin.OVSDBConfigService;
21 import org.slf4j.Logger;
22 import org.slf4j.LoggerFactory;
25 * OpenStack Neutron with the OpenVswitch data plan relies on a typical OVS bridge configurations that
26 * consists of br-int (Integration Bridge), br-tun (Tunnel bridge), br-ex (External bridge).
28 * In DevStack like setups, the br-tun is not automatically created on the controller nodes.
29 * Hence this class attempts to bring all the nodes to be elibible for OpenStack operations.
32 public class InternalNetworkManager {
33 static final Logger logger = LoggerFactory.getLogger(InternalNetworkManager.class);
35 private static InternalNetworkManager internalNetwork = new InternalNetworkManager();
36 private InternalNetworkManager() {
39 public static InternalNetworkManager getManager() {
40 return internalNetwork;
43 public boolean isInternalNetworkNeutronReady(Node node) throws Exception {
44 OVSDBConfigService ovsdbTable = (OVSDBConfigService)ServiceHelper.getGlobalInstance(OVSDBConfigService.class, this);
45 Map<String, Table<?>> bridgeTable = ovsdbTable.getRows(node, Bridge.NAME.getName());
46 if (bridgeTable != null) {
47 for (Table<?> row : bridgeTable.values()) {
48 Bridge bridge = (Bridge)row;
49 if (bridge.getName().equals(AdminConfigManager.getManager().getIntegrationBridgeName())) return true;
55 public boolean isInternalNetworkOverlayReady(Node node) throws Exception {
56 OVSDBConfigService ovsdbTable = (OVSDBConfigService)ServiceHelper.getGlobalInstance(OVSDBConfigService.class, this);
57 Map<String, Table<?>> bridgeTable = ovsdbTable.getRows(node, Bridge.NAME.getName());
58 if (bridgeTable != null) {
59 for (Table<?> row : bridgeTable.values()) {
60 Bridge bridge = (Bridge)row;
61 if (bridge.getName().equals(AdminConfigManager.getManager().getTunnelBridgeName())) return true;
67 public Status createInternalNetworkForOverlay(Node node) throws Exception {
68 if (!isInternalNetworkNeutronReady(node)) {
69 logger.error("Integration Bridge is not available in Node {}", node);
70 return new Status(StatusCode.NOTACCEPTABLE, "Integration Bridge is not avaialble in Node " + node);
72 if (isInternalNetworkOverlayReady(node)) {
73 logger.error("Network Overlay Bridge is already present in Node {}", node);
74 return new Status(StatusCode.NOTACCEPTABLE, "Network Overlay Bridge is already present in Node " + node);
84 options: {peer=patch-tun}
90 OVSDBConfigService ovsdbTable = (OVSDBConfigService)ServiceHelper.getGlobalInstance(OVSDBConfigService.class, this);
91 Bridge brTun = new Bridge();
92 brTun.setName(AdminConfigManager.getManager().getTunnelBridgeName());
93 // Create br-tun bridge
94 Status status = ovsdbTable.insertRow(node, Bridge.NAME.getName(), null, brTun);
95 if (!status.isSuccess()) return status;
96 String bridgeUUID = status.getDescription();
98 IConnectionServiceInternal connectionService = (IConnectionServiceInternal)ServiceHelper.getGlobalInstance(IConnectionServiceInternal.class, this);
99 connectionService.setOFController(node, bridgeUUID);
101 Port port = new Port();
102 port.setName(brTun.getName());
103 status = ovsdbTable.insertRow(node, Port.NAME.getName(), bridgeUUID, port);
105 status = addPatchPort(node, bridgeUUID, "patch-int", "patch-tun");
106 if (!status.isSuccess()) return status;
108 // Create the corresponding patch-tun port in br-int
109 Map<String, Table<?>> bridges = ovsdbTable.getRows(node, Bridge.NAME.getName());
110 for (String brIntUUID : bridges.keySet()) {
111 Bridge brInt = (Bridge) bridges.get(brIntUUID);
112 if (brInt.getName().equalsIgnoreCase(AdminConfigManager.getManager().getIntegrationBridgeName())) {
113 return addPatchPort(node, brIntUUID, "patch-tun", "patch-int");
120 private Status addPatchPort (Node node, String bridgeUUID, String portName, String patchName) throws Exception {
121 Status status = null;
122 OVSDBConfigService ovsdbTable = (OVSDBConfigService)ServiceHelper.getGlobalInstance(OVSDBConfigService.class, this);
124 Port patchPort = new Port();
125 patchPort.setName(portName);
126 // Create patch-int port and interface
127 status = ovsdbTable.insertRow(node, Port.NAME.getName(), bridgeUUID, patchPort);
128 if (!status.isSuccess()) return status;
130 String patchPortUUID = status.getDescription();
132 String interfaceUUID = null;
134 while ((interfaceUUID == null) && (timeout > 0)) {
135 patchPort = (Port)ovsdbTable.getRow(node, Port.NAME.getName(), patchPortUUID);
136 OvsDBSet<UUID> interfaces = patchPort.getInterfaces();
137 if (interfaces == null || interfaces.size() == 0) {
138 // Wait for the OVSDB update to sync up the Local cache.
143 interfaceUUID = interfaces.toArray()[0].toString();
146 if (interfaceUUID == null) {
147 return new Status(StatusCode.INTERNALERROR);
150 Interface tunInterface = new Interface();
151 tunInterface.setType("patch");
152 OvsDBMap<String, String> options = new OvsDBMap<String, String>();
153 options.put("peer", patchName);
154 tunInterface.setOptions(options);
155 status = ovsdbTable.updateRow(node, Interface.NAME.getName(), patchPortUUID, interfaceUUID, tunInterface);
160 private void prepareInternalNetwork (NeutronNetwork network, Node node) {
161 // vlan, vxlan, and gre
162 if (network.getProviderNetworkType().equalsIgnoreCase("gre") ||
163 network.getProviderNetworkType().equalsIgnoreCase("vxlan") ||
164 network.getProviderNetworkType().equalsIgnoreCase("vlan")) {
167 if (!this.isInternalNetworkOverlayReady(node)) {
168 this.createInternalNetworkForOverlay(node);
170 } catch (Exception e) {
175 if (!this.isInternalNetworkNeutronReady(node)) {
177 // this.createInternalNetworkForNeutron(node);
179 } catch (Exception e) {
185 public void prepareInternalNetwork(NeutronNetwork network) {
186 IConnectionServiceInternal connectionService = (IConnectionServiceInternal)ServiceHelper.getGlobalInstance(IConnectionServiceInternal.class, this);
187 List<Node> nodes = connectionService.getNodes();
188 for (Node node : nodes) {
189 prepareInternalNetwork(network, node);
193 public void prepareInternalNetwork(Node node) {
194 INeutronNetworkCRUD neutronNetworkService = (INeutronNetworkCRUD)ServiceHelper.getGlobalInstance(INeutronNetworkCRUD.class, this);
195 List <NeutronNetwork> networks = neutronNetworkService.getAllNetworks();
196 for (NeutronNetwork network : networks) {
197 prepareInternalNetwork(network, node);