Hello Dave, Long time back, I had posted about an issue with ip address deletion. Summary of the problem :
I added the dummy device addresses in the following sequence: ip addr add 10.3.3.3/8 dev dummy0 ip addr add 10.3.3.3/32 dev dummy0
ifconfig dummy0 10.3.3.3/32 down ip addr show dummy0 2: dummy0: <BROADCAST,NOARP> mtu 1500 qdisc noqueue link/ether 8a:d8:bd:26:14:ab brd ff:ff:ff:ff:ff:ff inet 10.3.3.3/32 scope global dummy0
The prefixes doesn't matter. Original post can be found here -> http://www.uwsg.iu.edu/hypermail/linux/net/0503.2/0000.html
Thomas Graf had pointed to a patch which was queued by you, which could fix the issue -> http://www.uwsg.iu.edu/hypermail/linux/net/0503.2/0002.html ( The patch has been moved from the link given in the mail. I have attached it here for convenience. )
But, the patch hasn't gone in and I am still seeing the problem on 2.6.19 :(.. I have tested this patch on 2.6.19 and if fixes the issue there.
Could you please push this patch ? Thanks, Suzuki
diff -Nru linux-2.6.11-bk3.orig/include/linux/inetdevice.h linux-2.6.11-bk3/include/linux/inetdevice.h --- linux-2.6.11-bk3.orig/include/linux/inetdevice.h 2005-03-08 13:10:37.000000000 +0100 +++ linux-2.6.11-bk3/include/linux/inetdevice.h 2005-03-08 16:29:27.000000000 +0100 @@ -7,6 +7,7 @@ #include <linux/netdevice.h> #include <linux/rcupdate.h> #include <linux/timer.h> +#include <linux/rtnetlink.h> struct ipv4_devconf { @@ -131,6 +132,25 @@ return 0; } +static inline int inet_ifa_match_local_prefixlen(struct ifaddrmsg *ifm, + struct in_ifaddr *ifa) +{ + int real_prefixlen = IFA_REAL_DEL_PREFIX(ifm->ifa_prefixlen); + + /* + * Since the prefix length hasn't been taken into account in + * previous kernel versions, parts of the userspace rely on the fact + * that the deletion of an address without specifying a prefix works. + * We cannot break this and thus a prefix length of 32 still represents + * a wildcard if no exact match is requested. + */ + if (real_prefixlen != 32 || ifm->ifa_prefixlen & IFA_PREFIX_EXACT_DEL) + if (real_prefixlen != ifa->ifa_prefixlen) + return 0; + + return 1; +} + #define for_primary_ifa(in_dev) { struct in_ifaddr *ifa; \ for (ifa = (in_dev)->ifa_list; ifa && !(ifa->ifa_flags&IFA_F_SECONDARY); ifa = ifa->ifa_next) diff -Nru linux-2.6.11-bk3.orig/include/linux/rtnetlink.h linux-2.6.11-bk3/include/linux/rtnetlink.h --- linux-2.6.11-bk3.orig/include/linux/rtnetlink.h 2005-03-08 16:28:04.000000000 +0100 +++ linux-2.6.11-bk3/include/linux/rtnetlink.h 2005-03-08 14:17:49.000000000 +0100 @@ -396,6 +396,19 @@ #define IFA_MAX (__IFA_MAX - 1) +/* + * Quirk for IPv4 address deletion to allow exact deletion of equal + * addresses varying only in prefix length. A explicit exact comparison + * of the prefix length will only be done if IFA_PREFIX_EXACT_DEL is + * ORed to ifa_prefixlen. + * + * Note: This special treatment is only understood while deleting + * addresses and will lead to unexpected behaviour if used + * otherwise. + */ +#define IFA_PREFIX_EXACT_DEL 0x40 +#define IFA_REAL_DEL_PREFIX(l) ((l) & 0x3f) + /* ifa_flags */ #define IFA_F_SECONDARY 0x01 diff -Nru linux-2.6.11-bk3.orig/net/ipv4/devinet.c linux-2.6.11-bk3/net/ipv4/devinet.c --- linux-2.6.11-bk3.orig/net/ipv4/devinet.c 2005-03-08 13:10:44.000000000 +0100 +++ linux-2.6.11-bk3/net/ipv4/devinet.c 2005-03-08 16:29:49.000000000 +0100 @@ -389,6 +389,7 @@ struct in_device *in_dev; struct ifaddrmsg *ifm = NLMSG_DATA(nlh); struct in_ifaddr *ifa, **ifap; + int real_prefixlen = IFA_REAL_DEL_PREFIX(ifm->ifa_prefixlen); ASSERT_RTNL(); @@ -399,12 +400,13 @@ for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL; ifap = &ifa->ifa_next) { if ((rta[IFA_LOCAL - 1] && + (!inet_ifa_match_local_prefixlen(ifm, ifa) || memcmp(RTA_DATA(rta[IFA_LOCAL - 1]), - &ifa->ifa_local, 4)) || + &ifa->ifa_local, 4))) || (rta[IFA_LABEL - 1] && rtattr_strcmp(rta[IFA_LABEL - 1], ifa->ifa_label)) || (rta[IFA_ADDRESS - 1] && - (ifm->ifa_prefixlen != ifa->ifa_prefixlen || + (real_prefixlen != ifa->ifa_prefixlen || !inet_ifa_match(*(u32*)RTA_DATA(rta[IFA_ADDRESS - 1]), ifa)))) continue;