From: Herbert Xu <herbert.xu@redhat.com> Date: Tue, 10 Feb 2009 17:00:50 +1100 Subject: [net] don't add NAT extension for confirmed conntracks Message-id: 20090210060050.GA19401@gondor.apana.org.au O-Subject: [RHEL5.4 PATCH] [NETFILTER]: nf_nat: don't add NAT extension for confirmed conntracks Bugzilla: 481076 RH-Acked-by: Anton Arapov <aarapov@redhat.com> RH-Acked-by: Thomas Graf <tgraf@redhat.com> RH-Acked-by: David Miller <davem@redhat.com> Hi: RHEL5.4 BZ 481076 This backport from upstream fixes a bug where a freshly loaded NAT module can trigger a crash for connections that existed prior to the loading. commit 8c87238b726e543f8af4bdb4296020a328df4744 Author: Patrick McHardy <kaber@trash.net> Date: Mon Apr 14 11:15:51 2008 +0200 [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> diff --git a/include/linux/netfilter_ipv4/ip_nat_rule.h b/include/linux/netfilter_ipv4/ip_nat_rule.h index 73b9552..fecd2a0 100644 --- a/include/linux/netfilter_ipv4/ip_nat_rule.h +++ b/include/linux/netfilter_ipv4/ip_nat_rule.h @@ -19,10 +19,5 @@ extern unsigned int alloc_null_binding(struct ip_conntrack *conntrack, struct ip_nat_info *info, unsigned int hooknum); - -extern unsigned int -alloc_null_binding_confirmed(struct ip_conntrack *conntrack, - struct ip_nat_info *info, - unsigned int hooknum); #endif #endif /* _IP_NAT_RULE_H */ diff --git a/net/ipv4/netfilter/ip_nat_rule.c b/net/ipv4/netfilter/ip_nat_rule.c index 1aba926..699eef7 100644 --- a/net/ipv4/netfilter/ip_nat_rule.c +++ b/net/ipv4/netfilter/ip_nat_rule.c @@ -225,27 +225,6 @@ alloc_null_binding(struct ip_conntrack *conntrack, return ip_nat_setup_info(conntrack, &range, hooknum); } -unsigned int -alloc_null_binding_confirmed(struct ip_conntrack *conntrack, - struct ip_nat_info *info, - unsigned int hooknum) -{ - u_int32_t ip - = (HOOK2MANIP(hooknum) == IP_NAT_MANIP_SRC - ? conntrack->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip - : conntrack->tuplehash[IP_CT_DIR_REPLY].tuple.src.ip); - u_int16_t all - = (HOOK2MANIP(hooknum) == IP_NAT_MANIP_SRC - ? conntrack->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u.all - : conntrack->tuplehash[IP_CT_DIR_REPLY].tuple.src.u.all); - struct ip_nat_range range - = { IP_NAT_RANGE_MAP_IPS, ip, ip, { all }, { all } }; - - DEBUGP("Allocating NULL binding for confirmed %p (%u.%u.%u.%u)\n", - conntrack, NIPQUAD(ip)); - return ip_nat_setup_info(conntrack, &range, hooknum); -} - int ip_nat_rule_find(struct sk_buff **pskb, unsigned int hooknum, const struct net_device *in, diff --git a/net/ipv4/netfilter/ip_nat_standalone.c b/net/ipv4/netfilter/ip_nat_standalone.c index 6db485f..8686b49 100644 --- a/net/ipv4/netfilter/ip_nat_standalone.c +++ b/net/ipv4/netfilter/ip_nat_standalone.c @@ -163,8 +163,7 @@ ip_nat_fn(unsigned int hooknum, if (unlikely(is_confirmed(ct))) /* NAT module was loaded late */ - ret = alloc_null_binding_confirmed(ct, info, - hooknum); + return NF_ACCEPT; else if (hooknum == NF_IP_LOCAL_IN) /* LOCAL_IN hook doesn't have a chain! */ ret = alloc_null_binding(ct, info, hooknum);