+ vlib_buffer_main_t *bm = vm->buffer_main;
+ vlib_buffer_t *b;
+
+ b = vlib_buffer_ptr_from_index (bm->buffer_mem_start, buffer_index, 0);
+ vlib_buffer_validate (vm, b);
+ return b;
+}
+
+static_always_inline u32
+vlib_buffer_get_default_data_size (vlib_main_t * vm)
+{
+ return vm->buffer_main->default_data_size;
+}
+
+static_always_inline void
+vlib_buffer_copy_indices (u32 * dst, u32 * src, u32 n_indices)
+{
+ clib_memcpy_u32 (dst, src, n_indices);
+}
+
+always_inline void
+vlib_buffer_copy_indices_from_ring (u32 * dst, u32 * ring, u32 start,
+ u32 ring_size, u32 n_buffers)
+{
+ ASSERT (n_buffers <= ring_size);
+
+ if (PREDICT_TRUE (start + n_buffers <= ring_size))
+ {
+ vlib_buffer_copy_indices (dst, ring + start, n_buffers);
+ }
+ else
+ {
+ u32 n = ring_size - start;
+ vlib_buffer_copy_indices (dst, ring + start, n);
+ vlib_buffer_copy_indices (dst + n, ring, n_buffers - n);
+ }
+}
+
+always_inline void
+vlib_buffer_copy_indices_to_ring (u32 * ring, u32 * src, u32 start,
+ u32 ring_size, u32 n_buffers)
+{
+ ASSERT (n_buffers <= ring_size);
+
+ if (PREDICT_TRUE (start + n_buffers <= ring_size))
+ {
+ vlib_buffer_copy_indices (ring + start, src, n_buffers);
+ }
+ else
+ {
+ u32 n = ring_size - start;
+ vlib_buffer_copy_indices (ring + start, src, n);
+ vlib_buffer_copy_indices (ring, src + n, n_buffers - n);
+ }
+}
+
+STATIC_ASSERT_OFFSET_OF (vlib_buffer_t, template_end, 64);
+static_always_inline void
+vlib_buffer_copy_template (vlib_buffer_t * b, vlib_buffer_t * bt)
+{
+#if defined CLIB_HAVE_VEC512
+ b->as_u8x64[0] = bt->as_u8x64[0];
+#elif defined (CLIB_HAVE_VEC256)
+ b->as_u8x32[0] = bt->as_u8x32[0];
+ b->as_u8x32[1] = bt->as_u8x32[1];
+#elif defined (CLIB_HAVE_VEC128)
+ b->as_u8x16[0] = bt->as_u8x16[0];
+ b->as_u8x16[1] = bt->as_u8x16[1];
+ b->as_u8x16[2] = bt->as_u8x16[2];
+ b->as_u8x16[3] = bt->as_u8x16[3];
+#else
+ clib_memcpy_fast (b, bt, 64);
+#endif
+}
+
+always_inline u8
+vlib_buffer_pool_get_default_for_numa (vlib_main_t * vm, u32 numa_node)
+{
+ ASSERT (numa_node < VLIB_BUFFER_MAX_NUMA_NODES);
+ return vm->buffer_main->default_buffer_pool_index_for_numa[numa_node];
+}
+
+/** \brief Translate array of buffer indices into buffer pointers with offset
+
+ @param vm - (vlib_main_t *) vlib main data structure pointer
+ @param bi - (u32 *) array of buffer indices
+ @param b - (void **) array to store buffer pointers
+ @param count - (uword) number of elements
+ @param offset - (i32) offset applied to each pointer
+*/
+static_always_inline void
+vlib_get_buffers_with_offset (vlib_main_t *vm, u32 *bi, void **b, u32 count,
+ i32 offset)
+{
+ uword buffer_mem_start = vm->buffer_main->buffer_mem_start;
+ void *base = (void *) (buffer_mem_start + offset);
+ int objsize = __builtin_object_size (b, 0);
+ const int sh = CLIB_LOG2_CACHE_LINE_BYTES;
+
+ if (COMPILE_TIME_CONST (count) == 0 && objsize >= 64 * sizeof (b[0]) &&
+ (objsize & ((8 * sizeof (b[0])) - 1)) == 0)
+ {
+ u32 n = round_pow2 (count, 8);
+ ASSERT (objsize >= count);
+ CLIB_ASSUME (objsize >= count);
+ while (n >= 64)
+ {
+ clib_index_to_ptr_u32 (bi, base, sh, b, 64);
+ b += 64;
+ bi += 64;
+ n -= 64;
+ }
+
+ while (n)
+ {
+ clib_index_to_ptr_u32 (bi, base, sh, b, 8);
+ b += 8;
+ bi += 8;
+ n -= 8;
+ }
+ }
+ else
+ clib_index_to_ptr_u32 (bi, base, sh, b, count);
+}
+
+/** \brief Translate array of buffer indices into buffer pointers
+
+ @param vm - (vlib_main_t *) vlib main data structure pointer
+ @param bi - (u32 *) array of buffer indices
+ @param b - (vlib_buffer_t **) array to store buffer pointers
+ @param count - (uword) number of elements
+*/
+
+static_always_inline void
+vlib_get_buffers (vlib_main_t *vm, u32 *bi, vlib_buffer_t **b, u32 count)
+{
+ vlib_get_buffers_with_offset (vm, bi, (void **) b, count, 0);