Skip to content

Commit 3e41af9

Browse files
edumazetkuba-moo
authored andcommitted
rtnetlink: use xarray iterator to implement rtnl_dump_ifinfo()
Adopt net->dev_by_index as I did in commit 0e0939c ("net-procfs: use xarray iterator to implement /proc/net/dev") This makes sure an existing device is always visible in the dump, regardless of concurrent insertions/deletions. v2: added suggestions from Jakub Kicinski and Ido Schimmel, thanks for the help ! Link: https://lore.kernel.org/all/[email protected]/ Link: https://lore.kernel.org/all/ZckR-XOsULLI9EHc@shredder/ Signed-off-by: Eric Dumazet <[email protected]> Reviewed-by: Ido Schimmel <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
1 parent f383ced commit 3e41af9

File tree

1 file changed

+20
-38
lines changed

1 file changed

+20
-38
lines changed

net/core/rtnetlink.c

Lines changed: 20 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -2188,25 +2188,22 @@ static int rtnl_valid_dump_ifinfo_req(const struct nlmsghdr *nlh,
21882188

21892189
static int rtnl_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb)
21902190
{
2191+
const struct rtnl_link_ops *kind_ops = NULL;
21912192
struct netlink_ext_ack *extack = cb->extack;
21922193
const struct nlmsghdr *nlh = cb->nlh;
21932194
struct net *net = sock_net(skb->sk);
2194-
struct net *tgt_net = net;
2195-
int h, s_h;
2196-
int idx = 0, s_idx;
2197-
struct net_device *dev;
2198-
struct hlist_head *head;
2195+
unsigned int flags = NLM_F_MULTI;
21992196
struct nlattr *tb[IFLA_MAX+1];
2197+
struct {
2198+
unsigned long ifindex;
2199+
} *ctx = (void *)cb->ctx;
2200+
struct net *tgt_net = net;
22002201
u32 ext_filter_mask = 0;
2201-
const struct rtnl_link_ops *kind_ops = NULL;
2202-
unsigned int flags = NLM_F_MULTI;
2202+
struct net_device *dev;
22032203
int master_idx = 0;
22042204
int netnsid = -1;
22052205
int err, i;
22062206

2207-
s_h = cb->args[0];
2208-
s_idx = cb->args[1];
2209-
22102207
err = rtnl_valid_dump_ifinfo_req(nlh, cb->strict_check, tb, extack);
22112208
if (err < 0) {
22122209
if (cb->strict_check)
@@ -2250,36 +2247,21 @@ static int rtnl_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb)
22502247
flags |= NLM_F_DUMP_FILTERED;
22512248

22522249
walk_entries:
2253-
for (h = s_h; h < NETDEV_HASHENTRIES; h++, s_idx = 0) {
2254-
idx = 0;
2255-
head = &tgt_net->dev_index_head[h];
2256-
hlist_for_each_entry(dev, head, index_hlist) {
2257-
if (link_dump_filtered(dev, master_idx, kind_ops))
2258-
goto cont;
2259-
if (idx < s_idx)
2260-
goto cont;
2261-
err = rtnl_fill_ifinfo(skb, dev, net,
2262-
RTM_NEWLINK,
2263-
NETLINK_CB(cb->skb).portid,
2264-
nlh->nlmsg_seq, 0, flags,
2265-
ext_filter_mask, 0, NULL, 0,
2266-
netnsid, GFP_KERNEL);
2267-
2268-
if (err < 0) {
2269-
if (likely(skb->len))
2270-
goto out;
2271-
2272-
goto out_err;
2273-
}
2274-
cont:
2275-
idx++;
2250+
err = 0;
2251+
for_each_netdev_dump(tgt_net, dev, ctx->ifindex) {
2252+
if (link_dump_filtered(dev, master_idx, kind_ops))
2253+
continue;
2254+
err = rtnl_fill_ifinfo(skb, dev, net, RTM_NEWLINK,
2255+
NETLINK_CB(cb->skb).portid,
2256+
nlh->nlmsg_seq, 0, flags,
2257+
ext_filter_mask, 0, NULL, 0,
2258+
netnsid, GFP_KERNEL);
2259+
if (err < 0) {
2260+
if (likely(skb->len))
2261+
err = skb->len;
2262+
break;
22762263
}
22772264
}
2278-
out:
2279-
err = skb->len;
2280-
out_err:
2281-
cb->args[1] = idx;
2282-
cb->args[0] = h;
22832265
cb->seq = tgt_net->dev_base_seq;
22842266
nl_dump_check_consistent(cb, nlmsg_hdr(skb));
22852267
if (netnsid >= 0)

0 commit comments

Comments
 (0)