diff options
Diffstat (limited to 'net/ipv6/ip6_vti.c')
| -rw-r--r-- | net/ipv6/ip6_vti.c | 20 | 
1 files changed, 20 insertions, 0 deletions
| diff --git a/net/ipv6/ip6_vti.c b/net/ipv6/ip6_vti.c index 8c184f84f353..fa3ae1cb50d3 100644 --- a/net/ipv6/ip6_vti.c +++ b/net/ipv6/ip6_vti.c @@ -626,6 +626,7 @@ static void vti6_link_config(struct ip6_tnl *t)  {  	struct net_device *dev = t->dev;  	struct __ip6_tnl_parm *p = &t->parms; +	struct net_device *tdev = NULL;  	memcpy(dev->dev_addr, &p->laddr, sizeof(struct in6_addr));  	memcpy(dev->broadcast, &p->raddr, sizeof(struct in6_addr)); @@ -638,6 +639,25 @@ static void vti6_link_config(struct ip6_tnl *t)  		dev->flags |= IFF_POINTOPOINT;  	else  		dev->flags &= ~IFF_POINTOPOINT; + +	if (p->flags & IP6_TNL_F_CAP_XMIT) { +		int strict = (ipv6_addr_type(&p->raddr) & +			      (IPV6_ADDR_MULTICAST | IPV6_ADDR_LINKLOCAL)); +		struct rt6_info *rt = rt6_lookup(t->net, +						 &p->raddr, &p->laddr, +						 p->link, strict); + +		if (rt) +			tdev = rt->dst.dev; +		ip6_rt_put(rt); +	} + +	if (!tdev && p->link) +		tdev = __dev_get_by_index(t->net, p->link); + +	if (tdev) +		dev->mtu = max_t(int, tdev->mtu - dev->hard_header_len, +				 IPV6_MIN_MTU);  }  /** |