Commit 2519a6fe7a8b for kernel

commit 2519a6fe7a8bba57a961eb804e43e7df35ac40fe
Author: Eric Dumazet <edumazet@kernel.org>
Date:   Wed Oct 28 13:26:59 2026 +0100

    net: add eth_type_trans_careful()

    eth_type_trans() assumes ETH_HLEN bytes are present in skb->head.
    NIC drivers always provide this, and they should keep using the fast
    version.

    Devices looping skbs from their transmit path back to their receive
    path get skbs built by the stack instead. Their link-layer header
    might have been popped by tc actions (act_vlan pop_eth, act_ife decode)
    or OVS actions (pop_eth + pop_mpls / pop_nsh), leaving fewer than
    ETH_HLEN bytes in the linear part. eth_type_trans() then hits
    the BUG() in __skb_pull().

    Add eth_type_trans_careful(), which first pulls the Ethernet header,
    and returns a drop reason on failure, so that the few devices exposed
    to this can drop such packets.

    Signed-off-by: Eric Dumazet <edumazet@kernel.org>
    Reviewed-by: Aaron Conole <aconole@redhat.com>
    Reviewed-by: Willem de Bruijn <willemb@google.com>
    Reviewed-by: Jamal Hadi Salim <jhs@mojatatu.com>
    Tested-by: Jamal Hadi Salim <jhs@mojatatu.com>
    Acked-by: Alexei Starovoitov <ast@kernel.org>
    Link: https://patch.msgid.link/20261028122703.2093730-2-edumazet@kernel.org
    Signed-off-by: Jakub Kicinski <kuba@kernel.org>

diff --git a/include/linux/etherdevice.h b/include/linux/etherdevice.h
index df8f88f63a70..1f833ebd71ed 100644
--- a/include/linux/etherdevice.h
+++ b/include/linux/etherdevice.h
@@ -38,6 +38,34 @@ int fwnode_get_mac_address(struct fwnode_handle *fwnode, char *addr);

 u32 eth_get_headlen(const struct net_device *dev, const void *data, u32 len);
 __be16 eth_type_trans(struct sk_buff *skb, struct net_device *dev);
+
+/**
+ * eth_type_trans_careful - eth_type_trans() for skbs coming from the stack
+ * @skb: buffer, possibly with less than ETH_HLEN bytes in its linear area
+ * @dev: receiving network device
+ *
+ * eth_type_trans() expects ETH_HLEN bytes in skb->head, which NIC drivers
+ * provide. Devices looping skbs from their transmit path back to the
+ * receive path (loopback, OVS internal ports) get skbs built by the stack,
+ * whose link-layer header might have been popped by tc or OVS actions.
+ *
+ * Sets skb->protocol on success.
+ *
+ * Return: SKB_NOT_DROPPED_YET on success, or a drop reason. In the latter
+ * case, the caller must free @skb.
+ */
+static inline enum skb_drop_reason
+eth_type_trans_careful(struct sk_buff *skb, struct net_device *dev)
+{
+	enum skb_drop_reason reason = pskb_may_pull_reason(skb, ETH_HLEN);
+
+	if (unlikely(reason))
+		return reason;
+
+	skb->protocol = eth_type_trans(skb, dev);
+	return SKB_NOT_DROPPED_YET;
+}
+
 extern const struct header_ops eth_header_ops;

 int eth_header(struct sk_buff *skb, struct net_device *dev, unsigned short type,