TCP IP详解卷2之mbuf宏与函数

mbuf的介绍在上一篇文章中已经介绍了.

查看介绍请移步:http://blog.csdn.net/shinichr/article/details/23044999

mbuf全称即memory buffer,即存储器缓存,在内核中属于全局支持的范畴。这里有超过两打的宏和函数来处理mbuf。

函数:

1:m_get 函数,分配mbuf的函数,是宏MGET的展开

1.1

插口层请求分配一个mbuf来存储sendto系统调用的目标地址时,nowait指定M_WAIT,因此会在这里阻塞,如果是请求分配一个mbuf来保存接收的帧时,nowait需指向M_DONTWAIT,便是不阻塞。


2:m_pullup函数,用来保证指定数目的字节(协议首部大小等)在链表的第一个buf中紧挨着存放。即这些字节被复制到一个新的mbuf并紧挨着存放。这里需要介绍下该函数用到的宏mtod和dtom,还有函数m_devget。

当接收到一个以太网帧时,调用m_devget来创建一个mbuf链表,并把设备中的帧复制进去,根据帧的长度会产生四种链表

2-14的左边用于数据的长度在0-84字节之间的情况,右边的是85-100的情况


图2-15是数据在101-207字节之间的情况。这里有两个mbuf,前100字节存放在第一个mbuf中(有分组首部),剩下的在第二个。

数据>=208字节时,就要用到cluster了。

m_pullup使用总结:

1:大多数设备驱动程序不把一个IP数据报的第一部分的分割到几个mbuf中,假设协议首部都紧挨着存放,则在每个协议(ICMP,IGMP,TCP,UDP)中调用m_pullup的可能性小,如果调用它,通常是因为数据报太小。


      2::对于接收到的IP分片,当IP数据报被放在一个cluster中时,调用m'_pullup,几乎对于接受到的每一个分片都要调用,因为大多数分片的长度大于208字节。

这里因为指向IP首部的指针(即指向cluster起始的pointer)不能转换成指向mbuf的指针(因为m_data指向一个cluster时不能使用dtom,因为没有从cluster指向mbuf的指针,IP分片不能把链指针存储在cluster 中)

3:只要TCP报文段不被IP分片,接收到一个报文段,不论是否失序,都不需要调用m_pullup

3:宏mtod和dtom。

#define mtod(m,t)    ((t)((m)->m_data))

#define dtom(x)   ((struct mbuf *)((int)(x) & ~(MSIZE-1)))

mtod返回指向一个mbuf数据的指针,并把指针声明为指定类型

dtom取得一个存放在mbuf任意位置的数据的指针,并返回这个mbuf结构本身的一个指针。这里MSIZE是128(10000000),dtom仅仅是为了清除参数中指针的低位来获取mbuf的起始位置。


m_copy函数:

cluster的好处就是当有大量数据时可以减少mbuf,还有就是可以多个mbuf共享一个cluster,共享的cluster避免了内核将数据从一个mbuf复制到另一个mbuf中,这里用到了引用计数,当另一个buf指向这个cluster时,相应的计数+1,当最后计数变成0时,才清除它。


宏:

1:MGET宏

                1.2

1.3

MGET调用的MALLOC是内核宏,它是通用存储器分配器进行的。数组mbtypes把mbuf的MT_xxx值转换成M_xxx(如图1.3)。

MBUFLOCK(mbuf锁,保护函数和宏不被中断) 做的是全局量mbstat的跟踪统计。当分配失败时,调用m_retry函数。


1.4

m_retry调用的第一个函数是m_reclaim,这里不对该函数做细致分析,调用m_reclaim后,可能 会有更多的存储器,所以再次调用了MGET

注意这里如果不#define m_retry(i,t) (struct mbuf *)0,把m_retry定义为一个空指针,再次进入MGET后如果分配失败又会调用m_retry,就可能会出现无休止的循环。当然这个定义在MGET展开之后就取消了。


书中的介绍:



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值