Commit 0feb396f authored by Eric Dumazet's avatar Eric Dumazet Committed by Jakub Kicinski

rtnetlink: use for_each_netdev_dump() in rtnl_stats_dump()

Switch rtnl_stats_dump() to use for_each_netdev_dump()
instead of net->dev_index_head[] hash table.

This makes the code much easier to read, and fixes
scalability issues.
Signed-off-by: default avatarEric Dumazet <edumazet@google.com>
Reviewed-by: default avatarDavid Ahern <dsahern@kernel.org>
Link: https://lore.kernel.org/r/20240502113748.1622637-3-edumazet@google.comSigned-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent 136c2a9a
...@@ -5961,19 +5961,17 @@ static int rtnl_stats_get(struct sk_buff *skb, struct nlmsghdr *nlh, ...@@ -5961,19 +5961,17 @@ static int rtnl_stats_get(struct sk_buff *skb, struct nlmsghdr *nlh,
static int rtnl_stats_dump(struct sk_buff *skb, struct netlink_callback *cb) static int rtnl_stats_dump(struct sk_buff *skb, struct netlink_callback *cb)
{ {
struct netlink_ext_ack *extack = cb->extack; struct netlink_ext_ack *extack = cb->extack;
int h, s_h, err, s_idx, s_idxattr, s_prividx;
struct rtnl_stats_dump_filters filters; struct rtnl_stats_dump_filters filters;
struct net *net = sock_net(skb->sk); struct net *net = sock_net(skb->sk);
unsigned int flags = NLM_F_MULTI; unsigned int flags = NLM_F_MULTI;
struct if_stats_msg *ifsm; struct if_stats_msg *ifsm;
struct hlist_head *head; struct {
unsigned long ifindex;
int idxattr;
int prividx;
} *ctx = (void *)cb->ctx;
struct net_device *dev; struct net_device *dev;
int idx = 0; int err;
s_h = cb->args[0];
s_idx = cb->args[1];
s_idxattr = cb->args[2];
s_prividx = cb->args[3];
cb->seq = net->dev_base_seq; cb->seq = net->dev_base_seq;
...@@ -5992,37 +5990,24 @@ static int rtnl_stats_dump(struct sk_buff *skb, struct netlink_callback *cb) ...@@ -5992,37 +5990,24 @@ static int rtnl_stats_dump(struct sk_buff *skb, struct netlink_callback *cb)
if (err) if (err)
return err; return err;
for (h = s_h; h < NETDEV_HASHENTRIES; h++, s_idx = 0) { for_each_netdev_dump(net, dev, ctx->ifindex) {
idx = 0;
head = &net->dev_index_head[h];
hlist_for_each_entry(dev, head, index_hlist) {
if (idx < s_idx)
goto cont;
err = rtnl_fill_statsinfo(skb, dev, RTM_NEWSTATS, err = rtnl_fill_statsinfo(skb, dev, RTM_NEWSTATS,
NETLINK_CB(cb->skb).portid, NETLINK_CB(cb->skb).portid,
cb->nlh->nlmsg_seq, 0, cb->nlh->nlmsg_seq, 0,
flags, &filters, flags, &filters,
&s_idxattr, &s_prividx, &ctx->idxattr, &ctx->prividx,
extack); extack);
/* If we ran out of room on the first message, /* If we ran out of room on the first message,
* we're in trouble * we're in trouble.
*/ */
WARN_ON((err == -EMSGSIZE) && (skb->len == 0)); WARN_ON((err == -EMSGSIZE) && (skb->len == 0));
if (err < 0) if (err < 0)
goto out; break;
s_prividx = 0; ctx->prividx = 0;
s_idxattr = 0; ctx->idxattr = 0;
nl_dump_check_consistent(cb, nlmsg_hdr(skb)); nl_dump_check_consistent(cb, nlmsg_hdr(skb));
cont:
idx++;
}
} }
out:
cb->args[3] = s_prividx;
cb->args[2] = s_idxattr;
cb->args[1] = idx;
cb->args[0] = h;
return err; return err;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment