[ovs-dev] [PATCH] datapath-windows: Refactor sofware offloads and mss
Alin Serdean
aserdean at cloudbasesolutions.com
Thu Jan 21 02:16:32 UTC 2016
The purpose of this patch is to refactor the software offloads found in
the VXLAN and GRE code and also to refactor how the maximmum segment
size for a given NBL is obtained.
This patch introduces two functions OvsApplySWChecksumOnNB and OVSGetTcpMSS.
OVSGetTcpMSS - will return the mss found in a given NBL.
OvsApplySWChecksumOnNB - will compute and set software offloads for a given
NBL.
Signed-off-by: Alin Gabriel Serdean <aserdean at cloudbasesolutions.com>
---
datapath-windows/ovsext/BufferMgmt.c | 106 +++++++++++++++++++++++++++++++++++
datapath-windows/ovsext/BufferMgmt.h | 21 ++++++-
datapath-windows/ovsext/Gre.c | 79 ++------------------------
datapath-windows/ovsext/Stt.c | 15 +----
datapath-windows/ovsext/Vxlan.c | 79 ++------------------------
5 files changed, 135 insertions(+), 165 deletions(-)
diff --git a/datapath-windows/ovsext/BufferMgmt.c b/datapath-windows/ovsext/BufferMgmt.c
index 7ec073b..e9d339c 100644
--- a/datapath-windows/ovsext/BufferMgmt.c
+++ b/datapath-windows/ovsext/BufferMgmt.c
@@ -1311,6 +1311,112 @@ nblcopy_error:
}
/*
+ * OvsApplySWChecksumOnNB --
+ *
+ * This function calculates and sets the required sofware offloads given by
+ * csumInfo for a given NBL(nbl) with a single NB.
+ *
+ */
+NDIS_STATUS
+OvsApplySWChecksumOnNB(POVS_PACKET_HDR_INFO layers,
+ PNET_BUFFER_LIST nbl,
+ PNDIS_TCP_IP_CHECKSUM_NET_BUFFER_LIST_INFO csumInfo)
+{
+ PNET_BUFFER curNb;
+ PMDL curMdl;
+ PUINT8 bufferStart;
+ UINT32 packetLength = 0;
+ ASSERT(nbl != NULL);
+
+ curNb = NET_BUFFER_LIST_FIRST_NB(nbl);
+ ASSERT(curNb->Next == NULL);
+ packetLength = NET_BUFFER_DATA_LENGTH(curNb);
+ curMdl = NET_BUFFER_CURRENT_MDL(curNb);
+ bufferStart = (PUINT8)MmGetSystemAddressForMdlSafe(curMdl,
+ LowPagePriority);
+ if (!bufferStart) {
+ return NDIS_STATUS_RESOURCES;
+ }
+
+ bufferStart += NET_BUFFER_CURRENT_MDL_OFFSET(curNb);
+
+ if (layers->isIPv4) {
+ IPHdr *ip = (IPHdr *)(bufferStart + layers->l3Offset);
+
+ if (csumInfo->Transmit.IpHeaderChecksum) {
+ ip->check = 0;
+ ip->check = IPChecksum((UINT8 *)ip, 4 * ip->ihl, 0);
+ }
+
+ if (layers->isTcp && csumInfo->Transmit.TcpChecksum) {
+ UINT16 csumLength = (UINT16)(packetLength - layers->l4Offset);
+ TCPHdr *tcp = (TCPHdr *)(bufferStart + layers->l4Offset);
+ tcp->check = IPPseudoChecksum(&ip->saddr, &ip->daddr,
+ IPPROTO_TCP, csumLength);
+ tcp->check = CalculateChecksumNB(curNb, csumLength,
+ (UINT32)(layers->l4Offset));
+ } else if (layers->isUdp && csumInfo->Transmit.UdpChecksum) {
+ UINT16 csumLength = (UINT16)(packetLength - layers->l4Offset);
+ UDPHdr *udp = (UDPHdr *)((PCHAR)ip + sizeof *ip);
+ udp->check = IPPseudoChecksum(&ip->saddr, &ip->daddr,
+ IPPROTO_UDP, csumLength);
+ udp->check = CalculateChecksumNB(curNb, csumLength,
+ (UINT32)(layers->l4Offset));
+ }
+ } else if (layers->isIPv6) {
+ IPv6Hdr *ip = (IPv6Hdr *)(bufferStart + layers->l3Offset);
+
+ if (layers->isTcp && csumInfo->Transmit.TcpChecksum) {
+ UINT16 csumLength = (UINT16)(packetLength - layers->l4Offset);
+ TCPHdr *tcp = (TCPHdr *)(bufferStart + layers->l4Offset);
+ tcp->check = IPv6PseudoChecksum((UINT32 *) &ip->saddr,
+ (UINT32 *) &ip->daddr,
+ IPPROTO_TCP, csumLength);
+ tcp->check = CalculateChecksumNB(curNb, csumLength,
+ (UINT32)(layers->l4Offset));
+ } else if (layers->isUdp && csumInfo->Transmit.UdpChecksum) {
+ UINT16 csumLength = (UINT16)(packetLength - layers->l4Offset);
+ UDPHdr *udp = (UDPHdr *)((PCHAR)ip + sizeof *ip);
+ udp->check = IPv6PseudoChecksum((UINT32 *) &ip->saddr,
+ (UINT32 *) &ip->daddr,
+ IPPROTO_UDP, csumLength);
+ udp->check = CalculateChecksumNB(curNb, csumLength,
+ (UINT32)(layers->l4Offset));
+ }
+ }
+
+ return NDIS_STATUS_SUCCESS;
+}
+
+/*
+ * OVSGetTcpMSS --
+ *
+ * This function returns the maximum segment size of the given NBL. It takes
+ * into consideration both LSO v1 and v2.
+ */
+ULONG
+OVSGetTcpMSS(PNET_BUFFER_LIST nbl)
+{
+ NDIS_TCP_LARGE_SEND_OFFLOAD_NET_BUFFER_LIST_INFO lsoInfo;
+ ASSERT(nbl != NULL);
+
+ lsoInfo.Value = NET_BUFFER_LIST_INFO(nbl,
+ TcpLargeSendNetBufferListInfo);
+ switch (lsoInfo.Transmit.Type) {
+ case NDIS_TCP_LARGE_SEND_OFFLOAD_V1_TYPE:
+ return lsoInfo.LsoV1Transmit.MSS;
+ break;
+ case NDIS_TCP_LARGE_SEND_OFFLOAD_V2_TYPE:
+ return lsoInfo.LsoV2Transmit.MSS;
+ break;
+ default:
+ OVS_LOG_ERROR("Unknown LSO transmit type:%d",
+ lsoInfo.Transmit.Type);
+ return 0;
+ }
+}
+
+/*
* --------------------------------------------------------------------------
* OvsAllocateNBLFromBuffer --
*
diff --git a/datapath-windows/ovsext/BufferMgmt.h b/datapath-windows/ovsext/BufferMgmt.h
index 79abc3d..3f44b9b 100644
--- a/datapath-windows/ovsext/BufferMgmt.h
+++ b/datapath-windows/ovsext/BufferMgmt.h
@@ -63,7 +63,6 @@ typedef union _OVS_BUFFER_CONTEXT {
UINT64 value[MEM_ALIGN_SIZE(16) >> 3];
} OVS_BUFFER_CONTEXT, *POVS_BUFFER_CONTEXT;
-
typedef struct _OVS_NBL_POOL {
NDIS_SWITCH_CONTEXT ndisContext;
NDIS_HANDLE ndisHandle;
@@ -83,11 +82,13 @@ typedef struct _OVS_NBL_POOL {
NDIS_STATUS OvsInitBufferPool(PVOID context);
+
VOID OvsCleanupBufferPool(PVOID context);
PNET_BUFFER_LIST OvsAllocateFixSizeNBL(PVOID context,
UINT32 size,
UINT32 headRoom);
+
PNET_BUFFER_LIST OvsAllocateVariableSizeNBL(PVOID context,
UINT32 size,
UINT32 headRoom);
@@ -106,22 +107,36 @@ PNET_BUFFER_LIST OvsPartialCopyToMultipleNBLs(PVOID context,
UINT32 copySize,
UINT32 headRoom,
BOOLEAN copyNblInfo);
+
PNET_BUFFER_LIST OvsFullCopyNBL(PVOID context, PNET_BUFFER_LIST nbl,
UINT32 headRoom, BOOLEAN copyNblInfo);
+
PNET_BUFFER_LIST OvsTcpSegmentNBL(PVOID context,
PNET_BUFFER_LIST nbl,
POVS_PACKET_HDR_INFO hdrInfo,
UINT32 MSS,
UINT32 headRoom);
+
PNET_BUFFER_LIST OvsAllocateNBLFromBuffer(PVOID context,
PVOID buffer,
ULONG length);
-PNET_BUFFER_LIST OvsFullCopyToMultipleNBLs(PVOID context,
- PNET_BUFFER_LIST nbl, UINT32 headRoom, BOOLEAN copyNblInfo);
+
+PNET_BUFFER_LIST OvsFullCopyToMultipleNBLs(PVOID context, PNET_BUFFER_LIST nbl,
+ UINT32 headRoom,
+ BOOLEAN copyNblInfo);
+
PNET_BUFFER_LIST OvsCompleteNBL(PVOID context, PNET_BUFFER_LIST nbl,
BOOLEAN updateRef);
+
NDIS_STATUS OvsSetCtxSourcePortNo(PNET_BUFFER_LIST nbl, UINT32 portNo);
NDIS_STATUS OvsGetCtxSourcePortNo(PNET_BUFFER_LIST nbl, UINT32 *portNo);
+ULONG OVSGetTcpMSS(PNET_BUFFER_LIST nbl);
+
+NDIS_STATUS OvsApplySWChecksumOnNB(POVS_PACKET_HDR_INFO layers,
+ PNET_BUFFER_LIST nbl,
+ PNDIS_TCP_IP_CHECKSUM_NET_BUFFER_LIST_INFO
+ csumInfo);
+
#endif /* __BUFFER_MGMT_H_ */
diff --git a/datapath-windows/ovsext/Gre.c b/datapath-windows/ovsext/Gre.c
index 5abd4a4..fbba930 100644
--- a/datapath-windows/ovsext/Gre.c
+++ b/datapath-windows/ovsext/Gre.c
@@ -147,21 +147,8 @@ OvsDoEncapGre(POVS_VPORT_ENTRY vport,
packetLength = NET_BUFFER_DATA_LENGTH(curNb);
if (layers->isTcp) {
- NDIS_TCP_LARGE_SEND_OFFLOAD_NET_BUFFER_LIST_INFO tsoInfo;
-
- tsoInfo.Value = NET_BUFFER_LIST_INFO(curNbl,
- TcpLargeSendNetBufferListInfo);
- switch (tsoInfo.Transmit.Type) {
- case NDIS_TCP_LARGE_SEND_OFFLOAD_V1_TYPE:
- mss = tsoInfo.LsoV1Transmit.MSS;
- break;
- case NDIS_TCP_LARGE_SEND_OFFLOAD_V2_TYPE:
- mss = tsoInfo.LsoV2Transmit.MSS;
- break;
- default:
- OVS_LOG_ERROR("Unknown LSO transmit type:%d",
- tsoInfo.Transmit.Type);
- }
+ mss = OVSGetTcpMSS(curNbl);
+
OVS_LOG_TRACE("MSS %u packet len %u", mss,
packetLength);
if (mss) {
@@ -188,71 +175,15 @@ OvsDoEncapGre(POVS_VPORT_ENTRY vport,
OVS_LOG_ERROR("Unable to copy NBL");
return NDIS_STATUS_FAILURE;
}
- /*
- * To this point we do not have GRE hardware offloading.
- * Apply defined checksums
- */
- curNb = NET_BUFFER_LIST_FIRST_NB(*newNbl);
- curMdl = NET_BUFFER_CURRENT_MDL(curNb);
- bufferStart = (PUINT8)MmGetSystemAddressForMdlSafe(curMdl,
- LowPagePriority);
- if (!bufferStart) {
- status = NDIS_STATUS_RESOURCES;
- goto ret_error;
- }
NDIS_TCP_IP_CHECKSUM_NET_BUFFER_LIST_INFO csumInfo;
csumInfo.Value = NET_BUFFER_LIST_INFO(curNbl,
TcpIpChecksumNetBufferListInfo);
- bufferStart += NET_BUFFER_CURRENT_MDL_OFFSET(curNb);
-
- if (layers->isIPv4) {
- IPHdr *ip = (IPHdr *)(bufferStart + layers->l3Offset);
-
- if (csumInfo.Transmit.IpHeaderChecksum) {
- ip->check = 0;
- ip->check = IPChecksum((UINT8 *)ip, 4 * ip->ihl, 0);
- }
-
- if (layers->isTcp && csumInfo.Transmit.TcpChecksum) {
- UINT16 csumLength = (UINT16)(packetLength - layers->l4Offset);
- TCPHdr *tcp = (TCPHdr *)(bufferStart + layers->l4Offset);
- tcp->check = IPPseudoChecksum(&ip->saddr, &ip->daddr,
- IPPROTO_TCP, csumLength);
- tcp->check = CalculateChecksumNB(curNb, csumLength,
- (UINT32)(layers->l4Offset));
- } else if (layers->isUdp && csumInfo.Transmit.UdpChecksum) {
- UINT16 csumLength = (UINT16)(packetLength - layers->l4Offset);
- UDPHdr *udp = (UDPHdr *)((PCHAR)ip + sizeof *ip);
- udp->check = IPPseudoChecksum(&ip->saddr, &ip->daddr,
- IPPROTO_UDP, csumLength);
- udp->check = CalculateChecksumNB(curNb, csumLength,
- (UINT32)(layers->l4Offset));
- }
- } else if (layers->isIPv6) {
- IPv6Hdr *ip = (IPv6Hdr *)(bufferStart + layers->l3Offset);
-
- if (layers->isTcp && csumInfo.Transmit.TcpChecksum) {
- UINT16 csumLength = (UINT16)(packetLength - layers->l4Offset);
- TCPHdr *tcp = (TCPHdr *)(bufferStart + layers->l4Offset);
- tcp->check = IPv6PseudoChecksum((UINT32 *) &ip->saddr,
- (UINT32 *) &ip->daddr,
- IPPROTO_TCP, csumLength);
- tcp->check = CalculateChecksumNB(curNb, csumLength,
- (UINT32)(layers->l4Offset));
- } else if (layers->isUdp && csumInfo.Transmit.UdpChecksum) {
- UINT16 csumLength = (UINT16)(packetLength - layers->l4Offset);
- UDPHdr *udp = (UDPHdr *)((PCHAR)ip + sizeof *ip);
- udp->check = IPv6PseudoChecksum((UINT32 *) &ip->saddr,
- (UINT32 *) &ip->daddr,
- IPPROTO_UDP, csumLength);
- udp->check = CalculateChecksumNB(curNb, csumLength,
- (UINT32)(layers->l4Offset));
- }
+ status = OvsApplySWChecksumOnNB(layers, *newNbl, &csumInfo);
+ if (status != NDIS_STATUS_SUCCESS) {
+ goto ret_error;
}
- /* Clear out TcpIpChecksumNetBufferListInfo flag */
- NET_BUFFER_LIST_INFO(*newNbl, TcpIpChecksumNetBufferListInfo) = 0;
}
curNbl = *newNbl;
diff --git a/datapath-windows/ovsext/Stt.c b/datapath-windows/ovsext/Stt.c
index 0ae2633..6da0ac9 100644
--- a/datapath-windows/ovsext/Stt.c
+++ b/datapath-windows/ovsext/Stt.c
@@ -163,20 +163,7 @@ OvsDoEncapStt(POVS_VPORT_ENTRY vport,
BOOLEAN innerPartialChecksum = FALSE;
if (layers->isTcp) {
- lsoInfo.Value = NET_BUFFER_LIST_INFO(curNbl,
- TcpLargeSendNetBufferListInfo);
-
- switch (lsoInfo.Transmit.Type) {
- case NDIS_TCP_LARGE_SEND_OFFLOAD_V1_TYPE:
- mss = lsoInfo.LsoV1Transmit.MSS;
- break;
- case NDIS_TCP_LARGE_SEND_OFFLOAD_V2_TYPE:
- mss = lsoInfo.LsoV2Transmit.MSS;
- break;
- default:
- OVS_LOG_ERROR("Unknown LSO transmit type:%d",
- lsoInfo.Transmit.Type);
- }
+ mss = OVSGetTcpMSS(curNbl);
}
vportStt = (POVS_STT_VPORT) GetOvsVportPriv(vport);
diff --git a/datapath-windows/ovsext/Vxlan.c b/datapath-windows/ovsext/Vxlan.c
index 2516ece..813fe42 100644
--- a/datapath-windows/ovsext/Vxlan.c
+++ b/datapath-windows/ovsext/Vxlan.c
@@ -201,21 +201,8 @@ OvsDoEncapVxlan(POVS_VPORT_ENTRY vport,
packetLength = NET_BUFFER_DATA_LENGTH(curNb);
if (layers->isTcp) {
- NDIS_TCP_LARGE_SEND_OFFLOAD_NET_BUFFER_LIST_INFO tsoInfo;
-
- tsoInfo.Value = NET_BUFFER_LIST_INFO(curNbl,
- TcpLargeSendNetBufferListInfo);
- switch (tsoInfo.Transmit.Type) {
- case NDIS_TCP_LARGE_SEND_OFFLOAD_V1_TYPE:
- mss = tsoInfo.LsoV1Transmit.MSS;
- break;
- case NDIS_TCP_LARGE_SEND_OFFLOAD_V2_TYPE:
- mss = tsoInfo.LsoV2Transmit.MSS;
- break;
- default:
- OVS_LOG_ERROR("Unknown LSO transmit type:%d",
- tsoInfo.Transmit.Type);
- }
+ mss = OVSGetTcpMSS(curNbl);
+
OVS_LOG_TRACE("MSS %u packet len %u", mss,
packetLength);
if (mss) {
@@ -242,70 +229,14 @@ OvsDoEncapVxlan(POVS_VPORT_ENTRY vport,
OVS_LOG_ERROR("Unable to copy NBL");
return NDIS_STATUS_FAILURE;
}
- /*
- * To this point we do not have VXLAN offloading.
- * Apply defined checksums
- */
- curNb = NET_BUFFER_LIST_FIRST_NB(*newNbl);
- curMdl = NET_BUFFER_CURRENT_MDL(curNb);
- bufferStart = (PUINT8)MmGetSystemAddressForMdlSafe(curMdl, LowPagePriority);
- if (!bufferStart) {
- status = NDIS_STATUS_RESOURCES;
- goto ret_error;
- }
-
NDIS_TCP_IP_CHECKSUM_NET_BUFFER_LIST_INFO csumInfo;
csumInfo.Value = NET_BUFFER_LIST_INFO(curNbl,
TcpIpChecksumNetBufferListInfo);
+ status = OvsApplySWChecksumOnNB(layers, *newNbl, &csumInfo);
- bufferStart += NET_BUFFER_CURRENT_MDL_OFFSET(curNb);
-
- if (layers->isIPv4) {
- IPHdr *ip = (IPHdr *)(bufferStart + layers->l3Offset);
-
- if (csumInfo.Transmit.IpHeaderChecksum) {
- ip->check = 0;
- ip->check = IPChecksum((UINT8 *)ip, 4 * ip->ihl, 0);
- }
-
- if (layers->isTcp && csumInfo.Transmit.TcpChecksum) {
- UINT16 csumLength = (UINT16)(packetLength - layers->l4Offset);
- TCPHdr *tcp = (TCPHdr *)(bufferStart + layers->l4Offset);
- tcp->check = IPPseudoChecksum(&ip->saddr, &ip->daddr,
- IPPROTO_TCP, csumLength);
- tcp->check = CalculateChecksumNB(curNb, csumLength,
- (UINT32)(layers->l4Offset));
- } else if (layers->isUdp && csumInfo.Transmit.UdpChecksum) {
- UINT16 csumLength = (UINT16)(packetLength - layers->l4Offset);
- UDPHdr *udp = (UDPHdr *)((PCHAR)ip + sizeof *ip);
- udp->check = IPPseudoChecksum(&ip->saddr, &ip->daddr,
- IPPROTO_UDP, csumLength);
- udp->check = CalculateChecksumNB(curNb, csumLength,
- (UINT32)(layers->l4Offset));
- }
- } else if (layers->isIPv6) {
- IPv6Hdr *ip = (IPv6Hdr *)(bufferStart + layers->l3Offset);
-
- if (layers->isTcp && csumInfo.Transmit.TcpChecksum) {
- UINT16 csumLength = (UINT16)(packetLength - layers->l4Offset);
- TCPHdr *tcp = (TCPHdr *)(bufferStart + layers->l4Offset);
- tcp->check = IPv6PseudoChecksum((UINT32 *) &ip->saddr,
- (UINT32 *) &ip->daddr,
- IPPROTO_TCP, csumLength);
- tcp->check = CalculateChecksumNB(curNb, csumLength,
- (UINT32)(layers->l4Offset));
- } else if (layers->isUdp && csumInfo.Transmit.UdpChecksum) {
- UINT16 csumLength = (UINT16)(packetLength - layers->l4Offset);
- UDPHdr *udp = (UDPHdr *)((PCHAR)ip + sizeof *ip);
- udp->check = IPv6PseudoChecksum((UINT32 *) &ip->saddr,
- (UINT32 *) &ip->daddr,
- IPPROTO_UDP, csumLength);
- udp->check = CalculateChecksumNB(curNb, csumLength,
- (UINT32)(layers->l4Offset));
- }
+ if (status != NDIS_STATUS_SUCCESS) {
+ goto ret_error;
}
- /* Clear out TcpIpChecksumNetBufferListInfo flag */
- NET_BUFFER_LIST_INFO(*newNbl, TcpIpChecksumNetBufferListInfo) = 0;
}
curNbl = *newNbl;
--
1.9.5.msysgit.0
More information about the dev
mailing list