这一层将主要学习网络层实际是怎样实现主机到主机的通信服务的。

梗概

网络层能够被 分解为两个相互作用的部分,即数据平面和控制平面。首先学习网络层 的数据平面功能,即网络层中每台路由器的功能,该数据平面功能决定到达路由器输入链 路之一的数据报(即网络层的分组)如何转发到该路由器的输出链路之一。

网络层概述

路由器是不运行应用层和传输层协议的。

转发和路由选择:数据平面和控制平面

即将分组从一台发送主机移动到一台接收主机,需要使用两种重要的网络层功能:

  • 转发,收到一个分组的时候,要将它转移到合适的输出链路。
  • 路由选择,当分组从发送方流向接收方时,网络层必须决定这些分组所采用的路由或路径。计算这些路径的算法被称为路由选择算法(routing algorithm),路由选择在网络层的控制平面中实现。

每台网络路由器中有一个关键元素是它的转发表(forwarding table)。路由器检査到达分组首部的一个或多个字段值,进而使用这些首部值在其转发表中索引,通过这种方法来转发分组。

如图,通过获取分组首部的值,选择本地的路由端口输出。

控制平面:传统的方法

传统的方法当然就是对每一种可能,人为地配置输出端口,这样一定可行。但是人为配置容易出错且无法应对复杂的网络环境。

控制平面:SDN方法

通过使用软件的方式去控制网络,这个在后面细说。

网络服务模型

网络服务模型可能包含以下类型的服务:

  • 确保交付
  • 具有时延上界的确保交付
  • 有序分组交付
  • 确保最小带宽
  • 安全

有一种服务叫尽力而为服务,说起来好听,实际就是不可靠服务。但是实际上证明了,它的工作效果还是很好的,有适当的带宽供给和带宽自适应应用级协议。

第四章概述

分组交换机是一个笼统的概念,路由器也是一种分组交换机,不过它是网络层的分组交换机,一般我们说的交换机是链路层交换机。

路由器工作原理

先来看看路由器的体系结构:

我们专注于数据平面的转发功能,就是实际将分组从一台路由器的入链路传送到适当的出链路。

这里包含四个结构:

  • 输入端口
  • 交换结构
  • 输出端口
  • 路由选择处理器,这个应该是交换结构的上层实现

考虑一下我们在使用路由器的时候,需要存储什么样的信息,举个例子:

我走到了十字路口,我到底是往哪里走(哪个端口)呢?

  • 第一种是基于目的地的转发,即我到哪我都预判一遍,然后选路,这是个显然合理的方案,但是我要去的地方可以有很多,如果都存储显然不合理。
  • 第二种是泛化转发,即把我要去的地方划分为区域,因为路口只有三个选择:直行,左转,右转。这样的话我可以使用很少的存储来解决所有的目的地址。

同样,类比到网络层,我的目的地址是一个32位的ip地址,算下来有42亿种的可能性,这显然不合理,因此我们会采取第二种的方式。

输入端口处理和基于目的的转发

就像前面说的一样,最简单的情况就是对所有的网络地址设置转发端口,可行性不太行。

书上举了一个例子,可以将同一网段的计算机设置一个链路出口,这样的话我们只需要使用 IP+子网掩码 + 端口即可很高效地完成转发。

这里需要注意一点:如果多个子网匹配上了,则优先考虑子网掩码较长的规则,这种规则叫最长前缀匹配规则

交换

有三种方式:

  • 经内存交换
  • 经总线交换
  • 经互联网络交换

输出端口处理

如图:

如何出现排队

排队过长会导致出现丢包事件,就像我们所说的:“在网络种丢失”,“被路由器丢弃”。

输入排队

假设输出端口缓存仅能存储一个分组,那么如下情况就会导致输入时延:

第一行和第三行的分组都要交换到输出端口第一行,那么我接受了第一行的分组之后,由于缓存满了,第三行的分组不得不等待。这种现象叫作输入排队交换机中的线路前部(Head-Of-the-Line,HOL)阻塞。

输出排队

我们当队列满了的时候,新的分组到达我们不得不做出如下决定:

  • 丢弃这个分组。
  • 删除一个已有分组替换当前接收的分组。

第二种做法是有利的,这可以向发送方提供一个拥塞信号。

当输出端口排队的时候,可能会使用分组调度器在这些排队分组中选择一个分组来传输,对于如何选择是我们接下来要讨论的问题了。

缓存需要多少才够用

这里可能颠覆之前的看法,在以前我们肯定都认为缓存越大越好,越大它越能容忍网络的波动。

