2 # SPDX-License-Identifier: GPL-2.0+
4 # Author: Justin Iurman <justin.iurman@uliege.be>
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 the 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 # +-----------------------------------------------------------+
121 ################################################################################
123 # WARNING: Be careful if you modify the block below - it MUST be kept #
124 # synchronized with configurations inside ioam6_parser.c and always #
125 # reflect the same. #
127 ################################################################################
133 0xffffffff # Ingress Wide ID
135 101101 # Egress Wide ID
136 0xdeadbee0 # Namespace Data
137 0xcafec0caf00dc0de # Namespace Wide Data
138 777 # Schema ID (0xffffff = None)
139 "something that will be 4n-aligned" # Schema Data
188 ################################################################################
192 ################################################################################
194 check_kernel_compatibility()
196 ip netns add ioam-tmp-node
197 ip link add name veth0 netns ioam-tmp-node type veth \
198 peer name veth1 netns ioam-tmp-node
200 ip -netns ioam-tmp-node link set veth0 up
201 ip -netns ioam-tmp-node link set veth1 up
203 ip -netns ioam-tmp-node ioam namespace add 0 &>/dev/null
206 ip -netns ioam-tmp-node ioam namespace show | grep -q "namespace 0"
209 if [[ $ns_ad != 0 || $ns_sh != 0 ]]
211 echo "SKIP: kernel version probably too old, missing ioam support"
212 ip link del veth0 2>/dev/null || true
213 ip netns del ioam-tmp-node || true
217 ip -netns ioam-tmp-node route add db02::/64 encap ioam6 trace prealloc \
218 type 0x800000 ns 0 size 4 dev veth0 &>/dev/null
221 ip -netns ioam-tmp-node -6 route | grep -q "encap ioam6 trace"
224 if [[ $tr_ad != 0 || $tr_sh != 0 ]]
226 echo "SKIP: cannot attach an ioam trace to a route, did you compile" \
227 "without CONFIG_IPV6_IOAM6_LWTUNNEL?"
228 ip link del veth0 2>/dev/null || true
229 ip netns del ioam-tmp-node || true
233 ip link del veth0 2>/dev/null || true
234 ip netns del ioam-tmp-node || true
239 ip link del ioam-veth-alpha 2>/dev/null || true
240 ip link del ioam-veth-gamma 2>/dev/null || true
242 ip netns del ioam-node-alpha || true
243 ip netns del ioam-node-beta || true
244 ip netns del ioam-node-gamma || true
249 ip netns add ioam-node-alpha
250 ip netns add ioam-node-beta
251 ip netns add ioam-node-gamma
253 ip link add name ioam-veth-alpha netns ioam-node-alpha type veth \
254 peer name ioam-veth-betaL netns ioam-node-beta
255 ip link add name ioam-veth-betaR netns ioam-node-beta type veth \
256 peer name ioam-veth-gamma netns ioam-node-gamma
258 ip -netns ioam-node-alpha link set ioam-veth-alpha name veth0
259 ip -netns ioam-node-beta link set ioam-veth-betaL name veth0
260 ip -netns ioam-node-beta link set ioam-veth-betaR name veth1
261 ip -netns ioam-node-gamma link set ioam-veth-gamma name veth0
263 ip -netns ioam-node-alpha addr add db01::2/64 dev veth0
264 ip -netns ioam-node-alpha link set veth0 up
265 ip -netns ioam-node-alpha link set lo up
266 ip -netns ioam-node-alpha route add db02::/64 via db01::1 dev veth0
267 ip -netns ioam-node-alpha route del db01::/64
268 ip -netns ioam-node-alpha route add db01::/64 dev veth0
270 ip -netns ioam-node-beta addr add db01::1/64 dev veth0
271 ip -netns ioam-node-beta addr add db02::1/64 dev veth1
272 ip -netns ioam-node-beta link set veth0 up
273 ip -netns ioam-node-beta link set veth1 up
274 ip -netns ioam-node-beta link set lo up
276 ip -netns ioam-node-gamma addr add db02::2/64 dev veth0
277 ip -netns ioam-node-gamma link set veth0 up
278 ip -netns ioam-node-gamma link set lo up
279 ip -netns ioam-node-gamma route add db01::/64 via db02::1 dev veth0
282 ip netns exec ioam-node-alpha sysctl -wq net.ipv6.ioam6_id=${ALPHA[0]}
283 ip netns exec ioam-node-alpha sysctl -wq net.ipv6.ioam6_id_wide=${ALPHA[1]}
284 ip netns exec ioam-node-alpha sysctl -wq net.ipv6.conf.veth0.ioam6_id=${ALPHA[4]}
285 ip netns exec ioam-node-alpha sysctl -wq net.ipv6.conf.veth0.ioam6_id_wide=${ALPHA[5]}
286 ip -netns ioam-node-alpha ioam namespace add 123 data ${ALPHA[6]} wide ${ALPHA[7]}
287 ip -netns ioam-node-alpha ioam schema add ${ALPHA[8]} "${ALPHA[9]}"
288 ip -netns ioam-node-alpha ioam namespace set 123 schema ${ALPHA[8]}
290 ip netns exec ioam-node-beta sysctl -wq net.ipv6.conf.all.forwarding=1
291 ip netns exec ioam-node-beta sysctl -wq net.ipv6.ioam6_id=${BETA[0]}
292 ip netns exec ioam-node-beta sysctl -wq net.ipv6.ioam6_id_wide=${BETA[1]}
293 ip netns exec ioam-node-beta sysctl -wq net.ipv6.conf.veth0.ioam6_enabled=1
294 ip netns exec ioam-node-beta sysctl -wq net.ipv6.conf.veth0.ioam6_id=${BETA[2]}
295 ip netns exec ioam-node-beta sysctl -wq net.ipv6.conf.veth0.ioam6_id_wide=${BETA[3]}
296 ip netns exec ioam-node-beta sysctl -wq net.ipv6.conf.veth1.ioam6_id=${BETA[4]}
297 ip netns exec ioam-node-beta sysctl -wq net.ipv6.conf.veth1.ioam6_id_wide=${BETA[5]}
298 ip -netns ioam-node-beta ioam namespace add 123 data ${BETA[6]} wide ${BETA[7]}
299 ip -netns ioam-node-beta ioam schema add ${BETA[8]} "${BETA[9]}"
300 ip -netns ioam-node-beta ioam namespace set 123 schema ${BETA[8]}
302 ip netns exec ioam-node-gamma sysctl -wq net.ipv6.ioam6_id=${GAMMA[0]}
303 ip netns exec ioam-node-gamma sysctl -wq net.ipv6.ioam6_id_wide=${GAMMA[1]}
304 ip netns exec ioam-node-gamma sysctl -wq net.ipv6.conf.veth0.ioam6_enabled=1
305 ip netns exec ioam-node-gamma sysctl -wq net.ipv6.conf.veth0.ioam6_id=${GAMMA[2]}
306 ip netns exec ioam-node-gamma sysctl -wq net.ipv6.conf.veth0.ioam6_id_wide=${GAMMA[3]}
307 ip -netns ioam-node-gamma ioam namespace add 123 data ${GAMMA[6]} wide ${GAMMA[7]}
311 ip netns exec ioam-node-alpha ping6 -c 5 -W 1 db02::2 &>/dev/null
323 printf "TEST: %-60s [ OK ]\n" "${desc}"
329 printf "TEST: %-60s [FAIL]\n" "${desc}"
344 ip netns exec $node_dst ./ioam6_parser $if_dst $name $ip6_src $ip6_dst \
345 $trace_type $ioam_ns &
349 ip netns exec $node_src ping6 -t 64 -c 1 -W 1 $ip6_dst &>/dev/null
352 log_test_failed "${desc}"
353 kill -2 $spid &>/dev/null
356 [ $? = 0 ] && log_test_passed "${desc}" || log_test_failed "${desc}"
364 printf "%0.s-" {1..74}
367 # set OUTPUT settings
368 ip netns exec ioam-node-beta sysctl -wq net.ipv6.conf.veth0.ioam6_enabled=0
370 for t in $TESTS_OUTPUT
375 # clean OUTPUT settings
376 ip netns exec ioam-node-beta sysctl -wq net.ipv6.conf.veth0.ioam6_enabled=1
377 ip -netns ioam-node-alpha route change db01::/64 dev veth0
382 printf "%0.s-" {1..74}
386 ip -netns ioam-node-alpha ioam namespace del 123
388 for t in $TESTS_INPUT
393 # clean INPUT settings
394 ip -netns ioam-node-alpha ioam namespace add 123 \
395 data ${ALPHA[6]} wide ${ALPHA[7]}
396 ip -netns ioam-node-alpha ioam namespace set 123 schema ${ALPHA[8]}
397 ip -netns ioam-node-alpha route change db01::/64 dev veth0
402 printf "%0.s-" {1..74}
405 for t in $TESTS_GLOBAL
412 0x800000 0x400000 0x200000 0x100000 0x080000 0x040000 0x020000 0x010000
413 0x008000 0x004000 0x002000 0x001000 0x000800 0x000400 0x000200 0x000100
414 0x000080 0x000040 0x000020 0x000010 0x000008 0x000004 0x000002
416 bit2size=( 4 4 4 4 4 4 4 4 8 8 8 4 4 4 4 4 4 4 4 4 4 4 4 )
419 ################################################################################
423 # Two nodes (sender/receiver), IOAM disabled on ingress for the receiver. #
424 ################################################################################
428 ##############################################################################
429 # Make sure that the encap node won't fill the trace if the chosen IOAM #
430 # namespace is not configured locally. #
431 ##############################################################################
432 local desc="Unknown IOAM namespace"
434 ip -netns ioam-node-alpha route change db01::/64 encap ioam6 trace prealloc \
435 type 0x800000 ns 0 size 4 dev veth0
437 run_test ${FUNCNAME[0]} "${desc}" ioam-node-alpha ioam-node-beta db01::2 \
438 db01::1 veth0 0x800000 0
443 ##############################################################################
444 # Make sure that the encap node won't fill the trace and will set the #
445 # Overflow flag since there is no room enough for its data. #
446 ##############################################################################
447 local desc="Missing trace room"
449 ip -netns ioam-node-alpha route change db01::/64 encap ioam6 trace prealloc \
450 type 0xc00000 ns 123 size 4 dev veth0
452 run_test ${FUNCNAME[0]} "${desc}" ioam-node-alpha ioam-node-beta db01::2 \
453 db01::1 veth0 0xc00000 123
458 ##############################################################################
459 # Make sure that, for each trace type bit, the encap node will either: #
460 # (i) fill the trace with its data when it is a supported bit #
461 # (ii) not fill the trace with its data when it is an unsupported bit #
462 ##############################################################################
463 local desc="Trace type with bit <n> only"
465 local tmp=${bit2size[22]}
466 bit2size[22]=$(( $tmp + ${#ALPHA[9]} + ((4 - (${#ALPHA[9]} % 4)) % 4) ))
470 ip -netns ioam-node-alpha route change db01::/64 encap ioam6 trace \
471 prealloc type ${bit2type[$i]} ns 123 size ${bit2size[$i]} \
472 dev veth0 &>/dev/null
475 local descr="${desc/<n>/$i}"
477 if [[ $i -ge 12 && $i -le 21 ]]
481 npassed=$((npassed+1))
482 log_test_passed "$descr"
484 nfailed=$((nfailed+1))
485 log_test_failed "$descr"
488 run_test "out_bit$i" "$descr" ioam-node-alpha ioam-node-beta \
489 db01::2 db01::1 veth0 ${bit2type[$i]} 123
496 out_full_supp_trace()
498 ##############################################################################
499 # Make sure that the encap node will correctly fill a full trace. Be careful,#
500 # "full trace" here does NOT mean all bits (only supported ones). #
501 ##############################################################################
502 local desc="Full supported trace"
504 ip -netns ioam-node-alpha route change db01::/64 encap ioam6 trace prealloc \
505 type 0xfff002 ns 123 size 100 dev veth0
507 run_test ${FUNCNAME[0]} "${desc}" ioam-node-alpha ioam-node-beta db01::2 \
508 db01::1 veth0 0xfff002 123
512 ################################################################################
516 # Two nodes (sender/receiver), the sender MUST NOT fill the trace upon #
517 # insertion -> the IOAM namespace configured on the sender is removed #
518 # and is used in the inserted trace to force the sender not to fill it. #
519 ################################################################################
523 ##############################################################################
524 # Make sure that the receiving node won't fill the trace if the related IOAM #
525 # namespace is not configured locally. #
526 ##############################################################################
527 local desc="Unknown IOAM namespace"
529 ip -netns ioam-node-alpha route change db01::/64 encap ioam6 trace prealloc \
530 type 0x800000 ns 0 size 4 dev veth0
532 run_test ${FUNCNAME[0]} "${desc}" ioam-node-alpha ioam-node-beta db01::2 \
533 db01::1 veth0 0x800000 0
538 ##############################################################################
539 # Make sure that the receiving node won't fill the trace and will set the #
540 # Overflow flag if there is no room enough for its data. #
541 ##############################################################################
542 local desc="Missing trace room"
544 ip -netns ioam-node-alpha route change db01::/64 encap ioam6 trace prealloc \
545 type 0xc00000 ns 123 size 4 dev veth0
547 run_test ${FUNCNAME[0]} "${desc}" ioam-node-alpha ioam-node-beta db01::2 \
548 db01::1 veth0 0xc00000 123
553 ##############################################################################
554 # Make sure that, for each trace type bit, the receiving node will either: #
555 # (i) fill the trace with its data when it is a supported bit #
556 # (ii) not fill the trace with its data when it is an unsupported bit #
557 ##############################################################################
558 local desc="Trace type with bit <n> only"
560 local tmp=${bit2size[22]}
561 bit2size[22]=$(( $tmp + ${#BETA[9]} + ((4 - (${#BETA[9]} % 4)) % 4) ))
563 for i in {0..11} {22..22}
565 ip -netns ioam-node-alpha route change db01::/64 encap ioam6 trace \
566 prealloc type ${bit2type[$i]} ns 123 size ${bit2size[$i]} dev veth0
568 run_test "in_bit$i" "${desc/<n>/$i}" ioam-node-alpha ioam-node-beta \
569 db01::2 db01::1 veth0 ${bit2type[$i]} 123
577 ##############################################################################
578 # Make sure that the receiving node won't fill the trace since the Overflow #
580 ##############################################################################
581 local desc="Overflow flag is set"
584 # Here, we need the sender to set the Overflow flag. For that, we will add
585 # back the IOAM namespace that was previously configured on the sender.
586 ip -netns ioam-node-alpha ioam namespace add 123
588 ip -netns ioam-node-alpha route change db01::/64 encap ioam6 trace prealloc \
589 type 0xc00000 ns 123 size 4 dev veth0
591 run_test ${FUNCNAME[0]} "${desc}" ioam-node-alpha ioam-node-beta db01::2 \
592 db01::1 veth0 0xc00000 123
594 # And we clean the exception for this test to get things back to normal for
596 ip -netns ioam-node-alpha ioam namespace del 123
601 ##############################################################################
602 # Make sure that the receiving node will correctly fill a full trace. Be #
603 # careful, "full trace" here does NOT mean all bits (only supported ones). #
604 ##############################################################################
605 local desc="Full supported trace"
607 ip -netns ioam-node-alpha route change db01::/64 encap ioam6 trace prealloc \
608 type 0xfff002 ns 123 size 80 dev veth0
610 run_test ${FUNCNAME[0]} "${desc}" ioam-node-alpha ioam-node-beta db01::2 \
611 db01::1 veth0 0xfff002 123
615 ################################################################################
619 # Three nodes (sender/router/receiver), IOAM fully enabled on every node. #
620 ################################################################################
622 fwd_full_supp_trace()
624 ##############################################################################
625 # Make sure that all three nodes correctly filled the full supported trace #
626 # by checking that the trace data is consistent with the predefined config. #
627 ##############################################################################
628 local desc="Forward - Full supported trace"
630 ip -netns ioam-node-alpha route change db02::/64 encap ioam6 trace prealloc \
631 type 0xfff002 ns 123 size 244 via db01::1 dev veth0
633 run_test ${FUNCNAME[0]} "${desc}" ioam-node-alpha ioam-node-gamma db01::2 \
634 db02::2 veth0 0xfff002 123
638 ################################################################################
642 ################################################################################
644 if [ "$(id -u)" -ne 0 ]
646 echo "SKIP: Need root privileges"
650 if [ ! -x "$(command -v ip)" ]
652 echo "SKIP: Could not run test without ip tool"
659 echo "SKIP: iproute2 too old, missing ioam command"
663 check_kernel_compatibility