DPDK自定义UDP发送端无法被普通C/C++ UDP接收端接收问题排查
排查DPDK UDP发送端向普通UDP接收端发送数据无响应问题
已知场景:
- 场景1:普通C/C++ UDP跨Linux主机收发功能正常
- 场景2:DPDK UDP发送端显示发送成功,Wireshark可捕获到数据包,但普通UDP接收端无响应
发送端(DPDK)可能的问题点
- 校验和未正确计算:DPDK默认不会自动计算IP/UDP校验和,若代码未手动生成校验和,普通接收端内核会直接丢弃校验和错误的包。需检查代码是否调用
rte_ipv4_cksum、rte_ipv4_udp_cksum等函数生成正确校验和,同时可通过Wireshark查看IP/UDP头部的校验和是否标记为「错误」。 - 网络头部字段错误:
- 检查IP头部的
version(必须为4)、ihl(IP头部长度,通常为5即20字节)、tot_len(IP总长度,需包含IP头部+UDP头部+数据)、protocol(UDP需设为17)、ttl(值需足够大,避免中途被路由丢弃)是否正确填充。 - 检查UDP头部的
source、dest端口是否与接收端监听端口匹配,len(UDP总长度)是否正确。 - 确认源IP是否为接收端可正常路由的地址(需与DPDK绑定的网卡IP一致),避免接收端内核判定为非法包丢弃。
- 检查IP头部的
- 以太网头部错误:若为同网段通信,DPDK发送的包目的MAC需为接收端网卡的MAC;跨网段则需为网关MAC。若MAC地址错误,即使Wireshark(如镜像端口)能捕获,接收端网卡会直接丢弃非自身MAC的包。
- 数据包长度不合法:若发送的数据包总长度(以太网头部+IP+UDP+数据)小于以太网最小帧长(64字节),部分网卡会直接丢弃这类包,需检查代码是否填充了足够的padding或确保包长合规。
接收端(普通UDP)可能的问题点
- 防火墙/iptables拦截:检查接收端的防火墙规则,确认是否允许DPDK发送端的IP/端口访问。可执行
iptables -L -n或firewall-cmd --list-all查看规则,对比场景1的发送端IP是否在允许列表,而DPDK发送端IP被拦截。 - 接收端绑定范围过窄:若接收端代码中
bind调用仅绑定了场景1发送端的IP(而非INADDR_ANY),则无法接收来自DPDK发送端IP的数据包。需检查绑定的sin_addr.s_addr是否设为htonl(INADDR_ANY)。 - 内核ARP缓存异常:接收端内核若未正确缓存DPDK发送端IP对应的MAC地址,可能无法将数据包递交给上层应用。可执行
arp -n查看ARP表,确认是否存在DPDK发送端IP的条目,若缺失可手动执行arp -s添加。 - 网卡接收过滤规则:部分网卡默认会过滤非自身MAC的数据包,即使Wireshark因开启混杂模式能捕获,内核仍会丢弃。可尝试在接收端执行
ip link set dev <网卡名> promisc on开启混杂模式后测试。
抓包验证关键点
通过Wireshark捕获的数据包,重点确认以下字段:
- 以太网层:目的MAC是否为接收端网卡/网关的MAC
- IP层:源IP、目的IP、TTL、校验和、协议字段是否正确
- UDP层:源端口、目的端口、校验和、长度是否正确
- 包总长度是否≥64字节
内容的提问来源于stack exchange,提问作者Ragul V
相关产品推荐
相关产品推荐

