diff options
Diffstat (limited to 'freebsd/sys/netpfil/ipfw/ip_fw_nat.c')
-rw-r--r-- | freebsd/sys/netpfil/ipfw/ip_fw_nat.c | 76 |
1 files changed, 53 insertions, 23 deletions
diff --git a/freebsd/sys/netpfil/ipfw/ip_fw_nat.c b/freebsd/sys/netpfil/ipfw/ip_fw_nat.c index 142c46c5..5d4dcc9f 100644 --- a/freebsd/sys/netpfil/ipfw/ip_fw_nat.c +++ b/freebsd/sys/netpfil/ipfw/ip_fw_nat.c @@ -55,8 +55,7 @@ __FBSDID("$FreeBSD$"); #include <machine/in_cksum.h> /* XXX for in_cksum */ -static VNET_DEFINE(eventhandler_tag, ifaddr_event_tag); -#define V_ifaddr_event_tag VNET(ifaddr_event_tag) +static eventhandler_tag ifaddr_event_tag; static void ifaddr_change(void *arg __unused, struct ifnet *ifp) @@ -65,6 +64,8 @@ ifaddr_change(void *arg __unused, struct ifnet *ifp) struct ifaddr *ifa; struct ip_fw_chain *chain; + KASSERT(curvnet == ifp->if_vnet, + ("curvnet(%p) differs from iface vnet(%p)", curvnet, ifp->if_vnet)); chain = &V_layer3_chain; IPFW_WLOCK(chain); /* Check every nat entry... */ @@ -443,7 +444,7 @@ ipfw_nat_cfg(struct sockopt *sopt) ptr->ip = cfg->ip; ptr->redir_cnt = cfg->redir_cnt; ptr->mode = cfg->mode; - LibAliasSetMode(ptr->lib, cfg->mode, cfg->mode); + LibAliasSetMode(ptr->lib, cfg->mode, ~0); LibAliasSetAddress(ptr->lib, ptr->ip); memcpy(ptr->if_name, cfg->if_name, IF_NAMESIZE); @@ -592,11 +593,38 @@ ipfw_nat_get_log(struct sockopt *sopt) return(0); } +static int +vnet_ipfw_nat_init(const void *arg __unused) +{ + + V_ipfw_nat_ready = 1; + return (0); +} + +static int +vnet_ipfw_nat_uninit(const void *arg __unused) +{ + struct cfg_nat *ptr, *ptr_temp; + struct ip_fw_chain *chain; + + chain = &V_layer3_chain; + IPFW_WLOCK(chain); + LIST_FOREACH_SAFE(ptr, &chain->nat, _next, ptr_temp) { + LIST_REMOVE(ptr, _next); + del_redir_spool_cfg(ptr, &ptr->redir_chain); + LibAliasUninit(ptr->lib); + free(ptr, M_IPFW); + } + flush_nat_ptrs(chain, -1 /* flush all */); + V_ipfw_nat_ready = 0; + IPFW_WUNLOCK(chain); + return (0); +} + static void ipfw_nat_init(void) { - IPFW_WLOCK(&V_layer3_chain); /* init ipfw hooks */ ipfw_nat_ptr = ipfw_nat; lookup_nat_ptr = lookup_nat; @@ -604,28 +632,16 @@ ipfw_nat_init(void) ipfw_nat_del_ptr = ipfw_nat_del; ipfw_nat_get_cfg_ptr = ipfw_nat_get_cfg; ipfw_nat_get_log_ptr = ipfw_nat_get_log; - IPFW_WUNLOCK(&V_layer3_chain); - V_ifaddr_event_tag = EVENTHANDLER_REGISTER( - ifaddr_event, ifaddr_change, + + ifaddr_event_tag = EVENTHANDLER_REGISTER(ifaddr_event, ifaddr_change, NULL, EVENTHANDLER_PRI_ANY); } static void ipfw_nat_destroy(void) { - struct cfg_nat *ptr, *ptr_temp; - struct ip_fw_chain *chain; - chain = &V_layer3_chain; - IPFW_WLOCK(chain); - LIST_FOREACH_SAFE(ptr, &chain->nat, _next, ptr_temp) { - LIST_REMOVE(ptr, _next); - del_redir_spool_cfg(ptr, &ptr->redir_chain); - LibAliasUninit(ptr->lib); - free(ptr, M_IPFW); - } - EVENTHANDLER_DEREGISTER(ifaddr_event, V_ifaddr_event_tag); - flush_nat_ptrs(chain, -1 /* flush all */); + EVENTHANDLER_DEREGISTER(ifaddr_event, ifaddr_event_tag); /* deregister ipfw_nat */ ipfw_nat_ptr = NULL; lookup_nat_ptr = NULL; @@ -633,7 +649,6 @@ ipfw_nat_destroy(void) ipfw_nat_del_ptr = NULL; ipfw_nat_get_cfg_ptr = NULL; ipfw_nat_get_log_ptr = NULL; - IPFW_WUNLOCK(chain); } static int @@ -643,11 +658,9 @@ ipfw_nat_modevent(module_t mod, int type, void *unused) switch (type) { case MOD_LOAD: - ipfw_nat_init(); break; case MOD_UNLOAD: - ipfw_nat_destroy(); break; default: @@ -663,8 +676,25 @@ static moduledata_t ipfw_nat_mod = { 0 }; -DECLARE_MODULE(ipfw_nat, ipfw_nat_mod, SI_SUB_PROTO_IFATTACHDOMAIN, SI_ORDER_ANY); +/* Define startup order. */ +#define IPFW_NAT_SI_SUB_FIREWALL SI_SUB_PROTO_IFATTACHDOMAIN +#define IPFW_NAT_MODEVENT_ORDER (SI_ORDER_ANY - 128) +#define IPFW_NAT_MODULE_ORDER (IPFW_NAT_MODEVENT_ORDER + 1) +#define IPFW_NAT_VNET_ORDER (IPFW_NAT_MODEVENT_ORDER + 2) + +DECLARE_MODULE(ipfw_nat, ipfw_nat_mod, IPFW_NAT_SI_SUB_FIREWALL, SI_ORDER_ANY); MODULE_DEPEND(ipfw_nat, libalias, 1, 1, 1); MODULE_DEPEND(ipfw_nat, ipfw, 2, 2, 2); MODULE_VERSION(ipfw_nat, 1); + +SYSINIT(ipfw_nat_init, IPFW_NAT_SI_SUB_FIREWALL, IPFW_NAT_MODULE_ORDER, + ipfw_nat_init, NULL); +VNET_SYSINIT(vnet_ipfw_nat_init, IPFW_NAT_SI_SUB_FIREWALL, IPFW_NAT_VNET_ORDER, + vnet_ipfw_nat_init, NULL); + +SYSUNINIT(ipfw_nat_destroy, IPFW_NAT_SI_SUB_FIREWALL, IPFW_NAT_MODULE_ORDER, + ipfw_nat_destroy, NULL); +VNET_SYSUNINIT(vnet_ipfw_nat_uninit, IPFW_NAT_SI_SUB_FIREWALL, + IPFW_NAT_VNET_ORDER, vnet_ipfw_nat_uninit, NULL); + /* end of file */ |