Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > 27922b4260f65d317aabda37e42bbbff > files > 2873

kernel-2.6.18-238.el5.src.rpm

From: Jiri Pirko <jpirko@redhat.com>
Date: Wed, 28 Jul 2010 11:10:29 -0400
Subject: [net] nat: avoid rerouting packets if only key changed
Message-id: <20100728111029.GA2696@psychotron.brq.redhat.com>
Patchwork-id: 27147
O-Subject: [RHEL5.6 patch] BZ566144 [NETFILTER]: nat: avoid rerouting packets
	if only XFRM policy key changed
Bugzilla: 566144
RH-Acked-by: David S. Miller <davem@redhat.com>

BZ566144
https://bugzilla.redhat.com/show_bug.cgi?id=566144

Description:
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.

Upstream:
http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commitdiff;h=848c29fd648e78fa87d0e399223826ce5dfc1b7a

Brew:
https://brewweb.devel.redhat.com/taskinfo?taskID=2624910

Test:
tested on x86_64 kvm guest. Works as expected.

Jirka

Signed-off-by: Jiri Pirko <jpirko@redhat.com>
Signed-off-by: Jarod Wilson <jarod@redhat.com>

diff --git a/net/ipv4/netfilter/ip_nat_standalone.c b/net/ipv4/netfilter/ip_nat_standalone.c
index 8686b49..3bc5ab9 100644
--- a/net/ipv4/netfilter/ip_nat_standalone.c
+++ b/net/ipv4/netfilter/ip_nat_standalone.c
@@ -268,13 +268,17 @@ ip_nat_local_fn(unsigned int hooknum,
 		enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
 
 		if (ct->tuplehash[dir].tuple.dst.ip !=
-		    ct->tuplehash[!dir].tuple.src.ip
+		    ct->tuplehash[!dir].tuple.src.ip) {
+			if (ip_route_me_harder(pskb))
+				ret = NF_DROP;
+		}
 #ifdef CONFIG_XFRM
-		    || ct->tuplehash[dir].tuple.dst.u.all !=
-		       ct->tuplehash[!dir].tuple.src.u.all
+		else if (ct->tuplehash[dir].tuple.dst.u.all !=
+			 ct->tuplehash[!dir].tuple.src.u.all)
+			if (ip_xfrm_me_harder(pskb))
+				ret = NF_DROP;
 #endif
-		    )
-			return ip_route_me_harder(pskb) == 0 ? ret : NF_DROP;
+
 	}
 	return ret;
 }