fib_nexthops.sh 77 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602
  1. #!/bin/bash
  2. # SPDX-License-Identifier: GPL-2.0
  3. #
  4. # ns: me | ns: peer | ns: remote
  5. # 2001:db8:91::1 | 2001:db8:91::2 |
  6. # 172.16.1.1 | 172.16.1.2 |
  7. # veth1 <---|---> veth2 |
  8. # | veth5 <--|--> veth6 172.16.101.1
  9. # veth3 <---|---> veth4 | 2001:db8:101::1
  10. # 172.16.2.1 | 172.16.2.2 |
  11. # 2001:db8:92::1 | 2001:db8:92::2 |
  12. #
  13. # This test is for checking IPv4 and IPv6 FIB behavior with nexthop
  14. # objects. Device reference counts and network namespace cleanup tested
  15. # by use of network namespace for peer.
  16. source lib.sh
  17. ret=0
  18. # Kselftest framework requirement - SKIP code is 4.
  19. ksft_skip=4
  20. # all tests in this script. Can be overridden with -t option
  21. IPV4_TESTS="
  22. ipv4_fcnal
  23. ipv4_grp_fcnal
  24. ipv4_res_grp_fcnal
  25. ipv4_withv6_fcnal
  26. ipv4_fcnal_runtime
  27. ipv4_large_grp
  28. ipv4_large_res_grp
  29. ipv4_compat_mode
  30. ipv4_fdb_grp_fcnal
  31. ipv4_mpath_select
  32. ipv4_torture
  33. ipv4_res_torture
  34. "
  35. IPV6_TESTS="
  36. ipv6_fcnal
  37. ipv6_grp_fcnal
  38. ipv6_res_grp_fcnal
  39. ipv6_fcnal_runtime
  40. ipv6_large_grp
  41. ipv6_large_res_grp
  42. ipv6_compat_mode
  43. ipv6_fdb_grp_fcnal
  44. ipv6_mpath_select
  45. ipv6_torture
  46. ipv6_res_torture
  47. "
  48. ALL_TESTS="
  49. basic
  50. basic_res
  51. ${IPV4_TESTS}
  52. ${IPV6_TESTS}
  53. "
  54. TESTS="${ALL_TESTS}"
  55. VERBOSE=0
  56. PAUSE_ON_FAIL=no
  57. PAUSE=no
  58. PING_TIMEOUT=5
  59. nsid=100
  60. ################################################################################
  61. # utilities
  62. log_test()
  63. {
  64. local rc=$1
  65. local expected=$2
  66. local msg="$3"
  67. if [ ${rc} -eq ${expected} ]; then
  68. printf "TEST: %-60s [ OK ]\n" "${msg}"
  69. nsuccess=$((nsuccess+1))
  70. else
  71. if [[ $rc -eq $ksft_skip ]]; then
  72. [[ $ret -eq 0 ]] && ret=$ksft_skip
  73. nskip=$((nskip+1))
  74. printf "TEST: %-60s [SKIP]\n" "${msg}"
  75. else
  76. ret=1
  77. nfail=$((nfail+1))
  78. printf "TEST: %-60s [FAIL]\n" "${msg}"
  79. fi
  80. if [ "$VERBOSE" = "1" ]; then
  81. echo " rc=$rc, expected $expected"
  82. fi
  83. if [ "${PAUSE_ON_FAIL}" = "yes" ]; then
  84. echo
  85. echo "hit enter to continue, 'q' to quit"
  86. read a
  87. [ "$a" = "q" ] && exit 1
  88. fi
  89. fi
  90. if [ "${PAUSE}" = "yes" ]; then
  91. echo
  92. echo "hit enter to continue, 'q' to quit"
  93. read a
  94. [ "$a" = "q" ] && exit 1
  95. fi
  96. [ "$VERBOSE" = "1" ] && echo
  97. }
  98. run_cmd()
  99. {
  100. local cmd="$1"
  101. local out
  102. local stderr="2>/dev/null"
  103. if [ "$VERBOSE" = "1" ]; then
  104. printf "COMMAND: $cmd\n"
  105. stderr=
  106. fi
  107. out=$(eval $cmd $stderr)
  108. rc=$?
  109. if [ "$VERBOSE" = "1" -a -n "$out" ]; then
  110. echo " $out"
  111. fi
  112. return $rc
  113. }
  114. get_linklocal()
  115. {
  116. local dev=$1
  117. local ns
  118. local addr
  119. [ -n "$2" ] && ns="-netns $2"
  120. addr=$(ip $ns -6 -br addr show dev ${dev} | \
  121. awk '{
  122. for (i = 3; i <= NF; ++i) {
  123. if ($i ~ /^fe80/)
  124. print $i
  125. }
  126. }'
  127. )
  128. addr=${addr/\/*}
  129. [ -z "$addr" ] && return 1
  130. echo $addr
  131. return 0
  132. }
  133. create_ns()
  134. {
  135. local n=${1}
  136. set -e
  137. ip netns exec ${n} sysctl -qw net.ipv4.ip_forward=1
  138. ip netns exec ${n} sysctl -qw net.ipv4.fib_multipath_use_neigh=1
  139. ip netns exec ${n} sysctl -qw net.ipv4.conf.default.ignore_routes_with_linkdown=1
  140. ip netns exec ${n} sysctl -qw net.ipv6.conf.all.keep_addr_on_down=1
  141. ip netns exec ${n} sysctl -qw net.ipv6.conf.all.forwarding=1
  142. ip netns exec ${n} sysctl -qw net.ipv6.conf.default.forwarding=1
  143. ip netns exec ${n} sysctl -qw net.ipv6.conf.default.ignore_routes_with_linkdown=1
  144. ip netns exec ${n} sysctl -qw net.ipv6.conf.all.accept_dad=0
  145. ip netns exec ${n} sysctl -qw net.ipv6.conf.default.accept_dad=0
  146. set +e
  147. }
  148. setup()
  149. {
  150. cleanup
  151. setup_ns me peer remote
  152. create_ns $me
  153. create_ns $peer
  154. create_ns $remote
  155. IP="ip -netns $me"
  156. BRIDGE="bridge -netns $me"
  157. set -e
  158. $IP li add veth1 type veth peer name veth2
  159. $IP li set veth1 up
  160. $IP addr add 172.16.1.1/24 dev veth1
  161. $IP -6 addr add 2001:db8:91::1/64 dev veth1 nodad
  162. $IP li add veth3 type veth peer name veth4
  163. $IP li set veth3 up
  164. $IP addr add 172.16.2.1/24 dev veth3
  165. $IP -6 addr add 2001:db8:92::1/64 dev veth3 nodad
  166. $IP li set veth2 netns $peer up
  167. ip -netns $peer addr add 172.16.1.2/24 dev veth2
  168. ip -netns $peer -6 addr add 2001:db8:91::2/64 dev veth2 nodad
  169. $IP li set veth4 netns $peer up
  170. ip -netns $peer addr add 172.16.2.2/24 dev veth4
  171. ip -netns $peer -6 addr add 2001:db8:92::2/64 dev veth4 nodad
  172. ip -netns $remote li add veth5 type veth peer name veth6
  173. ip -netns $remote li set veth5 up
  174. ip -netns $remote addr add dev veth5 172.16.101.1/24
  175. ip -netns $remote -6 addr add dev veth5 2001:db8:101::1/64 nodad
  176. ip -netns $remote ro add 172.16.0.0/22 via 172.16.101.2
  177. ip -netns $remote -6 ro add 2001:db8:90::/40 via 2001:db8:101::2
  178. ip -netns $remote li set veth6 netns $peer up
  179. ip -netns $peer addr add dev veth6 172.16.101.2/24
  180. ip -netns $peer -6 addr add dev veth6 2001:db8:101::2/64 nodad
  181. set +e
  182. }
  183. cleanup()
  184. {
  185. local ns
  186. for ns in $me $peer $remote; do
  187. ip netns del ${ns} 2>/dev/null
  188. done
  189. }
  190. check_output()
  191. {
  192. local out="$1"
  193. local expected="$2"
  194. local rc=0
  195. [ "${out}" = "${expected}" ] && return 0
  196. if [ -z "${out}" ]; then
  197. if [ "$VERBOSE" = "1" ]; then
  198. printf "\nNo entry found\n"
  199. printf "Expected:\n"
  200. printf " ${expected}\n"
  201. fi
  202. return 1
  203. fi
  204. out=$(echo ${out})
  205. if [ "${out}" != "${expected}" ]; then
  206. rc=1
  207. if [ "${VERBOSE}" = "1" ]; then
  208. printf " Unexpected entry. Have:\n"
  209. printf " ${out}\n"
  210. printf " Expected:\n"
  211. printf " ${expected}\n\n"
  212. else
  213. echo " WARNING: Unexpected route entry"
  214. fi
  215. fi
  216. return $rc
  217. }
  218. check_nexthop()
  219. {
  220. local nharg="$1"
  221. local expected="$2"
  222. local out
  223. out=$($IP nexthop ls ${nharg} 2>/dev/null)
  224. check_output "${out}" "${expected}"
  225. }
  226. check_nexthop_bucket()
  227. {
  228. local nharg="$1"
  229. local expected="$2"
  230. local out
  231. # remove the idle time since we cannot match it
  232. out=$($IP nexthop bucket ${nharg} \
  233. | sed s/idle_time\ [0-9.]*\ // 2>/dev/null)
  234. check_output "${out}" "${expected}"
  235. }
  236. check_route()
  237. {
  238. local pfx="$1"
  239. local expected="$2"
  240. local out
  241. out=$($IP route ls match ${pfx} 2>/dev/null)
  242. check_output "${out}" "${expected}"
  243. }
  244. check_route6()
  245. {
  246. local pfx="$1"
  247. local expected="$2"
  248. local out
  249. out=$($IP -6 route ls match ${pfx} 2>/dev/null | sed -e 's/pref medium//')
  250. check_output "${out}" "${expected}"
  251. }
  252. check_large_grp()
  253. {
  254. local ipv=$1
  255. local ecmp=$2
  256. local grpnum=100
  257. local nhidstart=100
  258. local grpidstart=1000
  259. local iter=0
  260. local nhidstr=""
  261. local grpidstr=""
  262. local grpstr=""
  263. local ipstr=""
  264. if [ $ipv -eq 4 ]; then
  265. ipstr="172.16.1."
  266. else
  267. ipstr="2001:db8:91::"
  268. fi
  269. #
  270. # Create $grpnum groups with specified $ecmp and dump them
  271. #
  272. # create nexthops with different gateways
  273. iter=2
  274. while [ $iter -le $(($ecmp + 1)) ]
  275. do
  276. nhidstr="$(($nhidstart + $iter))"
  277. run_cmd "$IP nexthop add id $nhidstr via $ipstr$iter dev veth1"
  278. check_nexthop "id $nhidstr" "id $nhidstr via $ipstr$iter dev veth1 scope link"
  279. if [ $iter -le $ecmp ]; then
  280. grpstr+="$nhidstr/"
  281. else
  282. grpstr+="$nhidstr"
  283. fi
  284. ((iter++))
  285. done
  286. # create duplicate large ecmp groups
  287. iter=0
  288. while [ $iter -le $grpnum ]
  289. do
  290. grpidstr="$(($grpidstart + $iter))"
  291. run_cmd "$IP nexthop add id $grpidstr group $grpstr"
  292. check_nexthop "id $grpidstr" "id $grpidstr group $grpstr"
  293. ((iter++))
  294. done
  295. # dump large groups
  296. run_cmd "$IP nexthop list"
  297. log_test $? 0 "Dump large (x$ecmp) ecmp groups"
  298. }
  299. check_large_res_grp()
  300. {
  301. local ipv=$1
  302. local buckets=$2
  303. local ipstr=""
  304. if [ $ipv -eq 4 ]; then
  305. ipstr="172.16.1.2"
  306. else
  307. ipstr="2001:db8:91::2"
  308. fi
  309. # create a resilient group with $buckets buckets and dump them
  310. run_cmd "$IP nexthop add id 100 via $ipstr dev veth1"
  311. run_cmd "$IP nexthop add id 1000 group 100 type resilient buckets $buckets"
  312. run_cmd "$IP nexthop bucket list"
  313. log_test $? 0 "Dump large (x$buckets) nexthop buckets"
  314. }
  315. get_route_dev()
  316. {
  317. local pfx="$1"
  318. local out
  319. if out=$($IP -j route get "$pfx" | jq -re ".[0].dev"); then
  320. echo "$out"
  321. fi
  322. }
  323. check_route_dev()
  324. {
  325. local pfx="$1"
  326. local expected="$2"
  327. local out
  328. out=$(get_route_dev "$pfx")
  329. check_output "$out" "$expected"
  330. }
  331. start_ip_monitor()
  332. {
  333. local mtype=$1
  334. # start the monitor in the background
  335. tmpfile=`mktemp /var/run/nexthoptestXXX`
  336. mpid=`($IP monitor $mtype > $tmpfile & echo $!) 2>/dev/null`
  337. sleep 0.2
  338. echo "$mpid $tmpfile"
  339. }
  340. stop_ip_monitor()
  341. {
  342. local mpid=$1
  343. local tmpfile=$2
  344. local el=$3
  345. # check the monitor results
  346. kill $mpid
  347. lines=`wc -l $tmpfile | cut "-d " -f1`
  348. test $lines -eq $el
  349. rc=$?
  350. rm -rf $tmpfile
  351. return $rc
  352. }
  353. check_nexthop_fdb_support()
  354. {
  355. $IP nexthop help 2>&1 | grep -q fdb
  356. if [ $? -ne 0 ]; then
  357. echo "SKIP: iproute2 too old, missing fdb nexthop support"
  358. return $ksft_skip
  359. fi
  360. }
  361. check_nexthop_res_support()
  362. {
  363. $IP nexthop help 2>&1 | grep -q resilient
  364. if [ $? -ne 0 ]; then
  365. echo "SKIP: iproute2 too old, missing resilient nexthop group support"
  366. return $ksft_skip
  367. fi
  368. }
  369. ipv6_fdb_grp_fcnal()
  370. {
  371. local rc
  372. echo
  373. echo "IPv6 fdb groups functional"
  374. echo "--------------------------"
  375. check_nexthop_fdb_support
  376. if [ $? -eq $ksft_skip ]; then
  377. return $ksft_skip
  378. fi
  379. # create group with multiple nexthops
  380. run_cmd "$IP nexthop add id 61 via 2001:db8:91::2 fdb"
  381. run_cmd "$IP nexthop add id 62 via 2001:db8:91::3 fdb"
  382. run_cmd "$IP nexthop add id 102 group 61/62 fdb"
  383. check_nexthop "id 102" "id 102 group 61/62 fdb"
  384. log_test $? 0 "Fdb Nexthop group with multiple nexthops"
  385. ## get nexthop group
  386. run_cmd "$IP nexthop get id 102"
  387. check_nexthop "id 102" "id 102 group 61/62 fdb"
  388. log_test $? 0 "Get Fdb nexthop group by id"
  389. # fdb nexthop group can only contain fdb nexthops
  390. run_cmd "$IP nexthop add id 63 via 2001:db8:91::4 dev veth1"
  391. run_cmd "$IP nexthop add id 64 via 2001:db8:91::5 dev veth1"
  392. run_cmd "$IP nexthop add id 103 group 63/64 fdb"
  393. log_test $? 2 "Fdb Nexthop group with non-fdb nexthops"
  394. # Non fdb nexthop group can not contain fdb nexthops
  395. run_cmd "$IP nexthop add id 65 via 2001:db8:91::5 fdb"
  396. run_cmd "$IP nexthop add id 66 via 2001:db8:91::6 fdb"
  397. run_cmd "$IP nexthop add id 104 group 65/66"
  398. log_test $? 2 "Non-Fdb Nexthop group with fdb nexthops"
  399. # fdb nexthop cannot have blackhole
  400. run_cmd "$IP nexthop add id 67 blackhole fdb"
  401. log_test $? 2 "Fdb Nexthop with blackhole"
  402. # fdb nexthop with oif
  403. run_cmd "$IP nexthop add id 68 via 2001:db8:91::7 dev veth1 fdb"
  404. log_test $? 2 "Fdb Nexthop with oif"
  405. # fdb nexthop with onlink
  406. run_cmd "$IP nexthop add id 68 via 2001:db8:91::7 onlink fdb"
  407. log_test $? 2 "Fdb Nexthop with onlink"
  408. # fdb nexthop with encap
  409. run_cmd "$IP nexthop add id 69 encap mpls 101 via 2001:db8:91::8 dev veth1 fdb"
  410. log_test $? 2 "Fdb Nexthop with encap"
  411. # Replace FDB nexthop to non-FDB and vice versa
  412. run_cmd "$IP nexthop add id 70 via 2001:db8:91::2 fdb"
  413. run_cmd "$IP nexthop replace id 70 via 2001:db8:91::2 dev veth1"
  414. log_test $? 0 "Replace FDB nexthop to non-FDB nexthop"
  415. run_cmd "$IP nexthop replace id 70 via 2001:db8:91::2 fdb"
  416. log_test $? 0 "Replace non-FDB nexthop to FDB nexthop"
  417. # Replace FDB nexthop address while in a group
  418. run_cmd "$IP nexthop add id 71 group 70 fdb"
  419. run_cmd "$IP nexthop replace id 70 via 2001:db8:91::3 fdb"
  420. log_test $? 0 "Replace FDB nexthop address while in a group"
  421. # Cannot replace FDB nexthop to non-FDB and vice versa while in a group
  422. run_cmd "$IP nexthop replace id 70 via 2001:db8:91::2 dev veth1"
  423. log_test $? 2 "Replace FDB nexthop to non-FDB nexthop while in a group"
  424. run_cmd "$IP nexthop add id 72 via 2001:db8:91::2 dev veth1"
  425. run_cmd "$IP nexthop add id 73 group 72"
  426. run_cmd "$IP nexthop replace id 72 via 2001:db8:91::2 fdb"
  427. log_test $? 2 "Replace non-FDB nexthop to FDB nexthop while in a group"
  428. run_cmd "$IP link add name vx10 type vxlan id 1010 local 2001:db8:91::9 remote 2001:db8:91::10 dstport 4789 nolearning noudpcsum tos inherit ttl 100"
  429. run_cmd "$BRIDGE fdb add 02:02:00:00:00:13 dev vx10 nhid 102 self"
  430. log_test $? 0 "Fdb mac add with nexthop group"
  431. ## fdb nexthops can only reference nexthop groups and not nexthops
  432. run_cmd "$BRIDGE fdb add 02:02:00:00:00:14 dev vx10 nhid 61 self"
  433. log_test $? 255 "Fdb mac add with nexthop"
  434. run_cmd "$IP -6 ro add 2001:db8:101::1/128 nhid 66"
  435. log_test $? 2 "Route add with fdb nexthop"
  436. run_cmd "$IP -6 ro add 2001:db8:101::1/128 nhid 103"
  437. log_test $? 2 "Route add with fdb nexthop group"
  438. run_cmd "$IP nexthop del id 61"
  439. run_cmd "$BRIDGE fdb get to 02:02:00:00:00:13 dev vx10 self"
  440. log_test $? 0 "Fdb entry after deleting a single nexthop"
  441. run_cmd "$IP nexthop del id 102"
  442. log_test $? 0 "Fdb nexthop delete"
  443. run_cmd "$BRIDGE fdb get to 02:02:00:00:00:13 dev vx10 self"
  444. log_test $? 254 "Fdb entry after deleting a nexthop group"
  445. $IP link del dev vx10
  446. }
  447. ipv4_fdb_grp_fcnal()
  448. {
  449. local rc
  450. echo
  451. echo "IPv4 fdb groups functional"
  452. echo "--------------------------"
  453. check_nexthop_fdb_support
  454. if [ $? -eq $ksft_skip ]; then
  455. return $ksft_skip
  456. fi
  457. # create group with multiple nexthops
  458. run_cmd "$IP nexthop add id 12 via 172.16.1.2 fdb"
  459. run_cmd "$IP nexthop add id 13 via 172.16.1.3 fdb"
  460. run_cmd "$IP nexthop add id 102 group 12/13 fdb"
  461. check_nexthop "id 102" "id 102 group 12/13 fdb"
  462. log_test $? 0 "Fdb Nexthop group with multiple nexthops"
  463. # get nexthop group
  464. run_cmd "$IP nexthop get id 102"
  465. check_nexthop "id 102" "id 102 group 12/13 fdb"
  466. log_test $? 0 "Get Fdb nexthop group by id"
  467. # fdb nexthop group can only contain fdb nexthops
  468. run_cmd "$IP nexthop add id 14 via 172.16.1.2 dev veth1"
  469. run_cmd "$IP nexthop add id 15 via 172.16.1.3 dev veth1"
  470. run_cmd "$IP nexthop add id 103 group 14/15 fdb"
  471. log_test $? 2 "Fdb Nexthop group with non-fdb nexthops"
  472. # Non fdb nexthop group can not contain fdb nexthops
  473. run_cmd "$IP nexthop add id 16 via 172.16.1.2 fdb"
  474. run_cmd "$IP nexthop add id 17 via 172.16.1.3 fdb"
  475. run_cmd "$IP nexthop add id 104 group 16/17"
  476. log_test $? 2 "Non-Fdb Nexthop group with fdb nexthops"
  477. # fdb nexthop cannot have blackhole
  478. run_cmd "$IP nexthop add id 18 blackhole fdb"
  479. log_test $? 2 "Fdb Nexthop with blackhole"
  480. # fdb nexthop with oif
  481. run_cmd "$IP nexthop add id 16 via 172.16.1.2 dev veth1 fdb"
  482. log_test $? 2 "Fdb Nexthop with oif"
  483. # fdb nexthop with onlink
  484. run_cmd "$IP nexthop add id 16 via 172.16.1.2 onlink fdb"
  485. log_test $? 2 "Fdb Nexthop with onlink"
  486. # fdb nexthop with encap
  487. run_cmd "$IP nexthop add id 17 encap mpls 101 via 172.16.1.2 dev veth1 fdb"
  488. log_test $? 2 "Fdb Nexthop with encap"
  489. # Replace FDB nexthop to non-FDB and vice versa
  490. run_cmd "$IP nexthop add id 18 via 172.16.1.2 fdb"
  491. run_cmd "$IP nexthop replace id 18 via 172.16.1.2 dev veth1"
  492. log_test $? 0 "Replace FDB nexthop to non-FDB nexthop"
  493. run_cmd "$IP nexthop replace id 18 via 172.16.1.2 fdb"
  494. log_test $? 0 "Replace non-FDB nexthop to FDB nexthop"
  495. # Replace FDB nexthop address while in a group
  496. run_cmd "$IP nexthop add id 19 group 18 fdb"
  497. run_cmd "$IP nexthop replace id 18 via 172.16.1.3 fdb"
  498. log_test $? 0 "Replace FDB nexthop address while in a group"
  499. # Cannot replace FDB nexthop to non-FDB and vice versa while in a group
  500. run_cmd "$IP nexthop replace id 18 via 172.16.1.2 dev veth1"
  501. log_test $? 2 "Replace FDB nexthop to non-FDB nexthop while in a group"
  502. run_cmd "$IP nexthop add id 20 via 172.16.1.2 dev veth1"
  503. run_cmd "$IP nexthop add id 21 group 20"
  504. run_cmd "$IP nexthop replace id 20 via 172.16.1.2 fdb"
  505. log_test $? 2 "Replace non-FDB nexthop to FDB nexthop while in a group"
  506. run_cmd "$IP link add name vx10 type vxlan id 1010 local 10.0.0.1 remote 10.0.0.2 dstport 4789 nolearning noudpcsum tos inherit ttl 100"
  507. run_cmd "$BRIDGE fdb add 02:02:00:00:00:13 dev vx10 nhid 102 self"
  508. log_test $? 0 "Fdb mac add with nexthop group"
  509. # fdb nexthops can only reference nexthop groups and not nexthops
  510. run_cmd "$BRIDGE fdb add 02:02:00:00:00:14 dev vx10 nhid 12 self"
  511. log_test $? 255 "Fdb mac add with nexthop"
  512. run_cmd "$IP ro add 172.16.0.0/22 nhid 16"
  513. log_test $? 2 "Route add with fdb nexthop"
  514. run_cmd "$IP ro add 172.16.0.0/22 nhid 103"
  515. log_test $? 2 "Route add with fdb nexthop group"
  516. run_cmd "$IP nexthop del id 12"
  517. run_cmd "$BRIDGE fdb get to 02:02:00:00:00:13 dev vx10 self"
  518. log_test $? 0 "Fdb entry after deleting a single nexthop"
  519. run_cmd "$IP nexthop del id 102"
  520. log_test $? 0 "Fdb nexthop delete"
  521. run_cmd "$BRIDGE fdb get to 02:02:00:00:00:13 dev vx10 self"
  522. log_test $? 254 "Fdb entry after deleting a nexthop group"
  523. $IP link del dev vx10
  524. }
  525. ipv4_mpath_select()
  526. {
  527. local rc dev match h addr
  528. echo
  529. echo "IPv4 multipath selection"
  530. echo "------------------------"
  531. if [ ! -x "$(command -v jq)" ]; then
  532. echo "SKIP: Could not run test; need jq tool"
  533. return $ksft_skip
  534. fi
  535. # Use status of existing neighbor entry when determining nexthop for
  536. # multipath routes.
  537. local -A gws
  538. gws=([veth1]=172.16.1.2 [veth3]=172.16.2.2)
  539. local -A other_dev
  540. other_dev=([veth1]=veth3 [veth3]=veth1)
  541. run_cmd "$IP nexthop add id 1 via ${gws["veth1"]} dev veth1"
  542. run_cmd "$IP nexthop add id 2 via ${gws["veth3"]} dev veth3"
  543. run_cmd "$IP nexthop add id 1001 group 1/2"
  544. run_cmd "$IP ro add 172.16.101.0/24 nhid 1001"
  545. rc=0
  546. for dev in veth1 veth3; do
  547. match=0
  548. for h in {1..254}; do
  549. addr="172.16.101.$h"
  550. if [ "$(get_route_dev "$addr")" = "$dev" ]; then
  551. match=1
  552. break
  553. fi
  554. done
  555. if (( match == 0 )); then
  556. echo "SKIP: Did not find a route using device $dev"
  557. return $ksft_skip
  558. fi
  559. run_cmd "$IP neigh add ${gws[$dev]} dev $dev nud failed"
  560. if ! check_route_dev "$addr" "${other_dev[$dev]}"; then
  561. rc=1
  562. break
  563. fi
  564. run_cmd "$IP neigh del ${gws[$dev]} dev $dev"
  565. done
  566. log_test $rc 0 "Use valid neighbor during multipath selection"
  567. run_cmd "$IP neigh add 172.16.1.2 dev veth1 nud incomplete"
  568. run_cmd "$IP neigh add 172.16.2.2 dev veth3 nud incomplete"
  569. run_cmd "$IP route get 172.16.101.1"
  570. # if we did not crash, success
  571. log_test $rc 0 "Multipath selection with no valid neighbor"
  572. }
  573. ipv6_mpath_select()
  574. {
  575. local rc dev match h addr
  576. echo
  577. echo "IPv6 multipath selection"
  578. echo "------------------------"
  579. if [ ! -x "$(command -v jq)" ]; then
  580. echo "SKIP: Could not run test; need jq tool"
  581. return $ksft_skip
  582. fi
  583. # Use status of existing neighbor entry when determining nexthop for
  584. # multipath routes.
  585. local -A gws
  586. gws=([veth1]=2001:db8:91::2 [veth3]=2001:db8:92::2)
  587. local -A other_dev
  588. other_dev=([veth1]=veth3 [veth3]=veth1)
  589. run_cmd "$IP nexthop add id 1 via ${gws["veth1"]} dev veth1"
  590. run_cmd "$IP nexthop add id 2 via ${gws["veth3"]} dev veth3"
  591. run_cmd "$IP nexthop add id 1001 group 1/2"
  592. run_cmd "$IP ro add 2001:db8:101::/64 nhid 1001"
  593. rc=0
  594. for dev in veth1 veth3; do
  595. match=0
  596. for h in {1..65535}; do
  597. addr=$(printf "2001:db8:101::%x" $h)
  598. if [ "$(get_route_dev "$addr")" = "$dev" ]; then
  599. match=1
  600. break
  601. fi
  602. done
  603. if (( match == 0 )); then
  604. echo "SKIP: Did not find a route using device $dev"
  605. return $ksft_skip
  606. fi
  607. run_cmd "$IP neigh add ${gws[$dev]} dev $dev nud failed"
  608. if ! check_route_dev "$addr" "${other_dev[$dev]}"; then
  609. rc=1
  610. break
  611. fi
  612. run_cmd "$IP neigh del ${gws[$dev]} dev $dev"
  613. done
  614. log_test $rc 0 "Use valid neighbor during multipath selection"
  615. run_cmd "$IP neigh add 2001:db8:91::2 dev veth1 nud incomplete"
  616. run_cmd "$IP neigh add 2001:db8:92::2 dev veth3 nud incomplete"
  617. run_cmd "$IP route get 2001:db8:101::1"
  618. # if we did not crash, success
  619. log_test $rc 0 "Multipath selection with no valid neighbor"
  620. }
  621. ################################################################################
  622. # basic operations (add, delete, replace) on nexthops and nexthop groups
  623. #
  624. # IPv6
  625. ipv6_fcnal()
  626. {
  627. local rc
  628. echo
  629. echo "IPv6"
  630. echo "----------------------"
  631. run_cmd "$IP nexthop add id 52 via 2001:db8:91::2 dev veth1"
  632. rc=$?
  633. log_test $rc 0 "Create nexthop with id, gw, dev"
  634. if [ $rc -ne 0 ]; then
  635. echo "Basic IPv6 create fails; can not continue"
  636. return 1
  637. fi
  638. run_cmd "$IP nexthop get id 52"
  639. log_test $? 0 "Get nexthop by id"
  640. check_nexthop "id 52" "id 52 via 2001:db8:91::2 dev veth1 scope link"
  641. run_cmd "$IP nexthop del id 52"
  642. log_test $? 0 "Delete nexthop by id"
  643. check_nexthop "id 52" ""
  644. #
  645. # gw, device spec
  646. #
  647. # gw validation, no device - fails since dev required
  648. run_cmd "$IP nexthop add id 52 via 2001:db8:92::3"
  649. log_test $? 2 "Create nexthop - gw only"
  650. # gw is not reachable through given dev
  651. run_cmd "$IP nexthop add id 53 via 2001:db8:3::3 dev veth1"
  652. log_test $? 2 "Create nexthop - invalid gw+dev combination"
  653. # onlink arg overrides gw+dev lookup
  654. run_cmd "$IP nexthop add id 53 via 2001:db8:3::3 dev veth1 onlink"
  655. log_test $? 0 "Create nexthop - gw+dev and onlink"
  656. # admin down should delete nexthops
  657. set -e
  658. run_cmd "$IP -6 nexthop add id 55 via 2001:db8:91::3 dev veth1"
  659. run_cmd "$IP nexthop add id 56 via 2001:db8:91::4 dev veth1"
  660. run_cmd "$IP nexthop add id 57 via 2001:db8:91::5 dev veth1"
  661. run_cmd "$IP li set dev veth1 down"
  662. set +e
  663. check_nexthop "dev veth1" ""
  664. log_test $? 0 "Nexthops removed on admin down"
  665. # error routes should be deleted when their nexthop is deleted
  666. run_cmd "$IP li set dev veth1 up"
  667. run_cmd "$IP -6 nexthop add id 58 dev veth1"
  668. run_cmd "$IP ro add blackhole 2001:db8:101::1/128 nhid 58"
  669. run_cmd "$IP nexthop del id 58"
  670. check_route6 "2001:db8:101::1" ""
  671. log_test $? 0 "Error route removed on nexthop deletion"
  672. }
  673. ipv6_grp_refs()
  674. {
  675. if [ ! -x "$(command -v mausezahn)" ]; then
  676. echo "SKIP: Could not run test; need mausezahn tool"
  677. return
  678. fi
  679. run_cmd "$IP link set dev veth1 up"
  680. run_cmd "$IP link add veth1.10 link veth1 up type vlan id 10"
  681. run_cmd "$IP link add veth1.20 link veth1 up type vlan id 20"
  682. run_cmd "$IP -6 addr add 2001:db8:91::1/64 dev veth1.10"
  683. run_cmd "$IP -6 addr add 2001:db8:92::1/64 dev veth1.20"
  684. run_cmd "$IP -6 neigh add 2001:db8:91::2 lladdr 00:11:22:33:44:55 dev veth1.10"
  685. run_cmd "$IP -6 neigh add 2001:db8:92::2 lladdr 00:11:22:33:44:55 dev veth1.20"
  686. run_cmd "$IP nexthop add id 100 via 2001:db8:91::2 dev veth1.10"
  687. run_cmd "$IP nexthop add id 101 via 2001:db8:92::2 dev veth1.20"
  688. run_cmd "$IP nexthop add id 102 group 100"
  689. run_cmd "$IP route add 2001:db8:101::1/128 nhid 102"
  690. # create per-cpu dsts through nh 100
  691. run_cmd "ip netns exec $me mausezahn -6 veth1.10 -B 2001:db8:101::1 -A 2001:db8:91::1 -c 5 -t tcp "dp=1-1023, flags=syn" >/dev/null 2>&1"
  692. # remove nh 100 from the group to delete the route potentially leaving
  693. # a stale per-cpu dst which holds a reference to the nexthop's net
  694. # device and to the IPv6 route
  695. run_cmd "$IP nexthop replace id 102 group 101"
  696. run_cmd "$IP route del 2001:db8:101::1/128"
  697. # add both nexthops to the group so a reference is taken on them
  698. run_cmd "$IP nexthop replace id 102 group 100/101"
  699. # if the bug described in commit "net: nexthop: release IPv6 per-cpu
  700. # dsts when replacing a nexthop group" exists at this point we have
  701. # an unlinked IPv6 route (but not freed due to stale dst) with a
  702. # reference over the group so we delete the group which will again
  703. # only unlink it due to the route reference
  704. run_cmd "$IP nexthop del id 102"
  705. # delete the nexthop with stale dst, since we have an unlinked
  706. # group with a ref to it and an unlinked IPv6 route with ref to the
  707. # group, the nh will only be unlinked and not freed so the stale dst
  708. # remains forever and we get a net device refcount imbalance
  709. run_cmd "$IP nexthop del id 100"
  710. # if a reference was lost this command will hang because the net device
  711. # cannot be removed
  712. timeout -s KILL 5 ip netns exec $me ip link del veth1.10 >/dev/null 2>&1
  713. # we can't cleanup if the command is hung trying to delete the netdev
  714. if [ $? -eq 137 ]; then
  715. return 1
  716. fi
  717. # cleanup
  718. run_cmd "$IP link del veth1.20"
  719. run_cmd "$IP nexthop flush"
  720. return 0
  721. }
  722. ipv6_grp_fcnal()
  723. {
  724. local rc
  725. echo
  726. echo "IPv6 groups functional"
  727. echo "----------------------"
  728. # basic functionality: create a nexthop group, default weight
  729. run_cmd "$IP nexthop add id 61 via 2001:db8:91::2 dev veth1"
  730. run_cmd "$IP nexthop add id 101 group 61"
  731. log_test $? 0 "Create nexthop group with single nexthop"
  732. # get nexthop group
  733. run_cmd "$IP nexthop get id 101"
  734. log_test $? 0 "Get nexthop group by id"
  735. check_nexthop "id 101" "id 101 group 61"
  736. # delete nexthop group
  737. run_cmd "$IP nexthop del id 101"
  738. log_test $? 0 "Delete nexthop group by id"
  739. check_nexthop "id 101" ""
  740. $IP nexthop flush >/dev/null 2>&1
  741. check_nexthop "id 101" ""
  742. #
  743. # create group with multiple nexthops - mix of gw and dev only
  744. #
  745. run_cmd "$IP nexthop add id 62 via 2001:db8:91::2 dev veth1"
  746. run_cmd "$IP nexthop add id 63 via 2001:db8:91::3 dev veth1"
  747. run_cmd "$IP nexthop add id 64 via 2001:db8:91::4 dev veth1"
  748. run_cmd "$IP nexthop add id 65 dev veth1"
  749. run_cmd "$IP nexthop add id 102 group 62/63/64/65"
  750. log_test $? 0 "Nexthop group with multiple nexthops"
  751. check_nexthop "id 102" "id 102 group 62/63/64/65"
  752. # Delete nexthop in a group and group is updated
  753. run_cmd "$IP nexthop del id 63"
  754. check_nexthop "id 102" "id 102 group 62/64/65"
  755. log_test $? 0 "Nexthop group updated when entry is deleted"
  756. # create group with multiple weighted nexthops
  757. run_cmd "$IP nexthop add id 63 via 2001:db8:91::3 dev veth1"
  758. run_cmd "$IP nexthop add id 103 group 62/63,2/64,3/65,4"
  759. log_test $? 0 "Nexthop group with weighted nexthops"
  760. check_nexthop "id 103" "id 103 group 62/63,2/64,3/65,4"
  761. # Delete nexthop in a weighted group and group is updated
  762. run_cmd "$IP nexthop del id 63"
  763. check_nexthop "id 103" "id 103 group 62/64,3/65,4"
  764. log_test $? 0 "Weighted nexthop group updated when entry is deleted"
  765. # admin down - nexthop is removed from group
  766. run_cmd "$IP li set dev veth1 down"
  767. check_nexthop "dev veth1" ""
  768. log_test $? 0 "Nexthops in groups removed on admin down"
  769. # expect groups to have been deleted as well
  770. check_nexthop "" ""
  771. run_cmd "$IP li set dev veth1 up"
  772. $IP nexthop flush >/dev/null 2>&1
  773. # group with nexthops using different devices
  774. set -e
  775. run_cmd "$IP nexthop add id 62 via 2001:db8:91::2 dev veth1"
  776. run_cmd "$IP nexthop add id 63 via 2001:db8:91::3 dev veth1"
  777. run_cmd "$IP nexthop add id 64 via 2001:db8:91::4 dev veth1"
  778. run_cmd "$IP nexthop add id 65 via 2001:db8:91::5 dev veth1"
  779. run_cmd "$IP nexthop add id 72 via 2001:db8:92::2 dev veth3"
  780. run_cmd "$IP nexthop add id 73 via 2001:db8:92::3 dev veth3"
  781. run_cmd "$IP nexthop add id 74 via 2001:db8:92::4 dev veth3"
  782. run_cmd "$IP nexthop add id 75 via 2001:db8:92::5 dev veth3"
  783. set +e
  784. # multiple groups with same nexthop
  785. run_cmd "$IP nexthop add id 104 group 62"
  786. run_cmd "$IP nexthop add id 105 group 62"
  787. check_nexthop "group" "id 104 group 62 id 105 group 62"
  788. log_test $? 0 "Multiple groups with same nexthop"
  789. run_cmd "$IP nexthop flush groups"
  790. [ $? -ne 0 ] && return 1
  791. # on admin down of veth1, it should be removed from the group
  792. run_cmd "$IP nexthop add id 105 group 62/63/72/73/64"
  793. run_cmd "$IP li set veth1 down"
  794. check_nexthop "id 105" "id 105 group 72/73"
  795. log_test $? 0 "Nexthops in group removed on admin down - mixed group"
  796. run_cmd "$IP nexthop add id 106 group 105/74"
  797. log_test $? 2 "Nexthop group can not have a group as an entry"
  798. # a group can have a blackhole entry only if it is the only
  799. # nexthop in the group. Needed for atomic replace with an
  800. # actual nexthop group
  801. run_cmd "$IP -6 nexthop add id 31 blackhole"
  802. run_cmd "$IP nexthop add id 107 group 31"
  803. log_test $? 0 "Nexthop group with a blackhole entry"
  804. run_cmd "$IP nexthop add id 108 group 31/24"
  805. log_test $? 2 "Nexthop group can not have a blackhole and another nexthop"
  806. ipv6_grp_refs
  807. log_test $? 0 "Nexthop group replace refcounts"
  808. #
  809. # 16-bit weights.
  810. #
  811. run_cmd "$IP nexthop add id 62 via 2001:db8:91::2 dev veth1"
  812. run_cmd "$IP nexthop add id 63 via 2001:db8:91::3 dev veth1"
  813. run_cmd "$IP nexthop add id 64 via 2001:db8:91::4 dev veth1"
  814. run_cmd "$IP nexthop add id 65 via 2001:db8:91::5 dev veth1"
  815. run_cmd "$IP nexthop add id 66 dev veth1"
  816. run_cmd "$IP nexthop add id 103 group 62,1000"
  817. if [[ $? == 0 ]]; then
  818. local GRP="id 103 group 62,254/63,255/64,256/65,257/66,65535"
  819. run_cmd "$IP nexthop replace $GRP"
  820. check_nexthop "id 103" "$GRP"
  821. rc=$?
  822. else
  823. rc=$ksft_skip
  824. fi
  825. $IP nexthop flush >/dev/null 2>&1
  826. log_test $rc 0 "16-bit weights"
  827. }
  828. ipv6_res_grp_fcnal()
  829. {
  830. local rc
  831. echo
  832. echo "IPv6 resilient groups functional"
  833. echo "--------------------------------"
  834. check_nexthop_res_support
  835. if [ $? -eq $ksft_skip ]; then
  836. return $ksft_skip
  837. fi
  838. #
  839. # migration of nexthop buckets - equal weights
  840. #
  841. run_cmd "$IP nexthop add id 62 via 2001:db8:91::2 dev veth1"
  842. run_cmd "$IP nexthop add id 63 via 2001:db8:91::3 dev veth1"
  843. run_cmd "$IP nexthop add id 102 group 62/63 type resilient buckets 2 idle_timer 0"
  844. run_cmd "$IP nexthop del id 63"
  845. check_nexthop "id 102" \
  846. "id 102 group 62 type resilient buckets 2 idle_timer 0 unbalanced_timer 0 unbalanced_time 0"
  847. log_test $? 0 "Nexthop group updated when entry is deleted"
  848. check_nexthop_bucket "list id 102" \
  849. "id 102 index 0 nhid 62 id 102 index 1 nhid 62"
  850. log_test $? 0 "Nexthop buckets updated when entry is deleted"
  851. run_cmd "$IP nexthop add id 63 via 2001:db8:91::3 dev veth1"
  852. run_cmd "$IP nexthop replace id 102 group 62/63 type resilient buckets 2 idle_timer 0"
  853. check_nexthop "id 102" \
  854. "id 102 group 62/63 type resilient buckets 2 idle_timer 0 unbalanced_timer 0 unbalanced_time 0"
  855. log_test $? 0 "Nexthop group updated after replace"
  856. check_nexthop_bucket "list id 102" \
  857. "id 102 index 0 nhid 63 id 102 index 1 nhid 62"
  858. log_test $? 0 "Nexthop buckets updated after replace"
  859. $IP nexthop flush >/dev/null 2>&1
  860. #
  861. # migration of nexthop buckets - unequal weights
  862. #
  863. run_cmd "$IP nexthop add id 62 via 2001:db8:91::2 dev veth1"
  864. run_cmd "$IP nexthop add id 63 via 2001:db8:91::3 dev veth1"
  865. run_cmd "$IP nexthop add id 102 group 62,3/63,1 type resilient buckets 4 idle_timer 0"
  866. run_cmd "$IP nexthop del id 63"
  867. check_nexthop "id 102" \
  868. "id 102 group 62,3 type resilient buckets 4 idle_timer 0 unbalanced_timer 0 unbalanced_time 0"
  869. log_test $? 0 "Nexthop group updated when entry is deleted - nECMP"
  870. check_nexthop_bucket "list id 102" \
  871. "id 102 index 0 nhid 62 id 102 index 1 nhid 62 id 102 index 2 nhid 62 id 102 index 3 nhid 62"
  872. log_test $? 0 "Nexthop buckets updated when entry is deleted - nECMP"
  873. run_cmd "$IP nexthop add id 63 via 2001:db8:91::3 dev veth1"
  874. run_cmd "$IP nexthop replace id 102 group 62,3/63,1 type resilient buckets 4 idle_timer 0"
  875. check_nexthop "id 102" \
  876. "id 102 group 62,3/63 type resilient buckets 4 idle_timer 0 unbalanced_timer 0 unbalanced_time 0"
  877. log_test $? 0 "Nexthop group updated after replace - nECMP"
  878. check_nexthop_bucket "list id 102" \
  879. "id 102 index 0 nhid 63 id 102 index 1 nhid 62 id 102 index 2 nhid 62 id 102 index 3 nhid 62"
  880. log_test $? 0 "Nexthop buckets updated after replace - nECMP"
  881. #
  882. # 16-bit weights.
  883. #
  884. run_cmd "$IP nexthop add id 62 via 2001:db8:91::2 dev veth1"
  885. run_cmd "$IP nexthop add id 63 via 2001:db8:91::3 dev veth1"
  886. run_cmd "$IP nexthop add id 64 via 2001:db8:91::4 dev veth1"
  887. run_cmd "$IP nexthop add id 65 via 2001:db8:91::5 dev veth1"
  888. run_cmd "$IP nexthop add id 66 dev veth1"
  889. run_cmd "$IP nexthop add id 103 group 62,1000 type resilient buckets 32"
  890. if [[ $? == 0 ]]; then
  891. local GRP="id 103 group 62,254/63,255/64,256/65,257/66,65535 $(:
  892. )type resilient buckets 32 idle_timer 0 $(:
  893. )unbalanced_timer 0"
  894. run_cmd "$IP nexthop replace $GRP"
  895. check_nexthop "id 103" "$GRP unbalanced_time 0"
  896. rc=$?
  897. else
  898. rc=$ksft_skip
  899. fi
  900. $IP nexthop flush >/dev/null 2>&1
  901. log_test $rc 0 "16-bit weights"
  902. }
  903. ipv6_fcnal_runtime()
  904. {
  905. local rc
  906. echo
  907. echo "IPv6 functional runtime"
  908. echo "-----------------------"
  909. #
  910. # IPv6 - the basics
  911. #
  912. run_cmd "$IP nexthop add id 81 via 2001:db8:91::2 dev veth1"
  913. run_cmd "$IP ro add 2001:db8:101::1/128 nhid 81"
  914. log_test $? 0 "Route add"
  915. run_cmd "$IP ro delete 2001:db8:101::1/128 nhid 81"
  916. log_test $? 0 "Route delete"
  917. run_cmd "$IP ro add 2001:db8:101::1/128 nhid 81"
  918. run_cmd "ip netns exec $me ping -c1 -w$PING_TIMEOUT 2001:db8:101::1"
  919. log_test $? 0 "Ping with nexthop"
  920. run_cmd "$IP nexthop add id 82 via 2001:db8:92::2 dev veth3"
  921. run_cmd "$IP nexthop add id 122 group 81/82"
  922. run_cmd "$IP ro replace 2001:db8:101::1/128 nhid 122"
  923. run_cmd "ip netns exec $me ping -c1 -w$PING_TIMEOUT 2001:db8:101::1"
  924. log_test $? 0 "Ping - multipath"
  925. #
  926. # IPv6 with blackhole nexthops
  927. #
  928. run_cmd "$IP -6 nexthop add id 83 blackhole"
  929. run_cmd "$IP ro replace 2001:db8:101::1/128 nhid 83"
  930. run_cmd "ip netns exec $me ping -c1 -w$PING_TIMEOUT 2001:db8:101::1"
  931. log_test $? 2 "Ping - blackhole"
  932. run_cmd "$IP nexthop replace id 83 via 2001:db8:91::2 dev veth1"
  933. run_cmd "ip netns exec $me ping -c1 -w$PING_TIMEOUT 2001:db8:101::1"
  934. log_test $? 0 "Ping - blackhole replaced with gateway"
  935. run_cmd "$IP -6 nexthop replace id 83 blackhole"
  936. run_cmd "ip netns exec $me ping -c1 -w$PING_TIMEOUT 2001:db8:101::1"
  937. log_test $? 2 "Ping - gateway replaced by blackhole"
  938. run_cmd "$IP ro replace 2001:db8:101::1/128 nhid 122"
  939. run_cmd "ip netns exec $me ping -c1 -w$PING_TIMEOUT 2001:db8:101::1"
  940. if [ $? -eq 0 ]; then
  941. run_cmd "$IP nexthop replace id 122 group 83"
  942. run_cmd "ip netns exec $me ping -c1 -w$PING_TIMEOUT 2001:db8:101::1"
  943. log_test $? 2 "Ping - group with blackhole"
  944. run_cmd "$IP nexthop replace id 122 group 81/82"
  945. run_cmd "ip netns exec $me ping -c1 -w$PING_TIMEOUT 2001:db8:101::1"
  946. log_test $? 0 "Ping - group blackhole replaced with gateways"
  947. else
  948. log_test 2 0 "Ping - multipath failed"
  949. fi
  950. #
  951. # device only and gw + dev only mix
  952. #
  953. run_cmd "$IP -6 nexthop add id 85 dev veth1"
  954. run_cmd "$IP ro replace 2001:db8:101::1/128 nhid 85"
  955. log_test $? 0 "IPv6 route with device only nexthop"
  956. check_route6 "2001:db8:101::1" "2001:db8:101::1 nhid 85 dev veth1 metric 1024"
  957. run_cmd "$IP nexthop add id 123 group 81/85"
  958. run_cmd "$IP ro replace 2001:db8:101::1/128 nhid 123"
  959. log_test $? 0 "IPv6 multipath route with nexthop mix - dev only + gw"
  960. check_route6 "2001:db8:101::1" "2001:db8:101::1 nhid 123 metric 1024 nexthop via 2001:db8:91::2 dev veth1 weight 1 nexthop dev veth1 weight 1"
  961. #
  962. # IPv6 route with v4 nexthop - not allowed
  963. #
  964. run_cmd "$IP ro delete 2001:db8:101::1/128"
  965. run_cmd "$IP nexthop add id 84 via 172.16.1.1 dev veth1"
  966. run_cmd "$IP ro add 2001:db8:101::1/128 nhid 84"
  967. log_test $? 2 "IPv6 route can not have a v4 gateway"
  968. run_cmd "$IP ro replace 2001:db8:101::1/128 nhid 81"
  969. run_cmd "$IP nexthop replace id 81 via 172.16.1.1 dev veth1"
  970. log_test $? 2 "Nexthop replace - v6 route, v4 nexthop"
  971. run_cmd "$IP ro replace 2001:db8:101::1/128 nhid 122"
  972. run_cmd "$IP nexthop replace id 81 via 172.16.1.1 dev veth1"
  973. log_test $? 2 "Nexthop replace of group entry - v6 route, v4 nexthop"
  974. run_cmd "$IP nexthop add id 86 via 2001:db8:92::2 dev veth3"
  975. run_cmd "$IP nexthop add id 87 via 172.16.1.1 dev veth1"
  976. run_cmd "$IP nexthop add id 88 via 172.16.1.1 dev veth1"
  977. run_cmd "$IP nexthop add id 124 group 86/87/88"
  978. run_cmd "$IP ro replace 2001:db8:101::1/128 nhid 124"
  979. log_test $? 2 "IPv6 route can not have a group with v4 and v6 gateways"
  980. run_cmd "$IP nexthop del id 88"
  981. run_cmd "$IP ro replace 2001:db8:101::1/128 nhid 124"
  982. log_test $? 2 "IPv6 route can not have a group with v4 and v6 gateways"
  983. run_cmd "$IP nexthop del id 87"
  984. run_cmd "$IP ro replace 2001:db8:101::1/128 nhid 124"
  985. log_test $? 0 "IPv6 route using a group after removing v4 gateways"
  986. run_cmd "$IP ro delete 2001:db8:101::1/128"
  987. run_cmd "$IP nexthop add id 87 via 172.16.1.1 dev veth1"
  988. run_cmd "$IP nexthop add id 88 via 172.16.1.1 dev veth1"
  989. run_cmd "$IP nexthop replace id 124 group 86/87/88"
  990. run_cmd "$IP ro replace 2001:db8:101::1/128 nhid 124"
  991. log_test $? 2 "IPv6 route can not have a group with v4 and v6 gateways"
  992. run_cmd "$IP nexthop replace id 88 via 2001:db8:92::2 dev veth3"
  993. run_cmd "$IP ro replace 2001:db8:101::1/128 nhid 124"
  994. log_test $? 2 "IPv6 route can not have a group with v4 and v6 gateways"
  995. run_cmd "$IP nexthop replace id 87 via 2001:db8:92::2 dev veth3"
  996. run_cmd "$IP ro replace 2001:db8:101::1/128 nhid 124"
  997. log_test $? 0 "IPv6 route using a group after replacing v4 gateways"
  998. $IP nexthop flush >/dev/null 2>&1
  999. #
  1000. # weird IPv6 cases
  1001. #
  1002. run_cmd "$IP nexthop add id 86 via 2001:db8:91::2 dev veth1"
  1003. run_cmd "$IP ro add 2001:db8:101::1/128 nhid 81"
  1004. # route can not use prefsrc with nexthops
  1005. run_cmd "$IP ro add 2001:db8:101::2/128 nhid 86 from 2001:db8:91::1"
  1006. log_test $? 2 "IPv6 route can not use src routing with external nexthop"
  1007. # check cleanup path on invalid metric
  1008. run_cmd "$IP ro add 2001:db8:101::2/128 nhid 86 congctl lock foo"
  1009. log_test $? 2 "IPv6 route with invalid metric"
  1010. # rpfilter and default route
  1011. $IP nexthop flush >/dev/null 2>&1
  1012. run_cmd "ip netns exec $me ip6tables -t mangle -I PREROUTING 1 -m rpfilter --invert -j DROP"
  1013. run_cmd "$IP nexthop add id 91 via 2001:db8:91::2 dev veth1"
  1014. run_cmd "$IP nexthop add id 92 via 2001:db8:92::2 dev veth3"
  1015. run_cmd "$IP nexthop add id 93 group 91/92"
  1016. run_cmd "$IP -6 ro add default nhid 91"
  1017. run_cmd "ip netns exec $me ping -c1 -w$PING_TIMEOUT 2001:db8:101::1"
  1018. log_test $? 0 "Nexthop with default route and rpfilter"
  1019. run_cmd "$IP -6 ro replace default nhid 93"
  1020. run_cmd "ip netns exec $me ping -c1 -w$PING_TIMEOUT 2001:db8:101::1"
  1021. log_test $? 0 "Nexthop with multipath default route and rpfilter"
  1022. # TO-DO:
  1023. # existing route with old nexthop; append route with new nexthop
  1024. # existing route with old nexthop; replace route with new
  1025. # existing route with new nexthop; replace route with old
  1026. # route with src address and using nexthop - not allowed
  1027. }
  1028. ipv6_large_grp()
  1029. {
  1030. local ecmp=32
  1031. echo
  1032. echo "IPv6 large groups (x$ecmp)"
  1033. echo "---------------------"
  1034. check_large_grp 6 $ecmp
  1035. $IP nexthop flush >/dev/null 2>&1
  1036. }
  1037. ipv6_large_res_grp()
  1038. {
  1039. echo
  1040. echo "IPv6 large resilient group (128k buckets)"
  1041. echo "-----------------------------------------"
  1042. check_nexthop_res_support
  1043. if [ $? -eq $ksft_skip ]; then
  1044. return $ksft_skip
  1045. fi
  1046. check_large_res_grp 6 $((128 * 1024))
  1047. $IP nexthop flush >/dev/null 2>&1
  1048. }
  1049. ipv6_del_add_loop1()
  1050. {
  1051. while :; do
  1052. $IP nexthop del id 100
  1053. $IP nexthop add id 100 via 2001:db8:91::2 dev veth1
  1054. done >/dev/null 2>&1
  1055. }
  1056. ipv6_grp_replace_loop()
  1057. {
  1058. while :; do
  1059. $IP nexthop replace id 102 group 100/101
  1060. done >/dev/null 2>&1
  1061. }
  1062. ipv6_torture()
  1063. {
  1064. local pid1
  1065. local pid2
  1066. local pid3
  1067. local pid4
  1068. local pid5
  1069. echo
  1070. echo "IPv6 runtime torture"
  1071. echo "--------------------"
  1072. if [ ! -x "$(command -v mausezahn)" ]; then
  1073. echo "SKIP: Could not run test; need mausezahn tool"
  1074. return
  1075. fi
  1076. run_cmd "$IP nexthop add id 100 via 2001:db8:91::2 dev veth1"
  1077. run_cmd "$IP nexthop add id 101 via 2001:db8:92::2 dev veth3"
  1078. run_cmd "$IP nexthop add id 102 group 100/101"
  1079. run_cmd "$IP route add 2001:db8:101::1 nhid 102"
  1080. run_cmd "$IP route add 2001:db8:101::2 nhid 102"
  1081. ipv6_del_add_loop1 &
  1082. pid1=$!
  1083. ipv6_grp_replace_loop &
  1084. pid2=$!
  1085. ip netns exec $me ping -f 2001:db8:101::1 >/dev/null 2>&1 &
  1086. pid3=$!
  1087. ip netns exec $me ping -f 2001:db8:101::2 >/dev/null 2>&1 &
  1088. pid4=$!
  1089. ip netns exec $me mausezahn -6 veth1 -B 2001:db8:101::2 -A 2001:db8:91::1 -c 0 -t tcp "dp=1-1023, flags=syn" >/dev/null 2>&1 &
  1090. pid5=$!
  1091. sleep 300
  1092. kill -9 $pid1 $pid2 $pid3 $pid4 $pid5
  1093. wait $pid1 $pid2 $pid3 $pid4 $pid5 2>/dev/null
  1094. # if we did not crash, success
  1095. log_test 0 0 "IPv6 torture test"
  1096. }
  1097. ipv6_res_grp_replace_loop()
  1098. {
  1099. while :; do
  1100. $IP nexthop replace id 102 group 100/101 type resilient
  1101. done >/dev/null 2>&1
  1102. }
  1103. ipv6_res_torture()
  1104. {
  1105. local pid1
  1106. local pid2
  1107. local pid3
  1108. local pid4
  1109. local pid5
  1110. echo
  1111. echo "IPv6 runtime resilient nexthop group torture"
  1112. echo "--------------------------------------------"
  1113. check_nexthop_res_support
  1114. if [ $? -eq $ksft_skip ]; then
  1115. return $ksft_skip
  1116. fi
  1117. if [ ! -x "$(command -v mausezahn)" ]; then
  1118. echo "SKIP: Could not run test; need mausezahn tool"
  1119. return
  1120. fi
  1121. run_cmd "$IP nexthop add id 100 via 2001:db8:91::2 dev veth1"
  1122. run_cmd "$IP nexthop add id 101 via 2001:db8:92::2 dev veth3"
  1123. run_cmd "$IP nexthop add id 102 group 100/101 type resilient buckets 512 idle_timer 0"
  1124. run_cmd "$IP route add 2001:db8:101::1 nhid 102"
  1125. run_cmd "$IP route add 2001:db8:101::2 nhid 102"
  1126. ipv6_del_add_loop1 &
  1127. pid1=$!
  1128. ipv6_res_grp_replace_loop &
  1129. pid2=$!
  1130. ip netns exec $me ping -f 2001:db8:101::1 >/dev/null 2>&1 &
  1131. pid3=$!
  1132. ip netns exec $me ping -f 2001:db8:101::2 >/dev/null 2>&1 &
  1133. pid4=$!
  1134. ip netns exec $me mausezahn -6 veth1 \
  1135. -B 2001:db8:101::2 -A 2001:db8:91::1 -c 0 \
  1136. -t tcp "dp=1-1023, flags=syn" >/dev/null 2>&1 &
  1137. pid5=$!
  1138. sleep 300
  1139. kill -9 $pid1 $pid2 $pid3 $pid4 $pid5
  1140. wait $pid1 $pid2 $pid3 $pid4 $pid5 2>/dev/null
  1141. # if we did not crash, success
  1142. log_test 0 0 "IPv6 resilient nexthop group torture test"
  1143. }
  1144. ipv4_fcnal()
  1145. {
  1146. local rc
  1147. echo
  1148. echo "IPv4 functional"
  1149. echo "----------------------"
  1150. #
  1151. # basic IPv4 ops - add, get, delete
  1152. #
  1153. run_cmd "$IP nexthop add id 12 via 172.16.1.2 dev veth1"
  1154. rc=$?
  1155. log_test $rc 0 "Create nexthop with id, gw, dev"
  1156. if [ $rc -ne 0 ]; then
  1157. echo "Basic IPv4 create fails; can not continue"
  1158. return 1
  1159. fi
  1160. run_cmd "$IP nexthop get id 12"
  1161. log_test $? 0 "Get nexthop by id"
  1162. check_nexthop "id 12" "id 12 via 172.16.1.2 dev veth1 scope link"
  1163. run_cmd "$IP nexthop del id 12"
  1164. log_test $? 0 "Delete nexthop by id"
  1165. check_nexthop "id 52" ""
  1166. #
  1167. # gw, device spec
  1168. #
  1169. # gw validation, no device - fails since dev is required
  1170. run_cmd "$IP nexthop add id 12 via 172.16.2.3"
  1171. log_test $? 2 "Create nexthop - gw only"
  1172. # gw not reachable through given dev
  1173. run_cmd "$IP nexthop add id 13 via 172.16.3.2 dev veth1"
  1174. log_test $? 2 "Create nexthop - invalid gw+dev combination"
  1175. # onlink flag overrides gw+dev lookup
  1176. run_cmd "$IP nexthop add id 13 via 172.16.3.2 dev veth1 onlink"
  1177. log_test $? 0 "Create nexthop - gw+dev and onlink"
  1178. # admin down should delete nexthops
  1179. set -e
  1180. run_cmd "$IP nexthop add id 15 via 172.16.1.3 dev veth1"
  1181. run_cmd "$IP nexthop add id 16 via 172.16.1.4 dev veth1"
  1182. run_cmd "$IP nexthop add id 17 via 172.16.1.5 dev veth1"
  1183. run_cmd "$IP li set dev veth1 down"
  1184. set +e
  1185. check_nexthop "dev veth1" ""
  1186. log_test $? 0 "Nexthops removed on admin down"
  1187. # nexthop route delete warning: route add with nhid and delete
  1188. # using device
  1189. run_cmd "$IP li set dev veth1 up"
  1190. run_cmd "$IP nexthop add id 12 via 172.16.1.3 dev veth1"
  1191. out1=`dmesg | grep "WARNING:.*fib_nh_match.*" | wc -l`
  1192. run_cmd "$IP route add 172.16.101.1/32 nhid 12"
  1193. run_cmd "$IP route delete 172.16.101.1/32 dev veth1"
  1194. out2=`dmesg | grep "WARNING:.*fib_nh_match.*" | wc -l`
  1195. [ $out1 -eq $out2 ]
  1196. rc=$?
  1197. log_test $rc 0 "Delete nexthop route warning"
  1198. run_cmd "$IP route delete 172.16.101.1/32 nhid 12"
  1199. run_cmd "$IP nexthop del id 12"
  1200. run_cmd "$IP nexthop add id 21 via 172.16.1.6 dev veth1"
  1201. run_cmd "$IP ro add 172.16.101.0/24 nhid 21"
  1202. run_cmd "$IP ro del 172.16.101.0/24 nexthop via 172.16.1.7 dev veth1 nexthop via 172.16.1.8 dev veth1"
  1203. log_test $? 2 "Delete multipath route with only nh id based entry"
  1204. run_cmd "$IP nexthop add id 22 via 172.16.1.6 dev veth1"
  1205. run_cmd "$IP ro add 172.16.102.0/24 nhid 22"
  1206. run_cmd "$IP ro del 172.16.102.0/24 dev veth1"
  1207. log_test $? 2 "Delete route when specifying only nexthop device"
  1208. run_cmd "$IP ro del 172.16.102.0/24 via 172.16.1.6"
  1209. log_test $? 2 "Delete route when specifying only gateway"
  1210. run_cmd "$IP ro del 172.16.102.0/24"
  1211. log_test $? 0 "Delete route when not specifying nexthop attributes"
  1212. # error routes should be deleted when their nexthop is deleted
  1213. run_cmd "$IP nexthop add id 23 dev veth1"
  1214. run_cmd "$IP ro add blackhole 172.16.102.100/32 nhid 23"
  1215. run_cmd "$IP nexthop del id 23"
  1216. check_route "172.16.102.100" ""
  1217. log_test $? 0 "Error route removed on nexthop deletion"
  1218. }
  1219. ipv4_grp_fcnal()
  1220. {
  1221. local rc
  1222. echo
  1223. echo "IPv4 groups functional"
  1224. echo "----------------------"
  1225. # basic functionality: create a nexthop group, default weight
  1226. run_cmd "$IP nexthop add id 11 via 172.16.1.2 dev veth1"
  1227. run_cmd "$IP nexthop add id 101 group 11"
  1228. log_test $? 0 "Create nexthop group with single nexthop"
  1229. # get nexthop group
  1230. run_cmd "$IP nexthop get id 101"
  1231. log_test $? 0 "Get nexthop group by id"
  1232. check_nexthop "id 101" "id 101 group 11"
  1233. # delete nexthop group
  1234. run_cmd "$IP nexthop del id 101"
  1235. log_test $? 0 "Delete nexthop group by id"
  1236. check_nexthop "id 101" ""
  1237. $IP nexthop flush >/dev/null 2>&1
  1238. #
  1239. # create group with multiple nexthops
  1240. run_cmd "$IP nexthop add id 12 via 172.16.1.2 dev veth1"
  1241. run_cmd "$IP nexthop add id 13 via 172.16.1.3 dev veth1"
  1242. run_cmd "$IP nexthop add id 14 via 172.16.1.4 dev veth1"
  1243. run_cmd "$IP nexthop add id 15 via 172.16.1.5 dev veth1"
  1244. run_cmd "$IP nexthop add id 102 group 12/13/14/15"
  1245. log_test $? 0 "Nexthop group with multiple nexthops"
  1246. check_nexthop "id 102" "id 102 group 12/13/14/15"
  1247. # Delete nexthop in a group and group is updated
  1248. run_cmd "$IP nexthop del id 13"
  1249. check_nexthop "id 102" "id 102 group 12/14/15"
  1250. log_test $? 0 "Nexthop group updated when entry is deleted"
  1251. # create group with multiple weighted nexthops
  1252. run_cmd "$IP nexthop add id 13 via 172.16.1.3 dev veth1"
  1253. run_cmd "$IP nexthop add id 103 group 12/13,2/14,3/15,4"
  1254. log_test $? 0 "Nexthop group with weighted nexthops"
  1255. check_nexthop "id 103" "id 103 group 12/13,2/14,3/15,4"
  1256. # Delete nexthop in a weighted group and group is updated
  1257. run_cmd "$IP nexthop del id 13"
  1258. check_nexthop "id 103" "id 103 group 12/14,3/15,4"
  1259. log_test $? 0 "Weighted nexthop group updated when entry is deleted"
  1260. # admin down - nexthop is removed from group
  1261. run_cmd "$IP li set dev veth1 down"
  1262. check_nexthop "dev veth1" ""
  1263. log_test $? 0 "Nexthops in groups removed on admin down"
  1264. # expect groups to have been deleted as well
  1265. check_nexthop "" ""
  1266. run_cmd "$IP li set dev veth1 up"
  1267. $IP nexthop flush >/dev/null 2>&1
  1268. # group with nexthops using different devices
  1269. set -e
  1270. run_cmd "$IP nexthop add id 12 via 172.16.1.2 dev veth1"
  1271. run_cmd "$IP nexthop add id 13 via 172.16.1.3 dev veth1"
  1272. run_cmd "$IP nexthop add id 14 via 172.16.1.4 dev veth1"
  1273. run_cmd "$IP nexthop add id 15 via 172.16.1.5 dev veth1"
  1274. run_cmd "$IP nexthop add id 22 via 172.16.2.2 dev veth3"
  1275. run_cmd "$IP nexthop add id 23 via 172.16.2.3 dev veth3"
  1276. run_cmd "$IP nexthop add id 24 via 172.16.2.4 dev veth3"
  1277. run_cmd "$IP nexthop add id 25 via 172.16.2.5 dev veth3"
  1278. set +e
  1279. # multiple groups with same nexthop
  1280. run_cmd "$IP nexthop add id 104 group 12"
  1281. run_cmd "$IP nexthop add id 105 group 12"
  1282. check_nexthop "group" "id 104 group 12 id 105 group 12"
  1283. log_test $? 0 "Multiple groups with same nexthop"
  1284. run_cmd "$IP nexthop flush groups"
  1285. [ $? -ne 0 ] && return 1
  1286. # on admin down of veth1, it should be removed from the group
  1287. run_cmd "$IP nexthop add id 105 group 12/13/22/23/14"
  1288. run_cmd "$IP li set veth1 down"
  1289. check_nexthop "id 105" "id 105 group 22/23"
  1290. log_test $? 0 "Nexthops in group removed on admin down - mixed group"
  1291. run_cmd "$IP nexthop add id 106 group 105/24"
  1292. log_test $? 2 "Nexthop group can not have a group as an entry"
  1293. # a group can have a blackhole entry only if it is the only
  1294. # nexthop in the group. Needed for atomic replace with an
  1295. # actual nexthop group
  1296. run_cmd "$IP nexthop add id 31 blackhole"
  1297. run_cmd "$IP nexthop add id 107 group 31"
  1298. log_test $? 0 "Nexthop group with a blackhole entry"
  1299. run_cmd "$IP nexthop add id 108 group 31/24"
  1300. log_test $? 2 "Nexthop group can not have a blackhole and another nexthop"
  1301. }
  1302. ipv4_res_grp_fcnal()
  1303. {
  1304. local rc
  1305. echo
  1306. echo "IPv4 resilient groups functional"
  1307. echo "--------------------------------"
  1308. check_nexthop_res_support
  1309. if [ $? -eq $ksft_skip ]; then
  1310. return $ksft_skip
  1311. fi
  1312. #
  1313. # migration of nexthop buckets - equal weights
  1314. #
  1315. run_cmd "$IP nexthop add id 12 via 172.16.1.2 dev veth1"
  1316. run_cmd "$IP nexthop add id 13 via 172.16.1.3 dev veth1"
  1317. run_cmd "$IP nexthop add id 102 group 12/13 type resilient buckets 2 idle_timer 0"
  1318. run_cmd "$IP nexthop del id 13"
  1319. check_nexthop "id 102" \
  1320. "id 102 group 12 type resilient buckets 2 idle_timer 0 unbalanced_timer 0 unbalanced_time 0"
  1321. log_test $? 0 "Nexthop group updated when entry is deleted"
  1322. check_nexthop_bucket "list id 102" \
  1323. "id 102 index 0 nhid 12 id 102 index 1 nhid 12"
  1324. log_test $? 0 "Nexthop buckets updated when entry is deleted"
  1325. run_cmd "$IP nexthop add id 13 via 172.16.1.3 dev veth1"
  1326. run_cmd "$IP nexthop replace id 102 group 12/13 type resilient buckets 2 idle_timer 0"
  1327. check_nexthop "id 102" \
  1328. "id 102 group 12/13 type resilient buckets 2 idle_timer 0 unbalanced_timer 0 unbalanced_time 0"
  1329. log_test $? 0 "Nexthop group updated after replace"
  1330. check_nexthop_bucket "list id 102" \
  1331. "id 102 index 0 nhid 13 id 102 index 1 nhid 12"
  1332. log_test $? 0 "Nexthop buckets updated after replace"
  1333. $IP nexthop flush >/dev/null 2>&1
  1334. #
  1335. # migration of nexthop buckets - unequal weights
  1336. #
  1337. run_cmd "$IP nexthop add id 12 via 172.16.1.2 dev veth1"
  1338. run_cmd "$IP nexthop add id 13 via 172.16.1.3 dev veth1"
  1339. run_cmd "$IP nexthop add id 102 group 12,3/13,1 type resilient buckets 4 idle_timer 0"
  1340. run_cmd "$IP nexthop del id 13"
  1341. check_nexthop "id 102" \
  1342. "id 102 group 12,3 type resilient buckets 4 idle_timer 0 unbalanced_timer 0 unbalanced_time 0"
  1343. log_test $? 0 "Nexthop group updated when entry is deleted - nECMP"
  1344. check_nexthop_bucket "list id 102" \
  1345. "id 102 index 0 nhid 12 id 102 index 1 nhid 12 id 102 index 2 nhid 12 id 102 index 3 nhid 12"
  1346. log_test $? 0 "Nexthop buckets updated when entry is deleted - nECMP"
  1347. run_cmd "$IP nexthop add id 13 via 172.16.1.3 dev veth1"
  1348. run_cmd "$IP nexthop replace id 102 group 12,3/13,1 type resilient buckets 4 idle_timer 0"
  1349. check_nexthop "id 102" \
  1350. "id 102 group 12,3/13 type resilient buckets 4 idle_timer 0 unbalanced_timer 0 unbalanced_time 0"
  1351. log_test $? 0 "Nexthop group updated after replace - nECMP"
  1352. check_nexthop_bucket "list id 102" \
  1353. "id 102 index 0 nhid 13 id 102 index 1 nhid 12 id 102 index 2 nhid 12 id 102 index 3 nhid 12"
  1354. log_test $? 0 "Nexthop buckets updated after replace - nECMP"
  1355. }
  1356. ipv4_withv6_fcnal()
  1357. {
  1358. local lladdr
  1359. set -e
  1360. lladdr=$(get_linklocal veth2 $peer)
  1361. run_cmd "$IP nexthop add id 11 via ${lladdr} dev veth1"
  1362. set +e
  1363. run_cmd "$IP ro add 172.16.101.1/32 nhid 11"
  1364. log_test $? 0 "IPv6 nexthop with IPv4 route"
  1365. check_route "172.16.101.1" "172.16.101.1 nhid 11 via inet6 ${lladdr} dev veth1"
  1366. set -e
  1367. run_cmd "$IP nexthop add id 12 via 172.16.1.2 dev veth1"
  1368. run_cmd "$IP nexthop add id 101 group 11/12"
  1369. set +e
  1370. run_cmd "$IP ro replace 172.16.101.1/32 nhid 101"
  1371. log_test $? 0 "IPv6 nexthop with IPv4 route"
  1372. check_route "172.16.101.1" "172.16.101.1 nhid 101 nexthop via inet6 ${lladdr} dev veth1 weight 1 nexthop via 172.16.1.2 dev veth1 weight 1"
  1373. run_cmd "$IP ro replace 172.16.101.1/32 via inet6 ${lladdr} dev veth1"
  1374. log_test $? 0 "IPv4 route with IPv6 gateway"
  1375. check_route "172.16.101.1" "172.16.101.1 via inet6 ${lladdr} dev veth1"
  1376. run_cmd "$IP ro replace 172.16.101.1/32 via inet6 2001:db8:50::1 dev veth1"
  1377. log_test $? 2 "IPv4 route with invalid IPv6 gateway"
  1378. # Test IPv4 route with loopback IPv6 nexthop
  1379. # Regression test: loopback IPv6 nexthop was misclassified as reject
  1380. # route, skipping nhc_pcpu_rth_output allocation, causing panic when
  1381. # an IPv4 route references it and triggers __mkroute_output().
  1382. run_cmd "$IP -6 nexthop add id 20 dev lo"
  1383. run_cmd "$IP ro add 172.20.20.0/24 nhid 20"
  1384. run_cmd "ip netns exec $me ping -c1 -W1 172.20.20.1"
  1385. log_test $? 1 "IPv4 route with loopback IPv6 nexthop (no crash)"
  1386. run_cmd "$IP ro del 172.20.20.0/24"
  1387. run_cmd "$IP nexthop del id 20"
  1388. }
  1389. ipv4_fcnal_runtime()
  1390. {
  1391. local lladdr
  1392. local rc
  1393. echo
  1394. echo "IPv4 functional runtime"
  1395. echo "-----------------------"
  1396. run_cmd "$IP nexthop add id 21 via 172.16.1.2 dev veth1"
  1397. run_cmd "$IP ro add 172.16.101.1/32 nhid 21"
  1398. log_test $? 0 "Route add"
  1399. check_route "172.16.101.1" "172.16.101.1 nhid 21 via 172.16.1.2 dev veth1"
  1400. run_cmd "$IP ro delete 172.16.101.1/32 nhid 21"
  1401. log_test $? 0 "Route delete"
  1402. #
  1403. # scope mismatch
  1404. #
  1405. run_cmd "$IP nexthop add id 22 via 172.16.1.2 dev veth1"
  1406. run_cmd "$IP ro add 172.16.101.1/32 nhid 22 scope host"
  1407. log_test $? 2 "Route add - scope conflict with nexthop"
  1408. run_cmd "$IP nexthop replace id 22 dev veth3"
  1409. run_cmd "$IP ro add 172.16.101.1/32 nhid 22 scope host"
  1410. run_cmd "$IP nexthop replace id 22 via 172.16.2.2 dev veth3"
  1411. log_test $? 2 "Nexthop replace with invalid scope for existing route"
  1412. # check cleanup path on invalid metric
  1413. run_cmd "$IP ro add 172.16.101.2/32 nhid 22 congctl lock foo"
  1414. log_test $? 2 "IPv4 route with invalid metric"
  1415. #
  1416. # add route with nexthop and check traffic
  1417. #
  1418. run_cmd "$IP nexthop replace id 21 via 172.16.1.2 dev veth1"
  1419. run_cmd "$IP ro replace 172.16.101.1/32 nhid 21"
  1420. run_cmd "ip netns exec $me ping -c1 -w$PING_TIMEOUT 172.16.101.1"
  1421. log_test $? 0 "Basic ping"
  1422. run_cmd "$IP nexthop replace id 22 via 172.16.2.2 dev veth3"
  1423. run_cmd "$IP nexthop add id 122 group 21/22"
  1424. run_cmd "$IP ro replace 172.16.101.1/32 nhid 122"
  1425. run_cmd "ip netns exec $me ping -c1 -w$PING_TIMEOUT 172.16.101.1"
  1426. log_test $? 0 "Ping - multipath"
  1427. run_cmd "$IP ro delete 172.16.101.1/32 nhid 122"
  1428. #
  1429. # multiple default routes
  1430. # - tests fib_select_default
  1431. run_cmd "$IP nexthop add id 501 via 172.16.1.2 dev veth1"
  1432. run_cmd "$IP ro add default nhid 501"
  1433. run_cmd "$IP ro add default via 172.16.1.3 dev veth1 metric 20"
  1434. run_cmd "ip netns exec $me ping -c1 -w$PING_TIMEOUT 172.16.101.1"
  1435. log_test $? 0 "Ping - multiple default routes, nh first"
  1436. # flip the order
  1437. run_cmd "$IP ro del default nhid 501"
  1438. run_cmd "$IP ro del default via 172.16.1.3 dev veth1 metric 20"
  1439. run_cmd "$IP ro add default via 172.16.1.2 dev veth1 metric 20"
  1440. run_cmd "$IP nexthop replace id 501 via 172.16.1.3 dev veth1"
  1441. run_cmd "$IP ro add default nhid 501 metric 20"
  1442. run_cmd "ip netns exec $me ping -c1 -w$PING_TIMEOUT 172.16.101.1"
  1443. log_test $? 0 "Ping - multiple default routes, nh second"
  1444. run_cmd "$IP nexthop delete nhid 501"
  1445. run_cmd "$IP ro del default"
  1446. #
  1447. # IPv4 with blackhole nexthops
  1448. #
  1449. run_cmd "$IP nexthop add id 23 blackhole"
  1450. run_cmd "$IP ro replace 172.16.101.1/32 nhid 23"
  1451. run_cmd "ip netns exec $me ping -c1 -w$PING_TIMEOUT 172.16.101.1"
  1452. log_test $? 2 "Ping - blackhole"
  1453. run_cmd "$IP nexthop replace id 23 via 172.16.1.2 dev veth1"
  1454. run_cmd "ip netns exec $me ping -c1 -w$PING_TIMEOUT 172.16.101.1"
  1455. log_test $? 0 "Ping - blackhole replaced with gateway"
  1456. run_cmd "$IP nexthop replace id 23 blackhole"
  1457. run_cmd "ip netns exec $me ping -c1 -w$PING_TIMEOUT 172.16.101.1"
  1458. log_test $? 2 "Ping - gateway replaced by blackhole"
  1459. run_cmd "$IP ro replace 172.16.101.1/32 nhid 122"
  1460. run_cmd "ip netns exec $me ping -c1 -w$PING_TIMEOUT 172.16.101.1"
  1461. if [ $? -eq 0 ]; then
  1462. run_cmd "$IP nexthop replace id 122 group 23"
  1463. run_cmd "ip netns exec $me ping -c1 -w$PING_TIMEOUT 172.16.101.1"
  1464. log_test $? 2 "Ping - group with blackhole"
  1465. run_cmd "$IP nexthop replace id 122 group 21/22"
  1466. run_cmd "ip netns exec $me ping -c1 -w$PING_TIMEOUT 172.16.101.1"
  1467. log_test $? 0 "Ping - group blackhole replaced with gateways"
  1468. else
  1469. log_test 2 0 "Ping - multipath failed"
  1470. fi
  1471. #
  1472. # device only and gw + dev only mix
  1473. #
  1474. run_cmd "$IP nexthop add id 85 dev veth1"
  1475. run_cmd "$IP ro replace 172.16.101.1/32 nhid 85"
  1476. log_test $? 0 "IPv4 route with device only nexthop"
  1477. check_route "172.16.101.1" "172.16.101.1 nhid 85 dev veth1"
  1478. run_cmd "$IP nexthop add id 123 group 21/85"
  1479. run_cmd "$IP ro replace 172.16.101.1/32 nhid 123"
  1480. log_test $? 0 "IPv4 multipath route with nexthop mix - dev only + gw"
  1481. check_route "172.16.101.1" "172.16.101.1 nhid 123 nexthop via 172.16.1.2 dev veth1 weight 1 nexthop dev veth1 weight 1"
  1482. #
  1483. # IPv4 with IPv6
  1484. #
  1485. set -e
  1486. lladdr=$(get_linklocal veth2 $peer)
  1487. run_cmd "$IP nexthop add id 24 via ${lladdr} dev veth1"
  1488. set +e
  1489. run_cmd "$IP ro replace 172.16.101.1/32 nhid 24"
  1490. run_cmd "ip netns exec $me ping -c1 -w$PING_TIMEOUT 172.16.101.1"
  1491. log_test $? 0 "IPv6 nexthop with IPv4 route"
  1492. $IP neigh sh | grep -q "${lladdr} dev veth1"
  1493. if [ $? -eq 1 ]; then
  1494. echo " WARNING: Neigh entry missing for ${lladdr}"
  1495. $IP neigh sh | grep 'dev veth1'
  1496. fi
  1497. $IP neigh sh | grep -q "172.16.101.1 dev eth1"
  1498. if [ $? -eq 0 ]; then
  1499. echo " WARNING: Neigh entry exists for 172.16.101.1"
  1500. $IP neigh sh | grep 'dev veth1'
  1501. fi
  1502. set -e
  1503. run_cmd "$IP nexthop add id 25 via 172.16.1.2 dev veth1"
  1504. run_cmd "$IP nexthop add id 101 group 24/25"
  1505. set +e
  1506. run_cmd "$IP ro replace 172.16.101.1/32 nhid 101"
  1507. log_test $? 0 "IPv4 route with mixed v4-v6 multipath route"
  1508. check_route "172.16.101.1" "172.16.101.1 nhid 101 nexthop via inet6 ${lladdr} dev veth1 weight 1 nexthop via 172.16.1.2 dev veth1 weight 1"
  1509. run_cmd "ip netns exec $me ping -c1 -w$PING_TIMEOUT 172.16.101.1"
  1510. log_test $? 0 "IPv6 nexthop with IPv4 route"
  1511. run_cmd "$IP ro replace 172.16.101.1/32 via inet6 ${lladdr} dev veth1"
  1512. run_cmd "ip netns exec $me ping -c1 -w$PING_TIMEOUT 172.16.101.1"
  1513. log_test $? 0 "IPv4 route with IPv6 gateway"
  1514. $IP neigh sh | grep -q "${lladdr} dev veth1"
  1515. if [ $? -eq 1 ]; then
  1516. echo " WARNING: Neigh entry missing for ${lladdr}"
  1517. $IP neigh sh | grep 'dev veth1'
  1518. fi
  1519. $IP neigh sh | grep -q "172.16.101.1 dev eth1"
  1520. if [ $? -eq 0 ]; then
  1521. echo " WARNING: Neigh entry exists for 172.16.101.1"
  1522. $IP neigh sh | grep 'dev veth1'
  1523. fi
  1524. run_cmd "$IP ro del 172.16.101.1/32 via inet6 ${lladdr} dev veth1"
  1525. run_cmd "$IP -4 ro add default via inet6 ${lladdr} dev veth1"
  1526. run_cmd "ip netns exec $me ping -c1 -w$PING_TIMEOUT 172.16.101.1"
  1527. log_test $? 0 "IPv4 default route with IPv6 gateway"
  1528. #
  1529. # MPLS as an example of LWT encap
  1530. #
  1531. run_cmd "$IP nexthop add id 51 encap mpls 101 via 172.16.1.2 dev veth1"
  1532. log_test $? 0 "IPv4 route with MPLS encap"
  1533. check_nexthop "id 51" "id 51 encap mpls 101 via 172.16.1.2 dev veth1 scope link"
  1534. log_test $? 0 "IPv4 route with MPLS encap - check"
  1535. run_cmd "$IP nexthop add id 52 encap mpls 102 via inet6 2001:db8:91::2 dev veth1"
  1536. log_test $? 0 "IPv4 route with MPLS encap and v6 gateway"
  1537. check_nexthop "id 52" "id 52 encap mpls 102 via 2001:db8:91::2 dev veth1 scope link"
  1538. log_test $? 0 "IPv4 route with MPLS encap, v6 gw - check"
  1539. }
  1540. ipv4_large_grp()
  1541. {
  1542. local ecmp=32
  1543. echo
  1544. echo "IPv4 large groups (x$ecmp)"
  1545. echo "---------------------"
  1546. check_large_grp 4 $ecmp
  1547. $IP nexthop flush >/dev/null 2>&1
  1548. }
  1549. ipv4_large_res_grp()
  1550. {
  1551. echo
  1552. echo "IPv4 large resilient group (128k buckets)"
  1553. echo "-----------------------------------------"
  1554. check_nexthop_res_support
  1555. if [ $? -eq $ksft_skip ]; then
  1556. return $ksft_skip
  1557. fi
  1558. check_large_res_grp 4 $((128 * 1024))
  1559. $IP nexthop flush >/dev/null 2>&1
  1560. }
  1561. sysctl_nexthop_compat_mode_check()
  1562. {
  1563. local sysctlname="net.ipv4.nexthop_compat_mode"
  1564. local lprefix=$1
  1565. IPE="ip netns exec $me"
  1566. $IPE sysctl -q $sysctlname 2>&1 >/dev/null
  1567. if [ $? -ne 0 ]; then
  1568. echo "SKIP: kernel lacks nexthop compat mode sysctl control"
  1569. return $ksft_skip
  1570. fi
  1571. out=$($IPE sysctl $sysctlname 2>/dev/null)
  1572. log_test $? 0 "$lprefix default nexthop compat mode check"
  1573. check_output "${out}" "$sysctlname = 1"
  1574. }
  1575. sysctl_nexthop_compat_mode_set()
  1576. {
  1577. local sysctlname="net.ipv4.nexthop_compat_mode"
  1578. local mode=$1
  1579. local lprefix=$2
  1580. IPE="ip netns exec $me"
  1581. out=$($IPE sysctl -w $sysctlname=$mode)
  1582. log_test $? 0 "$lprefix set compat mode - $mode"
  1583. check_output "${out}" "net.ipv4.nexthop_compat_mode = $mode"
  1584. }
  1585. ipv6_compat_mode()
  1586. {
  1587. local rc
  1588. echo
  1589. echo "IPv6 nexthop api compat mode test"
  1590. echo "--------------------------------"
  1591. sysctl_nexthop_compat_mode_check "IPv6"
  1592. if [ $? -eq $ksft_skip ]; then
  1593. return $ksft_skip
  1594. fi
  1595. run_cmd "$IP nexthop add id 62 via 2001:db8:91::2 dev veth1"
  1596. run_cmd "$IP nexthop add id 63 via 2001:db8:91::3 dev veth1"
  1597. run_cmd "$IP nexthop add id 122 group 62/63"
  1598. ipmout=$(start_ip_monitor route)
  1599. run_cmd "$IP -6 ro add 2001:db8:101::1/128 nhid 122"
  1600. # route add notification should contain expanded nexthops
  1601. stop_ip_monitor $ipmout 3
  1602. log_test $? 0 "IPv6 compat mode on - route add notification"
  1603. # route dump should contain expanded nexthops
  1604. check_route6 "2001:db8:101::1" "2001:db8:101::1 nhid 122 metric 1024 nexthop via 2001:db8:91::2 dev veth1 weight 1 nexthop via 2001:db8:91::3 dev veth1 weight 1"
  1605. log_test $? 0 "IPv6 compat mode on - route dump"
  1606. # change in nexthop group should generate route notification
  1607. run_cmd "$IP nexthop add id 64 via 2001:db8:91::4 dev veth1"
  1608. ipmout=$(start_ip_monitor route)
  1609. run_cmd "$IP nexthop replace id 122 group 62/64"
  1610. stop_ip_monitor $ipmout 3
  1611. log_test $? 0 "IPv6 compat mode on - nexthop change"
  1612. # set compat mode off
  1613. sysctl_nexthop_compat_mode_set 0 "IPv6"
  1614. run_cmd "$IP -6 ro del 2001:db8:101::1/128 nhid 122"
  1615. run_cmd "$IP nexthop add id 62 via 2001:db8:91::2 dev veth1"
  1616. run_cmd "$IP nexthop add id 63 via 2001:db8:91::3 dev veth1"
  1617. run_cmd "$IP nexthop add id 122 group 62/63"
  1618. ipmout=$(start_ip_monitor route)
  1619. run_cmd "$IP -6 ro add 2001:db8:101::1/128 nhid 122"
  1620. # route add notification should not contain expanded nexthops
  1621. stop_ip_monitor $ipmout 1
  1622. log_test $? 0 "IPv6 compat mode off - route add notification"
  1623. # route dump should not contain expanded nexthops
  1624. check_route6 "2001:db8:101::1" "2001:db8:101::1 nhid 122 metric 1024"
  1625. log_test $? 0 "IPv6 compat mode off - route dump"
  1626. # change in nexthop group should not generate route notification
  1627. run_cmd "$IP nexthop add id 64 via 2001:db8:91::4 dev veth1"
  1628. ipmout=$(start_ip_monitor route)
  1629. run_cmd "$IP nexthop replace id 122 group 62/64"
  1630. stop_ip_monitor $ipmout 0
  1631. log_test $? 0 "IPv6 compat mode off - nexthop change"
  1632. # nexthop delete should not generate route notification
  1633. ipmout=$(start_ip_monitor route)
  1634. run_cmd "$IP nexthop del id 122"
  1635. stop_ip_monitor $ipmout 0
  1636. log_test $? 0 "IPv6 compat mode off - nexthop delete"
  1637. # set compat mode back on
  1638. sysctl_nexthop_compat_mode_set 1 "IPv6"
  1639. }
  1640. ipv4_compat_mode()
  1641. {
  1642. local rc
  1643. echo
  1644. echo "IPv4 nexthop api compat mode"
  1645. echo "----------------------------"
  1646. sysctl_nexthop_compat_mode_check "IPv4"
  1647. if [ $? -eq $ksft_skip ]; then
  1648. return $ksft_skip
  1649. fi
  1650. run_cmd "$IP nexthop add id 21 via 172.16.1.2 dev veth1"
  1651. run_cmd "$IP nexthop add id 22 via 172.16.1.2 dev veth1"
  1652. run_cmd "$IP nexthop add id 122 group 21/22"
  1653. ipmout=$(start_ip_monitor route)
  1654. run_cmd "$IP ro add 172.16.101.1/32 nhid 122"
  1655. stop_ip_monitor $ipmout 3
  1656. # route add notification should contain expanded nexthops
  1657. log_test $? 0 "IPv4 compat mode on - route add notification"
  1658. # route dump should contain expanded nexthops
  1659. check_route "172.16.101.1" "172.16.101.1 nhid 122 nexthop via 172.16.1.2 dev veth1 weight 1 nexthop via 172.16.1.2 dev veth1 weight 1"
  1660. log_test $? 0 "IPv4 compat mode on - route dump"
  1661. # change in nexthop group should generate route notification
  1662. run_cmd "$IP nexthop add id 23 via 172.16.1.3 dev veth1"
  1663. ipmout=$(start_ip_monitor route)
  1664. run_cmd "$IP nexthop replace id 122 group 21/23"
  1665. stop_ip_monitor $ipmout 3
  1666. log_test $? 0 "IPv4 compat mode on - nexthop change"
  1667. sysctl_nexthop_compat_mode_set 0 "IPv4"
  1668. # cleanup
  1669. run_cmd "$IP ro del 172.16.101.1/32 nhid 122"
  1670. ipmout=$(start_ip_monitor route)
  1671. run_cmd "$IP ro add 172.16.101.1/32 nhid 122"
  1672. stop_ip_monitor $ipmout 1
  1673. # route add notification should not contain expanded nexthops
  1674. log_test $? 0 "IPv4 compat mode off - route add notification"
  1675. # route dump should not contain expanded nexthops
  1676. check_route "172.16.101.1" "172.16.101.1 nhid 122"
  1677. log_test $? 0 "IPv4 compat mode off - route dump"
  1678. # change in nexthop group should not generate route notification
  1679. ipmout=$(start_ip_monitor route)
  1680. run_cmd "$IP nexthop replace id 122 group 21/22"
  1681. stop_ip_monitor $ipmout 0
  1682. log_test $? 0 "IPv4 compat mode off - nexthop change"
  1683. # nexthop delete should not generate route notification
  1684. ipmout=$(start_ip_monitor route)
  1685. run_cmd "$IP nexthop del id 122"
  1686. stop_ip_monitor $ipmout 0
  1687. log_test $? 0 "IPv4 compat mode off - nexthop delete"
  1688. sysctl_nexthop_compat_mode_set 1 "IPv4"
  1689. }
  1690. ipv4_del_add_loop1()
  1691. {
  1692. while :; do
  1693. $IP nexthop del id 100
  1694. $IP nexthop add id 100 via 172.16.1.2 dev veth1
  1695. done >/dev/null 2>&1
  1696. }
  1697. ipv4_grp_replace_loop()
  1698. {
  1699. while :; do
  1700. $IP nexthop replace id 102 group 100/101
  1701. done >/dev/null 2>&1
  1702. }
  1703. ipv4_torture()
  1704. {
  1705. local pid1
  1706. local pid2
  1707. local pid3
  1708. local pid4
  1709. local pid5
  1710. echo
  1711. echo "IPv4 runtime torture"
  1712. echo "--------------------"
  1713. if [ ! -x "$(command -v mausezahn)" ]; then
  1714. echo "SKIP: Could not run test; need mausezahn tool"
  1715. return
  1716. fi
  1717. run_cmd "$IP nexthop add id 100 via 172.16.1.2 dev veth1"
  1718. run_cmd "$IP nexthop add id 101 via 172.16.2.2 dev veth3"
  1719. run_cmd "$IP nexthop add id 102 group 100/101"
  1720. run_cmd "$IP route add 172.16.101.1 nhid 102"
  1721. run_cmd "$IP route add 172.16.101.2 nhid 102"
  1722. ipv4_del_add_loop1 &
  1723. pid1=$!
  1724. ipv4_grp_replace_loop &
  1725. pid2=$!
  1726. ip netns exec $me ping -f 172.16.101.1 >/dev/null 2>&1 &
  1727. pid3=$!
  1728. ip netns exec $me ping -f 172.16.101.2 >/dev/null 2>&1 &
  1729. pid4=$!
  1730. ip netns exec $me mausezahn veth1 -B 172.16.101.2 -A 172.16.1.1 -c 0 -t tcp "dp=1-1023, flags=syn" >/dev/null 2>&1 &
  1731. pid5=$!
  1732. sleep 300
  1733. kill -9 $pid1 $pid2 $pid3 $pid4 $pid5
  1734. wait $pid1 $pid2 $pid3 $pid4 $pid5 2>/dev/null
  1735. # if we did not crash, success
  1736. log_test 0 0 "IPv4 torture test"
  1737. }
  1738. ipv4_res_grp_replace_loop()
  1739. {
  1740. while :; do
  1741. $IP nexthop replace id 102 group 100/101 type resilient
  1742. done >/dev/null 2>&1
  1743. }
  1744. ipv4_res_torture()
  1745. {
  1746. local pid1
  1747. local pid2
  1748. local pid3
  1749. local pid4
  1750. local pid5
  1751. echo
  1752. echo "IPv4 runtime resilient nexthop group torture"
  1753. echo "--------------------------------------------"
  1754. check_nexthop_res_support
  1755. if [ $? -eq $ksft_skip ]; then
  1756. return $ksft_skip
  1757. fi
  1758. if [ ! -x "$(command -v mausezahn)" ]; then
  1759. echo "SKIP: Could not run test; need mausezahn tool"
  1760. return
  1761. fi
  1762. run_cmd "$IP nexthop add id 100 via 172.16.1.2 dev veth1"
  1763. run_cmd "$IP nexthop add id 101 via 172.16.2.2 dev veth3"
  1764. run_cmd "$IP nexthop add id 102 group 100/101 type resilient buckets 512 idle_timer 0"
  1765. run_cmd "$IP route add 172.16.101.1 nhid 102"
  1766. run_cmd "$IP route add 172.16.101.2 nhid 102"
  1767. ipv4_del_add_loop1 &
  1768. pid1=$!
  1769. ipv4_res_grp_replace_loop &
  1770. pid2=$!
  1771. ip netns exec $me ping -f 172.16.101.1 >/dev/null 2>&1 &
  1772. pid3=$!
  1773. ip netns exec $me ping -f 172.16.101.2 >/dev/null 2>&1 &
  1774. pid4=$!
  1775. ip netns exec $me mausezahn veth1 \
  1776. -B 172.16.101.2 -A 172.16.1.1 -c 0 \
  1777. -t tcp "dp=1-1023, flags=syn" >/dev/null 2>&1 &
  1778. pid5=$!
  1779. sleep 300
  1780. kill -9 $pid1 $pid2 $pid3 $pid4 $pid5
  1781. wait $pid1 $pid2 $pid3 $pid4 $pid5 2>/dev/null
  1782. # if we did not crash, success
  1783. log_test 0 0 "IPv4 resilient nexthop group torture test"
  1784. }
  1785. basic()
  1786. {
  1787. echo
  1788. echo "Basic functional tests"
  1789. echo "----------------------"
  1790. run_cmd "$IP nexthop ls"
  1791. log_test $? 0 "List with nothing defined"
  1792. run_cmd "$IP nexthop get id 1"
  1793. log_test $? 2 "Nexthop get on non-existent id"
  1794. run_cmd "$IP nexthop del id 1"
  1795. log_test $? 2 "Nexthop del with non-existent id"
  1796. run_cmd "$IP nexthop del id 1 group 1/2/3/4/5/6/7/8"
  1797. log_test $? 2 "Nexthop del with non-existent id and extra attributes"
  1798. # attempt to create nh without a device or gw - fails
  1799. run_cmd "$IP nexthop add id 1"
  1800. log_test $? 2 "Nexthop with no device or gateway"
  1801. # attempt to create nh with down device - fails
  1802. $IP li set veth1 down
  1803. run_cmd "$IP nexthop add id 1 dev veth1"
  1804. log_test $? 2 "Nexthop with down device"
  1805. # create nh with linkdown device - fails
  1806. $IP li set veth1 up
  1807. ip -netns $peer li set veth2 down
  1808. run_cmd "$IP nexthop add id 1 dev veth1"
  1809. log_test $? 2 "Nexthop with device that is linkdown"
  1810. ip -netns $peer li set veth2 up
  1811. # device only
  1812. run_cmd "$IP nexthop add id 1 dev veth1"
  1813. log_test $? 0 "Nexthop with device only"
  1814. # create nh with duplicate id
  1815. run_cmd "$IP nexthop add id 1 dev veth3"
  1816. log_test $? 2 "Nexthop with duplicate id"
  1817. # blackhole nexthop
  1818. run_cmd "$IP nexthop add id 2 blackhole"
  1819. log_test $? 0 "Blackhole nexthop"
  1820. # blackhole nexthop can not have other specs
  1821. run_cmd "$IP nexthop replace id 2 blackhole dev veth1"
  1822. log_test $? 2 "Blackhole nexthop with other attributes"
  1823. # blackhole nexthop should not be affected by the state of the loopback
  1824. # device
  1825. run_cmd "$IP link set dev lo down"
  1826. check_nexthop "id 2" "id 2 blackhole"
  1827. log_test $? 0 "Blackhole nexthop with loopback device down"
  1828. run_cmd "$IP link set dev lo up"
  1829. # Dump should not loop endlessly when maximum nexthop ID is configured.
  1830. run_cmd "$IP nexthop add id $((2**32-1)) blackhole"
  1831. run_cmd "timeout 5 $IP nexthop"
  1832. log_test $? 0 "Maximum nexthop ID dump"
  1833. #
  1834. # groups
  1835. #
  1836. run_cmd "$IP nexthop add id 101 group 1"
  1837. log_test $? 0 "Create group"
  1838. run_cmd "$IP nexthop add id 102 group 2"
  1839. log_test $? 0 "Create group with blackhole nexthop"
  1840. # multipath group can not have a blackhole as 1 path
  1841. run_cmd "$IP nexthop add id 103 group 1/2"
  1842. log_test $? 2 "Create multipath group where 1 path is a blackhole"
  1843. # multipath group can not have a member replaced by a blackhole
  1844. run_cmd "$IP nexthop replace id 2 dev veth3"
  1845. run_cmd "$IP nexthop replace id 102 group 1/2"
  1846. run_cmd "$IP nexthop replace id 2 blackhole"
  1847. log_test $? 2 "Multipath group can not have a member replaced by blackhole"
  1848. # attempt to create group with non-existent nexthop
  1849. run_cmd "$IP nexthop add id 103 group 12"
  1850. log_test $? 2 "Create group with non-existent nexthop"
  1851. # attempt to create group with same nexthop
  1852. run_cmd "$IP nexthop add id 103 group 1/1"
  1853. log_test $? 2 "Create group with same nexthop multiple times"
  1854. # replace nexthop with a group - fails
  1855. run_cmd "$IP nexthop replace id 2 group 1"
  1856. log_test $? 2 "Replace nexthop with nexthop group"
  1857. # replace nexthop group with a nexthop - fails
  1858. run_cmd "$IP nexthop replace id 101 dev veth1"
  1859. log_test $? 2 "Replace nexthop group with nexthop"
  1860. # nexthop group with other attributes fail
  1861. run_cmd "$IP nexthop add id 104 group 1 dev veth1"
  1862. log_test $? 2 "Nexthop group and device"
  1863. # Tests to ensure that flushing works as expected.
  1864. run_cmd "$IP nexthop add id 105 blackhole proto 99"
  1865. run_cmd "$IP nexthop add id 106 blackhole proto 100"
  1866. run_cmd "$IP nexthop add id 107 blackhole proto 99"
  1867. run_cmd "$IP nexthop flush proto 99"
  1868. check_nexthop "id 105" ""
  1869. check_nexthop "id 106" "id 106 blackhole proto 100"
  1870. check_nexthop "id 107" ""
  1871. run_cmd "$IP nexthop flush proto 100"
  1872. check_nexthop "id 106" ""
  1873. run_cmd "$IP nexthop flush proto 100"
  1874. log_test $? 0 "Test proto flush"
  1875. run_cmd "$IP nexthop add id 104 group 1 blackhole"
  1876. log_test $? 2 "Nexthop group and blackhole"
  1877. $IP nexthop flush >/dev/null 2>&1
  1878. # Test to ensure that flushing with a multi-part nexthop dump works as
  1879. # expected.
  1880. local batch_file=$(mktemp)
  1881. for i in $(seq 1 $((64 * 1024))); do
  1882. echo "nexthop add id $i blackhole" >> $batch_file
  1883. done
  1884. $IP -b $batch_file
  1885. $IP nexthop flush >/dev/null 2>&1
  1886. [[ $($IP nexthop | wc -l) -eq 0 ]]
  1887. log_test $? 0 "Large scale nexthop flushing"
  1888. rm $batch_file
  1889. }
  1890. check_nexthop_buckets_balance()
  1891. {
  1892. local nharg=$1; shift
  1893. local ret
  1894. while (($# > 0)); do
  1895. local selector=$1; shift
  1896. local condition=$1; shift
  1897. local count
  1898. count=$($IP -j nexthop bucket ${nharg} ${selector} | jq length)
  1899. (( $count $condition ))
  1900. ret=$?
  1901. if ((ret != 0)); then
  1902. return $ret
  1903. fi
  1904. done
  1905. return 0
  1906. }
  1907. basic_res()
  1908. {
  1909. echo
  1910. echo "Basic resilient nexthop group functional tests"
  1911. echo "----------------------------------------------"
  1912. check_nexthop_res_support
  1913. if [ $? -eq $ksft_skip ]; then
  1914. return $ksft_skip
  1915. fi
  1916. run_cmd "$IP nexthop add id 1 dev veth1"
  1917. #
  1918. # resilient nexthop group addition
  1919. #
  1920. run_cmd "$IP nexthop add id 101 group 1 type resilient buckets 8"
  1921. log_test $? 0 "Add a nexthop group with default parameters"
  1922. run_cmd "$IP nexthop get id 101"
  1923. check_nexthop "id 101" \
  1924. "id 101 group 1 type resilient buckets 8 idle_timer 120 unbalanced_timer 0 unbalanced_time 0"
  1925. log_test $? 0 "Get a nexthop group with default parameters"
  1926. run_cmd "$IP nexthop add id 102 group 1 type resilient
  1927. buckets 4 idle_timer 100 unbalanced_timer 5"
  1928. run_cmd "$IP nexthop get id 102"
  1929. check_nexthop "id 102" \
  1930. "id 102 group 1 type resilient buckets 4 idle_timer 100 unbalanced_timer 5 unbalanced_time 0"
  1931. log_test $? 0 "Get a nexthop group with non-default parameters"
  1932. run_cmd "$IP nexthop add id 103 group 1 type resilient buckets 0"
  1933. log_test $? 2 "Add a nexthop group with 0 buckets"
  1934. #
  1935. # resilient nexthop group replacement
  1936. #
  1937. run_cmd "$IP nexthop replace id 101 group 1 type resilient
  1938. buckets 8 idle_timer 240 unbalanced_timer 80"
  1939. log_test $? 0 "Replace nexthop group parameters"
  1940. check_nexthop "id 101" \
  1941. "id 101 group 1 type resilient buckets 8 idle_timer 240 unbalanced_timer 80 unbalanced_time 0"
  1942. log_test $? 0 "Get a nexthop group after replacing parameters"
  1943. run_cmd "$IP nexthop replace id 101 group 1 type resilient idle_timer 512"
  1944. log_test $? 0 "Replace idle timer"
  1945. check_nexthop "id 101" \
  1946. "id 101 group 1 type resilient buckets 8 idle_timer 512 unbalanced_timer 80 unbalanced_time 0"
  1947. log_test $? 0 "Get a nexthop group after replacing idle timer"
  1948. run_cmd "$IP nexthop replace id 101 group 1 type resilient unbalanced_timer 256"
  1949. log_test $? 0 "Replace unbalanced timer"
  1950. check_nexthop "id 101" \
  1951. "id 101 group 1 type resilient buckets 8 idle_timer 512 unbalanced_timer 256 unbalanced_time 0"
  1952. log_test $? 0 "Get a nexthop group after replacing unbalanced timer"
  1953. run_cmd "$IP nexthop replace id 101 group 1 type resilient"
  1954. log_test $? 0 "Replace with no parameters"
  1955. check_nexthop "id 101" \
  1956. "id 101 group 1 type resilient buckets 8 idle_timer 512 unbalanced_timer 256 unbalanced_time 0"
  1957. log_test $? 0 "Get a nexthop group after replacing no parameters"
  1958. run_cmd "$IP nexthop replace id 101 group 1"
  1959. log_test $? 2 "Replace nexthop group type - implicit"
  1960. run_cmd "$IP nexthop replace id 101 group 1 type mpath"
  1961. log_test $? 2 "Replace nexthop group type - explicit"
  1962. run_cmd "$IP nexthop replace id 101 group 1 type resilient buckets 1024"
  1963. log_test $? 2 "Replace number of nexthop buckets"
  1964. check_nexthop "id 101" \
  1965. "id 101 group 1 type resilient buckets 8 idle_timer 512 unbalanced_timer 256 unbalanced_time 0"
  1966. log_test $? 0 "Get a nexthop group after replacing with invalid parameters"
  1967. #
  1968. # resilient nexthop buckets dump
  1969. #
  1970. $IP nexthop flush >/dev/null 2>&1
  1971. run_cmd "$IP nexthop add id 1 dev veth1"
  1972. run_cmd "$IP nexthop add id 2 dev veth3"
  1973. run_cmd "$IP nexthop add id 101 group 1/2 type resilient buckets 4"
  1974. run_cmd "$IP nexthop add id 201 group 1/2"
  1975. check_nexthop_bucket "" \
  1976. "id 101 index 0 nhid 2 id 101 index 1 nhid 2 id 101 index 2 nhid 1 id 101 index 3 nhid 1"
  1977. log_test $? 0 "Dump all nexthop buckets"
  1978. check_nexthop_bucket "list id 101" \
  1979. "id 101 index 0 nhid 2 id 101 index 1 nhid 2 id 101 index 2 nhid 1 id 101 index 3 nhid 1"
  1980. log_test $? 0 "Dump all nexthop buckets in a group"
  1981. sleep 0.1
  1982. (( $($IP -j nexthop bucket list id 101 |
  1983. jq '[.[] | select(.bucket.idle_time > 0 and
  1984. .bucket.idle_time < 2)] | length') == 4 ))
  1985. log_test $? 0 "All nexthop buckets report a positive near-zero idle time"
  1986. check_nexthop_bucket "list dev veth1" \
  1987. "id 101 index 2 nhid 1 id 101 index 3 nhid 1"
  1988. log_test $? 0 "Dump all nexthop buckets with a specific nexthop device"
  1989. check_nexthop_bucket "list nhid 2" \
  1990. "id 101 index 0 nhid 2 id 101 index 1 nhid 2"
  1991. log_test $? 0 "Dump all nexthop buckets with a specific nexthop identifier"
  1992. run_cmd "$IP nexthop bucket list id 111"
  1993. log_test $? 2 "Dump all nexthop buckets in a non-existent group"
  1994. run_cmd "$IP nexthop bucket list id 201"
  1995. log_test $? 2 "Dump all nexthop buckets in a non-resilient group"
  1996. run_cmd "$IP nexthop bucket list dev bla"
  1997. log_test $? 255 "Dump all nexthop buckets using a non-existent device"
  1998. run_cmd "$IP nexthop bucket list groups"
  1999. log_test $? 255 "Dump all nexthop buckets with invalid 'groups' keyword"
  2000. run_cmd "$IP nexthop bucket list fdb"
  2001. log_test $? 255 "Dump all nexthop buckets with invalid 'fdb' keyword"
  2002. # Dump should not loop endlessly when maximum nexthop ID is configured.
  2003. run_cmd "$IP nexthop add id $((2**32-1)) group 1/2 type resilient buckets 4"
  2004. run_cmd "timeout 5 $IP nexthop bucket"
  2005. log_test $? 0 "Maximum nexthop ID dump"
  2006. #
  2007. # resilient nexthop buckets get requests
  2008. #
  2009. check_nexthop_bucket "get id 101 index 0" "id 101 index 0 nhid 2"
  2010. log_test $? 0 "Get a valid nexthop bucket"
  2011. run_cmd "$IP nexthop bucket get id 101 index 999"
  2012. log_test $? 2 "Get a nexthop bucket with valid group, but invalid index"
  2013. run_cmd "$IP nexthop bucket get id 201 index 0"
  2014. log_test $? 2 "Get a nexthop bucket from a non-resilient group"
  2015. run_cmd "$IP nexthop bucket get id 999 index 0"
  2016. log_test $? 2 "Get a nexthop bucket from a non-existent group"
  2017. #
  2018. # tests for bucket migration
  2019. #
  2020. $IP nexthop flush >/dev/null 2>&1
  2021. run_cmd "$IP nexthop add id 1 dev veth1"
  2022. run_cmd "$IP nexthop add id 2 dev veth3"
  2023. run_cmd "$IP nexthop add id 101
  2024. group 1/2 type resilient buckets 10
  2025. idle_timer 1 unbalanced_timer 20"
  2026. check_nexthop_buckets_balance "list id 101" \
  2027. "nhid 1" "== 5" \
  2028. "nhid 2" "== 5"
  2029. log_test $? 0 "Initial bucket allocation"
  2030. run_cmd "$IP nexthop replace id 101
  2031. group 1,2/2,3 type resilient"
  2032. check_nexthop_buckets_balance "list id 101" \
  2033. "nhid 1" "== 4" \
  2034. "nhid 2" "== 6"
  2035. log_test $? 0 "Bucket allocation after replace"
  2036. # Check that increase in idle timer does not make buckets appear busy.
  2037. run_cmd "$IP nexthop replace id 101
  2038. group 1,2/2,3 type resilient
  2039. idle_timer 10"
  2040. run_cmd "$IP nexthop replace id 101
  2041. group 1/2 type resilient"
  2042. check_nexthop_buckets_balance "list id 101" \
  2043. "nhid 1" "== 5" \
  2044. "nhid 2" "== 5"
  2045. log_test $? 0 "Buckets migrated after idle timer change"
  2046. $IP nexthop flush >/dev/null 2>&1
  2047. }
  2048. ################################################################################
  2049. # usage
  2050. usage()
  2051. {
  2052. cat <<EOF
  2053. usage: ${0##*/} OPTS
  2054. -t <test> Test(s) to run (default: all)
  2055. (options: $ALL_TESTS)
  2056. -4 IPv4 tests only
  2057. -6 IPv6 tests only
  2058. -p Pause on fail
  2059. -P Pause after each test before cleanup
  2060. -v verbose mode (show commands and output)
  2061. -w Timeout for ping
  2062. Runtime test
  2063. -n num Number of nexthops to target
  2064. -N Use new style to install routes in DUT
  2065. done
  2066. EOF
  2067. }
  2068. ################################################################################
  2069. # main
  2070. while getopts :t:pP46hvw: o
  2071. do
  2072. case $o in
  2073. t) TESTS=$OPTARG;;
  2074. 4) TESTS=${IPV4_TESTS};;
  2075. 6) TESTS=${IPV6_TESTS};;
  2076. p) PAUSE_ON_FAIL=yes;;
  2077. P) PAUSE=yes;;
  2078. v) VERBOSE=$(($VERBOSE + 1));;
  2079. w) PING_TIMEOUT=$OPTARG;;
  2080. h) usage; exit 0;;
  2081. *) usage; exit 1;;
  2082. esac
  2083. done
  2084. # make sure we don't pause twice
  2085. [ "${PAUSE}" = "yes" ] && PAUSE_ON_FAIL=no
  2086. if [ "$(id -u)" -ne 0 ];then
  2087. echo "SKIP: Need root privileges"
  2088. exit $ksft_skip;
  2089. fi
  2090. if [ ! -x "$(command -v ip)" ]; then
  2091. echo "SKIP: Could not run test without ip tool"
  2092. exit $ksft_skip
  2093. fi
  2094. ip help 2>&1 | grep -q nexthop
  2095. if [ $? -ne 0 ]; then
  2096. echo "SKIP: iproute2 too old, missing nexthop command"
  2097. exit $ksft_skip
  2098. fi
  2099. out=$(ip nexthop ls 2>&1 | grep -q "Operation not supported")
  2100. if [ $? -eq 0 ]; then
  2101. echo "SKIP: kernel lacks nexthop support"
  2102. exit $ksft_skip
  2103. fi
  2104. for t in $TESTS
  2105. do
  2106. case $t in
  2107. none) IP="ip -netns $peer"; setup; exit 0;;
  2108. *) setup; $t; cleanup;;
  2109. esac
  2110. done
  2111. if [ "$TESTS" != "none" ]; then
  2112. printf "\nTests passed: %3d\n" ${nsuccess}
  2113. printf "Tests failed: %3d\n" ${nfail}
  2114. printf "Tests skipped: %2d\n" ${nskip}
  2115. fi
  2116. exit $ret