All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH net-next v2 0/8] Pass extack to NETDEV_PRE_UP
@ 2018-12-06 17:05 Petr Machata
  2018-12-06 17:05 ` [PATCH net-next v2 1/8] net: core: dev: Add extack argument to dev_open() Petr Machata
                   ` (8 more replies)
  0 siblings, 9 replies; 10+ messages in thread
From: Petr Machata @ 2018-12-06 17:05 UTC (permalink / raw)
  To: netdev; +Cc: David S. Miller, Jiri Pirko, Ido Schimmel, David Ahern

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:

# ip link add name br1 up type bridge vlan_filtering 0 mcast_snooping 0
# ip link add name vx1 up type vxlan id 1000 \
	local 192.0.2.17 remote 192.0.2.18 \
	dstport 4789 nolearning noudpcsum tos inherit ttl 100
# ip link set dev vx1 master br1
# ip link set dev sw1p1 master br1
# ip link add name br2 up type bridge vlan_filtering 0 mcast_snooping 0
# ip link add name vx2 up type vxlan id 2000 \
	local 192.0.2.17 remote 192.0.2.18 \
	dstport 4789 nolearning noudpcsum tos inherit ttl 100
# ip link set dev vx2 master br2
# ip link set dev sw1p2 master br2
# ip link set dev vx2 down
# ip link set dev vx2 type vxlan ttl 200
# ip link set dev vx2 up
Error: mlxsw_spectrum: Conflicting NVE tunnels configuration.

v2:
- Add David Ahern's tags.

Petr Machata (8):
  net: core: dev: Add extack argument to dev_open()
  net: vrf: cycle_netdev(): Add an extack argument
  net: ipvlan: ipvlan_set_port_mode(): Add an extack argument
  net: core: dev: Add extack argument to dev_change_flags()
  net: core: dev: Add extack argument to __dev_change_flags()
  net: core: dev: Add call_netdevice_notifiers_extack()
  net: core: dev: Attach extack to NETDEV_PRE_UP
  selftests: mlxsw: Add a new test extack.sh

 drivers/infiniband/ulp/ipoib/ipoib_main.c          |  6 +-
 drivers/net/bonding/bond_main.c                    |  2 +-
 .../net/ethernet/aquantia/atlantic/aq_ethtool.c    |  2 +-
 drivers/net/ethernet/cisco/enic/enic_ethtool.c     |  2 +-
 drivers/net/ethernet/hisilicon/hns/hns_ethtool.c   |  2 +-
 drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c |  2 +-
 drivers/net/ethernet/sfc/ethtool.c                 |  2 +-
 drivers/net/ethernet/sfc/falcon/ethtool.c          |  2 +-
 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c  |  2 +-
 drivers/net/hyperv/netvsc_drv.c                    |  6 +-
 drivers/net/ipvlan/ipvlan_main.c                   | 19 +++--
 drivers/net/net_failover.c                         |  8 +--
 drivers/net/team/team.c                            |  2 +-
 drivers/net/vrf.c                                  | 11 +--
 drivers/net/wireless/intersil/hostap/hostap_main.c |  2 +-
 drivers/s390/net/qeth_l2_main.c                    |  2 +-
 drivers/s390/net/qeth_l3_main.c                    |  2 +-
 drivers/staging/fsl-dpaa2/ethsw/ethsw.c            |  2 +-
 drivers/staging/unisys/visornic/visornic_main.c    |  2 +-
 include/linux/netdevice.h                          |  8 ++-
 net/8021q/vlan.c                                   |  4 +-
 net/bluetooth/6lowpan.c                            |  2 +-
 net/core/dev.c                                     | 43 +++++++----
 net/core/dev_ioctl.c                               |  2 +-
 net/core/net-sysfs.c                               |  2 +-
 net/core/netpoll.c                                 |  2 +-
 net/core/rtnetlink.c                               |  6 +-
 net/ipv4/devinet.c                                 |  2 +-
 net/ipv4/ipconfig.c                                |  6 +-
 net/ipv4/ipmr.c                                    |  4 +-
 net/ipv6/addrconf.c                                |  2 +-
 net/ipv6/ip6mr.c                                   |  2 +-
 net/openvswitch/vport-geneve.c                     |  2 +-
 net/openvswitch/vport-gre.c                        |  2 +-
 net/openvswitch/vport-vxlan.c                      |  2 +-
 .../testing/selftests/drivers/net/mlxsw/extack.sh  | 84 ++++++++++++++++++++++
 36 files changed, 182 insertions(+), 71 deletions(-)
 create mode 100755 tools/testing/selftests/drivers/net/mlxsw/extack.sh

-- 
2.4.11

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH net-next v2 1/8] net: core: dev: Add extack argument to dev_open()
  2018-12-06 17:05 [PATCH net-next v2 0/8] Pass extack to NETDEV_PRE_UP Petr Machata
