다음을 통해 공유


VMQ 수신 경로

네트워크 어댑터는 해당 큐에 설정된 필터에 대한 모든 필터 필드 테스트를 통과하는 경우에만 큐에서 수신된 패킷을 나타냅니다. 필터 테스트에 대한 자세한 내용은 VMQ 필터 작업을 참조하세요.

오버레이 프로토콜 드라이버가 NDIS_RECEIVE_QUEUE_PARAMETERS 구조의 Flags 멤버에서 NDIS_RECEIVE_QUEUE_PARAMETERS_PER_QUEUE_RECEIVE_INDICATION 플래그를 설정하는 경우 미니포트 드라이버는 NdisMIndicateReceiveNetBufferLists 함수에 대한 단일 호출에서 다른 수신 큐에 대한 NET_BUFFER_LIST 구조를 이 큐에 대한 NET_BUFFER_LIST 구조와 혼합해서는 안 됩니다. 또한 드라이버는 NdisMIndicateReceiveNetBufferLists 함수의 ReceiveFlags 매개 변수에서 NDIS_RECEIVE_FLAGS_SINGLE_QUEUE 플래그를 설정해야 합니다.

NDIS_RECEIVE_QUEUE_PARAMETERS_PER_QUEUE_RECEIVE_INDICATION 설정되지 않은 경우 미니포트 드라이버는 다른 VM 큐의 프레임에 대한 NET_BUFFER_LIST 구조를 연결하고 NdisMIndicateReceiveNetBufferLists에 대한 단일 호출에서 이를 나타낼 수 있습니다. 이 경우 표시된 NET_BUFFER_LIST 구조의 연결된 목록을 큐 번호별로 정렬할 필요가 없습니다. 서로 다른 큐에 대한 NET_BUFFER_LIST 구조는 함께 그룹화할 필요가 없습니다.

프로토콜 드라이버가 NDIS_RETURN_FLAGS_SINGLE_QUEUE 설정하고 수신 버퍼를 반환하는 경우 NdisReturnNetBufferLists 함수의 NetBufferLists 매개 변수에 있는 모든 NET_BUFFER_LIST 구조가 동일한 VM 큐에 속해야 합니다. 그러나 프로토콜 드라이버는 NdisReturnNetBufferLists에 대한 단일 호출에서 ProtocolReceiveNetBufferLists 함수에 대한 단일 호출에 표시된 모든 NET_BUFFER_LIST 구조를 반환할 필요가 없습니다. 또한 반환된 목록에는 동일한 VM 큐에 속하는 경우 여러 수신 표시의 NET_BUFFER_LIST 구조가 포함될 수 있습니다.

프로토콜 드라이버는 반환된 모든 NET_BUFFER_LIST 구조가 동일한 VM 큐에 속함을 나타내기 위해 NdisReturnNetBufferListsReturnFlags 매개 변수에 NDIS_RETURN_FLAGS_SINGLE_QUEUE 비트를 설정합니다.

VMQ 수신 표시에는 NET_BUFFER_LIST 구조체의 NetBufferListInfo 멤버에 다음과 같은 OOB(out of band) 정보가 포함되어야 합니다.

  • NetBufferListFilteringInfo 정보에서 큐 식별자를 지정합니다.

  • NetBufferListFilteringInfo 정보의 필터 식별자를 0으로 설정합니다.

NetBufferListFilteringInfo 정보는 NDIS_NET_BUFFER_LIST_FILTERING_INFO 구조에 지정됩니다. NET_BUFFER_LIST OOB 데이터의 NDIS_NET_BUFFER_LIST_FILTERING_INFO 구조에 액세스하기 위해 NDIS 드라이버는 NET_BUFFER_LIST_INFO 매크로를 호출하고 NetBufferListFilteringInfo 정보 유형을 지정합니다.

필터 식별자 및 큐 식별자에 직접 액세스하려면 NET_BUFFER_LIST_RECEIVE_FILTER_IDNET_BUFFER_LIST_RECEIVE_QUEUE_ID 매크로를 사용합니다.

VMQ 수신 표시는 NET_BUFFER 구조의 SharedMemoryInfo 멤버에서 공유 메모리 정보를 정의해야 합니다.

참고 VMQ가 삭제되면(예: VM 실시간 마이그레이션 중) 미니포트 드라이버가 잘못된 QueueId 값이 포함된 NBL을 받을 수 있습니다. 이 경우 미니포트는 잘못된 큐 ID를 무시하고 대신 0(기본 큐)을 사용해야 합니다. QueueId는 NBL의 OOB 데이터의 NetBufferListFilteringInfo 부분에 있으며 NET_BUFFER_LIST_RECEIVE_QUEUE_ID 매크로를 사용하여 검색됩니다.

SharedMemoryInfoNET_BUFFER_SHARED_MEMORY 포인터가 유효함을 나타내려면 미니포트 드라이버는 NdisMIndicateReceiveNetBufferLists 함수의 ReceiveFlags 매개 변수에서 NDIS_RECEIVE_FLAGS_SHARED_MEMORY_INFO_VALID 플래그를 설정해야 합니다. VMQ 수신 버퍼의 공유 메모리 버퍼 레이아웃에 대한 자세한 내용은 수신 버퍼의 공유 메모리를 참조하세요.

수신 표시는 NET_BUFFER_SHARED_MEMORY 구조에 다음 정보를 포함해야 합니다.

NextSharedMemorySegment
이러한 구조체의 NULL로 종료된 연결된 목록의 다음 NET_BUFFER_SHARED_MEMORY 구조체에 대한 포인터입니다.

SharedMemoryHandle
NdisAllocateSharedMemory가 반환한 NDIS 공유 메모리 핸들입니다.

SharedMemoryOffset
공유 메모리 버퍼의 시작부터 데이터 시작까지의 오프셋(바이트)입니다.

SharedMemoryLength
공유 메모리 세그먼트의 길이(바이트)입니다.

지나치게 많은 프로토콜 드라이버가 NDIS_RECEIVE_QUEUE_PARAMETERS 구조의 Flags 멤버에서 NDIS_RECEIVE_QUEUE_PARAMETERS_LOOKAHEAD_SPLIT_REQUIRED 플래그를 설정하는 경우 각 NET_BUFFER 다음을 포함합니다.

  • 두 개의 MDL 및 해당 SharedMemoryInfo 구조체.

  • 백필 공간이 있는 사후 조회 버퍼입니다.

필요한 경우 프로토콜 드라이버는 lookahead 버퍼의 내용을 백필 영역에 복사합니다. 그러나 패킷이 완전히 lookahead 버퍼에 있더라도 백필 공간이 있어야 합니다.

오버리싱 드라이버가 NDIS_RECEIVE_QUEUE_PARAMETERS_LOOKAHEAD_SPLIT_REQUIRED 플래그를 설정하지 않으면 각 NET_BUFFER 구조에는 단일 MDL과 단일 SharedMemoryInfo 구조가 포함됩니다.

MDL의 바이트 수 및 바이트 오프셋과 NET_BUFFER_DATA 구조의 DataLengthDataOffset 멤버는 VMQ를 사용하지 않는 드라이버에 대해 설정된 것과 동일한 방식으로 설정됩니다. SharedMemoryInfo 구조의 SharedMemoryLengthSharedMemoryOffset 멤버는 초기화 중에 한 번 설정할 수 있습니다. 지나치게 많은 드라이버와 NDIS는 NET_BUFFERDataLength 멤버와 MDL 바이트 수를 사용하여 패킷 시작 및 크기를 결정할 수 있으므로 미니포트 드라이버는 수신되는 모든 패킷에 대해 SharedMemoryLengthSharedMemoryOffset 멤버를 업데이트할 필요가 없습니다.

참고 NDIS 6.30 및 Windows Server 2012 시작하여 패킷 데이터를 별도의 lookahead 버퍼로 분할하는 것은 더 이상 지원되지 않습니다. 지나치게 많은 프로토콜 드라이버는 NDIS_RECEIVE_QUEUE_PARAMETERS_LOOKAHEAD_SPLIT_REQUIRED 플래그를 설정하지 않습니다.