aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6/addrconf.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv6/addrconf.c')
-rw-r--r--net/ipv6/addrconf.c53
1 files changed, 37 insertions, 16 deletions
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index f2c7e615f902..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)
2529static void init_loopback(struct net_device *dev) 2529static 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
2545static void addrconf_add_linklocal(struct inet6_dev *idev, const struct in6_addr *addr) 2572static void addrconf_add_linklocal(struct inet6_dev *idev, const struct in6_addr *addr)
@@ -4784,26 +4811,20 @@ static void addrconf_sysctl_unregister(struct inet6_dev *idev)
4784 4811
4785static int __net_init addrconf_init_net(struct net *net) 4812static int __net_init addrconf_init_net(struct net *net)
4786{ 4813{
4787 int err; 4814 int err = -ENOMEM;
4788 struct ipv6_devconf *all, *dflt; 4815 struct ipv6_devconf *all, *dflt;
4789 4816
4790 err = -ENOMEM; 4817 all = kmemdup(&ipv6_devconf, sizeof(ipv6_devconf), GFP_KERNEL);
4791 all = &ipv6_devconf; 4818 if (all == NULL)
4792 dflt = &ipv6_devconf_dflt; 4819 goto err_alloc_all;
4793 4820
4794 if (!net_eq(net, &init_net)) { 4821 dflt = kmemdup(&ipv6_devconf_dflt, sizeof(ipv6_devconf_dflt), GFP_KERNEL);
4795 all = kmemdup(all, sizeof(ipv6_devconf), GFP_KERNEL); 4822 if (dflt == NULL)
4796 if (all == NULL) 4823 goto err_alloc_dflt;
4797 goto err_alloc_all;
4798 4824
4799 dflt = kmemdup(dflt, sizeof(ipv6_devconf_dflt), GFP_KERNEL); 4825 /* these will be inherited by all namespaces */
4800 if (dflt == NULL) 4826 dflt->autoconf = ipv6_defaults.autoconf;
4801 goto err_alloc_dflt; 4827 dflt->disable_ipv6 = ipv6_defaults.disable_ipv6;
4802 } else {
4803 /* these will be inherited by all namespaces */
4804 dflt->autoconf = ipv6_defaults.autoconf;
4805 dflt->disable_ipv6 = ipv6_defaults.disable_ipv6;
4806 }
4807 4828
4808 net->ipv6.devconf_all = all; 4829 net->ipv6.devconf_all = all;
4809 net->ipv6.devconf_dflt = dflt; 4830 net->ipv6.devconf_dflt = dflt;