fixed bug #36017 ARP might not support duplicate addresses on multiple netifs (tried to correctly handle duplicate AutoIP addresses on multiple netifs, but only if explicitly enabled via ETHARP_TABLE_MATCH_NETIF==1)

This commit is contained in:
sg 2015-03-23 22:04:57 +01:00
parent 440c99100b
commit 2eb0386c2a
3 changed files with 27 additions and 6 deletions

View File

@ -6,6 +6,11 @@ HISTORY
++ New features:
2015-03-23: Simon Goldschmidt
* opt.h, etharp.c: with ETHARP_TABLE_MATCH_NETIF== 1, duplicate (Auto)-IP
addresses on multiple netifs should now be working correctly (if correctly
addressed by routing, that is)
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

View File

@ -563,6 +563,13 @@
#define ETHARP_SUPPORT_STATIC_ENTRIES 0
#endif
/** ETHARP_TABLE_MATCH_NETIF==1: Match netif for ARP table entries.
* If disabled, duplicate IP address on multiple netifs are not supported
* (but this should only occur for AutoIP).
*/
#ifndef ETHARP_TABLE_MATCH_NETIF
#define ETHARP_TABLE_MATCH_NETIF 0
#endif
/*
--------------------------------

View File

@ -271,7 +271,7 @@ etharp_tmr(void)
* entry is found or could be recycled.
*/
static s8_t
etharp_find_entry(const ip_addr_t *ipaddr, u8_t flags)
etharp_find_entry(const ip_addr_t *ipaddr, u8_t flags, struct netif* netif)
{
s8_t old_pending = ARP_TABLE_SIZE, old_stable = ARP_TABLE_SIZE;
s8_t empty = ARP_TABLE_SIZE;
@ -281,6 +281,8 @@ etharp_find_entry(const ip_addr_t *ipaddr, u8_t flags)
/* its age */
u16_t age_queue = 0, age_pending = 0, age_stable = 0;
LWIP_UNUSED_ARG(netif);
/**
* a) do a search through the cache, remember candidates
* b) select candidate entry
@ -307,7 +309,11 @@ etharp_find_entry(const ip_addr_t *ipaddr, u8_t flags)
LWIP_ASSERT("state == ETHARP_STATE_PENDING || state >= ETHARP_STATE_STABLE",
state == ETHARP_STATE_PENDING || state >= ETHARP_STATE_STABLE);
/* if given, does IP address match IP address in ARP entry? */
if (ipaddr && ip_addr_cmp(ipaddr, &arp_table[i].ipaddr)) {
if (ipaddr && ip_addr_cmp(ipaddr, &arp_table[i].ipaddr)
#if ETHARP_TABLE_MATCH_NETIF
&& ((netif == NULL) || (netif == arp_table[i].netif))
#endif /* ETHARP_TABLE_MATCH_NETIF */
) {
LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_find_entry: found matching entry %"U16_F"\n", (u16_t)i));
/* found exact IP address match, simply bail out */
return i;
@ -406,6 +412,9 @@ etharp_find_entry(const ip_addr_t *ipaddr, u8_t flags)
ip_addr_copy(arp_table[i].ipaddr, *ipaddr);
}
arp_table[i].ctime = 0;
#if ETHARP_TABLE_MATCH_NETIF
arp_table[i].netif = netif;
#endif /* ETHARP_TABLE_MATCH_NETIF*/
return (err_t)i;
}
@ -485,7 +494,7 @@ etharp_update_arp_entry(struct netif *netif, const ip_addr_t *ipaddr, struct eth
return ERR_ARG;
}
/* find or create ARP entry */
i = etharp_find_entry(ipaddr, flags);
i = etharp_find_entry(ipaddr, flags, netif);
/* bail out if no entry could be found */
if (i < 0) {
return (err_t)i;
@ -579,7 +588,7 @@ etharp_remove_static_entry(const ip_addr_t *ipaddr)
ip4_addr1_16(ipaddr), ip4_addr2_16(ipaddr), ip4_addr3_16(ipaddr), ip4_addr4_16(ipaddr)));
/* find or create ARP entry */
i = etharp_find_entry(ipaddr, ETHARP_FLAG_FIND_ONLY);
i = etharp_find_entry(ipaddr, ETHARP_FLAG_FIND_ONLY, NULL);
/* bail out if no entry could be found */
if (i < 0) {
return (err_t)i;
@ -634,7 +643,7 @@ etharp_find_addr(struct netif *netif, const ip_addr_t *ipaddr,
LWIP_UNUSED_ARG(netif);
i = etharp_find_entry(ipaddr, ETHARP_FLAG_FIND_ONLY);
i = etharp_find_entry(ipaddr, ETHARP_FLAG_FIND_ONLY, netif);
if((i >= 0) && (arp_table[i].state >= ETHARP_STATE_STABLE)) {
*eth_ret = &arp_table[i].ethaddr;
*ip_ret = &arp_table[i].ipaddr;
@ -1075,7 +1084,7 @@ etharp_query(struct netif *netif, const ip_addr_t *ipaddr, struct pbuf *q)
}
/* find entry in ARP cache, ask to create entry if queueing packet */
i = etharp_find_entry(ipaddr, ETHARP_FLAG_TRY_HARD);
i = etharp_find_entry(ipaddr, ETHARP_FLAG_TRY_HARD, netif);
/* could not find or create entry? */
if (i < 0) {