blob: aad9701080e0941d17505c7d56b2859ff576a26f [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
Damjan Marion038dad72024-01-19 21:19:57 +010050#include <vlib/config.h> /* for VLIB_BUFFER_PRE_DATA_SIZE */
Ed Warnickecb9cada2015-12-08 15:45:58 -070051
Damjan Marion5de3fec2019-02-06 14:22:32 +010052#define VLIB_BUFFER_DEFAULT_DATA_SIZE (2048)
53
Damjan Marionbd0da972018-10-31 10:59:02 +010054/* Minimum buffer chain segment size. Does not apply to last buffer in chain.
55 Dataplane code can safely asume that specified amount of data is not split
56 into 2 chained buffers */
57#define VLIB_BUFFER_MIN_CHAIN_SEG_SIZE (128)
58
59/* Amount of head buffer data copied to each replica head buffer */
60#define VLIB_BUFFER_CLONE_HEAD_SIZE (256)
61
Ed Warnickecb9cada2015-12-08 15:45:58 -070062/** \file
63 vlib buffer structure definition and a few select
64 access methods. This structure and the buffer allocation
Dave Barach9b8ffd92016-07-08 08:13:45 -040065 mechanism should perhaps live in vnet, but it would take a lot
Ed Warnickecb9cada2015-12-08 15:45:58 -070066 of typing to make it so.
67*/
Dave Barach9b8ffd92016-07-08 08:13:45 -040068
Damjan Mariondac03522018-02-01 15:30:13 +010069/**
70 * Buffer Flags
71 */
72#define foreach_vlib_buffer_flag \
Damjan Marion36eb7c22019-01-18 20:45:30 +010073 _( 0, IS_TRACED, 0) \
Benoît Ganne43543172019-10-21 15:13:54 +020074 _( 1, NEXT_PRESENT, "next-present") \
Damjan Marion36eb7c22019-01-18 20:45:30 +010075 _( 2, TOTAL_LENGTH_VALID, 0) \
76 _( 3, EXT_HDR_VALID, "ext-hdr-valid")
Damjan Mariondac03522018-02-01 15:30:13 +010077
78/* NOTE: only buffer generic flags should be defined here, please consider
79 using user flags. i.e. src/vnet/buffer.h */
80
81enum
82{
83#define _(bit, name, v) VLIB_BUFFER_##name = (1 << (bit)),
84 foreach_vlib_buffer_flag
85#undef _
86};
87
88enum
89{
90#define _(bit, name, v) VLIB_BUFFER_LOG2_##name = (bit),
91 foreach_vlib_buffer_flag
92#undef _
93};
94
95 /* User defined buffer flags. */
96#define LOG2_VLIB_BUFFER_FLAG_USER(n) (32 - (n))
97#define VLIB_BUFFER_FLAG_USER(n) (1 << LOG2_VLIB_BUFFER_FLAG_USER(n))
Damjan Marion36eb7c22019-01-18 20:45:30 +010098#define VLIB_BUFFER_FLAGS_ALL (0x0f)
Damjan Mariondac03522018-02-01 15:30:13 +010099
Benoît Gannef89bbbe2021-03-04 14:31:03 +0100100/** \brief Compile time buffer trajectory tracing option
101 Turn this on if you run into "bad monkey" contexts,
102 and you want to know exactly which nodes they've visited...
103 See vlib/main.c...
104*/
105#ifndef VLIB_BUFFER_TRACE_TRAJECTORY
106#define VLIB_BUFFER_TRACE_TRAJECTORY 0
107#endif /* VLIB_BUFFER_TRACE_TRAJECTORY */
108
Damjan Marionbf236632023-10-13 09:59:00 +0000109#define vlib_buffer_template_fields \
110 /** signed offset in data[], pre_data[] that we are currently \
111 * processing. If negative current header points into predata area. */ \
112 i16 current_data; \
113 \
114 /** Nbytes between current data and the end of this buffer. */ \
115 u16 current_length; \
116 /** buffer flags: \
117 <br> VLIB_BUFFER_FREE_LIST_INDEX_MASK: bits used to store free list \
118 index, <br> VLIB_BUFFER_IS_TRACED: trace this buffer. <br> \
119 VLIB_BUFFER_NEXT_PRESENT: this is a multi-chunk buffer. <br> \
120 VLIB_BUFFER_TOTAL_LENGTH_VALID: as it says <br> \
121 VLIB_BUFFER_EXT_HDR_VALID: buffer contains valid external buffer manager \
122 header, set to avoid adding it to a flow report <br> \
123 VLIB_BUFFER_FLAG_USER(n): user-defined bit N \
124 */ \
125 u32 flags; \
126 \
127 /** Generic flow identifier */ \
128 u32 flow_id; \
129 \
130 /** Reference count for this buffer. */ \
131 volatile u8 ref_count; \
132 \
133 /** index of buffer pool this buffer belongs. */ \
134 u8 buffer_pool_index; \
135 \
136 /** Error code for buffers to be enqueued to error handler. */ \
137 vlib_error_t error; \
138 \
139 /** Next buffer for this linked-list of buffers. Only valid if \
140 * VLIB_BUFFER_NEXT_PRESENT flag is set. */ \
141 u32 next_buffer; \
142 \
143 /** The following fields can be in a union because once a packet enters \
144 * the punt path, it is no longer on a feature arc */ \
145 union \
146 { \
147 /** Used by feature subgraph arcs to visit enabled feature nodes */ \
148 u32 current_config_index; \
149 /* the reason the packet once punted */ \
150 u32 punt_reason; \
151 }; \
152 \
153 /** Opaque data used by sub-graphs for their own purposes. */ \
154 u32 opaque[10];
155
156typedef struct
157{
158 CLIB_ALIGN_MARK (align_mark, 64);
159 vlib_buffer_template_fields
160} vlib_buffer_template_t;
161
162STATIC_ASSERT_SIZEOF (vlib_buffer_template_t, 64);
163
Damjan Marion9a8a12a2019-01-23 16:52:10 +0100164/** VLIB buffer representation. */
165typedef union
Dave Barach9b8ffd92016-07-08 08:13:45 -0400166{
Damjan Marionbf236632023-10-13 09:59:00 +0000167 CLIB_CACHE_LINE_ALIGN_MARK (cacheline0);
Damjan Marion9a8a12a2019-01-23 16:52:10 +0100168 struct
169 {
Neale Ranns76b56492018-09-28 15:16:14 +0000170 union
171 {
Damjan Marionbf236632023-10-13 09:59:00 +0000172 struct
173 {
174 vlib_buffer_template_fields
175 };
176 vlib_buffer_template_t template;
Neale Ranns76b56492018-09-28 15:16:14 +0000177 };
Damjan Marion072401e2017-07-13 18:53:27 +0200178
Damjan Marionbf236632023-10-13 09:59:00 +0000179 /* Data above is initialized or zeroed on alloc, data bellow is not
180 * and it is app responsibility to ensure data is valid */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700181
Damjan Marion6807b772020-11-13 10:46:32 +0100182 /** start of 2nd half (2nd cacheline on systems where cacheline size is 64) */
183 CLIB_ALIGN_MARK (second_half, 64);
Damjan Marion9a8a12a2019-01-23 16:52:10 +0100184
Dave Baracha638c182019-06-21 18:24:07 -0400185 /** Specifies trace buffer handle if VLIB_PACKET_IS_TRACED flag is
Damjan Marion9a8a12a2019-01-23 16:52:10 +0100186 * set. */
Dave Baracha638c182019-06-21 18:24:07 -0400187 u32 trace_handle;
Damjan Marion9a8a12a2019-01-23 16:52:10 +0100188
189 /** Only valid for first buffer in chain. Current length plus total length
190 * given here give total number of bytes in buffer chain. */
191 u32 total_length_not_including_first_buffer;
192
193 /**< More opaque data, see ../vnet/vnet/buffer.h */
194 u32 opaque2[14];
195
Benoît Gannef89bbbe2021-03-04 14:31:03 +0100196#if VLIB_BUFFER_TRACE_TRAJECTORY > 0
197 /** trace trajectory data - we use a specific cacheline for that in the
198 * buffer when it is compiled-in */
199#define VLIB_BUFFER_TRACE_TRAJECTORY_MAX 31
200#define VLIB_BUFFER_TRACE_TRAJECTORY_SZ 64
201#define VLIB_BUFFER_TRACE_TRAJECTORY_INIT(b) (b)->trajectory_nb = 0
202 CLIB_ALIGN_MARK (trajectory, 64);
203 u16 trajectory_nb;
204 u16 trajectory_trace[VLIB_BUFFER_TRACE_TRAJECTORY_MAX];
205#else /* VLIB_BUFFER_TRACE_TRAJECTORY */
206#define VLIB_BUFFER_TRACE_TRAJECTORY_SZ 0
207#define VLIB_BUFFER_TRACE_TRAJECTORY_INIT(b)
208#endif /* VLIB_BUFFER_TRACE_TRAJECTORY */
209
Damjan Marion6807b772020-11-13 10:46:32 +0100210 /** start of buffer headroom */
211 CLIB_ALIGN_MARK (headroom, 64);
Damjan Marion9a8a12a2019-01-23 16:52:10 +0100212
213 /** Space for inserting data before buffer start. Packet rewrite string
214 * will be rewritten backwards and may extend back before
215 * buffer->data[0]. Must come directly before packet data. */
216 u8 pre_data[VLIB_BUFFER_PRE_DATA_SIZE];
217
218 /** Packet data */
Benoît Ganne049d0b42020-04-24 11:48:04 +0200219 u8 data[];
Damjan Marion9a8a12a2019-01-23 16:52:10 +0100220 };
221#ifdef CLIB_HAVE_VEC128
222 u8x16 as_u8x16[4];
223#endif
224#ifdef CLIB_HAVE_VEC256
Damjan Marion22f23ae2019-01-24 15:36:57 +0100225 u8x32 as_u8x32[2];
Damjan Marion9a8a12a2019-01-23 16:52:10 +0100226#endif
227#ifdef CLIB_HAVE_VEC512
Damjan Marion22f23ae2019-01-24 15:36:57 +0100228 u8x64 as_u8x64[1];
Damjan Marion9a8a12a2019-01-23 16:52:10 +0100229#endif
230} vlib_buffer_t;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700231
Benoît Gannef89bbbe2021-03-04 14:31:03 +0100232STATIC_ASSERT_SIZEOF (vlib_buffer_t, 128 + VLIB_BUFFER_TRACE_TRAJECTORY_SZ +
233 VLIB_BUFFER_PRE_DATA_SIZE);
Damjan Marion6807b772020-11-13 10:46:32 +0100234STATIC_ASSERT (VLIB_BUFFER_PRE_DATA_SIZE % CLIB_CACHE_LINE_BYTES == 0,
235 "VLIB_BUFFER_PRE_DATA_SIZE must be divisible by cache line size");
236
Damjan Marion19010202016-03-24 17:17:47 +0100237#define VLIB_BUFFER_HDR_SIZE (sizeof(vlib_buffer_t) - VLIB_BUFFER_PRE_DATA_SIZE)
Damjan Marion2d725c62023-11-13 12:18:24 +0000238#define VLIB_BUFFER_INVALID_INDEX 0xffffffff
Damjan Marion19010202016-03-24 17:17:47 +0100239
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 */
Lukas Stockner63ff7a62024-06-04 16:14:55 +0200511 u32 default_buffers_per_numa;
512 u32 buffers_per_numa[VLIB_BUFFER_MAX_NUMA_NODES];
Damjan Marion910d3692019-01-21 11:48:34 +0100513 u16 ext_hdr_size;
Damjan Marion5de3fec2019-02-06 14:22:32 +0100514 u32 default_data_size;
Nathan Skrzypczak61559022020-11-23 16:25:21 +0100515 clib_mem_page_sz_t log2_page_size;
Damjan Marion910d3692019-01-21 11:48:34 +0100516
Benoît Gannee09a2332021-03-09 15:37:49 +0100517 /* Hash table mapping buffer index into number
518 0 => allocated but free, 1 => allocated and not-free.
519 If buffer index is not in hash table then this buffer
520 has never been allocated. */
521 uword *buffer_known_hash;
522 clib_spinlock_t buffer_known_hash_lockp;
523
Damjan Marion910d3692019-01-21 11:48:34 +0100524 /* logging */
525 vlib_log_class_t log_default;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700526} vlib_buffer_main_t;
527
Damjan Marion49d66f12017-07-20 18:10:35 +0200528clib_error_t *vlib_buffer_main_init (struct vlib_main_t *vm);
Damjan Marion878c6092017-01-04 13:19:27 +0100529
Benoît Gannee09a2332021-03-09 15:37:49 +0100530format_function_t format_vlib_buffer_pool_all;
531
532int vlib_buffer_set_alloc_free_callback (
533 struct vlib_main_t *vm, vlib_buffer_alloc_free_callback_t *alloc_callback_fn,
534 vlib_buffer_alloc_free_callback_t *free_callback_fn);
535
Damjan Marion910d3692019-01-21 11:48:34 +0100536extern u16 __vlib_buffer_external_hdr_size;
537#define VLIB_BUFFER_SET_EXT_HDR_SIZE(x) \
538static void __clib_constructor \
539vnet_buffer_set_ext_hdr_size() \
540{ \
541 if (__vlib_buffer_external_hdr_size) \
542 clib_error ("buffer external header space already set"); \
543 __vlib_buffer_external_hdr_size = CLIB_CACHE_LINE_ROUND (x); \
544}
Dave Barach9b8ffd92016-07-08 08:13:45 -0400545
Damjan Marion910d3692019-01-21 11:48:34 +0100546#endif /* included_vlib_buffer_h */
Damjan Marion04a7f052017-07-10 15:06:17 +0200547
Dave Barach9b8ffd92016-07-08 08:13:45 -0400548/*
549 * fd.io coding-style-patch-verification: ON
550 *
551 * Local Variables:
552 * eval: (c-set-style "gnu")
553 * End:
554 */