fib_tests.sh 85 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998
  1. #!/bin/bash
  2. # SPDX-License-Identifier: GPL-2.0
  3. # This test is for checking IPv4 and IPv6 FIB behavior in response to
  4. # different events.
  5. source lib.sh
  6. ret=0
  7. # all tests in this script. Can be overridden with -t option
  8. TESTS="unregister down carrier nexthop suppress ipv6_notify ipv4_notify \
  9. ipv6_rt ipv4_rt ipv6_addr_metric ipv4_addr_metric ipv6_route_metrics \
  10. ipv4_route_metrics ipv4_route_v6_gw rp_filter ipv4_del_addr \
  11. ipv6_del_addr ipv4_mangle ipv6_mangle ipv4_bcast_neigh fib6_gc_test \
  12. ipv4_mpath_list ipv6_mpath_list ipv4_mpath_balance ipv6_mpath_balance \
  13. ipv4_mpath_balance_preferred fib6_ra_to_static"
  14. VERBOSE=0
  15. PAUSE_ON_FAIL=no
  16. PAUSE=no
  17. which ping6 > /dev/null 2>&1 && ping6=$(which ping6) || ping6=$(which ping)
  18. log_test()
  19. {
  20. local rc=$1
  21. local expected=$2
  22. local msg="$3"
  23. if [ ${rc} -eq ${expected} ]; then
  24. printf " TEST: %-60s [ OK ]\n" "${msg}"
  25. nsuccess=$((nsuccess+1))
  26. else
  27. ret=1
  28. nfail=$((nfail+1))
  29. printf " TEST: %-60s [FAIL]\n" "${msg}"
  30. if [ "${PAUSE_ON_FAIL}" = "yes" ]; then
  31. echo
  32. echo "hit enter to continue, 'q' to quit"
  33. read a
  34. [ "$a" = "q" ] && exit 1
  35. fi
  36. fi
  37. if [ "${PAUSE}" = "yes" ]; then
  38. echo
  39. echo "hit enter to continue, 'q' to quit"
  40. read a
  41. [ "$a" = "q" ] && exit 1
  42. fi
  43. }
  44. setup()
  45. {
  46. set -e
  47. setup_ns ns1
  48. IP="$(which ip) -netns $ns1"
  49. NS_EXEC="$(which ip) netns exec $ns1"
  50. ip netns exec $ns1 sysctl -qw net.ipv4.ip_forward=1
  51. ip netns exec $ns1 sysctl -qw net.ipv6.conf.all.forwarding=1
  52. $IP link add dummy0 type dummy
  53. $IP link set dev dummy0 up
  54. $IP address add 198.51.100.1/24 dev dummy0
  55. $IP -6 address add 2001:db8:1::1/64 dev dummy0
  56. set +e
  57. }
  58. cleanup()
  59. {
  60. $IP link del dev dummy0 &> /dev/null
  61. cleanup_ns $ns1 $ns2
  62. }
  63. get_linklocal()
  64. {
  65. local dev=$1
  66. local addr
  67. addr=$($IP -6 -br addr show dev ${dev} | \
  68. awk '{
  69. for (i = 3; i <= NF; ++i) {
  70. if ($i ~ /^fe80/)
  71. print $i
  72. }
  73. }'
  74. )
  75. addr=${addr/\/*}
  76. [ -z "$addr" ] && return 1
  77. echo $addr
  78. return 0
  79. }
  80. fib_unreg_unicast_test()
  81. {
  82. echo
  83. echo "Single path route test"
  84. setup
  85. echo " Start point"
  86. $IP route get fibmatch 198.51.100.2 &> /dev/null
  87. log_test $? 0 "IPv4 fibmatch"
  88. $IP -6 route get fibmatch 2001:db8:1::2 &> /dev/null
  89. log_test $? 0 "IPv6 fibmatch"
  90. set -e
  91. $IP link del dev dummy0
  92. set +e
  93. echo " Nexthop device deleted"
  94. $IP route get fibmatch 198.51.100.2 &> /dev/null
  95. log_test $? 2 "IPv4 fibmatch - no route"
  96. $IP -6 route get fibmatch 2001:db8:1::2 &> /dev/null
  97. log_test $? 2 "IPv6 fibmatch - no route"
  98. cleanup
  99. }
  100. fib_unreg_multipath_test()
  101. {
  102. echo
  103. echo "Multipath route test"
  104. setup
  105. set -e
  106. $IP link add dummy1 type dummy
  107. $IP link set dev dummy1 up
  108. $IP address add 192.0.2.1/24 dev dummy1
  109. $IP -6 address add 2001:db8:2::1/64 dev dummy1
  110. $IP route add 203.0.113.0/24 \
  111. nexthop via 198.51.100.2 dev dummy0 \
  112. nexthop via 192.0.2.2 dev dummy1
  113. $IP -6 route add 2001:db8:3::/64 \
  114. nexthop via 2001:db8:1::2 dev dummy0 \
  115. nexthop via 2001:db8:2::2 dev dummy1
  116. set +e
  117. echo " Start point"
  118. $IP route get fibmatch 203.0.113.1 &> /dev/null
  119. log_test $? 0 "IPv4 fibmatch"
  120. $IP -6 route get fibmatch 2001:db8:3::1 &> /dev/null
  121. log_test $? 0 "IPv6 fibmatch"
  122. set -e
  123. $IP link del dev dummy0
  124. set +e
  125. echo " One nexthop device deleted"
  126. $IP route get fibmatch 203.0.113.1 &> /dev/null
  127. log_test $? 2 "IPv4 - multipath route removed on delete"
  128. $IP -6 route get fibmatch 2001:db8:3::1 &> /dev/null
  129. # In IPv6 we do not flush the entire multipath route.
  130. log_test $? 0 "IPv6 - multipath down to single path"
  131. set -e
  132. $IP link del dev dummy1
  133. set +e
  134. echo " Second nexthop device deleted"
  135. $IP -6 route get fibmatch 2001:db8:3::1 &> /dev/null
  136. log_test $? 2 "IPv6 - no route"
  137. cleanup
  138. }
  139. fib_unreg_test()
  140. {
  141. fib_unreg_unicast_test
  142. fib_unreg_multipath_test
  143. }
  144. fib_down_unicast_test()
  145. {
  146. echo
  147. echo "Single path, admin down"
  148. setup
  149. echo " Start point"
  150. $IP route get fibmatch 198.51.100.2 &> /dev/null
  151. log_test $? 0 "IPv4 fibmatch"
  152. $IP -6 route get fibmatch 2001:db8:1::2 &> /dev/null
  153. log_test $? 0 "IPv6 fibmatch"
  154. set -e
  155. $IP link set dev dummy0 down
  156. set +e
  157. echo " Route deleted on down"
  158. $IP route get fibmatch 198.51.100.2 &> /dev/null
  159. log_test $? 2 "IPv4 fibmatch"
  160. $IP -6 route get fibmatch 2001:db8:1::2 &> /dev/null
  161. log_test $? 2 "IPv6 fibmatch"
  162. cleanup
  163. }
  164. fib_down_multipath_test_do()
  165. {
  166. local down_dev=$1
  167. local up_dev=$2
  168. $IP route get fibmatch 203.0.113.1 \
  169. oif $down_dev &> /dev/null
  170. log_test $? 2 "IPv4 fibmatch on down device"
  171. $IP -6 route get fibmatch 2001:db8:3::1 \
  172. oif $down_dev &> /dev/null
  173. log_test $? 2 "IPv6 fibmatch on down device"
  174. $IP route get fibmatch 203.0.113.1 \
  175. oif $up_dev &> /dev/null
  176. log_test $? 0 "IPv4 fibmatch on up device"
  177. $IP -6 route get fibmatch 2001:db8:3::1 \
  178. oif $up_dev &> /dev/null
  179. log_test $? 0 "IPv6 fibmatch on up device"
  180. $IP route get fibmatch 203.0.113.1 | \
  181. grep $down_dev | grep -q "dead linkdown"
  182. log_test $? 0 "IPv4 flags on down device"
  183. $IP -6 route get fibmatch 2001:db8:3::1 | \
  184. grep $down_dev | grep -q "dead linkdown"
  185. log_test $? 0 "IPv6 flags on down device"
  186. $IP route get fibmatch 203.0.113.1 | \
  187. grep $up_dev | grep -q "dead linkdown"
  188. log_test $? 1 "IPv4 flags on up device"
  189. $IP -6 route get fibmatch 2001:db8:3::1 | \
  190. grep $up_dev | grep -q "dead linkdown"
  191. log_test $? 1 "IPv6 flags on up device"
  192. }
  193. fib_down_multipath_test()
  194. {
  195. echo
  196. echo "Admin down multipath"
  197. setup
  198. set -e
  199. $IP link add dummy1 type dummy
  200. $IP link set dev dummy1 up
  201. $IP address add 192.0.2.1/24 dev dummy1
  202. $IP -6 address add 2001:db8:2::1/64 dev dummy1
  203. $IP route add 203.0.113.0/24 \
  204. nexthop via 198.51.100.2 dev dummy0 \
  205. nexthop via 192.0.2.2 dev dummy1
  206. $IP -6 route add 2001:db8:3::/64 \
  207. nexthop via 2001:db8:1::2 dev dummy0 \
  208. nexthop via 2001:db8:2::2 dev dummy1
  209. set +e
  210. echo " Verify start point"
  211. $IP route get fibmatch 203.0.113.1 &> /dev/null
  212. log_test $? 0 "IPv4 fibmatch"
  213. $IP -6 route get fibmatch 2001:db8:3::1 &> /dev/null
  214. log_test $? 0 "IPv6 fibmatch"
  215. set -e
  216. $IP link set dev dummy0 down
  217. set +e
  218. echo " One device down, one up"
  219. fib_down_multipath_test_do "dummy0" "dummy1"
  220. set -e
  221. $IP link set dev dummy0 up
  222. $IP link set dev dummy1 down
  223. set +e
  224. echo " Other device down and up"
  225. fib_down_multipath_test_do "dummy1" "dummy0"
  226. set -e
  227. $IP link set dev dummy0 down
  228. set +e
  229. echo " Both devices down"
  230. $IP route get fibmatch 203.0.113.1 &> /dev/null
  231. log_test $? 2 "IPv4 fibmatch"
  232. $IP -6 route get fibmatch 2001:db8:3::1 &> /dev/null
  233. log_test $? 2 "IPv6 fibmatch"
  234. $IP link del dev dummy1
  235. cleanup
  236. }
  237. fib_down_test()
  238. {
  239. fib_down_unicast_test
  240. fib_down_multipath_test
  241. }
  242. # Local routes should not be affected when carrier changes.
  243. fib_carrier_local_test()
  244. {
  245. echo
  246. echo "Local carrier tests - single path"
  247. setup
  248. set -e
  249. $IP link set dev dummy0 carrier on
  250. set +e
  251. echo " Start point"
  252. $IP route get fibmatch 198.51.100.1 &> /dev/null
  253. log_test $? 0 "IPv4 fibmatch"
  254. $IP -6 route get fibmatch 2001:db8:1::1 &> /dev/null
  255. log_test $? 0 "IPv6 fibmatch"
  256. $IP route get fibmatch 198.51.100.1 | \
  257. grep -q "linkdown"
  258. log_test $? 1 "IPv4 - no linkdown flag"
  259. $IP -6 route get fibmatch 2001:db8:1::1 | \
  260. grep -q "linkdown"
  261. log_test $? 1 "IPv6 - no linkdown flag"
  262. set -e
  263. $IP link set dev dummy0 carrier off
  264. sleep 1
  265. set +e
  266. echo " Carrier off on nexthop"
  267. $IP route get fibmatch 198.51.100.1 &> /dev/null
  268. log_test $? 0 "IPv4 fibmatch"
  269. $IP -6 route get fibmatch 2001:db8:1::1 &> /dev/null
  270. log_test $? 0 "IPv6 fibmatch"
  271. $IP route get fibmatch 198.51.100.1 | \
  272. grep -q "linkdown"
  273. log_test $? 1 "IPv4 - linkdown flag set"
  274. $IP -6 route get fibmatch 2001:db8:1::1 | \
  275. grep -q "linkdown"
  276. log_test $? 1 "IPv6 - linkdown flag set"
  277. set -e
  278. $IP address add 192.0.2.1/24 dev dummy0
  279. $IP -6 address add 2001:db8:2::1/64 dev dummy0
  280. set +e
  281. echo " Route to local address with carrier down"
  282. $IP route get fibmatch 192.0.2.1 &> /dev/null
  283. log_test $? 0 "IPv4 fibmatch"
  284. $IP -6 route get fibmatch 2001:db8:2::1 &> /dev/null
  285. log_test $? 0 "IPv6 fibmatch"
  286. $IP route get fibmatch 192.0.2.1 | \
  287. grep -q "linkdown"
  288. log_test $? 1 "IPv4 linkdown flag set"
  289. $IP -6 route get fibmatch 2001:db8:2::1 | \
  290. grep -q "linkdown"
  291. log_test $? 1 "IPv6 linkdown flag set"
  292. cleanup
  293. }
  294. fib_carrier_unicast_test()
  295. {
  296. ret=0
  297. echo
  298. echo "Single path route carrier test"
  299. setup
  300. set -e
  301. $IP link set dev dummy0 carrier on
  302. set +e
  303. echo " Start point"
  304. $IP route get fibmatch 198.51.100.2 &> /dev/null
  305. log_test $? 0 "IPv4 fibmatch"
  306. $IP -6 route get fibmatch 2001:db8:1::2 &> /dev/null
  307. log_test $? 0 "IPv6 fibmatch"
  308. $IP route get fibmatch 198.51.100.2 | \
  309. grep -q "linkdown"
  310. log_test $? 1 "IPv4 no linkdown flag"
  311. $IP -6 route get fibmatch 2001:db8:1::2 | \
  312. grep -q "linkdown"
  313. log_test $? 1 "IPv6 no linkdown flag"
  314. set -e
  315. $IP link set dev dummy0 carrier off
  316. sleep 1
  317. set +e
  318. echo " Carrier down"
  319. $IP route get fibmatch 198.51.100.2 &> /dev/null
  320. log_test $? 0 "IPv4 fibmatch"
  321. $IP -6 route get fibmatch 2001:db8:1::2 &> /dev/null
  322. log_test $? 0 "IPv6 fibmatch"
  323. $IP route get fibmatch 198.51.100.2 | \
  324. grep -q "linkdown"
  325. log_test $? 0 "IPv4 linkdown flag set"
  326. $IP -6 route get fibmatch 2001:db8:1::2 | \
  327. grep -q "linkdown"
  328. log_test $? 0 "IPv6 linkdown flag set"
  329. set -e
  330. $IP address add 192.0.2.1/24 dev dummy0
  331. $IP -6 address add 2001:db8:2::1/64 dev dummy0
  332. set +e
  333. echo " Second address added with carrier down"
  334. $IP route get fibmatch 192.0.2.2 &> /dev/null
  335. log_test $? 0 "IPv4 fibmatch"
  336. $IP -6 route get fibmatch 2001:db8:2::2 &> /dev/null
  337. log_test $? 0 "IPv6 fibmatch"
  338. $IP route get fibmatch 192.0.2.2 | \
  339. grep -q "linkdown"
  340. log_test $? 0 "IPv4 linkdown flag set"
  341. $IP -6 route get fibmatch 2001:db8:2::2 | \
  342. grep -q "linkdown"
  343. log_test $? 0 "IPv6 linkdown flag set"
  344. cleanup
  345. }
  346. fib_carrier_test()
  347. {
  348. fib_carrier_local_test
  349. fib_carrier_unicast_test
  350. }
  351. fib_rp_filter_test()
  352. {
  353. echo
  354. echo "IPv4 rp_filter tests"
  355. setup
  356. set -e
  357. setup_ns ns2
  358. $IP link add name veth1 type veth peer name veth2
  359. $IP link set dev veth2 netns $ns2
  360. $IP address add 192.0.2.1/24 dev veth1
  361. ip -netns $ns2 address add 192.0.2.1/24 dev veth2
  362. $IP link set dev veth1 up
  363. ip -netns $ns2 link set dev veth2 up
  364. $IP link set dev lo address 52:54:00:6a:c7:5e
  365. $IP link set dev veth1 address 52:54:00:6a:c7:5e
  366. ip -netns $ns2 link set dev lo address 52:54:00:6a:c7:5e
  367. ip -netns $ns2 link set dev veth2 address 52:54:00:6a:c7:5e
  368. # 1. (ns2) redirect lo's egress to veth2's egress
  369. ip netns exec $ns2 tc qdisc add dev lo parent root handle 1: fq_codel
  370. ip netns exec $ns2 tc filter add dev lo parent 1: protocol arp basic \
  371. action mirred egress redirect dev veth2
  372. ip netns exec $ns2 tc filter add dev lo parent 1: protocol ip basic \
  373. action mirred egress redirect dev veth2
  374. # 2. (ns1) redirect veth1's ingress to lo's ingress
  375. $NS_EXEC tc qdisc add dev veth1 ingress
  376. $NS_EXEC tc filter add dev veth1 ingress protocol arp basic \
  377. action mirred ingress redirect dev lo
  378. $NS_EXEC tc filter add dev veth1 ingress protocol ip basic \
  379. action mirred ingress redirect dev lo
  380. # 3. (ns1) redirect lo's egress to veth1's egress
  381. $NS_EXEC tc qdisc add dev lo parent root handle 1: fq_codel
  382. $NS_EXEC tc filter add dev lo parent 1: protocol arp basic \
  383. action mirred egress redirect dev veth1
  384. $NS_EXEC tc filter add dev lo parent 1: protocol ip basic \
  385. action mirred egress redirect dev veth1
  386. # 4. (ns2) redirect veth2's ingress to lo's ingress
  387. ip netns exec $ns2 tc qdisc add dev veth2 ingress
  388. ip netns exec $ns2 tc filter add dev veth2 ingress protocol arp basic \
  389. action mirred ingress redirect dev lo
  390. ip netns exec $ns2 tc filter add dev veth2 ingress protocol ip basic \
  391. action mirred ingress redirect dev lo
  392. $NS_EXEC sysctl -qw net.ipv4.conf.all.rp_filter=1
  393. $NS_EXEC sysctl -qw net.ipv4.conf.all.accept_local=1
  394. $NS_EXEC sysctl -qw net.ipv4.conf.all.route_localnet=1
  395. ip netns exec $ns2 sysctl -qw net.ipv4.conf.all.rp_filter=1
  396. ip netns exec $ns2 sysctl -qw net.ipv4.conf.all.accept_local=1
  397. ip netns exec $ns2 sysctl -qw net.ipv4.conf.all.route_localnet=1
  398. set +e
  399. run_cmd "ip netns exec $ns2 ping -w1 -c1 192.0.2.1"
  400. log_test $? 0 "rp_filter passes local packets"
  401. run_cmd "ip netns exec $ns2 ping -w1 -c1 127.0.0.1"
  402. log_test $? 0 "rp_filter passes loopback packets"
  403. cleanup
  404. }
  405. ################################################################################
  406. # Tests on nexthop spec
  407. # run 'ip route add' with given spec
  408. add_rt()
  409. {
  410. local desc="$1"
  411. local erc=$2
  412. local vrf=$3
  413. local pfx=$4
  414. local gw=$5
  415. local dev=$6
  416. local cmd out rc
  417. [ "$vrf" = "-" ] && vrf="default"
  418. [ -n "$gw" ] && gw="via $gw"
  419. [ -n "$dev" ] && dev="dev $dev"
  420. cmd="$IP route add vrf $vrf $pfx $gw $dev"
  421. if [ "$VERBOSE" = "1" ]; then
  422. printf "\n COMMAND: $cmd\n"
  423. fi
  424. out=$(eval $cmd 2>&1)
  425. rc=$?
  426. if [ "$VERBOSE" = "1" -a -n "$out" ]; then
  427. echo " $out"
  428. fi
  429. log_test $rc $erc "$desc"
  430. }
  431. fib4_nexthop()
  432. {
  433. echo
  434. echo "IPv4 nexthop tests"
  435. echo "<<< write me >>>"
  436. }
  437. fib6_nexthop()
  438. {
  439. local lldummy=$(get_linklocal dummy0)
  440. local llv1=$(get_linklocal dummy0)
  441. if [ -z "$lldummy" ]; then
  442. echo "Failed to get linklocal address for dummy0"
  443. return 1
  444. fi
  445. if [ -z "$llv1" ]; then
  446. echo "Failed to get linklocal address for veth1"
  447. return 1
  448. fi
  449. echo
  450. echo "IPv6 nexthop tests"
  451. add_rt "Directly connected nexthop, unicast address" 0 \
  452. - 2001:db8:101::/64 2001:db8:1::2
  453. add_rt "Directly connected nexthop, unicast address with device" 0 \
  454. - 2001:db8:102::/64 2001:db8:1::2 "dummy0"
  455. add_rt "Gateway is linklocal address" 0 \
  456. - 2001:db8:103::1/64 $llv1 "veth0"
  457. # fails because LL address requires a device
  458. add_rt "Gateway is linklocal address, no device" 2 \
  459. - 2001:db8:104::1/64 $llv1
  460. # local address can not be a gateway
  461. add_rt "Gateway can not be local unicast address" 2 \
  462. - 2001:db8:105::/64 2001:db8:1::1
  463. add_rt "Gateway can not be local unicast address, with device" 2 \
  464. - 2001:db8:106::/64 2001:db8:1::1 "dummy0"
  465. add_rt "Gateway can not be a local linklocal address" 2 \
  466. - 2001:db8:107::1/64 $lldummy "dummy0"
  467. # VRF tests
  468. add_rt "Gateway can be local address in a VRF" 0 \
  469. - 2001:db8:108::/64 2001:db8:51::2
  470. add_rt "Gateway can be local address in a VRF, with device" 0 \
  471. - 2001:db8:109::/64 2001:db8:51::2 "veth0"
  472. add_rt "Gateway can be local linklocal address in a VRF" 0 \
  473. - 2001:db8:110::1/64 $llv1 "veth0"
  474. add_rt "Redirect to VRF lookup" 0 \
  475. - 2001:db8:111::/64 "" "red"
  476. add_rt "VRF route, gateway can be local address in default VRF" 0 \
  477. red 2001:db8:112::/64 2001:db8:51::1
  478. # local address in same VRF fails
  479. add_rt "VRF route, gateway can not be a local address" 2 \
  480. red 2001:db8:113::1/64 2001:db8:2::1
  481. add_rt "VRF route, gateway can not be a local addr with device" 2 \
  482. red 2001:db8:114::1/64 2001:db8:2::1 "dummy1"
  483. }
  484. # Default VRF:
  485. # dummy0 - 198.51.100.1/24 2001:db8:1::1/64
  486. # veth0 - 192.0.2.1/24 2001:db8:51::1/64
  487. #
  488. # VRF red:
  489. # dummy1 - 192.168.2.1/24 2001:db8:2::1/64
  490. # veth1 - 192.0.2.2/24 2001:db8:51::2/64
  491. #
  492. # [ dummy0 veth0 ]--[ veth1 dummy1 ]
  493. fib_nexthop_test()
  494. {
  495. setup
  496. set -e
  497. $IP -4 rule add pref 32765 table local
  498. $IP -4 rule del pref 0
  499. $IP -6 rule add pref 32765 table local
  500. $IP -6 rule del pref 0
  501. $IP link add red type vrf table 1
  502. $IP link set red up
  503. $IP -4 route add vrf red unreachable default metric 4278198272
  504. $IP -6 route add vrf red unreachable default metric 4278198272
  505. $IP link add veth0 type veth peer name veth1
  506. $IP link set dev veth0 up
  507. $IP address add 192.0.2.1/24 dev veth0
  508. $IP -6 address add 2001:db8:51::1/64 dev veth0
  509. $IP link set dev veth1 vrf red up
  510. $IP address add 192.0.2.2/24 dev veth1
  511. $IP -6 address add 2001:db8:51::2/64 dev veth1
  512. $IP link add dummy1 type dummy
  513. $IP link set dev dummy1 vrf red up
  514. $IP address add 192.168.2.1/24 dev dummy1
  515. $IP -6 address add 2001:db8:2::1/64 dev dummy1
  516. set +e
  517. sleep 1
  518. fib4_nexthop
  519. fib6_nexthop
  520. (
  521. $IP link del dev dummy1
  522. $IP link del veth0
  523. $IP link del red
  524. ) 2>/dev/null
  525. cleanup
  526. }
  527. fib6_notify_test()
  528. {
  529. setup
  530. echo
  531. echo "Fib6 info length calculation in route notify test"
  532. set -e
  533. for i in 10 20 30 40 50 60 70;
  534. do
  535. $IP link add dummy_$i type dummy
  536. $IP link set dev dummy_$i up
  537. $IP -6 address add 2001:$i::1/64 dev dummy_$i
  538. done
  539. $NS_EXEC ip monitor route &> errors.txt &
  540. sleep 2
  541. $IP -6 route add 2001::/64 \
  542. nexthop via 2001:10::2 dev dummy_10 \
  543. nexthop encap ip6 dst 2002::20 via 2001:20::2 dev dummy_20 \
  544. nexthop encap ip6 dst 2002::30 via 2001:30::2 dev dummy_30 \
  545. nexthop encap ip6 dst 2002::40 via 2001:40::2 dev dummy_40 \
  546. nexthop encap ip6 dst 2002::50 via 2001:50::2 dev dummy_50 \
  547. nexthop encap ip6 dst 2002::60 via 2001:60::2 dev dummy_60 \
  548. nexthop encap ip6 dst 2002::70 via 2001:70::2 dev dummy_70
  549. set +e
  550. err=`cat errors.txt |grep "Message too long"`
  551. if [ -z "$err" ];then
  552. ret=0
  553. else
  554. ret=1
  555. fi
  556. log_test $ret 0 "ipv6 route add notify"
  557. kill_process %%
  558. #rm errors.txt
  559. cleanup &> /dev/null
  560. }
  561. fib_notify_test()
  562. {
  563. setup
  564. echo
  565. echo "Fib4 info length calculation in route notify test"
  566. set -e
  567. for i in 10 20 30 40 50 60 70;
  568. do
  569. $IP link add dummy_$i type dummy
  570. $IP link set dev dummy_$i up
  571. $IP address add 20.20.$i.2/24 dev dummy_$i
  572. done
  573. $NS_EXEC ip monitor route &> errors.txt &
  574. sleep 2
  575. $IP route add 10.0.0.0/24 \
  576. nexthop via 20.20.10.1 dev dummy_10 \
  577. nexthop encap ip dst 192.168.10.20 via 20.20.20.1 dev dummy_20 \
  578. nexthop encap ip dst 192.168.10.30 via 20.20.30.1 dev dummy_30 \
  579. nexthop encap ip dst 192.168.10.40 via 20.20.40.1 dev dummy_40 \
  580. nexthop encap ip dst 192.168.10.50 via 20.20.50.1 dev dummy_50 \
  581. nexthop encap ip dst 192.168.10.60 via 20.20.60.1 dev dummy_60 \
  582. nexthop encap ip dst 192.168.10.70 via 20.20.70.1 dev dummy_70
  583. set +e
  584. err=`cat errors.txt |grep "Message too long"`
  585. if [ -z "$err" ];then
  586. ret=0
  587. else
  588. ret=1
  589. fi
  590. log_test $ret 0 "ipv4 route add notify"
  591. kill_process %%
  592. rm errors.txt
  593. cleanup &> /dev/null
  594. }
  595. # Create a new dummy_10 to remove all associated routes.
  596. reset_dummy_10()
  597. {
  598. $IP link del dev dummy_10
  599. $IP link add dummy_10 type dummy
  600. $IP link set dev dummy_10 up
  601. $IP -6 address add 2001:10::1/64 dev dummy_10
  602. }
  603. check_rt_num()
  604. {
  605. local expected=$1
  606. local num=$2
  607. if [ $num -ne $expected ]; then
  608. echo "FAIL: Expected $expected routes, got $num"
  609. ret=1
  610. else
  611. ret=0
  612. fi
  613. }
  614. check_rt_num_clean()
  615. {
  616. local expected=$1
  617. local num=$2
  618. if [ $num -ne $expected ]; then
  619. log_test 1 0 "expected $expected routes, got $num"
  620. set +e
  621. cleanup &> /dev/null
  622. return 1
  623. fi
  624. return 0
  625. }
  626. fib6_gc_test()
  627. {
  628. setup
  629. echo
  630. echo "Fib6 garbage collection test"
  631. set -e
  632. EXPIRE=5
  633. GC_WAIT_TIME=$((EXPIRE * 2 + 2))
  634. # Check expiration of routes every $EXPIRE seconds (GC)
  635. $NS_EXEC sysctl -wq net.ipv6.route.gc_interval=$EXPIRE
  636. $IP link add dummy_10 type dummy
  637. $IP link set dev dummy_10 up
  638. $IP -6 address add 2001:10::1/64 dev dummy_10
  639. $NS_EXEC sysctl -wq net.ipv6.route.flush=1
  640. # Temporary routes
  641. for i in $(seq 1 5); do
  642. # Expire route after $EXPIRE seconds
  643. $IP -6 route add 2001:20::$i \
  644. via 2001:10::2 dev dummy_10 expires $EXPIRE
  645. done
  646. sleep $GC_WAIT_TIME
  647. $NS_EXEC sysctl -wq net.ipv6.route.flush=1
  648. check_rt_num 0 $($IP -6 route list |grep expires|wc -l)
  649. log_test $ret 0 "ipv6 route garbage collection"
  650. reset_dummy_10
  651. # Permanent routes
  652. for i in $(seq 1 5); do
  653. $IP -6 route add 2001:30::$i \
  654. via 2001:10::2 dev dummy_10
  655. done
  656. # Temporary routes
  657. for i in $(seq 1 5); do
  658. # Expire route after $EXPIRE seconds
  659. $IP -6 route add 2001:20::$i \
  660. via 2001:10::2 dev dummy_10 expires $EXPIRE
  661. done
  662. # Wait for GC
  663. sleep $GC_WAIT_TIME
  664. check_rt_num 0 $($IP -6 route list |grep expires|wc -l)
  665. log_test $ret 0 "ipv6 route garbage collection (with permanent routes)"
  666. reset_dummy_10
  667. # Permanent routes
  668. for i in $(seq 1 5); do
  669. $IP -6 route add 2001:20::$i \
  670. via 2001:10::2 dev dummy_10
  671. done
  672. # Replace with temporary routes
  673. for i in $(seq 1 5); do
  674. # Expire route after $EXPIRE seconds
  675. $IP -6 route replace 2001:20::$i \
  676. via 2001:10::2 dev dummy_10 expires $EXPIRE
  677. done
  678. # Wait for GC
  679. sleep $GC_WAIT_TIME
  680. check_rt_num 0 $($IP -6 route list |grep expires|wc -l)
  681. log_test $ret 0 "ipv6 route garbage collection (replace with expires)"
  682. reset_dummy_10
  683. # Temporary routes
  684. for i in $(seq 1 5); do
  685. # Expire route after $EXPIRE seconds
  686. $IP -6 route add 2001:20::$i \
  687. via 2001:10::2 dev dummy_10 expires $EXPIRE
  688. done
  689. # Replace with permanent routes
  690. for i in $(seq 1 5); do
  691. $IP -6 route replace 2001:20::$i \
  692. via 2001:10::2 dev dummy_10
  693. done
  694. check_rt_num_clean 0 $($IP -6 route list |grep expires|wc -l) || return
  695. # Wait for GC
  696. sleep $GC_WAIT_TIME
  697. check_rt_num 5 $($IP -6 route list |grep -v expires|grep 2001:20::|wc -l)
  698. log_test $ret 0 "ipv6 route garbage collection (replace with permanent)"
  699. # Delete dummy_10 and remove all routes
  700. $IP link del dev dummy_10
  701. # rd6 is required for the next test. (ipv6toolkit)
  702. if [ ! -x "$(command -v rd6)" ]; then
  703. echo "SKIP: rd6 not found."
  704. set +e
  705. cleanup &> /dev/null
  706. return
  707. fi
  708. setup_ns ns2
  709. $IP link add veth1 type veth peer veth2 netns $ns2
  710. $IP link set veth1 up
  711. ip -netns $ns2 link set veth2 up
  712. $IP addr add fe80:dead::1/64 dev veth1
  713. ip -netns $ns2 addr add fe80:dead::2/64 dev veth2
  714. # Add NTF_ROUTER neighbour to prevent rt6_age_examine_exception()
  715. # from removing not-yet-expired exceptions.
  716. ip -netns $ns2 link set veth2 address 00:11:22:33:44:55
  717. $IP neigh add fe80:dead::3 lladdr 00:11:22:33:44:55 dev veth1 router
  718. $NS_EXEC sysctl -wq net.ipv6.conf.veth1.accept_redirects=1
  719. $NS_EXEC sysctl -wq net.ipv6.conf.veth1.forwarding=0
  720. # Temporary routes
  721. for i in $(seq 1 5); do
  722. # Expire route after $EXPIRE seconds
  723. $IP -6 route add 2001:10::$i \
  724. via fe80:dead::2 dev veth1 expires $EXPIRE
  725. ip netns exec $ns2 rd6 -i veth2 \
  726. -s fe80:dead::2 -d fe80:dead::1 \
  727. -r 2001:10::$i -t fe80:dead::3 -p ICMP6
  728. done
  729. check_rt_num 5 $($IP -6 route list | grep expires | grep 2001:10:: | wc -l)
  730. # Promote to permanent routes by "prepend" (w/o NLM_F_EXCL and NLM_F_REPLACE)
  731. for i in $(seq 1 5); do
  732. # -EEXIST, but the temporary route becomes the permanent route.
  733. $IP -6 route append 2001:10::$i \
  734. via fe80:dead::2 dev veth1 2>/dev/null || true
  735. done
  736. check_rt_num 5 $($IP -6 route list | grep -v expires | grep 2001:10:: | wc -l)
  737. check_rt_num 5 $($IP -6 route list cache | grep 2001:10:: | wc -l)
  738. # Trigger GC instead of waiting $GC_WAIT_TIME.
  739. # rt6_nh_dump_exceptions() just skips expired exceptions.
  740. $NS_EXEC sysctl -wq net.ipv6.route.flush=1
  741. check_rt_num 0 $($IP -6 route list cache | grep 2001:10:: | wc -l)
  742. log_test $ret 0 "ipv6 route garbage collection (promote to permanent routes)"
  743. $IP neigh del fe80:dead::3 lladdr 00:11:22:33:44:55 dev veth1 router
  744. $IP link del veth1
  745. # ra6 is required for the next test. (ipv6toolkit)
  746. if [ ! -x "$(command -v ra6)" ]; then
  747. echo "SKIP: ra6 not found."
  748. set +e
  749. cleanup &> /dev/null
  750. return
  751. fi
  752. # Create a pair of veth devices to send a RA message from one
  753. # device to another.
  754. $IP link add veth1 type veth peer name veth2
  755. $IP link set dev veth1 up
  756. $IP link set dev veth2 up
  757. $IP -6 address add 2001:10::1/64 dev veth1 nodad
  758. $IP -6 address add 2001:10::2/64 dev veth2 nodad
  759. # Make veth1 ready to receive RA messages.
  760. $NS_EXEC sysctl -wq net.ipv6.conf.veth1.accept_ra=2
  761. # Send a RA message with a route from veth2 to veth1.
  762. $NS_EXEC ra6 -i veth2 -d 2001:10::1 -t $EXPIRE
  763. # Wait for the RA message.
  764. sleep 1
  765. # systemd may mess up the test. You syould make sure that
  766. # systemd-networkd.service and systemd-networkd.socket are stopped.
  767. check_rt_num_clean 1 $($IP -6 route list|grep expires|wc -l) || return
  768. # Wait for GC
  769. sleep $GC_WAIT_TIME
  770. check_rt_num 0 $($IP -6 route list |grep expires|wc -l)
  771. log_test $ret 0 "ipv6 route garbage collection (RA message)"
  772. set +e
  773. cleanup &> /dev/null
  774. }
  775. fib_suppress_test()
  776. {
  777. echo
  778. echo "FIB rule with suppress_prefixlength"
  779. setup
  780. $IP link add dummy1 type dummy
  781. $IP link set dummy1 up
  782. $IP -6 route add default dev dummy1
  783. $IP -6 rule add table main suppress_prefixlength 0
  784. ping -f -c 1000 -W 1 1234::1 >/dev/null 2>&1
  785. $IP -6 rule del table main suppress_prefixlength 0
  786. $IP link del dummy1
  787. # If we got here without crashing, we're good.
  788. log_test 0 0 "FIB rule suppress test"
  789. cleanup
  790. }
  791. ################################################################################
  792. # Tests on route add and replace
  793. run_cmd()
  794. {
  795. local cmd="$1"
  796. local out
  797. local stderr="2>/dev/null"
  798. if [ "$VERBOSE" = "1" ]; then
  799. printf " COMMAND: $cmd\n"
  800. stderr=
  801. fi
  802. out=$(eval $cmd $stderr)
  803. rc=$?
  804. if [ "$VERBOSE" = "1" -a -n "$out" ]; then
  805. echo " $out"
  806. fi
  807. [ "$VERBOSE" = "1" ] && echo
  808. return $rc
  809. }
  810. check_expected()
  811. {
  812. local out="$1"
  813. local expected="$2"
  814. local rc=0
  815. [ "${out}" = "${expected}" ] && return 0
  816. if [ -z "${out}" ]; then
  817. if [ "$VERBOSE" = "1" ]; then
  818. printf "\nNo route entry found\n"
  819. printf "Expected:\n"
  820. printf " ${expected}\n"
  821. fi
  822. return 1
  823. fi
  824. # tricky way to convert output to 1-line without ip's
  825. # messy '\'; this drops all extra white space
  826. out=$(echo ${out})
  827. if [ "${out}" != "${expected}" ]; then
  828. rc=1
  829. if [ "${VERBOSE}" = "1" ]; then
  830. printf " Unexpected route entry. Have:\n"
  831. printf " ${out}\n"
  832. printf " Expected:\n"
  833. printf " ${expected}\n\n"
  834. fi
  835. fi
  836. return $rc
  837. }
  838. # add route for a prefix, flushing any existing routes first
  839. # expected to be the first step of a test
  840. add_route6()
  841. {
  842. local pfx="$1"
  843. local nh="$2"
  844. local out
  845. if [ "$VERBOSE" = "1" ]; then
  846. echo
  847. echo " ##################################################"
  848. echo
  849. fi
  850. run_cmd "$IP -6 ro flush ${pfx}"
  851. [ $? -ne 0 ] && exit 1
  852. out=$($IP -6 ro ls match ${pfx})
  853. if [ -n "$out" ]; then
  854. echo "Failed to flush routes for prefix used for tests."
  855. exit 1
  856. fi
  857. run_cmd "$IP -6 ro add ${pfx} ${nh}"
  858. if [ $? -ne 0 ]; then
  859. echo "Failed to add initial route for test."
  860. exit 1
  861. fi
  862. }
  863. # add initial route - used in replace route tests
  864. add_initial_route6()
  865. {
  866. add_route6 "2001:db8:104::/64" "$1"
  867. }
  868. check_route6()
  869. {
  870. local pfx
  871. local expected="$1"
  872. local out
  873. local rc=0
  874. set -- $expected
  875. pfx=$1
  876. out=$($IP -6 ro ls match ${pfx} | sed -e 's/ pref medium//')
  877. check_expected "${out}" "${expected}"
  878. }
  879. route_cleanup()
  880. {
  881. $IP li del red 2>/dev/null
  882. $IP li del dummy1 2>/dev/null
  883. $IP li del veth1 2>/dev/null
  884. $IP li del veth3 2>/dev/null
  885. cleanup &> /dev/null
  886. }
  887. route_setup()
  888. {
  889. route_cleanup
  890. setup
  891. [ "${VERBOSE}" = "1" ] && set -x
  892. set -e
  893. setup_ns ns2
  894. ip netns exec $ns2 sysctl -qw net.ipv4.ip_forward=1
  895. ip netns exec $ns2 sysctl -qw net.ipv6.conf.all.forwarding=1
  896. $IP li add veth1 type veth peer name veth2
  897. $IP li add veth3 type veth peer name veth4
  898. $IP li set veth1 up
  899. $IP li set veth3 up
  900. $IP li set veth2 netns $ns2 up
  901. $IP li set veth4 netns $ns2 up
  902. ip -netns $ns2 li add dummy1 type dummy
  903. ip -netns $ns2 li set dummy1 up
  904. $IP -6 addr add 2001:db8:101::1/64 dev veth1 nodad
  905. $IP -6 addr add 2001:db8:103::1/64 dev veth3 nodad
  906. $IP addr add 172.16.101.1/24 dev veth1
  907. $IP addr add 172.16.103.1/24 dev veth3
  908. ip -netns $ns2 -6 addr add 2001:db8:101::2/64 dev veth2 nodad
  909. ip -netns $ns2 -6 addr add 2001:db8:103::2/64 dev veth4 nodad
  910. ip -netns $ns2 -6 addr add 2001:db8:104::1/64 dev dummy1 nodad
  911. ip -netns $ns2 addr add 172.16.101.2/24 dev veth2
  912. ip -netns $ns2 addr add 172.16.103.2/24 dev veth4
  913. ip -netns $ns2 addr add 172.16.104.1/24 dev dummy1
  914. set +e
  915. }
  916. forwarding_cleanup()
  917. {
  918. cleanup_ns $ns3
  919. route_cleanup
  920. }
  921. # extend route_setup with an ns3 reachable through ns2 over both devices
  922. forwarding_setup()
  923. {
  924. forwarding_cleanup
  925. route_setup
  926. setup_ns ns3
  927. ip link add veth5 netns $ns3 type veth peer name veth6 netns $ns2
  928. ip -netns $ns3 link set veth5 up
  929. ip -netns $ns2 link set veth6 up
  930. ip -netns $ns3 -4 addr add dev veth5 172.16.105.1/24
  931. ip -netns $ns2 -4 addr add dev veth6 172.16.105.2/24
  932. ip -netns $ns3 -4 route add 172.16.100.0/22 via 172.16.105.2
  933. ip -netns $ns3 -6 addr add dev veth5 2001:db8:105::1/64 nodad
  934. ip -netns $ns2 -6 addr add dev veth6 2001:db8:105::2/64 nodad
  935. ip -netns $ns3 -6 route add 2001:db8:101::/33 via 2001:db8:105::2
  936. }
  937. # assumption is that basic add of a single path route works
  938. # otherwise just adding an address on an interface is broken
  939. ipv6_rt_add()
  940. {
  941. local rc
  942. echo
  943. echo "IPv6 route add / append tests"
  944. # route add same prefix - fails with EEXISTS b/c ip adds NLM_F_EXCL
  945. add_route6 "2001:db8:104::/64" "via 2001:db8:101::2"
  946. run_cmd "$IP -6 ro add 2001:db8:104::/64 via 2001:db8:103::2"
  947. log_test $? 2 "Attempt to add duplicate route - gw"
  948. # route add same prefix - fails with EEXISTS b/c ip adds NLM_F_EXCL
  949. add_route6 "2001:db8:104::/64" "via 2001:db8:101::2"
  950. run_cmd "$IP -6 ro add 2001:db8:104::/64 dev veth3"
  951. log_test $? 2 "Attempt to add duplicate route - dev only"
  952. # route add same prefix - fails with EEXISTS b/c ip adds NLM_F_EXCL
  953. add_route6 "2001:db8:104::/64" "via 2001:db8:101::2"
  954. run_cmd "$IP -6 ro add unreachable 2001:db8:104::/64"
  955. log_test $? 2 "Attempt to add duplicate route - reject route"
  956. # route append with same prefix adds a new route
  957. # - iproute2 sets NLM_F_CREATE | NLM_F_APPEND
  958. add_route6 "2001:db8:104::/64" "via 2001:db8:101::2"
  959. run_cmd "$IP -6 ro append 2001:db8:104::/64 via 2001:db8:103::2"
  960. check_route6 "2001:db8:104::/64 metric 1024 nexthop via 2001:db8:101::2 dev veth1 weight 1 nexthop via 2001:db8:103::2 dev veth3 weight 1"
  961. log_test $? 0 "Append nexthop to existing route - gw"
  962. # insert mpath directly
  963. add_route6 "2001:db8:104::/64" "nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2"
  964. check_route6 "2001:db8:104::/64 metric 1024 nexthop via 2001:db8:101::2 dev veth1 weight 1 nexthop via 2001:db8:103::2 dev veth3 weight 1"
  965. log_test $? 0 "Add multipath route"
  966. add_route6 "2001:db8:104::/64" "nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2"
  967. run_cmd "$IP -6 ro add 2001:db8:104::/64 nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2"
  968. log_test $? 2 "Attempt to add duplicate multipath route"
  969. # insert of a second route without append but different metric
  970. add_route6 "2001:db8:104::/64" "via 2001:db8:101::2"
  971. run_cmd "$IP -6 ro add 2001:db8:104::/64 via 2001:db8:103::2 metric 512"
  972. rc=$?
  973. if [ $rc -eq 0 ]; then
  974. run_cmd "$IP -6 ro add 2001:db8:104::/64 via 2001:db8:103::3 metric 256"
  975. rc=$?
  976. fi
  977. log_test $rc 0 "Route add with different metrics"
  978. run_cmd "$IP -6 ro del 2001:db8:104::/64 metric 512"
  979. rc=$?
  980. if [ $rc -eq 0 ]; then
  981. check_route6 "2001:db8:104::/64 via 2001:db8:103::3 dev veth3 metric 256 2001:db8:104::/64 via 2001:db8:101::2 dev veth1 metric 1024"
  982. rc=$?
  983. fi
  984. log_test $rc 0 "Route delete with metric"
  985. }
  986. ipv6_rt_replace_single()
  987. {
  988. # single path with single path
  989. #
  990. add_initial_route6 "via 2001:db8:101::2"
  991. run_cmd "$IP -6 ro replace 2001:db8:104::/64 via 2001:db8:103::2"
  992. check_route6 "2001:db8:104::/64 via 2001:db8:103::2 dev veth3 metric 1024"
  993. log_test $? 0 "Single path with single path"
  994. # single path with multipath
  995. #
  996. add_initial_route6 "nexthop via 2001:db8:101::2"
  997. run_cmd "$IP -6 ro replace 2001:db8:104::/64 nexthop via 2001:db8:101::3 nexthop via 2001:db8:103::2"
  998. check_route6 "2001:db8:104::/64 metric 1024 nexthop via 2001:db8:101::3 dev veth1 weight 1 nexthop via 2001:db8:103::2 dev veth3 weight 1"
  999. log_test $? 0 "Single path with multipath"
  1000. # single path with single path using MULTIPATH attribute
  1001. #
  1002. add_initial_route6 "via 2001:db8:101::2"
  1003. run_cmd "$IP -6 ro replace 2001:db8:104::/64 nexthop via 2001:db8:103::2"
  1004. check_route6 "2001:db8:104::/64 via 2001:db8:103::2 dev veth3 metric 1024"
  1005. log_test $? 0 "Single path with single path via multipath attribute"
  1006. # route replace fails - invalid nexthop
  1007. add_initial_route6 "via 2001:db8:101::2"
  1008. run_cmd "$IP -6 ro replace 2001:db8:104::/64 via 2001:db8:104::2"
  1009. if [ $? -eq 0 ]; then
  1010. # previous command is expected to fail so if it returns 0
  1011. # that means the test failed.
  1012. log_test 0 1 "Invalid nexthop"
  1013. else
  1014. check_route6 "2001:db8:104::/64 via 2001:db8:101::2 dev veth1 metric 1024"
  1015. log_test $? 0 "Invalid nexthop"
  1016. fi
  1017. # replace non-existent route
  1018. # - note use of change versus replace since ip adds NLM_F_CREATE
  1019. # for replace
  1020. add_initial_route6 "via 2001:db8:101::2"
  1021. run_cmd "$IP -6 ro change 2001:db8:105::/64 via 2001:db8:101::2"
  1022. log_test $? 2 "Single path - replace of non-existent route"
  1023. }
  1024. ipv6_rt_replace_mpath()
  1025. {
  1026. # multipath with multipath
  1027. add_initial_route6 "nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2"
  1028. run_cmd "$IP -6 ro replace 2001:db8:104::/64 nexthop via 2001:db8:101::3 nexthop via 2001:db8:103::3"
  1029. check_route6 "2001:db8:104::/64 metric 1024 nexthop via 2001:db8:101::3 dev veth1 weight 1 nexthop via 2001:db8:103::3 dev veth3 weight 1"
  1030. log_test $? 0 "Multipath with multipath"
  1031. # multipath with single
  1032. add_initial_route6 "nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2"
  1033. run_cmd "$IP -6 ro replace 2001:db8:104::/64 via 2001:db8:101::3"
  1034. check_route6 "2001:db8:104::/64 via 2001:db8:101::3 dev veth1 metric 1024"
  1035. log_test $? 0 "Multipath with single path"
  1036. # multipath with single
  1037. add_initial_route6 "nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2"
  1038. run_cmd "$IP -6 ro replace 2001:db8:104::/64 nexthop via 2001:db8:101::3"
  1039. check_route6 "2001:db8:104::/64 via 2001:db8:101::3 dev veth1 metric 1024"
  1040. log_test $? 0 "Multipath with single path via multipath attribute"
  1041. # multipath with dev-only
  1042. add_initial_route6 "nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2"
  1043. run_cmd "$IP -6 ro replace 2001:db8:104::/64 dev veth1"
  1044. check_route6 "2001:db8:104::/64 dev veth1 metric 1024"
  1045. log_test $? 0 "Multipath with dev-only"
  1046. # route replace fails - invalid nexthop 1
  1047. add_initial_route6 "nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2"
  1048. run_cmd "$IP -6 ro replace 2001:db8:104::/64 nexthop via 2001:db8:111::3 nexthop via 2001:db8:103::3"
  1049. check_route6 "2001:db8:104::/64 metric 1024 nexthop via 2001:db8:101::2 dev veth1 weight 1 nexthop via 2001:db8:103::2 dev veth3 weight 1"
  1050. log_test $? 0 "Multipath - invalid first nexthop"
  1051. # route replace fails - invalid nexthop 2
  1052. add_initial_route6 "nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2"
  1053. run_cmd "$IP -6 ro replace 2001:db8:104::/64 nexthop via 2001:db8:101::3 nexthop via 2001:db8:113::3"
  1054. check_route6 "2001:db8:104::/64 metric 1024 nexthop via 2001:db8:101::2 dev veth1 weight 1 nexthop via 2001:db8:103::2 dev veth3 weight 1"
  1055. log_test $? 0 "Multipath - invalid second nexthop"
  1056. # multipath non-existent route
  1057. add_initial_route6 "nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2"
  1058. run_cmd "$IP -6 ro change 2001:db8:105::/64 nexthop via 2001:db8:101::3 nexthop via 2001:db8:103::3"
  1059. log_test $? 2 "Multipath - replace of non-existent route"
  1060. }
  1061. ipv6_rt_replace()
  1062. {
  1063. echo
  1064. echo "IPv6 route replace tests"
  1065. ipv6_rt_replace_single
  1066. ipv6_rt_replace_mpath
  1067. }
  1068. ipv6_rt_dsfield()
  1069. {
  1070. echo
  1071. echo "IPv6 route with dsfield tests"
  1072. run_cmd "$IP -6 route flush 2001:db8:102::/64"
  1073. # IPv6 doesn't support routing based on dsfield
  1074. run_cmd "$IP -6 route add 2001:db8:102::/64 dsfield 0x04 via 2001:db8:101::2"
  1075. log_test $? 2 "Reject route with dsfield"
  1076. }
  1077. ipv6_route_test()
  1078. {
  1079. route_setup
  1080. ipv6_rt_add
  1081. ipv6_rt_replace
  1082. ipv6_rt_dsfield
  1083. route_cleanup
  1084. }
  1085. ip_addr_metric_check()
  1086. {
  1087. ip addr help 2>&1 | grep -q metric
  1088. if [ $? -ne 0 ]; then
  1089. echo "iproute2 command does not support metric for addresses. Skipping test"
  1090. return 1
  1091. fi
  1092. return 0
  1093. }
  1094. ipv6_addr_metric_test()
  1095. {
  1096. local rc
  1097. echo
  1098. echo "IPv6 prefix route tests"
  1099. ip_addr_metric_check || return 1
  1100. setup
  1101. set -e
  1102. $IP li add dummy1 type dummy
  1103. $IP li add dummy2 type dummy
  1104. $IP li set dummy1 up
  1105. $IP li set dummy2 up
  1106. # default entry is metric 256
  1107. run_cmd "$IP -6 addr add dev dummy1 2001:db8:104::1/64"
  1108. run_cmd "$IP -6 addr add dev dummy2 2001:db8:104::2/64"
  1109. set +e
  1110. check_route6 "2001:db8:104::/64 dev dummy1 proto kernel metric 256 2001:db8:104::/64 dev dummy2 proto kernel metric 256"
  1111. log_test $? 0 "Default metric"
  1112. set -e
  1113. run_cmd "$IP -6 addr flush dev dummy1"
  1114. run_cmd "$IP -6 addr add dev dummy1 2001:db8:104::1/64 metric 257"
  1115. set +e
  1116. check_route6 "2001:db8:104::/64 dev dummy2 proto kernel metric 256 2001:db8:104::/64 dev dummy1 proto kernel metric 257"
  1117. log_test $? 0 "User specified metric on first device"
  1118. set -e
  1119. run_cmd "$IP -6 addr flush dev dummy2"
  1120. run_cmd "$IP -6 addr add dev dummy2 2001:db8:104::2/64 metric 258"
  1121. set +e
  1122. check_route6 "2001:db8:104::/64 dev dummy1 proto kernel metric 257 2001:db8:104::/64 dev dummy2 proto kernel metric 258"
  1123. log_test $? 0 "User specified metric on second device"
  1124. run_cmd "$IP -6 addr del dev dummy1 2001:db8:104::1/64 metric 257"
  1125. rc=$?
  1126. if [ $rc -eq 0 ]; then
  1127. check_route6 "2001:db8:104::/64 dev dummy2 proto kernel metric 258"
  1128. rc=$?
  1129. fi
  1130. log_test $rc 0 "Delete of address on first device"
  1131. run_cmd "$IP -6 addr change dev dummy2 2001:db8:104::2/64 metric 259"
  1132. rc=$?
  1133. if [ $rc -eq 0 ]; then
  1134. check_route6 "2001:db8:104::/64 dev dummy2 proto kernel metric 259"
  1135. rc=$?
  1136. fi
  1137. log_test $rc 0 "Modify metric of address"
  1138. # verify prefix route removed on down
  1139. run_cmd "ip netns exec $ns1 sysctl -qw net.ipv6.conf.all.keep_addr_on_down=1"
  1140. run_cmd "$IP li set dev dummy2 down"
  1141. rc=$?
  1142. if [ $rc -eq 0 ]; then
  1143. out=$($IP -6 ro ls match 2001:db8:104::/64)
  1144. check_expected "${out}" ""
  1145. rc=$?
  1146. fi
  1147. log_test $rc 0 "Prefix route removed on link down"
  1148. # verify prefix route re-inserted with assigned metric
  1149. run_cmd "$IP li set dev dummy2 up"
  1150. rc=$?
  1151. if [ $rc -eq 0 ]; then
  1152. check_route6 "2001:db8:104::/64 dev dummy2 proto kernel metric 259"
  1153. rc=$?
  1154. fi
  1155. log_test $rc 0 "Prefix route with metric on link up"
  1156. # verify peer metric added correctly
  1157. set -e
  1158. run_cmd "$IP -6 addr flush dev dummy2"
  1159. run_cmd "$IP -6 addr add dev dummy2 2001:db8:104::1 peer 2001:db8:104::2 metric 260"
  1160. set +e
  1161. check_route6 "2001:db8:104::1 dev dummy2 proto kernel metric 260"
  1162. log_test $? 0 "Set metric with peer route on local side"
  1163. check_route6 "2001:db8:104::2 dev dummy2 proto kernel metric 260"
  1164. log_test $? 0 "Set metric with peer route on peer side"
  1165. set -e
  1166. run_cmd "$IP -6 addr change dev dummy2 2001:db8:104::1 peer 2001:db8:104::3 metric 261"
  1167. set +e
  1168. check_route6 "2001:db8:104::1 dev dummy2 proto kernel metric 261"
  1169. log_test $? 0 "Modify metric and peer address on local side"
  1170. check_route6 "2001:db8:104::3 dev dummy2 proto kernel metric 261"
  1171. log_test $? 0 "Modify metric and peer address on peer side"
  1172. $IP li del dummy1
  1173. $IP li del dummy2
  1174. cleanup
  1175. }
  1176. ipv6_route_metrics_test()
  1177. {
  1178. local rc
  1179. echo
  1180. echo "IPv6 routes with metrics"
  1181. route_setup
  1182. #
  1183. # single path with metrics
  1184. #
  1185. run_cmd "$IP -6 ro add 2001:db8:111::/64 via 2001:db8:101::2 mtu 1400"
  1186. rc=$?
  1187. if [ $rc -eq 0 ]; then
  1188. check_route6 "2001:db8:111::/64 via 2001:db8:101::2 dev veth1 metric 1024 mtu 1400"
  1189. rc=$?
  1190. fi
  1191. log_test $rc 0 "Single path route with mtu metric"
  1192. #
  1193. # multipath via separate routes with metrics
  1194. #
  1195. run_cmd "$IP -6 ro add 2001:db8:112::/64 via 2001:db8:101::2 mtu 1400"
  1196. run_cmd "$IP -6 ro append 2001:db8:112::/64 via 2001:db8:103::2"
  1197. rc=$?
  1198. if [ $rc -eq 0 ]; then
  1199. check_route6 "2001:db8:112::/64 metric 1024 mtu 1400 nexthop via 2001:db8:101::2 dev veth1 weight 1 nexthop via 2001:db8:103::2 dev veth3 weight 1"
  1200. rc=$?
  1201. fi
  1202. log_test $rc 0 "Multipath route via 2 single routes with mtu metric on first"
  1203. # second route is coalesced to first to make a multipath route.
  1204. # MTU of the second path is hidden from display!
  1205. run_cmd "$IP -6 ro add 2001:db8:113::/64 via 2001:db8:101::2"
  1206. run_cmd "$IP -6 ro append 2001:db8:113::/64 via 2001:db8:103::2 mtu 1400"
  1207. rc=$?
  1208. if [ $rc -eq 0 ]; then
  1209. check_route6 "2001:db8:113::/64 metric 1024 nexthop via 2001:db8:101::2 dev veth1 weight 1 nexthop via 2001:db8:103::2 dev veth3 weight 1"
  1210. rc=$?
  1211. fi
  1212. log_test $rc 0 "Multipath route via 2 single routes with mtu metric on 2nd"
  1213. run_cmd "$IP -6 ro del 2001:db8:113::/64 via 2001:db8:101::2"
  1214. if [ $? -eq 0 ]; then
  1215. check_route6 "2001:db8:113::/64 via 2001:db8:103::2 dev veth3 metric 1024 mtu 1400"
  1216. log_test $? 0 " MTU of second leg"
  1217. fi
  1218. #
  1219. # multipath with metrics
  1220. #
  1221. run_cmd "$IP -6 ro add 2001:db8:115::/64 mtu 1400 nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2"
  1222. rc=$?
  1223. if [ $rc -eq 0 ]; then
  1224. check_route6 "2001:db8:115::/64 metric 1024 mtu 1400 nexthop via 2001:db8:101::2 dev veth1 weight 1 nexthop via 2001:db8:103::2 dev veth3 weight 1"
  1225. rc=$?
  1226. fi
  1227. log_test $rc 0 "Multipath route with mtu metric"
  1228. $IP -6 ro add 2001:db8:104::/64 via 2001:db8:101::2 mtu 1300
  1229. run_cmd "ip netns exec $ns1 ${ping6} -w1 -c1 -s 1500 2001:db8:104::1"
  1230. log_test $? 0 "Using route with mtu metric"
  1231. run_cmd "$IP -6 ro add 2001:db8:114::/64 via 2001:db8:101::2 congctl lock foo"
  1232. log_test $? 2 "Invalid metric (fails metric_convert)"
  1233. route_cleanup
  1234. }
  1235. fib6_ra_to_static()
  1236. {
  1237. setup
  1238. echo
  1239. echo "Fib6 route promotion from RA-learned to static test"
  1240. set -e
  1241. # ra6 is required for the test. (ipv6toolkit)
  1242. if [ ! -x "$(command -v ra6)" ]; then
  1243. echo "SKIP: ra6 not found."
  1244. set +e
  1245. cleanup &> /dev/null
  1246. return
  1247. fi
  1248. # Create a pair of veth devices to send a RA message from one
  1249. # device to another.
  1250. $IP link add veth1 type veth peer name veth2
  1251. $IP link set dev veth1 up
  1252. $IP link set dev veth2 up
  1253. $IP -6 address add 2001:10::1/64 dev veth1 nodad
  1254. $IP -6 address add 2001:10::2/64 dev veth2 nodad
  1255. # Make veth1 ready to receive RA messages.
  1256. $NS_EXEC sysctl -wq net.ipv6.conf.veth1.accept_ra=2
  1257. # Send a RA message with a prefix from veth2.
  1258. $NS_EXEC ra6 -i veth2 -d 2001:10::1 -P 2001:12::/64\#LA\#120\#60
  1259. # Wait for the RA message.
  1260. sleep 1
  1261. # systemd may mess up the test. Make sure that
  1262. # systemd-networkd.service and systemd-networkd.socket are stopped.
  1263. check_rt_num_clean 2 $($IP -6 route list|grep expires|wc -l) || return
  1264. # Configure static address on the same prefix
  1265. $IP -6 address add 2001:12::dead/64 dev veth1 nodad
  1266. # On-link route won't expire anymore, default route still owned by RA
  1267. check_rt_num 1 $($IP -6 route list |grep expires|wc -l)
  1268. # Send a second RA message with a prefix from veth2.
  1269. $NS_EXEC ra6 -i veth2 -d 2001:10::1 -P 2001:12::/64\#LA\#120\#60
  1270. sleep 1
  1271. # Expire is not back, on-link route is still static
  1272. check_rt_num 1 $($IP -6 route list |grep expires|wc -l)
  1273. $IP -6 address del 2001:12::dead/64 dev veth1 nodad
  1274. # Expire is back, on-link route is now owned by RA again
  1275. check_rt_num 2 $($IP -6 route list |grep expires|wc -l)
  1276. log_test $ret 0 "ipv6 promote RA route to static"
  1277. set +e
  1278. cleanup &> /dev/null
  1279. }
  1280. # add route for a prefix, flushing any existing routes first
  1281. # expected to be the first step of a test
  1282. add_route()
  1283. {
  1284. local pfx="$1"
  1285. local nh="$2"
  1286. local out
  1287. if [ "$VERBOSE" = "1" ]; then
  1288. echo
  1289. echo " ##################################################"
  1290. echo
  1291. fi
  1292. run_cmd "$IP ro flush ${pfx}"
  1293. [ $? -ne 0 ] && exit 1
  1294. out=$($IP ro ls match ${pfx})
  1295. if [ -n "$out" ]; then
  1296. echo "Failed to flush routes for prefix used for tests."
  1297. exit 1
  1298. fi
  1299. run_cmd "$IP ro add ${pfx} ${nh}"
  1300. if [ $? -ne 0 ]; then
  1301. echo "Failed to add initial route for test."
  1302. exit 1
  1303. fi
  1304. }
  1305. # add initial route - used in replace route tests
  1306. add_initial_route()
  1307. {
  1308. add_route "172.16.104.0/24" "$1"
  1309. }
  1310. check_route()
  1311. {
  1312. local pfx
  1313. local expected="$1"
  1314. local out
  1315. set -- $expected
  1316. pfx=$1
  1317. [ "${pfx}" = "unreachable" ] && pfx=$2
  1318. out=$($IP ro ls match ${pfx})
  1319. check_expected "${out}" "${expected}"
  1320. }
  1321. # assumption is that basic add of a single path route works
  1322. # otherwise just adding an address on an interface is broken
  1323. ipv4_rt_add()
  1324. {
  1325. local rc
  1326. echo
  1327. echo "IPv4 route add / append tests"
  1328. # route add same prefix - fails with EEXISTS b/c ip adds NLM_F_EXCL
  1329. add_route "172.16.104.0/24" "via 172.16.101.2"
  1330. run_cmd "$IP ro add 172.16.104.0/24 via 172.16.103.2"
  1331. log_test $? 2 "Attempt to add duplicate route - gw"
  1332. # route add same prefix - fails with EEXISTS b/c ip adds NLM_F_EXCL
  1333. add_route "172.16.104.0/24" "via 172.16.101.2"
  1334. run_cmd "$IP ro add 172.16.104.0/24 dev veth3"
  1335. log_test $? 2 "Attempt to add duplicate route - dev only"
  1336. # route add same prefix - fails with EEXISTS b/c ip adds NLM_F_EXCL
  1337. add_route "172.16.104.0/24" "via 172.16.101.2"
  1338. run_cmd "$IP ro add unreachable 172.16.104.0/24"
  1339. log_test $? 2 "Attempt to add duplicate route - reject route"
  1340. # iproute2 prepend only sets NLM_F_CREATE
  1341. # - adds a new route; does NOT convert existing route to ECMP
  1342. add_route "172.16.104.0/24" "via 172.16.101.2"
  1343. run_cmd "$IP ro prepend 172.16.104.0/24 via 172.16.103.2"
  1344. check_route "172.16.104.0/24 via 172.16.103.2 dev veth3 172.16.104.0/24 via 172.16.101.2 dev veth1"
  1345. log_test $? 0 "Add new nexthop for existing prefix"
  1346. # route append with same prefix adds a new route
  1347. # - iproute2 sets NLM_F_CREATE | NLM_F_APPEND
  1348. add_route "172.16.104.0/24" "via 172.16.101.2"
  1349. run_cmd "$IP ro append 172.16.104.0/24 via 172.16.103.2"
  1350. check_route "172.16.104.0/24 via 172.16.101.2 dev veth1 172.16.104.0/24 via 172.16.103.2 dev veth3"
  1351. log_test $? 0 "Append nexthop to existing route - gw"
  1352. add_route "172.16.104.0/24" "via 172.16.101.2"
  1353. run_cmd "$IP ro append 172.16.104.0/24 dev veth3"
  1354. check_route "172.16.104.0/24 via 172.16.101.2 dev veth1 172.16.104.0/24 dev veth3 scope link"
  1355. log_test $? 0 "Append nexthop to existing route - dev only"
  1356. add_route "172.16.104.0/24" "via 172.16.101.2"
  1357. run_cmd "$IP ro append unreachable 172.16.104.0/24"
  1358. check_route "172.16.104.0/24 via 172.16.101.2 dev veth1 unreachable 172.16.104.0/24"
  1359. log_test $? 0 "Append nexthop to existing route - reject route"
  1360. run_cmd "$IP ro flush 172.16.104.0/24"
  1361. run_cmd "$IP ro add unreachable 172.16.104.0/24"
  1362. run_cmd "$IP ro append 172.16.104.0/24 via 172.16.103.2"
  1363. check_route "unreachable 172.16.104.0/24 172.16.104.0/24 via 172.16.103.2 dev veth3"
  1364. log_test $? 0 "Append nexthop to existing reject route - gw"
  1365. run_cmd "$IP ro flush 172.16.104.0/24"
  1366. run_cmd "$IP ro add unreachable 172.16.104.0/24"
  1367. run_cmd "$IP ro append 172.16.104.0/24 dev veth3"
  1368. check_route "unreachable 172.16.104.0/24 172.16.104.0/24 dev veth3 scope link"
  1369. log_test $? 0 "Append nexthop to existing reject route - dev only"
  1370. # insert mpath directly
  1371. add_route "172.16.104.0/24" "nexthop via 172.16.101.2 nexthop via 172.16.103.2"
  1372. check_route "172.16.104.0/24 nexthop via 172.16.101.2 dev veth1 weight 1 nexthop via 172.16.103.2 dev veth3 weight 1"
  1373. log_test $? 0 "add multipath route"
  1374. add_route "172.16.104.0/24" "nexthop via 172.16.101.2 nexthop via 172.16.103.2"
  1375. run_cmd "$IP ro add 172.16.104.0/24 nexthop via 172.16.101.2 nexthop via 172.16.103.2"
  1376. log_test $? 2 "Attempt to add duplicate multipath route"
  1377. # insert of a second route without append but different metric
  1378. add_route "172.16.104.0/24" "via 172.16.101.2"
  1379. run_cmd "$IP ro add 172.16.104.0/24 via 172.16.103.2 metric 512"
  1380. rc=$?
  1381. if [ $rc -eq 0 ]; then
  1382. run_cmd "$IP ro add 172.16.104.0/24 via 172.16.103.3 metric 256"
  1383. rc=$?
  1384. fi
  1385. log_test $rc 0 "Route add with different metrics"
  1386. run_cmd "$IP ro del 172.16.104.0/24 metric 512"
  1387. rc=$?
  1388. if [ $rc -eq 0 ]; then
  1389. check_route "172.16.104.0/24 via 172.16.101.2 dev veth1 172.16.104.0/24 via 172.16.103.3 dev veth3 metric 256"
  1390. rc=$?
  1391. fi
  1392. log_test $rc 0 "Route delete with metric"
  1393. }
  1394. ipv4_rt_replace_single()
  1395. {
  1396. # single path with single path
  1397. #
  1398. add_initial_route "via 172.16.101.2"
  1399. run_cmd "$IP ro replace 172.16.104.0/24 via 172.16.103.2"
  1400. check_route "172.16.104.0/24 via 172.16.103.2 dev veth3"
  1401. log_test $? 0 "Single path with single path"
  1402. # single path with multipath
  1403. #
  1404. add_initial_route "nexthop via 172.16.101.2"
  1405. run_cmd "$IP ro replace 172.16.104.0/24 nexthop via 172.16.101.3 nexthop via 172.16.103.2"
  1406. check_route "172.16.104.0/24 nexthop via 172.16.101.3 dev veth1 weight 1 nexthop via 172.16.103.2 dev veth3 weight 1"
  1407. log_test $? 0 "Single path with multipath"
  1408. # single path with reject
  1409. #
  1410. add_initial_route "nexthop via 172.16.101.2"
  1411. run_cmd "$IP ro replace unreachable 172.16.104.0/24"
  1412. check_route "unreachable 172.16.104.0/24"
  1413. log_test $? 0 "Single path with reject route"
  1414. # single path with single path using MULTIPATH attribute
  1415. #
  1416. add_initial_route "via 172.16.101.2"
  1417. run_cmd "$IP ro replace 172.16.104.0/24 nexthop via 172.16.103.2"
  1418. check_route "172.16.104.0/24 via 172.16.103.2 dev veth3"
  1419. log_test $? 0 "Single path with single path via multipath attribute"
  1420. # route replace fails - invalid nexthop
  1421. add_initial_route "via 172.16.101.2"
  1422. run_cmd "$IP ro replace 172.16.104.0/24 via 2001:db8:104::2"
  1423. if [ $? -eq 0 ]; then
  1424. # previous command is expected to fail so if it returns 0
  1425. # that means the test failed.
  1426. log_test 0 1 "Invalid nexthop"
  1427. else
  1428. check_route "172.16.104.0/24 via 172.16.101.2 dev veth1"
  1429. log_test $? 0 "Invalid nexthop"
  1430. fi
  1431. # replace non-existent route
  1432. # - note use of change versus replace since ip adds NLM_F_CREATE
  1433. # for replace
  1434. add_initial_route "via 172.16.101.2"
  1435. run_cmd "$IP ro change 172.16.105.0/24 via 172.16.101.2"
  1436. log_test $? 2 "Single path - replace of non-existent route"
  1437. }
  1438. ipv4_rt_replace_mpath()
  1439. {
  1440. # multipath with multipath
  1441. add_initial_route "nexthop via 172.16.101.2 nexthop via 172.16.103.2"
  1442. run_cmd "$IP ro replace 172.16.104.0/24 nexthop via 172.16.101.3 nexthop via 172.16.103.3"
  1443. check_route "172.16.104.0/24 nexthop via 172.16.101.3 dev veth1 weight 1 nexthop via 172.16.103.3 dev veth3 weight 1"
  1444. log_test $? 0 "Multipath with multipath"
  1445. # multipath with single
  1446. add_initial_route "nexthop via 172.16.101.2 nexthop via 172.16.103.2"
  1447. run_cmd "$IP ro replace 172.16.104.0/24 via 172.16.101.3"
  1448. check_route "172.16.104.0/24 via 172.16.101.3 dev veth1"
  1449. log_test $? 0 "Multipath with single path"
  1450. # multipath with single
  1451. add_initial_route "nexthop via 172.16.101.2 nexthop via 172.16.103.2"
  1452. run_cmd "$IP ro replace 172.16.104.0/24 nexthop via 172.16.101.3"
  1453. check_route "172.16.104.0/24 via 172.16.101.3 dev veth1"
  1454. log_test $? 0 "Multipath with single path via multipath attribute"
  1455. # multipath with reject
  1456. add_initial_route "nexthop via 172.16.101.2 nexthop via 172.16.103.2"
  1457. run_cmd "$IP ro replace unreachable 172.16.104.0/24"
  1458. check_route "unreachable 172.16.104.0/24"
  1459. log_test $? 0 "Multipath with reject route"
  1460. # route replace fails - invalid nexthop 1
  1461. add_initial_route "nexthop via 172.16.101.2 nexthop via 172.16.103.2"
  1462. run_cmd "$IP ro replace 172.16.104.0/24 nexthop via 172.16.111.3 nexthop via 172.16.103.3"
  1463. check_route "172.16.104.0/24 nexthop via 172.16.101.2 dev veth1 weight 1 nexthop via 172.16.103.2 dev veth3 weight 1"
  1464. log_test $? 0 "Multipath - invalid first nexthop"
  1465. # route replace fails - invalid nexthop 2
  1466. add_initial_route "nexthop via 172.16.101.2 nexthop via 172.16.103.2"
  1467. run_cmd "$IP ro replace 172.16.104.0/24 nexthop via 172.16.101.3 nexthop via 172.16.113.3"
  1468. check_route "172.16.104.0/24 nexthop via 172.16.101.2 dev veth1 weight 1 nexthop via 172.16.103.2 dev veth3 weight 1"
  1469. log_test $? 0 "Multipath - invalid second nexthop"
  1470. # multipath non-existent route
  1471. add_initial_route "nexthop via 172.16.101.2 nexthop via 172.16.103.2"
  1472. run_cmd "$IP ro change 172.16.105.0/24 nexthop via 172.16.101.3 nexthop via 172.16.103.3"
  1473. log_test $? 2 "Multipath - replace of non-existent route"
  1474. }
  1475. ipv4_rt_replace()
  1476. {
  1477. echo
  1478. echo "IPv4 route replace tests"
  1479. ipv4_rt_replace_single
  1480. ipv4_rt_replace_mpath
  1481. }
  1482. # checks that cached input route on VRF port is deleted
  1483. # when VRF is deleted
  1484. ipv4_local_rt_cache()
  1485. {
  1486. run_cmd "ip addr add 10.0.0.1/32 dev lo"
  1487. run_cmd "setup_ns test-ns"
  1488. run_cmd "ip link add veth-outside type veth peer name veth-inside"
  1489. run_cmd "ip link add vrf-100 type vrf table 1100"
  1490. run_cmd "ip link set veth-outside master vrf-100"
  1491. run_cmd "ip link set veth-inside netns $test-ns"
  1492. run_cmd "ip link set veth-outside up"
  1493. run_cmd "ip link set vrf-100 up"
  1494. run_cmd "ip route add 10.1.1.1/32 dev veth-outside table 1100"
  1495. run_cmd "ip netns exec $test-ns ip link set veth-inside up"
  1496. run_cmd "ip netns exec $test-ns ip addr add 10.1.1.1/32 dev veth-inside"
  1497. run_cmd "ip netns exec $test-ns ip route add 10.0.0.1/32 dev veth-inside"
  1498. run_cmd "ip netns exec $test-ns ip route add default via 10.0.0.1"
  1499. run_cmd "ip netns exec $test-ns ping 10.0.0.1 -c 1 -i 1"
  1500. run_cmd "ip link delete vrf-100"
  1501. # if we do not hang test is a success
  1502. log_test $? 0 "Cached route removed from VRF port device"
  1503. }
  1504. ipv4_rt_dsfield()
  1505. {
  1506. echo
  1507. echo "IPv4 route with dsfield tests"
  1508. run_cmd "$IP route flush 172.16.102.0/24"
  1509. # New routes should reject dsfield options that interfere with ECN
  1510. run_cmd "$IP route add 172.16.102.0/24 dsfield 0x01 via 172.16.101.2"
  1511. log_test $? 2 "Reject route with dsfield 0x01"
  1512. run_cmd "$IP route add 172.16.102.0/24 dsfield 0x02 via 172.16.101.2"
  1513. log_test $? 2 "Reject route with dsfield 0x02"
  1514. run_cmd "$IP route add 172.16.102.0/24 dsfield 0x03 via 172.16.101.2"
  1515. log_test $? 2 "Reject route with dsfield 0x03"
  1516. # A generic route that doesn't take DSCP into account
  1517. run_cmd "$IP route add 172.16.102.0/24 via 172.16.101.2"
  1518. # A more specific route for DSCP 0x10
  1519. run_cmd "$IP route add 172.16.102.0/24 dsfield 0x10 via 172.16.103.2"
  1520. # DSCP 0x10 should match the specific route, no matter the ECN bits
  1521. $IP route get fibmatch 172.16.102.1 dsfield 0x10 | \
  1522. grep -q "172.16.102.0/24 tos 0x10 via 172.16.103.2"
  1523. log_test $? 0 "IPv4 route with DSCP and ECN:Not-ECT"
  1524. $IP route get fibmatch 172.16.102.1 dsfield 0x11 | \
  1525. grep -q "172.16.102.0/24 tos 0x10 via 172.16.103.2"
  1526. log_test $? 0 "IPv4 route with DSCP and ECN:ECT(1)"
  1527. $IP route get fibmatch 172.16.102.1 dsfield 0x12 | \
  1528. grep -q "172.16.102.0/24 tos 0x10 via 172.16.103.2"
  1529. log_test $? 0 "IPv4 route with DSCP and ECN:ECT(0)"
  1530. $IP route get fibmatch 172.16.102.1 dsfield 0x13 | \
  1531. grep -q "172.16.102.0/24 tos 0x10 via 172.16.103.2"
  1532. log_test $? 0 "IPv4 route with DSCP and ECN:CE"
  1533. # Unknown DSCP should match the generic route, no matter the ECN bits
  1534. $IP route get fibmatch 172.16.102.1 dsfield 0x14 | \
  1535. grep -q "172.16.102.0/24 via 172.16.101.2"
  1536. log_test $? 0 "IPv4 route with unknown DSCP and ECN:Not-ECT"
  1537. $IP route get fibmatch 172.16.102.1 dsfield 0x15 | \
  1538. grep -q "172.16.102.0/24 via 172.16.101.2"
  1539. log_test $? 0 "IPv4 route with unknown DSCP and ECN:ECT(1)"
  1540. $IP route get fibmatch 172.16.102.1 dsfield 0x16 | \
  1541. grep -q "172.16.102.0/24 via 172.16.101.2"
  1542. log_test $? 0 "IPv4 route with unknown DSCP and ECN:ECT(0)"
  1543. $IP route get fibmatch 172.16.102.1 dsfield 0x17 | \
  1544. grep -q "172.16.102.0/24 via 172.16.101.2"
  1545. log_test $? 0 "IPv4 route with unknown DSCP and ECN:CE"
  1546. # Null DSCP should match the generic route, no matter the ECN bits
  1547. $IP route get fibmatch 172.16.102.1 dsfield 0x00 | \
  1548. grep -q "172.16.102.0/24 via 172.16.101.2"
  1549. log_test $? 0 "IPv4 route with no DSCP and ECN:Not-ECT"
  1550. $IP route get fibmatch 172.16.102.1 dsfield 0x01 | \
  1551. grep -q "172.16.102.0/24 via 172.16.101.2"
  1552. log_test $? 0 "IPv4 route with no DSCP and ECN:ECT(1)"
  1553. $IP route get fibmatch 172.16.102.1 dsfield 0x02 | \
  1554. grep -q "172.16.102.0/24 via 172.16.101.2"
  1555. log_test $? 0 "IPv4 route with no DSCP and ECN:ECT(0)"
  1556. $IP route get fibmatch 172.16.102.1 dsfield 0x03 | \
  1557. grep -q "172.16.102.0/24 via 172.16.101.2"
  1558. log_test $? 0 "IPv4 route with no DSCP and ECN:CE"
  1559. }
  1560. ipv4_route_test()
  1561. {
  1562. route_setup
  1563. ipv4_rt_add
  1564. ipv4_rt_replace
  1565. ipv4_local_rt_cache
  1566. ipv4_rt_dsfield
  1567. route_cleanup
  1568. }
  1569. ipv4_addr_metric_test()
  1570. {
  1571. local rc
  1572. echo
  1573. echo "IPv4 prefix route tests"
  1574. ip_addr_metric_check || return 1
  1575. setup
  1576. set -e
  1577. $IP li add dummy1 type dummy
  1578. $IP li add dummy2 type dummy
  1579. $IP li set dummy1 up
  1580. $IP li set dummy2 up
  1581. # default entry is metric 256
  1582. run_cmd "$IP addr add dev dummy1 172.16.104.1/24"
  1583. run_cmd "$IP addr add dev dummy2 172.16.104.2/24"
  1584. set +e
  1585. check_route "172.16.104.0/24 dev dummy1 proto kernel scope link src 172.16.104.1 172.16.104.0/24 dev dummy2 proto kernel scope link src 172.16.104.2"
  1586. log_test $? 0 "Default metric"
  1587. set -e
  1588. run_cmd "$IP addr flush dev dummy1"
  1589. run_cmd "$IP addr add dev dummy1 172.16.104.1/24 metric 257"
  1590. set +e
  1591. check_route "172.16.104.0/24 dev dummy2 proto kernel scope link src 172.16.104.2 172.16.104.0/24 dev dummy1 proto kernel scope link src 172.16.104.1 metric 257"
  1592. log_test $? 0 "User specified metric on first device"
  1593. set -e
  1594. run_cmd "$IP addr flush dev dummy2"
  1595. run_cmd "$IP addr add dev dummy2 172.16.104.2/24 metric 258"
  1596. set +e
  1597. check_route "172.16.104.0/24 dev dummy1 proto kernel scope link src 172.16.104.1 metric 257 172.16.104.0/24 dev dummy2 proto kernel scope link src 172.16.104.2 metric 258"
  1598. log_test $? 0 "User specified metric on second device"
  1599. run_cmd "$IP addr del dev dummy1 172.16.104.1/24 metric 257"
  1600. rc=$?
  1601. if [ $rc -eq 0 ]; then
  1602. check_route "172.16.104.0/24 dev dummy2 proto kernel scope link src 172.16.104.2 metric 258"
  1603. rc=$?
  1604. fi
  1605. log_test $rc 0 "Delete of address on first device"
  1606. run_cmd "$IP addr change dev dummy2 172.16.104.2/24 metric 259"
  1607. rc=$?
  1608. if [ $rc -eq 0 ]; then
  1609. check_route "172.16.104.0/24 dev dummy2 proto kernel scope link src 172.16.104.2 metric 259"
  1610. rc=$?
  1611. fi
  1612. log_test $rc 0 "Modify metric of address"
  1613. # verify prefix route removed on down
  1614. run_cmd "$IP li set dev dummy2 down"
  1615. rc=$?
  1616. if [ $rc -eq 0 ]; then
  1617. out=$($IP ro ls match 172.16.104.0/24)
  1618. check_expected "${out}" ""
  1619. rc=$?
  1620. fi
  1621. log_test $rc 0 "Prefix route removed on link down"
  1622. # verify prefix route re-inserted with assigned metric
  1623. run_cmd "$IP li set dev dummy2 up"
  1624. rc=$?
  1625. if [ $rc -eq 0 ]; then
  1626. check_route "172.16.104.0/24 dev dummy2 proto kernel scope link src 172.16.104.2 metric 259"
  1627. rc=$?
  1628. fi
  1629. log_test $rc 0 "Prefix route with metric on link up"
  1630. # explicitly check for metric changes on edge scenarios
  1631. run_cmd "$IP addr flush dev dummy2"
  1632. run_cmd "$IP addr add dev dummy2 172.16.104.0/24 metric 259"
  1633. run_cmd "$IP addr change dev dummy2 172.16.104.0/24 metric 260"
  1634. rc=$?
  1635. if [ $rc -eq 0 ]; then
  1636. check_route "172.16.104.0/24 dev dummy2 proto kernel scope link src 172.16.104.0 metric 260"
  1637. rc=$?
  1638. fi
  1639. log_test $rc 0 "Modify metric of .0/24 address"
  1640. run_cmd "$IP addr flush dev dummy2"
  1641. run_cmd "$IP addr add dev dummy2 172.16.104.1/32 peer 172.16.104.2 metric 260"
  1642. rc=$?
  1643. if [ $rc -eq 0 ]; then
  1644. check_route "172.16.104.2 dev dummy2 proto kernel scope link src 172.16.104.1 metric 260"
  1645. rc=$?
  1646. fi
  1647. log_test $rc 0 "Set metric of address with peer route"
  1648. run_cmd "$IP addr change dev dummy2 172.16.104.1/32 peer 172.16.104.3 metric 261"
  1649. rc=$?
  1650. if [ $rc -eq 0 ]; then
  1651. check_route "172.16.104.3 dev dummy2 proto kernel scope link src 172.16.104.1 metric 261"
  1652. rc=$?
  1653. fi
  1654. log_test $rc 0 "Modify metric and peer address for peer route"
  1655. $IP li del dummy1
  1656. $IP li del dummy2
  1657. cleanup
  1658. }
  1659. ipv4_route_metrics_test()
  1660. {
  1661. local rc
  1662. echo
  1663. echo "IPv4 route add / append tests"
  1664. route_setup
  1665. run_cmd "$IP ro add 172.16.111.0/24 via 172.16.101.2 mtu 1400"
  1666. rc=$?
  1667. if [ $rc -eq 0 ]; then
  1668. check_route "172.16.111.0/24 via 172.16.101.2 dev veth1 mtu 1400"
  1669. rc=$?
  1670. fi
  1671. log_test $rc 0 "Single path route with mtu metric"
  1672. run_cmd "$IP ro add 172.16.112.0/24 mtu 1400 nexthop via 172.16.101.2 nexthop via 172.16.103.2"
  1673. rc=$?
  1674. if [ $rc -eq 0 ]; then
  1675. check_route "172.16.112.0/24 mtu 1400 nexthop via 172.16.101.2 dev veth1 weight 1 nexthop via 172.16.103.2 dev veth3 weight 1"
  1676. rc=$?
  1677. fi
  1678. log_test $rc 0 "Multipath route with mtu metric"
  1679. $IP ro add 172.16.104.0/24 via 172.16.101.2 mtu 1300
  1680. run_cmd "ip netns exec $ns1 ping -w1 -c1 -s 1500 172.16.104.1"
  1681. log_test $? 0 "Using route with mtu metric"
  1682. run_cmd "$IP ro add 172.16.111.0/24 via 172.16.101.2 congctl lock foo"
  1683. log_test $? 2 "Invalid metric (fails metric_convert)"
  1684. route_cleanup
  1685. }
  1686. ipv4_del_addr_test()
  1687. {
  1688. echo
  1689. echo "IPv4 delete address route tests"
  1690. setup
  1691. set -e
  1692. $IP li add dummy1 type dummy
  1693. $IP li set dummy1 up
  1694. $IP li add dummy2 type dummy
  1695. $IP li set dummy2 up
  1696. $IP li add red type vrf table 1111
  1697. $IP li set red up
  1698. $IP ro add vrf red unreachable default
  1699. $IP li set dummy2 vrf red
  1700. $IP addr add dev dummy1 172.16.104.1/24
  1701. $IP addr add dev dummy1 172.16.104.11/24
  1702. $IP addr add dev dummy1 172.16.104.12/24
  1703. $IP addr add dev dummy1 172.16.104.13/24
  1704. $IP addr add dev dummy2 172.16.104.1/24
  1705. $IP addr add dev dummy2 172.16.104.11/24
  1706. $IP addr add dev dummy2 172.16.104.12/24
  1707. $IP route add 172.16.105.0/24 via 172.16.104.2 src 172.16.104.11
  1708. $IP route add 172.16.106.0/24 dev lo src 172.16.104.12
  1709. $IP route add table 0 172.16.107.0/24 via 172.16.104.2 src 172.16.104.13
  1710. $IP route add vrf red 172.16.105.0/24 via 172.16.104.2 src 172.16.104.11
  1711. $IP route add vrf red 172.16.106.0/24 dev lo src 172.16.104.12
  1712. set +e
  1713. # removing address from device in vrf should only remove route from vrf table
  1714. echo " Regular FIB info"
  1715. $IP addr del dev dummy2 172.16.104.11/24
  1716. $IP ro ls vrf red | grep -q 172.16.105.0/24
  1717. log_test $? 1 "Route removed from VRF when source address deleted"
  1718. $IP ro ls | grep -q 172.16.105.0/24
  1719. log_test $? 0 "Route in default VRF not removed"
  1720. $IP addr add dev dummy2 172.16.104.11/24
  1721. $IP route add vrf red 172.16.105.0/24 via 172.16.104.2 src 172.16.104.11
  1722. $IP addr del dev dummy1 172.16.104.11/24
  1723. $IP ro ls | grep -q 172.16.105.0/24
  1724. log_test $? 1 "Route removed in default VRF when source address deleted"
  1725. $IP ro ls vrf red | grep -q 172.16.105.0/24
  1726. log_test $? 0 "Route in VRF is not removed by address delete"
  1727. # removing address from device in vrf should only remove route from vrf
  1728. # table even when the associated fib info only differs in table ID
  1729. echo " Identical FIB info with different table ID"
  1730. $IP addr del dev dummy2 172.16.104.12/24
  1731. $IP ro ls vrf red | grep -q 172.16.106.0/24
  1732. log_test $? 1 "Route removed from VRF when source address deleted"
  1733. $IP ro ls | grep -q 172.16.106.0/24
  1734. log_test $? 0 "Route in default VRF not removed"
  1735. $IP addr add dev dummy2 172.16.104.12/24
  1736. $IP route add vrf red 172.16.106.0/24 dev lo src 172.16.104.12
  1737. $IP addr del dev dummy1 172.16.104.12/24
  1738. $IP ro ls | grep -q 172.16.106.0/24
  1739. log_test $? 1 "Route removed in default VRF when source address deleted"
  1740. $IP ro ls vrf red | grep -q 172.16.106.0/24
  1741. log_test $? 0 "Route in VRF is not removed by address delete"
  1742. # removing address from device in default vrf should remove route from
  1743. # the default vrf even when route was inserted with a table ID of 0.
  1744. echo " Table ID 0"
  1745. $IP addr del dev dummy1 172.16.104.13/24
  1746. $IP ro ls | grep -q 172.16.107.0/24
  1747. log_test $? 1 "Route removed in default VRF when source address deleted"
  1748. $IP li del dummy1
  1749. $IP li del dummy2
  1750. cleanup
  1751. }
  1752. ipv6_del_addr_test()
  1753. {
  1754. echo
  1755. echo "IPv6 delete address route tests"
  1756. setup
  1757. set -e
  1758. for i in $(seq 6); do
  1759. $IP li add dummy${i} up type dummy
  1760. done
  1761. $IP li add red up type vrf table 1111
  1762. $IP ro add vrf red unreachable default
  1763. for i in $(seq 4 6); do
  1764. $IP li set dummy${i} vrf red
  1765. done
  1766. $IP addr add dev dummy1 fe80::1/128
  1767. $IP addr add dev dummy1 2001:db8:101::1/64
  1768. $IP addr add dev dummy1 2001:db8:101::10/64
  1769. $IP addr add dev dummy1 2001:db8:101::11/64
  1770. $IP addr add dev dummy1 2001:db8:101::12/64
  1771. $IP addr add dev dummy1 2001:db8:101::13/64
  1772. $IP addr add dev dummy1 2001:db8:101::14/64
  1773. $IP addr add dev dummy1 2001:db8:101::15/64
  1774. $IP addr add dev dummy2 fe80::1/128
  1775. $IP addr add dev dummy2 2001:db8:101::1/64
  1776. $IP addr add dev dummy2 2001:db8:101::11/64
  1777. $IP addr add dev dummy3 fe80::1/128
  1778. $IP addr add dev dummy4 2001:db8:101::1/64
  1779. $IP addr add dev dummy4 2001:db8:101::10/64
  1780. $IP addr add dev dummy4 2001:db8:101::11/64
  1781. $IP addr add dev dummy4 2001:db8:101::12/64
  1782. $IP addr add dev dummy4 2001:db8:101::13/64
  1783. $IP addr add dev dummy4 2001:db8:101::14/64
  1784. $IP addr add dev dummy5 2001:db8:101::1/64
  1785. $IP addr add dev dummy5 2001:db8:101::11/64
  1786. # Single device using src address
  1787. $IP route add 2001:db8:110::/64 dev dummy3 src 2001:db8:101::10
  1788. # Two devices with the same source address
  1789. $IP route add 2001:db8:111::/64 dev dummy3 src 2001:db8:101::11
  1790. # VRF with single device using src address
  1791. $IP route add vrf red 2001:db8:110::/64 dev dummy6 src 2001:db8:101::10
  1792. # VRF with two devices using src address
  1793. $IP route add vrf red 2001:db8:111::/64 dev dummy6 src 2001:db8:101::11
  1794. # src address and nexthop dev in same VRF
  1795. $IP route add 2001:db8:112::/64 dev dummy3 src 2001:db8:101::12
  1796. $IP route add vrf red 2001:db8:112::/64 dev dummy6 src 2001:db8:101::12
  1797. # src address and nexthop device in different VRF
  1798. $IP route add 2001:db8:113::/64 dev lo src 2001:db8:101::13
  1799. $IP route add vrf red 2001:db8:113::/64 dev lo src 2001:db8:101::13
  1800. # table ID 0
  1801. $IP route add table 0 2001:db8:115::/64 via 2001:db8:101::2 src 2001:db8:101::15
  1802. # Link local source route
  1803. $IP route add 2001:db8:116::/64 dev dummy2 src fe80::1
  1804. $IP route add 2001:db8:117::/64 dev dummy3 src fe80::1
  1805. set +e
  1806. echo " Single device using src address"
  1807. $IP addr del dev dummy1 2001:db8:101::10/64
  1808. $IP -6 route show | grep -q "src 2001:db8:101::10 "
  1809. log_test $? 1 "Prefsrc removed when src address removed on other device"
  1810. echo " Two devices with the same source address"
  1811. $IP addr del dev dummy1 2001:db8:101::11/64
  1812. $IP -6 route show | grep -q "src 2001:db8:101::11 "
  1813. log_test $? 0 "Prefsrc not removed when src address exist on other device"
  1814. $IP addr del dev dummy2 2001:db8:101::11/64
  1815. $IP -6 route show | grep -q "src 2001:db8:101::11 "
  1816. log_test $? 1 "Prefsrc removed when src address removed on all devices"
  1817. echo " VRF with single device using src address"
  1818. $IP addr del dev dummy4 2001:db8:101::10/64
  1819. $IP -6 route show vrf red | grep -q "src 2001:db8:101::10 "
  1820. log_test $? 1 "Prefsrc removed when src address removed on other device"
  1821. echo " VRF with two devices using src address"
  1822. $IP addr del dev dummy4 2001:db8:101::11/64
  1823. $IP -6 route show vrf red | grep -q "src 2001:db8:101::11 "
  1824. log_test $? 0 "Prefsrc not removed when src address exist on other device"
  1825. $IP addr del dev dummy5 2001:db8:101::11/64
  1826. $IP -6 route show vrf red | grep -q "src 2001:db8:101::11 "
  1827. log_test $? 1 "Prefsrc removed when src address removed on all devices"
  1828. echo " src address and nexthop dev in same VRF"
  1829. $IP addr del dev dummy4 2001:db8:101::12/64
  1830. $IP -6 route show vrf red | grep -q "src 2001:db8:101::12 "
  1831. log_test $? 1 "Prefsrc removed from VRF when source address deleted"
  1832. $IP -6 route show | grep -q " src 2001:db8:101::12 "
  1833. log_test $? 0 "Prefsrc in default VRF not removed"
  1834. $IP addr add dev dummy4 2001:db8:101::12/64
  1835. $IP route replace vrf red 2001:db8:112::/64 dev dummy6 src 2001:db8:101::12
  1836. $IP addr del dev dummy1 2001:db8:101::12/64
  1837. $IP -6 route show vrf red | grep -q "src 2001:db8:101::12 "
  1838. log_test $? 0 "Prefsrc not removed from VRF when source address exist"
  1839. $IP -6 route show | grep -q " src 2001:db8:101::12 "
  1840. log_test $? 1 "Prefsrc in default VRF removed"
  1841. echo " src address and nexthop device in different VRF"
  1842. $IP addr del dev dummy4 2001:db8:101::13/64
  1843. $IP -6 route show vrf red | grep -q "src 2001:db8:101::13 "
  1844. log_test $? 0 "Prefsrc not removed from VRF when nexthop dev in diff VRF"
  1845. $IP -6 route show | grep -q "src 2001:db8:101::13 "
  1846. log_test $? 0 "Prefsrc not removed in default VRF"
  1847. $IP addr add dev dummy4 2001:db8:101::13/64
  1848. $IP addr del dev dummy1 2001:db8:101::13/64
  1849. $IP -6 route show vrf red | grep -q "src 2001:db8:101::13 "
  1850. log_test $? 1 "Prefsrc removed from VRF when nexthop dev in diff VRF"
  1851. $IP -6 route show | grep -q "src 2001:db8:101::13 "
  1852. log_test $? 1 "Prefsrc removed in default VRF"
  1853. echo " Table ID 0"
  1854. $IP addr del dev dummy1 2001:db8:101::15/64
  1855. $IP -6 route show | grep -q "src 2001:db8:101::15"
  1856. log_test $? 1 "Prefsrc removed from default VRF when source address deleted"
  1857. echo " Link local source route"
  1858. $IP addr del dev dummy1 fe80::1/128
  1859. $IP -6 route show | grep -q "2001:db8:116::/64 dev dummy2 src fe80::1"
  1860. log_test $? 0 "Prefsrc not removed when delete ll addr from other dev"
  1861. $IP addr del dev dummy2 fe80::1/128
  1862. $IP -6 route show | grep -q "2001:db8:116::/64 dev dummy2 src fe80::1"
  1863. log_test $? 1 "Prefsrc removed when delete ll addr"
  1864. $IP -6 route show | grep -q "2001:db8:117::/64 dev dummy3 src fe80::1"
  1865. log_test $? 0 "Prefsrc not removed when delete ll addr from other dev"
  1866. $IP addr add dev dummy1 fe80::1/128
  1867. $IP addr del dev dummy3 fe80::1/128
  1868. $IP -6 route show | grep -q "2001:db8:117::/64 dev dummy3 src fe80::1"
  1869. log_test $? 1 "Prefsrc removed even ll addr still exist on other dev"
  1870. for i in $(seq 6); do
  1871. $IP li del dummy${i}
  1872. done
  1873. cleanup
  1874. }
  1875. ipv4_route_v6_gw_test()
  1876. {
  1877. local rc
  1878. echo
  1879. echo "IPv4 route with IPv6 gateway tests"
  1880. route_setup
  1881. sleep 2
  1882. #
  1883. # single path route
  1884. #
  1885. run_cmd "$IP ro add 172.16.104.0/24 via inet6 2001:db8:101::2"
  1886. rc=$?
  1887. log_test $rc 0 "Single path route with IPv6 gateway"
  1888. if [ $rc -eq 0 ]; then
  1889. check_route "172.16.104.0/24 via inet6 2001:db8:101::2 dev veth1"
  1890. fi
  1891. run_cmd "ip netns exec $ns1 ping -w1 -c1 172.16.104.1"
  1892. log_test $rc 0 "Single path route with IPv6 gateway - ping"
  1893. run_cmd "$IP ro del 172.16.104.0/24 via inet6 2001:db8:101::2"
  1894. rc=$?
  1895. log_test $rc 0 "Single path route delete"
  1896. if [ $rc -eq 0 ]; then
  1897. check_route "172.16.112.0/24"
  1898. fi
  1899. #
  1900. # multipath - v6 then v4
  1901. #
  1902. run_cmd "$IP ro add 172.16.104.0/24 nexthop via inet6 2001:db8:101::2 dev veth1 nexthop via 172.16.103.2 dev veth3"
  1903. rc=$?
  1904. log_test $rc 0 "Multipath route add - v6 nexthop then v4"
  1905. if [ $rc -eq 0 ]; then
  1906. check_route "172.16.104.0/24 nexthop via inet6 2001:db8:101::2 dev veth1 weight 1 nexthop via 172.16.103.2 dev veth3 weight 1"
  1907. fi
  1908. run_cmd "$IP ro del 172.16.104.0/24 nexthop via 172.16.103.2 dev veth3 nexthop via inet6 2001:db8:101::2 dev veth1"
  1909. log_test $? 2 " Multipath route delete - nexthops in wrong order"
  1910. run_cmd "$IP ro del 172.16.104.0/24 nexthop via inet6 2001:db8:101::2 dev veth1 nexthop via 172.16.103.2 dev veth3"
  1911. log_test $? 0 " Multipath route delete exact match"
  1912. #
  1913. # multipath - v4 then v6
  1914. #
  1915. run_cmd "$IP ro add 172.16.104.0/24 nexthop via 172.16.103.2 dev veth3 nexthop via inet6 2001:db8:101::2 dev veth1"
  1916. rc=$?
  1917. log_test $rc 0 "Multipath route add - v4 nexthop then v6"
  1918. if [ $rc -eq 0 ]; then
  1919. check_route "172.16.104.0/24 nexthop via 172.16.103.2 dev veth3 weight 1 nexthop via inet6 2001:db8:101::2 dev veth1 weight 1"
  1920. fi
  1921. run_cmd "$IP ro del 172.16.104.0/24 nexthop via inet6 2001:db8:101::2 dev veth1 nexthop via 172.16.103.2 dev veth3"
  1922. log_test $? 2 " Multipath route delete - nexthops in wrong order"
  1923. run_cmd "$IP ro del 172.16.104.0/24 nexthop via 172.16.103.2 dev veth3 nexthop via inet6 2001:db8:101::2 dev veth1"
  1924. log_test $? 0 " Multipath route delete exact match"
  1925. route_cleanup
  1926. }
  1927. socat_check()
  1928. {
  1929. if [ ! -x "$(command -v socat)" ]; then
  1930. echo "socat command not found. Skipping test"
  1931. return 1
  1932. fi
  1933. return 0
  1934. }
  1935. iptables_check()
  1936. {
  1937. iptables -t mangle -L OUTPUT &> /dev/null
  1938. if [ $? -ne 0 ]; then
  1939. echo "iptables configuration not supported. Skipping test"
  1940. return 1
  1941. fi
  1942. return 0
  1943. }
  1944. ip6tables_check()
  1945. {
  1946. ip6tables -t mangle -L OUTPUT &> /dev/null
  1947. if [ $? -ne 0 ]; then
  1948. echo "ip6tables configuration not supported. Skipping test"
  1949. return 1
  1950. fi
  1951. return 0
  1952. }
  1953. ipv4_mangle_test()
  1954. {
  1955. local rc
  1956. echo
  1957. echo "IPv4 mangling tests"
  1958. socat_check || return 1
  1959. iptables_check || return 1
  1960. route_setup
  1961. sleep 2
  1962. local tmp_file=$(mktemp)
  1963. ip netns exec $ns2 socat UDP4-LISTEN:54321,fork $tmp_file &
  1964. # Add a FIB rule and a route that will direct our connection to the
  1965. # listening server.
  1966. $IP rule add pref 100 ipproto udp sport 12345 dport 54321 table 123
  1967. $IP route add table 123 172.16.101.0/24 dev veth1
  1968. # Add an unreachable route to the main table that will block our
  1969. # connection in case the FIB rule is not hit.
  1970. $IP route add unreachable 172.16.101.2/32
  1971. run_cmd "echo a | $NS_EXEC socat STDIN UDP4:172.16.101.2:54321,sourceport=12345"
  1972. log_test $? 0 " Connection with correct parameters"
  1973. run_cmd "echo a | $NS_EXEC socat STDIN UDP4:172.16.101.2:54321,sourceport=11111"
  1974. log_test $? 1 " Connection with incorrect parameters"
  1975. # Add a mangling rule and make sure connection is still successful.
  1976. $NS_EXEC iptables -t mangle -A OUTPUT -j MARK --set-mark 1
  1977. run_cmd "echo a | $NS_EXEC socat STDIN UDP4:172.16.101.2:54321,sourceport=12345"
  1978. log_test $? 0 " Connection with correct parameters - mangling"
  1979. # Delete the mangling rule and make sure connection is still
  1980. # successful.
  1981. $NS_EXEC iptables -t mangle -D OUTPUT -j MARK --set-mark 1
  1982. run_cmd "echo a | $NS_EXEC socat STDIN UDP4:172.16.101.2:54321,sourceport=12345"
  1983. log_test $? 0 " Connection with correct parameters - no mangling"
  1984. # Verify connections were indeed successful on server side.
  1985. [[ $(cat $tmp_file | wc -l) -eq 3 ]]
  1986. log_test $? 0 " Connection check - server side"
  1987. $IP route del unreachable 172.16.101.2/32
  1988. $IP route del table 123 172.16.101.0/24 dev veth1
  1989. $IP rule del pref 100
  1990. kill_process %%
  1991. rm $tmp_file
  1992. route_cleanup
  1993. }
  1994. ipv6_mangle_test()
  1995. {
  1996. local rc
  1997. echo
  1998. echo "IPv6 mangling tests"
  1999. socat_check || return 1
  2000. ip6tables_check || return 1
  2001. route_setup
  2002. sleep 2
  2003. local tmp_file=$(mktemp)
  2004. ip netns exec $ns2 socat UDP6-LISTEN:54321,fork $tmp_file &
  2005. # Add a FIB rule and a route that will direct our connection to the
  2006. # listening server.
  2007. $IP -6 rule add pref 100 ipproto udp sport 12345 dport 54321 table 123
  2008. $IP -6 route add table 123 2001:db8:101::/64 dev veth1
  2009. # Add an unreachable route to the main table that will block our
  2010. # connection in case the FIB rule is not hit.
  2011. $IP -6 route add unreachable 2001:db8:101::2/128
  2012. run_cmd "echo a | $NS_EXEC socat STDIN UDP6:[2001:db8:101::2]:54321,sourceport=12345"
  2013. log_test $? 0 " Connection with correct parameters"
  2014. run_cmd "echo a | $NS_EXEC socat STDIN UDP6:[2001:db8:101::2]:54321,sourceport=11111"
  2015. log_test $? 1 " Connection with incorrect parameters"
  2016. # Add a mangling rule and make sure connection is still successful.
  2017. $NS_EXEC ip6tables -t mangle -A OUTPUT -j MARK --set-mark 1
  2018. run_cmd "echo a | $NS_EXEC socat STDIN UDP6:[2001:db8:101::2]:54321,sourceport=12345"
  2019. log_test $? 0 " Connection with correct parameters - mangling"
  2020. # Delete the mangling rule and make sure connection is still
  2021. # successful.
  2022. $NS_EXEC ip6tables -t mangle -D OUTPUT -j MARK --set-mark 1
  2023. run_cmd "echo a | $NS_EXEC socat STDIN UDP6:[2001:db8:101::2]:54321,sourceport=12345"
  2024. log_test $? 0 " Connection with correct parameters - no mangling"
  2025. # Verify connections were indeed successful on server side.
  2026. [[ $(cat $tmp_file | wc -l) -eq 3 ]]
  2027. log_test $? 0 " Connection check - server side"
  2028. $IP -6 route del unreachable 2001:db8:101::2/128
  2029. $IP -6 route del table 123 2001:db8:101::/64 dev veth1
  2030. $IP -6 rule del pref 100
  2031. kill_process %%
  2032. rm $tmp_file
  2033. route_cleanup
  2034. }
  2035. ip_neigh_get_check()
  2036. {
  2037. ip neigh help 2>&1 | grep -q 'ip neigh get'
  2038. if [ $? -ne 0 ]; then
  2039. echo "iproute2 command does not support neigh get. Skipping test"
  2040. return 1
  2041. fi
  2042. return 0
  2043. }
  2044. ipv4_bcast_neigh_test()
  2045. {
  2046. local rc
  2047. echo
  2048. echo "IPv4 broadcast neighbour tests"
  2049. ip_neigh_get_check || return 1
  2050. setup
  2051. set -e
  2052. run_cmd "$IP neigh add 192.0.2.111 lladdr 00:11:22:33:44:55 nud perm dev dummy0"
  2053. run_cmd "$IP neigh add 192.0.2.255 lladdr 00:11:22:33:44:55 nud perm dev dummy0"
  2054. run_cmd "$IP neigh get 192.0.2.111 dev dummy0"
  2055. run_cmd "$IP neigh get 192.0.2.255 dev dummy0"
  2056. run_cmd "$IP address add 192.0.2.1/24 broadcast 192.0.2.111 dev dummy0"
  2057. run_cmd "$IP neigh add 203.0.113.111 nud failed dev dummy0"
  2058. run_cmd "$IP neigh add 203.0.113.255 nud failed dev dummy0"
  2059. run_cmd "$IP neigh get 203.0.113.111 dev dummy0"
  2060. run_cmd "$IP neigh get 203.0.113.255 dev dummy0"
  2061. run_cmd "$IP address add 203.0.113.1/24 broadcast 203.0.113.111 dev dummy0"
  2062. set +e
  2063. run_cmd "$IP neigh get 192.0.2.111 dev dummy0"
  2064. log_test $? 0 "Resolved neighbour for broadcast address"
  2065. run_cmd "$IP neigh get 192.0.2.255 dev dummy0"
  2066. log_test $? 0 "Resolved neighbour for network broadcast address"
  2067. run_cmd "$IP neigh get 203.0.113.111 dev dummy0"
  2068. log_test $? 2 "Unresolved neighbour for broadcast address"
  2069. run_cmd "$IP neigh get 203.0.113.255 dev dummy0"
  2070. log_test $? 2 "Unresolved neighbour for network broadcast address"
  2071. cleanup
  2072. }
  2073. mpath_dep_check()
  2074. {
  2075. if [ ! -x "$(command -v mausezahn)" ]; then
  2076. echo "mausezahn command not found. Skipping test"
  2077. return 1
  2078. fi
  2079. if [ ! -x "$(command -v jq)" ]; then
  2080. echo "jq command not found. Skipping test"
  2081. return 1
  2082. fi
  2083. if [ ! -x "$(command -v bc)" ]; then
  2084. echo "bc command not found. Skipping test"
  2085. return 1
  2086. fi
  2087. if [ ! -x "$(command -v perf)" ]; then
  2088. echo "perf command not found. Skipping test"
  2089. return 1
  2090. fi
  2091. perf list fib:* | grep -q fib_table_lookup
  2092. if [ $? -ne 0 ]; then
  2093. echo "IPv4 FIB tracepoint not found. Skipping test"
  2094. return 1
  2095. fi
  2096. perf list fib6:* | grep -q fib6_table_lookup
  2097. if [ $? -ne 0 ]; then
  2098. echo "IPv6 FIB tracepoint not found. Skipping test"
  2099. return 1
  2100. fi
  2101. return 0
  2102. }
  2103. link_stats_get()
  2104. {
  2105. local ns=$1; shift
  2106. local dev=$1; shift
  2107. local dir=$1; shift
  2108. local stat=$1; shift
  2109. ip -n $ns -j -s link show dev $dev \
  2110. | jq '.[]["stats64"]["'$dir'"]["'$stat'"]'
  2111. }
  2112. list_rcv_eval()
  2113. {
  2114. local file=$1; shift
  2115. local expected=$1; shift
  2116. local count=$(tail -n 1 $file | jq '.["counter-value"] | tonumber | floor')
  2117. local ratio=$(echo "scale=2; $count / $expected" | bc -l)
  2118. local res=$(echo "$ratio >= 0.95" | bc)
  2119. [[ $res -eq 1 ]]
  2120. log_test $? 0 "Multipath route hit ratio ($ratio)"
  2121. }
  2122. ipv4_mpath_list_test()
  2123. {
  2124. echo
  2125. echo "IPv4 multipath list receive tests"
  2126. mpath_dep_check || return 1
  2127. route_setup
  2128. set -e
  2129. run_cmd "ip netns exec $ns1 ethtool -K veth1 tcp-segmentation-offload off"
  2130. run_cmd "ip netns exec $ns2 bash -c \"echo 20000 > /sys/class/net/veth2/gro_flush_timeout\""
  2131. run_cmd "ip netns exec $ns2 bash -c \"echo 1 > /sys/class/net/veth2/napi_defer_hard_irqs\""
  2132. run_cmd "ip netns exec $ns2 ethtool -K veth2 generic-receive-offload on"
  2133. run_cmd "ip -n $ns2 link add name nh1 up type dummy"
  2134. run_cmd "ip -n $ns2 link add name nh2 up type dummy"
  2135. run_cmd "ip -n $ns2 address add 172.16.201.1/24 dev nh1"
  2136. run_cmd "ip -n $ns2 address add 172.16.202.1/24 dev nh2"
  2137. run_cmd "ip -n $ns2 neigh add 172.16.201.2 lladdr 00:11:22:33:44:55 nud perm dev nh1"
  2138. run_cmd "ip -n $ns2 neigh add 172.16.202.2 lladdr 00:aa:bb:cc:dd:ee nud perm dev nh2"
  2139. run_cmd "ip -n $ns2 route add 203.0.113.0/24
  2140. nexthop via 172.16.201.2 nexthop via 172.16.202.2"
  2141. run_cmd "ip netns exec $ns2 sysctl -qw net.ipv4.fib_multipath_hash_policy=1"
  2142. set +e
  2143. local dmac=$(ip -n $ns2 -j link show dev veth2 | jq -r '.[]["address"]')
  2144. local tmp_file=$(mktemp)
  2145. local cmd="ip netns exec $ns1 mausezahn veth1 -a own -b $dmac
  2146. -A 172.16.101.1 -B 203.0.113.1 -t udp 'sp=12345,dp=0-65535' -q"
  2147. # Packets forwarded in a list using a multipath route must not reuse a
  2148. # cached result so that a flow always hits the same nexthop. In other
  2149. # words, the FIB lookup tracepoint needs to be triggered for every
  2150. # packet.
  2151. local t0_rx_pkts=$(link_stats_get $ns2 veth2 rx packets)
  2152. run_cmd "perf stat -a -e fib:fib_table_lookup --filter 'err == 0' -j -o $tmp_file -- $cmd"
  2153. local t1_rx_pkts=$(link_stats_get $ns2 veth2 rx packets)
  2154. local diff=$(echo $t1_rx_pkts - $t0_rx_pkts | bc -l)
  2155. list_rcv_eval $tmp_file $diff
  2156. rm $tmp_file
  2157. route_cleanup
  2158. }
  2159. ipv6_mpath_list_test()
  2160. {
  2161. echo
  2162. echo "IPv6 multipath list receive tests"
  2163. mpath_dep_check || return 1
  2164. route_setup
  2165. set -e
  2166. run_cmd "ip netns exec $ns1 ethtool -K veth1 tcp-segmentation-offload off"
  2167. run_cmd "ip netns exec $ns2 bash -c \"echo 20000 > /sys/class/net/veth2/gro_flush_timeout\""
  2168. run_cmd "ip netns exec $ns2 bash -c \"echo 1 > /sys/class/net/veth2/napi_defer_hard_irqs\""
  2169. run_cmd "ip netns exec $ns2 ethtool -K veth2 generic-receive-offload on"
  2170. run_cmd "ip -n $ns2 link add name nh1 up type dummy"
  2171. run_cmd "ip -n $ns2 link add name nh2 up type dummy"
  2172. run_cmd "ip -n $ns2 -6 address add 2001:db8:201::1/64 dev nh1"
  2173. run_cmd "ip -n $ns2 -6 address add 2001:db8:202::1/64 dev nh2"
  2174. run_cmd "ip -n $ns2 -6 neigh add 2001:db8:201::2 lladdr 00:11:22:33:44:55 nud perm dev nh1"
  2175. run_cmd "ip -n $ns2 -6 neigh add 2001:db8:202::2 lladdr 00:aa:bb:cc:dd:ee nud perm dev nh2"
  2176. run_cmd "ip -n $ns2 -6 route add 2001:db8:301::/64
  2177. nexthop via 2001:db8:201::2 nexthop via 2001:db8:202::2"
  2178. run_cmd "ip netns exec $ns2 sysctl -qw net.ipv6.fib_multipath_hash_policy=1"
  2179. set +e
  2180. local dmac=$(ip -n $ns2 -j link show dev veth2 | jq -r '.[]["address"]')
  2181. local tmp_file=$(mktemp)
  2182. local cmd="ip netns exec $ns1 mausezahn -6 veth1 -a own -b $dmac
  2183. -A 2001:db8:101::1 -B 2001:db8:301::1 -t udp 'sp=12345,dp=0-65535' -q"
  2184. # Packets forwarded in a list using a multipath route must not reuse a
  2185. # cached result so that a flow always hits the same nexthop. In other
  2186. # words, the FIB lookup tracepoint needs to be triggered for every
  2187. # packet.
  2188. local t0_rx_pkts=$(link_stats_get $ns2 veth2 rx packets)
  2189. run_cmd "perf stat -a -e fib6:fib6_table_lookup --filter 'err == 0' -j -o $tmp_file -- $cmd"
  2190. local t1_rx_pkts=$(link_stats_get $ns2 veth2 rx packets)
  2191. local diff=$(echo $t1_rx_pkts - $t0_rx_pkts | bc -l)
  2192. list_rcv_eval $tmp_file $diff
  2193. rm $tmp_file
  2194. route_cleanup
  2195. }
  2196. tc_set_flower_counter__saddr_syn() {
  2197. tc_set_flower_counter $1 $2 $3 "src_ip $4 ip_proto tcp tcp_flags 0x2"
  2198. }
  2199. ip_mpath_balance_dep_check()
  2200. {
  2201. if [ ! -x "$(command -v socat)" ]; then
  2202. echo "socat command not found. Skipping test"
  2203. return 1
  2204. fi
  2205. if [ ! -x "$(command -v jq)" ]; then
  2206. echo "jq command not found. Skipping test"
  2207. return 1
  2208. fi
  2209. }
  2210. ip_mpath_balance() {
  2211. local -r ipver=$1
  2212. local -r daddr=$2
  2213. local -r num_conn=20
  2214. for i in $(seq 1 $num_conn); do
  2215. ip netns exec $ns3 socat $ipver TCP-LISTEN:8000 STDIO >/dev/null &
  2216. sleep 0.02
  2217. echo -n a | ip netns exec $ns1 socat $ipver STDIO TCP:$daddr:8000
  2218. done
  2219. local -r syn0="$(tc_get_flower_counter $ns1 veth1)"
  2220. local -r syn1="$(tc_get_flower_counter $ns1 veth3)"
  2221. local -r syns=$((syn0+syn1))
  2222. [ "$VERBOSE" = "1" ] && echo "multipath: syns seen: ($syn0,$syn1)"
  2223. [[ $syns -ge $num_conn ]] && [[ $syn0 -gt 0 ]] && [[ $syn1 -gt 0 ]]
  2224. }
  2225. ipv4_mpath_balance_test()
  2226. {
  2227. echo
  2228. echo "IPv4 multipath load balance test"
  2229. ip_mpath_balance_dep_check || return 1
  2230. forwarding_setup
  2231. $IP route add 172.16.105.1 \
  2232. nexthop via 172.16.101.2 \
  2233. nexthop via 172.16.103.2
  2234. ip netns exec $ns1 \
  2235. sysctl -q -w net.ipv4.fib_multipath_hash_policy=1
  2236. tc_set_flower_counter__saddr_syn $ns1 4 veth1 172.16.101.1
  2237. tc_set_flower_counter__saddr_syn $ns1 4 veth3 172.16.103.1
  2238. ip_mpath_balance -4 172.16.105.1
  2239. log_test $? 0 "IPv4 multipath loadbalance"
  2240. forwarding_cleanup
  2241. }
  2242. get_route_dev_src()
  2243. {
  2244. local pfx="$1"
  2245. local src="$2"
  2246. local out
  2247. if out=$($IP -j route get "$pfx" from "$src" | jq -re ".[0].dev"); then
  2248. echo "$out"
  2249. fi
  2250. }
  2251. ipv4_mpath_preferred()
  2252. {
  2253. local src_ip=$1
  2254. local pref_dev=$2
  2255. local dev routes
  2256. local route0=0
  2257. local route1=0
  2258. local pref_route=0
  2259. num_routes=254
  2260. for i in $(seq 1 $num_routes) ; do
  2261. dev=$(get_route_dev_src 172.16.105.$i $src_ip)
  2262. if [ "$dev" = "$pref_dev" ]; then
  2263. pref_route=$((pref_route+1))
  2264. elif [ "$dev" = "veth1" ]; then
  2265. route0=$((route0+1))
  2266. elif [ "$dev" = "veth3" ]; then
  2267. route1=$((route1+1))
  2268. fi
  2269. done
  2270. routes=$((route0+route1))
  2271. [ "$VERBOSE" = "1" ] && echo "multipath: routes seen: ($route0,$route1,$pref_route)"
  2272. if [ x"$pref_dev" = x"" ]; then
  2273. [[ $routes -ge $num_routes ]] && [[ $route0 -gt 0 ]] && [[ $route1 -gt 0 ]]
  2274. else
  2275. [[ $pref_route -ge $num_routes ]]
  2276. fi
  2277. }
  2278. ipv4_mpath_balance_preferred_test()
  2279. {
  2280. echo
  2281. echo "IPv4 multipath load balance preferred route"
  2282. forwarding_setup
  2283. $IP route add 172.16.105.0/24 \
  2284. nexthop via 172.16.101.2 \
  2285. nexthop via 172.16.103.2
  2286. ipv4_mpath_preferred 172.16.101.1 veth1
  2287. log_test $? 0 "IPv4 multipath loadbalance from veth1"
  2288. ipv4_mpath_preferred 172.16.103.1 veth3
  2289. log_test $? 0 "IPv4 multipath loadbalance from veth3"
  2290. ipv4_mpath_preferred 198.51.100.1
  2291. log_test $? 0 "IPv4 multipath loadbalance from dummy"
  2292. forwarding_cleanup
  2293. }
  2294. ipv6_mpath_balance_test()
  2295. {
  2296. echo
  2297. echo "IPv6 multipath load balance test"
  2298. ip_mpath_balance_dep_check || return 1
  2299. forwarding_setup
  2300. $IP route add 2001:db8:105::1\
  2301. nexthop via 2001:db8:101::2 \
  2302. nexthop via 2001:db8:103::2
  2303. ip netns exec $ns1 \
  2304. sysctl -q -w net.ipv6.fib_multipath_hash_policy=1
  2305. tc_set_flower_counter__saddr_syn $ns1 6 veth1 2001:db8:101::1
  2306. tc_set_flower_counter__saddr_syn $ns1 6 veth3 2001:db8:103::1
  2307. ip_mpath_balance -6 "[2001:db8:105::1]"
  2308. log_test $? 0 "IPv6 multipath loadbalance"
  2309. forwarding_cleanup
  2310. }
  2311. ################################################################################
  2312. # usage
  2313. usage()
  2314. {
  2315. cat <<EOF
  2316. usage: ${0##*/} OPTS
  2317. -t <test> Test(s) to run (default: all)
  2318. (options: $TESTS)
  2319. -p Pause on fail
  2320. -P Pause after each test before cleanup
  2321. -v verbose mode (show commands and output)
  2322. EOF
  2323. }
  2324. ################################################################################
  2325. # main
  2326. trap cleanup EXIT
  2327. while getopts :t:pPhv o
  2328. do
  2329. case $o in
  2330. t) TESTS=$OPTARG;;
  2331. p) PAUSE_ON_FAIL=yes;;
  2332. P) PAUSE=yes;;
  2333. v) VERBOSE=$(($VERBOSE + 1));;
  2334. h) usage; exit 0;;
  2335. *) usage; exit 1;;
  2336. esac
  2337. done
  2338. PEER_CMD="ip netns exec ${PEER_NS}"
  2339. # make sure we don't pause twice
  2340. [ "${PAUSE}" = "yes" ] && PAUSE_ON_FAIL=no
  2341. if [ "$(id -u)" -ne 0 ];then
  2342. echo "SKIP: Need root privileges"
  2343. exit $ksft_skip;
  2344. fi
  2345. if [ ! -x "$(command -v ip)" ]; then
  2346. echo "SKIP: Could not run test without ip tool"
  2347. exit $ksft_skip
  2348. fi
  2349. ip route help 2>&1 | grep -q fibmatch
  2350. if [ $? -ne 0 ]; then
  2351. echo "SKIP: iproute2 too old, missing fibmatch"
  2352. exit $ksft_skip
  2353. fi
  2354. # start clean
  2355. cleanup &> /dev/null
  2356. for t in $TESTS
  2357. do
  2358. case $t in
  2359. fib_unreg_test|unregister) fib_unreg_test;;
  2360. fib_down_test|down) fib_down_test;;
  2361. fib_carrier_test|carrier) fib_carrier_test;;
  2362. fib_rp_filter_test|rp_filter) fib_rp_filter_test;;
  2363. fib_nexthop_test|nexthop) fib_nexthop_test;;
  2364. fib_notify_test|ipv4_notify) fib_notify_test;;
  2365. fib6_notify_test|ipv6_notify) fib6_notify_test;;
  2366. fib_suppress_test|suppress) fib_suppress_test;;
  2367. ipv6_route_test|ipv6_rt) ipv6_route_test;;
  2368. ipv4_route_test|ipv4_rt) ipv4_route_test;;
  2369. ipv6_addr_metric) ipv6_addr_metric_test;;
  2370. ipv4_addr_metric) ipv4_addr_metric_test;;
  2371. ipv4_del_addr) ipv4_del_addr_test;;
  2372. ipv6_del_addr) ipv6_del_addr_test;;
  2373. ipv6_route_metrics) ipv6_route_metrics_test;;
  2374. ipv4_route_metrics) ipv4_route_metrics_test;;
  2375. ipv4_route_v6_gw) ipv4_route_v6_gw_test;;
  2376. ipv4_mangle) ipv4_mangle_test;;
  2377. ipv6_mangle) ipv6_mangle_test;;
  2378. ipv4_bcast_neigh) ipv4_bcast_neigh_test;;
  2379. fib6_gc_test|ipv6_gc) fib6_gc_test;;
  2380. ipv4_mpath_list) ipv4_mpath_list_test;;
  2381. ipv6_mpath_list) ipv6_mpath_list_test;;
  2382. ipv4_mpath_balance) ipv4_mpath_balance_test;;
  2383. ipv6_mpath_balance) ipv6_mpath_balance_test;;
  2384. ipv4_mpath_balance_preferred) ipv4_mpath_balance_preferred_test;;
  2385. fib6_ra_to_static) fib6_ra_to_static;;
  2386. help) echo "Test names: $TESTS"; exit 0;;
  2387. esac
  2388. done
  2389. if [ "$TESTS" != "none" ]; then
  2390. printf "\nTests passed: %3d\n" ${nsuccess}
  2391. printf "Tests failed: %3d\n" ${nfail}
  2392. fi
  2393. exit $ret