邻接子系统核心
基础知识
Linux 邻接子系统负责发现房钱链路上的节点,并且将 L3(网络层)地址转换为 L2(数据链路层)地址。在 IPv4 中,实现这种转化协议为地址解析协议(Address Resolution Protocol, ARP),而在 IPv6 则为邻居发现协议(Neighbour Discovery Protocol, NDISC 或 ND),邻接子系统为执行 L3 到 L2 映射提供了独立于协议的基础设施。
在 IPv4 中,使用邻接协议为 ARP,相应的请求和应答分别被称为 ARP 请求和 ARP 应答,在 IPv6 中,使用邻接协议为 NDISC,相应的请求和应答分别称为 邻居请求
和 邻居通告
。
Linux 邻接系统的基本数据结构是邻居,表示于当前链路相连的网络节点,用结构 neighbour 来表示。具体源码如下:
为了避免每次传输数据包时都发送请求,内核将 L3 地址和 L2 地址之间的映射存储在邻接表的数据结构中。在 IPv4 中,这个表就是 ARP 表,有时也被称为 ARP 缓存。在 IPv6 中,邻接表时 NDISC 表(也叫 NDISC 缓存),ARP 表和 NDISC 表都是结构 neigh_table
实例,具体内核源码表示如下:
使用领接子系统的每种 L3 协议都要注册一个协议协议处理程序。对于 IPv4 来说,ARP 数据包处理程序方法为 arp_rcv()
。
每个邻居对象结构 neigh_ops
中定义一组方法,它包含一个协议簇成员和四个函数指针,具体内核源码如下:
创建和释放邻居
邻居创建时由 __neigh_create()
处理:
邻居删除是由 neigh_release()
处理:
用户空间和邻接子系统交互
管理 ARP 表,可使用 iproute2
包中的命令 ip neigh
,也可以使用 net_tools
包中的命令 arp。
ARP 协议(IPv 4)
在以太网中,硬件地址称为 MAC,长度是 48 位,MAC 地址独一无二。发送 IPv4 数据包时,目标是 IPv4 地址是已知的,但是需要创建以太网头,其中包含目标的 MAC 地址,根据给定 IPv4 地址确定 MAC 地址的工作由 ARP 协议完成。ARP 表时一个 neigh_table
结构实例,具体内核源码如下:
ARP 发送请求
最常见场景是在传输路径中,在离开网络层(L3)进入数据链路层(L2)之前,在方法 ip_finish_output2
中,首先调用方法 __ipv4_neigh_lookup_noref
,在 ARP 表中查找下一个 IPv4 地址。
ARP 接受请求和应答
在 IPv4 中,方法 arp_rcv()
负责处理 ARP 数据包,具体对应函数内核源码如下:
评论