From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-wr1-f50.google.com (mail-wr1-f50.google.com [209.85.221.50]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C79043D1A9A for ; Sun, 9 Aug 2026 12:15:02 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.50 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786277710; cv=none; b=ee+XE4J6dzqtPcymrDTkd2Jhwx7caU/588kJxcRAWr+E1yB/Wsx63fa1H2wzIxL67ZRRRPRYSJF7mHKofBH/Xh6yuVzU/FJ2ygPkiOxazj5n5RaO35B4ZFodC1PIIbgrGaMzOVdsfSZwyuPIj/XpbllWA376zUiLmLnIDwkQWF0= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786277710; c=relaxed/simple; bh=v2IOzHAE8P7e7RPtUYejuCgStYNSB6rjJrtbYCdnJjI=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=abS1mAFiDbsN/dc1p94HOKnUetGuR5/nGaDkE3xqtYI9hLkLCwrwihhW2N86WZMFK+yB12wiF4tgF8hvE1BrZjhk22YtQgEubOzpBEDXYyVvuryCQBTYL4RH4n9Z+KodtZInypY+8zhxkYPpeAjjjXl65+gi9nRL7wN1/iOx+VM= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=jaxRpvxp; arc=none smtp.client-ip=209.85.221.50 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="jaxRpvxp" Received: by mail-wr1-f50.google.com with SMTP id ffacd0b85a97d-473987fc217so26685f8f.0 for ; Sun, 09 Aug 2026 05:15:02 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1786277701; x=1786882501; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=tK5etVjV8isZ+EPgOl8b6oOCjBS1RkzIoG5Pe4Znpcs=; b=jaxRpvxp0+bYmTbQuUsag8eEDCxNEzgqanm0XvuzVSn+sTWBP88Jkh4FXmNy5t7mz8 KbYNwlorwXWySIDuVP4MMWVZfPlXD5sh8HtbWO0mCWdmOGKSmCeVVjfheZbihHL7svER Ga8eHizLOtzHO+RR3sNQwqbU6RQ+EIEny/XTeqMsi4FFsfrFq6y1RtLlyeWDXORQ8uQk Ya7ea/dQ88bbES/bHkRqRIk2S3QOf0BSjaWRuzICqxSxeXM2vbYdAHNH0paz9N70T6Cw q2ekAFuPzcB3JOp/eu7fGtOnPolB1lBb1DS8R1o7a8Jz8zXP52YvLA0nbJgNkar4Ujgr Rdaw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1786277701; x=1786882501; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=tK5etVjV8isZ+EPgOl8b6oOCjBS1RkzIoG5Pe4Znpcs=; b=Rmh18gvpDInPlgJFea0+g+hAtAgdJSRxink7Bmh7CcaACjm0Ajz9CSBxxRbxyvknDV wSOmdjRz2a6JLv/0D+PbJOPmdNjyFIUf2rDbaXSsdADic8Ridi9slmsr1qCvZtNHaN1U LcnAxlmmqBjbb+Ziwq8DfuvkWxMRtRma8s2G6rRgKYM95oRVreAH1pn0Vja2Hf+IEXov 5AxRcHUsOi2ELl945qLiv8ZYUo7LFK1JKzKtfcyBC2e0+PnLMITUPRZFtDCKKTJHVg4z Bga/3kbpesrCy3ugU4F5inA/5AOiyLj1Mkil5ZcBt3LXhJAjZSQmTcgr/D0mparTPFe2 GinA== X-Forwarded-Encrypted: i=1; AHgh+RrSM7tUAmeuP31S2RE+v9C26bxXHelarvOlTdbFONwx+CmMiYdI8v2+rTapQ0KQ3d6zx+b/XNWLCCmBSYk=@vger.kernel.org X-Gm-Message-State: AOJu0Ywd1UJeUwEsDtQm7LdKOpCCO8n0PUMdse5mLOSXtk2pvQLximQq 1X/pVNltp/owC/NwHs46f1yl+5E/QDaYL2hg8PCLlXztEUB/WP5uEL09 X-Gm-Gg: AR+sD10tZez4XhZp5m3BJvSTfMFyJqQi5dDMSJWJIuLZImidNoTymaHbRpTR68tSQG4 L7HAQTZUJS7z8eiioaekfROuaVFgT5wRU3hxip6c6Q68pnybyq8qOCsmLr/FKS2aJEChj9mRbrf F2Vp9sbai2MjgwuC0mIbYOCbMZJ4ncixpOQM/3I/ffnyZ9igoCX0vparqTi86AQTCcJx2L/CmkE F7+FZRpaMDXeUY1E8cqNNYp+SBUpTF18Jj1Z/9xtpsjQvnSvAiiKxIc0C4gPP692lNx0AlbJ+ee su9zP59SHJ7a4f45c55WGZUn8XL7XTi+IKSdqX64vMGXZa808gJe6i5xFFA+VMzh9oZW0KsHRlb 1gXWA2y1frZVrrjlBJd1rx1ORLY5pCb+dK4F/HL2aC8c4PyNY3nj7p5TWMuQ9sJmk9KrcvogtR+ yklGrUiVxKaOUpzByTaHUMxWuo2bhAY6g5JNKes0JbxWRCKFSQHdgUr8TkIcpOdl8UsBD3lZuhX jukOsmTtUYLxRY8yeazEi1kblDRHHh3aYS1DozHNTcxDWYoBPp4QZ/1iojMjpdFy1bm4Zj6EAPV mop6b+KUDkPGmirDp1LAcmJp9FWEDKo= X-Received: by 2002:a5d:5c82:0:b0:481:3db3:8eb with SMTP id ffacd0b85a97d-4813db3093fmr3525985f8f.1.1786277700954; Sun, 09 Aug 2026 05:15:00 -0700 (PDT) Received: from L-022584.energy.envision.com (dynamic-077-012-133-135.77.12.pool.telefonica.de. [77.12.133.135]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-480021e7b3fsm25158434f8f.20.2026.08.09.05.14.59 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 09 Aug 2026 05:15:00 -0700 (PDT) From: Xin Xie To: netdev@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org Cc: davem@davemloft.net, edumazet@google.com, kuba@kernel.org, pabeni@redhat.com, horms@kernel.org, andrew+netdev@lunn.ch, shuah@kernel.org, kees@kernel.org, petr.wozniak@gmail.com, qingfang.deng@linux.dev, fmaurer@redhat.com, luka.gejak@linux.dev, bigeasy@linutronix.de, xiaoliang.yang_1@nxp.com, skhawaja@google.com, liuhangbin@gmail.com, stable@vger.kernel.org, sdf.kernel@gmail.com, Xin Xie Subject: [PATCH 3/4] net: hsr: unfold GSO super-packets at the forward entry Date: Sun, 9 Aug 2026 14:14:53 +0200 Message-ID: <20260809121455.1745-4-xiexinet@gmail.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260809121455.1745-1-xiexinet@gmail.com> References: <20260809121455.1745-1-xiexinet@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit HSR/PRP require per-wire-frame tags and sequence numbers; treating a GSO skb as one frame breaks those semantics. Classify GSO skbs at the forward entry by effective protocol rather than ingress port. Segment plain aggregates and process each segment normally, preserving local delivery and forwarding. Drop ETH_P_HSR and ETH_P_PRP aggregates (per-frame metadata cannot be rebuilt), classification failures (unreadable header, stacked or S-tag tagging), and aggregates with unreadable net_iov (device-memory) fragments: their payload is not host-readable, and segmentation would leave the segment payload uninitialized, silently dropped at transmit or exposed where netmem transmit is enabled. In-tree software GRO does not merge PRP RCT frames (its IPv4/IPv6 length checks reject trailing bytes); fixed-on GRO_HW output is outside this guarantee. Also remove the GSO_MASK member types from the HSR master's hw_features: local traffic is segmented by the core before the forward path, so the master funnel branch sees single frames, and TSO and the other GSO_MASK offloads can no longer be enabled on the master; generic-segmentation-offload stays changeable and is cleared at runtime. This patch depends on patch 2 ("net: hsr: shrink seqnr_lock to sequence counter updates") and the sparse-bitmap duplicate discard introduced by commit aae9d6b616b5 ("hsr: Implement more robust duplicate discard for HSR"); older trees require an adapted backport. Fixes: f421436a591d ("net/hsr: Add support for the High-availability Seamless Redundancy protocol (HSRv0)") Cc: # aae9d6b616b5: hsr: Implement more robust duplicate discard for HSR Signed-off-by: Xin Xie --- net/hsr/hsr_device.c | 2 +- net/hsr/hsr_forward.c | 106 +++++++++++++++++++++++++++++++++++++++++- 2 files changed, 106 insertions(+), 2 deletions(-) diff --git a/net/hsr/hsr_device.c b/net/hsr/hsr_device.c index 3fd1762d8916..248cbb142e21 100644 --- a/net/hsr/hsr_device.c +++ b/net/hsr/hsr_device.c @@ -652,7 +652,7 @@ void hsr_dev_setup(struct net_device *dev) dev->needs_free_netdev = true; dev->hw_features = NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_HIGHDMA | - NETIF_F_GSO_MASK | NETIF_F_HW_CSUM | + NETIF_F_HW_CSUM | NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_FILTER; diff --git a/net/hsr/hsr_forward.c b/net/hsr/hsr_forward.c index 8e4158a9b57c..ae49c2d74ace 100644 --- a/net/hsr/hsr_forward.c +++ b/net/hsr/hsr_forward.c @@ -12,6 +12,7 @@ #include #include #include +#include #include "hsr_main.h" #include "hsr_framereg.h" @@ -732,7 +733,7 @@ static int fill_frame_info(struct hsr_frame_info *frame, } /* Must be called holding rcu read lock (because of the port parameter) */ -void hsr_forward_skb(struct sk_buff *skb, struct hsr_port *port) +static void hsr_forward_skb_one(struct sk_buff *skb, struct hsr_port *port) { struct hsr_frame_info frame; @@ -761,3 +762,106 @@ void hsr_forward_skb(struct sk_buff *skb, struct hsr_port *port) port->dev->stats.tx_dropped++; kfree_skb(skb); } + +/* GSO fan-out funnel: unfold super-packets before per-frame processing so + * each wire frame gets its own HSR/PRP tag and sequence number. + */ +/* Effective frame protocol of a (possibly VLAN-tagged) skb, or 0 when + * it cannot be determined or the tagging exceeds what HSR supports. + * HSR supports one 802.1Q C-tag only: an accelerated tag must be a + * C-tag with a non-VLAN inner protocol; an in-band tag is unwrapped + * exactly once and a residual VLAN EtherType is rejected. Read-only; + * no state is kept beyond the immediate protocol value. + */ +static __be16 hsr_gso_effective_proto(const struct sk_buff *skb) +{ + struct ethhdr eh; + struct vlan_hdr vh; + const struct ethhdr *eth; + const struct vlan_hdr *vhdr; + __be16 proto; + + if (skb_vlan_tag_present(skb)) { + /* HSR supports one 802.1Q C-tag only. */ + if (skb->vlan_proto != htons(ETH_P_8021Q)) + return 0; + if (eth_type_vlan(skb->protocol)) + return 0; + return skb->protocol; + } + + eth = skb_header_pointer(skb, 0, sizeof(eh), &eh); + if (!eth) + return 0; + + proto = eth->h_proto; + if (!eth_type_vlan(proto)) + return proto; + if (proto != htons(ETH_P_8021Q)) + return 0; + + vhdr = skb_header_pointer(skb, ETH_HLEN, sizeof(vh), &vh); + if (!vhdr) + return 0; + + proto = vhdr->h_vlan_encapsulated_proto; + if (eth_type_vlan(proto)) + return 0; + + return proto; +} + +void hsr_forward_skb(struct sk_buff *skb, struct hsr_port *port) +{ + struct sk_buff *segs, *next; + __be16 proto; + + if (likely(!skb_is_gso(skb))) { + hsr_forward_skb_one(skb, port); + return; + } + + /* Conforming plain-protocol GSO super-packets carry trailer-free + * sender payload and are segmented here: each segment is delivered + * or forwarded as its own wire frame, on any ingress role. + * + * The gate is content-based, not port-based. An aggregate whose + * effective protocol is ETH_P_HSR or ETH_P_PRP cannot be safely + * segmented and is dropped, as is any skb whose header cannot be + * read, whose tagging exceeds the single 802.1Q C-tag HSR + * supports, or whose fragments are unreadable net_iov + * (device-memory) pages: software segmentation cannot read their + * payload, so each segment would inherit the unreadable flag and + * carry uninitialized data. With NETIF_F_HW_HSR_TAG_RM the lower + * has already stripped the tag, so such aggregates arrive plain + * and are segmented. + */ + proto = hsr_gso_effective_proto(skb); + if (!proto) + goto drop_gso; /* classification failure, fail-safe */ + if (proto == htons(ETH_P_HSR) || proto == htons(ETH_P_PRP)) + goto drop_gso; + if (!skb_frags_readable(skb)) + goto drop_gso; /* net_iov (device-memory) frags are not host-readable */ + + /* features = 0: request full software segmentation. tx_path is true + * only for locally generated traffic on the master; ingress from + * the interlink follows RX checksum semantics. + */ + segs = __skb_gso_segment(skb, 0, port->type == HSR_PT_MASTER); + if (IS_ERR(segs) || unlikely(!segs)) + goto drop_gso; + + consume_skb(skb); + while (segs) { + next = segs->next; + segs->next = NULL; + hsr_forward_skb_one(segs, port); + segs = next; + } + return; + +drop_gso: + port->dev->stats.tx_dropped++; + kfree_skb(skb); +} -- 2.43.0