Dear DPDK exports. I am Ick-Sung Choi living in South Korea. Thank you very much for your contributions. I studied a lot from your source codes. However, actually I have a lot of codes/algorithms that I can't understand. The codes seems to be incomplete, but it works in my test case. If I take an example, the worker assignment method using & (not %) in load balancing was not fixed yet. There are a lot of similar codes such as in rte_distributor_process() in distributor. I have a few questions about reading/writing/modifying packet header. I know it is complex. I will really appreciate if I can be given answer and some example codes. Question #1) I would like to know how can I read/write/modify TCP/UDP/ICMP/IGMP/... headers from packet in rte_mbuf. I will really appreciate if I can be given an example code. I guess it would be somewhat complex. Question #2) The IP checksum does not include 6 the ptr. 6 th ptr (ptr16[5]) is missing in the example code. Is it right? ( ip_cksum += ptr16[5]; in the following code.) The following code reads headers and write modified headers (used in DPDK source codes). void swap_header_in_a_packet ( struct rte_mbuf *buf ) { struct ether_hdr *eth_hdr; struct ether_addr eth_src_addr, eth_dest_addr ; struct ipv4_hdr *ip_hdr; uint32_t ip_src_addr, ip_dest_addr ; // Read Eternet header. eth_hdr = rte_pktmbuf_mtod( buf, struct ether_hdr *); // Extract MAC addresses. ether_addr_copy(&eth_hdr->s_addr, &eth_src_addr ); ether_addr_copy(&eth_hdr->d_addr, &eth_dest_addr ); // Swap MAC addresses. ether_addr_copy(&eth_src_addr, &eth_hdr->d_addr); ether_addr_copy(&eth_dest_addr, &eth_hdr->s_addr); // Swap IP addresses. ip_hdr = (struct ipv4_hdr *)(rte_pktmbuf_mtod( buf, unsigned char *) + sizeof(struct ether_hdr)); ip_src_addr = (uint32_t) ip_hdr->src_addr; // source IP address. ip_dest_addr = (uint32_t) ip_hdr->dst_addr; // destination IP address. ip_hdr->src_addr = (uint32_t) ip_dest_addr ; ip_hdr->dst_addr = (uint32_t) ip_src_addr ; setup_simple_example_pkt_ip_headers( (char *) ip_hdr ); copy_buf_to_pkt(&eth_hdr, sizeof(eth_hdr), buf, 0); copy_buf_to_pkt(&ip_hdr, sizeof(ip_hdr), buf, sizeof(struct ether_hdr)); } static void setup_simple_example_pkt_ip_headers( char *ip_hdr ) { uint16_t *ptr16; uint32_t ip_cksum; // uint16_t pkt_len; struct ipv4_hdr *ip_hdr1 = (struct ipv4_hdr *) ip_hdr ; // Initialize UDP header. /* pkt_len = (uint16_t) (pkt_data_len + sizeof(struct udp_hdr)); udp_hdr->src_port = rte_cpu_to_be_16(UDP_SRC_PORT); udp_hdr->dst_port = rte_cpu_to_be_16(UDP_DST_PORT); udp_hdr->dgram_len = RTE_CPU_TO_BE_16(pkt_len); udp_hdr->dgram_cksum = 0; // No UDP checksum. */ // Compute IP header checksum. ptr16 = (uint16_t*) ip_hdr1; ip_cksum = 0; ip_cksum += ptr16[0]; ip_cksum += ptr16[1]; ip_cksum += ptr16[2]; ip_cksum += ptr16[3]; ip_cksum += ptr16[4]; ip_cksum += ptr16[5]; ? // 6 th ptr (ptr16[5]) is missing in the example code. Is it right? ip_cksum += ptr16[6]; ip_cksum += ptr16[7]; ip_cksum += ptr16[8]; ip_cksum += ptr16[9]; // Reduce 32 bit checksum to 16 bits and complement it. ip_cksum = ((ip_cksum & 0xFFFF0000) >> 16) + (ip_cksum & 0x0000FFFF); if (ip_cksum > 65535) ip_cksum -= 65535; ip_cksum = (~ip_cksum) & 0x0000FFFF; if (ip_cksum == 0) ip_cksum = 0xFFFF; ip_hdr1->hdr_checksum = (uint16_t) ip_cksum; } Is the Ben really coding machine? (as in the presentation.) ^^ Thank you very much. Sincerely Yours, Ick-Sung Choi. &'!i_jrWc( kx]9MzEnsڶrڱƨ%y&E~&ǫ]8ҊrWkzuӍ(%y&מ]Vvd_"13t]ׯvd }|^t6@I4^qyfzmh%y&jǫM6֊rWmx^:nvǫ]8ҊrWds'}DHω۷ 'A 6]x슉