diff options
Diffstat (limited to 'net/ipv6/addrconf.c')
| -rw-r--r-- | net/ipv6/addrconf.c | 79 | 
1 files changed, 42 insertions, 37 deletions
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index d6ff12617f36..cd3fb301da38 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -1499,6 +1499,33 @@ static bool ipv6_chk_same_addr(struct net *net, const struct in6_addr *addr,  	return false;  } +/* Compares an address/prefix_len with addresses on device @dev. + * If one is found it returns true. + */ +bool ipv6_chk_custom_prefix(const struct in6_addr *addr, +	const unsigned int prefix_len, struct net_device *dev) +{ +	struct inet6_dev *idev; +	struct inet6_ifaddr *ifa; +	bool ret = false; + +	rcu_read_lock(); +	idev = __in6_dev_get(dev); +	if (idev) { +		read_lock_bh(&idev->lock); +		list_for_each_entry(ifa, &idev->addr_list, if_list) { +			ret = ipv6_prefix_equal(addr, &ifa->addr, prefix_len); +			if (ret) +				break; +		} +		read_unlock_bh(&idev->lock); +	} +	rcu_read_unlock(); + +	return ret; +} +EXPORT_SYMBOL(ipv6_chk_custom_prefix); +  int ipv6_chk_prefix(const struct in6_addr *addr, struct net_device *dev)  {  	struct inet6_dev *idev; @@ -2193,43 +2220,21 @@ ok:  			else  				stored_lft = 0;  			if (!update_lft && !create && stored_lft) { -				if (valid_lft > MIN_VALID_LIFETIME || -				    valid_lft > stored_lft) -					update_lft = 1; -				else if (stored_lft <= MIN_VALID_LIFETIME) { -					/* valid_lft <= stored_lft is always true */ -					/* -					 * RFC 4862 Section 5.5.3e: -					 * "Note that the preferred lifetime of -					 *  the corresponding address is always -					 *  reset to the Preferred Lifetime in -					 *  the received Prefix Information -					 *  option, regardless of whether the -					 *  valid lifetime is also reset or -					 *  ignored." -					 * -					 *  So if the preferred lifetime in -					 *  this advertisement is different -					 *  than what we have stored, but the -					 *  valid lifetime is invalid, just -					 *  reset prefered_lft. -					 * -					 *  We must set the valid lifetime -					 *  to the stored lifetime since we'll -					 *  be updating the timestamp below, -					 *  else we'll set it back to the -					 *  minimum. -					 */ -					if (prefered_lft != ifp->prefered_lft) { -						valid_lft = stored_lft; -						update_lft = 1; -					} -				} else { -					valid_lft = MIN_VALID_LIFETIME; -					if (valid_lft < prefered_lft) -						prefered_lft = valid_lft; -					update_lft = 1; -				} +				const u32 minimum_lft = min( +					stored_lft, (u32)MIN_VALID_LIFETIME); +				valid_lft = max(valid_lft, minimum_lft); + +				/* RFC4862 Section 5.5.3e: +				 * "Note that the preferred lifetime of the +				 *  corresponding address is always reset to +				 *  the Preferred Lifetime in the received +				 *  Prefix Information option, regardless of +				 *  whether the valid lifetime is also reset or +				 *  ignored." +				 * +				 * So we should always update prefered_lft here. +				 */ +				update_lft = 1;  			}  			if (update_lft) {  | 
