blob: eb0fe177470f81b37e8fd7613d726b6e9bbb5a35 [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 extern struct zclient *zlookup;
234
235 /* it only makes sense for this to be called on a clean exit */
236 assert (status == 0);
237
238 /* reverse bgp_master_init */
239 for (ALL_LIST_ELEMENTS (bm->bgp, node, nnode, bgp))
240 bgp_delete (bgp);
241 list_free (bm->bgp);
Lou Berger056f3762013-04-10 12:30:04 -0700242 bm->bgp = NULL;
243
244 /*
245 * bgp_delete can re-allocate the process queues after they were
246 * deleted in bgp_terminate. delete them again.
247 *
248 * It might be better to ensure the RIBs (including static routes)
249 * are cleared by bgp_terminate() during its call to bgp_cleanup_routes(),
250 * which currently only deletes the kernel routes.
251 */
252 if (bm->process_main_queue)
253 {
254 work_queue_free (bm->process_main_queue);
255 bm->process_main_queue = NULL;
256 }
257 if (bm->process_rsclient_queue)
258 {
259 work_queue_free (bm->process_rsclient_queue);
260 bm->process_rsclient_queue = NULL;
261 }
262
Chris Caputo228da422009-07-18 05:44:03 +0000263 /* reverse bgp_master_init */
264 for (ALL_LIST_ELEMENTS_RO(bm->listen_sockets, node, socket))
265 {
266 if (close ((int)(long)socket) == -1)
267 zlog_err ("close (%d): %s", (int)(long)socket, safe_strerror (errno));
268 }
269 list_delete (bm->listen_sockets);
270
271 /* reverse bgp_zebra_init/if_init */
272 if (retain_mode)
273 if_add_hook (IF_DELETE_HOOK, NULL);
Feng Lu126215c2015-05-22 11:39:58 +0200274 for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
Chris Caputo6c88b442010-07-27 16:28:55 +0000275 {
276 struct listnode *c_node, *c_nnode;
277 struct connected *c;
278
279 for (ALL_LIST_ELEMENTS (ifp->connected, c_node, c_nnode, c))
280 bgp_connected_delete (c);
Chris Caputo6c88b442010-07-27 16:28:55 +0000281 }
Chris Caputo228da422009-07-18 05:44:03 +0000282
283 /* reverse bgp_attr_init */
284 bgp_attr_finish ();
285
286 /* reverse bgp_dump_init */
287 bgp_dump_finish ();
288
289 /* reverse bgp_route_init */
290 bgp_route_finish ();
291
292 /* reverse bgp_route_map_init/route_map_init */
293 route_map_finish ();
294
295 /* reverse bgp_scan_init */
296 bgp_scan_finish ();
297
298 /* reverse access_list_init */
299 access_list_add_hook (NULL);
300 access_list_delete_hook (NULL);
301 access_list_reset ();
302
303 /* reverse bgp_filter_init */
304 as_list_add_hook (NULL);
305 as_list_delete_hook (NULL);
306 bgp_filter_reset ();
307
308 /* reverse prefix_list_init */
309 prefix_list_add_hook (NULL);
310 prefix_list_delete_hook (NULL);
311 prefix_list_reset ();
312
313 /* reverse community_list_init */
314 community_list_terminate (bgp_clist);
315
Feng Lu126215c2015-05-22 11:39:58 +0200316 vrf_terminate ();
Chris Caputo228da422009-07-18 05:44:03 +0000317 cmd_terminate ();
318 vty_terminate ();
Lou Berger63703572016-01-12 13:42:03 -0500319 bgp_address_destroy();
320 bgp_scan_destroy();
321 bgp_zebra_destroy();
Chris Caputo228da422009-07-18 05:44:03 +0000322 if (zlookup)
323 zclient_free (zlookup);
Josh Bailey8196f132011-07-20 20:47:07 -0700324 if (bgp_nexthop_buf)
325 stream_free (bgp_nexthop_buf);
Ayan Banerjeeb8d1f712015-11-09 20:14:54 -0500326 if (bgp_ifindices_buf)
327 stream_free (bgp_ifindices_buf);
Chris Caputo228da422009-07-18 05:44:03 +0000328
329 /* reverse bgp_master_init */
Donald Sharp774914f2015-10-14 08:50:39 -0400330 if (bm->master)
331 thread_master_free (bm->master);
Chris Caputo228da422009-07-18 05:44:03 +0000332
333 if (zlog_default)
334 closezlog (zlog_default);
335
336 if (CONF_BGP_DEBUG (normal, NORMAL))
337 log_memstats_stderr ("bgpd");
338
339 exit (status);
340}
David Lamparter6b0655a2014-06-04 06:53:35 +0200341
paul718e3742002-12-13 20:15:29 +0000342/* Main routine of bgpd. Treatment of argument and start bgp finite
343 state machine is handled at here. */
344int
345main (int argc, char **argv)
346{
347 char *p;
348 int opt;
349 int daemon_mode = 0;
Paul Jakma876b8be2006-10-15 23:35:57 +0000350 int dryrun = 0;
paul718e3742002-12-13 20:15:29 +0000351 char *progname;
352 struct thread thread;
Paul Jakma0d6b2ee2008-05-29 18:29:16 +0000353 int tmp_port;
Lou Bergerac6ff462016-05-17 07:10:37 -0400354 int skip_runas = 0;
paul718e3742002-12-13 20:15:29 +0000355
356 /* Set umask before anything for security */
357 umask (0027);
358
359 /* Preserve name of myself. */
360 progname = ((p = strrchr (argv[0], '/')) ? ++p : argv[0]);
361
ajs274a4a42004-12-07 15:39:31 +0000362 zlog_default = openzlog (progname, ZLOG_BGP,
paul718e3742002-12-13 20:15:29 +0000363 LOG_CONS|LOG_NDELAY|LOG_PID, LOG_DAEMON);
364
365 /* BGP master init. */
366 bgp_master_init ();
367
368 /* Command line argument treatment. */
369 while (1)
370 {
Lou Bergerac6ff462016-05-17 07:10:37 -0400371 opt = getopt_long (argc, argv, "df:i:z:hp:l:A:P:rnu:g:vCS", longopts, 0);
paul718e3742002-12-13 20:15:29 +0000372
373 if (opt == EOF)
374 break;
375
376 switch (opt)
377 {
378 case 0:
379 break;
380 case 'd':
381 daemon_mode = 1;
382 break;
383 case 'f':
384 config_file = optarg;
385 break;
386 case 'i':
387 pid_file = optarg;
388 break;
Vyacheslav Trushkinb5114682011-11-25 18:51:48 +0400389 case 'z':
390 zclient_serv_path_set (optarg);
391 break;
paul718e3742002-12-13 20:15:29 +0000392 case 'p':
Paul Jakma0d6b2ee2008-05-29 18:29:16 +0000393 tmp_port = atoi (optarg);
394 if (tmp_port <= 0 || tmp_port > 0xffff)
395 bm->port = BGP_PORT_DEFAULT;
396 else
397 bm->port = tmp_port;
paul718e3742002-12-13 20:15:29 +0000398 break;
399 case 'A':
400 vty_addr = optarg;
401 break;
402 case 'P':
paul4fc4e7a2003-01-22 19:47:09 +0000403 /* Deal with atoi() returning 0 on failure, and bgpd not
404 listening on bgp port... */
405 if (strcmp(optarg, "0") == 0)
406 {
407 vty_port = 0;
408 break;
409 }
410 vty_port = atoi (optarg);
Paul Jakma0d6b2ee2008-05-29 18:29:16 +0000411 if (vty_port <= 0 || vty_port > 0xffff)
412 vty_port = BGP_VTY_PORT;
paul718e3742002-12-13 20:15:29 +0000413 break;
414 case 'r':
415 retain_mode = 1;
416 break;
Paul Jakma3a02d1f2007-11-01 14:29:11 +0000417 case 'l':
418 bm->address = optarg;
419 /* listenon implies -n */
paul718e3742002-12-13 20:15:29 +0000420 case 'n':
421 bgp_option_set (BGP_OPT_NO_FIB);
422 break;
hassoc0652302004-11-25 19:33:48 +0000423 case 'u':
424 bgpd_privs.user = optarg;
425 break;
426 case 'g':
427 bgpd_privs.group = optarg;
428 break;
Lou Bergerac6ff462016-05-17 07:10:37 -0400429 case 'S': /* skip run as = override bgpd_privs */
430 skip_runas = 1;
431 break;
paul718e3742002-12-13 20:15:29 +0000432 case 'v':
433 print_version (progname);
434 exit (0);
435 break;
Paul Jakma876b8be2006-10-15 23:35:57 +0000436 case 'C':
437 dryrun = 1;
438 break;
paul718e3742002-12-13 20:15:29 +0000439 case 'h':
440 usage (progname, 0);
441 break;
442 default:
443 usage (progname, 1);
444 break;
445 }
446 }
447
paul718e3742002-12-13 20:15:29 +0000448 /* Initializations. */
Donald Sharpf31bab42015-06-19 19:26:19 -0400449 srandom (time (NULL));
Donald Sharp774914f2015-10-14 08:50:39 -0400450 signal_init (bm->master, array_size(bgp_signals), bgp_signals);
Lou Bergerac6ff462016-05-17 07:10:37 -0400451 if (skip_runas)
452 memset (&bgpd_privs, 0, sizeof (bgpd_privs));
pauledd7c242003-06-04 13:59:38 +0000453 zprivs_init (&bgpd_privs);
paul718e3742002-12-13 20:15:29 +0000454 cmd_init (1);
Donald Sharp774914f2015-10-14 08:50:39 -0400455 vty_init (bm->master);
paul718e3742002-12-13 20:15:29 +0000456 memory_init ();
Feng Lu126215c2015-05-22 11:39:58 +0200457 vrf_init ();
paul718e3742002-12-13 20:15:29 +0000458
459 /* BGP related initialization. */
460 bgp_init ();
461
paul718e3742002-12-13 20:15:29 +0000462 /* Parse config file. */
hasso320ec102004-06-20 19:54:37 +0000463 vty_read_config (config_file, config_default);
paul718e3742002-12-13 20:15:29 +0000464
Paul Jakma876b8be2006-10-15 23:35:57 +0000465 /* Start execution only if not in dry-run mode */
466 if(dryrun)
467 return(0);
468
paul718e3742002-12-13 20:15:29 +0000469 /* Turn into daemon if daemon_mode is set. */
Stephen Hemminger372b3c72009-05-15 10:29:41 -0700470 if (daemon_mode && daemon (0, 0) < 0)
471 {
472 zlog_err("BGPd daemon failed: %s", strerror(errno));
473 return (1);
474 }
475
paul718e3742002-12-13 20:15:29 +0000476
477 /* Process ID file creation. */
478 pid_output (pid_file);
479
480 /* Make bgp vty socket. */
481 vty_serv_sock (vty_addr, vty_port, BGP_VTYSH_PATH);
482
483 /* Print banner. */
Lou Berger056f3762013-04-10 12:30:04 -0700484 zlog_notice ("BGPd %s starting: vty@%d, bgp@%s:%d pid %d", QUAGGA_VERSION,
Paul Jakma7e992e92007-11-13 09:32:23 +0000485 vty_port,
Paul Jakmab63e6082007-11-21 21:25:34 +0000486 (bm->address ? bm->address : "<all>"),
Lou Berger056f3762013-04-10 12:30:04 -0700487 bm->port,
488 getpid ());
paul718e3742002-12-13 20:15:29 +0000489
490 /* Start finite state machine, here we go! */
Donald Sharp774914f2015-10-14 08:50:39 -0400491 while (thread_fetch (bm->master, &thread))
paul718e3742002-12-13 20:15:29 +0000492 thread_call (&thread);
493
494 /* Not reached. */
paule8e19462006-01-19 20:16:55 +0000495 return (0);
paul718e3742002-12-13 20:15:29 +0000496}