@ 2018-12-06 17:05 ` Petr Machata
  2018-12-06 17:05 ` [PATCH net-next v2 2/8] net: vrf: cycle_netdev(): Add an extack argument Petr Machata
                   ` (7 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Petr Machata @ 2018-12-06 17:05 UTC (permalink / raw)
  To: netdev; +Cc: David S. Miller, Jiri Pirko, Ido Schimmel, David Ahern

In order to pass extack together with NETDEV_PRE_UP notifications, it's
necessary to route the extack to __dev_open() from diverse (possibly
indirect) callers. One prominent API through which the notification is
invoked is dev_open().

Therefore extend dev_open() with and extra extack argument and update
all users. Most of the calls end up just encoding NULL, but bond and
team drivers have the extack readily available.

Signed-off-by: Petr Machata <petrm@mellanox.com>
Acked-by: Jiri Pirko <jiri@mellanox.com>
Reviewed-by: Ido Schimmel <idosch@mellanox.com>
Reviewed-by: David Ahern <dsahern@gmail.com>
---
 drivers/net/bonding/bond_main.c                     | 2 +-
 drivers/net/ethernet/aquantia/atlantic/aq_ethtool.c | 2 +-
 drivers/net/ethernet/cisco/enic/enic_ethtool.c      | 2 +-
 drivers/net/ethernet/hisilicon/hns/hns_ethtool.c    | 2 +-
 drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c  | 2 +-
 drivers/net/ethernet/sfc/ethtool.c                  | 2 +-
 drivers/net/ethernet/sfc/falcon/ethtool.c           | 2 +-
 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c   | 2 +-
 drivers/net/hyperv/netvsc_drv.c                     | 4 ++--
 drivers/net/net_failover.c                          | 8 ++++----
 drivers/net/team/team.c                             | 2 +-
 drivers/net/wireless/intersil/hostap/hostap_main.c  | 2 +-
 drivers/s390/net/qeth_l2_main.c                     | 2 +-
 drivers/s390/net/qeth_l3_main.c                     | 2 +-
 drivers/staging/fsl-dpaa2/ethsw/ethsw.c             | 2 +-
 drivers/staging/unisys/visornic/visornic_main.c     | 2 +-
 include/linux/netdevice.h                           | 2 +-
 net/bluetooth/6lowpan.c                             | 2 +-
 net/core/dev.c                                      | 5 +++--
 net/core/netpoll.c                                  | 2 +-
 net/ipv4/ipmr.c                                     | 4 ++--
 net/ipv6/addrconf.c                                 | 2 +-
 net/ipv6/ip6mr.c                                    | 2 +-
 23 files changed, 30 insertions(+), 29 deletions(-)

diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 333387f1f1fe..6b34dbefa7dd 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -1538,7 +1538,7 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev,
 	slave_dev->flags |= IFF_SLAVE;
 
 	/* open the slave since the application closed it */
-	res = dev_open(slave_dev);
+	res = dev_open(slave_dev, extack);
 	if (res) {
 		netdev_dbg(bond_dev, "Opening slave %s failed\n", slave_dev->name);
 		goto err_restore_mac;
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_ethtool.c b/drivers/net/ethernet/aquantia/atlantic/aq_ethtool.c
index a5fd71692c8b..43b42615ad84 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_ethtool.c
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_ethtool.c
@@ -525,7 +525,7 @@ static int aq_set_ringparam(struct net_device *ndev,
 		}
 	}
 	if (ndev_running)
-		err = dev_open(ndev);
+		err = dev_open(ndev, NULL);
 
 err_exit:
 	return err;
diff --git a/drivers/net/ethernet/cisco/enic/enic_ethtool.c b/drivers/net/ethernet/cisco/enic/enic_ethtool.c
index f42f7a6e1559..ebd5c2cf1efe 100644
--- a/drivers/net/ethernet/cisco/enic/enic_ethtool.c
+++ b/drivers/net/ethernet/cisco/enic/enic_ethtool.c
@@ -241,7 +241,7 @@ static int enic_set_ringparam(struct net_device *netdev,
 	}
 	enic_init_vnic_resources(enic);
 	if (running) {
-		err = dev_open(netdev);
+		err = dev_open(netdev, NULL);
 		if (err)
 			goto err_out;
 	}
diff --git a/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c b/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c
index 774beda040a1..8e9b95871d30 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c
+++ b/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c
@@ -624,7 +624,7 @@ static void hns_nic_self_test(struct net_device *ndev,
 		clear_bit(NIC_STATE_TESTING, &priv->state);
 
 		if (if_running)
-			(void)dev_open(ndev);
+			(void)dev_open(ndev, NULL);
 	}
 	/* Online tests aren't run; pass by default */
 
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c b/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
index 4563638367ac..e678b6939da3 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
@@ -821,7 +821,7 @@ static int hns3_set_ringparam(struct net_device *ndev,
 	}
 
 	if (if_running)
-		ret = dev_open(ndev);
+		ret = dev_open(ndev, NULL);
 
 	return ret;
 }
diff --git a/drivers/net/ethernet/sfc/ethtool.c b/drivers/net/ethernet/sfc/ethtool.c
index 3143588ffd77..600d7b895cf2 100644
--- a/drivers/net/ethernet/sfc/ethtool.c
+++ b/drivers/net/ethernet/sfc/ethtool.c
@@ -539,7 +539,7 @@ static void efx_ethtool_self_test(struct net_device *net_dev,
 	/* We need rx buffers and interrupts. */
 	already_up = (efx->net_dev->flags & IFF_UP);
 	if (!already_up) {
-		rc = dev_open(efx->net_dev);
+		rc = dev_open(efx->net_dev, NULL);
 		if (rc) {
 			netif_err(efx, drv, efx->net_dev,
 				  "failed opening device.\n");
diff --git a/drivers/net/ethernet/sfc/falcon/ethtool.c b/drivers/net/ethernet/sfc/falcon/ethtool.c
index 1ccdb7a82e2a..72cedec945c1 100644
--- a/drivers/net/ethernet/sfc/falcon/ethtool.c
+++ b/drivers/net/ethernet/sfc/falcon/ethtool.c
@@ -517,7 +517,7 @@ static void ef4_ethtool_self_test(struct net_device *net_dev,
 	/* We need rx buffers and interrupts. */
 	already_up = (efx->net_dev->flags & IFF_UP);
 	if (!already_up) {
-		rc = dev_open(efx->net_dev);
+		rc = dev_open(efx->net_dev, NULL);
 		if (rc) {
 			netif_err(efx, drv, efx->net_dev,
 				  "failed opening device.\n");
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index c728ed1375b2..d20496f0ebd0 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -4082,7 +4082,7 @@ static void stmmac_reset_subtask(struct stmmac_priv *priv)
 
 	set_bit(STMMAC_DOWN, &priv->state);
 	dev_close(priv->dev);
-	dev_open(priv->dev);
+	dev_open(priv->dev, NULL);
 	clear_bit(STMMAC_DOWN, &priv->state);
 	clear_bit(STMMAC_RESETING, &priv->state);
 	rtnl_unlock();
diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
index 85936ed9e952..c65620adab52 100644
--- a/drivers/net/hyperv/netvsc_drv.c
+++ b/drivers/net/hyperv/netvsc_drv.c
@@ -137,7 +137,7 @@ static int netvsc_open(struct net_device *net)
 		 * slave as up. If open fails, then slave will be
 		 * still be offline (and not used).
 		 */
-		ret = dev_open(vf_netdev);
+		ret = dev_open(vf_netdev, NULL);
 		if (ret)
 			netdev_warn(net,
 				    "unable to open slave: %s: %d\n",
@@ -2002,7 +2002,7 @@ static void __netvsc_vf_setup(struct net_device *ndev,
 	netif_addr_unlock_bh(ndev);
 
 	if (netif_running(ndev)) {
-		ret = dev_open(vf_netdev);
+		ret = dev_open(vf_netdev, NULL);
 		if (ret)
 			netdev_warn(vf_netdev,
 				    "unable to open: %d\n", ret);
diff --git a/drivers/net/net_failover.c b/drivers/net/net_failover.c
index e964d312f4ca..ed1166adaa2f 100644
--- a/drivers/net/net_failover.c
+++ b/drivers/net/net_failover.c
@@ -40,14 +40,14 @@ static int net_failover_open(struct net_device *dev)
 
 	primary_dev = rtnl_dereference(nfo_info->primary_dev);
 	if (primary_dev) {
-		err = dev_open(primary_dev);
+		err = dev_open(primary_dev, NULL);
 		if (err)
 			goto err_primary_open;
 	}
 
 	standby_dev = rtnl_dereference(nfo_info->standby_dev);
 	if (standby_dev) {
-		err = dev_open(standby_dev);
+		err = dev_open(standby_dev, NULL);
 		if (err)
 			goto err_standby_open;
 	}
@@ -517,7 +517,7 @@ static int net_failover_slave_register(struct net_device *slave_dev,
 	dev_hold(slave_dev);
 
 	if (netif_running(failover_dev)) {
-		err = dev_open(slave_dev);
+		err = dev_open(slave_dev, NULL);
 		if (err && (err != -EBUSY)) {
 			netdev_err(failover_dev, "Opening slave %s failed err:%d\n",
 				   slave_dev->name, err);
@@ -680,7 +680,7 @@ static int net_failover_slave_name_change(struct net_device *slave_dev,
 	/* We need to bring up the slave after the rename by udev in case
 	 * open failed with EBUSY when it was registered.
 	 */
-	dev_open(slave_dev);
+	dev_open(slave_dev, NULL);
 
 	return 0;
 }
diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c
index 364f514d56d8..93576e0240dd 100644
--- a/drivers/net/team/team.c
+++ b/drivers/net/team/team.c
@@ -1212,7 +1212,7 @@ static int team_port_add(struct team *team, struct net_device *port_dev,
 		goto err_port_enter;
 	}
 
-	err = dev_open(port_dev);
+	err = dev_open(port_dev, extack);
 	if (err) {
 		netdev_dbg(dev, "Device %s opening failed\n",
 			   portname);
diff --git a/drivers/net/wireless/intersil/hostap/hostap_main.c b/drivers/net/wireless/intersil/hostap/hostap_main.c
index 012930d35434..b0e7c0a0617e 100644
--- a/drivers/net/wireless/intersil/hostap/hostap_main.c
+++ b/drivers/net/wireless/intersil/hostap/hostap_main.c
@@ -690,7 +690,7 @@ static int prism2_open(struct net_device *dev)
 		/* Master radio interface is needed for all operation, so open
 		 * it automatically when any virtual net_device is opened. */
 		local->master_dev_auto_open = 1;
-		dev_open(local->dev);
+		dev_open(local->dev, NULL);
 	}
 
 	netif_device_attach(dev);
diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c
index 2836231c1c5d..f108d4b44605 100644
--- a/drivers/s390/net/qeth_l2_main.c
+++ b/drivers/s390/net/qeth_l2_main.c
@@ -1007,7 +1007,7 @@ static int __qeth_l2_set_online(struct ccwgroup_device *gdev, int recovery_mode)
 			qeth_l2_set_rx_mode(card->dev);
 		} else {
 			rtnl_lock();
-			dev_open(card->dev);
+			dev_open(card->dev, NULL);
 			rtnl_unlock();
 		}
 	}
diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c
index eca68da39d05..42a7cdc59b76 100644
--- a/drivers/s390/net/qeth_l3_main.c
+++ b/drivers/s390/net/qeth_l3_main.c
@@ -2417,7 +2417,7 @@ static int __qeth_l3_set_online(struct ccwgroup_device *gdev, int recovery_mode)
 			__qeth_l3_open(card->dev);
 			qeth_l3_set_rx_mode(card->dev);
 		} else {
-			dev_open(card->dev);
+			dev_open(card->dev, NULL);
 		}
 		rtnl_unlock();
 	}
diff --git a/drivers/staging/fsl-dpaa2/ethsw/ethsw.c b/drivers/staging/fsl-dpaa2/ethsw/ethsw.c
index 4fa37d6e598b..daabaceeea52 100644
--- a/drivers/staging/fsl-dpaa2/ethsw/ethsw.c
+++ b/drivers/staging/fsl-dpaa2/ethsw/ethsw.c
@@ -1172,7 +1172,7 @@ static int ethsw_open(struct ethsw_core *ethsw)
 
 	for (i = 0; i < ethsw->sw_attr.num_ifs; i++) {
 		port_priv = ethsw->ports[i];
-		err = dev_open(port_priv->netdev);
+		err = dev_open(port_priv->netdev, NULL);
 		if (err) {
 			netdev_err(port_priv->netdev, "dev_open err %d\n", err);
 			return err;
diff --git a/drivers/staging/unisys/visornic/visornic_main.c b/drivers/staging/unisys/visornic/visornic_main.c
index 3647b8f1ed28..5eeb4b93b45b 100644
--- a/drivers/staging/unisys/visornic/visornic_main.c
+++ b/drivers/staging/unisys/visornic/visornic_main.c
@@ -2095,7 +2095,7 @@ static int visornic_resume(struct visor_device *dev,
 	mod_timer(&devdata->irq_poll_timer, msecs_to_jiffies(2));
 
 	rtnl_lock();
-	dev_open(netdev);
+	dev_open(netdev, NULL);
 	rtnl_unlock();
 
 	complete_func(dev, 0);
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 94fb2e12f117..d79be3055f5f 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -2605,7 +2605,7 @@ struct net_device *dev_get_by_name(struct net *net, const char *name);
 struct net_device *dev_get_by_name_rcu(struct net *net, const char *name);
 struct net_device *__dev_get_by_name(struct net *net, const char *name);
 int dev_alloc_name(struct net_device *dev, const char *name);
-int dev_open(struct net_device *dev);
+int dev_open(struct net_device *dev, struct netlink_ext_ack *extack);
 void dev_close(struct net_device *dev);
 void dev_close_many(struct list_head *head, bool unlink);
 void dev_disable_lro(struct net_device *dev);
diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c
index 828e87fe8027..9d79c7de234a 100644
--- a/net/bluetooth/6lowpan.c
+++ b/net/bluetooth/6lowpan.c
@@ -607,7 +607,7 @@ static void ifup(struct net_device *netdev)
 	int err;
 
 	rtnl_lock();
-	err = dev_open(netdev);
+	err = dev_open(netdev, NULL);
 	if (err < 0)
 		BT_INFO("iface %s cannot be opened (%d)", netdev->name, err);
 	rtnl_unlock();
diff --git a/net/core/dev.c b/net/core/dev.c
index 04a6b7100aac..b801c1aafd70 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -1406,7 +1406,8 @@ static int __dev_open(struct net_device *dev)
 
 /**
  *	dev_open	- prepare an interface for use.
- *	@dev:	device to open
+ *	@dev: device to open
+ *	@extack: netlink extended ack
  *
  *	Takes a device from down to up state. The device's private open
  *	function is invoked and then the multicast lists are loaded. Finally
@@ -1416,7 +1417,7 @@ static int __dev_open(struct net_device *dev)
  *	Calling this function on an active interface is a nop. On a failure
  *	a negative errno code is returned.
  */
-int dev_open(struct net_device *dev)
+int dev_open(struct net_device *dev, struct netlink_ext_ack *extack)
 {
 	int ret;
 
diff --git a/net/core/netpoll.c b/net/core/netpoll.c
index 2b9fdbc43205..36a2b63ffd6d 100644
--- a/net/core/netpoll.c
+++ b/net/core/netpoll.c
@@ -663,7 +663,7 @@ int netpoll_setup(struct netpoll *np)
 
 		np_info(np, "device %s not up yet, forcing it\n", np->dev_name);
 
-		err = dev_open(ndev);
+		err = dev_open(ndev, NULL);
 
 		if (err) {
 			np_err(np, "failed to open %s\n", ndev->name);
diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c
index 5cbc749a50aa..ea04e38f56e9 100644
--- a/net/ipv4/ipmr.c
+++ b/net/ipv4/ipmr.c
@@ -506,7 +506,7 @@ static struct net_device *ipmr_new_tunnel(struct net *net, struct vifctl *v)
 			dev->flags |= IFF_MULTICAST;
 			if (!ipmr_init_vif_indev(dev))
 				goto failure;
-			if (dev_open(dev))
+			if (dev_open(dev, NULL))
 				goto failure;
 			dev_hold(dev);
 		}
@@ -589,7 +589,7 @@ static struct net_device *ipmr_reg_vif(struct net *net, struct mr_table *mrt)
 
 	if (!ipmr_init_vif_indev(dev))
 		goto failure;
-	if (dev_open(dev))
+	if (dev_open(dev, NULL))
 		goto failure;
 
 	dev_hold(dev);
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 045597b9a7c0..521e471f1cf9 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -2820,7 +2820,7 @@ int addrconf_set_dstaddr(struct net *net, void __user *arg)
 			dev = __dev_get_by_name(net, p.name);
 			if (!dev)
 				goto err_exit;
-			err = dev_open(dev);
+			err = dev_open(dev, NULL);
 		}
 	}
 #endif
diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c
index e2ea691e42c6..8c63494400c4 100644
--- a/net/ipv6/ip6mr.c
+++ b/net/ipv6/ip6mr.c
@@ -655,7 +655,7 @@ static struct net_device *ip6mr_reg_vif(struct net *net, struct mr_table *mrt)
 		return NULL;
 	}
 
-	if (dev_open(dev))
+	if (dev_open(dev, NULL))
 		goto failure;
 
 	dev_hold(dev);
-- 
2.4.11

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH net-next v2 2/8] net: vrf: cycle_netdev(): Add an extack argument
  2018-12-06 17:05 [PATCH net-next v2 0/8] Pass extack to NETDEV_PRE_UP Petr Machata
  2018-12-06 17:05 ` [PATCH net-next v2 1/8] net: core: dev: Add extack argument to dev_open() Petr Machata
