因特网协议栈:网络层之数据平面

什么是数据平面

应用程序部署在不同的终端中,相互之间需要交换信息,然后有了应用层协议。终端需要给生存在其之内的应用程序提供来自其他终端的应用程序的信息,然后有了运输层协议。至于如何让信息从一个终端到达另一个终端,就是网络层协议要完成的事情。

网络层.png

换言之,应用层服务于应用程序,运输层服务于主机,网络层服务于主机间的数据传输。就如寄出了一封信,信将在城市间穿梭,最终到达了收信人手中。以这样类比,信的构成为应用层协议,城市如何将信给到具体的人为运输层协议,信如何从一个城市抵达另一个城市为网络层协议。

网络层分为数据平面控制平面,数据平面实现了本地设备如何转发数据,控制平面控制了数据发送过程所要通过的路径。以同样的例子做类比,车辆从一个城市去往另一个城市,行车路径的规划与决定是控制平面所做的事情,每个ETC决定如何让车辆通过则是数据平面所做的事情。

所以,数据平面描述了本地设备如何转发,即在一个多端口的交换设备里,如何决定一个从输入端口而来的分组,该去向哪一个输出端口。,这一过程称为转发。需要注意的是,这里的端口指的是物理设备的端口,而不是运输层、网络层中的软件端口。

认识IPv4

交换设备要能实现转发,要先能识别分组。网络层中以IP(Internet Protocol,网际互联协议)来构建分组,包含了分组从哪来、到哪里、承载何种数据、做何处理的组织规则。当下广泛使用的IP协议有IPv4版本和IPv6版本。

现在,首先了解IPv4。

报文结构

IPv4报文结构.png

  • 版本:IP协议的版本号,不同的IP数据报的格式是不同的,通过版本号交换设备才知道如何解释报文。
  • 首部长度:IPv4报文首部固定长度为20字节,但是包含了可选部分,需要指示出首部实际长度。
  • 服务类型:用于区分IP数据报的类型,以能得到不同的处理,如实时数据报、非实时流量数据报等。
  • 数据报长度:报文的总长度,减去首部长度就得到有效数据的长度。
  • 标识、标志、偏移:有时候报文过大,超出交换设备的单次转发上限,需要将这种类型的报文切成多片发出,然后在接收处恢复,这些位置是为了这个过程而记录关键信息。
  • 寿命:也叫 TTL(Time-To-live),指报文还能在网络中转发的次数,为0时必须丢弃。
  • 上层协议:当报文到达最终目的地时才会使用,表示上层协议是什么,如UDP为17、TCP为6。
  • 首部校验和:用来检测报文在传输过程中是否发生错误。计算方式为,将首部中的每2个字节当做一个数,逐个通过反码算数得到和。
  • 源IP地址:表示数据的来源处,32比特,意味着总共能有约 42.95 亿个不同的地址。
  • 目的IP地址:表示数据的目的地,32比特。
  • 选项:允许对首部进行扩展,来实现一些特殊的功能,因此有首部长度来指明首部所占空间。
  • 数据:有效载荷,上层数据存储的地方,如整个TCP报文。

编址

与直观感觉不同的是,IP并不是针对于主机、设备来编址的。主机通过物理链路连接到网络,主机与物理链路之间的边界称为接口,IP编址针对的是这些接口。

在IPv4中,每个IP地址32bit,便于记忆与书写,以点分十进制计法记录IP地址,即每8字节一个十进制部分,以“.”分隔,如:

11000000 10101000 00000000 00000001
表示为
192.168.0.1
复制代码

两个IP地址在物理上是否连接,取决双方接口上是否有物理链路。逻辑上连接的IP地址是代表可以通过若干物理链路可以到达。

子网.png

图中路由器连接如197.1.1.xxx、197.1.2.xxx、197.1.3.xxx格式的IP地址。类似这样,有用共同前缀形如A.B.C.xxx的IP地址的主机、设备形成的网络,共同构成了一个子网,路由器使用了单独的接口连接上了子网。

更一般的,IP编址为子网分配地址时,将分配一个 A.B.C.D/y 的子网地址,其中 /y 表示最前左侧的y位为子网地址前缀,之后的位数用于分配对应主机、设备的接口地址。A.B.C.D/y也可叫做子网掩码

如图中的子网可分别为 197.1.1.0/24、197.1.2.0/24、197.1.3.0/24。

子网的概念非常有用:

  • 通过匹配子网能迅速地匹配目的地,不妨把子网类比于文件夹的功能,将所包含的文件(IP地址)聚类,以能更快的找到目的文件夹(子网)。如果没有子网,当一个路由器要转发到目的IP地址时,它需要知道 A.B.C.D/y 下所有的IP地址信息才能完成匹配,然后抵达目的IP地址,信息随着要连接的IP地址增长迅速。而有了子网,仅需要知道 A.B.C.D/y 即子网掩码就能完成匹配,此后再由连接子网的路由器进一步处理即可。
  • 编址将32比特的IP地址划分成两部分,前y比特为子网部分,y位后为具体部分。32 – y 的比特位可用于分配给子网内的设备接口,可以按需分配。而不是固定格式导致的子网内剩余过多IP地址而浪费,或IP地址不够用。这样的地址分配策略也叫CIDR(Classless Interdomain Routing,无类別域路由选择)。

地址分配

当然,IP地址并不是想编址成什么样都可以的,否则就无法保证IP地址的唯一性。为了得到一块子网地址以分配给组织内部,可以向ISP申请IP地址,或者向ICANN(一个全球性的IP地址管理和分配机构)申请IP地址。

在申请到IP地址后,就可以向组织内的各个接口配置IP地址。这项工作可以手动配置,也可以使用DHCP(Dynamic Host Configuration,动态主机配置协议)进行配置。

DHCP提供的即插即拔服务非常有用。想象一下,你拿着笔记本走到一个图书馆,插入网线,总不能让工作人员当场给分配一个IP地址吧。这样,就需要可以动态配置IP地址的服务来为临时的主机分配地址。

DHCP.png

  1. 在DHCP中,DHCP服务器程序监听来自67端口的报文。一个主机想要获得IP地址,主机生成包含DHCP发现报文的IP数据报,然后发往链路层。此时,主机没有IP地址,也不知道DHCP服务器地址,因此原地址为0.0.0.0,目的地址为255.255.255.255,以及一个会话ID。链路层发现255.255.255.255的地址后,会向子网的所有的节点广播这个DHCP报文。
  2. 子网中的所有DHCP服务器都可以收到DHCP发现报文,然后,使用DHCP提供报文向用户主机响应。报文中包含了自己的服务器地址 DHCP server ID,给用户主机分配的地址 yiaddr,会话ID,服务提供周期。
  3. 主机收到DHCP提供报文后,从中选择一个服务器使用服务,发送DHCP请求报文,此后得知了自己被分配的地址和服务器地址。
  4. DHCP服务器收到DHCP请求报文后,向用户主机发送DHCP ACK报文。此后主机正式使用DHCP服务,连接到网络。

当然,DHCP的服务提供周期到期后,可以继续请求DHCP继续使用服务,或选择其他的DHCP服务器提供服务。

NAT(网络地址转化)

子网可以在一定程度上为子网节点分配IP,但是当子节点过多,没有更多的IP分配给子节点该怎么办?

NAT(Network Address Translation,网络地址转换)就用于解决为子节点分配IP地址的问题,特使是针对于家庭网络、办公室网络等这些专用网络

在专用网络中,子网节点具有如 10.0.0.0/24 这样的子网掩码,然后各个节点从中分配各自的IP地址。这样的IP地址只有在专用网络中才有意义,不能在更大的因特网中使用,因为其他的专用网络也会使用相同的IP地址。因此,就需要将维护一份映射关系,以让专用网络下的IP地址能正确的访问子网外的网络。

NAT运作.png

  1. 专用网络下的IP地址为 10.0.0.1 的主机将要访问其他网络中的 X.Y.Z.V 地址,并以端口 a 来收发数据。NAT路由器将收到此报文。
  2. NAT路由为子网节点的网络请求分配 WAN 端口,并记录连接次节点端口的LAN端信息,此时 LAN端记录 10.0.0.1:端口a,WAN端记录 A.B.C.D:端口b。 然后NAT路由器将数据报中的源IP地址和端口更换为 A.B.C.D:B,向 X.Y.Z.V发起访问。
  3. 当收到来自 X.Y.Z.V 的请求时,NAT路由器通过响应报文中的目的IP地址和端口号,查阅NAT转换表,知道此响应报文是交给 10.0.0.1:端口a 处理,然后将数据报的目的IP地址和端口改写成 10.0.0.1:a.
  4. 使用NAT这样的方式,能为专用网络下的节点分配任意IP地址,而对于外部网络来说,它们根本不知道专用网络的存在,他们访问的总是 A.B.C.D 这个唯一IP地址。

类似NAT这样执行特殊功能的组件,称为中间盒,类似的还有负载均衡、防火墙等。

认识IPv6

