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