Add a regression test for veth_set_channels() incorrectly reporting LOWER_UP on a running interface whose peer is administratively down.
Test the up/up and both mixed up/down combinations with GRO enabled and disabled. Resize the RX and TX channel counts in both directions on each end and check LOWER_UP on each running interface. Also verify that rejecting an out-of-range channel count leaves that state unchanged. IFF_LOWER_UP is masked on administratively down interfaces, so do not use it to assert their raw carrier state. Omit the down/down combination, where neither endpoint can report LOWER_UP. On an unpatched UML kernel the four mixed up/down cases fail. All six cases pass with the carrier restoration fix. Assisted-by: LLM Signed-off-by: Xia Yan <[email protected]> --- Notes: Changes in v2: - Limit carrier assertions to running endpoints and omit down/down, since IFF_LOWER_UP does not expose a down endpoint's raw carrier state. - Use log_test_skip() on veth creation failure to avoid a stale retmsg. - Include the discovery and reproduction details in the driver commit. - Driver code is unchanged. v1: https://lore.kernel.org/netdev/[email protected]/ Review: https://netdev-ai.bots.linux.dev/sashiko/#/patchset/8081 Validation for the revised selftest on the original net baseline: - bash -n passed. - Unpatched UML kernel: 2 pass, 4 fail (the mixed up/down cases). - Patched UML kernel: 6 pass. - Injected veth creation failure after an earlier failed case: SKIP no longer repeats the earlier error; the aggregate failure is preserved. Reused the existing UML kernels; no kernel rebuild was performed for this revision. Prior build results and their limits remain archived. tools/testing/selftests/net/Makefile | 1 + .../selftests/net/veth_channels_carrier.sh | 93 +++++++++++++++++++ 2 files changed, 94 insertions(+) create mode 100755 tools/testing/selftests/net/veth_channels_carrier.sh diff --git a/tools/testing/selftests/net/Makefile b/tools/testing/selftests/net/Makefile index 590b33e..4004014 100644 --- a/tools/testing/selftests/net/Makefile +++ b/tools/testing/selftests/net/Makefile @@ -128,6 +128,7 @@ TEST_PROGS := \ udpgso_bench.sh \ unicast_extensions.sh \ veth.sh \ + veth_channels_carrier.sh \ vlan_bridge_binding.sh \ vlan_hw_filter.sh \ vrf-xfrm-tests.sh \ diff --git a/tools/testing/selftests/net/veth_channels_carrier.sh b/tools/testing/selftests/net/veth_channels_carrier.sh new file mode 100755 index 0000000..03c2995 --- /dev/null +++ b/tools/testing/selftests/net/veth_channels_carrier.sh @@ -0,0 +1,93 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0 + +source "$(dirname "${BASH_SOURCE[0]}")/lib.sh" + +require_command ip +require_command ethtool + +if [ "$EUID" -ne 0 ]; then + echo "SKIP: root privileges are required" + exit "$ksft_skip" +fi + +trap cleanup_all_ns EXIT +setup_ns ns || exit $? + +check_carrier() +{ + local dev=$1 + local state=$2 + local expected=$3 + local carrier=0 + local link + + # IFF_LOWER_UP is reported only for running interfaces. + [ "$state" = up ] || return 0 + + link=$(ip -n "$ns" -o link show dev "$dev") + check_err $? "Failed to read $dev link state" + [[ $link == *LOWER_UP* ]] && carrier=1 + [ "$carrier" -eq "$expected" ] + check_err $? "$dev carrier is $carrier, expected $expected" +} + +check_state() +{ + local left=$1 + local right=$2 + local gro=$3 + local expected=0 + local count dev + + RET=0 + if ! ip -n "$ns" link add vca numtxqueues 2 numrxqueues 2 \ + type veth peer name vcb numtxqueues 2 numrxqueues 2; then + log_test_skip "veth carrier: $left/$right, GRO $gro" + return + fi + + ip -n "$ns" link set vca "$left" + check_err $? "Failed to configure vca" + ip -n "$ns" link set vcb "$right" + check_err $? "Failed to configure vcb" + ip netns exec "$ns" ethtool -K vca gro "$gro" >/dev/null + check_err $? "Failed to configure GRO" + ip netns exec "$ns" ethtool -K vcb gro "$gro" >/dev/null + check_err $? "Failed to configure peer GRO" + + [ "$left" = up ] && [ "$right" = up ] && expected=1 + check_carrier vca "$left" "$expected" + check_carrier vcb "$right" "$expected" + + for dev in vca vcb; do + for count in 1 2; do + ip netns exec "$ns" ethtool -L "$dev" \ + rx "$count" tx "$count" + check_err $? "Failed to resize $dev channels" + check_carrier vca "$left" "$expected" + check_carrier vcb "$right" "$expected" + done + + ip netns exec "$ns" ethtool -L "$dev" rx 3 tx 3 \ + >/dev/null 2>&1 + check_fail $? "Out-of-range channel counts were accepted" + check_carrier vca "$left" "$expected" + check_carrier vcb "$right" "$expected" + done + + ip -n "$ns" link del vca + check_err $? "Failed to delete the veth pair" + log_test "veth carrier: $left/$right, GRO $gro" +} + +for gro in off on; do + for left in down up; do + for right in down up; do + [ "$left" = down ] && [ "$right" = down ] && continue + check_state "$left" "$right" "$gro" + done + done +done + +exit "$EXIT_STATUS" -- 2.43.0
