Thread (8 messages) 8 messages, 2 authors, 1d ago

Re: [PATCH v2 net] vlan: fix skb_under_panic and races when toggling HW VLAN offload

From: Eric Dumazet <edumazet@google.com>
Date: 2026-07-24 08:40:45
Subsystem: networking drivers, the rest · Maintainers: Andrew Lunn, "David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, Linus Torvalds

On Fri, Jul 24, 2026 at 10:13 AM xietangxin [off-list ref] wrote:

Hi Eric,

While testing this backport in our local environment, we hit a similar
skb_under_panic issue when layering macvlan on top of a VLAN device.

macvlan does't sync vlan's need_headroom, so skb head align to 16 bytes.
when skb arrive vlan, call vlan_header_ops -> vlan_dev_hard_header,
push VLAN_HLEN 4 + ETH_LEN 14 to skb, oops.

Call trace
==========
[  103.088286] skbuff: skb_under_panic: text:ffff800080d2159c len:114 put:14 head:ffff0000d2055800 data:ffff0000d20557fe tail:0x70 end:0x6c0 dev:macvlan
[  103.088344] ------------[ cut here ]------------
[  103.088346] kernel BUG at net/core/skbuff.c:214!
[  103.088350] Internal error: Oops - BUG: 00000000f2000800 [#1]  SMP
[  103.098003] CPU: 3 UID: 0 PID: 160 Comm: kworker/3:3 Kdump: loaded Not tainted 7.2.0-rc4+ #56 PREEMPTLAZY
[  103.099007] Hardware name: QEMU KVM Virtual Machine, BIOS 0.0.0 02/06/2015
[  103.099725] Workqueue: mld mld_ifc_work
[  103.100169] pstate: 60400005 (nZCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
[  103.100898] pc : skb_panic+0x58/0x68
[  103.101310] lr : skb_panic+0x58/0x68
[  103.101738] sp : ffff800083d1b950
[  103.109858] Call trace:
[  103.110161]  skb_panic+0x58/0x68 (P)
[  103.110578]  skb_push+0x58/0x60
[  103.110971]  eth_header+0x3c/0xe0
[  103.111359]  vlan_dev_hard_header+0x7c/0x1a8 [8021q]
[  103.111904]  macvlan_hard_header+0x38/0x60 [macvlan]
[  103.112455]  neigh_resolve_output.part.0+0xa8/0x168
[  103.113081]  neigh_resolve_output+0x4c/0x90
[  103.113639]  ip6_finish_output2+0x2c0/0x858
[  103.114182]  ip6_finish_output+0x23c/0x398
[  103.114741]  ip6_output+0x90/0x250
[  103.115211]  NF_HOOK.constprop.0+0x54/0x118
[  103.115699]  mld_sendpack+0x1cc/0x3d0
[  103.116202]  mld_send_cr+0x1cc/0x318
[  103.116696]  mld_ifc_work+0x38/0x128


Reproducer
==========
ip link add veth0 type veth peer name veth1
ip link set veth0 up
ip link set veth1 up

ip link add link veth0 name vlan_test type vlan id 10 reorder_hdr off
ip link set vlan_test up

# macvlan does't sync vlan's need_headroom,
ip link add link vlan_test name macvlan type macvlan
ip link set macvlan up

ethtool -K veth0 tx-vlan-hw-insert off

# skb_under_panic
ip -6 addr add fe80::1/64 dev macvlan
Thanks for testing and for providing a clean repro.

This definitely is a bug in macvlan :/, I am pretty sure it can be
stacked on top of devices that have a non zero needed_headroom.

Maybe the bug was hidden because skb->head was properly reallocated
for such lower devices incurring an expensive kmalloc()/kfree().

diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c
index c40fa331836bb2395267914807542ae5094e1a3c..0fb619413d94c89e472efed4a6a9f0dd7fb69940
100644
--- a/drivers/net/macvlan.c
+++ b/drivers/net/macvlan.c
@@ -950,6 +950,7 @@ static int macvlan_init(struct net_device *dev)
        dev->lltx               = true;
        netif_inherit_tso_max(dev, lowerdev);
        dev->hard_header_len    = lowerdev->hard_header_len;
+       dev->needed_headroom    = lowerdev->needed_headroom;
        macvlan_set_lockdep_class(dev);

        vlan->pcpu_stats = netdev_alloc_pcpu_stats(struct vlan_pcpu_stats);
@@ -1824,6 +1825,7 @@ static int macvlan_device_event(struct
notifier_block *unused,
        case NETDEV_FEAT_CHANGE:
                list_for_each_entry(vlan, &port->vlans, list) {
                        netif_inherit_tso_max(vlan->dev, dev);
+                       vlan->dev->needed_headroom = dev->needed_headroom;
                        netdev_update_features(vlan->dev);
                }
                break;
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help