From mboxrd@z Thu Jan  1 00:00:00 1970
Return-Path: <dev-bounces@dpdk.org>
Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124])
	by inbox.dpdk.org (Postfix) with ESMTP id 78899A0A02;
	Tue, 27 Apr 2021 15:58:50 +0200 (CEST)
Received: from [217.70.189.124] (localhost [127.0.0.1])
	by mails.dpdk.org (Postfix) with ESMTP id ECA7041274;
	Tue, 27 Apr 2021 15:58:29 +0200 (CEST)
Received: from mail-wm1-f42.google.com (mail-wm1-f42.google.com
 [209.85.128.42]) by mails.dpdk.org (Postfix) with ESMTP id D320641254
 for <dev@dpdk.org>; Tue, 27 Apr 2021 15:58:25 +0200 (CEST)
Received: by mail-wm1-f42.google.com with SMTP id
 a22-20020a05600c2256b0290142870824e9so1117995wmm.0
 for <dev@dpdk.org>; Tue, 27 Apr 2021 06:58:25 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=6wind.com; s=google;
 h=from:to:cc:subject:date:message-id:in-reply-to:references
 :mime-version:content-transfer-encoding;
 bh=+9q+Rz0axJ0UiuBfvKKPwN53KvGUF/JONezKfjojE6Y=;
 b=HfO0Y8F2PTtlIJK8hAtC3zWzEzMdF2cJYMMglz7zuZfeXdg/Qb53Ki2jrpX66ezbEY
 AoWS8NeCWnLPzdXQYHnc0d1NB1OAulyAc+yGfCqyG+qvdUBsPtX6lOB+u2tF4qaR9MwS
 oXNnx5n54FXGtlk0PXMkusp8v332CL+/SLtOAcOxIVrObDD6+0c6777GU2OBFhOzEhqs
 a3YH06wZTA7euQQEErfUl8Vp+5jAyfPryFlCx011nDqdLl8/ix7j+wuLh7Wmtna2mWRN
 SEz3DC6176yLhLzYIdUj4FQt+IeSZsgVKPq+g/wELJFj1y0vE0ux8wu8DFG21GvSwCv1
 08Tw==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
 d=1e100.net; s=20161025;
 h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to
 :references:mime-version:content-transfer-encoding;
 bh=+9q+Rz0axJ0UiuBfvKKPwN53KvGUF/JONezKfjojE6Y=;
 b=Cvk/BfiK7YuRgpryUO7UMLulq0atwmtYtzwY5UmlvWDEYel2atCmFNXcImQc1nZRie
 HkfccmOYXTchwDK+G/FqVmUb7+QIiyLM/74AuFetb65om84LimAXwxQ7wCa+MyNUX+kR
 id651JWFPNInPuHGH0m9344pmQa2QFtcE5gRRxWtpRfCoIzDM1tbM7EZq3OPeSBfvOZB
 omN9muN0mz3pFODlMsdVqUggciu5X2HRBxQ+Kip91bWqxAQIT5MJWzPzrRIGp9RL55zs
 nbEcbeeHUs2eP3Tgdwoaor94EgEE3COvvxVmeIpTjS7TPywh7e0Uh/eKMDXAuiwXD8JD
 Dusg==
X-Gm-Message-State: AOAM532YUwFZPj8m/aVN7Zjx7i+pmaoevWPaIv4LV4RAmE4ewgsb7wBg
 keeQojrRw1gZioax5ko+n4AP9sGsOxBtzw==
X-Google-Smtp-Source: ABdhPJz0kPFbw+HGIT3EmE+6wit4iCypa1vvFJlnkWAk3Ernb7vGRheAfnmmLNI8Sle+oQH7Jk6JdA==
X-Received: by 2002:a1c:1d91:: with SMTP id
 d139mr17107029wmd.101.1619531905627; 
 Tue, 27 Apr 2021 06:58:25 -0700 (PDT)
Received: from gojira.dev.6wind.com (host.78.145.23.62.rev.coltfrance.com.
 [62.23.145.78])
 by smtp.gmail.com with ESMTPSA id h9sm21072213wmb.35.2021.04.27.06.58.25
 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);
 Tue, 27 Apr 2021 06:58:25 -0700 (PDT)
From: Olivier Matz <olivier.matz@6wind.com>
To: dev@dpdk.org
Cc: Keith Wiles <keith.wiles@intel.com>, Hongzhi Guo <guohongzhi1@huawei.com>,
 =?UTF-8?q?Morten=20Br=C3=B8rup?= <mb@smartsharesystems.com>,
 Thomas Monjalon <thomas@monjalon.net>
Date: Tue, 27 Apr 2021 15:57:55 +0200
Message-Id: <20210427135755.927-5-olivier.matz@6wind.com>
X-Mailer: git-send-email 2.29.2
In-Reply-To: <20210427135755.927-1-olivier.matz@6wind.com>
References: <20210427135755.927-1-olivier.matz@6wind.com>
MIME-Version: 1.0
Content-Transfer-Encoding: 8bit
Subject: [dpdk-dev] [PATCH 4/4] test/cksum: new test for L3/L4 checksum API
X-BeenThere: dev@dpdk.org
X-Mailman-Version: 2.1.29
Precedence: list
List-Id: DPDK patches and discussions <dev.dpdk.org>
List-Unsubscribe: <https://mails.dpdk.org/options/dev>,
 <mailto:dev-request@dpdk.org?subject=unsubscribe>
List-Archive: <http://mails.dpdk.org/archives/dev/>
List-Post: <mailto:dev@dpdk.org>
List-Help: <mailto:dev-request@dpdk.org?subject=help>
List-Subscribe: <https://mails.dpdk.org/listinfo/dev>,
 <mailto:dev-request@dpdk.org?subject=subscribe>
Errors-To: dev-bounces@dpdk.org
Sender: "dev" <dev-bounces@dpdk.org>

Add a simple unit test for checksum API.

Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
---
 MAINTAINERS               |   1 +
 app/test/autotest_data.py |   6 +
 app/test/meson.build      |   2 +
 app/test/test_cksum.c     | 271 ++++++++++++++++++++++++++++++++++++++
 4 files changed, 280 insertions(+)
 create mode 100644 app/test/test_cksum.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 44f3d322ed..9fe7c92eac 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1309,6 +1309,7 @@ Packet processing
 Network headers
 M: Olivier Matz <olivier.matz@6wind.com>
 F: lib/net/
+F: app/test/test_cksum.c
 
 Packet CRC
 M: Jasvinder Singh <jasvinder.singh@intel.com>
diff --git a/app/test/autotest_data.py b/app/test/autotest_data.py
index 097638941f..2871ed8994 100644
--- a/app/test/autotest_data.py
+++ b/app/test/autotest_data.py
@@ -585,6 +585,12 @@
         "Func":    default_autotest,
         "Report":  None,
     },
+    {
+        "Name":    "Checksum autotest",
+        "Command": "cksum_autotest",
+        "Func":    default_autotest,
+        "Report":  None,
+    },
     #
     #Please always keep all dump tests at the end and together!
     #
