14418919fSjohnjiang /* SPDX-License-Identifier: BSD-3-Clause
24418919fSjohnjiang * Copyright(c) 2010-2014 Intel Corporation.
34418919fSjohnjiang * Copyright(c) 2014 6WIND S.A.
44418919fSjohnjiang */
54418919fSjohnjiang
64418919fSjohnjiang #include <stdio.h>
74418919fSjohnjiang #include <stdarg.h>
84418919fSjohnjiang #include <stdint.h>
94418919fSjohnjiang #include <string.h>
104418919fSjohnjiang #include <stdlib.h>
114418919fSjohnjiang #include <netinet/in.h>
124418919fSjohnjiang #include <termios.h>
134418919fSjohnjiang #include <inttypes.h>
144418919fSjohnjiang #include <errno.h>
154418919fSjohnjiang #include <sys/queue.h>
164418919fSjohnjiang
174418919fSjohnjiang #include <rte_common.h>
184418919fSjohnjiang #include <rte_log.h>
194418919fSjohnjiang #include <rte_debug.h>
204418919fSjohnjiang #include <rte_memory.h>
214418919fSjohnjiang #include <rte_memcpy.h>
224418919fSjohnjiang #include <rte_memzone.h>
234418919fSjohnjiang #include <rte_launch.h>
244418919fSjohnjiang #include <rte_cycles.h>
254418919fSjohnjiang #include <rte_eal.h>
264418919fSjohnjiang #include <rte_per_lcore.h>
274418919fSjohnjiang #include <rte_lcore.h>
284418919fSjohnjiang #include <rte_atomic.h>
294418919fSjohnjiang #include <rte_branch_prediction.h>
304418919fSjohnjiang #include <rte_ring.h>
314418919fSjohnjiang #include <rte_malloc.h>
324418919fSjohnjiang #include <rte_mempool.h>
334418919fSjohnjiang #include <rte_mbuf.h>
344418919fSjohnjiang #include <rte_devargs.h>
354418919fSjohnjiang
364418919fSjohnjiang #include <cmdline_rdline.h>
374418919fSjohnjiang #include <cmdline_parse.h>
384418919fSjohnjiang #include <cmdline_parse_ipaddr.h>
394418919fSjohnjiang #include <cmdline_parse_num.h>
404418919fSjohnjiang #include <cmdline_parse_string.h>
414418919fSjohnjiang #include <cmdline.h>
424418919fSjohnjiang #include <rte_string_fns.h>
434418919fSjohnjiang
444418919fSjohnjiang #include "test.h"
454418919fSjohnjiang
464418919fSjohnjiang /****************/
474418919fSjohnjiang
484418919fSjohnjiang static struct test_commands_list commands_list =
494418919fSjohnjiang TAILQ_HEAD_INITIALIZER(commands_list);
504418919fSjohnjiang
514418919fSjohnjiang void
add_test_command(struct test_command * t)524418919fSjohnjiang add_test_command(struct test_command *t)
534418919fSjohnjiang {
544418919fSjohnjiang TAILQ_INSERT_TAIL(&commands_list, t, next);
554418919fSjohnjiang }
564418919fSjohnjiang
574418919fSjohnjiang struct cmd_autotest_result {
584418919fSjohnjiang cmdline_fixed_string_t autotest;
594418919fSjohnjiang };
604418919fSjohnjiang
cmd_autotest_parsed(void * parsed_result,__rte_unused struct cmdline * cl,__rte_unused void * data)614418919fSjohnjiang static void cmd_autotest_parsed(void *parsed_result,
62*2d9fd380Sjfb8856606 __rte_unused struct cmdline *cl,
63*2d9fd380Sjfb8856606 __rte_unused void *data)
644418919fSjohnjiang {
654418919fSjohnjiang struct test_command *t;
664418919fSjohnjiang struct cmd_autotest_result *res = parsed_result;
674418919fSjohnjiang int ret = 0;
684418919fSjohnjiang
694418919fSjohnjiang TAILQ_FOREACH(t, &commands_list, next) {
704418919fSjohnjiang if (!strcmp(res->autotest, t->command))
714418919fSjohnjiang ret = t->callback();
724418919fSjohnjiang }
734418919fSjohnjiang
744418919fSjohnjiang last_test_result = ret;
754418919fSjohnjiang if (ret == 0)
764418919fSjohnjiang printf("Test OK\n");
774418919fSjohnjiang else if (ret == TEST_SKIPPED)
784418919fSjohnjiang printf("Test Skipped\n");
794418919fSjohnjiang else
804418919fSjohnjiang printf("Test Failed\n");
814418919fSjohnjiang fflush(stdout);
824418919fSjohnjiang }
834418919fSjohnjiang
844418919fSjohnjiang cmdline_parse_token_string_t cmd_autotest_autotest =
854418919fSjohnjiang TOKEN_STRING_INITIALIZER(struct cmd_autotest_result, autotest,
864418919fSjohnjiang "");
874418919fSjohnjiang
884418919fSjohnjiang cmdline_parse_inst_t cmd_autotest = {
894418919fSjohnjiang .f = cmd_autotest_parsed, /* function to call */
904418919fSjohnjiang .data = NULL, /* 2nd arg of func */
914418919fSjohnjiang .help_str = "launch autotest",
924418919fSjohnjiang .tokens = { /* token list, NULL terminated */
934418919fSjohnjiang (void *)&cmd_autotest_autotest,
944418919fSjohnjiang NULL,
954418919fSjohnjiang },
964418919fSjohnjiang };
974418919fSjohnjiang
984418919fSjohnjiang /****************/
994418919fSjohnjiang
1004418919fSjohnjiang struct cmd_dump_result {
1014418919fSjohnjiang cmdline_fixed_string_t dump;
1024418919fSjohnjiang };
1034418919fSjohnjiang
1044418919fSjohnjiang static void
dump_struct_sizes(void)1054418919fSjohnjiang dump_struct_sizes(void)
1064418919fSjohnjiang {
1074418919fSjohnjiang #define DUMP_SIZE(t) printf("sizeof(" #t ") = %u\n", (unsigned)sizeof(t));
1084418919fSjohnjiang DUMP_SIZE(struct rte_mbuf);
1094418919fSjohnjiang DUMP_SIZE(struct rte_mempool);
1104418919fSjohnjiang DUMP_SIZE(struct rte_ring);
1114418919fSjohnjiang #undef DUMP_SIZE
1124418919fSjohnjiang }
1134418919fSjohnjiang
cmd_dump_parsed(void * parsed_result,__rte_unused struct cmdline * cl,__rte_unused void * data)1144418919fSjohnjiang static void cmd_dump_parsed(void *parsed_result,
115*2d9fd380Sjfb8856606 __rte_unused struct cmdline *cl,
116*2d9fd380Sjfb8856606 __rte_unused void *data)
1174418919fSjohnjiang {
1184418919fSjohnjiang struct cmd_dump_result *res = parsed_result;
1194418919fSjohnjiang
1204418919fSjohnjiang if (!strcmp(res->dump, "dump_physmem"))
1214418919fSjohnjiang rte_dump_physmem_layout(stdout);
1224418919fSjohnjiang else if (!strcmp(res->dump, "dump_memzone"))
1234418919fSjohnjiang rte_memzone_dump(stdout);
1244418919fSjohnjiang else if (!strcmp(res->dump, "dump_struct_sizes"))
1254418919fSjohnjiang dump_struct_sizes();
1264418919fSjohnjiang else if (!strcmp(res->dump, "dump_ring"))
1274418919fSjohnjiang rte_ring_list_dump(stdout);
1284418919fSjohnjiang else if (!strcmp(res->dump, "dump_mempool"))
1294418919fSjohnjiang rte_mempool_list_dump(stdout);
1304418919fSjohnjiang else if (!strcmp(res->dump, "dump_devargs"))
1314418919fSjohnjiang rte_devargs_dump(stdout);
1324418919fSjohnjiang else if (!strcmp(res->dump, "dump_log_types"))
1334418919fSjohnjiang rte_log_dump(stdout);
1344418919fSjohnjiang else if (!strcmp(res->dump, "dump_malloc_stats"))
1354418919fSjohnjiang rte_malloc_dump_stats(stdout, NULL);
1364418919fSjohnjiang else if (!strcmp(res->dump, "dump_malloc_heaps"))
1374418919fSjohnjiang rte_malloc_dump_heaps(stdout);
1384418919fSjohnjiang }
1394418919fSjohnjiang
1404418919fSjohnjiang cmdline_parse_token_string_t cmd_dump_dump =
1414418919fSjohnjiang TOKEN_STRING_INITIALIZER(struct cmd_dump_result, dump,
1424418919fSjohnjiang "dump_physmem#"
1434418919fSjohnjiang "dump_memzone#"
1444418919fSjohnjiang "dump_struct_sizes#"
1454418919fSjohnjiang "dump_ring#"
1464418919fSjohnjiang "dump_mempool#"
1474418919fSjohnjiang "dump_malloc_stats#"
1484418919fSjohnjiang "dump_malloc_heaps#"
1494418919fSjohnjiang "dump_devargs#"
1504418919fSjohnjiang "dump_log_types");
1514418919fSjohnjiang
1524418919fSjohnjiang cmdline_parse_inst_t cmd_dump = {
1534418919fSjohnjiang .f = cmd_dump_parsed, /* function to call */
1544418919fSjohnjiang .data = NULL, /* 2nd arg of func */
1554418919fSjohnjiang .help_str = "dump status",
1564418919fSjohnjiang .tokens = { /* token list, NULL terminated */
1574418919fSjohnjiang (void *)&cmd_dump_dump,
1584418919fSjohnjiang NULL,
1594418919fSjohnjiang },
1604418919fSjohnjiang };
1614418919fSjohnjiang
1624418919fSjohnjiang /****************/
1634418919fSjohnjiang
1644418919fSjohnjiang struct cmd_dump_one_result {
1654418919fSjohnjiang cmdline_fixed_string_t dump;
1664418919fSjohnjiang cmdline_fixed_string_t name;
1674418919fSjohnjiang };
1684418919fSjohnjiang
cmd_dump_one_parsed(void * parsed_result,struct cmdline * cl,__rte_unused void * data)1694418919fSjohnjiang static void cmd_dump_one_parsed(void *parsed_result, struct cmdline *cl,
170*2d9fd380Sjfb8856606 __rte_unused void *data)
1714418919fSjohnjiang {
1724418919fSjohnjiang struct cmd_dump_one_result *res = parsed_result;
1734418919fSjohnjiang
1744418919fSjohnjiang if (!strcmp(res->dump, "dump_ring")) {
1754418919fSjohnjiang struct rte_ring *r;
1764418919fSjohnjiang r = rte_ring_lookup(res->name);
1774418919fSjohnjiang if (r == NULL) {
1784418919fSjohnjiang cmdline_printf(cl, "Cannot find ring\n");
1794418919fSjohnjiang return;
1804418919fSjohnjiang }
1814418919fSjohnjiang rte_ring_dump(stdout, r);
1824418919fSjohnjiang }
1834418919fSjohnjiang else if (!strcmp(res->dump, "dump_mempool")) {
1844418919fSjohnjiang struct rte_mempool *mp;
1854418919fSjohnjiang mp = rte_mempool_lookup(res->name);
1864418919fSjohnjiang if (mp == NULL) {
1874418919fSjohnjiang cmdline_printf(cl, "Cannot find mempool\n");
1884418919fSjohnjiang return;
1894418919fSjohnjiang }
1904418919fSjohnjiang rte_mempool_dump(stdout, mp);
1914418919fSjohnjiang }
1924418919fSjohnjiang }
1934418919fSjohnjiang
1944418919fSjohnjiang cmdline_parse_token_string_t cmd_dump_one_dump =
1954418919fSjohnjiang TOKEN_STRING_INITIALIZER(struct cmd_dump_one_result, dump,
1964418919fSjohnjiang "dump_ring#dump_mempool");
1974418919fSjohnjiang
1984418919fSjohnjiang cmdline_parse_token_string_t cmd_dump_one_name =
1994418919fSjohnjiang TOKEN_STRING_INITIALIZER(struct cmd_dump_one_result, name, NULL);
2004418919fSjohnjiang
2014418919fSjohnjiang cmdline_parse_inst_t cmd_dump_one = {
2024418919fSjohnjiang .f = cmd_dump_one_parsed, /* function to call */
2034418919fSjohnjiang .data = NULL, /* 2nd arg of func */
2044418919fSjohnjiang .help_str = "dump one ring/mempool: dump_ring|dump_mempool <name>",
2054418919fSjohnjiang .tokens = { /* token list, NULL terminated */
2064418919fSjohnjiang (void *)&cmd_dump_one_dump,
2074418919fSjohnjiang (void *)&cmd_dump_one_name,
2084418919fSjohnjiang NULL,
2094418919fSjohnjiang },
2104418919fSjohnjiang };
2114418919fSjohnjiang
2124418919fSjohnjiang /****************/
2134418919fSjohnjiang
2144418919fSjohnjiang struct cmd_quit_result {
2154418919fSjohnjiang cmdline_fixed_string_t quit;
2164418919fSjohnjiang };
2174418919fSjohnjiang
2184418919fSjohnjiang static void
cmd_quit_parsed(__rte_unused void * parsed_result,struct cmdline * cl,__rte_unused void * data)219*2d9fd380Sjfb8856606 cmd_quit_parsed(__rte_unused void *parsed_result,
2204418919fSjohnjiang struct cmdline *cl,
221*2d9fd380Sjfb8856606 __rte_unused void *data)
2224418919fSjohnjiang {
2234418919fSjohnjiang cmdline_quit(cl);
2244418919fSjohnjiang }
2254418919fSjohnjiang
2264418919fSjohnjiang cmdline_parse_token_string_t cmd_quit_quit =
2274418919fSjohnjiang TOKEN_STRING_INITIALIZER(struct cmd_quit_result, quit,
2284418919fSjohnjiang "quit");
2294418919fSjohnjiang
2304418919fSjohnjiang cmdline_parse_inst_t cmd_quit = {
2314418919fSjohnjiang .f = cmd_quit_parsed, /* function to call */
2324418919fSjohnjiang .data = NULL, /* 2nd arg of func */
2334418919fSjohnjiang .help_str = "exit application",
2344418919fSjohnjiang .tokens = { /* token list, NULL terminated */
2354418919fSjohnjiang (void *)&cmd_quit_quit,
2364418919fSjohnjiang NULL,
2374418919fSjohnjiang },
2384418919fSjohnjiang };
2394418919fSjohnjiang
2404418919fSjohnjiang /****************/
2414418919fSjohnjiang
2424418919fSjohnjiang struct cmd_set_rxtx_result {
2434418919fSjohnjiang cmdline_fixed_string_t set;
2444418919fSjohnjiang cmdline_fixed_string_t mode;
2454418919fSjohnjiang };
2464418919fSjohnjiang
cmd_set_rxtx_parsed(void * parsed_result,struct cmdline * cl,__rte_unused void * data)2474418919fSjohnjiang static void cmd_set_rxtx_parsed(void *parsed_result, struct cmdline *cl,
248*2d9fd380Sjfb8856606 __rte_unused void *data)
2494418919fSjohnjiang {
2504418919fSjohnjiang struct cmd_set_rxtx_result *res = parsed_result;
2514418919fSjohnjiang if (test_set_rxtx_conf(res->mode) < 0)
2524418919fSjohnjiang cmdline_printf(cl, "Cannot find such mode\n");
2534418919fSjohnjiang }
2544418919fSjohnjiang
2554418919fSjohnjiang cmdline_parse_token_string_t cmd_set_rxtx_set =
2564418919fSjohnjiang TOKEN_STRING_INITIALIZER(struct cmd_set_rxtx_result, set,
2574418919fSjohnjiang "set_rxtx_mode");
2584418919fSjohnjiang
2594418919fSjohnjiang cmdline_parse_token_string_t cmd_set_rxtx_mode =
2604418919fSjohnjiang TOKEN_STRING_INITIALIZER(struct cmd_set_rxtx_result, mode, NULL);
2614418919fSjohnjiang
2624418919fSjohnjiang cmdline_parse_inst_t cmd_set_rxtx = {
2634418919fSjohnjiang .f = cmd_set_rxtx_parsed, /* function to call */
2644418919fSjohnjiang .data = NULL, /* 2nd arg of func */
2654418919fSjohnjiang .help_str = "set rxtx routine: "
2664418919fSjohnjiang "set_rxtx <mode>",
2674418919fSjohnjiang .tokens = { /* token list, NULL terminated */
2684418919fSjohnjiang (void *)&cmd_set_rxtx_set,
2694418919fSjohnjiang (void *)&cmd_set_rxtx_mode,
2704418919fSjohnjiang NULL,
2714418919fSjohnjiang },
2724418919fSjohnjiang };
2734418919fSjohnjiang
2744418919fSjohnjiang /****************/
2754418919fSjohnjiang
2764418919fSjohnjiang struct cmd_set_rxtx_anchor {
2774418919fSjohnjiang cmdline_fixed_string_t set;
2784418919fSjohnjiang cmdline_fixed_string_t type;
2794418919fSjohnjiang };
2804418919fSjohnjiang
2814418919fSjohnjiang static void
cmd_set_rxtx_anchor_parsed(void * parsed_result,struct cmdline * cl,__rte_unused void * data)2824418919fSjohnjiang cmd_set_rxtx_anchor_parsed(void *parsed_result,
2834418919fSjohnjiang struct cmdline *cl,
284*2d9fd380Sjfb8856606 __rte_unused void *data)
2854418919fSjohnjiang {
2864418919fSjohnjiang struct cmd_set_rxtx_anchor *res = parsed_result;
2874418919fSjohnjiang if (test_set_rxtx_anchor(res->type) < 0)
2884418919fSjohnjiang cmdline_printf(cl, "Cannot find such anchor\n");
2894418919fSjohnjiang }
2904418919fSjohnjiang
2914418919fSjohnjiang cmdline_parse_token_string_t cmd_set_rxtx_anchor_set =
2924418919fSjohnjiang TOKEN_STRING_INITIALIZER(struct cmd_set_rxtx_anchor, set,
2934418919fSjohnjiang "set_rxtx_anchor");
2944418919fSjohnjiang
2954418919fSjohnjiang cmdline_parse_token_string_t cmd_set_rxtx_anchor_type =
2964418919fSjohnjiang TOKEN_STRING_INITIALIZER(struct cmd_set_rxtx_anchor, type, NULL);
2974418919fSjohnjiang
2984418919fSjohnjiang cmdline_parse_inst_t cmd_set_rxtx_anchor = {
2994418919fSjohnjiang .f = cmd_set_rxtx_anchor_parsed, /* function to call */
3004418919fSjohnjiang .data = NULL, /* 2nd arg of func */
3014418919fSjohnjiang .help_str = "set rxtx anchor: "
3024418919fSjohnjiang "set_rxtx_anchor <type>",
3034418919fSjohnjiang .tokens = { /* token list, NULL terminated */
3044418919fSjohnjiang (void *)&cmd_set_rxtx_anchor_set,
3054418919fSjohnjiang (void *)&cmd_set_rxtx_anchor_type,
3064418919fSjohnjiang NULL,
3074418919fSjohnjiang },
3084418919fSjohnjiang };
3094418919fSjohnjiang
3104418919fSjohnjiang /****************/
3114418919fSjohnjiang
3124418919fSjohnjiang /* for stream control */
3134418919fSjohnjiang struct cmd_set_rxtx_sc {
3144418919fSjohnjiang cmdline_fixed_string_t set;
3154418919fSjohnjiang cmdline_fixed_string_t type;
3164418919fSjohnjiang };
3174418919fSjohnjiang
3184418919fSjohnjiang static void
cmd_set_rxtx_sc_parsed(void * parsed_result,struct cmdline * cl,__rte_unused void * data)3194418919fSjohnjiang cmd_set_rxtx_sc_parsed(void *parsed_result,
3204418919fSjohnjiang struct cmdline *cl,
321*2d9fd380Sjfb8856606 __rte_unused void *data)
3224418919fSjohnjiang {
3234418919fSjohnjiang struct cmd_set_rxtx_sc *res = parsed_result;
3244418919fSjohnjiang if (test_set_rxtx_sc(res->type) < 0)
3254418919fSjohnjiang cmdline_printf(cl, "Cannot find such stream control\n");
3264418919fSjohnjiang }
3274418919fSjohnjiang
3284418919fSjohnjiang cmdline_parse_token_string_t cmd_set_rxtx_sc_set =
3294418919fSjohnjiang TOKEN_STRING_INITIALIZER(struct cmd_set_rxtx_sc, set,
3304418919fSjohnjiang "set_rxtx_sc");
3314418919fSjohnjiang
3324418919fSjohnjiang cmdline_parse_token_string_t cmd_set_rxtx_sc_type =
3334418919fSjohnjiang TOKEN_STRING_INITIALIZER(struct cmd_set_rxtx_sc, type, NULL);
3344418919fSjohnjiang
3354418919fSjohnjiang cmdline_parse_inst_t cmd_set_rxtx_sc = {
3364418919fSjohnjiang .f = cmd_set_rxtx_sc_parsed, /* function to call */
3374418919fSjohnjiang .data = NULL, /* 2nd arg of func */
3384418919fSjohnjiang .help_str = "set rxtx stream control: "
3394418919fSjohnjiang "set_rxtx_sc <type>",
3404418919fSjohnjiang .tokens = { /* token list, NULL terminated */
3414418919fSjohnjiang (void *)&cmd_set_rxtx_sc_set,
3424418919fSjohnjiang (void *)&cmd_set_rxtx_sc_type,
3434418919fSjohnjiang NULL,
3444418919fSjohnjiang },
3454418919fSjohnjiang };
3464418919fSjohnjiang
3474418919fSjohnjiang /****************/
3484418919fSjohnjiang
3494418919fSjohnjiang
3504418919fSjohnjiang cmdline_parse_ctx_t main_ctx[] = {
3514418919fSjohnjiang (cmdline_parse_inst_t *)&cmd_autotest,
3524418919fSjohnjiang (cmdline_parse_inst_t *)&cmd_dump,
3534418919fSjohnjiang (cmdline_parse_inst_t *)&cmd_dump_one,
3544418919fSjohnjiang (cmdline_parse_inst_t *)&cmd_quit,
3554418919fSjohnjiang (cmdline_parse_inst_t *)&cmd_set_rxtx,
3564418919fSjohnjiang (cmdline_parse_inst_t *)&cmd_set_rxtx_anchor,
3574418919fSjohnjiang (cmdline_parse_inst_t *)&cmd_set_rxtx_sc,
3584418919fSjohnjiang NULL,
3594418919fSjohnjiang };
3604418919fSjohnjiang
commands_init(void)3614418919fSjohnjiang int commands_init(void)
3624418919fSjohnjiang {
3634418919fSjohnjiang struct test_command *t;
3644418919fSjohnjiang char *commands;
3654418919fSjohnjiang int commands_len = 0;
3664418919fSjohnjiang
3674418919fSjohnjiang TAILQ_FOREACH(t, &commands_list, next) {
3684418919fSjohnjiang commands_len += strlen(t->command) + 1;
3694418919fSjohnjiang }
3704418919fSjohnjiang
3714418919fSjohnjiang commands = (char *)calloc(commands_len, sizeof(char));
3724418919fSjohnjiang if (!commands)
3734418919fSjohnjiang return -1;
3744418919fSjohnjiang
3754418919fSjohnjiang TAILQ_FOREACH(t, &commands_list, next) {
3764418919fSjohnjiang strlcat(commands, t->command, commands_len);
3774418919fSjohnjiang if (TAILQ_NEXT(t, next) != NULL)
3784418919fSjohnjiang strlcat(commands, "#", commands_len);
3794418919fSjohnjiang }
3804418919fSjohnjiang
3814418919fSjohnjiang cmd_autotest_autotest.string_data.str = commands;
3824418919fSjohnjiang return 0;
3834418919fSjohnjiang }
384