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


Разгрузка сегментации больших TCP-пакетов

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

  • Вычислите ip-проверка sumsums for send packets, которые содержат параметры IP-адресов.

  • Вычислите проверка сумы TCP для пакетов отправки, содержащих параметры TCP.

NDIS версии 6.0 и более поздних версий поддерживают большую разгрузку отправки версии 1 (LSOv1), которая похожа на большую разгрузку отправки (LSO) в NDIS 5.x. NDIS версии 6.0 и более поздних версий также поддерживают большую разгрузку отправки версии 2 (LSOv2), которая предоставляет расширенные службы сегментации больших пакетов, включая поддержку IPv6.

Минипорт-драйвер, поддерживающий LSOv2 и LSOv1, должен определить тип разгрузки из сведений о NET_BUFFER_LIST структуре OOB. Драйвер может использовать элемент Type структуры NDIS_TCP_LARGE_SEND_OFFLOAD_NET_BUFFER_LIST_INFO для определения того, используется ли стек драйверов LSOv2 или LSOv1 и выполняет соответствующие службы разгрузки. Любая NET_BUFFER_LIST структура, содержащая данные OOB LSOv1 или LSOv2, также содержит одну NET_BUFFER структуру. Дополнительные сведения о NDIS_TCP_LARGE_SEND_OFFLOAD_NET_BUFFER_LIST_INFO см. в разделе "Доступ к разгрузке TCP/IP", NET_BUFFER_LIST сведения.

Однако в случае, когда минипорт получил OID_TCP_OFFLOAD_PARAMETERS отключить функцию LSO в минипорте и после успешного завершения минипорта OID минипорт должен удалить все NET_BUFFER_LIST которые содержат любые ненулевых данных LSOv1 или LSOv2 OOB(NDIS_TCP_LARGE_SEND_OFFLOAD_NET_BUFFER_LIST_INFO).

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

  • Пакет представляет собой TCP-пакет. Транспорт TCP/IP не выгружает большие пакеты UDP для сегментации.

  • Пакет должен быть разделен по крайней мере минимальным количеством сегментов, указанных драйвером мини-порта. Дополнительные сведения см. в статье "Отчеты о возможностях сегментации tcp-пакетов" сетевого адаптера lSOv1 и отчеты о возможностях сегментации TCP-пакетов сетевого адаптера lSOv2.

  • Пакет не является пакетом обратного цикла.

  • Пакет не будет отправлен через туннель.

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

  • Обновления сведения о сегментации больших пакетов, связанные с NET_BUFFER_LIST структура. Эта информация представляет собой NDIS_TCP_LARGE_SEND_OFFLOAD_NET_BUFFER_LIST_INFO структуру, которая является частью NET_BUFFER_LIST информации, связанной с структурой NET_BUFFER_LIST. Дополнительные сведения о NET_BUFFER_LIST см. в разделе "Доступ к разгрузке TCP/IP" NET_BUFFER_LIST. Транспорт TCP/IP задает значение MSS максимальным размером сегмента (MSS).

  • Для LSOv1 записывает общую длину большого TCP-пакета в поле "Общая длина" заголовка IP-адреса пакета. Общая длина включает длину заголовка IP, длину параметров IP, если они присутствуют, длину заголовка TCP, длину параметров TCP, если они присутствуют, и длину полезных данных TCP. Для LSOv2 задает поле "Общая длина" заголовка IP-адреса пакета значение 0. Драйверы минипорта должны определить длину пакета из длины первой NET_BUFFER структуры в структуре NET_BUFFER_LIST.

  • Вычисляет сумму дополнения для псевдохедчика TCP и записывает эту сумму в поле "Контрольная сумма" заголовка TCP. Транспорт TCP/IP вычисляет сумму дополнения одного из следующих полей в псевдогоедчике: исходный IP-адрес, конечный IP-адрес и протокол. Сумма дополнения для псевдогоголовока, предоставленного транспортом TCP/IP, дает сетевому адаптеру раннее начало вычисления реальных tcp-проверка sum для каждого пакета, наследуемого сетевым адаптером от большого TCP-пакета без необходимости проверять заголовок IP. Обратите внимание, что RFC 793 предусматривает, что псевдозаголовок проверка sum вычисляется по исходному IP-адресу, целевому IP-адресу, протоколу и длине TCP. (Длина TCP — это длина заголовка TCP, а также длина полезных данных TCP. Длина TCP не включает длину псевдо-заголовка.) Однако, поскольку базовый минипорт-драйвер и сетевой адаптер создают сегменты TCP из большого пакета, передаваемого транспортом TCP/IP, транспорт не знает размер полезных данных TCP для каждого сегмента TCP и поэтому не может включать длину TCP в псевдозаголовок. Вместо этого, как описано ниже, сетевой адаптер расширяет псевдозаголовок проверка sum, предоставленный транспортом TCP/IP, чтобы охватывать длину TCP каждого созданного сегмента TCP.

  • Записывает правильный номер последовательности в поле "Номер последовательности" заголовка TCP. Номер последовательности определяет первый байт полезных данных TCP.

