etharp.c: re-arranged code in find_entry(), supposedly making it more readable for all cases.

This commit is contained in:
likewise 2004-11-29 11:01:20 +00:00
parent 62a37a4876
commit b429918b32

View File

@ -178,7 +178,7 @@ etharp_tmr(void)
} }
/** /**
* Search the ARP table for a specific entry. * Search the ARP table for a matching or new entry.
* *
* If an IP address is given, return a pending or stable ARP entry that matches * If an IP address is given, return a pending or stable ARP entry that matches
* the address. If no match is found, create a new entry with this address set, * the address. If no match is found, create a new entry with this address set,
@ -193,23 +193,23 @@ etharp_tmr(void)
* *
* @param ipaddr IP address to find in ARP cache, or to add if not found. * @param ipaddr IP address to find in ARP cache, or to add if not found.
* @param flags * @param flags
* - ETHARP_TRY_HARD: Try hard to create a entry by allowing recycling. * - ETHARP_TRY_HARD: Try hard to create a entry by allowing recycling of
* active (stable or pending) entries.
* *
* @return The ARP entry index that matched or is created, ERR_MEM if no * @return The ARP entry index that matched or is created, ERR_MEM if no
* entry is found or could be recycled. * entry is found or could be recycled.
*/ */
static s8_t find_entry(struct ip_addr *ipaddr, u8_t flags) static s8_t find_entry(struct ip_addr *ipaddr, u8_t flags)
{ {
s8_t old_pending, old_stable, empty, i; s8_t old_pending = ARP_TABLE_SIZE, old_stable = ARP_TABLE_SIZE, empty = ARP_TABLE_SIZE, i;
u8_t age_pending, age_stable; u8_t age_pending = 0, age_stable = 0;
#if ARP_QUEUEING #if ARP_QUEUEING
/* oldest entry with packets on queue */
s8_t old_queue = ARP_TABLE_SIZE; s8_t old_queue = ARP_TABLE_SIZE;
/* its age */
u8_t age_queue = 0; u8_t age_queue = 0;
#endif #endif
old_pending = old_stable = empty = ARP_TABLE_SIZE;
age_pending = age_stable = 0;
/** /**
* 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
@ -237,7 +237,7 @@ static s8_t find_entry(struct ip_addr *ipaddr, u8_t flags)
/* 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)) {
LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("find_entry: found matching pending entry %d\n", i)); LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("find_entry: found matching pending entry %d\n", i));
/* found match, simply bail out */ /* found exact IP address match, simply bail out */
return i; return i;
#if ARP_QUEUEING #if ARP_QUEUEING
/* pending with queued packets? */ /* pending with queued packets? */
@ -260,7 +260,7 @@ static s8_t find_entry(struct ip_addr *ipaddr, u8_t flags)
/* 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)) {
LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("find_entry: found matching stable entry %d\n", i)); LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("find_entry: found matching stable entry %d\n", i));
/* found match, simply bail out */ /* found exact IP address match, simply bail out */
return i; return i;
/* remember entry with oldest stable entry in oldest, its age in maxtime */ /* remember entry with oldest stable entry in oldest, its age in maxtime */
} else if (arp_table[i].ctime >= age_stable) { } else if (arp_table[i].ctime >= age_stable) {
@ -269,12 +269,21 @@ static s8_t find_entry(struct ip_addr *ipaddr, u8_t flags)
} }
} }
} }
/* { we have no match } => try to create a new entry */
/* no empty entry found and not allowed to recycle? */
if ((i == ARP_TABLE_SIZE) && ((flags & ETHARP_TRY_HARD) == 0))
{
return (s8_t)ERR_MEM;
}
/* b) choose the least destructive entry to recycle: /* b) choose the least destructive entry to recycle:
* 1) empty entry * 1) empty entry
* 2) oldest stable entry * 2) oldest stable entry
* 3) oldest pending entry without queued packets * 3) oldest pending entry without queued packets
* 4) oldest pending entry without queued packets * 4) oldest pending entry without queued packets
*
* { ETHARP_TRY_HARD is set at this point }
*/ */
/* 1) empty entry available? */ /* 1) empty entry available? */
@ -305,38 +314,26 @@ static s8_t find_entry(struct ip_addr *ipaddr, u8_t flags)
/* no empty or recyclable entries found */ /* no empty or recyclable entries found */
#endif #endif
} else { } else {
return ERR_MEM; return (s8_t)ERR_MEM;
} }
/* { empty or recyclable entry found } */ /* { empty or recyclable entry found } */
LWIP_ASSERT("i >= 0", i >= 0); LWIP_ASSERT("i >= 0", i >= 0);
LWIP_ASSERT("i < ARP_TABLE_SIZE", i < ARP_TABLE_SIZE); LWIP_ASSERT("i < ARP_TABLE_SIZE", i < ARP_TABLE_SIZE);
/* allowed to recycle a entry? */ /* recycle entry (no-op for an already empty entry) */
if (flags & ETHARP_TRY_HARD) { arp_table[i].state = ETHARP_STATE_EMPTY;
/* recycle (no-op for an already empty entry) */ /* IP address given? */
arp_table[i].state = ETHARP_STATE_EMPTY; if (ipaddr != NULL) {
/* set IP address */
ip_addr_set(&arp_table[i].ipaddr, ipaddr);
} }
arp_table[i].ctime = 0;
/* empty entry found or created? */
if (arp_table[i].state == ETHARP_STATE_EMPTY) {
/* IP address given? */
if (ipaddr != NULL) {
/* set IP address */
ip_addr_set(&arp_table[i].ipaddr, ipaddr);
}
arp_table[i].ctime = 0;
#if ARP_QUEUEING #if ARP_QUEUEING
/* remove any queued packets */ /* remove any queued packets */
if (arp_table[i].p != NULL) pbuf_free(arp_table[i].p); if (arp_table[i].p != NULL) pbuf_free(arp_table[i].p);
arp_table[i].p = NULL; arp_table[i].p = NULL;
#endif #endif
/* no entry available */
} else {
/* return failure */
i = (s8_t)ERR_MEM;
}
return (err_t)i; return (err_t)i;
} }