提交 1d142804 编写于 作者: K Kristian Slavov 提交者: David S. Miller

[IPV6]: Fix address deletion

If you add more than one IPv6 address belonging to the same prefix and 
delete the address that was last added, routing table entry for that 
prefix is also deleted.
Tested on 2.6.14.4

To reproduce:
ip addr add 3ffe::1/64 dev eth0
ip addr add 3ffe::2/64 dev eth0
/* wait DAD */
sleep 1
ip addr del 3ffe::2/64 dev eth0
ip -6 route

(route to 3ffe::/64 should be gone)

In ipv6_del_addr(), if ifa == ifp, we set ifa->if_next to NULL, and later 
assign ifap = &ifa->if_next, effectively terminating the for-loop.
This prevents us from checking if there are other addresses using the same 
prefix that are valid, and thus resulting in deletion of the prefix.
This applies only if the first entry in idev->addr_list is the address to 
be deleted.
Signed-off-by: NKristian Slavov <kristian.slavov@nomadiclab.com>
Acked-by: NYOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
Signed-off-by: NDavid S. Miller <davem@davemloft.net>
上级 7eb1b3d3
......@@ -634,8 +634,7 @@ static void ipv6_del_addr(struct inet6_ifaddr *ifp)
}
#endif
for (ifap = &idev->addr_list; (ifa=*ifap) != NULL;
ifap = &ifa->if_next) {
for (ifap = &idev->addr_list; (ifa=*ifap) != NULL;) {
if (ifa == ifp) {
*ifap = ifa->if_next;
__in6_ifa_put(ifp);
......@@ -643,6 +642,7 @@ static void ipv6_del_addr(struct inet6_ifaddr *ifp)
if (!(ifp->flags & IFA_F_PERMANENT) || onlink > 0)
break;
deleted = 1;
continue;
} else if (ifp->flags & IFA_F_PERMANENT) {
if (ipv6_prefix_equal(&ifa->addr, &ifp->addr,
ifp->prefix_len)) {
......@@ -666,6 +666,7 @@ static void ipv6_del_addr(struct inet6_ifaddr *ifp)
}
}
}
ifap = &ifa->if_next;
}
write_unlock_bh(&idev->lock);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册