[dpdk-dev] [PATCH] pktgen: fix checksum calculation logic

Rahul Lakkireddy rahul.lakkireddy at chelsio.com
Sat Sep 7 00:43:14 CEST 2019


Use rte_ipv4_udptcp_cksum() and rte_ipv6_udptcp_cksum() for
calculating L4 checksum in IPv4 and IPv6 packets, respectively.

Fix the IPv6 address copying logic to keep it consistent in all
places. Also, fix the payload length calculation in IPv4 and IPv6
headers.

Fixes: 9a43ed448cd1 ("First commit for dpdk.org")

Signed-off-by: Rahul Lakkireddy <rahul.lakkireddy at chelsio.com>
---
 app/pktgen-ipv6.c | 11 +++++------
 app/pktgen-tcp.c  | 23 +++++++++++++----------
 app/pktgen-udp.c  |  8 +++++---
 3 files changed, 23 insertions(+), 19 deletions(-)

diff --git a/app/pktgen-ipv6.c b/app/pktgen-ipv6.c
index 2e16b60..e8d3874 100644
--- a/app/pktgen-ipv6.c
+++ b/app/pktgen-ipv6.c
@@ -29,6 +29,7 @@ void
 pktgen_ipv6_ctor(pkt_seq_t *pkt, void *hdr)
 {
 	struct pg_ipv6_hdr *ip = hdr;
+	uint32_t addr;
 	uint16_t tlen;
 
 	/* IPv6 Header constructor */
@@ -41,12 +42,10 @@ pktgen_ipv6_ctor(pkt_seq_t *pkt, void *hdr)
 	ip->hop_limits = 4;
 	ip->proto = pkt->ipProto;
 
-	rte_memcpy(&ip->dst_addr[8],
-		   pkt->ip_dst_addr.addr.ipv6.s6_addr,
-		   sizeof(struct in6_addr));
-	rte_memcpy(&ip->src_addr[8],
-		   pkt->ip_dst_addr.addr.ipv6.s6_addr,
-		   sizeof(struct in6_addr));
+	addr = htonl(pkt->ip_dst_addr.addr.ipv4.s_addr);
+	(void)rte_memcpy(&ip->dst_addr[8], &addr, sizeof(uint32_t));
+	addr = htonl(pkt->ip_src_addr.addr.ipv4.s_addr);
+	(void)rte_memcpy(&ip->src_addr[8], &addr, sizeof(uint32_t));
 }
 
 /**************************************************************************//**
diff --git a/app/pktgen-tcp.c b/app/pktgen-tcp.c
index a06241f..7c31960 100644
--- a/app/pktgen-tcp.c
+++ b/app/pktgen-tcp.c
@@ -37,7 +37,7 @@ pktgen_tcp_hdr_ctor(pkt_seq_t *pkt, void * hdr, int type)
 		ipv4->src_addr = htonl(pkt->ip_src_addr.addr.ipv4.s_addr);
 		ipv4->dst_addr = htonl(pkt->ip_dst_addr.addr.ipv4.s_addr);
 
-		tlen = pkt->pktSize - (pkt->ether_hdr_size + sizeof(struct pg_ipv4_hdr));
+		tlen = pkt->pktSize - pkt->ether_hdr_size;
 		ipv4->total_length = htons(tlen);
 		ipv4->next_proto_id = pkt->ipProto;
 
@@ -50,21 +50,23 @@ pktgen_tcp_hdr_ctor(pkt_seq_t *pkt, void * hdr, int type)
 		tcp->rx_win = htons(DEFAULT_WND_SIZE);
 		tcp->tcp_urp = 0;
 
-		tlen = pkt->pktSize - pkt->ether_hdr_size;
-
-		tcp->cksum = rte_raw_cksum(tcp, tlen);
+		tcp->cksum = 0;
+		tcp->cksum = rte_ipv4_udptcp_cksum(ipv4, (const void *)tcp);
 	} else {
 		struct pg_ipv6_hdr *ipv6 = (struct pg_ipv6_hdr *)hdr;
 		struct pg_tcp_hdr *tcp = (struct pg_tcp_hdr *)&ipv6[1];
+		uint32_t addr;
 
 		/* Create the pseudo header and TCP information */
