xref: /linux/tools/testing/selftests/net/ioam6.sh (revision add452d09a38c7a7c44aea55c1015392cebf9fa7)
1#!/bin/bash
2# SPDX-License-Identifier: GPL-2.0+
3#
4# Author: Justin Iurman <justin.iurman@uliege.be>
5#
6# This script evaluates IOAM for IPv6 by checking local IOAM configurations and
7# IOAM data inside packets. There are three categories of tests: LOCAL, OUTPUT,
8# and INPUT. The former (LOCAL) checks all IOAM related configurations locally
9# without sending packets. OUTPUT tests verify the processing of an IOAM
10# encapsulating node, while INPUT tests verify the processing of an IOAM transit
11# node. Both OUTPUT and INPUT tests send packets. Each test is documented inside
12# its own handler.
13#
14# The topology used for OUTPUT and INPUT tests is made of three nodes:
15# - Alpha (the IOAM encapsulating node)
16# - Beta  (the IOAM transit node)
17# - Gamma (the receiver) **
18#
19# An IOAM domain is configured from Alpha to Beta, but not on the reverse path.
20# Alpha adds an IOAM option (Pre-allocated Trace) inside a Hop-by-hop.
21#
22# ** Gamma is required because ioam6_parser.c uses a packet socket and we need
23#    to see IOAM data inserted by the very last node (Beta), which would happen
24#    _after_ we get a copy of the packet on Beta. Note that using an
25#    IPv6 raw socket with IPV6_RECVHOPOPTS on Beta would not be enough: we also
26#    need to access the IPv6 header to check some fields (e.g., source and
27#    destination addresses), which is not possible in that case. As a
28#    consequence, we need Gamma as a receiver to run ioam6_parser.c which uses a
29#    packet socket.
30#
31#
32#         +-----------------------+          +-----------------------+
33#         |                       |          |                       |
34#         |      Alpha netns      |          |      Gamma netns      |
35#         |                       |          |                       |
36#         | +-------------------+ |          | +-------------------+ |
37#         | |       veth0       | |          | |       veth0       | |
38#         | | 2001:db8:1::2/64  | |          | | 2001:db8:2::2/64  | |
39#         | +-------------------+ |          | +-------------------+ |
40#         |           .           |          |           .           |
41#         +-----------.-----------+          +-----------.-----------+
42#                     .                                  .
43#                     .                                  .
44#                     .                                  .
45#         +-----------.----------------------------------.-----------+
46#         |           .                                  .           |
47#         | +-------------------+              +-------------------+ |
48#         | |       veth0       |              |       veth1       | |
49#         | | 2001:db8:1::1/64  | ............ | 2001:db8:2::1/64  | |
50#         | +-------------------+              +-------------------+ |
51#         |                                                          |
52#         |                        Beta netns                        |
53#         |                                                          |
54#         +----------------------------------------------------------+
55#
56#
57#
58#         +==========================================================+
59#         |                Alpha - IOAM configuration                |
60#         +=====================+====================================+
61#         | Node ID             | 1                                  |
62#         +---------------------+------------------------------------+
63#         | Node Wide ID        | 11111111                           |
64#         +---------------------+------------------------------------+
65#         | Ingress ID          | 0xffff (default value)             |
66#         +---------------------+------------------------------------+
67#         | Ingress Wide ID     | 0xffffffff (default value)         |
68#         +---------------------+------------------------------------+
69#         | Egress ID           | 101                                |
70#         +---------------------+------------------------------------+
71#         | Egress Wide ID      | 101101                             |
72#         +---------------------+------------------------------------+
73#         | Namespace Data      | 0xdeadbeef                         |
74#         +---------------------+------------------------------------+
75#         | Namespace Wide Data | 0xcafec0caf00dc0de                 |
76#         +---------------------+------------------------------------+
77#         | Schema ID           | 777                                |
78#         +---------------------+------------------------------------+
79#         | Schema Data         | something that will be 4n-aligned  |
80#         +---------------------+------------------------------------+
81#
82#
83#         +==========================================================+
84#         |                 Beta - IOAM configuration                |
85#         +=====================+====================================+
86#         | Node ID             | 2                                  |
87#         +---------------------+------------------------------------+
88#         | Node Wide ID        | 22222222                           |
89#         +---------------------+------------------------------------+
90#         | Ingress ID          | 201                                |
91#         +---------------------+------------------------------------+
92#         | Ingress Wide ID     | 201201                             |
93#         +---------------------+------------------------------------+
94#         | Egress ID           | 202                                |
95#         +---------------------+------------------------------------+
96#         | Egress Wide ID      | 202202                             |
97#         +---------------------+------------------------------------+
98#         | Namespace Data      | 0xffffffff (default value)         |
99#         +---------------------+------------------------------------+
100#         | Namespace Wide Data | 0xffffffffffffffff (default value) |
101#         +---------------------+------------------------------------+
102#         | Schema ID           | 0xffffff (= None)                  |
103#         +---------------------+------------------------------------+
104#         | Schema Data         |                                    |
105#         +---------------------+------------------------------------+
106
107source lib.sh
108
109################################################################################
110#                                                                              #
111# WARNING: Be careful if you modify the block below - it MUST be kept          #
112#          synchronized with configurations inside ioam6_parser.c and always   #
113#          reflect the same.                                                   #
114#                                                                              #
115################################################################################
116
117ALPHA=(
118  1                                    # ID
119  11111111                             # Wide ID
120  0xffff                               # Ingress ID (default value)
121  0xffffffff                           # Ingress Wide ID (default value)
122  101                                  # Egress ID
123  101101                               # Egress Wide ID
124  0xdeadbeef                           # Namespace Data
125  0xcafec0caf00dc0de                   # Namespace Wide Data
126  777                                  # Schema ID
127  "something that will be 4n-aligned"  # Schema Data
128)
129
130BETA=(
131  2                                    # ID
132  22222222                             # Wide ID
133  201                                  # Ingress ID
134  201201                               # Ingress Wide ID
135  202                                  # Egress ID
136  202202                               # Egress Wide ID
137  0xffffffff                           # Namespace Data (empty value)
138  0xffffffffffffffff                   # Namespace Wide Data (empty value)
139  0xffffff                             # Schema ID (empty value)
140  ""                                   # Schema Data (empty value)
141)
142
143TESTS_LOCAL="
144  local_sysctl_ioam_id
145  local_sysctl_ioam_id_wide
146  local_sysctl_ioam_intf_id
147  local_sysctl_ioam_intf_id_wide
148  local_sysctl_ioam_intf_enabled
149  local_ioam_namespace
150  local_ioam_schema
151  local_ioam_schema_namespace
152  local_route_ns
153  local_route_tunsrc
154  local_route_tundst
155  local_route_trace_type
156  local_route_trace_size
157  local_route_trace_type_bits
158  local_route_trace_size_values
159"
160
161TESTS_OUTPUT="
162  output_undef_ns
163  output_no_room
164  output_no_room_oss
165  output_bits
166  output_sizes
167  output_full_supp_trace
168"
169
170TESTS_INPUT="
171  input_undef_ns
172  input_no_room
173  input_no_room_oss
174  input_disabled
175  input_oflag
176  input_bits
177  input_sizes
178  input_full_supp_trace
179"
180
181################################################################################
182#                                                                              #
183#                                   LIBRARY                                    #
184#                                                                              #
185################################################################################
186
187check_kernel_compatibility()
188{
189  setup_ns ioam_tmp_node &>/dev/null
190  local ret=$?
191
192  ip link add name veth0 netns $ioam_tmp_node type veth \
193    peer name veth1 netns $ioam_tmp_node &>/dev/null
194  ret=$((ret + $?))
195
196  ip -netns $ioam_tmp_node link set veth0 up &>/dev/null
197  ret=$((ret + $?))
198
199  ip -netns $ioam_tmp_node link set veth1 up &>/dev/null
200  ret=$((ret + $?))
201
202  if [ $ret != 0 ]
203  then
204    echo "SKIP: Setup failed."
205    cleanup_ns $ioam_tmp_node
206    exit $ksft_skip
207  fi
208
209  ip -netns $ioam_tmp_node route add 2001:db8:2::/64 \
210    encap ioam6 trace prealloc type 0x800000 ns 0 size 4 dev veth0 &>/dev/null
211  ret=$?
212
213  ip -netns $ioam_tmp_node -6 route 2>/dev/null | grep -q "encap ioam6"
214  ret=$((ret + $?))
215
216  if [ $ret != 0 ]
217  then
218    echo "SKIP: Cannot attach an IOAM trace to a route. Was your kernel" \
219         "compiled without CONFIG_IPV6_IOAM6_LWTUNNEL? Are you running an" \
220         "old kernel? Are you using an old version of iproute2?"
221    cleanup_ns $ioam_tmp_node
222    exit $ksft_skip
223  fi
224
225  cleanup_ns $ioam_tmp_node
226
227  lsmod 2>/dev/null | grep -q "ip6_tunnel"
228  ip6tnl_loaded=$?
229
230  if [ $ip6tnl_loaded == 0 ]
231  then
232    encap_tests=0
233  else
234    modprobe ip6_tunnel &>/dev/null
235    lsmod 2>/dev/null | grep -q "ip6_tunnel"
236    encap_tests=$?
237
238    if [ $encap_tests != 0 ]
239    then
240      ip a 2>/dev/null | grep -q "ip6tnl0"
241      encap_tests=$?
242
243      if [ $encap_tests != 0 ]
244      then
245        echo "Note: ip6_tunnel not found neither as a module nor inside the" \
246             "kernel. Any tests that require it will be skipped."
247      fi
248    fi
249  fi
250}
251
252cleanup()
253{
254  cleanup_ns $ioam_node_alpha $ioam_node_beta $ioam_node_gamma
255
256  if [ $ip6tnl_loaded != 0 ]
257  then
258    modprobe -r ip6_tunnel &>/dev/null
259  fi
260}
261
262setup()
263{
264  setup_ns ioam_node_alpha ioam_node_beta ioam_node_gamma &>/dev/null
265
266  ip link add name ioam-veth-alpha netns $ioam_node_alpha type veth \
267    peer name ioam-veth-betaL netns $ioam_node_beta &>/dev/null
268  ip link add name ioam-veth-betaR netns $ioam_node_beta type veth \
269    peer name ioam-veth-gamma netns $ioam_node_gamma &>/dev/null
270
271  ip -netns $ioam_node_alpha link set ioam-veth-alpha name veth0 &>/dev/null
272  ip -netns $ioam_node_beta link set ioam-veth-betaL name veth0 &>/dev/null
273  ip -netns $ioam_node_beta link set ioam-veth-betaR name veth1 &>/dev/null
274  ip -netns $ioam_node_gamma link set ioam-veth-gamma name veth0 &>/dev/null
275
276  ip -netns $ioam_node_alpha addr add 2001:db8:1::50/64 dev veth0 &>/dev/null
277  ip -netns $ioam_node_alpha addr add 2001:db8:1::2/64 dev veth0 &>/dev/null
278  ip -netns $ioam_node_alpha link set veth0 up &>/dev/null
279  ip -netns $ioam_node_alpha link set lo up &>/dev/null
280  ip -netns $ioam_node_alpha route add 2001:db8:2::/64 \
281    via 2001:db8:1::1 dev veth0 &>/dev/null
282
283  ip -netns $ioam_node_beta addr add 2001:db8:1::1/64 dev veth0 &>/dev/null
284  ip -netns $ioam_node_beta addr add 2001:db8:2::1/64 dev veth1 &>/dev/null
285  ip -netns $ioam_node_beta link set veth0 up &>/dev/null
286  ip -netns $ioam_node_beta link set veth1 up &>/dev/null
287  ip -netns $ioam_node_beta link set lo up &>/dev/null
288
289  ip -netns $ioam_node_gamma addr add 2001:db8:2::2/64 dev veth0 &>/dev/null
290  ip -netns $ioam_node_gamma link set veth0 up &>/dev/null
291  ip -netns $ioam_node_gamma link set lo up &>/dev/null
292  ip -netns $ioam_node_gamma route add 2001:db8:1::/64 \
293    via 2001:db8:2::1 dev veth0 &>/dev/null
294
295  # - Alpha: IOAM config -
296  ip netns exec $ioam_node_alpha \
297    sysctl -wq net.ipv6.ioam6_id=${ALPHA[0]} &>/dev/null
298  ip netns exec $ioam_node_alpha \
299    sysctl -wq net.ipv6.ioam6_id_wide=${ALPHA[1]} &>/dev/null
300  ip netns exec $ioam_node_alpha \
301    sysctl -wq net.ipv6.conf.veth0.ioam6_id=${ALPHA[4]} &>/dev/null
302  ip netns exec $ioam_node_alpha \
303    sysctl -wq net.ipv6.conf.veth0.ioam6_id_wide=${ALPHA[5]} &>/dev/null
304  ip -netns $ioam_node_alpha \
305    ioam namespace add 123 data ${ALPHA[6]} wide ${ALPHA[7]} &>/dev/null
306  ip -netns $ioam_node_alpha \
307    ioam schema add ${ALPHA[8]} "${ALPHA[9]}" &>/dev/null
308  ip -netns $ioam_node_alpha \
309    ioam namespace set 123 schema ${ALPHA[8]} &>/dev/null
310
311  # - Beta: IOAM config -
312  ip netns exec $ioam_node_beta \
313    sysctl -wq net.ipv6.conf.all.forwarding=1 &>/dev/null
314  ip netns exec $ioam_node_beta \
315    sysctl -wq net.ipv6.ioam6_id=${BETA[0]} &>/dev/null
316  ip netns exec $ioam_node_beta \
317    sysctl -wq net.ipv6.ioam6_id_wide=${BETA[1]} &>/dev/null
318  ip netns exec $ioam_node_beta \
319    sysctl -wq net.ipv6.conf.veth0.ioam6_enabled=1 &>/dev/null
320  ip netns exec $ioam_node_beta \
321    sysctl -wq net.ipv6.conf.veth0.ioam6_id=${BETA[2]} &>/dev/null
322  ip netns exec $ioam_node_beta \
323    sysctl -wq net.ipv6.conf.veth0.ioam6_id_wide=${BETA[3]} &>/dev/null
324  ip netns exec $ioam_node_beta \
325    sysctl -wq net.ipv6.conf.veth1.ioam6_id=${BETA[4]} &>/dev/null
326  ip netns exec $ioam_node_beta \
327    sysctl -wq net.ipv6.conf.veth1.ioam6_id_wide=${BETA[5]} &>/dev/null
328  ip -netns $ioam_node_beta ioam namespace add 123 &>/dev/null
329
330  sleep 1
331
332  ip netns exec $ioam_node_alpha ping6 -c 5 -W 1 2001:db8:2::2 &>/dev/null
333  if [ $? != 0 ]
334  then
335    echo "SKIP: Setup failed."
336    cleanup
337    exit $ksft_skip
338  fi
339}
340
341log_test_passed()
342{
343  printf " - TEST: %-57s  [ OK ]\n" "$1"
344  npassed=$((npassed+1))
345}
346
347log_test_skipped()
348{
349  printf " - TEST: %-57s  [SKIP]\n" "$1"
350  nskipped=$((nskipped+1))
351}
352
353log_test_failed()
354{
355  printf " - TEST: %-57s  [FAIL]\n" "$1"
356  nfailed=$((nfailed+1))
357}
358
359run_test()
360{
361  local name=$1
362  local desc=$2
363  local ip6_src=$3
364  local trace_type=$4
365  local trace_size=$5
366  local ioam_ns=$6
367  local type=$7
368
369  ip netns exec $ioam_node_gamma \
370    ./ioam6_parser veth0 $name $ip6_src 2001:db8:2::2 \
371                   $trace_type $trace_size $ioam_ns $type &
372  local spid=$!
373  sleep 0.1
374
375  ip netns exec $ioam_node_alpha ping6 -t 64 -c 1 -W 1 2001:db8:2::2 &>/dev/null
376  if [ $? != 0 ]
377  then
378    log_test_failed "${desc}"
379    kill -2 $spid &>/dev/null
380  else
381    wait $spid
382    [ $? == 0 ] && log_test_passed "${desc}" || log_test_failed "${desc}"
383  fi
384}
385
386run()
387{
388  local test
389
390  echo
391  printf "+"
392  printf "%0.s-" {1..72}
393  printf "+"
394  echo
395  printf "| %-28s LOCAL tests %-29s |"
396  echo
397  printf "+"
398  printf "%0.s-" {1..72}
399  printf "+"
400  echo
401
402  echo
403  echo "Global config"
404  for test in $TESTS_LOCAL
405  do
406    $test
407  done
408
409  echo
410  echo "Inline mode"
411  for test in $TESTS_LOCAL
412  do
413    $test "inline"
414  done
415
416  echo
417  echo "Encap mode"
418  for test in $TESTS_LOCAL
419  do
420    $test "encap"
421  done
422
423  echo
424  printf "+"
425  printf "%0.s-" {1..72}
426  printf "+"
427  echo
428  printf "| %-28s OUTPUT tests %-28s |"
429  echo
430  printf "+"
431  printf "%0.s-" {1..72}
432  printf "+"
433  echo
434
435  # set OUTPUT settings
436  ip netns exec $ioam_node_beta \
437    sysctl -wq net.ipv6.conf.veth0.ioam6_enabled=0 &>/dev/null
438
439  echo
440  echo "Inline mode"
441  for test in $TESTS_OUTPUT
442  do
443    $test "inline"
444  done
445
446  echo
447  echo "Encap mode"
448  for test in $TESTS_OUTPUT
449  do
450    $test "encap"
451  done
452
453  echo
454  echo "Encap mode (with tunsrc)"
455  for test in $TESTS_OUTPUT
456  do
457    $test "encap" "tunsrc"
458  done
459
460  # clean OUTPUT settings
461  ip netns exec $ioam_node_beta \
462    sysctl -wq net.ipv6.conf.veth0.ioam6_enabled=1 &>/dev/null
463
464  echo
465  printf "+"
466  printf "%0.s-" {1..72}
467  printf "+"
468  echo
469  printf "| %-28s INPUT tests %-29s |"
470  echo
471  printf "+"
472  printf "%0.s-" {1..72}
473  printf "+"
474  echo
475
476  # set INPUT settings
477  ip -netns $ioam_node_alpha ioam namespace del 123 &>/dev/null
478
479  echo
480  echo "Inline mode"
481  for test in $TESTS_INPUT
482  do
483    $test "inline"
484  done
485
486  echo
487  echo "Encap mode"
488  for test in $TESTS_INPUT
489  do
490    $test "encap"
491  done
492
493  # clean INPUT settings
494  ip -netns $ioam_node_alpha \
495    ioam namespace add 123 data ${ALPHA[6]} wide ${ALPHA[7]} &>/dev/null
496  ip -netns $ioam_node_alpha \
497    ioam namespace set 123 schema ${ALPHA[8]} &>/dev/null
498
499  echo
500  printf "+"
501  printf "%0.s-" {1..72}
502  printf "+"
503  echo
504  printf "| %-30s Results %-31s |"
505  echo
506  printf "+"
507  printf "%0.s-" {1..72}
508  printf "+"
509  echo
510
511  echo
512  echo "- Passed:  ${npassed}"
513  echo "- Skipped: ${nskipped}"
514  echo "- Failed:  ${nfailed}"
515  echo
516}
517
518bit2type=(
519  0x800000 0x400000 0x200000 0x100000 0x080000 0x040000 0x020000 0x010000
520  0x008000 0x004000 0x002000 0x001000 0x000800 0x000400 0x000200 0x000100
521  0x000080 0x000040 0x000020 0x000010 0x000008 0x000004 0x000002 0x000001
522)
523bit2size=( 4 4 4 4 4 4 4 4 8 8 8 4 4 4 4 4 4 4 4 4 4 4 4 0 )
524
525
526################################################################################
527#                                                                              #
528#                                 LOCAL tests                                  #
529#                                                                              #
530################################################################################
531
532local_sysctl_ioam_id()
533{
534  ##############################################################################
535  # Make sure the sysctl "net.ipv6.ioam6_id" works as expected.                #
536  ##############################################################################
537  local desc="Sysctl net.ipv6.ioam6_id"
538
539  [ ! -z $1 ] && return
540
541  ip netns exec $ioam_node_alpha \
542    sysctl net.ipv6.ioam6_id 2>/dev/null | grep -wq ${ALPHA[0]}
543
544  [ $? == 0 ] && log_test_passed "${desc}" || log_test_failed "${desc}"
545}
546
547local_sysctl_ioam_id_wide()
548{
549  ##############################################################################
550  # Make sure the sysctl "net.ipv6.ioam6_id_wide" works as expected.           #
551  ##############################################################################
552  local desc="Sysctl net.ipv6.ioam6_id_wide"
553
554  [ ! -z $1 ] && return
555
556  ip netns exec $ioam_node_alpha \
557    sysctl net.ipv6.ioam6_id_wide 2>/dev/null | grep -wq ${ALPHA[1]}
558
559  [ $? == 0 ] && log_test_passed "${desc}" || log_test_failed "${desc}"
560}
561
562local_sysctl_ioam_intf_id()
563{
564  ##############################################################################
565  # Make sure the sysctl "net.ipv6.conf.XX.ioam6_id" works as expected.        #
566  ##############################################################################
567  local desc="Sysctl net.ipv6.conf.XX.ioam6_id"
568
569  [ ! -z $1 ] && return
570
571  ip netns exec $ioam_node_alpha \
572    sysctl net.ipv6.conf.veth0.ioam6_id 2>/dev/null | grep -wq ${ALPHA[4]}
573
574  [ $? == 0 ] && log_test_passed "${desc}" || log_test_failed "${desc}"
575}
576
577local_sysctl_ioam_intf_id_wide()
578{
579  ##############################################################################
580  # Make sure the sysctl "net.ipv6.conf.XX.ioam6_id_wide" works as expected.   #
581  ##############################################################################
582  local desc="Sysctl net.ipv6.conf.XX.ioam6_id_wide"
583
584  [ ! -z $1 ] && return
585
586  ip netns exec $ioam_node_alpha \
587    sysctl net.ipv6.conf.veth0.ioam6_id_wide 2>/dev/null | grep -wq ${ALPHA[5]}
588
589  [ $? == 0 ] && log_test_passed "${desc}" || log_test_failed "${desc}"
590}
591
592local_sysctl_ioam_intf_enabled()
593{
594  ##############################################################################
595  # Make sure the sysctl "net.ipv6.conf.XX.ioam6_enabled" works as expected.   #
596  ##############################################################################
597  local desc="Sysctl net.ipv6.conf.XX.ioam6_enabled"
598
599  [ ! -z $1 ] && return
600
601  ip netns exec $ioam_node_beta \
602    sysctl net.ipv6.conf.veth0.ioam6_enabled 2>/dev/null | grep -wq 1
603
604  [ $? == 0 ] && log_test_passed "${desc}" || log_test_failed "${desc}"
605}
606
607local_ioam_namespace()
608{
609  ##############################################################################
610  # Make sure the creation of an IOAM Namespace works as expected.             #
611  ##############################################################################
612  local desc="Create an IOAM Namespace"
613
614  [ ! -z $1 ] && return
615
616  ip -netns $ioam_node_alpha \
617    ioam namespace show 2>/dev/null | grep -wq 123
618  local ret=$?
619
620  ip -netns $ioam_node_alpha \
621    ioam namespace show 2>/dev/null | grep -wq ${ALPHA[6]}
622  ret=$((ret + $?))
623
624  ip -netns $ioam_node_alpha \
625    ioam namespace show 2>/dev/null | grep -wq ${ALPHA[7]}
626  ret=$((ret + $?))
627
628  [ $ret == 0 ] && log_test_passed "${desc}" || log_test_failed "${desc}"
629}
630
631local_ioam_schema()
632{
633  ##############################################################################
634  # Make sure the creation of an IOAM Schema works as expected.                #
635  ##############################################################################
636  local desc="Create an IOAM Schema"
637
638  [ ! -z $1 ] && return
639
640  ip -netns $ioam_node_alpha \
641    ioam schema show 2>/dev/null | grep -wq ${ALPHA[8]}
642  local ret=$?
643
644  local sc_data=$(
645    for i in `seq 0 $((${#ALPHA[9]}-1))`
646    do
647      chr=${ALPHA[9]:i:1}
648      printf "%x " "'${chr}"
649    done
650  )
651
652  ip -netns $ioam_node_alpha \
653    ioam schema show 2>/dev/null | grep -q "$sc_data"
654  ret=$((ret + $?))
655
656  [ $ret == 0 ] && log_test_passed "${desc}" || log_test_failed "${desc}"
657}
658
659local_ioam_schema_namespace()
660{
661  ##############################################################################
662  # Make sure the binding of a Schema to a Namespace works as expected.        #
663  ##############################################################################
664  local desc="Bind an IOAM Schema to an IOAM Namespace"
665
666  [ ! -z $1 ] && return
667
668  ip -netns $ioam_node_alpha \
669    ioam namespace show 2>/dev/null | grep -wq ${ALPHA[8]}
670  local ret=$?
671
672  ip -netns $ioam_node_alpha \
673    ioam schema show 2>/dev/null | grep -wq 123
674  ret=$((ret + $?))
675
676  [ $ret == 0 ] && log_test_passed "${desc}" || log_test_failed "${desc}"
677}
678
679local_route_ns()
680{
681  ##############################################################################
682  # Make sure the Namespace-ID is always provided, whatever the mode.          #
683  ##############################################################################
684  local desc="Mandatory Namespace-ID"
685  local mode
686
687  [ -z $1 ] && return
688
689  [ "$1" == "encap" ] && mode="$1 tundst 2001:db8:2::2" || mode="$1"
690
691  ip -netns $ioam_node_alpha \
692    route change 2001:db8:2::/64 \
693    encap ioam6 mode $mode trace prealloc type 0x800000 size 4 \
694    via 2001:db8:1::1 dev veth0 &>/dev/null
695  local ret1=$?
696
697  ip -netns $ioam_node_alpha \
698    route change 2001:db8:2::/64 \
699    encap ioam6 mode $mode trace prealloc type 0x800000 ns 0 size 4 \
700    via 2001:db8:1::1 dev veth0 &>/dev/null
701  local ret2=$?
702
703  [[ $ret1 == 0 || $ret2 != 0 ]] && log_test_failed "${desc}" \
704                                 || log_test_passed "${desc}"
705
706  ip -netns $ioam_node_alpha \
707    route change 2001:db8:2::/64 via 2001:db8:1::1 dev veth0 &>/dev/null
708}
709
710local_route_tunsrc()
711{
712  ##############################################################################
713  # Make sure the Tunnel Source is only (and possibly) used with encap mode.   #
714  ##############################################################################
715  local desc
716  local mode
717  local mode_tunsrc
718
719  [ -z $1 ] && return
720
721  if [ "$1" == "encap" ]
722  then
723    desc="Optional Tunnel Source"
724    mode="$1 tundst 2001:db8:2::2"
725    mode_tunsrc="$1 tunsrc 2001:db8:1::50 tundst 2001:db8:2::2"
726  else
727    desc="Unneeded Tunnel Source"
728    mode="$1"
729    mode_tunsrc="$1 tunsrc 2001:db8:1::50"
730  fi
731
732  ip -netns $ioam_node_alpha \
733    route change 2001:db8:2::/64 \
734    encap ioam6 mode $mode trace prealloc type 0x800000 ns 0 size 4 \
735    via 2001:db8:1::1 dev veth0 &>/dev/null
736  local ret1=$?
737
738  ip -netns $ioam_node_alpha \
739    route change 2001:db8:2::/64 \
740    encap ioam6 mode $mode_tunsrc trace prealloc type 0x800000 ns 0 size 4 \
741    via 2001:db8:1::1 dev veth0 &>/dev/null
742  local ret2=$?
743
744  if [ "$1" == "encap" ]
745  then
746    [[ $ret1 != 0 || $ret2 != 0 ]] && log_test_failed "${desc}" \
747                                   || log_test_passed "${desc}"
748  else
749    [[ $ret1 != 0 || $ret2 == 0 ]] && log_test_failed "${desc}" \
750                                   || log_test_passed "${desc}"
751  fi
752
753  ip -netns $ioam_node_alpha \
754    route change 2001:db8:2::/64 via 2001:db8:1::1 dev veth0 &>/dev/null
755}
756
757local_route_tundst()
758{
759  ##############################################################################
760  # Make sure the Tunnel Destination is only (and always) used with encap mode.#
761  ##############################################################################
762  local desc
763
764  [ -z $1 ] && return
765
766  [ "$1" == "encap" ] && desc="Mandatory Tunnel Destination" \
767                     || desc="Unneeded Tunnel Destination"
768
769  local mode="$1"
770  local mode_tundst="$1 tundst 2001:db8:2::2"
771
772  ip -netns $ioam_node_alpha \
773    route change 2001:db8:2::/64 \
774    encap ioam6 mode $mode trace prealloc type 0x800000 ns 0 size 4 \
775    via 2001:db8:1::1 dev veth0 &>/dev/null
776  local ret1=$?
777
778  ip -netns $ioam_node_alpha \
779    route change 2001:db8:2::/64 \
780    encap ioam6 mode $mode_tundst trace prealloc type 0x800000 ns 0 size 4 \
781    via 2001:db8:1::1 dev veth0 &>/dev/null
782  local ret2=$?
783
784  if [ "$1" == "encap" ]
785  then
786    [[ $ret1 == 0 || $ret2 != 0 ]] && log_test_failed "${desc}" \
787                                   || log_test_passed "${desc}"
788  else
789    [[ $ret1 != 0 || $ret2 == 0 ]] && log_test_failed "${desc}" \
790                                   || log_test_passed "${desc}"
791  fi
792
793  ip -netns $ioam_node_alpha \
794    route change 2001:db8:2::/64 via 2001:db8:1::1 dev veth0 &>/dev/null
795}
796
797local_route_trace_type()
798{
799  ##############################################################################
800  # Make sure the Trace Type is always provided, whatever the mode.            #
801  ##############################################################################
802  local desc="Mandatory Trace Type"
803  local mode
804
805  [ -z $1 ] && return
806
807  [ "$1" == "encap" ] && mode="$1 tundst 2001:db8:2::2" || mode="$1"
808
809  ip -netns $ioam_node_alpha \
810    route change 2001:db8:2::/64 \
811    encap ioam6 mode $mode trace prealloc ns 0 size 4 \
812    via 2001:db8:1::1 dev veth0 &>/dev/null
813  local ret1=$?
814
815  ip -netns $ioam_node_alpha \
816    route change 2001:db8:2::/64 \
817    encap ioam6 mode $mode trace prealloc type 0x800000 ns 0 size 4 \
818    via 2001:db8:1::1 dev veth0 &>/dev/null
819  local ret2=$?
820
821  [[ $ret1 == 0 || $ret2 != 0 ]] && log_test_failed "${desc}" \
822                                 || log_test_passed "${desc}"
823
824  ip -netns $ioam_node_alpha \
825    route change 2001:db8:2::/64 via 2001:db8:1::1 dev veth0 &>/dev/null
826}
827
828local_route_trace_size()
829{
830  ##############################################################################
831  # Make sure the Trace Size is always provided, whatever the mode.            #
832  ##############################################################################
833  local desc="Mandatory Trace Size"
834  local mode
835
836  [ -z $1 ] && return
837
838  [ "$1" == "encap" ] && mode="$1 tundst 2001:db8:2::2" || mode="$1"
839
840  ip -netns $ioam_node_alpha \
841    route change 2001:db8:2::/64 \
842    encap ioam6 mode $mode trace prealloc type 0x800000 ns 0 \
843    via 2001:db8:1::1 dev veth0 &>/dev/null
844  local ret1=$?
845
846  ip -netns $ioam_node_alpha \
847    route change 2001:db8:2::/64 \
848    encap ioam6 mode $mode trace prealloc type 0x800000 ns 0 size 4 \
849    via 2001:db8:1::1 dev veth0 &>/dev/null
850  local ret2=$?
851
852  [[ $ret1 == 0 || $ret2 != 0 ]] && log_test_failed "${desc}" \
853                                 || log_test_passed "${desc}"
854
855  ip -netns $ioam_node_alpha \
856    route change 2001:db8:2::/64 via 2001:db8:1::1 dev veth0 &>/dev/null
857}
858
859local_route_trace_type_bits()
860{
861  ##############################################################################
862  # Make sure only allowed bits (0-11 and 22) are accepted.                    #
863  ##############################################################################
864  local desc="Trace Type bits"
865  local mode
866
867  [ -z $1 ] && return
868
869  [ "$1" == "encap" ] && mode="$1 tundst 2001:db8:2::2" || mode="$1"
870
871  local i
872  for i in {0..23}
873  do
874    ip -netns $ioam_node_alpha \
875      route change 2001:db8:2::/64 \
876      encap ioam6 mode $mode trace prealloc type ${bit2type[$i]} ns 0 size 4 \
877      via 2001:db8:1::1 dev veth0 &>/dev/null
878
879    if [[ ($? == 0 && (($i -ge 12 && $i -le 21) || $i == 23)) ||
880          ($? != 0 && (($i -ge 0 && $i -le 11) || $i == 22)) ]]
881    then
882      local err=1
883      break
884    fi
885  done
886
887  [ -z $err ] && log_test_passed "${desc}" || log_test_failed "${desc}"
888
889  ip -netns $ioam_node_alpha \
890    route change 2001:db8:2::/64 via 2001:db8:1::1 dev veth0 &>/dev/null
891}
892
893local_route_trace_size_values()
894{
895  ##############################################################################
896  # Make sure only allowed sizes (multiples of four in [4,244]) are accepted.  #
897  ##############################################################################
898  local desc="Trace Size values"
899  local mode
900
901  [ -z $1 ] && return
902
903  [ "$1" == "encap" ] && mode="$1 tundst 2001:db8:2::2" || mode="$1"
904
905  # we also try the next multiple of four after the MAX to check it's refused
906  local i
907  for i in {0..248}
908  do
909    ip -netns $ioam_node_alpha \
910      route change 2001:db8:2::/64 \
911      encap ioam6 mode $mode trace prealloc type 0x800000 ns 0 size $i \
912      via 2001:db8:1::1 dev veth0 &>/dev/null
913
914    if [[ ($? == 0 && ($i == 0 || $i == 248 || $(( $i % 4 )) != 0)) ||
915          ($? != 0 && $i != 0 && $i != 248 && $(( $i % 4 )) == 0) ]]
916    then
917      local err=1
918      break
919    fi
920  done
921
922  [ -z $err ] && log_test_passed "${desc}" || log_test_failed "${desc}"
923
924  ip -netns $ioam_node_alpha \
925    route change 2001:db8:2::/64 via 2001:db8:1::1 dev veth0 &>/dev/null
926}
927
928
929################################################################################
930#                                                                              #
931#                                 OUTPUT tests                                 #
932#                                                                              #
933################################################################################
934
935output_undef_ns()
936{
937  ##############################################################################
938  # Make sure an IOAM encapsulating node does NOT fill the trace when the      #
939  # corresponding IOAM Namespace-ID is not configured locally.                 #
940  ##############################################################################
941  local desc="Unknown IOAM Namespace-ID"
942  local ns=0
943  local tr_type=0x800000
944  local tr_size=4
945  local mode="$1"
946  local saddr="2001:db8:1::2"
947
948  if [ "$1" == "encap" ]
949  then
950    if [ $encap_tests != 0 ]
951    then
952      log_test_skipped "${desc}"
953      return
954    fi
955
956    if [ "$2" == "tunsrc" ]
957    then
958      saddr="2001:db8:1::50"
959      mode+=" tunsrc 2001:db8:1::50"
960    fi
961
962    mode+=" tundst 2001:db8:2::2"
963    ip -netns $ioam_node_gamma link set ip6tnl0 up &>/dev/null
964  fi
965
966  ip -netns $ioam_node_alpha \
967    route change 2001:db8:2::/64 \
968    encap ioam6 mode $mode trace prealloc type $tr_type ns $ns size $tr_size \
969    via 2001:db8:1::1 dev veth0 &>/dev/null
970
971  if [ $? == 0 ]
972  then
973    run_test ${FUNCNAME[0]} "${desc}" $saddr $tr_type $tr_size $ns $1
974  else
975    log_test_failed "${desc}"
976  fi
977
978  ip -netns $ioam_node_alpha \
979    route change 2001:db8:2::/64 via 2001:db8:1::1 dev veth0 &>/dev/null
980
981  [ "$1" == "encap" ] && ip -netns $ioam_node_gamma \
982    link set ip6tnl0 down &>/dev/null
983}
984
985output_no_room()
986{
987  ##############################################################################
988  # Make sure an IOAM encapsulating node does NOT fill the trace AND sets the  #
989  # Overflow flag when there is not enough room for its data.                  #
990  ##############################################################################
991  local desc="Missing room for data"
992  local ns=123
993  local tr_type=0xc00000
994  local tr_size=4
995  local mode="$1"
996  local saddr="2001:db8:1::2"
997
998  if [ "$1" == "encap" ]
999  then
1000    if [ $encap_tests != 0 ]
1001    then
1002      log_test_skipped "${desc}"
1003      return
1004    fi
1005
1006    if [ "$2" == "tunsrc" ]
1007    then
1008      saddr="2001:db8:1::50"
1009      mode+=" tunsrc 2001:db8:1::50"
1010    fi
1011
1012    mode+=" tundst 2001:db8:2::2"
1013    ip -netns $ioam_node_gamma link set ip6tnl0 up &>/dev/null
1014  fi
1015
1016  ip -netns $ioam_node_alpha \
1017    route change 2001:db8:2::/64 \
1018    encap ioam6 mode $mode trace prealloc type $tr_type ns $ns size $tr_size \
1019    via 2001:db8:1::1 dev veth0 &>/dev/null
1020
1021  if [ $? == 0 ]
1022  then
1023    run_test ${FUNCNAME[0]} "${desc}" $saddr $tr_type $tr_size $ns $1
1024  else
1025    log_test_failed "${desc}"
1026  fi
1027
1028  ip -netns $ioam_node_alpha \
1029    route change 2001:db8:2::/64 via 2001:db8:1::1 dev veth0 &>/dev/null
1030
1031  [ "$1" == "encap" ] && ip -netns $ioam_node_gamma \
1032    link set ip6tnl0 down &>/dev/null
1033}
1034
1035output_no_room_oss()
1036{
1037  ##############################################################################
1038  # Make sure an IOAM encapsulating node does NOT fill the trace AND sets the  #
1039  # Overflow flag when there is not enough room for the Opaque State Snapshot. #
1040  ##############################################################################
1041  local desc="Missing room for Opaque State Snapshot"
1042  local ns=123
1043  local tr_type=0x000002
1044  local tr_size=4
1045  local mode="$1"
1046  local saddr="2001:db8:1::2"
1047
1048  if [ "$1" == "encap" ]
1049  then
1050    if [ $encap_tests != 0 ]
1051    then
1052      log_test_skipped "${desc}"
1053      return
1054    fi
1055
1056    if [ "$2" == "tunsrc" ]
1057    then
1058      saddr="2001:db8:1::50"
1059      mode+=" tunsrc 2001:db8:1::50"
1060    fi
1061
1062    mode+=" tundst 2001:db8:2::2"
1063    ip -netns $ioam_node_gamma link set ip6tnl0 up &>/dev/null
1064  fi
1065
1066  ip -netns $ioam_node_alpha \
1067    route change 2001:db8:2::/64 \
1068    encap ioam6 mode $mode trace prealloc type $tr_type ns $ns size $tr_size \
1069    via 2001:db8:1::1 dev veth0 &>/dev/null
1070
1071  if [ $? == 0 ]
1072  then
1073    run_test ${FUNCNAME[0]} "${desc}" $saddr $tr_type $tr_size $ns $1
1074  else
1075    log_test_failed "${desc}"
1076  fi
1077
1078  ip -netns $ioam_node_alpha \
1079    route change 2001:db8:2::/64 via 2001:db8:1::1 dev veth0 &>/dev/null
1080
1081  [ "$1" == "encap" ] && ip -netns $ioam_node_gamma \
1082    link set ip6tnl0 down &>/dev/null
1083}
1084
1085output_bits()
1086{
1087  ##############################################################################
1088  # Make sure an IOAM encapsulating node implements all supported bits by      #
1089  # checking it correctly fills the trace with its data.                       #
1090  ##############################################################################
1091  local desc="Trace Type with supported bit <n> only"
1092  local ns=123
1093  local mode="$1"
1094  local saddr="2001:db8:1::2"
1095
1096  if [ "$1" == "encap" ]
1097  then
1098    if [ "$2" == "tunsrc" ]
1099    then
1100      saddr="2001:db8:1::50"
1101      mode+=" tunsrc 2001:db8:1::50"
1102    fi
1103
1104    mode+=" tundst 2001:db8:2::2"
1105    ip -netns $ioam_node_gamma link set ip6tnl0 up &>/dev/null
1106  fi
1107
1108  local tmp=${bit2size[22]}
1109  bit2size[22]=$(( $tmp + ${#ALPHA[9]} + ((4 - (${#ALPHA[9]} % 4)) % 4) ))
1110
1111  local i
1112  for i in {0..11} {22..22}
1113  do
1114    local descr="${desc/<n>/$i}"
1115
1116    if [[ "$1" == "encap" && $encap_tests != 0 ]]
1117    then
1118      log_test_skipped "${descr}"
1119      continue
1120    fi
1121
1122    ip -netns $ioam_node_alpha \
1123      route change 2001:db8:2::/64 \
1124      encap ioam6 mode $mode trace prealloc \
1125      type ${bit2type[$i]} ns $ns size ${bit2size[$i]} \
1126      via 2001:db8:1::1 dev veth0 &>/dev/null
1127
1128    if [ $? == 0 ]
1129    then
1130      run_test "output_bit$i" "${descr}" $saddr \
1131        ${bit2type[$i]} ${bit2size[$i]} $ns $1
1132    else
1133      log_test_failed "${descr}"
1134    fi
1135  done
1136
1137  ip -netns $ioam_node_alpha \
1138    route change 2001:db8:2::/64 via 2001:db8:1::1 dev veth0 &>/dev/null
1139
1140  [ "$1" == "encap" ] && ip -netns $ioam_node_gamma \
1141    link set ip6tnl0 down &>/dev/null
1142
1143  bit2size[22]=$tmp
1144}
1145
1146output_sizes()
1147{
1148  ##############################################################################
1149  # Make sure an IOAM encapsulating node allocates supported sizes correctly.  #
1150  ##############################################################################
1151  local desc="Trace Size of <n> bytes"
1152  local ns=0
1153  local tr_type=0x800000
1154  local mode="$1"
1155  local saddr="2001:db8:1::2"
1156
1157  if [ "$1" == "encap" ]
1158  then
1159    if [ "$2" == "tunsrc" ]
1160    then
1161      saddr="2001:db8:1::50"
1162      mode+=" tunsrc 2001:db8:1::50"
1163    fi
1164
1165    mode+=" tundst 2001:db8:2::2"
1166    ip -netns $ioam_node_gamma link set ip6tnl0 up &>/dev/null
1167  fi
1168
1169  local i
1170  for i in $(seq 4 4 244)
1171  do
1172    local descr="${desc/<n>/$i}"
1173
1174    if [[ "$1" == "encap" && $encap_tests != 0 ]]
1175    then
1176      log_test_skipped "${descr}"
1177      continue
1178    fi
1179
1180    ip -netns $ioam_node_alpha \
1181      route change 2001:db8:2::/64 \
1182      encap ioam6 mode $mode trace prealloc type $tr_type ns $ns size $i \
1183      via 2001:db8:1::1 dev veth0 &>/dev/null
1184
1185    if [ $? == 0 ]
1186    then
1187      run_test "output_size$i" "${descr}" $saddr $tr_type $i $ns $1
1188    else
1189      log_test_failed "${descr}"
1190    fi
1191  done
1192
1193  ip -netns $ioam_node_alpha \
1194    route change 2001:db8:2::/64 via 2001:db8:1::1 dev veth0 &>/dev/null
1195
1196  [ "$1" == "encap" ] && ip -netns $ioam_node_gamma \
1197    link set ip6tnl0 down &>/dev/null
1198}
1199
1200output_full_supp_trace()
1201{
1202  ##############################################################################
1203  # Make sure an IOAM encapsulating node correctly fills a trace when all      #
1204  # supported bits are set.                                                    #
1205  ##############################################################################
1206  local desc="Full supported trace"
1207  local ns=123
1208  local tr_type=0xfff002
1209  local tr_size
1210  local mode="$1"
1211  local saddr="2001:db8:1::2"
1212
1213  if [ "$1" == "encap" ]
1214  then
1215    if [ $encap_tests != 0 ]
1216    then
1217      log_test_skipped "${desc}"
1218      return
1219    fi
1220
1221    if [ "$2" == "tunsrc" ]
1222    then
1223      saddr="2001:db8:1::50"
1224      mode+=" tunsrc 2001:db8:1::50"
1225    fi
1226
1227    mode+=" tundst 2001:db8:2::2"
1228    ip -netns $ioam_node_gamma link set ip6tnl0 up &>/dev/null
1229  fi
1230
1231  local i
1232  tr_size=$(( ${#ALPHA[9]} + ((4 - (${#ALPHA[9]} % 4)) % 4) ))
1233  for i in {0..11} {22..22}
1234  do
1235    tr_size=$((tr_size + bit2size[$i]))
1236  done
1237
1238  ip -netns $ioam_node_alpha \
1239    route change 2001:db8:2::/64 \
1240    encap ioam6 mode $mode trace prealloc type $tr_type ns $ns size $tr_size \
1241    via 2001:db8:1::1 dev veth0 &>/dev/null
1242
1243  if [ $? == 0 ]
1244  then
1245    run_test ${FUNCNAME[0]} "${desc}" $saddr $tr_type $tr_size $ns $1
1246  else
1247    log_test_failed "${desc}"
1248  fi
1249
1250  ip -netns $ioam_node_alpha \
1251    route change 2001:db8:2::/64 via 2001:db8:1::1 dev veth0 &>/dev/null
1252
1253  [ "$1" == "encap" ] && ip -netns $ioam_node_gamma \
1254    link set ip6tnl0 down &>/dev/null
1255}
1256
1257
1258################################################################################
1259#                                                                              #
1260#                                 INPUT tests                                  #
1261#                                                                              #
1262################################################################################
1263
1264input_undef_ns()
1265{
1266  ##############################################################################
1267  # Make sure an IOAM node does NOT fill the trace when the corresponding IOAM #
1268  # Namespace-ID is not configured locally.                                    #
1269  ##############################################################################
1270  local desc="Unknown IOAM Namespace-ID"
1271  local ns=0
1272  local tr_type=0x800000
1273  local tr_size=4
1274  local mode="$1"
1275
1276  if [ "$1" == "encap" ]
1277  then
1278    if [ $encap_tests != 0 ]
1279    then
1280      log_test_skipped "${desc}"
1281      return
1282    fi
1283
1284    mode+=" tundst 2001:db8:2::2"
1285    ip -netns $ioam_node_gamma link set ip6tnl0 up &>/dev/null
1286  fi
1287
1288  ip -netns $ioam_node_alpha \
1289    route change 2001:db8:2::/64 \
1290    encap ioam6 mode $mode trace prealloc type $tr_type ns $ns size $tr_size \
1291    via 2001:db8:1::1 dev veth0 &>/dev/null
1292
1293  if [ $? == 0 ]
1294  then
1295    run_test ${FUNCNAME[0]} "${desc}" 2001:db8:1::2 $tr_type $tr_size $ns $1
1296  else
1297    log_test_failed "${desc}"
1298  fi
1299
1300  ip -netns $ioam_node_alpha \
1301    route change 2001:db8:2::/64 via 2001:db8:1::1 dev veth0 &>/dev/null
1302
1303  [ "$1" == "encap" ] && ip -netns $ioam_node_gamma \
1304    link set ip6tnl0 down &>/dev/null
1305}
1306
1307input_no_room()
1308{
1309  ##############################################################################
1310  # Make sure an IOAM node does NOT fill the trace AND sets the Overflow flag  #
1311  # when there is not enough room for its data.                                #
1312  ##############################################################################
1313  local desc="Missing room for data"
1314  local ns=123
1315  local tr_type=0xc00000
1316  local tr_size=4
1317  local mode="$1"
1318
1319  if [ "$1" == "encap" ]
1320  then
1321    if [ $encap_tests != 0 ]
1322    then
1323      log_test_skipped "${desc}"
1324      return
1325    fi
1326
1327    mode+=" tundst 2001:db8:2::2"
1328    ip -netns $ioam_node_gamma link set ip6tnl0 up &>/dev/null
1329  fi
1330
1331  ip -netns $ioam_node_alpha \
1332    route change 2001:db8:2::/64 \
1333    encap ioam6 mode $mode trace prealloc type $tr_type ns $ns size $tr_size \
1334    via 2001:db8:1::1 dev veth0 &>/dev/null
1335
1336  if [ $? == 0 ]
1337  then
1338    run_test ${FUNCNAME[0]} "${desc}" 2001:db8:1::2 $tr_type $tr_size $ns $1
1339  else
1340    log_test_failed "${desc}"
1341  fi
1342
1343  ip -netns $ioam_node_alpha \
1344    route change 2001:db8:2::/64 via 2001:db8:1::1 dev veth0 &>/dev/null
1345
1346  [ "$1" == "encap" ] && ip -netns $ioam_node_gamma \
1347    link set ip6tnl0 down &>/dev/null
1348}
1349
1350input_no_room_oss()
1351{
1352  ##############################################################################
1353  # Make sure an IOAM node does NOT fill the trace AND sets the Overflow flag  #
1354  # when there is not enough room for the Opaque State Snapshot.               #
1355  ##############################################################################
1356  local desc="Missing room for Opaque State Snapshot"
1357  local ns=123
1358  local tr_type=0x000002
1359  local tr_size=4
1360  local mode="$1"
1361
1362  if [ "$1" == "encap" ]
1363  then
1364    if [ $encap_tests != 0 ]
1365    then
1366      log_test_skipped "${desc}"
1367      return
1368    fi
1369
1370    mode+=" tundst 2001:db8:2::2"
1371    ip -netns $ioam_node_gamma link set ip6tnl0 up &>/dev/null
1372  fi
1373
1374  ip -netns $ioam_node_alpha \
1375    route change 2001:db8:2::/64 \
1376    encap ioam6 mode $mode trace prealloc type $tr_type ns $ns size $tr_size \
1377    via 2001:db8:1::1 dev veth0 &>/dev/null
1378
1379  if [ $? == 0 ]
1380  then
1381    run_test ${FUNCNAME[0]} "${desc}" 2001:db8:1::2 $tr_type $tr_size $ns $1
1382  else
1383    log_test_failed "${desc}"
1384  fi
1385
1386  ip -netns $ioam_node_alpha \
1387    route change 2001:db8:2::/64 via 2001:db8:1::1 dev veth0 &>/dev/null
1388
1389  [ "$1" == "encap" ] && ip -netns $ioam_node_gamma \
1390    link set ip6tnl0 down &>/dev/null
1391}
1392
1393input_disabled()
1394{
1395  ##############################################################################
1396  # Make sure an IOAM node does NOT fill the trace when IOAM is not enabled on #
1397  # the corresponding (ingress) interface.                                     #
1398  ##############################################################################
1399  local desc="IOAM disabled on ingress interface"
1400  local ns=123
1401  local tr_type=0x800000
1402  local tr_size=4
1403  local mode="$1"
1404
1405  if [ "$1" == "encap" ]
1406  then
1407    if [ $encap_tests != 0 ]
1408    then
1409      log_test_skipped "${desc}"
1410      return
1411    fi
1412
1413    mode+=" tundst 2001:db8:2::2"
1414    ip -netns $ioam_node_gamma link set ip6tnl0 up &>/dev/null
1415  fi
1416
1417  # Exception: disable IOAM on ingress interface
1418  ip netns exec $ioam_node_beta \
1419    sysctl -wq net.ipv6.conf.veth0.ioam6_enabled=0 &>/dev/null
1420  local ret=$?
1421
1422  ip -netns $ioam_node_alpha \
1423    route change 2001:db8:2::/64 \
1424    encap ioam6 mode $mode trace prealloc type $tr_type ns $ns size $tr_size \
1425    via 2001:db8:1::1 dev veth0 &>/dev/null
1426  ret=$((ret + $?))
1427
1428  if [ $ret == 0 ]
1429  then
1430    run_test ${FUNCNAME[0]} "${desc}" 2001:db8:1::2 $tr_type $tr_size $ns $1
1431  else
1432    log_test_failed "${desc}"
1433  fi
1434
1435  # Clean Exception
1436  ip netns exec $ioam_node_beta \
1437    sysctl -wq net.ipv6.conf.veth0.ioam6_enabled=1 &>/dev/null
1438
1439  ip -netns $ioam_node_alpha \
1440    route change 2001:db8:2::/64 via 2001:db8:1::1 dev veth0 &>/dev/null
1441
1442  [ "$1" == "encap" ] && ip -netns $ioam_node_gamma \
1443    link set ip6tnl0 down &>/dev/null
1444}
1445
1446input_oflag()
1447{
1448  ##############################################################################
1449  # Make sure an IOAM node does NOT fill the trace when the Overflow flag is   #
1450  # set.                                                                       #
1451  ##############################################################################
1452  local desc="Overflow flag is set"
1453  local ns=123
1454  local tr_type=0xc00000
1455  local tr_size=4
1456  local mode="$1"
1457
1458  if [ "$1" == "encap" ]
1459  then
1460    if [ $encap_tests != 0 ]
1461    then
1462      log_test_skipped "${desc}"
1463      return
1464    fi
1465
1466    mode+=" tundst 2001:db8:2::2"
1467    ip -netns $ioam_node_gamma link set ip6tnl0 up &>/dev/null
1468  fi
1469
1470  # Exception:
1471  #   Here, we need the sender to set the Overflow flag. For that, we will add
1472  #   back the IOAM namespace that was previously configured on the sender.
1473  ip -netns $ioam_node_alpha ioam namespace add 123 &>/dev/null
1474  local ret=$?
1475
1476  ip -netns $ioam_node_alpha \
1477    route change 2001:db8:2::/64 \
1478    encap ioam6 mode $mode trace prealloc type $tr_type ns $ns size $tr_size \
1479    via 2001:db8:1::1 dev veth0 &>/dev/null
1480  ret=$((ret + $?))
1481
1482  if [ $ret == 0 ]
1483  then
1484    run_test ${FUNCNAME[0]} "${desc}" 2001:db8:1::2 $tr_type $tr_size $ns $1
1485  else
1486    log_test_failed "${desc}"
1487  fi
1488
1489  # Clean Exception
1490  ip -netns $ioam_node_alpha ioam namespace del 123 &>/dev/null
1491
1492  ip -netns $ioam_node_alpha \
1493    route change 2001:db8:2::/64 via 2001:db8:1::1 dev veth0 &>/dev/null
1494
1495  [ "$1" == "encap" ] && ip -netns $ioam_node_gamma \
1496    link set ip6tnl0 down &>/dev/null
1497}
1498
1499input_bits()
1500{
1501  ##############################################################################
1502  # Make sure an IOAM node implements all supported bits by checking it        #
1503  # correctly fills the trace with its data.                                   #
1504  ##############################################################################
1505  local desc="Trace Type with supported bit <n> only"
1506  local ns=123
1507  local mode="$1"
1508
1509  if [ "$1" == "encap" ]
1510  then
1511    mode+=" tundst 2001:db8:2::2"
1512    ip -netns $ioam_node_gamma link set ip6tnl0 up &>/dev/null
1513  fi
1514
1515  local tmp=${bit2size[22]}
1516  bit2size[22]=$(( $tmp + ${#BETA[9]} + ((4 - (${#BETA[9]} % 4)) % 4) ))
1517
1518  local i
1519  for i in {0..11} {22..22}
1520  do
1521    local descr="${desc/<n>/$i}"
1522
1523    if [[ "$1" == "encap" && $encap_tests != 0 ]]
1524    then
1525      log_test_skipped "${descr}"
1526      continue
1527    fi
1528
1529    ip -netns $ioam_node_alpha \
1530      route change 2001:db8:2::/64 \
1531      encap ioam6 mode $mode trace prealloc \
1532      type ${bit2type[$i]} ns $ns size ${bit2size[$i]} \
1533      via 2001:db8:1::1 dev veth0 &>/dev/null
1534
1535    if [ $? == 0 ]
1536    then
1537      run_test "input_bit$i" "${descr}" 2001:db8:1::2 \
1538        ${bit2type[$i]} ${bit2size[$i]} $ns $1
1539    else
1540      log_test_failed "${descr}"
1541    fi
1542  done
1543
1544  ip -netns $ioam_node_alpha \
1545    route change 2001:db8:2::/64 via 2001:db8:1::1 dev veth0 &>/dev/null
1546
1547  [ "$1" == "encap" ] && ip -netns $ioam_node_gamma \
1548    link set ip6tnl0 down &>/dev/null
1549
1550  bit2size[22]=$tmp
1551}
1552
1553input_sizes()
1554{
1555  ##############################################################################
1556  # Make sure an IOAM node handles all supported sizes correctly.              #
1557  ##############################################################################
1558  local desc="Trace Size of <n> bytes"
1559  local ns=123
1560  local tr_type=0x800000
1561  local mode="$1"
1562
1563  if [ "$1" == "encap" ]
1564  then
1565    mode+=" tundst 2001:db8:2::2"
1566    ip -netns $ioam_node_gamma link set ip6tnl0 up &>/dev/null
1567  fi
1568
1569  local i
1570  for i in $(seq 4 4 244)
1571  do
1572    local descr="${desc/<n>/$i}"
1573
1574    if [[ "$1" == "encap" && $encap_tests != 0 ]]
1575    then
1576      log_test_skipped "${descr}"
1577      continue
1578    fi
1579
1580    ip -netns $ioam_node_alpha \
1581      route change 2001:db8:2::/64 \
1582      encap ioam6 mode $mode trace prealloc type $tr_type ns $ns size $i \
1583      via 2001:db8:1::1 dev veth0 &>/dev/null
1584
1585    if [ $? == 0 ]
1586    then
1587      run_test "input_size$i" "${descr}" 2001:db8:1::2 $tr_type $i $ns $1
1588    else
1589      log_test_failed "${descr}"
1590    fi
1591  done
1592
1593  ip -netns $ioam_node_alpha \
1594    route change 2001:db8:2::/64 via 2001:db8:1::1 dev veth0 &>/dev/null
1595
1596  [ "$1" == "encap" ] && ip -netns $ioam_node_gamma \
1597    link set ip6tnl0 down &>/dev/null
1598}
1599
1600input_full_supp_trace()
1601{
1602  ##############################################################################
1603  # Make sure an IOAM node correctly fills a trace when all supported bits are #
1604  # set.                                                                       #
1605  ##############################################################################
1606  local desc="Full supported trace"
1607  local ns=123
1608  local tr_type=0xfff002
1609  local tr_size
1610  local mode="$1"
1611
1612  if [ "$1" == "encap" ]
1613  then
1614    if [ $encap_tests != 0 ]
1615    then
1616      log_test_skipped "${desc}"
1617      return
1618    fi
1619
1620    mode+=" tundst 2001:db8:2::2"
1621    ip -netns $ioam_node_gamma link set ip6tnl0 up &>/dev/null
1622  fi
1623
1624  local i
1625  tr_size=$(( ${#BETA[9]} + ((4 - (${#BETA[9]} % 4)) % 4) ))
1626  for i in {0..11} {22..22}
1627  do
1628    tr_size=$((tr_size + bit2size[$i]))
1629  done
1630
1631  ip -netns $ioam_node_alpha \
1632    route change 2001:db8:2::/64 \
1633    encap ioam6 mode $mode trace prealloc type $tr_type ns $ns size $tr_size \
1634    via 2001:db8:1::1 dev veth0 &>/dev/null
1635
1636  if [ $? == 0 ]
1637  then
1638    run_test ${FUNCNAME[0]} "${desc}" 2001:db8:1::2 $tr_type $tr_size $ns $1
1639  else
1640    log_test_failed "${desc}"
1641  fi
1642
1643  ip -netns $ioam_node_alpha \
1644    route change 2001:db8:2::/64 via 2001:db8:1::1 dev veth0 &>/dev/null
1645
1646  [ "$1" == "encap" ] && ip -netns $ioam_node_gamma \
1647    link set ip6tnl0 down &>/dev/null
1648}
1649
1650
1651################################################################################
1652#                                                                              #
1653#                                     MAIN                                     #
1654#                                                                              #
1655################################################################################
1656
1657npassed=0
1658nskipped=0
1659nfailed=0
1660
1661if [ "$(id -u)" -ne 0 ]
1662then
1663  echo "SKIP: Need root privileges."
1664  exit $ksft_skip
1665fi
1666
1667if [ ! -x "$(command -v ip)" ]
1668then
1669  echo "SKIP: Could not run test without ip tool."
1670  exit $ksft_skip
1671fi
1672
1673check_kernel_compatibility
1674setup
1675run
1676cleanup
1677
1678if [ $nfailed != 0 ]
1679then
1680  exit $ksft_fail
1681fi
1682
1683exit $ksft_pass
1684