mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	ipv6: Refactor __ip6_route_redirect
Move the nexthop evaluation of a fib entry to a helper that can be leveraged for each fib6_nh in a multipath nexthop object. In the move, 'continue' statements means the helper returns false (loop should continue) and 'break' means return true (found the entry of interest). Signed-off-by: David Ahern <dsahern@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
		
							parent
							
								
									0c59d00675
								
							
						
					
					
						commit
						0b34eb0043
					
				
					 1 changed files with 33 additions and 23 deletions
				
			
		| 
						 | 
				
			
			@ -2407,6 +2407,35 @@ void ip6_sk_dst_store_flow(struct sock *sk, struct dst_entry *dst,
 | 
			
		|||
		      NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static bool ip6_redirect_nh_match(struct fib6_info *f6i,
 | 
			
		||||
				  struct fib6_nh *nh,
 | 
			
		||||
				  struct flowi6 *fl6,
 | 
			
		||||
				  const struct in6_addr *gw,
 | 
			
		||||
				  struct rt6_info **ret)
 | 
			
		||||
{
 | 
			
		||||
	if (nh->fib_nh_flags & RTNH_F_DEAD || !nh->fib_nh_gw_family ||
 | 
			
		||||
	    fl6->flowi6_oif != nh->fib_nh_dev->ifindex)
 | 
			
		||||
		return false;
 | 
			
		||||
 | 
			
		||||
	/* rt_cache's gateway might be different from its 'parent'
 | 
			
		||||
	 * in the case of an ip redirect.
 | 
			
		||||
	 * So we keep searching in the exception table if the gateway
 | 
			
		||||
	 * is different.
 | 
			
		||||
	 */
 | 
			
		||||
	if (!ipv6_addr_equal(gw, &nh->fib_nh_gw6)) {
 | 
			
		||||
		struct rt6_info *rt_cache;
 | 
			
		||||
 | 
			
		||||
		rt_cache = rt6_find_cached_rt(f6i, &fl6->daddr, &fl6->saddr);
 | 
			
		||||
		if (rt_cache &&
 | 
			
		||||
		    ipv6_addr_equal(gw, &rt_cache->rt6i_gateway)) {
 | 
			
		||||
			*ret = rt_cache;
 | 
			
		||||
			return true;
 | 
			
		||||
		}
 | 
			
		||||
		return false;
 | 
			
		||||
	}
 | 
			
		||||
	return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Handle redirects */
 | 
			
		||||
struct ip6rd_flowi {
 | 
			
		||||
	struct flowi6 fl6;
 | 
			
		||||
| 
						 | 
				
			
			@ -2420,7 +2449,7 @@ static struct rt6_info *__ip6_route_redirect(struct net *net,
 | 
			
		|||
					     int flags)
 | 
			
		||||
{
 | 
			
		||||
	struct ip6rd_flowi *rdfl = (struct ip6rd_flowi *)fl6;
 | 
			
		||||
	struct rt6_info *ret = NULL, *rt_cache;
 | 
			
		||||
	struct rt6_info *ret = NULL;
 | 
			
		||||
	struct fib6_info *rt;
 | 
			
		||||
	struct fib6_node *fn;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -2438,34 +2467,15 @@ static struct rt6_info *__ip6_route_redirect(struct net *net,
 | 
			
		|||
	fn = fib6_node_lookup(&table->tb6_root, &fl6->daddr, &fl6->saddr);
 | 
			
		||||
restart:
 | 
			
		||||
	for_each_fib6_node_rt_rcu(fn) {
 | 
			
		||||
		if (rt->fib6_nh.fib_nh_flags & RTNH_F_DEAD)
 | 
			
		||||
			continue;
 | 
			
		||||
		if (fib6_check_expired(rt))
 | 
			
		||||
			continue;
 | 
			
		||||
		if (rt->fib6_flags & RTF_REJECT)
 | 
			
		||||
			break;
 | 
			
		||||
		if (!rt->fib6_nh.fib_nh_gw_family)
 | 
			
		||||
			continue;
 | 
			
		||||
		if (fl6->flowi6_oif != rt->fib6_nh.fib_nh_dev->ifindex)
 | 
			
		||||
			continue;
 | 
			
		||||
		/* rt_cache's gateway might be different from its 'parent'
 | 
			
		||||
		 * in the case of an ip redirect.
 | 
			
		||||
		 * So we keep searching in the exception table if the gateway
 | 
			
		||||
		 * is different.
 | 
			
		||||
		 */
 | 
			
		||||
		if (!ipv6_addr_equal(&rdfl->gateway, &rt->fib6_nh.fib_nh_gw6)) {
 | 
			
		||||
			rt_cache = rt6_find_cached_rt(rt,
 | 
			
		||||
						      &fl6->daddr,
 | 
			
		||||
						      &fl6->saddr);
 | 
			
		||||
			if (rt_cache &&
 | 
			
		||||
			    ipv6_addr_equal(&rdfl->gateway,
 | 
			
		||||
					    &rt_cache->rt6i_gateway)) {
 | 
			
		||||
				ret = rt_cache;
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
			continue;
 | 
			
		||||
		}
 | 
			
		||||
		break;
 | 
			
		||||
		if (ip6_redirect_nh_match(rt, &rt->fib6_nh, fl6,
 | 
			
		||||
					  &rdfl->gateway, &ret))
 | 
			
		||||
			goto out;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (!rt)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue