aboutsummaryrefslogtreecommitdiffstats
path: root/tools/testing/selftests/net/io_uring_zerocopy_tx.sh
blob: 6a65e44376408b09c3c634d6d35c680549ac3331 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
#!/bin/bash
#
# Send data between two processes across namespaces
# Run twice: once without and once with zerocopy

set -e

readonly DEV="veth0"
readonly DEV_MTU=65535
readonly BIN_TX="./io_uring_zerocopy_tx"
readonly BIN_RX="./msg_zerocopy"

readonly RAND="$(mktemp -u XXXXXX)"
readonly NSPREFIX="ns-${RAND}"
readonly NS1="${NSPREFIX}1"
readonly NS2="${NSPREFIX}2"

readonly SADDR4='192.168.1.1'
readonly DADDR4='192.168.1.2'
readonly SADDR6='fd::1'
readonly DADDR6='fd::2'

readonly path_sysctl_mem="net.core.optmem_max"

# No arguments: automated test
if [[ "$#" -eq "0" ]]; then
	IPs=( "4" "6" )
	protocols=( "tcp" "udp" )

	for IP in "${IPs[@]}"; do
		for proto in "${protocols[@]}"; do
			for mode in $(seq 1 3); do
				$0 "$IP" "$proto" -m "$mode" -t 1 -n 32
				$0 "$IP" "$proto" -m "$mode" -t 1 -n 32 -f
				$0 "$IP" "$proto" -m "$mode" -t 1 -n 32 -c -f
			done
		done
	done

	echo "OK. All tests passed"
	exit 0
fi

# Argument parsing
if [[ "$#" -lt "2" ]]; then
	echo "Usage: $0 [4|6] [tcp|udp|raw|raw_hdrincl|packet|packet_dgram] <args>"
	exit 1
fi

readonly IP="$1"
shift
readonly TXMODE="$1"
shift
readonly EXTRA_ARGS="$@"

# Argument parsing: configure addresses
if [[ "${IP}" == "4" ]]; then
	readonly SADDR="${SADDR4}"
	readonly DADDR="${DADDR4}"
elif [[ "${IP}" == "6" ]]; then
	readonly SADDR="${SADDR6}"
	readonly DADDR="${DADDR6}"
else
	echo "Invalid IP version ${IP}"
	exit 1
fi

# Argument parsing: select receive mode
#
# This differs from send mode for
# - packet:	use raw recv, because packet receives skb clones
# - raw_hdrinc: use raw recv, because hdrincl is a tx-only option
case "${TXMODE}" in
'packet' | 'packet_dgram' | 'raw_hdrincl')
	RXMODE='raw'
	;;
*)
	RXMODE="${TXMODE}"
	;;
esac

# Start of state changes: install cleanup handler
save_sysctl_mem="$(sysctl -n ${path_sysctl_mem})"

cleanup() {
	ip netns del "${NS2}"
	ip netns del "${NS1}"
	sysctl -w -q "${path_sysctl_mem}=${save_sysctl_mem}"
}

trap cleanup EXIT

# Configure system settings
sysctl -w -q "${path_sysctl_mem}=1000000"

# Create virtual ethernet pair between network namespaces
ip netns add "${NS1}"
ip netns add "${NS2}"

ip link add "${DEV}" mtu "${DEV_MTU}" netns "${NS1}" type veth \
  peer name "${DEV}" mtu "${DEV_MTU}" netns "${NS2}"

# Bring the devices up
ip -netns "${NS1}" link set "${DEV}" up
ip -netns "${NS2}" link set "${DEV}" up

# Set fixed MAC addresses on the devices
ip -netns "${NS1}" link set dev "${DEV}" address 02:02:02:02:02:02
ip -netns "${NS2}" link set dev "${DEV}" address 06:06:06:06:06:06

# Add fixed IP addresses to the devices
ip -netns "${NS1}" addr add 192.168.1.1/24 dev "${DEV}"
ip -netns "${NS2}" addr add 192.168.1.2/24 dev "${DEV}"
ip -netns "${NS1}" addr add       fd::1/64 dev "${DEV}" nodad
ip -netns "${NS2}" addr add       fd::2/64 dev "${DEV}" nodad

# Optionally disable sg or csum offload to test edge cases
# ip netns exec "${NS1}" ethtool -K "${DEV}" sg off

do_test() {
	local readonly ARGS="$1"

	echo "ipv${IP} ${TXMODE} ${ARGS}"
	ip netns exec "${NS2}" "${BIN_RX}" "-${IP}" -t 2 -C 2 -S "${SADDR}" -D "${DADDR}" -r "${RXMODE}" &
	sleep 0.2
	ip netns exec "${NS1}" "${BIN_TX}" "-${IP}" -t 1 -D "${DADDR}" ${ARGS} "${TXMODE}"
	wait
}

do_test "${EXTRA_ARGS}"
echo ok