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