aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPatrick McHardy <kaber@trash.net>2008-04-14 11:15:51 +0200
committerPatrick McHardy <kaber@trash.net>2008-04-14 11:15:51 +0200
commit8c87238b726e543f8af4bdb4296020a328df4744 (patch)
treed6c74123cfdd8ccd784f8383446a19d260c9bddf
parent42cf800c240fa845e9c154429d70d62750e65b64 (diff)
[NETFILTER]: nf_nat: don't add NAT extension for confirmed conntracks
Adding extensions to confirmed conntracks is not allowed to avoid races on reallocation. Don't setup NAT for confirmed conntracks in case NAT module is loaded late. The has one side-effect, the connections existing before the NAT module was loaded won't enter the bysource hash. The only case where this actually makes a difference is in case of SNAT to a multirange where the IP before NAT is also part of the range. Since old connections don't enter the bysource hash the first new connection from the IP will have a new address selected. This shouldn't matter at all. Signed-off-by: Patrick McHardy <kaber@trash.net>
-rw-r--r--include/net/netfilter/nf_nat_rule.h3
-rw-r--r--net/ipv4/netfilter/nf_nat_rule.c19
-rw-r--r--net/ipv4/netfilter/nf_nat_standalone.c8
3 files changed, 4 insertions, 26 deletions
diff --git a/include/net/netfilter/nf_nat_rule.h b/include/net/netfilter/nf_nat_rule.h
index 75d1825031d..e4a18ae361c 100644
--- a/include/net/netfilter/nf_nat_rule.h
+++ b/include/net/netfilter/nf_nat_rule.h
@@ -14,7 +14,4 @@ extern int nf_nat_rule_find(struct sk_buff *skb,
extern unsigned int
alloc_null_binding(struct nf_conn *ct, unsigned int hooknum);
-
-extern unsigned int
-alloc_null_binding_confirmed(struct nf_conn *ct, unsigned int hooknum);
#endif /* _NF_NAT_RULE_H */
diff --git a/net/ipv4/netfilter/nf_nat_rule.c b/net/ipv4/netfilter/nf_nat_rule.c
index ebe0c7903ae..e8b4d0d4439 100644
--- a/net/ipv4/netfilter/nf_nat_rule.c
+++ b/net/ipv4/netfilter/nf_nat_rule.c
@@ -188,25 +188,6 @@ alloc_null_binding(struct nf_conn *ct, unsigned int hooknum)
return nf_nat_setup_info(ct, &range, HOOK2MANIP(hooknum));
}
-unsigned int
-alloc_null_binding_confirmed(struct nf_conn *ct, unsigned int hooknum)
-{
- __be32 ip
- = (HOOK2MANIP(hooknum) == IP_NAT_MANIP_SRC
- ? ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u3.ip
- : ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.u3.ip);
- __be16 all
- = (HOOK2MANIP(hooknum) == IP_NAT_MANIP_SRC
- ? ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u.all
- : ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.u.all);
- struct nf_nat_range range
- = { IP_NAT_RANGE_MAP_IPS, ip, ip, { all }, { all } };
-
- pr_debug("Allocating NULL binding for confirmed %p (%u.%u.%u.%u)\n",
- ct, NIPQUAD(ip));
- return nf_nat_setup_info(ct, &range, HOOK2MANIP(hooknum));
-}
-
int nf_nat_rule_find(struct sk_buff *skb,
unsigned int hooknum,
const struct net_device *in,
diff --git a/net/ipv4/netfilter/nf_nat_standalone.c b/net/ipv4/netfilter/nf_nat_standalone.c
index c362f672755..a366b5865b9 100644
--- a/net/ipv4/netfilter/nf_nat_standalone.c
+++ b/net/ipv4/netfilter/nf_nat_standalone.c
@@ -102,6 +102,9 @@ nf_nat_fn(unsigned int hooknum,
nat = nfct_nat(ct);
if (!nat) {
+ /* NAT module was loaded late. */
+ if (nf_ct_is_confirmed(ct))
+ return NF_ACCEPT;
nat = nf_ct_ext_add(ct, NF_CT_EXT_NAT, GFP_ATOMIC);
if (nat == NULL) {
pr_debug("failed to add NAT extension\n");
@@ -127,10 +130,7 @@ nf_nat_fn(unsigned int hooknum,
if (!nf_nat_initialized(ct, maniptype)) {
unsigned int ret;
- if (unlikely(nf_ct_is_confirmed(ct)))
- /* NAT module was loaded late */
- ret = alloc_null_binding_confirmed(ct, hooknum);
- else if (hooknum == NF_INET_LOCAL_IN)
+ if (hooknum == NF_INET_LOCAL_IN)
/* LOCAL_IN hook doesn't have a chain! */
ret = alloc_null_binding(ct, hooknum);
else