Merge "BUG-6017 java.lang.NullPointerException at org.opendaylight.ovsdb.openstack...
[netvirt.git] / openstack / net-virt / src / main / java / org / opendaylight / netvirt / openstack / netvirt / impl / BridgeConfigurationManagerImpl.java
1 /*
2  * Copyright (c) 2013, 2015 Red Hat, Inc. and others. All rights reserved.
3  *
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
7  */
8
9 package org.opendaylight.netvirt.openstack.netvirt.impl;
10
11 import org.opendaylight.netvirt.openstack.netvirt.NetworkHandler;
12 import org.opendaylight.netvirt.openstack.netvirt.api.OvsdbTables;
13 import org.opendaylight.netvirt.openstack.netvirt.translator.NeutronNetwork;
14 import org.opendaylight.netvirt.openstack.netvirt.ConfigInterface;
15 import org.opendaylight.netvirt.openstack.netvirt.api.BridgeConfigurationManager;
16 import org.opendaylight.netvirt.openstack.netvirt.api.ConfigurationService;
17 import org.opendaylight.netvirt.openstack.netvirt.api.Constants;
18 import org.opendaylight.netvirt.openstack.netvirt.api.NetworkingProviderManager;
19 import org.opendaylight.netvirt.openstack.netvirt.api.Southbound;
20 import org.opendaylight.netvirt.utils.config.ConfigProperties;
21 import org.opendaylight.netvirt.utils.servicehelper.ServiceHelper;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.DatapathTypeBase;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.DatapathTypeNetdev;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbNodeAugmentation;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.ConnectionInfo;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.ManagerEntry;
27 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
28
29 import com.google.common.base.Preconditions;
30 import com.google.common.collect.Lists;
31
32 import java.net.InetAddress;
33 import java.net.NetworkInterface;
34 import java.net.UnknownHostException;
35 import java.util.ArrayList;
36 import java.util.Enumeration;
37 import java.util.List;
38 import java.util.Random;
39
40 import org.apache.commons.lang3.tuple.ImmutablePair;
41 import org.osgi.framework.ServiceReference;
42 import org.slf4j.Logger;
43 import org.slf4j.LoggerFactory;
44
45 /**
46  * @author Madhu Venugopal
47  * @author Brent Salisbury
48  * @author Sam Hague (shague@redhat.com)
49  */
50 public class BridgeConfigurationManagerImpl implements BridgeConfigurationManager, ConfigInterface {
51     private static final Logger LOG = LoggerFactory.getLogger(BridgeConfigurationManagerImpl.class);
52
53     // The implementation for each of these services is resolved by the OSGi Service Manager
54     private volatile ConfigurationService configurationService;
55     private volatile NetworkingProviderManager networkingProviderManager;
56     private volatile Southbound southbound;
57     private boolean intBridgeGenMac;
58     private Random random;
59
60     public BridgeConfigurationManagerImpl() {
61         this(true);
62     }
63
64     public BridgeConfigurationManagerImpl(boolean intBridgeGenMac) {
65         this.intBridgeGenMac = intBridgeGenMac;
66         this.random = new Random(System.currentTimeMillis());
67     }
68
69     public void setConfigurationService(ConfigurationService configurationService) {
70         this.configurationService = configurationService;
71     }
72
73     public void setSouthbound(Southbound southbound) {
74         this.southbound = southbound;
75     }
76
77     @Override
78     public String getBridgeUuid(Node node, String bridgeName) {
79         return southbound.getBridgeUuid(node, bridgeName);
80     }
81
82     @Override
83     public boolean isNodeNeutronReady(Node node) {
84         Preconditions.checkNotNull(configurationService);
85         return southbound.getBridge(node, configurationService.getIntegrationBridgeName()) != null;
86     }
87
88     @Override
89     public boolean isNodeOverlayReady(Node node) {
90         Preconditions.checkNotNull(configurationService);
91         return isNodeNeutronReady(node)
92                 && southbound.getBridge(node, configurationService.getNetworkBridgeName()) != null;
93     }
94
95     @Override
96     public boolean isPortOnBridge (Node bridgeNode, String portName) {
97         return southbound.extractTerminationPointAugmentation(bridgeNode, portName) != null;
98     }
99
100     @Override
101     public boolean isNodeTunnelReady(Node bridgeNode, Node ovsdbNode) {
102         Preconditions.checkNotNull(configurationService);
103         if (!southbound.isBridgeOnOvsdbNode(ovsdbNode, configurationService.getIntegrationBridgeName())) {
104             LOG.trace("isNodeTunnelReady: node: {}, {} missing",
105                     bridgeNode, configurationService.getIntegrationBridgeName());
106             return false;
107         }
108
109         return isNodeL3Ready(bridgeNode, ovsdbNode);
110     }
111
112     @Override
113     public boolean isNodeVlanReady(Node bridgeNode, Node ovsdbNode, NeutronNetwork network) {
114         Preconditions.checkNotNull(configurationService);
115
116         final String brInt = configurationService.getIntegrationBridgeName();
117         if (!southbound.isBridgeOnOvsdbNode(ovsdbNode, brInt)) {
118             LOG.trace("isNodeVlanReady: node: {}, {} missing", bridgeNode, brInt);
119             return false;
120         }
121
122         /* Check if physical device is added to br-int. */
123         String phyNetName = getPhysicalInterfaceName(ovsdbNode, network.getProviderPhysicalNetwork());
124         if (!isPortOnBridge(bridgeNode, phyNetName)) {
125             LOG.trace("isNodeVlanReady: node: {}, eth missing", bridgeNode);
126             return false;
127         }
128
129         return isNodeL3Ready(bridgeNode, ovsdbNode);
130     }
131
132     public boolean isNodeL3Ready(Node bridgeNode, Node ovsdbNode) {
133         Preconditions.checkNotNull(configurationService);
134         boolean ready = false;
135         if (configurationService.isL3ForwardingEnabled()) {
136             final String brInt = configurationService.getIntegrationBridgeName();
137             final String brExt = configurationService.getExternalBridgeName();
138             final String portNameInt = configurationService.getPatchPortName(new ImmutablePair<>(brInt, brExt));
139             final String portNameExt = configurationService.getPatchPortName(new ImmutablePair<>(brExt, brInt));
140             Preconditions.checkNotNull(portNameInt);
141             Preconditions.checkNotNull(portNameExt);
142
143             if (southbound.isBridgeOnOvsdbNode(ovsdbNode, brExt)) {
144                 ready = isNetworkPatchCreated(bridgeNode, southbound.readBridgeNode(ovsdbNode, brExt));
145             } else {
146                 LOG.trace("isNodeL3Ready: node: {}, {} missing",
147                         bridgeNode, brExt);
148             }
149         } else {
150             ready = true;
151         }
152         return ready;
153     }
154
155     @Override
156     public void prepareNode(Node ovsdbNode) {
157         Preconditions.checkNotNull(configurationService);
158
159         try {
160             createIntegrationBridge(ovsdbNode);
161         } catch (Exception e) {
162             LOG.error("Error creating Integration Bridge on {}", ovsdbNode, e);
163             return;
164         }
165
166         try {
167             if (configurationService.isL3ForwardingEnabled()) {
168                 createExternalBridge(ovsdbNode);
169             }
170         } catch (Exception e) {
171             LOG.error("Error creating External Bridge on {}", ovsdbNode, e);
172             return;
173         }
174         // this node is an ovsdb node so it doesn't have a bridge
175         // so either look up the bridges or just wait for the bridge update to come in
176         // and add the flows there.
177         //networkingProviderManager.getProvider(node).initializeFlowRules(node);
178     }
179
180     /**
181      * Check if the full network setup is available. If not, create it.
182      */
183     @Override
184     public boolean createLocalNetwork (Node bridgeNode, NeutronNetwork network) {
185         boolean isCreated = false;
186         Node ovsdbNode = southbound.readOvsdbNode(bridgeNode);
187         if (ovsdbNode == null) {
188             //this should never happen
189             LOG.error("createLocalNetwork could not find ovsdbNode from bridge node {}", bridgeNode);
190             return false;
191         }
192         if (network.getProviderNetworkType().equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_VLAN)) {
193             if (!isNodeVlanReady(bridgeNode, ovsdbNode, network)) {
194                 try {
195                     isCreated = createBridges(bridgeNode, ovsdbNode, network);
196                 } catch (Exception e) {
197                     LOG.error("Error creating internal vlan net network {}--{}", bridgeNode, network, e);
198                 }
199             } else {
200                 isCreated = true;
201             }
202         } else if (network.getProviderNetworkType().equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_VXLAN) ||
203                    network.getProviderNetworkType().equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_GRE)) {
204             if (!isNodeTunnelReady(bridgeNode, ovsdbNode)) {
205                 try {
206                     isCreated = createBridges(bridgeNode, ovsdbNode, network);
207                 } catch (Exception e) {
208                     LOG.error("Error creating internal vxlan/gre net network {}--{}", bridgeNode, network, e);
209                 }
210             } else {
211                 isCreated = true;
212             }
213         }
214         return isCreated;
215     }
216
217
218
219     @Override
220     public String getExternalInterfaceName (Node node, String extNetwork) {
221         String phyIf = null;
222         String providerMaps = southbound.getOtherConfig(node, OvsdbTables.OPENVSWITCH,
223                 configurationService.getProviderMappingsKey());
224         if (providerMaps != null) {
225             for (String map : providerMaps.split(",")) {
226                 String[] pair = map.split(":");
227                 if (pair[0].equals(extNetwork)) {
228                     phyIf = pair[1];
229                     break;
230                 }
231             }
232         }
233         if (phyIf == null) {
234             LOG.error("External interface not found for Node: {}, Network {}",
235                     node, extNetwork);
236         }
237         else {
238             LOG.info("External interface found for Node: {}, Network {} is {}",node,extNetwork,phyIf);
239         }
240         return phyIf;
241     }
242
243
244
245     @Override
246     public String getPhysicalInterfaceName (Node node, String physicalNetwork) {
247         String phyIf = null;
248         String providerMaps = southbound.getOtherConfig(node, OvsdbTables.OPENVSWITCH,
249                 configurationService.getProviderMappingsKey());
250         if (providerMaps == null) {
251             providerMaps = configurationService.getDefaultProviderMapping();
252         }
253
254         if (providerMaps != null) {
255             for (String map : providerMaps.split(",")) {
256                 String[] pair = map.split(":");
257                 if (pair[0].equals(physicalNetwork)) {
258                     phyIf = pair[1];
259                     break;
260                 }
261             }
262         }
263
264         if (phyIf == null) {
265             LOG.error("Physical interface not found for Node: {}, Network {}",
266                     node, physicalNetwork);
267         }
268
269         return phyIf;
270     }
271
272     @Override
273     public List<String> getAllPhysicalInterfaceNames(Node node) {
274         List<String> phyIfName = Lists.newArrayList();
275         String providerMaps = southbound.getOtherConfig(node, OvsdbTables.OPENVSWITCH,
276                 configurationService.getProviderMappingsKey());
277         if (providerMaps == null) {
278             providerMaps = configurationService.getDefaultProviderMapping();
279         }
280
281         if (providerMaps != null) {
282             for (String map : providerMaps.split(",")) {
283                 String[] pair = map.split(":");
284                 phyIfName.add(pair[1]);
285             }
286         }
287
288         return phyIfName;
289     }
290
291     /**
292      * Returns true if a patch port exists between the Integration Bridge and Network Bridge
293      */
294     private boolean isNetworkPatchCreated(Node intBridge, Node netBridge) {
295         Preconditions.checkNotNull(configurationService);
296
297         boolean isPatchCreated = false;
298
299         String portName = configurationService.getPatchPortName(new ImmutablePair<>(intBridge, netBridge));
300         if (isPortOnBridge(intBridge, portName)) {
301             portName = configurationService.getPatchPortName(new ImmutablePair<>(netBridge, intBridge));
302             if (isPortOnBridge(netBridge, portName)) {
303                 isPatchCreated = true;
304             }
305         }
306
307         return isPatchCreated;
308     }
309
310     /**
311      * Creates the Integration Bridge
312      */
313     private boolean createIntegrationBridge(Node ovsdbNode) {
314         Preconditions.checkNotNull(configurationService);
315
316         if (!addBridge(ovsdbNode, configurationService.getIntegrationBridgeName(),
317                                             intBridgeGenMac ? generateRandomMac() : null)) {
318             LOG.debug("Integration Bridge Creation failed");
319             return false;
320         }
321         return true;
322     }
323
324     private String generateRandomMac() {
325         byte[] macBytes = new byte[6];
326         random.nextBytes(macBytes);
327         macBytes[0] &= 0xfc; //the two low bits of the first byte need to be zero
328
329         StringBuilder stringBuilder = new StringBuilder();
330
331         int i = 0;
332         while(true) {
333             stringBuilder.append(String.format("%02x", macBytes[i++]));
334             if (i >= 6) {
335                 break;
336             }
337             stringBuilder.append(':');
338         }
339
340         return stringBuilder.toString();
341     }
342
343     private boolean createExternalBridge(Node ovsdbNode) {
344         Preconditions.checkNotNull(configurationService);
345
346         if (!addBridge(ovsdbNode, configurationService.getExternalBridgeName(), null)) {
347             LOG.debug("External Bridge Creation failed");
348             return false;
349         }
350         return true;
351     }
352
353     /**
354      * Create and configure bridges for all network types and OpenFlow versions.
355      *
356        OF 1.0 vlan:
357        Bridge br-int
358             Port patch-net
359                 Interface patch-net
360                     type: patch
361                     options: {peer=patch-int}
362             Port br-int
363                 Interface br-int
364                     type: internal
365        Bridge br-net
366             Port "eth1"
367                 Interface "eth1"
368             Port patch-int
369                 Interface patch-int
370                     type: patch
371                     options: {peer=patch-net}
372             Port br-net
373                 Interface br-net
374                     type: internal
375
376        OF 1.0 tunnel:
377        Bridge br-int
378             Port patch-net
379                 Interface patch-net
380                     type: patch
381                     options: {peer=patch-int}
382             Port br-int
383                 Interface br-int
384                     type: internal
385        Bridge "br-net"
386             Port patch-int
387                 Interface patch-int
388                     type: patch
389                     options: {peer=patch-net}
390             Port br-net
391                 Interface br-net
392                     type: internal
393
394        OF 1.3 vlan:
395        Bridge br-int
396             Port "eth1"
397                 Interface "eth1"
398             Port br-int
399                 Interface br-int
400                     type: internal
401
402        OF 1.3 tunnel:
403        Bridge br-int
404             Port br-int
405                 Interface br-int
406                     type: internal
407      */
408     private boolean createBridges(Node bridgeNode, Node ovsdbNode, NeutronNetwork network) {
409         Preconditions.checkNotNull(configurationService);
410         Preconditions.checkNotNull(networkingProviderManager);
411
412         LOG.debug("createBridges: node: {}, network type: {}", bridgeNode, network.getProviderNetworkType());
413
414         final String brInt = configurationService.getIntegrationBridgeName();
415         if (! createIntegrationBridge(ovsdbNode)) {
416             LOG.debug("{} Bridge creation failed", brInt);
417             return false;
418         }
419
420         if (configurationService.isL3ForwardingEnabled()) {
421             final String brExt = configurationService.getExternalBridgeName();
422             if (! createExternalBridge(ovsdbNode)) {
423                 LOG.error("{} Bridge creation failed", brExt);
424                 return false;
425             }
426
427             //get two patch port names
428             final String portNameInt = configurationService.getPatchPortName(new ImmutablePair<>(brInt, brExt));
429             final String portNameExt = configurationService.getPatchPortName(new ImmutablePair<>(brExt, brInt));
430             Preconditions.checkNotNull(portNameInt);
431             Preconditions.checkNotNull(portNameExt);
432
433             if (!addPatchPort(bridgeNode, brInt, portNameInt, portNameExt)) {
434                 LOG.error("Add Port {} to Bridge {} failed", portNameInt, brInt);
435                 return false;
436             }
437             Node extBridgeNode = southbound.readBridgeNode(ovsdbNode, brExt);
438             Preconditions.checkNotNull(extBridgeNode, "br-ex cannot be null or empty!");
439             if (!addPatchPort(extBridgeNode, brExt, portNameExt, portNameInt)) {
440                 LOG.error("Add Port {} to Bridge {} failed", portNameExt, brExt);
441                 return false;
442             }
443             String extNetName = getExternalInterfaceName(extBridgeNode, brExt);
444             if ( extNetName != null) {
445                 if (!addPortToBridge(extBridgeNode, brExt, extNetName)) {
446                     LOG.error("Add External Port {} to Bridge {} failed", extNetName, brExt);
447                     return false;
448                 }
449             LOG.info("Add External Port {} to Ext Bridge {} success", extNetName, brExt);
450             }
451         }
452         /* For vlan network types add physical port to br-int. */
453         if (network.getProviderNetworkType().equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_VLAN)) {
454             String phyNetName = this.getPhysicalInterfaceName(bridgeNode, network.getProviderPhysicalNetwork());
455             if (!addPortToBridge(bridgeNode, brInt, phyNetName)) {
456                 LOG.debug("Add Port {} to Bridge {} failed", phyNetName, brInt);
457                 return false;
458             }
459         }
460
461         LOG.info("createBridges: node: {}, status: success", bridgeNode);
462         return true;
463     }
464
465     /**
466      * Add a Port to a Bridge
467      */
468     private boolean addPortToBridge (Node node, String bridgeName, String portName) {
469         boolean rv = true;
470
471         if (southbound.extractTerminationPointAugmentation(node, portName) == null) {
472             rv = southbound.addTerminationPoint(node, bridgeName, portName, null);
473
474             if (rv) {
475                 LOG.info("addPortToBridge: node: {}, bridge: {}, portname: {} status: success",
476                         node.getNodeId().getValue(), bridgeName, portName);
477             } else {
478                 LOG.error("addPortToBridge: node: {}, bridge: {}, portname: {} status: FAILED",
479                         node.getNodeId().getValue(), bridgeName, portName);
480             }
481         } else {
482             LOG.trace("addPortToBridge: node: {}, bridge: {}, portname: {} status: not_needed",
483                     node.getNodeId().getValue(), bridgeName, portName);
484         }
485
486         return rv;
487     }
488
489     /**
490      * Add a Patch Port to a Bridge
491      */
492     private boolean addPatchPort (Node node, String bridgeName, String portName, String peerPortName) {
493         boolean rv = true;
494
495         if (southbound.extractTerminationPointAugmentation(node, portName) == null) {
496             rv = southbound.addPatchTerminationPoint(node, bridgeName, portName, peerPortName);
497
498             if (rv) {
499                 LOG.info("addPatchPort: node: {}, bridge: {}, portname: {} peer: {} status: success",
500                         node.getNodeId().getValue(), bridgeName, portName, peerPortName);
501             } else {
502                 LOG.error("addPatchPort: node: {}, bridge: {}, portname: {} peer: {} status: FAILED",
503                         node.getNodeId().getValue(), bridgeName, portName, peerPortName);
504             }
505         } else {
506             LOG.trace("addPatchPort: node: {}, bridge: {}, portname: {} peer: {} status: not_needed",
507                     node.getNodeId().getValue(), bridgeName, portName, peerPortName);
508         }
509
510         return rv;
511     }
512
513     /**
514      * Add Bridge to a Node
515      */
516     private boolean addBridge(Node ovsdbNode, String bridgeName, String mac) {
517         boolean rv = true;
518         if ((!southbound.isBridgeOnOvsdbNode(ovsdbNode, bridgeName)) ||
519                 (southbound.getBridgeFromConfig(ovsdbNode, bridgeName) == null)) {
520             Class<? extends DatapathTypeBase> dpType = null;
521             if (configurationService.isUserSpaceEnabled()) {
522                 dpType = DatapathTypeNetdev.class;
523             }
524             rv = southbound.addBridge(ovsdbNode, bridgeName, getControllersFromOvsdbNode(ovsdbNode), dpType, mac);
525         }
526         return rv;
527     }
528
529     private String getControllerIPAddress() {
530         String addressString = ConfigProperties.getProperty(this.getClass(), "ovsdb.controller.address");
531         if (addressString != null) {
532             try {
533                 if (InetAddress.getByName(addressString) != null) {
534                     return addressString;
535                 }
536             } catch (UnknownHostException e) {
537                 LOG.error("Host {} is invalid", addressString, e);
538             }
539         }
540
541         addressString = ConfigProperties.getProperty(this.getClass(), "of.address");
542         if (addressString != null) {
543             try {
544                 if (InetAddress.getByName(addressString) != null) {
545                     return addressString;
546                 }
547             } catch (UnknownHostException e) {
548                 LOG.error("Host {} is invalid", addressString, e);
549             }
550         }
551
552         return null;
553     }
554
555     private short getControllerOFPort() {
556         short openFlowPort = Constants.OPENFLOW_PORT;
557         String portString = ConfigProperties.getProperty(this.getClass(), "of.listenPort");
558         if (portString != null) {
559             try {
560                 openFlowPort = Short.parseShort(portString);
561             } catch (NumberFormatException e) {
562                 LOG.warn("Invalid port:{}, use default({})", portString,
563                         openFlowPort, e);
564             }
565         }
566         return openFlowPort;
567     }
568
569     public List<String> getControllersFromOvsdbNode(Node node) {
570         List<String> controllersStr = new ArrayList<>();
571
572         String controllerIpStr = getControllerIPAddress();
573         if (controllerIpStr != null) {
574             // If codepath makes it here, the ip address to be used was explicitly provided.
575             // Being so, also fetch openflowPort provided via ConfigProperties.
576             controllersStr.add(Constants.OPENFLOW_CONNECTION_PROTOCOL
577                     + ":" + controllerIpStr + ":" + getControllerOFPort());
578         } else {
579             // Check if ovsdb node has manager entries
580             OvsdbNodeAugmentation ovsdbNodeAugmentation = southbound.extractOvsdbNode(node);
581             if (ovsdbNodeAugmentation != null) {
582                 List<ManagerEntry> managerEntries = ovsdbNodeAugmentation.getManagerEntry();
583                 if (managerEntries != null && !managerEntries.isEmpty()) {
584                     for (ManagerEntry managerEntry : managerEntries) {
585                         if (managerEntry == null || managerEntry.getTarget() == null) {
586                             continue;
587                         }
588                         String[] tokens = managerEntry.getTarget().getValue().split(":");
589                         if (tokens.length == 3 && tokens[0].equalsIgnoreCase("tcp")) {
590                             controllersStr.add(Constants.OPENFLOW_CONNECTION_PROTOCOL
591                                     + ":" + tokens[1] + ":" + getControllerOFPort());
592                         } else if (tokens[0].equalsIgnoreCase("ptcp")) {
593                             ConnectionInfo connectionInfo = ovsdbNodeAugmentation.getConnectionInfo();
594                             if (connectionInfo != null && connectionInfo.getLocalIp() != null) {
595                                 controllerIpStr = String.valueOf(connectionInfo.getLocalIp().getValue());
596                                 controllersStr.add(Constants.OPENFLOW_CONNECTION_PROTOCOL
597                                         + ":" + controllerIpStr + ":" + Constants.OPENFLOW_PORT);
598                             } else {
599                                 LOG.warn("Ovsdb Node does not contain connection info: {}", node);
600                             }
601                         } else {
602                             LOG.trace("Skipping manager entry {} for node {}",
603                                     managerEntry.getTarget(), node.getNodeId().getValue());
604                         }
605                     }
606                 } else {
607                     LOG.warn("Ovsdb Node does not contain manager entries : {}", node);
608                 }
609             }
610         }
611
612         if (controllersStr.isEmpty()) {
613             // Neither user provided ip nor ovsdb node has manager entries. Lets use local machine ip address.
614             LOG.debug("Use local machine ip address as a OpenFlow Controller ip address");
615             controllerIpStr = getLocalControllerHostIpAddress();
616             if (controllerIpStr != null) {
617                 controllersStr.add(Constants.OPENFLOW_CONNECTION_PROTOCOL
618                         + ":" + controllerIpStr + ":" + Constants.OPENFLOW_PORT);
619             }
620         }
621
622         if (controllersStr.isEmpty()) {
623             LOG.warn("Failed to determine OpenFlow controller ip address");
624         } else if (LOG.isDebugEnabled()) {
625             controllerIpStr = "";
626             for (String currControllerIpStr : controllersStr) {
627                 controllerIpStr += " " + currControllerIpStr;
628             }
629             LOG.debug("Found {} OpenFlow Controller(s) :{}", controllersStr.size(), controllerIpStr);
630         }
631
632         return controllersStr;
633     }
634
635     private String getLocalControllerHostIpAddress() {
636         String ipaddress = null;
637         try{
638             for (Enumeration<NetworkInterface> ifaces = NetworkInterface.getNetworkInterfaces();ifaces.hasMoreElements();){
639                 NetworkInterface iface = ifaces.nextElement();
640
641                 for (Enumeration<InetAddress> inetAddrs = iface.getInetAddresses(); inetAddrs.hasMoreElements();) {
642                     InetAddress inetAddr = inetAddrs.nextElement();
643                     if (!inetAddr.isLoopbackAddress() && inetAddr.isSiteLocalAddress()) {
644                         ipaddress = inetAddr.getHostAddress();
645                         break;
646                     }
647                 }
648             }
649         }catch (Exception e){
650             LOG.warn("Exception while fetching local host ip address ", e);
651         }
652         return ipaddress;
653     }
654
655     @Override
656     public void setDependencies(ServiceReference serviceReference) {
657         configurationService =
658                 (ConfigurationService) ServiceHelper.getGlobalInstance(ConfigurationService.class, this);
659         networkingProviderManager =
660                 (NetworkingProviderManager) ServiceHelper.getGlobalInstance(NetworkingProviderManager.class, this);
661         southbound =
662                 (Southbound) ServiceHelper.getGlobalInstance(Southbound.class, this);
663     }
664
665     @Override
666     public void setDependencies(Object impl) {
667     }
668 }