datapath-windows/ovsext/Offload.c
/*
 *----------------------------------------------------------------------------
 * CalculateChecksumNB --
 *
 * Calculates checksum over a length of bytes contained in an NB.
 *
 * nb           : NB which contains the packet bytes.
 * csumDataLen  : Length of bytes to be checksummed.
 * offset       : offset to the first bytes of the data stream to be
 *                checksumed.
 *
 * Result:
 *  return 0, if there is a failure.
 *----------------------------------------------------------------------------
 */
CalculateChecksumNB
Calculates checksum over a length of bytes contained in an NB.

nb           : NB which contains the packet bytes.
csumDataLen  : Length of bytes to be checksummed.
offset       : offset to the first bytes of the data stream to be
checksumed.

return 0, if there is a failure.
CalculateChecksumNB Calculates checksum over a length of bytes contained in an NB . nb : NB which contains the packet bytes . csumDataLen : Length of bytes to be checksummed . offset : offset to the first bytes of the data stream to be checksumed . return 0 if there is a failure .
UINT16
CalculateChecksumNB(const PNET_BUFFER nb,
                    UINT16 csumDataLen,
                    UINT32 offset)
{
    ULONG mdlLen;
    UINT16 csLen;
    PUCHAR src;
    UINT64 csum = 0;
    PMDL currentMdl;
    ULONG firstMdlLen;
    ULONG packetLen;
    BOOLEAN swapEnd = 1 & csumDataLen;
    if ((nb == NULL) || (csumDataLen == 0)
            || (offset >= NET_BUFFER_DATA_LENGTH(nb))
            || (offset + csumDataLen > NET_BUFFER_DATA_LENGTH(nb))) {
        OVS_LOG_ERROR("Invalid parameters - csum length %u, offset %u,"
                "pkt%s len %u", csumDataLen, offset, nb? "":"(null)",
                nb? NET_BUFFER_DATA_LENGTH(nb) : 0);
        return 0;
    }
    currentMdl = NET_BUFFER_CURRENT_MDL(nb);
    packetLen = NET_BUFFER_DATA_LENGTH(nb);
    firstMdlLen =
        MmGetMdlByteCount(currentMdl) - NET_BUFFER_CURRENT_MDL_OFFSET(nb);
    firstMdlLen = MIN(firstMdlLen, packetLen);
    if (offset < firstMdlLen) {
        src = (PUCHAR)OvsGetMdlWithLowPriority(currentMdl);
        if (!src) {
            return 0;
        }
        src += (NET_BUFFER_CURRENT_MDL_OFFSET(nb) + offset);
        mdlLen = firstMdlLen - offset;
        packetLen -= firstMdlLen;
        ASSERT((INT)packetLen >= 0);
    } else {
        offset -= firstMdlLen;
        packetLen -= firstMdlLen;
        ASSERT((INT)packetLen >= 0);
        currentMdl = NDIS_MDL_LINKAGE(currentMdl);
        mdlLen = MmGetMdlByteCount(currentMdl);
        mdlLen = MIN(mdlLen, packetLen);
        while (offset >= mdlLen) {
            offset -= mdlLen;
            packetLen -= mdlLen;
            ASSERT((INT)packetLen >= 0);
            currentMdl = NDIS_MDL_LINKAGE(currentMdl);
            mdlLen = MmGetMdlByteCount(currentMdl);
            mdlLen = MIN(mdlLen, packetLen);
        }
        src = (PUCHAR)OvsGetMdlWithLowPriority(currentMdl);
        if (!src) {
            return 0;
        }
        src += offset;
        mdlLen -= offset;
    }
    while (csumDataLen && (currentMdl != NULL)) {
        ASSERT(mdlLen < 65536);
        csLen = MIN((UINT16) mdlLen, csumDataLen);
        csum = CalculateOnesComplement(src, csLen, csum, !(1 & csumDataLen));
        fold64(csum);
        csumDataLen -= csLen;
        currentMdl = NDIS_MDL_LINKAGE(currentMdl);
        if (csumDataLen && currentMdl) {
            src = OvsGetMdlWithLowPriority(currentMdl);
            if (!src) {
                return 0;
            }
            mdlLen = MmGetMdlByteCount(currentMdl);
            mdlLen = MIN(mdlLen, packetLen);
            packetLen -= mdlLen;
            ASSERT((INT)packetLen >= 0);
        }
    }
    fold64(csum);
    ASSERT(csumDataLen == 0);
    ASSERT((csum & ~0xffff) == 0);
    csum = (UINT16)~csum;
    if (swapEnd) {
        return _byteswap_ushort((UINT16)csum);
    }
    return (UINT16)csum;
}
UINT16 CalculateChecksumNB ( const PNET_BUFFER nb , UINT16 csumDataLen , UINT32 offset ) { ULONG mdlLen ; UINT16 csLen ; PUCHAR src ; UINT64 csum = 0 ; PMDL currentMdl ; ULONG firstMdlLen ; ULONG packetLen ; BOOLEAN swapEnd = 1 & csumDataLen ; if ( ( nb == NULL ) || ( csumDataLen == 0 ) || ( offset >= NET_BUFFER_DATA_LENGTH ( nb ) ) || ( offset + csumDataLen > NET_BUFFER_DATA_LENGTH ( nb ) ) ) { OVS_LOG_ERROR ( " " " " , csumDataLen , offset , nb ? " " : " " , nb ? NET_BUFFER_DATA_LENGTH ( nb ) : 0 ) ; return 0 ; } currentMdl = NET_BUFFER_CURRENT_MDL ( nb ) ; packetLen = NET_BUFFER_DATA_LENGTH ( nb ) ; firstMdlLen = MmGetMdlByteCount ( currentMdl ) - NET_BUFFER_CURRENT_MDL_OFFSET ( nb ) ; firstMdlLen = MIN ( firstMdlLen , packetLen ) ; if ( offset < firstMdlLen ) { src = ( PUCHAR ) OvsGetMdlWithLowPriority ( currentMdl ) ; if ( ! src ) { return 0 ; } src += ( NET_BUFFER_CURRENT_MDL_OFFSET ( nb ) + offset ) ; mdlLen = firstMdlLen - offset ; packetLen -= firstMdlLen ; ASSERT ( ( INT ) packetLen >= 0 ) ; } else { offset -= firstMdlLen ; packetLen -= firstMdlLen ; ASSERT ( ( INT ) packetLen >= 0 ) ; currentMdl = NDIS_MDL_LINKAGE ( currentMdl ) ; mdlLen = MmGetMdlByteCount ( currentMdl ) ; mdlLen = MIN ( mdlLen , packetLen ) ; while ( offset >= mdlLen ) { offset -= mdlLen ; packetLen -= mdlLen ; ASSERT ( ( INT ) packetLen >= 0 ) ; currentMdl = NDIS_MDL_LINKAGE ( currentMdl ) ; mdlLen = MmGetMdlByteCount ( currentMdl ) ; mdlLen = MIN ( mdlLen , packetLen ) ; } src = ( PUCHAR ) OvsGetMdlWithLowPriority ( currentMdl ) ; if ( ! src ) { return 0 ; } src += offset ; mdlLen -= offset ; } while ( csumDataLen && ( currentMdl != NULL ) ) { ASSERT ( mdlLen < 65536 ) ; csLen = MIN ( ( UINT16 ) mdlLen , csumDataLen ) ; csum = CalculateOnesComplement ( src , csLen , csum , ! ( 1 & csumDataLen ) ) ; fold64 ( csum ) ; csumDataLen -= csLen ; currentMdl = NDIS_MDL_LINKAGE ( currentMdl ) ; if ( csumDataLen && currentMdl ) { src = OvsGetMdlWithLowPriority ( currentMdl ) ; if ( ! src ) { return 0 ; } mdlLen = MmGetMdlByteCount ( currentMdl ) ; mdlLen = MIN ( mdlLen , packetLen ) ; packetLen -= mdlLen ; ASSERT ( ( INT ) packetLen >= 0 ) ; } } fold64 ( csum ) ; ASSERT ( csumDataLen == 0 ) ; ASSERT ( ( csum & ~ 0xffff ) == 0 ) ; csum = ( UINT16 ) ~ csum ; if ( swapEnd ) { return _byteswap_ushort ( ( UINT16 ) csum ) ; } return ( UINT16 ) csum ; }
CalculateChecksumNB
 Calculates checksum over a length of bytes contained in an NB.
CalculateChecksumNB Calculates checksum over a length of bytes contained in an NB .
/* Running count of bytes in remainder of the MDLs including current. */ /* packetLen does not include the current MDL from here on. */