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

Commit c331501c authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'enslavement-extack'



David Ahern says:

====================
net: Plumb extack error reporting to enslavements

Another round of extending extack error reporting, this time for
enslavements through ndo_add_slave and notifiers.

v2
- changed how the messages are added to bonding driver per Jiri's request
- fixed spectrum message for LAG overflow per Ido's comment
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 6621dd29 e58376e1
Loading
Loading
Loading
Loading
+14 −5
Original line number Diff line number Diff line
@@ -1217,14 +1217,15 @@ static enum netdev_lag_tx_type bond_lag_tx_type(struct bonding *bond)
	}
}

static int bond_master_upper_dev_link(struct bonding *bond, struct slave *slave)
static int bond_master_upper_dev_link(struct bonding *bond, struct slave *slave,
				      struct netlink_ext_ack *extack)
{
	struct netdev_lag_upper_info lag_upper_info;
	int err;

	lag_upper_info.tx_type = bond_lag_tx_type(bond);
	err = netdev_master_upper_dev_link(slave->dev, bond->dev, slave,
					   &lag_upper_info);
					   &lag_upper_info, extack);
	if (err)
		return err;
	rtmsg_ifinfo(RTM_NEWLINK, slave->dev, IFF_SLAVE, GFP_KERNEL);
@@ -1328,7 +1329,8 @@ void bond_lower_state_changed(struct slave *slave)
}

/* enslave device <slave> to bond device <master> */
int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev,
		 struct netlink_ext_ack *extack)
{
	struct bonding *bond = netdev_priv(bond_dev);
	const struct net_device_ops *slave_ops = slave_dev->netdev_ops;
@@ -1346,12 +1348,14 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)

	/* already in-use? */
	if (netdev_is_rx_handler_busy(slave_dev)) {
		NL_SET_ERR_MSG(extack, "Device is in use and cannot be enslaved");
		netdev_err(bond_dev,
			   "Error: Device is in use and cannot be enslaved\n");
		return -EBUSY;
	}

	if (bond_dev == slave_dev) {
		NL_SET_ERR_MSG(extack, "Cannot enslave bond to itself.");
		netdev_err(bond_dev, "cannot enslave bond to itself.\n");
		return -EPERM;
	}
