summaryrefslogtreecommitdiff
path: root/datapath-windows
diff options
context:
space:
mode:
Diffstat (limited to 'datapath-windows')
-rw-r--r--datapath-windows/ovsext/Actions.c60
1 files changed, 11 insertions, 49 deletions
diff --git a/datapath-windows/ovsext/Actions.c b/datapath-windows/ovsext/Actions.c
index 41d1c7b1b..0af4a660d 100644
--- a/datapath-windows/ovsext/Actions.c
+++ b/datapath-windows/ovsext/Actions.c
@@ -1528,6 +1528,11 @@ OvsUpdateAddressAndPort(OvsForwardingContext *ovsFwdCtx,
((BOOLEAN)csumInfo.Receive.UdpChecksumSucceeded ||
(BOOLEAN)csumInfo.Receive.UdpChecksumFailed);
}
+ if (l4Offload) {
+ *checkField = IPPseudoChecksum(&newAddr, &ipHdr->daddr,
+ tcpHdr ? IPPROTO_TCP : IPPROTO_UDP,
+ ntohs(ipHdr->tot_len) - ipHdr->ihl * 4);
+ }
} else {
addrField = &ipHdr->daddr;
if (tcpHdr) {
@@ -1538,19 +1543,13 @@ OvsUpdateAddressAndPort(OvsForwardingContext *ovsFwdCtx,
checkField = &udpHdr->check;
}
}
+
if (*addrField != newAddr) {
UINT32 oldAddr = *addrField;
- if (checkField && *checkField != 0) {
- if (l4Offload) {
- /* Recompute IP pseudo checksum */
- *checkField = ~(*checkField);
- *checkField = ChecksumUpdate32(*checkField, oldAddr,
- newAddr);
- *checkField = ~(*checkField);
- } else {
- *checkField = ChecksumUpdate32(*checkField, oldAddr,
- newAddr);
- }
+ if (checkField && *checkField != 0 && !l4Offload) {
+ /* Recompute total checksum. */
+ *checkField = ChecksumUpdate32(*checkField, oldAddr,
+ newAddr);
}
if (ipHdr->check != 0) {
ipHdr->check = ChecksumUpdate32(ipHdr->check, oldAddr,
@@ -1561,49 +1560,12 @@ OvsUpdateAddressAndPort(OvsForwardingContext *ovsFwdCtx,
if (portField && *portField != newPort) {
if (checkField && !l4Offload) {
+ /* Recompute total checksum. */
*checkField = ChecksumUpdate16(*checkField, *portField,
newPort);
}
*portField = newPort;
}
- PNET_BUFFER_LIST curNbl = ovsFwdCtx->curNbl;
- PNET_BUFFER_LIST newNbl = NULL;
- if (layers->isTcp) {
- UINT32 mss = OVSGetTcpMSS(curNbl);
- if (mss) {
- OVS_LOG_TRACE("l4Offset %d", layers->l4Offset);
- newNbl = OvsTcpSegmentNBL(ovsFwdCtx->switchContext, curNbl, layers,
- mss, 0, FALSE);
- if (newNbl == NULL) {
- OVS_LOG_ERROR("Unable to segment NBL");
- return NDIS_STATUS_FAILURE;
- }
- /* Clear out LSO flags after this point */
- NET_BUFFER_LIST_INFO(newNbl, TcpLargeSendNetBufferListInfo) = 0;
- }
- }
- /* If we didn't split the packet above, make a copy now */
- if (newNbl == NULL) {
- csumInfo.Value = NET_BUFFER_LIST_INFO(curNbl,
- TcpIpChecksumNetBufferListInfo);
- OvsApplySWChecksumOnNB(layers, curNbl, &csumInfo);
- }
-
- if (newNbl) {
- curNbl = newNbl;
- OvsCompleteNBLForwardingCtx(ovsFwdCtx,
- L"Complete after cloning NBL for encapsulation");
- OvsInitForwardingCtx(ovsFwdCtx, ovsFwdCtx->switchContext,
- newNbl, ovsFwdCtx->srcVportNo, 0,
- NET_BUFFER_LIST_SWITCH_FORWARDING_DETAIL(newNbl),
- ovsFwdCtx->completionList,
- &ovsFwdCtx->layers, FALSE);
- ovsFwdCtx->curNbl = newNbl;
- }
-
- NET_BUFFER_LIST_INFO(curNbl,
- TcpIpChecksumNetBufferListInfo) = 0;
-
return NDIS_STATUS_SUCCESS;
}