TCP重传用于相同的数据包但具有不同的TCP有效负载

时间:2015-04-15 16:18:00

标签: linux-kernel drivers tcp

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

我通过wireshark捕获了数据包,这意味着我捕获的数据包不是由我的驱动程序处理的,只是来自Linux内核中的TCP堆栈。但是当我使用其他以太网设备和驱动程序进行测试时,这个问题并没有发生。所以我的问题如下:

  1. TCP堆栈是否有可能在没有相同负载的情况下重新传输相同的数据包?
  2. Linux内核中的哪些参数会导致这些问题?
  3. 我的司机怎么会导致这个问题?

1 个答案:

答案 0 :(得分:0)

感谢您的回复。

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

由于使所有DMA缓冲区(在我的驱动程序中它的skb->数据)地址对齐到4字节,我调用了memmove函数来做到这一点。实际上,skb->数据引用的数据由内核中的所有TCP / IP堆栈共享。因此,在此错误操作之后,当TCP重新发送时,由TCP堆栈中的skb->数据引用的地址仍然保持原始地址。这就是为什么基于原始数据的校验和在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;

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