TCP/IP之buff分析m_buff与sk_buff

终于下决心开始看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 */  //用于构成链表
	short		sm_off ;			/* offset in m_data */   //偏移位
	u_int		sm_len ;			/* len of data */  //数据的长度
#ifdef	PCI
	int		sm_use_count ;
#endif
	char		sm_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;   //下一个

	__u32		qlen;    //链表的长度
	spinlock_t	lock;   //锁
};

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

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

	ktime_t			tstamp;

	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.
	 */
	char			cb[48] __aligned(8);

	unsigned long		_skb_dst;
#ifdef CONFIG_XFRM
	struct	sec_path	*sp;
#endif
	//表示当前sk_buff的数据的长度
	unsigned int		len,
				data_len;
	//mac头的长度
	__u16			mac_len,
				hdr_len;
	union {
		__wsum		csum;
		struct {
			__u16	csum_start;
			__u16	csum_offset;
		};
	};
	__u32			priority;
	kmemcheck_bitfield_begin(flags1);
	__u8			local_df:1,
				cloned:1,
				ip_summed:2,
				nohdr:1,
				nfctinfo:3;
	__u8			pkt_type:3,
				fclone:2,
				ipvs_property:1,
				peeked:1,
				nf_trace:1;
	kmemcheck_bitfield_end(flags1);
	__be16			protocol;

	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

	int			skb_iif;
#ifdef CONFIG_NET_SCHED
	__u16			tc_index;	/* traffic control index */
#ifdef CONFIG_NET_CLS_ACT
	__u16			tc_verd;	/* traffic control verdict */
#endif
#endif

	kmemcheck_bitfield_begin(flags2);
	__u16			queue_mapping:16;
#ifdef CONFIG_IPV6_NDISC_NODETYPE
	__u8			ndisc_nodetype:2;
#endif
	kmemcheck_bitfield_end(flags2);

	/* 0/14 bit hole */

#ifdef CONFIG_NET_DMA
	dma_cookie_t		dma_cookie;
#endif
#ifdef CONFIG_NETWORK_SECMARK
	__u32			secmark;
#endif
	union {
		__u32		mark;
		__u32		dropcount;
	};

	__u16			vlan_tci;

	sk_buff_data_t		transport_header;    //传输层头部
	sk_buff_data_t		network_header;   //网络层头部
	sk_buff_data_t		mac_header;    //链路层头部
	/* 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;    //整个sk_buff的大小,包括sk_buff结构和头部以及数据
	atomic_t		users;   //引用计数
};

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


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

你可能感兴趣的:(TCP/IP之buff分析m_buff与sk_buff)