Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

selftests: net: add new ioam tests

This patch re-adds the (updated) ioam selftests with support for the
tunsrc feature.

Signed-off-by: Justin Iurman <justin.iurman@uliege.be>
Link: https://patch.msgid.link/20241002162731.19847-3-justin.iurman@uliege.be
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

authored by

Justin Iurman and committed by
Jakub Kicinski
2d2b5028 897408d5

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