From 07fbe82305418b219ea94e72f9f907455db54974 Mon Sep 17 00:00:00 2001 From: Simon Goldschmidt Date: Sat, 22 Feb 2014 21:38:56 +0100 Subject: [PATCH] fixed bug #34681 Limit ARP queue length by ARP_QUEUE_LEN (=3) --- CHANGELOG | 3 +++ src/include/lwip/opt.h | 8 ++++++++ src/netif/etharp.c | 12 ++++++++++++ 3 files changed, 23 insertions(+) diff --git a/CHANGELOG b/CHANGELOG index 29701cfd..d646560e 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -96,6 +96,9 @@ HISTORY ++ Bugfixes: + 2014-02-22: Simon Goldschmidt (patch by Amir Shalem) + * etharp.c, opt.h: fixed bug #34681 Limit ARP queue length by ARP_QUEUE_LEN (=3) + 2014-02-22: Simon Goldschmidt (patch by Amir Shalem) * etharp.h/.c: fixed bug #34682 Limit ARP request flood for unresolved entry diff --git a/src/include/lwip/opt.h b/src/include/lwip/opt.h index d8cf3491..9ba9efd4 100644 --- a/src/include/lwip/opt.h +++ b/src/include/lwip/opt.h @@ -481,6 +481,14 @@ #define ARP_QUEUEING 0 #endif +/** The maximum number of packets which may be queued for each + * unresolved address by other network layers. Defaults to 3, 0 means disabled. + * Old packets are dropped, new packets are queued. + */ +#ifndef ARP_QUEUE_LEN +#define ARP_QUEUE_LEN 3 +#endif + /** * ETHARP_TRUST_IP_MAC==1: Incoming IP packets cause the ARP table to be * updated with the source MAC and IP addresses supplied in the packet. diff --git a/src/netif/etharp.c b/src/netif/etharp.c index fd9e0de1..87c423e7 100644 --- a/src/netif/etharp.c +++ b/src/netif/etharp.c @@ -1140,20 +1140,32 @@ etharp_query(struct netif *netif, ip_addr_t *ipaddr, struct pbuf *q) /* allocate a new arp queue entry */ new_entry = (struct etharp_q_entry *)memp_malloc(MEMP_ARP_QUEUE); if (new_entry != NULL) { + unsigned int qlen = 0; new_entry->next = 0; new_entry->p = p; if(arp_table[i].q != NULL) { /* queue was already existent, append the new entry to the end */ struct etharp_q_entry *r; r = arp_table[i].q; + qlen++; while (r->next != NULL) { r = r->next; + qlen++; } r->next = new_entry; } else { /* queue did not exist, first item in queue */ arp_table[i].q = new_entry; } +#if ARP_QUEUE_LEN + if (qlen >= ARP_QUEUE_LEN) { + struct etharp_q_entry *old; + old = arp_table[i].q; + arp_table[i].q = arp_table[i].q->next; + pbuf_free(old->p); + memp_free(MEMP_ARP_QUEUE, old); + } +#endif LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: queued packet %p on ARP entry %"S16_F"\n", (void *)q, (s16_t)i)); result = ERR_OK; } else {