Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 30 Mar 2026 16:15:39 +0000
From:      Mark Johnston <markj@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: 97a4bc9a0da7 - main - ip(6)_mroute: Grow the routing tables when the number of FIBs changes
Message-ID:  <69caa1ab.3adf0.13ae3610@gitrepo.freebsd.org>

index | next in thread | raw e-mail

The branch main has been updated by markj:

URL: https://cgit.FreeBSD.org/src/commit/?id=97a4bc9a0da7cd63c660ce59a9dd7c87efe1f218

commit 97a4bc9a0da7cd63c660ce59a9dd7c87efe1f218
Author:     Mark Johnston <markj@FreeBSD.org>
AuthorDate: 2026-03-30 13:30:38 +0000
Commit:     Mark Johnston <markj@FreeBSD.org>
CommitDate: 2026-03-30 16:08:21 +0000

    ip(6)_mroute: Grow the routing tables when the number of FIBs changes
    
    Use the new rtnumfibs_change event to expand the mfctable array when the
    number of FIBs increases.
    
    MFC after:      2 weeks
    Sponsored by:   Stormshield
    Sponsored by:   Klara, Inc.
    Differential Revision:  https://reviews.freebsd.org/D55240
---
 sys/netinet/ip_mroute.c   | 54 ++++++++++++++++++++++++++++++++++++++---------
 sys/netinet6/ip6_mroute.c | 43 ++++++++++++++++++++++++++++++++++---
 2 files changed, 84 insertions(+), 13 deletions(-)

diff --git a/sys/netinet/ip_mroute.c b/sys/netinet/ip_mroute.c
index 6e5b739f1da8..9ecaa9a669d6 100644
--- a/sys/netinet/ip_mroute.c
+++ b/sys/netinet/ip_mroute.c
@@ -189,6 +189,8 @@ struct mfctable {
 
 VNET_DEFINE_STATIC(struct mfctable *, mfctables);
 #define	V_mfctables		VNET(mfctables)
+VNET_DEFINE_STATIC(uint32_t, nmfctables);
+#define	V_nmfctables		VNET(nmfctables)
 
 VNET_DEFINE_STATIC(u_long, mfchash);
 #define	V_mfchash		VNET(mfchash)
@@ -206,7 +208,8 @@ VNET_DEFINE_STATIC(struct taskqueue *, task_queue);
 VNET_DEFINE_STATIC(struct task, task);
 #define	V_task		VNET(task)
 
-static eventhandler_tag if_detach_event_tag = NULL;
+static eventhandler_tag if_detach_event_tag;
+static eventhandler_tag rtnumfibs_change_tag;
 
 VNET_DEFINE_STATIC(struct callout, expire_upcalls_ch);
 #define	V_expire_upcalls_ch	VNET(expire_upcalls_ch)
@@ -2808,7 +2811,6 @@ out_locked:
 	MRW_RUNLOCK();
 	return (error);
 }
-
 static SYSCTL_NODE(_net_inet_ip, OID_AUTO, mfctable,
     CTLFLAG_RD | CTLFLAG_MPSAFE, sysctl_mfctable,
     "IPv4 Multicast Forwarding Table "
@@ -2838,26 +2840,51 @@ sysctl_viflist(SYSCTL_HANDLER_ARGS)
 	MRW_RUNLOCK();
 	return (error);
 }
-
 SYSCTL_PROC(_net_inet_ip, OID_AUTO, viftable,
     CTLTYPE_OPAQUE | CTLFLAG_VNET | CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, 0,
     sysctl_viflist, "S,vif[MAXVIFS]",
     "IPv4 Multicast Interfaces (struct vif[MAXVIFS], netinet/ip_mroute.h)");
 
 static void
