Thread (12 messages) flat view 12 messages, 1 author, 1d ago
WARM1d

[PATCH net-next 03/11] selftests: net: add a test for the tunnel RX drop reasons

From: Anton Danilov <hidden>
Date: 2026-08-31 21:51:58
Also in: linux-kselftest, lkml
Subsystem: kernel selftest framework, networking [general], the rest · Maintainers: Shuah Khan, Shuah Khan, "David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, Linus Torvalds

Exercise the two drop reasons added to ip_tunnel_rcv() and
__ip6_tnl_rcv() for the cases they were introduced for, on both GRE and
ip6gre:

 - a receiver configured with 'iseq' or 'icsum' facing a sender that
   emits neither reports IP_TUNNEL_CFG_OPTS_MISMATCH,

 - recreating the tunnel device on the sender resets its outgoing
   sequence number the way a peer reboot would, and the receiver then
   reports IP_TUNNEL_OLD_SEQ.

A control case, where both endpoints agree on the options, makes sure
that no tunnel drop reason is reported when the packets are accepted.

The reasons are read from the skb:kfree_skb tracepoint through a
dedicated trace instance, so that the test neither disturbs nor depends
on anything else using the tracing facility.  The test is skipped when
that instance cannot be set up.

Assisted-by: Claude-Code:claude-opus-5
Signed-off-by: Anton Danilov <redacted>
---
 tools/testing/selftests/net/Makefile          |   1 +
 tools/testing/selftests/net/config            |   1 +
 .../selftests/net/tunnel_drop_reasons.sh      | 228 ++++++++++++++++++
 3 files changed, 230 insertions(+)
 create mode 100755 tools/testing/selftests/net/tunnel_drop_reasons.sh
diff --git a/tools/testing/selftests/net/Makefile b/tools/testing/selftests/net/Makefile
index 0f5c178bc224..9acf364e8919 100644
--- a/tools/testing/selftests/net/Makefile
+++ b/tools/testing/selftests/net/Makefile
@@ -117,6 +117,7 @@ TEST_PROGS := \
 	test_vxlan_vnifiltering.sh \
 	tfo_passive.sh \
 	traceroute.sh \
+	tunnel_drop_reasons.sh \
 	txtimestamp.sh \
 	udpgro.sh \
 	udpgro_bench.sh \
diff --git a/tools/testing/selftests/net/config b/tools/testing/selftests/net/config
index 30d5fcb09a83..281633ff3aa9 100644
--- a/tools/testing/selftests/net/config
+++ b/tools/testing/selftests/net/config
@@ -14,6 +14,7 @@ CONFIG_CRYPTO_SM4_GENERIC=y
 CONFIG_DEBUG_INFO_BTF=y
 CONFIG_DEBUG_INFO_BTF_MODULES=n
 CONFIG_DUMMY=y
+CONFIG_ENABLE_DEFAULT_TRACERS=y
 CONFIG_GENEVE=m
 CONFIG_IFB=y
 CONFIG_INET_DIAG=y
