From 788378fefac03d0a51be8409b4d0d20b723ca234 Mon Sep 17 00:00:00 2001 From: Rafael Zalamena Date: Wed, 25 Jul 2018 13:39:58 -0300 Subject: [PATCH] bfdd: clean-up bfd clients data on shutdown On `zebra` / `bfdd` shutdown we now clean up all client data to avoid memory leaks (ghost clients). This also prevents 'slow' shutdown on `zebra` sparing us from seeing some rare topotests shutdown failures (signal handler getting stopped by signal). Signed-off-by: Rafael Zalamena --- bfdd/ptm_adapter.c | 17 +++++++++++++++++ zebra/zebra_ptm.c | 22 ++++++++++++++++++---- 2 files changed, 35 insertions(+), 4 deletions(-) diff --git a/bfdd/ptm_adapter.c b/bfdd/ptm_adapter.c index b2c6b8e2d0..ca44be6541 100644 --- a/bfdd/ptm_adapter.c +++ b/bfdd/ptm_adapter.c @@ -64,6 +64,7 @@ static int _ptm_msg_read(struct stream *msg, int command, static struct ptm_client *pc_lookup(uint32_t pid); static struct ptm_client *pc_new(uint32_t pid); static void pc_free(struct ptm_client *pc); +static void pc_free_all(void); static struct ptm_client_notification *pcn_new(struct ptm_client *pc, struct bfd_session *bs); static struct ptm_client_notification *pcn_lookup(struct ptm_client *pc, @@ -553,6 +554,9 @@ static void bfdd_zebra_connected(struct zclient *zc) { struct stream *msg = zc->obuf; + /* Clean-up and free ptm clients data memory. */ + pc_free_all(); + /* * The replay is an empty message just to trigger client daemons * configuration replay. @@ -585,6 +589,9 @@ void bfdd_zclient_init(struct zebra_privs_t *bfdd_priv) void bfdd_zclient_stop(void) { zclient_stop(zclient); + + /* Clean-up and free ptm clients data memory. */ + pc_free_all(); } @@ -641,6 +648,16 @@ static void pc_free(struct ptm_client *pc) XFREE(MTYPE_BFDD_CONTROL, pc); } +static void pc_free_all(void) +{ + struct ptm_client *pc; + + while (!TAILQ_EMPTY(&pcqueue)) { + pc = TAILQ_FIRST(&pcqueue); + pc_free(pc); + } +} + static struct ptm_client_notification *pcn_new(struct ptm_client *pc, struct bfd_session *bs) { diff --git a/zebra/zebra_ptm.c b/zebra/zebra_ptm.c index 76e427570b..cc2d5d411d 100644 --- a/zebra/zebra_ptm.c +++ b/zebra/zebra_ptm.c @@ -1175,6 +1175,7 @@ DEFINE_MTYPE_STATIC(ZEBRA, ZEBRA_PTM_BFD_PROCESS, static struct ptm_process *pp_new(pid_t pid, struct zserv *zs); static struct ptm_process *pp_lookup_byzs(struct zserv *zs); static void pp_free(struct ptm_process *pp); +static void pp_free_all(void); static void zebra_ptm_send_bfdd(struct stream *msg); static void zebra_ptm_send_clients(struct stream *msg); @@ -1239,6 +1240,16 @@ static void pp_free(struct ptm_process *pp) XFREE(MTYPE_ZEBRA_PTM_BFD_PROCESS, pp); } +static void pp_free_all(void) +{ + struct ptm_process *pp; + + while (!TAILQ_EMPTY(&ppqueue)) { + pp = TAILQ_FIRST(&ppqueue); + pp_free(pp); + } +} + /* * Use the FRR's internal daemon implementation. @@ -1385,6 +1396,13 @@ void zebra_ptm_init(void) hook_register(zserv_client_close, _zebra_ptm_bfd_client_deregister); } +void zebra_ptm_finish(void) +{ + /* Remove the client disconnect hook and free all memory. */ + hook_unregister(zserv_client_close, _zebra_ptm_bfd_client_deregister); + pp_free_all(); +} + /* * Message handling. @@ -1528,10 +1546,6 @@ void zebra_ptm_bfd_dst_replay(ZAPI_HANDLER_ARGS) /* * Unused functions. */ -void zebra_ptm_finish(void) -{ - /* NOTHING */ -} void zebra_ptm_if_init(struct zebra_if *zifp __attribute__((__unused__))) { /* NOTHING */ -- 2.39.5