在 NetAdapterCx 中,封包描述項 是描述網路封包的小型、精簡、運行時間可延伸結構。 每個封包都需要下列各項:
- 一個核心描述元
- 一或多個片段描述元
- 零個或多個封包延伸模組
封包 核心描述元 是 NET_PACKET 結構。 它只包含適用於所有封包的最基本元數據,例如指定封包的框架配置,以及封包第一個片段描述元的索引。
每個封包也必須有一或多個 片段描述元,或 NET_FRAGMENT 結構,描述封包數據所在系統記憶體中的位置。
延伸模組 是選擇性的,並保留案例特定功能的個別封包或個別片段元數據。 例如,封包擴充功能可以包含校驗和、大型分段卸載(LSO)、接收段合併(RSC)等卸載資訊,或保存應用程式特定的詳細數據。 片段延伸可以保存虛擬位址資訊、邏輯 DMA 位址資訊,或片段的其他資訊。
這些描述元和延伸模組一起會保存有關網路封包的所有元數據。 以下是兩個如何描述封包的範例。 第一個圖顯示一個情境,其中整個封包儲存在單一記憶體片段內,且已啟用檢查碼卸載。
第二個圖顯示一個封包儲存在兩個記憶體片段中,並且啟用了 RSC 和檢查和卸載功能。
封包描述元記憶體和存取
封包描述元和片段描述元都儲存在 NET_RING 結構中。 NIC 用戶端驅動程式會透過呼叫 Net Ring Iterator 介面來存取網路通道,並對其執行作業,讓驅動程式能夠與 NetAdapterCx 搭配運作,將網路數據張貼至硬體,並將已完成的數據清空回 OS。
如需 net rings 和 Net Ring Iterator 介面的詳細資訊,請參閱 net rings 簡介。
封包描述元擴充性
擴充性是 NetAdapterCx 封包描述元的核心功能,形成描述項版本性和效能的基礎。 在執行時,作業系統會配置連續區塊中每個封包佇列的所有封包描述符,及任何可用的擴充套件。 每個延伸模組區塊緊接在核心描述元後面,如下圖所示:
不允許網路介面卡用戶端驅動程式將位移硬編碼到任何擴充區塊。 相反地,它們必須在執行期間查詢,以取得任何特定擴充功能的偏移量。 例如,驅動程式可能會查詢延伸模組 B 的位移,並取回 70 個字節,如下圖所示:
一旦建立封包佇列及其描述元之後,系統會保證其所有擴充位移都是固定的,因此驅動程式不需要經常重新查詢位移。 此外,由於在封包佇列初始化時,系統會在區塊中預先配置所有延伸模組,因此不需要運行時間配置區塊、搜尋特定描述元的清單,或必須儲存每個封包擴充功能的指標。
封包描述項版本功能
NetAdapterCx 的核心封包描述元可透過將新的欄位新增至結尾,輕鬆地在未來版本中擴充,例如下圖:
瞭解 V2 欄位的較新用戶端驅動程式可以存取它們,而較舊的 V1 專用驅動程式會使用延伸模組位移來略過 V2 字段,以便存取他們瞭解的欄位。 此外,每個擴充功能都可以以相同的方式進行版本設定,如下圖所示:
瞭解新延伸模組的客戶端驅動程式可以使用它。 其他客戶端驅動程式可以略過新的欄位。 這可讓封包描述元的不同部分獨立進行版本設定。
封包描述元和數據路徑效能
先前提到的擴充性功能所提供的優勢,有助於客戶端驅動程式滿足每秒達數百Gbit且具有數千個佇列的NIC效能需求。
- 封包描述符會盡可能精簡,以改善 CPU 快取命中,因為未使用的功能和擴充功能在描述符中佔用 0 個字節空間。
- 沒有指標解參考,只有偏移運算,因為擴展功能是內嵌於代碼中,不僅節省空間,而且有助於提高CPU快取命中率。
- 擴充套件會在佇列創建時配置,因此驅動程式不需要在活躍的數據路徑中配置和解除分配記憶體,或處理內容區塊的旁觀清單。
使用資料包延伸功能
重要
目前,客戶端驅動程式僅限於作業系統 所定義的預先存在的封包擴充功能。
註冊封包延伸模組
在 NIC 用戶端驅動程式中使用封包擴充功能的第一個步驟是宣告您所支援的硬體卸載。 當您宣告對檢查碼和 LSO 等卸載進行支援時,NetAdapterCx 會自動為您註冊相關的封包擴充功能。
如需廣告硬體卸除的程式代碼範例,請參閱 硬體卸除簡介。
查詢資料路徑佇列中的封包擴展位移
藉由宣告硬體卸載支援來註冊封包擴充功能之後,您需要擴充功能偏移量,才能在您處理封包的過程中存取每個擴充功能。 若要減少驅動程式的呼叫並改善效能,您可以在 EvtNetAdapterCreateTx(Rx)Queue 回呼函式期間查詢延伸模組的位移,並將位移資訊儲存在您的佇列內容中。
如需查詢擴充位移並將其儲存在佇列內容中的範例,請參閱 傳輸和接收佇列。
在運行時間取得封包擴充功能
在佇列內容中儲存擴充位移之後,您可以隨時在擴充功能中需要資訊時使用這些位移。 例如,您可以在為傳輸佇列的硬體配置描述項時,呼叫 NetExtensionGetPacketChecksum 方法:
// Get the extension offset from the device context
PMY_TX_QUEUE_CONTEXT queueContext = GetMyTxQueueContext(txQueue);
NET_EXTENSION checksumExtension = queueContext->ChecksumExtension;
// Get the checksum info for this packet
NET_PACKET_CHECKSUM* checksumInfo = NetExtensionGetPacketChecksum(checksumExtension, packetIndex);
// Do work with the checksum info
if (packet->Layout.Layer3Type == NET_PACKET_LAYER3_TYPE_IPV4_NO_OPTIONS ||
packet->Layout.Layer3Type == NET_PACKET_LAYER3_TYPE_IPV4_WITH_OPTIONS ||
packet->Layout.Layer3Type == NET_PACKET_LAYER3_TYPE_IPV4_UNSPECIFIED_OPTIONS)
{
if(checksumInfo->Layer4 == NET_PACKET_TX_CHECKSUM_REQUIRED)
{
...
}
}
...
預先定義的封包擴充常數和協助程式方法
NetAdapterCx 提供已知封包擴充常數的定義。
恆定 | 定義 |
---|---|
NET_PACKET_EXTENSION_INVALID_OFFSET | 防止無效的偏移大小。 |
NET_PACKET_EXTENSION_CHECKSUM_NAME NET_PACKET_EXTENSION_CHECKSUM_VERSION_1 | 總和檢查碼封包延伸模組的名稱和版本。 |
NET_PACKET_EXTENSION_LSO_NAME NET_PACKET_EXTENSION_LSO_VERSION_1 | 大型傳送卸載(LSO)封包延伸模組的名稱和版本。 |
NET_PACKET_EXTENSION_RSC_NAME NET_PACKET_EXTENSION_RSC_VERSION_1 | 接收區段合併(RSC)封包擴充的名稱和版本。 |
此外,NetAdapterCx 提供協助程式方法,做為 NetExtensionGetData 方法的包裝函式。 每個方法都會傳回適當結構類型的指標。
方法 | 結構 |
---|---|
NetExtensionGetPacketChecksum | 網路封包校驗 |
NetExtensionGetGso | NET_PACKET_GSO |
NetExtensionGetPacketRsc | NET_PACKET_RSC |
使用片段延伸模組
重要
目前,客戶端驅動程式僅限於作業系統所定義的預先存在的片段擴展。
註冊片段延伸模組
NetAdapterCx 會藉由解譯驅動程式的表示功能,自動註冊大部分片段延伸模組。 例如,如果驅動程式表示它支援 DMA,架構會自動新增 DMA 程式設計所需的NET_FRAGMENT_LOGICAL_ADDRESS延伸模組。
查詢數據路徑佇列的片段擴展位移
若要存取片段擴展,您可以依照在資料路徑佇列中查詢封包擴展位移的位置中所述的相同步驟進行。
預先定義的片段延伸常數
NetAdapterCx 提供已知片段擴充常數的定義。
恆定的 | 定義 |
---|---|
NET_FRAGMENT_EXTENSION_DATA_BUFFER_NAME NET_FRAGMENT_EXTENSION_DATA_BUFFER_VERSION_1 | 數據緩衝區片段延伸模組的名稱和版本。 |
NET_FRAGMENT_EXTENSION_LOGICAL_ADDRESS_NAME NET_FRAGMENT_EXTENSION_LOGICAL_ADDRESS_VERSION_1 | 邏輯位址片段延伸模組的名稱和版本。 |
NET_FRAGMENT_EXTENSION_MDL_NAME NET_FRAGMENT_EXTENSION_MDL_VERSION_1 | MDL 片段延伸模組的名稱和版本。 |
NET_FRAGMENT_EXTENSION_RETURN_CONTEXT_NAME NET_FRAGMENT_EXTENSION_RETURN_CONTEXT_VERSION_1 | 傳回內容片段延伸模組的名稱和版本。 |
NET_FRAGMENT_EXTENSION_VIRTUAL_ADDRESS_NAME NET_FRAGMENT_EXTENSION_VIRTUAL_ADDRESS版本_1 | 虛擬位址片段延伸模組的名稱和版本。 |