@@ -6,4 +6,49 @@ icon: material/router-network
66
77!!! warning "本文编写中"
88
9- ## 路由表
9+ ## 路由表 {#routing-tables}
10+
11+ ** 路由** 是网络系统用来决定数据包去向的过程,主要由** 路由表** 来实现。
12+ 在 Linux 中,路由表存储在内核中,可以通过 ` ip route ` 命令查看当前的路由表:
13+
14+ ``` console
15+ $ ip route
16+ default via 192.0.2.1 dev eth0 src 192.0.2.100
17+ 192.0.2.0/24 dev eth0 src 192.0.2.100
18+ ```
19+
20+ 在以上示例中,第二行表示目标为 192.0.2.0/24 的地址发送到 eth0 设备的本地网络中,以源地址 192.0.2.100 进行通信(即本机地址);而其他所有流量(` default ` )都将发送给网关 192.0.2.1,由该网关决定进一步的去向。
21+
22+ Linux 的路由表数据结构为 Trie(前缀树),可以高效地进行** 最长前缀匹配** ,这也是 Linux 的基本路由规则[ ^ windows ] 。
23+ 在此基础上,` default ` 是 ` 0.0.0.0/0 ` (或 IPv6 ` ::/0 ` )的简写或别名,表示前缀长度为零的默认路由。
24+
25+ [ ^ windows ] : Windows 系统的路由表使用线性表结构,匹配时会按优先级顺序遍历所有规则,效率较低,且不符合最长前缀匹配原则。
26+
27+ ## ` ip route ` 命令 {#iproute2}
28+
29+ ` ip route ` 命令是管理路由表的主要工具,其默认操作是显示当前的路由表,等价于 ` ip route show table main ` 。
30+ 如果要增加或替换一条路由规则,可以使用 ` ip route add ` 或 ` ip route replace ` 命令,例如:
31+
32+ ``` shell
33+ ip route add 198.51.100.0/24 via 192.0.2.2 dev eth0
34+ ```
35+
36+ 此后,Linux 就会将目标地址为 198.51.100.0/24 的数据包发送给网关 192.0.2.2。
37+
38+ 对于本地网络的路由规则,可以省略 ` via ` 部分[ ^ via-zero ] ,例如:
39+
40+ ``` shell
41+ ip route add 192.0.2.0/24 dev eth0
42+ ```
43+
44+ 此后,Linux 就会将目标地址为 192.0.2.0/24 的数据包发送到 eth0 接口的本地网络中,不经过网关。
45+
46+ [ ^ via-zero ] : 事实上,若省略了 ` via ` 部分,` ip ` 命令向内核传递路由规则时会将其设置为 ` 0.0.0.0 ` (IPv4)或 ` :: ` (IPv6),这是系统接口的实现细节。如果你明确指定 ` via 0.0.0.0 ` ,会得到相同的效果。
47+
48+ 对于没有链路层的接口(如 WireGuard 接口、其他三层隧道接口和 TUN 设备等),` via ` 部分没有意义,即使指定了也不会产生任何影响。
49+
50+ ## 策略路由 {#policy-based-routing}
51+
52+ 单一的路由表只能根据数据包的目的地址来决定去向,无法满足更复杂的路由需求。
53+ 一个典型的场景是,同时接入多个网络的服务器在处理网络连接时,需要「源进源出」的路由方式才能确保与客户端正常通信。
54+ ** 策略路由** (Policy-based Routing,PBR)通过引入多个路由表和(不仅仅根据目的地址的)路由规则,实现了更灵活的路由控制。
0 commit comments