__  __    __   __  _____      _            _          _____ _          _ _ 
 |  \/  |   \ \ / / |  __ \    (_)          | |        / ____| |        | | |
 | \  / |_ __\ V /  | |__) | __ ___   ____ _| |_ ___  | (___ | |__   ___| | |
 | |\/| | '__|> <   |  ___/ '__| \ \ / / _` | __/ _ \  \___ \| '_ \ / _ \ | |
 | |  | | |_ / . \  | |   | |  | |\ V / (_| | ||  __/  ____) | | | |  __/ | |
 |_|  |_|_(_)_/ \_\ |_|   |_|  |_| \_/ \__,_|\__\___| |_____/|_| |_|\___V 2.1
 if you need WebShell for Seo everyday contact me on Telegram
 Telegram Address : @jackleet
        
        
For_More_Tools: Telegram: @jackleet | Bulk Smtp support mail sender | Business Mail Collector | Mail Bouncer All Mail | Bulk Office Mail Validator | Html Letter private



Upload:

Command:

[email protected]: ~ $
#!/bin/bash
# SPDX-License-Identifier: GPL-2.0+
#
# Author: Justin Iurman <[email protected]>
#
# This script evaluates IOAM for IPv6 by checking local IOAM configurations and
# IOAM data inside packets. There are three categories of tests: LOCAL, OUTPUT,
# and INPUT. The former (LOCAL) checks all IOAM related configurations locally
# without sending packets. OUTPUT tests verify the processing of an IOAM
# encapsulating node, while INPUT tests verify the processing of an IOAM transit
# node. Both OUTPUT and INPUT tests send packets. Each test is documented inside
# its own handler.
#
# The topology used for OUTPUT and INPUT tests is made of three nodes:
# - Alpha (the IOAM encapsulating node)
# - Beta  (the IOAM transit node)
# - Gamma (the receiver) **
#
# An IOAM domain is configured from Alpha to Beta, but not on the reverse path.
# Alpha adds an IOAM option (Pre-allocated Trace) inside a Hop-by-hop.
#
# ** Gamma is required because ioam6_parser.c uses a packet socket and we need
#    to see IOAM data inserted by the very last node (Beta), which would happen
#    _after_ we get a copy of the packet on Beta. Note that using an
#    IPv6 raw socket with IPV6_RECVHOPOPTS on Beta would not be enough: we also
#    need to access the IPv6 header to check some fields (e.g., source and
#    destination addresses), which is not possible in that case. As a
#    consequence, we need Gamma as a receiver to run ioam6_parser.c which uses a
#    packet socket.
#
#
#         +-----------------------+          +-----------------------+
#         |                       |          |                       |
#         |      Alpha netns      |          |      Gamma netns      |
#         |                       |          |                       |
#         | +-------------------+ |          | +-------------------+ |
#         | |       veth0       | |          | |       veth0       | |
#         | | 2001:db8:1::2/64  | |          | | 2001:db8:2::2/64  | |
#         | +-------------------+ |          | +-------------------+ |
#         |           .           |          |           .           |
#         +-----------.-----------+          +-----------.-----------+
#                     .                                  .
#                     .                                  .
#                     .                                  .
#         +-----------.----------------------------------.-----------+
#         |           .                                  .           |
#         | +-------------------+              +-------------------+ |
#         | |       veth0       |              |       veth1       | |
#         | | 2001:db8:1::1/64  | ............ | 2001:db8:2::1/64  | |
#         | +-------------------+              +-------------------+ |
#         |                                                          |
#         |                        Beta netns                        |
#         |                                                          |
#         +----------------------------------------------------------+
#
#
#
#         +==========================================================+
#         |                Alpha - IOAM configuration                |
#         +=====================+====================================+
#         | Node ID             | 1                                  |
#         +---------------------+------------------------------------+
#         | Node Wide ID        | 11111111                           |
#         +---------------------+------------------------------------+
#         | Ingress ID          | 0xffff (default value)             |
#         +---------------------+------------------------------------+
#         | Ingress Wide ID     | 0xffffffff (default value)         |
#         +---------------------+------------------------------------+
#         | Egress ID           | 101                                |
#         +---------------------+------------------------------------+
#         | Egress Wide ID      | 101101                             |
#         +---------------------+------------------------------------+
#         | Namespace Data      | 0xdeadbeef                         |
#         +---------------------+------------------------------------+
#         | Namespace Wide Data | 0xcafec0caf00dc0de                 |
#         +---------------------+------------------------------------+
#         | Schema ID           | 777                                |
#         +---------------------+------------------------------------+
#         | Schema Data         | something that will be 4n-aligned  |
#         +---------------------+------------------------------------+
#
#
#         +==========================================================+
#         |                 Beta - IOAM configuration                |
#         +=====================+====================================+
#         | Node ID             | 2                                  |
#         +---------------------+------------------------------------+
#         | Node Wide ID        | 22222222                           |
#         +---------------------+------------------------------------+
#         | Ingress ID          | 201                                |
#         +---------------------+------------------------------------+
#         | Ingress Wide ID     | 201201                             |
#         +---------------------+------------------------------------+
#         | Egress ID           | 202                                |
#         +---------------------+------------------------------------+
#         | Egress Wide ID      | 202202                             |
#         +---------------------+------------------------------------+
#         | Namespace Data      | 0xffffffff (default value)         |
#         +---------------------+------------------------------------+
#         | Namespace Wide Data | 0xffffffffffffffff (default value) |
#         +---------------------+------------------------------------+
#         | Schema ID           | 0xffffff (= None)                  |
#         +---------------------+------------------------------------+
#         | Schema Data         |                                    |
#         +---------------------+------------------------------------+

source lib.sh

################################################################################
#                                                                              #
# WARNING: Be careful if you modify the block below - it MUST be kept          #
#          synchronized with configurations inside ioam6_parser.c and always   #
#          reflect the same.                                                   #
#                                                                              #
################################################################################

ALPHA=(
  1                                    # ID
  11111111                             # Wide ID
  0xffff                               # Ingress ID (default value)
  0xffffffff                           # Ingress Wide ID (default value)
  101                                  # Egress ID
  101101                               # Egress Wide ID
  0xdeadbeef                           # Namespace Data
  0xcafec0caf00dc0de                   # Namespace Wide Data
  777                                  # Schema ID
  "something that will be 4n-aligned"  # Schema Data
)

BETA=(
  2                                    # ID
  22222222                             # Wide ID
  201                                  # Ingress ID
  201201                               # Ingress Wide ID
  202                                  # Egress ID
  202202                               # Egress Wide ID
  0xffffffff                           # Namespace Data (empty value)
  0xffffffffffffffff                   # Namespace Wide Data (empty value)
  0xffffff                             # Schema ID (empty value)
  ""                                   # Schema Data (empty value)
)

TESTS_LOCAL="
  local_sysctl_ioam_id
  local_sysctl_ioam_id_wide
  local_sysctl_ioam_intf_id
  local_sysctl_ioam_intf_id_wide
  local_sysctl_ioam_intf_enabled
  local_ioam_namespace
  local_ioam_schema
  local_ioam_schema_namespace
  local_route_ns
  local_route_tunsrc
  local_route_tundst
  local_route_trace_type
  local_route_trace_size
  local_route_trace_type_bits
  local_route_trace_size_values
"

TESTS_OUTPUT="
  output_undef_ns
  output_no_room
  output_no_room_oss
  output_bits
  output_sizes
  output_full_supp_trace
"

TESTS_INPUT="
  input_undef_ns
  input_no_room
  input_no_room_oss
  input_disabled
  input_oflag
  input_bits
  input_sizes
  input_full_supp_trace
"

################################################################################
#                                                                              #
#                                   LIBRARY                                    #
#                                                                              #
################################################################################

check_kernel_compatibility()
{
  setup_ns ioam_tmp_node &>/dev/null
  local ret=$?

  ip link add name veth0 netns $ioam_tmp_node type veth \
    peer name veth1 netns $ioam_tmp_node &>/dev/null
  ret=$((ret + $?))

  ip -netns $ioam_tmp_node link set veth0 up &>/dev/null
  ret=$((ret + $?))

  ip -netns $ioam_tmp_node link set veth1 up &>/dev/null
  ret=$((ret + $?))

  if [ $ret != 0 ]
  then
    echo "SKIP: Setup failed."
    cleanup_ns $ioam_tmp_node
    exit $ksft_skip
  fi

  ip -netns $ioam_tmp_node route add 2001:db8:2::/64 \
    encap ioam6 trace prealloc type 0x800000 ns 0 size 4 dev veth0 &>/dev/null
  ret=$?

  ip -netns $ioam_tmp_node -6 route 2>/dev/null | grep -q "encap ioam6"
  ret=$((ret + $?))

  if [ $ret != 0 ]
  then
    echo "SKIP: Cannot attach an IOAM trace to a route. Was your kernel" \
         "compiled without CONFIG_IPV6_IOAM6_LWTUNNEL? Are you running an" \
         "old kernel? Are you using an old version of iproute2?"
    cleanup_ns $ioam_tmp_node
    exit $ksft_skip
  fi

  cleanup_ns $ioam_tmp_node

  lsmod 2>/dev/null | grep -q "ip6_tunnel"
  ip6tnl_loaded=$?

  if [ $ip6tnl_loaded == 0 ]
  then
    encap_tests=0
  else
    modprobe ip6_tunnel &>/dev/null
    lsmod 2>/dev/null | grep -q "ip6_tunnel"
    encap_tests=$?

    if [ $encap_tests != 0 ]
    then
      ip a 2>/dev/null | grep -q "ip6tnl0"
      encap_tests=$?

      if [ $encap_tests != 0 ]
      then
        echo "Note: ip6_tunnel not found neither as a module nor inside the" \
             "kernel. Any tests that require it will be skipped."
      fi
    fi
  fi
}

cleanup()
{
  cleanup_ns $ioam_node_alpha $ioam_node_beta $ioam_node_gamma

  if [ $ip6tnl_loaded != 0 ]
  then
    modprobe -r ip6_tunnel &>/dev/null
  fi
}

setup()
{
  setup_ns ioam_node_alpha ioam_node_beta ioam_node_gamma &>/dev/null

  ip link add name ioam-veth-alpha netns $ioam_node_alpha type veth \
    peer name ioam-veth-betaL netns $ioam_node_beta &>/dev/null
  ip link add name ioam-veth-betaR netns $ioam_node_beta type veth \
    peer name ioam-veth-gamma netns $ioam_node_gamma &>/dev/null

  ip -netns $ioam_node_alpha link set ioam-veth-alpha name veth0 &>/dev/null
  ip -netns $ioam_node_beta link set ioam-veth-betaL name veth0 &>/dev/null
  ip -netns $ioam_node_beta link set ioam-veth-betaR name veth1 &>/dev/null
  ip -netns $ioam_node_gamma link set ioam-veth-gamma name veth0 &>/dev/null

  ip -netns $ioam_node_alpha addr add 2001:db8:1::50/64 dev veth0 &>/dev/null
  ip -netns $ioam_node_alpha addr add 2001:db8:1::2/64 dev veth0 &>/dev/null
  ip -netns $ioam_node_alpha link set veth0 up &>/dev/null
  ip -netns $ioam_node_alpha link set lo up &>/dev/null
  ip -netns $ioam_node_alpha route add 2001:db8:2::/64 \
    via 2001:db8:1::1 dev veth0 &>/dev/null

  ip -netns $ioam_node_beta addr add 2001:db8:1::1/64 dev veth0 &>/dev/null
  ip -netns $ioam_node_beta addr add 2001:db8:2::1/64 dev veth1 &>/dev/null
  ip -netns $ioam_node_beta link set veth0 up &>/dev/null
  ip -netns $ioam_node_beta link set veth1 up &>/dev/null
  ip -netns $ioam_node_beta link set lo up &>/dev/null

  ip -netns $ioam_node_gamma addr add 2001:db8:2::2/64 dev veth0 &>/dev/null
  ip -netns $ioam_node_gamma link set veth0 up &>/dev/null
  ip -netns $ioam_node_gamma link set lo up &>/dev/null
  ip -netns $ioam_node_gamma route add 2001:db8:1::/64 \
    via 2001:db8:2::1 dev veth0 &>/dev/null

  # - Alpha: IOAM config -
  ip netns exec $ioam_node_alpha \
    sysctl -wq net.ipv6.ioam6_id=${ALPHA[0]} &>/dev/null
  ip netns exec $ioam_node_alpha \
    sysctl -wq net.ipv6.ioam6_id_wide=${ALPHA[1]} &>/dev/null
  ip netns exec $ioam_node_alpha \
    sysctl -wq net.ipv6.conf.veth0.ioam6_id=${ALPHA[4]} &>/dev/null
  ip netns exec $ioam_node_alpha \
    sysctl -wq net.ipv6.conf.veth0.ioam6_id_wide=${ALPHA[5]} &>/dev/null
  ip -netns $ioam_node_alpha \
    ioam namespace add 123 data ${ALPHA[6]} wide ${ALPHA[7]} &>/dev/null
  ip -netns $ioam_node_alpha \
    ioam schema add ${ALPHA[8]} "${ALPHA[9]}" &>/dev/null
  ip -netns $ioam_node_alpha \
    ioam namespace set 123 schema ${ALPHA[8]} &>/dev/null

  # - Beta: IOAM config -
  ip netns exec $ioam_node_beta \
    sysctl -wq net.ipv6.conf.all.forwarding=1 &>/dev/null
  ip netns exec $ioam_node_beta \
    sysctl -wq net.ipv6.ioam6_id=${BETA[0]} &>/dev/null
  ip netns exec $ioam_node_beta \
    sysctl -wq net.ipv6.ioam6_id_wide=${BETA[1]} &>/dev/null
  ip netns exec $ioam_node_beta \
    sysctl -wq net.ipv6.conf.veth0.ioam6_enabled=1 &>/dev/null
  ip netns exec $ioam_node_beta \
    sysctl -wq net.ipv6.conf.veth0.ioam6_id=${BETA[2]} &>/dev/null
  ip netns exec $ioam_node_beta \
    sysctl -wq net.ipv6.conf.veth0.ioam6_id_wide=${BETA[3]} &>/dev/null
  ip netns exec $ioam_node_beta \
    sysctl -wq net.ipv6.conf.veth1.ioam6_id=${BETA[4]} &>/dev/null
  ip netns exec $ioam_node_beta \
    sysctl -wq net.ipv6.conf.veth1.ioam6_id_wide=${BETA[5]} &>/dev/null
  ip -netns $ioam_node_beta ioam namespace add 123 &>/dev/null

  sleep 1

  ip netns exec $ioam_node_alpha ping6 -c 5 -W 1 2001:db8:2::2 &>/dev/null
  if [ $? != 0 ]
  then
    echo "SKIP: Setup failed."
    cleanup
    exit $ksft_skip
  fi
}

log_test_passed()
{
  printf " - TEST: %-57s  [ OK ]\n" "$1"
  npassed=$((npassed+1))
}

log_test_skipped()
{
  printf " - TEST: %-57s  [SKIP]\n" "$1"
  nskipped=$((nskipped+1))
}

log_test_failed()
{
  printf " - TEST: %-57s  [FAIL]\n" "$1"
  nfailed=$((nfailed+1))
}

run_test()
{
  local name=$1
  local desc=$2
  local ip6_src=$3
  local trace_type=$4
  local trace_size=$5
  local ioam_ns=$6
  local type=$7

  ip netns exec $ioam_node_gamma \
    ./ioam6_parser veth0 $name $ip6_src 2001:db8:2::2 \
                   $trace_type $trace_size $ioam_ns $type &
  local spid=$!
  sleep 0.1

  ip netns exec $ioam_node_alpha ping6 -t 64 -c 1 -W 1 2001:db8:2::2 &>/dev/null
  if [ $? != 0 ]
  then
    log_test_failed "${desc}"
    kill -2 $spid &>/dev/null
  else
    wait $spid
    [ $? == 0 ] && log_test_passed "${desc}" || log_test_failed "${desc}"
  fi
}

run()
{
  local test

  echo
  printf "+"
  printf "%0.s-" {1..72}
  printf "+"
  echo
  printf "| %-28s LOCAL tests %-29s |"
  echo
  printf "+"
  printf "%0.s-" {1..72}
  printf "+"
  echo

  echo
  echo "Global config"
  for test in $TESTS_LOCAL
  do
    $test
  done

  echo
  echo "Inline mode"
  for test in $TESTS_LOCAL
  do
    $test "inline"
  done

  echo
  echo "Encap mode"
  for test in $TESTS_LOCAL
  do
    $test "encap"
  done

  echo
  printf "+"
  printf "%0.s-" {1..72}
  printf "+"
  echo
  printf "| %-28s OUTPUT tests %-28s |"
  echo
  printf "+"
  printf "%0.s-" {1..72}
  printf "+"
  echo

  # set OUTPUT settings
  ip netns exec $ioam_node_beta \
    sysctl -wq net.ipv6.conf.veth0.ioam6_enabled=0 &>/dev/null

  echo
  echo "Inline mode"
  for test in $TESTS_OUTPUT
  do
    $test "inline"
  done

  echo
  echo "Encap mode"
  for test in $TESTS_OUTPUT
  do
    $test "encap"
  done

  echo
  echo "Encap mode (with tunsrc)"
  for test in $TESTS_OUTPUT
  do
    $test "encap" "tunsrc"
  done

  # clean OUTPUT settings
  ip netns exec $ioam_node_beta \
    sysctl -wq net.ipv6.conf.veth0.ioam6_enabled=1 &>/dev/null

  echo
  printf "+"
  printf "%0.s-" {1..72}
  printf "+"
  echo
  printf "| %-28s INPUT tests %-29s |"
  echo
  printf "+"
  printf "%0.s-" {1..72}
  printf "+"
  echo

  # set INPUT settings
  ip -netns $ioam_node_alpha ioam namespace del 123 &>/dev/null

  echo
  echo "Inline mode"
  for test in $TESTS_INPUT
  do
    $test "inline"
  done

  echo
  echo "Encap mode"
  for test in $TESTS_INPUT
  do
    $test "encap"
  done

  # clean INPUT settings
  ip -netns $ioam_node_alpha \
    ioam namespace add 123 data ${ALPHA[6]} wide ${ALPHA[7]} &>/dev/null
  ip -netns $ioam_node_alpha \
    ioam namespace set 123 schema ${ALPHA[8]} &>/dev/null

  echo
  printf "+"
  printf "%0.s-" {1..72}
  printf "+"
  echo
  printf "| %-30s Results %-31s |"
  echo
  printf "+"
  printf "%0.s-" {1..72}
  printf "+"
  echo

  echo
  echo "- Passed:  ${npassed}"
  echo "- Skipped: ${nskipped}"
  echo "- Failed:  ${nfailed}"
  echo
}

bit2type=(
  0x800000 0x400000 0x200000 0x100000 0x080000 0x040000 0x020000 0x010000
  0x008000 0x004000 0x002000 0x001000 0x000800 0x000400 0x000200 0x000100
  0x000080 0x000040 0x000020 0x000010 0x000008 0x000004 0x000002 0x000001
)
bit2size=( 4 4 4 4 4 4 4 4 8 8 8 4 4 4 4 4 4 4 4 4 4 4 4 0 )


################################################################################
#                                                                              #
#                                 LOCAL tests                                  #
#                                                                              #
################################################################################

local_sysctl_ioam_id()
{
  ##############################################################################
  # Make sure the sysctl "net.ipv6.ioam6_id" works as expected.                #
  ##############################################################################
  local desc="Sysctl net.ipv6.ioam6_id"

  [ ! -z $1 ] && return

  ip netns exec $ioam_node_alpha \
    sysctl net.ipv6.ioam6_id 2>/dev/null | grep -wq ${ALPHA[0]}

  [ $? == 0 ] && log_test_passed "${desc}" || log_test_failed "${desc}"
}

local_sysctl_ioam_id_wide()
{
  ##############################################################################
  # Make sure the sysctl "net.ipv6.ioam6_id_wide" works as expected.           #
  ##############################################################################
  local desc="Sysctl net.ipv6.ioam6_id_wide"

  [ ! -z $1 ] && return

  ip netns exec $ioam_node_alpha \
    sysctl net.ipv6.ioam6_id_wide 2>/dev/null | grep -wq ${ALPHA[1]}

  [ $? == 0 ] && log_test_passed "${desc}" || log_test_failed "${desc}"
}

local_sysctl_ioam_intf_id()
{
  ##############################################################################
  # Make sure the sysctl "net.ipv6.conf.XX.ioam6_id" works as expected.        #
  ##############################################################################
  local desc="Sysctl net.ipv6.conf.XX.ioam6_id"

  [ ! -z $1 ] && return

  ip netns exec $ioam_node_alpha \
    sysctl net.ipv6.conf.veth0.ioam6_id 2>/dev/null | grep -wq ${ALPHA[4]}

  [ $? == 0 ] && log_test_passed "${desc}" || log_test_failed "${desc}"
}

local_sysctl_ioam_intf_id_wide()
{
  ##############################################################################
  # Make sure the sysctl "net.ipv6.conf.XX.ioam6_id_wide" works as expected.   #
  ##############################################################################
  local desc="Sysctl net.ipv6.conf.XX.ioam6_id_wide"

  [ ! -z $1 ] && return

  ip netns exec $ioam_node_alpha \
    sysctl net.ipv6.conf.veth0.ioam6_id_wide 2>/dev/null | grep -wq ${ALPHA[5]}

  [ $? == 0 ] && log_test_passed "${desc}" || log_test_failed "${desc}"
}

local_sysctl_ioam_intf_enabled()
{
  ##############################################################################
  # Make sure the sysctl "net.ipv6.conf.XX.ioam6_enabled" works as expected.   #
  ##############################################################################
  local desc="Sysctl net.ipv6.conf.XX.ioam6_enabled"

  [ ! -z $1 ] && return

  ip netns exec $ioam_node_beta \
    sysctl net.ipv6.conf.veth0.ioam6_enabled 2>/dev/null | grep -wq 1

  [ $? == 0 ] && log_test_passed "${desc}" || log_test_failed "${desc}"
}

local_ioam_namespace()
{
  ##############################################################################
  # Make sure the creation of an IOAM Namespace works as expected.             #
  ##############################################################################
  local desc="Create an IOAM Namespace"

  [ ! -z $1 ] && return

  ip -netns $ioam_node_alpha \
    ioam namespace show 2>/dev/null | grep -wq 123
  local ret=$?

  ip -netns $ioam_node_alpha \
    ioam namespace show 2>/dev/null | grep -wq ${ALPHA[6]}
  ret=$((ret + $?))

  ip -netns $ioam_node_alpha \
    ioam namespace show 2>/dev/null | grep -wq ${ALPHA[7]}
  ret=$((ret + $?))

  [ $ret == 0 ] && log_test_passed "${desc}" || log_test_failed "${desc}"
}

local_ioam_schema()
{
  ##############################################################################
  # Make sure the creation of an IOAM Schema works as expected.                #
  ##############################################################################
  local desc="Create an IOAM Schema"

  [ ! -z $1 ] && return

  ip -netns $ioam_node_alpha \
    ioam schema show 2>/dev/null | grep -wq ${ALPHA[8]}
  local ret=$?

  local sc_data=$(
    for i in `seq 0 $((${#ALPHA[9]}-1))`
    do
      chr=${ALPHA[9]:i:1}
      printf "%x " "'${chr}"
    done
  )

  ip -netns $ioam_node_alpha \
    ioam schema show 2>/dev/null | grep -q "$sc_data"
  ret=$((ret + $?))

  [ $ret == 0 ] && log_test_passed "${desc}" || log_test_failed "${desc}"
}

local_ioam_schema_namespace()
{
  ##############################################################################
  # Make sure the binding of a Schema to a Namespace works as expected.        #
  ##############################################################################
  local desc="Bind an IOAM Schema to an IOAM Namespace"

  [ ! -z $1 ] && return

  ip -netns $ioam_node_alpha \
    ioam namespace show 2>/dev/null | grep -wq ${ALPHA[8]}
  local ret=$?

  ip -netns $ioam_node_alpha \
    ioam schema show 2>/dev/null | grep -wq 123
  ret=$((ret + $?))

  [ $ret == 0 ] && log_test_passed "${desc}" || log_test_failed "${desc}"
}

local_route_ns()
{
  ##############################################################################
  # Make sure the Namespace-ID is always provided, whatever the mode.          #
  ##############################################################################
  local desc="Mandatory Namespace-ID"
  local mode

  [ -z $1 ] && return

  [ "$1" == "encap" ] && mode="$1 tundst 2001:db8:2::2" || mode="$1"

  ip -netns $ioam_node_alpha \
    route change 2001:db8:2::/64 \
    encap ioam6 mode $mode trace prealloc type 0x800000 size 4 \
    via 2001:db8:1::1 dev veth0 &>/dev/null
  local ret1=$?

  ip -netns $ioam_node_alpha \
    route change 2001:db8:2::/64 \
    encap ioam6 mode $mode trace prealloc type 0x800000 ns 0 size 4 \
    via 2001:db8:1::1 dev veth0 &>/dev/null
  local ret2=$?

  [[ $ret1 == 0 || $ret2 != 0 ]] && log_test_failed "${desc}" \
                                 || log_test_passed "${desc}"

  ip -netns $ioam_node_alpha \
    route change 2001:db8:2::/64 via 2001:db8:1::1 dev veth0 &>/dev/null
}

local_route_tunsrc()
{
  ##############################################################################
  # Make sure the Tunnel Source is only (and possibly) used with encap mode.   #
  ##############################################################################
  local desc
  local mode
  local mode_tunsrc

  [ -z $1 ] && return

  if [ "$1" == "encap" ]
  then
    desc="Optional Tunnel Source"
    mode="$1 tundst 2001:db8:2::2"
    mode_tunsrc="$1 tunsrc 2001:db8:1::50 tundst 2001:db8:2::2"
  else
    desc="Unneeded Tunnel Source"
    mode="$1"
    mode_tunsrc="$1 tunsrc 2001:db8:1::50"
  fi

  ip -netns $ioam_node_alpha \
    route change 2001:db8:2::/64 \
    encap ioam6 mode $mode trace prealloc type 0x800000 ns 0 size 4 \
    via 2001:db8:1::1 dev veth0 &>/dev/null
  local ret1=$?

  ip -netns $ioam_node_alpha \
    route change 2001:db8:2::/64 \
    encap ioam6 mode $mode_tunsrc trace prealloc type 0x800000 ns 0 size 4 \
    via 2001:db8:1::1 dev veth0 &>/dev/null
  local ret2=$?

  if [ "$1" == "encap" ]
  then
    [[ $ret1 != 0 || $ret2 != 0 ]] && log_test_failed "${desc}" \
                                   || log_test_passed "${desc}"
  else
    [[ $ret1 != 0 || $ret2 == 0 ]] && log_test_failed "${desc}" \
                                   || log_test_passed "${desc}"
  fi

  ip -netns $ioam_node_alpha \
    route change 2001:db8:2::/64 via 2001:db8:1::1 dev veth0 &>/dev/null
}

local_route_tundst()
{
  ##############################################################################
  # Make sure the Tunnel Destination is only (and always) used with encap mode.#
  ##############################################################################
  local desc

  [ -z $1 ] && return

  [ "$1" == "encap" ] && desc="Mandatory Tunnel Destination" \
                     || desc="Unneeded Tunnel Destination"

  local mode="$1"
  local mode_tundst="$1 tundst 2001:db8:2::2"

  ip -netns $ioam_node_alpha \
    route change 2001:db8:2::/64 \
    encap ioam6 mode $mode trace prealloc type 0x800000 ns 0 size 4 \
    via 2001:db8:1::1 dev veth0 &>/dev/null
  local ret1=$?

  ip -netns $ioam_node_alpha \
    route change 2001:db8:2::/64 \
    encap ioam6 mode $mode_tundst trace prealloc type 0x800000 ns 0 size 4 \
    via 2001:db8:1::1 dev veth0 &>/dev/null
  local ret2=$?

  if [ "$1" == "encap" ]
  then
    [[ $ret1 == 0 || $ret2 != 0 ]] && log_test_failed "${desc}" \
                                   || log_test_passed "${desc}"
  else
    [[ $ret1 != 0 || $ret2 == 0 ]] && log_test_failed "${desc}" \
                                   || log_test_passed "${desc}"
  fi

  ip -netns $ioam_node_alpha \
    route change 2001:db8:2::/64 via 2001:db8:1::1 dev veth0 &>/dev/null
}

local_route_trace_type()
{
  ##############################################################################
  # Make sure the Trace Type is always provided, whatever the mode.            #
  ##############################################################################
  local desc="Mandatory Trace Type"
  local mode

  [ -z $1 ] && return

  [ "$1" == "encap" ] && mode="$1 tundst 2001:db8:2::2" || mode="$1"

  ip -netns $ioam_node_alpha \
    route change 2001:db8:2::/64 \
    encap ioam6 mode $mode trace prealloc ns 0 size 4 \
    via 2001:db8:1::1 dev veth0 &>/dev/null
  local ret1=$?

  ip -netns $ioam_node_alpha \
    route change 2001:db8:2::/64 \
    encap ioam6 mode $mode trace prealloc type 0x800000 ns 0 size 4 \
    via 2001:db8:1::1 dev veth0 &>/dev/null
  local ret2=$?

  [[ $ret1 == 0 || $ret2 != 0 ]] && log_test_failed "${desc}" \
                                 || log_test_passed "${desc}"

  ip -netns $ioam_node_alpha \
    route change 2001:db8:2::/64 via 2001:db8:1::1 dev veth0 &>/dev/null
}

local_route_trace_size()
{
  ##############################################################################
  # Make sure the Trace Size is always provided, whatever the mode.            #
  ##############################################################################
  local desc="Mandatory Trace Size"
  local mode

  [ -z $1 ] && return

  [ "$1" == "encap" ] && mode="$1 tundst 2001:db8:2::2" || mode="$1"

  ip -netns $ioam_node_alpha \
    route change 2001:db8:2::/64 \
    encap ioam6 mode $mode trace prealloc type 0x800000 ns 0 \
    via 2001:db8:1::1 dev veth0 &>/dev/null
  local ret1=$?

  ip -netns $ioam_node_alpha \
    route change 2001:db8:2::/64 \
    encap ioam6 mode $mode trace prealloc type 0x800000 ns 0 size 4 \
    via 2001:db8:1::1 dev veth0 &>/dev/null
  local ret2=$?

  [[ $ret1 == 0 || $ret2 != 0 ]] && log_test_failed "${desc}" \
                                 || log_test_passed "${desc}"

  ip -netns $ioam_node_alpha \
    route change 2001:db8:2::/64 via 2001:db8:1::1 dev veth0 &>/dev/null
}

local_route_trace_type_bits()
{
  ##############################################################################
  # Make sure only allowed bits (0-11 and 22) are accepted.                    #
  ##############################################################################
  local desc="Trace Type bits"
  local mode

  [ -z $1 ] && return

  [ "$1" == "encap" ] && mode="$1 tundst 2001:db8:2::2" || mode="$1"

  local i
  for i in {0..23}
  do
    ip -netns $ioam_node_alpha \
      route change 2001:db8:2::/64 \
      encap ioam6 mode $mode trace prealloc type ${bit2type[$i]} ns 0 size 4 \
      via 2001:db8:1::1 dev veth0 &>/dev/null

    if [[ ($? == 0 && (($i -ge 12 && $i -le 21) || $i == 23)) ||
          ($? != 0 && (($i -ge 0 && $i -le 11) || $i == 22)) ]]
    then
      local err=1
      break
    fi
  done

  [ -z $err ] && log_test_passed "${desc}" || log_test_failed "${desc}"

  ip -netns $ioam_node_alpha \
    route change 2001:db8:2::/64 via 2001:db8:1::1 dev veth0 &>/dev/null
}

local_route_trace_size_values()
{
  ##############################################################################
  # Make sure only allowed sizes (multiples of four in [4,244]) are accepted.  #
  ##############################################################################
  local desc="Trace Size values"
  local mode

  [ -z $1 ] && return

  [ "$1" == "encap" ] && mode="$1 tundst 2001:db8:2::2" || mode="$1"

  # we also try the next multiple of four after the MAX to check it's refused
  local i
  for i in {0..248}
  do
    ip -netns $ioam_node_alpha \
      route change 2001:db8:2::/64 \
      encap ioam6 mode $mode trace prealloc type 0x800000 ns 0 size $i \
      via 2001:db8:1::1 dev veth0 &>/dev/null

    if [[ ($? == 0 && ($i == 0 || $i == 248 || $(( $i % 4 )) != 0)) ||
          ($? != 0 && $i != 0 && $i != 248 && $(( $i % 4 )) == 0) ]]
    then
      local err=1
      break
    fi
  done

  [ -z $err ] && log_test_passed "${desc}" || log_test_failed "${desc}"

  ip -netns $ioam_node_alpha \
    route change 2001:db8:2::/64 via 2001:db8:1::1 dev veth0 &>/dev/null
}


################################################################################
#                                                                              #
#                                 OUTPUT tests                                 #
#                                                                              #
################################################################################

output_undef_ns()
{
  ##############################################################################
  # Make sure an IOAM encapsulating node does NOT fill the trace when the      #
  # corresponding IOAM Namespace-ID is not configured locally.                 #
  ##############################################################################
  local desc="Unknown IOAM Namespace-ID"
  local ns=0
  local tr_type=0x800000
  local tr_size=4
  local mode="$1"
  local saddr="2001:db8:1::2"

  if [ "$1" == "encap" ]
  then
    if [ $encap_tests != 0 ]
    then
      log_test_skipped "${desc}"
      return
    fi

    if [ "$2" == "tunsrc" ]
    then
      saddr="2001:db8:1::50"
      mode+=" tunsrc 2001:db8:1::50"
    fi

    mode+=" tundst 2001:db8:2::2"
    ip -netns $ioam_node_gamma link set ip6tnl0 up &>/dev/null
  fi

  ip -netns $ioam_node_alpha \
    route change 2001:db8:2::/64 \
    encap ioam6 mode $mode trace prealloc type $tr_type ns $ns size $tr_size \
    via 2001:db8:1::1 dev veth0 &>/dev/null

  if [ $? == 0 ]
  then
    run_test ${FUNCNAME[0]} "${desc}" $saddr $tr_type $tr_size $ns $1
  else
    log_test_failed "${desc}"
  fi

  ip -netns $ioam_node_alpha \
    route change 2001:db8:2::/64 via 2001:db8:1::1 dev veth0 &>/dev/null

  [ "$1" == "encap" ] && ip -netns $ioam_node_gamma \
    link set ip6tnl0 down &>/dev/null
}

output_no_room()
{
  ##############################################################################
  # Make sure an IOAM encapsulating node does NOT fill the trace AND sets the  #
  # Overflow flag when there is not enough room for its data.                  #
  ##############################################################################
  local desc="Missing room for data"
  local ns=123
  local tr_type=0xc00000
  local tr_size=4
  local mode="$1"
  local saddr="2001:db8:1::2"

  if [ "$1" == "encap" ]
  then
    if [ $encap_tests != 0 ]
    then
      log_test_skipped "${desc}"
      return
    fi

    if [ "$2" == "tunsrc" ]
    then
      saddr="2001:db8:1::50"
      mode+=" tunsrc 2001:db8:1::50"
    fi

    mode+=" tundst 2001:db8:2::2"
    ip -netns $ioam_node_gamma link set ip6tnl0 up &>/dev/null
  fi

  ip -netns $ioam_node_alpha \
    route change 2001:db8:2::/64 \
    encap ioam6 mode $mode trace prealloc type $tr_type ns $ns size $tr_size \
    via 2001:db8:1::1 dev veth0 &>/dev/null

  if [ $? == 0 ]
  then
    run_test ${FUNCNAME[0]} "${desc}" $saddr $tr_type $tr_size $ns $1
  else
    log_test_failed "${desc}"
  fi

  ip -netns $ioam_node_alpha \
    route change 2001:db8:2::/64 via 2001:db8:1::1 dev veth0 &>/dev/null

  [ "$1" == "encap" ] && ip -netns $ioam_node_gamma \
    link set ip6tnl0 down &>/dev/null
}

output_no_room_oss()
{
  ##############################################################################
  # Make sure an IOAM encapsulating node does NOT fill the trace AND sets the  #
  # Overflow flag when there is not enough room for the Opaque State Snapshot. #
  ##############################################################################
  local desc="Missing room for Opaque State Snapshot"
  local ns=123
  local tr_type=0x000002
  local tr_size=4
  local mode="$1"
  local saddr="2001:db8:1::2"

  if [ "$1" == "encap" ]
  then
    if [ $encap_tests != 0 ]
    then
      log_test_skipped "${desc}"
      return
    fi

    if [ "$2" == "tunsrc" ]
    then
      saddr="2001:db8:1::50"
      mode+=" tunsrc 2001:db8:1::50"
    fi

    mode+=" tundst 2001:db8:2::2"
    ip -netns $ioam_node_gamma link set ip6tnl0 up &>/dev/null
  fi

  ip -netns $ioam_node_alpha \
    route change 2001:db8:2::/64 \
    encap ioam6 mode $mode trace prealloc type $tr_type ns $ns size $tr_size \
    via 2001:db8:1::1 dev veth0 &>/dev/null

  if [ $? == 0 ]
  then
    run_test ${FUNCNAME[0]} "${desc}" $saddr $tr_type $tr_size $ns $1
  else
    log_test_failed "${desc}"
  fi

  ip -netns $ioam_node_alpha \
    route change 2001:db8:2::/64 via 2001:db8:1::1 dev veth0 &>/dev/null

  [ "$1" == "encap" ] && ip -netns $ioam_node_gamma \
    link set ip6tnl0 down &>/dev/null
}

output_bits()
{
  ##############################################################################
  # Make sure an IOAM encapsulating node implements all supported bits by      #
  # checking it correctly fills the trace with its data.                       #
  ##############################################################################
  local desc="Trace Type with supported bit <n> only"
  local ns=123
  local mode="$1"
  local saddr="2001:db8:1::2"

  if [ "$1" == "encap" ]
  then
    if [ "$2" == "tunsrc" ]
    then
      saddr="2001:db8:1::50"
      mode+=" tunsrc 2001:db8:1::50"
    fi

    mode+=" tundst 2001:db8:2::2"
    ip -netns $ioam_node_gamma link set ip6tnl0 up &>/dev/null
  fi

  local tmp=${bit2size[22]}
  bit2size[22]=$(( $tmp + ${#ALPHA[9]} + ((4 - (${#ALPHA[9]} % 4)) % 4) ))

  local i
  for i in {0..11} {22..22}
  do
    local descr="${desc/<n>/$i}"

    if [[ "$1" == "encap" && $encap_tests != 0 ]]
    then
      log_test_skipped "${descr}"
      continue
    fi

    ip -netns $ioam_node_alpha \
      route change 2001:db8:2::/64 \
      encap ioam6 mode $mode trace prealloc \
      type ${bit2type[$i]} ns $ns size ${bit2size[$i]} \
      via 2001:db8:1::1 dev veth0 &>/dev/null

    if [ $? == 0 ]
    then
      run_test "output_bit$i" "${descr}" $saddr \
        ${bit2type[$i]} ${bit2size[$i]} $ns $1
    else
      log_test_failed "${descr}"
    fi
  done

  ip -netns $ioam_node_alpha \
    route change 2001:db8:2::/64 via 2001:db8:1::1 dev veth0 &>/dev/null

  [ "$1" == "encap" ] && ip -netns $ioam_node_gamma \
    link set ip6tnl0 down &>/dev/null

  bit2size[22]=$tmp
}

output_sizes()
{
  ##############################################################################
  # Make sure an IOAM encapsulating node allocates supported sizes correctly.  #
  ##############################################################################
  local desc="Trace Size of <n> bytes"
  local ns=0
  local tr_type=0x800000
  local mode="$1"
  local saddr="2001:db8:1::2"

  if [ "$1" == "encap" ]
  then
    if [ "$2" == "tunsrc" ]
    then
      saddr="2001:db8:1::50"
      mode+=" tunsrc 2001:db8:1::50"
    fi

    mode+=" tundst 2001:db8:2::2"
    ip -netns $ioam_node_gamma link set ip6tnl0 up &>/dev/null
  fi

  local i
  for i in $(seq 4 4 244)
  do
    local descr="${desc/<n>/$i}"

    if [[ "$1" == "encap" && $encap_tests != 0 ]]
    then
      log_test_skipped "${descr}"
      continue
    fi

    ip -netns $ioam_node_alpha \
      route change 2001:db8:2::/64 \
      encap ioam6 mode $mode trace prealloc type $tr_type ns $ns size $i \
      via 2001:db8:1::1 dev veth0 &>/dev/null

    if [ $? == 0 ]
    then
      run_test "output_size$i" "${descr}" $saddr $tr_type $i $ns $1
    else
      log_test_failed "${descr}"
    fi
  done

  ip -netns $ioam_node_alpha \
    route change 2001:db8:2::/64 via 2001:db8:1::1 dev veth0 &>/dev/null

  [ "$1" == "encap" ] && ip -netns $ioam_node_gamma \
    link set ip6tnl0 down &>/dev/null
}

output_full_supp_trace()
{
  ##############################################################################
  # Make sure an IOAM encapsulating node correctly fills a trace when all      #
  # supported bits are set.                                                    #
  ##############################################################################
  local desc="Full supported trace"
  local ns=123
  local tr_type=0xfff002
  local tr_size
  local mode="$1"
  local saddr="2001:db8:1::2"

  if [ "$1" == "encap" ]
  then
    if [ $encap_tests != 0 ]
    then
      log_test_skipped "${desc}"
      return
    fi

    if [ "$2" == "tunsrc" ]
    then
      saddr="2001:db8:1::50"
      mode+=" tunsrc 2001:db8:1::50"
    fi

    mode+=" tundst 2001:db8:2::2"
    ip -netns $ioam_node_gamma link set ip6tnl0 up &>/dev/null
  fi

  local i
  tr_size=$(( ${#ALPHA[9]} + ((4 - (${#ALPHA[9]} % 4)) % 4) ))
  for i in {0..11} {22..22}
  do
    tr_size=$((tr_size + bit2size[$i]))
  done

  ip -netns $ioam_node_alpha \
    route change 2001:db8:2::/64 \
    encap ioam6 mode $mode trace prealloc type $tr_type ns $ns size $tr_size \
    via 2001:db8:1::1 dev veth0 &>/dev/null

  if [ $? == 0 ]
  then
    run_test ${FUNCNAME[0]} "${desc}" $saddr $tr_type $tr_size $ns $1
  else
    log_test_failed "${desc}"
  fi

  ip -netns $ioam_node_alpha \
    route change 2001:db8:2::/64 via 2001:db8:1::1 dev veth0 &>/dev/null

  [ "$1" == "encap" ] && ip -netns $ioam_node_gamma \
    link set ip6tnl0 down &>/dev/null
}


################################################################################
#                                                                              #
#                                 INPUT tests                                  #
#                                                                              #
################################################################################

input_undef_ns()
{
  ##############################################################################
  # Make sure an IOAM node does NOT fill the trace when the corresponding IOAM #
  # Namespace-ID is not configured locally.                                    #
  ##############################################################################
  local desc="Unknown IOAM Namespace-ID"
  local ns=0
  local tr_type=0x800000
  local tr_size=4
  local mode="$1"

  if [ "$1" == "encap" ]
  then
    if [ $encap_tests != 0 ]
    then
      log_test_skipped "${desc}"
      return
    fi

    mode+=" tundst 2001:db8:2::2"
    ip -netns $ioam_node_gamma link set ip6tnl0 up &>/dev/null
  fi

  ip -netns $ioam_node_alpha \
    route change 2001:db8:2::/64 \
    encap ioam6 mode $mode trace prealloc type $tr_type ns $ns size $tr_size \
    via 2001:db8:1::1 dev veth0 &>/dev/null

  if [ $? == 0 ]
  then
    run_test ${FUNCNAME[0]} "${desc}" 2001:db8:1::2 $tr_type $tr_size $ns $1
  else
    log_test_failed "${desc}"
  fi

  ip -netns $ioam_node_alpha \
    route change 2001:db8:2::/64 via 2001:db8:1::1 dev veth0 &>/dev/null

  [ "$1" == "encap" ] && ip -netns $ioam_node_gamma \
    link set ip6tnl0 down &>/dev/null
}

input_no_room()
{
  ##############################################################################
  # Make sure an IOAM node does NOT fill the trace AND sets the Overflow flag  #
  # when there is not enough room for its data.                                #
  ##############################################################################
  local desc="Missing room for data"
  local ns=123
  local tr_type=0xc00000
  local tr_size=4
  local mode="$1"

  if [ "$1" == "encap" ]
  then
    if [ $encap_tests != 0 ]
    then
      log_test_skipped "${desc}"
      return
    fi

    mode+=" tundst 2001:db8:2::2"
    ip -netns $ioam_node_gamma link set ip6tnl0 up &>/dev/null
  fi

  ip -netns $ioam_node_alpha \
    route change 2001:db8:2::/64 \
    encap ioam6 mode $mode trace prealloc type $tr_type ns $ns size $tr_size \
    via 2001:db8:1::1 dev veth0 &>/dev/null

  if [ $? == 0 ]
  then
    run_test ${FUNCNAME[0]} "${desc}" 2001:db8:1::2 $tr_type $tr_size $ns $1
  else
    log_test_failed "${desc}"
  fi

  ip -netns $ioam_node_alpha \
    route change 2001:db8:2::/64 via 2001:db8:1::1 dev veth0 &>/dev/null

  [ "$1" == "encap" ] && ip -netns $ioam_node_gamma \
    link set ip6tnl0 down &>/dev/null
}

input_no_room_oss()
{
  ##############################################################################
  # Make sure an IOAM node does NOT fill the trace AND sets the Overflow flag  #
  # when there is not enough room for the Opaque State Snapshot.               #
  ##############################################################################
  local desc="Missing room for Opaque State Snapshot"
  local ns=123
  local tr_type=0x000002
  local tr_size=4
  local mode="$1"

  if [ "$1" == "encap" ]
  then
    if [ $encap_tests != 0 ]
    then
      log_test_skipped "${desc}"
      return
    fi

    mode+=" tundst 2001:db8:2::2"
    ip -netns $ioam_node_gamma link set ip6tnl0 up &>/dev/null
  fi

  ip -netns $ioam_node_alpha \
    route change 2001:db8:2::/64 \
    encap ioam6 mode $mode trace prealloc type $tr_type ns $ns size $tr_size \
    via 2001:db8:1::1 dev veth0 &>/dev/null

  if [ $? == 0 ]
  then
    run_test ${FUNCNAME[0]} "${desc}" 2001:db8:1::2 $tr_type $tr_size $ns $1
  else
    log_test_failed "${desc}"
  fi

  ip -netns $ioam_node_alpha \
    route change 2001:db8:2::/64 via 2001:db8:1::1 dev veth0 &>/dev/null

  [ "$1" == "encap" ] && ip -netns $ioam_node_gamma \
    link set ip6tnl0 down &>/dev/null
}

input_disabled()
{
  ##############################################################################
  # Make sure an IOAM node does NOT fill the trace when IOAM is not enabled on #
  # the corresponding (ingress) interface.                                     #
  ##############################################################################
  local desc="IOAM disabled on ingress interface"
  local ns=123
  local tr_type=0x800000
  local tr_size=4
  local mode="$1"

  if [ "$1" == "encap" ]
  then
    if [ $encap_tests != 0 ]
    then
      log_test_skipped "${desc}"
      return
    fi

    mode+=" tundst 2001:db8:2::2"
    ip -netns $ioam_node_gamma link set ip6tnl0 up &>/dev/null
  fi

  # Exception: disable IOAM on ingress interface
  ip netns exec $ioam_node_beta \
    sysctl -wq net.ipv6.conf.veth0.ioam6_enabled=0 &>/dev/null
  local ret=$?

  ip -netns $ioam_node_alpha \
    route change 2001:db8:2::/64 \
    encap ioam6 mode $mode trace prealloc type $tr_type ns $ns size $tr_size \
    via 2001:db8:1::1 dev veth0 &>/dev/null
  ret=$((ret + $?))

  if [ $ret == 0 ]
  then
    run_test ${FUNCNAME[0]} "${desc}" 2001:db8:1::2 $tr_type $tr_size $ns $1
  else
    log_test_failed "${desc}"
  fi

  # Clean Exception
  ip netns exec $ioam_node_beta \
    sysctl -wq net.ipv6.conf.veth0.ioam6_enabled=1 &>/dev/null

  ip -netns $ioam_node_alpha \
    route change 2001:db8:2::/64 via 2001:db8:1::1 dev veth0 &>/dev/null

  [ "$1" == "encap" ] && ip -netns $ioam_node_gamma \
    link set ip6tnl0 down &>/dev/null
}

input_oflag()
{
  ##############################################################################
  # Make sure an IOAM node does NOT fill the trace when the Overflow flag is   #
  # set.                                                                       #
  ##############################################################################
  local desc="Overflow flag is set"
  local ns=123
  local tr_type=0xc00000
  local tr_size=4
  local mode="$1"

  if [ "$1" == "encap" ]
  then
    if [ $encap_tests != 0 ]
    then
      log_test_skipped "${desc}"
      return
    fi

    mode+=" tundst 2001:db8:2::2"
    ip -netns $ioam_node_gamma link set ip6tnl0 up &>/dev/null
  fi

  # Exception:
  #   Here, we need the sender to set the Overflow flag. For that, we will add
  #   back the IOAM namespace that was previously configured on the sender.
  ip -netns $ioam_node_alpha ioam namespace add 123 &>/dev/null
  local ret=$?

  ip -netns $ioam_node_alpha \
    route change 2001:db8:2::/64 \
    encap ioam6 mode $mode trace prealloc type $tr_type ns $ns size $tr_size \
    via 2001:db8:1::1 dev veth0 &>/dev/null
  ret=$((ret + $?))

  if [ $ret == 0 ]
  then
    run_test ${FUNCNAME[0]} "${desc}" 2001:db8:1::2 $tr_type $tr_size $ns $1
  else
    log_test_failed "${desc}"
  fi

  # Clean Exception
  ip -netns $ioam_node_alpha ioam namespace del 123 &>/dev/null

  ip -netns $ioam_node_alpha \
    route change 2001:db8:2::/64 via 2001:db8:1::1 dev veth0 &>/dev/null

  [ "$1" == "encap" ] && ip -netns $ioam_node_gamma \
    link set ip6tnl0 down &>/dev/null
}

input_bits()
{
  ##############################################################################
  # Make sure an IOAM node implements all supported bits by checking it        #
  # correctly fills the trace with its data.                                   #
  ##############################################################################
  local desc="Trace Type with supported bit <n> only"
  local ns=123
  local mode="$1"

  if [ "$1" == "encap" ]
  then
    mode+=" tundst 2001:db8:2::2"
    ip -netns $ioam_node_gamma link set ip6tnl0 up &>/dev/null
  fi

  local tmp=${bit2size[22]}
  bit2size[22]=$(( $tmp + ${#BETA[9]} + ((4 - (${#BETA[9]} % 4)) % 4) ))

  local i
  for i in {0..11} {22..22}
  do
    local descr="${desc/<n>/$i}"

    if [[ "$1" == "encap" && $encap_tests != 0 ]]
    then
      log_test_skipped "${descr}"
      continue
    fi

    ip -netns $ioam_node_alpha \
      route change 2001:db8:2::/64 \
      encap ioam6 mode $mode trace prealloc \
      type ${bit2type[$i]} ns $ns size ${bit2size[$i]} \
      via 2001:db8:1::1 dev veth0 &>/dev/null

    if [ $? == 0 ]
    then
      run_test "input_bit$i" "${descr}" 2001:db8:1::2 \
        ${bit2type[$i]} ${bit2size[$i]} $ns $1
    else
      log_test_failed "${descr}"
    fi
  done

  ip -netns $ioam_node_alpha \
    route change 2001:db8:2::/64 via 2001:db8:1::1 dev veth0 &>/dev/null

  [ "$1" == "encap" ] && ip -netns $ioam_node_gamma \
    link set ip6tnl0 down &>/dev/null

  bit2size[22]=$tmp
}

input_sizes()
{
  ##############################################################################
  # Make sure an IOAM node handles all supported sizes correctly.              #
  ##############################################################################
  local desc="Trace Size of <n> bytes"
  local ns=123
  local tr_type=0x800000
  local mode="$1"

  if [ "$1" == "encap" ]
  then
    mode+=" tundst 2001:db8:2::2"
    ip -netns $ioam_node_gamma link set ip6tnl0 up &>/dev/null
  fi

  local i
  for i in $(seq 4 4 244)
  do
    local descr="${desc/<n>/$i}"

    if [[ "$1" == "encap" && $encap_tests != 0 ]]
    then
      log_test_skipped "${descr}"
      continue
    fi

    ip -netns $ioam_node_alpha \
      route change 2001:db8:2::/64 \
      encap ioam6 mode $mode trace prealloc type $tr_type ns $ns size $i \
      via 2001:db8:1::1 dev veth0 &>/dev/null

    if [ $? == 0 ]
    then
      run_test "input_size$i" "${descr}" 2001:db8:1::2 $tr_type $i $ns $1
    else
      log_test_failed "${descr}"
    fi
  done

  ip -netns $ioam_node_alpha \
    route change 2001:db8:2::/64 via 2001:db8:1::1 dev veth0 &>/dev/null

  [ "$1" == "encap" ] && ip -netns $ioam_node_gamma \
    link set ip6tnl0 down &>/dev/null
}

input_full_supp_trace()
{
  ##############################################################################
  # Make sure an IOAM node correctly fills a trace when all supported bits are #
  # set.                                                                       #
  ##############################################################################
  local desc="Full supported trace"
  local ns=123
  local tr_type=0xfff002
  local tr_size
  local mode="$1"

  if [ "$1" == "encap" ]
  then
    if [ $encap_tests != 0 ]
    then
      log_test_skipped "${desc}"
      return
    fi

    mode+=" tundst 2001:db8:2::2"
    ip -netns $ioam_node_gamma link set ip6tnl0 up &>/dev/null
  fi

  local i
  tr_size=$(( ${#BETA[9]} + ((4 - (${#BETA[9]} % 4)) % 4) ))
  for i in {0..11} {22..22}
  do
    tr_size=$((tr_size + bit2size[$i]))
  done

  ip -netns $ioam_node_alpha \
    route change 2001:db8:2::/64 \
    encap ioam6 mode $mode trace prealloc type $tr_type ns $ns size $tr_size \
    via 2001:db8:1::1 dev veth0 &>/dev/null

  if [ $? == 0 ]
  then
    run_test ${FUNCNAME[0]} "${desc}" 2001:db8:1::2 $tr_type $tr_size $ns $1
  else
    log_test_failed "${desc}"
  fi

  ip -netns $ioam_node_alpha \
    route change 2001:db8:2::/64 via 2001:db8:1::1 dev veth0 &>/dev/null

  [ "$1" == "encap" ] && ip -netns $ioam_node_gamma \
    link set ip6tnl0 down &>/dev/null
}


################################################################################
#                                                                              #
#                                     MAIN                                     #
#                                                                              #
################################################################################

npassed=0
nskipped=0
nfailed=0

if [ "$(id -u)" -ne 0 ]
then
  echo "SKIP: Need root privileges."
  exit $ksft_skip
fi

if [ ! -x "$(command -v ip)" ]
then
  echo "SKIP: Could not run test without ip tool."
  exit $ksft_skip
fi

check_kernel_compatibility
setup
run
cleanup

if [ $nfailed != 0 ]
then
  exit $ksft_fail
fi

exit $ksft_pass

Filemanager

Name Type Size Permission Actions
af_unix Folder 0755
forwarding Folder 0755
hsr Folder 0755
lib Folder 0755
mptcp Folder 0755
netfilter Folder 0755
openvswitch Folder 0755
packetdrill Folder 0755
rds Folder 0755
tcp_ao Folder 0755
Makefile File 4.82 KB 0644
altnames.sh File 1.77 KB 0755
amt.sh File 9.2 KB 0755
arp_ndisc_evict_nocarrier.sh File 5.15 KB 0755
arp_ndisc_untracked_subnets.sh File 7.04 KB 0755
bareudp.sh File 20.79 KB 0755
big_tcp.sh File 5.49 KB 0755
bind_bhash.sh File 1.34 KB 0755
busy_poll_test.sh File 3.47 KB 0755
cmsg_ipv6.sh File 3.34 KB 0755
cmsg_so_mark.sh File 1.54 KB 0755
cmsg_so_priority.sh File 3.93 KB 0755
cmsg_time.sh File 2.22 KB 0755
drop_monitor_tests.sh File 4.34 KB 0755
fcnal-test.sh File 106.62 KB 0755
fdb_flush.sh File 21.04 KB 0755
fdb_notify.sh File 1.81 KB 0755
fib-onlink-tests.sh File 12.04 KB 0755
fib_nexthop_multiprefix.sh File 5.81 KB 0755
fib_nexthop_nongw.sh File 2.19 KB 0755
fib_nexthops.sh File 73.9 KB 0755
fib_rule_tests.sh File 17.66 KB 0755
fib_tests.sh File 77.47 KB 0755
fin_ack_lat.sh File 507 B 0755
fq_band_pktlimit.sh File 1.81 KB 0755
gre_gso.sh File 4.04 KB 0755
gro.sh File 2.27 KB 0755
icmp.sh File 2.52 KB 0755
icmp_redirect.sh File 12.49 KB 0755
in_netns.sh File 323 B 0755
io_uring_zerocopy_tx.sh File 3 KB 0755
ioam6.sh File 50.49 KB 0755
ip6_gre_headroom.sh File 1.37 KB 0755
ip_defrag.sh File 2.04 KB 0755
ip_local_port_range.sh File 153 B 0755
ipv6_flowlabel.sh File 1 KB 0755
ipv6_route_update_soft_lockup.sh File 10.8 KB 0755
l2_tos_ttl_inherit.sh File 13.95 KB 0755
l2tp.sh File 9.68 KB 0755
lib.sh File 8.65 KB 0644
lwt_dst_cache_ref_loop.sh File 5.94 KB 0755
msg_zerocopy.sh File 2.93 KB 0755
ndisc_unsolicited_na_test.sh File 5.85 KB 0755
net_helper.sh File 514 B 0644
netdevice.sh File 5.69 KB 0755
netns-name.sh File 2.4 KB 0755
netns-sysctl.sh File 910 B 0755
pmtu.sh File 78.42 KB 0755
psock_snd.sh File 2.2 KB 0755
reuseaddr_ports_exhausted.sh File 635 B 0755
reuseport_addr_any.sh File 81 B 0755
route_localnet.sh File 1.92 KB 0755
rps_default_mask.sh File 2.19 KB 0755
rtnetlink.sh File 35.16 KB 0755
rxtimestamp.sh File 79 B 0755
sctp_vrf.sh File 5.81 KB 0755
setup_loopback.sh File 2.7 KB 0644
setup_veth.sh File 1.01 KB 0644
so_txtime.sh File 2.71 KB 0755
srv6_end_dt46_l3vpn_test.sh File 20.57 KB 0755
srv6_end_dt4_l3vpn_test.sh File 16.92 KB 0755
srv6_end_dt6_l3vpn_test.sh File 17.11 KB 0755
srv6_end_dx4_netfilter_test.sh File 10.92 KB 0755
srv6_end_dx6_netfilter_test.sh File 11.13 KB 0755
srv6_end_flavors_test.sh File 23.56 KB 0755
srv6_end_next_csid_l3vpn_test.sh File 32.53 KB 0755
srv6_end_x_next_csid_l3vpn_test.sh File 35.46 KB 0755
srv6_hencap_red_l3vpn_test.sh File 23.15 KB 0755
srv6_hl2encap_red_l2vpn_test.sh File 20.51 KB 0755
stress_reuseport_listen.sh File 539 B 0755
tcp_fastopen_backup_key.sh File 1.06 KB 0755
test_blackhole_dev.sh File 280 B 0755
test_bpf.sh File 225 B 0755
test_bridge_backup_port.sh File 27.35 KB 0755
test_bridge_neigh_suppress.sh File 28.4 KB 0755
test_ingress_egress_chaining.sh File 2.14 KB 0644
test_vxlan_fdb_changelink.sh File 678 B 0755
test_vxlan_mdb.sh File 92.63 KB 0755
test_vxlan_nolocalbypass.sh File 5.57 KB 0755
test_vxlan_under_vrf.sh File 5.54 KB 0755
test_vxlan_vnifiltering.sh File 20.91 KB 0755
toeplitz.sh File 4.87 KB 0755
toeplitz_client.sh File 667 B 0755
traceroute.sh File 6.91 KB 0755
txtimestamp.sh File 1.84 KB 0755
udpgro.sh File 5.72 KB 0755
udpgro_bench.sh File 2.08 KB 0755
udpgro_frglist.sh File 2.43 KB 0755
udpgro_fwd.sh File 7.08 KB 0755
udpgso.sh File 2.42 KB 0755
udpgso_bench.sh File 2.83 KB 0755
unicast_extensions.sh File 7.77 KB 0755
veth.sh File 10.75 KB 0755
vlan_bridge_binding.sh File 4.49 KB 0755
vlan_hw_filter.sh File 819 B 0755
vrf-xfrm-tests.sh File 10.65 KB 0755
vrf_route_leaking.sh File 16.48 KB 0755
vrf_strict_mode_test.sh File 8 KB 0755
xfrm_policy.sh File 14.65 KB 0755
xfrm_policy_add_speed.sh File 1.51 KB 0755
Filemanager