[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20210821210018.1314952-2-vladimir.oltean@nxp.com>
Date: Sun, 22 Aug 2021 00:00:15 +0300
From: Vladimir Oltean <vladimir.oltean@....com>
To: netdev@...r.kernel.org
Subject: [RFC PATCH 1/4] net: rtnetlink: create a netlink cb context struct for fdb dump
For the ability to grep for proper structure/variable names, if for
nothing else, use the more modern struct netlink_callback::ctx as
opposed to args to hold the stateful data over the course of an FDB dump
operation.
Signed-off-by: Vladimir Oltean <vladimir.oltean@....com>
---
.../ethernet/freescale/dpaa2/dpaa2-switch.c | 5 ++++-
drivers/net/ethernet/mscc/ocelot.c | 5 ++++-
drivers/net/vxlan.c | 5 +++--
include/linux/rtnetlink.h | 18 ++++++++++++++++++
net/bridge/br_fdb.c | 3 ++-
net/core/rtnetlink.c | 16 +++++++++-------
net/dsa/slave.c | 5 ++++-
7 files changed, 44 insertions(+), 13 deletions(-)
diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c b/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c
index d260993ab2dc..dd018dfb25ee 100644
--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c
+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c
@@ -771,10 +771,13 @@ static int dpaa2_switch_fdb_dump_nl(struct fdb_dump_entry *entry,
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 rtnl_fdb_dump_ctx *ctx;
struct nlmsghdr *nlh;
struct ndmsg *ndm;
- if (dump->idx < dump->cb->args[2])
+ ctx = (struct rtnl_fdb_dump_ctx *)dump->cb->ctx;
+
+ if (dump->idx < ctx->fidx)
goto skip;
nlh = nlmsg_put(dump->skb, portid, seq, RTM_NEWNEIGH,
diff --git a/drivers/net/ethernet/mscc/ocelot.c b/drivers/net/ethernet/mscc/ocelot.c
index 5209650fd25f..44a56f9cda07 100644
--- a/drivers/net/ethernet/mscc/ocelot.c
+++ b/drivers/net/ethernet/mscc/ocelot.c
@@ -971,10 +971,13 @@ int ocelot_port_fdb_do_dump(const unsigned char *addr, u16 vid,
struct ocelot_dump_ctx *dump = data;
u32 portid = NETLINK_CB(dump->cb->skb).portid;
u32 seq = dump->cb->nlh->nlmsg_seq;
+ struct rtnl_fdb_dump_ctx *ctx;
struct nlmsghdr *nlh;
struct ndmsg *ndm;
- if (dump->idx < dump->cb->args[2])
+ ctx = (struct rtnl_fdb_dump_ctx *)dump->cb->ctx;
+
+ if (dump->idx < ctx->fidx)
goto skip;
nlh = nlmsg_put(dump->skb, portid, seq, RTM_NEWNEIGH,
diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c
index 5a8df5a195cb..8c9371bf8195 100644
--- a/drivers/net/vxlan.c
+++ b/drivers/net/vxlan.c
@@ -1371,6 +1371,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 rtnl_fdb_dump_ctx *ctx = (struct rtnl_fdb_dump_ctx *)cb->ctx;
struct vxlan_dev *vxlan = netdev_priv(dev);
unsigned int h;
int err = 0;
@@ -1383,7 +1384,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->fidx)
goto skip_nh;
err = vxlan_fdb_info(skb, vxlan, f,
NETLINK_CB(cb->skb).portid,
@@ -1400,7 +1401,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->fidx)
goto skip;
err = vxlan_fdb_info(skb, vxlan, f,
diff --git a/include/linux/rtnetlink.h b/include/linux/rtnetlink.h
index bb9cb84114c1..f14cda6939c6 100644
--- a/include/linux/rtnetlink.h
+++ b/include/linux/rtnetlink.h
@@ -110,6 +110,24 @@ void rtnl_kfree_skbs(struct sk_buff *head, struct sk_buff *tail);
WARN_ONCE(!rtnl_is_locked(), \
"RTNL: assertion failed at %s (%d)\n", __FILE__, __LINE__)
+struct rtnl_fdb_dump_ctx {
+ /* Last bucket in the dev_index_head hash list that was checked.
+ * Used by rtnl_fdb_dump to resume in case the procedure is
+ * interrupted.
+ */
+ int pos_hash;
+ /* Last interface within bucket @pos_hash that was checked.
+ * Used by rtnl_fdb_dump to resume in case the procedure is
+ * interrupted.
+ */
+ int pos_idx;
+ /* Last FDB entry number that was dumped for the current interface.
+ * Updated by implementers of .ndo_fdb_dump and used to resume in case
+ * the dump procedure is interrupted.
+ */
+ int fidx;
+};
+
extern int ndo_dflt_fdb_dump(struct sk_buff *skb,
struct netlink_callback *cb,
struct net_device *dev,
diff --git a/net/bridge/br_fdb.c b/net/bridge/br_fdb.c
index 46812b659710..2f6527d1df27 100644
--- a/net/bridge/br_fdb.c
+++ b/net/bridge/br_fdb.c
@@ -821,6 +821,7 @@ int br_fdb_dump(struct sk_buff *skb,
struct net_device *filter_dev,
int *idx)
{
+ struct rtnl_fdb_dump_ctx *ctx = (struct rtnl_fdb_dump_ctx *)cb->ctx;
struct net_bridge *br = netdev_priv(dev);
struct net_bridge_fdb_entry *f;
int err = 0;
@@ -836,7 +837,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->fidx)
goto skip;
if (filter_dev && (!f->dst || f->dst->dev != filter_dev)) {
if (filter_dev != dev)
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index 2dcf1c084b20..06cd59b6260a 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -4184,6 +4184,7 @@ static int nlmsg_populate_fdb(struct sk_buff *skb,
int *idx,
struct netdev_hw_addr_list *list)
{
+ struct rtnl_fdb_dump_ctx *ctx = (struct rtnl_fdb_dump_ctx *)cb->ctx;
struct netdev_hw_addr *ha;
int err;
u32 portid, seq;
@@ -4192,7 +4193,7 @@ static int nlmsg_populate_fdb(struct sk_buff *skb,
seq = cb->nlh->nlmsg_seq;
list_for_each_entry(ha, &list->list, list) {
- if (*idx < cb->args[2])
+ if (*idx < ctx->fidx)
goto skip;
err = nlmsg_populate_fdb_fill(skb, dev, ha->addr, 0,
@@ -4331,6 +4332,7 @@ static int valid_fdb_dump_legacy(const struct nlmsghdr *nlh,
static int rtnl_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb)
{
+ struct rtnl_fdb_dump_ctx *ctx = (struct rtnl_fdb_dump_ctx *)cb->ctx;
struct net_device *dev;
struct net_device *br_dev = NULL;
const struct net_device_ops *ops = NULL;
@@ -4361,8 +4363,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->pos_hash;
+ s_idx = ctx->pos_idx;
for (h = s_h; h < NETDEV_HASHENTRIES; h++, s_idx = 0) {
idx = 0;
@@ -4414,7 +4416,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->fidx = 0;
fidx = 0;
cont:
idx++;
@@ -4422,9 +4424,9 @@ static int rtnl_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb)
}
out:
- cb->args[0] = h;
- cb->args[1] = idx;
- cb->args[2] = fidx;
+ ctx->pos_hash = h;
+ ctx->pos_idx = idx;
+ ctx->fidx = fidx;
return skb->len;
}
diff --git a/net/dsa/slave.c b/net/dsa/slave.c
index eb9d9e53c536..f25cd48a75ee 100644
--- a/net/dsa/slave.c
+++ b/net/dsa/slave.c
@@ -193,10 +193,13 @@ dsa_slave_port_fdb_do_dump(const unsigned char *addr, u16 vid,
struct dsa_slave_dump_ctx *dump = data;
u32 portid = NETLINK_CB(dump->cb->skb).portid;
u32 seq = dump->cb->nlh->nlmsg_seq;
+ struct rtnl_fdb_dump_ctx *ctx;
struct nlmsghdr *nlh;
struct ndmsg *ndm;
- if (dump->idx < dump->cb->args[2])
+ ctx = (struct rtnl_fdb_dump_ctx *)dump->cb->ctx;
+
+ if (dump->idx < ctx->fidx)
goto skip;
nlh = nlmsg_put(dump->skb, portid, seq, RTM_NEWNEIGH,
--
2.25.1
Powered by blists - more mailing lists