技术手册- 显示拥塞通知ECN
近期文章
名词解释
ECN(Explicit Congestion Notification,显示拥塞通知)是一种基于流的端到端流控技术,保证实现端到端的拥塞控制,在交换机出口(Egress port)拥塞时,对数据包做ECN标记,并让流量发送端降低发送速率来保证网络的可靠性。
背景
在传统网络中TCP 实现将TCP 端节点之间的中间网络视为一个不透明的“黑盒”。TCP 包进入和流出这个盒子,有些时候因为路由器的拥塞发生了丢包,这样路由器会静默地丢弃接下来进入的包。尽管TCP可以检测到TCP包的丢失并且进行重传,但是从TCP处理过程,重传过程和吞吐率下降这些方面看,这个重传过程将会耗费很大。
为了避免因为路由器拥塞而带来的丢包而产生的一系列问题,TCP/IP的设计者们创建了一些用于主机和路由器的标准。这些标准描述了在IP路由器上进行的主动队列管理算法(AQM)(RFC 2309),使得路由器能够监控转发队列的状态,以提供一个路由器向发送端报告发生拥塞的机制,让发送端在路由器开始丢包前降低发送速率。这种路由器报告和主机响应机制被称为显式拥塞通知(ECN)。
工作原理
ECN需要主动队列管理AQM策略结合才能发挥作用。路由器在队列溢出前检测到拥塞,在IP报头中设置Congestion Experienced (CE) Codepoint代码点来指示正在发生拥塞。
IP层对ECN的支持
在网络层一个发送主机必须能够表明自身能支持ECN与否,路由器在转发时必须能够表明它正在经历拥塞。ECN 使用 IPv4 首部或 IPv6 首部中 ToS (Type of Service,位于首部第 9 到 16 比特位) 字段的两个最低有效位(最右侧的位编码)来表示四个状态码。
IP 报文头部中的DSCP 字段有2 Bit 用于标识ECN。这2 个Bit 分别是:ECT(ECN Capable Transport)用来标识发送端设备是否支持ECN功能和CE(Congestion Experienced)用于标识报文在传输路径上是否经历过拥塞。
图1:IP Header中的ECN Bit
- 当ECT为0,CE为0时,表示IP报文不支持ECN
- 当ECT为0,CE为1时,表示IP报文支持ECN
- 当ECT为1,CE为0时,表示IP报文支持ECN
- 当ECT为1,CE为1时,表示IP报文支持ECN,且发生了拥塞
当两端支持 ECN 时,它将数据包标为 ECT(0) 或 ECT(1)。如果分组穿过一个遇到阻塞并且相应路由器支持 ECN 的活动队列管理(AQM)队列,它可以将代码点更改为CE而非丢包。这种行为就是“标记”,其目的是通知接收端即将发生拥塞。在接收端,该拥塞指示由上层协议(传输层协议)处理,并且需要将信号回传给发送端,以通知其降低传输速率。
因为 CE 指示只能由支持它的上层协议有效处理,ECN 只能配合上层协议使用。例如 TCP 协议,它支持阻塞控制并且有方法将 CE 指示回传给发送端。
IP层ECN报文交互
ECN 是报文在网络设备出口发生拥塞时,将使能ECN(当IP 报文的ECN 字段为01 或10,表示使能ECN)的IP 报文头部的ECN 字段标记ECN=11,表示该IP 报文遇到网络拥塞,且该IP 报文不会被WRED 机制丢弃。如果接收服务器发现IP 报文的ECN 字段被标记成11,就立刻产生CNP 拥塞通知报文,并将该报文发送带源服务器,CNP 消息里包含了拥塞的数据流信息,远端服务器接收到后,通过降低相应的数据流发送速率,环节网络设备拥塞,从而避免发生丢包。
- 发送端发送IP 报文标记ECN(ECN=10)
- 交换机在队列拥塞的情况下收到该报文,将ECN 字段修改为11 并转发出去
- 接收服务器收到ECN 为11 的报文发送拥塞,正常处理该报文
- 接收端产生拥塞通告,周期发送CNP(Congestion Notification Packets)报文,ECN字段为01,要求报文不能被网路丢弃
- 交换机收到CNP 报文后正常转发该报文
- 发送服务器收到ECN 标记为01 的CNP 报文解析后对相应的数据流限速算法
CNP报文格式
CNP作为拥塞控制报文,也会存在延迟和丢包,从发送端到接收端经过的每一跳设备、每一条链路都会有一定的延迟,会最终加大发送端接收到CNP的时间,而与此同时交换机端口下的拥塞也会逐步增多,若发送端不能及时降速,仍然可能造成丢包。建议拥塞通告域的规模不要过大,从而避免因为ECN控制报文交互回路的跳数过多,而影响发送端无法及时降速,造成拥塞。
图3:CNP协议报文格式
TCP层对ECN的支持
TCP支持使用TCP头中的三个标记来支持ECN。第一个标记是随机和(Nonce Sum,简称NS),用于防止TCP发送者的数据包标记被意外或恶意改动。另两位用于回传拥塞指示和确认接收到了拥塞指示回应。这即是ECN-Echo(ECE)和Congestion Window Reduced(CWR)位,图4为TCP Header中的CWR和ECE flag。
图4:TCP Header中的CWR和ECE flag
- TCP SYN握手包会包含两个额外的flag: ECN-echo(ECE)和Congestion Window Reduced (CWR) 。这样双方就可以协商在数据传输期间是否可以正确的处理设置了CE位的数据包。
- 发送方在所有发送的数据包中设置ECN Capable Transport (ECT) 位。
- 如果发送方收到一个TCP数据包,报头中设置了ECE flag,则发送方将调整其拥塞窗口,就像它从丢失的数据包中快速恢复一样。发送方下一个数据包设置CWR flag,向接收方表明它已对拥塞做出反应。发送方在每个RTT间隔最多做出一次这种反应。
- 当接收方接收到设置了CE 位的数据包时,接收方将在所有数据包中设置 ECE flag。这将一直持续到它收到一个设置了CWR flag的数据包,表明发送方已经对拥塞做出了反应。 ECT 标志仅在包含数据有效载荷的数据包中设置。发送不包含数据有效载荷的 TCP ACK 数据包时,应清除 ECT 位。
TCP层ECN报文交互
当在一个TCP连接上协商ECN后,发送方指示连接上的TCP段携带IP分组传输流量,将支持ECN的传输用ECT码点标记。这使支持ECN的中间路由器可以标记具有CE码点的IP分组而不是丢弃它们,以指示即将发生的阻塞。
当接收到具有遇到阻塞码点时,TCP接收者使用TCP头中的ECE标记回传这个阻塞指示。当一个端点收到TCP带有ECE位的段时,它减少其拥塞窗口来代替丢包。然后,它设置段的CWR位来确认阻塞指示。节点保持传输设置有ECE位的TCP段,直到它接收到设置有CWR的段。
图5:TCP层ECN报文交互示意图
- 发送端主机发送Segment 1-5到接收端,这些Segment全部都设置了ECT
- Segment 2由遇到阻塞的支持ECN的路由器转发,路由器将IP头设置CE代码点,这里检测到拥塞后的策略并不是直接丢弃数据包
- 接收端收到Sgement 2后,它会发送带有ECE flag的ACK
- 交换机收到报文后正常转发该报文
- 发送端收到带有ECE flag的第一个ACK时,它会降低其传输速率并发送带有CWR flag的下一个Segmemt 6,就好像检测到了丢包一样。同时接收端收到Segment 6后,因为已经解除拥塞所以发送的后续ACK将清除ECE flag
两个ECT Codepoints机制
- 在RFC2481中,ECN字段被分为ECN-Capable Transport(ECT) bit和CE bit。ECT对应着ECT(0) codepoint。ECT(1)在RFC2481中没有定义,所以在只支持单个ECT codepoint的时候,应该使用ECT(0)。
- 在RFC3168中,两个ECT codepoint的主要动机是提供一位ECN nouce随机数,路由器在设置CE codepoint时必须“擦除”这个随机数(擦除 CE codepoint的路由器在重建原始随机数时将面临额外的困难,因此终端节点更有可能检测到CE codepoint的重复擦除)。ECN nouce允许为发送方提供一种机制,验证网络元素没有擦除掉CE,并且接收方正确地向发送方报告接收到了带有CE codepoint的数据包。
- 发送方检测有缺陷网络元素的另一种方法是不定期的发送CE codepoint数据包,以查看接收方是否报告接收到。如果这些数据包在网络中遇到拥塞,路由器可能不会更改数据包,因为 CE codepoint已经设置,所以发送方无法确定路由器是否打算在这些数据包中设置 CE codepoint。 并且与ECN随机数相比,对有缺陷网络元素和接收器的检查效率较低。
- TCP设置ECN的规则
- 如果Host收到过ECN-setup SYN packet,那么它才能发送ECN-setup SYN-ACK packet
- Host不能在packet上设置ECT,除非它已发送过ECN-setup SYN或ECN-setup SYN-ACK packet,并且已收到过ECN-setup SYN或ECN-setup SYN-ACK packet,并且没有发送过non-ECN-setup SYN 或non-ECN-setup SYN-ACK packet
- 如果Host收到过non-ECN-setup SYN或non-ECN-setup SYN-ACK packet,则它不应在packet上设置 ECT
- 如果Host曾在packet上设置ECT,则它必须正确设置/清除连接中所有后续packet中的CWR TCP bit
- 如果Host发送过ECN-setup SYN 或 ECN-setup SYN-ACK packet,并且没有收到 non-ECN-setup SYN 或 non-ECN-setup SYN-ACK packet。那么如果Host收到ECT 和CE设置了的packet,那么它必须按照支持ECN连接指定的方式处理这些packet
- Host如果不愿意在TCP连接上使用ECN,则它应该清除packet中的ECE和CWR标志
- Host不能在SYN 或SYN-ACK packet上设置 ECT
Fast ECN
当交换机队列中缓存数据包超过ECN阈值时,交换机会将拥塞信息标记报文的ECN字段,并携带到发送端服务器以通知其网络拥塞。接收端服务器接收到带有ECN字段的数据包后,发送CNP通知发送端服务器调整发送速率。
图6:传统ECN处理机制
如上图所示,当数据报文进入队列排队时,传统的显式拥塞通知(ECN)判断队列使用的缓存是否超过ECN阈值。如果超过ECN阈值,交换机将数据报文IP头部中的ECN字段标记为11。发送端服务器接收带有ECN字段标记的数据报文的时间为交换机队列的数据包转发时间加上网络中标记的数据包转发时间。如果网络存在严重的网络拥塞,则ECN的反馈不及时可能会加剧队列拥塞。
图7:Fast ECN处理机制
Fast ECN通过在数据报文出队列时,标记数据报文的ECN字段,从而缩短了入队列标记ECN的数据包转发时延,接收端服务器可以在最小的时延接收到ECN标记的数据报文,从而加快发送端速率的调整。
配置实例
网络拓扑
图8:ECN物理网络拓扑
服务器端配置
Server1
[root@server1 ~]# modprobe 8021q
[root@server1 ~]# vconfig add ens1f3 100
[root@server1 ~]# ifconfig ens1f3.100 1.1.1.2/24 up
[root@server1 ~]# route add -net 1.1.0.0 netmask 255.255.0.0 gw 1.1.1.1
Server2
[root@server2 ~]# modprobe 8021q
[root@server2 ~]# vconfig add ens1f3 200
[root@server2 ~]# ifconfig ens1f3.200 1.1.2.2/24 up
[root@server2 ~]# route add -net 1.1.0.0 netmask 255.255.0.0 gw 1.1.2.1
交换机端配置
配置CISCO-LIKE命令行
在交换机配置时,需要先配置CLI模式。然后进入CISCO-LIKE视图,使用CISCO-LIKE命令行进行配置操作。
admin@sonic:~$ sudo config cli-mode cli
admin@sonic:~$ sudo sonic-cli
sonic#
交换机A
sonic# configure terminal
sonic(config)# vlan 100
sonic(config)# vlan 200
sonic(config)# interface ethernet 0/9
sonic(config-if-0/0)# switchport trunk vlan 100
sonic(config)# interface ethernet 0/10
发送流量包
发送流量包
sonic(config-if-0/0)# switchport trunk vlan 200
sonic(config)# interface vlan 100
sonic(config-vlanif-100)# ip address 1.1.1.1/24
sonic(config)# interface vlan 200
sonic(config-vlanif-100)# ip address 1.1.2.1/24
Server1和Server2配置了Mellanox网卡,在Server2建立服务端,Server1建立客户端发送IB流量。
Server2:
[root@server3 ~]# ib_send_bw -R -x 5 -d mlx5_0 -F –report_gbits -f 2 -D 800 -S 3
Server1:
[root@server1 ~]# ib_send_bw -R -x 5 -d mlx5_0 -F –report_gbits -f 2 -D 800 -S 3 1.1.2.2 -T 12
交机限速
对交换机A出口做端口限速处理,发包时容易产生拥塞。
sonic# configure terminal
sonic(config)# policy-map table-policy
sonic(config-pmap-table-policy)# port-shape 8000000 12800
sonic(config)# interface ethernet 0/10
sonic(config-if-0/4)# service-policy table-policy
观察拥塞情况
交换机A
观察交换机A出口的拥塞情况,可以看到在限速的情况下发IB流量包,交换机A出口没有配置ECN的情况下发生了拥塞
sonic# show counters queue 0/10
Server1
观察服务器Server1的IB发包带宽, 可以看到服务器Server1在没有配置ECN发生拥塞的情况下,发包的平均带宽为4.59Gb/s。
[root@serveer1 ~]# ib_send_bw -R -x 5 -d mlx5_0 -F –report_gbits -f 2 -D 800 -S 3 1.1.5.2
配置交换机ECN功能
交换机A
sonic# configure terminal
sonic(config)# wred ecnname
sonic(config-wred-ecnname)# mode ecn gmin 15000 gmax 150000\
gprobability 20
sonic(config)# class-map ecn1
sonic(config-cmap-ecn)# match cos 0
sonic(config)# policy-map ecn2
sonic(config-pmap-enc2)# class ecn1
sonic(config-pmap-enc2)# wred ecnname
sonic(config)# interface ethernet 0/9
sonic(config-if-0/9)# service-policy ecn2
sonic(config)# interface ethernet 0/10
sonic(config-if-0/10)# service-policy ecn2
Server1
[root@Server1 ~]# echo 1 > /proc/sys/net/ipv4/tcp_ecn
[root@Server1 ~]# cma_roce_mode -d mlx5_0 -p 1 -m 2
Server2
[root@Server2 ~]# echo 1 > /proc/sys/net/ipv4/tcp_ecn
[root@Server2 ~]# cma_roce_mode -d mlx5_1 -p 1 -m 2
[root@Server2 ~]# echo 41 > /sys/class/net/enp2s0f1/ecn/roce_np/cnp_dscp
观察ECN功能
清空流量包计数
清空交换机A的流量包计数。
sonic# clear counters queue
Clear saved counters
发送IB流量
Server1和Server2配置了Mellanox网卡,在Server2建立服务端,Server1建立客户端发送IB流量。
Server2:[root@server3 ~]# ib_send_bw -R -x 5 -d mlx5_0 -F –report_gbits -f 2 -D 800 -S 3
Server1:
[root@server1 ~]# ib_send_bw -R -x 5 -d mlx5_0 -F –report_gbits -f 2 -D 800 -S 3 1.1.2.2 -T 128
交换机A
观察交换机A入口是否收到CNP的返回流量,cnp_dscp的值设置为41,对应通道UC5。
同时观察交换机A出口的拥塞丢包情况。
sonic# show counters queue 0/10
sonic# show counters queue 0/9
Server1
同时观察到交换机A出口配置ECN的情况下拥塞几乎消失,交换机A入口的队列5收到了CNP的返回流量。Server1发包的平均带宽为5.9Gb/s。
[root@server1 ~]# ib_send_bw -R -x5 -d mlx5_1 -F –report_gbits –rate_limit=100 -f 2 -D 800 -S 3 1.1.2.2