All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH net-next 0/9] Pass extack to SWITCHDEV_PORT_OBJ_ADD
@ 2018-12-12 11:52 Petr Machata
  2018-12-12 11:52 ` [PATCH net-next 1/9] net: ndo_bridge_setlink: Add extack Petr Machata
                   ` (8 more replies)
  0 siblings, 9 replies; 19+ messages in thread
From: Petr Machata @ 2018-12-12 11:52 UTC (permalink / raw)
  To: netdev; +Cc: Jiri Pirko, Ido Schimmel, davem, ivecera

Drivers may need to do validation as a result of port object addition.
An example is mlxsw, which needs to check the configuration of a VXLAN
device attached to an offloaded bridge. Without a mapped VLAN, the
invalidity of the device is not important, but as soon as a pvid,
untagged VLAN is configured for the device, it has to be validated and
offloaded. Should the validation fail, there's currently no way to
communicate details of the failure to the user, beyond an error number.

Because currently, extack is not available at all in that area of code,
this patch starts down at the RTNL level and progresses up towards the
driver(s).

In patch #1, ndo_bridge_setlink is updated to include extack, and
callbacks of all clients are updated as well (ignoring the argument).

In patch #2, the bridge driver is updated to propagate the extack
through to the switchdev border, br_switchdev_port_vlan_add().

Patches #3, #4 and #5 then gradually extend switchdev to pass the extack
argument through to the switchdev blocking notifier chain.

Patches #6 and #7 then update mlxsw to pass the extack argument from
VXLAN events resp. port events on to mlxsw_sp_bridge_8021q_vxlan_join().

Finally in patches #8 and #9, the code paths from the previous two
patches are verified to yield an error message.

Petr Machata (9):
  net: ndo_bridge_setlink: Add extack
  net: bridge: Propagate extack to switchdev
  net: switchdev: Add extack argument to switchdev_port_obj_add()
  net: switchdev: Add extack to struct switchdev_notifier_info
  net: switchdev: Add extack to switchdev_handle_port_obj_add() callback
  mlxsw: spectrum_switchdev: Propagate extack on VXLAN VLAN events
  mlxsw: spectrum_switchdev: Propagate extack on port VLAN events
  selftests: mlxsw: extack: Test VLAN add on a VXLAN device
  selftests: mlxsw: extack: Test VLAN add on a port device

 drivers/net/ethernet/broadcom/bnxt/bnxt.c          |  2 +-
 drivers/net/ethernet/emulex/benet/be_main.c        |  2 +-
 drivers/net/ethernet/intel/i40e/i40e_main.c        |  4 +-
 drivers/net/ethernet/intel/ice/ice_main.c          |  3 +-
 drivers/net/ethernet/intel/ixgbe/ixgbe_main.c      |  3 +-
 .../ethernet/mellanox/mlxsw/spectrum_switchdev.c   | 53 ++++++++++++-------
 drivers/net/ethernet/mscc/ocelot.c                 |  3 +-
 drivers/net/vxlan.c                                |  1 +
 include/linux/netdevice.h                          |  6 ++-
 include/net/switchdev.h                            | 25 ++++++---
 net/bridge/br_if.c                                 |  2 +-
 net/bridge/br_mdb.c                                |  4 +-
 net/bridge/br_netlink.c                            | 30 ++++++-----
 net/bridge/br_private.h                            | 25 +++++----
 net/bridge/br_switchdev.c                          |  5 +-
 net/bridge/br_vlan.c                               | 59 ++++++++++++---------
 net/core/rtnetlink.c                               |  6 ++-
 net/switchdev/switchdev.c                          | 38 +++++++++-----
 .../testing/selftests/drivers/net/mlxsw/extack.sh  | 61 ++++++++++++++++++++++
 19 files changed, 230 insertions(+), 102 deletions(-)

-- 
2.4.11

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

* [PATCH net-next 1/9] net: ndo_bridge_setlink: Add extack
  2018-12-12 11:52 [PATCH net-next 0/9] Pass extack to SWITCHDEV_PORT_OBJ_ADD Petr Machata
@ 2018-12-12 11:52 ` Petr Machata
  2018-12-12 12:26   ` Nikolay Aleksandrov
  2018-12-12 11:52 ` [PATCH net-next 2/9] net: bridge: Propagate extack to switchdev Petr Machata
                   ` (7 subsequent siblings)
  8 siblings, 1 reply; 19+ messages in thread
From: Petr Machata @ 2018-12-12 11:52 UTC (permalink / raw)
  To: netdev; +Cc: Jiri Pirko, Ido Schimmel, davem, ivecera

Drivers may not be able to implement a VLAN addition or reconfiguration.
In those cases it's desirable to explain to the user that it was
rejected (and why).

To that end, add extack argument to ndo_bridge_setlink. Adapt all users
to that change.

Following patches will use the new argument in the bridge driver.

Signed-off-by: Petr Machata <petrm@mellanox.com>
Acked-by: Jiri Pirko <jiri@mellanox.com>
---
 drivers/net/ethernet/broadcom/bnxt/bnxt.c     | 2 +-
 drivers/net/ethernet/emulex/benet/be_main.c   | 2 +-
 drivers/net/ethernet/intel/i40e/i40e_main.c   | 4 +++-
 drivers/net/ethernet/intel/ice/ice_main.c     | 3 ++-
 drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 3 ++-
 include/linux/netdevice.h                     | 6 ++++--
 net/bridge/br_netlink.c                       | 3 ++-
 net/bridge/br_private.h                       | 3 ++-
 net/core/rtnetlink.c                          | 6 ++++--
 9 files changed, 21 insertions(+), 11 deletions(-)

diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
index 5d21c14853ac..a9a6d775e083 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
@@ -9617,7 +9617,7 @@ static int bnxt_bridge_getlink(struct sk_buff *skb, u32 pid, u32 seq,
 }
 
 static int bnxt_bridge_setlink(struct net_device *dev, struct nlmsghdr *nlh,
-			       u16 flags)
+			       u16 flags, struct netlink_ext_ack *extack)
 {
 	struct bnxt *bp = netdev_priv(dev);
 	struct nlattr *attr, *br_spec;
diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
index 245abf0d19c0..852f5bfe5f6d 100644
--- a/drivers/net/ethernet/emulex/benet/be_main.c
+++ b/drivers/net/ethernet/emulex/benet/be_main.c
@@ -4955,7 +4955,7 @@ int be_load_fw(struct be_adapter *adapter, u8 *fw_file)
 }
 
 static int be_ndo_bridge_setlink(struct net_device *dev, struct nlmsghdr *nlh,
-				 u16 flags)
+				 u16 flags, struct netlink_ext_ack *extack)
 {
 	struct be_adapter *adapter = netdev_priv(dev);
 	struct nlattr *attr, *br_spec;
diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c
index 6d5b13f69dec..fbb21ac06c98 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_main.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_main.c
@@ -11685,6 +11685,7 @@ static int i40e_ndo_fdb_add(struct ndmsg *ndm, struct nlattr *tb[],
  * @dev: the netdev being configured
  * @nlh: RTNL message
  * @flags: bridge flags
+ * @extack: netlink extended ack
  *
  * Inserts a new hardware bridge if not already created and
  * enables the bridging mode requested (VEB or VEPA). If the
@@ -11697,7 +11698,8 @@ static int i40e_ndo_fdb_add(struct ndmsg *ndm, struct nlattr *tb[],
  **/
 static int i40e_ndo_bridge_setlink(struct net_device *dev,
 				   struct nlmsghdr *nlh,
-				   u16 flags)
+				   u16 flags,
+				   struct netlink_ext_ack *extack)
 {
 	struct i40e_netdev_priv *np = netdev_priv(dev);
 	struct i40e_vsi *vsi = np->vsi;
diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c
index e45e57499d91..f9f0d470412b 100644
--- a/drivers/net/ethernet/intel/ice/ice_main.c
+++ b/drivers/net/ethernet/intel/ice/ice_main.c
@@ -3624,6 +3624,7 @@ static int ice_vsi_update_bridge_mode(struct ice_vsi *vsi, u16 bmode)
  * @dev: the netdev being configured
  * @nlh: RTNL message
  * @flags: bridge setlink flags
+ * @extack: netlink extended ack
  *
  * Sets the bridge mode (VEB/VEPA) of the switch to which the netdev (VSI) is
  * hooked up to. Iterates through the PF VSI list and sets the loopback mode (if
@@ -3632,7 +3633,7 @@ static int ice_vsi_update_bridge_mode(struct ice_vsi *vsi, u16 bmode)
  */
 static int
 ice_bridge_setlink(struct net_device *dev, struct nlmsghdr *nlh,
-		   u16 __always_unused flags)
+		   u16 __always_unused flags, struct netlink_ext_ack *extack)
 {
 	struct ice_netdev_priv *np = netdev_priv(dev);
 	struct ice_pf *pf = np->vsi->back;
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index 49a4ea38eb07..f1e40734c975 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -9979,7 +9979,8 @@ static int ixgbe_configure_bridge_mode(struct ixgbe_adapter *adapter,
 }
 
 static int ixgbe_ndo_bridge_setlink(struct net_device *dev,
-				    struct nlmsghdr *nlh, u16 flags)
+				    struct nlmsghdr *nlh, u16 flags,
+				    struct netlink_ext_ack *extack)
 {
 	struct ixgbe_adapter *adapter = netdev_priv(dev);
 	struct nlattr *attr, *br_spec;
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index fc6ba71513be..d8046696d27b 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -1165,7 +1165,7 @@ struct dev_ifalias {
  *	entries to skb and update idx with the number of entries.
  *
  * int (*ndo_bridge_setlink)(struct net_device *dev, struct nlmsghdr *nlh,
- *			     u16 flags)
+ *			     u16 flags, struct netlink_ext_ack *extack)
  * int (*ndo_bridge_getlink)(struct sk_buff *skb, u32 pid, u32 seq,
  *			     struct net_device *dev, u32 filter_mask,
  *			     int nlflags)
@@ -1390,7 +1390,9 @@ struct net_device_ops {
 
 	int			(*ndo_bridge_setlink)(struct net_device *dev,
 						      struct nlmsghdr *nlh,
-						      u16 flags);
+						      u16 flags,
+						      struct netlink_ext_ack *
+						      extack);
 	int			(*ndo_bridge_getlink)(struct sk_buff *skb,
 						      u32 pid, u32 seq,
 						      struct net_device *dev,
diff --git a/net/bridge/br_netlink.c b/net/bridge/br_netlink.c
index ff2c10d47529..f9be70b26091 100644
--- a/net/bridge/br_netlink.c
+++ b/net/bridge/br_netlink.c
@@ -850,7 +850,8 @@ static int br_setport(struct net_bridge_port *p, struct nlattr *tb[])
 }
 
 /* Change state and parameters on port. */
-int br_setlink(struct net_device *dev, struct nlmsghdr *nlh, u16 flags)
+int br_setlink(struct net_device *dev, struct nlmsghdr *nlh, u16 flags,
+	       struct netlink_ext_ack *extack)
 {
 	struct net_bridge *br = (struct net_bridge *)netdev_priv(dev);
 	struct nlattr *tb[IFLA_BRPORT_MAX + 1];
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h
index 5719b4d3e466..090dfacdc438 100644
--- a/net/bridge/br_private.h
+++ b/net/bridge/br_private.h
@@ -1138,7 +1138,8 @@ int br_netlink_init(void);
 void br_netlink_fini(void);
 void br_ifinfo_notify(int event, const struct net_bridge *br,
 		      const struct net_bridge_port *port);
-int br_setlink(struct net_device *dev, struct nlmsghdr *nlmsg, u16 flags);
+int br_setlink(struct net_device *dev, struct nlmsghdr *nlmsg, u16 flags,
+	       struct netlink_ext_ack *extack);
 int br_dellink(struct net_device *dev, struct nlmsghdr *nlmsg, u16 flags);
 int br_getlink(struct sk_buff *skb, u32 pid, u32 seq, struct net_device *dev,
 	       u32 filter_mask, int nlflags);
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index c9c0407a7ee0..3b6e551f9e69 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -4332,7 +4332,8 @@ static int rtnl_bridge_setlink(struct sk_buff *skb, struct nlmsghdr *nlh,
 			goto out;
 		}
 
-		err = br_dev->netdev_ops->ndo_bridge_setlink(dev, nlh, flags);
+		err = br_dev->netdev_ops->ndo_bridge_setlink(dev, nlh, flags,
+							     extack);
 		if (err)
 			goto out;
 
@@ -4344,7 +4345,8 @@ static int rtnl_bridge_setlink(struct sk_buff *skb, struct nlmsghdr *nlh,
 			err = -EOPNOTSUPP;
 		else
 			err = dev->netdev_ops->ndo_bridge_setlink(dev, nlh,
-								  flags);
+								  flags,
+								  extack);
 		if (!err) {
 			flags &= ~BRIDGE_FLAGS_SELF;
 
-- 
2.4.11

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

* [PATCH net-next 2/9] net: bridge: Propagate extack to switchdev
  2018-12-12 11:52 [PATCH net-next 0/9] Pass extack to SWITCHDEV_PORT_OBJ_ADD Petr Machata
  2018-12-12 11:52 ` [PATCH net-next 1/9] net: ndo_bridge_setlink: Add extack Petr Machata
@ 2018-12-12 11:52 ` Petr Machata
  2018-12-12 12:20     ` [Bridge] " Nikolay Aleksandrov
                     ` (2 more replies)
  2018-12-12 11:52 ` [PATCH net-next 3/9] net: switchdev: Add extack argument to switchdev_port_obj_add() Petr Machata
                   ` (6 subsequent siblings)
  8 siblings, 3 replies; 19+ messages in thread
From: Petr Machata @ 2018-12-12 11:52 UTC (permalink / raw)
  To: netdev; +Cc: Jiri Pirko, Ido Schimmel, davem, ivecera

ndo_bridge_setlink has been updated in the previous patch to have extack
available, and changelink RTNL op has had this argument since the time
extack was added. Propagate both through the bridge driver to eventually
reach br_switchdev_port_vlan_add(), where it will be used by subsequent
patches.

Signed-off-by: Petr Machata <petrm@mellanox.com>
Acked-by: Jiri Pirko <jiri@mellanox.com>
---
 net/bridge/br_if.c        |  2 +-
 net/bridge/br_netlink.c   | 27 +++++++++++++---------
 net/bridge/br_private.h   | 22 ++++++++++--------
 net/bridge/br_switchdev.c |  3 ++-
 net/bridge/br_vlan.c      | 59 ++++++++++++++++++++++++++---------------------
 5 files changed, 65 insertions(+), 48 deletions(-)

diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c
index d4863f5679ac..3b945d6369c4 100644
--- a/net/bridge/br_if.c
+++ b/net/bridge/br_if.c
@@ -650,7 +650,7 @@ int br_add_if(struct net_bridge *br, struct net_device *dev,
 	if (br_fdb_insert(br, p, dev->dev_addr, 0))
 		netdev_err(dev, "failed insert local address bridge forwarding table\n");
 
-	err = nbp_vlan_init(p);
+	err = nbp_vlan_init(p, extack);
 	if (err) {
 		netdev_err(dev, "failed to initialize vlan filtering on this port\n");
 		goto err7;
diff --git a/net/bridge/br_netlink.c b/net/bridge/br_netlink.c
index f9be70b26091..935495b93a99 100644
--- a/net/bridge/br_netlink.c
+++ b/net/bridge/br_netlink.c
@@ -525,7 +525,8 @@ int br_getlink(struct sk_buff *skb, u32 pid, u32 seq,
 }
 
 static int br_vlan_info(struct net_bridge *br, struct net_bridge_port *p,
-			int cmd, struct bridge_vlan_info *vinfo, bool *changed)
+			int cmd, struct bridge_vlan_info *vinfo, bool *changed,
+			struct netlink_ext_ack *extack)
 {
 	bool curr_change;
 	int err = 0;
@@ -537,11 +538,11 @@ static int br_vlan_info(struct net_bridge *br, struct net_bridge_port *p,
 			 * per-VLAN entry as well
 			 */
 			err = nbp_vlan_add(p, vinfo->vid, vinfo->flags,
-					   &curr_change);
+					   &curr_change, extack);
 		} else {
 			vinfo->flags |= BRIDGE_VLAN_INFO_BRENTRY;
 			err = br_vlan_add(br, vinfo->vid, vinfo->flags,
-					  &curr_change);
+					  &curr_change, extack);
 		}
 		if (curr_change)
 			*changed = true;
@@ -568,7 +569,8 @@ static int br_process_vlan_info(struct net_bridge *br,
 				struct net_bridge_port *p, int cmd,
 				struct bridge_vlan_info *vinfo_curr,
 				struct bridge_vlan_info **vinfo_last,
-				bool *changed)
+				bool *changed,
+				struct netlink_ext_ack *extack)
 {
 	if (!vinfo_curr->vid || vinfo_curr->vid >= VLAN_VID_MASK)
 		return -EINVAL;
@@ -598,7 +600,8 @@ static int br_process_vlan_info(struct net_bridge *br,
 		       sizeof(struct bridge_vlan_info));
 		for (v = (*vinfo_last)->vid; v <= vinfo_curr->vid; v++) {
 			tmp_vinfo.vid = v;
-			err = br_vlan_info(br, p, cmd, &tmp_vinfo, changed);
+			err = br_vlan_info(br, p, cmd, &tmp_vinfo, changed,
+					   extack);
 			if (err)
 				break;
 		}
@@ -607,13 +610,14 @@ static int br_process_vlan_info(struct net_bridge *br,
 		return err;
 	}
 
-	return br_vlan_info(br, p, cmd, vinfo_curr, changed);
+	return br_vlan_info(br, p, cmd, vinfo_curr, changed, extack);
 }
 
 static int br_afspec(struct net_bridge *br,
 		     struct net_bridge_port *p,
 		     struct nlattr *af_spec,
-		     int cmd, bool *changed)
+		     int cmd, bool *changed,
+		     struct netlink_ext_ack *extack)
 {
 	struct bridge_vlan_info *vinfo_curr = NULL;
 	struct bridge_vlan_info *vinfo_last = NULL;
@@ -643,7 +647,8 @@ static int br_afspec(struct net_bridge *br,
 				return -EINVAL;
 			vinfo_curr = nla_data(attr);
 			err = br_process_vlan_info(br, p, cmd, vinfo_curr,
-						   &vinfo_last, changed);
+						   &vinfo_last, changed,
+						   extack);
 			if (err)
 				return err;
 			break;
@@ -898,7 +903,7 @@ int br_setlink(struct net_device *dev, struct nlmsghdr *nlh, u16 flags,
 	}
 
 	if (afspec)
-		err = br_afspec(br, p, afspec, RTM_SETLINK, &changed);
+		err = br_afspec(br, p, afspec, RTM_SETLINK, &changed, extack);
 
 	if (changed)
 		br_ifinfo_notify(RTM_NEWLINK, br, p);
@@ -924,7 +929,7 @@ int br_dellink(struct net_device *dev, struct nlmsghdr *nlh, u16 flags)
 	if (!p && !(dev->priv_flags & IFF_EBRIDGE))
 		return -EINVAL;
 
-	err = br_afspec(br, p, afspec, RTM_DELLINK, &changed);
+	err = br_afspec(br, p, afspec, RTM_DELLINK, &changed, NULL);
 	if (changed)
 		/* Send RTM_NEWLINK because userspace
 		 * expects RTM_NEWLINK for vlan dels
@@ -1106,7 +1111,7 @@ static int br_changelink(struct net_device *brdev, struct nlattr *tb[],
 	if (data[IFLA_BR_VLAN_DEFAULT_PVID]) {
 		__u16 defpvid = nla_get_u16(data[IFLA_BR_VLAN_DEFAULT_PVID]);
 
-		err = __br_vlan_set_default_pvid(br, defpvid);
+		err = __br_vlan_set_default_pvid(br, defpvid, extack);
 		if (err)
 			return err;
 	}
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h
index 090dfacdc438..ff3dfb2a78b8 100644
--- a/net/bridge/br_private.h
+++ b/net/bridge/br_private.h
@@ -868,7 +868,7 @@ struct sk_buff *br_handle_vlan(struct net_bridge *br,
 			       struct net_bridge_vlan_group *vg,
 			       struct sk_buff *skb);
 int br_vlan_add(struct net_bridge *br, u16 vid, u16 flags,
-		bool *changed);
+		bool *changed, struct netlink_ext_ack *extack);
 int br_vlan_delete(struct net_bridge *br, u16 vid);
 void br_vlan_flush(struct net_bridge *br);
 struct net_bridge_vlan *br_vlan_find(struct net_bridge_vlan_group *vg, u16 vid);
@@ -881,12 +881,13 @@ int br_vlan_set_stats(struct net_bridge *br, unsigned long val);
 int br_vlan_set_stats_per_port(struct net_bridge *br, unsigned long val);
 int br_vlan_init(struct net_bridge *br);
 int br_vlan_set_default_pvid(struct net_bridge *br, unsigned long val);
-int __br_vlan_set_default_pvid(struct net_bridge *br, u16 pvid);
+int __br_vlan_set_default_pvid(struct net_bridge *br, u16 pvid,
+			       struct netlink_ext_ack *extack);
 int nbp_vlan_add(struct net_bridge_port *port, u16 vid, u16 flags,
-		 bool *changed);
+		 bool *changed, struct netlink_ext_ack *extack);
 int nbp_vlan_delete(struct net_bridge_port *port, u16 vid);
 void nbp_vlan_flush(struct net_bridge_port *port);
-int nbp_vlan_init(struct net_bridge_port *port);
+int nbp_vlan_init(struct net_bridge_port *port, struct netlink_ext_ack *extack);
 int nbp_get_num_vlan_infos(struct net_bridge_port *p, u32 filter_mask);
 void br_vlan_get_stats(const struct net_bridge_vlan *v,
 		       struct br_vlan_stats *stats);
@@ -971,7 +972,7 @@ static inline struct sk_buff *br_handle_vlan(struct net_bridge *br,
 }
 
 static inline int br_vlan_add(struct net_bridge *br, u16 vid, u16 flags,
-			      bool *changed)
+			      bool *changed, struct netlink_ext_ack *extack)
 {
 	*changed = false;
 	return -EOPNOTSUPP;
@@ -996,7 +997,7 @@ static inline int br_vlan_init(struct net_bridge *br)
 }
 
 static inline int nbp_vlan_add(struct net_bridge_port *port, u16 vid, u16 flags,
-			       bool *changed)
+			       bool *changed, struct netlink_ext_ack *extack)
 {
 	*changed = false;
 	return -EOPNOTSUPP;
@@ -1017,7 +1018,8 @@ static inline struct net_bridge_vlan *br_vlan_find(struct net_bridge_vlan_group
 	return NULL;
 }
 
-static inline int nbp_vlan_init(struct net_bridge_port *port)
+static inline int nbp_vlan_init(struct net_bridge_port *port,
+				struct netlink_ext_ack *extack)
 {
 	return 0;
 }
@@ -1174,7 +1176,8 @@ int br_switchdev_set_port_flag(struct net_bridge_port *p,
 			       unsigned long mask);
 void br_switchdev_fdb_notify(const struct net_bridge_fdb_entry *fdb,
 			     int type);
-int br_switchdev_port_vlan_add(struct net_device *dev, u16 vid, u16 flags);
+int br_switchdev_port_vlan_add(struct net_device *dev, u16 vid, u16 flags,
+			       struct netlink_ext_ack *extack);
 int br_switchdev_port_vlan_del(struct net_device *dev, u16 vid);
 
 static inline void br_switchdev_frame_unmark(struct sk_buff *skb)
@@ -1206,7 +1209,8 @@ static inline int br_switchdev_set_port_flag(struct net_bridge_port *p,
 }
 
 static inline int br_switchdev_port_vlan_add(struct net_device *dev,
-					     u16 vid, u16 flags)
+					     u16 vid, u16 flags,
+					     struct netlink_ext_ack *extack)
 {
 	return -EOPNOTSUPP;
 }
diff --git a/net/bridge/br_switchdev.c b/net/bridge/br_switchdev.c
index b993df770675..99ba32177b31 100644
--- a/net/bridge/br_switchdev.c
+++ b/net/bridge/br_switchdev.c
@@ -140,7 +140,8 @@ br_switchdev_fdb_notify(const struct net_bridge_fdb_entry *fdb, int type)
 	}
 }
 
-int br_switchdev_port_vlan_add(struct net_device *dev, u16 vid, u16 flags)
+int br_switchdev_port_vlan_add(struct net_device *dev, u16 vid, u16 flags,
+			       struct netlink_ext_ack *extack)
 {
 	struct switchdev_obj_port_vlan v = {
 		.obj.orig_dev = dev,
diff --git a/net/bridge/br_vlan.c b/net/bridge/br_vlan.c
index 48f50d7ac624..4a2f31157ef5 100644
--- a/net/bridge/br_vlan.c
+++ b/net/bridge/br_vlan.c
@@ -80,14 +80,14 @@ static bool __vlan_add_flags(struct net_bridge_vlan *v, u16 flags)
 }
 
 static int __vlan_vid_add(struct net_device *dev, struct net_bridge *br,
-			  u16 vid, u16 flags)
+			  u16 vid, u16 flags, struct netlink_ext_ack *extack)
 {
 	int err;
 
 	/* Try switchdev op first. In case it is not supported, fallback to
 	 * 8021q add.
 	 */
-	err = br_switchdev_port_vlan_add(dev, vid, flags);
+	err = br_switchdev_port_vlan_add(dev, vid, flags, extack);
 	if (err == -EOPNOTSUPP)
 		return vlan_vid_add(dev, br->vlan_proto, vid);
 	return err;
@@ -139,7 +139,9 @@ static int __vlan_vid_del(struct net_device *dev, struct net_bridge *br,
 /* Returns a master vlan, if it didn't exist it gets created. In all cases a
  * a reference is taken to the master vlan before returning.
  */
-static struct net_bridge_vlan *br_vlan_get_master(struct net_bridge *br, u16 vid)
+static struct net_bridge_vlan *
+br_vlan_get_master(struct net_bridge *br, u16 vid,
+		   struct netlink_ext_ack *extack)
 {
 	struct net_bridge_vlan_group *vg;
 	struct net_bridge_vlan *masterv;
@@ -150,7 +152,7 @@ static struct net_bridge_vlan *br_vlan_get_master(struct net_bridge *br, u16 vid
 		bool changed;
 
 		/* missing global ctx, create it now */
-		if (br_vlan_add(br, vid, 0, &changed))
+		if (br_vlan_add(br, vid, 0, &changed, extack))
 			return NULL;
 		masterv = br_vlan_find(vg, vid);
 		if (WARN_ON(!masterv))
@@ -214,7 +216,8 @@ static void nbp_vlan_rcu_free(struct rcu_head *rcu)
  * 4. same as 3 but with both master and brentry flags set so the entry
  *    will be used for filtering in both the port and the bridge
  */
-static int __vlan_add(struct net_bridge_vlan *v, u16 flags)
+static int __vlan_add(struct net_bridge_vlan *v, u16 flags,
+		      struct netlink_ext_ack *extack)
 {
 	struct net_bridge_vlan *masterv = NULL;
 	struct net_bridge_port *p = NULL;
@@ -239,7 +242,7 @@ static int __vlan_add(struct net_bridge_vlan *v, u16 flags)
 		 * This ensures tagged traffic enters the bridge when
 		 * promiscuous mode is disabled by br_manage_promisc().
 		 */
-		err = __vlan_vid_add(dev, br, v->vid, flags);
+		err = __vlan_vid_add(dev, br, v->vid, flags, extack);
 		if (err)
 			goto out;
 
@@ -249,12 +252,12 @@ static int __vlan_add(struct net_bridge_vlan *v, u16 flags)
 
 			err = br_vlan_add(br, v->vid,
 					  flags | BRIDGE_VLAN_INFO_BRENTRY,
-					  &changed);
+					  &changed, extack);
 			if (err)
 				goto out_filt;
 		}
 
-		masterv = br_vlan_get_master(br, v->vid);
+		masterv = br_vlan_get_master(br, v->vid, extack);
 		if (!masterv)
 			goto out_filt;
 		v->brvlan = masterv;
@@ -269,7 +272,7 @@ static int __vlan_add(struct net_bridge_vlan *v, u16 flags)
 			v->stats = masterv->stats;
 		}
 	} else {
-		err = br_switchdev_port_vlan_add(dev, v->vid, flags);
+		err = br_switchdev_port_vlan_add(dev, v->vid, flags, extack);
 		if (err && err != -EOPNOTSUPP)
 			goto out;
 	}
@@ -591,11 +594,12 @@ bool br_should_learn(struct net_bridge_port *p, struct sk_buff *skb, u16 *vid)
 static int br_vlan_add_existing(struct net_bridge *br,
 				struct net_bridge_vlan_group *vg,
 				struct net_bridge_vlan *vlan,
-				u16 flags, bool *changed)
+				u16 flags, bool *changed,
+				struct netlink_ext_ack *extack)
 {
 	int err;
 
-	err = br_switchdev_port_vlan_add(br->dev, vlan->vid, flags);
+	err = br_switchdev_port_vlan_add(br->dev, vlan->vid, flags, extack);
 	if (err && err != -EOPNOTSUPP)
 		return err;
 
@@ -634,7 +638,8 @@ static int br_vlan_add_existing(struct net_bridge *br,
  * Must be called with vid in range from 1 to 4094 inclusive.
  * changed must be true only if the vlan was created or updated
  */
-int br_vlan_add(struct net_bridge *br, u16 vid, u16 flags, bool *changed)
+int br_vlan_add(struct net_bridge *br, u16 vid, u16 flags, bool *changed,
+		struct netlink_ext_ack *extack)
 {
 	struct net_bridge_vlan_group *vg;
 	struct net_bridge_vlan *vlan;
@@ -646,7 +651,8 @@ int br_vlan_add(struct net_bridge *br, u16 vid, u16 flags, bool *changed)
 	vg = br_vlan_group(br);
 	vlan = br_vlan_find(vg, vid);
 	if (vlan)
-		return br_vlan_add_existing(br, vg, vlan, flags, changed);
+		return br_vlan_add_existing(br, vg, vlan, flags, changed,
+					    extack);
 
 	vlan = kzalloc(sizeof(*vlan), GFP_KERNEL);
 	if (!vlan)
@@ -663,7 +669,7 @@ int br_vlan_add(struct net_bridge *br, u16 vid, u16 flags, bool *changed)
 	vlan->br = br;
 	if (flags & BRIDGE_VLAN_INFO_BRENTRY)
 		refcount_set(&vlan->refcnt, 1);
-	ret = __vlan_add(vlan, flags);
+	ret = __vlan_add(vlan, flags, extack);
 	if (ret) {
 		free_percpu(vlan->stats);
 		kfree(vlan);
@@ -914,7 +920,8 @@ static void br_vlan_disable_default_pvid(struct net_bridge *br)
 	br->default_pvid = 0;
 }
 
-int __br_vlan_set_default_pvid(struct net_bridge *br, u16 pvid)
+int __br_vlan_set_default_pvid(struct net_bridge *br, u16 pvid,
+			       struct netlink_ext_ack *extack)
 {
 	const struct net_bridge_vlan *pvent;
 	struct net_bridge_vlan_group *vg;
@@ -946,7 +953,7 @@ int __br_vlan_set_default_pvid(struct net_bridge *br, u16 pvid)
 				  BRIDGE_VLAN_INFO_PVID |
 				  BRIDGE_VLAN_INFO_UNTAGGED |
 				  BRIDGE_VLAN_INFO_BRENTRY,
-				  &vlchange);
+				  &vlchange, extack);
 		if (err)
 			goto out;
 		br_vlan_delete(br, old_pvid);
@@ -966,7 +973,7 @@ int __br_vlan_set_default_pvid(struct net_bridge *br, u16 pvid)
 		err = nbp_vlan_add(p, pvid,
 				   BRIDGE_VLAN_INFO_PVID |
 				   BRIDGE_VLAN_INFO_UNTAGGED,
-				   &vlchange);
+				   &vlchange, extack);
 		if (err)
 			goto err_port;
 		nbp_vlan_delete(p, old_pvid);
@@ -988,7 +995,7 @@ int __br_vlan_set_default_pvid(struct net_bridge *br, u16 pvid)
 			nbp_vlan_add(p, old_pvid,
 				     BRIDGE_VLAN_INFO_PVID |
 				     BRIDGE_VLAN_INFO_UNTAGGED,
-				     &vlchange);
+				     &vlchange, NULL);
 		nbp_vlan_delete(p, pvid);
 	}
 
@@ -998,7 +1005,7 @@ int __br_vlan_set_default_pvid(struct net_bridge *br, u16 pvid)
 				    BRIDGE_VLAN_INFO_PVID |
 				    BRIDGE_VLAN_INFO_UNTAGGED |
 				    BRIDGE_VLAN_INFO_BRENTRY,
-				    &vlchange);
+				    &vlchange, NULL);
 		br_vlan_delete(br, pvid);
 	}
 	goto out;
@@ -1021,7 +1028,7 @@ int br_vlan_set_default_pvid(struct net_bridge *br, unsigned long val)
 		err = -EPERM;
 		goto out;
 	}
-	err = __br_vlan_set_default_pvid(br, pvid);
+	err = __br_vlan_set_default_pvid(br, pvid, NULL);
 out:
 	return err;
 }
