161 lines · 4.2 KB · Shell
RawDownload
#!/bin/bash## Send data between two processes across namespaces# Run twice: once without and once with zerocopy set -e readonly DEV="veth0"readonly DUMMY_DEV="dummy0"readonly DEV_MTU=65535readonly BIN="./msg_zerocopy" readonly RAND="$(mktemp -u XXXXXX)"readonly NSPREFIX="ns-${RAND}"readonly NS1="${NSPREFIX}1"readonly NS2="${NSPREFIX}2" readonly LPREFIX4='192.168.1'readonly RPREFIX4='192.168.2'readonly LPREFIX6='fd'readonly RPREFIX6='fc'  readonly path_sysctl_mem="net.core.optmem_max" # No arguments: automated testif [[ "$#" -eq "0" ]]; then	ret=0 	$0 4 tcp -t 1 || ret=1	$0 6 tcp -t 1 || ret=1	$0 4 udp -t 1 || ret=1	$0 6 udp -t 1 || ret=1 	[[ "$ret" == "0" ]] && echo "OK. All tests passed"	exit $retfi # Argument parsingif [[ "$#" -lt "2" ]]; then	echo "Usage: $0 [4|6] [tcp|udp|raw|raw_hdrincl|packet|packet_dgram] <args>"	exit 1fi readonly IP="$1"shiftreadonly TXMODE="$1"shiftreadonly EXTRA_ARGS="$@" # Argument parsing: configure addressesif [[ "${IP}" == "4" ]]; then	readonly SADDR="${LPREFIX4}.1"	readonly DADDR="${LPREFIX4}.2"	readonly DUMMY_ADDR="${RPREFIX4}.1"	readonly DADDR_TXONLY="${RPREFIX4}.2"	readonly MASK="24"elif [[ "${IP}" == "6" ]]; then	readonly SADDR="${LPREFIX6}::1"	readonly DADDR="${LPREFIX6}::2"	readonly DUMMY_ADDR="${RPREFIX6}::1"	readonly DADDR_TXONLY="${RPREFIX6}::2"	readonly MASK="64"	readonly NODAD="nodad"else	echo "Invalid IP version ${IP}"	exit 1fi # 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 optioncase "${TXMODE}" in'packet' | 'packet_dgram' | 'raw_hdrincl')	RXMODE='raw'	;;*)	RXMODE="${TXMODE}"	;;esac # Start of state changes: install cleanup handler cleanup() {	ip netns del "${NS2}"	ip netns del "${NS1}"} trap cleanup EXIT # Create virtual ethernet pair between network namespacesip netns add "${NS1}"ip netns add "${NS2}" # Configure system settingsip netns exec "${NS1}" sysctl -w -q "${path_sysctl_mem}=1000000"ip netns exec "${NS2}" sysctl -w -q "${path_sysctl_mem}=1000000" ip link add "${DEV}" mtu "${DEV_MTU}" netns "${NS1}" type veth \  peer name "${DEV}" mtu "${DEV_MTU}" netns "${NS2}" ip link add "${DUMMY_DEV}" mtu "${DEV_MTU}" netns "${NS2}" type dummy # Bring the devices upip -netns "${NS1}" link set "${DEV}" upip -netns "${NS2}" link set "${DEV}" upip -netns "${NS2}" link set "${DUMMY_DEV}" up # Set fixed MAC addresses on the devicesip -netns "${NS1}" link set dev "${DEV}" address 02:02:02:02:02:02ip -netns "${NS2}" link set dev "${DEV}" address 06:06:06:06:06:06 # Add fixed IP addresses to the devicesip -netns "${NS1}" addr add "${SADDR}/${MASK}" dev "${DEV}" ${NODAD}ip -netns "${NS2}" addr add "${DADDR}/${MASK}" dev "${DEV}" ${NODAD}ip -netns "${NS2}" addr add "${DUMMY_ADDR}/${MASK}" dev "${DUMMY_DEV}" ${NODAD} ip -netns "${NS1}" route add default via "${DADDR}" dev "${DEV}"ip -netns "${NS2}" route add default via "${DADDR_TXONLY}" dev "${DUMMY_DEV}" ip netns exec "${NS2}" sysctl -wq net.ipv4.ip_forward=1ip netns exec "${NS2}" sysctl -wq net.ipv6.conf.all.forwarding=1 # Optionally disable sg or csum offload to test edge cases# ip netns exec "${NS1}" ethtool -K "${DEV}" sg off ret=0 do_test() {	local readonly ARGS="$1" 	# tx-rx test	# packets queued to a local socket are copied,	# sender notification has SO_EE_CODE_ZEROCOPY_COPIED. 	echo -e "\nipv${IP} ${TXMODE} ${ARGS} tx-rx\n"	ip netns exec "${NS2}" "${BIN}" "-${IP}" -i "${DEV}" -t 2 -C 2 \		-S "${SADDR}" -D "${DADDR}" ${ARGS} -r "${RXMODE}" &	sleep 0.2	ip netns exec "${NS1}" "${BIN}" "-${IP}" -i "${DEV}" -t 1 -C 3 \		-S "${SADDR}" -D "${DADDR}" ${ARGS} "${TXMODE}" -Z 0 || ret=1	wait 	# next test is unconnected tx to dummy0, cannot exercise with tcp	[[ "${TXMODE}" == "tcp" ]] && return 	# tx-only test: send out dummy0	# packets leaving the host are not copied,	# sender notification does not have SO_EE_CODE_ZEROCOPY_COPIED. 	echo -e "\nipv${IP} ${TXMODE} ${ARGS} tx-only\n"	ip netns exec "${NS1}" "${BIN}" "-${IP}" -i "${DEV}" -t 1 -C 3 \		-S "${SADDR}" -D "${DADDR_TXONLY}" ${ARGS} "${TXMODE}" -Z 1 || ret=1} do_test "${EXTRA_ARGS}"do_test "-z ${EXTRA_ARGS}" [[ "$ret" == "0" ]] && echo "OK"