datapath-windows/ovsext/Offload.c
/*
 * OvsApplySWChecksumOnNB --
 *
 * This function calculates and sets the required software offloads given by
 * 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'.
 *
 */
OvsApplySWChecksumOnNB
This function calculates and sets the required software offloads given by
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'.
OvsApplySWChecksumOnNB This function calculates and sets the required software offloads given by 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
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);
    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)OvsGetMdlWithLowPriority(curMdl);
        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;
}
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 ) ; 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 ) OvsGetMdlWithLowPriority ( curMdl ) ; 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 ; }
OvsApplySWChecksumOnNB
 This function calculates and sets the required software offloads given by
 csumInfo for a given NBL(nbl).
OvsApplySWChecksumOnNB This function calculates and sets the required software offloads given by csumInfo for a given NBL ( nbl ) .