git: f71abf3f650f - main - netstat(1): Add nexthop statistics support with -os flag

From: Pouria Mousavizadeh Tehrani <pouria_at_FreeBSD.org>
Date: Fri, 21 Aug 2026 14:20:53 UTC
The branch main has been updated by pouria:

URL: https://cgit.FreeBSD.org/src/commit/?id=f71abf3f650f265974f90c24ad7d358d797bf22e

commit f71abf3f650f265974f90c24ad7d358d797bf22e
Author:     Pouria Mousavizadeh Tehrani <pouria@FreeBSD.org>
AuthorDate: 2026-08-19 22:01:10 +0000
Commit:     Pouria Mousavizadeh Tehrani <pouria@FreeBSD.org>
CommitDate: 2026-08-21 14:07:41 +0000

    netstat(1): Add nexthop statistics support with -os flag
    
    Add support nexthop statistics and update its manual.
    While here, fix manual of other nexthop related options.
    
    Reviewed by: kfv
    Differential Revision:  https://reviews.freebsd.org/D58538
---
 usr.bin/netstat/main.c    | 12 ++++++++---
 usr.bin/netstat/netstat.1 | 55 ++++++++++++++++++++++++++++++++++++++++++++++-
 usr.bin/netstat/netstat.h |  1 +
 usr.bin/netstat/nhops.c   | 24 +++++++++++++++++++++
 4 files changed, 88 insertions(+), 4 deletions(-)

