Skip to content

Commit

Permalink
[arp] Increase robustness of ARP discarder
Browse files Browse the repository at this point in the history
Take ownership from the ARP cache at the start of arp_destroy(), to
ensure that no code path can lead to arp_destroy() being re-entered.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
  • Loading branch information
mcb30 committed Oct 19, 2012
1 parent a4d1250 commit 885384f
Showing 1 changed file with 10 additions and 7 deletions.
17 changes: 10 additions & 7 deletions src/net/arp.c
Expand Up @@ -180,13 +180,16 @@ static void arp_destroy ( struct arp_entry *arp, int rc ) {
struct net_device *netdev = arp->netdev;
struct net_protocol *net_protocol = arp->net_protocol;
struct io_buffer *iobuf;
struct io_buffer *tmp;

/* Take ownership from cache */
list_del ( &arp->list );

/* Stop timer */
stop_timer ( &arp->timer );

/* Discard any outstanding I/O buffers */
list_for_each_entry_safe ( iobuf, tmp, &arp->tx_queue, list ) {
while ( ( iobuf = list_first_entry ( &arp->tx_queue, struct io_buffer,
list ) ) != NULL ) {
DBGC2 ( arp, "ARP %p %s %s %s discarding deferred packet: "
"%s\n", arp, netdev->name, net_protocol->name,
net_protocol->ntoa ( arp->net_dest ), strerror ( rc ) );
Expand All @@ -198,8 +201,7 @@ static void arp_destroy ( struct arp_entry *arp, int rc ) {
net_protocol->name, net_protocol->ntoa ( arp->net_dest ),
strerror ( rc ) );

/* Remove from cache and drop reference */
list_del ( &arp->list );
/* Drop remaining reference */
ref_put ( &arp->refcnt );
}

Expand Down Expand Up @@ -518,12 +520,13 @@ static unsigned int arp_discard ( void ) {
struct arp_entry *arp;

/* Drop oldest cache entry, if any */
list_for_each_entry_reverse ( arp, &arp_entries, list ) {
arp = list_last_entry ( &arp_entries, struct arp_entry, list );
if ( arp ) {
arp_destroy ( arp, -ENOBUFS );
return 1;
} else {
return 0;
}

return 0;
}

/** ARP cache discarder
Expand Down

0 comments on commit 885384f

Please sign in to comment.