DPDK 25.03.0-rc0
rte_cksum.h
Go to the documentation of this file.
1/* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 1982, 1986, 1990, 1993
3 * The Regents of the University of California.
4 * Copyright(c) 2010-2014 Intel Corporation.
5 * Copyright(c) 2014 6WIND S.A.
6 * All rights reserved.
7 */
8
9#ifndef _RTE_CKSUM_H_
10#define _RTE_CKSUM_H_
11
18#include <stdint.h>
19
20#include <rte_byteorder.h>
21#include <rte_common.h>
22#include <rte_mbuf.h>
23
24#ifdef __cplusplus
25extern "C" {
26#endif
27
28
42static inline uint32_t
43__rte_raw_cksum(const void *buf, size_t len, uint32_t sum)
44{
45 const void *end;
46
47 for (end = RTE_PTR_ADD(buf, RTE_ALIGN_FLOOR(len, sizeof(uint16_t)));
48 buf != end; buf = RTE_PTR_ADD(buf, sizeof(uint16_t))) {
49 uint16_t v;
50
51 memcpy(&v, buf, sizeof(uint16_t));
52 sum += v;
53 }
54
55 /* if length is odd, keeping it byte order independent */
56 if (unlikely(len % 2)) {
57 uint16_t left = 0;
58
59 memcpy(&left, end, 1);
60 sum += left;
61 }
62
63 return sum;
64}
65
75static inline uint16_t
76__rte_raw_cksum_reduce(uint32_t sum)
77{
78 sum = ((sum & 0xffff0000) >> 16) + (sum & 0xffff);
79 sum = ((sum & 0xffff0000) >> 16) + (sum & 0xffff);
80 return (uint16_t)sum;
81}
82
93static inline uint16_t
94rte_raw_cksum(const void *buf, size_t len)
95{
96 uint32_t sum;
97
98 sum = __rte_raw_cksum(buf, len, 0);
99 return __rte_raw_cksum_reduce(sum);
100}
101
116static inline int
117rte_raw_cksum_mbuf(const struct rte_mbuf *m, uint32_t off, uint32_t len,
118 uint16_t *cksum)
119{
120 const struct rte_mbuf *seg;
121 const char *buf;
122 uint32_t sum, tmp;
123 uint32_t seglen, done;
124
125 /* easy case: all data in the first segment */
126 if (off + len <= rte_pktmbuf_data_len(m)) {
128 const char *, off), len);
129 return 0;
130 }
131
132 if (unlikely(off + len > rte_pktmbuf_pkt_len(m)))
133 return -1; /* invalid params, return a dummy value */
134
135 /* else browse the segment to find offset */
136 seglen = 0;
137 for (seg = m; seg != NULL; seg = seg->next) {
138 seglen = rte_pktmbuf_data_len(seg);
139 if (off < seglen)
140 break;
141 off -= seglen;
142 }
143 RTE_ASSERT(seg != NULL);
144 if (seg == NULL)
145 return -1;
146 seglen -= off;
147 buf = rte_pktmbuf_mtod_offset(seg, const char *, off);
148 if (seglen >= len) {
149 /* all in one segment */
150 *cksum = rte_raw_cksum(buf, len);
151 return 0;
152 }
153
154 /* hard case: process checksum of several segments */
155 sum = 0;
156 done = 0;
157 for (;;) {
158 tmp = __rte_raw_cksum(buf, seglen, 0);
159 if (done & 1)
160 tmp = rte_bswap16((uint16_t)tmp);
161 sum += tmp;
162 done += seglen;
163 if (done == len)
164 break;
165 seg = seg->next;
166 buf = rte_pktmbuf_mtod(seg, const char *);
167 seglen = rte_pktmbuf_data_len(seg);
168 if (seglen > len - done)
169 seglen = len - done;
170 }
171
172 *cksum = __rte_raw_cksum_reduce(sum);
173 return 0;
174}
175
176#ifdef __cplusplus
177}
178#endif
179
180#endif /* _RTE_CKSUM_H_ */
#define unlikely(x)
static uint16_t rte_bswap16(uint16_t _x)
static uint16_t rte_raw_cksum(const void *buf, size_t len)
Definition: rte_cksum.h:94
static int rte_raw_cksum_mbuf(const struct rte_mbuf *m, uint32_t off, uint32_t len, uint16_t *cksum)
Definition: rte_cksum.h:117
#define RTE_ALIGN_FLOOR(val, align)
Definition: rte_common.h:507
#define RTE_PTR_ADD(ptr, x)
Definition: rte_common.h:469
#define rte_pktmbuf_data_len(m)
Definition: rte_mbuf.h:1571
#define rte_pktmbuf_pkt_len(m)
Definition: rte_mbuf.h:1561
#define rte_pktmbuf_mtod(m, t)
#define rte_pktmbuf_mtod_offset(m, t, o)
struct rte_mbuf * next