Skip to content

Commit ef2df7f

Browse files
committed
Merge branch 'Pass-extack-to-NETDEV_PRE_UP'
Petr Machata says: ==================== Pass extack to NETDEV_PRE_UP Drivers may need to validate configuration of a device that's about to be upped. An example is mlxsw, which needs to check the configuration of a VXLAN device attached to an offloaded bridge. Should the validation fail, there's currently no way to communicate details of the failure to the user, beyond an error number. Therefore this patch set extends the NETDEV_PRE_UP event to include extack, if available. There are three vectors through which NETDEV_PRE_UP invocation can be reached. The two major ones are dev_open() and dev_change_flags(), the last is then __dev_change_flags(). In patch #1, the first access vector, dev_open() is addressed. An extack parameter is added and all users converted to use it. Before addressing the second vector, two preparatory patches propagate extack argument to the proximity of the dev_change_flags() call in VRF and IPVLAN drivers. That happens in patches #2 and #3. Then in patch #4, dev_change_flags() is treated similarly to dev_open(). Likewise in patch #5, __dev_change_flags() is extended. Then in patches #6 and #7, the extack is finally propagated all the way to the point where the notification is emitted. This change allows particularly mlxsw (which already has code to leverage extack if available) to communicate to the user error messages regarding VXLAN configuration. In patch #8, add a test case that exercises this code and checks that an error message is propagated. For example: local 192.0.2.17 remote 192.0.2.18 \ dstport 4789 nolearning noudpcsum tos inherit ttl 100 local 192.0.2.17 remote 192.0.2.18 \ dstport 4789 nolearning noudpcsum tos inherit ttl 100 Error: mlxsw_spectrum: Conflicting NVE tunnels configuration. v2: - Add David Ahern's tags. ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents fdb8b29 + 1ba1dae commit ef2df7f

File tree

36 files changed

+182
-71
lines changed

36 files changed

+182
-71
lines changed

drivers/infiniband/ulp/ipoib/ipoib_main.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ int ipoib_open(struct net_device *dev)
167167
if (flags & IFF_UP)
168168
continue;
169169

170-
dev_change_flags(cpriv->dev, flags | IFF_UP);
170+
dev_change_flags(cpriv->dev, flags | IFF_UP, NULL);
171171
}
172172
up_read(&priv->vlan_rwsem);
173173
}
@@ -207,7 +207,7 @@ static int ipoib_stop(struct net_device *dev)
207207
if (!(flags & IFF_UP))
208208
continue;
209209

210-
dev_change_flags(cpriv->dev, flags & ~IFF_UP);
210+
dev_change_flags(cpriv->dev, flags & ~IFF_UP, NULL);
211211
}
212212
up_read(&priv->vlan_rwsem);
213213
}
@@ -1823,7 +1823,7 @@ static void ipoib_parent_unregister_pre(struct net_device *ndev)
18231823
* running ensures the it will not add more work.
18241824
*/
18251825
rtnl_lock();
1826-
dev_change_flags(priv->dev, priv->dev->flags & ~IFF_UP);
1826+
dev_change_flags(priv->dev, priv->dev->flags & ~IFF_UP, NULL);
18271827
rtnl_unlock();
18281828

18291829
/* ipoib_event() cannot be running once this returns */

drivers/net/bonding/bond_main.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1538,7 +1538,7 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev,
15381538
slave_dev->flags |= IFF_SLAVE;
15391539

15401540
/* open the slave since the application closed it */
1541-
res = dev_open(slave_dev);
1541+
res = dev_open(slave_dev, extack);
15421542
if (res) {
15431543
netdev_dbg(bond_dev, "Opening slave %s failed\n", slave_dev->name);
15441544
goto err_restore_mac;

drivers/net/ethernet/aquantia/atlantic/aq_ethtool.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -525,7 +525,7 @@ static int aq_set_ringparam(struct net_device *ndev,
525525
}
526526
}
527527
if (ndev_running)
528-
err = dev_open(ndev);
528+
err = dev_open(ndev, NULL);
529529

