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
27 #include <lib/version.h>
29 #include "memory_vty.h"
44 #include "bgpd/bgpd.h"
45 #include "bgpd/bgp_attr.h"
46 #include "bgpd/bgp_route.h"
47 #include "bgpd/bgp_mplsvpn.h"
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"
56 #include "bgpd/bgp_zebra.h"
59 #include "bgpd/rfapi/rfapi_backend.h"
62 /* bgpd options, we use GNU getopt library. */
63 static 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'},
72 /* signal definitions */
77 static void bgp_exit(int);
78 static void bgp_vrf_terminate(void);
80 static struct quagga_signal_t bgp_signals
[] = {
99 /* Route retain mode flag. */
100 static int retain_mode
= 0;
103 static zebra_capabilities_t _caps_p
[] = {
104 ZCAP_BIND
, ZCAP_NET_RAW
, ZCAP_NET_ADMIN
,
107 struct zebra_privs_t bgpd_privs
= {
108 #if defined(FRR_USER) && defined(FRR_GROUP)
113 .vty_group
= VTY_GROUP
,
116 .cap_num_p
= array_size(_caps_p
),
120 static struct frr_daemon_info bgpd_di
;
122 /* SIGHUP handler. */
125 zlog_info("SIGHUP received");
127 /* Terminate all thread. */
130 zlog_info("bgpd restarting!");
132 /* Reload config file. */
133 vty_read_config(bgpd_di
.config_file
, config_default
);
135 /* Try to return to normal operation. */
138 /* SIGINT handler. */
139 __attribute__((__noreturn__
)) void sigint(void)
141 zlog_notice("Terminating on signal");
145 if (bgpd_privs
.user
) /* NULL if skip_runas flag set */
146 zprivs_terminate(&bgpd_privs
);
154 /* SIGUSR1 handler. */
161 Try to free up allocations we know about so that diagnostic tools such as
162 valgrind are able to better illuminate leaks.
164 Zebra route removal and protocol teardown are not meant to be done here.
165 For example, "retain_mode" may be set.
167 static __attribute__((__noreturn__
)) void bgp_exit(int status
)
170 struct listnode
*node
, *nnode
;
172 /* it only makes sense for this to be called on a clean exit */
180 if_add_hook(IF_DELETE_HOOK
, NULL
);
182 /* reverse bgp_master_init */
183 for (ALL_LIST_ELEMENTS(bm
->bgp
, node
, nnode
, bgp
))
186 /* reverse bgp_dump_init */
189 /* reverse bgp_route_init */
192 /* cleanup route maps */
193 bgp_route_map_terminate();
195 /* reverse bgp_attr_init */
198 /* reverse access_list_init */
199 access_list_add_hook(NULL
);
200 access_list_delete_hook(NULL
);
203 /* reverse bgp_filter_init */
204 as_list_add_hook(NULL
);
205 as_list_delete_hook(NULL
);
208 /* reverse prefix_list_init */
209 prefix_list_add_hook(NULL
);
210 prefix_list_delete_hook(NULL
);
213 /* reverse community_list_init */
214 community_list_terminate(bgp_clist
);
224 /* reverse bgp_master_init */
226 thread_master_free(bm
->master
);
230 list_delete(bm
->bgp
);
231 memset(bm
, 0, sizeof(*bm
));
233 if (bgp_debug_count())
234 log_memstats_stderr("bgpd");
238 static int bgp_vrf_new(struct vrf
*vrf
)
240 if (BGP_DEBUG(zebra
, ZEBRA
))
241 zlog_debug("VRF Created: %s(%d)", vrf
->name
, vrf
->vrf_id
);
246 static int bgp_vrf_delete(struct vrf
*vrf
)
248 if (BGP_DEBUG(zebra
, ZEBRA
))
249 zlog_debug("VRF Deletion: %s(%d)", vrf
->name
, vrf
->vrf_id
);
254 static int bgp_vrf_enable(struct vrf
*vrf
)
259 if (BGP_DEBUG(zebra
, ZEBRA
))
260 zlog_debug("VRF enable add %s id %d", vrf
->name
, vrf
->vrf_id
);
262 bgp
= bgp_lookup_by_name(vrf
->name
);
264 old_vrf_id
= bgp
->vrf_id
;
265 /* We have instance configured, link to VRF and make it "up". */
266 bgp_vrf_link(bgp
, vrf
);
268 /* Update any redistribute vrf bitmaps if the vrf_id changed */
269 if (old_vrf_id
!= bgp
->vrf_id
)
270 bgp_update_redist_vrf_bitmaps(bgp
, old_vrf_id
);
271 bgp_instance_up(bgp
);
277 static int bgp_vrf_disable(struct vrf
*vrf
)
282 if (vrf
->vrf_id
== VRF_DEFAULT
)
285 if (BGP_DEBUG(zebra
, ZEBRA
))
286 zlog_debug("VRF disable %s id %d", vrf
->name
, vrf
->vrf_id
);
288 bgp
= bgp_lookup_by_name(vrf
->name
);
290 old_vrf_id
= bgp
->vrf_id
;
291 /* We have instance configured, unlink from VRF and make it
293 bgp_vrf_unlink(bgp
, vrf
);
294 /* Update any redistribute vrf bitmaps if the vrf_id changed */
295 if (old_vrf_id
!= bgp
->vrf_id
)
296 bgp_update_redist_vrf_bitmaps(bgp
, old_vrf_id
);
297 bgp_instance_down(bgp
);
300 /* Note: This is a callback, the VRF will be deleted by the caller. */
304 static void bgp_vrf_init(void)
306 vrf_init(bgp_vrf_new
, bgp_vrf_enable
, bgp_vrf_disable
, bgp_vrf_delete
);
309 static void bgp_vrf_terminate(void)
314 FRR_DAEMON_INFO(bgpd
, BGP
, .vty_port
= BGP_VTY_PORT
,
316 .proghelp
= "Implementation of the BGP routing protocol.",
318 .signals
= bgp_signals
, .n_signals
= array_size(bgp_signals
),
320 .privs
= &bgpd_privs
, )
322 /* Main routine of bgpd. Treatment of argument and start bgp finite
323 state machine is handled at here. */
324 int main(int argc
, char **argv
)
329 int bgp_port
= BGP_PORT_DEFAULT
;
330 char *bgp_address
= NULL
;
334 frr_preinit(&bgpd_di
, argc
, argv
);
336 "p:l:rne:", longopts
,
337 " -p, --bgp_port Set bgp protocol's port number\n"
338 " -l, --listenon Listen on specified address (implies -n)\n"
339 " -r, --retain When program terminates, retain added route by bgpd.\n"
340 " -n, --no_kernel Do not install route to kernel.\n"
341 " -S, --skip_runas Skip capabilities checks, and changing user and group IDs.\n"
342 " -e, --ecmp Specify ECMP to use.\n");
344 /* Command line argument treatment. */
346 opt
= frr_getopt(argc
, argv
, 0);
355 tmp_port
= atoi(optarg
);
356 if (tmp_port
<= 0 || tmp_port
> 0xffff)
357 bgp_port
= BGP_PORT_DEFAULT
;
362 multipath_num
= atoi(optarg
);
363 if (multipath_num
> MULTIPATH_NUM
364 || multipath_num
<= 0) {
366 "Multipath Number specified must be less than %d and greater than 0",
375 bgp_address
= optarg
;
376 /* listenon implies -n */
390 memset(&bgpd_privs
, 0, sizeof(bgpd_privs
));
392 /* BGP master init. */
393 bgp_master_init(frr_init());
395 bm
->address
= bgp_address
;
397 bgp_option_set(BGP_OPT_NO_FIB
);
399 /* Initializations. */
402 /* BGP related initialization. */
405 snprintf(bgpd_di
.startinfo
, sizeof(bgpd_di
.startinfo
), ", bgp@%s:%d",
406 (bm
->address
? bm
->address
: "<all>"), bm
->port
);