Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'selftests-drivers-bash-support-for-remote-traffic-generators'

Ioana Ciornei says:

====================
selftests: drivers: bash support for remote traffic generators

This patch set aims to add the necessary support so that bash written
selftests are also able to easily run with a remote traffic generator
system, either be it in another netns or one accessible through ssh.

This patch set is a result of the discussion from v1:
https://lore.kernel.org/all/20260303084330.340b6459@kernel.org/
Even though the python infrastructure is already established, some
things are easier in bash and it would be a shame to leave behind the
bash tests that we already have.

This support is based on the requirements described in the
tools/testing/selftests/drivers/net/README.rst file.

Mainly, the drivers/net selftests should be able to run on a interface
specified through the NETIF env variable. On top of that, variables such
as REMOTE_TYPE and REMOTE_ARGS define how the remote traffic generator
can be accessed. Patch 3/10 parses these env variables and constructs the
NETIFS array that bash tests are accustomed to. This is with the
intention of enabling already written tests to incur minimal changes.

The second patch also defines the TARGETS array which will hold the
necessary information about the target on which a specific interface
is located.

For example, a net.config which looks like below:
NETIF=eth0
LOCAL_V4=192.168.1.1
REMOTE_V4=192.168.1.2
REMOTE_TYPE=ssh
REMOTE_ARGS=root@192.168.1.2

will generate the NETIFS and TARGETS arrays with the following data.

NETIFS[p1]="eth0"
NETIFS[p2]="eth2"

TARGETS[eth0]="local:"
TARGETS[eth2]="ssh:root@192.168.1.2"

The above will be true if on the remote target, the interface which has
the 192.168.1.2 address is named eth2.

The values held in the TARGETS array will be used by the new 'run_on'
helper added in patch 2/10 to know how to run a specific command, on the
local system, on another netns or by using ssh. Patch 4/10 updates some
helpers to use run_on so that, for example, lib.sh is able to ensure
stable MAC addresses even with the remote interface located in another
netns.

The next 5 patches, 5/10-9/10 update the ethtool_rmon.sh script so that it
can work with the kselftest infrastructure and the new
NETIF/REMOTE_TYPE etc way of working. Beside updating each ip link or
ethtool command to use the run_on helper, the patches also remove any
testing done on the remote interface.

The last patch adds a new test which checks the standard counters -
eth-ctrl, eth-mac and pause - and uses the new infrastructure put in
place by the first patches.

With this patch set, both tests can be run using a net.config file and
run_kselftest.sh as shown below.

$ make -C tools/testing/selftests/ TARGETS="drivers/net drivers/net/hw" \
install INSTALL_PATH=/tmp/ksft-net-drv
$ cd /tmp/ksft-net-drv/
$ cat > ./drivers/net/net.config <<EOF
NETIF=endpmac17
LOCAL_V4=17.0.0.1
REMOTE_V4=17.0.0.2
REMOTE_TYPE=ssh
REMOTE_ARGS=root@192.168.5.200
EOF

$ ./run_kselftest.sh -t drivers/net/hw:ethtool_rmon.sh
TAP version 13
1..1
# timeout set to 0
# selftests: drivers/net/hw: ethtool_rmon.sh
# TAP version 13
# 1..14
# ok 1 ethtool_rmon.rx-pkts64to64
# ok 2 ethtool_rmon.rx-pkts65to127
# ok 3 ethtool_rmon.rx-pkts128to255
# ok 4 ethtool_rmon.rx-pkts256to511
# ok 5 ethtool_rmon.rx-pkts512to1023
# ok 6 ethtool_rmon.rx-pkts1024to1518
# ok 7 ethtool_rmon.rx-pkts1519to10240
# ok 8 ethtool_rmon.tx-pkts64to64
# ok 9 ethtool_rmon.tx-pkts65to127
# ok 10 ethtool_rmon.tx-pkts128to255
# ok 11 ethtool_rmon.tx-pkts256to511
# ok 12 ethtool_rmon.tx-pkts512to1023
# ok 13 ethtool_rmon.tx-pkts1024to1518
# ok 14 ethtool_rmon.tx-pkts1519to10240
# # Totals: pass:14 fail:0 xfail:0 xpass:0 skip:0 error:0
ok 1 selftests: drivers/net/hw: ethtool_rmon.sh

