]> git.proxmox.com Git - mirror_frr.git/blame - bgpd/bgp_main.c
bgpd: cli for srv6-locator assignment (step4)
[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"
e4a46416
CS
64#include "lib/routing_nb.h"
65#include "bgpd/bgp_nb.h"
45a859f1 66#include "bgpd/bgp_evpn_mh.h"
c589d847 67#include "bgpd/bgp_nht.h"
48cb7ea9 68#include "bgpd/bgp_routemap_nb.h"
ed0e57e3 69#include "bgpd/bgp_community_alias.h"
718e3744 70
65efcfce 71#ifdef ENABLE_BGP_VNC
f8b6f499 72#include "bgpd/rfapi/rfapi_backend.h"
65efcfce
LB
73#endif
74
718e3744 75/* bgpd options, we use GNU getopt library. */
d62a17ae 76static const struct option longopts[] = {
77 {"bgp_port", required_argument, NULL, 'p'},
78 {"listenon", required_argument, NULL, 'l'},
d62a17ae 79 {"no_kernel", no_argument, NULL, 'n'},
80 {"skip_runas", no_argument, NULL, 'S'},
81 {"ecmp", required_argument, NULL, 'e'},
f533be73 82 {"int_num", required_argument, NULL, 'I'},
c0064d2a 83 {"no_zebra", no_argument, NULL, 'Z'},
c2d020ad 84 {"socket_size", required_argument, NULL, 's'},
d62a17ae 85 {0}};
718e3744 86
2d75d052 87/* signal definitions */
d62a17ae 88void sighup(void);
89void sigint(void);
90void sigusr1(void);
2d75d052 91
d62a17ae 92static void bgp_exit(int);
93static void bgp_vrf_terminate(void);
228da428 94
d62a17ae 95static struct quagga_signal_t bgp_signals[] = {
96 {
97 .signal = SIGHUP,
98 .handler = &sighup,
99 },
100 {
101 .signal = SIGUSR1,
102 .handler = &sigusr1,
103 },
104 {
105 .signal = SIGINT,
106 .handler = &sigint,
107 },
108 {
109 .signal = SIGTERM,
110 .handler = &sigint,
111 },
2d75d052 112};
113
edd7c245 114/* privileges */
996c9314
LB
115static zebra_capabilities_t _caps_p[] = {ZCAP_BIND, ZCAP_NET_RAW,
116 ZCAP_NET_ADMIN, ZCAP_SYS_ADMIN};
edd7c245 117
d62a17ae 118struct zebra_privs_t bgpd_privs = {
b2f36157 119#if defined(FRR_USER) && defined(FRR_GROUP)
d62a17ae 120 .user = FRR_USER,
121 .group = FRR_GROUP,
d81fadfd 122#endif
123#ifdef VTY_GROUP
d62a17ae 124 .vty_group = VTY_GROUP,
edd7c245 125#endif
d62a17ae 126 .caps_p = _caps_p,
127 .cap_num_p = array_size(_caps_p),
128 .cap_num_i = 0,
edd7c245 129};
130
eb05883f
DL
131static struct frr_daemon_info bgpd_di;
132
718e3744 133/* SIGHUP handler. */
d62a17ae 134void sighup(void)
718e3744 135{
23ca3269
DS
136 zlog_info("SIGHUP received, ignoring");
137
138 return;
139
140 /*
141 * This is turned off for the moment. There is all
142 * sorts of config turned off by bgp_terminate
3130e286 143 * that is not setup properly again in bgp_reset.
23ca3269
DS
144 * I see no easy way to do this nor do I see that
145 * this is a desirable way to reload config
146 * given the yang work.
147 */
d62a17ae 148 /* Terminate all thread. */
3130e286
DS
149 /*
150 * bgp_terminate();
151 * bgp_reset();
152 * zlog_info("bgpd restarting!");
718e3744 153
3130e286
DS
154 * Reload config file.
155 * vty_read_config(NULL, bgpd_di.config_file, config_default);
156 */
d62a17ae 157 /* Try to return to normal operation. */
718e3744 158}
159
160/* SIGINT handler. */
d62a17ae 161__attribute__((__noreturn__)) void sigint(void)
718e3744 162{
d62a17ae 163 zlog_notice("Terminating on signal");
97b4a0ec
LB
164 assert(bm->terminating == false);
165 bm->terminating = true; /* global flag that shutting down */
718e3744 166
21bfce98
RZ
167 /* Disable BFD events to avoid wasting processing. */
168 bfd_protocol_integration_set_shutdown(true);
169
c8dde10f 170 bgp_terminate();
718e3744 171
d62a17ae 172 bgp_exit(0);
540766e7 173
d62a17ae 174 exit(0);
718e3744 175}
176
177/* SIGUSR1 handler. */
d62a17ae 178void sigusr1(void)
718e3744 179{
d62a17ae 180 zlog_rotate();
718e3744 181}
228da428
CC
182
183/*
184 Try to free up allocations we know about so that diagnostic tools such as
185 valgrind are able to better illuminate leaks.
186
187 Zebra route removal and protocol teardown are not meant to be done here.
188 For example, "retain_mode" may be set.
189*/
d62a17ae 190static __attribute__((__noreturn__)) void bgp_exit(int status)
228da428 191{
e2f3a930 192 struct bgp *bgp, *bgp_default, *bgp_evpn;
d62a17ae 193 struct listnode *node, *nnode;
228da428 194
d62a17ae 195 /* it only makes sense for this to be called on a clean exit */
196 assert(status == 0);
228da428 197
03951374
DL
198 frr_early_fini();
199
d62a17ae 200 bgp_close();
1ff9a340 201
0e42e319 202 bgp_default = bgp_get_default();
e2f3a930 203 bgp_evpn = bgp_get_evpn();
0e42e319 204
d62a17ae 205 /* reverse bgp_master_init */
0e42e319 206 for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) {
e2f3a930 207 if (bgp_default == bgp || bgp_evpn == bgp)
0e42e319 208 continue;
d62a17ae 209 bgp_delete(bgp);
0e42e319 210 }
e2f3a930
T
211 if (bgp_evpn && bgp_evpn != bgp_default)
212 bgp_delete(bgp_evpn);
1f4b2cce
DS
213 if (bgp_default)
214 bgp_delete(bgp_default);
46abd3e3 215
45a859f1 216 bgp_evpn_mh_finish();
c589d847 217 bgp_l3nhg_finish();
45a859f1 218
d62a17ae 219 /* reverse bgp_dump_init */
220 bgp_dump_finish();
ed0e57e3
DA
221
222 /* BGP community aliases */
223 bgp_community_alias_finish();
228da428 224
d62a17ae 225 /* reverse bgp_route_init */
226 bgp_route_finish();
228da428 227
d62a17ae 228 /* cleanup route maps */
229 bgp_route_map_terminate();
228da428 230
d62a17ae 231 /* reverse bgp_attr_init */
232 bgp_attr_finish();
7b8def58 233
2d4ee774
QY
234 /* stop pthreads */
235 bgp_pthreads_finish();
236
d62a17ae 237 /* reverse access_list_init */
238 access_list_add_hook(NULL);
239 access_list_delete_hook(NULL);
240 access_list_reset();
228da428 241
d62a17ae 242 /* reverse bgp_filter_init */
243 as_list_add_hook(NULL);
244 as_list_delete_hook(NULL);
245 bgp_filter_reset();
228da428 246
d62a17ae 247 /* reverse prefix_list_init */
248 prefix_list_add_hook(NULL);
249 prefix_list_delete_hook(NULL);
250 prefix_list_reset();
228da428 251
d62a17ae 252 /* reverse community_list_init */
253 community_list_terminate(bgp_clist);
228da428 254
d62a17ae 255 bgp_vrf_terminate();
49e5a4a0 256#ifdef ENABLE_BGP_VNC
d62a17ae 257 vnc_zebra_destroy();
65efcfce 258#endif
d62a17ae 259 bgp_zebra_destroy();
228da428 260
3d57c994 261 bf_free(bm->rd_idspace);
6a154c88 262 list_delete(&bm->bgp);
85e9cd9a 263 list_delete(&bm->addresses);
0768f289
PG
264
265 bgp_lp_finish();
266
d62a17ae 267 memset(bm, 0, sizeof(*bm));
46857efe 268
03951374 269 frr_fini();
d62a17ae 270 exit(status);
228da428 271}
6b0655a2 272
d62a17ae 273static int bgp_vrf_new(struct vrf *vrf)
2fcc254e 274{
d62a17ae 275 if (BGP_DEBUG(zebra, ZEBRA))
a8bf7d9c 276 zlog_debug("VRF Created: %s(%u)", vrf->name, vrf->vrf_id);
2fcc254e 277
d62a17ae 278 return 0;
2fcc254e
DS
279}
280
d62a17ae 281static int bgp_vrf_delete(struct vrf *vrf)
2fcc254e 282{
d62a17ae 283 if (BGP_DEBUG(zebra, ZEBRA))
a8bf7d9c 284 zlog_debug("VRF Deletion: %s(%u)", vrf->name, vrf->vrf_id);
2fcc254e 285
d62a17ae 286 return 0;
2fcc254e
DS
287}
288
d62a17ae 289static int bgp_vrf_enable(struct vrf *vrf)
2fcc254e 290{
d62a17ae 291 struct bgp *bgp;
292 vrf_id_t old_vrf_id;
293
294 if (BGP_DEBUG(zebra, ZEBRA))
a8bf7d9c 295 zlog_debug("VRF enable add %s id %u", vrf->name, vrf->vrf_id);
d62a17ae 296
297 bgp = bgp_lookup_by_name(vrf->name);
d5f31d5f 298 if (bgp && bgp->vrf_id != vrf->vrf_id) {
9a8bdf1c
PG
299 if (bgp->name && strmatch(vrf->name, VRF_DEFAULT_NAME)) {
300 XFREE(MTYPE_BGP, bgp->name);
9a8bdf1c
PG
301 XFREE(MTYPE_BGP, bgp->name_pretty);
302 bgp->name_pretty = XSTRDUP(MTYPE_BGP, "VRF default");
d5f31d5f 303 bgp->inst_type = BGP_INSTANCE_TYPE_DEFAULT;
49e5a4a0 304#ifdef ENABLE_BGP_VNC
d5f31d5f
PG
305 if (!bgp->rfapi) {
306 bgp->rfapi = bgp_rfapi_new(bgp);
307 assert(bgp->rfapi);
308 assert(bgp->rfapi_cfg);
309 }
310#endif /* ENABLE_BGP_VNC */
9a8bdf1c 311 }
d62a17ae 312 old_vrf_id = bgp->vrf_id;
313 /* We have instance configured, link to VRF and make it "up". */
314 bgp_vrf_link(bgp, vrf);
315
e5619c28 316 bgp_handle_socket(bgp, vrf, old_vrf_id, true);
d62a17ae 317 bgp_instance_up(bgp);
ddb5b488
PZ
318 vpn_leak_zebra_vrf_label_update(bgp, AFI_IP);
319 vpn_leak_zebra_vrf_label_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[] = {
e4a46416 380 &frr_bgp_info,
c2aab693 381 &frr_filter_info,
91835f1f
RZ
382 &frr_interface_info,
383 &frr_route_map_info,
e4a46416 384 &frr_routing_info,
6fd8972a 385 &frr_vrf_info,
48cb7ea9 386 &frr_bgp_route_map_info,
8fcdd0d6
RW
387};
388
d62a17ae 389FRR_DAEMON_INFO(bgpd, BGP, .vty_port = BGP_VTY_PORT,
4f04a76b 390
d62a17ae 391 .proghelp = "Implementation of the BGP routing protocol.",
4f04a76b 392
d62a17ae 393 .signals = bgp_signals, .n_signals = array_size(bgp_signals),
4f04a76b 394
8fcdd0d6 395 .privs = &bgpd_privs, .yang_modules = bgpd_yang_modules,
80413c20
DL
396 .n_yang_modules = array_size(bgpd_yang_modules),
397);
4f04a76b 398
f28963f7 399#define DEPRECATED_OPTIONS ""
c8dde10f 400
718e3744 401/* Main routine of bgpd. Treatment of argument and start bgp finite
402 state machine is handled at here. */
d62a17ae 403int main(int argc, char **argv)
718e3744 404{
d62a17ae 405 int opt;
406 int tmp_port;
407
408 int bgp_port = BGP_PORT_DEFAULT;
85e9cd9a 409 struct list *addresses = list_new();
d62a17ae 410 int no_fib_flag = 0;
0b014ea6 411 int no_zebra_flag = 0;
d62a17ae 412 int skip_runas = 0;
f533be73 413 int instance = 0;
c2d020ad 414 int buffer_size = BGP_SOCKET_SNDBUF_SIZE;
85e9cd9a
AMR
415 char *address;
416 struct listnode *node;
417
418 addresses->cmp = (int (*)(void *, void *))strcmp;
d62a17ae 419
420 frr_preinit(&bgpd_di, argc, argv);
421 frr_opt_add(
c2d020ad 422 "p:l:SnZe:I:s:" DEPRECATED_OPTIONS, longopts,
580f8636 423 " -p, --bgp_port Set BGP listen port number (0 means do not listen).\n"
d62a17ae 424 " -l, --listenon Listen on specified address (implies -n)\n"
d62a17ae 425 " -n, --no_kernel Do not install route to kernel.\n"
0b014ea6 426 " -Z, --no_zebra Do not communicate with Zebra.\n"
d62a17ae 427 " -S, --skip_runas Skip capabilities checks, and changing user and group IDs.\n"
f533be73 428 " -e, --ecmp Specify ECMP to use.\n"
c2d020ad
DS
429 " -I, --int_num Set instance number (label-manager)\n"
430 " -s, --socket_size Set BGP peer socket send buffer size\n");
d62a17ae 431
432 /* Command line argument treatment. */
433 while (1) {
434 opt = frr_getopt(argc, argv, 0);
435
c8dde10f
QY
436 if (opt && opt < 128 && strchr(DEPRECATED_OPTIONS, opt)) {
437 fprintf(stderr,
438 "The -%c option no longer exists.\nPlease refer to the manual.\n",
439 opt);
440 continue;
441 }
442
d62a17ae 443 if (opt == EOF)
444 break;
445
446 switch (opt) {
447 case 0:
448 break;
449 case 'p':
450 tmp_port = atoi(optarg);
580f8636 451 if (tmp_port < 0 || tmp_port > 0xffff)
d62a17ae 452 bgp_port = BGP_PORT_DEFAULT;
453 else
454 bgp_port = tmp_port;
455 break;
1e03d6bc
QY
456 case 'e': {
457 unsigned long int parsed_multipath =
458 strtoul(optarg, NULL, 10);
459 if (parsed_multipath == 0
460 || parsed_multipath > MULTIPATH_NUM
461 || parsed_multipath > UINT_MAX) {
af4c2728 462 flog_err(
e50f7cfd 463 EC_BGP_MULTIPATH,
1e03d6bc 464 "Multipath Number specified must be less than %u and greater than 0",
d62a17ae 465 MULTIPATH_NUM);
466 return 1;
467 }
1e03d6bc 468 multipath_num = parsed_multipath;
d62a17ae 469 break;
1e03d6bc 470 }
d62a17ae 471 case 'l':
85e9cd9a 472 listnode_add_sort_nodup(addresses, optarg);
d62a17ae 473 /* listenon implies -n */
474 /* fallthru */
475 case 'n':
476 no_fib_flag = 1;
477 break;
0b014ea6
PG
478 case 'Z':
479 no_zebra_flag = 1;
480 break;
d62a17ae 481 case 'S':
482 skip_runas = 1;
483 break;
f533be73 484 case 'I':
485 instance = atoi(optarg);
486 if (instance > (unsigned short)-1)
487 zlog_err("Instance %i out of range (0..%u)",
488 instance, (unsigned short)-1);
489 break;
c2d020ad
DS
490 case 's':
491 buffer_size = atoi(optarg);
492 break;
d62a17ae 493 default:
494 frr_help_exit(1);
495 break;
496 }
718e3744 497 }
d62a17ae 498 if (skip_runas)
499 memset(&bgpd_privs, 0, sizeof(bgpd_privs));
718e3744 500
d62a17ae 501 /* BGP master init. */
85e9cd9a 502 bgp_master_init(frr_init(), buffer_size, addresses);
d62a17ae 503 bm->port = bgp_port;
580f8636 504 if (bgp_port == 0)
505 bgp_option_set(BGP_OPT_NO_LISTEN);
0b014ea6 506 if (no_fib_flag || no_zebra_flag)
d62a17ae 507 bgp_option_set(BGP_OPT_NO_FIB);
0b014ea6
PG
508 if (no_zebra_flag)
509 bgp_option_set(BGP_OPT_NO_ZEBRA);
def31c13 510 bgp_error_init();
d62a17ae 511 /* Initializations. */
512 bgp_vrf_init();
718e3744 513
fa22080d 514#ifdef HAVE_SCRIPTING
b4becb06 515 bgp_script_init();
fa22080d 516#endif
b4becb06 517
374069da
CS
518 hook_register(routing_conf_event,
519 routing_control_plane_protocols_name_validate);
520
521
d62a17ae 522 /* BGP related initialization. */
f533be73 523 bgp_init((unsigned short)instance);
718e3744 524
85e9cd9a
AMR
525 if (list_isempty(bm->addresses)) {
526 snprintf(bgpd_di.startinfo, sizeof(bgpd_di.startinfo),
527 ", bgp@<all>:%d", bm->port);
528 } else {
529 for (ALL_LIST_ELEMENTS_RO(bm->addresses, node, address))
530 snprintf(bgpd_di.startinfo + strlen(bgpd_di.startinfo),
531 sizeof(bgpd_di.startinfo)
532 - strlen(bgpd_di.startinfo),
533 ", bgp@%s:%d", address, bm->port);
534 }
718e3744 535
d62a17ae 536 frr_config_fork();
2d4ee774 537 /* must be called after fork() */
034e185d 538 bgp_gr_apply_running_config();
419dfe6a 539 bgp_pthreads_run();
d62a17ae 540 frr_run(bm->master);
718e3744 541
d62a17ae 542 /* Not reached. */
95f7965d 543 return 0;
718e3744 544}