On Tue, Oct 27, 2026 at 4:26 AM Eric Dumazet <[email protected]> wrote: > > 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, without an extra pskb_may_pull(). > > Devices looping skbs from their transmit path back to their receive > path get skbs built by the stack instead. tc actions (act_vlan pop_eth, > act_ife decode), BPF helpers (bpf_skb_change_head() before a redirect) > or OVS actions (pop_eth followed by pop_mpls/pop_nsh) can leave fewer > than ETH_HLEN bytes in the linear part, and eth_type_trans() then hits > the BUG() in __skb_pull(). > > Instead of fixing every producer, or adding a check to all > eth_type_trans() users, fix the few consumers exposed to this: > > - Patch 1 adds eth_type_trans_careful(), which pulls the Ethernet > header first and returns a drop reason on failure. > - Patch 2 uses it in loopback_xmit(). > - Patch 3 uses it in __dev_forward_skb2(), used by BPF redirects to > ingress and by veth, macvlan, ipvlan, netdevsim and l2tp_eth. > - Patch 4 uses it in OVS internal_dev_recv(), covering both the MPLS > (TEB) and NSH pop cases at once (only the MPLS case was tested). > - Patch 5 (from Jamal) fixes act_ife decode on egress, which was > consuming the inner Ethernet header. This is no longer a crash after > patch 2, but egress decode never delivered a correct frame. > > Other eth_type_trans() users already pull the header or never see > such skbs: > - vrf_process_v{4,6}_outbound() already pull ETH_HLEN + IP header > before vrf_local_xmit(). > - tun already uses pskb_may_pull_reason(skb, ETH_HLEN). > - XDP: bpf_xdp_adjust_head() and bpf_xdp_adjust_tail() keep at least > ETH_HLEN bytes in the linear part, and multi-buffer tail shrinking > only trims frags. > > Tested under virtme-ng with AF_PACKET reproducers. Without the series, > all four cases crash in eth_type_trans(): > - lo egress "action vlan pop_eth", eth/eth/8192 bytes frame > - lo egress "action ife decode pipe", IFE frame with 8192 bytes payload > - lo egress "action vlan pop_eth continue", then a BPF program doing > bpf_skb_change_head(skb, 1, 0) + bpf_redirect(veth1, BPF_F_INGRESS) > - OVS flow "pop_eth,pop_mpls(0x6558),0" to the internal port, > eth/mpls/eth/4096 bytes frame > With the series, no crash. An ICMP echo inside an IFE frame decoded > on lo egress is now received and answered. Normal traffic on lo, > veth (including 8000 byte pings) and vrf is unchanged. > > Link: https://lore.kernel.org/netdev/[email protected]/ > Link: > https://lore.kernel.org/netdev/[email protected]/ >
Looks interesting ;-> I dont think you are covering xdp/bpf holes but we can worry about that later. I will spend time later this morning looking closely and actually running it. Will keep you posted. cheers, jamal _______________________________________________ dev mailing list [email protected] https://mail.openvswitch.org/mailman/listinfo/ovs-dev