虽然IPv4能满足设计它的目的,但是它将面临一个问题,40多亿的唯一IP地址将不够被分配。因此有了IPv6来解决IP地址不够分配的问题,并做了其他优化。

报文结构

IPv6 报文结构.png

  • 版本:IP协议的版本号,这里为6。
  • 流量类型:与IPv4服务类型区一样,用来表明数据包的类型,以能做特殊处理。
  • 流标签:没有明确定义的,为未来预留的区域,可用于“给属于特殊流的分组加上标签,这些特殊流是发送方要求进行特殊处理的流,如一种非默认服务质量或需要实时服务的流”。
  • 有效载荷:指示数据区的长度。
  • 下一首部:与IPv4 上层协议字段一样,表明数据区承载的是哪种上层协议的数据报。
  • 跳限制:此数据报允许转发的次数。
  • 源地址:128bit组成的IP地址,现在就算是地球上的每一粒沙子都可以被分配IP地址。
  • 目的地址:也是由128bit组成的IP地址。
  • 数据:有效数据,由下一首部中的协议处理。

与IPv4版本相比,IPv6使用了固定的40字节首部:

  1. 极大地扩大了IP地址能分配的数量。
  2. 去掉了IPv4支持的分片/重装功能,要求这样的功能只能在源和目的地进行,如果交换设备收到的IPv6报文过大,会向发送方但会一个“分组太大”的ICMP差错报文。原因是因为,分组/重装是一个很耗时的操作,从交换设备中移除,能有效地提升分组在网络中的转发速度。
  3. 去掉了首部校验和,因特网协议栈中,网络层的上下层运输层与链路层都执行了校验操作,再次在交换设备中进行此操作实属多余,因此去掉。于分组/重装操作一样,校验操作也是耗时操作。去掉后进一步调高分组的转发速度。
  4. 选项部分不再是首部的一部分,进一步的,它体现在下一首部区域,然后再在数据区填入内容,这样首部大小恒定。

隧道

一个现实的问题是,现实网络中,大多数交换设备仅支持使用IPv4交换分组,一次性替换到支持IPv6是不现实的。支持IPv6的交换设备可以很容易地向前兼容,但是已部署的IPv4交换设备不能向后兼容。一个可行的解决方案称为隧道

隧道.png

  • 当一个IPv6交换设备知道即将穿过若干个IPv4交换设备最终到达一个IPv6交换设备,就将IPv6数据报装成一个IPv4数据报,这个IPv4数据报源地址为 X,目的地址为 Y,数据区内容为原先的IPv6数据报。
  • 其中穿过的IPv4交换设备集合称为隧道,这些设备依旧按照IPv4标准处理IPv4数据报。
  • 当IPv4数据报到达地址为Y的IPv6交换设备后,再从中还原IPv6数据报,继续发往下一个IPv6设备。

以隧道这样的形式,IPv6能向前兼容仅支持IPv4的交换设备,IPv4交换设备也并不知道自己转发了一个IPv6报文,只需当成IPv4报文来处理。

路由器

有了IP协议之后,就能识别一个数据分组从哪来、到哪去,并能从中读出需要交换设备进行处理的功能。

路由器.png

一种常见的交换设备为路由器,它基于网络层数据报的首部做出转发决定,路由器组成部分包括:

  • 输入端口:接收来自其他交换设备的分组,通过路由选择的指示,调整分组,发往合适的输出端口。
  • 路由选择:在路由器内部或者在远端的软件功能,决定了从源IP到目的IP在整个网络中要经过的交换设备路径。路由选择体现在控制平面,当前我们关注数据平面功能,并假设得到了控制平面的指示而不关心具体如何得到。通过路由选择,路由器可以决定从输入端口得到的交换设备,要去往下一个交换设备要从哪个输出端口发出。
  • 交换结构:将输入端口与输出端口连接。
  • 输出端口:输出分组到连接的链路上。

转发决策

路由器如何决策转发呢?类比与ETC,如何给通过的车辆指明路径。从A省B市出发去往X省Y市的车,到达了I省O市的ETC,O市的EXT指明自己知道的去往X省的路而可能不关心如何到达Y市,这样的决策方式叫做基于目的转发。当车辆行驶到K省L市的ETC,此ETC认为车辆类型不符合上路标准,因此不予通过或者指示选择另一地点的EXT,像这样的决策方式称为通用转发

通过路由选择提示与IP编址规则,路由器基于目的在转发可以通过匹配IP地址范围来知道输出端口。如:

基于目的转发地址.png

