[v3] ipv4 and udp/tcp cksum verification through software

Message ID 20211008155111.125786-1-usama.nadeem@emumba.com (mailing list archive)
State Superseded, archived
Delegated to: Thomas Monjalon
Headers
Series [v3] ipv4 and udp/tcp cksum verification through software |

Checks

Context Check Description
ci/checkpatch success coding style OK
ci/github-robot: build success github build: passed
ci/iol-aarch64-unit-testing fail Testing issues
ci/iol-broadcom-Functional success Functional Testing PASS
ci/iol-aarch64-compile-testing success Testing PASS
ci/iol-broadcom-Performance success Performance Testing PASS
ci/iol-intel-Performance success Performance Testing PASS
ci/iol-intel-Functional success Functional Testing PASS
ci/iol-x86_64-compile-testing success Testing PASS
ci/iol-x86_64-unit-testing success Testing PASS
ci/iol-mellanox-Performance success Performance Testing PASS
ci/Intel-compilation fail Compilation issues

Commit Message

Usama Nadeem Oct. 8, 2021, 3:51 p.m. UTC
  checks if ipv4 and udptcp cksum offload capability available
If not available, cksum is verified through software
If cksum is corrupt, packet is dropped, rest of the packets
are forwarded back.

Bugzilla ID:545
Signed-off-by: Usama Nadeem <usama.nadeem@emumba.com>
---
 examples/l3fwd/l3fwd.h     |  6 ++++
 examples/l3fwd/l3fwd_lpm.c | 71 ++++++++++++++++++++++++++++++++++++--
 examples/l3fwd/main.c      | 32 +++++++++++++++--
 3 files changed, 103 insertions(+), 6 deletions(-)
  

Patch

diff --git a/examples/l3fwd/l3fwd.h b/examples/l3fwd/l3fwd.h
index a808d60247..b0b6a906d4 100644
--- a/examples/l3fwd/l3fwd.h
+++ b/examples/l3fwd/l3fwd.h
@@ -55,6 +55,8 @@ 
 #define L3FWD_HASH_ENTRIES		(1024*1024*1)
 #endif
 #define HASH_ENTRY_NUMBER_DEFAULT	4
+bool l3_sft_cksum;
+bool l4_sft_cksum;
 
 struct mbuf_table {
 	uint16_t len;
@@ -210,6 +212,10 @@  em_main_loop(__rte_unused void *dummy);
 int
 lpm_main_loop(__rte_unused void *dummy);
 
+int
+check_software_cksum(struct rte_mbuf **pkts_burst,
+struct rte_mbuf **pkts_burst_to_send, int nb_rx);
+
 int
 fib_main_loop(__rte_unused void *dummy);
 
diff --git a/examples/l3fwd/l3fwd_lpm.c b/examples/l3fwd/l3fwd_lpm.c
index 232b606b54..e237ca6bc4 100644
--- a/examples/l3fwd/l3fwd_lpm.c
+++ b/examples/l3fwd/l3fwd_lpm.c
@@ -26,6 +26,7 @@ 
 #include <rte_udp.h>
 #include <rte_lpm.h>
 #include <rte_lpm6.h>
+#include <rte_net.h>
 
 #include "l3fwd.h"
 #include "l3fwd_event.h"
@@ -139,16 +140,65 @@  lpm_get_dst_port_with_ipv4(const struct lcore_conf *qconf, struct rte_mbuf *pkt,
 #include "l3fwd_lpm.h"
 #endif
 
+
+int check_software_cksum(struct rte_mbuf **pkts_burst,
+struct rte_mbuf **pkts_burst_to_send, int nb_rx)
+{
+	int j;
+	int i = 0;
+	struct rte_net_hdr_lens hdr_lens;
+	struct rte_ipv4_hdr *ipv4_hdr;
+	void *l3_hdr;
+	void *l4_hdr;
+	rte_be16_t prev_cksum;
+	int dropped_pkts_udp_tcp = 0;
+	int dropped_pkts_ipv4 = 0;
+	bool dropped;
+	for (j = 0; j < nb_rx; j++) {
+		dropped = false;
+		rte_net_get_ptype(pkts_burst[j], &hdr_lens, RTE_PTYPE_ALL_MASK);
+		l3_hdr = rte_pktmbuf_mtod_offset(pkts_burst[j],
+		void *, hdr_lens.l2_len);
+		l4_hdr = rte_pktmbuf_mtod_offset(pkts_burst[j],
+		void *, hdr_lens.l2_len + hdr_lens.l3_len);
+		ipv4_hdr = l3_hdr;
+		prev_cksum = ipv4_hdr->hdr_checksum;
+		ipv4_hdr->hdr_checksum = 0;
+		ipv4_hdr->hdr_checksum = rte_ipv4_cksum(ipv4_hdr);
+
+		if (l3_sft_cksum && prev_cksum != ipv4_hdr->hdr_checksum) {
+			rte_pktmbuf_free(pkts_burst[j]);
+			dropped_pkts_ipv4++;
+			dropped = true;
+		} else if (l4_sft_cksum &&
+				rte_ipv4_udptcp_cksum_verify
+				(l3_hdr, l4_hdr) != 0) {
+
+			rte_pktmbuf_free(pkts_burst[j]);
+			dropped_pkts_udp_tcp++;
+			dropped = true;
+		}
+		if (dropped == false) {
+			pkts_burst_to_send[i] = pkts_burst[j];
+			i++;
+		}
+
+	}
+	return dropped_pkts_udp_tcp+dropped_pkts_ipv4;
+}
+
 /* main processing loop */
 int
 lpm_main_loop(__rte_unused void *dummy)
 {
 	struct rte_mbuf *pkts_burst[MAX_PKT_BURST];
+	struct rte_mbuf *pkts_burst_to_send[MAX_PKT_BURST];
 	unsigned lcore_id;
 	uint64_t prev_tsc, diff_tsc, cur_tsc;
 	int i, nb_rx;
 	uint16_t portid;
 	uint8_t queueid;
+	int dropped;
 	struct lcore_conf *qconf;
 	const uint64_t drain_tsc = (rte_get_tsc_hz() + US_PER_S - 1) /
 		US_PER_S * BURST_TX_DRAIN_US;
@@ -208,20 +258,35 @@  lpm_main_loop(__rte_unused void *dummy)
 				MAX_PKT_BURST);
 			if (nb_rx == 0)
 				continue;
+			if (l3_sft_cksum || l4_sft_cksum) {
+				dropped = check_software_cksum(pkts_burst,
+				pkts_burst_to_send,	nb_rx);
+
+				nb_rx = nb_rx-dropped;
+			}
+
 
 #if defined RTE_ARCH_X86 || defined __ARM_NEON \
 			 || defined RTE_ARCH_PPC_64
+		if (l3_sft_cksum == false && l4_sft_cksum == false)
 			l3fwd_lpm_send_packets(nb_rx, pkts_burst,
 						portid, qconf);
+		else
+			l3fwd_lpm_send_packets(nb_rx, pkts_burst_to_send,
+						portid, qconf);
+
 #else
-			l3fwd_lpm_no_opt_send_packets(nb_rx, pkts_burst,
+			if (l3_sft_cksum == false && l4_sft_cksum == false)
+				l3fwd_lpm_no_opt_send_packets(nb_rx, pkts_burst,
 							portid, qconf);
+			else
+				l3fwd_lpm_no_opt_send_packets(nb_rx,
+				pkts_burst_to_send, portid, qconf);
+
 #endif /* X86 */
 		}
-
 		cur_tsc = rte_rdtsc();
 	}
-
 	return 0;
 }
 
diff --git a/examples/l3fwd/main.c b/examples/l3fwd/main.c
index 00ac267af1..68248fd189 100644
--- a/examples/l3fwd/main.c
+++ b/examples/l3fwd/main.c
@@ -123,7 +123,6 @@  static struct rte_eth_conf port_conf = {
 		.mq_mode = ETH_MQ_RX_RSS,
 		.max_rx_pkt_len = RTE_ETHER_MAX_LEN,
 		.split_hdr_size = 0,
-		.offloads = DEV_RX_OFFLOAD_CHECKSUM,
 	},
 	.rx_adv_conf = {
 		.rss_conf = {
@@ -981,6 +980,7 @@  prepare_ptype_parser(uint16_t portid, uint16_t queueid)
 	return 0;
 }
 
+
 static void
 l3fwd_poll_resource_setup(void)
 {
@@ -993,7 +993,8 @@  l3fwd_poll_resource_setup(void)
 	unsigned int nb_ports;
 	unsigned int lcore_id;
 	int ret;
-
+	l3_sft_cksum = false;
+	l4_sft_cksum = false;
 	if (check_lcore_params() < 0)
 		rte_exit(EXIT_FAILURE, "check_lcore_params failed\n");
 
@@ -1034,11 +1035,36 @@  l3fwd_poll_resource_setup(void)
 			rte_exit(EXIT_FAILURE,
 				"Error during getting device (port %u) info: %s\n",
 				portid, strerror(-ret));
-
 		if (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_MBUF_FAST_FREE)
 			local_port_conf.txmode.offloads |=
 				DEV_TX_OFFLOAD_MBUF_FAST_FREE;
 
+		if (dev_info.rx_offload_capa & DEV_RX_OFFLOAD_IPV4_CKSUM)
+			local_port_conf.rxmode.offloads |=
+			DEV_RX_OFFLOAD_IPV4_CKSUM;
+		else {
+			l3_sft_cksum = true;
+			printf("WARNING: IPV4 Checksum offload not available.\n");
+			}
+
+		if (dev_info.rx_offload_capa & DEV_RX_OFFLOAD_UDP_CKSUM)
+			local_port_conf.rxmode.offloads |=
+				DEV_RX_OFFLOAD_UDP_CKSUM;
+
+		else {
+			l4_sft_cksum = true;
+			printf("WARNING: UDP Checksum offload not available.\n");
+			}
+
+		if (dev_info.rx_offload_capa & DEV_RX_OFFLOAD_TCP_CKSUM)
+			local_port_conf.rxmode.offloads |=
+				DEV_RX_OFFLOAD_TCP_CKSUM;
+
+		else {
+			l4_sft_cksum = true;
+			printf("WARNING: TCP Checksum offload not available.\n");
+			}
+
 		local_port_conf.rx_adv_conf.rss_conf.rss_hf &=
 			dev_info.flow_type_rss_offloads;