TSO(TCP Segmentation Offload): 是一种利用网卡来对大数据包进行自动分段,降低CPU负载的技术。 其主要是延迟分段。

GSO(Generic Segmentation Offload): GSO是协议栈是否推迟分段,在发送到网卡之前判断网卡是否支持TSO,如果网卡支持TSO则让网卡分段,否则协议栈分完段再交给驱动。 如果TSO开启,GSO会自动开启。


查看tso和gso是否开启

[root@localhost ~]# ethtool -k enp4s0f3

Features for enp4s0f3:

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: off [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-tcp-mangleid-segmentation: on

        tx-tcp6-segmentation: on

generic-segmentation-offload: on



GSO开启, TSO开启: 协议栈推迟分段,并直接传递大数据包到网卡,让网卡自动分段

GSO开启, TSO关闭: 协议栈推迟分段,在最后发送到网卡前才执行分段

GSO关闭, TSO开启: 同GSO开启, TSO开启

GSO关闭, TSO关闭: 不推迟分段,在tcp_sendmsg中直接发送MSS大小的数据包


tcpdump抓包路径:

rx端: Wire -> NIC -> tcpdump -> netfilter/iptables

tx端: iptables -> tcpdump -> NIC -> Wire



网卡收发包流程,网卡--驱动--协议栈


TSO和GSO_传输层


2个概念

MTU:链路层具有最大传输单元MTU这个特性,限制了数据帧的最大长度,不同的网络类型都有一个上限值。如以太网Ethernet II和802.3规范对帧中的数据字段长度都有一个限制,其最大值分别是1500和1492个字节。 如果IP层有数据包要传,而且数据包的长度(包括IP头)超过了MTU,那么IP层就要对数据包进行分片(fragmentation)操作,使每一片的长度都小于或等于MTU。

MSS:TCP 数据包每次能够传输的最大数据分段称为 MSS (Maxitum Segment Size),为了达到最佳的传输效能,在建立 TCP 连接时双方协商 MSS 值,双方提供的 MSS 值的最小值为这次连接的最大 MSS 值。MSS 往往基于 MTU 计算出来,通常 MSS=MTU-sizeof(IP Header)-sizeof(TCPHeader)=1500-20-20=1460

IP分片产生的原因是网络层的MTU;TCP分段产生原因是MSS.

IP分片由网络层完成,也在网络层进行重组;TCP分段是在传输层完成,并在传输层进行重组.

故采用TCP协议进行数据传输,是不会造成IP分片的。若数据过大,只会在传输层进行数据分段,到了IP层就不用分片。

而我们常提到的IP分片是由于UDP传输协议造成的,因为UDP传输协议并未限定传输数据报的大小。



通常在三次握手的过程中,server端发出的ack+syn报文中会有MSS的协商,此处协商的MSS为1460,因为MTU是1500-20(IP头)-20(TCP头)

TSO和GSO_传输层_02


TCP在传输的时候因为会先三次握手建立连接,因此必然会协商MSS的大小,后续客户端会根据MSS大小来分段报文,因此在IP层就不需要再次分段了。

UDP因为未限制报文大小(实际按65536来算),因此如果UDP报文大于mtu的话,会在IP层进行分片。


抛开上面协议层的处理不说,先来说网卡的功能,由于开启TSO后是由网卡分片,因此发送大于MTU的TCP报文后,在到网卡之前都是不会分片的。


客户端发送超过mtu的报文,长度为1600   iperf3 -c 10.84.10.200 -t 100 -i 2 -l 1600

TSO关闭:

TCP分段,在到达网卡前已经分好端,在TXtcpdump抓包

因为是  TCP报文,即使不在网卡分段,也不会在IP层分片

又TCP协议栈根据MSS分段发送报文

TSO和GSO_抓包_03


TSO打开:

报文在发送到网卡前不会分段,由网卡进行分段

tcpdump在tx抓包,因为没有到网卡,因此报文还未分段

TSO和GSO_传输层_04


在rx抓包,发现出来的报文已经分好段了,因为是tx端网卡 分的

TSO和GSO_传输层_05