mirror of
https://github.com/torvalds/linux.git
synced 2026-05-27 16:44:58 +02:00
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>
This commit is contained in:
commit
90da34d146
|
|
@ -780,13 +780,14 @@ struct ethsw_dump_ctx {
|
|||
static int dpaa2_switch_fdb_dump_nl(struct fdb_dump_entry *entry,
|
||||
struct ethsw_dump_ctx *dump)
|
||||
{
|
||||
struct ndo_fdb_dump_context *ctx = (void *)dump->cb->ctx;
|
||||
int is_dynamic = entry->type & DPSW_FDB_ENTRY_DINAMIC;
|
||||
u32 portid = NETLINK_CB(dump->cb->skb).portid;
|
||||
u32 seq = dump->cb->nlh->nlmsg_seq;
|
||||
struct nlmsghdr *nlh;
|
||||
struct ndmsg *ndm;
|
||||
|
||||
if (dump->idx < dump->cb->args[2])
|
||||
if (dump->idx < ctx->fdb_idx)
|
||||
goto skip;
|
||||
|
||||
nlh = nlmsg_put(dump->skb, portid, seq, RTM_NEWNEIGH,
|
||||
|
|
|
|||
|
|
@ -758,12 +758,13 @@ static int ocelot_port_fdb_do_dump(const unsigned char *addr, u16 vid,
|
|||
bool is_static, void *data)
|
||||
{
|
||||
struct ocelot_dump_ctx *dump = data;
|
||||
struct ndo_fdb_dump_context *ctx = (void *)dump->cb->ctx;
|
||||
u32 portid = NETLINK_CB(dump->cb->skb).portid;
|
||||
u32 seq = dump->cb->nlh->nlmsg_seq;
|
||||
struct nlmsghdr *nlh;
|
||||
struct ndmsg *ndm;
|
||||
|
||||
if (dump->idx < dump->cb->args[2])
|
||||
if (dump->idx < ctx->fdb_idx)
|
||||
goto skip;
|
||||
|
||||
nlh = nlmsg_put(dump->skb, portid, seq, RTM_NEWNEIGH,
|
||||
|
|
|
|||
|
|
@ -1352,6 +1352,7 @@ static int vxlan_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb,
|
|||
struct net_device *dev,
|
||||
struct net_device *filter_dev, int *idx)
|
||||
{
|
||||
struct ndo_fdb_dump_context *ctx = (void *)cb->ctx;
|
||||
struct vxlan_dev *vxlan = netdev_priv(dev);
|
||||
unsigned int h;
|
||||
int err = 0;
|
||||
|
|
@ -1364,7 +1365,7 @@ static int vxlan_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb,
|
|||
struct vxlan_rdst *rd;
|
||||
|
||||
if (rcu_access_pointer(f->nh)) {
|
||||
if (*idx < cb->args[2])
|
||||
if (*idx < ctx->fdb_idx)
|
||||
goto skip_nh;
|
||||
err = vxlan_fdb_info(skb, vxlan, f,
|
||||
NETLINK_CB(cb->skb).portid,
|
||||
|
|
@ -1381,7 +1382,7 @@ static int vxlan_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb,
|
|||
}
|
||||
|
||||
list_for_each_entry_rcu(rd, &f->remotes, list) {
|
||||
if (*idx < cb->args[2])
|
||||
if (*idx < ctx->fdb_idx)
|
||||
goto skip;
|
||||
|
||||
err = vxlan_fdb_info(skb, vxlan, f,
|
||||
|
|
|
|||
|
|
@ -178,6 +178,12 @@ void rtnetlink_init(void);
|
|||
void __rtnl_unlock(void);
|
||||
void rtnl_kfree_skbs(struct sk_buff *head, struct sk_buff *tail);
|
||||
|
||||
/* Shared by rtnl_fdb_dump() and various ndo_fdb_dump() helpers. */
|
||||
struct ndo_fdb_dump_context {
|
||||
unsigned long ifindex;
|
||||
unsigned long fdb_idx;
|
||||
};
|
||||
|
||||
extern int ndo_dflt_fdb_dump(struct sk_buff *skb,
|
||||
struct netlink_callback *cb,
|
||||
struct net_device *dev,
|
||||
|
|
|
|||
|
|
@ -955,6 +955,7 @@ int br_fdb_dump(struct sk_buff *skb,
|
|||
struct net_device *filter_dev,
|
||||
int *idx)
|
||||
{
|
||||
struct ndo_fdb_dump_context *ctx = (void *)cb->ctx;
|
||||
struct net_bridge *br = netdev_priv(dev);
|
||||
struct net_bridge_fdb_entry *f;
|
||||
int err = 0;
|
||||
|
|
@ -970,7 +971,7 @@ int br_fdb_dump(struct sk_buff *skb,
|
|||
|
||||
rcu_read_lock();
|
||||
hlist_for_each_entry_rcu(f, &br->fdb_list, fdb_node) {
|
||||
if (*idx < cb->args[2])
|
||||
if (*idx < ctx->fdb_idx)
|
||||
goto skip;
|
||||
if (filter_dev && (!f->dst || f->dst->dev != filter_dev)) {
|
||||
if (filter_dev != dev)
|
||||
|
|
|
|||
|
|
@ -4762,15 +4762,16 @@ static int nlmsg_populate_fdb(struct sk_buff *skb,
|
|||
int *idx,
|
||||
struct netdev_hw_addr_list *list)
|
||||
{
|
||||
struct ndo_fdb_dump_context *ctx = (void *)cb->ctx;
|
||||
struct netdev_hw_addr *ha;
|
||||
int err;
|
||||
u32 portid, seq;
|
||||
int err;
|
||||
|
||||
portid = NETLINK_CB(cb->skb).portid;
|
||||
seq = cb->nlh->nlmsg_seq;
|
||||
|
||||
list_for_each_entry(ha, &list->list, list) {
|
||||
if (*idx < cb->args[2])
|
||||
if (*idx < ctx->fdb_idx)
|
||||
goto skip;
|
||||
|
||||
err = nlmsg_populate_fdb_fill(skb, dev, ha->addr, 0,
|
||||
|
|
@ -4909,18 +4910,16 @@ static int valid_fdb_dump_legacy(const struct nlmsghdr *nlh,
|
|||
|
||||
static int rtnl_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb)
|
||||
{
|
||||
struct net_device *dev;
|
||||
struct net_device *br_dev = NULL;
|
||||
const struct net_device_ops *ops = NULL;
|
||||
const struct net_device_ops *cops = NULL;
|
||||
const struct net_device_ops *ops = NULL, *cops = NULL;
|
||||
struct ndo_fdb_dump_context *ctx = (void *)cb->ctx;
|
||||
struct net_device *dev, *br_dev = NULL;
|
||||
struct net *net = sock_net(skb->sk);
|
||||
struct hlist_head *head;
|
||||
int brport_idx = 0;
|
||||
int br_idx = 0;
|
||||
int h, s_h;
|
||||
int idx = 0, s_idx;
|
||||
int err = 0;
|
||||
int fidx = 0;
|
||||
int err;
|
||||
|
||||
NL_ASSERT_CTX_FITS(struct ndo_fdb_dump_context);
|
||||
|
||||
if (cb->strict_check)
|
||||
err = valid_fdb_dump_strict(cb->nlh, &br_idx, &brport_idx,
|
||||
|
|
@ -4939,70 +4938,51 @@ static int rtnl_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb)
|
|||
ops = br_dev->netdev_ops;
|
||||
}
|
||||
|
||||
s_h = cb->args[0];
|
||||
s_idx = cb->args[1];
|
||||
for_each_netdev_dump(net, dev, ctx->ifindex) {
|
||||
if (brport_idx && (dev->ifindex != brport_idx))
|
||||
continue;
|
||||
|
||||
for (h = s_h; h < NETDEV_HASHENTRIES; h++, s_idx = 0) {
|
||||
idx = 0;
|
||||
head = &net->dev_index_head[h];
|
||||
hlist_for_each_entry(dev, head, index_hlist) {
|
||||
|
||||
if (brport_idx && (dev->ifindex != brport_idx))
|
||||
if (!br_idx) { /* user did not specify a specific bridge */
|
||||
if (netif_is_bridge_port(dev)) {
|
||||
br_dev = netdev_master_upper_dev_get(dev);
|
||||
cops = br_dev->netdev_ops;
|
||||
}
|
||||
} else {
|
||||
if (dev != br_dev &&
|
||||
!netif_is_bridge_port(dev))
|
||||
continue;
|
||||
|
||||
if (!br_idx) { /* user did not specify a specific bridge */
|
||||
if (netif_is_bridge_port(dev)) {
|
||||
br_dev = netdev_master_upper_dev_get(dev);
|
||||
cops = br_dev->netdev_ops;
|
||||
}
|
||||
} else {
|
||||
if (dev != br_dev &&
|
||||
!netif_is_bridge_port(dev))
|
||||
continue;
|
||||
|
||||
if (br_dev != netdev_master_upper_dev_get(dev) &&
|
||||
!netif_is_bridge_master(dev))
|
||||
continue;
|
||||
cops = ops;
|
||||
}
|
||||
|
||||
if (idx < s_idx)
|
||||
goto cont;
|
||||
|
||||
if (netif_is_bridge_port(dev)) {
|
||||
if (cops && cops->ndo_fdb_dump) {
|
||||
err = cops->ndo_fdb_dump(skb, cb,
|
||||
br_dev, dev,
|
||||
&fidx);
|
||||
if (err == -EMSGSIZE)
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
if (dev->netdev_ops->ndo_fdb_dump)
|
||||
err = dev->netdev_ops->ndo_fdb_dump(skb, cb,
|
||||
dev, NULL,
|
||||
&fidx);
|
||||
else
|
||||
err = ndo_dflt_fdb_dump(skb, cb, dev, NULL,
|
||||
&fidx);
|
||||
if (err == -EMSGSIZE)
|
||||
goto out;
|
||||
|
||||
cops = NULL;
|
||||
|
||||
/* reset fdb offset to 0 for rest of the interfaces */
|
||||
cb->args[2] = 0;
|
||||
fidx = 0;
|
||||
cont:
|
||||
idx++;
|
||||
if (br_dev != netdev_master_upper_dev_get(dev) &&
|
||||
!netif_is_bridge_master(dev))
|
||||
continue;
|
||||
cops = ops;
|
||||
}
|
||||
|
||||
if (netif_is_bridge_port(dev)) {
|
||||
if (cops && cops->ndo_fdb_dump) {
|
||||
err = cops->ndo_fdb_dump(skb, cb, br_dev, dev,
|
||||
&fidx);
|
||||
if (err == -EMSGSIZE)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (dev->netdev_ops->ndo_fdb_dump)
|
||||
err = dev->netdev_ops->ndo_fdb_dump(skb, cb, dev, NULL,
|
||||
&fidx);
|
||||
else
|
||||
err = ndo_dflt_fdb_dump(skb, cb, dev, NULL, &fidx);
|
||||
if (err == -EMSGSIZE)
|
||||
break;
|
||||
|
||||
cops = NULL;
|
||||
|
||||
/* reset fdb offset to 0 for rest of the interfaces */
|
||||
ctx->fdb_idx = 0;
|
||||
fidx = 0;
|
||||
}
|
||||
|
||||
out:
|
||||
cb->args[0] = h;
|
||||
cb->args[1] = idx;
|
||||
cb->args[2] = fidx;
|
||||
ctx->fdb_idx = fidx;
|
||||
|
||||
return skb->len;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -515,12 +515,13 @@ dsa_user_port_fdb_do_dump(const unsigned char *addr, u16 vid,
|
|||
bool is_static, void *data)
|
||||
{
|
||||
struct dsa_user_dump_ctx *dump = data;
|
||||
struct ndo_fdb_dump_context *ctx = (void *)dump->cb->ctx;
|
||||
u32 portid = NETLINK_CB(dump->cb->skb).portid;
|
||||
u32 seq = dump->cb->nlh->nlmsg_seq;
|
||||
struct nlmsghdr *nlh;
|
||||
struct ndmsg *ndm;
|
||||
|
||||
if (dump->idx < dump->cb->args[2])
|
||||
if (dump->idx < ctx->fdb_idx)
|
||||
goto skip;
|
||||
|
||||
nlh = nlmsg_put(dump->skb, portid, seq, RTM_NEWNEIGH,
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user