git: 47c00a983592 - stable/13 - Plug nexthop group refcount leak. In case with batch route delete via rib_walk_del(), when some paths from the multipath route gets deleted, old multipath group were not freed.

Alexander V. Chernikov melifaro at FreeBSD.org
Thu Mar 25 20:26:32 UTC 2021


The branch stable/13 has been updated by melifaro:

URL: https://cgit.FreeBSD.org/src/commit/?id=47c00a9835926e96e562c67fa28e4432e99d9c56

commit 47c00a9835926e96e562c67fa28e4432e99d9c56
Author:     Alexander V. Chernikov <melifaro at FreeBSD.org>
AuthorDate: 2021-03-24 23:51:45 +0000
Commit:     Alexander V. Chernikov <melifaro at FreeBSD.org>
CommitDate: 2021-03-25 20:22:58 +0000

    Plug nexthop group refcount leak.
    In case with batch route delete via rib_walk_del(), when
     some paths from the multipath route gets deleted, old
     multipath group were not freed.
    
    PR:    254496
    Reported by:   Zhenlei Huang <zlei.huang at gmail.com>
    
    (cherry picked from commit 66f138563becf12d5c21924f816d2a45c3a1ed7a)
---
 sys/net/route/route_ctl.c | 18 ++++++++++++++----
 1 file changed, 14 insertions(+), 4 deletions(-)

diff --git a/sys/net/route/route_ctl.c b/sys/net/route/route_ctl.c
index 58b89c28f945..af3853041ac6 100644
--- a/sys/net/route/route_ctl.c
+++ b/sys/net/route/route_ctl.c
@@ -130,6 +130,7 @@ vnet_rtzone_destroy()
 static void
 destroy_rtentry(struct rtentry *rt)
 {
+#ifdef VIMAGE
 	struct nhop_object *nh = rt->rt_nhop;
 
 	/*
@@ -146,9 +147,10 @@ destroy_rtentry(struct rtentry *rt)
 	}
 #endif
 	CURVNET_SET(nhop_get_vnet(nh));
+#endif
 
 	/* Unreference nexthop */
-	nhop_free_any(nh);
+	nhop_free_any(rt->rt_nhop);
 
 	uma_zfree(V_rtzone, rt);
 
@@ -1252,7 +1254,6 @@ rt_checkdelroute(struct radix_node *rn, void *arg)
 	struct rt_delinfo *di;
 	struct rt_addrinfo *info;
 	struct rtentry *rt;
-	int error;
 
 	di = (struct rt_delinfo *)arg;
 	rt = (struct rtentry *)rn;
@@ -1261,7 +1262,8 @@ rt_checkdelroute(struct radix_node *rn, void *arg)
 	info->rti_info[RTAX_DST] = rt_key(rt);
 	info->rti_info[RTAX_NETMASK] = rt_mask(rt);
 
-	error = rt_unlinkrte(di->rnh, info, &di->rc);
+	if (rt_unlinkrte(di->rnh, info, &di->rc) != 0)
+		return (0);
 
 	/*
 	 * Add deleted rtentries to the list to GC them
@@ -1270,10 +1272,18 @@ rt_checkdelroute(struct radix_node *rn, void *arg)
 	 * XXX: Delayed notifications not implemented
 	 *  for nexthop updates.
 	 */
-	if ((error == 0) && (di->rc.rc_cmd == RTM_DELETE)) {
+	if (di->rc.rc_cmd == RTM_DELETE) {
 		/* Add to the list and return */
 		rt->rt_chain = di->head;
 		di->head = rt;
+#ifdef ROUTE_MPATH
+	} else {
+		/*
+		 * RTM_CHANGE to a diferent nexthop or nexthop group.
+		 * Free old multipath group.
+		 */
+		nhop_free_any(di->rc.rc_nh_old);
+#endif
 	}
 
 	return (0);


More information about the dev-commits-src-all mailing list