Tag 贴在哪:802.1Q 与 QinQ
导读:VLAN 明明配了,抓包却「没有 Tag」
前面 讲清了 Access / Trunk / Native / SVI 的配置语义:
哪口属于哪个 VLAN、Trunk 允许列表、Native 不一致会怎样。
现场更常遇到的是 字节级困惑:
交换机 show vlan 显示 PC 在 VLAN 20
主机 tcpdump 抓到的 ARP/ICMP 帧里却找不到 0x8100
→ 「VLAN 没生效?」「是不是抓包工具坏了?」
多数情况下 VLAN 已生效,只是 802.1Q Tag 是链路上的语法,不是终端内存里的属性。
Access 口在送给终端前会 剥 Tag;你在 PC 网卡上看到的是 无 Tag 的 Ethernet II,交换机内部仍按 VLAN 20 转发。
一、概念:802.1Q 在帧上标记什么
1.1 定义(报文视角)
IEEE 802.1Q VLAN Tag:在以太网 MAC 头与 内层 EtherType/Length 之间插入 4 字节,标识该帧属于哪个 VLAN(广播域),并可携带 优先级与丢弃提示。
关键区分:
|
视角 |
你关心什么 |
|---|---|
|
配置语义(05-04) |
口模式、PVID、allowed VLAN、Native、SVI |
|
报文语法(本篇) |
线上有没有 Tag、TPID 多少、VID 几位、双层 Tag 谁外谁内 |
1.2 802.1Q Tag 四字段一览
Tag 共 4 字节(32 bit),逻辑上拆为 TPID(2B)+ TCI(2B):
|
字段 |
宽度 |
别名/备注 |
工程含义 |
|---|---|---|---|
|
TPID |
16 bit |
Tag Protocol Identifier |
声明「后面是 VLAN Tag」;客户网常见 |
|
PCP |
3 bit |
Priority Code Point,在 TCI 高 3 位 |
802.1p 优先级 0~7;影响队列调度(与 802.1Qbb PFC 等同族) |
|
DEI |
1 bit |
Drop Eligible Indicator;旧称 CFI |
|
|
VID |
12 bit |
VLAN Identifier |
VLAN 号;可用范围通常 1~4094(0、4095 保留) |
TCI(Tag Control Information) = PCP(3)+ DEI(1)+ VID(12),共 16 bit。
TPID (16) TCI (16)
┌────────────┐ ┌───┬─┬────────────┐
│ 0x8100 │ │PCP│D│ VID │
└────────────┘ └───┴─┴────────────┘
3 1 12
1.2a 理论背景:802.1Q 在标准体系里的位置
IEEE 802.1 工作组管 桥接与 LAN 管理(VLAN、STP、LLDP、802.1X 等);IEEE 802.3 管 以太 MAC 与物理层。
802.1Q(正式名称常写 IEEE 802.1Q — Virtual Bridged Local Area Networks)解决的是:
在同一套物理以太网基础设施上,逻辑划分多个广播域,且 Tag 可在 Trunk 链路上被交换机识别。
桥(Bridge)与交换机(Switch)在标准语言里本是同一类设备:学习源 MAC、按目的 MAC 转发、未知则洪泛。
「交换机」是产品名;802.1Q Tag 是桥在 Trunk 上互相告知「这一帧属于哪个 VLAN」的语法。
广播域(Broadcast Domain) 与 VLAN 的关系:
-
同一 VLAN ID 的帧,在二层洪泛时 应在同一广播域内(无 ACL/私有 VLAN 等例外)。
-
不同 VLAN 之间 默认不转发二层广播(含 ARP Request)——这是 VLAN 分割 ARP 域的根本原因。
-
三层互通靠 路由 / SVI(Switch Virtual Interface)——配置见 05-04,本篇只强调:Tag 里的 VID 决定帧进哪个广播域。
802.1p 与 PCP: 802.1Q 头里的 PCP(Priority Code Point) 最初来自 802.1p 对流量优先级的定义(0 最低,7 最高)。
PCP 不决定「进哪个 VLAN」——那是 VID;PCP 影响 队列调度,并与 802.1Qbb PFC(按优先级暂停)同族。
DEI 在拥塞时标记 「更易丢弃」,与 DiffServ 的 Drop Precedence 思想类似,只是发生在 二层 Tag 上。
标准演进(读抓包时够用):
|
标准/术语 |
要点 |
|---|---|
|
802.1Q-1998 |
引入 4 字节 Tag、TPID |
|
802.1ad(QinQ) |
服务商 S-Tag,TPID 常用 |
|
802.1Q-2014 及以后 |
与 802.1Qbg/802.1BR 等数据中心桥接扩展并存;现网园区仍以 单层/双层 Tag 为主 |
1.3 Native VLAN(无 Tag 的约定)
Native VLAN:Trunk 链路上 不打 Tag 的那条 VLAN 的 约定名称(配置概念见 05-04)。
报文表现:
-
属于 Native VLAN 的帧在 Trunk 上 不带 802.1Q Tag(MAC 后直接跟 EtherType)
-
对端若 Native 配置不一致,会把 同一串无 Tag 字节 判进 不同 VLAN → 隐蔽的二层错配
抓包提示: 在 Trunk 口能看到 有 Tag 的 10/20/30 与 无 Tag 的 Native 混在一起,这是设计行为,不是丢 Tag 的故障。
1.4 QinQ / 802.1ad:双层 Tag
QinQ(802.1Q-in-Q):在已有 客户 Tag(Inner / C-Tag) 外再包一层 服务提供商 Tag(Outer / S-Tag),共 8 字节 标签栈。
|
层级 |
常见 TPID |
谁打 |
VID 通常表示 |
|---|---|---|---|
|
Outer(S-Tag) |
|
运营商/汇聚 PE |
客户专线、业务实例 |
|
Inner(C-Tag) |
|
客户 CE / 园区核心 |
客户内部 VLAN |
Dst MAC | Src MAC | Outer TPID+TCI | Inner TPID+TCI | EtherType | Payload | FCS
与单层 802.1Q 的关系: 内层 Tag 语法不变;外层只是多包一层「信封」。
Wireshark 常显示 「802.1Q VLAN #X → 802.1Q VLAN #Y → IPv4」。
1.5 为什么 Access 口抓包常 没有 Tag
这是本篇最高频问题,机制如下:
PC 网卡 ──发送──► 无 Tag 帧(Ethernet II)
│
Access 口(PVID = 20)
│ 交换机内部:打上 VLAN 20 标记(或等价逻辑)
▼
交换 fabric 按 VLAN 20 转发
│
发往 Trunk ──► 带 Tag VID=20(若非 Native)
│
发往另一 Access(VLAN 20)──► 剥 Tag ──► PC 收到仍无 Tag
结论:
-
终端几乎从不自己发 802.1Q Tag(除非网卡/VF 开 VLAN 卸载或虚拟化显式打 Tag)。
-
Access 口出方向 对终端 剥 Tag 是默认行为——PC 不需要理解 VLAN。
-
你在 PC 上抓包 看不到 Tag ≠ 没进 VLAN;应到 上行 Trunk、镜像口、或交换机 CPU 抓包 看 Tag。
-
PVID(Port VLAN ID)决定「无 Tag 帧进哪个 VLAN」——配置语义见
[05-04 §2.2](./计算机网络专栏-05-04-VLAN专章.md)。
例外(能看见 Tag 的情况):
-
抓包点在 Trunk 链路 或 SPAN 镜像(且镜像未 strip)
-
Linux
eth0.20VLAN 子接口、MacVTap/ SR-IOV with VLAN 等显式 Tag 场景 -
用 tcpdump 在交换机 或 带 VLAN 的 bond/bridge 子接口 上抓
二、原理:十六进制布局与位域手算
2.1 单层 802.1Q 帧(Ethernet II + Tag)
相对无 Tag 帧,在 源 MAC 之后 插入 4 字节:
┌─────────┬─────────┬──────────┬─────┬─────────────┬─────┐
│ Dst MAC │ Src MAC │ 802.1Q │Type │ Payload │ FCS │
│ 6 B │ 6 B │ 4 B │ 2 B │ 46~1500 B │ 4 B │
└─────────┴─────────┴──────────┴─────┴─────────────┴─────┘
TPID+TCI ↑
内层 EtherType
仍是 0x0800 等
带 Tag 经典最大帧长: 1522 字节(含 FCS;无 Tag 为 1518)。MTU 讨论常写 「L3 MTU 1500 + 14 MAC + 4 Tag = 1518 L2」。
2.2 示例:VID=20,PCP=0,DEI=0
假设内层为 IPv4(0x0800),Tag 段 hex:
81 00 00 14 08 00
│ │ └── 内层 EtherType IPv4
│ └── TCI = 0x0014
└── TPID = 0x8100
TCI 手算:
TCI = 0x0014 = 0b 0000 0000 0001 0100
PCP = 000 = 0
DEI = 0
VID = 0x014 = 20
带 QoS 时: VID=100、PCP=5、DEI=1 → TCI = 0xB064,线上 81 00 b0 64(PCP 占 TCI 高 3 位)。
2.3 QinQ 双层布局
Dst(6) | Src(6) | Outer TPID(2) | Outer TCI(2) | Inner TPID(2) | Inner TCI(2) | Type(2) | ...
示例:Outer VID=100,Inner VID=20,均为 PCP=0、DEI=0:
88 a8 00 64 81 00 00 14 08 00
│ │ │ │ └── IPv4
│ │ │ └── Inner TCI VID=20
│ │ └── Inner TPID
│ └── Outer TCI VID=100
└── Outer TPID 802.1ad
若外层 TPID 也是 0x8100(部分厂商 QinQ Type 可选 8100/88A8),Wireshark 仍按 两层 VLAN 嵌套 解析,但 Ethertype 合规性 以设备实现为准——排障以 两端配置 + 抓包 为准,不硬背单一 TPID。
2.3a 理论:Tag 栈、Provider Bridge 与 TCAM
Tag 栈(Tag Stack) 在标准里的模型是:帧可携带 多个 Tag,交换机 从外向内 解析:
收到帧 → 若 Outer TPID=0x88A8 → 按 S-VID 选服务商上下文
→ 再读 Inner 0x8100 → 按 C-VID 进客户广播域
→ 再读内层 EtherType → 交给三层或继续桥接
802.1ad Provider Bridge(.provider 桥) 把网络分为:
-
Customer Bridge(CE):客户侧,只理解 C-Tag;
-
Provider Bridge(PE):运营商侧,添加/剥离 S-Tag,在 S-VLAN 里承载多条客户专线。
为何需要 QinQ: 客户内部 VLAN ID(1~4094)可能 与另一客户冲突;外层 S-VID 在运营商域内唯一即可,内层 C-VID 由客户自定。
抓包看到 Outer=100, Inner=20 时:100 是运营商分配的「管道号」,20 是客户自己的 VLAN 20。
交换机如何匹配 Tag(理论): 商用芯片用 TCAM / 匹配表 对 入端口 + Tag 栈 + 内层字段 做 最长匹配。
Access 口规则等价于:无 Tag 帧 → 打 PVID 进表;出 Access → 剥 Tag。
Trunk 口:有 Tag → 按 VID 转发;无 Tag → 归入 Native VLAN。
理解 TCAM 后,「Native 不一致 = 同一无 Tag 字节被判进不同 VLAN」 就是逻辑必然。
Private VLAN(PVLAN,理论一笔): 在 同一主 VLAN(Primary) 内再分 Isolated / Community / Promiscuous 端口,使 同 VLAN 号内仍不能互访。
抓包 VID 可能相同但端口隔离——若 ping 不通且 Tag 正确,要查 PVLAN 策略,不能只看 VID。
2.4 与 802.3 Length 帧的交界
若线上是 802.3 + LLC(Length ≤ 1500),Tag 仍插在 源 MAC 与 Length 字段之间;
判别 Length 还是 Ethertype 时,要看 最内层类型字段(Tag 之后第一个 2 字节)。详见 [07-02 §2.3](./计算机网络专栏-07-02-以太帧格式与LLC.md)。
2.5 保留 VID 与抓包
|
VID |
含义(直觉) |
|---|---|
|
0 |
有时用于 优先级 Tag(Priority Tagging,VID=0 表示仅 PCP 有意义);部分设备禁止作 Access PVID |
|
1 |
常作默认 VLAN;Native 默认值因厂商而异 |
|
4095 |
保留 |
工程上: 生产 Access PVID 避免 0/4095;抓包看到 VID=0 要查是 Priority Tag 还是 配置异常。
2.5a 理论:MAC 学习与 VLAN 的交叉
MAC 地址表(Forwarding Database) 在标准桥模型里 按 {VLAN, MAC} 二元组 学习——同一 MAC 在不同 VLAN 可有不同出端口(少见但合法,如路由器多 SVI)。
学习方向: 帧 从某端口进入 时,交换机记录 「该 VLAN 下此 SMAC 从该端口来」;未知 DMAC 则洪泛(在该 VLAN 内)。
因此 ARP Request 洪泛 与 Reply 单播 都依赖 VID 一致;VID 错则 学不到对端 MAC,Reply 即使发出也可能 进错表项。
对称性与非对称 VLAN: 若一端 Trunk allowed 不含对端 VID,表现为 单向通——Request 能出、Reply 回不来。抓包要在 两侧 Trunk 同时镜像 才看得见 非对称。
2.5b 理论:Voice VLAN、Priority Tagging 与 GVRP(一笔)
Voice VLAN(概念): 话机 数据口 常 无 Tag 跑 PVID;识别为 IP Phone 后,交换机 Voice VLAN(如 100) 给 语音流量打 Tag。
抓包 同一 Access 口 可能见 无 Tag CDP/LLDP + 带 Tag VID=100 的 RTP——不是 Tag 「丢失」,是 策略分流。
Priority Tagging(VID=0): TCI 中 VID=0 表示 仅 PCP/DEI 有意义,帧 归属 PVID 广播域——Wireshark 显示 vlan 0 时查 是否 Priority Tag,勿与 Native VLAN 1 混淆。
GVRP / MVRP(802.1Q 动态 VLAN 注册): 交换机间 自动通告 VLAN 成员——现网多被 静态 Trunk allowed 取代;若抓包见 GVRP PDU(Ethertype 相关慢协议或厂商封装),说明 动态 VLAN 仍在用,Trunk allowed 会 随 GVRP 变化,静态文档易过时。
三、场景:在哪看见 Tag、哪层 VID 算数
3.1 园区接入:Access + 上行 Trunk
[PC 无 Tag] ─ Access VLAN30 ─ [接入交换机]
│
Trunk allowed 10,20,30
│
[汇聚/核心] ── SVI 网关
-
PC 抓包: 无 Tag;VLAN 30 体现在 交换机端口 PVID。
-
Trunk 抓包: 见
vlan 30;Native 流量除外。 -
跨 VLAN 路由: 帧在 三层离开 SVI 后,L3 包头已变;回二层时 重新打当前 VLAN 的 Tag(若从 Trunk 出去)。
3.2 服务器 Trunk:Hypervisor / Linux bond
虚拟化常把 VM 不同 VLAN 映射到 宿主机 Trunk:
eth0(Trunk)上 tcpdump → 可见多 VID 并行
VM-A VLAN10、VM-B VLAN20 → 由 vSwitch/Open vSwitch 按 Tag 分流
Linux:eth0.10 由内核剥/加 Tag;在父接口 eth0 抓包 比子接口更易看到 0x8100。
3.3 云 VPC / 虚拟交换
公有云 子网 多对应 overlay 或 ToR 上的 VLAN/VNI 映射:
租户看到:子网 A / 子网 B(三层)
Underlay 可能:ToR Trunk 上 802.1Q 区分租户或业务
Overlay 可能:VXLAN VNI(Tag 在 UDP 里,不在以太 MAC 后)
宿主机 vSwitch 抓包可能同时见 802.1Q underlay 与 VXLAN;安全组无误时仍要查 underlay VID / Trunk allowed(05-04 + 本篇)。
3.4 运营商 QinQ 专线入云
典型模型:
客户 CE ── Inner Tag(客户 VLAN) ──► 运营商 PE
PE 加 Outer Tag(专线 S-VLAN) ──► MPLS/城域网 ──► 云侧 PE 剥 Outer
-
客户侧抓包: 通常只见 Inner
0x8100。 -
运营商汇聚 mirror: 见 Outer
0x88A8+ Inner0x8100。 -
Outer VID 不一致 → 专线两端 业务 VLAN 串线 或 完全不通。
-
Inner 保留 贯穿隧道,客户 可继续使用自有 VLAN 规划(在 Inner 空间内)。
四、抓包解读:Wireshark 与 tcpdump
4.1 Wireshark 显示习惯
常见展开:
Ethernet II, Src …, Dst …
802.1Q Virtual LAN, PRI: 0, DEI: 0, ID: 20
Internet Protocol Version 4, …
QinQ:
802.1Q #100 (Outer)
802.1Q #20 (Inner)
IPv4 …
Expert Info 若提示 「VLAN ID mismatch」 或 「Unexpected VLAN」,对照 Trunk allowed list / Native(05-04)。
4.2 tcpdump 过滤器
先看链路层(-e 推荐):
# 所有带 802.1Q 的帧(libpcap 解析 vlan 关键字)
sudo tcpdump -i eth0 -e -nn 'vlan'
# 指定 VID(等效 vlan id)
sudo tcpdump -i eth0 -e -nn 'vlan 20'
sudo tcpdump -i eth0 -e -nn 'vlan id 20'
# 组合:VLAN 20 上的 ARP
sudo tcpdump -i eth0 -e -nn 'vlan 20 and arp'
# 排除某 VLAN
sudo tcpdump -i eth0 -e -nn 'vlan and not vlan 1'
QinQ / 双层 Tag:
# 外层 VID=100(需较新 libpcap;老版本可能只认第一层)
sudo tcpdump -i eth0 -e -nn 'vlan 100'
# 看原始 hex 确认双层
sudo tcpdump -i eth0 -e -nn -xx 'vlan' -c 5
# 找连续 88 a8 .. .. 81 00 .. ..
注意: vlan 关键字依赖 libpcap 对 802.1Q 的解析;
在 Access 口 PC 上 对 无 Tag 流量 用 vlan 20 会抓不到——不是过滤器写错,是 线上本就没有 Tag。
4.3 Wireshark 显示过滤器
vlan # 任意 VLAN 标记帧
vlan.id == 20 # VID=20
vlan.id == 20 && arp
vlan.id == 100 && vlan.id == 20 # QinQ:部分版本需用 vlan stacking 字段
eth.type == 0x8100 # 仅按外层 TPID(粗糙)
Statistics → VLANs 可统计 pcap 里各 VID 占比,快速发现 「只应有 10/20,却出现 99」。
4.4 对照实验:同一 ping,不同抓包点
|
抓包位置 |
预期 Tag |
预期 VID 显示 |
|---|---|---|
|
PC Access 口 |
无 |
(无 vlan 层) |
|
接入交换机 Trunk 镜像 |
有 |
与 PVID/映射一致 |
|
Native VLAN 帧过 Trunk |
无 |
易与 Access 混淆 |
|
QinQ PE 外侧 |
双层 |
Outer=专线,Inner=客户 |
五、问题定位:从 Tag 现象回配置
|
现象 |
报文线索 |
常见原因 |
回链 |
|---|---|---|---|
|
PC 抓包无 Tag |
无 |
Access 剥 Tag 正常 |
本篇 §1.5;要 Tag 改 Trunk 镜像 |
|
Trunk 上无 Tag 但应对端有 VLAN |
裸 EtherType |
Native VLAN 或 Tag 被 strip |
05-04 Native 一致 |
|
只有一侧 VID 对 |
一端 20 一端 30 |
PVID/allowed 错、Hybrid 口策略 |
05-04 |
|
pcap 里 VID=1 泛滥 |
大量 |
默认 VLAN 未规划、管理流量 |
05-04 §2.4 |
|
QinQ 外层对、内层错 |
Outer 100 OK, Inner 乱 |
CE 配置或 PE 重写 Inner 策略 |
运营商工单 |
|
MTU 黑 hole |
大包不通小包通 |
Tag +4 未计入 Path MTU |
05-02/04 MTU |
|
|
线上无 Tag |
抓在 Access 终端 |
换 Trunk 镜像 |
|
双 Tag 设备不认 |
单 Tag 设备接 QinQ |
TPID/层级不匹配 |
改 access-mode vs trunk |
5.1 决策树:「VLAN 配了但抓不到 Tag」
show vlan / 端口 PVID 是否预期?
├─ 否 → 05-04 改 Access/PVID
└─ 是 → 抓包点是否在 Access 终端?
├─ 是 → 正常无 Tag;到 Trunk 镜像再抓
└─ 否 → Trunk 上仍无 Tag?
├─ 是 → 是否 Native VLAN 流量?
│ ├─ 是 → 预期无 Tag
│ └─ 否 → 查 strip/转换 ACL、错误 mirror
└─ 有 Tag 但 VID 错 → 05-04 allowed/PVID/映射表
5.2 与 ARP 章联动
同网段 ARP 无 Reply 时,在 Trunk 镜像 上看 Request 的 VID:
Request 带 vlan 20 → 说明源侧已进 VLAN 20
Reply 从未以 vlan 20 出现 → 对端不在 20 或 Trunk 未放行 20
Request 本身无 Tag(在 Trunk 镜像上)→ Native 或 PVID 问题
六、实操
6.1 实验 A:验证 Access 口无 Tag
# 终端(Access VLAN 20)
sudo tcpdump -i eth0 -e -nn -c 3 'arp or icmp'
# 预期:Ethernet II,直接 0x0806 / 0x0800,无 vlan 关键字
# 同时在交换机 Trunk 镜像口(若可)
sudo tcpdump -i eth1 -e -nn -c 3 'vlan 20'
# 预期:可见 802.1Q, id 20
6.2 实验 B:手读 TCI
从 -xx 输出截取(示例):
... 52 54 00 aa bb cc ← 源 MAC 尾
81 00 00 14 ← TPID + TCI(VID=20)
08 00 ← IPv4
用 printf / 脚本 验证:TCI=0x0014 → VID=0x14=20。
6.3 实验 C:Linux VLAN 子接口对照
# 创建 VLAN 子接口(需父接口支持)
sudo ip link add link eth0 name eth0.20 type vlan id 20
sudo ip link set eth0.20 up
# 在父接口抓 → 通常见 Tag;在子接口抓 → 内核已剥 Tag
sudo tcpdump -i eth0 -e -nn -c 2 'vlan 20' &
sudo tcpdump -i eth0.20 -e -nn -c 2 'icmp' &
ping -c 1 -I eth0.20 192.168.20.1
6.4 实验 D:Wireshark 统计与 QinQ 指纹
-
Statistics → VLANs:列出规划外 意外 VID → 回 Trunk allowed。
-
QinQ 在
-xx中搜88 a8 … 81 00连续两段 TPID+TCI(Outer → Inner →08 00)。
七、小结
-
802.1Q 在源 MAC 后插 4 字节:TPID
0x8100+ TCI(PCP/DEI/VID);内层 EtherType 不变语义。 -
VID 12 bit → 1~4094 为常用规划空间;PCP/DEI 服务 QoS,不决定广播域边界。
-
Access 口抓包常无 Tag 因 终端不发 Tag、交换机出方向剥 Tag;VLAN 生效看 交换机转发域,不看 PC pcap 有没有
0x8100。 -
Native VLAN 在 Trunk 上 无 Tag,是最常见的 「有 VLAN 无 Tag」 合法形态,也是 Native 不一致 的故障温床(配置 → 05-04)。
-
QinQ 外层
0x88A8(或厂商0x8100)+ 内层0x8100,Outer 管运营商,Inner 管客户。 -
过滤器:
vlan/vlan id 20;Access 终端上对 Tag 过滤 常为空 是正常现象。
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐

所有评论(0)