diff options
author | Rafael Zalamena <rzalamena@opensourcerouting.org> | 2018-07-11 21:04:51 +0200 |
---|---|---|
committer | Rafael Zalamena <rzalamena@opensourcerouting.org> | 2018-08-08 23:25:08 +0200 |
commit | a375de5c460c7e3b31cf5668af238b517785a24e (patch) | |
tree | 14050fe170b5ceff0ebc7b8b9c396b987c37c258 /bfdd/ptm_adapter.c | |
parent | bfdd: send replay request on zebra connection (diff) | |
download | frr-a375de5c460c7e3b31cf5668af238b517785a24e.tar.xz frr-a375de5c460c7e3b31cf5668af238b517785a24e.zip |
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 <rzalamena@opensourcerouting.org>
Diffstat (limited to 'bfdd/ptm_adapter.c')
-rw-r--r-- | bfdd/ptm_adapter.c | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/bfdd/ptm_adapter.c b/bfdd/ptm_adapter.c index 28e332626..b2c6b8e2d 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) { |