aboutsummaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorJulian Anastasov <ja@ssi.bg>2013-10-20 15:43:03 +0300
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-11-04 04:31:05 -0800
commit208a6152b633a33722cc53bca47c46b79e88a2ad (patch)
tree533f347093b805cbd47d788eb2bd441fb1d412d1 /include
parentb90cd7b9d0baab2e8176d9cca5f18a592ef16063 (diff)
ipv6: always prefer rt6i_gateway if present
[ Upstream commit 96dc809514fb2328605198a0602b67554d8cce7b ] In v3.9 6fd6ce2056de2709 ("ipv6: Do not depend on rt->n in ip6_finish_output2()." changed the behaviour of ip6_finish_output2() such that the recently introduced rt6_nexthop() is used instead of an assigned neighbor. As rt6_nexthop() prefers rt6i_gateway only for gatewayed routes this causes a problem for users like IPVS, xt_TEE and RAW(hdrincl) if they want to use different address for routing compared to the destination address. Another case is when redirect can create RTF_DYNAMIC route without RTF_GATEWAY flag, we ignore the rt6i_gateway in rt6_nexthop(). Fix the above problems by considering the rt6i_gateway if present, so that traffic routed to address on local subnet is not wrongly diverted to the destination address. Thanks to Simon Horman and Phil Oester for spotting the problematic commit. Thanks to Hannes Frederic Sowa for his review and help in testing. Reported-by: Phil Oester <kernel@linuxace.com> Reported-by: Mark Brooks <mark@loadbalancer.org> Signed-off-by: Julian Anastasov <ja@ssi.bg> Acked-by: Hannes Frederic Sowa <hannes@stressinduktion.org> Signed-off-by: David S. Miller <davem@davemloft.net> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'include')
-rw-r--r--include/net/ip6_route.h2
1 files changed, 1 insertions, 1 deletions
diff --git a/include/net/ip6_route.h b/include/net/ip6_route.h
index 260f83f16bc..5cba2302a7a 100644
--- a/include/net/ip6_route.h
+++ b/include/net/ip6_route.h
@@ -196,7 +196,7 @@ static inline int ip6_skb_dst_mtu(struct sk_buff *skb)
static inline struct in6_addr *rt6_nexthop(struct rt6_info *rt, struct in6_addr *dest)
{
- if (rt->rt6i_flags & RTF_GATEWAY)
+ if (rt->rt6i_flags & RTF_GATEWAY || !ipv6_addr_any(&rt->rt6i_gateway))
return &rt->rt6i_gateway;
return dest;
}