diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/ipv4/netfilter/ip_nat_rule.c | 21 | ||||
-rw-r--r-- | net/ipv4/netfilter/ip_nat_standalone.c | 8 |
2 files changed, 27 insertions, 2 deletions
diff --git a/net/ipv4/netfilter/ip_nat_rule.c b/net/ipv4/netfilter/ip_nat_rule.c index 60d70fa41a15..cb66b8bddeb3 100644 --- a/net/ipv4/netfilter/ip_nat_rule.c +++ b/net/ipv4/netfilter/ip_nat_rule.c | |||
@@ -255,6 +255,27 @@ alloc_null_binding(struct ip_conntrack *conntrack, | |||
255 | return ip_nat_setup_info(conntrack, &range, hooknum); | 255 | return ip_nat_setup_info(conntrack, &range, hooknum); |
256 | } | 256 | } |
257 | 257 | ||
258 | unsigned int | ||
259 | alloc_null_binding_confirmed(struct ip_conntrack *conntrack, | ||
260 | struct ip_nat_info *info, | ||
261 | unsigned int hooknum) | ||
262 | { | ||
263 | u_int32_t ip | ||
264 | = (HOOK2MANIP(hooknum) == IP_NAT_MANIP_SRC | ||
265 | ? conntrack->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip | ||
266 | : conntrack->tuplehash[IP_CT_DIR_REPLY].tuple.src.ip); | ||
267 | u_int16_t all | ||
268 | = (HOOK2MANIP(hooknum) == IP_NAT_MANIP_SRC | ||
269 | ? conntrack->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u.all | ||
270 | : conntrack->tuplehash[IP_CT_DIR_REPLY].tuple.src.u.all); | ||
271 | struct ip_nat_range range | ||
272 | = { IP_NAT_RANGE_MAP_IPS, ip, ip, { all }, { all } }; | ||
273 | |||
274 | DEBUGP("Allocating NULL binding for confirmed %p (%u.%u.%u.%u)\n", | ||
275 | conntrack, NIPQUAD(ip)); | ||
276 | return ip_nat_setup_info(conntrack, &range, hooknum); | ||
277 | } | ||
278 | |||
258 | int ip_nat_rule_find(struct sk_buff **pskb, | 279 | int ip_nat_rule_find(struct sk_buff **pskb, |
259 | unsigned int hooknum, | 280 | unsigned int hooknum, |
260 | const struct net_device *in, | 281 | const struct net_device *in, |
diff --git a/net/ipv4/netfilter/ip_nat_standalone.c b/net/ipv4/netfilter/ip_nat_standalone.c index 89db052add81..0ff368b131f6 100644 --- a/net/ipv4/netfilter/ip_nat_standalone.c +++ b/net/ipv4/netfilter/ip_nat_standalone.c | |||
@@ -123,8 +123,12 @@ ip_nat_fn(unsigned int hooknum, | |||
123 | if (!ip_nat_initialized(ct, maniptype)) { | 123 | if (!ip_nat_initialized(ct, maniptype)) { |
124 | unsigned int ret; | 124 | unsigned int ret; |
125 | 125 | ||
126 | /* LOCAL_IN hook doesn't have a chain! */ | 126 | if (unlikely(is_confirmed(ct))) |
127 | if (hooknum == NF_IP_LOCAL_IN) | 127 | /* NAT module was loaded late */ |
128 | ret = alloc_null_binding_confirmed(ct, info, | ||
129 | hooknum); | ||
130 | else if (hooknum == NF_IP_LOCAL_IN) | ||
131 | /* LOCAL_IN hook doesn't have a chain! */ | ||
128 | ret = alloc_null_binding(ct, info, hooknum); | 132 | ret = alloc_null_binding(ct, info, hooknum); |
129 | else | 133 | else |
130 | ret = ip_nat_rule_find(pskb, hooknum, | 134 | ret = ip_nat_rule_find(pskb, hooknum, |