Skip to content

交换机与路由器:两种转发机制 ​

标签
基本功/网络
字数
4567 字
阅读时间
19 分钟

网络设备按工作在哪一层分工。交换机看 MAC 地址,在一个广播域内搬帧;路由器看 IP 地址,在广播域之间搬包。

两者的差别落在动不动包上——交换机原样搬,路由器拆了重装。

1. 交换机与 MAC 表 ​

1.1 三个动作 ​

收帧
 ├─ ① 学习:把「源 MAC + 入端口」写进 MAC 表
 ├─ ② 查表:看目的 MAC,命中 → 只从对应端口发(单播转发)
 └─ ③ 泛洪:未命中 → 从除入端口外的所有端口发

学习靠源 MAC,转发靠目的 MAC——这个不对称是理解交换机的关键。一台交换机不需要任何配置,接上网线就能工作,靠的就是这个自学习机制。

MAC 表项有老化时间(通常 300 秒),老条目会被删除,所以设备换端口后网络能自己收敛。

1.2 三种转发模式 ​

模式读多少就开始转发延迟代价
存储转发(store-and-forward)收完整帧、校验 FCS大能丢弃坏帧
直通(cut-through)只读前 6 字节(目的 MAC)小会转发坏帧
无碎片(fragment-free)读满 64 字节(最小帧长)折中能过滤残帧

直通模式的适用边界:链路质量好、对延迟敏感的场景(如高性能计算集群)。链路上误码多时,坏帧被转发出去反而浪费下游带宽。

1.3 三条性质 ​

性质说明
不隔离广播域广播帧(FF:FF:FF:FF:FF:FF)泛洪到所有端口
隔离冲突域每个端口一个冲突域;全双工下冲突已消失
完全不改帧源/目的 MAC、TTL、校验和一个都不动

第三条的成因很直接——交换机不看 IP 首部,所以没有任何理由去改它。

1.4 环路要靠 STP ​

二层没有 TTL 这样的兜底机制。一条二层环路会让广播帧无限循环,几秒钟打满整个网络。这一个数字值得推一遍——

三台交换机两两相连(三角形),一台机器发出一个广播帧:

T=0   SW1 收到 → 从另外两个口各发一份 → SW2、SW3 各收到一份
T=1   SW2 收到 → 除入端口外泛洪 → 发回 SW1,同时发给 SW3
      SW3 收到 → 除入端口外泛洪 → 发回 SW1,同时发给 SW2
T=2   SW2 又收到一份(来自 SW3)→ 再泛洪
      SW3 又收到一份(来自 SW2)→ 再泛洪

T=1 那一行是关键:两台交换机各自收到的那份又被互相转发了一遍,于是每绕一圈帧数翻倍。二层帧里没有任何字段会随转发递减,所以它不会自己停:

绕圈数环上的帧数
12
24
101024
20一百多万

以交换机微秒级的转发速度,几秒内就能打满链路带宽与 CPU。这就是广播风暴。

同时还有两个连带后果:

后果机制
MAC 表震荡(MAC flapping)同一个源 MAC 从两个不同端口轮流进来,表项被反复改写,CPU 全花在写表上
重复帧同一个广播帧在环里绕,接收方收到多份

1.5 STP 怎么断环 ​

三代防环协议的完整细节(选举与定时器、RSTP 的提议-同意握手、MSTP 的多实例与 Region)在 13-STP、RSTP 与 MSTP,这一节只讲基础机制。

解法是 STP(Spanning Tree Protocol,IEEE 802.1D):所有交换机协商出一个共识——哪些端口可以转发,哪些必须闲着。

「闲着」不等于「断开」:

阻塞端口仍然做阻塞端口不做
收发 BPDU(协议报文)不转发用户数据帧
听拓扑变化不学习源 MAC 到 MAC 表

所以那条链路平时闲着,但心跳还在。活跃链路一断,它立刻接手——这就是冗余的意义。

四步选举 ​

