sk
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组装电脑配置单推荐报价格
推荐阅读
留言与评论(共有 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代表发送封包的设备 |