[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20210306140033.axpbtqamaruzzzew@skbuf>
Date: Sat, 6 Mar 2021 16:00:33 +0200
From: Vladimir Oltean <olteanv@...il.com>
To: Tobias Waldekranz <tobias@...dekranz.com>
Cc: davem@...emloft.net, kuba@...nel.org, andrew@...n.ch,
vivien.didelot@...il.com, f.fainelli@...il.com,
netdev@...r.kernel.org
Subject: Re: [PATCH net 2/2] net: dsa: Always react to global bridge
attribute changes
Hi Tobias,
On Sat, Mar 06, 2021 at 01:24:55AM +0100, Tobias Waldekranz wrote:
> This is the second attempt to provide a fix for the issue described in
> 99b8202b179f, which was reverted in the previous commit.
>
> When a change is made to some global bridge attribute, such as VLAN
> filtering, accept events where orig_dev is the bridge master netdev.
>
> Separate the validation of orig_dev based on whether the attribute in
> question is global or per-port.
>
> Fixes: 5696c8aedfcc ("net: dsa: Don't offload port attributes on standalone ports")
> Signed-off-by: Tobias Waldekranz <tobias@...dekranz.com>
> ---
What do you think about this alternative?
-----------------------------[ cut here ]-----------------------------
>From af528ac6de2b16df4c8ba21bc7d978984883f319 Mon Sep 17 00:00:00 2001
From: Vladimir Oltean <vladimir.oltean@....com>
Date: Sat, 6 Mar 2021 15:47:01 +0200
Subject: [PATCH] net: dsa: fix switchdev objects on bridge master mistakenly
being applied on ports
Tobias reports that the blamed patch was too broad, and now, VLAN
objects being added to a bridge:
ip link add br0 type bridge vlan_filtering 1
ip link set swp2 master br0
ip link set swp3 master br0
bridge vlan add dev br0 vid 100 self
are being added to all slave ports instead (swp2, swp3).
This is because the fix was too broad: we made dsa_port_offloads_netdev
say "yes, I offload the br0 bridge" for all slave ports, but we didn't
add the checks whether the switchdev object was in fact meant for the
physical port or for the bridge itself.
Let's keep that definition of dsa_port_offloads_netdev, and just add the
checks for the individual switchdev object types and attributes that can
be notified both on a physical port as well as on the bridge network
interface. This will allow us in the future to do things such as offload
VLANs on the bridge interface by sending them to the CPU port, instead
of the crude "all VLANs on user ports must be added to the CPU port too"
logic that we have now. It will also allow us to properly support the
drivers that don't implement .port_bridge_add and .port_bridge_leave,
because we'll still have an accurate answer to the question
"dsa_port_offloads_netdev".
Fixes: 99b8202b179f ("net: dsa: fix SWITCHDEV_ATTR_ID_BRIDGE_VLAN_FILTERING getting ignored")
Reported-by: Tobias Waldekranz <tobias@...dekranz.com>
Signed-off-by: Vladimir Oltean <vladimir.oltean@....com>
---
net/dsa/slave.c | 60 ++++++++++++++++++++++++++++++++++---------------
1 file changed, 42 insertions(+), 18 deletions(-)
diff --git a/net/dsa/slave.c b/net/dsa/slave.c
index 491e3761b5f4..6e6384b2d5d2 100644
--- a/net/dsa/slave.c
+++ b/net/dsa/slave.c
@@ -283,6 +283,9 @@ static int dsa_slave_port_attr_set(struct net_device *dev,
switch (attr->id) {
case SWITCHDEV_ATTR_ID_PORT_STP_STATE:
+ if (!dsa_slave_dev_check(dev))
+ return 0;
+
ret = dsa_port_set_state(dp, attr->u.stp_state);
break;
case SWITCHDEV_ATTR_ID_BRIDGE_VLAN_FILTERING:
@@ -290,13 +293,22 @@ static int dsa_slave_port_attr_set(struct net_device *dev,
extack);
break;
case SWITCHDEV_ATTR_ID_BRIDGE_AGEING_TIME:
+ if (!dsa_slave_dev_check(attr->orig_dev))
+ return 0;
+
ret = dsa_port_ageing_time(dp, attr->u.ageing_time);
break;
case SWITCHDEV_ATTR_ID_PORT_PRE_BRIDGE_FLAGS:
+ if (!dsa_slave_dev_check(attr->orig_dev))
+ return 0;
+
ret = dsa_port_pre_bridge_flags(dp, attr->u.brport_flags,
extack);
break;
case SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS:
+ if (!dsa_slave_dev_check(attr->orig_dev))
+ return 0;
+
ret = dsa_port_bridge_flags(dp, attr->u.brport_flags, extack);
break;
case SWITCHDEV_ATTR_ID_BRIDGE_MROUTER:
@@ -341,9 +353,6 @@ static int dsa_slave_vlan_add(struct net_device *dev,
struct switchdev_obj_port_vlan vlan;
int err;
- if (!dsa_port_offloads_netdev(dp, obj->orig_dev))
- return -EOPNOTSUPP;
-
if (dsa_port_skip_vlan_configuration(dp)) {
NL_SET_ERR_MSG_MOD(extack, "skipping configuration of VLAN");
return 0;
@@ -389,10 +398,14 @@ static int dsa_slave_port_obj_add(struct net_device *dev,
struct dsa_port *dp = dsa_slave_to_port(dev);
int err;
+ if (!dsa_port_offloads_netdev(dp, obj->orig_dev))
+ return -EOPNOTSUPP;
+
switch (obj->id) {
case SWITCHDEV_OBJ_ID_PORT_MDB:
- if (!dsa_port_offloads_netdev(dp, obj->orig_dev))
- return -EOPNOTSUPP;
+ if (!dsa_slave_dev_check(obj->orig_dev))
+ return 0;
+
err = dsa_port_mdb_add(dp, SWITCHDEV_OBJ_PORT_MDB(obj));
break;
case SWITCHDEV_OBJ_ID_HOST_MDB:
@@ -402,16 +415,21 @@ static int dsa_slave_port_obj_add(struct net_device *dev,
err = dsa_port_mdb_add(dp->cpu_dp, SWITCHDEV_OBJ_PORT_MDB(obj));
break;
case SWITCHDEV_OBJ_ID_PORT_VLAN:
+ if (!dsa_slave_dev_check(obj->orig_dev))
+ return 0;
+
err = dsa_slave_vlan_add(dev, obj, extack);
break;
case SWITCHDEV_OBJ_ID_MRP:
- if (!dsa_port_offloads_netdev(dp, obj->orig_dev))
- return -EOPNOTSUPP;
+ if (!dsa_slave_dev_check(obj->orig_dev))
+ return 0;
+
err = dsa_port_mrp_add(dp, SWITCHDEV_OBJ_MRP(obj));
break;
case SWITCHDEV_OBJ_ID_RING_ROLE_MRP:
- if (!dsa_port_offloads_netdev(dp, obj->orig_dev))
- return -EOPNOTSUPP;
+ if (!dsa_slave_dev_check(obj->orig_dev))
+ return 0;
+
err = dsa_port_mrp_add_ring_role(dp,
SWITCHDEV_OBJ_RING_ROLE_MRP(obj));
break;
@@ -431,9 +449,6 @@ static int dsa_slave_vlan_del(struct net_device *dev,
struct switchdev_obj_port_vlan *vlan;
int err;
- if (!dsa_port_offloads_netdev(dp, obj->orig_dev))
- return -EOPNOTSUPP;
-
if (dsa_port_skip_vlan_configuration(dp))
return 0;
@@ -457,10 +472,14 @@ static int dsa_slave_port_obj_del(struct net_device *dev,
struct dsa_port *dp = dsa_slave_to_port(dev);
int err;
+ if (!dsa_port_offloads_netdev(dp, obj->orig_dev))
+ return -EOPNOTSUPP;
+
switch (obj->id) {
case SWITCHDEV_OBJ_ID_PORT_MDB:
- if (!dsa_port_offloads_netdev(dp, obj->orig_dev))
- return -EOPNOTSUPP;
+ if (!dsa_slave_dev_check(obj->orig_dev))
+ return 0;
+
err = dsa_port_mdb_del(dp, SWITCHDEV_OBJ_PORT_MDB(obj));
break;
case SWITCHDEV_OBJ_ID_HOST_MDB:
@@ -470,16 +489,21 @@ static int dsa_slave_port_obj_del(struct net_device *dev,
err = dsa_port_mdb_del(dp->cpu_dp, SWITCHDEV_OBJ_PORT_MDB(obj));
break;
case SWITCHDEV_OBJ_ID_PORT_VLAN:
+ if (!dsa_slave_dev_check(obj->orig_dev))
+ return 0;
+
err = dsa_slave_vlan_del(dev, obj);
break;
case SWITCHDEV_OBJ_ID_MRP:
- if (!dsa_port_offloads_netdev(dp, obj->orig_dev))
- return -EOPNOTSUPP;
+ if (!dsa_slave_dev_check(obj->orig_dev))
+ return 0;
+
err = dsa_port_mrp_del(dp, SWITCHDEV_OBJ_MRP(obj));
break;
case SWITCHDEV_OBJ_ID_RING_ROLE_MRP:
- if (!dsa_port_offloads_netdev(dp, obj->orig_dev))
- return -EOPNOTSUPP;
+ if (!dsa_slave_dev_check(obj->orig_dev))
+ return 0;
+
err = dsa_port_mrp_del_ring_role(dp,
SWITCHDEV_OBJ_RING_ROLE_MRP(obj));
break;
-----------------------------[ cut here ]-----------------------------
Powered by blists - more mailing lists