git: 4c9db9566e67 - main - linprocfs: Add net/route.

From: Dmitry Chagin <dchagin_at_FreeBSD.org>
Date: Sat, 22 Oct 2022 10:54:20 UTC
The branch main has been updated by dchagin:

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

commit 4c9db9566e67779905c667c2719e5b1628c3af3d
Author:     John Grafton <john.grafton@runbox.com>
AuthorDate: 2022-10-22 10:52:58 +0000
Commit:     Dmitry Chagin <dchagin@FreeBSD.org>
CommitDate: 2022-10-22 10:52:58 +0000

    linprocfs: Add net/route.
    
    PR:                     266482
    Reviewed by:            melifaro, me
    Differential revision:  https://reviews.freebsd.org/D36949
    MFC after:              1 week
---
 sys/compat/linprocfs/linprocfs.c | 79 ++++++++++++++++++++++++++++++++++++++++
 sys/modules/linprocfs/Makefile   |  2 +-
 2 files changed, 80 insertions(+), 1 deletion(-)

diff --git a/sys/compat/linprocfs/linprocfs.c b/sys/compat/linprocfs/linprocfs.c
index 23e407771fcc..15c4d3c41749 100644
--- a/sys/compat/linprocfs/linprocfs.c
+++ b/sys/compat/linprocfs/linprocfs.c
@@ -41,6 +41,8 @@
  *	@(#)procfs_status.c	8.4 (Berkeley) 6/15/94
  */
 
+#include "opt_inet.h"
+
 #include <sys/cdefs.h>
 __FBSDID("$FreeBSD$");
 
@@ -86,6 +88,10 @@ __FBSDID("$FreeBSD$");
 #include <net/if_var.h>
 #include <net/if_types.h>
 
+#include <net/route.h>
+#include <net/route/nhop.h>
+#include <net/route/route_ctl.h>
+
 #include <vm/vm.h>
 #include <vm/vm_extern.h>
 #include <vm/pmap.h>
@@ -1546,6 +1552,77 @@ linprocfs_donetdev(PFS_FILL_ARGS)
 	return (0);
 }
 
+struct walkarg {
+	struct sbuf *sb;
+};
+
+static int
+linux_route_print(struct rtentry *rt, void *vw)
+{
+#ifdef INET
+	struct walkarg *w = vw;
+	struct route_nhop_data rnd;
+	struct in_addr dst, mask;
+	struct nhop_object *nh;
+	char ifname[16];
+	uint32_t scopeid = 0;
+	uint32_t gw = 0;
+	uint32_t linux_flags = 0;
+
+	rt_get_inet_prefix_pmask(rt, &dst, &mask, &scopeid);
+
+	rt_get_rnd(rt, &rnd);
+
+	/* select only first route in case of multipath */
+	nh = nhop_select_func(rnd.rnd_nhop, 0);
+
+	linux_ifname(nh->nh_ifp, ifname, sizeof(ifname));
+
+	gw = (nh->nh_flags & NHF_GATEWAY)
+		? nh->gw4_sa.sin_addr.s_addr : 0;
+
+	linux_flags = RTF_UP |
+		(nhop_get_rtflags(nh) & (RTF_GATEWAY | RTF_HOST));
+
+	sbuf_printf(w->sb,
+		"%s\t"
+		"%08X\t%08X\t%04X\t"
+		"%d\t%u\t%d\t"
+		"%08X\t%d\t%u\t%u",
+		ifname,
+		dst.s_addr, gw, linux_flags,
+		0, 0, rnd.rnd_weight,
+		mask.s_addr, nh->nh_mtu, 0, 0);
+
+	sbuf_printf(w->sb, "\n\n");
+#endif
+	return (0);
+}
+
+/*
+ * Filler function for proc/net/route
+ */
+static int
+linprocfs_donetroute(PFS_FILL_ARGS)
+{
+	struct walkarg w = {
+		.sb = sb
+	};
+	uint32_t fibnum = curthread->td_proc->p_fibnum;
+
+	sbuf_printf(w.sb, "%-127s\n", "Iface\tDestination\tGateway "
+               "\tFlags\tRefCnt\tUse\tMetric\tMask\t\tMTU"
+               "\tWindow\tIRTT");
+
+	CURVNET_SET(TD_TO_VNET(curthread));
+	IFNET_RLOCK();
+	rib_walk(fibnum, AF_INET, false, linux_route_print, &w);
+	IFNET_RUNLOCK();
+	CURVNET_RESTORE();
+
+	return (0);
+}
+
 /*
  * Filler function for proc/sys/kernel/osrelease
  */
@@ -2100,6 +2177,8 @@ linprocfs_init(PFS_INIT_ARGS)
 	dir = pfs_create_dir(root, "net", NULL, NULL, NULL, 0);
 	pfs_create_file(dir, "dev", &linprocfs_donetdev,
 	    NULL, NULL, NULL, PFS_RD);
+	pfs_create_file(dir, "route", &linprocfs_donetroute,
+	    NULL, NULL, NULL, PFS_RD);
 
 	/* /proc/<pid>/... */
 	dir = pfs_create_dir(root, "pid", NULL, NULL, NULL, PFS_PROCDEP);
diff --git a/sys/modules/linprocfs/Makefile b/sys/modules/linprocfs/Makefile
index fa7ac8725d14..16f9f8c703be 100644
--- a/sys/modules/linprocfs/Makefile
+++ b/sys/modules/linprocfs/Makefile
@@ -4,7 +4,7 @@
 
 KMOD=	linprocfs
 SRCS=	vnode_if.h \
-	device_if.h bus_if.h \
+	device_if.h bus_if.h opt_inet.h \
 	linprocfs.c
 
 .if !defined(KERNBUILDDIR)