📚 第三章 数据链路
📄 一句话概括

VLAN 就是往帧里插一个 4 字节标签,写明「这个帧属于哪个虚拟局域网」。 它缩小的是「广播的传播范围」,不是把「带宽」变大——这一点最容易搞错。

📝 本节和前面几节的关系

3.2.5 讲的是「怎么不出环」,这一节讲「怎么把一台交换机切成几台」。 标签只占 4 字节,但它把可用的 VLAN 编号限死在 4094 个。

一、4 个字节的标签

插在源 MAC 之后、类型字段之前:

字段 长度 取值 作用
TPID 2 字节 固定 0x8100 告诉对方「后面是 VLAN 标签」
PCP 3 位 0~7 优先级,语音 5、视频 4
DEI 1 位 0/1 拥塞时能不能丢
VID 12 位 0~4095 VLAN 编号,真正干活的字段

第一行那个 TPID 是「识别标志」:它占用了原来「类型」字段的位置,值固定 0x8100。 接收方看到 0x8100,就知道「这里不是类型,是标签」。 真正的类型字段被往后推了 4 个字节。 第四行那个 12 位决定了上限:2 的 12 次方是 4096,但 0 表示「没打标签」、4095 是保留, 所以能用的只有 4094 个。 「交换机的 VLAN 编号到 4094 就到顶」就是这么来的。

二、帧长了 4 字节,MTU 没变

这是最容易混的一处:

项目 不打标签 打一层 打两层(QinQ)
最小帧 64 68 72
最大帧 1518 1522 1526
MTU 1500 1500 1500

第三行不变是对的:标签插在「头」里,不占「载荷」,所以应用层感觉不到少了什么。 变的只是「帧的最大长度」这个数。 所以老设备上的「巨帧」配置里会出现 1522、1526 这种数: 那不是巨帧,是「给 VLAN 标签留了位置的正常帧」。 把 1518 配成上限的交换机,收到带标签的帧就会判为超长而丢弃—— 这是「换了交换机之后某些 VLAN 不通」的经典原因。 第二行那个「QinQ」是运营商的用法: 打两层标签,外层标识「哪个客户」,内层保留客户自己的 VLAN。 这样不同客户的 VLAN 编号就不会冲突。

三、省下来的是广播域

一台 48 口交换机,划几个 VLAN 就有几个广播域:

VLAN 数 每域端口数 一个 ARP 广播影响几个口
1 48 47
4 12 11
8 6 5

第一行是「不划 VLAN」的默认状态:任何一台机器发 ARP,剩下 47 个口都要收。 第三行划成 8 个域之后,广播只在各自的 5 个口里转。 这就是 VLAN 的收益:缩小广播的传播范围。 它并不是「让带宽变大」:总带宽一点没变,变的是「广播占掉多少」。 所以 VLAN 的效果在「广播多的网络」里明显,在「全是单播大流量」的环境里几乎没感觉。 代价是「跨 VLAN 必须过路由器」:VLAN 之间在二层完全隔离,想通就得走三层。 所以「三层交换机」这个品类才有意义—— 它把「每个 VLAN 一个网关」做进硬件,省掉一台外接路由器。

四、动手 Demo:VLAN 用一个 4 字节标签,换来了几个广播域

先把 4 个字节拆开看清,再算「打标签之后帧长变成多少」,最后看广播域的变化。 注意 MTU 那一行始终是 1500。

for pay in (46, 1500):
    base = 14 + pay + 4
    print('载荷 %4d:不打标签 %4d,打一层 %4d,打两层 %4d'
          % (pay, base, base + 4, base + 8))

