[PATCH] 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
b4c4ed175f ([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>
This commit is contained in:
Patrick McHardy
2006-11-17 06:35:48 +01:00
committed by Chris Wright
parent 61706f0a27
commit faed318ca8
5 changed files with 21 additions and 6 deletions
+1 -1
View File
@@ -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);
+10
View File
@@ -813,6 +813,16 @@ ip_vs_out(unsigned int hooknum, struct sk_buff **pskb,
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);
+6 -3
View File
@@ -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 **pskb)
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 **pskb, const struct nf_info *info)
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;
}
+2 -1
View File
@@ -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;
}
+2 -1
View File
@@ -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;
}