17df5e3dbSPeter Oskolkov#!/bin/bash 27df5e3dbSPeter Oskolkov# SPDX-License-Identifier: GPL-2.0 37df5e3dbSPeter Oskolkov# 47df5e3dbSPeter Oskolkov# This test installs a TC bpf program that throttles a TCP flow 57df5e3dbSPeter Oskolkov# with dst port = 9000 down to 5MBps. Then it measures actual 67df5e3dbSPeter Oskolkov# throughput of the flow. 77df5e3dbSPeter Oskolkov 8*98af3746SWang YufenBPF_FILE="test_tc_edt.bpf.o" 97df5e3dbSPeter Oskolkovif [[ $EUID -ne 0 ]]; then 107df5e3dbSPeter Oskolkov echo "This script must be run as root" 117df5e3dbSPeter Oskolkov echo "FAIL" 127df5e3dbSPeter Oskolkov exit 1 137df5e3dbSPeter Oskolkovfi 147df5e3dbSPeter Oskolkov 157df5e3dbSPeter Oskolkov# check that nc, dd, and timeout are present 167df5e3dbSPeter Oskolkovcommand -v nc >/dev/null 2>&1 || \ 177df5e3dbSPeter Oskolkov { echo >&2 "nc is not available"; exit 1; } 187df5e3dbSPeter Oskolkovcommand -v dd >/dev/null 2>&1 || \ 197df5e3dbSPeter Oskolkov { echo >&2 "nc is not available"; exit 1; } 207df5e3dbSPeter Oskolkovcommand -v timeout >/dev/null 2>&1 || \ 217df5e3dbSPeter Oskolkov { echo >&2 "timeout is not available"; exit 1; } 227df5e3dbSPeter Oskolkov 237df5e3dbSPeter Oskolkovreadonly NS_SRC="ns-src-$(mktemp -u XXXXXX)" 247df5e3dbSPeter Oskolkovreadonly NS_DST="ns-dst-$(mktemp -u XXXXXX)" 257df5e3dbSPeter Oskolkov 267df5e3dbSPeter Oskolkovreadonly IP_SRC="172.16.1.100" 277df5e3dbSPeter Oskolkovreadonly IP_DST="172.16.2.100" 287df5e3dbSPeter Oskolkov 297df5e3dbSPeter Oskolkovcleanup() 307df5e3dbSPeter Oskolkov{ 317df5e3dbSPeter Oskolkov ip netns del ${NS_SRC} 327df5e3dbSPeter Oskolkov ip netns del ${NS_DST} 337df5e3dbSPeter Oskolkov} 347df5e3dbSPeter Oskolkov 357df5e3dbSPeter Oskolkovtrap cleanup EXIT 367df5e3dbSPeter Oskolkov 377df5e3dbSPeter Oskolkovset -e # exit on error 387df5e3dbSPeter Oskolkov 397df5e3dbSPeter Oskolkovip netns add "${NS_SRC}" 407df5e3dbSPeter Oskolkovip netns add "${NS_DST}" 417df5e3dbSPeter Oskolkovip link add veth_src type veth peer name veth_dst 427df5e3dbSPeter Oskolkovip link set veth_src netns ${NS_SRC} 437df5e3dbSPeter Oskolkovip link set veth_dst netns ${NS_DST} 447df5e3dbSPeter Oskolkov 457df5e3dbSPeter Oskolkovip -netns ${NS_SRC} addr add ${IP_SRC}/24 dev veth_src 467df5e3dbSPeter Oskolkovip -netns ${NS_DST} addr add ${IP_DST}/24 dev veth_dst 477df5e3dbSPeter Oskolkov 487df5e3dbSPeter Oskolkovip -netns ${NS_SRC} link set dev veth_src up 497df5e3dbSPeter Oskolkovip -netns ${NS_DST} link set dev veth_dst up 507df5e3dbSPeter Oskolkov 517df5e3dbSPeter Oskolkovip -netns ${NS_SRC} route add ${IP_DST}/32 dev veth_src 527df5e3dbSPeter Oskolkovip -netns ${NS_DST} route add ${IP_SRC}/32 dev veth_dst 537df5e3dbSPeter Oskolkov 547df5e3dbSPeter Oskolkov# set up TC on TX 557df5e3dbSPeter Oskolkovip netns exec ${NS_SRC} tc qdisc add dev veth_src root fq 567df5e3dbSPeter Oskolkovip netns exec ${NS_SRC} tc qdisc add dev veth_src clsact 577df5e3dbSPeter Oskolkovip netns exec ${NS_SRC} tc filter add dev veth_src egress \ 58*98af3746SWang Yufen bpf da obj ${BPF_FILE} sec cls_test 597df5e3dbSPeter Oskolkov 607df5e3dbSPeter Oskolkov 617df5e3dbSPeter Oskolkov# start the listener 627df5e3dbSPeter Oskolkovip netns exec ${NS_DST} bash -c \ 6311875ba7SJiri Benc "nc -4 -l -p 9000 >/dev/null &" 647df5e3dbSPeter Oskolkovdeclare -i NC_PID=$! 657df5e3dbSPeter Oskolkovsleep 1 667df5e3dbSPeter Oskolkov 677df5e3dbSPeter Oskolkovdeclare -ir TIMEOUT=20 687df5e3dbSPeter Oskolkovdeclare -ir EXPECTED_BPS=5000000 697df5e3dbSPeter Oskolkov 707df5e3dbSPeter Oskolkov# run the load, capture RX bytes on DST 717df5e3dbSPeter Oskolkovdeclare -ir RX_BYTES_START=$( ip netns exec ${NS_DST} \ 727df5e3dbSPeter Oskolkov cat /sys/class/net/veth_dst/statistics/rx_bytes ) 737df5e3dbSPeter Oskolkov 747df5e3dbSPeter Oskolkovset +e 757df5e3dbSPeter Oskolkovip netns exec ${NS_SRC} bash -c "timeout ${TIMEOUT} dd if=/dev/zero \ 767df5e3dbSPeter Oskolkov bs=1000 count=1000000 > /dev/tcp/${IP_DST}/9000 2>/dev/null" 777df5e3dbSPeter Oskolkovset -e 787df5e3dbSPeter Oskolkov 797df5e3dbSPeter Oskolkovdeclare -ir RX_BYTES_END=$( ip netns exec ${NS_DST} \ 807df5e3dbSPeter Oskolkov cat /sys/class/net/veth_dst/statistics/rx_bytes ) 817df5e3dbSPeter Oskolkov 827df5e3dbSPeter Oskolkovdeclare -ir ACTUAL_BPS=$(( ($RX_BYTES_END - $RX_BYTES_START) / $TIMEOUT )) 837df5e3dbSPeter Oskolkov 847df5e3dbSPeter Oskolkovecho $TIMEOUT $ACTUAL_BPS $EXPECTED_BPS | \ 857df5e3dbSPeter Oskolkov awk '{printf "elapsed: %d sec; bps difference: %.2f%%\n", 867df5e3dbSPeter Oskolkov $1, ($2-$3)*100.0/$3}' 877df5e3dbSPeter Oskolkov 887df5e3dbSPeter Oskolkov# Pass the test if the actual bps is within 1% of the expected bps. 897df5e3dbSPeter Oskolkov# The difference is usually about 0.1% on a 20-sec test, and ==> zero 907df5e3dbSPeter Oskolkov# the longer the test runs. 917df5e3dbSPeter Oskolkovdeclare -ir RES=$( echo $ACTUAL_BPS $EXPECTED_BPS | \ 927df5e3dbSPeter Oskolkov awk 'function abs(x){return ((x < 0.0) ? -x : x)} 937df5e3dbSPeter Oskolkov {if (abs(($1-$2)*100.0/$2) > 1.0) { print "1" } 947df5e3dbSPeter Oskolkov else { print "0"} }' ) 957df5e3dbSPeter Oskolkovif [ "${RES}" == "0" ] ; then 967df5e3dbSPeter Oskolkov echo "PASS" 977df5e3dbSPeter Oskolkovelse 987df5e3dbSPeter Oskolkov echo "FAIL" 997df5e3dbSPeter Oskolkov exit 1 1007df5e3dbSPeter Oskolkovfi 101