鄰居子系統是 Linux 內核網絡協議棧中連接網絡層(L3)與鏈路層(L2)的關鍵模塊,負責將 IP 地址解析為 MAC 地址(ARP/NDP),維護鄰居可達性狀態機,提供硬件頭緩存加速數據包發送。本文從架構定位、核心流程、發送路徑三個維度構建整體認知框架。
gateway 指向的下一跳設備,或本地網段內的目的主機。
用戶態應用
↓ sendmsg()
內核 Socket 層
↓ ip_route_output() / ip_route_output_slow()
路由查找 → 分配 dst_entry
↓ arp_bind_neighbour(dst) 【關鍵綁定點】
綁定 neighbour (創建/查找)
↓ dst->output() → ip_output()
↓ ip_finish_output2()
dst->neighbour->output(skb) 【進入鄰居子系統】
↓
neigh_resolve_output() / neigh_connected_output()
↓
構建 L2 頭部 → dev_queue_xmit() → 驅動發送
sendmsg()
→ inet_sendmsg()
→ ip_route_output_flow() // 路由查找,獲取 dst_entry
→ arp_bind_neighbour(dst) // 綁定鄰居
→ __neigh_lookup_errno() // 查找/創建 neighbour
→ ip_build_xmit() // 構建 IP 頭
→ output_maybe_reroute()
→ dst->output() // ip_output()
→ __ip_finish_output()
→ ip_finish_output2()
→ dst->neighbour->output(skb) // 關鍵:調用鄰居輸出函數
根據 neigh->nud_state 動態綁定:
| 狀態 | output 函數 | 行為 |
|---|---|---|
| NUD_CONNECTED | neigh_resolve_output / neigh_hh_output | 直接構建 L2 頭發送,或使用硬件頭緩存快速路徑 |
| NUD_STALE | neigh_suspect_output | 發送前先轉入 DELAY 狀態啟動定時器,仍嘗試發送 |
| NUD_DELAY | neigh_suspect_output | 等待 delay_probe_time,超時轉 PROBE |
| NUD_PROBE | neigh_suspect_output | 主動發送單播/多播探測,排隊數據包 |
| NUD_INCOMPLETE | neigh_suspect_output | 剛創建,發送首個探測,排隊數據包 |
| NUD_FAILED | neigh_blackhole | 直接丟棄,返回 -ENETUNREACH |
| 接口 | 功能 | 示例 |
|---|---|---|
| /proc/net/arp | 查看 IPv4 鄰居緩存 | IP address, HW type, Flags, HW address, Mask, Device |
| /proc/net/neigh/* | 每個設備的參數調優 | base_reachable_time, retrans_time, gc_staletime |
| netlink NETLINK_ROUTE | RTM_NEWNEIGH/DELNEIGH/GETNEIGH | ip neigh 命令 |
| ioctl SIOCGARP/SIOCSARP/SIOCDARP | 舊式管理接口 | arp -s 192.168.1.5 00:11:22:33:44:55 |
neighbour 抽象訪問。