mirror of
https://github.com/openwrt/openwrt.git
synced 2024-12-21 14:37:57 +00:00
90120a1552
Removed upstreamed: backport-5.10/888-v6.1-ca8210-Fix-crash-by-zero-initializing-data.patch[1] All patches automatically rebased. 1. https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?h=v5.10.159&id=0a8e66e375736ea12c11f0ef238ba2a8efec460b Build system: x86_64 Build-tested: ramips/tplink_archer-a6-v3 Run-tested: ramips/tplink_archer-a6-v3 Signed-off-by: John Audia <therealgraysky@proton.me>
139 lines
4.7 KiB
Diff
139 lines
4.7 KiB
Diff
From bea7907837c57a0aaac009931eb14efb056dafab Mon Sep 17 00:00:00 2001
|
|
From: Vladimir Oltean <vladimir.oltean@nxp.com>
|
|
Date: Thu, 29 Jul 2021 17:56:00 +0300
|
|
Subject: [PATCH] net: dsa: don't set skb->offload_fwd_mark when not offloading
|
|
the bridge
|
|
|
|
DSA has gained the recent ability to deal gracefully with upper
|
|
interfaces it cannot offload, such as the bridge, bonding or team
|
|
drivers. When such uppers exist, the ports are still in standalone mode
|
|
as far as the hardware is concerned.
|
|
|
|
But when we deliver packets to the software bridge in order for that to
|
|
do the forwarding, there is an unpleasant surprise in that the bridge
|
|
will refuse to forward them. This is because we unconditionally set
|
|
skb->offload_fwd_mark = true, meaning that the bridge thinks the frames
|
|
were already forwarded in hardware by us.
|
|
|
|
Since dp->bridge_dev is populated only when there is hardware offload
|
|
for it, but not in the software fallback case, let's introduce a new
|
|
helper that can be called from the tagger data path which sets the
|
|
skb->offload_fwd_mark accordingly to zero when there is no hardware
|
|
offload for bridging. This lets the bridge forward packets back to other
|
|
interfaces of our switch, if needed.
|
|
|
|
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
|
|
Reviewed-by: Tobias Waldekranz <tobias@waldekranz.com>
|
|
Signed-off-by: David S. Miller <davem@davemloft.net>
|
|
---
|
|
net/dsa/dsa_priv.h | 14 ++++++++++++++
|
|
net/dsa/tag_brcm.c | 4 ++--
|
|
net/dsa/tag_dsa.c | 15 +++++++++++----
|
|
net/dsa/tag_ksz.c | 2 +-
|
|
net/dsa/tag_lan9303.c | 3 ++-
|
|
net/dsa/tag_mtk.c | 2 +-
|
|
net/dsa/tag_ocelot.c | 2 +-
|
|
net/dsa/tag_rtl4_a.c | 2 +-
|
|
net/dsa/tag_sja1105.c | 20 ++++++++++++++------
|
|
9 files changed, 47 insertions(+), 17 deletions(-)
|
|
|
|
--- a/net/dsa/dsa_priv.h
|
|
+++ b/net/dsa/dsa_priv.h
|
|
@@ -266,6 +266,20 @@ static inline struct sk_buff *dsa_untag_
|
|
return skb;
|
|
}
|
|
|
|
+/* If the ingress port offloads the bridge, we mark the frame as autonomously
|
|
+ * forwarded by hardware, so the software bridge doesn't forward in twice, back
|
|
+ * to us, because we already did. However, if we're in fallback mode and we do
|
|
+ * software bridging, we are not offloading it, therefore the dp->bridge_dev
|
|
+ * pointer is not populated, and flooding needs to be done by software (we are
|
|
+ * effectively operating in standalone ports mode).
|
|
+ */
|
|
+static inline void dsa_default_offload_fwd_mark(struct sk_buff *skb)
|
|
+{
|
|
+ struct dsa_port *dp = dsa_slave_to_port(skb->dev);
|
|
+
|
|
+ skb->offload_fwd_mark = !!(dp->bridge_dev);
|
|
+}
|
|
+
|
|
/* switch.c */
|
|
int dsa_switch_register_notifier(struct dsa_switch *ds);
|
|
void dsa_switch_unregister_notifier(struct dsa_switch *ds);
|
|
--- a/net/dsa/tag_brcm.c
|
|
+++ b/net/dsa/tag_brcm.c
|
|
@@ -166,7 +166,7 @@ static struct sk_buff *brcm_tag_rcv_ll(s
|
|
/* Remove Broadcom tag and update checksum */
|
|
skb_pull_rcsum(skb, BRCM_TAG_LEN);
|
|
|
|
- skb->offload_fwd_mark = 1;
|
|
+ dsa_default_offload_fwd_mark(skb);
|
|
|
|
return skb;
|
|
}
|
|
@@ -270,7 +270,7 @@ static struct sk_buff *brcm_leg_tag_rcv(
|
|
/* Remove Broadcom tag and update checksum */
|
|
skb_pull_rcsum(skb, BRCM_LEG_TAG_LEN);
|
|
|
|
- skb->offload_fwd_mark = 1;
|
|
+ dsa_default_offload_fwd_mark(skb);
|
|
|
|
/* Move the Ethernet DA and SA */
|
|
memmove(skb->data - ETH_HLEN,
|
|
--- a/net/dsa/tag_ksz.c
|
|
+++ b/net/dsa/tag_ksz.c
|
|
@@ -25,7 +25,7 @@ static struct sk_buff *ksz_common_rcv(st
|
|
if (pskb_trim_rcsum(skb, skb->len - len))
|
|
return NULL;
|
|
|
|
- skb->offload_fwd_mark = true;
|
|
+ dsa_default_offload_fwd_mark(skb);
|
|
|
|
return skb;
|
|
}
|
|
--- a/net/dsa/tag_lan9303.c
|
|
+++ b/net/dsa/tag_lan9303.c
|
|
@@ -115,7 +115,8 @@ static struct sk_buff *lan9303_rcv(struc
|
|
skb_pull_rcsum(skb, 2 + 2);
|
|
memmove(skb->data - ETH_HLEN, skb->data - (ETH_HLEN + LAN9303_TAG_LEN),
|
|
2 * ETH_ALEN);
|
|
- skb->offload_fwd_mark = !(lan9303_tag1 & LAN9303_TAG_RX_TRAPPED_TO_CPU);
|
|
+ if (!(lan9303_tag1 & LAN9303_TAG_RX_TRAPPED_TO_CPU))
|
|
+ dsa_default_offload_fwd_mark(skb);
|
|
|
|
return skb;
|
|
}
|
|
--- a/net/dsa/tag_mtk.c
|
|
+++ b/net/dsa/tag_mtk.c
|
|
@@ -104,7 +104,7 @@ static struct sk_buff *mtk_tag_rcv(struc
|
|
|
|
/* Only unicast or broadcast frames are offloaded */
|
|
if (likely(!is_multicast_skb))
|
|
- skb->offload_fwd_mark = 1;
|
|
+ dsa_default_offload_fwd_mark(skb);
|
|
|
|
return skb;
|
|
}
|
|
--- a/net/dsa/tag_ocelot.c
|
|
+++ b/net/dsa/tag_ocelot.c
|
|
@@ -225,7 +225,7 @@ static struct sk_buff *ocelot_rcv(struct
|
|
*/
|
|
return NULL;
|
|
|
|
- skb->offload_fwd_mark = 1;
|
|
+ dsa_default_offload_fwd_mark(skb);
|
|
skb->priority = qos_class;
|
|
|
|
/* Ocelot switches copy frames unmodified to the CPU. However, it is
|
|
--- a/net/dsa/tag_rtl4_a.c
|
|
+++ b/net/dsa/tag_rtl4_a.c
|
|
@@ -115,7 +115,7 @@ static struct sk_buff *rtl4a_tag_rcv(str
|
|
skb->data - ETH_HLEN - RTL4_A_HDR_LEN,
|
|
2 * ETH_ALEN);
|
|
|
|
- skb->offload_fwd_mark = 1;
|
|
+ dsa_default_offload_fwd_mark(skb);
|
|
|
|
return skb;
|
|
}
|