图中表示了各输出端口转发的IP地址范围,不同的IP地址通过前缀匹配可以找到目的转发输出端口,每一个前缀匹配规则与对应的输出端口形成一个转发表项,建立出转发表,如:

IP地址 目的输出端口
1100 1000 0001 0111 0001 0*** **** **** **** 0
1100 1000 0001 0111 0001 1000 **** **** **** 1
1100 1000 0001 0111 0001 1*** **** **** **** 2
其他 其他

当出现同时满足输出端口1和2的多个表项的IP地址时,采用最长前缀匹配规则来确定。按照这样的方式,转发表不必记住所有的IP地址的去向关系,只需记录少得多的IP地址范围的去向关系。顺带一提,匹配操作由硬件完成,以保证在纳秒级别从所有表项中匹配出结果。

基于这样的规则,控制转发表的匹配关系,就可以达到控制传输路径的目的,由此可以拓展到如负载均衡、防火墙、NAT等功能。这部分能力在控制平面得到表达,当下继续聚焦于数据平面。

交换

经由交换结构,输入端口向输出端口交换分组的方式有如下几种发方法:

交换.png

  • 经内存交换:最简单和直接的交换方式,通过CPU来处理分组交换过程,一个来自于输入端口的分组被存储入内存,再由另一输出端口读出。这样的方式下,假设CPU处理速度为 N,那么总的转发速率必然小于 N/2。
  • 经总线交换:类似于DMA的处理,数据不经过CPU干预,直接通过总线传输到达目的地。当然,同一之间只有一个分组能够跨越总线,转发速率取决于总线的速率。
  • 经内部网络交换:复杂的控制方式,由多条总线纵横交错成了一幅网络路径图,未被使用的路径均可以用来传输分组(可到达的话)。比如一个分组传输经由交叉点ABEF,一个经由DEF的分组必须等待,因为EF被占用,但是一个经由DEHI的分组则可以同时传输。

排队

经过交换结构,分组最终到达输出端口,发往下一目的地。需要考虑的是,在交换过程中并不总是能马上得到处理,一个分组前可能有N个分组还未得到处理,需要缓存分组排队进行处理。

排队即可能出现在输入端口,又可能出现在输出端口上。输入端口与输出端口拥有着多对多的关系。假设每个端口的处理能力均为 N、有K个输入端口、L个输出端口。输入端口的排队是因为到达输入端口的分组速率 X > N输出端口的排队是因为接收来自各个输入端口的总速率 Y(=u1+u2+u3…+uk) > N

无论哪一端出现排队,端口的缓存能力有限,当没有更多缓存存储更多分组时,则必须丢弃某些分组,这样的情况叫做丢包

在输入端口还可能因为线路前部阻塞(Head-Of-the-Line,HOL)而出现排队。HOL描述的情况是。每个分组最终到达的输出端口不同,假设输入端口中的分组要去往的输出端口的顺序为 02231110。如果输出端口 0 是忙碌的,后续去往其他输出端口的分组也不得不排队等待,即使目的输出端口是空闲的。针对于HOL,也会有很多解决方案的讨论,这里不做深入。

分组调度

对于排队中的分组,有不同的策略进行处理:
先进先出:最简单的调度方式,按照分组到达的顺序传输。
优先权:将到达的分组按照优先权的不同,进入到不同的队列中排队,高优先权的分组优先被传输。注意这是非抢占式优先权排队,如果低优先权的某个分组正在传输中,高优先权的分组也必须先等待。
循环和加权公平队列:将到达的分组分类到不同的队列中,不同的队列拥有不同的权值w,在规定的时间间隔内,每个队列得到的传输速率比例满足它的权值占总权值的比例。

匹配与动作

观察数据平面所做的工作,交换处理了一个来自于输入端口的分组,如何交换到特定的输出端口的本地行为动作。在网络中,不同的交换设备可能进行的工作不同,如转发、NAT、防火墙、负载均衡等。如果交换设备各自为营,独立作战,将难以管理、维护并达到设计目的。

就交换设备而言,参照,先从转发表匹配出了输入端口的分组的对应表项,然后执行了动作将分组交换到输出端口。那么,将这个过程一般化,抽象出匹配规则与动作规范,就能达到控制交换设备的目的。

OpenFlow制定了匹配加动作和控制器的标准

openFlow.png

在OpenFlow中,包括:

  • OpenFlow Controller:称为控制器,控制着分组如何在网络中穿梭,通过OpenFlow Protocol为交换设备提供Flow Table。现在,我们不必关心控制器如何决定Flow Table 如何形成。
  • Controller Channel:可以视为交换设备与控制器通信的端口。
  • FLow Table:称为流表,表中每一项为流表项,每一项指示了特定动作,通过将分组信息匹配流表项,能决定此分组的动作。
  • OpenFlow Protocol:通过协议规则,控制器才能为交换设备提供流表。

