Descarregamento de segmentação UDP (USO)

O USO (descarregamento de segmentação de UDP), com suporte em Windows 10, versão 2004 e posterior, é um recurso que permite que as NICs (placas de interface de rede) descarregam a segmentação de datagramas UDP maiores que a MTU (unidade de transmissão máxima) da mídia de rede. Ao fazer isso, o Windows reduz a utilização da CPU associada ao processamento TCP/IP por pacote. Os requisitos para USO são semelhantes ao LSOv2, que é para o protocolo de transporte TCP.

Requisitos para USO

Esta seção refere-se principalmente ao protocolo NDIS e aos drivers de miniport. Os LWFs (drivers de filtro leve) do NDIS devem seguir os requisitos do driver de protocolo ao modificar ou enviar pacotes e também podem supor que todos os pacotes fornecidos ao manipulador FilterSendNetBufferLists atendam aos requisitos do driver de protocolo.

Os drivers de miniport podem descarregar a segmentação de pacotes UDP grandes que são maiores que a MTU do meio de rede. Uma NIC que dá suporte à segmentação de pacotes UDP grandes também deve ser capaz de fazer o seguinte:

  • Calcular somas de verificação de IP para pacotes enviados que contêm opções IPv4
  • Calcular somas de verificação UDP para pacotes enviados

Um driver de miniporto que dá suporte ao USO deve determinar o tipo de descarregamento das informações de OOB (fora de banda) da estrutura NET_BUFFER_LIST . Se o valor da estrutura NDIS_UDP_SEGMENTATION_OFFLOAD_NET_BUFFER_LIST_INFO for diferente de zero, o driver de miniporto deverá executar USO. Qualquer NET_BUFFER_LIST que contenha dados uso OOB também contém uma única estrutura de NET_BUFFER . No entanto, no caso em que o driver de miniporto recebeu OID_TCP_OFFLOAD_PARAMETERS para desativar USO, depois que o driver de miniporto tiver concluído o OID com êxito, ele deverá rejeitar e retornar qualquer NET_BUFFER_LIST que tenha o campo USO OOB definido.

O transporte TCP/IP descarrega apenas os pacotes UDP que atendem aos seguintes critérios:

  • O pacote é um pacote UDP.
  • O comprimento do pacote deve ser maior que o tamanho máximo do segmento (MSS) * (MinSegmentCount - 1).
  • Se o driver de miniporto não definir a funcionalidade SubMssFinalSegmentSupported , cada pacote UDP grande descarregado pelo transporte deverá ter o Tamanho % MSS == 0. Ou seja, o pacote grande é divisível em N pacotes com cada segmento de pacote contendo exatamente bytes de usuário mss . Se o driver de miniporto definir a funcionalidade SubMssFinalSegmentSupported , essa condição de divisibilidade de comprimento do pacote no transporte não se aplicará. Em outras palavras, o segmento final pode ser menor que MSS.
  • O pacote não é um pacote de loopback.
  • O bit MF no cabeçalho IP do pacote UDP grande que o transporte TCP/IP descarregado não será definido e o Deslocamento de Fragmento no cabeçalho IP será zero.
  • O aplicativo especificou UDP_SEND_MSG_SIZE/WSASetUdpSendMessageSize.

Antes de descarregar um pacote UDP grande para segmentação, o transporte TCP/IP faz o seguinte:

  • Atualizações as informações de segmentação de pacotes grandes associadas à estrutura NET_BUFFER_LIST. Essas informações são uma estrutura NDIS_UDP_SEGMENTATION_OFFLOAD_NET_BUFFER_LIST_INFO que faz parte das informações de OOB da estrutura NET_BUFFER_LIST . O transporte TCP/IP define o valor MSS como o MSS desejado.
  • Calcula a soma complementar de um para o pseudoheader UDP e grava essa soma no campo Soma de verificação do cabeçalho UDP. O transporte TCP/IP calcula a soma dos complementos dos seguintes campos no pseudoheader: Endereço IP de origem, Endereço IP de Destino e Protocolo.

A soma complementar para o pseudoheader fornecido pelo transporte TCP/IP fornece à NIC um início antecipado no cálculo da soma de verificação de UDP real para cada pacote que a NIC deriva do pacote UDP grande, sem precisar examinar o cabeçalho IP.

Observe que RFC 768 e RFC 2460 estipulam que o pseudoheader seja calculado sobre o Endereço IP de Origem, o Endereço IP de Destino, o Protocolo e o Comprimento do UDP (o comprimento do cabeçalho UDP mais o comprimento da carga UDP, não incluindo o comprimento do pseudoheader). No entanto, como o driver de miniporto subjacente e a NIC geram datagramas UDP a partir do pacote grande passado pelo transporte TCP/IP, o transporte não sabe o tamanho da carga UDP para cada datagrama UDP e, portanto, não pode incluir o Comprimento do UDP no cálculo do pseudoheader. Em vez disso, conforme descrito na seção a seguir, a NIC estende a soma de verificação do pseudoheader fornecida pelo transporte TCP/IP para cobrir o comprimento UDP de cada datagrama UDP gerado.

Importante

Se o campo de soma de verificação de cabeçalho UDP fornecido pelo transporte TCP/IP for zero, a NIC não deverá executar o cálculo de soma de verificação UDP.

Enviando pacotes com USO

Depois que o driver de miniporto obtém o NET_BUFFER_LIST em sua função de retorno de chamada MiniportSendNetBufferLists , ele pode chamar a macro NET_BUFFER_LIST_INFO com um _Id de UdpSegmentationOffloadInfo para obter o valor MSS e o protocolo IP.

O driver de miniporto obtém o comprimento total do pacote grande do comprimento da primeira estrutura NET_BUFFER e usa o valor MSS para dividir o pacote UDP grande em pacotes UDP menores. Cada um dos pacotes menores contém MSS ou menos bytes de dados do usuário. Observe que apenas o último pacote que foi criado com base no pacote grande segmentado deve conter menos de bytes de dados do usuário mss . Todos os outros pacotes que foram criados com base no pacote segmentado devem conter bytes de dados de usuário do MSS . Se um driver de miniporto não seguir essa regra, os datagramas UDP serão entregues incorretamente. Se o driver de miniporto não definir a funcionalidade SubMssFinalSegmentSupported , o comprimento do pacote será dividido pelo MSS e cada um dos pacotes segmentados conterá bytes de usuário mss .

O driver de miniporta afixa cabeçalhos MAC, IP e UDP para cada segmento derivado do pacote grande. O driver de miniporto deve calcular as somas de verificação ip e UDP para esses pacotes derivados. Para calcular a soma de verificação de UDP para cada pacote derivado do pacote UDP grande, a NIC calcula a parte variável da soma de verificação UDP (para o cabeçalho UDP e a carga UDP), adiciona essa soma de verificação à soma complementar do pseudoheader calculado pelo transporte TCP/IP e calcula o complemento de 16 bits para a soma de verificação. Para obter mais informações sobre como calcular essas somas de verificação, consulte RFC 768 e RFC 2460.

O comprimento dos dados do usuário UDP no pacote UDP grande deve ser menor ou igual ao valor que o driver de miniporto atribui ao valor MaxOffLoadSize .

Depois que um driver emite uma indicação de status para indicar uma alteração no valor MaxOffLoadSize, o driver não deve causar um bug marcar se receber uma solicitação de envio de LSO que usa o valor MaxOffLoadSize anterior. Em vez disso, o driver deve falhar na solicitação de envio. Os drivers devem falhar em qualquer solicitação de envio que não possam executar, por qualquer motivo (incluindo tamanho, contagem mínima de segmentos, opções de IP etc.). Os drivers devem enviar uma indicação de status o mais rápido possível se suas funcionalidades forem alteradas.

Um driver intermediário que emite independentemente status indicações de que relatam uma alteração no valor MaxOffLoadSize deve garantir que o adaptador de miniporto subjacente que não tenha emitido uma indicação de status não obtenha nenhum pacote maior que o valor MaxOffLoadSize relatado pelo adaptador de miniporto.

Um driver intermediário de miniporto que responde a OID_TCP_OFFLOAD_PARAMETERS para desativar os serviços USO deve estar preparado para uma pequena janela de tempo em que as solicitações USO ainda possam alcançar o driver de miniporto.

O número de pacotes de segmentação que foram derivados do pacote UDP grande deve ser igual ou maior que o valor MinSegmentCount especificado pelo driver de miniport.