print('可用 VLAN 编号:%d 个(0 和 4095 不能用)' % (2 ** 12 - 2))
for v in (1, 2, 4, 8):
    print('%d 个 VLAN:每域 %d 口,广播影响 %d 口'
          % (v, 48 // v, 48 // v - 1))

实跑输出:

--------------------------------------------------------------------
VLAN 用一个 4 字节标签,换来了几个广播域
--------------------------------------------------------------------
**VLAN 要解决的问题很具体:一台交换机上的 48 个口,能不能当成几台独立的交换机用。**
**做法是在帧里插一个 4 字节的标签,写明「这个帧属于哪个虚拟局域网」。**

**这 4 个字节拆开是这样**:
  字段     长度       取值            作用
  ------------------------------------------------------------------
  TPID     2 字节     固定 0x8100     告诉对方「后面是 VLAN 标签」
  PCP      3 位       0~7            优先级,语音走 5、视频走 4
  DEI      1 位       0/1            拥塞时能不能丢
  VID      12 位      0~4095         **VLAN 编号,真正干活的字段**

**12 位能编 4096 个,但可用只有 4094 个**:
**0 表示「没打标签」,4095 是保留值,两个都不能当普通 VLAN 用。**
**这也解释了为什么交换机的 VLAN 编号到 4094 就到顶了。**
**插了标签,帧就长了 4 字节**:
  载荷     不打标签     打一层标签     打两层(QinQ)
  ----------------------------------------------------
  46       64           68             72
  1500     1518         1522           1526

**所以带标签的帧最大是 1522 字节,不是 1518**:
**很多老设备「巨帧」配置里写的 1522 或者 1526,就是在给 VLAN 标签留位置。**
**而 MTU 那个 1500 是不变的**——**标签插在原有头里,不占载荷,所以应用层感觉不到。**
**真正省下来的是广播域**:
  VLAN 数     每域端口数     广播域个数
  --------------------------------------
  1           48             1
  2           48/2 = 24     2
  4           48/4 = 12     4
  8           48/8 = 6      8

**一台 48 口交换机不划 VLAN 时,是一个大广播域**——**任何一台机器的 ARP 广播,47 个口都要收。**
**划成 8 个 VLAN,就变成 8 个小广播域,广播只在各自的 6 个口里转。**
**这就是 VLAN 的收益:把「广播的传播范围」缩小,而不是把「带宽」变大。**
**代价是「跨 VLAN 必须过路由器」**:**VLAN 之间在二层是隔离的,想通就得走三层**。
**所以「三层交换机」这个品类才有存在意义**——
**它把「每个 VLAN 一个网关」这件事做进了硬件,省掉一台外接路由器。**

载荷 46 字节时,不打标签是 64(14 + 46 + 4),这正好是最小帧长;打了标签就是 68。 所以「最小帧 64」这条规则在 VLAN 环境下要改成 68—— 很多抓包工具会把 68 字节的帧标成「小于最小帧」,其实是没算标签。 载荷 1500 那一行是 1518 / 1522 / 1526: 这就是「巨帧配置写 1522」的来历——它不是巨帧,是「带 VLAN 标签的正常帧」。 最后那个 4094 是硬上限:12 位能编 4096 个,去掉 0 和 4095 就剩 4094。 所以「VLAN 不够用」时只能上 QinQ(再套一层),两层加起来能到一千六百万个组合。

30 秒实验

  1. 把 pay 改成 1,看打标签后的帧长(会被填充到 68)。
  2. 算一下:QinQ 两层标签最多能组合出多少个 VLAN?
  3. 想一下:为什么「跨 VLAN 必须过三层」,二层能不能想办法直通?

常见误区

  1. 以为 VLAN 让带宽变大。 总量不变,变的是「广播占多少」。
  2. 以为 VLAN 会缩小 MTU。 MTU 还是 1500,标签插在头里,不占载荷。
  3. 以为 VLAN 是安全隔离。 它只是「不广播」,二层仍可构造跨 VLAN 的攻击帧(如 VLAN 跳跃)。
自测三问(点开对答案) 1. VLAN 标签占几个字节?里面有哪几个字段? —— **4 字节。** TPID(2)+ PCP(3 位)+ DEI(1 位)+ VID(12 位)。 2. 为什么 VLAN 编号最多到 4094? —— **VID 是 12 位,能编 4096 个。**0 表示「没打标签」、4095 保留,所以能用 4094 个。 3. 带 VLAN 标签的最大帧是多少?MTU 变了吗? —— **1522 字节(单层)/1526(QinQ)。** MTU 仍是 1500。

下一节换介质:从双绞线、同轴到光纤,以太网的身体换了好几次。

相关笔记