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