设为首页 加入收藏

TOP

TCP/IP详解2 学习笔记---mbuf(二)
2014-11-23 17:31:52 来源: 作者: 【 】 浏览:219
Tags:TCP/IP 详解 学习 笔记 --- mbuf
-attempt to allocate an mbuf.


*/


struct mbuf *


m_retry(i, t)


int i, t;


{


register struct mbuf *m;


调用协议的注册函数释放内存


m_reclaim();


把m_retrydefine成NULL这样就直接返回NULL了,但这里怎么保证这个MGET中m_retry返回的是NULL,而上一个返回的是这个函数???????#define在预编译期间就做替换了。


这个的关键就是MGET是一个宏,而不是函数。


#define m_retry(i, t) (struct mbuf *)0


MGET(m, i, t);


#undef m_retry


return (m);


}




这个函数循环调用协议的drain函数分配内存



m_reclaim()


{


register struct domain *dp;


register struct protosw *pr;


提升处理器的优先级不被网络处理中断


int s = splimp();




for (dp = domains; dp; dp = dp->dom_next)


for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++)


if (pr->pr_drain)


(*pr->pr_drain)();


恢复处理器的优先级


splx(s);


mbstat.m_drain++;


}





分配一个分组头部的mbuf,对m_data和m_flags进行初始化


#define MGETHDR(m, how, type) { \


MALLOC((m), struct mbuf *, MSIZE, mbtypes[type], (how)); \


if (m) { \


(m)->m_type = (type); \


MBUFLOCK(mbstat.m_mtypes[type]++;) \


(m)->m_next = (struct mbuf *)NULL; \


(m)->m_nextpkt = (struct mbuf *)NULL; \


(m)->m_data = (m)->m_pktdat; \


(m)->m_flags = M_PKTHDR; \


} else \


(m) = m_retryhdr((how), (type)); \


}




587 /*


588 * Routine to copy from device local memory into mbufs.


589 */


590 struct mbuf *


591 m_devget(buf, totlen, off0, ifp, copy)


592 char *buf;


593 int totlen, off0;


594 struct ifnet *ifp;


595 void (*copy)();


这个函数是对MGET和MGETHDR的封装,一般由设备驱动程序调用,分配mbuf空间。


1,如果数据长度《84,则在数据(IP数据包)的前面保留16个字节。为输出时添加14字节的MAC包头准备。(一个包含pak_hdr的mbuf最多放100字节的数据)


2,如果数据》85 && 数据《100则不额外保留这16字节的数据


3,如果数据》100,则分配一个cluster进行数据的存放。


可见m_devget根据数据的长度,分配合适的mbuf




4.2mbuf到mbuf中data的转换


定义了两个宏



56 * mtod(m,t) - convert mbuf pointer to data pointer of correct type


57 * dtom(x) - convert data pointer within mbuf to mbuf pointer (XXX)



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


MSIZE == 128 这个基于mbuf是128字节对齐


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


dotm对cluster的数据有问题,不能正常转换到mbuf,所以需要下面的函数




/*


* Rearange an mbuf chain so that len bytes are contiguous


* and in the data area of an mbuf (so that mtod and dtom


* will work for a structure of size len). Returns the resulting


* mbuf chain on success, frees it and returns null on failure.


* If there is room, it will add up to max_protohdr-len extra bytes to the


* contiguous region in an attempt to avoid being called next time.


*/




这个函数从mbuf链表中取出len字节的数据放在第一个mbuf中,使dtom能正确运行


struct mbuf *


m_pullup(n, len)


register struct mbuf *n;


int len;


{


register struct mbuf *m;


register int count;


int space;




/*


* If first mbuf has no cluster, and has room for len bytes


* without shifting current data, pullup into it,


* otherwise allocate a new mbuf to prepend to the chain.


*/


if ((n->m_flags & M_EXT) == 0 &&


n->m_data + len < &n->m_dat[MLEN] && n->m_next) {


if (n->m_len >= len)


return (n);


m = n;


n = n->m_next;


len -= m->m_len;


} else {


if (len > MHLEN)


goto bad;


MGET(m, M_DONTWAIT, n->m_type);


if (m == 0)


goto bad;


m->m_len = 0;


if (n->m_flags & M_PKTHDR) {


M_COPY_PKTHDR(m, n);


n->m_flags &= ~M_PKTHDR;


}


}


space = &m->m_dat[MLEN] - (m->m_data + m->m_len);


do {


count = min(min(max(len, max_protohdr), space), n->m_len);


bcopy(mtod(n, caddr_t), mtod(m, caddr_t) + m->m_len,


(unsigned)count);


len -= count;


m->m_len += count;


n->m_len -= count;


space -= count;


if (n->m_len)


n->m_data += count;


else


n = m_free(n);


} while (len > 0 && n);


if (len > 0) {


(void) m_free(m);


g

首页 上一页 1 2 3 下一页 尾页 2/3/3
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇TCP/IP详解2 学习笔记2---ifne.. 下一篇Linux下的多线程编程

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: