共用方式為


UDP 接收區段合併卸載 (URO)

從 Windows 11 版本 24H2 開始,UDP 接收區段聯合卸載 (URO) 可讓網路適配器 (NIC) 聯合 UDP 接收區段。 NIC 可以將符合一組規則的相同資料流中的 UDP 封包合併成邏輯上連續的緩衝區。 然後,這些合併的數據報會以單一大型封包的形式向 Windows 網路堆疊表示。

合併 UDP 數據報可降低在高頻寬流量中處理封包的 CPU 成本,進而提高吞吐量並降低每個位元組的處理循環次數。

下列各節說明聯合 UDP 封包的規則,以及如何撰寫 URO 迷你埠驅動程式。

UDP封包合併的規則

URO 結合只能在符合下列所有準則的封包上才能夠嘗試:

  • 所有封包的 IpHeader.Version 都相同。
  • 所有封包的 IpHeader.SourceAddressIpHeader.DestinationAddress 都相同。
  • 所有封包的 UdpHeader.SourcePortUdpHeader.DestinationPort 都相同。
  • 所有封包的 UdpHeader.Length 都相同,除了最後一個封包,其可能較小。
  • UdpHeader.Length 必須是非零。
  • UdpHeader.Checksum,如果不是零,則必須在所有封包上都正確。 這表示接收總和檢查碼卸除必須驗證封包。
  • 所有封包的 Layer 2 headers 必須相同。

如果封包是 IPv4,它們也必須符合下列準則:

  • 所有數據包的 IPv4Header.Protocol == 17(UDP)。
  • EthernetHeader.EtherType == 0x0800,用於所有封包。
  • 已接收封包上的 IPv4Header.HeaderChecksum 必須正確。 這表示接收校驗和卸載必須驗證標題。
  • 所有封包的 IPv4Header.HeaderLength == 5(無 IPv4 選項標頭)。
  • 所有封包的 IPv4Header.ToS 都相同。
  • 所有封包的 IPv4Header.ECN 都相同。
  • 所有封包的 IPv4Header.DontFragment 都相同。
  • 所有封包的 IPv4Header.TTL 都相同。
  • IPv4Header.TotalLength == UdpHeader.Length* + 所有封包的長度 (IPv4Header)。

如果封包是 IPv6,它們也必須符合下列準則:

  • 所有封包的 IPv6Header.NextHeader == 17(UDP)(沒有擴展標頭)。
  • EthernetHeader.EtherType == 0x86dd (IPv6)適用於所有封包。
  • 所有封包的 IPv6Header.TrafficClassIPv6Header.ECN 都相同。
  • 所有封包的 IPv6Header.FlowLabel 都相同。
  • 所有封包的 IPv6Header.HopLimit 值都相同。
  • 所有封包的 IPv6Header.PayloadLength == UdpHeader.Length

URO 封包結構

產生的單一聯合單位(SCU)必須具有單一的IP標頭和UDP標頭,然後接著是所有聯合數據報的UDP承載的內容被串連在一起。

URO 指示必須將 IPv4Header.TotalLength 欄位設定為 SCU 的總長度,或將欄位 IPv6Header.PayloadLength 為 UDP 承載的長度,並將 UdpHeader.Length 欄位設定為聯合承載的長度。

如果第 2 層 (L2) 標頭存在於聯合式數據報中,SCU 必須包含有效的 L2 標頭。 SCU 中的 L2 標頭必須與聯合數據報的 L2 標頭類似。

總和檢查碼驗證和指示

URO 指示必須將 IPv4Header.HeaderChecksumUdpHeader.Checksum 欄位設定為零,並在 SCU 上填寫校驗和卸載的帶外資訊,表示 IPv4 和 UDP 校驗和驗證成功。

符合合併之所有條件但總和檢查碼驗證失敗的封包必須個別指出。 接收後的封包不得與接收前的封包合併。

例如,假設封包 1、2、3、4 和 5 是從相同的流程接收,但封包 3 會失敗總和檢查碼驗證。 封包 1 和 2 可以合併在一起,封包 4 和 5 可以聯合在一起,但封包 3 不得與任一 SCU 聯合。 封包 1 和 2 不得與封包 4 和 5 合併。 封包 2 是 SCU 中的最後一個封包,封包 4 會啟動新的 SCU。 此外,必須先指出包含封包 1 和 2 的 SCU,然後才能指出封包 3,而且必須先指出封包 3,然後才能指出包含封包 4 和 5 的 SCU。

封包合併和流量分離

多個資料流的封包可以同時合併,視硬體和記憶體許可而定。 來自不同流程的封包不得合併在一起。

來自多個接收的交錯封包可與其各自的數據流分離並合併。 例如,假設有流 A、B 和 C,封包按 A、A、B、C、B、A 的順序到達,那麼來自 A 流的封包可以合併成 AAA,來自 B 流的封包可以合併成 BB,而來自 C 流的封包可以正常顯示,或者與 C 流中的待處理 SCU 合併。

指定流程內的封包不得彼此重新排序。 例如,A 流的封包必須按照接收的順序合併,無論期間接收到的 B 和 C 流的封包為何。

