Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
1#!/bin/bash
2# SPDX-License-Identifier: GPL-2.0
3#shellcheck disable=SC2034 # SC does not see the global variables
4#shellcheck disable=SC2317,SC2329 # unused functions
5
6ALL_TESTS="
7 rmon_rx_histogram
8 rmon_tx_histogram
9"
10
11: "${DRIVER_TEST_CONFORMANT:=yes}"
12NUM_NETIFS=2
13lib_dir=$(dirname "$0")
14source "$lib_dir"/../../../net/forwarding/lib.sh
15source "$lib_dir"/../../../kselftest/ktap_helpers.sh
16
17UINT32_MAX=$((2**32 - 1))
18ETH_FCS_LEN=4
19ETH_HLEN=$((6+6+2))
20TEST_NAME=$(basename "$0" .sh)
21
22declare -A netif_mtu
23
24ensure_mtu()
25{
26 local iface=$1; shift
27 local len=$1; shift
28 local required=$((len - ETH_HLEN - ETH_FCS_LEN))
29 local current
30
31 current=$(run_on "$iface" \
32 ip -j link show dev "$iface" | jq -r '.[0].mtu')
33 if [ "$current" -lt "$required" ]; then
34 run_on "$iface" ip link set dev "$iface" mtu "$required" \
35 || return 1
36 fi
37}
38
39bucket_test()
40{
41 local iface=$1; shift
42 local neigh=$1; shift
43 local set=$1; shift
44 local bucket=$1; shift
45 local len=$1; shift
46 local num_rx=10000
47 local num_tx=20000
48 local expected=
49 local before=
50 local after=
51 local delta=
52
53 # Mausezahn does not include FCS bytes in its length - but the
54 # histogram counters do
55 len=$((len - ETH_FCS_LEN))
56 len=$((len > 0 ? len : 0))
57
58 before=$(run_on "$iface" ethtool --json -S "$iface" --groups rmon | \
59 jq -r ".[0].rmon[\"${set}-pktsNtoM\"][$bucket].val")
60
61 # Send 10k one way and 20k in the other, to detect counters
62 # mapped to the wrong direction
63 run_on "$neigh" \
64 "$MZ" "$neigh" -q -c "$num_rx" -p "$len" -a own -b bcast -d 10us
65 run_on "$iface" \
66 "$MZ" "$iface" -q -c "$num_tx" -p "$len" -a own -b bcast -d 10us
67
68 after=$(run_on "$iface" ethtool --json -S "$iface" --groups rmon | \
69 jq -r ".[0].rmon[\"${set}-pktsNtoM\"][$bucket].val")
70
71 delta=$((after - before))
72
73 expected=$([ "$set" = rx ] && echo "$num_rx" || echo "$num_tx")
74
75 [ "$delta" -ge "$expected" ] && [ "$delta" -le "$UINT32_MAX" ]
76}
77
78rmon_histogram()
79{
80 local iface=$1; shift
81 local neigh=$1; shift
82 local set=$1; shift
83 local nbuckets=0
84 local step=
85
86 while read -r -a bucket; do
87 step="$set-pkts${bucket[0]}to${bucket[1]}"
88
89 for if in "$iface" "$neigh"; do
90 if ! ensure_mtu "$if" "${bucket[0]}"; then
91 ktap_print_msg "$if does not support the required MTU for $step"
92 ktap_test_xfail "$TEST_NAME.$step"
93 return
94 fi
95 done
96
97 if ! bucket_test "$iface" "$neigh" "$set" "$nbuckets" "${bucket[0]}"; then
98 ktap_test_fail "$TEST_NAME.$step"
99 return 1
100 fi
101 ktap_test_pass "$TEST_NAME.$step"
102 nbuckets=$((nbuckets + 1))
103 done < <(run_on "$iface" ethtool --json -S "$iface" --groups rmon | \
104 jq -r ".[0].rmon[\"${set}-pktsNtoM\"][]|[.low, .high]|@tsv" 2>/dev/null)
105
106 if [ "$nbuckets" -eq 0 ]; then
107 ktap_print_msg "$iface does not support $set histogram counters"
108 return
109 fi
110}
111
112rmon_rx_histogram()
113{
114 rmon_histogram "$h1" "$h2" rx
115}
116
117rmon_tx_histogram()
118{
119 rmon_histogram "$h1" "$h2" tx
120}
121
122setup_prepare()
123{
124 h1=${NETIFS[p1]}
125 h2=${NETIFS[p2]}
126
127 for iface in "$h1" "$h2"; do
128 netif_mtu["$iface"]=$(run_on "$iface" \
129 ip -j link show dev "$iface" | jq -r '.[0].mtu')
130 done
131}
132
133cleanup()
134{
135 pre_cleanup
136
137 # Do not bring down the interfaces, just configure the initial MTU
138 for iface in "$h2" "$h1"; do
139 run_on "$iface" ip link set dev "$iface" \
140 mtu "${netif_mtu[$iface]}"
141 done
142}
143
144check_ethtool_counter_group_support
145trap cleanup EXIT
146
147bucket_count=$(ethtool --json -S "${NETIFS[p1]}" --groups rmon | \
148 jq -r '.[0].rmon |
149 "\((."rx-pktsNtoM" | length) +
150 (."tx-pktsNtoM" | length))"')
151ktap_print_header
152ktap_set_plan "$bucket_count"
153
154setup_prepare
155setup_wait
156
157tests_run
158
159ktap_finished