2 # SPDX-License-Identifier: GPL-2.0+
6 # This script evaluates the IOAM insertion for IPv6 by checking the IOAM data
7 # consistency directly inside packets on the receiver side. Tests are divided
8 # into three categories: OUTPUT (evaluates the IOAM processing by the sender),
9 # INPUT (evaluates the IOAM processing by a receiver) and GLOBAL (evaluates
10 # wider use cases that do not fall into the other two categories). Both OUTPUT
11 # and INPUT tests only use a two-node topology (alpha and beta), while GLOBAL
12 # tests use the entire three-node topology (alpha, beta, gamma). Each test is
13 # documented inside its own handler in the code below.
15 # An IOAM domain is configured from Alpha to Gamma but not on the reverse path.
16 # When either Beta or Gamma is the destination (depending on the test category),
17 # Alpha adds an IOAM option (Pre-allocated Trace) inside a Hop-by-hop.
20 # +-------------------+ +-------------------+
22 # | Alpha netns | | Gamma netns |
24 # | +-------------+ | | +-------------+ |
25 # | | veth0 | | | | veth0 | |
26 # | | db01::2/64 | | | | db02::2/64 | |
27 # | +-------------+ | | +-------------+ |
29 # +-------------------+ +-------------------+
33 # +----------------------------------------------------+
35 # | +-------------+ +-------------+ |
36 # | | veth0 | | veth1 | |
37 # | | db01::1/64 | ................ | db02::1/64 | |
38 # | +-------------+ +-------------+ |
42 # +----------------------------------------------------+
46 # =============================================================
47 # | Alpha - IOAM configuration |
48 # +===========================================================+
50 # +-----------------------------------------------------------+
51 # | Node Wide ID | 11111111 |
52 # +-----------------------------------------------------------+
53 # | Ingress ID | 0xffff (default value) |
54 # +-----------------------------------------------------------+
55 # | Ingress Wide ID | 0xffffffff (default value) |
56 # +-----------------------------------------------------------+
58 # +-----------------------------------------------------------+
59 # | Egress Wide ID | 101101 |
60 # +-----------------------------------------------------------+
61 # | Namespace Data | 0xdeadbee0 |
62 # +-----------------------------------------------------------+
63 # | Namespace Wide Data | 0xcafec0caf00dc0de |
64 # +-----------------------------------------------------------+
66 # +-----------------------------------------------------------+
67 # | Schema Data | something that will be 4n-aligned |
68 # +-----------------------------------------------------------+
71 # =============================================================
72 # | Beta - IOAM configuration |
73 # +===========================================================+
75 # +-----------------------------------------------------------+
76 # | Node Wide ID | 22222222 |
77 # +-----------------------------------------------------------+
78 # | Ingress ID | 201 |
79 # +-----------------------------------------------------------+
80 # | Ingress Wide ID | 201201 |
81 # +-----------------------------------------------------------+
83 # +-----------------------------------------------------------+
84 # | Egress Wide ID | 202202 |
85 # +-----------------------------------------------------------+
86 # | Namespace Data | 0xdeadbee1 |
87 # +-----------------------------------------------------------+
88 # | Namespace Wide Data | 0xcafec0caf11dc0de |
89 # +-----------------------------------------------------------+
91 # +-----------------------------------------------------------+
92 # | Schema Data | Hello there -Obi |
93 # +-----------------------------------------------------------+
96 # =============================================================
97 # | Gamma - IOAM configuration |
98 # +===========================================================+
100 # +-----------------------------------------------------------+
101 # | Node Wide ID | 33333333 |
102 # +-----------------------------------------------------------+
103 # | Ingress ID | 301 |
104 # +-----------------------------------------------------------+
105 # | Ingress Wide ID | 301301 |
106 # +-----------------------------------------------------------+
107 # | Egress ID | 0xffff (default value) |
108 # +-----------------------------------------------------------+
109 # | Egress Wide ID | 0xffffffff (default value) |
110 # +-----------------------------------------------------------+
111 # | Namespace Data | 0xdeadbee2 |
112 # +-----------------------------------------------------------+
113 # | Namespace Wide Data | 0xcafec0caf22dc0de |
114 # +-----------------------------------------------------------+
115 # | Schema ID | 0xffffff (= None) |
116 # +-----------------------------------------------------------+
118 # +-----------------------------------------------------------+
120 # Kselftest framework requirement - SKIP code is 4.
123 ################################################################################
125 # WARNING: Be careful if you modify the block below - it MUST be kept #
126 # synchronized with configurations inside ioam6_parser.c and always #
127 # reflect the same. #
129 ################################################################################
135 0xffffffff # Ingress Wide ID
137 101101 # Egress Wide ID
138 0xdeadbee0 # Namespace Data
139 0xcafec0caf00dc0de # Namespace Wide Data
140 777 # Schema ID (0xffffff = None)
141 "something that will be 4n-aligned" # Schema Data
190 ################################################################################
194 ################################################################################
196 check_kernel_compatibility()
198 ip netns add ioam-tmp-node
199 ip link add name veth0 netns ioam-tmp-node type veth \
200 peer name veth1 netns ioam-tmp-node
202 ip -netns ioam-tmp-node link set veth0 up
203 ip -netns ioam-tmp-node link set veth1 up
205 ip -netns ioam-tmp-node ioam namespace add 0
208 ip -netns ioam-tmp-node ioam namespace show | grep -q "namespace 0"
211 if [[ $ns_ad != 0 || $ns_sh != 0 ]]
213 echo "SKIP: kernel version probably too old, missing ioam support"
214 ip link del veth0 2>/dev/null || true
215 ip netns del ioam-tmp-node || true
219 ip -netns ioam-tmp-node route add db02::/64 encap ioam6 mode inline \
220 trace prealloc type 0x800000 ns 0 size 4 dev veth0
223 ip -netns ioam-tmp-node -6 route | grep -q "encap ioam6"
226 if [[ $tr_ad != 0 || $tr_sh != 0 ]]
228 echo "SKIP: cannot attach an ioam trace to a route, did you compile" \
229 "without CONFIG_IPV6_IOAM6_LWTUNNEL?"
230 ip link del veth0 2>/dev/null || true
231 ip netns del ioam-tmp-node || true
235 ip link del veth0 2>/dev/null || true
236 ip netns del ioam-tmp-node || true
238 lsmod | grep -q "ip6_tunnel"
241 if [ $ip6tnl_loaded = 0 ]
245 modprobe ip6_tunnel &>/dev/null
246 lsmod | grep -q "ip6_tunnel"
249 if [ $encap_tests != 0 ]
251 ip a | grep -q "ip6tnl0"
254 if [ $encap_tests != 0 ]
256 echo "Note: ip6_tunnel not found neither as a module nor inside the" \
257 "kernel, tests that require it (encap mode) will be omitted"
265 ip link del ioam-veth-alpha 2>/dev/null || true
266 ip link del ioam-veth-gamma 2>/dev/null || true
268 ip netns del ioam-node-alpha || true
269 ip netns del ioam-node-beta || true
270 ip netns del ioam-node-gamma || true
272 if [ $ip6tnl_loaded != 0 ]
274 modprobe -r ip6_tunnel 2>/dev/null || true
280 ip netns add ioam-node-alpha
281 ip netns add ioam-node-beta
282 ip netns add ioam-node-gamma
284 ip link add name ioam-veth-alpha netns ioam-node-alpha type veth \
285 peer name ioam-veth-betaL netns ioam-node-beta
286 ip link add name ioam-veth-betaR netns ioam-node-beta type veth \
287 peer name ioam-veth-gamma netns ioam-node-gamma
289 ip -netns ioam-node-alpha link set ioam-veth-alpha name veth0
290 ip -netns ioam-node-beta link set ioam-veth-betaL name veth0
291 ip -netns ioam-node-beta link set ioam-veth-betaR name veth1
292 ip -netns ioam-node-gamma link set ioam-veth-gamma name veth0
294 ip -netns ioam-node-alpha addr add db01::2/64 dev veth0
295 ip -netns ioam-node-alpha link set veth0 up
296 ip -netns ioam-node-alpha link set lo up
297 ip -netns ioam-node-alpha route add db02::/64 via db01::1 dev veth0
298 ip -netns ioam-node-alpha route del db01::/64
299 ip -netns ioam-node-alpha route add db01::/64 dev veth0
301 ip -netns ioam-node-beta addr add db01::1/64 dev veth0
302 ip -netns ioam-node-beta addr add db02::1/64 dev veth1
303 ip -netns ioam-node-beta link set veth0 up
304 ip -netns ioam-node-beta link set veth1 up
305 ip -netns ioam-node-beta link set lo up
307 ip -netns ioam-node-gamma addr add db02::2/64 dev veth0
308 ip -netns ioam-node-gamma link set veth0 up
309 ip -netns ioam-node-gamma link set lo up
310 ip -netns ioam-node-gamma route add db01::/64 via db02::1 dev veth0
313 ip netns exec ioam-node-alpha sysctl -wq net.ipv6.ioam6_id=${ALPHA[0]}
314 ip netns exec ioam-node-alpha sysctl -wq net.ipv6.ioam6_id_wide=${ALPHA[1]}
315 ip netns exec ioam-node-alpha sysctl -wq net.ipv6.conf.veth0.ioam6_id=${ALPHA[4]}
316 ip netns exec ioam-node-alpha sysctl -wq net.ipv6.conf.veth0.ioam6_id_wide=${ALPHA[5]}
317 ip -netns ioam-node-alpha ioam namespace add 123 data ${ALPHA[6]} wide ${ALPHA[7]}
318 ip -netns ioam-node-alpha ioam schema add ${ALPHA[8]} "${ALPHA[9]}"
319 ip -netns ioam-node-alpha ioam namespace set 123 schema ${ALPHA[8]}
321 ip netns exec ioam-node-beta sysctl -wq net.ipv6.conf.all.forwarding=1
322 ip netns exec ioam-node-beta sysctl -wq net.ipv6.ioam6_id=${BETA[0]}
323 ip netns exec ioam-node-beta sysctl -wq net.ipv6.ioam6_id_wide=${BETA[1]}
324 ip netns exec ioam-node-beta sysctl -wq net.ipv6.conf.veth0.ioam6_enabled=1
325 ip netns exec ioam-node-beta sysctl -wq net.ipv6.conf.veth0.ioam6_id=${BETA[2]}
326 ip netns exec ioam-node-beta sysctl -wq net.ipv6.conf.veth0.ioam6_id_wide=${BETA[3]}
327 ip netns exec ioam-node-beta sysctl -wq net.ipv6.conf.veth1.ioam6_id=${BETA[4]}
328 ip netns exec ioam-node-beta sysctl -wq net.ipv6.conf.veth1.ioam6_id_wide=${BETA[5]}
329 ip -netns ioam-node-beta ioam namespace add 123 data ${BETA[6]} wide ${BETA[7]}
330 ip -netns ioam-node-beta ioam schema add ${BETA[8]} "${BETA[9]}"
331 ip -netns ioam-node-beta ioam namespace set 123 schema ${BETA[8]}
333 ip netns exec ioam-node-gamma sysctl -wq net.ipv6.ioam6_id=${GAMMA[0]}
334 ip netns exec ioam-node-gamma sysctl -wq net.ipv6.ioam6_id_wide=${GAMMA[1]}
335 ip netns exec ioam-node-gamma sysctl -wq net.ipv6.conf.veth0.ioam6_enabled=1
336 ip netns exec ioam-node-gamma sysctl -wq net.ipv6.conf.veth0.ioam6_id=${GAMMA[2]}
337 ip netns exec ioam-node-gamma sysctl -wq net.ipv6.conf.veth0.ioam6_id_wide=${GAMMA[3]}
338 ip -netns ioam-node-gamma ioam namespace add 123 data ${GAMMA[6]} wide ${GAMMA[7]}
342 ip netns exec ioam-node-alpha ping6 -c 5 -W 1 db02::2 &>/dev/null
354 printf "TEST: %-60s [ OK ]\n" "${desc}"
360 printf "TEST: %-60s [FAIL]\n" "${desc}"
365 echo "- Tests passed: ${npassed}"
366 echo "- Tests failed: ${nfailed}"
381 ip netns exec $node_dst ./ioam6_parser $if_dst $name $ip6_src $ip6_dst \
382 $trace_type $ioam_ns &
386 ip netns exec $node_src ping6 -t 64 -c 1 -W 1 $ip6_dst &>/dev/null
389 nfailed=$((nfailed+1))
390 log_test_failed "${desc}"
391 kill -2 $spid &>/dev/null
396 npassed=$((npassed+1))
397 log_test_passed "${desc}"
399 nfailed=$((nfailed+1))
400 log_test_failed "${desc}"
408 printf "%0.s-" {1..74}
411 printf "%0.s-" {1..74}
414 # set OUTPUT settings
415 ip netns exec ioam-node-beta sysctl -wq net.ipv6.conf.veth0.ioam6_enabled=0
417 for t in $TESTS_OUTPUT
420 [ $encap_tests = 0 ] && $t "encap"
423 # clean OUTPUT settings
424 ip netns exec ioam-node-beta sysctl -wq net.ipv6.conf.veth0.ioam6_enabled=1
425 ip -netns ioam-node-alpha route change db01::/64 dev veth0
429 printf "%0.s-" {1..74}
432 printf "%0.s-" {1..74}
436 ip -netns ioam-node-alpha ioam namespace del 123
438 for t in $TESTS_INPUT
441 [ $encap_tests = 0 ] && $t "encap"
444 # clean INPUT settings
445 ip -netns ioam-node-alpha ioam namespace add 123 \
446 data ${ALPHA[6]} wide ${ALPHA[7]}
447 ip -netns ioam-node-alpha ioam namespace set 123 schema ${ALPHA[8]}
448 ip -netns ioam-node-alpha route change db01::/64 dev veth0
451 printf "%0.s-" {1..74}
454 printf "%0.s-" {1..74}
457 for t in $TESTS_GLOBAL
460 [ $encap_tests = 0 ] && $t "encap"
468 0x800000 0x400000 0x200000 0x100000 0x080000 0x040000 0x020000 0x010000
469 0x008000 0x004000 0x002000 0x001000 0x000800 0x000400 0x000200 0x000100
470 0x000080 0x000040 0x000020 0x000010 0x000008 0x000004 0x000002
472 bit2size=( 4 4 4 4 4 4 4 4 8 8 8 4 4 4 4 4 4 4 4 4 4 4 4 )
475 ################################################################################
479 # Two nodes (sender/receiver), IOAM disabled on ingress for the receiver. #
480 ################################################################################
484 ##############################################################################
485 # Make sure that the encap node won't fill the trace if the chosen IOAM #
486 # namespace is not configured locally. #
487 ##############################################################################
488 local desc="Unknown IOAM namespace"
490 [ "$1" = "encap" ] && mode="$1 tundst db01::1" || mode="$1"
491 [ "$1" = "encap" ] && ip -netns ioam-node-beta link set ip6tnl0 up
493 ip -netns ioam-node-alpha route change db01::/64 encap ioam6 mode $mode \
494 trace prealloc type 0x800000 ns 0 size 4 dev veth0
496 run_test ${FUNCNAME[0]} "${desc} ($1 mode)" ioam-node-alpha ioam-node-beta \
497 db01::2 db01::1 veth0 0x800000 0
499 [ "$1" = "encap" ] && ip -netns ioam-node-beta link set ip6tnl0 down
504 ##############################################################################
505 # Make sure that the encap node won't fill the trace and will set the #
506 # Overflow flag since there is no room enough for its data. #
507 ##############################################################################
508 local desc="Missing trace room"
510 [ "$1" = "encap" ] && mode="$1 tundst db01::1" || mode="$1"
511 [ "$1" = "encap" ] && ip -netns ioam-node-beta link set ip6tnl0 up
513 ip -netns ioam-node-alpha route change db01::/64 encap ioam6 mode $mode \
514 trace prealloc type 0xc00000 ns 123 size 4 dev veth0
516 run_test ${FUNCNAME[0]} "${desc} ($1 mode)" ioam-node-alpha ioam-node-beta \
517 db01::2 db01::1 veth0 0xc00000 123
519 [ "$1" = "encap" ] && ip -netns ioam-node-beta link set ip6tnl0 down
524 ##############################################################################
525 # Make sure that, for each trace type bit, the encap node will either: #
526 # (i) fill the trace with its data when it is a supported bit #
527 # (ii) not fill the trace with its data when it is an unsupported bit #
528 ##############################################################################
529 local desc="Trace type with bit <n> only"
531 local tmp=${bit2size[22]}
532 bit2size[22]=$(( $tmp + ${#ALPHA[9]} + ((4 - (${#ALPHA[9]} % 4)) % 4) ))
534 [ "$1" = "encap" ] && mode="$1 tundst db01::1" || mode="$1"
535 [ "$1" = "encap" ] && ip -netns ioam-node-beta link set ip6tnl0 up
539 ip -netns ioam-node-alpha route change db01::/64 encap ioam6 mode $mode \
540 trace prealloc type ${bit2type[$i]} ns 123 size ${bit2size[$i]} \
541 dev veth0 &>/dev/null
544 local descr="${desc/<n>/$i}"
546 if [[ $i -ge 12 && $i -le 21 ]]
550 npassed=$((npassed+1))
551 log_test_passed "$descr"
553 nfailed=$((nfailed+1))
554 log_test_failed "$descr"
557 run_test "out_bit$i" "$descr ($1 mode)" ioam-node-alpha \
558 ioam-node-beta db01::2 db01::1 veth0 ${bit2type[$i]} 123
562 [ "$1" = "encap" ] && ip -netns ioam-node-beta link set ip6tnl0 down
567 out_full_supp_trace()
569 ##############################################################################
570 # Make sure that the encap node will correctly fill a full trace. Be careful,#
571 # "full trace" here does NOT mean all bits (only supported ones). #
572 ##############################################################################
573 local desc="Full supported trace"
575 [ "$1" = "encap" ] && mode="$1 tundst db01::1" || mode="$1"
576 [ "$1" = "encap" ] && ip -netns ioam-node-beta link set ip6tnl0 up
578 ip -netns ioam-node-alpha route change db01::/64 encap ioam6 mode $mode \
579 trace prealloc type 0xfff002 ns 123 size 100 dev veth0
581 run_test ${FUNCNAME[0]} "${desc} ($1 mode)" ioam-node-alpha ioam-node-beta \
582 db01::2 db01::1 veth0 0xfff002 123
584 [ "$1" = "encap" ] && ip -netns ioam-node-beta link set ip6tnl0 down
588 ################################################################################
592 # Two nodes (sender/receiver), the sender MUST NOT fill the trace upon #
593 # insertion -> the IOAM namespace configured on the sender is removed #
594 # and is used in the inserted trace to force the sender not to fill it. #
595 ################################################################################
599 ##############################################################################
600 # Make sure that the receiving node won't fill the trace if the related IOAM #
601 # namespace is not configured locally. #
602 ##############################################################################
603 local desc="Unknown IOAM namespace"
605 [ "$1" = "encap" ] && mode="$1 tundst db01::1" || mode="$1"
606 [ "$1" = "encap" ] && ip -netns ioam-node-beta link set ip6tnl0 up
608 ip -netns ioam-node-alpha route change db01::/64 encap ioam6 mode $mode \
609 trace prealloc type 0x800000 ns 0 size 4 dev veth0
611 run_test ${FUNCNAME[0]} "${desc} ($1 mode)" ioam-node-alpha ioam-node-beta \
612 db01::2 db01::1 veth0 0x800000 0
614 [ "$1" = "encap" ] && ip -netns ioam-node-beta link set ip6tnl0 down
619 ##############################################################################
620 # Make sure that the receiving node won't fill the trace and will set the #
621 # Overflow flag if there is no room enough for its data. #
622 ##############################################################################
623 local desc="Missing trace room"
625 [ "$1" = "encap" ] && mode="$1 tundst db01::1" || mode="$1"
626 [ "$1" = "encap" ] && ip -netns ioam-node-beta link set ip6tnl0 up
628 ip -netns ioam-node-alpha route change db01::/64 encap ioam6 mode $mode \
629 trace prealloc type 0xc00000 ns 123 size 4 dev veth0
631 run_test ${FUNCNAME[0]} "${desc} ($1 mode)" ioam-node-alpha ioam-node-beta \
632 db01::2 db01::1 veth0 0xc00000 123
634 [ "$1" = "encap" ] && ip -netns ioam-node-beta link set ip6tnl0 down
639 ##############################################################################
640 # Make sure that, for each trace type bit, the receiving node will either: #
641 # (i) fill the trace with its data when it is a supported bit #
642 # (ii) not fill the trace with its data when it is an unsupported bit #
643 ##############################################################################
644 local desc="Trace type with bit <n> only"
646 local tmp=${bit2size[22]}
647 bit2size[22]=$(( $tmp + ${#BETA[9]} + ((4 - (${#BETA[9]} % 4)) % 4) ))
649 [ "$1" = "encap" ] && mode="$1 tundst db01::1" || mode="$1"
650 [ "$1" = "encap" ] && ip -netns ioam-node-beta link set ip6tnl0 up
652 for i in {0..11} {22..22}
654 ip -netns ioam-node-alpha route change db01::/64 encap ioam6 mode $mode \
655 trace prealloc type ${bit2type[$i]} ns 123 size ${bit2size[$i]} \
658 run_test "in_bit$i" "${desc/<n>/$i} ($1 mode)" ioam-node-alpha \
659 ioam-node-beta db01::2 db01::1 veth0 ${bit2type[$i]} 123
662 [ "$1" = "encap" ] && ip -netns ioam-node-beta link set ip6tnl0 down
669 ##############################################################################
670 # Make sure that the receiving node won't fill the trace since the Overflow #
672 ##############################################################################
673 local desc="Overflow flag is set"
676 # Here, we need the sender to set the Overflow flag. For that, we will add
677 # back the IOAM namespace that was previously configured on the sender.
678 ip -netns ioam-node-alpha ioam namespace add 123
680 [ "$1" = "encap" ] && mode="$1 tundst db01::1" || mode="$1"
681 [ "$1" = "encap" ] && ip -netns ioam-node-beta link set ip6tnl0 up
683 ip -netns ioam-node-alpha route change db01::/64 encap ioam6 mode $mode \
684 trace prealloc type 0xc00000 ns 123 size 4 dev veth0
686 run_test ${FUNCNAME[0]} "${desc} ($1 mode)" ioam-node-alpha ioam-node-beta \
687 db01::2 db01::1 veth0 0xc00000 123
689 [ "$1" = "encap" ] && ip -netns ioam-node-beta link set ip6tnl0 down
691 # And we clean the exception for this test to get things back to normal for
693 ip -netns ioam-node-alpha ioam namespace del 123
698 ##############################################################################
699 # Make sure that the receiving node will correctly fill a full trace. Be #
700 # careful, "full trace" here does NOT mean all bits (only supported ones). #
701 ##############################################################################
702 local desc="Full supported trace"
704 [ "$1" = "encap" ] && mode="$1 tundst db01::1" || mode="$1"
705 [ "$1" = "encap" ] && ip -netns ioam-node-beta link set ip6tnl0 up
707 ip -netns ioam-node-alpha route change db01::/64 encap ioam6 mode $mode \
708 trace prealloc type 0xfff002 ns 123 size 80 dev veth0
710 run_test ${FUNCNAME[0]} "${desc} ($1 mode)" ioam-node-alpha ioam-node-beta \
711 db01::2 db01::1 veth0 0xfff002 123
713 [ "$1" = "encap" ] && ip -netns ioam-node-beta link set ip6tnl0 down
717 ################################################################################
721 # Three nodes (sender/router/receiver), IOAM fully enabled on every node. #
722 ################################################################################
724 fwd_full_supp_trace()
726 ##############################################################################
727 # Make sure that all three nodes correctly filled the full supported trace #
728 # by checking that the trace data is consistent with the predefined config. #
729 ##############################################################################
730 local desc="Forward - Full supported trace"
732 [ "$1" = "encap" ] && mode="$1 tundst db02::2" || mode="$1"
733 [ "$1" = "encap" ] && ip -netns ioam-node-gamma link set ip6tnl0 up
735 ip -netns ioam-node-alpha route change db02::/64 encap ioam6 mode $mode \
736 trace prealloc type 0xfff002 ns 123 size 244 via db01::1 dev veth0
738 run_test ${FUNCNAME[0]} "${desc} ($1 mode)" ioam-node-alpha ioam-node-gamma \
739 db01::2 db02::2 veth0 0xfff002 123
741 [ "$1" = "encap" ] && ip -netns ioam-node-gamma link set ip6tnl0 down
745 ################################################################################
749 ################################################################################
754 if [ "$(id -u)" -ne 0 ]
756 echo "SKIP: Need root privileges"
760 if [ ! -x "$(command -v ip)" ]
762 echo "SKIP: Could not run test without ip tool"
769 echo "SKIP: iproute2 too old, missing ioam command"
773 check_kernel_compatibility