diff options
Diffstat (limited to 'net/ipv6')
-rw-r--r-- | net/ipv6/addrconf.c | 27 |
1 files changed, 27 insertions, 0 deletions
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 26512250e095..a459c4f5b769 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c | |||
@@ -2529,6 +2529,9 @@ static void sit_add_v4_addrs(struct inet6_dev *idev) | |||
2529 | static void init_loopback(struct net_device *dev) | 2529 | static void init_loopback(struct net_device *dev) |
2530 | { | 2530 | { |
2531 | struct inet6_dev *idev; | 2531 | struct inet6_dev *idev; |
2532 | struct net_device *sp_dev; | ||
2533 | struct inet6_ifaddr *sp_ifa; | ||
2534 | struct rt6_info *sp_rt; | ||
2532 | 2535 | ||
2533 | /* ::1 */ | 2536 | /* ::1 */ |
2534 | 2537 | ||
@@ -2540,6 +2543,30 @@ static void init_loopback(struct net_device *dev) | |||
2540 | } | 2543 | } |
2541 | 2544 | ||
2542 | add_addr(idev, &in6addr_loopback, 128, IFA_HOST); | 2545 | add_addr(idev, &in6addr_loopback, 128, IFA_HOST); |
2546 | |||
2547 | /* Add routes to other interface's IPv6 addresses */ | ||
2548 | for_each_netdev(dev_net(dev), sp_dev) { | ||
2549 | if (!strcmp(sp_dev->name, dev->name)) | ||
2550 | continue; | ||
2551 | |||
2552 | idev = __in6_dev_get(sp_dev); | ||
2553 | if (!idev) | ||
2554 | continue; | ||
2555 | |||
2556 | read_lock_bh(&idev->lock); | ||
2557 | list_for_each_entry(sp_ifa, &idev->addr_list, if_list) { | ||
2558 | |||
2559 | if (sp_ifa->flags & (IFA_F_DADFAILED | IFA_F_TENTATIVE)) | ||
2560 | continue; | ||
2561 | |||
2562 | sp_rt = addrconf_dst_alloc(idev, &sp_ifa->addr, 0); | ||
2563 | |||
2564 | /* Failure cases are ignored */ | ||
2565 | if (!IS_ERR(sp_rt)) | ||
2566 | ip6_ins_rt(sp_rt); | ||
2567 | } | ||
2568 | read_unlock_bh(&idev->lock); | ||
2569 | } | ||
2543 | } | 2570 | } |
2544 | 2571 | ||
2545 | static void addrconf_add_linklocal(struct inet6_dev *idev, const struct in6_addr *addr) | 2572 | static void addrconf_add_linklocal(struct inet6_dev *idev, const struct in6_addr *addr) |