1*7d157501SCoco Li#!/bin/bash 2*7d157501SCoco Li# SPDX-License-Identifier: GPL-2.0 3*7d157501SCoco Li 4*7d157501SCoco Lisource setup_loopback.sh 5*7d157501SCoco Lireadonly SERVER_MAC="aa:00:00:00:00:02" 6*7d157501SCoco Lireadonly CLIENT_MAC="aa:00:00:00:00:01" 7*7d157501SCoco Lireadonly TESTS=("data" "ack" "flags" "tcp" "ip" "large") 8*7d157501SCoco Lireadonly PROTOS=("ipv4" "ipv6") 9*7d157501SCoco Lidev="eth0" 10*7d157501SCoco Litest="all" 11*7d157501SCoco Liproto="ipv4" 12*7d157501SCoco Li 13*7d157501SCoco Lisetup_interrupt() { 14*7d157501SCoco Li # Use timer on host to trigger the network stack 15*7d157501SCoco Li # Also disable device interrupt to not depend on NIC interrupt 16*7d157501SCoco Li # Reduce test flakiness caused by unexpected interrupts 17*7d157501SCoco Li echo 100000 >"${FLUSH_PATH}" 18*7d157501SCoco Li echo 50 >"${IRQ_PATH}" 19*7d157501SCoco Li} 20*7d157501SCoco Li 21*7d157501SCoco Lisetup_ns() { 22*7d157501SCoco Li # Set up server_ns namespace and client_ns namespace 23*7d157501SCoco Li setup_macvlan_ns "${dev}" server_ns server "${SERVER_MAC}" 24*7d157501SCoco Li setup_macvlan_ns "${dev}" client_ns client "${CLIENT_MAC}" 25*7d157501SCoco Li} 26*7d157501SCoco Li 27*7d157501SCoco Licleanup_ns() { 28*7d157501SCoco Li cleanup_macvlan_ns server_ns server client_ns client 29*7d157501SCoco Li} 30*7d157501SCoco Li 31*7d157501SCoco Lisetup() { 32*7d157501SCoco Li setup_loopback_environment "${dev}" 33*7d157501SCoco Li setup_interrupt 34*7d157501SCoco Li} 35*7d157501SCoco Li 36*7d157501SCoco Licleanup() { 37*7d157501SCoco Li cleanup_loopback "${dev}" 38*7d157501SCoco Li 39*7d157501SCoco Li echo "${FLUSH_TIMEOUT}" >"${FLUSH_PATH}" 40*7d157501SCoco Li echo "${HARD_IRQS}" >"${IRQ_PATH}" 41*7d157501SCoco Li} 42*7d157501SCoco Li 43*7d157501SCoco Lirun_test() { 44*7d157501SCoco Li local server_pid=0 45*7d157501SCoco Li local exit_code=0 46*7d157501SCoco Li local protocol=$1 47*7d157501SCoco Li local test=$2 48*7d157501SCoco Li local ARGS=( "--${protocol}" "--dmac" "${SERVER_MAC}" \ 49*7d157501SCoco Li "--smac" "${CLIENT_MAC}" "--test" "${test}" "--verbose" ) 50*7d157501SCoco Li 51*7d157501SCoco Li setup_ns 52*7d157501SCoco Li # Each test is run 3 times to deflake, because given the receive timing, 53*7d157501SCoco Li # not all packets that should coalesce will be considered in the same flow 54*7d157501SCoco Li # on every try. 55*7d157501SCoco Li for tries in {1..3}; do 56*7d157501SCoco Li # Actual test starts here 57*7d157501SCoco Li ip netns exec server_ns ./gro "${ARGS[@]}" "--rx" "--iface" "server" \ 58*7d157501SCoco Li 1>>log.txt & 59*7d157501SCoco Li server_pid=$! 60*7d157501SCoco Li sleep 0.5 # to allow for socket init 61*7d157501SCoco Li ip netns exec client_ns ./gro "${ARGS[@]}" "--iface" "client" \ 62*7d157501SCoco Li 1>>log.txt 63*7d157501SCoco Li wait "${server_pid}" 64*7d157501SCoco Li exit_code=$? 65*7d157501SCoco Li if [[ "${exit_code}" -eq 0 ]]; then 66*7d157501SCoco Li break; 67*7d157501SCoco Li fi 68*7d157501SCoco Li done 69*7d157501SCoco Li cleanup_ns 70*7d157501SCoco Li echo ${exit_code} 71*7d157501SCoco Li} 72*7d157501SCoco Li 73*7d157501SCoco Lirun_all_tests() { 74*7d157501SCoco Li local failed_tests=() 75*7d157501SCoco Li for proto in "${PROTOS[@]}"; do 76*7d157501SCoco Li for test in "${TESTS[@]}"; do 77*7d157501SCoco Li echo "running test ${proto} ${test}" >&2 78*7d157501SCoco Li exit_code=$(run_test $proto $test) 79*7d157501SCoco Li if [[ "${exit_code}" -ne 0 ]]; then 80*7d157501SCoco Li failed_tests+=("${proto}_${test}") 81*7d157501SCoco Li fi; 82*7d157501SCoco Li done; 83*7d157501SCoco Li done 84*7d157501SCoco Li if [[ ${#failed_tests[@]} -ne 0 ]]; then 85*7d157501SCoco Li echo "failed tests: ${failed_tests[*]}. \ 86*7d157501SCoco Li Please see log.txt for more logs" 87*7d157501SCoco Li exit 1 88*7d157501SCoco Li else 89*7d157501SCoco Li echo "All Tests Succeeded!" 90*7d157501SCoco Li fi; 91*7d157501SCoco Li} 92*7d157501SCoco Li 93*7d157501SCoco Liusage() { 94*7d157501SCoco Li echo "Usage: $0 \ 95*7d157501SCoco Li [-i <DEV>] \ 96*7d157501SCoco Li [-t data|ack|flags|tcp|ip|large] \ 97*7d157501SCoco Li [-p <ipv4|ipv6>]" 1>&2; 98*7d157501SCoco Li exit 1; 99*7d157501SCoco Li} 100*7d157501SCoco Li 101*7d157501SCoco Liwhile getopts "i:t:p:" opt; do 102*7d157501SCoco Li case "${opt}" in 103*7d157501SCoco Li i) 104*7d157501SCoco Li dev="${OPTARG}" 105*7d157501SCoco Li ;; 106*7d157501SCoco Li t) 107*7d157501SCoco Li test="${OPTARG}" 108*7d157501SCoco Li ;; 109*7d157501SCoco Li p) 110*7d157501SCoco Li proto="${OPTARG}" 111*7d157501SCoco Li ;; 112*7d157501SCoco Li *) 113*7d157501SCoco Li usage 114*7d157501SCoco Li ;; 115*7d157501SCoco Li esac 116*7d157501SCoco Lidone 117*7d157501SCoco Li 118*7d157501SCoco Lireadonly FLUSH_PATH="/sys/class/net/${dev}/gro_flush_timeout" 119*7d157501SCoco Lireadonly IRQ_PATH="/sys/class/net/${dev}/napi_defer_hard_irqs" 120*7d157501SCoco Lireadonly FLUSH_TIMEOUT="$(< ${FLUSH_PATH})" 121*7d157501SCoco Lireadonly HARD_IRQS="$(< ${IRQ_PATH})" 122*7d157501SCoco Lisetup 123*7d157501SCoco Litrap cleanup EXIT 124*7d157501SCoco Liif [[ "${test}" == "all" ]]; then 125*7d157501SCoco Li run_all_tests 126*7d157501SCoco Lielse 127*7d157501SCoco Li run_test "${proto}" "${test}" 128*7d157501SCoco Lifi; 129