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)  static void init_loopback(struct net_device *dev)  {  	struct inet6_dev  *idev; +	struct net_device *sp_dev; +	struct inet6_ifaddr *sp_ifa; +	struct rt6_info *sp_rt;  	/* ::1 */ @@ -2540,6 +2543,30 @@ static void init_loopback(struct net_device *dev)  	}  	add_addr(idev, &in6addr_loopback, 128, IFA_HOST); + +	/* Add routes to other interface's IPv6 addresses */ +	for_each_netdev(dev_net(dev), sp_dev) { +		if (!strcmp(sp_dev->name, dev->name)) +			continue; + +		idev = __in6_dev_get(sp_dev); +		if (!idev) +			continue; + +		read_lock_bh(&idev->lock); +		list_for_each_entry(sp_ifa, &idev->addr_list, if_list) { + +			if (sp_ifa->flags & (IFA_F_DADFAILED | IFA_F_TENTATIVE)) +				continue; + +			sp_rt = addrconf_dst_alloc(idev, &sp_ifa->addr, 0); + +			/* Failure cases are ignored */ +			if (!IS_ERR(sp_rt)) +				ip6_ins_rt(sp_rt); +		} +		read_unlock_bh(&idev->lock); +	}  }  static void addrconf_add_linklocal(struct inet6_dev *idev, const struct in6_addr *addr) |