Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 13 Jun 2017 10:52:31 +0000 (UTC)
From:      "Andrey V. Elsukov" <ae@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r319895 - head/sys/net
Message-ID:  <201706131052.v5DAqVnF036704@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: ae
Date: Tue Jun 13 10:52:31 2017
New Revision: 319895
URL: https://svnweb.freebsd.org/changeset/base/319895

Log:
  Resurrect RTF_RNH_LOCKED flag and restore ability to call rtalloc1_fib()
  with acquired RIB lock.
  
  This fixes a possible panic due to trying to acquire RIB rlock when it is
  already exclusive locked.
  
  PR:		215963, 215122
  MFC after:	1 week
  Sponsored by:	Yandex LLC

Modified:
  head/sys/net/route.c
  head/sys/net/route.h

Modified: head/sys/net/route.c
==============================================================================
--- head/sys/net/route.c	Tue Jun 13 10:38:28 2017	(r319894)
+++ head/sys/net/route.c	Tue Jun 13 10:52:31 2017	(r319895)
@@ -454,18 +454,23 @@ rtalloc1_fib(struct sockaddr *dst, int report, u_long 
 	/*
 	 * Look up the address in the table for that Address Family
 	 */
-	RIB_RLOCK(rh);
+	if ((ignflags & RTF_RNH_LOCKED) == 0)
+		RIB_RLOCK(rh);
+#ifdef INVARIANTS
+	else
+		RIB_LOCK_ASSERT(rh);
+#endif
 	rn = rh->rnh_matchaddr(dst, &rh->head);
 	if (rn && ((rn->rn_flags & RNF_ROOT) == 0)) {
 		newrt = RNTORT(rn);
 		RT_LOCK(newrt);
 		RT_ADDREF(newrt);
-		RIB_RUNLOCK(rh);
+		if ((ignflags & RTF_RNH_LOCKED) == 0)
+			RIB_RUNLOCK(rh);
 		return (newrt);
 
-	} else
+	} else if ((ignflags & RTF_RNH_LOCKED) == 0)
 		RIB_RUNLOCK(rh);
-	
 	/*
 	 * Either we hit the root or could not find any match,
 	 * which basically means: "cannot get there from here".
@@ -748,7 +753,9 @@ ifa_ifwithroute(int flags, const struct sockaddr *dst,
 	if (ifa == NULL)
 		ifa = ifa_ifwithnet(gateway, 0, fibnum);
 	if (ifa == NULL) {
-		struct rtentry *rt = rtalloc1_fib(gateway, 0, 0, fibnum);
+		struct rtentry *rt;
+
+		rt = rtalloc1_fib(gateway, 0, flags, fibnum);
 		if (rt == NULL)
 			return (NULL);
 		/*
@@ -1838,8 +1845,13 @@ rtrequest1_fib_change(struct rib_head *rnh, struct rt_
 	    info->rti_info[RTAX_IFP] != NULL ||
 	    (info->rti_info[RTAX_IFA] != NULL &&
 	     !sa_equal(info->rti_info[RTAX_IFA], rt->rt_ifa->ifa_addr))) {
-
+		/*
+		 * XXX: Temporarily set RTF_RNH_LOCKED flag in the rti_flags
+		 *	to avoid rlock in the ifa_ifwithroute().
+		 */
+		info->rti_flags |= RTF_RNH_LOCKED;
 		error = rt_getifa_fib(info, fibnum);
+		info->rti_flags &= ~RTF_RNH_LOCKED;
 		if (info->rti_ifa != NULL)
 			free_ifa = 1;
 

Modified: head/sys/net/route.h
==============================================================================
--- head/sys/net/route.h	Tue Jun 13 10:38:28 2017	(r319894)
+++ head/sys/net/route.h	Tue Jun 13 10:52:31 2017	(r319895)
@@ -189,7 +189,7 @@ struct rtentry {
 					/* 0x8000000 and up unassigned */
 #define	RTF_STICKY	 0x10000000	/* always route dst->src */
 
-#define	RTF_RNH_LOCKED	 0x40000000	/* unused */
+#define	RTF_RNH_LOCKED	 0x40000000	/* radix node head is locked */
 
 #define	RTF_GWFLAG_COMPAT 0x80000000	/* a compatibility bit for interacting
 					   with existing routing apps */



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201706131052.v5DAqVnF036704>