blob: f02cee8a008454e433357838646683fc85480457 [file] [log] [blame]
Satish Ke107e662015-09-21 19:00:17 +05301/*
2 * Copyright 2015 Open Networking Laboratory
3 *
4 * 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
7 *
8 * 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.
15 */
16package org.onosproject.bgp.controller.impl;
17
18import static org.onlab.util.Tools.groupedThreads;
19
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
Shashikanth VHfd75b842015-11-18 19:10:13 +053027import org.jboss.netty.bootstrap.ClientBootstrap;
Satish Ke107e662015-09-21 19:00:17 +053028import org.jboss.netty.bootstrap.ServerBootstrap;
Vidyashree Rama7bd3d782015-11-23 08:46:33 +053029import org.jboss.netty.channel.Channel;
Satish Ke107e662015-09-21 19:00:17 +053030import org.jboss.netty.channel.ChannelPipelineFactory;
31import org.jboss.netty.channel.group.ChannelGroup;
32import org.jboss.netty.channel.group.DefaultChannelGroup;
Shashikanth VHfd75b842015-11-18 19:10:13 +053033import org.jboss.netty.channel.socket.nio.NioClientSocketChannelFactory;
Satish Ke107e662015-09-21 19:00:17 +053034import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory;
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +053035import org.onosproject.bgp.controller.BgpController;
36import org.onosproject.bgpio.protocol.BgpFactories;
37import org.onosproject.bgpio.protocol.BgpFactory;
38import org.onosproject.bgpio.protocol.BgpVersion;
Satish Ke107e662015-09-21 19:00:17 +053039import org.slf4j.Logger;
40import org.slf4j.LoggerFactory;
41
42/**
43 * The main controller class. Handles all setup and network listeners - Distributed ownership control of bgp peer
44 * through IControllerRegistryService
45 */
46public class Controller {
47
Shashikanth VH9f8afb42015-11-04 18:00:30 +053048 private static final Logger log = LoggerFactory.getLogger(Controller.class);
49
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +053050 private static final BgpFactory FACTORY4 = BgpFactories.getFactory(BgpVersion.BGP_4);
Satish Ke107e662015-09-21 19:00:17 +053051
52 private ChannelGroup cg;
Vidyashree Rama7bd3d782015-11-23 08:46:33 +053053 public Channel serverChannel;
Satish Ke107e662015-09-21 19:00:17 +053054
55 // Configuration options
56 private static final short BGP_PORT_NUM = 179;
Vidyashree Rama7bd3d782015-11-23 08:46:33 +053057 private static final short PORT_NUM_ZERO = 0;
58 private static boolean isPortNumSet = false;
Shashikanth VH9f8afb42015-11-04 18:00:30 +053059 private final int workerThreads = 16;
Shashikanth VHfd75b842015-11-18 19:10:13 +053060 private final int peerWorkerThreads = 16;
Satish Ke107e662015-09-21 19:00:17 +053061
62 // Start time of the controller
Shashikanth VH9f8afb42015-11-04 18:00:30 +053063 private long systemStartTime;
Satish Ke107e662015-09-21 19:00:17 +053064
65 private NioServerSocketChannelFactory serverExecFactory;
Shashikanth VHfd75b842015-11-18 19:10:13 +053066 private NioClientSocketChannelFactory peerExecFactory;
67 private static ClientBootstrap peerBootstrap;
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +053068 private BgpController bgpController;
Satish Ke107e662015-09-21 19:00:17 +053069
70 // Perf. related configuration
Shashikanth VH9f8afb42015-11-04 18:00:30 +053071 private static final int SEND_BUFFER_SIZE = 4 * 1024 * 1024;
Satish Ke107e662015-09-21 19:00:17 +053072
73 /**
Shashikanth VH9f8afb42015-11-04 18:00:30 +053074 * Constructor to initialize the values.
Satish Ke107e662015-09-21 19:00:17 +053075 *
Shashikanth VH9f8afb42015-11-04 18:00:30 +053076 * @param bgpController bgp controller instance
Satish Ke107e662015-09-21 19:00:17 +053077 */
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +053078 public Controller(BgpController bgpController) {
Shashikanth VH9f8afb42015-11-04 18:00:30 +053079 this.bgpController = bgpController;
80 }
81
82 /**
83 * Returns factory version for processing BGP messages.
84 *
85 * @return instance of factory version
86 */
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +053087 static BgpFactory getBgpMessageFactory4() {
Shashikanth VH9f8afb42015-11-04 18:00:30 +053088 return FACTORY4;
Satish Ke107e662015-09-21 19:00:17 +053089 }
90
Satish Ke107e662015-09-21 19:00:17 +053091 /**
92 * To get system start time.
93 *
94 * @return system start time in milliseconds
95 */
96 public long getSystemStartTime() {
97 return (this.systemStartTime);
98 }
99
Satish Ke107e662015-09-21 19:00:17 +0530100 /**
101 * Tell controller that we're ready to accept bgp peer connections.
102 */
103 public void run() {
104
105 try {
Shashikanth VHfd75b842015-11-18 19:10:13 +0530106
107 peerBootstrap = createPeerBootStrap();
108
109 peerBootstrap.setOption("reuseAddr", true);
110 peerBootstrap.setOption("child.keepAlive", true);
111 peerBootstrap.setOption("child.tcpNoDelay", true);
112 peerBootstrap.setOption("child.sendBufferSize", Controller.SEND_BUFFER_SIZE);
113
Satish Ke107e662015-09-21 19:00:17 +0530114 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
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530121 ChannelPipelineFactory pfact = new BgpPipelineFactory(bgpController, true);
Satish Ke107e662015-09-21 19:00:17 +0530122
123 bootstrap.setPipelineFactory(pfact);
124 InetSocketAddress sa = new InetSocketAddress(getBgpPortNum());
125 cg = new DefaultChannelGroup();
Vidyashree Rama7bd3d782015-11-23 08:46:33 +0530126 serverChannel = bootstrap.bind(sa);
127 cg.add(serverChannel);
Satish Ke107e662015-09-21 19:00:17 +0530128 log.info("Listening for Peer connection on {}", sa);
129 } catch (Exception e) {
130 throw new RuntimeException(e);
131 }
132 }
133
134 /**
135 * Creates server boot strap.
136 *
137 * @return ServerBootStrap
138 */
139 private ServerBootstrap createServerBootStrap() {
140
141 if (workerThreads == 0) {
142 serverExecFactory = new NioServerSocketChannelFactory(
143 Executors.newCachedThreadPool(groupedThreads("onos/bgp", "boss-%d")),
144 Executors.newCachedThreadPool(groupedThreads("onos/bgp", "worker-%d")));
145 return new ServerBootstrap(serverExecFactory);
146 } else {
147 serverExecFactory = new NioServerSocketChannelFactory(
148 Executors.newCachedThreadPool(groupedThreads("onos/bgp", "boss-%d")),
149 Executors.newCachedThreadPool(groupedThreads("onos/bgp", "worker-%d")),
150 workerThreads);
151 return new ServerBootstrap(serverExecFactory);
152 }
153 }
154
155 /**
Shashikanth VHfd75b842015-11-18 19:10:13 +0530156 * Creates peer boot strap.
157 *
158 * @return ClientBootstrap
159 */
160 private ClientBootstrap createPeerBootStrap() {
161
162 if (peerWorkerThreads == 0) {
163 peerExecFactory = new NioClientSocketChannelFactory(
164 Executors.newCachedThreadPool(groupedThreads("onos/bgp", "boss-%d")),
165 Executors.newCachedThreadPool(groupedThreads("onos/bgp", "worker-%d")));
166 return new ClientBootstrap(peerExecFactory);
167 } else {
168 peerExecFactory = new NioClientSocketChannelFactory(
169 Executors.newCachedThreadPool(groupedThreads("onos/bgp", "boss-%d")),
170 Executors.newCachedThreadPool(groupedThreads("onos/bgp", "worker-%d")),
171 peerWorkerThreads);
172 return new ClientBootstrap(peerExecFactory);
173 }
174 }
175
176 /**
177 * Gets peer bootstrap.
178 *
179 * @return peer bootstrap
180 */
181 public static ClientBootstrap peerBootstrap() {
182 return peerBootstrap;
183 }
184
185 /**
Satish Ke107e662015-09-21 19:00:17 +0530186 * Initialize internal data structures.
187 */
188 public void init() {
189 // These data structures are initialized here because other
190 // module's startUp() might be called before ours
191 this.systemStartTime = System.currentTimeMillis();
192 }
193
Shashikanth VHfd75b842015-11-18 19:10:13 +0530194 /**
195 * Gets run time memory.
196 *
197 * @return m run time memory
198 */
Satish Ke107e662015-09-21 19:00:17 +0530199 public Map<String, Long> getMemory() {
200 Map<String, Long> m = new HashMap<>();
201 Runtime runtime = Runtime.getRuntime();
202 m.put("total", runtime.totalMemory());
203 m.put("free", runtime.freeMemory());
204 return m;
205 }
206
Shashikanth VHfd75b842015-11-18 19:10:13 +0530207 /**
208 * Gets UP time.
209 *
210 * @return UP time
211 */
Satish Ke107e662015-09-21 19:00:17 +0530212 public Long getUptime() {
213 RuntimeMXBean rb = ManagementFactory.getRuntimeMXBean();
214 return rb.getUptime();
215 }
216
217 /**
218 * Starts the BGP controller.
219 */
220 public void start() {
221 log.info("Started");
222 this.init();
223 this.run();
224 }
225
226 /**
227 * Stops the BGP controller.
228 */
229 public void stop() {
230 log.info("Stopped");
231 serverExecFactory.shutdown();
Shashikanth VHfd75b842015-11-18 19:10:13 +0530232 peerExecFactory.shutdown();
Satish Ke107e662015-09-21 19:00:17 +0530233 cg.close();
234 }
235
236 /**
237 * Returns port number.
238 *
239 * @return port number
240 */
241 public static short getBgpPortNum() {
Vidyashree Rama7bd3d782015-11-23 08:46:33 +0530242 if (isPortNumSet) {
243 return PORT_NUM_ZERO;
244 }
Satish Ke107e662015-09-21 19:00:17 +0530245 return BGP_PORT_NUM;
246 }
Vidyashree Rama7bd3d782015-11-23 08:46:33 +0530247
248 /**
249 * sets the isPortNumSet as true.
250 */
251 public void setBgpPortNum() {
252 isPortNumSet = true;
253 }
Satish Ke107e662015-09-21 19:00:17 +0530254}