dpdk ipv4分片重组

目录

DPDK frag & reassembly 介绍

 1)分片

2)重组


前言

报文在以太网中传输时,中间会经过各种交换设备,由于物理链路的MTU值大小的限制,当要发送报文数据长度超过MTU,若DF 标记位未设置时,则会进行分片,相应对于最终 目的IP设备会进行重组。(其实,对于传输过程中的某些中间设备如交换机、路由器并不关心报文的实际内容,只是进行转发,而对于某些网关设备由于需要根据L3层以上数据进行业务处理,则会进行重组,处理结束后再分片发出,各设备的接口MTU可能不一样,因此不同探点抓包会有所区别)

以下是IPv4头部结构:

dpdk 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)