diff mbox series

[ovs-dev] datapath-windows:Correct checksum for DNAT action

Message ID 20210720072357.4804-1-kumaranand@vmware.com
State Accepted
Headers show
Series [ovs-dev] datapath-windows:Correct checksum for DNAT action | expand

Checks

Context Check Description
ovsrobot/apply-robot warning apply and check: warning
ovsrobot/github-robot success github build: passed

Commit Message

Anand Kumar July 20, 2021, 7:23 a.m. UTC
From: Wilson Peng <pweisong@vmware.com>

While testing OVS-windows flows for the DNAT action, the checksum
In TCP header is set incorrectly when TCP offload is enabled by
Default. As a result, the packet will be dropped on receiver linuxVM.

>>>sample flow default configuration on both Windows VM and Linux VM
(src=40.0.1.2,dst=10.150.0.1) --dnat--> (src=40.0.1.2,dst==30.1.0.2)
Without the fix for some TCP packet(40.0.1.2->30.1.0.2 with payload
len 207) the TCP checksum will be pseduo header checksum and the value
is 0x01d6. With the fix the checksum will be 0x47ee, it could be got
the correct TCP checksum on the receiver Linux VM.

Signed-off-by: Wilson Peng<pweisong@vmware.com>
Signed-off-by: Anand Kumar<kumaranand@vmware.com>
---
 datapath-windows/ovsext/Actions.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)
diff mbox series

Patch

diff --git a/datapath-windows/ovsext/Actions.c b/datapath-windows/ovsext/Actions.c
index 4f43369..e130c2f 100644
--- a/datapath-windows/ovsext/Actions.c
+++ b/datapath-windows/ovsext/Actions.c
@@ -1550,9 +1550,21 @@  OvsUpdateAddressAndPort(OvsForwardingContext *ovsFwdCtx,
         if (tcpHdr) {
             portField = &tcpHdr->dest;
             checkField = &tcpHdr->check;
+            l4Offload = isTx ? (BOOLEAN)csumInfo.Transmit.TcpChecksum :
+                        ((BOOLEAN)csumInfo.Receive.TcpChecksumSucceeded ||
+                         (BOOLEAN)csumInfo.Receive.TcpChecksumFailed);
         } else if (udpHdr) {
             portField = &udpHdr->dest;
             checkField = &udpHdr->check;
+            l4Offload = isTx ? (BOOLEAN)csumInfo.Transmit.UdpChecksum :
+                        ((BOOLEAN)csumInfo.Receive.UdpChecksumSucceeded ||
+                         (BOOLEAN)csumInfo.Receive.UdpChecksumFailed);
+        }
+
+       if (l4Offload) {
+            *checkField = IPPseudoChecksum(&ipHdr->saddr, &newAddr,
+                tcpHdr ? IPPROTO_TCP : IPPROTO_UDP,
+                ntohs(ipHdr->tot_len) - ipHdr->ihl * 4);
         }
     }