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