From a46014d2b975b038559a2b4e83f9ecad136530ad Mon Sep 17 00:00:00 2001 From: ChenJianxing Date: Mon, 20 Jul 2020 21:03:09 +0800 Subject: [PATCH] nd6: Queue IPv6 packets while ND6 inprogress ...and return ERR_MEM on ND6 queue full. Issue: When ESP32/S2 UDPv6 TX, the pkts are queued into neighbor cache queue when MAC address is being resolved, and as a result of LwIP component's "malloc" use C lib not the LwIP memory pool, which cause the restriction of max nd6 queue num can't limit the memory use. picked from espressif/esp-lwip@80d6d19a Ref IDF-4849 --- src/core/ipv6/nd6.c | 19 +++++++++++++++++++ src/include/lwip/opt.h | 8 ++++++++ 2 files changed, 27 insertions(+) diff --git a/src/core/ipv6/nd6.c b/src/core/ipv6/nd6.c index 81992fa30..53d11de13 100644 --- a/src/core/ipv6/nd6.c +++ b/src/core/ipv6/nd6.c @@ -2086,6 +2086,12 @@ nd6_queue_packet(s8_t neighbor_index, struct pbuf *q) if (copy_needed) { /* copy the whole packet into new pbufs */ p = pbuf_clone(PBUF_LINK, PBUF_RAM, q); +#if ESP_ND6_QUEUEING + if(p == NULL) { + pbuf_free(q); + return ERR_MEM; + } +#else while ((p == NULL) && (neighbor_cache[neighbor_index].q != NULL)) { /* Free oldest packet (as per RFC recommendation) */ #if LWIP_ND6_QUEUEING @@ -2099,6 +2105,7 @@ nd6_queue_packet(s8_t neighbor_index, struct pbuf *q) #endif /* LWIP_ND6_QUEUEING */ p = pbuf_clone(PBUF_LINK, PBUF_RAM, q); } +#endif } else { /* referencing the old pbuf is enough */ p = q; @@ -2119,19 +2126,31 @@ nd6_queue_packet(s8_t neighbor_index, struct pbuf *q) new_entry = (struct nd6_q_entry *)memp_malloc(MEMP_ND6_QUEUE); } if (new_entry != NULL) { + unsigned int qlen = 0; new_entry->next = NULL; new_entry->p = p; if (neighbor_cache[neighbor_index].q != NULL) { /* queue was already existent, append the new entry to the end */ r = neighbor_cache[neighbor_index].q; + qlen++; while (r->next != NULL) { r = r->next; + qlen++; } r->next = new_entry; } else { /* queue did not exist, first item in queue */ neighbor_cache[neighbor_index].q = new_entry; } +#if ESP_ND6_QUEUEING + if (qlen >= MEMP_NUM_ND6_QUEUE) { + r->next = NULL; + pbuf_free(new_entry->p); + memp_free(MEMP_ND6_QUEUE, new_entry); + LWIP_DEBUGF(LWIP_DBG_TRACE, ("ipv6: could not queue the packet %p (queue is full)\n", (void *)q)); + return ERR_MEM; + } +#endif LWIP_DEBUGF(LWIP_DBG_TRACE, ("ipv6: queued packet %p on neighbor entry %"S16_F"\n", (void *)p, (s16_t)neighbor_index)); result = ERR_OK; } else { diff --git a/src/include/lwip/opt.h b/src/include/lwip/opt.h index 2e6f5e7f1..6e7af7963 100644 --- a/src/include/lwip/opt.h +++ b/src/include/lwip/opt.h @@ -2571,6 +2571,14 @@ #define LWIP_ND6_QUEUEING LWIP_IPV6 #endif +/** + * ESP_ND6_QUEUEING==1: queue outgoing IPv6 packets while MAC address + * is being resolved. + */ +#if !defined ESP_ND6_QUEUEING || defined __DOXYGEN__ +#define ESP_ND6_QUEUEING LWIP_IPV6 +#endif + /** * MEMP_NUM_ND6_QUEUE: Max number of IPv6 packets to queue during MAC resolution. */