xref: /linux/tools/testing/selftests/net/msg_zerocopy.sh (revision 8be4d31cb8aaeea27bde4b7ddb26e28a89062ebf)
1#!/bin/bash
2#
3# Send data between two processes across namespaces
4# Run twice: once without and once with zerocopy
5
6set -e
7
8readonly DEV="veth0"
9readonly DUMMY_DEV="dummy0"
10readonly DEV_MTU=65535
11readonly BIN="./msg_zerocopy"
12
13readonly RAND="$(mktemp -u XXXXXX)"
14readonly NSPREFIX="ns-${RAND}"
15readonly NS1="${NSPREFIX}1"
16readonly NS2="${NSPREFIX}2"
17
18readonly LPREFIX4='192.168.1'
19readonly RPREFIX4='192.168.2'
20readonly LPREFIX6='fd'
21readonly RPREFIX6='fc'
22
23
24readonly path_sysctl_mem="net.core.optmem_max"
25
26# No arguments: automated test
27if [[ "$#" -eq "0" ]]; then
28	ret=0
29
30	$0 4 tcp -t 1 || ret=1
31	$0 6 tcp -t 1 || ret=1
32	$0 4 udp -t 1 || ret=1
33	$0 6 udp -t 1 || ret=1
34
35	[[ "$ret" == "0" ]] && echo "OK. All tests passed"
36	exit $ret
37fi
38
39# Argument parsing
40if [[ "$#" -lt "2" ]]; then
41	echo "Usage: $0 [4|6] [tcp|udp|raw|raw_hdrincl|packet|packet_dgram] <args>"
42	exit 1
43fi
44
45readonly IP="$1"
46shift
47readonly TXMODE="$1"
48shift
49readonly EXTRA_ARGS="$@"
50
51# Argument parsing: configure addresses
52if [[ "${IP}" == "4" ]]; then
53	readonly SADDR="${LPREFIX4}.1"
54	readonly DADDR="${LPREFIX4}.2"
55	readonly DUMMY_ADDR="${RPREFIX4}.1"
56	readonly DADDR_TXONLY="${RPREFIX4}.2"
57	readonly MASK="24"
58elif [[ "${IP}" == "6" ]]; then
59	readonly SADDR="${LPREFIX6}::1"
60	readonly DADDR="${LPREFIX6}::2"
61	readonly DUMMY_ADDR="${RPREFIX6}::1"
62	readonly DADDR_TXONLY="${RPREFIX6}::2"
63	readonly MASK="64"
64	readonly NODAD="nodad"
65else
66	echo "Invalid IP version ${IP}"
67	exit 1
68fi
69
70# Argument parsing: select receive mode
71#
72# This differs from send mode for
73# - packet:	use raw recv, because packet receives skb clones
74# - raw_hdrinc: use raw recv, because hdrincl is a tx-only option
75case "${TXMODE}" in
76'packet' | 'packet_dgram' | 'raw_hdrincl')
77	RXMODE='raw'
78	;;
79*)
80	RXMODE="${TXMODE}"
81	;;
82esac
83
84# Start of state changes: install cleanup handler
85
86cleanup() {
87	ip netns del "${NS2}"
88	ip netns del "${NS1}"
89}
90
91trap cleanup EXIT
92
93# Create virtual ethernet pair between network namespaces
94ip netns add "${NS1}"
95ip netns add "${NS2}"
96
97# Configure system settings
98ip netns exec "${NS1}" sysctl -w -q "${path_sysctl_mem}=1000000"
99ip netns exec "${NS2}" sysctl -w -q "${path_sysctl_mem}=1000000"
100
101ip link add "${DEV}" mtu "${DEV_MTU}" netns "${NS1}" type veth \
102  peer name "${DEV}" mtu "${DEV_MTU}" netns "${NS2}"
103
104ip link add "${DUMMY_DEV}" mtu "${DEV_MTU}" netns "${NS2}" type dummy
105
106# Bring the devices up
107ip -netns "${NS1}" link set "${DEV}" up
108ip -netns "${NS2}" link set "${DEV}" up
109ip -netns "${NS2}" link set "${DUMMY_DEV}" up
110
111# Set fixed MAC addresses on the devices
112ip -netns "${NS1}" link set dev "${DEV}" address 02:02:02:02:02:02
113ip -netns "${NS2}" link set dev "${DEV}" address 06:06:06:06:06:06
114
115# Add fixed IP addresses to the devices
116ip -netns "${NS1}" addr add "${SADDR}/${MASK}" dev "${DEV}" ${NODAD}
117ip -netns "${NS2}" addr add "${DADDR}/${MASK}" dev "${DEV}" ${NODAD}
118ip -netns "${NS2}" addr add "${DUMMY_ADDR}/${MASK}" dev "${DUMMY_DEV}" ${NODAD}
119
120ip -netns "${NS1}" route add default via "${DADDR}" dev "${DEV}"
121ip -netns "${NS2}" route add default via "${DADDR_TXONLY}" dev "${DUMMY_DEV}"
122
123ip netns exec "${NS2}" sysctl -wq net.ipv4.ip_forward=1
124ip netns exec "${NS2}" sysctl -wq net.ipv6.conf.all.forwarding=1
125
126# Optionally disable sg or csum offload to test edge cases
127# ip netns exec "${NS1}" ethtool -K "${DEV}" sg off
128
129ret=0
130
131do_test() {
132	local readonly ARGS="$1"
133
134	# tx-rx test
135	# packets queued to a local socket are copied,
136	# sender notification has SO_EE_CODE_ZEROCOPY_COPIED.
137
138	echo -e "\nipv${IP} ${TXMODE} ${ARGS} tx-rx\n"
139	ip netns exec "${NS2}" "${BIN}" "-${IP}" -i "${DEV}" -t 2 -C 2 \
140		-S "${SADDR}" -D "${DADDR}" ${ARGS} -r "${RXMODE}" &
141	sleep 0.2
142	ip netns exec "${NS1}" "${BIN}" "-${IP}" -i "${DEV}" -t 1 -C 3 \
143		-S "${SADDR}" -D "${DADDR}" ${ARGS} "${TXMODE}" -Z 0 || ret=1
144	wait
145
146	# next test is unconnected tx to dummy0, cannot exercise with tcp
147	[[ "${TXMODE}" == "tcp" ]] && return
148
149	# tx-only test: send out dummy0
150	# packets leaving the host are not copied,
151	# sender notification does not have SO_EE_CODE_ZEROCOPY_COPIED.
152
153	echo -e "\nipv${IP} ${TXMODE} ${ARGS} tx-only\n"
154	ip netns exec "${NS1}" "${BIN}" "-${IP}" -i "${DEV}" -t 1 -C 3 \
155		-S "${SADDR}" -D "${DADDR_TXONLY}" ${ARGS} "${TXMODE}" -Z 1 || ret=1
156}
157
158do_test "${EXTRA_ARGS}"
159do_test "-z ${EXTRA_ARGS}"
160
161[[ "$ret" == "0" ]] && echo "OK"
162