Refresh ARP entries from incoming IP traffic

uip_arp_ipin() is an empty macro with its body under #if 0, both inherited
from the uIP import and untouched since. That leaves uip_arp_update()
reachable only from uip_arp_arpin(), so an entry is refreshed only by ARP
addressed to us and ages out after UIP_ARP_MAXAGE no matter how much traffic
passed over it.

When it goes, the next transmission to that host hits the miss path of
uip_arp_out(), which overwrites the packet in uip_buf with an ARP request and
returns. For TCP that costs a retransmission. For UDP nothing retransmits, and
handle_tx() sends the UDP connections through uip_arp_out() too, so the
datagram is lost.

The body could not be enabled as written: uip_len -= sizeof(struct uip_eth_hdr)
is a leftover from when UIP_LLH_LEN was 0. Here it is ETHER_HEADER_SIZE +
RTL_FRAME_DESC_SIZE and uip.c reads the IP header at uip_buf[UIP_LLH_LEN], so
uip_len has to keep the link layer in it. The rest of the function is sound.
This commit is contained in:
d00f committed 2026-09-08 01:55:37 +02:00
1 parent 6488433584
commit d6d9c368e9
3 files changed
+3 -8

No files matched your search

+1 -1
View File
@@ -1252,7 +1252,7 @@ void handle_rx(void)
} }
} else if (ETH_IN->ether_type == HTONS(0x0800)) { // IPv4 } else if (ETH_IN->ether_type == HTONS(0x0800)) { // IPv4
if (!management_vlan || management_vlan == rx_packet_vlan) { if (!management_vlan || management_vlan == rx_packet_vlan) {
uip_arp_ipin(); // Learn MAC addresses in TCP packets uip_arp_ipin();
uip_input(); uip_input();
if (uip_len) { if (uip_len) {
// Add ethernet frame // Add ethernet frame
+1 -5
View File
@@ -239,12 +239,9 @@ uip_arp_update(__xdata u16_t * __xdata ipaddr, __xdata struct uip_eth_addr * __x
* variable uip_len. * variable uip_len.
*/ */
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
#if 0
void void
uip_arp_ipin(void) uip_arp_ipin(void) __banked
{ {
uip_len -= sizeof(struct uip_eth_hdr);
/* Only insert/update an entry if the source IP address of the /* Only insert/update an entry if the source IP address of the
incoming IP packet comes from a host on the local network. */ incoming IP packet comes from a host on the local network. */
if((IPBUF->srcipaddr[0] & uip_netmask[0]) != if((IPBUF->srcipaddr[0] & uip_netmask[0]) !=
@@ -259,7 +256,6 @@ uip_arp_ipin(void)
return; return;
} }
#endif /* 0 */
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
/** /**
* ARP processing for incoming ARP packets. * ARP processing for incoming ARP packets.
+1 -2
View File
@@ -78,8 +78,7 @@ void uip_arp_init(void) __banked;
inserts a new mapping if none exists. The function assumes that an inserts a new mapping if none exists. The function assumes that an
IP packet with an Ethernet header is present in the uip_buf buffer IP packet with an Ethernet header is present in the uip_buf buffer
and that the length of the packet is in the uip_len variable. */ and that the length of the packet is in the uip_len variable. */
/*void uip_arp_ipin(void);*/ void uip_arp_ipin(void) __banked;
#define uip_arp_ipin()
/* The uip_arp_arpin() should be called when an ARP packet is received /* The uip_arp_arpin() should be called when an ARP packet is received
by the Ethernet driver. This function also assumes that the by the Ethernet driver. This function also assumes that the