From a375de5c460c7e3b31cf5668af238b517785a24e Mon Sep 17 00:00:00 2001 From: Rafael Zalamena Date: Wed, 11 Jul 2018 16:04:51 -0300 Subject: [PATCH] bfdd: free zebra clients data on unregistration Avoid a memory leak on client daemons restart by getting rid of old registrations. Signed-off-by: Rafael Zalamena --- bfdd/ptm_adapter.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/bfdd/ptm_adapter.c b/bfdd/ptm_adapter.c index 28e3326264..b2c6b8e2d0 100644 --- a/bfdd/ptm_adapter.c +++ b/bfdd/ptm_adapter.c @@ -63,6 +63,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 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, @@ -73,6 +74,7 @@ static void pcn_free(struct ptm_client_notification *pcn); static void bfdd_dest_register(struct stream *msg); static void bfdd_dest_deregister(struct stream *msg); static void bfdd_client_register(struct stream *msg); +static void bfdd_client_deregister(struct stream *msg); /* * Functions @@ -487,6 +489,32 @@ stream_failure: log_error("%s: failed to register client", __func__); } +/* + * header: command, VRF + * l: pid + */ +static void bfdd_client_deregister(struct stream *msg) +{ + struct ptm_client *pc; + uint32_t pid; + + /* Find or allocate process context data. */ + STREAM_GETL(msg, pid); + + pc = pc_lookup(pid); + if (pc == NULL) { + log_debug("%s: failed to find client: %u", __func__, pid); + return; + } + + pc_free(pc); + + return; + +stream_failure: + log_error("%s: failed to deregister client", __func__); +} + static int bfdd_replay(int cmd, struct zclient *zc, uint16_t len, vrf_id_t vid) { struct stream *msg = zc->ibuf; @@ -505,6 +533,9 @@ static int bfdd_replay(int cmd, struct zclient *zc, uint16_t len, vrf_id_t vid) case ZEBRA_BFD_CLIENT_REGISTER: bfdd_client_register(msg); break; + case ZEBRA_BFD_CLIENT_DEREGISTER: + bfdd_client_deregister(msg); + break; default: log_debug("%s: invalid message type %u", __func__, rcmd); @@ -593,6 +624,23 @@ static struct ptm_client *pc_new(uint32_t pid) return pc; } +static void pc_free(struct ptm_client *pc) +{ + struct ptm_client_notification *pcn; + + if (pc == NULL) + return; + + TAILQ_REMOVE(&pcqueue, pc, pc_entry); + + while (!TAILQ_EMPTY(&pc->pc_pcnqueue)) { + pcn = TAILQ_FIRST(&pc->pc_pcnqueue); + pcn_free(pcn); + } + + XFREE(MTYPE_BFDD_CONTROL, pc); +} + static struct ptm_client_notification *pcn_new(struct ptm_client *pc, struct bfd_session *bs) { -- 2.39.5