Skip to content

Commit

Permalink
[NETFILTER]: nf_nat: don't add NAT extension for confirmed conntracks
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Patrick McHardy committed Apr 14, 2008
1 parent 42cf800 commit 8c87238
Show file tree
Hide file tree
Showing 3 changed files with 4 additions and 26 deletions.
3 changes: 0 additions & 3 deletions include/net/netfilter/nf_nat_rule.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
19 changes: 0 additions & 19 deletions net/ipv4/netfilter/nf_nat_rule.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
8 changes: 4 additions & 4 deletions net/ipv4/netfilter/nf_nat_standalone.c
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand All @@ -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
Expand Down

0 comments on commit 8c87238

Please sign in to comment.