Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a435a07f authored by Vincent Bernat's avatar Vincent Bernat Committed by David S. Miller
Browse files

net: ipv6: fallback to full lookup if table lookup is unsuitable



Commit 8c14586f ("net: ipv6: Use passed in table for nexthop
lookups") introduced a regression: insertion of an IPv6 route in a table
not containing the appropriate connected route for the gateway but which
contained a non-connected route (like a default gateway) fails while it
was previously working:

    $ ip link add eth0 type dummy
    $ ip link set up dev eth0
    $ ip addr add 2001:db8::1/64 dev eth0
    $ ip route add ::/0 via 2001:db8::5 dev eth0 table 20
    $ ip route add 2001:db8:cafe::1/128 via 2001:db8::6 dev eth0 table 20
    RTNETLINK answers: No route to host
    $ ip -6 route show table 20
    default via 2001:db8::5 dev eth0  metric 1024  pref medium

After this patch, we get:

    $ ip route add 2001:db8:cafe::1/128 via 2001:db8::6 dev eth0 table 20
    $ ip -6 route show table 20
    2001:db8:cafe::1 via 2001:db8::6 dev eth0  metric 1024  pref medium
    default via 2001:db8::5 dev eth0  metric 1024  pref medium

Fixes: 8c14586f ("net: ipv6: Use passed in table for nexthop lookups")
Signed-off-by: default avatarVincent Bernat <vincent@bernat.im>
Acked-by: default avatarDavid Ahern <dsa@cumulusnetworks.com>
Tested-by: default avatarDavid Ahern <dsa@cumulusnetworks.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 7675bb2b
Loading
Loading
Loading
Loading
+10 −1
Original line number Original line Diff line number Diff line
@@ -1986,9 +1986,18 @@ static struct rt6_info *ip6_route_info_create(struct fib6_config *cfg)
			if (!(gwa_type & IPV6_ADDR_UNICAST))
			if (!(gwa_type & IPV6_ADDR_UNICAST))
				goto out;
				goto out;


			if (cfg->fc_table)
			if (cfg->fc_table) {
				grt = ip6_nh_lookup_table(net, cfg, gw_addr);
				grt = ip6_nh_lookup_table(net, cfg, gw_addr);


				if (grt) {
					if (grt->rt6i_flags & RTF_GATEWAY ||
					    (dev && dev != grt->dst.dev)) {
						ip6_rt_put(grt);
						grt = NULL;
					}
				}
			}

			if (!grt)
			if (!grt)
				grt = rt6_lookup(net, gw_addr, NULL,
				grt = rt6_lookup(net, gw_addr, NULL,
						 cfg->fc_ifindex, 1);
						 cfg->fc_ifindex, 1);