[Toybox] Entering the home stretch on ifconfig...
Rob Landley
rob at landley.net
Mon Jun 10 11:10:41 PDT 2013
On 06/10/2013 01:31:36 AM, idunham at lavabit.com wrote:
> On Sat, Jun 08, 2013 at 02:40:04PM -0500, Rob Landley wrote:
> > On 06/07/2013 01:11:50 AM, Bastian Bittorf wrote:
> > >* Rob Landley <rob at landley.net> [07.06.2013 07:57]:
> > >> It looks like show_iface() enumerates /proc/net/dev and then
> calls
> > >> readconf() to do ioctl() based enumeration. The /proc one gives
> > >us RX
> > >> bytes and such, the ioctl gives us a "virtual interface" (ala
> lo:0 I
> > >
> > >dont use the deprecated one, but /sys/class/net/
> > >or even "better" via netlink.
> >
> > I didn't write this code, I'm just cleaning it up. Patches welcome.
> >
> > Where is it deprecated? Documentation/filesystems/proc.txt currently
> > says (line 1029):
> >
> > dev network devices with statistics
> >
> > Line 1056 then provides an example. No warnings about using it.
>
> I don't know for sure, but he may mean the interface referred to in
> this
> line in the linux.die.net version of the manpage:
Last time I checked that was a random assortment of BSD, Solaris, and
obsolete Linux man pages. But it's been a while...
> "Ifconfig uses obsolete kernel interface. It uses the ioctl access
> method
> to get the full address information, which limits hardware addresses
> to 8
> bytes. Since an Infiniband address is 20 bytes, only the first 8
> bytes of
> Infiniband address are displayed."
I don't have any infiniband hardware to test on, but I note that the
set codepath handles 20 bytes of infiniband data around line 586.
The display side has an infiniband case on line 257, but the actual
hardware address display only triggers for ARPHRD_ETHER so it doesn't
look like it displays an infiniband address at all. As for fetch, yes
it does ioctl(TT.sockfd, SIOCGIFHWADDR, &ifre) and the field it fills
out is struct sockaddr, and according to linux/socket.h _K_SS_MAXSIZE
is 128 so if the ioctl can't fit 20 bytes of hardware address in there
something is wrong.
Let's see what the kernel actually does with SIOCGIFHWADDR? Well, in
net/core/dev_ioctl.c dev_ioctl() calls dev_ifsioc_locked(), and _that_
has:
memcpy(ifr->ifr_hwaddr.sa_data, dev->dev_addr,
min(sizeof ifr->ifr_hwaddr.sa_data, (size_t) dev->addr_len));
And ifr_hwaddr.sa_data is "struct sock", and in include/linux/socket.h:
/*
* 1003.1g requires sa_family_t and that sa_data is char.
*/
struct sockaddr {
sa_family_t sa_family; /* address family,
AF_xxx */
char sa_data[14]; /* 14 bytes of protocol
address */
};
Great. So the uapi one is 128 bytes, but the kernel internal one is 16,
only 14 of which are left for payload after the family. So the die.net
man page has the size wrong, but the limit is still under 20.
(Sigh. I see why infiniband has a CONFIG symbol to chop it out
everywhere, the implementation is really crappy.)
So what method are you supposed to use to fetch an infiniband address?
Some variant of "cat /sys/class/net/$IFACE/address" and just output
that verbatim?
The problem remains: I don't have an inifiniband test system. I can
just chop infiniband support out completely, but when it comes to
extending it I haven't got a test environment. (If somebody _else_
wants to test it...)
> Of course, /sys/ carries all sorts of dire warnings about not being
> intended as a public interface...although it's really the nicest one
> to
> use.
Yeah, I have history with those guys.
http://landley.net/notes-2008.html#05-05-2008
Rob
More information about the Toybox
mailing list