diff options
author | Billy McFall <bmcfall@redhat.com> | 2017-02-10 14:57:24 -0500 |
---|---|---|
committer | Damjan Marion <dmarion.lists@gmail.com> | 2017-02-14 12:28:47 +0000 |
commit | 33e2dc078b4cc7eb32a829180bd8a58ec5aafc90 (patch) | |
tree | 4a1c394c79cc60ea5727358bdefae304911197e4 | |
parent | d3ba515d99551ee87096931b34a5b8d4222b385d (diff) |
VPP-279: Document changes for vnet/vnet/devices
Add doxygen documentation for pcap tx trace CLI command.
In the process of adding the documentation, made the following changes
to the way the command worked:
* If there is an error with any of the attributes, the whole command
fails. The existing behavior was to apply attribute by attribute,
then bail if there was an issue, with partial apply.
* Move the 'on' processing to the end. The existing behavior was to
process the 'on' as it was encountered on the commandline. That meant
that any attributes after the 'on' in the commandline were saved and
displayed, but not really being used in the packet trace.
* Enhanced the 'status' to show all the configured attributes.
NOTE: The packet capture has some weird behavior with regards to how
many packets are written to file and if the file is appended or
overwritten. VPP-634 written to document the issue.
Change-Id: Iab241228b125385052de242865afd9515fa2524f
Signed-off-by: Billy McFall <bmcfall@redhat.com>
-rw-r--r-- | src/vnet/devices/dpdk/cli.c | 235 | ||||
-rw-r--r-- | src/vnet/devices/dpdk/dir.dox | 27 |
2 files changed, 210 insertions, 52 deletions
diff --git a/src/vnet/devices/dpdk/cli.c b/src/vnet/devices/dpdk/cli.c index 3bbace26b73..d133cfd95db 100644 --- a/src/vnet/devices/dpdk/cli.c +++ b/src/vnet/devices/dpdk/cli.c @@ -25,43 +25,49 @@ #include "dpdk_priv.h" +/** + * @file + * @brief CLI for DPDK Abstraction Layer and pcap Tx Trace. + * + * This file contains the source code for CLI for DPDK + * Abstraction Layer and pcap Tx Trace. + */ + static clib_error_t * pcap_trace_command_fn (vlib_main_t * vm, unformat_input_t * input, vlib_cli_command_t * cmd) { +#define PCAP_DEF_PKT_TO_CAPTURE (100) + + unformat_input_t _line_input, *line_input = &_line_input; dpdk_main_t *dm = &dpdk_main; u8 *filename; - u32 max; - int matched = 0; + u8 *chroot_filename = 0; + u32 max = 0; + int enabled = 0; + int errorFlag = 0; clib_error_t *error = 0; - while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) + /* Get a line of input. */ + if (!unformat_user (input, unformat_line_input, line_input)) + return 0; + + while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) { - if (unformat (input, "on")) + if (unformat (line_input, "on")) { if (dm->tx_pcap_enable == 0) { - if (dm->pcap_filename == 0) - dm->pcap_filename = format (0, "/tmp/vpe.pcap%c", 0); - - memset (&dm->pcap_main, 0, sizeof (dm->pcap_main)); - dm->pcap_main.file_name = (char *) dm->pcap_filename; - dm->pcap_main.n_packets_to_capture = 100; - if (dm->pcap_pkts_to_capture) - dm->pcap_main.n_packets_to_capture = dm->pcap_pkts_to_capture; - - dm->pcap_main.packet_type = PCAP_PACKET_TYPE_ethernet; - dm->tx_pcap_enable = 1; - matched = 1; - vlib_cli_output (vm, "pcap tx capture on..."); + enabled = 1; } else { vlib_cli_output (vm, "pcap tx capture already on..."); + errorFlag = 1; + break; } - matched = 1; } - else if (unformat (input, "off")) + else if (unformat (line_input, "off")) { if (dm->tx_pcap_enable) { @@ -77,81 +83,206 @@ pcap_trace_command_fn (vlib_main_t * vm, else vlib_cli_output (vm, "saved to %s...", dm->pcap_filename); } + + dm->tx_pcap_enable = 0; } else { vlib_cli_output (vm, "pcap tx capture already off..."); + errorFlag = 1; + break; } - - dm->tx_pcap_enable = 0; - matched = 1; } - else if (unformat (input, "max %d", &max)) + else if (unformat (line_input, "max %d", &max)) { - dm->pcap_pkts_to_capture = max; - matched = 1; + if (dm->tx_pcap_enable) + { + vlib_cli_output (vm, + "can't change max value while pcap tx capture active..."); + errorFlag = 1; + break; + } } - - else if (unformat (input, "intfc %U", + else if (unformat (line_input, "intfc %U", unformat_vnet_sw_interface, dm->vnet_main, &dm->pcap_sw_if_index)) - matched = 1; - else if (unformat (input, "intfc any")) + ; + + else if (unformat (line_input, "intfc any")) { dm->pcap_sw_if_index = 0; - matched = 1; } - else if (unformat (input, "file %s", &filename)) + else if (unformat (line_input, "file %s", &filename)) { - u8 *chroot_filename; + if (dm->tx_pcap_enable) + { + vlib_cli_output (vm, + "can't change file while pcap tx capture active..."); + errorFlag = 1; + break; + } + /* Brain-police user path input */ if (strstr ((char *) filename, "..") || index ((char *) filename, '/')) { vlib_cli_output (vm, "illegal characters in filename '%s'", filename); - continue; + vlib_cli_output (vm, + "Hint: Only filename, do not enter directory structure."); + vec_free (filename); + errorFlag = 1; + break; } chroot_filename = format (0, "/tmp/%s%c", filename, 0); vec_free (filename); - - if (dm->pcap_filename) - vec_free (dm->pcap_filename); - vec_add1 (filename, 0); - dm->pcap_filename = chroot_filename; - matched = 1; } - else if (unformat (input, "status")) + else if (unformat (line_input, "status")) { + if (dm->pcap_sw_if_index == 0) + { + vlib_cli_output (vm, "max is %d for any interface to file %s", + dm-> + pcap_pkts_to_capture ? dm->pcap_pkts_to_capture + : PCAP_DEF_PKT_TO_CAPTURE, + dm-> + pcap_filename ? dm->pcap_filename : (u8 *) + "/tmp/vpe.pcap"); + } + else + { + vlib_cli_output (vm, "max is %d for interface %U to file %s", + dm-> + pcap_pkts_to_capture ? dm->pcap_pkts_to_capture + : PCAP_DEF_PKT_TO_CAPTURE, + format_vnet_sw_if_index_name, dm->vnet_main, + dm->pcap_sw_if_index, + dm-> + pcap_filename ? dm->pcap_filename : (u8 *) + "/tmp/vpe.pcap"); + } + if (dm->tx_pcap_enable == 0) { vlib_cli_output (vm, "pcap tx capture is off..."); - continue; } - - vlib_cli_output (vm, "pcap tx capture: %d of %d pkts...", - dm->pcap_main.n_packets_captured, - dm->pcap_main.n_packets_to_capture); - matched = 1; + else + { + vlib_cli_output (vm, "pcap tx capture is on: %d of %d pkts...", + dm->pcap_main.n_packets_captured, + dm->pcap_main.n_packets_to_capture); + } + break; } else - break; + { + error = clib_error_return (0, "unknown input `%U'", + format_unformat_error, line_input); + errorFlag = 1; + break; + } } + unformat_free (line_input); - if (matched == 0) - return clib_error_return (0, "unknown input `%U'", - format_unformat_error, input); - return 0; + if (errorFlag == 0) + { + /* Since no error, save configured values. */ + if (chroot_filename) + { + if (dm->pcap_filename) + vec_free (dm->pcap_filename); + vec_add1 (chroot_filename, 0); + dm->pcap_filename = chroot_filename; + } + + if (max) + dm->pcap_pkts_to_capture = max; + + + if (enabled) + { + if (dm->pcap_filename == 0) + dm->pcap_filename = format (0, "/tmp/vpe.pcap%c", 0); + + memset (&dm->pcap_main, 0, sizeof (dm->pcap_main)); + dm->pcap_main.file_name = (char *) dm->pcap_filename; + dm->pcap_main.n_packets_to_capture = PCAP_DEF_PKT_TO_CAPTURE; + if (dm->pcap_pkts_to_capture) + dm->pcap_main.n_packets_to_capture = dm->pcap_pkts_to_capture; + + dm->pcap_main.packet_type = PCAP_PACKET_TYPE_ethernet; + dm->tx_pcap_enable = 1; + vlib_cli_output (vm, "pcap tx capture on..."); + } + } + else if (chroot_filename) + vec_free (chroot_filename); + + + return error; } +/*? + * This command is used to start or stop a packet capture, or show + * the status of packet capture. + * + * This command has the following optional parameters: + * + * - <b>on|off</b> - Used to start or stop a packet capture. + * + * - <b>max <nn></b> - Depth of local buffer. Once '<em>nn</em>' number + * of packets have been received, buffer is flushed to file. Once another + * '<em>nn</em>' number of packets have been received, buffer is flushed + * to file, overwriting previous write. If not entered, value defaults + * to 100. Can only be updated if packet capture is off. + * + * - <b>intfc <interface>|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 + * packet capture are preserved, so '<em>any</em>' can be used to reset + * the interface setting. + * + * - <b>file <name></b> - Used to specify the output filename. The file will + * be placed in the '<em>/tmp</em>' directory, so only the filename is + * supported. Directory should not be entered. If file already exists, file + * will be overwritten. If no filename is provided, '<em>/tmp/vpe.pcap</em>' + * will be used. Can only be updated if packet capture is off. + * + * - <b>status</b> - Displays the current status and configured attributes + * associated with a packet capture. If packet capture is in progress, + * '<em>status</em>' also will return the number of packets currently in + * the local buffer. All additional attributes entered on command line + * with '<em>status</em>' will be ingnored and not applied. + * + * @cliexpar + * Example of how to display the status of a tx packet capture when off: + * @cliexstart{pcap tx trace status} + * max is 100, for any interface to file /tmp/vpe.pcap + * pcap tx capture is off... + * @cliexend + * Example of how to start a tx packet capture: + * @cliexstart{pcap tx trace on max 35 intfc GigabitEthernet0/8/0 file vppTest.pcap} + * pcap tx capture on... + * @cliexend + * Example of how to display the status of a tx packet capture in progress: + * @cliexstart{pcap tx trace status} + * max is 35, for interface GigabitEthernet0/8/0 to file /tmp/vppTest.pcap + * pcap tx capture is on: 20 of 35 pkts... + * @cliexend + * Example of how to stop a tx packet capture: + * @cliexstart{vppctl pcap tx trace off} + * captured 21 pkts... + * saved to /tmp/vppTest.pcap... + * @cliexend +?*/ /* *INDENT-OFF* */ VLIB_CLI_COMMAND (pcap_trace_command, static) = { .path = "pcap tx trace", .short_help = - "pcap tx trace on off max <nn> intfc <intfc> file <name> status", + "pcap tx trace [on|off] [max <nn>] [intfc <interface>|any] [file <name>] [status]", .function = pcap_trace_command_fn, }; /* *INDENT-ON* */ diff --git a/src/vnet/devices/dpdk/dir.dox b/src/vnet/devices/dpdk/dir.dox new file mode 100644 index 00000000000..43e36753245 --- /dev/null +++ b/src/vnet/devices/dpdk/dir.dox @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* Doxygen directory documentation */ + +/** +@dir +@brief DPDK Abstraction Layer. + +This directory contains the source code for the DPDK abstraction layer. + +*/ +/*? %%clicmd:group_label DPDK and pcap tx %% ?*/ +/*? %%syscfg:group_label DPDK and pcap tx %% ?*/ |