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