blob: acd1c7bff20b8f36051f49f744df803059046232 [file] [log] [blame]
Satish Ke107e662015-09-21 19:00:17 +05301/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2015-present Open Networking Foundation
Satish Ke107e662015-09-21 19:00:17 +05303 *
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;
Shashikanth VH83f77e42016-05-26 20:34:56 +053019import io.netty.util.internal.PlatformDependent;
Satish Ke107e662015-09-21 19:00:17 +053020import 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;
Ray Milkeye4afdb52017-04-05 09:42:04 -070053 private Channel serverChannel;
Satish Ke107e662015-09-21 19:00:17 +053054
55 // Configuration options
Shashikanth VH83f77e42016-05-26 20:34:56 +053056 protected static final short BGP_PORT_NUM = 179;
57 private static final short BGP_PRIVILEGED_PORT = 1790; // server port used for non root users in linux
Vidyashree Rama7bd3d782015-11-23 08:46:33 +053058 private static final short PORT_NUM_ZERO = 0;
59 private static boolean isPortNumSet = false;
Shashikanth VH83f77e42016-05-26 20:34:56 +053060 private static short portNumber = BGP_PORT_NUM;
Shashikanth VH9f8afb42015-11-04 18:00:30 +053061 private final int workerThreads = 16;
Shashikanth VHfd75b842015-11-18 19:10:13 +053062 private final int peerWorkerThreads = 16;
Satish Ke107e662015-09-21 19:00:17 +053063
64 // Start time of the controller
Shashikanth VH9f8afb42015-11-04 18:00:30 +053065 private long systemStartTime;
Satish Ke107e662015-09-21 19:00:17 +053066
67 private NioServerSocketChannelFactory serverExecFactory;
Shashikanth VHfd75b842015-11-18 19:10:13 +053068 private NioClientSocketChannelFactory peerExecFactory;
69 private static ClientBootstrap peerBootstrap;
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +053070 private BgpController bgpController;
Satish Ke107e662015-09-21 19:00:17 +053071
72 // Perf. related configuration
Shashikanth VH9f8afb42015-11-04 18:00:30 +053073 private static final int SEND_BUFFER_SIZE = 4 * 1024 * 1024;
Satish Ke107e662015-09-21 19:00:17 +053074
75 /**
Shashikanth VH9f8afb42015-11-04 18:00:30 +053076 * Constructor to initialize the values.
Satish Ke107e662015-09-21 19:00:17 +053077 *
Shashikanth VH9f8afb42015-11-04 18:00:30 +053078 * @param bgpController bgp controller instance
Satish Ke107e662015-09-21 19:00:17 +053079 */
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +053080 public Controller(BgpController bgpController) {
Shashikanth VH9f8afb42015-11-04 18:00:30 +053081 this.bgpController = bgpController;
82 }
83
84 /**
85 * Returns factory version for processing BGP messages.
86 *
87 * @return instance of factory version
88 */
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +053089 static BgpFactory getBgpMessageFactory4() {
Shashikanth VH9f8afb42015-11-04 18:00:30 +053090 return FACTORY4;
Satish Ke107e662015-09-21 19:00:17 +053091 }
92
Satish Ke107e662015-09-21 19:00:17 +053093 /**
94 * To get system start time.
95 *
96 * @return system start time in milliseconds
97 */
98 public long getSystemStartTime() {
99 return (this.systemStartTime);
100 }
101
Satish Ke107e662015-09-21 19:00:17 +0530102 /**
103 * Tell controller that we're ready to accept bgp peer connections.
104 */
105 public void run() {
106
107 try {
Shashikanth VHfd75b842015-11-18 19:10:13 +0530108
109 peerBootstrap = createPeerBootStrap();
110
111 peerBootstrap.setOption("reuseAddr", true);
112 peerBootstrap.setOption("child.keepAlive", true);
113 peerBootstrap.setOption("child.tcpNoDelay", true);
114 peerBootstrap.setOption("child.sendBufferSize", Controller.SEND_BUFFER_SIZE);
115
Satish Ke107e662015-09-21 19:00:17 +0530116 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
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530123 ChannelPipelineFactory pfact = new BgpPipelineFactory(bgpController, true);
Satish Ke107e662015-09-21 19:00:17 +0530124
125 bootstrap.setPipelineFactory(pfact);
126 InetSocketAddress sa = new InetSocketAddress(getBgpPortNum());
127 cg = new DefaultChannelGroup();
Vidyashree Rama7bd3d782015-11-23 08:46:33 +0530128 serverChannel = bootstrap.bind(sa);
129 cg.add(serverChannel);
Satish Ke107e662015-09-21 19:00:17 +0530130 log.info("Listening for Peer connection on {}", sa);
131 } catch (Exception e) {
Ray Milkey986a47a2018-01-25 11:38:51 -0800132 throw new IllegalStateException(e);
Satish Ke107e662015-09-21 19:00:17 +0530133 }
134 }
135
136 /**
137 * Creates server boot strap.
138 *
139 * @return ServerBootStrap
140 */
141 private ServerBootstrap createServerBootStrap() {
142
143 if (workerThreads == 0) {
144 serverExecFactory = new NioServerSocketChannelFactory(
145 Executors.newCachedThreadPool(groupedThreads("onos/bgp", "boss-%d")),
146 Executors.newCachedThreadPool(groupedThreads("onos/bgp", "worker-%d")));
147 return new ServerBootstrap(serverExecFactory);
148 } else {
149 serverExecFactory = new NioServerSocketChannelFactory(
150 Executors.newCachedThreadPool(groupedThreads("onos/bgp", "boss-%d")),
151 Executors.newCachedThreadPool(groupedThreads("onos/bgp", "worker-%d")),
152 workerThreads);
153 return new ServerBootstrap(serverExecFactory);
154 }
155 }
156
157 /**
Shashikanth VHfd75b842015-11-18 19:10:13 +0530158 * Creates peer boot strap.
159 *
160 * @return ClientBootstrap
161 */
162 private ClientBootstrap createPeerBootStrap() {
163
164 if (peerWorkerThreads == 0) {
165 peerExecFactory = new NioClientSocketChannelFactory(
166 Executors.newCachedThreadPool(groupedThreads("onos/bgp", "boss-%d")),
167 Executors.newCachedThreadPool(groupedThreads("onos/bgp", "worker-%d")));
168 return new ClientBootstrap(peerExecFactory);
169 } else {
170 peerExecFactory = new NioClientSocketChannelFactory(
171 Executors.newCachedThreadPool(groupedThreads("onos/bgp", "boss-%d")),
172 Executors.newCachedThreadPool(groupedThreads("onos/bgp", "worker-%d")),
173 peerWorkerThreads);
174 return new ClientBootstrap(peerExecFactory);
175 }
176 }
177
178 /**
179 * Gets peer bootstrap.
180 *
181 * @return peer bootstrap
182 */
183 public static ClientBootstrap peerBootstrap() {
184 return peerBootstrap;
185 }
186
187 /**
Satish Ke107e662015-09-21 19:00:17 +0530188 * Initialize internal data structures.
189 */
190 public void init() {
191 // These data structures are initialized here because other
192 // module's startUp() might be called before ours
193 this.systemStartTime = System.currentTimeMillis();
194 }
195
Shashikanth VHfd75b842015-11-18 19:10:13 +0530196 /**
197 * Gets run time memory.
198 *
199 * @return m run time memory
200 */
Satish Ke107e662015-09-21 19:00:17 +0530201 public Map<String, Long> getMemory() {
202 Map<String, Long> m = new HashMap<>();
203 Runtime runtime = Runtime.getRuntime();
204 m.put("total", runtime.totalMemory());
205 m.put("free", runtime.freeMemory());
206 return m;
207 }
208
Shashikanth VHfd75b842015-11-18 19:10:13 +0530209 /**
210 * Gets UP time.
211 *
212 * @return UP time
213 */
Satish Ke107e662015-09-21 19:00:17 +0530214 public Long getUptime() {
215 RuntimeMXBean rb = ManagementFactory.getRuntimeMXBean();
216 return rb.getUptime();
217 }
218
219 /**
220 * Starts the BGP controller.
221 */
222 public void start() {
223 log.info("Started");
Yuta HIGUCHIdc86de72017-11-08 20:43:27 -0800224 if (!PlatformDependent.isWindows() && !PlatformDependent.isRoot()) {
Shashikanth VH83f77e42016-05-26 20:34:56 +0530225 portNumber = BGP_PRIVILEGED_PORT;
226 } else {
227 portNumber = BGP_PORT_NUM;
228 }
Satish Ke107e662015-09-21 19:00:17 +0530229 this.init();
230 this.run();
231 }
232
233 /**
234 * Stops the BGP controller.
235 */
236 public void stop() {
237 log.info("Stopped");
238 serverExecFactory.shutdown();
Shashikanth VHfd75b842015-11-18 19:10:13 +0530239 peerExecFactory.shutdown();
Satish Ke107e662015-09-21 19:00:17 +0530240 cg.close();
241 }
242
243 /**
244 * Returns port number.
245 *
246 * @return port number
247 */
248 public static short getBgpPortNum() {
Vidyashree Rama7bd3d782015-11-23 08:46:33 +0530249 if (isPortNumSet) {
250 return PORT_NUM_ZERO;
251 }
Shashikanth VH83f77e42016-05-26 20:34:56 +0530252
253 return portNumber;
Satish Ke107e662015-09-21 19:00:17 +0530254 }
Vidyashree Rama7bd3d782015-11-23 08:46:33 +0530255
256 /**
257 * sets the isPortNumSet as true.
258 */
259 public void setBgpPortNum() {
260 isPortNumSet = true;
261 }
Ray Milkeye4afdb52017-04-05 09:42:04 -0700262}