我正在Linux平台上开发以太网驱动程序。我发现当发生TCP重传时,涉及相同序列号分组的多个重传分组的TCP有效载荷是不同的。我不明白为什么会这样。在我的驱动程序中,我刚刚分配了没有任何特定标志的普通网络设备。顺便说一句,TCP校验和字段在这些重传数据包中也是错误的,但是,所有其他类型的TCP数据包中的校验和是正确的,例如SYNC,ACK和DUP ACK。
我通过wireshark捕获了数据包,这意味着我捕获的数据包不是由我的驱动程序处理的,只是来自Linux内核中的TCP堆栈。但是当我使用其他以太网设备和驱动程序进行测试时,这个问题并没有发生。所以我的问题如下:
答案 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;
我希望我的经验可以帮助别人避免这种愚蠢的错误。