Hello, I noticed that dpdk devices set the VLIB_BUFFER_TOTAL_LENGTH_VALID flag when receiving packets, regardless of the value of total_length_not_including_first_buffer. Since dpdk only copies one cacheline from its vlib_buffer template into the buffer upon receipt of a packet, b->total_length_not_including_first_buffer is left unitialized (because it's in the second cacheline).
In most cases, this doesn't cause issues — for non-chained buffers the vlib_buffer_length_in_chain() function will still return the correct value because it only looks at b->current_length. However, if the buffer is later vlib_buffer_clone()d, the stale total_length_not_including_first_buffer value will propagate to the new head of the chain, for which vlib_buffer_length_in_chain() will now return a wrong value. This can be observed for instance when using BIER, with which replicated packets will sometimes have oversized lengths. An obvious fix for that is to remove the VLIB_BUFFER_TOTAL_LENGTH_VALID flag from the buffer_flags_template in dpdk_init(). I'm concerned about the performance of this approach though, because vlib_buffer_length_in_chain() will then have to go through the slow path for all chained packets, causing branches. The other solution would be to, in addition, add something along the lines of the following in dpdk_process_rx_burst(): b[0]->flags |= (!b[0]->total_length_not_including_first_buffer) << VLIB_BUFFER_LOG2_TOTAL_LENGTH_VALID; so as to set the flag in correct packets as early as possible. This would be branchless code, but would cost a few cycles for every packet received by dpdk. Any thoughts? Also, does anyone know if this can happen with other devices than dpdk? Best, Yoann