赞
踩
linux内核是模块化的,允许你选择要包含什么以及省略什么。因此,只有当内核编译位支持特定功能时候,如防火墙或者Qos,某些字段才会包含在sk_buff数据结构中。
unsigned long nfmark
__u32 nfcache
__u32 nfctinfo
struct nf_conntrack *nfct
unsigned int nfdebug
struct nf_bridge_info *nf_bridge
这些参数由netfileter 使用,更明确的讲就是由内核选项Device Drivers->Networking support->Networkiong options ->Networking packet filtering
以及两个子选项,Network packet filtering debugging和Bridged IP/ARP packets filteriing 所用。
uinon {...} private
这个联合由HIPPI(High Performance Parallel interface 高性能并行接口)使用,
先关联的内核选项位Device Drivers->Networking support->Networkong device support
__u32 tc_index
__u32 tc_verd
__u32 tc_classid
这些参数由流量控制功能使用,更明确的讲就是指由内核选项Device Drivers->Networking support->Networking options->Qos and /or fair queueing 以及其他子选项,Packet classifier API使用。
struct sec_path *sp
由IPsec协议组使用,以及记录转换信息。
管理函数
内核通常提供许多很短,很简单的函数,用以操作sk_buff元素或者元素列表,在图2-4的协助下,将描述其中最重要的几个函数。
首先,我们来看用于分配释放缓冲区的函数,然后是用于在帧头部或者预留空间的操作指针函数。skb->data
如果你查看一下include/linux/skbuff.h和Net/core/skbuff.c文件,就会注意到几乎所有的函数都由两个版本,名称类似do_something和__do_something 通常来讲,第一个是包裹函数,增加了额外的合理性检查或者在调用第二个函数前后加入上锁机制,内部所用的__do_somethng 形式通常不会被直接调用,违反规则时通常写得很差的函数,而最终都会被修正。
sk->data
sk->len
sk->tail
skb_put. skb_push, skb_pull skb_reserve
内存分配:alloc_skb和dev_alloc_skb
定义在net/core/skbuff.c 中的alloc_skb 是分配缓冲区的主要函数,我们已经知道,数据缓冲区的报头sk_buff 数据结构是两种不同的实力,也就说是,建立一个缓冲区会涉及到两次分配内存,一个是分配缓冲区,一个是分配sk_buff结构。
然后嗲用kmalloc 以取得一个数据缓冲区,其代码如下
skb = kmem_cache_alloc(skbuff_head_cache, gfp_mask & &__GFP_DMA)
size = SKB_DATA_ALLIGN(size);
data = kmalloc();size + sizeof(struct skb_shared_info), gfp_mask
调用kmalloc之前,size参数被SKB_DATA_ALIGN宏进行调整以强制对齐,返回之前,此函数会对结构中的一些参数做初始化,产生的最后结果如图2-5所示。
在图2-5 右侧内存区块的低端,可以发现引入了填充区域以强制对齐,skb_shared_info块主要用于处理一些IP片段,本章稍后予以描述,图左侧的字段已经先前说明了。
填充区域 size SKB_DATA_ALIGN(size)
struct skb_shared_info
len = 0
head
data
tail
end
dev_alloc_skb 是由设备驱动程序使用的缓冲区分配函数,而且应该是在中断模式中执行的,此函数是一个包裹alloc_skb的函数,为了优化的原因在申请大大小之上再加16个字节,而且因为此函数是由中断事件处理函数调用的,所以会要求原子操作
GFP_ATOMIC
static inline struct sk_buff *dev_alloc_skb(unsigned int length)
{
return ++dev_alloc_skb(length, GFP_ATOMIC);
}
static inline struct sk_buff *__dev_alloc_skb(unsigned int length, int gfp_mask)
{
struct sk_buff *skb = alloc_skb(length + 16, gfp_mask)
if (likyly(skb))
skb_reserve(skb, 16);
return skb;
}
当没有体系结构说明定义时,__dev_alloc_skb 的定义就是默认的。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。