···11+#!/bin/bash22+# SPDX-License-Identifier: GPL-2.033+#44+# ns: me | ns: peer | ns: remote55+# 2001:db8:91::1 | 2001:db8:91::2 |66+# 172.16.1.1 | 172.16.1.2 |77+# veth1 <---|---> veth2 |88+# | veth5 <--|--> veth6 172.16.101.199+# veth3 <---|---> veth4 | 2001:db8:101::11010+# 172.16.2.1 | 172.16.2.2 |1111+# 2001:db8:92::1 | 2001:db8:92::2 |1212+#1313+# This test is for checking IPv4 and IPv6 FIB behavior with nexthop1414+# objects. Device reference counts and network namespace cleanup tested1515+# by use of network namespace for peer.1616+1717+ret=01818+# Kselftest framework requirement - SKIP code is 4.1919+ksft_skip=42020+2121+# all tests in this script. Can be overridden with -t option2222+IPV4_TESTS="ipv4_fcnal ipv4_grp_fcnal ipv4_withv6_fcnal ipv4_fcnal_runtime"2323+IPV6_TESTS="ipv6_fcnal ipv6_grp_fcnal ipv6_fcnal_runtime"2424+2525+ALL_TESTS="basic ${IPV4_TESTS} ${IPV6_TESTS}"2626+TESTS="${ALL_TESTS}"2727+VERBOSE=02828+PAUSE_ON_FAIL=no2929+PAUSE=no3030+3131+nsid=1003232+3333+################################################################################3434+# utilities3535+3636+log_test()3737+{3838+ local rc=$13939+ local expected=$24040+ local msg="$3"4141+4242+ if [ ${rc} -eq ${expected} ]; then4343+ printf "TEST: %-60s [ OK ]\n" "${msg}"4444+ nsuccess=$((nsuccess+1))4545+ else4646+ ret=14747+ nfail=$((nfail+1))4848+ printf "TEST: %-60s [FAIL]\n" "${msg}"4949+ if [ "$VERBOSE" = "1" ]; then5050+ echo " rc=$rc, expected $expected"5151+ fi5252+5353+ if [ "${PAUSE_ON_FAIL}" = "yes" ]; then5454+ echo5555+ echo "hit enter to continue, 'q' to quit"5656+ read a5757+ [ "$a" = "q" ] && exit 15858+ fi5959+ fi6060+6161+ if [ "${PAUSE}" = "yes" ]; then6262+ echo6363+ echo "hit enter to continue, 'q' to quit"6464+ read a6565+ [ "$a" = "q" ] && exit 16666+ fi6767+6868+ [ "$VERBOSE" = "1" ] && echo6969+}7070+7171+run_cmd()7272+{7373+ local cmd="$1"7474+ local out7575+ local stderr="2>/dev/null"7676+7777+ if [ "$VERBOSE" = "1" ]; then7878+ printf "COMMAND: $cmd\n"7979+ stderr=8080+ fi8181+8282+ out=$(eval $cmd $stderr)8383+ rc=$?8484+ if [ "$VERBOSE" = "1" -a -n "$out" ]; then8585+ echo " $out"8686+ fi8787+8888+ return $rc8989+}9090+9191+get_linklocal()9292+{9393+ local dev=$19494+ local ns9595+ local addr9696+9797+ [ -n "$2" ] && ns="-netns $2"9898+ addr=$(ip $ns -6 -br addr show dev ${dev} | \9999+ awk '{100100+ for (i = 3; i <= NF; ++i) {101101+ if ($i ~ /^fe80/)102102+ print $i103103+ }104104+ }'105105+ )106106+ addr=${addr/\/*}107107+108108+ [ -z "$addr" ] && return 1109109+110110+ echo $addr111111+112112+ return 0113113+}114114+115115+create_ns()116116+{117117+ local n=${1}118118+119119+ ip netns del ${n} 2>/dev/null120120+121121+ set -e122122+ ip netns add ${n}123123+ ip netns set ${n} $((nsid++))124124+ ip -netns ${n} addr add 127.0.0.1/8 dev lo125125+ ip -netns ${n} link set lo up126126+127127+ ip netns exec ${n} sysctl -qw net.ipv4.ip_forward=1128128+ ip netns exec ${n} sysctl -qw net.ipv4.fib_multipath_use_neigh=1129129+ ip netns exec ${n} sysctl -qw net.ipv4.conf.default.ignore_routes_with_linkdown=1130130+ ip netns exec ${n} sysctl -qw net.ipv6.conf.all.keep_addr_on_down=1131131+ ip netns exec ${n} sysctl -qw net.ipv6.conf.all.forwarding=1132132+ ip netns exec ${n} sysctl -qw net.ipv6.conf.default.forwarding=1133133+ ip netns exec ${n} sysctl -qw net.ipv6.conf.default.ignore_routes_with_linkdown=1134134+ ip netns exec ${n} sysctl -qw net.ipv6.conf.all.accept_dad=0135135+ ip netns exec ${n} sysctl -qw net.ipv6.conf.default.accept_dad=0136136+137137+ set +e138138+}139139+140140+setup()141141+{142142+ cleanup143143+144144+ create_ns me145145+ create_ns peer146146+ create_ns remote147147+148148+ IP="ip -netns me"149149+ set -e150150+ $IP li add veth1 type veth peer name veth2151151+ $IP li set veth1 up152152+ $IP addr add 172.16.1.1/24 dev veth1153153+ $IP -6 addr add 2001:db8:91::1/64 dev veth1154154+155155+ $IP li add veth3 type veth peer name veth4156156+ $IP li set veth3 up157157+ $IP addr add 172.16.2.1/24 dev veth3158158+ $IP -6 addr add 2001:db8:92::1/64 dev veth3159159+160160+ $IP li set veth2 netns peer up161161+ ip -netns peer addr add 172.16.1.2/24 dev veth2162162+ ip -netns peer -6 addr add 2001:db8:91::2/64 dev veth2163163+164164+ $IP li set veth4 netns peer up165165+ ip -netns peer addr add 172.16.2.2/24 dev veth4166166+ ip -netns peer -6 addr add 2001:db8:92::2/64 dev veth4167167+168168+ ip -netns remote li add veth5 type veth peer name veth6169169+ ip -netns remote li set veth5 up170170+ ip -netns remote addr add dev veth5 172.16.101.1/24171171+ ip -netns remote addr add dev veth5 2001:db8:101::1/64172172+ ip -netns remote ro add 172.16.0.0/22 via 172.16.101.2173173+ ip -netns remote -6 ro add 2001:db8:90::/40 via 2001:db8:101::2174174+175175+ ip -netns remote li set veth6 netns peer up176176+ ip -netns peer addr add dev veth6 172.16.101.2/24177177+ ip -netns peer addr add dev veth6 2001:db8:101::2/64178178+ set +e179179+}180180+181181+cleanup()182182+{183183+ local ns184184+185185+ for ns in me peer remote; do186186+ ip netns del ${ns} 2>/dev/null187187+ done188188+}189189+190190+check_output()191191+{192192+ local out="$1"193193+ local expected="$2"194194+ local rc=0195195+196196+ [ "${out}" = "${expected}" ] && return 0197197+198198+ if [ -z "${out}" ]; then199199+ if [ "$VERBOSE" = "1" ]; then200200+ printf "\nNo entry found\n"201201+ printf "Expected:\n"202202+ printf " ${expected}\n"203203+ fi204204+ return 1205205+ fi206206+207207+ out=$(echo ${out})208208+ if [ "${out}" != "${expected}" ]; then209209+ rc=1210210+ if [ "${VERBOSE}" = "1" ]; then211211+ printf " Unexpected entry. Have:\n"212212+ printf " ${out}\n"213213+ printf " Expected:\n"214214+ printf " ${expected}\n\n"215215+ fi216216+ fi217217+218218+ return $rc219219+}220220+221221+check_nexthop()222222+{223223+ local nharg="$1"224224+ local expected="$2"225225+ local out226226+227227+ out=$($IP nexthop ls ${nharg} 2>/dev/null)228228+229229+ check_output "${out}" "${expected}"230230+}231231+232232+check_route()233233+{234234+ local pfx="$1"235235+ local expected="$2"236236+ local out237237+238238+ out=$($IP route ls match ${pfx} 2>/dev/null)239239+240240+ check_output "${out}" "${expected}"241241+}242242+243243+check_route6()244244+{245245+ local pfx="$1"246246+ local expected="$2"247247+ local out248248+249249+ out=$($IP -6 route ls match ${pfx} 2>/dev/null)250250+251251+ check_output "${out}" "${expected}"252252+}253253+254254+################################################################################255255+# basic operations (add, delete, replace) on nexthops and nexthop groups256256+#257257+# IPv6258258+259259+ipv6_fcnal()260260+{261261+ local rc262262+263263+ echo264264+ echo "IPv6"265265+ echo "----------------------"266266+267267+ run_cmd "$IP nexthop add id 52 via 2001:db8:91::2 dev veth1"268268+ rc=$?269269+ log_test $rc 0 "Create nexthop with id, gw, dev"270270+ if [ $rc -ne 0 ]; then271271+ echo "Basic IPv6 create fails; can not continue"272272+ return 1273273+ fi274274+275275+ run_cmd "$IP nexthop get id 52"276276+ log_test $? 0 "Get nexthop by id"277277+ check_nexthop "id 52" "id 52 via 2001:db8:91::2 dev veth1"278278+279279+ run_cmd "$IP nexthop del id 52"280280+ log_test $? 0 "Delete nexthop by id"281281+ check_nexthop "id 52" ""282282+283283+ #284284+ # gw, device spec285285+ #286286+ # gw validation, no device - fails since dev required287287+ run_cmd "$IP nexthop add id 52 via 2001:db8:92::3"288288+ log_test $? 2 "Create nexthop - gw only"289289+290290+ # gw is not reachable throught given dev291291+ run_cmd "$IP nexthop add id 53 via 2001:db8:3::3 dev veth1"292292+ log_test $? 2 "Create nexthop - invalid gw+dev combination"293293+294294+ # onlink arg overrides gw+dev lookup295295+ run_cmd "$IP nexthop add id 53 via 2001:db8:3::3 dev veth1 onlink"296296+ log_test $? 0 "Create nexthop - gw+dev and onlink"297297+298298+ # admin down should delete nexthops299299+ set -e300300+ run_cmd "$IP -6 nexthop add id 55 via 2001:db8:91::3 dev veth1"301301+ run_cmd "$IP nexthop add id 56 via 2001:db8:91::4 dev veth1"302302+ run_cmd "$IP nexthop add id 57 via 2001:db8:91::5 dev veth1"303303+ run_cmd "$IP li set dev veth1 down"304304+ set +e305305+ check_nexthop "dev veth1" ""306306+ log_test $? 0 "Nexthops removed on admin down"307307+}308308+309309+ipv6_grp_fcnal()310310+{311311+ local rc312312+313313+ echo314314+ echo "IPv6 groups functional"315315+ echo "----------------------"316316+317317+ # basic functionality: create a nexthop group, default weight318318+ run_cmd "$IP nexthop add id 61 via 2001:db8:91::2 dev veth1"319319+ run_cmd "$IP nexthop add id 101 group 61"320320+ log_test $? 0 "Create nexthop group with single nexthop"321321+322322+ # get nexthop group323323+ run_cmd "$IP nexthop get id 101"324324+ log_test $? 0 "Get nexthop group by id"325325+ check_nexthop "id 101" "id 101 group 61"326326+327327+ # delete nexthop group328328+ run_cmd "$IP nexthop del id 101"329329+ log_test $? 0 "Delete nexthop group by id"330330+ check_nexthop "id 101" ""331331+332332+ $IP nexthop flush >/dev/null 2>&1333333+ check_nexthop "id 101" ""334334+335335+ #336336+ # create group with multiple nexthops - mix of gw and dev only337337+ #338338+ run_cmd "$IP nexthop add id 62 via 2001:db8:91::2 dev veth1"339339+ run_cmd "$IP nexthop add id 63 via 2001:db8:91::3 dev veth1"340340+ run_cmd "$IP nexthop add id 64 via 2001:db8:91::4 dev veth1"341341+ run_cmd "$IP nexthop add id 65 dev veth1"342342+ run_cmd "$IP nexthop add id 102 group 62/63/64/65"343343+ log_test $? 0 "Nexthop group with multiple nexthops"344344+ check_nexthop "id 102" "id 102 group 62/63/64/65"345345+346346+ # Delete nexthop in a group and group is updated347347+ run_cmd "$IP nexthop del id 63"348348+ check_nexthop "id 102" "id 102 group 62/64/65"349349+ log_test $? 0 "Nexthop group updated when entry is deleted"350350+351351+ # create group with multiple weighted nexthops352352+ run_cmd "$IP nexthop add id 63 via 2001:db8:91::3 dev veth1"353353+ run_cmd "$IP nexthop add id 103 group 62/63,2/64,3/65,4"354354+ log_test $? 0 "Nexthop group with weighted nexthops"355355+ check_nexthop "id 103" "id 103 group 62/63,2/64,3/65,4"356356+357357+ # Delete nexthop in a weighted group and group is updated358358+ run_cmd "$IP nexthop del id 63"359359+ check_nexthop "id 103" "id 103 group 62/64,3/65,4"360360+ log_test $? 0 "Weighted nexthop group updated when entry is deleted"361361+362362+ # admin down - nexthop is removed from group363363+ run_cmd "$IP li set dev veth1 down"364364+ check_nexthop "dev veth1" ""365365+ log_test $? 0 "Nexthops in groups removed on admin down"366366+367367+ # expect groups to have been deleted as well368368+ check_nexthop "" ""369369+370370+ run_cmd "$IP li set dev veth1 up"371371+372372+ $IP nexthop flush >/dev/null 2>&1373373+374374+ # group with nexthops using different devices375375+ set -e376376+ run_cmd "$IP nexthop add id 62 via 2001:db8:91::2 dev veth1"377377+ run_cmd "$IP nexthop add id 63 via 2001:db8:91::3 dev veth1"378378+ run_cmd "$IP nexthop add id 64 via 2001:db8:91::4 dev veth1"379379+ run_cmd "$IP nexthop add id 65 via 2001:db8:91::5 dev veth1"380380+381381+ run_cmd "$IP nexthop add id 72 via 2001:db8:92::2 dev veth3"382382+ run_cmd "$IP nexthop add id 73 via 2001:db8:92::3 dev veth3"383383+ run_cmd "$IP nexthop add id 74 via 2001:db8:92::4 dev veth3"384384+ run_cmd "$IP nexthop add id 75 via 2001:db8:92::5 dev veth3"385385+ set +e386386+387387+ # multiple groups with same nexthop388388+ run_cmd "$IP nexthop add id 104 group 62"389389+ run_cmd "$IP nexthop add id 105 group 62"390390+ check_nexthop "group" "id 104 group 62 id 105 group 62"391391+ log_test $? 0 "Multiple groups with same nexthop"392392+393393+ run_cmd "$IP nexthop flush groups"394394+ [ $? -ne 0 ] && return 1395395+396396+ # on admin down of veth1, it should be removed from the group397397+ run_cmd "$IP nexthop add id 105 group 62/63/72/73/64"398398+ run_cmd "$IP li set veth1 down"399399+ check_nexthop "id 105" "id 105 group 72/73"400400+ log_test $? 0 "Nexthops in group removed on admin down - mixed group"401401+402402+ run_cmd "$IP nexthop add id 106 group 105/74"403403+ log_test $? 2 "Nexthop group can not have a group as an entry"404404+405405+ # a group can have a blackhole entry only if it is the only406406+ # nexthop in the group. Needed for atomic replace with an407407+ # actual nexthop group408408+ run_cmd "$IP -6 nexthop add id 31 blackhole"409409+ run_cmd "$IP nexthop add id 107 group 31"410410+ log_test $? 0 "Nexthop group with a blackhole entry"411411+412412+ run_cmd "$IP nexthop add id 108 group 31/24"413413+ log_test $? 2 "Nexthop group can not have a blackhole and another nexthop"414414+}415415+416416+ipv6_fcnal_runtime()417417+{418418+ local rc419419+420420+ echo421421+ echo "IPv6 functional runtime"422422+ echo "-----------------------"423423+424424+ sleep 5425425+426426+ #427427+ # IPv6 - the basics428428+ #429429+ run_cmd "$IP nexthop add id 81 via 2001:db8:91::2 dev veth1"430430+ run_cmd "$IP ro add 2001:db8:101::1/128 nhid 81"431431+ log_test $? 0 "Route add"432432+433433+ run_cmd "$IP ro delete 2001:db8:101::1/128 nhid 81"434434+ log_test $? 0 "Route delete"435435+436436+ run_cmd "$IP ro add 2001:db8:101::1/128 nhid 81"437437+ run_cmd "ip netns exec me ping -c1 -w1 2001:db8:101::1"438438+ log_test $? 0 "Ping with nexthop"439439+440440+ run_cmd "$IP nexthop add id 82 via 2001:db8:92::2 dev veth3"441441+ run_cmd "$IP nexthop add id 122 group 81/82"442442+ run_cmd "$IP ro replace 2001:db8:101::1/128 nhid 122"443443+ run_cmd "ip netns exec me ping -c1 -w1 2001:db8:101::1"444444+ log_test $? 0 "Ping - multipath"445445+446446+ #447447+ # IPv6 with blackhole nexthops448448+ #449449+ run_cmd "$IP -6 nexthop add id 83 blackhole"450450+ run_cmd "$IP ro replace 2001:db8:101::1/128 nhid 83"451451+ run_cmd "ip netns exec me ping -c1 -w1 2001:db8:101::1"452452+ log_test $? 2 "Ping - blackhole"453453+454454+ run_cmd "$IP nexthop replace id 83 via 2001:db8:91::2 dev veth1"455455+ run_cmd "ip netns exec me ping -c1 -w1 2001:db8:101::1"456456+ log_test $? 0 "Ping - blackhole replaced with gateway"457457+458458+ run_cmd "$IP -6 nexthop replace id 83 blackhole"459459+ run_cmd "ip netns exec me ping -c1 -w1 2001:db8:101::1"460460+ log_test $? 2 "Ping - gateway replaced by blackhole"461461+462462+ run_cmd "$IP ro replace 2001:db8:101::1/128 nhid 122"463463+ run_cmd "ip netns exec me ping -c1 -w1 2001:db8:101::1"464464+ if [ $? -eq 0 ]; then465465+ run_cmd "$IP nexthop replace id 122 group 83"466466+ run_cmd "ip netns exec me ping -c1 -w1 2001:db8:101::1"467467+ log_test $? 2 "Ping - group with blackhole"468468+469469+ run_cmd "$IP nexthop replace id 122 group 81/82"470470+ run_cmd "ip netns exec me ping -c1 -w1 2001:db8:101::1"471471+ log_test $? 0 "Ping - group blackhole replaced with gateways"472472+ else473473+ log_test 2 0 "Ping - multipath failed"474474+ fi475475+476476+ #477477+ # device only and gw + dev only mix478478+ #479479+ run_cmd "$IP -6 nexthop add id 85 dev veth1"480480+ run_cmd "$IP ro replace 2001:db8:101::1/128 nhid 85"481481+ log_test $? 0 "IPv6 route with device only nexthop"482482+ check_route6 "2001:db8:101::1" "2001:db8:101::1 nhid 85 dev veth1"483483+484484+ run_cmd "$IP nexthop add id 123 group 81/85"485485+ run_cmd "$IP ro replace 2001:db8:101::1/128 nhid 123"486486+ log_test $? 0 "IPv6 multipath route with nexthop mix - dev only + gw"487487+ check_route6 "2001:db8:101::1" "2001:db8:101::1 nhid 85 nexthop via 2001:db8:91::2 dev veth1 nexthop dev veth1"488488+489489+ #490490+ # IPv6 route with v4 nexthop - not allowed491491+ #492492+ run_cmd "$IP ro delete 2001:db8:101::1/128"493493+ run_cmd "$IP nexthop add id 84 via 172.16.1.1 dev veth1"494494+ run_cmd "$IP ro add 2001:db8:101::1/128 nhid 84"495495+ log_test $? 2 "IPv6 route can not have a v4 gateway"496496+497497+ run_cmd "$IP ro replace 2001:db8:101::1/128 nhid 81"498498+ run_cmd "$IP nexthop replace id 81 via 172.16.1.1 dev veth1"499499+ log_test $? 2 "Nexthop replace - v6 route, v4 nexthop"500500+501501+ run_cmd "$IP ro replace 2001:db8:101::1/128 nhid 122"502502+ run_cmd "$IP nexthop replace id 81 via 172.16.1.1 dev veth1"503503+ log_test $? 2 "Nexthop replace of group entry - v6 route, v4 nexthop"504504+505505+ $IP nexthop flush >/dev/null 2>&1506506+507507+ #508508+ # weird IPv6 cases509509+ #510510+ run_cmd "$IP nexthop add id 86 via 2001:db8:91::2 dev veth1"511511+ run_cmd "$IP ro add 2001:db8:101::1/128 nhid 81"512512+513513+ # TO-DO:514514+ # existing route with old nexthop; append route with new nexthop515515+ # existing route with old nexthop; replace route with new516516+ # existing route with new nexthop; replace route with old517517+ # route with src address and using nexthop - not allowed518518+}519519+520520+ipv4_fcnal()521521+{522522+ local rc523523+524524+ echo525525+ echo "IPv4 functional"526526+ echo "----------------------"527527+528528+ #529529+ # basic IPv4 ops - add, get, delete530530+ #531531+ run_cmd "$IP nexthop add id 12 via 172.16.1.2 dev veth1"532532+ rc=$?533533+ log_test $rc 0 "Create nexthop with id, gw, dev"534534+ if [ $rc -ne 0 ]; then535535+ echo "Basic IPv4 create fails; can not continue"536536+ return 1537537+ fi538538+539539+ run_cmd "$IP nexthop get id 12"540540+ log_test $? 0 "Get nexthop by id"541541+ check_nexthop "id 12" "id 12 via 172.16.1.2 src 172.16.1.1 dev veth1 scope link"542542+543543+ run_cmd "$IP nexthop del id 12"544544+ log_test $? 0 "Delete nexthop by id"545545+ check_nexthop "id 52" ""546546+547547+ #548548+ # gw, device spec549549+ #550550+ # gw validation, no device - fails since dev is required551551+ run_cmd "$IP nexthop add id 12 via 172.16.2.3"552552+ log_test $? 2 "Create nexthop - gw only"553553+554554+ # gw not reachable through given dev555555+ run_cmd "$IP nexthop add id 13 via 172.16.3.2 dev veth1"556556+ log_test $? 2 "Create nexthop - invalid gw+dev combination"557557+558558+ # onlink flag overrides gw+dev lookup559559+ run_cmd "$IP nexthop add id 13 via 172.16.3.2 dev veth1 onlink"560560+ log_test $? 0 "Create nexthop - gw+dev and onlink"561561+562562+ # admin down should delete nexthops563563+ set -e564564+ run_cmd "$IP nexthop add id 15 via 172.16.1.3 dev veth1"565565+ run_cmd "$IP nexthop add id 16 via 172.16.1.4 dev veth1"566566+ run_cmd "$IP nexthop add id 17 via 172.16.1.5 dev veth1"567567+ run_cmd "$IP li set dev veth1 down"568568+ set +e569569+ check_nexthop "dev veth1" ""570570+ log_test $? 0 "Nexthops removed on admin down"571571+}572572+573573+ipv4_grp_fcnal()574574+{575575+ local rc576576+577577+ echo578578+ echo "IPv4 groups functional"579579+ echo "----------------------"580580+581581+ # basic functionality: create a nexthop group, default weight582582+ run_cmd "$IP nexthop add id 11 via 172.16.1.2 dev veth1"583583+ run_cmd "$IP nexthop add id 101 group 11"584584+ log_test $? 0 "Create nexthop group with single nexthop"585585+586586+ # get nexthop group587587+ run_cmd "$IP nexthop get id 101"588588+ log_test $? 0 "Get nexthop group by id"589589+ check_nexthop "id 101" "id 101 group 11"590590+591591+ # delete nexthop group592592+ run_cmd "$IP nexthop del id 101"593593+ log_test $? 0 "Delete nexthop group by id"594594+ check_nexthop "id 101" ""595595+596596+ $IP nexthop flush >/dev/null 2>&1597597+598598+ #599599+ # create group with multiple nexthops600600+ run_cmd "$IP nexthop add id 12 via 172.16.1.2 dev veth1"601601+ run_cmd "$IP nexthop add id 13 via 172.16.1.3 dev veth1"602602+ run_cmd "$IP nexthop add id 14 via 172.16.1.4 dev veth1"603603+ run_cmd "$IP nexthop add id 15 via 172.16.1.5 dev veth1"604604+ run_cmd "$IP nexthop add id 102 group 12/13/14/15"605605+ log_test $? 0 "Nexthop group with multiple nexthops"606606+ check_nexthop "id 102" "id 102 group 12/13/14/15"607607+608608+ # Delete nexthop in a group and group is updated609609+ run_cmd "$IP nexthop del id 13"610610+ check_nexthop "id 102" "id 102 group 12/14/15"611611+ log_test $? 0 "Nexthop group updated when entry is deleted"612612+613613+ # create group with multiple weighted nexthops614614+ run_cmd "$IP nexthop add id 13 via 172.16.1.3 dev veth1"615615+ run_cmd "$IP nexthop add id 103 group 12/13,2/14,3/15,4"616616+ log_test $? 0 "Nexthop group with weighted nexthops"617617+ check_nexthop "id 103" "id 103 group 12/13,2/14,3/15,4"618618+619619+ # Delete nexthop in a weighted group and group is updated620620+ run_cmd "$IP nexthop del id 13"621621+ check_nexthop "id 103" "id 103 group 12/14,3/15,4"622622+ log_test $? 0 "Weighted nexthop group updated when entry is deleted"623623+624624+ # admin down - nexthop is removed from group625625+ run_cmd "$IP li set dev veth1 down"626626+ check_nexthop "dev veth1" ""627627+ log_test $? 0 "Nexthops in groups removed on admin down"628628+629629+ # expect groups to have been deleted as well630630+ check_nexthop "" ""631631+632632+ run_cmd "$IP li set dev veth1 up"633633+634634+ $IP nexthop flush >/dev/null 2>&1635635+636636+ # group with nexthops using different devices637637+ set -e638638+ run_cmd "$IP nexthop add id 12 via 172.16.1.2 dev veth1"639639+ run_cmd "$IP nexthop add id 13 via 172.16.1.3 dev veth1"640640+ run_cmd "$IP nexthop add id 14 via 172.16.1.4 dev veth1"641641+ run_cmd "$IP nexthop add id 15 via 172.16.1.5 dev veth1"642642+643643+ run_cmd "$IP nexthop add id 22 via 172.16.2.2 dev veth3"644644+ run_cmd "$IP nexthop add id 23 via 172.16.2.3 dev veth3"645645+ run_cmd "$IP nexthop add id 24 via 172.16.2.4 dev veth3"646646+ run_cmd "$IP nexthop add id 25 via 172.16.2.5 dev veth3"647647+ set +e648648+649649+ # multiple groups with same nexthop650650+ run_cmd "$IP nexthop add id 104 group 12"651651+ run_cmd "$IP nexthop add id 105 group 12"652652+ check_nexthop "group" "id 104 group 12 id 105 group 12"653653+ log_test $? 0 "Multiple groups with same nexthop"654654+655655+ run_cmd "$IP nexthop flush groups"656656+ [ $? -ne 0 ] && return 1657657+658658+ # on admin down of veth1, it should be removed from the group659659+ run_cmd "$IP nexthop add id 105 group 12/13/22/23/14"660660+ run_cmd "$IP li set veth1 down"661661+ check_nexthop "id 105" "id 105 group 22/23"662662+ log_test $? 0 "Nexthops in group removed on admin down - mixed group"663663+664664+ run_cmd "$IP nexthop add id 106 group 105/24"665665+ log_test $? 2 "Nexthop group can not have a group as an entry"666666+667667+ # a group can have a blackhole entry only if it is the only668668+ # nexthop in the group. Needed for atomic replace with an669669+ # actual nexthop group670670+ run_cmd "$IP nexthop add id 31 blackhole"671671+ run_cmd "$IP nexthop add id 107 group 31"672672+ log_test $? 0 "Nexthop group with a blackhole entry"673673+674674+ run_cmd "$IP nexthop add id 108 group 31/24"675675+ log_test $? 2 "Nexthop group can not have a blackhole and another nexthop"676676+}677677+678678+ipv4_withv6_fcnal()679679+{680680+ local lladdr681681+682682+ set -e683683+ lladdr=$(get_linklocal veth2 peer)684684+ run_cmd "$IP nexthop add id 11 via ${lladdr} dev veth1"685685+ set +e686686+ run_cmd "$IP ro add 172.16.101.1/32 nhid 11"687687+ log_test $? 0 "IPv6 nexthop with IPv4 route"688688+ check_route "172.16.101.1" "172.16.101.1 nhid 11 via ${lladdr} dev veth1"689689+690690+ set -e691691+ run_cmd "$IP nexthop add id 12 via 172.16.1.2 dev veth1"692692+ run_cmd "$IP nexthop add id 101 group 11/12"693693+ set +e694694+ run_cmd "$IP ro replace 172.16.101.1/32 nhid 101"695695+ log_test $? 0 "IPv6 nexthop with IPv4 route"696696+697697+ check_route "172.16.101.1" "172.16.101.1 nhid 101 nexthop via ${lladdr} dev veth1 weight 1 nexthop via 172.16.1.2 dev veth1 weight 1"698698+699699+ run_cmd "$IP ro replace 172.16.101.1/32 via inet6 ${lladdr} dev veth1"700700+ log_test $? 0 "IPv4 route with IPv6 gateway"701701+ check_route "172.16.101.1" "172.16.101.1 via ${lladdr} dev veth1"702702+703703+ run_cmd "$IP ro replace 172.16.101.1/32 via inet6 2001:db8:50::1 dev veth1"704704+ log_test $? 2 "IPv4 route with invalid IPv6 gateway"705705+}706706+707707+ipv4_fcnal_runtime()708708+{709709+ local lladdr710710+ local rc711711+712712+ echo713713+ echo "IPv4 functional runtime"714714+ echo "-----------------------"715715+716716+ run_cmd "$IP nexthop add id 21 via 172.16.1.2 dev veth1"717717+ run_cmd "$IP ro add 172.16.101.1/32 nhid 21"718718+ log_test $? 0 "Route add"719719+ check_route "172.16.101.1" "172.16.101.1 nhid 21 via 172.16.1.2 dev veth1"720720+721721+ run_cmd "$IP ro delete 172.16.101.1/32 nhid 21"722722+ log_test $? 0 "Route delete"723723+724724+ #725725+ # scope mismatch726726+ #727727+ run_cmd "$IP nexthop add id 22 via 172.16.1.2 dev veth1"728728+ run_cmd "$IP ro add 172.16.101.1/32 nhid 22 scope host"729729+ log_test $? 2 "Route add - scope conflict with nexthop"730730+731731+ run_cmd "$IP nexthop replace id 22 dev veth3"732732+ run_cmd "$IP ro add 172.16.101.1/32 nhid 22 scope host"733733+ run_cmd "$IP nexthop replace id 22 via 172.16.2.2 dev veth3"734734+ log_test $? 2 "Nexthop replace with invalid scope for existing route"735735+736736+ #737737+ # add route with nexthop and check traffic738738+ #739739+ run_cmd "$IP nexthop replace id 21 via 172.16.1.2 dev veth1"740740+ run_cmd "$IP ro replace 172.16.101.1/32 nhid 21"741741+ run_cmd "ip netns exec me ping -c1 -w1 172.16.101.1"742742+ log_test $? 0 "Basic ping"743743+744744+ run_cmd "$IP nexthop replace id 22 via 172.16.2.2 dev veth3"745745+ run_cmd "$IP nexthop add id 122 group 21/22"746746+ run_cmd "$IP ro replace 172.16.101.1/32 nhid 122"747747+ run_cmd "ip netns exec me ping -c1 -w1 172.16.101.1"748748+ log_test $? 0 "Ping - multipath"749749+750750+ #751751+ # IPv4 with blackhole nexthops752752+ #753753+ run_cmd "$IP nexthop add id 23 blackhole"754754+ run_cmd "$IP ro replace 172.16.101.1/32 nhid 23"755755+ run_cmd "ip netns exec me ping -c1 -w1 172.16.101.1"756756+ log_test $? 2 "Ping - blackhole"757757+758758+ run_cmd "$IP nexthop replace id 23 via 172.16.1.2 dev veth1"759759+ run_cmd "ip netns exec me ping -c1 -w1 172.16.101.1"760760+ log_test $? 0 "Ping - blackhole replaced with gateway"761761+762762+ run_cmd "$IP nexthop replace id 23 blackhole"763763+ run_cmd "ip netns exec me ping -c1 -w1 172.16.101.1"764764+ log_test $? 2 "Ping - gateway replaced by blackhole"765765+766766+ run_cmd "$IP ro replace 172.16.101.1/32 nhid 122"767767+ run_cmd "ip netns exec me ping -c1 -w1 172.16.101.1"768768+ if [ $? -eq 0 ]; then769769+ run_cmd "$IP nexthop replace id 122 group 23"770770+ run_cmd "ip netns exec me ping -c1 -w1 172.16.101.1"771771+ log_test $? 2 "Ping - group with blackhole"772772+773773+ run_cmd "$IP nexthop replace id 122 group 21/22"774774+ run_cmd "ip netns exec me ping -c1 -w1 172.16.101.1"775775+ log_test $? 0 "Ping - group blackhole replaced with gateways"776776+ else777777+ log_test 2 0 "Ping - multipath failed"778778+ fi779779+780780+ #781781+ # device only and gw + dev only mix782782+ #783783+ run_cmd "$IP nexthop add id 85 dev veth1"784784+ run_cmd "$IP ro replace 172.16.101.1/32 nhid 85"785785+ log_test $? 0 "IPv4 route with device only nexthop"786786+ check_route "172.16.101.1" "172.16.101.1 nhid 85 dev veth1"787787+788788+ run_cmd "$IP nexthop add id 122 group 21/85"789789+ run_cmd "$IP ro replace 172.16.101.1/32 nhid 122"790790+ log_test $? 0 "IPv4 multipath route with nexthop mix - dev only + gw"791791+ check_route "172.16.101.1" "172.16.101.1 nhid 85 nexthop via 172.16.1.2 dev veth1 nexthop dev veth1"792792+793793+ #794794+ # IPv4 with IPv6795795+ #796796+ set -e797797+ lladdr=$(get_linklocal veth2 peer)798798+ run_cmd "$IP nexthop add id 24 via ${lladdr} dev veth1"799799+ set +e800800+ run_cmd "$IP ro replace 172.16.101.1/32 nhid 24"801801+ run_cmd "ip netns exec me ping -c1 -w1 172.16.101.1"802802+ log_test $? 0 "IPv6 nexthop with IPv4 route"803803+804804+ $IP neigh sh | grep -q "${lladdr} dev veth1"805805+ if [ $? -eq 1 ]; then806806+ echo " WARNING: Neigh entry missing for ${lladdr}"807807+ $IP neigh sh | grep 'dev veth1'808808+ fi809809+810810+ $IP neigh sh | grep -q "172.16.101.1 dev eth1"811811+ if [ $? -eq 0 ]; then812812+ echo " WARNING: Neigh entry exists for 172.16.101.1"813813+ $IP neigh sh | grep 'dev veth1'814814+ fi815815+816816+ set -e817817+ run_cmd "$IP nexthop add id 25 via 172.16.1.2 dev veth1"818818+ run_cmd "$IP nexthop add id 101 group 24/25"819819+ set +e820820+ run_cmd "$IP ro replace 172.16.101.1/32 nhid 101"821821+ log_test $? 0 "IPv4 route with mixed v4-v6 multipath route"822822+823823+ check_route "172.16.101.1" "172.16.101.1 nhid 101 nexthop via ${lladdr} dev veth1 weight 1 nexthop via 172.16.1.2 dev veth1 weight 1"824824+825825+ run_cmd "ip netns exec me ping -c1 -w1 172.16.101.1"826826+ log_test $? 0 "IPv6 nexthop with IPv4 route"827827+828828+ run_cmd "$IP ro replace 172.16.101.1/32 via inet6 ${lladdr} dev veth1"829829+ run_cmd "ip netns exec me ping -c1 -w1 172.16.101.1"830830+ log_test $? 0 "IPv4 route with IPv6 gateway"831831+832832+ $IP neigh sh | grep -q "${lladdr} dev veth1"833833+ if [ $? -eq 1 ]; then834834+ echo " WARNING: Neigh entry missing for ${lladdr}"835835+ $IP neigh sh | grep 'dev veth1'836836+ fi837837+838838+ $IP neigh sh | grep -q "172.16.101.1 dev eth1"839839+ if [ $? -eq 0 ]; then840840+ echo " WARNING: Neigh entry exists for 172.16.101.1"841841+ $IP neigh sh | grep 'dev veth1'842842+ fi843843+844844+ #845845+ # MPLS as an example of LWT encap846846+ #847847+ run_cmd "$IP nexthop add id 51 encap mpls 101 via 172.16.1.2 dev veth1"848848+ log_test $? 0 "IPv4 route with MPLS encap"849849+ check_nexthop "id 51" "id 51 encap mpls 101 via 172.16.1.2 dev veth1 scope link"850850+ log_test $? 0 "IPv4 route with MPLS encap - check"851851+852852+ run_cmd "$IP nexthop add id 52 encap mpls 102 via inet6 2001:db8:91::2 dev veth1"853853+ log_test $? 0 "IPv4 route with MPLS encap and v6 gateway"854854+ check_nexthop "id 52" "id 52 encap mpls 102 via 2001:db8:91::2 dev veth1 scope link"855855+ log_test $? 0 "IPv4 route with MPLS encap, v6 gw - check"856856+}857857+858858+basic()859859+{860860+ echo861861+ echo "Basic functional tests"862862+ echo "----------------------"863863+ run_cmd "$IP nexthop ls"864864+ log_test $? 0 "List with nothing defined"865865+866866+ run_cmd "$IP nexthop get id 1"867867+ log_test $? 2 "Nexthop get on non-existent id"868868+869869+ # attempt to create nh without a device or gw - fails870870+ run_cmd "$IP nexthop add id 1"871871+ log_test $? 2 "Nexthop with no device or gateway"872872+873873+ # attempt to create nh with down device - fails874874+ $IP li set veth1 down875875+ run_cmd "$IP nexthop add id 1 dev veth1"876876+ log_test $? 2 "Nexthop with down device"877877+878878+ # create nh with linkdown device - fails879879+ $IP li set veth1 up880880+ ip -netns peer li set veth2 down881881+ run_cmd "$IP nexthop add id 1 dev veth1"882882+ log_test $? 2 "Nexthop with device that is linkdown"883883+ ip -netns peer li set veth2 up884884+885885+ # device only886886+ run_cmd "$IP nexthop add id 1 dev veth1"887887+ log_test $? 0 "Nexthop with device only"888888+889889+ # create nh with duplicate id890890+ run_cmd "$IP nexthop add id 1 dev veth3"891891+ log_test $? 2 "Nexthop with duplicate id"892892+893893+ # blackhole nexthop894894+ run_cmd "$IP nexthop add id 2 blackhole"895895+ log_test $? 0 "Blackhole nexthop"896896+897897+ # blackhole nexthop can not have other specs898898+ run_cmd "$IP nexthop replace id 2 blackhole dev veth1"899899+ log_test $? 2 "Blackhole nexthop with other attributes"900900+901901+ #902902+ # groups903903+ #904904+905905+ run_cmd "$IP nexthop add id 101 group 1"906906+ log_test $? 0 "Create group"907907+908908+ run_cmd "$IP nexthop add id 102 group 2"909909+ log_test $? 0 "Create group with blackhole nexthop"910910+911911+ # multipath group can not have a blackhole as 1 path912912+ run_cmd "$IP nexthop add id 103 group 1/2"913913+ log_test $? 2 "Create multipath group where 1 path is a blackhole"914914+915915+ # multipath group can not have a member replaced by a blackhole916916+ run_cmd "$IP nexthop replace id 2 dev veth3"917917+ run_cmd "$IP nexthop replace id 102 group 1/2"918918+ run_cmd "$IP nexthop replace id 2 blackhole"919919+ log_test $? 2 "Multipath group can not have a member replaced by blackhole"920920+921921+ # attempt to create group with non-existent nexthop922922+ run_cmd "$IP nexthop add id 103 group 12"923923+ log_test $? 2 "Create group with non-existent nexthop"924924+925925+ # attempt to create group with same nexthop926926+ run_cmd "$IP nexthop add id 103 group 1/1"927927+ log_test $? 2 "Create group with same nexthop multiple times"928928+929929+ # replace nexthop with a group - fails930930+ run_cmd "$IP nexthop replace id 2 group 1"931931+ log_test $? 2 "Replace nexthop with nexthop group"932932+933933+ # replace nexthop group with a nexthop - fails934934+ run_cmd "$IP nexthop replace id 101 dev veth1"935935+ log_test $? 2 "Replace nexthop group with nexthop"936936+937937+ # nexthop group with other attributes fail938938+ run_cmd "$IP nexthop add id 104 group 1 dev veth1"939939+ log_test $? 2 "Nexthop group and device"940940+941941+ run_cmd "$IP nexthop add id 104 group 1 blackhole"942942+ log_test $? 2 "Nexthop group and blackhole"943943+944944+ $IP nexthop flush >/dev/null 2>&1945945+}946946+947947+################################################################################948948+# usage949949+950950+usage()951951+{952952+ cat <<EOF953953+usage: ${0##*/} OPTS954954+955955+ -t <test> Test(s) to run (default: all)956956+ (options: $ALL_TESTS)957957+ -4 IPv4 tests only958958+ -6 IPv6 tests only959959+ -p Pause on fail960960+ -P Pause after each test before cleanup961961+ -v verbose mode (show commands and output)962962+963963+ Runtime test964964+ -n num Number of nexthops to target965965+ -N Use new style to install routes in DUT966966+967967+done968968+EOF969969+}970970+971971+################################################################################972972+# main973973+974974+while getopts :t:pP46hv o975975+do976976+ case $o in977977+ t) TESTS=$OPTARG;;978978+ 4) TESTS=${IPV4_TESTS};;979979+ 6) TESTS=${IPV6_TESTS};;980980+ p) PAUSE_ON_FAIL=yes;;981981+ P) PAUSE=yes;;982982+ v) VERBOSE=$(($VERBOSE + 1));;983983+ h) usage; exit 0;;984984+ *) usage; exit 1;;985985+ esac986986+done987987+988988+# make sure we don't pause twice989989+[ "${PAUSE}" = "yes" ] && PAUSE_ON_FAIL=no990990+991991+if [ "$(id -u)" -ne 0 ];then992992+ echo "SKIP: Need root privileges"993993+ exit $ksft_skip;994994+fi995995+996996+if [ ! -x "$(command -v ip)" ]; then997997+ echo "SKIP: Could not run test without ip tool"998998+ exit $ksft_skip999999+fi10001000+10011001+ip help 2>&1 | grep -q nexthop10021002+if [ $? -ne 0 ]; then10031003+ echo "SKIP: iproute2 too old, missing nexthop command"10041004+ exit $ksft_skip10051005+fi10061006+10071007+out=$(ip nexthop ls 2>&1 | grep -q "Operation not supported")10081008+if [ $? -eq 0 ]; then10091009+ echo "SKIP: kernel lacks nexthop support"10101010+ exit $ksft_skip10111011+fi10121012+10131013+for t in $TESTS10141014+do10151015+ case $t in10161016+ none) IP="ip -netns peer"; setup; exit 0;;10171017+ *) setup; $t; cleanup;;10181018+ esac10191019+done10201020+10211021+if [ "$TESTS" != "none" ]; then10221022+ printf "\nTests passed: %3d\n" ${nsuccess}10231023+ printf "Tests failed: %3d\n" ${nfail}10241024+fi10251025+10261026+exit $ret