From: Kuniyuki Iwashima <kuniyu@google.com>
To: Petr Machata <petrm@nvidia.com>
Cc: "David S. Miller" <davem@davemloft.net>,
Eric Dumazet <edumazet@kernel.org>,
Jakub Kicinski <kuba@kernel.org>,
Paolo Abeni <pabeni@redhat.com>, Simon Horman <horms@kernel.org>,
netdev@vger.kernel.org, Ido Schimmel <idosch@nvidia.com>,
Andy Roulin <aroulin@nvidia.com>,
mlxsw@nvidia.com
Subject: Re: [PATCH net-next] net: neighbour: Avoid sending RTM_NEWNEIGH for a dead neighbor
Date: Thu, 5 Nov 2026 20:28:31 +0000 [thread overview]
Message-ID: <auzmIrtt_gMVjWhs@google.com> (raw)
In-Reply-To: <217109d64f0cdcba1db9569ee6ff7304754c47a4.1793793623.git.petrm@nvidia.com>
On Wed, 04 Nov 2026 14:56:56 +0100, Petr Machata wrote:
> During the processing of neighbor timer, in neigh_timer_handler(),
> when the number of probes for an unresolved neighbor is exceeded, a
> non-ext_validated neighbor is marked as failed. To send the ICMP /
> ICMPv6 destination unreachable diagnostic, neigh_invalidate() unlocks,
> and gives opportunity for a concurrent update to mark the neighbor as
> dead and send an RTM_DELNEIGH notification. After the lock is
> regained, neigh_timer_handler() proceeds to send its own RTM_NEWNEIGH
> notification, this time on a dead neighbor.
>
> Sending an RTM_NEWNEIGH after the corresponding RTM_DELNEIGH has the
> obvious semantics of recreating the neighbor, which is not what we want to
> convey here.
>
> Userspace can in theory recognize these faulty RTM_NEWNEIGH reports by
> the state, which will be NUD_NONE, but there is no reason why it
> should.
>
> The following diagram, which illustrates the issue, comes from Andy
> Roulin:
>
> timer handler (softirq) neigh_flush_dev() (linkwatch)
> write_lock(n->lock)
> nud_state = NUD_FAILED
> neigh_invalidate():
> write_unlock(n->lock)
> error_report()
> write_lock(n->lock)
> unlink, n->dead = 1
> refcnt != 1 -> nud_state = NUD_NONE
> write_unlock(n->lock)
> RTM_DELNEIGH
> write_lock(n->lock)
> write_unlock(n->lock)
> RTM_NEWNEIGH: state 0, no lladdr, ndm_refcnt 0 <- stale
> neigh_release() -> neigh_destroy()
>
> Fix the problem by refusing to send any notification other than
> RTM_DELNEIGH when the neighbor is dead.
>
> The issue comes from a user report and was obseved in the wild. It was
> reproduced on a vanilla kernel by extending the race window by inserting an
> mdelay for neighbors on a device with a hardcoded name.
>
> It is tricky to track down where the issue was actually introduced, and
> practically speaking, it may have been present "always". At least as far
> back as 5.10, which is currently the oldest LTS-supported kernel release,
> the code still looks substantially the same: neighbor timer causes neighbor
> invalidation, which unlocks to send ICMP, which a flush can then race. Even
> 2.6 has elements that look like they could combine into the same race. I am
> therefore not citing any particular Fixes tag.
>
> Assisted-by: LLM
> Co-developed-by: Andy Roulin <aroulin@nvidia.com>
> Reviewed-by: Ido Schimmel <idosch@nvidia.com>
> Signed-off-by: Andy Roulin <aroulin@nvidia.com>
> Signed-off-by: Petr Machata <petrm@nvidia.com>
> ---
> net/core/neighbour.c | 7 +++++++
> 1 file changed, 7 insertions(+)
>
> diff --git a/net/core/neighbour.c b/net/core/neighbour.c
> index d6e9c7c59a89..6fa490f7652a 100644
> --- a/net/core/neighbour.c
> +++ b/net/core/neighbour.c
> @@ -3593,6 +3593,13 @@ static void __neigh_notify(struct neighbour *n, int type, int flags,
> int err = -ENOBUFS;
> struct net *net;
>
> + /* An attempt to send anything but RTM_DELNEIGH on a dead neighbor
> + * indicates that the neighbor was marked dead while another update
> + * gave the lock up for a bit. Do not send such notifications.
> + */
I'd remove the comment, it's apparent from ->dead that there
was a race and the rest is just repeating the condition bleow.
Otherwise looks good.
Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com>
> + if (n->dead && type != RTM_DELNEIGH)
> + return;
> +
> rcu_read_lock();
> net = dev_net_rcu(n->dev);
> skb = nlmsg_new(neigh_nlmsg_size(), GFP_ATOMIC);
> --
> 2.56.0
>
next prev parent reply other threads:[~2026-11-05 20:28 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-04 13:56 [PATCH net-next] net: neighbour: Avoid sending RTM_NEWNEIGH for a dead neighbor Petr Machata
2026-11-05 20:28 ` Kuniyuki Iwashima [this message]
2026-11-06 15:39 ` Petr Machata
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=auzmIrtt_gMVjWhs@google.com \
--to=kuniyu@google.com \
--cc=aroulin@nvidia.com \
--cc=davem@davemloft.net \
--cc=edumazet@kernel.org \
--cc=horms@kernel.org \
--cc=idosch@nvidia.com \
--cc=kuba@kernel.org \
--cc=mlxsw@nvidia.com \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=petrm@nvidia.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox