summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Dumazet <edumazet@google.com>2026-05-25 11:35:42 +0300
committerJakub Kicinski <kuba@kernel.org>2026-05-27 05:20:15 +0300
commitd628604f7ea75a4dfe7ee3792f3c79c29ca81c04 (patch)
tree0e34a03ee3cb6d6f4dea10bb11c8ce1343d4d121
parent6768c7c3d70f0d6f9cb6fad2b33357ec7379d952 (diff)
downloadlinux-d628604f7ea75a4dfe7ee3792f3c79c29ca81c04.tar.xz
rtnetlink: add RTEXT_FILTER_NAME_ONLY support to rtnl_dump_ifinfo()
When user requests RTEXT_FILTER_NAME_ONLY flag, we limit the dump parts to: - struct nlmsghdr - IFLA_IFNAME - IFLA_PROP_LIST (alternate names) - This saves space in the dump, pushing more devices per system call. - This can be done without acquiring RTNL. I still have a medium term goal to avoid RTNL in rtnl_dump_ifinfo() regardless of RTEXT_FILTER_NAME_ONLY being used. Signed-off-by: Eric Dumazet <edumazet@google.com> Link: https://patch.msgid.link/20260525083542.1565964-6-edumazet@google.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
-rw-r--r--net/core/rtnetlink.c19
1 files changed, 15 insertions, 4 deletions
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index 0a59036d5f93..652dd008955a 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -2499,6 +2499,7 @@ static int rtnl_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb)
int ops_srcu_index;
int master_idx = 0;
int netnsid = -1;
+ bool need_rtnl;
int err, i;
err = rtnl_valid_dump_ifinfo_req(nlh, cb->strict_check, tb, extack);
@@ -2548,6 +2549,12 @@ static int rtnl_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb)
walk_entries:
err = 0;
+ need_rtnl = !(ext_filter_mask & RTEXT_FILTER_NAME_ONLY);
+ if (need_rtnl)
+ rtnl_lock();
+ else
+ rcu_read_lock();
+
for_each_netdev_dump(tgt_net, dev, ctx->ifindex) {
if (link_dump_filtered(dev, master_idx, kind_ops))
continue;
@@ -2559,11 +2566,13 @@ walk_entries:
if (err < 0)
break;
}
-
-
- cb->seq = tgt_net->dev_base_seq;
+ cb->seq = READ_ONCE(tgt_net->dev_base_seq);
nl_dump_check_consistent(cb, nlmsg_hdr(skb));
+ if (need_rtnl)
+ rtnl_unlock();
+ else
+ rcu_read_unlock();
out:
if (kind_ops)
@@ -7159,7 +7168,9 @@ static const struct rtnl_msg_handler rtnetlink_rtnl_msg_handlers[] __initconst =
.flags = RTNL_FLAG_DOIT_PERNET_WIP},
{.msgtype = RTM_GETLINK, .doit = rtnl_getlink,
.dumpit = rtnl_dump_ifinfo,
- .flags = RTNL_FLAG_DUMP_SPLIT_NLM_DONE | RTNL_FLAG_DOIT_UNLOCKED},
+ .flags = RTNL_FLAG_DUMP_SPLIT_NLM_DONE |
+ RTNL_FLAG_DOIT_UNLOCKED |
+ RTNL_FLAG_DUMP_UNLOCKED},
{.msgtype = RTM_SETLINK, .doit = rtnl_setlink,
.flags = RTNL_FLAG_DOIT_PERNET_WIP},
{.msgtype = RTM_GETADDR, .dumpit = rtnl_dump_all},