git: 790817f5a7a6 - main - route/fib_algo: Free leaked radix_masks in radix_lockless

From: Pouria Mousavizadeh Tehrani <pouria_at_FreeBSD.org>
Date: Sun, 23 Aug 2026 07:38:54 UTC
The branch main has been updated by pouria:

URL: https://cgit.FreeBSD.org/src/commit/?id=790817f5a7a640c9ceb5c2ad99135f1a69aeb77d

commit 790817f5a7a640c9ceb5c2ad99135f1a69aeb77d
Author:     Pouria Mousavizadeh Tehrani <pouria@FreeBSD.org>
AuthorDate: 2026-08-22 20:37:58 +0000
Commit:     Pouria Mousavizadeh Tehrani <pouria@FreeBSD.org>
CommitDate: 2026-08-23 07:35:52 +0000

    route/fib_algo: Free leaked radix_masks in radix_lockless
    
    radix_lockless algorithm creates its own radix tree and
    allocates its own radix_masks by directly calling rnh_addaddr().
    However, during destruction, it only frees the radix_tree without
    freeing its allocated radix_masks.
    Fix the leak by calling rn_delete() during radix_destroy().
    
    PR:             297339
    Reviewed by:    melifaro
    MFC after:      2 weeks
    Differential Revision: https://reviews.freebsd.org/D59112
---
 sys/netinet/in_fib_algo.c   | 13 ++++++++++++-
 sys/netinet6/in6_fib_algo.c | 15 +++++++++++++--
 2 files changed, 25 insertions(+), 3 deletions(-)

diff --git a/sys/netinet/in_fib_algo.c b/sys/netinet/in_fib_algo.c
index ab2743034c48..2dcc3261946f 100644
--- a/sys/netinet/in_fib_algo.c
+++ b/sys/netinet/in_fib_algo.c
@@ -582,13 +582,24 @@ lradix4_init(uint32_t fibnum, struct fib_data *fd, void *_old_data, void **_data
 	return (FLM_SUCCESS);
 }
 
+static int
+lradix4_free_route(struct radix_node *rn, void *arg)
+{
+	struct radix_head *head = arg;
+
+	rn_delete(rn->rn_key, rn->rn_mask, head);
+	return (0);
+}
+
 static void
 lradix4_destroy(void *_data)
 {
 	struct lradix4_data *lr = (struct lradix4_data *)_data;
 
-	if (lr->rnh != NULL)
+	if (lr->rnh != NULL) {
+		rn_walktree(&lr->rnh->rh, lradix4_free_route, &lr->rnh->rh);
 		rn_detachhead((void **)&lr->rnh);
+	}
 	if (lr->mem != NULL)
 		free(lr->mem, M_RTABLE);
 	free(lr, M_RTABLE);
diff --git a/sys/netinet6/in6_fib_algo.c b/sys/netinet6/in6_fib_algo.c
index 47c1f7d20786..281d53ca9cb3 100644
--- a/sys/netinet6/in6_fib_algo.c
+++ b/sys/netinet6/in6_fib_algo.c
@@ -129,7 +129,7 @@ lradix6_init(uint32_t fibnum, struct fib_data *fd, void *_old_data, void **_data
 	struct rib_rtable_info rinfo;
 	uint32_t count;
 	void *mem;
- 
+
 	lr = malloc(sizeof(struct lradix6_data), M_RTABLE, M_NOWAIT | M_ZERO);
 	if (lr == NULL || !rn_inithead((void **)&lr->rnh, OFF_LEN_INET6))
 		return (FLM_REBUILD);
@@ -150,13 +150,24 @@ lradix6_init(uint32_t fibnum, struct fib_data *fd, void *_old_data, void **_data
 	return (FLM_SUCCESS);
 }
 
+static int
+lradix6_free_route(struct radix_node *rn, void *arg)
+{
+	struct radix_head *head = arg;
+
+	rn_delete(rn->rn_key, rn->rn_mask, head);
+	return (0);
+}
+
 static void
 lradix6_destroy(void *_data)
 {
 	struct lradix6_data *lr = (struct lradix6_data *)_data;
 
-	if (lr->rnh != NULL)
+	if (lr->rnh != NULL) {
+		rn_walktree(&lr->rnh->rh, lradix6_free_route, &lr->rnh->rh);
 		rn_detachhead((void **)&lr->rnh);
+	}
 	if (lr->mem != NULL)
 		free(lr->mem, M_RTABLE);
 	free(lr, M_RTABLE);