]> git.proxmox.com Git - mirror_frr.git/blame - bgpd/bgp_main.c
Merge pull request #3394 from karamalla0406/frr3360
[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"
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"
4f04a76b 43#include "libfrr.h"
61cf4b37 44#include "ns.h"
718e3744 45
46#include "bgpd/bgpd.h"
47#include "bgpd/bgp_attr.h"
b2f0fa55 48#include "bgpd/bgp_route.h"
718e3744 49#include "bgpd/bgp_mplsvpn.h"
228da428
CC
50#include "bgpd/bgp_aspath.h"
51#include "bgpd/bgp_dump.h"
52#include "bgpd/bgp_route.h"
53#include "bgpd/bgp_nexthop.h"
54#include "bgpd/bgp_regex.h"
55#include "bgpd/bgp_clist.h"
56#include "bgpd/bgp_debug.h"
14454c9f 57#include "bgpd/bgp_errors.h"
228da428 58#include "bgpd/bgp_filter.h"
8196f13d 59#include "bgpd/bgp_zebra.h"
d3ecc69e 60#include "bgpd/bgp_packet.h"
03014d48 61#include "bgpd/bgp_keepalives.h"
61cf4b37 62#include "bgpd/bgp_network.h"
def31c13 63#include "bgpd/bgp_errors.h"
718e3744 64
65efcfce 65#ifdef ENABLE_BGP_VNC
f8b6f499 66#include "bgpd/rfapi/rfapi_backend.h"
65efcfce
LB
67#endif
68
718e3744 69/* bgpd options, we use GNU getopt library. */
d62a17ae 70static const struct option longopts[] = {
71 {"bgp_port", required_argument, NULL, 'p'},
72 {"listenon", required_argument, NULL, 'l'},
c8dde10f
QY
73#if CONFDATE > 20190521
74 CPP_NOTICE("-r / --retain has reached deprecation EOL, remove")
75#endif
d62a17ae 76 {"retain", no_argument, NULL, 'r'},
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'},
d62a17ae 81 {0}};
718e3744 82
2d75d052 83/* signal definitions */
d62a17ae 84void sighup(void);
85void sigint(void);
86void sigusr1(void);
2d75d052 87
d62a17ae 88static void bgp_exit(int);
89static void bgp_vrf_terminate(void);
228da428 90
d62a17ae 91static struct quagga_signal_t bgp_signals[] = {
92 {
93 .signal = SIGHUP,
94 .handler = &sighup,
95 },
96 {
97 .signal = SIGUSR1,
98 .handler = &sigusr1,
99 },
100 {
101 .signal = SIGINT,
102 .handler = &sigint,
103 },
104 {
105 .signal = SIGTERM,
106 .handler = &sigint,
107 },
2d75d052 108};
109
edd7c245 110/* privileges */
996c9314
LB
111static zebra_capabilities_t _caps_p[] = {ZCAP_BIND, ZCAP_NET_RAW,
112 ZCAP_NET_ADMIN, ZCAP_SYS_ADMIN};
edd7c245 113
d62a17ae 114struct zebra_privs_t bgpd_privs = {
b2f36157 115#if defined(FRR_USER) && defined(FRR_GROUP)
d62a17ae 116 .user = FRR_USER,
117 .group = FRR_GROUP,
d81fadfd 118#endif
119#ifdef VTY_GROUP
d62a17ae 120 .vty_group = VTY_GROUP,
edd7c245 121#endif
d62a17ae 122 .caps_p = _caps_p,
123 .cap_num_p = array_size(_caps_p),
124 .cap_num_i = 0,
edd7c245 125};
126
eb05883f
DL
127static struct frr_daemon_info bgpd_di;
128
718e3744 129/* SIGHUP handler. */
d62a17ae 130void sighup(void)
718e3744 131{
d62a17ae 132 zlog_info("SIGHUP received");
718e3744 133
d62a17ae 134 /* Terminate all thread. */
135 bgp_terminate();
136 bgp_reset();
137 zlog_info("bgpd restarting!");
718e3744 138
d62a17ae 139 /* Reload config file. */
1c2facd1 140 vty_read_config(NULL, bgpd_di.config_file, config_default);
718e3744 141
d62a17ae 142 /* Try to return to normal operation. */
718e3744 143}
144
145/* SIGINT handler. */
d62a17ae 146__attribute__((__noreturn__)) void sigint(void)
718e3744 147{
d62a17ae 148 zlog_notice("Terminating on signal");
97b4a0ec
LB
149 assert(bm->terminating == false);
150 bm->terminating = true; /* global flag that shutting down */
718e3744 151
c8dde10f 152 bgp_terminate();
718e3744 153
d62a17ae 154 bgp_exit(0);
540766e7 155
d62a17ae 156 exit(0);
718e3744 157}
158
159/* SIGUSR1 handler. */
d62a17ae 160void sigusr1(void)
718e3744 161{
d62a17ae 162 zlog_rotate();
718e3744 163}
228da428
CC
164
165/*
166 Try to free up allocations we know about so that diagnostic tools such as
167 valgrind are able to better illuminate leaks.
168
169 Zebra route removal and protocol teardown are not meant to be done here.
170 For example, "retain_mode" may be set.
171*/
d62a17ae 172static __attribute__((__noreturn__)) void bgp_exit(int status)
228da428 173{
0e42e319 174 struct bgp *bgp, *bgp_default;
d62a17ae 175 struct listnode *node, *nnode;
228da428 176
d62a17ae 177 /* it only makes sense for this to be called on a clean exit */
178 assert(status == 0);
228da428 179
03951374
DL
180 frr_early_fini();
181
d62a17ae 182 bfd_gbl_exit();
567b877d 183
d62a17ae 184 bgp_close();
1ff9a340 185
0e42e319
DS
186 bgp_default = bgp_get_default();
187
d62a17ae 188 /* reverse bgp_master_init */
0e42e319
DS
189 for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) {
190 if (bgp_default == bgp)
191 continue;
d62a17ae 192 bgp_delete(bgp);
0e42e319 193 }
1f4b2cce
DS
194 if (bgp_default)
195 bgp_delete(bgp_default);
46abd3e3 196
d62a17ae 197 /* reverse bgp_dump_init */
198 bgp_dump_finish();
228da428 199
d62a17ae 200 /* reverse bgp_route_init */
201 bgp_route_finish();
228da428 202
d62a17ae 203 /* cleanup route maps */
204 bgp_route_map_terminate();
228da428 205
d62a17ae 206 /* reverse bgp_attr_init */
207 bgp_attr_finish();
7b8def58 208
2d4ee774
QY
209 /* stop pthreads */
210 bgp_pthreads_finish();
211
d62a17ae 212 /* reverse access_list_init */
213 access_list_add_hook(NULL);
214 access_list_delete_hook(NULL);
215 access_list_reset();
228da428 216
d62a17ae 217 /* reverse bgp_filter_init */
218 as_list_add_hook(NULL);
219 as_list_delete_hook(NULL);
220 bgp_filter_reset();
228da428 221
d62a17ae 222 /* reverse prefix_list_init */
223 prefix_list_add_hook(NULL);
224 prefix_list_delete_hook(NULL);
225 prefix_list_reset();
228da428 226
d62a17ae 227 /* reverse community_list_init */
228 community_list_terminate(bgp_clist);
228da428 229
d62a17ae 230 bgp_vrf_terminate();
65efcfce 231#if ENABLE_BGP_VNC
d62a17ae 232 vnc_zebra_destroy();
65efcfce 233#endif
d62a17ae 234 bgp_zebra_destroy();
228da428 235
3d57c994 236 bf_free(bm->rd_idspace);
6a154c88 237 list_delete(&bm->bgp);
d62a17ae 238 memset(bm, 0, sizeof(*bm));
46857efe 239
03951374 240 frr_fini();
d62a17ae 241 exit(status);
228da428 242}
6b0655a2 243
d62a17ae 244static int bgp_vrf_new(struct vrf *vrf)
2fcc254e 245{
d62a17ae 246 if (BGP_DEBUG(zebra, ZEBRA))
a8bf7d9c 247 zlog_debug("VRF Created: %s(%u)", vrf->name, vrf->vrf_id);
2fcc254e 248
d62a17ae 249 return 0;
2fcc254e
DS
250}
251
d62a17ae 252static int bgp_vrf_delete(struct vrf *vrf)
2fcc254e 253{
d62a17ae 254 if (BGP_DEBUG(zebra, ZEBRA))
a8bf7d9c 255 zlog_debug("VRF Deletion: %s(%u)", vrf->name, vrf->vrf_id);
2fcc254e 256
d62a17ae 257 return 0;
2fcc254e
DS
258}
259
d62a17ae 260static int bgp_vrf_enable(struct vrf *vrf)
2fcc254e 261{
d62a17ae 262 struct bgp *bgp;
263 vrf_id_t old_vrf_id;
264
265 if (BGP_DEBUG(zebra, ZEBRA))
a8bf7d9c 266 zlog_debug("VRF enable add %s id %u", vrf->name, vrf->vrf_id);
d62a17ae 267
268 bgp = bgp_lookup_by_name(vrf->name);
269 if (bgp) {
9a8bdf1c
PG
270 if (bgp->name && strmatch(vrf->name, VRF_DEFAULT_NAME)) {
271 XFREE(MTYPE_BGP, bgp->name);
272 bgp->name = NULL;
273 XFREE(MTYPE_BGP, bgp->name_pretty);
274 bgp->name_pretty = XSTRDUP(MTYPE_BGP, "VRF default");
275 }
d62a17ae 276 old_vrf_id = bgp->vrf_id;
277 /* We have instance configured, link to VRF and make it "up". */
278 bgp_vrf_link(bgp, vrf);
279
e5619c28 280 bgp_handle_socket(bgp, vrf, old_vrf_id, true);
d62a17ae 281 /* Update any redistribute vrf bitmaps if the vrf_id changed */
282 if (old_vrf_id != bgp->vrf_id)
283 bgp_update_redist_vrf_bitmaps(bgp, old_vrf_id);
284 bgp_instance_up(bgp);
ddb5b488
PZ
285 vpn_leak_zebra_vrf_label_update(bgp, AFI_IP);
286 vpn_leak_zebra_vrf_label_update(bgp, AFI_IP6);
e504cf3b
DS
287 vpn_leak_postchange(BGP_VPN_POLICY_DIR_TOVPN, AFI_IP,
288 bgp_get_default(), bgp);
289 vpn_leak_postchange(BGP_VPN_POLICY_DIR_FROMVPN, AFI_IP,
290 bgp_get_default(), bgp);
291 vpn_leak_postchange(BGP_VPN_POLICY_DIR_TOVPN, AFI_IP6,
292 bgp_get_default(), bgp);
293 vpn_leak_postchange(BGP_VPN_POLICY_DIR_FROMVPN, AFI_IP6,
294 bgp_get_default(), bgp);
d62a17ae 295 }
296
297 return 0;
2fcc254e
DS
298}
299
d62a17ae 300static int bgp_vrf_disable(struct vrf *vrf)
2fcc254e 301{
d62a17ae 302 struct bgp *bgp;
303 vrf_id_t old_vrf_id;
304
305 if (vrf->vrf_id == VRF_DEFAULT)
306 return 0;
307
308 if (BGP_DEBUG(zebra, ZEBRA))
309 zlog_debug("VRF disable %s id %d", vrf->name, vrf->vrf_id);
310
311 bgp = bgp_lookup_by_name(vrf->name);
312 if (bgp) {
ddb5b488
PZ
313
314 vpn_leak_zebra_vrf_label_withdraw(bgp, AFI_IP);
315 vpn_leak_zebra_vrf_label_withdraw(bgp, AFI_IP6);
e504cf3b
DS
316 vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN, AFI_IP,
317 bgp_get_default(), bgp);
318 vpn_leak_prechange(BGP_VPN_POLICY_DIR_FROMVPN, AFI_IP,
319 bgp_get_default(), bgp);
320 vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN, AFI_IP6,
321 bgp_get_default(), bgp);
322 vpn_leak_prechange(BGP_VPN_POLICY_DIR_FROMVPN, AFI_IP6,
323 bgp_get_default(), bgp);
ddb5b488 324
d62a17ae 325 old_vrf_id = bgp->vrf_id;
e5619c28 326 bgp_handle_socket(bgp, vrf, VRF_UNKNOWN, false);
d62a17ae 327 /* We have instance configured, unlink from VRF and make it
328 * "down". */
329 bgp_vrf_unlink(bgp, vrf);
330 /* Update any redistribute vrf bitmaps if the vrf_id changed */
331 if (old_vrf_id != bgp->vrf_id)
332 bgp_update_redist_vrf_bitmaps(bgp, old_vrf_id);
333 bgp_instance_down(bgp);
334 }
335
336 /* Note: This is a callback, the VRF will be deleted by the caller. */
337 return 0;
2fcc254e
DS
338}
339
d62a17ae 340static void bgp_vrf_init(void)
2fcc254e 341{
ecbc5a37
PG
342 vrf_init(bgp_vrf_new, bgp_vrf_enable, bgp_vrf_disable,
343 bgp_vrf_delete, NULL);
2fcc254e
DS
344}
345
d62a17ae 346static void bgp_vrf_terminate(void)
021530c1 347{
d62a17ae 348 vrf_terminate();
021530c1 349}
350
8fcdd0d6
RW
351static const struct frr_yang_module_info *bgpd_yang_modules[] = {
352};
353
d62a17ae 354FRR_DAEMON_INFO(bgpd, BGP, .vty_port = BGP_VTY_PORT,
4f04a76b 355
d62a17ae 356 .proghelp = "Implementation of the BGP routing protocol.",
4f04a76b 357
d62a17ae 358 .signals = bgp_signals, .n_signals = array_size(bgp_signals),
4f04a76b 359
8fcdd0d6
RW
360 .privs = &bgpd_privs, .yang_modules = bgpd_yang_modules,
361 .n_yang_modules = array_size(bgpd_yang_modules), )
4f04a76b 362
c8dde10f
QY
363#if CONFDATE > 20190521
364CPP_NOTICE("-r / --retain has reached deprecation EOL, remove")
365#endif
366#define DEPRECATED_OPTIONS "r"
367
718e3744 368/* Main routine of bgpd. Treatment of argument and start bgp finite
369 state machine is handled at here. */
d62a17ae 370int main(int argc, char **argv)
718e3744 371{
d62a17ae 372 int opt;
373 int tmp_port;
374
375 int bgp_port = BGP_PORT_DEFAULT;
376 char *bgp_address = NULL;
377 int no_fib_flag = 0;
0b014ea6 378 int no_zebra_flag = 0;
d62a17ae 379 int skip_runas = 0;
f533be73 380 int instance = 0;
d62a17ae 381
382 frr_preinit(&bgpd_di, argc, argv);
383 frr_opt_add(
f533be73 384 "p:l:Sne:I:" DEPRECATED_OPTIONS, longopts,
580f8636 385 " -p, --bgp_port Set BGP listen port number (0 means do not listen).\n"
d62a17ae 386 " -l, --listenon Listen on specified address (implies -n)\n"
d62a17ae 387 " -n, --no_kernel Do not install route to kernel.\n"
0b014ea6 388 " -Z, --no_zebra Do not communicate with Zebra.\n"
d62a17ae 389 " -S, --skip_runas Skip capabilities checks, and changing user and group IDs.\n"
f533be73 390 " -e, --ecmp Specify ECMP to use.\n"
391 " -I, --int_num Set instance number (label-manager)\n");
d62a17ae 392
393 /* Command line argument treatment. */
394 while (1) {
395 opt = frr_getopt(argc, argv, 0);
396
c8dde10f
QY
397 if (opt && opt < 128 && strchr(DEPRECATED_OPTIONS, opt)) {
398 fprintf(stderr,
399 "The -%c option no longer exists.\nPlease refer to the manual.\n",
400 opt);
401 continue;
402 }
403
d62a17ae 404 if (opt == EOF)
405 break;
406
407 switch (opt) {
408 case 0:
409 break;
410 case 'p':
411 tmp_port = atoi(optarg);
580f8636 412 if (tmp_port < 0 || tmp_port > 0xffff)
d62a17ae 413 bgp_port = BGP_PORT_DEFAULT;
414 else
415 bgp_port = tmp_port;
416 break;
417 case 'e':
418 multipath_num = atoi(optarg);
419 if (multipath_num > MULTIPATH_NUM
420 || multipath_num <= 0) {
af4c2728 421 flog_err(
e50f7cfd 422 EC_BGP_MULTIPATH,
d62a17ae 423 "Multipath Number specified must be less than %d and greater than 0",
424 MULTIPATH_NUM);
425 return 1;
426 }
427 break;
d62a17ae 428 case 'l':
429 bgp_address = optarg;
430 /* listenon implies -n */
431 /* fallthru */
432 case 'n':
433 no_fib_flag = 1;
434 break;
0b014ea6
PG
435 case 'Z':
436 no_zebra_flag = 1;
437 break;
d62a17ae 438 case 'S':
439 skip_runas = 1;
440 break;
f533be73 441 case 'I':
442 instance = atoi(optarg);
443 if (instance > (unsigned short)-1)
444 zlog_err("Instance %i out of range (0..%u)",
445 instance, (unsigned short)-1);
446 break;
d62a17ae 447 default:
448 frr_help_exit(1);
449 break;
450 }
718e3744 451 }
d62a17ae 452 if (skip_runas)
453 memset(&bgpd_privs, 0, sizeof(bgpd_privs));
718e3744 454
d62a17ae 455 /* BGP master init. */
456 bgp_master_init(frr_init());
457 bm->port = bgp_port;
580f8636 458 if (bgp_port == 0)
459 bgp_option_set(BGP_OPT_NO_LISTEN);
d62a17ae 460 bm->address = bgp_address;
0b014ea6 461 if (no_fib_flag || no_zebra_flag)
d62a17ae 462 bgp_option_set(BGP_OPT_NO_FIB);
0b014ea6
PG
463 if (no_zebra_flag)
464 bgp_option_set(BGP_OPT_NO_ZEBRA);
def31c13 465 bgp_error_init();
d62a17ae 466 /* Initializations. */
467 bgp_vrf_init();
718e3744 468
d62a17ae 469 /* BGP related initialization. */
f533be73 470 bgp_init((unsigned short)instance);
718e3744 471
d62a17ae 472 snprintf(bgpd_di.startinfo, sizeof(bgpd_di.startinfo), ", bgp@%s:%d",
473 (bm->address ? bm->address : "<all>"), bm->port);
718e3744 474
d62a17ae 475 frr_config_fork();
2d4ee774 476 /* must be called after fork() */
419dfe6a 477 bgp_pthreads_run();
d62a17ae 478 frr_run(bm->master);
718e3744 479
d62a17ae 480 /* Not reached. */
481 return (0);
718e3744 482}