xref: /aosp_15_r20/external/linux-kselftest/tools/testing/selftests/net/udpgro.sh (revision 053f45be4e351dfd5e965df293cd45b779f579ee)
1*053f45beSAndroid Build Coastguard Worker#!/bin/bash
2*053f45beSAndroid Build Coastguard Worker# SPDX-License-Identifier: GPL-2.0
3*053f45beSAndroid Build Coastguard Worker#
4*053f45beSAndroid Build Coastguard Worker# Run a series of udpgro functional tests.
5*053f45beSAndroid Build Coastguard Worker
6*053f45beSAndroid Build Coastguard Workerreadonly PEER_NS="ns-peer-$(mktemp -u XXXXXX)"
7*053f45beSAndroid Build Coastguard Worker
8*053f45beSAndroid Build Coastguard WorkerBPF_FILE="../bpf/xdp_dummy.bpf.o"
9*053f45beSAndroid Build Coastguard Worker
10*053f45beSAndroid Build Coastguard Worker# set global exit status, but never reset nonzero one.
11*053f45beSAndroid Build Coastguard Workercheck_err()
12*053f45beSAndroid Build Coastguard Worker{
13*053f45beSAndroid Build Coastguard Worker	if [ $ret -eq 0 ]; then
14*053f45beSAndroid Build Coastguard Worker		ret=$1
15*053f45beSAndroid Build Coastguard Worker	fi
16*053f45beSAndroid Build Coastguard Worker}
17*053f45beSAndroid Build Coastguard Worker
18*053f45beSAndroid Build Coastguard Workercleanup() {
19*053f45beSAndroid Build Coastguard Worker	local -r jobs="$(jobs -p)"
20*053f45beSAndroid Build Coastguard Worker	local -r ns="$(ip netns list|grep $PEER_NS)"
21*053f45beSAndroid Build Coastguard Worker
22*053f45beSAndroid Build Coastguard Worker	[ -n "${jobs}" ] && kill -1 ${jobs} 2>/dev/null
23*053f45beSAndroid Build Coastguard Worker	[ -n "$ns" ] && ip netns del $ns 2>/dev/null
24*053f45beSAndroid Build Coastguard Worker}
25*053f45beSAndroid Build Coastguard Workertrap cleanup EXIT
26*053f45beSAndroid Build Coastguard Worker
27*053f45beSAndroid Build Coastguard Workercfg_veth() {
28*053f45beSAndroid Build Coastguard Worker	ip netns add "${PEER_NS}"
29*053f45beSAndroid Build Coastguard Worker	ip -netns "${PEER_NS}" link set lo up
30*053f45beSAndroid Build Coastguard Worker	ip link add type veth
31*053f45beSAndroid Build Coastguard Worker	ip link set dev veth0 up
32*053f45beSAndroid Build Coastguard Worker	ip addr add dev veth0 192.168.1.2/24
33*053f45beSAndroid Build Coastguard Worker	ip addr add dev veth0 2001:db8::2/64 nodad
34*053f45beSAndroid Build Coastguard Worker
35*053f45beSAndroid Build Coastguard Worker	ip link set dev veth1 netns "${PEER_NS}"
36*053f45beSAndroid Build Coastguard Worker	ip -netns "${PEER_NS}" addr add dev veth1 192.168.1.1/24
37*053f45beSAndroid Build Coastguard Worker	ip -netns "${PEER_NS}" addr add dev veth1 2001:db8::1/64 nodad
38*053f45beSAndroid Build Coastguard Worker	ip -netns "${PEER_NS}" link set dev veth1 up
39*053f45beSAndroid Build Coastguard Worker	ip -n "${PEER_NS}" link set veth1 xdp object ${BPF_FILE} section xdp
40*053f45beSAndroid Build Coastguard Worker}
41*053f45beSAndroid Build Coastguard Worker
42*053f45beSAndroid Build Coastguard Workerrun_one() {
43*053f45beSAndroid Build Coastguard Worker	# use 'rx' as separator between sender args and receiver args
44*053f45beSAndroid Build Coastguard Worker	local -r all="$@"
45*053f45beSAndroid Build Coastguard Worker	local -r tx_args=${all%rx*}
46*053f45beSAndroid Build Coastguard Worker	local -r rx_args=${all#*rx}
47*053f45beSAndroid Build Coastguard Worker
48*053f45beSAndroid Build Coastguard Worker	cfg_veth
49*053f45beSAndroid Build Coastguard Worker
50*053f45beSAndroid Build Coastguard Worker	ip netns exec "${PEER_NS}" ./udpgso_bench_rx -C 1000 -R 10 ${rx_args} && \
51*053f45beSAndroid Build Coastguard Worker		echo "ok" || \
52*053f45beSAndroid Build Coastguard Worker		echo "failed" &
53*053f45beSAndroid Build Coastguard Worker
54*053f45beSAndroid Build Coastguard Worker	# Hack: let bg programs complete the startup
55*053f45beSAndroid Build Coastguard Worker	sleep 0.2
56*053f45beSAndroid Build Coastguard Worker	./udpgso_bench_tx ${tx_args}
57*053f45beSAndroid Build Coastguard Worker	ret=$?
58*053f45beSAndroid Build Coastguard Worker	wait $(jobs -p)
59*053f45beSAndroid Build Coastguard Worker	return $ret
60*053f45beSAndroid Build Coastguard Worker}
61*053f45beSAndroid Build Coastguard Worker
62*053f45beSAndroid Build Coastguard Workerrun_test() {
63*053f45beSAndroid Build Coastguard Worker	local -r args=$@
64*053f45beSAndroid Build Coastguard Worker
65*053f45beSAndroid Build Coastguard Worker	printf " %-40s" "$1"
66*053f45beSAndroid Build Coastguard Worker	./in_netns.sh $0 __subprocess $2 rx -G -r $3
67*053f45beSAndroid Build Coastguard Worker}
68*053f45beSAndroid Build Coastguard Worker
69*053f45beSAndroid Build Coastguard Workerrun_one_nat() {
70*053f45beSAndroid Build Coastguard Worker	# use 'rx' as separator between sender args and receiver args
71*053f45beSAndroid Build Coastguard Worker	local addr1 addr2 pid family="" ipt_cmd=ip6tables
72*053f45beSAndroid Build Coastguard Worker	local -r all="$@"
73*053f45beSAndroid Build Coastguard Worker	local -r tx_args=${all%rx*}
74*053f45beSAndroid Build Coastguard Worker	local -r rx_args=${all#*rx}
75*053f45beSAndroid Build Coastguard Worker
76*053f45beSAndroid Build Coastguard Worker	if [[ ${tx_args} = *-4* ]]; then
77*053f45beSAndroid Build Coastguard Worker		ipt_cmd=iptables
78*053f45beSAndroid Build Coastguard Worker		family=-4
79*053f45beSAndroid Build Coastguard Worker		addr1=192.168.1.1
80*053f45beSAndroid Build Coastguard Worker		addr2=192.168.1.3/24
81*053f45beSAndroid Build Coastguard Worker	else
82*053f45beSAndroid Build Coastguard Worker		addr1=2001:db8::1
83*053f45beSAndroid Build Coastguard Worker		addr2="2001:db8::3/64 nodad"
84*053f45beSAndroid Build Coastguard Worker	fi
85*053f45beSAndroid Build Coastguard Worker
86*053f45beSAndroid Build Coastguard Worker	cfg_veth
87*053f45beSAndroid Build Coastguard Worker	ip -netns "${PEER_NS}" addr add dev veth1 ${addr2}
88*053f45beSAndroid Build Coastguard Worker
89*053f45beSAndroid Build Coastguard Worker	# fool the GRO engine changing the destination address ...
90*053f45beSAndroid Build Coastguard Worker	ip netns exec "${PEER_NS}" $ipt_cmd -t nat -I PREROUTING -d ${addr1} -j DNAT --to-destination ${addr2%/*}
91*053f45beSAndroid Build Coastguard Worker
92*053f45beSAndroid Build Coastguard Worker	# ... so that GRO will match the UDP_GRO enabled socket, but packets
93*053f45beSAndroid Build Coastguard Worker	# will land on the 'plain' one
94*053f45beSAndroid Build Coastguard Worker	ip netns exec "${PEER_NS}" ./udpgso_bench_rx -G ${family} -b ${addr1} -n 0 &
95*053f45beSAndroid Build Coastguard Worker	pid=$!
96*053f45beSAndroid Build Coastguard Worker	ip netns exec "${PEER_NS}" ./udpgso_bench_rx -C 1000 -R 10 ${family} -b ${addr2%/*} ${rx_args} && \
97*053f45beSAndroid Build Coastguard Worker		echo "ok" || \
98*053f45beSAndroid Build Coastguard Worker		echo "failed"&
99*053f45beSAndroid Build Coastguard Worker
100*053f45beSAndroid Build Coastguard Worker	sleep 0.1
101*053f45beSAndroid Build Coastguard Worker	./udpgso_bench_tx ${tx_args}
102*053f45beSAndroid Build Coastguard Worker	ret=$?
103*053f45beSAndroid Build Coastguard Worker	kill -INT $pid
104*053f45beSAndroid Build Coastguard Worker	wait $(jobs -p)
105*053f45beSAndroid Build Coastguard Worker	return $ret
106*053f45beSAndroid Build Coastguard Worker}
107*053f45beSAndroid Build Coastguard Worker
108*053f45beSAndroid Build Coastguard Workerrun_one_2sock() {
109*053f45beSAndroid Build Coastguard Worker	# use 'rx' as separator between sender args and receiver args
110*053f45beSAndroid Build Coastguard Worker	local -r all="$@"
111*053f45beSAndroid Build Coastguard Worker	local -r tx_args=${all%rx*}
112*053f45beSAndroid Build Coastguard Worker	local -r rx_args=${all#*rx}
113*053f45beSAndroid Build Coastguard Worker
114*053f45beSAndroid Build Coastguard Worker	cfg_veth
115*053f45beSAndroid Build Coastguard Worker
116*053f45beSAndroid Build Coastguard Worker	ip netns exec "${PEER_NS}" ./udpgso_bench_rx -C 1000 -R 10 ${rx_args} -p 12345 &
117*053f45beSAndroid Build Coastguard Worker	ip netns exec "${PEER_NS}" ./udpgso_bench_rx -C 2000 -R 10 ${rx_args} && \
118*053f45beSAndroid Build Coastguard Worker		echo "ok" || \
119*053f45beSAndroid Build Coastguard Worker		echo "failed" &
120*053f45beSAndroid Build Coastguard Worker
121*053f45beSAndroid Build Coastguard Worker	# Hack: let bg programs complete the startup
122*053f45beSAndroid Build Coastguard Worker	sleep 0.2
123*053f45beSAndroid Build Coastguard Worker	./udpgso_bench_tx ${tx_args} -p 12345
124*053f45beSAndroid Build Coastguard Worker	sleep 0.1
125*053f45beSAndroid Build Coastguard Worker	# first UDP GSO socket should be closed at this point
126*053f45beSAndroid Build Coastguard Worker	./udpgso_bench_tx ${tx_args}
127*053f45beSAndroid Build Coastguard Worker	ret=$?
128*053f45beSAndroid Build Coastguard Worker	wait $(jobs -p)
129*053f45beSAndroid Build Coastguard Worker	return $ret
130*053f45beSAndroid Build Coastguard Worker}
131*053f45beSAndroid Build Coastguard Worker
132*053f45beSAndroid Build Coastguard Workerrun_nat_test() {
133*053f45beSAndroid Build Coastguard Worker	local -r args=$@
134*053f45beSAndroid Build Coastguard Worker
135*053f45beSAndroid Build Coastguard Worker	printf " %-40s" "$1"
136*053f45beSAndroid Build Coastguard Worker	./in_netns.sh $0 __subprocess_nat $2 rx -r $3
137*053f45beSAndroid Build Coastguard Worker}
138*053f45beSAndroid Build Coastguard Worker
139*053f45beSAndroid Build Coastguard Workerrun_2sock_test() {
140*053f45beSAndroid Build Coastguard Worker	local -r args=$@
141*053f45beSAndroid Build Coastguard Worker
142*053f45beSAndroid Build Coastguard Worker	printf " %-40s" "$1"
143*053f45beSAndroid Build Coastguard Worker	./in_netns.sh $0 __subprocess_2sock $2 rx -G -r $3
144*053f45beSAndroid Build Coastguard Worker}
145*053f45beSAndroid Build Coastguard Worker
146*053f45beSAndroid Build Coastguard Workerrun_all() {
147*053f45beSAndroid Build Coastguard Worker	local -r core_args="-l 4"
148*053f45beSAndroid Build Coastguard Worker	local -r ipv4_args="${core_args} -4 -D 192.168.1.1"
149*053f45beSAndroid Build Coastguard Worker	local -r ipv6_args="${core_args} -6 -D 2001:db8::1"
150*053f45beSAndroid Build Coastguard Worker	ret=0
151*053f45beSAndroid Build Coastguard Worker
152*053f45beSAndroid Build Coastguard Worker	echo "ipv4"
153*053f45beSAndroid Build Coastguard Worker	run_test "no GRO" "${ipv4_args} -M 10 -s 1400" "-4 -n 10 -l 1400"
154*053f45beSAndroid Build Coastguard Worker	check_err $?
155*053f45beSAndroid Build Coastguard Worker
156*053f45beSAndroid Build Coastguard Worker	# explicitly check we are not receiving UDP_SEGMENT cmsg (-S -1)
157*053f45beSAndroid Build Coastguard Worker	# when GRO does not take place
158*053f45beSAndroid Build Coastguard Worker	run_test "no GRO chk cmsg" "${ipv4_args} -M 10 -s 1400" "-4 -n 10 -l 1400 -S -1"
159*053f45beSAndroid Build Coastguard Worker	check_err $?
160*053f45beSAndroid Build Coastguard Worker
161*053f45beSAndroid Build Coastguard Worker	# the GSO packets are aggregated because:
162*053f45beSAndroid Build Coastguard Worker	# * veth schedule napi after each xmit
163*053f45beSAndroid Build Coastguard Worker	# * segmentation happens in BH context, veth napi poll is delayed after
164*053f45beSAndroid Build Coastguard Worker	#   the transmission of the last segment
165*053f45beSAndroid Build Coastguard Worker	run_test "GRO" "${ipv4_args} -M 1 -s 14720 -S 0 " "-4 -n 1 -l 14720"
166*053f45beSAndroid Build Coastguard Worker	check_err $?
167*053f45beSAndroid Build Coastguard Worker	run_test "GRO chk cmsg" "${ipv4_args} -M 1 -s 14720 -S 0 " "-4 -n 1 -l 14720 -S 1472"
168*053f45beSAndroid Build Coastguard Worker	check_err $?
169*053f45beSAndroid Build Coastguard Worker	run_test "GRO with custom segment size" "${ipv4_args} -M 1 -s 14720 -S 500 " "-4 -n 1 -l 14720"
170*053f45beSAndroid Build Coastguard Worker	check_err $?
171*053f45beSAndroid Build Coastguard Worker	run_test "GRO with custom segment size cmsg" "${ipv4_args} -M 1 -s 14720 -S 500 " "-4 -n 1 -l 14720 -S 500"
172*053f45beSAndroid Build Coastguard Worker	check_err $?
173*053f45beSAndroid Build Coastguard Worker
174*053f45beSAndroid Build Coastguard Worker	run_nat_test "bad GRO lookup" "${ipv4_args} -M 1 -s 14720 -S 0" "-n 10 -l 1472"
175*053f45beSAndroid Build Coastguard Worker	check_err $?
176*053f45beSAndroid Build Coastguard Worker	run_2sock_test "multiple GRO socks" "${ipv4_args} -M 1 -s 14720 -S 0 " "-4 -n 1 -l 14720 -S 1472"
177*053f45beSAndroid Build Coastguard Worker	check_err $?
178*053f45beSAndroid Build Coastguard Worker
179*053f45beSAndroid Build Coastguard Worker	echo "ipv6"
180*053f45beSAndroid Build Coastguard Worker	run_test "no GRO" "${ipv6_args} -M 10 -s 1400" "-n 10 -l 1400"
181*053f45beSAndroid Build Coastguard Worker	check_err $?
182*053f45beSAndroid Build Coastguard Worker	run_test "no GRO chk cmsg" "${ipv6_args} -M 10 -s 1400" "-n 10 -l 1400 -S -1"
183*053f45beSAndroid Build Coastguard Worker	check_err $?
184*053f45beSAndroid Build Coastguard Worker	run_test "GRO" "${ipv6_args} -M 1 -s 14520 -S 0" "-n 1 -l 14520"
185*053f45beSAndroid Build Coastguard Worker	check_err $?
186*053f45beSAndroid Build Coastguard Worker	run_test "GRO chk cmsg" "${ipv6_args} -M 1 -s 14520 -S 0" "-n 1 -l 14520 -S 1452"
187*053f45beSAndroid Build Coastguard Worker	check_err $?
188*053f45beSAndroid Build Coastguard Worker	run_test "GRO with custom segment size" "${ipv6_args} -M 1 -s 14520 -S 500" "-n 1 -l 14520"
189*053f45beSAndroid Build Coastguard Worker	check_err $?
190*053f45beSAndroid Build Coastguard Worker	run_test "GRO with custom segment size cmsg" "${ipv6_args} -M 1 -s 14520 -S 500" "-n 1 -l 14520 -S 500"
191*053f45beSAndroid Build Coastguard Worker	check_err $?
192*053f45beSAndroid Build Coastguard Worker
193*053f45beSAndroid Build Coastguard Worker	run_nat_test "bad GRO lookup" "${ipv6_args} -M 1 -s 14520 -S 0" "-n 10 -l 1452"
194*053f45beSAndroid Build Coastguard Worker	check_err $?
195*053f45beSAndroid Build Coastguard Worker	run_2sock_test "multiple GRO socks" "${ipv6_args} -M 1 -s 14520 -S 0 " "-n 1 -l 14520 -S 1452"
196*053f45beSAndroid Build Coastguard Worker	check_err $?
197*053f45beSAndroid Build Coastguard Worker	return $ret
198*053f45beSAndroid Build Coastguard Worker}
199*053f45beSAndroid Build Coastguard Worker
200*053f45beSAndroid Build Coastguard Workerif [ ! -f ${BPF_FILE} ]; then
201*053f45beSAndroid Build Coastguard Worker	echo "Missing ${BPF_FILE}. Build bpf selftest first"
202*053f45beSAndroid Build Coastguard Worker	exit -1
203*053f45beSAndroid Build Coastguard Workerfi
204*053f45beSAndroid Build Coastguard Worker
205*053f45beSAndroid Build Coastguard Workerif [[ $# -eq 0 ]]; then
206*053f45beSAndroid Build Coastguard Worker	run_all
207*053f45beSAndroid Build Coastguard Workerelif [[ $1 == "__subprocess" ]]; then
208*053f45beSAndroid Build Coastguard Worker	shift
209*053f45beSAndroid Build Coastguard Worker	run_one $@
210*053f45beSAndroid Build Coastguard Workerelif [[ $1 == "__subprocess_nat" ]]; then
211*053f45beSAndroid Build Coastguard Worker	shift
212*053f45beSAndroid Build Coastguard Worker	run_one_nat $@
213*053f45beSAndroid Build Coastguard Workerelif [[ $1 == "__subprocess_2sock" ]]; then
214*053f45beSAndroid Build Coastguard Worker	shift
215*053f45beSAndroid Build Coastguard Worker	run_one_2sock $@
216*053f45beSAndroid Build Coastguard Workerfi
217*053f45beSAndroid Build Coastguard Worker
218*053f45beSAndroid Build Coastguard Workerexit $?
219