本文基于Synopsys DesignWare Cores Ethernet Quality-of-Service Databook,深入讲解VLAN技术原理、报文构造方法、VIP配置以及常见面试问题。
一、VLAN基础概念
1.1 什么是VLAN?
VLAN(Virtual Local Area Network,虚拟局域网)是一种将物理网络划分为多个逻辑网络的技术。通过VLAN,我们可以在不改变物理连接的情况下,将网络设备按功能、部门或应用进行逻辑分组。
通俗理解:想象一栋办公楼,虽然大家都在同一栋楼里工作(同一个物理网络),但通过VLAN技术,我们可以把不同部门的人"虚拟地"隔离到不同的楼层,就像他们真的在不同楼层工作一样。
1.2 为什么需要VLAN?
主要优势:
- 隔离广播域:减少广播风暴,提高网络性能
- 增强安全性:不同VLAN之间无法直接通信
- 灵活管理:无需物理重新布线即可调整网络结构
- 降低成本:减少物理设备需求
1.3 VLAN标准 - IEEE 802.1Q
IEEE 802.1Q是VLAN的官方标准,定义了在以太网帧中插入VLAN标签的方法。
二、VLAN标签结构详解
2.1 标准以太网帧 vs VLAN标签帧
标准以太网帧结构:
+-------------------+-------------------+------------------+
| 目的MAC地址(6B) | 源MAC地址(6B) | 类型/长度(2B) |
+-------------------+-------------------+------------------+
| 有效载荷(46-1500B) |
+--------------------------------------------------------+
| FCS校验(4B) |
+--------------------------------------------------------+
VLAN标签帧结构:
+-------------------+-------------------+------------------+
| 目的MAC地址(6B) | 源MAC地址(6B) | TPID=0x8100(2B) |
+-------------------+-------------------+------------------+
| TCI(2B) | 类型/长度(2B) | 有效载荷 |
+--------------------------------------------------------+
| FCS校验(4B) |
+--------------------------------------------------------+
2.2 VLAN标签字段详解
TPID (Tag Protocol Identifier)
- 长度:2字节
- 作用:标识这是一个VLAN标签帧
- 标准值:0x8100(IEEE 802.1Q)
- 其他值 :
- 0x88A8:Q-in-Q(双层VLAN,用于运营商网络)
- 0x9100:非标准Q-in-Q
TCI (Tag Control Information)
-
长度:2字节(16位)
-
结构:
+-----+-----+---------------------+ | PCP | DEI | VID | | 3b | 1b | 12b | +-----+-----+---------------------+
各字段说明:
| 字段 | 长度 | 说明 |
|---|---|---|
| PCP (Priority Code Point) | 3位 | 优先级,用于QoS,范围0-7 |
| DEI (Drop Eligible Indicator) | 1位 | 丢弃指示,1表示可丢弃 |
| VID (VLAN Identifier) | 12位 | VLAN ID,范围0-4095 |
2.3 VID的特殊值
| VID值 | 含义 | 用途 |
|---|---|---|
| 0 | 空VLAN | 仅携带优先级信息,不表示VLAN成员资格 |
| 1 | 默认VLAN | 交换机默认VLAN |
| 2-4094 | 正常VLAN | 用户可配置的VLAN |
| 4095 | 保留VLAN | 保留,不使用 |
三、VLAN类型详解
3.1 基于端口的VLAN(Port-based VLAN)
最常用的VLAN类型,根据交换机端口划分VLAN。
特点:
- 配置简单
- 端口与VLAN静态绑定
- 适合网络结构稳定的环境
示例:
交换机配置:
Port 1-4 → VLAN 10 (研发部)
Port 5-8 → VLAN 20 (市场部)
Port 9-12 → VLAN 30 (财务部)
3.2 基于MAC地址的VLAN
根据设备的MAC地址划分VLAN。
特点:
- 用户移动时VLAN归属不变
- 配置复杂,需要维护MAC-VLAN映射表
- 适合移动办公环境
3.3 基于协议的VLAN
根据帧中的协议类型划分VLAN。
示例:
IPv4帧 → VLAN 10
IPv6帧 → VLAN 20
IPX帧 → VLAN 30
3.4 QinQ(双层VLAN)
应用场景:运营商网络,实现用户VLAN和运营商VLAN的分离。
帧结构:
+----------+----------+--------+--------+--------+----------+
| Dst MAC | Src MAC | 0x88A8 | S-TCI | 0x8100 | C-TCI |
+----------+----------+--------+--------+--------+----------+
| Type | Payload | FCS |
+----------+----------+--------+
字段说明:
- S-TCI:外层VLAN标签(Service VLAN,运营商VLAN)
- C-TCI:内层VLAN标签(Customer VLAN,用户VLAN)
四、SVT Ethernet VIP中构造VLAN报文
4.1 VLAN帧类型定义
在SVT Ethernet VIP中,VLAN帧类型定义如下:
systemverilog
// 帧类型枚举
typedef enum {
ETH_MAC_DATA_FRAME, // 普通数据帧
ETH_MAC_CONTROL_FRAME, // 控制帧
ETH_MAC_VLAN_FRAME, // VLAN帧
ETH_MAC_STACKED_VLAN_FRAME, // 堆叠VLAN帧(QinQ)
ETH_MAC_JUMBO_DATA_FRAME, // Jumbo数据帧
ETH_MAC_JUMBO_VLAN_FRAME, // Jumbo VLAN帧
ETH_MAC_JUMBO_STACKED_VLAN_FRAME // Jumbo堆叠VLAN帧
} eth_mac_frame_type_enum;
4.2 构造单层VLAN帧
示例代码:
systemverilog
class vlan_frame_sequence extends svt_ethernet_sequence;
`uvm_object_utils(vlan_frame_sequence)
function new(string name = "vlan_frame_sequence");
super.new(name);
endfunction
task body();
svt_ethernet_transaction trans;
// 创建VLAN帧
trans = svt_ethernet_transaction::type_id::create("trans");
// 设置帧类型为VLAN帧
trans.command = ETH_MAC_VLAN_FRAME;
// 设置MAC地址
trans.address = 48'h00_11_22_33_44_55; // 目的MAC
trans.source = 48'h66_77_88_99_AA_BB; // 源MAC
// 设置VLAN标签
trans.vlan_tpid = 16'h8100; // 标准TPID
trans.vlan_tci = 16'h000A; // VLAN ID = 10
// 或者分别设置VLAN字段
trans.vlan_priority = 3'h5; // 优先级 = 5
trans.vlan_cfi = 1'b0; // CFI/DEI = 0
trans.vlan_id = 12'd10; // VLAN ID = 10
// 设置载荷
trans.payload = new[100];
foreach(trans.payload[i])
trans.payload[i] = $urandom;
// 发送帧
start_item(trans);
trans.randomize();
finish_item(trans);
endtask
endclass
4.3 构造双层VLAN帧(QinQ)
示例代码:
systemverilog
class qinq_frame_sequence extends svt_ethernet_sequence;
`uvm_object_utils(qinq_frame_sequence)
task body();
svt_ethernet_transaction trans;
trans = svt_ethernet_transaction::type_id::create("trans");
// 设置帧类型为堆叠VLAN帧
trans.command = ETH_MAC_STACKED_VLAN_FRAME;
// 设置MAC地址
trans.address = 48'h00_11_22_33_44_55;
trans.source = 48'h66_77_88_99_AA_BB;
// 外层VLAN(运营商VLAN)
trans.outer_vlan_tpid = 16'h88A8; // QinQ TPID
trans.outer_vlan_tci = 16'h0064; // S-VID = 100
trans.outer_vlan_priority = 3'h7;
trans.outer_vlan_cfi = 1'b0;
trans.outer_vlan_id = 12'd100;
// 内层VLAN(用户VLAN)
trans.inner_vlan_tpid = 16'h8100; // 标准TPID
trans.inner_vlan_tci = 16'h000A; // C-VID = 10
trans.inner_vlan_priority = 3'h3;
trans.inner_vlan_cfi = 1'b0;
trans.inner_vlan_id = 12'd10;
// 设置载荷
trans.payload = new[100];
foreach(trans.payload[i])
trans.payload[i] = $urandom;
start_item(trans);
trans.randomize();
finish_item(trans);
endtask
endclass
4.4 构造带优先级的VLAN帧
示例代码:
systemverilog
class priority_vlan_frame_sequence extends svt_ethernet_sequence;
`uvm_object_utils(priority_vlan_frame_sequence)
task body();
svt_ethernet_transaction trans;
trans = svt_ethernet_transaction::type_id::create("trans");
trans.command = ETH_MAC_VLAN_FRAME;
trans.address = 48'h00_11_22_33_44_55;
trans.source = 48'h66_77_88_99_AA_BB;
// 设置高优先级VLAN帧
trans.vlan_tpid = 16'h8100;
trans.vlan_priority = 3'h7; // 最高优先级
trans.vlan_cfi = 1'b0;
trans.vlan_id = 12'd10;
// 设置IP数据报文
trans.ether_type = 16'h0800; // IPv4
// ... 设置IP头和载荷
start_item(trans);
trans.randomize();
finish_item(trans);
endtask
endclass
五、VIP配置VLAN功能
5.1 配置VLAN过滤
在DWC Ethernet QoS MAC中配置VLAN过滤:
systemverilog
class test_env extends uvm_env;
svt_ethernet_agent agent;
function void build_phase(uvm_phase phase);
svt_ethernet_agent_configuration cfg;
super.build_phase(phase);
// 创建配置对象
cfg = svt_ethernet_agent_configuration::type_id::create("cfg");
// 启用VLAN过滤
cfg.enable_vlan_filter = 1'b1;
// 配置VLAN过滤表
cfg.vlan_filter_table = '{
'{vid: 10, valid: 1'b1}, // 允许VLAN 10
'{vid: 20, valid: 1'b1}, // 允许VLAN 20
'{vid: 30, valid: 1'b1}, // 允许VLAN 30
default: '{vid: 0, valid: 1'b0} // 其他VLAN拒绝
};
// 设置配置
uvm_config_db#(svt_ethernet_agent_configuration)::set(
this, "agent", "cfg", cfg);
agent = svt_ethernet_agent::type_id::create("agent", this);
endfunction
endclass
5.2 配置VLAN标签处理
配置VLAN标签的剥离和插入:
systemverilog
// 配置接收端VLAN处理
cfg.rx_vlan_strip_enable = 1'b1; // 剥离接收帧的VLAN标签
// 配置发送端VLAN处理
cfg.tx_vlan_insert_enable = 1'b1; // 在发送帧中插入VLAN标签
cfg.default_vlan_id = 12'd10; // 默认VLAN ID
5.3 配置QinQ处理
systemverilog
// 启用QinQ支持
cfg.enable_qinq = 1'b1;
// 配置外层VLAN TPID
cfg.outer_vlan_tpid = 16'h88A8; // 运营商VLAN TPID
// 配置内层VLAN TPID
cfg.inner_vlan_tpid = 16'h8100; // 用户VLAN TPID
5.4 配置VLAN优先级映射
将VLAN优先级映射到队列:
systemverilog
// 优先级到队列的映射
cfg.priority_to_queue_map = '{
3'h0 => 0, // 优先级0 → 队列0
3'h1 => 0, // 优先级1 → 队列0
3'h2 => 1, // 优先级2 → 队列1
3'h3 => 1, // 优先级3 → 队列1
3'h4 => 2, // 优先级4 → 队列2
3'h5 => 2, // 优先级5 → 队列2
3'h6 => 3, // 优先级6 → 队列3
3'h7 => 3 // 优先级7 → 队列3
};
六、DWC Ethernet QoS中的VLAN特性
6.1 VLAN过滤功能
DWC Ethernet QoS MAC支持以下VLAN过滤特性:
- VLAN ID过滤:根据VID过滤帧
- VLAN优先级过滤:根据PCP过滤帧
- VLAN标签存在性检查:检查帧是否包含VLAN标签
寄存器配置:
c
// 启用VLAN过滤
MAC_VLAN_TAG_FILTER_ENABLE = 0x1;
// 配置VLAN过滤表
VLAN_FILTER_TABLE[0] = {
.vid = 10,
.valid = 1,
.priority = 0 // 不检查优先级
};
VLAN_FILTER_TABLE[1] = {
.vid = 20,
.valid = 1,
.priority = 5 // 仅接受优先级为5的帧
};
6.2 VLAN标签剥离与插入
接收路径:
- 可配置是否剥离VLAN标签
- 剥离的VLAN信息保存在描述符中
发送路径:
- 可配置是否自动插入VLAN标签
- VLAN信息从描述符中获取
6.3 VLAN Filter Fail Packets Queue
特性:VLAN过滤失败的帧可以被路由到特定队列,而不是直接丢弃。
配置示例:
c
// 启用VLAN过滤失败队列
MAC_VLAN_FILTER_FAIL_QUEUE_ENABLE = 0x1;
// 设置失败队列编号
MAC_VLAN_FILTER_FAIL_QUEUE = 7; // 路由到队列7
应用场景:
- 监控不符合VLAN过滤规则的帧
- 调试和故障诊断
- 安全审计
七、实战:完整的VLAN测试用例
7.1 测试场景设计
systemverilog
class vlan_test extends uvm_test;
`uvm_component_utils(vlan_test)
// 测试场景
// 1. 发送不同VLAN ID的帧
// 2. 验证VLAN过滤功能
// 3. 验证优先级处理
// 4. 验证QinQ处理
task run_phase(uvm_phase phase);
phase.raise_objection(this);
// 场景1:单层VLAN帧测试
test_single_vlan();
// 场景2:双层VLAN帧测试
test_qinq_vlan();
// 场景3:VLAN过滤测试
test_vlan_filter();
// 场景4:优先级测试
test_vlan_priority();
phase.drop_objection(this);
endtask
task test_single_vlan();
svt_ethernet_transaction trans;
for(int vid = 1; vid <= 10; vid++) begin
trans = create_vlan_frame(vid);
send_frame(trans);
check_frame_received(trans);
end
endtask
function svt_ethernet_transaction create_vlan_frame(int vid);
svt_ethernet_transaction trans;
trans = svt_ethernet_transaction::type_id::create("trans");
trans.command = ETH_MAC_VLAN_FRAME;
trans.address = 48'h00_11_22_33_44_55;
trans.source = 48'h66_77_88_99_AA_BB;
trans.vlan_id = vid;
trans.vlan_priority = 3'h5;
return trans;
endfunction
endclass
八、面试常见问题与解答
Q1: VLAN标签在以太网帧的什么位置?
答:VLAN标签插入在源MAC地址和类型/长度字段之间,共4字节(TPID 2字节 + TCI 2字节)。
Q2: 为什么VLAN ID最大是4094?
答:VLAN ID字段为12位,理论范围是0-4095。但VID 0表示仅携带优先级信息,VID 4095保留,所以可用VLAN ID范围是1-4094。
Q3: 什么是VLAN的PCP字段?有什么作用?
答:PCP(Priority Code Point)是3位优先级字段,用于QoS。取值范围0-7,值越大优先级越高。交换机可以根据PCP值将帧分配到不同优先级的队列。
Q4: QinQ双层VLAN的应用场景是什么?
答:QinQ主要用于运营商网络:
- 外层VLAN(S-VID):标识运营商的网络
- 内层VLAN(C-VID):标识用户的VLAN
- 实现用户VLAN和运营商VLAN的分离,支持多达4094×4094个VLAN
Q5: Access端口、Trunk端口和Hybrid端口有什么区别?
答:
| 端口类型 | 说明 | PVID | 允许VLAN |
|---|---|---|---|
| Access | 连接终端设备 | 有 | 仅允许一个VLAN |
| Trunk | 连接交换机 | 有 | 允许多个VLAN |
| Hybrid | 灵活配置 | 有 | 可配置 tagged/untagged |
处理规则:
- Access端口:接收untagged帧添加PVID标签,发送时剥离标签
- Trunk端口:仅允许native VLAN的帧untagged,其他VLAN必须tagged
- Hybrid端口:可配置每个VLAN是否tagged
Q6: VLAN 0有什么特殊含义?
答:VLAN 0表示"空VLAN",帧中包含VLAN标签但VID=0。这种帧仅用于携带优先级信息(PCP字段),不表示VLAN成员资格。常用于需要QoS但不需要VLAN隔离的场景。
Q7: 如何计算VLAN标签帧的FCS?
答:FCS(Frame Check Sequence)计算范围包括:
- 目的MAC地址
- 源MAC地址
- VLAN标签(TPID + TCI)
- 类型/长度
- 有效载荷
注意:VLAN标签包含在FCS计算范围内。
Q8: 什么是VLAN跳跃攻击?如何防范?
答:VLAN跳跃攻击是一种网络攻击方式:
攻击原理:
- 发送带有双重VLAN标签的帧
- 第一层交换机剥离外层标签
- 第二层交换机将内层标签当作真实VLAN处理
- 实现跨VLAN通信
防范措施:
- 禁用Trunk端口的native VLAN
- 将native VLAN设置为未使用的VLAN ID
- 严格配置VLAN过滤规则
- 启用端口安全特性
Q9: 在SVT Ethernet VIP中如何验证VLAN功能?
答:验证VLAN功能需要测试以下场景:
-
VLAN标签正确性:
- 验证TPID、TCI字段值
- 验证VID、PCP、DEI字段解析
-
VLAN过滤功能:
- 发送允许的VLAN帧,验证通过
- 发送禁止的VLAN帧,验证被过滤
-
VLAN标签处理:
- 验证标签剥离功能
- 验证标签插入功能
-
QinQ功能:
- 验证双层VLAN标签处理
- 验证内外层VLAN独立性
-
优先级处理:
- 验证PCP到队列的映射
- 验证优先级调度
Q10: DWC Ethernet QoS MAC的VLAN特性有哪些?
答:DWC Ethernet QoS MAC支持丰富的VLAN特性:
-
VLAN过滤:
- 基于VID过滤
- 基于优先级过滤
- VLAN过滤失败队列
-
VLAN标签处理:
- 接收端标签剥离
- 发送端标签插入
- 支持QinQ
-
高级特性:
- VLAN标签在MACsec帧中的位置可配置
- 支持VLAN标签重写
- 支持VLAN统计
九、总结
核心要点回顾
-
VLAN标签结构:TPID(2B) + TCI(2B),TCI包含PCP(3b)、DEI(1b)、VID(12b)
-
VLAN类型:单层VLAN、QinQ、基于端口/MAC/协议的VLAN
-
VIP构造方法 :使用
ETH_MAC_VLAN_FRAME和ETH_MAC_STACKED_VLAN_FRAME类型 -
VIP配置:VLAN过滤、标签处理、优先级映射
-
DWC特性:VLAN过滤失败队列、灵活的标签处理
最佳实践建议
-
设计阶段:
- 合理规划VLAN ID范围
- 考虑QoS需求,规划优先级
- 预留VLAN用于管理和其他用途
-
验证阶段:
- 全面测试VLAN过滤功能
- 测试边界情况(VID 0、4095)
- 性能测试(大量VLAN帧处理)
-
调试技巧:
- 使用VLAN过滤失败队列捕获异常帧
- 检查VLAN标签的FCS计算
- 验证优先级到队列的映射
参考资料
- IEEE 802.1Q Standard
- Synopsys DesignWare Cores Ethernet Quality-of-Service Databook
- SVT Ethernet VIP User Guide
- SVT Ethernet Transaction Class Reference
作者注:本文基于DesignWare Ethernet QoS Databook和SVT Ethernet VIP文档编写,旨在帮助深入理解VLAN技术及其在验证环境中的应用。如有疑问,欢迎留言讨论。
关键词:VLAN、IEEE 802.1Q、QinQ、SVT Ethernet VIP、DWC Ethernet QoS、网络验证