问题
I am working with DPDK version 18.11.8 stable on Linux with an Intel X722 NIC.
My app works fine if I calculate IP and UDP checksums in software but I get a segmentation fault if I calculate in hardware. Here is my code:
local_port_conf.txmode.offloads = local_port_conf.txmode.offloads | DEV_TX_OFFLOAD_IPV4_CKSUM | DEV_TX_OFFLOAD_UDP_CKSUM;
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);
The rte_ipv4_phdr_cksum() call is mysterious, have I understood what to do correctly?
Understandably, the C++ compiler gaves a warning:
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);
^
What is wrong with my code?
回答1:
Following are the steps required for HW checksum offload for IP and UDP in DPDK
- check whether hardware supports HW checksum offload.
- prepare the packet IP and UDP header fields.
- update the default checksum fields. In case of partial UDP checksum support, update with pseudo checksum.
Note: In case of Intel NIC X710 & X722 support partial checksum, hence use code sinpet as
/* during port configuration */
txmode = {
.offloads = DEV_TX_OFFLOAD_IPV4_CKSUM | DEV_TX_OFFLOAD_UDP_CKSUM,
}
/* during device configuration */
if (!(dev_info.tx_offload_capa & DEV_TX_OFFLOAD_UDP_CKSUM) || !(dev_info.tx_offload_capa & DEV_TX_OFFLOAD_IPV4_CKSUM)) {
rte_panic(" offload not supported");
}
/* mb is mbuf packet to transmit */
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);
struct rte_ether_hdr *eth_hdr = rte_pktmbuf_mtod(mb, struct rte_ether_hdr *);
struct ipv4_hdr *p_ipv4_hdr = (struct ipv4_hdr*) ((char *)eth_hdr + sizeof(struct ether_hdr));
struct udp_hdr *p_udp_hdr = (struct udp_hdr *)((unsigned char *) + sizeof(struct ipv4_hdr));
/* update v4 header feilds with version, length, ttl, ip and others */
/* update udp headers */
/* SW check sum */
p_ip_hdr->hdr_checksum = 0;
p_udp_hdr->dgram_cksum = 0;
p_udp_hdr->dgram_cksum = rte_ipv4_udptcp_cksum(p_ip_hdr, p_udp_hdr);
p_ip_hdr->hdr_checksum = rte_ipv4_cksum(p_ip_hdr)
/* HW check sum */
p_ip_hdr->hdr_checksum = 0;
p_udp_hdr->dgram_cksum = rte_ipv4_phdr_cksum(p_ipv4_hdr, ol_flags);
来源:https://stackoverflow.com/questions/62755041/dpdk-hw-offloaded-calculation-of-udp-checksum-not-working