mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-25 21:24:08 +08:00
[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: Kristian Slavov <kristian.slavov@nomadiclab.com> Acked-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
7eb1b3d372
commit
1d1428045c
@ -634,8 +634,7 @@ static void ipv6_del_addr(struct inet6_ifaddr *ifp)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (ifap = &idev->addr_list; (ifa=*ifap) != NULL;
|
for (ifap = &idev->addr_list; (ifa=*ifap) != NULL;) {
|
||||||
ifap = &ifa->if_next) {
|
|
||||||
if (ifa == ifp) {
|
if (ifa == ifp) {
|
||||||
*ifap = ifa->if_next;
|
*ifap = ifa->if_next;
|
||||||
__in6_ifa_put(ifp);
|
__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)
|
if (!(ifp->flags & IFA_F_PERMANENT) || onlink > 0)
|
||||||
break;
|
break;
|
||||||
deleted = 1;
|
deleted = 1;
|
||||||
|
continue;
|
||||||
} else if (ifp->flags & IFA_F_PERMANENT) {
|
} else if (ifp->flags & IFA_F_PERMANENT) {
|
||||||
if (ipv6_prefix_equal(&ifa->addr, &ifp->addr,
|
if (ipv6_prefix_equal(&ifa->addr, &ifp->addr,
|
||||||
ifp->prefix_len)) {
|
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);
|
write_unlock_bh(&idev->lock);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user