diff options
author | kmacy <kmacy@FreeBSD.org> | 2008-12-10 09:21:52 +0000 |
---|---|---|
committer | kmacy <kmacy@FreeBSD.org> | 2008-12-10 09:21:52 +0000 |
commit | 5c136f32ed16508d6aad90c4de48153890ff71dd (patch) | |
tree | 292ba17868cac07bf01c25812ded5c4bc7b09d9d | |
parent | 1db5145a8d916011049ba78bd93f43d2bb21e114 (diff) | |
download | FreeBSD-src-5c136f32ed16508d6aad90c4de48153890ff71dd.zip FreeBSD-src-5c136f32ed16508d6aad90c4de48153890ff71dd.tar.gz |
fix a reported panic when adding a route and one hit here when deleting a route
- pass RTF_RNH_LOCKED to rtalloc1_fib in 2 cases where the lock is held
- make sure the rnh lock is held across rt_setgate and rt_getifa_fib
-rw-r--r-- | sys/net/route.c | 4 | ||||
-rw-r--r-- | sys/net/rtsock.c | 12 |
2 files changed, 12 insertions, 4 deletions
diff --git a/sys/net/route.c b/sys/net/route.c index 365ec1e..be71e13 100644 --- a/sys/net/route.c +++ b/sys/net/route.c @@ -680,7 +680,7 @@ ifa_ifwithroute_fib(int flags, struct sockaddr *dst, struct sockaddr *gateway, if (ifa == NULL) ifa = ifa_ifwithnet(gateway); if (ifa == NULL) { - struct rtentry *rt = rtalloc1_fib(gateway, 0, 0UL, fibnum); + struct rtentry *rt = rtalloc1_fib(gateway, 0, RTF_RNH_LOCKED, fibnum); if (rt == NULL) return (NULL); /* @@ -1161,7 +1161,7 @@ deldone: * then we just blow it away and retry the insertion * of the new one. */ - rt2 = rtalloc1_fib(dst, 0, 0, fibnum); + rt2 = rtalloc1_fib(dst, 0, RTF_RNH_LOCKED, fibnum); if (rt2 && rt2->rt_parent) { rtexpunge(rt2); RT_UNLOCK(rt2); diff --git a/sys/net/rtsock.c b/sys/net/rtsock.c index 03bf7fa..e8cc021 100644 --- a/sys/net/rtsock.c +++ b/sys/net/rtsock.c @@ -672,9 +672,11 @@ route_output(struct mbuf *m, struct socket *so) !sa_equal(info.rti_info[RTAX_IFA], rt->rt_ifa->ifa_addr))) { RT_UNLOCK(rt); + RADIX_NODE_HEAD_LOCK(rnh); if ((error = rt_getifa_fib(&info, rt->rt_fibnum)) != 0) senderr(error); + RADIX_NODE_HEAD_UNLOCK(rnh); RT_LOCK(rt); } if (info.rti_ifa != NULL && @@ -686,8 +688,14 @@ route_output(struct mbuf *m, struct socket *so) IFAFREE(rt->rt_ifa); } if (info.rti_info[RTAX_GATEWAY] != NULL) { - if ((error = rt_setgate(rt, rt_key(rt), - info.rti_info[RTAX_GATEWAY])) != 0) { + RT_UNLOCK(rt); + RADIX_NODE_HEAD_LOCK(rnh); + RT_LOCK(rt); + + error = rt_setgate(rt, rt_key(rt), + info.rti_info[RTAX_GATEWAY]); + RADIX_NODE_HEAD_UNLOCK(rnh); + if (error != 0) { RT_UNLOCK(rt); senderr(error); } |