这个队列的数据结构:
- 在memp.h的
MEMP_ARP_QUEUE
内存池中有这个数据结构的内存资源 。共有MEMP_NUM_ARP_QUEUE
个,默认为30个 。
#if ARP_QUEUEINGstruct etharp_q_entry {struct etharp_q_entry *next; /* 下一个节点 */struct pbuf *p; /* pbuf */};#endif /* ARP_QUEUEING */
8.4.5 ARP缓存表entry状态信息u8_t state;
:/** ARP states */enum etharp_state {ETHARP_STATE_EMPTY = 0, /* 空闲态 */ETHARP_STATE_PENDING, /* pending态 */ETHARP_STATE_STABLE, /* 有效态 */ETHARP_STATE_STABLE_REREQUESTING_1, /* 有效过渡态1 */ETHARP_STATE_STABLE_REREQUESTING_2 /* 有效过渡态2 */#if ETHARP_SUPPORT_STATIC_ENTRIES, ETHARP_STATE_STATIC /* 静态entry */#endif /* ETHARP_SUPPORT_STATIC_ENTRIES */};
当前netry的状态信息:ETHARP_STATE_EMPTY
:空状态 。当前entry资源无效,可以被填充使用 。ETHARP_STATE_PENDING
:PENDING态 。当前entry正在ARP请求,但是还没收到ARP响应 。ETHARP_STATE_STABLE
:有效态 。当前entry记录的IP地址与MAC地址映射有效 。ETHARP_STATE_STABLE_REREQUESTING_1
:有效过渡态1 。就是为了防止entry块过期前频繁发起ARP请求 。ETHARP_STATE_STABLE_REREQUESTING_2
:有效过渡态2 。ETHARP_STATE_STATIC
:静态条目 。手动配置的ARP映射,一直有效 。
ETHARP_STATE_STABLE
的时候又发送一个ARP请求包,那么表项状态会暂时被设置为THARP_STATE_STABLE_REREQUESTING_1
,然后被设置为ETHARP_STATE_STABLE_REREQUESTING_2
状态,这些是一个过渡状态,当收到ARP应答后,表项又会被设置为ETHARP_STATE_STABLE
,这样能保持表项的有效 。比如,每个IP层的数据包都会先遍历ARP缓存表,如果找到有效的条目后,直接使用该条目,然后会继续调用
etharp_output_to_arp_index()
把数据发送出去,源码如下:- 在发送IP包时检查当前被使用的ARP entry是否块过期,如果快过期,需要发起ARP请求更新当前条目,更新有两种级别:
ARP_AGE_REREQUEST_USED_UNICAST
:默认在条目超时前30秒,发起单播级别的ARP请求,减少不必要的广播 。ARP_AGE_REREQUEST_USED_BROADCAST
:默认在条目超时前15秒,发起广播级别的ARP请求 。
/* 为避免由于ARP表项超时导致稳定使用的连接中断,需要在ARP表项过期前重新请求,更新ARP缓存表 */#define ARP_AGE_REREQUEST_USED_UNICAST(ARP_MAXAGE - 30)#define ARP_AGE_REREQUEST_USED_BROADCAST (ARP_MAXAGE - 15)/* Just a small helper function that sends a pbuf to an ethernet address in the arp_table specified by the index 'arp_idx'. */static err_tetharp_output_to_arp_index(struct netif *netif, struct pbuf *q, netif_addr_idx_t arp_idx){LWIP_ASSERT("arp_table[arp_idx].state >= ETHARP_STATE_STABLE",arp_table[arp_idx].state >= ETHARP_STATE_STABLE);/* 在entry快过期前,发起ARP请求进行更新 。为了防止在这段时间频繁发起ARP请求,所以引入有效过渡态 。这里为有效态才能发起ARP请求 。*/if (arp_table[arp_idx].state == ETHARP_STATE_STABLE) {if (arp_table[arp_idx].ctime >= ARP_AGE_REREQUEST_USED_BROADCAST) {/* 使用广播级别(过期前15秒),发起标准ARP请求 */if (etharp_request(netif, &arp_table[arp_idx].ipaddr) == ERR_OK) {arp_table[arp_idx].state = ETHARP_STATE_STABLE_REREQUESTING_1; /* 更新为有效过渡态1 */}} else if (arp_table[arp_idx].ctime >= ARP_AGE_REREQUEST_USED_UNICAST) {/* 发出单播ARP请求(过期前30秒),以防止不必要的广播 */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; /* 更新为有效过渡态1 */}}}/* IP层发送数据 */return ethernet_output(netif, q, (struct eth_addr *)(netif->hwaddr), &arp_table[arp_idx].ethaddr, ETHTYPE_IP);}
经验总结扩展阅读
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Unity坐标系入门
- 原神蔷薇种子怎么获取
- 原神3.0须弥旋曜玉帛位置在哪
- 2023年10月29日结婚好不好 嫁娶吉利吗
- 2023年农历十一月属羊人哪天适合结婚
- 聚财公司名字大全集 招财旺生意的公司名字
- 抖音店铺取名 抖音吸引人店铺名字
- 电影狼溪一共几部?
- 2023年1月30日制作嫁衣行吗 2023年1月30日制作嫁衣好不好
- 菠萝袜是什么袜子?