summaryrefslogtreecommitdiffstats
path: root/sys/netinet6/in6.c
diff options
context:
space:
mode:
authorbz <bz@FreeBSD.org>2010-04-21 19:51:22 +0000
committerbz <bz@FreeBSD.org>2010-04-21 19:51:22 +0000
commite36601cbc07715392430d5c4e0028505d13e6466 (patch)
treed4da6a40cea6c9dca9f4e141d7d26ef6da5190a8 /sys/netinet6/in6.c
parentfbe36a7d8f86f769ca62aef699b956b8af0a83ff (diff)
downloadFreeBSD-src-e36601cbc07715392430d5c4e0028505d13e6466.zip
FreeBSD-src-e36601cbc07715392430d5c4e0028505d13e6466.tar.gz
MFC r206481:
Plug reference leaks in the link-layer code ("new-arp") that previously prevented the link-layer entry from being freed. In both in.c and in6.c (though that code path seems to be basically dead) plug a reference leak in case of a pending callout being drained. In if_ether.c consistently add a reference before resetting the callout and in case we canceled a pending one remove the reference for that. In the final case in arptimer, before freeing the expired entry, remove the reference again and explicitly call callout_stop() to clear the active flag. In nd6.c:nd6_free() we are only ever called from the callout function and thus need to remove the reference there as well before calling into llentry_free(). In if_llatbl.c when freeing the entire tables make sure that in case we cancel a pending callout to remove the reference as well. Reviewed by: qingli (earlier version) MFC after: 10 days Problem observed, patch tested by: simon on ipv6gw.f.o, Christian Kratzer (ck cksoft.de), Evgenii Davidov (dado korolev-net.ru) PR: kern/144564 Configurations still affected: with options FLOWTABLE
Diffstat (limited to 'sys/netinet6/in6.c')
-rw-r--r--sys/netinet6/in6.c6
1 files changed, 5 insertions, 1 deletions
diff --git a/sys/netinet6/in6.c b/sys/netinet6/in6.c
index 7e5d6d4..1cceb9f 100644
--- a/sys/netinet6/in6.c
+++ b/sys/netinet6/in6.c
@@ -2337,8 +2337,12 @@ in6_lltable_prefix_free(struct lltable *llt,
&((struct sockaddr_in6 *)L3_ADDR(lle))->sin6_addr,
&pfx->sin6_addr,
&msk->sin6_addr)) {
- callout_drain(&lle->la_timer);
+ int canceled;
+
+ canceled = callout_drain(&lle->la_timer);
LLE_WLOCK(lle);
+ if (canceled)
+ LLE_REMREF(lle);
llentry_free(lle);
}
}
OpenPOWER on IntegriCloud