用於控制URO的INF關鍵詞

下列關鍵詞可用於通過註冊表項設定來啟用或停用 URO:

  • *UdpRsc

列舉標準化 INF 關鍵詞具有下列屬性:

  • SubkeyName:您必須在 INF 檔案中指定且出現在登錄中的關鍵詞名稱。

  • ParamDesc:與 SubkeyName 相關聯的顯示文字。

  • Value:與清單中每個選項相關聯的列舉整數值。 此值會儲存在 NDI\params\SubkeyName\Value中。

  • EnumDesc:與功能表中每個值相關聯的顯示文字。

  • 預設:選單的預設值。

SubkeyName ParamDesc 價值 EnumDesc
*UdpRsc URO 0 禁用
1 (預設值) 啟用

如需使用列舉關鍵詞的詳細資訊,請參閱 列舉關鍵詞

撰寫 URO 迷你埠驅動程式

從 NDIS 6.89 開始,URO 的 NDIS 介面有助於 TCP/IP 與 NDIS 迷你埠驅動程式之間的通訊。

報告 URO 功能

迷你埠驅動程式會在 NDIS_OFFLOAD 結構 UdpRsc 成員中公告 URO 的支援,其會傳遞給 NdisMSetMiniportAttributes 函式。

查詢URO功能

若要檢查迷你埠驅動程式是否支援 URO,NDIS 驅動程式和其他應用程式可以查詢 OID_TCP_OFFLOAD_HARDWARE_CAPABILITIES OID,該 OID 會傳回 NDIS_OFFLOAD 結構。

查詢URO狀態

若要判斷目前的 URO 狀態,NDIS 驅動程式和其他應用程式可以查詢 OID_TCP_OFFLOAD_CURRENT_CONFIG OID 要求。 NDIS 會處理此 OID,且不會將其傳遞至迷你埠。

變更URO狀態

您可以發出 OID_TCP_OFFLOAD_PARAMETERS OID 要求來啟用或停用 URO。 此 OID 使用 NDIS_OFFLOAD_PARAMETERS 結構。 在此結構中,UdpRsc.Enabled 成員可以有下列值:

價值 意義
NDIS卸載參數_UDP_RSC_未變更
0
迷你埠驅動程序不應該變更目前的設定。
NDIS_OFFLOAD_PARAMETERS_UDP_RSC_DISABLED
1
URO 已停用。
NDIS_OFFLOAD_PARAMETERS_UDP_RSC_ENABLED
2
已啟用URO。

當驅動程式處理已設定 NDIS_OFFLOAD_PARAMETERS_UDP_RSC_DISABLED 旗標的 OID_TCP_OFFLOAD_PARAMETERS OID 要求時,NIC 必須等候完成要求,直到指出所有現有的聯合區段和未完成的 URO 指示為止。 這可確保跨 NDIS 元件同步處理 URO 啟用/停用事件。

迷你埠驅動程序處理 OID_TCP_OFFLOAD_PARAMETERS OID 要求之後,迷你埠驅動程式必須發出 NDIS_STATUS_TASK_OFFLOAD_CURRENT_CONFIG 狀態指示,並顯示更新的卸除狀態。

NDIS_OFFLOAD_PARAMETERS 中的 NDIS_OFFLOAD_PARAMETERS_SKIP_REGISTRY_UPDATE 旗標允許僅在運行時間禁用 URO。 使用此旗標所做的變更不會儲存至登錄。

在 NDIS 6.89 及之後版本中取消 URO

以 NDIS 6.89 和更新版本為目標的驅動程式應該瞭解 URO 封包並正常處理它們。 若要退出 URO:

此方法可確保不熟悉URO的元件不會收到URO NBL。 如果存在不支援 URO 的 LWF 或通訊協定驅動程式,NDIS 在綁定過程中會停用小型埠上的 URO。

URO 驅動程式的程式設計考慮

實作支援URO的迷你埠驅動程式時,請考慮下列問題。

Winsock URO API

如需有關 Winsock URO API 的資訊,請參閱 IPPROTO_UDP 套接字選項。 請參閱 UDP_RECV_MAX_COALESCED_SIZEUDP_COALESCED_INFO的相關信息。

Windows TCP/IP 堆棧更新

Microsoft TCP/IP 傳輸協定會在與 NDIS 綁定時啟用 URO,除非配置阻止它這樣做。

糧食計劃署的圖說文字可以在 FWPS_CALLOUT2 中使用 FWP_CALLOUT_FLAG_ALLOW_URO 來宣傳他們對 URO 的支援。 如果在 URO 敏感層上註冊不相容的 WFP 呼出,則 OS 會在該呼出註冊期間停用 URO。

如果套接字選擇加入URO,且合併最大大小大於或等於硬體卸載大小,那麼堆疊會將來自硬體的NBLs原封不動地傳遞到套接字。 如果套接字選擇較小的合併最大大小,堆疊會將合併的接收數據分成適合該套接字的較小大小。

如果套接字未選擇加入URO(接收重組選項),則協議棧會重新分段該套接字的接收。 如果沒有硬體 URO,現有的軟體 URO 功能仍可繼續使用。