Partilhar via


UDP recebem descarga coalescente de segmento (URO)

A partir do Windows 11, versão 24H2, o UDP receive segment coalescing offload (URO) permite que placas de interface de rede (NICs) coalescam segmentos de recebimento UDP. As NICs podem combinar datagramas UDP do mesmo fluxo que correspondem a um conjunto de regras em um buffer logicamente contíguo. Esses datagramas combinados são então indicados para a pilha de rede do Windows como um único pacote grande.

A coalescência de datagramas UDP reduz o custo da CPU para processar pacotes em fluxos de alta largura de banda, resultando em maior taxa de transferência e menos ciclos por byte.

As seções a seguir descrevem as regras para aglutinar pacotes UDP e como escrever um driver de miniporta URO.

Regras para aglutinar pacotes UDP

A coalescência URO só pode ser tentada em pacotes que atendam a todos os seguintes critérios:

  • IpHeader.Version é idêntico para todos os pacotes.
  • IpHeader.SourceAddress e IpHeader.DestinationAddress são idênticos para todos os pacotes.
  • UdpHeader.SourcePort e UdpHeader.DestinationPort são idênticos para todos os pacotes.
  • UdpHeader.Length é idêntico para todos os pacotes, exceto o último pacote, que pode ser menor.
  • UdpHeader.Length deve ser diferente de zero.
  • UdpHeader.Checksum, se for diferente de zero, deve estar correto em todos os pacotes. Isso significa que o descarregamento da soma de verificação de recebimento deve validar o pacote.
  • Layer 2 headers deve ser idêntico para todos os pacotes.

Se os pacotes forem IPv4, eles também devem atender aos seguintes critérios:

  • IPv4Header.Protocol == 17 (UDP) para todos os pacotes.
  • EthernetHeader.EtherType == 0x0800 para todos os pacotes.
  • O IPv4Header.HeaderChecksum no pacote recebido deve estar correto. Isso significa que receber o descarregamento da soma de verificação deve validar o cabeçalho.
  • IPv4Header.HeaderLength == 5 (sem cabeçalhos de opção IPv4) para todos os pacotes.
  • IPv4Header.ToS é idêntico para todos os pacotes.
  • IPv4Header.ECN é idêntico para todos os pacotes.
  • IPv4Header.DontFragment é idêntico para todos os pacotes.
  • IPv4Header.TTL é idêntico para todos os pacotes.
  • IPv4Header.TotalLength == UdpHeader.Length* + comprimento(IPv4Header) para todos os pacotes.

Se os pacotes forem IPv6, eles também devem atender aos seguintes critérios:

  • IPv6Header.NextHeader == 17 (UDP) para todos os pacotes (sem cabeçalhos de extensão).
  • EthernetHeader.EtherType == 0x86dd (IPv6) para todos os pacotes.
  • IPv6Header.TrafficClass e IPv6Header.ECN são idênticos para todos os pacotes.
  • IPv6Header.FlowLabel é idêntico para todos os pacotes.
  • IPv6Header.HopLimit é idêntico para todos os pacotes.
  • IPv6Header.PayloadLength == UdpHeader.Length para todos os pacotes.

Estrutura de pacotes URO

A unidade única coalescida (SCU) resultante deve ter um único cabeçalho IP e um cabeçalho UDP, seguidos pela carga útil UDP para todos os datagramas coalescentes concatenados.

As indicações URO devem definir o campo IPv4Header.TotalLength para o comprimento total da SCU, o campo IPv6Header.PayloadLength para o comprimento da carga útil UDP e o campo UdpHeader.Length para o comprimento das cargas úteis coalescidas.

Se os cabeçalhos de Camada 2 (L2) estiverem presentes em datagramas coalescidos, a SCU deverá conter um cabeçalho L2 válido. O cabeçalho L2 na SCU deve ser semelhante ao cabeçalho L2 dos datagramas coalescidos.

Validação e indicação do checksum

As indicações URO devem definir os campos IPv4Header.HeaderChecksum e UdpHeader.Checksum como zero e preencher as informações de descarregamento fora de banda da soma de verificação na SCU indicando o sucesso da soma de verificação IPv4 e UDP.

Um pacote que corresponda a todas as condições para ser coalescido, mas que não seja validado pela soma de verificação, deve ser indicado separadamente. Os pacotes recebidos após não devem ser agrupados com os pacotes recebidos antes.

Por exemplo, suponha que os pacotes 1, 2, 3, 4 e 5 sejam recebidos do mesmo fluxo, mas o pacote 3 falhe na validação da soma de verificação. Os pacotes 1 e 2 podem ser aglutinados, e os pacotes 4 e 5 podem ser aglutinados, mas o pacote 3 não deve ser aglutinado com nenhum dos SCU. Os pacotes 1 e 2 não devem ser aglutinados com os pacotes 4 e 5. O pacote 2 é o último pacote em uma SCU e o pacote 4 inicia uma nova SCU. Além disso, o SCU que contém os pacotes 1 e 2 deve ser indicado antes da indicação do pacote 3 e o pacote 3 deve ser indicado antes do SCU que contém os pacotes 4 e 5.

Coalescência de pacotes e separação de fluxo

Os pacotes de vários fluxos podem ser aglutinados em paralelo, conforme o hardware e a memória permitirem. Os pacotes provenientes de fluxos diferentes não devem ser aglutinados.

Os pacotes de múltiplos recebíveis intercalados podem ser separados e aglutinados com seus respetivos fluxos. Por exemplo, dados os fluxos A, B e C, se os pacotes chegassem na ordem A, A, B, C, B, A, os pacotes do fluxo A podem ser aglutinados em AAA, e os pacotes do fluxo B aglutinados em BB, enquanto o pacote do fluxo C pode ser indicado normalmente ou aglutinado com uma SCU pendente do fluxo C.

