2 * Copyright (c) 2013 Cisco Systems, 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.controller.protocol_plugin.openflow.core.internal;
11 import java.io.IOException;
12 import java.net.InetAddress;
13 import java.net.NetworkInterface;
14 import java.net.SocketException;
15 import java.nio.channels.SelectionKey;
16 import java.nio.channels.Selector;
17 import java.nio.channels.ServerSocketChannel;
18 import java.nio.channels.spi.SelectorProvider;
19 import java.util.Iterator;
21 import org.opendaylight.controller.protocol_plugin.openflow.core.IController;
22 import org.slf4j.Logger;
23 import org.slf4j.LoggerFactory;
25 public class ControllerIO {
26 private static final Logger logger = LoggerFactory
27 .getLogger(ControllerIO.class);
28 private static Short defaultOpenFlowPort = 6633;
29 private Short openFlowPort;
30 private InetAddress controllerIP;
31 private NetworkInterface netInt;
32 private SelectionKey serverSelectionKey;
33 private IController listener;
34 private ServerSocketChannel serverSocket;
35 private Selector selector;
36 private boolean running;
37 private Thread controllerIOThread;
39 public ControllerIO(IController l) {
41 this.openFlowPort = defaultOpenFlowPort;
42 String portString = System.getProperty("of.listenPort");
43 if (portString != null) {
45 openFlowPort = Short.decode(portString).shortValue();
46 } catch (NumberFormatException e) {
47 logger.warn("Invalid port:{}, use default({})", portString,
51 String addressString = System.getProperty("of.address");
52 if (addressString != null) {
54 controllerIP = InetAddress.getByName(addressString);
55 } catch (Exception e) {
57 logger.warn("Invalid IP: {}, use wildcard *", addressString);
64 public void start() throws IOException {
67 controllerIOThread = new Thread(new Runnable() {
70 waitUntilInterfaceUp();
71 if (!startAcceptConnections()) {
74 logger.info("Controller is now listening on {}:{}",
75 (controllerIP == null) ? "any" : controllerIP.getHostAddress(),
77 boolean netInterfaceUp = true;
80 // wait for an incoming connection
81 // check interface state every 5sec
82 selector.select(5000);
83 Iterator<SelectionKey> selectedKeys = selector
84 .selectedKeys().iterator();
85 netInterfaceUp = isNetInterfaceUp(netInterfaceUp);
86 while (selectedKeys.hasNext()) {
87 SelectionKey skey = selectedKeys.next();
88 selectedKeys.remove();
89 if (skey.isValid() && skey.isAcceptable()) {
90 ((Controller) listener).handleNewConnection(
91 selector, serverSelectionKey);
94 } catch (Exception e) {
99 }, "ControllerI/O Thread");
100 controllerIOThread.start();
103 private boolean startAcceptConnections() {
107 selector = SelectorProvider.provider().openSelector();
108 // create the listening socket
109 serverSocket = ServerSocketChannel.open();
110 serverSocket.configureBlocking(false);
111 serverSocket.socket().bind(
112 new java.net.InetSocketAddress(controllerIP,
114 serverSocket.socket().setReuseAddress(true);
115 // register this socket for accepting incoming
117 serverSelectionKey = serverSocket.register(selector,
118 SelectionKey.OP_ACCEPT);
119 } catch (IOException e) {
121 "Failed to listen on {}:{}, exit",
122 (controllerIP == null) ? "" : controllerIP
123 .getHostAddress(), openFlowPort);
131 private boolean isNetInterfaceUp(boolean currentlyUp) {
132 if (controllerIP == null) {
133 // for wildcard address, return since there is always an "up"
134 // interface (such as loopback)
139 if (netInt == null) {
140 logger.warn("Can't find any operational interface for address {}",
141 controllerIP.getHostAddress());
146 // always generate log if the interface is down
147 logger.warn("Interface {} with address {} is DOWN!",
148 netInt.getDisplayName(),
149 controllerIP.getHostAddress());
152 // only generate log if the interface changes from down to up
153 logger.trace("Interface {} with address {} is UP!",
154 netInt.getDisplayName(),
155 controllerIP.getHostAddress());
158 } catch (SocketException e) {
159 logger.warn("Interface {} with address {} is DOWN!",
160 netInt.getDisplayName(),
161 controllerIP.getHostAddress());
167 private void waitUntilInterfaceUp() {
168 if (controllerIP == null) {
169 // for wildcard address, return since there is always an "up"
170 // interface (such as loopback)
173 boolean isUp = false;
176 // get the network interface from the address
177 netInt = NetworkInterface.getByInetAddress(controllerIP);
178 isUp = isNetInterfaceUp(isUp);
182 } catch (Exception e) {
184 } while ((!isUp) && (running));
186 public void shutDown() throws IOException {
187 this.running = false;
188 this.selector.wakeup();
189 this.serverSocket.close();