* [PATCH net] net: neighbour: Serialize proxy queue admission
@ 2026-09-26 17:37 Chengfeng Ye
2026-09-26 19:45 ` Kuniyuki Iwashima
0 siblings, 1 reply; 2+ messages in thread
From: Chengfeng Ye @ 2026-09-26 17:37 UTC (permalink / raw)
To: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Simon Horman, Mark Brown, Kuniyuki Iwashima, Florian Westphal
Cc: netdev, linux-kernel, Chengfeng Ye
pneigh_enqueue() checks p->qlen before taking proxy_queue.lock, although
both enqueueing and the timer and purge paths update it under that lock.
The unlocked read races with those updates and allows concurrent proxy
ARP or NDP requests to bypass the queue's admission limit.
For example, CPU0 and CPU1 can both observe p->qlen == PROXY_QLEN before
either takes the lock. CPU0 then locks and enqueues, raising the count to
PROXY_QLEN + 1. CPU1 subsequently locks and enqueues using its stale
admission decision, raising the count to PROXY_QLEN + 2. The extra queued
packets consume memory until the timer or purge path removes them.
With a temporary 20 ms delay before locking and a queue-length assertion,
the kernel reported qlen=6 with PROXY_QLEN=4:
WARNING: net/core/neighbour.c:1757 at pneigh_enqueue+0x4ee/0x650
Call Trace:
<IRQ>
arp_process+0x1846/0x2060
__netif_receive_skb_core.constprop.0+0x1524/0x2bd0
__netif_receive_skb_one_core+0xa9/0x1b0
process_backlog+0x1e5/0x5e0
__napi_poll+0x9c/0x540
net_rx_action+0x988/0xfb0
handle_softirqs+0x18d/0x5b0
do_softirq+0x3b/0x60
</IRQ>
Move the existing lock acquisition before the admission check so that the
check and increment are serialized with all queue-length updates. Unlock
before freeing a rejected packet. Keep the existing > comparison so that
serial admission behavior is unchanged.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Signed-off-by: Chengfeng Ye <nicoyip.dev@gmail.com>
---
net/core/neighbour.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/net/core/neighbour.c b/net/core/neighbour.c
index 7448320f7ad5..e35ce26b4f8a 100644
--- a/net/core/neighbour.c
+++ b/net/core/neighbour.c
@@ -1721,7 +1721,9 @@ void pneigh_enqueue(struct neigh_table *tbl, struct neigh_parms *p,
{
unsigned long sched_next = neigh_proxy_delay(p);
+ spin_lock(&tbl->proxy_queue.lock);
if (p->qlen > NEIGH_VAR(p, PROXY_QLEN)) {
+ spin_unlock(&tbl->proxy_queue.lock);
kfree_skb(skb);
return;
}
@@ -1729,7 +1731,6 @@ void pneigh_enqueue(struct neigh_table *tbl, struct neigh_parms *p,
NEIGH_CB(skb)->sched_next = sched_next;
NEIGH_CB(skb)->flags |= LOCALLY_ENQUEUED;
- spin_lock(&tbl->proxy_queue.lock);
if (timer_delete(&tbl->proxy_timer)) {
if (time_before(tbl->proxy_timer.expires, sched_next))
sched_next = tbl->proxy_timer.expires;
--
2.43.0
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: [PATCH net] net: neighbour: Serialize proxy queue admission
2026-09-26 17:37 [PATCH net] net: neighbour: Serialize proxy queue admission Chengfeng Ye
@ 2026-09-26 19:45 ` Kuniyuki Iwashima
0 siblings, 0 replies; 2+ messages in thread
From: Kuniyuki Iwashima @ 2026-09-26 19:45 UTC (permalink / raw)
To: Chengfeng Ye
Cc: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Simon Horman, Mark Brown, Florian Westphal, netdev, linux-kernel
On Sat, Sep 26, 2026 at 10:37 AM Chengfeng Ye <nicoyip.dev@gmail.com> wrote:
>
> pneigh_enqueue() checks p->qlen before taking proxy_queue.lock, although
> both enqueueing and the timer and purge paths update it under that lock.
> The unlocked read races with those updates and allows concurrent proxy
> ARP or NDP requests to bypass the queue's admission limit.
>
> For example, CPU0 and CPU1 can both observe p->qlen == PROXY_QLEN before
> either takes the lock. CPU0 then locks and enqueues, raising the count to
> PROXY_QLEN + 1. CPU1 subsequently locks and enqueues using its stale
> admission decision, raising the count to PROXY_QLEN + 2. The extra queued
> packets consume memory until the timer or purge path removes them.
>
> With a temporary 20 ms delay before locking and a queue-length assertion,
> the kernel reported qlen=6 with PROXY_QLEN=4:
>
> WARNING: net/core/neighbour.c:1757 at pneigh_enqueue+0x4ee/0x650
Please do not include a local-only stack trace in the commit message.
A transient overshoot is not a problem.
You can already set PROXY_QLEN below the actual qlen anyway.
> Call Trace:
> <IRQ>
> arp_process+0x1846/0x2060
> __netif_receive_skb_core.constprop.0+0x1524/0x2bd0
> __netif_receive_skb_one_core+0xa9/0x1b0
> process_backlog+0x1e5/0x5e0
> __napi_poll+0x9c/0x540
> net_rx_action+0x988/0xfb0
> handle_softirqs+0x18d/0x5b0
> do_softirq+0x3b/0x60
> </IRQ>
>
> Move the existing lock acquisition before the admission check so that the
> check and increment are serialized with all queue-length updates. Unlock
> before freeing a rejected packet. Keep the existing > comparison so that
> serial admission behavior is unchanged.
>
> Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
> Signed-off-by: Chengfeng Ye <nicoyip.dev@gmail.com>
> ---
> net/core/neighbour.c | 3 ++-
> 1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/net/core/neighbour.c b/net/core/neighbour.c
> index 7448320f7ad5..e35ce26b4f8a 100644
> --- a/net/core/neighbour.c
> +++ b/net/core/neighbour.c
> @@ -1721,7 +1721,9 @@ void pneigh_enqueue(struct neigh_table *tbl, struct neigh_parms *p,
> {
> unsigned long sched_next = neigh_proxy_delay(p);
>
> + spin_lock(&tbl->proxy_queue.lock);
> if (p->qlen > NEIGH_VAR(p, PROXY_QLEN)) {
> + spin_unlock(&tbl->proxy_queue.lock);
> kfree_skb(skb);
> return;
> }
> @@ -1729,7 +1731,6 @@ void pneigh_enqueue(struct neigh_table *tbl, struct neigh_parms *p,
> NEIGH_CB(skb)->sched_next = sched_next;
> NEIGH_CB(skb)->flags |= LOCALLY_ENQUEUED;
>
> - spin_lock(&tbl->proxy_queue.lock);
> if (timer_delete(&tbl->proxy_timer)) {
> if (time_before(tbl->proxy_timer.expires, sched_next))
> sched_next = tbl->proxy_timer.expires;
> --
> 2.43.0
>
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2026-09-26 19:45 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-09-26 17:37 [PATCH net] net: neighbour: Serialize proxy queue admission Chengfeng Ye
2026-09-26 19:45 ` Kuniyuki Iwashima
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®