2013-05-14 134 views
0

我正在使用netfilter来操作TCP数据包,所以我必须重新计算TCP和IP校验和,它按预期工作。TCP校验和计算更改 - 禁用TCP卸载

Wireshark报告在离开服务器的路上校验和是正确的(它与客户端认为它们应该是一致的),但是当它们到达客户端时校验和总是被0xAA6A代替。

在后路由挂钩,我正在计算TCP校验和如下...操作地址/端口后。

tcp_header->check = 0; 
tcp_header->check = tcp_v4_check(tcp_len, 
    ip_header->saddr, 
    ip_header->daddr, 
    csum_partial((char *)tcp_header, tcp_len, 0)); 

IP校验是好的使用

ip_send_check(ip_header); 

服务器没有为RX或TX启用TCP卸载,也甚至不支持它,我得到尝试启用时或不支持的错误禁用。

Offload parameters for eth0: 
rx-checksumming: off 
tx-checksumming: off 
scatter-gather: off 
tcp-segmentation-offload: off 
udp-fragmentation-offload: off 
generic-segmentation-offload: off 
generic-receive-offload: on 
large-receive-offload: off 
rx-vlan-offload: off 
tx-vlan-offload: off 
ntuple-filters: off 
receive-hashing: off 

另一个相关的问题,我不肯定...我还操纵数据包/端口的服务器上的路由前钩,并且它们通过传输层接受和肯定让我应用程序,无论我对TCP校验和做了什么,我都假设如果TCP校验和在更改IP地址/和端口后没有更新,它们将被丢弃。

这种行为是否有任何明显的原因,或者我误解了网络堆栈的一部分?

更新:

设置已ip_summed到CHECKSUM_NONE被停止校验被重新计算一次离开我的代码。我不确定的是为什么它被重新计算为一个不正确的固定值?如果我没有设置它,它将被设置为CHECKSUM_PARTIAL。

回答

1

如果在另一端的值总是相同的,我会看到2个主要的可能性:1)在此代码后面覆盖校验和2)tcp_len错误 您还应该检查是否在sockbuff dev中设置了NETIF_F_V4_CSUM - >特性,因为内核做一些事情在这种情况下

+0

校验和是不是在我的代码覆盖不同,至少,和tcp_len应该是正确的,因为我实际得到正确的校验,直到它离开netfilter的POSTROUTING钩(也可见由Wireshark提供)。我会看看NETIF_F_V4_CSUM。将skb-> ip_summed设置为CHECKSUM_NONE似乎可行,理想情况下这只是一个临时修复,因为卸载会有所帮助。我假设卸载使用数据包的IP地址为TCP psuedo头? – DarkRyuu 2013-05-14 19:23:16

+0

将它设置为CHECKSUM_NONE之前的值是什么? 当你说“它的工作原理”,你怎么在电线上的校验看到设置为NONE后? (或者是你看到0) 卸载在Linux香草不会在发送端做太多,除了校验但无论如何,你的补丁需要不管是什么工作。 – Guillaume 2013-05-14 20:31:02

+0

当我设置ip_summed到CHECKSUM_NONE,TCP校验是正确的,当它离开我的网络过滤器钩子(如前),也是正确的,当它到达客户端(这是不是之前)。我会用更多的信息更新这个问题。 – DarkRyuu 2013-05-15 11:17:42