Adds support to testpmd to load a set of cmdline CLI commands at startup. This can be helpful when needing to cut-n-paste many commands each time testpmd is restarted. This option will work in both interactive and non-interactive modes.
./testpmd -n4 -c3 ... -- --cmdline-file=/home/ubuntu/somefile.txt Signed-off-by: Allain Legacy <allain.leg...@windriver.com> --- app/test-pmd/cmdline.c | 21 ++++++++++++++++ app/test-pmd/parameters.c | 10 ++++++++ app/test-pmd/testpmd.c | 4 +++ app/test-pmd/testpmd.h | 2 ++ doc/guides/testpmd_app_ug/testpmd_funcs.rst | 39 +++++++++++++++++++++++++++++ 5 files changed, 76 insertions(+) diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c index 47f935d20..3d7f90360 100644 --- a/app/test-pmd/cmdline.c +++ b/app/test-pmd/cmdline.c @@ -12579,6 +12579,27 @@ cmdline_parse_ctx_t main_ctx[] = { NULL, }; +/* read cmdline commands from file */ +void +cmdline_read_from_file(const char *filename) +{ + struct cmdline *cl; + + cl = cmdline_file_new(main_ctx, "testpmd> ", filename); + if (cl == NULL) { + printf("Failed to create file based cmdline context: %s\n", + filename); + return; + } + + cmdline_interact(cl); + cmdline_quit(cl); + + cmdline_free(cl); + + printf("Read CLI commands from %s\n", filename); +} + /* prompt function, called from main on MASTER lcore */ void prompt(void) diff --git a/app/test-pmd/parameters.c b/app/test-pmd/parameters.c index 28db8cdd3..085b6fc73 100644 --- a/app/test-pmd/parameters.c +++ b/app/test-pmd/parameters.c @@ -86,6 +86,7 @@ usage(char* progname) printf("usage: %s " #ifdef RTE_LIBRTE_CMDLINE "[--interactive|-i] " + "[--cmdline-file=FILENAME] " #endif "[--help|-h] | [--auto-start|-a] | [" "--coremask=COREMASK --portmask=PORTMASK --numa " @@ -103,6 +104,7 @@ usage(char* progname) progname); #ifdef RTE_LIBRTE_CMDLINE printf(" --interactive: run in interactive mode.\n"); + printf(" --cmdline-file: execute cli commands before startup.\n"); #endif printf(" --auto-start: start forwarding on init " "[always when non-interactive].\n"); @@ -505,6 +507,7 @@ launch_args_parse(int argc, char** argv) { "help", 0, 0, 0 }, #ifdef RTE_LIBRTE_CMDLINE { "interactive", 0, 0, 0 }, + { "cmdline-file", 1, 0, 0 }, { "auto-start", 0, 0, 0 }, { "eth-peers-configfile", 1, 0, 0 }, { "eth-peer", 1, 0, 0 }, @@ -595,6 +598,13 @@ launch_args_parse(int argc, char** argv) printf("Interactive-mode selected\n"); interactive = 1; } + if (!strcmp(lgopts[opt_idx].name, "cmdline-file")) { + printf("CLI commands to be read from %s\n", + optarg); + snprintf(cmdline_filename, + sizeof(cmdline_filename), "%s", + optarg); + } if (!strcmp(lgopts[opt_idx].name, "auto-start")) { printf("Auto-start selected\n"); auto_start = 1; diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c index e04e215ba..f7722d91f 100644 --- a/app/test-pmd/testpmd.c +++ b/app/test-pmd/testpmd.c @@ -87,6 +87,7 @@ uint16_t verbose_level = 0; /**< Silent by default. */ /* use master core for command line ? */ uint8_t interactive = 0; uint8_t auto_start = 0; +char cmdline_filename[PATH_MAX] = {0}; /* * NUMA support configuration. @@ -2140,6 +2141,9 @@ main(int argc, char** argv) rte_eth_promiscuous_enable(port_id); #ifdef RTE_LIBRTE_CMDLINE + if (strlen(cmdline_filename) != 0) + cmdline_read_from_file(cmdline_filename); + if (interactive == 1) { if (auto_start) { printf("Start automatic packet forwarding\n"); diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h index 8cf286052..554896dc6 100644 --- a/app/test-pmd/testpmd.h +++ b/app/test-pmd/testpmd.h @@ -308,6 +308,7 @@ extern uint16_t nb_rx_queue_stats_mappings; extern uint16_t verbose_level; /**< Drives messages being displayed, if any. */ extern uint8_t interactive; extern uint8_t auto_start; +extern char cmdline_filename[PATH_MAX]; /**< offline commands file */ extern uint8_t numa_support; /**< set by "--numa" parameter */ extern uint16_t port_topology; /**< set by "--port-topology" parameter */ extern uint8_t no_flush_rx; /**<set by "--no-flush-rx" parameter */ @@ -492,6 +493,7 @@ unsigned int parse_item_list(char* str, const char* item_name, unsigned int max_items, unsigned int *parsed_items, int check_unique_values); void launch_args_parse(int argc, char** argv); +void cmdline_read_from_file(const char *filename); void prompt(void); void prompt_exit(void); void nic_stats_display(portid_t port_id); diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst index bdc6a14df..4bf0f799a 100644 --- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst +++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst @@ -86,6 +86,45 @@ These are divided into sections and can be accessed using help, help section or help all : All of the above sections. +Command File Functions +---------------------- + +To facilitate loading large number of commands or to avoid cutting and pasting where not +practical or possible testpmd supports alternative methods for executing commands. + +* If started with the ``--cmdline-file=FILENAME`` command line argument testpmd + will execute all CLI commands contained within the file immediately before + starting packet forwarding or entering interactive mode. + +.. code-block:: console + + ./testpmd -n4 -r2 ... -- -i --cmdline-file=/home/ubuntu/flow-create-commands.txt + Interactive-mode selected + CLI commands to be read from /home/ubuntu/flow-create-commands.txt + Configuring Port 0 (socket 0) + Port 0: 7C:FE:90:CB:74:CE + Configuring Port 1 (socket 0) + Port 1: 7C:FE:90:CB:74:CA + Checking link statuses... + Port 0 Link Up - speed 10000 Mbps - full-duplex + Port 1 Link Up - speed 10000 Mbps - full-duplex + Done + Flow rule #0 created + Flow rule #1 created + ... + ... + Flow rule #498 created + Flow rule #499 created + Read all CLI commands from /home/ubuntu/flow-create-commands.txt + testpmd> + + +In all cases output from any included command will be displayed as standard output. +Execution will continue until the end of the file is reached regardless of +whether any errors occur. The end user must examine the output to determine if +any failures occurred. + + Control Functions ----------------- -- 2.12.1