学习内容:
在Basic Forwarding实验的基础上扩展ECN功能。
关于ECN的概念可以参考:RoCE网络
简单来说,Host1的IPv4报文携带ECN置位(01或者10),如果Switch队列长度达到了阈值时,Switch会将ECN位重新置位为11。Host2收到ECN置位11后,会发送CNP报文通知Host1降速。从而达到拥塞避免的效果。
我们这次的实验只能体现出Switch拥塞置位ECN。
和之前的实验一样,我们只关注数据平面的逻辑。控制平面已经提前定义好了。
步骤1:运行不完整的开始代码
在tutorials/exercises/ecn目录下的ecn.p4是一个程序的框架。初始是L3 forwarding,后续我们要做的是扩展它的ECN功能。
- 在终端输入
sudo make run
这步操作包括:
- 编译ecn.p4
- 开启mininet实例如图组网
- 配置相应的IP
- 每个Switchde 的控制平面依据sx-runtime.json 加载(x代表Switch 编号)。
2. h1到h2发送低速流量,h11到h22通过iperf发送高速流量。s1和s2之间的链路限速512kbps。这时在h2抓包观察ECN的置位情况。
- 在mininet视图下打开h1,h11,h2,h22
xterm h1 h11 h2 h22
- 在h2的窗口,开启server端收包
./receive.py > h2.log
- 在h22的窗口,开启iperf UDP server
iperf -s -u
- 在h1的窗口,发送数据包,每秒1个包,发送30秒
./send.py 10.0.2.2 "P4 is cool" 30
- 在h11的窗口,开启iperf客户端发送udp 15秒
iperf -c 10.0.2.22 -t 15 -u
- 在h2,打开h2.log可以看到ipv4.tos的字段(DiffServ+ECN)总是1
- exit,退出XTerm 窗口。
步骤2:实施ECN
ecn.p4是一个框架,我们需要把代码中TODO部分替换。
首先,我们把ipv4_t header 的TOS字段拆分为DiffServ和ECN两部分。记住更新checksum块。
然后,在ingress control我们必须检查队列长度的ECN阈值。如果队列长度大于阈值,则ECN置位。
注意:这个逻辑只有在Host通过设定原始ECN为01或10来声明支持ECN时才能生效。
完整的ecn.p4将包括以下部分:
- Ethernet (ethernet_t)和 IPv4 (ipv4_t)的Header Type定义。
- 解析Ethernet和IPv4。
- 丢弃报文的action,mark_to_drop() 。
- ipv4_forward的action:
为下一跳设置出接口
更新目的Mac为下一跳的Mac
更新源Mac为Switch的Mac
减TTL - egress control检查ECN和standard_metadata.enq_qdepth,设置ipv4.ecn 。
- 将字段按顺序恢复的逆解析
- parser,control,checksum verification,deparser的包实例化。
拆分TOS
检查ECN阈值,判断是否置位
步骤3:运行解决方案
修改好ecn,p4文件,然后重复步骤1的操作。如果执行有问题可以参照solution目录下的正确的答案。
这时我们能看到ECN是被置位成了0x3(二进制的11),说明此时Switch缓存达到了阈值。