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; |
