2 # SPDX-License-Identifier: GPL-2.0
4 # This test is for checking IPv4 and IPv6 FIB rules API
8 PAUSE_ON_FAIL
=${PAUSE_ON_FAIL:=no}
19 DEV_ADDR6
=2001:db8
:1::1
38 if [ ${rc} -eq ${expected} ]; then
39 nsuccess
=$
((nsuccess
+1))
40 printf " TEST: %-60s [ OK ]\n" "${msg}"
44 printf " TEST: %-60s [FAIL]\n" "${msg}"
45 if [ "${PAUSE_ON_FAIL}" = "yes" ]; then
47 echo "hit enter to continue, 'q' to quit"
49 [ "$a" = "q" ] && exit 1
58 IP
="ip -netns $testns"
60 $IP link add dummy0
type dummy
61 $IP link
set dev dummy0 up
62 $IP address add
$DEV_ADDR/24 dev dummy0
63 $IP -6 address add
$DEV_ADDR6/64 dev dummy0
70 $IP link del dev dummy0
&> /dev
/null
79 IP_PEER
="ip -netns $peerns"
80 $IP_PEER link
set dev lo up
82 ip link add name veth0 netns
$testns type veth \
83 peer name veth1 netns
$peerns
84 $IP link
set dev veth0 up
85 $IP_PEER link
set dev veth1 up
87 $IP address add
192.0.2.10 peer
192.0.2.11/32 dev veth0
88 $IP_PEER address add
192.0.2.11 peer
192.0.2.10/32 dev veth1
90 $IP address add
2001:db8
::10 peer
2001:db8
::11/128 dev veth0 nodad
91 $IP_PEER address add
2001:db8
::11 peer
2001:db8
::10/128 dev veth1 nodad
93 $IP_PEER address add
198.51.100.11/32 dev lo
94 $IP route add table
$RTABLE_PEER 198.51.100.11/32 via
192.0.2.11
96 $IP_PEER address add
2001:db8
::1:11/128 dev lo
97 $IP route add table
$RTABLE_PEER 2001:db8
::1:11/128 via
2001:db8
::11
104 $IP link del dev veth0
110 $IP link add name vrf0 up
type vrf table
$RTABLE_VRF
111 $IP link
set dev
$DEV master vrf0
116 $IP link del dev vrf0
119 fib_check_iproute_support
()
121 ip rule
help 2>&1 |
grep -q $1
122 if [ $?
-ne 0 ]; then
123 echo "SKIP: iproute2 iprule too old, missing $1 match"
127 ip route get
help 2>&1 |
grep -q $2
128 if [ $?
-ne 0 ]; then
129 echo "SKIP: iproute2 get route too old, missing $2 match"
139 log_test $?
0 "rule6 del $1"
142 fib_rule6_del_by_pref
()
144 pref
=$
($IP -6 rule show
$1 table
$RTABLE | cut
-d ":" -f 1)
145 $IP -6 rule del pref
$pref
148 fib_rule6_test_match_n_redirect
()
152 local getnomatch
="$3"
153 local description
="$4"
154 local nomatch_description
="$5"
156 $IP -6 rule add
$match table
$RTABLE
157 $IP -6 route get
$GW_IP6 $getmatch |
grep -q "table $RTABLE"
158 log_test $?
0 "rule6 check: $description"
160 $IP -6 route get
$GW_IP6 $getnomatch 2>&1 |
grep -q "table $RTABLE"
161 log_test $?
1 "rule6 check: $nomatch_description"
163 fib_rule6_del_by_pref
"$match"
164 log_test $?
0 "rule6 del by pref: $description"
167 fib_rule6_test_reject
()
172 $IP -6 rule add
$match table
$RTABLE 2>/dev
/null
174 log_test
$rc 2 "rule6 check: $match"
176 if [ $rc -eq 0 ]; then
177 $IP -6 rule del
$match table
$RTABLE
183 local ext_name
=$1; shift
190 echo "IPv6 FIB rule tests $ext_name"
192 # setup the fib rule redirect route
193 $IP -6 route add table
$RTABLE default via
$GW_IP6 dev
$DEV onlink
197 fib_rule6_test_match_n_redirect
"$match" "$match" "$getnomatch" \
198 "oif redirect to table" "oif no redirect to table"
200 match
="from $SRC_IP6 iif $DEV"
201 getnomatch
="from $SRC_IP6 iif lo"
202 fib_rule6_test_match_n_redirect
"$match" "$match" "$getnomatch" \
203 "iif redirect to table" "iif no redirect to table"
205 # Reject dsfield (tos) options which have ECN bits set
206 for cnt
in $
(seq 1 3); do
208 fib_rule6_test_reject
"$match"
211 # Don't take ECN bits into account when matching on dsfield
213 for cnt
in "0x10" "0x11" "0x12" "0x13"; do
214 # Using option 'tos' instead of 'dsfield' as old iproute2
215 # versions don't support 'dsfield' in ip rule show.
217 getnomatch
="tos 0x20"
218 fib_rule6_test_match_n_redirect
"$match" "$getmatch" \
219 "$getnomatch" "$getmatch redirect to table" \
220 "$getnomatch no redirect to table"
223 # Re-test TOS matching, but with input routes since they are handled
224 # differently from output routes.
226 for cnt
in "0x10" "0x11" "0x12" "0x13"; do
228 getnomatch
="tos 0x20"
229 fib_rule6_test_match_n_redirect
"$match" \
230 "from $SRC_IP6 iif $DEV $getmatch" \
231 "from $SRC_IP6 iif $DEV $getnomatch" \
232 "iif $getmatch redirect to table" \
233 "iif $getnomatch no redirect to table"
238 getnomatch
="mark 0x63"
239 fib_rule6_test_match_n_redirect
"$match" "$getmatch" "$getnomatch" \
240 "fwmark redirect to table" "fwmark no redirect to table"
242 fib_check_iproute_support
"uidrange" "uid"
243 if [ $?
-eq 0 ]; then
244 match
="uidrange 100-100"
247 fib_rule6_test_match_n_redirect
"$match" "$getmatch" \
248 "$getnomatch" "uid redirect to table" \
249 "uid no redirect to table"
252 fib_check_iproute_support
"sport" "sport"
253 if [ $?
-eq 0 ]; then
254 match
="sport 666 dport 777"
255 getnomatch
="sport 667 dport 778"
256 fib_rule6_test_match_n_redirect
"$match" "$match" \
257 "$getnomatch" "sport and dport redirect to table" \
258 "sport and dport no redirect to table"
261 fib_check_iproute_support
"ipproto" "ipproto"
262 if [ $?
-eq 0 ]; then
264 getnomatch
="ipproto udp"
265 fib_rule6_test_match_n_redirect
"$match" "$match" \
266 "$getnomatch" "ipproto tcp match" "ipproto udp no match"
269 fib_check_iproute_support
"ipproto" "ipproto"
270 if [ $?
-eq 0 ]; then
271 match
="ipproto ipv6-icmp"
272 getnomatch
="ipproto tcp"
273 fib_rule6_test_match_n_redirect
"$match" "$match" \
274 "$getnomatch" "ipproto ipv6-icmp match" \
275 "ipproto ipv6-tcp no match"
278 fib_check_iproute_support
"dscp" "tos"
279 if [ $?
-eq 0 ]; then
282 getnomatch
="tos 0xf4"
283 fib_rule6_test_match_n_redirect
"$match" "$getmatch" \
284 "$getnomatch" "dscp redirect to table" \
285 "dscp no redirect to table"
288 getmatch
="from $SRC_IP6 iif $DEV tos 0xfc"
289 getnomatch
="from $SRC_IP6 iif $DEV tos 0xf4"
290 fib_rule6_test_match_n_redirect
"$match" "$getmatch" \
291 "$getnomatch" "iif dscp redirect to table" \
292 "iif dscp no redirect to table"
299 fib_rule6_test
"- with VRF"
303 # Verify that the IPV6_TCLASS option of UDPv6 and TCPv6 sockets is properly
304 # taken into account when connecting the socket and when sending packets.
305 fib_rule6_connect_test
()
310 echo "IPv6 FIB rule connect tests"
313 $IP -6 rule add dsfield
0x04 table
$RTABLE_PEER
315 # Combine the base DS Field value (0x04) with all possible ECN values
316 # (Not-ECT: 0, ECT(1): 1, ECT(0): 2, CE: 3).
317 # The ECN bits shouldn't influence the result of the test.
318 for dsfield
in 0x04 0x05 0x06 0x07; do
319 nettest
-q -6 -B -t 5 -N $testns -O $peerns -U -D \
320 -Q "${dsfield}" -l 2001:db8
::1:11 -r 2001:db8
::1:11
321 log_test $?
0 "rule6 dsfield udp connect (dsfield ${dsfield})"
323 nettest
-q -6 -B -t 5 -N $testns -O $peerns -Q "${dsfield}" \
324 -l 2001:db8
::1:11 -r 2001:db8
::1:11
325 log_test $?
0 "rule6 dsfield tcp connect (dsfield ${dsfield})"
328 # Check that UDP and TCP connections fail when using a DS Field that
329 # does not match the previously configured FIB rule.
330 nettest
-q -6 -B -t 5 -N $testns -O $peerns -U -D \
331 -Q 0x20 -l 2001:db8
::1:11 -r 2001:db8
::1:11
332 log_test $?
1 "rule6 dsfield udp no connect (dsfield 0x20)"
334 nettest
-q -6 -B -t 5 -N $testns -O $peerns -Q 0x20 \
335 -l 2001:db8
::1:11 -r 2001:db8
::1:11
336 log_test $?
1 "rule6 dsfield tcp no connect (dsfield 0x20)"
338 $IP -6 rule del dsfield
0x04 table
$RTABLE_PEER
340 ip rule
help 2>&1 |
grep -q dscp
341 if [ $?
-ne 0 ]; then
342 echo "SKIP: iproute2 iprule too old, missing dscp match"
347 $IP -6 rule add dscp
0x3f table
$RTABLE_PEER
349 nettest
-q -6 -B -t 5 -N $testns -O $peerns -U -D -Q 0xfc \
350 -l 2001:db8
::1:11 -r 2001:db8
::1:11
351 log_test $?
0 "rule6 dscp udp connect"
353 nettest
-q -6 -B -t 5 -N $testns -O $peerns -Q 0xfc \
354 -l 2001:db8
::1:11 -r 2001:db8
::1:11
355 log_test $?
0 "rule6 dscp tcp connect"
357 nettest
-q -6 -B -t 5 -N $testns -O $peerns -U -D -Q 0xf4 \
358 -l 2001:db8
::1:11 -r 2001:db8
::1:11
359 log_test $?
1 "rule6 dscp udp no connect"
361 nettest
-q -6 -B -t 5 -N $testns -O $peerns -Q 0xf4 \
362 -l 2001:db8
::1:11 -r 2001:db8
::1:11
363 log_test $?
1 "rule6 dscp tcp no connect"
365 $IP -6 rule del dscp
0x3f table
$RTABLE_PEER
373 log_test $?
0 "del $1"
376 fib_rule4_del_by_pref
()
378 pref
=$
($IP rule show
$1 table
$RTABLE | cut
-d ":" -f 1)
379 $IP rule del pref
$pref
382 fib_rule4_test_match_n_redirect
()
386 local getnomatch
="$3"
387 local description
="$4"
388 local nomatch_description
="$5"
390 $IP rule add
$match table
$RTABLE
391 $IP route get
$GW_IP4 $getmatch |
grep -q "table $RTABLE"
392 log_test $?
0 "rule4 check: $description"
394 $IP route get
$GW_IP4 $getnomatch 2>&1 |
grep -q "table $RTABLE"
395 log_test $?
1 "rule4 check: $nomatch_description"
397 fib_rule4_del_by_pref
"$match"
398 log_test $?
0 "rule4 del by pref: $description"
401 fib_rule4_test_reject
()
406 $IP rule add
$match table
$RTABLE 2>/dev
/null
408 log_test
$rc 2 "rule4 check: $match"
410 if [ $rc -eq 0 ]; then
411 $IP rule del
$match table
$RTABLE
417 local ext_name
=$1; shift
424 echo "IPv4 FIB rule tests $ext_name"
426 # setup the fib rule redirect route
427 $IP route add table
$RTABLE default via
$GW_IP4 dev
$DEV onlink
431 fib_rule4_test_match_n_redirect
"$match" "$match" "$getnomatch" \
432 "oif redirect to table" "oif no redirect to table"
434 # Enable forwarding and disable rp_filter as all the addresses are in
435 # the same subnet and egress device == ingress device.
436 ip netns
exec $testns sysctl
-qw net.ipv4.ip_forward
=1
437 ip netns
exec $testns sysctl
-qw net.ipv4.conf.
$DEV.rp_filter
=0
438 match
="from $SRC_IP iif $DEV"
439 getnomatch
="from $SRC_IP iif lo"
440 fib_rule4_test_match_n_redirect
"$match" "$match" "$getnomatch" \
441 "iif redirect to table" "iif no redirect to table"
443 # Reject dsfield (tos) options which have ECN bits set
444 for cnt
in $
(seq 1 3); do
446 fib_rule4_test_reject
"$match"
449 # Don't take ECN bits into account when matching on dsfield
451 for cnt
in "0x10" "0x11" "0x12" "0x13"; do
452 # Using option 'tos' instead of 'dsfield' as old iproute2
453 # versions don't support 'dsfield' in ip rule show.
455 getnomatch
="tos 0x20"
456 fib_rule4_test_match_n_redirect
"$match" "$getmatch" \
457 "$getnomatch" "$getmatch redirect to table" \
458 "$getnomatch no redirect to table"
461 # Re-test TOS matching, but with input routes since they are handled
462 # differently from output routes.
464 for cnt
in "0x10" "0x11" "0x12" "0x13"; do
466 getnomatch
="tos 0x20"
467 fib_rule4_test_match_n_redirect
"$match" \
468 "from $SRC_IP iif $DEV $getmatch" \
469 "from $SRC_IP iif $DEV $getnomatch" \
470 "iif $getmatch redirect to table" \
471 "iif $getnomatch no redirect to table"
476 getnomatch
="mark 0x63"
477 fib_rule4_test_match_n_redirect
"$match" "$getmatch" "$getnomatch" \
478 "fwmark redirect to table" "fwmark no redirect to table"
480 fib_check_iproute_support
"uidrange" "uid"
481 if [ $?
-eq 0 ]; then
482 match
="uidrange 100-100"
485 fib_rule4_test_match_n_redirect
"$match" "$getmatch" \
486 "$getnomatch" "uid redirect to table" \
487 "uid no redirect to table"
490 fib_check_iproute_support
"sport" "sport"
491 if [ $?
-eq 0 ]; then
492 match
="sport 666 dport 777"
493 getnomatch
="sport 667 dport 778"
494 fib_rule4_test_match_n_redirect
"$match" "$match" \
495 "$getnomatch" "sport and dport redirect to table" \
496 "sport and dport no redirect to table"
499 fib_check_iproute_support
"ipproto" "ipproto"
500 if [ $?
-eq 0 ]; then
502 getnomatch
="ipproto udp"
503 fib_rule4_test_match_n_redirect
"$match" "$match" \
504 "$getnomatch" "ipproto tcp match" \
505 "ipproto udp no match"
508 fib_check_iproute_support
"ipproto" "ipproto"
509 if [ $?
-eq 0 ]; then
511 getnomatch
="ipproto tcp"
512 fib_rule4_test_match_n_redirect
"$match" "$match" \
513 "$getnomatch" "ipproto icmp match" \
514 "ipproto tcp no match"
517 fib_check_iproute_support
"dscp" "tos"
518 if [ $?
-eq 0 ]; then
521 getnomatch
="tos 0xf4"
522 fib_rule4_test_match_n_redirect
"$match" "$getmatch" \
523 "$getnomatch" "dscp redirect to table" \
524 "dscp no redirect to table"
527 getmatch
="from $SRC_IP iif $DEV tos 0xfc"
528 getnomatch
="from $SRC_IP iif $DEV tos 0xf4"
529 fib_rule4_test_match_n_redirect
"$match" "$getmatch" \
530 "$getnomatch" "iif dscp redirect to table" \
531 "iif dscp no redirect to table"
538 fib_rule4_test
"- with VRF"
542 # Verify that the IP_TOS option of UDPv4 and TCPv4 sockets is properly taken
543 # into account when connecting the socket and when sending packets.
544 fib_rule4_connect_test
()
549 echo "IPv4 FIB rule connect tests"
552 $IP -4 rule add dsfield
0x04 table
$RTABLE_PEER
554 # Combine the base DS Field value (0x04) with all possible ECN values
555 # (Not-ECT: 0, ECT(1): 1, ECT(0): 2, CE: 3).
556 # The ECN bits shouldn't influence the result of the test.
557 for dsfield
in 0x04 0x05 0x06 0x07; do
558 nettest
-q -B -t 5 -N $testns -O $peerns -D -U -Q "${dsfield}" \
559 -l 198.51.100.11 -r 198.51.100.11
560 log_test $?
0 "rule4 dsfield udp connect (dsfield ${dsfield})"
562 nettest
-q -B -t 5 -N $testns -O $peerns -Q "${dsfield}" \
563 -l 198.51.100.11 -r 198.51.100.11
564 log_test $?
0 "rule4 dsfield tcp connect (dsfield ${dsfield})"
567 # Check that UDP and TCP connections fail when using a DS Field that
568 # does not match the previously configured FIB rule.
569 nettest
-q -B -t 5 -N $testns -O $peerns -D -U -Q 0x20 \
570 -l 198.51.100.11 -r 198.51.100.11
571 log_test $?
1 "rule4 dsfield udp no connect (dsfield 0x20)"
573 nettest
-q -B -t 5 -N $testns -O $peerns -Q 0x20 \
574 -l 198.51.100.11 -r 198.51.100.11
575 log_test $?
1 "rule4 dsfield tcp no connect (dsfield 0x20)"
577 $IP -4 rule del dsfield
0x04 table
$RTABLE_PEER
579 ip rule
help 2>&1 |
grep -q dscp
580 if [ $?
-ne 0 ]; then
581 echo "SKIP: iproute2 iprule too old, missing dscp match"
586 $IP -4 rule add dscp
0x3f table
$RTABLE_PEER
588 nettest
-q -B -t 5 -N $testns -O $peerns -D -U -Q 0xfc \
589 -l 198.51.100.11 -r 198.51.100.11
590 log_test $?
0 "rule4 dscp udp connect"
592 nettest
-q -B -t 5 -N $testns -O $peerns -Q 0xfc \
593 -l 198.51.100.11 -r 198.51.100.11
594 log_test $?
0 "rule4 dscp tcp connect"
596 nettest
-q -B -t 5 -N $testns -O $peerns -D -U -Q 0xf4 \
597 -l 198.51.100.11 -r 198.51.100.11
598 log_test $?
1 "rule4 dscp udp no connect"
600 nettest
-q -B -t 5 -N $testns -O $peerns -Q 0xf4 \
601 -l 198.51.100.11 -r 198.51.100.11
602 log_test $?
1 "rule4 dscp tcp no connect"
604 $IP -4 rule del dscp
0x3f table
$RTABLE_PEER
608 ################################################################################
616 -t <test> Test(s) to run (default: all)
621 ################################################################################
624 while getopts ":t:h" opt
; do
632 if [ "$(id -u)" -ne 0 ];then
633 echo "SKIP: Need root privileges"
637 if [ ! -x "$(command -v ip)" ]; then
638 echo "SKIP: Could not run test without ip tool"
642 check_gen_prog
"nettest"
650 fib_rule6_test|fib_rule6
) fib_rule6_test
;;
651 fib_rule4_test|fib_rule4
) fib_rule4_test
;;
652 fib_rule6_connect_test|fib_rule6_connect
) fib_rule6_connect_test
;;
653 fib_rule4_connect_test|fib_rule4_connect
) fib_rule4_connect_test
;;
654 fib_rule6_vrf_test|fib_rule6_vrf
) fib_rule6_vrf_test
;;
655 fib_rule4_vrf_test|fib_rule4_vrf
) fib_rule4_vrf_test
;;
657 help) echo "Test names: $TESTS"; exit 0;;
663 if [ "$TESTS" != "none" ]; then
664 printf "\nTests passed: %3d\n" ${nsuccess}
665 printf "Tests failed: %3d\n" ${nfail}