@ 2018-12-06 17:05 ` Petr Machata
  2018-12-06 17:05 ` [PATCH net-next v2 3/8] net: ipvlan: ipvlan_set_port_mode(): " Petr Machata
                   ` (6 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Petr Machata @ 2018-12-06 17:05 UTC (permalink / raw)
  To: netdev; +Cc: David S. Miller, Jiri Pirko, Ido Schimmel, David Ahern

A follow-up patch will extend dev_change_flags() with an extack
argument. Extend cycle_netdev() to have that argument available for the
conversion.

Signed-off-by: Petr Machata <petrm@mellanox.com>
Acked-by: Jiri Pirko <jiri@mellanox.com>
Reviewed-by: Ido Schimmel <idosch@mellanox.com>
Reviewed-by: David Ahern <dsahern@gmail.com>
---
 drivers/net/vrf.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/net/vrf.c b/drivers/net/vrf.c
index 21ad4b1d7f03..1e9f2dc0de07 100644
--- a/drivers/net/vrf.c
+++ b/drivers/net/vrf.c
@@ -747,7 +747,8 @@ static int vrf_rtable_create(struct net_device *dev)
 /**************************** device handling ********************/
 
 /* cycle interface to flush neighbor cache and move routes across tables */
-static void cycle_netdev(struct net_device *dev)
+static void cycle_netdev(struct net_device *dev,
+			 struct netlink_ext_ack *extack)
 {
 	unsigned int flags = dev->flags;
 	int ret;
@@ -785,7 +786,7 @@ static int do_vrf_add_slave(struct net_device *dev, struct net_device *port_dev,
 	if (ret < 0)
 		goto err;
 
-	cycle_netdev(port_dev);
+	cycle_netdev(port_dev, extack);
 
 	return 0;
 
@@ -815,7 +816,7 @@ static int do_vrf_del_slave(struct net_device *dev, struct net_device *port_dev)
 	netdev_upper_dev_unlink(port_dev, dev);
 	port_dev->priv_flags &= ~IFF_L3MDEV_SLAVE;
 
-	cycle_netdev(port_dev);
+	cycle_netdev(port_dev, NULL);
 
 	return 0;
 }
-- 
2.4.11

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH net-next v2 3/8] net: ipvlan: ipvlan_set_port_mode(): Add an extack argument
  2018-12-06 17:05 [PATCH net-next v2 0/8] Pass extack to NETDEV_PRE_UP Petr Machata
  2018-12-06 17:05 ` [PATCH net-next v2 1/8] net: core: dev: Add extack argument to dev_open() Petr Machata
  2018-12-06 17:05 ` [PATCH net-next v2 2/8] net: vrf: cycle_netdev(): Add an extack argument Petr Machata
@ 2018-12-06 17:05 ` Petr Machata
  2018-12-06 17:05 ` [PATCH net-next v2 4/8] net: core: dev: Add extack argument to dev_change_flags() Petr Machata
                   ` (5 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Petr Machata @ 2018-12-06 17:05 UTC (permalink / raw)
  To: netdev; +Cc: David S. Miller, Jiri Pirko, Ido Schimmel, David Ahern

A follow-up patch will extend dev_change_flags() with an extack
argument. Extend ipvlan_set_port_mode() to have that argument available
for the conversion.

Signed-off-by: Petr Machata <petrm@mellanox.com>
Acked-by: Jiri Pirko <jiri@mellanox.com>
Reviewed-by: Ido Schimmel <idosch@mellanox.com>
---
 drivers/net/ipvlan/ipvlan_main.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ipvlan/ipvlan_main.c b/drivers/net/ipvlan/ipvlan_main.c
index 4a949569ec4c..14f1cbd3b96f 100644
--- a/drivers/net/ipvlan/ipvlan_main.c
+++ b/drivers/net/ipvlan/ipvlan_main.c
@@ -71,7 +71,8 @@ static void ipvlan_unregister_nf_hook(struct net *net)
 					ARRAY_SIZE(ipvl_nfops));
 }
 