$ ./run_kselftest.sh -t drivers/net/hw:ethtool_std_stats.sh
TAP version 13
1..1
# timeout set to 0
# selftests: drivers/net/hw: ethtool_std_stats.sh
# TAP version 13
# 1..26
# ok 1 ethtool_std_stats.eth-ctrl-MACControlFramesTransmitted
# ok 2 ethtool_std_stats.eth-ctrl-MACControlFramesReceived
# ok 3 ethtool_std_stats.eth-mac-FrameCheckSequenceErrors
# ok 4 ethtool_std_stats.eth-mac-AlignmentErrors
# ok 5 ethtool_std_stats.eth-mac-FramesLostDueToIntMACXmitError
# ok 6 ethtool_std_stats.eth-mac-CarrierSenseErrors # SKIP
# ok 7 ethtool_std_stats.eth-mac-FramesLostDueToIntMACRcvError
# ok 8 ethtool_std_stats.eth-mac-InRangeLengthErrors # SKIP
# ok 9 ethtool_std_stats.eth-mac-OutOfRangeLengthField # SKIP
# ok 10 ethtool_std_stats.eth-mac-FrameTooLongErrors # SKIP
# ok 11 ethtool_std_stats.eth-mac-FramesAbortedDueToXSColls # SKIP
# ok 12 ethtool_std_stats.eth-mac-SingleCollisionFrames # SKIP
# ok 13 ethtool_std_stats.eth-mac-MultipleCollisionFrames # SKIP
# ok 14 ethtool_std_stats.eth-mac-FramesWithDeferredXmissions # SKIP
# ok 15 ethtool_std_stats.eth-mac-LateCollisions # SKIP
# ok 16 ethtool_std_stats.eth-mac-FramesWithExcessiveDeferral # SKIP
# ok 17 ethtool_std_stats.eth-mac-BroadcastFramesXmittedOK
# ok 18 ethtool_std_stats.eth-mac-OctetsTransmittedOK
# ok 19 ethtool_std_stats.eth-mac-BroadcastFramesReceivedOK
# ok 20 ethtool_std_stats.eth-mac-OctetsReceivedOK
# ok 21 ethtool_std_stats.eth-mac-FramesTransmittedOK
# ok 22 ethtool_std_stats.eth-mac-MulticastFramesXmittedOK
# ok 23 ethtool_std_stats.eth-mac-FramesReceivedOK
# ok 24 ethtool_std_stats.eth-mac-MulticastFramesReceivedOK
# ok 25 ethtool_std_stats.pause-tx_pause_frames
# ok 26 ethtool_std_stats.pause-rx_pause_frames
# # 10 skipped test(s) detected. Consider enabling relevant config options to improve coverage.
# # Totals: pass:16 fail:0 xfail:0 xpass:0 skip:10 error:0
ok 1 selftests: drivers/net/hw: ethtool_std_stats.sh
====================

Link: https://patch.msgid.link/20260330152933.2195885-1-ioana.ciornei@nxp.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>

