summaryrefslogtreecommitdiff
path: root/datapath-windows/ovsext/Offload.c
diff options
context:
space:
mode:
authorAlin Serdean <aserdean@cloudbasesolutions.com>2017-04-21 02:43:17 +0000
committerGurucharan Shetty <guru@ovn.org>2017-04-21 10:08:30 -0700
commit6405341f610d73c7d0e36715090011b8780316f0 (patch)
tree877824f63047d546d48cb8f5b6056d64d5cbb836 /datapath-windows/ovsext/Offload.c
parentae584afe5d2b62eda6623f73bd9b34bbf9365651 (diff)
downloadopenvswitch-6405341f610d73c7d0e36715090011b8780316f0.tar.gz
datapath-windows: Add software checksums for nbl which contain multiple nb
Until now we only needed to compute software checksums on net buffer lists containing a single net buffer. This patch allows the software checksums to be applied on a net buffer list with multiple net buffers. The hard assumption for this, is the net buffers are part of the same connection. The position of the offsets is pointed by the layers parameter. This will be useful for introducing support ip fragments in conntrack. Signed-off-by: Alin Gabriel Serdean <aserdean@cloudbasesolutions.com> Acked-by: Anand Kumar <kumaranand@vmware.com> Signed-off-by: Gurucharan Shetty <guru@ovn.org>
Diffstat (limited to 'datapath-windows/ovsext/Offload.c')
-rw-r--r--datapath-windows/ovsext/Offload.c105
1 files changed, 54 insertions, 51 deletions
diff --git a/datapath-windows/ovsext/Offload.c b/datapath-windows/ovsext/Offload.c
index f3ab0e169..65d3b6744 100644
--- a/datapath-windows/ovsext/Offload.c
+++ b/datapath-windows/ovsext/Offload.c
@@ -647,7 +647,9 @@ OvsCalculateUDPChecksum(PNET_BUFFER_LIST curNbl,
* OvsApplySWChecksumOnNB --
*
* This function calculates and sets the required software offloads given by
- * csumInfo for a given NBL(nbl) with a single NB.
+ * csumInfo for a given NBL(nbl). If the given net buffer list 'nbl'
+ * has multiple net buffers, we assume that they are part of the same
+ * connection with the same offsets defined in 'layers'.
*
*/
NDIS_STATUS
@@ -661,60 +663,61 @@ OvsApplySWChecksumOnNB(POVS_PACKET_HDR_INFO layers,
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;
- }
+ for (curNb = NET_BUFFER_LIST_FIRST_NB(nbl); curNb != NULL;
+ curNb = curNb->Next) {
+ 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);
+ bufferStart += NET_BUFFER_CURRENT_MDL_OFFSET(curNb);
- if (layers->isIPv4) {
- IPHdr *ip = (IPHdr *)(bufferStart + layers->l3Offset);
+ 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 (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 (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));
+ }
}
}