TCP/IP之buff分析m_buff与sk_buff

时间:2021-12-28 11:03:01

终于下决心开始看TCP/IP部分的源码了,从《TCI/IP详解,卷二》作为入口。。。

首先来分析一下存取数据的buff,

在书上,强调的是mbuf,不过好像现在新版本的内核改动比较大,更重要的还是sk_buff,不过还是先来看看mbuff吧,

文件在:Driver/net/skfp/h/mbuf.h 

struct s_mbuf {
struct s_mbuf*sm_next ;/* low level linked list */ //用于构成链表
shortsm_off ;/* offset in m_data */ //偏移位
u_intsm_len ;/* len of data */ //数据的长度
#ifdefPCI
intsm_use_count ;
#endif
charsm_data[M_SIZE] ; //用于实际的数据存储
} ;

typedef struct s_mbuf SMbuf ;

定义其实很简单了,与书上差异很大。。。不过重点还是来看看sk_buff的定义吧,首先是head的定义,其实他是一个占位节点,用于将sk_buff连接起来:

//sk_buff的头部的定义,其实是用于组织成一个链表
struct sk_buff_head {
/* These two members must be first. */
struct sk_buff*next; //上一个
struct sk_buff*prev; //下一个

__u32qlen; //链表的长度
spinlock_tlock; //锁
};

用两个指针构成链表,接下来来看看sk_buff的定义:

struct sk_buff {
/* These two members must be first. */
struct sk_buff*next; //指向上一个buff结构
struct sk_buff*prev; //指向下一个buff结构

ktime_ttstamp;

struct sock*sk; //属于哪一个sock,主要是在传输层中用到
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.
*/
charcb[48] __aligned(8);

unsigned long_skb_dst;
#ifdef CONFIG_XFRM
structsec_path*sp;
#endif
//表示当前sk_buff的数据的长度
unsigned intlen,
data_len;
//mac头的长度
__u16mac_len,
hdr_len;
union {
__wsumcsum;
struct {
__u16csum_start;
__u16csum_offset;
};
};
__u32priority;
kmemcheck_bitfield_begin(flags1);
__u8local_df:1,
cloned:1,
ip_summed:2,
nohdr:1,
nfctinfo:3;
__u8pkt_type:3,
fclone:2,
ipvs_property:1,
peeked:1,
nf_trace:1;
kmemcheck_bitfield_end(flags1);
__be16protocol;

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;
#endif
#ifdef CONFIG_BRIDGE_NETFILTER
struct nf_bridge_info*nf_bridge;
#endif

intskb_iif;
#ifdef CONFIG_NET_SCHED
__u16tc_index;/* traffic control index */
#ifdef CONFIG_NET_CLS_ACT
__u16tc_verd;/* traffic control verdict */
#endif
#endif

kmemcheck_bitfield_begin(flags2);
__u16queue_mapping:16;
#ifdef CONFIG_IPV6_NDISC_NODETYPE
__u8ndisc_nodetype:2;
#endif
kmemcheck_bitfield_end(flags2);

/* 0/14 bit hole */

#ifdef CONFIG_NET_DMA
dma_cookie_tdma_cookie;
#endif
#ifdef CONFIG_NETWORK_SECMARK
__u32secmark;
#endif
union {
__u32mark;
__u32dropcount;
};

__u16vlan_tci;

sk_buff_data_ttransport_header; //传输层头部
sk_buff_data_tnetwork_header; //网络层头部
sk_buff_data_tmac_header; //链路层头部
/* These elements must be at the end, see alloc_skb() for details. */
sk_buff_data_ttail; //指向数据的尾部
sk_buff_data_tend; //指向分配的内存的微薄
unsigned char*head, //分配的内存的起始位置
*data; //指向当前数据的起始位置
unsigned inttruesize; //整个sk_buff的大小,包括sk_buff结构和头部以及数据
atomic_tusers; //引用计数
};

在内核中,用sk_buff来表示一个网络数据包,它里面包含了从链路层到传输层的数据,具体的那些字段的意思再注释中已经写了出来。。。


好了第一篇,还是轻松一些好,就介绍一下buff的定义