@@ -1362,6 +1366,7 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
		netdev_dbg(bond_dev, "%s is NETIF_F_VLAN_CHALLENGED\n",
			   slave_dev->name);
		if (vlan_uses_dev(bond_dev)) {
			NL_SET_ERR_MSG(extack, "Can not enslave VLAN challenged device to VLAN enabled bond");
			netdev_err(bond_dev, "Error: cannot enslave VLAN challenged slave %s on VLAN enabled bond %s\n",
				   slave_dev->name, bond_dev->name);
			return -EPERM;
@@ -1381,6 +1386,7 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
	 * enslaving it; the old ifenslave will not.
	 */
	if (slave_dev->flags & IFF_UP) {
		NL_SET_ERR_MSG(extack, "Device can not be enslaved while up");
		netdev_err(bond_dev, "%s is up - this may be due to an out of date ifenslave\n",
			   slave_dev->name);
		return -EPERM;
@@ -1421,6 +1427,7 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
						 bond_dev);
		}
	} else if (bond_dev->type != slave_dev->type) {
		NL_SET_ERR_MSG(extack, "Device type is different from other slaves");
		netdev_err(bond_dev, "%s ether type (%d) is different from other slaves (%d), can not enslave it\n",
			   slave_dev->name, slave_dev->type, bond_dev->type);
		return -EINVAL;
@@ -1428,6 +1435,7 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)

	if (slave_dev->type == ARPHRD_INFINIBAND &&
	    BOND_MODE(bond) != BOND_MODE_ACTIVEBACKUP) {
		NL_SET_ERR_MSG(extack, "Only active-backup mode is supported for infiniband slaves");
		netdev_warn(bond_dev, "Type (%d) supports only active-backup mode\n",
			    slave_dev->type);
		res = -EOPNOTSUPP;
@@ -1443,6 +1451,7 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
				bond->params.fail_over_mac = BOND_FOM_ACTIVE;
				netdev_warn(bond_dev, "Setting fail_over_mac to active for active-backup mode\n");
			} else {
				NL_SET_ERR_MSG(extack, "Slave device does not support setting the MAC address, but fail_over_mac is not set to active");
				netdev_err(bond_dev, "The slave device specified does not support setting the MAC address, but fail_over_mac is not set to active\n");
				res = -EOPNOTSUPP;
				goto err_undo_flags;
@@ -1709,7 +1718,7 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
		goto err_detach;
	}

	res = bond_master_upper_dev_link(bond, new_slave);
	res = bond_master_upper_dev_link(bond, new_slave, extack);
	if (res) {
		netdev_dbg(bond_dev, "Error %d calling bond_master_upper_dev_link\n", res);
		goto err_unregister;
@@ -3492,7 +3501,7 @@ static int bond_do_ioctl(struct net_device *bond_dev, struct ifreq *ifr, int cmd
	switch (cmd) {
	case BOND_ENSLAVE_OLD:
	case SIOCBONDENSLAVE:
		res = bond_enslave(bond_dev, slave_dev);
		res = bond_enslave(bond_dev, slave_dev, NULL);
		break;
	case BOND_RELEASE_OLD:
	case SIOCBONDRELEASE:
+1 −1
Original line number Diff line number Diff line
@@ -1383,7 +1383,7 @@ static int bond_option_slaves_set(struct bonding *bond,
	switch (command[0]) {
	case '+':
		netdev_dbg(bond->dev, "Adding slave %s\n", dev->name);
		ret = bond_enslave(bond->dev, dev);
		ret = bond_enslave(bond->dev, dev, NULL);
		break;

	case '-':
+37 −10
Original line number Diff line number Diff line
@@ -4019,14 +4019,21 @@ static int mlxsw_sp_lag_index_get(struct mlxsw_sp *mlxsw_sp,
static bool
mlxsw_sp_master_lag_check(struct mlxsw_sp *mlxsw_sp,
			  struct net_device *lag_dev,
			  struct netdev_lag_upper_info *lag_upper_info)
			  struct netdev_lag_upper_info *lag_upper_info,
			  struct netlink_ext_ack *extack)
{
	u16 lag_id;

	if (mlxsw_sp_lag_index_get(mlxsw_sp, lag_dev, &lag_id) != 0)
	if (mlxsw_sp_lag_index_get(mlxsw_sp, lag_dev, &lag_id) != 0) {
		NL_SET_ERR_MSG(extack,
			       "spectrum: Exceeded number of supported LAG devices");
		return false;
	if (lag_upper_info->tx_type != NETDEV_LAG_TX_TYPE_HASH)
	}
	if (lag_upper_info->tx_type != NETDEV_LAG_TX_TYPE_HASH) {
		NL_SET_ERR_MSG(extack,
			       "spectrum: LAG device using unsupported Tx type");
		return false;
	}
	return true;
}

@@ -4231,6 +4238,7 @@ static int mlxsw_sp_netdevice_port_upper_event(struct net_device *lower_dev,
{
	struct netdev_notifier_changeupper_info *info;
	struct mlxsw_sp_port *mlxsw_sp_port;
	struct netlink_ext_ack *extack;
	struct net_device *upper_dev;
	struct mlxsw_sp *mlxsw_sp;
	int err = 0;
@@ -4238,6 +4246,7 @@ static int mlxsw_sp_netdevice_port_upper_event(struct net_device *lower_dev,
	mlxsw_sp_port = netdev_priv(dev);
	mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
	info = ptr;
	extack = netdev_notifier_info_to_extack(&info->info);

	switch (event) {
	case NETDEV_PRECHANGEUPPER:
@@ -4245,25 +4254,43 @@ static int mlxsw_sp_netdevice_port_upper_event(struct net_device *lower_dev,
		if (!is_vlan_dev(upper_dev) &&
		    !netif_is_lag_master(upper_dev) &&
		    !netif_is_bridge_master(upper_dev) &&
		    !netif_is_ovs_master(upper_dev))
		    !netif_is_ovs_master(upper_dev)) {
			NL_SET_ERR_MSG(extack,
				       "spectrum: Unknown upper device type");
			return -EINVAL;
		}
		if (!info->linking)
			break;
		if (netdev_has_any_upper_dev(upper_dev))
		if (netdev_has_any_upper_dev(upper_dev)) {
			NL_SET_ERR_MSG(extack,
				       "spectrum: Enslaving a port to a device that already has an upper device is not supported");
			return -EINVAL;
		}
		if (netif_is_lag_master(upper_dev) &&
		    !mlxsw_sp_master_lag_check(mlxsw_sp, upper_dev,
					       info->upper_info))
					       info->upper_info, extack))
			return -EINVAL;
		if (netif_is_lag_master(upper_dev) && vlan_uses_dev(dev))
		if (netif_is_lag_master(upper_dev) && vlan_uses_dev(dev)) {
			NL_SET_ERR_MSG(extack,
				       "spectrum: Master device is a LAG master and this device has a VLAN");
			return -EINVAL;
		}
		if (netif_is_lag_port(dev) && is_vlan_dev(upper_dev) &&
		    !netif_is_lag_master(vlan_dev_real_dev(upper_dev)))
		    !netif_is_lag_master(vlan_dev_real_dev(upper_dev))) {
			NL_SET_ERR_MSG(extack,
				       "spectrum: Can not put a VLAN on a LAG port");
			return -EINVAL;
		if (netif_is_ovs_master(upper_dev) && vlan_uses_dev(dev))
		}
		if (netif_is_ovs_master(upper_dev) && vlan_uses_dev(dev)) {
			NL_SET_ERR_MSG(extack,
				       "spectrum: Master device is an OVS master and this device has a VLAN");
			return -EINVAL;
		if (netif_is_ovs_port(dev) && is_vlan_dev(upper_dev))
		}
		if (netif_is_ovs_port(dev) && is_vlan_dev(upper_dev)) {
			NL_SET_ERR_MSG(extack,
				       "spectrum: Can not put a VLAN on an OVS port");
			return -EINVAL;
		}
		break;
	case NETDEV_CHANGEUPPER:
		upper_dev = info->upper_dev;
+1 −1
Original line number Diff line number Diff line
@@ -178,7 +178,7 @@ static int rmnet_newlink(struct net *src_net, struct net_device *dev,
	if (err)
		goto err1;

	err = netdev_master_upper_dev_link(dev, real_dev, NULL, NULL);
	err = netdev_master_upper_dev_link(dev, real_dev, NULL, NULL, extack);
	if (err)
		goto err2;

+1 −1
Original line number Diff line number Diff line
@@ -1748,7 +1748,7 @@ static int netvsc_vf_join(struct net_device *vf_netdev,
		goto rx_handler_failed;
	}

	ret = netdev_upper_dev_link(vf_netdev, ndev);
	ret = netdev_upper_dev_link(vf_netdev, ndev, NULL);
	if (ret != 0) {
		netdev_err(vf_netdev,
			   "can not set master device %s (err = %d)\n",
Loading