From 0cbcecfa78e75dc5eea2c2033ea6e4320f5bad28 Mon Sep 17 00:00:00 2001 From: Florin Coras Date: Wed, 14 May 2025 00:13:59 -0400 Subject: [PATCH] tcp: avoid spurious asserts while discarding bytes Found by hst in ci, probably because of af_packet interfaces with gso/gro on. Only applies to chained buffers. Type: fix Change-Id: I8d223a526bbdf88a2a7b60a0028e79ce14015a37 Signed-off-by: Florin Coras --- src/vnet/tcp/tcp_input.c | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/src/vnet/tcp/tcp_input.c b/src/vnet/tcp/tcp_input.c index 3abfc9512a7..f1b34290afc 100644 --- a/src/vnet/tcp/tcp_input.c +++ b/src/vnet/tcp/tcp_input.c @@ -1173,27 +1173,37 @@ tcp_session_enqueue_ooo (tcp_connection_t * tc, vlib_buffer_t * b, static int tcp_buffer_discard_bytes (vlib_buffer_t * b, u32 n_bytes_to_drop) { - u32 discard, first = b->current_length; - vlib_main_t *vm = vlib_get_main (); - /* Handle multi-buffer segments */ if (n_bytes_to_drop > b->current_length) { + u32 n_to_drop, first = b->current_length; + vlib_main_t *vm = vlib_get_main (); + if (!(b->flags & VLIB_BUFFER_NEXT_PRESENT) || (first + b->total_length_not_including_first_buffer < n_bytes_to_drop)) return -1; b->total_length_not_including_first_buffer -= n_bytes_to_drop - first; + n_to_drop = n_bytes_to_drop; do { - discard = clib_min (n_bytes_to_drop, b->current_length); - vlib_buffer_advance (b, discard); + /* Not calling vlib_buffer_advance to avoid min chain seg size + * asserts that are not relevant for chained buffers that are about + * to be freed */ + if (n_to_drop <= b->current_length) + { + b->current_length -= n_to_drop; + b->current_data += n_to_drop; + break; + } + n_to_drop -= b->current_length; + b->current_data += b->current_length; + b->current_length = 0; b = vlib_get_buffer (vm, b->next_buffer); - n_bytes_to_drop -= discard; - if (!b && n_bytes_to_drop) + if (!b) return -1; } - while (n_bytes_to_drop); + while (n_to_drop); } else vlib_buffer_advance (b, n_bytes_to_drop); -- 2.16.6