bc's club

This is Bc's club

计算机网络:自顶向下方法 - Day 9 | 网络层概述、数据平面与路由器工作原理

Day 9 — 网络层概述、数据平面与路由器工作原理#

前情回顾:Day 7 我们聊了 UDP 和可靠数据传输原理,Day 8 深入 TCP 的拥塞控制。传输层的故事暂时告一段落——但你会发现,不管 TCP 还是 UDP,它们都建立在一个假设之上:网络层会把数据从源送到目的。这个”网络层”到底怎么送的?今天我们终于要打开这个黑盒,看看互联网的”快递分拣中心”——路由器——是怎么工作的。


一、网络层是个什么层?#

1.1 从传输层到网络层#

回顾一下我们的五层模型:

1
2
3
4
5
应用层    ← HTTP, DNS, SMTP...
传输层 ← TCP, UDP
★网络层★ ← IP, 路由协议
链路层 ← Ethernet, WiFi
物理层 ← 光、电、无线信号

传输层的 TCP/UDP 负责端到端的通信(进程到进程),而网络层负责主机到主机的通信。你可以理解为:

  • 传输层:你给快递员打电话说”请把这个包裹送到张三家,交给张三本人”(进程到进程,端口寻址)
  • 网络层:快递分拣中心看地址,决定这个包裹要从北京发到上海(主机到主机,IP 寻址)

🎯 生活类比:传输层像是快递单上的收件人姓名和电话(具体到人),网络层像是收件地址里的城市和街道(具体到地方)。你写的快递单两层信息缺一不可,网络世界也一样。

1.2 网络层的两大功能#

网络层可以说是整个互联网最忙的一层,它有两个核心功能:

① 转发(Forwarding)——数据平面

当一个数据包到达路由器的某个输入端口,路由器要决定:这个包该从哪个输出端口送出去?这个决策是本地的、即时的,就在路由器内部完成。

② 路由(Routing)——控制平面

路由器们需要互相交流,搞清楚整个网络的拓扑结构,然后在每台路由器上建立起转发表(Forwarding Table),告诉转发逻辑”遇到去某个网络的包,应该从哪个端口送出去”。这个决策是全局的、慢速的,需要路由协议(如 OSPF、BGP)的参与。

对比项 转发(数据平面) 路由(控制平面)
时间尺度 纳秒级(每个包都要处理) 秒~分钟级(拓扑变化才更新)
作用范围 单个路由器内部 整个网络/自治系统
关键设备 路由器的硬件/软件 路由协议和算法
类比 快递员看地址分拣包裹 快递公司规划物流线路

🎯 生活类比:想象一个巨大的快递分拣中心。转发就是传送带上的包裹到了一个分叉口,工作人员看一眼邮编,推到对应的滑道里——这个动作每秒发生几百万次。路由则是公司的调度部门根据全国道路情况、新开的网点、拥堵的高速,定期更新一份”路由指南”发到每个分拣中心——这个动作可能一天才更新一次。

1.3 数据平面 vs 控制平面#

这是第 8 版书里特别强调的一个架构视角:

1
2
3
4
5
6
7
8
9
10
11
12
13
┌─────────────────────────────────────────┐
│ 网络层 │
│ │
│ ┌──────────────┐ ┌──────────────────┐ │
│ │ 数据平面 │ │ 控制平面 │ │
│ │ (Data Plane) │ │ (Control Plane) │ │
│ │ │ │ │ │
│ │ • 转发 │ │ • 路由算法 │ │
│ │ • 查表 │ │ • 路由协议 │ │
│ │ • 移交到输出 │ │ • 维护转发表 │ │
│ │ • 硬件实现 │ │ • 软件实现 │ │
│ └──────────────┘ └──────────────────┘ │
└─────────────────────────────────────────┘

数据平面是路由器的”肌肉”——快速、机械、每包执行。通常用硬件(ASIC、FPGA)实现,追求速度。

控制平面是路由器的”大脑”——思考、协商、更新。通常用软件实现,运行路由协议进程。