但是考虑这样的问题:假设缓存有25个分组的长度,输入速率正好等于输出速率,那么我每一个包的时延都是25倍单个包传输的时延,因此缓存过大不一定是好事,这会导致缓存膨胀

后面有一种AQM机制用于对抗缓存膨胀。

分组调度

先进先出

字面意思

优先权排队

会分两个队列,高优先权的队列一定比低优先权的队列先开始传输,但不被打断。

循环加权公平排队

优先级不分上下,如果队列中有则会交替去发包。

网络中立性:

是指ISP必须在条件允许的情况下给用户提供

  • 无阻塞
  • 无限流
  • 无付费优先

的服务。

网际协议

有一句话:掌握IP编址就是掌握因特网的网络层

IPv4数据报格式

网络层的分组被称为数据报,数据报的格式如下:

  • 版本字段:这4比特规定了IP的版本,路由器可以查看该字段确定如何解析剩余的部分。
  • 首部长度:这4比特标识了首部的长度,因为首部长度必须是4的倍数,所以这里能表示4~64中4的整倍数。
  • 服务类型:能够区分实时数据报(比如IP电话应用)和非实时数据报(比如FTP),里面还有两个bit是可以告诉主机网络发生了拥塞。
  • 数据报长度(包括首部):占16个bit,理论上长度是65535,但是实际上,数据报一般不超过1500字节,因为这个长度相当于链路层的payload长度。
  • 标识、标志、片偏移:这三个字段与所谓IP分片有关。
  • 寿命(Time-To-Live):这个字段防止数据报出现环路,每当路由器处理数据报的时候,会把TTL-1,减为0的时候,数据报会被路由器丢弃。
  • 协议:指明了该数据报的上层传输层协议,是使用UDP还是TCP,UDP数据报此字段值为 17,TCP数据报此字段值为6。
  • 首部检验和:同TCP的吧,不过不同的是,因为存在TTL字段,所以每次需要修改一下检验和再发出去。
  • 源地址和目的地址:字面意思
  • 数据:就是payload了,但是ICMP报文也可以承载其它类型的数据。

IPv4编址

首先明确一点:IP地址是和主机绑定的,是和主机的物理接口绑定的。

IP地址采用点分十进制表示法,每个接口必须有一个全球唯一的IP地址(NAT接口除外)。这些地址不能随意决定,而是需要由其所连接的子网来决定。

把IP地址拆成32位二进制数,可能会有连续的相同的高位,它们属于同一子网,比如我们最常见的:

192.168.1.xxx的ip地址,在这里它们的最左侧24位的比特是相同的,这几个接口也通过一个不包含路由器的网络互联起来。该网络可能是以太网LAN互联或是无限接入点互联。

用IP的术语来说,左边三个主机与其路由器的接口形成一个子网

IP编址为这个子网分配一个地址223.1.1.0/24,其中的 /24记法,有时称为子网掩码(network mask),指示32比特中的最左侧24比特定义了子网地址,所有连接到这个网络的主机ip地址必须是 223.1.1.xxx 的形式。

为了确定子网,分开主机和路由器的每个接口,产生几个隔离的网络岛,使用接口端接这些隔离的网络的端点。这些隔离的网络中的每一个都叫作一个子网

比如下面的网络:

使用三台路由器有6个子网,因此我们可以发现,路由器是用于连接不同子网的网络层设备。

下面来看看因特网是如何处理编址的:

因特网地址分配策略是:无类别域间路由选择(CIDR)。当使用子网寻址时,32比特的IP地址被划分为两部分,并且也具有点分十进制数形式a. h. c. d/x,其中 x 指示了地址的第一部分中的比特数。

前x位叫做该IP地址的网络部分,被称为地址前缀,这样的话在设计路由表的时候就只需要考虑前面的x比特,大大减少了所需的存储空间,使用单个网络前缀通告多个网络的能力称为地址聚合,即具有相同网络前缀,但是子网掩码长度不一样的多个网络,一般来说,较短子网掩码的网络可以包括较长子网掩码的网络。

然后就是,多个子网匹配的话会给到最长的前缀(尽可能小的网络)。而剩余的32-x比特可以认为是区分子网的内部设备所使用的。

CIDR之前,IP地址的网络部分被限制为长度8、16、24比特,分别叫A,B,C类的网络地址。但是这样的分配方案不太合理,因为一个B类网络地址有65534个主机,而一个C类网络地址的主机数为254,假设我有一个公司需要1000台主机,C类网络地址放不下,而B类网络地址会导致大量地址占用。

主机号全0标识网络地址,全1表示广播地址,特别的:255.255.255.255 表示整个网络的主机。

