X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvlib%2Fbuffer.h;h=69c8c7ccb093f2131baf5f1cd0060116494acde2;hb=68b0fb0c620c7451ef1a6380c43c39de6614db51;hp=fffb50c8fe5c194a4d847025e324d355a1efda56;hpb=bd69a5f24c6e83e9101f203dd124864fb2877a17;p=vpp.git diff --git a/src/vlib/buffer.h b/src/vlib/buffer.h index fffb50c8fe5..69c8c7ccb09 100644 --- a/src/vlib/buffer.h +++ b/src/vlib/buffer.h @@ -61,6 +61,7 @@ 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[] @@ -77,6 +78,7 @@ typedef struct
VLIB_BUFFER_REPL_FAIL: packet replication failure
VLIB_BUFFER_RECYCLE: as it says
VLIB_BUFFER_FLOW_REPORT: buffer is a flow report, +
VLIB_BUFFER_EXT_HDR_VALID: buffer contains valid external buffer manager header, set to avoid adding it to a flow report
VLIB_BUFFER_FLAG_USER(n): user-defined bit N */ @@ -88,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)) @@ -101,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. @@ -117,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! */ @@ -234,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;