diff options
Diffstat (limited to 'net/ipv6/route.c')
| -rw-r--r-- | net/ipv6/route.c | 38 | 
1 files changed, 20 insertions, 18 deletions
diff --git a/net/ipv6/route.c b/net/ipv6/route.c index a493ad9b891..7ff687020fa 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -109,7 +109,7 @@ static struct dst_ops ip6_dst_ops_template = {  	.negative_advice	=	ip6_negative_advice,  	.link_failure		=	ip6_link_failure,  	.update_pmtu		=	ip6_rt_update_pmtu, -	.local_out		=	ip6_local_out, +	.local_out		=	__ip6_local_out,  	.entry_size		=	sizeof(struct rt6_info),  	.entries		=	ATOMIC_INIT(0),  }; @@ -240,7 +240,7 @@ static inline int rt6_need_strict(struct in6_addr *daddr)  static inline struct rt6_info *rt6_device_match(struct net *net,  						    struct rt6_info *rt,  						    int oif, -						    int strict) +						    int flags)  {  	struct rt6_info *local = NULL;  	struct rt6_info *sprt; @@ -253,7 +253,7 @@ static inline struct rt6_info *rt6_device_match(struct net *net,  			if (dev->flags & IFF_LOOPBACK) {  				if (sprt->rt6i_idev == NULL ||  				    sprt->rt6i_idev->dev->ifindex != oif) { -					if (strict && oif) +					if (flags & RT6_LOOKUP_F_IFACE && oif)  						continue;  					if (local && (!oif ||  						      local->rt6i_idev->dev->ifindex == oif)) @@ -266,7 +266,7 @@ static inline struct rt6_info *rt6_device_match(struct net *net,  		if (local)  			return local; -		if (strict) +		if (flags & RT6_LOOKUP_F_IFACE)  			return net->ipv6.ip6_null_entry;  	}  	return rt; @@ -446,7 +446,7 @@ int rt6_route_rcv(struct net_device *dev, u8 *opt, int len,  	struct route_info *rinfo = (struct route_info *) opt;  	struct in6_addr prefix_buf, *prefix;  	unsigned int pref; -	u32 lifetime; +	unsigned long lifetime;  	struct rt6_info *rt;  	if (len < sizeof(struct route_info)) { @@ -472,13 +472,7 @@ int rt6_route_rcv(struct net_device *dev, u8 *opt, int len,  	if (pref == ICMPV6_ROUTER_PREF_INVALID)  		pref = ICMPV6_ROUTER_PREF_MEDIUM; -	lifetime = ntohl(rinfo->lifetime); -	if (lifetime == 0xffffffff) { -		/* infinity */ -	} else if (lifetime > 0x7fffffff/HZ) { -		/* Avoid arithmetic overflow */ -		lifetime = 0x7fffffff/HZ - 1; -	} +	lifetime = addrconf_timeout_fixup(ntohl(rinfo->lifetime), HZ);  	if (rinfo->length == 3)  		prefix = (struct in6_addr *)rinfo->prefix; @@ -506,7 +500,7 @@ int rt6_route_rcv(struct net_device *dev, u8 *opt, int len,  				 (rt->rt6i_flags & ~RTF_PREF_MASK) | RTF_PREF(pref);  	if (rt) { -		if (lifetime == 0xffffffff) { +		if (!addrconf_finite_timeout(lifetime)) {  			rt->rt6i_flags &= ~RTF_EXPIRES;  		} else {  			rt->rt6i_expires = jiffies + HZ * lifetime; @@ -1106,7 +1100,9 @@ int ip6_route_add(struct fib6_config *cfg)  	}  	rt->u.dst.obsolete = -1; -	rt->rt6i_expires = jiffies + clock_t_to_jiffies(cfg->fc_expires); +	rt->rt6i_expires = (cfg->fc_flags & RTF_EXPIRES) ? +				jiffies + clock_t_to_jiffies(cfg->fc_expires) : +				0;  	if (cfg->fc_protocol == RTPROT_UNSPEC)  		cfg->fc_protocol = RTPROT_BOOT; @@ -1243,11 +1239,11 @@ install_route:  		}  	} -	if (rt->u.dst.metrics[RTAX_HOPLIMIT-1] == 0) +	if (dst_metric(&rt->u.dst, RTAX_HOPLIMIT) == 0)  		rt->u.dst.metrics[RTAX_HOPLIMIT-1] = -1; -	if (!rt->u.dst.metrics[RTAX_MTU-1]) +	if (!dst_metric(&rt->u.dst, RTAX_MTU))  		rt->u.dst.metrics[RTAX_MTU-1] = ipv6_get_mtu(dev); -	if (!rt->u.dst.metrics[RTAX_ADVMSS-1]) +	if (!dst_metric(&rt->u.dst, RTAX_ADVMSS))  		rt->u.dst.metrics[RTAX_ADVMSS-1] = ipv6_advmss(net, dst_mtu(&rt->u.dst));  	rt->u.dst.dev = dev;  	rt->rt6i_idev = idev; @@ -2200,7 +2196,13 @@ static int rt6_fill_node(struct sk_buff *skb, struct rt6_info *rt,  	NLA_PUT_U32(skb, RTA_PRIORITY, rt->rt6i_metric); -	expires = rt->rt6i_expires ? rt->rt6i_expires - jiffies : 0; +	if (!(rt->rt6i_flags & RTF_EXPIRES)) +		expires = 0; +	else if (rt->rt6i_expires - jiffies < INT_MAX) +		expires = rt->rt6i_expires - jiffies; +	else +		expires = INT_MAX; +  	if (rtnl_put_cacheinfo(skb, &rt->u.dst, 0, 0, 0,  			       expires, rt->u.dst.error) < 0)  		goto nla_put_failure;  |