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 <[email protected]> --- 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

