]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
rtnetlink: add RTEXT_FILTER_NAME_ONLY support to rtnl_dump_ifinfo()
authorEric Dumazet <edumazet@google.com>
Mon, 25 May 2026 08:35:42 +0000 (08:35 +0000)
committerJakub Kicinski <kuba@kernel.org>
Wed, 27 May 2026 02:20:15 +0000 (19:20 -0700)
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>
net/core/rtnetlink.c

index 0a59036d5f933c5b2f123a47e059036d2a555911..652dd008955a90691403de9a54d8693d64ea7799 100644 (file)
@@ -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},