После получения функции miniport driver NET_BUFFER_LIST в функции MiniportSendNetBufferLists или MiniportCoSendNetBufferLists можно вызвать макрос NET_BUFFER_LIST_INFO с _IdTcpLargeSendNetBufferListInfo, чтобы получить значение MSS, записанное транспортом TCP/IP.

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

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

На следующем рисунке показана сегментация большого пакета.

Схема, показывающая сегментацию большого TCP-пакета на меньшие пакеты с заголовками MAC, IP и TCP.

Длина данных пользователя TCP в большом пакете TCP должна быть равна или меньше значения, которое драйвер минипорта назначает значению MaxOffLoadSize . Дополнительные сведения о значении MaxOffLoadSize см. в разделе "Отчеты о возможностяхсегментации tcp-пакетов" сетевого адаптера lSOv2 TCP-Packet-Segmentation и отчетности о возможностях сегментации TCP-пакетов NIC.

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

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

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

Длина данных пользователя TCP в пакете сегмента должна быть меньше или равна MSS. MSS — это значение ULONG, которое передает транспорт TCP с помощью LSO NET_BUFFER_LIST сведения, связанные со структурой NET_BUFFER_LIST. Обратите внимание, что только последний пакет, созданный из сегментированного большого пакета, должен содержать меньше байтов пользовательских данных MSS. Все остальные пакеты, созданные из сегментированного пакета, должны содержать байты данных пользователя MSS. Если вы не следуйте этому правилу, создание и передача ненужных дополнительных пакетов может снизить производительность.

Число пакетов сегментов, производных от большого TCP-пакета, должно быть равно или больше значения MinSegmentCount , указанного мини-драйвером. Дополнительные сведения о значении MinSegmentCount см. в разделе "Отчеты о возможностях сегментации tcp-пакетов" сетевого адаптера LSOv1 и создании отчетов о возможностях сегментации TCP-пакетов NIC.

Следующие предположения и ограничения применяются к обработке заголовков IP и TCP для любого мини-порта, поддерживающего LSO, независимо от версии:

  • Бит MF в заголовке IP-адреса большого TCP-пакета, который не был загружен транспортОМ TCP/IP, и смещение фрагмента в заголовке IP-адресов будет равно нулю.

  • Флаги URG, RST и SYN в заголовке TCP большого TCP-пакета не будут заданы, а срочное смещение (указатель) в заголовке TCP будет равно нулю.

  • Если бит FIN в заголовке TCP большого пакета установлен, драйвер минипорта должен задать этот бит в заголовке TCP последнего пакета, который он создает из большого TCP-пакета.

  • Если задан бит PSH в заголовке TCP большого TCP-пакета, мини-драйвер должен задать этот бит в заголовке TCP последнего пакета, который он создает из большого TCP-пакета.

  • Если бит CWR в заголовке TCP большого TCP-пакета установлен, драйвер минипорта должен задать этот бит в заголовке TCP первого пакета, который он создает из большого TCP-пакета. Минипорт-драйвер может задать этот бит в заголовке TCP последнего пакета, который он создает из большого TCP-пакета, хотя это менее желательно.

  • Если большой TCP-пакет содержит параметры IP или параметры TCP (или оба), драйвер минипорта копирует эти параметры, неуправляемые, в каждый пакет, производный от большого TCP-пакета. В частности, сетевой адаптер не будет увеличивать параметр метки времени.

  • Все заголовки пакетов (Ethernet, IP, TCP) будут находиться в первом MDL пакета. Заголовки не будут разделены между несколькими многомерными значениями.

    Совет

    Это предположение допустимо при включении LSO. В противном случае, если LSO не включен, минипорт-драйверы не могут предположить, что заголовки IP-адресов находятся в том же MDL, что и заголовки Ethernet.

