+ size = round_pow2 (sizeof (vlib_frame_t), VLIB_FRAME_DATA_ALIGN);
+
+ /* scalar data size */
+ if (r->scalar_size)
+ {
+ n->scalar_offset = size;
+ size += round_pow2 (r->scalar_size, VLIB_FRAME_DATA_ALIGN);
+ }
+ else
+ n->scalar_offset = 0;
+
+ /* Vecor data size */
+ n->vector_offset = size;
+ size += r->vector_size * VLIB_FRAME_SIZE;
+
+ /* Allocate a few extra slots of vector data to support
+ speculative vector enqueues which overflow vector data in next frame. */
+ size += r->vector_size * VLIB_FRAME_SIZE_EXTRA;
+
+ /* space for VLIB_FRAME_MAGIC */
+ n->magic_offset = size;
+ size += sizeof (u32);
+
+ /* round size to VLIB_FRAME_DATA_ALIGN */
+ size = round_pow2 (size, VLIB_FRAME_DATA_ALIGN);
+
+ if (r->aux_size)
+ {
+ n->aux_offset = size;
+ size += r->aux_size * VLIB_FRAME_SIZE;
+ }
+ else
+ n->aux_offset = 0;
+
+ /* final size */
+ n->frame_size = size = round_pow2 (size, CLIB_CACHE_LINE_BYTES);
+ ASSERT (size <= __UINT16_MAX__);
+
+ vlib_frame_size_t *fs = 0;
+
+ n->frame_size_index = (u16) ~0;
+ vec_foreach (fs, nm->frame_sizes)
+ if (fs->frame_size == size)
+ {
+ n->frame_size_index = fs - nm->frame_sizes;
+ break;
+ }
+
+ if (n->frame_size_index == (u16) ~0)
+ {
+ vec_add2 (nm->frame_sizes, fs, 1);
+ fs->frame_size = size;
+ n->frame_size_index = fs - nm->frame_sizes;
+ }
+