mirror of
https://github.com/lwip-tcpip/lwip.git
synced 2024-11-04 14:29:39 +00:00
fixed bug #34617: Stable etharp entries that are about to expire are now refreshed using unicast to prevent unnecessary broadcast.
Only if no answer is received after 15 seconds, broadcast is used.
This commit is contained in:
parent
33d5e646e5
commit
440c99100b
@ -6,6 +6,11 @@ HISTORY
|
||||
|
||||
++ New features:
|
||||
|
||||
2015-03-23: Simon Goldschmidt
|
||||
* etharp.c: Stable etharp entries that are about to expire are now refreshed
|
||||
using unicast to prevent unnecessary broadcast. Only if no answer is received
|
||||
after 15 seconds, broadcast is used.
|
||||
|
||||
2015-03-06: Philip Gladstone
|
||||
* netif.h/.c: patch #8359 (Provide utility function to add an IPv6 address to
|
||||
an interface)
|
||||
|
@ -80,7 +80,8 @@ const struct eth_addr ethzero = {{0,0,0,0,0,0}};
|
||||
#define ARP_MAXAGE 1200
|
||||
/** Re-request a used ARP entry 1 minute before it would expire to prevent
|
||||
* breaking a steadily used connection because the ARP entry timed out. */
|
||||
#define ARP_AGE_REREQUEST_USED (ARP_MAXAGE - 60)
|
||||
#define ARP_AGE_REREQUEST_USED_UNICAST (ARP_MAXAGE - 30)
|
||||
#define ARP_AGE_REREQUEST_USED_BROADCAST (ARP_MAXAGE - 15)
|
||||
|
||||
/** the time an ARP entry stays pending after first request,
|
||||
* for ARP_TMR_INTERVAL = 1000, this is
|
||||
@ -97,7 +98,8 @@ enum etharp_state {
|
||||
ETHARP_STATE_EMPTY = 0,
|
||||
ETHARP_STATE_PENDING,
|
||||
ETHARP_STATE_STABLE,
|
||||
ETHARP_STATE_STABLE_REREQUESTING
|
||||
ETHARP_STATE_STABLE_REREQUESTING_1,
|
||||
ETHARP_STATE_STABLE_REREQUESTING_2
|
||||
#if ETHARP_SUPPORT_STATIC_ENTRIES
|
||||
,ETHARP_STATE_STATIC
|
||||
#endif /* ETHARP_SUPPORT_STATIC_ENTRIES */
|
||||
@ -146,6 +148,9 @@ static u8_t etharp_cached_entry;
|
||||
#endif
|
||||
|
||||
|
||||
static err_t etharp_request_dst(struct netif *netif, const ip_addr_t *ipaddr, const struct eth_addr* hw_dst_addr);
|
||||
|
||||
|
||||
#if ARP_QUEUEING
|
||||
/**
|
||||
* Free a complete queue of etharp entries
|
||||
@ -200,7 +205,7 @@ etharp_free_entry(int i)
|
||||
/**
|
||||
* Clears expired entries in the ARP table.
|
||||
*
|
||||
* This function should be called every ETHARP_TMR_INTERVAL milliseconds (5 seconds),
|
||||
* This function should be called every ARP_TMR_INTERVAL milliseconds (1 second),
|
||||
* in order to expire entries in the ARP table.
|
||||
*/
|
||||
void
|
||||
@ -226,8 +231,10 @@ etharp_tmr(void)
|
||||
arp_table[i].state >= ETHARP_STATE_STABLE ? "stable" : "pending", (u16_t)i));
|
||||
/* clean up entries that have just been expired */
|
||||
etharp_free_entry(i);
|
||||
}
|
||||
else if (arp_table[i].state == ETHARP_STATE_STABLE_REREQUESTING) {
|
||||
} else if (arp_table[i].state == ETHARP_STATE_STABLE_REREQUESTING_1) {
|
||||
/* Don't send more than one request every 2 seconds. */
|
||||
arp_table[i].state = ETHARP_STATE_STABLE_REREQUESTING_2;
|
||||
} else if (arp_table[i].state == ETHARP_STATE_STABLE_REREQUESTING_2) {
|
||||
/* Reset state to stable, so that the next transmitted packet will
|
||||
re-send an ARP request. */
|
||||
arp_table[i].state = ETHARP_STATE_STABLE;
|
||||
@ -863,10 +870,17 @@ etharp_output_to_arp_index(struct netif *netif, struct pbuf *q, u8_t arp_idx)
|
||||
/* if arp table entry is about to expire: re-request it,
|
||||
but only if its state is ETHARP_STATE_STABLE to prevent flooding the
|
||||
network with ARP requests if this address is used frequently. */
|
||||
if ((arp_table[arp_idx].state == ETHARP_STATE_STABLE) &&
|
||||
(arp_table[arp_idx].ctime >= ARP_AGE_REREQUEST_USED)) {
|
||||
if (etharp_request(netif, &arp_table[arp_idx].ipaddr) == ERR_OK) {
|
||||
arp_table[arp_idx].state = ETHARP_STATE_STABLE_REREQUESTING;
|
||||
if (arp_table[arp_idx].state == ETHARP_STATE_STABLE) {
|
||||
if (arp_table[arp_idx].ctime >= ARP_AGE_REREQUEST_USED_BROADCAST) {
|
||||
/* issue a standard request using broadcast */
|
||||
if (etharp_request(netif, &arp_table[arp_idx].ipaddr) == ERR_OK) {
|
||||
arp_table[arp_idx].state = ETHARP_STATE_STABLE_REREQUESTING_1;
|
||||
}
|
||||
} else if (arp_table[arp_idx].ctime >= ARP_AGE_REREQUEST_USED_UNICAST) {
|
||||
/* issue a unicast request (for 15 seconds) to prevent unnecessary broadcast */
|
||||
if (etharp_request_dst(netif, &arp_table[arp_idx].ipaddr, &arp_table[arp_idx].ethaddr) == ERR_OK) {
|
||||
arp_table[arp_idx].state = ETHARP_STATE_STABLE_REREQUESTING_1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1316,6 +1330,26 @@ etharp_raw(struct netif *netif, const struct eth_addr *ethsrc_addr,
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send an ARP request packet asking for ipaddr to a specific eth address.
|
||||
* Used to send unicast request to refresh the ARP table just before an entry
|
||||
* times out
|
||||
*
|
||||
* @param netif the lwip network interface on which to send the request
|
||||
* @param ipaddr the IP address for which to ask
|
||||
* @param hw_dst_addr the ethernet address to send this packet to
|
||||
* @return ERR_OK if the request has been sent
|
||||
* ERR_MEM if the ARP packet couldn't be allocated
|
||||
* any other err_t on failure
|
||||
*/
|
||||
static err_t
|
||||
etharp_request_dst(struct netif *netif, const ip_addr_t *ipaddr, const struct eth_addr* hw_dst_addr)
|
||||
{
|
||||
return etharp_raw(netif, (struct eth_addr *)netif->hwaddr, hw_dst_addr,
|
||||
(struct eth_addr *)netif->hwaddr, &netif->ip_addr, ðzero,
|
||||
ipaddr, ARP_REQUEST);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send an ARP request packet asking for ipaddr.
|
||||
*
|
||||
@ -1329,9 +1363,7 @@ err_t
|
||||
etharp_request(struct netif *netif, const ip_addr_t *ipaddr)
|
||||
{
|
||||
LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_request: sending ARP request.\n"));
|
||||
return etharp_raw(netif, (struct eth_addr *)netif->hwaddr, ðbroadcast,
|
||||
(struct eth_addr *)netif->hwaddr, &netif->ip_addr, ðzero,
|
||||
ipaddr, ARP_REQUEST);
|
||||
return etharp_request_dst(netif, ipaddr, ðbroadcast);
|
||||
}
|
||||
#endif /* LWIP_ARP */
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user