diff options
| author | David Ahern <dsahern@gmail.com> | 2019-04-09 17:41:19 -0400 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2019-04-11 17:24:07 -0400 |
| commit | 0b34eb004347308ed0952ddb5b3898a71869ac3c (patch) | |
| tree | 4c67f46492b695373ffde163f26ef2e3c7bb8594 /net/ipv6 | |
| parent | 0c59d00675874f9ee7a0371ad9d9b69386ea2d03 (diff) | |
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>
Diffstat (limited to 'net/ipv6')
| -rw-r--r-- | net/ipv6/route.c | 56 |
1 files changed, 33 insertions, 23 deletions
diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 0e8becb1e455..d555edaaff13 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c | |||
| @@ -2407,6 +2407,35 @@ void ip6_sk_dst_store_flow(struct sock *sk, struct dst_entry *dst, | |||
| 2407 | NULL); | 2407 | NULL); |
| 2408 | } | 2408 | } |
| 2409 | 2409 | ||
| 2410 | static bool ip6_redirect_nh_match(struct fib6_info *f6i, | ||
| 2411 | struct fib6_nh *nh, | ||
| 2412 | struct flowi6 *fl6, | ||
| 2413 | const struct in6_addr *gw, | ||
| 2414 | struct rt6_info **ret) | ||
| 2415 | { | ||
| 2416 | if (nh->fib_nh_flags & RTNH_F_DEAD || !nh->fib_nh_gw_family || | ||
| 2417 | fl6->flowi6_oif != nh->fib_nh_dev->ifindex) | ||
| 2418 | return false; | ||
| 2419 | |||
| 2420 | /* rt_cache's gateway might be different from its 'parent' | ||
| 2421 | * in the case of an ip redirect. | ||
| 2422 | * So we keep searching in the exception table if the gateway | ||
| 2423 | * is different. | ||
| 2424 | */ | ||
| 2425 | if (!ipv6_addr_equal(gw, &nh->fib_nh_gw6)) { | ||
| 2426 | struct rt6_info *rt_cache; | ||
| 2427 | |||
| 2428 | rt_cache = rt6_find_cached_rt(f6i, &fl6->daddr, &fl6->saddr); | ||
| 2429 | if (rt_cache && | ||
| 2430 | ipv6_addr_equal(gw, &rt_cache->rt6i_gateway)) { | ||
| 2431 | *ret = rt_cache; | ||
| 2432 | return true; | ||
| 2433 | } | ||
| 2434 | return false; | ||
| 2435 | } | ||
| 2436 | return true; | ||
| 2437 | } | ||
| 2438 | |||
| 2410 | /* Handle redirects */ | 2439 | /* Handle redirects */ |
| 2411 | struct ip6rd_flowi { | 2440 | struct ip6rd_flowi { |
| 2412 | struct flowi6 fl6; | 2441 | struct flowi6 fl6; |
| @@ -2420,7 +2449,7 @@ static struct rt6_info *__ip6_route_redirect(struct net *net, | |||
| 2420 | int flags) | 2449 | int flags) |
| 2421 | { | 2450 | { |
| 2422 | struct ip6rd_flowi *rdfl = (struct ip6rd_flowi *)fl6; | 2451 | struct ip6rd_flowi *rdfl = (struct ip6rd_flowi *)fl6; |
| 2423 | struct rt6_info *ret = NULL, *rt_cache; | 2452 | struct rt6_info *ret = NULL; |
| 2424 | struct fib6_info *rt; | 2453 | struct fib6_info *rt; |
| 2425 | struct fib6_node *fn; | 2454 | struct fib6_node *fn; |
| 2426 | 2455 | ||
| @@ -2438,34 +2467,15 @@ static struct rt6_info *__ip6_route_redirect(struct net *net, | |||
| 2438 | fn = fib6_node_lookup(&table->tb6_root, &fl6->daddr, &fl6->saddr); | 2467 | fn = fib6_node_lookup(&table->tb6_root, &fl6->daddr, &fl6->saddr); |
| 2439 | restart: | 2468 | restart: |
| 2440 | for_each_fib6_node_rt_rcu(fn) { | 2469 | for_each_fib6_node_rt_rcu(fn) { |
| 2441 | if (rt->fib6_nh.fib_nh_flags & RTNH_F_DEAD) | ||
| 2442 | continue; | ||
| 2443 | if (fib6_check_expired(rt)) | 2470 | if (fib6_check_expired(rt)) |
| 2444 | continue; | 2471 | continue; |
| 2445 | if (rt->fib6_flags & RTF_REJECT) | 2472 | if (rt->fib6_flags & RTF_REJECT) |
| 2446 | break; | 2473 | break; |
| 2447 | if (!rt->fib6_nh.fib_nh_gw_family) | ||
| 2448 | continue; | ||
| 2449 | if (fl6->flowi6_oif != rt->fib6_nh.fib_nh_dev->ifindex) | 2474 | if (fl6->flowi6_oif != rt->fib6_nh.fib_nh_dev->ifindex) |
| 2450 | continue; | 2475 | continue; |
| 2451 | /* rt_cache's gateway might be different from its 'parent' | 2476 | if (ip6_redirect_nh_match(rt, &rt->fib6_nh, fl6, |
| 2452 | * in the case of an ip redirect. | 2477 | &rdfl->gateway, &ret)) |
| 2453 | * So we keep searching in the exception table if the gateway | 2478 | goto out; |
| 2454 | * is different. | ||
| 2455 | */ | ||
| 2456 | if (!ipv6_addr_equal(&rdfl->gateway, &rt->fib6_nh.fib_nh_gw6)) { | ||
| 2457 | rt_cache = rt6_find_cached_rt(rt, | ||
| 2458 | &fl6->daddr, | ||
| 2459 | &fl6->saddr); | ||
| 2460 | if (rt_cache && | ||
| 2461 | ipv6_addr_equal(&rdfl->gateway, | ||
| 2462 | &rt_cache->rt6i_gateway)) { | ||
| 2463 | ret = rt_cache; | ||
| 2464 | break; | ||
| 2465 | } | ||
| 2466 | continue; | ||
| 2467 | } | ||
| 2468 | break; | ||
| 2469 | } | 2479 | } |
| 2470 | 2480 | ||
| 2471 | if (!rt) | 2481 | if (!rt) |
