summaryrefslogtreecommitdiff
path: root/datapath-windows/ovsext/BufferMgmt.c
diff options
context:
space:
mode:
authorAlin Serdean <aserdean@cloudbasesolutions.com>2015-09-30 21:16:55 +0000
committerBen Pfaff <blp@nicira.com>2015-10-02 07:22:49 -0700
commit89d762f3d5339a1f257de4298f48b535878ddf20 (patch)
tree3bca0e1fe9938510502d2b74f0642bbdf6a4ff9f /datapath-windows/ovsext/BufferMgmt.c
parent9f0c26b9bd116b13b52d050e990aa48e2393d98a (diff)
downloadopenvswitch-89d762f3d5339a1f257de4298f48b535878ddf20.tar.gz
datapath-windows: Compute checksums for VXLAN inner packets.
Windows does not support VXLAN hardware offloading. Currently we do not compute IP/TCP/UDP checksums for the inner packet. This patch computes the checksums mentioned above in regards with the enabled settings. i.e. if IP checksum offloading is enabled for the inner packet we compute it. The same applies for TCP and UDP packets. This patch also revizes the computation of ones' complement over different memory blocks, in the case the lengths are odd. Also per documentation: https://msdn.microsoft.com/en-us/library/windows/hardware/ff568840%28v=vs.85%29.aspx set the TCP flags FIN and PSH only for the last segment in the case LSO is enabled. Signed-off-by: Alin Gabriel Serdean <aserdean@cloudbasesolutions.com> Acked-by: Sairam Venugopal <vsairam@vmware.com> Acked-by: Sorin Vinturis <svinturis@cloudbasesolutions.com> Signed-off-by: Ben Pfaff <blp@nicira.com>
Diffstat (limited to 'datapath-windows/ovsext/BufferMgmt.c')
-rw-r--r--datapath-windows/ovsext/BufferMgmt.c37
1 files changed, 29 insertions, 8 deletions
diff --git a/datapath-windows/ovsext/BufferMgmt.c b/datapath-windows/ovsext/BufferMgmt.c
index 3550e20cc..9a1cf96b1 100644
--- a/datapath-windows/ovsext/BufferMgmt.c
+++ b/datapath-windows/ovsext/BufferMgmt.c
@@ -1116,7 +1116,8 @@ GetSegmentHeaderInfo(PNET_BUFFER_LIST nbl,
* --------------------------------------------------------------------------
*/
static NDIS_STATUS
-FixSegmentHeader(PNET_BUFFER nb, UINT16 segmentSize, UINT32 seqNumber)
+FixSegmentHeader(PNET_BUFFER nb, UINT16 segmentSize, UINT32 seqNumber,
+ BOOLEAN lastPacket, UINT16 packetCounter)
{
EthHdr *dstEth;
IPHdr *dstIP;
@@ -1141,18 +1142,34 @@ FixSegmentHeader(PNET_BUFFER nb, UINT16 segmentSize, UINT32 seqNumber)
/* Fix IP length and checksum */
ASSERT(dstIP->protocol == IPPROTO_TCP);
dstIP->tot_len = htons(segmentSize + dstIP->ihl * 4 + TCP_HDR_LEN(dstTCP));
+ dstIP->id += packetCounter;
dstIP->check = 0;
dstIP->check = IPChecksum((UINT8 *)dstIP, dstIP->ihl * 4, 0);
/* Fix TCP checksum */
dstTCP->seq = htonl(seqNumber);
- dstTCP->check =
- IPPseudoChecksum((UINT32 *)&dstIP->saddr,
- (UINT32 *)&dstIP->daddr,
- IPPROTO_TCP, segmentSize + TCP_HDR_LEN(dstTCP));
+
+ /*
+ * Set the TCP FIN and PSH bit only for the last packet
+ * More information can be found under:
+ * https://msdn.microsoft.com/en-us/library/windows/hardware/ff568840%28v=vs.85%29.aspx
+ */
+ if (dstTCP->fin) {
+ dstTCP->fin = lastPacket;
+ }
+ if (dstTCP->psh) {
+ dstTCP->psh = lastPacket;
+ }
+
+ UINT16 csumLength = segmentSize + TCP_HDR_LEN(dstTCP);
+ dstTCP->check = IPPseudoChecksum(&dstIP->saddr,
+ &dstIP->daddr,
+ IPPROTO_TCP,
+ csumLength);
dstTCP->check = CalculateChecksumNB(nb,
- (UINT16)(NET_BUFFER_DATA_LENGTH(nb) - sizeof *dstEth - dstIP->ihl * 4),
- sizeof *dstEth + dstIP->ihl * 4);
+ csumLength,
+ sizeof *dstEth + dstIP->ihl * 4);
+
return STATUS_SUCCESS;
}
@@ -1190,6 +1207,7 @@ OvsTcpSegmentNBL(PVOID ovsContext,
NDIS_STATUS status;
UINT16 segmentSize;
ULONG copiedSize;
+ UINT16 packetCounter = 0;
srcCtx = (POVS_BUFFER_CONTEXT)NET_BUFFER_LIST_CONTEXT_DATA_START(nbl);
if (srcCtx == NULL || srcCtx->magic != OVS_CTX_MAGIC) {
@@ -1232,7 +1250,9 @@ OvsTcpSegmentNBL(PVOID ovsContext,
goto nblcopy_error;
}
- status = FixSegmentHeader(newNb, segmentSize, seqNumber);
+ status = FixSegmentHeader(newNb, segmentSize, seqNumber,
+ NET_BUFFER_NEXT_NB(newNb) == NULL,
+ packetCounter);
if (status != NDIS_STATUS_SUCCESS) {
goto nblcopy_error;
}
@@ -1241,6 +1261,7 @@ OvsTcpSegmentNBL(PVOID ovsContext,
/* Move on to the next segment */
size -= segmentSize;
seqNumber += segmentSize;
+ packetCounter++;
}
status = OvsAllocateNBLContext(context, newNbl);