blob: 5504bf7c90b22f59cc5857dad8f7252f938e79a5 [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 Marion878c6092017-01-04 13:19:27 +010051#define VLIB_BUFFER_DATA_SIZE (2048)
Damjan Marion19010202016-03-24 17:17:47 +010052#define VLIB_BUFFER_PRE_DATA_SIZE __PRE_DATA_SIZE
Ed Warnickecb9cada2015-12-08 15:45:58 -070053
Ed Warnickecb9cada2015-12-08 15:45:58 -070054/** \file
55 vlib buffer structure definition and a few select
56 access methods. This structure and the buffer allocation
Dave Barach9b8ffd92016-07-08 08:13:45 -040057 mechanism should perhaps live in vnet, but it would take a lot
Ed Warnickecb9cada2015-12-08 15:45:58 -070058 of typing to make it so.
59*/
Dave Barach9b8ffd92016-07-08 08:13:45 -040060
Ed Warnickecb9cada2015-12-08 15:45:58 -070061/* VLIB buffer representation. */
Dave Barach9b8ffd92016-07-08 08:13:45 -040062typedef struct
63{
64 CLIB_CACHE_LINE_ALIGN_MARK (cacheline0);
Dave Barachf8690282017-03-01 11:38:02 -050065 STRUCT_MARK (template_start);
Ed Warnickecb9cada2015-12-08 15:45:58 -070066 /* Offset within data[] that we are currently processing.
Dave Barach9b8ffd92016-07-08 08:13:45 -040067 If negative current header points into predata area. */
68 i16 current_data; /**< signed offset in data[], pre_data[]
Ed Warnickecb9cada2015-12-08 15:45:58 -070069 that we are currently processing.
70 If negative current header points into predata area.
71 */
Dave Barach9b8ffd92016-07-08 08:13:45 -040072 u16 current_length; /**< Nbytes between current data and
Ed Warnickecb9cada2015-12-08 15:45:58 -070073 the end of this buffer.
74 */
Dave Barach9b8ffd92016-07-08 08:13:45 -040075 u32 flags; /**< buffer flags:
Damjan Marion072401e2017-07-13 18:53:27 +020076 <br> VLIB_BUFFER_FREE_LIST_INDEX_MASK: bits used to store free list index,
Ed Warnickecb9cada2015-12-08 15:45:58 -070077 <br> VLIB_BUFFER_IS_TRACED: trace this buffer.
78 <br> VLIB_BUFFER_NEXT_PRESENT: this is a multi-chunk buffer.
79 <br> VLIB_BUFFER_TOTAL_LENGTH_VALID: as it says
80 <br> VLIB_BUFFER_REPL_FAIL: packet replication failure
Dave Barachb5adaea2016-06-17 14:09:56 -040081 <br> VLIB_BUFFER_RECYCLE: as it says
Dave Barachad41b352016-10-07 08:30:23 -070082 <br> VLIB_BUFFER_FLOW_REPORT: buffer is a flow report,
Damjan Marionff542702017-02-27 11:29:20 +010083 <br> VLIB_BUFFER_EXT_HDR_VALID: buffer contains valid external buffer manager header,
Dave Barachad41b352016-10-07 08:30:23 -070084 set to avoid adding it to a flow report
Ed Warnickecb9cada2015-12-08 15:45:58 -070085 <br> VLIB_BUFFER_FLAG_USER(n): user-defined bit N
86 */
Damjan Marion072401e2017-07-13 18:53:27 +020087
88/* any change to the following line requres update of
89 * vlib_buffer_get_free_list_index(...) and
90 * vlib_buffer_set_free_list_index(...) functions */
Dave Wallaced756b352017-07-03 13:11:38 -040091#define VLIB_BUFFER_FREE_LIST_INDEX_MASK ((1 << 5) - 1)
Damjan Marion072401e2017-07-13 18:53:27 +020092
Dave Wallaced756b352017-07-03 13:11:38 -040093#define VLIB_BUFFER_IS_TRACED (1 << 5)
94#define VLIB_BUFFER_LOG2_NEXT_PRESENT (6)
Dave Barach9b8ffd92016-07-08 08:13:45 -040095#define VLIB_BUFFER_NEXT_PRESENT (1 << VLIB_BUFFER_LOG2_NEXT_PRESENT)
Dave Wallaced756b352017-07-03 13:11:38 -040096#define VLIB_BUFFER_IS_RECYCLED (1 << 7)
97#define VLIB_BUFFER_TOTAL_LENGTH_VALID (1 << 8)
98#define VLIB_BUFFER_REPL_FAIL (1 << 9)
99#define VLIB_BUFFER_RECYCLE (1 << 10)
100#define VLIB_BUFFER_FLOW_REPORT (1 << 11)
101#define VLIB_BUFFER_EXT_HDR_VALID (1 << 12)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700102
103 /* User defined buffer flags. */
104#define LOG2_VLIB_BUFFER_FLAG_USER(n) (32 - (n))
105#define VLIB_BUFFER_FLAG_USER(n) (1 << LOG2_VLIB_BUFFER_FLAG_USER(n))
106
Dave Barachf8690282017-03-01 11:38:02 -0500107 STRUCT_MARK (template_end);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700108
Ed Warnickecb9cada2015-12-08 15:45:58 -0700109 u32 next_buffer; /**< Next buffer for this linked-list of buffers.
Dave Barach9b8ffd92016-07-08 08:13:45 -0400110 Only valid if VLIB_BUFFER_NEXT_PRESENT flag is set.
Ed Warnickecb9cada2015-12-08 15:45:58 -0700111 */
112
Dave Barach9b8ffd92016-07-08 08:13:45 -0400113 vlib_error_t error; /**< Error code for buffers to be enqueued
114 to error handler.
Ed Warnickecb9cada2015-12-08 15:45:58 -0700115 */
Dave Barachd6534602016-06-14 18:38:02 -0400116 u32 current_config_index; /**< Used by feature subgraph arcs to
117 visit enabled feature nodes
118 */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700119
Damjan Marion87cd1192016-11-04 11:00:27 +0100120 u8 feature_arc_index; /**< Used to identify feature arcs by intermediate
121 feature node
122 */
123
Damjan Marionc47ed032017-01-25 14:18:03 +0100124 u8 n_add_refs; /**< Number of additional references to this buffer. */
125
126 u8 dont_waste_me[2]; /**< Available space in the (precious)
Damjan Marion87cd1192016-11-04 11:00:27 +0100127 first 32 octets of buffer metadata
128 Before allocating any of it, discussion required!
129 */
Dave Barachb5adaea2016-06-17 14:09:56 -0400130
Damjan Marion072401e2017-07-13 18:53:27 +0200131 u32 opaque[10]; /**< Opaque data used by sub-graphs for their own purposes.
Ed Warnickecb9cada2015-12-08 15:45:58 -0700132 See .../vnet/vnet/buffer.h
133 */
Dave Barach9b8ffd92016-07-08 08:13:45 -0400134 CLIB_CACHE_LINE_ALIGN_MARK (cacheline1);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700135
Dave Barach9b8ffd92016-07-08 08:13:45 -0400136 u32 trace_index; /**< Specifies index into trace buffer
137 if VLIB_PACKET_IS_TRACED flag is set.
Dave Barachd6534602016-06-14 18:38:02 -0400138 */
Dave Barachb5adaea2016-06-17 14:09:56 -0400139 u32 recycle_count; /**< Used by L2 path recycle code */
Damjan Marion072401e2017-07-13 18:53:27 +0200140
141 u32 total_length_not_including_first_buffer;
142 /**< Only valid for first buffer in chain. Current length plus
143 total length given here give total number of bytes in buffer chain.
144 */
145 u32 opaque2[13]; /**< More opaque data, currently unused */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700146
147 /***** end of second cache line */
Dave Barach9b8ffd92016-07-08 08:13:45 -0400148 CLIB_CACHE_LINE_ALIGN_MARK (cacheline2);
149 u8 pre_data[VLIB_BUFFER_PRE_DATA_SIZE]; /**< Space for inserting data
Damjan Marion19010202016-03-24 17:17:47 +0100150 before buffer start.
151 Packet rewrite string will be
152 rewritten backwards and may extend
153 back before buffer->data[0].
154 Must come directly before packet data.
155 */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700156
Ed Warnickecb9cada2015-12-08 15:45:58 -0700157 u8 data[0]; /**< Packet data. Hardware DMA here */
Dave Barach9b8ffd92016-07-08 08:13:45 -0400158} vlib_buffer_t; /* Must be a multiple of 64B. */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700159
Damjan Marion19010202016-03-24 17:17:47 +0100160#define VLIB_BUFFER_HDR_SIZE (sizeof(vlib_buffer_t) - VLIB_BUFFER_PRE_DATA_SIZE)
161
Ed Warnickecb9cada2015-12-08 15:45:58 -0700162/** \brief Prefetch buffer metadata.
163 The first 64 bytes of buffer contains most header information
164
165 @param b - (vlib_buffer_t *) pointer to the buffer
166 @param type - LOAD, STORE. In most cases, STORE is the right answer
167*/
168
169#define vlib_prefetch_buffer_header(b,type) CLIB_PREFETCH (b, 64, type)
170
171always_inline vlib_buffer_t *
172vlib_buffer_next_contiguous (vlib_buffer_t * b, u32 buffer_bytes)
Dave Barach9b8ffd92016-07-08 08:13:45 -0400173{
174 return (void *) (b + 1) + buffer_bytes;
175}
Ed Warnickecb9cada2015-12-08 15:45:58 -0700176
177always_inline void
178vlib_buffer_struct_is_sane (vlib_buffer_t * b)
179{
180 ASSERT (sizeof (b[0]) % 64 == 0);
181
182 /* Rewrite data must be before and contiguous with packet data. */
183 ASSERT (b->pre_data + VLIB_BUFFER_PRE_DATA_SIZE == b->data);
184}
185
186/** \brief Get pointer to current data to process
187
188 @param b - (vlib_buffer_t *) pointer to the buffer
189 @return - (void *) (b->data + b->current_data)
Dave Barach9b8ffd92016-07-08 08:13:45 -0400190*/
Ed Warnickecb9cada2015-12-08 15:45:58 -0700191
192always_inline void *
193vlib_buffer_get_current (vlib_buffer_t * b)
194{
195 /* Check bounds. */
196 ASSERT ((signed) b->current_data >= (signed) -VLIB_BUFFER_PRE_DATA_SIZE);
197 return b->data + b->current_data;
198}
199
200/** \brief Advance current data pointer by the supplied (signed!) amount
201
202 @param b - (vlib_buffer_t *) pointer to the buffer
203 @param l - (word) signed increment
Dave Barach9b8ffd92016-07-08 08:13:45 -0400204*/
Ed Warnickecb9cada2015-12-08 15:45:58 -0700205always_inline void
206vlib_buffer_advance (vlib_buffer_t * b, word l)
207{
208 ASSERT (b->current_length >= l);
209 b->current_data += l;
210 b->current_length -= l;
211}
212
Filip Tehlar816f4372017-04-26 16:09:06 +0200213/** \brief Check if there is enough space in buffer to advance
214
215 @param b - (vlib_buffer_t *) pointer to the buffer
216 @param l - (word) size to check
217 @return - 0 if there is less space than 'l' in buffer
218*/
219always_inline u8
220vlib_buffer_has_space (vlib_buffer_t * b, word l)
221{
222 return b->current_length >= l;
223}
224
Ed Warnickecb9cada2015-12-08 15:45:58 -0700225/** \brief Reset current header & length to state they were in when
226 packet was received.
227
228 @param b - (vlib_buffer_t *) pointer to the buffer
229*/
230
231always_inline void
232vlib_buffer_reset (vlib_buffer_t * b)
233{
234 b->current_length += clib_max (b->current_data, 0);
235 b->current_data = 0;
236}
237
238/** \brief Get pointer to buffer's opaque data array
239
240 @param b - (vlib_buffer_t *) pointer to the buffer
241 @return - (void *) b->opaque
242*/
243always_inline void *
244vlib_get_buffer_opaque (vlib_buffer_t * b)
Dave Barach9b8ffd92016-07-08 08:13:45 -0400245{
246 return (void *) b->opaque;
247}
Ed Warnickecb9cada2015-12-08 15:45:58 -0700248
249/** \brief Get pointer to buffer's opaque2 data array
250
251 @param b - (vlib_buffer_t *) pointer to the buffer
252 @return - (void *) b->opaque2
253*/
254always_inline void *
255vlib_get_buffer_opaque2 (vlib_buffer_t * b)
Dave Barach9b8ffd92016-07-08 08:13:45 -0400256{
257 return (void *) b->opaque2;
258}
Ed Warnickecb9cada2015-12-08 15:45:58 -0700259
Dave Barach68b0fb02017-02-28 15:15:56 -0500260/** \brief Get pointer to the end of buffer's data
261 * @param b pointer to the buffer
262 * @return pointer to tail of packet's data
263 */
264always_inline u8 *
265vlib_buffer_get_tail (vlib_buffer_t * b)
266{
267 return b->data + b->current_data + b->current_length;
268}
269
270/** \brief Append uninitialized data to buffer
271 * @param b pointer to the buffer
272 * @param size number of uninitialized bytes
273 * @return pointer to beginning of uninitialized data
274 */
275always_inline void *
276vlib_buffer_put_uninit (vlib_buffer_t * b, u8 size)
277{
278 void *p = vlib_buffer_get_tail (b);
279 /* XXX make sure there's enough space */
280 b->current_length += size;
281 return p;
282}
283
284/** \brief Prepend uninitialized data to buffer
285 * @param b pointer to the buffer
286 * @param size number of uninitialized bytes
287 * @return pointer to beginning of uninitialized data
288 */
289always_inline void *
290vlib_buffer_push_uninit (vlib_buffer_t * b, u8 size)
291{
292 ASSERT (b->current_data + VLIB_BUFFER_PRE_DATA_SIZE >= size);
293 b->current_data -= size;
294 b->current_length += size;
295
296 return vlib_buffer_get_current (b);
297}
298
299/** \brief Make head room, typically for packet headers
300 * @param b pointer to the buffer
301 * @param size number of head room bytes
302 * @return pointer to start of buffer (current data)
303 */
304always_inline void *
305vlib_buffer_make_headroom (vlib_buffer_t * b, u8 size)
306{
307 ASSERT (b->current_data + VLIB_BUFFER_PRE_DATA_SIZE >= size);
308 b->current_data += size;
309 return vlib_buffer_get_current (b);
310}
311
312/** \brief Retrieve bytes from buffer head
313 * @param b pointer to the buffer
314 * @param size number of bytes to pull
315 * @return pointer to start of buffer (current data)
316 */
317always_inline void *
318vlib_buffer_pull (vlib_buffer_t * b, u8 size)
319{
320 if (b->current_length + VLIB_BUFFER_PRE_DATA_SIZE < size)
321 return 0;
322
323 void *data = vlib_buffer_get_current (b);
324 vlib_buffer_advance (b, size);
325 return data;
326}
327
Ed Warnickecb9cada2015-12-08 15:45:58 -0700328/* Forward declaration. */
329struct vlib_main_t;
330
Dave Barach9b8ffd92016-07-08 08:13:45 -0400331typedef struct vlib_buffer_free_list_t
332{
Ed Warnickecb9cada2015-12-08 15:45:58 -0700333 /* Template buffer used to initialize first 16 bytes of buffers
334 allocated on this free list. */
335 vlib_buffer_t buffer_init_template;
336
337 /* Our index into vlib_main_t's buffer_free_list_pool. */
338 u32 index;
339
340 /* Number of data bytes for buffers in this free list. */
341 u32 n_data_bytes;
342
343 /* Number of buffers to allocate when we need to allocate new buffers
344 from physmem heap. */
345 u32 min_n_buffers_each_physmem_alloc;
346
347 /* Total number of buffers allocated from this free list. */
348 u32 n_alloc;
349
Damjan Marionbd69a5f2017-02-05 23:44:42 +0100350 /* Vector of free buffers. Each element is a byte offset into I/O heap. */
351 u32 *buffers;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700352
Damjan Marionb6a8ed72017-08-29 00:15:35 +0200353 /* global vector of free buffers, used only on main thread.
354 Bufers are returned to global buffers only in case when number of
355 buffers on free buffers list grows about threshold */
356 u32 *global_buffers;
357 clib_spinlock_t global_buffers_lock;
358
Ed Warnickecb9cada2015-12-08 15:45:58 -0700359 /* Memory chunks allocated for this free list
360 recorded here so they can be freed when free list
361 is deleted. */
Dave Barach9b8ffd92016-07-08 08:13:45 -0400362 void **buffer_memory_allocated;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700363
364 /* Free list name. */
Dave Barach9b8ffd92016-07-08 08:13:45 -0400365 u8 *name;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700366
367 /* Callback functions to initialize newly allocated buffers.
368 If null buffers are zeroed. */
Dave Barach9b8ffd92016-07-08 08:13:45 -0400369 void (*buffer_init_function) (struct vlib_main_t * vm,
370 struct vlib_buffer_free_list_t * fl,
371 u32 * buffers, u32 n_buffers);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700372
373 /* Callback function to announce that buffers have been
374 added to the freelist */
Dave Barach9b8ffd92016-07-08 08:13:45 -0400375 void (*buffers_added_to_freelist_function)
376 (struct vlib_main_t * vm, struct vlib_buffer_free_list_t * fl);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700377
378 uword buffer_init_function_opaque;
379} __attribute__ ((aligned (16))) vlib_buffer_free_list_t;
380
Dave Barach9b8ffd92016-07-08 08:13:45 -0400381typedef struct
382{
Damjan Marion878c6092017-01-04 13:19:27 +0100383 u32 (*vlib_buffer_alloc_cb) (struct vlib_main_t * vm, u32 * buffers,
384 u32 n_buffers);
385 u32 (*vlib_buffer_alloc_from_free_list_cb) (struct vlib_main_t * vm,
386 u32 * buffers, u32 n_buffers,
387 u32 free_list_index);
388 void (*vlib_buffer_free_cb) (struct vlib_main_t * vm, u32 * buffers,
389 u32 n_buffers);
390 void (*vlib_buffer_free_no_next_cb) (struct vlib_main_t * vm, u32 * buffers,
391 u32 n_buffers);
392 void (*vlib_packet_template_init_cb) (struct vlib_main_t * vm, void *t,
393 void *packet_data,
394 uword n_packet_data_bytes,
395 uword
396 min_n_buffers_each_physmem_alloc,
397 u8 * name);
398 void (*vlib_buffer_delete_free_list_cb) (struct vlib_main_t * vm,
399 u32 free_list_index);
400} vlib_buffer_callbacks_t;
401
Damjan Marion04a7f052017-07-10 15:06:17 +0200402extern vlib_buffer_callbacks_t *vlib_buffer_callbacks;
403
Damjan Marion878c6092017-01-04 13:19:27 +0100404typedef struct
405{
Damjan Marion04a7f052017-07-10 15:06:17 +0200406 CLIB_CACHE_LINE_ALIGN_MARK (cacheline0);
407 /* Virtual memory address and size of buffer memory, used for calculating
408 buffer index */
409 uword buffer_mem_start;
410 uword buffer_mem_size;
411
Ed Warnickecb9cada2015-12-08 15:45:58 -0700412 /* Buffer free callback, for subversive activities */
Damjan Marion04a7f052017-07-10 15:06:17 +0200413 u32 (*buffer_free_callback) (struct vlib_main_t * vm,
414 u32 * buffers,
415 u32 n_buffers, u32 follow_buffer_next);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700416 /* Pool of buffer free lists.
417 Multiple free lists exist for packet generator which uses
418 separate free lists for each packet stream --- so as to avoid
419 initializing static data for each packet generated. */
Dave Barach9b8ffd92016-07-08 08:13:45 -0400420 vlib_buffer_free_list_t *buffer_free_list_pool;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700421#define VLIB_BUFFER_DEFAULT_FREE_LIST_INDEX (0)
Damjan Marion19010202016-03-24 17:17:47 +0100422#define VLIB_BUFFER_DEFAULT_FREE_LIST_BYTES VLIB_BUFFER_DATA_SIZE
Ed Warnickecb9cada2015-12-08 15:45:58 -0700423
424 /* Hash table mapping buffer size (rounded to next unit of
425 sizeof (vlib_buffer_t)) to free list index. */
Dave Barach9b8ffd92016-07-08 08:13:45 -0400426 uword *free_list_by_size;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700427
428 /* Hash table mapping buffer index into number
429 0 => allocated but free, 1 => allocated and not-free.
430 If buffer index is not in hash table then this buffer
431 has never been allocated. */
Dave Barach9b8ffd92016-07-08 08:13:45 -0400432 uword *buffer_known_hash;
Damjan Marion6b0f5892017-07-27 04:01:24 -0400433 clib_spinlock_t buffer_known_hash_lockp;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700434
435 /* List of free-lists needing Blue Light Special announcements */
436 vlib_buffer_free_list_t **announce_list;
437
Damjan Marion878c6092017-01-04 13:19:27 +0100438 /* Callbacks */
439 vlib_buffer_callbacks_t cb;
Damjan Marion04a7f052017-07-10 15:06:17 +0200440 int callbacks_registered;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700441} vlib_buffer_main_t;
442
Damjan Marion04a7f052017-07-10 15:06:17 +0200443void vlib_buffer_add_mem_range (struct vlib_main_t *vm, uword start,
444 uword size);
Damjan Marion878c6092017-01-04 13:19:27 +0100445void vlib_buffer_cb_init (struct vlib_main_t *vm);
Damjan Marion878c6092017-01-04 13:19:27 +0100446
Dave Barach9b8ffd92016-07-08 08:13:45 -0400447typedef struct
448{
449 struct vlib_main_t *vlib_main;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700450
451 u32 first_buffer, last_buffer;
452
Dave Barach9b8ffd92016-07-08 08:13:45 -0400453 union
454 {
455 struct
456 {
Ed Warnickecb9cada2015-12-08 15:45:58 -0700457 /* Total accumulated bytes in chain starting with first_buffer. */
458 u32 n_total_data_bytes;
459
460 /* Max number of bytes to accumulate in chain starting with first_buffer.
Dave Barach9b8ffd92016-07-08 08:13:45 -0400461 As this limit is reached buffers are enqueued to next node. */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700462 u32 max_n_data_bytes_per_chain;
463
464 /* Next node to enqueue buffers to relative to current process node. */
465 u32 next_index;
466
467 /* Free list to use to allocate new buffers. */
468 u32 free_list_index;
469 } tx;
470
Dave Barach9b8ffd92016-07-08 08:13:45 -0400471 struct
472 {
Ed Warnickecb9cada2015-12-08 15:45:58 -0700473 /* CLIB fifo of buffer indices waiting to be unserialized. */
Dave Barach9b8ffd92016-07-08 08:13:45 -0400474 u32 *buffer_fifo;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700475
476 /* Event type used to signal that RX buffers have been added to fifo. */
477 uword ready_one_time_event;
478 } rx;
479 };
480} vlib_serialize_buffer_main_t;
481
Dave Barach9b8ffd92016-07-08 08:13:45 -0400482void serialize_open_vlib_buffer (serialize_main_t * m, struct vlib_main_t *vm,
483 vlib_serialize_buffer_main_t * sm);
484void unserialize_open_vlib_buffer (serialize_main_t * m,
485 struct vlib_main_t *vm,
486 vlib_serialize_buffer_main_t * sm);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700487
488u32 serialize_close_vlib_buffer (serialize_main_t * m);
489void unserialize_close_vlib_buffer (serialize_main_t * m);
490void *vlib_set_buffer_free_callback (struct vlib_main_t *vm, void *fp);
491
492always_inline u32
493serialize_vlib_buffer_n_bytes (serialize_main_t * m)
494{
Dave Barach9b8ffd92016-07-08 08:13:45 -0400495 serialize_stream_t *s = &m->stream;
496 vlib_serialize_buffer_main_t *sm
497 = uword_to_pointer (m->stream.data_function_opaque,
498 vlib_serialize_buffer_main_t *);
499 return sm->tx.n_total_data_bytes + s->current_buffer_index +
500 vec_len (s->overflow_buffer);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700501}
502
Ed Warnickecb9cada2015-12-08 15:45:58 -0700503/*
504 */
505
506/** \brief Compile time buffer trajectory tracing option
Dave Barach9b8ffd92016-07-08 08:13:45 -0400507 Turn this on if you run into "bad monkey" contexts,
508 and you want to know exactly which nodes they've visited...
Ed Warnickecb9cada2015-12-08 15:45:58 -0700509 See vlib/main.c...
510*/
511#define VLIB_BUFFER_TRACE_TRAJECTORY 0
512
513#if VLIB_BUFFER_TRACE_TRAJECTORY > 0
514#define VLIB_BUFFER_TRACE_TRAJECTORY_INIT(b) (b)->pre_data[0]=0
Dave Barach9b8ffd92016-07-08 08:13:45 -0400515#else
Ed Warnickecb9cada2015-12-08 15:45:58 -0700516#define VLIB_BUFFER_TRACE_TRAJECTORY_INIT(b)
517#endif /* VLIB_BUFFER_TRACE_TRAJECTORY */
518
519#endif /* included_vlib_buffer_h */
Dave Barach9b8ffd92016-07-08 08:13:45 -0400520
Damjan Marion04a7f052017-07-10 15:06:17 +0200521#define VLIB_BUFFER_REGISTER_CALLBACKS(x,...) \
522 __VA_ARGS__ vlib_buffer_callbacks_t __##x##_buffer_callbacks; \
523static void __vlib_add_buffer_callbacks_t_##x (void) \
524 __attribute__((__constructor__)) ; \
525static void __vlib_add_buffer_callbacks_t_##x (void) \
526{ \
527 if (vlib_buffer_callbacks) \
528 clib_panic ("vlib buffer callbacks already registered"); \
529 vlib_buffer_callbacks = &__##x##_buffer_callbacks; \
530} \
531__VA_ARGS__ vlib_buffer_callbacks_t __##x##_buffer_callbacks
532
Dave Barach9b8ffd92016-07-08 08:13:45 -0400533/*
534 * fd.io coding-style-patch-verification: ON
535 *
536 * Local Variables:
537 * eval: (c-set-style "gnu")
538 * End:
539 */