Skip to content

Commit

Permalink
nd6: Queue IPv6 packets while ND6 inprogress
Browse files Browse the repository at this point in the history
...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 80d6d19a
Ref IDF-4849
  • Loading branch information
MaxwellAlan authored and david-cermak committed Aug 16, 2022
1 parent 0058564 commit a46014d
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 0 deletions.
19 changes: 19 additions & 0 deletions src/core/ipv6/nd6.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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;
Expand All @@ -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 {
Expand Down
8 changes: 8 additions & 0 deletions src/include/lwip/opt.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*/
Expand Down

0 comments on commit a46014d

Please sign in to comment.