3、L2交换基础:MAC地址表学习、老化机制、泛洪与转发决策

各位同学,今天我们来聊聊L2交换的核心。说白了,就是交换机怎么知道要把数据包扔给谁。

我刚开始做路由芯片那会儿,总觉得L2交换很简单——不就是查个MAC表嘛。后来在项目中踩过几次坑,才发现这里面的门道比想象中深得多。你想想看,一个万兆端口,每秒要处理上千万个包,MAC表的学习、老化、查找,每一步都不能掉链子。

3.1 MAC地址表学习:交换机的大脑记忆

交换机的MAC地址表,我习惯叫它「转发表」。它记录着每个MAC地址从哪个端口学来的。嗯,这里要注意,学习过程其实是被动的——交换机不会主动去问「你是谁」,而是从收到的数据帧里偷看源MAC。

具体流程是这样的:

  1. 端口收到一个帧,先看源MAC
  2. 查表,看这个MAC有没有记录
  3. 如果没有,就新建一条表项:MAC + 端口号 + 时间戳
  4. 如果有,就更新时间戳(这叫「刷新」)

核心要点:MAC学习只关心源MAC,不关心目的MAC。目的MAC是转发时用的。

我在项目中遇到过一个问题:某个端口突然收到大量源MAC为全0的帧。你猜怎么着?芯片直接把表项写成了0:0:0:0:0:0,导致后续所有查表都命中这条垃圾记录。后来我们在学习逻辑里加了源MAC有效性检查——全0、广播MAC、组播MAC都不学。

3.2 MAC表老化机制:该忘就忘

为什么要老化?很简单,设备会移动,会关机。如果表项永远不删,交换机迟早撑爆。

我建议把老化机制理解成一个「倒计时器」:

  • 每学到一条MAC,给它一个初始寿命(比如300秒)
  • 每次收到这个源MAC的帧,重置计时器
  • 计时器归零,删除表项

实际芯片里,老化扫描是个麻烦事。你想想看,一张表可能有几万条记录,总不能每秒都去遍历一遍吧?

工程小技巧:很多芯片用「时间轮」算法。把表项按时间戳分组,每次只检查一个组。这样扫描开销是常数级的,不会随着表项数量增长而爆炸。

我曾经在调试一款交换芯片时,发现老化时间设得太短(30秒)。结果呢?设备稍微发几个包慢一点,表项就被删了,然后又要重新学习,导致频繁泛洪。嗯,后来我们把默认老化时间改成了300秒,问题就解决了。

3.3 泛洪与转发决策:查表的两条路

收到一个帧,查目的MAC,结果只有两种:

查表结果 动作 原因
命中 单播转发 知道目标在哪个端口
未命中 泛洪 不知道目标在哪,广播出去

泛洪,说白了就是「我不知道该给谁,那就所有人都给一份」。但注意,泛洪不是无脑广播——它只泛洪到同一个VLAN内的所有端口(除了接收端口)。

这里有个坑:广播帧和未知单播帧都会泛洪。但广播帧是目的MAC为FF:FF:FF:FF:FF:FF,而未知单播帧是查表没找到。两者在转发逻辑上走的是同一条路径,但处理优先级不同。我建议在芯片设计时,给广播帧更高的优先级——因为ARP请求这类关键协议都靠广播。

避坑指南:我曾经遇到一个案例,某个端口疯狂泛洪,导致整个交换机的CPU利用率飙升。查了半天,发现是MAC表被恶意填满了(MAC泛洪攻击)。新来的未知单播帧全部泛洪,把带宽吃光了。解决方案?端口限速 + MAC表数量限制。

3.4 转发决策的完整流程

把上面三个机制串起来,一个帧的处理流程是这样的:

  1. 端口收到帧,提取源MAC和目的MAC
  2. 源MAC学习:查表,更新或新建表项
  3. 目的MAC查表:
    • 如果命中,查端口号,单播转发
    • 如果未命中,标记为泛洪
  4. 如果是广播/组播帧,直接泛洪
  5. 老化线程定期扫描,删除过期表项

你可能会问:学习和转发谁先谁后?我习惯先学习再转发。为什么?因为如果先转发再学习,这个帧的源MAC信息就浪费了——下一个帧还得重新学。但有些芯片为了流水线效率,会把学习和转发并行做,这需要额外的硬件资源。

3.5 芯片实现中的关键点

在路由芯片里,L2交换通常由专门的「MAC学习引擎」和「转发查找引擎」两个模块完成。我个人习惯把MAC表放在SRAM里,用哈希表实现。哈希冲突怎么办?用链地址法,但要注意链表深度不能太深——否则查表延迟会抖动。

还有一个容易被忽略的点:MAC表项的优先级。静态配置的MAC(比如给服务器绑定的)应该比动态学习的优先级高。老化时,静态表项不能被删除。我在芯片里加了一个「静态标志位」,老化扫描时直接跳过。

总结一下:L2交换的核心就三件事——学、老、转。学要快,老要准,转要稳。任何一个环节出问题,整个交换机的性能都会崩。

3.6 知识体系图:L2交换核心逻辑

下面这张图展示了MAC地址表学习、老化、泛洪与转发决策的完整流程。我建议你把它打印出来贴在工位上。

L2交换核心逻辑流程图 端口收到数据帧 提取源MAC + 目的MAC 源MAC学习(查表/更新) 目的MAC查表(转发决策) 老化计时器重置/新建 命中? 单播 泛洪 帧从指定端口发出

这张图里,左侧是学习路径,右侧是转发路径。两条路径并行执行,互不干扰。老化机制在后台默默运行,定期清理过期表项。

个人建议:刚开始学L2交换的同学,先把这个流程图背下来。然后在脑子里跑几个例子——比如PC1发个包给PC2,看看表项怎么学、怎么查、怎么转。跑通了,L2交换你就入门了。


公众号:蓝海资料掘金营,微信deep3321