#!/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] " 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