DPDK 分片 mbuf 原理

2021-10-10 16:17:03 字數 3656 閱讀 5540

mtu是最大傳輸單元( maximum transmission unit)的縮寫,指乙個介面無需分片所能傳送的資料報的最大位元組數。 

mtu範圍在46 ~ 1500位元組,預設一般都是1500。

1)mtu為1500時計算總長度

7位元組前導碼+1位元組幀開始定界符+6位元組的目的mac+6位元組的源mac+2位元組的幀型別+1500位元組ip頭及資料+4位元組的 fcs = 1526位元組。

2)為什麼我們抓包得到的最大幀是1514位元組?

當資料幀到達網絡卡時,在物理層上網絡卡要先去掉前導同步碼和幀開始定界符,然後對幀進行crc檢驗,如果幀校驗和錯,就丟棄此幀。如果校驗和正確,就去掉fcs再交給「裝置驅動程式」做進一步處理。這時我們的抓包軟體才能抓到資料,因此,抓包軟體抓到的是去掉前導碼、幀開始定界符、fcs之外的資料,其最大值是 6+6+2+1500=1514。

3)如果mtu為46,不分片的最大以太幀長度

乙太網規定,乙太網幀資料域部分最小為46位元組,也就是乙太網幀最小是 6+6+2+46+4=64。抓包時要除去4個位元組的fcs,因此,抓包看到是60位元組。

當資料字段的長度小於46位元組時,mac層(由驅動程式)會在資料字段的後面填充資料,以滿足資料幀長不小於64位元組。

ip分片發生在ip層,不僅源端主機會進行分片,中間的路由器也有可能分片,因為不同的網路的mtu是不一樣的,如果傳輸路徑上的某個網路的mtu比源端網路的mtu要小,路由器就可能對ip資料報再次進行分片。而分片資料的重組只會發生在目的端的ip層。

下圖紅色框裡是我們熟悉的ip首部格式,與分片相關的是圖中淺綠色+深綠色的方框(共32位)

1)淺綠框的「16位元組標識」

同乙個資料報的各個分片的標識是一樣的,目的端會根據這個標識來判斷ip分片是否屬於同乙個ip資料報。

2)深綠框的「標誌」

3)深綠框的「片偏移」

它表示分片在原始資料中的偏移,這裡的原始資料是ip層收到的tcp或udp資料,不包含ip首部。需要注意的是,在分片的資料中,傳輸層的首部只會出現在第乙個分片中,因為傳輸層的資料格式對ip層是透明的,傳輸層的首部只有在傳輸層才會有它的作用,ip層不知道也不需要保證在每個分片中都有傳輸層首部。所以,在網路上傳輸的資料報是有可能沒有傳輸層首部的。

在網路程式設計中,我們要避免出現ip分片。因為ip層是沒有超時重傳機制的,如果ip層對乙個資料報進行了分片,只要有乙個分片丟失了,只能依賴於傳輸層進行重傳,結果是所有的分片都要重傳一遍,會大大降低傳輸層傳送資料的成功率,所以我們要避免ip分片。

1)udp

我們需要在應用層去限制每個包的大小,一般不要超過1472位元組(不考慮ip首部選項欄位的情況),即乙太網mtu(1500) - ip首部(20)- udp首部(8)。

2)tcp(不用考慮ip分片)

應用層不需要考慮這個問題,因為傳輸層已經幫我們做了。在建立連線的三次握手的過程中,連線雙方會相互通告mss(maximum segment size,最大報文段長度),mss肯定是<=網路層的最大路徑mtu,然後tcp資料封裝成ip資料報通過網路層傳送,當伺服器端傳輸層接收到tcp資料之後進行tcp重組。tcp的ip資料報在傳輸過程中是不會發生分片的。

linux實現分析:

bsd:tcp/ip詳解卷二,第十章

ip分段和重組庫實現ipv4和ipv6資料報的分段和重組。

資料報分段邏輯將輸入的資料報劃分為多個分段。 rte_ipv4_fragment_packet()和rte_ipv6_fragment_packet()函式均假定輸入mbuf資料指向資料報ip報頭的開頭(即l2報頭已被剝離)。為避免複製實際資料報的資料,使用了零拷貝技術(rte_pktmbuf_attach)。

