neighbour: Drop read_lock_bh(&tbl->lock) in pneigh_dump_table().

Now pneigh_entry is guaranteed to be alive during the
RCU critical section even without holding tbl->lock.

Let's drop read_lock_bh(&tbl->lock) and use rcu_dereference()
to iterate tbl->phash_buckets[] in pneigh_dump_table()

Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com>
Link: https://patch.msgid.link/20250716221221.442239-11-kuniyu@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
Kuniyuki Iwashima 2025-07-16 22:08:15 +00:00 committed by Jakub Kicinski
parent ed6e380d2d
commit 32d5eaabf1

View File

@ -2808,14 +2808,12 @@ static int pneigh_dump_table(struct neigh_table *tbl, struct sk_buff *skb,
if (filter->dev_idx || filter->master_idx)
flags |= NLM_F_DUMP_FILTERED;
read_lock_bh(&tbl->lock);
for (h = s_h; h <= PNEIGH_HASHMASK; h++) {
if (h > s_h)
s_idx = 0;
for (n = rcu_dereference_protected(tbl->phash_buckets[h], 1), idx = 0;
for (n = rcu_dereference(tbl->phash_buckets[h]), idx = 0;
n;
n = rcu_dereference_protected(n->next, 1)) {
n = rcu_dereference(n->next)) {
if (idx < s_idx || pneigh_net(n) != net)
goto next;
if (neigh_ifindex_filtered(n->dev, filter->dev_idx) ||
@ -2824,16 +2822,13 @@ static int pneigh_dump_table(struct neigh_table *tbl, struct sk_buff *skb,
err = pneigh_fill_info(skb, n, NETLINK_CB(cb->skb).portid,
cb->nlh->nlmsg_seq,
RTM_NEWNEIGH, flags, tbl);
if (err < 0) {
read_unlock_bh(&tbl->lock);
if (err < 0)
goto out;
}
next:
idx++;
}
}
read_unlock_bh(&tbl->lock);
out:
cb->args[3] = h;
cb->args[4] = idx;