VPP-598: tcp stack initial commit
[vpp.git] / src / vlib / buffer.h
index d270c08..69c8c7c 100644 (file)
 #define VLIB_BUFFER_DATA_SIZE          (2048)
 #define VLIB_BUFFER_PRE_DATA_SIZE      __PRE_DATA_SIZE
 
-#if defined (CLIB_HAVE_VEC128) || defined (__aarch64__)
-typedef u8x16 vlib_copy_unit_t;
-#else
-typedef u64 vlib_copy_unit_t;
-#endif
-
 /** \file
     vlib buffer structure definition and a few select
     access methods. This structure and the buffer allocation
@@ -67,6 +61,7 @@ typedef u64 vlib_copy_unit_t;
 typedef struct
 {
   CLIB_CACHE_LINE_ALIGN_MARK (cacheline0);
+  STRUCT_MARK (template_start);
   /* Offset within data[] that we are currently processing.
      If negative current header points into predata area. */
   i16 current_data;  /**< signed offset in data[], pre_data[]
@@ -83,6 +78,7 @@ typedef struct
                 <br> VLIB_BUFFER_REPL_FAIL: packet replication failure
                 <br> VLIB_BUFFER_RECYCLE: as it says
                 <br> VLIB_BUFFER_FLOW_REPORT: buffer is a flow report,
+                <br> VLIB_BUFFER_EXT_HDR_VALID: buffer contains valid external buffer manager header,
                 set to avoid adding it to a flow report
                 <br> VLIB_BUFFER_FLAG_USER(n): user-defined bit N
              */
@@ -94,6 +90,7 @@ typedef struct
 #define VLIB_BUFFER_REPL_FAIL (1 << 4)
 #define VLIB_BUFFER_RECYCLE (1 << 5)
 #define VLIB_BUFFER_FLOW_REPORT (1 << 6)
+#define VLIB_BUFFER_EXT_HDR_VALID (1 << 7)
 
   /* User defined buffer flags. */
 #define LOG2_VLIB_BUFFER_FLAG_USER(n) (32 - (n))
@@ -107,6 +104,7 @@ typedef struct
   /**< Only valid for first buffer in chain. Current length plus
      total length given here give total number of bytes in buffer chain.
   */
+    STRUCT_MARK (template_end);
 
   u32 next_buffer;   /**< Next buffer for this linked-list of buffers.
                         Only valid if VLIB_BUFFER_NEXT_PRESENT flag is set.
@@ -123,7 +121,9 @@ typedef struct
                            feature node
                         */
 
-  u8 dont_waste_me[3]; /**< Available space in the (precious)
+  u8 n_add_refs; /**< Number of additional references to this buffer. */
+
+  u8 dont_waste_me[2]; /**< Available space in the (precious)
                           first 32 octets of buffer metadata
                           Before allocating any of it, discussion required!
                        */
@@ -240,6 +240,74 @@ vlib_get_buffer_opaque2 (vlib_buffer_t * b)
   return (void *) b->opaque2;
 }
 
+/** \brief Get pointer to the end of buffer's data
+ * @param b     pointer to the buffer
+ * @return      pointer to tail of packet's data
+ */
+always_inline u8 *
+vlib_buffer_get_tail (vlib_buffer_t * b)
+{
+  return b->data + b->current_data + b->current_length;
+}
+
+/** \brief Append uninitialized data to buffer
+ * @param b     pointer to the buffer
+ * @param size  number of uninitialized bytes
+ * @return      pointer to beginning of uninitialized data
+ */
+always_inline void *
+vlib_buffer_put_uninit (vlib_buffer_t * b, u8 size)
+{
+  void *p = vlib_buffer_get_tail (b);
+  /* XXX make sure there's enough space */
+  b->current_length += size;
+  return p;
+}
+
+/** \brief Prepend uninitialized data to buffer
+ * @param b     pointer to the buffer
+ * @param size  number of uninitialized bytes
+ * @return      pointer to beginning of uninitialized data
+ */
+always_inline void *
+vlib_buffer_push_uninit (vlib_buffer_t * b, u8 size)
+{
+  ASSERT (b->current_data + VLIB_BUFFER_PRE_DATA_SIZE >= size);
+  b->current_data -= size;
+  b->current_length += size;
+
+  return vlib_buffer_get_current (b);
+}
+
+/** \brief Make head room, typically for packet headers
+ * @param b     pointer to the buffer
+ * @param size  number of head room bytes
+ * @return      pointer to start of buffer (current data)
+ */
+always_inline void *
+vlib_buffer_make_headroom (vlib_buffer_t * b, u8 size)
+{
+  ASSERT (b->current_data + VLIB_BUFFER_PRE_DATA_SIZE >= size);
+  b->current_data += size;
+  return vlib_buffer_get_current (b);
+}
+
+/** \brief Retrieve bytes from buffer head
+ * @param b     pointer to the buffer
+ * @param size  number of bytes to pull
+ * @return      pointer to start of buffer (current data)
+ */
+always_inline void *
+vlib_buffer_pull (vlib_buffer_t * b, u8 size)
+{
+  if (b->current_length + VLIB_BUFFER_PRE_DATA_SIZE < size)
+    return 0;
+
+  void *data = vlib_buffer_get_current (b);
+  vlib_buffer_advance (b, size);
+  return data;
+}
+
 /* Forward declaration. */
 struct vlib_main_t;
 
@@ -262,11 +330,8 @@ typedef struct vlib_buffer_free_list_t
   /* Total number of buffers allocated from this free list. */
   u32 n_alloc;
 
-  /* Vector of free buffers.  Each element is a byte offset into I/O heap.
-     Aligned vectors always has naturally aligned vlib_copy_unit_t sized chunks
-     of buffer indices.  Unaligned vector has any left over.  This is meant to
-     speed up copy routines. */
-  u32 *aligned_buffers, *unaligned_buffers;
+  /* Vector of free buffers.  Each element is a byte offset into I/O heap. */
+  u32 *buffers;
 
   /* Memory chunks allocated for this free list
      recorded here so they can be freed when free list