diff options
author | Patrick McHardy <kaber@trash.net> | 2007-03-22 15:30:29 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2007-03-22 15:30:29 -0400 |
commit | 848c29fd648e78fa87d0e399223826ce5dfc1b7a (patch) | |
tree | e76dac40d1d318f98bfdfe604ae43a29dec85ff9 | |
parent | ca8fbb859c42c9a402c5c19fd0588d89ae4988ba (diff) |
[NETFILTER]: nat: avoid rerouting packets if only XFRM policy key changed
Currently NAT not only reroutes packets in the OUTPUT chain when the
routing key changed, but also if only the non-routing part of the
IPsec policy key changed. This breaks ping -I since it doesn't use
SO_BINDTODEVICE but IP_PKTINFO cmsg to specify the output device, and
this information is lost.
Only do full rerouting if the routing key changed, and just do a new
policy lookup with the old route if only the ports changed.
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | net/ipv4/netfilter/ip_nat_standalone.c | 15 | ||||
-rw-r--r-- | net/ipv4/netfilter/nf_nat_standalone.c | 14 |
2 files changed, 17 insertions, 12 deletions
diff --git a/net/ipv4/netfilter/ip_nat_standalone.c b/net/ipv4/netfilter/ip_nat_standalone.c index adf25f9f70e1..6bcfdf6dfcc9 100644 --- a/net/ipv4/netfilter/ip_nat_standalone.c +++ b/net/ipv4/netfilter/ip_nat_standalone.c | |||
@@ -253,14 +253,17 @@ ip_nat_local_fn(unsigned int hooknum, | |||
253 | enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo); | 253 | enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo); |
254 | 254 | ||
255 | if (ct->tuplehash[dir].tuple.dst.ip != | 255 | if (ct->tuplehash[dir].tuple.dst.ip != |
256 | ct->tuplehash[!dir].tuple.src.ip | 256 | ct->tuplehash[!dir].tuple.src.ip) { |
257 | #ifdef CONFIG_XFRM | ||
258 | || ct->tuplehash[dir].tuple.dst.u.all != | ||
259 | ct->tuplehash[!dir].tuple.src.u.all | ||
260 | #endif | ||
261 | ) | ||
262 | if (ip_route_me_harder(pskb, RTN_UNSPEC)) | 257 | if (ip_route_me_harder(pskb, RTN_UNSPEC)) |
263 | ret = NF_DROP; | 258 | ret = NF_DROP; |
259 | } | ||
260 | #ifdef CONFIG_XFRM | ||
261 | else if (ct->tuplehash[dir].tuple.dst.u.all != | ||
262 | ct->tuplehash[!dir].tuple.src.u.all) | ||
263 | if (ip_xfrm_me_harder(pskb)) | ||
264 | ret = NF_DROP; | ||
265 | #endif | ||
266 | |||
264 | } | 267 | } |
265 | return ret; | 268 | return ret; |
266 | } | 269 | } |
diff --git a/net/ipv4/netfilter/nf_nat_standalone.c b/net/ipv4/netfilter/nf_nat_standalone.c index e4d3ef17d45b..15aa3db8cb33 100644 --- a/net/ipv4/netfilter/nf_nat_standalone.c +++ b/net/ipv4/netfilter/nf_nat_standalone.c | |||
@@ -245,14 +245,16 @@ nf_nat_local_fn(unsigned int hooknum, | |||
245 | enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo); | 245 | enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo); |
246 | 246 | ||
247 | if (ct->tuplehash[dir].tuple.dst.u3.ip != | 247 | if (ct->tuplehash[dir].tuple.dst.u3.ip != |
248 | ct->tuplehash[!dir].tuple.src.u3.ip | 248 | ct->tuplehash[!dir].tuple.src.u3.ip) { |
249 | #ifdef CONFIG_XFRM | ||
250 | || ct->tuplehash[dir].tuple.dst.u.all != | ||
251 | ct->tuplehash[!dir].tuple.src.u.all | ||
252 | #endif | ||
253 | ) | ||
254 | if (ip_route_me_harder(pskb, RTN_UNSPEC)) | 249 | if (ip_route_me_harder(pskb, RTN_UNSPEC)) |
255 | ret = NF_DROP; | 250 | ret = NF_DROP; |
251 | } | ||
252 | #ifdef CONFIG_XFRM | ||
253 | else if (ct->tuplehash[dir].tuple.dst.u.all != | ||
254 | ct->tuplehash[!dir].tuple.src.u.all) | ||
255 | if (ip_xfrm_me_harder(pskb)) | ||
256 | ret = NF_DROP; | ||
257 | #endif | ||
256 | } | 258 | } |
257 | return ret; | 259 | return ret; |
258 | } | 260 | } |