對於每個片段,將建立兩個新的mbuf:

然後,將l3頭部從原始mbuf複製到「直接」mbuf,並進行更新以反映新的分片狀態。請注意,對於ipv4,不重新計算標頭校驗和,並將其設定為零。

最後,每個片段的「直接」和「間接」 mbuf通過mbuf的next欄位鏈結在一起,以組成新片段的資料報。

呼叫方可以明確指定應使用哪些記憶體池來分配「直接」和「間接」 mbuf。

分片表中維護已經接收到的資料報片段的資訊。

請注意,片段表上的所有更新/查詢操作都不是執行緒安全的。因此,如果不同的執行上下文(執行緒/程序)要同時訪問同一張表時,必須提供一些外部同步機制。

每個表條目都可以儲存有關資料報的資訊,這些資訊最多由rte_librte_ip_frag_max(預設為4個)片段組成。

該**示例演示了如何建立新的分片表:

frag_cycles = (rte_get_tsc_hz() + ms_per_s - 1) / ms_per_s * max_flow_ttl;

bucket_num = max_flow_num + max_flow_num / 4;

frag_tbl = rte_ip_frag_table_create(max_flow_num, bucket_entries, max_flow_num, frag_cycles, socket_id);

內部分片表是乙個簡單的雜湊表。基本思想是使用兩個雜湊函式和主備兩個hash桶,每個桶下有若干。這為每個鍵在雜湊表中提供了2 * 個可能的位置。當衝突發生並且所有2 * 都被占用時,ip_frag_tbl_add()不會將現有鍵重新插入替代位置,而只會返回失敗。(我的理解,這裡是對hash庫里cuckoo演算法的簡化說明)。

此外,表中駐留時間長於的條目被視為無效,可以被新條目替換或刪除。

請注意,重組需要分配大量的mbuf。在任何給定時間,最多可以將(2 * bucket_entries * rte_librte_ip_frag_max * 《每個資料報的最大mbufs個數》)儲存在分片表中,以等待剩餘的分片。

分片資料報的處理和重組是由rte_ipv4_frag_reassemble_packet()/ rte_ipv6_frag_reassemble_packet()函式完成的。它們要麼返回乙個指向「包含重組後資料報的有效mbuf「的指標,要麼返回null(由於某種原因而無法完成據包重組數)。

這些功能包括:

1)占用乙個空條目。

2)刪除超時條目,釋放與它相關聯的mbufs,並在其中儲存具有指定鍵的新條目。

1)如果是,則重新組合資料報,將表的條目標記為空,然後將重新組合的mbuf返回給呼叫方。

2)如果否,則將null返回給呼叫方。

rte_librte_ip_frag_tbl_stat配置巨集控制分片表的統計資訊收集。預設情況下不啟用此巨集。

rte_librte_ip_frag_debug控制ip分片處理和重組的除錯日誌記錄。預設情況下禁用此巨集。請注意,雖然日誌記錄包含許多詳細資訊,但它減慢了資料報處理的速度,並可能導致許多資料報的丟失。

參考:

dpdk官方程式設計指南:

dpdk中文 mbuf的基本操作

mbuf是報文中的描素的結構體,是整個 過程中最核心的資料結構之一。主要針對於mbuf的常用api與基本原理做乙個簡單的介紹 首先我們看一下rte mbuf的資料結構的定義 先主要說明幾個跟資料有關的變數 struct rte mbuf 既然叫mbuf,其實就是一種buf管理的結構體 如上圖所示 m...

IP分片原理

ip 分片原理 ip分片是網路上傳輸 ip報文的一種技術手段。ip協議在傳輸資料報時,將資料報文分為若干分片進行傳輸,並在目標系統中進行重組。不同的鏈路型別規定有不同最大長度的鏈路層資料幀,稱為鏈路層 mtu 最大傳輸單元 常見乙太網的 mtu為 1500 若ip 協議在傳輸資料報時,ip報文長度大...

Elasticsearch 分片原理1

elasticsearch版本 6.0 elasticsearch基於lucene,採用倒排索引寫入磁碟,lucene引入了按段搜尋的概念,來動態更新索引。乙個lucene索引包含乙個提交點和三個短,如圖 關於索引和分片乙個lucene索引在elasticsearch成為分片,乙個elasticse...