linux-kernel - 相同数据包的 TCP 重传,但具有不同的 TCP 负载

标签 linux-kernel drivers tcp

我正在 Linux 平台上开发以太网驱动程序。我发现当发生TCP重传时,引用相同序号数据包的多个重传数据包的TCP负载是不同的。我不明白为什么会这样。在我的驱动程序中,我只是分配了一个没有任何特定标志的普通网络设备。顺便说一句,这些重传数据包中的 TCP 校验和字段也是错误的,但是所有其他类型的 TCP 数据包中的校验和都是正确的,例如 SYNC、ACK 和 DUP ACK。

我是用wireshark抓包的,也就是说我抓到的包不是我的驱动处理的,只是来自Linux内核的TCP栈。但是当我用其他以太网设备和驱动程序进行测试时,并没有出现这个问题。所以我的问题如下。

  1. TCP 堆栈是否有可能在没有相同负载的情况下重传相同的数据包?
  2. Linux内核中的哪些参数会导致这些问题?
  3. 我的驱动程序如何导致此问题?

最佳答案

感谢您的所有回复。

我找到了这个问题的原因。这是一个非常非常愚蠢的错误。

由于使所有 DMA 缓冲区(在我的驱动程序中是 skb->data)地址对齐到 4 字节,我调用了一个 memmove 函数来做到这一点。实际上,skb->data 引用的数据由内核中的所有 TCP/IP 堆栈共享。所以在这个错误的操作之后,当发生TCP重传时,TCP栈中skb->data引用的地址仍然保持原来的地址。这就是为什么基于原始数据的校验和在 wireshark 中似乎是错误的。我的驱动程序中的代码如下。

u32 skb_len = skb->len;
u32 align = check_aligned(skb);
if !align
    return skb;

skb_push(skb,align);
memmove(skb->data, skb->data+align, skb_len);
skb_trim(skb, skb_len);
return skb;

我希望我的经验可以帮助其他人避免这种愚蠢的错误。

关于linux-kernel - 相同数据包的 TCP 重传,但具有不同的 TCP 负载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29658336/

相关文章:

linux - 当 linux 系统调用被阻塞时如何以及何时设置 -EINTR

c - 如何从设备树节点获取时钟

c - Kconfig、宏和未定义的宏警告

linux-kernel - 在strace中捕获vDSO

c++ - UMDF,无法为 Microsoft 定义的类指定 [ClassInstall32] 部分

java - 如何使用 spring 集成在 TCP 连接上实现保持连接?

java - 由服务器发起的 TCP 连接关闭是否有利?

c++ - 在客户端看不到的内部接口(interface)中测试有效参数

java - 枚举外部驱动器

wcf - WCF HTTP 绑定(bind)是否在 TCP 上运行?