[Xorp-hackers] Re: Deleting IP addresses in Linux using ioctl()

Pavlin Radoslavov pavlin@icir.org
Tue, 14 Oct 2003 13:54:37 -0700


[Email thread moved into xorp-hackers, and Bcc to the original ML]

> /-- Pavlin Radoslavov wrote:
> | In the process of dealing with FEA support for Linux, I found
> | another "interesting" thing about Linux.
> | 
> | The well-known ioctl(SIOCDIFADDR) that is used for deleting IP
> | addresses on an interface simply doesn't work on Linux. The ioctl()
> | returns an error (EINVAL: "Invalid argument"), and a search in the
> | Linux kernel source code reveals that in fact it is implemented only
> | in case of IPv6 address deletion!
> | 
> | Indeed, the ifconfig(8) manual page says that we are allowed only to
> | add or delete IPv6 addresses: 
> | 
> |        add addr/prefixlen
> |               Add an IPv6 address to an interface.
> | 
> |        del addr/prefixlen
> |               Remove an IPv6 address from an interface.
> | 
> | Never mind that the ifconfig "add" command and the corresponding
> | ioctl(SIOCSIFADDR) do work for IPv4 as well. Further, "ifconfig del"
> | of IPv4 address is a no-op: the IPv4 address is not deleted, but
> | ifconfig doesn't return any error.
> | 
> | 
> | After some search on the subject, the closest info I found was an
> | old email thread with the bottom line that people should use the
> | Linux-specific "ip" tool instead of "ifconfig" to manipulate network
> | interfaces.
> | This "ip" tool actually uses Netlink for adding/deleting IP
> | addresses and is suppose to be the model for using the Netlink
> | facility, but actually uses ioctl() to set the MTU and network
> | interface flags (see my few days old email on the Linux MTU
> | subject).
> | 
> | After a bit of experimenting, I found that actually if I try to set
> | the IP address to 0.0.0.0 by using ioctl(SIOCSIFADDR), then the
> | effect of this is deletion of the IP address that was set previously
> | on that interface.
> | 
> | 
> | Hence, the only thing I could do to delete an IP address using the
> | ioctl() facility was to use the equivalent of:
> | 
> | #ifndef HOST_OS_LINUX
> |     // Delete the address
> |     ioctl(SIOCDIFADDR, ipv4_address);
> | #else
> |     // XXX: In case of Linux, SIOCDIFADDR doesn't delete IPv4 addresses.
> |     // Hence, we use SIOCSIFADDR to add 0.0.0.0 as an address. The
> |     // effect of this hack is that the IPv4 address on that interface
> |     // is deleted. Sigh...
> |     ioctl(SIOCSIFADDR, "0.0.0.0");
> | #endif
> | 
> | 
> | Note that by default on Linux system we are going to use the Netlink
> | facility to add/delete IP addresses, hence the above hack won't be
> | executed. Only if for whatever reasons someone needs to relay on the
> | ioctl() facility, then the above code is executed. Probably not a
> | big deal because it shoudn't break anything, except that the
> | solution is a hack.
> | 
> | Any suggestions if the above problem should be handled differently?
> 
> [xorp-hackers email???]
> 
> There doesn't seem to be much more you can do.  Add a '#error' to
> force the person playing ioctl-land to see the code and comment in
> question?

Currently, the way the code is organized is that all high-level
mechanisms supported on a given platform (e.g., routing-sockets,
netlink-sockets, ioctl()) are compiled, and then at run time only
one of them is plugged-in as the one to be used to set/get info
to/from the kernel, etc. This compilation is intentional so no
compilation error is introduced if the code changes.
(FYI, right now if there is more than one methods supported by an
OS, the specific decision which particular mechanism is used is
hard-coded; if necessary, this can easily be changed to run-time
configuration).

An #error will break the compilation of the ioctl()-related code
under Linux, hence I'd prefer not to disable the compilation of the
the ioctl() code.

> This would less of an issue if we had fea unit tests.  These would
> need root permission and probably some a host specific config
> (e.g. interfaces), and platform specific verification,
> e.g. running platform equivalent of ifconfig, and checking the
> output over all operations.

I have some shell scripts that I use to test various mechanisms in
the FEA. I will clean them up and will commit them soon.

Pavlin