Changeset View
Standalone View
sys/compat/linprocfs/linprocfs.c
Show All 35 Lines | ||||||||||||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |||||||||||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |||||||||||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |||||||||||||
* SUCH DAMAGE. | * SUCH DAMAGE. | |||||||||||||
* | * | |||||||||||||
* @(#)procfs_status.c 8.4 (Berkeley) 6/15/94 | * @(#)procfs_status.c 8.4 (Berkeley) 6/15/94 | |||||||||||||
*/ | */ | |||||||||||||
#include "opt_inet.h" | ||||||||||||||
#include <sys/cdefs.h> | #include <sys/cdefs.h> | |||||||||||||
__FBSDID("$FreeBSD$"); | __FBSDID("$FreeBSD$"); | |||||||||||||
#include <sys/param.h> | #include <sys/param.h> | |||||||||||||
#include <sys/queue.h> | #include <sys/queue.h> | |||||||||||||
#include <sys/blist.h> | #include <sys/blist.h> | |||||||||||||
#include <sys/conf.h> | #include <sys/conf.h> | |||||||||||||
#include <sys/exec.h> | #include <sys/exec.h> | |||||||||||||
Show All 29 Lines | ||||||||||||||
#include <sys/vnode.h> | #include <sys/vnode.h> | |||||||||||||
#include <sys/bus.h> | #include <sys/bus.h> | |||||||||||||
#include <sys/uio.h> | #include <sys/uio.h> | |||||||||||||
#include <net/if.h> | #include <net/if.h> | |||||||||||||
#include <net/if_var.h> | #include <net/if_var.h> | |||||||||||||
#include <net/if_types.h> | #include <net/if_types.h> | |||||||||||||
#include <net/route.h> | ||||||||||||||
#include <net/route/nhop.h> | ||||||||||||||
#include <net/route/route_ctl.h> | ||||||||||||||
melifaro: You shouldn’t include it, that’s a private header for the routing code. | ||||||||||||||
#include <vm/vm.h> | #include <vm/vm.h> | |||||||||||||
#include <vm/vm_extern.h> | #include <vm/vm_extern.h> | |||||||||||||
#include <vm/pmap.h> | #include <vm/pmap.h> | |||||||||||||
#include <vm/vm_map.h> | #include <vm/vm_map.h> | |||||||||||||
#include <vm/vm_param.h> | #include <vm/vm_param.h> | |||||||||||||
#include <vm/vm_object.h> | #include <vm/vm_object.h> | |||||||||||||
#include <vm/swap_pager.h> | #include <vm/swap_pager.h> | |||||||||||||
▲ Show 20 Lines • Show All 1,444 Lines • ▼ Show 20 Lines | sbuf_printf(sb, "%8ju %7ju %4ju %4ju %4lu %5ju %7lu %10lu\n", | |||||||||||||
0UL); /* tx_compressed */ | 0UL); /* tx_compressed */ | |||||||||||||
} | } | |||||||||||||
IFNET_RUNLOCK(); | IFNET_RUNLOCK(); | |||||||||||||
CURVNET_RESTORE(); | CURVNET_RESTORE(); | |||||||||||||
return (0); | return (0); | |||||||||||||
} | } | |||||||||||||
struct walkarg { | ||||||||||||||
struct sbuf *sb; | ||||||||||||||
}; | ||||||||||||||
Done Inline ActionsProbably worth using ‘struct in_addr’ here melifaro: Probably worth using ‘struct in_addr’ here | ||||||||||||||
Done Inline ActionsNit: any reason not to have dst and mask as stack variables in linux_route_print() ? melifaro: Nit: any reason not to have `dst` and `mask` as stack variables in `linux_route_print()` ? | ||||||||||||||
Done Inline ActionsNo good reason. :) john.grafton_runbox.com: No good reason. :) | ||||||||||||||
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); | ||||||||||||||
Done Inline ActionsRe multipath: to be safe probably worth using nhop_select(raw_nhop, 0) to ensure it doesnt crash with multipath routes melifaro: Re multipath: to be safe probably worth using nhop_select(raw_nhop, 0) to ensure it doesnt… | ||||||||||||||
/* select only first route in case of multipath */ | ||||||||||||||
nh = nhop_select_func(rnd.rnd_nhop, 0); | ||||||||||||||
Done Inline Actions
melifaro: | ||||||||||||||
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, | ||||||||||||||
Done Inline ActionsI’d suggest defining 0xF explicitely as a flag combination melifaro: I’d suggest defining 0xF explicitely as a flag combination | ||||||||||||||
"%s\t" | ||||||||||||||
Done Inline ActionsYou shouldn’t access rtentry fields directly, use rt_get_weight(). melifaro: You shouldn’t access rtentry fields directly, use rt_get_weight(). | ||||||||||||||
"%08X\t%08X\t%04X\t" | ||||||||||||||
"%d\t%u\t%d\t" | ||||||||||||||
"%08X\t%d\t%u\t%u", | ||||||||||||||
ifname, | ||||||||||||||
Done Inline Actions
melifaro: | ||||||||||||||
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 | ||||||||||||||
Done Inline Actionsafter malloc? dchagin: after malloc? | ||||||||||||||
Done Inline Actions
Worth using c11 initialisers: melifaro: Worth using c11 initialisers:
| ||||||||||||||
linprocfs_donetroute(PFS_FILL_ARGS) | ||||||||||||||
{ | ||||||||||||||
struct walkarg w = { | ||||||||||||||
Done Inline Actionsbtw, Is that enough? rtsock messages can be up to 64k dchagin: btw, Is that enough? rtsock messages can be up to 64k | ||||||||||||||
.sb = sb | ||||||||||||||
}; | ||||||||||||||
uint32_t fibnum = curthread->td_proc->p_fibnum; | ||||||||||||||
Done Inline Actionsplease, move decl before code dchagin: please, move decl before code | ||||||||||||||
sbuf_printf(w.sb, "%-127s\n", "Iface\tDestination\tGateway " | ||||||||||||||
"\tFlags\tRefCnt\tUse\tMetric\tMask\t\tMTU" | ||||||||||||||
Done Inline ActionsI’d rather use ‘rib_walk(fibnum, af, linux_route_print)’ public KPI instead of using it indirectly via sysctl. melifaro: I’d rather use ‘rib_walk(fibnum, af, linux_route_print)’ public KPI instead of using it… | ||||||||||||||
Done Inline ActionsAh, thank you. rib_walk was my first inclination but I wasn't sure if it'd return the information I needed. netstat(1) uses sysctl and thus provided an example on how to decode the results. john.grafton_runbox.com: Ah, thank you. rib_walk was my first inclination but I wasn't sure if it'd return the… | ||||||||||||||
Done Inline ActionsIt does. You'll get 'struct rtentry' in the iterator, which allows extracting prefix data via melifaro: It does.
You'll get 'struct rtentry' in the iterator, which allows extracting prefix data via… | ||||||||||||||
"\tWindow\tIRTT"); | ||||||||||||||
CURVNET_SET(TD_TO_VNET(curthread)); | ||||||||||||||
IFNET_RLOCK(); | ||||||||||||||
rib_walk(fibnum, AF_INET, false, linux_route_print, &w); | ||||||||||||||
IFNET_RUNLOCK(); | ||||||||||||||
Not Done Inline ActionsYou don’t need to hold ifnet lock, but you need to be in network epoch (NET_EPOCH_ENTER()) melifaro: You don’t need to hold ifnet lock, but you need to be in network epoch (NET_EPOCH_ENTER()) | ||||||||||||||
Done Inline ActionsWithout the ifnet lock, linux_ifname() panics due to IFNET_RLOCK_ASSERT() panic: Lock (sx) ifnet_sx not locked john.grafton_runbox.com: Without the ifnet lock, linux_ifname() panics due to IFNET_RLOCK_ASSERT()
panic: Lock (sx)… | ||||||||||||||
CURVNET_RESTORE(); | ||||||||||||||
return (0); | ||||||||||||||
} | ||||||||||||||
Done Inline Actionsmalloc in case of M_WAITOK can't return NULL dchagin: malloc in case of M_WAITOK can't return NULL | ||||||||||||||
/* | ||||||||||||||
* Filler function for proc/sys/kernel/osrelease | * Filler function for proc/sys/kernel/osrelease | |||||||||||||
Done Inline Actionserror = kern_sysctl goto out; dchagin: error = kern_sysctl
if (error != 0)
goto out; | ||||||||||||||
*/ | */ | |||||||||||||
static int | static int | |||||||||||||
linprocfs_doosrelease(PFS_FILL_ARGS) | linprocfs_doosrelease(PFS_FILL_ARGS) | |||||||||||||
{ | { | |||||||||||||
char osrelease[LINUX_MAX_UTSNAME]; | char osrelease[LINUX_MAX_UTSNAME]; | |||||||||||||
linux_get_osrelease(td, osrelease); | linux_get_osrelease(td, osrelease); | |||||||||||||
sbuf_printf(sb, "%s\n", osrelease); | sbuf_printf(sb, "%s\n", osrelease); | |||||||||||||
return (0); | return (0); | |||||||||||||
} | } | |||||||||||||
/* | /* | |||||||||||||
* Filler function for proc/sys/kernel/ostype | * Filler function for proc/sys/kernel/ostype | |||||||||||||
*/ | */ | |||||||||||||
static int | static int | |||||||||||||
linprocfs_doostype(PFS_FILL_ARGS) | linprocfs_doostype(PFS_FILL_ARGS) | |||||||||||||
{ | { | |||||||||||||
char osname[LINUX_MAX_UTSNAME]; | char osname[LINUX_MAX_UTSNAME]; | |||||||||||||
Done Inline Actionsout before free() dchagin: out before free() | ||||||||||||||
linux_get_osname(td, osname); | linux_get_osname(td, osname); | |||||||||||||
sbuf_printf(sb, "%s\n", osname); | sbuf_printf(sb, "%s\n", osname); | |||||||||||||
return (0); | return (0); | |||||||||||||
Done Inline Actionsreturn (error); dchagin: return (error); | ||||||||||||||
} | } | |||||||||||||
/* | /* | |||||||||||||
* Filler function for proc/sys/kernel/version | * Filler function for proc/sys/kernel/version | |||||||||||||
*/ | */ | |||||||||||||
static int | static int | |||||||||||||
linprocfs_doosbuild(PFS_FILL_ARGS) | linprocfs_doosbuild(PFS_FILL_ARGS) | |||||||||||||
{ | { | |||||||||||||
▲ Show 20 Lines • Show All 511 Lines • ▼ Show 20 Lines | linprocfs_init(PFS_INIT_ARGS) | |||||||||||||
/* /proc/bus/... */ | /* /proc/bus/... */ | |||||||||||||
dir = pfs_create_dir(root, "bus", NULL, NULL, NULL, 0); | dir = pfs_create_dir(root, "bus", NULL, NULL, NULL, 0); | |||||||||||||
dir = pfs_create_dir(dir, "pci", NULL, NULL, NULL, 0); | dir = pfs_create_dir(dir, "pci", NULL, NULL, NULL, 0); | |||||||||||||
dir = pfs_create_dir(dir, "devices", NULL, NULL, NULL, 0); | dir = pfs_create_dir(dir, "devices", NULL, NULL, NULL, 0); | |||||||||||||
/* /proc/net/... */ | /* /proc/net/... */ | |||||||||||||
dir = pfs_create_dir(root, "net", NULL, NULL, NULL, 0); | dir = pfs_create_dir(root, "net", NULL, NULL, NULL, 0); | |||||||||||||
pfs_create_file(dir, "dev", &linprocfs_donetdev, | pfs_create_file(dir, "dev", &linprocfs_donetdev, | |||||||||||||
NULL, NULL, NULL, PFS_RD); | ||||||||||||||
pfs_create_file(dir, "route", &linprocfs_donetroute, | ||||||||||||||
NULL, NULL, NULL, PFS_RD); | NULL, NULL, NULL, PFS_RD); | |||||||||||||
/* /proc/<pid>/... */ | /* /proc/<pid>/... */ | |||||||||||||
dir = pfs_create_dir(root, "pid", NULL, NULL, NULL, PFS_PROCDEP); | dir = pfs_create_dir(root, "pid", NULL, NULL, NULL, PFS_PROCDEP); | |||||||||||||
pfs_create_file(dir, "cmdline", &linprocfs_doproccmdline, | pfs_create_file(dir, "cmdline", &linprocfs_doproccmdline, | |||||||||||||
NULL, NULL, NULL, PFS_RD); | NULL, NULL, NULL, PFS_RD); | |||||||||||||
pfs_create_link(dir, "cwd", &linprocfs_doproccwd, | pfs_create_link(dir, "cwd", &linprocfs_doproccwd, | |||||||||||||
NULL, NULL, NULL, 0); | NULL, NULL, NULL, 0); | |||||||||||||
▲ Show 20 Lines • Show All 111 Lines • Show Last 20 Lines |
You shouldn’t include it, that’s a private header for the routing code.