datapath-windows/ovsext/User.c
/*
 *----------------------------------------------------------------------------
 * OvsCreateAndAddPackets --
 *
 *  Create a packet and forwarded to user space.
 *
 *  This function would fragment packet if needed, and queue
 *  each segment to user space.
 *----------------------------------------------------------------------------
 */
OvsCreateAndAddPackets
Create a packet and forwarded to user space.

This function would fragment packet if needed, and queue
each segment to user space.
OvsCreateAndAddPackets Create a packet and forwarded to user space . This function would fragment packet if needed and queue each segment to user space .
NTSTATUS
OvsCreateAndAddPackets(PVOID userData,
                       UINT32 userDataLen,
                       UINT32 cmd,
                       POVS_VPORT_ENTRY vport,
                       OvsFlowKey *key,
                       PNET_BUFFER_LIST nbl,
                       BOOLEAN isRecv,
                       POVS_PACKET_HDR_INFO hdrInfo,
                       POVS_SWITCH_CONTEXT switchContext,
                       LIST_ENTRY *list,
                       UINT32 *num)
{
    POVS_PACKET_QUEUE_ELEM elem;
    PNET_BUFFER_LIST newNbl = NULL;
    PNET_BUFFER nb;
    if (hdrInfo->isTcp) {
        NDIS_TCP_LARGE_SEND_OFFLOAD_NET_BUFFER_LIST_INFO tsoInfo;
        UINT32 packetLength;
        tsoInfo.Value = NET_BUFFER_LIST_INFO(nbl,
                                             TcpLargeSendNetBufferListInfo);
        nb = NET_BUFFER_LIST_FIRST_NB(nbl);
        packetLength = NET_BUFFER_DATA_LENGTH(nb);
        OVS_LOG_TRACE("MSS %u packet len %u",
                tsoInfo.LsoV1Transmit.MSS, packetLength);
        if (tsoInfo.LsoV1Transmit.MSS) {
            OVS_LOG_TRACE("l4Offset %d", hdrInfo->l4Offset);
            newNbl = OvsTcpSegmentNBL(switchContext, nbl, hdrInfo,
                                      tsoInfo.LsoV1Transmit.MSS , 0, FALSE);
            if (newNbl == NULL) {
                return NDIS_STATUS_FAILURE;
            }
            nbl = newNbl;
        }
    }
    nb = NET_BUFFER_LIST_FIRST_NB(nbl);
    while (nb) {
        elem = OvsCreateQueueNlPacket(userData, userDataLen,
                                    cmd, vport, key, NULL, nbl, nb,
                                    isRecv, hdrInfo);
        if (elem) {
            InsertTailList(list, &elem->link);
            (*num)++;
        }
        nb = NET_BUFFER_NEXT_NB(nb);
    }
    if (newNbl) {
        OvsCompleteNBL(switchContext, newNbl, TRUE);
    }
    return NDIS_STATUS_SUCCESS;
}
NTSTATUS OvsCreateAndAddPackets ( PVOID userData , UINT32 userDataLen , UINT32 cmd , POVS_VPORT_ENTRY vport , OvsFlowKey * key , PNET_BUFFER_LIST nbl , BOOLEAN isRecv , POVS_PACKET_HDR_INFO hdrInfo , POVS_SWITCH_CONTEXT switchContext , LIST_ENTRY * list , UINT32 * num ) { POVS_PACKET_QUEUE_ELEM elem ; PNET_BUFFER_LIST newNbl = NULL ; PNET_BUFFER nb ; if ( hdrInfo -> isTcp ) { NDIS_TCP_LARGE_SEND_OFFLOAD_NET_BUFFER_LIST_INFO tsoInfo ; UINT32 packetLength ; tsoInfo . Value = NET_BUFFER_LIST_INFO ( nbl , TcpLargeSendNetBufferListInfo ) ; nb = NET_BUFFER_LIST_FIRST_NB ( nbl ) ; packetLength = NET_BUFFER_DATA_LENGTH ( nb ) ; OVS_LOG_TRACE ( " " , tsoInfo . LsoV1Transmit . MSS , packetLength ) ; if ( tsoInfo . LsoV1Transmit . MSS ) { OVS_LOG_TRACE ( " " , hdrInfo -> l4Offset ) ; newNbl = OvsTcpSegmentNBL ( switchContext , nbl , hdrInfo , tsoInfo . LsoV1Transmit . MSS , 0 , FALSE ) ; if ( newNbl == NULL ) { return NDIS_STATUS_FAILURE ; } nbl = newNbl ; } } nb = NET_BUFFER_LIST_FIRST_NB ( nbl ) ; while ( nb ) { elem = OvsCreateQueueNlPacket ( userData , userDataLen , cmd , vport , key , NULL , nbl , nb , isRecv , hdrInfo ) ; if ( elem ) { InsertTailList ( list , & elem -> link ) ; ( * num ) ++ ; } nb = NET_BUFFER_NEXT_NB ( nb ) ; } if ( newNbl ) { OvsCompleteNBL ( switchContext , newNbl , TRUE ) ; } return NDIS_STATUS_SUCCESS ; }
OvsCreateAndAddPackets
  Create a packet and forwarded to user space.
OvsCreateAndAddPackets Create a packet and forwarded to user space .