diff --git a/sys/compat/linprocfs/linprocfs.c b/sys/compat/linprocfs/linprocfs.c --- 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 __FBSDID("$FreeBSD$"); @@ -86,6 +88,10 @@ #include #include +#include +#include +#include + #include #include #include @@ -1546,6 +1552,79 @@ return (0); } +struct walkarg { + struct sbuf *sb; + struct sockaddr_in dst; + struct sockaddr_in mask; +}; + +static int +linux_route_print(struct rtentry *rt, void *vw) +{ +#ifdef INET + struct walkarg *w = vw; + + char ifname[16]; + struct nhop_object *nh; + uint32_t scopeid = 0; + uint32_t gw = 0; + uint32_t rtflags; + + rt_get_inet_prefix_pmask(rt, &w->dst.sin_addr, + &w->mask.sin_addr, &scopeid); + nh = rt_get_raw_nhop(rt); + linux_ifname(nh->nh_ifp, ifname, sizeof(ifname)); + gw = (nh->nh_flags & NHF_GATEWAY) + ? satosin(&nh->gw_sa)->sin_addr.s_addr : 0; + rtflags = nhop_get_rtflags(nh); + + 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, + w->dst.sin_addr.s_addr, gw, ((rtflags | RTF_UP) & 0xf), + 0, 0, 0, + w->mask.sin_addr.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; + uint32_t fibnum = curthread->td_proc->p_fibnum; + + w.sb = sb; + + bzero(&w.dst, sizeof(struct sockaddr_in)); + bzero(&w.mask, sizeof(struct sockaddr_in)); + + w.dst.sin_family = AF_INET; + w.dst.sin_len = sizeof(struct sockaddr_in); + w.mask.sin_family = AF_INET; + w.mask.sin_len = sizeof(struct sockaddr_in); + + 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 +2179,8 @@ 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//... */ dir = pfs_create_dir(root, "pid", NULL, NULL, NULL, PFS_PROCDEP);