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

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.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents bed90b06 3e41af90
Loading
Loading
Loading
Loading
+16 −30
Original line number Diff line number Diff line
@@ -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
 */

/* start read of /proc/net/vlan/config */
static void *vlan_seq_start(struct seq_file *seq, loff_t *pos)
	__acquires(rcu)
static void *vlan_seq_from_index(struct seq_file *seq, loff_t *pos)
{
	unsigned long ifindex = *pos;
	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))
			continue;

		if (i++ == *pos)
		*pos = dev->ifindex;
		return dev;
	}

	return NULL;
}

static void *vlan_seq_next(struct seq_file *seq, void *v, loff_t *pos)
static void *vlan_seq_start(struct seq_file *seq, loff_t *pos)
	__acquires(rcu)
{
	struct net_device *dev;
	struct net *net = seq_file_net(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;
	rcu_read_lock();
	if (*pos == 0)
		return SEQ_START_TOKEN;

		return dev;
	return vlan_seq_from_index(seq, pos);
}

	return NULL;
static void *vlan_seq_next(struct seq_file *seq, void *v, loff_t *pos)
{
	++*pos;
	return vlan_seq_from_index(seq, pos);
}

static void vlan_seq_stop(struct seq_file *seq, void *v)
+20 −38
Original line number Diff line number Diff line
@@ -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)
{
	const struct rtnl_link_ops *kind_ops = NULL;
	struct netlink_ext_ack *extack = cb->extack;
	const struct nlmsghdr *nlh = cb->nlh;
	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;
	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;
	const struct rtnl_link_ops *kind_ops = NULL;
	unsigned int flags = NLM_F_MULTI;
	struct net_device *dev;
	int master_idx = 0;
	int netnsid = -1;
	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);
	if (err < 0) {
		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;

walk_entries:
	for (h = s_h; h < NETDEV_HASHENTRIES; h++, s_idx = 0) {
		idx = 0;
		head = &tgt_net->dev_index_head[h];
		hlist_for_each_entry(dev, head, index_hlist) {
	err = 0;
	for_each_netdev_dump(tgt_net, dev, ctx->ifindex) {
		if (link_dump_filtered(dev, master_idx, kind_ops))
				goto cont;
			if (idx < s_idx)
				goto cont;
			err = rtnl_fill_ifinfo(skb, dev, net,
					       RTM_NEWLINK,
			continue;
		err = rtnl_fill_ifinfo(skb, dev, net, RTM_NEWLINK,
				       NETLINK_CB(cb->skb).portid,
				       nlh->nlmsg_seq, 0, flags,
				       ext_filter_mask, 0, NULL, 0,
				       netnsid, GFP_KERNEL);

		if (err < 0) {
			if (likely(skb->len))
					goto out;

				goto out_err;
			}
cont:
			idx++;
				err = skb->len;
			break;
		}
	}
out:
	err = skb->len;
out_err:
	cb->args[1] = idx;
	cb->args[0] = h;
	cb->seq = tgt_net->dev_base_seq;
	nl_dump_check_consistent(cb, nlmsg_hdr(skb));
	if (netnsid >= 0)