数据包从L4传到IP后,IP调用路由子系统来查询路由,并且在查询到路由后,创建一个新的邻居项(struct neigh)
与该路由项绑定。该neigh的初始状态为INCOMPLETE,此时在调用发送函数ip_finish_output2中调用
if (dst->hh)
return neigh_hh_output(dst->hh, skb);
else if (dst->neighbour)
return dst->neighbour->output(skb);
处于INCOMPLETE状态下,output函数为neigh_resolve_output
该函数为:
if (!dst || !(neigh = dst->neighbour))
goto discard;
__skb_pull(skb, skb_network_offset(skb));
if (!neigh_event_send(neigh, skb))
在__neigh_event_send函数中,数据包被存入缓存队列
if (neigh->nud_state == NUD_INCOMPLETE) {
if (skb) {
if (skb_queue_len(&neigh->arp_queue) >=
neigh->parms->queue_len) {
struct sk_buff *buff;
buff = __skb_dequeue(&neigh->arp_queue);
kfree_skb(buff);
NEIGH_CACHE_STAT_INC(neigh->tbl, unres_discards);
}
__skb_queue_tail(&neigh->arp_queue, skb);
}
rc = 1;
}
可以看出,如果在neigh的ARP未收到应答包前,如果发出了多个数据包,且个数超过了缓存队列的大小,则会直接丢弃