blob: 1d0e4cbf43b6dc351b4c78871d037178ddf0ca75 [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
19import java.lang.management.ManagementFactory;
20import java.lang.management.RuntimeMXBean;
21import java.net.InetSocketAddress;
22import java.util.HashMap;
23import java.util.Map;
24import java.util.concurrent.Executors;
25
26import org.jboss.netty.bootstrap.ServerBootstrap;
27import org.jboss.netty.channel.ChannelPipelineFactory;
28import org.jboss.netty.channel.group.ChannelGroup;
29import org.jboss.netty.channel.group.DefaultChannelGroup;
30import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory;
tom9c94c5b2014-09-17 13:14:42 -070031import org.onlab.onos.openflow.controller.Dpid;
32import org.onlab.onos.openflow.controller.driver.OpenFlowAgent;
33import org.onlab.onos.openflow.controller.driver.OpenFlowSwitchDriver;
34import org.onlab.onos.openflow.drivers.impl.DriverManager;
tom7ef8ff92014-09-17 13:08:06 -070035import org.projectfloodlight.openflow.protocol.OFDescStatsReply;
36import org.projectfloodlight.openflow.protocol.OFFactories;
37import org.projectfloodlight.openflow.protocol.OFFactory;
38import org.projectfloodlight.openflow.protocol.OFVersion;
39import org.slf4j.Logger;
40import org.slf4j.LoggerFactory;
41
42
43/**
44 * The main controller class. Handles all setup and network listeners
45 * - Distributed ownership control of switch through IControllerRegistryService
46 */
47public class Controller {
48
49 protected static final Logger log = LoggerFactory.getLogger(Controller.class);
alshabib9eab22f2014-10-20 17:17:31 -070050
tom7ef8ff92014-09-17 13:08:06 -070051 protected static final OFFactory FACTORY13 = OFFactories.getFactory(OFVersion.OF_13);
52 protected static final OFFactory FACTORY10 = OFFactories.getFactory(OFVersion.OF_10);
53
tom7ef8ff92014-09-17 13:08:06 -070054 protected HashMap<String, String> controllerNodeIPsCache;
55
56 private ChannelGroup cg;
57
58 // Configuration options
59 protected int openFlowPort = 6633;
60 protected int workerThreads = 0;
61
62 // Start time of the controller
63 protected long systemStartTime;
64
65 private OpenFlowAgent agent;
66
67 private NioServerSocketChannelFactory execFactory;
68
69 // Perf. related configuration
70 protected static final int SEND_BUFFER_SIZE = 4 * 1024 * 1024;
71
72 // ***************
73 // Getters/Setters
74 // ***************
75
76 public OFFactory getOFMessageFactory10() {
77 return FACTORY10;
78 }
79
80
81 public OFFactory getOFMessageFactory13() {
82 return FACTORY13;
83 }
84
85
86
87 public Map<String, String> getControllerNodeIPs() {
88 // We return a copy of the mapping so we can guarantee that
89 // the mapping return is the same as one that will be (or was)
90 // dispatched to IHAListeners
91 HashMap<String, String> retval = new HashMap<String, String>();
92 synchronized (controllerNodeIPsCache) {
93 retval.putAll(controllerNodeIPsCache);
94 }
95 return retval;
96 }
97
98
99 public long getSystemStartTime() {
100 return (this.systemStartTime);
101 }
102
103 // **************
104 // Initialization
105 // **************
106
107 /**
108 * Tell controller that we're ready to accept switches loop.
109 */
110 public void run() {
111
112 try {
113 final ServerBootstrap bootstrap = createServerBootStrap();
114
115 bootstrap.setOption("reuseAddr", true);
116 bootstrap.setOption("child.keepAlive", true);
117 bootstrap.setOption("child.tcpNoDelay", true);
118 bootstrap.setOption("child.sendBufferSize", Controller.SEND_BUFFER_SIZE);
119
120 ChannelPipelineFactory pfact =
121 new OpenflowPipelineFactory(this, null);
122 bootstrap.setPipelineFactory(pfact);
123 InetSocketAddress sa = new InetSocketAddress(openFlowPort);
124 cg = new DefaultChannelGroup();
125 cg.add(bootstrap.bind(sa));
126
127 log.info("Listening for switch connections on {}", sa);
128 } catch (Exception e) {
129 throw new RuntimeException(e);
130 }
131
132 }
133
134 private ServerBootstrap createServerBootStrap() {
135
136 if (workerThreads == 0) {
137 execFactory = new NioServerSocketChannelFactory(
138 Executors.newCachedThreadPool(),
139 Executors.newCachedThreadPool());
140 return new ServerBootstrap(execFactory);
141 } else {
142 execFactory = new NioServerSocketChannelFactory(
143 Executors.newCachedThreadPool(),
144 Executors.newCachedThreadPool(), workerThreads);
145 return new ServerBootstrap(execFactory);
146 }
147 }
148
149 public void setConfigParams(Map<String, String> configParams) {
150 String ofPort = configParams.get("openflowport");
151 if (ofPort != null) {
152 this.openFlowPort = Integer.parseInt(ofPort);
153 }
154 log.debug("OpenFlow port set to {}", this.openFlowPort);
155 String threads = configParams.get("workerthreads");
tom1679e182014-10-09 13:50:45 -0700156 this.workerThreads = threads != null ? Integer.parseInt(threads) : 16;
tom7ef8ff92014-09-17 13:08:06 -0700157 log.debug("Number of worker threads set to {}", this.workerThreads);
158 }
159
160
161 /**
162 * Initialize internal data structures.
Yuta HIGUCHI5c947272014-11-03 21:39:21 -0800163 * @param configParams configuration parameters
tom7ef8ff92014-09-17 13:08:06 -0700164 */
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.
Yuta HIGUCHI5c947272014-11-03 21:39:21 -0800196 * @param dpid data path id
197 * @param desc switch description
198 * @param ofv OpenFlow version
tom7ef8ff92014-09-17 13:08:06 -0700199 * @return switch instance
200 */
201 protected OpenFlowSwitchDriver getOFSwitchInstance(long dpid,
202 OFDescStatsReply desc, OFVersion ofv) {
203 OpenFlowSwitchDriver sw = DriverManager.getSwitch(new Dpid(dpid),
204 desc, ofv);
205 sw.setAgent(agent);
206 sw.setRoleHandler(new RoleManager(sw));
207 return sw;
208 }
209
210 public void start(OpenFlowAgent ag) {
211 log.info("Starting OpenFlow IO");
212 this.agent = ag;
213 this.init(new HashMap<String, String>());
214 this.run();
215 }
216
217
218 public void stop() {
219 log.info("Stopping OpenFlow IO");
220 execFactory.shutdown();
221 cg.close();
222 }
223
224}