传统路由器把这两个功能合在一台设备里。但 SDN(Software-Defined Networking,软件定义网络)的革命性思想就是:把控制平面从路由器里抽出来,放到一个集中的控制器上。就像连锁快餐店把菜单决策权从每家门店收回总部——门店只管按菜单做菜(转发),总部负责研发新品和调整策略(路由)。

🔧 实战关联:你家跑 OpenWrt 的路由器就是一个完整的传统路由器。OpenWrt 里 ip route 显示的 routing table 就是控制平面维护的转发表,而路由器芯片内部的硬件转发芯片(如 MediaTek/Qualcomm 的 SoC)就是数据平面。当你跑 tc qdisc 做流量整形时,你其实是在数据平面上动手脚!


二、路由器的”解剖图”#

现在让我们打开路由器的外壳,看看里面长什么样。一个通用的路由器架构如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
       输入端口          交换结构          输出端口
┌────────┐ ┌─────────┐ ┌────────┐
线路 │ 物理层 │ │ │ │ 物理层 │ 线路
──────┤ 链路层 │─────▶│ 交换 │─────▶│ 链路层 ├──────
│ 网络层 │ │ 结构 │ │ 网络层 │
│(查找/ │ │ │ │(排队/ │
│ 转发) │ │ │ │ 调度) │
└────────┘ └─────────┘ └────────┘
│ │
▼ ▼
┌─────────────────────────────────────────┐
│ 路由处理器 │
│ (控制平面:路由协议、维护转发表) │
└─────────────────────────────────────────┘

路由器由四大组件构成:

  1. 输入端口(Input Ports)
  2. 交换结构(Switching Fabric)
  3. 输出端口(Output Ports)
  4. 路由处理器(Routing Processor)

我们逐一拆解。


三、输入端口:门口的”安检+导航员”#

3.1 输入端口的三层结构#

输入端口不止是一个”网线口”那么简单。它从物理层到网络层都有处理逻辑:

1
2
3
4
5
6
7
8
9
10
┌──────────────────────────────────┐
│ 物理层:终止物理链路 │
│ (光电信号 → 比特流) │
├──────────────────────────────────┤
│ 链路层:处理链路层协议 │
│ (如 Ethernet 帧的解封装) │
├──────────────────────────────────┤
│ 网络层:查找转发表,决定输出端口 │
│ (最长前缀匹配) │
└──────────────────────────────────┘

🎯 生活类比:输入端口就像公司大楼的前台。物理层是保安检查你的车有没有停对位置,链路层是前台确认你是不是从合作公司来的(链路层帧),网络层是前台查访客系统,决定你应该去几楼哪个会议室。

3.2 最长前缀匹配(Longest Prefix Matching)#

这是输入端口网络层的核心工作。转发表大概长这样:

目的网络前缀 输出接口 下一跳
11001000.10101010.00000000.00 接口0
11001000.10101010.10100000.00 接口1
11001000.10101010. 接口2
0.0.0.0/0(默认路由) 接口3 网关

当一个目的 IP 为 192.168.160.111001000.10101010.10100000.00000001)的包到达时,路由器需要在表里找最匹配的那一条。

  • 第一条 ...00000000.00/26 不匹配
  • 第二条 ...10100000.00/26 匹配!26 位前缀
  • 第三条 192.168.x.x/16 也匹配,但只有 16 位前缀

最长前缀匹配的规则是:选择匹配位数最多的那条——这里是第二条(26 位 > 16 位),从接口 1 输出。

🎯 生活类比:你寄快递写的地址是”北京市海淀区中关村大街1号”。快递分拣中心有一张表:

  • “北京市” → 发到北京转运中心
  • “北京市海淀区” → 发到海淀分部
  • “北京市海淀区中关村” → 发到中关村网点

三个都匹配,但当然选最精确的那个——最长的前缀匹配!

3.3 为什么要在输入端口做查找?#

你可能会问:为什么不把包直接送给路由处理器(CPU)去查表?因为太慢了

现代骨干路由器每个端口要处理 100Gbps 甚至 400Gbps 的流量。每个包的转发决策必须在纳秒级完成。如果每个包都走 CPU 查表,CPU 早就累趴了。所以输入端口上有专用的硬件查找引擎(TCAM,三态内容寻址存储器),一个时钟周期就能完成查找。

🔧 实战关联:在 OpenWrt 上跑 ip route get 8.8.8.8,你看到的就是路由查找的结果。你的家用路由器虽然速度不比骨干路由器,但原理一样——每个到达的包都要走一遍这个查找过程。当你用 frp 做内网穿透时,frp 服务器收到的数据包要转发到你内网的服务,这个过程中经过的每一个路由器都在做最长前缀匹配。


四、交换结构:路由器的”十字路口”#

查完表,知道了包该从哪个输出端口出去,接下来就是把包从输入端口送到输出端口。这个”搬运”动作就是交换结构要干的事。

有三种经典的交换方式:

4.1 经内存交换(Switching via Memory)#

最早的路由器其实就是一台普通计算机,用 CPU 来”交换”:输入端口把包写入内存,CPU 再从内存读出来写到输出端口。

1
2
输入端口 ──▶ [ 内存 ] ──▶ 输出端口
(CPU 介入)

优点:简单,用现成的硬件就行。

缺点:慢!每个包要两次内存访问(读+写),而且 CPU 要介入。如果内存带宽是 B,那最大吞吐量是 B/2。而且 CPU 处理速度有限。

🎯 生活类比:就像你一个人在家里搬东西。左手从门口拿进来放桌上(写内存),右手再从桌上拿到后门口递出去(读内存)。一个人两手交替,速度可想而知。

4.2 总线交换(Switching via Bus)#

输入端口把包放到一条共享总线上,输出端口从总线上取走。

1
2
3
输入端口0 ──┐
输入端口1 ──┼──[ 共享总线 ]──┬── 输出端口0
输入端口2 ──┘ └── 输出端口1

优点:比内存交换快,不需要 CPU 介入。

缺点:总线是共享的!同一时刻只能有一个端口往总线上放数据。如果 N 个输入端口同时有包要送,只有一个能成功,其他要等。总线带宽成了瓶颈。

🎯 生活类比:公司只有一部电梯。每层楼的人都要用它下楼。同一时间只能载一批人,大家只能排队等。楼层多了就堵成一锅粥。

大多数家用路由器(包括 OpenWrt 设备)用的就是总线交换架构。因为家用场景流量不大,总线够用了。但在骨干网,总线交换就力不从心了。

4.3 互联网络交换(Switching via Interconnection Network)#

这是高性能路由器用的方案。用一个多级的交叉开关矩阵(Crossbar Switch),让多个输入-输出对同时交换数据。

1
2
3
4
5
6
7
          输出0   输出1   输出2   输出3
输入0 ──[×]──[ ]──[×]──[ ]──
输入1 ──[ ]──[×]──[ ]──[ ]──
输入2 ──[ ]──[ ]──[ ]──[×]──
输入3 ──[×]──[ ]──[ ]──[ ]──

× = 交叉点闭合(连通)

如果输入端口0要送到输出端口0,同时输入端口1要送到输出端口1,这两个交换可以同时进行,互不干扰。只有当两个输入端口要送到同一个输出端口时才会冲突。

优点:可以并行交换,吞吐量高,是现代骨干路由器的标配。

缺点:复杂、贵、功耗大。N×N 的 crossbar 需要 N² 个交叉点。

🎯 生活类比:从”一部电梯”升级到了”立交桥”。每条路都有自己的匝道,想去哪直接走对应的匝道,互不干扰。只有当两辆车想去同一个出口时,才需要排队。

4.4 交换结构的性能瓶颈#

无论哪种交换方式,当多个输入端口的包都想去同一个输出端口时,就会出现拥塞(HOL Blocking,Head-of-Line Blocking)。排在队头的包如果因为输出端口冲突而被阻塞,后面即使目的地是空闲端口的包也出不去——这就是队头阻塞问题。

