When a VLAN entry is added multiple times in a row to a bridge port:
bridge vlan add dev lan12 vid 100 master static
the bridge notifies switchdev each time, even if nothing changed, which
makes driver-level accounting impossible.
Since nbp_vlan_add() changes only the flags of the existing port VLAN,
record the old flags, and restore them on the error path of
br_switchdev_port_vlan_add().
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
---
net/bridge/br_vlan.c | 15 +++++++++++----
1 file changed, 11 insertions(+), 4 deletions(-)
diff --git a/net/bridge/br_vlan.c b/net/bridge/br_vlan.c
index c7cadc1b4f71..3c149b54124e 100644
--- a/net/bridge/br_vlan.c
+++ b/net/bridge/br_vlan.c
@@ -1279,11 +1279,18 @@ int nbp_vlan_add(struct net_bridge_port *port, u16 vid, u16 flags,
*changed = false;
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, extack);
- if (ret && ret != -EOPNOTSUPP)
- return ret;
+ u16 old_flags = vlan->flags;
+
*changed = __vlan_add_flags(vlan, flags);
+ if (*changed) {
+ /* Pass the flags to the hardware bridge */
+ ret = br_switchdev_port_vlan_add(port->dev, vid, flags,
+ extack);
+ if (ret && ret != -EOPNOTSUPP) {
+ __vlan_add_flags(vlan, old_flags);
+ return ret;
+ }
+ }
return 0;
}--
2.25.1