關於skb header pointer函式

2022-06-17 11:24:08 字數 2329 閱讀 5091

摘自:

最近一段時間看核心**,總是看到skb_header_pointer函式,這個函式的主要功能很簡單,就是從skb欄位中獲取指定長度到內容到快取中。函式原型是這個樣子的:

static inline void *skb_header_pointer(const struct sk_buff *skb, int offset,

int len, void *buffer)

也就是從skb中skb->data開始的offset偏移處,獲取len長度的內容到buff中。

看起來這個並沒有什麼問題,不過無意中在網上搜了一下這個函式,卻發現還真有一些別的意義在裡面。。好吧,看一下**,依然是2.6.30版本核心。

static inline void *skb_header_pointer(const struct sk_buff *skb, int offset,

int len, void *buffer)

引數為:

skb:資料報struct sk_buff的指標

offset:相對資料起始頭(如ip頭)的偏移量

len:資料長度

buffer:緩衝區,大小不小於len

其中skb_headlen()函式的定義為:

static inline unsigned int skb_headlen(const struct sk_buff *skb)

其中skb->len是資料報長度,在ipv4中就是單個完整ip包的總長,但這些資料並不一定都在當前記憶體頁;skb->data_len表示在其他頁的資料長度(包括本skb在其他頁中的資料以及分片skb中的資料),因此skb->len - skb->data_len表示在當前頁的資料大小。

如果skb->data_len不為0,表示該ip包的資料分屬不同的頁,該資料報也就被成為非線性化的,函式skb_is_nonlinear()就是通過該引數判斷,一般剛進行完碎片重組的skb包就屬於此類。

這樣skb_header_pointer()函式就好理解了,先判斷要處理的資料是否都在當前頁面內,如果是,則返回可以直接對資料處理,返回所求資料指標,否則用skb_copy_bits()函式進行拷貝,下面再來看一下這個函式的實現過程,並不複雜。

/* copy some data bits from skb to kernel buffer. */

int skb_copy_bits(const struct sk_buff *skb, int offset, void *to, int len)

/*拷貝本skb中其他碎片的部分*/

for (i = 0; i < skb_shinfo(skb)->nr_frags; i++)

start = end;

}/*拷貝其他碎片skb中的資料部分,對於skb的遞迴呼叫*/

if (skb_shinfo(skb)->frag_list)

start = end;}}

if (!len)

return 0;

fault:

return -efault;

}其中的skb_copy_from_linear_data_offset函式,就是乙個線性拷貝的過程,內部是對memcpy的乙個封裝。

kmap_skb_frap沒有看明白,不過其意思應該是把分片資料所在的page位址對映到了乙個核心可訪問的虛擬位址上,通過這個虛擬位址完成資料的拷貝,最後再通過kunmap_skb_frag完成對映位址的釋放。

這些都不是重點,主要的是我在網上看到了這樣一些話,便直接把它們拷貝過來吧:

在2.4中是沒有這一函式的,因為2.4的netfilter首先進行碎片包重組,隨即進行skb的線性化檢查,對非線性skb包進行線性化,因此合法skb包進入後續hook點操作時實際skb->data_len就都是0了,可以直接操作。

netfilter的碎片重組函式為ip_ct_gather_frags(),在2.4中碎片重組完還進行線性化,而2.6中重組完就直接返回了,並不進行線性化操作,因此以後在使用的時候必須檢查要處理的資料是否在記憶體頁面中。

由於2.6中的碎片重組操作後不進行skb資料報的線性化,因此資料可能存在於不同的記憶體頁面中,對於不在同一頁面中的情況不能直接進行資料操作,需要將資料拷貝到乙個單獨緩衝區後再進行處理。

關於核心為什麼這樣做,我沒找到標誌答案,下面是乙個網友的回覆,也貼上過來,有機會的話就慢慢了解了:

非線性化很重要的一點是為了支援網絡卡晶元的一些功能,這些功能可以大大增加tcp的效能。

如tso(tcp segment offload),在sendfile中。 系統只是增加file對應的page cache 的引用數,接著將乙個個頁面放在skb中傳送,一次可以放接近65535 - tcp頭的資料。網絡卡如e1000,會根據mss大小切割報文並計算校驗後傳送。

關於程式關於世界

首先,在學了1年多的軟體設計的基礎上,問下自己 程式是什麼?業務需求是什麼?程式有什麼用?什麼是演算法?什麼是資料庫?或許每個人的理解不同,會給出不同的答案。那麼自己的理解 程式是乙個讓計算機工作的流程,在程式寫好之後,計算機就會按照,程式設計師定義好流程在執行。其實很多時候,乙個程式的好壞,在於乙...

關於血液關於軟體

1 自然沉降法 將血袋垂直吊掛於4 2 冰箱內,使紅細胞自然下沉1 3d,或將血袋呈70 80 角立於冰箱,需用時,用一次性分漿器分出血漿,制得濃縮紅細胞。2 洗滌法 一般用生理鹽水反覆洗滌3 6次。經洗滌的紅細胞,除白細胞和血小板減少外,血漿蛋白也極少,紅細胞中殘存的血漿蛋白含量約為原總蛋白的1 ...

關於冷漠,關於愛情

我不知道為什麼今天又莫名其妙開始思考愛情這件事,隨之就解決了我一直無法面對冷漠這件事 被冷漠是我始終無法消化的一件事,每當遇見冷漠時,我總會覺得就像一團火把自己燒得面目全非,但對方卻毫無傷害。但我突然懂了,遇到冷漠時,體面的離開即可 在乎你的人一定會在你離開後,找到你跟你解釋為什麼 連解釋都來不及,...