lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <fdf9b17e685bb9de400e5c33efadf248cad921a2.1764056123.git.pabeni@redhat.com>
Date: Tue, 25 Nov 2025 17:11:15 +0100
From: Paolo Abeni <pabeni@...hat.com>
To: netdev@...r.kernel.org
Cc: "David S. Miller" <davem@...emloft.net>,
	Eric Dumazet <edumazet@...gle.com>,
	Jakub Kicinski <kuba@...nel.org>,
	Simon Horman <horms@...nel.org>,
	Donald Hunter <donald.hunter@...il.com>,
	Andrew Lunn <andrew+netdev@...n.ch>,
	Shuah Khan <shuah@...nel.org>,
	Willem de Bruijn <willemdebruijn.kernel@...il.com>
Subject: [PATCH net-next 10/10] selftests: net: tests for add double tunneling GRO/GSO

Create a simple, netns-based topology with double, nested UDP tunnels and
perform TSO transfers on top.

Explicitly enable GSO and/or GRO and check the skb layout consistency with
different configuration allowing (or not) GSO frames to be delivered on
the other end.

Signed-off-by: Paolo Abeni <pabeni@...hat.com>
---
 tools/testing/selftests/net/Makefile          |   1 +
 .../testing/selftests/net/double_udp_encap.sh | 340 ++++++++++++++++++
 2 files changed, 341 insertions(+)
 create mode 100755 tools/testing/selftests/net/double_udp_encap.sh

diff --git a/tools/testing/selftests/net/Makefile b/tools/testing/selftests/net/Makefile
index b66ba04f19d9..063155f42cd7 100644
--- a/tools/testing/selftests/net/Makefile
+++ b/tools/testing/selftests/net/Makefile
@@ -22,6 +22,7 @@ TEST_PROGS := \
 	cmsg_so_mark.sh \
 	cmsg_so_priority.sh \
 	cmsg_time.sh \
+	double_udp_encap.sh \
 	drop_monitor_tests.sh \
 	fcnal-ipv4.sh \
 	fcnal-ipv6.sh \
