This patch entirely removes the ioam selftests to prepare for the next patch in this series, which re-adds the new ioam selftests for better readability. Signed-off-by: Justin Iurman <justin.iurman@xxxxxxxxx> --- tools/testing/selftests/net/Makefile | 2 - tools/testing/selftests/net/config | 1 - tools/testing/selftests/net/ioam6.sh | 771 --------------------- tools/testing/selftests/net/ioam6_parser.c | 674 ------------------ 4 files changed, 1448 deletions(-) delete mode 100755 tools/testing/selftests/net/ioam6.sh delete mode 100644 tools/testing/selftests/net/ioam6_parser.c diff --git a/tools/testing/selftests/net/Makefile b/tools/testing/selftests/net/Makefile index 649f1fe0dc46..ef40d099aa1c 100644 --- a/tools/testing/selftests/net/Makefile +++ b/tools/testing/selftests/net/Makefile @@ -28,7 +28,6 @@ TEST_PROGS += unicast_extensions.sh TEST_PROGS += udpgro_fwd.sh TEST_PROGS += udpgro_frglist.sh TEST_PROGS += veth.sh -TEST_PROGS += ioam6.sh TEST_PROGS += gro.sh TEST_PROGS += gre_gso.sh TEST_PROGS += cmsg_so_mark.sh @@ -67,7 +66,6 @@ TEST_GEN_FILES += fin_ack_lat TEST_GEN_FILES += reuseaddr_ports_exhausted TEST_GEN_FILES += hwtstamp_config rxtimestamp timestamping txtimestamp TEST_GEN_FILES += ipsec -TEST_GEN_FILES += ioam6_parser TEST_GEN_FILES += gro TEST_GEN_PROGS = reuseport_bpf reuseport_bpf_cpu reuseport_bpf_numa TEST_GEN_PROGS += reuseport_dualstack reuseaddr_conflict tls tun tap epoll_busy_poll diff --git a/tools/testing/selftests/net/config b/tools/testing/selftests/net/config index 5b9baf708950..3f0b02835e78 100644 --- a/tools/testing/selftests/net/config +++ b/tools/testing/selftests/net/config @@ -95,7 +95,6 @@ CONFIG_NET_CLS_FLOWER=m CONFIG_NET_ACT_TUNNEL_KEY=m CONFIG_NET_ACT_MIRRED=m CONFIG_BAREUDP=m -CONFIG_IPV6_IOAM6_LWTUNNEL=y CONFIG_CRYPTO_SM4_GENERIC=y CONFIG_AMT=m CONFIG_TUN=y diff --git a/tools/testing/selftests/net/ioam6.sh b/tools/testing/selftests/net/ioam6.sh deleted file mode 100755 index 12491850ae98..000000000000 --- a/tools/testing/selftests/net/ioam6.sh +++ /dev/null @@ -1,771 +0,0 @@ -#!/bin/bash -# SPDX-License-Identifier: GPL-2.0+ -# -# Author: Justin Iurman <justin.iurman@xxxxxxxxx> -# -# This script evaluates the IOAM insertion for IPv6 by checking the IOAM data -# consistency directly inside packets on the receiver side. Tests are divided -# into three categories: OUTPUT (evaluates the IOAM processing by the sender), -# INPUT (evaluates the IOAM processing by a receiver) and GLOBAL (evaluates -# wider use cases that do not fall into the other two categories). Both OUTPUT -# and INPUT tests only use a two-node topology (alpha and beta), while GLOBAL -# tests use the entire three-node topology (alpha, beta, gamma). Each test is -# documented inside its own handler in the code below. -# -# An IOAM domain is configured from Alpha to Gamma but not on the reverse path. -# When either Beta or Gamma is the destination (depending on the test category), -# Alpha adds an IOAM option (Pre-allocated Trace) inside a Hop-by-hop. -# -# -# +-------------------+ +-------------------+ -# | | | | -# | Alpha netns | | Gamma netns | -# | | | | -# | +-------------+ | | +-------------+ | -# | | veth0 | | | | veth0 | | -# | | db01::2/64 | | | | db02::2/64 | | -# | +-------------+ | | +-------------+ | -# | . | | . | -# +-------------------+ +-------------------+ -# . . -# . . -# . . -# +----------------------------------------------------+ -# | . . | -# | +-------------+ +-------------+ | -# | | veth0 | | veth1 | | -# | | db01::1/64 | ................ | db02::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 | 0xdeadbee0 | -# +-----------------------------------------------------------+ -# | 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 | 0xdeadbee1 | -# +-----------------------------------------------------------+ -# | Namespace Wide Data | 0xcafec0caf11dc0de | -# +-----------------------------------------------------------+ -# | Schema ID | 666 | -# +-----------------------------------------------------------+ -# | Schema Data | Hello there -Obi | -# +-----------------------------------------------------------+ -# -# -# ============================================================= -# | Gamma - IOAM configuration | -# +===========================================================+ -# | Node ID | 3 | -# +-----------------------------------------------------------+ -# | Node Wide ID | 33333333 | -# +-----------------------------------------------------------+ -# | Ingress ID | 301 | -# +-----------------------------------------------------------+ -# | Ingress Wide ID | 301301 | -# +-----------------------------------------------------------+ -# | Egress ID | 0xffff (default value) | -# +-----------------------------------------------------------+ -# | Egress Wide ID | 0xffffffff (default value) | -# +-----------------------------------------------------------+ -# | Namespace Data | 0xdeadbee2 | -# +-----------------------------------------------------------+ -# | Namespace Wide Data | 0xcafec0caf22dc0de | -# +-----------------------------------------------------------+ -# | 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 - 0xffffffff # Ingress Wide ID - 101 # Egress ID - 101101 # Egress Wide ID - 0xdeadbee0 # Namespace Data - 0xcafec0caf00dc0de # Namespace Wide Data - 777 # Schema ID (0xffffff = None) - "something that will be 4n-aligned" # Schema Data -) - -BETA=( - 2 - 22222222 - 201 - 201201 - 202 - 202202 - 0xdeadbee1 - 0xcafec0caf11dc0de - 666 - "Hello there -Obi" -) - -GAMMA=( - 3 - 33333333 - 301 - 301301 - 0xffff - 0xffffffff - 0xdeadbee2 - 0xcafec0caf22dc0de - 0xffffff - "" -) - -TESTS_OUTPUT=" - out_undef_ns - out_no_room - out_bits - out_full_supp_trace -" - -TESTS_INPUT=" - in_undef_ns - in_no_room - in_oflag - in_bits - in_full_supp_trace -" - -TESTS_GLOBAL=" - fwd_full_supp_trace -" - - -################################################################################ -# # -# LIBRARY # -# # -################################################################################ - -check_kernel_compatibility() -{ - setup_ns ioam_tmp_node - ip link add name veth0 netns $ioam_tmp_node type veth \ - peer name veth1 netns $ioam_tmp_node - - ip -netns $ioam_tmp_node link set veth0 up - ip -netns $ioam_tmp_node link set veth1 up - - ip -netns $ioam_tmp_node ioam namespace add 0 - ns_ad=$? - - ip -netns $ioam_tmp_node ioam namespace show | grep -q "namespace 0" - ns_sh=$? - - if [[ $ns_ad != 0 || $ns_sh != 0 ]] - then - echo "SKIP: kernel version probably too old, missing ioam support" - ip link del veth0 2>/dev/null || true - cleanup_ns $ioam_tmp_node || true - exit $ksft_skip - fi - - ip -netns $ioam_tmp_node route add db02::/64 encap ioam6 mode inline \ - trace prealloc type 0x800000 ns 0 size 4 dev veth0 - tr_ad=$? - - ip -netns $ioam_tmp_node -6 route | grep -q "encap ioam6" - tr_sh=$? - - if [[ $tr_ad != 0 || $tr_sh != 0 ]] - then - echo "SKIP: cannot attach an ioam trace to a route, did you compile" \ - "without CONFIG_IPV6_IOAM6_LWTUNNEL?" - ip link del veth0 2>/dev/null || true - cleanup_ns $ioam_tmp_node || true - exit $ksft_skip - fi - - ip link del veth0 2>/dev/null || true - cleanup_ns $ioam_tmp_node || true - - lsmod | grep -q "ip6_tunnel" - ip6tnl_loaded=$? - - if [ $ip6tnl_loaded = 0 ] - then - encap_tests=0 - else - modprobe ip6_tunnel &>/dev/null - lsmod | grep -q "ip6_tunnel" - encap_tests=$? - - if [ $encap_tests != 0 ] - then - ip a | grep -q "ip6tnl0" - encap_tests=$? - - if [ $encap_tests != 0 ] - then - echo "Note: ip6_tunnel not found neither as a module nor inside the" \ - "kernel, tests that require it (encap mode) will be omitted" - fi - fi - fi -} - -cleanup() -{ - ip link del ioam-veth-alpha 2>/dev/null || true - ip link del ioam-veth-gamma 2>/dev/null || true - - cleanup_ns $ioam_node_alpha $ioam_node_beta $ioam_node_gamma || true - - if [ $ip6tnl_loaded != 0 ] - then - modprobe -r ip6_tunnel 2>/dev/null || true - fi -} - -setup() -{ - setup_ns ioam_node_alpha ioam_node_beta ioam_node_gamma - - ip link add name ioam-veth-alpha netns $ioam_node_alpha type veth \ - peer name ioam-veth-betaL netns $ioam_node_beta - ip link add name ioam-veth-betaR netns $ioam_node_beta type veth \ - peer name ioam-veth-gamma netns $ioam_node_gamma - - ip -netns $ioam_node_alpha link set ioam-veth-alpha name veth0 - ip -netns $ioam_node_beta link set ioam-veth-betaL name veth0 - ip -netns $ioam_node_beta link set ioam-veth-betaR name veth1 - ip -netns $ioam_node_gamma link set ioam-veth-gamma name veth0 - - ip -netns $ioam_node_alpha addr add db01::2/64 dev veth0 - ip -netns $ioam_node_alpha link set veth0 up - ip -netns $ioam_node_alpha link set lo up - ip -netns $ioam_node_alpha route add db02::/64 via db01::1 dev veth0 - ip -netns $ioam_node_alpha route del db01::/64 - ip -netns $ioam_node_alpha route add db01::/64 dev veth0 - - ip -netns $ioam_node_beta addr add db01::1/64 dev veth0 - ip -netns $ioam_node_beta addr add db02::1/64 dev veth1 - ip -netns $ioam_node_beta link set veth0 up - ip -netns $ioam_node_beta link set veth1 up - ip -netns $ioam_node_beta link set lo up - - ip -netns $ioam_node_gamma addr add db02::2/64 dev veth0 - ip -netns $ioam_node_gamma link set veth0 up - ip -netns $ioam_node_gamma link set lo up - ip -netns $ioam_node_gamma route add db01::/64 via db02::1 dev veth0 - - # - IOAM config - - ip netns exec $ioam_node_alpha sysctl -wq net.ipv6.ioam6_id=${ALPHA[0]} - ip netns exec $ioam_node_alpha sysctl -wq net.ipv6.ioam6_id_wide=${ALPHA[1]} - ip netns exec $ioam_node_alpha sysctl -wq net.ipv6.conf.veth0.ioam6_id=${ALPHA[4]} - ip netns exec $ioam_node_alpha sysctl -wq net.ipv6.conf.veth0.ioam6_id_wide=${ALPHA[5]} - ip -netns $ioam_node_alpha ioam namespace add 123 data ${ALPHA[6]} wide ${ALPHA[7]} - ip -netns $ioam_node_alpha ioam schema add ${ALPHA[8]} "${ALPHA[9]}" - ip -netns $ioam_node_alpha ioam namespace set 123 schema ${ALPHA[8]} - - ip netns exec $ioam_node_beta sysctl -wq net.ipv6.conf.all.forwarding=1 - ip netns exec $ioam_node_beta sysctl -wq net.ipv6.ioam6_id=${BETA[0]} - ip netns exec $ioam_node_beta sysctl -wq net.ipv6.ioam6_id_wide=${BETA[1]} - ip netns exec $ioam_node_beta sysctl -wq net.ipv6.conf.veth0.ioam6_enabled=1 - ip netns exec $ioam_node_beta sysctl -wq net.ipv6.conf.veth0.ioam6_id=${BETA[2]} - ip netns exec $ioam_node_beta sysctl -wq net.ipv6.conf.veth0.ioam6_id_wide=${BETA[3]} - ip netns exec $ioam_node_beta sysctl -wq net.ipv6.conf.veth1.ioam6_id=${BETA[4]} - ip netns exec $ioam_node_beta sysctl -wq net.ipv6.conf.veth1.ioam6_id_wide=${BETA[5]} - ip -netns $ioam_node_beta ioam namespace add 123 data ${BETA[6]} wide ${BETA[7]} - ip -netns $ioam_node_beta ioam schema add ${BETA[8]} "${BETA[9]}" - ip -netns $ioam_node_beta ioam namespace set 123 schema ${BETA[8]} - - ip netns exec $ioam_node_gamma sysctl -wq net.ipv6.ioam6_id=${GAMMA[0]} - ip netns exec $ioam_node_gamma sysctl -wq net.ipv6.ioam6_id_wide=${GAMMA[1]} - ip netns exec $ioam_node_gamma sysctl -wq net.ipv6.conf.veth0.ioam6_enabled=1 - ip netns exec $ioam_node_gamma sysctl -wq net.ipv6.conf.veth0.ioam6_id=${GAMMA[2]} - ip netns exec $ioam_node_gamma sysctl -wq net.ipv6.conf.veth0.ioam6_id_wide=${GAMMA[3]} - ip -netns $ioam_node_gamma ioam namespace add 123 data ${GAMMA[6]} wide ${GAMMA[7]} - - sleep 1 - - ip netns exec $ioam_node_alpha ping6 -c 5 -W 1 db02::2 &>/dev/null - if [ $? != 0 ] - then - echo "Setup FAILED" - cleanup &>/dev/null - exit 0 - fi -} - -log_test_passed() -{ - local desc=$1 - printf "TEST: %-60s [ OK ]\n" "${desc}" -} - -log_test_failed() -{ - local desc=$1 - printf "TEST: %-60s [FAIL]\n" "${desc}" -} - -log_results() -{ - echo "- Tests passed: ${npassed}" - echo "- Tests failed: ${nfailed}" -} - -run_test() -{ - local name=$1 - local desc=$2 - local node_src=$3 - local node_dst=$4 - local ip6_dst=$5 - local trace_type=$6 - local ioam_ns=$7 - local type=$8 - - ip netns exec $node_dst ./ioam6_parser $name $trace_type $ioam_ns $type & - local spid=$! - sleep 0.1 - - ip netns exec $node_src ping6 -t 64 -c 1 -W 1 $ip6_dst &>/dev/null - if [ $? != 0 ] - then - nfailed=$((nfailed+1)) - log_test_failed "${desc}" - kill -2 $spid &>/dev/null - else - wait $spid - if [ $? = 0 ] - then - npassed=$((npassed+1)) - log_test_passed "${desc}" - else - nfailed=$((nfailed+1)) - log_test_failed "${desc}" - fi - fi -} - -run() -{ - echo - printf "%0.s-" {1..74} - echo - echo "OUTPUT tests" - printf "%0.s-" {1..74} - echo - - # set OUTPUT settings - ip netns exec $ioam_node_beta sysctl -wq net.ipv6.conf.veth0.ioam6_enabled=0 - - for t in $TESTS_OUTPUT - do - $t "inline" - [ $encap_tests = 0 ] && $t "encap" - done - - # clean OUTPUT settings - ip netns exec $ioam_node_beta sysctl -wq net.ipv6.conf.veth0.ioam6_enabled=1 - ip -netns $ioam_node_alpha route change db01::/64 dev veth0 - - - echo - printf "%0.s-" {1..74} - echo - echo "INPUT tests" - printf "%0.s-" {1..74} - echo - - # set INPUT settings - ip -netns $ioam_node_alpha ioam namespace del 123 - - for t in $TESTS_INPUT - do - $t "inline" - [ $encap_tests = 0 ] && $t "encap" - done - - # clean INPUT settings - ip -netns $ioam_node_alpha ioam namespace add 123 \ - data ${ALPHA[6]} wide ${ALPHA[7]} - ip -netns $ioam_node_alpha ioam namespace set 123 schema ${ALPHA[8]} - ip -netns $ioam_node_alpha route change db01::/64 dev veth0 - - echo - printf "%0.s-" {1..74} - echo - echo "GLOBAL tests" - printf "%0.s-" {1..74} - echo - - for t in $TESTS_GLOBAL - do - $t "inline" - [ $encap_tests = 0 ] && $t "encap" - done - - echo - log_results -} - -bit2type=( - 0x800000 0x400000 0x200000 0x100000 0x080000 0x040000 0x020000 0x010000 - 0x008000 0x004000 0x002000 0x001000 0x000800 0x000400 0x000200 0x000100 - 0x000080 0x000040 0x000020 0x000010 0x000008 0x000004 0x000002 -) -bit2size=( 4 4 4 4 4 4 4 4 8 8 8 4 4 4 4 4 4 4 4 4 4 4 4 ) - - -################################################################################ -# # -# OUTPUT tests # -# # -# Two nodes (sender/receiver), IOAM disabled on ingress for the receiver. # -################################################################################ - -out_undef_ns() -{ - ############################################################################## - # Make sure that the encap node won't fill the trace if the chosen IOAM # - # namespace is not configured locally. # - ############################################################################## - local desc="Unknown IOAM namespace" - - [ "$1" = "encap" ] && mode="$1 tundst db01::1" || mode="$1" - [ "$1" = "encap" ] && ip -netns $ioam_node_beta link set ip6tnl0 up - - ip -netns $ioam_node_alpha route change db01::/64 encap ioam6 mode $mode \ - trace prealloc type 0x800000 ns 0 size 4 dev veth0 - - run_test ${FUNCNAME[0]} "${desc} ($1 mode)" $ioam_node_alpha $ioam_node_beta \ - db01::1 0x800000 0 $1 - - [ "$1" = "encap" ] && ip -netns $ioam_node_beta link set ip6tnl0 down -} - -out_no_room() -{ - ############################################################################## - # Make sure that the encap node won't fill the trace and will set the # - # Overflow flag since there is no room enough for its data. # - ############################################################################## - local desc="Missing trace room" - - [ "$1" = "encap" ] && mode="$1 tundst db01::1" || mode="$1" - [ "$1" = "encap" ] && ip -netns $ioam_node_beta link set ip6tnl0 up - - ip -netns $ioam_node_alpha route change db01::/64 encap ioam6 mode $mode \ - trace prealloc type 0xc00000 ns 123 size 4 dev veth0 - - run_test ${FUNCNAME[0]} "${desc} ($1 mode)" $ioam_node_alpha $ioam_node_beta \ - db01::1 0xc00000 123 $1 - - [ "$1" = "encap" ] && ip -netns $ioam_node_beta link set ip6tnl0 down -} - -out_bits() -{ - ############################################################################## - # Make sure that, for each trace type bit, the encap node will either: # - # (i) fill the trace with its data when it is a supported bit # - # (ii) not fill the trace with its data when it is an unsupported bit # - ############################################################################## - local desc="Trace type with bit <n> only" - - local tmp=${bit2size[22]} - bit2size[22]=$(( $tmp + ${#ALPHA[9]} + ((4 - (${#ALPHA[9]} % 4)) % 4) )) - - [ "$1" = "encap" ] && mode="$1 tundst db01::1" || mode="$1" - [ "$1" = "encap" ] && ip -netns $ioam_node_beta link set ip6tnl0 up - - for i in {0..22} - do - ip -netns $ioam_node_alpha route change db01::/64 encap ioam6 mode $mode \ - trace prealloc type ${bit2type[$i]} ns 123 size ${bit2size[$i]} \ - dev veth0 &>/dev/null - - local cmd_res=$? - local descr="${desc/<n>/$i}" - - if [[ $i -ge 12 && $i -le 21 ]] - then - if [ $cmd_res != 0 ] - then - npassed=$((npassed+1)) - log_test_passed "$descr ($1 mode)" - else - nfailed=$((nfailed+1)) - log_test_failed "$descr ($1 mode)" - fi - else - run_test "out_bit$i" "$descr ($1 mode)" $ioam_node_alpha \ - $ioam_node_beta db01::1 ${bit2type[$i]} 123 $1 - fi - done - - [ "$1" = "encap" ] && ip -netns $ioam_node_beta link set ip6tnl0 down - - bit2size[22]=$tmp -} - -out_full_supp_trace() -{ - ############################################################################## - # Make sure that the encap node will correctly fill a full trace. Be careful,# - # "full trace" here does NOT mean all bits (only supported ones). # - ############################################################################## - local desc="Full supported trace" - - [ "$1" = "encap" ] && mode="$1 tundst db01::1" || mode="$1" - [ "$1" = "encap" ] && ip -netns $ioam_node_beta link set ip6tnl0 up - - ip -netns $ioam_node_alpha route change db01::/64 encap ioam6 mode $mode \ - trace prealloc type 0xfff002 ns 123 size 100 dev veth0 - - run_test ${FUNCNAME[0]} "${desc} ($1 mode)" $ioam_node_alpha $ioam_node_beta \ - db01::1 0xfff002 123 $1 - - [ "$1" = "encap" ] && ip -netns $ioam_node_beta link set ip6tnl0 down -} - - -################################################################################ -# # -# INPUT tests # -# # -# Two nodes (sender/receiver), the sender MUST NOT fill the trace upon # -# insertion -> the IOAM namespace configured on the sender is removed # -# and is used in the inserted trace to force the sender not to fill it. # -################################################################################ - -in_undef_ns() -{ - ############################################################################## - # Make sure that the receiving node won't fill the trace if the related IOAM # - # namespace is not configured locally. # - ############################################################################## - local desc="Unknown IOAM namespace" - - [ "$1" = "encap" ] && mode="$1 tundst db01::1" || mode="$1" - [ "$1" = "encap" ] && ip -netns $ioam_node_beta link set ip6tnl0 up - - ip -netns $ioam_node_alpha route change db01::/64 encap ioam6 mode $mode \ - trace prealloc type 0x800000 ns 0 size 4 dev veth0 - - run_test ${FUNCNAME[0]} "${desc} ($1 mode)" $ioam_node_alpha $ioam_node_beta \ - db01::1 0x800000 0 $1 - - [ "$1" = "encap" ] && ip -netns $ioam_node_beta link set ip6tnl0 down -} - -in_no_room() -{ - ############################################################################## - # Make sure that the receiving node won't fill the trace and will set the # - # Overflow flag if there is no room enough for its data. # - ############################################################################## - local desc="Missing trace room" - - [ "$1" = "encap" ] && mode="$1 tundst db01::1" || mode="$1" - [ "$1" = "encap" ] && ip -netns $ioam_node_beta link set ip6tnl0 up - - ip -netns $ioam_node_alpha route change db01::/64 encap ioam6 mode $mode \ - trace prealloc type 0xc00000 ns 123 size 4 dev veth0 - - run_test ${FUNCNAME[0]} "${desc} ($1 mode)" $ioam_node_alpha $ioam_node_beta \ - db01::1 0xc00000 123 $1 - - [ "$1" = "encap" ] && ip -netns $ioam_node_beta link set ip6tnl0 down -} - -in_bits() -{ - ############################################################################## - # Make sure that, for each trace type bit, the receiving node will either: # - # (i) fill the trace with its data when it is a supported bit # - # (ii) not fill the trace with its data when it is an unsupported bit # - ############################################################################## - local desc="Trace type with bit <n> only" - - local tmp=${bit2size[22]} - bit2size[22]=$(( $tmp + ${#BETA[9]} + ((4 - (${#BETA[9]} % 4)) % 4) )) - - [ "$1" = "encap" ] && mode="$1 tundst db01::1" || mode="$1" - [ "$1" = "encap" ] && ip -netns $ioam_node_beta link set ip6tnl0 up - - for i in {0..11} {22..22} - do - ip -netns $ioam_node_alpha route change db01::/64 encap ioam6 mode $mode \ - trace prealloc type ${bit2type[$i]} ns 123 size ${bit2size[$i]} \ - dev veth0 - - run_test "in_bit$i" "${desc/<n>/$i} ($1 mode)" $ioam_node_alpha \ - $ioam_node_beta db01::1 ${bit2type[$i]} 123 $1 - done - - [ "$1" = "encap" ] && ip -netns $ioam_node_beta link set ip6tnl0 down - - bit2size[22]=$tmp -} - -in_oflag() -{ - ############################################################################## - # Make sure that the receiving node won't fill the trace since the Overflow # - # flag is set. # - ############################################################################## - local desc="Overflow flag is set" - - # 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 - - [ "$1" = "encap" ] && mode="$1 tundst db01::1" || mode="$1" - [ "$1" = "encap" ] && ip -netns $ioam_node_beta link set ip6tnl0 up - - ip -netns $ioam_node_alpha route change db01::/64 encap ioam6 mode $mode \ - trace prealloc type 0xc00000 ns 123 size 4 dev veth0 - - run_test ${FUNCNAME[0]} "${desc} ($1 mode)" $ioam_node_alpha $ioam_node_beta \ - db01::1 0xc00000 123 $1 - - [ "$1" = "encap" ] && ip -netns $ioam_node_beta link set ip6tnl0 down - - # And we clean the exception for this test to get things back to normal for - # other INPUT tests - ip -netns $ioam_node_alpha ioam namespace del 123 -} - -in_full_supp_trace() -{ - ############################################################################## - # Make sure that the receiving node will correctly fill a full trace. Be # - # careful, "full trace" here does NOT mean all bits (only supported ones). # - ############################################################################## - local desc="Full supported trace" - - [ "$1" = "encap" ] && mode="$1 tundst db01::1" || mode="$1" - [ "$1" = "encap" ] && ip -netns $ioam_node_beta link set ip6tnl0 up - - ip -netns $ioam_node_alpha route change db01::/64 encap ioam6 mode $mode \ - trace prealloc type 0xfff002 ns 123 size 80 dev veth0 - - run_test ${FUNCNAME[0]} "${desc} ($1 mode)" $ioam_node_alpha $ioam_node_beta \ - db01::1 0xfff002 123 $1 - - [ "$1" = "encap" ] && ip -netns $ioam_node_beta link set ip6tnl0 down -} - - -################################################################################ -# # -# GLOBAL tests # -# # -# Three nodes (sender/router/receiver), IOAM fully enabled on every node. # -################################################################################ - -fwd_full_supp_trace() -{ - ############################################################################## - # Make sure that all three nodes correctly filled the full supported trace # - # by checking that the trace data is consistent with the predefined config. # - ############################################################################## - local desc="Forward - Full supported trace" - - [ "$1" = "encap" ] && mode="$1 tundst db02::2" || mode="$1" - [ "$1" = "encap" ] && ip -netns $ioam_node_gamma link set ip6tnl0 up - - ip -netns $ioam_node_alpha route change db02::/64 encap ioam6 mode $mode \ - trace prealloc type 0xfff002 ns 123 size 244 via db01::1 dev veth0 - - run_test ${FUNCNAME[0]} "${desc} ($1 mode)" $ioam_node_alpha $ioam_node_gamma \ - db02::2 0xfff002 123 $1 - - [ "$1" = "encap" ] && ip -netns $ioam_node_gamma link set ip6tnl0 down -} - - -################################################################################ -# # -# MAIN # -# # -################################################################################ - -npassed=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 - -ip ioam &>/dev/null -if [ $? = 1 ] -then - echo "SKIP: iproute2 too old, missing ioam command" - exit $ksft_skip -fi - -check_kernel_compatibility - -cleanup &>/dev/null -setup -run -cleanup &>/dev/null diff --git a/tools/testing/selftests/net/ioam6_parser.c b/tools/testing/selftests/net/ioam6_parser.c deleted file mode 100644 index 895e5bb5044b..000000000000 --- a/tools/testing/selftests/net/ioam6_parser.c +++ /dev/null @@ -1,674 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * Author: Justin Iurman (justin.iurman@xxxxxxxxx) - * - * IOAM tester for IPv6, see ioam6.sh for details on each test case. - */ -#include <arpa/inet.h> -#include <errno.h> -#include <limits.h> -#include <linux/const.h> -#include <linux/ioam6.h> -#include <linux/ipv6.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> - -struct ioam_config { - __u32 id; - __u64 wide; - __u16 ingr_id; - __u16 egr_id; - __u32 ingr_wide; - __u32 egr_wide; - __u32 ns_data; - __u64 ns_wide; - __u32 sc_id; - __u8 hlim; - char *sc_data; -}; - -/* - * Be careful if you modify structs below - everything MUST be kept synchronized - * with configurations inside ioam6.sh and always reflect the same. - */ - -static struct ioam_config node1 = { - .id = 1, - .wide = 11111111, - .ingr_id = 0xffff, /* default value */ - .egr_id = 101, - .ingr_wide = 0xffffffff, /* default value */ - .egr_wide = 101101, - .ns_data = 0xdeadbee0, - .ns_wide = 0xcafec0caf00dc0de, - .sc_id = 777, - .sc_data = "something that will be 4n-aligned", - .hlim = 64, -}; - -static struct ioam_config node2 = { - .id = 2, - .wide = 22222222, - .ingr_id = 201, - .egr_id = 202, - .ingr_wide = 201201, - .egr_wide = 202202, - .ns_data = 0xdeadbee1, - .ns_wide = 0xcafec0caf11dc0de, - .sc_id = 666, - .sc_data = "Hello there -Obi", - .hlim = 63, -}; - -static struct ioam_config node3 = { - .id = 3, - .wide = 33333333, - .ingr_id = 301, - .egr_id = 0xffff, /* default value */ - .ingr_wide = 301301, - .egr_wide = 0xffffffff, /* default value */ - .ns_data = 0xdeadbee2, - .ns_wide = 0xcafec0caf22dc0de, - .sc_id = 0xffffff, /* default value */ - .sc_data = NULL, - .hlim = 62, -}; - -enum { - /********** - * OUTPUT * - **********/ - TEST_OUT_UNDEF_NS, - TEST_OUT_NO_ROOM, - TEST_OUT_BIT0, - TEST_OUT_BIT1, - TEST_OUT_BIT2, - TEST_OUT_BIT3, - TEST_OUT_BIT4, - TEST_OUT_BIT5, - TEST_OUT_BIT6, - TEST_OUT_BIT7, - TEST_OUT_BIT8, - TEST_OUT_BIT9, - TEST_OUT_BIT10, - TEST_OUT_BIT11, - TEST_OUT_BIT22, - TEST_OUT_FULL_SUPP_TRACE, - - /********* - * INPUT * - *********/ - TEST_IN_UNDEF_NS, - TEST_IN_NO_ROOM, - TEST_IN_OFLAG, - TEST_IN_BIT0, - TEST_IN_BIT1, - TEST_IN_BIT2, - TEST_IN_BIT3, - TEST_IN_BIT4, - TEST_IN_BIT5, - TEST_IN_BIT6, - TEST_IN_BIT7, - TEST_IN_BIT8, - TEST_IN_BIT9, - TEST_IN_BIT10, - TEST_IN_BIT11, - TEST_IN_BIT22, - TEST_IN_FULL_SUPP_TRACE, - - /********** - * GLOBAL * - **********/ - TEST_FWD_FULL_SUPP_TRACE, - - __TEST_MAX, -}; - -static int check_ioam_header(int tid, struct ioam6_trace_hdr *ioam6h, - __u32 trace_type, __u16 ioam_ns) -{ - if (__be16_to_cpu(ioam6h->namespace_id) != ioam_ns || - __be32_to_cpu(ioam6h->type_be32) != (trace_type << 8)) - return 1; - - switch (tid) { - case TEST_OUT_UNDEF_NS: - case TEST_IN_UNDEF_NS: - return ioam6h->overflow || - ioam6h->nodelen != 1 || - ioam6h->remlen != 1; - - case TEST_OUT_NO_ROOM: - case TEST_IN_NO_ROOM: - case TEST_IN_OFLAG: - return !ioam6h->overflow || - ioam6h->nodelen != 2 || - ioam6h->remlen != 1; - - case TEST_OUT_BIT0: - case TEST_IN_BIT0: - case TEST_OUT_BIT1: - case TEST_IN_BIT1: - case TEST_OUT_BIT2: - case TEST_IN_BIT2: - case TEST_OUT_BIT3: - case TEST_IN_BIT3: - case TEST_OUT_BIT4: - case TEST_IN_BIT4: - case TEST_OUT_BIT5: - case TEST_IN_BIT5: - case TEST_OUT_BIT6: - case TEST_IN_BIT6: - case TEST_OUT_BIT7: - case TEST_IN_BIT7: - case TEST_OUT_BIT11: - case TEST_IN_BIT11: - return ioam6h->overflow || - ioam6h->nodelen != 1 || - ioam6h->remlen; - - case TEST_OUT_BIT8: - case TEST_IN_BIT8: - case TEST_OUT_BIT9: - case TEST_IN_BIT9: - case TEST_OUT_BIT10: - case TEST_IN_BIT10: - return ioam6h->overflow || - ioam6h->nodelen != 2 || - ioam6h->remlen; - - case TEST_OUT_BIT22: - case TEST_IN_BIT22: - return ioam6h->overflow || - ioam6h->nodelen || - ioam6h->remlen; - - case TEST_OUT_FULL_SUPP_TRACE: - case TEST_IN_FULL_SUPP_TRACE: - case TEST_FWD_FULL_SUPP_TRACE: - return ioam6h->overflow || - ioam6h->nodelen != 15 || - ioam6h->remlen; - - default: - break; - } - - return 1; -} - -static int check_ioam6_data(__u8 **p, struct ioam6_trace_hdr *ioam6h, - const struct ioam_config cnf) -{ - unsigned int len; - __u8 aligned; - __u64 raw64; - __u32 raw32; - - if (ioam6h->type.bit0) { - raw32 = __be32_to_cpu(*((__u32 *)*p)); - if (cnf.hlim != (raw32 >> 24) || cnf.id != (raw32 & 0xffffff)) - return 1; - *p += sizeof(__u32); - } - - if (ioam6h->type.bit1) { - raw32 = __be32_to_cpu(*((__u32 *)*p)); - if (cnf.ingr_id != (raw32 >> 16) || - cnf.egr_id != (raw32 & 0xffff)) - return 1; - *p += sizeof(__u32); - } - - if (ioam6h->type.bit2) - *p += sizeof(__u32); - - if (ioam6h->type.bit3) - *p += sizeof(__u32); - - if (ioam6h->type.bit4) { - if (__be32_to_cpu(*((__u32 *)*p)) != 0xffffffff) - return 1; - *p += sizeof(__u32); - } - - if (ioam6h->type.bit5) { - if (__be32_to_cpu(*((__u32 *)*p)) != cnf.ns_data) - return 1; - *p += sizeof(__u32); - } - - if (ioam6h->type.bit6) - *p += sizeof(__u32); - - if (ioam6h->type.bit7) { - if (__be32_to_cpu(*((__u32 *)*p)) != 0xffffffff) - return 1; - *p += sizeof(__u32); - } - - if (ioam6h->type.bit8) { - raw64 = __be64_to_cpu(*((__u64 *)*p)); - if (cnf.hlim != (raw64 >> 56) || - cnf.wide != (raw64 & 0xffffffffffffff)) - return 1; - *p += sizeof(__u64); - } - - if (ioam6h->type.bit9) { - if (__be32_to_cpu(*((__u32 *)*p)) != cnf.ingr_wide) - return 1; - *p += sizeof(__u32); - - if (__be32_to_cpu(*((__u32 *)*p)) != cnf.egr_wide) - return 1; - *p += sizeof(__u32); - } - - if (ioam6h->type.bit10) { - if (__be64_to_cpu(*((__u64 *)*p)) != cnf.ns_wide) - return 1; - *p += sizeof(__u64); - } - - if (ioam6h->type.bit11) { - if (__be32_to_cpu(*((__u32 *)*p)) != 0xffffffff) - return 1; - *p += sizeof(__u32); - } - - if (ioam6h->type.bit12) { - if (__be32_to_cpu(*((__u32 *)*p)) != 0xffffffff) - return 1; - *p += sizeof(__u32); - } - - if (ioam6h->type.bit13) { - if (__be32_to_cpu(*((__u32 *)*p)) != 0xffffffff) - return 1; - *p += sizeof(__u32); - } - - if (ioam6h->type.bit14) { - if (__be32_to_cpu(*((__u32 *)*p)) != 0xffffffff) - return 1; - *p += sizeof(__u32); - } - - if (ioam6h->type.bit15) { - if (__be32_to_cpu(*((__u32 *)*p)) != 0xffffffff) - return 1; - *p += sizeof(__u32); - } - - if (ioam6h->type.bit16) { - if (__be32_to_cpu(*((__u32 *)*p)) != 0xffffffff) - return 1; - *p += sizeof(__u32); - } - - if (ioam6h->type.bit17) { - if (__be32_to_cpu(*((__u32 *)*p)) != 0xffffffff) - return 1; - *p += sizeof(__u32); - } - - if (ioam6h->type.bit18) { - if (__be32_to_cpu(*((__u32 *)*p)) != 0xffffffff) - return 1; - *p += sizeof(__u32); - } - - if (ioam6h->type.bit19) { - if (__be32_to_cpu(*((__u32 *)*p)) != 0xffffffff) - return 1; - *p += sizeof(__u32); - } - - if (ioam6h->type.bit20) { - if (__be32_to_cpu(*((__u32 *)*p)) != 0xffffffff) - return 1; - *p += sizeof(__u32); - } - - if (ioam6h->type.bit21) { - if (__be32_to_cpu(*((__u32 *)*p)) != 0xffffffff) - return 1; - *p += sizeof(__u32); - } - - if (ioam6h->type.bit22) { - len = cnf.sc_data ? strlen(cnf.sc_data) : 0; - aligned = cnf.sc_data ? __ALIGN_KERNEL(len, 4) : 0; - - raw32 = __be32_to_cpu(*((__u32 *)*p)); - if (aligned != (raw32 >> 24) * 4 || - cnf.sc_id != (raw32 & 0xffffff)) - return 1; - *p += sizeof(__u32); - - if (cnf.sc_data) { - if (strncmp((char *)*p, cnf.sc_data, len)) - return 1; - - *p += len; - aligned -= len; - - while (aligned--) { - if (**p != '\0') - return 1; - *p += sizeof(__u8); - } - } - } - - return 0; -} - -static int check_ioam_header_and_data(int tid, struct ioam6_trace_hdr *ioam6h, - __u32 trace_type, __u16 ioam_ns) -{ - __u8 *p; - - if (check_ioam_header(tid, ioam6h, trace_type, ioam_ns)) - return 1; - - p = ioam6h->data + ioam6h->remlen * 4; - - switch (tid) { - case TEST_OUT_BIT0: - case TEST_OUT_BIT1: - case TEST_OUT_BIT2: - case TEST_OUT_BIT3: - case TEST_OUT_BIT4: - case TEST_OUT_BIT5: - case TEST_OUT_BIT6: - case TEST_OUT_BIT7: - case TEST_OUT_BIT8: - case TEST_OUT_BIT9: - case TEST_OUT_BIT10: - case TEST_OUT_BIT11: - case TEST_OUT_BIT22: - case TEST_OUT_FULL_SUPP_TRACE: - return check_ioam6_data(&p, ioam6h, node1); - - case TEST_IN_BIT0: - case TEST_IN_BIT1: - case TEST_IN_BIT2: - case TEST_IN_BIT3: - case TEST_IN_BIT4: - case TEST_IN_BIT5: - case TEST_IN_BIT6: - case TEST_IN_BIT7: - case TEST_IN_BIT8: - case TEST_IN_BIT9: - case TEST_IN_BIT10: - case TEST_IN_BIT11: - case TEST_IN_BIT22: - case TEST_IN_FULL_SUPP_TRACE: - { - __u32 tmp32 = node2.egr_wide; - __u16 tmp16 = node2.egr_id; - int res; - - node2.egr_id = 0xffff; - node2.egr_wide = 0xffffffff; - - res = check_ioam6_data(&p, ioam6h, node2); - - node2.egr_id = tmp16; - node2.egr_wide = tmp32; - - return res; - } - - case TEST_FWD_FULL_SUPP_TRACE: - if (check_ioam6_data(&p, ioam6h, node3)) - return 1; - if (check_ioam6_data(&p, ioam6h, node2)) - return 1; - return check_ioam6_data(&p, ioam6h, node1); - - default: - break; - } - - return 1; -} - -static int str2id(const char *tname) -{ - if (!strcmp("out_undef_ns", tname)) - return TEST_OUT_UNDEF_NS; - if (!strcmp("out_no_room", tname)) - return TEST_OUT_NO_ROOM; - if (!strcmp("out_bit0", tname)) - return TEST_OUT_BIT0; - if (!strcmp("out_bit1", tname)) - return TEST_OUT_BIT1; - if (!strcmp("out_bit2", tname)) - return TEST_OUT_BIT2; - if (!strcmp("out_bit3", tname)) - return TEST_OUT_BIT3; - if (!strcmp("out_bit4", tname)) - return TEST_OUT_BIT4; - if (!strcmp("out_bit5", tname)) - return TEST_OUT_BIT5; - if (!strcmp("out_bit6", tname)) - return TEST_OUT_BIT6; - if (!strcmp("out_bit7", tname)) - return TEST_OUT_BIT7; - if (!strcmp("out_bit8", tname)) - return TEST_OUT_BIT8; - if (!strcmp("out_bit9", tname)) - return TEST_OUT_BIT9; - if (!strcmp("out_bit10", tname)) - return TEST_OUT_BIT10; - if (!strcmp("out_bit11", tname)) - return TEST_OUT_BIT11; - if (!strcmp("out_bit22", tname)) - return TEST_OUT_BIT22; - if (!strcmp("out_full_supp_trace", tname)) - return TEST_OUT_FULL_SUPP_TRACE; - if (!strcmp("in_undef_ns", tname)) - return TEST_IN_UNDEF_NS; - if (!strcmp("in_no_room", tname)) - return TEST_IN_NO_ROOM; - if (!strcmp("in_oflag", tname)) - return TEST_IN_OFLAG; - if (!strcmp("in_bit0", tname)) - return TEST_IN_BIT0; - if (!strcmp("in_bit1", tname)) - return TEST_IN_BIT1; - if (!strcmp("in_bit2", tname)) - return TEST_IN_BIT2; - if (!strcmp("in_bit3", tname)) - return TEST_IN_BIT3; - if (!strcmp("in_bit4", tname)) - return TEST_IN_BIT4; - if (!strcmp("in_bit5", tname)) - return TEST_IN_BIT5; - if (!strcmp("in_bit6", tname)) - return TEST_IN_BIT6; - if (!strcmp("in_bit7", tname)) - return TEST_IN_BIT7; - if (!strcmp("in_bit8", tname)) - return TEST_IN_BIT8; - if (!strcmp("in_bit9", tname)) - return TEST_IN_BIT9; - if (!strcmp("in_bit10", tname)) - return TEST_IN_BIT10; - if (!strcmp("in_bit11", tname)) - return TEST_IN_BIT11; - if (!strcmp("in_bit22", tname)) - return TEST_IN_BIT22; - if (!strcmp("in_full_supp_trace", tname)) - return TEST_IN_FULL_SUPP_TRACE; - if (!strcmp("fwd_full_supp_trace", tname)) - return TEST_FWD_FULL_SUPP_TRACE; - - return -1; -} - -static int get_u32(__u32 *val, const char *arg, int base) -{ - unsigned long res; - char *ptr; - - if (!arg || !*arg) - return -1; - res = strtoul(arg, &ptr, base); - - if (!ptr || ptr == arg || *ptr) - return -1; - - if (res == ULONG_MAX && errno == ERANGE) - return -1; - - if (res > 0xFFFFFFFFUL) - return -1; - - *val = res; - return 0; -} - -static int get_u16(__u16 *val, const char *arg, int base) -{ - unsigned long res; - char *ptr; - - if (!arg || !*arg) - return -1; - res = strtoul(arg, &ptr, base); - - if (!ptr || ptr == arg || *ptr) - return -1; - - if (res == ULONG_MAX && errno == ERANGE) - return -1; - - if (res > 0xFFFFUL) - return -1; - - *val = res; - return 0; -} - -static int (*func[__TEST_MAX])(int, struct ioam6_trace_hdr *, __u32, __u16) = { - [TEST_OUT_UNDEF_NS] = check_ioam_header, - [TEST_OUT_NO_ROOM] = check_ioam_header, - [TEST_OUT_BIT0] = check_ioam_header_and_data, - [TEST_OUT_BIT1] = check_ioam_header_and_data, - [TEST_OUT_BIT2] = check_ioam_header_and_data, - [TEST_OUT_BIT3] = check_ioam_header_and_data, - [TEST_OUT_BIT4] = check_ioam_header_and_data, - [TEST_OUT_BIT5] = check_ioam_header_and_data, - [TEST_OUT_BIT6] = check_ioam_header_and_data, - [TEST_OUT_BIT7] = check_ioam_header_and_data, - [TEST_OUT_BIT8] = check_ioam_header_and_data, - [TEST_OUT_BIT9] = check_ioam_header_and_data, - [TEST_OUT_BIT10] = check_ioam_header_and_data, - [TEST_OUT_BIT11] = check_ioam_header_and_data, - [TEST_OUT_BIT22] = check_ioam_header_and_data, - [TEST_OUT_FULL_SUPP_TRACE] = check_ioam_header_and_data, - [TEST_IN_UNDEF_NS] = check_ioam_header, - [TEST_IN_NO_ROOM] = check_ioam_header, - [TEST_IN_OFLAG] = check_ioam_header, - [TEST_IN_BIT0] = check_ioam_header_and_data, - [TEST_IN_BIT1] = check_ioam_header_and_data, - [TEST_IN_BIT2] = check_ioam_header_and_data, - [TEST_IN_BIT3] = check_ioam_header_and_data, - [TEST_IN_BIT4] = check_ioam_header_and_data, - [TEST_IN_BIT5] = check_ioam_header_and_data, - [TEST_IN_BIT6] = check_ioam_header_and_data, - [TEST_IN_BIT7] = check_ioam_header_and_data, - [TEST_IN_BIT8] = check_ioam_header_and_data, - [TEST_IN_BIT9] = check_ioam_header_and_data, - [TEST_IN_BIT10] = check_ioam_header_and_data, - [TEST_IN_BIT11] = check_ioam_header_and_data, - [TEST_IN_BIT22] = check_ioam_header_and_data, - [TEST_IN_FULL_SUPP_TRACE] = check_ioam_header_and_data, - [TEST_FWD_FULL_SUPP_TRACE] = check_ioam_header_and_data, -}; - -int main(int argc, char **argv) -{ - int fd, size, hoplen, tid, ret = 1, on = 1; - struct ioam6_hdr *opt; - struct cmsghdr *cmsg; - struct msghdr msg; - struct iovec iov; - __u8 buffer[512]; - __u32 tr_type; - __u16 ioam_ns; - __u8 *ptr; - - if (argc != 5) - goto out; - - tid = str2id(argv[1]); - if (tid < 0 || !func[tid]) - goto out; - - if (get_u32(&tr_type, argv[2], 16) || - get_u16(&ioam_ns, argv[3], 0)) - goto out; - - fd = socket(PF_INET6, SOCK_RAW, - !strcmp(argv[4], "encap") ? IPPROTO_IPV6 : IPPROTO_ICMPV6); - if (fd < 0) - goto out; - - setsockopt(fd, IPPROTO_IPV6, IPV6_RECVHOPOPTS, &on, sizeof(on)); - - iov.iov_len = 1; - iov.iov_base = malloc(CMSG_SPACE(sizeof(buffer))); - if (!iov.iov_base) - goto close; -recv: - memset(&msg, 0, sizeof(msg)); - msg.msg_iov = &iov; - msg.msg_iovlen = 1; - msg.msg_control = buffer; - msg.msg_controllen = CMSG_SPACE(sizeof(buffer)); - - size = recvmsg(fd, &msg, 0); - if (size <= 0) - goto close; - - for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) { - if (cmsg->cmsg_level != IPPROTO_IPV6 || - cmsg->cmsg_type != IPV6_HOPOPTS || - cmsg->cmsg_len < sizeof(struct ipv6_hopopt_hdr)) - continue; - - ptr = (__u8 *)CMSG_DATA(cmsg); - - hoplen = (ptr[1] + 1) << 3; - ptr += sizeof(struct ipv6_hopopt_hdr); - - while (hoplen > 0) { - opt = (struct ioam6_hdr *)ptr; - - if (opt->opt_type == IPV6_TLV_IOAM && - opt->type == IOAM6_TYPE_PREALLOC) { - ptr += sizeof(*opt); - ret = func[tid](tid, - (struct ioam6_trace_hdr *)ptr, - tr_type, ioam_ns); - goto close; - } - - ptr += opt->opt_len + 2; - hoplen -= opt->opt_len + 2; - } - } - - goto recv; -close: - free(iov.iov_base); - close(fd); -out: - return ret; -} -- 2.34.1