mirror of
https://github.com/torvalds/linux.git
synced 2026-09-24 06:24:02 +02:00
The combination of checksum offload disabled (that causes software GSO)
and a debug kernel is inherently slow. Depending on the CPU power and
load, RTT may increase, limiting sk_pacing_rate, so tcp_tso_autosize
caps SKBs at around 40 segments, and zero BIG TCP packets are produced.
Increase sysctl net.ipv4.tcp_min_tso_segs and set a bigger initial value
of CWND in these configurations to force BIG TCP.
Fixes: 5cb53743e1 ("selftests: net: Add a test for BIG TCP in UDP tunnels")
Signed-off-by: Alice Mikityanska <alice@isovalent.com>
Acked-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
Link: https://patch.msgid.link/20260822120308.1165200-5-alice.kernel@fastmail.im
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
219 lines
7.4 KiB
Bash
Executable File
219 lines
7.4 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# SPDX-License-Identifier: GPL-2.0
|
|
#
|
|
# Testing for IPv4 and IPv6 BIG TCP over VXLAN and GENEVE tunnels.
|
|
|
|
source "$(dirname "$0")/lib.sh"
|
|
|
|
SERVER_NS=$(mktemp -u server-XXXXXXXX)
|
|
SERVER_IP4="192.168.1.1"
|
|
SERVER_IP6="2001:db8::1:1"
|
|
SERVER_IP4_TUN="192.168.2.1"
|
|
SERVER_IP6_TUN="2001:db8::2:1"
|
|
|
|
CLIENT_NS=$(mktemp -u client-XXXXXXXX)
|
|
CLIENT_IP4="192.168.1.2"
|
|
CLIENT_IP6="2001:db8::1:2"
|
|
CLIENT_IP4_TUN="192.168.2.2"
|
|
CLIENT_IP6_TUN="2001:db8::2:2"
|
|
|
|
# Kselftest framework requirement - SKIP code is 4.
|
|
ksft_skip=4
|
|
|
|
if [ -z "$PACKETS_THRESHOLD" ]; then
|
|
if [ "$KSFT_MACHINE_SLOW" = yes ]; then
|
|
echo 'Debug kernel detected, lowering the default threshold'
|
|
PACKETS_THRESHOLD=100
|
|
else
|
|
PACKETS_THRESHOLD=1000
|
|
fi
|
|
fi
|
|
|
|
setup() {
|
|
ip netns add "$SERVER_NS"
|
|
ip netns add "$CLIENT_NS"
|
|
ip -netns "$SERVER_NS" link add link1 type veth peer name link0 netns "$CLIENT_NS"
|
|
|
|
ip -netns "$CLIENT_NS" link set link0 up
|
|
ip -netns "$CLIENT_NS" addr replace "$CLIENT_IP4/24" dev link0
|
|
ip -netns "$CLIENT_NS" addr replace "$CLIENT_IP6/112" dev link0 nodad
|
|
ip -netns "$CLIENT_NS" link set link0 \
|
|
gso_max_size 196608 gso_ipv4_max_size 196608 \
|
|
gro_max_size 196608 gro_ipv4_max_size 196608
|
|
ip -netns "$SERVER_NS" link set link1 up
|
|
ip -netns "$SERVER_NS" addr replace "$SERVER_IP4/24" dev link1
|
|
ip -netns "$SERVER_NS" addr replace "$SERVER_IP6/112" dev link1 nodad
|
|
ip -netns "$SERVER_NS" link set link1 \
|
|
gso_max_size 196608 gso_ipv4_max_size 196608 \
|
|
gro_max_size 196608 gro_ipv4_max_size 196608
|
|
|
|
ip netns exec "$SERVER_NS" netserver >/dev/null
|
|
wait_local_port_listen "$SERVER_NS" 12865 tcp
|
|
|
|
DEFAULT_TCP_MIN_TSO_SEGS=$(ip netns exec "$CLIENT_NS" sysctl -n net.ipv4.tcp_min_tso_segs)
|
|
}
|
|
|
|
setup_tunnel() {
|
|
if [ "$2" = 4 ]; then
|
|
SERVER_IP="$SERVER_IP4"
|
|
CLIENT_IP="$CLIENT_IP4"
|
|
echo "Setting up ${1^^} over IPv4, veth tx csum offload $3"
|
|
else
|
|
SERVER_IP="$SERVER_IP6"
|
|
CLIENT_IP="$CLIENT_IP6"
|
|
echo "Setting up ${1^^} over IPv6, veth tx csum offload $3"
|
|
fi
|
|
|
|
if [ "$1" = vxlan ]; then
|
|
ip -netns "$CLIENT_NS" link add tun0 type vxlan \
|
|
id 5001 remote "$SERVER_IP" local "$CLIENT_IP" dev link0 dstport 4789
|
|
else
|
|
ip -netns "$CLIENT_NS" link add tun0 type geneve \
|
|
id 5001 remote "$SERVER_IP"
|
|
fi
|
|
ip -netns "$CLIENT_NS" link set tun0 up
|
|
ip -netns "$CLIENT_NS" addr replace "$CLIENT_IP4_TUN/24" dev tun0
|
|
ip -netns "$CLIENT_NS" addr replace "$CLIENT_IP6_TUN/112" dev tun0 nodad
|
|
ip -netns "$CLIENT_NS" link set tun0 \
|
|
gso_max_size 196608 gso_ipv4_max_size 196608 \
|
|
gro_max_size 196608 gro_ipv4_max_size 196608
|
|
if [ "$1" = vxlan ]; then
|
|
ip -netns "$SERVER_NS" link add tun1 type vxlan \
|
|
id 5001 remote "$CLIENT_IP" local "$SERVER_IP" dev link1 dstport 4789
|
|
else
|
|
ip -netns "$SERVER_NS" link add tun1 type geneve \
|
|
id 5001 remote "$CLIENT_IP"
|
|
fi
|
|
ip -netns "$SERVER_NS" link set tun1 up
|
|
ip -netns "$SERVER_NS" addr replace "$SERVER_IP4_TUN/24" dev tun1
|
|
ip -netns "$SERVER_NS" addr replace "$SERVER_IP6_TUN/112" dev tun1 nodad
|
|
ip -netns "$SERVER_NS" link set tun1 \
|
|
gso_max_size 196608 gso_ipv4_max_size 196608 \
|
|
gro_max_size 196608 gro_ipv4_max_size 196608
|
|
|
|
ip netns exec "$CLIENT_NS" ethtool -K link0 tx-checksumming "$3" > /dev/null
|
|
ip netns exec "$SERVER_NS" ethtool -K link1 tx-checksumming "$3" > /dev/null
|
|
}
|
|
|
|
cleanup_tunnel() {
|
|
ip -netns "$CLIENT_NS" link del tun0
|
|
ip -netns "$SERVER_NS" link del tun1
|
|
}
|
|
|
|
cleanup() {
|
|
ip netns pids "$SERVER_NS" | xargs -r kill
|
|
ip netns pids "$CLIENT_NS" | xargs -r kill
|
|
ip netns del "$SERVER_NS"
|
|
ip netns del "$CLIENT_NS"
|
|
rm -rf "$WORKDIR"
|
|
}
|
|
|
|
do_test() {
|
|
local packets_threshold="$PACKETS_THRESHOLD"
|
|
|
|
# When tx csum offload is off, software GSO is performed before passing the
|
|
# packet to veth. Check BIG TCP packets inside the VXLAN tunnel to verify
|
|
# the software checksum path: if the checksum code is broken, these packets
|
|
# will be dropped.
|
|
if [ "$3" = on ]; then
|
|
CAPTURE_IFACE='link'
|
|
if [ "$1" = 4 ]; then
|
|
IPTABLES=iptables
|
|
else
|
|
IPTABLES=ip6tables
|
|
fi
|
|
else
|
|
CAPTURE_IFACE='tun'
|
|
if [ "$2" = 4 ]; then
|
|
IPTABLES=iptables
|
|
else
|
|
IPTABLES=ip6tables
|
|
fi
|
|
packets_threshold=$(( PACKETS_THRESHOLD / 10 ))
|
|
fi
|
|
if [ "$2" = 4 ]; then
|
|
IPTABLES_SACK=iptables
|
|
else
|
|
IPTABLES_SACK=ip6tables
|
|
fi
|
|
|
|
if [ "$3" != 'on' ] && [ "$KSFT_MACHINE_SLOW" = yes ]; then
|
|
echo 'Slow configuration; increasing net.ipv4.tcp_min_tso_segs and initcwnd'
|
|
ip netns exec "$CLIENT_NS" sysctl -w net.ipv4.tcp_min_tso_segs=52
|
|
if [ "$2" = 4 ]; then
|
|
ip -netns "$CLIENT_NS" \
|
|
route change 192.168.2.0/24 dev tun0 initcwnd 100
|
|
else
|
|
ip -netns "$CLIENT_NS" -6 \
|
|
route change 2001:db8::2:0/112 dev tun0 initcwnd 100
|
|
fi
|
|
else
|
|
ip netns exec "$CLIENT_NS" \
|
|
sysctl -w net.ipv4.tcp_min_tso_segs="$DEFAULT_TCP_MIN_TSO_SEGS"
|
|
fi
|
|
|
|
ip netns exec "$SERVER_NS" "$IPTABLES" -w -t raw -I PREROUTING -i "${CAPTURE_IFACE}1" -m length ! --length 0:65535 -m comment --comment "bigtcp"
|
|
ip netns exec "$CLIENT_NS" "$IPTABLES" -w -t raw -I OUTPUT -o "${CAPTURE_IFACE}0" -m length ! --length 0:65535 -m comment --comment "bigtcp"
|
|
ip netns exec "$SERVER_NS" "$IPTABLES_SACK" -w -t raw -I OUTPUT -o "tun1" -p tcp -m tcp --tcp-flags ACK ACK --tcp-option 5 -m comment --comment "sack"
|
|
|
|
if [ "$2" = 4 ]; then
|
|
SERVER_IP="$SERVER_IP4_TUN"
|
|
echo "Running IPv4 traffic in the tunnel"
|
|
else
|
|
SERVER_IP="$SERVER_IP6_TUN"
|
|
echo "Running IPv6 traffic in the tunnel"
|
|
fi
|
|
|
|
ip netns exec "$CLIENT_NS" netperf -t TCP_STREAM -l 5 -H "$SERVER_IP" -- \
|
|
-m 80000 > /dev/null
|
|
|
|
PACKETS_SERVER=$(ip netns exec "$SERVER_NS" "$IPTABLES-save" -c -t raw | sed -rn '/ --comment bigtcp/{s/^\[([0-9]+):.*/\1/p;q}')
|
|
PACKETS_CLIENT=$(ip netns exec "$CLIENT_NS" "$IPTABLES-save" -c -t raw | sed -rn '/ --comment bigtcp/{s/^\[([0-9]+):.*/\1/p;q}')
|
|
PACKETS_SACK=$(ip netns exec "$SERVER_NS" "$IPTABLES_SACK-save" -c -t raw | sed -rn '/ --comment sack/{s/^\[([0-9]+):.*/\1/p;q}')
|
|
ip netns exec "$SERVER_NS" "$IPTABLES" -w -t raw -D PREROUTING -i "${CAPTURE_IFACE}1" -m length ! --length 0:65535 -m comment --comment "bigtcp"
|
|
ip netns exec "$CLIENT_NS" "$IPTABLES" -w -t raw -D OUTPUT -o "${CAPTURE_IFACE}0" -m length ! --length 0:65535 -m comment --comment "bigtcp"
|
|
ip netns exec "$SERVER_NS" "$IPTABLES_SACK" -w -t raw -D OUTPUT -o "tun1" -p tcp -m tcp --tcp-flags ACK ACK --tcp-option 5 -m comment --comment "sack"
|
|
|
|
echo "Captured BIG TCP RX packets: $PACKETS_SERVER"
|
|
echo "Captured BIG TCP TX packets: $PACKETS_CLIENT"
|
|
echo "Captured TCP SACK packets: $PACKETS_SACK"
|
|
[ "$PACKETS_SERVER" -gt "$packets_threshold" ] || return 1
|
|
[ "$PACKETS_CLIENT" -gt "$packets_threshold" ] || return 1
|
|
[ "$PACKETS_SACK" -lt "$(( PACKETS_CLIENT / 2 ))" ] || return 1
|
|
}
|
|
|
|
if ! netperf -V &> /dev/null; then
|
|
echo "SKIP: Could not run test without netperf tool"
|
|
exit "$ksft_skip"
|
|
fi
|
|
|
|
if ! iptables --version &> /dev/null; then
|
|
echo "SKIP: Could not run test without iptables tool"
|
|
exit "$ksft_skip"
|
|
fi
|
|
|
|
if ! ethtool --version &> /dev/null; then
|
|
echo "SKIP: Could not run test without ethtool tool"
|
|
exit "$ksft_skip"
|
|
fi
|
|
|
|
if ! ip link help 2>&1 | grep gso_ipv4_max_size &> /dev/null; then
|
|
echo "SKIP: Could not run test without gso/gro_ipv4_max_size supported in ip-link"
|
|
exit "$ksft_skip"
|
|
fi
|
|
|
|
WORKDIR=$(mktemp -d)
|
|
trap cleanup EXIT
|
|
setup
|
|
for tunnel in vxlan geneve; do
|
|
for tun_family in 4 6; do
|
|
for traffic_family in 4 6; do
|
|
for csum_offload in on off; do
|
|
setup_tunnel "$tunnel" "$tun_family" "$csum_offload" || exit "$?"
|
|
do_test "$tun_family" "$traffic_family" "$csum_offload" || exit "$?"
|
|
cleanup_tunnel
|
|
done
|
|
done
|
|
done
|
|
done
|