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