Subject: [PATCH] hethost ipv4: Don't bring down the network when brining down a single ip. From: Eric W. Biederman Date: 1134307346 -0700 In an attempt to always select the proper source address I allowed multiple primaries on the same subnet if they were for different hosts. Unfortunately this supressed the promote secondaries code which is responsible for keeping a route up when a ip address goes down. - So modify inet_select_addr to look at all addresses. - Revert inet_insert_ifa to it's old behaviour for selecting secondaries. - Update inet_del_ifa to always promote seconaries if they are for a different host. This appears better then allowing one host to delete another hosts ip addresses. --- net/ipv4/devinet.c | 15 ++++++++------- 1 files changed, 8 insertions(+), 7 deletions(-) 476333b9ec3514155a130f815aa40aabab740a65 diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c index 28db04d..139b23c 100644 --- a/net/ipv4/devinet.c +++ b/net/ipv4/devinet.c @@ -279,14 +279,14 @@ static void inet_del_ifa(struct in_devic while ((ifa = *ifap1) != NULL) { if (!(ifa->ifa_flags & IFA_F_SECONDARY) || - ifa1->ifa_host != ifa->ifa_host || ifa1->ifa_mask != ifa->ifa_mask || !inet_ifa_match(ifa1->ifa_address, ifa)) { ifap1 = &ifa->ifa_next; continue; } - if (!IN_DEV_PROMOTE_SECONDARIES(in_dev)) { + if (!IN_DEV_PROMOTE_SECONDARIES(in_dev) && + (ifa1->ifa_host == ifa->ifa_host)) { *ifap1 = ifa->ifa_next; rtmsg_ifa(RTM_DELADDR, ifa); @@ -322,7 +322,7 @@ static void inet_del_ifa(struct in_devic inetdev_destroy(in_dev); } - if (promote && IN_DEV_PROMOTE_SECONDARIES(in_dev)) { + if (promote) { /* not sure if we should send a delete notify first? */ promote->ifa_flags &= ~IFA_F_SECONDARY; rtmsg_ifa(RTM_NEWADDR, promote); @@ -367,8 +367,7 @@ static int inet_insert_ifa(struct in_ifa inet_free_ifa(ifa); return -EINVAL; } - if (ifa1->ifa_host == ifa->ifa_host) - ifa->ifa_flags |= IFA_F_SECONDARY; + ifa->ifa_flags |= IFA_F_SECONDARY; } } @@ -843,7 +842,7 @@ u32 inet_select_addr(struct nethost *hos if (!in_dev) goto no_in_dev; - for_primary_ifa(in_dev) { + for_ifa(in_dev) { if (ifa->ifa_host && host && ifa->ifa_host != host) continue; if (ifa->ifa_scope > scope) @@ -871,7 +870,7 @@ no_in_dev: if ((in_dev = __in_dev_get_rcu(dev)) == NULL) continue; - for_primary_ifa(in_dev) { + for_ifa(in_dev) { if (ifa->ifa_host && host && ifa->ifa_host != host) continue; if (ifa->ifa_scope != RT_SCOPE_LINK && @@ -1099,6 +1098,8 @@ static int inetdev_event(struct notifier if (dev->mtu >= 68) break; /* MTU falled under 68, disable IP */ + inetdev_destroy(in_dev); + break; case NETDEV_UNREGISTER: inethost_destroy(loopback_host(dev)); inetdev_destroy(in_dev); -- 1.0.GIT