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