xref: /openbmc/linux/tools/testing/selftests/bpf/test_tc_edt.sh (revision 7ae9fb1b7ecbb5d85d07857943f677fd1a559b18)
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