您现在的位置是:首页 > 数码 > 

sk

2025-07-27 13:30:57
sk sk_buff 简介 封包存储于struct sk_buff中,所有网络分层都会使用这个结构来储存其报头、有关用户数据的信息,以及协调其工作的其他内部信息。从第二层到第四层都会使用这个数据结构。L4附加一个报头传给L,L附加自己的报头传给L2,L2附加自己的报头传给L1转发出去。设备收到sk_buff之后,每层都只

sk

sk_buff 简介

封包存储于struct sk_buff中,所有网络分层都会使用这个结构来储存其报头、有关用户数据的信息,以及协调其工作的其他内部信息。从第二层到第四层都会使用这个数据结构。L4附加一个报头传给L,L附加自己的报头传给L2,L2附加自己的报头传给L1转发出去。设备收到sk_buff之后,每层都只处理自己的报头,并将其呈交给上层。

sk_buff数据结构

内核使用一个双向链表来维护sk_buff,链表的开端使用了一个哑元元素sk_buff_head,如下图所示为sk_buff链表:

  sk_buff_head以及sk_buff的数据结构如下:

struct sk_buff_head {/* These two members must be first. */struct sk_buff	*next;   //第一个元素struct sk_buff	*prev;   //最后一个元素__u2		qlen;        //表中元素的数目spinlock_t	lock;        //防止对表的并发访问
};struct sk_buff {union {struct {/* These two members must be first. */struct sk_buff		*next;struct sk_buff		*prev;union {struct net_device	*dev;/* Some protocols might use this space to store information,* while device pointer would be ULL.* UDP receive path is one user.*/unsigned long		dev_scratch;};};struct rb_node		rbnode; /* used in netem, ip4 defrag, and tcp stack */struct list_head	list;};union {struct sock		*sk;int			ip_defrag_offset;};union {ktime_t		tstamp;u64		skb_mstamp_ns; /* earliest departure time */};/** 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);union {struct {unsigned long	_skb_refdst;void		(*destructor)(struct sk_buff *skb);};struct list_head	tcp_tsorted_anchor;};#if defined(COFIG_F_COTRACK) || defined(COFIG_F_COTRACK_MODULE)unsigned long		 _nfct;
#endifunsigned int		len,data_len;__u16			mac_len,hdr_len;/* Following fields are _not_ copied in __copy_skb_header()* ote that queue_mapping is here mostly to fill a hole.*/__u16			queue_mapping;/* if you move cloned around you also must adapt those ctants */
#ifdef __BIG_EDIA_BITFIELD
#define CLOED_MASK	(1 << 7)
#else
#define CLOED_MASK	1
#endif
#define CLOED_OFFSET()		offsetof(struct sk_buff, __cloned_offset)__u8			__cloned_offset[0];__u8			cloned:1,nohdr:1,fclone:2,peeked:1,head_frag:1,pfmemalloc:1;
#ifdef COFIG_SKB_EXTESIOS__u8			active_extensi;
#endif/* fields enclosed in headers_start/headers_end are copied* using a single memcpy() in __copy_skb_header()*//* private: */__u2			headers_start[0];/* public: *//* if you move pkt_type around you also must adapt those ctants */
#ifdef __BIG_EDIA_BITFIELD
#define PKT_TYPE_MAX	(7 << 5)
#else
#define PKT_TYPE_MAX	7
#endif
#define PKT_TYPE_OFFSET()	offsetof(struct sk_buff, __pkt_type_offset)__u8			__pkt_type_offset[0];__u8			pkt_type:;__u8			ignore_df:1;__u8			nf_trace:1;__u8			ip_summed:2;__u8			ooo_okay:1;__u8			l4_hash:1;__u8			sw_hash:1;__u8			wifi_acked_valid:1;__u8			wifi_acked:1;__u8			no_fcs:1;/* Indicates the inner headers are valid in the skbuff. */__u8			encapsulation:1;__u8			encap_hdr_csum:1;__u8			csum_valid:1;#ifdef __BIG_EDIA_BITFIELD
#define PKT_VLA_PRESET_BIT	7
#else
#define PKT_VLA_PRESET_BIT	0
#endif
#define PKT_VLA_PRESET_OFFSET()	offsetof(struct sk_buff, __pkt_vlan_present_offset)__u8			__pkt_vlan_present_offset[0];__u8			vlan_present:1;__u8			csum_complete_sw:1;__u8			csum_level:2;__u8			csum_not_inet:1;__u8			dst_pending_confirm:1;
#ifdef COFIG_IPV6_DISC_ODETYPE__u8			ndisc_nodetype:2;
#endif__u8			ipvs_property:1;__u8			inner_protocol_type:1;__u8			remcsum_offload:1;
#ifdef COFIG_ET_SWITCHDEV__u8			offload_fwd_mark:1;__u8			offload_l_fwd_mark:1;
#endif
#ifdef COFIG_ET_CLS_ACT__u8			tc_skip_classify:1;__u8			tc_at_ingress:1;__u8			tc_redirected:1;__u8			tc_from_ingress:1;
#endif
#ifdef COFIG_TLS_DEVICE__u8			decrypted:1;
#endif#ifdef COFIG_ET_SCHED__u16			tc_index;	/* traffic control index */
#endifunion {__wsum		csum;struct {__u16	csum_start;__u16	csum_offset;};};__u2			priority;int			skb_iif;__u2			hash;__be16			vlan_proto;__u16			vlan_tci;
#if defined(COFIG_ET_RX_BUSY_POLL) || defined(COFIG_XPS)union {unsigned int	napi_id;unsigned int	sender_cpu;};
#endif
#ifdef COFIG_ETWORK_SECMARK__u2		secmark;
#endifunion {__u2		mark;__u2		reserved_tailroom;};union {__be16		inner_protocol;__u8		inner_ipproto;};__u16			inner_transport_header;__u16			inner_network_header;__u16			inner_mac_header;__be16			protocol;__u16			transport_header;__u16			network_header;__u16			mac_header;/* private: */__u2			headers_end[0];/* public: *//* These elements must be at the end, see alloc_skb() for details.  */sk_buff_data_t		tail;sk_buff_data_t		end;unsigned char		*head,*data;unsigned int		truesize;refcount_t		users;#ifdef COFIG_SKB_EXTESIOS/* only useable after checking ->active_extensi != 0 */struct skb_ext		*extensi;
#endif
};