想象你在超市收银台排队。你前面的大哥在找零钱(输出端口忙),你后面的小姐姐其实只是想退个货(另一个收银台空闲),但她排在你后面,只能等你——这就是队头阻塞。


五、输出端口:出门前的”排队等候区”#

5.1 输出端口的结构#

输出端口是包离开路由器前的最后一站:

1
2
3
4
5
6
7
8
9
10
┌──────────────────────────────────┐
│ 网络层:排队管理 + 调度 │
│ (哪个包先发?要不要丢包?) │
├──────────────────────────────────┤
│ 链路层:封装链路层帧 │
│ (加 Ethernet 头) │
├──────────────────────────────────┤
│ 物理层:发送到链路 │
│ (比特流 → 信号) │
└──────────────────────────────────┘

5.2 为什么要排队?#

排队的根本原因:到达速率 > 输出链路的发送速率

想象一个水槽。进水管的水流(到达的包)大于出水管的水流(输出链路带宽),水就会在槽里积攒。这就是排队。

1
2
3
4
5
6
       到达的包                    输出链路
┌──┐ ┌──┐ ┌──┐ ↓
──────▶│ │ │ │ │ │──────────▶ (100 Mbps)
│ │ │ │ │ │
└──┘ └──┘ └──┘
输出队列(缓存)

当队列满了,新来的包就只能被丢弃(Drop)或者挤掉已有的包(如果用了 AQM 主动队列管理)。

5.3 排队场景#

考虑两种排队场景:

场景一:输入排队

当交换结构来不及处理所有输入端口的包时,包在输入端口排队。前面提到的 HOL 队头阻塞就是输入排队的主要问题。

场景二:输出排队

当多个输入端口的包同时到达同一个输出端口时(交换结构足够快,但输出链路只有一条),包在输出端口排队。

实际路由器中,输出排队更常见,因为现代 crossbar 交换结构速度已经足够快,瓶颈通常在输出链路带宽上。

5.4 队列管理策略#

队列满了怎么办?有几种策略:

① 尾丢弃(Tail Drop,FIFO/DropTail)

最简单的策略:队列满了,新来的包直接丢弃。

1
2
队列状态:[包A][包B][包C][包D][包E] ← 满了!
新包F到达:💀 丢弃

缺点:会导致”全局同步”问题——TCP 流同时感知到丢包,同时降低发送速率,然后同时增大,导致网络流量呈锯齿状波动。

② 随机早期检测(RED, Random Early Detection)

在队列还没满的时候就开始以一定概率随机丢包,给 TCP 发送方”温柔”的信号:”快了快了,悠着点”。

1
2
3
队列长度 < min_threshold → 不丢包
min_threshold < 队列长度 < max_threshold → 以概率 p 丢包
队列长度 > max_threshold → 丢包

RED 的聪明之处在于:在崩溃之前就发预警,而不是等到队列满了才暴力丢包。

🎯 生活类比:尾丢弃就像高速收费站在车已经堵了一公里后才关闭入口。RED 则是在车排队到 200 米时就放一块”前方拥堵,建议绕行”的牌子,让一部分车主动分流。

③ 公平排队(Fair Queuing)

不同流轮流发送,避免一个贪婪的流量霸占整个队列。

🎯 生活类比:银行窗口排队,每个人限办 3 分钟,时间到了下一位。不会因为前面有个大哥办 50 张银行卡的复杂业务就让你等一下午。

5.5 调度策略(Scheduling)#

当输出端口有多个包排队时,谁先走?这就是调度器要回答的问题。

调度策略 规则 特点
FIFO(先来先服务) 按到达顺序发送 最简单,但无法区分优先级
优先级排队 高优先级先发 可能导致低优先级饿死
加权公平排队(WFQ) 按权重分配带宽 各流公平,可保证最低带宽
缺口轮转(Round Robin) 轮流给每个流发送机会 简单的公平

