]>
Commit | Line | Data |
---|---|---|
91088554 | 1 | /* |
cf62fa4c | 2 | * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013 Nicira, Inc. |
91088554 DDP |
3 | * |
4 | * Licensed under the Apache License, Version 2.0 (the "License"); | |
5 | * you may not use this file except in compliance with the License. | |
6 | * You may obtain a copy of the License at: | |
7 | * | |
8 | * http://www.apache.org/licenses/LICENSE-2.0 | |
9 | * | |
10 | * Unless required by applicable law or agreed to in writing, software | |
11 | * distributed under the License is distributed on an "AS IS" BASIS, | |
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
13 | * See the License for the specific language governing permissions and | |
14 | * limitations under the License. | |
15 | */ | |
16 | ||
cf62fa4c PS |
17 | #ifndef DPBUF_H |
18 | #define DPBUF_H 1 | |
91088554 | 19 | |
cf62fa4c PS |
20 | #include <stddef.h> |
21 | #include <stdint.h> | |
b19bab5b | 22 | #include "openvswitch/list.h" |
cf62fa4c PS |
23 | #include "packets.h" |
24 | #include "util.h" | |
25 | #include "netdev-dpdk.h" | |
91088554 DDP |
26 | |
27 | #ifdef __cplusplus | |
28 | extern "C" { | |
29 | #endif | |
30 | ||
cf62fa4c PS |
31 | enum OVS_PACKED_ENUM dp_packet_source { |
32 | DPBUF_MALLOC, /* Obtained via malloc(). */ | |
33 | DPBUF_STACK, /* Un-movable stack space or static buffer. */ | |
34 | DPBUF_STUB, /* Starts on stack, may expand into heap. */ | |
35 | DPBUF_DPDK, /* buffer data is from DPDK allocated memory. | |
5a07c6e1 | 36 | * ref to build_dp_packet() in netdev-dpdk. */ |
cf62fa4c | 37 | }; |
91088554 | 38 | |
82eb5b0a | 39 | /* Buffer for holding packet data. A dp_packet is automatically reallocated |
cf62fa4c | 40 | * as necessary if it grows too large for the available memory. |
cf62fa4c | 41 | */ |
e14deea0 | 42 | struct dp_packet { |
cf62fa4c PS |
43 | #ifdef DPDK_NETDEV |
44 | struct rte_mbuf mbuf; /* DPDK mbuf */ | |
45 | #else | |
b8e57534 | 46 | void *base_; /* First byte of allocated space. */ |
11a6fbd5 | 47 | uint16_t allocated_; /* Number of bytes allocated. */ |
b8e57534 MK |
48 | uint16_t data_ofs; /* First byte actually in use. */ |
49 | uint32_t size_; /* Number of bytes in use. */ | |
2bc1bbd2 | 50 | uint32_t rss_hash; /* Packet hash. */ |
f2f44f5d | 51 | bool rss_hash_valid; /* Is the 'rss_hash' valid? */ |
61a2647e | 52 | #endif |
cf62fa4c | 53 | enum dp_packet_source source; /* Source of memory allocated as 'base'. */ |
82eb5b0a DDP |
54 | uint8_t l2_pad_size; /* Detected l2 padding size. |
55 | * Padding is non-pullable. */ | |
56 | uint16_t l2_5_ofs; /* MPLS label stack offset, or UINT16_MAX */ | |
57 | uint16_t l3_ofs; /* Network-level header offset, | |
58 | * or UINT16_MAX. */ | |
59 | uint16_t l4_ofs; /* Transport-level header offset, | |
60 | or UINT16_MAX. */ | |
41ccaa24 | 61 | struct pkt_metadata md; |
91088554 DDP |
62 | }; |
63 | ||
5a07c6e1 | 64 | static inline void *dp_packet_data(const struct dp_packet *); |
cf62fa4c | 65 | static inline void dp_packet_set_data(struct dp_packet *, void *); |
5a07c6e1 | 66 | static inline void *dp_packet_base(const struct dp_packet *); |
cf62fa4c PS |
67 | static inline void dp_packet_set_base(struct dp_packet *, void *); |
68 | ||
69 | static inline uint32_t dp_packet_size(const struct dp_packet *); | |
70 | static inline void dp_packet_set_size(struct dp_packet *, uint32_t); | |
71 | ||
11a6fbd5 DDP |
72 | static inline uint16_t dp_packet_get_allocated(const struct dp_packet *); |
73 | static inline void dp_packet_set_allocated(struct dp_packet *, uint16_t); | |
74 | ||
5a07c6e1 DDP |
75 | void *dp_packet_resize_l2(struct dp_packet *, int increment); |
76 | void *dp_packet_resize_l2_5(struct dp_packet *, int increment); | |
77 | static inline void *dp_packet_l2(const struct dp_packet *); | |
82eb5b0a | 78 | static inline void dp_packet_reset_offsets(struct dp_packet *); |
cf62fa4c PS |
79 | static inline uint8_t dp_packet_l2_pad_size(const struct dp_packet *); |
80 | static inline void dp_packet_set_l2_pad_size(struct dp_packet *, uint8_t); | |
5a07c6e1 | 81 | static inline void *dp_packet_l2_5(const struct dp_packet *); |
cf62fa4c | 82 | static inline void dp_packet_set_l2_5(struct dp_packet *, void *); |
5a07c6e1 | 83 | static inline void *dp_packet_l3(const struct dp_packet *); |
cf62fa4c | 84 | static inline void dp_packet_set_l3(struct dp_packet *, void *); |
5a07c6e1 | 85 | static inline void *dp_packet_l4(const struct dp_packet *); |
cf62fa4c PS |
86 | static inline void dp_packet_set_l4(struct dp_packet *, void *); |
87 | static inline size_t dp_packet_l4_size(const struct dp_packet *); | |
88 | static inline const void *dp_packet_get_tcp_payload(const struct dp_packet *); | |
89 | static inline const void *dp_packet_get_udp_payload(const struct dp_packet *); | |
90 | static inline const void *dp_packet_get_sctp_payload(const struct dp_packet *); | |
91 | static inline const void *dp_packet_get_icmp_payload(const struct dp_packet *); | |
92 | static inline const void *dp_packet_get_nd_payload(const struct dp_packet *); | |
93 | ||
94 | void dp_packet_use(struct dp_packet *, void *, size_t); | |
95 | void dp_packet_use_stub(struct dp_packet *, void *, size_t); | |
96 | void dp_packet_use_const(struct dp_packet *, const void *, size_t); | |
97 | ||
5a07c6e1 | 98 | void dp_packet_init_dpdk(struct dp_packet *, size_t allocated); |
cf62fa4c PS |
99 | |
100 | void dp_packet_init(struct dp_packet *, size_t); | |
101 | void dp_packet_uninit(struct dp_packet *); | |
cf62fa4c PS |
102 | |
103 | struct dp_packet *dp_packet_new(size_t); | |
104 | struct dp_packet *dp_packet_new_with_headroom(size_t, size_t headroom); | |
105 | struct dp_packet *dp_packet_clone(const struct dp_packet *); | |
106 | struct dp_packet *dp_packet_clone_with_headroom(const struct dp_packet *, | |
5a07c6e1 | 107 | size_t headroom); |
cf62fa4c PS |
108 | struct dp_packet *dp_packet_clone_data(const void *, size_t); |
109 | struct dp_packet *dp_packet_clone_data_with_headroom(const void *, size_t, | |
5a07c6e1 | 110 | size_t headroom); |
cf62fa4c PS |
111 | static inline void dp_packet_delete(struct dp_packet *); |
112 | ||
113 | static inline void *dp_packet_at(const struct dp_packet *, size_t offset, | |
5a07c6e1 DDP |
114 | size_t size); |
115 | static inline void *dp_packet_at_assert(const struct dp_packet *, | |
116 | size_t offset, size_t size); | |
cf62fa4c PS |
117 | static inline void *dp_packet_tail(const struct dp_packet *); |
118 | static inline void *dp_packet_end(const struct dp_packet *); | |
119 | ||
120 | void *dp_packet_put_uninit(struct dp_packet *, size_t); | |
121 | void *dp_packet_put_zeros(struct dp_packet *, size_t); | |
122 | void *dp_packet_put(struct dp_packet *, const void *, size_t); | |
123 | char *dp_packet_put_hex(struct dp_packet *, const char *s, size_t *n); | |
124 | void dp_packet_reserve(struct dp_packet *, size_t); | |
5a07c6e1 DDP |
125 | void dp_packet_reserve_with_tailroom(struct dp_packet *, size_t headroom, |
126 | size_t tailroom); | |
127 | void *dp_packet_push_uninit(struct dp_packet *, size_t); | |
cf62fa4c | 128 | void *dp_packet_push_zeros(struct dp_packet *, size_t); |
5a07c6e1 | 129 | void *dp_packet_push(struct dp_packet *, const void *, size_t); |
cf62fa4c PS |
130 | |
131 | static inline size_t dp_packet_headroom(const struct dp_packet *); | |
132 | static inline size_t dp_packet_tailroom(const struct dp_packet *); | |
133 | void dp_packet_prealloc_headroom(struct dp_packet *, size_t); | |
134 | void dp_packet_prealloc_tailroom(struct dp_packet *, size_t); | |
135 | void dp_packet_shift(struct dp_packet *, int); | |
91088554 | 136 | |
cf62fa4c PS |
137 | static inline void dp_packet_clear(struct dp_packet *); |
138 | static inline void *dp_packet_pull(struct dp_packet *, size_t); | |
139 | static inline void *dp_packet_try_pull(struct dp_packet *, size_t); | |
91088554 | 140 | |
cf62fa4c | 141 | void *dp_packet_steal_data(struct dp_packet *); |
91088554 | 142 | |
5a07c6e1 DDP |
143 | static inline bool dp_packet_equal(const struct dp_packet *, |
144 | const struct dp_packet *); | |
cf62fa4c PS |
145 | |
146 | \f | |
cf62fa4c | 147 | /* Frees memory that 'b' points to, as well as 'b' itself. */ |
5a07c6e1 DDP |
148 | static inline void |
149 | dp_packet_delete(struct dp_packet *b) | |
cf62fa4c PS |
150 | { |
151 | if (b) { | |
152 | if (b->source == DPBUF_DPDK) { | |
153 | /* If this dp_packet was allocated by DPDK it must have been | |
154 | * created as a dp_packet */ | |
155 | free_dpdk_buf((struct dp_packet*) b); | |
156 | return; | |
157 | } | |
158 | ||
159 | dp_packet_uninit(b); | |
160 | free(b); | |
161 | } | |
162 | } | |
163 | ||
164 | /* If 'b' contains at least 'offset + size' bytes of data, returns a pointer to | |
165 | * byte 'offset'. Otherwise, returns a null pointer. */ | |
5a07c6e1 DDP |
166 | static inline void * |
167 | dp_packet_at(const struct dp_packet *b, size_t offset, size_t size) | |
91088554 | 168 | { |
5a07c6e1 DDP |
169 | return offset + size <= dp_packet_size(b) |
170 | ? (char *) dp_packet_data(b) + offset | |
171 | : NULL; | |
cf62fa4c | 172 | } |
91088554 | 173 | |
cf62fa4c PS |
174 | /* Returns a pointer to byte 'offset' in 'b', which must contain at least |
175 | * 'offset + size' bytes of data. */ | |
5a07c6e1 DDP |
176 | static inline void * |
177 | dp_packet_at_assert(const struct dp_packet *b, size_t offset, size_t size) | |
cf62fa4c PS |
178 | { |
179 | ovs_assert(offset + size <= dp_packet_size(b)); | |
180 | return ((char *) dp_packet_data(b)) + offset; | |
181 | } | |
182 | ||
183 | /* Returns a pointer to byte following the last byte of data in use in 'b'. */ | |
5a07c6e1 DDP |
184 | static inline void * |
185 | dp_packet_tail(const struct dp_packet *b) | |
cf62fa4c PS |
186 | { |
187 | return (char *) dp_packet_data(b) + dp_packet_size(b); | |
188 | } | |
189 | ||
190 | /* Returns a pointer to byte following the last byte allocated for use (but | |
191 | * not necessarily in use) in 'b'. */ | |
5a07c6e1 DDP |
192 | static inline void * |
193 | dp_packet_end(const struct dp_packet *b) | |
cf62fa4c | 194 | { |
11a6fbd5 | 195 | return (char *) dp_packet_base(b) + dp_packet_get_allocated(b); |
cf62fa4c PS |
196 | } |
197 | ||
198 | /* Returns the number of bytes of headroom in 'b', that is, the number of bytes | |
199 | * of unused space in dp_packet 'b' before the data that is in use. (Most | |
5a07c6e1 DDP |
200 | * commonly, the data in a dp_packet is at its beginning, and thus the |
201 | * dp_packet's headroom is 0.) */ | |
202 | static inline size_t | |
203 | dp_packet_headroom(const struct dp_packet *b) | |
cf62fa4c | 204 | { |
5a07c6e1 | 205 | return (char *) dp_packet_data(b) - (char *) dp_packet_base(b); |
cf62fa4c PS |
206 | } |
207 | ||
5a07c6e1 DDP |
208 | /* Returns the number of bytes that may be appended to the tail end of |
209 | * dp_packet 'b' before the dp_packet must be reallocated. */ | |
210 | static inline size_t | |
211 | dp_packet_tailroom(const struct dp_packet *b) | |
cf62fa4c | 212 | { |
5a07c6e1 | 213 | return (char *) dp_packet_end(b) - (char *) dp_packet_tail(b); |
cf62fa4c PS |
214 | } |
215 | ||
216 | /* Clears any data from 'b'. */ | |
5a07c6e1 DDP |
217 | static inline void |
218 | dp_packet_clear(struct dp_packet *b) | |
cf62fa4c PS |
219 | { |
220 | dp_packet_set_data(b, dp_packet_base(b)); | |
221 | dp_packet_set_size(b, 0); | |
222 | } | |
223 | ||
224 | /* Removes 'size' bytes from the head end of 'b', which must contain at least | |
225 | * 'size' bytes of data. Returns the first byte of data removed. */ | |
5a07c6e1 DDP |
226 | static inline void * |
227 | dp_packet_pull(struct dp_packet *b, size_t size) | |
cf62fa4c PS |
228 | { |
229 | void *data = dp_packet_data(b); | |
230 | ovs_assert(dp_packet_size(b) - dp_packet_l2_pad_size(b) >= size); | |
5a07c6e1 | 231 | dp_packet_set_data(b, (char *) dp_packet_data(b) + size); |
cf62fa4c PS |
232 | dp_packet_set_size(b, dp_packet_size(b) - size); |
233 | return data; | |
234 | } | |
235 | ||
236 | /* If 'b' has at least 'size' bytes of data, removes that many bytes from the | |
237 | * head end of 'b' and returns the first byte removed. Otherwise, returns a | |
238 | * null pointer without modifying 'b'. */ | |
5a07c6e1 DDP |
239 | static inline void * |
240 | dp_packet_try_pull(struct dp_packet *b, size_t size) | |
cf62fa4c PS |
241 | { |
242 | return dp_packet_size(b) - dp_packet_l2_pad_size(b) >= size | |
243 | ? dp_packet_pull(b, size) : NULL; | |
244 | } | |
245 | ||
5a07c6e1 DDP |
246 | static inline bool |
247 | dp_packet_equal(const struct dp_packet *a, const struct dp_packet *b) | |
cf62fa4c PS |
248 | { |
249 | return dp_packet_size(a) == dp_packet_size(b) && | |
5a07c6e1 | 250 | !memcmp(dp_packet_data(a), dp_packet_data(b), dp_packet_size(a)); |
cf62fa4c PS |
251 | } |
252 | ||
82eb5b0a | 253 | /* Get the start of the Ethernet frame. 'l3_ofs' marks the end of the l2 |
cf62fa4c | 254 | * headers, so return NULL if it is not set. */ |
5a07c6e1 DDP |
255 | static inline void * |
256 | dp_packet_l2(const struct dp_packet *b) | |
cf62fa4c | 257 | { |
82eb5b0a | 258 | return (b->l3_ofs != UINT16_MAX) ? dp_packet_data(b) : NULL; |
cf62fa4c PS |
259 | } |
260 | ||
82eb5b0a DDP |
261 | /* Resets all layer offsets. 'l3' offset must be set before 'l2' can be |
262 | * retrieved. */ | |
5a07c6e1 DDP |
263 | static inline void |
264 | dp_packet_reset_offsets(struct dp_packet *b) | |
cf62fa4c | 265 | { |
cf62fa4c PS |
266 | b->l2_pad_size = 0; |
267 | b->l2_5_ofs = UINT16_MAX; | |
268 | b->l3_ofs = UINT16_MAX; | |
269 | b->l4_ofs = UINT16_MAX; | |
270 | } | |
271 | ||
5a07c6e1 DDP |
272 | static inline uint8_t |
273 | dp_packet_l2_pad_size(const struct dp_packet *b) | |
cf62fa4c PS |
274 | { |
275 | return b->l2_pad_size; | |
276 | } | |
277 | ||
5a07c6e1 DDP |
278 | static inline void |
279 | dp_packet_set_l2_pad_size(struct dp_packet *b, uint8_t pad_size) | |
cf62fa4c PS |
280 | { |
281 | ovs_assert(pad_size <= dp_packet_size(b)); | |
282 | b->l2_pad_size = pad_size; | |
283 | } | |
284 | ||
5a07c6e1 DDP |
285 | static inline void * |
286 | dp_packet_l2_5(const struct dp_packet *b) | |
cf62fa4c | 287 | { |
82eb5b0a DDP |
288 | return b->l2_5_ofs != UINT16_MAX |
289 | ? (char *) dp_packet_data(b) + b->l2_5_ofs | |
290 | : NULL; | |
cf62fa4c PS |
291 | } |
292 | ||
5a07c6e1 DDP |
293 | static inline void |
294 | dp_packet_set_l2_5(struct dp_packet *b, void *l2_5) | |
cf62fa4c | 295 | { |
82eb5b0a DDP |
296 | b->l2_5_ofs = l2_5 |
297 | ? (char *) l2_5 - (char *) dp_packet_data(b) | |
298 | : UINT16_MAX; | |
cf62fa4c PS |
299 | } |
300 | ||
5a07c6e1 DDP |
301 | static inline void * |
302 | dp_packet_l3(const struct dp_packet *b) | |
cf62fa4c | 303 | { |
82eb5b0a DDP |
304 | return b->l3_ofs != UINT16_MAX |
305 | ? (char *) dp_packet_data(b) + b->l3_ofs | |
306 | : NULL; | |
cf62fa4c PS |
307 | } |
308 | ||
5a07c6e1 DDP |
309 | static inline void |
310 | dp_packet_set_l3(struct dp_packet *b, void *l3) | |
cf62fa4c | 311 | { |
82eb5b0a | 312 | b->l3_ofs = l3 ? (char *) l3 - (char *) dp_packet_data(b) : UINT16_MAX; |
cf62fa4c PS |
313 | } |
314 | ||
5a07c6e1 DDP |
315 | static inline void * |
316 | dp_packet_l4(const struct dp_packet *b) | |
cf62fa4c | 317 | { |
82eb5b0a DDP |
318 | return b->l4_ofs != UINT16_MAX |
319 | ? (char *) dp_packet_data(b) + b->l4_ofs | |
320 | : NULL; | |
cf62fa4c PS |
321 | } |
322 | ||
5a07c6e1 DDP |
323 | static inline void |
324 | dp_packet_set_l4(struct dp_packet *b, void *l4) | |
cf62fa4c | 325 | { |
82eb5b0a | 326 | b->l4_ofs = l4 ? (char *) l4 - (char *) dp_packet_data(b) : UINT16_MAX; |
cf62fa4c PS |
327 | } |
328 | ||
5a07c6e1 DDP |
329 | static inline size_t |
330 | dp_packet_l4_size(const struct dp_packet *b) | |
cf62fa4c PS |
331 | { |
332 | return b->l4_ofs != UINT16_MAX | |
333 | ? (const char *)dp_packet_tail(b) - (const char *)dp_packet_l4(b) | |
334 | - dp_packet_l2_pad_size(b) | |
335 | : 0; | |
336 | } | |
337 | ||
5a07c6e1 DDP |
338 | static inline const void * |
339 | dp_packet_get_tcp_payload(const struct dp_packet *b) | |
cf62fa4c PS |
340 | { |
341 | size_t l4_size = dp_packet_l4_size(b); | |
342 | ||
343 | if (OVS_LIKELY(l4_size >= TCP_HEADER_LEN)) { | |
344 | struct tcp_header *tcp = dp_packet_l4(b); | |
345 | int tcp_len = TCP_OFFSET(tcp->tcp_ctl) * 4; | |
346 | ||
347 | if (OVS_LIKELY(tcp_len >= TCP_HEADER_LEN && tcp_len <= l4_size)) { | |
348 | return (const char *)tcp + tcp_len; | |
349 | } | |
350 | } | |
351 | return NULL; | |
352 | } | |
353 | ||
5a07c6e1 DDP |
354 | static inline const void * |
355 | dp_packet_get_udp_payload(const struct dp_packet *b) | |
cf62fa4c PS |
356 | { |
357 | return OVS_LIKELY(dp_packet_l4_size(b) >= UDP_HEADER_LEN) | |
358 | ? (const char *)dp_packet_l4(b) + UDP_HEADER_LEN : NULL; | |
359 | } | |
360 | ||
5a07c6e1 DDP |
361 | static inline const void * |
362 | dp_packet_get_sctp_payload(const struct dp_packet *b) | |
cf62fa4c PS |
363 | { |
364 | return OVS_LIKELY(dp_packet_l4_size(b) >= SCTP_HEADER_LEN) | |
365 | ? (const char *)dp_packet_l4(b) + SCTP_HEADER_LEN : NULL; | |
366 | } | |
367 | ||
5a07c6e1 DDP |
368 | static inline const void * |
369 | dp_packet_get_icmp_payload(const struct dp_packet *b) | |
cf62fa4c PS |
370 | { |
371 | return OVS_LIKELY(dp_packet_l4_size(b) >= ICMP_HEADER_LEN) | |
372 | ? (const char *)dp_packet_l4(b) + ICMP_HEADER_LEN : NULL; | |
373 | } | |
374 | ||
5a07c6e1 DDP |
375 | static inline const void * |
376 | dp_packet_get_nd_payload(const struct dp_packet *b) | |
cf62fa4c PS |
377 | { |
378 | return OVS_LIKELY(dp_packet_l4_size(b) >= ND_MSG_LEN) | |
379 | ? (const char *)dp_packet_l4(b) + ND_MSG_LEN : NULL; | |
380 | } | |
381 | ||
382 | #ifdef DPDK_NETDEV | |
383 | BUILD_ASSERT_DECL(offsetof(struct dp_packet, mbuf) == 0); | |
384 | ||
5a07c6e1 DDP |
385 | static inline void * |
386 | dp_packet_base(const struct dp_packet *b) | |
cf62fa4c PS |
387 | { |
388 | return b->mbuf.buf_addr; | |
389 | } | |
390 | ||
5a07c6e1 DDP |
391 | static inline void |
392 | dp_packet_set_base(struct dp_packet *b, void *d) | |
cf62fa4c PS |
393 | { |
394 | b->mbuf.buf_addr = d; | |
395 | } | |
396 | ||
5a07c6e1 DDP |
397 | static inline uint32_t |
398 | dp_packet_size(const struct dp_packet *b) | |
cf62fa4c | 399 | { |
b8e57534 | 400 | return b->mbuf.pkt_len; |
cf62fa4c PS |
401 | } |
402 | ||
5a07c6e1 DDP |
403 | static inline void |
404 | dp_packet_set_size(struct dp_packet *b, uint32_t v) | |
cf62fa4c | 405 | { |
b8e57534 MK |
406 | /* netdev-dpdk does not currently support segmentation; consequently, for |
407 | * all intents and purposes, 'data_len' (16 bit) and 'pkt_len' (32 bit) may | |
408 | * be used interchangably. | |
409 | * | |
410 | * On the datapath, it is expected that the size of packets | |
411 | * (and thus 'v') will always be <= UINT16_MAX; this means that there is no | |
412 | * loss of accuracy in assigning 'v' to 'data_len'. | |
b8e57534 MK |
413 | */ |
414 | b->mbuf.data_len = (uint16_t)v; /* Current seg length. */ | |
415 | b->mbuf.pkt_len = v; /* Total length of all segments linked to | |
416 | * this segment. */ | |
cf62fa4c PS |
417 | } |
418 | ||
5a07c6e1 DDP |
419 | static inline uint16_t |
420 | __packet_data(const struct dp_packet *b) | |
cf62fa4c | 421 | { |
b8e57534 | 422 | return b->mbuf.data_off; |
cf62fa4c PS |
423 | } |
424 | ||
5a07c6e1 DDP |
425 | static inline void |
426 | __packet_set_data(struct dp_packet *b, uint16_t v) | |
cf62fa4c | 427 | { |
b8e57534 | 428 | b->mbuf.data_off = v; |
cf62fa4c PS |
429 | } |
430 | ||
5a07c6e1 DDP |
431 | static inline uint16_t |
432 | dp_packet_get_allocated(const struct dp_packet *b) | |
11a6fbd5 DDP |
433 | { |
434 | return b->mbuf.buf_len; | |
435 | } | |
436 | ||
5a07c6e1 DDP |
437 | static inline void |
438 | dp_packet_set_allocated(struct dp_packet *b, uint16_t s) | |
11a6fbd5 DDP |
439 | { |
440 | b->mbuf.buf_len = s; | |
441 | } | |
b8e57534 | 442 | #else |
5a07c6e1 DDP |
443 | static inline void * |
444 | dp_packet_base(const struct dp_packet *b) | |
cf62fa4c PS |
445 | { |
446 | return b->base_; | |
447 | } | |
448 | ||
5a07c6e1 DDP |
449 | static inline void |
450 | dp_packet_set_base(struct dp_packet *b, void *d) | |
cf62fa4c PS |
451 | { |
452 | b->base_ = d; | |
453 | } | |
454 | ||
5a07c6e1 DDP |
455 | static inline uint32_t |
456 | dp_packet_size(const struct dp_packet *b) | |
cf62fa4c PS |
457 | { |
458 | return b->size_; | |
459 | } | |
460 | ||
5a07c6e1 DDP |
461 | static inline void |
462 | dp_packet_set_size(struct dp_packet *b, uint32_t v) | |
cf62fa4c PS |
463 | { |
464 | b->size_ = v; | |
465 | } | |
b8e57534 | 466 | |
5a07c6e1 DDP |
467 | static inline uint16_t |
468 | __packet_data(const struct dp_packet *b) | |
b8e57534 MK |
469 | { |
470 | return b->data_ofs; | |
471 | } | |
472 | ||
5a07c6e1 DDP |
473 | static inline void |
474 | __packet_set_data(struct dp_packet *b, uint16_t v) | |
b8e57534 MK |
475 | { |
476 | b->data_ofs = v; | |
477 | } | |
478 | ||
5a07c6e1 DDP |
479 | static inline uint16_t |
480 | dp_packet_get_allocated(const struct dp_packet *b) | |
11a6fbd5 DDP |
481 | { |
482 | return b->allocated_; | |
483 | } | |
484 | ||
5a07c6e1 DDP |
485 | static inline void |
486 | dp_packet_set_allocated(struct dp_packet *b, uint16_t s) | |
11a6fbd5 DDP |
487 | { |
488 | b->allocated_ = s; | |
489 | } | |
cf62fa4c PS |
490 | #endif |
491 | ||
5a07c6e1 DDP |
492 | static inline void * |
493 | dp_packet_data(const struct dp_packet *b) | |
b8e57534 | 494 | { |
5a07c6e1 DDP |
495 | return __packet_data(b) != UINT16_MAX |
496 | ? (char *) dp_packet_base(b) + __packet_data(b) : NULL; | |
b8e57534 MK |
497 | } |
498 | ||
5a07c6e1 DDP |
499 | static inline void |
500 | dp_packet_set_data(struct dp_packet *b, void *data) | |
b8e57534 MK |
501 | { |
502 | if (data) { | |
5a07c6e1 | 503 | __packet_set_data(b, (char *) data - (char *) dp_packet_base(b)); |
b8e57534 MK |
504 | } else { |
505 | __packet_set_data(b, UINT16_MAX); | |
506 | } | |
507 | } | |
508 | ||
5a07c6e1 DDP |
509 | static inline void |
510 | dp_packet_reset_packet(struct dp_packet *b, int off) | |
cf62fa4c PS |
511 | { |
512 | dp_packet_set_size(b, dp_packet_size(b) - off); | |
82eb5b0a | 513 | dp_packet_set_data(b, ((unsigned char *) dp_packet_data(b) + off)); |
cf62fa4c | 514 | b->l2_5_ofs = b->l3_ofs = b->l4_ofs = UINT16_MAX; |
91088554 DDP |
515 | } |
516 | ||
f2f44f5d DDP |
517 | /* Returns the RSS hash of the packet 'p'. Note that the returned value is |
518 | * correct only if 'dp_packet_rss_valid(p)' returns true */ | |
5a07c6e1 DDP |
519 | static inline uint32_t |
520 | dp_packet_get_rss_hash(struct dp_packet *p) | |
61a2647e DDP |
521 | { |
522 | #ifdef DPDK_NETDEV | |
b8e57534 | 523 | return p->mbuf.hash.rss; |
61a2647e | 524 | #else |
2bc1bbd2 | 525 | return p->rss_hash; |
61a2647e DDP |
526 | #endif |
527 | } | |
528 | ||
5a07c6e1 DDP |
529 | static inline void |
530 | dp_packet_set_rss_hash(struct dp_packet *p, uint32_t hash) | |
61a2647e DDP |
531 | { |
532 | #ifdef DPDK_NETDEV | |
b8e57534 | 533 | p->mbuf.hash.rss = hash; |
f2f44f5d | 534 | p->mbuf.ol_flags |= PKT_RX_RSS_HASH; |
61a2647e | 535 | #else |
2bc1bbd2 | 536 | p->rss_hash = hash; |
f2f44f5d DDP |
537 | p->rss_hash_valid = true; |
538 | #endif | |
539 | } | |
540 | ||
541 | static inline bool | |
542 | dp_packet_rss_valid(struct dp_packet *p) | |
543 | { | |
544 | #ifdef DPDK_NETDEV | |
545 | return p->mbuf.ol_flags & PKT_RX_RSS_HASH; | |
546 | #else | |
547 | return p->rss_hash_valid; | |
548 | #endif | |
549 | } | |
550 | ||
551 | static inline void | |
552 | dp_packet_rss_invalidate(struct dp_packet *p) | |
553 | { | |
554 | #ifdef DPDK_NETDEV | |
555 | p->mbuf.ol_flags &= ~PKT_RX_RSS_HASH; | |
556 | #else | |
557 | p->rss_hash_valid = false; | |
61a2647e DDP |
558 | #endif |
559 | } | |
560 | ||
91088554 DDP |
561 | #ifdef __cplusplus |
562 | } | |
563 | #endif | |
564 | ||
aaaac302 | 565 | #endif /* dp-packet.h */ |