1#!/bin/sh 2# SPDX-License-Identifier: GPL-2.0 3# 4# nft_concat_range.sh - Tests for sets with concatenation of ranged fields 5# 6# Copyright (c) 2019 Red Hat GmbH 7# 8# Author: Stefano Brivio <sbrivio@redhat.com> 9# 10# shellcheck disable=SC2154,SC2034,SC2016,SC2030,SC2031 11# ^ Configuration and templates sourced with eval, counters reused in subshells 12 13KSELFTEST_SKIP=4 14 15# Available test groups: 16# - reported_issues: check for issues that were reported in the past 17# - correctness: check that packets match given entries, and only those 18# - concurrency: attempt races between insertion, deletion and lookup 19# - timeout: check that packets match entries until they expire 20# - performance: estimate matching rate, compare with rbtree and hash baselines 21TESTS="reported_issues correctness concurrency timeout" 22[ "${quicktest}" != "1" ] && TESTS="${TESTS} performance" 23 24# Set types, defined by TYPE_ variables below 25TYPES="net_port port_net net6_port port_proto net6_port_mac net6_port_mac_proto 26 net_port_net net_mac net_mac_icmp net6_mac_icmp net6_port_net6_port 27 net_port_mac_proto_net" 28 29# Reported bugs, also described by TYPE_ variables below 30BUGS="flush_remove_add reload" 31 32# List of possible paths to pktgen script from kernel tree for performance tests 33PKTGEN_SCRIPT_PATHS=" 34 ../../../../samples/pktgen/pktgen_bench_xmit_mode_netif_receive.sh 35 pktgen/pktgen_bench_xmit_mode_netif_receive.sh" 36 37# Definition of set types: 38# display display text for test report 39# type_spec nftables set type specifier 40# chain_spec nftables type specifier for rules mapping to set 41# dst call sequence of format_*() functions for destination fields 42# src call sequence of format_*() functions for source fields 43# start initial integer used to generate addresses and ports 44# count count of entries to generate and match 45# src_delta number summed to destination generator for source fields 46# tools list of tools for correctness and timeout tests, any can be used 47# proto L4 protocol of test packets 48# 49# race_repeat race attempts per thread, 0 disables concurrency test for type 50# flood_tools list of tools for concurrency tests, any can be used 51# flood_proto L4 protocol of test packets for concurrency tests 52# flood_spec nftables type specifier for concurrency tests 53# 54# perf_duration duration of single pktgen injection test 55# perf_spec nftables type specifier for performance tests 56# perf_dst format_*() functions for destination fields in performance test 57# perf_src format_*() functions for source fields in performance test 58# perf_entries number of set entries for performance test 59# perf_proto L3 protocol of test packets 60TYPE_net_port=" 61display net,port 62type_spec ipv4_addr . inet_service 63chain_spec ip daddr . udp dport 64dst addr4 port 65src 66start 1 67count 5 68src_delta 2000 69tools sendip nc bash 70proto udp 71 72race_repeat 3 73flood_tools iperf3 iperf netperf 74flood_proto udp 75flood_spec ip daddr . udp dport 76 77perf_duration 5 78perf_spec ip daddr . udp dport 79perf_dst addr4 port 80perf_src 81perf_entries 1000 82perf_proto ipv4 83" 84 85TYPE_port_net=" 86display port,net 87type_spec inet_service . ipv4_addr 88chain_spec udp dport . ip daddr 89dst port addr4 90src 91start 1 92count 5 93src_delta 2000 94tools sendip nc bash 95proto udp 96 97race_repeat 3 98flood_tools iperf3 iperf netperf 99flood_proto udp 100flood_spec udp dport . ip daddr 101 102perf_duration 5 103perf_spec udp dport . ip daddr 104perf_dst port addr4 105perf_src 106perf_entries 100 107perf_proto ipv4 108" 109 110TYPE_net6_port=" 111display net6,port 112type_spec ipv6_addr . inet_service 113chain_spec ip6 daddr . udp dport 114dst addr6 port 115src 116start 10 117count 5 118src_delta 2000 119tools sendip nc bash 120proto udp6 121 122race_repeat 3 123flood_tools iperf3 iperf netperf 124flood_proto tcp6 125flood_spec ip6 daddr . udp dport 126 127perf_duration 5 128perf_spec ip6 daddr . udp dport 129perf_dst addr6 port 130perf_src 131perf_entries 1000 132perf_proto ipv6 133" 134 135TYPE_port_proto=" 136display port,proto 137type_spec inet_service . inet_proto 138chain_spec udp dport . meta l4proto 139dst port proto 140src 141start 1 142count 5 143src_delta 2000 144tools sendip nc bash 145proto udp 146 147race_repeat 0 148 149perf_duration 5 150perf_spec udp dport . meta l4proto 151perf_dst port proto 152perf_src 153perf_entries 30000 154perf_proto ipv4 155" 156 157TYPE_net6_port_mac=" 158display net6,port,mac 159type_spec ipv6_addr . inet_service . ether_addr 160chain_spec ip6 daddr . udp dport . ether saddr 161dst addr6 port 162src mac 163start 10 164count 5 165src_delta 2000 166tools sendip nc bash 167proto udp6 168 169race_repeat 0 170 171perf_duration 5 172perf_spec ip6 daddr . udp dport . ether daddr 173perf_dst addr6 port mac 174perf_src 175perf_entries 10 176perf_proto ipv6 177" 178 179TYPE_net6_port_mac_proto=" 180display net6,port,mac,proto 181type_spec ipv6_addr . inet_service . ether_addr . inet_proto 182chain_spec ip6 daddr . udp dport . ether saddr . meta l4proto 183dst addr6 port 184src mac proto 185start 10 186count 5 187src_delta 2000 188tools sendip nc bash 189proto udp6 190 191race_repeat 0 192 193perf_duration 5 194perf_spec ip6 daddr . udp dport . ether daddr . meta l4proto 195perf_dst addr6 port mac proto 196perf_src 197perf_entries 1000 198perf_proto ipv6 199" 200 201TYPE_net_port_net=" 202display net,port,net 203type_spec ipv4_addr . inet_service . ipv4_addr 204chain_spec ip daddr . udp dport . ip saddr 205dst addr4 port 206src addr4 207start 1 208count 5 209src_delta 2000 210tools sendip nc bash 211proto udp 212 213race_repeat 3 214flood_tools iperf3 iperf netperf 215flood_proto tcp 216flood_spec ip daddr . udp dport . ip saddr 217 218perf_duration 0 219" 220 221TYPE_net6_port_net6_port=" 222display net6,port,net6,port 223type_spec ipv6_addr . inet_service . ipv6_addr . inet_service 224chain_spec ip6 daddr . udp dport . ip6 saddr . udp sport 225dst addr6 port 226src addr6 port 227start 10 228count 5 229src_delta 2000 230tools sendip nc 231proto udp6 232 233race_repeat 3 234flood_tools iperf3 iperf netperf 235flood_proto tcp6 236flood_spec ip6 daddr . tcp dport . ip6 saddr . tcp sport 237 238perf_duration 0 239" 240 241TYPE_net_port_mac_proto_net=" 242display net,port,mac,proto,net 243type_spec ipv4_addr . inet_service . ether_addr . inet_proto . ipv4_addr 244chain_spec ip daddr . udp dport . ether saddr . meta l4proto . ip saddr 245dst addr4 port 246src mac proto addr4 247start 1 248count 5 249src_delta 2000 250tools sendip nc bash 251proto udp 252 253race_repeat 0 254 255perf_duration 0 256" 257 258TYPE_net_mac=" 259display net,mac 260type_spec ipv4_addr . ether_addr 261chain_spec ip daddr . ether saddr 262dst addr4 263src mac 264start 1 265count 5 266src_delta 2000 267tools sendip nc bash 268proto udp 269 270race_repeat 0 271 272perf_duration 5 273perf_spec ip daddr . ether daddr 274perf_dst addr4 mac 275perf_src 276perf_entries 1000 277perf_proto ipv4 278" 279 280TYPE_net_mac_icmp=" 281display net,mac - ICMP 282type_spec ipv4_addr . ether_addr 283chain_spec ip daddr . ether saddr 284dst addr4 285src mac 286start 1 287count 5 288src_delta 2000 289tools ping 290proto icmp 291 292race_repeat 0 293 294perf_duration 0 295" 296 297TYPE_net6_mac_icmp=" 298display net6,mac - ICMPv6 299type_spec ipv6_addr . ether_addr 300chain_spec ip6 daddr . ether saddr 301dst addr6 302src mac 303start 10 304count 50 305src_delta 2000 306tools ping 307proto icmp6 308 309race_repeat 0 310 311perf_duration 0 312" 313 314TYPE_net_port_proto_net=" 315display net,port,proto,net 316type_spec ipv4_addr . inet_service . inet_proto . ipv4_addr 317chain_spec ip daddr . udp dport . meta l4proto . ip saddr 318dst addr4 port proto 319src addr4 320start 1 321count 5 322src_delta 2000 323tools sendip nc 324proto udp 325 326race_repeat 3 327flood_tools iperf3 iperf netperf 328flood_proto tcp 329flood_spec ip daddr . tcp dport . meta l4proto . ip saddr 330 331perf_duration 0 332" 333 334# Definition of tests for bugs reported in the past: 335# display display text for test report 336TYPE_flush_remove_add=" 337display Add two elements, flush, re-add 338" 339 340TYPE_reload=" 341display net,mac with reload 342type_spec ipv4_addr . ether_addr 343chain_spec ip daddr . ether saddr 344dst addr4 345src mac 346start 1 347count 1 348src_delta 2000 349tools sendip nc bash 350proto udp 351 352race_repeat 0 353 354perf_duration 0 355" 356 357# Set template for all tests, types and rules are filled in depending on test 358set_template=' 359flush ruleset 360 361table inet filter { 362 counter test { 363 packets 0 bytes 0 364 } 365 366 set test { 367 type ${type_spec} 368 flags interval,timeout 369 } 370 371 chain input { 372 type filter hook prerouting priority 0; policy accept; 373 ${chain_spec} @test counter name \"test\" 374 } 375} 376 377table netdev perf { 378 counter test { 379 packets 0 bytes 0 380 } 381 382 counter match { 383 packets 0 bytes 0 384 } 385 386 set test { 387 type ${type_spec} 388 flags interval 389 } 390 391 set norange { 392 type ${type_spec} 393 } 394 395 set noconcat { 396 type ${type_spec%% *} 397 flags interval 398 } 399 400 chain test { 401 type filter hook ingress device veth_a priority 0; 402 } 403} 404' 405 406err_buf= 407info_buf= 408 409# Append string to error buffer 410err() { 411 err_buf="${err_buf}${1} 412" 413} 414 415# Append string to information buffer 416info() { 417 info_buf="${info_buf}${1} 418" 419} 420 421# Flush error buffer to stdout 422err_flush() { 423 printf "%s" "${err_buf}" 424 err_buf= 425} 426 427# Flush information buffer to stdout 428info_flush() { 429 printf "%s" "${info_buf}" 430 info_buf= 431} 432 433# Setup veth pair: this namespace receives traffic, B generates it 434setup_veth() { 435 ip netns add B 436 ip link add veth_a type veth peer name veth_b || return 1 437 438 ip link set veth_a up 439 ip link set veth_b netns B 440 441 ip -n B link set veth_b up 442 443 ip addr add dev veth_a 10.0.0.1 444 ip route add default dev veth_a 445 446 ip -6 addr add fe80::1/64 dev veth_a nodad 447 ip -6 addr add 2001:db8::1/64 dev veth_a nodad 448 ip -6 route add default dev veth_a 449 450 ip -n B route add default dev veth_b 451 452 ip -6 -n B addr add fe80::2/64 dev veth_b nodad 453 ip -6 -n B addr add 2001:db8::2/64 dev veth_b nodad 454 ip -6 -n B route add default dev veth_b 455 456 B() { 457 ip netns exec B "$@" >/dev/null 2>&1 458 } 459 460 sleep 2 461} 462 463# Fill in set template and initialise set 464setup_set() { 465 eval "echo \"${set_template}\"" | nft -f - 466} 467 468# Check that at least one of the needed tools is available 469check_tools() { 470 [ -z "${tools}" ] && return 0 471 472 __tools= 473 for tool in ${tools}; do 474 if [ "${tool}" = "nc" ] && [ "${proto}" = "udp6" ] && \ 475 ! nc -u -w0 1.1.1.1 1 2>/dev/null; then 476 # Some GNU netcat builds might not support IPv6 477 __tools="${__tools} netcat-openbsd" 478 continue 479 fi 480 __tools="${__tools} ${tool}" 481 482 command -v "${tool}" >/dev/null && return 0 483 done 484 err "need one of:${__tools}, skipping" && return 1 485} 486 487# Set up function to send ICMP packets 488setup_send_icmp() { 489 send_icmp() { 490 B ping -c1 -W1 "${dst_addr4}" >/dev/null 2>&1 491 } 492} 493 494# Set up function to send ICMPv6 packets 495setup_send_icmp6() { 496 if command -v ping6 >/dev/null; then 497 send_icmp6() { 498 ip -6 addr add "${dst_addr6}" dev veth_a nodad \ 499 2>/dev/null 500 B ping6 -q -c1 -W1 "${dst_addr6}" 501 } 502 else 503 send_icmp6() { 504 ip -6 addr add "${dst_addr6}" dev veth_a nodad \ 505 2>/dev/null 506 B ping -q -6 -c1 -W1 "${dst_addr6}" 507 } 508 fi 509} 510 511# Set up function to send single UDP packets on IPv4 512setup_send_udp() { 513 if command -v sendip >/dev/null; then 514 send_udp() { 515 [ -n "${src_port}" ] && src_port="-us ${src_port}" 516 [ -n "${dst_port}" ] && dst_port="-ud ${dst_port}" 517 [ -n "${src_addr4}" ] && src_addr4="-is ${src_addr4}" 518 519 # shellcheck disable=SC2086 # sendip needs split options 520 B sendip -p ipv4 -p udp ${src_addr4} ${src_port} \ 521 ${dst_port} "${dst_addr4}" 522 523 src_port= 524 dst_port= 525 src_addr4= 526 } 527 elif command -v nc >/dev/null; then 528 if nc -u -w0 1.1.1.1 1 2>/dev/null; then 529 # OpenBSD netcat 530 nc_opt="-w0" 531 else 532 # GNU netcat 533 nc_opt="-q0" 534 fi 535 536 send_udp() { 537 if [ -n "${src_addr4}" ]; then 538 B ip addr add "${src_addr4}" dev veth_b 539 __src_addr4="-s ${src_addr4}" 540 fi 541 ip addr add "${dst_addr4}" dev veth_a 2>/dev/null 542 [ -n "${src_port}" ] && src_port="-p ${src_port}" 543 544 echo "" | B nc -u "${nc_opt}" "${__src_addr4}" \ 545 "${src_port}" "${dst_addr4}" "${dst_port}" 546 547 src_addr4= 548 src_port= 549 } 550 elif [ -z "$(bash -c 'type -p')" ]; then 551 send_udp() { 552 ip addr add "${dst_addr4}" dev veth_a 2>/dev/null 553 if [ -n "${src_addr4}" ]; then 554 B ip addr add "${src_addr4}/16" dev veth_b 555 B ip route add default dev veth_b 556 fi 557 558 B bash -c "echo > /dev/udp/${dst_addr4}/${dst_port}" 559 560 if [ -n "${src_addr4}" ]; then 561 B ip addr del "${src_addr4}/16" dev veth_b 562 fi 563 src_addr4= 564 } 565 else 566 return 1 567 fi 568} 569 570# Set up function to send single UDP packets on IPv6 571setup_send_udp6() { 572 if command -v sendip >/dev/null; then 573 send_udp6() { 574 [ -n "${src_port}" ] && src_port="-us ${src_port}" 575 [ -n "${dst_port}" ] && dst_port="-ud ${dst_port}" 576 if [ -n "${src_addr6}" ]; then 577 src_addr6="-6s ${src_addr6}" 578 else 579 src_addr6="-6s 2001:db8::2" 580 fi 581 ip -6 addr add "${dst_addr6}" dev veth_a nodad \ 582 2>/dev/null 583 584 # shellcheck disable=SC2086 # this needs split options 585 B sendip -p ipv6 -p udp ${src_addr6} ${src_port} \ 586 ${dst_port} "${dst_addr6}" 587 588 src_port= 589 dst_port= 590 src_addr6= 591 } 592 elif command -v nc >/dev/null && nc -u -w0 1.1.1.1 1 2>/dev/null; then 593 # GNU netcat might not work with IPv6, try next tool 594 send_udp6() { 595 ip -6 addr add "${dst_addr6}" dev veth_a nodad \ 596 2>/dev/null 597 if [ -n "${src_addr6}" ]; then 598 B ip addr add "${src_addr6}" dev veth_b nodad 599 else 600 src_addr6="2001:db8::2" 601 fi 602 [ -n "${src_port}" ] && src_port="-p ${src_port}" 603 604 # shellcheck disable=SC2086 # this needs split options 605 echo "" | B nc -u w0 "-s${src_addr6}" ${src_port} \ 606 ${dst_addr6} ${dst_port} 607 608 src_addr6= 609 src_port= 610 } 611 elif [ -z "$(bash -c 'type -p')" ]; then 612 send_udp6() { 613 ip -6 addr add "${dst_addr6}" dev veth_a nodad \ 614 2>/dev/null 615 B ip addr add "${src_addr6}" dev veth_b nodad 616 B bash -c "echo > /dev/udp/${dst_addr6}/${dst_port}" 617 ip -6 addr del "${dst_addr6}" dev veth_a 2>/dev/null 618 } 619 else 620 return 1 621 fi 622} 623 624# Set up function to send TCP traffic on IPv4 625setup_flood_tcp() { 626 if command -v iperf3 >/dev/null; then 627 flood_tcp() { 628 [ -n "${dst_port}" ] && dst_port="-p ${dst_port}" 629 if [ -n "${src_addr4}" ]; then 630 B ip addr add "${src_addr4}/16" dev veth_b 631 src_addr4="-B ${src_addr4}" 632 else 633 B ip addr add dev veth_b 10.0.0.2 634 src_addr4="-B 10.0.0.2" 635 fi 636 if [ -n "${src_port}" ]; then 637 src_port="--cport ${src_port}" 638 fi 639 B ip route add default dev veth_b 2>/dev/null 640 ip addr add "${dst_addr4}" dev veth_a 2>/dev/null 641 642 # shellcheck disable=SC2086 # this needs split options 643 iperf3 -s -DB "${dst_addr4}" ${dst_port} >/dev/null 2>&1 644 sleep 2 645 646 # shellcheck disable=SC2086 # this needs split options 647 B iperf3 -c "${dst_addr4}" ${dst_port} ${src_port} \ 648 ${src_addr4} -l16 -t 1000 649 650 src_addr4= 651 src_port= 652 dst_port= 653 } 654 elif command -v iperf >/dev/null; then 655 flood_tcp() { 656 [ -n "${dst_port}" ] && dst_port="-p ${dst_port}" 657 if [ -n "${src_addr4}" ]; then 658 B ip addr add "${src_addr4}/16" dev veth_b 659 src_addr4="-B ${src_addr4}" 660 else 661 B ip addr add dev veth_b 10.0.0.2 2>/dev/null 662 src_addr4="-B 10.0.0.2" 663 fi 664 if [ -n "${src_port}" ]; then 665 src_addr4="${src_addr4}:${src_port}" 666 fi 667 B ip route add default dev veth_b 668 ip addr add "${dst_addr4}" dev veth_a 2>/dev/null 669 670 # shellcheck disable=SC2086 # this needs split options 671 iperf -s -DB "${dst_addr4}" ${dst_port} >/dev/null 2>&1 672 sleep 2 673 674 # shellcheck disable=SC2086 # this needs split options 675 B iperf -c "${dst_addr4}" ${dst_port} ${src_addr4} \ 676 -l20 -t 1000 677 678 src_addr4= 679 src_port= 680 dst_port= 681 } 682 elif command -v netperf >/dev/null; then 683 flood_tcp() { 684 [ -n "${dst_port}" ] && dst_port="-p ${dst_port}" 685 if [ -n "${src_addr4}" ]; then 686 B ip addr add "${src_addr4}/16" dev veth_b 687 else 688 B ip addr add dev veth_b 10.0.0.2 689 src_addr4="10.0.0.2" 690 fi 691 if [ -n "${src_port}" ]; then 692 dst_port="${dst_port},${src_port}" 693 fi 694 B ip route add default dev veth_b 695 ip addr add "${dst_addr4}" dev veth_a 2>/dev/null 696 697 # shellcheck disable=SC2086 # this needs split options 698 netserver -4 ${dst_port} -L "${dst_addr4}" \ 699 >/dev/null 2>&1 700 sleep 2 701 702 # shellcheck disable=SC2086 # this needs split options 703 B netperf -4 -H "${dst_addr4}" ${dst_port} \ 704 -L "${src_addr4}" -l 1000 -t TCP_STREAM 705 706 src_addr4= 707 src_port= 708 dst_port= 709 } 710 else 711 return 1 712 fi 713} 714 715# Set up function to send TCP traffic on IPv6 716setup_flood_tcp6() { 717 if command -v iperf3 >/dev/null; then 718 flood_tcp6() { 719 [ -n "${dst_port}" ] && dst_port="-p ${dst_port}" 720 if [ -n "${src_addr6}" ]; then 721 B ip addr add "${src_addr6}" dev veth_b nodad 722 src_addr6="-B ${src_addr6}" 723 else 724 src_addr6="-B 2001:db8::2" 725 fi 726 if [ -n "${src_port}" ]; then 727 src_port="--cport ${src_port}" 728 fi 729 B ip route add default dev veth_b 730 ip -6 addr add "${dst_addr6}" dev veth_a nodad \ 731 2>/dev/null 732 733 # shellcheck disable=SC2086 # this needs split options 734 iperf3 -s -DB "${dst_addr6}" ${dst_port} >/dev/null 2>&1 735 sleep 2 736 737 # shellcheck disable=SC2086 # this needs split options 738 B iperf3 -c "${dst_addr6}" ${dst_port} \ 739 ${src_port} ${src_addr6} -l16 -t 1000 740 741 src_addr6= 742 src_port= 743 dst_port= 744 } 745 elif command -v iperf >/dev/null; then 746 flood_tcp6() { 747 [ -n "${dst_port}" ] && dst_port="-p ${dst_port}" 748 if [ -n "${src_addr6}" ]; then 749 B ip addr add "${src_addr6}" dev veth_b nodad 750 src_addr6="-B ${src_addr6}" 751 else 752 src_addr6="-B 2001:db8::2" 753 fi 754 if [ -n "${src_port}" ]; then 755 src_addr6="${src_addr6}:${src_port}" 756 fi 757 B ip route add default dev veth_b 758 ip -6 addr add "${dst_addr6}" dev veth_a nodad \ 759 2>/dev/null 760 761 # shellcheck disable=SC2086 # this needs split options 762 iperf -s -VDB "${dst_addr6}" ${dst_port} >/dev/null 2>&1 763 sleep 2 764 765 # shellcheck disable=SC2086 # this needs split options 766 B iperf -c "${dst_addr6}" -V ${dst_port} \ 767 ${src_addr6} -l1 -t 1000 768 769 src_addr6= 770 src_port= 771 dst_port= 772 } 773 elif command -v netperf >/dev/null; then 774 flood_tcp6() { 775 [ -n "${dst_port}" ] && dst_port="-p ${dst_port}" 776 if [ -n "${src_addr6}" ]; then 777 B ip addr add "${src_addr6}" dev veth_b nodad 778 else 779 src_addr6="2001:db8::2" 780 fi 781 if [ -n "${src_port}" ]; then 782 dst_port="${dst_port},${src_port}" 783 fi 784 B ip route add default dev veth_b 785 ip -6 addr add "${dst_addr6}" dev veth_a nodad \ 786 2>/dev/null 787 788 # shellcheck disable=SC2086 # this needs split options 789 netserver -6 ${dst_port} -L "${dst_addr6}" \ 790 >/dev/null 2>&1 791 sleep 2 792 793 # shellcheck disable=SC2086 # this needs split options 794 B netperf -6 -H "${dst_addr6}" ${dst_port} \ 795 -L "${src_addr6}" -l 1000 -t TCP_STREAM 796 797 src_addr6= 798 src_port= 799 dst_port= 800 } 801 else 802 return 1 803 fi 804} 805 806# Set up function to send UDP traffic on IPv4 807setup_flood_udp() { 808 if command -v iperf3 >/dev/null; then 809 flood_udp() { 810 [ -n "${dst_port}" ] && dst_port="-p ${dst_port}" 811 if [ -n "${src_addr4}" ]; then 812 B ip addr add "${src_addr4}/16" dev veth_b 813 src_addr4="-B ${src_addr4}" 814 else 815 B ip addr add dev veth_b 10.0.0.2 2>/dev/null 816 src_addr4="-B 10.0.0.2" 817 fi 818 if [ -n "${src_port}" ]; then 819 src_port="--cport ${src_port}" 820 fi 821 B ip route add default dev veth_b 822 ip addr add "${dst_addr4}" dev veth_a 2>/dev/null 823 824 # shellcheck disable=SC2086 # this needs split options 825 iperf3 -s -DB "${dst_addr4}" ${dst_port} 826 sleep 2 827 828 # shellcheck disable=SC2086 # this needs split options 829 B iperf3 -u -c "${dst_addr4}" -Z -b 100M -l16 -t1000 \ 830 ${dst_port} ${src_port} ${src_addr4} 831 832 src_addr4= 833 src_port= 834 dst_port= 835 } 836 elif command -v iperf >/dev/null; then 837 flood_udp() { 838 [ -n "${dst_port}" ] && dst_port="-p ${dst_port}" 839 if [ -n "${src_addr4}" ]; then 840 B ip addr add "${src_addr4}/16" dev veth_b 841 src_addr4="-B ${src_addr4}" 842 else 843 B ip addr add dev veth_b 10.0.0.2 844 src_addr4="-B 10.0.0.2" 845 fi 846 if [ -n "${src_port}" ]; then 847 src_addr4="${src_addr4}:${src_port}" 848 fi 849 B ip route add default dev veth_b 850 ip addr add "${dst_addr4}" dev veth_a 2>/dev/null 851 852 # shellcheck disable=SC2086 # this needs split options 853 iperf -u -sDB "${dst_addr4}" ${dst_port} >/dev/null 2>&1 854 sleep 2 855 856 # shellcheck disable=SC2086 # this needs split options 857 B iperf -u -c "${dst_addr4}" -b 100M -l1 -t1000 \ 858 ${dst_port} ${src_addr4} 859 860 src_addr4= 861 src_port= 862 dst_port= 863 } 864 elif command -v netperf >/dev/null; then 865 flood_udp() { 866 [ -n "${dst_port}" ] && dst_port="-p ${dst_port}" 867 if [ -n "${src_addr4}" ]; then 868 B ip addr add "${src_addr4}/16" dev veth_b 869 else 870 B ip addr add dev veth_b 10.0.0.2 871 src_addr4="10.0.0.2" 872 fi 873 if [ -n "${src_port}" ]; then 874 dst_port="${dst_port},${src_port}" 875 fi 876 B ip route add default dev veth_b 877 ip addr add "${dst_addr4}" dev veth_a 2>/dev/null 878 879 # shellcheck disable=SC2086 # this needs split options 880 netserver -4 ${dst_port} -L "${dst_addr4}" \ 881 >/dev/null 2>&1 882 sleep 2 883 884 # shellcheck disable=SC2086 # this needs split options 885 B netperf -4 -H "${dst_addr4}" ${dst_port} \ 886 -L "${src_addr4}" -l 1000 -t UDP_STREAM 887 888 src_addr4= 889 src_port= 890 dst_port= 891 } 892 else 893 return 1 894 fi 895} 896 897# Find pktgen script and set up function to start pktgen injection 898setup_perf() { 899 for pktgen_script_path in ${PKTGEN_SCRIPT_PATHS} __notfound; do 900 command -v "${pktgen_script_path}" >/dev/null && break 901 done 902 [ "${pktgen_script_path}" = "__notfound" ] && return 1 903 904 perf_ipv4() { 905 ${pktgen_script_path} -s80 \ 906 -i veth_a -d "${dst_addr4}" -p "${dst_port}" \ 907 -m "${dst_mac}" \ 908 -t $(($(nproc) / 5 + 1)) -b10000 -n0 2>/dev/null & 909 perf_pid=$! 910 } 911 perf_ipv6() { 912 IP6=6 ${pktgen_script_path} -s100 \ 913 -i veth_a -d "${dst_addr6}" -p "${dst_port}" \ 914 -m "${dst_mac}" \ 915 -t $(($(nproc) / 5 + 1)) -b10000 -n0 2>/dev/null & 916 perf_pid=$! 917 } 918} 919 920# Clean up before each test 921cleanup() { 922 nft reset counter inet filter test >/dev/null 2>&1 923 nft flush ruleset >/dev/null 2>&1 924 ip link del dummy0 2>/dev/null 925 ip route del default 2>/dev/null 926 ip -6 route del default 2>/dev/null 927 ip netns del B 2>/dev/null 928 ip link del veth_a 2>/dev/null 929 timeout= 930 killall iperf3 2>/dev/null 931 killall iperf 2>/dev/null 932 killall netperf 2>/dev/null 933 killall netserver 2>/dev/null 934 rm -f ${tmp} 935 sleep 2 936} 937 938# Entry point for setup functions 939setup() { 940 if [ "$(id -u)" -ne 0 ]; then 941 echo " need to run as root" 942 exit ${KSELFTEST_SKIP} 943 fi 944 945 cleanup 946 check_tools || return 1 947 for arg do 948 if ! eval setup_"${arg}"; then 949 err " ${arg} not supported" 950 return 1 951 fi 952 done 953} 954 955# Format integer into IPv4 address, summing 10.0.0.5 (arbitrary) to it 956format_addr4() { 957 a=$((${1} + 16777216 * 10 + 5)) 958 printf "%i.%i.%i.%i" \ 959 "$((a / 16777216))" "$((a % 16777216 / 65536))" \ 960 "$((a % 65536 / 256))" "$((a % 256))" 961} 962 963# Format integer into IPv6 address, summing 2001:db8:: to it 964format_addr6() { 965 printf "2001:db8::%04x:%04x" "$((${1} / 65536))" "$((${1} % 65536))" 966} 967 968# Format integer into EUI-48 address, summing 00:01:00:00:00:00 to it 969format_mac() { 970 printf "00:01:%02x:%02x:%02x:%02x" \ 971 "$((${1} / 16777216))" "$((${1} % 16777216 / 65536))" \ 972 "$((${1} % 65536 / 256))" "$((${1} % 256))" 973} 974 975# Format integer into port, avoid 0 port 976format_port() { 977 printf "%i" "$((${1} % 65534 + 1))" 978} 979 980# Drop suffixed '6' from L4 protocol, if any 981format_proto() { 982 printf "%s" "${proto}" | tr -d 6 983} 984 985# Format destination and source fields into nft concatenated type 986format() { 987 __start= 988 __end= 989 __expr="{ " 990 991 for f in ${dst}; do 992 [ "${__expr}" != "{ " ] && __expr="${__expr} . " 993 994 __start="$(eval format_"${f}" "${start}")" 995 __end="$(eval format_"${f}" "${end}")" 996 997 if [ "${f}" = "proto" ]; then 998 __expr="${__expr}${__start}" 999 else 1000 __expr="${__expr}${__start}-${__end}" 1001 fi 1002 done 1003 for f in ${src}; do 1004 __expr="${__expr} . " 1005 __start="$(eval format_"${f}" "${srcstart}")" 1006 __end="$(eval format_"${f}" "${srcend}")" 1007 1008 if [ "${f}" = "proto" ]; then 1009 __expr="${__expr}${__start}" 1010 else 1011 __expr="${__expr}${__start}-${__end}" 1012 fi 1013 done 1014 1015 if [ -n "${timeout}" ]; then 1016 echo "${__expr} timeout ${timeout}s }" 1017 else 1018 echo "${__expr} }" 1019 fi 1020} 1021 1022# Format destination and source fields into nft type, start element only 1023format_norange() { 1024 __expr="{ " 1025 1026 for f in ${dst}; do 1027 [ "${__expr}" != "{ " ] && __expr="${__expr} . " 1028 1029 __expr="${__expr}$(eval format_"${f}" "${start}")" 1030 done 1031 for f in ${src}; do 1032 __expr="${__expr} . $(eval format_"${f}" "${start}")" 1033 done 1034 1035 echo "${__expr} }" 1036} 1037 1038# Format first destination field into nft type 1039format_noconcat() { 1040 for f in ${dst}; do 1041 __start="$(eval format_"${f}" "${start}")" 1042 __end="$(eval format_"${f}" "${end}")" 1043 1044 if [ "${f}" = "proto" ]; then 1045 echo "{ ${__start} }" 1046 else 1047 echo "{ ${__start}-${__end} }" 1048 fi 1049 return 1050 done 1051} 1052 1053# Add single entry to 'test' set in 'inet filter' table 1054add() { 1055 if ! nft add element inet filter test "${1}"; then 1056 err "Failed to add ${1} given ruleset:" 1057 err "$(nft -a list ruleset)" 1058 return 1 1059 fi 1060} 1061 1062# Format and output entries for sets in 'netdev perf' table 1063add_perf() { 1064 if [ "${1}" = "test" ]; then 1065 echo "add element netdev perf test $(format)" 1066 elif [ "${1}" = "norange" ]; then 1067 echo "add element netdev perf norange $(format_norange)" 1068 elif [ "${1}" = "noconcat" ]; then 1069 echo "add element netdev perf noconcat $(format_noconcat)" 1070 fi 1071} 1072 1073# Add single entry to 'norange' set in 'netdev perf' table 1074add_perf_norange() { 1075 if ! nft add element netdev perf norange "${1}"; then 1076 err "Failed to add ${1} given ruleset:" 1077 err "$(nft -a list ruleset)" 1078 return 1 1079 fi 1080} 1081 1082# Add single entry to 'noconcat' set in 'netdev perf' table 1083add_perf_noconcat() { 1084 if ! nft add element netdev perf noconcat "${1}"; then 1085 err "Failed to add ${1} given ruleset:" 1086 err "$(nft -a list ruleset)" 1087 return 1 1088 fi 1089} 1090 1091# Delete single entry from set 1092del() { 1093 if ! nft delete element inet filter test "${1}"; then 1094 err "Failed to delete ${1} given ruleset:" 1095 err "$(nft -a list ruleset)" 1096 return 1 1097 fi 1098} 1099 1100# Return packet count from 'test' counter in 'inet filter' table 1101count_packets() { 1102 found=0 1103 for token in $(nft list counter inet filter test); do 1104 [ ${found} -eq 1 ] && echo "${token}" && return 1105 [ "${token}" = "packets" ] && found=1 1106 done 1107} 1108 1109# Return packet count from 'test' counter in 'netdev perf' table 1110count_perf_packets() { 1111 found=0 1112 for token in $(nft list counter netdev perf test); do 1113 [ ${found} -eq 1 ] && echo "${token}" && return 1114 [ "${token}" = "packets" ] && found=1 1115 done 1116} 1117 1118# Set MAC addresses, send traffic according to specifier 1119flood() { 1120 ip link set veth_a address "$(format_mac "${1}")" 1121 ip -n B link set veth_b address "$(format_mac "${2}")" 1122 1123 for f in ${dst}; do 1124 eval dst_"$f"=\$\(format_\$f "${1}"\) 1125 done 1126 for f in ${src}; do 1127 eval src_"$f"=\$\(format_\$f "${2}"\) 1128 done 1129 eval flood_\$proto 1130} 1131 1132# Set MAC addresses, start pktgen injection 1133perf() { 1134 dst_mac="$(format_mac "${1}")" 1135 ip link set veth_a address "${dst_mac}" 1136 1137 for f in ${dst}; do 1138 eval dst_"$f"=\$\(format_\$f "${1}"\) 1139 done 1140 for f in ${src}; do 1141 eval src_"$f"=\$\(format_\$f "${2}"\) 1142 done 1143 eval perf_\$perf_proto 1144} 1145 1146# Set MAC addresses, send single packet, check that it matches, reset counter 1147send_match() { 1148 ip link set veth_a address "$(format_mac "${1}")" 1149 ip -n B link set veth_b address "$(format_mac "${2}")" 1150 1151 for f in ${dst}; do 1152 eval dst_"$f"=\$\(format_\$f "${1}"\) 1153 done 1154 for f in ${src}; do 1155 eval src_"$f"=\$\(format_\$f "${2}"\) 1156 done 1157 eval send_\$proto 1158 if [ "$(count_packets)" != "1" ]; then 1159 err "${proto} packet to:" 1160 err " $(for f in ${dst}; do 1161 eval format_\$f "${1}"; printf ' '; done)" 1162 err "from:" 1163 err " $(for f in ${src}; do 1164 eval format_\$f "${2}"; printf ' '; done)" 1165 err "should have matched ruleset:" 1166 err "$(nft -a list ruleset)" 1167 return 1 1168 fi 1169 nft reset counter inet filter test >/dev/null 1170} 1171 1172# Set MAC addresses, send single packet, check that it doesn't match 1173send_nomatch() { 1174 ip link set veth_a address "$(format_mac "${1}")" 1175 ip -n B link set veth_b address "$(format_mac "${2}")" 1176 1177 for f in ${dst}; do 1178 eval dst_"$f"=\$\(format_\$f "${1}"\) 1179 done 1180 for f in ${src}; do 1181 eval src_"$f"=\$\(format_\$f "${2}"\) 1182 done 1183 eval send_\$proto 1184 if [ "$(count_packets)" != "0" ]; then 1185 err "${proto} packet to:" 1186 err " $(for f in ${dst}; do 1187 eval format_\$f "${1}"; printf ' '; done)" 1188 err "from:" 1189 err " $(for f in ${src}; do 1190 eval format_\$f "${2}"; printf ' '; done)" 1191 err "should not have matched ruleset:" 1192 err "$(nft -a list ruleset)" 1193 return 1 1194 fi 1195} 1196 1197# Correctness test template: 1198# - add ranged element, check that packets match it 1199# - check that packets outside range don't match it 1200# - remove some elements, check that packets don't match anymore 1201test_correctness() { 1202 setup veth send_"${proto}" set || return ${KSELFTEST_SKIP} 1203 1204 range_size=1 1205 for i in $(seq "${start}" $((start + count))); do 1206 end=$((start + range_size)) 1207 1208 # Avoid negative or zero-sized port ranges 1209 if [ $((end / 65534)) -gt $((start / 65534)) ]; then 1210 start=${end} 1211 end=$((end + 1)) 1212 fi 1213 srcstart=$((start + src_delta)) 1214 srcend=$((end + src_delta)) 1215 1216 add "$(format)" || return 1 1217 for j in $(seq ${start} $((range_size / 2 + 1)) ${end}); do 1218 send_match "${j}" $((j + src_delta)) || return 1 1219 done 1220 send_nomatch $((end + 1)) $((end + 1 + src_delta)) || return 1 1221 1222 # Delete elements now and then 1223 if [ $((i % 3)) -eq 0 ]; then 1224 del "$(format)" || return 1 1225 for j in $(seq ${start} \ 1226 $((range_size / 2 + 1)) ${end}); do 1227 send_nomatch "${j}" $((j + src_delta)) \ 1228 || return 1 1229 done 1230 fi 1231 1232 range_size=$((range_size + 1)) 1233 start=$((end + range_size)) 1234 done 1235} 1236 1237# Concurrency test template: 1238# - add all the elements 1239# - start a thread for each physical thread that: 1240# - adds all the elements 1241# - flushes the set 1242# - adds all the elements 1243# - flushes the entire ruleset 1244# - adds the set back 1245# - adds all the elements 1246# - delete all the elements 1247test_concurrency() { 1248 proto=${flood_proto} 1249 tools=${flood_tools} 1250 chain_spec=${flood_spec} 1251 setup veth flood_"${proto}" set || return ${KSELFTEST_SKIP} 1252 1253 range_size=1 1254 cstart=${start} 1255 flood_pids= 1256 for i in $(seq ${start} $((start + count))); do 1257 end=$((start + range_size)) 1258 srcstart=$((start + src_delta)) 1259 srcend=$((end + src_delta)) 1260 1261 add "$(format)" || return 1 1262 1263 flood "${i}" $((i + src_delta)) & flood_pids="${flood_pids} $!" 1264 1265 range_size=$((range_size + 1)) 1266 start=$((end + range_size)) 1267 done 1268 1269 sleep 10 1270 1271 pids= 1272 for c in $(seq 1 "$(nproc)"); do ( 1273 for r in $(seq 1 "${race_repeat}"); do 1274 range_size=1 1275 1276 # $start needs to be local to this subshell 1277 # shellcheck disable=SC2030 1278 start=${cstart} 1279 for i in $(seq ${start} $((start + count))); do 1280 end=$((start + range_size)) 1281 srcstart=$((start + src_delta)) 1282 srcend=$((end + src_delta)) 1283 1284 add "$(format)" 2>/dev/null 1285 1286 range_size=$((range_size + 1)) 1287 start=$((end + range_size)) 1288 done 1289 1290 nft flush inet filter test 2>/dev/null 1291 1292 range_size=1 1293 start=${cstart} 1294 for i in $(seq ${start} $((start + count))); do 1295 end=$((start + range_size)) 1296 srcstart=$((start + src_delta)) 1297 srcend=$((end + src_delta)) 1298 1299 add "$(format)" 2>/dev/null 1300 1301 range_size=$((range_size + 1)) 1302 start=$((end + range_size)) 1303 done 1304 1305 nft flush ruleset 1306 setup set 2>/dev/null 1307 1308 range_size=1 1309 start=${cstart} 1310 for i in $(seq ${start} $((start + count))); do 1311 end=$((start + range_size)) 1312 srcstart=$((start + src_delta)) 1313 srcend=$((end + src_delta)) 1314 1315 add "$(format)" 2>/dev/null 1316 1317 range_size=$((range_size + 1)) 1318 start=$((end + range_size)) 1319 done 1320 1321 range_size=1 1322 start=${cstart} 1323 for i in $(seq ${start} $((start + count))); do 1324 end=$((start + range_size)) 1325 srcstart=$((start + src_delta)) 1326 srcend=$((end + src_delta)) 1327 1328 del "$(format)" 2>/dev/null 1329 1330 range_size=$((range_size + 1)) 1331 start=$((end + range_size)) 1332 done 1333 done 1334 ) & pids="${pids} $!" 1335 done 1336 1337 # shellcheck disable=SC2046,SC2086 # word splitting wanted here 1338 wait $(for pid in ${pids}; do echo ${pid}; done) 1339 # shellcheck disable=SC2046,SC2086 1340 kill $(for pid in ${flood_pids}; do echo ${pid}; done) 2>/dev/null 1341 # shellcheck disable=SC2046,SC2086 1342 wait $(for pid in ${flood_pids}; do echo ${pid}; done) 2>/dev/null 1343 1344 return 0 1345} 1346 1347# Timeout test template: 1348# - add all the elements with 3s timeout while checking that packets match 1349# - wait 3s after the last insertion, check that packets don't match any entry 1350test_timeout() { 1351 setup veth send_"${proto}" set || return ${KSELFTEST_SKIP} 1352 1353 timeout=3 1354 range_size=1 1355 for i in $(seq "${start}" $((start + count))); do 1356 end=$((start + range_size)) 1357 srcstart=$((start + src_delta)) 1358 srcend=$((end + src_delta)) 1359 1360 add "$(format)" || return 1 1361 1362 for j in $(seq ${start} $((range_size / 2 + 1)) ${end}); do 1363 send_match "${j}" $((j + src_delta)) || return 1 1364 done 1365 1366 range_size=$((range_size + 1)) 1367 start=$((end + range_size)) 1368 done 1369 sleep 3 1370 for i in $(seq ${start} $((start + count))); do 1371 end=$((start + range_size)) 1372 srcstart=$((start + src_delta)) 1373 srcend=$((end + src_delta)) 1374 1375 for j in $(seq ${start} $((range_size / 2 + 1)) ${end}); do 1376 send_nomatch "${j}" $((j + src_delta)) || return 1 1377 done 1378 1379 range_size=$((range_size + 1)) 1380 start=$((end + range_size)) 1381 done 1382} 1383 1384# Performance test template: 1385# - add concatenated ranged entries 1386# - add non-ranged concatenated entries (for hash set matching rate baseline) 1387# - add ranged entries with first field only (for rbhash baseline) 1388# - start pktgen injection directly on device rx path of this namespace 1389# - measure drop only rate, hash and rbtree baselines, then matching rate 1390test_performance() { 1391 chain_spec=${perf_spec} 1392 dst="${perf_dst}" 1393 src="${perf_src}" 1394 setup veth perf set || return ${KSELFTEST_SKIP} 1395 1396 first=${start} 1397 range_size=1 1398 for set in test norange noconcat; do 1399 start=${first} 1400 for i in $(seq ${start} $((start + perf_entries))); do 1401 end=$((start + range_size)) 1402 srcstart=$((start + src_delta)) 1403 srcend=$((end + src_delta)) 1404 1405 if [ $((end / 65534)) -gt $((start / 65534)) ]; then 1406 start=${end} 1407 end=$((end + 1)) 1408 elif [ ${start} -eq ${end} ]; then 1409 end=$((start + 1)) 1410 fi 1411 1412 add_perf ${set} 1413 1414 start=$((end + range_size)) 1415 done > "${tmp}" 1416 nft -f "${tmp}" 1417 done 1418 1419 perf $((end - 1)) ${srcstart} 1420 1421 sleep 2 1422 1423 nft add rule netdev perf test counter name \"test\" drop 1424 nft reset counter netdev perf test >/dev/null 2>&1 1425 sleep "${perf_duration}" 1426 pps="$(printf %10s $(($(count_perf_packets) / perf_duration)))" 1427 info " baseline (drop from netdev hook): ${pps}pps" 1428 handle="$(nft -a list chain netdev perf test | grep counter)" 1429 handle="${handle##* }" 1430 nft delete rule netdev perf test handle "${handle}" 1431 1432 nft add rule "netdev perf test ${chain_spec} @norange \ 1433 counter name \"test\" drop" 1434 nft reset counter netdev perf test >/dev/null 2>&1 1435 sleep "${perf_duration}" 1436 pps="$(printf %10s $(($(count_perf_packets) / perf_duration)))" 1437 info " baseline hash (non-ranged entries): ${pps}pps" 1438 handle="$(nft -a list chain netdev perf test | grep counter)" 1439 handle="${handle##* }" 1440 nft delete rule netdev perf test handle "${handle}" 1441 1442 nft add rule "netdev perf test ${chain_spec%%. *} @noconcat \ 1443 counter name \"test\" drop" 1444 nft reset counter netdev perf test >/dev/null 2>&1 1445 sleep "${perf_duration}" 1446 pps="$(printf %10s $(($(count_perf_packets) / perf_duration)))" 1447 info " baseline rbtree (match on first field only): ${pps}pps" 1448 handle="$(nft -a list chain netdev perf test | grep counter)" 1449 handle="${handle##* }" 1450 nft delete rule netdev perf test handle "${handle}" 1451 1452 nft add rule "netdev perf test ${chain_spec} @test \ 1453 counter name \"test\" drop" 1454 nft reset counter netdev perf test >/dev/null 2>&1 1455 sleep "${perf_duration}" 1456 pps="$(printf %10s $(($(count_perf_packets) / perf_duration)))" 1457 p5="$(printf %5s "${perf_entries}")" 1458 info " set with ${p5} full, ranged entries: ${pps}pps" 1459 kill "${perf_pid}" 1460} 1461 1462test_bug_flush_remove_add() { 1463 set_cmd='{ set s { type ipv4_addr . inet_service; flags interval; }; }' 1464 elem1='{ 10.0.0.1 . 22-25, 10.0.0.1 . 10-20 }' 1465 elem2='{ 10.0.0.1 . 10-20, 10.0.0.1 . 22-25 }' 1466 for i in `seq 1 100`; do 1467 nft add table t ${set_cmd} || return ${KSELFTEST_SKIP} 1468 nft add element t s ${elem1} 2>/dev/null || return 1 1469 nft flush set t s 2>/dev/null || return 1 1470 nft add element t s ${elem2} 2>/dev/null || return 1 1471 done 1472 nft flush ruleset 1473} 1474 1475# - add ranged element, check that packets match it 1476# - reload the set, check packets still match 1477test_bug_reload() { 1478 setup veth send_"${proto}" set || return ${KSELFTEST_SKIP} 1479 rstart=${start} 1480 1481 range_size=1 1482 for i in $(seq "${start}" $((start + count))); do 1483 end=$((start + range_size)) 1484 1485 # Avoid negative or zero-sized port ranges 1486 if [ $((end / 65534)) -gt $((start / 65534)) ]; then 1487 start=${end} 1488 end=$((end + 1)) 1489 fi 1490 srcstart=$((start + src_delta)) 1491 srcend=$((end + src_delta)) 1492 1493 add "$(format)" || return 1 1494 range_size=$((range_size + 1)) 1495 start=$((end + range_size)) 1496 done 1497 1498 # check kernel does allocate pcpu sctrach map 1499 # for reload with no elemet add/delete 1500 ( echo flush set inet filter test ; 1501 nft list set inet filter test ) | nft -f - 1502 1503 start=${rstart} 1504 range_size=1 1505 1506 for i in $(seq "${start}" $((start + count))); do 1507 end=$((start + range_size)) 1508 1509 # Avoid negative or zero-sized port ranges 1510 if [ $((end / 65534)) -gt $((start / 65534)) ]; then 1511 start=${end} 1512 end=$((end + 1)) 1513 fi 1514 srcstart=$((start + src_delta)) 1515 srcend=$((end + src_delta)) 1516 1517 for j in $(seq ${start} $((range_size / 2 + 1)) ${end}); do 1518 send_match "${j}" $((j + src_delta)) || return 1 1519 done 1520 1521 range_size=$((range_size + 1)) 1522 start=$((end + range_size)) 1523 done 1524 1525 nft flush ruleset 1526} 1527 1528test_reported_issues() { 1529 eval test_bug_"${subtest}" 1530} 1531 1532# Run everything in a separate network namespace 1533[ "${1}" != "run" ] && { unshare -n "${0}" run; exit $?; } 1534tmp="$(mktemp)" 1535trap cleanup EXIT 1536 1537# Entry point for test runs 1538passed=0 1539for name in ${TESTS}; do 1540 printf "TEST: %s\n" "$(echo ${name} | tr '_' ' ')" 1541 if [ "${name}" = "reported_issues" ]; then 1542 SUBTESTS="${BUGS}" 1543 else 1544 SUBTESTS="${TYPES}" 1545 fi 1546 1547 for subtest in ${SUBTESTS}; do 1548 eval desc=\$TYPE_"${subtest}" 1549 IFS=' 1550' 1551 for __line in ${desc}; do 1552 # shellcheck disable=SC2086 1553 eval ${__line%% *}=\"${__line##* }\"; 1554 done 1555 IFS=' 1556' 1557 1558 if [ "${name}" = "concurrency" ] && \ 1559 [ "${race_repeat}" = "0" ]; then 1560 continue 1561 fi 1562 if [ "${name}" = "performance" ] && \ 1563 [ "${perf_duration}" = "0" ]; then 1564 continue 1565 fi 1566 1567 printf " %-60s " "${display}" 1568 eval test_"${name}" 1569 ret=$? 1570 1571 if [ $ret -eq 0 ]; then 1572 printf "[ OK ]\n" 1573 info_flush 1574 passed=$((passed + 1)) 1575 elif [ $ret -eq 1 ]; then 1576 printf "[FAIL]\n" 1577 err_flush 1578 exit 1 1579 elif [ $ret -eq ${KSELFTEST_SKIP} ]; then 1580 printf "[SKIP]\n" 1581 err_flush 1582 fi 1583 done 1584done 1585 1586[ ${passed} -eq 0 ] && exit ${KSELFTEST_SKIP} || exit 0 1587