@@ -1047,7 +1054,7 @@ int br_vlan_init(struct net_bridge *br)
 	rcu_assign_pointer(br->vlgrp, vg);
 	ret = br_vlan_add(br, 1,
 			  BRIDGE_VLAN_INFO_PVID | BRIDGE_VLAN_INFO_UNTAGGED |
-			  BRIDGE_VLAN_INFO_BRENTRY, &changed);
+			  BRIDGE_VLAN_INFO_BRENTRY, &changed, NULL);
 	if (ret)
 		goto err_vlan_add;
 
@@ -1064,7 +1071,7 @@ int br_vlan_init(struct net_bridge *br)
 	goto out;
 }
 
-int nbp_vlan_init(struct net_bridge_port *p)
+int nbp_vlan_init(struct net_bridge_port *p, struct netlink_ext_ack *extack)
 {
 	struct switchdev_attr attr = {
 		.orig_dev = p->br->dev,
@@ -1097,7 +1104,7 @@ int nbp_vlan_init(struct net_bridge_port *p)
 		ret = nbp_vlan_add(p, p->br->default_pvid,
 				   BRIDGE_VLAN_INFO_PVID |
 				   BRIDGE_VLAN_INFO_UNTAGGED,
-				   &changed);
+				   &changed, extack);
 		if (ret)
 			goto err_vlan_add;
 	}
