blob: 5d8fd12480b3d16e4ef7a5a69a6116eb6e3b97a7 [file] [log] [blame]
tom7ef8ff92014-09-17 13:08:06 -07001/**
2 * Copyright 2011, Big Switch Networks, Inc.
3 * Originally created by David Erickson, Stanford University
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License"); you may
6 * not use this file except in compliance with the License. You may obtain
7 * a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14 * License for the specific language governing permissions and limitations
15 * under the License.
16 **/
17
tom9c94c5b2014-09-17 13:14:42 -070018package org.onlab.onos.openflow.controller.impl;
tom7ef8ff92014-09-17 13:08:06 -070019
20import java.lang.management.ManagementFactory;
21import java.lang.management.RuntimeMXBean;
22import java.net.InetSocketAddress;
23import java.util.HashMap;
24import java.util.Map;
25import java.util.concurrent.Executors;
26
27import org.jboss.netty.bootstrap.ServerBootstrap;
28import org.jboss.netty.channel.ChannelPipelineFactory;
29import org.jboss.netty.channel.group.ChannelGroup;
30import org.jboss.netty.channel.group.DefaultChannelGroup;
31import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory;
tom9c94c5b2014-09-17 13:14:42 -070032import org.onlab.onos.openflow.controller.Dpid;
33import org.onlab.onos.openflow.controller.driver.OpenFlowAgent;
34import org.onlab.onos.openflow.controller.driver.OpenFlowSwitchDriver;
35import org.onlab.onos.openflow.drivers.impl.DriverManager;
tom7ef8ff92014-09-17 13:08:06 -070036import org.projectfloodlight.openflow.protocol.OFDescStatsReply;
37import org.projectfloodlight.openflow.protocol.OFFactories;
38import org.projectfloodlight.openflow.protocol.OFFactory;
39import org.projectfloodlight.openflow.protocol.OFVersion;
40import org.slf4j.Logger;
41import org.slf4j.LoggerFactory;
42
43
44/**
45 * The main controller class. Handles all setup and network listeners
46 * - Distributed ownership control of switch through IControllerRegistryService
47 */
48public class Controller {
49
50 protected static final Logger log = LoggerFactory.getLogger(Controller.class);
alshabib9eab22f2014-10-20 17:17:31 -070051
tom7ef8ff92014-09-17 13:08:06 -070052 protected static final OFFactory FACTORY13 = OFFactories.getFactory(OFVersion.OF_13);
53 protected static final OFFactory FACTORY10 = OFFactories.getFactory(OFVersion.OF_10);
54
tom7ef8ff92014-09-17 13:08:06 -070055 protected HashMap<String, String> controllerNodeIPsCache;
56
57 private ChannelGroup cg;
58
59 // Configuration options
60 protected int openFlowPort = 6633;
61 protected int workerThreads = 0;
62
63 // Start time of the controller
64 protected long systemStartTime;
65
66 private OpenFlowAgent agent;
67
68 private NioServerSocketChannelFactory execFactory;
69
70 // Perf. related configuration
71 protected static final int SEND_BUFFER_SIZE = 4 * 1024 * 1024;
72
73 // ***************
74 // Getters/Setters
75 // ***************
76
77 public OFFactory getOFMessageFactory10() {
78 return FACTORY10;
79 }
80
81
82 public OFFactory getOFMessageFactory13() {
83 return FACTORY13;
84 }
85
86
87
88 public Map<String, String> getControllerNodeIPs() {
89 // We return a copy of the mapping so we can guarantee that
90 // the mapping return is the same as one that will be (or was)
91 // dispatched to IHAListeners
92 HashMap<String, String> retval = new HashMap<String, String>();
93 synchronized (controllerNodeIPsCache) {
94 retval.putAll(controllerNodeIPsCache);
95 }
96 return retval;
97 }
98
99
100 public long getSystemStartTime() {
101 return (this.systemStartTime);
102 }
103
104 // **************
105 // Initialization
106 // **************
107
108 /**
109 * Tell controller that we're ready to accept switches loop.
110 */
111 public void run() {
112
113 try {
114 final ServerBootstrap bootstrap = createServerBootStrap();
115
116 bootstrap.setOption("reuseAddr", true);
117 bootstrap.setOption("child.keepAlive", true);
118 bootstrap.setOption("child.tcpNoDelay", true);
119 bootstrap.setOption("child.sendBufferSize", Controller.SEND_BUFFER_SIZE);
120
121 ChannelPipelineFactory pfact =
122 new OpenflowPipelineFactory(this, null);
123 bootstrap.setPipelineFactory(pfact);
124 InetSocketAddress sa = new InetSocketAddress(openFlowPort);
125 cg = new DefaultChannelGroup();
126 cg.add(bootstrap.bind(sa));
127
128 log.info("Listening for switch connections on {}", sa);
129 } catch (Exception e) {
130 throw new RuntimeException(e);
131 }
132
133 }
134
135 private ServerBootstrap createServerBootStrap() {
136
137 if (workerThreads == 0) {
138 execFactory = new NioServerSocketChannelFactory(
139 Executors.newCachedThreadPool(),
140 Executors.newCachedThreadPool());
141 return new ServerBootstrap(execFactory);
142 } else {
143 execFactory = new NioServerSocketChannelFactory(
144 Executors.newCachedThreadPool(),
145 Executors.newCachedThreadPool(), workerThreads);
146 return new ServerBootstrap(execFactory);
147 }
148 }
149
150 public void setConfigParams(Map<String, String> configParams) {
151 String ofPort = configParams.get("openflowport");
152 if (ofPort != null) {
153 this.openFlowPort = Integer.parseInt(ofPort);
154 }
155 log.debug("OpenFlow port set to {}", this.openFlowPort);
156 String threads = configParams.get("workerthreads");
tom1679e182014-10-09 13:50:45 -0700157 this.workerThreads = threads != null ? Integer.parseInt(threads) : 16;
tom7ef8ff92014-09-17 13:08:06 -0700158 log.debug("Number of worker threads set to {}", this.workerThreads);
159 }
160
161
162 /**
163 * Initialize internal data structures.
164 */
165 public void init(Map<String, String> configParams) {
166 // These data structures are initialized here because other
167 // module's startUp() might be called before ours
168 this.controllerNodeIPsCache = new HashMap<String, String>();
169
170 setConfigParams(configParams);
171 this.systemStartTime = System.currentTimeMillis();
172
173
174 }
175
176 // **************
177 // Utility methods
178 // **************
179
180 public Map<String, Long> getMemory() {
181 Map<String, Long> m = new HashMap<String, Long>();
182 Runtime runtime = Runtime.getRuntime();
183 m.put("total", runtime.totalMemory());
184 m.put("free", runtime.freeMemory());
185 return m;
186 }
187
188
189 public Long getUptime() {
190 RuntimeMXBean rb = ManagementFactory.getRuntimeMXBean();
191 return rb.getUptime();
192 }
193
194 /**
195 * Forward to the driver-manager to get an IOFSwitch instance.
196 * @param desc
197 * @return switch instance
198 */
199 protected OpenFlowSwitchDriver getOFSwitchInstance(long dpid,
200 OFDescStatsReply desc, OFVersion ofv) {
201 OpenFlowSwitchDriver sw = DriverManager.getSwitch(new Dpid(dpid),
202 desc, ofv);
203 sw.setAgent(agent);
204 sw.setRoleHandler(new RoleManager(sw));
205 return sw;
206 }
207
208 public void start(OpenFlowAgent ag) {
209 log.info("Starting OpenFlow IO");
210 this.agent = ag;
211 this.init(new HashMap<String, String>());
212 this.run();
213 }
214
215
216 public void stop() {
217 log.info("Stopping OpenFlow IO");
218 execFactory.shutdown();
219 cg.close();
220 }
221
222}