Ao processar um pacote UDP grande, o driver de miniport é responsável apenas por segmentar o pacote e afixar cabeçalhos MAC, IP e UDP para os pacotes derivados do pacote UDP grande. Se o miniporto não enviar pelo menos um pacote segmentado, o NBL deverá ser concluído com uma falha status. O miniporto pode continuar enviando pacotes subsequentes, mas não é necessário fazê-lo. A NBL não pode ser concluída de volta ao NDIS até que todos os pacotes segmentados tenham sido transmitidos ou falhados.

Os drivers de miniporto compatíveis com USO também devem fazer o seguinte:

  • Suporte a IPv4 e IPv6.
  • Suporte à replicação de opções IPv4 do pacote grande em cada pacote segmentado gerado pela NIC.
  • Use o cabeçalho IP e UDP na estrutura NET_BUFFER_LIST como um modelo para gerar cabeçalhos UDP e IP para cada pacote segmentado.
  • Use valores de ID de IP (identificação de IP) no intervalo de 0x0000 a 0xFFFF. Por exemplo, se o cabeçalho IP do modelo começar com um valor de campo identificação de 0xFFFE, o primeiro pacote de datagrama UDP deverá ter um valor de 0xFFFE, seguido por 0xFFFF, 0x0000, 0x0001 e assim por diante.
  • Se o pacote UDP grande contiver opções de IP, o driver de miniporto copiará essas opções, sem restrições, para cada pacote derivado do pacote UDP grande.
  • Use o deslocamento de bytes no membro UdpHeaderOffset de NDIS_UDP_SEGMENTATION_OFFLOAD_NET_BUFFER_LIST_INFO para determinar o local do cabeçalho UDP, começando a partir do primeiro byte do pacote.
  • Incrementar as estatísticas de transmissão com base nos pacotes segmentados. Por exemplo, inclua a contagem de bytes de cabeçalho Ethernet, IP e UDP para cada segmento de pacote e a contagem de pacotes é o número de segmentos do tamanho mss, não 1.
  • Defina os campos tamanho total e comprimento de IP da UDP com base em cada tamanho de datagrama segmentado.

Alterações na interface NDIS

Esta seção descreve as alterações no NDIS 6.83 que permitem que a pilha de driver TCP/IP do host aproveite os recursos uso expostos por drivers de miniport.

O NDIS e o driver de miniporte executam o seguinte:

  • Anunciar que a NIC dá suporte à funcionalidade USO
  • Habilitar ou desabilitar USO
  • Obter o estado atual da funcionalidade USO

Funcionalidade uso de publicidade

Os drivers de miniport anunciam a funcionalidade USO preenchendo o campo UdpSegmentation da estrutura NDIS_OFFLOAD , que é passado nos parâmetros de NdisMSetMiniportAttributes. O campo Header.Revision na estrutura NDIS_OFFLOAD deve ser definido como NDIS_OFFLOAD_REVISION_6 e o campo Header.Size deve ser definido como NDIS_SIZEOF_NDIS_OFFLOAD_REVISION_6.

Consultando o estado USO

O estado uso atual pode ser consultado com OID_TCP_OFFLOAD_CURRENT_CONFIG. O NDIS manipula essa OID e não a passa para o driver de miniporto.

Alterando o estado uso

USO pode ser habilitado ou desabilitado usando OID_TCP_OFFLOAD_PARAMETERS. Depois que o driver de miniporto processa o OID, ele deve enviar um NDIS_STATUS_TASK_OFFLOAD_CURRENT_CONFIG status indicação com o estado de descarregamento atualizado.

Palavras-chave USO

As palavras-chave de enumeração USO são as seguintes:

  • *UsoIPv4
  • *UsoIPv6

Esses valores descrevem se USO está habilitado ou desabilitado para esse protocolo IP específico. As configurações uso não dependem da configuração de NDIS_TCP_IP_CHECKSUM_OFFLOAD . Por exemplo, desabilitar *UDPChecksumOffloadIPv4 não desabilita implicitamente *UsoIPv4.

Nome da subchave Descrição do parâmetro Valor Descrição da enumeração
*UsoIPv4 Descarregamento de segmentação UDP (IPv4) 0 Desabilitado
1 habilitado
*UsoIPv6 Descarregamento de segmentação UDP (IPV6) 0 Desabilitado
1 habilitado