| From e19cfa0f0b9c8bec88cb3a8abed586ed4917b937 Mon Sep 17 00:00:00 2001 |
| From: Zhiqiang Liu <liuzhiqiang26@huawei.com> |
| Date: Mon, 11 Feb 2019 10:57:46 +0800 |
| Subject: net: fix IPv6 prefix route residue |
| |
| [ Upstream commit e75913c93f7cd5f338ab373c34c93a655bd309cb ] |
| |
| Follow those steps: |
| # ip addr add 2001:123::1/32 dev eth0 |
| # ip addr add 2001:123:456::2/64 dev eth0 |
| # ip addr del 2001:123::1/32 dev eth0 |
| # ip addr del 2001:123:456::2/64 dev eth0 |
| and then prefix route of 2001:123::1/32 will still exist. |
| |
| This is because ipv6_prefix_equal in check_cleanup_prefix_route |
| func does not check whether two IPv6 addresses have the same |
| prefix length. If the prefix of one address starts with another |
| shorter address prefix, even though their prefix lengths are |
| different, the return value of ipv6_prefix_equal is true. |
| |
| Here I add a check of whether two addresses have the same prefix |
| to decide whether their prefixes are equal. |
| |
| Fixes: 5b84efecb7d9 ("ipv6 addrconf: don't cleanup prefix route for IFA_F_NOPREFIXROUTE") |
| Signed-off-by: Zhiqiang Liu <liuzhiqiang26@huawei.com> |
| Reported-by: Wenhao Zhang <zhangwenhao8@huawei.com> |
| Signed-off-by: David S. Miller <davem@davemloft.net> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| net/ipv6/addrconf.c | 3 ++- |
| 1 file changed, 2 insertions(+), 1 deletion(-) |
| |
| diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c |
| index 3dfc50cd86d68..c57efd5c5b387 100644 |
| --- a/net/ipv6/addrconf.c |
| +++ b/net/ipv6/addrconf.c |
| @@ -1148,7 +1148,8 @@ check_cleanup_prefix_route(struct inet6_ifaddr *ifp, unsigned long *expires) |
| list_for_each_entry(ifa, &idev->addr_list, if_list) { |
| if (ifa == ifp) |
| continue; |
| - if (!ipv6_prefix_equal(&ifa->addr, &ifp->addr, |
| + if (ifa->prefix_len != ifp->prefix_len || |
| + !ipv6_prefix_equal(&ifa->addr, &ifp->addr, |
| ifp->prefix_len)) |
| continue; |
| if (ifa->flags & (IFA_F_PERMANENT | IFA_F_NOPREFIXROUTE)) |
| -- |
| 2.19.1 |
| |