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