1a9de470cSBruce Richardson /* SPDX-License-Identifier: BSD-3-Clause 2a9de470cSBruce Richardson * Copyright(c) 2010-2014 Intel Corporation. 3a9de470cSBruce Richardson * Copyright(c) 2014 6WIND S.A. 4a9de470cSBruce Richardson */ 5a9de470cSBruce Richardson 6a9de470cSBruce Richardson #include <stdio.h> 7a9de470cSBruce Richardson #include <stdarg.h> 8a9de470cSBruce Richardson #include <stdint.h> 9a9de470cSBruce Richardson #include <string.h> 10a9de470cSBruce Richardson #include <stdlib.h> 11a9de470cSBruce Richardson #include <netinet/in.h> 12a9de470cSBruce Richardson #include <termios.h> 13a9de470cSBruce Richardson #ifndef __linux__ 14a9de470cSBruce Richardson #ifndef __FreeBSD__ 15a9de470cSBruce Richardson #include <net/socket.h> 16a9de470cSBruce Richardson #endif 17a9de470cSBruce Richardson #endif 18a9de470cSBruce Richardson #include <inttypes.h> 19a9de470cSBruce Richardson #include <errno.h> 20a9de470cSBruce Richardson #include <sys/queue.h> 21a9de470cSBruce Richardson 22a9de470cSBruce Richardson #include <rte_common.h> 23a9de470cSBruce Richardson #include <rte_log.h> 24a9de470cSBruce Richardson #include <rte_debug.h> 25a9de470cSBruce Richardson #include <rte_memory.h> 26a9de470cSBruce Richardson #include <rte_memcpy.h> 27a9de470cSBruce Richardson #include <rte_memzone.h> 28a9de470cSBruce Richardson #include <rte_launch.h> 29a9de470cSBruce Richardson #include <rte_cycles.h> 30a9de470cSBruce Richardson #include <rte_eal.h> 31a9de470cSBruce Richardson #include <rte_per_lcore.h> 32a9de470cSBruce Richardson #include <rte_lcore.h> 33a9de470cSBruce Richardson #include <rte_atomic.h> 34a9de470cSBruce Richardson #include <rte_branch_prediction.h> 35a9de470cSBruce Richardson #include <rte_ring.h> 36a9de470cSBruce Richardson #include <rte_malloc.h> 37a9de470cSBruce Richardson #include <rte_mempool.h> 38a9de470cSBruce Richardson #include <rte_mbuf.h> 39a9de470cSBruce Richardson #include <rte_devargs.h> 40a9de470cSBruce Richardson 41a9de470cSBruce Richardson #include <cmdline_rdline.h> 42a9de470cSBruce Richardson #include <cmdline_parse.h> 43a9de470cSBruce Richardson #include <cmdline_parse_ipaddr.h> 44a9de470cSBruce Richardson #include <cmdline_parse_num.h> 45a9de470cSBruce Richardson #include <cmdline_parse_string.h> 46a9de470cSBruce Richardson #include <cmdline.h> 47*32364372SPallantla Poornima #include <rte_string_fns.h> 48a9de470cSBruce Richardson 49a9de470cSBruce Richardson #include "test.h" 50a9de470cSBruce Richardson 51a9de470cSBruce Richardson /****************/ 52a9de470cSBruce Richardson 53a9de470cSBruce Richardson static struct test_commands_list commands_list = 54a9de470cSBruce Richardson TAILQ_HEAD_INITIALIZER(commands_list); 55a9de470cSBruce Richardson 56a9de470cSBruce Richardson void 57a9de470cSBruce Richardson add_test_command(struct test_command *t) 58a9de470cSBruce Richardson { 59a9de470cSBruce Richardson TAILQ_INSERT_TAIL(&commands_list, t, next); 60a9de470cSBruce Richardson } 61a9de470cSBruce Richardson 62a9de470cSBruce Richardson struct cmd_autotest_result { 63a9de470cSBruce Richardson cmdline_fixed_string_t autotest; 64a9de470cSBruce Richardson }; 65a9de470cSBruce Richardson 66a9de470cSBruce Richardson static void cmd_autotest_parsed(void *parsed_result, 67a9de470cSBruce Richardson __attribute__((unused)) struct cmdline *cl, 68a9de470cSBruce Richardson __attribute__((unused)) void *data) 69a9de470cSBruce Richardson { 70a9de470cSBruce Richardson struct test_command *t; 71a9de470cSBruce Richardson struct cmd_autotest_result *res = parsed_result; 72a9de470cSBruce Richardson int ret = 0; 73a9de470cSBruce Richardson 74a9de470cSBruce Richardson TAILQ_FOREACH(t, &commands_list, next) { 75a9de470cSBruce Richardson if (!strcmp(res->autotest, t->command)) 76a9de470cSBruce Richardson ret = t->callback(); 77a9de470cSBruce Richardson } 78a9de470cSBruce Richardson 79a9de470cSBruce Richardson last_test_result = ret; 80a9de470cSBruce Richardson if (ret == 0) 81a9de470cSBruce Richardson printf("Test OK\n"); 82a9de470cSBruce Richardson else if (ret == TEST_SKIPPED) 83a9de470cSBruce Richardson printf("Test Skipped\n"); 84a9de470cSBruce Richardson else 85a9de470cSBruce Richardson printf("Test Failed\n"); 86a9de470cSBruce Richardson fflush(stdout); 87a9de470cSBruce Richardson } 88a9de470cSBruce Richardson 89a9de470cSBruce Richardson cmdline_parse_token_string_t cmd_autotest_autotest = 90a9de470cSBruce Richardson TOKEN_STRING_INITIALIZER(struct cmd_autotest_result, autotest, 91a9de470cSBruce Richardson ""); 92a9de470cSBruce Richardson 93a9de470cSBruce Richardson cmdline_parse_inst_t cmd_autotest = { 94a9de470cSBruce Richardson .f = cmd_autotest_parsed, /* function to call */ 95a9de470cSBruce Richardson .data = NULL, /* 2nd arg of func */ 96a9de470cSBruce Richardson .help_str = "launch autotest", 97a9de470cSBruce Richardson .tokens = { /* token list, NULL terminated */ 98a9de470cSBruce Richardson (void *)&cmd_autotest_autotest, 99a9de470cSBruce Richardson NULL, 100a9de470cSBruce Richardson }, 101a9de470cSBruce Richardson }; 102a9de470cSBruce Richardson 103a9de470cSBruce Richardson /****************/ 104a9de470cSBruce Richardson 105a9de470cSBruce Richardson struct cmd_dump_result { 106a9de470cSBruce Richardson cmdline_fixed_string_t dump; 107a9de470cSBruce Richardson }; 108a9de470cSBruce Richardson 109a9de470cSBruce Richardson static void 110a9de470cSBruce Richardson dump_struct_sizes(void) 111a9de470cSBruce Richardson { 112a9de470cSBruce Richardson #define DUMP_SIZE(t) printf("sizeof(" #t ") = %u\n", (unsigned)sizeof(t)); 113a9de470cSBruce Richardson DUMP_SIZE(struct rte_mbuf); 114a9de470cSBruce Richardson DUMP_SIZE(struct rte_mempool); 115a9de470cSBruce Richardson DUMP_SIZE(struct rte_ring); 116a9de470cSBruce Richardson #undef DUMP_SIZE 117a9de470cSBruce Richardson } 118a9de470cSBruce Richardson 119a9de470cSBruce Richardson static void cmd_dump_parsed(void *parsed_result, 120a9de470cSBruce Richardson __attribute__((unused)) struct cmdline *cl, 121a9de470cSBruce Richardson __attribute__((unused)) void *data) 122a9de470cSBruce Richardson { 123a9de470cSBruce Richardson struct cmd_dump_result *res = parsed_result; 124a9de470cSBruce Richardson 125a9de470cSBruce Richardson if (!strcmp(res->dump, "dump_physmem")) 126a9de470cSBruce Richardson rte_dump_physmem_layout(stdout); 127a9de470cSBruce Richardson else if (!strcmp(res->dump, "dump_memzone")) 128a9de470cSBruce Richardson rte_memzone_dump(stdout); 129a9de470cSBruce Richardson else if (!strcmp(res->dump, "dump_struct_sizes")) 130a9de470cSBruce Richardson dump_struct_sizes(); 131a9de470cSBruce Richardson else if (!strcmp(res->dump, "dump_ring")) 132a9de470cSBruce Richardson rte_ring_list_dump(stdout); 133a9de470cSBruce Richardson else if (!strcmp(res->dump, "dump_mempool")) 134a9de470cSBruce Richardson rte_mempool_list_dump(stdout); 135a9de470cSBruce Richardson else if (!strcmp(res->dump, "dump_devargs")) 136a9de470cSBruce Richardson rte_devargs_dump(stdout); 137a9de470cSBruce Richardson else if (!strcmp(res->dump, "dump_log_types")) 138a9de470cSBruce Richardson rte_log_dump(stdout); 139a9de470cSBruce Richardson else if (!strcmp(res->dump, "dump_malloc_stats")) 140a9de470cSBruce Richardson rte_malloc_dump_stats(stdout, NULL); 141a9de470cSBruce Richardson else if (!strcmp(res->dump, "dump_malloc_heaps")) 142a9de470cSBruce Richardson rte_malloc_dump_heaps(stdout); 143a9de470cSBruce Richardson } 144a9de470cSBruce Richardson 145a9de470cSBruce Richardson cmdline_parse_token_string_t cmd_dump_dump = 146a9de470cSBruce Richardson TOKEN_STRING_INITIALIZER(struct cmd_dump_result, dump, 147a9de470cSBruce Richardson "dump_physmem#" 148a9de470cSBruce Richardson "dump_memzone#" 149a9de470cSBruce Richardson "dump_struct_sizes#" 150a9de470cSBruce Richardson "dump_ring#" 151a9de470cSBruce Richardson "dump_mempool#" 152a9de470cSBruce Richardson "dump_malloc_stats#" 153a9de470cSBruce Richardson "dump_malloc_heaps#" 154a9de470cSBruce Richardson "dump_devargs#" 155a9de470cSBruce Richardson "dump_log_types"); 156a9de470cSBruce Richardson 157a9de470cSBruce Richardson cmdline_parse_inst_t cmd_dump = { 158a9de470cSBruce Richardson .f = cmd_dump_parsed, /* function to call */ 159a9de470cSBruce Richardson .data = NULL, /* 2nd arg of func */ 160a9de470cSBruce Richardson .help_str = "dump status", 161a9de470cSBruce Richardson .tokens = { /* token list, NULL terminated */ 162a9de470cSBruce Richardson (void *)&cmd_dump_dump, 163a9de470cSBruce Richardson NULL, 164a9de470cSBruce Richardson }, 165a9de470cSBruce Richardson }; 166a9de470cSBruce Richardson 167a9de470cSBruce Richardson /****************/ 168a9de470cSBruce Richardson 169a9de470cSBruce Richardson struct cmd_dump_one_result { 170a9de470cSBruce Richardson cmdline_fixed_string_t dump; 171a9de470cSBruce Richardson cmdline_fixed_string_t name; 172a9de470cSBruce Richardson }; 173a9de470cSBruce Richardson 174a9de470cSBruce Richardson static void cmd_dump_one_parsed(void *parsed_result, struct cmdline *cl, 175a9de470cSBruce Richardson __attribute__((unused)) void *data) 176a9de470cSBruce Richardson { 177a9de470cSBruce Richardson struct cmd_dump_one_result *res = parsed_result; 178a9de470cSBruce Richardson 179a9de470cSBruce Richardson if (!strcmp(res->dump, "dump_ring")) { 180a9de470cSBruce Richardson struct rte_ring *r; 181a9de470cSBruce Richardson r = rte_ring_lookup(res->name); 182a9de470cSBruce Richardson if (r == NULL) { 183a9de470cSBruce Richardson cmdline_printf(cl, "Cannot find ring\n"); 184a9de470cSBruce Richardson return; 185a9de470cSBruce Richardson } 186a9de470cSBruce Richardson rte_ring_dump(stdout, r); 187a9de470cSBruce Richardson } 188a9de470cSBruce Richardson else if (!strcmp(res->dump, "dump_mempool")) { 189a9de470cSBruce Richardson struct rte_mempool *mp; 190a9de470cSBruce Richardson mp = rte_mempool_lookup(res->name); 191a9de470cSBruce Richardson if (mp == NULL) { 192a9de470cSBruce Richardson cmdline_printf(cl, "Cannot find mempool\n"); 193a9de470cSBruce Richardson return; 194a9de470cSBruce Richardson } 195a9de470cSBruce Richardson rte_mempool_dump(stdout, mp); 196a9de470cSBruce Richardson } 197a9de470cSBruce Richardson } 198a9de470cSBruce Richardson 199a9de470cSBruce Richardson cmdline_parse_token_string_t cmd_dump_one_dump = 200a9de470cSBruce Richardson TOKEN_STRING_INITIALIZER(struct cmd_dump_one_result, dump, 201a9de470cSBruce Richardson "dump_ring#dump_mempool"); 202a9de470cSBruce Richardson 203a9de470cSBruce Richardson cmdline_parse_token_string_t cmd_dump_one_name = 204a9de470cSBruce Richardson TOKEN_STRING_INITIALIZER(struct cmd_dump_one_result, name, NULL); 205a9de470cSBruce Richardson 206a9de470cSBruce Richardson cmdline_parse_inst_t cmd_dump_one = { 207a9de470cSBruce Richardson .f = cmd_dump_one_parsed, /* function to call */ 208a9de470cSBruce Richardson .data = NULL, /* 2nd arg of func */ 209a9de470cSBruce Richardson .help_str = "dump one ring/mempool: dump_ring|dump_mempool <name>", 210a9de470cSBruce Richardson .tokens = { /* token list, NULL terminated */ 211a9de470cSBruce Richardson (void *)&cmd_dump_one_dump, 212a9de470cSBruce Richardson (void *)&cmd_dump_one_name, 213a9de470cSBruce Richardson NULL, 214a9de470cSBruce Richardson }, 215a9de470cSBruce Richardson }; 216a9de470cSBruce Richardson 217a9de470cSBruce Richardson /****************/ 218a9de470cSBruce Richardson 219a9de470cSBruce Richardson struct cmd_quit_result { 220a9de470cSBruce Richardson cmdline_fixed_string_t quit; 221a9de470cSBruce Richardson }; 222a9de470cSBruce Richardson 223a9de470cSBruce Richardson static void 224a9de470cSBruce Richardson cmd_quit_parsed(__attribute__((unused)) void *parsed_result, 225a9de470cSBruce Richardson struct cmdline *cl, 226a9de470cSBruce Richardson __attribute__((unused)) void *data) 227a9de470cSBruce Richardson { 228a9de470cSBruce Richardson cmdline_quit(cl); 229a9de470cSBruce Richardson } 230a9de470cSBruce Richardson 231a9de470cSBruce Richardson cmdline_parse_token_string_t cmd_quit_quit = 232a9de470cSBruce Richardson TOKEN_STRING_INITIALIZER(struct cmd_quit_result, quit, 233a9de470cSBruce Richardson "quit"); 234a9de470cSBruce Richardson 235a9de470cSBruce Richardson cmdline_parse_inst_t cmd_quit = { 236a9de470cSBruce Richardson .f = cmd_quit_parsed, /* function to call */ 237a9de470cSBruce Richardson .data = NULL, /* 2nd arg of func */ 238a9de470cSBruce Richardson .help_str = "exit application", 239a9de470cSBruce Richardson .tokens = { /* token list, NULL terminated */ 240a9de470cSBruce Richardson (void *)&cmd_quit_quit, 241a9de470cSBruce Richardson NULL, 242a9de470cSBruce Richardson }, 243a9de470cSBruce Richardson }; 244a9de470cSBruce Richardson 245a9de470cSBruce Richardson /****************/ 246a9de470cSBruce Richardson 247a9de470cSBruce Richardson struct cmd_set_rxtx_result { 248a9de470cSBruce Richardson cmdline_fixed_string_t set; 249a9de470cSBruce Richardson cmdline_fixed_string_t mode; 250a9de470cSBruce Richardson }; 251a9de470cSBruce Richardson 252a9de470cSBruce Richardson static void cmd_set_rxtx_parsed(void *parsed_result, struct cmdline *cl, 253a9de470cSBruce Richardson __attribute__((unused)) void *data) 254a9de470cSBruce Richardson { 255a9de470cSBruce Richardson struct cmd_set_rxtx_result *res = parsed_result; 256a9de470cSBruce Richardson if (test_set_rxtx_conf(res->mode) < 0) 257a9de470cSBruce Richardson cmdline_printf(cl, "Cannot find such mode\n"); 258a9de470cSBruce Richardson } 259a9de470cSBruce Richardson 260a9de470cSBruce Richardson cmdline_parse_token_string_t cmd_set_rxtx_set = 261a9de470cSBruce Richardson TOKEN_STRING_INITIALIZER(struct cmd_set_rxtx_result, set, 262a9de470cSBruce Richardson "set_rxtx_mode"); 263a9de470cSBruce Richardson 264a9de470cSBruce Richardson cmdline_parse_token_string_t cmd_set_rxtx_mode = 265a9de470cSBruce Richardson TOKEN_STRING_INITIALIZER(struct cmd_set_rxtx_result, mode, NULL); 266a9de470cSBruce Richardson 267a9de470cSBruce Richardson cmdline_parse_inst_t cmd_set_rxtx = { 268a9de470cSBruce Richardson .f = cmd_set_rxtx_parsed, /* function to call */ 269a9de470cSBruce Richardson .data = NULL, /* 2nd arg of func */ 270a9de470cSBruce Richardson .help_str = "set rxtx routine: " 271a9de470cSBruce Richardson "set_rxtx <mode>", 272a9de470cSBruce Richardson .tokens = { /* token list, NULL terminated */ 273a9de470cSBruce Richardson (void *)&cmd_set_rxtx_set, 274a9de470cSBruce Richardson (void *)&cmd_set_rxtx_mode, 275a9de470cSBruce Richardson NULL, 276a9de470cSBruce Richardson }, 277a9de470cSBruce Richardson }; 278a9de470cSBruce Richardson 279a9de470cSBruce Richardson /****************/ 280a9de470cSBruce Richardson 281a9de470cSBruce Richardson struct cmd_set_rxtx_anchor { 282a9de470cSBruce Richardson cmdline_fixed_string_t set; 283a9de470cSBruce Richardson cmdline_fixed_string_t type; 284a9de470cSBruce Richardson }; 285a9de470cSBruce Richardson 286a9de470cSBruce Richardson static void 287a9de470cSBruce Richardson cmd_set_rxtx_anchor_parsed(void *parsed_result, 288a9de470cSBruce Richardson struct cmdline *cl, 289a9de470cSBruce Richardson __attribute__((unused)) void *data) 290a9de470cSBruce Richardson { 291a9de470cSBruce Richardson struct cmd_set_rxtx_anchor *res = parsed_result; 292a9de470cSBruce Richardson if (test_set_rxtx_anchor(res->type) < 0) 293a9de470cSBruce Richardson cmdline_printf(cl, "Cannot find such anchor\n"); 294a9de470cSBruce Richardson } 295a9de470cSBruce Richardson 296a9de470cSBruce Richardson cmdline_parse_token_string_t cmd_set_rxtx_anchor_set = 297a9de470cSBruce Richardson TOKEN_STRING_INITIALIZER(struct cmd_set_rxtx_anchor, set, 298a9de470cSBruce Richardson "set_rxtx_anchor"); 299a9de470cSBruce Richardson 300a9de470cSBruce Richardson cmdline_parse_token_string_t cmd_set_rxtx_anchor_type = 301a9de470cSBruce Richardson TOKEN_STRING_INITIALIZER(struct cmd_set_rxtx_anchor, type, NULL); 302a9de470cSBruce Richardson 303a9de470cSBruce Richardson cmdline_parse_inst_t cmd_set_rxtx_anchor = { 304a9de470cSBruce Richardson .f = cmd_set_rxtx_anchor_parsed, /* function to call */ 305a9de470cSBruce Richardson .data = NULL, /* 2nd arg of func */ 306a9de470cSBruce Richardson .help_str = "set rxtx anchor: " 307a9de470cSBruce Richardson "set_rxtx_anchor <type>", 308a9de470cSBruce Richardson .tokens = { /* token list, NULL terminated */ 309a9de470cSBruce Richardson (void *)&cmd_set_rxtx_anchor_set, 310a9de470cSBruce Richardson (void *)&cmd_set_rxtx_anchor_type, 311a9de470cSBruce Richardson NULL, 312a9de470cSBruce Richardson }, 313a9de470cSBruce Richardson }; 314a9de470cSBruce Richardson 315a9de470cSBruce Richardson /****************/ 316a9de470cSBruce Richardson 317a9de470cSBruce Richardson /* for stream control */ 318a9de470cSBruce Richardson struct cmd_set_rxtx_sc { 319a9de470cSBruce Richardson cmdline_fixed_string_t set; 320a9de470cSBruce Richardson cmdline_fixed_string_t type; 321a9de470cSBruce Richardson }; 322a9de470cSBruce Richardson 323a9de470cSBruce Richardson static void 324a9de470cSBruce Richardson cmd_set_rxtx_sc_parsed(void *parsed_result, 325a9de470cSBruce Richardson struct cmdline *cl, 326a9de470cSBruce Richardson __attribute__((unused)) void *data) 327a9de470cSBruce Richardson { 328a9de470cSBruce Richardson struct cmd_set_rxtx_sc *res = parsed_result; 329a9de470cSBruce Richardson if (test_set_rxtx_sc(res->type) < 0) 330a9de470cSBruce Richardson cmdline_printf(cl, "Cannot find such stream control\n"); 331a9de470cSBruce Richardson } 332a9de470cSBruce Richardson 333a9de470cSBruce Richardson cmdline_parse_token_string_t cmd_set_rxtx_sc_set = 334a9de470cSBruce Richardson TOKEN_STRING_INITIALIZER(struct cmd_set_rxtx_sc, set, 335a9de470cSBruce Richardson "set_rxtx_sc"); 336a9de470cSBruce Richardson 337a9de470cSBruce Richardson cmdline_parse_token_string_t cmd_set_rxtx_sc_type = 338a9de470cSBruce Richardson TOKEN_STRING_INITIALIZER(struct cmd_set_rxtx_sc, type, NULL); 339a9de470cSBruce Richardson 340a9de470cSBruce Richardson cmdline_parse_inst_t cmd_set_rxtx_sc = { 341a9de470cSBruce Richardson .f = cmd_set_rxtx_sc_parsed, /* function to call */ 342a9de470cSBruce Richardson .data = NULL, /* 2nd arg of func */ 343a9de470cSBruce Richardson .help_str = "set rxtx stream control: " 344a9de470cSBruce Richardson "set_rxtx_sc <type>", 345a9de470cSBruce Richardson .tokens = { /* token list, NULL terminated */ 346a9de470cSBruce Richardson (void *)&cmd_set_rxtx_sc_set, 347a9de470cSBruce Richardson (void *)&cmd_set_rxtx_sc_type, 348a9de470cSBruce Richardson NULL, 349a9de470cSBruce Richardson }, 350a9de470cSBruce Richardson }; 351a9de470cSBruce Richardson 352a9de470cSBruce Richardson /****************/ 353a9de470cSBruce Richardson 354a9de470cSBruce Richardson 355a9de470cSBruce Richardson cmdline_parse_ctx_t main_ctx[] = { 356a9de470cSBruce Richardson (cmdline_parse_inst_t *)&cmd_autotest, 357a9de470cSBruce Richardson (cmdline_parse_inst_t *)&cmd_dump, 358a9de470cSBruce Richardson (cmdline_parse_inst_t *)&cmd_dump_one, 359a9de470cSBruce Richardson (cmdline_parse_inst_t *)&cmd_quit, 360a9de470cSBruce Richardson (cmdline_parse_inst_t *)&cmd_set_rxtx, 361a9de470cSBruce Richardson (cmdline_parse_inst_t *)&cmd_set_rxtx_anchor, 362a9de470cSBruce Richardson (cmdline_parse_inst_t *)&cmd_set_rxtx_sc, 363a9de470cSBruce Richardson NULL, 364a9de470cSBruce Richardson }; 365a9de470cSBruce Richardson 366a9de470cSBruce Richardson int commands_init(void) 367a9de470cSBruce Richardson { 368a9de470cSBruce Richardson struct test_command *t; 369*32364372SPallantla Poornima char *commands; 370a9de470cSBruce Richardson int commands_len = 0; 371a9de470cSBruce Richardson 372a9de470cSBruce Richardson TAILQ_FOREACH(t, &commands_list, next) { 373a9de470cSBruce Richardson commands_len += strlen(t->command) + 1; 374a9de470cSBruce Richardson } 375a9de470cSBruce Richardson 376*32364372SPallantla Poornima commands = (char *)calloc(commands_len, sizeof(char)); 377a9de470cSBruce Richardson if (!commands) 378a9de470cSBruce Richardson return -1; 379a9de470cSBruce Richardson 380a9de470cSBruce Richardson TAILQ_FOREACH(t, &commands_list, next) { 381*32364372SPallantla Poornima strlcat(commands, t->command, commands_len); 382*32364372SPallantla Poornima if (TAILQ_NEXT(t, next) != NULL) 383*32364372SPallantla Poornima strlcat(commands, "#", commands_len); 384a9de470cSBruce Richardson } 385a9de470cSBruce Richardson 386a9de470cSBruce Richardson cmd_autotest_autotest.string_data.str = commands; 387a9de470cSBruce Richardson return 0; 388a9de470cSBruce Richardson } 389