net/ipv6: Allow onlink routes to have a device mismatch if it is the default route
authorDavid Ahern <dsahern@gmail.com>
Wed, 24 Oct 2018 20:58:39 +0000 (13:58 -0700)
committerDavid S. Miller <davem@davemloft.net>
Wed, 24 Oct 2018 21:36:38 +0000 (14:36 -0700)
The intent of ip6_route_check_nh_onlink is to make sure the gateway
given for an onlink route is not actually on a connected route for
a different interface (e.g., 2001:db8:1::/64 is on dev eth1 and then
an onlink route has a via 2001:db8:1::1 dev eth2). If the gateway
lookup hits the default route then it most likely will be a different
interface than the onlink route which is ok.

Update ip6_route_check_nh_onlink to disregard the device mismatch
if the gateway lookup hits the default route. Turns out the existing
onlink tests are passing because there is no default route or it is
an unreachable default, so update the onlink tests to have a default
route other than unreachable.

Fixes: fc1e64e1092f6 ("net/ipv6: Add support for onlink flag")
Signed-off-by: David Ahern <dsahern@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/ipv6/route.c
tools/testing/selftests/net/fib-onlink-tests.sh

index e3226284e4801f34913c8446971425ff52295a45..2a7423c394560c0bc70d6f0398781a0b35fa9fa0 100644 (file)
@@ -2745,6 +2745,8 @@ static int ip6_route_check_nh_onlink(struct net *net,
        grt = ip6_nh_lookup_table(net, cfg, gw_addr, tbid, 0);
        if (grt) {
                if (!grt->dst.error &&
+                   /* ignore match if it is the default route */
+                   grt->from && !ipv6_addr_any(&grt->from->fib6_dst.addr) &&
                    (grt->rt6i_flags & flags || dev != grt->dst.dev)) {
                        NL_SET_ERR_MSG(extack,
                                       "Nexthop has invalid gateway or device mismatch");
index 3991ad1a368d54abc19ca1d1f0c8adbb2124ae0b..864f865eee55f8c9d787217d89075278bcc84a57 100755 (executable)
@@ -167,8 +167,8 @@ setup()
        # add vrf table
        ip li add ${VRF} type vrf table ${VRF_TABLE}
        ip li set ${VRF} up
-       ip ro add table ${VRF_TABLE} unreachable default
-       ip -6 ro add table ${VRF_TABLE} unreachable default
+       ip ro add table ${VRF_TABLE} unreachable default metric 8192
+       ip -6 ro add table ${VRF_TABLE} unreachable default metric 8192
 
        # create test interfaces
        ip li add ${NETIFS[p1]} type veth peer name ${NETIFS[p2]}
@@ -185,20 +185,20 @@ setup()
        for n in 1 3 5 7; do
                ip li set ${NETIFS[p${n}]} up
                ip addr add ${V4ADDRS[p${n}]}/24 dev ${NETIFS[p${n}]}
-               ip addr add ${V6ADDRS[p${n}]}/64 dev ${NETIFS[p${n}]}
+               ip addr add ${V6ADDRS[p${n}]}/64 dev ${NETIFS[p${n}]} nodad
        done
 
        # move peer interfaces to namespace and add addresses
        for n in 2 4 6 8; do
                ip li set ${NETIFS[p${n}]} netns ${PEER_NS} up
                ip -netns ${PEER_NS} addr add ${V4ADDRS[p${n}]}/24 dev ${NETIFS[p${n}]}
-               ip -netns ${PEER_NS} addr add ${V6ADDRS[p${n}]}/64 dev ${NETIFS[p${n}]}
+               ip -netns ${PEER_NS} addr add ${V6ADDRS[p${n}]}/64 dev ${NETIFS[p${n}]} nodad
        done
 
-       set +e
+       ip -6 ro add default via ${V6ADDRS[p3]/::[0-9]/::64}
+       ip -6 ro add table ${VRF_TABLE} default via ${V6ADDRS[p7]/::[0-9]/::64}
 
-       # let DAD complete - assume default of 1 probe
-       sleep 1
+       set +e
 }
 
 cleanup()