歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux基礎 >> 關於Linux

linux協議棧之鏈路層上的數據傳輸-sk

sk_buff結構分析

sk_buff是我們遇到的第二個重要的結構,在內核中經常被縮寫成skb.在linux 2.6.21它被定義成:

struct sk_buff {

//指向下一個skb

struct sk_buff *next;

//上一個skb

struct sk_buff *prev;



struct sk_buf0f_head *list;

//對應的sock。這也是個重要的結構,在傳輸層的時候我們再來分析

struct sock *sk;

//接收或者發送時間戳

struct timeval stamp;

//接收或者發送時對應的net_device

struct net_device *dev;

//接收的net_device

struct net_device *input_dev;

//數據包對應的真實net_device.關於虛擬設備可以在之後的網橋模式分析中討論

struct net_device *real_dev;

//ip層的相關信息

union {

struct tcphdr *th;

struct udphdr *uh;

struct icmphdr *icmph;

struct igmphdr *igmph;

struct iphdr *ipiph;

struct ipv6hdr *ipv6h;

unsigned char *raw;

} h;

//協議層的相關信息

union {

struct iphdr *iph;

struct ipv6hdr *ipv6h;

struct arphdr *arph;

unsigned char *raw;

} nh;

//鏈路層的相關信息

union {

unsigned char *raw;

} mac;

//在路由子系統中再來分析這一結構

struct dst_entry *dst;

struct sec_path *sp;



/*

* 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[40];

//各層的數據長度

unsigned int len,

data_len,

mac_len,

csum;

unsigned char local_df,

cloned,

pkt_type,

ip_summed;

__u32 priority;

unsigned short protocol,

security;



void (*destructor)(struct sk_buff *skb);

#ifdef CONFIG_NETFILTER

unsigned long nfmark;

__u32 nfcache;

__u32 nfctinfo;

struct nf_conntrack *nfct;

#ifdef CONFIG_NETFILTER_DEBUG

unsigned int nf_debug;

#endif

#ifdef CONFIG_BRIDGE_NETFILTER

struct nf_bridge_info *nf_bridge;

#endif

#endif /* CONFIG_NETFILTER */

#if defined(CONFIG_HIPPI)

union {

__u32 ifield;

} private;

#endif

#ifdef CONFIG_NET_SCHED

__u32 tc_index; /* traffic control index */

#ifdef CONFIG_NET_CLS_ACT

__u32 tc_verd; /* traffic control verdict */

__u32 tc_classid; /* traffic control classid */

#endif



#endif





/* These elements must be at the end, see alloc_skb() for details. */

unsigned int truesize;

//引用計數

atomic_t users;

//存儲空間的起始地址

unsigned char *head,

//網絡數據的起始起址

*data,

//存放網絡數據的結束地址

*tail,

//存儲空間的結束地址

*end;

}

對應我們上面的網卡驅動分析。接收到的數據是存放在data至tail之間的區域。

Skb通常還有常用的幾個函數,一一列舉分析如下:

struct sk_buff *alloc_skb(unsigned int size,int gfp_mask)

分配存儲空間為sixe的skb,內存分配級別為gfp_mask.注意這裡的存儲空間的含義,即為skb->data至skb->tail的區域

struct sk_buff *skb_clone(struct sk_buff *skb, int priority)

克隆出的skb指向同一個結構,同時會增加skb的引用計數

struct sk_buff *skb_copy(const struct sk_buff *skb, int priority)

復制一個全新的skb

void kfree_skb(struct sk_buff *skb)

當skb的引用計數為1的時候,釋放此skb

unsigned char *skb_put(struct sk_buff *skb, unsigned int len)

使skb的存儲空間擴大len.即使tail指針下移

unsigned char *skb_push(struct sk_buff *skb, unsigned int len)

push,即推出一段數據,使data指針下層。

void skb_reserve(struct sk_buff *skb, unsigned int len)

該操作使data指針跟tail指針同時下移,即擴大存儲區域之前的空間

int skb_headroom(const struct sk_buff *skb)

返回data之前可用的空間數量

int skb_tailroom(const struct sk_buff *skb)

返回緩存區中可用的空間大小
 

Copyright © Linux教程網 All Rights Reserved