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