blob: af9c03052020db2065ff22d9c27c554915292ca2 [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"
Feng Lu126215c2015-05-22 11:39:58 +020039#include "vrf.h"
Lou Berger056f3762013-04-10 12:30:04 -070040#include "workqueue.h"
paul718e3742002-12-13 20:15:29 +000041
42#include "bgpd/bgpd.h"
43#include "bgpd/bgp_attr.h"
44#include "bgpd/bgp_mplsvpn.h"
Chris Caputo228da422009-07-18 05:44:03 +000045#include "bgpd/bgp_aspath.h"
46#include "bgpd/bgp_dump.h"
47#include "bgpd/bgp_route.h"
48#include "bgpd/bgp_nexthop.h"
49#include "bgpd/bgp_regex.h"
50#include "bgpd/bgp_clist.h"
51#include "bgpd/bgp_debug.h"
52#include "bgpd/bgp_filter.h"
Josh Bailey8196f132011-07-20 20:47:07 -070053#include "bgpd/bgp_zebra.h"
paul718e3742002-12-13 20:15:29 +000054
55/* bgpd options, we use GNU getopt library. */
Stephen Hemminger372b3c72009-05-15 10:29:41 -070056static const struct option longopts[] =
paul718e3742002-12-13 20:15:29 +000057{
58 { "daemon", no_argument, NULL, 'd'},
59 { "config_file", required_argument, NULL, 'f'},
60 { "pid_file", required_argument, NULL, 'i'},
Vyacheslav Trushkinb5114682011-11-25 18:51:48 +040061 { "socket", required_argument, NULL, 'z'},
paul718e3742002-12-13 20:15:29 +000062 { "bgp_port", required_argument, NULL, 'p'},
Paul Jakma3a02d1f2007-11-01 14:29:11 +000063 { "listenon", required_argument, NULL, 'l'},
paul718e3742002-12-13 20:15:29 +000064 { "vty_addr", required_argument, NULL, 'A'},
65 { "vty_port", required_argument, NULL, 'P'},
66 { "retain", no_argument, NULL, 'r'},
67 { "no_kernel", no_argument, NULL, 'n'},
pauledd7c242003-06-04 13:59:38 +000068 { "user", required_argument, NULL, 'u'},
hassoc0652302004-11-25 19:33:48 +000069 { "group", required_argument, NULL, 'g'},
Lou Bergerac6ff462016-05-17 07:10:37 -040070 { "skip_runas", no_argument, NULL, 'S'},
paul718e3742002-12-13 20:15:29 +000071 { "version", no_argument, NULL, 'v'},
Paul Jakma876b8be2006-10-15 23:35:57 +000072 { "dryrun", no_argument, NULL, 'C'},
paul718e3742002-12-13 20:15:29 +000073 { "help", no_argument, NULL, 'h'},
74 { 0 }
75};
76
paul2d75d052004-01-19 21:31:15 +000077/* signal definitions */
78void sighup (void);
79void sigint (void);
80void sigusr1 (void);
81
Chris Caputo228da422009-07-18 05:44:03 +000082static void bgp_exit (int);
83
Stephen Hemminger372b3c72009-05-15 10:29:41 -070084static struct quagga_signal_t bgp_signals[] =
paul2d75d052004-01-19 21:31:15 +000085{
86 {
87 .signal = SIGHUP,
88 .handler = &sighup,
89 },
90 {
91 .signal = SIGUSR1,
92 .handler = &sigusr1,
93 },
94 {
95 .signal = SIGINT,
96 .handler = &sigint,
97 },
hassof571dab2004-03-22 08:55:25 +000098 {
99 .signal = SIGTERM,
100 .handler = &sigint,
101 },
paul2d75d052004-01-19 21:31:15 +0000102};
103
paul718e3742002-12-13 20:15:29 +0000104/* Configuration file and directory. */
paul718e3742002-12-13 20:15:29 +0000105char config_default[] = SYSCONFDIR BGP_DEFAULT_CONFIG;
106
107/* Route retain mode flag. */
Stephen Hemminger372b3c72009-05-15 10:29:41 -0700108static int retain_mode = 0;
paul718e3742002-12-13 20:15:29 +0000109
paul718e3742002-12-13 20:15:29 +0000110/* 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\
Lou Bergerac6ff462016-05-17 07:10:37 -0400165-S, --skip_runas Skip user and group run as\n\
paul718e3742002-12-13 20:15:29 +0000166-v, --version Print program version\n\
Paul Jakma876b8be2006-10-15 23:35:57 +0000167-C, --dryrun Check configuration for validity and exit\n\
paul718e3742002-12-13 20:15:29 +0000168-h, --help Display this help and exit\n\
169\n\
170Report bugs to %s\n", progname, ZEBRA_BUG_ADDRESS);
171 }
172
173 exit (status);
174}
David Lamparter6b0655a2014-06-04 06:53:35 +0200175
paul718e3742002-12-13 20:15:29 +0000176/* SIGHUP handler. */
177void
paul2d75d052004-01-19 21:31:15 +0000178sighup (void)
paul718e3742002-12-13 20:15:29 +0000179{
180 zlog (NULL, LOG_INFO, "SIGHUP received");
181
182 /* Terminate all thread. */
183 bgp_terminate ();
184 bgp_reset ();
185 zlog_info ("bgpd restarting!");
186
187 /* Reload config file. */
hasso320ec102004-06-20 19:54:37 +0000188 vty_read_config (config_file, config_default);
paul718e3742002-12-13 20:15:29 +0000189
190 /* Create VTY's socket */
paul4fc4e7a2003-01-22 19:47:09 +0000191 vty_serv_sock (vty_addr, vty_port, BGP_VTYSH_PATH);
paul718e3742002-12-13 20:15:29 +0000192
193 /* Try to return to normal operation. */
194}
195
196/* SIGINT handler. */
197void
paul2d75d052004-01-19 21:31:15 +0000198sigint (void)
paul718e3742002-12-13 20:15:29 +0000199{
ajs887c44a2004-12-03 16:36:46 +0000200 zlog_notice ("Terminating on signal");
paul718e3742002-12-13 20:15:29 +0000201
Lou Berger056f3762013-04-10 12:30:04 -0700202 if (! retain_mode)
203 {
204 bgp_terminate ();
Lou Bergerac6ff462016-05-17 07:10:37 -0400205 if (bgpd_privs.user) /* NULL if skip_runas flag set */
206 zprivs_terminate (&bgpd_privs);
Lou Berger056f3762013-04-10 12:30:04 -0700207 }
paul718e3742002-12-13 20:15:29 +0000208
Chris Caputo228da422009-07-18 05:44:03 +0000209 bgp_exit (0);
paul718e3742002-12-13 20:15:29 +0000210}
211
212/* SIGUSR1 handler. */
213void
paul2d75d052004-01-19 21:31:15 +0000214sigusr1 (void)
paul718e3742002-12-13 20:15:29 +0000215{
216 zlog_rotate (NULL);
217}
Chris Caputo228da422009-07-18 05:44:03 +0000218
219/*
220 Try to free up allocations we know about so that diagnostic tools such as
221 valgrind are able to better illuminate leaks.
222
223 Zebra route removal and protocol teardown are not meant to be done here.
224 For example, "retain_mode" may be set.
225*/
226static void
227bgp_exit (int status)
228{
229 struct bgp *bgp;
230 struct listnode *node, *nnode;
231 int *socket;
232 struct interface *ifp;
Chris Caputo228da422009-07-18 05:44:03 +0000233
234 /* it only makes sense for this to be called on a clean exit */
235 assert (status == 0);
236
237 /* reverse bgp_master_init */
238 for (ALL_LIST_ELEMENTS (bm->bgp, node, nnode, bgp))
239 bgp_delete (bgp);
240 list_free (bm->bgp);
Lou Berger056f3762013-04-10 12:30:04 -0700241 bm->bgp = NULL;
242
243 /*
244 * bgp_delete can re-allocate the process queues after they were
245 * deleted in bgp_terminate. delete them again.
246 *
247 * It might be better to ensure the RIBs (including static routes)
248 * are cleared by bgp_terminate() during its call to bgp_cleanup_routes(),
249 * which currently only deletes the kernel routes.
250 */
251 if (bm->process_main_queue)
252 {
253 work_queue_free (bm->process_main_queue);
254 bm->process_main_queue = NULL;
255 }
256 if (bm->process_rsclient_queue)
257 {
258 work_queue_free (bm->process_rsclient_queue);
259 bm->process_rsclient_queue = NULL;
260 }
261
Chris Caputo228da422009-07-18 05:44:03 +0000262 /* reverse bgp_master_init */
263 for (ALL_LIST_ELEMENTS_RO(bm->listen_sockets, node, socket))
264 {
265 if (close ((int)(long)socket) == -1)
266 zlog_err ("close (%d): %s", (int)(long)socket, safe_strerror (errno));
267 }
268 list_delete (bm->listen_sockets);
269
270 /* reverse bgp_zebra_init/if_init */
271 if (retain_mode)
272 if_add_hook (IF_DELETE_HOOK, NULL);
Feng Lu126215c2015-05-22 11:39:58 +0200273 for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
Chris Caputo6c88b442010-07-27 16:28:55 +0000274 {
275 struct listnode *c_node, *c_nnode;
276 struct connected *c;
277
278 for (ALL_LIST_ELEMENTS (ifp->connected, c_node, c_nnode, c))
279 bgp_connected_delete (c);
Chris Caputo6c88b442010-07-27 16:28:55 +0000280 }
Chris Caputo228da422009-07-18 05:44:03 +0000281
282 /* reverse bgp_attr_init */
283 bgp_attr_finish ();
284
285 /* reverse bgp_dump_init */
286 bgp_dump_finish ();
287
288 /* reverse bgp_route_init */
289 bgp_route_finish ();
290
291 /* reverse bgp_route_map_init/route_map_init */
292 route_map_finish ();
293
Chris Caputo228da422009-07-18 05:44:03 +0000294 /* reverse access_list_init */
295 access_list_add_hook (NULL);
296 access_list_delete_hook (NULL);
297 access_list_reset ();
298
299 /* reverse bgp_filter_init */
300 as_list_add_hook (NULL);
301 as_list_delete_hook (NULL);
302 bgp_filter_reset ();
303
304 /* reverse prefix_list_init */
305 prefix_list_add_hook (NULL);
306 prefix_list_delete_hook (NULL);
307 prefix_list_reset ();
308
309 /* reverse community_list_init */
310 community_list_terminate (bgp_clist);
311
Feng Lu126215c2015-05-22 11:39:58 +0200312 vrf_terminate ();
Chris Caputo228da422009-07-18 05:44:03 +0000313 cmd_terminate ();
314 vty_terminate ();
Lou Berger63703572016-01-12 13:42:03 -0500315 bgp_address_destroy();
316 bgp_scan_destroy();
317 bgp_zebra_destroy();
Josh Bailey8196f132011-07-20 20:47:07 -0700318 if (bgp_nexthop_buf)
319 stream_free (bgp_nexthop_buf);
Ayan Banerjeeb8d1f712015-11-09 20:14:54 -0500320 if (bgp_ifindices_buf)
321 stream_free (bgp_ifindices_buf);
Chris Caputo228da422009-07-18 05:44:03 +0000322
Dinesh Duttd9ab53a2015-05-19 17:47:21 -0700323 /* reverse bgp_scan_init */
324 bgp_scan_finish ();
325
Chris Caputo228da422009-07-18 05:44:03 +0000326 /* reverse bgp_master_init */
Donald Sharp774914f2015-10-14 08:50:39 -0400327 if (bm->master)
328 thread_master_free (bm->master);
Chris Caputo228da422009-07-18 05:44:03 +0000329
330 if (zlog_default)
331 closezlog (zlog_default);
332
333 if (CONF_BGP_DEBUG (normal, NORMAL))
334 log_memstats_stderr ("bgpd");
335
336 exit (status);
337}
David Lamparter6b0655a2014-06-04 06:53:35 +0200338
paul718e3742002-12-13 20:15:29 +0000339/* Main routine of bgpd. Treatment of argument and start bgp finite
340 state machine is handled at here. */
341int
342main (int argc, char **argv)
343{
344 char *p;
345 int opt;
346 int daemon_mode = 0;
Paul Jakma876b8be2006-10-15 23:35:57 +0000347 int dryrun = 0;
paul718e3742002-12-13 20:15:29 +0000348 char *progname;
349 struct thread thread;
Paul Jakma0d6b2ee2008-05-29 18:29:16 +0000350 int tmp_port;
Lou Bergerac6ff462016-05-17 07:10:37 -0400351 int skip_runas = 0;
paul718e3742002-12-13 20:15:29 +0000352
353 /* Set umask before anything for security */
354 umask (0027);
355
356 /* Preserve name of myself. */
357 progname = ((p = strrchr (argv[0], '/')) ? ++p : argv[0]);
358
ajs274a4a42004-12-07 15:39:31 +0000359 zlog_default = openzlog (progname, ZLOG_BGP,
paul718e3742002-12-13 20:15:29 +0000360 LOG_CONS|LOG_NDELAY|LOG_PID, LOG_DAEMON);
361
362 /* BGP master init. */
363 bgp_master_init ();
364
365 /* Command line argument treatment. */
366 while (1)
367 {
Lou Bergerac6ff462016-05-17 07:10:37 -0400368 opt = getopt_long (argc, argv, "df:i:z:hp:l:A:P:rnu:g:vCS", longopts, 0);
paul718e3742002-12-13 20:15:29 +0000369
370 if (opt == EOF)
371 break;
372
373 switch (opt)
374 {
375 case 0:
376 break;
377 case 'd':
378 daemon_mode = 1;
379 break;
380 case 'f':
381 config_file = optarg;
382 break;
383 case 'i':
384 pid_file = optarg;
385 break;
Vyacheslav Trushkinb5114682011-11-25 18:51:48 +0400386 case 'z':
387 zclient_serv_path_set (optarg);
388 break;
paul718e3742002-12-13 20:15:29 +0000389 case 'p':
Paul Jakma0d6b2ee2008-05-29 18:29:16 +0000390 tmp_port = atoi (optarg);
391 if (tmp_port <= 0 || tmp_port > 0xffff)
392 bm->port = BGP_PORT_DEFAULT;
393 else
394 bm->port = tmp_port;
paul718e3742002-12-13 20:15:29 +0000395 break;
396 case 'A':
397 vty_addr = optarg;
398 break;
399 case 'P':
paul4fc4e7a2003-01-22 19:47:09 +0000400 /* Deal with atoi() returning 0 on failure, and bgpd not
401 listening on bgp port... */
402 if (strcmp(optarg, "0") == 0)
403 {
404 vty_port = 0;
405 break;
406 }
407 vty_port = atoi (optarg);
Paul Jakma0d6b2ee2008-05-29 18:29:16 +0000408 if (vty_port <= 0 || vty_port > 0xffff)
409 vty_port = BGP_VTY_PORT;
paul718e3742002-12-13 20:15:29 +0000410 break;
411 case 'r':
412 retain_mode = 1;
413 break;
Paul Jakma3a02d1f2007-11-01 14:29:11 +0000414 case 'l':
415 bm->address = optarg;
416 /* listenon implies -n */
paul718e3742002-12-13 20:15:29 +0000417 case 'n':
418 bgp_option_set (BGP_OPT_NO_FIB);
419 break;
hassoc0652302004-11-25 19:33:48 +0000420 case 'u':
421 bgpd_privs.user = optarg;
422 break;
423 case 'g':
424 bgpd_privs.group = optarg;
425 break;
Lou Bergerac6ff462016-05-17 07:10:37 -0400426 case 'S': /* skip run as = override bgpd_privs */
427 skip_runas = 1;
428 break;
paul718e3742002-12-13 20:15:29 +0000429 case 'v':
430 print_version (progname);
431 exit (0);
432 break;
Paul Jakma876b8be2006-10-15 23:35:57 +0000433 case 'C':
434 dryrun = 1;
435 break;
paul718e3742002-12-13 20:15:29 +0000436 case 'h':
437 usage (progname, 0);
438 break;
439 default:
440 usage (progname, 1);
441 break;
442 }
443 }
444
paul718e3742002-12-13 20:15:29 +0000445 /* Initializations. */
Donald Sharpf31bab42015-06-19 19:26:19 -0400446 srandom (time (NULL));
Donald Sharp774914f2015-10-14 08:50:39 -0400447 signal_init (bm->master, array_size(bgp_signals), bgp_signals);
Lou Bergerac6ff462016-05-17 07:10:37 -0400448 if (skip_runas)
449 memset (&bgpd_privs, 0, sizeof (bgpd_privs));
pauledd7c242003-06-04 13:59:38 +0000450 zprivs_init (&bgpd_privs);
paul718e3742002-12-13 20:15:29 +0000451 cmd_init (1);
Donald Sharp774914f2015-10-14 08:50:39 -0400452 vty_init (bm->master);
paul718e3742002-12-13 20:15:29 +0000453 memory_init ();
Feng Lu126215c2015-05-22 11:39:58 +0200454 vrf_init ();
paul718e3742002-12-13 20:15:29 +0000455
456 /* BGP related initialization. */
457 bgp_init ();
458
paul718e3742002-12-13 20:15:29 +0000459 /* Parse config file. */
hasso320ec102004-06-20 19:54:37 +0000460 vty_read_config (config_file, config_default);
paul718e3742002-12-13 20:15:29 +0000461
Paul Jakma876b8be2006-10-15 23:35:57 +0000462 /* Start execution only if not in dry-run mode */
463 if(dryrun)
464 return(0);
465
paul718e3742002-12-13 20:15:29 +0000466 /* Turn into daemon if daemon_mode is set. */
Stephen Hemminger372b3c72009-05-15 10:29:41 -0700467 if (daemon_mode && daemon (0, 0) < 0)
468 {
469 zlog_err("BGPd daemon failed: %s", strerror(errno));
470 return (1);
471 }
472
paul718e3742002-12-13 20:15:29 +0000473
474 /* Process ID file creation. */
475 pid_output (pid_file);
476
477 /* Make bgp vty socket. */
478 vty_serv_sock (vty_addr, vty_port, BGP_VTYSH_PATH);
479
480 /* Print banner. */
Lou Berger056f3762013-04-10 12:30:04 -0700481 zlog_notice ("BGPd %s starting: vty@%d, bgp@%s:%d pid %d", QUAGGA_VERSION,
Paul Jakma7e992e92007-11-13 09:32:23 +0000482 vty_port,
Paul Jakmab63e6082007-11-21 21:25:34 +0000483 (bm->address ? bm->address : "<all>"),
Lou Berger056f3762013-04-10 12:30:04 -0700484 bm->port,
485 getpid ());
paul718e3742002-12-13 20:15:29 +0000486
487 /* Start finite state machine, here we go! */
Donald Sharp774914f2015-10-14 08:50:39 -0400488 while (thread_fetch (bm->master, &thread))
paul718e3742002-12-13 20:15:29 +0000489 thread_call (&thread);
490
491 /* Not reached. */
paule8e19462006-01-19 20:16:55 +0000492 return (0);
paul718e3742002-12-13 20:15:29 +0000493}