다음을 통해 공유


UDP 수신 세그먼트 병합 오프로드(URO)

Windows 11 버전 24H2부터 UDP URO(수신 세그먼트 병합 오프로드)를 사용하면 NIC(네트워크 인터페이스 카드)가 UDP 수신 세그먼트를 병합할 수 있습니다. NIC는 규칙 집합과 일치하는 동일한 흐름의 UDP 데이터그램을 논리적으로 연속된 버퍼로 결합할 수 있습니다. 이러한 결합된 데이터그램은 Windows 네트워킹 스택에 단일 큰 패킷으로 표시됩니다.

UDP 데이터그램을 병합하면 대역폭이 높은 흐름에서 패킷을 처리하는 데 드는 CPU 비용이 줄어들어 처리량이 늘어나고 바이트당 주기가 줄어듭니다.

다음 섹션에서는 UDP 패킷을 병합하는 규칙과 URO 미니포트 드라이버를 작성하는 방법에 대해 설명합니다.

UDP 패킷 병합 규칙

URO 병합은 다음 조건을 모두 충족하는 패킷에서만 시도할 수 있습니다.

  • IpHeader.Version 은 모든 패킷에 대해 동일합니다.
  • IpHeader.SourceAddressIpHeader.DestinationAddress 는 모든 패킷에 대해 동일합니다.
  • UdpHeader.SourcePortUdpHeader.DestinationPort 는 모든 패킷에 대해 동일합니다.
  • UdpHeader.Length 는 마지막 패킷을 제외한 모든 패킷에 대해 동일하며, 더 적을 수 있습니다.
  • UdpHeader.Length는 0이 아니어야 합니다.
  • UdpHeader.Checksum(0이 아닌 경우)은 모든 패킷에서 정확해야 합니다. 즉, 수신 검사sum 오프로드는 패킷의 유효성을 검사해야 합니다.
  • 계층 2 헤더는 모든 패킷에 대해 동일해야 합니다.

패킷이 IPv4인 경우 다음 조건도 충족해야 합니다.

  • 모든 패킷에 대한 IPv4Header.Protocol == 17(UDP)입니다.
  • EthernetHeader.EtherType == 모든 패킷에 대한 0x0800.
  • 수신된 패킷의 IPv4Header.HeaderChecksum 이 올바르야 합니다. 즉, 수신 검사sum 오프로드는 헤더의 유효성을 검사해야 합니다.
  • 모든 패킷에 대한 IPv4Header.HeaderLength == 5(IPv4 옵션 헤더 없음)
  • IPv4Header.ToS 는 모든 패킷에 대해 동일합니다.
  • IPv4Header.ECN 은 모든 패킷에 대해 동일합니다.
  • IPv4Header.DontFragment 는 모든 패킷에 대해 동일합니다.
  • IPv4Header.TTL 은 모든 패킷에 대해 동일합니다.
  • 모든 패킷에 대한 IPv4Header.TotalLength == UdpHeader.Length + length(IPv4Header).

패킷이 IPv6인 경우 다음 조건도 충족해야 합니다.

  • 모든 패킷(확장 헤더 없음)에 대한 IPv6Header.NextHeader == 17(UDP)입니다.
  • 모든 패킷에 대한 EthernetHeader.EtherType == 0x86dd(IPv6)입니다.
  • IPv6Header.TrafficClassIPv6Header.ECN 은 모든 패킷에 대해 동일합니다.
  • IPv6Header.FlowLabel 은 모든 패킷에 대해 동일합니다.
  • IPv6Header.HopLimit 는 모든 패킷에 대해 동일합니다.
  • 모든 패킷에 대한 IPv6Header.PayloadLength == UdpHeader.Length 입니다.

URO 패킷 구조

결과 SCU(Single Coalesced Unit)에는 단일 IP 헤더와 UDP 헤더가 있어야 하며, 그 다음에는 결합된 모든 데이터그램에 대한 UDP 페이로드가 함께 연결되어야 합니다.

URO 표시는 IPv4Header.TotalLength 필드를 SCU의 총 길이로 설정하거나 IPv6Header.PayloadLength 필드를 UDP 페이로드 및 UdpHeader.Length 필드의 길이로 병합된 페이로드의 길이로 설정해야 합니다.

계층 2(L2) 헤더가 병합된 데이터그램에 있는 경우 SCU에는 유효한 L2 헤더가 포함되어야 합니다. SCU의 L2 헤더는 병합된 데이터그램의 L2 헤더와 유사해야 합니다.

체크섬 유효성 검사 및 표시

