summaryrefslogtreecommitdiffstats
path: root/sys/netinet6
diff options
context:
space:
mode:
authorglebius <glebius@FreeBSD.org>2012-12-13 11:11:15 +0000
committerglebius <glebius@FreeBSD.org>2012-12-13 11:11:15 +0000
commit8137816adb03dc4adf599f4790b2f2cecbe5f5b4 (patch)
treee234b73341b1557dce509188f3ea487c6df2c5fa /sys/netinet6
parent2d5902ca92bed1978312dee52ee4a8d78fb4046a (diff)
downloadFreeBSD-src-8137816adb03dc4adf599f4790b2f2cecbe5f5b4.zip
FreeBSD-src-8137816adb03dc4adf599f4790b2f2cecbe5f5b4.tar.gz
Fix problem in r238990. The LLE_LINKED flag should be tested prior to
entering llentry_free(), and in case if we lose the race, we should simply perform LLE_FREE_LOCKED(). Otherwise, if the race is lost by the thread performing arptimer(), it will remove two references from the lle instead of one. Reported by: Ian FREISLICH <ianf clue.co.za>
Diffstat (limited to 'sys/netinet6')
-rw-r--r--sys/netinet6/nd6.c10
1 files changed, 8 insertions, 2 deletions
diff --git a/sys/netinet6/nd6.c b/sys/netinet6/nd6.c
index 9993c77..5107f1d 100644
--- a/sys/netinet6/nd6.c
+++ b/sys/netinet6/nd6.c
@@ -1108,8 +1108,14 @@ nd6_free(struct llentry *ln, int gc)
LLE_WUNLOCK(ln);
IF_AFDATA_LOCK(ifp);
LLE_WLOCK(ln);
- LLE_REMREF(ln);
- llentry_free(ln);
+
+ /* Guard against race with other llentry_free(). */
+ if (ln->la_flags & LLE_LINKED) {
+ LLE_REMREF(ln);
+ llentry_free(ln);
+ } else
+ LLE_FREE_LOCKED(ln);
+
IF_AFDATA_UNLOCK(ifp);
return (next);
OpenPOWER on IntegriCloud