]> git.ipfire.org Git - thirdparty/iproute2.git/commitdiff
ip: ipnexthop: Support dumping next hop group HW stats
authorPetr Machata <petrm@nvidia.com>
Thu, 14 Mar 2024 14:52:14 +0000 (15:52 +0100)
committerDavid Ahern <dsahern@kernel.org>
Fri, 15 Mar 2024 15:03:34 +0000 (15:03 +0000)
Besides SW datapath stats, the kernel also support collecting statistics
from HW datapath, for nexthop groups offloaded to HW. Request that these be
collected when ip is given "-s -s", similarly to how "ip link" shows more
statistics in that case.

Besides the statistics themselves, also show whether the collection of HW
statistics was in fact requested, and whether any driver actually
implemented the request.

Signed-off-by: Petr Machata <petrm@nvidia.com>
Signed-off-by: David Ahern <dsahern@kernel.org>
ip/ipnexthop.c
ip/nh_common.h

index cba3d934e8ddd7a00146d8097d06824ce2623430..6c5d524b104d825a80ab473b69c01a881090a675 100644 (file)
@@ -327,6 +327,11 @@ static void parse_nh_group_stats_rta(const struct rtattr *grp_stats_attr,
                        rta = tb[NHA_GROUP_STATS_ENTRY_PACKETS];
                        nh_grp_stats->packets = rta_getattr_uint(rta);
                }
+
+               if (tb[NHA_GROUP_STATS_ENTRY_PACKETS_HW]) {
+                       rta = tb[NHA_GROUP_STATS_ENTRY_PACKETS_HW];
+                       nh_grp_stats->packets_hw = rta_getattr_uint(rta);
+               }
        }
 }
 
@@ -395,6 +400,9 @@ static void print_nh_grp_stats(const struct nh_entry *nhe)
                           nhe->nh_grp_stats[i].nh_id);
                print_u64(PRINT_ANY, "packets", " packets %llu",
                          nhe->nh_grp_stats[i].packets);
+               if (show_stats > 1)
+                       print_u64(PRINT_ANY, "packets_hw", " packets_hw %llu",
+                                 nhe->nh_grp_stats[i].packets_hw);
 
                if (i != nhe->nh_groups_cnt - 1)
                        print_nl();
@@ -479,6 +487,15 @@ static int ipnh_parse_nhmsg(FILE *fp, const struct nhmsg *nhm, int len,
                nhe->nh_has_res_grp = true;
        }
 
+       if (tb[NHA_HW_STATS_ENABLE]) {
+               nhe->nh_hw_stats_supported = true;
+               nhe->nh_hw_stats_enabled =
+                       !!rta_getattr_u32(tb[NHA_HW_STATS_ENABLE]);
+       }
+
+       if (tb[NHA_HW_STATS_USED])
+               nhe->nh_hw_stats_used = !!rta_getattr_u32(tb[NHA_HW_STATS_USED]);
+
        if (tb[NHA_GROUP_STATS]) {
                nhe->nh_grp_stats = calloc(nhe->nh_groups_cnt,
                                           sizeof(*nhe->nh_grp_stats));
@@ -555,6 +572,15 @@ static void __print_nexthop_entry(FILE *fp, const char *jsobj,
        if (nhe->nh_fdb)
                print_null(PRINT_ANY, "fdb", "fdb", NULL);
 
+       if ((show_details > 0 || show_stats) && nhe->nh_hw_stats_supported) {
+               open_json_object("hw_stats");
+               print_on_off(PRINT_ANY, "enabled", "hw_stats %s ",
+                            nhe->nh_hw_stats_enabled);
+               print_on_off(PRINT_ANY, "used", "used %s ",
+                            nhe->nh_hw_stats_used);
+               close_json_object();
+       }
+
        if (nhe->nh_grp_stats)
                print_nh_grp_stats(nhe);
 
@@ -567,6 +593,8 @@ static __u32 ipnh_get_op_flags(void)
 
        if (show_stats) {
                op_flags |= NHA_OP_FLAG_DUMP_STATS;
+               if (show_stats > 1)
+                       op_flags |= NHA_OP_FLAG_DUMP_HW_STATS;
        }
 
        return op_flags;
index e2f74ec5ac214645081c588eefbfd8381b45fc80..33b1d847466096cb23d14393f6d19beca9b78a83 100644 (file)
@@ -16,6 +16,7 @@ struct nha_res_grp {
 struct nh_grp_stats {
        __u32                   nh_id;
        __u64                   packets;
+       __u64                   packets_hw;
 };
 
 struct nh_entry {
@@ -32,6 +33,10 @@ struct nh_entry {
        bool                    nh_blackhole;
        bool                    nh_fdb;
 
+       bool                    nh_hw_stats_supported;
+       bool                    nh_hw_stats_enabled;
+       bool                    nh_hw_stats_used;
+
        int                     nh_gateway_len;
        union {
                __be32          ipv4;