diff --git a/app/test/meson.build b/app/test/meson.build
index 08c82d3d23..28d8a9a111 100644
--- a/app/test/meson.build
+++ b/app/test/meson.build
@@ -17,6 +17,7 @@ test_sources = files(
         'test_bitmap.c',
         'test_bpf.c',
         'test_byteorder.c',
+        'test_cksum.c',
         'test_cmdline.c',
         'test_cmdline_cirbuf.c',
         'test_cmdline_etheraddr.c',
@@ -189,6 +190,7 @@ fast_tests = [
         ['atomic_autotest', false],
         ['bitops_autotest', true],
         ['byteorder_autotest', true],
+        ['cksum_autotest', true],
         ['cmdline_autotest', true],
         ['common_autotest', true],
         ['cpuflags_autotest', true],
diff --git a/app/test/test_cksum.c b/app/test/test_cksum.c
new file mode 100644
index 0000000000..cd983d7c01
--- /dev/null
+++ b/app/test/test_cksum.c
@@ -0,0 +1,271 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2021 6WIND S.A.
+ */
+
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+
+#include <rte_net.h>
+#include <rte_mbuf.h>
+#include <rte_ip.h>
+
+#include "test.h"
+
+#define MEMPOOL_CACHE_SIZE      0
+#define MBUF_DATA_SIZE          256
+#define NB_MBUF                 128
+
+/*
+ * Test L3/L4 checksum API.
+ */
+
+#define GOTO_FAIL(str, ...) do {					\
+		printf("cksum test FAILED (l.%d): <" str ">\n",		\
+		       __LINE__,  ##__VA_ARGS__);			\
+		goto fail;						\
+	} while (0)
+
+/* generated in scapy with Ether()/IP()/TCP())) */
+static const char test_cksum_ipv4_tcp[] = {
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x45, 0x00,
+	0x00, 0x28, 0x00, 0x01, 0x00, 0x00, 0x40, 0x06,
+	0x7c, 0xcd, 0x7f, 0x00, 0x00, 0x01, 0x7f, 0x00,
+	0x00, 0x01, 0x00, 0x14, 0x00, 0x50, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x02,
+	0x20, 0x00, 0x91, 0x7c, 0x00, 0x00,
+
+};
+
+/* generated in scapy with Ether()/IPv6()/TCP()) */
+static const char test_cksum_ipv6_tcp[] = {
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x60, 0x00,
+	0x00, 0x00, 0x00, 0x14, 0x06, 0x40, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x14,
+	0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x50, 0x02, 0x20, 0x00, 0x8f, 0x7d,
+	0x00, 0x00,
+};
+
+/* generated in scapy with Ether()/IP()/UDP()/Raw('x')) */
+static const char test_cksum_ipv4_udp[] = {
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x45, 0x00,
+	0x00, 0x1d, 0x00, 0x01, 0x00, 0x00, 0x40, 0x11,
+	0x7c, 0xcd, 0x7f, 0x00, 0x00, 0x01, 0x7f, 0x00,
+	0x00, 0x01, 0x00, 0x35, 0x00, 0x35, 0x00, 0x09,
+	0x89, 0x6f, 0x78,
+};
+
+/* generated in scapy with Ether()/IPv6()/UDP()/Raw('x')) */
+static const char test_cksum_ipv6_udp[] = {
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x86, 0xdd, 0x60, 0x00,
+	0x00, 0x00, 0x00, 0x09, 0x11, 0x40, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x35,
+	0x00, 0x35, 0x00, 0x09, 0x87, 0x70, 0x78,
+};
+
+/* generated in scapy with Ether()/IP(options='\x00')/UDP()/Raw('x')) */
+static const char test_cksum_ipv4_opts_udp[] = {
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x46, 0x00,
+	0x00, 0x21, 0x00, 0x01, 0x00, 0x00, 0x40, 0x11,
+	0x7b, 0xc9, 0x7f, 0x00, 0x00, 0x01, 0x7f, 0x00,
+	0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x35,
+	0x00, 0x35, 0x00, 0x09, 0x89, 0x6f, 0x78,
+};
+
+/* test l3/l4 checksum api */
+static int
+test_l4_cksum(struct rte_mempool *pktmbuf_pool, const char *pktdata, size_t len)
+{
+	struct rte_net_hdr_lens hdr_lens;
+	struct rte_mbuf *m = NULL;
+	uint32_t packet_type;
+	uint16_t prev_cksum;
+	void *l3_hdr;
+	void *l4_hdr;
+	uint32_t l3;
+	uint32_t l4;
+	char *data;
+
+	m = rte_pktmbuf_alloc(pktmbuf_pool);
+	if (m == NULL)
+		GOTO_FAIL("Cannot allocate mbuf");
+
+	data = rte_pktmbuf_append(m, len);
+	if (data == NULL)
+		GOTO_FAIL("Cannot append data");
+
+	memcpy(data, pktdata, len);
+
+	packet_type = rte_net_get_ptype(m, &hdr_lens, RTE_PTYPE_ALL_MASK);
+	l3 = packet_type & RTE_PTYPE_L3_MASK;
+	l4 = packet_type & RTE_PTYPE_L4_MASK;
+
+	l3_hdr = rte_pktmbuf_mtod_offset(m, void *, hdr_lens.l2_len);
+	l4_hdr = rte_pktmbuf_mtod_offset(m, void *,
+					 hdr_lens.l2_len + hdr_lens.l3_len);
+
+	if (l3 == RTE_PTYPE_L3_IPV4 || l3 == RTE_PTYPE_L3_IPV4_EXT) {
+		struct rte_ipv4_hdr *ip = l3_hdr;
+
+		/* verify IPv4 checksum */
+		if (rte_ipv4_cksum(l3_hdr) != 0)
+			GOTO_FAIL("invalid IPv4 checksum verification");
+
+		/* verify bad IPv4 checksum */
+		ip->hdr_checksum++;
+		if (rte_ipv4_cksum(l3_hdr) == 0)
+			GOTO_FAIL("invalid IPv4 bad checksum verification");
+		ip->hdr_checksum--;
+
+		/* recalculate IPv4 checksum */
+		prev_cksum = ip->hdr_checksum;
+		ip->hdr_checksum = 0;
+		ip->hdr_checksum = rte_ipv4_cksum(ip);
+		if (ip->hdr_checksum != prev_cksum)
+			GOTO_FAIL("invalid IPv4 checksum calculation");
+
+		/* verify L4 checksum */
+		if (rte_ipv4_udptcp_cksum_verify(l3_hdr, l4_hdr) != 0)
+			GOTO_FAIL("invalid L4 checksum verification");
+
+		if (l4 == RTE_PTYPE_L4_TCP) {
+			struct rte_tcp_hdr *tcp = l4_hdr;
+
+			/* verify bad TCP checksum */
+			tcp->cksum++;
+			if (rte_ipv4_udptcp_cksum_verify(l3_hdr, l4_hdr) == 0)
+				GOTO_FAIL("invalid bad TCP checksum verification");
+			tcp->cksum--;
+
+			/* recalculate TCP checksum */
+			prev_cksum = tcp->cksum;
+			tcp->cksum = 0;
+			tcp->cksum = rte_ipv4_udptcp_cksum(l3_hdr, l4_hdr);
+			if (tcp->cksum != prev_cksum)
+				GOTO_FAIL("invalid TCP checksum calculation");
+
+		} else if (l4 == RTE_PTYPE_L4_UDP) {
+			struct rte_udp_hdr *udp = l4_hdr;
+
+			/* verify bad UDP checksum */
+			udp->dgram_cksum++;
+			if (rte_ipv4_udptcp_cksum_verify(l3_hdr, l4_hdr) == 0)
+				GOTO_FAIL("invalid bad UDP checksum verification");
+			udp->dgram_cksum--;
+
+			/* recalculate UDP checksum */
+			prev_cksum = udp->dgram_cksum;
+			udp->dgram_cksum = 0;
+			udp->dgram_cksum = rte_ipv4_udptcp_cksum(l3_hdr,
+								 l4_hdr);
+			if (udp->dgram_cksum != prev_cksum)
+				GOTO_FAIL("invalid TCP checksum calculation");
+		}
+	} else if (l3 == RTE_PTYPE_L3_IPV6 || l3 == RTE_PTYPE_L3_IPV6_EXT) {
+		if (rte_ipv6_udptcp_cksum_verify(l3_hdr, l4_hdr) != 0)
+			GOTO_FAIL("invalid L4 checksum verification");
+
+		if (l4 == RTE_PTYPE_L4_TCP) {
+			struct rte_tcp_hdr *tcp = l4_hdr;
+
+			/* verify bad TCP checksum */
+			tcp->cksum++;
+			if (rte_ipv6_udptcp_cksum_verify(l3_hdr, l4_hdr) == 0)
+				GOTO_FAIL("invalid bad TCP checksum verification");
+			tcp->cksum--;
+
+			/* recalculate TCP checksum */
+			prev_cksum = tcp->cksum;
+			tcp->cksum = 0;
+			tcp->cksum = rte_ipv6_udptcp_cksum(l3_hdr, l4_hdr);
+			if (tcp->cksum != prev_cksum)
+				GOTO_FAIL("invalid TCP checksum calculation");
+
+		} else if (l4 == RTE_PTYPE_L4_UDP) {
+			struct rte_udp_hdr *udp = l4_hdr;
+
+			/* verify bad UDP checksum */
+			udp->dgram_cksum++;
+			if (rte_ipv6_udptcp_cksum_verify(l3_hdr, l4_hdr) == 0)
+				GOTO_FAIL("invalid bad UDP checksum verification");
+			udp->dgram_cksum--;
+
+			/* recalculate UDP checksum */
+			prev_cksum = udp->dgram_cksum;
+			udp->dgram_cksum = 0;
+			udp->dgram_cksum = rte_ipv6_udptcp_cksum(l3_hdr,
+								 l4_hdr);
+			if (udp->dgram_cksum != prev_cksum)
+				GOTO_FAIL("invalid TCP checksum calculation");
+		}
+	}
+
+	rte_pktmbuf_free(m);
+
+	return 0;
+
+fail:
+	if (m)
+		rte_pktmbuf_free(m);
+
+	return -1;
+}
+
+static int
+test_cksum(void)
+{
+	struct rte_mempool *pktmbuf_pool = NULL;
+
+	/* create pktmbuf pool if it does not exist */
+	pktmbuf_pool = rte_pktmbuf_pool_create("test_cksum_mbuf_pool",
+			NB_MBUF, MEMPOOL_CACHE_SIZE, 0, MBUF_DATA_SIZE,
+			SOCKET_ID_ANY);
+
+	if (pktmbuf_pool == NULL)
+		GOTO_FAIL("cannot allocate mbuf pool");
+
+	if (test_l4_cksum(pktmbuf_pool, test_cksum_ipv4_tcp,
+			  sizeof(test_cksum_ipv4_tcp)) < 0)
+		GOTO_FAIL("checksum error on ipv4_tcp");
+
+	if (test_l4_cksum(pktmbuf_pool, test_cksum_ipv6_tcp,
+			  sizeof(test_cksum_ipv6_tcp)) < 0)
+		GOTO_FAIL("checksum error on ipv6_tcp");
+
+	if (test_l4_cksum(pktmbuf_pool, test_cksum_ipv4_udp,
+			  sizeof(test_cksum_ipv4_udp)) < 0)
+		GOTO_FAIL("checksum error on ipv4_udp");
+
+	if (test_l4_cksum(pktmbuf_pool, test_cksum_ipv6_udp,
+			  sizeof(test_cksum_ipv6_udp)) < 0)
+		GOTO_FAIL("checksum error on ipv6_udp");
+
+	if (test_l4_cksum(pktmbuf_pool, test_cksum_ipv4_opts_udp,
+			  sizeof(test_cksum_ipv4_opts_udp)) < 0)
+		GOTO_FAIL("checksum error on ipv4_opts_udp");
+
+	rte_mempool_free(pktmbuf_pool);
+
+	return 0;
+
+fail:
+	rte_mempool_free(pktmbuf_pool);
+
+	return -1;
+}
+#undef GOTO_FAIL
+
+REGISTER_TEST_COMMAND(cksum_autotest, test_cksum);
-- 
2.29.2