DPDK  24.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
25 extern "C" {
26 #endif
27 
28 
42 static 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 
75 static 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 
93 static inline uint16_t
94 rte_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 
116 static inline int
117 rte_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_ */
struct rte_mbuf * next
#define RTE_ALIGN_FLOOR(val, align)
Definition: rte_common.h:482
static uint16_t rte_bswap16(uint16_t _x)
#define rte_pktmbuf_mtod_offset(m, t, o)
#define RTE_PTR_ADD(ptr, x)
Definition: rte_common.h:444
#define unlikely(x)
#define rte_pktmbuf_mtod(m, t)
static uint16_t rte_raw_cksum(const void *buf, size_t len)
Definition: rte_cksum.h:94
#define rte_pktmbuf_pkt_len(m)
Definition: rte_mbuf.h:1561
#define rte_pktmbuf_data_len(m)
Definition: rte_mbuf.h:1571
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