From: Antonio Pastor Date: Fri, 20 Dec 2024 16:28:45 +0000 (-0500) Subject: kernel: generic: patch: 802.2+LLC - set transport_header offset X-Git-Url: http://git.cdn.openwrt.org/?a=commitdiff_plain;h=da7ab64f1f6d72597a1c8a8bb3b57409227bc635;p=openwrt%2Fopenwrt.git 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 Link: https://github.com/openwrt/openwrt/pull/17220 Signed-off-by: Robert Marko --- diff --git a/target/linux/generic/backport-6.6/902-net-llc-reset-skb-transport_header.patch b/target/linux/generic/backport-6.6/902-net-llc-reset-skb-transport_header.patch new file mode 100644 index 0000000000..b1f0b8fce7 --- /dev/null +++ b/target/linux/generic/backport-6.6/902-net-llc-reset-skb-transport_header.patch @@ -0,0 +1,52 @@ +From a024e377efed31ecfb39210bed562932321345b3 Mon Sep 17 00:00:00 2001 +From: Antonio Pastor +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 +Reviewed-by: Eric Dumazet +Link: https://patch.msgid.link/20241225010723.2830290-1-antonio.pastor@gmail.com +Signed-off-by: Jakub Kicinski +--- + 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;