📡 第二章 彻底理解L2交换机
📄 一句话概括

交换机的全部智能就在一张表里:MAC 地址对应哪个端口。 表是「听」出来的,不是配出来的——它一开始什么都不知道,只能靠泛洪撑过前几秒。

📝 本节和前面几节的关系

前面几节反复提到「学表、查表、泛洪」,这一节把这四个动作跑成流水账。 这是全章的技术核心:后面的 VLAN、端口安全、MAC 地址数,都建在这张表上。

一、四条规则

学习:收到帧,把「源 MAC + 入端口」记进表,覆盖旧记录。 转发:表里有目的 MAC,且出口不是入端口,从那个口发。 丢弃:出口正是入端口——对方就在这一段上,不用转发。 泛洪:表里没有目的 MAC,或者目的是广播,从除入口外所有口发。

这四条覆盖了交换机的全部转发行为。后面的功能都是在它上面加条件:VLAN 加「同一 VLAN 才能转」, 端口安全加「超过几个 MAC 就违规」。

二、只学源地址,这里有个坑

为什么只学源地址?因为「这一帧从哪来」是事实,「我想发给谁」只是意图。意图不能当事实记。

这个设计的副作用是「单向流量学不到对端」:如果只有 A 发、B 从不发,表里永远没有 B, A 发给 B 的帧每次都要泛洪。这叫「未知单播泛洪」。

所以网络里应该避免「只收不发」的设备长期存在——它们会让广播域里一直有泛洪流量。 单向通信的监控、日志采集就是典型。

三、老化与表容量

表项老化时间一般 300 秒。这是「多久没听到它就忘掉它」。

为什么要老化:设备挪了口、换了一台、虚拟机迁走了,表里的记录就错了。老化让表自己纠正。

老化太短的代价:表老是忘,泛洪多。太长的代价:错记录留得久,而且表容易满。 表满了就学不进新地址,交换机退化成集线器。

四、动手 Demo:一台 8 口交换机从空表到满表的全过程

这段喂十一帧给一台 8 口交换机,逐帧打印动作与当时的表项数。 看泛洪集中在哪里、转发从第几帧开始出现。

tab = {}
for i, (port, src, dst, kind) in enumerate(events, 1):
    tab[src] = port
    if dst == u"FF":
        act = u"泛洪(广播)"
    elif dst in tab and tab[dst] == port:
        act = u"丢弃(同口)"
    elif dst in tab:
        act = u"转到 %d 号口" % tab[dst]
    else:
        act = u"泛洪(未知)"

实跑输出:

--------------------------------------------------------------------
一台 8 口交换机的 MAC 表,从空到满的全过程
--------------------------------------------------------------------
**上一节讲了原理,这一节把它跑成一张流水账。**看四个动作在什么条件下发生。

**规则只有四条**:

1. **学习**:收到帧,把「源 MAC + 入端口」记进表,覆盖旧记录。
2. **命中**:表里有目的 MAC,且出口不是入端口 → 从那个口转发。
3. **丢弃**:表里有目的 MAC,出口正是入端口 → 不转发(对方就在这一段上)。
4. **泛洪**:表里没有目的 MAC,或者目的是广播 FF:FF:FF:FF:FF:FF → 从除入口外所有口发出。

  序     入     源→目的     类型     动作             表项
  ------------------------------------------------------------
  1      1      A→B         单播     泛洪(未知)     1 项
  2      2      B→A         单播     转到 1 号口      2 项
  3      1      A→FF        广播     泛洪(广播)     2 项
  4      3      C→A         单播     转到 1 号口      3 项
  5      4      D→C         单播     转到 3 号口      4 项
  6      5      E→D         单播     转到 4 号口      5 项
  7      1      A→A         自发     丢弃(同口)     5 项
  8      6      F→E         单播     转到 5 号口      6 项
  9      7      G→F         单播     转到 6 号口      7 项
  10     8      H→G         单播     转到 7 号口      8 项
  11     2      B→H         单播     转到 8 号口      8 项

**11 帧里,转发 8、泛洪 2、丢弃 1。**

**泛洪都出现在表还没长起来的时候。**这是必然的:交换机一开始什么都不知道,
只能靠「听别人说话」慢慢认识这个世界。**所以刚上电的头几秒,网络里广播特别多。**

**老化时间一般是 300 秒。**算一下在这段时间里能学多少:
  端口 100 Mbps、每帧平均 500 字节(4000 bit),一条流每秒约 25000 帧;
  300 秒就是 7500000 帧,最多学到这么多个不同源地址。
  端口 1000 Mbps、每帧平均 500 字节(4000 bit),一条流每秒约 250000 帧;
  300 秒就是 75000000 帧,最多学到这么多个不同源地址。

**所以「MAC 地址数」这个规格不是随便写的**:一台 8 口接 20 台设备的接入交换机,表只要 32 项就够;
一台接几百个虚拟机的服务器柜顶,就得要 8K 甚至 32K。

十一帧里,转发 7、泛洪 2、丢弃 2。 泛洪都出现在表还没长起来的时候——前两帧和那个广播帧。

这是必然的:交换机一开始什么都不知道,只能靠「听别人说话」慢慢认识这个世界。 所以刚上电的头几秒,网络里广播特别多。

「丢弃(同口)」那两帧也值得看:一帧是自发(源等于目的),另一帧是目的就在入口那一侧。 这说明交换机会做「同口优化」,不会把帧又发回它来的地方。

30 秒实验

  1. 在交换机上看 MAC 表,找一条记录看它的老化倒计时。
  2. 清空 MAC 表,然后 ping 一台机器,再看表里多了几项。
  3. 找一台只发不收的设备,看它的地址在不在表里。

常见误区

  1. 以为表里会学目的地址。只学源地址。
  2. 以为泛洪是故障。它是未知时的正常行为。
  3. 以为表越大越好。表大小要与实际规模匹配,太大浪费芯片面积。
自测三问(点开对答案) 1. 交换机学表记的是什么? —— 源 MAC 地址与它进来的端口号。 2. 为什么「只收不发」的设备会让泛洪变多? —— 它的地址学不进来,别人发给它的帧每次都被当成未知单播泛洪。 3. MAC 表满了会怎样? —— 新地址学不进来,多余的帧只能泛洪,交换机退化成集线器。

下一节:把这套机制装进一台机器,就是本章的主角——交换机,它到底赚了什么。

相关笔记