1 From 032a954061afd4b7426c3eb6bfd2952ef1e9a384 Mon Sep 17 00:00:00 2001
2 From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= <noltari@gmail.com>
3 Date: Sun, 19 Mar 2023 10:55:40 +0100
4 Subject: [PATCH] net: dsa: tag_brcm: legacy: fix daisy-chained switches
6 Content-Type: text/plain; charset=UTF-8
7 Content-Transfer-Encoding: 8bit
9 When BCM63xx internal switches are connected to switches with a 4-byte
10 Broadcom tag, it does not identify the packet as VLAN tagged, so it adds one
11 based on its PVID (which is likely 0).
12 Right now, the packet is received by the BCM63xx internal switch and the 6-byte
13 tag is properly processed. The next step would to decode the corresponding
14 4-byte tag. However, the internal switch adds an invalid VLAN tag after the
15 6-byte tag and the 4-byte tag handling fails.
16 In order to fix this we need to remove the invalid VLAN tag after the 6-byte
17 tag before passing it to the 4-byte tag decoding.
19 Fixes: 964dbf186eaa ("net: dsa: tag_brcm: add support for legacy tags")
20 Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
21 Reviewed-by: Michal Swiatkowski <michal.swiatkowski@linux.intel.com>
22 Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
23 Link: https://lore.kernel.org/r/20230319095540.239064-1-noltari@gmail.com
24 Signed-off-by: Jakub Kicinski <kuba@kernel.org>
26 net/dsa/tag_brcm.c | 10 ++++++++--
27 1 file changed, 8 insertions(+), 2 deletions(-)
29 --- a/net/dsa/tag_brcm.c
30 +++ b/net/dsa/tag_brcm.c
33 #include <linux/dsa/brcm.h>
34 #include <linux/etherdevice.h>
35 +#include <linux/if_vlan.h>
36 #include <linux/list.h>
37 #include <linux/slab.h>
39 @@ -248,6 +249,7 @@ static struct sk_buff *brcm_leg_tag_xmit
40 static struct sk_buff *brcm_leg_tag_rcv(struct sk_buff *skb,
41 struct net_device *dev)
43 + int len = BRCM_LEG_TAG_LEN;
47 @@ -262,12 +264,16 @@ static struct sk_buff *brcm_leg_tag_rcv(
51 + /* VLAN tag is added by BCM63xx internal switch */
52 + if (netdev_uses_dsa(skb->dev))
55 /* Remove Broadcom tag and update checksum */
56 - skb_pull_rcsum(skb, BRCM_LEG_TAG_LEN);
57 + skb_pull_rcsum(skb, len);
59 dsa_default_offload_fwd_mark(skb);
61 - dsa_strip_etype_header(skb, BRCM_LEG_TAG_LEN);
62 + dsa_strip_etype_header(skb, len);