Thread (12 messages) flat view 12 messages, 3 authors, 19h ago

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)
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help