我正在使用 Intel X722 NIC 在 Linux 上使用 DPDK 版本 18.11.8 稳定版本。
如果我在软件中计算 IP 和 UDP 校验和,我的应用程序工作正常,但如果我在硬件中计算,则会出现分段错误。这是我的代码:
local_port_conf.txmode.offloads = local_port_conf.txmode.offloads | DEV_TX_OFFLOAD_IPV4_CKSUM | DEV_TX_OFFLOAD_UDP_CKSUM;
Run Code Online (Sandbox Code Playgroud)
mb->ol_flags |= PKT_TX_IPV4 | PKT_TX_IP_CKSUM | PKT_TX_UDP_CKSUM;
mb->l2_len = sizeof(struct ether_hdr);
mb->l3_len = sizeof(struct ipv4_hdr);
mb->l4_len = sizeof(struct udp_hdr);
p_ip_hdr->hdr_checksum = 0;
p_udp_hdr->dgram_cksum = rte_ipv4_phdr_cksum((const ipv4_hdr*)(mb->l3_len), mb->ol_flags);
Run Code Online (Sandbox Code Playgroud)
rte_ipv4_phdr_cksum() 调用很神秘,我是否理解正确的做法?
可以理解的是,C++编译器给出了警告:
warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
p_udp_hdr->dgram_cksum = rte_ipv4_phdr_cksum((const ipv4_hdr*)(ptMbuf->l3_len), ptMbuf->ol_flags);
^
Run Code Online (Sandbox Code Playgroud)
我的代码有什么问题吗?
以下是 DPDK 中 IP 和 UDP 硬件校验和卸载所需的步骤:
\n注意:Intel NIC X553、X710 和 X722(可能还有其他)仅支持部分 UDP 校验和卸载,
\n[根据 @maxschlepzig 评论中的查询进行编辑]是否有支持完整 UDP 校验和卸载的 NIC?如果是,是否有某种 DPDK 方法来检查是否完全支持?
\n[答] 是的,有一个简单的方法可以检查。在NIC 功能中,表 1.1 突出显示了校验和卸载是否可用、部分或不存在。但真正的问题是检查NIC 特定固件的发行说明,因为硬件 ASIC 或固定功能已启用或禁用。
\n这需要这样的片段:
\n/* during port configuration */\ntxmode = {\n .offloads = DEV_TX_OFFLOAD_IPV4_CKSUM | DEV_TX_OFFLOAD_UDP_CKSUM\n};\n\n/* during device configuration */\nif (!(dev_info.tx_offload_capa & DEV_TX_OFFLOAD_UDP_CKSUM) || !(dev_info.tx_offload_capa & DEV_TX_OFFLOAD_IPV4_CKSUM)) {\n rte_panic(" offload not supported");\n}\n\n/* mb is mbuf packet to transmit */\nmb->ol_flags = PKT_TX_IPV4 | PKT_TX_IP_CKSUM | PKT_TX_UDP_CKSUM;\nmb->l2_len = sizeof(struct ether_hdr);\nmb->l3_len = sizeof(struct ipv4_hdr); \n\nstruct rte_ether_hdr *eth_hdr = rte_pktmbuf_mtod(mb, struct rte_ether_hdr *);\nstruct ipv4_hdr *p_ipv4_hdr = (struct ipv4_hdr*) ((char *)eth_hdr + sizeof(struct ether_hdr));\nstruct udp_hdr *p_udp_hdr = (struct udp_hdr *)((unsigned char *) + sizeof(struct ipv4_hdr));\n\n/* update v4 header fields with version, length, ttl, ip and others */\n/* update udp headers */\n\n/* in case hardware offload is unavailable */ \np_udp_hdr->dgram_cksum = rte_ipv4_udptcp_cksum(p_ip_hdr, p_udp_hdr);\np_ip_hdr->hdr_checksum = rte_ipv4_cksum(p_ip_hdr)\n\n/* otherwise, equivalent offloaded checksum computation */ \np_udp_hdr->dgram_cksum = rte_ipv4_phdr_cksum(p_ipv4_hdr, ol_flags);\np_ip_hdr->hdr_checksum = 0; \nRun Code Online (Sandbox Code Playgroud)\n[EDIT-2] 感谢 @maxschlepzig 指出l4_lenUDP 校验和卸载不需要。这是仅TX 的 TCP 段卸载l4_len所需的正确信息。
根据 @DavidA 的实时调试,段错误原因被确定为不正确的使用,并且在注释中,代码更新为
\n@VipinVarghese Thanks so I now have: struct ipv4_hdr* p_ipv4_hdr = rte_pktmbuf_mtod(mb, struct ipv4_hdr *) + mb->l2_len; p_udp_hdr->dgram_cksum = rte_ipv4_phdr_cksum(p_ipv4_hdr, mb->ol_flags); but the udp checksum is still incorrect.\n\nHi David, I believe you have not st the right values. Will update in couple of hours \xe2\x80\x93 Vipin Varghese\nRun Code Online (Sandbox Code Playgroud)\n与 David 分享的行动项目之一是更新伪代码,因为真正的问题围绕着DPDk: HW offloaded calculation of UDP checksum not working。感谢 @maxschlepzig 解释了这一切,因为许多人很容易错过注释和实时调试。
| 归档时间: |
|
| 查看次数: |
2299 次 |
| 最近记录: |