Partilhar via


Descarga de segmentação UDP (USO)

A descarregamento de segmentação UDP (USO), suportada no Windows 10, versão 2004 e posterior, é um recurso que permite às placas de interface de rede (NICs) descarregarem a segmentação de datagramas UDP que são maiores do que a unidade de transmissão máxima (MTU) do meio 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 a grande descarregamento de envio versão 2 (LSOv2), que é para o protocolo de transporte TCP.

Requisitos para a OSU

Esta seção refere-se principalmente ao protocolo NDIS e drivers de miniporta. Os drivers NDIS de filtro leves (LWFs) devem seguir os requisitos do driver de protocolo ao modificar ou enviar pacotes e podem assumir que todos os pacotes fornecidos ao manipulador FilterSendNetBufferLists atendem aos requisitos do driver de protocolo.

Os drivers de miniporta podem descarregar a segmentação de pacotes UDP grandes que são maiores do que a MTU da mídia de rede. Uma NIC que ofereça suporte à segmentação de pacotes UDP grandes também deve ser capaz de fazer o seguinte:

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

Um driver de miniporta que suporte USO deve determinar o tipo de descarga a partir das informações fora de banda (OOB) da estrutura de NET_BUFFER_LIST. Se o valor da estrutura NDIS_UDP_SEGMENTATION_OFFLOAD_NET_BUFFER_LIST_INFO for diferente de zero, o driver de miniporta deverá executar USO. Qualquer NET_BUFFER_LIST que contenha dados USO OOB contém também uma única estrutura NET_BUFFER. No entanto, no caso em que o driver de miniporta recebeu OID_TCP_OFFLOAD_PARAMETERS para desligar o USO, depois que o driver de miniporta tiver concluído o OID com êxito, ele deve 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 do que o tamanho máximo do segmento (MSS) * (MinSegmentCount - 1).
  • Se o driver de miniporta não definir a capacidade de SubMssFinalSegmentSupported, cada pacote UDP grande descarregado pelo transporte deverá ter Length % MSS == 0. Ou seja, o pacote grande é divisível em N pacotes com cada segmento de pacote contendo exatamente MSS bytes de usuário. Se o driver da miniporta definir a capacidade de SubMssFinalSegmentSupported, essa condição de divisibilidade do comprimento do pacote no transporte não se aplica. Em outras palavras, o segmento final pode ser inferior a MSS.
  • O pacote não é um pacote de loopback.
  • O bit MF no cabeçalho IP do grande pacote UDP transportado pelo TCP/IP não será ativado, 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 a informação de segmentação de pacotes grandes que está associada à estrutura NET_BUFFER_LIST. Esta informação é uma estrutura NDIS_UDP_SEGMENTATION_OFFLOAD_NET_BUFFER_LIST_INFO pertencente às informações OOB da estrutura NET_BUFFER_LIST. O transporte TCP/IP define o valor MSS para o MSS desejado.
  • Calcula uma soma de complemento para o pseudocabeçalho UDP e grava essa soma no campo Checksum do cabeçalho UDP. O transporte TCP/IP calcula a soma dos complementos nos seguintes campos no pseudocabeçalho: Endereço IP de origem, Endereço IP de destino e Protocolo.

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

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

Importante

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

Envio de pacotes com USO

Depois de o driver de miniporta obter o NET_BUFFER_LIST na sua função de retorno de chamada MiniportSendNetBufferLists, ele pode chamar a macro NET_BUFFER_LIST_INFO com _Id de UdpSegmentationOffloadInfo para obter o valor MSS e o protocolo IP.

O driver de miniporta obtém o comprimento total do pacote grande a partir 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. Somente o último pacote que foi criado a partir do pacote grande segmentado deve conter menos de MSS bytes de dados do usuário. Todos os outros pacotes que foram criados a partir do pacote segmentado devem conter MSS bytes de dados do usuário. Se um driver de miniporta não aderir a essa regra, os datagramas UDP serão entregues incorretamente. Se o driver de miniporta não definir a capacidade de SubMssFinalSegmentSupported, o comprimento do pacote será dividido por MSS e cada um dos pacotes segmentados conterá MSS bytes de usuário.