@@ -1122,7 +1129,7 @@ int nbp_vlan_init(struct net_bridge_port *p)
  * changed must be true only if the vlan was created or updated
  */
 int nbp_vlan_add(struct net_bridge_port *port, u16 vid, u16 flags,
-		 bool *changed)
+		 bool *changed, struct netlink_ext_ack *extack)
 {
 	struct net_bridge_vlan *vlan;
 	int ret;
@@ -1133,7 +1140,7 @@ int nbp_vlan_add(struct net_bridge_port *port, u16 vid, u16 flags,
 	vlan = br_vlan_find(nbp_vlan_group(port), vid);
 	if (vlan) {
 		/* Pass the flags to the hardware bridge */
-		ret = br_switchdev_port_vlan_add(port->dev, vid, flags);
+		ret = br_switchdev_port_vlan_add(port->dev, vid, flags, extack);
 		if (ret && ret != -EOPNOTSUPP)
 			return ret;
 		*changed = __vlan_add_flags(vlan, flags);
@@ -1147,7 +1154,7 @@ int nbp_vlan_add(struct net_bridge_port *port, u16 vid, u16 flags,
 
 	vlan->vid = vid;
 	vlan->port = port;
-	ret = __vlan_add(vlan, flags);
+	ret = __vlan_add(vlan, flags, extack);
 	if (ret)
 		kfree(vlan);
 	else
-- 
2.4.11

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

* [PATCH net-next 3/9] net: switchdev: Add extack argument to switchdev_port_obj_add()
  2018-12-12 11:52 [PATCH net-next 0/9] Pass extack to SWITCHDEV_PORT_OBJ_ADD Petr Machata
  2018-12-12 11:52 ` [PATCH net-next 1/9] net: ndo_bridge_setlink: Add extack Petr Machata
  2018-12-12 11:52 ` [PATCH net-next 2/9] net: bridge: Propagate extack to switchdev Petr Machata
@ 2018-12-12 11:52 ` Petr Machata
  2018-12-12 13:11   ` Ivan Vecera
  2018-12-12 11:52 ` [PATCH net-next 4/9] net: switchdev: Add extack to struct switchdev_notifier_info Petr Machata
                   ` (5 subsequent siblings)
  8 siblings, 1 reply; 19+ messages in thread
From: Petr Machata @ 2018-12-12 11:52 UTC (permalink / raw)
  To: netdev; +Cc: Jiri Pirko, Ido Schimmel, davem, ivecera

After the previous patch, bridge driver has extack argument available to
pass to switchdev. Therefore extend switchdev_port_obj_add() with this
argument, updating all callers, and passing the argument through to
switchdev_port_obj_notify().

Signed-off-by: Petr Machata <petrm@mellanox.com>
Acked-by: Jiri Pirko <jiri@mellanox.com>
---
 include/net/switchdev.h   |  6 ++++--
 net/bridge/br_mdb.c       |  4 ++--
 net/bridge/br_switchdev.c |  2 +-
 net/switchdev/switchdev.c | 19 +++++++++++--------
 4 files changed, 18 insertions(+), 13 deletions(-)

diff --git a/include/net/switchdev.h b/include/net/switchdev.h
index 866b6d148b77..69016305ad58 100644
--- a/include/net/switchdev.h
+++ b/include/net/switchdev.h
@@ -180,7 +180,8 @@ int switchdev_port_attr_get(struct net_device *dev,
 int switchdev_port_attr_set(struct net_device *dev,
 			    const struct switchdev_attr *attr);
 int switchdev_port_obj_add(struct net_device *dev,
-			   const struct switchdev_obj *obj);
+			   const struct switchdev_obj *obj,
+			   struct netlink_ext_ack *extack);
 int switchdev_port_obj_del(struct net_device *dev,
 			   const struct switchdev_obj *obj);
 
@@ -233,7 +234,8 @@ static inline int switchdev_port_attr_set(struct net_device *dev,
 }
 
 static inline int switchdev_port_obj_add(struct net_device *dev,
-					 const struct switchdev_obj *obj)
+					 const struct switchdev_obj *obj,
+					 struct netlink_ext_ack *extack)
 {
 	return -EOPNOTSUPP;
 }
diff --git a/net/bridge/br_mdb.c b/net/bridge/br_mdb.c
index 79d4c9d253e0..f69c8d91dc81 100644
--- a/net/bridge/br_mdb.c
+++ b/net/bridge/br_mdb.c
@@ -331,7 +331,7 @@ static void br_mdb_switchdev_host_port(struct net_device *dev,
 	mdb.obj.orig_dev = dev;
 	switch (type) {
 	case RTM_NEWMDB:
-		switchdev_port_obj_add(lower_dev, &mdb.obj);
+		switchdev_port_obj_add(lower_dev, &mdb.obj, NULL);
 		break;
 	case RTM_DELMDB:
 		switchdev_port_obj_del(lower_dev, &mdb.obj);
@@ -381,7 +381,7 @@ static void __br_mdb_notify(struct net_device *dev, struct net_bridge_port *p,
 			__mdb_entry_to_br_ip(entry, &complete_info->ip);
 			mdb.obj.complete_priv = complete_info;
 			mdb.obj.complete = br_mdb_complete;
-			if (switchdev_port_obj_add(port_dev, &mdb.obj))
+			if (switchdev_port_obj_add(port_dev, &mdb.obj, NULL))
 				kfree(complete_info);
 		}
 	} else if (p && port_dev && type == RTM_DELMDB) {
diff --git a/net/bridge/br_switchdev.c b/net/bridge/br_switchdev.c
index 99ba32177b31..035ff59d9cbd 100644
--- a/net/bridge/br_switchdev.c
+++ b/net/bridge/br_switchdev.c
@@ -151,7 +151,7 @@ int br_switchdev_port_vlan_add(struct net_device *dev, u16 vid, u16 flags,
 		.vid_end = vid,
 	};
 
-	return switchdev_port_obj_add(dev, &v.obj);
+	return switchdev_port_obj_add(dev, &v.obj, extack);
 }
 
 int br_switchdev_port_vlan_del(struct net_device *dev, u16 vid)
diff --git a/net/switchdev/switchdev.c b/net/switchdev/switchdev.c
index fe23fac4dc4b..cb20669bf6ce 100644
--- a/net/switchdev/switchdev.c
+++ b/net/switchdev/switchdev.c
@@ -356,7 +356,8 @@ static size_t switchdev_obj_size(const struct switchdev_obj *obj)
 static int switchdev_port_obj_notify(enum switchdev_notifier_type nt,
 				     struct net_device *dev,
 				     const struct switchdev_obj *obj,
-				     struct switchdev_trans *trans)
+				     struct switchdev_trans *trans,
+				     struct netlink_ext_ack *extack)
 {
 	int rc;
 	int err;
@@ -379,7 +380,8 @@ static int switchdev_port_obj_notify(enum switchdev_notifier_type nt,
 }
 
 static int switchdev_port_obj_add_now(struct net_device *dev,
-				      const struct switchdev_obj *obj)
+				      const struct switchdev_obj *obj,
+				      struct netlink_ext_ack *extack)
 {
 	struct switchdev_trans trans;
 	int err;
@@ -397,7 +399,7 @@ static int switchdev_port_obj_add_now(struct net_device *dev,
 
 	trans.ph_prepare = true;
 	err = switchdev_port_obj_notify(SWITCHDEV_PORT_OBJ_ADD,
-					dev, obj, &trans);
+					dev, obj, &trans, extack);
 	if (err) {
 		/* Prepare phase failed: abort the transaction.  Any
 		 * resources reserved in the prepare phase are
@@ -417,7 +419,7 @@ static int switchdev_port_obj_add_now(struct net_device *dev,
 
 	trans.ph_prepare = false;
 	err = switchdev_port_obj_notify(SWITCHDEV_PORT_OBJ_ADD,
-					dev, obj, &trans);
+					dev, obj, &trans, extack);
 	WARN(err, "%s: Commit of object (id=%d) failed.\n", dev->name, obj->id);
 	switchdev_trans_items_warn_destroy(dev, &trans);
 
@@ -430,7 +432,7 @@ static void switchdev_port_obj_add_deferred(struct net_device *dev,
 	const struct switchdev_obj *obj = data;
 	int err;
 
-	err = switchdev_port_obj_add_now(dev, obj);
+	err = switchdev_port_obj_add_now(dev, obj, NULL);
 	if (err && err != -EOPNOTSUPP)
 		netdev_err(dev, "failed (err=%d) to add object (id=%d)\n",
 			   err, obj->id);
@@ -460,12 +462,13 @@ static int switchdev_port_obj_add_defer(struct net_device *dev,
  *	in case SWITCHDEV_F_DEFER flag is not set.
  */
 int switchdev_port_obj_add(struct net_device *dev,
-			   const struct switchdev_obj *obj)
+			   const struct switchdev_obj *obj,
+			   struct netlink_ext_ack *extack)
 {
 	if (obj->flags & SWITCHDEV_F_DEFER)
 		return switchdev_port_obj_add_defer(dev, obj);
 	ASSERT_RTNL();
-	return switchdev_port_obj_add_now(dev, obj);
+	return switchdev_port_obj_add_now(dev, obj, extack);
 }
 EXPORT_SYMBOL_GPL(switchdev_port_obj_add);
 
@@ -473,7 +476,7 @@ static int switchdev_port_obj_del_now(struct net_device *dev,
 				      const struct switchdev_obj *obj)
 {
 	return switchdev_port_obj_notify(SWITCHDEV_PORT_OBJ_DEL,
-					 dev, obj, NULL);
+					 dev, obj, NULL, NULL);
 }
 
 static void switchdev_port_obj_del_deferred(struct net_device *dev,
-- 
2.4.11

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

* [PATCH net-next 4/9] net: switchdev: Add extack to struct switchdev_notifier_info
  2018-12-12 11:52 [PATCH net-next 0/9] Pass extack to SWITCHDEV_PORT_OBJ_ADD Petr Machata
                   ` (2 preceding siblings ...)
  2018-12-12 11:52 ` [PATCH net-next 3/9] net: switchdev: Add extack argument to switchdev_port_obj_add() Petr Machata
@ 2018-12-12 11:52 ` Petr Machata
  2018-12-12 13:12   ` Ivan Vecera
  2018-12-12 11:52 ` [PATCH net-next 5/9] net: switchdev: Add extack to switchdev_handle_port_obj_add() callback Petr Machata
                   ` (4 subsequent siblings)
  8 siblings, 1 reply; 19+ messages in thread
From: Petr Machata @ 2018-12-12 11:52 UTC (permalink / raw)
  To: netdev; +Cc: Jiri Pirko, Ido Schimmel, davem, ivecera

In order to pass extack to the drivers that need it, add an extack field
to struct switchdev_notifier_info, and an extack argument to the
function call_switchdev_blocking_notifiers(). Also add a helper function
switchdev_notifier_info_to_extack().

Signed-off-by: Petr Machata <petrm@mellanox.com>
Acked-by: Jiri Pirko <jiri@mellanox.com>
---
 drivers/net/vxlan.c       |  1 +
 include/net/switchdev.h   | 13 +++++++++++--
 net/switchdev/switchdev.c |  7 +++++--
 3 files changed, 17 insertions(+), 4 deletions(-)

diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c
index b56ef684ecac..49d4b5854c62 100644
--- a/drivers/net/vxlan.c
+++ b/drivers/net/vxlan.c
@@ -364,6 +364,7 @@ static void vxlan_fdb_switchdev_notifier_info(const struct vxlan_dev *vxlan,
 			    struct switchdev_notifier_vxlan_fdb_info *fdb_info)
 {
 	fdb_info->info.dev = vxlan->dev;
+	fdb_info->info.extack = NULL;
 	fdb_info->remote_ip = rd->remote_ip;
 	fdb_info->remote_port = rd->remote_port;
 	fdb_info->remote_vni = rd->remote_vni;
diff --git a/include/net/switchdev.h b/include/net/switchdev.h
index 69016305ad58..4facfa6775e8 100644
--- a/include/net/switchdev.h
+++ b/include/net/switchdev.h
@@ -149,6 +149,7 @@ enum switchdev_notifier_type {
 
 struct switchdev_notifier_info {
 	struct net_device *dev;
+	struct netlink_ext_ack *extack;
 };
 
 struct switchdev_notifier_fdb_info {
@@ -172,6 +173,12 @@ switchdev_notifier_info_to_dev(const struct switchdev_notifier_info *info)
 	return info->dev;
 }
 
+static inline struct netlink_ext_ack *
+switchdev_notifier_info_to_extack(const struct switchdev_notifier_info *info)
+{
+	return info->extack;
+}
+
 #ifdef CONFIG_NET_SWITCHDEV
 
 void switchdev_deferred_process(void);
@@ -193,7 +200,8 @@ int call_switchdev_notifiers(unsigned long val, struct net_device *dev,
 int register_switchdev_blocking_notifier(struct notifier_block *nb);
 int unregister_switchdev_blocking_notifier(struct notifier_block *nb);
 int call_switchdev_blocking_notifiers(unsigned long val, struct net_device *dev,
-				      struct switchdev_notifier_info *info);
+				      struct switchdev_notifier_info *info,
+				      struct netlink_ext_ack *extack);
 
 void switchdev_port_fwd_mark_set(struct net_device *dev,
 				 struct net_device *group_dev,
@@ -278,7 +286,8 @@ unregister_switchdev_blocking_notifier(struct notifier_block *nb)
 static inline int
 call_switchdev_blocking_notifiers(unsigned long val,
 				  struct net_device *dev,
-				  struct switchdev_notifier_info *info)
+				  struct switchdev_notifier_info *info,
+				  struct netlink_ext_ack *extack)
 {
 	return NOTIFY_DONE;
 }
diff --git a/net/switchdev/switchdev.c b/net/switchdev/switchdev.c
index cb20669bf6ce..aa84acfb6632 100644
--- a/net/switchdev/switchdev.c
+++ b/net/switchdev/switchdev.c
@@ -368,7 +368,7 @@ static int switchdev_port_obj_notify(enum switchdev_notifier_type nt,
 		.handled = false,
 	};
 
-	rc = call_switchdev_blocking_notifiers(nt, dev, &obj_info.info);
+	rc = call_switchdev_blocking_notifiers(nt, dev, &obj_info.info, extack);
 	err = notifier_to_errno(rc);
 	if (err) {
 		WARN_ON(!obj_info.handled);
@@ -559,6 +559,7 @@ int call_switchdev_notifiers(unsigned long val, struct net_device *dev,
 			     struct switchdev_notifier_info *info)
 {
 	info->dev = dev;
+	info->extack = NULL;
 	return atomic_notifier_call_chain(&switchdev_notif_chain, val, info);
 }
 EXPORT_SYMBOL_GPL(call_switchdev_notifiers);
@@ -580,9 +581,11 @@ int unregister_switchdev_blocking_notifier(struct notifier_block *nb)
 EXPORT_SYMBOL_GPL(unregister_switchdev_blocking_notifier);
 
 int call_switchdev_blocking_notifiers(unsigned long val, struct net_device *dev,
-				      struct switchdev_notifier_info *info)
+				      struct switchdev_notifier_info *info,
+				      struct netlink_ext_ack *extack)
 {
 	info->dev = dev;
+	info->extack = extack;
 	return blocking_notifier_call_chain(&switchdev_blocking_notif_chain,
 					    val, info);
 }
-- 
2.4.11

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

* [PATCH net-next 5/9] net: switchdev: Add extack to switchdev_handle_port_obj_add() callback
  2018-12-12 11:52 [PATCH net-next 0/9] Pass extack to SWITCHDEV_PORT_OBJ_ADD Petr Machata
                   ` (3 preceding siblings ...)
  2018-12-12 11:52 ` [PATCH net-next 4/9] net: switchdev: Add extack to struct switchdev_notifier_info Petr Machata
@ 2018-12-12 11:52 ` Petr Machata
  2018-12-12 13:12   ` Ivan Vecera
  2018-12-12 11:52 ` [PATCH net-next 6/9] mlxsw: spectrum_switchdev: Propagate extack on VXLAN VLAN events Petr Machata
                   ` (3 subsequent siblings)
  8 siblings, 1 reply; 19+ messages in thread
From: Petr Machata @ 2018-12-12 11:52 UTC (permalink / raw)
  To: netdev; +Cc: Jiri Pirko, Ido Schimmel, davem, ivecera

Drivers use switchdev_handle_port_obj_add() to handle recursive descent
through lower devices. Change this function prototype to take add_cb
that itself takes an extack argument. Decode extack from
switchdev_notifier_port_obj_info and pass it to add_cb.

Update mlxsw and ocelot drivers which use this helper.

Signed-off-by: Petr Machata <petrm@mellanox.com>
Acked-by: Jiri Pirko <jiri@mellanox.com>
---
 drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c |  3 ++-
 drivers/net/ethernet/mscc/ocelot.c                       |  3 ++-
 include/net/switchdev.h                                  |  6 ++++--
 net/switchdev/switchdev.c                                | 12 +++++++++---
 4 files changed, 17 insertions(+), 7 deletions(-)

diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
index 5ad1fcebf788..4b9292289256 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
@@ -1777,7 +1777,8 @@ static void mlxsw_sp_span_respin_schedule(struct mlxsw_sp *mlxsw_sp)
 
 static int mlxsw_sp_port_obj_add(struct net_device *dev,
 				 const struct switchdev_obj *obj,
-				 struct switchdev_trans *trans)
+				 struct switchdev_trans *trans,
+				 struct netlink_ext_ack *extack)
 {
 	struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev);
 	const struct switchdev_obj_port_vlan *vlan;
diff --git a/drivers/net/ethernet/mscc/ocelot.c b/drivers/net/ethernet/mscc/ocelot.c
index 7f8da8873a96..ea3eec263875 100644
--- a/drivers/net/ethernet/mscc/ocelot.c
+++ b/drivers/net/ethernet/mscc/ocelot.c
@@ -1293,7 +1293,8 @@ static int ocelot_port_obj_del_mdb(struct net_device *dev,
 
 static int ocelot_port_obj_add(struct net_device *dev,
 			       const struct switchdev_obj *obj,
-			       struct switchdev_trans *trans)
+			       struct switchdev_trans *trans,
+			       struct netlink_ext_ack *extack)
 {
 	int ret = 0;
 
diff --git a/include/net/switchdev.h b/include/net/switchdev.h
index 4facfa6775e8..a7fdab5ee6c3 100644
--- a/include/net/switchdev.h
+++ b/include/net/switchdev.h
@@ -215,7 +215,8 @@ int switchdev_handle_port_obj_add(struct net_device *dev,
 			bool (*check_cb)(const struct net_device *dev),
 			int (*add_cb)(struct net_device *dev,
 				      const struct switchdev_obj *obj,
-				      struct switchdev_trans *trans));
+				      struct switchdev_trans *trans,
+				      struct netlink_ext_ack *extack));
 int switchdev_handle_port_obj_del(struct net_device *dev,
 			struct switchdev_notifier_port_obj_info *port_obj_info,
 			bool (*check_cb)(const struct net_device *dev),
@@ -304,7 +305,8 @@ switchdev_handle_port_obj_add(struct net_device *dev,
 			bool (*check_cb)(const struct net_device *dev),
 			int (*add_cb)(struct net_device *dev,
 				      const struct switchdev_obj *obj,
-				      struct switchdev_trans *trans))
+				      struct switchdev_trans *trans,
+				      struct netlink_ext_ack *extack))
 {
 	return 0;
 }
diff --git a/net/switchdev/switchdev.c b/net/switchdev/switchdev.c
index aa84acfb6632..5df9d1138ac9 100644
--- a/net/switchdev/switchdev.c
+++ b/net/switchdev/switchdev.c
@@ -616,16 +616,21 @@ static int __switchdev_handle_port_obj_add(struct net_device *dev,
 			bool (*check_cb)(const struct net_device *dev),
 			int (*add_cb)(struct net_device *dev,
 				      const struct switchdev_obj *obj,
-				      struct switchdev_trans *trans))
+				      struct switchdev_trans *trans,
+				      struct netlink_ext_ack *extack))
 {
+	struct netlink_ext_ack *extack;
 	struct net_device *lower_dev;
 	struct list_head *iter;
 	int err = -EOPNOTSUPP;
 
+	extack = switchdev_notifier_info_to_extack(&port_obj_info->info);
+
 	if (check_cb(dev)) {
 		/* This flag is only checked if the return value is success. */
 		port_obj_info->handled = true;
-		return add_cb(dev, port_obj_info->obj, port_obj_info->trans);
+		return add_cb(dev, port_obj_info->obj, port_obj_info->trans,
+			      extack);
 	}
 
 	/* Switch ports might be stacked under e.g. a LAG. Ignore the
@@ -650,7 +655,8 @@ int switchdev_handle_port_obj_add(struct net_device *dev,
 			bool (*check_cb)(const struct net_device *dev),
 			int (*add_cb)(struct net_device *dev,
 				      const struct switchdev_obj *obj,
-				      struct switchdev_trans *trans))
+				      struct switchdev_trans *trans,
+				      struct netlink_ext_ack *extack))
 {
 	int err;
 
-- 
2.4.11

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

* [PATCH net-next 6/9] mlxsw: spectrum_switchdev: Propagate extack on VXLAN VLAN events
  2018-12-12 11:52 [PATCH net-next 0/9] Pass extack to SWITCHDEV_PORT_OBJ_ADD Petr Machata
                   ` (4 preceding siblings ...)
  2018-12-12 11:52 ` [PATCH net-next 5/9] net: switchdev: Add extack to switchdev_handle_port_obj_add() callback Petr Machata
@ 2018-12-12 11:52 ` Petr Machata
  2018-12-12 11:52 ` [PATCH net-next 7/9] mlxsw: spectrum_switchdev: Propagate extack on port " Petr Machata
                   ` (2 subsequent siblings)
  8 siblings, 0 replies; 19+ messages in thread
From: Petr Machata @ 2018-12-12 11:52 UTC (permalink / raw)
  To: netdev; +Cc: Jiri Pirko, Ido Schimmel, davem, ivecera

Now that VLAN port object addition notifications carry an extack,
propagate it from mlxsw_sp_switchdev_vxlan_vlans_add() through
mlxsw_sp_switchdev_vxlan_vlan_add() to
mlxsw_sp_bridge_8021q_vxlan_join().

This code path is used when a VLAN is added to a VXLAN netdevice that
cannot be offloaded.

Signed-off-by: Petr Machata <petrm@mellanox.com>
Acked-by: Jiri Pirko <jiri@mellanox.com>
---
 drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c | 12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
index 4b9292289256..906dfded3098 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
@@ -3205,7 +3205,8 @@ mlxsw_sp_switchdev_vxlan_vlan_add(struct mlxsw_sp *mlxsw_sp,
 				  struct mlxsw_sp_bridge_device *bridge_device,
 				  const struct net_device *vxlan_dev, u16 vid,
 				  bool flag_untagged, bool flag_pvid,
-				  struct switchdev_trans *trans)
+				  struct switchdev_trans *trans,
+				  struct netlink_ext_ack *extack)
 {
 	struct vxlan_dev *vxlan = netdev_priv(vxlan_dev);
 	__be32 vni = vxlan->cfg.vni;
@@ -3237,7 +3238,7 @@ mlxsw_sp_switchdev_vxlan_vlan_add(struct mlxsw_sp *mlxsw_sp,
 		if (!flag_untagged || !flag_pvid)
 			return 0;
 		return mlxsw_sp_bridge_8021q_vxlan_join(bridge_device,
-							vxlan_dev, vid, NULL);
+							vxlan_dev, vid, extack);
 	}
 
 	/* Second case: FID is associated with the VNI and the VLAN associated
@@ -3277,7 +3278,7 @@ mlxsw_sp_switchdev_vxlan_vlan_add(struct mlxsw_sp *mlxsw_sp,
 		return 0;
 
 	err = mlxsw_sp_bridge_8021q_vxlan_join(bridge_device, vxlan_dev, vid,
-					       NULL);
+					       extack);
 	if (err)
 		goto err_vxlan_join;
 
@@ -3326,10 +3327,12 @@ mlxsw_sp_switchdev_vxlan_vlans_add(struct net_device *vxlan_dev,
 	bool flag_pvid = vlan->flags & BRIDGE_VLAN_INFO_PVID;
 	struct switchdev_trans *trans = port_obj_info->trans;
 	struct mlxsw_sp_bridge_device *bridge_device;
+	struct netlink_ext_ack *extack;
 	struct mlxsw_sp *mlxsw_sp;
 	struct net_device *br_dev;
 	u16 vid;
 
+	extack = switchdev_notifier_info_to_extack(&port_obj_info->info);
 	br_dev = netdev_master_upper_dev_get(vxlan_dev);
 	if (!br_dev)
 		return 0;
@@ -3353,7 +3356,8 @@ mlxsw_sp_switchdev_vxlan_vlans_add(struct net_device *vxlan_dev,
 		err = mlxsw_sp_switchdev_vxlan_vlan_add(mlxsw_sp, bridge_device,
 							vxlan_dev, vid,
 							flag_untagged,
-							flag_pvid, trans);
+							flag_pvid, trans,
+							extack);
 		if (err)
 			return err;
 	}
-- 
2.4.11

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

* [PATCH net-next 7/9] mlxsw: spectrum_switchdev: Propagate extack on port VLAN events
  2018-12-12 11:52 [PATCH net-next 0/9] Pass extack to SWITCHDEV_PORT_OBJ_ADD Petr Machata
                   ` (5 preceding siblings ...)
  2018-12-12 11:52 ` [PATCH net-next 6/9] mlxsw: spectrum_switchdev: Propagate extack on VXLAN VLAN events Petr Machata
@ 2018-12-12 11:52 ` Petr Machata
  2018-12-12 11:52 ` [PATCH net-next 8/9] selftests: mlxsw: extack: Test VLAN add on a VXLAN device Petr Machata
  2018-12-12 11:52 ` [PATCH net-next 9/9] selftests: mlxsw: extack: Test VLAN add on a port device Petr Machata
  8 siblings, 0 replies; 19+ messages in thread
From: Petr Machata @ 2018-12-12 11:52 UTC (permalink / raw)
  To: netdev; +Cc: Jiri Pirko, Ido Schimmel, davem, ivecera

After switchdev_handle_port_obj_add() was extended in a preceding patch,
mlxsw_sp_port_obj_add() now takes an extack argument. Propagate it
further by extending a callee chain from mlxsw_sp_port_vlans_add(), via
mlxsw_sp_bridge_port_vlan_add() via mlxsw_sp_port_vlan_bridge_join() via
mlxsw_sp_port_vlan_fid_join() to mlxsw_sp_bridge_ops.fid_get, adding an
extack argument for each of them.

This code path is used when a VLAN is added to a port netdevice if there
already is an unoffloadable VXLAN device with that VLAN mapped.

mlxsw_sp_bridge_8021d_port_join() is updated to obey the new interfaces
changed by the abovementioned code, propagating extack ultimately from
NETDEV_CHANGEUPPER events.

Signed-off-by: Petr Machata <petrm@mellanox.com>
Acked-by: Jiri Pirko <jiri@mellanox.com>
---
 .../ethernet/mellanox/mlxsw/spectrum_switchdev.c   | 38 +++++++++++++---------
 1 file changed, 23 insertions(+), 15 deletions(-)

diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
index 906dfded3098..627efe7a6eef 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
@@ -89,7 +89,7 @@ struct mlxsw_sp_bridge_ops {
 			  struct netlink_ext_ack *extack);
 	struct mlxsw_sp_fid *
 		(*fid_get)(struct mlxsw_sp_bridge_device *bridge_device,
-			   u16 vid);
+			   u16 vid, struct netlink_ext_ack *extack);
 	struct mlxsw_sp_fid *
 		(*fid_lookup)(struct mlxsw_sp_bridge_device *bridge_device,
 			      u16 vid);
@@ -933,7 +933,8 @@ static int mlxsw_sp_port_attr_set(struct net_device *dev,
 
 static int
 mlxsw_sp_port_vlan_fid_join(struct mlxsw_sp_port_vlan *mlxsw_sp_port_vlan,
-			    struct mlxsw_sp_bridge_port *bridge_port)
+			    struct mlxsw_sp_bridge_port *bridge_port,
+			    struct netlink_ext_ack *extack)
 {
 	struct mlxsw_sp_port *mlxsw_sp_port = mlxsw_sp_port_vlan->mlxsw_sp_port;
 	struct mlxsw_sp_bridge_device *bridge_device;
@@ -943,7 +944,7 @@ mlxsw_sp_port_vlan_fid_join(struct mlxsw_sp_port_vlan *mlxsw_sp_port_vlan,
 	int err;
 
 	bridge_device = bridge_port->bridge_device;
-	fid = bridge_device->ops->fid_get(bridge_device, vid);
+	fid = bridge_device->ops->fid_get(bridge_device, vid, extack);
 	if (IS_ERR(fid))
 		return PTR_ERR(fid);
 
@@ -1011,7 +1012,8 @@ mlxsw_sp_port_pvid_determine(const struct mlxsw_sp_port *mlxsw_sp_port,
 
 static int
 mlxsw_sp_port_vlan_bridge_join(struct mlxsw_sp_port_vlan *mlxsw_sp_port_vlan,
-			       struct mlxsw_sp_bridge_port *bridge_port)
+			       struct mlxsw_sp_bridge_port *bridge_port,
+			       struct netlink_ext_ack *extack)
 {
 	struct mlxsw_sp_port *mlxsw_sp_port = mlxsw_sp_port_vlan->mlxsw_sp_port;
 	struct mlxsw_sp_bridge_vlan *bridge_vlan;
@@ -1024,7 +1026,8 @@ mlxsw_sp_port_vlan_bridge_join(struct mlxsw_sp_port_vlan *mlxsw_sp_port_vlan,
 		return 0;
 	}
 
-	err = mlxsw_sp_port_vlan_fid_join(mlxsw_sp_port_vlan, bridge_port);
+	err = mlxsw_sp_port_vlan_fid_join(mlxsw_sp_port_vlan, bridge_port,
+					  extack);
 	if (err)
 		return err;
 
@@ -1101,7 +1104,8 @@ mlxsw_sp_port_vlan_bridge_leave(struct mlxsw_sp_port_vlan *mlxsw_sp_port_vlan)
 static int
 mlxsw_sp_bridge_port_vlan_add(struct mlxsw_sp_port *mlxsw_sp_port,
 			      struct mlxsw_sp_bridge_port *bridge_port,
-			      u16 vid, bool is_untagged, bool is_pvid)
+			      u16 vid, bool is_untagged, bool is_pvid,
+			      struct netlink_ext_ack *extack)
 {
 	u16 pvid = mlxsw_sp_port_pvid_determine(mlxsw_sp_port, vid, is_pvid);
 	struct mlxsw_sp_port_vlan *mlxsw_sp_port_vlan;
@@ -1121,7 +1125,8 @@ mlxsw_sp_bridge_port_vlan_add(struct mlxsw_sp_port *mlxsw_sp_port,
 	if (err)
 		goto err_port_pvid_set;
 
-	err = mlxsw_sp_port_vlan_bridge_join(mlxsw_sp_port_vlan, bridge_port);
+	err = mlxsw_sp_port_vlan_bridge_join(mlxsw_sp_port_vlan, bridge_port,
+					     extack);
 	if (err)
 		goto err_port_vlan_bridge_join;
 
@@ -1171,7 +1176,8 @@ mlxsw_sp_br_ban_rif_pvid_change(struct mlxsw_sp *mlxsw_sp,
 
 static int mlxsw_sp_port_vlans_add(struct mlxsw_sp_port *mlxsw_sp_port,
 				   const struct switchdev_obj_port_vlan *vlan,
-				   struct switchdev_trans *trans)
+				   struct switchdev_trans *trans,
+				   struct netlink_ext_ack *extack)
 {
 	bool flag_untagged = vlan->flags & BRIDGE_VLAN_INFO_UNTAGGED;
 	bool flag_pvid = vlan->flags & BRIDGE_VLAN_INFO_PVID;
@@ -1208,7 +1214,7 @@ static int mlxsw_sp_port_vlans_add(struct mlxsw_sp_port *mlxsw_sp_port,
 
 		err = mlxsw_sp_bridge_port_vlan_add(mlxsw_sp_port, bridge_port,
 						    vid, flag_untagged,
-						    flag_pvid);
+						    flag_pvid, extack);
 		if (err)
 			return err;
 	}
@@ -1787,7 +1793,8 @@ static int mlxsw_sp_port_obj_add(struct net_device *dev,
 	switch (obj->id) {
 	case SWITCHDEV_OBJ_ID_PORT_VLAN:
 		vlan = SWITCHDEV_OBJ_PORT_VLAN(obj);
-		err = mlxsw_sp_port_vlans_add(mlxsw_sp_port, vlan, trans);
+		err = mlxsw_sp_port_vlans_add(mlxsw_sp_port, vlan, trans,
+					      extack);
 
 		if (switchdev_trans_ph_prepare(trans)) {
 			/* The event is emitted before the changes are actually
@@ -2087,7 +2094,7 @@ mlxsw_sp_bridge_8021q_vxlan_dev_find(struct net_device *br_dev, u16 vid)
 
 static struct mlxsw_sp_fid *
 mlxsw_sp_bridge_8021q_fid_get(struct mlxsw_sp_bridge_device *bridge_device,
-			      u16 vid)
+			      u16 vid, struct netlink_ext_ack *extack)
 {
 	struct mlxsw_sp *mlxsw_sp = mlxsw_sp_lower_get(bridge_device->dev);
 	struct net_device *vxlan_dev;
@@ -2113,7 +2120,7 @@ mlxsw_sp_bridge_8021q_fid_get(struct mlxsw_sp_bridge_device *bridge_device,
 		return fid;
 
 	err = mlxsw_sp_bridge_8021q_vxlan_join(bridge_device, vxlan_dev, vid,
-					       NULL);
+					       extack);
 	if (err)
 		goto err_vxlan_join;
 
@@ -2190,7 +2197,8 @@ mlxsw_sp_bridge_8021d_port_join(struct mlxsw_sp_bridge_device *bridge_device,
 	if (mlxsw_sp_port_vlan->fid)
 		mlxsw_sp_port_vlan_router_leave(mlxsw_sp_port_vlan);
 
-	return mlxsw_sp_port_vlan_bridge_join(mlxsw_sp_port_vlan, bridge_port);
+	return mlxsw_sp_port_vlan_bridge_join(mlxsw_sp_port_vlan, bridge_port,
+					      extack);
 }
 
 static void
@@ -2253,7 +2261,7 @@ mlxsw_sp_bridge_8021d_vxlan_join(struct mlxsw_sp_bridge_device *bridge_device,
 
 static struct mlxsw_sp_fid *
 mlxsw_sp_bridge_8021d_fid_get(struct mlxsw_sp_bridge_device *bridge_device,
-			      u16 vid)
+			      u16 vid, struct netlink_ext_ack *extack)
 {
 	struct mlxsw_sp *mlxsw_sp = mlxsw_sp_lower_get(bridge_device->dev);
 	struct net_device *vxlan_dev;
@@ -2275,7 +2283,7 @@ mlxsw_sp_bridge_8021d_fid_get(struct mlxsw_sp_bridge_device *bridge_device,
 		return fid;
 
 	err = mlxsw_sp_bridge_8021d_vxlan_join(bridge_device, vxlan_dev, 0,
-					       NULL);
+					       extack);
 	if (err)
 		goto err_vxlan_join;
 
-- 
2.4.11

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

* [PATCH net-next 8/9] selftests: mlxsw: extack: Test VLAN add on a VXLAN device
  2018-12-12 11:52 [PATCH net-next 0/9] Pass extack to SWITCHDEV_PORT_OBJ_ADD Petr Machata
                   ` (6 preceding siblings ...)
  2018-12-12 11:52 ` [PATCH net-next 7/9] mlxsw: spectrum_switchdev: Propagate extack on port " Petr Machata
@ 2018-12-12 11:52 ` Petr Machata
  2018-12-12 11:52 ` [PATCH net-next 9/9] selftests: mlxsw: extack: Test VLAN add on a port device Petr Machata
  8 siblings, 0 replies; 19+ messages in thread
From: Petr Machata @ 2018-12-12 11:52 UTC (permalink / raw)
  To: netdev; +Cc: Jiri Pirko, Ido Schimmel, davem, ivecera

Test mapping a VLAN at a VXLAN device that can't be offloaded.

Signed-off-by: Petr Machata <petrm@mellanox.com>
Acked-by: Jiri Pirko <jiri@mellanox.com>
---
 .../testing/selftests/drivers/net/mlxsw/extack.sh  | 31 ++++++++++++++++++++++
 1 file changed, 31 insertions(+)

diff --git a/tools/testing/selftests/drivers/net/mlxsw/extack.sh b/tools/testing/selftests/drivers/net/mlxsw/extack.sh
index 101a5508bdfd..d9e02624c70b 100755
--- a/tools/testing/selftests/drivers/net/mlxsw/extack.sh
+++ b/tools/testing/selftests/drivers/net/mlxsw/extack.sh
@@ -7,6 +7,7 @@ lib_dir=$(dirname $0)/../../../net/forwarding
 
 ALL_TESTS="
 	netdev_pre_up_test
+	vxlan_vlan_add_test
 "
 NUM_NETIFS=2
 source $lib_dir/lib.sh
@@ -74,6 +75,36 @@ netdev_pre_up_test()
 	ip link del dev br1
 }
 
+vxlan_vlan_add_test()
+{
+	RET=0
+
+	ip link add name br1 up type bridge vlan_filtering 1 mcast_snooping 0
+
+	# Unsupported configuration: mlxsw demands VXLAN with "noudpcsum".
+	ip link add name vx1 up type vxlan id 1000 \
+		local 192.0.2.17 remote 192.0.2.18 \
+		dstport 4789 tos inherit ttl 100
+
+	ip link set dev vx1 master br1
+	check_err $?
+
+	bridge vlan add dev vx1 vid 1
+	check_err $?
+
+	ip link set dev $swp1 master br1
+	check_err $?
+
+	bridge vlan add dev vx1 vid 1 pvid untagged 2>&1 >/dev/null \
+		| grep -q mlxsw_spectrum
+	check_err $?
+
+	log_test "extack - map VLAN at VXLAN device"
+
+	ip link del dev vx1
+	ip link del dev br1
+}
+
 trap cleanup EXIT
 
 setup_prepare
-- 
2.4.11

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

* [PATCH net-next 9/9] selftests: mlxsw: extack: Test VLAN add on a port device
  2018-12-12 11:52 [PATCH net-next 0/9] Pass extack to SWITCHDEV_PORT_OBJ_ADD Petr Machata
                   ` (7 preceding siblings ...)
  2018-12-12 11:52 ` [PATCH net-next 8/9] selftests: mlxsw: extack: Test VLAN add on a VXLAN device Petr Machata
@ 2018-12-12 11:52 ` Petr Machata
  8 siblings, 0 replies; 19+ messages in thread
From: Petr Machata @ 2018-12-12 11:52 UTC (permalink / raw)
  To: netdev; +Cc: Jiri Pirko, Ido Schimmel, davem, ivecera

Test mapping a VLAN at a port device such that on the same VLAN, there
already is an unoffloadable VXLAN device.

Signed-off-by: Petr Machata <petrm@mellanox.com>
Acked-by: Jiri Pirko <jiri@mellanox.com>
---
 .../testing/selftests/drivers/net/mlxsw/extack.sh  | 30 ++++++++++++++++++++++
 1 file changed, 30 insertions(+)

diff --git a/tools/testing/selftests/drivers/net/mlxsw/extack.sh b/tools/testing/selftests/drivers/net/mlxsw/extack.sh
index d9e02624c70b..d72d8488a3b2 100755
--- a/tools/testing/selftests/drivers/net/mlxsw/extack.sh
+++ b/tools/testing/selftests/drivers/net/mlxsw/extack.sh
@@ -8,6 +8,7 @@ lib_dir=$(dirname $0)/../../../net/forwarding
 ALL_TESTS="
 	netdev_pre_up_test
 	vxlan_vlan_add_test
+	port_vlan_add_test
 "
 NUM_NETIFS=2
 source $lib_dir/lib.sh
@@ -105,6 +106,35 @@ vxlan_vlan_add_test()
 	ip link del dev br1
 }
 
+port_vlan_add_test()
+{
+	RET=0
+
+	ip link add name br1 up type bridge vlan_filtering 1 mcast_snooping 0
+
+	# Unsupported configuration: mlxsw demands VXLAN with "noudpcsum".
+	ip link add name vx1 up type vxlan id 1000 \
+		local 192.0.2.17 remote 192.0.2.18 \
+		dstport 4789 tos inherit ttl 100
+
+	ip link set dev $swp1 master br1
+	check_err $?
+
+	bridge vlan del dev $swp1 vid 1
+
+	ip link set dev vx1 master br1
+	check_err $?
+
+	bridge vlan add dev $swp1 vid 1 pvid untagged 2>&1 >/dev/null \
+		| grep -q mlxsw_spectrum
+	check_err $?
+
+	log_test "extack - map VLAN at port"
+
+	ip link del dev vx1
+	ip link del dev br1
+}
+
 trap cleanup EXIT
 
 setup_prepare
-- 
2.4.11

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

* Re: [PATCH net-next 2/9] net: bridge: Propagate extack to switchdev
  2018-12-12 11:52 ` [PATCH net-next 2/9] net: bridge: Propagate extack to switchdev Petr Machata
@ 2018-12-12 12:20     ` Nikolay Aleksandrov
  2018-12-12 13:05   ` Ivan Vecera
  2018-12-12 15:33   ` Roopa Prabhu
  2 siblings, 0 replies; 19+ messages in thread
From: Nikolay Aleksandrov @ 2018-12-12 12:20 UTC (permalink / raw)
  To: Petr Machata, netdev
  Cc: Jiri Pirko, Ido Schimmel, davem, ivecera, Roopa Prabhu,
	David Ahern, bridge

On 12/12/2018 13:52, Petr Machata wrote:
> ndo_bridge_setlink has been updated in the previous patch to have extack
> available, and changelink RTNL op has had this argument since the time
> extack was added. Propagate both through the bridge driver to eventually
> reach br_switchdev_port_vlan_add(), where it will be used by subsequent
> patches.
> 
> Signed-off-by: Petr Machata <petrm@mellanox.com>
> Acked-by: Jiri Pirko <jiri@mellanox.com>
> ---
>  net/bridge/br_if.c        |  2 +-
>  net/bridge/br_netlink.c   | 27 +++++++++++++---------
>  net/bridge/br_private.h   | 22 ++++++++++--------
>  net/bridge/br_switchdev.c |  3 ++-
>  net/bridge/br_vlan.c      | 59 ++++++++++++++++++++++++++---------------------
>  5 files changed, 65 insertions(+), 48 deletions(-)
> 

+CC Roopa & bridge list

Looks good to me.
Acked-by: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>

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

* Re: [Bridge] [PATCH net-next 2/9] net: bridge: Propagate extack to switchdev
@ 2018-12-12 12:20     ` Nikolay Aleksandrov
  0 siblings, 0 replies; 19+ messages in thread
From: Nikolay Aleksandrov @ 2018-12-12 12:20 UTC (permalink / raw)
  To: Petr Machata, netdev
  Cc: ivecera, Roopa Prabhu, bridge, Ido Schimmel, Jiri Pirko,
	David Ahern, davem

On 12/12/2018 13:52, Petr Machata wrote:
> ndo_bridge_setlink has been updated in the previous patch to have extack
> available, and changelink RTNL op has had this argument since the time
> extack was added. Propagate both through the bridge driver to eventually
> reach br_switchdev_port_vlan_add(), where it will be used by subsequent
> patches.
> 
> Signed-off-by: Petr Machata <petrm@mellanox.com>
> Acked-by: Jiri Pirko <jiri@mellanox.com>
> ---
>  net/bridge/br_if.c        |  2 +-
>  net/bridge/br_netlink.c   | 27 +++++++++++++---------
>  net/bridge/br_private.h   | 22 ++++++++++--------
>  net/bridge/br_switchdev.c |  3 ++-
>  net/bridge/br_vlan.c      | 59 ++++++++++++++++++++++++++---------------------
>  5 files changed, 65 insertions(+), 48 deletions(-)
> 

+CC Roopa & bridge list

Looks good to me.
Acked-by: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>


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

* Re: [PATCH net-next 1/9] net: ndo_bridge_setlink: Add extack
  2018-12-12 11:52 ` [PATCH net-next 1/9] net: ndo_bridge_setlink: Add extack Petr Machata
@ 2018-12-12 12:26   ` Nikolay Aleksandrov
  2018-12-12 13:58     ` Petr Machata
  0 siblings, 1 reply; 19+ messages in thread
From: Nikolay Aleksandrov @ 2018-12-12 12:26 UTC (permalink / raw)
  To: Petr Machata, netdev; +Cc: Jiri Pirko, Ido Schimmel, davem, ivecera

On 12/12/2018 13:52, Petr Machata wrote:
> Drivers may not be able to implement a VLAN addition or reconfiguration.
> In those cases it's desirable to explain to the user that it was
> rejected (and why).
> 
> To that end, add extack argument to ndo_bridge_setlink. Adapt all users
> to that change.
> 
> Following patches will use the new argument in the bridge driver.
> 
> Signed-off-by: Petr Machata <petrm@mellanox.com>
> Acked-by: Jiri Pirko <jiri@mellanox.com>
> ---
>  drivers/net/ethernet/broadcom/bnxt/bnxt.c     | 2 +-
>  drivers/net/ethernet/emulex/benet/be_main.c   | 2 +-
>  drivers/net/ethernet/intel/i40e/i40e_main.c   | 4 +++-
>  drivers/net/ethernet/intel/ice/ice_main.c     | 3 ++-
>  drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 3 ++-
>  include/linux/netdevice.h                     | 6 ++++--
>  net/bridge/br_netlink.c                       | 3 ++-
>  net/bridge/br_private.h                       | 3 ++-
>  net/core/rtnetlink.c                          | 6 ++++--
>  9 files changed, 21 insertions(+), 11 deletions(-)
> 
[snip]
> diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
> index fc6ba71513be..d8046696d27b 100644
> --- a/include/linux/netdevice.h
> +++ b/include/linux/netdevice.h
> @@ -1165,7 +1165,7 @@ struct dev_ifalias {
>   *	entries to skb and update idx with the number of entries.
>   *
>   * int (*ndo_bridge_setlink)(struct net_device *dev, struct nlmsghdr *nlh,
> - *			     u16 flags)
> + *			     u16 flags, struct netlink_ext_ack *extack)
>   * int (*ndo_bridge_getlink)(struct sk_buff *skb, u32 pid, u32 seq,
>   *			     struct net_device *dev, u32 filter_mask,
>   *			     int nlflags)
> @@ -1390,7 +1390,9 @@ struct net_device_ops {
>  
>  	int			(*ndo_bridge_setlink)(struct net_device *dev,
>  						      struct nlmsghdr *nlh,
> -						      u16 flags);
> +						      u16 flags,
> +						      struct netlink_ext_ack *
> +						      extack);

IMO it's better to have struct netlink_ext_ack and extack on the same
line even if it goes a little over 80 here, it is normal for netdevice
ops and wouldn't be the first (check below or above). At first I thought
the arg name is missing. :)

>  	int			(*ndo_bridge_getlink)(struct sk_buff *skb,
>  						      u32 pid, u32 seq,
>  						      struct net_device *dev,
> diff --git a/net/bridge/br_netlink.c b/net/bridge/br_netlink.c
> index ff2c10d47529..f9be70b26091 100644
> --- a/net/bridge/br_netlink.c
> +++ b/net/bridge/br_netlink.c
> @@ -850,7 +850,8 @@ static int br_setport(struct net_bridge_port *p, struct nlattr *tb[])
>  }
>  
>  /* Change state and parameters on port. */
> -int br_setlink(struct net_device *dev, struct nlmsghdr *nlh, u16 flags)
> +int br_setlink(struct net_device *dev, struct nlmsghdr *nlh, u16 flags,
> +	       struct netlink_ext_ack *extack)
>  {
>  	struct net_bridge *br = (struct net_bridge *)netdev_priv(dev);
>  	struct nlattr *tb[IFLA_BRPORT_MAX + 1];
> diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h
> index 5719b4d3e466..090dfacdc438 100644
> --- a/net/bridge/br_private.h
> +++ b/net/bridge/br_private.h
> @@ -1138,7 +1138,8 @@ int br_netlink_init(void);
>  void br_netlink_fini(void);
>  void br_ifinfo_notify(int event, const struct net_bridge *br,
>  		      const struct net_bridge_port *port);
> -int br_setlink(struct net_device *dev, struct nlmsghdr *nlmsg, u16 flags);
> +int br_setlink(struct net_device *dev, struct nlmsghdr *nlmsg, u16 flags,
> +	       struct netlink_ext_ack *extack);
>  int br_dellink(struct net_device *dev, struct nlmsghdr *nlmsg, u16 flags);
>  int br_getlink(struct sk_buff *skb, u32 pid, u32 seq, struct net_device *dev,
>  	       u32 filter_mask, int nlflags);
> diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
> index c9c0407a7ee0..3b6e551f9e69 100644
> --- a/net/core/rtnetlink.c
> +++ b/net/core/rtnetlink.c
> @@ -4332,7 +4332,8 @@ static int rtnl_bridge_setlink(struct sk_buff *skb, struct nlmsghdr *nlh,
>  			goto out;
>  		}
>  
> -		err = br_dev->netdev_ops->ndo_bridge_setlink(dev, nlh, flags);
> +		err = br_dev->netdev_ops->ndo_bridge_setlink(dev, nlh, flags,
> +							     extack);
>  		if (err)
>  			goto out;
>  
> @@ -4344,7 +4345,8 @@ static int rtnl_bridge_setlink(struct sk_buff *skb, struct nlmsghdr *nlh,
>  			err = -EOPNOTSUPP;
>  		else
>  			err = dev->netdev_ops->ndo_bridge_setlink(dev, nlh,
> -								  flags);
> +								  flags,
> +								  extack);
>  		if (!err) {
>  			flags &= ~BRIDGE_FLAGS_SELF;
>  
> 

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

* Re: [PATCH net-next 2/9] net: bridge: Propagate extack to switchdev
  2018-12-12 11:52 ` [PATCH net-next 2/9] net: bridge: Propagate extack to switchdev Petr Machata
  2018-12-12 12:20     ` [Bridge] " Nikolay Aleksandrov
@ 2018-12-12 13:05   ` Ivan Vecera
  2018-12-12 15:33   ` Roopa Prabhu
  2 siblings, 0 replies; 19+ messages in thread
From: Ivan Vecera @ 2018-12-12 13:05 UTC (permalink / raw)
  To: Petr Machata, netdev; +Cc: Jiri Pirko, Ido Schimmel, davem

On 12. 12. 18 12:52, Petr Machata wrote:
> ndo_bridge_setlink has been updated in the previous patch to have extack
> available, and changelink RTNL op has had this argument since the time
> extack was added. Propagate both through the bridge driver to eventually
> reach br_switchdev_port_vlan_add(), where it will be used by subsequent
> patches.
> 
> Signed-off-by: Petr Machata <petrm@mellanox.com>
> Acked-by: Jiri Pirko <jiri@mellanox.com>
> ---
>   net/bridge/br_if.c        |  2 +-
>   net/bridge/br_netlink.c   | 27 +++++++++++++---------
>   net/bridge/br_private.h   | 22 ++++++++++--------
>   net/bridge/br_switchdev.c |  3 ++-
>   net/bridge/br_vlan.c      | 59 ++++++++++++++++++++++++++---------------------
>   5 files changed, 65 insertions(+), 48 deletions(-)
> 
> diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c
> index d4863f5679ac..3b945d6369c4 100644
> --- a/net/bridge/br_if.c
> +++ b/net/bridge/br_if.c
> @@ -650,7 +650,7 @@ int br_add_if(struct net_bridge *br, struct net_device *dev,
>   	if (br_fdb_insert(br, p, dev->dev_addr, 0))
>   		netdev_err(dev, "failed insert local address bridge forwarding table\n");
>   
> -	err = nbp_vlan_init(p);
> +	err = nbp_vlan_init(p, extack);
>   	if (err) {
>   		netdev_err(dev, "failed to initialize vlan filtering on this port\n");
>   		goto err7;
> diff --git a/net/bridge/br_netlink.c b/net/bridge/br_netlink.c
> index f9be70b26091..935495b93a99 100644
> --- a/net/bridge/br_netlink.c
> +++ b/net/bridge/br_netlink.c
> @@ -525,7 +525,8 @@ int br_getlink(struct sk_buff *skb, u32 pid, u32 seq,
>   }
>   
>   static int br_vlan_info(struct net_bridge *br, struct net_bridge_port *p,
> -			int cmd, struct bridge_vlan_info *vinfo, bool *changed)
> +			int cmd, struct bridge_vlan_info *vinfo, bool *changed,
> +			struct netlink_ext_ack *extack)
>   {
>   	bool curr_change;
>   	int err = 0;
> @@ -537,11 +538,11 @@ static int br_vlan_info(struct net_bridge *br, struct net_bridge_port *p,
>   			 * per-VLAN entry as well
>   			 */
>   			err = nbp_vlan_add(p, vinfo->vid, vinfo->flags,
> -					   &curr_change);
> +					   &curr_change, extack);
>   		} else {
>   			vinfo->flags |= BRIDGE_VLAN_INFO_BRENTRY;
>   			err = br_vlan_add(br, vinfo->vid, vinfo->flags,
> -					  &curr_change);
> +					  &curr_change, extack);
>   		}
>   		if (curr_change)
>   			*changed = true;
> @@ -568,7 +569,8 @@ static int br_process_vlan_info(struct net_bridge *br,
>   				struct net_bridge_port *p, int cmd,
>   				struct bridge_vlan_info *vinfo_curr,
>   				struct bridge_vlan_info **vinfo_last,
> -				bool *changed)
> +				bool *changed,
> +				struct netlink_ext_ack *extack)
>   {
>   	if (!vinfo_curr->vid || vinfo_curr->vid >= VLAN_VID_MASK)
>   		return -EINVAL;
> @@ -598,7 +600,8 @@ static int br_process_vlan_info(struct net_bridge *br,
>   		       sizeof(struct bridge_vlan_info));
>   		for (v = (*vinfo_last)->vid; v <= vinfo_curr->vid; v++) {
>   			tmp_vinfo.vid = v;
> -			err = br_vlan_info(br, p, cmd, &tmp_vinfo, changed);
> +			err = br_vlan_info(br, p, cmd, &tmp_vinfo, changed,
> +					   extack);
>   			if (err)
>   				break;
>   		}
> @@ -607,13 +610,14 @@ static int br_process_vlan_info(struct net_bridge *br,
>   		return err;
>   	}
>   
> -	return br_vlan_info(br, p, cmd, vinfo_curr, changed);
> +	return br_vlan_info(br, p, cmd, vinfo_curr, changed, extack);
>   }
>   
>   static int br_afspec(struct net_bridge *br,
>   		     struct net_bridge_port *p,
>   		     struct nlattr *af_spec,
> -		     int cmd, bool *changed)
> +		     int cmd, bool *changed,
> +		     struct netlink_ext_ack *extack)
>   {
>   	struct bridge_vlan_info *vinfo_curr = NULL;
>   	struct bridge_vlan_info *vinfo_last = NULL;
> @@ -643,7 +647,8 @@ static int br_afspec(struct net_bridge *br,
>   				return -EINVAL;
>   			vinfo_curr = nla_data(attr);
>   			err = br_process_vlan_info(br, p, cmd, vinfo_curr,
> -						   &vinfo_last, changed);
> +						   &vinfo_last, changed,
> +						   extack);
>   			if (err)
>   				return err;
>   			break;
> @@ -898,7 +903,7 @@ int br_setlink(struct net_device *dev, struct nlmsghdr *nlh, u16 flags,
>   	}
>   
>   	if (afspec)
> -		err = br_afspec(br, p, afspec, RTM_SETLINK, &changed);
> +		err = br_afspec(br, p, afspec, RTM_SETLINK, &changed, extack);
>   
>   	if (changed)
>   		br_ifinfo_notify(RTM_NEWLINK, br, p);
> @@ -924,7 +929,7 @@ int br_dellink(struct net_device *dev, struct nlmsghdr *nlh, u16 flags)
>   	if (!p && !(dev->priv_flags & IFF_EBRIDGE))
>   		return -EINVAL;
>   
> -	err = br_afspec(br, p, afspec, RTM_DELLINK, &changed);
> +	err = br_afspec(br, p, afspec, RTM_DELLINK, &changed, NULL);
>   	if (changed)
>   		/* Send RTM_NEWLINK because userspace
>   		 * expects RTM_NEWLINK for vlan dels
> @@ -1106,7 +1111,7 @@ static int br_changelink(struct net_device *brdev, struct nlattr *tb[],
>   	if (data[IFLA_BR_VLAN_DEFAULT_PVID]) {
>   		__u16 defpvid = nla_get_u16(data[IFLA_BR_VLAN_DEFAULT_PVID]);
>   
> -		err = __br_vlan_set_default_pvid(br, defpvid);
> +		err = __br_vlan_set_default_pvid(br, defpvid, extack);
>   		if (err)
>   			return err;
>   	}
> diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h
> index 090dfacdc438..ff3dfb2a78b8 100644
> --- a/net/bridge/br_private.h
> +++ b/net/bridge/br_private.h
> @@ -868,7 +868,7 @@ struct sk_buff *br_handle_vlan(struct net_bridge *br,
>   			       struct net_bridge_vlan_group *vg,
>   			       struct sk_buff *skb);
>   int br_vlan_add(struct net_bridge *br, u16 vid, u16 flags,
> -		bool *changed);
> +		bool *changed, struct netlink_ext_ack *extack);
>   int br_vlan_delete(struct net_bridge *br, u16 vid);
>   void br_vlan_flush(struct net_bridge *br);
>   struct net_bridge_vlan *br_vlan_find(struct net_bridge_vlan_group *vg, u16 vid);
> @@ -881,12 +881,13 @@ int br_vlan_set_stats(struct net_bridge *br, unsigned long val);
>   int br_vlan_set_stats_per_port(struct net_bridge *br, unsigned long val);
>   int br_vlan_init(struct net_bridge *br);
>   int br_vlan_set_default_pvid(struct net_bridge *br, unsigned long val);
> -int __br_vlan_set_default_pvid(struct net_bridge *br, u16 pvid);
> +int __br_vlan_set_default_pvid(struct net_bridge *br, u16 pvid,
> +			       struct netlink_ext_ack *extack);
>   int nbp_vlan_add(struct net_bridge_port *port, u16 vid, u16 flags,
> -		 bool *changed);
> +		 bool *changed, struct netlink_ext_ack *extack);
>   int nbp_vlan_delete(struct net_bridge_port *port, u16 vid);
>   void nbp_vlan_flush(struct net_bridge_port *port);
> -int nbp_vlan_init(struct net_bridge_port *port);
> +int nbp_vlan_init(struct net_bridge_port *port, struct netlink_ext_ack *extack);
>   int nbp_get_num_vlan_infos(struct net_bridge_port *p, u32 filter_mask);
>   void br_vlan_get_stats(const struct net_bridge_vlan *v,
>   		       struct br_vlan_stats *stats);
> @@ -971,7 +972,7 @@ static inline struct sk_buff *br_handle_vlan(struct net_bridge *br,
>   }
>   
>   static inline int br_vlan_add(struct net_bridge *br, u16 vid, u16 flags,
> -			      bool *changed)
> +			      bool *changed, struct netlink_ext_ack *extack)
>   {
>   	*changed = false;
>   	return -EOPNOTSUPP;
> @@ -996,7 +997,7 @@ static inline int br_vlan_init(struct net_bridge *br)
>   }
>   
>   static inline int nbp_vlan_add(struct net_bridge_port *port, u16 vid, u16 flags,
> -			       bool *changed)
> +			       bool *changed, struct netlink_ext_ack *extack)
>   {
>   	*changed = false;
>   	return -EOPNOTSUPP;
> @@ -1017,7 +1018,8 @@ static inline struct net_bridge_vlan *br_vlan_find(struct net_bridge_vlan_group
>   	return NULL;
>   }
>   
> -static inline int nbp_vlan_init(struct net_bridge_port *port)
> +static inline int nbp_vlan_init(struct net_bridge_port *port,
> +				struct netlink_ext_ack *extack)
>   {
>   	return 0;
>   }
> @@ -1174,7 +1176,8 @@ int br_switchdev_set_port_flag(struct net_bridge_port *p,
>   			       unsigned long mask);
>   void br_switchdev_fdb_notify(const struct net_bridge_fdb_entry *fdb,
>   			     int type);
> -int br_switchdev_port_vlan_add(struct net_device *dev, u16 vid, u16 flags);
> +int br_switchdev_port_vlan_add(struct net_device *dev, u16 vid, u16 flags,
> +			       struct netlink_ext_ack *extack);
>   int br_switchdev_port_vlan_del(struct net_device *dev, u16 vid);
>   
>   static inline void br_switchdev_frame_unmark(struct sk_buff *skb)
> @@ -1206,7 +1209,8 @@ static inline int br_switchdev_set_port_flag(struct net_bridge_port *p,
>   }
>   
>   static inline int br_switchdev_port_vlan_add(struct net_device *dev,
> -					     u16 vid, u16 flags)
> +					     u16 vid, u16 flags,
> +					     struct netlink_ext_ack *extack)
>   {
>   	return -EOPNOTSUPP;
>   }
> diff --git a/net/bridge/br_switchdev.c b/net/bridge/br_switchdev.c
> index b993df770675..99ba32177b31 100644
> --- a/net/bridge/br_switchdev.c
> +++ b/net/bridge/br_switchdev.c
> @@ -140,7 +140,8 @@ br_switchdev_fdb_notify(const struct net_bridge_fdb_entry *fdb, int type)
>   	}
>   }
>   
> -int br_switchdev_port_vlan_add(struct net_device *dev, u16 vid, u16 flags)
> +int br_switchdev_port_vlan_add(struct net_device *dev, u16 vid, u16 flags,
> +			       struct netlink_ext_ack *extack)
>   {
>   	struct switchdev_obj_port_vlan v = {
>   		.obj.orig_dev = dev,
> diff --git a/net/bridge/br_vlan.c b/net/bridge/br_vlan.c
> index 48f50d7ac624..4a2f31157ef5 100644
> --- a/net/bridge/br_vlan.c
> +++ b/net/bridge/br_vlan.c
> @@ -80,14 +80,14 @@ static bool __vlan_add_flags(struct net_bridge_vlan *v, u16 flags)
>   }
>   
>   static int __vlan_vid_add(struct net_device *dev, struct net_bridge *br,
> -			  u16 vid, u16 flags)
> +			  u16 vid, u16 flags, struct netlink_ext_ack *extack)
>   {
>   	int err;
>   
>   	/* Try switchdev op first. In case it is not supported, fallback to
>   	 * 8021q add.
>   	 */
> -	err = br_switchdev_port_vlan_add(dev, vid, flags);
> +	err = br_switchdev_port_vlan_add(dev, vid, flags, extack);
>   	if (err == -EOPNOTSUPP)
>   		return vlan_vid_add(dev, br->vlan_proto, vid);
>   	return err;
> @@ -139,7 +139,9 @@ static int __vlan_vid_del(struct net_device *dev, struct net_bridge *br,
>   /* Returns a master vlan, if it didn't exist it gets created. In all cases a
>    * a reference is taken to the master vlan before returning.
>    */
> -static struct net_bridge_vlan *br_vlan_get_master(struct net_bridge *br, u16 vid)
> +static struct net_bridge_vlan *
> +br_vlan_get_master(struct net_bridge *br, u16 vid,
> +		   struct netlink_ext_ack *extack)
>   {
>   	struct net_bridge_vlan_group *vg;
>   	struct net_bridge_vlan *masterv;
> @@ -150,7 +152,7 @@ static struct net_bridge_vlan *br_vlan_get_master(struct net_bridge *br, u16 vid
>   		bool changed;
>   
>   		/* missing global ctx, create it now */
> -		if (br_vlan_add(br, vid, 0, &changed))
> +		if (br_vlan_add(br, vid, 0, &changed, extack))
>   			return NULL;
>   		masterv = br_vlan_find(vg, vid);
>   		if (WARN_ON(!masterv))
> @@ -214,7 +216,8 @@ static void nbp_vlan_rcu_free(struct rcu_head *rcu)
>    * 4. same as 3 but with both master and brentry flags set so the entry
>    *    will be used for filtering in both the port and the bridge
>    */
> -static int __vlan_add(struct net_bridge_vlan *v, u16 flags)
> +static int __vlan_add(struct net_bridge_vlan *v, u16 flags,
> +		      struct netlink_ext_ack *extack)
>   {
>   	struct net_bridge_vlan *masterv = NULL;
>   	struct net_bridge_port *p = NULL;
> @@ -239,7 +242,7 @@ static int __vlan_add(struct net_bridge_vlan *v, u16 flags)
>   		 * This ensures tagged traffic enters the bridge when
>   		 * promiscuous mode is disabled by br_manage_promisc().
>   		 */
> -		err = __vlan_vid_add(dev, br, v->vid, flags);
> +		err = __vlan_vid_add(dev, br, v->vid, flags, extack);
>   		if (err)
>   			goto out;
>   
> @@ -249,12 +252,12 @@ static int __vlan_add(struct net_bridge_vlan *v, u16 flags)
>   
>   			err = br_vlan_add(br, v->vid,
>   					  flags | BRIDGE_VLAN_INFO_BRENTRY,
> -					  &changed);
> +					  &changed, extack);
>   			if (err)
>   				goto out_filt;
>   		}
>   
> -		masterv = br_vlan_get_master(br, v->vid);
> +		masterv = br_vlan_get_master(br, v->vid, extack);
>   		if (!masterv)
>   			goto out_filt;
>   		v->brvlan = masterv;
> @@ -269,7 +272,7 @@ static int __vlan_add(struct net_bridge_vlan *v, u16 flags)
>   			v->stats = masterv->stats;
>   		}
>   	} else {
> -		err = br_switchdev_port_vlan_add(dev, v->vid, flags);
> +		err = br_switchdev_port_vlan_add(dev, v->vid, flags, extack);
>   		if (err && err != -EOPNOTSUPP)
>   			goto out;
>   	}
> @@ -591,11 +594,12 @@ bool br_should_learn(struct net_bridge_port *p, struct sk_buff *skb, u16 *vid)
>   static int br_vlan_add_existing(struct net_bridge *br,
>   				struct net_bridge_vlan_group *vg,
>   				struct net_bridge_vlan *vlan,
> -				u16 flags, bool *changed)
> +				u16 flags, bool *changed,
> +				struct netlink_ext_ack *extack)
>   {
>   	int err;
>   
> -	err = br_switchdev_port_vlan_add(br->dev, vlan->vid, flags);
> +	err = br_switchdev_port_vlan_add(br->dev, vlan->vid, flags, extack);
>   	if (err && err != -EOPNOTSUPP)
>   		return err;
>   
> @@ -634,7 +638,8 @@ static int br_vlan_add_existing(struct net_bridge *br,
>    * Must be called with vid in range from 1 to 4094 inclusive.
>    * changed must be true only if the vlan was created or updated
>    */
> -int br_vlan_add(struct net_bridge *br, u16 vid, u16 flags, bool *changed)
> +int br_vlan_add(struct net_bridge *br, u16 vid, u16 flags, bool *changed,
> +		struct netlink_ext_ack *extack)
>   {
>   	struct net_bridge_vlan_group *vg;
>   	struct net_bridge_vlan *vlan;
> @@ -646,7 +651,8 @@ int br_vlan_add(struct net_bridge *br, u16 vid, u16 flags, bool *changed)
>   	vg = br_vlan_group(br);
>   	vlan = br_vlan_find(vg, vid);
>   	if (vlan)
> -		return br_vlan_add_existing(br, vg, vlan, flags, changed);
> +		return br_vlan_add_existing(br, vg, vlan, flags, changed,
> +					    extack);
>   
>   	vlan = kzalloc(sizeof(*vlan), GFP_KERNEL);
>   	if (!vlan)
> @@ -663,7 +669,7 @@ int br_vlan_add(struct net_bridge *br, u16 vid, u16 flags, bool *changed)
>   	vlan->br = br;
>   	if (flags & BRIDGE_VLAN_INFO_BRENTRY)
>   		refcount_set(&vlan->refcnt, 1);
> -	ret = __vlan_add(vlan, flags);
> +	ret = __vlan_add(vlan, flags, extack);
>   	if (ret) {
>   		free_percpu(vlan->stats);
>   		kfree(vlan);
> @@ -914,7 +920,8 @@ static void br_vlan_disable_default_pvid(struct net_bridge *br)
>   	br->default_pvid = 0;
>   }
>   
> -int __br_vlan_set_default_pvid(struct net_bridge *br, u16 pvid)
> +int __br_vlan_set_default_pvid(struct net_bridge *br, u16 pvid,
> +			       struct netlink_ext_ack *extack)
>   {
>   	const struct net_bridge_vlan *pvent;
>   	struct net_bridge_vlan_group *vg;
> @@ -946,7 +953,7 @@ int __br_vlan_set_default_pvid(struct net_bridge *br, u16 pvid)
>   				  BRIDGE_VLAN_INFO_PVID |
>   				  BRIDGE_VLAN_INFO_UNTAGGED |
>   				  BRIDGE_VLAN_INFO_BRENTRY,
> -				  &vlchange);
> +				  &vlchange, extack);
>   		if (err)
>   			goto out;
>   		br_vlan_delete(br, old_pvid);
> @@ -966,7 +973,7 @@ int __br_vlan_set_default_pvid(struct net_bridge *br, u16 pvid)
>   		err = nbp_vlan_add(p, pvid,
>   				   BRIDGE_VLAN_INFO_PVID |
>   				   BRIDGE_VLAN_INFO_UNTAGGED,
> -				   &vlchange);
> +				   &vlchange, extack);
>   		if (err)
>   			goto err_port;
>   		nbp_vlan_delete(p, old_pvid);
> @@ -988,7 +995,7 @@ int __br_vlan_set_default_pvid(struct net_bridge *br, u16 pvid)
>   			nbp_vlan_add(p, old_pvid,
>   				     BRIDGE_VLAN_INFO_PVID |
>   				     BRIDGE_VLAN_INFO_UNTAGGED,
> -				     &vlchange);
> +				     &vlchange, NULL);
>   		nbp_vlan_delete(p, pvid);
>   	}
>   
> @@ -998,7 +1005,7 @@ int __br_vlan_set_default_pvid(struct net_bridge *br, u16 pvid)
>   				    BRIDGE_VLAN_INFO_PVID |
>   				    BRIDGE_VLAN_INFO_UNTAGGED |
>   				    BRIDGE_VLAN_INFO_BRENTRY,
> -				    &vlchange);
> +				    &vlchange, NULL);
>   		br_vlan_delete(br, pvid);
>   	}
>   	goto out;
> @@ -1021,7 +1028,7 @@ int br_vlan_set_default_pvid(struct net_bridge *br, unsigned long val)
>   		err = -EPERM;
>   		goto out;
>   	}
> -	err = __br_vlan_set_default_pvid(br, pvid);
> +	err = __br_vlan_set_default_pvid(br, pvid, NULL);
>   out:
>   	return err;
>   }
> @@ -1047,7 +1054,7 @@ int br_vlan_init(struct net_bridge *br)
>   	rcu_assign_pointer(br->vlgrp, vg);
>   	ret = br_vlan_add(br, 1,
>   			  BRIDGE_VLAN_INFO_PVID | BRIDGE_VLAN_INFO_UNTAGGED |
> -			  BRIDGE_VLAN_INFO_BRENTRY, &changed);
> +			  BRIDGE_VLAN_INFO_BRENTRY, &changed, NULL);
>   	if (ret)
>   		goto err_vlan_add;
>   
> @@ -1064,7 +1071,7 @@ int br_vlan_init(struct net_bridge *br)
>   	goto out;
>   }
>   
> -int nbp_vlan_init(struct net_bridge_port *p)
> +int nbp_vlan_init(struct net_bridge_port *p, struct netlink_ext_ack *extack)
>   {
>   	struct switchdev_attr attr = {
>   		.orig_dev = p->br->dev,
> @@ -1097,7 +1104,7 @@ int nbp_vlan_init(struct net_bridge_port *p)
>   		ret = nbp_vlan_add(p, p->br->default_pvid,
>   				   BRIDGE_VLAN_INFO_PVID |
>   				   BRIDGE_VLAN_INFO_UNTAGGED,
> -				   &changed);
> +				   &changed, extack);
>   		if (ret)
>   			goto err_vlan_add;
>   	}
> @@ -1122,7 +1129,7 @@ int nbp_vlan_init(struct net_bridge_port *p)
>    * changed must be true only if the vlan was created or updated
>    */
>   int nbp_vlan_add(struct net_bridge_port *port, u16 vid, u16 flags,
> -		 bool *changed)
> +		 bool *changed, struct netlink_ext_ack *extack)
>   {
>   	struct net_bridge_vlan *vlan;
>   	int ret;
> @@ -1133,7 +1140,7 @@ int nbp_vlan_add(struct net_bridge_port *port, u16 vid, u16 flags,
>   	vlan = br_vlan_find(nbp_vlan_group(port), vid);
>   	if (vlan) {
>   		/* Pass the flags to the hardware bridge */
> -		ret = br_switchdev_port_vlan_add(port->dev, vid, flags);
> +		ret = br_switchdev_port_vlan_add(port->dev, vid, flags, extack);
>   		if (ret && ret != -EOPNOTSUPP)
>   			return ret;
>   		*changed = __vlan_add_flags(vlan, flags);
> @@ -1147,7 +1154,7 @@ int nbp_vlan_add(struct net_bridge_port *port, u16 vid, u16 flags,
>   
>   	vlan->vid = vid;
>   	vlan->port = port;
> -	ret = __vlan_add(vlan, flags);
> +	ret = __vlan_add(vlan, flags, extack);
>   	if (ret)
>   		kfree(vlan);
>   	else
> 

Acked-by: Ivan Vecera <ivecera@redhat.com>

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

* Re: [PATCH net-next 3/9] net: switchdev: Add extack argument to switchdev_port_obj_add()
  2018-12-12 11:52 ` [PATCH net-next 3/9] net: switchdev: Add extack argument to switchdev_port_obj_add() Petr Machata
@ 2018-12-12 13:11   ` Ivan Vecera
  0 siblings, 0 replies; 19+ messages in thread
From: Ivan Vecera @ 2018-12-12 13:11 UTC (permalink / raw)
  To: Petr Machata, netdev; +Cc: Jiri Pirko, Ido Schimmel, davem

On 12. 12. 18 12:52, Petr Machata wrote:
> After the previous patch, bridge driver has extack argument available to
> pass to switchdev. Therefore extend switchdev_port_obj_add() with this
> argument, updating all callers, and passing the argument through to
> switchdev_port_obj_notify().
> 
> Signed-off-by: Petr Machata <petrm@mellanox.com>
> Acked-by: Jiri Pirko <jiri@mellanox.com>
> ---
>   include/net/switchdev.h   |  6 ++++--
>   net/bridge/br_mdb.c       |  4 ++--
>   net/bridge/br_switchdev.c |  2 +-
>   net/switchdev/switchdev.c | 19 +++++++++++--------
>   4 files changed, 18 insertions(+), 13 deletions(-)
> 
> diff --git a/include/net/switchdev.h b/include/net/switchdev.h
> index 866b6d148b77..69016305ad58 100644
> --- a/include/net/switchdev.h
> +++ b/include/net/switchdev.h
> @@ -180,7 +180,8 @@ int switchdev_port_attr_get(struct net_device *dev,
>   int switchdev_port_attr_set(struct net_device *dev,
>   			    const struct switchdev_attr *attr);
>   int switchdev_port_obj_add(struct net_device *dev,
> -			   const struct switchdev_obj *obj);
> +			   const struct switchdev_obj *obj,
> +			   struct netlink_ext_ack *extack);
>   int switchdev_port_obj_del(struct net_device *dev,
>   			   const struct switchdev_obj *obj);
>   
> @@ -233,7 +234,8 @@ static inline int switchdev_port_attr_set(struct net_device *dev,
>   }
>   
>   static inline int switchdev_port_obj_add(struct net_device *dev,
> -					 const struct switchdev_obj *obj)
> +					 const struct switchdev_obj *obj,
> +					 struct netlink_ext_ack *extack)
>   {
>   	return -EOPNOTSUPP;
>   }
> diff --git a/net/bridge/br_mdb.c b/net/bridge/br_mdb.c
> index 79d4c9d253e0..f69c8d91dc81 100644
> --- a/net/bridge/br_mdb.c
> +++ b/net/bridge/br_mdb.c
> @@ -331,7 +331,7 @@ static void br_mdb_switchdev_host_port(struct net_device *dev,
>   	mdb.obj.orig_dev = dev;
>   	switch (type) {
>   	case RTM_NEWMDB:
> -		switchdev_port_obj_add(lower_dev, &mdb.obj);
> +		switchdev_port_obj_add(lower_dev, &mdb.obj, NULL);
>   		break;
>   	case RTM_DELMDB:
>   		switchdev_port_obj_del(lower_dev, &mdb.obj);
> @@ -381,7 +381,7 @@ static void __br_mdb_notify(struct net_device *dev, struct net_bridge_port *p,
>   			__mdb_entry_to_br_ip(entry, &complete_info->ip);
>   			mdb.obj.complete_priv = complete_info;
>   			mdb.obj.complete = br_mdb_complete;
> -			if (switchdev_port_obj_add(port_dev, &mdb.obj))
> +			if (switchdev_port_obj_add(port_dev, &mdb.obj, NULL))
>   				kfree(complete_info);
>   		}
>   	} else if (p && port_dev && type == RTM_DELMDB) {
> diff --git a/net/bridge/br_switchdev.c b/net/bridge/br_switchdev.c
> index 99ba32177b31..035ff59d9cbd 100644
> --- a/net/bridge/br_switchdev.c
> +++ b/net/bridge/br_switchdev.c
> @@ -151,7 +151,7 @@ int br_switchdev_port_vlan_add(struct net_device *dev, u16 vid, u16 flags,
>   		.vid_end = vid,
>   	};
>   
> -	return switchdev_port_obj_add(dev, &v.obj);
> +	return switchdev_port_obj_add(dev, &v.obj, extack);
>   }
>   
>   int br_switchdev_port_vlan_del(struct net_device *dev, u16 vid)
> diff --git a/net/switchdev/switchdev.c b/net/switchdev/switchdev.c
> index fe23fac4dc4b..cb20669bf6ce 100644
> --- a/net/switchdev/switchdev.c
> +++ b/net/switchdev/switchdev.c
> @@ -356,7 +356,8 @@ static size_t switchdev_obj_size(const struct switchdev_obj *obj)
>   static int switchdev_port_obj_notify(enum switchdev_notifier_type nt,
>   				     struct net_device *dev,
>   				     const struct switchdev_obj *obj,
> -				     struct switchdev_trans *trans)
> +				     struct switchdev_trans *trans,
> +				     struct netlink_ext_ack *extack)
>   {
>   	int rc;
>   	int err;
> @@ -379,7 +380,8 @@ static int switchdev_port_obj_notify(enum switchdev_notifier_type nt,
>   }
>   
>   static int switchdev_port_obj_add_now(struct net_device *dev,
> -				      const struct switchdev_obj *obj)
> +				      const struct switchdev_obj *obj,
> +				      struct netlink_ext_ack *extack)
>   {
>   	struct switchdev_trans trans;
>   	int err;
> @@ -397,7 +399,7 @@ static int switchdev_port_obj_add_now(struct net_device *dev,
>   
>   	trans.ph_prepare = true;
>   	err = switchdev_port_obj_notify(SWITCHDEV_PORT_OBJ_ADD,
> -					dev, obj, &trans);
> +					dev, obj, &trans, extack);
>   	if (err) {
>   		/* Prepare phase failed: abort the transaction.  Any
>   		 * resources reserved in the prepare phase are
> @@ -417,7 +419,7 @@ static int switchdev_port_obj_add_now(struct net_device *dev,
>   
>   	trans.ph_prepare = false;
>   	err = switchdev_port_obj_notify(SWITCHDEV_PORT_OBJ_ADD,
> -					dev, obj, &trans);
> +					dev, obj, &trans, extack);
>   	WARN(err, "%s: Commit of object (id=%d) failed.\n", dev->name, obj->id);
>   	switchdev_trans_items_warn_destroy(dev, &trans);
>   
> @@ -430,7 +432,7 @@ static void switchdev_port_obj_add_deferred(struct net_device *dev,
>   	const struct switchdev_obj *obj = data;
>   	int err;
>   
> -	err = switchdev_port_obj_add_now(dev, obj);
> +	err = switchdev_port_obj_add_now(dev, obj, NULL);
>   	if (err && err != -EOPNOTSUPP)
>   		netdev_err(dev, "failed (err=%d) to add object (id=%d)\n",
>   			   err, obj->id);
> @@ -460,12 +462,13 @@ static int switchdev_port_obj_add_defer(struct net_device *dev,
>    *	in case SWITCHDEV_F_DEFER flag is not set.
>    */
>   int switchdev_port_obj_add(struct net_device *dev,
> -			   const struct switchdev_obj *obj)
> +			   const struct switchdev_obj *obj,
> +			   struct netlink_ext_ack *extack)
>   {
>   	if (obj->flags & SWITCHDEV_F_DEFER)
>   		return switchdev_port_obj_add_defer(dev, obj);
>   	ASSERT_RTNL();
> -	return switchdev_port_obj_add_now(dev, obj);
> +	return switchdev_port_obj_add_now(dev, obj, extack);
>   }
>   EXPORT_SYMBOL_GPL(switchdev_port_obj_add);
>   
> @@ -473,7 +476,7 @@ static int switchdev_port_obj_del_now(struct net_device *dev,
>   				      const struct switchdev_obj *obj)
>   {
>   	return switchdev_port_obj_notify(SWITCHDEV_PORT_OBJ_DEL,
> -					 dev, obj, NULL);
> +					 dev, obj, NULL, NULL);
>   }
>   
>   static void switchdev_port_obj_del_deferred(struct net_device *dev,
> 

Acked-by: Ivan Vecera <ivecera@redhat.com>

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

* Re: [PATCH net-next 4/9] net: switchdev: Add extack to struct switchdev_notifier_info
  2018-12-12 11:52 ` [PATCH net-next 4/9] net: switchdev: Add extack to struct switchdev_notifier_info Petr Machata
@ 2018-12-12 13:12   ` Ivan Vecera
  0 siblings, 0 replies; 19+ messages in thread
From: Ivan Vecera @ 2018-12-12 13:12 UTC (permalink / raw)
  To: Petr Machata, netdev; +Cc: Jiri Pirko, Ido Schimmel, davem

On 12. 12. 18 12:52, Petr Machata wrote:
> In order to pass extack to the drivers that need it, add an extack field
> to struct switchdev_notifier_info, and an extack argument to the
> function call_switchdev_blocking_notifiers(). Also add a helper function
> switchdev_notifier_info_to_extack().
> 
> Signed-off-by: Petr Machata <petrm@mellanox.com>
> Acked-by: Jiri Pirko <jiri@mellanox.com>
> ---
>   drivers/net/vxlan.c       |  1 +
>   include/net/switchdev.h   | 13 +++++++++++--
>   net/switchdev/switchdev.c |  7 +++++--
>   3 files changed, 17 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c
> index b56ef684ecac..49d4b5854c62 100644
> --- a/drivers/net/vxlan.c
> +++ b/drivers/net/vxlan.c
> @@ -364,6 +364,7 @@ static void vxlan_fdb_switchdev_notifier_info(const struct vxlan_dev *vxlan,
>   			    struct switchdev_notifier_vxlan_fdb_info *fdb_info)
>   {
>   	fdb_info->info.dev = vxlan->dev;
> +	fdb_info->info.extack = NULL;
>   	fdb_info->remote_ip = rd->remote_ip;
>   	fdb_info->remote_port = rd->remote_port;
>   	fdb_info->remote_vni = rd->remote_vni;
> diff --git a/include/net/switchdev.h b/include/net/switchdev.h
> index 69016305ad58..4facfa6775e8 100644
> --- a/include/net/switchdev.h
> +++ b/include/net/switchdev.h
> @@ -149,6 +149,7 @@ enum switchdev_notifier_type {
>   
>   struct switchdev_notifier_info {
>   	struct net_device *dev;
> +	struct netlink_ext_ack *extack;
>   };
>   
>   struct switchdev_notifier_fdb_info {
> @@ -172,6 +173,12 @@ switchdev_notifier_info_to_dev(const struct switchdev_notifier_info *info)
>   	return info->dev;
>   }
>   
> +static inline struct netlink_ext_ack *
> +switchdev_notifier_info_to_extack(const struct switchdev_notifier_info *info)
> +{
> +	return info->extack;
> +}
> +
>   #ifdef CONFIG_NET_SWITCHDEV
>   
>   void switchdev_deferred_process(void);
> @@ -193,7 +200,8 @@ int call_switchdev_notifiers(unsigned long val, struct net_device *dev,
>   int register_switchdev_blocking_notifier(struct notifier_block *nb);
>   int unregister_switchdev_blocking_notifier(struct notifier_block *nb);
>   int call_switchdev_blocking_notifiers(unsigned long val, struct net_device *dev,
> -				      struct switchdev_notifier_info *info);
> +				      struct switchdev_notifier_info *info,
> +				      struct netlink_ext_ack *extack);
>   
>   void switchdev_port_fwd_mark_set(struct net_device *dev,
>   				 struct net_device *group_dev,
> @@ -278,7 +286,8 @@ unregister_switchdev_blocking_notifier(struct notifier_block *nb)
>   static inline int
>   call_switchdev_blocking_notifiers(unsigned long val,
>   				  struct net_device *dev,
> -				  struct switchdev_notifier_info *info)
> +				  struct switchdev_notifier_info *info,
> +				  struct netlink_ext_ack *extack)
>   {
>   	return NOTIFY_DONE;
>   }
> diff --git a/net/switchdev/switchdev.c b/net/switchdev/switchdev.c
> index cb20669bf6ce..aa84acfb6632 100644
> --- a/net/switchdev/switchdev.c
> +++ b/net/switchdev/switchdev.c
> @@ -368,7 +368,7 @@ static int switchdev_port_obj_notify(enum switchdev_notifier_type nt,
>   		.handled = false,
>   	};
>   
> -	rc = call_switchdev_blocking_notifiers(nt, dev, &obj_info.info);
> +	rc = call_switchdev_blocking_notifiers(nt, dev, &obj_info.info, extack);
>   	err = notifier_to_errno(rc);
>   	if (err) {
>   		WARN_ON(!obj_info.handled);
> @@ -559,6 +559,7 @@ int call_switchdev_notifiers(unsigned long val, struct net_device *dev,
>   			     struct switchdev_notifier_info *info)
>   {
>   	info->dev = dev;
> +	info->extack = NULL;
>   	return atomic_notifier_call_chain(&switchdev_notif_chain, val, info);
>   }
>   EXPORT_SYMBOL_GPL(call_switchdev_notifiers);
> @@ -580,9 +581,11 @@ int unregister_switchdev_blocking_notifier(struct notifier_block *nb)
>   EXPORT_SYMBOL_GPL(unregister_switchdev_blocking_notifier);
>   
>   int call_switchdev_blocking_notifiers(unsigned long val, struct net_device *dev,
> -				      struct switchdev_notifier_info *info)
> +				      struct switchdev_notifier_info *info,
> +				      struct netlink_ext_ack *extack)
>   {
>   	info->dev = dev;
> +	info->extack = extack;
>   	return blocking_notifier_call_chain(&switchdev_blocking_notif_chain,
>   					    val, info);
>   }
> 


Acked-by: Ivan Vecera <ivecera@redhat.com>

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

* Re: [PATCH net-next 5/9] net: switchdev: Add extack to switchdev_handle_port_obj_add() callback
  2018-12-12 11:52 ` [PATCH net-next 5/9] net: switchdev: Add extack to switchdev_handle_port_obj_add() callback Petr Machata
@ 2018-12-12 13:12   ` Ivan Vecera
  0 siblings, 0 replies; 19+ messages in thread
From: Ivan Vecera @ 2018-12-12 13:12 UTC (permalink / raw)
  To: Petr Machata, netdev; +Cc: Jiri Pirko, Ido Schimmel, davem

On 12. 12. 18 12:52, Petr Machata wrote:
> Drivers use switchdev_handle_port_obj_add() to handle recursive descent
> through lower devices. Change this function prototype to take add_cb
> that itself takes an extack argument. Decode extack from
> switchdev_notifier_port_obj_info and pass it to add_cb.
> 
> Update mlxsw and ocelot drivers which use this helper.
> 
> Signed-off-by: Petr Machata <petrm@mellanox.com>
> Acked-by: Jiri Pirko <jiri@mellanox.com>
> ---
>   drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c |  3 ++-
>   drivers/net/ethernet/mscc/ocelot.c                       |  3 ++-
>   include/net/switchdev.h                                  |  6 ++++--
>   net/switchdev/switchdev.c                                | 12 +++++++++---
>   4 files changed, 17 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
> index 5ad1fcebf788..4b9292289256 100644
> --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
> +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
> @@ -1777,7 +1777,8 @@ static void mlxsw_sp_span_respin_schedule(struct mlxsw_sp *mlxsw_sp)
>   
>   static int mlxsw_sp_port_obj_add(struct net_device *dev,
>   				 const struct switchdev_obj *obj,
> -				 struct switchdev_trans *trans)
> +				 struct switchdev_trans *trans,
> +				 struct netlink_ext_ack *extack)
>   {
>   	struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev);
>   	const struct switchdev_obj_port_vlan *vlan;
> diff --git a/drivers/net/ethernet/mscc/ocelot.c b/drivers/net/ethernet/mscc/ocelot.c
> index 7f8da8873a96..ea3eec263875 100644
> --- a/drivers/net/ethernet/mscc/ocelot.c
> +++ b/drivers/net/ethernet/mscc/ocelot.c
> @@ -1293,7 +1293,8 @@ static int ocelot_port_obj_del_mdb(struct net_device *dev,
>   
>   static int ocelot_port_obj_add(struct net_device *dev,
>   			       const struct switchdev_obj *obj,
> -			       struct switchdev_trans *trans)
> +			       struct switchdev_trans *trans,
> +			       struct netlink_ext_ack *extack)
>   {
>   	int ret = 0;
>   
> diff --git a/include/net/switchdev.h b/include/net/switchdev.h
> index 4facfa6775e8..a7fdab5ee6c3 100644
> --- a/include/net/switchdev.h
> +++ b/include/net/switchdev.h
> @@ -215,7 +215,8 @@ int switchdev_handle_port_obj_add(struct net_device *dev,
>   			bool (*check_cb)(const struct net_device *dev),
>   			int (*add_cb)(struct net_device *dev,
>   				      const struct switchdev_obj *obj,
> -				      struct switchdev_trans *trans));
> +				      struct switchdev_trans *trans,
> +				      struct netlink_ext_ack *extack));
>   int switchdev_handle_port_obj_del(struct net_device *dev,
>   			struct switchdev_notifier_port_obj_info *port_obj_info,
>   			bool (*check_cb)(const struct net_device *dev),
> @@ -304,7 +305,8 @@ switchdev_handle_port_obj_add(struct net_device *dev,
>   			bool (*check_cb)(const struct net_device *dev),
>   			int (*add_cb)(struct net_device *dev,
>   				      const struct switchdev_obj *obj,
> -				      struct switchdev_trans *trans))
> +				      struct switchdev_trans *trans,
> +				      struct netlink_ext_ack *extack))
>   {
>   	return 0;
>   }
> diff --git a/net/switchdev/switchdev.c b/net/switchdev/switchdev.c
> index aa84acfb6632..5df9d1138ac9 100644
> --- a/net/switchdev/switchdev.c
> +++ b/net/switchdev/switchdev.c
> @@ -616,16 +616,21 @@ static int __switchdev_handle_port_obj_add(struct net_device *dev,
>   			bool (*check_cb)(const struct net_device *dev),
>   			int (*add_cb)(struct net_device *dev,
>   				      const struct switchdev_obj *obj,
> -				      struct switchdev_trans *trans))
> +				      struct switchdev_trans *trans,
> +				      struct netlink_ext_ack *extack))
>   {
> +	struct netlink_ext_ack *extack;
>   	struct net_device *lower_dev;
>   	struct list_head *iter;
>   	int err = -EOPNOTSUPP;
>   
> +	extack = switchdev_notifier_info_to_extack(&port_obj_info->info);
> +
>   	if (check_cb(dev)) {
>   		/* This flag is only checked if the return value is success. */
>   		port_obj_info->handled = true;
> -		return add_cb(dev, port_obj_info->obj, port_obj_info->trans);
> +		return add_cb(dev, port_obj_info->obj, port_obj_info->trans,
> +			      extack);
>   	}
>   
>   	/* Switch ports might be stacked under e.g. a LAG. Ignore the
> @@ -650,7 +655,8 @@ int switchdev_handle_port_obj_add(struct net_device *dev,
>   			bool (*check_cb)(const struct net_device *dev),
>   			int (*add_cb)(struct net_device *dev,
>   				      const struct switchdev_obj *obj,
> -				      struct switchdev_trans *trans))
> +				      struct switchdev_trans *trans,
> +				      struct netlink_ext_ack *extack))
>   {
>   	int err;
>   
> 

Acked-by: Ivan Vecera <ivecera@redhat.com>

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

* Re: [PATCH net-next 1/9] net: ndo_bridge_setlink: Add extack
  2018-12-12 12:26   ` Nikolay Aleksandrov
@ 2018-12-12 13:58     ` Petr Machata
  0 siblings, 0 replies; 19+ messages in thread
From: Petr Machata @ 2018-12-12 13:58 UTC (permalink / raw)
  To: Nikolay Aleksandrov; +Cc: netdev, Jiri Pirko, Ido Schimmel, davem, ivecera

Nikolay Aleksandrov <nikolay@cumulusnetworks.com> writes:

> On 12/12/2018 13:52, Petr Machata wrote:
>>  	int			(*ndo_bridge_setlink)(struct net_device *dev,
>>  						      struct nlmsghdr *nlh,
>> -						      u16 flags);
>> +						      u16 flags,
>> +						      struct netlink_ext_ack *
>> +						      extack);
>
> IMO it's better to have struct netlink_ext_ack and extack on the same
> line even if it goes a little over 80 here, it is normal for netdevice
> ops and wouldn't be the first (check below or above). At first I thought
> the arg name is missing. :)

Yeah, I didn't really like this either. It would be 86, which is the
reason I broke it like this, but it's not the longest declaration in
that file. I'll fold it like you propose.

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

* Re: [PATCH net-next 2/9] net: bridge: Propagate extack to switchdev
  2018-12-12 11:52 ` [PATCH net-next 2/9] net: bridge: Propagate extack to switchdev Petr Machata
  2018-12-12 12:20     ` [Bridge] " Nikolay Aleksandrov
  2018-12-12 13:05   ` Ivan Vecera
@ 2018-12-12 15:33   ` Roopa Prabhu
  2 siblings, 0 replies; 19+ messages in thread
From: Roopa Prabhu @ 2018-12-12 15:33 UTC (permalink / raw)
  To: Petr Machata; +Cc: netdev, Jiri Pirko, Ido Schimmel, David Miller, ivecera

On Wed, Dec 12, 2018 at 3:52 AM Petr Machata <petrm@mellanox.com> wrote:
>
> ndo_bridge_setlink has been updated in the previous patch to have extack
> available, and changelink RTNL op has had this argument since the time
> extack was added. Propagate both through the bridge driver to eventually
> reach br_switchdev_port_vlan_add(), where it will be used by subsequent
> patches.
>
> Signed-off-by: Petr Machata <petrm@mellanox.com>
> Acked-by: Jiri Pirko <jiri@mellanox.com>
> ---

Acked-by: Roopa Prabhu <roopa@cumulusnetworks.com>

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

end of thread, other threads:[~2018-12-12 15:33 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-12-12 11:52 [PATCH net-next 0/9] Pass extack to SWITCHDEV_PORT_OBJ_ADD Petr Machata
2018-12-12 11:52 ` [PATCH net-next 1/9] net: ndo_bridge_setlink: Add extack Petr Machata
2018-12-12 12:26   ` Nikolay Aleksandrov
2018-12-12 13:58     ` Petr Machata
2018-12-12 11:52 ` [PATCH net-next 2/9] net: bridge: Propagate extack to switchdev Petr Machata
2018-12-12 12:20   ` Nikolay Aleksandrov
2018-12-12 12:20     ` [Bridge] " Nikolay Aleksandrov
2018-12-12 13:05   ` Ivan Vecera
2018-12-12 15:33   ` Roopa Prabhu
2018-12-12 11:52 ` [PATCH net-next 3/9] net: switchdev: Add extack argument to switchdev_port_obj_add() Petr Machata
2018-12-12 13:11   ` Ivan Vecera
2018-12-12 11:52 ` [PATCH net-next 4/9] net: switchdev: Add extack to struct switchdev_notifier_info Petr Machata
2018-12-12 13:12   ` Ivan Vecera
2018-12-12 11:52 ` [PATCH net-next 5/9] net: switchdev: Add extack to switchdev_handle_port_obj_add() callback Petr Machata
2018-12-12 13:12   ` Ivan Vecera
2018-12-12 11:52 ` [PATCH net-next 6/9] mlxsw: spectrum_switchdev: Propagate extack on VXLAN VLAN events Petr Machata
2018-12-12 11:52 ` [PATCH net-next 7/9] mlxsw: spectrum_switchdev: Propagate extack on port " Petr Machata
2018-12-12 11:52 ` [PATCH net-next 8/9] selftests: mlxsw: extack: Test VLAN add on a VXLAN device Petr Machata
2018-12-12 11:52 ` [PATCH net-next 9/9] selftests: mlxsw: extack: Test VLAN add on a port device Petr Machata

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.