不知道是不是因为 GSO, GRO 是 Linux 新增特性的原因, 在 google 上找了半天都没有找到一篇详细的介绍如何使用 GSO/GRO 的文章, 最后从 Linux 内核中与 GSO/GRO 相关的 testcase 中窥到了一丝信息, 总结如下. 另外由于 GSO 是 5.0 新加的特性, 而且手头上也没有 linux 5.0 的机器, 所以如下总结并未实际验证过…
GSO, 关于 GSO 的原理, 参见 UDP segmentation offload 了解. 简单来说, 在业务发送 UDP 数据包时, 为了避免 IP 层对包进行分片, 一般会将待发送的 UDP 数据包的大小控制在 MTU - sizeof(udp header) - sizeof(ip header)
以下. 这里之所以要避免 IP 层分片, 主要是额外的 IP 层分片与重组有时候会导致不少问题, 比如同属于同一个上层数据包的多个 IP 分片在发送时, 任一分片的丢失都将导致整个上层数据包的重传. 再比如接收端设备为了完成 IP 重组不得不分配额外的内存等资源来存放管理当前已经收到的 IP 分片, 如果发送端发送大量的 IP 分片, 那么将会导致接收端用于暂存分片包的缓冲区被打满, 更糟糕的是如果发送端的一个数据包对应的分片数目过多, 那么接收端可能会一直无法完成一次完整的分片重组. 举个极端例子: 假设接收端 R 最多可以缓存 4 个 IP 分片包, 现在有发送端 S 发送了 1 个 8000 字节长度的 UDP 数据包, 在 MTU 为 1500 的情况下, 这个 UDP 数据