sk_buff中的部分字段:

struct sock *sk:指向拥有此缓冲区的套接字sock数据结构。当数据在本地产生或者正由本地进程接受时,就需要这个指针,因为该数据以及套接字相关信息会由L4以及用户应用程序使用。当缓冲区只是被转发时,该指针就是ULL。

unsigned int len:指缓冲区中数据块的大小。当缓冲区从一个网络分层移往下一个网络分层时,其值会变化 

unsigned int data_len:只计算片段中数据的大小

unsigned int mac_len:mac头大小

atomic_t users:使用sk_buff的的实例数目,当值为0时释放掉此缓冲区

unsigned int truesize:代表此缓冲区总的大小,包括sk_buff结构本身。其值为lensizeof(sk_buff)

unsigned char* head, unsigned char* end, unsigned char* data unsigned* tail:

head和end指向一根陪缓冲区空间的开端和尾端,data和tail指向实际数据的开端和尾端。每一层在head和data之间填上一个协议报头,或在tail和end之间填入新数据。

void (*destructor)(...):缓冲区的析构函数

struct timeval_stamp:用于表示封包何时被接收,由netif_rx函数用net_timestapmp设置。

struct net_device *dev:当收到一个封包,dev表示此接收接口的数据结构的指针。当传输一个封包,dev代表发送封包的设备。

struct net_device *input_dev:表示已被接受的封包来源的设备。

