* [PATCH net-next 1/5] netdevsim: Add ethtool get_link support
2026-05-10 16:43 [PATCH net-next 0/5] netdevsim: get link via ethtool, set via sysfs Íñigo Huguet
@ 2026-05-10 16:43 ` Íñigo Huguet
2026-05-10 16:43 ` [PATCH net-next 2/5] netdevsim: allow changing carrier state via sysfs Íñigo Huguet
` (4 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Íñigo Huguet @ 2026-05-10 16:43 UTC (permalink / raw)
To: Jakub Kicinski, Andrew Lunn, David S . Miller, Eric Dumazet,
Paolo Abeni, Shuah Khan
Cc: Sabrina Dubroca, Filip Pokryvka, netdev, linux-kernel,
linux-kselftest, Íñigo Huguet
From: Filip Pokryvka <fpokryvk@redhat.com>
Add ethtool get_link callback to netdevsim. They are devices that have
the concept of a carrier, so it makes sense that it can be queried via
ethtool too, like ethernet devices.
Signed-off-by: Filip Pokryvka <fpokryvk@redhat.com>
---
drivers/net/netdevsim/ethtool.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/net/netdevsim/ethtool.c b/drivers/net/netdevsim/ethtool.c
index 36a201533aae..4d47eb989c24 100644
--- a/drivers/net/netdevsim/ethtool.c
+++ b/drivers/net/netdevsim/ethtool.c
@@ -209,6 +209,7 @@ static const struct ethtool_ops nsim_ethtool_ops = {
.supported_coalesce_params = ETHTOOL_COALESCE_ALL_PARAMS,
.supported_ring_params = ETHTOOL_RING_USE_TCP_DATA_SPLIT |
ETHTOOL_RING_USE_HDS_THRS,
+ .get_link = ethtool_op_get_link,
.get_pause_stats = nsim_get_pause_stats,
.get_pauseparam = nsim_get_pauseparam,
.set_pauseparam = nsim_set_pauseparam,
--
2.53.0
^ permalink raw reply related [flat|nested] 7+ messages in thread* [PATCH net-next 2/5] netdevsim: allow changing carrier state via sysfs
2026-05-10 16:43 [PATCH net-next 0/5] netdevsim: get link via ethtool, set via sysfs Íñigo Huguet
2026-05-10 16:43 ` [PATCH net-next 1/5] netdevsim: Add ethtool get_link support Íñigo Huguet
@ 2026-05-10 16:43 ` Íñigo Huguet
2026-05-10 16:43 ` [PATCH net-next 3/5] selftest: netdevsim: test carrier change " Íñigo Huguet
` (3 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Íñigo Huguet @ 2026-05-10 16:43 UTC (permalink / raw)
To: Jakub Kicinski, Andrew Lunn, David S . Miller, Eric Dumazet,
Paolo Abeni, Shuah Khan
Cc: Sabrina Dubroca, Filip Pokryvka, netdev, linux-kernel,
linux-kselftest, Íñigo Huguet
Currently it is only possible to change it by linking a peer netdevsim
and setting the peer's state to down.
Allow to change the carrier state when having a single netdevsim device
without any peer, by writing to it's carrier attribute in sysfs:
/sys/bus/netdevsim/devices/netdevsimX/net/eniYynpZ/carrier. This might
be useful for carrier related tests where a peer device is not needed
for anything else.
If it's linked with a peer, change the carrier of both, while they stay
administratively up. The alternative would be to return EOPNOTSUPP, but
that doesn't seem very intuitive. Also, there is no reason why it should
not be supported, it simulates the cable being cut or disconnected, for
example.
Signed-off-by: Íñigo Huguet <ihuguet@riseup.net>
---
drivers/net/netdevsim/netdev.c | 23 +++++++++++++++++++++++
1 file changed, 23 insertions(+)
diff --git a/drivers/net/netdevsim/netdev.c b/drivers/net/netdevsim/netdev.c
index a750768912b5..4f77c9171b06 100644
--- a/drivers/net/netdevsim/netdev.c
+++ b/drivers/net/netdevsim/netdev.c
@@ -616,6 +616,28 @@ static void nsim_shaper_cap(struct net_shaper_binding *binding,
*flags = ULONG_MAX;
}
+static int nsim_change_carrier(struct net_device *dev, bool new_carrier)
+{
+ struct netdevsim *ns = netdev_priv(dev);
+ struct netdevsim *peer;
+
+ netdev_assert_locked(dev);
+
+ peer = rtnl_dereference(ns->peer);
+
+ if (new_carrier) {
+ netif_carrier_on(dev);
+ if (peer)
+ netif_carrier_on(peer->netdev);
+ } else {
+ netif_carrier_off(dev);
+ if (peer)
+ netif_carrier_off(peer->netdev);
+ }
+
+ return 0;
+}
+
static const struct net_shaper_ops nsim_shaper_ops = {
.set = nsim_shaper_set,
.delete = nsim_shaper_del,
@@ -645,6 +667,7 @@ static const struct net_device_ops nsim_netdev_ops = {
.ndo_stop = nsim_stop,
.ndo_vlan_rx_add_vid = nsim_vlan_rx_add_vid,
.ndo_vlan_rx_kill_vid = nsim_vlan_rx_kill_vid,
+ .ndo_change_carrier = nsim_change_carrier,
.net_shaper_ops = &nsim_shaper_ops,
};
--
2.53.0
^ permalink raw reply related [flat|nested] 7+ messages in thread* [PATCH net-next 3/5] selftest: netdevsim: test carrier change via sysfs
2026-05-10 16:43 [PATCH net-next 0/5] netdevsim: get link via ethtool, set via sysfs Íñigo Huguet
2026-05-10 16:43 ` [PATCH net-next 1/5] netdevsim: Add ethtool get_link support Íñigo Huguet
2026-05-10 16:43 ` [PATCH net-next 2/5] netdevsim: allow changing carrier state via sysfs Íñigo Huguet
@ 2026-05-10 16:43 ` Íñigo Huguet
2026-05-10 16:43 ` [PATCH net-next 4/5] selftest: netdevsim: cleanup the devices and module on failure Íñigo Huguet
` (2 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Íñigo Huguet @ 2026-05-10 16:43 UTC (permalink / raw)
To: Jakub Kicinski, Andrew Lunn, David S . Miller, Eric Dumazet,
Paolo Abeni, Shuah Khan
Cc: Sabrina Dubroca, Filip Pokryvka, netdev, linux-kernel,
linux-kselftest, Íñigo Huguet
The previous commits allowed to change the carrier state via the sysfs
carrier attribute and to get the carrier state via ethtool. Add
selftest for it.
Signed-off-by: Íñigo Huguet <ihuguet@riseup.net>
---
.../selftests/drivers/net/netdevsim/peer.sh | 59 +++++++++++++++----
1 file changed, 48 insertions(+), 11 deletions(-)
diff --git a/tools/testing/selftests/drivers/net/netdevsim/peer.sh b/tools/testing/selftests/drivers/net/netdevsim/peer.sh
index f4721f7636dd..5e7b6c1d0bfb 100755
--- a/tools/testing/selftests/drivers/net/netdevsim/peer.sh
+++ b/tools/testing/selftests/drivers/net/netdevsim/peer.sh
@@ -52,21 +52,17 @@ cleanup_ns()
ip netns del nssv
}
-is_carrier_up()
-{
- local netns="$1"
- local nsim_dev="$2"
-
- test "$(ip netns exec "$netns" \
- cat /sys/class/net/"$nsim_dev"/carrier 2>/dev/null)" -eq 1
-}
-
assert_carrier_up()
{
local netns="$1"
local nsim_dev="$2"
- if ! is_carrier_up "$netns" "$nsim_dev"; then
+ local sysfs_carrier="$(ip netns exec "$netns" \
+ cat /sys/class/net/"$nsim_dev"/carrier 2>/dev/null)"
+ local ethtool_carrier="$(ip netns exec "$netns" \
+ ethtool -j "$nsim_dev" | jq '.[0]["link-detected"]' 2>/dev/null)"
+
+ if [ "$sysfs_carrier" -ne 1 -o "$ethtool_carrier" != "true" ]; then
echo "$nsim_dev's carrier should be UP, but it isn't"
cleanup_ns
exit 1
@@ -78,13 +74,36 @@ assert_carrier_down()
local netns="$1"
local nsim_dev="$2"
- if is_carrier_up "$netns" "$nsim_dev"; then
+ local sysfs_carrier="$(ip netns exec "$netns" \
+ cat /sys/class/net/"$nsim_dev"/carrier 2>/dev/null)"
+ local ethtool_carrier="$(ip netns exec "$netns" \
+ ethtool -j "$nsim_dev" | jq '.[0]["link-detected"]' 2>/dev/null)"
+
+ if [ "$sysfs_carrier" -ne 0 -o "$ethtool_carrier" != "false" ]; then
echo "$nsim_dev's carrier should be DOWN, but it isn't"
cleanup_ns
exit 1
fi
}
+set_carrier_up()
+{
+ local netns="$1"
+ local nsim_dev="$2"
+
+ ip netns exec "$netns" \
+ sh -c "echo 1 > /sys/class/net/$nsim_dev/carrier" 2>/dev/null
+}
+
+set_carrier_down()
+{
+ local netns="$1"
+ local nsim_dev="$2"
+
+ ip netns exec "$netns" \
+ sh -c "echo 0 > /sys/class/net/$nsim_dev/carrier" 2>/dev/null
+}
+
###
### Code start
###
@@ -161,6 +180,14 @@ ip netns exec nssv ip link set dev "$NSIM_DEV_1_NAME" up
assert_carrier_down nssv "$NSIM_DEV_1_NAME"
assert_carrier_down nscl "$NSIM_DEV_2_NAME"
+set_carrier_up nssv "$NSIM_DEV_1_NAME"
+
+assert_carrier_up nssv "$NSIM_DEV_1_NAME"
+assert_carrier_down nscl "$NSIM_DEV_2_NAME"
+
+set_carrier_down nssv "$NSIM_DEV_1_NAME"
+assert_carrier_down nssv "$NSIM_DEV_1_NAME"
+
echo "$NSIM_DEV_1_FD:$NSIM_DEV_1_IFIDX $NSIM_DEV_2_FD:$NSIM_DEV_2_IFIDX" > $NSIM_DEV_SYS_LINK
assert_carrier_up nssv "$NSIM_DEV_1_NAME"
@@ -172,6 +199,16 @@ ip netns exec nssv ip link set dev "$NSIM_DEV_1_NAME" up
assert_carrier_up nssv "$NSIM_DEV_1_NAME"
assert_carrier_up nscl "$NSIM_DEV_2_NAME"
+set_carrier_down nssv "$NSIM_DEV_1_NAME"
+
+assert_carrier_down nssv "$NSIM_DEV_1_NAME"
+assert_carrier_down nscl "$NSIM_DEV_2_NAME"
+
+set_carrier_up nscl "$NSIM_DEV_2_NAME"
+
+assert_carrier_up nssv "$NSIM_DEV_1_NAME"
+assert_carrier_up nscl "$NSIM_DEV_2_NAME"
+
# send/recv packets
tmp_file=$(mktemp)
--
2.53.0
^ permalink raw reply related [flat|nested] 7+ messages in thread* [PATCH net-next 4/5] selftest: netdevsim: cleanup the devices and module on failure
2026-05-10 16:43 [PATCH net-next 0/5] netdevsim: get link via ethtool, set via sysfs Íñigo Huguet
` (2 preceding siblings ...)
2026-05-10 16:43 ` [PATCH net-next 3/5] selftest: netdevsim: test carrier change " Íñigo Huguet
@ 2026-05-10 16:43 ` Íñigo Huguet
2026-05-10 16:43 ` [PATCH net-next 5/5] selftest: netdevsim: suppress socat warnings Íñigo Huguet
2026-05-10 16:52 ` [PATCH net-next 0/5] netdevsim: get link via ethtool, set via sysfs Jakub Kicinski
5 siblings, 0 replies; 7+ messages in thread
From: Íñigo Huguet @ 2026-05-10 16:43 UTC (permalink / raw)
To: Jakub Kicinski, Andrew Lunn, David S . Miller, Eric Dumazet,
Paolo Abeni, Shuah Khan
Cc: Sabrina Dubroca, Filip Pokryvka, netdev, linux-kernel,
linux-kselftest, Íñigo Huguet
In case of failures only the netns were cleaned, leaving behind the
netdevsim devices created for the test and the module loaded. On
failure, delete the devices and unload the module.
Signed-off-by: Íñigo Huguet <ihuguet@riseup.net>
---
.../selftests/drivers/net/netdevsim/peer.sh | 21 ++++++-------------
1 file changed, 6 insertions(+), 15 deletions(-)
diff --git a/tools/testing/selftests/drivers/net/netdevsim/peer.sh b/tools/testing/selftests/drivers/net/netdevsim/peer.sh
index 5e7b6c1d0bfb..ec96015bc9eb 100755
--- a/tools/testing/selftests/drivers/net/netdevsim/peer.sh
+++ b/tools/testing/selftests/drivers/net/netdevsim/peer.sh
@@ -46,10 +46,13 @@ setup_ns()
set +e
}
-cleanup_ns()
+cleanup()
{
ip netns del nscl
ip netns del nssv
+ echo $NSIM_DEV_2_ID > $NSIM_DEV_SYS_DEL
+ echo $NSIM_DEV_1_ID > $NSIM_DEV_SYS_DEL
+ modprobe -r netdevsim
}
assert_carrier_up()
@@ -64,7 +67,6 @@ assert_carrier_up()
if [ "$sysfs_carrier" -ne 1 -o "$ethtool_carrier" != "true" ]; then
echo "$nsim_dev's carrier should be UP, but it isn't"
- cleanup_ns
exit 1
fi
}
@@ -81,7 +83,6 @@ assert_carrier_down()
if [ "$sysfs_carrier" -ne 0 -o "$ethtool_carrier" != "false" ]; then
echo "$nsim_dev's carrier should be DOWN, but it isn't"
- cleanup_ns
exit 1
fi
}
@@ -120,6 +121,8 @@ udevadm settle
setup_ns
+trap cleanup EXIT
+
NSIM_DEV_1_FD=$((256 + RANDOM % 256))
exec {NSIM_DEV_1_FD}</var/run/netns/nssv
NSIM_DEV_1_IFIDX=$(ip netns exec nssv cat /sys/class/net/$NSIM_DEV_1_NAME/ifindex)
@@ -131,28 +134,24 @@ NSIM_DEV_2_IFIDX=$(ip netns exec nscl cat /sys/class/net/$NSIM_DEV_2_NAME/ifinde
echo "$NSIM_DEV_1_FD:$NSIM_DEV_1_IFIDX $NSIM_DEV_2_FD:2000" > $NSIM_DEV_SYS_LINK 2>/dev/null
if [ $? -eq 0 ]; then
echo "linking with non-existent netdevsim should fail"
- cleanup_ns
exit 1
fi
echo "$NSIM_DEV_1_FD:$NSIM_DEV_1_IFIDX 2000:$NSIM_DEV_2_IFIDX" > $NSIM_DEV_SYS_LINK 2>/dev/null
if [ $? -eq 0 ]; then
echo "linking with non-existent netnsid should fail"
- cleanup_ns
exit 1
fi
echo "$NSIM_DEV_1_FD:$NSIM_DEV_1_IFIDX $NSIM_DEV_1_FD:$NSIM_DEV_1_IFIDX" > $NSIM_DEV_SYS_LINK 2>/dev/null
if [ $? -eq 0 ]; then
echo "linking with self should fail"
- cleanup_ns
exit 1
fi
echo "$NSIM_DEV_1_FD:$NSIM_DEV_1_IFIDX $NSIM_DEV_2_FD:$NSIM_DEV_2_IFIDX" > $NSIM_DEV_SYS_LINK
if [ $? -ne 0 ]; then
echo "linking netdevsim1 with netdevsim2 should succeed"
- cleanup_ns
exit 1
fi
@@ -161,7 +160,6 @@ fi
echo "$NSIM_DEV_1_FD:$NSIM_DEV_1_IFIDX $NSIM_DEV_2_FD:a" > $NSIM_DEV_SYS_LINK 2>/dev/null
if [ $? -eq 0 ]; then
echo "invalid arg should fail"
- cleanup_ns
exit 1
fi
@@ -228,13 +226,6 @@ fi
echo "$NSIM_DEV_1_FD:$NSIM_DEV_1_IFIDX" > $NSIM_DEV_SYS_UNLINK
-echo $NSIM_DEV_2_ID > $NSIM_DEV_SYS_DEL
-
kill $pid
-echo $NSIM_DEV_1_ID > $NSIM_DEV_SYS_DEL
-
-cleanup_ns
-
-modprobe -r netdevsim
exit $res
--
2.53.0
^ permalink raw reply related [flat|nested] 7+ messages in thread* [PATCH net-next 5/5] selftest: netdevsim: suppress socat warnings
2026-05-10 16:43 [PATCH net-next 0/5] netdevsim: get link via ethtool, set via sysfs Íñigo Huguet
` (3 preceding siblings ...)
2026-05-10 16:43 ` [PATCH net-next 4/5] selftest: netdevsim: cleanup the devices and module on failure Íñigo Huguet
@ 2026-05-10 16:43 ` Íñigo Huguet
2026-05-10 16:52 ` [PATCH net-next 0/5] netdevsim: get link via ethtool, set via sysfs Jakub Kicinski
5 siblings, 0 replies; 7+ messages in thread
From: Íñigo Huguet @ 2026-05-10 16:43 UTC (permalink / raw)
To: Jakub Kicinski, Andrew Lunn, David S . Miller, Eric Dumazet,
Paolo Abeni, Shuah Khan
Cc: Sabrina Dubroca, Filip Pokryvka, netdev, linux-kernel,
linux-kselftest, Íñigo Huguet
When executing the peer.sh selftest, socat emits these 2 warnings:
socat[116839] W address is opened in read-write mode but only supports read-only
socat[116833] W exiting on signal 15
The first one is because socat tries to open in read-write mode by
default, but STDIN can only be opened in read mode. Fix it by adding the
-u option (unidirectional left-to-right).
The second is because 'kill' is used to terminate the first socat process.
Suppress this warning by redirecting its stderr to /dev/null
Signed-off-by: Íñigo Huguet <ihuguet@riseup.net>
---
tools/testing/selftests/drivers/net/netdevsim/peer.sh | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/tools/testing/selftests/drivers/net/netdevsim/peer.sh b/tools/testing/selftests/drivers/net/netdevsim/peer.sh
index ec96015bc9eb..183a130c6e4b 100755
--- a/tools/testing/selftests/drivers/net/netdevsim/peer.sh
+++ b/tools/testing/selftests/drivers/net/netdevsim/peer.sh
@@ -210,13 +210,13 @@ assert_carrier_up nscl "$NSIM_DEV_2_NAME"
# send/recv packets
tmp_file=$(mktemp)
-ip netns exec nssv socat TCP-LISTEN:1234,fork $tmp_file &
+ip netns exec nssv socat TCP-LISTEN:1234,fork $tmp_file 2>/dev/null &
pid=$!
res=0
wait_local_port_listen nssv 1234 tcp
-echo "HI" | ip netns exec nscl socat STDIN TCP:192.168.1.1:1234
+echo "HI" | ip netns exec nscl socat -u STDIN TCP:192.168.1.1:1234
count=$(cat $tmp_file | wc -c)
if [[ $count -ne 3 ]]; then
--
2.53.0
^ permalink raw reply related [flat|nested] 7+ messages in thread* Re: [PATCH net-next 0/5] netdevsim: get link via ethtool, set via sysfs
2026-05-10 16:43 [PATCH net-next 0/5] netdevsim: get link via ethtool, set via sysfs Íñigo Huguet
` (4 preceding siblings ...)
2026-05-10 16:43 ` [PATCH net-next 5/5] selftest: netdevsim: suppress socat warnings Íñigo Huguet
@ 2026-05-10 16:52 ` Jakub Kicinski
5 siblings, 0 replies; 7+ messages in thread
From: Jakub Kicinski @ 2026-05-10 16:52 UTC (permalink / raw)
To: Íñigo Huguet
Cc: Andrew Lunn, David S . Miller, Eric Dumazet, Paolo Abeni,
Shuah Khan, Sabrina Dubroca, Filip Pokryvka, netdev, linux-kernel,
linux-kselftest
On Sun, 10 May 2026 18:43:32 +0200 Íñigo Huguet wrote:
> Allow to read the carrier status of a netdevsim device via ethtool, like
> most of Ethernet devices allow.
>
> Also, allow to set its carrier status via sysfs. Currently it's only
> possible by linking a peer device and setting its admin state to
> UP/DOWN. By editing the carrier status via sysfs tests that need to
> check carrier related stuff may be simpler.
>
> The third patch add the proper selftest for both things, and the fourth
> and fifth fix a few small bugs in the selftest itself.
Could you please explain your motivation? Feels quite trivial,
so it's not immediately obvious why we need tests.
^ permalink raw reply [flat|nested] 7+ messages in thread