Skip to content

Commit

Permalink
kernel: generic: patch: 802.2+LLC - set transport_header offset
Browse files Browse the repository at this point in the history
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:
  86dadeb - generic: add patch for GPON-ONU-34-20BI quirk
Image built at following commit exhibits the issue:
  337e36e - 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 <[email protected]>
Link: openwrt/openwrt#17220
Signed-off-by: Robert Marko <[email protected]>
(cherry picked from commit da7ab64)
  • Loading branch information
Antonio Pastor authored and robimarko committed Dec 28, 2024
1 parent 5b4a081 commit 76a546a
Showing 1 changed file with 52 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
From a024e377efed31ecfb39210bed562932321345b3 Mon Sep 17 00:00:00 2001
From: Antonio Pastor <[email protected]>
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 <[email protected]>
Reviewed-by: Eric Dumazet <[email protected]>
Link: https://patch.msgid.link/[email protected]
Signed-off-by: Jakub Kicinski <[email protected]>
---
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;

0 comments on commit 76a546a

Please sign in to comment.