我正在使用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