1#!/bin/bash
2# SPDX-License-Identifier: GPL-2.0+
3#
4# Author: Justin Iurman <justin.iurman@uliege.be>
5#
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.
14#
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.
18#
19#
20#            +-------------------+            +-------------------+
21#            |                   |            |                   |
22#            |    Alpha netns    |            |    Gamma netns    |
23#            |                   |            |                   |
24#            |  +-------------+  |            |  +-------------+  |
25#            |  |    veth0    |  |            |  |    veth0    |  |
26#            |  |  db01::2/64 |  |            |  |  db02::2/64 |  |
27#            |  +-------------+  |            |  +-------------+  |
28#            |         .         |            |         .         |
29#            +-------------------+            +-------------------+
30#                      .                                .
31#                      .                                .
32#                      .                                .
33#            +----------------------------------------------------+
34#            |         .                                .         |
35#            |  +-------------+                  +-------------+  |
36#            |  |    veth0    |                  |    veth1    |  |
37#            |  |  db01::1/64 | ................ |  db02::1/64 |  |
38#            |  +-------------+                  +-------------+  |
39#            |                                                    |
40#            |                      Beta netns                    |
41#            |                                                    |
42#            +----------------------------------------------------+
43#
44#
45#
46#        =============================================================
47#        |                Alpha - IOAM configuration                 |
48#        +===========================================================+
49#        | Node ID             | 1                                   |
50#        +-----------------------------------------------------------+
51#        | Node Wide ID        | 11111111                            |
52#        +-----------------------------------------------------------+
53#        | Ingress ID          | 0xffff (default value)              |
54#        +-----------------------------------------------------------+
55#        | Ingress Wide ID     | 0xffffffff (default value)          |
56#        +-----------------------------------------------------------+
57#        | Egress ID           | 101                                 |
58#        +-----------------------------------------------------------+
59#        | Egress Wide ID      | 101101                              |
60#        +-----------------------------------------------------------+
61#        | Namespace Data      | 0xdeadbee0                          |
62#        +-----------------------------------------------------------+
63#        | Namespace Wide Data | 0xcafec0caf00dc0de                  |
64#        +-----------------------------------------------------------+
65#        | Schema ID           | 777                                 |
66#        +-----------------------------------------------------------+
67#        | Schema Data         | something that will be 4n-aligned   |
68#        +-----------------------------------------------------------+
69#
70#
71#        =============================================================
72#        |                 Beta - IOAM configuration                 |
73#        +===========================================================+
74#        | Node ID             | 2                                   |
75#        +-----------------------------------------------------------+
76#        | Node Wide ID        | 22222222                            |
77#        +-----------------------------------------------------------+
78#        | Ingress ID          | 201                                 |
79#        +-----------------------------------------------------------+
80#        | Ingress Wide ID     | 201201                              |
81#        +-----------------------------------------------------------+
82#        | Egress ID           | 202                                 |
83#        +-----------------------------------------------------------+
84#        | Egress Wide ID      | 202202                              |
85#        +-----------------------------------------------------------+
86#        | Namespace Data      | 0xdeadbee1                          |
87#        +-----------------------------------------------------------+
88#        | Namespace Wide Data | 0xcafec0caf11dc0de                  |
89#        +-----------------------------------------------------------+
90#        | Schema ID           | 666                                 |
91#        +-----------------------------------------------------------+
92#        | Schema Data         | Hello there -Obi                    |
93#        +-----------------------------------------------------------+
94#
95#
96#        =============================================================
97#        |                Gamma - IOAM configuration                 |
98#        +===========================================================+
99#        | Node ID             | 3                                   |
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#        +-----------------------------------------------------------+
117#        | Schema Data         |                                     |
118#        +-----------------------------------------------------------+
119
120
121################################################################################
122#                                                                              #
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.                                                   #
126#                                                                              #
127################################################################################
128
129ALPHA=(
130	1					# ID
131	11111111				# Wide ID
132	0xffff					# Ingress ID
133	0xffffffff				# Ingress Wide ID
134	101					# Egress 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
140)
141
142BETA=(
143	2
144	22222222
145	201
146	201201
147	202
148	202202
149	0xdeadbee1
150	0xcafec0caf11dc0de
151	666
152	"Hello there -Obi"
153)
154
155GAMMA=(
156	3
157	33333333
158	301
159	301301
160	0xffff
161	0xffffffff
162	0xdeadbee2
163	0xcafec0caf22dc0de
164	0xffffff
165	""
166)
167
168TESTS_OUTPUT="
169	out_undef_ns
170	out_no_room
171	out_bits
172	out_full_supp_trace
173"
174
175TESTS_INPUT="
176	in_undef_ns
177	in_no_room
178	in_oflag
179	in_bits
180	in_full_supp_trace
181"
182
183TESTS_GLOBAL="
184	fwd_full_supp_trace
185"
186
187
188################################################################################
189#                                                                              #
190#                                   LIBRARY                                    #
191#                                                                              #
192################################################################################
193
194check_kernel_compatibility()
195{
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
199
200  ip -netns ioam-tmp-node link set veth0 up
201  ip -netns ioam-tmp-node link set veth1 up
202
203  ip -netns ioam-tmp-node ioam namespace add 0
204  ns_ad=$?
205
206  ip -netns ioam-tmp-node ioam namespace show | grep -q "namespace 0"
207  ns_sh=$?
208
209  if [[ $ns_ad != 0 || $ns_sh != 0 ]]
210  then
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
214    exit 1
215  fi
216
217  ip -netns ioam-tmp-node route add db02::/64 encap ioam6 mode inline \
218         trace prealloc type 0x800000 ns 0 size 4 dev veth0
219  tr_ad=$?
220
221  ip -netns ioam-tmp-node -6 route | grep -q "encap ioam6"
222  tr_sh=$?
223
224  if [[ $tr_ad != 0 || $tr_sh != 0 ]]
225  then
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
230    exit 1
231  fi
232
233  ip link del veth0 2>/dev/null || true
234  ip netns del ioam-tmp-node || true
235
236  lsmod | grep -q "ip6_tunnel"
237  ip6tnl_loaded=$?
238
239  if [ $ip6tnl_loaded = 0 ]
240  then
241    encap_tests=0
242  else
243    modprobe ip6_tunnel &>/dev/null
244    lsmod | grep -q "ip6_tunnel"
245    encap_tests=$?
246
247    if [ $encap_tests != 0 ]
248    then
249      ip a | grep -q "ip6tnl0"
250      encap_tests=$?
251
252      if [ $encap_tests != 0 ]
253      then
254        echo "Note: ip6_tunnel not found neither as a module nor inside the" \
255             "kernel, tests that require it (encap mode) will be omitted"
256      fi
257    fi
258  fi
259}
260
261cleanup()
262{
263  ip link del ioam-veth-alpha 2>/dev/null || true
264  ip link del ioam-veth-gamma 2>/dev/null || true
265
266  ip netns del ioam-node-alpha || true
267  ip netns del ioam-node-beta || true
268  ip netns del ioam-node-gamma || true
269
270  if [ $ip6tnl_loaded != 0 ]
271  then
272    modprobe -r ip6_tunnel 2>/dev/null || true
273  fi
274}
275
276setup()
277{
278  ip netns add ioam-node-alpha
279  ip netns add ioam-node-beta
280  ip netns add ioam-node-gamma
281
282  ip link add name ioam-veth-alpha netns ioam-node-alpha type veth \
283         peer name ioam-veth-betaL netns ioam-node-beta
284  ip link add name ioam-veth-betaR netns ioam-node-beta type veth \
285         peer name ioam-veth-gamma netns ioam-node-gamma
286
287  ip -netns ioam-node-alpha link set ioam-veth-alpha name veth0
288  ip -netns ioam-node-beta link set ioam-veth-betaL name veth0
289  ip -netns ioam-node-beta link set ioam-veth-betaR name veth1
290  ip -netns ioam-node-gamma link set ioam-veth-gamma name veth0
291
292  ip -netns ioam-node-alpha addr add db01::2/64 dev veth0
293  ip -netns ioam-node-alpha link set veth0 up
294  ip -netns ioam-node-alpha link set lo up
295  ip -netns ioam-node-alpha route add db02::/64 via db01::1 dev veth0
296  ip -netns ioam-node-alpha route del db01::/64
297  ip -netns ioam-node-alpha route add db01::/64 dev veth0
298
299  ip -netns ioam-node-beta addr add db01::1/64 dev veth0
300  ip -netns ioam-node-beta addr add db02::1/64 dev veth1
301  ip -netns ioam-node-beta link set veth0 up
302  ip -netns ioam-node-beta link set veth1 up
303  ip -netns ioam-node-beta link set lo up
304
305  ip -netns ioam-node-gamma addr add db02::2/64 dev veth0
306  ip -netns ioam-node-gamma link set veth0 up
307  ip -netns ioam-node-gamma link set lo up
308  ip -netns ioam-node-gamma route add db01::/64 via db02::1 dev veth0
309
310  # - IOAM config -
311  ip netns exec ioam-node-alpha sysctl -wq net.ipv6.ioam6_id=${ALPHA[0]}
312  ip netns exec ioam-node-alpha sysctl -wq net.ipv6.ioam6_id_wide=${ALPHA[1]}
313  ip netns exec ioam-node-alpha sysctl -wq net.ipv6.conf.veth0.ioam6_id=${ALPHA[4]}
314  ip netns exec ioam-node-alpha sysctl -wq net.ipv6.conf.veth0.ioam6_id_wide=${ALPHA[5]}
315  ip -netns ioam-node-alpha ioam namespace add 123 data ${ALPHA[6]} wide ${ALPHA[7]}
316  ip -netns ioam-node-alpha ioam schema add ${ALPHA[8]} "${ALPHA[9]}"
317  ip -netns ioam-node-alpha ioam namespace set 123 schema ${ALPHA[8]}
318
319  ip netns exec ioam-node-beta sysctl -wq net.ipv6.conf.all.forwarding=1
320  ip netns exec ioam-node-beta sysctl -wq net.ipv6.ioam6_id=${BETA[0]}
321  ip netns exec ioam-node-beta sysctl -wq net.ipv6.ioam6_id_wide=${BETA[1]}
322  ip netns exec ioam-node-beta sysctl -wq net.ipv6.conf.veth0.ioam6_enabled=1
323  ip netns exec ioam-node-beta sysctl -wq net.ipv6.conf.veth0.ioam6_id=${BETA[2]}
324  ip netns exec ioam-node-beta sysctl -wq net.ipv6.conf.veth0.ioam6_id_wide=${BETA[3]}
325  ip netns exec ioam-node-beta sysctl -wq net.ipv6.conf.veth1.ioam6_id=${BETA[4]}
326  ip netns exec ioam-node-beta sysctl -wq net.ipv6.conf.veth1.ioam6_id_wide=${BETA[5]}
327  ip -netns ioam-node-beta ioam namespace add 123 data ${BETA[6]} wide ${BETA[7]}
328  ip -netns ioam-node-beta ioam schema add ${BETA[8]} "${BETA[9]}"
329  ip -netns ioam-node-beta ioam namespace set 123 schema ${BETA[8]}
330
331  ip netns exec ioam-node-gamma sysctl -wq net.ipv6.ioam6_id=${GAMMA[0]}
332  ip netns exec ioam-node-gamma sysctl -wq net.ipv6.ioam6_id_wide=${GAMMA[1]}
333  ip netns exec ioam-node-gamma sysctl -wq net.ipv6.conf.veth0.ioam6_enabled=1
334  ip netns exec ioam-node-gamma sysctl -wq net.ipv6.conf.veth0.ioam6_id=${GAMMA[2]}
335  ip netns exec ioam-node-gamma sysctl -wq net.ipv6.conf.veth0.ioam6_id_wide=${GAMMA[3]}
336  ip -netns ioam-node-gamma ioam namespace add 123 data ${GAMMA[6]} wide ${GAMMA[7]}
337
338  sleep 1
339
340  ip netns exec ioam-node-alpha ping6 -c 5 -W 1 db02::2 &>/dev/null
341  if [ $? != 0 ]
342  then
343    echo "Setup FAILED"
344    cleanup &>/dev/null
345    exit 0
346  fi
347}
348
349log_test_passed()
350{
351  local desc=$1
352  printf "TEST: %-60s  [ OK ]\n" "${desc}"
353}
354
355log_test_failed()
356{
357  local desc=$1
358  printf "TEST: %-60s  [FAIL]\n" "${desc}"
359}
360
361log_results()
362{
363  echo "- Tests passed: ${npassed}"
364  echo "- Tests failed: ${nfailed}"
365}
366
367run_test()
368{
369  local name=$1
370  local desc=$2
371  local node_src=$3
372  local node_dst=$4
373  local ip6_src=$5
374  local ip6_dst=$6
375  local if_dst=$7
376  local trace_type=$8
377  local ioam_ns=$9
378
379  ip netns exec $node_dst ./ioam6_parser $if_dst $name $ip6_src $ip6_dst \
380         $trace_type $ioam_ns &
381  local spid=$!
382  sleep 0.1
383
384  ip netns exec $node_src ping6 -t 64 -c 1 -W 1 $ip6_dst &>/dev/null
385  if [ $? != 0 ]
386  then
387    nfailed=$((nfailed+1))
388    log_test_failed "${desc}"
389    kill -2 $spid &>/dev/null
390  else
391    wait $spid
392    if [ $? = 0 ]
393    then
394      npassed=$((npassed+1))
395      log_test_passed "${desc}"
396    else
397      nfailed=$((nfailed+1))
398      log_test_failed "${desc}"
399    fi
400  fi
401}
402
403run()
404{
405  echo
406  printf "%0.s-" {1..74}
407  echo
408  echo "OUTPUT tests"
409  printf "%0.s-" {1..74}
410  echo
411
412  # set OUTPUT settings
413  ip netns exec ioam-node-beta sysctl -wq net.ipv6.conf.veth0.ioam6_enabled=0
414
415  for t in $TESTS_OUTPUT
416  do
417    $t "inline"
418    [ $encap_tests = 0 ] && $t "encap"
419  done
420
421  # clean OUTPUT settings
422  ip netns exec ioam-node-beta sysctl -wq net.ipv6.conf.veth0.ioam6_enabled=1
423  ip -netns ioam-node-alpha route change db01::/64 dev veth0
424
425
426  echo
427  printf "%0.s-" {1..74}
428  echo
429  echo "INPUT tests"
430  printf "%0.s-" {1..74}
431  echo
432
433  # set INPUT settings
434  ip -netns ioam-node-alpha ioam namespace del 123
435
436  for t in $TESTS_INPUT
437  do
438    $t "inline"
439    [ $encap_tests = 0 ] && $t "encap"
440  done
441
442  # clean INPUT settings
443  ip -netns ioam-node-alpha ioam namespace add 123 \
444         data ${ALPHA[6]} wide ${ALPHA[7]}
445  ip -netns ioam-node-alpha ioam namespace set 123 schema ${ALPHA[8]}
446  ip -netns ioam-node-alpha route change db01::/64 dev veth0
447
448  echo
449  printf "%0.s-" {1..74}
450  echo
451  echo "GLOBAL tests"
452  printf "%0.s-" {1..74}
453  echo
454
455  for t in $TESTS_GLOBAL
456  do
457    $t "inline"
458    [ $encap_tests = 0 ] && $t "encap"
459  done
460
461  echo
462  log_results
463}
464
465bit2type=(
466  0x800000 0x400000 0x200000 0x100000 0x080000 0x040000 0x020000 0x010000
467  0x008000 0x004000 0x002000 0x001000 0x000800 0x000400 0x000200 0x000100
468  0x000080 0x000040 0x000020 0x000010 0x000008 0x000004 0x000002
469)
470bit2size=( 4 4 4 4 4 4 4 4 8 8 8 4 4 4 4 4 4 4 4 4 4 4 4 )
471
472
473################################################################################
474#                                                                              #
475#                              OUTPUT tests                                    #
476#                                                                              #
477#   Two nodes (sender/receiver), IOAM disabled on ingress for the receiver.    #
478################################################################################
479
480out_undef_ns()
481{
482  ##############################################################################
483  # Make sure that the encap node won't fill the trace if the chosen IOAM      #
484  # namespace is not configured locally.                                       #
485  ##############################################################################
486  local desc="Unknown IOAM namespace"
487
488  [ "$1" = "encap" ] && mode="$1 tundst db01::1" || mode="$1"
489  [ "$1" = "encap" ] && ip -netns ioam-node-beta link set ip6tnl0 up
490
491  ip -netns ioam-node-alpha route change db01::/64 encap ioam6 mode $mode \
492         trace prealloc type 0x800000 ns 0 size 4 dev veth0
493
494  run_test ${FUNCNAME[0]} "${desc} ($1 mode)" ioam-node-alpha ioam-node-beta \
495         db01::2 db01::1 veth0 0x800000 0
496
497  [ "$1" = "encap" ] && ip -netns ioam-node-beta link set ip6tnl0 down
498}
499
500out_no_room()
501{
502  ##############################################################################
503  # Make sure that the encap node won't fill the trace and will set the        #
504  # Overflow flag since there is no room enough for its data.                  #
505  ##############################################################################
506  local desc="Missing trace room"
507
508  [ "$1" = "encap" ] && mode="$1 tundst db01::1" || mode="$1"
509  [ "$1" = "encap" ] && ip -netns ioam-node-beta link set ip6tnl0 up
510
511  ip -netns ioam-node-alpha route change db01::/64 encap ioam6 mode $mode \
512         trace prealloc type 0xc00000 ns 123 size 4 dev veth0
513
514  run_test ${FUNCNAME[0]} "${desc} ($1 mode)" ioam-node-alpha ioam-node-beta \
515         db01::2 db01::1 veth0 0xc00000 123
516
517  [ "$1" = "encap" ] && ip -netns ioam-node-beta link set ip6tnl0 down
518}
519
520out_bits()
521{
522  ##############################################################################
523  # Make sure that, for each trace type bit, the encap node will either:       #
524  #  (i)  fill the trace with its data when it is a supported bit              #
525  #  (ii) not fill the trace with its data when it is an unsupported bit       #
526  ##############################################################################
527  local desc="Trace type with bit <n> only"
528
529  local tmp=${bit2size[22]}
530  bit2size[22]=$(( $tmp + ${#ALPHA[9]} + ((4 - (${#ALPHA[9]} % 4)) % 4) ))
531
532  [ "$1" = "encap" ] && mode="$1 tundst db01::1" || mode="$1"
533  [ "$1" = "encap" ] && ip -netns ioam-node-beta link set ip6tnl0 up
534
535  for i in {0..22}
536  do
537    ip -netns ioam-node-alpha route change db01::/64 encap ioam6 mode $mode \
538           trace prealloc type ${bit2type[$i]} ns 123 size ${bit2size[$i]} \
539           dev veth0 &>/dev/null
540
541    local cmd_res=$?
542    local descr="${desc/<n>/$i}"
543
544    if [[ $i -ge 12 && $i -le 21 ]]
545    then
546      if [ $cmd_res != 0 ]
547      then
548        npassed=$((npassed+1))
549        log_test_passed "$descr"
550      else
551        nfailed=$((nfailed+1))
552        log_test_failed "$descr"
553      fi
554    else
555	run_test "out_bit$i" "$descr ($1 mode)" ioam-node-alpha \
556           ioam-node-beta db01::2 db01::1 veth0 ${bit2type[$i]} 123
557    fi
558  done
559
560  [ "$1" = "encap" ] && ip -netns ioam-node-beta link set ip6tnl0 down
561
562  bit2size[22]=$tmp
563}
564
565out_full_supp_trace()
566{
567  ##############################################################################
568  # Make sure that the encap node will correctly fill a full trace. Be careful,#
569  # "full trace" here does NOT mean all bits (only supported ones).            #
570  ##############################################################################
571  local desc="Full supported trace"
572
573  [ "$1" = "encap" ] && mode="$1 tundst db01::1" || mode="$1"
574  [ "$1" = "encap" ] && ip -netns ioam-node-beta link set ip6tnl0 up
575
576  ip -netns ioam-node-alpha route change db01::/64 encap ioam6 mode $mode \
577         trace prealloc type 0xfff002 ns 123 size 100 dev veth0
578
579  run_test ${FUNCNAME[0]} "${desc} ($1 mode)" ioam-node-alpha ioam-node-beta \
580         db01::2 db01::1 veth0 0xfff002 123
581
582  [ "$1" = "encap" ] && ip -netns ioam-node-beta link set ip6tnl0 down
583}
584
585
586################################################################################
587#                                                                              #
588#                               INPUT tests                                    #
589#                                                                              #
590#     Two nodes (sender/receiver), the sender MUST NOT fill the trace upon     #
591#     insertion -> the IOAM namespace configured on the sender is removed      #
592#     and is used in the inserted trace to force the sender not to fill it.    #
593################################################################################
594
595in_undef_ns()
596{
597  ##############################################################################
598  # Make sure that the receiving node won't fill the trace if the related IOAM #
599  # namespace is not configured locally.                                       #
600  ##############################################################################
601  local desc="Unknown IOAM namespace"
602
603  [ "$1" = "encap" ] && mode="$1 tundst db01::1" || mode="$1"
604  [ "$1" = "encap" ] && ip -netns ioam-node-beta link set ip6tnl0 up
605
606  ip -netns ioam-node-alpha route change db01::/64 encap ioam6 mode $mode \
607         trace prealloc type 0x800000 ns 0 size 4 dev veth0
608
609  run_test ${FUNCNAME[0]} "${desc} ($1 mode)" ioam-node-alpha ioam-node-beta \
610         db01::2 db01::1 veth0 0x800000 0
611
612  [ "$1" = "encap" ] && ip -netns ioam-node-beta link set ip6tnl0 down
613}
614
615in_no_room()
616{
617  ##############################################################################
618  # Make sure that the receiving node won't fill the trace and will set the    #
619  # Overflow flag if there is no room enough for its data.                     #
620  ##############################################################################
621  local desc="Missing trace room"
622
623  [ "$1" = "encap" ] && mode="$1 tundst db01::1" || mode="$1"
624  [ "$1" = "encap" ] && ip -netns ioam-node-beta link set ip6tnl0 up
625
626  ip -netns ioam-node-alpha route change db01::/64 encap ioam6 mode $mode \
627         trace prealloc type 0xc00000 ns 123 size 4 dev veth0
628
629  run_test ${FUNCNAME[0]} "${desc} ($1 mode)" ioam-node-alpha ioam-node-beta \
630         db01::2 db01::1 veth0 0xc00000 123
631
632  [ "$1" = "encap" ] && ip -netns ioam-node-beta link set ip6tnl0 down
633}
634
635in_bits()
636{
637  ##############################################################################
638  # Make sure that, for each trace type bit, the receiving node will either:   #
639  #  (i)  fill the trace with its data when it is a supported bit              #
640  #  (ii) not fill the trace with its data when it is an unsupported bit       #
641  ##############################################################################
642  local desc="Trace type with bit <n> only"
643
644  local tmp=${bit2size[22]}
645  bit2size[22]=$(( $tmp + ${#BETA[9]} + ((4 - (${#BETA[9]} % 4)) % 4) ))
646
647  [ "$1" = "encap" ] && mode="$1 tundst db01::1" || mode="$1"
648  [ "$1" = "encap" ] && ip -netns ioam-node-beta link set ip6tnl0 up
649
650  for i in {0..11} {22..22}
651  do
652    ip -netns ioam-node-alpha route change db01::/64 encap ioam6 mode $mode \
653           trace prealloc type ${bit2type[$i]} ns 123 size ${bit2size[$i]} \
654           dev veth0
655
656    run_test "in_bit$i" "${desc/<n>/$i} ($1 mode)" ioam-node-alpha \
657           ioam-node-beta db01::2 db01::1 veth0 ${bit2type[$i]} 123
658  done
659
660  [ "$1" = "encap" ] && ip -netns ioam-node-beta link set ip6tnl0 down
661
662  bit2size[22]=$tmp
663}
664
665in_oflag()
666{
667  ##############################################################################
668  # Make sure that the receiving node won't fill the trace since the Overflow  #
669  # flag is set.                                                               #
670  ##############################################################################
671  local desc="Overflow flag is set"
672
673  # Exception:
674  #   Here, we need the sender to set the Overflow flag. For that, we will add
675  #   back the IOAM namespace that was previously configured on the sender.
676  ip -netns ioam-node-alpha ioam namespace add 123
677
678  [ "$1" = "encap" ] && mode="$1 tundst db01::1" || mode="$1"
679  [ "$1" = "encap" ] && ip -netns ioam-node-beta link set ip6tnl0 up
680
681  ip -netns ioam-node-alpha route change db01::/64 encap ioam6 mode $mode \
682         trace prealloc type 0xc00000 ns 123 size 4 dev veth0
683
684  run_test ${FUNCNAME[0]} "${desc} ($1 mode)" ioam-node-alpha ioam-node-beta \
685         db01::2 db01::1 veth0 0xc00000 123
686
687  [ "$1" = "encap" ] && ip -netns ioam-node-beta link set ip6tnl0 down
688
689  # And we clean the exception for this test to get things back to normal for
690  # other INPUT tests
691  ip -netns ioam-node-alpha ioam namespace del 123
692}
693
694in_full_supp_trace()
695{
696  ##############################################################################
697  # Make sure that the receiving node will correctly fill a full trace. Be     #
698  # careful, "full trace" here does NOT mean all bits (only supported ones).   #
699  ##############################################################################
700  local desc="Full supported trace"
701
702  [ "$1" = "encap" ] && mode="$1 tundst db01::1" || mode="$1"
703  [ "$1" = "encap" ] && ip -netns ioam-node-beta link set ip6tnl0 up
704
705  ip -netns ioam-node-alpha route change db01::/64 encap ioam6 mode $mode \
706         trace prealloc type 0xfff002 ns 123 size 80 dev veth0
707
708  run_test ${FUNCNAME[0]} "${desc} ($1 mode)" ioam-node-alpha ioam-node-beta \
709         db01::2 db01::1 veth0 0xfff002 123
710
711  [ "$1" = "encap" ] && ip -netns ioam-node-beta link set ip6tnl0 down
712}
713
714
715################################################################################
716#                                                                              #
717#                              GLOBAL tests                                    #
718#                                                                              #
719#   Three nodes (sender/router/receiver), IOAM fully enabled on every node.    #
720################################################################################
721
722fwd_full_supp_trace()
723{
724  ##############################################################################
725  # Make sure that all three nodes correctly filled the full supported trace   #
726  # by checking that the trace data is consistent with the predefined config.  #
727  ##############################################################################
728  local desc="Forward - Full supported trace"
729
730  [ "$1" = "encap" ] && mode="$1 tundst db02::2" || mode="$1"
731  [ "$1" = "encap" ] && ip -netns ioam-node-gamma link set ip6tnl0 up
732
733  ip -netns ioam-node-alpha route change db02::/64 encap ioam6 mode $mode \
734         trace prealloc type 0xfff002 ns 123 size 244 via db01::1 dev veth0
735
736  run_test ${FUNCNAME[0]} "${desc} ($1 mode)" ioam-node-alpha ioam-node-gamma \
737         db01::2 db02::2 veth0 0xfff002 123
738
739  [ "$1" = "encap" ] && ip -netns ioam-node-gamma link set ip6tnl0 down
740}
741
742
743################################################################################
744#                                                                              #
745#                                     MAIN                                     #
746#                                                                              #
747################################################################################
748
749npassed=0
750nfailed=0
751
752if [ "$(id -u)" -ne 0 ]
753then
754  echo "SKIP: Need root privileges"
755  exit 1
756fi
757
758if [ ! -x "$(command -v ip)" ]
759then
760  echo "SKIP: Could not run test without ip tool"
761  exit 1
762fi
763
764ip ioam &>/dev/null
765if [ $? = 1 ]
766then
767  echo "SKIP: iproute2 too old, missing ioam command"
768  exit 1
769fi
770
771check_kernel_compatibility
772
773cleanup &>/dev/null
774setup
775run
776cleanup &>/dev/null
777