summaryrefslogtreecommitdiffstats
path: root/sys/netinet/ip_mroute.c
diff options
context:
space:
mode:
authorsam <sam@FreeBSD.org>2003-10-24 00:09:18 +0000
committersam <sam@FreeBSD.org>2003-10-24 00:09:18 +0000
commit841ffbf14af9b09c4c8844dc47d53fd486d236f9 (patch)
treead88aa3308f024c465ed2ce92d27df4ecc2b9b79 /sys/netinet/ip_mroute.c
parent090c7c6e677e0af171777fa516e819fea0ebd518 (diff)
downloadFreeBSD-src-841ffbf14af9b09c4c8844dc47d53fd486d236f9.zip
FreeBSD-src-841ffbf14af9b09c4c8844dc47d53fd486d236f9.tar.gz
o restructure initialization code so data structures are setup
when loaded as a module o cleanup data structures on module unload when no application has been started (i.e. kldload, kldunload w/o mrtd) o remove extraneous unlocks immediately prior to destroying them Supported by: FreeBSD Foundation
Diffstat (limited to 'sys/netinet/ip_mroute.c')
-rw-r--r--sys/netinet/ip_mroute.c56
1 files changed, 34 insertions, 22 deletions
diff --git a/sys/netinet/ip_mroute.c b/sys/netinet/ip_mroute.c
index 6eb20d5..354aafc 100644
--- a/sys/netinet/ip_mroute.c
+++ b/sys/netinet/ip_mroute.c
@@ -584,6 +584,27 @@ get_vif_cnt(struct sioc_vif_req *req)
return 0;
}
+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;
+ mrt_api_config = 0;
+
+ callout_init(&expire_upcalls_ch, CALLOUT_MPSAFE);
+
+ bw_upcalls_n = 0;
+ bzero((caddr_t)bw_meter_timers, sizeof(bw_meter_timers));
+ callout_init(&bw_upcalls_ch, CALLOUT_MPSAFE);
+ callout_init(&bw_meter_ch, CALLOUT_MPSAFE);
+
+ callout_init(&tbf_reprocess_ch, CALLOUT_MPSAFE);
+}
+
/*
* Enable multicast routing
*/
@@ -603,29 +624,15 @@ ip_mrouter_init(struct socket *so, int version)
if (ip_mrouter != NULL)
return EADDRINUSE;
- ip_mrouter = so;
-
- bzero((caddr_t)mfctable, sizeof(mfctable));
- MFC_LOCK_INIT();
- VIF_LOCK_INIT();
- bzero((caddr_t)nexpire, sizeof(nexpire));
+ ip_mrouter_reset();
- pim_assert = 0;
-
- callout_init(&expire_upcalls_ch, CALLOUT_MPSAFE);
callout_reset(&expire_upcalls_ch, EXPIRE_TIMEOUT, expire_upcalls, NULL);
- bw_upcalls_n = 0;
- bzero((caddr_t)bw_meter_timers, sizeof(bw_meter_timers));
- callout_init(&bw_upcalls_ch, CALLOUT_MPSAFE);
callout_reset(&bw_upcalls_ch, BW_UPCALLS_PERIOD,
expire_bw_upcalls_send, NULL);
- callout_init(&bw_meter_ch, CALLOUT_MPSAFE);
callout_reset(&bw_meter_ch, BW_METER_PERIOD, expire_bw_meter_process, NULL);
- callout_init(&tbf_reprocess_ch, CALLOUT_MPSAFE);
-
- mrt_api_config = 0;
+ ip_mrouter = so;
if (mrtdebug)
log(LOG_DEBUG, "ip_mrouter_init\n");
@@ -679,7 +686,6 @@ X_ip_mrouter_done(void)
bzero((caddr_t)viftable, sizeof(viftable));
numvifs = 0;
pim_assert = 0;
- VIF_UNLOCK();
VIF_LOCK_DESTROY();
/*
@@ -709,7 +715,6 @@ X_ip_mrouter_done(void)
bzero((caddr_t)mfctable, sizeof(mfctable));
bw_upcalls_n = 0;
bzero(bw_meter_timers, sizeof(bw_meter_timers));
- MFC_UNLOCK();
MFC_LOCK_DESTROY();
/*
@@ -3353,7 +3358,8 @@ ip_mroute_modevent(module_t mod, int type, void *unused)
switch (type) {
case MOD_LOAD:
s = splnet();
- /* XXX Protect against multiple loading */
+ 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;
@@ -3364,14 +3370,21 @@ ip_mroute_modevent(module_t mod, int type, void *unused)
legal_vif_num = X_legal_vif_num;
mrt_ioctl = X_mrt_ioctl;
rsvp_input_p = X_rsvp_input;
- splx(s);
break;
case MOD_UNLOAD:
+ /*
+ * Typically module unload happens after the user-level
+ * process has shutdown the kernel services (the check
+ * below insures someone can't just yank the module out
+ * from under a running process). But if the module is
+ * just loaded and then unloaded w/o starting up a user
+ * process we still need to cleanup.
+ */
if (ip_mrouter)
return EINVAL;
- s = splnet();
+ X_ip_mrouter_done();
ip_mcast_src = NULL;
ip_mforward = NULL;
ip_mrouter_done = NULL;
@@ -3382,7 +3395,6 @@ ip_mroute_modevent(module_t mod, int type, void *unused)
legal_vif_num = NULL;
mrt_ioctl = NULL;
rsvp_input_p = NULL;
- splx(s);
break;
}
return 0;
OpenPOWER on IntegriCloud