git: 9d16275c65bf - main - netinet6: simplify defrouter_select_fib()

From: Alexander V. Chernikov <melifaro_at_FreeBSD.org>
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);