每日学习之邻居子系统

今天我们来学习Linux网络中的邻居子系统

现实中的邻居即家或住处与另一人的家或住处靠近或邻近的人,那网络中的邻居是什么?

在网络中,如果一台主机和你的计算机连接在同一个LAN上,那他就是你的邻居,你们两人有着相同的L3网络配置,你们可以通过连接二者的物理介质(比如Ethernet)相关的协议直接进行通信。从你的主机到你的邻居,必须有且仅有一个L3跃点,L3路由表中必须提供可以直接与你的邻居通信的路径。若你的主机与另一台主机进行通信必须经过网关或路由器,你们就不是邻居(如果只是被网桥这种L2上的设备隔离,那还是邻居)。

我们可以通过这张图更加清晰的明白邻居的概念
微信截图_20250630171222
可以看到
a中A、B主机是邻居,他们同属一个子网
b中A、B主机是邻居,但是A、C不是邻居,他们分属两个IP子网,彼此通信需要依赖路由器,两台主机之间有两个L3跃点
c中A、B主机不是邻居,他们被配置成不同的IP子网,不能在L3实现彼此通信
d中A、B主机是邻居,他们通过集线器/网桥/交换机这类L2层的设备连接,同属一个IP子网,而主机C跟A、B不是邻居,他们通过路由器连接

那么邻居子系统的存在有什么意义或起什么作用?

是为了管理L3地址到L2地址的关联。

如果两台主机之间是点对点的连接方式,例如拨号,连接运行在一条半双工的介质上,那此时的邻居协议也是最简的,只需要简单的调用层协议就行
若主机之间采用的是共享介质连接,A主机要将数据传输给B主机,必须指定L2地址,但由于共享介质,该共享介质上的所有主机都会收到该数据,此时,就需要邻居协议为数据选择与L3地址相匹配的L2地址。
微信截图_20250630173953

在以下三种情况中,需要改变L3地址,同时,L3到相应的L2地址的映射也会发生变化。这些情况就需要邻居协议来完成。
1.动态配置:
在IP网络中,通过例如DHCP这样的协议可以给一台主机指定动态IP地址,同一个主机每次请求的IP地址可能会不同,但是硬件地址是固化在网卡或者无线网卡中,因此L3到L2的映射也要相应更新
2.故障接口的重新配置:
如果更换了主机的NIC,那L2地址就改变了,但是管理员可能为了在网络中保持相同的逻辑配置,因此L3地址不变
3.L3地址的移动
当某台服务器无法工作后,需要在另一台服务器处理相同的流量,因此如果需要旧的L3地址设置到新服务器的接口上,保持L3的地址不变。

所有的邻居协议都会用到下面两个术语:
Solicitation 请求:
这个术语表示在网络中发出一个封包并询问所有主机,是否有主机知道这个L3地址对应的L2地址。根据不同的协议和实际情况,该请求以单播、多播、广播的方式发送出去。
Solicitation 应答:
发出一个封包作为Solicitation 请求的应答。通常使用单播方式发送,特殊情况下,也可以使用广播。

什么时候应该处理Solicitation 请求术语呢?
当接收到Solicitation 请求的主机启动桥接功能时,主机对其不予处理,会直接按照网桥配置,将其转发。桥接功能会在邻居协议之前生效,即Linux中,桥接模块会在代理模块处理请求之前。若不存在桥接模块,则处理Solicitation 请求会受到以下几点因素的影响:
1.逻辑子网:若两台主机同属一个逻辑子网,它们可以直接通信,否则,需要路由器的帮忙来完成通信
2.物理子网:若两台主机同属一个LAN,理论上可以直接通信,但如果他们属于不同的IP子网,即逻辑配置不同,同样也需要路由器的帮助
3.代理服务器的要求:代理服务器并不处理所有收到的Solicitation 请求

管理邻居最重要的工作是知道他们是否可达。如果接收者可以正确地接收地址是其单薄地址的帧,那么该主机就被认为是可到达的主机,这个可到达是双向的。

