blob: 244fc49e95039bc139b0a89d24ecb332ffbe0a65 [file] [log] [blame]
Thomas Vachuska781d18b2014-10-27 10:31:25 -07001/*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
tom7ef8ff92014-09-17 13:08:06 -07009 *
Thomas Vachuska781d18b2014-10-27 10:31:25 -070010 * http://www.apache.org/licenses/LICENSE-2.0
tom7ef8ff92014-09-17 13:08:06 -070011 *
Thomas Vachuska781d18b2014-10-27 10:31:25 -070012 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
tom7ef8ff92014-09-17 13:08:06 -070019
tom9c94c5b2014-09-17 13:14:42 -070020package org.onlab.onos.openflow.controller.impl;
tom7ef8ff92014-09-17 13:08:06 -070021
22import java.lang.management.ManagementFactory;
23import java.lang.management.RuntimeMXBean;
24import java.net.InetSocketAddress;
25import java.util.HashMap;
26import java.util.Map;
27import java.util.concurrent.Executors;
28
29import org.jboss.netty.bootstrap.ServerBootstrap;
30import org.jboss.netty.channel.ChannelPipelineFactory;
31import org.jboss.netty.channel.group.ChannelGroup;
32import org.jboss.netty.channel.group.DefaultChannelGroup;
33import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory;
tom9c94c5b2014-09-17 13:14:42 -070034import org.onlab.onos.openflow.controller.Dpid;
35import org.onlab.onos.openflow.controller.driver.OpenFlowAgent;
36import org.onlab.onos.openflow.controller.driver.OpenFlowSwitchDriver;
37import org.onlab.onos.openflow.drivers.impl.DriverManager;
tom7ef8ff92014-09-17 13:08:06 -070038import org.projectfloodlight.openflow.protocol.OFDescStatsReply;
39import org.projectfloodlight.openflow.protocol.OFFactories;
40import org.projectfloodlight.openflow.protocol.OFFactory;
41import org.projectfloodlight.openflow.protocol.OFVersion;
42import org.slf4j.Logger;
43import org.slf4j.LoggerFactory;
44
45
46/**
47 * The main controller class. Handles all setup and network listeners
48 * - Distributed ownership control of switch through IControllerRegistryService
49 */
50public class Controller {
51
52 protected static final Logger log = LoggerFactory.getLogger(Controller.class);
alshabib9eab22f2014-10-20 17:17:31 -070053
tom7ef8ff92014-09-17 13:08:06 -070054 protected static final OFFactory FACTORY13 = OFFactories.getFactory(OFVersion.OF_13);
55 protected static final OFFactory FACTORY10 = OFFactories.getFactory(OFVersion.OF_10);
56
tom7ef8ff92014-09-17 13:08:06 -070057 protected HashMap<String, String> controllerNodeIPsCache;
58
59 private ChannelGroup cg;
60
61 // Configuration options
62 protected int openFlowPort = 6633;
63 protected int workerThreads = 0;
64
65 // Start time of the controller
66 protected long systemStartTime;
67
68 private OpenFlowAgent agent;
69
70 private NioServerSocketChannelFactory execFactory;
71
72 // Perf. related configuration
73 protected static final int SEND_BUFFER_SIZE = 4 * 1024 * 1024;
74
75 // ***************
76 // Getters/Setters
77 // ***************
78
79 public OFFactory getOFMessageFactory10() {
80 return FACTORY10;
81 }
82
83
84 public OFFactory getOFMessageFactory13() {
85 return FACTORY13;
86 }
87
88
89
90 public Map<String, String> getControllerNodeIPs() {
91 // We return a copy of the mapping so we can guarantee that
92 // the mapping return is the same as one that will be (or was)
93 // dispatched to IHAListeners
94 HashMap<String, String> retval = new HashMap<String, String>();
95 synchronized (controllerNodeIPsCache) {
96 retval.putAll(controllerNodeIPsCache);
97 }
98 return retval;
99 }
100
101
102 public long getSystemStartTime() {
103 return (this.systemStartTime);
104 }
105
106 // **************
107 // Initialization
108 // **************
109
110 /**
111 * Tell controller that we're ready to accept switches loop.
112 */
113 public void run() {
114
115 try {
116 final ServerBootstrap bootstrap = createServerBootStrap();
117
118 bootstrap.setOption("reuseAddr", true);
119 bootstrap.setOption("child.keepAlive", true);
120 bootstrap.setOption("child.tcpNoDelay", true);
121 bootstrap.setOption("child.sendBufferSize", Controller.SEND_BUFFER_SIZE);
122
123 ChannelPipelineFactory pfact =
124 new OpenflowPipelineFactory(this, null);
125 bootstrap.setPipelineFactory(pfact);
126 InetSocketAddress sa = new InetSocketAddress(openFlowPort);
127 cg = new DefaultChannelGroup();
128 cg.add(bootstrap.bind(sa));
129
130 log.info("Listening for switch connections on {}", sa);
131 } catch (Exception e) {
132 throw new RuntimeException(e);
133 }
134
135 }
136
137 private ServerBootstrap createServerBootStrap() {
138
139 if (workerThreads == 0) {
140 execFactory = new NioServerSocketChannelFactory(
141 Executors.newCachedThreadPool(),
142 Executors.newCachedThreadPool());
143 return new ServerBootstrap(execFactory);
144 } else {
145 execFactory = new NioServerSocketChannelFactory(
146 Executors.newCachedThreadPool(),
147 Executors.newCachedThreadPool(), workerThreads);
148 return new ServerBootstrap(execFactory);
149 }
150 }
151
152 public void setConfigParams(Map<String, String> configParams) {
153 String ofPort = configParams.get("openflowport");
154 if (ofPort != null) {
155 this.openFlowPort = Integer.parseInt(ofPort);
156 }
157 log.debug("OpenFlow port set to {}", this.openFlowPort);
158 String threads = configParams.get("workerthreads");
tom1679e182014-10-09 13:50:45 -0700159 this.workerThreads = threads != null ? Integer.parseInt(threads) : 16;
tom7ef8ff92014-09-17 13:08:06 -0700160 log.debug("Number of worker threads set to {}", this.workerThreads);
161 }
162
163
164 /**
165 * Initialize internal data structures.
166 */
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.
198 * @param desc
199 * @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}