Commit 88c9d07b authored by Jakub Kicinski's avatar Jakub Kicinski

Merge branch 'net-use-net-dev_by_index-in-two-places'

Eric Dumazet says:

====================
net: use net->dev_by_index in two places

Bring "ip link" ordering to /proc/net/dev one (by ifindexes).

Do the same for /proc/net/vlan/config

v2: https://lore.kernel.org/all/20240209142441.6c56435b@kernel.org/
====================

Link: https://lore.kernel.org/r/20240211214404.1882191-1-edumazet@google.comSigned-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents bed90b06 3e41af90
...@@ -163,48 +163,34 @@ void vlan_proc_rem_dev(struct net_device *vlandev) ...@@ -163,48 +163,34 @@ void vlan_proc_rem_dev(struct net_device *vlandev)
* The following few functions build the content of /proc/net/vlan/config * The following few functions build the content of /proc/net/vlan/config
*/ */
/* start read of /proc/net/vlan/config */ static void *vlan_seq_from_index(struct seq_file *seq, loff_t *pos)
static void *vlan_seq_start(struct seq_file *seq, loff_t *pos)
__acquires(rcu)
{ {
unsigned long ifindex = *pos;
struct net_device *dev; struct net_device *dev;
struct net *net = seq_file_net(seq);
loff_t i = 1;
rcu_read_lock();
if (*pos == 0)
return SEQ_START_TOKEN;
for_each_netdev_rcu(net, dev) { for_each_netdev_dump(seq_file_net(seq), dev, ifindex) {
if (!is_vlan_dev(dev)) if (!is_vlan_dev(dev))
continue; continue;
*pos = dev->ifindex;
if (i++ == *pos) return dev;
return dev;
} }
return NULL;
}
static void *vlan_seq_start(struct seq_file *seq, loff_t *pos)
__acquires(rcu)
{
rcu_read_lock();
if (*pos == 0)
return SEQ_START_TOKEN;
return NULL; return vlan_seq_from_index(seq, pos);
} }
static void *vlan_seq_next(struct seq_file *seq, void *v, loff_t *pos) static void *vlan_seq_next(struct seq_file *seq, void *v, loff_t *pos)
{ {
struct net_device *dev;
struct net *net = seq_file_net(seq);
++*pos; ++*pos;
return vlan_seq_from_index(seq, pos);
dev = v;
if (v == SEQ_START_TOKEN)
dev = net_device_entry(&net->dev_base_head);
for_each_netdev_continue_rcu(net, dev) {
if (!is_vlan_dev(dev))
continue;
return dev;
}
return NULL;
} }
static void vlan_seq_stop(struct seq_file *seq, void *v) static void vlan_seq_stop(struct seq_file *seq, void *v)
......
...@@ -2188,25 +2188,22 @@ static int rtnl_valid_dump_ifinfo_req(const struct nlmsghdr *nlh, ...@@ -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; unsigned int flags = NLM_F_MULTI;
int h, s_h;
int idx = 0, s_idx;
struct net_device *dev;
struct hlist_head *head;
struct nlattr *tb[IFLA_MAX+1]; struct nlattr *tb[IFLA_MAX+1];
struct {
unsigned long ifindex;
} *ctx = (void *)cb->ctx;
struct net *tgt_net = net;
u32 ext_filter_mask = 0; u32 ext_filter_mask = 0;
const struct rtnl_link_ops *kind_ops = NULL; struct net_device *dev;
unsigned int flags = NLM_F_MULTI;
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) ...@@ -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)
......
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