Browse Source

[arp] Increase robustness of ARP discarder

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>
tags/v1.20.1
Michael Brown 12 years ago
parent
commit
885384faf3
1 changed files with 10 additions and 7 deletions
  1. 10
    7
      src/net/arp.c

+ 10
- 7
src/net/arp.c View File

180
 	struct net_device *netdev = arp->netdev;
180
 	struct net_device *netdev = arp->netdev;
181
 	struct net_protocol *net_protocol = arp->net_protocol;
181
 	struct net_protocol *net_protocol = arp->net_protocol;
182
 	struct io_buffer *iobuf;
182
 	struct io_buffer *iobuf;
183
-	struct io_buffer *tmp;
183
+
184
+	/* Take ownership from cache */
185
+	list_del ( &arp->list );
184
 
186
 
185
 	/* Stop timer */
187
 	/* Stop timer */
186
 	stop_timer ( &arp->timer );
188
 	stop_timer ( &arp->timer );
187
 
189
 
188
 	/* Discard any outstanding I/O buffers */
190
 	/* Discard any outstanding I/O buffers */
189
-	list_for_each_entry_safe ( iobuf, tmp, &arp->tx_queue, list ) {
191
+	while ( ( iobuf = list_first_entry ( &arp->tx_queue, struct io_buffer,
192
+					     list ) ) != NULL ) {
190
 		DBGC2 ( arp, "ARP %p %s %s %s discarding deferred packet: "
193
 		DBGC2 ( arp, "ARP %p %s %s %s discarding deferred packet: "
191
 			"%s\n", arp, netdev->name, net_protocol->name,
194
 			"%s\n", arp, netdev->name, net_protocol->name,
192
 			net_protocol->ntoa ( arp->net_dest ), strerror ( rc ) );
195
 			net_protocol->ntoa ( arp->net_dest ), strerror ( rc ) );
198
 	       net_protocol->name, net_protocol->ntoa ( arp->net_dest ),
201
 	       net_protocol->name, net_protocol->ntoa ( arp->net_dest ),
199
 	       strerror ( rc ) );
202
 	       strerror ( rc ) );
200
 
203
 
201
-	/* Remove from cache and drop reference */
202
-	list_del ( &arp->list );
204
+	/* Drop remaining reference */
203
 	ref_put ( &arp->refcnt );
205
 	ref_put ( &arp->refcnt );
204
 }
206
 }
205
 
207
 
518
 	struct arp_entry *arp;
520
 	struct arp_entry *arp;
519
 
521
 
520
 	/* Drop oldest cache entry, if any */
522
 	/* Drop oldest cache entry, if any */
521
-	list_for_each_entry_reverse ( arp, &arp_entries, list ) {
523
+	arp = list_last_entry ( &arp_entries, struct arp_entry, list );
524
+	if ( arp ) {
522
 		arp_destroy ( arp, -ENOBUFS );
525
 		arp_destroy ( arp, -ENOBUFS );
523
 		return 1;
526
 		return 1;
527
+	} else {
528
+		return 0;
524
 	}
529
 	}
525
-
526
-	return 0;
527
 }
530
 }
528
 
531
 
529
 /** ARP cache discarder
532
 /** ARP cache discarder

Loading…
Cancel
Save