[NETFILTER]: nf_nat: don't add NAT extension for confirmed conntracks
authorPatrick McHardy <kaber@trash.net>
Mon, 14 Apr 2008 09:15:51 +0000 (11:15 +0200)
committerPatrick McHardy <kaber@trash.net>
Mon, 14 Apr 2008 09:15:51 +0000 (11:15 +0200)
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>
include/net/netfilter/nf_nat_rule.h
net/ipv4/netfilter/nf_nat_rule.c
net/ipv4/netfilter/nf_nat_standalone.c

index 75d1825031d712fa420a3af403fe0ad78e593b90..e4a18ae361c62fd543999554461299ad86ba3714 100644 (file)
@@ -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 */
index ebe0c7903ae964823f5552edb3499e69ebde1d42..e8b4d0d4439ea51fb0b638ae46b1b5a86ca6aca6 100644 (file)
@@ -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,
index c362f672755a59dcd0c404a18d8b74441bbad9ca..a366b5865b9c3c3b0556a5ebb772097b64299ac4 100644 (file)
@@ -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