[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <20250926113208.07fa0b2f@kernel.org>
Date: Fri, 26 Sep 2025 11:32:08 -0700
From: Jakub Kicinski <kuba@...nel.org>
To: Breno Leitao <leitao@...ian.org>
Cc: Andrew Lunn <andrew+netdev@...n.ch>, "David S. Miller"
<davem@...emloft.net>, Eric Dumazet <edumazet@...gle.com>, Paolo Abeni
<pabeni@...hat.com>, Shuah Khan <shuah@...nel.org>, Simon Horman
<horms@...nel.org>, david decotigny <decot@...glers.com>,
linux-kernel@...r.kernel.org, netdev@...r.kernel.org,
linux-kselftest@...r.kernel.org, asantostc@...il.com, efault@....de,
calvin@...nvd.org, kernel-team@...a.com, jv@...sburgh.net
Subject: Re: [PATCH net v5 4/4] selftest: netcons: add test for netconsole
over bonded interfaces
On Fri, 26 Sep 2025 07:06:50 -0700 Breno Leitao wrote:
> > Since the bonding tests can't run on real HW it can't live directly in
> > tools/testing/selftests/drivers/net/ we need to move it to either the
> > netdevsim group or the bonding group.
>
> Are you talking abouttools/testing/selftests/drivers/net/bonding as the
> bonding group?
>
> With the changed above, this is how the selftest looks like now:
>
> Author: Breno Leitao <leitao@...ian.org>
> Date: Wed Sep 17 01:46:26 2025 -0700
>
> selftest: netcons: add test for netconsole over bonded interfaces
>
> This patch adds a selftest that verifies netconsole functionality
> over bonded network interfaces using netdevsim. It sets up two bonded
> interfaces acting as transmit (TX) and receive (RX) ends, placed in
> separate network namespaces. The test sends kernel log messages and
> verifies that they are properly received on the bonded RX interfaces
> with both IPv4 and IPv6, and using basic and extended netconsole
> formats.
>
> This patchset aims to test a long-standing netpoll are where netpoll has
> multiple users. (in this case netconsole and bonding). A similar
> selftest has been discussed in [1] and [2].
>
> This test also try to enable bonding and netpoll at the same time, and
> make sure that it fails.
>
> Link: https://lore.kernel.org/all/20250905-netconsole_torture-v3-0-875c7febd316@debian.org/ [1]
> Link: https://lore.kernel.org/lkml/96b940137a50e5c387687bb4f57de8b0435a653f.1404857349.git.decot@googlers.com/ [2]
> Signed-off-by: Breno Leitao <leitao@...ian.org>
>
> diff --git a/tools/testing/selftests/drivers/net/bonding/Makefile b/tools/testing/selftests/drivers/net/bonding/Makefile
> index 3462783ed3aca..d7fb239c02814 100644
> --- a/tools/testing/selftests/drivers/net/bonding/Makefile
> +++ b/tools/testing/selftests/drivers/net/bonding/Makefile
> @@ -8,6 +8,7 @@ TEST_PROGS := \
> dev_addr_lists.sh \
> mode-1-recovery-updelay.sh \
> mode-2-recovery-updelay.sh \
> + netcons_over_bonding.sh \
> bond_options.sh \
> bond-eth-type-change.sh \
> bond_macvlan_ipvlan.sh \
Do we need to add the netcons lib to TEST_INCLUDES ?
> diff --git a/tools/testing/selftests/drivers/net/bonding/config b/tools/testing/selftests/drivers/net/bonding/config
> index 4d16a69ffc650..c9e609ff5b5dd 100644
> --- a/tools/testing/selftests/drivers/net/bonding/config
> +++ b/tools/testing/selftests/drivers/net/bonding/config
> @@ -10,3 +10,8 @@ CONFIG_NET_CLS_MATCHALL=m
> CONFIG_NET_SCH_INGRESS=y
> CONFIG_NLMON=y
> CONFIG_VETH=y
> +CONFIG_NETDEVSIM=m
> +CONFIG_CONFIGFS_FS=y
> +CONFIG_NETCONSOLE=m
> +CONFIG_NETCONSOLE_DYNAMIC=y
> +CONFIG_NETCONSOLE_EXTENDED_LOG=y
For the config options some approximation of alphabetical sort is good.
Adding at the end increases the risk of cherry-pick / merge conflicts
dramatically.
> +function enable_netpoll_on_enslaved_iface() {
> + echo 0 > "${NETCONS_PATH}"/enabled
> +
> + # At this stage, BOND_TX1_IF is enslaved to BONDTX_IF, and linked to
> + # BOND_RX1_IF inside the namespace.
> + echo "${BOND_TX1_IF}" > "${NETCONS_PATH}"/dev_name
> +
> + # This should fail with the following message in dmesg:
> + # netpoll: netconsole: ethX is a slave device, aborting
> + set +e
> + echo 1 > "${NETCONS_PATH}"/enabled
> + set -e
> +
> + if [ "$(cat "${NETCONS_PATH}/enabled")" -eq 1 ]
> + then
> + echo "netpoll: Bonding and netpoll cannot co-exists. Test failed." >&2
> + exit "${ksft_fail}"
> +
nit: extra nl
> + fi
> +}
> +# Test #3
> +# Detach the interface from a bonding interface and attach netpoll again
> +delete_bond_and_reenable_target
> +echo "test #3: Able to attach to an unbound interface. Test passed." >&2
Do we need a fouth case? Enable netpoll on an interface and then try to
enslave it while netpoll is active, then try to enable netpoll on the
bond?
And possibly a couple of cases where we set up netpoll on the bond
first, then we add to bond (success and fail case).
> +cleanup_bond
> +trap - EXIT
> +exit "${EXIT_STATUS}"
> diff --git a/tools/testing/selftests/drivers/net/lib/sh/lib_netcons.sh b/tools/testing/selftests/drivers/net/lib/sh/lib_netcons.sh
> index 9b5ef8074440c..4862d025b7c74 100644
> --- a/tools/testing/selftests/drivers/net/lib/sh/lib_netcons.sh
> +++ b/tools/testing/selftests/drivers/net/lib/sh/lib_netcons.sh
> @@ -28,17 +28,24 @@ NETCONS_PATH="${NETCONS_CONFIGFS}"/"${TARGET}"
> # NAMESPACE will be populated by setup_ns with a random value
> NAMESPACE=""
>
> -# IDs for netdevsim
> +# IDs for netdevsim. We either use NSIM_DEV_{1,2}_ID for standard test
> +# or NSIM_BOND_{T,R}X_{1,2} for the bonding tests. Not both at the
> +# same time.
> NSIM_DEV_1_ID=$((256 + RANDOM % 256))
> NSIM_DEV_2_ID=$((512 + RANDOM % 256))
> +NSIM_BOND_TX_1=$((768 + RANDOM % 256))
> +NSIM_BOND_TX_2=$((1024 + RANDOM % 256))
> +NSIM_BOND_RX_1=$((1280 + RANDOM % 256))
> +NSIM_BOND_RX_2=$((1536 + RANDOM % 256))
> NSIM_DEV_SYS_NEW="/sys/bus/netdevsim/new_device"
> +NSIM_DEV_SYS_LINK="/sys/bus/netdevsim/link_device"
> +NSIM_DEV_SYS_DEL="/sys/bus/netdevsim/del_device"
>
> # Used to create and delete namespaces
> source "${LIBDIR}"/../../../../net/lib.sh
>
> # Create netdevsim interfaces
> create_ifaces() {
> -
> echo "$NSIM_DEV_2_ID" > "$NSIM_DEV_SYS_NEW"
> echo "$NSIM_DEV_1_ID" > "$NSIM_DEV_SYS_NEW"
> udevadm settle 2> /dev/null || true
> @@ -54,7 +61,6 @@ create_ifaces() {
> }
>
> link_ifaces() {
> - local NSIM_DEV_SYS_LINK="/sys/bus/netdevsim/link_device"
> local SRCIF_IFIDX=$(cat /sys/class/net/"$SRCIF"/ifindex)
> local DSTIF_IFIDX=$(cat /sys/class/net/"$DSTIF"/ifindex)
>
> @@ -96,6 +102,33 @@ function select_ipv4_or_ipv6()
> fi
> }
>
> +# Create 4 netdevsim interfaces. Two of them will be bound to TX bonding iface
> +# and the other two will be bond to the RX interface (on the other namespace)
> +function create_ifaces_bond() {
> + echo "$NSIM_BOND_TX_1" > "$NSIM_DEV_SYS_NEW"
> + echo "$NSIM_BOND_TX_2" > "$NSIM_DEV_SYS_NEW"
> + echo "$NSIM_BOND_RX_1" > "$NSIM_DEV_SYS_NEW"
> + echo "$NSIM_BOND_RX_2" > "$NSIM_DEV_SYS_NEW"
> + udevadm settle 2> /dev/null || true
> +
> + local BOND_TX1=/sys/bus/netdevsim/devices/netdevsim"$NSIM_BOND_TX_1"
> + local BOND_TX2=/sys/bus/netdevsim/devices/netdevsim"$NSIM_BOND_TX_2"
> + local BOND_RX1=/sys/bus/netdevsim/devices/netdevsim"$NSIM_BOND_RX_1"
> + local BOND_RX2=/sys/bus/netdevsim/devices/netdevsim"$NSIM_BOND_RX_2"
> +
> + # TX
> + BOND_TX1_IF=$(find "$BOND_TX1"/net -maxdepth 1 -type d ! \
> + -path "$BOND_TX1"/net -exec basename {} \; | grep -v net)
> + BOND_TX2_IF=$(find "$BOND_TX2"/net -maxdepth 1 -type d ! \
> + -path "$BOND_TX2"/net -exec basename {} \; | grep -v net)
> +
> + # RX
> + BOND_RX1_IF=$(find "$BOND_RX1"/net -maxdepth 1 -type d ! \
> + -path "$BOND_RX1"/net -exec basename {} \; | grep -v net)
> + BOND_RX2_IF=$(find "$BOND_RX2"/net -maxdepth 1 -type d ! \
> + -path "$BOND_RX2"/net -exec basename {} \; | grep -v net)
> +}
> +
> function set_network() {
> local IP_VERSION=${1:-"ipv4"}
>
> @@ -180,8 +213,6 @@ function disable_release_append() {
> }
>
> function do_cleanup() {
> - local NSIM_DEV_SYS_DEL="/sys/bus/netdevsim/del_device"
> -
> # Delete netdevsim devices
> echo "$NSIM_DEV_2_ID" > "$NSIM_DEV_SYS_DEL"
> echo "$NSIM_DEV_1_ID" > "$NSIM_DEV_SYS_DEL"
> @@ -193,14 +224,26 @@ function do_cleanup() {
> echo "${DEFAULT_PRINTK_VALUES}" > /proc/sys/kernel/printk
> }
>
> -function cleanup() {
> +function cleanup_netcons() {
> # delete netconsole dynamic reconfiguration
> - echo 0 > "${NETCONS_PATH}"/enabled
> + # do not fail if the target is already disabled
> + if [[ ! -d "${NETCONS_PATH}" ]]
> + then
> + # in some cases this is called before netcons path is created
> + return
> + fi
> + if [[ $(cat "${NETCONS_PATH}"/enabled) != 0 ]]
> + then
> + echo 0 > "${NETCONS_PATH}"/enabled || true
> + fi
> # Remove all the keys that got created during the selftest
> find "${NETCONS_PATH}/userdata/" -mindepth 1 -type d -delete
> # Remove the configfs entry
> rmdir "${NETCONS_PATH}"
> +}
>
> +function cleanup() {
> + cleanup_netcons
> do_cleanup
> }
>
> @@ -377,3 +420,105 @@ function wait_for_port() {
> # more frequently on IPv6
> sleep 1
> }
> +
> +# netdevsim link BOND_TX to BOND_RX interfaces
> +function link_ifaces_bond() {
> + local BOND_TX1_IFIDX
> + local BOND_TX2_IFIDX
> + local BOND_RX1_IFIDX
> + local BOND_RX2_IFIDX
> +
> + BOND_TX1_IFIDX=$(cat /sys/class/net/"$BOND_TX1_IF"/ifindex)
> + BOND_TX2_IFIDX=$(cat /sys/class/net/"$BOND_TX2_IF"/ifindex)
> + BOND_RX1_IFIDX=$(cat /sys/class/net/"$BOND_RX1_IF"/ifindex)
> + BOND_RX2_IFIDX=$(cat /sys/class/net/"$BOND_RX2_IF"/ifindex)
> +
> + exec {NAMESPACE_FD}</var/run/netns/"${NAMESPACE}"
> + exec {INITNS_FD}</proc/self/ns/net
> +
> + # Bind the dst interfaces to namespace
> + ip link set "${BOND_RX1_IF}" netns "${NAMESPACE}"
> + ip link set "${BOND_RX2_IF}" netns "${NAMESPACE}"
> +
> + # Linking TX ifaces to the RX ones (on the other namespace}
> + echo "${INITNS_FD}:$BOND_TX1_IFIDX $NAMESPACE_FD:$BOND_RX1_IFIDX" \
> + > "$NSIM_DEV_SYS_LINK"
> + echo "${INITNS_FD}:$BOND_TX2_IFIDX $NAMESPACE_FD:$BOND_RX2_IFIDX" \
> + > "$NSIM_DEV_SYS_LINK"
> +}
> +
> +# Create "bond_tx_XX" and "bond_rx_XX" interfaces, and set DSTIF and SRCIF with
> +# the bonding interfaces
> +function setup_bonding_ifaces() {
> + local RAND=$(( RANDOM % 100 ))
> + BONDTX_IF="bond_tx_$RAND"
> + BONDRX_IF="bond_rx_$RAND"
> +
> + if ! ip link add "${BONDTX_IF}" type bond mode balance-rr
> + then
> + echo "Failed to create bond TX interface. Is CONFIG_BONDING set?" >&2
> + # only clean nsim ifaces and namespace. Nothing else has been
> + # initialized
> + cleanup_bond_nsim
> + trap - EXIT
> + exit "${ksft_skip}"
> + fi
> + ip link set "${BOND_TX1_IF}" down
> + ip link set "${BOND_TX2_IF}" down
> +
> + ip link set "${BOND_TX1_IF}" master "${BONDTX_IF}"
> + ip link set "${BOND_TX2_IF}" master "${BONDTX_IF}"
> + ip link set "${BONDTX_IF}" up
> +
> + # now create the RX bonding iface
> + ip netns exec "${NAMESPACE}" \
> + ip link add "${BONDRX_IF}" type bond mode balance-rr
> + ip netns exec "${NAMESPACE}" \
> + ip link set "${BOND_RX1_IF}" down
> + ip netns exec "${NAMESPACE}" \
> + ip link set "${BOND_RX2_IF}" down
> +
> + ip netns exec "${NAMESPACE}" \
> + ip link set "${BOND_RX1_IF}" master "${BONDRX_IF}"
> + ip netns exec "${NAMESPACE}" \
> + ip link set "${BOND_RX2_IF}" master "${BONDRX_IF}"
> + ip netns exec "${NAMESPACE}" \
> + ip link set "${BONDRX_IF}" up
> + ip netns exec "${NAMESPACE}" \
> + ip link set "${BOND_RX1_IF}" up
> + ip netns exec "${NAMESPACE}" \
> + ip link set "${BOND_RX2_IF}" up
> +
> +}
> +
> +# Clean up netdevsim ifaces created for bonding test
> +function cleanup_bond_nsim() {
> + echo "$NSIM_BOND_TX_1" > "$NSIM_DEV_SYS_DEL"
> + echo "$NSIM_BOND_TX_2" > "$NSIM_DEV_SYS_DEL"
> + echo "$NSIM_BOND_RX_1" > "$NSIM_DEV_SYS_DEL"
> + echo "$NSIM_BOND_RX_2" > "$NSIM_DEV_SYS_DEL"
> + cleanup_all_ns
> +}
> +
> +# cleanup tests that use bonding interfaces
> +function cleanup_bond() {
> + cleanup_netcons
> +
> + # Delete TX ifaces
> + ip link set "${BONDTX_IF}" down 2> /dev/null|| true
> + ip link set "${BOND_TX1_IF}" down || true
> + ip link set "${BOND_TX2_IF}" down || true
> + ip link delete "${BONDTX_IF}" type bond 2> /dev/null || true
> +
> + # Delete RX ifaces
> + ip netns exec "${NAMESPACE}" \
> + ip link set "${BONDRX_IF}" down || true
> + ip netns exec "${NAMESPACE}" \
> + ip link set "${BOND_RX1_IF}" down || true
> + ip netns exec "${NAMESPACE}" \
> + ip link set "${BOND_RX2_IF}" down || true
> + ip netns exec "${NAMESPACE}" \
> + ip link delete "${BONDRX_IF}" type bond || true
> +
> + cleanup_bond_nsim
> +}
>
>
Powered by blists - more mailing lists