diff --git a/tools/testing/selftests/net/tunnel_drop_reasons.sh b/tools/testing/selftests/net/tunnel_drop_reasons.sh
new file mode 100755
index 000000000000..eb19967ae7dd
--- /dev/null
+++ b/tools/testing/selftests/net/tunnel_drop_reasons.sh
@@ -0,0 +1,228 @@
+#!/bin/bash
+# SPDX-License-Identifier: GPL-2.0
+#
+# Test the drop reasons reported by the generic tunnel RX path,
+# ip_tunnel_rcv() and __ip6_tnl_rcv().
+#
+# Two situations are checked, for both GRE and ip6gre:
+#
+#  - the options carried by the packet do not match the tunnel
+#    configuration, which is reported as IP_TUNNEL_CFG_OPTS_MISMATCH.
+#    It is triggered here by configuring the receiver with 'iseq' or
+#    'icsum' while the sender emits neither.
+#
+#  - the sequence number of the packet is older than the one expected by
+#    the tunnel, which is reported as IP_TUNNEL_OLD_SEQ.  It is
+#    triggered here by recreating the tunnel device on the sender, which
+#    resets its outgoing sequence number the same way a peer reboot
+#    would.
+#
+# A control case, where both endpoints agree on the options, makes sure
+# that no tunnel drop reason is reported when packets are accepted.
+#
+# Drop reasons are read from the skb:kfree_skb tracepoint.  A dedicated
+# trace instance is used so that the test does not disturb, and is not
+# disturbed by, anything else using the tracing facility.
+
+source lib.sh
+
+NS_SND=""
+NS_RCV=""
+TRACE_DIR=""
+TR=""
+
+SND_V4=10.0.0.1
+RCV_V4=10.0.0.2
+SND_V6=2001:db8::1
+RCV_V6=2001:db8::2
+TUN_SND=192.168.1.1
+TUN_RCV=192.168.1.2
+
+cleanup()
+{
+	if [ -n "$TR" ]; then
+		echo 0 > "$TR/events/skb/kfree_skb/enable" 2>/dev/null
+		rmdir "$TR" 2>/dev/null
+	fi
+	cleanup_all_ns
+}
+
+trap cleanup EXIT
+
+setup_tracing()
+{
+	local dir
+
+	for dir in /sys/kernel/tracing /sys/kernel/debug/tracing; do
+		if [ -f "$dir/trace" ]; then
+			TRACE_DIR="$dir"
+			break
+		fi
+	done
+	[ -n "$TRACE_DIR" ] || return 1
+	[ -d "$TRACE_DIR/instances" ] || return 1
+	[ -e "$TRACE_DIR/events/skb/kfree_skb" ] || return 1
+
+	TR="$TRACE_DIR/instances/tunnel_drop_reasons"
+	mkdir "$TR" 2>/dev/null || return 1
+	echo 1 > "$TR/events/skb/kfree_skb/enable" || return 1
+}
+
+setup_ns_pair()
+{
+	cleanup_all_ns
+	setup_ns NS_SND NS_RCV
+
+	ip link add veth_s netns "$NS_SND" type veth \
+		peer name veth_r netns "$NS_RCV"
+	ip -n "$NS_SND" link set veth_s up
+	ip -n "$NS_RCV" link set veth_r up
+
+	ip -n "$NS_SND" addr add "$SND_V4/24" dev veth_s
+	ip -n "$NS_RCV" addr add "$RCV_V4/24" dev veth_r
+	ip -n "$NS_SND" addr add "$SND_V6/64" dev veth_s nodad
+	ip -n "$NS_RCV" addr add "$RCV_V6/64" dev veth_r nodad
+}
+
+# $1: namespace, $2: local, $3: remote, $4...: tunnel options
+add_gre()
+{
+	local ns=$1 loc=$2 rem=$3
+
+	shift 3
+	ip -n "$ns" link add gre_test type gre local "$loc" remote "$rem" "$@"
+	ip -n "$ns" link set gre_test up
+}
+
+# $1: namespace, $2: local, $3: remote, $4...: tunnel options
+add_ip6gre()
+{
+	local ns=$1 loc=$2 rem=$3
+
+	shift 3
+	ip -n "$ns" link add gre_test type ip6gre local "$loc" remote "$rem" \
+		"$@"
+	ip -n "$ns" link set gre_test up
+}
+
+addr_tunnels()
+{
+	ip -n "$NS_SND" addr add "$TUN_SND/24" dev gre_test
+	ip -n "$NS_RCV" addr add "$TUN_RCV/24" dev gre_test
+}
+
+send_traffic()
+{
+	ip netns exec "$NS_SND" ping -c 2 -W 1 "$TUN_RCV" >/dev/null 2>&1
+	# Let the tracepoint records reach the trace buffer.
+	sleep 1
+}
+
+# $1: test name, $2: expected reason, empty if none is expected
+check_reason()
+{
+	local name=$1 want=$2 count
+
+	echo > "$TR/trace"
+	send_traffic
+
+	if [ -n "$want" ]; then
+		count=$(grep -c "reason: $want" "$TR/trace")
+		if [ "$count" -gt 0 ]; then
+			RET=$ksft_pass
+		else
+			RET=$ksft_fail
+		fi
+		log_test "$name" "$count dropped"
+	else
+		count=$(grep -c "reason: IP_TUNNEL_" "$TR/trace")
+		if [ "$count" -eq 0 ]; then
+			RET=$ksft_pass
+		else
+			RET=$ksft_fail
+		fi
+		log_test "$name" "$count dropped"
+	fi
+}
+
+test_opts_mismatch()
+{
+	local proto=$1 opt=$2
+	local add=add_gre loc=$SND_V4 rem=$RCV_V4
+
+	if [ "$proto" = "ip6gre" ]; then
+		add=add_ip6gre
+		loc=$SND_V6
+		rem=$RCV_V6
+	fi
+
+	setup_ns_pair
+	# The sender emits no option, the receiver expects one.
+	$add "$NS_SND" "$loc" "$rem"
+	$add "$NS_RCV" "$rem" "$loc" "$opt"
+	addr_tunnels
+
+	check_reason "$proto: $opt option mismatch" \
+		IP_TUNNEL_CFG_OPTS_MISMATCH
+}
+
+test_old_seq()
+{
+	local proto=$1
+	local add=add_gre loc=$SND_V4 rem=$RCV_V4
+
+	if [ "$proto" = "ip6gre" ]; then
+		add=add_ip6gre
+		loc=$SND_V6
+		rem=$RCV_V6
+	fi
+
+	setup_ns_pair
+	$add "$NS_SND" "$loc" "$rem" oseq
+	$add "$NS_RCV" "$rem" "$loc" iseq
+	addr_tunnels
+
+	# Raise the sequence number expected by the receiver, then reset the
+	# one used by the sender, as a peer reboot would do.
+	send_traffic
+	ip -n "$NS_SND" link del gre_test
+	$add "$NS_SND" "$loc" "$rem" oseq
+	ip -n "$NS_SND" addr add "$TUN_SND/24" dev gre_test
+
+	check_reason "$proto: old sequence number" IP_TUNNEL_OLD_SEQ
+}
+
+test_control()
+{
+	setup_ns_pair
+	add_gre "$NS_SND" "$SND_V4" "$RCV_V4" oseq ocsum
+	add_gre "$NS_RCV" "$RCV_V4" "$SND_V4" iseq icsum
+	addr_tunnels
+
+	check_reason "gre: matching configuration (control)" ""
+}
+
+if [ "$(id -u)" -ne 0 ]; then
+	echo "SKIP: need root"
+	exit "$ksft_skip"
+fi
+
+if ! setup_tracing; then
+	echo "SKIP: could not set up a trace instance for skb:kfree_skb"
+	exit "$ksft_skip"
+fi
+
+test_opts_mismatch gre iseq
+test_opts_mismatch gre icsum
+test_control
+test_old_seq gre
+
+if [ -e /proc/sys/net/ipv6 ]; then
+	test_opts_mismatch ip6gre iseq
+	test_old_seq ip6gre
+else
+	log_test_skip "ip6gre: iseq option mismatch"
+	log_test_skip "ip6gre: old sequence number"
+fi
+
+exit "$EXIT_STATUS"
-- 
2.47.3
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help