[v4,4/5] linux-gen: dpdk: TX - set checksum calculation offload flags

Message ID 1504605995-28026-5-git-send-email-odpbot@yandex.ru
State New
Headers show
Series
  • [v4,1/5] linux-gen: dpdk: retrieve offload capabilities
Related show

Commit Message

Github ODP bot Sept. 5, 2017, 10:06 a.m.
From: Bogdan Pricope <bogdan.pricope@linaro.org>


Signed-off-by: Bogdan Pricope <bogdan.pricope@linaro.org>

---
/** Email created from pull request 124 (bogdanPricope:dpdk_hw_csum_pr)
 ** https://github.com/Linaro/odp/pull/124
 ** Patch: https://github.com/Linaro/odp/pull/124.patch
 ** Base sha: 7508c5ac906bb7cb1d339b4c5e924f3a18e504ca
 ** Merge commit sha: 086fe31f96e49f97f945702d0691f019245b959c
 **/
 platform/linux-generic/pktio/dpdk.c | 108 ++++++++++++++++++++++++++++++++++++
 1 file changed, 108 insertions(+)

Patch

diff --git a/platform/linux-generic/pktio/dpdk.c b/platform/linux-generic/pktio/dpdk.c
index 891adcd5..26ca0d6b 100644
--- a/platform/linux-generic/pktio/dpdk.c
+++ b/platform/linux-generic/pktio/dpdk.c
@@ -32,6 +32,10 @@ 
 #include <rte_mbuf.h>
 #include <rte_mempool.h>
 #include <rte_ethdev.h>
+#include <rte_ip.h>
+#include <rte_ip_frag.h>
+#include <rte_udp.h>
+#include <rte_tcp.h>
 #include <rte_string_fns.h>
 
 #if ODP_DPDK_ZERO_COPY
@@ -434,6 +438,95 @@  static inline int mbuf_to_pkt(pktio_entry_t *pktio_entry,
 	return (i > 0 ? i : -1);
 }
 
+static inline int check_proto(void *l3_hdr, odp_bool_t *l3_proto_v4,
+			      uint8_t *l4_proto)
+{
+	uint8_t l3_proto_ver = _ODP_IPV4HDR_VER(*(uint8_t *)l3_hdr);
+
+	if (l3_proto_ver == _ODP_IPV4) {
+		struct ipv4_hdr *ip = (struct ipv4_hdr *)l3_hdr;
+
+		*l3_proto_v4 = 1;
+		if (!rte_ipv4_frag_pkt_is_fragmented(ip))
+			*l4_proto = ip->next_proto_id;
+		else
+			*l4_proto = 0;
+
+		return 0;
+	} else if (l3_proto_ver == _ODP_IPV6) {
+		struct ipv6_hdr *ipv6 = (struct ipv6_hdr *)l3_hdr;
+
+		*l3_proto_v4 = 0;
+		*l4_proto = ipv6->proto;
+		return 0;
+	}
+
+	return -1;
+}
+
+static inline uint16_t phdr_csum(odp_bool_t ipv4, void *l3_hdr,
+				 uint64_t ol_flags)
+{
+	if (ipv4)
+		return rte_ipv4_phdr_cksum(l3_hdr, ol_flags);
+	else /*ipv6*/
+		return rte_ipv6_phdr_cksum(l3_hdr, ol_flags);
+}
+
+static inline void pkt_set_ol_tx(odp_pktout_config_opt_t *pktout_cfg,
+				 odp_packet_hdr_t *pkt_hdr,
+				 struct rte_mbuf *mbuf,
+				 char *mbuf_data)
+{
+	void *l3_hdr, *l4_hdr;
+	uint8_t l4_proto;
+	odp_bool_t l3_proto_v4;
+	odp_bool_t ipv4_chksum_pkt, udp_chksum_pkt, tcp_chksum_pkt;
+	packet_parser_t *pkt_p = &pkt_hdr->p;
+
+	l3_hdr = (void *)(mbuf_data + pkt_p->l3_offset);
+
+	if (check_proto(l3_hdr, &l3_proto_v4, &l4_proto))
+		return;
+
+	ipv4_chksum_pkt = pktout_cfg->bit.ipv4_chksum && l3_proto_v4;
+	udp_chksum_pkt =  pktout_cfg->bit.udp_chksum &&
+		(l4_proto == _ODP_IPPROTO_UDP);
+	tcp_chksum_pkt = pktout_cfg->bit.tcp_chksum &&
+			(l4_proto == _ODP_IPPROTO_TCP);
+
+	if (!ipv4_chksum_pkt && !udp_chksum_pkt && !tcp_chksum_pkt)
+			return;
+
+	mbuf->l2_len = pkt_p->l3_offset - pkt_p->l2_offset;
+	mbuf->l3_len = pkt_p->l4_offset - pkt_p->l3_offset;
+
+	if (l3_proto_v4)
+		mbuf->ol_flags = PKT_TX_IPV4;
+	else
+		mbuf->ol_flags = PKT_TX_IPV6;
+
+	if (ipv4_chksum_pkt) {
+		mbuf->ol_flags |=  PKT_TX_IP_CKSUM;
+
+		((struct ipv4_hdr *)l3_hdr)->hdr_checksum = 0;
+	}
+
+	l4_hdr = (void *)(mbuf_data + pkt_p->l4_offset);
+
+	if (udp_chksum_pkt) {
+		mbuf->ol_flags |= PKT_TX_UDP_CKSUM;
+
+		((struct udp_hdr *)l4_hdr)->dgram_cksum =
+			phdr_csum(l3_proto_v4, l3_hdr, mbuf->ol_flags);
+	} else if (tcp_chksum_pkt) {
+		mbuf->ol_flags |= PKT_TX_TCP_CKSUM;
+
+		((struct tcp_hdr *)l4_hdr)->cksum =
+			phdr_csum(l3_proto_v4, l3_hdr, mbuf->ol_flags);
+	}
+}
+
 static inline int pkt_to_mbuf(pktio_entry_t *pktio_entry,
 			      struct rte_mbuf *mbuf_table[],
 			      const odp_packet_t pkt_table[], uint16_t num)
