aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4
diff options
context:
space:
mode:
authorPatrick McHardy <kaber@trash.net>2008-04-14 05:15:51 -0400
committerPatrick McHardy <kaber@trash.net>2008-04-14 05:15:51 -0400
commit8c87238b726e543f8af4bdb4296020a328df4744 (patch)
treed6c74123cfdd8ccd784f8383446a19d260c9bddf /net/ipv4
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>
Diffstat (limited to 'net/ipv4')
-rw-r--r--net/ipv4/netfilter/nf_nat_rule.c19
-rw-r--r--net/ipv4/netfilter/nf_nat_standalone.c8
2 files changed, 4 insertions, 23 deletions
diff --git a/net/ipv4/netfilter/nf_nat_rule.c b/net/ipv4/netfilter/nf_nat_rule.c
index ebe0c7903ae9..e8b4d0d4439e 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)
188 return nf_nat_setup_info(ct, &range, HOOK2MANIP(hooknum)); 188 return nf_nat_setup_info(ct, &range, HOOK2MANIP(hooknum));
189} 189}
190 190
191unsigned int
192alloc_null_binding_confirmed(struct nf_conn *ct, unsigned int hooknum)
193{
194 __be32 ip
195 = (HOOK2MANIP(hooknum) == IP_NAT_MANIP_SRC
196 ? ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u3.ip
197 : ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.u3.ip);
198 __be16 all
199 = (HOOK2MANIP(hooknum) == IP_NAT_MANIP_SRC
200 ? ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u.all
201 : ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.u.all);
202 struct nf_nat_range range
203 = { IP_NAT_RANGE_MAP_IPS, ip, ip, { all }, { all } };
204
205 pr_debug("Allocating NULL binding for confirmed %p (%u.%u.%u.%u)\n",
206 ct, NIPQUAD(ip));
207 return nf_nat_setup_info(ct, &range, HOOK2MANIP(hooknum));
208}
209
210int nf_nat_rule_find(struct sk_buff *skb, 191int nf_nat_rule_find(struct sk_buff *skb,
211 unsigned int hooknum, 192 unsigned int hooknum,
212 const struct net_device *in, 193 const struct net_device *in,
diff --git a/net/ipv4/netfilter/nf_nat_standalone.c b/net/ipv4/netfilter/nf_nat_standalone.c
index c362f672755a..a366b5865b9c 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,
102 102
103 nat = nfct_nat(ct); 103 nat = nfct_nat(ct);
104 if (!nat) { 104 if (!nat) {
105 /* NAT module was loaded late. */
106 if (nf_ct_is_confirmed(ct))
107 return NF_ACCEPT;
105 nat = nf_ct_ext_add(ct, NF_CT_EXT_NAT, GFP_ATOMIC); 108 nat = nf_ct_ext_add(ct, NF_CT_EXT_NAT, GFP_ATOMIC);
106 if (nat == NULL) { 109 if (nat == NULL) {
107 pr_debug("failed to add NAT extension\n"); 110 pr_debug("failed to add NAT extension\n");
@@ -127,10 +130,7 @@ nf_nat_fn(unsigned int hooknum,
127 if (!nf_nat_initialized(ct, maniptype)) { 130 if (!nf_nat_initialized(ct, maniptype)) {
128 unsigned int ret; 131 unsigned int ret;
129 132
130 if (unlikely(nf_ct_is_confirmed(ct))) 133 if (hooknum == NF_INET_LOCAL_IN)
131 /* NAT module was loaded late */
132 ret = alloc_null_binding_confirmed(ct, hooknum);
133 else if (hooknum == NF_INET_LOCAL_IN)
134 /* LOCAL_IN hook doesn't have a chain! */ 134 /* LOCAL_IN hook doesn't have a chain! */
135 ret = alloc_null_binding(ct, hooknum); 135 ret = alloc_null_binding(ct, hooknum);
136 else 136 else