我正在使用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。
校验和是不是在我的代码覆盖不同,至少,和tcp_len应该是正确的,因为我实际得到正确的校验,直到它离开netfilter的POSTROUTING钩(也可见由Wireshark提供)。我会看看NETIF_F_V4_CSUM。将skb-> ip_summed设置为CHECKSUM_NONE似乎可行,理想情况下这只是一个临时修复,因为卸载会有所帮助。我假设卸载使用数据包的IP地址为TCP psuedo头? – DarkRyuu 2013-05-14 19:23:16
将它设置为CHECKSUM_NONE之前的值是什么? 当你说“它的工作原理”,你怎么在电线上的校验看到设置为NONE后? (或者是你看到0) 卸载在Linux香草不会在发送端做太多,除了校验但无论如何,你的补丁需要不管是什么工作。 – Guillaume 2013-05-14 20:31:02
当我设置ip_summed到CHECKSUM_NONE,TCP校验是正确的,当它离开我的网络过滤器钩子(如前),也是正确的,当它到达客户端(这是不是之前)。我会用更多的信息更新这个问题。 – DarkRyuu 2013-05-15 11:17:42