From 19de8709d7ee951e582e288e5940e0a1afe10399 Mon Sep 17 00:00:00 2001 From: "G. Paul Ziemba" Date: Tue, 11 Apr 2023 10:57:43 -0700 Subject: [PATCH] bgpd: rfapi memleak fixes Signed-off-by: G. Paul Ziemba Signed-off-by: Donatas Abraitis --- bgpd/rfapi/rfapi.c | 27 +++++++++++++++++++++++++++ bgpd/rfapi/rfapi_rib.c | 19 +++++++++++++++++++ bgpd/rfapi/rfapi_vty.c | 1 + 3 files changed, 47 insertions(+) diff --git a/bgpd/rfapi/rfapi.c b/bgpd/rfapi/rfapi.c index 80d0b3e269..e9ed7224e2 100644 --- a/bgpd/rfapi/rfapi.c +++ b/bgpd/rfapi/rfapi.c @@ -64,6 +64,8 @@ #include #endif /* HAVE_GLIBC_BACKTRACE */ +#define DEBUG_CLEANUP 0 + struct ethaddr rfapi_ethaddr0 = {{0}}; #define DEBUG_RFAPI_STR "RF API debugging/testing command\n" @@ -3690,11 +3692,36 @@ void rfapi_delete(struct bgp *bgp) { extern void rfp_clear_vnc_nve_all(void); /* can't fix correctly yet */ +#if DEBUG_CLEANUP + zlog_debug("%s: bgp %p", __func__, bgp); +#endif + /* * This clears queries and registered routes, and closes nves */ if (bgp->rfapi) rfp_clear_vnc_nve_all(); + + /* + * close any remaining descriptors + */ + struct rfapi *h = bgp->rfapi; + + if (h && h->descriptors.count) { + struct listnode *node, *nnode; + struct rfapi_descriptor *rfd; +#if DEBUG_CLEANUP + zlog_debug("%s: descriptor count %u", __func__, + h->descriptors.count); +#endif + for (ALL_LIST_ELEMENTS(&h->descriptors, node, nnode, rfd)) { +#if DEBUG_CLEANUP + zlog_debug("%s: closing rfd %p", __func__, rfd); +#endif + (void)rfapi_close(rfd); + } + } + bgp_rfapi_cfg_destroy(bgp, bgp->rfapi_cfg); bgp->rfapi_cfg = NULL; bgp_rfapi_destroy(bgp, bgp->rfapi); diff --git a/bgpd/rfapi/rfapi_rib.c b/bgpd/rfapi/rfapi_rib.c index 50a10c3b1d..a9c0c026ed 100644 --- a/bgpd/rfapi/rfapi_rib.c +++ b/bgpd/rfapi/rfapi_rib.c @@ -53,6 +53,7 @@ #define DEBUG_PENDING_DELETE_ROUTE 0 #define DEBUG_NHL 0 #define DEBUG_RIB_SL_RD 0 +#define DEBUG_CLEANUP 0 /* forward decl */ #if DEBUG_NHL @@ -344,6 +345,11 @@ static void rfapiRibStartTimer(struct rfapi_descriptor *rfd, tcb = XCALLOC(MTYPE_RFAPI_RECENT_DELETE, sizeof(struct rfapi_rib_tcb)); } +#if DEBUG_CLEANUP + zlog_debug("%s: rfd %p, rn %p, ri %p, tcb %p", __func__, rfd, rn, ri, + tcb); +#endif + tcb->rfd = rfd; tcb->ri = ri; tcb->rn = rn; @@ -523,6 +529,16 @@ void rfapiRibClear(struct rfapi_descriptor *rfd) NULL, (void **)&ri)) { + if (ri->timer) { + struct rfapi_rib_tcb + *tcb; + + tcb = THREAD_ARG( + ri->timer); + THREAD_OFF(ri->timer); + XFREE(MTYPE_RFAPI_RECENT_DELETE, + tcb); + } rfapi_info_free(ri); skiplist_delete_first( (struct skiplist *) @@ -572,6 +588,9 @@ void rfapiRibFree(struct rfapi_descriptor *rfd) { afi_t afi; +#if DEBUG_CLEANUP + zlog_debug("%s: rfd %p", __func__, rfd); +#endif /* * NB rfd is typically detached from master list, so is not included diff --git a/bgpd/rfapi/rfapi_vty.c b/bgpd/rfapi/rfapi_vty.c index d04d1ee750..60605658ca 100644 --- a/bgpd/rfapi/rfapi_vty.c +++ b/bgpd/rfapi/rfapi_vty.c @@ -4914,6 +4914,7 @@ static int vnc_clear_vrf(struct vty *vty, struct bgp *bgp, const char *arg_vrf, clear_vnc_prefix(&cda); vty_out(vty, "Cleared %u out of %d prefixes.\n", cda.pfx_count, start_count); + print_cleared_stats(&cda); /* frees lists in cda */ return CMD_SUCCESS; } -- 2.39.5