]> git.proxmox.com Git - mirror_frr.git/blob - bgpd/bgp_main.c
Merge pull request #2352 from qlyoung/fix-yet-another-vtysh-read-bug
[mirror_frr.git] / bgpd / bgp_main.c
1 /* Main routine of bgpd.
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 */
20
21 #include <zebra.h>
22
23 #include <pthread.h>
24 #include "vector.h"
25 #include "command.h"
26 #include "getopt.h"
27 #include "thread.h"
28 #include <lib/version.h>
29 #include "memory.h"
30 #include "memory_vty.h"
31 #include "prefix.h"
32 #include "log.h"
33 #include "privs.h"
34 #include "sigevent.h"
35 #include "zclient.h"
36 #include "routemap.h"
37 #include "filter.h"
38 #include "plist.h"
39 #include "stream.h"
40 #include "queue.h"
41 #include "vrf.h"
42 #include "bfd.h"
43 #include "libfrr.h"
44 #include "ns.h"
45
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_filter.h"
58 #include "bgpd/bgp_zebra.h"
59 #include "bgpd/bgp_packet.h"
60 #include "bgpd/bgp_keepalives.h"
61 #include "bgpd/bgp_network.h"
62
63 #ifdef ENABLE_BGP_VNC
64 #include "bgpd/rfapi/rfapi_backend.h"
65 #endif
66
67 /* bgpd options, we use GNU getopt library. */
68 static const struct option longopts[] = {
69 {"bgp_port", required_argument, NULL, 'p'},
70 {"listenon", required_argument, NULL, 'l'},
71 #if CONFDATE > 20190521
72 CPP_NOTICE("-r / --retain has reached deprecation EOL, remove")
73 #endif
74 {"retain", no_argument, NULL, 'r'},
75 {"no_kernel", no_argument, NULL, 'n'},
76 {"skip_runas", no_argument, NULL, 'S'},
77 {"ecmp", required_argument, NULL, 'e'},
78 {0}};
79
80 /* signal definitions */
81 void sighup(void);
82 void sigint(void);
83 void sigusr1(void);
84
85 static void bgp_exit(int);
86 static void bgp_vrf_terminate(void);
87
88 static struct quagga_signal_t bgp_signals[] = {
89 {
90 .signal = SIGHUP,
91 .handler = &sighup,
92 },
93 {
94 .signal = SIGUSR1,
95 .handler = &sigusr1,
96 },
97 {
98 .signal = SIGINT,
99 .handler = &sigint,
100 },
101 {
102 .signal = SIGTERM,
103 .handler = &sigint,
104 },
105 };
106
107 /* privileges */
108 static zebra_capabilities_t _caps_p[] = {ZCAP_BIND, ZCAP_NET_RAW,
109 ZCAP_NET_ADMIN, ZCAP_SYS_ADMIN};
110
111 struct zebra_privs_t bgpd_privs = {
112 #if defined(FRR_USER) && defined(FRR_GROUP)
113 .user = FRR_USER,
114 .group = FRR_GROUP,
115 #endif
116 #ifdef VTY_GROUP
117 .vty_group = VTY_GROUP,
118 #endif
119 .caps_p = _caps_p,
120 .cap_num_p = array_size(_caps_p),
121 .cap_num_i = 0,
122 };
123
124 static struct frr_daemon_info bgpd_di;
125
126 /* SIGHUP handler. */
127 void sighup(void)
128 {
129 zlog_info("SIGHUP received");
130
131 /* Terminate all thread. */
132 bgp_terminate();
133 bgp_reset();
134 zlog_info("bgpd restarting!");
135
136 /* Reload config file. */
137 vty_read_config(bgpd_di.config_file, config_default);
138
139 /* Try to return to normal operation. */
140 }
141
142 /* SIGINT handler. */
143 __attribute__((__noreturn__)) void sigint(void)
144 {
145 zlog_notice("Terminating on signal");
146 assert(bm->terminating == false);
147 bm->terminating = true; /* global flag that shutting down */
148
149 bgp_terminate();
150
151 bgp_exit(0);
152
153 exit(0);
154 }
155
156 /* SIGUSR1 handler. */
157 void sigusr1(void)
158 {
159 zlog_rotate();
160 }
161
162 /*
163 Try to free up allocations we know about so that diagnostic tools such as
164 valgrind are able to better illuminate leaks.
165
166 Zebra route removal and protocol teardown are not meant to be done here.
167 For example, "retain_mode" may be set.
168 */
169 static __attribute__((__noreturn__)) void bgp_exit(int status)
170 {
171 struct bgp *bgp;
172 struct listnode *node, *nnode;
173
174 /* it only makes sense for this to be called on a clean exit */
175 assert(status == 0);
176
177 frr_early_fini();
178
179 bfd_gbl_exit();
180
181 bgp_close();
182
183 /* reverse bgp_master_init */
184 for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp))
185 bgp_delete(bgp);
186
187 /* reverse bgp_dump_init */
188 bgp_dump_finish();
189
190 /* reverse bgp_route_init */
191 bgp_route_finish();
192
193 /* cleanup route maps */
194 bgp_route_map_terminate();
195
196 /* reverse bgp_attr_init */
197 bgp_attr_finish();
198
199 /* stop pthreads */
200 bgp_pthreads_finish();
201
202 /* reverse access_list_init */
203 access_list_add_hook(NULL);
204 access_list_delete_hook(NULL);
205 access_list_reset();
206
207 /* reverse bgp_filter_init */
208 as_list_add_hook(NULL);
209 as_list_delete_hook(NULL);
210 bgp_filter_reset();
211
212 /* reverse prefix_list_init */
213 prefix_list_add_hook(NULL);
214 prefix_list_delete_hook(NULL);
215 prefix_list_reset();
216
217 /* reverse community_list_init */
218 community_list_terminate(bgp_clist);
219
220 bgp_vrf_terminate();
221 #if ENABLE_BGP_VNC
222 vnc_zebra_destroy();
223 #endif
224 bgp_zebra_destroy();
225
226 bf_free(bm->rd_idspace);
227 list_delete_and_null(&bm->bgp);
228 memset(bm, 0, sizeof(*bm));
229
230 frr_fini();
231 exit(status);
232 }
233
234 static int bgp_vrf_new(struct vrf *vrf)
235 {
236 if (BGP_DEBUG(zebra, ZEBRA))
237 zlog_debug("VRF Created: %s(%u)", vrf->name, vrf->vrf_id);
238
239 return 0;
240 }
241
242 static int bgp_vrf_delete(struct vrf *vrf)
243 {
244 if (BGP_DEBUG(zebra, ZEBRA))
245 zlog_debug("VRF Deletion: %s(%u)", vrf->name, vrf->vrf_id);
246
247 return 0;
248 }
249
250 static int bgp_vrf_enable(struct vrf *vrf)
251 {
252 struct bgp *bgp;
253 vrf_id_t old_vrf_id;
254
255 if (BGP_DEBUG(zebra, ZEBRA))
256 zlog_debug("VRF enable add %s id %u", vrf->name, vrf->vrf_id);
257
258 bgp = bgp_lookup_by_name(vrf->name);
259 if (bgp) {
260 old_vrf_id = bgp->vrf_id;
261 /* We have instance configured, link to VRF and make it "up". */
262 bgp_vrf_link(bgp, vrf);
263
264 bgp_handle_socket(bgp, vrf, old_vrf_id, true);
265 /* Update any redistribute vrf bitmaps if the vrf_id changed */
266 if (old_vrf_id != bgp->vrf_id)
267 bgp_update_redist_vrf_bitmaps(bgp, old_vrf_id);
268 bgp_instance_up(bgp);
269 vpn_leak_zebra_vrf_label_update(bgp, AFI_IP);
270 vpn_leak_zebra_vrf_label_update(bgp, AFI_IP6);
271 }
272
273 return 0;
274 }
275
276 static int bgp_vrf_disable(struct vrf *vrf)
277 {
278 struct bgp *bgp;
279 vrf_id_t old_vrf_id;
280
281 if (vrf->vrf_id == VRF_DEFAULT)
282 return 0;
283
284 if (BGP_DEBUG(zebra, ZEBRA))
285 zlog_debug("VRF disable %s id %d", vrf->name, vrf->vrf_id);
286
287 bgp = bgp_lookup_by_name(vrf->name);
288 if (bgp) {
289
290 vpn_leak_zebra_vrf_label_withdraw(bgp, AFI_IP);
291 vpn_leak_zebra_vrf_label_withdraw(bgp, AFI_IP6);
292
293 old_vrf_id = bgp->vrf_id;
294 bgp_handle_socket(bgp, vrf, VRF_UNKNOWN, false);
295 /* We have instance configured, unlink from VRF and make it
296 * "down". */
297 bgp_vrf_unlink(bgp, vrf);
298 /* Update any redistribute vrf bitmaps if the vrf_id changed */
299 if (old_vrf_id != bgp->vrf_id)
300 bgp_update_redist_vrf_bitmaps(bgp, old_vrf_id);
301 bgp_instance_down(bgp);
302 }
303
304 /* Note: This is a callback, the VRF will be deleted by the caller. */
305 return 0;
306 }
307
308 static void bgp_vrf_init(void)
309 {
310 vrf_init(bgp_vrf_new, bgp_vrf_enable, bgp_vrf_disable, bgp_vrf_delete);
311 }
312
313 static void bgp_vrf_terminate(void)
314 {
315 vrf_terminate();
316 }
317
318 FRR_DAEMON_INFO(bgpd, BGP, .vty_port = BGP_VTY_PORT,
319
320 .proghelp = "Implementation of the BGP routing protocol.",
321
322 .signals = bgp_signals, .n_signals = array_size(bgp_signals),
323
324 .privs = &bgpd_privs, )
325
326 #if CONFDATE > 20190521
327 CPP_NOTICE("-r / --retain has reached deprecation EOL, remove")
328 #endif
329 #define DEPRECATED_OPTIONS "r"
330
331 /* Main routine of bgpd. Treatment of argument and start bgp finite
332 state machine is handled at here. */
333 int main(int argc, char **argv)
334 {
335 int opt;
336 int tmp_port;
337
338 int bgp_port = BGP_PORT_DEFAULT;
339 char *bgp_address = NULL;
340 int no_fib_flag = 0;
341 int skip_runas = 0;
342
343 frr_preinit(&bgpd_di, argc, argv);
344 frr_opt_add(
345 "p:l:Sne:" DEPRECATED_OPTIONS, longopts,
346 " -p, --bgp_port Set BGP listen port number (0 means do not listen).\n"
347 " -l, --listenon Listen on specified address (implies -n)\n"
348 " -n, --no_kernel Do not install route to kernel.\n"
349 " -S, --skip_runas Skip capabilities checks, and changing user and group IDs.\n"
350 " -e, --ecmp Specify ECMP to use.\n");
351
352 /* Command line argument treatment. */
353 while (1) {
354 opt = frr_getopt(argc, argv, 0);
355
356 if (opt && opt < 128 && strchr(DEPRECATED_OPTIONS, opt)) {
357 fprintf(stderr,
358 "The -%c option no longer exists.\nPlease refer to the manual.\n",
359 opt);
360 continue;
361 }
362
363 if (opt == EOF)
364 break;
365
366 switch (opt) {
367 case 0:
368 break;
369 case 'p':
370 tmp_port = atoi(optarg);
371 if (tmp_port < 0 || tmp_port > 0xffff)
372 bgp_port = BGP_PORT_DEFAULT;
373 else
374 bgp_port = tmp_port;
375 break;
376 case 'e':
377 multipath_num = atoi(optarg);
378 if (multipath_num > MULTIPATH_NUM
379 || multipath_num <= 0) {
380 zlog_err(
381 "Multipath Number specified must be less than %d and greater than 0",
382 MULTIPATH_NUM);
383 return 1;
384 }
385 break;
386 case 'l':
387 bgp_address = optarg;
388 /* listenon implies -n */
389 /* fallthru */
390 case 'n':
391 no_fib_flag = 1;
392 break;
393 case 'S':
394 skip_runas = 1;
395 break;
396 default:
397 frr_help_exit(1);
398 break;
399 }
400 }
401 if (skip_runas)
402 memset(&bgpd_privs, 0, sizeof(bgpd_privs));
403
404 /* BGP master init. */
405 bgp_master_init(frr_init());
406 bm->port = bgp_port;
407 if (bgp_port == 0)
408 bgp_option_set(BGP_OPT_NO_LISTEN);
409 bm->address = bgp_address;
410 if (no_fib_flag)
411 bgp_option_set(BGP_OPT_NO_FIB);
412
413 /* Initializations. */
414 bgp_vrf_init();
415
416 /* BGP related initialization. */
417 bgp_init();
418
419 snprintf(bgpd_di.startinfo, sizeof(bgpd_di.startinfo), ", bgp@%s:%d",
420 (bm->address ? bm->address : "<all>"), bm->port);
421
422 frr_config_fork();
423 /* must be called after fork() */
424 bgp_pthreads_run();
425 frr_run(bm->master);
426
427 /* Not reached. */
428 return (0);
429 }