次の方法で共有


UDP セグメント化オフロード (USO)

Windows 10 バージョン 2004 以降でサポートされている UDP セグメント化オフロード (USO) は、ネットワーク インターフェイス カード (NIC) がネットワーク メディアの最大伝送単位 (MTU) より大きい UDP データグラムのセグメント化をオフロードできるようにする機能です。 これにより、Windows はパケットごとの TCP/IP 処理に関連する CPU 使用率を減らします。 USO の要件は、TCP トランスポート プロトコル 大きな送信オフロード バージョン 2 (LSOv2)に似ています。

USO の要件

このセクションでは、主に NDIS プロトコルとミニポート ドライバーを参照します。 NDIS 軽量フィルター ドライバー (LWF) は、パケットを変更または送信するときにプロトコル ドライバーの要件に従う必要があります。また、FilterSendNetBufferLists ハンドラーに提供されるすべてのパケットがプロトコル ドライバーの要件を満たしていると想定することもできます。

ミニポート ドライバーは、ネットワーク メディアの MTU より大きい大きい UDP パケットのセグメント化をオフロードできます。 大きな UDP パケットのセグメント化をサポートする NIC でも、次の操作を実行できる必要があります。

  • IPv4 オプションを含む送信済みパケットの IP チェックサムを計算する
  • 送信されたパケットの UDP チェックサムを計算する

USO をサポートするミニポート ドライバーは、NET_BUFFER_LIST 構造体の帯域外 (OOB) 情報からオフロードの種類を決定する必要があります。 NDIS_UDP_SEGMENTATION_OFFLOAD_NET_BUFFER_LIST_INFO 構造体の値が 0 以外の場合、ミニポート ドライバーは USO を実行する必要があります。 USO OOB データを含む NET_BUFFER_LIST には、1 つの NET_BUFFER 構造体も含まれます。 ただし、ミニポート ドライバーが USO をオフにするために OID_TCP_OFFLOAD_PARAMETERS を受け取った場合、ミニポート ドライバーが OID を正常に完了した後は、USO OOB フィールドが設定されている NET_BUFFER_LIST を必ず拒否して返さなければなりません。

TCP/IP トランスポートは、次の条件を満たす UDP パケットのみをオフロードします。

  • パケットは UDP パケットです。
  • パケットの長さは、(MSS) * (MinSegmentCount - 1)最大セグメント サイズを超える必要があります。
  • ミニポート ドライバーが SubMssFinalSegmentSupported 機能を設定していない場合は、トランスポートによってオフロードされた各大きな UDP パケットに Length % MSS == 0が必要です。 つまり、大きなパケットは N 個のパケットに分割可能であり、各パケット セグメントには正確に MSS ユーザー バイトが含まれます。 ミニポート ドライバーが SubMssFinalSegmentSupported 機能を設定する場合、トランスポートのこのパケット長の割り切り条件は適用されません。 つまり、最終的なセグメントは MSS未満にすることができます。
  • パケットはループバック パケットではありません。
  • オフロードされた TCP/IP トランスポートによる大きな UDP パケットの IP ヘッダーでは、MF ビットが設定されず、フラグメント オフセット は 0 になります。
  • アプリケーションは UDP_SEND_MSG_SIZE/WSASetUdpSendMessageSizeを指定しました。

セグメント化のために大きな UDP パケットをオフロードする前に、TCP/IP トランスポートは次の処理を行います。

  • NET_BUFFER_LIST 構造に関連付けられている大きなパケット セグメント化情報を更新します。 この情報は、NET_BUFFER_LIST 構造体の OOB 情報の一部である NDIS_UDP_SEGMENTATION_OFFLOAD_NET_BUFFER_LIST_INFO 構造体です。 TCP/IP トランスポートは、MSS 値を目的の MSS に設定します。
  • UDP 擬似ヘッダーの 1 の補数合計 を計算し、この合計を UDP ヘッダーの Checksum フィールドに書き込みます。 TCP/IP トランスポートは、擬似ヘッダーの次のフィールドに対する補数の合計を計算します。送信元 IP アドレス、宛先 IP アドレス、プロトコル。

