1 /* Main routine of bgpd.
2 * Copyright (C) 1996, 97, 98, 1999 Kunihiro Ishiguro
4 * This file is part of GNU Zebra.
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
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.
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
28 #include <lib/version.h>
30 #include "memory_vty.h"
46 #include "bgpd/bgpd.h"
47 #include "bgpd/bgp_attr.h"
48 #include "bgpd/bgp_route.h"
49 #include "bgpd/bgp_mplsvpn.h"
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_errors.h"
58 #include "bgpd/bgp_filter.h"
59 #include "bgpd/bgp_zebra.h"
60 #include "bgpd/bgp_packet.h"
61 #include "bgpd/bgp_keepalives.h"
62 #include "bgpd/bgp_network.h"
63 #include "bgpd/bgp_errors.h"
66 #include "bgpd/rfapi/rfapi_backend.h"
69 /* bgpd options, we use GNU getopt library. */
70 static const struct option longopts
[] = {
71 {"bgp_port", required_argument
, NULL
, 'p'},
72 {"listenon", required_argument
, NULL
, 'l'},
73 #if CONFDATE > 20190521
74 CPP_NOTICE("-r / --retain has reached deprecation EOL, remove")
76 {"retain", no_argument
, NULL
, 'r'},
77 {"no_kernel", no_argument
, NULL
, 'n'},
78 {"skip_runas", no_argument
, NULL
, 'S'},
79 {"ecmp", required_argument
, NULL
, 'e'},
82 /* signal definitions */
87 static void bgp_exit(int);
88 static void bgp_vrf_terminate(void);
90 static struct quagga_signal_t bgp_signals
[] = {
110 static zebra_capabilities_t _caps_p
[] = {ZCAP_BIND
, ZCAP_NET_RAW
,
111 ZCAP_NET_ADMIN
, ZCAP_SYS_ADMIN
};
113 struct zebra_privs_t bgpd_privs
= {
114 #if defined(FRR_USER) && defined(FRR_GROUP)
119 .vty_group
= VTY_GROUP
,
122 .cap_num_p
= array_size(_caps_p
),
126 static struct frr_daemon_info bgpd_di
;
128 /* SIGHUP handler. */
131 zlog_info("SIGHUP received");
133 /* Terminate all thread. */
136 zlog_info("bgpd restarting!");
138 /* Reload config file. */
139 vty_read_config(bgpd_di
.config_file
, config_default
);
141 /* Try to return to normal operation. */
144 /* SIGINT handler. */
145 __attribute__((__noreturn__
)) void sigint(void)
147 zlog_notice("Terminating on signal");
148 assert(bm
->terminating
== false);
149 bm
->terminating
= true; /* global flag that shutting down */
158 /* SIGUSR1 handler. */
165 Try to free up allocations we know about so that diagnostic tools such as
166 valgrind are able to better illuminate leaks.
168 Zebra route removal and protocol teardown are not meant to be done here.
169 For example, "retain_mode" may be set.
171 static __attribute__((__noreturn__
)) void bgp_exit(int status
)
173 struct bgp
*bgp
, *bgp_default
;
174 struct listnode
*node
, *nnode
;
176 /* it only makes sense for this to be called on a clean exit */
185 bgp_default
= bgp_get_default();
187 /* reverse bgp_master_init */
188 for (ALL_LIST_ELEMENTS(bm
->bgp
, node
, nnode
, bgp
)) {
189 if (bgp_default
== bgp
)
194 bgp_delete(bgp_default
);
196 /* reverse bgp_dump_init */
199 /* reverse bgp_route_init */
202 /* cleanup route maps */
203 bgp_route_map_terminate();
205 /* reverse bgp_attr_init */
209 bgp_pthreads_finish();
211 /* reverse access_list_init */
212 access_list_add_hook(NULL
);
213 access_list_delete_hook(NULL
);
216 /* reverse bgp_filter_init */
217 as_list_add_hook(NULL
);
218 as_list_delete_hook(NULL
);
221 /* reverse prefix_list_init */
222 prefix_list_add_hook(NULL
);
223 prefix_list_delete_hook(NULL
);
226 /* reverse community_list_init */
227 community_list_terminate(bgp_clist
);
235 bf_free(bm
->rd_idspace
);
236 list_delete_and_null(&bm
->bgp
);
237 memset(bm
, 0, sizeof(*bm
));
243 static int bgp_vrf_new(struct vrf
*vrf
)
245 if (BGP_DEBUG(zebra
, ZEBRA
))
246 zlog_debug("VRF Created: %s(%u)", vrf
->name
, vrf
->vrf_id
);
251 static int bgp_vrf_delete(struct vrf
*vrf
)
253 if (BGP_DEBUG(zebra
, ZEBRA
))
254 zlog_debug("VRF Deletion: %s(%u)", vrf
->name
, vrf
->vrf_id
);
259 static int bgp_vrf_enable(struct vrf
*vrf
)
264 if (BGP_DEBUG(zebra
, ZEBRA
))
265 zlog_debug("VRF enable add %s id %u", vrf
->name
, vrf
->vrf_id
);
267 bgp
= bgp_lookup_by_name(vrf
->name
);
269 old_vrf_id
= bgp
->vrf_id
;
270 /* We have instance configured, link to VRF and make it "up". */
271 bgp_vrf_link(bgp
, vrf
);
273 bgp_handle_socket(bgp
, vrf
, old_vrf_id
, true);
274 /* Update any redistribute vrf bitmaps if the vrf_id changed */
275 if (old_vrf_id
!= bgp
->vrf_id
)
276 bgp_update_redist_vrf_bitmaps(bgp
, old_vrf_id
);
277 bgp_instance_up(bgp
);
278 vpn_leak_zebra_vrf_label_update(bgp
, AFI_IP
);
279 vpn_leak_zebra_vrf_label_update(bgp
, AFI_IP6
);
280 vpn_leak_postchange(BGP_VPN_POLICY_DIR_TOVPN
, AFI_IP
,
281 bgp_get_default(), bgp
);
282 vpn_leak_postchange(BGP_VPN_POLICY_DIR_FROMVPN
, AFI_IP
,
283 bgp_get_default(), bgp
);
284 vpn_leak_postchange(BGP_VPN_POLICY_DIR_TOVPN
, AFI_IP6
,
285 bgp_get_default(), bgp
);
286 vpn_leak_postchange(BGP_VPN_POLICY_DIR_FROMVPN
, AFI_IP6
,
287 bgp_get_default(), bgp
);
293 static int bgp_vrf_disable(struct vrf
*vrf
)
298 if (vrf
->vrf_id
== VRF_DEFAULT
)
301 if (BGP_DEBUG(zebra
, ZEBRA
))
302 zlog_debug("VRF disable %s id %d", vrf
->name
, vrf
->vrf_id
);
304 bgp
= bgp_lookup_by_name(vrf
->name
);
307 vpn_leak_zebra_vrf_label_withdraw(bgp
, AFI_IP
);
308 vpn_leak_zebra_vrf_label_withdraw(bgp
, AFI_IP6
);
309 vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN
, AFI_IP
,
310 bgp_get_default(), bgp
);
311 vpn_leak_prechange(BGP_VPN_POLICY_DIR_FROMVPN
, AFI_IP
,
312 bgp_get_default(), bgp
);
313 vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN
, AFI_IP6
,
314 bgp_get_default(), bgp
);
315 vpn_leak_prechange(BGP_VPN_POLICY_DIR_FROMVPN
, AFI_IP6
,
316 bgp_get_default(), bgp
);
318 old_vrf_id
= bgp
->vrf_id
;
319 bgp_handle_socket(bgp
, vrf
, VRF_UNKNOWN
, false);
320 /* We have instance configured, unlink from VRF and make it
322 bgp_vrf_unlink(bgp
, vrf
);
323 /* Update any redistribute vrf bitmaps if the vrf_id changed */
324 if (old_vrf_id
!= bgp
->vrf_id
)
325 bgp_update_redist_vrf_bitmaps(bgp
, old_vrf_id
);
326 bgp_instance_down(bgp
);
329 /* Note: This is a callback, the VRF will be deleted by the caller. */
333 static void bgp_vrf_init(void)
335 vrf_init(bgp_vrf_new
, bgp_vrf_enable
, bgp_vrf_disable
, bgp_vrf_delete
);
338 static void bgp_vrf_terminate(void)
343 FRR_DAEMON_INFO(bgpd
, BGP
, .vty_port
= BGP_VTY_PORT
,
345 .proghelp
= "Implementation of the BGP routing protocol.",
347 .signals
= bgp_signals
, .n_signals
= array_size(bgp_signals
),
349 .privs
= &bgpd_privs
, )
351 #if CONFDATE > 20190521
352 CPP_NOTICE("-r / --retain has reached deprecation EOL, remove")
354 #define DEPRECATED_OPTIONS "r"
356 /* Main routine of bgpd. Treatment of argument and start bgp finite
357 state machine is handled at here. */
358 int main(int argc
, char **argv
)
363 int bgp_port
= BGP_PORT_DEFAULT
;
364 char *bgp_address
= NULL
;
368 frr_preinit(&bgpd_di
, argc
, argv
);
370 "p:l:Sne:" DEPRECATED_OPTIONS
, longopts
,
371 " -p, --bgp_port Set BGP listen port number (0 means do not listen).\n"
372 " -l, --listenon Listen on specified address (implies -n)\n"
373 " -n, --no_kernel Do not install route to kernel.\n"
374 " -S, --skip_runas Skip capabilities checks, and changing user and group IDs.\n"
375 " -e, --ecmp Specify ECMP to use.\n");
377 /* Command line argument treatment. */
379 opt
= frr_getopt(argc
, argv
, 0);
381 if (opt
&& opt
< 128 && strchr(DEPRECATED_OPTIONS
, opt
)) {
383 "The -%c option no longer exists.\nPlease refer to the manual.\n",
395 tmp_port
= atoi(optarg
);
396 if (tmp_port
< 0 || tmp_port
> 0xffff)
397 bgp_port
= BGP_PORT_DEFAULT
;
402 multipath_num
= atoi(optarg
);
403 if (multipath_num
> MULTIPATH_NUM
404 || multipath_num
<= 0) {
407 "Multipath Number specified must be less than %d and greater than 0",
413 bgp_address
= optarg
;
414 /* listenon implies -n */
428 memset(&bgpd_privs
, 0, sizeof(bgpd_privs
));
430 /* BGP master init. */
431 bgp_master_init(frr_init());
434 bgp_option_set(BGP_OPT_NO_LISTEN
);
435 bm
->address
= bgp_address
;
437 bgp_option_set(BGP_OPT_NO_FIB
);
440 /* Initializations. */
443 /* BGP related initialization. */
446 snprintf(bgpd_di
.startinfo
, sizeof(bgpd_di
.startinfo
), ", bgp@%s:%d",
447 (bm
->address
? bm
->address
: "<all>"), bm
->port
);
450 /* must be called after fork() */