summaryrefslogtreecommitdiff
path: root/sys/net/route.c
diff options
context:
space:
mode:
authorAndrey V. Elsukov <ae@FreeBSD.org>2017-06-13 10:52:31 +0000
committerAndrey V. Elsukov <ae@FreeBSD.org>2017-06-13 10:52:31 +0000
commitb83aa367a51b9449e175912b7eb604f5299e7971 (patch)
tree47fffd70cf8546a6d7700281b96d5bdaee8bc2db /sys/net/route.c
parentdfde8e4b54fead6a899d9cbba64a503c6e5f9d1d (diff)
downloadsrc-test2-b83aa367a51b9449e175912b7eb604f5299e7971.tar.gz
src-test2-b83aa367a51b9449e175912b7eb604f5299e7971.zip
Notes
Diffstat (limited to 'sys/net/route.c')
-rw-r--r--sys/net/route.c24
1 files changed, 18 insertions, 6 deletions
diff --git a/sys/net/route.c b/sys/net/route.c
index 408452e6bee6..498b9be91cf1 100644
--- a/sys/net/route.c
+++ b/sys/net/route.c
@@ -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;