1#!/usr/bin/env bash 2# SPDX-License-Identifier: GPL-2.0 3# 4# Testing for IPv4 and IPv6 BIG TCP over VXLAN and GENEVE tunnels. 5 6source "$(dirname "$0")/lib.sh" 7 8SERVER_NS=$(mktemp -u server-XXXXXXXX) 9SERVER_IP4="192.168.1.1" 10SERVER_IP6="2001:db8::1:1" 11SERVER_IP4_TUN="192.168.2.1" 12SERVER_IP6_TUN="2001:db8::2:1" 13 14CLIENT_NS=$(mktemp -u client-XXXXXXXX) 15CLIENT_IP4="192.168.1.2" 16CLIENT_IP6="2001:db8::1:2" 17CLIENT_IP4_TUN="192.168.2.2" 18CLIENT_IP6_TUN="2001:db8::2:2" 19 20# Kselftest framework requirement - SKIP code is 4. 21ksft_skip=4 22 23if [ -z "$PACKETS_THRESHOLD" ]; then 24 if [ "$KSFT_MACHINE_SLOW" = yes ]; then 25 echo 'Debug kernel detected, lowering the default threshold' 26 PACKETS_THRESHOLD=100 27 else 28 PACKETS_THRESHOLD=1000 29 fi 30fi 31 32setup() { 33 ip netns add "$SERVER_NS" 34 ip netns add "$CLIENT_NS" 35 ip -netns "$SERVER_NS" link add link1 type veth peer name link0 netns "$CLIENT_NS" 36 37 ip -netns "$CLIENT_NS" link set link0 up 38 ip -netns "$CLIENT_NS" addr replace "$CLIENT_IP4/24" dev link0 39 ip -netns "$CLIENT_NS" addr replace "$CLIENT_IP6/112" dev link0 nodad 40 ip -netns "$CLIENT_NS" link set link0 \ 41 gso_max_size 196608 gso_ipv4_max_size 196608 \ 42 gro_max_size 196608 gro_ipv4_max_size 196608 43 ip -netns "$SERVER_NS" link set link1 up 44 ip -netns "$SERVER_NS" addr replace "$SERVER_IP4/24" dev link1 45 ip -netns "$SERVER_NS" addr replace "$SERVER_IP6/112" dev link1 nodad 46 ip -netns "$SERVER_NS" link set link1 \ 47 gso_max_size 196608 gso_ipv4_max_size 196608 \ 48 gro_max_size 196608 gro_ipv4_max_size 196608 49 50 ip netns exec "$SERVER_NS" netserver >/dev/null 51 wait_local_port_listen "$SERVER_NS" 12865 tcp 52 53 DEFAULT_TCP_MIN_TSO_SEGS=$(ip netns exec "$CLIENT_NS" sysctl -n net.ipv4.tcp_min_tso_segs) 54} 55 56setup_tunnel() { 57 if [ "$2" = 4 ]; then 58 SERVER_IP="$SERVER_IP4" 59 CLIENT_IP="$CLIENT_IP4" 60 echo "Setting up ${1^^} over IPv4, veth tx csum offload $3" 61 else 62 SERVER_IP="$SERVER_IP6" 63 CLIENT_IP="$CLIENT_IP6" 64 echo "Setting up ${1^^} over IPv6, veth tx csum offload $3" 65 fi 66 67 if [ "$1" = vxlan ]; then 68 ip -netns "$CLIENT_NS" link add tun0 type vxlan \ 69 id 5001 remote "$SERVER_IP" local "$CLIENT_IP" dev link0 dstport 4789 70 else 71 ip -netns "$CLIENT_NS" link add tun0 type geneve \ 72 id 5001 remote "$SERVER_IP" 73 fi 74 ip -netns "$CLIENT_NS" link set tun0 up 75 ip -netns "$CLIENT_NS" addr replace "$CLIENT_IP4_TUN/24" dev tun0 76 ip -netns "$CLIENT_NS" addr replace "$CLIENT_IP6_TUN/112" dev tun0 nodad 77 ip -netns "$CLIENT_NS" link set tun0 \ 78 gso_max_size 196608 gso_ipv4_max_size 196608 \ 79 gro_max_size 196608 gro_ipv4_max_size 196608 80 if [ "$1" = vxlan ]; then 81 ip -netns "$SERVER_NS" link add tun1 type vxlan \ 82 id 5001 remote "$CLIENT_IP" local "$SERVER_IP" dev link1 dstport 4789 83 else 84 ip -netns "$SERVER_NS" link add tun1 type geneve \ 85 id 5001 remote "$CLIENT_IP" 86 fi 87 ip -netns "$SERVER_NS" link set tun1 up 88 ip -netns "$SERVER_NS" addr replace "$SERVER_IP4_TUN/24" dev tun1 89 ip -netns "$SERVER_NS" addr replace "$SERVER_IP6_TUN/112" dev tun1 nodad 90 ip -netns "$SERVER_NS" link set tun1 \ 91 gso_max_size 196608 gso_ipv4_max_size 196608 \ 92 gro_max_size 196608 gro_ipv4_max_size 196608 93 94 ip netns exec "$CLIENT_NS" ethtool -K link0 tx-checksumming "$3" > /dev/null 95 ip netns exec "$SERVER_NS" ethtool -K link1 tx-checksumming "$3" > /dev/null 96} 97 98cleanup_tunnel() { 99 ip -netns "$CLIENT_NS" link del tun0 100 ip -netns "$SERVER_NS" link del tun1 101} 102 103cleanup() { 104 ip netns pids "$SERVER_NS" | xargs -r kill 105 ip netns pids "$CLIENT_NS" | xargs -r kill 106 ip netns del "$SERVER_NS" 107 ip netns del "$CLIENT_NS" 108 rm -rf "$WORKDIR" 109} 110 111do_test() { 112 local packets_threshold="$PACKETS_THRESHOLD" 113 114 # When tx csum offload is off, software GSO is performed before passing the 115 # packet to veth. Check BIG TCP packets inside the VXLAN tunnel to verify 116 # the software checksum path: if the checksum code is broken, these packets 117 # will be dropped. 118 if [ "$3" = on ]; then 119 CAPTURE_IFACE='link' 120 if [ "$1" = 4 ]; then 121 IPTABLES=iptables 122 else 123 IPTABLES=ip6tables 124 fi 125 else 126 CAPTURE_IFACE='tun' 127 if [ "$2" = 4 ]; then 128 IPTABLES=iptables 129 else 130 IPTABLES=ip6tables 131 fi 132 packets_threshold=$(( PACKETS_THRESHOLD / 10 )) 133 fi 134 if [ "$2" = 4 ]; then 135 IPTABLES_SACK=iptables 136 else 137 IPTABLES_SACK=ip6tables 138 fi 139 140 if [ "$3" != 'on' ] && [ "$KSFT_MACHINE_SLOW" = yes ]; then 141 echo 'Slow configuration; increasing net.ipv4.tcp_min_tso_segs and initcwnd' 142 ip netns exec "$CLIENT_NS" sysctl -w net.ipv4.tcp_min_tso_segs=52 143 if [ "$2" = 4 ]; then 144 ip -netns "$CLIENT_NS" \ 145 route change 192.168.2.0/24 dev tun0 initcwnd 100 146 else 147 ip -netns "$CLIENT_NS" -6 \ 148 route change 2001:db8::2:0/112 dev tun0 initcwnd 100 149 fi 150 else 151 ip netns exec "$CLIENT_NS" \ 152 sysctl -w net.ipv4.tcp_min_tso_segs="$DEFAULT_TCP_MIN_TSO_SEGS" 153 fi 154 155 ip netns exec "$SERVER_NS" "$IPTABLES" -w -t raw -I PREROUTING -i "${CAPTURE_IFACE}1" -m length ! --length 0:65535 -m comment --comment "bigtcp" 156 ip netns exec "$CLIENT_NS" "$IPTABLES" -w -t raw -I OUTPUT -o "${CAPTURE_IFACE}0" -m length ! --length 0:65535 -m comment --comment "bigtcp" 157 ip netns exec "$SERVER_NS" "$IPTABLES_SACK" -w -t raw -I OUTPUT -o "tun1" -p tcp -m tcp --tcp-flags ACK ACK --tcp-option 5 -m comment --comment "sack" 158 159 if [ "$2" = 4 ]; then 160 SERVER_IP="$SERVER_IP4_TUN" 161 echo "Running IPv4 traffic in the tunnel" 162 else 163 SERVER_IP="$SERVER_IP6_TUN" 164 echo "Running IPv6 traffic in the tunnel" 165 fi 166 167 ip netns exec "$CLIENT_NS" netperf -t TCP_STREAM -l 5 -H "$SERVER_IP" -- \ 168 -m 80000 > /dev/null 169 170 PACKETS_SERVER=$(ip netns exec "$SERVER_NS" "$IPTABLES-save" -c -t raw | sed -rn '/ --comment bigtcp/{s/^\[([0-9]+):.*/\1/p;q}') 171 PACKETS_CLIENT=$(ip netns exec "$CLIENT_NS" "$IPTABLES-save" -c -t raw | sed -rn '/ --comment bigtcp/{s/^\[([0-9]+):.*/\1/p;q}') 172 PACKETS_SACK=$(ip netns exec "$SERVER_NS" "$IPTABLES_SACK-save" -c -t raw | sed -rn '/ --comment sack/{s/^\[([0-9]+):.*/\1/p;q}') 173 ip netns exec "$SERVER_NS" "$IPTABLES" -w -t raw -D PREROUTING -i "${CAPTURE_IFACE}1" -m length ! --length 0:65535 -m comment --comment "bigtcp" 174 ip netns exec "$CLIENT_NS" "$IPTABLES" -w -t raw -D OUTPUT -o "${CAPTURE_IFACE}0" -m length ! --length 0:65535 -m comment --comment "bigtcp" 175 ip netns exec "$SERVER_NS" "$IPTABLES_SACK" -w -t raw -D OUTPUT -o "tun1" -p tcp -m tcp --tcp-flags ACK ACK --tcp-option 5 -m comment --comment "sack" 176 177 echo "Captured BIG TCP RX packets: $PACKETS_SERVER" 178 echo "Captured BIG TCP TX packets: $PACKETS_CLIENT" 179 echo "Captured TCP SACK packets: $PACKETS_SACK" 180 [ "$PACKETS_SERVER" -gt "$packets_threshold" ] || return 1 181 [ "$PACKETS_CLIENT" -gt "$packets_threshold" ] || return 1 182 [ "$PACKETS_SACK" -lt "$(( PACKETS_CLIENT / 2 ))" ] || return 1 183} 184 185if ! netperf -V &> /dev/null; then 186 echo "SKIP: Could not run test without netperf tool" 187 exit "$ksft_skip" 188fi 189 190if ! iptables --version &> /dev/null; then 191 echo "SKIP: Could not run test without iptables tool" 192 exit "$ksft_skip" 193fi 194 195if ! ethtool --version &> /dev/null; then 196 echo "SKIP: Could not run test without ethtool tool" 197 exit "$ksft_skip" 198fi 199 200if ! ip link help 2>&1 | grep gso_ipv4_max_size &> /dev/null; then 201 echo "SKIP: Could not run test without gso/gro_ipv4_max_size supported in ip-link" 202 exit "$ksft_skip" 203fi 204 205WORKDIR=$(mktemp -d) 206trap cleanup EXIT 207setup 208for tunnel in vxlan geneve; do 209 for tun_family in 4 6; do 210 for traffic_family in 4 6; do 211 for csum_offload in on off; do 212 setup_tunnel "$tunnel" "$tun_family" "$csum_offload" || exit "$?" 213 do_test "$tun_family" "$traffic_family" "$csum_offload" || exit "$?" 214 cleanup_tunnel 215 done 216 done 217 done 218done 219