Skip to content

Commit

Permalink
ldpd: Stop and free synchronous Zebra client on destroy
Browse files Browse the repository at this point in the history
Signed-off-by: Donatas Abraitis <[email protected]>
  • Loading branch information
ton31337 committed Jun 25, 2023
1 parent 356d0ec commit 9e59d62
Show file tree
Hide file tree
Showing 4 changed files with 97 additions and 84 deletions.
88 changes: 4 additions & 84 deletions ldpd/lde.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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);
Expand All @@ -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)

Expand All @@ -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)
Expand Down Expand Up @@ -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)
{
Expand Down Expand Up @@ -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;
Expand Down
3 changes: 3 additions & 0 deletions ldpd/lde.h
Original file line number Diff line number Diff line change
Expand Up @@ -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_ */
79 changes: 79 additions & 0 deletions ldpd/ldp_zebra.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 *);
Expand All @@ -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)
{
Expand Down Expand Up @@ -696,11 +711,75 @@ 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)
{
ldp_zebra_opaque_unregister();
zclient_stop(zclient);
zclient_free(zclient);
zclient = NULL;
zclient_stop(zclient_sync);
zclient_free(zclient_sync);
zclient_sync = NULL;
}
11 changes: 11 additions & 0 deletions ldpd/ldp_zebra.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/* Zebra 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 */

0 comments on commit 9e59d62

Please sign in to comment.