第四章:链路层测试——MAC地址学习与老化、VLAN转发规则验证、流控(PFC/802.3x)测试

链路层测试,说白了就是验证你的芯片能不能像个合格的“交通警察”一样,管好数据帧的进出。MAC地址学习、VLAN隔离、流控机制,这三板斧砍下来,基本能看出芯片的底子硬不硬。

我个人习惯把链路层测试分成三个维度:转发正确性表项管理拥塞控制。咱们一个一个来聊。

4.1 MAC地址学习与老化测试

MAC地址学习,是交换芯片最基础的功能。你想想看,芯片得知道哪个MAC在哪个端口上,才能把数据帧准确送过去。这个机制要是出问题,整个网络就乱套了。

4.1.1 学习功能验证

测试思路很简单:从端口A发一个源MAC为M1的帧,然后查芯片的MAC表,看M1是不是关联到了端口A。

我在项目中遇到过一个问题:芯片学习到了MAC,但老化时间不对。默认300秒,结果60秒就清掉了。后来发现是硬件定时器的分频系数配错了。

核心测试用例:

  • 基础学习:从不同端口发送不同源MAC,验证表项正确性
  • MAC迁移:同一个MAC从不同端口出现,验证表项更新
  • 广播抑制:大量MAC同时学习,验证表项容量和性能
// 测试脚本伪代码
send_frame(port=0, src_mac="00:11:22:33:44:01", dst_mac="ff:ff:ff:ff:ff:ff")
sleep(100ms)
mac_entry = read_mac_table("00:11:22:33:44:01")
assert(mac_entry.port == 0, "MAC学习失败")

// 测试MAC迁移
send_frame(port=1, src_mac="00:11:22:33:44:01", dst_mac="ff:ff:ff:ff:ff:ff")
sleep(100ms)
mac_entry = read_mac_table("00:11:22:33:44:01")
assert(mac_entry.port == 1, "MAC迁移失败")

4.1.2 老化机制验证

老化测试,说白了就是看芯片能不能按时把“过时”的表项清掉。嗯,这里要注意:老化时间不能太短,否则频繁刷新浪费资源;也不能太长,否则表项占着茅坑不拉屎。

我的经验: 老化测试最好用自动化脚本跑,设置不同的老化时间(比如60s、120s、300s),然后发帧、等待、再发帧,看表项是否按预期老化。我曾经踩过一个坑:芯片在老化过程中,如果同时有新的MAC学习请求,会触发死锁。后来加了超时保护才解决。

测试项 预期结果 实际结果
老化时间=60s,60s内无流量 表项清除 通过
老化时间=60s,30s时有流量 表项保留,老化计时器重置 通过
老化时间=0(禁用老化) 表项永久保留 通过

4.2 VLAN转发规则验证

VLAN测试,核心就一句话:同一个VLAN内的帧能互通,不同VLAN的帧不能互通。但实际测试中,细节多得很。

4.2.1 基于端口的VLAN

这是最基础的VLAN模式。把端口划分到不同VLAN,然后验证隔离性。

我记得有一次测试,端口配置了VLAN 10,但帧就是转发不过去。查了半天,发现是端口的PVID没配。你想想看,芯片收到不带VLAN标签的帧,得知道它属于哪个VLAN,PVID就是干这个的。

常见坑点:

  • PVID和允许通过的VLAN列表要同时配置
  • Trunk端口要配置Tagged模式,Access端口配Untagged模式
  • VLAN 1是默认VLAN,很多芯片会特殊处理

4.2.2 基于802.1Q的VLAN

带标签的VLAN测试,要验证Tag的添加、删除、替换逻辑。我建议用抓包工具同时看入口和出口的报文,对比Tag字段的变化。

// VLAN转发测试用例
// 测试1:同VLAN内互通
configure_port(port0, pvid=10, allowed_vlans=[10])
configure_port(port1, pvid=10, allowed_vlans=[10])
send_frame(port0, vlan_tag=None)  // 不带Tag
// 预期:port1收到帧,且带VLAN 10的Tag

