Re: inconsistency between SIOCGIFCONF and SIOCGIFNAME

From: David S. Miller
Date: Tue Jun 29 2004 - 03:27:27 EST


On Mon, 28 Jun 2004 21:06:25 -0700
Ulrich Drepper <drepper@xxxxxxxxxx> wrote:

> With the current kernels all I could do is to make if_indextoname and
> if_nametoindex slower by always calling if_nameindex implicitly to see
> whether the interface is defined at all. It would be much better if the
> kernel could do the right thing. I.e., do one of the following:
>
> ~ if the SIOCGIFCONF, return all interfaces SIOCGIFNAME also knows
> about.
>
> ~ do not allow SIOCGIFNAME and SIOCGIFINDEX) to return values if
> SIOCGIFCONF, would not return any.

Indeed the if_* routines are specified as you describe, yet the
BSD ioctl interfaces discussed here are defined by BSD and
therefore I'm hesitant to change how they behave. But I've
actually discovered that we diverge from BSD, see below.

What I can recommend is that you obtain the interface information
using NETLINK sockets. Specifically via the RTM_GETLINK message.
I believe it provides the functionality you desire, and also because
I believe you are using netlink for some other implementations in
glibc you can make this if_* code share some of that code.

It is one idea, the other is to make us match BSD. At least
my best understanding of what BSD does based upon reading the
description in Steven's Volume 2.

The exact check we make during ipv4 gifconf processing is that we do
not report the interface if either of the following is true:

1) No ipv4 private area has been allocated and attached to
the device. This is created the first time an ipv4 address
is assigned to a device.

2) No ipv4 addresses are presently assigned to the device.

So it is possible for the device to be UP yet not get reported
by SIOCGIFCONF. This occurs when no ipv4 addresses are assigned
to it. BSD reports all interfaces, as best as I can tell.

Anyways, I guess we could do your suggestion. SIOCGIFCONF
is actually implemented using per-protocol handlers. So, for
example there is an ipv4 handler, an ipv6 one, etc. We'd need
to make the change for all of them.

I enclose a potential implementation for the ipv4 instance.
Please at least make sure it does what you want.

I really really hope there is not some application out there
that assumes that devices reported by SIOCGIFCONF are all up.
That works now, and we'd break things by making the suggested
change. So this is what I'm most concerned about.

===== net/ipv4/devinet.c 1.29 vs edited =====
--- 1.29/net/ipv4/devinet.c 2004-05-30 11:56:05 -07:00
+++ edited/net/ipv4/devinet.c 2004-06-29 01:17:42 -07:00
@@ -720,8 +720,18 @@
struct ifreq ifr;
int done = 0;

- if (!in_dev || (ifa = in_dev->ifa_list) == NULL)
+ if (!in_dev || (ifa = in_dev->ifa_list) == NULL) {
+ if (!buf)
+ return sizeof(struct ifreq);
+ if (len >= (int) sizeof(ifr)) {
+ memset(&ifr, 0, sizeof(struct ifreq));
+ strcpy(ifr.ifr_name, dev->name);
+ if (copy_to_user(buf, &ifr, sizeof(struct ifreq)))
+ return -EFAULT;
+ done += sizeof(struct ifreq);
+ }
goto out;
+ }

for (; ifa; ifa = ifa->ifa_next) {
if (!buf) {
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/