The solution is simple: Stop using the prehistoric ifconfig
. It is deprecated and it uses deprecated ioctl APIs. What you are hitting is the kernel's compatibility layer, which tries to infer information that ifconfig
and route
does not provide.
Use ip
from the iproute2
package. This is what a modern ifupdown
does anyway (see ifup -v eth0
to see what i'm talking about).
ip
and rtnetlink have native capabilities to add several IP addresses to an interface, without using huge obsolete hacks like interfaces aliases which are not interfaces nor aliases.
Oh, and by the way: modern ifupdown
should be able to support this:
auto eth0
iface eth0 inet static
address 192.168.3.75
netmask 255.255.255.0
gateway 192.168.3.0
iface eth0 inet static
address 192.168.3.111
netmask 255.255.255.0
And it should do the right thing. Test with ifup -v eth0
to make sure.
Why does the compatibility layer break this way ? That's simple. Consider what a user expect the system to do when it runs ifconfig eth0 192.0.2.42
:
- Does the user want to add the 192.0.2.42 IP address to the list of available addresses ?
- Does the user want to reset the existing address(es) of the interface so it only have the 192.0.2.42 address ?
Sometimes, the user want the first option. Sometimes, it want the second option (e.g. when changing the configuration completely). But there is no defined semantics to the SIOCSIFADDR ioctl.
With rtnetlink, there is no ambiguity: You manage a list of addresses with different types (IPv4, IPv6 ...) and you use RTM_NEWADDR to add a address, RTM_DELADDR to remove an existing address (if you specify one) or all addresses of an interface.
And ip
is a thin wrapper for the rtnetlink API:
- Use
ip addr add 192.168.3.111/24 dev eth0
to add an address.
- Use
ip addr del 192.168.3.111/24 dev eth0
to delete an address. The operation will fail if the address does not exist.
- Use
ip -4 addr flush dev eth0
to remove all ipv4 addresses.
You can manage IPv6 addresses the same way. Which is pretty convenient considering that having multiple IPv6 addresses on an interface is just normal behavior.