-static int ipvlan_set_port_mode(struct ipvl_port *port, u16 nval)
+static int ipvlan_set_port_mode(struct ipvl_port *port, u16 nval,
+				struct netlink_ext_ack *extack)
 {
 	struct ipvl_dev *ipvlan;
 	struct net_device *mdev = port->dev;
@@ -498,7 +499,7 @@ static int ipvlan_nl_changelink(struct net_device *dev,
 	if (data[IFLA_IPVLAN_MODE]) {
 		u16 nmode = nla_get_u16(data[IFLA_IPVLAN_MODE]);
 
-		err = ipvlan_set_port_mode(port, nmode);
+		err = ipvlan_set_port_mode(port, nmode, extack);
 	}
 
 	if (!err && data[IFLA_IPVLAN_FLAGS]) {
@@ -672,7 +673,7 @@ int ipvlan_link_new(struct net *src_net, struct net_device *dev,
 	if (data && data[IFLA_IPVLAN_MODE])
 		mode = nla_get_u16(data[IFLA_IPVLAN_MODE]);
 
-	err = ipvlan_set_port_mode(port, mode);
+	err = ipvlan_set_port_mode(port, mode, extack);
 	if (err)
 		goto unlink_netdev;
 
-- 
2.4.11

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH net-next v2 4/8] net: core: dev: Add extack argument to dev_change_flags()
  2018-12-06 17:05 [PATCH net-next v2 0/8] Pass extack to NETDEV_PRE_UP Petr Machata
                   ` (2 preceding siblings ...)
  2018-12-06 17:05 ` [PATCH net-next v2 3/8] net: ipvlan: ipvlan_set_port_mode(): " Petr Machata
@ 2018-12-06 17:05 ` Petr Machata
  2018-12-06 17:05 ` [PATCH net-next v2 5/8] net: core: dev: Add extack argument to __dev_change_flags() Petr Machata
                   ` (4 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Petr Machata @ 2018-12-06 17:05 UTC (permalink / raw)
  To: netdev; +Cc: David S. Miller, Jiri Pirko, Ido Schimmel, David Ahern

In order to pass extack together with NETDEV_PRE_UP notifications, it's
necessary to route the extack to __dev_open() from diverse (possibly
indirect) callers. One prominent API through which the notification is
invoked is dev_change_flags().

Therefore extend dev_change_flags() with and extra extack argument and
update all users. Most of the calls end up just encoding NULL, but
several sites (VLAN, ipvlan, VRF, rtnetlink) do have extack available.

Since the function declaration line is changed anyway, name the other
function arguments to placate checkpatch.

Signed-off-by: Petr Machata <petrm@mellanox.com>
Acked-by: Jiri Pirko <jiri@mellanox.com>
Reviewed-by: Ido Schimmel <idosch@mellanox.com>
Reviewed-by: David Ahern <dsahern@gmail.com>
---
 drivers/infiniband/ulp/ipoib/ipoib_main.c |  6 +++---
 drivers/net/hyperv/netvsc_drv.c           |  2 +-
 drivers/net/ipvlan/ipvlan_main.c          | 12 ++++++++----
 drivers/net/vrf.c                         |  4 ++--
 include/linux/netdevice.h                 |  3 ++-
 net/8021q/vlan.c                          |  4 +++-
 net/core/dev.c                            |  4 +++-
 net/core/dev_ioctl.c                      |  2 +-
 net/core/net-sysfs.c                      |  2 +-
 net/core/rtnetlink.c                      |  3 ++-
 net/ipv4/devinet.c                        |  2 +-
 net/ipv4/ipconfig.c                       |  6 +++---
 net/openvswitch/vport-geneve.c            |  2 +-
 net/openvswitch/vport-gre.c               |  2 +-
 net/openvswitch/vport-vxlan.c             |  2 +-
 15 files changed, 33 insertions(+), 23 deletions(-)

diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c
index 8710214594d8..6214d8c0d546 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_main.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c
@@ -167,7 +167,7 @@ int ipoib_open(struct net_device *dev)
 			if (flags & IFF_UP)
 				continue;
 
-			dev_change_flags(cpriv->dev, flags | IFF_UP);
+			dev_change_flags(cpriv->dev, flags | IFF_UP, NULL);
 		}
 		up_read(&priv->vlan_rwsem);
 	}
@@ -207,7 +207,7 @@ static int ipoib_stop(struct net_device *dev)
 			if (!(flags & IFF_UP))
 				continue;
 
-			dev_change_flags(cpriv->dev, flags & ~IFF_UP);
+			dev_change_flags(cpriv->dev, flags & ~IFF_UP, NULL);
 		}
 		up_read(&priv->vlan_rwsem);
 	}
@@ -1823,7 +1823,7 @@ static void ipoib_parent_unregister_pre(struct net_device *ndev)
 	 * running ensures the it will not add more work.
 	 */
 	rtnl_lock();
-	dev_change_flags(priv->dev, priv->dev->flags & ~IFF_UP);
+	dev_change_flags(priv->dev, priv->dev->flags & ~IFF_UP, NULL);
 	rtnl_unlock();
 
 	/* ipoib_event() cannot be running once this returns */
diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
index c65620adab52..18b5584d6377 100644
--- a/drivers/net/hyperv/netvsc_drv.c
+++ b/drivers/net/hyperv/netvsc_drv.c
@@ -1993,7 +1993,7 @@ static void __netvsc_vf_setup(struct net_device *ndev,
 			    "unable to change mtu to %u\n", ndev->mtu);
 
 	/* set multicast etc flags on VF */
-	dev_change_flags(vf_netdev, ndev->flags | IFF_SLAVE);
+	dev_change_flags(vf_netdev, ndev->flags | IFF_SLAVE, NULL);
 
 	/* sync address list from ndev to VF */
 	netif_addr_lock_bh(ndev);
diff --git a/drivers/net/ipvlan/ipvlan_main.c b/drivers/net/ipvlan/ipvlan_main.c
index 14f1cbd3b96f..c3d3e458f541 100644
--- a/drivers/net/ipvlan/ipvlan_main.c
+++ b/drivers/net/ipvlan/ipvlan_main.c
@@ -85,10 +85,12 @@ static int ipvlan_set_port_mode(struct ipvl_port *port, u16 nval,
 			flags = ipvlan->dev->flags;
 			if (nval == IPVLAN_MODE_L3 || nval == IPVLAN_MODE_L3S) {
 				err = dev_change_flags(ipvlan->dev,
-						       flags | IFF_NOARP);
+						       flags | IFF_NOARP,
+						       extack);
 			} else {
 				err = dev_change_flags(ipvlan->dev,
-						       flags & ~IFF_NOARP);
+						       flags & ~IFF_NOARP,
+						       extack);
 			}
 			if (unlikely(err))
 				goto fail;
@@ -117,9 +119,11 @@ static int ipvlan_set_port_mode(struct ipvl_port *port, u16 nval,
 		flags = ipvlan->dev->flags;
 		if (port->mode == IPVLAN_MODE_L3 ||
 		    port->mode == IPVLAN_MODE_L3S)
-			dev_change_flags(ipvlan->dev, flags | IFF_NOARP);
+			dev_change_flags(ipvlan->dev, flags | IFF_NOARP,
+					 NULL);
 		else
-			dev_change_flags(ipvlan->dev, flags & ~IFF_NOARP);
+			dev_change_flags(ipvlan->dev, flags & ~IFF_NOARP,
+					 NULL);
 	}
 
 	return err;
diff --git a/drivers/net/vrf.c b/drivers/net/vrf.c
index 1e9f2dc0de07..95909e262ba4 100644
--- a/drivers/net/vrf.c
+++ b/drivers/net/vrf.c
@@ -756,9 +756,9 @@ static void cycle_netdev(struct net_device *dev,
 	if (!netif_running(dev))
 		return;
 
-	ret = dev_change_flags(dev, flags & ~IFF_UP);
+	ret = dev_change_flags(dev, flags & ~IFF_UP, extack);
 	if (ret >= 0)
-		ret = dev_change_flags(dev, flags);
+		ret = dev_change_flags(dev, flags, extack);
 
 	if (ret < 0) {
 		netdev_err(dev,
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index d79be3055f5f..18cf464450ee 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -3612,7 +3612,8 @@ int dev_ifconf(struct net *net, struct ifconf *, int);
 int dev_ethtool(struct net *net, struct ifreq *);
 unsigned int dev_get_flags(const struct net_device *);
 int __dev_change_flags(struct net_device *, unsigned int flags);
-int dev_change_flags(struct net_device *, unsigned int);
+int dev_change_flags(struct net_device *dev, unsigned int flags,
+		     struct netlink_ext_ack *extack);
 void __dev_notify_flags(struct net_device *, unsigned int old_flags,
 			unsigned int gchanges);
 int dev_change_name(struct net_device *, const char *);
diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c
index aef1a977279c..dc4411165e43 100644
--- a/net/8021q/vlan.c
+++ b/net/8021q/vlan.c
@@ -358,6 +358,7 @@ static int __vlan_device_event(struct net_device *dev, unsigned long event)
 static int vlan_device_event(struct notifier_block *unused, unsigned long event,
 			     void *ptr)
 {
+	struct netlink_ext_ack *extack = netdev_notifier_info_to_extack(ptr);
 	struct net_device *dev = netdev_notifier_info_to_dev(ptr);
 	struct vlan_group *grp;
 	struct vlan_info *vlan_info;
@@ -460,7 +461,8 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event,
 
 			vlan = vlan_dev_priv(vlandev);
 			if (!(vlan->flags & VLAN_FLAG_LOOSE_BINDING))
-				dev_change_flags(vlandev, flgs | IFF_UP);
+				dev_change_flags(vlandev, flgs | IFF_UP,
+						 extack);
 			netif_stacked_transfer_operstate(dev, vlandev);
 		}
 		break;
diff --git a/net/core/dev.c b/net/core/dev.c
index b801c1aafd70..8bba6f98b545 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -7595,11 +7595,13 @@ void __dev_notify_flags(struct net_device *dev, unsigned int old_flags,
  *	dev_change_flags - change device settings
  *	@dev: device
  *	@flags: device state flags
+ *	@extack: netlink extended ack
  *
  *	Change settings on device based state flags. The flags are
  *	in the userspace exported format.
  */
-int dev_change_flags(struct net_device *dev, unsigned int flags)
+int dev_change_flags(struct net_device *dev, unsigned int flags,
+		     struct netlink_ext_ack *extack)
 {
 	int ret;
 	unsigned int changes, old_flags = dev->flags, old_gflags = dev->gflags;
diff --git a/net/core/dev_ioctl.c b/net/core/dev_ioctl.c
index 90e8aa36881e..da273ec3cc57 100644
--- a/net/core/dev_ioctl.c
+++ b/net/core/dev_ioctl.c
@@ -234,7 +234,7 @@ static int dev_ifsioc(struct net *net, struct ifreq *ifr, unsigned int cmd)
 
 	switch (cmd) {
 	case SIOCSIFFLAGS:	/* Set interface flags */
-		return dev_change_flags(dev, ifr->ifr_flags);
+		return dev_change_flags(dev, ifr->ifr_flags, NULL);
 
 	case SIOCSIFMETRIC:	/* Set the metric on the interface
 				   (currently unused) */
diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c
index bd67c4d0fcfd..ff9fd2bb4ce4 100644
--- a/net/core/net-sysfs.c
+++ b/net/core/net-sysfs.c
@@ -337,7 +337,7 @@ NETDEVICE_SHOW_RW(mtu, fmt_dec);
 
 static int change_flags(struct net_device *dev, unsigned long new_flags)
 {
-	return dev_change_flags(dev, (unsigned int)new_flags);
+	return dev_change_flags(dev, (unsigned int)new_flags, NULL);
 }
 
 static ssize_t flags_store(struct device *dev, struct device_attribute *attr,
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index 98876cd1e36c..4c9e4e187600 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -2489,7 +2489,8 @@ static int do_setlink(const struct sk_buff *skb,
 	}
 
 	if (ifm->ifi_flags || ifm->ifi_change) {
-		err = dev_change_flags(dev, rtnl_dev_combine_flags(dev, ifm));
+		err = dev_change_flags(dev, rtnl_dev_combine_flags(dev, ifm),
+				       extack);
 		if (err < 0)
 			goto errout;
 	}
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
index a34602ae27de..5b9b6d497f71 100644
--- a/net/ipv4/devinet.c
+++ b/net/ipv4/devinet.c
@@ -1100,7 +1100,7 @@ int devinet_ioctl(struct net *net, unsigned int cmd, struct ifreq *ifr)
 				inet_del_ifa(in_dev, ifap, 1);
 			break;
 		}
-		ret = dev_change_flags(dev, ifr->ifr_flags);
+		ret = dev_change_flags(dev, ifr->ifr_flags, NULL);
 		break;
 
 	case SIOCSIFADDR:	/* Set interface address (and family) */
diff --git a/net/ipv4/ipconfig.c b/net/ipv4/ipconfig.c
index 88212615bf4c..55757764c381 100644
--- a/net/ipv4/ipconfig.c
+++ b/net/ipv4/ipconfig.c
@@ -220,7 +220,7 @@ static int __init ic_open_devs(void)
 	for_each_netdev(&init_net, dev) {
 		if (!(dev->flags & IFF_LOOPBACK) && !netdev_uses_dsa(dev))
 			continue;
-		if (dev_change_flags(dev, dev->flags | IFF_UP) < 0)
+		if (dev_change_flags(dev, dev->flags | IFF_UP, NULL) < 0)
 			pr_err("IP-Config: Failed to open %s\n", dev->name);
 	}
 
@@ -238,7 +238,7 @@ static int __init ic_open_devs(void)
 			if (ic_proto_enabled && !able)
 				continue;
 			oflags = dev->flags;
-			if (dev_change_flags(dev, oflags | IFF_UP) < 0) {
+			if (dev_change_flags(dev, oflags | IFF_UP, NULL) < 0) {
 				pr_err("IP-Config: Failed to open %s\n",
 				       dev->name);
 				continue;
@@ -315,7 +315,7 @@ static void __init ic_close_devs(void)
 		dev = d->dev;
 		if (d != ic_dev && !netdev_uses_dsa(dev)) {
 			pr_debug("IP-Config: Downing %s\n", dev->name);
-			dev_change_flags(dev, d->flags);
+			dev_change_flags(dev, d->flags, NULL);
 		}
 		kfree(d);
 	}
diff --git a/net/openvswitch/vport-geneve.c b/net/openvswitch/vport-geneve.c
index 5aaf3babfc3f..acb6077b7478 100644
--- a/net/openvswitch/vport-geneve.c
+++ b/net/openvswitch/vport-geneve.c
@@ -93,7 +93,7 @@ static struct vport *geneve_tnl_create(const struct vport_parms *parms)
 		return ERR_CAST(dev);
 	}
 
-	err = dev_change_flags(dev, dev->flags | IFF_UP);
+	err = dev_change_flags(dev, dev->flags | IFF_UP, NULL);
 	if (err < 0) {
 		rtnl_delete_link(dev);
 		rtnl_unlock();
diff --git a/net/openvswitch/vport-gre.c b/net/openvswitch/vport-gre.c
index 0e72d95b0e8f..c38a62464b85 100644
--- a/net/openvswitch/vport-gre.c
+++ b/net/openvswitch/vport-gre.c
@@ -68,7 +68,7 @@ static struct vport *gre_tnl_create(const struct vport_parms *parms)
 		return ERR_CAST(dev);
 	}
 
-	err = dev_change_flags(dev, dev->flags | IFF_UP);
+	err = dev_change_flags(dev, dev->flags | IFF_UP, NULL);
 	if (err < 0) {
 		rtnl_delete_link(dev);
 		rtnl_unlock();
diff --git a/net/openvswitch/vport-vxlan.c b/net/openvswitch/vport-vxlan.c
index 7e6301b2ec4d..8f16f11f7ad3 100644
--- a/net/openvswitch/vport-vxlan.c
+++ b/net/openvswitch/vport-vxlan.c
@@ -131,7 +131,7 @@ static struct vport *vxlan_tnl_create(const struct vport_parms *parms)
 		return ERR_CAST(dev);
 	}
 
-	err = dev_change_flags(dev, dev->flags | IFF_UP);
+	err = dev_change_flags(dev, dev->flags | IFF_UP, NULL);
 	if (err < 0) {
 		rtnl_delete_link(dev);
 		rtnl_unlock();
-- 
2.4.11

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH net-next v2 5/8] net: core: dev: Add extack argument to __dev_change_flags()
  2018-12-06 17:05 [PATCH net-next v2 0/8] Pass extack to NETDEV_PRE_UP Petr Machata
                   ` (3 preceding siblings ...)
  2018-12-06 17:05 ` [PATCH net-next v2 4/8] net: core: dev: Add extack argument to dev_change_flags() Petr Machata
@ 2018-12-06 17:05 ` Petr Machata
  2018-12-06 17:05 ` [PATCH net-next v2 6/8] net: core: dev: Add call_netdevice_notifiers_extack() Petr Machata
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Petr Machata @ 2018-12-06 17:05 UTC (permalink / raw)
  To: netdev; +Cc: David S. Miller, Jiri Pirko, Ido Schimmel, David Ahern

In order to pass extack together with NETDEV_PRE_UP notifications, it's
necessary to route the extack to __dev_open() from diverse (possibly
indirect) callers. The last missing API is __dev_change_flags().

Therefore extend __dev_change_flags() with and extra extack argument and
update the two existing users.

Since the function declaration line is changed anyway, name the struct
net_device argument to placate checkpatch.

Signed-off-by: Petr Machata <petrm@mellanox.com>
Acked-by: Jiri Pirko <jiri@mellanox.com>
Reviewed-by: Ido Schimmel <idosch@mellanox.com>
Reviewed-by: David Ahern <dsahern@gmail.com>
---
 include/linux/netdevice.h | 3 ++-
 net/core/dev.c            | 5 +++--
 net/core/rtnetlink.c      | 3 ++-
 3 files changed, 7 insertions(+), 4 deletions(-)

diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 18cf464450ee..fc6ba71513be 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -3611,7 +3611,8 @@ int dev_ioctl(struct net *net, unsigned int cmd, struct ifreq *ifr,
 int dev_ifconf(struct net *net, struct ifconf *, int);
 int dev_ethtool(struct net *net, struct ifreq *);
 unsigned int dev_get_flags(const struct net_device *);
-int __dev_change_flags(struct net_device *, unsigned int flags);
+int __dev_change_flags(struct net_device *dev, unsigned int flags,
+		       struct netlink_ext_ack *extack);
 int dev_change_flags(struct net_device *dev, unsigned int flags,
 		     struct netlink_ext_ack *extack);
 void __dev_notify_flags(struct net_device *, unsigned int old_flags,
diff --git a/net/core/dev.c b/net/core/dev.c
index 8bba6f98b545..b37e320def13 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -7498,7 +7498,8 @@ unsigned int dev_get_flags(const struct net_device *dev)
 }
 EXPORT_SYMBOL(dev_get_flags);
 
-int __dev_change_flags(struct net_device *dev, unsigned int flags)
+int __dev_change_flags(struct net_device *dev, unsigned int flags,
+		       struct netlink_ext_ack *extack)
 {
 	unsigned int old_flags = dev->flags;
 	int ret;
@@ -7606,7 +7607,7 @@ int dev_change_flags(struct net_device *dev, unsigned int flags,
 	int ret;
 	unsigned int changes, old_flags = dev->flags, old_gflags = dev->gflags;
 
-	ret = __dev_change_flags(dev, flags);
+	ret = __dev_change_flags(dev, flags, extack);
 	if (ret < 0)
 		return ret;
 
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index 4c9e4e187600..91a0f7477f8e 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -2871,7 +2871,8 @@ int rtnl_configure_link(struct net_device *dev, const struct ifinfomsg *ifm)
 
 	old_flags = dev->flags;
 	if (ifm && (ifm->ifi_flags || ifm->ifi_change)) {
-		err = __dev_change_flags(dev, rtnl_dev_combine_flags(dev, ifm));
+		err = __dev_change_flags(dev, rtnl_dev_combine_flags(dev, ifm),
+					 NULL);
 		if (err < 0)
 			return err;
 	}
-- 
2.4.11

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH net-next v2 6/8] net: core: dev: Add call_netdevice_notifiers_extack()
  2018-12-06 17:05 [PATCH net-next v2 0/8] Pass extack to NETDEV_PRE_UP Petr Machata
                   ` (4 preceding siblings ...)
  2018-12-06 17:05 ` [PATCH net-next v2 5/8] net: core: dev: Add extack argument to __dev_change_flags() Petr Machata
@ 2018-12-06 17:05 ` Petr Machata
  2018-12-06 17:05 ` [PATCH net-next v2 7/8] net: core: dev: Attach extack to NETDEV_PRE_UP Petr Machata
                   ` (2 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Petr Machata @ 2018-12-06 17:05 UTC (permalink / raw)
  To: netdev; +Cc: David S. Miller, Jiri Pirko, Ido Schimmel, David Ahern

In order to propagate extack through NETDEV_PRE_UP, add a new function
call_netdevice_notifiers_extack() that primes the extack field of the
notifier info. Convert call_netdevice_notifiers() to a simple wrapper
around the new function that passes NULL for extack.

Signed-off-by: Petr Machata <petrm@mellanox.com>
Acked-by: Jiri Pirko <jiri@mellanox.com>
Reviewed-by: Ido Schimmel <idosch@mellanox.com>
Reviewed-by: David Ahern <dsahern@gmail.com>
---
 net/core/dev.c | 21 ++++++++++++++++-----
 1 file changed, 16 insertions(+), 5 deletions(-)

diff --git a/net/core/dev.c b/net/core/dev.c
index b37e320def13..4b033af8e6cd 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -162,6 +162,9 @@ static struct list_head offload_base __read_mostly;
 static int netif_rx_internal(struct sk_buff *skb);
 static int call_netdevice_notifiers_info(unsigned long val,
 					 struct netdev_notifier_info *info);
+static int call_netdevice_notifiers_extack(unsigned long val,
+					   struct net_device *dev,
+					   struct netlink_ext_ack *extack);
 static struct napi_struct *napi_by_id(unsigned int napi_id);
 
 /*
@@ -1734,6 +1737,18 @@ static int call_netdevice_notifiers_info(unsigned long val,
 	return raw_notifier_call_chain(&netdev_chain, val, info);
 }
 
+static int call_netdevice_notifiers_extack(unsigned long val,
+					   struct net_device *dev,
+					   struct netlink_ext_ack *extack)
+{
+	struct netdev_notifier_info info = {
+		.dev = dev,
+		.extack = extack,
+	};
+
+	return call_netdevice_notifiers_info(val, &info);
+}
+
 /**
  *	call_netdevice_notifiers - call all network notifier blocks
  *      @val: value passed unmodified to notifier function
@@ -1745,11 +1760,7 @@ static int call_netdevice_notifiers_info(unsigned long val,
 
 int call_netdevice_notifiers(unsigned long val, struct net_device *dev)
 {
-	struct netdev_notifier_info info = {
-		.dev = dev,
-	};
-
-	return call_netdevice_notifiers_info(val, &info);
+	return call_netdevice_notifiers_extack(val, dev, NULL);
 }
 EXPORT_SYMBOL(call_netdevice_notifiers);
 
-- 
2.4.11

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH net-next v2 7/8] net: core: dev: Attach extack to NETDEV_PRE_UP
  2018-12-06 17:05 [PATCH net-next v2 0/8] Pass extack to NETDEV_PRE_UP Petr Machata
                   ` (5 preceding siblings ...)
  2018-12-06 17:05 ` [PATCH net-next v2 6/8] net: core: dev: Add call_netdevice_notifiers_extack() Petr Machata
@ 2018-12-06 17:05 ` Petr Machata
  2018-12-06 17:05 ` [PATCH net-next v2 8/8] selftests: mlxsw: Add a new test extack.sh Petr Machata
  2018-12-06 21:31 ` [PATCH net-next v2 0/8] Pass extack to NETDEV_PRE_UP David Miller
  8 siblings, 0 replies; 10+ messages in thread
From: Petr Machata @ 2018-12-06 17:05 UTC (permalink / raw)
  To: netdev; +Cc: David S. Miller, Jiri Pirko, Ido Schimmel, David Ahern

Drivers may need to validate configuration of a device that's about to
be upped. Should the validation fail, there's currently no way to
communicate details of the failure to the user, beyond an error number.

To mend that, change __dev_open() to take an extack argument and pass it
from __dev_change_flags() and dev_open(), where it was propagated in the
previous patches.

Change __dev_open() to call call_netdevice_notifiers_extack() so that
the passed-in extack is attached to the NETDEV_PRE_UP notifier.

Signed-off-by: Petr Machata <petrm@mellanox.com>
Acked-by: Jiri Pirko <jiri@mellanox.com>
Reviewed-by: Ido Schimmel <idosch@mellanox.com>
Reviewed-by: David Ahern <dsahern@gmail.com>
---
 net/core/dev.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/net/core/dev.c b/net/core/dev.c
index 4b033af8e6cd..068b60db35ae 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -1364,7 +1364,7 @@ void netdev_notify_peers(struct net_device *dev)
 }
 EXPORT_SYMBOL(netdev_notify_peers);
 
-static int __dev_open(struct net_device *dev)
+static int __dev_open(struct net_device *dev, struct netlink_ext_ack *extack)
 {
 	const struct net_device_ops *ops = dev->netdev_ops;
 	int ret;
@@ -1380,7 +1380,7 @@ static int __dev_open(struct net_device *dev)
 	 */
 	netpoll_poll_disable(dev);
 
-	ret = call_netdevice_notifiers(NETDEV_PRE_UP, dev);
+	ret = call_netdevice_notifiers_extack(NETDEV_PRE_UP, dev, extack);
 	ret = notifier_to_errno(ret);
 	if (ret)
 		return ret;
@@ -1427,7 +1427,7 @@ int dev_open(struct net_device *dev, struct netlink_ext_ack *extack)
 	if (dev->flags & IFF_UP)
 		return 0;
 
-	ret = __dev_open(dev);
+	ret = __dev_open(dev, extack);
 	if (ret < 0)
 		return ret;
 
@@ -7547,7 +7547,7 @@ int __dev_change_flags(struct net_device *dev, unsigned int flags,
 		if (old_flags & IFF_UP)
 			__dev_close(dev);
 		else
-			ret = __dev_open(dev);
+			ret = __dev_open(dev, extack);
 	}
 
 	if ((flags ^ dev->gflags) & IFF_PROMISC) {
-- 
2.4.11

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH net-next v2 8/8] selftests: mlxsw: Add a new test extack.sh
  2018-12-06 17:05 [PATCH net-next v2 0/8] Pass extack to NETDEV_PRE_UP Petr Machata
                   ` (6 preceding siblings ...)
  2018-12-06 17:05 ` [PATCH net-next v2 7/8] net: core: dev: Attach extack to NETDEV_PRE_UP Petr Machata
@ 2018-12-06 17:05 ` Petr Machata
  2018-12-06 21:31 ` [PATCH net-next v2 0/8] Pass extack to NETDEV_PRE_UP David Miller
  8 siblings, 0 replies; 10+ messages in thread
From: Petr Machata @ 2018-12-06 17:05 UTC (permalink / raw)
  To: netdev; +Cc: David S. Miller, Jiri Pirko, Ido Schimmel, David Ahern

Add a testsuite dedicated to testing extack propagation and related
functionality.

Signed-off-by: Petr Machata <petrm@mellanox.com>
Acked-by: Jiri Pirko <jiri@mellanox.com>
Reviewed-by: Ido Schimmel <idosch@mellanox.com>
---
 .../testing/selftests/drivers/net/mlxsw/extack.sh  | 84 ++++++++++++++++++++++
 1 file changed, 84 insertions(+)
 create mode 100755 tools/testing/selftests/drivers/net/mlxsw/extack.sh

diff --git a/tools/testing/selftests/drivers/net/mlxsw/extack.sh b/tools/testing/selftests/drivers/net/mlxsw/extack.sh
new file mode 100755
index 000000000000..101a5508bdfd
--- /dev/null
+++ b/tools/testing/selftests/drivers/net/mlxsw/extack.sh
@@ -0,0 +1,84 @@
+#!/bin/bash
+# SPDX-License-Identifier: GPL-2.0
+#
+# Test operations that we expect to report extended ack.
+
+lib_dir=$(dirname $0)/../../../net/forwarding
+
+ALL_TESTS="
+	netdev_pre_up_test
+"
+NUM_NETIFS=2
+source $lib_dir/lib.sh
+
+setup_prepare()
+{
+	swp1=${NETIFS[p1]}
+	swp2=${NETIFS[p2]}
+
+	ip link set dev $swp1 up
+	ip link set dev $swp2 up
+}
+
+cleanup()
+{
+	pre_cleanup
+
+	ip link set dev $swp2 down
+	ip link set dev $swp1 down
+}
+
+netdev_pre_up_test()
+{
+	RET=0
+
+	ip link add name br1 up type bridge vlan_filtering 0 mcast_snooping 0
+	ip link add name vx1 up type vxlan id 1000 \
+		local 192.0.2.17 remote 192.0.2.18 \
+		dstport 4789 nolearning noudpcsum tos inherit ttl 100
+
+	ip link set dev vx1 master br1
+	check_err $?
+
+	ip link set dev $swp1 master br1
+	check_err $?
+
+	ip link add name br2 up type bridge vlan_filtering 0 mcast_snooping 0
+	ip link add name vx2 up type vxlan id 2000 \
+		local 192.0.2.17 remote 192.0.2.18 \
+		dstport 4789 nolearning noudpcsum tos inherit ttl 100
+
+	ip link set dev vx2 master br2
+	check_err $?
+
+	ip link set dev $swp2 master br2
+	check_err $?
+
+	# Unsupported configuration: mlxsw demands that all offloaded VXLAN
+	# devices have the same TTL.
+	ip link set dev vx2 down
+	ip link set dev vx2 type vxlan ttl 200
+
+	ip link set dev vx2 up &>/dev/null
+	check_fail $?
+
+	ip link set dev vx2 up 2>&1 >/dev/null | grep -q mlxsw_spectrum
+	check_err $?
+
+	log_test "extack - NETDEV_PRE_UP"
+
+	ip link del dev vx2
+	ip link del dev br2
+
+	ip link del dev vx1
+	ip link del dev br1
+}
+
+trap cleanup EXIT
+
+setup_prepare
+setup_wait
+
+tests_run
+
+exit $EXIT_STATUS
-- 
2.4.11

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [PATCH net-next v2 0/8] Pass extack to NETDEV_PRE_UP
  2018-12-06 17:05 [PATCH net-next v2 0/8] Pass extack to NETDEV_PRE_UP Petr Machata
                   ` (7 preceding siblings ...)
  2018-12-06 17:05 ` [PATCH net-next v2 8/8] selftests: mlxsw: Add a new test extack.sh Petr Machata
@ 2018-12-06 21:31 ` David Miller
  8 siblings, 0 replies; 10+ messages in thread
From: David Miller @ 2018-12-06 21:31 UTC (permalink / raw)
  To: petrm; +Cc: netdev, jiri, idosch, dsa

From: Petr Machata <petrm@mellanox.com>
Date: Thu, 6 Dec 2018 17:05:35 +0000

> 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.
 ...

Series applied, thank you.

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2018-12-06 21:32 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-12-06 17:05 [PATCH net-next v2 0/8] Pass extack to NETDEV_PRE_UP Petr Machata
2018-12-06 17:05 ` [PATCH net-next v2 1/8] net: core: dev: Add extack argument to dev_open() Petr Machata
2018-12-06 17:05 ` [PATCH net-next v2 2/8] net: vrf: cycle_netdev(): Add an extack argument Petr Machata
2018-12-06 17:05 ` [PATCH net-next v2 3/8] net: ipvlan: ipvlan_set_port_mode(): " Petr Machata
2018-12-06 17:05 ` [PATCH net-next v2 4/8] net: core: dev: Add extack argument to dev_change_flags() Petr Machata
2018-12-06 17:05 ` [PATCH net-next v2 5/8] net: core: dev: Add extack argument to __dev_change_flags() Petr Machata
2018-12-06 17:05 ` [PATCH net-next v2 6/8] net: core: dev: Add call_netdevice_notifiers_extack() Petr Machata
2018-12-06 17:05 ` [PATCH net-next v2 7/8] net: core: dev: Attach extack to NETDEV_PRE_UP Petr Machata
2018-12-06 17:05 ` [PATCH net-next v2 8/8] selftests: mlxsw: Add a new test extack.sh Petr Machata
2018-12-06 21:31 ` [PATCH net-next v2 0/8] Pass extack to NETDEV_PRE_UP David Miller

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.