步骤选什么判据
1根桥(全网一台)BID 最小
2根端口(每台非根交换机一个)到根桥的路径开销最小
3指定端口(每条链路一个)该链路上到根桥开销最小的一端
4落选的阻塞

BID(Bridge ID,8 字节) = 桥优先级(2 字节)+ 交换机 MAC(6 字节)。先比优先级,小的赢;相同再比 MAC。 优先级默认 32768,只能取 4096 的倍数(0、4096、8192…)。

路径开销按带宽折算并沿途累加:

链路带宽经典 STPRSTP
10 Mbps1002000000
100 Mbps19200000
1 Gbps420000
10 Gbps22000

所以「到根桥的开销」= 沿途各出端口开销之和。环里开销大的那条链路,会有一端被判为阻塞——这就是图里 SW3 ↔ SW2 那条的由来。

BPDU ​

上述信息靠 BPDU 传递,默认每 2 秒一次,发往链路协议专用组播地址 01:80:C2:00:00:00(交换机不会转发这类帧,只在本机处理)。

字段作用
根桥 ID发送方认为的根桥是谁
到根桥的路径开销从这里到根桥要花多少
发送方桥 ID / 端口 ID我是谁、从哪个口发的
消息寿命 / 最大寿命防止 BPDU 无限转发的计时字段

「发送方认为的根桥」是协议的精髓:每台交换机启动时都以为自己是根桥(BPDU 里填自己),收到别人的 BPDU 一比较——发现对方报的根桥更优就改认对方,并把更新后的信息往下游传。这个过程就是收敛。

根桥持续每 2 秒发一次;非根交换机收到后把自己的开销加上再往下传,所以从根桥往外,BPDU 里的开销递增。

端口状态与收敛时间 ​

经典 STP 的五个状态:

状态持续收 BPDU学 MAC转发数据
Disabled——否否否
Blocking——是否否
Listening15 秒是否否
Learning15 秒是是否
Forwarding——是是是

从阻塞到转发最少等 30 秒(15 + 15),全程通常 30~50 秒。

为什么要等:拓扑变化时新 BPDU 要一层层传到全网,传播本身需要时间。端口若立刻转发,在「有人还以为旧拓扑有效」的窗口里会形成临时环路。这 30 秒是用一个保守的等待窗口覆盖信息传播的最坏延迟。

这个数字在今天很难接受——插上网线等半分钟才通。这是 RSTP 出现的主要动机。

拓扑变化的通知 ​

链路断了,下游怎么告诉根桥?靠 TCN BPDU:

1. 发现变化的交换机 → 从根端口向上游发 TCN
2. 上游继续向上转发 → 一直到根桥
3. 根桥 → 回带 TCA 标志的 BPDU 确认
4. 根桥 → 向下游广播「拓扑变了」
5. 所有交换机把 MAC 表老化时间从 300 秒缩短到 15 秒

第 5 步是关键:拓扑变了,原有的「MAC → 端口」映射可能已失效,不清理就会继续往旧端口发。缩短老化时间让收敛更快。

三代协议 ​

协议标准状态数收敛关键改进
STP802.1D530~50 秒基础版本
RSTP802.1w3亚秒级提议 / 同意握手,断开即可切换
MSTP802.1s3亚秒级多实例,可做负载分担

RSTP 快在哪:把 Listening / Learning 合并成 Discarding,引入提议-同意(Proposal-Agreement)握手——上游发提议、下游同意,端口立刻转发,不等定时器。只有对端不回话时才退回老的等待模式。

MSTP 解决的是闲置问题:经典 STP 全网只有一棵树,所有 VLAN 共用同一条活跃路径,其余冗余链路全部闲置。MSTP 把多个 VLAN 映射到不同实例,每实例一棵独立的树:

实例 1(VLAN 1-10)  → 活跃路径走链路 A
实例 2(VLAN 11-20) → 活跃路径走链路 B

两条链路都在用,冗余链路从「闲置」变成「负载分担」。

代价与替代 ​

核心代价是「用闲置换无环」——为断环必须阻塞链路,而阻塞的就是白白闲置的带宽。