O driver de miniporta afixa cabeçalhos MAC, IP e UDP em cada segmento derivado do pacote grande. O driver de miniporta deve calcular as somas de verificação IP e UDP para esses pacotes derivados. Para calcular a soma de verificação 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 útil UDP), adiciona essa soma de verificação à soma de complemento de uns para o pseudocabeçalho que foi calculado pelo transporte TCP/IP e depois calcula o complemento de uns 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 miniporta atribui a MaxOffLoadSize.

Depois que um driver emite uma indicação de status para indicar uma alteração para MaxOffLoadSize, o driver não deve causar uma verificação de bug se receber uma solicitação de envio LSO que usa o valor de MaxOffLoadSize anterior. Em vez disso, o driver deve rejeitar a solicitação de envio. Os drivers devem rejeitar qualquer solicitação de envio que não possam executar, por qualquer razão (incluindo tamanho, contagem mínima de segmentos, opções de IP, etc.). Os condutores devem enviar uma indicação de estado o mais rapidamente possível se as suas capacidades mudarem.

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

Um driver intermediário de miniporta que responda a OID_TCP_OFFLOAD_PARAMETERS para desativar os serviços de USO deve estar preparado para um curto período de tempo em que as solicitações de USO ainda possam chegar ao driver de miniporta.

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

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

Os controladores de miniporta compatíveis com USO também devem realizar o seguinte:

  • Suporta IPv4 e IPv6.
  • Ofereça 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 identificação IP (ID 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, 0x0001e assim por diante.
  • Se o pacote UDP grande contiver opções IP, o driver de miniporta copiará essas opções, inalteradas, para cada pacote derivado do pacote UDP grande.
  • Use o deslocamento em bytes no membro UdpHeaderOffset de NDIS_UDP_SEGMENTATION_OFFLOAD_NET_BUFFER_LIST_INFO para determinar o local do cabeçalho UDP, começando no primeiro byte do pacote.
  • Incremente as estatísticas de transmissão com base nos pacotes segmentados. Por exemplo, inclua a contagem de bytes dos cabeçalhos ethernet, IP e UDP para cada segmento de pacote, e o número de pacotes equivale aos segmentos do tamanho de MSS, e não de 1.
  • Defina os campos comprimento total UDP e comprimento IP 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 drivers TCP/IP do host aproveite os recursos de USO expostos pelos drivers de miniporta.

O NDIS e o driver de miniporta executam o seguinte:

  • Divulgue que a NIC suporta a funcionalidade USO
  • Ativar ou desativar a USO
  • Obter o estado atual da funcionalidade USO

Capacidade de publicidade USO

Os drivers de miniport anunciam a capacidade de USO preenchendo o campo UdpSegmentation da estrutura de NDIS_OFFLOAD, que é passado como parte dos 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 da USO

O estado atual do USO pode ser consultado através de OID_TCP_OFFLOAD_CURRENT_CONFIG. O NDIS lida com este OID e não o passa para o controlador miniport.

Alterando o estado do USO

A USO pode ser ativada ou desativada usando OID_TCP_OFFLOAD_PARAMETERS. Após o driver de miniporta processar o OID, ele deve enviar uma indicação de status NDIS_STATUS_TASK_OFFLOAD_CURRENT_CONFIG 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 a USO está habilitada ou desabilitada para esse protocolo IP específico. As configurações de USO não dependem da configuração NDIS_TCP_IP_CHECKSUM_OFFLOAD. Por exemplo, desativar *UDPChecksumOffloadIPv4 não desativa implicitamente *UsoIPv4.

Nome da subchave Descrição do parâmetro Valor Descrição do Enum
*UsoIPv4 USO (IPv4) 0 Desabilitado
1 Ativado
*UsoIPv6 USO (IPV6) 0 Desabilitado
1 Ativado