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