]> git.proxmox.com Git - mirror_frr.git/blob - zebra/main.c
Merge pull request #12802 from sri-mohan1/sri-bable
[mirror_frr.git] / zebra / main.c
1 /* zebra daemon main routine.
2 * Copyright (C) 1997, 98 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 <lib/version.h>
24 #include "getopt.h"
25 #include "command.h"
26 #include "thread.h"
27 #include "filter.h"
28 #include "memory.h"
29 #include "prefix.h"
30 #include "log.h"
31 #include "plist.h"
32 #include "privs.h"
33 #include "sigevent.h"
34 #include "vrf.h"
35 #include "libfrr.h"
36 #include "affinitymap.h"
37 #include "routemap.h"
38 #include "routing_nb.h"
39
40 #include "zebra/zebra_router.h"
41 #include "zebra/zebra_errors.h"
42 #include "zebra/rib.h"
43 #include "zebra/zserv.h"
44 #include "zebra/debug.h"
45 #include "zebra/router-id.h"
46 #include "zebra/irdp.h"
47 #include "zebra/rtadv.h"
48 #include "zebra/zebra_ptm.h"
49 #include "zebra/zebra_ns.h"
50 #include "zebra/redistribute.h"
51 #include "zebra/zebra_mpls.h"
52 #include "zebra/label_manager.h"
53 #include "zebra/zebra_netns_notify.h"
54 #include "zebra/zebra_rnh.h"
55 #include "zebra/zebra_pbr.h"
56 #include "zebra/zebra_vxlan.h"
57 #include "zebra/zebra_routemap.h"
58 #include "zebra/zebra_nb.h"
59 #include "zebra/zebra_opaque.h"
60 #include "zebra/zebra_srte.h"
61 #include "zebra/zebra_srv6.h"
62 #include "zebra/zebra_srv6_vty.h"
63
64 #define ZEBRA_PTM_SUPPORT
65
66 /* process id. */
67 pid_t pid;
68
69 /* Pacify zclient.o in libfrr, which expects this variable. */
70 struct thread_master *master;
71
72 /* Route retain mode flag. */
73 int retain_mode = 0;
74
75 int graceful_restart;
76
77 bool v6_rr_semantics = false;
78
79 /* Receive buffer size for kernel control sockets */
80 #define RCVBUFSIZE_MIN 4194304
81 #ifdef HAVE_NETLINK
82 uint32_t rcvbufsize = RCVBUFSIZE_MIN;
83 #else
84 uint32_t rcvbufsize = 128 * 1024;
85 #endif
86
87 #define OPTION_V6_RR_SEMANTICS 2000
88 #define OPTION_ASIC_OFFLOAD 2001
89
90 /* Command line options. */
91 const struct option longopts[] = {
92 {"batch", no_argument, NULL, 'b'},
93 {"allow_delete", no_argument, NULL, 'a'},
94 {"socket", required_argument, NULL, 'z'},
95 {"ecmp", required_argument, NULL, 'e'},
96 {"retain", no_argument, NULL, 'r'},
97 {"graceful_restart", required_argument, NULL, 'K'},
98 {"asic-offload", optional_argument, NULL, OPTION_ASIC_OFFLOAD},
99 #ifdef HAVE_NETLINK
100 {"vrfwnetns", no_argument, NULL, 'n'},
101 {"nl-bufsize", required_argument, NULL, 's'},
102 {"v6-rr-semantics", no_argument, NULL, OPTION_V6_RR_SEMANTICS},
103 #endif /* HAVE_NETLINK */
104 {0}};
105
106 zebra_capabilities_t _caps_p[] = {ZCAP_NET_ADMIN, ZCAP_SYS_ADMIN,
107 ZCAP_NET_RAW,
108 #ifdef HAVE_DPDK
109 ZCAP_IPC_LOCK, ZCAP_READ_SEARCH,
110 ZCAP_SYS_RAWIO
111 #endif
112 };
113
114 /* zebra privileges to run with */
115 struct zebra_privs_t zserv_privs = {
116 #if defined(FRR_USER) && defined(FRR_GROUP)
117 .user = FRR_USER,
118 .group = FRR_GROUP,
119 #endif
120 #ifdef VTY_GROUP
121 .vty_group = VTY_GROUP,
122 #endif
123 .caps_p = _caps_p,
124 .cap_num_p = array_size(_caps_p),
125 .cap_num_i = 0};
126
127 /* SIGHUP handler. */
128 static void sighup(void)
129 {
130 zlog_info("SIGHUP received");
131
132 /* Reload of config file. */
133 ;
134 }
135
136 /* SIGINT handler. */
137 static void sigint(void)
138 {
139 struct vrf *vrf;
140 struct zebra_vrf *zvrf;
141 struct listnode *ln, *nn;
142 struct zserv *client;
143 static bool sigint_done;
144
145 if (sigint_done)
146 return;
147
148 sigint_done = true;
149
150 zlog_notice("Terminating on signal");
151
152 atomic_store_explicit(&zrouter.in_shutdown, true,
153 memory_order_relaxed);
154
155 /* send RA lifetime of 0 before stopping. rfc4861/6.2.5 */
156 rtadv_stop_ra_all();
157
158 frr_early_fini();
159
160 /* Stop the opaque module pthread */
161 zebra_opaque_stop();
162
163 zebra_dplane_pre_finish();
164
165 /* Clean up GR related info. */
166 zebra_gr_stale_client_cleanup(zrouter.stale_client_list);
167 list_delete_all_node(zrouter.stale_client_list);
168
169 /* Clean up zapi clients and server module */
170 for (ALL_LIST_ELEMENTS(zrouter.client_list, ln, nn, client))
171 zserv_close_client(client);
172
173 zserv_close();
174 list_delete_all_node(zrouter.client_list);
175
176 /* Once all the zclients are cleaned up, clean up the opaque module */
177 zebra_opaque_finish();
178
179 zebra_ptm_finish();
180
181 if (retain_mode) {
182 zebra_nhg_mark_keep();
183 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
184 zvrf = vrf->info;
185 if (zvrf)
186 SET_FLAG(zvrf->flags, ZEBRA_VRF_RETAIN);
187 }
188 }
189
190 if (zrouter.lsp_process_q)
191 work_queue_free_and_null(&zrouter.lsp_process_q);
192
193 vrf_terminate();
194
195 ns_walk_func(zebra_ns_early_shutdown, NULL, NULL);
196 zebra_ns_notify_close();
197
198 access_list_reset();
199 prefix_list_reset();
200 /*
201 * zebra_routemap_finish will
202 * 1 set rmap upd timer to 0 so that rmap update wont be scheduled again
203 * 2 Put off the rmap update thread
204 * 3 route_map_finish
205 */
206 zebra_routemap_finish();
207
208 list_delete(&zrouter.client_list);
209
210 /* Indicate that all new dplane work has been enqueued. When that
211 * work is complete, the dataplane will enqueue an event
212 * with the 'finalize' function.
213 */
214 zebra_dplane_finish();
215 }
216
217 /*
218 * Final shutdown step for the zebra main thread. This is run after all
219 * async update processing has completed.
220 */
221 void zebra_finalize(struct thread *dummy)
222 {
223 zlog_info("Zebra final shutdown");
224
225 /* Stop dplane thread and finish any cleanup */
226 zebra_dplane_shutdown();
227
228 /* Final shutdown of ns resources */
229 ns_walk_func(zebra_ns_final_shutdown, NULL, NULL);
230
231 zebra_router_terminate();
232
233 ns_terminate();
234 frr_fini();
235 exit(0);
236 }
237
238 /* SIGUSR1 handler. */
239 static void sigusr1(void)
240 {
241 zlog_rotate();
242 }
243
244 struct frr_signal_t zebra_signals[] = {
245 {
246 .signal = SIGHUP,
247 .handler = &sighup,
248 },
249 {
250 .signal = SIGUSR1,
251 .handler = &sigusr1,
252 },
253 {
254 .signal = SIGINT,
255 .handler = &sigint,
256 },
257 {
258 .signal = SIGTERM,
259 .handler = &sigint,
260 },
261 };
262
263 /* clang-format off */
264 static const struct frr_yang_module_info *const zebra_yang_modules[] = {
265 &frr_filter_info,
266 &frr_interface_info,
267 &frr_route_map_info,
268 &frr_zebra_info,
269 &frr_vrf_info,
270 &frr_routing_info,
271 &frr_affinity_map_info,
272 &frr_zebra_route_map_info,
273 };
274 /* clang-format on */
275
276 FRR_DAEMON_INFO(
277 zebra, ZEBRA, .vty_port = ZEBRA_VTY_PORT, .flags = FRR_NO_ZCLIENT,
278
279 .proghelp =
280 "Daemon which manages kernel routing table management and\nredistribution between different routing protocols.",
281
282 .signals = zebra_signals, .n_signals = array_size(zebra_signals),
283
284 .privs = &zserv_privs,
285
286 .yang_modules = zebra_yang_modules,
287 .n_yang_modules = array_size(zebra_yang_modules),
288 );
289
290 /* Main startup routine. */
291 int main(int argc, char **argv)
292 {
293 // int batch_mode = 0;
294 char *zserv_path = NULL;
295 struct sockaddr_storage dummy;
296 socklen_t dummylen;
297 bool asic_offload = false;
298 bool notify_on_ack = true;
299
300 graceful_restart = 0;
301 vrf_configure_backend(VRF_BACKEND_VRF_LITE);
302
303 frr_preinit(&zebra_di, argc, argv);
304
305 frr_opt_add(
306 "baz:e:rK:s:"
307 #ifdef HAVE_NETLINK
308 "n"
309 #endif
310 ,
311 longopts,
312 " -b, --batch Runs in batch mode\n"
313 " -a, --allow_delete Allow other processes to delete zebra routes\n"
314 " -z, --socket Set path of zebra socket\n"
315 " -e, --ecmp Specify ECMP to use.\n"
316 " -r, --retain When program terminates, retain added route by zebra.\n"
317 " -K, --graceful_restart Graceful restart at the kernel level, timer in seconds for expiration\n"
318 " -A, --asic-offload FRR is interacting with an asic underneath the linux kernel\n"
319 #ifdef HAVE_NETLINK
320 " -s, --nl-bufsize Set netlink receive buffer size\n"
321 " -n, --vrfwnetns Use NetNS as VRF backend\n"
322 " --v6-rr-semantics Use v6 RR semantics\n"
323 #else
324 " -s, Set kernel socket receive buffer size\n"
325 #endif /* HAVE_NETLINK */
326 );
327
328 while (1) {
329 int opt = frr_getopt(argc, argv, NULL);
330
331 if (opt == EOF)
332 break;
333
334 switch (opt) {
335 case 0:
336 break;
337 case 'b':
338 // batch_mode = 1;
339 break;
340 case 'a':
341 zrouter.allow_delete = true;
342 break;
343 case 'e': {
344 unsigned long int parsed_multipath =
345 strtoul(optarg, NULL, 10);
346 if (parsed_multipath == 0
347 || parsed_multipath > MULTIPATH_NUM
348 || parsed_multipath > UINT32_MAX) {
349 flog_err(
350 EC_ZEBRA_BAD_MULTIPATH_NUM,
351 "Multipath Number specified must be less than %u and greater than 0",
352 MULTIPATH_NUM);
353 return 1;
354 }
355 zrouter.multipath_num = parsed_multipath;
356 break;
357 }
358 case 'z':
359 zserv_path = optarg;
360 if (!frr_zclient_addr(&dummy, &dummylen, optarg)) {
361 fprintf(stderr,
362 "Invalid zserv socket path: %s\n",
363 optarg);
364 exit(1);
365 }
366 break;
367 case 'r':
368 retain_mode = 1;
369 break;
370 case 'K':
371 graceful_restart = atoi(optarg);
372 break;
373 case 's':
374 rcvbufsize = atoi(optarg);
375 if (rcvbufsize < RCVBUFSIZE_MIN)
376 fprintf(stderr,
377 "Rcvbufsize is smaller than recommended value: %d\n",
378 RCVBUFSIZE_MIN);
379 break;
380 #ifdef HAVE_NETLINK
381 case 'n':
382 vrf_configure_backend(VRF_BACKEND_NETNS);
383 break;
384 case OPTION_V6_RR_SEMANTICS:
385 v6_rr_semantics = true;
386 break;
387 case OPTION_ASIC_OFFLOAD:
388 if (!strcmp(optarg, "notify_on_offload"))
389 notify_on_ack = false;
390 if (!strcmp(optarg, "notify_on_ack"))
391 notify_on_ack = true;
392 asic_offload = true;
393 break;
394 #endif /* HAVE_NETLINK */
395 default:
396 frr_help_exit(1);
397 }
398 }
399
400 zrouter.master = frr_init();
401
402 /* Zebra related initialize. */
403 zebra_router_init(asic_offload, notify_on_ack);
404 zserv_init();
405 rib_init();
406 zebra_if_init();
407 zebra_debug_init();
408
409 /*
410 * Initialize NS( and implicitly the VRF module), and make kernel
411 * routing socket. */
412 zebra_ns_init();
413 router_id_cmd_init();
414 zebra_vty_init();
415 access_list_init();
416 prefix_list_init();
417 rtadv_cmd_init();
418 /* PTM socket */
419 #ifdef ZEBRA_PTM_SUPPORT
420 zebra_ptm_init();
421 #endif
422
423 zebra_mpls_init();
424 zebra_mpls_vty_init();
425 zebra_pw_vty_init();
426 zebra_pbr_init();
427 zebra_opaque_init();
428 zebra_srte_init();
429 zebra_srv6_init();
430 zebra_srv6_vty_init();
431
432 /* For debug purpose. */
433 /* SET_FLAG (zebra_debug_event, ZEBRA_DEBUG_EVENT); */
434
435 /* Process the configuration file. Among other configuration
436 * directives we can meet those installing static routes. Such
437 * requests will not be executed immediately, but queued in
438 * zebra->ribq structure until we enter the main execution loop.
439 * The notifications from kernel will show originating PID equal
440 * to that after daemon() completes (if ever called).
441 */
442 frr_config_fork();
443
444 /* After we have successfully acquired the pidfile, we can be sure
445 * about being the only copy of zebra process, which is submitting
446 * changes to the FIB.
447 * Clean up zebra-originated routes. The requests will be sent to OS
448 * immediately, so originating PID in notifications from kernel
449 * will be equal to the current getpid(). To know about such routes,
450 * we have to have route_read() called before.
451 */
452 zrouter.startup_time = monotime(NULL);
453 thread_add_timer(zrouter.master, rib_sweep_route, NULL,
454 graceful_restart, &zrouter.sweeper);
455
456 /* Needed for BSD routing socket. */
457 pid = getpid();
458
459 /* Start dataplane system */
460 zebra_dplane_start();
461
462 /* Start the ted module, before zserv */
463 zebra_opaque_start();
464
465 /* Start Zebra API server */
466 zserv_start(zserv_path);
467
468 /* Init label manager */
469 label_manager_init();
470
471 /* RNH init */
472 zebra_rnh_init();
473
474 /* Config handler Init */
475 zebra_evpn_init();
476
477 /* Error init */
478 zebra_error_init();
479
480 frr_run(zrouter.master);
481
482 /* Not reached... */
483 return 0;
484 }