美文网首页
mbuf : 存储器缓存

mbuf : 存储器缓存

作者: 食梦狸猫 | 来源:发表于2019-05-30 16:48 被阅读0次

    mbuf的主要用途就是保存在进程和网络接口之间相互传递的用户数据,以及源与目标地址,插口选项等等。根据在成员m_flags中填写不同标志,有4种不同的mbuf:

    1. 若m_flags为0,mbuf只包含数据。 3.08.04.png
    2. 若m_flags为M_PKTHDR,则这是一个分组首部,描述一个分组数据的第一个mbuf。


      3.09.16.png
    3. 若m_flags为M_EXT,则这是不包含分组首部,但包含超过208字节的数据,这用到了一个叫“簇”的外部缓存。 3.21.14.png

    4 最后一类mbuf包含一个分组首部,并包含超过208字节的数据。同时设置了标志M_PKTHDR和M_EXT。


    3.24.36.png

    另外有几点:

    • mbuf结构的大小为128字节,之后两个mbuf结构中有m_ext,其m_ext的空间是88字节。

    • 因为有些协议(如UDP)允许零长记录,那就就可以有m_len=0的数据缓存。

    • mbuf成员中的m_data指向的是相应缓存的开始。

    • 带有簇的mbuf总是包含缓存的起始地址m_ext.ext_buf和它的大小m_ext.ext_size

    • 指针m_next把mbuf链接在一起,把一个分组形成一条mbuf链表。

    • 指针m_nextpkt把多个分组链接成一个mbuf链表队列。

    3.36.00.png

    代码介绍:

    3.44.57.png 有一个全局变量为mbstat,用于mbuf的统计信息,其中所维护的各种统计,如图: 3.49.16.png

    可通过netstat -m检测。(内核在一个全局变量中保持对某些统计信息的跟踪,当内核在运行时,一个进程对这些信息进行检查)

    m_flags的独立的值:


    3.55.28.png

    m_devget函数

    当接收到一个以太网帧时,设备驱动程序调用m_devget来创建一个mbuf链表,并把所接收到的帧复制到这个链表中。根据所接收到的帧的长度不同,导致以下4种不同的mbuf链表。


    4.06.15.png 4.06.23.png 4.06.28.png
    • mtod返回一个指回mbuf数据的指针,并把指针声名为指定类型。

    • dtom取得一个存放在一个mbuf中任意位置的数据的指针,并返回这个mbuf结构本身的一个指针。(如果m_data指向一个簇时不能使用宏dtom,因为没有从簇指回mbuf的指针)

    m_pullup函数

    m_pullup函数有两个目的:

    • 当一个协议发现第一个mbuf的数据量m_len小于协议首部的最小长度(IP 20,UDP 8,TCP 20),m_pullup基于假定协议首部的剩余部分存在链表中的下一个mbuf,然后m——pullup重新安排mbuf链表,使得前N字节的数据被连续放在链表的第一个mbuf中。(N<=MHLEN:100)m_pullup有两个原因会失败:(1)如果它需要其他mbuf并且调用MGET失败,(2)如果整个mbuf链表中的数据总数少于要求的字节数
    • m_pullup涉及到IP和TCP的重组。IP分片算法把各分片都存在一个双向链表中,并且用IP首部中的源和目标IP地址来存放向前与向后的链表指针。但若IP首部在一个簇中,链表指针也就在一个簇中,当遍历链表时,指向IP首部的指针不能转换成指向mbuf的指针。所以当接收到一个分片时,若分片在一个簇中,IP分片例程总是调用m_pullup。重组TCP报文段使用的是不同的技术而不是m_pullup,是因为m_pullup数据复制开销较大。

    只有头指针的mbuf链表


    4.41.38.png

    有头尾指针的链表


    4.43.18.png

    使用簇的好处在于:

    • 在要求包含大量数据的时候能减少mbuf的数目。

    • 在多个mbuf间可以共享一个簇。避免了内核将数据从一个mbuf复制到另一个mbuf中。

    相关文章

      网友评论

          本文标题:mbuf : 存储器缓存

          本文链接:https://www.haomeiwen.com/subject/cncvtctx.html