Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'net-prepare-for-removal-of-net-dev_index_head'

Eric Dumazet says:

====================
net: prepare for removal of net->dev_index_head

This series changes rtnl_fdb_dump, last iterator using net->dev_index_head[]

First patch creates ndo_fdb_dump_context structure, to no longer
assume specific layout for the arguments.

Second patch adopts for_each_netdev_dump() in rtnl_fdb_dump(),
while changing two first fields of ndo_fdb_dump_context.

Third patch removes the padding, thus changing the location
of ctx->fdb_idx now that all users agree on how to retrive it.

After this series, the only users of net->dev_index_head
are __dev_get_by_index() and dev_get_by_index_rcu().

We have to evaluate if switching them to dev_by_index xarray
would be sensible.

v1: https://lore.kernel.org/20241207162248.18536-1-edumazet@google.com/T/#m800755d4b16c7f335927a76d9f52ebd37f7f077c
====================

Link: https://patch.msgid.link/20241209100747.2269613-1-edumazet@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

+65 -74
+2 -1
drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c
··· 780 780 static int dpaa2_switch_fdb_dump_nl(struct fdb_dump_entry *entry, 781 781 struct ethsw_dump_ctx *dump) 782 782 { 783 + struct ndo_fdb_dump_context *ctx = (void *)dump->cb->ctx; 783 784 int is_dynamic = entry->type & DPSW_FDB_ENTRY_DINAMIC; 784 785 u32 portid = NETLINK_CB(dump->cb->skb).portid; 785 786 u32 seq = dump->cb->nlh->nlmsg_seq; 786 787 struct nlmsghdr *nlh; 787 788 struct ndmsg *ndm; 788 789 789 - if (dump->idx < dump->cb->args[2]) 790 + if (dump->idx < ctx->fdb_idx) 790 791 goto skip; 791 792 792 793 nlh = nlmsg_put(dump->skb, portid, seq, RTM_NEWNEIGH,
+2 -1
drivers/net/ethernet/mscc/ocelot_net.c
··· 758 758 bool is_static, void *data) 759 759 { 760 760 struct ocelot_dump_ctx *dump = data; 761 + struct ndo_fdb_dump_context *ctx = (void *)dump->cb->ctx; 761 762 u32 portid = NETLINK_CB(dump->cb->skb).portid; 762 763 u32 seq = dump->cb->nlh->nlmsg_seq; 763 764 struct nlmsghdr *nlh; 764 765 struct ndmsg *ndm; 765 766 766 - if (dump->idx < dump->cb->args[2]) 767 + if (dump->idx < ctx->fdb_idx) 767 768 goto skip; 768 769 769 770 nlh = nlmsg_put(dump->skb, portid, seq, RTM_NEWNEIGH,
+3 -2
drivers/net/vxlan/vxlan_core.c
··· 1352 1352 struct net_device *dev, 1353 1353 struct net_device *filter_dev, int *idx) 1354 1354 { 1355 + struct ndo_fdb_dump_context *ctx = (void *)cb->ctx; 1355 1356 struct vxlan_dev *vxlan = netdev_priv(dev); 1356 1357 unsigned int h; 1357 1358 int err = 0; ··· 1365 1364 struct vxlan_rdst *rd; 1366 1365 1367 1366 if (rcu_access_pointer(f->nh)) { 1368 - if (*idx < cb->args[2]) 1367 + if (*idx < ctx->fdb_idx) 1369 1368 goto skip_nh; 1370 1369 err = vxlan_fdb_info(skb, vxlan, f, 1371 1370 NETLINK_CB(cb->skb).portid, ··· 1382 1381 } 1383 1382 1384 1383 list_for_each_entry_rcu(rd, &f->remotes, list) { 1385 - if (*idx < cb->args[2]) 1384 + if (*idx < ctx->fdb_idx) 1386 1385 goto skip; 1387 1386 1388 1387 err = vxlan_fdb_info(skb, vxlan, f,
+6
include/linux/rtnetlink.h
··· 178 178 void __rtnl_unlock(void); 179 179 void rtnl_kfree_skbs(struct sk_buff *head, struct sk_buff *tail); 180 180 181 + /* Shared by rtnl_fdb_dump() and various ndo_fdb_dump() helpers. */ 182 + struct ndo_fdb_dump_context { 183 + unsigned long ifindex; 184 + unsigned long fdb_idx; 185 + }; 186 + 181 187 extern int ndo_dflt_fdb_dump(struct sk_buff *skb, 182 188 struct netlink_callback *cb, 183 189 struct net_device *dev,
+2 -1
net/bridge/br_fdb.c
··· 955 955 struct net_device *filter_dev, 956 956 int *idx) 957 957 { 958 + struct ndo_fdb_dump_context *ctx = (void *)cb->ctx; 958 959 struct net_bridge *br = netdev_priv(dev); 959 960 struct net_bridge_fdb_entry *f; 960 961 int err = 0; ··· 971 970 972 971 rcu_read_lock(); 973 972 hlist_for_each_entry_rcu(f, &br->fdb_list, fdb_node) { 974 - if (*idx < cb->args[2]) 973 + if (*idx < ctx->fdb_idx) 975 974 goto skip; 976 975 if (filter_dev && (!f->dst || f->dst->dev != filter_dev)) { 977 976 if (filter_dev != dev)
+48 -68
net/core/rtnetlink.c
··· 4762 4762 int *idx, 4763 4763 struct netdev_hw_addr_list *list) 4764 4764 { 4765 + struct ndo_fdb_dump_context *ctx = (void *)cb->ctx; 4765 4766 struct netdev_hw_addr *ha; 4766 - int err; 4767 4767 u32 portid, seq; 4768 + int err; 4768 4769 4769 4770 portid = NETLINK_CB(cb->skb).portid; 4770 4771 seq = cb->nlh->nlmsg_seq; 4771 4772 4772 4773 list_for_each_entry(ha, &list->list, list) { 4773 - if (*idx < cb->args[2]) 4774 + if (*idx < ctx->fdb_idx) 4774 4775 goto skip; 4775 4776 4776 4777 err = nlmsg_populate_fdb_fill(skb, dev, ha->addr, 0, ··· 4910 4909 4911 4910 static int rtnl_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb) 4912 4911 { 4913 - struct net_device *dev; 4914 - struct net_device *br_dev = NULL; 4915 - const struct net_device_ops *ops = NULL; 4916 - const struct net_device_ops *cops = NULL; 4912 + const struct net_device_ops *ops = NULL, *cops = NULL; 4913 + struct ndo_fdb_dump_context *ctx = (void *)cb->ctx; 4914 + struct net_device *dev, *br_dev = NULL; 4917 4915 struct net *net = sock_net(skb->sk); 4918 - struct hlist_head *head; 4919 4916 int brport_idx = 0; 4920 4917 int br_idx = 0; 4921 - int h, s_h; 4922 - int idx = 0, s_idx; 4923 - int err = 0; 4924 4918 int fidx = 0; 4919 + int err; 4920 + 4921 + NL_ASSERT_CTX_FITS(struct ndo_fdb_dump_context); 4925 4922 4926 4923 if (cb->strict_check) 4927 4924 err = valid_fdb_dump_strict(cb->nlh, &br_idx, &brport_idx, ··· 4938 4939 ops = br_dev->netdev_ops; 4939 4940 } 4940 4941 4941 - s_h = cb->args[0]; 4942 - s_idx = cb->args[1]; 4942 + for_each_netdev_dump(net, dev, ctx->ifindex) { 4943 + if (brport_idx && (dev->ifindex != brport_idx)) 4944 + continue; 4943 4945 4944 - for (h = s_h; h < NETDEV_HASHENTRIES; h++, s_idx = 0) { 4945 - idx = 0; 4946 - head = &net->dev_index_head[h]; 4947 - hlist_for_each_entry(dev, head, index_hlist) { 4948 - 4949 - if (brport_idx && (dev->ifindex != brport_idx)) 4946 + if (!br_idx) { /* user did not specify a specific bridge */ 4947 + if (netif_is_bridge_port(dev)) { 4948 + br_dev = netdev_master_upper_dev_get(dev); 4949 + cops = br_dev->netdev_ops; 4950 + } 4951 + } else { 4952 + if (dev != br_dev && 4953 + !netif_is_bridge_port(dev)) 4950 4954 continue; 4951 4955 4952 - if (!br_idx) { /* user did not specify a specific bridge */ 4953 - if (netif_is_bridge_port(dev)) { 4954 - br_dev = netdev_master_upper_dev_get(dev); 4955 - cops = br_dev->netdev_ops; 4956 - } 4957 - } else { 4958 - if (dev != br_dev && 4959 - !netif_is_bridge_port(dev)) 4960 - continue; 4961 - 4962 - if (br_dev != netdev_master_upper_dev_get(dev) && 4963 - !netif_is_bridge_master(dev)) 4964 - continue; 4965 - cops = ops; 4966 - } 4967 - 4968 - if (idx < s_idx) 4969 - goto cont; 4970 - 4971 - if (netif_is_bridge_port(dev)) { 4972 - if (cops && cops->ndo_fdb_dump) { 4973 - err = cops->ndo_fdb_dump(skb, cb, 4974 - br_dev, dev, 4975 - &fidx); 4976 - if (err == -EMSGSIZE) 4977 - goto out; 4978 - } 4979 - } 4980 - 4981 - if (dev->netdev_ops->ndo_fdb_dump) 4982 - err = dev->netdev_ops->ndo_fdb_dump(skb, cb, 4983 - dev, NULL, 4984 - &fidx); 4985 - else 4986 - err = ndo_dflt_fdb_dump(skb, cb, dev, NULL, 4987 - &fidx); 4988 - if (err == -EMSGSIZE) 4989 - goto out; 4990 - 4991 - cops = NULL; 4992 - 4993 - /* reset fdb offset to 0 for rest of the interfaces */ 4994 - cb->args[2] = 0; 4995 - fidx = 0; 4996 - cont: 4997 - idx++; 4956 + if (br_dev != netdev_master_upper_dev_get(dev) && 4957 + !netif_is_bridge_master(dev)) 4958 + continue; 4959 + cops = ops; 4998 4960 } 4961 + 4962 + if (netif_is_bridge_port(dev)) { 4963 + if (cops && cops->ndo_fdb_dump) { 4964 + err = cops->ndo_fdb_dump(skb, cb, br_dev, dev, 4965 + &fidx); 4966 + if (err == -EMSGSIZE) 4967 + break; 4968 + } 4969 + } 4970 + 4971 + if (dev->netdev_ops->ndo_fdb_dump) 4972 + err = dev->netdev_ops->ndo_fdb_dump(skb, cb, dev, NULL, 4973 + &fidx); 4974 + else 4975 + err = ndo_dflt_fdb_dump(skb, cb, dev, NULL, &fidx); 4976 + if (err == -EMSGSIZE) 4977 + break; 4978 + 4979 + cops = NULL; 4980 + 4981 + /* reset fdb offset to 0 for rest of the interfaces */ 4982 + ctx->fdb_idx = 0; 4983 + fidx = 0; 4999 4984 } 5000 4985 5001 - out: 5002 - cb->args[0] = h; 5003 - cb->args[1] = idx; 5004 - cb->args[2] = fidx; 4986 + ctx->fdb_idx = fidx; 5005 4987 5006 4988 return skb->len; 5007 4989 }
+2 -1
net/dsa/user.c
··· 515 515 bool is_static, void *data) 516 516 { 517 517 struct dsa_user_dump_ctx *dump = data; 518 + struct ndo_fdb_dump_context *ctx = (void *)dump->cb->ctx; 518 519 u32 portid = NETLINK_CB(dump->cb->skb).portid; 519 520 u32 seq = dump->cb->nlh->nlmsg_seq; 520 521 struct nlmsghdr *nlh; 521 522 struct ndmsg *ndm; 522 523 523 - if (dump->idx < dump->cb->args[2]) 524 + if (dump->idx < ctx->fdb_idx) 524 525 goto skip; 525 526 526 527 nlh = nlmsg_put(dump->skb, portid, seq, RTM_NEWNEIGH,