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
This commit is contained in:
parent
dfde8e4b54
commit
b83aa367a5
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=319895
@ -454,18 +454,23 @@ rtalloc1_fib(struct sockaddr *dst, int report, u_long ignflags,
|
||||
/*
|
||||
* 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, struct sockaddr *gateway,
|
||||
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_addrinfo *info,
|
||||
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;
|
||||
|
||||
|
@ -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 */
|
||||
|
Loading…
Reference in New Issue
Block a user