summaryrefslogtreecommitdiffstats
path: root/net/ipv6
diff options
context:
space:
mode:
authorHannes Frederic Sowa <hannes@stressinduktion.org>2014-01-19 15:58:19 -0500
committerDavid S. Miller <davem@davemloft.net>2014-01-19 22:55:50 -0500
commit602582ca7a159622aebc5e643f6577fe8f0d6a41 (patch)
treedb0366c0727e2bea43a32bc831eb4b68bddd3079 /net/ipv6
parent395056edd687f7b44e6e5c2c3d2725446d762434 (diff)
ipv6: optimize link local address search
ipv6_link_dev_addr sorts newly added addresses by scope in ifp->addr_list. Smaller scope addresses are added to the tail of the list. Use this fact to iterate in reverse over addr_list and break out as soon as a higher scoped one showes up, so we can spare some cycles on machines with lot's of addresses. The ordering of the addresses is not relevant and we are more likely to get the eui64 generated address with this change anyway. Suggested-by: Brian Haley <brian.haley@hp.com> Signed-off-by: Hannes Frederic Sowa <hannes@stressinduktion.org> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv6')
-rw-r--r--net/ipv6/addrconf.c12
1 files changed, 9 insertions, 3 deletions
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index f91e107d5f88..31bdedc32bdd 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -1437,7 +1437,9 @@ int __ipv6_get_lladdr(struct inet6_dev *idev, struct in6_addr *addr,
1437 struct inet6_ifaddr *ifp; 1437 struct inet6_ifaddr *ifp;
1438 int err = -EADDRNOTAVAIL; 1438 int err = -EADDRNOTAVAIL;
1439 1439
1440 list_for_each_entry(ifp, &idev->addr_list, if_list) { 1440 list_for_each_entry_reverse(ifp, &idev->addr_list, if_list) {
1441 if (ifp->scope > IFA_LINK)
1442 break;
1441 if (ifp->scope == IFA_LINK && 1443 if (ifp->scope == IFA_LINK &&
1442 !(ifp->flags & banned_flags)) { 1444 !(ifp->flags & banned_flags)) {
1443 *addr = ifp->addr; 1445 *addr = ifp->addr;
@@ -1858,7 +1860,9 @@ static int ipv6_inherit_eui64(u8 *eui, struct inet6_dev *idev)
1858 struct inet6_ifaddr *ifp; 1860 struct inet6_ifaddr *ifp;
1859 1861
1860 read_lock_bh(&idev->lock); 1862 read_lock_bh(&idev->lock);
1861 list_for_each_entry(ifp, &idev->addr_list, if_list) { 1863 list_for_each_entry_reverse(ifp, &idev->addr_list, if_list) {
1864 if (ifp->scope > IFA_LINK)
1865 break;
1862 if (ifp->scope == IFA_LINK && !(ifp->flags&IFA_F_TENTATIVE)) { 1866 if (ifp->scope == IFA_LINK && !(ifp->flags&IFA_F_TENTATIVE)) {
1863 memcpy(eui, ifp->addr.s6_addr+8, 8); 1867 memcpy(eui, ifp->addr.s6_addr+8, 8);
1864 err = 0; 1868 err = 0;
@@ -3239,7 +3243,9 @@ static bool ipv6_lonely_lladdr(struct inet6_ifaddr *ifp)
3239 struct inet6_ifaddr *ifpiter; 3243 struct inet6_ifaddr *ifpiter;
3240 struct inet6_dev *idev = ifp->idev; 3244 struct inet6_dev *idev = ifp->idev;
3241 3245
3242 list_for_each_entry(ifpiter, &idev->addr_list, if_list) { 3246 list_for_each_entry_reverse(ifpiter, &idev->addr_list, if_list) {
3247 if (ifpiter->scope > IFA_LINK)
3248 break;
3243 if (ifp != ifpiter && ifpiter->scope == IFA_LINK && 3249 if (ifp != ifpiter && ifpiter->scope == IFA_LINK &&
3244 (ifpiter->flags & (IFA_F_PERMANENT|IFA_F_TENTATIVE| 3250 (ifpiter->flags & (IFA_F_PERMANENT|IFA_F_TENTATIVE|
3245 IFA_F_OPTIMISTIC|IFA_F_DADFAILED)) == 3251 IFA_F_OPTIMISTIC|IFA_F_DADFAILED)) ==