blob: 23fd1497320b6bb0786b20276c22d76883e6edc8 [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
Brian O'Connorabafb502014-12-02 22:26:20 -080017package org.onosproject.openflow.controller.impl;
tom7ef8ff92014-09-17 13:08:06 -070018
tom7ef8ff92014-09-17 13:08:06 -070019import org.jboss.netty.bootstrap.ServerBootstrap;
20import org.jboss.netty.channel.ChannelPipelineFactory;
21import org.jboss.netty.channel.group.ChannelGroup;
22import org.jboss.netty.channel.group.DefaultChannelGroup;
23import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory;
Brian O'Connorabafb502014-12-02 22:26:20 -080024import org.onosproject.openflow.controller.Dpid;
25import org.onosproject.openflow.controller.driver.OpenFlowAgent;
26import org.onosproject.openflow.controller.driver.OpenFlowSwitchDriver;
27import org.onosproject.openflow.drivers.DriverManager;
tom7ef8ff92014-09-17 13:08:06 -070028import org.projectfloodlight.openflow.protocol.OFDescStatsReply;
29import org.projectfloodlight.openflow.protocol.OFFactories;
30import org.projectfloodlight.openflow.protocol.OFFactory;
31import org.projectfloodlight.openflow.protocol.OFVersion;
32import org.slf4j.Logger;
33import org.slf4j.LoggerFactory;
34
Thomas Vachuska6f94ded2015-02-21 14:02:38 -080035import java.lang.management.ManagementFactory;
36import java.lang.management.RuntimeMXBean;
37import java.net.InetSocketAddress;
38import java.util.HashMap;
39import java.util.Map;
40import java.util.concurrent.Executors;
41
42import static org.onlab.util.Tools.groupedThreads;
43
tom7ef8ff92014-09-17 13:08:06 -070044
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
tom7ef8ff92014-09-17 13:08:06 -070088 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) {
Thomas Vachuska6f94ded2015-02-21 14:02:38 -0800138 execFactory = new NioServerSocketChannelFactory(
139 Executors.newCachedThreadPool(groupedThreads("onos/of", "boss-%d")),
140 Executors.newCachedThreadPool(groupedThreads("onos/of", "worker-%d")));
tom7ef8ff92014-09-17 13:08:06 -0700141 return new ServerBootstrap(execFactory);
142 } else {
143 execFactory = new NioServerSocketChannelFactory(
Thomas Vachuska6f94ded2015-02-21 14:02:38 -0800144 Executors.newCachedThreadPool(groupedThreads("onos/of", "boss-%d")),
145 Executors.newCachedThreadPool(groupedThreads("onos/of", "worker-%d")), workerThreads);
tom7ef8ff92014-09-17 13:08:06 -0700146 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.
Thomas Vachuska6f94ded2015-02-21 14:02:38 -0800164 *
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.
Thomas Vachuska6f94ded2015-02-21 14:02:38 -0800198 *
Yuta HIGUCHI5c947272014-11-03 21:39:21 -0800199 * @param dpid data path id
200 * @param desc switch description
Thomas Vachuska6f94ded2015-02-21 14:02:38 -0800201 * @param ofv OpenFlow version
tom7ef8ff92014-09-17 13:08:06 -0700202 * @return switch instance
203 */
204 protected OpenFlowSwitchDriver getOFSwitchInstance(long dpid,
Thomas Vachuska6f94ded2015-02-21 14:02:38 -0800205 OFDescStatsReply desc, OFVersion ofv) {
tom7ef8ff92014-09-17 13:08:06 -0700206 OpenFlowSwitchDriver sw = DriverManager.getSwitch(new Dpid(dpid),
alshabib452234e2014-11-25 00:03:49 -0500207 desc, ofv);
tom7ef8ff92014-09-17 13:08:06 -0700208 sw.setAgent(agent);
209 sw.setRoleHandler(new RoleManager(sw));
210 return sw;
211 }
212
213 public void start(OpenFlowAgent ag) {
214 log.info("Starting OpenFlow IO");
215 this.agent = ag;
216 this.init(new HashMap<String, String>());
217 this.run();
218 }
219
220
221 public void stop() {
222 log.info("Stopping OpenFlow IO");
223 execFactory.shutdown();
224 cg.close();
225 }
226
227}