All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH net-next 1/3] switchdev: fix: erasing too much of vlan obj when handling multiple vlan specs
@ 2015-10-20 19:36 sfeldma
  2015-10-20 19:36 ` [PATCH net-next 2/3] switchdev: fix: pass correct obj size when deferring obj add sfeldma
                   ` (2 more replies)
  0 siblings, 3 replies; 6+ messages in thread
From: sfeldma @ 2015-10-20 19:36 UTC (permalink / raw)
  To: netdev; +Cc: jiri, siva.mannem.lnx, vivien.didelot

From: Scott Feldman <sfeldma@gmail.com>

When adding vlans with multiple IFLA_BRIDGE_VLAN_INFO attrs set in AFSPEC,
we would wipe the vlan obj struct after the first IFLA_BRIDGE_VLAN_INFO.
Fix this by only clearing what's necessary on each IFLA_BRIDGE_VLAN_INFO
iteration.

Fixes: 9e8f4a54 ("switchdev: push object ID back to object structure")
Signed-off-by: Scott Feldman <sfeldma@gmail.com>
---
 net/switchdev/switchdev.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/net/switchdev/switchdev.c b/net/switchdev/switchdev.c
index 73e3895..56d8479 100644
--- a/net/switchdev/switchdev.c
+++ b/net/switchdev/switchdev.c
@@ -863,7 +863,7 @@ static int switchdev_port_br_afspec(struct net_device *dev,
 			err = f(dev, &vlan.obj);
 			if (err)
 				return err;
-			memset(&vlan, 0, sizeof(vlan));
+			vlan.vid_begin = 0;
 		} else {
 			if (vlan.vid_begin)
 				return -EINVAL;
@@ -872,7 +872,7 @@ static int switchdev_port_br_afspec(struct net_device *dev,
 			err = f(dev, &vlan.obj);
 			if (err)
 				return err;
-			memset(&vlan, 0, sizeof(vlan));
+			vlan.vid_begin = 0;
 		}
 	}
 
-- 
1.7.10.4

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

* [PATCH net-next 2/3] switchdev: fix: pass correct obj size when deferring obj add
  2015-10-20 19:36 [PATCH net-next 1/3] switchdev: fix: erasing too much of vlan obj when handling multiple vlan specs sfeldma
@ 2015-10-20 19:36 ` sfeldma
  2015-10-21  7:40   ` Jiri Pirko
  2015-10-20 19:36 ` [PATCH net-next 3/3] switchdev: split switchdev_attr into individual structs sfeldma
  2015-10-21  7:46 ` [PATCH net-next 1/3] switchdev: fix: erasing too much of vlan obj when handling multiple vlan specs Jiri Pirko
  2 siblings, 1 reply; 6+ messages in thread
From: sfeldma @ 2015-10-20 19:36 UTC (permalink / raw)
  To: netdev; +Cc: jiri, siva.mannem.lnx, vivien.didelot

From: Scott Feldman <sfeldma@gmail.com>

Fixes: 0bc05d585d ("switchdev: allow caller to explicitly request attr_set as deferred")
Signed-off-by: Scott Feldman <sfeldma@gmail.com>
---
 net/switchdev/switchdev.c |   19 ++++++++++++++++++-
 1 file changed, 18 insertions(+), 1 deletion(-)

diff --git a/net/switchdev/switchdev.c b/net/switchdev/switchdev.c
index 56d8479..be8ced1 100644
--- a/net/switchdev/switchdev.c
+++ b/net/switchdev/switchdev.c
@@ -489,7 +489,24 @@ static void switchdev_port_obj_del_deferred(struct net_device *dev,
 static int switchdev_port_obj_del_defer(struct net_device *dev,
 					const struct switchdev_obj *obj)
 {
-	return switchdev_deferred_enqueue(dev, obj, sizeof(*obj),
+	size_t size = 0;
+
+	switch (obj->id) {
+	case SWITCHDEV_OBJ_ID_PORT_VLAN:
+		size = sizeof(struct switchdev_obj_port_vlan);
+		break;
+	case SWITCHDEV_OBJ_ID_IPV4_FIB:
+		size = sizeof(struct switchdev_obj_ipv4_fib);
+		break;
+	case SWITCHDEV_OBJ_ID_PORT_FDB:
+		size = sizeof(struct switchdev_obj_port_fdb);
+		break;
+	default:
+		WARN_ON(!size);
+		return -EINVAL;
+	}
+
+	return switchdev_deferred_enqueue(dev, obj, size,
 					  switchdev_port_obj_del_deferred);
 }
 
-- 
1.7.10.4

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

* [PATCH net-next 3/3] switchdev: split switchdev_attr into individual structs
  2015-10-20 19:36 [PATCH net-next 1/3] switchdev: fix: erasing too much of vlan obj when handling multiple vlan specs sfeldma
  2015-10-20 19:36 ` [PATCH net-next 2/3] switchdev: fix: pass correct obj size when deferring obj add sfeldma
@ 2015-10-20 19:36 ` sfeldma
  2015-10-21  7:49   ` Jiri Pirko
  2015-10-21  7:46 ` [PATCH net-next 1/3] switchdev: fix: erasing too much of vlan obj when handling multiple vlan specs Jiri Pirko
  2 siblings, 1 reply; 6+ messages in thread
From: sfeldma @ 2015-10-20 19:36 UTC (permalink / raw)
  To: netdev; +Cc: jiri, siva.mannem.lnx, vivien.didelot

From: Scott Feldman <sfeldma@gmail.com>

This was already done for switchdev_objs.   Changing switchdev_attrs to new
style makes switchdev API consistent for both attrs and objs.

No functional changes here.

Signed-off-by: Scott Feldman <sfeldma@gmail.com>
---
 .../ethernet/mellanox/mlxsw/spectrum_switchdev.c   |   24 ++++--
 drivers/net/ethernet/mellanox/mlxsw/switchx2.c     |    7 +-
 drivers/net/ethernet/rocker/rocker.c               |   23 ++++--
 include/net/switchdev.h                            |   51 +++++++++++--
 net/bridge/br_stp.c                                |   24 +++---
 net/core/net-sysfs.c                               |   14 ++--
 net/core/rtnetlink.c                               |   14 ++--
 net/dsa/slave.c                                    |   10 ++-
 net/switchdev/switchdev.c                          |   77 +++++++++++++-------
 9 files changed, 172 insertions(+), 72 deletions(-)

diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
index c39b7a1..efa1aa8 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
@@ -56,15 +56,19 @@ static int mlxsw_sp_port_attr_get(struct net_device *dev,
 {
 	struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev);
 	struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
+	struct switchdev_attr_port_parent_id *parent_id;
+	struct switchdev_attr_port_bridge_flags *brport_flags;
 
 	switch (attr->id) {
 	case SWITCHDEV_ATTR_ID_PORT_PARENT_ID:
-		attr->u.ppid.id_len = sizeof(mlxsw_sp->base_mac);
-		memcpy(&attr->u.ppid.id, &mlxsw_sp->base_mac,
-		       attr->u.ppid.id_len);
+		parent_id = SWITCHDEV_ATTR_PORT_PARENT_ID(attr);
+		parent_id->ppid.id_len = sizeof(mlxsw_sp->base_mac);
+		memcpy(&parent_id->ppid.id, &mlxsw_sp->base_mac,
+		       parent_id->ppid.id_len);
 		break;
 	case SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS:
-		attr->u.brport_flags =
+		brport_flags = SWITCHDEV_ATTR_PORT_BRIDGE_FLAGS(attr);
+		brport_flags->brport_flags =
 			(mlxsw_sp_port->learning ? BR_LEARNING : 0) |
 			(mlxsw_sp_port->learning_sync ? BR_LEARNING_SYNC : 0);
 		break;
@@ -166,20 +170,26 @@ static int mlxsw_sp_port_attr_set(struct net_device *dev,
 				  struct switchdev_trans *trans)
 {
 	struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev);
+	struct switchdev_attr_port_stp_state *stp_state;
+	struct switchdev_attr_port_bridge_flags *brport_flags;
+	struct switchdev_attr_bridge_ageing_time *ageing_time;
 	int err = 0;
 
 	switch (attr->id) {
 	case SWITCHDEV_ATTR_ID_PORT_STP_STATE:
+		stp_state = SWITCHDEV_ATTR_PORT_STP_STATE(attr);
 		err = mlxsw_sp_port_attr_stp_state_set(mlxsw_sp_port, trans,
-						       attr->u.stp_state);
+						       stp_state->state);
 		break;
 	case SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS:
+		brport_flags = SWITCHDEV_ATTR_PORT_BRIDGE_FLAGS(attr);
 		err = mlxsw_sp_port_attr_br_flags_set(mlxsw_sp_port, trans,
-						      attr->u.brport_flags);
+						      brport_flags->brport_flags);
 		break;
 	case SWITCHDEV_ATTR_ID_BRIDGE_AGEING_TIME:
+		ageing_time = SWITCHDEV_ATTR_BRIDGE_AGEING_TIME(attr);
 		err = mlxsw_sp_port_attr_br_ageing_set(mlxsw_sp_port, trans,
-						       attr->u.ageing_time);
+						       ageing_time->ageing_time);
 		break;
 	default:
 		err = -EOPNOTSUPP;
diff --git a/drivers/net/ethernet/mellanox/mlxsw/switchx2.c b/drivers/net/ethernet/mellanox/mlxsw/switchx2.c
index 2fd2279..edabc82 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/switchx2.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/switchx2.c
@@ -864,11 +864,14 @@ static int mlxsw_sx_port_attr_get(struct net_device *dev,
 {
 	struct mlxsw_sx_port *mlxsw_sx_port = netdev_priv(dev);
 	struct mlxsw_sx *mlxsw_sx = mlxsw_sx_port->mlxsw_sx;
+	struct switchdev_attr_port_parent_id *parent_id;
 
 	switch (attr->id) {
 	case SWITCHDEV_ATTR_ID_PORT_PARENT_ID:
-		attr->u.ppid.id_len = sizeof(mlxsw_sx->hw_id);
-		memcpy(&attr->u.ppid.id, &mlxsw_sx->hw_id, attr->u.ppid.id_len);
+		parent_id = SWITCHDEV_ATTR_PORT_PARENT_ID(attr);
+		parent_id->ppid.id_len = sizeof(mlxsw_sx->hw_id);
+		memcpy(&parent_id->ppid.id, &mlxsw_sx->hw_id,
+		       parent_id->ppid.id_len);
 		break;
 	default:
 		return -EOPNOTSUPP;
diff --git a/drivers/net/ethernet/rocker/rocker.c b/drivers/net/ethernet/rocker/rocker.c
index 32a80d2..512dc51 100644
--- a/drivers/net/ethernet/rocker/rocker.c
+++ b/drivers/net/ethernet/rocker/rocker.c
@@ -4327,14 +4327,19 @@ static int rocker_port_attr_get(struct net_device *dev,
 {
 	const struct rocker_port *rocker_port = netdev_priv(dev);
 	const struct rocker *rocker = rocker_port->rocker;
+	struct switchdev_attr_port_parent_id *parent_id;
+	struct switchdev_attr_port_bridge_flags *brport_flags;
 
 	switch (attr->id) {
 	case SWITCHDEV_ATTR_ID_PORT_PARENT_ID:
-		attr->u.ppid.id_len = sizeof(rocker->hw.id);
-		memcpy(&attr->u.ppid.id, &rocker->hw.id, attr->u.ppid.id_len);
+		parent_id = SWITCHDEV_ATTR_PORT_PARENT_ID(attr);
+		parent_id->ppid.id_len = sizeof(rocker->hw.id);
+		memcpy(&parent_id->ppid.id, &rocker->hw.id,
+		       parent_id->ppid.id_len);
 		break;
 	case SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS:
-		attr->u.brport_flags = rocker_port->brport_flags;
+		brport_flags = SWITCHDEV_ATTR_PORT_BRIDGE_FLAGS(attr);
+		brport_flags->brport_flags = rocker_port->brport_flags;
 		break;
 	default:
 		return -EOPNOTSUPP;
@@ -4378,20 +4383,26 @@ static int rocker_port_attr_set(struct net_device *dev,
 				struct switchdev_trans *trans)
 {
 	struct rocker_port *rocker_port = netdev_priv(dev);
+	struct switchdev_attr_port_stp_state *stp_state;
+	struct switchdev_attr_port_bridge_flags *brport_flags;
+	struct switchdev_attr_bridge_ageing_time *ageing_time;
 	int err = 0;
 
 	switch (attr->id) {
 	case SWITCHDEV_ATTR_ID_PORT_STP_STATE:
+		stp_state = SWITCHDEV_ATTR_PORT_STP_STATE(attr);
 		err = rocker_port_stp_update(rocker_port, trans, 0,
-					     attr->u.stp_state);
+					     stp_state->state);
 		break;
 	case SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS:
+		brport_flags = SWITCHDEV_ATTR_PORT_BRIDGE_FLAGS(attr);
 		err = rocker_port_brport_flags_set(rocker_port, trans,
-						   attr->u.brport_flags);
+						   brport_flags->brport_flags);
 		break;
 	case SWITCHDEV_ATTR_ID_BRIDGE_AGEING_TIME:
+		ageing_time = SWITCHDEV_ATTR_BRIDGE_AGEING_TIME(attr);
 		err = rocker_port_bridge_ageing_time(rocker_port, trans,
-						     attr->u.ageing_time);
+						     ageing_time->ageing_time);
 		break;
 	default:
 		err = -EOPNOTSUPP;
diff --git a/include/net/switchdev.h b/include/net/switchdev.h
index bc865e2..fa5ee68 100644
--- a/include/net/switchdev.h
+++ b/include/net/switchdev.h
@@ -52,14 +52,53 @@ enum switchdev_attr_id {
 struct switchdev_attr {
 	enum switchdev_attr_id id;
 	u32 flags;
-	union {
-		struct netdev_phys_item_id ppid;	/* PORT_PARENT_ID */
-		u8 stp_state;				/* PORT_STP_STATE */
-		unsigned long brport_flags;		/* PORT_BRIDGE_FLAGS */
-		u32 ageing_time;			/* BRIDGE_AGEING_TIME */
-	} u;
 };
 
+/* SWITCHDEV_ATTR_ID_PORT_PARENT_ID */
+struct switchdev_attr_port_parent_id {
+	struct switchdev_attr attr;
+	struct netdev_phys_item_id ppid;
+};
+
+#define SWITCHDEV_ATTR_PORT_PARENT_ID(attr) \
+	container_of(attr, struct switchdev_attr_port_parent_id, attr)
+
+/* SWITCHDEV_ATTR_ID_PORT_STP_STATE */
+struct switchdev_attr_port_stp_state {
+	struct switchdev_attr attr;
+	u8 state;
+};
+
+#define SWITCHDEV_ATTR_PORT_STP_STATE(attr) \
+	container_of(attr, struct switchdev_attr_port_stp_state, attr)
+
+/* SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS */
+struct switchdev_attr_port_bridge_flags {
+	struct switchdev_attr attr;
+	unsigned long brport_flags;
+};
+
+#define SWITCHDEV_ATTR_PORT_BRIDGE_FLAGS(attr) \
+	container_of(attr, struct switchdev_attr_port_bridge_flags, attr)
+
+/* SWITCHDEV_ATTR_ID_BRIDGE_AGEING_TIME */
+struct switchdev_attr_bridge_ageing_time {
+	struct switchdev_attr attr;
+	u32 ageing_time;
+};
+
+#define SWITCHDEV_ATTR_BRIDGE_AGEING_TIME(attr) \
+	container_of(attr, struct switchdev_attr_bridge_ageing_time, attr)
+
+/* SWITCHDEV_ATTR_ID_SWITCH_ID */
+struct switchdev_attr_switch_id {
+	struct switchdev_attr attr;
+	struct netdev_phys_item_id ppid;
+};
+
+#define SWITCHDEV_ATTR_SWITCH_ID(attr) \
+	container_of(attr, struct switchdev_attr_switch_id, attr)
+
 enum switchdev_obj_id {
 	SWITCHDEV_OBJ_ID_UNDEFINED,
 	SWITCHDEV_OBJ_ID_PORT_VLAN,
diff --git a/net/bridge/br_stp.c b/net/bridge/br_stp.c
index 80c34d7..50bc679 100644
--- a/net/bridge/br_stp.c
+++ b/net/bridge/br_stp.c
@@ -39,15 +39,17 @@ void br_log_state(const struct net_bridge_port *p)
 
 void br_set_state(struct net_bridge_port *p, unsigned int state)
 {
-	struct switchdev_attr attr = {
-		.id = SWITCHDEV_ATTR_ID_PORT_STP_STATE,
-		.flags = SWITCHDEV_F_DEFER,
-		.u.stp_state = state,
+	struct switchdev_attr_port_stp_state attr = {
+		.attr = {
+			.id = SWITCHDEV_ATTR_ID_PORT_STP_STATE,
+			.flags = SWITCHDEV_F_DEFER,
+		},
+		.state = state,
 	};
 	int err;
 
 	p->state = state;
-	err = switchdev_port_attr_set(p->dev, &attr);
+	err = switchdev_port_attr_set(p->dev, &attr.attr);
 	if (err)
 		br_warn(p->br, "error setting offload STP state on port %u(%s)\n",
 				(unsigned int) p->port_no, p->dev->name);
@@ -569,10 +571,12 @@ int br_set_max_age(struct net_bridge *br, unsigned long val)
 
 int br_set_ageing_time(struct net_bridge *br, u32 ageing_time)
 {
-	struct switchdev_attr attr = {
-		.id = SWITCHDEV_ATTR_ID_BRIDGE_AGEING_TIME,
-		.flags = SWITCHDEV_F_SKIP_EOPNOTSUPP,
-		.u.ageing_time = ageing_time,
+	struct switchdev_attr_bridge_ageing_time attr = {
+		.attr = {
+			.id = SWITCHDEV_ATTR_ID_BRIDGE_AGEING_TIME,
+			.flags = SWITCHDEV_F_SKIP_EOPNOTSUPP,
+		},
+		.ageing_time = ageing_time,
 	};
 	unsigned long t = clock_t_to_jiffies(ageing_time);
 	int err;
@@ -580,7 +584,7 @@ int br_set_ageing_time(struct net_bridge *br, u32 ageing_time)
 	if (t < BR_MIN_AGEING_TIME || t > BR_MAX_AGEING_TIME)
 		return -ERANGE;
 
-	err = switchdev_port_attr_set(br->dev, &attr);
+	err = switchdev_port_attr_set(br->dev, &attr.attr);
 	if (err)
 		return err;
 
diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c
index f88a62a..1ee6d44 100644
--- a/net/core/net-sysfs.c
+++ b/net/core/net-sysfs.c
@@ -470,15 +470,17 @@ static ssize_t phys_switch_id_show(struct device *dev,
 		return restart_syscall();
 
 	if (dev_isalive(netdev)) {
-		struct switchdev_attr attr = {
-			.id = SWITCHDEV_ATTR_ID_PORT_PARENT_ID,
-			.flags = SWITCHDEV_F_NO_RECURSE,
+		struct switchdev_attr_port_parent_id parent_id = {
+			.attr = {
+				.id = SWITCHDEV_ATTR_ID_PORT_PARENT_ID,
+				.flags = SWITCHDEV_F_NO_RECURSE,
+			},
 		};
 
-		ret = switchdev_port_attr_get(netdev, &attr);
+		ret = switchdev_port_attr_get(netdev, &parent_id.attr);
 		if (!ret)
-			ret = sprintf(buf, "%*phN\n", attr.u.ppid.id_len,
-				      attr.u.ppid.id);
+			ret = sprintf(buf, "%*phN\n", parent_id.ppid.id_len,
+				      parent_id.ppid.id);
 	}
 	rtnl_unlock();
 
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index 2477595..656e7a5 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -1024,20 +1024,22 @@ static int rtnl_phys_port_name_fill(struct sk_buff *skb, struct net_device *dev)
 static int rtnl_phys_switch_id_fill(struct sk_buff *skb, struct net_device *dev)
 {
 	int err;
-	struct switchdev_attr attr = {
-		.id = SWITCHDEV_ATTR_ID_PORT_PARENT_ID,
-		.flags = SWITCHDEV_F_NO_RECURSE,
+	struct switchdev_attr_port_parent_id parent_id = {
+		.attr = {
+			.id = SWITCHDEV_ATTR_ID_PORT_PARENT_ID,
+			.flags = SWITCHDEV_F_NO_RECURSE,
+		},
 	};
 
-	err = switchdev_port_attr_get(dev, &attr);
+	err = switchdev_port_attr_get(dev, &parent_id.attr);
 	if (err) {
 		if (err == -EOPNOTSUPP)
 			return 0;
 		return err;
 	}
 
-	if (nla_put(skb, IFLA_PHYS_SWITCH_ID, attr.u.ppid.id_len,
-		    attr.u.ppid.id))
+	if (nla_put(skb, IFLA_PHYS_SWITCH_ID, parent_id.ppid.id_len,
+		    parent_id.ppid.id))
 		return -EMSGSIZE;
 
 	return 0;
diff --git a/net/dsa/slave.c b/net/dsa/slave.c
index b0b8da0..e41803f 100644
--- a/net/dsa/slave.c
+++ b/net/dsa/slave.c
@@ -458,15 +458,17 @@ static int dsa_slave_port_attr_set(struct net_device *dev,
 {
 	struct dsa_slave_priv *p = netdev_priv(dev);
 	struct dsa_switch *ds = p->parent;
+	struct switchdev_attr_port_stp_state *stp_state;
 	int ret;
 
 	switch (attr->id) {
 	case SWITCHDEV_ATTR_ID_PORT_STP_STATE:
+		stp_state = SWITCHDEV_ATTR_PORT_STP_STATE(attr);
 		if (switchdev_trans_ph_prepare(trans))
 			ret = ds->drv->port_stp_update ? 0 : -EOPNOTSUPP;
 		else
 			ret = ds->drv->port_stp_update(ds, p->port,
-						       attr->u.stp_state);
+						       stp_state->state);
 		break;
 	default:
 		ret = -EOPNOTSUPP;
@@ -595,11 +597,13 @@ static int dsa_slave_port_attr_get(struct net_device *dev,
 {
 	struct dsa_slave_priv *p = netdev_priv(dev);
 	struct dsa_switch *ds = p->parent;
+	struct switchdev_attr_port_parent_id *parent_id;
 
 	switch (attr->id) {
 	case SWITCHDEV_ATTR_ID_PORT_PARENT_ID:
-		attr->u.ppid.id_len = sizeof(ds->index);
-		memcpy(&attr->u.ppid.id, &ds->index, attr->u.ppid.id_len);
+		parent_id = SWITCHDEV_ATTR_PORT_PARENT_ID(attr);
+		parent_id->ppid.id_len = sizeof(ds->index);
+		memcpy(&parent_id->ppid.id, &ds->index, parent_id->ppid.id_len);
 		break;
 	default:
 		return -EOPNOTSUPP;
diff --git a/net/switchdev/switchdev.c b/net/switchdev/switchdev.c
index be8ced1..8daac88d 100644
--- a/net/switchdev/switchdev.c
+++ b/net/switchdev/switchdev.c
@@ -309,7 +309,27 @@ static void switchdev_port_attr_set_deferred(struct net_device *dev,
 static int switchdev_port_attr_set_defer(struct net_device *dev,
 					 const struct switchdev_attr *attr)
 {
-	return switchdev_deferred_enqueue(dev, attr, sizeof(*attr),
+	size_t size = 0;
+
+	switch (attr->id) {
+	case SWITCHDEV_ATTR_ID_PORT_PARENT_ID:
+		size = sizeof(struct switchdev_attr_port_parent_id);
+		break;
+	case SWITCHDEV_ATTR_ID_PORT_STP_STATE:
+		size = sizeof(struct switchdev_attr_port_stp_state);
+		break;
+	case SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS:
+		size = sizeof(struct switchdev_attr_port_bridge_flags);
+		break;
+	case SWITCHDEV_ATTR_ID_BRIDGE_AGEING_TIME:
+		size = sizeof(struct switchdev_attr_bridge_ageing_time);
+		break;
+	default:
+		WARN_ON(!size);
+		return -EINVAL;
+	}
+
+	return switchdev_deferred_enqueue(dev, attr, size,
 					  switchdev_port_attr_set_deferred);
 }
 
@@ -758,19 +778,19 @@ int switchdev_port_bridge_getlink(struct sk_buff *skb, u32 pid, u32 seq,
 				  struct net_device *dev, u32 filter_mask,
 				  int nlflags)
 {
-	struct switchdev_attr attr = {
-		.id = SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS,
+	struct switchdev_attr_port_bridge_flags attr = {
+		.attr.id = SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS,
 	};
 	u16 mode = BRIDGE_MODE_UNDEF;
 	u32 mask = BR_LEARNING | BR_LEARNING_SYNC;
 	int err;
 
-	err = switchdev_port_attr_get(dev, &attr);
+	err = switchdev_port_attr_get(dev, &attr.attr);
 	if (err && err != -EOPNOTSUPP)
 		return err;
 
 	return ndo_dflt_bridge_getlink(skb, pid, seq, dev, mode,
-				       attr.u.brport_flags, mask, nlflags,
+				       attr.brport_flags, mask, nlflags,
 				       filter_mask, switchdev_port_vlan_fill);
 }
 EXPORT_SYMBOL_GPL(switchdev_port_bridge_getlink);
@@ -779,22 +799,22 @@ static int switchdev_port_br_setflag(struct net_device *dev,
 				     struct nlattr *nlattr,
 				     unsigned long brport_flag)
 {
-	struct switchdev_attr attr = {
-		.id = SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS,
+	struct switchdev_attr_port_bridge_flags attr = {
+		.attr.id = SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS,
 	};
 	u8 flag = nla_get_u8(nlattr);
 	int err;
 
-	err = switchdev_port_attr_get(dev, &attr);
+	err = switchdev_port_attr_get(dev, &attr.attr);
 	if (err)
 		return err;
 
 	if (flag)
-		attr.u.brport_flags |= brport_flag;
+		attr.brport_flags |= brport_flag;
 	else
-		attr.u.brport_flags &= ~brport_flag;
+		attr.brport_flags &= ~brport_flag;
 
-	return switchdev_port_attr_set(dev, &attr);
+	return switchdev_port_attr_set(dev, &attr.attr);
 }
 
 static const struct nla_policy
@@ -1111,10 +1131,10 @@ static struct net_device *switchdev_get_lowest_dev(struct net_device *dev)
 
 static struct net_device *switchdev_get_dev_by_nhs(struct fib_info *fi)
 {
-	struct switchdev_attr attr = {
-		.id = SWITCHDEV_ATTR_ID_PORT_PARENT_ID,
+	struct switchdev_attr_port_parent_id parent_id = {
+		.attr.id = SWITCHDEV_ATTR_ID_PORT_PARENT_ID,
 	};
-	struct switchdev_attr prev_attr;
+	struct switchdev_attr_port_parent_id prev_parent_id;
 	struct net_device *dev = NULL;
 	int nhsel;
 
@@ -1132,14 +1152,15 @@ static struct net_device *switchdev_get_dev_by_nhs(struct fib_info *fi)
 		if (!dev)
 			return NULL;
 
-		if (switchdev_port_attr_get(dev, &attr))
+		if (switchdev_port_attr_get(dev, &parent_id.attr))
 			return NULL;
 
 		if (nhsel > 0 &&
-		    !netdev_phys_item_id_same(&prev_attr.u.ppid, &attr.u.ppid))
+		    !netdev_phys_item_id_same(&prev_parent_id.ppid,
+					      &parent_id.ppid))
 				return NULL;
 
-		prev_attr = attr;
+		prev_parent_id = parent_id;
 	}
 
 	return dev;
@@ -1266,20 +1287,24 @@ EXPORT_SYMBOL_GPL(switchdev_fib_ipv4_abort);
 static bool switchdev_port_same_parent_id(struct net_device *a,
 					  struct net_device *b)
 {
-	struct switchdev_attr a_attr = {
-		.id = SWITCHDEV_ATTR_ID_PORT_PARENT_ID,
-		.flags = SWITCHDEV_F_NO_RECURSE,
+	struct switchdev_attr_port_parent_id parent_a_id = {
+		.attr = {
+			.id = SWITCHDEV_ATTR_ID_PORT_PARENT_ID,
+			.flags = SWITCHDEV_F_NO_RECURSE,
+		},
 	};
-	struct switchdev_attr b_attr = {
-		.id = SWITCHDEV_ATTR_ID_PORT_PARENT_ID,
-		.flags = SWITCHDEV_F_NO_RECURSE,
+	struct switchdev_attr_port_parent_id parent_b_id = {
+		.attr = {
+			.id = SWITCHDEV_ATTR_ID_PORT_PARENT_ID,
+			.flags = SWITCHDEV_F_NO_RECURSE,
+		},
 	};
 
-	if (switchdev_port_attr_get(a, &a_attr) ||
-	    switchdev_port_attr_get(b, &b_attr))
+	if (switchdev_port_attr_get(a, &parent_a_id.attr) ||
+	    switchdev_port_attr_get(b, &parent_b_id.attr))
 		return false;
 
-	return netdev_phys_item_id_same(&a_attr.u.ppid, &b_attr.u.ppid);
+	return netdev_phys_item_id_same(&parent_a_id.ppid, &parent_b_id.ppid);
 }
 
 static u32 switchdev_port_fwd_mark_get(struct net_device *dev,
-- 
1.7.10.4

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

* Re: [PATCH net-next 2/3] switchdev: fix: pass correct obj size when deferring obj add
  2015-10-20 19:36 ` [PATCH net-next 2/3] switchdev: fix: pass correct obj size when deferring obj add sfeldma
@ 2015-10-21  7:40   ` Jiri Pirko
  0 siblings, 0 replies; 6+ messages in thread
From: Jiri Pirko @ 2015-10-21  7:40 UTC (permalink / raw)
  To: sfeldma; +Cc: netdev, siva.mannem.lnx, vivien.didelot

Tue, Oct 20, 2015 at 09:36:38PM CEST, sfeldma@gmail.com wrote:
>From: Scott Feldman <sfeldma@gmail.com>
>
>Fixes: 0bc05d585d ("switchdev: allow caller to explicitly request attr_set as deferred")

This "fixes" is wrong. Should be:
4d429c5ddc5128fccd3048059ae26bb39f0d8284
"switchdev: introduce possibility to defer obj_add/del"


>Signed-off-by: Scott Feldman <sfeldma@gmail.com>
>---
> net/switchdev/switchdev.c |   19 ++++++++++++++++++-
> 1 file changed, 18 insertions(+), 1 deletion(-)
>
>diff --git a/net/switchdev/switchdev.c b/net/switchdev/switchdev.c
>index 56d8479..be8ced1 100644
>--- a/net/switchdev/switchdev.c
>+++ b/net/switchdev/switchdev.c
>@@ -489,7 +489,24 @@ static void switchdev_port_obj_del_deferred(struct net_device *dev,
> static int switchdev_port_obj_del_defer(struct net_device *dev,
> 					const struct switchdev_obj *obj)
> {
>-	return switchdev_deferred_enqueue(dev, obj, sizeof(*obj),
>+	size_t size = 0;
>+
>+	switch (obj->id) {
>+	case SWITCHDEV_OBJ_ID_PORT_VLAN:
>+		size = sizeof(struct switchdev_obj_port_vlan);
>+		break;
>+	case SWITCHDEV_OBJ_ID_IPV4_FIB:
>+		size = sizeof(struct switchdev_obj_ipv4_fib);
>+		break;
>+	case SWITCHDEV_OBJ_ID_PORT_FDB:
>+		size = sizeof(struct switchdev_obj_port_fdb);
>+		break;
>+	default:
>+		WARN_ON(!size);
>+		return -EINVAL;
>+	}
>+
>+	return switchdev_deferred_enqueue(dev, obj, size,
> 					  switchdev_port_obj_del_deferred);

we need this for add as well. Perhaps some generic helper to get size of
obj?


> }
> 
>-- 
>1.7.10.4
>

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

* Re: [PATCH net-next 1/3] switchdev: fix: erasing too much of vlan obj when handling multiple vlan specs
  2015-10-20 19:36 [PATCH net-next 1/3] switchdev: fix: erasing too much of vlan obj when handling multiple vlan specs sfeldma
  2015-10-20 19:36 ` [PATCH net-next 2/3] switchdev: fix: pass correct obj size when deferring obj add sfeldma
  2015-10-20 19:36 ` [PATCH net-next 3/3] switchdev: split switchdev_attr into individual structs sfeldma
@ 2015-10-21  7:46 ` Jiri Pirko
  2 siblings, 0 replies; 6+ messages in thread
From: Jiri Pirko @ 2015-10-21  7:46 UTC (permalink / raw)
  To: sfeldma; +Cc: netdev, siva.mannem.lnx, vivien.didelot

Tue, Oct 20, 2015 at 09:36:37PM CEST, sfeldma@gmail.com wrote:
>From: Scott Feldman <sfeldma@gmail.com>
>
>When adding vlans with multiple IFLA_BRIDGE_VLAN_INFO attrs set in AFSPEC,
>we would wipe the vlan obj struct after the first IFLA_BRIDGE_VLAN_INFO.
>Fix this by only clearing what's necessary on each IFLA_BRIDGE_VLAN_INFO
>iteration.
>
>Fixes: 9e8f4a54 ("switchdev: push object ID back to object structure")
>Signed-off-by: Scott Feldman <sfeldma@gmail.com>

Acked-by: Jiri Pirko <jiri@mellanox.com>

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

* Re: [PATCH net-next 3/3] switchdev: split switchdev_attr into individual structs
  2015-10-20 19:36 ` [PATCH net-next 3/3] switchdev: split switchdev_attr into individual structs sfeldma
@ 2015-10-21  7:49   ` Jiri Pirko
  0 siblings, 0 replies; 6+ messages in thread
From: Jiri Pirko @ 2015-10-21  7:49 UTC (permalink / raw)
  To: sfeldma; +Cc: netdev, siva.mannem.lnx, vivien.didelot

Tue, Oct 20, 2015 at 09:36:39PM CEST, sfeldma@gmail.com wrote:
>From: Scott Feldman <sfeldma@gmail.com>
>
>This was already done for switchdev_objs.   Changing switchdev_attrs to new
>style makes switchdev API consistent for both attrs and objs.
>
>No functional changes here.
>
>Signed-off-by: Scott Feldman <sfeldma@gmail.com>

This was on my todo list. Thanks for taking care of this.

Acked-by: Jiri Pirko <jiri@mellanox.com>

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

end of thread, other threads:[~2015-10-21  7:49 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-10-20 19:36 [PATCH net-next 1/3] switchdev: fix: erasing too much of vlan obj when handling multiple vlan specs sfeldma
2015-10-20 19:36 ` [PATCH net-next 2/3] switchdev: fix: pass correct obj size when deferring obj add sfeldma
2015-10-21  7:40   ` Jiri Pirko
2015-10-20 19:36 ` [PATCH net-next 3/3] switchdev: split switchdev_attr into individual structs sfeldma
2015-10-21  7:49   ` Jiri Pirko
2015-10-21  7:46 ` [PATCH net-next 1/3] switchdev: fix: erasing too much of vlan obj when handling multiple vlan specs Jiri Pirko

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.