Back to home page

OSCL-LXR

 
 

    


0001 #!/bin/bash
0002 # SPDX-License-Identifier: GPL-2.0
0003 #
0004 # This test installs a TC bpf program that throttles a TCP flow
0005 # with dst port = 9000 down to 5MBps. Then it measures actual
0006 # throughput of the flow.
0007 
0008 if [[ $EUID -ne 0 ]]; then
0009         echo "This script must be run as root"
0010         echo "FAIL"
0011         exit 1
0012 fi
0013 
0014 # check that nc, dd, and timeout are present
0015 command -v nc >/dev/null 2>&1 || \
0016         { echo >&2 "nc is not available"; exit 1; }
0017 command -v dd >/dev/null 2>&1 || \
0018         { echo >&2 "nc is not available"; exit 1; }
0019 command -v timeout >/dev/null 2>&1 || \
0020         { echo >&2 "timeout is not available"; exit 1; }
0021 
0022 readonly NS_SRC="ns-src-$(mktemp -u XXXXXX)"
0023 readonly NS_DST="ns-dst-$(mktemp -u XXXXXX)"
0024 
0025 readonly IP_SRC="172.16.1.100"
0026 readonly IP_DST="172.16.2.100"
0027 
0028 cleanup()
0029 {
0030         ip netns del ${NS_SRC}
0031         ip netns del ${NS_DST}
0032 }
0033 
0034 trap cleanup EXIT
0035 
0036 set -e  # exit on error
0037 
0038 ip netns add "${NS_SRC}"
0039 ip netns add "${NS_DST}"
0040 ip link add veth_src type veth peer name veth_dst
0041 ip link set veth_src netns ${NS_SRC}
0042 ip link set veth_dst netns ${NS_DST}
0043 
0044 ip -netns ${NS_SRC} addr add ${IP_SRC}/24  dev veth_src
0045 ip -netns ${NS_DST} addr add ${IP_DST}/24  dev veth_dst
0046 
0047 ip -netns ${NS_SRC} link set dev veth_src up
0048 ip -netns ${NS_DST} link set dev veth_dst up
0049 
0050 ip -netns ${NS_SRC} route add ${IP_DST}/32  dev veth_src
0051 ip -netns ${NS_DST} route add ${IP_SRC}/32  dev veth_dst
0052 
0053 # set up TC on TX
0054 ip netns exec ${NS_SRC} tc qdisc add dev veth_src root fq
0055 ip netns exec ${NS_SRC} tc qdisc add dev veth_src clsact
0056 ip netns exec ${NS_SRC} tc filter add dev veth_src egress \
0057         bpf da obj test_tc_edt.o sec cls_test
0058 
0059 
0060 # start the listener
0061 ip netns exec ${NS_DST} bash -c \
0062         "nc -4 -l -p 9000 >/dev/null &"
0063 declare -i NC_PID=$!
0064 sleep 1
0065 
0066 declare -ir TIMEOUT=20
0067 declare -ir EXPECTED_BPS=5000000
0068 
0069 # run the load, capture RX bytes on DST
0070 declare -ir RX_BYTES_START=$( ip netns exec ${NS_DST} \
0071         cat /sys/class/net/veth_dst/statistics/rx_bytes )
0072 
0073 set +e
0074 ip netns exec ${NS_SRC} bash -c "timeout ${TIMEOUT} dd if=/dev/zero \
0075         bs=1000 count=1000000 > /dev/tcp/${IP_DST}/9000 2>/dev/null"
0076 set -e
0077 
0078 declare -ir RX_BYTES_END=$( ip netns exec ${NS_DST} \
0079         cat /sys/class/net/veth_dst/statistics/rx_bytes )
0080 
0081 declare -ir ACTUAL_BPS=$(( ($RX_BYTES_END - $RX_BYTES_START) / $TIMEOUT ))
0082 
0083 echo $TIMEOUT $ACTUAL_BPS $EXPECTED_BPS | \
0084         awk '{printf "elapsed: %d sec; bps difference: %.2f%%\n",
0085                 $1, ($2-$3)*100.0/$3}'
0086 
0087 # Pass the test if the actual bps is within 1% of the expected bps.
0088 # The difference is usually about 0.1% on a 20-sec test, and ==> zero
0089 # the longer the test runs.
0090 declare -ir RES=$( echo $ACTUAL_BPS $EXPECTED_BPS | \
0091          awk 'function abs(x){return ((x < 0.0) ? -x : x)}
0092               {if (abs(($1-$2)*100.0/$2) > 1.0) { print "1" }
0093                 else { print "0"} }' )
0094 if [ "${RES}" == "0" ] ; then
0095         echo "PASS"
0096 else
0097         echo "FAIL"
0098         exit 1
0099 fi