fib_tests.sh 60 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136
  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. ret=0
  6. # Kselftest framework requirement - SKIP code is 4.
  7. ksft_skip=4
  8. # all tests in this script. Can be overridden with -t option
  9. TESTS="unregister down carrier nexthop suppress ipv6_rt ipv4_rt ipv6_addr_metric ipv4_addr_metric ipv6_route_metrics ipv4_route_metrics ipv4_route_v6_gw rp_filter ipv4_del_addr ipv4_mangle ipv6_mangle ipv4_bcast_neigh"
  10. VERBOSE=0
  11. PAUSE_ON_FAIL=no
  12. PAUSE=no
  13. IP="ip -netns ns1"
  14. NS_EXEC="ip netns exec ns1"
  15. which ping6 > /dev/null 2>&1 && ping6=$(which ping6) || ping6=$(which ping)
  16. log_test()
  17. {
  18. local rc=$1
  19. local expected=$2
  20. local msg="$3"
  21. if [ ${rc} -eq ${expected} ]; then
  22. printf " TEST: %-60s [ OK ]\n" "${msg}"
  23. nsuccess=$((nsuccess+1))
  24. else
  25. ret=1
  26. nfail=$((nfail+1))
  27. printf " TEST: %-60s [FAIL]\n" "${msg}"
  28. if [ "${PAUSE_ON_FAIL}" = "yes" ]; then
  29. echo
  30. echo "hit enter to continue, 'q' to quit"
  31. read a
  32. [ "$a" = "q" ] && exit 1
  33. fi
  34. fi
  35. if [ "${PAUSE}" = "yes" ]; then
  36. echo
  37. echo "hit enter to continue, 'q' to quit"
  38. read a
  39. [ "$a" = "q" ] && exit 1
  40. fi
  41. }
  42. setup()
  43. {
  44. set -e
  45. ip netns add ns1
  46. ip netns set ns1 auto
  47. $IP link set dev lo up
  48. ip netns exec ns1 sysctl -qw net.ipv4.ip_forward=1
  49. ip netns exec ns1 sysctl -qw net.ipv6.conf.all.forwarding=1
  50. $IP link add dummy0 type dummy
  51. $IP link set dev dummy0 up
  52. $IP address add 198.51.100.1/24 dev dummy0
  53. $IP -6 address add 2001:db8:1::1/64 dev dummy0
  54. set +e
  55. }
  56. cleanup()
  57. {
  58. $IP link del dev dummy0 &> /dev/null
  59. ip netns del ns1 &> /dev/null
  60. ip netns del ns2 &> /dev/null
  61. }
  62. get_linklocal()
  63. {
  64. local dev=$1
  65. local addr
  66. addr=$($IP -6 -br addr show dev ${dev} | \
  67. awk '{
  68. for (i = 3; i <= NF; ++i) {
  69. if ($i ~ /^fe80/)
  70. print $i
  71. }
  72. }'
  73. )
  74. addr=${addr/\/*}
  75. [ -z "$addr" ] && return 1
  76. echo $addr
  77. return 0
  78. }
  79. fib_unreg_unicast_test()
  80. {
  81. echo
  82. echo "Single path route test"
  83. setup
  84. echo " Start point"
  85. $IP route get fibmatch 198.51.100.2 &> /dev/null
  86. log_test $? 0 "IPv4 fibmatch"
  87. $IP -6 route get fibmatch 2001:db8:1::2 &> /dev/null
  88. log_test $? 0 "IPv6 fibmatch"
  89. set -e
  90. $IP link del dev dummy0
  91. set +e
  92. echo " Nexthop device deleted"
  93. $IP route get fibmatch 198.51.100.2 &> /dev/null
  94. log_test $? 2 "IPv4 fibmatch - no route"
  95. $IP -6 route get fibmatch 2001:db8:1::2 &> /dev/null
  96. log_test $? 2 "IPv6 fibmatch - no route"
  97. cleanup
  98. }
  99. fib_unreg_multipath_test()
  100. {
  101. echo
  102. echo "Multipath route test"
  103. setup
  104. set -e
  105. $IP link add dummy1 type dummy
  106. $IP link set dev dummy1 up
  107. $IP address add 192.0.2.1/24 dev dummy1
  108. $IP -6 address add 2001:db8:2::1/64 dev dummy1
  109. $IP route add 203.0.113.0/24 \
  110. nexthop via 198.51.100.2 dev dummy0 \
  111. nexthop via 192.0.2.2 dev dummy1
  112. $IP -6 route add 2001:db8:3::/64 \
  113. nexthop via 2001:db8:1::2 dev dummy0 \
  114. nexthop via 2001:db8:2::2 dev dummy1
  115. set +e
  116. echo " Start point"
  117. $IP route get fibmatch 203.0.113.1 &> /dev/null
  118. log_test $? 0 "IPv4 fibmatch"
  119. $IP -6 route get fibmatch 2001:db8:3::1 &> /dev/null
  120. log_test $? 0 "IPv6 fibmatch"
  121. set -e
  122. $IP link del dev dummy0
  123. set +e
  124. echo " One nexthop device deleted"
  125. $IP route get fibmatch 203.0.113.1 &> /dev/null
  126. log_test $? 2 "IPv4 - multipath route removed on delete"
  127. $IP -6 route get fibmatch 2001:db8:3::1 &> /dev/null
  128. # In IPv6 we do not flush the entire multipath route.
  129. log_test $? 0 "IPv6 - multipath down to single path"
  130. set -e
  131. $IP link del dev dummy1
  132. set +e
  133. echo " Second nexthop device deleted"
  134. $IP -6 route get fibmatch 2001:db8:3::1 &> /dev/null
  135. log_test $? 2 "IPv6 - no route"
  136. cleanup
  137. }
  138. fib_unreg_test()
  139. {
  140. fib_unreg_unicast_test
  141. fib_unreg_multipath_test
  142. }
  143. fib_down_unicast_test()
  144. {
  145. echo
  146. echo "Single path, admin down"
  147. setup
  148. echo " Start point"
  149. $IP route get fibmatch 198.51.100.2 &> /dev/null
  150. log_test $? 0 "IPv4 fibmatch"
  151. $IP -6 route get fibmatch 2001:db8:1::2 &> /dev/null
  152. log_test $? 0 "IPv6 fibmatch"
  153. set -e
  154. $IP link set dev dummy0 down
  155. set +e
  156. echo " Route deleted on down"
  157. $IP route get fibmatch 198.51.100.2 &> /dev/null
  158. log_test $? 2 "IPv4 fibmatch"
  159. $IP -6 route get fibmatch 2001:db8:1::2 &> /dev/null
  160. log_test $? 2 "IPv6 fibmatch"
  161. cleanup
  162. }
  163. fib_down_multipath_test_do()
  164. {
  165. local down_dev=$1
  166. local up_dev=$2
  167. $IP route get fibmatch 203.0.113.1 \
  168. oif $down_dev &> /dev/null
  169. log_test $? 2 "IPv4 fibmatch on down device"
  170. $IP -6 route get fibmatch 2001:db8:3::1 \
  171. oif $down_dev &> /dev/null
  172. log_test $? 2 "IPv6 fibmatch on down device"
  173. $IP route get fibmatch 203.0.113.1 \
  174. oif $up_dev &> /dev/null
  175. log_test $? 0 "IPv4 fibmatch on up device"
  176. $IP -6 route get fibmatch 2001:db8:3::1 \
  177. oif $up_dev &> /dev/null
  178. log_test $? 0 "IPv6 fibmatch on up device"
  179. $IP route get fibmatch 203.0.113.1 | \
  180. grep $down_dev | grep -q "dead linkdown"
  181. log_test $? 0 "IPv4 flags on down device"
  182. $IP -6 route get fibmatch 2001:db8:3::1 | \
  183. grep $down_dev | grep -q "dead linkdown"
  184. log_test $? 0 "IPv6 flags on down device"
  185. $IP route get fibmatch 203.0.113.1 | \
  186. grep $up_dev | grep -q "dead linkdown"
  187. log_test $? 1 "IPv4 flags on up device"
  188. $IP -6 route get fibmatch 2001:db8:3::1 | \
  189. grep $up_dev | grep -q "dead linkdown"
  190. log_test $? 1 "IPv6 flags on up device"
  191. }
  192. fib_down_multipath_test()
  193. {
  194. echo
  195. echo "Admin down multipath"
  196. setup
  197. set -e
  198. $IP link add dummy1 type dummy
  199. $IP link set dev dummy1 up
  200. $IP address add 192.0.2.1/24 dev dummy1
  201. $IP -6 address add 2001:db8:2::1/64 dev dummy1
  202. $IP route add 203.0.113.0/24 \
  203. nexthop via 198.51.100.2 dev dummy0 \
  204. nexthop via 192.0.2.2 dev dummy1
  205. $IP -6 route add 2001:db8:3::/64 \
  206. nexthop via 2001:db8:1::2 dev dummy0 \
  207. nexthop via 2001:db8:2::2 dev dummy1
  208. set +e
  209. echo " Verify start point"
  210. $IP route get fibmatch 203.0.113.1 &> /dev/null
  211. log_test $? 0 "IPv4 fibmatch"
  212. $IP -6 route get fibmatch 2001:db8:3::1 &> /dev/null
  213. log_test $? 0 "IPv6 fibmatch"
  214. set -e
  215. $IP link set dev dummy0 down
  216. set +e
  217. echo " One device down, one up"
  218. fib_down_multipath_test_do "dummy0" "dummy1"
  219. set -e
  220. $IP link set dev dummy0 up
  221. $IP link set dev dummy1 down
  222. set +e
  223. echo " Other device down and up"
  224. fib_down_multipath_test_do "dummy1" "dummy0"
  225. set -e
  226. $IP link set dev dummy0 down
  227. set +e
  228. echo " Both devices down"
  229. $IP route get fibmatch 203.0.113.1 &> /dev/null
  230. log_test $? 2 "IPv4 fibmatch"
  231. $IP -6 route get fibmatch 2001:db8:3::1 &> /dev/null
  232. log_test $? 2 "IPv6 fibmatch"
  233. $IP link del dev dummy1
  234. cleanup
  235. }
  236. fib_down_test()
  237. {
  238. fib_down_unicast_test
  239. fib_down_multipath_test
  240. }
  241. # Local routes should not be affected when carrier changes.
  242. fib_carrier_local_test()
  243. {
  244. echo
  245. echo "Local carrier tests - single path"
  246. setup
  247. set -e
  248. $IP link set dev dummy0 carrier on
  249. set +e
  250. echo " Start point"
  251. $IP route get fibmatch 198.51.100.1 &> /dev/null
  252. log_test $? 0 "IPv4 fibmatch"
  253. $IP -6 route get fibmatch 2001:db8:1::1 &> /dev/null
  254. log_test $? 0 "IPv6 fibmatch"
  255. $IP route get fibmatch 198.51.100.1 | \
  256. grep -q "linkdown"
  257. log_test $? 1 "IPv4 - no linkdown flag"
  258. $IP -6 route get fibmatch 2001:db8:1::1 | \
  259. grep -q "linkdown"
  260. log_test $? 1 "IPv6 - no linkdown flag"
  261. set -e
  262. $IP link set dev dummy0 carrier off
  263. sleep 1
  264. set +e
  265. echo " Carrier off on nexthop"
  266. $IP route get fibmatch 198.51.100.1 &> /dev/null
  267. log_test $? 0 "IPv4 fibmatch"
  268. $IP -6 route get fibmatch 2001:db8:1::1 &> /dev/null
  269. log_test $? 0 "IPv6 fibmatch"
  270. $IP route get fibmatch 198.51.100.1 | \
  271. grep -q "linkdown"
  272. log_test $? 1 "IPv4 - linkdown flag set"
  273. $IP -6 route get fibmatch 2001:db8:1::1 | \
  274. grep -q "linkdown"
  275. log_test $? 1 "IPv6 - linkdown flag set"
  276. set -e
  277. $IP address add 192.0.2.1/24 dev dummy0
  278. $IP -6 address add 2001:db8:2::1/64 dev dummy0
  279. set +e
  280. echo " Route to local address with carrier down"
  281. $IP route get fibmatch 192.0.2.1 &> /dev/null
  282. log_test $? 0 "IPv4 fibmatch"
  283. $IP -6 route get fibmatch 2001:db8:2::1 &> /dev/null
  284. log_test $? 0 "IPv6 fibmatch"
  285. $IP route get fibmatch 192.0.2.1 | \
  286. grep -q "linkdown"
  287. log_test $? 1 "IPv4 linkdown flag set"
  288. $IP -6 route get fibmatch 2001:db8:2::1 | \
  289. grep -q "linkdown"
  290. log_test $? 1 "IPv6 linkdown flag set"
  291. cleanup
  292. }
  293. fib_carrier_unicast_test()
  294. {
  295. ret=0
  296. echo
  297. echo "Single path route carrier test"
  298. setup
  299. set -e
  300. $IP link set dev dummy0 carrier on
  301. set +e
  302. echo " Start point"
  303. $IP route get fibmatch 198.51.100.2 &> /dev/null
  304. log_test $? 0 "IPv4 fibmatch"
  305. $IP -6 route get fibmatch 2001:db8:1::2 &> /dev/null
  306. log_test $? 0 "IPv6 fibmatch"
  307. $IP route get fibmatch 198.51.100.2 | \
  308. grep -q "linkdown"
  309. log_test $? 1 "IPv4 no linkdown flag"
  310. $IP -6 route get fibmatch 2001:db8:1::2 | \
  311. grep -q "linkdown"
  312. log_test $? 1 "IPv6 no linkdown flag"
  313. set -e
  314. $IP link set dev dummy0 carrier off
  315. sleep 1
  316. set +e
  317. echo " Carrier down"
  318. $IP route get fibmatch 198.51.100.2 &> /dev/null
  319. log_test $? 0 "IPv4 fibmatch"
  320. $IP -6 route get fibmatch 2001:db8:1::2 &> /dev/null
  321. log_test $? 0 "IPv6 fibmatch"
  322. $IP route get fibmatch 198.51.100.2 | \
  323. grep -q "linkdown"
  324. log_test $? 0 "IPv4 linkdown flag set"
  325. $IP -6 route get fibmatch 2001:db8:1::2 | \
  326. grep -q "linkdown"
  327. log_test $? 0 "IPv6 linkdown flag set"
  328. set -e
  329. $IP address add 192.0.2.1/24 dev dummy0
  330. $IP -6 address add 2001:db8:2::1/64 dev dummy0
  331. set +e
  332. echo " Second address added with carrier down"
  333. $IP route get fibmatch 192.0.2.2 &> /dev/null
  334. log_test $? 0 "IPv4 fibmatch"
  335. $IP -6 route get fibmatch 2001:db8:2::2 &> /dev/null
  336. log_test $? 0 "IPv6 fibmatch"
  337. $IP route get fibmatch 192.0.2.2 | \
  338. grep -q "linkdown"
  339. log_test $? 0 "IPv4 linkdown flag set"
  340. $IP -6 route get fibmatch 2001:db8:2::2 | \
  341. grep -q "linkdown"
  342. log_test $? 0 "IPv6 linkdown flag set"
  343. cleanup
  344. }
  345. fib_carrier_test()
  346. {
  347. fib_carrier_local_test
  348. fib_carrier_unicast_test
  349. }
  350. fib_rp_filter_test()
  351. {
  352. echo
  353. echo "IPv4 rp_filter tests"
  354. setup
  355. set -e
  356. ip netns add ns2
  357. ip netns set ns2 auto
  358. ip -netns ns2 link set dev lo up
  359. $IP link add name veth1 type veth peer name veth2
  360. $IP link set dev veth2 netns ns2
  361. $IP address add 192.0.2.1/24 dev veth1
  362. ip -netns ns2 address add 192.0.2.1/24 dev veth2
  363. $IP link set dev veth1 up
  364. ip -netns ns2 link set dev veth2 up
  365. $IP link set dev lo address 52:54:00:6a:c7:5e
  366. $IP link set dev veth1 address 52:54:00:6a:c7:5e
  367. ip -netns ns2 link set dev lo address 52:54:00:6a:c7:5e
  368. ip -netns ns2 link set dev veth2 address 52:54:00:6a:c7:5e
  369. # 1. (ns2) redirect lo's egress to veth2's egress
  370. ip netns exec ns2 tc qdisc add dev lo parent root handle 1: fq_codel
  371. ip netns exec ns2 tc filter add dev lo parent 1: protocol arp basic \
  372. action mirred egress redirect dev veth2
  373. ip netns exec ns2 tc filter add dev lo parent 1: protocol ip basic \
  374. action mirred egress redirect dev veth2
  375. # 2. (ns1) redirect veth1's ingress to lo's ingress
  376. $NS_EXEC tc qdisc add dev veth1 ingress
  377. $NS_EXEC tc filter add dev veth1 ingress protocol arp basic \
  378. action mirred ingress redirect dev lo
  379. $NS_EXEC tc filter add dev veth1 ingress protocol ip basic \
  380. action mirred ingress redirect dev lo
  381. # 3. (ns1) redirect lo's egress to veth1's egress
  382. $NS_EXEC tc qdisc add dev lo parent root handle 1: fq_codel
  383. $NS_EXEC tc filter add dev lo parent 1: protocol arp basic \
  384. action mirred egress redirect dev veth1
  385. $NS_EXEC tc filter add dev lo parent 1: protocol ip basic \
  386. action mirred egress redirect dev veth1
  387. # 4. (ns2) redirect veth2's ingress to lo's ingress
  388. ip netns exec ns2 tc qdisc add dev veth2 ingress
  389. ip netns exec ns2 tc filter add dev veth2 ingress protocol arp basic \
  390. action mirred ingress redirect dev lo
  391. ip netns exec ns2 tc filter add dev veth2 ingress protocol ip basic \
  392. action mirred ingress redirect dev lo
  393. $NS_EXEC sysctl -qw net.ipv4.conf.all.rp_filter=1
  394. $NS_EXEC sysctl -qw net.ipv4.conf.all.accept_local=1
  395. $NS_EXEC sysctl -qw net.ipv4.conf.all.route_localnet=1
  396. ip netns exec ns2 sysctl -qw net.ipv4.conf.all.rp_filter=1
  397. ip netns exec ns2 sysctl -qw net.ipv4.conf.all.accept_local=1
  398. ip netns exec ns2 sysctl -qw net.ipv4.conf.all.route_localnet=1
  399. set +e
  400. run_cmd "ip netns exec ns2 ping -w1 -c1 192.0.2.1"
  401. log_test $? 0 "rp_filter passes local packets"
  402. run_cmd "ip netns exec ns2 ping -w1 -c1 127.0.0.1"
  403. log_test $? 0 "rp_filter passes loopback packets"
  404. cleanup
  405. }
  406. ################################################################################
  407. # Tests on nexthop spec
  408. # run 'ip route add' with given spec
  409. add_rt()
  410. {
  411. local desc="$1"
  412. local erc=$2
  413. local vrf=$3
  414. local pfx=$4
  415. local gw=$5
  416. local dev=$6
  417. local cmd out rc
  418. [ "$vrf" = "-" ] && vrf="default"
  419. [ -n "$gw" ] && gw="via $gw"
  420. [ -n "$dev" ] && dev="dev $dev"
  421. cmd="$IP route add vrf $vrf $pfx $gw $dev"
  422. if [ "$VERBOSE" = "1" ]; then
  423. printf "\n COMMAND: $cmd\n"
  424. fi
  425. out=$(eval $cmd 2>&1)
  426. rc=$?
  427. if [ "$VERBOSE" = "1" -a -n "$out" ]; then
  428. echo " $out"
  429. fi
  430. log_test $rc $erc "$desc"
  431. }
  432. fib4_nexthop()
  433. {
  434. echo
  435. echo "IPv4 nexthop tests"
  436. echo "<<< write me >>>"
  437. }
  438. fib6_nexthop()
  439. {
  440. local lldummy=$(get_linklocal dummy0)
  441. local llv1=$(get_linklocal dummy0)
  442. if [ -z "$lldummy" ]; then
  443. echo "Failed to get linklocal address for dummy0"
  444. return 1
  445. fi
  446. if [ -z "$llv1" ]; then
  447. echo "Failed to get linklocal address for veth1"
  448. return 1
  449. fi
  450. echo
  451. echo "IPv6 nexthop tests"
  452. add_rt "Directly connected nexthop, unicast address" 0 \
  453. - 2001:db8:101::/64 2001:db8:1::2
  454. add_rt "Directly connected nexthop, unicast address with device" 0 \
  455. - 2001:db8:102::/64 2001:db8:1::2 "dummy0"
  456. add_rt "Gateway is linklocal address" 0 \
  457. - 2001:db8:103::1/64 $llv1 "veth0"
  458. # fails because LL address requires a device
  459. add_rt "Gateway is linklocal address, no device" 2 \
  460. - 2001:db8:104::1/64 $llv1
  461. # local address can not be a gateway
  462. add_rt "Gateway can not be local unicast address" 2 \
  463. - 2001:db8:105::/64 2001:db8:1::1
  464. add_rt "Gateway can not be local unicast address, with device" 2 \
  465. - 2001:db8:106::/64 2001:db8:1::1 "dummy0"
  466. add_rt "Gateway can not be a local linklocal address" 2 \
  467. - 2001:db8:107::1/64 $lldummy "dummy0"
  468. # VRF tests
  469. add_rt "Gateway can be local address in a VRF" 0 \
  470. - 2001:db8:108::/64 2001:db8:51::2
  471. add_rt "Gateway can be local address in a VRF, with device" 0 \
  472. - 2001:db8:109::/64 2001:db8:51::2 "veth0"
  473. add_rt "Gateway can be local linklocal address in a VRF" 0 \
  474. - 2001:db8:110::1/64 $llv1 "veth0"
  475. add_rt "Redirect to VRF lookup" 0 \
  476. - 2001:db8:111::/64 "" "red"
  477. add_rt "VRF route, gateway can be local address in default VRF" 0 \
  478. red 2001:db8:112::/64 2001:db8:51::1
  479. # local address in same VRF fails
  480. add_rt "VRF route, gateway can not be a local address" 2 \
  481. red 2001:db8:113::1/64 2001:db8:2::1
  482. add_rt "VRF route, gateway can not be a local addr with device" 2 \
  483. red 2001:db8:114::1/64 2001:db8:2::1 "dummy1"
  484. }
  485. # Default VRF:
  486. # dummy0 - 198.51.100.1/24 2001:db8:1::1/64
  487. # veth0 - 192.0.2.1/24 2001:db8:51::1/64
  488. #
  489. # VRF red:
  490. # dummy1 - 192.168.2.1/24 2001:db8:2::1/64
  491. # veth1 - 192.0.2.2/24 2001:db8:51::2/64
  492. #
  493. # [ dummy0 veth0 ]--[ veth1 dummy1 ]
  494. fib_nexthop_test()
  495. {
  496. setup
  497. set -e
  498. $IP -4 rule add pref 32765 table local
  499. $IP -4 rule del pref 0
  500. $IP -6 rule add pref 32765 table local
  501. $IP -6 rule del pref 0
  502. $IP link add red type vrf table 1
  503. $IP link set red up
  504. $IP -4 route add vrf red unreachable default metric 4278198272
  505. $IP -6 route add vrf red unreachable default metric 4278198272
  506. $IP link add veth0 type veth peer name veth1
  507. $IP link set dev veth0 up
  508. $IP address add 192.0.2.1/24 dev veth0
  509. $IP -6 address add 2001:db8:51::1/64 dev veth0
  510. $IP link set dev veth1 vrf red up
  511. $IP address add 192.0.2.2/24 dev veth1
  512. $IP -6 address add 2001:db8:51::2/64 dev veth1
  513. $IP link add dummy1 type dummy
  514. $IP link set dev dummy1 vrf red up
  515. $IP address add 192.168.2.1/24 dev dummy1
  516. $IP -6 address add 2001:db8:2::1/64 dev dummy1
  517. set +e
  518. sleep 1
  519. fib4_nexthop
  520. fib6_nexthop
  521. (
  522. $IP link del dev dummy1
  523. $IP link del veth0
  524. $IP link del red
  525. ) 2>/dev/null
  526. cleanup
  527. }
  528. fib_suppress_test()
  529. {
  530. echo
  531. echo "FIB rule with suppress_prefixlength"
  532. setup
  533. $IP link add dummy1 type dummy
  534. $IP link set dummy1 up
  535. $IP -6 route add default dev dummy1
  536. $IP -6 rule add table main suppress_prefixlength 0
  537. ping -f -c 1000 -W 1 1234::1 >/dev/null 2>&1
  538. $IP -6 rule del table main suppress_prefixlength 0
  539. $IP link del dummy1
  540. # If we got here without crashing, we're good.
  541. log_test 0 0 "FIB rule suppress test"
  542. cleanup
  543. }
  544. ################################################################################
  545. # Tests on route add and replace
  546. run_cmd()
  547. {
  548. local cmd="$1"
  549. local out
  550. local stderr="2>/dev/null"
  551. if [ "$VERBOSE" = "1" ]; then
  552. printf " COMMAND: $cmd\n"
  553. stderr=
  554. fi
  555. out=$(eval $cmd $stderr)
  556. rc=$?
  557. if [ "$VERBOSE" = "1" -a -n "$out" ]; then
  558. echo " $out"
  559. fi
  560. [ "$VERBOSE" = "1" ] && echo
  561. return $rc
  562. }
  563. check_expected()
  564. {
  565. local out="$1"
  566. local expected="$2"
  567. local rc=0
  568. [ "${out}" = "${expected}" ] && return 0
  569. if [ -z "${out}" ]; then
  570. if [ "$VERBOSE" = "1" ]; then
  571. printf "\nNo route entry found\n"
  572. printf "Expected:\n"
  573. printf " ${expected}\n"
  574. fi
  575. return 1
  576. fi
  577. # tricky way to convert output to 1-line without ip's
  578. # messy '\'; this drops all extra white space
  579. out=$(echo ${out})
  580. if [ "${out}" != "${expected}" ]; then
  581. rc=1
  582. if [ "${VERBOSE}" = "1" ]; then
  583. printf " Unexpected route entry. Have:\n"
  584. printf " ${out}\n"
  585. printf " Expected:\n"
  586. printf " ${expected}\n\n"
  587. fi
  588. fi
  589. return $rc
  590. }
  591. # add route for a prefix, flushing any existing routes first
  592. # expected to be the first step of a test
  593. add_route6()
  594. {
  595. local pfx="$1"
  596. local nh="$2"
  597. local out
  598. if [ "$VERBOSE" = "1" ]; then
  599. echo
  600. echo " ##################################################"
  601. echo
  602. fi
  603. run_cmd "$IP -6 ro flush ${pfx}"
  604. [ $? -ne 0 ] && exit 1
  605. out=$($IP -6 ro ls match ${pfx})
  606. if [ -n "$out" ]; then
  607. echo "Failed to flush routes for prefix used for tests."
  608. exit 1
  609. fi
  610. run_cmd "$IP -6 ro add ${pfx} ${nh}"
  611. if [ $? -ne 0 ]; then
  612. echo "Failed to add initial route for test."
  613. exit 1
  614. fi
  615. }
  616. # add initial route - used in replace route tests
  617. add_initial_route6()
  618. {
  619. add_route6 "2001:db8:104::/64" "$1"
  620. }
  621. check_route6()
  622. {
  623. local pfx
  624. local expected="$1"
  625. local out
  626. local rc=0
  627. set -- $expected
  628. pfx=$1
  629. out=$($IP -6 ro ls match ${pfx} | sed -e 's/ pref medium//')
  630. check_expected "${out}" "${expected}"
  631. }
  632. route_cleanup()
  633. {
  634. $IP li del red 2>/dev/null
  635. $IP li del dummy1 2>/dev/null
  636. $IP li del veth1 2>/dev/null
  637. $IP li del veth3 2>/dev/null
  638. cleanup &> /dev/null
  639. }
  640. route_setup()
  641. {
  642. route_cleanup
  643. setup
  644. [ "${VERBOSE}" = "1" ] && set -x
  645. set -e
  646. ip netns add ns2
  647. ip netns set ns2 auto
  648. ip -netns ns2 link set dev lo up
  649. ip netns exec ns2 sysctl -qw net.ipv4.ip_forward=1
  650. ip netns exec ns2 sysctl -qw net.ipv6.conf.all.forwarding=1
  651. $IP li add veth1 type veth peer name veth2
  652. $IP li add veth3 type veth peer name veth4
  653. $IP li set veth1 up
  654. $IP li set veth3 up
  655. $IP li set veth2 netns ns2 up
  656. $IP li set veth4 netns ns2 up
  657. ip -netns ns2 li add dummy1 type dummy
  658. ip -netns ns2 li set dummy1 up
  659. $IP -6 addr add 2001:db8:101::1/64 dev veth1 nodad
  660. $IP -6 addr add 2001:db8:103::1/64 dev veth3 nodad
  661. $IP addr add 172.16.101.1/24 dev veth1
  662. $IP addr add 172.16.103.1/24 dev veth3
  663. ip -netns ns2 -6 addr add 2001:db8:101::2/64 dev veth2 nodad
  664. ip -netns ns2 -6 addr add 2001:db8:103::2/64 dev veth4 nodad
  665. ip -netns ns2 -6 addr add 2001:db8:104::1/64 dev dummy1 nodad
  666. ip -netns ns2 addr add 172.16.101.2/24 dev veth2
  667. ip -netns ns2 addr add 172.16.103.2/24 dev veth4
  668. ip -netns ns2 addr add 172.16.104.1/24 dev dummy1
  669. set +e
  670. }
  671. # assumption is that basic add of a single path route works
  672. # otherwise just adding an address on an interface is broken
  673. ipv6_rt_add()
  674. {
  675. local rc
  676. echo
  677. echo "IPv6 route add / append tests"
  678. # route add same prefix - fails with EEXISTS b/c ip adds NLM_F_EXCL
  679. add_route6 "2001:db8:104::/64" "via 2001:db8:101::2"
  680. run_cmd "$IP -6 ro add 2001:db8:104::/64 via 2001:db8:103::2"
  681. log_test $? 2 "Attempt to add duplicate route - gw"
  682. # route add same prefix - fails with EEXISTS b/c ip adds NLM_F_EXCL
  683. add_route6 "2001:db8:104::/64" "via 2001:db8:101::2"
  684. run_cmd "$IP -6 ro add 2001:db8:104::/64 dev veth3"
  685. log_test $? 2 "Attempt to add duplicate route - dev only"
  686. # route add same prefix - fails with EEXISTS b/c ip adds NLM_F_EXCL
  687. add_route6 "2001:db8:104::/64" "via 2001:db8:101::2"
  688. run_cmd "$IP -6 ro add unreachable 2001:db8:104::/64"
  689. log_test $? 2 "Attempt to add duplicate route - reject route"
  690. # route append with same prefix adds a new route
  691. # - iproute2 sets NLM_F_CREATE | NLM_F_APPEND
  692. add_route6 "2001:db8:104::/64" "via 2001:db8:101::2"
  693. run_cmd "$IP -6 ro append 2001:db8:104::/64 via 2001:db8:103::2"
  694. 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"
  695. log_test $? 0 "Append nexthop to existing route - gw"
  696. # insert mpath directly
  697. add_route6 "2001:db8:104::/64" "nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2"
  698. 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"
  699. log_test $? 0 "Add multipath route"
  700. add_route6 "2001:db8:104::/64" "nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2"
  701. run_cmd "$IP -6 ro add 2001:db8:104::/64 nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2"
  702. log_test $? 2 "Attempt to add duplicate multipath route"
  703. # insert of a second route without append but different metric
  704. add_route6 "2001:db8:104::/64" "via 2001:db8:101::2"
  705. run_cmd "$IP -6 ro add 2001:db8:104::/64 via 2001:db8:103::2 metric 512"
  706. rc=$?
  707. if [ $rc -eq 0 ]; then
  708. run_cmd "$IP -6 ro add 2001:db8:104::/64 via 2001:db8:103::3 metric 256"
  709. rc=$?
  710. fi
  711. log_test $rc 0 "Route add with different metrics"
  712. run_cmd "$IP -6 ro del 2001:db8:104::/64 metric 512"
  713. rc=$?
  714. if [ $rc -eq 0 ]; then
  715. 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"
  716. rc=$?
  717. fi
  718. log_test $rc 0 "Route delete with metric"
  719. }
  720. ipv6_rt_replace_single()
  721. {
  722. # single path with single path
  723. #
  724. add_initial_route6 "via 2001:db8:101::2"
  725. run_cmd "$IP -6 ro replace 2001:db8:104::/64 via 2001:db8:103::2"
  726. check_route6 "2001:db8:104::/64 via 2001:db8:103::2 dev veth3 metric 1024"
  727. log_test $? 0 "Single path with single path"
  728. # single path with multipath
  729. #
  730. add_initial_route6 "nexthop via 2001:db8:101::2"
  731. run_cmd "$IP -6 ro replace 2001:db8:104::/64 nexthop via 2001:db8:101::3 nexthop via 2001:db8:103::2"
  732. 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"
  733. log_test $? 0 "Single path with multipath"
  734. # single path with single path using MULTIPATH attribute
  735. #
  736. add_initial_route6 "via 2001:db8:101::2"
  737. run_cmd "$IP -6 ro replace 2001:db8:104::/64 nexthop via 2001:db8:103::2"
  738. check_route6 "2001:db8:104::/64 via 2001:db8:103::2 dev veth3 metric 1024"
  739. log_test $? 0 "Single path with single path via multipath attribute"
  740. # route replace fails - invalid nexthop
  741. add_initial_route6 "via 2001:db8:101::2"
  742. run_cmd "$IP -6 ro replace 2001:db8:104::/64 via 2001:db8:104::2"
  743. if [ $? -eq 0 ]; then
  744. # previous command is expected to fail so if it returns 0
  745. # that means the test failed.
  746. log_test 0 1 "Invalid nexthop"
  747. else
  748. check_route6 "2001:db8:104::/64 via 2001:db8:101::2 dev veth1 metric 1024"
  749. log_test $? 0 "Invalid nexthop"
  750. fi
  751. # replace non-existent route
  752. # - note use of change versus replace since ip adds NLM_F_CREATE
  753. # for replace
  754. add_initial_route6 "via 2001:db8:101::2"
  755. run_cmd "$IP -6 ro change 2001:db8:105::/64 via 2001:db8:101::2"
  756. log_test $? 2 "Single path - replace of non-existent route"
  757. }
  758. ipv6_rt_replace_mpath()
  759. {
  760. # multipath with multipath
  761. add_initial_route6 "nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2"
  762. run_cmd "$IP -6 ro replace 2001:db8:104::/64 nexthop via 2001:db8:101::3 nexthop via 2001:db8:103::3"
  763. 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"
  764. log_test $? 0 "Multipath with multipath"
  765. # multipath with single
  766. add_initial_route6 "nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2"
  767. run_cmd "$IP -6 ro replace 2001:db8:104::/64 via 2001:db8:101::3"
  768. check_route6 "2001:db8:104::/64 via 2001:db8:101::3 dev veth1 metric 1024"
  769. log_test $? 0 "Multipath with single path"
  770. # multipath with single
  771. add_initial_route6 "nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2"
  772. run_cmd "$IP -6 ro replace 2001:db8:104::/64 nexthop via 2001:db8:101::3"
  773. check_route6 "2001:db8:104::/64 via 2001:db8:101::3 dev veth1 metric 1024"
  774. log_test $? 0 "Multipath with single path via multipath attribute"
  775. # multipath with dev-only
  776. add_initial_route6 "nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2"
  777. run_cmd "$IP -6 ro replace 2001:db8:104::/64 dev veth1"
  778. check_route6 "2001:db8:104::/64 dev veth1 metric 1024"
  779. log_test $? 0 "Multipath with dev-only"
  780. # route replace fails - invalid nexthop 1
  781. add_initial_route6 "nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2"
  782. run_cmd "$IP -6 ro replace 2001:db8:104::/64 nexthop via 2001:db8:111::3 nexthop via 2001:db8:103::3"
  783. 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"
  784. log_test $? 0 "Multipath - invalid first nexthop"
  785. # route replace fails - invalid nexthop 2
  786. add_initial_route6 "nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2"
  787. run_cmd "$IP -6 ro replace 2001:db8:104::/64 nexthop via 2001:db8:101::3 nexthop via 2001:db8:113::3"
  788. 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"
  789. log_test $? 0 "Multipath - invalid second nexthop"
  790. # multipath non-existent route
  791. add_initial_route6 "nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2"
  792. run_cmd "$IP -6 ro change 2001:db8:105::/64 nexthop via 2001:db8:101::3 nexthop via 2001:db8:103::3"
  793. log_test $? 2 "Multipath - replace of non-existent route"
  794. }
  795. ipv6_rt_replace()
  796. {
  797. echo
  798. echo "IPv6 route replace tests"
  799. ipv6_rt_replace_single
  800. ipv6_rt_replace_mpath
  801. }
  802. ipv6_rt_dsfield()
  803. {
  804. echo
  805. echo "IPv6 route with dsfield tests"
  806. run_cmd "$IP -6 route flush 2001:db8:102::/64"
  807. # IPv6 doesn't support routing based on dsfield
  808. run_cmd "$IP -6 route add 2001:db8:102::/64 dsfield 0x04 via 2001:db8:101::2"
  809. log_test $? 2 "Reject route with dsfield"
  810. }
  811. ipv6_route_test()
  812. {
  813. route_setup
  814. ipv6_rt_add
  815. ipv6_rt_replace
  816. ipv6_rt_dsfield
  817. route_cleanup
  818. }
  819. ip_addr_metric_check()
  820. {
  821. ip addr help 2>&1 | grep -q metric
  822. if [ $? -ne 0 ]; then
  823. echo "iproute2 command does not support metric for addresses. Skipping test"
  824. return 1
  825. fi
  826. return 0
  827. }
  828. ipv6_addr_metric_test()
  829. {
  830. local rc
  831. echo
  832. echo "IPv6 prefix route tests"
  833. ip_addr_metric_check || return 1
  834. setup
  835. set -e
  836. $IP li add dummy1 type dummy
  837. $IP li add dummy2 type dummy
  838. $IP li set dummy1 up
  839. $IP li set dummy2 up
  840. # default entry is metric 256
  841. run_cmd "$IP -6 addr add dev dummy1 2001:db8:104::1/64"
  842. run_cmd "$IP -6 addr add dev dummy2 2001:db8:104::2/64"
  843. set +e
  844. check_route6 "2001:db8:104::/64 dev dummy1 proto kernel metric 256 2001:db8:104::/64 dev dummy2 proto kernel metric 256"
  845. log_test $? 0 "Default metric"
  846. set -e
  847. run_cmd "$IP -6 addr flush dev dummy1"
  848. run_cmd "$IP -6 addr add dev dummy1 2001:db8:104::1/64 metric 257"
  849. set +e
  850. check_route6 "2001:db8:104::/64 dev dummy2 proto kernel metric 256 2001:db8:104::/64 dev dummy1 proto kernel metric 257"
  851. log_test $? 0 "User specified metric on first device"
  852. set -e
  853. run_cmd "$IP -6 addr flush dev dummy2"
  854. run_cmd "$IP -6 addr add dev dummy2 2001:db8:104::2/64 metric 258"
  855. set +e
  856. check_route6 "2001:db8:104::/64 dev dummy1 proto kernel metric 257 2001:db8:104::/64 dev dummy2 proto kernel metric 258"
  857. log_test $? 0 "User specified metric on second device"
  858. run_cmd "$IP -6 addr del dev dummy1 2001:db8:104::1/64 metric 257"
  859. rc=$?
  860. if [ $rc -eq 0 ]; then
  861. check_route6 "2001:db8:104::/64 dev dummy2 proto kernel metric 258"
  862. rc=$?
  863. fi
  864. log_test $rc 0 "Delete of address on first device"
  865. run_cmd "$IP -6 addr change dev dummy2 2001:db8:104::2/64 metric 259"
  866. rc=$?
  867. if [ $rc -eq 0 ]; then
  868. check_route6 "2001:db8:104::/64 dev dummy2 proto kernel metric 259"
  869. rc=$?
  870. fi
  871. log_test $rc 0 "Modify metric of address"
  872. # verify prefix route removed on down
  873. run_cmd "ip netns exec ns1 sysctl -qw net.ipv6.conf.all.keep_addr_on_down=1"
  874. run_cmd "$IP li set dev dummy2 down"
  875. rc=$?
  876. if [ $rc -eq 0 ]; then
  877. out=$($IP -6 ro ls match 2001:db8:104::/64)
  878. check_expected "${out}" ""
  879. rc=$?
  880. fi
  881. log_test $rc 0 "Prefix route removed on link down"
  882. # verify prefix route re-inserted with assigned metric
  883. run_cmd "$IP li set dev dummy2 up"
  884. rc=$?
  885. if [ $rc -eq 0 ]; then
  886. check_route6 "2001:db8:104::/64 dev dummy2 proto kernel metric 259"
  887. rc=$?
  888. fi
  889. log_test $rc 0 "Prefix route with metric on link up"
  890. # verify peer metric added correctly
  891. set -e
  892. run_cmd "$IP -6 addr flush dev dummy2"
  893. run_cmd "$IP -6 addr add dev dummy2 2001:db8:104::1 peer 2001:db8:104::2 metric 260"
  894. set +e
  895. check_route6 "2001:db8:104::1 dev dummy2 proto kernel metric 260"
  896. log_test $? 0 "Set metric with peer route on local side"
  897. check_route6 "2001:db8:104::2 dev dummy2 proto kernel metric 260"
  898. log_test $? 0 "Set metric with peer route on peer side"
  899. set -e
  900. run_cmd "$IP -6 addr change dev dummy2 2001:db8:104::1 peer 2001:db8:104::3 metric 261"
  901. set +e
  902. check_route6 "2001:db8:104::1 dev dummy2 proto kernel metric 261"
  903. log_test $? 0 "Modify metric and peer address on local side"
  904. check_route6 "2001:db8:104::3 dev dummy2 proto kernel metric 261"
  905. log_test $? 0 "Modify metric and peer address on peer side"
  906. $IP li del dummy1
  907. $IP li del dummy2
  908. cleanup
  909. }
  910. ipv6_route_metrics_test()
  911. {
  912. local rc
  913. echo
  914. echo "IPv6 routes with metrics"
  915. route_setup
  916. #
  917. # single path with metrics
  918. #
  919. run_cmd "$IP -6 ro add 2001:db8:111::/64 via 2001:db8:101::2 mtu 1400"
  920. rc=$?
  921. if [ $rc -eq 0 ]; then
  922. check_route6 "2001:db8:111::/64 via 2001:db8:101::2 dev veth1 metric 1024 mtu 1400"
  923. rc=$?
  924. fi
  925. log_test $rc 0 "Single path route with mtu metric"
  926. #
  927. # multipath via separate routes with metrics
  928. #
  929. run_cmd "$IP -6 ro add 2001:db8:112::/64 via 2001:db8:101::2 mtu 1400"
  930. run_cmd "$IP -6 ro append 2001:db8:112::/64 via 2001:db8:103::2"
  931. rc=$?
  932. if [ $rc -eq 0 ]; then
  933. 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"
  934. rc=$?
  935. fi
  936. log_test $rc 0 "Multipath route via 2 single routes with mtu metric on first"
  937. # second route is coalesced to first to make a multipath route.
  938. # MTU of the second path is hidden from display!
  939. run_cmd "$IP -6 ro add 2001:db8:113::/64 via 2001:db8:101::2"
  940. run_cmd "$IP -6 ro append 2001:db8:113::/64 via 2001:db8:103::2 mtu 1400"
  941. rc=$?
  942. if [ $rc -eq 0 ]; then
  943. 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"
  944. rc=$?
  945. fi
  946. log_test $rc 0 "Multipath route via 2 single routes with mtu metric on 2nd"
  947. run_cmd "$IP -6 ro del 2001:db8:113::/64 via 2001:db8:101::2"
  948. if [ $? -eq 0 ]; then
  949. check_route6 "2001:db8:113::/64 via 2001:db8:103::2 dev veth3 metric 1024 mtu 1400"
  950. log_test $? 0 " MTU of second leg"
  951. fi
  952. #
  953. # multipath with metrics
  954. #
  955. run_cmd "$IP -6 ro add 2001:db8:115::/64 mtu 1400 nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2"
  956. rc=$?
  957. if [ $rc -eq 0 ]; then
  958. 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"
  959. rc=$?
  960. fi
  961. log_test $rc 0 "Multipath route with mtu metric"
  962. $IP -6 ro add 2001:db8:104::/64 via 2001:db8:101::2 mtu 1300
  963. run_cmd "ip netns exec ns1 ${ping6} -w1 -c1 -s 1500 2001:db8:104::1"
  964. log_test $? 0 "Using route with mtu metric"
  965. run_cmd "$IP -6 ro add 2001:db8:114::/64 via 2001:db8:101::2 congctl lock foo"
  966. log_test $? 2 "Invalid metric (fails metric_convert)"
  967. route_cleanup
  968. }
  969. # add route for a prefix, flushing any existing routes first
  970. # expected to be the first step of a test
  971. add_route()
  972. {
  973. local pfx="$1"
  974. local nh="$2"
  975. local out
  976. if [ "$VERBOSE" = "1" ]; then
  977. echo
  978. echo " ##################################################"
  979. echo
  980. fi
  981. run_cmd "$IP ro flush ${pfx}"
  982. [ $? -ne 0 ] && exit 1
  983. out=$($IP ro ls match ${pfx})
  984. if [ -n "$out" ]; then
  985. echo "Failed to flush routes for prefix used for tests."
  986. exit 1
  987. fi
  988. run_cmd "$IP ro add ${pfx} ${nh}"
  989. if [ $? -ne 0 ]; then
  990. echo "Failed to add initial route for test."
  991. exit 1
  992. fi
  993. }
  994. # add initial route - used in replace route tests
  995. add_initial_route()
  996. {
  997. add_route "172.16.104.0/24" "$1"
  998. }
  999. check_route()
  1000. {
  1001. local pfx
  1002. local expected="$1"
  1003. local out
  1004. set -- $expected
  1005. pfx=$1
  1006. [ "${pfx}" = "unreachable" ] && pfx=$2
  1007. out=$($IP ro ls match ${pfx})
  1008. check_expected "${out}" "${expected}"
  1009. }
  1010. # assumption is that basic add of a single path route works
  1011. # otherwise just adding an address on an interface is broken
  1012. ipv4_rt_add()
  1013. {
  1014. local rc
  1015. echo
  1016. echo "IPv4 route add / append tests"
  1017. # route add same prefix - fails with EEXISTS b/c ip adds NLM_F_EXCL
  1018. add_route "172.16.104.0/24" "via 172.16.101.2"
  1019. run_cmd "$IP ro add 172.16.104.0/24 via 172.16.103.2"
  1020. log_test $? 2 "Attempt to add duplicate route - gw"
  1021. # route add same prefix - fails with EEXISTS b/c ip adds NLM_F_EXCL
  1022. add_route "172.16.104.0/24" "via 172.16.101.2"
  1023. run_cmd "$IP ro add 172.16.104.0/24 dev veth3"
  1024. log_test $? 2 "Attempt to add duplicate route - dev only"
  1025. # route add same prefix - fails with EEXISTS b/c ip adds NLM_F_EXCL
  1026. add_route "172.16.104.0/24" "via 172.16.101.2"
  1027. run_cmd "$IP ro add unreachable 172.16.104.0/24"
  1028. log_test $? 2 "Attempt to add duplicate route - reject route"
  1029. # iproute2 prepend only sets NLM_F_CREATE
  1030. # - adds a new route; does NOT convert existing route to ECMP
  1031. add_route "172.16.104.0/24" "via 172.16.101.2"
  1032. run_cmd "$IP ro prepend 172.16.104.0/24 via 172.16.103.2"
  1033. 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"
  1034. log_test $? 0 "Add new nexthop for existing prefix"
  1035. # route append with same prefix adds a new route
  1036. # - iproute2 sets NLM_F_CREATE | NLM_F_APPEND
  1037. add_route "172.16.104.0/24" "via 172.16.101.2"
  1038. run_cmd "$IP ro append 172.16.104.0/24 via 172.16.103.2"
  1039. 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"
  1040. log_test $? 0 "Append nexthop to existing route - gw"
  1041. add_route "172.16.104.0/24" "via 172.16.101.2"
  1042. run_cmd "$IP ro append 172.16.104.0/24 dev veth3"
  1043. check_route "172.16.104.0/24 via 172.16.101.2 dev veth1 172.16.104.0/24 dev veth3 scope link"
  1044. log_test $? 0 "Append nexthop to existing route - dev only"
  1045. add_route "172.16.104.0/24" "via 172.16.101.2"
  1046. run_cmd "$IP ro append unreachable 172.16.104.0/24"
  1047. check_route "172.16.104.0/24 via 172.16.101.2 dev veth1 unreachable 172.16.104.0/24"
  1048. log_test $? 0 "Append nexthop to existing route - reject route"
  1049. run_cmd "$IP ro flush 172.16.104.0/24"
  1050. run_cmd "$IP ro add unreachable 172.16.104.0/24"
  1051. run_cmd "$IP ro append 172.16.104.0/24 via 172.16.103.2"
  1052. check_route "unreachable 172.16.104.0/24 172.16.104.0/24 via 172.16.103.2 dev veth3"
  1053. log_test $? 0 "Append nexthop to existing reject route - gw"
  1054. run_cmd "$IP ro flush 172.16.104.0/24"
  1055. run_cmd "$IP ro add unreachable 172.16.104.0/24"
  1056. run_cmd "$IP ro append 172.16.104.0/24 dev veth3"
  1057. check_route "unreachable 172.16.104.0/24 172.16.104.0/24 dev veth3 scope link"
  1058. log_test $? 0 "Append nexthop to existing reject route - dev only"
  1059. # insert mpath directly
  1060. add_route "172.16.104.0/24" "nexthop via 172.16.101.2 nexthop via 172.16.103.2"
  1061. 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"
  1062. log_test $? 0 "add multipath route"
  1063. add_route "172.16.104.0/24" "nexthop via 172.16.101.2 nexthop via 172.16.103.2"
  1064. run_cmd "$IP ro add 172.16.104.0/24 nexthop via 172.16.101.2 nexthop via 172.16.103.2"
  1065. log_test $? 2 "Attempt to add duplicate multipath route"
  1066. # insert of a second route without append but different metric
  1067. add_route "172.16.104.0/24" "via 172.16.101.2"
  1068. run_cmd "$IP ro add 172.16.104.0/24 via 172.16.103.2 metric 512"
  1069. rc=$?
  1070. if [ $rc -eq 0 ]; then
  1071. run_cmd "$IP ro add 172.16.104.0/24 via 172.16.103.3 metric 256"
  1072. rc=$?
  1073. fi
  1074. log_test $rc 0 "Route add with different metrics"
  1075. run_cmd "$IP ro del 172.16.104.0/24 metric 512"
  1076. rc=$?
  1077. if [ $rc -eq 0 ]; then
  1078. 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"
  1079. rc=$?
  1080. fi
  1081. log_test $rc 0 "Route delete with metric"
  1082. }
  1083. ipv4_rt_replace_single()
  1084. {
  1085. # single path with single path
  1086. #
  1087. add_initial_route "via 172.16.101.2"
  1088. run_cmd "$IP ro replace 172.16.104.0/24 via 172.16.103.2"
  1089. check_route "172.16.104.0/24 via 172.16.103.2 dev veth3"
  1090. log_test $? 0 "Single path with single path"
  1091. # single path with multipath
  1092. #
  1093. add_initial_route "nexthop via 172.16.101.2"
  1094. run_cmd "$IP ro replace 172.16.104.0/24 nexthop via 172.16.101.3 nexthop via 172.16.103.2"
  1095. 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"
  1096. log_test $? 0 "Single path with multipath"
  1097. # single path with reject
  1098. #
  1099. add_initial_route "nexthop via 172.16.101.2"
  1100. run_cmd "$IP ro replace unreachable 172.16.104.0/24"
  1101. check_route "unreachable 172.16.104.0/24"
  1102. log_test $? 0 "Single path with reject route"
  1103. # single path with single path using MULTIPATH attribute
  1104. #
  1105. add_initial_route "via 172.16.101.2"
  1106. run_cmd "$IP ro replace 172.16.104.0/24 nexthop via 172.16.103.2"
  1107. check_route "172.16.104.0/24 via 172.16.103.2 dev veth3"
  1108. log_test $? 0 "Single path with single path via multipath attribute"
  1109. # route replace fails - invalid nexthop
  1110. add_initial_route "via 172.16.101.2"
  1111. run_cmd "$IP ro replace 172.16.104.0/24 via 2001:db8:104::2"
  1112. if [ $? -eq 0 ]; then
  1113. # previous command is expected to fail so if it returns 0
  1114. # that means the test failed.
  1115. log_test 0 1 "Invalid nexthop"
  1116. else
  1117. check_route "172.16.104.0/24 via 172.16.101.2 dev veth1"
  1118. log_test $? 0 "Invalid nexthop"
  1119. fi
  1120. # replace non-existent route
  1121. # - note use of change versus replace since ip adds NLM_F_CREATE
  1122. # for replace
  1123. add_initial_route "via 172.16.101.2"
  1124. run_cmd "$IP ro change 172.16.105.0/24 via 172.16.101.2"
  1125. log_test $? 2 "Single path - replace of non-existent route"
  1126. }
  1127. ipv4_rt_replace_mpath()
  1128. {
  1129. # multipath with multipath
  1130. add_initial_route "nexthop via 172.16.101.2 nexthop via 172.16.103.2"
  1131. run_cmd "$IP ro replace 172.16.104.0/24 nexthop via 172.16.101.3 nexthop via 172.16.103.3"
  1132. 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"
  1133. log_test $? 0 "Multipath with multipath"
  1134. # multipath with single
  1135. add_initial_route "nexthop via 172.16.101.2 nexthop via 172.16.103.2"
  1136. run_cmd "$IP ro replace 172.16.104.0/24 via 172.16.101.3"
  1137. check_route "172.16.104.0/24 via 172.16.101.3 dev veth1"
  1138. log_test $? 0 "Multipath with single path"
  1139. # multipath with single
  1140. add_initial_route "nexthop via 172.16.101.2 nexthop via 172.16.103.2"
  1141. run_cmd "$IP ro replace 172.16.104.0/24 nexthop via 172.16.101.3"
  1142. check_route "172.16.104.0/24 via 172.16.101.3 dev veth1"
  1143. log_test $? 0 "Multipath with single path via multipath attribute"
  1144. # multipath with reject
  1145. add_initial_route "nexthop via 172.16.101.2 nexthop via 172.16.103.2"
  1146. run_cmd "$IP ro replace unreachable 172.16.104.0/24"
  1147. check_route "unreachable 172.16.104.0/24"
  1148. log_test $? 0 "Multipath with reject route"
  1149. # route replace fails - invalid nexthop 1
  1150. add_initial_route "nexthop via 172.16.101.2 nexthop via 172.16.103.2"
  1151. run_cmd "$IP ro replace 172.16.104.0/24 nexthop via 172.16.111.3 nexthop via 172.16.103.3"
  1152. 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"
  1153. log_test $? 0 "Multipath - invalid first nexthop"
  1154. # route replace fails - invalid nexthop 2
  1155. add_initial_route "nexthop via 172.16.101.2 nexthop via 172.16.103.2"
  1156. run_cmd "$IP ro replace 172.16.104.0/24 nexthop via 172.16.101.3 nexthop via 172.16.113.3"
  1157. 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"
  1158. log_test $? 0 "Multipath - invalid second nexthop"
  1159. # multipath non-existent route
  1160. add_initial_route "nexthop via 172.16.101.2 nexthop via 172.16.103.2"
  1161. run_cmd "$IP ro change 172.16.105.0/24 nexthop via 172.16.101.3 nexthop via 172.16.103.3"
  1162. log_test $? 2 "Multipath - replace of non-existent route"
  1163. }
  1164. ipv4_rt_replace()
  1165. {
  1166. echo
  1167. echo "IPv4 route replace tests"
  1168. ipv4_rt_replace_single
  1169. ipv4_rt_replace_mpath
  1170. }
  1171. # checks that cached input route on VRF port is deleted
  1172. # when VRF is deleted
  1173. ipv4_local_rt_cache()
  1174. {
  1175. run_cmd "ip addr add 10.0.0.1/32 dev lo"
  1176. run_cmd "ip netns add test-ns"
  1177. run_cmd "ip link add veth-outside type veth peer name veth-inside"
  1178. run_cmd "ip link add vrf-100 type vrf table 1100"
  1179. run_cmd "ip link set veth-outside master vrf-100"
  1180. run_cmd "ip link set veth-inside netns test-ns"
  1181. run_cmd "ip link set veth-outside up"
  1182. run_cmd "ip link set vrf-100 up"
  1183. run_cmd "ip route add 10.1.1.1/32 dev veth-outside table 1100"
  1184. run_cmd "ip netns exec test-ns ip link set veth-inside up"
  1185. run_cmd "ip netns exec test-ns ip addr add 10.1.1.1/32 dev veth-inside"
  1186. run_cmd "ip netns exec test-ns ip route add 10.0.0.1/32 dev veth-inside"
  1187. run_cmd "ip netns exec test-ns ip route add default via 10.0.0.1"
  1188. run_cmd "ip netns exec test-ns ping 10.0.0.1 -c 1 -i 1"
  1189. run_cmd "ip link delete vrf-100"
  1190. # if we do not hang test is a success
  1191. log_test $? 0 "Cached route removed from VRF port device"
  1192. }
  1193. ipv4_rt_dsfield()
  1194. {
  1195. echo
  1196. echo "IPv4 route with dsfield tests"
  1197. run_cmd "$IP route flush 172.16.102.0/24"
  1198. # New routes should reject dsfield options that interfere with ECN
  1199. run_cmd "$IP route add 172.16.102.0/24 dsfield 0x01 via 172.16.101.2"
  1200. log_test $? 2 "Reject route with dsfield 0x01"
  1201. run_cmd "$IP route add 172.16.102.0/24 dsfield 0x02 via 172.16.101.2"
  1202. log_test $? 2 "Reject route with dsfield 0x02"
  1203. run_cmd "$IP route add 172.16.102.0/24 dsfield 0x03 via 172.16.101.2"
  1204. log_test $? 2 "Reject route with dsfield 0x03"
  1205. # A generic route that doesn't take DSCP into account
  1206. run_cmd "$IP route add 172.16.102.0/24 via 172.16.101.2"
  1207. # A more specific route for DSCP 0x10
  1208. run_cmd "$IP route add 172.16.102.0/24 dsfield 0x10 via 172.16.103.2"
  1209. # DSCP 0x10 should match the specific route, no matter the ECN bits
  1210. $IP route get fibmatch 172.16.102.1 dsfield 0x10 | \
  1211. grep -q "via 172.16.103.2"
  1212. log_test $? 0 "IPv4 route with DSCP and ECN:Not-ECT"
  1213. $IP route get fibmatch 172.16.102.1 dsfield 0x11 | \
  1214. grep -q "via 172.16.103.2"
  1215. log_test $? 0 "IPv4 route with DSCP and ECN:ECT(1)"
  1216. $IP route get fibmatch 172.16.102.1 dsfield 0x12 | \
  1217. grep -q "via 172.16.103.2"
  1218. log_test $? 0 "IPv4 route with DSCP and ECN:ECT(0)"
  1219. $IP route get fibmatch 172.16.102.1 dsfield 0x13 | \
  1220. grep -q "via 172.16.103.2"
  1221. log_test $? 0 "IPv4 route with DSCP and ECN:CE"
  1222. # Unknown DSCP should match the generic route, no matter the ECN bits
  1223. $IP route get fibmatch 172.16.102.1 dsfield 0x14 | \
  1224. grep -q "via 172.16.101.2"
  1225. log_test $? 0 "IPv4 route with unknown DSCP and ECN:Not-ECT"
  1226. $IP route get fibmatch 172.16.102.1 dsfield 0x15 | \
  1227. grep -q "via 172.16.101.2"
  1228. log_test $? 0 "IPv4 route with unknown DSCP and ECN:ECT(1)"
  1229. $IP route get fibmatch 172.16.102.1 dsfield 0x16 | \
  1230. grep -q "via 172.16.101.2"
  1231. log_test $? 0 "IPv4 route with unknown DSCP and ECN:ECT(0)"
  1232. $IP route get fibmatch 172.16.102.1 dsfield 0x17 | \
  1233. grep -q "via 172.16.101.2"
  1234. log_test $? 0 "IPv4 route with unknown DSCP and ECN:CE"
  1235. # Null DSCP should match the generic route, no matter the ECN bits
  1236. $IP route get fibmatch 172.16.102.1 dsfield 0x00 | \
  1237. grep -q "via 172.16.101.2"
  1238. log_test $? 0 "IPv4 route with no DSCP and ECN:Not-ECT"
  1239. $IP route get fibmatch 172.16.102.1 dsfield 0x01 | \
  1240. grep -q "via 172.16.101.2"
  1241. log_test $? 0 "IPv4 route with no DSCP and ECN:ECT(1)"
  1242. $IP route get fibmatch 172.16.102.1 dsfield 0x02 | \
  1243. grep -q "via 172.16.101.2"
  1244. log_test $? 0 "IPv4 route with no DSCP and ECN:ECT(0)"
  1245. $IP route get fibmatch 172.16.102.1 dsfield 0x03 | \
  1246. grep -q "via 172.16.101.2"
  1247. log_test $? 0 "IPv4 route with no DSCP and ECN:CE"
  1248. }
  1249. ipv4_route_test()
  1250. {
  1251. route_setup
  1252. ipv4_rt_add
  1253. ipv4_rt_replace
  1254. ipv4_local_rt_cache
  1255. ipv4_rt_dsfield
  1256. route_cleanup
  1257. }
  1258. ipv4_addr_metric_test()
  1259. {
  1260. local rc
  1261. echo
  1262. echo "IPv4 prefix route tests"
  1263. ip_addr_metric_check || return 1
  1264. setup
  1265. set -e
  1266. $IP li add dummy1 type dummy
  1267. $IP li add dummy2 type dummy
  1268. $IP li set dummy1 up
  1269. $IP li set dummy2 up
  1270. # default entry is metric 256
  1271. run_cmd "$IP addr add dev dummy1 172.16.104.1/24"
  1272. run_cmd "$IP addr add dev dummy2 172.16.104.2/24"
  1273. set +e
  1274. 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"
  1275. log_test $? 0 "Default metric"
  1276. set -e
  1277. run_cmd "$IP addr flush dev dummy1"
  1278. run_cmd "$IP addr add dev dummy1 172.16.104.1/24 metric 257"
  1279. set +e
  1280. 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"
  1281. log_test $? 0 "User specified metric on first device"
  1282. set -e
  1283. run_cmd "$IP addr flush dev dummy2"
  1284. run_cmd "$IP addr add dev dummy2 172.16.104.2/24 metric 258"
  1285. set +e
  1286. 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"
  1287. log_test $? 0 "User specified metric on second device"
  1288. run_cmd "$IP addr del dev dummy1 172.16.104.1/24 metric 257"
  1289. rc=$?
  1290. if [ $rc -eq 0 ]; then
  1291. check_route "172.16.104.0/24 dev dummy2 proto kernel scope link src 172.16.104.2 metric 258"
  1292. rc=$?
  1293. fi
  1294. log_test $rc 0 "Delete of address on first device"
  1295. run_cmd "$IP addr change dev dummy2 172.16.104.2/24 metric 259"
  1296. rc=$?
  1297. if [ $rc -eq 0 ]; then
  1298. check_route "172.16.104.0/24 dev dummy2 proto kernel scope link src 172.16.104.2 metric 259"
  1299. rc=$?
  1300. fi
  1301. log_test $rc 0 "Modify metric of address"
  1302. # verify prefix route removed on down
  1303. run_cmd "$IP li set dev dummy2 down"
  1304. rc=$?
  1305. if [ $rc -eq 0 ]; then
  1306. out=$($IP ro ls match 172.16.104.0/24)
  1307. check_expected "${out}" ""
  1308. rc=$?
  1309. fi
  1310. log_test $rc 0 "Prefix route removed on link down"
  1311. # verify prefix route re-inserted with assigned metric
  1312. run_cmd "$IP li set dev dummy2 up"
  1313. rc=$?
  1314. if [ $rc -eq 0 ]; then
  1315. check_route "172.16.104.0/24 dev dummy2 proto kernel scope link src 172.16.104.2 metric 259"
  1316. rc=$?
  1317. fi
  1318. log_test $rc 0 "Prefix route with metric on link up"
  1319. # explicitly check for metric changes on edge scenarios
  1320. run_cmd "$IP addr flush dev dummy2"
  1321. run_cmd "$IP addr add dev dummy2 172.16.104.0/24 metric 259"
  1322. run_cmd "$IP addr change dev dummy2 172.16.104.0/24 metric 260"
  1323. rc=$?
  1324. if [ $rc -eq 0 ]; then
  1325. check_route "172.16.104.0/24 dev dummy2 proto kernel scope link src 172.16.104.0 metric 260"
  1326. rc=$?
  1327. fi
  1328. log_test $rc 0 "Modify metric of .0/24 address"
  1329. run_cmd "$IP addr flush dev dummy2"
  1330. run_cmd "$IP addr add dev dummy2 172.16.104.1/32 peer 172.16.104.2 metric 260"
  1331. rc=$?
  1332. if [ $rc -eq 0 ]; then
  1333. check_route "172.16.104.2 dev dummy2 proto kernel scope link src 172.16.104.1 metric 260"
  1334. rc=$?
  1335. fi
  1336. log_test $rc 0 "Set metric of address with peer route"
  1337. run_cmd "$IP addr change dev dummy2 172.16.104.1/32 peer 172.16.104.3 metric 261"
  1338. rc=$?
  1339. if [ $rc -eq 0 ]; then
  1340. check_route "172.16.104.3 dev dummy2 proto kernel scope link src 172.16.104.1 metric 261"
  1341. rc=$?
  1342. fi
  1343. log_test $rc 0 "Modify metric and peer address for peer route"
  1344. $IP li del dummy1
  1345. $IP li del dummy2
  1346. cleanup
  1347. }
  1348. ipv4_route_metrics_test()
  1349. {
  1350. local rc
  1351. echo
  1352. echo "IPv4 route add / append tests"
  1353. route_setup
  1354. run_cmd "$IP ro add 172.16.111.0/24 via 172.16.101.2 mtu 1400"
  1355. rc=$?
  1356. if [ $rc -eq 0 ]; then
  1357. check_route "172.16.111.0/24 via 172.16.101.2 dev veth1 mtu 1400"
  1358. rc=$?
  1359. fi
  1360. log_test $rc 0 "Single path route with mtu metric"
  1361. run_cmd "$IP ro add 172.16.112.0/24 mtu 1400 nexthop via 172.16.101.2 nexthop via 172.16.103.2"
  1362. rc=$?
  1363. if [ $rc -eq 0 ]; then
  1364. 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"
  1365. rc=$?
  1366. fi
  1367. log_test $rc 0 "Multipath route with mtu metric"
  1368. $IP ro add 172.16.104.0/24 via 172.16.101.2 mtu 1300
  1369. run_cmd "ip netns exec ns1 ping -w1 -c1 -s 1500 172.16.104.1"
  1370. log_test $? 0 "Using route with mtu metric"
  1371. run_cmd "$IP ro add 172.16.111.0/24 via 172.16.101.2 congctl lock foo"
  1372. log_test $? 2 "Invalid metric (fails metric_convert)"
  1373. route_cleanup
  1374. }
  1375. ipv4_del_addr_test()
  1376. {
  1377. echo
  1378. echo "IPv4 delete address route tests"
  1379. setup
  1380. set -e
  1381. $IP li add dummy1 type dummy
  1382. $IP li set dummy1 up
  1383. $IP li add dummy2 type dummy
  1384. $IP li set dummy2 up
  1385. $IP li add red type vrf table 1111
  1386. $IP li set red up
  1387. $IP ro add vrf red unreachable default
  1388. $IP li set dummy2 vrf red
  1389. $IP addr add dev dummy1 172.16.104.1/24
  1390. $IP addr add dev dummy1 172.16.104.11/24
  1391. $IP addr add dev dummy1 172.16.104.12/24
  1392. $IP addr add dev dummy1 172.16.104.13/24
  1393. $IP addr add dev dummy2 172.16.104.1/24
  1394. $IP addr add dev dummy2 172.16.104.11/24
  1395. $IP addr add dev dummy2 172.16.104.12/24
  1396. $IP route add 172.16.105.0/24 via 172.16.104.2 src 172.16.104.11
  1397. $IP route add 172.16.106.0/24 dev lo src 172.16.104.12
  1398. $IP route add table 0 172.16.107.0/24 via 172.16.104.2 src 172.16.104.13
  1399. $IP route add vrf red 172.16.105.0/24 via 172.16.104.2 src 172.16.104.11
  1400. $IP route add vrf red 172.16.106.0/24 dev lo src 172.16.104.12
  1401. set +e
  1402. # removing address from device in vrf should only remove route from vrf table
  1403. echo " Regular FIB info"
  1404. $IP addr del dev dummy2 172.16.104.11/24
  1405. $IP ro ls vrf red | grep -q 172.16.105.0/24
  1406. log_test $? 1 "Route removed from VRF when source address deleted"
  1407. $IP ro ls | grep -q 172.16.105.0/24
  1408. log_test $? 0 "Route in default VRF not removed"
  1409. $IP addr add dev dummy2 172.16.104.11/24
  1410. $IP route add vrf red 172.16.105.0/24 via 172.16.104.2 src 172.16.104.11
  1411. $IP addr del dev dummy1 172.16.104.11/24
  1412. $IP ro ls | grep -q 172.16.105.0/24
  1413. log_test $? 1 "Route removed in default VRF when source address deleted"
  1414. $IP ro ls vrf red | grep -q 172.16.105.0/24
  1415. log_test $? 0 "Route in VRF is not removed by address delete"
  1416. # removing address from device in vrf should only remove route from vrf
  1417. # table even when the associated fib info only differs in table ID
  1418. echo " Identical FIB info with different table ID"
  1419. $IP addr del dev dummy2 172.16.104.12/24
  1420. $IP ro ls vrf red | grep -q 172.16.106.0/24
  1421. log_test $? 1 "Route removed from VRF when source address deleted"
  1422. $IP ro ls | grep -q 172.16.106.0/24
  1423. log_test $? 0 "Route in default VRF not removed"
  1424. $IP addr add dev dummy2 172.16.104.12/24
  1425. $IP route add vrf red 172.16.106.0/24 dev lo src 172.16.104.12
  1426. $IP addr del dev dummy1 172.16.104.12/24
  1427. $IP ro ls | grep -q 172.16.106.0/24
  1428. log_test $? 1 "Route removed in default VRF when source address deleted"
  1429. $IP ro ls vrf red | grep -q 172.16.106.0/24
  1430. log_test $? 0 "Route in VRF is not removed by address delete"
  1431. # removing address from device in default vrf should remove route from
  1432. # the default vrf even when route was inserted with a table ID of 0.
  1433. echo " Table ID 0"
  1434. $IP addr del dev dummy1 172.16.104.13/24
  1435. $IP ro ls | grep -q 172.16.107.0/24
  1436. log_test $? 1 "Route removed in default VRF when source address deleted"
  1437. $IP li del dummy1
  1438. $IP li del dummy2
  1439. cleanup
  1440. }
  1441. ipv4_route_v6_gw_test()
  1442. {
  1443. local rc
  1444. echo
  1445. echo "IPv4 route with IPv6 gateway tests"
  1446. route_setup
  1447. sleep 2
  1448. #
  1449. # single path route
  1450. #
  1451. run_cmd "$IP ro add 172.16.104.0/24 via inet6 2001:db8:101::2"
  1452. rc=$?
  1453. log_test $rc 0 "Single path route with IPv6 gateway"
  1454. if [ $rc -eq 0 ]; then
  1455. check_route "172.16.104.0/24 via inet6 2001:db8:101::2 dev veth1"
  1456. fi
  1457. run_cmd "ip netns exec ns1 ping -w1 -c1 172.16.104.1"
  1458. log_test $rc 0 "Single path route with IPv6 gateway - ping"
  1459. run_cmd "$IP ro del 172.16.104.0/24 via inet6 2001:db8:101::2"
  1460. rc=$?
  1461. log_test $rc 0 "Single path route delete"
  1462. if [ $rc -eq 0 ]; then
  1463. check_route "172.16.112.0/24"
  1464. fi
  1465. #
  1466. # multipath - v6 then v4
  1467. #
  1468. 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"
  1469. rc=$?
  1470. log_test $rc 0 "Multipath route add - v6 nexthop then v4"
  1471. if [ $rc -eq 0 ]; then
  1472. 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"
  1473. fi
  1474. 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"
  1475. log_test $? 2 " Multipath route delete - nexthops in wrong order"
  1476. 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"
  1477. log_test $? 0 " Multipath route delete exact match"
  1478. #
  1479. # multipath - v4 then v6
  1480. #
  1481. 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"
  1482. rc=$?
  1483. log_test $rc 0 "Multipath route add - v4 nexthop then v6"
  1484. if [ $rc -eq 0 ]; then
  1485. 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"
  1486. fi
  1487. 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"
  1488. log_test $? 2 " Multipath route delete - nexthops in wrong order"
  1489. 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"
  1490. log_test $? 0 " Multipath route delete exact match"
  1491. route_cleanup
  1492. }
  1493. socat_check()
  1494. {
  1495. if [ ! -x "$(command -v socat)" ]; then
  1496. echo "socat command not found. Skipping test"
  1497. return 1
  1498. fi
  1499. return 0
  1500. }
  1501. iptables_check()
  1502. {
  1503. iptables -t mangle -L OUTPUT &> /dev/null
  1504. if [ $? -ne 0 ]; then
  1505. echo "iptables configuration not supported. Skipping test"
  1506. return 1
  1507. fi
  1508. return 0
  1509. }
  1510. ip6tables_check()
  1511. {
  1512. ip6tables -t mangle -L OUTPUT &> /dev/null
  1513. if [ $? -ne 0 ]; then
  1514. echo "ip6tables configuration not supported. Skipping test"
  1515. return 1
  1516. fi
  1517. return 0
  1518. }
  1519. ipv4_mangle_test()
  1520. {
  1521. local rc
  1522. echo
  1523. echo "IPv4 mangling tests"
  1524. socat_check || return 1
  1525. iptables_check || return 1
  1526. route_setup
  1527. sleep 2
  1528. local tmp_file=$(mktemp)
  1529. ip netns exec ns2 socat UDP4-LISTEN:54321,fork $tmp_file &
  1530. # Add a FIB rule and a route that will direct our connection to the
  1531. # listening server.
  1532. $IP rule add pref 100 ipproto udp sport 12345 dport 54321 table 123
  1533. $IP route add table 123 172.16.101.0/24 dev veth1
  1534. # Add an unreachable route to the main table that will block our
  1535. # connection in case the FIB rule is not hit.
  1536. $IP route add unreachable 172.16.101.2/32
  1537. run_cmd "echo a | $NS_EXEC socat STDIN UDP4:172.16.101.2:54321,sourceport=12345"
  1538. log_test $? 0 " Connection with correct parameters"
  1539. run_cmd "echo a | $NS_EXEC socat STDIN UDP4:172.16.101.2:54321,sourceport=11111"
  1540. log_test $? 1 " Connection with incorrect parameters"
  1541. # Add a mangling rule and make sure connection is still successful.
  1542. $NS_EXEC iptables -t mangle -A OUTPUT -j MARK --set-mark 1
  1543. run_cmd "echo a | $NS_EXEC socat STDIN UDP4:172.16.101.2:54321,sourceport=12345"
  1544. log_test $? 0 " Connection with correct parameters - mangling"
  1545. # Delete the mangling rule and make sure connection is still
  1546. # successful.
  1547. $NS_EXEC iptables -t mangle -D OUTPUT -j MARK --set-mark 1
  1548. run_cmd "echo a | $NS_EXEC socat STDIN UDP4:172.16.101.2:54321,sourceport=12345"
  1549. log_test $? 0 " Connection with correct parameters - no mangling"
  1550. # Verify connections were indeed successful on server side.
  1551. [[ $(cat $tmp_file | wc -l) -eq 3 ]]
  1552. log_test $? 0 " Connection check - server side"
  1553. $IP route del unreachable 172.16.101.2/32
  1554. $IP route del table 123 172.16.101.0/24 dev veth1
  1555. $IP rule del pref 100
  1556. { kill %% && wait %%; } 2>/dev/null
  1557. rm $tmp_file
  1558. route_cleanup
  1559. }
  1560. ipv6_mangle_test()
  1561. {
  1562. local rc
  1563. echo
  1564. echo "IPv6 mangling tests"
  1565. socat_check || return 1
  1566. ip6tables_check || return 1
  1567. route_setup
  1568. sleep 2
  1569. local tmp_file=$(mktemp)
  1570. ip netns exec ns2 socat UDP6-LISTEN:54321,fork $tmp_file &
  1571. # Add a FIB rule and a route that will direct our connection to the
  1572. # listening server.
  1573. $IP -6 rule add pref 100 ipproto udp sport 12345 dport 54321 table 123
  1574. $IP -6 route add table 123 2001:db8:101::/64 dev veth1
  1575. # Add an unreachable route to the main table that will block our
  1576. # connection in case the FIB rule is not hit.
  1577. $IP -6 route add unreachable 2001:db8:101::2/128
  1578. run_cmd "echo a | $NS_EXEC socat STDIN UDP6:[2001:db8:101::2]:54321,sourceport=12345"
  1579. log_test $? 0 " Connection with correct parameters"
  1580. run_cmd "echo a | $NS_EXEC socat STDIN UDP6:[2001:db8:101::2]:54321,sourceport=11111"
  1581. log_test $? 1 " Connection with incorrect parameters"
  1582. # Add a mangling rule and make sure connection is still successful.
  1583. $NS_EXEC ip6tables -t mangle -A OUTPUT -j MARK --set-mark 1
  1584. run_cmd "echo a | $NS_EXEC socat STDIN UDP6:[2001:db8:101::2]:54321,sourceport=12345"
  1585. log_test $? 0 " Connection with correct parameters - mangling"
  1586. # Delete the mangling rule and make sure connection is still
  1587. # successful.
  1588. $NS_EXEC ip6tables -t mangle -D OUTPUT -j MARK --set-mark 1
  1589. run_cmd "echo a | $NS_EXEC socat STDIN UDP6:[2001:db8:101::2]:54321,sourceport=12345"
  1590. log_test $? 0 " Connection with correct parameters - no mangling"
  1591. # Verify connections were indeed successful on server side.
  1592. [[ $(cat $tmp_file | wc -l) -eq 3 ]]
  1593. log_test $? 0 " Connection check - server side"
  1594. $IP -6 route del unreachable 2001:db8:101::2/128
  1595. $IP -6 route del table 123 2001:db8:101::/64 dev veth1
  1596. $IP -6 rule del pref 100
  1597. { kill %% && wait %%; } 2>/dev/null
  1598. rm $tmp_file
  1599. route_cleanup
  1600. }
  1601. ip_neigh_get_check()
  1602. {
  1603. ip neigh help 2>&1 | grep -q 'ip neigh get'
  1604. if [ $? -ne 0 ]; then
  1605. echo "iproute2 command does not support neigh get. Skipping test"
  1606. return 1
  1607. fi
  1608. return 0
  1609. }
  1610. ipv4_bcast_neigh_test()
  1611. {
  1612. local rc
  1613. echo
  1614. echo "IPv4 broadcast neighbour tests"
  1615. ip_neigh_get_check || return 1
  1616. setup
  1617. set -e
  1618. run_cmd "$IP neigh add 192.0.2.111 lladdr 00:11:22:33:44:55 nud perm dev dummy0"
  1619. run_cmd "$IP neigh add 192.0.2.255 lladdr 00:11:22:33:44:55 nud perm dev dummy0"
  1620. run_cmd "$IP neigh get 192.0.2.111 dev dummy0"
  1621. run_cmd "$IP neigh get 192.0.2.255 dev dummy0"
  1622. run_cmd "$IP address add 192.0.2.1/24 broadcast 192.0.2.111 dev dummy0"
  1623. run_cmd "$IP neigh add 203.0.113.111 nud failed dev dummy0"
  1624. run_cmd "$IP neigh add 203.0.113.255 nud failed dev dummy0"
  1625. run_cmd "$IP neigh get 203.0.113.111 dev dummy0"
  1626. run_cmd "$IP neigh get 203.0.113.255 dev dummy0"
  1627. run_cmd "$IP address add 203.0.113.1/24 broadcast 203.0.113.111 dev dummy0"
  1628. set +e
  1629. run_cmd "$IP neigh get 192.0.2.111 dev dummy0"
  1630. log_test $? 0 "Resolved neighbour for broadcast address"
  1631. run_cmd "$IP neigh get 192.0.2.255 dev dummy0"
  1632. log_test $? 0 "Resolved neighbour for network broadcast address"
  1633. run_cmd "$IP neigh get 203.0.113.111 dev dummy0"
  1634. log_test $? 2 "Unresolved neighbour for broadcast address"
  1635. run_cmd "$IP neigh get 203.0.113.255 dev dummy0"
  1636. log_test $? 2 "Unresolved neighbour for network broadcast address"
  1637. cleanup
  1638. }
  1639. ################################################################################
  1640. # usage
  1641. usage()
  1642. {
  1643. cat <<EOF
  1644. usage: ${0##*/} OPTS
  1645. -t <test> Test(s) to run (default: all)
  1646. (options: $TESTS)
  1647. -p Pause on fail
  1648. -P Pause after each test before cleanup
  1649. -v verbose mode (show commands and output)
  1650. EOF
  1651. }
  1652. ################################################################################
  1653. # main
  1654. trap cleanup EXIT
  1655. while getopts :t:pPhv o
  1656. do
  1657. case $o in
  1658. t) TESTS=$OPTARG;;
  1659. p) PAUSE_ON_FAIL=yes;;
  1660. P) PAUSE=yes;;
  1661. v) VERBOSE=$(($VERBOSE + 1));;
  1662. h) usage; exit 0;;
  1663. *) usage; exit 1;;
  1664. esac
  1665. done
  1666. PEER_CMD="ip netns exec ${PEER_NS}"
  1667. # make sure we don't pause twice
  1668. [ "${PAUSE}" = "yes" ] && PAUSE_ON_FAIL=no
  1669. if [ "$(id -u)" -ne 0 ];then
  1670. echo "SKIP: Need root privileges"
  1671. exit $ksft_skip;
  1672. fi
  1673. if [ ! -x "$(command -v ip)" ]; then
  1674. echo "SKIP: Could not run test without ip tool"
  1675. exit $ksft_skip
  1676. fi
  1677. ip route help 2>&1 | grep -q fibmatch
  1678. if [ $? -ne 0 ]; then
  1679. echo "SKIP: iproute2 too old, missing fibmatch"
  1680. exit $ksft_skip
  1681. fi
  1682. # start clean
  1683. cleanup &> /dev/null
  1684. for t in $TESTS
  1685. do
  1686. case $t in
  1687. fib_unreg_test|unregister) fib_unreg_test;;
  1688. fib_down_test|down) fib_down_test;;
  1689. fib_carrier_test|carrier) fib_carrier_test;;
  1690. fib_rp_filter_test|rp_filter) fib_rp_filter_test;;
  1691. fib_nexthop_test|nexthop) fib_nexthop_test;;
  1692. fib_suppress_test|suppress) fib_suppress_test;;
  1693. ipv6_route_test|ipv6_rt) ipv6_route_test;;
  1694. ipv4_route_test|ipv4_rt) ipv4_route_test;;
  1695. ipv6_addr_metric) ipv6_addr_metric_test;;
  1696. ipv4_addr_metric) ipv4_addr_metric_test;;
  1697. ipv4_del_addr) ipv4_del_addr_test;;
  1698. ipv6_route_metrics) ipv6_route_metrics_test;;
  1699. ipv4_route_metrics) ipv4_route_metrics_test;;
  1700. ipv4_route_v6_gw) ipv4_route_v6_gw_test;;
  1701. ipv4_mangle) ipv4_mangle_test;;
  1702. ipv6_mangle) ipv6_mangle_test;;
  1703. ipv4_bcast_neigh) ipv4_bcast_neigh_test;;
  1704. help) echo "Test names: $TESTS"; exit 0;;
  1705. esac
  1706. done
  1707. if [ "$TESTS" != "none" ]; then
  1708. printf "\nTests passed: %3d\n" ${nsuccess}
  1709. printf "Tests failed: %3d\n" ${nfail}
  1710. fi
  1711. exit $ret