From patchwork Thu Jul 21 08:08:22 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Olivier Matz X-Patchwork-Id: 14940 X-Patchwork-Delegate: thomas@monjalon.net Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [IPv6:::1]) by dpdk.org (Postfix) with ESMTP id 965265588; Thu, 21 Jul 2016 10:08:54 +0200 (CEST) Received: from proxy.6wind.com (host.76.145.23.62.rev.coltfrance.com [62.23.145.76]) by dpdk.org (Postfix) with ESMTP id 21F503979 for ; Thu, 21 Jul 2016 10:08:50 +0200 (CEST) Received: from glumotte.dev.6wind.com (unknown [10.16.0.195]) by proxy.6wind.com (Postfix) with ESMTP id 567B929DC4; Thu, 21 Jul 2016 10:08:49 +0200 (CEST) From: Olivier Matz To: dev@dpdk.org, yuanhan.liu@linux.intel.com, konstantin.ananyev@intel.com Cc: sugesh.chandran@intel.com, bruce.richardson@intel.com, jianfeng.tan@intel.com, helin.zhang@intel.com, adrien.mazarguil@6wind.com Date: Thu, 21 Jul 2016 10:08:22 +0200 Message-Id: <1469088510-7552-5-git-send-email-olivier.matz@6wind.com> X-Mailer: git-send-email 2.8.1 In-Reply-To: <1469088510-7552-1-git-send-email-olivier.matz@6wind.com> References: <1469088510-7552-1-git-send-email-olivier.matz@6wind.com> Subject: [dpdk-dev] [PATCH 04/12] mbuf: add function to calculate a checksum X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: patches and discussions about DPDK List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" This function can be used to calculate the checksum of data embedded in mbuf, that can be composed of several segments. This function will be used by the virtio pmd in next commits to calculate the checksum in software in case the protocol is not recognized. Signed-off-by: Olivier Matz --- doc/guides/rel_notes/release_16_11.rst | 5 ++++ lib/librte_mbuf/rte_mbuf.c | 55 ++++++++++++++++++++++++++++++++-- lib/librte_mbuf/rte_mbuf.h | 13 ++++++++ lib/librte_mbuf/rte_mbuf_version.map | 1 + 4 files changed, 72 insertions(+), 2 deletions(-) diff --git a/doc/guides/rel_notes/release_16_11.rst b/doc/guides/rel_notes/release_16_11.rst index 6a591e2..da70f3b 100644 --- a/doc/guides/rel_notes/release_16_11.rst +++ b/doc/guides/rel_notes/release_16_11.rst @@ -53,6 +53,11 @@ New Features Added two new functions ``rte_get_rx_ol_flag_list()`` and ``rte_get_tx_ol_flag_list()`` to dump offload flags as a string. +* **Added a functions to calculate the checksum of data in a mbuf.** + + Added a new function ``rte_pktmbuf_cksum()`` to process the checksum of + data embedded in an mbuf chain. + Resolved Issues --------------- diff --git a/lib/librte_mbuf/rte_mbuf.c b/lib/librte_mbuf/rte_mbuf.c index 56f37e6..0304245 100644 --- a/lib/librte_mbuf/rte_mbuf.c +++ b/lib/librte_mbuf/rte_mbuf.c @@ -60,6 +60,7 @@ #include #include #include +#include /* * ctrlmbuf constructor, given as a callback function to @@ -273,8 +274,7 @@ const void *__rte_pktmbuf_read(const struct rte_mbuf *m, uint32_t off, if (off + len > rte_pktmbuf_pkt_len(m)) return NULL; - while (off >= rte_pktmbuf_data_len(seg) && - rte_pktmbuf_data_len(seg) != 0) { + while (off >= rte_pktmbuf_data_len(seg)) { off -= rte_pktmbuf_data_len(seg); seg = seg->next; } @@ -432,3 +432,54 @@ int rte_get_tx_ol_flag_list(uint64_t mask, char *buf, size_t buflen) return 0; } + +/* compute the raw (non complemented) checksum of a packet */ +uint16_t +rte_pktmbuf_cksum(const struct rte_mbuf *m, uint32_t off, uint32_t len) +{ + const struct rte_mbuf *seg; + const char *buf; + uint32_t sum, tmp; + uint32_t seglen, done; + + /* easy case: all data in the first segment */ + if (off + len <= rte_pktmbuf_data_len(m)) + return rte_raw_cksum(rte_pktmbuf_mtod_offset(m, + const char *, off), len); + + if (off + len > rte_pktmbuf_pkt_len(m)) + return 0; /* invalid params, return a dummy value */ + + /* else browse the segment to find offset */ + seglen = 0; + for (seg = m; seg != NULL; seg = seg->next) { + seglen = rte_pktmbuf_data_len(seg); + if (off < seglen) + break; + off -= seglen; + } + seglen -= off; + buf = rte_pktmbuf_mtod_offset(seg, const char *, off); + if (seglen >= len) /* all in one segment */ + return rte_raw_cksum(buf, len); + + /* hard case: process checksum of several segments */ + sum = 0; + done = 0; + for (;;) { + tmp = __rte_raw_cksum(buf, seglen, 0); + if (done & 1) + tmp = rte_bswap16(tmp); + sum += tmp; + done += seglen; + if (done == len) + break; + seg = seg->next; + buf = rte_pktmbuf_mtod(seg, const char *); + seglen = rte_pktmbuf_data_len(seg); + if (seglen > len - done) + seglen = len - done; + } + + return __rte_raw_cksum_reduce(sum); +} diff --git a/lib/librte_mbuf/rte_mbuf.h b/lib/librte_mbuf/rte_mbuf.h index 3c21c71..7bbe096 100644 --- a/lib/librte_mbuf/rte_mbuf.h +++ b/lib/librte_mbuf/rte_mbuf.h @@ -1581,6 +1581,19 @@ static inline int rte_pktmbuf_chain(struct rte_mbuf *head, struct rte_mbuf *tail */ void rte_pktmbuf_dump(FILE *f, const struct rte_mbuf *m, unsigned dump_len); +/** + * Compute the raw (non complemented) checksum of a packet. + * + * @param m + * The pointer to the mbuf. + * @param off + * The offset in bytes to start the checksum. + * @param len + * The length in bytes of the data to ckecksum. + */ +uint16_t +rte_pktmbuf_cksum(const struct rte_mbuf *m, uint32_t off, uint32_t len); + #ifdef __cplusplus } #endif diff --git a/lib/librte_mbuf/rte_mbuf_version.map b/lib/librte_mbuf/rte_mbuf_version.map index 6f83745..7b85dad 100644 --- a/lib/librte_mbuf/rte_mbuf_version.map +++ b/lib/librte_mbuf/rte_mbuf_version.map @@ -33,6 +33,7 @@ DPDK_16.11 { rte_get_ptype_tunnel_name; rte_get_rx_ol_flag_list; rte_get_tx_ol_flag_list; + rte_pktmbuf_cksum; rte_pktmbuf_get_ptype; } DPDK_2.1;