网络层概述

穷则独善其身,达则兼善天下。

—— 战国·孟子·《孟子》

数据链路层 解决了同一网络内多台主机间的通信问题,同一以太网内的主机通过以太网帧进行通信:

那么,以太网是否能够用来进行全球组网呢?

数据链路层局限性

随着接入以太网的主机不断增加,交换机一定遇到瓶颈。试想,如果全世界的主机都接入,需要制造一台多大的交换机!这根本就无法实现!

上一章介绍了级联交换机的组网技术,这确实可以扩展以太网络规模,但远远达不到组建全球网络的水平。制约以太网规模的主要瓶颈有两个:

  1. 广播风暴;
  2. MAC 地址表规模;

交换机转发数据帧时,如果发现目的 MAC 地址不认识,就采取广播策略。这意味着与陌生节点第一次通信时,数据帧需要广播到所有节点。这便是 广播风暴 ,网络规模越大,广播流量越恐怖。

为了唯一性,MAC 地址按 设备厂商 划分并烧在网卡设备内。某个组织内部使用的设备可能千差万别,因此无法对地址表进行合并。如果地址是 连续 的,就可以合并起来,进而组成 地址段 转发策略。

假设 MAC 地址是连续的,左右交换机主机 MAC 地址前缀相同,中间交换机 MAC 地址表便仅需两个条目。但实际上 MAC 地址是散乱的,中间交换机便只能为每台主机都维护一条转发配置记录了。

如果采用以太网进行全球组网,每台交换机都需要为所有主机都维护一条转发配置,这该消耗多少内存!—— 从工程角度上看,几乎没有实现的可能性。

为解决上述诸多问题,我们需要找到新的技术方案,以达到以下目标:

  • 引入新寻址机制,地址按网络拓扑分配,同个网络下地址是连续的;
  • 引入更高效的转发机制,杜绝广播风暴;

分层设计思想

那么,能否对数据链路层和以太网协议做一些改进,以适应全球组网的需要呢?

理论上,这种思路是能够实现的,但不够优雅。为什么呢?

我们知道,复杂的软件系统一般采用分层的思路进行设计,以便最大限度降低复杂性的同时提高灵活度。

举个例子,一个电商平台,后端可能会分成数据库层、缓存层、业务逻辑层、接入层等等。每个层次均只专注于本层处理逻辑,复杂性大大降低;各个层次间则互相配合,协同完成复杂业务逻辑。

计算机网络协议正是一个非常庞大的体系,势必也能从分层设计思想中获益。

举个例子,有两个不同的以太网,中间用一个特殊的转发设备连接起来:

由于前面讨论的诸多局限性,我们不希望中间的转发设备 R 参与以太网帧转发。这样一来,以太网 ① 中的主机,无法直接通过以太网与以太网 ② 中的主机进行通信。图中主机通信可以分为两种不同情况:

  1. 以太网内通信,例如 ① 与 ② ,又如 AB,亦如 ① 与转发设备;
  2. 以太网间通信,例如 ① 与 A

网内通信,数据链路层中的以太网协议就能很好胜任,但跨网通信又该如何实现呢?

以主机 ① 与主机 A 通信为例:我们知道,主机 ① 与转发设备是可以直接通信的;转发设备与主机 A 也是可以直接通信的。因此,我们只需在数据链路层之上,设计新的 网络层 ,专注于跨网通讯。跨网通信可以分解成若干次网内通信,而网内通信直接复用数据链路层能力即可!

采用分层设计思想后,网内通信与网间通信完全解耦。每个层都可以根据需要设计不同的协议,上下层协议可以自由组合,获得最大的灵活度。

网络层

为了解决 数据链路层 的局限性,需要引入新的一层,以及新的地址。新的一层为 网络层 ,新的地址就是 网络层地址 。在网络层转发数据的中间节点,称为 网络层路由 。网络层主要职责在于:实现 全球寻址 以及 数据路由

每台参与网络层通信的主机需要分配一个唯一的地址,这就是 网络层地址 。网络层地址按 网络拓扑 分配,保证一个组织内部的地址是连续的。例如,给某个公司分配地址段 123.58.173.x ,这些地址只有最后一个数字是不同的。这样一来,一条转发配置便可为几百个地址服务。相应地,用于地址表规模也可下降若干数量级。

网络层传输单元称为 ( packet ),结构可参考数据链路层,包含 地址数据 以及 类型 等字段。网络层包承载在数据链路层帧之上,也就是说数据链路层帧的 数据负载 就是一个网络层包。

网络层路由维护 路由表 ,规定了目的地址与下一跳的对应关系。路由表看起来与数据链路层 MAC地址表 颇为相似,但更加高级:

  • 支持 地址段 ,一条记录配置某一段地址的下一跳,有效降低路由表规模;
  • 支持 高级学习算法 ,例如选择一条跳数最少的路径;

以下面的拓扑为例,假设主机 ① 通过网络层包向主机 A 发送数据 hello ,步骤大致如下:

NetworkLayer - LayeringPackage

  1. 主机 ① 将数据封装到一个网络包中,包源地址是主机 ① 的网络层地址,目的地址是主机 A 的网络层地址;该网络包需要先发给转发设备 R,由它转发给目标主机 A

  2. 主机 ① 可以通过链路层协议与转发设备 R 通信,因此只需将网络层包作为数据封装在链路层帧中发给R,帧源地址是主机 ① 的链路层地址,目的地址是转发设备R的链路层地址;

  3. 转发设备 R 收到该帧,从中取出网络层包,检查包目的地址知道该包需要转发给主机 A

  4. 转发设备 R 可以通过链路层协议与主机 A 通信,因此只需将网络层包作为数据封装在链路层帧中转发给 A,帧源地址是转发设备R 的链路层地址,目的地址是主机 A 的链路层地址;

  5. 主机 A 收到该帧,从中取出网络包,检查包源地址知道它是主机 ① 发来的,进而取出其中的数据;

那么,主机 ① 怎么知道发给 A 的网络层包要通过 R 来转发呢?答案就藏在路由表中,它正等着我们继续探索。

小菜学网络】系列文章首发于公众号【小菜学编程】,敬请关注:

【小菜学网络】系列文章首发于公众号【小菜学编程】,敬请关注: