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