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