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