diff --git a/tools/testing/selftests/net/double_udp_encap.sh b/tools/testing/selftests/net/double_udp_encap.sh
new file mode 100755
index 000000000000..99c855b11df2
--- /dev/null
+++ b/tools/testing/selftests/net/double_udp_encap.sh
@@ -0,0 +1,340 @@
+#!/bin/bash
+# SPDX-License-Identifier: GPL-2.0
+
+source lib.sh
+
+readonly CLI=$(dirname $(readlink -f $0))/../../../net/ynl/pyynl/cli.py
+
+readonly SRC=1
+readonly DST=2
+
+readonly NET_V4=192.168.1.
+readonly NET_V6=2001:db8::
+readonly OL1_NET_V4=172.16.1.
+readonly OL1_NET_V6=2001:db8:1::
+readonly OL2_NET_V4=172.16.2.
+readonly OL2_NET_V6=2001:db8:2::
+
+trap cleanup_all_ns EXIT
+
+is_ipv6() {
+	if [[ $1 =~ .*:.* ]]; then
+		return 0
+	fi
+	return 1
+}
+
+create_gnv_endpoint() {
+	local -r netns=$1
+	local -r bm_dev=$2
+	local -r bm_rem_addr=$3
+	local -r gnv_dev=$4
+	local -r gnv_id=$5
+	local gnv_json
+	local opts
+	local rem
+	shift 5
+
+	if is_ipv6 $bm_rem_addr; then
+		rem=remote6
+	else
+		rem=remote
+	fi
+
+	while [ -n "$1" ]; do
+		opts="$opts, $1"
+		shift
+	done
+
+	gnv_json="{ \"id\": $gnv_id, \"$rem\": \"$bm_rem_addr\"$opts }"
+	ip netns exec $netns $CLI --family rt-link --create --excl \
+		--do newlink  --json "{\"ifname\": \"$gnv_dev\",
+				       \"linkinfo\": {\"kind\":\"geneve\",
+				       \"data\": $gnv_json } }" > /dev/null
+	ip -n $netns link set dev $gnv_dev up
+}
+
+create_vxlan_endpoint() {
+	local -r netns=$1
+	local -r bm_dev=$2
+	local -r bm_rem_addr=$3
+	local -r vxlan_dev=$4
+	local -r vxlan_id=$5
+	local opts
+	shift 5
+
+	# convert the arguments from yaml format
+	while [ -n "$1" ]; do
+		local opt=$1
+		local pattern='"port":'
+
+		opts="$opts ${opt/$pattern/dstport }"
+		shift
+	done
+	[ -n "$opts" ] || opts="dstport 4789"
+
+	ip -n $netns link add $vxlan_dev type vxlan id $vxlan_id \
+		remote $bm_rem_addr $opts
+	ip -n $netns link set dev $vxlan_dev up
+}
+
+create_ns() {
+	local create_endpoint
+	local nested_opt="$2"
+	local options="$1"
+	local addr_src
+	local addr_dst
+	local feature
+	local dev
+	local id
+	local ns
+
+	RET=0
+
+	#  +-------------+    +-------------+
+	#  | NS_SRC      |    | NS_NST_DST  |
+	#  |             |    |             |
+	#  |   gnv_nst1  |    |  gnv_nst2   |
+	#  |   +         |    |         +   |
+	#  |   |         |    |         |   |
+	#  |   +         |    |         +   |
+	#  |  gnv1       |    |        gnv2 |
+	#  |   +         |    |         +   |
+	#  |   |         |    |         |   |
+	#  |   + veth1 +--------+ veth2 +   |
+	#  |             |    |             |
+	#  +-------------+    +-------------+
+
+	setup_ns NS_SRC NS_DST
+
+	ip link add name veth$SRC netns $NS_SRC type veth \
+		peer name veth$DST netns $NS_DST
+	case "$ENCAP" in
+	vxlan)
+		create_endpoint=create_vxlan_endpoint
+		dev=vx
+		;;
+	geneve)
+		create_endpoint=create_gnv_endpoint
+		dev=gnv
+		;;
+	esac
+
+	id=1
+	for ns in ${NS_LIST[@]}; do
+		ip -n $ns link set dev veth$id up
+
+		# ensure the sender can do large write just after 3whs
+		ip netns exec $ns \
+			sysctl -qw net.ipv4.tcp_wmem="4096 4194304 4194304"
+
+		# note that 3 - $SRC == $DST and 3 - $DST == $SRC
+		if [ $FAMILY = "4" ]; then
+			ip -n $ns addr add dev veth$id $NET_V4$id/24
+			$create_endpoint $ns veth$id $NET_V4$((3 - $id)) \
+				$dev$id 4 $options
+			ip -n $ns addr add dev $dev$id $OL1_NET_V4$id/24
+
+			# nested tunnel devices
+			# pmtu can't be propagated to upper layer devices;
+			# need manual adjust
+			$create_endpoint $ns $dev$id $OL1_NET_V4$((3 - $id)) \
+				$dev"_nst"$id 40 '"port":6082' $nested_opt
+			ip -n $ns addr add dev $dev"_nst"$id $OL2_NET_V4$id/24
+			ip -n $ns link set dev $dev"_nst"$id mtu 1392
+		else
+			ip -n $ns addr add dev veth$id $NET_V6$id/64 nodad
+			$create_endpoint $ns veth$id $NET_V6$((3 - $id)) \
+				$dev"6"$id 6 $options
+			ip -n $ns addr add dev $dev"6"$id $OL1_NET_V6$id/64 \
+				nodad
+
+			$create_endpoint $ns $dev"6"$id $OL1_NET_V6$((3 - $id))\
+				$dev"6_nst"$id 60 '"port":6082' $nested_opt
+			ip -n $ns addr add dev $dev"6_nst"$id $OL2_NET_V6$id/64\
+				nodad
+			ip -n $ns link set dev $dev"6_nst"$id mtu 1352
+		fi
+		id=$((id+1))
+	done
+
+	# enable GRO heuristic on the veth peer and ensure UDP L4 over tunnel is
+	# actually segmented
+	for feature in tso tx-udp_tnl-segmentation; do
+		ip netns exec $NS_SRC ethtool -K veth$SRC $feature off \
+			2>/dev/null
+	done
+}
+
+create_ns_gso()
+{
+	local dev
+
+	create_ns $*
+	if [ $ENCAP = "geneve" ]; then
+		dev=gnv
+	else
+		dev=vx
+	fi
+	if [ $FAMILY = "4" ]; then
+		ip netns exec $NS_SRC ethtool -K $dev$SRC tx-gso-partial on \
+			tx-udp_tnl-segmentation on \
+			tx-udp_tnl-csum-segmentation on
+	else
+		ip netns exec $NS_SRC ethtool -K $dev"6"$SRC tx-gso-partial on \
+			tx-udp_tnl-segmentation on \
+			tx-udp_tnl-csum-segmentation on
+	fi
+}
+
+create_ns_gso_gro()
+{
+	create_ns_gso $*
+	ip netns exec $NS_DST ethtool -K veth$DST gro on
+	ip netns exec $NS_SRC ethtool -K veth$SRC tx off >/dev/null 2>&1
+}
+
+run_test() {
+	local -r dst=$NET$DST
+	local -r msg=$1
+	local -r total_size=$2
+	local -r encappkts=$3
+	local rx_args=""
+	local rx_family="-4"
+	local filter=IpInReceives
+	local ipt=iptables
+	local wire_pkts
+	local dport
+	local pkts
+
+	if [ $FAMILY = "6" ]; then
+		# rx program does not support '-6' and implies ipv6 usage by
+		# default
+		rx_family=""
+		filter=Ip6InReceives
+		ipt=ip6tables
+	fi
+
+	# The received can only check fixed size packet
+	pkts=$((total_size / $GSO_SIZE))
+	rx_args="$rx_family"
+	if [ -n "$4" ]; then
+		wire_pkts=$4
+	elif [ $((total_size % $GSO_SIZE)) -eq 0 ]; then
+		wire_pkts=1
+		rx_args="$rx_args -l $GSO_SIZE"
+	else
+		wire_pkts=2
+		pkts=$((pkts + 1))
+	fi
+
+	if [ $ENCAP = "geneve" ]; then
+		dport=6081
+	else
+		dport=4789
+	fi
+
+	# ignore shorts packet, to avoid arp/mld induced noise
+	ip netns exec $NS_SRC $ipt -A OUTPUT -p udp --dport $dport \
+		-m length --length 300:65535
+	ip netns exec $NS_DST $ipt -A INPUT -p udp --dport $dport \
+		-m length --length 300:65535
+
+	ip netns exec $NS_DST ./udpgso_bench_rx -C 2000 -t -R 100 -n $pkts \
+		$rx_args &
+	local spid=$!
+	wait_local_port_listen "$NS_DST" 8000 tcp
+	ip netns exec $NS_SRC ./udpgso_bench_tx -$FAMILY -t -M 1 \
+		-s $total_size -D $dst
+	local ret=$?
+	check_err $ret "client failure exit code $ret"
+	wait $spid
+	ret=$?
+	check_err $ret "sever failure exit code $ret"
+
+	local snd=$(ip netns exec $NS_SRC $ipt"-save" -c |
+		    grep "dport $dport" | sed -e 's/\[//' -e 's/:.*//')
+	[ "$snd" = "$wire_pkts" ]
+	check_err $? "send $snd packets on the lowest link, expected $wire_pkts"
+
+	local rcvpkts=$(ip netns exec $NS_DST $ipt"-save" -c | \
+			grep "dport $dport" | sed -e 's/\[//' -e 's/:.*//')
+
+	[ "$rcvpkts" = "$encappkts" ]
+	check_err $? "received $rcvpkts $ENCAP packets, expected $encappkts"
+	log_test "$msg"
+}
+
+# tcp retransmisions will break the accounting
+[ "$KSFT_MACHINE_SLOW" = yes ] && FAIL_TO_XFAIL=yes
+for FAMILY in 4 6; do
+	NET=$OL2_NET_V4
+	IPT=iptables
+	GSO_SIZE=1340 # 1392 - 20 - 32
+
+	if [ $FAMILY = 6 ]; then
+		NET=$OL2_NET_V6
+		IPT=ip6tables
+		GSO_SIZE=1280 # 1352 - 40 - 32
+	fi
+
+	echo "IPv$FAMILY"
+
+	# "geneve" must be last encap in list, so that later
+	# test cases will run on it
+	for ENCAP in "vxlan" "geneve"; do
+		create_ns
+		run_test "No GSO - $ENCAP" $((GSO_SIZE * 4)) 4 4
+		cleanup_all_ns
+
+		create_ns_gso
+		run_test "GSO without GRO - $ENCAP" $((GSO_SIZE * 4)) 4 1
+		cleanup_all_ns
+
+		# IPv4 only test
+		[ $FAMILY = "4" ] || continue
+		create_ns_gso
+		ip netns exec $NS_SRC sysctl -qw net.ipv4.ip_no_pmtu_disc=1
+		run_test "GSO disable due to no fixedid - $ENCAP" \
+			$((GSO_SIZE * 4)) 4 4
+		cleanup_all_ns
+	done
+
+	# GRO tests imply/require geneve encap, the only one providing
+	# GRO hints
+	create_ns_gso_gro
+	run_test "double tunnel GRO, no hints" $((GSO_SIZE * 4)) 4
+	cleanup_all_ns
+
+	create_ns_gso_gro '"gro-hint":1'
+	run_test "double tunnel GRO" $((GSO_SIZE * 4)) 1
+	cleanup_all_ns
+
+	create_ns_gso_gro '"gro-hint":1,"udp-csum":1' '"udp-csum":1'
+	run_test "double tunnel GRO - csum complete" $((GSO_SIZE * 4)) 1
+	cleanup_all_ns
+
+	create_ns_gso_gro '"gro-hint":1' \
+		'"udp-csum":1,"udp-zero-csum6-tx":1,"udp-zero-csum6-rx":1'
+	run_test "double tunnel GRO - no nested csum" $((GSO_SIZE * 4)) 1
+	cleanup_all_ns
+
+	create_ns_gso_gro \
+		'"gro-hint":1,"udp-zero-csum6-tx":1,"udp-zero-csum6-rx":1' \
+		'"udp-csum":1'
+	run_test "double tunnel GRO - skip due nested csum with outer 0-csum" \
+		$((GSO_SIZE * 4)) 4
+	cleanup_all_ns
+
+	create_ns_gso_gro '"gro-hint":1,"udp-csum":1' \
+		'"udp-csum":1 "inner-proto-inherit":1'
+	run_test "double tunnel GRO - nested inherit proto" $((GSO_SIZE * 4)) 1
+	cleanup_all_ns
+
+	create_ns_gso_gro '"gro-hint":1'
+	run_test "double tunnel GRO - short last pkt" \
+		$((GSO_SIZE * 4 + $GSO_SIZE / 2)) 2
+	cleanup_all_ns
+done
+
+exit $EXIT_STATUS
-- 
2.52.0


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