+frag_set_sw_if_index (vlib_buffer_t * to, vlib_buffer_t * from)
+{
+ vnet_buffer (to)->sw_if_index[VLIB_RX] =
+ vnet_buffer (from)->sw_if_index[VLIB_RX];
+ vnet_buffer (to)->sw_if_index[VLIB_TX] =
+ vnet_buffer (from)->sw_if_index[VLIB_TX];
+
+ /* Copy adj_index in case DPO based node is sending for the
+ * fragmentation, the packet would be sent back to the proper
+ * DPO next node and Index
+ */
+ vnet_buffer (to)->ip.adj_index[VLIB_RX] =
+ vnet_buffer (from)->ip.adj_index[VLIB_RX];
+ vnet_buffer (to)->ip.adj_index[VLIB_TX] =
+ vnet_buffer (from)->ip.adj_index[VLIB_TX];
+
+ /* Copy QoS Bits */
+ if (PREDICT_TRUE (from->flags & VNET_BUFFER_F_QOS_DATA_VALID))
+ {
+ vnet_buffer2 (to)->qos = vnet_buffer2 (from)->qos;
+ to->flags |= VNET_BUFFER_F_QOS_DATA_VALID;
+ }
+}
+
+static vlib_buffer_t *
+frag_buffer_alloc (vlib_buffer_t * org_b, u32 * bi)
+{
+ vlib_main_t *vm = vlib_get_main ();
+ if (vlib_buffer_alloc (vm, bi, 1) != 1)
+ return 0;
+
+ vlib_buffer_t *b = vlib_get_buffer (vm, *bi);
+ vlib_buffer_free_list_t *fl =
+ vlib_buffer_get_free_list (vm, VLIB_BUFFER_DEFAULT_FREE_LIST_INDEX);
+ vlib_buffer_init_for_free_list (b, fl);
+ VLIB_BUFFER_TRACE_TRAJECTORY_INIT (b);
+ vlib_buffer_copy_trace_flag (vm, org_b, *bi);
+
+ return b;
+}
+
+/*
+ * Limitation: Does follow buffer chains in the packet to fragment,
+ * but does not generate buffer chains. I.e. a fragment is always
+ * contained with in a single buffer and limited to the max buffer
+ * size.
+ */
+void
+ip4_frag_do_fragment (vlib_main_t * vm, u32 from_bi, u32 ** buffer,