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: ++ 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 2015-03-23: Simon Goldschmidt
* etharp.c: Stable etharp entries that are about to expire are now refreshed * 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 using unicast to prevent unnecessary broadcast. Only if no answer is received

View File

@ -563,6 +563,13 @@
#define ETHARP_SUPPORT_STATIC_ENTRIES 0 #define ETHARP_SUPPORT_STATIC_ENTRIES 0
#endif #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. * entry is found or could be recycled.
*/ */
static s8_t 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 old_pending = ARP_TABLE_SIZE, old_stable = ARP_TABLE_SIZE;
s8_t empty = 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 */ /* its age */
u16_t age_queue = 0, age_pending = 0, age_stable = 0; u16_t age_queue = 0, age_pending = 0, age_stable = 0;
LWIP_UNUSED_ARG(netif);
/** /**
* a) do a search through the cache, remember candidates * a) do a search through the cache, remember candidates
* b) select candidate entry * 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", LWIP_ASSERT("state == ETHARP_STATE_PENDING || state >= ETHARP_STATE_STABLE",
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 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)); 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 */ /* found exact IP address match, simply bail out */
return i; 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); ip_addr_copy(arp_table[i].ipaddr, *ipaddr);
} }
arp_table[i].ctime = 0; arp_table[i].ctime = 0;
#if ETHARP_TABLE_MATCH_NETIF
arp_table[i].netif = netif;
#endif /* ETHARP_TABLE_MATCH_NETIF*/
return (err_t)i; 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; return ERR_ARG;
} }
/* find or create ARP entry */ /* 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 */ /* bail out if no entry could be found */
if (i < 0) { if (i < 0) {
return (err_t)i; 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))); ip4_addr1_16(ipaddr), ip4_addr2_16(ipaddr), ip4_addr3_16(ipaddr), ip4_addr4_16(ipaddr)));
/* find or create ARP entry */ /* 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 */ /* bail out if no entry could be found */
if (i < 0) { if (i < 0) {
return (err_t)i; return (err_t)i;
@ -634,7 +643,7 @@ etharp_find_addr(struct netif *netif, const ip_addr_t *ipaddr,
LWIP_UNUSED_ARG(netif); 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)) { if((i >= 0) && (arp_table[i].state >= ETHARP_STATE_STABLE)) {
*eth_ret = &arp_table[i].ethaddr; *eth_ret = &arp_table[i].ethaddr;
*ip_ret = &arp_table[i].ipaddr; *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 */ /* 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? */ /* could not find or create entry? */
if (i < 0) { if (i < 0) {