Os pacotes dentro de um determinado fluxo não devem ser reordenados uns em relação aos outros. Por exemplo, os pacotes do fluxo A devem ser aglutinados na ordem recebida, independentemente dos pacotes dos fluxos B e C recebidos entre eles.

Palavra-chave INF para controlar URO

A seguinte palavra-chave pode ser usada para ativar/desativar o URO com uma configuração de chave do Registro:

  • *UdpRsc

As palavras-chave INF padronizadas pela enumeração têm os seguintes atributos:

  • SubkeyName: O nome da palavra-chave que você deve especificar no arquivo INF e que aparece no registro.

  • ParamDesc: O texto de exibição associado a SubkeyName.

  • Valor: O valor inteiro de enumeração associado a cada opção na lista. Esse valor é armazenado em NDI\params\SubkeyName\Value.

  • EnumDesc: O texto de exibição associado a cada valor que aparece no menu.

  • Default: O valor padrão para o menu.

Nome da subchave ParamDesc Valor EnumDesc
*UdpRsc URO 0 Desabilitado
1 (Padrão) Ativado

Para obter mais informações sobre como usar palavras-chave de enumeração, consulte Palavras-chave de enumeração.

Escrever um controlador de miniporta URO

A partir do NDIS 6.89, a interface NDIS para URO facilita a comunicação entre o TCP/IP e o driver de miniporta NDIS.

Capacidade de relatório URO

Um driver de miniporta anuncia suporte para URO no membro da estrutura NDIS_OFFLOAD, que passa para a função NdisMSetMiniportAttributes.

Capacidade de consulta URO

Para verificar se um driver de miniporta suporta URO, os drivers NDIS e outras aplicações podem consultar os OIDs OID_TCP_OFFLOAD_HARDWARE_CAPABILITIES OID, que retornam a estrutura NDIS_OFFLOAD.

Consultar estado URO

Para determinar o estado atual do URO, os controladores NDIS e outras aplicações podem consultar a solicitação OID OID_TCP_OFFLOAD_CURRENT_CONFIG. O NDIS lida com esse OID e não o transmite para a miniporta.

Alterar o estado do URO

O URO pode ser ativado ou desativado emitindo a solicitação OID_TCP_OFFLOAD_PARAMETERS OID. Este OID usa uma estrutura NDIS_OFFLOAD_PARAMETERS. Nesta estrutura, o membro UdpRsc.Enabled pode ter os seguintes valores:

Valor Significado
NDIS_OFFLOAD_PARAMETERS_UDP_RSC_NO_CHANGE
0
O driver da miniporta não deve alterar a configuração atual.
NDIS_OFFLOAD_PARAMETERS_UDP_RSC_DISABLED
1
O URO está desativado.
NDIS_OFFLOAD_PARAMETERS_UDP_RSC_ENABLED
2
O URO está ativado.

Quando um driver processa uma solicitação OID OID_TCP_OFFLOAD_PARAMETERS com o sinalizador NDIS_OFFLOAD_PARAMETERS_UDP_RSC_DISABLED definido, a NIC deve esperar para concluir a solicitação até que todos os segmentos coalescidos existentes e as indicações URO pendentes sejam sinalizadas. Isso garante a sincronização de eventos de habilitação/desativação do URO entre os componentes NDIS.

Depois que o driver de miniporta processar a solicitação de OID de OID_TCP_OFFLOAD_PARAMETERS, o driver de miniporta deve emitir uma indicação de status de NDIS_STATUS_TASK_OFFLOAD_CURRENT_CONFIG com o estado de descarregamento atualizado.

O sinalizador NDIS_OFFLOAD_PARAMETERS_SKIP_REGISTRY_UPDATE em NDIS_OFFLOAD_PARAMETERS permite a desativação do URO somente em tempo de execução. As alterações feitas com esse sinalizador não são salvas no registro.

Desativação do URO no NDIS 6.89 e posterior

Os drivers que visam o NDIS 6.89 e posterior devem entender os pacotes URO e manipulá-los de forma eficiente. Para optar por não participar da URO:

Essa abordagem garante que os componentes que não estejam familiarizados com o URO não recebam NBLs de URO. O NDIS desativa o URO na miniporta durante a vinculação se um driver de protocolo ou LWF que não suporta URO estiver presente.

Considerações de programação para drivers URO

Considere os seguintes problemas ao implementar um driver de miniporta compatível com URO.

Winsock URO API

Para obter informações sobre a API Winsock URO, consulte IPPROTO_UDP opções de soquete. Consulte as informações sobre UDP_RECV_MAX_COALESCED_SIZE e UDP_COALESCED_INFO.

Atualizações de pilha de TCP/IP do Windows

O transporte TCP/IP da Microsoft habilita o URO no momento da ligação com NDIS, a menos que a configuração impeça isso.

Os textos explicativos do PMA podem usar FWP_CALLOUT_FLAG_ALLOW_URO em FWPS_CALLOUT2 para anunciar o seu apoio à URO. Se um módulo WFP incompatível for registado numa camada sensível ao URO, o sistema operativo desativará o URO enquanto o módulo estiver registado.

Se um soquete optar por URO com um tamanho máximo coalesced maior ou igual ao tamanho de descarregamento de hardware, a pilha entregará os NBLs do hardware não modificado para o soquete. Se um socket optar por um tamanho máximo agregado menor, a pilha divide o recebimento combinado no tamanho menor para o socket.

Se um soquete não optar por URO, a pilha resegmenta os recebimentos para esse soquete. Na ausência de hardware URO, o recurso de software URO existente continua disponível.