[Toybox] Finishing ifconfig cleanup!

Rob Landley rob at landley.net
Fri Nov 29 22:49:27 PST 2013


This is really 1129 through 1133, but let's focus on:

http://landley.net/hg/toybox/rev/1133

The last post didn't mention the "try to compile, fix the obvious build  
breaks, debug a weird thing..." part where get_addrinfo() was copying  
addresses with the wrong size and the wrong offset because  
rp->ai_addr->sa_data is "struct sockaddr", not the actual struct  
in_addr or struct in6_addr. wheee.

Both of them have "family" and "port". sockaddr_in6 says family is an  
unsigned short int (2 bytes ala LP64), and then port is __be16 (2  
bytes). Meanwhile sockaddr_in says family is __kernel_sa_family_t  
(which is also 2 bytes but you have to go digging to confirm it), and  
then sin_port is __be16.

EXTRA FUN: the ipv6 one has a third field before the address, __be32  
flowinfo. whatever that is, adds 4 bytes to the offset. So for ipv4  
it's offset 4, size 4, and for ipv6 it's offset 8 size 16. The ipv4  
sockaddr makes a big deal about struct sockaddr fitting in 16 bytes for  
all sockaddr types, and the ipv6 one doesn't. (But infiniband didn't  
get extra space to let the ioctl set its address correctly, because  
Intel shares the "do not care" attribute with honey badgers,  
apparently.)

Right. I'm just going to do byte offsets here. I'm aware it's cheating,  
but it works with just one codepath and should be ok on all Linux  
targets, and whoever laid out the ipv6 structures needs to be punished.

Next day: I screwed up and missed that I did a lib/lib.c atolx_range()  
function that this is using now, so check _that_ in so this builds  
again for people other than me. (That was commit 1131.)

Clean up the sockaddr nonsense described above so it's not using  
sa_data out of the ai_addr field (which skips "family" but not "port",  
so the extra level of dereferencing serves no useful purpose. Just add  
the 4 bytes manually as described above; that's now how I coded it the  
first time but as usual writing up documentation makes me change the  
code to be something easier to explain. :)

Redoing the help text at the top, and... what the heck are "trailers"  
and "dynamic"? The ubuntu ifconfig man page doesn't mention them. Let's  
see, they set IFF_NOTRAILERS and IFF_DYNAMIC which are... only  
mentioned once in the kernel source, the syscall passes them through in  
The Great Unmasking and then nothing else ever uses those flags. what?

Let's see, include/uapi/linux/if.h #defines them, and using my "git  
history back to 1991" tree, annotate says IFF_DYNAMIC was added by  
Linux 2.1.127 (commit c10fbfad61d6 in the big tree) in 1998 with  
comment "/* dialup device with changing addresses */", as a flag passed  
through in net/core/dev.c but never used by anything else. And it still  
isn't.

IFF_NOTRAILERS is from 1993, Linux 0.99.10 (commit 54c93c05f69e in the  
big tree) which was "the big switch-over version" from Ross Biro's  
net-1 to Fred van Kempen's net-2. "fsync() isn't just a stub any more,  
and System V IPC is also showing up." so yeah, pretty early on. Once  
again, the commit introducing it added the #define to the header and  
the flag to the syscall mask, and that's it. No code ever used it for  
anything.

So I'm yanking them both. The kernel does nothing with these flags, and  
never has.

Next up: what do "outfill", "keepalive", and "metric" do? Let's see,  
OUTFILL and KEEPALIVE are both from linux 1.3.61 in 1996 (commit  
76086e13f472) which added:

   +CONFIG_SLIP_SMART
   +  Adds additional capabilities to the SLIP driver to support the  
RELCOM
   +  line fill and keepalive monitoring. Ideal on poor quality  
analogue lines.

So just _deeply_ relevant in 2013. I could either yank it, or say  
something like "obsolete SLIP analog dialup line quality monitoring".  
Either way...

And metric was added to sockios.h in 1993 also by commit 54c93c05f69e  
(linux 0.99.10 again), with the informative comment "get metric" and  
"set metric". So it sets dev->metric in struct ifnet which had the  
comment "/* routing metric (not used) */". Great. That one IS still  
documented in ifconfig's man page but it just says "This parameter sets  
the interface metric." without ever hinting at what that MEANS. Because  
in Linux, it means nothing. The field can be set and read back, but is  
never used.

Sigh. Alas, it's a prominent part of the ifconfig output and removing  
it might break stuff.

Speaking of "Sigh", I want to document that to use promisc these days  
you have to throw a switch into hub mode, and the easy way to do that  
is to fill up its ARP table and force it to degrade to broadcast. I.E.  
set your interface to a random mac address and send a packet (ping the  
gateway or something), and repeat a couple thousand times. The switch  
will have too many mac addresses to store in its tiny little brain and  
will degrade to sending all packets to all interfaces, I.E. hub mode.  
If you DON'T do that, promisc mode is useless on modern hardware  
because the switch only sends you packets for your hardware address.  
(There might also be some arp magic to request a copy of everything,  
but if so I don't know it and it doesn't happen automatically the way  
normal arp does.)

But that entire digression is waaaay to long for toybox help text.

Ok, group obsolete fields. Think of adding a config option but A) they  
can't currently edit help text much, B) it wouldn't save much space.  
Possibly somebody should send a patch upstream to yank trailers and  
dynamic (and for that matter metric). But meanwhile?

Ifconfig cleanup: done.

Rob


More information about the Toybox mailing list