走進Linux核心網路 報文是什麼 sk buff

2021-08-30 17:35:11 字數 1973 閱讀 6077

今天來聊下sk_buff。如果把核心網路協議棧比作乙個人,那麼sk_buff就是流淌在他體內血管裡紅血球,它運輸養分(資料)走遍全身(協議棧每一層)。乙個sk_buff就是乙個報文。

在協議棧層次模型中,我們提到過,報文在協議棧各層之間穿梭,傳送方向不斷加上header,接收方向不斷去掉header。自然而然,我們要設計資料結構去表示在各個層上形態各異的報文

我們可以這麼設計ip報文:

struct ip_pdu
tcp報文呢, 就像下面這樣

struct tcp_pdu
然後層與層之間進行報文資料結構的拷貝和轉換。

等等!網路協議那麼多,難道要每種協議設計乙個新的資料結構?!另外,像這樣每個報文都要拷貝多次的話效率也太低了吧?!

所以,linux採用的報文層間傳遞的方式就是乙個結構,傳遞指標,這個結構就是sk_buff, 也就是說, 無論是哪個層次的報文, 在核心中始終都以sk_buff表示(sk_buffsocket buffer的簡稱)

下面是sk_buff結構的構成(精簡後)

typedef

unsigned

char

*sk_buffer_data_t;

struct sk_buff

重點關注最後四個字段,準確的說是四個指標,

如上圖所示,這四個指標的外面兩個限定了乙個大的緩衝區,而中間兩個則是包裹了有效資料,所謂有效資料便是報文。這麼設計的原因就是避免拷貝! 以傳送方向為例,我們知道傳送過程是一層一層的在報文前方貼header,因此,既然我們知道隨著報文向下傳遞時,長度會增加。那麼我們不如就在最初報文(應用層)的前面預留一定的空間,就可以避免向下傳遞時還要重新申請記憶體再拷貝了。

上圖描述了在接收方向報文上送時的指標移動方向,之前說的去掉header就是指這個。

控制字段cb是乙個很有意思的字段,它是乙個雜貨間,沒有標準的格式,因此可以存放各種資料,最多40個位元組。當報文在協議棧中流動時,流到哪一層,哪一層就將自己的私有資料放到這個區域。比如tcp用這個區域儲存收到的tcp報文頭中的一些字段。

struct tcp_skb_cb
struct sock *skstruct net_device *dev則分別代表了sk_buff的起點和終點。對於傳送方向,報文由應用層產生,自然是通過乙個套接字到核心,最終從乙個裝置傳送出去,這時sk是起點,dev是終點。而對於接收方向,報文由乙個裝置接收,最終被應用層通過乙個套接字拿到,這時,這時dev是起點,sk是終點.

協議棧使用sk_buff表示所有報文,sk_buff在協議棧中傳遞時以指標傳遞並且不會拷貝

cb是乙個雜貨間,每一層都可以使用

skdev是報文的起點和終點,對傳送方向和接收方向來說正好相反。

Linux核心網路報文簡單流程

linux核心網路報文簡單流程 2014 08 12 10 05 09 分類 linux linux下的網絡卡驅動中通常會提供類似 rx的接收函式 該函式處理與具體硬體相關的暫存器操作 包括中斷檢查,資料狀態檢查,錯誤檢查等 在確認有資料抵達後讀取資料或從dma的接收環中獲取資料位址 rx函式以sk...

linux核心網路協議棧 網絡卡報文收發(十六)

linux版本 3.10.103 網絡卡驅動 ixgbev 網絡卡驅動預設採用的是napi的報文處理方式。即中斷 輪詢的方式,網絡卡收到乙個報文之後會產生接收中斷,並且遮蔽中斷,直到收夠了netdev max backlog個報文 預設300 或者收完網絡卡上的所有報文之後,重新開啟中斷。網絡卡啟用...

linux 核心網路雜燴

linux核心網路驅動屬於iso的第二層,資料鏈路層 其中sk buff在資料報的收發中起關鍵性作用,作為資料的載體,經由每一層其資料區域都在變化,關於sk buff相關資料,以下幾篇很不錯,主要講解sk buff的結構以及在每一層的變化過程,學習網路驅動,sk buff是重要的乙個結構體,必須足夠...