diff options
author | qingli <qingli@FreeBSD.org> | 2010-01-05 00:35:46 +0000 |
---|---|---|
committer | qingli <qingli@FreeBSD.org> | 2010-01-05 00:35:46 +0000 |
commit | 281d5caa0e0a4189fdc52bf94445383c124630a4 (patch) | |
tree | d1ded4dbf0d32596af446debbd7abbc1d5dd7a4f /sys/netinet/if_ether.c | |
parent | a506bcc1c47ba8270fca36d4e3c5f3eee9c65cb2 (diff) | |
download | FreeBSD-src-281d5caa0e0a4189fdc52bf94445383c124630a4.zip FreeBSD-src-281d5caa0e0a4189fdc52bf94445383c124630a4.tar.gz |
An existing incomplete ARP entry would expire a subsequent
statically configured entry of the same host. This bug was
due to the expiration timer was not cancelled when installing
the static entry. Since there exist a potential race condition
with respect to timer cancellation, simply check for the
LLE_STATIC bit inside the expiration function instead of
cancelling the active timer.
MFC after: 5 days
Diffstat (limited to 'sys/netinet/if_ether.c')
-rw-r--r-- | sys/netinet/if_ether.c | 26 |
1 files changed, 16 insertions, 10 deletions
diff --git a/sys/netinet/if_ether.c b/sys/netinet/if_ether.c index a259278..97152a7 100644 --- a/sys/netinet/if_ether.c +++ b/sys/netinet/if_ether.c @@ -175,18 +175,24 @@ arptimer(void *arg) CURVNET_SET(ifp->if_vnet); IF_AFDATA_LOCK(ifp); LLE_WLOCK(lle); - if ((!callout_pending(&lle->la_timer) && - callout_active(&lle->la_timer))) { - (void) llentry_free(lle); - ARPSTAT_INC(timeouts); - } -#ifdef DIAGNOSTIC + if (lle->la_flags & LLE_STATIC) + LLE_WUNLOCK(lle); else { - struct sockaddr *l3addr = L3_ADDR(lle); - log(LOG_INFO, "arptimer issue: %p, IPv4 address: \"%s\"\n", lle, - inet_ntoa(((const struct sockaddr_in *)l3addr)->sin_addr)); - } + if (!callout_pending(&lle->la_timer) && + callout_active(&lle->la_timer)) { + (void) llentry_free(lle); + ARPSTAT_INC(timeouts); + } +#ifdef DIAGNOSTIC + else { + struct sockaddr *l3addr = L3_ADDR(lle); + log(LOG_INFO, + "arptimer issue: %p, IPv4 address: \"%s\"\n", lle, + inet_ntoa( + ((const struct sockaddr_in *)l3addr)->sin_addr)); + } #endif + } IF_AFDATA_UNLOCK(ifp); CURVNET_RESTORE(); } |