// 测试2:不同VLAN隔离
configure_port(port0, pvid=10, allowed_vlans=[10])
configure_port(port1, pvid=20, allowed_vlans=[20])
send_frame(port0, vlan_tag=None)
// 预期:port1不会收到帧

// 测试3:Trunk端口转发
configure_port(port0, mode="trunk", allowed_vlans=[10, 20])
send_frame(port0, vlan_tag=10)
// 预期:只有属于VLAN 10的端口能收到

4.3 流控测试(PFC / 802.3x)

流控测试,是验证芯片在拥塞时能不能“踩刹车”。802.3x是全局流控,PFC是优先级流控。我个人觉得PFC更实用,也更难测。

4.3.1 802.3x 全局流控

802.3x通过PAUSE帧实现。当接收端缓存快满时,发送PAUSE帧给发送端,让对方暂停发送。

测试方法:构造一个拥塞场景,比如让多个端口往同一个端口发数据,然后看芯片是否发出了PAUSE帧。

测试步骤:

  1. 配置端口A为接收端,端口B、C为发送端
  2. 端口B、C以线速向端口A发送数据
  3. 监控端口A的出口,看是否发出PAUSE帧
  4. 验证PAUSE帧的MAC地址(目的MAC为01:80:C2:00:00:01)

4.3.2 PFC 优先级流控

PFC(Priority Flow Control)是802.1Qbb标准,它把流量分成8个优先级,每个优先级独立流控。这在RoCEv2网络中特别重要。

我曾经在测试PFC时遇到一个诡异问题:高优先级流量把低优先级流量饿死了。后来发现是PFC的阈值配置不合理,高优先级占用了太多缓存。

PFC测试要点:

  • 验证每个优先级独立流控,互不影响
  • 测试PFC死锁场景:两个端口互相发送PFC帧
  • 验证PFC帧的格式:Opcode、Time参数是否正确
  • 测试PFC恢复:拥塞解除后,流量是否恢复正常
// PFC测试伪代码
// 配置端口A的优先级3开启PFC
configure_pfc(port=0, priority=3, enable=True)

// 构造拥塞:端口B以线速向端口A发送优先级3的流量
start_traffic(src_port=1, dst_port=0, priority=3, rate="line_rate")

// 等待PFC触发
sleep(500ms)
pfc_frame = capture_pfc_frame(port=0)
assert(pfc_frame.priority == 3, "PFC优先级错误")
assert(pfc_frame.time > 0, "PFC Time参数为0")

// 停止流量,验证恢复
stop_traffic()
sleep(200ms)
assert(no_pfc_frame_captured(), "PFC未正常恢复")

4.4 本章小结

链路层测试,说白了就是验证芯片的“记忆力”和“规则意识”。MAC地址学习看芯片记不记得住,VLAN转发看芯片守不守规矩,流控测试看芯片懂不懂刹车。

我建议你在测试时,多关注边界条件:表项满了怎么办?老化时间到了但还有流量怎么办?PFC帧丢了怎么办?这些才是真正考验芯片设计的地方。

核心要点回顾:

  • MAC学习:验证学习、迁移、老化三个核心机制
  • VLAN转发:验证隔离性、Tag处理、PVID配置
  • 流控测试:802.3x全局流控 + PFC优先级流控
  • 边界条件:表项满、老化冲突、PFC死锁
链路层测试知识体系 MAC地址学习与老化 VLAN转发规则验证 流控测试 基础学习与迁移 老化时间验证 表项容量测试 基于端口VLAN 802.1Q Tag处理 隔离性验证 802.3x PAUSE帧 PFC优先级流控 死锁与恢复测试 核心目标:验证芯片的转发正确性、表项管理能力、拥塞控制机制

专注资料整理