mirror of
https://github.com/openwrt/openwrt.git
synced 2025-01-09 14:33:00 +00:00
kernel: generic: patch: 802.2+LLC - set transport_header offset
Conversion to DSA broke 802.2+LLC+SNAP packet processing. Frames received by napi_complete_done with GRO and DSA have transport_header set two bytes short, or pointing 2 bytes before network_header & skb->data. As snap_rcv expects transport_header to point to SNAP header (OID:PID) after LLC processing advances offset over LLC header (llc_rcv & llc_fixup_skb), code doesn't find a match and packet is dropped. Image built at this commit operates properly:86dadeba48
- generic: add patch for GPON-ONU-34-20BI quirk Image built at following commit exhibits the issue:337e36e0ef
- ipq806x: convert each device to DSA implementation As issue is LLC specific, to avoid impacting non-LLC traffic, and to follow up on original assumption made on kernel commit fda55eca5a33 ("net: introduce skb_transport_header_was_set()") stating "network stacks usually reset the transport header anyway", llc_fixup_skb to reset and advance the offset. llc_fixup_skb already assumes the LLC header is at skb->data, and by definition SNAP header immediately follows. Signed-off-by: Antonio Pastor <antonio.pastor@gmail.com> Link: https://github.com/openwrt/openwrt/pull/17220 Signed-off-by: Robert Marko <robimarko@gmail.com> (cherry picked from commitda7ab64f1f
)
This commit is contained in:
parent
5b4a081f47
commit
76a546a83a
@ -0,0 +1,52 @@
|
|||||||
|
From a024e377efed31ecfb39210bed562932321345b3 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Antonio Pastor <antonio.pastor@gmail.com>
|
||||||
|
Date: Tue, 24 Dec 2024 20:07:20 -0500
|
||||||
|
Subject: [PATCH] net: llc: reset skb->transport_header
|
||||||
|
|
||||||
|
802.2+LLC+SNAP frames received by napi_complete_done with GRO and DSA
|
||||||
|
have skb->transport_header set two bytes short, or pointing 2 bytes
|
||||||
|
before network_header & skb->data. As snap_rcv expects transport_header
|
||||||
|
to point to SNAP header (OID:PID) after LLC processing advances offset
|
||||||
|
over LLC header (llc_rcv & llc_fixup_skb), code doesn't find a match
|
||||||
|
and packet is dropped.
|
||||||
|
|
||||||
|
Between napi_complete_done and snap_rcv, transport_header is not used
|
||||||
|
until __netif_receive_skb_core, where originally it was being reset.
|
||||||
|
Commit fda55eca5a33 ("net: introduce skb_transport_header_was_set()")
|
||||||
|
only does so if not set, on the assumption the value was set correctly
|
||||||
|
by GRO (and also on assumption that "network stacks usually reset the
|
||||||
|
transport header anyway"). Afterwards it is moved forward by
|
||||||
|
llc_fixup_skb.
|
||||||
|
|
||||||
|
Locally generated traffic shows up at __netif_receive_skb_core with no
|
||||||
|
transport_header set and is processed without issue. On a setup with
|
||||||
|
GRO but no DSA, transport_header and network_header are both set to
|
||||||
|
point to skb->data which is also correct.
|
||||||
|
|
||||||
|
As issue is LLC specific, to avoid impacting non-LLC traffic, and to
|
||||||
|
follow up on original assumption made on previous code change,
|
||||||
|
llc_fixup_skb to reset the offset after skb pull. llc_fixup_skb
|
||||||
|
assumes the LLC header is at skb->data, and by definition SNAP header
|
||||||
|
immediately follows.
|
||||||
|
|
||||||
|
Fixes: fda55eca5a33 ("net: introduce skb_transport_header_was_set()")
|
||||||
|
Signed-off-by: Antonio Pastor <antonio.pastor@gmail.com>
|
||||||
|
Reviewed-by: Eric Dumazet <edumazet@google.com>
|
||||||
|
Link: https://patch.msgid.link/20241225010723.2830290-1-antonio.pastor@gmail.com
|
||||||
|
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||||
|
---
|
||||||
|
net/llc/llc_input.c | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
--- a/net/llc/llc_input.c
|
||||||
|
+++ b/net/llc/llc_input.c
|
||||||
|
@@ -124,8 +124,8 @@ static inline int llc_fixup_skb(struct s
|
||||||
|
if (unlikely(!pskb_may_pull(skb, llc_len)))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
- skb->transport_header += llc_len;
|
||||||
|
skb_pull(skb, llc_len);
|
||||||
|
+ skb_reset_transport_header(skb);
|
||||||
|
if (skb->protocol == htons(ETH_P_802_2)) {
|
||||||
|
__be16 pdulen;
|
||||||
|
s32 data_size;
|
Loading…
Reference in New Issue
Block a user