blob: 8c210f899b6b9ac9900f348dc983968c945279e4 [file] [log] [blame]
From stable-bounces@linux.kernel.org Thu Nov 16 21:40:54 2006
From: Patrick McHardy <kaber@trash.net>
To: stable@kernel.org
Message-Id: <20061117053548.10231.71519.sendpatchset@localhost.localdomain>
Date: Fri, 17 Nov 2006 06:35:48 +0100 (MET)
Cc: Patrick McHardy <kaber@trash.net>, davem@davemloft.net
Subject: NETFILTER: Honour source routing for LVS-NAT
For policy routing, packets originating from this machine itself may be
routed differently to packets passing through. We want this packet to be
routed as if it came from this machine itself. So re-compute the routing
information using ip_route_me_harder().
This patch is derived from work by Ken Brownfield
This patch (-stable version) also includes commit
b4c4ed175ff0ee816df48571cfa9b73f521964b6 ([NETFILTER]: add type parameter
to ip_route_me_harder), which is a precondition for the fix.
Cc: Ken Brownfield <krb@irridia.com>
Signed-off-by: Simon Horman <horms@verge.net.au>
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Chris Wright <chrisw@sous-sol.org>
---
commit cf08e74a590c945d3c0b95886ea3fad8ff73793d
tree d5c1a44360bb9a4a2d59e37a9f0dc3c6ce0b6c49
parent 6b22b99ecd431b63aece1fa5b1faa01b75a8302e
author Patrick McHardy <kaber@trash.net> Fri, 17 Nov 2006 06:25:11 +0100
committer Patrick McHardy <kaber@trash.net> Fri, 17 Nov 2006 06:25:11 +0100
include/linux/netfilter_ipv4.h | 2 +-
net/ipv4/ipvs/ip_vs_core.c | 10 ++++++++++
net/ipv4/netfilter.c | 9 ++++++---
net/ipv4/netfilter/ip_nat_standalone.c | 3 ++-
net/ipv4/netfilter/iptable_mangle.c | 3 ++-
5 files changed, 21 insertions(+), 6 deletions(-)
--- linux-2.6.18.4.orig/include/linux/netfilter_ipv4.h
+++ linux-2.6.18.4/include/linux/netfilter_ipv4.h
@@ -77,7 +77,7 @@ enum nf_ip_hook_priorities {
#define SO_ORIGINAL_DST 80
#ifdef __KERNEL__
-extern int ip_route_me_harder(struct sk_buff **pskb);
+extern int ip_route_me_harder(struct sk_buff **pskb, unsigned addr_type);
extern int ip_xfrm_me_harder(struct sk_buff **pskb);
extern unsigned int nf_ip_checksum(struct sk_buff *skb, unsigned int hook,
unsigned int dataoff, u_int8_t protocol);
--- linux-2.6.18.4.orig/net/ipv4/ipvs/ip_vs_core.c
+++ linux-2.6.18.4/net/ipv4/ipvs/ip_vs_core.c
@@ -813,6 +813,16 @@ ip_vs_out(unsigned int hooknum, struct s
skb->nh.iph->saddr = cp->vaddr;
ip_send_check(skb->nh.iph);
+ /* For policy routing, packets originating from this
+ * machine itself may be routed differently to packets
+ * passing through. We want this packet to be routed as
+ * if it came from this machine itself. So re-compute
+ * the routing information.
+ */
+ if (ip_route_me_harder(pskb, RTN_LOCAL) != 0)
+ goto drop;
+ skb = *pskb;
+
IP_VS_DBG_PKT(10, pp, skb, 0, "After SNAT");
ip_vs_out_stats(cp, skb);
--- linux-2.6.18.4.orig/net/ipv4/netfilter.c
+++ linux-2.6.18.4/net/ipv4/netfilter.c
@@ -8,7 +8,7 @@
#include <net/ip.h>
/* route_me_harder function, used by iptable_nat, iptable_mangle + ip_queue */
-int ip_route_me_harder(struct sk_buff **pskb)
+int ip_route_me_harder(struct sk_buff **pskb, unsigned addr_type)
{
struct iphdr *iph = (*pskb)->nh.iph;
struct rtable *rt;
@@ -16,10 +16,13 @@ int ip_route_me_harder(struct sk_buff **
struct dst_entry *odst;
unsigned int hh_len;
+ if (addr_type == RTN_UNSPEC)
+ addr_type = inet_addr_type(iph->saddr);
+
/* some non-standard hacks like ipt_REJECT.c:send_reset() can cause
* packets with foreign saddr to appear on the NF_IP_LOCAL_OUT hook.
*/
- if (inet_addr_type(iph->saddr) == RTN_LOCAL) {
+ if (addr_type == RTN_LOCAL) {
fl.nl_u.ip4_u.daddr = iph->daddr;
fl.nl_u.ip4_u.saddr = iph->saddr;
fl.nl_u.ip4_u.tos = RT_TOS(iph->tos);
@@ -156,7 +159,7 @@ static int nf_ip_reroute(struct sk_buff
if (!(iph->tos == rt_info->tos
&& iph->daddr == rt_info->daddr
&& iph->saddr == rt_info->saddr))
- return ip_route_me_harder(pskb);
+ return ip_route_me_harder(pskb, RTN_UNSPEC);
}
return 0;
}
--- linux-2.6.18.4.orig/net/ipv4/netfilter/ip_nat_standalone.c
+++ linux-2.6.18.4/net/ipv4/netfilter/ip_nat_standalone.c
@@ -275,7 +275,8 @@ ip_nat_local_fn(unsigned int hooknum,
ct->tuplehash[!dir].tuple.src.u.all
#endif
)
- return ip_route_me_harder(pskb) == 0 ? ret : NF_DROP;
+ if (ip_route_me_harder(pskb, RTN_UNSPEC))
+ ret = NF_DROP;
}
return ret;
}
--- linux-2.6.18.4.orig/net/ipv4/netfilter/iptable_mangle.c
+++ linux-2.6.18.4/net/ipv4/netfilter/iptable_mangle.c
@@ -157,7 +157,8 @@ ipt_local_hook(unsigned int hook,
|| (*pskb)->nfmark != nfmark
#endif
|| (*pskb)->nh.iph->tos != tos))
- return ip_route_me_harder(pskb) == 0 ? ret : NF_DROP;
+ if (ip_route_me_harder(pskb, RTN_UNSPEC))
+ ret = NF_DROP;
return ret;
}