TCP/IP トランスポートによって提供される擬似ヘッダーの補数の合計により、NIC は、IP ヘッダーを調べることなく、NIC が大きな UDP パケットから派生する各パケットの実際の UDP チェックサムの計算を早期に開始できます。

RFC 768 および RFC 2460 は、擬似ヘッダーが送信元 IP アドレス、宛先 IP アドレス、プロトコル、および UDPの長さ (UDPヘッダーの長さとUDPペイロードの長さを加えたもので、擬似ヘッダーの長さは含まない) に基づいて計算されることを規定しています。 ただし、基になるミニポート ドライバーと NIC は、TCP/IP トランスポートによって渡される大きなパケットから UDP データグラムを生成するため、トランスポートは各 UDP データグラムの UDP ペイロードのサイズを認識しないため、擬似ヘッダーの計算に UDP の長さを含めることはできません。 代わりに、次のセクションで説明するように、NIC は TCP/IP トランスポートによって提供された擬似ヘッダー チェックサムを拡張して、生成された各 UDP データグラムの UDP 長さをカバーします。

重要

TCP/IP トランスポートによって提供される UDP ヘッダー チェックサム フィールドが 0 の場合、NIC は UDP チェックサム計算を実行しないでください。

USO を使用したパケットの送信

ミニポート ドライバーが MiniportSendNetBufferLists コールバック関数内で NET_BUFFER_LIST を取得した後、MSS 値と IP プロトコルを取得するために、UdpSegmentationOffloadInfo_Id を伴って NET_BUFFER_LIST_INFO マクロを呼び出すことができます。

ミニポート ドライバーは、最初の NET_BUFFER 構造体の長さから大きなパケットの合計の長さを取得し、MSS 値を使用して、大きな UDP パケットをより小さな UDP パケットに分割します。 小さい各パケットには、MSS 以下のユーザー データ バイトが含まれます。 セグメント化された大きなパケットから作成された最後のパケットにのみ、MSS ユーザー データ バイト 未満を含める必要があります。 セグメント化されたパケットから作成された他のすべてのパケットには、MSS ユーザー データ バイト 含まれている必要があります。 ミニポート ドライバーがこの規則に準拠していない場合、UDP データグラムが正しく配信されません。 ミニポート ドライバーが 機能を設定していない場合、パケットの長さは MSS で除算され、セグメント化された各パケットには MSS ユーザー バイトが含まれます。

ミニポート ドライバーは、大きなパケットから派生した各セグメントに MAC、IP、および UDP ヘッダーを付加します。 ミニポート ドライバーは、これらの派生パケットの IP および UDP チェックサムを計算する必要があります。 大きな UDP パケットから派生した各パケットの UDP チェックサムを計算するために、NIC は UDP チェックサムの可変部分 (UDP ヘッダーと UDP ペイロード) を計算し、TCP/IP トランスポートによって計算された擬似ヘッダーの合計にこのチェックサムを追加し、チェックサムの 16 ビットの補数を計算します。 このようなチェックサムの計算の詳細については、RFC 768 および RFC 2460を参照してください。

大きい UDP パケット内の UDP ユーザー データの長さは、ミニポート ドライバーが MaxOffLoadSizeに割り当てる値以下である必要があります。

ドライバーが MaxOffLoadSizeへの変更を示す状態表示を発行した後、ドライバーは、前の MaxOffLoadSize 値を使用する LSO 送信要求を受信した場合、バグ チェックを発生させてはなりません。 代わりに、ドライバーは送信要求に失敗する必要があります。 ドライバー は、何らかの理由(サイズ、最小セグメント数、IPオプションなど)により実行できない送信要求 は必ず失敗させる必要があります。 ドライバーは、機能が変更された場合、できるだけ早く状態表示を送信する必要があります。

