[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20190409214119.15258-7-dsahern@kernel.org>
Date: Tue, 9 Apr 2019 14:41:15 -0700
From: David Ahern <dsahern@...nel.org>
To: davem@...emloft.net, netdev@...r.kernel.org
Cc: idosch@...lanox.com, David Ahern <dsahern@...il.com>
Subject: [PATCH net-next 06/10] ipv6: Refactor find_rr_leaf
From: David Ahern <dsahern@...il.com>
find_rr_leaf has 3 loops over fib_entries calling find_match. The loops
are very similar with differences in start point and whether the metric
is evaluated:
1. start at rr_head, no extra loop compare, check fib metric
2. start at leaf, compare rt against rr_head, check metric
3. start at cont (potential saved point from earlier loops), no
extra loop compare, no metric check
Create 1 loop that is called 3 different times. This will make a
later change with multipath nexthop objects much simpler.
Signed-off-by: David Ahern <dsahern@...il.com>
---
net/ipv6/route.c | 66 ++++++++++++++++++++++++++------------------------------
1 file changed, 30 insertions(+), 36 deletions(-)
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index 200bd5bb56bf..52aa48a8dbda 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -668,58 +668,52 @@ static bool find_match(struct fib6_nh *nh, u32 fib6_flags,
return rc;
}
-static struct fib6_info *find_rr_leaf(struct fib6_node *fn,
- struct fib6_info *leaf,
- struct fib6_info *rr_head,
- u32 metric, int oif, int strict,
- bool *do_rr)
+static void __find_rr_leaf(struct fib6_info *rt_start,
+ struct fib6_info *nomatch, u32 metric,
+ struct fib6_info **match, struct fib6_info **cont,
+ int oif, int strict, bool *do_rr, int *mpri)
{
- struct fib6_info *rt, *match, *cont;
- struct fib6_nh *nh;
- int mpri = -1;
+ struct fib6_info *rt;
- match = NULL;
- cont = NULL;
- for (rt = rr_head; rt; rt = rcu_dereference(rt->fib6_next)) {
- if (rt->fib6_metric != metric) {
- cont = rt;
- break;
+ for (rt = rt_start;
+ rt && rt != nomatch;
+ rt = rcu_dereference(rt->fib6_next)) {
+ struct fib6_nh *nh;
+
+ if (cont && rt->fib6_metric != metric) {
+ *cont = rt;
+ return;
}
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 (find_match(nh, rt->fib6_flags, oif, strict, mpri, do_rr))
+ *match = rt;
}
+}
- for (rt = leaf; rt && rt != rr_head;
- rt = rcu_dereference(rt->fib6_next)) {
- if (rt->fib6_metric != metric) {
- cont = rt;
- break;
- }
+static struct fib6_info *find_rr_leaf(struct fib6_node *fn,
+ struct fib6_info *leaf,
+ struct fib6_info *rr_head,
+ u32 metric, int oif, int strict,
+ bool *do_rr)
+{
+ struct fib6_info *match = NULL, *cont = NULL;
+ int mpri = -1;
- if (fib6_check_expired(rt))
- continue;
+ __find_rr_leaf(rr_head, NULL, metric, &match, &cont,
+ oif, strict, do_rr, &mpri);
- nh = &rt->fib6_nh;
- if (find_match(nh, rt->fib6_flags, oif, strict, &mpri, do_rr))
- match = rt;
- }
+ __find_rr_leaf(leaf, rr_head, metric, &match, &cont,
+ oif, strict, do_rr, &mpri);
if (match || !cont)
return match;
- 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;
- }
+ __find_rr_leaf(cont, NULL, metric, &match, NULL,
+ oif, strict, do_rr, &mpri);
return match;
}
--
2.11.0
Powered by blists - more mailing lists