From: Petr Machata <petrm@nvidia.com>
To: "David S. Miller" <davem@davemloft.net>,
Eric Dumazet <edumazet@google.com>,
Jakub Kicinski <kuba@kernel.org>, Paolo Abeni <pabeni@redhat.com>,
<netdev@vger.kernel.org>
Cc: Ido Schimmel <idosch@nvidia.com>, Petr Machata <petrm@nvidia.com>,
"David Ahern" <dsahern@kernel.org>, <mlxsw@nvidia.com>
Subject: [PATCH net-next 4/7] net: nexthop: Expose nexthop group stats to user space
Date: Tue, 27 Feb 2024 19:17:29 +0100 [thread overview]
Message-ID: <b194971db40744eb8aa6e1e562564cac7118c42f.1709057158.git.petrm@nvidia.com> (raw)
In-Reply-To: <cover.1709057158.git.petrm@nvidia.com>
From: Ido Schimmel <idosch@nvidia.com>
Add netlink support for reading NH group stats.
This data is only for statistics of the traffic in the SW datapath. HW
nexthop group statistics will be added in the following patches.
Emission of the stats is keyed to a new op_stats flag to avoid cluttering
the netlink message with stats if the user doesn't need them:
NHA_OP_FLAG_DUMP_STATS.
Co-developed-by: Petr Machata <petrm@nvidia.com>
Signed-off-by: Petr Machata <petrm@nvidia.com>
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
---
include/uapi/linux/nexthop.h | 32 +++++++++++++
net/ipv4/nexthop.c | 91 ++++++++++++++++++++++++++++++++----
2 files changed, 115 insertions(+), 8 deletions(-)
diff --git a/include/uapi/linux/nexthop.h b/include/uapi/linux/nexthop.h
index 0d7969911fd2..b19871b7e7f5 100644
--- a/include/uapi/linux/nexthop.h
+++ b/include/uapi/linux/nexthop.h
@@ -30,6 +30,8 @@ enum {
#define NEXTHOP_GRP_TYPE_MAX (__NEXTHOP_GRP_TYPE_MAX - 1)
+#define NHA_OP_FLAG_DUMP_STATS BIT(0)
+
enum {
NHA_UNSPEC,
NHA_ID, /* u32; id for nexthop. id == 0 means auto-assign */
@@ -63,6 +65,9 @@ enum {
/* bitfield32; operation-specific flags */
NHA_OP_FLAGS,
+ /* nested; nexthop group stats */
+ NHA_GROUP_STATS,
+
__NHA_MAX,
};
@@ -104,4 +109,31 @@ enum {
#define NHA_RES_BUCKET_MAX (__NHA_RES_BUCKET_MAX - 1)
+enum {
+ NHA_GROUP_STATS_UNSPEC,
+
+ /* nested; nexthop group entry stats */
+ NHA_GROUP_STATS_ENTRY,
+
+ __NHA_GROUP_STATS_MAX,
+};
+
+#define NHA_GROUP_STATS_MAX (__NHA_GROUP_STATS_MAX - 1)
+
+enum {
+ NHA_GROUP_STATS_ENTRY_UNSPEC,
+ /* Pad attribute for 64-bit alignment */
+ NHA_GROUP_STATS_ENTRY_PAD = NHA_GROUP_STATS_ENTRY_UNSPEC,
+
+ /* u32; nexthop id of the nexthop group entry */
+ NHA_GROUP_STATS_ENTRY_ID,
+
+ /* u64; number of packets forwarded via the nexthop group entry */
+ NHA_GROUP_STATS_ENTRY_PACKETS,
+
+ __NHA_GROUP_STATS_ENTRY_MAX,
+};
+
+#define NHA_GROUP_STATS_ENTRY_MAX (__NHA_GROUP_STATS_ENTRY_MAX - 1)
+
#endif
diff --git a/net/ipv4/nexthop.c b/net/ipv4/nexthop.c
index 29d0ed049b91..9c7ec9f15f55 100644
--- a/net/ipv4/nexthop.c
+++ b/net/ipv4/nexthop.c
@@ -41,7 +41,7 @@ static const struct nla_policy rtm_nh_policy_new[] = {
static const struct nla_policy rtm_nh_policy_get[] = {
[NHA_ID] = { .type = NLA_U32 },
- [NHA_OP_FLAGS] = NLA_POLICY_BITFIELD32(0),
+ [NHA_OP_FLAGS] = NLA_POLICY_BITFIELD32(NHA_OP_FLAG_DUMP_STATS),
};
static const struct nla_policy rtm_nh_policy_del[] = {
@@ -53,7 +53,7 @@ static const struct nla_policy rtm_nh_policy_dump[] = {
[NHA_GROUPS] = { .type = NLA_FLAG },
[NHA_MASTER] = { .type = NLA_U32 },
[NHA_FDB] = { .type = NLA_FLAG },
- [NHA_OP_FLAGS] = NLA_POLICY_BITFIELD32(0),
+ [NHA_OP_FLAGS] = NLA_POLICY_BITFIELD32(NHA_OP_FLAG_DUMP_STATS),
};
static const struct nla_policy rtm_nh_res_policy_new[] = {
@@ -661,8 +661,78 @@ static int nla_put_nh_group_res(struct sk_buff *skb, struct nh_group *nhg)
return -EMSGSIZE;
}
-static int nla_put_nh_group(struct sk_buff *skb, struct nh_group *nhg)
+static void nh_grp_entry_stats_read(struct nh_grp_entry *nhge,
+ struct nh_grp_entry_stats *stats)
{
+ int i;
+
+ memset(stats, 0, sizeof(*stats));
+ for_each_possible_cpu(i) {
+ struct nh_grp_entry_stats *cpu_stats;
+ unsigned int start;
+ u64 packets;
+
+ cpu_stats = per_cpu_ptr(nhge->stats, i);
+ do {
+ start = u64_stats_fetch_begin(&cpu_stats->syncp);
+ packets = cpu_stats->packets;
+ } while (u64_stats_fetch_retry(&cpu_stats->syncp, start));
+
+ stats->packets += packets;
+ }
+}
+
+static int nla_put_nh_group_stats_entry(struct sk_buff *skb,
+ struct nh_grp_entry *nhge)
+{
+ struct nh_grp_entry_stats stats;
+ struct nlattr *nest;
+
+ nh_grp_entry_stats_read(nhge, &stats);
+
+ nest = nla_nest_start(skb, NHA_GROUP_STATS_ENTRY);
+ if (!nest)
+ return -EMSGSIZE;
+
+ if (nla_put_u32(skb, NHA_GROUP_STATS_ENTRY_ID, nhge->nh->id) ||
+ nla_put_u64_64bit(skb, NHA_GROUP_STATS_ENTRY_PACKETS, stats.packets,
+ NHA_GROUP_STATS_ENTRY_PAD))
+ goto nla_put_failure;
+
+ nla_nest_end(skb, nest);
+ return 0;
+
+nla_put_failure:
+ nla_nest_cancel(skb, nest);
+ return -EMSGSIZE;
+}
+
+static int nla_put_nh_group_stats(struct sk_buff *skb, struct nexthop *nh)
+{
+ struct nh_group *nhg = rtnl_dereference(nh->nh_grp);
+ struct nlattr *nest;
+ int i;
+
+ nest = nla_nest_start(skb, NHA_GROUP_STATS);
+ if (!nest)
+ return -EMSGSIZE;
+
+ for (i = 0; i < nhg->num_nh; i++)
+ if (nla_put_nh_group_stats_entry(skb, &nhg->nh_entries[i]))
+ goto nla_put_failure;
+
+ nla_nest_end(skb, nest);
+ return 0;
+
+nla_put_failure:
+ nla_nest_cancel(skb, nest);
+ return -EMSGSIZE;
+}
+
+static int nla_put_nh_group(struct sk_buff *skb, struct nexthop *nh,
+ u32 op_flags)
+{
+ struct nh_group *nhg = rtnl_dereference(nh->nh_grp);
struct nexthop_grp *p;
size_t len = nhg->num_nh * sizeof(*p);
struct nlattr *nla;
@@ -691,6 +761,10 @@ static int nla_put_nh_group(struct sk_buff *skb, struct nh_group *nhg)
if (nhg->resilient && nla_put_nh_group_res(skb, nhg))
goto nla_put_failure;
+ if (op_flags & NHA_OP_FLAG_DUMP_STATS &&
+ nla_put_nh_group_stats(skb, nh))
+ goto nla_put_failure;
+
return 0;
nla_put_failure:
@@ -698,7 +772,8 @@ static int nla_put_nh_group(struct sk_buff *skb, struct nh_group *nhg)
}
static int nh_fill_node(struct sk_buff *skb, struct nexthop *nh,
- int event, u32 portid, u32 seq, unsigned int nlflags)
+ int event, u32 portid, u32 seq, unsigned int nlflags,
+ u32 op_flags)
{
struct fib6_nh *fib6_nh;
struct fib_nh *fib_nh;
@@ -725,7 +800,7 @@ static int nh_fill_node(struct sk_buff *skb, struct nexthop *nh,
if (nhg->fdb_nh && nla_put_flag(skb, NHA_FDB))
goto nla_put_failure;
- if (nla_put_nh_group(skb, nhg))
+ if (nla_put_nh_group(skb, nh, op_flags))
goto nla_put_failure;
goto out;
}
@@ -856,7 +931,7 @@ static void nexthop_notify(int event, struct nexthop *nh, struct nl_info *info)
if (!skb)
goto errout;
- err = nh_fill_node(skb, nh, event, info->portid, seq, nlflags);
+ err = nh_fill_node(skb, nh, event, info->portid, seq, nlflags, 0);
if (err < 0) {
/* -EMSGSIZE implies BUG in nh_nlmsg_size() */
WARN_ON(err == -EMSGSIZE);
@@ -3084,7 +3159,7 @@ static int rtm_get_nexthop(struct sk_buff *in_skb, struct nlmsghdr *nlh,
goto errout_free;
err = nh_fill_node(skb, nh, RTM_NEWNEXTHOP, NETLINK_CB(in_skb).portid,
- nlh->nlmsg_seq, 0);
+ nlh->nlmsg_seq, 0, op_flags);
if (err < 0) {
WARN_ON(err == -EMSGSIZE);
goto errout_free;
@@ -3254,7 +3329,7 @@ static int rtm_dump_nexthop_cb(struct sk_buff *skb, struct netlink_callback *cb,
return nh_fill_node(skb, nh, RTM_NEWNEXTHOP,
NETLINK_CB(cb->skb).portid,
- cb->nlh->nlmsg_seq, NLM_F_MULTI);
+ cb->nlh->nlmsg_seq, NLM_F_MULTI, filter->op_flags);
}
/* rtnl */
--
2.43.0
next prev parent reply other threads:[~2024-02-27 18:18 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-02-27 18:17 [PATCH net-next 0/7] Support for nexthop group statistics Petr Machata
2024-02-27 18:17 ` [PATCH net-next 1/7] net: nexthop: Adjust netlink policy parsing for a new attribute Petr Machata
2024-02-27 18:17 ` [PATCH net-next 2/7] net: nexthop: Add NHA_OP_FLAGS Petr Machata
2024-02-28 3:34 ` Jakub Kicinski
2024-02-28 10:50 ` Petr Machata
2024-02-28 14:48 ` Jakub Kicinski
2024-02-28 15:16 ` Jakub Kicinski
2024-02-28 15:58 ` Petr Machata
2024-02-28 16:42 ` Jakub Kicinski
2024-02-29 14:03 ` Petr Machata
2024-02-27 18:17 ` [PATCH net-next 3/7] net: nexthop: Add nexthop group entry stats Petr Machata
2024-02-28 14:30 ` Simon Horman
2024-02-28 15:57 ` Petr Machata
2024-02-27 18:17 ` Petr Machata [this message]
2024-02-28 3:35 ` [PATCH net-next 4/7] net: nexthop: Expose nexthop group stats to user space Jakub Kicinski
2024-02-28 11:24 ` Petr Machata
2024-02-27 18:17 ` [PATCH net-next 5/7] net: nexthop: Add hardware statistics notifications Petr Machata
2024-02-27 18:17 ` [PATCH net-next 6/7] net: nexthop: Add ability to enable / disable hardware statistics Petr Machata
2024-02-27 18:17 ` [PATCH net-next 7/7] net: nexthop: Expose nexthop group HW stats to user space Petr Machata
2024-02-28 3:39 ` Jakub Kicinski
2024-02-28 17:16 ` Petr Machata
2024-02-28 3:56 ` Kees Cook
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=b194971db40744eb8aa6e1e562564cac7118c42f.1709057158.git.petrm@nvidia.com \
--to=petrm@nvidia.com \
--cc=davem@davemloft.net \
--cc=dsahern@kernel.org \
--cc=edumazet@google.com \
--cc=idosch@nvidia.com \
--cc=kuba@kernel.org \
--cc=mlxsw@nvidia.com \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).