mirror of
https://github.com/torvalds/linux.git
synced 2026-07-27 17:47:41 +02:00
Add a selftest for the protodown mechanism.
Five test cases are included:
1. Basic protodown toggling: Verify that setting protodown on macvlan
results in DOWN operational state and clearing it restores UP.
2. Same as the previous test case, but with vxlan.
3. Protodown reasons: Verify that protodown cannot be cleared while
there are active protodown reasons, but can be cleared once all
reasons are removed.
4. Protodown with lower device being toggled: Verify that toggling the
lower device's carrier while protodown is on does not cause the
macvlan to gain carrier.
5. Protodown with lower device down: Verify that toggling protodown
while the lower device has no carrier does not cause the macvlan to
gain carrier.
Note that the last two test cases fail without "net: Do not turn on
carrier when protodown is on" and "net: Do not unconditionally turn on
carrier when turning off protodown":
# ./protodown.sh
TEST: Basic protodown on/off with macvlan [ OK ]
TEST: Basic protodown on/off with vxlan [ OK ]
TEST: Protodown reasons [ OK ]
TEST: Protodown with lower device toggled [FAIL]
Macvlan operational state is not DOWN despite protodown
TEST: Protodown with lower device down [FAIL]
Macvlan is not LOWERLAYERDOWN after clearing protodown
Assisted-by: Claude:claude-opus-4-6
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
Link: https://patch.msgid.link/20260507105906.891817-5-idosch@nvidia.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
183 lines
4.7 KiB
Bash
Executable File
183 lines
4.7 KiB
Bash
Executable File
#!/bin/bash
|
|
# SPDX-License-Identifier: GPL-2.0
|
|
#
|
|
# Test the protodown mechanism. Verify basic protodown toggling, protodown
|
|
# reasons, operational state when the lower device carrier changes, and correct
|
|
# operational state when the lower device has no carrier.
|
|
|
|
# shellcheck disable=SC1091,SC2034,SC2154,SC2317
|
|
source lib.sh
|
|
|
|
require_command jq
|
|
|
|
ALL_TESTS="
|
|
protodown_basic_macvlan
|
|
protodown_basic_vxlan
|
|
protodown_reasons
|
|
protodown_lower_toggle
|
|
protodown_lower_down
|
|
"
|
|
|
|
operstate_get()
|
|
{
|
|
local ns=$1; shift
|
|
local dev=$1; shift
|
|
|
|
ip -n "$ns" -j link show dev "$dev" | jq -r '.[].operstate'
|
|
}
|
|
|
|
operstate_check()
|
|
{
|
|
local ns=$1; shift
|
|
local dev=$1; shift
|
|
local expected=$1; shift
|
|
|
|
local current
|
|
current=$(operstate_get "$ns" "$dev")
|
|
|
|
[ "$current" = "$expected" ]
|
|
}
|
|
|
|
setup_prepare()
|
|
{
|
|
setup_ns NS
|
|
defer cleanup_all_ns
|
|
|
|
ip -n "$NS" link add name dummy0 up type dummy
|
|
|
|
ip -n "$NS" link add name macvlan0 link dummy0 up type macvlan mode bridge
|
|
|
|
ip -n "$NS" link add name vxlan0 up type vxlan id 10010 dstport 4789
|
|
}
|
|
|
|
protodown_basic()
|
|
{
|
|
local dev=$1; shift
|
|
|
|
ip -n "$NS" link set dev "$dev" protodown on
|
|
check_err $? "Failed to set protodown on"
|
|
|
|
busywait "$BUSYWAIT_TIMEOUT" operstate_check "$NS" "$dev" DOWN
|
|
check_err $? "Operational state is not DOWN after setting protodown"
|
|
|
|
ip -n "$NS" link set dev "$dev" protodown off
|
|
check_err $? "Failed to set protodown off"
|
|
|
|
busywait "$BUSYWAIT_TIMEOUT" operstate_check "$NS" "$dev" UP
|
|
check_err $? "Operational state is not UP after clearing protodown"
|
|
}
|
|
|
|
protodown_basic_macvlan()
|
|
{
|
|
RET=0
|
|
|
|
protodown_basic macvlan0
|
|
|
|
log_test "Basic protodown on/off with macvlan"
|
|
}
|
|
|
|
protodown_basic_vxlan()
|
|
{
|
|
RET=0
|
|
|
|
protodown_basic vxlan0
|
|
|
|
log_test "Basic protodown on/off with vxlan"
|
|
}
|
|
|
|
protodown_reasons()
|
|
{
|
|
RET=0
|
|
|
|
ip -n "$NS" link set dev macvlan0 protodown on
|
|
|
|
ip -n "$NS" link set dev macvlan0 protodown_reason 0 on
|
|
check_err $? "Failed to set protodown reason bit 0"
|
|
|
|
# Cannot clear protodown while reasons are active.
|
|
ip -n "$NS" link set dev macvlan0 protodown off 2>/dev/null
|
|
check_fail $? "Clearing protodown succeeded with active reasons"
|
|
|
|
ip -n "$NS" link set dev macvlan0 protodown_reason 0 off
|
|
check_err $? "Failed to clear protodown reason bit 0"
|
|
|
|
# Can clear protodown when no reasons are active.
|
|
ip -n "$NS" link set dev macvlan0 protodown off
|
|
check_err $? "Failed to clear protodown with no active reasons"
|
|
|
|
busywait "$BUSYWAIT_TIMEOUT" operstate_check "$NS" macvlan0 UP
|
|
check_err $? "Operational state is not UP after clearing protodown"
|
|
|
|
log_test "Protodown reasons"
|
|
}
|
|
|
|
protodown_lower_toggle()
|
|
{
|
|
RET=0
|
|
|
|
ip -n "$NS" link set dev macvlan0 protodown on
|
|
|
|
busywait "$BUSYWAIT_TIMEOUT" operstate_check "$NS" macvlan0 DOWN
|
|
check_err $? "Operational state is not DOWN after setting protodown"
|
|
|
|
# Toggle carrier on the lower device. The macvlan should stay DOWN
|
|
# because protodown is on.
|
|
ip -n "$NS" link set dev dummy0 carrier off
|
|
ip -n "$NS" link set dev dummy0 carrier on
|
|
|
|
busywait "$BUSYWAIT_TIMEOUT" operstate_check "$NS" dummy0 UP
|
|
check_err $? "Lower device is not UP after carrier on"
|
|
|
|
busywait "$BUSYWAIT_TIMEOUT" operstate_check "$NS" macvlan0 DOWN
|
|
check_err $? "Macvlan operational state is not DOWN despite protodown"
|
|
|
|
# Clear protodown and verify the macvlan comes back up.
|
|
ip -n "$NS" link set dev macvlan0 protodown off
|
|
|
|
busywait "$BUSYWAIT_TIMEOUT" operstate_check "$NS" macvlan0 UP
|
|
check_err $? "Operational state is not UP after clearing protodown"
|
|
|
|
log_test "Protodown with lower device toggled"
|
|
}
|
|
|
|
protodown_lower_down()
|
|
{
|
|
RET=0
|
|
|
|
# Bring the lower device carrier down first.
|
|
ip -n "$NS" link set dev dummy0 carrier off
|
|
|
|
busywait "$BUSYWAIT_TIMEOUT" operstate_check "$NS" macvlan0 LOWERLAYERDOWN
|
|
check_err $? "Macvlan is not LOWERLAYERDOWN with lower carrier off"
|
|
|
|
# Toggle protodown on and off while lower has no carrier. The macvlan
|
|
# should not transition to UP.
|
|
ip -n "$NS" link set dev macvlan0 protodown on
|
|
|
|
busywait "$BUSYWAIT_TIMEOUT" operstate_check "$NS" macvlan0 LOWERLAYERDOWN
|
|
check_err $? "Macvlan is not LOWERLAYERDOWN after setting protodown"
|
|
|
|
ip -n "$NS" link set dev macvlan0 protodown off
|
|
|
|
busywait "$BUSYWAIT_TIMEOUT" operstate_check "$NS" macvlan0 LOWERLAYERDOWN
|
|
check_err $? "Macvlan is not LOWERLAYERDOWN after clearing protodown"
|
|
|
|
# Bring the lower device carrier up. The macvlan should transition to
|
|
# UP.
|
|
ip -n "$NS" link set dev dummy0 carrier on
|
|
|
|
busywait "$BUSYWAIT_TIMEOUT" operstate_check "$NS" dummy0 UP
|
|
check_err $? "Lower device is not UP after carrier on"
|
|
|
|
busywait "$BUSYWAIT_TIMEOUT" operstate_check "$NS" macvlan0 UP
|
|
check_err $? "Macvlan is not UP after lower device is UP"
|
|
|
|
log_test "Protodown with lower device down"
|
|
}
|
|
|
|
trap defer_scopes_cleanup EXIT
|
|
setup_prepare
|
|
tests_run
|
|
|
|
exit "$EXIT_STATUS"
|