]> git.proxmox.com Git - mirror_frr.git/blame - bgpd/bgp_main.c
Merge pull request #9497 from opensourcerouting/cli-better-no
[mirror_frr.git] / bgpd / bgp_main.c
CommitLineData
718e3744 1/* Main routine of bgpd.
896014f4
DL
2 * Copyright (C) 1996, 97, 98, 1999 Kunihiro Ishiguro
3 *
4 * This file is part of GNU Zebra.
5 *
6 * GNU Zebra is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2, or (at your option) any
9 * later version.
10 *
11 * GNU Zebra is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; see the file COPYING; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 */
718e3744 20
21#include <zebra.h>
22
03014d48 23#include <pthread.h>
718e3744 24#include "vector.h"
718e3744 25#include "command.h"
26#include "getopt.h"
27#include "thread.h"
5e4fa164 28#include <lib/version.h>
718e3744 29#include "memory.h"
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"
4f04a76b 42#include "libfrr.h"
61cf4b37 43#include "ns.h"
718e3744 44
45#include "bgpd/bgpd.h"
46#include "bgpd/bgp_attr.h"
b2f0fa55 47#include "bgpd/bgp_route.h"
718e3744 48#include "bgpd/bgp_mplsvpn.h"
228da428
CC
49#include "bgpd/bgp_aspath.h"
50#include "bgpd/bgp_dump.h"
51#include "bgpd/bgp_route.h"
52#include "bgpd/bgp_nexthop.h"
53#include "bgpd/bgp_regex.h"
54#include "bgpd/bgp_clist.h"
55#include "bgpd/bgp_debug.h"
14454c9f 56#include "bgpd/bgp_errors.h"
228da428 57#include "bgpd/bgp_filter.h"
8196f13d 58#include "bgpd/bgp_zebra.h"
d3ecc69e 59#include "bgpd/bgp_packet.h"
03014d48 60#include "bgpd/bgp_keepalives.h"
61cf4b37 61#include "bgpd/bgp_network.h"
def31c13 62#include "bgpd/bgp_errors.h"
b4becb06 63#include "bgpd/bgp_script.h"
45a859f1 64#include "bgpd/bgp_evpn_mh.h"
c589d847 65#include "bgpd/bgp_nht.h"
48cb7ea9 66#include "bgpd/bgp_routemap_nb.h"
ed0e57e3 67#include "bgpd/bgp_community_alias.h"
718e3744 68
65efcfce 69#ifdef ENABLE_BGP_VNC
f8b6f499 70#include "bgpd/rfapi/rfapi_backend.h"
65efcfce
LB
71#endif
72
718e3744 73/* bgpd options, we use GNU getopt library. */
d62a17ae 74static const struct option longopts[] = {
75 {"bgp_port", required_argument, NULL, 'p'},
76 {"listenon", required_argument, NULL, 'l'},
d62a17ae 77 {"no_kernel", no_argument, NULL, 'n'},
78 {"skip_runas", no_argument, NULL, 'S'},
79 {"ecmp", required_argument, NULL, 'e'},
f533be73 80 {"int_num", required_argument, NULL, 'I'},
c0064d2a 81 {"no_zebra", no_argument, NULL, 'Z'},
c2d020ad 82 {"socket_size", required_argument, NULL, 's'},
d62a17ae 83 {0}};
718e3744 84
2d75d052 85/* signal definitions */
d62a17ae 86void sighup(void);
87void sigint(void);
88void sigusr1(void);
2d75d052 89
d62a17ae 90static void bgp_exit(int);
91static void bgp_vrf_terminate(void);
228da428 92
d62a17ae 93static struct quagga_signal_t bgp_signals[] = {
94 {
95 .signal = SIGHUP,
96 .handler = &sighup,
97 },
98 {
99 .signal = SIGUSR1,
100 .handler = &sigusr1,
101 },
102 {
103 .signal = SIGINT,
104 .handler = &sigint,
105 },
106 {
107 .signal = SIGTERM,
108 .handler = &sigint,
109 },
2d75d052 110};
111
edd7c245 112/* privileges */
996c9314
LB
113static zebra_capabilities_t _caps_p[] = {ZCAP_BIND, ZCAP_NET_RAW,
114 ZCAP_NET_ADMIN, ZCAP_SYS_ADMIN};
edd7c245 115
d62a17ae 116struct zebra_privs_t bgpd_privs = {
b2f36157 117#if defined(FRR_USER) && defined(FRR_GROUP)
d62a17ae 118 .user = FRR_USER,
119 .group = FRR_GROUP,
d81fadfd 120#endif
121#ifdef VTY_GROUP
d62a17ae 122 .vty_group = VTY_GROUP,
edd7c245 123#endif
d62a17ae 124 .caps_p = _caps_p,
125 .cap_num_p = array_size(_caps_p),
126 .cap_num_i = 0,
edd7c245 127};
128
eb05883f
DL
129static struct frr_daemon_info bgpd_di;
130
718e3744 131/* SIGHUP handler. */
d62a17ae 132void sighup(void)
718e3744 133{
23ca3269
DS
134 zlog_info("SIGHUP received, ignoring");
135
136 return;
137
138 /*
139 * This is turned off for the moment. There is all
140 * sorts of config turned off by bgp_terminate
3130e286 141 * that is not setup properly again in bgp_reset.
23ca3269
DS
142 * I see no easy way to do this nor do I see that
143 * this is a desirable way to reload config
144 * given the yang work.
145 */
d62a17ae 146 /* Terminate all thread. */
3130e286
DS
147 /*
148 * bgp_terminate();
149 * bgp_reset();
150 * zlog_info("bgpd restarting!");
718e3744 151
3130e286
DS
152 * Reload config file.
153 * vty_read_config(NULL, bgpd_di.config_file, config_default);
154 */
d62a17ae 155 /* Try to return to normal operation. */
718e3744 156}
157
158/* SIGINT handler. */
d62a17ae 159__attribute__((__noreturn__)) void sigint(void)
718e3744 160{
d62a17ae 161 zlog_notice("Terminating on signal");
97b4a0ec
LB
162 assert(bm->terminating == false);
163 bm->terminating = true; /* global flag that shutting down */
718e3744 164
21bfce98
RZ
165 /* Disable BFD events to avoid wasting processing. */
166 bfd_protocol_integration_set_shutdown(true);
167
c8dde10f 168 bgp_terminate();
718e3744 169
d62a17ae 170 bgp_exit(0);
540766e7 171
d62a17ae 172 exit(0);
718e3744 173}
174
175/* SIGUSR1 handler. */
d62a17ae 176void sigusr1(void)
718e3744 177{
d62a17ae 178 zlog_rotate();
718e3744 179}
228da428
CC
180
181/*
182 Try to free up allocations we know about so that diagnostic tools such as
183 valgrind are able to better illuminate leaks.
184
185 Zebra route removal and protocol teardown are not meant to be done here.
186 For example, "retain_mode" may be set.
187*/
d62a17ae 188static __attribute__((__noreturn__)) void bgp_exit(int status)
228da428 189{
e2f3a930 190 struct bgp *bgp, *bgp_default, *bgp_evpn;
d62a17ae 191 struct listnode *node, *nnode;
228da428 192
d62a17ae 193 /* it only makes sense for this to be called on a clean exit */
194 assert(status == 0);
228da428 195
03951374
DL
196 frr_early_fini();
197
d62a17ae 198 bgp_close();
1ff9a340 199
0e42e319 200 bgp_default = bgp_get_default();
e2f3a930 201 bgp_evpn = bgp_get_evpn();
0e42e319 202
d62a17ae 203 /* reverse bgp_master_init */
0e42e319 204 for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) {
e2f3a930 205 if (bgp_default == bgp || bgp_evpn == bgp)
0e42e319 206 continue;
d62a17ae 207 bgp_delete(bgp);
0e42e319 208 }
e2f3a930
T
209 if (bgp_evpn && bgp_evpn != bgp_default)
210 bgp_delete(bgp_evpn);
1f4b2cce
DS
211 if (bgp_default)
212 bgp_delete(bgp_default);
46abd3e3 213
45a859f1 214 bgp_evpn_mh_finish();
c589d847 215 bgp_l3nhg_finish();
45a859f1 216
d62a17ae 217 /* reverse bgp_dump_init */
218 bgp_dump_finish();
ed0e57e3
DA
219
220 /* BGP community aliases */
221 bgp_community_alias_finish();
228da428 222
d62a17ae 223 /* reverse bgp_route_init */
224 bgp_route_finish();
228da428 225
d62a17ae 226 /* cleanup route maps */
227 bgp_route_map_terminate();
228da428 228
d62a17ae 229 /* reverse bgp_attr_init */
230 bgp_attr_finish();
7b8def58 231
2d4ee774
QY
232 /* stop pthreads */
233 bgp_pthreads_finish();
234
d62a17ae 235 /* reverse access_list_init */
236 access_list_add_hook(NULL);
237 access_list_delete_hook(NULL);
238 access_list_reset();
228da428 239
d62a17ae 240 /* reverse bgp_filter_init */
241 as_list_add_hook(NULL);
242 as_list_delete_hook(NULL);
243 bgp_filter_reset();
228da428 244
d62a17ae 245 /* reverse prefix_list_init */
246 prefix_list_add_hook(NULL);
247 prefix_list_delete_hook(NULL);
248 prefix_list_reset();
228da428 249
d62a17ae 250 /* reverse community_list_init */
251 community_list_terminate(bgp_clist);
228da428 252
d62a17ae 253 bgp_vrf_terminate();
49e5a4a0 254#ifdef ENABLE_BGP_VNC
d62a17ae 255 vnc_zebra_destroy();
65efcfce 256#endif
d62a17ae 257 bgp_zebra_destroy();
228da428 258
3d57c994 259 bf_free(bm->rd_idspace);
6a154c88 260 list_delete(&bm->bgp);
85e9cd9a 261 list_delete(&bm->addresses);
0768f289
PG
262
263 bgp_lp_finish();
264
d62a17ae 265 memset(bm, 0, sizeof(*bm));
46857efe 266
03951374 267 frr_fini();
d62a17ae 268 exit(status);
228da428 269}
6b0655a2 270
d62a17ae 271static int bgp_vrf_new(struct vrf *vrf)
2fcc254e 272{
d62a17ae 273 if (BGP_DEBUG(zebra, ZEBRA))
a8bf7d9c 274 zlog_debug("VRF Created: %s(%u)", vrf->name, vrf->vrf_id);
2fcc254e 275
d62a17ae 276 return 0;
2fcc254e
DS
277}
278
d62a17ae 279static int bgp_vrf_delete(struct vrf *vrf)
2fcc254e 280{
d62a17ae 281 if (BGP_DEBUG(zebra, ZEBRA))
a8bf7d9c 282 zlog_debug("VRF Deletion: %s(%u)", vrf->name, vrf->vrf_id);
2fcc254e 283
d62a17ae 284 return 0;
2fcc254e
DS
285}
286
d62a17ae 287static int bgp_vrf_enable(struct vrf *vrf)
2fcc254e 288{
d62a17ae 289 struct bgp *bgp;
290 vrf_id_t old_vrf_id;
291
292 if (BGP_DEBUG(zebra, ZEBRA))
a8bf7d9c 293 zlog_debug("VRF enable add %s id %u", vrf->name, vrf->vrf_id);
d62a17ae 294
295 bgp = bgp_lookup_by_name(vrf->name);
d5f31d5f 296 if (bgp && bgp->vrf_id != vrf->vrf_id) {
9a8bdf1c
PG
297 if (bgp->name && strmatch(vrf->name, VRF_DEFAULT_NAME)) {
298 XFREE(MTYPE_BGP, bgp->name);
9a8bdf1c
PG
299 XFREE(MTYPE_BGP, bgp->name_pretty);
300 bgp->name_pretty = XSTRDUP(MTYPE_BGP, "VRF default");
d5f31d5f 301 bgp->inst_type = BGP_INSTANCE_TYPE_DEFAULT;
49e5a4a0 302#ifdef ENABLE_BGP_VNC
d5f31d5f
PG
303 if (!bgp->rfapi) {
304 bgp->rfapi = bgp_rfapi_new(bgp);
305 assert(bgp->rfapi);
306 assert(bgp->rfapi_cfg);
307 }
308#endif /* ENABLE_BGP_VNC */
9a8bdf1c 309 }
d62a17ae 310 old_vrf_id = bgp->vrf_id;
311 /* We have instance configured, link to VRF and make it "up". */
312 bgp_vrf_link(bgp, vrf);
313
e5619c28 314 bgp_handle_socket(bgp, vrf, old_vrf_id, true);
d62a17ae 315 bgp_instance_up(bgp);
ddb5b488
PZ
316 vpn_leak_zebra_vrf_label_update(bgp, AFI_IP);
317 vpn_leak_zebra_vrf_label_update(bgp, AFI_IP6);
b72c9e14
HS
318 vpn_leak_zebra_vrf_sid_update(bgp, AFI_IP);
319 vpn_leak_zebra_vrf_sid_update(bgp, AFI_IP6);
e504cf3b
DS
320 vpn_leak_postchange(BGP_VPN_POLICY_DIR_TOVPN, AFI_IP,
321 bgp_get_default(), bgp);
322 vpn_leak_postchange(BGP_VPN_POLICY_DIR_FROMVPN, AFI_IP,
323 bgp_get_default(), bgp);
324 vpn_leak_postchange(BGP_VPN_POLICY_DIR_TOVPN, AFI_IP6,
325 bgp_get_default(), bgp);
326 vpn_leak_postchange(BGP_VPN_POLICY_DIR_FROMVPN, AFI_IP6,
327 bgp_get_default(), bgp);
d62a17ae 328 }
329
330 return 0;
2fcc254e
DS
331}
332
d62a17ae 333static int bgp_vrf_disable(struct vrf *vrf)
2fcc254e 334{
d62a17ae 335 struct bgp *bgp;
d62a17ae 336
337 if (vrf->vrf_id == VRF_DEFAULT)
338 return 0;
339
340 if (BGP_DEBUG(zebra, ZEBRA))
341 zlog_debug("VRF disable %s id %d", vrf->name, vrf->vrf_id);
342
343 bgp = bgp_lookup_by_name(vrf->name);
344 if (bgp) {
ddb5b488
PZ
345
346 vpn_leak_zebra_vrf_label_withdraw(bgp, AFI_IP);
347 vpn_leak_zebra_vrf_label_withdraw(bgp, AFI_IP6);
e504cf3b
DS
348 vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN, AFI_IP,
349 bgp_get_default(), bgp);
350 vpn_leak_prechange(BGP_VPN_POLICY_DIR_FROMVPN, AFI_IP,
351 bgp_get_default(), bgp);
352 vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN, AFI_IP6,
353 bgp_get_default(), bgp);
354 vpn_leak_prechange(BGP_VPN_POLICY_DIR_FROMVPN, AFI_IP6,
355 bgp_get_default(), bgp);
ddb5b488 356
e5619c28 357 bgp_handle_socket(bgp, vrf, VRF_UNKNOWN, false);
d62a17ae 358 /* We have instance configured, unlink from VRF and make it
359 * "down". */
d62a17ae 360 bgp_instance_down(bgp);
6cc0114b 361 bgp_vrf_unlink(bgp, vrf);
d62a17ae 362 }
363
364 /* Note: This is a callback, the VRF will be deleted by the caller. */
365 return 0;
2fcc254e
DS
366}
367
d62a17ae 368static void bgp_vrf_init(void)
2fcc254e 369{
ecbc5a37 370 vrf_init(bgp_vrf_new, bgp_vrf_enable, bgp_vrf_disable,
d5f31d5f 371 bgp_vrf_delete, bgp_vrf_enable);
2fcc254e
DS
372}
373
d62a17ae 374static void bgp_vrf_terminate(void)
021530c1 375{
d62a17ae 376 vrf_terminate();
021530c1 377}
378
0d8c7a26 379static const struct frr_yang_module_info *const bgpd_yang_modules[] = {
c2aab693 380 &frr_filter_info,
91835f1f
RZ
381 &frr_interface_info,
382 &frr_route_map_info,
6fd8972a 383 &frr_vrf_info,
48cb7ea9 384 &frr_bgp_route_map_info,
8fcdd0d6
RW
385};
386
d62a17ae 387FRR_DAEMON_INFO(bgpd, BGP, .vty_port = BGP_VTY_PORT,
4f04a76b 388
d62a17ae 389 .proghelp = "Implementation of the BGP routing protocol.",
4f04a76b 390
d62a17ae 391 .signals = bgp_signals, .n_signals = array_size(bgp_signals),
4f04a76b 392
8fcdd0d6 393 .privs = &bgpd_privs, .yang_modules = bgpd_yang_modules,
80413c20
DL
394 .n_yang_modules = array_size(bgpd_yang_modules),
395);
4f04a76b 396
f28963f7 397#define DEPRECATED_OPTIONS ""
c8dde10f 398
718e3744 399/* Main routine of bgpd. Treatment of argument and start bgp finite
400 state machine is handled at here. */
d62a17ae 401int main(int argc, char **argv)
718e3744 402{
d62a17ae 403 int opt;
404 int tmp_port;
405
406 int bgp_port = BGP_PORT_DEFAULT;
85e9cd9a 407 struct list *addresses = list_new();
d62a17ae 408 int no_fib_flag = 0;
0b014ea6 409 int no_zebra_flag = 0;
d62a17ae 410 int skip_runas = 0;
f533be73 411 int instance = 0;
c2d020ad 412 int buffer_size = BGP_SOCKET_SNDBUF_SIZE;
85e9cd9a
AMR
413 char *address;
414 struct listnode *node;
415
416 addresses->cmp = (int (*)(void *, void *))strcmp;
d62a17ae 417
418 frr_preinit(&bgpd_di, argc, argv);
419 frr_opt_add(
c2d020ad 420 "p:l:SnZe:I:s:" DEPRECATED_OPTIONS, longopts,
580f8636 421 " -p, --bgp_port Set BGP listen port number (0 means do not listen).\n"
d62a17ae 422 " -l, --listenon Listen on specified address (implies -n)\n"
d62a17ae 423 " -n, --no_kernel Do not install route to kernel.\n"
0b014ea6 424 " -Z, --no_zebra Do not communicate with Zebra.\n"
d62a17ae 425 " -S, --skip_runas Skip capabilities checks, and changing user and group IDs.\n"
f533be73 426 " -e, --ecmp Specify ECMP to use.\n"
c2d020ad
DS
427 " -I, --int_num Set instance number (label-manager)\n"
428 " -s, --socket_size Set BGP peer socket send buffer size\n");
d62a17ae 429
430 /* Command line argument treatment. */
431 while (1) {
432 opt = frr_getopt(argc, argv, 0);
433
c8dde10f
QY
434 if (opt && opt < 128 && strchr(DEPRECATED_OPTIONS, opt)) {
435 fprintf(stderr,
436 "The -%c option no longer exists.\nPlease refer to the manual.\n",
437 opt);
438 continue;
439 }
440
d62a17ae 441 if (opt == EOF)
442 break;
443
444 switch (opt) {
445 case 0:
446 break;
447 case 'p':
448 tmp_port = atoi(optarg);
580f8636 449 if (tmp_port < 0 || tmp_port > 0xffff)
d62a17ae 450 bgp_port = BGP_PORT_DEFAULT;
451 else
452 bgp_port = tmp_port;
453 break;
1e03d6bc
QY
454 case 'e': {
455 unsigned long int parsed_multipath =
456 strtoul(optarg, NULL, 10);
457 if (parsed_multipath == 0
458 || parsed_multipath > MULTIPATH_NUM
459 || parsed_multipath > UINT_MAX) {
af4c2728 460 flog_err(
e50f7cfd 461 EC_BGP_MULTIPATH,
1e03d6bc 462 "Multipath Number specified must be less than %u and greater than 0",
d62a17ae 463 MULTIPATH_NUM);
464 return 1;
465 }
1e03d6bc 466 multipath_num = parsed_multipath;
d62a17ae 467 break;
1e03d6bc 468 }
d62a17ae 469 case 'l':
85e9cd9a 470 listnode_add_sort_nodup(addresses, optarg);
d62a17ae 471 /* listenon implies -n */
472 /* fallthru */
473 case 'n':
474 no_fib_flag = 1;
475 break;
0b014ea6
PG
476 case 'Z':
477 no_zebra_flag = 1;
478 break;
d62a17ae 479 case 'S':
480 skip_runas = 1;
481 break;
f533be73 482 case 'I':
483 instance = atoi(optarg);
484 if (instance > (unsigned short)-1)
485 zlog_err("Instance %i out of range (0..%u)",
486 instance, (unsigned short)-1);
487 break;
c2d020ad
DS
488 case 's':
489 buffer_size = atoi(optarg);
490 break;
d62a17ae 491 default:
492 frr_help_exit(1);
d62a17ae 493 }
718e3744 494 }
d62a17ae 495 if (skip_runas)
496 memset(&bgpd_privs, 0, sizeof(bgpd_privs));
718e3744 497
d62a17ae 498 /* BGP master init. */
85e9cd9a 499 bgp_master_init(frr_init(), buffer_size, addresses);
d62a17ae 500 bm->port = bgp_port;
580f8636 501 if (bgp_port == 0)
502 bgp_option_set(BGP_OPT_NO_LISTEN);
0b014ea6 503 if (no_fib_flag || no_zebra_flag)
d62a17ae 504 bgp_option_set(BGP_OPT_NO_FIB);
0b014ea6
PG
505 if (no_zebra_flag)
506 bgp_option_set(BGP_OPT_NO_ZEBRA);
def31c13 507 bgp_error_init();
d62a17ae 508 /* Initializations. */
509 bgp_vrf_init();
718e3744 510
fa22080d 511#ifdef HAVE_SCRIPTING
b4becb06 512 bgp_script_init();
fa22080d 513#endif
b4becb06 514
d62a17ae 515 /* BGP related initialization. */
f533be73 516 bgp_init((unsigned short)instance);
718e3744 517
85e9cd9a
AMR
518 if (list_isempty(bm->addresses)) {
519 snprintf(bgpd_di.startinfo, sizeof(bgpd_di.startinfo),
520 ", bgp@<all>:%d", bm->port);
521 } else {
522 for (ALL_LIST_ELEMENTS_RO(bm->addresses, node, address))
523 snprintf(bgpd_di.startinfo + strlen(bgpd_di.startinfo),
524 sizeof(bgpd_di.startinfo)
525 - strlen(bgpd_di.startinfo),
526 ", bgp@%s:%d", address, bm->port);
527 }
718e3744 528
d62a17ae 529 frr_config_fork();
2d4ee774 530 /* must be called after fork() */
034e185d 531 bgp_gr_apply_running_config();
419dfe6a 532 bgp_pthreads_run();
d62a17ae 533 frr_run(bm->master);
718e3744 534
d62a17ae 535 /* Not reached. */
95f7965d 536 return 0;
718e3744 537}