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 # +-----------------------------------------------------------+
122 ################################################################################
124 # WARNING: Be careful if you modify the block below - it MUST be kept #
125 # synchronized with configurations inside ioam6_parser.c and always #
126 # reflect the same. #
128 ################################################################################
134 0xffffffff # Ingress Wide ID
136 101101 # Egress Wide ID
137 0xdeadbee0 # Namespace Data
138 0xcafec0caf00dc0de # Namespace Wide Data
139 777 # Schema ID (0xffffff = None)
140 "something that will be 4n-aligned" # Schema Data
189 ################################################################################
193 ################################################################################
195 check_kernel_compatibility()
197 setup_ns ioam_tmp_node
198 ip link add name veth0 netns $ioam_tmp_node type veth \
199 peer name veth1 netns $ioam_tmp_node
201 ip -netns $ioam_tmp_node link set veth0 up
202 ip -netns $ioam_tmp_node link set veth1 up
204 ip -netns $ioam_tmp_node ioam namespace add 0
207 ip -netns $ioam_tmp_node ioam namespace show | grep -q "namespace 0"
210 if [[ $ns_ad != 0 || $ns_sh != 0 ]]
212 echo "SKIP: kernel version probably too old, missing ioam support"
213 ip link del veth0 2>/dev/null || true
214 cleanup_ns $ioam_tmp_node || true
218 ip -netns $ioam_tmp_node route add db02::/64 encap ioam6 mode inline \
219 trace prealloc type 0x800000 ns 0 size 4 dev veth0
222 ip -netns $ioam_tmp_node -6 route | grep -q "encap ioam6"
225 if [[ $tr_ad != 0 || $tr_sh != 0 ]]
227 echo "SKIP: cannot attach an ioam trace to a route, did you compile" \
228 "without CONFIG_IPV6_IOAM6_LWTUNNEL?"
229 ip link del veth0 2>/dev/null || true
230 cleanup_ns $ioam_tmp_node || true
234 ip link del veth0 2>/dev/null || true
235 cleanup_ns $ioam_tmp_node || true
237 lsmod | grep -q "ip6_tunnel"
240 if [ $ip6tnl_loaded = 0 ]
244 modprobe ip6_tunnel &>/dev/null
245 lsmod | grep -q "ip6_tunnel"
248 if [ $encap_tests != 0 ]
250 ip a | grep -q "ip6tnl0"
253 if [ $encap_tests != 0 ]
255 echo "Note: ip6_tunnel not found neither as a module nor inside the" \
256 "kernel, tests that require it (encap mode) will be omitted"
264 ip link del ioam-veth-alpha 2>/dev/null || true
265 ip link del ioam-veth-gamma 2>/dev/null || true
267 cleanup_ns $ioam_node_alpha $ioam_node_beta $ioam_node_gamma || true
269 if [ $ip6tnl_loaded != 0 ]
271 modprobe -r ip6_tunnel 2>/dev/null || true
277 setup_ns ioam_node_alpha ioam_node_beta ioam_node_gamma
279 ip link add name ioam-veth-alpha netns $ioam_node_alpha type veth \
280 peer name ioam-veth-betaL netns $ioam_node_beta
281 ip link add name ioam-veth-betaR netns $ioam_node_beta type veth \
282 peer name ioam-veth-gamma netns $ioam_node_gamma
284 ip -netns $ioam_node_alpha link set ioam-veth-alpha name veth0
285 ip -netns $ioam_node_beta link set ioam-veth-betaL name veth0
286 ip -netns $ioam_node_beta link set ioam-veth-betaR name veth1
287 ip -netns $ioam_node_gamma link set ioam-veth-gamma name veth0
289 ip -netns $ioam_node_alpha addr add db01::2/64 dev veth0
290 ip -netns $ioam_node_alpha link set veth0 up
291 ip -netns $ioam_node_alpha link set lo up
292 ip -netns $ioam_node_alpha route add db02::/64 via db01::1 dev veth0
293 ip -netns $ioam_node_alpha route del db01::/64
294 ip -netns $ioam_node_alpha route add db01::/64 dev veth0
296 ip -netns $ioam_node_beta addr add db01::1/64 dev veth0
297 ip -netns $ioam_node_beta addr add db02::1/64 dev veth1
298 ip -netns $ioam_node_beta link set veth0 up
299 ip -netns $ioam_node_beta link set veth1 up
300 ip -netns $ioam_node_beta link set lo up
302 ip -netns $ioam_node_gamma addr add db02::2/64 dev veth0
303 ip -netns $ioam_node_gamma link set veth0 up
304 ip -netns $ioam_node_gamma link set lo up
305 ip -netns $ioam_node_gamma route add db01::/64 via db02::1 dev veth0
308 ip netns exec $ioam_node_alpha sysctl -wq net.ipv6.ioam6_id=${ALPHA[0]}
309 ip netns exec $ioam_node_alpha sysctl -wq net.ipv6.ioam6_id_wide=${ALPHA[1]}
310 ip netns exec $ioam_node_alpha sysctl -wq net.ipv6.conf.veth0.ioam6_id=${ALPHA[4]}
311 ip netns exec $ioam_node_alpha sysctl -wq net.ipv6.conf.veth0.ioam6_id_wide=${ALPHA[5]}
312 ip -netns $ioam_node_alpha ioam namespace add 123 data ${ALPHA[6]} wide ${ALPHA[7]}
313 ip -netns $ioam_node_alpha ioam schema add ${ALPHA[8]} "${ALPHA[9]}"
314 ip -netns $ioam_node_alpha ioam namespace set 123 schema ${ALPHA[8]}
316 ip netns exec $ioam_node_beta sysctl -wq net.ipv6.conf.all.forwarding=1
317 ip netns exec $ioam_node_beta sysctl -wq net.ipv6.ioam6_id=${BETA[0]}
318 ip netns exec $ioam_node_beta sysctl -wq net.ipv6.ioam6_id_wide=${BETA[1]}
319 ip netns exec $ioam_node_beta sysctl -wq net.ipv6.conf.veth0.ioam6_enabled=1
320 ip netns exec $ioam_node_beta sysctl -wq net.ipv6.conf.veth0.ioam6_id=${BETA[2]}
321 ip netns exec $ioam_node_beta sysctl -wq net.ipv6.conf.veth0.ioam6_id_wide=${BETA[3]}
322 ip netns exec $ioam_node_beta sysctl -wq net.ipv6.conf.veth1.ioam6_id=${BETA[4]}
323 ip netns exec $ioam_node_beta sysctl -wq net.ipv6.conf.veth1.ioam6_id_wide=${BETA[5]}
324 ip -netns $ioam_node_beta ioam namespace add 123 data ${BETA[6]} wide ${BETA[7]}
325 ip -netns $ioam_node_beta ioam schema add ${BETA[8]} "${BETA[9]}"
326 ip -netns $ioam_node_beta ioam namespace set 123 schema ${BETA[8]}
328 ip netns exec $ioam_node_gamma sysctl -wq net.ipv6.ioam6_id=${GAMMA[0]}
329 ip netns exec $ioam_node_gamma sysctl -wq net.ipv6.ioam6_id_wide=${GAMMA[1]}
330 ip netns exec $ioam_node_gamma sysctl -wq net.ipv6.conf.veth0.ioam6_enabled=1
331 ip netns exec $ioam_node_gamma sysctl -wq net.ipv6.conf.veth0.ioam6_id=${GAMMA[2]}
332 ip netns exec $ioam_node_gamma sysctl -wq net.ipv6.conf.veth0.ioam6_id_wide=${GAMMA[3]}
333 ip -netns $ioam_node_gamma ioam namespace add 123 data ${GAMMA[6]} wide ${GAMMA[7]}
337 ip netns exec $ioam_node_alpha ping6 -c 5 -W 1 db02::2 &>/dev/null
349 printf "TEST: %-60s [ OK ]\n" "${desc}"
355 printf "TEST: %-60s [FAIL]\n" "${desc}"
360 echo "- Tests passed: ${npassed}"
361 echo "- Tests failed: ${nfailed}"
375 ip netns exec $node_dst ./ioam6_parser $name $trace_type $ioam_ns $type &
379 ip netns exec $node_src ping6 -t 64 -c 1 -W 1 $ip6_dst &>/dev/null
382 nfailed=$((nfailed+1))
383 log_test_failed "${desc}"
384 kill -2 $spid &>/dev/null
389 npassed=$((npassed+1))
390 log_test_passed "${desc}"
392 nfailed=$((nfailed+1))
393 log_test_failed "${desc}"
401 printf "%0.s-" {1..74}
404 printf "%0.s-" {1..74}
407 # set OUTPUT settings
408 ip netns exec $ioam_node_beta sysctl -wq net.ipv6.conf.veth0.ioam6_enabled=0
410 for t in $TESTS_OUTPUT
413 [ $encap_tests = 0 ] && $t "encap"
416 # clean OUTPUT settings
417 ip netns exec $ioam_node_beta sysctl -wq net.ipv6.conf.veth0.ioam6_enabled=1
418 ip -netns $ioam_node_alpha route change db01::/64 dev veth0
422 printf "%0.s-" {1..74}
425 printf "%0.s-" {1..74}
429 ip -netns $ioam_node_alpha ioam namespace del 123
431 for t in $TESTS_INPUT
434 [ $encap_tests = 0 ] && $t "encap"
437 # clean INPUT settings
438 ip -netns $ioam_node_alpha ioam namespace add 123 \
439 data ${ALPHA[6]} wide ${ALPHA[7]}
440 ip -netns $ioam_node_alpha ioam namespace set 123 schema ${ALPHA[8]}
441 ip -netns $ioam_node_alpha route change db01::/64 dev veth0
444 printf "%0.s-" {1..74}
447 printf "%0.s-" {1..74}
450 for t in $TESTS_GLOBAL
453 [ $encap_tests = 0 ] && $t "encap"
461 0x800000 0x400000 0x200000 0x100000 0x080000 0x040000 0x020000 0x010000
462 0x008000 0x004000 0x002000 0x001000 0x000800 0x000400 0x000200 0x000100
463 0x000080 0x000040 0x000020 0x000010 0x000008 0x000004 0x000002
465 bit2size=( 4 4 4 4 4 4 4 4 8 8 8 4 4 4 4 4 4 4 4 4 4 4 4 )
468 ################################################################################
472 # Two nodes (sender/receiver), IOAM disabled on ingress for the receiver. #
473 ################################################################################
477 ##############################################################################
478 # Make sure that the encap node won't fill the trace if the chosen IOAM #
479 # namespace is not configured locally. #
480 ##############################################################################
481 local desc="Unknown IOAM namespace"
483 [ "$1" = "encap" ] && mode="$1 tundst db01::1" || mode="$1"
484 [ "$1" = "encap" ] && ip -netns $ioam_node_beta link set ip6tnl0 up
486 ip -netns $ioam_node_alpha route change db01::/64 encap ioam6 mode $mode \
487 trace prealloc type 0x800000 ns 0 size 4 dev veth0
489 run_test ${FUNCNAME[0]} "${desc} ($1 mode)" $ioam_node_alpha $ioam_node_beta \
490 db01::1 0x800000 0 $1
492 [ "$1" = "encap" ] && ip -netns $ioam_node_beta link set ip6tnl0 down
497 ##############################################################################
498 # Make sure that the encap node won't fill the trace and will set the #
499 # Overflow flag since there is no room enough for its data. #
500 ##############################################################################
501 local desc="Missing trace room"
503 [ "$1" = "encap" ] && mode="$1 tundst db01::1" || mode="$1"
504 [ "$1" = "encap" ] && ip -netns $ioam_node_beta link set ip6tnl0 up
506 ip -netns $ioam_node_alpha route change db01::/64 encap ioam6 mode $mode \
507 trace prealloc type 0xc00000 ns 123 size 4 dev veth0
509 run_test ${FUNCNAME[0]} "${desc} ($1 mode)" $ioam_node_alpha $ioam_node_beta \
510 db01::1 0xc00000 123 $1
512 [ "$1" = "encap" ] && ip -netns $ioam_node_beta link set ip6tnl0 down
517 ##############################################################################
518 # Make sure that, for each trace type bit, the encap node will either: #
519 # (i) fill the trace with its data when it is a supported bit #
520 # (ii) not fill the trace with its data when it is an unsupported bit #
521 ##############################################################################
522 local desc="Trace type with bit <n> only"
524 local tmp=${bit2size[22]}
525 bit2size[22]=$(( $tmp + ${#ALPHA[9]} + ((4 - (${#ALPHA[9]} % 4)) % 4) ))
527 [ "$1" = "encap" ] && mode="$1 tundst db01::1" || mode="$1"
528 [ "$1" = "encap" ] && ip -netns $ioam_node_beta link set ip6tnl0 up
532 ip -netns $ioam_node_alpha route change db01::/64 encap ioam6 mode $mode \
533 trace prealloc type ${bit2type[$i]} ns 123 size ${bit2size[$i]} \
534 dev veth0 &>/dev/null
537 local descr="${desc/<n>/$i}"
539 if [[ $i -ge 12 && $i -le 21 ]]
543 npassed=$((npassed+1))
544 log_test_passed "$descr ($1 mode)"
546 nfailed=$((nfailed+1))
547 log_test_failed "$descr ($1 mode)"
550 run_test "out_bit$i" "$descr ($1 mode)" $ioam_node_alpha \
551 $ioam_node_beta db01::1 ${bit2type[$i]} 123 $1
555 [ "$1" = "encap" ] && ip -netns $ioam_node_beta link set ip6tnl0 down
560 out_full_supp_trace()
562 ##############################################################################
563 # Make sure that the encap node will correctly fill a full trace. Be careful,#
564 # "full trace" here does NOT mean all bits (only supported ones). #
565 ##############################################################################
566 local desc="Full supported trace"
568 [ "$1" = "encap" ] && mode="$1 tundst db01::1" || mode="$1"
569 [ "$1" = "encap" ] && ip -netns $ioam_node_beta link set ip6tnl0 up
571 ip -netns $ioam_node_alpha route change db01::/64 encap ioam6 mode $mode \
572 trace prealloc type 0xfff002 ns 123 size 100 dev veth0
574 run_test ${FUNCNAME[0]} "${desc} ($1 mode)" $ioam_node_alpha $ioam_node_beta \
575 db01::1 0xfff002 123 $1
577 [ "$1" = "encap" ] && ip -netns $ioam_node_beta link set ip6tnl0 down
581 ################################################################################
585 # Two nodes (sender/receiver), the sender MUST NOT fill the trace upon #
586 # insertion -> the IOAM namespace configured on the sender is removed #
587 # and is used in the inserted trace to force the sender not to fill it. #
588 ################################################################################
592 ##############################################################################
593 # Make sure that the receiving node won't fill the trace if the related IOAM #
594 # namespace is not configured locally. #
595 ##############################################################################
596 local desc="Unknown IOAM namespace"
598 [ "$1" = "encap" ] && mode="$1 tundst db01::1" || mode="$1"
599 [ "$1" = "encap" ] && ip -netns $ioam_node_beta link set ip6tnl0 up
601 ip -netns $ioam_node_alpha route change db01::/64 encap ioam6 mode $mode \
602 trace prealloc type 0x800000 ns 0 size 4 dev veth0
604 run_test ${FUNCNAME[0]} "${desc} ($1 mode)" $ioam_node_alpha $ioam_node_beta \
605 db01::1 0x800000 0 $1
607 [ "$1" = "encap" ] && ip -netns $ioam_node_beta link set ip6tnl0 down
612 ##############################################################################
613 # Make sure that the receiving node won't fill the trace and will set the #
614 # Overflow flag if there is no room enough for its data. #
615 ##############################################################################
616 local desc="Missing trace room"
618 [ "$1" = "encap" ] && mode="$1 tundst db01::1" || mode="$1"
619 [ "$1" = "encap" ] && ip -netns $ioam_node_beta link set ip6tnl0 up
621 ip -netns $ioam_node_alpha route change db01::/64 encap ioam6 mode $mode \
622 trace prealloc type 0xc00000 ns 123 size 4 dev veth0
624 run_test ${FUNCNAME[0]} "${desc} ($1 mode)" $ioam_node_alpha $ioam_node_beta \
625 db01::1 0xc00000 123 $1
627 [ "$1" = "encap" ] && ip -netns $ioam_node_beta link set ip6tnl0 down
632 ##############################################################################
633 # Make sure that, for each trace type bit, the receiving node will either: #
634 # (i) fill the trace with its data when it is a supported bit #
635 # (ii) not fill the trace with its data when it is an unsupported bit #
636 ##############################################################################
637 local desc="Trace type with bit <n> only"
639 local tmp=${bit2size[22]}
640 bit2size[22]=$(( $tmp + ${#BETA[9]} + ((4 - (${#BETA[9]} % 4)) % 4) ))
642 [ "$1" = "encap" ] && mode="$1 tundst db01::1" || mode="$1"
643 [ "$1" = "encap" ] && ip -netns $ioam_node_beta link set ip6tnl0 up
645 for i in {0..11} {22..22}
647 ip -netns $ioam_node_alpha route change db01::/64 encap ioam6 mode $mode \
648 trace prealloc type ${bit2type[$i]} ns 123 size ${bit2size[$i]} \
651 run_test "in_bit$i" "${desc/<n>/$i} ($1 mode)" $ioam_node_alpha \
652 $ioam_node_beta db01::1 ${bit2type[$i]} 123 $1
655 [ "$1" = "encap" ] && ip -netns $ioam_node_beta link set ip6tnl0 down
662 ##############################################################################
663 # Make sure that the receiving node won't fill the trace since the Overflow #
665 ##############################################################################
666 local desc="Overflow flag is set"
669 # Here, we need the sender to set the Overflow flag. For that, we will add
670 # back the IOAM namespace that was previously configured on the sender.
671 ip -netns $ioam_node_alpha ioam namespace add 123
673 [ "$1" = "encap" ] && mode="$1 tundst db01::1" || mode="$1"
674 [ "$1" = "encap" ] && ip -netns $ioam_node_beta link set ip6tnl0 up
676 ip -netns $ioam_node_alpha route change db01::/64 encap ioam6 mode $mode \
677 trace prealloc type 0xc00000 ns 123 size 4 dev veth0
679 run_test ${FUNCNAME[0]} "${desc} ($1 mode)" $ioam_node_alpha $ioam_node_beta \
680 db01::1 0xc00000 123 $1
682 [ "$1" = "encap" ] && ip -netns $ioam_node_beta link set ip6tnl0 down
684 # And we clean the exception for this test to get things back to normal for
686 ip -netns $ioam_node_alpha ioam namespace del 123
691 ##############################################################################
692 # Make sure that the receiving node will correctly fill a full trace. Be #
693 # careful, "full trace" here does NOT mean all bits (only supported ones). #
694 ##############################################################################
695 local desc="Full supported trace"
697 [ "$1" = "encap" ] && mode="$1 tundst db01::1" || mode="$1"
698 [ "$1" = "encap" ] && ip -netns $ioam_node_beta link set ip6tnl0 up
700 ip -netns $ioam_node_alpha route change db01::/64 encap ioam6 mode $mode \
701 trace prealloc type 0xfff002 ns 123 size 80 dev veth0
703 run_test ${FUNCNAME[0]} "${desc} ($1 mode)" $ioam_node_alpha $ioam_node_beta \
704 db01::1 0xfff002 123 $1
706 [ "$1" = "encap" ] && ip -netns $ioam_node_beta link set ip6tnl0 down
710 ################################################################################
714 # Three nodes (sender/router/receiver), IOAM fully enabled on every node. #
715 ################################################################################
717 fwd_full_supp_trace()
719 ##############################################################################
720 # Make sure that all three nodes correctly filled the full supported trace #
721 # by checking that the trace data is consistent with the predefined config. #
722 ##############################################################################
723 local desc="Forward - Full supported trace"
725 [ "$1" = "encap" ] && mode="$1 tundst db02::2" || mode="$1"
726 [ "$1" = "encap" ] && ip -netns $ioam_node_gamma link set ip6tnl0 up
728 ip -netns $ioam_node_alpha route change db02::/64 encap ioam6 mode $mode \
729 trace prealloc type 0xfff002 ns 123 size 244 via db01::1 dev veth0
731 run_test ${FUNCNAME[0]} "${desc} ($1 mode)" $ioam_node_alpha $ioam_node_gamma \
732 db02::2 0xfff002 123 $1
734 [ "$1" = "encap" ] && ip -netns $ioam_node_gamma link set ip6tnl0 down
738 ################################################################################
742 ################################################################################
747 if [ "$(id -u)" -ne 0 ]
749 echo "SKIP: Need root privileges"
753 if [ ! -x "$(command -v ip)" ]
755 echo "SKIP: Could not run test without ip tool"
762 echo "SKIP: iproute2 too old, missing ioam command"
766 check_kernel_compatibility