summaryrefslogtreecommitdiffstats
path: root/sys/netinet/in_rmx.c
diff options
context:
space:
mode:
authordelphij <delphij@FreeBSD.org>2010-09-27 19:26:56 +0000
committerdelphij <delphij@FreeBSD.org>2010-09-27 19:26:56 +0000
commitf0a3248def60f8c0835ab4354386d7ce007771bc (patch)
treead4db2ca515fc0cc41a568c55ee278cd8c7587ce /sys/netinet/in_rmx.c
parent3d9c031cfc23f4e72fda525c5941b62635e7abde (diff)
downloadFreeBSD-src-f0a3248def60f8c0835ab4354386d7ce007771bc.zip
FreeBSD-src-f0a3248def60f8c0835ab4354386d7ce007771bc.tar.gz
Add a bandaid for a long-standing race condition during route entry
un-expiring. The previous version of code have no locking when testing rt_refcnt. The result of the lack of locking may result in a condition where a routing entry have a reference count but at the same time have RTPRF_OURS bit set and an expiration timer. These would eventually lead to a panic: panic: rtqkill route really not free When the system have ICMP redirects accepted from local gateway in a moderate frequency, for instance. Commit this workaround for now until we have some better solution. PR: kern/149804 Reviewed by: bz Tested by: Zhao Xin, Pete French MFC after: 2 weeks
Diffstat (limited to 'sys/netinet/in_rmx.c')
-rw-r--r--sys/netinet/in_rmx.c5
1 files changed, 3 insertions, 2 deletions
diff --git a/sys/netinet/in_rmx.c b/sys/netinet/in_rmx.c
index 96406aa..1389873 100644
--- a/sys/netinet/in_rmx.c
+++ b/sys/netinet/in_rmx.c
@@ -121,12 +121,13 @@ in_matroute(void *v_arg, struct radix_node_head *head)
struct radix_node *rn = rn_match(v_arg, head);
struct rtentry *rt = (struct rtentry *)rn;
- /*XXX locking? */
- if (rt && rt->rt_refcnt == 0) { /* this is first reference */
+ if (rt) {
+ RT_LOCK(rt);
if (rt->rt_flags & RTPRF_OURS) {
rt->rt_flags &= ~RTPRF_OURS;
rt->rt_rmx.rmx_expire = 0;
}
+ RT_UNLOCK(rt);
}
return rn;
}
OpenPOWER on IntegriCloud