瀏覽代碼

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 <shemminger@vyatta.com>
Reviewed-by: Shan Wei <shanwei@cn.fujitsu.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Stephen Hemminger 15 年之前
父節點
當前提交
eedf042a63
共有 1 個文件被更改,包括 8 次插入7 次删除
  1. 8 7
      net/ipv6/addrconf.c

+ 8 - 7
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,
 int ipv6_chk_addr(struct net *net, struct in6_addr *addr,
 		  struct net_device *dev, int strict)
 		  struct net_device *dev, int strict)
 {
 {
-	struct inet6_ifaddr *ifp = NULL;
+	struct inet6_ifaddr *ifp;
 	struct hlist_node *node;
 	struct hlist_node *node;
 	unsigned int hash = ipv6_addr_hash(addr);
 	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))
 		if (!net_eq(dev_net(ifp->idev->dev), net))
 			continue;
 			continue;
 		if (ipv6_addr_equal(&ifp->addr, addr) &&
 		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);
 EXPORT_SYMBOL(ipv6_chk_addr);