+422 -52
+4
tools/testing/selftests/drivers/net/README.rst
··· 26 26 Refer to list of :ref:`Variables` later in this file to set up running 27 27 the tests against a real device. 28 28 29 + The current support for bash tests restricts the use of the same interface name 30 + on the local system and the remote one and will bail if this case is 31 + encountered. 32 + 29 33 Both modes required 30 34 ~~~~~~~~~~~~~~~~~~~ 31 35
+1
tools/testing/selftests/drivers/net/hw/Makefile
··· 26 26 ethtool_extended_state.sh \ 27 27 ethtool_mm.sh \ 28 28 ethtool_rmon.sh \ 29 + ethtool_std_stats.sh \ 29 30 gro_hw.py \ 30 31 hw_stats_l3.sh \ 31 32 hw_stats_l3_gre.sh \
+48 -34
tools/testing/selftests/drivers/net/hw/ethtool_rmon.sh
··· 1 1 #!/bin/bash 2 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 3 5 4 6 ALL_TESTS=" 5 7 rmon_rx_histogram 6 8 rmon_tx_histogram 7 9 " 8 10 11 + : "${DRIVER_TEST_CONFORMANT:=yes}" 9 12 NUM_NETIFS=2 10 13 lib_dir=$(dirname "$0") 11 14 source "$lib_dir"/../../../net/forwarding/lib.sh 15 + source "$lib_dir"/../../../kselftest/ktap_helpers.sh 12 16 17 + UINT32_MAX=$((2**32 - 1)) 13 18 ETH_FCS_LEN=4 14 19 ETH_HLEN=$((6+6+2)) 20 + TEST_NAME=$(basename "$0" .sh) 15 21 16 22 declare -A netif_mtu 17 23 ··· 25 19 { 26 20 local iface=$1; shift 27 21 local len=$1; shift 28 - local current=$(ip -j link show dev $iface | jq -r '.[0].mtu') 29 22 local required=$((len - ETH_HLEN - ETH_FCS_LEN)) 23 + local current 30 24 31 - if [ $current -lt $required ]; then 32 - ip link set dev $iface mtu $required || return 1 25 + current=$(run_on "$iface" \ 26 + ip -j link show dev "$iface" | jq -r '.[0].mtu') 27 + if [ "$current" -lt "$required" ]; then 28 + run_on "$iface" ip link set dev "$iface" mtu "$required" \ 29 + || return 1 33 30 fi 34 31 } 35 32 ··· 55 46 len=$((len - ETH_FCS_LEN)) 56 47 len=$((len > 0 ? len : 0)) 57 48 58 - before=$(ethtool --json -S $iface --groups rmon | \ 49 + before=$(run_on "$iface" ethtool --json -S "$iface" --groups rmon | \ 59 50 jq -r ".[0].rmon[\"${set}-pktsNtoM\"][$bucket].val") 60 51 61 52 # Send 10k one way and 20k in the other, to detect counters 62 53 # mapped to the wrong direction 63 - $MZ $neigh -q -c $num_rx -p $len -a own -b bcast -d 10us 64 - $MZ $iface -q -c $num_tx -p $len -a own -b bcast -d 10us 54 + run_on "$neigh" \ 55 + "$MZ" "$neigh" -q -c "$num_rx" -p "$len" -a own -b bcast -d 10us 56 + run_on "$iface" \ 57 + "$MZ" "$iface" -q -c "$num_tx" -p "$len" -a own -b bcast -d 10us 65 58 66 - after=$(ethtool --json -S $iface --groups rmon | \ 59 + after=$(run_on "$iface" ethtool --json -S "$iface" --groups rmon | \ 67 60 jq -r ".[0].rmon[\"${set}-pktsNtoM\"][$bucket].val") 68 61 69 62 delta=$((after - before)) 70 63 71 - expected=$([ $set = rx ] && echo $num_rx || echo $num_tx) 64 + expected=$([ "$set" = rx ] && echo "$num_rx" || echo "$num_tx") 72 65 73 - # Allow some extra tolerance for other packets sent by the stack 74 - [ $delta -ge $expected ] && [ $delta -le $((expected + 100)) ] 66 + [ "$delta" -ge "$expected" ] && [ "$delta" -le "$UINT32_MAX" ] 75 67 } 76 68 77 69 rmon_histogram() ··· 83 73 local nbuckets=0 84 74 local step= 85 75 86 - RET=0 87 - 88 76 while read -r -a bucket; do 89 - step="$set-pkts${bucket[0]}to${bucket[1]} on $iface" 77 + step="$set-pkts${bucket[0]}to${bucket[1]}" 90 78 91 - for if in $iface $neigh; do 92 - if ! ensure_mtu $if ${bucket[0]}; then 93 - log_test_xfail "$if does not support the required MTU for $step" 79 + for if in "$iface" "$neigh"; do 80 + if ! ensure_mtu "$if" "${bucket[0]}"; then 81 + ktap_print_msg "$if does not support the required MTU for $step" 82 + ktap_test_xfail "$TEST_NAME.$step" 94 83 return 95 84 fi 96 85 done 97 86 98 - if ! bucket_test $iface $neigh $set $nbuckets ${bucket[0]}; then 99 - check_err 1 "$step failed" 87 + if ! bucket_test "$iface" "$neigh" "$set" "$nbuckets" "${bucket[0]}"; then 88 + ktap_test_fail "$TEST_NAME.$step" 100 89 return 1 101 90 fi 102 - log_test "$step" 91 + ktap_test_pass "$TEST_NAME.$step" 103 92 nbuckets=$((nbuckets + 1)) 104 - done < <(ethtool --json -S $iface --groups rmon | \ 93 + done < <(run_on "$iface" ethtool --json -S "$iface" --groups rmon | \ 105 94 jq -r ".[0].rmon[\"${set}-pktsNtoM\"][]|[.low, .high]|@tsv" 2>/dev/null) 106 95 107 - if [ $nbuckets -eq 0 ]; then 108 - log_test_xfail "$iface does not support $set histogram counters" 96 + if [ "$nbuckets" -eq 0 ]; then 97 + ktap_print_msg "$iface does not support $set histogram counters" 109 98 return 110 99 fi 111 100 } 112 101 113 102 rmon_rx_histogram() 114 103 { 115 - rmon_histogram $h1 $h2 rx 116 - rmon_histogram $h2 $h1 rx 104 + rmon_histogram "$h1" "$h2" rx 117 105 } 118 106 119 107 rmon_tx_histogram() 120 108 { 121 - rmon_histogram $h1 $h2 tx 122 - rmon_histogram $h2 $h1 tx 109 + rmon_histogram "$h1" "$h2" tx 123 110 } 124 111 125 112 setup_prepare() ··· 124 117 h1=${NETIFS[p1]} 125 118 h2=${NETIFS[p2]} 126 119 127 - for iface in $h1 $h2; do 128 - netif_mtu[$iface]=$(ip -j link show dev $iface | jq -r '.[0].mtu') 129 - ip link set dev $iface up 120 + for iface in "$h1" "$h2"; do 121 + netif_mtu["$iface"]=$(run_on "$iface" \ 122 + ip -j link show dev "$iface" | jq -r '.[0].mtu') 130 123 done 131 124 } 132 125 ··· 134 127 { 135 128 pre_cleanup 136 129 137 - for iface in $h2 $h1; do 138 - ip link set dev $iface \ 139 - mtu ${netif_mtu[$iface]} \ 140 - down 130 + # Do not bring down the interfaces, just configure the initial MTU 131 + for iface in "$h2" "$h1"; do 132 + run_on "$iface" ip link set dev "$iface" \ 133 + mtu "${netif_mtu[$iface]}" 141 134 done 142 135 } 143 136 144 137 check_ethtool_counter_group_support 145 138 trap cleanup EXIT 146 139 140 + bucket_count=$(ethtool --json -S "${NETIFS[p1]}" --groups rmon | \ 141 + jq -r '.[0].rmon | 142 + "\((."rx-pktsNtoM" | length) + 143 + (."tx-pktsNtoM" | length))"') 144 + ktap_print_header 145 + ktap_set_plan "$bucket_count" 146 + 147 147 setup_prepare 148 148 setup_wait 149 149 150 150 tests_run 151 151 152 - exit $EXIT_STATUS 152 + ktap_finished
+206
tools/testing/selftests/drivers/net/hw/ethtool_std_stats.sh
··· 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 + 6 + ALL_TESTS=" 7 + test_eth_ctrl_stats 8 + test_eth_mac_stats 9 + test_pause_stats 10 + " 11 + : "${DRIVER_TEST_CONFORMANT:=yes}" 12 + STABLE_MAC_ADDRS=yes 13 + NUM_NETIFS=2 14 + lib_dir=$(dirname "$0") 15 + # shellcheck source=./../../../net/forwarding/lib.sh 16 + source "$lib_dir"/../../../net/forwarding/lib.sh 17 + # shellcheck source=./../../../kselftest/ktap_helpers.sh 18 + source "$lib_dir"/../../../kselftest/ktap_helpers.sh 19 + 20 + UINT32_MAX=$((2**32 - 1)) 21 + SUBTESTS=0 22 + TEST_NAME=$(basename "$0" .sh) 23 + 24 + traffic_test() 25 + { 26 + local iface=$1; shift 27 + local neigh=$1; shift 28 + local num_tx=$1; shift 29 + local pkt_format="$1"; shift 30 + local -a counters=("$@") 31 + local int grp cnt target exact_check 32 + local before after delta 33 + local num_rx=$((num_tx * 2)) 34 + local xfail_message 35 + local src="aggregate" 36 + local i 37 + 38 + for i in "${!counters[@]}"; do 39 + read -r int grp cnt target exact_check xfail_message \ 40 + <<< "${counters[$i]}" 41 + 42 + before[i]=$(ethtool_std_stats_get "$int" "$grp" "$cnt" "$src") 43 + done 44 + 45 + # shellcheck disable=SC2086 # needs split options 46 + run_on "$iface" "$MZ" "$iface" -q -c "$num_tx" $pkt_format 47 + 48 + # shellcheck disable=SC2086 # needs split options 49 + run_on "$neigh" "$MZ" "$neigh" -q -c "$num_rx" $pkt_format 50 + 51 + for i in "${!counters[@]}"; do 52 + read -r int grp cnt target exact_check xfail_message \ 53 + <<< "${counters[$i]}" 54 + 55 + after[i]=$(ethtool_std_stats_get "$int" "$grp" "$cnt" "$src") 56 + if [[ "${after[$i]}" == "null" ]]; then 57 + ktap_test_skip "$TEST_NAME.$grp-$cnt" 58 + continue; 59 + fi 60 + 61 + delta=$((after[i] - before[i])) 62 + 63 + if [ "$exact_check" -ne 0 ]; then 64 + [ "$delta" -eq "$target" ] 65 + else 66 + [ "$delta" -ge "$target" ] && \ 67 + [ "$delta" -le "$UINT32_MAX" ] 68 + fi 69 + err="$?" 70 + 71 + if [[ $err != 0 ]] && [[ -n $xfail_message ]]; then 72 + ktap_print_msg "$xfail_message" 73 + ktap_test_xfail "$TEST_NAME.$grp-$cnt" 74 + continue; 75 + fi 76 + 77 + if [[ $err != 0 ]]; then 78 + ktap_print_msg "$grp-$cnt is not valid on $int (expected $target, got $delta)" 79 + ktap_test_fail "$TEST_NAME.$grp-$cnt" 80 + else 81 + ktap_test_pass "$TEST_NAME.$grp-$cnt" 82 + fi 83 + done 84 + } 85 + 86 + test_eth_ctrl_stats() 87 + { 88 + local pkt_format="-a own -b bcast 88:08 -p 64" 89 + local num_pkts=1000 90 + local -a counters 91 + 92 + counters=("$h1 eth-ctrl MACControlFramesTransmitted $num_pkts 0") 93 + traffic_test "$h1" "$h2" "$num_pkts" "$pkt_format" \ 94 + "${counters[@]}" 95 + 96 + counters=("$h1 eth-ctrl MACControlFramesReceived $num_pkts 0") 97 + traffic_test "$h2" "$h1" "$num_pkts" "$pkt_format" \ 98 + "${counters[@]}" 99 + } 100 + SUBTESTS=$((SUBTESTS + 2)) 101 + 102 + test_eth_mac_stats() 103 + { 104 + local pkt_size=100 105 + local pkt_size_fcs=$((pkt_size + 4)) 106 + local bcast_pkt_format="-a own -b bcast -p $pkt_size" 107 + local mcast_pkt_format="-a own -b 01:00:5E:00:00:01 -p $pkt_size" 108 + local num_pkts=2000 109 + local octets=$((pkt_size_fcs * num_pkts)) 110 + local -a counters error_cnt collision_cnt 111 + 112 + # Error counters should be exactly zero 113 + counters=("$h1 eth-mac FrameCheckSequenceErrors 0 1" 114 + "$h1 eth-mac AlignmentErrors 0 1" 115 + "$h1 eth-mac FramesLostDueToIntMACXmitError 0 1" 116 + "$h1 eth-mac CarrierSenseErrors 0 1" 117 + "$h1 eth-mac FramesLostDueToIntMACRcvError 0 1" 118 + "$h1 eth-mac InRangeLengthErrors 0 1" 119 + "$h1 eth-mac OutOfRangeLengthField 0 1" 120 + "$h1 eth-mac FrameTooLongErrors 0 1" 121 + "$h1 eth-mac FramesAbortedDueToXSColls 0 1") 122 + traffic_test "$h1" "$h2" "$num_pkts" "$bcast_pkt_format" \ 123 + "${counters[@]}" 124 + 125 + # Collision related counters should also be zero 126 + counters=("$h1 eth-mac SingleCollisionFrames 0 1" 127 + "$h1 eth-mac MultipleCollisionFrames 0 1" 128 + "$h1 eth-mac FramesWithDeferredXmissions 0 1" 129 + "$h1 eth-mac LateCollisions 0 1" 130 + "$h1 eth-mac FramesWithExcessiveDeferral 0 1") 131 + traffic_test "$h1" "$h2" "$num_pkts" "$bcast_pkt_format" \ 132 + "${counters[@]}" 133 + 134 + counters=("$h1 eth-mac BroadcastFramesXmittedOK $num_pkts 0" 135 + "$h1 eth-mac OctetsTransmittedOK $octets 0") 136 + traffic_test "$h1" "$h2" "$num_pkts" "$bcast_pkt_format" \ 137 + "${counters[@]}" 138 + 139 + counters=("$h1 eth-mac BroadcastFramesReceivedOK $num_pkts 0" 140 + "$h1 eth-mac OctetsReceivedOK $octets 0") 141 + traffic_test "$h2" "$h1" "$num_pkts" "$bcast_pkt_format" \ 142 + "${counters[@]}" 143 + 144 + counters=("$h1 eth-mac FramesTransmittedOK $num_pkts 0" 145 + "$h1 eth-mac MulticastFramesXmittedOK $num_pkts 0") 146 + traffic_test "$h1" "$h2" "$num_pkts" "$mcast_pkt_format" \ 147 + "${counters[@]}" 148 + 149 + counters=("$h1 eth-mac FramesReceivedOK $num_pkts 0" 150 + "$h1 eth-mac MulticastFramesReceivedOK $num_pkts 0") 151 + traffic_test "$h2" "$h1" "$num_pkts" "$mcast_pkt_format" \ 152 + "${counters[@]}" 153 + } 154 + SUBTESTS=$((SUBTESTS + 22)) 155 + 156 + test_pause_stats() 157 + { 158 + local pkt_format="-a own -b 01:80:c2:00:00:01 88:08:00:01:00:01" 159 + local xfail_message="software sent pause frames not detected" 160 + local num_pkts=2000 161 + local -a counters 162 + local int 163 + local i 164 + 165 + # Check that there is pause frame support 166 + for ((i = 1; i <= NUM_NETIFS; ++i)); do 167 + int="${NETIFS[p$i]}" 168 + if ! run_on "$int" ethtool -I --json -a "$int" > /dev/null 2>&1; then 169 + ktap_test_skip "$TEST_NAME.tx_pause_frames" 170 + ktap_test_skip "$TEST_NAME.rx_pause_frames" 171 + return 172 + fi 173 + done 174 + 175 + counters=("$h1 pause tx_pause_frames $num_pkts 0 $xfail_message") 176 + traffic_test "$h1" "$h2" "$num_pkts" "$pkt_format" \ 177 + "${counters[@]}" 178 + 179 + counters=("$h1 pause rx_pause_frames $num_pkts 0") 180 + traffic_test "$h2" "$h1" "$num_pkts" "$pkt_format" \ 181 + "${counters[@]}" 182 + } 183 + SUBTESTS=$((SUBTESTS + 2)) 184 + 185 + setup_prepare() 186 + { 187 + local iface 188 + 189 + h1=${NETIFS[p1]} 190 + h2=${NETIFS[p2]} 191 + 192 + h2_mac=$(mac_get "$h2") 193 + } 194 + 195 + ktap_print_header 196 + ktap_set_plan $SUBTESTS 197 + 198 + check_ethtool_counter_group_support 199 + trap cleanup EXIT 200 + 201 + setup_prepare 202 + setup_wait 203 + 204 + tests_run 205 + 206 + ktap_finished
+156 -17
tools/testing/selftests/net/forwarding/lib.sh
··· 1 1 #!/bin/bash 2 2 # SPDX-License-Identifier: GPL-2.0 3 + #shellcheck disable=SC2034 # SC doesn't see our uses of global variables 3 4 4 5 ############################################################################## 5 6 # Topology description. p1 looped back to p2, p3 to p4 and so on. ··· 341 340 ############################################################################## 342 341 # Command line options handling 343 342 344 - count=0 345 - 346 - while [[ $# -gt 0 ]]; do 347 - if [[ "$count" -eq "0" ]]; then 348 - unset NETIFS 349 - declare -A NETIFS 343 + check_env() { 344 + if [[ ! (( -n "$LOCAL_V4" && -n "$REMOTE_V4") || 345 + ( -n "$LOCAL_V6" && -n "$REMOTE_V6" )) ]]; then 346 + echo "SKIP: Invalid environment, missing or inconsistent LOCAL_V4/REMOTE_V4/LOCAL_V6/REMOTE_V6" 347 + echo "Please see tools/testing/selftests/drivers/net/README.rst" 348 + exit "$ksft_skip" 350 349 fi 351 - count=$((count + 1)) 352 - NETIFS[p$count]="$1" 353 - shift 354 - done 350 + 351 + if [[ -z "$REMOTE_TYPE" ]]; then 352 + echo "SKIP: Invalid environment, missing REMOTE_TYPE" 353 + exit "$ksft_skip" 354 + fi 355 + 356 + if [[ -z "$REMOTE_ARGS" ]]; then 357 + echo "SKIP: Invalid environment, missing REMOTE_ARGS" 358 + exit "$ksft_skip" 359 + fi 360 + } 361 + 362 + __run_on() 363 + { 364 + local target=$1; shift 365 + local type args 366 + 367 + IFS=':' read -r type args <<< "$target" 368 + 369 + case "$type" in 370 + netns) 371 + # Execute command in network namespace 372 + # args contains the namespace name 373 + ip netns exec "$args" "$@" 374 + ;; 375 + ssh) 376 + # Execute command via SSH args contains user@host 377 + ssh -n "$args" "$@" 378 + ;; 379 + local|*) 380 + # Execute command locally. This is also the fallback 381 + # case for when the interface's target is not found in 382 + # the TARGETS array. 383 + "$@" 384 + ;; 385 + esac 386 + } 387 + 388 + run_on() 389 + { 390 + local iface=$1; shift 391 + local target="local:" 392 + 393 + if [ "${DRIVER_TEST_CONFORMANT}" = "yes" ]; then 394 + target="${TARGETS[$iface]}" 395 + fi 396 + 397 + __run_on "$target" "$@" 398 + } 399 + 400 + get_ifname_by_ip() 401 + { 402 + local target=$1; shift 403 + local ip_addr=$1; shift 404 + 405 + __run_on "$target" ip -j addr show to "$ip_addr" | jq -r '.[].ifname' 406 + } 407 + 408 + # Whether the test is conforming to the requirements and usage described in 409 + # drivers/net/README.rst. 410 + : "${DRIVER_TEST_CONFORMANT:=no}" 411 + 412 + declare -A TARGETS 413 + 414 + # Based on DRIVER_TEST_CONFORMANT, decide if to source drivers/net/net.config 415 + # or not. In the "yes" case, the test expects to pass the arguments through the 416 + # variables specified in drivers/net/README.rst file. If not, fallback on 417 + # parsing the script arguments for interface names. 418 + if [ "${DRIVER_TEST_CONFORMANT}" = "yes" ]; then 419 + if [[ -f $net_forwarding_dir/../../drivers/net/net.config ]]; then 420 + source "$net_forwarding_dir/../../drivers/net/net.config" 421 + fi 422 + 423 + if (( NUM_NETIFS > 2)); then 424 + echo "SKIP: DRIVER_TEST_CONFORMANT=yes and NUM_NETIFS is bigger than 2" 425 + exit "$ksft_skip" 426 + fi 427 + 428 + check_env 429 + 430 + # Populate the NETIFS and TARGETS arrays automatically based on the 431 + # environment variables. The TARGETS array is indexed by the network 432 + # interface name keeping track of the target on which the interface 433 + # resides. Values will be strings of the following format - 434 + # <type>:<args>. 435 + # 436 + # TARGETS[eth0]="local:" - meaning that the eth0 interface is 437 + # accessible locally 438 + # TARGETS[eth1]="netns:foo" - eth1 is in the foo netns 439 + # TARGETS[eth2]="ssh:root@10.0.0.2" - eth2 is accessible through 440 + # running the 'ssh root@10.0.0.2' command. 441 + 442 + unset NETIFS 443 + declare -A NETIFS 444 + 445 + NETIFS[p1]="$NETIF" 446 + TARGETS[$NETIF]="local:" 447 + 448 + # Locate the name of the remote interface 449 + remote_target="$REMOTE_TYPE:$REMOTE_ARGS" 450 + if [[ -v REMOTE_V4 ]]; then 451 + remote_netif=$(get_ifname_by_ip "$remote_target" "$REMOTE_V4") 452 + else 453 + remote_netif=$(get_ifname_by_ip "$remote_target" "$REMOTE_V6") 454 + fi 455 + if [[ ! -n "$remote_netif" ]]; then 456 + echo "SKIP: cannot find remote interface" 457 + exit "$ksft_skip" 458 + fi 459 + 460 + if [[ "$NETIF" == "$remote_netif" ]]; then 461 + echo "SKIP: local and remote interfaces cannot have the same name" 462 + exit "$ksft_skip" 463 + fi 464 + 465 + NETIFS[p2]="$remote_netif" 466 + TARGETS[$remote_netif]="$REMOTE_TYPE:$REMOTE_ARGS" 467 + else 468 + count=0 469 + 470 + while [[ $# -gt 0 ]]; do 471 + if [[ "$count" -eq "0" ]]; then 472 + unset NETIFS 473 + declare -A NETIFS 474 + fi 475 + count=$((count + 1)) 476 + NETIFS[p$count]="$1" 477 + TARGETS[$1]="local:" 478 + shift 479 + done 480 + fi 355 481 356 482 ############################################################################## 357 483 # Network interfaces configuration ··· 546 418 dev=${NETIFS[p$i]} 547 419 new_addr=$(printf "00:01:02:03:04:%02x" $i) 548 420 549 - MAC_ADDR_ORIG["$dev"]=$(ip -j link show dev $dev | jq -e '.[].address') 421 + MAC_ADDR_ORIG["$dev"]=$(run_on "$dev" \ 422 + ip -j link show dev "$dev" | jq -e '.[].address') 550 423 # Strip quotes 551 424 MAC_ADDR_ORIG["$dev"]=${MAC_ADDR_ORIG["$dev"]//\"/} 552 - ip link set dev $dev address $new_addr 425 + run_on "$dev" ip link set dev "$dev" address $new_addr 553 426 done 554 427 } 555 428 ··· 560 431 561 432 for ((i = 1; i <= NUM_NETIFS; ++i)); do 562 433 dev=${NETIFS[p$i]} 563 - ip link set dev $dev address ${MAC_ADDR_ORIG["$dev"]} 434 + run_on "$dev" \ 435 + ip link set dev "$dev" address ${MAC_ADDR_ORIG["$dev"]} 564 436 done 565 437 } 566 438 ··· 574 444 fi 575 445 576 446 for ((i = 1; i <= NUM_NETIFS; ++i)); do 577 - ip link show dev ${NETIFS[p$i]} &> /dev/null 447 + int="${NETIFS[p$i]}" 448 + 449 + run_on "$int" ip link show dev "$int" &> /dev/null 578 450 if [[ $? -ne 0 ]]; then 579 451 echo "SKIP: could not find all required interfaces" 580 452 exit $ksft_skip ··· 659 527 local i 660 528 661 529 for ((i = 1; i <= $max_iterations; ++i)); do 662 - ip link show dev $dev up \ 530 + run_on "$dev" ip link show dev "$dev" up \ 663 531 | grep 'state UP' &> /dev/null 664 532 if [[ $? -ne 0 ]]; then 665 533 sleep 1 ··· 963 831 local name=$1; shift 964 832 local src=$1; shift 965 833 966 - ethtool --json -S $dev --groups $grp -- --src $src | \ 967 - jq '.[]."'"$grp"'"."'$name'"' 834 + if [[ "$grp" == "pause" ]]; then 835 + run_on "$dev" ethtool -I --json -a "$dev" --src "$src" | \ 836 + jq --arg name "$name" '.[].statistics[$name]' 837 + return 838 + fi 839 + 840 + run_on "$dev" \ 841 + ethtool --json -S "$dev" --groups "$grp" -- --src "$src" | \ 842 + jq --arg grp "$grp" --arg name "$name" '.[][$grp][$name]' 968 843 } 969 844 970 845 qdisc_stats_get()
+7 -1
tools/testing/selftests/net/lib.sh
··· 514 514 { 515 515 local if_name=$1 516 516 517 - ip -j link show dev $if_name | jq -r '.[]["address"]' 517 + run_on "$if_name" \ 518 + ip -j link show dev "$if_name" | jq -r '.[]["address"]' 518 519 } 519 520 520 521 kill_process() ··· 670 669 echo $output 671 670 # return success only in case of non-empty output 672 671 [ ! -z "$output" ] 672 + } 673 + 674 + run_on() 675 + { 676 + shift; "$@" 673 677 }