]> git.proxmox.com Git - mirror_frr.git/blame - bgpd/bgp_main.c
bgpd: fix ambiguity between show ip bgp ipv4|ipv6 encap|vpn commands
[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 57#ifdef ENABLE_BGP_VNC
f8b6f499 58#include "bgpd/rfapi/rfapi_backend.h"
65efcfce
LB
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{
b2f36157
DL
137#if defined(FRR_USER) && defined(FRR_GROUP)
138 .user = FRR_USER,
139 .group = FRR_GROUP,
d81fadfd 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\
b2f36157 177Report bugs to %s\n", progname, FRR_BUG_ADDRESS);
718e3744 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_dump_init */
257 bgp_dump_finish ();
258
259 /* reverse bgp_route_init */
260 bgp_route_finish ();
261
518f0eb1
DS
262 /* cleanup route maps */
263 bgp_route_map_terminate();
228da428 264
7b8def58
DS
265 /* reverse bgp_attr_init */
266 bgp_attr_finish ();
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 310static int
661512bf 311bgp_vrf_new (struct vrf *vrf)
2fcc254e
DS
312{
313 if (BGP_DEBUG (zebra, ZEBRA))
661512bf 314 zlog_debug ("VRF Created: %s(%d)", vrf->name, vrf->vrf_id);
2fcc254e
DS
315
316 return 0;
317}
318
319static int
661512bf 320bgp_vrf_delete (struct vrf *vrf)
2fcc254e
DS
321{
322 if (BGP_DEBUG (zebra, ZEBRA))
661512bf 323 zlog_debug ("VRF Deletion: %s(%d)", vrf->name, vrf->vrf_id);
2fcc254e
DS
324
325 return 0;
326}
327
328static int
661512bf 329bgp_vrf_enable (struct vrf *vrf)
2fcc254e 330{
2fcc254e 331 struct bgp *bgp;
eb117f29 332 vrf_id_t old_vrf_id;
2fcc254e 333
2fcc254e 334 if (BGP_DEBUG (zebra, ZEBRA))
661512bf 335 zlog_debug("VRF enable add %s id %d", vrf->name, vrf->vrf_id);
2fcc254e 336
661512bf 337 bgp = bgp_lookup_by_name (vrf->name);
2fcc254e
DS
338 if (bgp)
339 {
eb117f29 340 old_vrf_id = bgp->vrf_id;
2fcc254e
DS
341 /* We have instance configured, link to VRF and make it "up". */
342 bgp_vrf_link (bgp, vrf);
eb117f29
SK
343
344 /* Update any redistribute vrf bitmaps if the vrf_id changed */
345 if (old_vrf_id != bgp->vrf_id)
346 bgp_update_redist_vrf_bitmaps(bgp, old_vrf_id);
2fcc254e
DS
347 bgp_instance_up (bgp);
348 }
349
350 return 0;
351}
352
353static int
661512bf 354bgp_vrf_disable (struct vrf *vrf)
2fcc254e 355{
2fcc254e 356 struct bgp *bgp;
eb117f29 357 vrf_id_t old_vrf_id;
2fcc254e 358
661512bf 359 if (vrf->vrf_id == VRF_DEFAULT)
2fcc254e
DS
360 return 0;
361
2fcc254e 362 if (BGP_DEBUG (zebra, ZEBRA))
661512bf 363 zlog_debug("VRF disable %s id %d", vrf->name, vrf->vrf_id);
2fcc254e 364
661512bf 365 bgp = bgp_lookup_by_name (vrf->name);
2fcc254e
DS
366 if (bgp)
367 {
eb117f29 368 old_vrf_id = bgp->vrf_id;
2fcc254e
DS
369 /* We have instance configured, unlink from VRF and make it "down". */
370 bgp_vrf_unlink (bgp, vrf);
eb117f29
SK
371 /* Update any redistribute vrf bitmaps if the vrf_id changed */
372 if (old_vrf_id != bgp->vrf_id)
373 bgp_update_redist_vrf_bitmaps(bgp, old_vrf_id);
2fcc254e
DS
374 bgp_instance_down (bgp);
375 }
376
377 /* Note: This is a callback, the VRF will be deleted by the caller. */
378 return 0;
379}
380
381static void
382bgp_vrf_init (void)
383{
384 vrf_add_hook (VRF_NEW_HOOK, bgp_vrf_new);
385 vrf_add_hook (VRF_ENABLE_HOOK, bgp_vrf_enable);
386 vrf_add_hook (VRF_DISABLE_HOOK, bgp_vrf_disable);
387 vrf_add_hook (VRF_DELETE_HOOK, bgp_vrf_delete);
388
389 vrf_init ();
390}
391
021530c1 392static void
393bgp_vrf_terminate (void)
394{
395 vrf_add_hook (VRF_NEW_HOOK, NULL);
396 vrf_add_hook (VRF_ENABLE_HOOK, NULL);
397 vrf_add_hook (VRF_DISABLE_HOOK, NULL);
398 vrf_add_hook (VRF_DELETE_HOOK, NULL);
399
400 vrf_terminate ();
401}
402
718e3744 403/* Main routine of bgpd. Treatment of argument and start bgp finite
404 state machine is handled at here. */
405int
406main (int argc, char **argv)
407{
408 char *p;
409 int opt;
410 int daemon_mode = 0;
876b8be0 411 int dryrun = 0;
718e3744 412 char *progname;
413 struct thread thread;
0d6b2ee2 414 int tmp_port;
a008f49a 415 int skip_runas = 0;
718e3744 416
417 /* Set umask before anything for security */
418 umask (0027);
419
420 /* Preserve name of myself. */
421 progname = ((p = strrchr (argv[0], '/')) ? ++p : argv[0]);
422
718e3744 423 /* BGP master init. */
424 bgp_master_init ();
425
426 /* Command line argument treatment. */
427 while (1)
428 {
a008f49a 429 opt = getopt_long (argc, argv, "df:i:z:hp:l:A:P:rnu:g:vCS", longopts, 0);
718e3744 430
431 if (opt == EOF)
432 break;
433
434 switch (opt)
435 {
436 case 0:
437 break;
438 case 'd':
439 daemon_mode = 1;
440 break;
441 case 'f':
442 config_file = optarg;
443 break;
444 case 'i':
445 pid_file = optarg;
446 break;
b5114685
VT
447 case 'z':
448 zclient_serv_path_set (optarg);
449 break;
718e3744 450 case 'p':
0d6b2ee2
PJ
451 tmp_port = atoi (optarg);
452 if (tmp_port <= 0 || tmp_port > 0xffff)
453 bm->port = BGP_PORT_DEFAULT;
454 else
455 bm->port = tmp_port;
718e3744 456 break;
457 case 'A':
458 vty_addr = optarg;
459 break;
460 case 'P':
4fc4e7ab 461 /* Deal with atoi() returning 0 on failure, and bgpd not
462 listening on bgp port... */
463 if (strcmp(optarg, "0") == 0)
464 {
465 vty_port = 0;
466 break;
467 }
468 vty_port = atoi (optarg);
0d6b2ee2
PJ
469 if (vty_port <= 0 || vty_port > 0xffff)
470 vty_port = BGP_VTY_PORT;
718e3744 471 break;
472 case 'r':
473 retain_mode = 1;
474 break;
3a02d1f7
PJ
475 case 'l':
476 bm->address = optarg;
477 /* listenon implies -n */
718e3744 478 case 'n':
479 bgp_option_set (BGP_OPT_NO_FIB);
480 break;
c065230a 481 case 'u':
482 bgpd_privs.user = optarg;
483 break;
484 case 'g':
485 bgpd_privs.group = optarg;
486 break;
a008f49a
LB
487 case 'S': /* skip run as = override bgpd_privs */
488 skip_runas = 1;
489 break;
718e3744 490 case 'v':
491 print_version (progname);
492 exit (0);
493 break;
876b8be0
PJ
494 case 'C':
495 dryrun = 1;
496 break;
718e3744 497 case 'h':
498 usage (progname, 0);
499 break;
500 default:
501 usage (progname, 1);
502 break;
503 }
504 }
505
03809024
DS
506 zlog_default = openzlog (progname, ZLOG_BGP, 0,
507 LOG_CONS|LOG_NDELAY|LOG_PID, LOG_DAEMON);
a008f49a
LB
508
509 if (skip_runas)
510 memset (&bgpd_privs, 0, sizeof (bgpd_privs));
03809024 511 zprivs_init (&bgpd_privs);
a008f49a 512
03809024
DS
513#if defined(HAVE_CUMULUS)
514 zlog_set_level (NULL, ZLOG_DEST_SYSLOG, zlog_default->default_lvl);
515#endif
87d4a781 516
718e3744 517 /* Initializations. */
b06fd125 518 srandom (time (NULL));
9229d914 519 signal_init (bm->master, array_size(bgp_signals), bgp_signals);
718e3744 520 cmd_init (1);
9229d914 521 vty_init (bm->master);
718e3744 522 memory_init ();
2fcc254e 523 bgp_vrf_init ();
718e3744 524
525 /* BGP related initialization. */
526 bgp_init ();
527
718e3744 528 /* Parse config file. */
320ec10a 529 vty_read_config (config_file, config_default);
718e3744 530
876b8be0
PJ
531 /* Start execution only if not in dry-run mode */
532 if(dryrun)
533 return(0);
534
718e3744 535 /* Turn into daemon if daemon_mode is set. */
372b3c70
SH
536 if (daemon_mode && daemon (0, 0) < 0)
537 {
538 zlog_err("BGPd daemon failed: %s", strerror(errno));
539 return (1);
540 }
541
718e3744 542
543 /* Process ID file creation. */
544 pid_output (pid_file);
545
546 /* Make bgp vty socket. */
547 vty_serv_sock (vty_addr, vty_port, BGP_VTYSH_PATH);
548
549 /* Print banner. */
b2f36157 550 zlog_notice ("BGPd %s starting: vty@%d, bgp@%s:%d", FRR_COPYRIGHT,
7e992e95 551 vty_port,
b63e6089 552 (bm->address ? bm->address : "<all>"),
7e992e95 553 bm->port);
718e3744 554
555 /* Start finite state machine, here we go! */
9229d914 556 while (thread_fetch (bm->master, &thread))
718e3744 557 thread_call (&thread);
558
559 /* Not reached. */
e8e1946e 560 return (0);
718e3744 561}