Sometimes, one would like to play with an IP address/netmask/etc. on a
network interface temporarily, and then be able to down the interface, and
reuse that IP address/netmask/etc. on another host on the same subnet.
However, a simple "ifconfig eth0 192.11.13.15 netmask 255.255.255.192 up",
followed by an "ifconfig eth0 down" still leaves FIB rules in place for
the 192.11.13.15 address, so that an ARP request that arrives on, say eth1
for 192.11.13.15 would result in a response being generated from eth1 for
the old 192.11.13.15 address that was on eth0, even though eth0 is down.
There are a couple of ways that one can get around this problem:
1. From user space, by modifying the "ifdown" scripts to "ifconfig eth0 0
down", i.e. remove the IP address information associated with the network
interface entirely.
or
2. From the kernel, with the following enhancement that I have
developed. If a user specifies "ifconfig eth0 down -arp" with my kernel
changes, this gets rid of the FIB rules in the kernel for the IP address
associated with the interface, but leaves the IP address information still
associated with the down network interface. So a subsequent "ifconfig eth0
up" will restore the FIB rules and re-enable the interface with its old IP
address information.
I believe that this could be a differentiating feature of Linux
versus other Un*x OSes, that some system/network admins would like to
use. The reason I went down this path is because we got bitten by this
problem on a number of subnets, because we have many
multi-network-interface servers on our networks that we play around with.
Here is the patch against the 2.4.18 kernel...
diff -aur linux-2.4.18/net/ipv4/devinet.c linux-2.4.18-arp/net/ipv4/devinet.c
--- linux-2.4.18/net/ipv4/devinet.c Fri Dec 21 10:42:05 2001
+++ linux-2.4.18-arp/net/ipv4/devinet.c Fri Jul 26 14:32:18 2002
@@ -586,6 +586,14 @@
inet_del_ifa(in_dev, ifap, 1);
break;
}
+ if (!(ifr.ifr_flags&IFF_UP) &&
+ (ifr.ifr_flags&IFF_NOARP)) {
+ ifr.ifr_flags &= ~IFF_NOARP;
+ in_dev->flags |= IFF_NOARP;
+ notifier_call_chain(&inetaddr_chain,
+ NETDEV_DOWN, ifa);
+ in_dev->flags &= ~IFF_NOARP;
+ }
ret = dev_change_flags(dev, ifr.ifr_flags);
break;
diff -aur linux-2.4.18/net/ipv4/fib_frontend.c linux-2.4.18-arp/net/ipv4/fib_frontend.c
--- linux-2.4.18/net/ipv4/fib_frontend.c Fri Dec 21 10:42:05 2001
+++ linux-2.4.18-arp/net/ipv4/fib_frontend.c Fri Jul 26 14:33:10 2002
@@ -583,7 +583,9 @@
break;
case NETDEV_DOWN:
fib_del_ifaddr(ifa);
- if (ifa->ifa_dev && ifa->ifa_dev->ifa_list == NULL) {
+ if (ifa->ifa_dev &&
+ ((ifa->ifa_dev->ifa_list == NULL) ||
+ (ifa->ifa_dev->flags&IFF_NOARP))) {
/* Last address was deleted from this interface.
Disable IP.
*/
--
Bhavesh P. Davda
Avaya Inc.
[email protected]
IFF_NOARP is a deprecated 2.2.x feature for normal interfaces and is
no longer used in 2.4.x and later.
The only reason IFF_NOARP still exists in the current code is to
handle some tunneling issues.
Hello,
Bhavesh_P_Davda wrote:
> However, a simple "ifconfig eth0 192.11.13.15 netmask 255.255.255.192 up",
> followed by an "ifconfig eth0 down" still leaves FIB rules in place for
> the 192.11.13.15 address, so that an ARP request that arrives on, say eth1
> for 192.11.13.15 would result in a response being generated from eth1 for
> the old 192.11.13.15 address that was on eth0, even though eth0 is down.
>
> There are a couple of ways that one can get around this problem:
You can also solve it with ip:
ip addr del 192.11.13.15/26 dev eth0
ifconfig does not delete the last remaining primary address
Regards
--
Julian Anastasov <[email protected]>