diff options
author | sam <sam@FreeBSD.org> | 2003-10-24 00:09:18 +0000 |
---|---|---|
committer | sam <sam@FreeBSD.org> | 2003-10-24 00:09:18 +0000 |
commit | 841ffbf14af9b09c4c8844dc47d53fd486d236f9 (patch) | |
tree | ad88aa3308f024c465ed2ce92d27df4ecc2b9b79 /sys/netinet/ip_mroute.c | |
parent | 090c7c6e677e0af171777fa516e819fea0ebd518 (diff) | |
download | FreeBSD-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.c | 56 |
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; |