Skip to content

Commit c331501

Browse files
committed
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: David S. Miller <[email protected]>
2 parents 6621dd2 + e58376e commit c331501

File tree

27 files changed

+192
-97
lines changed

27 files changed

+192
-97
lines changed

drivers/net/bonding/bond_main.c

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1217,14 +1217,15 @@ static enum netdev_lag_tx_type bond_lag_tx_type(struct bonding *bond)
12171217
}
12181218
}
12191219

1220-
static int bond_master_upper_dev_link(struct bonding *bond, struct slave *slave)
1220+
static int bond_master_upper_dev_link(struct bonding *bond, struct slave *slave,
1221+
struct netlink_ext_ack *extack)
12211222
{
12221223
struct netdev_lag_upper_info lag_upper_info;
12231224
int err;
12241225

12251226
lag_upper_info.tx_type = bond_lag_tx_type(bond);
12261227
err = netdev_master_upper_dev_link(slave->dev, bond->dev, slave,
1227-
&lag_upper_info);
1228+
&lag_upper_info, extack);
12281229
if (err)
12291230
return err;
12301231
rtmsg_ifinfo(RTM_NEWLINK, slave->dev, IFF_SLAVE, GFP_KERNEL);
@@ -1328,7 +1329,8 @@ void bond_lower_state_changed(struct slave *slave)
13281329
}
13291330

13301331
/* enslave device <slave> to bond device <master> */
1331-
int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
1332+
int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev,
1333+
struct netlink_ext_ack *extack)
13321334
{
13331335
struct bonding *bond = netdev_priv(bond_dev);
13341336
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)
13461348

13471349
/* already in-use? */
13481350
if (netdev_is_rx_handler_busy(slave_dev)) {
1351+
NL_SET_ERR_MSG(extack, "Device is in use and cannot be enslaved");
13491352
netdev_err(bond_dev,
13501353
"Error: Device is in use and cannot be enslaved\n");
13511354
return -EBUSY;
13521355
}
13531356

13541357
if (bond_dev == slave_dev) {
1358+
NL_SET_ERR_MSG(extack, "Cannot enslave bond to itself.");
13551359
netdev_err(bond_dev, "cannot enslave bond to itself.\n");
13561360
return -EPERM;
13571361
}
@@ -1362,6 +1366,7 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
13621366
netdev_dbg(bond_dev, "%s is NETIF_F_VLAN_CHALLENGED\n",
13631367
slave_dev->name);
13641368
if (vlan_uses_dev(bond_dev)) {
1369+
NL_SET_ERR_MSG(extack, "Can not enslave VLAN challenged device to VLAN enabled bond");
13651370
netdev_err(bond_dev, "Error: cannot enslave VLAN challenged slave %s on VLAN enabled bond %s\n",
13661371
slave_dev->name, bond_dev->name);
13671372
return -EPERM;
@@ -1381,6 +1386,7 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
13811386
* enslaving it; the old ifenslave will not.
13821387
*/
13831388
if (slave_dev->flags & IFF_UP) {
1389+
NL_SET_ERR_MSG(extack, "Device can not be enslaved while up");
13841390
netdev_err(bond_dev, "%s is up - this may be due to an out of date ifenslave\n",
13851391
slave_dev->name);
13861392
return -EPERM;
@@ -1421,13 +1427,15 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
14211427
bond_dev);
14221428
}
14231429
} else if (bond_dev->type != slave_dev->type) {
1430+
NL_SET_ERR_MSG(extack, "Device type is different from other slaves");
14241431
netdev_err(bond_dev, "%s ether type (%d) is different from other slaves (%d), can not enslave it\n",
14251432
slave_dev->name, slave_dev->type, bond_dev->type);
14261433
return -EINVAL;
14271434
}
14281435

14291436
if (slave_dev->type == ARPHRD_INFINIBAND &&
14301437
BOND_MODE(bond) != BOND_MODE_ACTIVEBACKUP) {
1438+
NL_SET_ERR_MSG(extack, "Only active-backup mode is supported for infiniband slaves");
14311439
netdev_warn(bond_dev, "Type (%d) supports only active-backup mode\n",
14321440
slave_dev->type);
14331441
res = -EOPNOTSUPP;
@@ -1443,6 +1451,7 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
14431451
bond->params.fail_over_mac = BOND_FOM_ACTIVE;
14441452
netdev_warn(bond_dev, "Setting fail_over_mac to active for active-backup mode\n");
14451453
} else {
1454+
NL_SET_ERR_MSG(extack, "Slave device does not support setting the MAC address, but fail_over_mac is not set to active");
14461455
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");
14471456
res = -EOPNOTSUPP;
14481457
goto err_undo_flags;
@@ -1709,7 +1718,7 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
17091718
goto err_detach;
17101719
}
17111720

