FPGA网络协议栈加速TSO/UFO/GSO/LRO/GRO/RSS

参考

网卡多队列技术与RSS功能介绍
ETHTOOL设置网卡接收哈希(RSS)
TSO、UFO、GSO、LRO、GRO和RSS介绍(ethtool命令)
Linux 内核协议栈的 TSO、GSO
linux内核网络协议栈学习笔记:关于GRO/GSO/LRO/TSO等patch的分析和测试
GSO: Generic Segmentation Offload
网络数据包分析 网卡Offload
linux内核网络协议栈学习笔记(6)
GSO: Generic Segmentation Offload
GSO/TSO/GRO等对VirtIO虚机的网络性能影响分析(by quqi99)

GSO

dev_hard_start_xmit里判断netif_needs_gso判断网卡是否支持gso,如果不支持则调用dev_gso_segment里面又调用skb_gso_segment把报文分片,对于ipv4而言,实际调用了tcp_tso_segment,最后返回多个sk_buff组成的链表,头指针存在skb->next里,如果网卡本身支持的话,直接把大块的skb交给网卡:调用netdev_ops->ndo_start_xmit发送出去,判断netif_need_gso时,检查网卡的netdev->features,位于include/linux/netdevice.h

#define NETIF_F_SG      1   /* Scatter/gather IO. */
#define NETIF_F_IP_CSUM     2   /* Can checksum TCP/UDP over IPv4. */
#define NETIF_F_NO_CSUM     4   /* Does not require checksum. F.e. loopack. */
#define NETIF_F_HW_CSUM     8   /* Can checksum all the packets. */

#define NETIF_F_FRAGLIST    64  /* Scatter/gather IO. */

#define NETIF_F_GSO     2048    /* Enable software GSO. */

#define NETIF_F_GSO_SHIFT   16
#define NETIF_F_GSO_MASK    0x00ff0000
#define NETIF_F_TSO     (SKB_GSO_TCPV4 << NETIF_F_GSO_SHIFT)
#define NETIF_F_UFO     (SKB_GSO_UDP << NETIF_F_GSO_SHIFT)

对于要支持TSO的网卡而言,需要有NETIF_F_SG | NETIF_F_TSO | NETIF_F_IP_CSUM,相应如果要支持UFO,应该就需要NETIF_F_SG | NETIF_F_UFO | NETIF_F_IP_CSUM,命令ethtool -k eth0可查看网卡驱动的gso/tso特性:

$ ethtool -k enp1s0f0
Features for enp1s0f0:
rx-checksumming: on
tx-checksumming: on
	tx-checksum-ipv4: off [fixed]
	tx-checksum-ip-generic: on
	tx-checksum-ipv6: off [fixed]
	tx-checksum-fcoe-crc: on [fixed]
	tx-checksum-sctp: on
scatter-gather: on
	tx-scatter-gather: on
	tx-scatter-gather-fraglist: off [fixed]
tcp-segmentation-offload: on
	tx-tcp-segmentation: on
	tx-tcp-ecn-segmentation: off [fixed]
	tx-tcp6-segmentation: on
	tx-tcp-mangleid-segmentation: off
udp-fragmentation-offload: off [fixed]
generic-segmentation-offload: on
generic-receive-offload: on
large-receive-offload: off
rx-vlan-offload: on
tx-vlan-offload: on
ntuple-filters: off
receive-hashing: on
highdma: on [fixed]
rx-vlan-filter: on
vlan-challenged: off [fixed]
tx-lockless: off [fixed]
netns-local: off [fixed]
tx-gso-robust: off [fixed]
tx-fcoe-segmentation: on [fixed]
tx-gre-segmentation: on
tx-ipip-segmentation: on
tx-sit-segmentation: on
tx-udp_tnl-segmentation: on
fcoe-mtu: off [fixed]
tx-nocache-copy: off
loopback: off [fixed]
rx-fcs: off [fixed]
rx-all: off
tx-vlan-stag-hw-insert: off [fixed]
rx-vlan-stag-hw-parse: off [fixed]
rx-vlan-stag-filter: off [fixed]
busy-poll: off [fixed]
tx-gre-csum-segmentation: on
tx-udp_tnl-csum-segmentation: on
tx-gso-partial: on
tx-sctp-segmentation: off [fixed]
rx-gro-hw: off [fixed]
l2-fwd-offload: off
hw-tc-offload: off
rx-udp_tunnel-port-offload: on

