aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/vnet/interface.h2
-rw-r--r--src/vnet/interface_cli.c52
2 files changed, 49 insertions, 5 deletions
diff --git a/src/vnet/interface.h b/src/vnet/interface.h
index 7d73c5f6473..618eefe8f67 100644
--- a/src/vnet/interface.h
+++ b/src/vnet/interface.h
@@ -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;
diff --git a/src/vnet/interface_cli.c b/src/vnet/interface_cli.c
index c622a605be8..46c5d5e8389 100644
--- a/src/vnet/interface_cli.c
+++ b/src/vnet/interface_cli.c
@@ -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* */