@@ -442,6 +535,7 @@  static inline int pkt_to_mbuf(pktio_entry_t *pktio_entry,
 	int i, j;
 	char *data;
 	uint16_t pkt_len;
+	odp_pktout_config_opt_t *pktout_cfg = &pktio_entry->s.config.pktout;
 
 	if (odp_unlikely((rte_pktmbuf_alloc_bulk(pkt_dpdk->pkt_pool,
 						 mbuf_table, num)))) {
@@ -461,6 +555,11 @@  static inline int pkt_to_mbuf(pktio_entry_t *pktio_entry,
 		data = rte_pktmbuf_append(mbuf_table[i], pkt_len);
 
 		odp_packet_copy_to_mem(pkt_table[i], 0, pkt_len, data);
+
+		if (pktout_cfg->all_bits)
+			pkt_set_ol_tx(pktout_cfg,
+				      odp_packet_hdr(pkt_table[i]),
+				      mbuf_table[i], data);
 	}
 	return i;
 
@@ -549,6 +648,7 @@  static inline int pkt_to_mbuf_zero(pktio_entry_t *pktio_entry,
 				   uint16_t *copy_count)
 {
 	pkt_dpdk_t *pkt_dpdk = &pktio_entry->s.pkt_dpdk;
+	odp_pktout_config_opt_t *pktout_cfg = &pktio_entry->s.config.pktout;
 	int i;
 	*copy_count = 0;
 
@@ -565,6 +665,10 @@  static inline int pkt_to_mbuf_zero(pktio_entry_t *pktio_entry,
 		if (odp_likely(pkt_hdr->buf_hdr.segcount == 1 &&
 			       pkt_hdr->extra_type == PKT_EXTRA_TYPE_DPDK)) {
 			mbuf_update(mbuf, pkt_hdr, pkt_len);
+
+			if (pktout_cfg->all_bits)
+				pkt_set_ol_tx(pktout_cfg, pkt_hdr,
+					      mbuf, odp_packet_data(pkt));
 		} else {
 			pool_t *pool_entry = pkt_hdr->buf_hdr.pool_ptr;
 
@@ -580,6 +684,10 @@  static inline int pkt_to_mbuf_zero(pktio_entry_t *pktio_entry,
 				mbuf_init(pkt_dpdk->pkt_pool, mbuf,
 					  pkt_hdr);
 				mbuf_update(mbuf, pkt_hdr, pkt_len);
+				if (pktout_cfg->all_bits)
+					pkt_set_ol_tx(pktout_cfg, pkt_hdr,
+						      mbuf,
+						      odp_packet_data(pkt));
 			}
 		}
 		mbuf_table[i] = mbuf;