|
| 1 | +#!/bin/bash |
| 2 | +# SPDX-License-Identifier: GPL-2.0 |
| 3 | +# |
| 4 | +# Run a series of udpgro functional tests. |
| 5 | + |
| 6 | +readonly PEER_NS="ns-peer-$(mktemp -u XXXXXX)" |
| 7 | + |
| 8 | +cleanup() { |
| 9 | + local -r jobs="$(jobs -p)" |
| 10 | + local -r ns="$(ip netns list|grep $PEER_NS)" |
| 11 | + |
| 12 | + [ -n "${jobs}" ] && kill -1 ${jobs} 2>/dev/null |
| 13 | + [ -n "$ns" ] && ip netns del $ns 2>/dev/null |
| 14 | +} |
| 15 | +trap cleanup EXIT |
| 16 | + |
| 17 | +cfg_veth() { |
| 18 | + ip netns add "${PEER_NS}" |
| 19 | + ip -netns "${PEER_NS}" link set lo up |
| 20 | + ip link add type veth |
| 21 | + ip link set dev veth0 up |
| 22 | + ip addr add dev veth0 192.168.1.2/24 |
| 23 | + ip addr add dev veth0 2001:db8::2/64 nodad |
| 24 | + |
| 25 | + ip link set dev veth1 netns "${PEER_NS}" |
| 26 | + ip -netns "${PEER_NS}" addr add dev veth1 192.168.1.1/24 |
| 27 | + ip -netns "${PEER_NS}" addr add dev veth1 2001:db8::1/64 nodad |
| 28 | + ip -netns "${PEER_NS}" link set dev veth1 up |
| 29 | + ip -n "${PEER_NS}" link set veth1 xdp object ../bpf/xdp_dummy.o section xdp_dummy |
| 30 | +} |
| 31 | + |
| 32 | +run_one() { |
| 33 | + # use 'rx' as separator between sender args and receiver args |
| 34 | + local -r all="$@" |
| 35 | + local -r tx_args=${all%rx*} |
| 36 | + local -r rx_args=${all#*rx} |
| 37 | + |
| 38 | + cfg_veth |
| 39 | + |
| 40 | + ip netns exec "${PEER_NS}" ./udpgso_bench_rx ${rx_args} && \ |
| 41 | + echo "ok" || \ |
| 42 | + echo "failed" & |
| 43 | + |
| 44 | + # Hack: let bg programs complete the startup |
| 45 | + sleep 0.1 |
| 46 | + ./udpgso_bench_tx ${tx_args} |
| 47 | + wait $(jobs -p) |
| 48 | +} |
| 49 | + |
| 50 | +run_test() { |
| 51 | + local -r args=$@ |
| 52 | + |
| 53 | + printf " %-40s" "$1" |
| 54 | + ./in_netns.sh $0 __subprocess $2 rx -G -r $3 |
| 55 | +} |
| 56 | + |
| 57 | +run_one_nat() { |
| 58 | + # use 'rx' as separator between sender args and receiver args |
| 59 | + local addr1 addr2 pid family="" ipt_cmd=ip6tables |
| 60 | + local -r all="$@" |
| 61 | + local -r tx_args=${all%rx*} |
| 62 | + local -r rx_args=${all#*rx} |
| 63 | + |
| 64 | + if [[ ${tx_args} = *-4* ]]; then |
| 65 | + ipt_cmd=iptables |
| 66 | + family=-4 |
| 67 | + addr1=192.168.1.1 |
| 68 | + addr2=192.168.1.3/24 |
| 69 | + else |
| 70 | + addr1=2001:db8::1 |
| 71 | + addr2="2001:db8::3/64 nodad" |
| 72 | + fi |
| 73 | + |
| 74 | + cfg_veth |
| 75 | + ip -netns "${PEER_NS}" addr add dev veth1 ${addr2} |
| 76 | + |
| 77 | + # fool the GRO engine changing the destination address ... |
| 78 | + ip netns exec "${PEER_NS}" $ipt_cmd -t nat -I PREROUTING -d ${addr1} -j DNAT --to-destination ${addr2%/*} |
| 79 | + |
| 80 | + # ... so that GRO will match the UDP_GRO enabled socket, but packets |
| 81 | + # will land on the 'plain' one |
| 82 | + ip netns exec "${PEER_NS}" ./udpgso_bench_rx -G ${family} -b ${addr1} -n 0 & |
| 83 | + pid=$! |
| 84 | + ip netns exec "${PEER_NS}" ./udpgso_bench_rx ${family} -b ${addr2%/*} ${rx_args} && \ |
| 85 | + echo "ok" || \ |
| 86 | + echo "failed"& |
| 87 | + |
| 88 | + sleep 0.1 |
| 89 | + ./udpgso_bench_tx ${tx_args} |
| 90 | + kill -INT $pid |
| 91 | + wait $(jobs -p) |
| 92 | +} |
| 93 | + |
| 94 | +run_nat_test() { |
| 95 | + local -r args=$@ |
| 96 | + |
| 97 | + printf " %-40s" "$1" |
| 98 | + ./in_netns.sh $0 __subprocess_nat $2 rx -r $3 |
| 99 | +} |
| 100 | + |
| 101 | +run_all() { |
| 102 | + local -r core_args="-l 4" |
| 103 | + local -r ipv4_args="${core_args} -4 -D 192.168.1.1" |
| 104 | + local -r ipv6_args="${core_args} -6 -D 2001:db8::1" |
| 105 | + |
| 106 | + echo "ipv4" |
| 107 | + run_test "no GRO" "${ipv4_args} -M 10 -s 1400" "-4 -n 10 -l 1400" |
| 108 | + |
| 109 | + # explicitly check we are not receiving UDP_SEGMENT cmsg (-S -1) |
| 110 | + # when GRO does not take place |
| 111 | + run_test "no GRO chk cmsg" "${ipv4_args} -M 10 -s 1400" "-4 -n 10 -l 1400 -S -1" |
| 112 | + |
| 113 | + # the GSO packets are aggregated because: |
| 114 | + # * veth schedule napi after each xmit |
| 115 | + # * segmentation happens in BH context, veth napi poll is delayed after |
| 116 | + # the transmission of the last segment |
| 117 | + run_test "GRO" "${ipv4_args} -M 1 -s 14720 -S 0 " "-4 -n 1 -l 14720" |
| 118 | + run_test "GRO chk cmsg" "${ipv4_args} -M 1 -s 14720 -S 0 " "-4 -n 1 -l 14720 -S 1472" |
| 119 | + run_test "GRO with custom segment size" "${ipv4_args} -M 1 -s 14720 -S 500 " "-4 -n 1 -l 14720" |
| 120 | + run_test "GRO with custom segment size cmsg" "${ipv4_args} -M 1 -s 14720 -S 500 " "-4 -n 1 -l 14720 -S 500" |
| 121 | + |
| 122 | + run_nat_test "bad GRO lookup" "${ipv4_args} -M 1 -s 14720 -S 0" "-n 10 -l 1472" |
| 123 | + |
| 124 | + echo "ipv6" |
| 125 | + run_test "no GRO" "${ipv6_args} -M 10 -s 1400" "-n 10 -l 1400" |
| 126 | + run_test "no GRO chk cmsg" "${ipv6_args} -M 10 -s 1400" "-n 10 -l 1400 -S -1" |
| 127 | + run_test "GRO" "${ipv6_args} -M 1 -s 14520 -S 0" "-n 1 -l 14520" |
| 128 | + run_test "GRO chk cmsg" "${ipv6_args} -M 1 -s 14520 -S 0" "-n 1 -l 14520 -S 1452" |
| 129 | + run_test "GRO with custom segment size" "${ipv6_args} -M 1 -s 14520 -S 500" "-n 1 -l 14520" |
| 130 | + run_test "GRO with custom segment size cmsg" "${ipv6_args} -M 1 -s 14520 -S 500" "-n 1 -l 14520 -S 500" |
| 131 | + |
| 132 | + run_nat_test "bad GRO lookup" "${ipv6_args} -M 1 -s 14520 -S 0" "-n 10 -l 1452" |
| 133 | +} |
| 134 | + |
| 135 | +if [ ! -f ../bpf/xdp_dummy.o ]; then |
| 136 | + echo "Missing xdp_dummy helper. Build bpf selftest first" |
| 137 | + exit -1 |
| 138 | +fi |
| 139 | + |
| 140 | +if [[ $# -eq 0 ]]; then |
| 141 | + run_all |
| 142 | +elif [[ $1 == "__subprocess" ]]; then |
| 143 | + shift |
| 144 | + run_one $@ |
| 145 | +elif [[ $1 == "__subprocess_nat" ]]; then |
| 146 | + shift |
| 147 | + run_one_nat $@ |
| 148 | +fi |
0 commit comments