diff --git a/ldpd/lde.c b/ldpd/lde.c index 806bab6a213b..49764153cb9a 100644 --- a/ldpd/lde.c +++ b/ldpd/lde.c @@ -28,6 +28,7 @@ #include "stream.h" #include "network.h" #include "libfrr.h" +#include "ldp_zebra.h" static void lde_shutdown(void); static void lde_dispatch_imsg(struct event *thread); @@ -46,8 +47,6 @@ static void lde_map_free(void *); static int lde_address_add(struct lde_nbr *, struct lde_addr *); static int lde_address_del(struct lde_nbr *, struct lde_addr *); static void lde_address_list_free(struct lde_nbr *); -static void zclient_sync_init(void); -static void lde_label_list_init(void); static int lde_get_label_chunk(void); static void on_get_label_chunk_response(uint32_t start, uint32_t end); static uint32_t lde_get_next_label(void); @@ -56,6 +55,8 @@ static bool lde_fec_outside_mpls_network(const struct fec_node *); static void lde_check_filter_af(int, struct ldpd_af_conf *, const char *); +extern struct zebra_privs_t lde_privs; + RB_GENERATE(nbr_tree, lde_nbr, entry, lde_nbr_compare) RB_GENERATE(lde_map_head, lde_map, entry, lde_map_compare) @@ -66,29 +67,10 @@ static struct imsgev *iev_ldpe; static struct imsgev iev_main_sync_data; static struct imsgev *iev_main, *iev_main_sync; -/* lde privileges */ -static zebra_capabilities_t _caps_p [] = -{ - ZCAP_NET_ADMIN -}; - -static struct zebra_privs_t lde_privs = -{ -#if defined(VTY_GROUP) - .vty_group = VTY_GROUP, -#endif - .caps_p = _caps_p, - .cap_num_p = array_size(_caps_p), - .cap_num_i = 0 -}; - /* List of chunks of labels externally assigned by Zebra */ static struct list *label_chunk_list; static struct listnode *current_label_chunk; -/* Synchronous zclient to request labels */ -static struct zclient *zclient_sync; - /* SIGINT / SIGTERM handler. */ static void sigint(void) @@ -2120,67 +2102,6 @@ lde_address_list_free(struct lde_nbr *ln) free(lde_addr); } -/* - * Event callback used to retry the label-manager sync zapi session. - */ -static void zclient_sync_retry(struct event *thread) -{ - zclient_sync_init(); -} - -/* - * Initialize and open a synchronous zapi session. This is used by label chunk - * management code, which acquires and releases blocks of labels from the - * zebra label-manager module. - */ -static void zclient_sync_init(void) -{ - struct zclient_options options = zclient_options_default; - - options.synchronous = true; - - /* Initialize special zclient for synchronous message exchanges. */ - zclient_sync = zclient_new(master, &options, NULL, 0); - zclient_sync->sock = -1; - zclient_sync->redist_default = ZEBRA_ROUTE_LDP; - zclient_sync->session_id = 1; /* Distinguish from main session */ - zclient_sync->privs = &lde_privs; - - if (zclient_socket_connect(zclient_sync) < 0) { - log_warnx("Error connecting synchronous zclient!"); - goto retry; - } - /* make socket non-blocking */ - sock_set_nonblock(zclient_sync->sock); - - /* Send hello to notify zebra this is a synchronous client */ - if (zclient_send_hello(zclient_sync) == ZCLIENT_SEND_FAILURE) { - log_warnx("Error sending hello for synchronous zclient!"); - goto retry; - } - - /* Connect to label manager */ - if (lm_label_manager_connect(zclient_sync, 0) != 0) { - log_warnx("Error connecting to label manager!"); - goto retry; - } - - /* Finish label-manager init once the LM session is running */ - lde_label_list_init(); - - return; - -retry: - - /* Discard failed zclient object */ - zclient_stop(zclient_sync); - zclient_free(zclient_sync); - zclient_sync = NULL; - - /* Retry using a timer */ - event_add_timer(master, zclient_sync_retry, NULL, 1, NULL); -} - static void lde_del_label_chunk(void *val) { @@ -2219,8 +2140,7 @@ lde_get_label_chunk(void) return (0); } -static void -lde_label_list_init(void) +void lde_label_list_init(void) { label_chunk_list = list_new(); label_chunk_list->del = lde_del_label_chunk; diff --git a/ldpd/lde.h b/ldpd/lde.h index 2688b6a86bcb..4bcd3207cd6c 100644 --- a/ldpd/lde.h +++ b/ldpd/lde.h @@ -250,5 +250,8 @@ void l2vpn_recv_pw_status_wcard(struct lde_nbr *, int l2vpn_pw_status_update(struct zapi_pw_status *); void l2vpn_pw_ctl(pid_t); void l2vpn_binding_ctl(pid_t); +extern void lde_label_list_init(void); + +extern struct zclient *zclient_sync; #endif /* _LDE_H_ */ diff --git a/ldpd/ldp_zebra.c b/ldpd/ldp_zebra.c index 2010829035a1..a73fa0783e13 100644 --- a/ldpd/ldp_zebra.c +++ b/ldpd/ldp_zebra.c @@ -20,6 +20,7 @@ #include "ldp_sync.h" #include "log.h" #include "ldp_debug.h" +#include "ldp_zebra.h" static void ifp2kif(struct interface *, struct kif *); static void ifc2kaddr(struct interface *, struct connected *, struct kaddr *); @@ -39,8 +40,22 @@ static int ldp_zebra_opaque_msg_handler(ZAPI_CALLBACK_ARGS); static void ldp_sync_zebra_init(void); static struct zclient *zclient; +/* Synchronous zclient to request labels */ +struct zclient *zclient_sync; static bool zebra_registered = false; +/* lde privileges */ +static zebra_capabilities_t _caps_p[] = { ZCAP_NET_ADMIN }; + +struct zebra_privs_t lde_privs = { +#if defined(VTY_GROUP) + .vty_group = VTY_GROUP, +#endif + .caps_p = _caps_p, + .cap_num_p = array_size(_caps_p), + .cap_num_i = 0 +}; + static void ifp2kif(struct interface *ifp, struct kif *kif) { @@ -696,6 +711,67 @@ void ldp_zebra_init(struct event_loop *master) access_list_delete_hook(ldp_zebra_filter_update); } +/* + * Event callback used to retry the label-manager sync zapi session. + */ +static void zclient_sync_retry(struct event *thread) +{ + zclient_sync_init(); +} + +/* + * Initialize and open a synchronous zapi session. This is used by label chunk + * management code, which acquires and releases blocks of labels from the + * zebra label-manager module. + */ +void zclient_sync_init(void) +{ + struct zclient_options options = zclient_options_default; + + options.synchronous = true; + + /* Initialize special zclient for synchronous message exchanges. */ + zclient_sync = zclient_new(master, &options, NULL, 0); + zclient_sync->sock = -1; + zclient_sync->redist_default = ZEBRA_ROUTE_LDP; + zclient_sync->session_id = 1; /* Distinguish from main session */ + zclient_sync->privs = &lde_privs; + + if (zclient_socket_connect(zclient_sync) < 0) { + log_warnx("Error connecting synchronous zclient!"); + goto retry; + } + /* make socket non-blocking */ + sock_set_nonblock(zclient_sync->sock); + + /* Send hello to notify zebra this is a synchronous client */ + if (zclient_send_hello(zclient_sync) == ZCLIENT_SEND_FAILURE) { + log_warnx("Error sending hello for synchronous zclient!"); + goto retry; + } + + /* Connect to label manager */ + if (lm_label_manager_connect(zclient_sync, 0) != 0) { + log_warnx("Error connecting to label manager!"); + goto retry; + } + + /* Finish label-manager init once the LM session is running */ + lde_label_list_init(); + + return; + +retry: + + /* Discard failed zclient object */ + zclient_stop(zclient_sync); + zclient_free(zclient_sync); + zclient_sync = NULL; + + /* Retry using a timer */ + event_add_timer(master, zclient_sync_retry, NULL, 1, NULL); +} + void ldp_zebra_destroy(void) { @@ -703,4 +779,7 @@ ldp_zebra_destroy(void) zclient_stop(zclient); zclient_free(zclient); zclient = NULL; + zclient_stop(zclient_sync); + zclient_free(zclient_sync); + zclient_sync = NULL; } diff --git a/ldpd/ldp_zebra.h b/ldpd/ldp_zebra.h new file mode 100644 index 000000000000..72b8a0ee555d --- /dev/null +++ b/ldpd/ldp_zebra.h @@ -0,0 +1,11 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* zebra connection and redistribute fucntions. + * Copyright (C) 2023 Donatas Abraitis + */ + +#ifndef _FRR_LDP_ZEBRA_H +#define _FRR_LDP_ZEBRA_H + +extern void zclient_sync_init(void); + +#endif /* _FRR_LDP_ZEBRA_H */