0x01 缘由
在安全行业,对数据包的处理是一个必须的过程,好的数据包存储结构可以减少对内存的拷贝,发现在我们产品开发过程中对数据包结构的存储和处理比较简单,当然效率可能没追求极致。本着学习和开阔视野的心,再次学习DPDK Mbuf结构。
0x02 介绍
对于数据报文的存储(包括协议头),可以考虑如下两种方式:
1、将网络帧元数据(metadata)和帧本身存放在固定大小的同一段缓存中;
用单独的内存缓存结构哦存储元数据,后面跟着固定大小的内存区域去保存报文数据;
2、将元数据和网络帧分开存放在两段缓存里;
两种方式的优缺点:
第一种 对缓存的申请及释放均只需一条指令,缺点是因为缓存长度固定而网络帧大小不一,大部分帧只能使用填0(padding)的方式填满整个缓存,较为耗费内存空间。
第二种 帧数据的大小可以任意,同时对元数据和网络帧的缓存可以分开申请及释放;缺点是低效,因为无法保证数据存在一个Cache Line中,可以造成HIT Miss;
以上翻译《prog_guide-17.05.pdf》
0x03 深入理解Mbuf
为了高效访问数据,DPDK将内存封装在Mbuf(struct rte_mbuf)结构体内。Mbuf主要用来封装网络帧缓存,也可以用来封装通用控制信息缓存(缓存类型需使用CTRL_MBUF_FLAG来指定)。Mbuf结构报头经过精心设计,原先仅占1个Cache Line。随着Mbuf头部携带的信息越来越多,现在Mbuf头部已经调整成两个Cache Line,原则上讲基础性、频繁访问的数据放在一个Cache Line字节,而将功能性扩展的数据放在第二个Cache Line字节。Mbuf报头包含包处理所需的所有数据,对于单个Mbuf存放不下的巨型帧(Jumbo Frame),Mbuf还有指向下一个Mbuf结构的指针来形成帧链表结构。所有应用都应使用Mbuf结构来传输网络帧。
为了保持包处理的效率,DPDK采用0x02中的第一种方式。网络帧元数据的一部分内容由DPDK网卡驱动写入。这些内容包括VLAN标签、RSS哈希值、网络入口端口号以及巨型帧所占的Mbuf个数等。对于巨型帧,网络帧元数据仅出现在第一个帧的Mbuf结构中,其他的帧该信息为空。
Mbuf结构如下:
0x04 API
创建:struct rte_mbuf * rte_pktmbuf_alloc()从rte_mempool获取一个mbuf
获得帧数据长度:rte_pktmbuf_data_len(m)
获得指向数据的指针:rte_pktmbuf_data_len(m)
......
0x05 总结
虽然有些东西只能通过sample去学习,但是慢慢熟悉为今后产品事件中打下基础。