diff --git a/usr.bin/netstat/main.c b/usr.bin/netstat/main.c
index 0084426540f6..6f24c5696644 100644
--- a/usr.bin/netstat/main.c
+++ b/usr.bin/netstat/main.c
@@ -531,7 +531,10 @@ main(int argc, char *argv[])
 	if (oflag) {
 		xo_open_container("statistics");
 		xo_set_version(NETSTAT_XO_VERSION);
-		nhops_print(fib, af);
+		if (sflag)
+			nhops_stats();
+		else
+			nhops_print(fib, af);
 		xo_close_container("statistics");
 		if (xo_finish() < 0)
 			xo_err(EX_IOERR, "stdout");
@@ -916,7 +919,7 @@ name2protox(const char *name)
 static void
 usage(void)
 {
-	xo_error("%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n",
+	xo_error("%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n",
 "usage: netstat [-j jail] [-46AaCcLnRSTWx] [-f protocol_family | -p protocol]\n"
 "               [-M core] [-N system]",
 "       netstat [-j jail] -i | -I interface [-46abdhnW] [-f address_family]\n"
@@ -934,6 +937,9 @@ usage(void)
 "       netstat [-j jail] -rs [-s] [-M core] [-N system]",
 "       netstat [-j jail] -g [-46W] [-f address_family] [-M core] [-N system]",
 "       netstat [-j jail] -gs [-46s] [-f address_family] [-M core] [-N system]",
-"       netstat [-j jail] -Q");
+"       netstat [-j jail] -Q",
+"       netstat [-j jail] -o -4 | -6",
+"       netstat [-j jail] -os [-s] [-M core] [-N system]",
+"       netstat [-j jail] -O -4 | -6");
 	exit(EX_USAGE);
 }
diff --git a/usr.bin/netstat/netstat.1 b/usr.bin/netstat/netstat.1
index 52e91c20d5eb..e9a63a64b18f 100644
--- a/usr.bin/netstat/netstat.1
+++ b/usr.bin/netstat/netstat.1
@@ -25,7 +25,7 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.Dd May 18, 2026
+.Dd August 20, 2026
 .Dt NETSTAT 1
 .Os
 .Sh NAME
@@ -108,8 +108,18 @@
 .Op Fl -libxo
 .It Nm Fl o
 .Fl 4 | Fl 6
+.Op Fl j Ar jail
+.Op Fl -libxo
+.It Nm Fl os
+.Op Fl j Ar jail
+.Op Fl -libxo
+.Op Fl s
+.Op Fl M Ar core
+.Op Fl N Ar system
 .It Nm Fl O
 .Fl 4 | Fl 6
+.Op Fl j Ar jail
+.Op Fl -libxo
 .El
 .Ek
 .Sh DESCRIPTION
@@ -401,6 +411,7 @@ See
 .Nm netstat
 .Fl o
 .Fl 4 | Fl 6
+.Op Fl j Ar jail
 .Ek
 .Xc
 Print nexthop (nhops) information associated with routing entries.
@@ -411,11 +422,47 @@ or
 limit the output to IPv4 or IPv6 routes respectively.
 This option provides details about individual nexthop addresses
 used in routing decisions.
+.Bl -tag -width indent
+.It Fl j Ar jail
+Run inside a jail.
+See
+.Sx GENERAL OPTIONS .
+.El
+.It Xo
+.Bk -words
+.Nm
+.Fl os
+.Op Fl s
+.Op Fl M Ar core
+.Op Fl N Ar system
+.Op Fl j Ar jail
+.Ek
+.Xc
+Display nexthop statistics.
+.Bl -tag -width indent
+.It Fl s
+If
+.Fl s
+is repeated, counters with a value of zero are suppressed.
+.It Fl M
+Use an alternative core
+See
+.Sx GENERAL OPTIONS .
+.It Fl N
+Use an alternative kernel image
+See
+.Sx GENERAL OPTIONS .
+.It Fl j Ar jail
+Run inside a jail.
+See
+.Sx GENERAL OPTIONS .
+.El
 .It Xo
 .Bk -words
 .Nm netstat
 .Fl O
 .Fl 4 | Fl 6
+.Op Fl j Ar jail
 .Ek
 .Xc
 Print nexthop groups (nhgrp) information associated with routing entries.
@@ -426,6 +473,12 @@ or
 restrict the output to IPv4 or IPv6 nexthop groups respectively.
 This option shows grouped nexthop entries for multipath or
 load-balanced routing setups.
+.Bl -tag -width indent
+.It Fl j Ar jail
+Run inside a jail.
+See
+.Sx GENERAL OPTIONS .
+.El
 .It Xo
 .Bk -words
 .Nm
diff --git a/usr.bin/netstat/netstat.h b/usr.bin/netstat/netstat.h
index 1255bfdf2e57..c9773169b639 100644
--- a/usr.bin/netstat/netstat.h
+++ b/usr.bin/netstat/netstat.h
@@ -165,4 +165,5 @@ void	mroutepr(void);
 void	mrt_stats(void);
 void	bpf_stats(char *);
 void	nhops_print(int fibnum, int af);
+void	nhops_stats(void);
 void	nhgrp_print(int fibnum, int af);
diff --git a/usr.bin/netstat/nhops.c b/usr.bin/netstat/nhops.c
index d40211e7ff77..84b8dfb970f2 100644
--- a/usr.bin/netstat/nhops.c
+++ b/usr.bin/netstat/nhops.c
@@ -61,6 +61,7 @@
 #include <libxo/xo.h>
 #include "netstat.h"
 #include "common.h"
+#include "nl_defs.h"
 
 /* column widths; each followed by one space */
 #define WID_IF_DEFAULT		(Wflag ? IFNAMSIZ : 12)	/* width of netif column */
@@ -476,3 +477,26 @@ nhops_print(int fibnum, int af)
 	xo_close_container("route-nhop-information");
 }
 
+/*
+ * Print nexthop statistics
+ */
+void
+nhops_stats(void)
+{
+	struct rtstat rtstat;
+
+	if (fetch_stats("net.route.stats", nl[N_RTSTAT].n_value, &rtstat,
+	    sizeof(rtstat), kread_counters) != 0)
+		return;
+
+	xo_emit("{T:nexthop}:\n");
+
+#define	p(f, m) if (rtstat.f || sflag <= 1) \
+	xo_emit(m, rtstat.f, plural(rtstat.f))
+
+	p(rts_nh_idx_alloc_failure, "\t{:nh-idx-alloc-failure/%ju} "
+	    "{N:/index allocation failure%s}\n");
+	p(rts_nh_alloc_failure, "\t{:nh-alloc-failure/%ju} "
+	    "{N:/nexthop allocation failure%s}\n");
+#undef p
+}