<div dir="ltr"><div>Hi,<br><br>Regarding the issue below.<br><br>I ran more tests and found that setting the CHECKSUM_PARTIAL flag corrupts the checksum in non mangled NAT packets when hitting the queue_userspace_packet() function (as reported below).<br>When I tried to reset the flag after the helper function call, non mangled packets had the correct checksum but mangled FTP packets were still incorrect.<br>Instead of setting the CHECKSUM_PARTIAL to avoid hitting the skb_dst on pre kernel 4.5, I have attached a patch that gives the skb the required skb_dst and the flags that are checked in the kernel checksum calculation.</div><div>This essentially causes the pre kernel 4.5 version to hit the same code as post 4.5 and recalculate the layer 4 checksums in the Netfilter modules.<br>I have tested this and the checksums are now correct for both mangled and non mangled NATed packet that go through the FTP helper.<br><br>Is it ok to submit this patch here? If this approach seems valid I can prepare it for the dev email list.<br><br>Thanks,<br>John<br><br><br></div><br><div class="gmail_quote">---------- Forwarded message ----------<br>From: <b class="gmail_sendername">John Hurley</b> <span dir="ltr">&lt;<a href="mailto:john.hurley@netronome.com" target="_blank">john.hurley@netronome.com</a>&gt;</span><br>Date: Tue, Dec 20, 2016 at 5:22 PM<br>Subject: TCP Checksum issue on OVS 2.6.1<br>To: <a href="mailto:bugs@openvswitch.org" target="_blank">bugs@openvswitch.org</a><br><br><br><div dir="ltr">Hi,<br><br>I am playing about with NAT in OVS 2.6.1 and have come across an issue with TCP checksums when helpers are being used.<div><br></div><div>I have a setup of client -&gt; OVS -&gt; ftp server (all physical ports with no checksum offloading enabled the network cards). OVS is running kernel version 3.13.<br><br>I am using rules such as these for testing purposes:<br><br><div> cookie=0x0, duration=121.467s, table=0, n_packets=0, n_bytes=0, idle_age=121, ct_state=-trk,ip,in_port=4 actions=ct(commit,table=0,nat)</div><div> cookie=0x0, duration=121.453s, table=0, n_packets=0, n_bytes=0, idle_age=121, ct_state=-trk,ip,in_port=3 actions=ct(commit,table=0,nat(<wbr>src=10.0.0.5))</div><div> cookie=0x0, duration=121.462s, table=0, n_packets=0, n_bytes=0, idle_age=121, ct_state=+rel+trk,in_port=4 actions=output:3</div><div> cookie=0x0, duration=121.458s, table=0, n_packets=0, n_bytes=0, idle_age=121, ct_state=-rel+trk,in_port=4 actions=output:3</div><div> cookie=0x0, duration=121.449s, table=0, n_packets=0, n_bytes=0, idle_age=121, ct_state=+rel+trk,in_port=3 actions=output:4</div><div> cookie=0x0, duration=121.444s, table=0, n_packets=0, n_bytes=0, idle_age=121, ct_state=-rel+trk,in_port=3 actions=output:4</div><div> cookie=0x0, duration=121.440s, table=0, n_packets=0, n_bytes=0, idle_age=121, priority=0,arp,in_port=3 actions=output:4</div><div> cookie=0x0, duration=121.435s, table=0, n_packets=0, n_bytes=0, idle_age=121, priority=0,arp,in_port=4 actions=output:3</div><div><br></div><br>This works fine and I can establish FTP connections between client and server. However, when I introduce helper modules, I can no longer connect. I&#39;ve narrowed this down to bad TCP checksums.</div><div><br>Tracing through the code, the marking of the skb checksum data in the he ovs_ct_helper (datapath/conntrack.c) seems to be the cause (only happens in kernels &lt; 4.6). When the packet is recirculated and upcalled to user-space, the following code ends up corrupting the TCP checksum:<br><br>in datapath.c/queue_userspace_pac<wbr>ket()<br><br><div><span class="m_-1045162329353359539gmail-m_-5733438531668063706gmail-Apple-tab-span" style="white-space:pre-wrap">        </span>/* Complete checksum if needed */</div><div><span class="m_-1045162329353359539gmail-m_-5733438531668063706gmail-Apple-tab-span" style="white-space:pre-wrap">        </span>if (skb-&gt;ip_summed == CHECKSUM_PARTIAL &amp;&amp;</div><div><span class="m_-1045162329353359539gmail-m_-5733438531668063706gmail-Apple-tab-span" style="white-space:pre-wrap">        </span>    (err = skb_checksum_help(skb)))<br><br>I have verified the checksums before and after this call and it goes from correct (taking into account the address translation) to invalid.<br><br>In this case, it is the SYN packet of the FTP connection that has the bad checksum so there should be no payload changes involved from the helper. The checksum is updated correctly from the Netfilter NAT code so should not need CHECKSUM_PARTIAL set here? This will, obviously, not cover cases where the packet is modified by the helper.<br><br>I will try to dig a bit more into this and report any further information.<br><br>Thanks,<br>John</div></div></div>
</div><br></div>