diff options
Diffstat (limited to 'net/ipv6/addrconf.c')
-rw-r--r-- | net/ipv6/addrconf.c | 25 |
1 files changed, 22 insertions, 3 deletions
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index c250d0af10d7..2316a4315a18 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c | |||
@@ -508,6 +508,26 @@ void inet6_ifa_finish_destroy(struct inet6_ifaddr *ifp) | |||
508 | kfree(ifp); | 508 | kfree(ifp); |
509 | } | 509 | } |
510 | 510 | ||
511 | static void | ||
512 | ipv6_link_dev_addr(struct inet6_dev *idev, struct inet6_ifaddr *ifp) | ||
513 | { | ||
514 | struct inet6_ifaddr *ifa, **ifap; | ||
515 | int ifp_scope = ipv6_addr_src_scope(&ifp->addr); | ||
516 | |||
517 | /* | ||
518 | * Each device address list is sorted in order of scope - | ||
519 | * global before linklocal. | ||
520 | */ | ||
521 | for (ifap = &idev->addr_list; (ifa = *ifap) != NULL; | ||
522 | ifap = &ifa->if_next) { | ||
523 | if (ifp_scope >= ipv6_addr_src_scope(&ifa->addr)) | ||
524 | break; | ||
525 | } | ||
526 | |||
527 | ifp->if_next = *ifap; | ||
528 | *ifap = ifp; | ||
529 | } | ||
530 | |||
511 | /* On success it returns ifp with increased reference count */ | 531 | /* On success it returns ifp with increased reference count */ |
512 | 532 | ||
513 | static struct inet6_ifaddr * | 533 | static struct inet6_ifaddr * |
@@ -573,8 +593,7 @@ ipv6_add_addr(struct inet6_dev *idev, const struct in6_addr *addr, int pfxlen, | |||
573 | 593 | ||
574 | write_lock(&idev->lock); | 594 | write_lock(&idev->lock); |
575 | /* Add to inet6_dev unicast addr list. */ | 595 | /* Add to inet6_dev unicast addr list. */ |
576 | ifa->if_next = idev->addr_list; | 596 | ipv6_link_dev_addr(idev, ifa); |
577 | idev->addr_list = ifa; | ||
578 | 597 | ||
579 | #ifdef CONFIG_IPV6_PRIVACY | 598 | #ifdef CONFIG_IPV6_PRIVACY |
580 | if (ifa->flags&IFA_F_TEMPORARY) { | 599 | if (ifa->flags&IFA_F_TEMPORARY) { |
@@ -987,7 +1006,7 @@ int ipv6_dev_get_saddr(struct net_device *daddr_dev, | |||
987 | continue; | 1006 | continue; |
988 | } else if (score.scope < hiscore.scope) { | 1007 | } else if (score.scope < hiscore.scope) { |
989 | if (score.scope < daddr_scope) | 1008 | if (score.scope < daddr_scope) |
990 | continue; | 1009 | break; /* addresses sorted by scope */ |
991 | else { | 1010 | else { |
992 | score.rule = 2; | 1011 | score.rule = 2; |
993 | goto record_it; | 1012 | goto record_it; |