-		(void)rte_memcpy(ipv6->dst_addr, &pkt->ip_dst_addr.addr.ipv4.s_addr,
-				 sizeof(struct in6_addr));
-		(void)rte_memcpy(ipv6->src_addr, &pkt->ip_src_addr.addr.ipv4.s_addr,
-				 sizeof(struct in6_addr));
+		memset(ipv6->dst_addr, 0, sizeof(struct in6_addr));
+		memset(ipv6->src_addr, 0, sizeof(struct in6_addr));
+		addr = htonl(pkt->ip_dst_addr.addr.ipv4.s_addr);
+		(void)rte_memcpy(&ipv6->dst_addr[8], &addr, sizeof(uint32_t));
+		addr = htonl(pkt->ip_src_addr.addr.ipv4.s_addr);
+		(void)rte_memcpy(&ipv6->src_addr[8], &addr, sizeof(uint32_t));
 
 		tlen = pkt->pktSize - (pkt->ether_hdr_size + sizeof(struct pg_ipv6_hdr));
-		ipv6->payload_len = htonl(tlen);
+		ipv6->payload_len = htons(tlen);
 		ipv6->proto = pkt->ipProto;
 
 		tcp->src_port = htons(pkt->sport);
@@ -77,7 +79,8 @@ pktgen_tcp_hdr_ctor(pkt_seq_t *pkt, void * hdr, int type)
 		tcp->rx_win     = htons(DEFAULT_WND_SIZE);
 		tcp->tcp_urp = 0;
 
-		tcp->cksum = rte_raw_cksum(tcp, tlen);
+		tcp->cksum = 0;
+		tcp->cksum = rte_ipv6_udptcp_cksum(ipv6, (const void *)tcp);
 	}
 
 	/* In this case we return the original value to allow IP ctor to work */
diff --git a/app/pktgen-udp.c b/app/pktgen-udp.c
index e2751d0..41bb5c6 100644
--- a/app/pktgen-udp.c
+++ b/app/pktgen-udp.c
@@ -64,16 +64,18 @@ pktgen_udp_hdr_ctor(pkt_seq_t *pkt, void *hdr, int type)
 		struct pg_udp_hdr *udp = (struct pg_udp_hdr *)&ipv6[1];
 
 		/* Create the pseudo header and TCP information */
+		memset(ipv6->dst_addr, 0, sizeof(struct in6_addr));
+		memset(ipv6->src_addr, 0, sizeof(struct in6_addr));
 		addr = htonl(pkt->ip_dst_addr.addr.ipv4.s_addr);
 		(void)rte_memcpy(&ipv6->dst_addr[8], &addr, sizeof(uint32_t));
 		addr = htonl(pkt->ip_src_addr.addr.ipv4.s_addr);
 		(void)rte_memcpy(&ipv6->src_addr[8], &addr, sizeof(uint32_t));
 
-		tlen = pkt->pktSize - pkt->ether_hdr_size;
-		ipv6->payload_len = htonl(tlen);
+		tlen = pkt->pktSize - (pkt->ether_hdr_size +
+				       sizeof(struct pg_ipv6_hdr));
+		ipv6->payload_len = htons(tlen);
 		ipv6->proto = pkt->ipProto;
 
-		tlen = pkt->pktSize - (pkt->ether_hdr_size + sizeof(struct pg_ipv6_hdr));
 		udp->dgram_len = htons(tlen);
 		udp->src_port = htons(pkt->sport);
 		udp->dst_port = htons(pkt->dport);
-- 
2.18.0



More information about the dev mailing list