fib_rule_tests.sh 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804
  1. #!/bin/bash
  2. # SPDX-License-Identifier: GPL-2.0
  3. # This test is for checking IPv4 and IPv6 FIB rules API
  4. source lib.sh
  5. ret=0
  6. PAUSE_ON_FAIL=${PAUSE_ON_FAIL:=no}
  7. RTABLE=100
  8. RTABLE_PEER=101
  9. RTABLE_VRF=102
  10. GW_IP4=192.51.100.2
  11. SRC_IP=192.51.100.3
  12. GW_IP6=2001:db8:1::2
  13. SRC_IP6=2001:db8:1::3
  14. DEV_ADDR=192.51.100.1
  15. DEV_ADDR6=2001:db8:1::1
  16. DEV=dummy0
  17. TESTS="
  18. fib_rule6
  19. fib_rule4
  20. fib_rule6_connect
  21. fib_rule4_connect
  22. fib_rule6_vrf
  23. fib_rule4_vrf
  24. "
  25. SELFTEST_PATH=""
  26. log_test()
  27. {
  28. local rc=$1
  29. local expected=$2
  30. local msg="$3"
  31. if [ ${rc} -eq ${expected} ]; then
  32. nsuccess=$((nsuccess+1))
  33. printf " TEST: %-60s [ OK ]\n" "${msg}"
  34. else
  35. ret=1
  36. nfail=$((nfail+1))
  37. printf " TEST: %-60s [FAIL]\n" "${msg}"
  38. if [ "${PAUSE_ON_FAIL}" = "yes" ]; then
  39. echo
  40. echo "hit enter to continue, 'q' to quit"
  41. read a
  42. [ "$a" = "q" ] && exit 1
  43. fi
  44. fi
  45. }
  46. setup()
  47. {
  48. set -e
  49. setup_ns testns
  50. IP="ip -netns $testns"
  51. $IP link add dummy0 type dummy
  52. $IP link set dev dummy0 up
  53. $IP address add $DEV_ADDR/24 dev dummy0
  54. $IP -6 address add $DEV_ADDR6/64 dev dummy0
  55. set +e
  56. }
  57. cleanup()
  58. {
  59. $IP link del dev dummy0 &> /dev/null
  60. cleanup_ns $testns
  61. }
  62. setup_peer()
  63. {
  64. set -e
  65. setup_ns peerns
  66. IP_PEER="ip -netns $peerns"
  67. $IP_PEER link set dev lo up
  68. ip link add name veth0 netns $testns type veth \
  69. peer name veth1 netns $peerns
  70. $IP link set dev veth0 up
  71. $IP_PEER link set dev veth1 up
  72. $IP address add 192.0.2.10 peer 192.0.2.11/32 dev veth0
  73. $IP_PEER address add 192.0.2.11 peer 192.0.2.10/32 dev veth1
  74. $IP address add 2001:db8::10 peer 2001:db8::11/128 dev veth0 nodad
  75. $IP_PEER address add 2001:db8::11 peer 2001:db8::10/128 dev veth1 nodad
  76. $IP_PEER address add 198.51.100.11/32 dev lo
  77. $IP route add table $RTABLE_PEER 198.51.100.11/32 via 192.0.2.11
  78. $IP_PEER address add 2001:db8::1:11/128 dev lo
  79. $IP route add table $RTABLE_PEER 2001:db8::1:11/128 via 2001:db8::11
  80. set +e
  81. }
  82. cleanup_peer()
  83. {
  84. $IP link del dev veth0
  85. ip netns del $peerns
  86. }
  87. setup_vrf()
  88. {
  89. $IP link add name vrf0 up type vrf table $RTABLE_VRF
  90. $IP link set dev $DEV master vrf0
  91. }
  92. cleanup_vrf()
  93. {
  94. $IP link del dev vrf0
  95. }
  96. fib_check_iproute_support()
  97. {
  98. ip rule help 2>&1 | grep -q $1
  99. if [ $? -ne 0 ]; then
  100. echo "SKIP: iproute2 iprule too old, missing $1 match"
  101. return 1
  102. fi
  103. ip route get help 2>&1 | grep -q $2
  104. if [ $? -ne 0 ]; then
  105. echo "SKIP: iproute2 get route too old, missing $2 match"
  106. return 1
  107. fi
  108. return 0
  109. }
  110. fib_rule6_del()
  111. {
  112. $IP -6 rule del $1
  113. log_test $? 0 "rule6 del $1"
  114. }
  115. fib_rule6_del_by_pref()
  116. {
  117. pref=$($IP -6 rule show $1 table $RTABLE | cut -d ":" -f 1)
  118. $IP -6 rule del pref $pref
  119. }
  120. fib_rule6_test_match_n_redirect()
  121. {
  122. local match="$1"
  123. local getmatch="$2"
  124. local getnomatch="$3"
  125. local description="$4"
  126. local nomatch_description="$5"
  127. $IP -6 rule add $match table $RTABLE
  128. $IP -6 route get $GW_IP6 $getmatch | grep -q "table $RTABLE"
  129. log_test $? 0 "rule6 check: $description"
  130. $IP -6 route get $GW_IP6 $getnomatch 2>&1 | grep -q "table $RTABLE"
  131. log_test $? 1 "rule6 check: $nomatch_description"
  132. fib_rule6_del_by_pref "$match"
  133. log_test $? 0 "rule6 del by pref: $description"
  134. }
  135. fib_rule6_test_reject()
  136. {
  137. local match="$1"
  138. local rc
  139. $IP -6 rule add $match table $RTABLE 2>/dev/null
  140. rc=$?
  141. log_test $rc 2 "rule6 check: $match"
  142. if [ $rc -eq 0 ]; then
  143. $IP -6 rule del $match table $RTABLE
  144. fi
  145. }
  146. fib_rule6_test()
  147. {
  148. local ext_name=$1; shift
  149. local getnomatch
  150. local getmatch
  151. local match
  152. local cnt
  153. echo
  154. echo "IPv6 FIB rule tests $ext_name"
  155. # setup the fib rule redirect route
  156. $IP -6 route add table $RTABLE default via $GW_IP6 dev $DEV onlink
  157. match="oif $DEV"
  158. getnomatch="oif lo"
  159. fib_rule6_test_match_n_redirect "$match" "$match" "$getnomatch" \
  160. "oif redirect to table" "oif no redirect to table"
  161. match="from $SRC_IP6 iif $DEV"
  162. getnomatch="from $SRC_IP6 iif lo"
  163. fib_rule6_test_match_n_redirect "$match" "$match" "$getnomatch" \
  164. "iif redirect to table" "iif no redirect to table"
  165. # Reject dsfield (tos) options which have ECN bits set
  166. for cnt in $(seq 1 3); do
  167. match="dsfield $cnt"
  168. fib_rule6_test_reject "$match"
  169. done
  170. # Don't take ECN bits into account when matching on dsfield
  171. match="tos 0x10"
  172. for cnt in "0x10" "0x11" "0x12" "0x13"; do
  173. # Using option 'tos' instead of 'dsfield' as old iproute2
  174. # versions don't support 'dsfield' in ip rule show.
  175. getmatch="tos $cnt"
  176. getnomatch="tos 0x20"
  177. fib_rule6_test_match_n_redirect "$match" "$getmatch" \
  178. "$getnomatch" "$getmatch redirect to table" \
  179. "$getnomatch no redirect to table"
  180. done
  181. # Re-test TOS matching, but with input routes since they are handled
  182. # differently from output routes.
  183. match="tos 0x10"
  184. for cnt in "0x10" "0x11" "0x12" "0x13"; do
  185. getmatch="tos $cnt"
  186. getnomatch="tos 0x20"
  187. fib_rule6_test_match_n_redirect "$match" \
  188. "from $SRC_IP6 iif $DEV $getmatch" \
  189. "from $SRC_IP6 iif $DEV $getnomatch" \
  190. "iif $getmatch redirect to table" \
  191. "iif $getnomatch no redirect to table"
  192. done
  193. match="fwmark 0x64"
  194. getmatch="mark 0x64"
  195. getnomatch="mark 0x63"
  196. fib_rule6_test_match_n_redirect "$match" "$getmatch" "$getnomatch" \
  197. "fwmark redirect to table" "fwmark no redirect to table"
  198. fib_check_iproute_support "uidrange" "uid"
  199. if [ $? -eq 0 ]; then
  200. match="uidrange 100-100"
  201. getmatch="uid 100"
  202. getnomatch="uid 101"
  203. fib_rule6_test_match_n_redirect "$match" "$getmatch" \
  204. "$getnomatch" "uid redirect to table" \
  205. "uid no redirect to table"
  206. fi
  207. fib_check_iproute_support "sport" "sport"
  208. if [ $? -eq 0 ]; then
  209. match="sport 666 dport 777"
  210. getnomatch="sport 667 dport 778"
  211. fib_rule6_test_match_n_redirect "$match" "$match" \
  212. "$getnomatch" "sport and dport redirect to table" \
  213. "sport and dport no redirect to table"
  214. match="sport 100-200 dport 300-400"
  215. getmatch="sport 100 dport 400"
  216. getnomatch="sport 100 dport 401"
  217. fib_rule6_test_match_n_redirect "$match" "$getmatch" \
  218. "$getnomatch" \
  219. "sport and dport range redirect to table" \
  220. "sport and dport range no redirect to table"
  221. fi
  222. ip rule help 2>&1 | grep sport | grep -q MASK
  223. if [ $? -eq 0 ]; then
  224. match="sport 0x0f00/0xff00 dport 0x000f/0x00ff"
  225. getmatch="sport 0x0f11 dport 0x220f"
  226. getnomatch="sport 0x1f11 dport 0x221f"
  227. fib_rule6_test_match_n_redirect "$match" "$getmatch" \
  228. "$getnomatch" "sport and dport masked redirect to table" \
  229. "sport and dport masked no redirect to table"
  230. fi
  231. fib_check_iproute_support "ipproto" "ipproto"
  232. if [ $? -eq 0 ]; then
  233. match="ipproto tcp"
  234. getnomatch="ipproto udp"
  235. fib_rule6_test_match_n_redirect "$match" "$match" \
  236. "$getnomatch" "ipproto tcp match" "ipproto udp no match"
  237. fi
  238. fib_check_iproute_support "ipproto" "ipproto"
  239. if [ $? -eq 0 ]; then
  240. match="ipproto ipv6-icmp"
  241. getnomatch="ipproto tcp"
  242. fib_rule6_test_match_n_redirect "$match" "$match" \
  243. "$getnomatch" "ipproto ipv6-icmp match" \
  244. "ipproto ipv6-tcp no match"
  245. fi
  246. fib_check_iproute_support "dscp" "tos"
  247. if [ $? -eq 0 ]; then
  248. match="dscp 0x3f"
  249. getmatch="tos 0xfc"
  250. getnomatch="tos 0xf4"
  251. fib_rule6_test_match_n_redirect "$match" "$getmatch" \
  252. "$getnomatch" "dscp redirect to table" \
  253. "dscp no redirect to table"
  254. match="dscp 0x3f"
  255. getmatch="from $SRC_IP6 iif $DEV tos 0xfc"
  256. getnomatch="from $SRC_IP6 iif $DEV tos 0xf4"
  257. fib_rule6_test_match_n_redirect "$match" "$getmatch" \
  258. "$getnomatch" "iif dscp redirect to table" \
  259. "iif dscp no redirect to table"
  260. fi
  261. ip rule help 2>&1 | grep -q "DSCP\[/MASK\]"
  262. if [ $? -eq 0 ]; then
  263. match="dscp 0x0f/0x0f"
  264. tosmatch=$(printf 0x"%x" $((0x1f << 2)))
  265. tosnomatch=$(printf 0x"%x" $((0x1e << 2)))
  266. getmatch="tos $tosmatch"
  267. getnomatch="tos $tosnomatch"
  268. fib_rule6_test_match_n_redirect "$match" "$getmatch" \
  269. "$getnomatch" "dscp masked redirect to table" \
  270. "dscp masked no redirect to table"
  271. match="dscp 0x0f/0x0f"
  272. getmatch="from $SRC_IP6 iif $DEV tos $tosmatch"
  273. getnomatch="from $SRC_IP6 iif $DEV tos $tosnomatch"
  274. fib_rule6_test_match_n_redirect "$match" "$getmatch" \
  275. "$getnomatch" "iif dscp masked redirect to table" \
  276. "iif dscp masked no redirect to table"
  277. fi
  278. fib_check_iproute_support "flowlabel" "flowlabel"
  279. if [ $? -eq 0 ]; then
  280. match="flowlabel 0xfffff"
  281. getmatch="flowlabel 0xfffff"
  282. getnomatch="flowlabel 0xf"
  283. fib_rule6_test_match_n_redirect "$match" "$getmatch" \
  284. "$getnomatch" "flowlabel redirect to table" \
  285. "flowlabel no redirect to table"
  286. match="flowlabel 0xfffff"
  287. getmatch="from $SRC_IP6 iif $DEV flowlabel 0xfffff"
  288. getnomatch="from $SRC_IP6 iif $DEV flowlabel 0xf"
  289. fib_rule6_test_match_n_redirect "$match" "$getmatch" \
  290. "$getnomatch" "iif flowlabel redirect to table" \
  291. "iif flowlabel no redirect to table"
  292. match="flowlabel 0x08000/0x08000"
  293. getmatch="flowlabel 0xfffff"
  294. getnomatch="flowlabel 0xf7fff"
  295. fib_rule6_test_match_n_redirect "$match" "$getmatch" \
  296. "$getnomatch" "flowlabel masked redirect to table" \
  297. "flowlabel masked no redirect to table"
  298. match="flowlabel 0x08000/0x08000"
  299. getmatch="from $SRC_IP6 iif $DEV flowlabel 0xfffff"
  300. getnomatch="from $SRC_IP6 iif $DEV flowlabel 0xf7fff"
  301. fib_rule6_test_match_n_redirect "$match" "$getmatch" \
  302. "$getnomatch" "iif flowlabel masked redirect to table" \
  303. "iif flowlabel masked no redirect to table"
  304. fi
  305. $IP link show dev $DEV | grep -q vrf0
  306. if [ $? -eq 0 ]; then
  307. match="oif vrf0"
  308. getmatch="oif $DEV"
  309. getnomatch="oif lo"
  310. fib_rule6_test_match_n_redirect "$match" "$getmatch" \
  311. "$getnomatch" "VRF oif redirect to table" \
  312. "VRF oif no redirect to table"
  313. match="from $SRC_IP6 iif vrf0"
  314. getmatch="from $SRC_IP6 iif $DEV"
  315. getnomatch="from $SRC_IP6 iif lo"
  316. fib_rule6_test_match_n_redirect "$match" "$getmatch" \
  317. "$getnomatch" "VRF iif redirect to table" \
  318. "VRF iif no redirect to table"
  319. fi
  320. }
  321. fib_rule6_vrf_test()
  322. {
  323. setup_vrf
  324. fib_rule6_test "- with VRF"
  325. cleanup_vrf
  326. }
  327. # Verify that the IPV6_TCLASS option of UDPv6 and TCPv6 sockets is properly
  328. # taken into account when connecting the socket and when sending packets.
  329. fib_rule6_connect_test()
  330. {
  331. local dsfield
  332. echo
  333. echo "IPv6 FIB rule connect tests"
  334. setup_peer
  335. $IP -6 rule add dsfield 0x04 table $RTABLE_PEER
  336. # Combine the base DS Field value (0x04) with all possible ECN values
  337. # (Not-ECT: 0, ECT(1): 1, ECT(0): 2, CE: 3).
  338. # The ECN bits shouldn't influence the result of the test.
  339. for dsfield in 0x04 0x05 0x06 0x07; do
  340. nettest -q -6 -B -t 5 -N $testns -O $peerns -U -D \
  341. -Q "${dsfield}" -l 2001:db8::1:11 -r 2001:db8::1:11
  342. log_test $? 0 "rule6 dsfield udp connect (dsfield ${dsfield})"
  343. nettest -q -6 -B -t 5 -N $testns -O $peerns -Q "${dsfield}" \
  344. -l 2001:db8::1:11 -r 2001:db8::1:11
  345. log_test $? 0 "rule6 dsfield tcp connect (dsfield ${dsfield})"
  346. done
  347. # Check that UDP and TCP connections fail when using a DS Field that
  348. # does not match the previously configured FIB rule.
  349. nettest -q -6 -B -t 5 -N $testns -O $peerns -U -D \
  350. -Q 0x20 -l 2001:db8::1:11 -r 2001:db8::1:11
  351. log_test $? 1 "rule6 dsfield udp no connect (dsfield 0x20)"
  352. nettest -q -6 -B -t 5 -N $testns -O $peerns -Q 0x20 \
  353. -l 2001:db8::1:11 -r 2001:db8::1:11
  354. log_test $? 1 "rule6 dsfield tcp no connect (dsfield 0x20)"
  355. $IP -6 rule del dsfield 0x04 table $RTABLE_PEER
  356. ip rule help 2>&1 | grep -q dscp
  357. if [ $? -ne 0 ]; then
  358. echo "SKIP: iproute2 iprule too old, missing dscp match"
  359. cleanup_peer
  360. return
  361. fi
  362. $IP -6 rule add dscp 0x3f table $RTABLE_PEER
  363. nettest -q -6 -B -t 5 -N $testns -O $peerns -U -D -Q 0xfc \
  364. -l 2001:db8::1:11 -r 2001:db8::1:11
  365. log_test $? 0 "rule6 dscp udp connect"
  366. nettest -q -6 -B -t 5 -N $testns -O $peerns -Q 0xfc \
  367. -l 2001:db8::1:11 -r 2001:db8::1:11
  368. log_test $? 0 "rule6 dscp tcp connect"
  369. nettest -q -6 -B -t 5 -N $testns -O $peerns -U -D -Q 0xf4 \
  370. -l 2001:db8::1:11 -r 2001:db8::1:11
  371. log_test $? 1 "rule6 dscp udp no connect"
  372. nettest -q -6 -B -t 5 -N $testns -O $peerns -Q 0xf4 \
  373. -l 2001:db8::1:11 -r 2001:db8::1:11
  374. log_test $? 1 "rule6 dscp tcp no connect"
  375. $IP -6 rule del dscp 0x3f table $RTABLE_PEER
  376. cleanup_peer
  377. }
  378. fib_rule4_del()
  379. {
  380. $IP rule del $1
  381. log_test $? 0 "del $1"
  382. }
  383. fib_rule4_del_by_pref()
  384. {
  385. pref=$($IP rule show $1 table $RTABLE | cut -d ":" -f 1)
  386. $IP rule del pref $pref
  387. }
  388. fib_rule4_test_match_n_redirect()
  389. {
  390. local match="$1"
  391. local getmatch="$2"
  392. local getnomatch="$3"
  393. local description="$4"
  394. local nomatch_description="$5"
  395. $IP rule add $match table $RTABLE
  396. $IP route get $GW_IP4 $getmatch | grep -q "table $RTABLE"
  397. log_test $? 0 "rule4 check: $description"
  398. $IP route get $GW_IP4 $getnomatch 2>&1 | grep -q "table $RTABLE"
  399. log_test $? 1 "rule4 check: $nomatch_description"
  400. fib_rule4_del_by_pref "$match"
  401. log_test $? 0 "rule4 del by pref: $description"
  402. }
  403. fib_rule4_test_reject()
  404. {
  405. local match="$1"
  406. local rc
  407. $IP rule add $match table $RTABLE 2>/dev/null
  408. rc=$?
  409. log_test $rc 2 "rule4 check: $match"
  410. if [ $rc -eq 0 ]; then
  411. $IP rule del $match table $RTABLE
  412. fi
  413. }
  414. fib_rule4_test()
  415. {
  416. local ext_name=$1; shift
  417. local getnomatch
  418. local getmatch
  419. local match
  420. local cnt
  421. echo
  422. echo "IPv4 FIB rule tests $ext_name"
  423. # setup the fib rule redirect route
  424. $IP route add table $RTABLE default via $GW_IP4 dev $DEV onlink
  425. match="oif $DEV"
  426. getnomatch="oif lo"
  427. fib_rule4_test_match_n_redirect "$match" "$match" "$getnomatch" \
  428. "oif redirect to table" "oif no redirect to table"
  429. ip netns exec $testns sysctl -qw net.ipv4.ip_forward=1
  430. match="from $SRC_IP iif $DEV"
  431. getnomatch="from $SRC_IP iif lo"
  432. fib_rule4_test_match_n_redirect "$match" "$match" "$getnomatch" \
  433. "iif redirect to table" "iif no redirect to table"
  434. # Reject dsfield (tos) options which have ECN bits set
  435. for cnt in $(seq 1 3); do
  436. match="dsfield $cnt"
  437. fib_rule4_test_reject "$match"
  438. done
  439. # Don't take ECN bits into account when matching on dsfield
  440. match="tos 0x10"
  441. for cnt in "0x10" "0x11" "0x12" "0x13"; do
  442. # Using option 'tos' instead of 'dsfield' as old iproute2
  443. # versions don't support 'dsfield' in ip rule show.
  444. getmatch="tos $cnt"
  445. getnomatch="tos 0x20"
  446. fib_rule4_test_match_n_redirect "$match" "$getmatch" \
  447. "$getnomatch" "$getmatch redirect to table" \
  448. "$getnomatch no redirect to table"
  449. done
  450. # Re-test TOS matching, but with input routes since they are handled
  451. # differently from output routes.
  452. match="tos 0x10"
  453. for cnt in "0x10" "0x11" "0x12" "0x13"; do
  454. getmatch="tos $cnt"
  455. getnomatch="tos 0x20"
  456. fib_rule4_test_match_n_redirect "$match" \
  457. "from $SRC_IP iif $DEV $getmatch" \
  458. "from $SRC_IP iif $DEV $getnomatch" \
  459. "iif $getmatch redirect to table" \
  460. "iif $getnomatch no redirect to table"
  461. done
  462. match="fwmark 0x64"
  463. getmatch="mark 0x64"
  464. getnomatch="mark 0x63"
  465. fib_rule4_test_match_n_redirect "$match" "$getmatch" "$getnomatch" \
  466. "fwmark redirect to table" "fwmark no redirect to table"
  467. fib_check_iproute_support "uidrange" "uid"
  468. if [ $? -eq 0 ]; then
  469. match="uidrange 100-100"
  470. getmatch="uid 100"
  471. getnomatch="uid 101"
  472. fib_rule4_test_match_n_redirect "$match" "$getmatch" \
  473. "$getnomatch" "uid redirect to table" \
  474. "uid no redirect to table"
  475. fi
  476. fib_check_iproute_support "sport" "sport"
  477. if [ $? -eq 0 ]; then
  478. match="sport 666 dport 777"
  479. getnomatch="sport 667 dport 778"
  480. fib_rule4_test_match_n_redirect "$match" "$match" \
  481. "$getnomatch" "sport and dport redirect to table" \
  482. "sport and dport no redirect to table"
  483. match="sport 100-200 dport 300-400"
  484. getmatch="sport 100 dport 400"
  485. getnomatch="sport 100 dport 401"
  486. fib_rule4_test_match_n_redirect "$match" "$getmatch" \
  487. "$getnomatch" \
  488. "sport and dport range redirect to table" \
  489. "sport and dport range no redirect to table"
  490. fi
  491. ip rule help 2>&1 | grep sport | grep -q MASK
  492. if [ $? -eq 0 ]; then
  493. match="sport 0x0f00/0xff00 dport 0x000f/0x00ff"
  494. getmatch="sport 0x0f11 dport 0x220f"
  495. getnomatch="sport 0x1f11 dport 0x221f"
  496. fib_rule4_test_match_n_redirect "$match" "$getmatch" \
  497. "$getnomatch" "sport and dport masked redirect to table" \
  498. "sport and dport masked no redirect to table"
  499. fi
  500. fib_check_iproute_support "ipproto" "ipproto"
  501. if [ $? -eq 0 ]; then
  502. match="ipproto tcp"
  503. getnomatch="ipproto udp"
  504. fib_rule4_test_match_n_redirect "$match" "$match" \
  505. "$getnomatch" "ipproto tcp match" \
  506. "ipproto udp no match"
  507. fi
  508. fib_check_iproute_support "ipproto" "ipproto"
  509. if [ $? -eq 0 ]; then
  510. match="ipproto icmp"
  511. getnomatch="ipproto tcp"
  512. fib_rule4_test_match_n_redirect "$match" "$match" \
  513. "$getnomatch" "ipproto icmp match" \
  514. "ipproto tcp no match"
  515. fi
  516. fib_check_iproute_support "dscp" "tos"
  517. if [ $? -eq 0 ]; then
  518. match="dscp 0x3f"
  519. getmatch="tos 0xfc"
  520. getnomatch="tos 0xf4"
  521. fib_rule4_test_match_n_redirect "$match" "$getmatch" \
  522. "$getnomatch" "dscp redirect to table" \
  523. "dscp no redirect to table"
  524. match="dscp 0x3f"
  525. getmatch="from $SRC_IP iif $DEV tos 0xfc"
  526. getnomatch="from $SRC_IP iif $DEV tos 0xf4"
  527. fib_rule4_test_match_n_redirect "$match" "$getmatch" \
  528. "$getnomatch" "iif dscp redirect to table" \
  529. "iif dscp no redirect to table"
  530. fi
  531. ip rule help 2>&1 | grep -q "DSCP\[/MASK\]"
  532. if [ $? -eq 0 ]; then
  533. match="dscp 0x0f/0x0f"
  534. tosmatch=$(printf 0x"%x" $((0x1f << 2)))
  535. tosnomatch=$(printf 0x"%x" $((0x1e << 2)))
  536. getmatch="tos $tosmatch"
  537. getnomatch="tos $tosnomatch"
  538. fib_rule4_test_match_n_redirect "$match" "$getmatch" \
  539. "$getnomatch" "dscp masked redirect to table" \
  540. "dscp masked no redirect to table"
  541. match="dscp 0x0f/0x0f"
  542. getmatch="from $SRC_IP iif $DEV tos $tosmatch"
  543. getnomatch="from $SRC_IP iif $DEV tos $tosnomatch"
  544. fib_rule4_test_match_n_redirect "$match" "$getmatch" \
  545. "$getnomatch" "iif dscp masked redirect to table" \
  546. "iif dscp masked no redirect to table"
  547. fi
  548. $IP link show dev $DEV | grep -q vrf0
  549. if [ $? -eq 0 ]; then
  550. match="oif vrf0"
  551. getmatch="oif $DEV"
  552. getnomatch="oif lo"
  553. fib_rule4_test_match_n_redirect "$match" "$getmatch" \
  554. "$getnomatch" "VRF oif redirect to table" \
  555. "VRF oif no redirect to table"
  556. match="from $SRC_IP iif vrf0"
  557. getmatch="from $SRC_IP iif $DEV"
  558. getnomatch="from $SRC_IP iif lo"
  559. fib_rule4_test_match_n_redirect "$match" "$getmatch" \
  560. "$getnomatch" "VRF iif redirect to table" \
  561. "VRF iif no redirect to table"
  562. fi
  563. }
  564. fib_rule4_vrf_test()
  565. {
  566. setup_vrf
  567. fib_rule4_test "- with VRF"
  568. cleanup_vrf
  569. }
  570. # Verify that the IP_TOS option of UDPv4 and TCPv4 sockets is properly taken
  571. # into account when connecting the socket and when sending packets.
  572. fib_rule4_connect_test()
  573. {
  574. local dsfield
  575. echo
  576. echo "IPv4 FIB rule connect tests"
  577. setup_peer
  578. $IP -4 rule add dsfield 0x04 table $RTABLE_PEER
  579. # Combine the base DS Field value (0x04) with all possible ECN values
  580. # (Not-ECT: 0, ECT(1): 1, ECT(0): 2, CE: 3).
  581. # The ECN bits shouldn't influence the result of the test.
  582. for dsfield in 0x04 0x05 0x06 0x07; do
  583. nettest -q -B -t 5 -N $testns -O $peerns -D -U -Q "${dsfield}" \
  584. -l 198.51.100.11 -r 198.51.100.11
  585. log_test $? 0 "rule4 dsfield udp connect (dsfield ${dsfield})"
  586. nettest -q -B -t 5 -N $testns -O $peerns -Q "${dsfield}" \
  587. -l 198.51.100.11 -r 198.51.100.11
  588. log_test $? 0 "rule4 dsfield tcp connect (dsfield ${dsfield})"
  589. done
  590. # Check that UDP and TCP connections fail when using a DS Field that
  591. # does not match the previously configured FIB rule.
  592. nettest -q -B -t 5 -N $testns -O $peerns -D -U -Q 0x20 \
  593. -l 198.51.100.11 -r 198.51.100.11
  594. log_test $? 1 "rule4 dsfield udp no connect (dsfield 0x20)"
  595. nettest -q -B -t 5 -N $testns -O $peerns -Q 0x20 \
  596. -l 198.51.100.11 -r 198.51.100.11
  597. log_test $? 1 "rule4 dsfield tcp no connect (dsfield 0x20)"
  598. $IP -4 rule del dsfield 0x04 table $RTABLE_PEER
  599. ip rule help 2>&1 | grep -q dscp
  600. if [ $? -ne 0 ]; then
  601. echo "SKIP: iproute2 iprule too old, missing dscp match"
  602. cleanup_peer
  603. return
  604. fi
  605. $IP -4 rule add dscp 0x3f table $RTABLE_PEER
  606. nettest -q -B -t 5 -N $testns -O $peerns -D -U -Q 0xfc \
  607. -l 198.51.100.11 -r 198.51.100.11
  608. log_test $? 0 "rule4 dscp udp connect"
  609. nettest -q -B -t 5 -N $testns -O $peerns -Q 0xfc \
  610. -l 198.51.100.11 -r 198.51.100.11
  611. log_test $? 0 "rule4 dscp tcp connect"
  612. nettest -q -B -t 5 -N $testns -O $peerns -D -U -Q 0xf4 \
  613. -l 198.51.100.11 -r 198.51.100.11
  614. log_test $? 1 "rule4 dscp udp no connect"
  615. nettest -q -B -t 5 -N $testns -O $peerns -Q 0xf4 \
  616. -l 198.51.100.11 -r 198.51.100.11
  617. log_test $? 1 "rule4 dscp tcp no connect"
  618. $IP -4 rule del dscp 0x3f table $RTABLE_PEER
  619. cleanup_peer
  620. }
  621. ################################################################################
  622. # usage
  623. usage()
  624. {
  625. cat <<EOF
  626. usage: ${0##*/} OPTS
  627. -t <test> Test(s) to run (default: all)
  628. (options: $TESTS)
  629. EOF
  630. }
  631. ################################################################################
  632. # main
  633. while getopts ":t:h" opt; do
  634. case $opt in
  635. t) TESTS=$OPTARG;;
  636. h) usage; exit 0;;
  637. *) usage; exit 1;;
  638. esac
  639. done
  640. if [ "$(id -u)" -ne 0 ];then
  641. echo "SKIP: Need root privileges"
  642. exit $ksft_skip
  643. fi
  644. if [ ! -x "$(command -v ip)" ]; then
  645. echo "SKIP: Could not run test without ip tool"
  646. exit $ksft_skip
  647. fi
  648. check_gen_prog "nettest"
  649. # start clean
  650. cleanup &> /dev/null
  651. setup
  652. for t in $TESTS
  653. do
  654. case $t in
  655. fib_rule6_test|fib_rule6) fib_rule6_test;;
  656. fib_rule4_test|fib_rule4) fib_rule4_test;;
  657. fib_rule6_connect_test|fib_rule6_connect) fib_rule6_connect_test;;
  658. fib_rule4_connect_test|fib_rule4_connect) fib_rule4_connect_test;;
  659. fib_rule6_vrf_test|fib_rule6_vrf) fib_rule6_vrf_test;;
  660. fib_rule4_vrf_test|fib_rule4_vrf) fib_rule4_vrf_test;;
  661. help) echo "Test names: $TESTS"; exit 0;;
  662. esac
  663. done
  664. cleanup
  665. if [ "$TESTS" != "none" ]; then
  666. printf "\nTests passed: %3d\n" ${nsuccess}
  667. printf "Tests failed: %3d\n" ${nfail}
  668. fi
  669. exit $ret