diff options
author | David Ahern <dsahern@gmail.com> | 2019-04-09 23:41:14 +0200 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2019-04-11 23:24:06 +0200 |
commit | 28679ed1047955e1a618984c90e4f1c6bfdaeb93 (patch) | |
tree | a4d6270deb66855a791aad60e66b714d5a64b128 /net/ipv6/route.c | |
parent | ipv6: Pass fib6_nh and flags to rt6_score_route (diff) | |
download | linux-28679ed1047955e1a618984c90e4f1c6bfdaeb93.tar.xz linux-28679ed1047955e1a618984c90e4f1c6bfdaeb93.zip |
ipv6: Refactor find_match
find_match primarily needs a fib6_nh (and fib6_flags which it passes
through to rt6_score_route). Move fib6_check_expired up to the call
sites so find_match is only called for relevant entries. Remove the
match argument which is mostly a pass through and use the return
boolean to decide if match gets set in the call sites.
The end result is a helper that can be called per fib6_nh struct
which is needed once fib entries reference nexthop objects that
have more than one fib6_nh.
Signed-off-by: David Ahern <dsahern@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to '')
-rw-r--r-- | net/ipv6/route.c | 50 |
1 files changed, 32 insertions, 18 deletions
diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 22d1933278ae..200bd5bb56bf 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -632,25 +632,22 @@ static int rt6_score_route(const struct fib6_nh *nh, u32 fib6_flags, int oif, return m; } -static struct fib6_info *find_match(struct fib6_info *rt, int oif, int strict, - int *mpri, struct fib6_info *match, - bool *do_rr) +static bool find_match(struct fib6_nh *nh, u32 fib6_flags, + int oif, int strict, int *mpri, bool *do_rr) { - int m; bool match_do_rr = false; + bool rc = false; + int m; - if (rt->fib6_nh.fib_nh_flags & RTNH_F_DEAD) + if (nh->fib_nh_flags & RTNH_F_DEAD) goto out; - if (ip6_ignore_linkdown(rt->fib6_nh.fib_nh_dev) && - rt->fib6_nh.fib_nh_flags & RTNH_F_LINKDOWN && + if (ip6_ignore_linkdown(nh->fib_nh_dev) && + nh->fib_nh_flags & RTNH_F_LINKDOWN && !(strict & RT6_LOOKUP_F_IGNORE_LINKSTATE)) goto out; - if (fib6_check_expired(rt)) - goto out; - - m = rt6_score_route(&rt->fib6_nh, rt->fib6_flags, oif, strict); + m = rt6_score_route(nh, fib6_flags, oif, strict); if (m == RT6_NUD_FAIL_DO_RR) { match_do_rr = true; m = 0; /* lowest valid score */ @@ -659,16 +656,16 @@ static struct fib6_info *find_match(struct fib6_info *rt, int oif, int strict, } if (strict & RT6_LOOKUP_F_REACHABLE) - rt6_probe(&rt->fib6_nh); + rt6_probe(nh); /* note that m can be RT6_NUD_FAIL_PROBE at this point */ if (m > *mpri) { *do_rr = match_do_rr; *mpri = m; - match = rt; + rc = true; } out: - return match; + return rc; } static struct fib6_info *find_rr_leaf(struct fib6_node *fn, @@ -678,6 +675,7 @@ static struct fib6_info *find_rr_leaf(struct fib6_node *fn, bool *do_rr) { struct fib6_info *rt, *match, *cont; + struct fib6_nh *nh; int mpri = -1; match = NULL; @@ -688,7 +686,12 @@ static struct fib6_info *find_rr_leaf(struct fib6_node *fn, break; } - match = find_match(rt, oif, strict, &mpri, match, do_rr); + if (fib6_check_expired(rt)) + continue; + + nh = &rt->fib6_nh; + if (find_match(nh, rt->fib6_flags, oif, strict, &mpri, do_rr)) + match = rt; } for (rt = leaf; rt && rt != rr_head; @@ -698,14 +701,25 @@ static struct fib6_info *find_rr_leaf(struct fib6_node *fn, break; } - match = find_match(rt, oif, strict, &mpri, match, do_rr); + if (fib6_check_expired(rt)) + continue; + + nh = &rt->fib6_nh; + if (find_match(nh, rt->fib6_flags, oif, strict, &mpri, do_rr)) + match = rt; } if (match || !cont) return match; - for (rt = cont; rt; rt = rcu_dereference(rt->fib6_next)) - match = find_match(rt, oif, strict, &mpri, match, do_rr); + for (rt = cont; rt; rt = rcu_dereference(rt->fib6_next)) { + if (fib6_check_expired(rt)) + continue; + + nh = &rt->fib6_nh; + if (find_match(nh, rt->fib6_flags, oif, strict, &mpri, do_rr)) + match = rt; + } return match; } |