interface: add pcap trace data preallocation

Type: fix

Signed-off-by: Dave Barach <dave@barachs.net>
Change-Id: I2e53fa85a0b4082666f57a3a58a09c04ae2001b5
(cherry picked from commit 586462fabcc913a5a4fa9115d4b5caf33dfdb347)
This commit is contained in:
Dave Barach
2020-08-05 16:12:35 -04:00
committed by Dave Barach
parent 6aaa567959
commit ecc98b54f2
2 changed files with 49 additions and 5 deletions

View File

@ -906,6 +906,8 @@ typedef struct
u8 rx_enable;
u8 tx_enable;
u8 drop_enable;
u8 preallocate_data;
u8 free_data;
u32 sw_if_index;
int filter;
} vnet_pcap_dispatch_trace_args_t;

View File

@ -1782,15 +1782,25 @@ vnet_pcap_dispatch_trace_configure (vnet_pcap_dispatch_trace_args_t * a)
if (a->rx_enable + a->tx_enable + a->drop_enable)
{
void *save_pcap_data;
/* Sanity check max bytes per pkt */
if (a->max_bytes_per_pkt < 32 || a->max_bytes_per_pkt > 9000)
return VNET_API_ERROR_INVALID_MEMORY_SIZE;
/* Clean up from previous run, if any */
vec_free (pm->file_name);
vec_free (pm->pcap_data);
vec_reset_length (pm->pcap_data);
/* Throw away the data buffer? */
if (a->free_data)
vec_free (pm->pcap_data);
save_pcap_data = pm->pcap_data;
memset (pm, 0, sizeof (*pm));
pm->pcap_data = save_pcap_data;
vec_validate_aligned (vnet_trace_dummy, 2048, CLIB_CACHE_LINE_BYTES);
if (pm->lock == 0)
clib_spinlock_init (&(pm->lock));
@ -1812,6 +1822,14 @@ vnet_pcap_dispatch_trace_configure (vnet_pcap_dispatch_trace_args_t * a)
pm->file_name = (char *) a->filename;
pm->n_packets_captured = 0;
pm->packet_type = PCAP_PACKET_TYPE_ethernet;
/* Preallocate the data vector? */
if (a->preallocate_data)
{
vec_validate
(pm->pcap_data, a->packets_to_capture
* ((sizeof (pcap_packet_header_t) + a->max_bytes_per_pkt)));
vec_reset_length (pm->pcap_data);
}
pm->n_packets_to_capture = a->packets_to_capture;
pp->pcap_sw_if_index = a->sw_if_index;
if (a->filter)
@ -1844,6 +1862,9 @@ vnet_pcap_dispatch_trace_configure (vnet_pcap_dispatch_trace_args_t * a)
clib_error_report (error);
return VNET_API_ERROR_SYSCALL_ERROR_1;
}
vec_free (pm->file_name);
if (a->free_data)
vec_free (pm->pcap_data);
return 0;
}
else
@ -1866,10 +1887,12 @@ pcap_trace_command_fn (vlib_main_t * vm,
int rv;
int rx_enable = 0;
int tx_enable = 0;
int preallocate_data = 0;
int drop_enable = 0;
int status = 0;
int filter = 0;
u32 sw_if_index = ~0;
int free_data = 0;
u32 sw_if_index = 0; /* default: any interface */
/* Get a line of input. */
if (!unformat_user (input, unformat_line_input, line_input))
@ -1900,7 +1923,16 @@ pcap_trace_command_fn (vlib_main_t * vm,
else if (unformat (line_input, "intfc %U",
unformat_vnet_sw_interface, vnm, &sw_if_index))
;
else if (unformat (line_input, "intfc any"))
else if (unformat (line_input, "interface %U",
unformat_vnet_sw_interface, vnm, &sw_if_index))
;
else if (unformat (line_input, "preallocate-data %=",
&preallocate_data, 1))
;
else if (unformat (line_input, "free-data %=", &free_data, 1))
;
else if (unformat (line_input, "intfc any")
|| unformat (line_input, "interface any"))
sw_if_index = 0;
else if (unformat (line_input, "filter"))
filter = 1;
@ -1917,6 +1949,8 @@ pcap_trace_command_fn (vlib_main_t * vm,
a->filename = filename;
a->rx_enable = rx_enable;
a->tx_enable = tx_enable;
a->preallocate_data = preallocate_data;
a->free_data = free_data;
a->drop_enable = drop_enable;
a->status = status;
a->packets_to_capture = max;
@ -1986,6 +2020,12 @@ pcap_trace_command_fn (vlib_main_t * vm,
* - <b>max-bytes-per-pkt <nnnn></b> - Maximum number of bytes to capture
* for each packet. Must be >= 32, <= 9000.
*
* - <b>preallocate-data</b> - Preallocate the data buffer, to avoid
* vector expansion delays during pcap capture
*
* - <b>free-data</b> - Free the data buffer. Ordinarily it's a feature
* to retain the data buffer so this option is seldom used.
*
* - <b>intfc <interface-name>|any</b> - Used to specify a given interface,
* or use '<em>any</em>' to run packet capture on all interfaces.
* '<em>any</em>' is the default if not provided. Settings from a previous
@ -2035,7 +2075,9 @@ pcap_trace_command_fn (vlib_main_t * vm,
VLIB_CLI_COMMAND (pcap_tx_trace_command, static) = {
.path = "pcap trace",
.short_help =
"pcap trace rx tx drop off [max <nn>] [intfc <interface>|any] [file <name>] [status] [max-bytes-per-pkt <nnnn>][filter]",
"pcap trace [rx] [tx] [drop] [off] [max <nn>] [intfc <interface>|any]\n"
" [file <name>] [status] [max-bytes-per-pkt <nnnn>][filter]\n"
" [preallocate-data][free-data]",
.function = pcap_trace_command_fn,
};
/* *INDENT-ON* */