David Brazdil | 0f672f6 | 2019-12-10 10:32:29 +0000 | [diff] [blame^] | 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 -C 1000 -R 10 ${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 -C 1000 -R 10 ${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_one_2sock() { |
| 95 | # use 'rx' as separator between sender args and receiver args |
| 96 | local -r all="$@" |
| 97 | local -r tx_args=${all%rx*} |
| 98 | local -r rx_args=${all#*rx} |
| 99 | |
| 100 | cfg_veth |
| 101 | |
| 102 | ip netns exec "${PEER_NS}" ./udpgso_bench_rx -C 1000 -R 10 ${rx_args} -p 12345 & |
| 103 | ip netns exec "${PEER_NS}" ./udpgso_bench_rx -C 2000 -R 10 ${rx_args} && \ |
| 104 | echo "ok" || \ |
| 105 | echo "failed" & |
| 106 | |
| 107 | # Hack: let bg programs complete the startup |
| 108 | sleep 0.1 |
| 109 | ./udpgso_bench_tx ${tx_args} -p 12345 |
| 110 | sleep 0.1 |
| 111 | # first UDP GSO socket should be closed at this point |
| 112 | ./udpgso_bench_tx ${tx_args} |
| 113 | wait $(jobs -p) |
| 114 | } |
| 115 | |
| 116 | run_nat_test() { |
| 117 | local -r args=$@ |
| 118 | |
| 119 | printf " %-40s" "$1" |
| 120 | ./in_netns.sh $0 __subprocess_nat $2 rx -r $3 |
| 121 | } |
| 122 | |
| 123 | run_2sock_test() { |
| 124 | local -r args=$@ |
| 125 | |
| 126 | printf " %-40s" "$1" |
| 127 | ./in_netns.sh $0 __subprocess_2sock $2 rx -G -r $3 |
| 128 | } |
| 129 | |
| 130 | run_all() { |
| 131 | local -r core_args="-l 4" |
| 132 | local -r ipv4_args="${core_args} -4 -D 192.168.1.1" |
| 133 | local -r ipv6_args="${core_args} -6 -D 2001:db8::1" |
| 134 | |
| 135 | echo "ipv4" |
| 136 | run_test "no GRO" "${ipv4_args} -M 10 -s 1400" "-4 -n 10 -l 1400" |
| 137 | |
| 138 | # explicitly check we are not receiving UDP_SEGMENT cmsg (-S -1) |
| 139 | # when GRO does not take place |
| 140 | run_test "no GRO chk cmsg" "${ipv4_args} -M 10 -s 1400" "-4 -n 10 -l 1400 -S -1" |
| 141 | |
| 142 | # the GSO packets are aggregated because: |
| 143 | # * veth schedule napi after each xmit |
| 144 | # * segmentation happens in BH context, veth napi poll is delayed after |
| 145 | # the transmission of the last segment |
| 146 | run_test "GRO" "${ipv4_args} -M 1 -s 14720 -S 0 " "-4 -n 1 -l 14720" |
| 147 | run_test "GRO chk cmsg" "${ipv4_args} -M 1 -s 14720 -S 0 " "-4 -n 1 -l 14720 -S 1472" |
| 148 | run_test "GRO with custom segment size" "${ipv4_args} -M 1 -s 14720 -S 500 " "-4 -n 1 -l 14720" |
| 149 | run_test "GRO with custom segment size cmsg" "${ipv4_args} -M 1 -s 14720 -S 500 " "-4 -n 1 -l 14720 -S 500" |
| 150 | |
| 151 | run_nat_test "bad GRO lookup" "${ipv4_args} -M 1 -s 14720 -S 0" "-n 10 -l 1472" |
| 152 | run_2sock_test "multiple GRO socks" "${ipv4_args} -M 1 -s 14720 -S 0 " "-4 -n 1 -l 14720 -S 1472" |
| 153 | |
| 154 | echo "ipv6" |
| 155 | run_test "no GRO" "${ipv6_args} -M 10 -s 1400" "-n 10 -l 1400" |
| 156 | run_test "no GRO chk cmsg" "${ipv6_args} -M 10 -s 1400" "-n 10 -l 1400 -S -1" |
| 157 | run_test "GRO" "${ipv6_args} -M 1 -s 14520 -S 0" "-n 1 -l 14520" |
| 158 | run_test "GRO chk cmsg" "${ipv6_args} -M 1 -s 14520 -S 0" "-n 1 -l 14520 -S 1452" |
| 159 | run_test "GRO with custom segment size" "${ipv6_args} -M 1 -s 14520 -S 500" "-n 1 -l 14520" |
| 160 | run_test "GRO with custom segment size cmsg" "${ipv6_args} -M 1 -s 14520 -S 500" "-n 1 -l 14520 -S 500" |
| 161 | |
| 162 | run_nat_test "bad GRO lookup" "${ipv6_args} -M 1 -s 14520 -S 0" "-n 10 -l 1452" |
| 163 | run_2sock_test "multiple GRO socks" "${ipv6_args} -M 1 -s 14520 -S 0 " "-n 1 -l 14520 -S 1452" |
| 164 | } |
| 165 | |
| 166 | if [ ! -f ../bpf/xdp_dummy.o ]; then |
| 167 | echo "Missing xdp_dummy helper. Build bpf selftest first" |
| 168 | exit -1 |
| 169 | fi |
| 170 | |
| 171 | if [[ $# -eq 0 ]]; then |
| 172 | run_all |
| 173 | elif [[ $1 == "__subprocess" ]]; then |
| 174 | shift |
| 175 | run_one $@ |
| 176 | elif [[ $1 == "__subprocess_nat" ]]; then |
| 177 | shift |
| 178 | run_one_nat $@ |
| 179 | elif [[ $1 == "__subprocess_2sock" ]]; then |
| 180 | shift |
| 181 | run_one_2sock $@ |
| 182 | fi |