第二十六章:邻居子系统概念

一台主机如何由IP地址找到对应的MAC地址,这个步骤由邻居协议完成。常用的邻居协议是ARP。在ipv6中对应的协议是Neighbor Discovery(ND)协议。处于同一个LAN里的设备互为邻居。

上图a:主机A和主机B是邻居,因为它们属于同一个IP子网,可以直接通信。

上图b:主机A和B在同一个子网,是邻居。A和C不在同一个子网,不是邻居。

上图c:虽然A和C连接到同一个集线器,但它们不能通信。尽管彼此会收到对方转发的数据,但由于配置成不同的ip子网,因此无法实现在L3通信。下一节以及后续的章节有解决方式。

上图d:A,B实际上处于同一个子网,互为邻居。注意,用于合并LAN的设备接口上没有配置ip,因为这些设备(集线器,网桥,交换机)都工作在ip层下。

路由器可以有两块网卡,或者是配置多个IP信息的单个NIC。

L3地址何时需要被转换为L2地址:

二层网络协议(Ethernet,,802.11无线,点对点等)和三层网络协议(IP等)的区别是,为了邻居间可以交互数据存在着许多不同的二层协议。而三层协议传输数据时不用关心使用哪种物理介质。

共享介质:

在共享介质中,任一主机发出的任何帧都会被直接连接道该介质的所有主机收到。例如无线连接以及10-base2以太网。因此,使用共享介质的链路层协议需要定义一种寻址机制,以便发送方可以指定接收方,接收方可以识别发送方。

Solicitation请求和应答:

不同的邻居协议有不同的工作机制,但是所有的邻居协议都使用下面两个术语:

    Solicitation请求(邻居Solicitation):这个术语表示网络中发出一个封包询问所有主机,是否有知道这个L3地址对应的L2地址。

    Solicitation应答(邻居advertisement):一般来说,这个术语指发出一个封包作为Solicitation请求的应答。但该封包也可以独立生成。

Linux实现:

传送一个封包时,执行下面的步骤:

    路由子系统选择下一个跳点的L3地址。

    如果下一跳在同一个网络中,邻居层把L3目的地址解析为L2地址,同时放入缓存以便下次不用做解析。

    调用dev_queue_xmit发送封包。

注意,如果需要L2头部信息的话,邻居层必须在调用dev_queue_xmit前添加到封包上。点对点连接,广播,多播都不需要L2头部信息,因此也不需要L3地址到L2地址的映射。其他的传输使用共享介质,因此需要一个L2头部信息。

邻居协议:

ipv4中的邻居协议是ARP,ipv6中的是ND。ARP是一个L3协议,但在ipv6中,其功能被移到了L4中,ND协议在ipv6中是作为ICMPv6多的一部分。

为了减少系统开销和所有邻居协议使用的相似代码,Linux提供了一个通用基础结构。下面是通用基础结构提供的部分功能:

    为每个协议提供一个缓存来存放L3到L2转换的结果。

    提供在缓存中增删改查一个特定映射项的函数。

    为每个协议缓存的数据项提供老化机制。

    为每个邻居提供一个请求队列,当准备发送一个封包且其L2地址不在缓存区时,必须把这个包放到缓冲区里,等待solicitation请求的的响应结果。

邻居协议代理:

邻居协议的代理服务器是一台主机,对请求不属于自己的地址的solicitation请求,它能够代替拥有这些地址的主机做出应答。代理服务器在满足下列条件时才会对solicitation请求做出应答:

    请求的地址和代理服务器收到请求的接口上配置的地址不属于同一个子网。不然的话,目的主机和代理主机同时应答,发送方将不知道应该选择哪一个。

    必须启动代理功能。

    代理服务器上已经开启了转发功能。因为代理服务器是插入到主机之间的,所以必须接收两个端点间转发的流量。

ARP solicitation请求总是发往L2广播地址,这样代理服务器不需要把接口配置成混杂模式,就可以收到它代理的主机的请求。应答的时候使用单播。

ND协议使用L3广播地址处理 solicitation请求和应答。当路由器想代理一个特定IP地址时,它必须接收对应的L3多播地址。

基于设备:该设备接收的所有有效请求都会被处理,ipv4中常用的请求,ipv6不使用。

基于目的地址:在决定是否要进行代理时,同时考虑基于目的地址和设备两个属性。也就是说代理可以对选定IP地址的请求做出应答。ipv6中常用,但ipv4也是可以使用的。

何时发送和处理solicitation请求:

图26-9给出了导致主机发出solicitation请求的一些因素。图26-10给出了接收到该请求的Linux主机用于决定是否对其处理的常见因素,为了说明接收的复杂性,假定接收主机同时具有代理和桥接功能。在邻居协议之前是桥接在处理请求,因此邻居协议并不总是能看到入口solicitation请求。

当接收到solicitation请求的主机启动桥接功能时,该主机对其不进行处理,而是按照网桥配置,将其从合适的接口上转发出去。

现在假定关闭桥接,在一个共享介质中的一台主机能够接收到目的地址是其他主机的solicitation请求。

邻居状态和网络不可到达性探测(NUD):

从邻居的角度来说,如果内核有证据表明接收者可以正确的接收地址是其单播地址的帧,那么这台主机就认为是可到达主机。

ipv6定义了NUD机制,可以快速判断邻居是否断线或死机。Linux内核对ipv4和ipv6使用了同样的机制。

下图总结了邻居可能处于的状态和触发状态转换的条件。每个邻居项可以由多个事件创建,如传送数据封包到邻居的请求,收到来自邻居的solicitation请求。

NUD_NONE:邻居项刚被创建,还没有状态可用。

NUD_INCOMPLETES:一个solicitation请求已经被送出,但还没有收到应答。

NUD_REACHABLE:邻居的地址被放入缓存,并且知道该邻居是可到达的。

NUD_FAILED:由于solicitation请求失败,将邻居标记为不可到达。

NUD_STALE:

NUD_DELAY:

NUD_PROBE:状态转换阶段,当本地主机确定邻居是否可到达时,状态会被改变。

下面两个状态一旦指定,就不会再改变:

NUD_NOARP:该状态用于标记不要任何协议进行L3到L2地址映射的邻居。

NUD_PERMANENT:邻居的L2地址是静态配置,不需要邻居协议进行解析。

上面是一些基本状态,还有一些派生状态(懒得记录了)。

可到达性确认:

由于L3地址到L2地址的映射是可用改变的,因此,有必要对保存在缓存中的信息定期确认,看是否有信息在一定时间内没有使用。这个过程就叫可到达性确认。NUD_STALE,NUD_DELAY,NUD_PROBE这几个状态都支持可到达性确认,只有当一个封包要发送到相关邻居时,才启动可到达性确认。

NUD_STALE:缓存中包含一个邻居的地址,但是该地址有一段时间没有确认了。当下此有封包要到达这个邻居时,要启动可到达性确认。

NUD_DELAY:当要发送一个封包到邻居,且邻居相关的缓存项处于NUD_STALE状态,这时,进入NUD_DELAY状态,该状态表示一个时间窗口,若在该窗口内,被怀疑的邻居发出一个封包,则表明它在运行且可以访问(这个过程叫外部认证),这个期间,内核不会发出solicitation请求。如果在窗口期间,邻居没有发出封包,就进入下一个状态NUD_PROBE。

NUD_PROBE:在这状态下,通过明确的solicitation请求或协议使用的其他机制判断指定邻居的情况。

邻居的可到达性状况可以通过两种方式进行确认:来自单播的solicitation应答认证和外部认证。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值