DPDK 可以通过检查分片偏移和总长度来判断该分片是否能承载原报文的全部数据。具体的实现可以参考如下代码:
/* 检查分片是否能承载原报文 */
int check_fragment(struct rte_ipv4_hdr *ipv4_hdr, uint16_t l2_len)
{
uint16_t frag_offset = rte_be_to_cpu_16(ipv4_hdr->fragment_offset);
uint16_t total_length = rte_be_to_cpu_16(ipv4_hdr->total_length);
if (frag_offset == 0 && total_length <= RTE_IPV4_MAX_PACKET_LEN - l2_len) {
/* 非分片包,且总长度小于等于 MTU - L2 头部长度 */
return 1;
} else if (frag_offset != 0 && (frag_offset + total_length) <= RTE_IPV4_MAX_PACKET_LEN - l2_len) {
/* 分片包,且偏移加总长度小于等于 MTU - L2 头部长度 */
return 1;
}
/* 分片无法承载原报文 */
return 0;
}
首先获取到 IP 首部中的 fragment_offset 和 total_length 字段,并将它们转换为主机字节序。然后根据以下两种情况判断分片是否能承载原报文:
- 如果 fragment_offset 等于 0,表示该 IP 数据包是非分片包,此时只需要判断总长度是否小于等于 MTU 减去 L2 头部长度即可。
- 如果 fragment_offset 不等于 0,表示该 IP 数据包是分片包,此时需要判断偏移加总长度是否小于等于 MTU 减去 L2 头部长度。
如果分片能够承载原报文,则返回 1,否则返回 0。