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