sysctl(8) can't read IFMIB nodes

Kevin Day toasty at dragondata.com
Fri Jan 12 15:09:29 UTC 2018


IFMIB doesn't work with the command-line tool sysctl(8). src/tools/tools/ifinfo uses IFMIB correctly though, so I looked at why:

ifinfo is calling sysctlbyname() directly:

 86387 ifinfo   CALL  __sysctl(0x7fffffffe510,0x6,0x7fffffffe530,0x7fffffffe100,0,0)
 86387 ifinfo   SCTL  "net.link.generic.ifdata.1.1"
 86387 ifinfo   RET   __sysctl 0

But using sysctl directly doesn't:

# ktrace sysctl net.link.generic.ifdata.1.1
sysctl: unknown oid 'net.link.generic.ifdata.1.1': No such file or directory

The problem is that sysctl(8) is calling sysctl.name2oid on it first, so that it can get type information on it:

 21090 sysctl   CALL  __sysctl(0x7fffffffda00,0x2,0x7fffffffd970,0x7fffffffd9f8,0x7fffffffe210,0x1b)
 21090 sysctl   SCTL  "sysctl.name2oid"
 21090 sysctl   RET   __sysctl -1 errno 2 No such file or directory
 21090 sysctl   CALL  write(0x2,0x7fffffffd2d0,0x8)
 21090 sysctl   GIO   fd 2 wrote 8 bytes
       "sysctl: "
 21090 sysctl   RET   write 8
 21090 sysctl   CALL  write(0x2,0x7fffffffd3c0,0x29)
 21090 sysctl   GIO   fd 2 wrote 41 bytes
       "unknown oid 'net.link.generic.ifdata.1.1'"

This fails because in the kernel, ifmib isn't setting up oids for every possible entry under ifdata, it configures the parent node then captures every request under it.

I'm specifically looking to be able to get link state/speed on all interfaces from what's essentially a shell script using tools that only exist in a base install.

If I were trying to fix this with a patch that would likely get accepted, what's the best way of fixing this?

1) Making IFMIB create sysctls for every interface? This would require it get involved every time an interface is added or deleted, which might not be popular because this is a very infrequently used feature.

2) Allowing sysctl(8) to forge ahead anyway with reading/writing to sysctls without oids (maybe only if the -o flag is present?)

3) Overhauling sysctl.oidfmt and oiddescr to somehow work by names as well as oids so that sysctl(8) doesn't need to translate them to oids first





More information about the freebsd-hackers mailing list