方案思路
MLAG / vPC把两台物理交换机当成一台逻辑设备,从根上不产生环,链路全部可用
TRILL / SPB用类似三层路由的方式做二层转发,支持多路径
VXLAN + EVPN数据中心主流:用 overlay 封装绕过二层,底层走三层等价多路径

数据中心现在基本不以 STP 为主力——要么 MLAG 消环,要么 VXLAN 绕开二层。STP 主要留在办公网与接入层这类对收敛不苛刻的场景。

三个最常见的坑 ​

现象成因处置
根桥不是核心交换机默认优先级全为 32768,于是比 MAC——MAC 小的当选,等于随机。一台接入层设备可能成为全网中心核心交换机显式配 priority 4096
插了台家用路由器全网卡顿它发 BPDU 参与选举,或不参与导致临时环路接入端口配 BPDU Guard(收到 BPDU 就关端口)
收敛慢、业务中断 30 秒以上还在跑经典 STP换 RSTP,终端口配 edge port 不参与选举
bash
# Linux bridge
cat /sys/class/net/br0/bridge/root_id   # 根桥 ID
bridge link show                        # 各端口状态

2. 路由器与路由表 ​

2.1 完整转发路径 ​

收到帧
  ├─ 目的 MAC 不是本机,也不是组播/广播 → 丢弃
  └─ 剥掉帧头,把 IP 包交给 IP 层
       ├─ 目的地址是本机 → 按 Protocol 字段交给上层协议
       └─ 需要转发
            ├─ TTL 减 1;减到 0 → 丢弃 + 回 ICMP Time Exceeded
            ├─ 查路由表(最长前缀匹配)
            │    ├─ 无命中 → 丢弃 + 回 ICMP Destination Unreachable
            │    └─ 命中 → 得到下一跳与出接口
            ├─ 包长 > 出接口 MTU?
            │    ├─ DF=0 → 分片
            │    └─ DF=1 → 丢弃 + 回 ICMP Fragmentation Needed
            ├─ 重算 IP 首部校验和(TTL 变了)
            ├─ 查 ARP 缓存拿下一跳的 MAC → 重新封装成帧
            └─ 从出接口发出

第 7、8 步是路由器的核心特征:

  • TTL 变了,首部校验和必须重算(TCP 的校验和不用改,因为它不覆盖 TTL);
  • 下一跳变了,帧头的目的 MAC 必须换。

所以同一个包穿过多个路由器时,MAC 地址逐跳改写,IP 地址端到端不变。

2.2 路由表的四个来源 ​

bash
$ ip route show
default via 10.0.0.1 dev eth0 proto dhcp metric 100     # 租约下发
10.1.0.0/16 via 10.0.0.2 dev eth0 proto static          # 手工配置
10.0.0.0/24 dev eth0 proto kernel scope link            # 内核按掩码自动算
172.16.0.0/16 via 10.0.0.3 dev eth0 proto ospf          # 动态路由协议

proto 字段是排查的钥匙——看到一条不符合预期的路由,先看这一列就知道该去哪改:

proto来源该去哪改
kernel配地址时按掩码自动生成改地址配置
static手工 ip route add改配置或脚本
dhcp租约下发(见 11-主机接入网络:DHCP 与地址配置)改 DHCP 服务器
ospf / bgp / isis动态协议学到的查协议邻居

2.3 三条性质 ​

性质说明
隔离广播域不转发广播帧,一个接口一个广播域
每跳改包TTL 减一、校验和重算、帧头 MAC 重写
查不到就丢回 ICMP Destination Unreachable,没有泛洪兜底

3. 逐项对比 ​

维度交换机路由器
工作层二层(链路层)三层(网络层)
转发表MAC 表路由表 / FIB
表的来源自学习(看源 MAC)直连 + 静态 + 动态协议 + DHCP
匹配方式精确匹配(48 位全等)最长前缀匹配
是否改包完全不动TTL、校验和、帧头 MAC 全改
隔离广播域不能能
查不到时泛洪丢包 + ICMP
环路防护STP(协议主动断环)TTL(自然兜底)
延迟量级微秒几十微秒到毫秒
端口成本低(芯片简单)高(要跑协议、存路由)