530530
err_exit:
531531
return err;

drivers/net/ethernet/cisco/enic/enic_ethtool.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,7 @@ static int enic_set_ringparam(struct net_device *netdev,
241241
}
242242
enic_init_vnic_resources(enic);
243243
if (running) {
244-
err = dev_open(netdev);
244+
err = dev_open(netdev, NULL);
245245
if (err)
246246
goto err_out;
247247
}

drivers/net/ethernet/hisilicon/hns/hns_ethtool.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -624,7 +624,7 @@ static void hns_nic_self_test(struct net_device *ndev,
624624
clear_bit(NIC_STATE_TESTING, &priv->state);
625625

626626
if (if_running)
627-
(void)dev_open(ndev);
627+
(void)dev_open(ndev, NULL);
628628
}
629629
/* Online tests aren't run; pass by default */
630630

drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -821,7 +821,7 @@ static int hns3_set_ringparam(struct net_device *ndev,
821821
}
822822

823823
if (if_running)
824-
ret = dev_open(ndev);
824+
ret = dev_open(ndev, NULL);
825825

826826
return ret;
827827
}

drivers/net/ethernet/sfc/ethtool.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -539,7 +539,7 @@ static void efx_ethtool_self_test(struct net_device *net_dev,
539539
/* We need rx buffers and interrupts. */
540540
already_up = (efx->net_dev->flags & IFF_UP);
541541
if (!already_up) {
542-
rc = dev_open(efx->net_dev);
542+
rc = dev_open(efx->net_dev, NULL);
543543
if (rc) {
544544
netif_err(efx, drv, efx->net_dev,
545545
"failed opening device.\n");

drivers/net/ethernet/sfc/falcon/ethtool.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -517,7 +517,7 @@ static void ef4_ethtool_self_test(struct net_device *net_dev,
517517
/* We need rx buffers and interrupts. */
518518
already_up = (efx->net_dev->flags & IFF_UP);
519519
if (!already_up) {
520-
rc = dev_open(efx->net_dev);
520+
rc = dev_open(efx->net_dev, NULL);
521521
if (rc) {
522522
netif_err(efx, drv, efx->net_dev,
523523
"failed opening device.\n");

drivers/net/ethernet/stmicro/stmmac/stmmac_main.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4082,7 +4082,7 @@ static void stmmac_reset_subtask(struct stmmac_priv *priv)
40824082

40834083
set_bit(STMMAC_DOWN, &priv->state);
40844084
dev_close(priv->dev);
4085-
dev_open(priv->dev);
4085+
dev_open(priv->dev, NULL);
40864086
clear_bit(STMMAC_DOWN, &priv->state);
40874087
clear_bit(STMMAC_RESETING, &priv->state);
40884088
rtnl_unlock();

drivers/net/hyperv/netvsc_drv.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ static int netvsc_open(struct net_device *net)
137137
* slave as up. If open fails, then slave will be
138138
* still be offline (and not used).
139139
*/
140-
ret = dev_open(vf_netdev);
140+
ret = dev_open(vf_netdev, NULL);
141141
if (ret)
142142
netdev_warn(net,
143143
"unable to open slave: %s: %d\n",
@@ -1993,7 +1993,7 @@ static void __netvsc_vf_setup(struct net_device *ndev,
19931993
"unable to change mtu to %u\n", ndev->mtu);
19941994

19951995
/* set multicast etc flags on VF */
1996-
dev_change_flags(vf_netdev, ndev->flags | IFF_SLAVE);
1996+
dev_change_flags(vf_netdev, ndev->flags | IFF_SLAVE, NULL);
19971997

19981998
/* sync address list from ndev to VF */
19991999
netif_addr_lock_bh(ndev);
@@ -2002,7 +2002,7 @@ static void __netvsc_vf_setup(struct net_device *ndev,
20022002
netif_addr_unlock_bh(ndev);
20032003

20042004
if (netif_running(ndev)) {
2005-
ret = dev_open(vf_netdev);
2005+
ret = dev_open(vf_netdev, NULL);
20062006
if (ret)
20072007
netdev_warn(vf_netdev,
20082008
"unable to open: %d\n", ret);

drivers/net/ipvlan/ipvlan_main.c

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,8 @@ static void ipvlan_unregister_nf_hook(struct net *net)
7171
ARRAY_SIZE(ipvl_nfops));
7272
}
7373

74-
static int ipvlan_set_port_mode(struct ipvl_port *port, u16 nval)
74+
static int ipvlan_set_port_mode(struct ipvl_port *port, u16 nval,
75+
struct netlink_ext_ack *extack)
7576
{
7677
struct ipvl_dev *ipvlan;
7778
struct net_device *mdev = port->dev;
@@ -84,10 +85,12 @@ static int ipvlan_set_port_mode(struct ipvl_port *port, u16 nval)
8485
flags = ipvlan->dev->flags;
8586
if (nval == IPVLAN_MODE_L3 || nval == IPVLAN_MODE_L3S) {
8687
err = dev_change_flags(ipvlan->dev,
87-
flags | IFF_NOARP);
88+
flags | IFF_NOARP,
89+
extack);
8890
} else {
8991
err = dev_change_flags(ipvlan->dev,
90-
flags & ~IFF_NOARP);
92+
flags & ~IFF_NOARP,
93+
extack);
9194
}
9295
if (unlikely(err))
9396
goto fail;
@@ -116,9 +119,11 @@ static int ipvlan_set_port_mode(struct ipvl_port *port, u16 nval)
116119
flags = ipvlan->dev->flags;
117120
if (port->mode == IPVLAN_MODE_L3 ||
118121
port->mode == IPVLAN_MODE_L3S)
119-
dev_change_flags(ipvlan->dev, flags | IFF_NOARP);
122+
dev_change_flags(ipvlan->dev, flags | IFF_NOARP,
123+
NULL);
120124
else
121-
dev_change_flags(ipvlan->dev, flags & ~IFF_NOARP);
125+
dev_change_flags(ipvlan->dev, flags & ~IFF_NOARP,
126+
NULL);
122127
}
123128

124129
return err;
@@ -498,7 +503,7 @@ static int ipvlan_nl_changelink(struct net_device *dev,
498503
if (data[IFLA_IPVLAN_MODE]) {
499504
u16 nmode = nla_get_u16(data[IFLA_IPVLAN_MODE]);
500505

501-
err = ipvlan_set_port_mode(port, nmode);
506+
err = ipvlan_set_port_mode(port, nmode, extack);
502507
}
503508

504509
if (!err && data[IFLA_IPVLAN_FLAGS]) {
@@ -672,7 +677,7 @@ int ipvlan_link_new(struct net *src_net, struct net_device *dev,
672677
if (data && data[IFLA_IPVLAN_MODE])
673678
mode = nla_get_u16(data[IFLA_IPVLAN_MODE]);
674679

675-
err = ipvlan_set_port_mode(port, mode);
680+
err = ipvlan_set_port_mode(port, mode, extack);
676681
if (err)
677682
goto unlink_netdev;
678683

drivers/net/net_failover.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,14 +40,14 @@ static int net_failover_open(struct net_device *dev)
4040

4141
primary_dev = rtnl_dereference(nfo_info->primary_dev);
4242
if (primary_dev) {
43-
err = dev_open(primary_dev);
43+
err = dev_open(primary_dev, NULL);
4444
if (err)
4545
goto err_primary_open;
4646
}
4747

4848
standby_dev = rtnl_dereference(nfo_info->standby_dev);
4949
if (standby_dev) {
50-
err = dev_open(standby_dev);
50+
err = dev_open(standby_dev, NULL);
5151
if (err)
5252
goto err_standby_open;
5353
}
@@ -517,7 +517,7 @@ static int net_failover_slave_register(struct net_device *slave_dev,
517517
dev_hold(slave_dev);
518518

519519
if (netif_running(failover_dev)) {
520-
err = dev_open(slave_dev);
520+
err = dev_open(slave_dev, NULL);
521521
if (err && (err != -EBUSY)) {
522522
netdev_err(failover_dev, "Opening slave %s failed err:%d\n",
523523
slave_dev->name, err);
@@ -680,7 +680,7 @@ static int net_failover_slave_name_change(struct net_device *slave_dev,
680680
/* We need to bring up the slave after the rename by udev in case
681681
* open failed with EBUSY when it was registered.
682682
*/
683-
dev_open(slave_dev);
683+
dev_open(slave_dev, NULL);
684684

685685
return 0;
686686
}

drivers/net/team/team.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1212,7 +1212,7 @@ static int team_port_add(struct team *team, struct net_device *port_dev,
12121212
goto err_port_enter;
12131213
}
12141214

1215-
err = dev_open(port_dev);
1215+
err = dev_open(port_dev, extack);
12161216
if (err) {
12171217
netdev_dbg(dev, "Device %s opening failed\n",
12181218
portname);

drivers/net/vrf.c

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -747,17 +747,18 @@ static int vrf_rtable_create(struct net_device *dev)
747747
/**************************** device handling ********************/
748748

749749
/* cycle interface to flush neighbor cache and move routes across tables */
750-
static void cycle_netdev(struct net_device *dev)
750+
static void cycle_netdev(struct net_device *dev,
751+
struct netlink_ext_ack *extack)
751752
{
752753
unsigned int flags = dev->flags;
753754
int ret;
754755

755756
if (!netif_running(dev))
756757
return;
757758

758-
ret = dev_change_flags(dev, flags & ~IFF_UP);
759+
ret = dev_change_flags(dev, flags & ~IFF_UP, extack);
759760
if (ret >= 0)
760-
ret = dev_change_flags(dev, flags);
761+
ret = dev_change_flags(dev, flags, extack);
761762

762763
if (ret < 0) {
763764
netdev_err(dev,
@@ -785,7 +786,7 @@ static int do_vrf_add_slave(struct net_device *dev, struct net_device *port_dev,
785786
if (ret < 0)
786787
goto err;
787788

788-
cycle_netdev(port_dev);
789+
cycle_netdev(port_dev, extack);
789790

790791
return 0;
791792

@@ -815,7 +816,7 @@ static int do_vrf_del_slave(struct net_device *dev, struct net_device *port_dev)
815816
netdev_upper_dev_unlink(port_dev, dev);
816817
port_dev->priv_flags &= ~IFF_L3MDEV_SLAVE;
817818

818-
cycle_netdev(port_dev);
819+
cycle_netdev(port_dev, NULL);
819820

820821
return 0;
821822
}

drivers/net/wireless/intersil/hostap/hostap_main.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -690,7 +690,7 @@ static int prism2_open(struct net_device *dev)
690690
/* Master radio interface is needed for all operation, so open
691691
* it automatically when any virtual net_device is opened. */
692692
local->master_dev_auto_open = 1;
693-
dev_open(local->dev);
693+
dev_open(local->dev, NULL);
694694
}
695695

696696
netif_device_attach(dev);

drivers/s390/net/qeth_l2_main.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1007,7 +1007,7 @@ static int __qeth_l2_set_online(struct ccwgroup_device *gdev, int recovery_mode)
10071007
qeth_l2_set_rx_mode(card->dev);
10081008
} else {
10091009
rtnl_lock();
1010-
dev_open(card->dev);
1010+
dev_open(card->dev, NULL);
10111011
rtnl_unlock();
10121012
}
10131013
}

drivers/s390/net/qeth_l3_main.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2417,7 +2417,7 @@ static int __qeth_l3_set_online(struct ccwgroup_device *gdev, int recovery_mode)
24172417
__qeth_l3_open(card->dev);
24182418
qeth_l3_set_rx_mode(card->dev);
24192419
} else {
2420-
dev_open(card->dev);
2420+
dev_open(card->dev, NULL);
24212421
}
24222422
rtnl_unlock();
24232423
}

drivers/staging/fsl-dpaa2/ethsw/ethsw.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1172,7 +1172,7 @@ static int ethsw_open(struct ethsw_core *ethsw)
11721172

11731173
for (i = 0; i < ethsw->sw_attr.num_ifs; i++) {
11741174
port_priv = ethsw->ports[i];
1175-
err = dev_open(port_priv->netdev);
1175+
err = dev_open(port_priv->netdev, NULL);
11761176
if (err) {
11771177
netdev_err(port_priv->netdev, "dev_open err %d\n", err);
11781178
return err;

drivers/staging/unisys/visornic/visornic_main.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2095,7 +2095,7 @@ static int visornic_resume(struct visor_device *dev,
20952095
mod_timer(&devdata->irq_poll_timer, msecs_to_jiffies(2));
20962096

20972097
rtnl_lock();
2098-
dev_open(netdev);
2098+
dev_open(netdev, NULL);
20992099
rtnl_unlock();
21002100

21012101
complete_func(dev, 0);

include/linux/netdevice.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2605,7 +2605,7 @@ struct net_device *dev_get_by_name(struct net *net, const char *name);
26052605
struct net_device *dev_get_by_name_rcu(struct net *net, const char *name);
26062606
struct net_device *__dev_get_by_name(struct net *net, const char *name);
26072607
int dev_alloc_name(struct net_device *dev, const char *name);
2608-
int dev_open(struct net_device *dev);
2608+
int dev_open(struct net_device *dev, struct netlink_ext_ack *extack);
26092609
void dev_close(struct net_device *dev);
26102610
void dev_close_many(struct list_head *head, bool unlink);
26112611
void dev_disable_lro(struct net_device *dev);
@@ -3611,8 +3611,10 @@ int dev_ioctl(struct net *net, unsigned int cmd, struct ifreq *ifr,
36113611
int dev_ifconf(struct net *net, struct ifconf *, int);
36123612
int dev_ethtool(struct net *net, struct ifreq *);
36133613
unsigned int dev_get_flags(const struct net_device *);
3614-
int __dev_change_flags(struct net_device *, unsigned int flags);
3615-
int dev_change_flags(struct net_device *, unsigned int);
3614+
int __dev_change_flags(struct net_device *dev, unsigned int flags,
3615+
struct netlink_ext_ack *extack);
3616+
int dev_change_flags(struct net_device *dev, unsigned int flags,
3617+
struct netlink_ext_ack *extack);
36163618
void __dev_notify_flags(struct net_device *, unsigned int old_flags,
36173619
unsigned int gchanges);
36183620
int dev_change_name(struct net_device *, const char *);

net/8021q/vlan.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -358,6 +358,7 @@ static int __vlan_device_event(struct net_device *dev, unsigned long event)
358358
static int vlan_device_event(struct notifier_block *unused, unsigned long event,
359359
void *ptr)
360360
{
361+
struct netlink_ext_ack *extack = netdev_notifier_info_to_extack(ptr);
361362
struct net_device *dev = netdev_notifier_info_to_dev(ptr);
362363
struct vlan_group *grp;
363364
struct vlan_info *vlan_info;
@@ -460,7 +461,8 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event,
460461

461462
vlan = vlan_dev_priv(vlandev);
462463
if (!(vlan->flags & VLAN_FLAG_LOOSE_BINDING))
463-
dev_change_flags(vlandev, flgs | IFF_UP);
464+
dev_change_flags(vlandev, flgs | IFF_UP,
465+
extack);
464466
netif_stacked_transfer_operstate(dev, vlandev);
465467
}
466468
break;

net/bluetooth/6lowpan.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -607,7 +607,7 @@ static void ifup(struct net_device *netdev)
607607
int err;
608608

609609
rtnl_lock();
610-
err = dev_open(netdev);
610+
err = dev_open(netdev, NULL);
611611
if (err < 0)
612612
BT_INFO("iface %s cannot be opened (%d)", netdev->name, err);
613613
rtnl_unlock();

0 commit comments

Comments
 (0)