ARP緩存表的超時處理
ARP表項的生存時間是5分鐘,而ARP請求的等待時間是5秒鐘,當這些時間到達後,就會更新ARP表項,如果在物理鏈路層無法連通則會刪除表項。這就需要ARP層有一個超時處理函數對ARP進行管理,這些操作都是根據ARP表項的ctime字段進行的,它記錄着對應表項的生存時間,而超時處理函數是etharp_tmr(),它是一個週期性的超時處理函數,每隔1秒就調用一次,當ctime的值大於指定的時間,就會刪除對應的表項。
LwIP中實現的函數是:etharp_tmr(void)。
由於LwIP的ARP表是比較小的,LwIP採用直接遍歷ARP緩存表,更新ARP表的內容,而當表項的時間大於表項的生存時間(5分鐘),或者表項狀態是ETHARP_STATE_PENDING處於等待目標主機迴應ARP請求包,並且等待的時間超過ARP_MAXPENDING(5秒),那麼LwIP就認爲這些表項是無效了,就調用etharp_free_entry()函數刪除表項。
void
etharp_tmr(void)
{
int i;
LWIP_DEBUGF(ETHARP_DEBUG, ("etharp_timer\n"));
/* 遍歷ARP表,從ARP表中刪除過期的表項 */
for (i = 0; i < ARP_TABLE_SIZE; ++i) {
u8_t state = arp_table[i].state;
if (state != ETHARP_STATE_EMPTY
#if ETHARP_SUPPORT_STATIC_ENTRIES
&& (state != ETHARP_STATE_STATIC)
#endif /* ETHARP_SUPPORT_STATIC_ENTRIES */
) {
arp_table[i].ctime++;
/* 等待表項穩定或者表項已經過期*/
if ((arp_table[i].ctime >= ARP_MAXAGE) ||
((arp_table[i].state == ETHARP_STATE_PENDING) &&
(arp_table[i].ctime >= ARP_MAXPENDING)))
{
LWIP_DEBUGF(ETHARP_DEBUG, ("etharp_timer: expired %s entry %d.\n",
arp_table[i].state >= ETHARP_STATE_STABLE ? "stable" : "pending", i));
/* clean up entries that have just been expired */
etharp_free_entry(i);
}
else if (arp_table[i].state == ETHARP_STATE_STABLE_REREQUESTING_1)
{
/* 過渡階段 */
arp_table[i].state = ETHARP_STATE_STABLE_REREQUESTING_2;
}
else if (arp_table[i].state == ETHARP_STATE_STABLE_REREQUESTING_2)
{
/* 進入ETHARP_STATE_STABLE狀態 */
arp_table[i].state = ETHARP_STATE_STABLE;
}
else if (arp_table[i].state == ETHARP_STATE_PENDING)
{
/*仍然掛起,重新發送ARP請求 */
etharp_request(arp_table[i].netif, &arp_table[i].ipaddr);
}
}
}
}