一句话分工:

交换机在一个广播域内用 MAC 地址搬帧,路由器在广播域之间用 IP 地址搬包。MAC 逐跳改写,IP 端到端不变。

广播域与冲突域 ​

两个概念的区分值得单独记:

设备隔离冲突域隔离广播域
集线器(Hub)否否
交换机是(每端口一个)否
路由器是是(每接口一个)
VLAN——是(一个 VLAN 一个广播域)

VLAN 的价值就在这张表里:它让一台交换机上划分出多个广播域,等价于「在一台设备里装了多台逻辑交换机」。跨 VLAN 通信必须经过三层——这是 VLAN 安全隔离的基础。

4. 为什么需要两种设备 ​

只用交换机只用路由器
广播域无限大,一台主机的广播打到全网每个网段都要一个接口,成本爆炸
无法跨越网段慢:每个包都要拆装

三层交换机 ​

折中产物:把路由功能做进交换芯片。

  • 第一个包走慢路径:CPU 查路由表、把结果装进硬件转发表;
  • 后续同一条流的包直接查硬件表,不再经过 CPU。

这叫「一次路由、多次交换」。数据中心里跨 VLAN 的流量基本都靠它——层二的速度、层三的功能。

代价是它通常不具备广域网接口,也跑不了完整的 BGP 表(FIB 表项受芯片容量限制)。

5. 现实中的设备是组合体 ​

「交换机」和「路由器」是逻辑角色,实际设备经常一身兼多职:

场景实际构成
家用路由器交换机 + 路由器 + NAT + DHCP 服务器,一个盒子
数据中心接入交换机三层交换机,兼做 VLAN 间路由
K8s 节点Linux bridge 当交换机、IP 转发当路由器,都在内核里
容器每个 netns 一套独立路由表,靠 veth 对接到 bridge

容器网络是这套模型的直接翻版:

容器 netns                    宿主机
  eth0 ←── veth 对 ──→ veth0 ┐
                              ├─ bridge(当交换机用,也有 MAC 表与自学习)
容器 B 的 veth ───────────────┘
                              └─ ip_forward=1(当路由器用)

Linux bridge 的行为与物理交换机几乎一致:MAC 表、自学习、泛洪、老化都有。net.ipv4.ip_forward=1 打开的就是「路由转发」这个角色。

云厂商的 VPC 也是同一套抽象:子网 = 广播域,路由表 = 三层路由,安全组作用在两边。

6. 排查时按哪张表找 ​

三个层次的「转发失败」对应三种完全不同的现象,按这个顺序查:

顺序查什么命令失败现象
1路由表ip route get <目标>Network is unreachable / No route to host
2邻居表ip neigh show路由有但下一跳解析不出来
3交换机 MAC 表交换机管理界面链路层泛洪、丢包

三类典型症状 ​

症状指向依据
同网段通、跨网段不通路由问题默认路由缺失或网关配错
路由有、网关 ping 不通ARP 问题ip neigh 里网关是 FAILED
时通时不通、广播量大交换机问题MAC 表被打满,或者存在二层环路
跨 VLAN 不通三层问题没配 VLAN 间路由(SVI 或单臂路由)

一个直接的判据:ping 不通时先看它是「立刻报错」还是「卡住超时」。

  • 立刻报错(Network is unreachable)→ 本机路由表就没有可用条目,问题在自己;
  • 卡住超时 → 包发出去了但没回来,问题在中间或对端。

这个区分能把排查范围立刻砍掉一半。

相关 ​

参考 ​

IEEE 802.1D 与 802.1Q 是付费标准,本篇的 STP 与 VLAN 描述对照公开资料;Linux bridge 与 ip_forward 的行为来自内核文档,未逐条对应到单一规范。

贡献者 ​

文件历史 ​