🔧 实战关联:OpenWrt 的 SQM(Smart Queue Management)就是一个典型的输出端口队列管理 + 调度系统。当你在家开 Zoom 会议的同时下载大文件,SQM 通过 CAKE 或 fq_codel 算法,保证 Zoom 的包(低延迟需求)优先发送,而下载流量(吞吐量需求)排队等候。这背后就是今天讲的排队管理和调度策略!


六、把所有部件串起来:一个包的路由器之旅#

让我们追踪一个 IP 数据包穿过路由器的完整过程:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
1. 包从物理链路到达输入端口 X

2. 输入端口 X:
① 物理层:光电信号 → 比特流
② 链路层:解封装 Ethernet 帧,提取 IP 数据报
③ 网络层:用目的 IP 查转发表(最长前缀匹配)
→ 决定输出端口 Y

3. 交换结构:把包从输入端口 X 送到输出端口 Y
(如果用 crossbar,可能和其他交换并行进行)

4. 输出端口 Y:
① 网络层:包进入输出队列,等待调度
② 链路层:封装成 Ethernet 帧
③ 物理层:比特流 → 信号,发到链路上

5. 包继续它的旅程,到达下一个路由器,重复以上过程

🎯 完整类比:想象你是一封信。

  1. 邮递员把你从信箱里取出来(物理层接收)
  2. 分拣员检查信封上的地址(链路层解封装 + 网络层查表)
  3. 分拣员决定你该发往哪个城市的分拣中心(最长前缀匹配 → 输出端口)
  4. 你被放到传送带上,送到了正确的发货口(交换结构)
  5. 发货口前面排了很多信,你在队列里等了一会儿(输出排队)
  6. 终于轮到你了,你被装到邮车里出发了(调度发送)
  7. 到了下一个分拣中心,重复以上过程……

一封从北京寄到上海的信,中间可能经过 5-10 个分拣中心。一个从你的电脑发到 B 站服务器的数据包,中间通常也要经过 5-15 台路由器。每经过一台路由器,就叫一跳(hop)。


七、实战分析:你家路由器的一天#

7.1 OpenWrt 路由器 = 小型路由器#

你家里的 OpenWrt 路由器就是一个麻雀虽小五脏俱全的路由器:

1
2
3
4
5
# 查看路由表(控制平面的产物)
root@openwrt:~# ip route show
default via 192.168.1.1 dev eth0 # 默认路由
10.0.0.0/24 dev br-lan proto kernel # 局域网
192.168.1.0/24 dev eth0 proto kernel # WAN 口
  • 输入端口:WAN 口(eth0)和 LAN 口(br-lan,其实是一个 bridge)
  • 交换结构:多数用总线交换(SoC 集成)
  • 输出端口:同上,WAN/LAN 口复用
  • 路由处理器:路由器的 CPU(可能就是一个小小的 ARM 核)
  • 转发表ip route 看到的路由表

7.2 frp 数据转发的路由过程#

当你用 frp 做内网穿透时,数据包经过了哪些路由器?

1
2
3
4
5
你的服务器(内网 192.168.1.100)
→ 家里路由器 (OpenWrt, 192.168.1.1)
→ 光猫 (桥接/路由模式)
→ 运营商网络 (经过多台路由器)
→ frp 服务器 (公网 IP, 如 1.2.3.4)

每一跳,路由器都在做同样的事:

  1. 收到包,看目的 IP
  2. 最长前缀匹配,决定下一跳
  3. 通过交换结构送到对应端口
  4. 从输出端口发出去

frp 服务器收到包后,解封装,看到的是你内网服务的应用层数据(比如 HTTP 请求),然后再转发给目标服务。从网络层的角度,frp 服务器只是路径上的一个中间节点,但它同时也是一个应用层代理——既走路由器的活(网络层转发,不过是通过应用层代理实现的),又做应用层的事。

