struct s_mbuf與struct sk_buff本文的copyleft歸[email protected]所有,使用GPL釋出,可以自由拷貝,轉載。但轉載請保持文檔的完整性,注明原作者及原連結,嚴禁用于任何商業用途。
部落格:linuxfocus.blog.chinaunix.net
為了有一個入口來研究TCP/IP源碼,那麼就按照《TCP/IP詳解——卷2》來開始吧。
TCP/IP詳解的内容是Linux2.4的,在Linux2.6中mbuf有了很大的變化。
檔案位置:linux-2.6.36.1/drivers/net/skfp/h/mubf.h
#define M_SIZE 4504
#ifndef MAX_MBUF
#define MAX_MBUF 4
#endif
#ifndef NO_STD_MBUF
#define sm_next m_next
#define sm_off m_off
#define sm_len m_len
#define sm_data m_data
#define SMbuf Mbuf
#define mtod smtod
#define mtodoff smtodoff
struct s_mbuf {
struct s_mbuf *sm_next ; /* low level linked list */
short sm_off ; /* offset in m_data */
u_int sm_len ; /* len of data */
#ifdef PCI
int sm_use_count ;
char sm_data[M_SIZE] ;
} ;
typedef struct s_mbuf SMbuf ;
/* mbuf head, to typed data */
/* 得到s_mbuf中的資料轉換成指定的類型t */
#define smtod(x,t) ((t)((x)->sm_data + (x)->sm_off))
/* 這個宏沒有被别的地方調用,用途是将data指定偏移位址o的指針轉為類型t */
#define smtodoff(x,t,o) ((t)((x)->sm_data + (o)))
通過查詢SMbuf在源代碼中的引用,可以看出s_mbuf在linux2.6中的用途遠沒有mbuf在linux中廣泛——linux2.4中,mbuf負責了核心中的存儲器緩存。
那麼在linux2.6中,又由哪一個結構來承擔linux2.4中mbuf的作用——答案是sk_buff。
struct sk_buff {
/*
These two members must be first. */
/* 這兩個變量用于形成sk_buff的雙連結清單 */
struct sk_buff *next;
struct sk_buff *prev;
/* 資料包到達的時間 */
ktime_t tstamp;
/* 這個sk_buff被哪個sock擁有 */
struct sock *sk;
/* 這個sk_buff到達的device或者要從哪個device發送 */
struct net_device *dev;
* This is the control buffer. It is free to use for every
* layer. Please put your private variables there. If you
* want to keep them across layers you have to do a skb_clone()
* first. This is owned by whoever has the skb queued ATM.
*/
char cb[48] __aligned(8);
/* destination entry */
unsigned long _skb_refdst;
#ifdef CONFIG_XFRM
struct sec_path *sp;
/* len為實際資料長度,data_len為資料長度 */
unsigned int len,
data_len;
/* mac_len:資料鍊路層位址長度,hdr_len:克隆的skb可寫頭部的長度 */
__u16 mac_len,
hdr_len;
union {
__wsum csum;
struct {
__u16 csum_start;
__u16 csum_offset;
};
};
/* 包的排隊優先級 */
__u32 priority;
kmemcheck_bitfield_begin(flags1);
/*
一些标志位:
local_df:允許本地分片;
nohdr:隻能引用其payload
*/
__u8 local_df:1,
cloned:1,
ip_summed:2,
nohdr:1,
nfctinfo:3;
__u8 pkt_type:3,
fclone:2,
ipvs_property:1,
peeked:1,
nf_trace:1;
kmemcheck_bitfield_end(flags1);
__be16 protocol;
void (*destructor)(struct sk_buff *skb);
#if defined(CONFIG_NF_CONNTRACK) ||defined(CONFIG_NF_CONNTRACK_MODULE)
struct nf_conntrack *nfct;
struct sk_buff *nfct_reasm;
#ifdef CONFIG_BRIDGE_NETFILTER
struct nf_bridge_info *nf_bridge;
/* 由哪個interface到達的 */
int skb_iif;
#ifdef CONFIG_NET_SCHED
__u16 tc_index; /* traffic control index */
#ifdef CONFIG_NET_CLS_ACT
__u16 tc_verd; /* traffic control verdict */
__u32 rxhash;
kmemcheck_bitfield_begin(flags2);
__u16 queue_mapping:16;
#ifdef CONFIG_IPV6_NDISC_NODETYPE
__u8 ndisc_nodetype:2,
deliver_no_wcard:1;
#else
__u8 deliver_no_wcard:1;
kmemcheck_bitfield_end(flags2);
0/14 bit hole */
#ifdef CONFIG_NET_DMA
dma_cookie_t dma_cookie;
#ifdef CONFIG_NETWORK_SECMARK
__u32 secmark;
/* 這個sk_buff被哪個sock擁有 */
__u32 mark;
__u32 dropcount;
__u16 vlan_tci;
/* 傳輸層報頭 */
sk_buff_data_t transport_header;
/* 網絡層報頭 */
sk_buff_data_t network_header;
/* 鍊路層報頭 */
sk_buff_data_t mac_header;
sk_buff_data_t tail;
sk_buff_data_t end;
unsigned char *head,
*data;
unsigned int truesize;
atomic_t users;
};
今天隻能先寫到這裡,明天繼續分析sk_buff結構。其實在linux 2.6代碼中,每個變量的用途,注釋寫得很明白。