]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
net: stmmac: Consider Tx VLAN offload tag length for maxSDU
authorRohan G Thomas <rohan.g.thomas@altera.com>
Tue, 28 Oct 2025 03:18:44 +0000 (11:18 +0800)
committerJakub Kicinski <kuba@kernel.org>
Thu, 30 Oct 2025 01:49:24 +0000 (18:49 -0700)
Queue maxSDU requirement of 802.1 Qbv standard requires mac to drop
packets that exceeds maxSDU length and maxSDU doesn't include
preamble, destination and source address, or FCS but includes
ethernet type and VLAN header.

On hardware with Tx VLAN offload enabled, VLAN header length is not
included in the skb->len, when Tx VLAN offload is requested. This
leads to incorrect length checks and allows transmission of
oversized packets. Add the VLAN_HLEN to the skb->len before checking
the Qbv maxSDU if Tx VLAN offload is requested for the packet.

Fixes: c5c3e1bfc9e0 ("net: stmmac: Offload queueMaxSDU from tc-taprio")
Signed-off-by: Rohan G Thomas <rohan.g.thomas@altera.com>
Reviewed-by: Matthew Gerlach <matthew.gerlach@altera.com>
Link: https://patch.msgid.link/20251028-qbv-fixes-v4-2-26481c7634e3@altera.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c

index 5b452469ad2cf9f3eba5b5d8eb1c19af86228310..7b90ecd3a55e600458b0c87d6125831626f4683d 100644 (file)
@@ -4500,6 +4500,7 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev)
        bool has_vlan, set_ic;
        int entry, first_tx;
        dma_addr_t des;
+       u32 sdu_len;
 
        tx_q = &priv->dma_conf.tx_queue[queue];
        txq_stats = &priv->xstats.txq_stats[queue];
@@ -4517,10 +4518,15 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev)
        }
 
        if (priv->est && priv->est->enable &&
-           priv->est->max_sdu[queue] &&
-           skb->len > priv->est->max_sdu[queue]){
-               priv->xstats.max_sdu_txq_drop[queue]++;
-               goto max_sdu_err;
+           priv->est->max_sdu[queue]) {
+               sdu_len = skb->len;
+               /* Add VLAN tag length if VLAN tag insertion offload is requested */
+               if (priv->dma_cap.vlins && skb_vlan_tag_present(skb))
+                       sdu_len += VLAN_HLEN;
+               if (sdu_len > priv->est->max_sdu[queue]) {
+                       priv->xstats.max_sdu_txq_drop[queue]++;
+                       goto max_sdu_err;
+               }
        }
 
        if (unlikely(stmmac_tx_avail(priv, queue) < nfrags + 1)) {