链路内和链路外的数据包发送:单播、组播、任播

翻译自:https://info.menandmice.com/blog/bid/103274/On-link-vs-Off-Link-Packet-Delivery-Unicast-Multicast-Anycast

原作者:David Beck, a Men & Mice trainer and course developer

翻译:Analylx

在子网内(链路内)分发数据报文和在不同的子网间(链路外)分发数据报文是不同的。本文基于不同目的地址类型单播、组播、任播来讲述这些不同点。主要目的是指明任播的不同之处和解释链路内的任播。除了特别指出的一点例外,以下所有的都适用于IPv4和IPv6。不管怎样,这是一篇讲述IPv6基础的文章。IPv6术语“link”被用来代替“subnet”,“Node”被用来代替“host”。

单播

一个单播地址唯一标识一个节点上的一个接口。它被用来发送数据包到唯一的一个接口。它是一个人听到“IP地址”之后最先被想到的一种接口类型。发送者在发送去往一个单播地址的报文时,会先在路由表中查找这个报文的目的地址,并且选择最长匹配优先。

这条最长匹配的表项可能会指出这个目的地址是在链路内的。对于链路内的目的地址,发送者采用数据链路层协议,例如以太网,来将报文发送到最终地址。或者最长匹配指出这个地址是链路外的。对于链路外地址的路由表项,包含一个靠近这个目的的链路内的路由器。发送者利用数据链路层协议将报文发送给那个路由器。路由器重复这个动作直到到达目的地。

一个互联网络包含两个或者多个经由路由器加入的链路(网络)。将单播地址的报文发送到链路外的需求催生了IP协议。如果所有的目的地址都是链路内的话,报文的发送靠数据链路层的协议和数据链路层的地址就可以完成了。(请注意互联网是一个巨大的网络,由全世界所有加入的路由器组成)

组播

组播地址指定多个接口分布在多个节点上。发送给组播地址的报文会所有指定的接口。对于iPv4和ipv6,组播地址和单播地址都是截然不同的很容易区分。IPv4组播地址是224.0.0.0/4(地址从224-239)。IPv6组播地址是ff00::/8。组播并不一开始就是IP的一部分,它是在1980年代才加进去的。

