封包描述項和延伸模組
在 NetAdapterCx 中, 封包描述項 是描述網路封包的小型、精簡、執行時間可延伸結構。 每個封包都需要下列各項:
- 一個核心描述項
- 一或多個片段描述項
- 零或多個封包延伸模組
封包 的核心描述項 是 NET_PACKET 結構。 它只包含適用于所有封包的最基本中繼資料,例如指定封包的框架配置,以及封包第一個片段描述元的索引。
每個封包也必須有一或多個 片段描述項,或 NET_FRAGMENT 結構,描述封包資料所在系統記憶體中的位置。
擴充 功能是選擇性的,可保留案例特定功能的個別封包或每個片段中繼資料。 例如,封包延伸模組可以保存總和檢查碼的卸載資訊、大型傳送卸載 (LSO) ,以及接收區段聯合 (RSC) ,或者可以保存應用程式特定的詳細資料。 片段延伸可以保存虛擬位址資訊、邏輯 DMA 位址資訊,或片段的其他資訊。
這些描述項和延伸模組會一起保存有關網路封包的所有中繼資料。 以下是其描述封包方式的兩個範例。 第一個圖顯示整個封包儲存在單一記憶體片段內,並已開啟總和檢查碼卸載的案例。
第二個圖顯示儲存在兩個記憶體片段上的封包,並同時啟用 RSC 和總和檢查碼卸載。
封包描述項儲存體和存取
封包描述項和片段描述元都儲存在 NET_RING 結構中。 NIC 用戶端驅動程式會存取網路通道,並藉由呼叫 Net Ring Iterator 介面來執行作業,讓驅動程式能夠使用 NetAdapterCx 將網路資料張貼到硬體,並將已完成的資料清空回 OS。
如需 net ring 和 Net Ring Iterator 介面的詳細資訊,請參閱 net ring 簡介。
封包描述項擴充性
擴充性是 NetAdapterCx 封包描述元的核心功能,形成描述項版本性和效能的基礎。 在執行時間,作業系統會將所有封包描述項配置給連續區塊中的每個封包佇列,以及任何可復原的擴充功能。 每個擴充功能區塊緊接在核心描述元後方,如下圖所示:
不允許 NIC 用戶端驅動程式將位移硬式編碼為任何擴充區塊。 相反地,它們必須在執行時間查詢,以取得任何特定延伸模組的位移。 例如,驅動程式可能會查詢擴充功能 B 的位移,並取得 70 個位元組,如下圖所示:
一旦建立封包佇列及其描述項,系統就會保證其所有擴充位移都是固定的,因此驅動程式不需要經常重新查詢位移。 此外,由於在封包佇列初始化時,系統會在區塊中預先配置所有延伸模組,因此不需要執行時間配置區塊、搜尋特定描述元的清單,或必須儲存每個封包延伸模組的指標。
封包描述項版本性
NetAdapterCx 的核心封包描述元可藉由將新的欄位新增至結尾,輕鬆地在未來版本中擴充,如下圖所示:
瞭解 V2 欄位的較新用戶端驅動程式可以存取它們,而較舊的僅限 V1 驅動程式會使用延伸模組位移來略過 V2 欄位,讓他們可以存取他們瞭解的欄位。 此外,每個擴充功能都可以以相同方式進行版本設定,如下圖所示:
瞭解新延伸模組的用戶端驅動程式可以使用它。 其他用戶端驅動程式可以略過新的欄位。 這可讓封包描述元的不同部分獨立進行版本設定。
封包描述項和資料路徑效能
先前所述的擴充性功能提供優點,可協助用戶端驅動程式符合每秒數百 GB 的 NIC 效能需求,以及數千個佇列:
- 封包描述項會盡可能精簡,以改善 CPU 快取點擊,因為未使用的功能和擴充功能佔用描述元中的 0 個位元組空間。
- 沒有指標取值,只有位移算術,因為延伸模組內嵌,不僅節省空間,也有助於 CPU 快取叫用。
- 擴充功能會在佇列建立時配置,因此驅動程式不需要在作用中資料路徑中配置和解除配置記憶體,或處理內容區塊的外觀清單。
使用封包擴充功能
重要
目前,用戶端驅動程式僅限於 作業系統所定義的既有封包擴充功能。
註冊封包擴充功能
在 NIC 用戶端驅動程式中使用封包擴充功能的第一個步驟是宣告您支援的硬體卸載。 當您公告對總和檢查碼和 LSO 等卸載的支援時,NetAdapterCx 會自動代表您註冊相關聯的封包延伸模組。
如需廣告硬體卸載的程式碼範例,請參閱 硬體卸載簡介。
查詢資料路徑佇列的封包延伸模組位移
藉由宣告硬體卸載支援來註冊封包擴充功能之後,您需要擴充功能位移,才能在處理封包時存取每個延伸模組。 若要減少驅動程式的呼叫並改善效能,您可以在 EvtNetAdapterCreateTx (Rx) 佇列 回呼函式期間查詢擴充功能的位移,並將位移資訊儲存在佇列內容中。
如需查詢擴充位移並將其儲存在佇列內容中的範例,請參閱 傳輸和接收佇列。
在執行時間取得封包擴充功能
在佇列內容中儲存延伸模組位移之後,您可以隨時在擴充功能中需要資訊時使用這些位移。 例如,當您將描述項程式設計為傳輸佇列的硬體時,您可以呼叫 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 | NET_PACKET_CHECKSUM |
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_VERSION_1 | 虛擬位址片段延伸模組的名稱和版本。 |