OpenFlow的匹配规则,可以对各层报文首部共11个字段进行匹配。

OpenFlow 匹配.png

每一层的报文都被下层协议封装,才能完成对应层的功能。在交换设备中,不仅处理网络层,还处理了链路层的具体逻辑。因此,能分别对不同层级的首部字段进行匹配。

对于动作,每个流表项可有0或多个动作列表,这些动作决定了对分组的最终处理,包括但不限于:

  • 转发:将一个分组转发到一个特定的物理输出端口、广播到所有端口等。也可能将分组发送给远端的控制器。
  • 丢弃:没有动作的流表项,表明某个匹配的分组应当被丢弃。
  • 修改字段:可以在分组到达最终目的前,改写匹配规则中的字段,以达成某些控制目的。

例子

以OpenFlow为标准,观察在网络场景中如何使用。

openFlow例子.png

图中交换设备s1、s2、s3共为6台主机连接网络,每台交换设备有4个端口,并有对应流表来完成对应工作,当前,省略了从控制器获取流表的过程(未画出)。

–简单转发–

一个简单的例子是,主机h5或h6,发往h3或4,途经s3 -> s1 -> s2 转发。按照流表的设想与,各交换设备流表为:

s3流表

(匹配)IP Scr=10.3.*.*  IP Dst=10.1.*.*        (动作)转发
复制代码

s1流表

(匹配)Ingress Port=1  IP Scr=10.3.*.*  IP Dst=10.2.*.*        (动作)转发
复制代码

s1流表

(匹配)Ingress Port=2  IP Dst=10.2.0.3    (动作)转发
(匹配)Ingress Port=2  IP Dst=10.2.0.4    (动作)转发
复制代码

–负载均衡–

这个例子是,主机h3发往10.1.*.*的分组经过 s2 -> s1,而h4发往10.1.*.*的分组经过s2 -> s3 -> s1

s2流表

(匹配)Ingress Port=3  IP Dst=10.1.*.*    (动作)转发
(匹配)Ingress Port=4  IP Dst=10.1.*.*    (动作)转发
复制代码

s1流表

(匹配)Ingress Port=4  IP Scr=10.2.0.3  IP Dst=10.1.*.*        (动作)转发
(匹配)Ingress Port=3  IP Dst=10.1.0.2    (动作)转发
(匹配)Ingress Port=2  IP Dst=10.2.0.1    (动作)转发
(匹配)Ingress Port=1  IP Scr=10.2.*.*  IP Dst=10.1.*.*        (动作)转发
复制代码

s3流表

(匹配)Ingress Port=4  IP Scr=10.2.0.4  IP Dst=10.1.*.*        (动作)转发
复制代码

–防火墙–

现在的例子是,s2仅希望接收来自s3的流量。
s2流表

(匹配)Src=10.3.*.*  IP Dst=10.2.0.3      (动作)转发
(匹配)Src=10.3.*.*  IP Dst=10.2.0.4      (动作)转发
复制代码

总结

数据平面描述了网络层如何将来自于运输层数据的分组后进行转发,是交换设备的本地行为:

  1. 一开始,为了识别分组从哪来、到哪去、需要什么服务,以IPv4协议来编织分组结构,在封装、拆解的行为中,能从IP报文中提取信息。
  2. 而IPv4地址不能分配越来越多的唯一地址后,以IPv6来应对并调优了一些问题。并以隧道的形式将IPv6报文放入IPv4报文数据段中并更换报文源、目的IP地址,来兼容两版本协议间协作。
  3. 进而,交换设备结余最长前缀匹配将输出端口与目的地址做映射关系,这样就能通过少得多的记录维护输出端口与分组最终目的地的关系。
  4. 通过观察交换设备的行为,使用了更一般的OpenFlow协议规范了交换设备的行为,在数据平面上,参照流表,就能完成各种中间盒功能如NAT、负载均衡、防火墙等的管理、维护与实现,而不关心流表如何形成。
  5. 最终,分组最终能通过交换结构从输入端口交换到输出端口,转发到下一交换设备并最终交付给目标主机。

文章大部分来自《计算机网络——自顶向下方法》,第七版,第4章。

参考

《计算机网络——自顶向下方法》,第七版,第4章。

OpenFlow协议初探——OpenFLow中的流和流表

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享