aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorJulian Anastasov <ja@ssi.bg>2012-10-08 07:41:20 -0400
committerDavid S. Miller <davem@davemloft.net>2012-10-08 17:42:36 -0400
commitad4d3ef8b7eb527cca478dc08c02c10936e64115 (patch)
tree530706cd517a8810cb0ccea44ebccc6c19d875bd /net
parentc92b96553a80c1dbe2ebe128bbe37c8f98f148bf (diff)
ipvs: fix ARP resolving for direct routing mode
After the change "Make neigh lookups directly in output packet path" (commit a263b30936) IPVS can not reach the real server for DR mode because we resolve the destination address from IP header, not from route neighbour. Use the new FLOWI_FLAG_KNOWN_NH flag to request output routes with known nexthop, so that it has preference on resolving. Signed-off-by: Julian Anastasov <ja@ssi.bg> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r--net/netfilter/ipvs/ip_vs_xmit.c6
1 files changed, 5 insertions, 1 deletions
diff --git a/net/netfilter/ipvs/ip_vs_xmit.c b/net/netfilter/ipvs/ip_vs_xmit.c
index 56f6d5d81a77..cc4c8095681a 100644
--- a/net/netfilter/ipvs/ip_vs_xmit.c
+++ b/net/netfilter/ipvs/ip_vs_xmit.c
@@ -50,6 +50,7 @@ enum {
50 * local 50 * local
51 */ 51 */
52 IP_VS_RT_MODE_CONNECT = 8, /* Always bind route to saddr */ 52 IP_VS_RT_MODE_CONNECT = 8, /* Always bind route to saddr */
53 IP_VS_RT_MODE_KNOWN_NH = 16,/* Route via remote addr */
53}; 54};
54 55
55/* 56/*
@@ -113,6 +114,8 @@ static struct rtable *do_output_route4(struct net *net, __be32 daddr,
113 fl4.daddr = daddr; 114 fl4.daddr = daddr;
114 fl4.saddr = (rt_mode & IP_VS_RT_MODE_CONNECT) ? *saddr : 0; 115 fl4.saddr = (rt_mode & IP_VS_RT_MODE_CONNECT) ? *saddr : 0;
115 fl4.flowi4_tos = rtos; 116 fl4.flowi4_tos = rtos;
117 fl4.flowi4_flags = (rt_mode & IP_VS_RT_MODE_KNOWN_NH) ?
118 FLOWI_FLAG_KNOWN_NH : 0;
116 119
117retry: 120retry:
118 rt = ip_route_output_key(net, &fl4); 121 rt = ip_route_output_key(net, &fl4);
@@ -1061,7 +1064,8 @@ ip_vs_dr_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
1061 if (!(rt = __ip_vs_get_out_rt(skb, cp->dest, cp->daddr.ip, 1064 if (!(rt = __ip_vs_get_out_rt(skb, cp->dest, cp->daddr.ip,
1062 RT_TOS(iph->tos), 1065 RT_TOS(iph->tos),
1063 IP_VS_RT_MODE_LOCAL | 1066 IP_VS_RT_MODE_LOCAL |
1064 IP_VS_RT_MODE_NON_LOCAL, NULL))) 1067 IP_VS_RT_MODE_NON_LOCAL |
1068 IP_VS_RT_MODE_KNOWN_NH, NULL)))
1065 goto tx_error_icmp; 1069 goto tx_error_icmp;
1066 if (rt->rt_flags & RTCF_LOCAL) { 1070 if (rt->rt_flags & RTCF_LOCAL) {
1067 ip_rt_put(rt); 1071 ip_rt_put(rt);