2、非線性區域
在1、中,可以看到每張sk_buff的圖: 在end指針緊挨著一個非線性區域 ;
在struct sk_buff中沒有指向skb_shared_info結構的指針,利用end指針,,可以用skb_shinfo宏來訪問:
#define skb_shinfo(SKB) ((struct skb_shared_info *)(skb_end_pointer(SKB)))
其中skb_end_pointer函數如下,返回end指針
static inline unsigned char *skb_end_pointer(const struct sk_buff *skb)
{
return skb- >end;
}
具體地,struct skb_shared_info如下:
struct skb_shared_info {
__u8 __unused;
__u8 meta_len;
//數組frags包含的元素個數
__u8 nr_frags;
__u8 tx_flags;
unsigned short gso_size;
/* Warning: this field is not always filled in (UFO)! */
unsigned short gso_segs;
struct sk_buff *frag_list;
struct skb_shared_hwtstamps hwtstamps;
unsigned int gso_type;
u32 tskey;
/*
* Warning : all fields before dataref are cleared in __alloc_skb()
*/
//結構skb_shared_info 的引用計數器
atomic_t dataref;
/* Intermediate layers must ensure that destructor_arg
* remains valid until skb destructor */
void * destructor_arg;
/* must be last field, see pskb_expand_head() */
skb_frag_t frags[MAX_SKB_FRAGS];
};
其中skb_frag_t如下:
typedef struct skb_frag_struct skb_frag_t;
struct skb_frag_struct {
struct {
//指向文件系統緩存頁的指針
struct page *p;
} page;
#if (BITS_PER_LONG > 32) || (PAGE_SIZE >= 65536)
//數據起始地址在文件系統緩存頁中的偏移
__u32 page_offset;
//數據在文件系統緩存頁中使用的長度
__u32 size;
#else
__u16 page_offset;
__u16 size;
#endif
};
nr_frags,frags,frag_list與IP分片存儲有關。
frag_list的用法:
- 用于在接收分組后鏈接多個分片,組成一個完整的IP數據報
- 在UDP數據報輸出中,將待分片的SKB鏈接到第一個SKB中,然后在輸出過程中能夠快速的分片
- 用于存放FRAGLIST類型的聚合分散I/O數據包
判斷是否存在非線性緩沖區:
- 先說明struct sk_buff中關于長度的兩個字段
- len字段:無分片的報文,數據報文的大小
- data_len字段:存在分散報文,data_len表示分片的部分大小
如下所示,沒有開啟分片的報文len = x,data_len = 0:
如下所示在Linux內核中,使用skb_is_nonlinear函數判斷是否存在分片,即通過判斷data_len的大小是否為0:
static inline bool skb_is_nonlinear(const struct sk_buff *skb)
{
return skb- >data_len;
}
- 在沒有開啟分片的報文中,數據包長度在struct sk_buff中為len字段的大小,即data到tail的長度,nf_frags為0,frag_list為NULL。
普通聚合分散I/O的報文:
采用聚合分散I/O的報文, frag_list為 NULL,nf_frags不等于0 ,說明這不是一個普通的分片,而是聚合分散I/O的報文。
如下所示:
nr_frags為2,而frag_list為NULL,說明這不是普通的分片,而是聚合分散I/O分片,數量為2,這兩個分片指向同一物理分頁,各自在分頁中的偏移和長度分別是0/S1和S1/S2。
FRAGLIST類型的分散聚合I/O的報文:
采用FRAGLIST類型的分散聚合I/O報文, ** frag_list不為NULL,nf_frags等于0 ,** 數據長度len為x+S1,data_len為S1,
以上從struct sk_buff的四大指針以及操作、非線性區域對套接字緩存(socket buffer)進行分析,更多sk_buff的分析、實操等將在以后的文章中梳理。
-
嵌入式
+關注
關注
5094文章
19184瀏覽量
307845 -
Linux
+關注
關注
87文章
11350瀏覽量
210460 -
內存
+關注
關注
8文章
3060瀏覽量
74353
發布評論請先 登錄
相關推薦
Linux sk_buff四大指針與相關操作
![Linux <b class='flag-5'>sk_buff</b>四大指針與<b class='flag-5'>相關</b><b class='flag-5'>操作</b>](https://file.elecfans.com/web2/M00/6F/CE/poYBAGNH1sCANs83AAAOVhEjMFs521.png)
Linux內存點滴 用戶進程內存空間
嵌入式linux TCP/IP協議棧概述
DM8127使用SWOSD_TI_alloc()分配內存空間怎么加大?
ARM32 Linux的內存布局
RTThread的動態內存空間該如何去分配呢
Linux網絡設備驅動程序
如何讓你的手機省出內存空間
網卡的Ring Buffer詳解
網卡的Ring Buffer詳解
sk_buff內存空間布局情況與相關操作(二)
![<b class='flag-5'>sk_buff</b><b class='flag-5'>內存空間布局</b><b class='flag-5'>情況</b>與<b class='flag-5'>相關</b><b class='flag-5'>操作</b>(二)](https://file1.elecfans.com/web2/M00/8E/67/wKgaomTGIp6AbIqeAAA2bQfUjsI705.jpg)
淺析新能源電動汽車充電樁空間布局優化研究
![淺析新能源電動汽車充電樁<b class='flag-5'>空間布局</b>優化研究](https://file1.elecfans.com//web3/M00/02/76/wKgZPGdf25OAYzS6AACh3TFyOrA435.png)
評論