Introduce l{2,3,4}_hdr_offset fields in the buffer metadata

To save space in the first cacheline following is changed:

- total_length_not_including_first_buffer moved to the 2nd cacheline.
This field is used only when VLIB_BUFFER_TOTAL_LENGTH_VALID and
VLIB_BUFFER_NEXT_PRESENT are both set.

- free_list_index is now stored in 4bits inside flags, which
allows up to 16 free lists. In case we need more we can store index
in the 2nd cachelin

Change-Id: Ic8521350819391af470d31d3fa1013e67ecb7681
Signed-off-by: Damjan Marion <damarion@cisco.com>
diff --git a/src/plugins/dpdk/device/node.c b/src/plugins/dpdk/device/node.c
index 69acc52..74fb8da 100644
--- a/src/plugins/dpdk/device/node.c
+++ b/src/plugins/dpdk/device/node.c
@@ -208,7 +208,13 @@
   mb_seg = mb->next;
   b_chain = b;
 
-  while ((mb->nb_segs > 1) && (nb_seg < mb->nb_segs))
+  if (mb->nb_segs < 2)
+    return;
+
+  b->flags |= VLIB_BUFFER_TOTAL_LENGTH_VALID;
+  b->total_length_not_including_first_buffer = 0;
+
+  while (nb_seg < mb->nb_segs)
     {
       ASSERT (mb_seg != 0);
 
diff --git a/src/vlib/buffer.c b/src/vlib/buffer.c
index b2a095c..53b60c1 100644
--- a/src/vlib/buffer.c
+++ b/src/vlib/buffer.c
@@ -72,8 +72,8 @@
   uword indent = format_get_indent (s);
 
   s = format (s, "current data %d, length %d, free-list %d, clone-count %u",
-	      b->current_data, b->current_length, b->free_list_index,
-	      b->n_add_refs);
+	      b->current_data, b->current_length,
+	      vlib_buffer_get_free_list_index (b), b->n_add_refs);
 
   if (b->flags & VLIB_BUFFER_TOTAL_LENGTH_VALID)
     s = format (s, ", totlen-nifb %d",
@@ -163,10 +163,14 @@
   vlib_buffer_main_t *bm = vm->buffer_main;
   vlib_buffer_free_list_t *fl;
 
-  if (pool_is_free_index (bm->buffer_free_list_pool, b->free_list_index))
-    return format (0, "unknown free list 0x%x", b->free_list_index);
+  if (pool_is_free_index
+      (bm->buffer_free_list_pool, vlib_buffer_get_free_list_index (b)))
+    return format (0, "unknown free list 0x%x",
+		   vlib_buffer_get_free_list_index (b));
 
-  fl = pool_elt_at_index (bm->buffer_free_list_pool, b->free_list_index);
+  fl =
+    pool_elt_at_index (bm->buffer_free_list_pool,
+		       vlib_buffer_get_free_list_index (b));
 
   if ((signed) b->current_data < (signed) -VLIB_BUFFER_PRE_DATA_SIZE)
     return format (0, "current data %d before pre-data", b->current_data);
@@ -388,7 +392,7 @@
   f->name = clib_mem_is_vec (name) ? name : format (0, "%s", name);
 
   /* Setup free buffer template. */
-  f->buffer_init_template.free_list_index = f->index;
+  vlib_buffer_set_free_list_index (&f->buffer_init_template, f->index);
   f->buffer_init_template.n_add_refs = 0;
 
   if (is_public)
diff --git a/src/vlib/buffer.h b/src/vlib/buffer.h
index b20538b..c810db4 100644
--- a/src/vlib/buffer.h
+++ b/src/vlib/buffer.h
@@ -72,6 +72,7 @@
                           the end of this buffer.
                        */
   u32 flags; /**< buffer flags:
+                <br> VLIB_BUFFER_FREE_LIST_INDEX_MASK: bits used to store free list index,
                 <br> VLIB_BUFFER_IS_TRACED: trace this buffer.
                 <br> VLIB_BUFFER_NEXT_PRESENT: this is a multi-chunk buffer.
                 <br> VLIB_BUFFER_TOTAL_LENGTH_VALID: as it says
@@ -82,28 +83,26 @@
                 set to avoid adding it to a flow report
                 <br> VLIB_BUFFER_FLAG_USER(n): user-defined bit N
              */
-#define VLIB_BUFFER_IS_TRACED (1 << 0)
-#define VLIB_BUFFER_LOG2_NEXT_PRESENT (1)
+
+/* any change to the following line requres update of
+ * vlib_buffer_get_free_list_index(...) and
+ * vlib_buffer_set_free_list_index(...) functions */
+#define VLIB_BUFFER_FREE_LIST_INDEX_MASK ((1 << 4) - 1)
+
+#define VLIB_BUFFER_IS_TRACED (1 << 4)
+#define VLIB_BUFFER_LOG2_NEXT_PRESENT (5)
 #define VLIB_BUFFER_NEXT_PRESENT (1 << VLIB_BUFFER_LOG2_NEXT_PRESENT)
-#define VLIB_BUFFER_IS_RECYCLED (1 << 2)
-#define VLIB_BUFFER_TOTAL_LENGTH_VALID (1 << 3)
-#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)
+#define VLIB_BUFFER_IS_RECYCLED (1 << 6)
+#define VLIB_BUFFER_TOTAL_LENGTH_VALID (1 << 7)
+#define VLIB_BUFFER_REPL_FAIL (1 << 8)
+#define VLIB_BUFFER_RECYCLE (1 << 9)
+#define VLIB_BUFFER_FLOW_REPORT (1 << 10)
+#define VLIB_BUFFER_EXT_HDR_VALID (1 << 11)
 
   /* User defined buffer flags. */
 #define LOG2_VLIB_BUFFER_FLAG_USER(n) (32 - (n))
 #define VLIB_BUFFER_FLAG_USER(n) (1 << LOG2_VLIB_BUFFER_FLAG_USER(n))
 
-  u32 free_list_index; /**< Buffer free list that this buffer was
-                          allocated from and will be freed to.
-                       */
-
-  u32 total_length_not_including_first_buffer;
-  /**< 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.
@@ -128,7 +127,7 @@
                           Before allocating any of it, discussion required!
                        */
 
-  u32 opaque[8]; /**< Opaque data used by sub-graphs for their own purposes.
+  u32 opaque[10]; /**< Opaque data used by sub-graphs for their own purposes.
                     See .../vnet/vnet/buffer.h
                  */
     CLIB_CACHE_LINE_ALIGN_MARK (cacheline1);
@@ -137,7 +136,12 @@
                       if VLIB_PACKET_IS_TRACED flag is set.
                    */
   u32 recycle_count; /**< Used by L2 path recycle code */
-  u32 opaque2[14];  /**< More opaque data, currently unused */
+
+  u32 total_length_not_including_first_buffer;
+  /**< Only valid for first buffer in chain. Current length plus
+     total length given here give total number of bytes in buffer chain.
+  */
+  u32 opaque2[13];  /**< More opaque data, currently unused */
 
   /***** end of second cache line */
     CLIB_CACHE_LINE_ALIGN_MARK (cacheline2);
diff --git a/src/vlib/buffer_funcs.h b/src/vlib/buffer_funcs.h
index 97442e1..1aaac0b 100644
--- a/src/vlib/buffer_funcs.h
+++ b/src/vlib/buffer_funcs.h
@@ -106,12 +106,15 @@
 always_inline uword
 vlib_buffer_length_in_chain (vlib_main_t * vm, vlib_buffer_t * b)
 {
-  uword l = b->current_length + b->total_length_not_including_first_buffer;
-  if (PREDICT_FALSE ((b->flags & (VLIB_BUFFER_NEXT_PRESENT
-				  | VLIB_BUFFER_TOTAL_LENGTH_VALID))
-		     == VLIB_BUFFER_NEXT_PRESENT))
-    return vlib_buffer_length_in_chain_slow_path (vm, b);
-  return l;
+  uword len = b->current_length;
+
+  if (PREDICT_TRUE ((b->flags & VLIB_BUFFER_NEXT_PRESENT) == 0))
+    return len;
+
+  if (PREDICT_TRUE (b->flags & VLIB_BUFFER_TOTAL_LENGTH_VALID))
+    return len + b->total_length_not_including_first_buffer;
+
+  return vlib_buffer_length_in_chain_slow_path (vm, b);
 }
 
 /** \brief Get length in bytes of the buffer index buffer chain
@@ -261,6 +264,24 @@
   return round_pow2 (size, sizeof (vlib_buffer_t));
 }
 
+always_inline u32
+vlib_buffer_get_free_list_index (vlib_buffer_t * b)
+{
+  return b->flags & VLIB_BUFFER_FREE_LIST_INDEX_MASK;
+}
+
+always_inline void
+vlib_buffer_set_free_list_index (vlib_buffer_t * b, u32 index)
+{
+  /* if there is an need for more free lists we should consider
+     storig data in the 2nd cacheline */
+  ASSERT (VLIB_BUFFER_FREE_LIST_INDEX_MASK & 1);
+  ASSERT (index <= VLIB_BUFFER_FREE_LIST_INDEX_MASK);
+
+  b->flags &= ~VLIB_BUFFER_FREE_LIST_INDEX_MASK;
+  b->flags |= index & VLIB_BUFFER_FREE_LIST_INDEX_MASK;
+}
+
 /** \brief Allocate buffers from specific freelist into supplied array
 
     @param vm - (vlib_main_t *) vlib main data structure pointer
@@ -381,7 +402,7 @@
   vlib_buffer_main_t *bm = vm->buffer_main;
   u32 i;
 
-  *index = i = b->free_list_index;
+  *index = i = vlib_buffer_get_free_list_index (b);
   return pool_elt_at_index (bm->buffer_free_list_pool, i);
 }
 
@@ -569,7 +590,8 @@
     }
 
   n_buffers = vlib_buffer_alloc_from_free_list (vm, buffers, n_buffers,
-						s->free_list_index);
+						vlib_buffer_get_free_list_index
+						(s));
   if (PREDICT_FALSE (n_buffers == 0))
     {
       buffers[0] = src_buffer;
@@ -581,7 +603,8 @@
       vlib_buffer_t *d = vlib_get_buffer (vm, buffers[i]);
       d->current_data = s->current_data;
       d->current_length = head_end_offset;
-      d->free_list_index = s->free_list_index;
+      vlib_buffer_set_free_list_index (d,
+				       vlib_buffer_get_free_list_index (s));
       d->total_length_not_including_first_buffer =
 	s->total_length_not_including_first_buffer + s->current_length -
 	head_end_offset;
@@ -615,7 +638,8 @@
 			  vlib_buffer_t * tail)
 {
   ASSERT ((head->flags & VLIB_BUFFER_NEXT_PRESENT) == 0);
-  ASSERT (head->free_list_index == tail->free_list_index);
+  ASSERT (vlib_buffer_get_free_list_index (head) ==
+	  vlib_buffer_get_free_list_index (tail));
 
   head->flags |= VLIB_BUFFER_NEXT_PRESENT;
   head->flags &= ~VLIB_BUFFER_TOTAL_LENGTH_VALID;
@@ -791,7 +815,7 @@
 	  CLIB_CACHE_LINE_BYTES * 2);
 
   /* Make sure buffer template is sane. */
-  ASSERT (fl->index == fl->buffer_init_template.free_list_index);
+  ASSERT (fl->index == vlib_buffer_get_free_list_index (src));
 
   clib_memcpy (STRUCT_MARK_PTR (dst, template_start),
 	       STRUCT_MARK_PTR (src, template_start),
@@ -806,7 +830,6 @@
   _(current_data);
   _(current_length);
   _(flags);
-  _(free_list_index);
 #undef _
   ASSERT (dst->total_length_not_including_first_buffer == 0);
   ASSERT (dst->n_add_refs == 0);
@@ -832,7 +855,7 @@
   vlib_buffer_t *src = &fl->buffer_init_template;
 
   /* Make sure buffer template is sane. */
-  ASSERT (fl->index == fl->buffer_init_template.free_list_index);
+  ASSERT (fl->index == vlib_buffer_get_free_list_index (src));
 
   clib_memcpy (STRUCT_MARK_PTR (dst0, template_start),
 	       STRUCT_MARK_PTR (src, template_start),
@@ -853,7 +876,6 @@
   _(current_data);
   _(current_length);
   _(flags);
-  _(free_list_index);
 #undef _
 
   ASSERT (dst0->total_length_not_including_first_buffer == 0);
diff --git a/src/vnet/bfd/bfd_udp.c b/src/vnet/bfd/bfd_udp.c
index 346c549..06b843c 100644
--- a/src/vnet/bfd/bfd_udp.c
+++ b/src/vnet/bfd/bfd_udp.c
@@ -843,7 +843,7 @@
 		       udp_header_t ** udp)
 {
   /* sanity check first */
-  const i32 start = vnet_buffer (b)->ip.start_of_ip_header;
+  const i32 start = vnet_buffer (b)->l3_hdr_offset;
   if (start < 0 && start < sizeof (b->pre_data))
     {
       BFD_ERR ("Start of ip header is before pre_data, ignoring");
@@ -1000,7 +1000,7 @@
 		       udp_header_t ** udp)
 {
   /* sanity check first */
-  const i32 start = vnet_buffer (b)->ip.start_of_ip_header;
+  const i32 start = vnet_buffer (b)->l3_hdr_offset;
   if (start < 0 && start < sizeof (b->pre_data))
     {
       BFD_ERR ("Start of ip header is before pre_data, ignoring");
diff --git a/src/vnet/buffer.h b/src/vnet/buffer.h
index 9aba34d..8647db0 100644
--- a/src/vnet/buffer.h
+++ b/src/vnet/buffer.h
@@ -71,7 +71,6 @@
 #define VNET_BUFFER_SPAN_CLONE (1 << LOG2_VNET_BUFFER_SPAN_CLONE)
 
 #define foreach_buffer_opaque_union_subtype     \
-_(ethernet)                                     \
 _(ip)                                           \
 _(swt)                                          \
 _(l2)                                           \
@@ -100,16 +99,12 @@
 typedef struct
 {
   u32 sw_if_index[VLIB_N_RX_TX];
+  i16 l2_hdr_offset;
+  i16 l3_hdr_offset;
+  i16 l4_hdr_offset;
 
   union
   {
-    /* Ethernet. */
-    struct
-    {
-      /* Saved value of current header by ethernet-input. */
-      i32 start_of_ethernet_header;
-    } ethernet;
-
     /* IP4/6 buffer opaque. */
     struct
     {
@@ -143,9 +138,6 @@
 	  u8 code;
 	  u32 data;
 	} icmp;
-
-	/* IP header offset from vlib_buffer.data - saved by ip*_local nodes */
-	i32 start_of_ip_header;
       };
 
     } ip;
diff --git a/src/vnet/dhcp/dhcp4_proxy_node.c b/src/vnet/dhcp/dhcp4_proxy_node.c
index 26e1e65..1b59cde 100644
--- a/src/vnet/dhcp/dhcp4_proxy_node.c
+++ b/src/vnet/dhcp/dhcp4_proxy_node.c
@@ -231,7 +231,7 @@
               o = (dhcp_option_t *) (((uword) o) + (o->length + 2));
           }
 
-          fl = vlib_buffer_get_free_list (vm, b0->free_list_index);
+          fl = vlib_buffer_get_free_list (vm, vlib_buffer_get_free_list_index (b0));
           // start write at (option*)o, some packets have padding
           if (((u8 *)o - (u8 *)b0->data + VPP_DHCP_OPTION82_SIZE) > fl->n_data_bytes)
           {
diff --git a/src/vnet/dhcp/dhcp6_proxy_node.c b/src/vnet/dhcp/dhcp6_proxy_node.c
index 885313a..e109cc4 100644
--- a/src/vnet/dhcp/dhcp6_proxy_node.c
+++ b/src/vnet/dhcp/dhcp6_proxy_node.c
@@ -306,7 +306,7 @@
           copy_ip6_address(&r1->link_addr, ia0);
 
         link_address_set:
-          fl = vlib_buffer_get_free_list (vm, b0->free_list_index);
+          fl = vlib_buffer_get_free_list (vm, vlib_buffer_get_free_list_index (b0));
 
           if ((b0->current_length+sizeof(*id1)+sizeof(*vss1)+sizeof(*cmac))
               > fl->n_data_bytes)
diff --git a/src/vnet/ethernet/ethernet.h b/src/vnet/ethernet/ethernet.h
index dcc656a..2fc5b80 100644
--- a/src/vnet/ethernet/ethernet.h
+++ b/src/vnet/ethernet/ethernet.h
@@ -344,8 +344,7 @@
 always_inline ethernet_header_t *
 ethernet_buffer_get_header (vlib_buffer_t * b)
 {
-  return (void *)
-    (b->data + vnet_buffer (b)->ethernet.start_of_ethernet_header);
+  return (void *) (b->data + vnet_buffer (b)->l2_hdr_offset);
 }
 
 /** Returns the number of VLAN headers in the current Ethernet frame in the
diff --git a/src/vnet/ethernet/node.c b/src/vnet/ethernet/node.c
index d9fdff4..421d501 100755
--- a/src/vnet/ethernet/node.c
+++ b/src/vnet/ethernet/node.c
@@ -101,7 +101,7 @@
 
       e0 = (void *) (b0->data + b0->current_data);
 
-      vnet_buffer (b0)->ethernet.start_of_ethernet_header = b0->current_data;
+      vnet_buffer (b0)->l2_hdr_offset = b0->current_data;
 
       vlib_buffer_advance (b0, sizeof (e0[0]));
 
@@ -205,9 +205,7 @@
       if (!(*is_l2))
 	{
 	  ethernet_header_t *e0;
-	  e0 =
-	    (void *) (b0->data +
-		      vnet_buffer (b0)->ethernet.start_of_ethernet_header);
+	  e0 = (void *) (b0->data + vnet_buffer (b0)->l2_hdr_offset);
 
 	  if (!(ethernet_address_cast (e0->dst_address)))
 	    {
@@ -238,7 +236,7 @@
     {
       *next0 = em->l2_next;
       // record the L2 len and reset the buffer so the L2 header is preserved
-      u32 eth_start = vnet_buffer (b0)->ethernet.start_of_ethernet_header;
+      u32 eth_start = vnet_buffer (b0)->l2_hdr_offset;
       vnet_buffer (b0)->l2.l2_len = b0->current_data - eth_start;
       ASSERT (vnet_buffer (b0)->l2.l2_len ==
 	      ethernet_buffer_header_size (b0));
@@ -424,10 +422,8 @@
 		  cached_is_l2 = is_l20 = subint0->flags & SUBINT_CONFIG_L2;
 		}
 
-	      vnet_buffer (b0)->ethernet.start_of_ethernet_header =
-		b0->current_data;
-	      vnet_buffer (b1)->ethernet.start_of_ethernet_header =
-		b1->current_data;
+	      vnet_buffer (b0)->l2_hdr_offset = b0->current_data;
+	      vnet_buffer (b1)->l2_hdr_offset = b1->current_data;
 
 	      if (PREDICT_TRUE (is_l20 != 0))
 		{
@@ -519,9 +515,9 @@
 	    {
 
 	      len0 = vlib_buffer_length_in_chain (vm, b0) + b0->current_data
-		- vnet_buffer (b0)->ethernet.start_of_ethernet_header;
+		- vnet_buffer (b0)->l2_hdr_offset;
 	      len1 = vlib_buffer_length_in_chain (vm, b1) + b1->current_data
-		- vnet_buffer (b1)->ethernet.start_of_ethernet_header;
+		- vnet_buffer (b1)->l2_hdr_offset;
 
 	      stats_n_packets += 2;
 	      stats_n_bytes += len0 + len1;
@@ -646,8 +642,7 @@
 		  cached_is_l2 = is_l20 = subint0->flags & SUBINT_CONFIG_L2;
 		}
 
-	      vnet_buffer (b0)->ethernet.start_of_ethernet_header =
-		b0->current_data;
+	      vnet_buffer (b0)->l2_hdr_offset = b0->current_data;
 
 	      if (PREDICT_TRUE (is_l20 != 0))
 		{
@@ -710,7 +705,7 @@
 	    {
 
 	      len0 = vlib_buffer_length_in_chain (vm, b0) + b0->current_data
-		- vnet_buffer (b0)->ethernet.start_of_ethernet_header;
+		- vnet_buffer (b0)->l2_hdr_offset;
 
 	      stats_n_packets += 1;
 	      stats_n_bytes += len0;
diff --git a/src/vnet/ip/ip4_forward.c b/src/vnet/ip/ip4_forward.c
index 8263e01..b8dfa84 100755
--- a/src/vnet/ip/ip4_forward.c
+++ b/src/vnet/ip/ip4_forward.c
@@ -1585,8 +1585,8 @@
 	  ip0 = vlib_buffer_get_current (p0);
 	  ip1 = vlib_buffer_get_current (p1);
 
-	  vnet_buffer (p0)->ip.start_of_ip_header = p0->current_data;
-	  vnet_buffer (p1)->ip.start_of_ip_header = p1->current_data;
+	  vnet_buffer (p0)->l3_hdr_offset = p0->current_data;
+	  vnet_buffer (p1)->l3_hdr_offset = p1->current_data;
 
 	  sw_if_index0 = vnet_buffer (p0)->sw_if_index[VLIB_RX];
 	  sw_if_index1 = vnet_buffer (p1)->sw_if_index[VLIB_RX];
@@ -1788,7 +1788,7 @@
 
 	  ip0 = vlib_buffer_get_current (p0);
 
-	  vnet_buffer (p0)->ip.start_of_ip_header = p0->current_data;
+	  vnet_buffer (p0)->l3_hdr_offset = p0->current_data;
 
 	  sw_if_index0 = vnet_buffer (p0)->sw_if_index[VLIB_RX];
 
diff --git a/src/vnet/ip/ip6_forward.c b/src/vnet/ip/ip6_forward.c
index 4b574b9..2b8c2bd 100644
--- a/src/vnet/ip/ip6_forward.c
+++ b/src/vnet/ip/ip6_forward.c
@@ -1362,8 +1362,8 @@
 	  ip0 = vlib_buffer_get_current (p0);
 	  ip1 = vlib_buffer_get_current (p1);
 
-	  vnet_buffer (p0)->ip.start_of_ip_header = p0->current_data;
-	  vnet_buffer (p1)->ip.start_of_ip_header = p1->current_data;
+	  vnet_buffer (p0)->l3_hdr_offset = p0->current_data;
+	  vnet_buffer (p1)->l3_hdr_offset = p1->current_data;
 
 	  type0 = lm->builtin_protocol_by_ip_protocol[ip0->protocol];
 	  type1 = lm->builtin_protocol_by_ip_protocol[ip1->protocol];
@@ -1493,7 +1493,7 @@
 
 	  ip0 = vlib_buffer_get_current (p0);
 
-	  vnet_buffer (p0)->ip.start_of_ip_header = p0->current_data;
+	  vnet_buffer (p0)->l3_hdr_offset = p0->current_data;
 
 	  type0 = lm->builtin_protocol_by_ip_protocol[ip0->protocol];
 	  next0 = lm->local_next_by_ip_protocol[ip0->protocol];
diff --git a/src/vnet/ip/ip6_neighbor.c b/src/vnet/ip/ip6_neighbor.c
index b8f6f9b..68a8cbb 100644
--- a/src/vnet/ip/ip6_neighbor.c
+++ b/src/vnet/ip/ip6_neighbor.c
@@ -1479,9 +1479,8 @@
 			sizeof (icmp6_router_advertisement_header_t);
 
 		      vlib_buffer_add_data (vm,
-					    p0->free_list_index,
-					    bi0,
-					    (void *) &rh,
+					    vlib_buffer_get_free_list_index
+					    (p0), bi0, (void *) &rh,
 					    sizeof
 					    (icmp6_router_advertisement_header_t));
 
@@ -1499,9 +1498,8 @@
 				       eth_if0->address, 6);
 
 			  vlib_buffer_add_data (vm,
-						p0->free_list_index,
-						bi0,
-						(void *) &h,
+						vlib_buffer_get_free_list_index
+						(p0), bi0, (void *) &h,
 						sizeof
 						(icmp6_neighbor_discovery_ethernet_link_layer_address_option_t));
 
@@ -1525,9 +1523,8 @@
 			    sizeof (icmp6_neighbor_discovery_mtu_option_t);
 
 			  vlib_buffer_add_data (vm,
-						p0->free_list_index,
-						bi0,
-						(void *) &h,
+						vlib_buffer_get_free_list_index
+						(p0), bi0, (void *) &h,
 						sizeof
 						(icmp6_neighbor_discovery_mtu_option_t));
 			}
@@ -1579,7 +1576,7 @@
                             payload_length += sizeof( icmp6_neighbor_discovery_prefix_information_option_t);
 
                             vlib_buffer_add_data (vm,
-                                                  p0->free_list_index,
+					    vlib_buffer_get_free_list_index (p0),
                                                   bi0,
                                                   (void *)&h, sizeof(icmp6_neighbor_discovery_prefix_information_option_t));
 
@@ -2326,7 +2323,7 @@
     num_addr_records++;
 
     vlib_buffer_add_data
-      (vm, b0->free_list_index, bo0,
+      (vm, vlib_buffer_get_free_list_index (b0), bo0,
        (void *)&rr, sizeof(icmp6_multicast_address_record_t));
 
     payload_length += sizeof( icmp6_multicast_address_record_t);
diff --git a/src/vnet/l2/l2_bvi.h b/src/vnet/l2/l2_bvi.h
index e21a161..662ec40 100644
--- a/src/vnet/l2/l2_bvi.h
+++ b/src/vnet/l2/l2_bvi.h
@@ -57,7 +57,7 @@
     }
 
   /* Save L2 header position which may be changed due to packet replication */
-  vnet_buffer (b0)->ethernet.start_of_ethernet_header = b0->current_data;
+  vnet_buffer (b0)->l2_hdr_offset = b0->current_data;
 
   /* Strip L2 header */
   l2_len = vnet_buffer (b0)->l2.l2_len;
diff --git a/src/vnet/lisp-cp/control.c b/src/vnet/lisp-cp/control.c
index 22b5c82..d8a1372 100644
--- a/src/vnet/lisp-cp/control.c
+++ b/src/vnet/lisp-cp/control.c
@@ -3706,7 +3706,7 @@
 static void
 find_ip_header (vlib_buffer_t * b, u8 ** ip_hdr)
 {
-  const i32 start = vnet_buffer (b)->ip.start_of_ip_header;
+  const i32 start = vnet_buffer (b)->l3_hdr_offset;
   if (start < 0 && start < -sizeof (b->pre_data))
     {
       *ip_hdr = 0;
diff --git a/src/vnet/replication.c b/src/vnet/replication.c
index 1c6f28d..0fdca0b 100644
--- a/src/vnet/replication.c
+++ b/src/vnet/replication.c
@@ -43,12 +43,12 @@
   ctx_id = ctx - rm->contexts[thread_index];
 
   /* Save state from vlib buffer */
-  ctx->saved_free_list_index = b0->free_list_index;
+  ctx->saved_free_list_index = vlib_buffer_get_free_list_index (b0);
   ctx->current_data = b0->current_data;
 
   /* Set up vlib buffer hooks */
   b0->recycle_count = ctx_id;
-  b0->free_list_index = rm->recycle_list_index;
+  vlib_buffer_set_free_list_index (b0, rm->recycle_list_index);
   b0->flags |= VLIB_BUFFER_RECYCLE;
 
   /* Save feature state */
@@ -129,7 +129,7 @@
        * This is the last replication in the list.
        * Restore original buffer free functionality.
        */
-      b0->free_list_index = ctx->saved_free_list_index;
+      vlib_buffer_set_free_list_index (b0, ctx->saved_free_list_index);
       b0->flags &= ~VLIB_BUFFER_RECYCLE;
 
       /* Free context back to its pool */