diff options
| author | Eric Dumazet <edumazet@google.com> | 2026-05-25 11:35:42 +0300 |
|---|---|---|
| committer | Jakub Kicinski <kuba@kernel.org> | 2026-05-27 05:20:15 +0300 |
| commit | d628604f7ea75a4dfe7ee3792f3c79c29ca81c04 (patch) | |
| tree | 0e34a03ee3cb6d6f4dea10bb11c8ce1343d4d121 | |
| parent | 6768c7c3d70f0d6f9cb6fad2b33357ec7379d952 (diff) | |
| download | linux-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.c | 19 |
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}, |
