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