Путь получения VMQ
Сетевой адаптер указывает полученный пакет в очереди, только если он передает все тесты поля фильтра для фильтра, установленного в этой очереди. Дополнительные сведения о тестах фильтров см. в разделе "Операции фильтра VMQ".
Если драйвер протокола задал флаг NDIS_RECEIVE_QUEUE_PARAMETERS_PER_QUEUE_RECEIVE_INDICATION в элементе Flags структуры NDIS_RECEIVE_QUEUE_PARAMETERS, драйвер минипорта не должен смешивать структуры NET_BUFFER_LIST для других очередей получения со структурами NET_BUFFER_LIST для этой очереди в одном вызове функции NdisMIndicateReceiveNetBufferLists. Кроме того, драйвер должен задать флаг NDIS_RECEIVE_FLAGS_SINGLE_QUEUE в параметре ReceiveFlags функции NdisMIndicateReceiveNetBufferLists.
Если NDIS_RECEIVE_QUEUE_PARAMETERS_PER_QUEUE_RECEIVE_INDICATION не задано, драйверы минипорта могут связывать NET_BUFFER_LIST структуры для кадров из разных очередей виртуальных машин и указывать их в одном вызове NdisMIndicateReceiveNetBufferLists. В этом случае указанный связанный список структур NET_BUFFER_LIST не требуется отсортировать по номеру очереди. NET_BUFFER_LIST структуры для разных очередей не требуют группировки.
Если драйвер протокола задает NDIS_RETURN_FLAGS_SINGLE_QUEUE и возвращает буферы получения, все структуры NET_BUFFER_LIST в параметре NetBufferLists функции NdisReturnNetBufferLists должны принадлежать одной очереди виртуальных машин. Однако драйверы протокола не требуются для возврата всех NET_BUFFER_LIST структур, указанных в одном вызове функции ProtocolReceiveNetBufferLists в одном вызове NdisReturnNetBufferLists. Кроме того, возвращенный список может включать NET_BUFFER_LIST структуры из нескольких признаков получения, если они принадлежат к одной очереди виртуальных машин.
Драйверы протокола задают NDIS_RETURN_FLAGS_SINGLE_QUEUE бит в параметре ReturnFlags NdisReturnNetBufferLists, чтобы указать, что все возвращаемые NET_BUFFER_LIST структуры принадлежат одной очереди виртуальных машин.
Признаки получения VMQ должны содержать следующие данные вне полосы (OOB) в элементе NetBufferListInfo структуры NET_BUFFER_LIST.
Укажите идентификатор очереди в сведениях NetBufferListFilteringInfo .
Задайте идентификатор фильтра в сведениях NetBufferListFilteringInfo равным нулю.
Сведения NetBufferListFilteringInfo указываются в структуре NDIS_NET_BUFFER_LIST_FILTERING_INFO. Чтобы получить доступ к структуре NDIS_NET_BUFFER_LIST_FILTERING_INFO в данных OOB NET_BUFFER_LIST, драйвер NDIS вызывает макрос NET_BUFFER_LIST_INFO и указывает тип сведений NetBufferListFilteringInfo.
Чтобы получить доступ к идентификатору фильтра и идентификатору очереди напрямую, используйте макросы NET_BUFFER_LIST_RECEIVE_FILTER_ID и NET_BUFFER_LIST_RECEIVE_QUEUE_ID.
Признаки получения VMQ должны определять сведения о общей памяти в элементе SharedMemoryInfo структуры NET_BUFFER.
Примечание. Если виртуальная машина удаляется (например, во время динамической миграции виртуальной машины), драйвер минипорта может получить NBL, содержащий недопустимое значение QueueId . В этом случае мини-порт должен игнорировать недопустимый идентификатор очереди и вместо этого использовать 0 (очередь по умолчанию). QueueId находится в части netBufferListFilteringInfo данных OOB NBL и извлекается с помощью макроса NET_BUFFER_LIST_RECEIVE_QUEUE_ID.
Чтобы указать, что указатель NET_BUFFER_SHARED_MEMORY в SharedMemoryInfo действителен, драйвер минипорта должен задать флаг NDIS_RECEIVE_FLAGS_SHARED_MEMORY_INFO_VALID в параметре ReceiveFlags функции NdisMIndicateReceiveNetBufferLists. Дополнительные сведения о макете буферов общей памяти в буферах получения VMQ см. в разделе "Общая память" в буферах получения.
Указание получения должно содержать следующие сведения в структуру NET_BUFFER_SHARED_MEMORY .
NextSharedMemorySegment
Указатель на следующую NET_BUFFER_SHARED_MEMORY структуру в связанном списке таких структур, завершаемых значением NULL.
SharedMemoryHandle
Дескриптор NDIS общей памяти, возвращенный NdisAllocateSharedMemory.
SharedMemoryOffset
Смещение в байтах до начала данных с начала буфера общей памяти.
SharedMemoryLength
Длина в байтах сегмента общей памяти.
Если драйвер протокола с превышением задает флаг NDIS_RECEIVE_QUEUE_PARAMETERS_LOOKAHEAD_SPLIT_REQUIRED в элементе Flags структуры NDIS_RECEIVE_QUEUE_PARAMETERS, каждая NET_BUFFER включает:
Два многомерных выражения и соответствующие структуры SharedMemoryInfo .
Буфер post-lookahead с пространством обратной заполнения.
При необходимости драйвер протокола копирует содержимое буфера lookahead в область обратной заполнения. Однако место обратной заполнения должно существовать, даже если пакет полностью находится в буфере lookahead.
Если драйвер с превышением не задает флаг NDIS_RECEIVE_QUEUE_PARAMETERS_LOOKAHEAD_SPLIT_REQUIRED, каждая NET_BUFFER структура включает один MDL и одну структуру SharedMemoryInfo.
Число байтов и смещение байтов в MDL и элементах DataLength и DataOffset в структуре NET_BUFFER_DATA задаются так же, как и для драйверов, которые не используют VMQ. Члены SharedMemoryLength и SharedMemoryOffset в структуре SharedMemoryInfo можно задать один раз во время инициализации. Мини-драйвер не требуется для обновления элементов SharedMemoryLength и SharedMemoryOffset для каждого полученного пакета, так как драйверы и NDIS могут использовать элемент NET_BUFFER DataLength и число байтов MDL для определения начала и размера пакета.
Примечание. Начиная с NDIS 6.30 и Windows Server 2012, разделение данных пакетов на отдельные буферы lookahead больше не поддерживается. Драйвер протокола с превышением не будет устанавливать флаг NDIS_RECEIVE_QUEUE_PARAMETERS_LOOKAHEAD_SPLIT_REQUIRED .