Commit 28679ed1 authored by David Ahern's avatar David Ahern Committed by David S. Miller

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: default avatarDavid Ahern <dsahern@gmail.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 702cea56
...@@ -632,25 +632,22 @@ static int rt6_score_route(const struct fib6_nh *nh, u32 fib6_flags, int oif, ...@@ -632,25 +632,22 @@ static int rt6_score_route(const struct fib6_nh *nh, u32 fib6_flags, int oif,
return m; return m;
} }
static struct fib6_info *find_match(struct fib6_info *rt, int oif, int strict, static bool find_match(struct fib6_nh *nh, u32 fib6_flags,
int *mpri, struct fib6_info *match, int oif, int strict, int *mpri, bool *do_rr)
bool *do_rr)
{ {
int m;
bool match_do_rr = false; 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; goto out;
if (ip6_ignore_linkdown(rt->fib6_nh.fib_nh_dev) && if (ip6_ignore_linkdown(nh->fib_nh_dev) &&
rt->fib6_nh.fib_nh_flags & RTNH_F_LINKDOWN && nh->fib_nh_flags & RTNH_F_LINKDOWN &&
!(strict & RT6_LOOKUP_F_IGNORE_LINKSTATE)) !(strict & RT6_LOOKUP_F_IGNORE_LINKSTATE))
goto out; goto out;
if (fib6_check_expired(rt)) m = rt6_score_route(nh, fib6_flags, oif, strict);
goto out;
m = rt6_score_route(&rt->fib6_nh, rt->fib6_flags, oif, strict);
if (m == RT6_NUD_FAIL_DO_RR) { if (m == RT6_NUD_FAIL_DO_RR) {
match_do_rr = true; match_do_rr = true;
m = 0; /* lowest valid score */ m = 0; /* lowest valid score */
...@@ -659,16 +656,16 @@ static struct fib6_info *find_match(struct fib6_info *rt, int oif, int strict, ...@@ -659,16 +656,16 @@ static struct fib6_info *find_match(struct fib6_info *rt, int oif, int strict,
} }
if (strict & RT6_LOOKUP_F_REACHABLE) 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 */ /* note that m can be RT6_NUD_FAIL_PROBE at this point */
if (m > *mpri) { if (m > *mpri) {
*do_rr = match_do_rr; *do_rr = match_do_rr;
*mpri = m; *mpri = m;
match = rt; rc = true;
} }
out: out:
return match; return rc;
} }
static struct fib6_info *find_rr_leaf(struct fib6_node *fn, 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, ...@@ -678,6 +675,7 @@ static struct fib6_info *find_rr_leaf(struct fib6_node *fn,
bool *do_rr) bool *do_rr)
{ {
struct fib6_info *rt, *match, *cont; struct fib6_info *rt, *match, *cont;
struct fib6_nh *nh;
int mpri = -1; int mpri = -1;
match = NULL; match = NULL;
...@@ -688,7 +686,12 @@ static struct fib6_info *find_rr_leaf(struct fib6_node *fn, ...@@ -688,7 +686,12 @@ static struct fib6_info *find_rr_leaf(struct fib6_node *fn,
break; 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; for (rt = leaf; rt && rt != rr_head;
...@@ -698,14 +701,25 @@ static struct fib6_info *find_rr_leaf(struct fib6_node *fn, ...@@ -698,14 +701,25 @@ static struct fib6_info *find_rr_leaf(struct fib6_node *fn,
break; 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) if (match || !cont)
return match; return match;
for (rt = cont; rt; rt = rcu_dereference(rt->fib6_next)) for (rt = cont; rt; rt = rcu_dereference(rt->fib6_next)) {
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;
}
return match; return match;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment