[PATCH net-next v3 3/3] selftest: net: test SO_PRIORITY ancillary data with cmsg_sender
From: Anna Emese Nyiri <hidden>
Date: 2024-11-07 13:23:06
Subsystem:
kernel selftest framework, networking [general], the rest · Maintainers:
Shuah Khan, "David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, Linus Torvalds
Extend cmsg_sender.c with a new option '-Q' to send SO_PRIORITY ancillary data. Add the `cmsg_so_priority.sh` script, which sets up two network namespaces (red and green) and uses the `cmsg_sender.c` program to send messages between them. The script sets packet priorities both via `setsockopt` and control messages (cmsg) and verifies whether packets are routed to the same queue based on priority settings. Suggested-by: Ido Schimmel <redacted> Signed-off-by: Anna Emese Nyiri <redacted> --- tools/testing/selftests/net/cmsg_sender.c | 11 +- .../testing/selftests/net/cmsg_so_priority.sh | 115 ++++++++++++++++++ 2 files changed, 125 insertions(+), 1 deletion(-) create mode 100755 tools/testing/selftests/net/cmsg_so_priority.sh
diff --git a/tools/testing/selftests/net/cmsg_sender.c b/tools/testing/selftests/net/cmsg_sender.c
index 876c2db02a63..6fbe93dd63d2 100644
--- a/tools/testing/selftests/net/cmsg_sender.c
+++ b/tools/testing/selftests/net/cmsg_sender.c@@ -52,6 +52,7 @@ struct options { unsigned int tclass; unsigned int hlimit; unsigned int priority; + unsigned int priority_cmsg; } sockopt; struct { unsigned int family;
@@ -59,6 +60,7 @@ struct options { unsigned int proto; } sock; struct option_cmsg_u32 mark; + struct option_cmsg_u32 priority_cmsg; struct { bool ena; unsigned int delay;
@@ -97,6 +99,7 @@ static void __attribute__((noreturn)) cs_usage(const char *bin) "\n" "\t\t-m val Set SO_MARK with given value\n" "\t\t-M val Set SO_MARK via setsockopt\n" + "\t\t-Q val Set SO_PRIORITY via cmsg\n" "\t\t-d val Set SO_TXTIME with given delay (usec)\n" "\t\t-t Enable time stamp reporting\n" "\t\t-f val Set don't fragment via cmsg\n"
@@ -115,7 +118,7 @@ static void cs_parse_args(int argc, char *argv[]) { int o; - while ((o = getopt(argc, argv, "46sS:p:P:m:M:n:d:tf:F:c:C:l:L:H:")) != -1) { + while ((o = getopt(argc, argv, "46sS:p:P:m:M:n:d:tf:F:c:C:l:L:H:Q:")) != -1) { switch (o) { case 's': opt.silent_send = true;
@@ -148,6 +151,10 @@ static void cs_parse_args(int argc, char *argv[]) opt.mark.ena = true; opt.mark.val = atoi(optarg); break; + case 'Q': + opt.priority_cmsg.ena = true; + opt.priority_cmsg.val = atoi(optarg); + break; case 'M': opt.sockopt.mark = atoi(optarg); break;
@@ -252,6 +259,8 @@ cs_write_cmsg(int fd, struct msghdr *msg, char *cbuf, size_t cbuf_sz) ca_write_cmsg_u32(cbuf, cbuf_sz, &cmsg_len, SOL_SOCKET, SO_MARK, &opt.mark); + ca_write_cmsg_u32(cbuf, cbuf_sz, &cmsg_len, + SOL_SOCKET, SO_PRIORITY, &opt.priority_cmsg); ca_write_cmsg_u32(cbuf, cbuf_sz, &cmsg_len, SOL_IPV6, IPV6_DONTFRAG, &opt.v6.dontfrag); ca_write_cmsg_u32(cbuf, cbuf_sz, &cmsg_len,
diff --git a/tools/testing/selftests/net/cmsg_so_priority.sh b/tools/testing/selftests/net/cmsg_so_priority.sh
new file mode 100755
index 000000000000..706d29b251e9
--- /dev/null
+++ b/tools/testing/selftests/net/cmsg_so_priority.sh@@ -0,0 +1,115 @@ +#!/bin/bash + +source lib.sh + +IP4=192.168.0.2/16 +TGT4=192.168.0.3/16 +TGT4_NO_MASK=192.168.0.3 +IP6=2001:db8::2/64 +TGT6=2001:db8::3/64 +TGT6_NO_MASK=2001:db8::3 +IP4BR=192.168.0.1/16 +IP6BR=2001:db8::1/64 +PORT=8080 +DELAY=400000 +QUEUE_NUM=4 + + +cleanup() { + ip netns del red 2>/dev/null + ip netns del green 2>/dev/null + ip link del br0 2>/dev/null + ip link del vethcab0 2>/dev/null + ip link del vethcab1 2>/dev/null +} + +trap cleanup EXIT + +priority_values=($(seq 0 $((QUEUE_NUM - 1)))) + +queue_config="" +for ((i=0; i<$QUEUE_NUM; i++)); do + queue_config+=" 1@$i" +done + +map_config=$(seq 0 $((QUEUE_NUM - 1)) | tr '\n' ' ') + +ip netns add red +ip netns add green +ip link add br0 type bridge +ip link set br0 up +ip addr add $IP4BR dev br0 +ip addr add $IP6BR dev br0 + +ip link add vethcab0 type veth peer name red0 +ip link set vethcab0 master br0 +ip link set red0 netns red +ip netns exec red bash -c " +ip link set lo up +ip link set red0 up +ip addr add $IP4 dev red0 +ip addr add $IP6 dev red0 +sysctl -w net.ipv4.ping_group_range='0 2147483647' +exit" +ip link set vethcab0 up + +ip link add vethcab1 type veth peer name green0 +ip link set vethcab1 master br0 +ip link set green0 netns green +ip netns exec green bash -c " +ip link set lo up +ip link set green0 up +ip addr add $TGT4 dev green0 +ip addr add $TGT6 dev green0 +exit" +ip link set vethcab1 up + +ip netns exec red bash -c " +sudo ethtool -L red0 tx $QUEUE_NUM rx $QUEUE_NUM +sudo tc qdisc add dev red0 root mqprio num_tc $QUEUE_NUM queues $queue_config map $map_config hw 0 +exit" + +get_queue_bytes() { + ip netns exec red sudo tc -s qdisc show dev red0 | grep 'Sent' | awk '{print $2}' +} + +TOTAL_TESTS=0 +FAILED_TESTS=0 + +check_result() { + ((TOTAL_TESTS++)) + if [ "$1" -ne 0 ]; then + ((FAILED_TESTS++)) + fi +} + + +for i in 4 6; do + [ $i == 4 ] && TGT=$TGT4_NO_MASK || TGT=$TGT6_NO_MASK + + for p in u i r; do + echo "Test IPV$i, prot: $p" + for value in "${priority_values[@]}"; do + ip netns exec red ./cmsg_sender -$i -Q $value -d "${DELAY}" -p $p $TGT $PORT + setsockopt_priority_bytes_num=($(get_queue_bytes)) + + ip netns exec red ./cmsg_sender -$i -P $value -d "${DELAY}" -p $p $TGT $PORT + cmsg_priority_bytes_num=($(get_queue_bytes)) + + if [[ "${cmsg_priority_bytes_num[$actual_queue]}" != \ + "${setsockopt_priority_bytes_num[$actual_queue]}" ]]; then + check_result 0 + else + check_result 1 + fi + done + done +done + +if [ $FAILED_TESTS -ne 0 ]; then + echo "FAIL - $FAILED_TESTS/$TOTAL_TESTS tests failed" + exit 1 +else + echo "OK - All $TOTAL_TESTS tests passed" + exit 0 +fi
--
2.43.0