MaxOffLoadSize 値の変更を報告する状態表示を個別に発行する中間ドライバーは、ステータス表示を発行していない基になるミニポート アダプターが、ミニポート アダプターが報告した MaxOffLoadSize 値よりも大きいパケットを取得しないようにする必要があります。

USO サービスをオフにする OID_TCP_OFFLOAD_PARAMETERS に応答するミニポート中間ドライバーは、USO 要求がミニポート ドライバーに到達できる小さな期間に備える必要があります。

大きな UDP パケットから派生したセグメント化パケットの数は、ミニポート ドライバーによって指定された MinSegmentCount 値以上である必要があります。

大きな UDP パケットを処理する場合、ミニポート ドライバーは、パケットをセグメント化し、大きな UDP パケットから派生したパケットに MAC、IP、および UDP ヘッダーを貼り付ける必要があります。 ミニポートが少なくとも 1 つのセグメント化されたパケットの送信に失敗した場合、NBL は最終的にエラー状態で完了する必要があります。 ミニポートは後続のパケットの送信を続行できますが、送信する必要はありません。 セグメント化されたすべてのパケットが送信または失敗するまで、NBL を NDIS に戻すことはできません。

USO 対応ミニポート ドライバーでは、次の操作も行う必要があります。

  • IPv4 と IPv6 の両方をサポートします。
  • NIC によって生成されるセグメント化された各パケットの大きなパケットからの IPv4 オプションのレプリケーションをサポートします。
  • NET_BUFFER_LIST 構造の IP ヘッダーと UDP ヘッダーをテンプレートとして使用して、セグメント化された各パケットの UDP ヘッダーと IP ヘッダーを生成します。
  • 0x0000 から 0xFFFFまでの範囲で IP 識別 (IP ID) 値を使用します。 たとえば、テンプレート IP ヘッダーが 0xFFFEの Identification フィールド値で始まる場合、最初の UDP データグラム パケットの値は 0xFFFE、その後に 0xFFFF0x00000x0001などである必要があります。
  • 大きな UDP パケットに IP オプションが含まれている場合、ミニポート ドライバーは、大きな UDP パケットから派生した各パケットに、変更されていないこれらのオプションをコピーします。
  • NDIS_UDP_SEGMENTATION_OFFLOAD_NET_BUFFER_LIST_INFOUdpHeaderOffset メンバーのバイトオフセットを使って、パケットの先頭からUDPヘッダーがどこにあるかを特定します。
  • セグメント化されたパケットに基づいて送信統計情報をインクリメントします。 たとえば、各パケットセグメントごとのイーサネット、IP、UDPヘッダーのバイト数を含め、パケットの数はMSSサイズのセグメント 数であり、1ではありません。
  • セグメント化された各データグラム・サイズに基づいて、UDP の合計長フィールドと IP 長フィールドを設定します。

NDIS インターフェイスの変更

このセクションでは、ミニポート ドライバーによって公開される USO 機能を利用するホスト TCP/IP ドライバー スタックを有効にする NDIS 6.83 の変更について説明します。

NDIS とミニポート ドライバーは、次を実行します。

  • NIC が USO 機能をサポートしていることをアドバタイズする
  • USO を有効または無効にする
  • 現在の USO 機能の状態を取得する

USO 機能のアドバタイズ

ミニポート ドライバーは、NdisMSetMiniportAttributes のパラメータで渡される NDIS_OFFLOADUdpSegmentation フィールドを入力することで、USO 機能をアドバタイズします。 NDIS_OFFLOAD 構造の Header.Revision フィールドを 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 が有効か無効かを示します。 USO 設定は、NDIS_TCP_IP_CHECKSUM_OFFLOAD 構成に依存しません。 たとえば、*UDPChecksumOffloadIPv4 を無効にしても、*UsoIPv4は暗黙的に無効になりません。

サブキー名 パラメーターの説明 価値 列挙型の説明
*UsoIPv4 USO (IPv4) 0 いいえ
1 有効
*UsoIPv6 USO (IPV6) 0 いいえ
1 有効