计算机网络
知 识 梳 理
(第一版)
建议先修课程:数据结构。
配套教材:
Computer Networking - A Top Down Approach, 7th edition James F. Kurose, Keith W. Ross
参考书目:
1、计算机网络(第8版) 谢希仁 编著 高等教育出版社
链接:https://pan.baidu.com/s/1jABCuckHr-eqA9AFvbpXuQ
提取码:0000
四 网络层——数据
4.1 网络层概览
网络层的功能主要有:
·转发。分组到达路由器的输入链路时,路由器将其移动到适当的输出链路。这是最常见、最重要的功能。不过,分组也可能被路由器阻挡(如果来源于一台已知的恶意主机,或发向一台被禁止的目标主机),或者是冗余的。
·路由。当分组从发送方流向接收方时,网络层必须决定分组经过的路由。计算这些路径的算法称为路由算法。
使用相同网络层协议的异构(heterogeneous,即架构不同)网络可以被路由器互连起来。
在讨论网络层时,许多作者经常交替使用转发和路由选择这两个术语。为了避免混淆,这里统一一下用法:
转发(forwarding),是指将分组从一条输入链路转移到适当的输出链路的、路由器的本地动作,也就是说:转发仅涉及单一路由器。转发的耗时很短(例如几ns),多用硬件实现。
路由选择(routing),是指确定分组从源到目的地所采取的端到端路径的、网络范围的处理过程,也就是说:路由涉及到多台路由器。路由选择的用时长得多(比如几秒),多用软件实现。
每台路由器都有一个关键部分:转发表(forwarding table)。路由器检查分组首部的若干个字段,使用这些值在转发表中索引(查找),并转发分组。这些值对应存储在转发表项中的值,后者指出该分组将被转发到的输出链路。
路由算法决定该路由器的转发表。路由选择算法可以运行在每台路由器中,每台路由器都包含转发和路由选择两种功能。我们将在5.3、5.4节学到:一台路由器中的路由选择算法与其它路由器的路由选择算法通信,以计算出它的转发表的值。这种通信是如何执行的呢?答案是:根据路由选择协议,交换包含路由选择信息的路由选择报文。
上述方法是传统方法。使用该方法,每台路由器都具备与其它路由器的路由选择组件通信的路由选择组件。然而,也存在其它方式来确定转发表的内容。
另一种方法是:远程控制器计算并分发转发表,供每台路由器使用。上下两图中,数据层面相同;而在下图中,控制层面的路由功能与路由器在物理上分离:路由器仅执行转发,而远程控制器给出转发表。远程控制器使用高可靠、高冗余的数据中心实现,并由ISP或第三方管理。路由器和远程控制器通过交换包含转发表和其它路由信息的报文来通信。此方法称为软件定义网络(Software-Defined Networking,SDN),因为计算转发表并与路由器交互的控制器是用软件实现的,故网络是“软件定义”的。这些软件实现也越来越开放,类似于Linux:这些代码可为公众所用,允许ISP(以及科研人员和学生)去创新,并对控制网络层功能的软件提出更改建议。5.5节进一步学习SDN。
网络层能提供的服务包括:
·确保交付:保证分组最终到达目的地。
·具有时延上界的确保交付:不仅确保交付,而且确保在特定的主机到主机时延上界内(如100 ms内)交付。
·有序分组交付。该服务确保分组以它们发送的顺序到达目的地。
·确保最小带宽。只要发送主机以低于特定比特率的速率传输,则保证所有分组最终会交付到目标主机。
·安全性。网络层在源点加密所有数据报,并在目的地解密这些分组,从而对所有运输层报文段提供机密性。
这只是网络层能提供的部分服务。具体能提供哪些,视实现的不同而不同。
Internet的网络层仅提供单一的尽力而为服务(best-effort service):既不保证分组按发送顺序被接收,也不保证最终成功交付;既不保证分组不出错,也不保证不重复;既不保证端到端时延,也不保证最小带宽。这似乎是“根本无服务”的一种委婉说法:一个从来不向目的地交付分组的网络,也符合尽力而为服务的定义!许多网络架构定义和实现了超过Internet尽力而为服务的服务模型。例如,ATM(Asynchronous Transfer Mode,异步传输模式)确保按序时延、有界时延及最小带宽,但现已很少使用。还有新提出的对Internet体系结构的服务模型扩展。例如,集成服务体系结构RFC 1633的目标是:提供端到端时延保证与无拥塞通信。诚然,这些方案也许都很不错;但大量事实证明,Internet的尽力而为服务在带宽足够的情形下,已经表现得足够好,能够用于无数应用,包括Netflix、IP语音等串流影音,以及Skype和Facetime等实时会议应用。互联网能发展到今日的规模,充分证明了当初采用这种设计思路的正确性。
在继续学习之前,先明确几个常用术语:
路由器(router)和交换机(switch)都能转发分组:将分组从入站(输入)链路转移到出站(输出)链路。但路由器根据网络层数据报的报头来决定如何转发,而交换机既可能根据数据报报头也可能根据链路层帧的首部选择转发策略。因此,路由器工作在网络层,即第三层。工作在链路层和网络层的交换机常称为二层交换机和三层交换机。三层交换机具备一定的路由功能。随着技术的发展,三层交换机和路由器的功能越来越相似了(特别是高端产品)。
4.2 路由器的内部有什么?
路由器的结构通常是这样的:
主要的组件有:
·输入端口(input port)。它执行几项重要功能:接收传输的位(物理层功能);与位于输入链路远端的链路层交互、传送帧(数据链路层功能);更重要的是,输入端口还执行查找功能(网络层功能)。这3个功能由各自的处理模块处理,在图上画成了3个方框。控制分组(如:携带路由协议信息的分组)从输入端口转发到路由处理器。对于一般的数据分组,则按照分组首部中的目的地址查找转发表并进行转发。
一台路由器的端口数量可以很少,比如企业路由器;而位于某ISP边缘的路由器可以具有数百乃至上千个Gbps级别的端口,输入线路的数量在网络中也接近最大。
·交换结构(switching fabric)。交换结构将路由器的输入端口连接到它的输出端口。这种复杂的结构通常做成芯片(例如,BCM83XX),位于路由器中,是网络路由器中的网络。
·输出端口。输出端口存储从交换结构接收的分组,并通过执行必要的链路层和物理层功能。在输出链路上传输这些分组。如果一条链路是双向的,那么输出端口通常与该链路的输入端口成对出现在同一线路卡上。
线路卡(line card)也称数字线路卡(digital line card),是一种用于交换机、路由器或其它网络设备的访问线路与访问设备间的一种设备接口。
·路由处理器。通常比较类似CPU,执行控制功能。在传统路由器中,它执行路由协议(见5.3、5.4节),对链路进行响应,维护路由表(下文)、转发表与关联链路的状态信息。在SDN路由器中,它与远程控制器通信,接收远程控制器计算的转发表项,并在路由器输入端口写入这些项。路由选择处理器还执行网络管理功能,参见5.7节。
如图,在交换结构之前,在每个输入端口处就可以查找转发表副本(影子副本,shadow copy)并决定转发路径,而无需统一交由路由处理器,避免了集中式处理的瓶颈。
如何构造转发表呢?暴力法是不可取的:即使只使用IPv4,整个表就可以具有30 ~ 40亿个条目。
一种方法是:通过前缀选择出站链路。举例,一张转发表可以是这样的(每一项的其它内容未列出):
使用这种转发表,路由器用分组目标地址的前缀与表项匹配;若匹配成功,则向匹配项对应的链路转发分组。有多个匹配时,使用最长前缀匹配(longest prefix matching,LPM)算法选择最长的匹配项,并向对应链路转发分组。在4.3节学习Internet编址时,你将明白使用LPM的理由:网络前缀越长,其地址块就越小,因而路由就越具体。
查表理论上很简单,硬件逻辑只是搜索转发表查找LPM。但在G级速率下,查找必须在ns级的时间内完成(设想一条10 G链路每秒能传送多少份IP数据报)。因此,不仅必须使用硬件执行查找,而且需要对大型转发表使用先进的搜索算法,还必须特别留意内存访问时间。为缩短这些时间,芯片上被整合DRAM和SRAM。实践中也经常使用三态内容寻址存储器(Ternary Content Address Memory,TCAM)来查找:IP地址被放入内存,TCAM基本能在常数时间内返回对该地址的转发表项。一些路由器能保存上百万TCAM转发表项。
给定32位的目标IPv4地址(参见4.3节),一个最简单的LPM方法是:枚举全部32种前缀,并在路由表中查找每个枚举。找不到相应的表项时,算法达到最坏情况。即便是对经常使用的路由,也需要浪费很多查找次数。
为了更加有效地查找,可以使用二叉字典树(binary trie)。字典树(trie)也称前缀树(prefix tree)、单词查找树,其每个节点代表一个字符串前缀;任何一个节点的子节点代表的字符串,都与该节点代表的前缀相同。示例:
根节点代表空字符串。查找字符串时,从根节点出发,每读取前缀的一个字符,就根据读取结果向深一层移动。如果能走到叶节点,就匹配到了一个完整的字符串(单词)。根据需求的不同,每个节点还可以存取额外的信息,比如单词的出现次数,等等。字符串本身不需要保存在节点中。图示中标注出完整的单词,只是为了演示trie的原理。
trie中的键通常是字符串,但也可以是其它的结构。trie的算法很容易修改为处理其它结构的有序序列,比如一串数字或者形状的排列。Bitwise trie(按位字典树)中的键是一串二进制位,可以用于表示整数或者内存地址等。位数据的存取由 CPU 指令一次直接实现,对于二进制数据,它理论上要比普通的trie快。
顺带一提,trie一词来自于retrieval(检索),具有两种读音(tree或try)。
事实上,我们在词典中查找单词时,根据前缀列出可能需要的单词这个功能就可以用字典树实现。如图:
为了进一步提高查找速率,常常对字典树进行压缩,以减少比较次数,进而减小查找时间。构造压缩的二叉字典树需要更多的计算,但由于每一次查找路由表时都可以提高查找速度,因此这样做还是值得的。
有的压缩技术则减小字典树的占用空间。此外,字典树的许多变种也已经问世。
注意:转发表和路由表是有区别的。路由表一般仅包含从目的网络到下一跳(用IP地址表示)的映射,而转发表是从路由表得出的。转发表必须包含转发需要的信息:每一行都包含从目的网络到输出端口和某些MAC地址(见第6章)信息(如,下一跳的MAC地址)的映射。将转发表和路由表用不同的数据结构实现有好处。转发分组时,转发表的结构应当使查找过程最优化,路由表则需要令网络拓扑变化时带来的计算量最少。路由表总是用软件实现的,但转发表可用特殊的硬件实现。有的资料不区分转发表和路由表,而笼统地使用“路由表”一词。
一旦确定了输出端口,分组通常就进入交换结构。如果其它输入端口的分组占用了交换结构,后到的分组可能会被暂时阻塞,在输入端口排队,等待稍后处理。其它动作也需及时进行:
①必须进行物理层和链路层相关的处理;
②必须检查分组的版本号、校验和及寿命字段(见4.3节),并重写后两个字段;
③必须更新用于网络管理(5.7节)的计数器(如接收到的IP数据报的数目)。
在输入端口查找目的IP地址,这是匹配(matching);发送该分组进入交换结构,这是动作(action)。“匹配 + 动作”(match-plus-action)的基本思想,在许多网络设备中都能看到。在链路层交换机(第6章)中,除了发送帧进入交换结构去往输出端口外,还要查找链路层目的地址,并采取若干其它措施。在防火墙(第8章)中,首部符合过滤规则的分组可能被阻止转发。在网络地址转换(4.3节)中,一个运输层端口号匹配某给定值的输入分组,在转发(动作)前其端口号将被重写。这个思想对于我们将在4.4节中学习的通用转发是至关重要的。
常用的分组转发(交换)技术大致分为三种:
·内存交换(memory switching)。最简单、最早的路由器是传统的计算机,输入输出端口之间的交换是在CPU的直接控制下完成的。I/O端口的功能就像传统操作系统中的I/O设备一样。一个分组到达输入端口时,该端口产生中断,向CPU发出信号。于是,分组从输入端口被复制到内存中。CPU则从其首部提取目的地址,在转发表中找出适当的输出端口,将其复制到输出端口的缓存中。这种情况下,如果内存读写速率为N个分组 / 秒,则总的转发吞吐量(分组从输入端口被传送到输出端口的总速率)必然小于N / 2分组 / 秒。此外,不能同时转发两个分组,即使它们有不同的目标端口,因为通过共享系统总线一次仅能执行一个内存读 / 写操作。
许多现代路由器通过内存进行交换。然而,与早期路由器的一个主要差别是,目的地址的查找和将分组存储(交换)进适当的内存位置是由输入线路卡来处理的。在某些方面,经内存交换的路由器很像共享内存的多处理器,通过一张线路卡上的处理,将分组交换(写)进适当的输出端口的内存中。
·总线交换(bus switching)。在这种方法中,输入端口经一根共享总线将分组直接传送到输出端口,无需路由处理器的干预。这通常按以下方式完成:输入端口为分组预先设定一个内部标签(首部),使分组在总线上传送,并正确发送到对应的输出端口。该分组能由所有输出端口收到,但只有与该标签匹配的端口才能保存该分组(类似的情况非常常见,相信大家在数字电路必修课及其实验课上已经注意到了)。标签在输出端口被移除,因为其仅用于交换机内部区别分组。如果N个分组同时到达路由器,则(N-1)个分组必须等待,因为一次只有1个分组能够跨越总线。故路由器的交换带宽受总线速率的限制。较新的路由器中,总线带宽已达Gbps级别。
·互连网络交换(interconnection network switching)。克服单一、共享式总线的带宽限制的一种方法是:使用更复杂的互联网络,类似于互连多CPU或GPU的拓扑结构。crossbar交换机具有一种由2N条总线组成的互联网络,连接输入输出端口各N个。每条垂直总线在交叉点与每条水平总线相交,交点由交换结构的控制器控制,能够随时开启和关闭。如上图,某分组到达端口A,需要转发到端口Y时,控制器闭合总线A和Y的交点,端口A在其总线上发送该分组,该分组仅由总线Y接收。来自端口B的一个分组同时能够转发到端口X,因为A到Y和B到X的分组使用不同的输入输出总线。因此,与前面两种交换方法不同,这种结构可并行转发多个分组。纵横式交换机是非阻塞的(non-blocking):只要没有其它分组被转发到该输出端口,转发到输出端口的分组就不会被阻塞。然而,如果来自2个不同输入端口的分组的目的地为相同的输出端口,则1个分组必须在输入端等待,因为在某个时刻经给定总线仍然仅能发送1个分组。更为复杂的互联网络使用多级交换,以使不同输入端口的分组可以同时转发到同一输出端口。路由器的交换能力也能够通过并行运行多种交换结构进行扩展。通过此方法,输入输出端口被连接到并行运行的N个交换结构。一个输入端口将一个分组分成K小块,并通过N个交换结构中的K个发送这些块到所选择的输出端口,输出端口再将K个块组装成原始的分组。
在路由器内部完成交换后,输出端口开始处理分组并发送到输出链路上,过程大致与输入端口的相应过程相反。
如果数据包来得太快,那么在输入和输出端口都可以形成等待队列。排队的位置和程度取决于流量负载、交换结构速率和线路速率。随着队列的增长,路由器的缓存将会耗尽。当无内存可用于存储到达的分组时,就出现丢包(packet loss)。前面我们常说分组“在网络中丢失”或“被路由器丢弃”。正是在路由器的这些队列中,分组被丢弃。当然,设备或线路出故障也可能使分组丢失。
为了尽量减少队列长度,路由器内部的交换结构转发分组的速率必须远远快于输入线路与输出线路的传输速率。
输入排队是路由器缓冲区排队的一种情况。如果交换结构的转发速率不够快,那么输入排队出现的概率就不低。
举例来说,现有一台使用crossbar形式的交换结构的路由器,并且:
【1】所有输入输出链路的传输速率相同;
【2】分组从任何一个输入端口传送到任何一个输出端口的用时都相同;
【3】分组按照FCFS(先来先服务)的方式进行转发。
那么,只要分组们的输出端口不同,多个分组就可以并行传送。然而,如果2个输入队列前端的2个分组发往同一输出队列,则其中1个分组将被阻塞,必须继续排队。因为单个交换结构一次只能传送1个分组到指定端口。
如下图,左上和左下的输入队列中,最早的分组都需要发往右上的输出队列。假设交换结构决定令左上的输入端口头部的分组先行传送,如此一来,左下的输入端口的头部的分组,连同它后面的一个分组,都需要在队列中等待,即便它之后的那个分组并不是要一起发送到右上的输出端口,而是将发送到中间的输出端口,且中间的输出端口并未被其它分组占用。这称为线路头部(Head-of-the-Line,HOL)阻塞。有研究指出,当发生