Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2315dc91 authored by Veaceslav Falico's avatar Veaceslav Falico Committed by David S. Miller
Browse files

net: make dev_set_mtu() honor notification return code



Currently, after changing the MTU for a device, dev_set_mtu() calls
NETDEV_CHANGEMTU notification, however doesn't verify it's return code -
which can be NOTIFY_BAD - i.e. some of the net notifier blocks refused this
change, and continues nevertheless.

To fix this, verify the return code, and if it's an error - then revert the
MTU to the original one, notify again and pass the error code.

CC: Jiri Pirko <jiri@resnulli.us>
CC: "David S. Miller" <davem@davemloft.net>
CC: Eric Dumazet <edumazet@google.com>
CC: Alexander Duyck <alexander.h.duyck@intel.com>
CC: Nicolas Dichtel <nicolas.dichtel@6wind.com>
Signed-off-by: default avatarVeaceslav Falico <vfalico@redhat.com>
Reviewed-by: default avatarJiri Pirko <jiri@resnulli.us>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 7e11daa7
Loading
Loading
Loading
Loading
+25 −9
Original line number Diff line number Diff line
@@ -5300,6 +5300,17 @@ int dev_change_flags(struct net_device *dev, unsigned int flags)
}
EXPORT_SYMBOL(dev_change_flags);

static int __dev_set_mtu(struct net_device *dev, int new_mtu)
{
	const struct net_device_ops *ops = dev->netdev_ops;

	if (ops->ndo_change_mtu)
		return ops->ndo_change_mtu(dev, new_mtu);

	dev->mtu = new_mtu;
	return 0;
}

/**
 *	dev_set_mtu - Change maximum transfer unit
 *	@dev: device
@@ -5309,8 +5320,7 @@ EXPORT_SYMBOL(dev_change_flags);
 */
int dev_set_mtu(struct net_device *dev, int new_mtu)
{
	const struct net_device_ops *ops = dev->netdev_ops;
	int err;
	int err, orig_mtu;

	if (new_mtu == dev->mtu)
		return 0;
@@ -5322,14 +5332,20 @@ int dev_set_mtu(struct net_device *dev, int new_mtu)
	if (!netif_device_present(dev))
		return -ENODEV;

	err = 0;
	if (ops->ndo_change_mtu)
		err = ops->ndo_change_mtu(dev, new_mtu);
	else
		dev->mtu = new_mtu;
	orig_mtu = dev->mtu;
	err = __dev_set_mtu(dev, new_mtu);

	if (!err)
	if (!err) {
		err = call_netdevice_notifiers(NETDEV_CHANGEMTU, dev);
		err = notifier_to_errno(err);
		if (err) {
			/* setting mtu back and notifying everyone again,
			 * so that they have a chance to revert changes.
			 */
			__dev_set_mtu(dev, orig_mtu);
			call_netdevice_notifiers(NETDEV_CHANGEMTU, dev);
		}
	}
	return err;
}
EXPORT_SYMBOL(dev_set_mtu);