命令ethtool -K eth0 tso|gso off|on可打开或关闭网卡驱动的gso/tso特性,采用-k得到的缩写generic-receive-offloadgro

$ sudo ethtool -K enp1s0f0 gro off
  • 物理网卡不支持GSO时,使用TSO时,TCP分段在驱动处调用硬件做,不使用TSO时,TCP分段在TCP协议处软件做。
  • 物理网卡不支持UFO时,使用GSO时,在发送给驱动前一刻做,不使用GSO在IP层软件做。
  • 物理网卡不支持TSO时,使用GSO时,在发送给驱动前一刻做,不使用GSO在TCP层软件做。

TSO与GSO的区别,

  • TSO只有第一个分片有TCP头和IP头,接着的分段只有IP头。意味着第一个分段丢失,所有分段得重传。
  • GSO在分段时会调用TCP或UDP的回调函数(udp4_ufo_fragment)为每个分段都加上IP头,由于分段是通过mss设置的(mss由发送端设置),所以长度仍然可能超过mtu值,所以在IP层还得再分片(代码位于dev_hard_start_xmit)。

checksum offloading

mac地址字节序,
FPGA网络协议栈加速TSO/UFO/GSO/LRO/GRO/RSS_第1张图片
UDP帧格式,
FPGA网络协议栈加速TSO/UFO/GSO/LRO/GRO/RSS_第2张图片
TCP帧格式,
FPGA网络协议栈加速TSO/UFO/GSO/LRO/GRO/RSS_第3张图片
IP头校验,

原始         csum清零     16bit组合   取反        求和         32bit组合   取反        求和
0  1  2  3   0  1  2  3   0 1   2 3   0 1   2 3                0 1 2 3     0 1 2 3  
45 00 00 7a  45 00 00 7a  0045  7a00  ffba  85ff  7+d161=d168  7a000045    85ffffba    4+7BAA+55BA=d168
3c 52 40 00  3c 52 40 00  523c  0040  adc3  ffbf               0040523c    ffbfadc3  
40 06 68 d1  40 06 00 00  0640  0000  f9bf  ffff               00000640    fffff9bf  
c0 a8 0a 08  c0 a8 0a 08  a8c0  080a  573f  f7f5               080aa8c0    f7f5573f  
c0 a8 0a 02  c0 a8 0a 02  a8c0  020a  573f  fdf5               020aa8c0    fdf5573f

TCP,UDP校验,其中UDP报文长度可从报文直接提取,而TCP由IP报文长度减去IP头长度得到,

0000   30 09 f9 20 23 64 00 0a 35 00 00 c8 08 00 45 00
0010   00 3c 59 e2 40 00 40 06 4b 7f c0 a8 0a 08 c0 a8
0020   0a 02 8b 20 1f 90 5f 9b fd 3d 00 00 00 00 a0 02
0030   72 10 94 23 00 00 02 04 05 b4 04 02 08 0a 00 08
0040   a4 df 00 00 00 00 01 03 03 07

伪首部
c0 a8 0a 08  a8c0 080a
c0 a8 0a 02  a8c0 020a
00 06 00 28  0600 2800

TCP
8b 20 1f 90 5f 9b fd 3d 00 00 00 00 a0 02 72 10    208b    901f 9b5f 3dfd 0000 0000 02a0 1072
94 23 00 00 02 04 05 b4 04 02 08 0a 00 08 a4 df    2394(0) 0000 0402 b405 0204 0a08 0800 dfa4
00 00 00 00 01 03 03 07                            0000    0000 0301 0703

IP分片

使用iperf3测UDP带宽时,8192字节的包超过MSS,导致IP分片,抓包发现带UDP包头的包在最后,不是《TCP/IP详解》中说的在最前面,或者说,我们需要需要通过off字段来重组,目前本人能想到的设计,接收端需要n个buffer,占用资源量又增加了,后面分片重组时,还得考虑流水线的出口的dma需要支持多通道Stream,按照off来把数据搬到正确的内存地址。在计算/检验(发送/接收)checksum的时候,每一片都要计算/检验IP头checksum,累计到最后一个片计算/检验UDP的checksum。显然把UDP包头放在最后一个片有利于计算/检验checksum。
FPGA网络协议栈加速TSO/UFO/GSO/LRO/GRO/RSS_第4张图片

你可能感兴趣的:(网络,FPGA)