Commit 032a9540 authored by Álvaro Fernández Rojas's avatar Álvaro Fernández Rojas Committed by Jakub Kicinski

net: dsa: tag_brcm: legacy: fix daisy-chained switches

When BCM63xx internal switches are connected to switches with a 4-byte
Broadcom tag, it does not identify the packet as VLAN tagged, so it adds one
based on its PVID (which is likely 0).
Right now, the packet is received by the BCM63xx internal switch and the 6-byte
tag is properly processed. The next step would to decode the corresponding
4-byte tag. However, the internal switch adds an invalid VLAN tag after the
6-byte tag and the 4-byte tag handling fails.
In order to fix this we need to remove the invalid VLAN tag after the 6-byte
tag before passing it to the 4-byte tag decoding.

Fixes: 964dbf18 ("net: dsa: tag_brcm: add support for legacy tags")
Signed-off-by: default avatarÁlvaro Fernández Rojas <noltari@gmail.com>
Reviewed-by: default avatarMichal Swiatkowski <michal.swiatkowski@linux.intel.com>
Reviewed-by: default avatarFlorian Fainelli <f.fainelli@gmail.com>
Link: https://lore.kernel.org/r/20230319095540.239064-1-noltari@gmail.comSigned-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent f038f391
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include <linux/dsa/brcm.h> #include <linux/dsa/brcm.h>
#include <linux/etherdevice.h> #include <linux/etherdevice.h>
#include <linux/if_vlan.h>
#include <linux/list.h> #include <linux/list.h>
#include <linux/slab.h> #include <linux/slab.h>
...@@ -252,6 +253,7 @@ static struct sk_buff *brcm_leg_tag_xmit(struct sk_buff *skb, ...@@ -252,6 +253,7 @@ static struct sk_buff *brcm_leg_tag_xmit(struct sk_buff *skb,
static struct sk_buff *brcm_leg_tag_rcv(struct sk_buff *skb, static struct sk_buff *brcm_leg_tag_rcv(struct sk_buff *skb,
struct net_device *dev) struct net_device *dev)
{ {
int len = BRCM_LEG_TAG_LEN;
int source_port; int source_port;
u8 *brcm_tag; u8 *brcm_tag;
...@@ -266,12 +268,16 @@ static struct sk_buff *brcm_leg_tag_rcv(struct sk_buff *skb, ...@@ -266,12 +268,16 @@ static struct sk_buff *brcm_leg_tag_rcv(struct sk_buff *skb,
if (!skb->dev) if (!skb->dev)
return NULL; return NULL;
/* VLAN tag is added by BCM63xx internal switch */
if (netdev_uses_dsa(skb->dev))
len += VLAN_HLEN;
/* Remove Broadcom tag and update checksum */ /* Remove Broadcom tag and update checksum */
skb_pull_rcsum(skb, BRCM_LEG_TAG_LEN); skb_pull_rcsum(skb, len);
dsa_default_offload_fwd_mark(skb); dsa_default_offload_fwd_mark(skb);
dsa_strip_etype_header(skb, BRCM_LEG_TAG_LEN); dsa_strip_etype_header(skb, len);
return skb; return skb;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment