Поделиться через


Разгрузка сегментации UDP (USO)

Разгрузка сегментации UDP (USO), поддерживаемая в Windows 10 версии 2004 и более поздних версий, — это функция, которая позволяет сетевому интерфейсу карта (СЕТЕВЫе адаптеры) выгрузить сегментацию диаграмм данных UDP, размер которых превышает максимальное значение единицы передачи (MTU) сетевой среды. Благодаря этому Windows сокращает использование ЦП, связанное с обработкой TCP/IP-адресов для каждого пакета. Требования к usO аналогичны LSOv2, который предназначен для протокола tcp-транспорта.

Требования к USO

Этот раздел относится в основном к протоколам NDIS и мини-драйверам. Драйверы упрощенных фильтров NDIS (LWFs) должны соответствовать требованиям драйвера протокола при изменении или отправке пакетов, а также предположить, что все пакеты, предоставленные обработчику FilterSendNetBufferLists , соответствуют требованиям драйвера протокола.

Мини-портовые драйверы могут выгрузить сегментацию больших пакетов UDP, размер которых превышает MTU сетевого носителя. Сетевой адаптер, поддерживающий сегментацию больших пакетов UDP, также должен иметь возможность выполнять следующие действия:

  • Вычисление ip-проверка sumsums для отправленных пакетов, содержащих параметры IPv4
  • Вычисление UDP проверка sumsums for sent packets

Минипорт-драйвер, поддерживающий единый вход, должен определить тип разгрузки из сведений о NET_BUFFER_LIST структуре вне полосы (OOB). Если значение структуры NDIS_UDP_SEGMENTATION_OFFLOAD_NET_BUFFER_LIST_INFO не равно нулю, драйвер минипорта должен выполнить вход в USO. Любая NET_BUFFER_LIST, содержащая данные OOB usO, также содержит одну NET_BUFFER структуру. Однако в случае, когда драйвер минипорта получил OID_TCP_OFFLOAD_PARAMETERS отключить USO, после того, как минипорт драйвер успешно завершил OID, он должен отклонить и вернуть все NET_BUFFER_LIST с набором полей OOB USO.

Транспорт TCP/IP выгружает только те пакеты UDP, которые соответствуют следующим критериям:

  • Пакет является пакетом UDP.
  • Длина пакета должна превышать максимальный размер сегмента (MSS) * (MinSegmentCount - 1).
  • Если минипорт-драйвер не задает возможность SubMssFinalSegmentSupported , то каждый большой пакет UDP, загруженный транспортом, должен иметь длину % MSS == 0. То есть большой пакет делится на N-пакеты с каждым сегментом пакетов, содержащим ровно байты пользователей MSS . Если драйвер минипорта задает возможность SubMssFinalSegmentSupported , то это условие разбиения длины пакета на транспорте не применяется. Другими словами, конечный сегмент может быть меньше MSS.
  • Пакет не является пакетом обратного цикла.
  • Бит MF в заголовке IP-адреса большого пакета UDP, который не будет загружен транспортОМ TCP/IP, и смещение фрагмента в заголовке IP-адресов будет равно нулю.
  • Приложение указало UDP_SEND_MSG_SIZE/WSASetUdpSendMessageSize.

Перед разгрузкой большого пакета UDP для сегментации транспорт TCP/IP выполняет следующие действия:

  • Обновления сведения о сегментации больших пакетов, связанные с NET_BUFFER_LIST структура. Эта информация представляет собой NDIS_UDP_SEGMENTATION_OFFLOAD_NET_BUFFER_LIST_INFO структуру, которая является частью сведений о OOB NET_BUFFER_LIST структуры. Транспорт TCP/IP задает значение MSS требуемым MSS.
  • Вычисляет сумму дополнения для псевдохедчика UDP и записывает эту сумму в поле "Контрольная сумма " заголовка UDP. Транспорт TCP/IP вычисляет сумму дополнения одного из следующих полей в псевдогоедчике: исходный IP-адрес, конечный IP-адрес и протокол.

Сумма дополнения для псевдогоголовока, предоставленного транспортом TCP/IP, дает сетевому адаптеру раннее начало вычисления реальной суммы UDP проверка sum для каждого пакета, наследуемого сетевым адаптером от большого пакета UDP, без необходимости проверять заголовок IP.

Обратите внимание, что RFC 768 и RFC 2460 указывают, что псевдогоголовок вычисляется по исходному IP-адресу, IP-адресу назначения, протоколу и длине UDP (длина заголовка UDP плюс длина полезных данных UDP, не включая длину псевдогоголовока). Тем не менее, поскольку базовый мини-драйвер и сетевой адаптер создают UDP-диаграммы данных из большого пакета, передаваемого транспортом TCP/IP, транспорт не знает размер полезных данных UDP для каждой диаграммы данных UDP, поэтому не может включать длину UDP в вычислении псевдогодера. Вместо этого, как описано в следующем разделе, сетевой адаптер расширяет псевдозаголовок проверка sum, предоставленный транспортом TCP/IP, чтобы охватывать длину UDP каждой созданной диаграммы данных UDP.

Внимание

Если поле заголовка UDP проверка sum, предоставленное транспортом TCP/IP, равно нулю, сетевой адаптер не должен выполнять вычисление проверка sum UDP.

Отправка пакетов с помощью USO

После получения NET_BUFFER_LIST в функции обратного вызова MiniportSendNetBufferLists драйвер минипорта может вызвать макрос NET_BUFFER_LIST_INFO с _IdUdpSegmentationOffloadInfo, чтобы получить значение и IP-протокол MSS.

Минипорт-драйвер получает общую длину большого пакета из длины первой NET_BUFFER структуры и использует значение MSS для разделения большого пакета UDP на меньшие пакеты UDP. Каждый из небольших пакетов содержит MSS или меньше байт данных пользователя. Обратите внимание, что только последний пакет, созданный из сегментированного большого пакета, должен содержать меньше байтов пользовательских данных MSS . Все остальные пакеты, созданные из сегментированного пакета, должны содержать байты пользовательских данных MSS . Если мини-драйвер не соответствует этому правилу, UDP-диаграммы данных будут неправильно доставлены. Если драйвер минипорта не задает функцию SubMssFinalSegmentSupported, длина пакета делится на MSS, а каждая из сегментированных пакетов содержит байты пользователей MSS.

Минипорт-драйвер прикрепляет заголовки MAC, IP-адреса и UDP к каждому сегменту, производным от большого пакета. Минипорт-драйвер должен вычислить IP-адрес и UDP проверка sumsums for этих производных пакетов. Чтобы вычислить UDP проверка sum для каждого пакета, полученного из большого пакета UDP, Сетевой адаптер вычисляет переменную часть UDP проверка sum (для заголовка UDP и полезных данных UDP), добавляет эту проверка sum к сумме дополнения для псевдохедера, вычисляемого транспортом TCP/IP, а затем вычисляет 16-разрядное дополнение для проверка sum. Дополнительные сведения о вычислении таких проверка sumsums см. в rfC 768 и RFC 2460.

Длина пользовательских данных UDP в большом пакете UDP должна быть меньше или равна значению, которое драйвер минипорта назначает значению MaxOffLoadSize .

После того как драйвер выдает указание состояния на изменение значения MaxOffLoadSize, драйвер не должен вызывать ошибку проверка, если он получает запрос на отправку LSO, использующий предыдущее значение MaxOffLoadSize. Вместо этого драйвер должен завершить запрос на отправку. Драйверы должны завершить запрос на отправку, по какой-либо причине (включая размер, минимальное число сегментов, параметры IP и т. д.). Драйверы должны отправлять указание состояния как можно скорее, если их возможности изменяются.

Промежуточный драйвер, который независимо выдает сведения о состоянии, сообщающий об изменении значения MaxOffLoadSize , должен убедиться, что базовый минипорт-адаптер, не выдаваемый индикатор состояния, не получает пакеты, превышающие значение MaxOffLoadSize , которое сообщает адаптер минипорта.

Минипорт-промежуточный драйвер, реагирующий на OID_TCP_OFFLOAD_PARAMETERS для отключения служб USO, должен быть подготовлен к небольшому окну времени, когда запросы USO по-прежнему могут достичь минипорта драйвера.

Число пакетов сегментации, производных от большого пакета UDP, должно быть равно или больше значения MinSegmentCount , заданного мини-драйвером.

При обработке большого пакета UDP драйвер минипорта отвечает только за сегментирование пакета и аффиксирование заголовков MAC, IP и UDP к пакетам, производным от большого пакета UDP. Если минипорт не может отправить по крайней мере один сегментированный пакет, NBL в конечном итоге должен быть завершен с состоянием сбоя. Минипорт может продолжать отправлять последующие пакеты, но не требуется для этого. NBL не может быть завершен обратно в NDIS до тех пор, пока все сегментированные пакеты не передаются или завершаются ошибкой.

Мини-порты с поддержкой USO также должны выполнять следующие действия:

  • Поддержка IPv4 и IPv6.
  • Поддержка реплика параметров IPv4 из большого пакета в каждом сегментованном пакете, который создает сетевой адаптер.
  • Используйте заголовок IP и UDP в структуре NET_BUFFER_LIST в качестве шаблона для создания заголовков UDP и IP-адресов для каждого сегментированного пакета.
  • Используйте значения идентификатора IP в диапазоне от 0x0000 до 0xFFFF. Например, если заголовок IP-адреса шаблона начинается со значения поля идентификации 0xFFFE, первый пакет диаграммы UDP должен иметь значение 0xFFFE, за которым следует 0xFFFF, 0x0000, 0x0001 и т. д.
  • Если большой пакет UDP содержит параметры IP- адреса, драйвер минипорта копирует эти параметры, неуправляемые, в каждый пакет, производный от большого пакета UDP.
  • Используйте смещение байтов в элементе NDIS_UDP_SEGMENTATION_OFFLOAD_NET_BUFFER_LIST_INFO UdpHeaderOffset, чтобы определить расположение заголовка UDP, начиная с первого байта пакета.
  • Добавочная передача статистики на основе сегментированных пакетов. Например, включите число байтов заголовков Ethernet, IP и UDP для каждого сегмента пакета, а число пакетов — это число сегментов размера MSS, а не 1.
  • Задайте для полей UDP общую длину и длину IP-адресов на основе каждого сегментированного размера диаграммы данных.

Изменения интерфейса NDIS

В этом разделе описываются изменения в NDIS 6.83, которые позволяют стеку драйверов TCP/IP узла использовать возможности USO, предоставляемые драйверами мини-порта.

NDIS и драйвер минипорта выполняют следующие действия:

  • Объявление о том, что сетевой адаптер поддерживает возможности USO
  • Включение или отключение входа в USO
  • Получение текущего состояния функциональных возможностей USO

Реклама возможностей USO

Минипорт драйверы объявляют возможности USO путем заполнения поля UdpSegmentation структуры NDIS_OFFLOAD, которая передается в параметрах NdisMSetMiniportAttributes. Поле Header.Revision в структуре NDIS_OFFLOAD должно иметь значение NDIS_OFFLOAD_REVISION_6, а для поля Header.Size должно быть задано значение NDIS_SIZEOF_NDIS_OFFLOAD_REVISION_6.

Запрос состояния USO

Текущее состояние USO можно запросить с помощью OID_TCP_OFFLOAD_CURRENT_CONFIG. NDIS обрабатывает этот OID и не передает его на минипорт-драйвер.

Изменение состояния USO

Вход в USO можно включить или отключить с помощью OID_TCP_OFFLOAD_PARAMETERS. После обработки OID драйвер минипорта должен отправить указание состояния NDIS_STATUS_TASK_OFFLOAD_CURRENT_CONFIG с обновленным состоянием разгрузки.

Ключевое слово USO

Перечисление usO ключевое слово выглядит следующим образом:

  • *UsoIPv4
  • *UsoIPv6

Эти значения описывают, включен или отключен вход для этого конкретного IP-протокола. Параметры USO не зависят от конфигурации NDIS_TCP_IP_CHECKSUM_OFFLOAD. Например, отключение *UDPChecksumOffloadIPv4 неявно отключает *UsoIPv4.

Имя подраздела Описание параметра Значение Описание перечисления
*UsoIPv4 Разгрузка сегментации UDP (IPv4) 0 Выключено
1 Включен
*UsoIPv6 Разгрузка сегментации UDP (IPV6) 0 Выключено
1 Включен