summaryrefslogtreecommitdiffstats
path: root/sys/netinet/ip_mroute.c
diff options
context:
space:
mode:
authorsam <sam@FreeBSD.org>2003-12-20 18:32:48 +0000
committersam <sam@FreeBSD.org>2003-12-20 18:32:48 +0000
commit2a76f369023e788a7c5ccb1d06a260ac3cb0c6f1 (patch)
tree1f696b9029d105e6f415d5cbcedfc0039836d49d /sys/netinet/ip_mroute.c
parent3ff50058b8f1c4e96bc4e8483146029f3f583331 (diff)
downloadFreeBSD-src-2a76f369023e788a7c5ccb1d06a260ac3cb0c6f1.zip
FreeBSD-src-2a76f369023e788a7c5ccb1d06a260ac3cb0c6f1.tar.gz
o move mutex init/destroy logic to the module load/unload hooks;
otherwise they are initialized twice when the code is statically configured in the kernel because the module load method gets invoked before the user application calls ip_mrouter_init o add a mutex to synchronize the module init/done operations; this sort of was done using the value of ip_mroute but X_ip_mrouter_done sets it to NULL very early on which can lead to a race against ip_mrouter_init--using the additional mutex means this is safe now o don't call ip_mrouter_reset from ip_mrouter_init; this now happens once at module load and X_ip_mrouter_done does the appropriate cleanup work to insure the data structures are in a consistent state so that a subsequent init operation inherits good state Reviewed by: juli
Diffstat (limited to 'sys/netinet/ip_mroute.c')
-rw-r--r--sys/netinet/ip_mroute.c38
1 files changed, 27 insertions, 11 deletions
diff --git a/sys/netinet/ip_mroute.c b/sys/netinet/ip_mroute.c
index 447cc27..83f4aa3 100644
--- a/sys/netinet/ip_mroute.c
+++ b/sys/netinet/ip_mroute.c
@@ -588,8 +588,6 @@ static void
ip_mrouter_reset(void)
{
bzero((caddr_t)mfctable, sizeof(mfctable));
- MFC_LOCK_INIT();
- VIF_LOCK_INIT();
bzero((caddr_t)nexpire, sizeof(nexpire));
pim_assert = 0;
@@ -605,6 +603,8 @@ ip_mrouter_reset(void)
callout_init(&tbf_reprocess_ch, CALLOUT_MPSAFE);
}
+static struct mtx mrouter_mtx; /* used to synch init/done work */
+
/*
* Enable multicast routing
*/
@@ -621,10 +621,12 @@ ip_mrouter_init(struct socket *so, int version)
if (version != 1)
return ENOPROTOOPT;
- if (ip_mrouter != NULL)
- return EADDRINUSE;
+ mtx_lock(&mrouter_mtx);
- ip_mrouter_reset();
+ if (ip_mrouter != NULL) {
+ mtx_unlock(&mrouter_mtx);
+ return EADDRINUSE;
+ }
callout_reset(&expire_upcalls_ch, EXPIRE_TIMEOUT, expire_upcalls, NULL);
@@ -634,6 +636,8 @@ ip_mrouter_init(struct socket *so, int version)
ip_mrouter = so;
+ mtx_unlock(&mrouter_mtx);
+
if (mrtdebug)
log(LOG_DEBUG, "ip_mrouter_init\n");
@@ -653,6 +657,13 @@ X_ip_mrouter_done(void)
struct mfc *rt;
struct rtdetq *rte;
+ mtx_lock(&mrouter_mtx);
+
+ if (ip_mrouter == NULL) {
+ mtx_unlock(&mrouter_mtx);
+ return EINVAL;
+ }
+
/*
* Detach/disable hooks to the reset of the system.
*/
@@ -690,7 +701,7 @@ X_ip_mrouter_done(void)
bzero((caddr_t)viftable, sizeof(viftable));
numvifs = 0;
pim_assert = 0;
- VIF_LOCK_DESTROY();
+ VIF_UNLOCK();
/*
* Free all multicast forwarding cache entries.
@@ -717,9 +728,10 @@ X_ip_mrouter_done(void)
}
}
bzero((caddr_t)mfctable, sizeof(mfctable));
+ bzero((caddr_t)nexpire, sizeof(nexpire));
bw_upcalls_n = 0;
bzero(bw_meter_timers, sizeof(bw_meter_timers));
- MFC_LOCK_DESTROY();
+ MFC_UNLOCK();
/*
* Reset de-encapsulation cache
@@ -730,6 +742,8 @@ X_ip_mrouter_done(void)
reg_vif_num = VIFI_INVALID;
#endif
+ mtx_unlock(&mrouter_mtx);
+
if (mrtdebug)
log(LOG_DEBUG, "ip_mrouter_done\n");
@@ -3358,13 +3372,12 @@ pim_input_to_daemon:
static int
ip_mroute_modevent(module_t mod, int type, void *unused)
{
- int s;
-
switch (type) {
case MOD_LOAD:
- s = splnet();
+ mtx_init(&mrouter_mtx, "mrouter initialization", NULL, MTX_DEF);
+ MFC_LOCK_INIT();
+ VIF_LOCK_INIT();
ip_mrouter_reset();
- /* XXX synchronize setup */
ip_mcast_src = X_ip_mcast_src;
ip_mforward = X_ip_mforward;
ip_mrouter_done = X_ip_mrouter_done;
@@ -3400,6 +3413,9 @@ ip_mroute_modevent(module_t mod, int type, void *unused)
legal_vif_num = NULL;
mrt_ioctl = NULL;
rsvp_input_p = NULL;
+ VIF_LOCK_DESTROY();
+ MFC_LOCK_DESTROY();
+ mtx_destroy(&mrouter_mtx);
break;
}
return 0;
OpenPOWER on IntegriCloud