DPDK: HW offloaded calculation of UDP checksum not working

蹲街弑〆低调 提交于 2021-01-25 07:19:26

问题


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

  1. check whether hardware supports HW checksum offload.
  2. prepare the packet IP and UDP header fields.
  3. 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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!