rtnetlink: use xarray iterator to implement rtnl_dump_ifinfo()
Adopt net->dev_by_index as I did in commit 0e0939c0ad
("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/20240209142441.6c56435b@kernel.org/
Link: https://lore.kernel.org/all/ZckR-XOsULLI9EHc@shredder/
Signed-off-by: Eric Dumazet <edumazet@google.com>
Reviewed-by: Ido Schimmel <idosch@nvidia.com>
Link: https://lore.kernel.org/r/20240211214404.1882191-3-edumazet@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
f383ced24d
commit
3e41af9076
1 changed files with 21 additions and 39 deletions
|
@ -2188,25 +2188,22 @@ static int rtnl_valid_dump_ifinfo_req(const struct nlmsghdr *nlh,
|
||||||
|
|
||||||
static int rtnl_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb)
|
static int rtnl_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb)
|
||||||
{
|
{
|
||||||
|
const struct rtnl_link_ops *kind_ops = NULL;
|
||||||
struct netlink_ext_ack *extack = cb->extack;
|
struct netlink_ext_ack *extack = cb->extack;
|
||||||
const struct nlmsghdr *nlh = cb->nlh;
|
const struct nlmsghdr *nlh = cb->nlh;
|
||||||
struct net *net = sock_net(skb->sk);
|
struct net *net = sock_net(skb->sk);
|
||||||
struct net *tgt_net = net;
|
|
||||||
int h, s_h;
|
|
||||||
int idx = 0, s_idx;
|
|
||||||
struct net_device *dev;
|
|
||||||
struct hlist_head *head;
|
|
||||||
struct nlattr *tb[IFLA_MAX+1];
|
|
||||||
u32 ext_filter_mask = 0;
|
|
||||||
const struct rtnl_link_ops *kind_ops = NULL;
|
|
||||||
unsigned int flags = NLM_F_MULTI;
|
unsigned int flags = NLM_F_MULTI;
|
||||||
|
struct nlattr *tb[IFLA_MAX+1];
|
||||||
|
struct {
|
||||||
|
unsigned long ifindex;
|
||||||
|
} *ctx = (void *)cb->ctx;
|
||||||
|
struct net *tgt_net = net;
|
||||||
|
u32 ext_filter_mask = 0;
|
||||||
|
struct net_device *dev;
|
||||||
int master_idx = 0;
|
int master_idx = 0;
|
||||||
int netnsid = -1;
|
int netnsid = -1;
|
||||||
int err, i;
|
int err, i;
|
||||||
|
|
||||||
s_h = cb->args[0];
|
|
||||||
s_idx = cb->args[1];
|
|
||||||
|
|
||||||
err = rtnl_valid_dump_ifinfo_req(nlh, cb->strict_check, tb, extack);
|
err = rtnl_valid_dump_ifinfo_req(nlh, cb->strict_check, tb, extack);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
if (cb->strict_check)
|
if (cb->strict_check)
|
||||||
|
@ -2250,36 +2247,21 @@ static int rtnl_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb)
|
||||||
flags |= NLM_F_DUMP_FILTERED;
|
flags |= NLM_F_DUMP_FILTERED;
|
||||||
|
|
||||||
walk_entries:
|
walk_entries:
|
||||||
for (h = s_h; h < NETDEV_HASHENTRIES; h++, s_idx = 0) {
|
err = 0;
|
||||||
idx = 0;
|
for_each_netdev_dump(tgt_net, dev, ctx->ifindex) {
|
||||||
head = &tgt_net->dev_index_head[h];
|
if (link_dump_filtered(dev, master_idx, kind_ops))
|
||||||
hlist_for_each_entry(dev, head, index_hlist) {
|
continue;
|
||||||
if (link_dump_filtered(dev, master_idx, kind_ops))
|
err = rtnl_fill_ifinfo(skb, dev, net, RTM_NEWLINK,
|
||||||
goto cont;
|
NETLINK_CB(cb->skb).portid,
|
||||||
if (idx < s_idx)
|
nlh->nlmsg_seq, 0, flags,
|
||||||
goto cont;
|
ext_filter_mask, 0, NULL, 0,
|
||||||
err = rtnl_fill_ifinfo(skb, dev, net,
|
netnsid, GFP_KERNEL);
|
||||||
RTM_NEWLINK,
|
if (err < 0) {
|
||||||
NETLINK_CB(cb->skb).portid,
|
if (likely(skb->len))
|
||||||
nlh->nlmsg_seq, 0, flags,
|
err = skb->len;
|
||||||
ext_filter_mask, 0, NULL, 0,
|
break;
|
||||||
netnsid, GFP_KERNEL);
|
|
||||||
|
|
||||||
if (err < 0) {
|
|
||||||
if (likely(skb->len))
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
goto out_err;
|
|
||||||
}
|
|
||||||
cont:
|
|
||||||
idx++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
out:
|
|
||||||
err = skb->len;
|
|
||||||
out_err:
|
|
||||||
cb->args[1] = idx;
|
|
||||||
cb->args[0] = h;
|
|
||||||
cb->seq = tgt_net->dev_base_seq;
|
cb->seq = tgt_net->dev_base_seq;
|
||||||
nl_dump_check_consistent(cb, nlmsg_hdr(skb));
|
nl_dump_check_consistent(cb, nlmsg_hdr(skb));
|
||||||
if (netnsid >= 0)
|
if (netnsid >= 0)
|
||||||
|
|
Loading…
Add table
Reference in a new issue