]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
rtnetlink: add ndo_fdb_dump_context
authorEric Dumazet <edumazet@google.com>
Mon, 9 Dec 2024 10:07:45 +0000 (10:07 +0000)
committerJakub Kicinski <kuba@kernel.org>
Wed, 11 Dec 2024 02:32:32 +0000 (18:32 -0800)
rtnl_fdb_dump() and various ndo_fdb_dump() helpers share
a hidden layout of cb->ctx.

Before switching rtnl_fdb_dump() to for_each_netdev_dump()
in the following patch, make this more explicit.

Signed-off-by: Eric Dumazet <edumazet@google.com>
Reviewed-by: Ido Schimmel <idosch@nvidia.com>
Reviewed-by: Kuniyuki Iwashima <kuniyu@amazon.com>
Link: https://patch.msgid.link/20241209100747.2269613-2-edumazet@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c
drivers/net/ethernet/mscc/ocelot_net.c
drivers/net/vxlan/vxlan_core.c
include/linux/rtnetlink.h
net/bridge/br_fdb.c
net/core/rtnetlink.c
net/dsa/user.c

index a293b08f36d46dfde7e25412951da78c15e2dfd6..147a93bf9fa913f663676f30559202de9e889f40 100644 (file)
@@ -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,
index 558e03301aa8ed89e15c5f37d148a287feaf0018..8d48468cddd7cf91fb49ad23a5c57110900160ef 100644 (file)
@@ -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,
index 43cf672b7b9fc64da442f6a7502845f4112a2f23..0c356e0a61ef01450fbe9f8ffd0d1dceab73d0a9 100644 (file)
@@ -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 @@ skip_nh:
                        }
 
                        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,
index 811ce44113f6f88b2ad9bd73d126e49dd454813c..c43cffb014a7ce1b98cb9604c545fc6c9d36eed9 100644 (file)
@@ -178,6 +178,13 @@ 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 s_h;
+       unsigned long s_idx;
+       unsigned long fdb_idx;
+};
+
 extern int ndo_dflt_fdb_dump(struct sk_buff *skb,
                             struct netlink_callback *cb,
                             struct net_device *dev,
index 82bac2426631bcea63ea834e72f074fa2eaf0cee..902694c0ce643ec448978e4c4625692ccb1facd9 100644 (file)
@@ -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)
index ab5f201bf0ab41b463175f501e8560b4d64d9b0a..453cc8bf18fbe0d2ac41fed13576279b4c7a2c07 100644 (file)
@@ -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,10 +4910,9 @@ 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;
@@ -4922,6 +4922,8 @@ static int rtnl_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb)
        int err = 0;
        int fidx = 0;
 
+       NL_ASSERT_CTX_FITS(struct ndo_fdb_dump_context);
+
        if (cb->strict_check)
                err = valid_fdb_dump_strict(cb->nlh, &br_idx, &brport_idx,
                                            cb->extack);
@@ -4939,8 +4941,8 @@ 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];
+       s_h = ctx->s_h;
+       s_idx = ctx->s_idx;
 
        for (h = s_h; h < NETDEV_HASHENTRIES; h++, s_idx = 0) {
                idx = 0;
@@ -4992,7 +4994,7 @@ static int rtnl_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb)
                        cops = NULL;
 
                        /* reset fdb offset to 0 for rest of the interfaces */
-                       cb->args[2] = 0;
+                       ctx->fdb_idx = 0;
                        fidx = 0;
 cont:
                        idx++;
@@ -5000,9 +5002,9 @@ cont:
        }
 
 out:
-       cb->args[0] = h;
-       cb->args[1] = idx;
-       cb->args[2] = fidx;
+       ctx->s_h = h;
+       ctx->s_idx = idx;
+       ctx->fdb_idx = fidx;
 
        return skb->len;
 }
index 06c30a9e29ff820d2dd58fb1801d5e76a5928326..c736c019e2af90747738f10b667e6ad936c9eb0b 100644 (file)
@@ -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,