Page MenuHomeFreeBSD

D55240.id171702.diff
No OneTemporary

D55240.id171702.diff

diff --git a/sys/netinet/ip_mroute.c b/sys/netinet/ip_mroute.c
--- a/sys/netinet/ip_mroute.c
+++ b/sys/netinet/ip_mroute.c
@@ -189,6 +189,8 @@
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 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 @@
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 @@
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 @@
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_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
--- 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 @@
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)
@@ -1924,11 +1929,36 @@
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);
}
@@ -1955,6 +1985,10 @@
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) {
@@ -1974,7 +2008,10 @@
case MOD_UNLOAD:
if (V_ip6_mrouting_enabled)
- return EINVAL;
+ return (EINVAL);
+
+ EVENTHANDLER_DEREGISTER(rtnumfibs_change,
+ rtnumfibs_change_tag);
if (pim6_encap_cookie) {
ip6_encap_detach(pim6_encap_cookie);
@@ -2005,4 +2042,4 @@
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);

File Metadata

Mime Type
text/plain
Expires
Thu, Apr 16, 3:30 AM (2 h, 37 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
31574998
Default Alt Text
D55240.id171702.diff (5 KB)

Event Timeline