]> git.proxmox.com Git - mirror_frr.git/blame - bgpd/bgp_main.c
lib: add skiplist
[mirror_frr.git] / bgpd / bgp_main.c
CommitLineData
718e3744 1/* 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"
5e4fa164 28#include <lib/version.h>
718e3744 29#include "memory.h"
fc7948fa 30#include "memory_vty.h"
718e3744 31#include "prefix.h"
32#include "log.h"
edd7c245 33#include "privs.h"
2d75d052 34#include "sigevent.h"
228da428
CC
35#include "zclient.h"
36#include "routemap.h"
37#include "filter.h"
38#include "plist.h"
8196f13d 39#include "stream.h"
3f9c7369 40#include "queue.h"
6a69b354 41#include "vrf.h"
567b877d 42#include "bfd.h"
718e3744 43
44#include "bgpd/bgpd.h"
45#include "bgpd/bgp_attr.h"
46#include "bgpd/bgp_mplsvpn.h"
228da428
CC
47#include "bgpd/bgp_aspath.h"
48#include "bgpd/bgp_dump.h"
49#include "bgpd/bgp_route.h"
50#include "bgpd/bgp_nexthop.h"
51#include "bgpd/bgp_regex.h"
52#include "bgpd/bgp_clist.h"
53#include "bgpd/bgp_debug.h"
54#include "bgpd/bgp_filter.h"
8196f13d 55#include "bgpd/bgp_zebra.h"
718e3744 56
57/* bgpd options, we use GNU getopt library. */
372b3c70 58static const struct option longopts[] =
718e3744 59{
60 { "daemon", no_argument, NULL, 'd'},
61 { "config_file", required_argument, NULL, 'f'},
62 { "pid_file", required_argument, NULL, 'i'},
b5114685 63 { "socket", required_argument, NULL, 'z'},
718e3744 64 { "bgp_port", required_argument, NULL, 'p'},
3a02d1f7 65 { "listenon", required_argument, NULL, 'l'},
718e3744 66 { "vty_addr", required_argument, NULL, 'A'},
67 { "vty_port", required_argument, NULL, 'P'},
68 { "retain", no_argument, NULL, 'r'},
69 { "no_kernel", no_argument, NULL, 'n'},
edd7c245 70 { "user", required_argument, NULL, 'u'},
c065230a 71 { "group", required_argument, NULL, 'g'},
a008f49a 72 { "skip_runas", no_argument, NULL, 'S'},
718e3744 73 { "version", no_argument, NULL, 'v'},
876b8be0 74 { "dryrun", no_argument, NULL, 'C'},
718e3744 75 { "help", no_argument, NULL, 'h'},
76 { 0 }
77};
78
2d75d052 79/* signal definitions */
80void sighup (void);
81void sigint (void);
82void sigusr1 (void);
83
228da428 84static void bgp_exit (int);
021530c1 85static void bgp_vrf_terminate (void);
228da428 86
372b3c70 87static struct quagga_signal_t bgp_signals[] =
2d75d052 88{
89 {
90 .signal = SIGHUP,
91 .handler = &sighup,
92 },
93 {
94 .signal = SIGUSR1,
95 .handler = &sigusr1,
96 },
97 {
98 .signal = SIGINT,
99 .handler = &sigint,
f571dab0 100 },
101 {
102 .signal = SIGTERM,
103 .handler = &sigint,
2d75d052 104 },
105};
106
718e3744 107/* Configuration file and directory. */
718e3744 108char config_default[] = SYSCONFDIR BGP_DEFAULT_CONFIG;
109
110/* Route retain mode flag. */
372b3c70 111static int retain_mode = 0;
718e3744 112
718e3744 113/* Manually specified configuration file name. */
114char *config_file = NULL;
115
116/* Process ID saved for use by init system */
372b3c70 117static const char *pid_file = PATH_BGPD_PID;
718e3744 118
119/* VTY port number and address. */
120int vty_port = BGP_VTY_PORT;
121char *vty_addr = NULL;
122
edd7c245 123/* privileges */
372b3c70 124static zebra_capabilities_t _caps_p [] =
edd7c245 125{
98f5163c 126 ZCAP_BIND,
ceacedba 127 ZCAP_NET_RAW,
5c88f19d 128 ZCAP_NET_ADMIN,
edd7c245 129};
130
131struct zebra_privs_t bgpd_privs =
132{
d81fadfd 133#if defined(QUAGGA_USER) && defined(QUAGGA_GROUP)
134 .user = QUAGGA_USER,
135 .group = QUAGGA_GROUP,
136#endif
137#ifdef VTY_GROUP
138 .vty_group = VTY_GROUP,
edd7c245 139#endif
140 .caps_p = _caps_p,
837d16cc 141 .cap_num_p = array_size(_caps_p),
edd7c245 142 .cap_num_i = 0,
143};
144
718e3744 145/* Help information display. */
146static void
147usage (char *progname, int status)
148{
149 if (status != 0)
150 fprintf (stderr, "Try `%s --help' for more information.\n", progname);
151 else
152 {
153 printf ("Usage : %s [OPTION...]\n\n\
154Daemon which manages kernel routing table management and \
155redistribution between different routing protocols.\n\n\
156-d, --daemon Runs in daemon mode\n\
157-f, --config_file Set configuration file name\n\
158-i, --pid_file Set process identifier file name\n\
b5114685 159-z, --socket Set path of zebra socket\n\
718e3744 160-p, --bgp_port Set bgp protocol's port number\n\
3a02d1f7 161-l, --listenon Listen on specified address (implies -n)\n\
718e3744 162-A, --vty_addr Set vty's bind address\n\
163-P, --vty_port Set vty's port number\n\
164-r, --retain When program terminates, retain added route by bgpd.\n\
165-n, --no_kernel Do not install route to kernel.\n\
c065230a 166-u, --user User to run as\n\
167-g, --group Group to run as\n\
a008f49a 168-S, --skip_runas Skip user and group run as\n\
718e3744 169-v, --version Print program version\n\
876b8be0 170-C, --dryrun Check configuration for validity and exit\n\
718e3744 171-h, --help Display this help and exit\n\
172\n\
173Report bugs to %s\n", progname, ZEBRA_BUG_ADDRESS);
174 }
175
176 exit (status);
177}
6b0655a2 178
718e3744 179/* SIGHUP handler. */
180void
2d75d052 181sighup (void)
718e3744 182{
16286195 183 zlog_info ("SIGHUP received");
718e3744 184
185 /* Terminate all thread. */
186 bgp_terminate ();
187 bgp_reset ();
188 zlog_info ("bgpd restarting!");
189
190 /* Reload config file. */
320ec10a 191 vty_read_config (config_file, config_default);
718e3744 192
193 /* Create VTY's socket */
4fc4e7ab 194 vty_serv_sock (vty_addr, vty_port, BGP_VTYSH_PATH);
718e3744 195
196 /* Try to return to normal operation. */
197}
198
199/* SIGINT handler. */
35dece84 200__attribute__((__noreturn__)) void
2d75d052 201sigint (void)
718e3744 202{
887c44a4 203 zlog_notice ("Terminating on signal");
718e3744 204
205 if (! retain_mode)
a008f49a
LB
206 {
207 bgp_terminate ();
208 if (bgpd_privs.user) /* NULL if skip_runas flag set */
209 zprivs_terminate (&bgpd_privs);
210 }
718e3744 211
228da428 212 bgp_exit (0);
540766e7
DS
213
214 exit (0);
718e3744 215}
216
217/* SIGUSR1 handler. */
218void
2d75d052 219sigusr1 (void)
718e3744 220{
221 zlog_rotate (NULL);
222}
228da428
CC
223
224/*
225 Try to free up allocations we know about so that diagnostic tools such as
226 valgrind are able to better illuminate leaks.
227
228 Zebra route removal and protocol teardown are not meant to be done here.
229 For example, "retain_mode" may be set.
230*/
35dece84 231static __attribute__((__noreturn__)) void
228da428
CC
232bgp_exit (int status)
233{
234 struct bgp *bgp;
235 struct listnode *node, *nnode;
228da428
CC
236
237 /* it only makes sense for this to be called on a clean exit */
238 assert (status == 0);
239
567b877d 240 bfd_gbl_exit();
241
1ff9a340
DS
242 bgp_close();
243
228da428
CC
244 if (retain_mode)
245 if_add_hook (IF_DELETE_HOOK, NULL);
ad4cbda1 246
46abd3e3 247 /* reverse bgp_master_init */
248 for (ALL_LIST_ELEMENTS (bm->bgp, node, nnode, bgp))
249 bgp_delete (bgp);
250 list_free (bm->bgp);
251
228da428
CC
252 /* reverse bgp_attr_init */
253 bgp_attr_finish ();
254
255 /* reverse bgp_dump_init */
256 bgp_dump_finish ();
257
258 /* reverse bgp_route_init */
259 bgp_route_finish ();
260
518f0eb1
DS
261 /* cleanup route maps */
262 bgp_route_map_terminate();
228da428 263
228da428
CC
264 /* reverse access_list_init */
265 access_list_add_hook (NULL);
266 access_list_delete_hook (NULL);
267 access_list_reset ();
268
269 /* reverse bgp_filter_init */
270 as_list_add_hook (NULL);
271 as_list_delete_hook (NULL);
272 bgp_filter_reset ();
273
274 /* reverse prefix_list_init */
275 prefix_list_add_hook (NULL);
276 prefix_list_delete_hook (NULL);
277 prefix_list_reset ();
278
279 /* reverse community_list_init */
280 community_list_terminate (bgp_clist);
281
021530c1 282 bgp_vrf_terminate ();
228da428
CC
283 cmd_terminate ();
284 vty_terminate ();
2f35bbfe
LB
285
286 bgp_zebra_destroy();
8196f13d
JB
287 if (bgp_nexthop_buf)
288 stream_free (bgp_nexthop_buf);
431aa9f9
DS
289 if (bgp_ifindices_buf)
290 stream_free (bgp_ifindices_buf);
228da428
CC
291
292 /* reverse bgp_master_init */
9229d914
DS
293 if (bm->master)
294 thread_master_free (bm->master);
228da428
CC
295
296 if (zlog_default)
297 closezlog (zlog_default);
298
90dcf2d7
LB
299 if (bgp_debug_count())
300 log_memstats_stderr ("bgpd");
228da428
CC
301 exit (status);
302}
6b0655a2 303
2fcc254e
DS
304static int
305bgp_vrf_new (vrf_id_t vrf_id, const char *name, void **info)
306{
307 if (BGP_DEBUG (zebra, ZEBRA))
308 zlog_debug ("VRF Created: %s(%d)", name, vrf_id);
309
310 return 0;
311}
312
313static int
314bgp_vrf_delete (vrf_id_t vrf_id, const char *name, void **info)
315{
316 if (BGP_DEBUG (zebra, ZEBRA))
317 zlog_debug ("VRF Deletion: %s(%d)", name, vrf_id);
318
319 return 0;
320}
321
322static int
323bgp_vrf_enable (vrf_id_t vrf_id, const char *name, void **info)
324{
325 struct vrf *vrf;
326 struct bgp *bgp;
eb117f29 327 vrf_id_t old_vrf_id;
2fcc254e
DS
328
329 vrf = vrf_lookup (vrf_id);
330 if (!vrf) // unexpected
331 return -1;
332
333 if (BGP_DEBUG (zebra, ZEBRA))
334 zlog_debug("VRF enable add %s id %d", name, vrf_id);
335
336 bgp = bgp_lookup_by_name(name);
337 if (bgp)
338 {
eb117f29 339 old_vrf_id = bgp->vrf_id;
2fcc254e
DS
340 /* We have instance configured, link to VRF and make it "up". */
341 bgp_vrf_link (bgp, vrf);
eb117f29
SK
342
343 /* Update any redistribute vrf bitmaps if the vrf_id changed */
344 if (old_vrf_id != bgp->vrf_id)
345 bgp_update_redist_vrf_bitmaps(bgp, old_vrf_id);
2fcc254e
DS
346 bgp_instance_up (bgp);
347 }
348
349 return 0;
350}
351
352static int
353bgp_vrf_disable (vrf_id_t vrf_id, const char *name, void **info)
354{
355 struct vrf *vrf;
356 struct bgp *bgp;
eb117f29 357 vrf_id_t old_vrf_id;
2fcc254e
DS
358
359 if (vrf_id == VRF_DEFAULT)
360 return 0;
361
362 vrf = vrf_lookup (vrf_id);
363 if (!vrf) // unexpected
364 return -1;
365
366 if (BGP_DEBUG (zebra, ZEBRA))
367 zlog_debug("VRF disable %s id %d", name, vrf_id);
368
369 bgp = bgp_lookup_by_name(name);
370 if (bgp)
371 {
eb117f29 372 old_vrf_id = bgp->vrf_id;
2fcc254e
DS
373 /* We have instance configured, unlink from VRF and make it "down". */
374 bgp_vrf_unlink (bgp, vrf);
eb117f29
SK
375 /* Update any redistribute vrf bitmaps if the vrf_id changed */
376 if (old_vrf_id != bgp->vrf_id)
377 bgp_update_redist_vrf_bitmaps(bgp, old_vrf_id);
2fcc254e
DS
378 bgp_instance_down (bgp);
379 }
380
381 /* Note: This is a callback, the VRF will be deleted by the caller. */
382 return 0;
383}
384
385static void
386bgp_vrf_init (void)
387{
388 vrf_add_hook (VRF_NEW_HOOK, bgp_vrf_new);
389 vrf_add_hook (VRF_ENABLE_HOOK, bgp_vrf_enable);
390 vrf_add_hook (VRF_DISABLE_HOOK, bgp_vrf_disable);
391 vrf_add_hook (VRF_DELETE_HOOK, bgp_vrf_delete);
392
393 vrf_init ();
394}
395
021530c1 396static void
397bgp_vrf_terminate (void)
398{
399 vrf_add_hook (VRF_NEW_HOOK, NULL);
400 vrf_add_hook (VRF_ENABLE_HOOK, NULL);
401 vrf_add_hook (VRF_DISABLE_HOOK, NULL);
402 vrf_add_hook (VRF_DELETE_HOOK, NULL);
403
404 vrf_terminate ();
405}
406
718e3744 407/* Main routine of bgpd. Treatment of argument and start bgp finite
408 state machine is handled at here. */
409int
410main (int argc, char **argv)
411{
412 char *p;
413 int opt;
414 int daemon_mode = 0;
876b8be0 415 int dryrun = 0;
718e3744 416 char *progname;
417 struct thread thread;
0d6b2ee2 418 int tmp_port;
a008f49a 419 int skip_runas = 0;
718e3744 420
421 /* Set umask before anything for security */
422 umask (0027);
423
424 /* Preserve name of myself. */
425 progname = ((p = strrchr (argv[0], '/')) ? ++p : argv[0]);
426
718e3744 427 /* BGP master init. */
428 bgp_master_init ();
429
430 /* Command line argument treatment. */
431 while (1)
432 {
a008f49a 433 opt = getopt_long (argc, argv, "df:i:z:hp:l:A:P:rnu:g:vCS", longopts, 0);
718e3744 434
435 if (opt == EOF)
436 break;
437
438 switch (opt)
439 {
440 case 0:
441 break;
442 case 'd':
443 daemon_mode = 1;
444 break;
445 case 'f':
446 config_file = optarg;
447 break;
448 case 'i':
449 pid_file = optarg;
450 break;
b5114685
VT
451 case 'z':
452 zclient_serv_path_set (optarg);
453 break;
718e3744 454 case 'p':
0d6b2ee2
PJ
455 tmp_port = atoi (optarg);
456 if (tmp_port <= 0 || tmp_port > 0xffff)
457 bm->port = BGP_PORT_DEFAULT;
458 else
459 bm->port = tmp_port;
718e3744 460 break;
461 case 'A':
462 vty_addr = optarg;
463 break;
464 case 'P':
4fc4e7ab 465 /* Deal with atoi() returning 0 on failure, and bgpd not
466 listening on bgp port... */
467 if (strcmp(optarg, "0") == 0)
468 {
469 vty_port = 0;
470 break;
471 }
472 vty_port = atoi (optarg);
0d6b2ee2
PJ
473 if (vty_port <= 0 || vty_port > 0xffff)
474 vty_port = BGP_VTY_PORT;
718e3744 475 break;
476 case 'r':
477 retain_mode = 1;
478 break;
3a02d1f7
PJ
479 case 'l':
480 bm->address = optarg;
481 /* listenon implies -n */
718e3744 482 case 'n':
483 bgp_option_set (BGP_OPT_NO_FIB);
484 break;
c065230a 485 case 'u':
486 bgpd_privs.user = optarg;
487 break;
488 case 'g':
489 bgpd_privs.group = optarg;
490 break;
a008f49a
LB
491 case 'S': /* skip run as = override bgpd_privs */
492 skip_runas = 1;
493 break;
718e3744 494 case 'v':
495 print_version (progname);
496 exit (0);
497 break;
876b8be0
PJ
498 case 'C':
499 dryrun = 1;
500 break;
718e3744 501 case 'h':
502 usage (progname, 0);
503 break;
504 default:
505 usage (progname, 1);
506 break;
507 }
508 }
509
03809024
DS
510 zlog_default = openzlog (progname, ZLOG_BGP, 0,
511 LOG_CONS|LOG_NDELAY|LOG_PID, LOG_DAEMON);
a008f49a
LB
512
513 if (skip_runas)
514 memset (&bgpd_privs, 0, sizeof (bgpd_privs));
03809024 515 zprivs_init (&bgpd_privs);
a008f49a 516
03809024
DS
517#if defined(HAVE_CUMULUS)
518 zlog_set_level (NULL, ZLOG_DEST_SYSLOG, zlog_default->default_lvl);
519#endif
87d4a781 520
718e3744 521 /* Initializations. */
b06fd125 522 srandom (time (NULL));
9229d914 523 signal_init (bm->master, array_size(bgp_signals), bgp_signals);
718e3744 524 cmd_init (1);
9229d914 525 vty_init (bm->master);
718e3744 526 memory_init ();
2fcc254e 527 bgp_vrf_init ();
718e3744 528
529 /* BGP related initialization. */
530 bgp_init ();
531
718e3744 532 /* Parse config file. */
320ec10a 533 vty_read_config (config_file, config_default);
718e3744 534
876b8be0
PJ
535 /* Start execution only if not in dry-run mode */
536 if(dryrun)
537 return(0);
538
718e3744 539 /* Turn into daemon if daemon_mode is set. */
372b3c70
SH
540 if (daemon_mode && daemon (0, 0) < 0)
541 {
542 zlog_err("BGPd daemon failed: %s", strerror(errno));
543 return (1);
544 }
545
718e3744 546
547 /* Process ID file creation. */
548 pid_output (pid_file);
549
550 /* Make bgp vty socket. */
551 vty_serv_sock (vty_addr, vty_port, BGP_VTYSH_PATH);
552
553 /* Print banner. */
3a02d1f7 554 zlog_notice ("BGPd %s starting: vty@%d, bgp@%s:%d", QUAGGA_VERSION,
7e992e95 555 vty_port,
b63e6089 556 (bm->address ? bm->address : "<all>"),
7e992e95 557 bm->port);
718e3744 558
559 /* Start finite state machine, here we go! */
9229d914 560 while (thread_fetch (bm->master, &thread))
718e3744 561 thread_call (&thread);
562
563 /* Not reached. */
e8e1946e 564 return (0);
718e3744 565}