链路内的IP组播的发送依赖于下层的数据链路层协议要支持组播,或者说至少要支持广播。幸运的是以太网和802.11无线网络协议都有组播功能,并且有组播MAC地址。这使得链路内组播分发变得很简单。通过公式把组播IP地址转换成组播MAC地址。对于IPv4,这个定义在RFC"Host Extensions for IP Multicasting" (http://www.rfc-editor.org/rfc/rfc1112.txt),对于IPv6,定义在RFC “Transmission of IPv6 Packets over Ethernet Networks” (http://www.rfc-editor.org/rfc/rfc2464.txt)。一个分配了组播IP的接口会配置成侦听相应的组播MAC地址。当一个报文被发送到链路内的组播IP地址去的时候,会被封装在相应的目的MAC的帧中。所有侦听这个MAC地址的节点接收并处理这个报文。链路内组播容易部署并且得到广泛的应用。

IPv4和IPv6的路由协议都依赖于链路内组播。路由器发送报文告知所有其他设备路由协议的信息,例如网络拓扑的改变。(在不支持组播或者广播的数据链路层之上进行链路内IP组播是非常有挑战性的。幸运的是这个歌小梦魇不在本书的讨论范围之内)。

在不同的链路上的不同节点配置组播地址运行链路外组播更加具有挑战性。必须应用特定的组播路由协议。发送者生成一个报文,组播路由器必须复制多份到不同链路上的节点。链路外组播应该并不广泛。绝大多数的组织并不使用组播路由协议。组播路由协议也没被用在开放互联网上。

任播

现在来到文章的主要部分。

跟多播地址一样,任播地址也是被分配在多个节点的多个接口上。不同之处是任播报文只发送到一个节点,发送者并不关心谁收到了这个报文,因为所有的目的地址都是对等的。

和组播一样对于任播,链路内和链路外有很大的不同。对于组播链路内传递很简单并且应用广泛,链路外传递很有挑战并且很少应用。但是任播正好相反,链路外任播很简单。

链路外任播被用于根或者顶级的DNS server。例如F root server(f.root-server.net)的IPv4地址是192.5.5.241.这是一个任播地址(第一次听说ipv4的任播地址)。它被分配在全世界范围内的54台DNS服务器上(http://www.isc.org/f-root/)。对于DNS服务来说所有这些服务器都是相同的。对发送到192.5.5.241这个地址的报文,路由器一般把它发送到唯一一个节点(单个DNS server)。因为所有的服务器都用于相同的信息,所以具体发送到哪个服务器也就无关紧要了。为了管理这些服务器,每台服务器还有自己的单播地址,但是这些单播地址并不是用来响应DNS请求的。

链路外的任播地址是无法和单播地址区分的。当一个单播地址被分配到第二个节点上去的时候就自动成为一个任播地址。分配了相同任播地址的不同节点是不知道这是一个任播地址还是一个单播地址的。发送者也不会对发往任播地址的报文做特殊的处理。也没有专门用来支持任播的协议,也的确并不需要。使用普通的单播路由来处理链路外任播地址。唯一的要求是配置了相同任播地址的节点要在不同的链路上,并且正确配置路由。RFC "Operation of Anycast Services" 就是一篇最佳实践的文档 (http://www.rfc-editor.org/rfc/rfc4786.txt).

链路外任播可以建立在IPv4和IPv6网络中,但是链路内任播只能用在Ipv6网络中。在同一链路上的节点共享一个地址,发往这个地址的数据包也只发送到一个接口。但是这些节点都在同一个链路上,IP路由无法处理这个地址的分发。不同于链路外任播,链路内任播需要一些技术规范的支持参看RFC "IP Version 6 Addressing Architecture" (http://www.rfc-editor.org/rfc/rfc4291.txt)。

根据规范,一个任播地址可以分配的多个接口。每个分配了任播地址的节点都会发送NA报文来告知这个任播地址和本地单播数据链路层地址的绑定关系。这些NA报文是互相竞争的。其他节点会把这个任播地址绑定到其中一个数据链路层的单播地址上。如果有三个节点分配了同一个任播地址,第四个节点会绑定其中一个数据链路层的单播地址。当有报文要发送到这个任播地址的时候,数据链路层会把它发送到其中一个节点。这样就可以满足任播报文发送到单一节点的要求。

为什么要用数据链路层单播去发送链路内任播报文呢?因为数据链路层协议不支持任播。如果以太网有任播地址和任播的功能,那么链路内任播可以映射到任播的MAC地址。链路内任播就跟链路内组播或者链路内单播那样简单了。因为数据链路层任播不存在所以链路内任播必须映射到数据链路层能提供的地址类型上去例如单播、广播或者组播。数据链路层单播或者组播功能无法在这里应用,因为他们无法满足任播只发送给一个节点的需求。综上链路内任播就只能采用数据链路层单播的方式。

链路内任播需要特殊的处理而链路外任播不需要。节点分配链路内任播地址的时候需要明确指出这个地址是任播地址。链路内任播地址会抑制DAD机制。当配置一个IPv6单播地址的时候,DAD机制会检查链路内是否分配了相同的单播地址。如果DAD报告地址重复了,就不会再去分配这个地址。链路内任播地址要分配到多个接口,所以禁止DAD。另外链路内任播的NA报文会稍微延迟一点发送,NA message中的Override flag会被清除。

设置了Override flag后,接收者会去清除缓存的IPv6地址表项。对于单播地址Override flag是设置的,所以接收者会采用新的通告信息。这对于单播NA是有道理的,因为单播NA总是来自同一个节点,新的通告更好。但是对于链路内任播,每个分配了链路内任播地址的节点都会发送NA并带上自己的数据链路层地址。Override flag清零表示接收者会采用最先收到的NA中的通告信息。

被清除置位的Override flag可以防止在收到来自不同数据链路层地址的相同任播地址的时候出现震荡。另外这可以认为发送者在那段时间内可以连接到链路上不同的配置了这个任播地址的节点。正面的看,可以提供负载均衡。但是这里存在不可控的因素,可能所有的发送者都将任播报文发送到链路上的同一个数据链路层地址(也就是同一个节点)。如果缓存的任播目的地址无法到达了,在超时之前是无法更新的。如果一个不幸的节点缓存了无法到达的任播地址节点,在链路上其他节点都可用的情况下,这个节点还是无法发送到这个地址的任播报文。

配置了链路内任播的节点需要对这个任播地址进行特殊的配置和特殊的处理,而链路外任播不需要。发送者对于链路内任播和链路外任播都不需要特殊的处理。

RFC定义了IPv6任播地址。只是定义了任播地址之间的区别,并没有和单播地址做区分。应该最广泛的任播地址是子网路由任播地址(SRA)。每条链路都有一个子网路由任播地址。在定义子网路由任播地址时所有的接口比特都置成0.例如链路2001:db8:cafe:fee::/64,它的子网路由任播地址就是2001:db8:cafe:fee::/128。这个子网路由任播地址在RFC4291中定义RFC "Reserved IPv6 Subnet Anycast Addresses" (http://www.rfc-editor.org/rfc/rfc2526.txt),它预留了最高的128位地址给每个链路的任播地址。

初看起来子网路由任播地址可以比较理想的应用在FHRP上。但是目前应用比较广泛的FHRP,例如HSRP、VRRP、GLBP、CARP等,虽然都支持IPv6但不支持子网路由任播地址。那么子网路由任播地址能用在什么地方?它还没有得到广泛的实施,并被夸大了它目前的用途。根据反馈,或许其他的文章能深入研究挖掘它的应用。

那么就让这个牢骚来当做结尾:虽然IPv6支持了链路内任播却没有任何关键应用采用这是不正常的。

总结

posted @ 2018-08-27 12:31  Analylx  阅读(1099)  评论(0编辑  收藏  举报