1#!/bin/bash 2# SPDX-License-Identifier: GPL-2.0 3# 4# Test that packets are sampled when tc-sample is used and that reported 5# metadata is correct. Two sets of hosts (with and without LAG) are used, since 6# metadata extraction in mlxsw is a bit different when LAG is involved. 7# 8# +---------------------------------+ +---------------------------------+ 9# | H1 (vrf) | | H3 (vrf) | 10# | + $h1 | | + $h3_lag | 11# | | 192.0.2.1/28 | | | 192.0.2.17/28 | 12# | | | | | | 13# | | default via 192.0.2.2 | | | default via 192.0.2.18 | 14# +----|----------------------------+ +----|----------------------------+ 15# | | 16# +----|-----------------------------------------|----------------------------+ 17# | | 192.0.2.2/28 | 192.0.2.18/28 | 18# | + $rp1 + $rp3_lag | 19# | | 20# | + $rp2 + $rp4_lag | 21# | | 198.51.100.2/28 | 198.51.100.18/28 | 22# +----|-----------------------------------------|----------------------------+ 23# | | 24# +----|----------------------------+ +----|----------------------------+ 25# | | default via 198.51.100.2 | | | default via 198.51.100.18 | 26# | | | | | | 27# | | 198.51.100.1/28 | | | 198.51.100.17/28 | 28# | + $h2 | | + $h4_lag | 29# | H2 (vrf) | | H4 (vrf) | 30# +---------------------------------+ +---------------------------------+ 31 32lib_dir=$(dirname $0)/../../../net/forwarding 33 34ALL_TESTS=" 35 tc_sample_rate_test 36 tc_sample_max_rate_test 37 tc_sample_conflict_test 38 tc_sample_group_conflict_test 39 tc_sample_md_iif_test 40 tc_sample_md_lag_iif_test 41 tc_sample_md_oif_test 42 tc_sample_md_lag_oif_test 43 tc_sample_md_out_tc_test 44 tc_sample_md_out_tc_occ_test 45 tc_sample_md_latency_test 46 tc_sample_acl_group_conflict_test 47 tc_sample_acl_rate_test 48 tc_sample_acl_max_rate_test 49" 50NUM_NETIFS=8 51CAPTURE_FILE=$(mktemp) 52source $lib_dir/lib.sh 53source $lib_dir/devlink_lib.sh 54 55# Available at https://github.com/Mellanox/libpsample 56require_command psample 57 58h1_create() 59{ 60 simple_if_init $h1 192.0.2.1/28 61 62 ip -4 route add default vrf v$h1 nexthop via 192.0.2.2 63} 64 65h1_destroy() 66{ 67 ip -4 route del default vrf v$h1 nexthop via 192.0.2.2 68 69 simple_if_fini $h1 192.0.2.1/28 70} 71 72h2_create() 73{ 74 simple_if_init $h2 198.51.100.1/28 75 76 ip -4 route add default vrf v$h2 nexthop via 198.51.100.2 77} 78 79h2_destroy() 80{ 81 ip -4 route del default vrf v$h2 nexthop via 198.51.100.2 82 83 simple_if_fini $h2 198.51.100.1/28 84} 85 86h3_create() 87{ 88 ip link set dev $h3 down 89 ip link add name ${h3}_bond type bond mode 802.3ad 90 ip link set dev $h3 master ${h3}_bond 91 92 simple_if_init ${h3}_bond 192.0.2.17/28 93 94 ip -4 route add default vrf v${h3}_bond nexthop via 192.0.2.18 95} 96 97h3_destroy() 98{ 99 ip -4 route del default vrf v${h3}_bond nexthop via 192.0.2.18 100 101 simple_if_fini ${h3}_bond 192.0.2.17/28 102 103 ip link set dev $h3 nomaster 104 ip link del dev ${h3}_bond 105} 106 107h4_create() 108{ 109 ip link set dev $h4 down 110 ip link add name ${h4}_bond type bond mode 802.3ad 111 ip link set dev $h4 master ${h4}_bond 112 113 simple_if_init ${h4}_bond 198.51.100.17/28 114 115 ip -4 route add default vrf v${h4}_bond nexthop via 198.51.100.18 116} 117 118h4_destroy() 119{ 120 ip -4 route del default vrf v${h4}_bond nexthop via 198.51.100.18 121 122 simple_if_fini ${h4}_bond 198.51.100.17/28 123 124 ip link set dev $h4 nomaster 125 ip link del dev ${h4}_bond 126} 127 128router_create() 129{ 130 ip link set dev $rp1 up 131 __addr_add_del $rp1 add 192.0.2.2/28 132 tc qdisc add dev $rp1 clsact 133 134 ip link set dev $rp2 up 135 __addr_add_del $rp2 add 198.51.100.2/28 136 tc qdisc add dev $rp2 clsact 137 138 ip link add name ${rp3}_bond type bond mode 802.3ad 139 ip link set dev $rp3 master ${rp3}_bond 140 __addr_add_del ${rp3}_bond add 192.0.2.18/28 141 tc qdisc add dev $rp3 clsact 142 ip link set dev ${rp3}_bond up 143 144 ip link add name ${rp4}_bond type bond mode 802.3ad 145 ip link set dev $rp4 master ${rp4}_bond 146 __addr_add_del ${rp4}_bond add 198.51.100.18/28 147 tc qdisc add dev $rp4 clsact 148 ip link set dev ${rp4}_bond up 149} 150 151router_destroy() 152{ 153 ip link set dev ${rp4}_bond down 154 tc qdisc del dev $rp4 clsact 155 __addr_add_del ${rp4}_bond del 198.51.100.18/28 156 ip link set dev $rp4 nomaster 157 ip link del dev ${rp4}_bond 158 159 ip link set dev ${rp3}_bond down 160 tc qdisc del dev $rp3 clsact 161 __addr_add_del ${rp3}_bond del 192.0.2.18/28 162 ip link set dev $rp3 nomaster 163 ip link del dev ${rp3}_bond 164 165 tc qdisc del dev $rp2 clsact 166 __addr_add_del $rp2 del 198.51.100.2/28 167 ip link set dev $rp2 down 168 169 tc qdisc del dev $rp1 clsact 170 __addr_add_del $rp1 del 192.0.2.2/28 171 ip link set dev $rp1 down 172} 173 174setup_prepare() 175{ 176 h1=${NETIFS[p1]} 177 rp1=${NETIFS[p2]} 178 rp2=${NETIFS[p3]} 179 h2=${NETIFS[p4]} 180 h3=${NETIFS[p5]} 181 rp3=${NETIFS[p6]} 182 h4=${NETIFS[p7]} 183 rp4=${NETIFS[p8]} 184 185 vrf_prepare 186 187 h1_create 188 h2_create 189 h3_create 190 h4_create 191 router_create 192} 193 194cleanup() 195{ 196 pre_cleanup 197 198 rm -f $CAPTURE_FILE 199 200 router_destroy 201 h4_destroy 202 h3_destroy 203 h2_destroy 204 h1_destroy 205 206 vrf_cleanup 207} 208 209psample_capture_start() 210{ 211 rm -f $CAPTURE_FILE 212 213 psample &> $CAPTURE_FILE & 214 215 sleep 1 216} 217 218psample_capture_stop() 219{ 220 { kill %% && wait %%; } 2>/dev/null 221} 222 223__tc_sample_rate_test() 224{ 225 local desc=$1; shift 226 local dip=$1; shift 227 local pkts pct 228 229 RET=0 230 231 tc filter add dev $rp1 ingress protocol all pref 1 handle 101 matchall \ 232 skip_sw action sample rate 32 group 1 233 check_err $? "Failed to configure sampling rule" 234 235 psample_capture_start 236 237 ip vrf exec v$h1 $MZ $h1 -c 3200 -d 1msec -p 64 -A 192.0.2.1 \ 238 -B $dip -t udp dp=52768,sp=42768 -q 239 240 psample_capture_stop 241 242 pkts=$(grep -e "group 1 " $CAPTURE_FILE | wc -l) 243 pct=$((100 * (pkts - 100) / 100)) 244 (( -25 <= pct && pct <= 25)) 245 check_err $? "Expected 100 packets, got $pkts packets, which is $pct% off. Required accuracy is +-25%" 246 247 log_test "tc sample rate ($desc)" 248 249 tc filter del dev $rp1 ingress protocol all pref 1 handle 101 matchall 250} 251 252tc_sample_rate_test() 253{ 254 __tc_sample_rate_test "forward" 198.51.100.1 255 __tc_sample_rate_test "local receive" 192.0.2.2 256} 257 258tc_sample_max_rate_test() 259{ 260 RET=0 261 262 tc filter add dev $rp1 ingress protocol all pref 1 handle 101 matchall \ 263 skip_sw action sample rate $((35 * 10 ** 8)) group 1 264 check_err $? "Failed to configure sampling rule with max rate" 265 266 tc filter del dev $rp1 ingress protocol all pref 1 handle 101 matchall 267 268 tc filter add dev $rp1 ingress protocol all pref 1 handle 101 matchall \ 269 skip_sw action sample rate $((35 * 10 ** 8 + 1)) \ 270 group 1 &> /dev/null 271 check_fail $? "Managed to configure sampling rate above maximum" 272 273 log_test "tc sample maximum rate" 274} 275 276tc_sample_conflict_test() 277{ 278 RET=0 279 280 # Test that two sampling rules cannot be configured on the same port, 281 # even when they share the same parameters. 282 283 tc filter add dev $rp1 ingress protocol all pref 1 handle 101 matchall \ 284 skip_sw action sample rate 1024 group 1 285 check_err $? "Failed to configure sampling rule" 286 287 tc filter add dev $rp1 ingress protocol all pref 2 handle 102 matchall \ 288 skip_sw action sample rate 1024 group 1 &> /dev/null 289 check_fail $? "Managed to configure second sampling rule" 290 291 # Delete the first rule and make sure the second rule can now be 292 # configured. 293 294 tc filter del dev $rp1 ingress protocol all pref 1 handle 101 matchall 295 296 tc filter add dev $rp1 ingress protocol all pref 2 handle 102 matchall \ 297 skip_sw action sample rate 1024 group 1 298 check_err $? "Failed to configure sampling rule after deletion" 299 300 log_test "tc sample conflict test" 301 302 tc filter del dev $rp1 ingress protocol all pref 2 handle 102 matchall 303} 304 305tc_sample_group_conflict_test() 306{ 307 RET=0 308 309 # Test that two sampling rules cannot be configured on the same port 310 # with different groups. 311 312 tc filter add dev $rp1 ingress protocol all pref 1 handle 101 matchall \ 313 skip_sw action sample rate 1024 group 1 314 check_err $? "Failed to configure sampling rule" 315 316 tc filter add dev $rp1 ingress protocol all pref 2 handle 102 matchall \ 317 skip_sw action sample rate 1024 group 2 &> /dev/null 318 check_fail $? "Managed to configure sampling rule with conflicting group" 319 320 log_test "tc sample group conflict test" 321 322 tc filter del dev $rp1 ingress protocol all pref 1 handle 101 matchall 323} 324 325tc_sample_md_iif_test() 326{ 327 local rp1_ifindex 328 329 RET=0 330 331 tc filter add dev $rp1 ingress protocol all pref 1 handle 101 matchall \ 332 skip_sw action sample rate 5 group 1 333 check_err $? "Failed to configure sampling rule" 334 335 psample_capture_start 336 337 ip vrf exec v$h1 $MZ $h1 -c 3200 -d 1msec -p 64 -A 192.0.2.1 \ 338 -B 198.51.100.1 -t udp dp=52768,sp=42768 -q 339 340 psample_capture_stop 341 342 rp1_ifindex=$(ip -j -p link show dev $rp1 | jq '.[]["ifindex"]') 343 grep -q -e "in-ifindex $rp1_ifindex " $CAPTURE_FILE 344 check_err $? "Sampled packets do not have expected in-ifindex" 345 346 log_test "tc sample iif" 347 348 tc filter del dev $rp1 ingress protocol all pref 1 handle 101 matchall 349} 350 351tc_sample_md_lag_iif_test() 352{ 353 local rp3_ifindex 354 355 RET=0 356 357 tc filter add dev $rp3 ingress protocol all pref 1 handle 101 matchall \ 358 skip_sw action sample rate 5 group 1 359 check_err $? "Failed to configure sampling rule" 360 361 psample_capture_start 362 363 ip vrf exec v${h3}_bond $MZ ${h3}_bond -c 3200 -d 1msec -p 64 \ 364 -A 192.0.2.17 -B 198.51.100.17 -t udp dp=52768,sp=42768 -q 365 366 psample_capture_stop 367 368 rp3_ifindex=$(ip -j -p link show dev $rp3 | jq '.[]["ifindex"]') 369 grep -q -e "in-ifindex $rp3_ifindex " $CAPTURE_FILE 370 check_err $? "Sampled packets do not have expected in-ifindex" 371 372 log_test "tc sample lag iif" 373 374 tc filter del dev $rp3 ingress protocol all pref 1 handle 101 matchall 375} 376 377tc_sample_md_oif_test() 378{ 379 local rp2_ifindex 380 381 RET=0 382 383 tc filter add dev $rp1 ingress protocol all pref 1 handle 101 matchall \ 384 skip_sw action sample rate 5 group 1 385 check_err $? "Failed to configure sampling rule" 386 387 psample_capture_start 388 389 ip vrf exec v$h1 $MZ $h1 -c 3200 -d 1msec -p 64 -A 192.0.2.1 \ 390 -B 198.51.100.1 -t udp dp=52768,sp=42768 -q 391 392 psample_capture_stop 393 394 rp2_ifindex=$(ip -j -p link show dev $rp2 | jq '.[]["ifindex"]') 395 grep -q -e "out-ifindex $rp2_ifindex " $CAPTURE_FILE 396 check_err $? "Sampled packets do not have expected out-ifindex" 397 398 log_test "tc sample oif" 399 400 tc filter del dev $rp1 ingress protocol all pref 1 handle 101 matchall 401} 402 403tc_sample_md_lag_oif_test() 404{ 405 local rp4_ifindex 406 407 RET=0 408 409 tc filter add dev $rp3 ingress protocol all pref 1 handle 101 matchall \ 410 skip_sw action sample rate 5 group 1 411 check_err $? "Failed to configure sampling rule" 412 413 psample_capture_start 414 415 ip vrf exec v${h3}_bond $MZ ${h3}_bond -c 3200 -d 1msec -p 64 \ 416 -A 192.0.2.17 -B 198.51.100.17 -t udp dp=52768,sp=42768 -q 417 418 psample_capture_stop 419 420 rp4_ifindex=$(ip -j -p link show dev $rp4 | jq '.[]["ifindex"]') 421 grep -q -e "out-ifindex $rp4_ifindex " $CAPTURE_FILE 422 check_err $? "Sampled packets do not have expected out-ifindex" 423 424 log_test "tc sample lag oif" 425 426 tc filter del dev $rp3 ingress protocol all pref 1 handle 101 matchall 427} 428 429tc_sample_md_out_tc_test() 430{ 431 RET=0 432 433 # Output traffic class is not supported on Spectrum-1. 434 [[ "$DEVLINK_VIDDID" == "15b3:cb84" ]] && return 435 436 tc filter add dev $rp1 ingress protocol all pref 1 handle 101 matchall \ 437 skip_sw action sample rate 5 group 1 438 check_err $? "Failed to configure sampling rule" 439 440 # By default, all the packets should go to the same traffic class (0). 441 442 psample_capture_start 443 444 ip vrf exec v$h1 $MZ $h1 -c 3200 -d 1msec -p 64 -A 192.0.2.1 \ 445 -B 198.51.100.1 -t udp dp=52768,sp=42768 -q 446 447 psample_capture_stop 448 449 grep -q -e "out-tc 0 " $CAPTURE_FILE 450 check_err $? "Sampled packets do not have expected out-tc (0)" 451 452 # Map all priorities to highest traffic class (7) and check reported 453 # out-tc. 454 tc qdisc replace dev $rp2 root handle 1: \ 455 prio bands 3 priomap 0 0 0 0 0 0 0 0 456 457 psample_capture_start 458 459 ip vrf exec v$h1 $MZ $h1 -c 3200 -d 1msec -p 64 -A 192.0.2.1 \ 460 -B 198.51.100.1 -t udp dp=52768,sp=42768 -q 461 462 psample_capture_stop 463 464 grep -q -e "out-tc 7 " $CAPTURE_FILE 465 check_err $? "Sampled packets do not have expected out-tc (7)" 466 467 log_test "tc sample out-tc" 468 469 tc qdisc del dev $rp2 root handle 1: 470 tc filter del dev $rp1 ingress protocol all pref 1 handle 101 matchall 471} 472 473tc_sample_md_out_tc_occ_test() 474{ 475 local backlog pct occ 476 477 RET=0 478 479 # Output traffic class occupancy is not supported on Spectrum-1. 480 [[ "$DEVLINK_VIDDID" == "15b3:cb84" ]] && return 481 482 tc filter add dev $rp1 ingress protocol all pref 1 handle 101 matchall \ 483 skip_sw action sample rate 1024 group 1 484 check_err $? "Failed to configure sampling rule" 485 486 # Configure a shaper on egress to create congestion. 487 tc qdisc replace dev $rp2 root handle 1: \ 488 tbf rate 1Mbit burst 256k limit 1M 489 490 psample_capture_start 491 492 ip vrf exec v$h1 $MZ $h1 -c 0 -d 1usec -p 1400 -A 192.0.2.1 \ 493 -B 198.51.100.1 -t udp dp=52768,sp=42768 -q & 494 495 # Allow congestion to reach steady state. 496 sleep 10 497 498 backlog=$(tc -j -p -s qdisc show dev $rp2 | jq '.[0]["backlog"]') 499 500 # Kill mausezahn. 501 { kill %% && wait %%; } 2>/dev/null 502 503 psample_capture_stop 504 505 # Record last congestion sample. 506 occ=$(grep -e "out-tc-occ " $CAPTURE_FILE | tail -n 1 | \ 507 cut -d ' ' -f 16) 508 509 pct=$((100 * (occ - backlog) / backlog)) 510 (( -1 <= pct && pct <= 1)) 511 check_err $? "Recorded a congestion of $backlog bytes, but sampled congestion is $occ bytes, which is $pct% off. Required accuracy is +-5%" 512 513 log_test "tc sample out-tc-occ" 514 515 tc qdisc del dev $rp2 root handle 1: 516 tc filter del dev $rp1 ingress protocol all pref 1 handle 101 matchall 517} 518 519tc_sample_md_latency_test() 520{ 521 RET=0 522 523 # Egress sampling not supported on Spectrum-1. 524 [[ "$DEVLINK_VIDDID" == "15b3:cb84" ]] && return 525 526 tc filter add dev $rp2 egress protocol all pref 1 handle 101 matchall \ 527 skip_sw action sample rate 5 group 1 528 check_err $? "Failed to configure sampling rule" 529 530 psample_capture_start 531 532 ip vrf exec v$h1 $MZ $h1 -c 3200 -d 1msec -p 64 -A 192.0.2.1 \ 533 -B 198.51.100.1 -t udp dp=52768,sp=42768 -q 534 535 psample_capture_stop 536 537 grep -q -e "latency " $CAPTURE_FILE 538 check_err $? "Sampled packets do not have latency attribute" 539 540 log_test "tc sample latency" 541 542 tc filter del dev $rp2 egress protocol all pref 1 handle 101 matchall 543} 544 545tc_sample_acl_group_conflict_test() 546{ 547 RET=0 548 549 # Test that two flower sampling rules cannot be configured on the same 550 # port with different groups. 551 552 # Policy-based sampling is not supported on Spectrum-1. 553 [[ "$DEVLINK_VIDDID" == "15b3:cb84" ]] && return 554 555 tc filter add dev $rp1 ingress protocol ip pref 1 handle 101 flower \ 556 skip_sw action sample rate 1024 group 1 557 check_err $? "Failed to configure sampling rule" 558 559 tc filter add dev $rp1 ingress protocol ip pref 2 handle 102 flower \ 560 skip_sw action sample rate 1024 group 1 561 check_err $? "Failed to configure sampling rule with same group" 562 563 tc filter add dev $rp1 ingress protocol ip pref 3 handle 103 flower \ 564 skip_sw action sample rate 1024 group 2 &> /dev/null 565 check_fail $? "Managed to configure sampling rule with conflicting group" 566 567 log_test "tc sample (w/ flower) group conflict test" 568 569 tc filter del dev $rp1 ingress protocol ip pref 2 handle 102 flower 570 tc filter del dev $rp1 ingress protocol ip pref 1 handle 101 flower 571} 572 573__tc_sample_acl_rate_test() 574{ 575 local bind=$1; shift 576 local port=$1; shift 577 local pkts pct 578 579 RET=0 580 581 # Policy-based sampling is not supported on Spectrum-1. 582 [[ "$DEVLINK_VIDDID" == "15b3:cb84" ]] && return 583 584 tc filter add dev $port $bind protocol ip pref 1 handle 101 flower \ 585 skip_sw dst_ip 198.51.100.1 action sample rate 32 group 1 586 check_err $? "Failed to configure sampling rule" 587 588 psample_capture_start 589 590 ip vrf exec v$h1 $MZ $h1 -c 3200 -d 1msec -p 64 -A 192.0.2.1 \ 591 -B 198.51.100.1 -t udp dp=52768,sp=42768 -q 592 593 psample_capture_stop 594 595 pkts=$(grep -e "group 1 " $CAPTURE_FILE | wc -l) 596 pct=$((100 * (pkts - 100) / 100)) 597 (( -25 <= pct && pct <= 25)) 598 check_err $? "Expected 100 packets, got $pkts packets, which is $pct% off. Required accuracy is +-25%" 599 600 # Setup a filter that should not match any packet and make sure packets 601 # are not sampled. 602 tc filter del dev $port $bind protocol ip pref 1 handle 101 flower 603 604 tc filter add dev $port $bind protocol ip pref 1 handle 101 flower \ 605 skip_sw dst_ip 198.51.100.10 action sample rate 32 group 1 606 check_err $? "Failed to configure sampling rule" 607 608 psample_capture_start 609 610 ip vrf exec v$h1 $MZ $h1 -c 3200 -d 1msec -p 64 -A 192.0.2.1 \ 611 -B 198.51.100.1 -t udp dp=52768,sp=42768 -q 612 613 psample_capture_stop 614 615 grep -q -e "group 1 " $CAPTURE_FILE 616 check_fail $? "Sampled packets when should not" 617 618 log_test "tc sample (w/ flower) rate ($bind)" 619 620 tc filter del dev $port $bind protocol ip pref 1 handle 101 flower 621} 622 623tc_sample_acl_rate_test() 624{ 625 __tc_sample_acl_rate_test ingress $rp1 626 __tc_sample_acl_rate_test egress $rp2 627} 628 629tc_sample_acl_max_rate_test() 630{ 631 RET=0 632 633 # Policy-based sampling is not supported on Spectrum-1. 634 [[ "$DEVLINK_VIDDID" == "15b3:cb84" ]] && return 635 636 tc filter add dev $rp1 ingress protocol ip pref 1 handle 101 flower \ 637 skip_sw action sample rate $((2 ** 24 - 1)) group 1 638 check_err $? "Failed to configure sampling rule with max rate" 639 640 tc filter del dev $rp1 ingress protocol ip pref 1 handle 101 flower 641 642 tc filter add dev $rp1 ingress protocol ip pref 1 handle 101 flower \ 643 skip_sw action sample rate $((2 ** 24)) \ 644 group 1 &> /dev/null 645 check_fail $? "Managed to configure sampling rate above maximum" 646 647 log_test "tc sample (w/ flower) maximum rate" 648} 649 650trap cleanup EXIT 651 652setup_prepare 653setup_wait 654 655tests_run 656 657exit $EXIT_STATUS 658