datapath-windows/ovsext/User.c
/*
 *----------------------------------------------------------------------------
 * This function completes the IP Header csum. record the L4 payload offset and
 * if there is a need to calculate the TCP or UDP csum. The actual csum will be
 * caluculated simopultaneossly with the copy of the payload to the destination
 * buffer when the packet is read.
 *----------------------------------------------------------------------------
 */
This function completes the IP Header csum. record the L4 payload offset and
if there is a need to calculate the TCP or UDP csum. The actual csum will be
caluculated simopultaneossly with the copy of the payload to the destination
buffer when the packet is read.
This function completes the IP Header csum . record the L4 payload offset and if there is a need to calculate the TCP or UDP csum . The actual csum will be caluculated simopultaneossly with the copy of the payload to the destination buffer when the packet is read .
static VOID
OvsCompletePacketHeader(UINT8 *packet,
                        BOOLEAN isRecv,
                        NDIS_TCP_IP_CHECKSUM_NET_BUFFER_LIST_INFO csumInfo,
                        POVS_PACKET_HDR_INFO hdrInfoIn,
                        POVS_PACKET_HDR_INFO hdrInfoOut)
{
    if ((isRecv && csumInfo.Receive.IpChecksumValueInvalid) ||
        (!isRecv && csumInfo.Transmit.IsIPv4 &&
        csumInfo.Transmit.IpHeaderChecksum)) {
        PIPV4_HEADER ipHdr = (PIPV4_HEADER)(packet + hdrInfoOut->l3Offset);
        ASSERT(hdrInfoIn->isIPv4);
        ASSERT(ipHdr->Version == 4);
        ipHdr->HeaderChecksum = IPChecksum((UINT8 *)ipHdr,
            ipHdr->HeaderLength << 2,
            (UINT16)~ipHdr->HeaderChecksum);
        ovsUserStats.ipCsum++;
    }
    ASSERT(hdrInfoIn->tcpCsumNeeded == 0 && hdrInfoOut->udpCsumNeeded == 0);
    if (isRecv && csumInfo.Receive.TcpChecksumValueInvalid) {
        PTCP_HDR tcpHdr = (PTCP_HDR)(packet + hdrInfoIn->l4Offset);
        if (hdrInfoIn->isIPv4) {
            PIPV4_HEADER ipHdr = (PIPV4_HEADER)(packet + hdrInfoIn->l3Offset);
            hdrInfoOut->l4PayLoad = (UINT16)(ntohs(ipHdr->TotalLength) -
                                    (ipHdr->HeaderLength << 2));
            tcpHdr->th_sum = IPPseudoChecksum((UINT32 *)&ipHdr->SourceAddress,
                                         (UINT32 *)&ipHdr->DestinationAddress,
                                         IPPROTO_TCP, hdrInfoOut->l4PayLoad);
        } else {
            PIPV6_HEADER ipv6Hdr = (PIPV6_HEADER)(packet +
                                                  hdrInfoIn->l3Offset);
            hdrInfoOut->l4PayLoad =
                (UINT16)(ntohs(ipv6Hdr->PayloadLength) +
                hdrInfoIn->l3Offset + sizeof(IPV6_HEADER)-
                hdrInfoIn->l4Offset);
            ASSERT(hdrInfoIn->isIPv6);
            tcpHdr->th_sum =
                IPv6PseudoChecksum((UINT32 *)&ipv6Hdr->SourceAddress,
                (UINT32 *)&ipv6Hdr->DestinationAddress,
                IPPROTO_TCP, hdrInfoOut->l4PayLoad);
        }
        hdrInfoOut->tcpCsumNeeded = 1;
        ovsUserStats.recalTcpCsum++;
    } else if (!isRecv) {
        if (hdrInfoIn->isTcp && csumInfo.Transmit.TcpChecksum) {
            hdrInfoOut->tcpCsumNeeded = 1;
        } else if (hdrInfoIn->isUdp && csumInfo.Transmit.UdpChecksum) {
            hdrInfoOut->udpCsumNeeded = 1;
        }
        if (hdrInfoOut->tcpCsumNeeded || hdrInfoOut->udpCsumNeeded) {
#ifdef DBG
            UINT16 sum, *ptr;
            UINT8 proto =
                hdrInfoOut->tcpCsumNeeded ? IPPROTO_TCP : IPPROTO_UDP;
#endif
            if (hdrInfoIn->isIPv4) {
                PIPV4_HEADER ipHdr = (PIPV4_HEADER)(packet +
                                                    hdrInfoIn->l3Offset);
                hdrInfoOut->l4PayLoad = (UINT16)(ntohs(ipHdr->TotalLength) -
                    (ipHdr->HeaderLength << 2));
#ifdef DBG
                sum = IPPseudoChecksum((UINT32 *)&ipHdr->SourceAddress,
                    (UINT32 *)&ipHdr->DestinationAddress,
                    proto, hdrInfoOut->l4PayLoad);
#endif
            } else {
                PIPV6_HEADER ipv6Hdr = (PIPV6_HEADER)(packet +
                    hdrInfoIn->l3Offset);
                hdrInfoOut->l4PayLoad =
                    (UINT16)(ntohs(ipv6Hdr->PayloadLength) +
                    hdrInfoIn->l3Offset + sizeof(IPV6_HEADER)-
                    hdrInfoIn->l4Offset);
                ASSERT(hdrInfoIn->isIPv6);
#ifdef DBG
                sum = IPv6PseudoChecksum((UINT32 *)&ipv6Hdr->SourceAddress,
                    (UINT32 *)&ipv6Hdr->DestinationAddress,
                    proto, hdrInfoOut->l4PayLoad);
#endif
            }
#ifdef DBG
            ptr = (UINT16 *)(packet + hdrInfoIn->l4Offset +
                (hdrInfoOut->tcpCsumNeeded ?
            TCP_CSUM_OFFSET : UDP_CSUM_OFFSET));
            ASSERT(*ptr == sum);
#endif
        }
    }
}
static VOID OvsCompletePacketHeader ( UINT8 * packet , BOOLEAN isRecv , NDIS_TCP_IP_CHECKSUM_NET_BUFFER_LIST_INFO csumInfo , POVS_PACKET_HDR_INFO hdrInfoIn , POVS_PACKET_HDR_INFO hdrInfoOut ) { if ( ( isRecv && csumInfo . Receive . IpChecksumValueInvalid ) || ( ! isRecv && csumInfo . Transmit . IsIPv4 && csumInfo . Transmit . IpHeaderChecksum ) ) { PIPV4_HEADER ipHdr = ( PIPV4_HEADER ) ( packet + hdrInfoOut -> l3Offset ) ; ASSERT ( hdrInfoIn -> isIPv4 ) ; ASSERT ( ipHdr -> Version == 4 ) ; ipHdr -> HeaderChecksum = IPChecksum ( ( UINT8 * ) ipHdr , ipHdr -> HeaderLength << 2 , ( UINT16 ) ~ ipHdr -> HeaderChecksum ) ; ovsUserStats . ipCsum ++ ; } ASSERT ( hdrInfoIn -> tcpCsumNeeded == 0 && hdrInfoOut -> udpCsumNeeded == 0 ) ; if ( isRecv && csumInfo . Receive . TcpChecksumValueInvalid ) { PTCP_HDR tcpHdr = ( PTCP_HDR ) ( packet + hdrInfoIn -> l4Offset ) ; if ( hdrInfoIn -> isIPv4 ) { PIPV4_HEADER ipHdr = ( PIPV4_HEADER ) ( packet + hdrInfoIn -> l3Offset ) ; hdrInfoOut -> l4PayLoad = ( UINT16 ) ( ntohs ( ipHdr -> TotalLength ) - ( ipHdr -> HeaderLength << 2 ) ) ; tcpHdr -> th_sum = IPPseudoChecksum ( ( UINT32 * ) & ipHdr -> SourceAddress , ( UINT32 * ) & ipHdr -> DestinationAddress , IPPROTO_TCP , hdrInfoOut -> l4PayLoad ) ; } else { PIPV6_HEADER ipv6Hdr = ( PIPV6_HEADER ) ( packet + hdrInfoIn -> l3Offset ) ; hdrInfoOut -> l4PayLoad = ( UINT16 ) ( ntohs ( ipv6Hdr -> PayloadLength ) + hdrInfoIn -> l3Offset + sizeof ( IPV6_HEADER ) - hdrInfoIn -> l4Offset ) ; ASSERT ( hdrInfoIn -> isIPv6 ) ; tcpHdr -> th_sum = IPv6PseudoChecksum ( ( UINT32 * ) & ipv6Hdr -> SourceAddress , ( UINT32 * ) & ipv6Hdr -> DestinationAddress , IPPROTO_TCP , hdrInfoOut -> l4PayLoad ) ; } hdrInfoOut -> tcpCsumNeeded = 1 ; ovsUserStats . recalTcpCsum ++ ; } else if ( ! isRecv ) { if ( hdrInfoIn -> isTcp && csumInfo . Transmit . TcpChecksum ) { hdrInfoOut -> tcpCsumNeeded = 1 ; } else if ( hdrInfoIn -> isUdp && csumInfo . Transmit . UdpChecksum ) { hdrInfoOut -> udpCsumNeeded = 1 ; } if ( hdrInfoOut -> tcpCsumNeeded || hdrInfoOut -> udpCsumNeeded ) { #ifdef DBG UINT16 sum , * ptr ; UINT8 proto = hdrInfoOut -> tcpCsumNeeded ? IPPROTO_TCP : IPPROTO_UDP ; #endif if ( hdrInfoIn -> isIPv4 ) { PIPV4_HEADER ipHdr = ( PIPV4_HEADER ) ( packet + hdrInfoIn -> l3Offset ) ; hdrInfoOut -> l4PayLoad = ( UINT16 ) ( ntohs ( ipHdr -> TotalLength ) - ( ipHdr -> HeaderLength << 2 ) ) ; #ifdef DBG sum = IPPseudoChecksum ( ( UINT32 * ) & ipHdr -> SourceAddress , ( UINT32 * ) & ipHdr -> DestinationAddress , proto , hdrInfoOut -> l4PayLoad ) ; #endif } else { PIPV6_HEADER ipv6Hdr = ( PIPV6_HEADER ) ( packet + hdrInfoIn -> l3Offset ) ; hdrInfoOut -> l4PayLoad = ( UINT16 ) ( ntohs ( ipv6Hdr -> PayloadLength ) + hdrInfoIn -> l3Offset + sizeof ( IPV6_HEADER ) - hdrInfoIn -> l4Offset ) ; ASSERT ( hdrInfoIn -> isIPv6 ) ; #ifdef DBG sum = IPv6PseudoChecksum ( ( UINT32 * ) & ipv6Hdr -> SourceAddress , ( UINT32 * ) & ipv6Hdr -> DestinationAddress , proto , hdrInfoOut -> l4PayLoad ) ; #endif } #ifdef DBG ptr = ( UINT16 * ) ( packet + hdrInfoIn -> l4Offset + ( hdrInfoOut -> tcpCsumNeeded ? TCP_CSUM_OFFSET : UDP_CSUM_OFFSET ) ) ; ASSERT ( * ptr == sum ) ; #endif } } }
This function completes the IP Header csum.
This function completes the IP Header csum .
/*
     * calculate TCP/UDP pseudo checksum
     */ /*
         * Only this case, we need to reclaculate pseudo checksum
         * all other cases, it is assumed the pseudo checksum is
         * filled already.
         *
         */