💡 有趣观察:frp 本质上是在应用层模拟了网络层的转发功能。真正的路由器在 IP 层转发,而 frp 在 TCP/应用层转发。这就像快递公司(IP 路由)和跑腿小哥(frp 代理)都能帮你送东西,但快递公司走的是自动化分拣流水线,跑腿小哥走的是”人肉转交”——速度和效率不可同日耳语,但跑腿小哥能送的”东西”更灵活。


八、路由器的性能指标#

8.1 吞吐量#

路由器的吞吐量是指单位时间内能处理的数据量。这取决于三个环节中最慢的那个:

  1. 输入端口处理速度
  2. 交换结构带宽
  3. 输出端口发送速度

木桶效应——哪个环节最慢,整个路由器的吞吐量就被限制在哪里。

8.2 延迟#

一个包穿过路由器的时间包括:

  • 处理延迟:查表、检查首部(通常微秒级)
  • 排队延迟:在输出队列等待的时间(取决于拥塞程度,从 0 到毫秒级不等)
  • 交换延迟:通过交换结构的时间(通常纳秒级)

注意,路由器的延迟主要来自排队。如果你家的网速测试显示延迟很高,很多时候不是路由器处理慢,而是队列太长了!

8.3 丢包率#

当队列满了,包被丢弃。丢包率是衡量路由器拥塞程度的重要指标。TCP 会根据丢包调整发送速率——这就是 Day 8 讲的 TCP 拥塞控制的基础。现在你知道了:TCP 感知到的”丢包”,本质上很多时候就是路由器输出端口队列满了之后的尾丢弃(或 RED 丢弃)。

💡 恍然大悟时刻:TCP 拥塞控制和路由器排队管理其实是一个闭环系统。路由器丢包 → TCP 减速 → 路由器队列变短 → 不再丢包 → TCP 加速 → 路由器队列又变长 → 又开始丢包……如此循环。理解了这个循环,你就理解了互联网流量自我调节的核心机制。


关键知识点回顾#

让我们用一张表总结今天的内容:

概念 要点
网络层两大功能 转发(数据平面,本地快速决策)+ 路由(控制平面,全局拓扑计算)
数据平面 vs 控制平面 数据平面硬件实现每包转发,控制平面软件实现路由协议;SDN 将二者分离
路由器四大组件 输入端口、交换结构、输出端口、路由处理器
输入端口核心 最长前缀匹配查找,决定输出端口
交换方式 内存交换(慢)、总线交换(中等)、互联网络/crossbar(快)
输出端口核心 排队管理(DropTail、RED)+ 调度策略(FIFO、优先级、WFQ)
排队位置 主要在输出端口排队(现代交换结构足够快)
HOL 阻塞 输入排队时的队头阻塞问题
队列管理策略 尾丢弃(简单但导致全局同步)、RED(主动预警)、公平排队
TCP 与队列的闭环 路由器丢包 → TCP 减速 → 队列缩短 → TCP 加速 → 循环

一句话总结:路由器就是一个高性能的”快递分拣中心”——输入端口看地址(最长前缀匹配),交换结构搬运包裹(crossbar 并行交换),输出端口排队发货(排队管理+调度),路由处理器在后台规划路线(路由协议)。


Day 10 预告#

今天我们了解了路由器的硬件架构和工作原理,但有一个关键的东西还没深入:路由器查的那张转发表是怎么来的? 路由器怎么知道去往某个网络该走哪条路?这涉及到:

  • IP 协议详解:IPv4 数据报格式、分片与重组
  • IPv6:为什么需要 IPv6?IPv4 和 IPv6 有什么区别?
  • DHCP:你的电脑是怎么自动获得 IP 地址的?
  • NAT:你家一个公网 IP,多台设备怎么上网的?
  • 路由算法:链路状态(LS)和距离矢量(DV)算法是怎么算出最短路径的?
  • OSPF 与 BGP:互联网的两 大路由协议

Day 10,我们将深入 IP 协议的细节,看看那个 192.168.1.1 背后的故事。咱们不见不散!


📖 读书进度:《计算机网络:自顶向下方法》第 8 版 第 4 章(4.1-4.2 节)

下期见 👋