图 30-1 给出了网络协议栈中路由子系统的位置(灰色框)。

30.1 路由器(Routers),路由(Routes),路由表(Routing Tables)
路由器:
- 为一种配备了多个网络接口卡(NIC),并利用其对网络的认知来正确转发入站流量的网络设备。
- 路由器需要更多关于如何访问远程网络的信息,可能需要运行路由协议(routing protocol)。
路由表:
- 判断一个入站数据包 (ingress packet) 是发往本地主机、还是需要被转发所需的信息,以及在后一种情况下正确转发数据包所需的信息,都存储在一个名为转发信息库(Forwarding Information Base, FIB)的数据库中。
- 每台主机都会维护一张路由表,在需要处理网络流量时(无论是发送还是接收)都会查询该表。
图 30-2 展示了一个简单场景:一个局域网(LAN)内的主机都配置在 10.0.0.0/24 子网中,局域网主机通过一台名为 RT 的路由器访问互联网。

默认网关(default gateway):
- 主机被配置为使用默认网关来访问所有非本地地址。
- 在图 30‑2 中,发往
10.0.0.0/24网络之外任何主机的流量(用0.0.0.0/0表示)都会被发送到地址为10.0.0.1的网关。
对于 10.0.0.0/24 网段内的主机,则会使用第六部分介绍的邻居子系统。
路由表只不过是路由项的集合。一条路由是一组参数,用于存储向指定目的地转发流量所需的信息。
定义一条路由所需的最小参数集:
目的网络(Destination network)
- 路由表用于将流量转发至其目的地。路由查找过程中最重要的字段。
- 图 30‑2 展示了包含两条路由的路由表:一条通往本地子网 10.0.0.0/24,另一条通往其他所有网络。后者被称为默认路由(default route),在路由表中记为全零网络(参见 “默认网关选择” 一节)。
出接口设备 (Egress device)
- 这是匹配该路由的数据包应该被发送出去的网络设备。
- 例如,发往地址 10.0.0.100 的数据包会从 eth0 接口发出。
下一跳网关(Next hop gateway)
- 当目的网络与本地主机并非直连时,就需要依靠其他路由器来到达该网络。
- 例如,图 30‑2 中的主机需要依靠路由器 RT,才能访问 10.0.0.0/24 子网以外的任何主机。下一跳网关就是该路由器的地址。
30.1.1 非路由型多宿主主机 (Nonrouting Multihomed Hosts)
非路由型主机(尤其是服务器)也可以拥有多个网卡,而不执行任何数据包转发。一台大型服务器配备多个网卡通常出于以下一个或多个原因:
高可用性 (High availability)
- 如果一个接口故障或断开,流量可以由第二个接口接管(该接口也可以连接到不同的局域网)。
更强的路由能力
服务器可以配置不只一条默认路由。例如,出于特定目的(如方便系统日志记录),它可以通过静态路由或多块网卡访问特定的主机或子网。
图 30‑3 展示了一个示例:一台多宿主主机通过第二块网卡连接到另一个局域网,从而访问主机 A。

链路聚合(Channeling)
- 可以将多个接口绑定在一起,使它们在路由子系统看来就像单个接口一样,提高指定连接的总带宽
30.1.2 路由配置的种类
图 30‑4 展示了三种路由子系统设计中你需要理解的配置。这些配置中的路由器命名为 Rn。来看一下这些场景的特别之处:
(a) 这是最常见的情况:不同的接口配置在不同的子网上,每个子网对应不同的局域网。
(b) 路由器 RT 有两个接口连接到同一个局域网(显示在路由器下方),但这两个接口被配置在两个不同的子网中。
(c) 路由器 RT 在 10.0.2.0/24 和 10.0.3.0/24 两个子网中仍各拥有一个地址,但这两个地址都配置在同一块网卡上。这可以通过两种方式实现:使用 iproute2 提供的多 IP 地址功能,或者创建传统风格的别名接口。

