Skip to content

Commit b38e659

Browse files
vladimirolteandavem330
authored andcommitted
net: dsa: sja1105: update existing VLANs from the bridge VLAN list
When running this sequence of operations: ip link add br0 type bridge vlan_filtering 1 ip link set swp4 master br0 bridge vlan add dev swp4 vid 1 We observe the traffic sent on swp4 is still untagged, even though the bridge has overwritten the existing VLAN entry: port vlan ids swp4 1 PVID br0 1 PVID Egress Untagged This happens because we didn't consider that the 'bridge vlan add' command just overwrites VLANs like it's nothing. We treat the 'vid 1 pvid untagged' and the 'vid 1' as two separate VLANs, and the first still has precedence when calling sja1105_build_vlan_table. Obviously there is a disagreement regarding semantics, and we end up doing something unexpected from the PoV of the bridge. Let's actually consider an "existing VLAN" to be one which is on the same port, and has the same VLAN ID, as one we already have, and update it if it has different flags than we do. The first blamed commit is the one introducing the bug, the second one is the latest on top of which the bugfix still applies. Fixes: ec5ae61 ("net: dsa: sja1105: save/restore VLANs using a delta commit method") Fixes: 5899ee3 ("net: dsa: tag_8021q: add a context structure") Signed-off-by: Vladimir Oltean <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent ed040ab commit b38e659

File tree

1 file changed

+15
-4
lines changed

1 file changed

+15
-4
lines changed

drivers/net/dsa/sja1105/sja1105_main.c

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2816,11 +2816,22 @@ static int sja1105_vlan_add_one(struct dsa_switch *ds, int port, u16 vid,
28162816
bool pvid = flags & BRIDGE_VLAN_INFO_PVID;
28172817
struct sja1105_bridge_vlan *v;
28182818

2819-
list_for_each_entry(v, vlan_list, list)
2820-
if (v->port == port && v->vid == vid &&
2821-
v->untagged == untagged && v->pvid == pvid)
2819+
list_for_each_entry(v, vlan_list, list) {
2820+
if (v->port == port && v->vid == vid) {
28222821
/* Already added */
2823-
return 0;
2822+
if (v->untagged == untagged && v->pvid == pvid)
2823+
/* Nothing changed */
2824+
return 0;
2825+
2826+
/* It's the same VLAN, but some of the flags changed
2827+
* and the user did not bother to delete it first.
2828+
* Update it and trigger sja1105_build_vlan_table.
2829+
*/
2830+
v->untagged = untagged;
2831+
v->pvid = pvid;
2832+
return 1;
2833+
}
2834+
}
28242835

28252836
v = kzalloc(sizeof(*v), GFP_KERNEL);
28262837
if (!v) {

0 commit comments

Comments
 (0)