diff options
Diffstat (limited to 'src/vnet/pg')
-rw-r--r-- | src/vnet/pg/pg.h | 51 |
1 files changed, 40 insertions, 11 deletions
diff --git a/src/vnet/pg/pg.h b/src/vnet/pg/pg.h index 5e99d9af9f6..5e63b58caf6 100644 --- a/src/vnet/pg/pg.h +++ b/src/vnet/pg/pg.h @@ -182,14 +182,38 @@ typedef struct pg_stream_t } pg_stream_t; always_inline void -pg_buffer_index_free (pg_buffer_index_t * bi) +pg_free_buffers (pg_buffer_index_t *bi) { vlib_main_t *vm = vlib_get_main (); - word n_alloc; - vec_free (bi->edits); - n_alloc = clib_fifo_elts (bi->buffer_fifo); - vlib_buffer_free (vm, bi->buffer_fifo, n_alloc); - clib_fifo_free (bi->buffer_fifo); + uword n_elts, head, len; + + if (!bi || !bi->buffer_fifo) + return; + + n_elts = clib_fifo_elts (bi->buffer_fifo); + if (n_elts) + { + len = clib_fifo_len (bi->buffer_fifo); + head = clib_fifo_head_index (bi->buffer_fifo); + + if (head + n_elts <= len) + vlib_buffer_free (vm, &bi->buffer_fifo[head], n_elts); + else + { + vlib_buffer_free (vm, &bi->buffer_fifo[head], len - head); + vlib_buffer_free (vm, bi->buffer_fifo, n_elts - (len - head)); + } + } +} + +always_inline void +pg_buffer_index_free (pg_buffer_index_t *bi) +{ + if (bi) + { + vec_free (bi->edits); + clib_fifo_free (bi->buffer_fifo); + } } always_inline void @@ -220,11 +244,16 @@ pg_stream_free (pg_stream_t * s) vec_free (s->replay_packet_templates); vec_free (s->replay_packet_timestamps); - { - pg_buffer_index_t *bi; - vec_foreach (bi, s->buffer_indices) pg_buffer_index_free (bi); - vec_free (s->buffer_indices); - } + if (s->buffer_indices) + { + pg_buffer_index_t *bi; + // We only need to free the buffers from the first array, as the buffers + // are chained when packet-generator enable is issued. + pg_free_buffers (s->buffer_indices); + vec_foreach (bi, s->buffer_indices) + pg_buffer_index_free (bi); + vec_free (s->buffer_indices); + } } always_inline int |