blob: 4de2deab7d05a95ff20e825f89b330f513112107 [file] [log] [blame]
Ed Warnickecb9cada2015-12-08 15:45:58 -07001/*
2 * Copyright (c) 2015 Cisco and/or its affiliates.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at:
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15/*
16 * buffer.h: VLIB buffers
17 *
18 * Copyright (c) 2008 Eliot Dresselhaus
19 *
20 * Permission is hereby granted, free of charge, to any person obtaining
21 * a copy of this software and associated documentation files (the
22 * "Software"), to deal in the Software without restriction, including
23 * without limitation the rights to use, copy, modify, merge, publish,
24 * distribute, sublicense, and/or sell copies of the Software, and to
25 * permit persons to whom the Software is furnished to do so, subject to
26 * the following conditions:
27 *
28 * The above copyright notice and this permission notice shall be
29 * included in all copies or substantial portions of the Software.
30 *
31 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
32 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
33 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
34 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
35 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
36 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
37 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
38 */
39
40#ifndef included_vlib_buffer_h
41#define included_vlib_buffer_h
42
43#include <vppinfra/types.h>
44#include <vppinfra/cache.h>
45#include <vppinfra/serialize.h>
46#include <vppinfra/vector.h>
Damjan Marion6b0f5892017-07-27 04:01:24 -040047#include <vppinfra/lock.h>
Ed Warnickecb9cada2015-12-08 15:45:58 -070048#include <vlib/error.h> /* for vlib_error_t */
Damjan Marion19010202016-03-24 17:17:47 +010049
Dave Barach9b8ffd92016-07-08 08:13:45 -040050#include <vlib/config.h> /* for __PRE_DATA_SIZE */
Damjan Marion19010202016-03-24 17:17:47 +010051#define VLIB_BUFFER_PRE_DATA_SIZE __PRE_DATA_SIZE
Ed Warnickecb9cada2015-12-08 15:45:58 -070052
Damjan Marion5de3fec2019-02-06 14:22:32 +010053#define VLIB_BUFFER_DEFAULT_DATA_SIZE (2048)
54
Damjan Marionbd0da972018-10-31 10:59:02 +010055/* Minimum buffer chain segment size. Does not apply to last buffer in chain.
56 Dataplane code can safely asume that specified amount of data is not split
57 into 2 chained buffers */
58#define VLIB_BUFFER_MIN_CHAIN_SEG_SIZE (128)
59
60/* Amount of head buffer data copied to each replica head buffer */
61#define VLIB_BUFFER_CLONE_HEAD_SIZE (256)
62
Ed Warnickecb9cada2015-12-08 15:45:58 -070063/** \file
64 vlib buffer structure definition and a few select
65 access methods. This structure and the buffer allocation
Dave Barach9b8ffd92016-07-08 08:13:45 -040066 mechanism should perhaps live in vnet, but it would take a lot
Ed Warnickecb9cada2015-12-08 15:45:58 -070067 of typing to make it so.
68*/
Dave Barach9b8ffd92016-07-08 08:13:45 -040069
Damjan Mariondac03522018-02-01 15:30:13 +010070/**
71 * Buffer Flags
72 */
73#define foreach_vlib_buffer_flag \
Damjan Marion36eb7c22019-01-18 20:45:30 +010074 _( 0, IS_TRACED, 0) \
Benoît Ganne43543172019-10-21 15:13:54 +020075 _( 1, NEXT_PRESENT, "next-present") \
Damjan Marion36eb7c22019-01-18 20:45:30 +010076 _( 2, TOTAL_LENGTH_VALID, 0) \
77 _( 3, EXT_HDR_VALID, "ext-hdr-valid")
Damjan Mariondac03522018-02-01 15:30:13 +010078
79/* NOTE: only buffer generic flags should be defined here, please consider
80 using user flags. i.e. src/vnet/buffer.h */
81
82enum
83{
84#define _(bit, name, v) VLIB_BUFFER_##name = (1 << (bit)),
85 foreach_vlib_buffer_flag
86#undef _
87};
88
89enum
90{
91#define _(bit, name, v) VLIB_BUFFER_LOG2_##name = (bit),
92 foreach_vlib_buffer_flag
93#undef _
94};
95
96 /* User defined buffer flags. */
97#define LOG2_VLIB_BUFFER_FLAG_USER(n) (32 - (n))
98#define VLIB_BUFFER_FLAG_USER(n) (1 << LOG2_VLIB_BUFFER_FLAG_USER(n))
Damjan Marion36eb7c22019-01-18 20:45:30 +010099#define VLIB_BUFFER_FLAGS_ALL (0x0f)
Damjan Mariondac03522018-02-01 15:30:13 +0100100
Benoît Gannef89bbbe2021-03-04 14:31:03 +0100101/** \brief Compile time buffer trajectory tracing option
102 Turn this on if you run into "bad monkey" contexts,
103 and you want to know exactly which nodes they've visited...
104 See vlib/main.c...
105*/
106#ifndef VLIB_BUFFER_TRACE_TRAJECTORY
107#define VLIB_BUFFER_TRACE_TRAJECTORY 0
108#endif /* VLIB_BUFFER_TRACE_TRAJECTORY */
109
Damjan Marionbf236632023-10-13 09:59:00 +0000110#define vlib_buffer_template_fields \
111 /** signed offset in data[], pre_data[] that we are currently \
112 * processing. If negative current header points into predata area. */ \
113 i16 current_data; \
114 \
115 /** Nbytes between current data and the end of this buffer. */ \
116 u16 current_length; \
117 /** buffer flags: \
118 <br> VLIB_BUFFER_FREE_LIST_INDEX_MASK: bits used to store free list \
119 index, <br> VLIB_BUFFER_IS_TRACED: trace this buffer. <br> \
120 VLIB_BUFFER_NEXT_PRESENT: this is a multi-chunk buffer. <br> \
121 VLIB_BUFFER_TOTAL_LENGTH_VALID: as it says <br> \
122 VLIB_BUFFER_EXT_HDR_VALID: buffer contains valid external buffer manager \
123 header, set to avoid adding it to a flow report <br> \
124 VLIB_BUFFER_FLAG_USER(n): user-defined bit N \
125 */ \
126 u32 flags; \
127 \
128 /** Generic flow identifier */ \
129 u32 flow_id; \
130 \
131 /** Reference count for this buffer. */ \
132 volatile u8 ref_count; \
133 \
134 /** index of buffer pool this buffer belongs. */ \
135 u8 buffer_pool_index; \
136 \
137 /** Error code for buffers to be enqueued to error handler. */ \
138 vlib_error_t error; \
139 \
140 /** Next buffer for this linked-list of buffers. Only valid if \
141 * VLIB_BUFFER_NEXT_PRESENT flag is set. */ \
142 u32 next_buffer; \
143 \
144 /** The following fields can be in a union because once a packet enters \
145 * the punt path, it is no longer on a feature arc */ \
146 union \
147 { \
148 /** Used by feature subgraph arcs to visit enabled feature nodes */ \
149 u32 current_config_index; \
150 /* the reason the packet once punted */ \
151 u32 punt_reason; \
152 }; \
153 \
154 /** Opaque data used by sub-graphs for their own purposes. */ \
155 u32 opaque[10];
156
157typedef struct
158{
159 CLIB_ALIGN_MARK (align_mark, 64);
160 vlib_buffer_template_fields
161} vlib_buffer_template_t;
162
163STATIC_ASSERT_SIZEOF (vlib_buffer_template_t, 64);
164
Damjan Marion9a8a12a2019-01-23 16:52:10 +0100165/** VLIB buffer representation. */
166typedef union
Dave Barach9b8ffd92016-07-08 08:13:45 -0400167{
Damjan Marionbf236632023-10-13 09:59:00 +0000168 CLIB_CACHE_LINE_ALIGN_MARK (cacheline0);
Damjan Marion9a8a12a2019-01-23 16:52:10 +0100169 struct
170 {
Neale Ranns76b56492018-09-28 15:16:14 +0000171 union
172 {
Damjan Marionbf236632023-10-13 09:59:00 +0000173 struct
174 {
175 vlib_buffer_template_fields
176 };
177 vlib_buffer_template_t template;
Neale Ranns76b56492018-09-28 15:16:14 +0000178 };
Damjan Marion072401e2017-07-13 18:53:27 +0200179
Damjan Marionbf236632023-10-13 09:59:00 +0000180 /* Data above is initialized or zeroed on alloc, data bellow is not
181 * and it is app responsibility to ensure data is valid */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700182
Damjan Marion6807b772020-11-13 10:46:32 +0100183 /** start of 2nd half (2nd cacheline on systems where cacheline size is 64) */
184 CLIB_ALIGN_MARK (second_half, 64);
Damjan Marion9a8a12a2019-01-23 16:52:10 +0100185
Dave Baracha638c182019-06-21 18:24:07 -0400186 /** Specifies trace buffer handle if VLIB_PACKET_IS_TRACED flag is
Damjan Marion9a8a12a2019-01-23 16:52:10 +0100187 * set. */
Dave Baracha638c182019-06-21 18:24:07 -0400188 u32 trace_handle;
Damjan Marion9a8a12a2019-01-23 16:52:10 +0100189
190 /** Only valid for first buffer in chain. Current length plus total length
191 * given here give total number of bytes in buffer chain. */
192 u32 total_length_not_including_first_buffer;
193
194 /**< More opaque data, see ../vnet/vnet/buffer.h */
195 u32 opaque2[14];
196
Benoît Gannef89bbbe2021-03-04 14:31:03 +0100197#if VLIB_BUFFER_TRACE_TRAJECTORY > 0
198 /** trace trajectory data - we use a specific cacheline for that in the
199 * buffer when it is compiled-in */
200#define VLIB_BUFFER_TRACE_TRAJECTORY_MAX 31
201#define VLIB_BUFFER_TRACE_TRAJECTORY_SZ 64
202#define VLIB_BUFFER_TRACE_TRAJECTORY_INIT(b) (b)->trajectory_nb = 0
203 CLIB_ALIGN_MARK (trajectory, 64);
204 u16 trajectory_nb;
205 u16 trajectory_trace[VLIB_BUFFER_TRACE_TRAJECTORY_MAX];
206#else /* VLIB_BUFFER_TRACE_TRAJECTORY */
207#define VLIB_BUFFER_TRACE_TRAJECTORY_SZ 0
208#define VLIB_BUFFER_TRACE_TRAJECTORY_INIT(b)
209#endif /* VLIB_BUFFER_TRACE_TRAJECTORY */
210
Damjan Marion6807b772020-11-13 10:46:32 +0100211 /** start of buffer headroom */
212 CLIB_ALIGN_MARK (headroom, 64);
Damjan Marion9a8a12a2019-01-23 16:52:10 +0100213
214 /** Space for inserting data before buffer start. Packet rewrite string
215 * will be rewritten backwards and may extend back before
216 * buffer->data[0]. Must come directly before packet data. */
217 u8 pre_data[VLIB_BUFFER_PRE_DATA_SIZE];
218
219 /** Packet data */
Benoît Ganne049d0b42020-04-24 11:48:04 +0200220 u8 data[];
Damjan Marion9a8a12a2019-01-23 16:52:10 +0100221 };
222#ifdef CLIB_HAVE_VEC128
223 u8x16 as_u8x16[4];
224#endif
225#ifdef CLIB_HAVE_VEC256
Damjan Marion22f23ae2019-01-24 15:36:57 +0100226 u8x32 as_u8x32[2];
Damjan Marion9a8a12a2019-01-23 16:52:10 +0100227#endif
228#ifdef CLIB_HAVE_VEC512
Damjan Marion22f23ae2019-01-24 15:36:57 +0100229 u8x64 as_u8x64[1];
Damjan Marion9a8a12a2019-01-23 16:52:10 +0100230#endif
231} vlib_buffer_t;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700232
Benoît Gannef89bbbe2021-03-04 14:31:03 +0100233STATIC_ASSERT_SIZEOF (vlib_buffer_t, 128 + VLIB_BUFFER_TRACE_TRAJECTORY_SZ +
234 VLIB_BUFFER_PRE_DATA_SIZE);
Damjan Marion6807b772020-11-13 10:46:32 +0100235STATIC_ASSERT (VLIB_BUFFER_PRE_DATA_SIZE % CLIB_CACHE_LINE_BYTES == 0,
236 "VLIB_BUFFER_PRE_DATA_SIZE must be divisible by cache line size");
237
Damjan Marion19010202016-03-24 17:17:47 +0100238#define VLIB_BUFFER_HDR_SIZE (sizeof(vlib_buffer_t) - VLIB_BUFFER_PRE_DATA_SIZE)
239
Ed Warnickecb9cada2015-12-08 15:45:58 -0700240/** \brief Prefetch buffer metadata.
241 The first 64 bytes of buffer contains most header information
242
243 @param b - (vlib_buffer_t *) pointer to the buffer
244 @param type - LOAD, STORE. In most cases, STORE is the right answer
245*/
246
247#define vlib_prefetch_buffer_header(b,type) CLIB_PREFETCH (b, 64, type)
Damjan Mariond30bf012018-11-18 23:48:43 +0100248#define vlib_prefetch_buffer_data(b,type) \
249 CLIB_PREFETCH (vlib_buffer_get_current(b), CLIB_CACHE_LINE_BYTES, type)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700250
Ed Warnickecb9cada2015-12-08 15:45:58 -0700251always_inline void
252vlib_buffer_struct_is_sane (vlib_buffer_t * b)
253{
254 ASSERT (sizeof (b[0]) % 64 == 0);
255
256 /* Rewrite data must be before and contiguous with packet data. */
257 ASSERT (b->pre_data + VLIB_BUFFER_PRE_DATA_SIZE == b->data);
258}
259
Damjan Marion8f499362018-10-22 13:07:02 +0200260always_inline uword
261vlib_buffer_get_va (vlib_buffer_t * b)
262{
263 return pointer_to_uword (b->data);
264}
265
Ed Warnickecb9cada2015-12-08 15:45:58 -0700266/** \brief Get pointer to current data to process
267
268 @param b - (vlib_buffer_t *) pointer to the buffer
269 @return - (void *) (b->data + b->current_data)
Dave Barach9b8ffd92016-07-08 08:13:45 -0400270*/
Ed Warnickecb9cada2015-12-08 15:45:58 -0700271
272always_inline void *
273vlib_buffer_get_current (vlib_buffer_t * b)
274{
275 /* Check bounds. */
276 ASSERT ((signed) b->current_data >= (signed) -VLIB_BUFFER_PRE_DATA_SIZE);
277 return b->data + b->current_data;
278}
279
Damjan Marion8f499362018-10-22 13:07:02 +0200280always_inline uword
281vlib_buffer_get_current_va (vlib_buffer_t * b)
282{
283 return vlib_buffer_get_va (b) + b->current_data;
284}
285
Ed Warnickecb9cada2015-12-08 15:45:58 -0700286/** \brief Advance current data pointer by the supplied (signed!) amount
287
288 @param b - (vlib_buffer_t *) pointer to the buffer
289 @param l - (word) signed increment
Dave Barach9b8ffd92016-07-08 08:13:45 -0400290*/
Ed Warnickecb9cada2015-12-08 15:45:58 -0700291always_inline void
292vlib_buffer_advance (vlib_buffer_t * b, word l)
293{
294 ASSERT (b->current_length >= l);
295 b->current_data += l;
296 b->current_length -= l;
Damjan Marionbd0da972018-10-31 10:59:02 +0100297
298 ASSERT ((b->flags & VLIB_BUFFER_NEXT_PRESENT) == 0 ||
299 b->current_length >= VLIB_BUFFER_MIN_CHAIN_SEG_SIZE);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700300}
301
Filip Tehlar816f4372017-04-26 16:09:06 +0200302/** \brief Check if there is enough space in buffer to advance
303
304 @param b - (vlib_buffer_t *) pointer to the buffer
305 @param l - (word) size to check
306 @return - 0 if there is less space than 'l' in buffer
307*/
308always_inline u8
309vlib_buffer_has_space (vlib_buffer_t * b, word l)
310{
311 return b->current_length >= l;
312}
313
Ed Warnickecb9cada2015-12-08 15:45:58 -0700314/** \brief Reset current header & length to state they were in when
315 packet was received.
316
317 @param b - (vlib_buffer_t *) pointer to the buffer
318*/
319
320always_inline void
321vlib_buffer_reset (vlib_buffer_t * b)
322{
323 b->current_length += clib_max (b->current_data, 0);
324 b->current_data = 0;
325}
326
327/** \brief Get pointer to buffer's opaque data array
328
329 @param b - (vlib_buffer_t *) pointer to the buffer
330 @return - (void *) b->opaque
331*/
332always_inline void *
333vlib_get_buffer_opaque (vlib_buffer_t * b)
Dave Barach9b8ffd92016-07-08 08:13:45 -0400334{
335 return (void *) b->opaque;
336}
Ed Warnickecb9cada2015-12-08 15:45:58 -0700337
338/** \brief Get pointer to buffer's opaque2 data array
339
340 @param b - (vlib_buffer_t *) pointer to the buffer
341 @return - (void *) b->opaque2
342*/
343always_inline void *
344vlib_get_buffer_opaque2 (vlib_buffer_t * b)
Dave Barach9b8ffd92016-07-08 08:13:45 -0400345{
346 return (void *) b->opaque2;
347}
Ed Warnickecb9cada2015-12-08 15:45:58 -0700348
Dave Barach68b0fb02017-02-28 15:15:56 -0500349/** \brief Get pointer to the end of buffer's data
350 * @param b pointer to the buffer
351 * @return pointer to tail of packet's data
352 */
353always_inline u8 *
354vlib_buffer_get_tail (vlib_buffer_t * b)
355{
356 return b->data + b->current_data + b->current_length;
357}
358
359/** \brief Append uninitialized data to buffer
360 * @param b pointer to the buffer
361 * @param size number of uninitialized bytes
362 * @return pointer to beginning of uninitialized data
363 */
364always_inline void *
Eyal Barid3d42412018-11-05 13:29:25 +0200365vlib_buffer_put_uninit (vlib_buffer_t * b, u16 size)
Dave Barach68b0fb02017-02-28 15:15:56 -0500366{
367 void *p = vlib_buffer_get_tail (b);
368 /* XXX make sure there's enough space */
369 b->current_length += size;
370 return p;
371}
372
373/** \brief Prepend uninitialized data to buffer
374 * @param b pointer to the buffer
375 * @param size number of uninitialized bytes
376 * @return pointer to beginning of uninitialized data
377 */
378always_inline void *
379vlib_buffer_push_uninit (vlib_buffer_t * b, u8 size)
380{
381 ASSERT (b->current_data + VLIB_BUFFER_PRE_DATA_SIZE >= size);
382 b->current_data -= size;
383 b->current_length += size;
384
385 return vlib_buffer_get_current (b);
386}
387
388/** \brief Make head room, typically for packet headers
389 * @param b pointer to the buffer
390 * @param size number of head room bytes
391 * @return pointer to start of buffer (current data)
392 */
393always_inline void *
394vlib_buffer_make_headroom (vlib_buffer_t * b, u8 size)
395{
Dave Barach68b0fb02017-02-28 15:15:56 -0500396 b->current_data += size;
397 return vlib_buffer_get_current (b);
398}
399
Dave Baracha638c182019-06-21 18:24:07 -0400400/** \brief Construct a trace handle from thread and pool index
401 * @param thread Thread id
402 * @param pool_index Pool index
403 * @return trace handle
404 */
405always_inline u32
406vlib_buffer_make_trace_handle (u32 thread, u32 pool_index)
407{
408 u32 rv;
409 ASSERT (thread < 0xff);
410 ASSERT (pool_index < 0x00FFFFFF);
411 rv = (thread << 24) | (pool_index & 0x00FFFFFF);
412 return rv;
413}
414
415/** \brief Extract the thread id from a trace handle
416 * @param trace_handle the trace handle
417 * @return the thread id
418 */
419always_inline u32
420vlib_buffer_get_trace_thread (vlib_buffer_t * b)
421{
422 u32 trace_handle = b->trace_handle;
423
424 return trace_handle >> 24;
425}
426
427/** \brief Extract the trace (pool) index from a trace handle
428 * @param trace_handle the trace handle
429 * @return the trace index
430 */
431always_inline u32
432vlib_buffer_get_trace_index (vlib_buffer_t * b)
433{
434 u32 trace_handle = b->trace_handle;
435 return trace_handle & 0x00FFFFFF;
436}
437
Dave Barach68b0fb02017-02-28 15:15:56 -0500438/** \brief Retrieve bytes from buffer head
439 * @param b pointer to the buffer
440 * @param size number of bytes to pull
441 * @return pointer to start of buffer (current data)
442 */
443always_inline void *
444vlib_buffer_pull (vlib_buffer_t * b, u8 size)
445{
446 if (b->current_length + VLIB_BUFFER_PRE_DATA_SIZE < size)
447 return 0;
448
449 void *data = vlib_buffer_get_current (b);
450 vlib_buffer_advance (b, size);
451 return data;
452}
453
Ed Warnickecb9cada2015-12-08 15:45:58 -0700454/* Forward declaration. */
455struct vlib_main_t;
456
Damjan Marionb6e8b1a2019-03-12 18:14:15 +0100457#define VLIB_BUFFER_POOL_PER_THREAD_CACHE_SZ 512
458
Dave Barach9b8ffd92016-07-08 08:13:45 -0400459typedef struct
460{
Damjan Marion910d3692019-01-21 11:48:34 +0100461 CLIB_CACHE_LINE_ALIGN_MARK (cacheline0);
Damjan Marionb6e8b1a2019-03-12 18:14:15 +0100462 u32 cached_buffers[VLIB_BUFFER_POOL_PER_THREAD_CACHE_SZ];
463 u32 n_cached;
Damjan Marion910d3692019-01-21 11:48:34 +0100464} vlib_buffer_pool_thread_t;
Damjan Marionb6e8b1a2019-03-12 18:14:15 +0100465
Damjan Marion878c6092017-01-04 13:19:27 +0100466typedef struct
467{
Damjan Marion04a7f052017-07-10 15:06:17 +0200468 CLIB_CACHE_LINE_ALIGN_MARK (cacheline0);
Damjan Marion149ba772017-10-12 13:09:26 +0200469 uword start;
470 uword size;
Damjan Marion65dc34b2023-10-06 10:59:32 +0200471 u8 log2_page_size;
Damjan Marion910d3692019-01-21 11:48:34 +0100472 u8 index;
Damjan Marion65dc34b2023-10-06 10:59:32 +0200473 u8 numa_node;
Damjan Marion68b4da62018-09-30 18:26:20 +0200474 u32 physmem_map_index;
Damjan Marion910d3692019-01-21 11:48:34 +0100475 u32 data_size;
Damjan Marion65dc34b2023-10-06 10:59:32 +0200476 u32 alloc_size;
Damjan Marion910d3692019-01-21 11:48:34 +0100477 u32 n_buffers;
Damjan Marionb6e8b1a2019-03-12 18:14:15 +0100478 u32 n_avail;
Damjan Mariond1274cb2018-03-13 21:32:17 +0100479 u32 *buffers;
Damjan Marion910d3692019-01-21 11:48:34 +0100480 u8 *name;
Damjan Mariond1274cb2018-03-13 21:32:17 +0100481 clib_spinlock_t lock;
Damjan Marion910d3692019-01-21 11:48:34 +0100482
483 /* per-thread data */
484 vlib_buffer_pool_thread_t *threads;
485
486 /* buffer metadata template */
Damjan Marionbf236632023-10-13 09:59:00 +0000487 vlib_buffer_template_t buffer_template;
Damjan Marion149ba772017-10-12 13:09:26 +0200488} vlib_buffer_pool_t;
489
Damjan Marionb592d1b2019-02-28 23:16:11 +0100490#define VLIB_BUFFER_MAX_NUMA_NODES 32
491
Benoît Gannee09a2332021-03-09 15:37:49 +0100492typedef u32 (vlib_buffer_alloc_free_callback_t) (struct vlib_main_t *vm,
493 u8 buffer_pool_index,
494 u32 *buffers, u32 n_buffers);
495
Damjan Marion149ba772017-10-12 13:09:26 +0200496typedef struct
497{
498 CLIB_CACHE_LINE_ALIGN_MARK (cacheline0);
Damjan Marion04a7f052017-07-10 15:06:17 +0200499 /* Virtual memory address and size of buffer memory, used for calculating
500 buffer index */
501 uword buffer_mem_start;
502 uword buffer_mem_size;
Damjan Marion149ba772017-10-12 13:09:26 +0200503 vlib_buffer_pool_t *buffer_pools;
Damjan Marion04a7f052017-07-10 15:06:17 +0200504
Benoît Gannee09a2332021-03-09 15:37:49 +0100505 vlib_buffer_alloc_free_callback_t *alloc_callback_fn;
506 vlib_buffer_alloc_free_callback_t *free_callback_fn;
507
Damjan Marionb592d1b2019-02-28 23:16:11 +0100508 u8 default_buffer_pool_index_for_numa[VLIB_BUFFER_MAX_NUMA_NODES];
Ed Warnickecb9cada2015-12-08 15:45:58 -0700509
Damjan Marion910d3692019-01-21 11:48:34 +0100510 /* config */
511 u32 buffers_per_numa;
512 u16 ext_hdr_size;
Damjan Marion5de3fec2019-02-06 14:22:32 +0100513 u32 default_data_size;
Nathan Skrzypczak61559022020-11-23 16:25:21 +0100514 clib_mem_page_sz_t log2_page_size;
Damjan Marion910d3692019-01-21 11:48:34 +0100515
Benoît Gannee09a2332021-03-09 15:37:49 +0100516 /* Hash table mapping buffer index into number
517 0 => allocated but free, 1 => allocated and not-free.
518 If buffer index is not in hash table then this buffer
519 has never been allocated. */
520 uword *buffer_known_hash;
521 clib_spinlock_t buffer_known_hash_lockp;
522
Damjan Marion910d3692019-01-21 11:48:34 +0100523 /* logging */
524 vlib_log_class_t log_default;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700525} vlib_buffer_main_t;
526
Damjan Marion49d66f12017-07-20 18:10:35 +0200527clib_error_t *vlib_buffer_main_init (struct vlib_main_t *vm);
Damjan Marion878c6092017-01-04 13:19:27 +0100528
Benoît Gannee09a2332021-03-09 15:37:49 +0100529format_function_t format_vlib_buffer_pool_all;
530
531int vlib_buffer_set_alloc_free_callback (
532 struct vlib_main_t *vm, vlib_buffer_alloc_free_callback_t *alloc_callback_fn,
533 vlib_buffer_alloc_free_callback_t *free_callback_fn);
534
Damjan Marion910d3692019-01-21 11:48:34 +0100535extern u16 __vlib_buffer_external_hdr_size;
536#define VLIB_BUFFER_SET_EXT_HDR_SIZE(x) \
537static void __clib_constructor \
538vnet_buffer_set_ext_hdr_size() \
539{ \
540 if (__vlib_buffer_external_hdr_size) \
541 clib_error ("buffer external header space already set"); \
542 __vlib_buffer_external_hdr_size = CLIB_CACHE_LINE_ROUND (x); \
543}
Dave Barach9b8ffd92016-07-08 08:13:45 -0400544
Damjan Marion910d3692019-01-21 11:48:34 +0100545#endif /* included_vlib_buffer_h */
Damjan Marion04a7f052017-07-10 15:06:17 +0200546
Dave Barach9b8ffd92016-07-08 08:13:45 -0400547/*
548 * fd.io coding-style-patch-verification: ON
549 *
550 * Local Variables:
551 * eval: (c-set-style "gnu")
552 * End:
553 */