1712-
res = bond_master_upper_dev_link(bond, new_slave);
1721+
res = bond_master_upper_dev_link(bond, new_slave, extack);
17131722
if (res) {
17141723
netdev_dbg(bond_dev, "Error %d calling bond_master_upper_dev_link\n", res);
17151724
goto err_unregister;
@@ -3492,7 +3501,7 @@ static int bond_do_ioctl(struct net_device *bond_dev, struct ifreq *ifr, int cmd
34923501
switch (cmd) {
34933502
case BOND_ENSLAVE_OLD:
34943503
case SIOCBONDENSLAVE:
3495-
res = bond_enslave(bond_dev, slave_dev);
3504+
res = bond_enslave(bond_dev, slave_dev, NULL);
34963505
break;
34973506
case BOND_RELEASE_OLD:
34983507
case SIOCBONDRELEASE:

drivers/net/bonding/bond_options.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1383,7 +1383,7 @@ static int bond_option_slaves_set(struct bonding *bond,
13831383
switch (command[0]) {
13841384
case '+':
13851385
netdev_dbg(bond->dev, "Adding slave %s\n", dev->name);
1386-
ret = bond_enslave(bond->dev, dev);
1386+
ret = bond_enslave(bond->dev, dev, NULL);
13871387
break;
13881388

13891389
case '-':

drivers/net/ethernet/mellanox/mlxsw/spectrum.c

Lines changed: 37 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4019,14 +4019,21 @@ static int mlxsw_sp_lag_index_get(struct mlxsw_sp *mlxsw_sp,
40194019
static bool
40204020
mlxsw_sp_master_lag_check(struct mlxsw_sp *mlxsw_sp,
40214021
struct net_device *lag_dev,
4022-
struct netdev_lag_upper_info *lag_upper_info)
4022+
struct netdev_lag_upper_info *lag_upper_info,
4023+
struct netlink_ext_ack *extack)
40234024
{
40244025
u16 lag_id;
40254026

4026-
if (mlxsw_sp_lag_index_get(mlxsw_sp, lag_dev, &lag_id) != 0)
4027+
if (mlxsw_sp_lag_index_get(mlxsw_sp, lag_dev, &lag_id) != 0) {
4028+
NL_SET_ERR_MSG(extack,
4029+
"spectrum: Exceeded number of supported LAG devices");
40274030
return false;
4028-
if (lag_upper_info->tx_type != NETDEV_LAG_TX_TYPE_HASH)
4031+
}
4032+
if (lag_upper_info->tx_type != NETDEV_LAG_TX_TYPE_HASH) {
4033+
NL_SET_ERR_MSG(extack,
4034+
"spectrum: LAG device using unsupported Tx type");
40294035
return false;
4036+
}
40304037
return true;
40314038
}
40324039

@@ -4231,39 +4238,59 @@ static int mlxsw_sp_netdevice_port_upper_event(struct net_device *lower_dev,
42314238
{
42324239
struct netdev_notifier_changeupper_info *info;
42334240
struct mlxsw_sp_port *mlxsw_sp_port;
4241+
struct netlink_ext_ack *extack;
42344242
struct net_device *upper_dev;
42354243
struct mlxsw_sp *mlxsw_sp;
42364244
int err = 0;
42374245

42384246
mlxsw_sp_port = netdev_priv(dev);
42394247
mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
42404248
info = ptr;
4249+
extack = netdev_notifier_info_to_extack(&info->info);
42414250

42424251
switch (event) {
42434252
case NETDEV_PRECHANGEUPPER:
42444253
upper_dev = info->upper_dev;
42454254
if (!is_vlan_dev(upper_dev) &&
42464255
!netif_is_lag_master(upper_dev) &&
42474256
!netif_is_bridge_master(upper_dev) &&
4248-
!netif_is_ovs_master(upper_dev))
4257+
!netif_is_ovs_master(upper_dev)) {
4258+
NL_SET_ERR_MSG(extack,
4259+
"spectrum: Unknown upper device type");
42494260
return -EINVAL;
4261+
}
42504262
if (!info->linking)
42514263
break;
4252-
if (netdev_has_any_upper_dev(upper_dev))
4264+
if (netdev_has_any_upper_dev(upper_dev)) {
4265+
NL_SET_ERR_MSG(extack,
4266+
"spectrum: Enslaving a port to a device that already has an upper device is not supported");
42534267
return -EINVAL;
4268+
}
42544269
if (netif_is_lag_master(upper_dev) &&
42554270
!mlxsw_sp_master_lag_check(mlxsw_sp, upper_dev,
4256-
info->upper_info))
4271+
info->upper_info, extack))
42574272
return -EINVAL;
4258-
if (netif_is_lag_master(upper_dev) && vlan_uses_dev(dev))
4273+
if (netif_is_lag_master(upper_dev) && vlan_uses_dev(dev)) {
4274+
NL_SET_ERR_MSG(extack,
4275+
"spectrum: Master device is a LAG master and this device has a VLAN");
42594276
return -EINVAL;
4277+
}
42604278
if (netif_is_lag_port(dev) && is_vlan_dev(upper_dev) &&
4261-
!netif_is_lag_master(vlan_dev_real_dev(upper_dev)))
4279+
!netif_is_lag_master(vlan_dev_real_dev(upper_dev))) {
4280+
NL_SET_ERR_MSG(extack,
4281+
"spectrum: Can not put a VLAN on a LAG port");
42624282
return -EINVAL;
4263-
if (netif_is_ovs_master(upper_dev) && vlan_uses_dev(dev))
4283+
}
4284+
if (netif_is_ovs_master(upper_dev) && vlan_uses_dev(dev)) {
4285+
NL_SET_ERR_MSG(extack,
4286+
"spectrum: Master device is an OVS master and this device has a VLAN");
42644287
return -EINVAL;
4265-
if (netif_is_ovs_port(dev) && is_vlan_dev(upper_dev))
4288+
}
4289+
if (netif_is_ovs_port(dev) && is_vlan_dev(upper_dev)) {
4290+
NL_SET_ERR_MSG(extack,
4291+
"spectrum: Can not put a VLAN on an OVS port");
42664292
return -EINVAL;
4293+
}
42674294
break;
42684295
case NETDEV_CHANGEUPPER:
42694296
upper_dev = info->upper_dev;

drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,7 @@ static int rmnet_newlink(struct net *src_net, struct net_device *dev,
178178
if (err)
179179
goto err1;
180180

181-
err = netdev_master_upper_dev_link(dev, real_dev, NULL, NULL);
181+
err = netdev_master_upper_dev_link(dev, real_dev, NULL, NULL, extack);
182182
if (err)
183183
goto err2;
184184

drivers/net/hyperv/netvsc_drv.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1748,7 +1748,7 @@ static int netvsc_vf_join(struct net_device *vf_netdev,
17481748
goto rx_handler_failed;
17491749
}
17501750

1751-
ret = netdev_upper_dev_link(vf_netdev, ndev);
1751+
ret = netdev_upper_dev_link(vf_netdev, ndev, NULL);
17521752
if (ret != 0) {
17531753
netdev_err(vf_netdev,
17541754
"can not set master device %s (err = %d)\n",

drivers/net/ipvlan/ipvlan_main.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -584,7 +584,7 @@ int ipvlan_link_new(struct net *src_net, struct net_device *dev,
584584
if (err < 0)
585585
goto remove_ida;
586586

587-
err = netdev_upper_dev_link(phy_dev, dev);
587+
err = netdev_upper_dev_link(phy_dev, dev, extack);
588588
if (err) {
589589
goto unregister_netdev;
590590
}

drivers/net/macsec.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3244,7 +3244,7 @@ static int macsec_newlink(struct net *net, struct net_device *dev,
32443244
&macsec_netdev_addr_lock_key,
32453245
macsec_get_nest_level(dev));
32463246

3247-
err = netdev_upper_dev_link(real_dev, dev);
3247+
err = netdev_upper_dev_link(real_dev, dev, extack);
32483248
if (err < 0)
32493249
goto unregister;
32503250

drivers/net/macvlan.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1344,7 +1344,8 @@ static int macvlan_changelink_sources(struct macvlan_dev *vlan, u32 mode,
13441344
}
13451345

13461346
int macvlan_common_newlink(struct net *src_net, struct net_device *dev,
1347-
struct nlattr *tb[], struct nlattr *data[])
1347+
struct nlattr *tb[], struct nlattr *data[],
1348+
struct netlink_ext_ack *extack)
13481349
{
13491350
struct macvlan_dev *vlan = netdev_priv(dev);
13501351
struct macvlan_port *port;
@@ -1433,7 +1434,7 @@ int macvlan_common_newlink(struct net *src_net, struct net_device *dev,
14331434
goto destroy_macvlan_port;
14341435

14351436
dev->priv_flags |= IFF_MACVLAN;
1436-
err = netdev_upper_dev_link(lowerdev, dev);
1437+
err = netdev_upper_dev_link(lowerdev, dev, extack);
14371438
if (err)
14381439
goto unregister_netdev;
14391440

@@ -1456,7 +1457,7 @@ static int macvlan_newlink(struct net *src_net, struct net_device *dev,
14561457
struct nlattr *tb[], struct nlattr *data[],
14571458
struct netlink_ext_ack *extack)
14581459
{
1459-
return macvlan_common_newlink(src_net, dev, tb, data);
1460+
return macvlan_common_newlink(src_net, dev, tb, data, extack);
14601461
}
14611462

14621463
void macvlan_dellink(struct net_device *dev, struct list_head *head)

drivers/net/macvtap.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ static int macvtap_newlink(struct net *src_net, struct net_device *dev,
105105
/* Don't put anything that may fail after macvlan_common_newlink
106106
* because we can't undo what it does.
107107
*/
108-
err = macvlan_common_newlink(src_net, dev, tb, data);
108+
err = macvlan_common_newlink(src_net, dev, tb, data, extack);
109109
if (err) {
110110
netdev_rx_handler_unregister(dev);
111111
return err;

drivers/net/team/team.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1112,7 +1112,7 @@ static int team_upper_dev_link(struct team *team, struct team_port *port)
11121112

11131113
lag_upper_info.tx_type = team->mode->lag_tx_type;
11141114
err = netdev_master_upper_dev_link(port->dev, team->dev, NULL,
1115-
&lag_upper_info);
1115+
&lag_upper_info, NULL);
11161116
if (err)
11171117
return err;
11181118
port->dev->priv_flags |= IFF_TEAM_PORT;
@@ -1914,7 +1914,8 @@ static int team_netpoll_setup(struct net_device *dev,
19141914
}
19151915
#endif
19161916

1917-
static int team_add_slave(struct net_device *dev, struct net_device *port_dev)
1917+
static int team_add_slave(struct net_device *dev, struct net_device *port_dev,
1918+
struct netlink_ext_ack *extack)
19181919
{
19191920
struct team *team = netdev_priv(dev);
19201921
int err;

drivers/net/usb/qmi_wwan.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,7 @@ static int qmimux_register_device(struct net_device *real_dev, u8 mux_id)
221221
/* Account for reference in struct qmimux_priv_priv */
222222
dev_hold(real_dev);
223223

224-
err = netdev_upper_dev_link(real_dev, new_dev);
224+
err = netdev_upper_dev_link(real_dev, new_dev, NULL);
225225
if (err)
226226
goto out_unregister_netdev;
227227

drivers/net/vrf.c

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -764,18 +764,22 @@ static void cycle_netdev(struct net_device *dev)
764764
}
765765
}
766766

767-
static int do_vrf_add_slave(struct net_device *dev, struct net_device *port_dev)
767+
static int do_vrf_add_slave(struct net_device *dev, struct net_device *port_dev,
768+
struct netlink_ext_ack *extack)
768769
{
769770
int ret;
770771

771772
/* do not allow loopback device to be enslaved to a VRF.
772773
* The vrf device acts as the loopback for the vrf.
773774
*/
774-
if (port_dev == dev_net(dev)->loopback_dev)
775+
if (port_dev == dev_net(dev)->loopback_dev) {
776+
NL_SET_ERR_MSG(extack,
777+
"Can not enslave loopback device to a VRF");
775778
return -EOPNOTSUPP;
779+
}
776780

777781
port_dev->priv_flags |= IFF_L3MDEV_SLAVE;
778-
ret = netdev_master_upper_dev_link(port_dev, dev, NULL, NULL);
782+
ret = netdev_master_upper_dev_link(port_dev, dev, NULL, NULL, extack);
779783
if (ret < 0)
780784
goto err;
781785

@@ -788,12 +792,19 @@ static int do_vrf_add_slave(struct net_device *dev, struct net_device *port_dev)
788792
return ret;
789793
}
790794

791-
static int vrf_add_slave(struct net_device *dev, struct net_device *port_dev)
795+
static int vrf_add_slave(struct net_device *dev, struct net_device *port_dev,
796+
struct netlink_ext_ack *extack)
792797
{
793-
if (netif_is_l3_master(port_dev) || netif_is_l3_slave(port_dev))
798+
if (netif_is_l3_master(port_dev)) {
799+
NL_SET_ERR_MSG(extack,
800+
"Can not enslave an L3 master device to a VRF");
801+
return -EINVAL;
802+
}
803+
804+
if (netif_is_l3_slave(port_dev))
794805
return -EINVAL;
795806

796-
return do_vrf_add_slave(dev, port_dev);
807+
return do_vrf_add_slave(dev, port_dev, extack);
797808
}
798809

799810
/* inverse of do_vrf_add_slave */

include/linux/if_macvlan.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,8 @@ static inline void macvlan_count_rx(const struct macvlan_dev *vlan,
7272
extern void macvlan_common_setup(struct net_device *dev);
7373

7474
extern int macvlan_common_newlink(struct net *src_net, struct net_device *dev,
75-
struct nlattr *tb[], struct nlattr *data[]);
75+
struct nlattr *tb[], struct nlattr *data[],
76+
struct netlink_ext_ack *extack);
7677

7778
extern void macvlan_count_rx(const struct macvlan_dev *vlan,
7879
unsigned int len, bool success,

0 commit comments

Comments
 (0)