-vnet_mroute_init(const void *unused __unused)
+ip_mroute_rtnumfibs_change(void *arg __unused, uint32_t ntables)
 {
-	V_mfctables = mallocarray(V_rt_numfibs, sizeof(*V_mfctables), M_MRTABLE,
+	struct mfctable *mfctables, *omfctables;
+
+	KASSERT(ntables >= V_nmfctables,
+	    ("%s: ntables %u nmfctables %u", __func__, ntables, V_nmfctables));
+
+	mfctables = mallocarray(ntables, sizeof(*mfctables), M_MRTABLE,
 	    M_WAITOK | M_ZERO);
-	for (int i = 0; i < V_rt_numfibs; i++) {
+	omfctables = V_mfctables;
+
+	for (int i = V_nmfctables; i < ntables; i++) {
 		struct mfctable *mfct;
 
-		mfct = &V_mfctables[i];
+		mfct = &mfctables[i];
 		mfct->nexpire = malloc(mfchashsize, M_MRTABLE,
 		    M_WAITOK | M_ZERO);
 		mfct->register_vif = VIFI_INVALID;
 	}
 
+	MRW_TEARDOWN_WLOCK();
+	MRW_WLOCK();
+	for (int i = 0; i < V_nmfctables; i++)
+		memcpy(&mfctables[i], &omfctables[i], sizeof(*mfctables));
+	atomic_store_rel_ptr((uintptr_t *)&V_mfctables, (uintptr_t)mfctables);
+	MRW_WUNLOCK();
+	MRW_TEARDOWN_WUNLOCK();
+
+	NET_EPOCH_WAIT();
+
+	V_nmfctables = ntables;
+	free(omfctables, M_MRTABLE);
+}
+
+static void
+vnet_mroute_init(const void *unused __unused)
+{
+	ip_mroute_rtnumfibs_change(NULL, V_rt_numfibs);
+
 	callout_init_rw(&V_expire_upcalls_ch, &mrouter_lock, 0);
 	callout_init_rw(&V_bw_upcalls_ch, &mrouter_lock, 0);
 
@@ -2895,8 +2922,12 @@ ip_mroute_modevent(module_t mod, int type, void *unused)
 		MRW_TEARDOWN_LOCK_INIT();
 		MRW_LOCK_INIT();
 
-		if_detach_event_tag = EVENTHANDLER_REGISTER(ifnet_departure_event,
-		    if_detached_event, NULL, EVENTHANDLER_PRI_ANY);
+		if_detach_event_tag = EVENTHANDLER_REGISTER(
+		    ifnet_departure_event, if_detached_event, NULL,
+		    EVENTHANDLER_PRI_ANY);
+		rtnumfibs_change_tag = EVENTHANDLER_REGISTER(
+		    rtnumfibs_change, ip_mroute_rtnumfibs_change,
+		    NULL, EVENTHANDLER_PRI_ANY);
 
 		if (!powerof2(mfchashsize)) {
 			printf("WARNING: %s not a power of 2; using default\n",
@@ -2937,7 +2968,10 @@ ip_mroute_modevent(module_t mod, int type, void *unused)
 		ip_mrouter_unloading = 1;
 		MRW_WUNLOCK();
 
-		EVENTHANDLER_DEREGISTER(ifnet_departure_event, if_detach_event_tag);
+		EVENTHANDLER_DEREGISTER(rtnumfibs_change,
+		    rtnumfibs_change_tag);
+		EVENTHANDLER_DEREGISTER(ifnet_departure_event,
+		    if_detach_event_tag);
 
 		if (pim_encap_cookie) {
 			ip_encap_detach(pim_encap_cookie);
diff --git a/sys/netinet6/ip6_mroute.c b/sys/netinet6/ip6_mroute.c
index 912bbfda2486..fff68a7ff47d 100644
--- a/sys/netinet6/ip6_mroute.c
+++ b/sys/netinet6/ip6_mroute.c
@@ -83,6 +83,7 @@
 #include <sys/param.h>
 #include <sys/callout.h>
 #include <sys/errno.h>
+#include <sys/eventhandler.h>
 #include <sys/kernel.h>
 #include <sys/lock.h>
 #include <sys/malloc.h>
@@ -207,6 +208,10 @@ struct mf6ctable {
 
 VNET_DEFINE_STATIC(struct mf6ctable *, mfctables);
 #define	V_mfctables		VNET(mfctables)
+VNET_DEFINE_STATIC(uint32_t, nmfctables);
+#define	V_nmfctables		VNET(nmfctables)
+
+static eventhandler_tag rtnumfibs_change_tag;
 
 static int
 sysctl_mfctable(SYSCTL_HANDLER_ARGS)
@@ -1926,11 +1931,36 @@ pim6_input(struct mbuf *m, int off, int proto, void *arg __unused)
 	return (rip6_input(&m, &off, proto));
 }
 
+static void
+ip6_mroute_rtnumfibs_change(void *arg __unused, uint32_t ntables)
+{
+	struct mf6ctable *mfctables, *omfctables;
+
+	KASSERT(ntables >= V_nmfctables,
+	    ("%s: ntables %u nmfctables %u", __func__, ntables, V_nmfctables));
+
+	mfctables = mallocarray(ntables, sizeof(*mfctables), M_MRTABLE6,
+	    M_WAITOK | M_ZERO);
+	omfctables = V_mfctables;
+
+	MROUTER6_LOCK();
+	MFC6_LOCK();
+	for (int i = 0; i < V_nmfctables; i++)
+		memcpy(&mfctables[i], &omfctables[i], sizeof(*mfctables));
+	atomic_store_rel_ptr((uintptr_t *)&V_mfctables, (uintptr_t)mfctables);
+	MFC6_UNLOCK();
+	MROUTER6_UNLOCK();
+
+	NET_EPOCH_WAIT();
+
+	V_nmfctables = ntables;
+	free(omfctables, M_MRTABLE6);
+}
+
 static void
 vnet_mroute_init(const void *unused __unused)
 {
-	V_mfctables = mallocarray(V_rt_numfibs, sizeof(*V_mfctables),
-	    M_MRTABLE6, M_WAITOK | M_ZERO);
+	ip6_mroute_rtnumfibs_change(NULL, V_rt_numfibs);
 
 	callout_init_mtx(&V_expire_upcalls_ch, MFC6_LOCKPTR(), 0);
 }
@@ -1957,6 +1987,10 @@ ip6_mroute_modevent(module_t mod, int type, void *unused)
 		MFC6_LOCK_INIT();
 		MIF6_LOCK_INIT();
 
+		rtnumfibs_change_tag = EVENTHANDLER_REGISTER(
+		    rtnumfibs_change, ip6_mroute_rtnumfibs_change,
+		    NULL, EVENTHANDLER_PRI_ANY);
+
 		pim6_encap_cookie = ip6_encap_attach(&ipv6_encap_cfg,
 		    NULL, M_WAITOK);
 		if (pim6_encap_cookie == NULL) {
@@ -1978,6 +2012,9 @@ ip6_mroute_modevent(module_t mod, int type, void *unused)
 		if (V_ip6_mrouting_enabled)
 			return (EBUSY);
 
+		EVENTHANDLER_DEREGISTER(rtnumfibs_change,
+		    rtnumfibs_change_tag);
+
 		if (pim6_encap_cookie) {
 			ip6_encap_detach(pim6_encap_cookie);
 			pim6_encap_cookie = NULL;
@@ -2007,4 +2044,4 @@ static moduledata_t ip6_mroutemod = {
 	0
 };
 
-DECLARE_MODULE(ip6_mroute, ip6_mroutemod, SI_SUB_PROTO_MC, SI_ORDER_ANY);
+DECLARE_MODULE(ip6_mroute, ip6_mroutemod, SI_SUB_PROTO_MC, SI_ORDER_MIDDLE);


home | help

Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?69caa1ab.3adf0.13ae3610>