dpdk ipv4分片重组
目录
前言
报文在以太网中传输时,中间会经过各种交换设备,由于物理链路的MTU值大小的限制,当要发送报文数据长度超过MTU,若DF 标记位未设置时,则会进行分片,相应对于最终 目的IP设备会进行重组。(其实,对于传输过程中的某些中间设备如交换机、路由器并不关心报文的实际内容,只是进行转发,而对于某些网关设备由于需要根据L3层以上数据进行业务处理,则会进行重组,处理结束后再分片发出,各设备的接口MTU可能不一样,因此不同探点抓包会有所区别)
以下是IPv4头部结构:
图片来源:https://www.cnblogs.com/craftor/p/3811739.html
分片重组一般涉及头部的 total_len ipid offset flags(以及checksum):
flags:占3bit
RSV | DF | MF
其中DF,表示是否允许分片标记位
MF,用于表示是否还有更多的片,尾片为0,其他为1
Offset:偏移量,占13bit
分片大小frag_size = MTU-sizeof(ip_hdr) 需为8的倍数,故offset实际值需左移3位得到,而填入时则需要除以8
DPDK的分片、重组使用mbuf管理、存储报文,通过零拷贝实现高性能。
1)分片
入口函数:rte_ipv4_fragment_packet
使用indirect mbuf,不存放数据,指向另一块存放实际数据的 direct mbuf
1. 申请direct mbuf :rte_pktmbuf_alloc(pool_direct)
只存放分片 ip头信息
2. 申请indirect mbuf:rte_pktmbuf_alloc(pool_indirect)
3. attach :rte_pktmbuf_attach
将上一步申请的indirect mbuf attach 到报文对应的mbuf(direct),进行buf_addr指针、len等设置
4. 重复上述3步,直到首个mbuf分片完成;
5. 若原始报文存在mbuf链,则重复上述4步,直到所有完成。
2)重组
入口函数为:rte_ipv4_frag_reassemble_packet
主要过程:
1.创建hash表:rte_ip_frag_table_create
key为:(src_ip,dst_ip,ipid)
2.从表中查找,是否已存在表项:
ip_frag_find ---> ip_frag_lookup(此处如果所有片未收到,而表项生存时间已到,则会释放之前收到所有的分片,然后重新复用 它)
3.分片信息存储:ip_frag_process
将每一个分片信息存储在表项中 frags[ ]区域,直到收到所有分片
4.执行重组:ipv4_frag_reassemble
从尾片往前依次重组,在存储分片信息的frags[ ]中查找尾片的前一片,查到后,修改尾片的mbuf信息,然后以buf链形式挂到前一片,同时修改前一片的mbuf,重复 直到第一片; 最后,将首片和后面所有重组好的片链接。因此,重组后是一个多mbuf链的报文(重组过程无需新申请mbuf)