diff options
author | qingli <qingli@FreeBSD.org> | 2011-05-20 19:12:20 +0000 |
---|---|---|
committer | qingli <qingli@FreeBSD.org> | 2011-05-20 19:12:20 +0000 |
commit | a1bf1a258207345435ea10acd5842a3edd836a66 (patch) | |
tree | 25e7bd536a80b8bf826cad648267e4078b9e4f2e /sys/netinet6 | |
parent | 8b344f95a5795eba597f19d5c6b1516c99bb2fa9 (diff) | |
download | FreeBSD-src-a1bf1a258207345435ea10acd5842a3edd836a66.zip FreeBSD-src-a1bf1a258207345435ea10acd5842a3edd836a66.tar.gz |
The statically configured (permanent) ARP entries are removed when an
interface is brought down, even though the interface address is still
valid. This patch maintains the permanent ARP entries as long as the
interface address (having the same prefix as that of the ARP entries)
is valid.
Reviewed by: delphij
MFC after: 5 days
Diffstat (limited to 'sys/netinet6')
-rw-r--r-- | sys/netinet6/in6.c | 10 |
1 files changed, 8 insertions, 2 deletions
diff --git a/sys/netinet6/in6.c b/sys/netinet6/in6.c index c522422..9e8e5cd 100644 --- a/sys/netinet6/in6.c +++ b/sys/netinet6/in6.c @@ -2376,19 +2376,25 @@ in6_lltable_free(struct lltable *llt, struct llentry *lle) static void in6_lltable_prefix_free(struct lltable *llt, const struct sockaddr *prefix, - const struct sockaddr *mask) + const struct sockaddr *mask, + u_int flags) { 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; + /* + * (flags & LLE_STATIC) means deleting all entries + * including static ND6 entries + */ 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)) { + &msk->sin6_addr) && + ((flags & LLE_STATIC) || !(lle->la_flags & LLE_STATIC))) { int canceled; canceled = callout_drain(&lle->la_timer); |