当前位置: 首页 > >

linux协议栈之链路层上的数据传输-----sk_buff结构分析

发布时间:

出处:http://ericxiao.cublog.cn/


------------------------------------------



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)


返回缓存区中可用的空间大小


?



?



友情链接: