Skip to content

Commit

Permalink
selftests: net: test SO_PRIORITY ancillary data with cmsg_sender
Browse files Browse the repository at this point in the history
Extend cmsg_sender.c with a new option '-Q' to send SO_PRIORITY
ancillary data.

cmsg_so_priority.sh script added to validate SO_PRIORITY behavior
by creating VLAN device with egress QoS mapping and testing packet
priorities using flower filters. Verify that packets with different
priorities are correctly matched and counted by filters for multiple
protocols and IP versions.

Reviewed-by: Willem de Bruijn <willemb@google.com>
Acked-by: Willem de Bruijn <willemb@google.com>
Reviewed-by: Ido Schimmel <idosch@nvidia.com>
Tested-by: Ido Schimmel <idosch@nvidia.com>
Suggested-by: Ido Schimmel <idosch@idosch.org>
Signed-off-by: Anna Emese Nyiri <annaemesenyiri@gmail.com>
Link: https://patch.msgid.link/20241213084457.45120-4-annaemesenyiri@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
  • Loading branch information
Anna Emese Nyiri authored and Jakub Kicinski committed Dec 17, 2024
1 parent a32f3e9 commit cda7d5a
Show file tree
Hide file tree
Showing 3 changed files with 162 additions and 1 deletion.
1 change: 1 addition & 0 deletions tools/testing/selftests/net/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ TEST_PROGS += ioam6.sh
TEST_PROGS += gro.sh
TEST_PROGS += gre_gso.sh
TEST_PROGS += cmsg_so_mark.sh
TEST_PROGS += cmsg_so_priority.sh
TEST_PROGS += cmsg_time.sh cmsg_ipv6.sh
TEST_PROGS += netns-name.sh
TEST_PROGS += nl_netdev.py
Expand Down
11 changes: 10 additions & 1 deletion tools/testing/selftests/net/cmsg_sender.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ struct options {
unsigned int proto;
} sock;
struct option_cmsg_u32 mark;
struct option_cmsg_u32 priority;
struct {
bool ena;
unsigned int delay;
Expand Down Expand Up @@ -97,6 +98,8 @@ 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-P val Set SO_PRIORITY 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"
Expand All @@ -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;
Expand Down Expand Up @@ -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.ena = true;
opt.priority.val = atoi(optarg);
break;
case 'M':
opt.sockopt.mark = atoi(optarg);
break;
Expand Down Expand Up @@ -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);
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,
Expand Down
151 changes: 151 additions & 0 deletions tools/testing/selftests/net/cmsg_so_priority.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
#!/bin/bash
# SPDX-License-Identifier: GPL-2.0

source lib.sh

readonly KSFT_SKIP=4

IP4=192.0.2.1/24
TGT4=192.0.2.2
TGT4_RAW=192.0.2.3
IP6=2001:db8::1/64
TGT6=2001:db8::2
TGT6_RAW=2001:db8::3
PORT=1234
TOTAL_TESTS=0
FAILED_TESTS=0

if ! command -v jq &> /dev/null; then
echo "SKIP cmsg_so_priroity.sh test: jq is not installed." >&2
exit "$KSFT_SKIP"
fi

check_result() {
((TOTAL_TESTS++))
if [ "$1" -ne 0 ]; then
((FAILED_TESTS++))
fi
}

cleanup()
{
cleanup_ns $NS
}

trap cleanup EXIT

setup_ns NS

create_filter() {
local handle=$1
local vlan_prio=$2
local ip_type=$3
local proto=$4
local dst_ip=$5
local ip_proto

if [[ "$proto" == "u" ]]; then
ip_proto="udp"
elif [[ "$ip_type" == "ipv4" && "$proto" == "i" ]]; then
ip_proto="icmp"
elif [[ "$ip_type" == "ipv6" && "$proto" == "i" ]]; then
ip_proto="icmpv6"
fi

tc -n $NS filter add dev dummy1 \
egress pref 1 handle "$handle" proto 802.1q \
flower vlan_prio "$vlan_prio" vlan_ethtype "$ip_type" \
dst_ip "$dst_ip" ${ip_proto:+ip_proto $ip_proto} \
action pass
}

ip -n $NS link set dev lo up
ip -n $NS link add name dummy1 up type dummy

ip -n $NS link add link dummy1 name dummy1.10 up type vlan id 10 \
egress-qos-map 0:0 1:1 2:2 3:3 4:4 5:5 6:6 7:7

ip -n $NS address add $IP4 dev dummy1.10
ip -n $NS address add $IP6 dev dummy1.10 nodad

ip netns exec $NS sysctl -wq net.ipv4.ping_group_range='0 2147483647'

ip -n $NS neigh add $TGT4 lladdr 00:11:22:33:44:55 nud permanent \
dev dummy1.10
ip -n $NS neigh add $TGT6 lladdr 00:11:22:33:44:55 nud permanent \
dev dummy1.10
ip -n $NS neigh add $TGT4_RAW lladdr 00:11:22:33:44:66 nud permanent \
dev dummy1.10
ip -n $NS neigh add $TGT6_RAW lladdr 00:11:22:33:44:66 nud permanent \
dev dummy1.10

tc -n $NS qdisc add dev dummy1 clsact

FILTER_COUNTER=10

for i in 4 6; do
for proto in u i r; do
echo "Test IPV$i, prot: $proto"
for priority in {0..7}; do
if [[ $i == 4 && $proto == "r" ]]; then
TGT=$TGT4_RAW
elif [[ $i == 6 && $proto == "r" ]]; then
TGT=$TGT6_RAW
elif [ $i == 4 ]; then
TGT=$TGT4
else
TGT=$TGT6
fi

handle="${FILTER_COUNTER}${priority}"

create_filter $handle $priority ipv$i $proto $TGT

pkts=$(tc -n $NS -j -s filter show dev dummy1 egress \
| jq ".[] | select(.options.handle == ${handle}) | \
.options.actions[0].stats.packets")

if [[ $pkts == 0 ]]; then
check_result 0
else
echo "prio $priority: expected 0, got $pkts"
check_result 1
fi

ip netns exec $NS ./cmsg_sender -$i -Q $priority \
-p $proto $TGT $PORT

pkts=$(tc -n $NS -j -s filter show dev dummy1 egress \
| jq ".[] | select(.options.handle == ${handle}) | \
.options.actions[0].stats.packets")
if [[ $pkts == 1 ]]; then
check_result 0
else
echo "prio $priority -Q: expected 1, got $pkts"
check_result 1
fi

ip netns exec $NS ./cmsg_sender -$i -P $priority \
-p $proto $TGT $PORT

pkts=$(tc -n $NS -j -s filter show dev dummy1 egress \
| jq ".[] | select(.options.handle == ${handle}) | \
.options.actions[0].stats.packets")
if [[ $pkts == 2 ]]; then
check_result 0
else
echo "prio $priority -P: expected 2, got $pkts"
check_result 1
fi
done
FILTER_COUNTER=$((FILTER_COUNTER + 10))
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

0 comments on commit cda7d5a

Please sign in to comment.