ipv6: Handle all fib6_nh in a nexthop in __find_rr_leaf
Add a hook in __find_rr_leaf to handle nexthop struct in a fib6_info. nexthop_for_each_fib6_nh is used to walk each fib6_nh in a nexthop and call find_match. On a match, use the fib6_nh saved in the callback arg to setup fib6_result. Signed-off-by: David Ahern <dsahern@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
		
							parent
							
								
									962b680383
								
							
						
					
					
						commit
						17a5984eee
					
				| @ -765,6 +765,24 @@ out: | ||||
| 	return rc; | ||||
| } | ||||
| 
 | ||||
| struct fib6_nh_frl_arg { | ||||
| 	u32		flags; | ||||
| 	int		oif; | ||||
| 	int		strict; | ||||
| 	int		*mpri; | ||||
| 	bool		*do_rr; | ||||
| 	struct fib6_nh	*nh; | ||||
| }; | ||||
| 
 | ||||
| static int rt6_nh_find_match(struct fib6_nh *nh, void *_arg) | ||||
| { | ||||
| 	struct fib6_nh_frl_arg *arg = _arg; | ||||
| 
 | ||||
| 	arg->nh = nh; | ||||
| 	return find_match(nh, arg->flags, arg->oif, arg->strict, | ||||
| 			  arg->mpri, arg->do_rr); | ||||
| } | ||||
| 
 | ||||
| static void __find_rr_leaf(struct fib6_info *f6i_start, | ||||
| 			   struct fib6_info *nomatch, u32 metric, | ||||
| 			   struct fib6_result *res, struct fib6_info **cont, | ||||
| @ -775,6 +793,7 @@ static void __find_rr_leaf(struct fib6_info *f6i_start, | ||||
| 	for (f6i = f6i_start; | ||||
| 	     f6i && f6i != nomatch; | ||||
| 	     f6i = rcu_dereference(f6i->fib6_next)) { | ||||
| 		bool matched = false; | ||||
| 		struct fib6_nh *nh; | ||||
| 
 | ||||
| 		if (cont && f6i->fib6_metric != metric) { | ||||
| @ -785,8 +804,34 @@ static void __find_rr_leaf(struct fib6_info *f6i_start, | ||||
| 		if (fib6_check_expired(f6i)) | ||||
| 			continue; | ||||
| 
 | ||||
| 		nh = f6i->fib6_nh; | ||||
| 		if (find_match(nh, f6i->fib6_flags, oif, strict, mpri, do_rr)) { | ||||
| 		if (unlikely(f6i->nh)) { | ||||
| 			struct fib6_nh_frl_arg arg = { | ||||
| 				.flags  = f6i->fib6_flags, | ||||
| 				.oif    = oif, | ||||
| 				.strict = strict, | ||||
| 				.mpri   = mpri, | ||||
| 				.do_rr  = do_rr | ||||
| 			}; | ||||
| 
 | ||||
| 			if (nexthop_is_blackhole(f6i->nh)) { | ||||
| 				res->fib6_flags = RTF_REJECT; | ||||
| 				res->fib6_type = RTN_BLACKHOLE; | ||||
| 				res->f6i = f6i; | ||||
| 				res->nh = nexthop_fib6_nh(f6i->nh); | ||||
| 				return; | ||||
| 			} | ||||
| 			if (nexthop_for_each_fib6_nh(f6i->nh, rt6_nh_find_match, | ||||
| 						     &arg)) { | ||||
| 				matched = true; | ||||
| 				nh = arg.nh; | ||||
| 			} | ||||
| 		} else { | ||||
| 			nh = f6i->fib6_nh; | ||||
| 			if (find_match(nh, f6i->fib6_flags, oif, strict, | ||||
| 				       mpri, do_rr)) | ||||
| 				matched = true; | ||||
| 		} | ||||
| 		if (matched) { | ||||
| 			res->f6i = f6i; | ||||
| 			res->nh = nh; | ||||
| 			res->fib6_flags = f6i->fib6_flags; | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user