summaryrefslogtreecommitdiffstats
path: root/sys/netinet6
diff options
context:
space:
mode:
authorqingli <qingli@FreeBSD.org>2009-05-20 21:07:15 +0000
committerqingli <qingli@FreeBSD.org>2009-05-20 21:07:15 +0000
commite6b86b7c8fc96c72c1f5df5a94c60e96783ecaac (patch)
tree3c5f22922fbf16f4da56611f23479ce79b4deb12 /sys/netinet6
parent803ffe40e141533bd4dd2d51a0c7bd977f855ee7 (diff)
downloadFreeBSD-src-e6b86b7c8fc96c72c1f5df5a94c60e96783ecaac.zip
FreeBSD-src-e6b86b7c8fc96c72c1f5df5a94c60e96783ecaac.tar.gz
When an interface address is removed and the last prefix
route is also being deleted, the link-layer address table (arp or nd6) will flush those L2 llinfo entries that match the removed prefix. Reviewed by: kmacy
Diffstat (limited to 'sys/netinet6')
-rw-r--r--sys/netinet6/in6.c25
1 files changed, 25 insertions, 0 deletions
diff --git a/sys/netinet6/in6.c b/sys/netinet6/in6.c
index a2321ff..60d56a8 100644
--- a/sys/netinet6/in6.c
+++ b/sys/netinet6/in6.c
@@ -2284,6 +2284,30 @@ in6_lltable_free(struct lltable *llt, struct llentry *lle)
free(lle, M_LLTABLE);
}
+static void
+in6_lltable_prefix_free(struct lltable *llt,
+ const struct sockaddr *prefix,
+ const struct sockaddr *mask)
+{
+ const struct sockaddr_in6 *pfx = (const struct sockaddr_in6 *)prefix;
+ const struct sockaddr_in6 *msk = (const struct sockaddr_in6 *)mask;
+ struct llentry *lle, *next;
+ register int i;
+
+ for (i=0; i < LLTBL_HASHTBL_SIZE; i++) {
+ LIST_FOREACH_SAFE(lle, &llt->lle_head[i], lle_next, next) {
+ if (IN6_ARE_MASKED_ADDR_EQUAL(
+ &((struct sockaddr_in6 *)L3_ADDR(lle))->sin6_addr,
+ &pfx->sin6_addr,
+ &msk->sin6_addr)) {
+ callout_drain(&lle->la_timer);
+ LLE_WLOCK(lle);
+ llentry_free(lle);
+ }
+ }
+ }
+}
+
static int
in6_lltable_rtcheck(struct ifnet *ifp, const struct sockaddr *l3addr)
{
@@ -2490,6 +2514,7 @@ in6_domifattach(struct ifnet *ifp)
if (ext->lltable != NULL) {
ext->lltable->llt_new = in6_lltable_new;
ext->lltable->llt_free = in6_lltable_free;
+ ext->lltable->llt_prefix_free = in6_lltable_prefix_free;
ext->lltable->llt_rtcheck = in6_lltable_rtcheck;
ext->lltable->llt_lookup = in6_lltable_lookup;
ext->lltable->llt_dump = in6_lltable_dump;
OpenPOWER on IntegriCloud