Минипорт-драйвер должен отправлять пакеты в NET_BUFFER_LIST структурах в том порядке, в который он получает NET_BUFFER_LIST структуры от транспорта TCP/IP.

При обработке большого TCP-пакета мини-адаптер отвечает только за сегментирование пакета и аффиксирование заголовков MAC, IP и TCP на пакеты, производные от большого TCP-пакета. Транспорт TCP/IP выполняет все остальные задачи (например, изменение размера окна отправки на основе размера окна получения удаленного узла).

Перед выполнением операции отправки для большого пакета (например, с NdisMSendNetBufferListsComplete или NdisMCoSendNetBufferListsComplete), мини-порт записывает значение NDIS_TCP_LARGE_SEND_OFFLOAD_NET_BUFFER_LIST_INFO (NET_BUFFER_LIST сведения о больших разгрузках) с общим количеством байтов данных пользователя TCP, которые успешно отправляются во всех пакетах, созданных из большого пакета TCP.

Помимо предыдущих требований LSO, драйверы мини-порта, поддерживаемые LSOv2, также должны:

  • Поддержка IPv4 или IPv6 или IPv4 и IPv6.

  • Поддержка реплика параметров IPv4 из большого пакета в каждом пакете сегмента, который создает сетевой интерфейс карта (сетевой адаптер).

  • Поддержка реплика заголовка расширения IPv6 из большого tcp-пакета в каждом пакете сегмента TCP.

  • Поддержка реплика параметров TCP в каждом пакете сегмента TCP, который создает драйвер мини-порта.

  • Используйте заголовок IP и TCP в структуре NET_BUFFER_LIST в качестве шаблона для создания заголовков TCP/IP для каждого пакета сегмента.

  • Используйте значения идентификатора IP в диапазоне от 0x0000 до 0x7FFF. (Диапазон от 0x8000 до 0xFFFF зарезервирован для устройств с поддержкой разгрузки TCP.) Например, если заголовок IP-адреса шаблона начинается со значения поля идентификации 0x7FFE, первый пакет сегмента TCP должен иметь значение ip-идентификатора 0x7FFE, а затем 0x7FFF, 0x0000, 0x0001 и т. д.

  • Используйте смещение байтов в элементе TcpHeaderOffset NDIS_TCP_LARGE_SEND_OFFLOAD_NET_BUFFER_LIST_INFO, чтобы определить расположение заголовка TCP, начиная с первого байта пакета.

  • Ограничить число NET_BUFFER структур, связанных с каждой структурой LSOv2 NET_BUFFER_LIST, до одной.

    Примечание.

    Это новое требование для мини-портов LSOv2. Это правило не применяется для драйверов мини-порта LSOv1 явно, хотя рекомендуется.

  • Определите общую длину пакета из длины первой NET_BUFFER структуры в структуре NET_BUFFER_LIST. Это отличается от драйверов методов, используемых для LSOv1.

  • Поддержка параметров TCP, параметров IP и заголовков расширений IP.

  • После завершения операции отправки драйвер минипорта должен задать для элемента LsoV2TransmitComplete.Reserved для структуры NDIS_TCP_LARGE_SEND_OFFLOAD_NET_BUFFER_LIST_INFO значение нулю, а член LsoV2TransmitComplete.Type — NDIS_TCP_LARGE_SEND_OFFLOAD_V2_TYPE.