URO 표시는 IPv4Header.HeaderChecksumUdpHeader.Checksum 필드를 0으로 설정하고 IPv4 및 UDP 검사sum 성공을 나타내는 SCU의 검사sum 오프로드 대역 외 정보를 입력해야 합니다.

병합되는 모든 조건과 일치하지만 검사섬 유효성 검사에 실패하는 패킷은 별도로 표시되어야 합니다. 수신된 패킷은 이전에 받은 패킷과 병합되어서는 안 됩니다.

예를 들어 패킷 1, 2, 3, 4 및 5가 동일한 흐름에서 수신되지만 패킷 3은 검사섬 유효성 검사에 실패한다고 가정합니다. 패킷 1과 2는 함께 병합할 수 있으며 패킷 4와 5는 함께 병합할 수 있지만 패킷 3은 SCU와 결합되어서는 안 됩니다. 패킷 1과 2는 패킷 4 및 5와 함께 병합하면 안 됩니다. 패킷 2는 SCU의 마지막 패킷이며 패킷 4는 새 SCU를 시작합니다. 또한 패킷 1과 2를 포함하는 SCU는 패킷 3이 표시되기 전에 표시해야 하며 패킷 3은 패킷 4와 5를 포함하는 SCU 앞에 표시되어야 합니다.

패킷 병합 및 흐름 분리

하드웨어 및 메모리 허용으로 여러 흐름의 패킷이 병렬로 병합될 수 있습니다. 서로 다른 흐름의 패킷을 함께 병합하면 안 됩니다.

인터리브된 여러 수신의 패킷은 해당 흐름과 분리되고 병합될 수 있습니다. 예를 들어, 지정된 흐름 A, B 및 C에서 패킷이 A, A, B, C, B, A 순서로 도착하면 A 흐름의 패킷이 AAA로 병합되고 B 흐름의 패킷이 BB로 병합되는 반면 C 흐름의 패킷은 정상적으로 표시되거나 흐름 C에서 보류 중인 SCU와 병합될 수 있습니다.

지정된 흐름 내의 패킷은 서로 관련하여 순서를 다시 지정해서는 안 됩니다. 예를 들어 A 흐름의 패킷은 그 사이에 수신된 B 및 C 흐름의 패킷에 관계없이 수신된 순서대로 병합되어야 합니다.

URO 제어를 위한 INF 키워드(keyword)

다음 키워드(keyword) 레지스트리 키 설정으로 URO를 사용하거나 사용하지 않도록 설정하는 데 사용할 수 있습니다.

*UdpRsc

표준화된 INF 키워드(keyword) 열거형에는 다음과 같은 특성이 있습니다.

SubkeyName
INF 파일에서 지정해야 하고 레지스트리에 표시되는 키워드(keyword) 이름입니다.

ParamDesc
SubkeyName과 연결된 표시 텍스트입니다.


목록의 각 옵션과 연결된 열거형 정수 값입니다. 이 값은 NDI\params\ SubkeyName 값에\저장됩니다.

EnumDesc
메뉴에 표시되는 각 값과 연결된 표시 텍스트입니다.

기본값
메뉴의 기본값입니다.

SubkeyName ParamDesc EnumDesc
*UdpRsc Uro 0 사용 안 함
1(기본값) 활성화

열거형 키워드(keyword) 사용에 대한 자세한 내용은 열거형 키워드를 참조하세요.

URO 미니포트 드라이버 작성

NDIS 6.89부터 URO용 NDIS 인터페이스는 TCP/IP와 NDIS 미니포트 드라이버 간의 통신을 용이하게 합니다.

URO 기능 보고

미니포트 드라이버는 NdisMSetMiniportAttributes 함수에 전달되는 NDIS_OFFLOAD 구조체의 UdpRsc 멤버에서 URO에 대한 지원을 보급합니다.

쿼리 URO 기능

미니포트 드라이버가 URO를 지원하는지 검사 위해 NDIS 드라이버 및 기타 애플리케이션은 NDIS_OFFLOAD 구조를 반환하는 OID_TCP_OFFLOAD_HARDWARE_CAPABILITIES OID를 쿼리할 수 있습니다.

URO 상태 쿼리

현재 URO 상태를 확인하기 위해 NDIS 드라이버 및 기타 애플리케이션은 OID_TCP_OFFLOAD_CURRENT_CONFIG OID 요청을 쿼리할 수 있습니다. NDIS는 이 OID를 처리하고 미니포트에 전달하지 않습니다.

URO 상태 변경

URO는 OID_TCP_OFFLOAD_PARAMETERS OID 요청을 실행하여 사용하거나 사용하지 않도록 설정할 수 있습니다. 이 OID는 NDIS_OFFLOAD_PARAMETERS 구조를 사용합니다. 이 구조 에서 UdpRsc.Enabled 멤버는 다음 값을 가질 수 있습니다.

의미
NDIS_OFFLOAD_PARAMETERS_UDP_RSC_NO_CHANGE
0
미니포트 드라이버는 현재 설정을 변경하지 않아야 합니다.
NDIS_OFFLOAD_PARAMETERS_UDP_RSC_DISABLED
1
URO를 사용할 수 없습니다.
NDIS_OFFLOAD_PARAMETERS_UDP_RSC_ENABLED
2
URO를 사용할 수 있습니다.

드라이버가 플래그 집합을 NDIS_OFFLOAD_PARAMETERS_UDP_RSC_DISABLED 사용하여 OID_TCP_OFFLOAD_PARAMETERS OID 요청을 처리하는 경우 NIC는 기존의 모든 병합 세그먼트와 미해결 URO 표시가 표시될 때까지 요청을 완료하기 위해 기다려야 합니다. 이렇게 하면 NDIS 구성 요소 간에 URO 사용/사용 안 함 이벤트가 동기화됩니다.

미니포트 드라이버가 OID_TCP_OFFLOAD_PARAMETERS OID 요청을 처리한 후 미니포트 드라이버는 업데이트된 오프로드 상태와 함께 NDIS_STATUS_TASK_OFFLOAD_CURRENT_CONFIG 상태 표시를 실행해야 합니다.

NDIS_OFFLOAD_PARAMETERS_SKIP_REGISTRY_UPDATE NDIS_OFFLOAD_PARAMETERS 플래그를 사용하면 URO를 런타임 전용으로 비활성화할 수 있습니다. 이 플래그로 변경한 내용은 레지스트리에 저장되지 않습니다.

NDIS 6.89 이상에서 URO 옵트아웃

NDIS 6.89 이상을 대상으로 하는 드라이버는 URO 패킷을 이해하고 정상적으로 처리해야 합니다. URO를 옵트아웃하려면:

  • LWF(경량 필터) 드라이버는 NDIS_FILTER_DRIVER_CHARACTERISTICS 구조에서 플래그를 설정합니다NDIS_FILTER_DRIVER_UDP_RSC_NOT_SUPPORTED.
  • 프로토콜 드라이버는 NDIS_PROTOCOL_DRIVER_CHARACTERISTICS 구조에서 플래그를 설정합니다NDIS_PROTOCOL_DRIVER_UDP_RSC_NOT_SUPPORTED.

이 방법을 사용하면 URO에 익숙하지 않은 구성 요소가 URO NCL을 수신하지 않습니다. URO를 지원하지 않는 LWF 또는 프로토콜 드라이버가 있는 경우 NDIS는 바인딩하는 동안 미니포트에서 URO를 사용하지 않도록 설정합니다.

URO 드라이버에 대한 프로그래밍 고려 사항

URO 지원 미니포트 드라이버를 구현할 때 다음 문제를 고려합니다.

Winsock URO API

Winsock URO API에 대한 자세한 내용은 IPPROTO_UDP 소켓 옵션을 참조 하세요. UDP_RECV_MAX_COALESCED_SIZE 및 UDP_COALESCED_INFO 대한 정보를 참조하세요.

Windows TCP/IP 스택 업데이트

Microsoft TCP/IP 전송을 사용하면 구성에서 이를 방지하지 않는 한 NDIS와 함께 바인딩할 때 URO를 사용할 수 있습니다.

WFP 설명선은 FWPS_CALLOUT2 URO에 대한 지원을 보급하는 데 사용할 FWP_CALLOUT_FLAG_ALLOW_URO수 있습니다. 호환되지 않는 WFP 설명선이 URO 구분 계층에 등록된 경우 설명선이 등록된 동안 OS는 URO를 사용하지 않도록 설정합니다.

소켓이 하드웨어 오프로드 크기보다 크거나 같은 최대 병합된 크기로 URO에 옵트인하는 경우 스택은 수정되지 않은 하드웨어의 NCL을 소켓으로 전달합니다. 소켓이 더 작은 최대 병합된 크기로 옵트인하는 경우 스택은 병합된 수신을 소켓의 더 작은 크기로 중단합니다.

소켓이 URO에 옵트인하지 않는 경우 스택은 해당 소켓에 대해 수신을 다시 설정합니다. 하드웨어 URO가 없으면 기존 소프트웨어 URO 기능을 계속 사용할 수 있습니다.