ipv4_large_res_grp
        ipv4_compat_mode
        ipv4_fdb_grp_fcnal
+       ipv4_mpath_select
        ipv4_torture
        ipv4_res_torture
 "
        ipv6_large_res_grp
        ipv6_compat_mode
        ipv6_fdb_grp_fcnal
+       ipv6_mpath_select
        ipv6_torture
        ipv6_res_torture
 "
        log_test $? 0 "Dump large (x$buckets) nexthop buckets"
 }
 
+get_route_dev()
+{
+       local pfx="$1"
+       local out
+
+       if out=$($IP -j route get "$pfx" | jq -re ".[0].dev"); then
+               echo "$out"
+       fi
+}
+
+check_route_dev()
+{
+       local pfx="$1"
+       local expected="$2"
+       local out
+
+       out=$(get_route_dev "$pfx")
+
+       check_output "$out" "$expected"
+}
+
 start_ip_monitor()
 {
        local mtype=$1
        $IP link del dev vx10
 }
 
+ipv4_mpath_select()
+{
+       local rc dev match h addr
+
+       echo
+       echo "IPv4 multipath selection"
+       echo "------------------------"
+       if [ ! -x "$(command -v jq)" ]; then
+               echo "SKIP: Could not run test; need jq tool"
+               return $ksft_skip
+       fi
+
+       # Use status of existing neighbor entry when determining nexthop for
+       # multipath routes.
+       local -A gws
+       gws=([veth1]=172.16.1.2 [veth3]=172.16.2.2)
+       local -A other_dev
+       other_dev=([veth1]=veth3 [veth3]=veth1)
+
+       run_cmd "$IP nexthop add id 1 via ${gws["veth1"]} dev veth1"
+       run_cmd "$IP nexthop add id 2 via ${gws["veth3"]} dev veth3"
+       run_cmd "$IP nexthop add id 1001 group 1/2"
+       run_cmd "$IP ro add 172.16.101.0/24 nhid 1001"
+       rc=0
+       for dev in veth1 veth3; do
+               match=0
+               for h in {1..254}; do
+                       addr="172.16.101.$h"
+                       if [ "$(get_route_dev "$addr")" = "$dev" ]; then
+                               match=1
+                               break
+                       fi
+               done
+               if (( match == 0 )); then
+                       echo "SKIP: Did not find a route using device $dev"
+                       return $ksft_skip
+               fi
+               run_cmd "$IP neigh add ${gws[$dev]} dev $dev nud failed"
+               if ! check_route_dev "$addr" "${other_dev[$dev]}"; then
+                       rc=1
+                       break
+               fi
+               run_cmd "$IP neigh del ${gws[$dev]} dev $dev"
+       done
+       log_test $rc 0 "Use valid neighbor during multipath selection"
+
+       run_cmd "$IP neigh add 172.16.1.2 dev veth1 nud incomplete"
+       run_cmd "$IP neigh add 172.16.2.2 dev veth3 nud incomplete"
+       run_cmd "$IP route get 172.16.101.1"
+       # if we did not crash, success
+       log_test $rc 0 "Multipath selection with no valid neighbor"
+}
+
+ipv6_mpath_select()
+{
+       local rc dev match h addr
+
+       echo
+       echo "IPv6 multipath selection"
+       echo "------------------------"
+       if [ ! -x "$(command -v jq)" ]; then
+               echo "SKIP: Could not run test; need jq tool"
+               return $ksft_skip
+       fi
+
+       # Use status of existing neighbor entry when determining nexthop for
+       # multipath routes.
+       local -A gws
+       gws=([veth1]=2001:db8:91::2 [veth3]=2001:db8:92::2)
+       local -A other_dev
+       other_dev=([veth1]=veth3 [veth3]=veth1)
+
+       run_cmd "$IP nexthop add id 1 via ${gws["veth1"]} dev veth1"
+       run_cmd "$IP nexthop add id 2 via ${gws["veth3"]} dev veth3"
+       run_cmd "$IP nexthop add id 1001 group 1/2"
+       run_cmd "$IP ro add 2001:db8:101::/64 nhid 1001"
+       rc=0
+       for dev in veth1 veth3; do
+               match=0
+               for h in {1..65535}; do
+                       addr=$(printf "2001:db8:101::%x" $h)
+                       if [ "$(get_route_dev "$addr")" = "$dev" ]; then
+                               match=1
+                               break
+                       fi
+               done
+               if (( match == 0 )); then
+                       echo "SKIP: Did not find a route using device $dev"
+                       return $ksft_skip
+               fi
+               run_cmd "$IP neigh add ${gws[$dev]} dev $dev nud failed"
+               if ! check_route_dev "$addr" "${other_dev[$dev]}"; then
+                       rc=1
+                       break
+               fi
+               run_cmd "$IP neigh del ${gws[$dev]} dev $dev"
+       done
+       log_test $rc 0 "Use valid neighbor during multipath selection"
+
+       run_cmd "$IP neigh add 2001:db8:91::2 dev veth1 nud incomplete"
+       run_cmd "$IP neigh add 2001:db8:92::2 dev veth3 nud incomplete"
+       run_cmd "$IP route get 2001:db8:101::1"
+       # if we did not crash, success
+       log_test $rc 0 "Multipath selection with no valid neighbor"
+}
+
 ################################################################################
 # basic operations (add, delete, replace) on nexthops and nexthop groups
 #