ARP协议是TCP/IP协议族中实现IP地址与MAC地址映射的核心机制,在Linux内核中,其实现位于网络层与数据链路层交互的关键位置,主要由net/ipv4/arp.c文件及相关数据结构完成,内核通过ARP缓存(邻居表)维护IP-MAC映射关系,减少广播请求频率,提升网络通信效率。

内核ARP核心数据结构
Linux内核使用邻居子系统管理ARP缓存,核心数据结构包括neigh_table(邻居表)和neigh(邻居表项),neigh_table定义了整个ARP表的通用操作接口,如创建、删除、查找表项等,其关键字段包括tbl_ops(操作函数集)、parms(参数配置,如超时时间)、entry_size(表项大小)等,每个网络接口对应一个独立的neigh_table实例,通过哈希表存储表项,以IP地址为键快速查找。
neigh结构体表示单个ARP缓存项,存储具体映射信息,核心字段如下:
| 字段名 | 类型 | 说明 |
|---|---|---|
| key | const void * | 目标IP地址(哈希查找的键) |
| ha | char[MAX_ADDR_LEN] | 存储的MAC地址(以太网为6字节) |
| nud_state | u8 | 邻居状态(NUD_REACHABLE可达、NUD_STALE过期、NUD_NONE无效等) |
| parms | struct neigh_parms * | 指向接口的邻居参数(如超时时间、重试次数) |
| confirmed | unsigned long | 最后一次成功确认的时间戳(用于判断是否过期) |
ARP报文处理流程
内核对ARP报文的处理遵循严格的流程,从接收到响应均通过标准化接口完成。
报文接收与校验:当网络接口收到ARP报文时,通过协议栈的ptype_base注册的arp_rcv函数(net/ipv4/arp.c)进入处理流程,首先校验报文长度(以太网ARP报文最小28字节)、硬件类型(1表示以太网)、协议类型(0x0800表示IPv4),以及目标协议地址长度(4字节),确保报文格式合法。

报文类型解析:调用arp_process函数根据操作码(opcode)区分报文类型:
- ARP请求(opcode=1):检查目标IP是否为本机接口IP,若是则构造ARP应答报文,通过arp_send_reply函数发送;若非本机IP,直接丢弃(非代理ARP场景)。
- ARP应答(opcode=2):调用neigh_update函数更新本地ARP缓存,将对应的MAC地址更新,并将状态置为NUD_REACHABLE(可达)。
- 免费ARP(opcode=0或3):用于IP冲突检测或地址通告,内核通过免费ARP更新自身缓存项状态,若发现IP冲突,会通过内核日志输出警告。
报文发送:当需要发送ARP请求(如目标IP未在缓存中)或应答时,通过arp_send函数构造报文,该函数会填充发送方IP/MAC、目标IP/MAC(请求时目标MAC为广播地址),并通过dev_queue_xmit函数将报文交由网络接口发送。
ARP缓存管理与安全机制
内核通过邻居子系统实现ARP缓存的生命周期管理,包括老化、垃圾回收等机制,每个缓存项关联定时器,超时后状态从NUD_REACHABLE转为NUD_STALE(仍可用但需验证),若继续未使用,经延迟探测后转为NUD_PROBE,发送单播ARP请求确认可达性;多次无响应则标记为NUD_NONE,最终被垃圾回收(通过gc_thresh参数控制内存阈值)。
为防止ARP欺骗,内核提供多个sysctl参数增强安全性:

- arp_filter:1时,接口仅响应目标IP属于本子网的ARP请求,避免跨子网伪造。
- arp_announce:控制发送ARP报文时的源IP选择(0:使用任意接口IP;1:优先选择目标IP所在子网的接口IP;2:仅使用目标IP匹配的接口IP),减少IP泄露。
- arp_ignore:0时响应所有ARP请求;1时仅响应目标IP为本地接口IP的请求,避免接口伪造。
相关问答FAQs
问题1:Linux内核如何处理ARP缓存项的老化?
解答:ARP缓存项的老化通过定时器和状态机管理,内核为每个缓存项维护一个定时器,初始超时时间为base_reachable_time(默认30秒),超时后,状态从NUD_REACHABLE转为NUD_STALE(仍可使用但需重新验证);若继续未使用,经delay_probe_time(默认5秒)后转为NUD_DELAY,此时发送单播ARP请求确认;若请求无响应,状态转为NUD_PROBE,发送多播ARP请求(最多重试3次);最终仍无响应则标记为NUD_NONE,被垃圾回收机制释放,neigh_periodic_work函数定期扫描缓存表,根据gc_thresh参数(gc_thresh1/2/3)控制内存使用,优先清理长期未使用的项。
问题2:arp_filter参数的作用是什么?如何配置?
解答:arp_filter是Linux内核的ARP安全参数,取值为0或1,当设置为1时,接口仅响应目标IP属于该接口所在子网的ARP请求(通过子网掩码判断目标IP是否与接口IP在同一网段),若不在则忽略请求,从而防止外部主机伪造IP发送ARP请求(如中间人攻击),配置方式可通过sysctl命令临时修改(如sysctl -w net.ipv4.conf.eth0.arp_filter=1),或永久修改/etc/sysctl.conf文件添加对应配置(如net.ipv4.conf.eth0.arp_filter=1),重启后生效。
【版权声明】:本站所有内容均来自网络,若无意侵犯到您的权利,请及时与我们联系将尽快删除相关内容!
发表回复