Index: netinet/ip_fw.h =================================================================== --- netinet/ip_fw.h (revision 196077) +++ netinet/ip_fw.h (working copy) @@ -645,8 +645,10 @@ int ipfw_chk(struct ip_fw_args *); -int ipfw_init(void); -void ipfw_destroy(void); +int ipfw_hook(void); +int ipfw6_hook(void); +int ipfw_unhook(void); +int ipfw6_unhook(void); #ifdef NOTYET void ipfw_nat_destroy(void); #endif Index: netinet/ipfw/ip_fw_pfil.c =================================================================== --- netinet/ipfw/ip_fw_pfil.c (revision 196077) +++ netinet/ipfw/ip_fw_pfil.c (working copy) @@ -48,11 +48,16 @@ #include #include #include +#ifdef VIMAGE +#include +#include +#endif #include #include #include #include +#include #include #include @@ -441,7 +446,7 @@ return 1; } -static int +int ipfw_hook(void) { struct pfil_head *pfh_inet; @@ -458,7 +463,7 @@ return 0; } -static int +int ipfw_unhook(void) { struct pfil_head *pfh_inet; @@ -476,7 +481,7 @@ } #ifdef INET6 -static int +int ipfw6_hook(void) { struct pfil_head *pfh_inet6; @@ -493,7 +498,7 @@ return 0; } -static int +int ipfw6_unhook(void) { struct pfil_head *pfh_inet6; @@ -517,6 +522,10 @@ int enable = *(int *)arg1; int error; +#if defined(VIMAGE) + if (TD_TO_VNET(curthread) != vnet0) + return (EPERM); +#endif error = sysctl_handle_int(oidp, &enable, 0, req); if (error) return (error); @@ -549,50 +558,3 @@ return (0); } -static int -ipfw_modevent(module_t mod, int type, void *unused) -{ - int err = 0; - - switch (type) { - case MOD_LOAD: - if ((err = ipfw_init()) != 0) { - printf("ipfw_init() error\n"); - break; - } - if ((err = ipfw_hook()) != 0) { - printf("ipfw_hook() error\n"); - break; - } -#ifdef INET6 - if ((err = ipfw6_hook()) != 0) { - printf("ipfw_hook() error\n"); - break; - } -#endif - break; - - case MOD_UNLOAD: - if ((err = ipfw_unhook()) > 0) - break; -#ifdef INET6 - if ((err = ipfw6_unhook()) > 0) - break; -#endif - ipfw_destroy(); - break; - - default: - return EOPNOTSUPP; - break; - } - return err; -} - -static moduledata_t ipfwmod = { - "ipfw", - ipfw_modevent, - 0 -}; -DECLARE_MODULE(ipfw, ipfwmod, SI_SUB_PROTO_IFATTACHDOMAIN, SI_ORDER_ANY - 256); -MODULE_VERSION(ipfw, 2); Index: netinet/ipfw/ip_fw2.c =================================================================== --- netinet/ipfw/ip_fw2.c (revision 196077) +++ netinet/ipfw/ip_fw2.c (working copy) @@ -4581,10 +4581,13 @@ + /**************** * Stuff that must be initialised only on boot or module load */ -int + +/* init on boot or module load */ +static int ipfw_init(void) { int error = 0; @@ -4636,17 +4639,31 @@ V_verbose_limit); /* + * hook us up to pfil + */ + if ((error = ipfw_hook()) != 0) { + printf("ipfw_hook() error\n"); + return (error); + } +#ifdef INET6 + if ((error = ipfw6_hook()) != 0) { + printf("ipfw_hook() error\n"); + return (error); + } +#endif + /* * Other things that are only done the first time. * (now that we a re cuaranteed of success). */ ip_fw_ctl_ptr = ipfw_ctl; ip_fw_chk_ptr = ipfw_chk; + return (error); } /**************** - * Stuff that must be initialised for every instance - * (including the forst of course). + * Stuff that must be initialized for every instance + * (including the first of course). */ static int vnet_ipfw_init(const void *unused) @@ -4732,9 +4749,15 @@ /********************** * Called for the removal of the last instance only on module unload. */ -void +static void ipfw_destroy(void) { + + /* XXX the unhooks can return errors, what if they do? */ + ipfw_unhook(); +#ifdef INET6 + ipfw6_unhook(); +#endif ip_fw_chk_ptr = NULL; ip_fw_ctl_ptr = NULL; uma_zdestroy(ipfw_dyn_rule_zone); @@ -4766,10 +4789,57 @@ return 0; } -VNET_SYSINIT(vnet_ipfw_init, SI_SUB_PROTO_IFATTACHDOMAIN, SI_ORDER_ANY - 255, +static int +ipfw_modevent(module_t mod, int type, void *unused) +{ + int err = 0; + + switch (type) { + case MOD_LOAD: + break; + + case MOD_UNLOAD: + break; + + case MOD_QUIESCE: + ip_fw_chk_ptr = NULL; + ip_fw_ctl_ptr = NULL; + /* + * XXX A 1 mSec sleep here would be a good idea + * to let other processors exith ipfw. + */ + break; + + default: + err = EOPNOTSUPP; + break; + } + return err; +} + +static moduledata_t ipfwmod = { + "ipfw", + ipfw_modevent, + 0 +}; + +/* define startup order. */ +#define IPFW_SYSINIT_ORDER SI_SUB_PROTO_IFATTACHDOMAIN +#define IPFW_MODEVENT_ORDER (SI_ORDER_ANY - 255) +#define IPFW_MODULE_ORDER (IPFW_MODEVENT_ORDER + 1) +#define IPFW_VNET_ORDER (IPFW_MODULE_ORDER + 1 ) + +DECLARE_MODULE(ipfw, ipfwmod, IPFW_SYSINIT_ORDER, IPFW_MODEVENT_ORDER); +MODULE_VERSION(ipfw, 2); + +SYSINIT(ipfw_init, IPFW_SYSINIT_ORDER, IPFW_MODULE_ORDER, + ipfw_init, NULL); +SYSUNINIT(ipfw_destroy, IPFW_SYSINIT_ORDER, IPFW_MODULE_ORDER, + ipfw_destroy, NULL); + +VNET_SYSINIT(vnet_ipfw_init, IPFW_SYSINIT_ORDER, IPFW_VNET_ORDER, vnet_ipfw_init, NULL); - -VNET_SYSUNINIT(vnet_ipfw_uninit, SI_SUB_PROTO_IFATTACHDOMAIN, SI_ORDER_ANY - 255, +VNET_SYSUNINIT(vnet_ipfw_uninit, IPFW_SYSINIT_ORDER, IPFW_VNET_ORDER, vnet_ipfw_uninit, NULL);