diff options
author | John Grafton <john.grafton@runbox.com> | 2022-10-22 10:52:58 +0000 |
---|---|---|
committer | Dmitry Chagin <dchagin@FreeBSD.org> | 2023-01-24 07:34:29 +0000 |
commit | dab4775da30809c65df81837c74a9d634375a704 (patch) | |
tree | a45a6f2dd672d88cd6b0dfa5ea6f8e4468b01899 /sys/compat/linprocfs/linprocfs.c | |
parent | 6192776124c5b79521ca290dfbf5f62560c4a163 (diff) |
linprocfs: Add net/route.
PR: 266482
Reviewed by: melifaro, me
Differential revision: https://reviews.freebsd.org/D36949
MFC after: 1 week
(cherry picked from commit 4c9db9566e67779905c667c2719e5b1628c3af3d)
Diffstat (limited to 'sys/compat/linprocfs/linprocfs.c')
-rw-r--r-- | sys/compat/linprocfs/linprocfs.c | 79 |
1 files changed, 79 insertions, 0 deletions
diff --git a/sys/compat/linprocfs/linprocfs.c b/sys/compat/linprocfs/linprocfs.c index 6f6cd3f5f55f..a93f8a1dbb8b 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); |