2013-05-14 141 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