summaryrefslogtreecommitdiffstats
path: root/sys/netpfil/ipfw/ip_fw_nat.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/netpfil/ipfw/ip_fw_nat.c')
-rw-r--r--sys/netpfil/ipfw/ip_fw_nat.c85
1 files changed, 45 insertions, 40 deletions
diff --git a/sys/netpfil/ipfw/ip_fw_nat.c b/sys/netpfil/ipfw/ip_fw_nat.c
index 0fb4534..627603d 100644
--- a/sys/netpfil/ipfw/ip_fw_nat.c
+++ b/sys/netpfil/ipfw/ip_fw_nat.c
@@ -64,26 +64,33 @@ ifaddr_change(void *arg __unused, struct ifnet *ifp)
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... */
- LIST_FOREACH(ptr, &chain->nat, _next) {
- /* ...using nic 'ifp->if_xname' as dynamic alias address. */
- if (strncmp(ptr->if_name, ifp->if_xname, IF_NAMESIZE) != 0)
+
+ IPFW_CTX_RLOCK();
+ for (int i = 1; i < IP_FW_MAXCTX; i++) {
+ chain = V_ip_fw_contexts.chain[i];
+ if (chain == NULL)
continue;
- if_addr_rlock(ifp);
- TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
- if (ifa->ifa_addr == NULL)
- continue;
- if (ifa->ifa_addr->sa_family != AF_INET)
+ IPFW_WLOCK(chain);
+ /* Check every nat entry... */
+ LIST_FOREACH(ptr, &chain->nat, _next) {
+ /* ...using nic 'ifp->if_xname' as dynamic alias address. */
+ if (strncmp(ptr->if_name, ifp->if_xname, IF_NAMESIZE) != 0)
continue;
- ptr->ip = ((struct sockaddr_in *)
- (ifa->ifa_addr))->sin_addr;
- LibAliasSetAddress(ptr->lib, ptr->ip);
+ if_addr_rlock(ifp);
+ TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
+ if (ifa->ifa_addr == NULL)
+ continue;
+ if (ifa->ifa_addr->sa_family != AF_INET)
+ continue;
+ ptr->ip = ((struct sockaddr_in *)
+ (ifa->ifa_addr))->sin_addr;
+ LibAliasSetAddress(ptr->lib, ptr->ip);
+ }
+ if_addr_runlock(ifp);
}
- if_addr_runlock(ifp);
+ IPFW_WUNLOCK(chain);
}
- IPFW_WUNLOCK(chain);
+ IPFW_CTX_RUNLOCK();
}
/*
@@ -206,18 +213,18 @@ add_redir_spool_cfg(char *buf, struct cfg_nat *ptr)
/*
* ipfw_nat - perform mbuf header translation.
*
- * Note V_layer3_chain has to be locked while calling ipfw_nat() in
+ * Note *chain has to be locked while calling ipfw_nat() in
* 'global' operation mode (t == NULL).
*
*/
static int
-ipfw_nat(struct ip_fw_args *args, struct cfg_nat *t, struct mbuf *m)
+ipfw_nat(struct ip_fw_args *args, struct cfg_nat *t, struct mbuf *m,
+ struct ip_fw_chain *chain)
{
struct mbuf *mcl;
struct ip *ip;
/* XXX - libalias duct tape */
int ldt, retval, found;
- struct ip_fw_chain *chain;
char *c;
ldt = 0;
@@ -276,7 +283,6 @@ ipfw_nat(struct ip_fw_args *args, struct cfg_nat *t, struct mbuf *m)
}
found = 0;
- chain = &V_layer3_chain;
IPFW_RLOCK_ASSERT(chain);
/* Check every nat entry... */
LIST_FOREACH(t, &chain->nat, _next) {
@@ -391,11 +397,10 @@ lookup_nat(struct nat_list *l, int nat_id)
}
static int
-ipfw_nat_cfg(struct sockopt *sopt)
+ipfw_nat_cfg(struct sockopt *sopt, struct ip_fw_chain *chain)
{
struct cfg_nat *cfg, *ptr;
char *buf;
- struct ip_fw_chain *chain = &V_layer3_chain;
size_t len;
int gencnt, error = 0;
@@ -468,10 +473,9 @@ out:
}
static int
-ipfw_nat_del(struct sockopt *sopt)
+ipfw_nat_del(struct sockopt *sopt, struct ip_fw_chain *chain)
{
struct cfg_nat *ptr;
- struct ip_fw_chain *chain = &V_layer3_chain;
int i;
sooptcopyin(sopt, &i, sizeof i, sizeof i);
@@ -492,9 +496,8 @@ ipfw_nat_del(struct sockopt *sopt)
}
static int
-ipfw_nat_get_cfg(struct sockopt *sopt)
+ipfw_nat_get_cfg(struct sockopt *sopt, struct ip_fw_chain *chain)
{
- struct ip_fw_chain *chain = &V_layer3_chain;
struct cfg_nat *n;
struct cfg_redir *r;
struct cfg_spool *s;
@@ -552,14 +555,11 @@ retry:
}
static int
-ipfw_nat_get_log(struct sockopt *sopt)
+ipfw_nat_get_log(struct sockopt *sopt, struct ip_fw_chain *chain)
{
uint8_t *data;
struct cfg_nat *ptr;
int i, size;
- struct ip_fw_chain *chain;
-
- chain = &V_layer3_chain;
IPFW_RLOCK(chain);
/* one pass to count, one to copy the data */
@@ -604,17 +604,22 @@ 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);
+ IPFW_CTX_RLOCK();
+ for (int i = 1; i < IP_FW_MAXCTX; i++) {
+ chain = V_ip_fw_contexts.chain[i];
+ 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);
}
- flush_nat_ptrs(chain, -1 /* flush all */);
- V_ipfw_nat_ready = 0;
- IPFW_WUNLOCK(chain);
+ IPFW_CTX_RUNLOCK();
+
return (0);
}
OpenPOWER on IntegriCloud