From: Stephen Hemminger Date: Tue, 18 May 2010 05:27:12 +0000 (-0700) Subject: ipv6: fix the bug of address check X-Git-Url: http://drtracing.org/?a=commitdiff_plain;h=eedf042a63ffef050ebc015de19b52dc065e830b;p=deliverable%2Flinux.git ipv6: fix the bug of address check The duplicate address check code got broken in the conversion to hlist (2.6.35). The earlier patch did not fix the case where two addresses match same hash value. Use two exit paths, rather than depending on state of loop variables (from macro). Based on earlier fix by Shan Wei. Signed-off-by: Stephen Hemminger Reviewed-by: Shan Wei Signed-off-by: David S. Miller --- diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 3984f52181f4..75d3b8c1e856 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -1274,7 +1274,7 @@ static int ipv6_count_addresses(struct inet6_dev *idev) int ipv6_chk_addr(struct net *net, struct in6_addr *addr, struct net_device *dev, int strict) { - struct inet6_ifaddr *ifp = NULL; + struct inet6_ifaddr *ifp; struct hlist_node *node; unsigned int hash = ipv6_addr_hash(addr); @@ -1283,15 +1283,16 @@ int ipv6_chk_addr(struct net *net, struct in6_addr *addr, if (!net_eq(dev_net(ifp->idev->dev), net)) continue; if (ipv6_addr_equal(&ifp->addr, addr) && - !(ifp->flags&IFA_F_TENTATIVE)) { - if (dev == NULL || ifp->idev->dev == dev || - !(ifp->scope&(IFA_LINK|IFA_HOST) || strict)) - break; + !(ifp->flags&IFA_F_TENTATIVE) && + (dev == NULL || ifp->idev->dev == dev || + !(ifp->scope&(IFA_LINK|IFA_HOST) || strict))) { + rcu_read_unlock_bh(); + return 1; } } - rcu_read_unlock_bh(); - return ifp != NULL; + rcu_read_unlock_bh(); + return 0; } EXPORT_SYMBOL(ipv6_chk_addr);