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