kern/149804: commit references a PR
dfilter service
dfilter at FreeBSD.ORG
Mon Sep 27 19:30:12 UTC 2010
The following reply was made to PR kern/149804; it has been noted by GNATS.
From: dfilter at FreeBSD.ORG (dfilter service)
To: bug-followup at FreeBSD.org
Cc:
Subject: Re: kern/149804: commit references a PR
Date: Mon, 27 Sep 2010 19:27:05 +0000 (UTC)
Author: delphij
Date: Mon Sep 27 19:26:56 2010
New Revision: 213225
URL: http://svn.freebsd.org/changeset/base/213225
Log:
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
Modified:
head/sys/netinet/in_rmx.c
head/sys/netinet6/in6_rmx.c
Modified: head/sys/netinet/in_rmx.c
==============================================================================
--- head/sys/netinet/in_rmx.c Mon Sep 27 19:03:18 2010 (r213224)
+++ head/sys/netinet/in_rmx.c Mon Sep 27 19:26:56 2010 (r213225)
@@ -121,12 +121,13 @@ in_matroute(void *v_arg, struct radix_no
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;
}
Modified: head/sys/netinet6/in6_rmx.c
==============================================================================
--- head/sys/netinet6/in6_rmx.c Mon Sep 27 19:03:18 2010 (r213224)
+++ head/sys/netinet6/in6_rmx.c Mon Sep 27 19:26:56 2010 (r213225)
@@ -193,11 +193,13 @@ in6_matroute(void *v_arg, struct radix_n
struct radix_node *rn = rn_match(v_arg, head);
struct rtentry *rt = (struct rtentry *)rn;
- 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;
}
_______________________________________________
svn-src-all at freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscribe at freebsd.org"
More information about the freebsd-net
mailing list