(b) 和 (c) 这两种情况并不常见,但完全合法,也体现了 Linux 与 IP 协议的灵活性。
局域网(LAN)是一个广播域。属于同一个二层广播域的所有主机都会收到彼此的广播报文。
在情况 (b) 和 (c) 中,如果路由器 RT(或 10.0.2.0/24 网段中的任何其他主机)向广播地址 10.0.2.255 发送数据包,10.0.3.0/24 子网的所有主机都会收到(尽管它们会丢弃),当然也包括路由器 RT 本身。
入接口与出接口不一定不同,尽管通常是不同的。转发一般是在一个接口接收数据包,再从另一个接口发送出去。但在情况 (c) 中,路由器 RT 可以在同一个网卡、同一个局域网上,从一个子网接收数据包,再转发到另一个子网。
30.1.3 本部分将解答的问题
此时你可能会产生一些普遍性的疑问,例如:
- 如果路由器需要转发数据包,内核如何知道转发功能已启用
- 路由是全局开启,还是在接口对之间开启
- 是否存在能显著影响 Linux 路由器性能的调优参数
- 路由表的语法是什么
或是更具体的问题,例如:
- 查找转发数据包所需信息时使用的是什么算法
- 路由表是否仅用于转发流量,还是有其他用途
- 内核如何与运行在用户空间的动态路由协议(dynamic routing protocol)守护进程交互
30.2 路由的核心要素
互联网服务提供商(ISP)
- 提供互联网接入服务的公司或机构。
转发信息库(FIB, Forwarding Information Base)
- 其实就是路由表
对称路由与非对称路由
- 对称路由:从主机A到主机B的路径,与从主机B返回主机A的路径是相同的
- 非对称路由:在复杂网络结构中,往返路径可能不同
度量值(Metrics)
- 可以在路由上配置的可选参数。
- 当使用
iproute2配置路由时,可以指定名为度量值的附加参数,如“路由的核心要素”一节中所定义。其中一个参数——路径最大传输单元(Path MTU),已在第18章介绍。 - 其他参数会被传输控制协议(TCP) 用作内部变量的初始值,这些变量后续可由协议自行调整。它们的含义与用法可参考任何一本TCP相关书籍:
- 窗口(Window)
- 往返时间(Round trip)
- 往返时间波动(Round-trip time variation)
- 慢启动阈值(Slow-start threshold)
- 拥塞窗口(Congestion window)
- 宣告的最大报文段大小(Maximum segment size to advertise)
- 重排序(Reordering)
Realm
- 一个数值表示的域标识
地址分类


可路由地址与不可路由地址
不可路由地址
- 保留给局域网 (LAN) 内部使用
- 任何人都可以配置不可路由地址,大多数用户的设备在路由器后方所使用的正是这类地址。
- 不可路由地址不能用于提供互联网服务,因为它们不具备全球唯一性,而且互联网路由器也不会转发去往这些地址的流量。
可路由地址
- 必须由统一的管理机构分配,并且在全球范围内是唯一的。
127.0.0.0/8 子网
- 一段特殊的地址范围,其作用范围 (scope) 仅限于配置这些地址的本机。
- 任何以这类地址作为源地址或目的地址的数据包,都无法离开本机。

图 30-5 中
- 两个使用相同的不可路由 IP 子网 10.0.1.0/24
- 可路由的子网 100.0.1.0/24
- 10.0.1.0/24 子网内的任何一个主机要与子网外部的主机通信,路由器必须使用 NAT 来隐藏本地不可路由的子网
- 每台主机都配置有默认地址 127.0.0.1
- 三个路由器与各自 ISP 的接口上都配置了 ISP 分配的可路由的 IP 地址

30.2.1 Scope
在 Linux 中,
路由的 scope 表示到目的网络的距离
IP 地址的 scope 表示该地址在离本地主机多远的范围内可见,在一定程度上也能反映出该地址的拥有者与本地主机的距离。
IP 地址的 scope:
主机 (Host)
- 当一个地址只能用于主机自身的内部通信时
- 如:回环地址 127.0.0.1
链路 (Link)
- 当一个地址只在一个局域网内有意义且只在局域网内使用时
- 如:子网的广播地址
全域 (Universe)
- 当一个地址可以在任何地方使用时
广播地址和回环地址由内核来自动设定合适的 scope 值。
当同样三个 scope 用于路由时表示什么:
主机 (Host)
- 当一条路由指向本机上的目的地址时
链路 (Link)
- 当一条路由指向本地局域网内的目的地址时
全域 (Universe)
- 当一条路由指向跨一跳以上的地址时
30.2.1.1 scope 的使用
在 Linux 中,尽管管理员是在接口上配置 IP 地址,但这些地址属于主机本身,而不是接口。更多细节可参见第 28 章 “从多个接口响应” 一节。