diff options
-rw-r--r-- | src/vnet/interface.h | 2 | ||||
-rw-r--r-- | src/vnet/interface_cli.c | 52 |
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* */ |