Patrick McHardy wrote:
> Chinh Nguyen wrote:
> 
>>I discovered that the "bug" is in the function tcp_v4_rcv for kernel 
>>2.6.16-rc1.
>>
>>After the ESP packet is decapped and decrypted in xfrm4_rcv_encap_finish, the
>>unencrypted packet is pushed back through ip_local_deliver. For a UDP packet, 
>>it
>>goes (back) to function udp_queue_rcv_skb. The first thing this function does 
>>is
>>called xfrm4_policy_check. As noted previously, in xfrm4_policy_check, if the
>>skb->sp != NULL, the esp_post_input function is called. The post input 
>>function
>>sets skb->ip_summed to CHECKSUM_UNNECESSASRY if we are in transport mode.
>>Therefore, further down in udp_queue_rcv_skb, we skip the checksum check and 
>>the
>>packet is passed up the stack.
>>
>>However, for a decrypted TCP packet, the packet goes to tcp_v4_rcv. This
>>function does the checksum check right away if skb->ip_summed !=
>>CHECKSUM_UNNECESSARY while xfrm4_policy_check is called a little later in the
>>function. Therefore, the esp post input has not yet set the ip_summed to
>>unnecessary. The decrypted packet fails the checksum and is discarded.
>>
>>To confirm this, I added another call to xfrm4_policy_check before the 
>>checksum
>>check in tcp_v4_rcv (to call esp post input). Once patched, my systems were 
>>able
>>to initiate TCP connections using Transport Mode/NAT.
> 
> 
> What values does skb->ip_summed have before that?

the skb->ip_summed value before the checksum check in tcp_v4_rcv is
CHECKSUM_NONE. Hence tcp_v4_rcv checks its value, which is incorrect because the
checksum is with regards to the private IP but the NAT device has modified the
source IP. I believe that skb->ip_summed is set to CHECKSUM_NONE by esp_input
(net/ipv4/esp4.c:180) which is called by xfrm4_rcv_encap
(net/ipv4/xfrm4_input.c:101).

-
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to