git: 9d16275c65bf - main - netinet6: simplify defrouter_select_fib()
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Fri, 12 Aug 2022 12:45:14 UTC
The branch main has been updated by melifaro:
URL: https://cgit.FreeBSD.org/src/commit/?id=9d16275c65bfe0f577e6f97397e024a33169acc9
commit 9d16275c65bfe0f577e6f97397e024a33169acc9
Author: Alexander V. Chernikov <melifaro@FreeBSD.org>
AuthorDate: 2022-08-12 11:43:14 +0000
Commit: Alexander V. Chernikov <melifaro@FreeBSD.org>
CommitDate: 2022-08-12 11:43:37 +0000
netinet6: simplify defrouter_select_fib()
* factor out underlying llentry check into a separate function and use it consistently
* enter epoch once instead of per-router enter/exit
* don't execute body with fibnum = `RT_ALL_FIBS`
Differential Revision: https://reviews.freebsd.org/D35523
MFC after: 2 weeks
---
sys/netinet6/nd6_rtr.c | 51 ++++++++++++++++++++++----------------------------
1 file changed, 22 insertions(+), 29 deletions(-)
diff --git a/sys/netinet6/nd6_rtr.c b/sys/netinet6/nd6_rtr.c
index 47cc6bd0aa99..4502428e1690 100644
--- a/sys/netinet6/nd6_rtr.c
+++ b/sys/netinet6/nd6_rtr.c
@@ -915,6 +915,18 @@ rtpref(struct nd_defrouter *dr)
/* NOTREACHED */
}
+static bool
+is_dr_reachable(const struct nd_defrouter *dr) {
+ struct llentry *ln = NULL;
+
+ ln = nd6_lookup(&dr->rtaddr, LLE_SF(AF_INET6, 0), dr->ifp);
+ if (ln == NULL)
+ return (false);
+ bool reachable = ND6_IS_LLINFO_PROBREACH(ln);
+ LLE_RUNLOCK(ln);
+ return reachable;
+}
+
/*
* Default Router Selection according to Section 6.3.6 of RFC 2461 and
* draft-ietf-ipngwg-router-selection:
@@ -945,12 +957,12 @@ defrouter_select_fib(int fibnum)
{
struct epoch_tracker et;
struct nd_defrouter *dr, *selected_dr, *installed_dr;
- struct llentry *ln = NULL;
if (fibnum == RT_ALL_FIBS) {
for (fibnum = 0; fibnum < rt_numfibs; fibnum++) {
defrouter_select_fib(fibnum);
}
+ return;
}
ND6_RLOCK();
@@ -969,21 +981,17 @@ defrouter_select_fib(int fibnum)
* the ordering rule of the list described in defrtrlist_update().
*/
selected_dr = installed_dr = NULL;
+ NET_EPOCH_ENTER(et);
TAILQ_FOREACH(dr, &V_nd6_defrouter, dr_entry) {
- NET_EPOCH_ENTER(et);
- if (selected_dr == NULL && dr->ifp->if_fib == fibnum &&
- (ln = nd6_lookup(&dr->rtaddr, LLE_SF(AF_INET6, 0), dr->ifp)) &&
- ND6_IS_LLINFO_PROBREACH(ln)) {
+ if (dr->ifp->if_fib != fibnum)
+ continue;
+
+ if (selected_dr == NULL && is_dr_reachable(dr)) {
selected_dr = dr;
defrouter_ref(selected_dr);
}
- NET_EPOCH_EXIT(et);
- if (ln != NULL) {
- LLE_RUNLOCK(ln);
- ln = NULL;
- }
- if (dr->installed && dr->ifp->if_fib == fibnum) {
+ if (dr->installed) {
if (installed_dr == NULL) {
installed_dr = dr;
defrouter_ref(installed_dr);
@@ -997,6 +1005,7 @@ defrouter_select_fib(int fibnum)
}
}
}
+
/*
* If none of the default routers was found to be reachable,
* round-robin the list regardless of preference.
@@ -1021,22 +1030,14 @@ defrouter_select_fib(int fibnum)
}
}
} else if (installed_dr != NULL) {
- NET_EPOCH_ENTER(et);
- if ((ln = nd6_lookup(&installed_dr->rtaddr, 0,
- installed_dr->ifp)) &&
- ND6_IS_LLINFO_PROBREACH(ln) &&
- installed_dr->ifp->if_fib == fibnum &&
+ if (is_dr_reachable(installed_dr) &&
rtpref(selected_dr) <= rtpref(installed_dr)) {
defrouter_rele(selected_dr);
selected_dr = installed_dr;
}
- NET_EPOCH_EXIT(et);
- if (ln != NULL)
- LLE_RUNLOCK(ln);
}
ND6_RUNLOCK();
- NET_EPOCH_ENTER(et);
/*
* If we selected a router for this FIB and it's different
* than the installed one, remove the installed router and
@@ -1807,20 +1808,12 @@ find_pfxlist_reachable_router(struct nd_prefix *pr)
{
struct epoch_tracker et;
struct nd_pfxrouter *pfxrtr;
- struct llentry *ln;
- int canreach;
ND6_LOCK_ASSERT();
NET_EPOCH_ENTER(et);
LIST_FOREACH(pfxrtr, &pr->ndpr_advrtrs, pfr_entry) {
- ln = nd6_lookup(&pfxrtr->router->rtaddr, LLE_SF(AF_INET6, 0),
- pfxrtr->router->ifp);
- if (ln == NULL)
- continue;
- canreach = ND6_IS_LLINFO_PROBREACH(ln);
- LLE_RUNLOCK(ln);
- if (canreach)
+ if (is_dr_reachable(pfxrtr->router))
break;
}
NET_EPOCH_EXIT(et);