struct net_device *real_dev:代表与虚拟设备所关联的真实设备。

union {...}h、union {...}nh、union {...}mac:h针对L4、nh针对L、,mac针对L2。

struct dst_entry dst:由路由子系统使用

char cb[40]:控制缓冲区,或说是私有信息的存储空间,维护每一层内部使用 

unsigned char cloned:表示另一个sk_buff缓冲区的克隆

__u2 priority:表示整备传输或转发的封包QoS等级。

unsigned short     protocol:L2层表示下一个较高层的协议

unsigned short security:封包的安全级

sk_buff API使用

alloc_skb用于分配sk_buff数据结构以及数据缓冲区
dev_alloc_skb在中断模式下的缓冲区分配,即原子操作的alloc_skb
kfree_skb释放缓冲区
dev_kfree_skb释放缓冲区,调用kfree_skb,当skb->users减为0才释放内存
skb_reserve在缓冲区的头部预留一些空间,允许插入一个报头。此函数只是移动了data和tail指针
skb_put将 tail  指针向数据区的末尾移动,增加了 len 字段的长度。
skb_push将 data 指针向数据区的前端移动,增加 了len 字段的长度。
skb_pull将 data 指针向数据区的末尾移动,减少了len 字段的长度。
skb_clone克隆sk_buff数据结构,双方的clone位置1,user置1,数据缓冲区内的dataref递增
skb_share_check

检查引用计数skb->users,并且当users字段说明该缓冲区是共享时可以克隆该缓冲区        

skb_copy拷贝sk_buff以及数据缓冲区
pskb_copy只拷贝sk_buff

#感谢您对电脑配置推荐网 - 最新i3 i5 i7组装电脑配置单推荐报价格的认可,转载请说明来源于"电脑配置推荐网 - 最新i3 i5 i7组装电脑配置单推荐报价格

本文地址:http://www.dnpztj.cn/shuma/857119.html

相关标签:无
上传时间: 2024-02-10 07:42:40
留言与评论(共有 12 条评论)
本站网友 止咳胶囊
7分钟前 发表
struct dst_entry dst:由路由子系统使用 char cb[40]:控制缓冲区,或说是私有信息的存储空间,维护每一层内部使用  unsigned char cloned:表示另一个sk_buff缓冲区的克隆 __u2 priority:表示整备传输或转发的封包QoS等级
本站网友 胆囊炎的治疗
15分钟前 发表
1;__u8 csum_valid
本站网友 qq会员签到
21分钟前 发表
1;__u8 tc_redirected
本站网友 避孕套正确使用方法
27分钟前 发表
unsigned int len:指缓冲区中数据块的大小
本站网友 中华人民共和国执业医师法
15分钟前 发表
当缓冲区从一个网络分层移往下一个网络分层时,其值会变化  unsigned int data_len:只计算片段中数据的大小 unsigned int mac_len:mac头大小 atomic_t users:使用sk_buff的的实例数目,当值为0时释放掉此缓冲区 unsigned int truesize:代表此缓冲区总的大小,包括sk_buff结构本身
本站网友 搜房博客
5分钟前 发表
2;__u8 ooo_okay
本站网友 桑螵蛸
6分钟前 发表
*//* if you move pkt_type around you also must adapt those ctants */ #ifdef __BIG_EDIA_BITFIELD #define PKT_TYPE_MAX (7 << 5) #else #define PKT_TYPE_MAX 7 #endif #define PKT_TYPE_OFFSET() offsetof(struct sk_buff
本站网友 微信自己退出
5分钟前 发表
有关用户数据的信息,以及协调其工作的其他内部信息
本站网友 平安二手房网
12分钟前 发表
1; #ifdef COFIG_ET_SWITCHDEV__u8 offload_fwd_mark
本站网友 泰安盛世
16分钟前 发表
1;__u8 wifi_acked
本站网友 妇科整形
13分钟前 发表
当传输一个封包,dev代表发送封包的设备