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>