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