获取一块地址

我们PC要获取IP地址需要从ISP中获得分配的地址,而ISP得到的地址块是由权威机构指定的。

获取主机地址:动态主机配置协议

这其实就是DHCP协议,我们理解为可以自动获取网络接口的IP地址就好了,因为这个特性,它也被称为即插即用协议或者是零配置协议

DHCP是 C/S 协议,最简单的情况就是每个子网都有一个DHCP服务器,这样每个计算机接入该子网都能获得自己的IP地址。如果该子网中不存在DHCP服务器,则需要一个DHCP中继代理,它会指明DHCP服务器的地址。

DHCP方式获取IP地址的步骤如下:

如下四个步骤:

  • DHCP服务器发现:首先我得找到我子网的DHCP服务器吧,这可通过使用DHCP发现报文(DHCP discover message)来完成,DHCP客户端使用68端口广播,DHCP服务器在67端口接收广播。
  • DHCP服务器提供:使用DHCP提供报文给客户端做出响应,这里我也必须广播,因为此时主机并没有IP地址,包含有收到的 发现报文的事务ID、向客户推荐的IP地址、网络掩码以及IP地址租用期(address lease time) 即IP地址有效的时间量。
  • DHCP请求:向DHCP服务器请求自己的IP地址。
  • DHCP ACK:对DHCP请求报文回应,证实所要求的参数。

在客户端正式获得一个ip地址之前,发送的都是广播。

网络地址转换

32位的IP地址中,有三段私有地址:

  • 10.0.0.0/8
  • 172.16.0.0/12
  • 192.168.0.0/16

私有地址到公网地址的转换需要通过网络地址转换(Network Address Translation,NAT),具有私有地址IP的主机仅在该网络有意义,不过私有地址已经足够我们平时的生活,因为拥有私有地址的我们同样能通过NAT访问因特网任意一台主机,因为因特网的主机IP是唯一的。

那私有地址如何收发来自因特网的分组呢?答案在于理解NAT。

NAT使得一个私有网络的所有设备聚合成一台具有单一公网IP的设备。

过程是这样的:

10.0.0.1的主机向1.1.1.1的主机发送一个分组,那么在与公网连接的路由器会把该私有地址(包括端口)进行端口映射并存储在NAT转换表当中。路由器向公网发送分组的时候,把源IP和端口改为了自己与公网连接的那个IP和对应的NAT映射端口。这样在公网主机想往回发送分组的时候,就会发送到这里的IP和端口,路由器收到分组会查看NAT表,返回给对应的内网主机。

IPv6

因为32位的IP地址即将用完,因此研发了IPv6协议,IPv6地址为128位长度,数据报也有所不同,IPv6的数据报如图所示:

IPv6相比IPv4具有以下优点:

  • 除了单播和多播以外,还出现了任播地址,使得我们可以发送数据报给预期IP地址的任何一个。
  • 固定40字节的首部长度
  • 流标签可以给特殊的分组加上标签。

下面详细解释一下IPv4数据报的字段:

  • 版本:用于标识IP版本号,IPv6中,该字段值为6。
  • 流量类型:与IPv4中的TOS一致。
  • 流标签:用于区分优先权。
  • 有效荷载长度:就是有效数据的长度。
  • 下一个首部:标识需要交付给哪个传输层协议。
  • 跳限制:同TTL。
  • 源地址和目的地址:字面意思。
  • 数据:字面意思。

通用转发和SDN

基于目的地的转发的特征主要分两个步骤:匹配+操作,这样的转发表在OpenFlow中称为流表

流表包含如下字段:

  • 首部字段集合:可以匹配首部字段的值。
  • 计数器集合,这里可以包括与该表项匹配的分组数量。
  • 操作:这里的操作可以进行转发或者丢弃,或者是改写首部字段的值。

匹配

可以匹配以下首部字段:

包括链路层,传输层首部和网络层的地址,协议类型以及TOS。

操作

  • 转发:可以转发到一个特定的物理端口,或者是广播到所有端口。
  • 丢弃:没有操作的流表标识该分组会被丢弃。
  • 修改字段:除了IP协议字段外的所有二三四层的字段中的值可以重写。

例子

从书上给的三个例子来看,它可以完成如下的功能:

  • 简单转发
  • 负载均衡
  • 防火墙

中间盒

用于提供除转发以外的功能,比如NAT,安全服务,增强性能等等

小结

在本章中,我们讨论了网络层的数据平面(data plane)功能,即每台路由器的如下功能:决定到达路由器的输入链路之一的分组如何转发到该路由器的输岀链路之一。