一帧以太网报文如何穿过 Switch:VLAN、VTU、FID 与 ATU 转发机制
以太网帧进入 Switch 后,会先获得交换机内部使用的 VLAN 身份,再经过成员关系、目的地址和端口策略的共同筛选,最终形成出口集合。PVID 负责默认分类,VTU 维护 VLAN 关系,FID 选择地址数据库,ATU/FDB 提供目的地址到端口的映射。 它们各自解决不同问题,只有组合起来才能解释一帧报文的完整去向。
本文承接硬件架构与接口,用匿名化虚拟网络展开二层转发。配置与 MDIO 管理会继续说明如何确认这些规则已经写入硬件。
文中 VTU、ATU 和 802.1Q Mode 使用 Marvell 部分交换芯片家族常见的名称。它们有助于理解实现,但不代表所有 Switch 都具有相同单元、寄存器布局或模式细节。以下步骤是逻辑分析顺序,不是对某颗芯片内部流水线级数的断言。
1. 虚拟网络与一帧输入
所有参数均为演示数据。MAC 使用本地管理的单播地址,不来自实际设备。假设链路正常、端口处于 Forwarding、没有额外的 ACL/TCAM 重定向或丢弃规则。
| 端口 | 虚拟节点 | MAC 地址 | 接口上的业务 |
|---|---|---|---|
| P1 | Sensor | 02:00:00:00:01:11 | 未打 Tag 的 VLAN 120 业务 |
| P8 | Computing SoC | 02:00:00:00:08:88 | 接收/发送带 VLAN Tag 的业务 |
| P3 | Diagnostic Node | 02:00:00:00:03:33 | 未打 Tag 的 VLAN 320 业务 |
| 配置对象 | 演示值 |
|---|---|
| P1 Default VID / PVID | 120;Force Default VID 关闭 |
| P3 Default VID / PVID | 320;Force Default VID 关闭 |
| P1、P3 入口策略 | 接受未标记帧,使用需要入口成员校验的模式 |
| P8 入口策略 | 接受相应 Tagged 帧,保留识别出的有效 VID |
| VTU:VID 120 | FID=9;P1=Untagged,P8=Tagged;其他端口不是成员 |
| VTU:VID 320 | FID=12;P3=Untagged,P8=Tagged;其他端口不是成员 |
| 目的 MAC 表项 | (FID 9, 02:00:00:00:08:88) → P8,有效转发表项 |
Sensor 发出一帧未打 Tag 的报文:SA 为传感器 MAC,DA 为计算 SoC MAC。帧从 P1 进入,目标是从 P8 发出并带上 VLAN 120 的 Tag。
Source MAC(SA)描述发送者,Destination MAC(DA)描述二层接收对象。普通桥接主要根据 DA 决定去向,根据合法的 SA 学习“这个发送者在哪个端口”。IP、UDP 和 SOME/IP 可以是帧的上层内容;普通二层转发无需将它们送入 MCU 协议栈解析。
2. 入口分类:PVID 与 VLAN Tag
PVID 是 Port VLAN Identifier,给需要默认分类的入帧提供 VLAN 身份。常见普通 C-VLAN 情况可以按下表理解:
普通 802.1Q Tag 的 VID 字段为 12 bit,通常使用 1–4094 标识 VLAN;VID=0 表示优先级标记,4095 为保留值。因此不能把每个可编码数值都作为普通 VLAN ID 使用。
| 入帧 | 常见内部 VID 来源 | 需要同时检查 |
|---|---|---|
| Untagged | 入口端口 PVID | 是否允许接收未标记帧 |
| 识别到有效、非零 VID 的 Tagged 帧 | 帧内 VID | TPID 识别、Tag 层次、VID 覆盖规则 |
| Priority-tagged,VID=0 | 默认分类/PVID;PCP 可参与优先级处理 | 器件对 VID=0 的具体处理 |
| 开启 VID 强制覆盖的入帧 | 可能被改用 Default VID | 覆盖适用帧类型及芯片规则 |
示例帧没有 Tag,因此内部 VID=120。入口分类可能只形成内部元数据,不要求这一刻就在缓存帧中插入四字节 Tag;真正发出去的 Tag 由出口规则决定。
PVID 也不等于 VLAN 成员资格。假设 P1 的 PVID 是 120,而 VTU 只存在 VID 320,就不能因为“P1 与 P8 都在 VLAN 320 中”,把 P1 收到的未标记帧自动归入 320。先分类成 120,再根据当前模式处理 120 的查询结果,才是需要验证的路径。
Default VID 是值,Force Default VID 是决定是否覆盖其他分类结果的控制项。Provider VID 则可能关联 Provider 模式、Service Tag 或工具自己的配置对象;不能由名字含有 VID 就当成 PVID。涉及多层 Tag、Provider 模式或专有 CPU Tag 时,需要单独核对解析顺序。
3. 802.1Q Mode:决定怎样使用 VLAN 表
一些 Marvell 家族使用 Disabled、Fallback、Check、Secure 四种入口模式。Linux 的 mv88e6xxx 公共实现也分别定义了这些模式。[1] 下面描述常见语义,实际应用必须与目标型号文档和运行时设置对应。
| 模式 | 常见行为 | 工程关注点 |
|---|---|---|
| Disabled | 不按通常的 VTU 查询执行 VLAN 感知桥接 | Port Based VLAN 与默认地址域可能承担主要隔离职责 |
| Fallback | VTU 命中时使用表项;未命中时采用回退路径 | 缺少 VLAN 表项不一定直接丢帧 |
| Check | 常见实现对 VTU 未命中的 VID 丢弃 | 不能直接等同于严格检查入口成员资格 |
| Secure | 常见实现同时检查 VTU 命中和入口端口成员资格 | VLAN 存在,但入端口不属于该 VLAN,也可能丢帧 |
Check 与 Secure 的这一区别可在早期 Marvell 家族的公开内核开发讨论中看到。[2] 它是具体实现语义,不是 IEEE 为所有交换芯片统一规定的四个模式。
接收 Tagged/Untagged 的过滤开关、TPID 识别、VLAN 分类以及入口成员校验,是相关但不同的条件。不能简单写成“Check 只允许 Tagged”或“Secure 开启后一切帧都会转发”。
示例按严格入口校验分析:VID 120 存在,P1 是其成员,帧才能继续进入相应交换域。
4. VTU:成员关系与出口表示
VTU 是 VLAN Table Unit。部分芯片的 VLAN 表项关联 VID、FID、各端口成员状态和出口 Tag 处理;还可能具有优先级、生成树关联或其他属性。Linux mv88e6xxx 将 VTU 表项与 FID、端口成员数据分别处理,可以作为公开实现参考。[3]
示例 VID 120 的成员集合为 {P1, P8}。P1 的 PVID=120 解决入口分类;VTU 把 P1/P8 列为成员,解决该 VLAN 可经过哪些端口;P8=Tagged 解决出口如何表现该 VLAN。三项配置不能相互替代。
| 端口 | VID 120 的表内状态 | 对示例的含义 |
|---|---|---|
| P1 | Member / Untagged | 属于 VLAN 120;从这里发给 Sensor 时不带该 VLAN Tag |
| P8 | Member / Tagged | 属于 VLAN 120;发给 SoC 时带该 VLAN Tag |
| P3 | Not Member | 不属于 VLAN 120,不应作为该普通业务帧的出口 |
表内 Tagged/Untagged 描述出口行为,不能据此单独断言这个端口接收哪种入帧。入口过滤与出口表示需要分别检查。
5. FID:为 MAC 地址提供查找上下文
FID 是 Filtering Identifier,标识过滤/地址学习数据库的上下文。VID 描述帧所属的 VLAN,FID 描述它使用哪个地址数据库。两者数值可以相同,也可以不同。
示例将 VID 120 映射到 FID 9:查找目的 MAC 时进入 FID 9。如果 FID 12 中存在相同的目的 MAC,也不能据此认为 FID 9 中已经有有效表项。Linux DSA 的公开文档同样区分了 VLAN 与硬件地址数据库/桥接域。[4]
| 学习方式 | 概念 | 示意关系 |
|---|---|---|
| IVL:Independent VLAN Learning | 不同 VLAN 使用独立的学习上下文 | VID 120→FID 9;VID 320→FID 12 |
| SVL:Shared VLAN Learning | 某些 VLAN 共享地址学习上下文 | VID 120、121 都使用 FID 9 |
共享 FID 不等于把 VLAN 成员集合合并。即使两个 VLAN 共享 MAC 数据库,具体帧仍受它自身 VLAN 的出口资格约束。支持多少 FID、怎样关联 VLAN,以及 VLAN 不感知模式下使用哪个默认 FID,均取决于芯片实现。
6. ATU / FDB:目的地址决定候选出口
FDB 是 Filtering Database;ATU 是 Address Translation Unit,是部分芯片对地址表相关单元的称呼。普通查询模型可以写成:
查找键:FID + Destination MAC
结果:目的端口集合 + 表项状态及相关属性示例命中 (FID 9, 02:00:00:00:08:88) → P8。这是目的出口的候选结果,后续仍需经过适用的 VLAN、端口状态和策略筛选。已知目的地址并不保证链路正常,也不会自动跳过所有安全或隔离规则。
Port Vector 是集合的位图
假定演示模型使用 bit n 对应 Pn:
/* 演示数据:32 位位图,仅适用于 port < 32 的表示模型。 */
uint32_t p8_only = UINT32_C(1) << 8; /* 0x0100 */
uint32_t vlan_members = (UINT32_C(1) << 1)
| (UINT32_C(1) << 8); /* 0x0102 */0x0100 的含义是集合 {P8},而不是“第 256 个端口”;0x0102 表示 {P1, P8}。有些设备的逻辑端口、硬件位位置和驱动端口号并非相同编号,位图宽度也不同,需要结合其映射解释。
单播普通表项常指向一个端口;组播、静态多目的规则或特定实现可以使用多个端口。Trunk、LAG 和专有 CPU 端口格式还可能改变字段语义,不能把所有返回字段一律当普通 Port Vector。
7. Source MAC 学习与老化
如果 P1 开启学习、帧通过相应接纳条件,且 SA 是可学习的单播源地址,Switch 可以建立或刷新:
(FID 9, 02:00:00:00:01:11) → P1学习回答的是“Sensor 从哪个入口来”,与本帧 DA 查找回答的“SoC 在哪个出口”不同。学习到 Sensor 的 SA,不会同时学习本帧尚未出现过的 SoC 的 SA。
| 表项类型 | 常见来源 | 生命周期 |
|---|---|---|
| Dynamic | 从合法入帧的 Source MAC 学习 | 刷新、老化、移动或被策略处理 |
| Static | 管理软件或初始化配置显式写入 | 通常不按动态老化方式移除,仍受删除/复位等影响 |
老化时间不是 Ethernet 的统一常数;源地址移动、锁定端口、学习禁用和表容量也会改变行为。若禁止学习且阻止未知单播,要让双向通信成立,就需分别准备两端目的地址的可用规则。
同样,把静态 MAC 写进一个 C 结构体或日志,不会自动建立静态 FDB。必须存在实际的表项写入、完成状态和必要的读回,才能判断硬件已使用它。
8. Unknown Unicast、Broadcast 与 Multicast
| 流量类别 | 判断依据 | 常见转发处理 |
|---|---|---|
| Known Unicast | 单播 DA 在当前地址域命中 | 按命中结果形成候选出口 |
| Unknown Unicast | 单播 DA 未命中 | 按未知单播策略向允许的出口 Flood,或丢弃/送 CPU |
| Broadcast | DA=ff:ff:ff:ff:ff:ff | 向广播策略允许的 VLAN 出口复制 |
| Multicast | DA 是组地址 | 使用静态组播表、Snooping 结果或未知组播策略 |
Flood 不是无条件向所有物理端口发送。它仍受到交换域、成员关系、适用的端口掩码和转发状态限制,普通情况下排除入口端口。某些保留链路本地地址还存在特殊处理,例如终止、Trap 或受控转发。
FDB 没有 SoC 表项时,示例可能通过 Unknown Unicast Flood 从 P8 发出,也可能因为洪泛被禁止而丢弃。未在 MCU 源码中找到 flood-block 调用,不足以证明洪泛已开启:其他初始化源、固件或工具可能已经设置相关状态。
ARP 常使用广播,IPv6 Neighbor Discovery 使用组播。因此“已知单播能通”也不足以证明上层通信完整,解析地址所需的广播/组播路径还要成立。
9. Port Based VLAN 与 VTU 的协作
Port Based VLAN 常以入口相关的端口映射限制可达出口。在 VLAN 不感知或 VTU 回退路径中,它可能是主要规则;在 VLAN 感知路径中,它是否继续参与、是否被表项覆盖,或者何时被特殊规则绕过,依芯片而定。
所以分析 Port Based VLAN 时应记录“在哪种模式、哪条路径上使用”,不能直接把它等同于 PVID,也不能认定它与 VTU 永远相与。
对于本文启用相关出口限制的普通演示模型,可以使用集合来推演:
最终出口 = 目的候选集合
∩ 当前 VLAN 合格出口
∩ 此路径适用的端口策略
∩ 允许转发且链路可用的端口
− 普通情况下的入口端口示例 DA 候选是 {P8},VLAN 合格集合含 P8,当前路径的端口策略允许 P1→P8,P8 也允许转发,因此出口为 {P8}。若把 P8 从任一确实参与的允许集合移除,交集为空,便没有普通转发出口。
这是一种排查模型,不是给所有芯片规定同一条位运算公式。ACL、Trap、镜像、Trunk、Hairpin 和特殊帧优先规则应按该实现单独展开。
10. 端口状态与出口 Tag
Link Up 描述物理链路,Forwarding 描述桥接是否允许转发,两者不同。常见端口状态包括 Disabled、Blocking、Learning、Forwarding;Learning 可以学习源地址,但并不等于允许普通业务帧转发。某些设备还支持按 VLAN/生成树实例设置状态。[1]
最终从 P8 发出时,应用出口 Tag 处理。以下描述以普通单层 VLAN Tag 为例:
| 出口模式 | 常见表示 | 示例 |
|---|---|---|
| Tagged | 输出该 VLAN 的 Tag | P8 发给 SoC,带 VID 120 |
| Untagged | 不输出该 VLAN 的 Tag | P1 发给 Sensor,不带该 Tag |
| Unmodified | 在实现允许的范围内保留原帧 Tag 表示 | 未标记入帧通常仍未标记,Tagged 入帧通常保留 |
Unmodified 不等于“所有帧一定带 Tag”或“一定去 Tag”。Port 级出口模式、VTU 成员表示、Provider 模式与 CPU Tag 可能存在优先关系,需按目标器件确认。Tag 变化后,输出帧的 FCS 也应与最终帧内容一致。
SoC 回复时,若从 P8 发送 Tagged VID 120,入口分类仍进入 FID 9,再通过 Sensor 地址表项选择 P1,最后按 P1 的 Untagged 设置发出。这样,Sensor 无需感知 VLAN Tag,SoC 可以在同一上联上区分多种 VLAN 业务。
11. 按一帧逐项定位丢帧
| 现象或变化 | 分析位置 | 可能结果 |
|---|---|---|
| P1 PVID 改成 320,但帧仍 Untagged | 入口分类 | 进入 320;严格成员检查下,P1 不是成员可被丢弃 |
| VID 120 的 VTU 表项缺失 | 802.1Q Mode | Check/Secure 路径通常丢弃;Fallback 需分析回退 |
| VLAN 存在,但 P1 不在成员表 | 入口成员检查 | 严格校验可丢弃,不能仅因 VID 存在就放行 |
| SoC MAC 只写在 FID 12 | FDB 查找 | FID 9 中仍可能未命中,转入未知单播策略 |
| 禁止学习,且禁止未知单播 | MAC 与洪泛规则 | 缺少有效静态目的表项时没有所需出口 |
| P8 被相关端口策略排除 | 出口资格 | 即便 FDB 命中 P8,也可能无法转发 |
| P8 Link Up,但处于 Blocking | 转发状态 | 普通业务不能按预期发出 |
| P8 输出 Untagged,SoC 只接对应 Tagged VLAN | 出口表示与对端 | Switch 已发出,接收端仍可能分类失败 |
工程验证从原始入帧开始记录 Tag、SA、DA,再读取入口分类配置、VTU/FID、FDB、适用掩码和状态,最后结合出口抓包与计数器。多个节点“属于同一个 VLAN”是必要关系之一,完整转发还需要其余条件共同成立。
公开参考资料
- Linux v6.12:mv88e6xxx/port.h,公开的端口状态、802.1Q Mode、出口模式定义;仅代表相应驱动支持的器件。
- Linux netdev 公开开发讨论:Marvell 88E609x 模式语义,Check 的 VTU Miss 与 Secure 的成员检查;不外推为全部 88Q 型号行为。
- Linux v6.12:mv88e6xxx/global1_vtu.c、global1_atu.c,VLAN 表与地址表访问的公开实现。
- Linux DSA Architecture,VLAN、地址数据库、硬件桥接域与学习/洪泛控制。
- IEEE 802.1Q:Bridges and Bridged Networks,桥接、VLAN 与过滤体系;芯片实现细节仍以其文档为准。
继续阅读: Switch 配置与 MDIO 管理 · 硬件架构与接口 · 专栏首页
