DPDK 26.11.0-rc1
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
92static inline uint16_t
93__rte_raw_cksum_reduce_u64(uint64_t sum)
94{
95 uint32_t tmp;
96
97 tmp = __rte_raw_cksum_reduce((uint32_t)sum);
98 tmp += __rte_raw_cksum_reduce((uint32_t)(sum >> 32));
99 return __rte_raw_cksum_reduce(tmp);
100}
101
112static inline uint16_t
113rte_raw_cksum(const void *buf, size_t len)
114{
115 uint32_t sum;
116
117 sum = __rte_raw_cksum(buf, len, 0);
118 return __rte_raw_cksum_reduce(sum);
119}
120
135static inline int
136rte_raw_cksum_mbuf(const struct rte_mbuf *m, uint32_t off, uint32_t len,
137 uint16_t *cksum)
138{
139 const struct rte_mbuf *seg;
140 const char *buf;
141 uint32_t seglen, done, tmp;
142 uint64_t sum;
143
144 /* easy case: all data in the first segment */
145 if (off + len <= rte_pktmbuf_data_len(m)) {
147 const char *, off), len);
148 return 0;
149 }
150
151 if (unlikely(off + len > rte_pktmbuf_pkt_len(m)))
152 return -1; /* invalid params, return a dummy value */
153
154 /* else browse the segment to find offset */
155 seglen = 0;
156 for (seg = m; seg != NULL; seg = seg->next) {
157 seglen = rte_pktmbuf_data_len(seg);
158 if (off < seglen)
159 break;
160 off -= seglen;
161 }
162 RTE_ASSERT(seg != NULL);
163 if (seg == NULL)
164 return -1;
165 seglen -= off;
166 buf = rte_pktmbuf_mtod_offset(seg, const char *, off);
167 if (seglen >= len) {
168 /* all in one segment */
169 *cksum = rte_raw_cksum(buf, len);
170 return 0;
171 }
172
173 /* hard case: process checksum of several segments */
174 sum = 0;
175 done = 0;
176 for (;;) {
177 tmp = __rte_raw_cksum(buf, seglen, 0);
178 if (done & 1)
179 tmp = rte_bswap32(tmp);
180 sum += tmp;
181 done += seglen;
182 if (done == len)
183 break;
184 seg = seg->next;
185 buf = rte_pktmbuf_mtod(seg, const char *);
186 seglen = rte_pktmbuf_data_len(seg);
187 if (seglen > len - done)
188 seglen = len - done;
189 }
190
191 *cksum = __rte_raw_cksum_reduce_u64(sum);
192 return 0;
193}
194
195#ifdef __cplusplus
196}
197#endif
198
199#endif /* _RTE_CKSUM_H_ */
#define unlikely(x)
static uint32_t rte_bswap32(uint32_t x)
static uint16_t rte_raw_cksum(const void *buf, size_t len)
Definition: rte_cksum.h:113
static int rte_raw_cksum_mbuf(const struct rte_mbuf *m, uint32_t off, uint32_t len, uint16_t *cksum)
Definition: rte_cksum.h:136
#define RTE_ALIGN_FLOOR(val, align)
Definition: rte_common.h:769
#define RTE_PTR_ADD(ptr, x)
Definition: rte_common.h:643
#define rte_pktmbuf_data_len(m)
Definition: rte_mbuf.h:1671
#define rte_pktmbuf_pkt_len(m)
Definition: rte_mbuf.h:1661
#define rte_pktmbuf_mtod(m, t)
#define rte_pktmbuf_mtod_offset(m, t, o)
struct rte_mbuf * next