git: 1f03c62e43a0 - main - netstat(1): Show metric value for routes
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Wed, 20 May 2026 20:58:54 UTC
The branch main has been updated by pouria:
URL: https://cgit.FreeBSD.org/src/commit/?id=1f03c62e43a02ec705b9998f37edde0258c442e9
commit 1f03c62e43a02ec705b9998f37edde0258c442e9
Author: Pouria Mousavizadeh Tehrani <pouria@FreeBSD.org>
AuthorDate: 2026-05-15 10:08:16 +0000
Commit: Pouria Mousavizadeh Tehrani <pouria@FreeBSD.org>
CommitDate: 2026-05-20 20:55:10 +0000
netstat(1): Show metric value for routes
Add metric support and show its value in wide flag and
libxo output.
Also, add metric to the description of wide flag (`-w`) in
routing display (`-r`) section of manual page.
Reviewed by: markj (manpage)
Discussed with: markj
Differential Revision: https://reviews.freebsd.org/D57011
---
usr.bin/netstat/common.h | 1 +
usr.bin/netstat/netstat.1 | 4 ++--
usr.bin/netstat/route.c | 12 ++++++++----
usr.bin/netstat/route_netlink.c | 9 ++++++---
4 files changed, 17 insertions(+), 9 deletions(-)
diff --git a/usr.bin/netstat/common.h b/usr.bin/netstat/common.h
index d5d39902037b..a2b560c1b849 100644
--- a/usr.bin/netstat/common.h
+++ b/usr.bin/netstat/common.h
@@ -52,6 +52,7 @@ struct _wid {
int pksent;
int mtu;
int iface;
+ int metric;
int expire;
};
void set_wid(int fam);
diff --git a/usr.bin/netstat/netstat.1 b/usr.bin/netstat/netstat.1
index 5c7f2336c06b..52e91c20d5eb 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 April 7, 2026
+.Dd May 18, 2026
.Dt NETSTAT 1
.Os
.Sh NAME
@@ -678,7 +678,7 @@ Do not resolve numeric addresses and port numbers to names.
See
.Sx GENERAL OPTIONS .
.It Fl W
-Show the path MTU for each route, and print interface names with a
+Show the metric and path MTU for each route, and print interface names with a
wider field size.
.It Fl F
Display the routing table with the number
diff --git a/usr.bin/netstat/route.c b/usr.bin/netstat/route.c
index 697c7ba2e9e1..1337a48faeed 100644
--- a/usr.bin/netstat/route.c
+++ b/usr.bin/netstat/route.c
@@ -205,13 +205,14 @@ pr_rthdr(int af1 __unused)
if (Wflag) {
xo_emit("{T:/%-*.*s} {T:/%-*.*s} {T:/%-*.*s} {T:/%*.*s} "
- "{T:/%*.*s} {T:/%*.*s} {T:/%*s}\n",
+ "{T:/%*.*s} {T:/%*.*s} {T:/%*.*s} {T:/%*s}\n",
wid.dst, wid.dst, "Destination",
wid.gw, wid.gw, "Gateway",
wid.flags, wid.flags, "Flags",
wid.mtu, wid.mtu, "Nhop#",
wid.mtu, wid.mtu, "Mtu",
wid.iface, wid.iface, "Netif",
+ wid.metric, wid.metric, "Metric",
wid.expire, "Expire");
} else {
xo_emit("{T:/%-*.*s} {T:/%-*.*s} {T:/%-*.*s} {T:/%*.*s} "
@@ -233,6 +234,7 @@ set_wid(int fam)
wid.pksent = 8;
wid.mtu = 6;
wid.iface = WID_IF_DEFAULT;
+ wid.metric = 8;
wid.expire = 6;
}
@@ -326,8 +328,9 @@ p_rtentry_sysctl(const char *name, struct rt_msghdr *rtm)
snprintf(buffer, sizeof(buffer), "{[:-%d}{:flags/%%s}{]:} ",
wid.flags - protrusion);
p_flags(rtm->rtm_flags, buffer);
- /* Output path weight as non-visual property */
+ /* Output path weight and metric as non-visual property */
xo_emit("{e:weight/%u}", rtm->rtm_rmx.rmx_weight);
+ xo_emit("{e:metric/%lu}", rtm->rtm_rmx.rmx_metric);
if (Wflag) {
/* XXX: use=0? */
xo_emit("{t:nhop/%*lu} ", wid.mtu, rtm->rtm_rmx.rmx_nhidx);
@@ -346,9 +349,10 @@ p_rtentry_sysctl(const char *name, struct rt_msghdr *rtm)
strlcpy(prettyname, "---", sizeof(prettyname));
}
- if (Wflag)
+ if (Wflag) {
xo_emit("{t:interface-name/%*s}", wid.iface, prettyname);
- else
+ xo_emit("{t:metric/%*lu} ", wid.metric, rtm->rtm_rmx.rmx_metric);
+ } else
xo_emit("{t:interface-name/%*.*s}", wid.iface, wid.iface,
prettyname);
if (rtm->rtm_rmx.rmx_expire) {
diff --git a/usr.bin/netstat/route_netlink.c b/usr.bin/netstat/route_netlink.c
index 2c4b7a5c6b00..f7349650f4c6 100644
--- a/usr.bin/netstat/route_netlink.c
+++ b/usr.bin/netstat/route_netlink.c
@@ -177,8 +177,9 @@ p_path(struct snl_parsed_route *rt, bool is_mpath)
snprintf(buffer, sizeof(buffer), "{[:-%d}{:flags/%%s}{]:} ",
wid.flags - protrusion);
p_flags(rt->rta_rtflags | RTF_UP, buffer);
- /* Output path weight as non-visual property */
+ /* Output path weight and metric as non-visual property */
xo_emit("{e:weight/%u}", rt->rtax_weight);
+ xo_emit("{e:metric/%lu}", rt->rta_metric);
if (is_mpath)
xo_emit("{e:nhg-kidx/%u}", rt->rta_knh_id);
else
@@ -213,9 +214,10 @@ p_path(struct snl_parsed_route *rt, bool is_mpath)
}
- if (Wflag)
+ if (Wflag) {
xo_emit("{t:interface-name/%*s}", wid.iface, prettyname);
- else
+ xo_emit("{t:metric/%*lu} ", wid.metric, rt->rta_metric);
+ } else
xo_emit("{t:interface-name/%*.*s}", wid.iface, wid.iface,
prettyname);
if (rt->rta_expire > 0) {
@@ -242,6 +244,7 @@ p_rtentry_netlink(struct snl_state *ss, const char *name, struct nlmsghdr *hdr)
rt.rta_gw = nhop->gw;
rt.rta_oif = nhop->ifindex;
rt.rtax_weight = nhop->rtnh_weight;
+ rt.rta_metric = nhop->rta_metric;
rt.rta_rtflags = nhop->rta_rtflags ? nhop->rta_rtflags : orig_rtflags;
rt.rtax_mtu = nhop->rtax_mtu ? nhop->rtax_mtu : orig_mtu;
rt.rta_expire = nhop->rta_expire;