blob: 1be65043bb066066d49574874c9853a98ef166ac [file] [log] [blame]
paul718e3742002-12-13 20:15:29 +00001/* Main routine of bgpd.
2 Copyright (C) 1996, 97, 98, 1999 Kunihiro Ishiguro
3
4This file is part of GNU Zebra.
5
6GNU Zebra is free software; you can redistribute it and/or modify it
7under the terms of the GNU General Public License as published by the
8Free Software Foundation; either version 2, or (at your option) any
9later version.
10
11GNU Zebra is distributed in the hope that it will be useful, but
12WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GNU Zebra; see the file COPYING. If not, write to the Free
18Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
1902111-1307, USA. */
20
21#include <zebra.h>
22
23#include "vector.h"
24#include "vty.h"
25#include "command.h"
26#include "getopt.h"
27#include "thread.h"
gdt5e4fa162004-03-16 14:38:36 +000028#include <lib/version.h>
paul718e3742002-12-13 20:15:29 +000029#include "memory.h"
30#include "prefix.h"
31#include "log.h"
pauledd7c242003-06-04 13:59:38 +000032#include "privs.h"
paul2d75d052004-01-19 21:31:15 +000033#include "sigevent.h"
Chris Caputo228da422009-07-18 05:44:03 +000034#include "zclient.h"
35#include "routemap.h"
36#include "filter.h"
37#include "plist.h"
Josh Bailey8196f132011-07-20 20:47:07 -070038#include "stream.h"
paul718e3742002-12-13 20:15:29 +000039
40#include "bgpd/bgpd.h"
41#include "bgpd/bgp_attr.h"
42#include "bgpd/bgp_mplsvpn.h"
Chris Caputo228da422009-07-18 05:44:03 +000043#include "bgpd/bgp_aspath.h"
44#include "bgpd/bgp_dump.h"
45#include "bgpd/bgp_route.h"
46#include "bgpd/bgp_nexthop.h"
47#include "bgpd/bgp_regex.h"
48#include "bgpd/bgp_clist.h"
49#include "bgpd/bgp_debug.h"
50#include "bgpd/bgp_filter.h"
Josh Bailey8196f132011-07-20 20:47:07 -070051#include "bgpd/bgp_zebra.h"
paul718e3742002-12-13 20:15:29 +000052
53/* bgpd options, we use GNU getopt library. */
Stephen Hemminger372b3c72009-05-15 10:29:41 -070054static const struct option longopts[] =
paul718e3742002-12-13 20:15:29 +000055{
56 { "daemon", no_argument, NULL, 'd'},
57 { "config_file", required_argument, NULL, 'f'},
58 { "pid_file", required_argument, NULL, 'i'},
Vyacheslav Trushkinb5114682011-11-25 18:51:48 +040059 { "socket", required_argument, NULL, 'z'},
paul718e3742002-12-13 20:15:29 +000060 { "bgp_port", required_argument, NULL, 'p'},
Paul Jakma3a02d1f2007-11-01 14:29:11 +000061 { "listenon", required_argument, NULL, 'l'},
paul718e3742002-12-13 20:15:29 +000062 { "vty_addr", required_argument, NULL, 'A'},
63 { "vty_port", required_argument, NULL, 'P'},
64 { "retain", no_argument, NULL, 'r'},
65 { "no_kernel", no_argument, NULL, 'n'},
pauledd7c242003-06-04 13:59:38 +000066 { "user", required_argument, NULL, 'u'},
hassoc0652302004-11-25 19:33:48 +000067 { "group", required_argument, NULL, 'g'},
paul718e3742002-12-13 20:15:29 +000068 { "version", no_argument, NULL, 'v'},
Paul Jakma876b8be2006-10-15 23:35:57 +000069 { "dryrun", no_argument, NULL, 'C'},
paul718e3742002-12-13 20:15:29 +000070 { "help", no_argument, NULL, 'h'},
71 { 0 }
72};
73
paul2d75d052004-01-19 21:31:15 +000074/* signal definitions */
75void sighup (void);
76void sigint (void);
77void sigusr1 (void);
78
Chris Caputo228da422009-07-18 05:44:03 +000079static void bgp_exit (int);
80
Stephen Hemminger372b3c72009-05-15 10:29:41 -070081static struct quagga_signal_t bgp_signals[] =
paul2d75d052004-01-19 21:31:15 +000082{
83 {
84 .signal = SIGHUP,
85 .handler = &sighup,
86 },
87 {
88 .signal = SIGUSR1,
89 .handler = &sigusr1,
90 },
91 {
92 .signal = SIGINT,
93 .handler = &sigint,
94 },
hassof571dab2004-03-22 08:55:25 +000095 {
96 .signal = SIGTERM,
97 .handler = &sigint,
98 },
paul2d75d052004-01-19 21:31:15 +000099};
100
paul718e3742002-12-13 20:15:29 +0000101/* Configuration file and directory. */
paul718e3742002-12-13 20:15:29 +0000102char config_default[] = SYSCONFDIR BGP_DEFAULT_CONFIG;
103
104/* Route retain mode flag. */
Stephen Hemminger372b3c72009-05-15 10:29:41 -0700105static int retain_mode = 0;
paul718e3742002-12-13 20:15:29 +0000106
107/* Master of threads. */
108struct thread_master *master;
109
110/* Manually specified configuration file name. */
111char *config_file = NULL;
112
113/* Process ID saved for use by init system */
Stephen Hemminger372b3c72009-05-15 10:29:41 -0700114static const char *pid_file = PATH_BGPD_PID;
paul718e3742002-12-13 20:15:29 +0000115
116/* VTY port number and address. */
117int vty_port = BGP_VTY_PORT;
118char *vty_addr = NULL;
119
pauledd7c242003-06-04 13:59:38 +0000120/* privileges */
Stephen Hemminger372b3c72009-05-15 10:29:41 -0700121static zebra_capabilities_t _caps_p [] =
pauledd7c242003-06-04 13:59:38 +0000122{
paul98f51632004-10-25 14:19:15 +0000123 ZCAP_BIND,
paulceacedb2005-09-29 14:39:32 +0000124 ZCAP_NET_RAW,
Chris Luke5c88f192011-10-18 17:26:51 +0400125 ZCAP_NET_ADMIN,
pauledd7c242003-06-04 13:59:38 +0000126};
127
128struct zebra_privs_t bgpd_privs =
129{
pauld81fadf2003-08-14 05:32:12 +0000130#if defined(QUAGGA_USER) && defined(QUAGGA_GROUP)
131 .user = QUAGGA_USER,
132 .group = QUAGGA_GROUP,
133#endif
134#ifdef VTY_GROUP
135 .vty_group = VTY_GROUP,
pauledd7c242003-06-04 13:59:38 +0000136#endif
137 .caps_p = _caps_p,
Balaji.G837d16c2012-09-26 14:09:10 +0530138 .cap_num_p = array_size(_caps_p),
pauledd7c242003-06-04 13:59:38 +0000139 .cap_num_i = 0,
140};
141
paul718e3742002-12-13 20:15:29 +0000142/* Help information display. */
143static void
144usage (char *progname, int status)
145{
146 if (status != 0)
147 fprintf (stderr, "Try `%s --help' for more information.\n", progname);
148 else
149 {
150 printf ("Usage : %s [OPTION...]\n\n\
151Daemon which manages kernel routing table management and \
152redistribution between different routing protocols.\n\n\
153-d, --daemon Runs in daemon mode\n\
154-f, --config_file Set configuration file name\n\
155-i, --pid_file Set process identifier file name\n\
Vyacheslav Trushkinb5114682011-11-25 18:51:48 +0400156-z, --socket Set path of zebra socket\n\
paul718e3742002-12-13 20:15:29 +0000157-p, --bgp_port Set bgp protocol's port number\n\
Paul Jakma3a02d1f2007-11-01 14:29:11 +0000158-l, --listenon Listen on specified address (implies -n)\n\
paul718e3742002-12-13 20:15:29 +0000159-A, --vty_addr Set vty's bind address\n\
160-P, --vty_port Set vty's port number\n\
161-r, --retain When program terminates, retain added route by bgpd.\n\
162-n, --no_kernel Do not install route to kernel.\n\
hassoc0652302004-11-25 19:33:48 +0000163-u, --user User to run as\n\
164-g, --group Group to run as\n\
paul718e3742002-12-13 20:15:29 +0000165-v, --version Print program version\n\
Paul Jakma876b8be2006-10-15 23:35:57 +0000166-C, --dryrun Check configuration for validity and exit\n\
paul718e3742002-12-13 20:15:29 +0000167-h, --help Display this help and exit\n\
168\n\
169Report bugs to %s\n", progname, ZEBRA_BUG_ADDRESS);
170 }
171
172 exit (status);
173}
174
175/* SIGHUP handler. */
176void
paul2d75d052004-01-19 21:31:15 +0000177sighup (void)
paul718e3742002-12-13 20:15:29 +0000178{
179 zlog (NULL, LOG_INFO, "SIGHUP received");
180
181 /* Terminate all thread. */
182 bgp_terminate ();
183 bgp_reset ();
184 zlog_info ("bgpd restarting!");
185
186 /* Reload config file. */
hasso320ec102004-06-20 19:54:37 +0000187 vty_read_config (config_file, config_default);
paul718e3742002-12-13 20:15:29 +0000188
189 /* Create VTY's socket */
paul4fc4e7a2003-01-22 19:47:09 +0000190 vty_serv_sock (vty_addr, vty_port, BGP_VTYSH_PATH);
paul718e3742002-12-13 20:15:29 +0000191
192 /* Try to return to normal operation. */
193}
194
195/* SIGINT handler. */
196void
paul2d75d052004-01-19 21:31:15 +0000197sigint (void)
paul718e3742002-12-13 20:15:29 +0000198{
ajs887c44a2004-12-03 16:36:46 +0000199 zlog_notice ("Terminating on signal");
paul718e3742002-12-13 20:15:29 +0000200
201 if (! retain_mode)
202 bgp_terminate ();
203
Stephen Hemminger04d5e242011-12-07 00:04:46 +0400204 zprivs_terminate (&bgpd_privs);
Chris Caputo228da422009-07-18 05:44:03 +0000205 bgp_exit (0);
paul718e3742002-12-13 20:15:29 +0000206}
207
208/* SIGUSR1 handler. */
209void
paul2d75d052004-01-19 21:31:15 +0000210sigusr1 (void)
paul718e3742002-12-13 20:15:29 +0000211{
212 zlog_rotate (NULL);
213}
Chris Caputo228da422009-07-18 05:44:03 +0000214
215/*
216 Try to free up allocations we know about so that diagnostic tools such as
217 valgrind are able to better illuminate leaks.
218
219 Zebra route removal and protocol teardown are not meant to be done here.
220 For example, "retain_mode" may be set.
221*/
222static void
223bgp_exit (int status)
224{
225 struct bgp *bgp;
226 struct listnode *node, *nnode;
227 int *socket;
228 struct interface *ifp;
229 extern struct zclient *zclient;
230 extern struct zclient *zlookup;
231
232 /* it only makes sense for this to be called on a clean exit */
233 assert (status == 0);
234
235 /* reverse bgp_master_init */
236 for (ALL_LIST_ELEMENTS (bm->bgp, node, nnode, bgp))
237 bgp_delete (bgp);
238 list_free (bm->bgp);
239
240 /* reverse bgp_master_init */
241 for (ALL_LIST_ELEMENTS_RO(bm->listen_sockets, node, socket))
242 {
243 if (close ((int)(long)socket) == -1)
244 zlog_err ("close (%d): %s", (int)(long)socket, safe_strerror (errno));
245 }
246 list_delete (bm->listen_sockets);
247
248 /* reverse bgp_zebra_init/if_init */
249 if (retain_mode)
250 if_add_hook (IF_DELETE_HOOK, NULL);
251 for (ALL_LIST_ELEMENTS (iflist, node, nnode, ifp))
Chris Caputo6c88b442010-07-27 16:28:55 +0000252 {
253 struct listnode *c_node, *c_nnode;
254 struct connected *c;
255
256 for (ALL_LIST_ELEMENTS (ifp->connected, c_node, c_nnode, c))
257 bgp_connected_delete (c);
258
259 if_delete (ifp);
260 }
Chris Caputo228da422009-07-18 05:44:03 +0000261 list_free (iflist);
262
263 /* reverse bgp_attr_init */
264 bgp_attr_finish ();
265
266 /* reverse bgp_dump_init */
267 bgp_dump_finish ();
268
269 /* reverse bgp_route_init */
270 bgp_route_finish ();
271
272 /* reverse bgp_route_map_init/route_map_init */
273 route_map_finish ();
274
275 /* reverse bgp_scan_init */
276 bgp_scan_finish ();
277
278 /* reverse access_list_init */
279 access_list_add_hook (NULL);
280 access_list_delete_hook (NULL);
281 access_list_reset ();
282
283 /* reverse bgp_filter_init */
284 as_list_add_hook (NULL);
285 as_list_delete_hook (NULL);
286 bgp_filter_reset ();
287
288 /* reverse prefix_list_init */
289 prefix_list_add_hook (NULL);
290 prefix_list_delete_hook (NULL);
291 prefix_list_reset ();
292
293 /* reverse community_list_init */
294 community_list_terminate (bgp_clist);
295
296 cmd_terminate ();
297 vty_terminate ();
298 if (zclient)
299 zclient_free (zclient);
300 if (zlookup)
301 zclient_free (zlookup);
Josh Bailey8196f132011-07-20 20:47:07 -0700302 if (bgp_nexthop_buf)
303 stream_free (bgp_nexthop_buf);
Chris Caputo228da422009-07-18 05:44:03 +0000304
305 /* reverse bgp_master_init */
306 if (master)
307 thread_master_free (master);
308
309 if (zlog_default)
310 closezlog (zlog_default);
311
312 if (CONF_BGP_DEBUG (normal, NORMAL))
313 log_memstats_stderr ("bgpd");
314
315 exit (status);
316}
paul718e3742002-12-13 20:15:29 +0000317
318/* Main routine of bgpd. Treatment of argument and start bgp finite
319 state machine is handled at here. */
320int
321main (int argc, char **argv)
322{
323 char *p;
324 int opt;
325 int daemon_mode = 0;
Paul Jakma876b8be2006-10-15 23:35:57 +0000326 int dryrun = 0;
paul718e3742002-12-13 20:15:29 +0000327 char *progname;
328 struct thread thread;
Paul Jakma0d6b2ee2008-05-29 18:29:16 +0000329 int tmp_port;
paul718e3742002-12-13 20:15:29 +0000330
331 /* Set umask before anything for security */
332 umask (0027);
333
334 /* Preserve name of myself. */
335 progname = ((p = strrchr (argv[0], '/')) ? ++p : argv[0]);
336
ajs274a4a42004-12-07 15:39:31 +0000337 zlog_default = openzlog (progname, ZLOG_BGP,
paul718e3742002-12-13 20:15:29 +0000338 LOG_CONS|LOG_NDELAY|LOG_PID, LOG_DAEMON);
339
340 /* BGP master init. */
341 bgp_master_init ();
342
343 /* Command line argument treatment. */
344 while (1)
345 {
Vyacheslav Trushkinb5114682011-11-25 18:51:48 +0400346 opt = getopt_long (argc, argv, "df:i:z:hp:l:A:P:rnu:g:vC", longopts, 0);
paul718e3742002-12-13 20:15:29 +0000347
348 if (opt == EOF)
349 break;
350
351 switch (opt)
352 {
353 case 0:
354 break;
355 case 'd':
356 daemon_mode = 1;
357 break;
358 case 'f':
359 config_file = optarg;
360 break;
361 case 'i':
362 pid_file = optarg;
363 break;
Vyacheslav Trushkinb5114682011-11-25 18:51:48 +0400364 case 'z':
365 zclient_serv_path_set (optarg);
366 break;
paul718e3742002-12-13 20:15:29 +0000367 case 'p':
Paul Jakma0d6b2ee2008-05-29 18:29:16 +0000368 tmp_port = atoi (optarg);
369 if (tmp_port <= 0 || tmp_port > 0xffff)
370 bm->port = BGP_PORT_DEFAULT;
371 else
372 bm->port = tmp_port;
paul718e3742002-12-13 20:15:29 +0000373 break;
374 case 'A':
375 vty_addr = optarg;
376 break;
377 case 'P':
paul4fc4e7a2003-01-22 19:47:09 +0000378 /* Deal with atoi() returning 0 on failure, and bgpd not
379 listening on bgp port... */
380 if (strcmp(optarg, "0") == 0)
381 {
382 vty_port = 0;
383 break;
384 }
385 vty_port = atoi (optarg);
Paul Jakma0d6b2ee2008-05-29 18:29:16 +0000386 if (vty_port <= 0 || vty_port > 0xffff)
387 vty_port = BGP_VTY_PORT;
paul718e3742002-12-13 20:15:29 +0000388 break;
389 case 'r':
390 retain_mode = 1;
391 break;
Paul Jakma3a02d1f2007-11-01 14:29:11 +0000392 case 'l':
393 bm->address = optarg;
394 /* listenon implies -n */
paul718e3742002-12-13 20:15:29 +0000395 case 'n':
396 bgp_option_set (BGP_OPT_NO_FIB);
397 break;
hassoc0652302004-11-25 19:33:48 +0000398 case 'u':
399 bgpd_privs.user = optarg;
400 break;
401 case 'g':
402 bgpd_privs.group = optarg;
403 break;
paul718e3742002-12-13 20:15:29 +0000404 case 'v':
405 print_version (progname);
406 exit (0);
407 break;
Paul Jakma876b8be2006-10-15 23:35:57 +0000408 case 'C':
409 dryrun = 1;
410 break;
paul718e3742002-12-13 20:15:29 +0000411 case 'h':
412 usage (progname, 0);
413 break;
414 default:
415 usage (progname, 1);
416 break;
417 }
418 }
419
420 /* Make thread master. */
421 master = bm->master;
422
423 /* Initializations. */
424 srand (time (NULL));
Balaji.G837d16c2012-09-26 14:09:10 +0530425 signal_init (master, array_size(bgp_signals), bgp_signals);
pauledd7c242003-06-04 13:59:38 +0000426 zprivs_init (&bgpd_privs);
paul718e3742002-12-13 20:15:29 +0000427 cmd_init (1);
paulb21b19c2003-06-15 01:28:29 +0000428 vty_init (master);
paul718e3742002-12-13 20:15:29 +0000429 memory_init ();
430
431 /* BGP related initialization. */
432 bgp_init ();
433
paul718e3742002-12-13 20:15:29 +0000434 /* Parse config file. */
hasso320ec102004-06-20 19:54:37 +0000435 vty_read_config (config_file, config_default);
paul718e3742002-12-13 20:15:29 +0000436
Paul Jakma876b8be2006-10-15 23:35:57 +0000437 /* Start execution only if not in dry-run mode */
438 if(dryrun)
439 return(0);
440
paul718e3742002-12-13 20:15:29 +0000441 /* Turn into daemon if daemon_mode is set. */
Stephen Hemminger372b3c72009-05-15 10:29:41 -0700442 if (daemon_mode && daemon (0, 0) < 0)
443 {
444 zlog_err("BGPd daemon failed: %s", strerror(errno));
445 return (1);
446 }
447
paul718e3742002-12-13 20:15:29 +0000448
449 /* Process ID file creation. */
450 pid_output (pid_file);
451
452 /* Make bgp vty socket. */
453 vty_serv_sock (vty_addr, vty_port, BGP_VTYSH_PATH);
454
455 /* Print banner. */
Paul Jakma3a02d1f2007-11-01 14:29:11 +0000456 zlog_notice ("BGPd %s starting: vty@%d, bgp@%s:%d", QUAGGA_VERSION,
Paul Jakma7e992e92007-11-13 09:32:23 +0000457 vty_port,
Paul Jakmab63e6082007-11-21 21:25:34 +0000458 (bm->address ? bm->address : "<all>"),
Paul Jakma7e992e92007-11-13 09:32:23 +0000459 bm->port);
paul718e3742002-12-13 20:15:29 +0000460
461 /* Start finite state machine, here we go! */
462 while (thread_fetch (master, &thread))
463 thread_call (&thread);
464
465 /* Not reached. */
paule8e19462006-01-19 20:16:55 +0000466 return (0);
paul718e3742002-12-13 20:15:29 +0000467}