diff --git a/zebra/main.c b/zebra/main.c index 4d9b7c3bbe35..138a955bc313 100644 --- a/zebra/main.c +++ b/zebra/main.c @@ -54,6 +54,8 @@ #define ZEBRA_PTM_SUPPORT +char *zserv_path; + /* process id. */ pid_t pid; @@ -314,17 +316,46 @@ FRR_DAEMON_INFO(zebra, ZEBRA, ); /* clang-format on */ +void zebra_main_router_started(void) +{ + /* + * Clean up zebra-originated routes. The requests will be sent to OS + * immediately, so originating PID in notifications from kernel + * will be equal to the current getpid(). To know about such routes, + * we have to have route_read() called before. + * If FRR is gracefully restarting, we either wait for clients + * (e.g., BGP) to signal GR is complete else we wait for specified + * duration. + */ + zrouter.startup_time = monotime(NULL); + zrouter.rib_sweep_time = 0; + zrouter.graceful_restart = zebra_di.graceful_restart; + if (!zrouter.graceful_restart) + event_add_timer(zrouter.master, rib_sweep_route, NULL, 0, NULL); + else { + int gr_cleanup_time; + + gr_cleanup_time = zebra_di.gr_cleanup_time ? zebra_di.gr_cleanup_time + : ZEBRA_GR_DEFAULT_RIB_SWEEP_TIME; + event_add_timer(zrouter.master, rib_sweep_route, NULL, gr_cleanup_time, + &zrouter.t_rib_sweep); + } + + zserv_start(zserv_path); +} + /* Main startup routine. */ int main(int argc, char **argv) { // int batch_mode = 0; - char *zserv_path = NULL; struct sockaddr_storage dummy; socklen_t dummylen; bool asic_offload = false; bool v6_with_v4_nexthop = false; bool notify_on_ack = true; + zserv_path = NULL; + vrf_configure_backend(VRF_BACKEND_VRF_LITE); frr_preinit(&zebra_di, argc, argv); @@ -475,31 +506,11 @@ int main(int argc, char **argv) */ frr_config_fork(); - /* After we have successfully acquired the pidfile, we can be sure - * about being the only copy of zebra process, which is submitting - * changes to the FIB. - * Clean up zebra-originated routes. The requests will be sent to OS - * immediately, so originating PID in notifications from kernel - * will be equal to the current getpid(). To know about such routes, - * we have to have route_read() called before. - * If FRR is gracefully restarting, we either wait for clients - * (e.g., BGP) to signal GR is complete else we wait for specified - * duration. - */ - zrouter.startup_time = monotime(NULL); - zrouter.rib_sweep_time = 0; - zrouter.graceful_restart = zebra_di.graceful_restart; - if (!zrouter.graceful_restart) - event_add_timer(zrouter.master, rib_sweep_route, NULL, 0, NULL); - else { - int gr_cleanup_time; - - gr_cleanup_time = zebra_di.gr_cleanup_time - ? zebra_di.gr_cleanup_time - : ZEBRA_GR_DEFAULT_RIB_SWEEP_TIME; - event_add_timer(zrouter.master, rib_sweep_route, NULL, - gr_cleanup_time, &zrouter.t_rib_sweep); - } + /* + * After we have successfully acquired the pidfile, we can be sure + * about being the only copy of zebra process, which is submitting + * changes to the FIB. + */ /* Needed for BSD routing socket. */ pid = getpid(); @@ -510,9 +521,6 @@ int main(int argc, char **argv) /* Start the ted module, before zserv */ zebra_opaque_start(); - /* Start Zebra API server */ - zserv_start(zserv_path); - /* Init label manager */ label_manager_init(); diff --git a/zebra/zebra_ns.c b/zebra/zebra_ns.c index ffd749fcf17e..d6ed0cc40564 100644 --- a/zebra/zebra_ns.c +++ b/zebra/zebra_ns.c @@ -123,6 +123,17 @@ void zebra_ns_startup_continue(struct zebra_dplane_ctx *ctx) vlan_read(zns); kernel_read_pbr_rules(zns); kernel_read_tc_qdisc(zns); + + /* + * At this point FRR has requested and read a bunch + * of data from the dplane about initial state of + * the system. Zebra now needs to initialize + * the gr subsystem ( or the route sweeping + * subsystem ) to allow that to properly work. + * This must be done *immediately* after the + * load of all data from the underlying dplane. + */ + zebra_main_router_started(); break; } } diff --git a/zebra/zebra_router.h b/zebra/zebra_router.h index c86c6be1ef56..a637c3214e06 100644 --- a/zebra/zebra_router.h +++ b/zebra/zebra_router.h @@ -329,6 +329,8 @@ static inline uint8_t if_netlink_get_frr_protodown_r_bit(void) return zrouter.protodown_r_bit; } +extern void zebra_main_router_started(void); + /* zebra_northbound.c */ extern const struct frr_yang_module_info frr_zebra_info;