在Linux系统中,当传送一个封包时,会从本地主机的路由子系统选择L3目的地址(下一个跃点)。如果下一个跃点在同一个网络中(说明下一个跃点是邻居),邻居层就把目的L3地址解析为跃点的L2地址(这个关联被放入缓存以便将来再次使用)。如此,当某个应用短期内发送多个封包给另一个应用程序,只在发送第一个封包时使用邻居协议。最后,通过dev_queue_xmit负责完成发送,将封包传递给流量控制层或者QoS层。
微信截图_20250630231753

在现在的IP网络中使用两个协议。绝大多数的系统使用IPv4中的ARP协议,另一个更通用的协议是邻居发现协议(ND),专为IPv6服务。

IPv6定义了一种NUD机制,用于快速判断邻居是否断线或死机。一个邻居项的状态在他的生存期间可能会改变多次,并且同一个状态可以多次被同一个邻居项使用。
下面是一个邻居项的一些基本状态:
NUD_NONE:邻居项刚被创建,还没有状态可用,也是邻居项的初态
NUD_INCOMPLETE:一个solicitation请求已经被送出,但还没有应答
NUD_REACHABEL:邻居地址被放入缓存,并且知道该邻居是可达的
NUD_FAILED:由于solicitation请求失败,将邻居标为不可达
NUD_STALE
NUD_DELAY
NUD_PROBE:状态转换阶段;当本地主机确定邻居是否可达,状态会改变
下面的值表示一组的特定状态,这些状态一旦被指定永远不会改变
NUD_NOARP:该状态用于标记不要任何协议进行L3到L2的地址映射的邻居
NUD_PERMANENT:邻居的L2地址是静态配置,因此不需要邻居协议进行地址解析
此外还有一些特殊状态:NUD_VALID(若邻居项的状态不在上述的基本状态当中,则被认为是NUD_VALID态)、NUD_CONNECTED(NUD_VALID的子状态)、NUD_IN_TIMER(当某项邻居项的状态不是很清晰,邻居子系统就会为其运行一个定时器)

ARP协议
ARP封包格式
微信截图_20250701001158
硬件类型:硬件类型标识符(例如,Ethernet)
协议类型:L3协议标识符(例如,IPv4)
硬件地址长度:L2地址长度(字节数)
协议地址长度:L3地址长度(字节数)
操作码
发送方硬件地址,发送方协议地址
目的地硬件地址,目的地协议地址:接收方的硬件地址和协议地址

ARP封包中的目的地址类型
分三类:
单播:最常见,解析采用普通solicitation方法
广播:ARP简单的将L3广播地址直接映射为与具体设备有关的L2广播地址
多播:ARP使用函数arp_mc_map从L3多播地址导出L2多播地址,ARP不需要生成solicitation请求

无端ARP:当发送方生成ARPOP_REQUEST请求不是为了通信,而是为了通知请求方一些信息

以下几种情况需要无端ARP发挥他的作用
1.L2地址发生变化:当L2地址变化后,L2和L3之间的关联需要更新,就需要通过无端ARP来进行更新
2.重复地址检测:在同时使用静态IP配置和动态IP配置(基于DHCP)的大型网络中可能存在两台主机有相同的L3地址,主机可以通过使用无端ARP来检测重复地址的存在。如果你发出一个目的地是你自己地址的ARP请求,那么只有当有且只存在一台与你有相同IP配置的主机时,才会收到应答。如果不存在重复地址,就收不到任何应答
3.虚拟IP:当活跃服务器由于某些原因宕机,被检查到这个故障之后,会启动新的活跃服务器。这个服务器会生成一个无端ARP封包来更新网络中所有其他主机的ARP缓存

调整ARP选项
内核允许用户通过/proc文件系统和编译时间选项来调整ARP的行为
在编译时可以设置两个选项
1.ARPD:允许用户空间的守护进程处理ARP包,在超大型且流量比较大的网络中,可以提高传输性能
2.UNSOLICITED ARP:默认情况下,丢弃未决的ARPOP_REQUEST应答,但也可以通过这个选项开启,收下该应答

ARP代理
ARP通过/proc接口可以启动按设备代理,也可以启动全局代理。ARP代理服务器作为路由器使用,可以简化主机和子网的配置。但是网络的负载和代理服务器上的CPU占用会很高,因为会有大量的solicitation封包

关于邻居子系统的学习我们今天就暂时到这里啦

posted @ 2025-07-01 01:08  努力成为OM大师  阅读(30)  评论(0)    收藏  举报