Commit 96dc8095 authored by Julian Anastasov's avatar Julian Anastasov Committed by David S. Miller

ipv6: always prefer rt6i_gateway if present

In v3.9 6fd6ce20 ("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: default avatarPhil Oester <kernel@linuxace.com>
Reported-by: default avatarMark Brooks <mark@loadbalancer.org>
Signed-off-by: default avatarJulian Anastasov <ja@ssi.bg>
Acked-by: default avatarHannes Frederic Sowa <hannes@stressinduktion.org>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 4440c6f7
...@@ -196,7 +196,7 @@ static inline int ip6_skb_dst_mtu(struct sk_buff *skb) ...@@ -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) 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 &rt->rt6i_gateway;
return dest; return dest;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment