Re: [PATCH v1 net 1/4] neighbour: Add missing RCU annotation for neightbl_dump_info().
From: Ido Schimmel <idosch@nvidia.com>
Date: 2026-09-08 10:05:37
Subsystem:
networking [general], the rest · Maintainers:
"David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, Linus Torvalds
On Mon, Sep 07, 2026 at 09:57:52PM +0000, Kuniyuki Iwashima wrote:
quoted hunk ↗ jump to hunk
neightbl_dump_info() fetches the first non-default neigh_parms with list_next_entry(&tbl->parms, ...) and iterates through the list with list_for_each_entry_from_rcu(). However, list_next_entry() does not use RCU helper. Let's fetch the default parms with list_first_entry() and use list_for_each_entry_continue_rcu() for iteration. Note that the first entry is always tbl->parms, which never goes away, so list_first_entry(&tbl->parms_list, ...) is safe. Fixes: 4ae34be50064 ("neighbour: Convert RTM_GETNEIGHTBL to RCU.") Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com> --- net/core/neighbour.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)diff --git a/net/core/neighbour.c b/net/core/neighbour.c index 1349c0eedb64..4b17c2a15594 100644 --- a/net/core/neighbour.c +++ b/net/core/neighbour.c@@ -2611,8 +2611,9 @@ static int neightbl_dump_info(struct sk_buff *skb, struct netlink_callback *cb) break; nidx = 0; - p = list_next_entry(&tbl->parms, list); - list_for_each_entry_from_rcu(p, &tbl->parms_list, list) { + + p = list_first_entry(&tbl->parms_list, struct neigh_parms, list); + list_for_each_entry_continue_rcu(p, &tbl->parms_list, list) { if (!net_eq(neigh_parms_net(p), net)) continue;
I find this more readable:
diff --git a/net/core/neighbour.c b/net/core/neighbour.c
index 1349c0eedb64..3af539f5fd4b 100644
--- a/net/core/neighbour.c
+++ b/net/core/neighbour.c@@ -2611,11 +2611,13 @@ static int neightbl_dump_info(struct sk_buff *skb, struct netlink_callback *cb) break; nidx = 0; - p = list_next_entry(&tbl->parms, list); - list_for_each_entry_from_rcu(p, &tbl->parms_list, list) { + list_for_each_entry_rcu(p, &tbl->parms_list, list) { if (!net_eq(neigh_parms_net(p), net)) continue; + if (!p->dev) + continue; + if (nidx < neigh_skip) goto next;
Then patch #3 becomes:
diff --git a/net/core/neighbour.c b/net/core/neighbour.c
index 3af539f5fd4b..b4d8e5b6832c 100644
--- a/net/core/neighbour.c
+++ b/net/core/neighbour.c@@ -2615,7 +2615,7 @@ static int neightbl_dump_info(struct sk_buff *skb, struct netlink_callback *cb) if (!net_eq(neigh_parms_net(p), net)) continue; - if (!p->dev) + if (!p->dev || p->dev == blackhole_netdev) continue; if (nidx < neigh_skip)