4.8-stable review patch.  If anyone has any objections, please let me know.

------------------

From: David Ahern <d...@cumulusnetworks.com>


[ Upstream commit d5d32e4b76687f4df9ad3ba8d3702b7347f51fa6 ]

Similar to IPv4, do not consider link state when validating next hops.

Currently, if the link is down default routes can fail to insert:
 $ ip -6 ro add vrf blue default via 2100:2::64 dev eth2
 RTNETLINK answers: No route to host

With this patch the command succeeds.

Fixes: 8c14586fc320 ("net: ipv6: Use passed in table for nexthop lookups")
Signed-off-by: David Ahern <d...@cumulusnetworks.com>
Signed-off-by: David S. Miller <da...@davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>
---
 include/net/ip6_route.h |    1 +
 net/ipv6/route.c        |    6 ++++--
 2 files changed, 5 insertions(+), 2 deletions(-)

--- a/include/net/ip6_route.h
+++ b/include/net/ip6_route.h
@@ -32,6 +32,7 @@ struct route_info {
 #define RT6_LOOKUP_F_SRCPREF_TMP       0x00000008
 #define RT6_LOOKUP_F_SRCPREF_PUBLIC    0x00000010
 #define RT6_LOOKUP_F_SRCPREF_COA       0x00000020
+#define RT6_LOOKUP_F_IGNORE_LINKSTATE  0x00000040
 
 /* We do not (yet ?) support IPv6 jumbograms (RFC 2675)
  * Unlike IPv4, hdr->seg_len doesn't include the IPv6 header
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -656,7 +656,8 @@ static struct rt6_info *find_match(struc
        struct net_device *dev = rt->dst.dev;
 
        if (dev && !netif_carrier_ok(dev) &&
-           idev->cnf.ignore_routes_with_linkdown)
+           idev->cnf.ignore_routes_with_linkdown &&
+           !(strict & RT6_LOOKUP_F_IGNORE_LINKSTATE))
                goto out;
 
        if (rt6_check_expired(rt))
@@ -1050,6 +1051,7 @@ struct rt6_info *ip6_pol_route(struct ne
        int strict = 0;
 
        strict |= flags & RT6_LOOKUP_F_IFACE;
+       strict |= flags & RT6_LOOKUP_F_IGNORE_LINKSTATE;
        if (net->ipv6.devconf_all->forwarding == 0)
                strict |= RT6_LOOKUP_F_REACHABLE;
 
@@ -1783,7 +1785,7 @@ static struct rt6_info *ip6_nh_lookup_ta
        };
        struct fib6_table *table;
        struct rt6_info *rt;
-       int flags = RT6_LOOKUP_F_IFACE;
+       int flags = RT6_LOOKUP_F_IFACE | RT6_LOOKUP_F_IGNORE_LINKSTATE;
 
        table = fib6_get_table(net, cfg->fc_table);
        if (!table)


Reply via email to