xref: /dpdk/examples/pipeline/cli.c (revision 7fef9ef11ff790e2ea67fc0411d64a7e0457d375)
15074e1d5SCristian Dumitrescu /* SPDX-License-Identifier: BSD-3-Clause
25074e1d5SCristian Dumitrescu  * Copyright(c) 2020 Intel Corporation
35074e1d5SCristian Dumitrescu  */
45074e1d5SCristian Dumitrescu 
55074e1d5SCristian Dumitrescu #include <stdio.h>
65074e1d5SCristian Dumitrescu #include <stdint.h>
75074e1d5SCristian Dumitrescu #include <stdlib.h>
85074e1d5SCristian Dumitrescu #include <string.h>
95074e1d5SCristian Dumitrescu 
105074e1d5SCristian Dumitrescu #include <rte_common.h>
115074e1d5SCristian Dumitrescu #include <rte_ethdev.h>
125074e1d5SCristian Dumitrescu #include <rte_swx_port_ethdev.h>
135074e1d5SCristian Dumitrescu #include <rte_swx_port_source_sink.h>
145074e1d5SCristian Dumitrescu #include <rte_swx_pipeline.h>
155074e1d5SCristian Dumitrescu #include <rte_swx_ctl.h>
165074e1d5SCristian Dumitrescu 
175074e1d5SCristian Dumitrescu #include "cli.h"
185074e1d5SCristian Dumitrescu 
195074e1d5SCristian Dumitrescu #include "obj.h"
205074e1d5SCristian Dumitrescu #include "thread.h"
215074e1d5SCristian Dumitrescu 
225074e1d5SCristian Dumitrescu #ifndef CMD_MAX_TOKENS
235074e1d5SCristian Dumitrescu #define CMD_MAX_TOKENS     256
245074e1d5SCristian Dumitrescu #endif
255074e1d5SCristian Dumitrescu 
265074e1d5SCristian Dumitrescu #define MSG_OUT_OF_MEMORY   "Not enough memory.\n"
275074e1d5SCristian Dumitrescu #define MSG_CMD_UNKNOWN     "Unknown command \"%s\".\n"
285074e1d5SCristian Dumitrescu #define MSG_CMD_UNIMPLEM    "Command \"%s\" not implemented.\n"
295074e1d5SCristian Dumitrescu #define MSG_ARG_NOT_ENOUGH  "Not enough arguments for command \"%s\".\n"
305074e1d5SCristian Dumitrescu #define MSG_ARG_TOO_MANY    "Too many arguments for command \"%s\".\n"
315074e1d5SCristian Dumitrescu #define MSG_ARG_MISMATCH    "Wrong number of arguments for command \"%s\".\n"
325074e1d5SCristian Dumitrescu #define MSG_ARG_NOT_FOUND   "Argument \"%s\" not found.\n"
335074e1d5SCristian Dumitrescu #define MSG_ARG_INVALID     "Invalid value for argument \"%s\".\n"
345074e1d5SCristian Dumitrescu #define MSG_FILE_ERR        "Error in file \"%s\" at line %u.\n"
355074e1d5SCristian Dumitrescu #define MSG_FILE_NOT_ENOUGH "Not enough rules in file \"%s\".\n"
365074e1d5SCristian Dumitrescu #define MSG_CMD_FAIL        "Command \"%s\" failed.\n"
375074e1d5SCristian Dumitrescu 
385074e1d5SCristian Dumitrescu #define skip_white_spaces(pos)			\
395074e1d5SCristian Dumitrescu ({						\
405074e1d5SCristian Dumitrescu 	__typeof__(pos) _p = (pos);		\
415074e1d5SCristian Dumitrescu 	for ( ; isspace(*_p); _p++)		\
425074e1d5SCristian Dumitrescu 		;				\
435074e1d5SCristian Dumitrescu 	_p;					\
445074e1d5SCristian Dumitrescu })
455074e1d5SCristian Dumitrescu 
465074e1d5SCristian Dumitrescu static int
475074e1d5SCristian Dumitrescu parser_read_uint64(uint64_t *value, const char *p)
485074e1d5SCristian Dumitrescu {
495074e1d5SCristian Dumitrescu 	char *next;
505074e1d5SCristian Dumitrescu 	uint64_t val;
515074e1d5SCristian Dumitrescu 
525074e1d5SCristian Dumitrescu 	p = skip_white_spaces(p);
535074e1d5SCristian Dumitrescu 	if (!isdigit(*p))
545074e1d5SCristian Dumitrescu 		return -EINVAL;
555074e1d5SCristian Dumitrescu 
565074e1d5SCristian Dumitrescu 	val = strtoul(p, &next, 10);
575074e1d5SCristian Dumitrescu 	if (p == next)
585074e1d5SCristian Dumitrescu 		return -EINVAL;
595074e1d5SCristian Dumitrescu 
605074e1d5SCristian Dumitrescu 	p = next;
615074e1d5SCristian Dumitrescu 	switch (*p) {
625074e1d5SCristian Dumitrescu 	case 'T':
635074e1d5SCristian Dumitrescu 		val *= 1024ULL;
645074e1d5SCristian Dumitrescu 		/* fall through */
655074e1d5SCristian Dumitrescu 	case 'G':
665074e1d5SCristian Dumitrescu 		val *= 1024ULL;
675074e1d5SCristian Dumitrescu 		/* fall through */
685074e1d5SCristian Dumitrescu 	case 'M':
695074e1d5SCristian Dumitrescu 		val *= 1024ULL;
705074e1d5SCristian Dumitrescu 		/* fall through */
715074e1d5SCristian Dumitrescu 	case 'k':
725074e1d5SCristian Dumitrescu 	case 'K':
735074e1d5SCristian Dumitrescu 		val *= 1024ULL;
745074e1d5SCristian Dumitrescu 		p++;
755074e1d5SCristian Dumitrescu 		break;
765074e1d5SCristian Dumitrescu 	}
775074e1d5SCristian Dumitrescu 
785074e1d5SCristian Dumitrescu 	p = skip_white_spaces(p);
795074e1d5SCristian Dumitrescu 	if (*p != '\0')
805074e1d5SCristian Dumitrescu 		return -EINVAL;
815074e1d5SCristian Dumitrescu 
825074e1d5SCristian Dumitrescu 	*value = val;
835074e1d5SCristian Dumitrescu 	return 0;
845074e1d5SCristian Dumitrescu }
855074e1d5SCristian Dumitrescu 
865074e1d5SCristian Dumitrescu static int
875074e1d5SCristian Dumitrescu parser_read_uint32(uint32_t *value, const char *p)
885074e1d5SCristian Dumitrescu {
895074e1d5SCristian Dumitrescu 	uint64_t val = 0;
905074e1d5SCristian Dumitrescu 	int ret = parser_read_uint64(&val, p);
915074e1d5SCristian Dumitrescu 
925074e1d5SCristian Dumitrescu 	if (ret < 0)
935074e1d5SCristian Dumitrescu 		return ret;
945074e1d5SCristian Dumitrescu 
955074e1d5SCristian Dumitrescu 	if (val > UINT32_MAX)
965074e1d5SCristian Dumitrescu 		return -ERANGE;
975074e1d5SCristian Dumitrescu 
985074e1d5SCristian Dumitrescu 	*value = val;
995074e1d5SCristian Dumitrescu 	return 0;
1005074e1d5SCristian Dumitrescu }
1015074e1d5SCristian Dumitrescu 
1025074e1d5SCristian Dumitrescu static int
1035074e1d5SCristian Dumitrescu parser_read_uint16(uint16_t *value, const char *p)
1045074e1d5SCristian Dumitrescu {
1055074e1d5SCristian Dumitrescu 	uint64_t val = 0;
1065074e1d5SCristian Dumitrescu 	int ret = parser_read_uint64(&val, p);
1075074e1d5SCristian Dumitrescu 
1085074e1d5SCristian Dumitrescu 	if (ret < 0)
1095074e1d5SCristian Dumitrescu 		return ret;
1105074e1d5SCristian Dumitrescu 
1115074e1d5SCristian Dumitrescu 	if (val > UINT16_MAX)
1125074e1d5SCristian Dumitrescu 		return -ERANGE;
1135074e1d5SCristian Dumitrescu 
1145074e1d5SCristian Dumitrescu 	*value = val;
1155074e1d5SCristian Dumitrescu 	return 0;
1165074e1d5SCristian Dumitrescu }
1175074e1d5SCristian Dumitrescu 
1185074e1d5SCristian Dumitrescu #define PARSE_DELIMITER " \f\n\r\t\v"
1195074e1d5SCristian Dumitrescu 
1205074e1d5SCristian Dumitrescu static int
1215074e1d5SCristian Dumitrescu parse_tokenize_string(char *string, char *tokens[], uint32_t *n_tokens)
1225074e1d5SCristian Dumitrescu {
1235074e1d5SCristian Dumitrescu 	uint32_t i;
1245074e1d5SCristian Dumitrescu 
1255074e1d5SCristian Dumitrescu 	if ((string == NULL) ||
1265074e1d5SCristian Dumitrescu 		(tokens == NULL) ||
1275074e1d5SCristian Dumitrescu 		(*n_tokens < 1))
1285074e1d5SCristian Dumitrescu 		return -EINVAL;
1295074e1d5SCristian Dumitrescu 
1305074e1d5SCristian Dumitrescu 	for (i = 0; i < *n_tokens; i++) {
1315074e1d5SCristian Dumitrescu 		tokens[i] = strtok_r(string, PARSE_DELIMITER, &string);
1325074e1d5SCristian Dumitrescu 		if (tokens[i] == NULL)
1335074e1d5SCristian Dumitrescu 			break;
1345074e1d5SCristian Dumitrescu 	}
1355074e1d5SCristian Dumitrescu 
1365074e1d5SCristian Dumitrescu 	if ((i == *n_tokens) && strtok_r(string, PARSE_DELIMITER, &string))
1375074e1d5SCristian Dumitrescu 		return -E2BIG;
1385074e1d5SCristian Dumitrescu 
1395074e1d5SCristian Dumitrescu 	*n_tokens = i;
1405074e1d5SCristian Dumitrescu 	return 0;
1415074e1d5SCristian Dumitrescu }
1425074e1d5SCristian Dumitrescu 
1435074e1d5SCristian Dumitrescu static int
1445074e1d5SCristian Dumitrescu is_comment(char *in)
1455074e1d5SCristian Dumitrescu {
1465074e1d5SCristian Dumitrescu 	if ((strlen(in) && index("!#%;", in[0])) ||
1475074e1d5SCristian Dumitrescu 		(strncmp(in, "//", 2) == 0) ||
1485074e1d5SCristian Dumitrescu 		(strncmp(in, "--", 2) == 0))
1495074e1d5SCristian Dumitrescu 		return 1;
1505074e1d5SCristian Dumitrescu 
1515074e1d5SCristian Dumitrescu 	return 0;
1525074e1d5SCristian Dumitrescu }
1535074e1d5SCristian Dumitrescu 
1545074e1d5SCristian Dumitrescu static const char cmd_mempool_help[] =
1555074e1d5SCristian Dumitrescu "mempool <mempool_name>\n"
1565074e1d5SCristian Dumitrescu "   buffer <buffer_size>\n"
1575074e1d5SCristian Dumitrescu "   pool <pool_size>\n"
1585074e1d5SCristian Dumitrescu "   cache <cache_size>\n"
1595074e1d5SCristian Dumitrescu "   cpu <cpu_id>\n";
1605074e1d5SCristian Dumitrescu 
1615074e1d5SCristian Dumitrescu static void
1625074e1d5SCristian Dumitrescu cmd_mempool(char **tokens,
1635074e1d5SCristian Dumitrescu 	uint32_t n_tokens,
1645074e1d5SCristian Dumitrescu 	char *out,
1655074e1d5SCristian Dumitrescu 	size_t out_size,
1665074e1d5SCristian Dumitrescu 	void *obj)
1675074e1d5SCristian Dumitrescu {
1685074e1d5SCristian Dumitrescu 	struct mempool_params p;
1695074e1d5SCristian Dumitrescu 	char *name;
1705074e1d5SCristian Dumitrescu 	struct mempool *mempool;
1715074e1d5SCristian Dumitrescu 
1725074e1d5SCristian Dumitrescu 	if (n_tokens != 10) {
1735074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1745074e1d5SCristian Dumitrescu 		return;
1755074e1d5SCristian Dumitrescu 	}
1765074e1d5SCristian Dumitrescu 
1775074e1d5SCristian Dumitrescu 	name = tokens[1];
1785074e1d5SCristian Dumitrescu 
1795074e1d5SCristian Dumitrescu 	if (strcmp(tokens[2], "buffer") != 0) {
1805074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "buffer");
1815074e1d5SCristian Dumitrescu 		return;
1825074e1d5SCristian Dumitrescu 	}
1835074e1d5SCristian Dumitrescu 
1845074e1d5SCristian Dumitrescu 	if (parser_read_uint32(&p.buffer_size, tokens[3]) != 0) {
1855074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "buffer_size");
1865074e1d5SCristian Dumitrescu 		return;
1875074e1d5SCristian Dumitrescu 	}
1885074e1d5SCristian Dumitrescu 
1895074e1d5SCristian Dumitrescu 	if (strcmp(tokens[4], "pool") != 0) {
1905074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pool");
1915074e1d5SCristian Dumitrescu 		return;
1925074e1d5SCristian Dumitrescu 	}
1935074e1d5SCristian Dumitrescu 
1945074e1d5SCristian Dumitrescu 	if (parser_read_uint32(&p.pool_size, tokens[5]) != 0) {
1955074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pool_size");
1965074e1d5SCristian Dumitrescu 		return;
1975074e1d5SCristian Dumitrescu 	}
1985074e1d5SCristian Dumitrescu 
1995074e1d5SCristian Dumitrescu 	if (strcmp(tokens[6], "cache") != 0) {
2005074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cache");
2015074e1d5SCristian Dumitrescu 		return;
2025074e1d5SCristian Dumitrescu 	}
2035074e1d5SCristian Dumitrescu 
2045074e1d5SCristian Dumitrescu 	if (parser_read_uint32(&p.cache_size, tokens[7]) != 0) {
2055074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "cache_size");
2065074e1d5SCristian Dumitrescu 		return;
2075074e1d5SCristian Dumitrescu 	}
2085074e1d5SCristian Dumitrescu 
2095074e1d5SCristian Dumitrescu 	if (strcmp(tokens[8], "cpu") != 0) {
2105074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cpu");
2115074e1d5SCristian Dumitrescu 		return;
2125074e1d5SCristian Dumitrescu 	}
2135074e1d5SCristian Dumitrescu 
2145074e1d5SCristian Dumitrescu 	if (parser_read_uint32(&p.cpu_id, tokens[9]) != 0) {
2155074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "cpu_id");
2165074e1d5SCristian Dumitrescu 		return;
2175074e1d5SCristian Dumitrescu 	}
2185074e1d5SCristian Dumitrescu 
2195074e1d5SCristian Dumitrescu 	mempool = mempool_create(obj, name, &p);
2205074e1d5SCristian Dumitrescu 	if (mempool == NULL) {
2215074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
2225074e1d5SCristian Dumitrescu 		return;
2235074e1d5SCristian Dumitrescu 	}
2245074e1d5SCristian Dumitrescu }
2255074e1d5SCristian Dumitrescu 
2265074e1d5SCristian Dumitrescu static const char cmd_link_help[] =
2275074e1d5SCristian Dumitrescu "link <link_name>\n"
2285074e1d5SCristian Dumitrescu "   dev <device_name> | port <port_id>\n"
2295074e1d5SCristian Dumitrescu "   rxq <n_queues> <queue_size> <mempool_name>\n"
2305074e1d5SCristian Dumitrescu "   txq <n_queues> <queue_size>\n"
2315074e1d5SCristian Dumitrescu "   promiscuous on | off\n"
2325074e1d5SCristian Dumitrescu "   [rss <qid_0> ... <qid_n>]\n";
2335074e1d5SCristian Dumitrescu 
2345074e1d5SCristian Dumitrescu static void
2355074e1d5SCristian Dumitrescu cmd_link(char **tokens,
2365074e1d5SCristian Dumitrescu 	uint32_t n_tokens,
2375074e1d5SCristian Dumitrescu 	char *out,
2385074e1d5SCristian Dumitrescu 	size_t out_size,
2395074e1d5SCristian Dumitrescu 	void *obj)
2405074e1d5SCristian Dumitrescu {
2415074e1d5SCristian Dumitrescu 	struct link_params p;
2425074e1d5SCristian Dumitrescu 	struct link_params_rss rss;
2435074e1d5SCristian Dumitrescu 	struct link *link;
2445074e1d5SCristian Dumitrescu 	char *name;
2455074e1d5SCristian Dumitrescu 
2465074e1d5SCristian Dumitrescu 	memset(&p, 0, sizeof(p));
2475074e1d5SCristian Dumitrescu 
2485074e1d5SCristian Dumitrescu 	if ((n_tokens < 13) || (n_tokens > 14 + LINK_RXQ_RSS_MAX)) {
2495074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2505074e1d5SCristian Dumitrescu 		return;
2515074e1d5SCristian Dumitrescu 	}
2525074e1d5SCristian Dumitrescu 	name = tokens[1];
2535074e1d5SCristian Dumitrescu 
2545074e1d5SCristian Dumitrescu 	if (strcmp(tokens[2], "dev") == 0)
2555074e1d5SCristian Dumitrescu 		p.dev_name = tokens[3];
2565074e1d5SCristian Dumitrescu 	else if (strcmp(tokens[2], "port") == 0) {
2575074e1d5SCristian Dumitrescu 		p.dev_name = NULL;
2585074e1d5SCristian Dumitrescu 
2595074e1d5SCristian Dumitrescu 		if (parser_read_uint16(&p.port_id, tokens[3]) != 0) {
2605074e1d5SCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
2615074e1d5SCristian Dumitrescu 			return;
2625074e1d5SCristian Dumitrescu 		}
2635074e1d5SCristian Dumitrescu 	} else {
2645074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "dev or port");
2655074e1d5SCristian Dumitrescu 		return;
2665074e1d5SCristian Dumitrescu 	}
2675074e1d5SCristian Dumitrescu 
2685074e1d5SCristian Dumitrescu 	if (strcmp(tokens[4], "rxq") != 0) {
2695074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rxq");
2705074e1d5SCristian Dumitrescu 		return;
2715074e1d5SCristian Dumitrescu 	}
2725074e1d5SCristian Dumitrescu 
2735074e1d5SCristian Dumitrescu 	if (parser_read_uint32(&p.rx.n_queues, tokens[5]) != 0) {
2745074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "n_queues");
2755074e1d5SCristian Dumitrescu 		return;
2765074e1d5SCristian Dumitrescu 	}
2775074e1d5SCristian Dumitrescu 	if (parser_read_uint32(&p.rx.queue_size, tokens[6]) != 0) {
2785074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "queue_size");
2795074e1d5SCristian Dumitrescu 		return;
2805074e1d5SCristian Dumitrescu 	}
2815074e1d5SCristian Dumitrescu 
2825074e1d5SCristian Dumitrescu 	p.rx.mempool_name = tokens[7];
2835074e1d5SCristian Dumitrescu 
2845074e1d5SCristian Dumitrescu 	if (strcmp(tokens[8], "txq") != 0) {
2855074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "txq");
2865074e1d5SCristian Dumitrescu 		return;
2875074e1d5SCristian Dumitrescu 	}
2885074e1d5SCristian Dumitrescu 
2895074e1d5SCristian Dumitrescu 	if (parser_read_uint32(&p.tx.n_queues, tokens[9]) != 0) {
2905074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "n_queues");
2915074e1d5SCristian Dumitrescu 		return;
2925074e1d5SCristian Dumitrescu 	}
2935074e1d5SCristian Dumitrescu 
2945074e1d5SCristian Dumitrescu 	if (parser_read_uint32(&p.tx.queue_size, tokens[10]) != 0) {
2955074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "queue_size");
2965074e1d5SCristian Dumitrescu 		return;
2975074e1d5SCristian Dumitrescu 	}
2985074e1d5SCristian Dumitrescu 
2995074e1d5SCristian Dumitrescu 	if (strcmp(tokens[11], "promiscuous") != 0) {
3005074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "promiscuous");
3015074e1d5SCristian Dumitrescu 		return;
3025074e1d5SCristian Dumitrescu 	}
3035074e1d5SCristian Dumitrescu 
3045074e1d5SCristian Dumitrescu 	if (strcmp(tokens[12], "on") == 0)
3055074e1d5SCristian Dumitrescu 		p.promiscuous = 1;
3065074e1d5SCristian Dumitrescu 	else if (strcmp(tokens[12], "off") == 0)
3075074e1d5SCristian Dumitrescu 		p.promiscuous = 0;
3085074e1d5SCristian Dumitrescu 	else {
3095074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "on or off");
3105074e1d5SCristian Dumitrescu 		return;
3115074e1d5SCristian Dumitrescu 	}
3125074e1d5SCristian Dumitrescu 
3135074e1d5SCristian Dumitrescu 	/* RSS */
3145074e1d5SCristian Dumitrescu 	p.rx.rss = NULL;
3155074e1d5SCristian Dumitrescu 	if (n_tokens > 13) {
3165074e1d5SCristian Dumitrescu 		uint32_t queue_id, i;
3175074e1d5SCristian Dumitrescu 
3185074e1d5SCristian Dumitrescu 		if (strcmp(tokens[13], "rss") != 0) {
3195074e1d5SCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rss");
3205074e1d5SCristian Dumitrescu 			return;
3215074e1d5SCristian Dumitrescu 		}
3225074e1d5SCristian Dumitrescu 
3235074e1d5SCristian Dumitrescu 		p.rx.rss = &rss;
3245074e1d5SCristian Dumitrescu 
3255074e1d5SCristian Dumitrescu 		rss.n_queues = 0;
3265074e1d5SCristian Dumitrescu 		for (i = 14; i < n_tokens; i++) {
3275074e1d5SCristian Dumitrescu 			if (parser_read_uint32(&queue_id, tokens[i]) != 0) {
3285074e1d5SCristian Dumitrescu 				snprintf(out, out_size, MSG_ARG_INVALID,
3295074e1d5SCristian Dumitrescu 					"queue_id");
3305074e1d5SCristian Dumitrescu 				return;
3315074e1d5SCristian Dumitrescu 			}
3325074e1d5SCristian Dumitrescu 
3335074e1d5SCristian Dumitrescu 			rss.queue_id[rss.n_queues] = queue_id;
3345074e1d5SCristian Dumitrescu 			rss.n_queues++;
3355074e1d5SCristian Dumitrescu 		}
3365074e1d5SCristian Dumitrescu 	}
3375074e1d5SCristian Dumitrescu 
3385074e1d5SCristian Dumitrescu 	link = link_create(obj, name, &p);
3395074e1d5SCristian Dumitrescu 	if (link == NULL) {
3405074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
3415074e1d5SCristian Dumitrescu 		return;
3425074e1d5SCristian Dumitrescu 	}
3435074e1d5SCristian Dumitrescu }
3445074e1d5SCristian Dumitrescu 
3455074e1d5SCristian Dumitrescu /* Print the link stats and info */
3465074e1d5SCristian Dumitrescu static void
3475074e1d5SCristian Dumitrescu print_link_info(struct link *link, char *out, size_t out_size)
3485074e1d5SCristian Dumitrescu {
3495074e1d5SCristian Dumitrescu 	struct rte_eth_stats stats;
3505074e1d5SCristian Dumitrescu 	struct rte_ether_addr mac_addr;
3515074e1d5SCristian Dumitrescu 	struct rte_eth_link eth_link;
3525074e1d5SCristian Dumitrescu 	uint16_t mtu;
3535074e1d5SCristian Dumitrescu 	int ret;
3545074e1d5SCristian Dumitrescu 
3555074e1d5SCristian Dumitrescu 	memset(&stats, 0, sizeof(stats));
3565074e1d5SCristian Dumitrescu 	rte_eth_stats_get(link->port_id, &stats);
3575074e1d5SCristian Dumitrescu 
3585074e1d5SCristian Dumitrescu 	ret = rte_eth_macaddr_get(link->port_id, &mac_addr);
3595074e1d5SCristian Dumitrescu 	if (ret != 0) {
3605074e1d5SCristian Dumitrescu 		snprintf(out, out_size, "\n%s: MAC address get failed: %s",
3615074e1d5SCristian Dumitrescu 			 link->name, rte_strerror(-ret));
3625074e1d5SCristian Dumitrescu 		return;
3635074e1d5SCristian Dumitrescu 	}
3645074e1d5SCristian Dumitrescu 
3655074e1d5SCristian Dumitrescu 	ret = rte_eth_link_get(link->port_id, &eth_link);
3665074e1d5SCristian Dumitrescu 	if (ret < 0) {
3675074e1d5SCristian Dumitrescu 		snprintf(out, out_size, "\n%s: link get failed: %s",
3685074e1d5SCristian Dumitrescu 			 link->name, rte_strerror(-ret));
3695074e1d5SCristian Dumitrescu 		return;
3705074e1d5SCristian Dumitrescu 	}
3715074e1d5SCristian Dumitrescu 
3725074e1d5SCristian Dumitrescu 	rte_eth_dev_get_mtu(link->port_id, &mtu);
3735074e1d5SCristian Dumitrescu 
3745074e1d5SCristian Dumitrescu 	snprintf(out, out_size,
3755074e1d5SCristian Dumitrescu 		"\n"
3765074e1d5SCristian Dumitrescu 		"%s: flags=<%s> mtu %u\n"
3775074e1d5SCristian Dumitrescu 		"\tether %02X:%02X:%02X:%02X:%02X:%02X rxqueues %u txqueues %u\n"
3785074e1d5SCristian Dumitrescu 		"\tport# %u  speed %s\n"
3795074e1d5SCristian Dumitrescu 		"\tRX packets %" PRIu64"  bytes %" PRIu64"\n"
3805074e1d5SCristian Dumitrescu 		"\tRX errors %" PRIu64"  missed %" PRIu64"  no-mbuf %" PRIu64"\n"
3815074e1d5SCristian Dumitrescu 		"\tTX packets %" PRIu64"  bytes %" PRIu64"\n"
3825074e1d5SCristian Dumitrescu 		"\tTX errors %" PRIu64"\n",
3835074e1d5SCristian Dumitrescu 		link->name,
3845074e1d5SCristian Dumitrescu 		eth_link.link_status == 0 ? "DOWN" : "UP",
3855074e1d5SCristian Dumitrescu 		mtu,
3865074e1d5SCristian Dumitrescu 		mac_addr.addr_bytes[0], mac_addr.addr_bytes[1],
3875074e1d5SCristian Dumitrescu 		mac_addr.addr_bytes[2], mac_addr.addr_bytes[3],
3885074e1d5SCristian Dumitrescu 		mac_addr.addr_bytes[4], mac_addr.addr_bytes[5],
3895074e1d5SCristian Dumitrescu 		link->n_rxq,
3905074e1d5SCristian Dumitrescu 		link->n_txq,
3915074e1d5SCristian Dumitrescu 		link->port_id,
3925074e1d5SCristian Dumitrescu 		rte_eth_link_speed_to_str(eth_link.link_speed),
3935074e1d5SCristian Dumitrescu 		stats.ipackets,
3945074e1d5SCristian Dumitrescu 		stats.ibytes,
3955074e1d5SCristian Dumitrescu 		stats.ierrors,
3965074e1d5SCristian Dumitrescu 		stats.imissed,
3975074e1d5SCristian Dumitrescu 		stats.rx_nombuf,
3985074e1d5SCristian Dumitrescu 		stats.opackets,
3995074e1d5SCristian Dumitrescu 		stats.obytes,
4005074e1d5SCristian Dumitrescu 		stats.oerrors);
4015074e1d5SCristian Dumitrescu }
4025074e1d5SCristian Dumitrescu 
4035074e1d5SCristian Dumitrescu /*
4045074e1d5SCristian Dumitrescu  * link show [<link_name>]
4055074e1d5SCristian Dumitrescu  */
4065074e1d5SCristian Dumitrescu static void
4075074e1d5SCristian Dumitrescu cmd_link_show(char **tokens,
4085074e1d5SCristian Dumitrescu 	      uint32_t n_tokens,
4095074e1d5SCristian Dumitrescu 	      char *out,
4105074e1d5SCristian Dumitrescu 	      size_t out_size,
4115074e1d5SCristian Dumitrescu 	      void *obj)
4125074e1d5SCristian Dumitrescu {
4135074e1d5SCristian Dumitrescu 	struct link *link;
4145074e1d5SCristian Dumitrescu 	char *link_name;
4155074e1d5SCristian Dumitrescu 
4165074e1d5SCristian Dumitrescu 	if (n_tokens != 2 && n_tokens != 3) {
4175074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
4185074e1d5SCristian Dumitrescu 		return;
4195074e1d5SCristian Dumitrescu 	}
4205074e1d5SCristian Dumitrescu 
4215074e1d5SCristian Dumitrescu 	if (n_tokens == 2) {
4225074e1d5SCristian Dumitrescu 		link = link_next(obj, NULL);
4235074e1d5SCristian Dumitrescu 
4245074e1d5SCristian Dumitrescu 		while (link != NULL) {
4255074e1d5SCristian Dumitrescu 			out_size = out_size - strlen(out);
4265074e1d5SCristian Dumitrescu 			out = &out[strlen(out)];
4275074e1d5SCristian Dumitrescu 
4285074e1d5SCristian Dumitrescu 			print_link_info(link, out, out_size);
4295074e1d5SCristian Dumitrescu 			link = link_next(obj, link);
4305074e1d5SCristian Dumitrescu 		}
4315074e1d5SCristian Dumitrescu 	} else {
4325074e1d5SCristian Dumitrescu 		out_size = out_size - strlen(out);
4335074e1d5SCristian Dumitrescu 		out = &out[strlen(out)];
4345074e1d5SCristian Dumitrescu 
4355074e1d5SCristian Dumitrescu 		link_name = tokens[2];
4365074e1d5SCristian Dumitrescu 		link = link_find(obj, link_name);
4375074e1d5SCristian Dumitrescu 
4385074e1d5SCristian Dumitrescu 		if (link == NULL) {
4395074e1d5SCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_INVALID,
4405074e1d5SCristian Dumitrescu 					"Link does not exist");
4415074e1d5SCristian Dumitrescu 			return;
4425074e1d5SCristian Dumitrescu 		}
4435074e1d5SCristian Dumitrescu 		print_link_info(link, out, out_size);
4445074e1d5SCristian Dumitrescu 	}
4455074e1d5SCristian Dumitrescu }
4465074e1d5SCristian Dumitrescu 
4475074e1d5SCristian Dumitrescu static const char cmd_pipeline_create_help[] =
4485074e1d5SCristian Dumitrescu "pipeline <pipeline_name> create <numa_node>\n";
4495074e1d5SCristian Dumitrescu 
4505074e1d5SCristian Dumitrescu static void
4515074e1d5SCristian Dumitrescu cmd_pipeline_create(char **tokens,
4525074e1d5SCristian Dumitrescu 	uint32_t n_tokens,
4535074e1d5SCristian Dumitrescu 	char *out,
4545074e1d5SCristian Dumitrescu 	size_t out_size,
4555074e1d5SCristian Dumitrescu 	void *obj)
4565074e1d5SCristian Dumitrescu {
4575074e1d5SCristian Dumitrescu 	struct pipeline *p;
4585074e1d5SCristian Dumitrescu 	char *name;
4595074e1d5SCristian Dumitrescu 	uint32_t numa_node;
4605074e1d5SCristian Dumitrescu 
4615074e1d5SCristian Dumitrescu 	if (n_tokens != 4) {
4625074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
4635074e1d5SCristian Dumitrescu 		return;
4645074e1d5SCristian Dumitrescu 	}
4655074e1d5SCristian Dumitrescu 
4665074e1d5SCristian Dumitrescu 	name = tokens[1];
4675074e1d5SCristian Dumitrescu 
4685074e1d5SCristian Dumitrescu 	if (parser_read_uint32(&numa_node, tokens[3]) != 0) {
4695074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "numa_node");
4705074e1d5SCristian Dumitrescu 		return;
4715074e1d5SCristian Dumitrescu 	}
4725074e1d5SCristian Dumitrescu 
4735074e1d5SCristian Dumitrescu 	p = pipeline_create(obj, name, (int)numa_node);
4745074e1d5SCristian Dumitrescu 	if (!p) {
4755074e1d5SCristian Dumitrescu 		snprintf(out, out_size, "pipeline create error.");
4765074e1d5SCristian Dumitrescu 		return;
4775074e1d5SCristian Dumitrescu 	}
4785074e1d5SCristian Dumitrescu }
4795074e1d5SCristian Dumitrescu 
4805074e1d5SCristian Dumitrescu static const char cmd_pipeline_port_in_help[] =
4815074e1d5SCristian Dumitrescu "pipeline <pipeline_name> port in <port_id>\n"
4825074e1d5SCristian Dumitrescu "   link <link_name> rxq <queue_id> bsz <burst_size>\n"
483*7fef9ef1SYogesh Jangra "   | source <mempool_name> <file_name>\n";
4845074e1d5SCristian Dumitrescu 
4855074e1d5SCristian Dumitrescu static void
4865074e1d5SCristian Dumitrescu cmd_pipeline_port_in(char **tokens,
4875074e1d5SCristian Dumitrescu 	uint32_t n_tokens,
4885074e1d5SCristian Dumitrescu 	char *out,
4895074e1d5SCristian Dumitrescu 	size_t out_size,
4905074e1d5SCristian Dumitrescu 	void *obj)
4915074e1d5SCristian Dumitrescu {
4925074e1d5SCristian Dumitrescu 	struct pipeline *p;
4935074e1d5SCristian Dumitrescu 	int status;
4945074e1d5SCristian Dumitrescu 	uint32_t port_id = 0, t0;
4955074e1d5SCristian Dumitrescu 
4965074e1d5SCristian Dumitrescu 	if (n_tokens < 6) {
4975074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
4985074e1d5SCristian Dumitrescu 		return;
4995074e1d5SCristian Dumitrescu 	}
5005074e1d5SCristian Dumitrescu 
5015074e1d5SCristian Dumitrescu 	p = pipeline_find(obj, tokens[1]);
5025074e1d5SCristian Dumitrescu 	if (!p || p->ctl) {
5035074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
5045074e1d5SCristian Dumitrescu 		return;
5055074e1d5SCristian Dumitrescu 	}
5065074e1d5SCristian Dumitrescu 
5075074e1d5SCristian Dumitrescu 	if (strcmp(tokens[2], "port") != 0) {
5085074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
5095074e1d5SCristian Dumitrescu 		return;
5105074e1d5SCristian Dumitrescu 	}
5115074e1d5SCristian Dumitrescu 
5125074e1d5SCristian Dumitrescu 	if (strcmp(tokens[3], "in") != 0) {
5135074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "in");
5145074e1d5SCristian Dumitrescu 		return;
5155074e1d5SCristian Dumitrescu 	}
5165074e1d5SCristian Dumitrescu 
5175074e1d5SCristian Dumitrescu 	if (parser_read_uint32(&port_id, tokens[4]) != 0) {
5185074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
5195074e1d5SCristian Dumitrescu 		return;
5205074e1d5SCristian Dumitrescu 	}
5215074e1d5SCristian Dumitrescu 
5225074e1d5SCristian Dumitrescu 	t0 = 5;
5235074e1d5SCristian Dumitrescu 
5245074e1d5SCristian Dumitrescu 	if (strcmp(tokens[t0], "link") == 0) {
5255074e1d5SCristian Dumitrescu 		struct rte_swx_port_ethdev_reader_params params;
5265074e1d5SCristian Dumitrescu 		struct link *link;
5275074e1d5SCristian Dumitrescu 
5285074e1d5SCristian Dumitrescu 		if (n_tokens < t0 + 6) {
5295074e1d5SCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_MISMATCH,
5305074e1d5SCristian Dumitrescu 				"pipeline port in link");
5315074e1d5SCristian Dumitrescu 			return;
5325074e1d5SCristian Dumitrescu 		}
5335074e1d5SCristian Dumitrescu 
5345074e1d5SCristian Dumitrescu 		link = link_find(obj, tokens[t0 + 1]);
5355074e1d5SCristian Dumitrescu 		if (!link) {
5365074e1d5SCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_INVALID,
5375074e1d5SCristian Dumitrescu 				"link_name");
5385074e1d5SCristian Dumitrescu 			return;
5395074e1d5SCristian Dumitrescu 		}
5405074e1d5SCristian Dumitrescu 		params.dev_name = link->dev_name;
5415074e1d5SCristian Dumitrescu 
5425074e1d5SCristian Dumitrescu 		if (strcmp(tokens[t0 + 2], "rxq") != 0) {
5435074e1d5SCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rxq");
5445074e1d5SCristian Dumitrescu 			return;
5455074e1d5SCristian Dumitrescu 		}
5465074e1d5SCristian Dumitrescu 
5475074e1d5SCristian Dumitrescu 		if (parser_read_uint16(&params.queue_id, tokens[t0 + 3]) != 0) {
5485074e1d5SCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_INVALID,
5495074e1d5SCristian Dumitrescu 				"queue_id");
5505074e1d5SCristian Dumitrescu 			return;
5515074e1d5SCristian Dumitrescu 		}
5525074e1d5SCristian Dumitrescu 
5535074e1d5SCristian Dumitrescu 		if (strcmp(tokens[t0 + 4], "bsz") != 0) {
5545074e1d5SCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_NOT_FOUND, "bsz");
5555074e1d5SCristian Dumitrescu 			return;
5565074e1d5SCristian Dumitrescu 		}
5575074e1d5SCristian Dumitrescu 
5585074e1d5SCristian Dumitrescu 		if (parser_read_uint32(&params.burst_size, tokens[t0 + 5])) {
5595074e1d5SCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_INVALID,
5605074e1d5SCristian Dumitrescu 				"burst_size");
5615074e1d5SCristian Dumitrescu 			return;
5625074e1d5SCristian Dumitrescu 		}
5635074e1d5SCristian Dumitrescu 
5645074e1d5SCristian Dumitrescu 		t0 += 6;
5655074e1d5SCristian Dumitrescu 
5665074e1d5SCristian Dumitrescu 		status = rte_swx_pipeline_port_in_config(p->p,
5675074e1d5SCristian Dumitrescu 			port_id,
5685074e1d5SCristian Dumitrescu 			"ethdev",
5695074e1d5SCristian Dumitrescu 			&params);
5705074e1d5SCristian Dumitrescu 	} else if (strcmp(tokens[t0], "source") == 0) {
5715074e1d5SCristian Dumitrescu 		struct rte_swx_port_source_params params;
5725074e1d5SCristian Dumitrescu 		struct mempool *mp;
5735074e1d5SCristian Dumitrescu 
5745074e1d5SCristian Dumitrescu 		if (n_tokens < t0 + 3) {
5755074e1d5SCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_MISMATCH,
5765074e1d5SCristian Dumitrescu 				"pipeline port in source");
5775074e1d5SCristian Dumitrescu 			return;
5785074e1d5SCristian Dumitrescu 		}
5795074e1d5SCristian Dumitrescu 
5805074e1d5SCristian Dumitrescu 		mp = mempool_find(obj, tokens[t0 + 1]);
5815074e1d5SCristian Dumitrescu 		if (!mp) {
5825074e1d5SCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_INVALID,
5835074e1d5SCristian Dumitrescu 				"mempool_name");
5845074e1d5SCristian Dumitrescu 			return;
5855074e1d5SCristian Dumitrescu 		}
5865074e1d5SCristian Dumitrescu 		params.pool = mp->m;
5875074e1d5SCristian Dumitrescu 
5885074e1d5SCristian Dumitrescu 		params.file_name = tokens[t0 + 2];
5895074e1d5SCristian Dumitrescu 
5905074e1d5SCristian Dumitrescu 		t0 += 3;
5915074e1d5SCristian Dumitrescu 
5925074e1d5SCristian Dumitrescu 		status = rte_swx_pipeline_port_in_config(p->p,
5935074e1d5SCristian Dumitrescu 			port_id,
5945074e1d5SCristian Dumitrescu 			"source",
5955074e1d5SCristian Dumitrescu 			&params);
5965074e1d5SCristian Dumitrescu 	} else {
5975074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
5985074e1d5SCristian Dumitrescu 		return;
5995074e1d5SCristian Dumitrescu 	}
6005074e1d5SCristian Dumitrescu 
6015074e1d5SCristian Dumitrescu 	if (status) {
6025074e1d5SCristian Dumitrescu 		snprintf(out, out_size, "port in error.");
6035074e1d5SCristian Dumitrescu 		return;
6045074e1d5SCristian Dumitrescu 	}
6055074e1d5SCristian Dumitrescu 
6065074e1d5SCristian Dumitrescu 	if (n_tokens != t0) {
6075074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
6085074e1d5SCristian Dumitrescu 		return;
6095074e1d5SCristian Dumitrescu 	}
6105074e1d5SCristian Dumitrescu }
6115074e1d5SCristian Dumitrescu 
6125074e1d5SCristian Dumitrescu static const char cmd_pipeline_port_out_help[] =
6135074e1d5SCristian Dumitrescu "pipeline <pipeline_name> port out <port_id>\n"
6145074e1d5SCristian Dumitrescu "   link <link_name> txq <txq_id> bsz <burst_size>\n"
6155074e1d5SCristian Dumitrescu "   | sink <file_name> | none\n";
6165074e1d5SCristian Dumitrescu 
6175074e1d5SCristian Dumitrescu static void
6185074e1d5SCristian Dumitrescu cmd_pipeline_port_out(char **tokens,
6195074e1d5SCristian Dumitrescu 	uint32_t n_tokens,
6205074e1d5SCristian Dumitrescu 	char *out,
6215074e1d5SCristian Dumitrescu 	size_t out_size,
6225074e1d5SCristian Dumitrescu 	void *obj)
6235074e1d5SCristian Dumitrescu {
6245074e1d5SCristian Dumitrescu 	struct pipeline *p;
6255074e1d5SCristian Dumitrescu 	int status;
6265074e1d5SCristian Dumitrescu 	uint32_t port_id = 0, t0;
6275074e1d5SCristian Dumitrescu 
6285074e1d5SCristian Dumitrescu 	if (n_tokens < 6) {
6295074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
6305074e1d5SCristian Dumitrescu 		return;
6315074e1d5SCristian Dumitrescu 	}
6325074e1d5SCristian Dumitrescu 
6335074e1d5SCristian Dumitrescu 	p = pipeline_find(obj, tokens[1]);
6345074e1d5SCristian Dumitrescu 	if (!p || p->ctl) {
6355074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
6365074e1d5SCristian Dumitrescu 		return;
6375074e1d5SCristian Dumitrescu 	}
6385074e1d5SCristian Dumitrescu 
6395074e1d5SCristian Dumitrescu 	if (strcmp(tokens[2], "port") != 0) {
6405074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
6415074e1d5SCristian Dumitrescu 		return;
6425074e1d5SCristian Dumitrescu 	}
6435074e1d5SCristian Dumitrescu 
6445074e1d5SCristian Dumitrescu 	if (strcmp(tokens[3], "out") != 0) {
6455074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "out");
6465074e1d5SCristian Dumitrescu 		return;
6475074e1d5SCristian Dumitrescu 	}
6485074e1d5SCristian Dumitrescu 
6495074e1d5SCristian Dumitrescu 	if (parser_read_uint32(&port_id, tokens[4]) != 0) {
6505074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
6515074e1d5SCristian Dumitrescu 		return;
6525074e1d5SCristian Dumitrescu 	}
6535074e1d5SCristian Dumitrescu 
6545074e1d5SCristian Dumitrescu 	t0 = 5;
6555074e1d5SCristian Dumitrescu 
6565074e1d5SCristian Dumitrescu 	if (strcmp(tokens[t0], "link") == 0) {
6575074e1d5SCristian Dumitrescu 		struct rte_swx_port_ethdev_writer_params params;
6585074e1d5SCristian Dumitrescu 		struct link *link;
6595074e1d5SCristian Dumitrescu 
6605074e1d5SCristian Dumitrescu 		if (n_tokens < t0 + 6) {
6615074e1d5SCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_MISMATCH,
6625074e1d5SCristian Dumitrescu 				"pipeline port out link");
6635074e1d5SCristian Dumitrescu 			return;
6645074e1d5SCristian Dumitrescu 		}
6655074e1d5SCristian Dumitrescu 
6665074e1d5SCristian Dumitrescu 		link = link_find(obj, tokens[t0 + 1]);
6675074e1d5SCristian Dumitrescu 		if (!link) {
6685074e1d5SCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_INVALID,
6695074e1d5SCristian Dumitrescu 				"link_name");
6705074e1d5SCristian Dumitrescu 			return;
6715074e1d5SCristian Dumitrescu 		}
6725074e1d5SCristian Dumitrescu 		params.dev_name = link->dev_name;
6735074e1d5SCristian Dumitrescu 
6745074e1d5SCristian Dumitrescu 		if (strcmp(tokens[t0 + 2], "txq") != 0) {
6755074e1d5SCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_NOT_FOUND, "txq");
6765074e1d5SCristian Dumitrescu 			return;
6775074e1d5SCristian Dumitrescu 		}
6785074e1d5SCristian Dumitrescu 
6795074e1d5SCristian Dumitrescu 		if (parser_read_uint16(&params.queue_id, tokens[t0 + 3]) != 0) {
6805074e1d5SCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_INVALID,
6815074e1d5SCristian Dumitrescu 				"queue_id");
6825074e1d5SCristian Dumitrescu 			return;
6835074e1d5SCristian Dumitrescu 		}
6845074e1d5SCristian Dumitrescu 
6855074e1d5SCristian Dumitrescu 		if (strcmp(tokens[t0 + 4], "bsz") != 0) {
6865074e1d5SCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_NOT_FOUND, "bsz");
6875074e1d5SCristian Dumitrescu 			return;
6885074e1d5SCristian Dumitrescu 		}
6895074e1d5SCristian Dumitrescu 
6905074e1d5SCristian Dumitrescu 		if (parser_read_uint32(&params.burst_size, tokens[t0 + 5])) {
6915074e1d5SCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_INVALID,
6925074e1d5SCristian Dumitrescu 				"burst_size");
6935074e1d5SCristian Dumitrescu 			return;
6945074e1d5SCristian Dumitrescu 		}
6955074e1d5SCristian Dumitrescu 
6965074e1d5SCristian Dumitrescu 		t0 += 6;
6975074e1d5SCristian Dumitrescu 
6985074e1d5SCristian Dumitrescu 		status = rte_swx_pipeline_port_out_config(p->p,
6995074e1d5SCristian Dumitrescu 			port_id,
7005074e1d5SCristian Dumitrescu 			"ethdev",
7015074e1d5SCristian Dumitrescu 			&params);
7025074e1d5SCristian Dumitrescu 	} else if (strcmp(tokens[t0], "sink") == 0) {
7035074e1d5SCristian Dumitrescu 		struct rte_swx_port_sink_params params;
7045074e1d5SCristian Dumitrescu 
7055074e1d5SCristian Dumitrescu 		params.file_name = strcmp(tokens[t0 + 1], "none") ?
7065074e1d5SCristian Dumitrescu 			tokens[t0 + 1] : NULL;
7075074e1d5SCristian Dumitrescu 
7085074e1d5SCristian Dumitrescu 		t0 += 2;
7095074e1d5SCristian Dumitrescu 
7105074e1d5SCristian Dumitrescu 		status = rte_swx_pipeline_port_out_config(p->p,
7115074e1d5SCristian Dumitrescu 			port_id,
7125074e1d5SCristian Dumitrescu 			"sink",
7135074e1d5SCristian Dumitrescu 			&params);
7145074e1d5SCristian Dumitrescu 	} else {
7155074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
7165074e1d5SCristian Dumitrescu 		return;
7175074e1d5SCristian Dumitrescu 	}
7185074e1d5SCristian Dumitrescu 
7195074e1d5SCristian Dumitrescu 	if (status) {
7205074e1d5SCristian Dumitrescu 		snprintf(out, out_size, "port out error.");
7215074e1d5SCristian Dumitrescu 		return;
7225074e1d5SCristian Dumitrescu 	}
7235074e1d5SCristian Dumitrescu 
7245074e1d5SCristian Dumitrescu 	if (n_tokens != t0) {
7255074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
7265074e1d5SCristian Dumitrescu 		return;
7275074e1d5SCristian Dumitrescu 	}
7285074e1d5SCristian Dumitrescu }
7295074e1d5SCristian Dumitrescu 
7305074e1d5SCristian Dumitrescu static const char cmd_pipeline_build_help[] =
7315074e1d5SCristian Dumitrescu "pipeline <pipeline_name> build <spec_file>\n";
7325074e1d5SCristian Dumitrescu 
7335074e1d5SCristian Dumitrescu static void
7345074e1d5SCristian Dumitrescu cmd_pipeline_build(char **tokens,
7355074e1d5SCristian Dumitrescu 	uint32_t n_tokens,
7365074e1d5SCristian Dumitrescu 	char *out,
7375074e1d5SCristian Dumitrescu 	size_t out_size,
7385074e1d5SCristian Dumitrescu 	void *obj)
7395074e1d5SCristian Dumitrescu {
7405074e1d5SCristian Dumitrescu 	struct pipeline *p = NULL;
7415074e1d5SCristian Dumitrescu 	FILE *spec = NULL;
7425074e1d5SCristian Dumitrescu 	uint32_t err_line;
7435074e1d5SCristian Dumitrescu 	const char *err_msg;
7445074e1d5SCristian Dumitrescu 	int status;
7455074e1d5SCristian Dumitrescu 
7465074e1d5SCristian Dumitrescu 	if (n_tokens != 4) {
7475074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
7485074e1d5SCristian Dumitrescu 		return;
7495074e1d5SCristian Dumitrescu 	}
7505074e1d5SCristian Dumitrescu 
7515074e1d5SCristian Dumitrescu 	p = pipeline_find(obj, tokens[1]);
7525074e1d5SCristian Dumitrescu 	if (!p || p->ctl) {
7535074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
7545074e1d5SCristian Dumitrescu 		return;
7555074e1d5SCristian Dumitrescu 	}
7565074e1d5SCristian Dumitrescu 
7575074e1d5SCristian Dumitrescu 	spec = fopen(tokens[3], "r");
7585074e1d5SCristian Dumitrescu 	if (!spec) {
7595074e1d5SCristian Dumitrescu 		snprintf(out, out_size, "Cannot open file %s.\n", tokens[3]);
7605074e1d5SCristian Dumitrescu 		return;
7615074e1d5SCristian Dumitrescu 	}
7625074e1d5SCristian Dumitrescu 
7635074e1d5SCristian Dumitrescu 	status = rte_swx_pipeline_build_from_spec(p->p,
7645074e1d5SCristian Dumitrescu 		spec,
7655074e1d5SCristian Dumitrescu 		&err_line,
7665074e1d5SCristian Dumitrescu 		&err_msg);
7675074e1d5SCristian Dumitrescu 	fclose(spec);
7685074e1d5SCristian Dumitrescu 	if (status) {
7695074e1d5SCristian Dumitrescu 		snprintf(out, out_size, "Error %d at line %u: %s\n.",
7705074e1d5SCristian Dumitrescu 			status, err_line, err_msg);
7715074e1d5SCristian Dumitrescu 		return;
7725074e1d5SCristian Dumitrescu 	}
7735074e1d5SCristian Dumitrescu 
7745074e1d5SCristian Dumitrescu 	p->ctl = rte_swx_ctl_pipeline_create(p->p);
7755074e1d5SCristian Dumitrescu 	if (!p->ctl) {
7765074e1d5SCristian Dumitrescu 		snprintf(out, out_size, "Pipeline control create failed.");
7775074e1d5SCristian Dumitrescu 		rte_swx_pipeline_free(p->p);
7785074e1d5SCristian Dumitrescu 		return;
7795074e1d5SCristian Dumitrescu 	}
7805074e1d5SCristian Dumitrescu }
7815074e1d5SCristian Dumitrescu 
7825074e1d5SCristian Dumitrescu static const char cmd_pipeline_table_update_help[] =
7835074e1d5SCristian Dumitrescu "pipeline <pipeline_name> table <table_name> update <file_name_add> "
7845074e1d5SCristian Dumitrescu "<file_name_delete> <file_name_default>";
7855074e1d5SCristian Dumitrescu 
7865074e1d5SCristian Dumitrescu static void
7875074e1d5SCristian Dumitrescu cmd_pipeline_table_update(char **tokens,
7885074e1d5SCristian Dumitrescu 	uint32_t n_tokens,
7895074e1d5SCristian Dumitrescu 	char *out,
7905074e1d5SCristian Dumitrescu 	size_t out_size,
7915074e1d5SCristian Dumitrescu 	void *obj)
7925074e1d5SCristian Dumitrescu {
7935074e1d5SCristian Dumitrescu 	struct pipeline *p;
7945074e1d5SCristian Dumitrescu 	char *pipeline_name, *table_name, *line = NULL;
7955074e1d5SCristian Dumitrescu 	char *file_name_add, *file_name_delete, *file_name_default;
7965074e1d5SCristian Dumitrescu 	FILE *file_add = NULL, *file_delete = NULL, *file_default = NULL;
7975074e1d5SCristian Dumitrescu 	uint32_t line_id;
7985074e1d5SCristian Dumitrescu 	int status;
7995074e1d5SCristian Dumitrescu 
8005074e1d5SCristian Dumitrescu 	if (n_tokens != 8) {
8015074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
8025074e1d5SCristian Dumitrescu 		return;
8035074e1d5SCristian Dumitrescu 	}
8045074e1d5SCristian Dumitrescu 
8055074e1d5SCristian Dumitrescu 	pipeline_name = tokens[1];
8065074e1d5SCristian Dumitrescu 	p = pipeline_find(obj, pipeline_name);
8075074e1d5SCristian Dumitrescu 	if (!p || !p->ctl) {
8085074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
8095074e1d5SCristian Dumitrescu 		return;
8105074e1d5SCristian Dumitrescu 	}
8115074e1d5SCristian Dumitrescu 
8125074e1d5SCristian Dumitrescu 	if (strcmp(tokens[2], "table") != 0) {
8135074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
8145074e1d5SCristian Dumitrescu 		return;
8155074e1d5SCristian Dumitrescu 	}
8165074e1d5SCristian Dumitrescu 
8175074e1d5SCristian Dumitrescu 	table_name = tokens[3];
8185074e1d5SCristian Dumitrescu 
8195074e1d5SCristian Dumitrescu 	if (strcmp(tokens[4], "update") != 0) {
8205074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "update");
8215074e1d5SCristian Dumitrescu 		return;
8225074e1d5SCristian Dumitrescu 	}
8235074e1d5SCristian Dumitrescu 
8245074e1d5SCristian Dumitrescu 	file_name_add = tokens[5];
8255074e1d5SCristian Dumitrescu 	file_name_delete = tokens[6];
8265074e1d5SCristian Dumitrescu 	file_name_default = tokens[7];
8275074e1d5SCristian Dumitrescu 
8285074e1d5SCristian Dumitrescu 	/* File open. */
8295074e1d5SCristian Dumitrescu 	if (strcmp(file_name_add, "none")) {
8305074e1d5SCristian Dumitrescu 		file_add = fopen(file_name_add, "r");
8315074e1d5SCristian Dumitrescu 		if (!file_add) {
8325074e1d5SCristian Dumitrescu 			snprintf(out, out_size, "Cannot open file %s",
8335074e1d5SCristian Dumitrescu 				file_name_add);
8345074e1d5SCristian Dumitrescu 			goto error;
8355074e1d5SCristian Dumitrescu 		}
8365074e1d5SCristian Dumitrescu 	}
8375074e1d5SCristian Dumitrescu 
8385074e1d5SCristian Dumitrescu 	if (strcmp(file_name_delete, "none")) {
83964eaee23SCristian Dumitrescu 		file_delete = fopen(file_name_delete, "r");
84064eaee23SCristian Dumitrescu 		if (!file_delete) {
8415074e1d5SCristian Dumitrescu 			snprintf(out, out_size, "Cannot open file %s",
8425074e1d5SCristian Dumitrescu 				file_name_delete);
8435074e1d5SCristian Dumitrescu 			goto error;
8445074e1d5SCristian Dumitrescu 		}
8455074e1d5SCristian Dumitrescu 	}
8465074e1d5SCristian Dumitrescu 
8475074e1d5SCristian Dumitrescu 	if (strcmp(file_name_default, "none")) {
84864eaee23SCristian Dumitrescu 		file_default = fopen(file_name_default, "r");
84964eaee23SCristian Dumitrescu 		if (!file_default) {
8505074e1d5SCristian Dumitrescu 			snprintf(out, out_size, "Cannot open file %s",
8515074e1d5SCristian Dumitrescu 				file_name_default);
8525074e1d5SCristian Dumitrescu 			goto error;
8535074e1d5SCristian Dumitrescu 		}
8545074e1d5SCristian Dumitrescu 	}
8555074e1d5SCristian Dumitrescu 
8565074e1d5SCristian Dumitrescu 	if (!file_add && !file_delete && !file_default) {
8575074e1d5SCristian Dumitrescu 		snprintf(out, out_size, "Nothing to be done.");
8585074e1d5SCristian Dumitrescu 		return;
8595074e1d5SCristian Dumitrescu 	}
8605074e1d5SCristian Dumitrescu 
8615074e1d5SCristian Dumitrescu 	/* Buffer allocation. */
8625074e1d5SCristian Dumitrescu 	line = malloc(2048);
8635074e1d5SCristian Dumitrescu 	if (!line) {
8645074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_OUT_OF_MEMORY);
8655074e1d5SCristian Dumitrescu 		goto error;
8665074e1d5SCristian Dumitrescu 	}
8675074e1d5SCristian Dumitrescu 
8685074e1d5SCristian Dumitrescu 	/* Add. */
86903665a48SCristian Dumitrescu 	if (file_add)
8705074e1d5SCristian Dumitrescu 		for (line_id = 1; ; line_id++) {
8715074e1d5SCristian Dumitrescu 			struct rte_swx_table_entry *entry;
8725074e1d5SCristian Dumitrescu 
8735074e1d5SCristian Dumitrescu 			if (fgets(line, 2048, file_add) == NULL)
8745074e1d5SCristian Dumitrescu 				break;
8755074e1d5SCristian Dumitrescu 
8765074e1d5SCristian Dumitrescu 			entry = rte_swx_ctl_pipeline_table_entry_read(p->ctl,
8775074e1d5SCristian Dumitrescu 				table_name,
8785074e1d5SCristian Dumitrescu 				line);
8795074e1d5SCristian Dumitrescu 			if (!entry) {
8805074e1d5SCristian Dumitrescu 				snprintf(out, out_size, MSG_FILE_ERR,
8815074e1d5SCristian Dumitrescu 					file_name_add, line_id);
8825074e1d5SCristian Dumitrescu 				goto error;
8835074e1d5SCristian Dumitrescu 			}
8845074e1d5SCristian Dumitrescu 
8855074e1d5SCristian Dumitrescu 			status = rte_swx_ctl_pipeline_table_entry_add(p->ctl,
8865074e1d5SCristian Dumitrescu 				table_name,
8875074e1d5SCristian Dumitrescu 				entry);
8885074e1d5SCristian Dumitrescu 			if (status) {
8895074e1d5SCristian Dumitrescu 				snprintf(out, out_size,
8905074e1d5SCristian Dumitrescu 					"Invalid entry in file %s at line %u",
8915074e1d5SCristian Dumitrescu 					file_name_add, line_id);
8925074e1d5SCristian Dumitrescu 				goto error;
8935074e1d5SCristian Dumitrescu 			}
8945074e1d5SCristian Dumitrescu 		}
8955074e1d5SCristian Dumitrescu 
8965074e1d5SCristian Dumitrescu 
8975074e1d5SCristian Dumitrescu 	/* Delete. */
89803665a48SCristian Dumitrescu 	if (file_delete)
8995074e1d5SCristian Dumitrescu 		for (line_id = 1; ; line_id++) {
9005074e1d5SCristian Dumitrescu 			struct rte_swx_table_entry *entry;
9015074e1d5SCristian Dumitrescu 
9025074e1d5SCristian Dumitrescu 			if (fgets(line, 2048, file_delete) == NULL)
9035074e1d5SCristian Dumitrescu 				break;
9045074e1d5SCristian Dumitrescu 
9055074e1d5SCristian Dumitrescu 			entry = rte_swx_ctl_pipeline_table_entry_read(p->ctl,
9065074e1d5SCristian Dumitrescu 				table_name,
9075074e1d5SCristian Dumitrescu 				line);
9085074e1d5SCristian Dumitrescu 			if (!entry) {
9095074e1d5SCristian Dumitrescu 				snprintf(out, out_size, MSG_FILE_ERR,
9105074e1d5SCristian Dumitrescu 					file_name_delete, line_id);
9115074e1d5SCristian Dumitrescu 				goto error;
9125074e1d5SCristian Dumitrescu 			}
9135074e1d5SCristian Dumitrescu 
9145074e1d5SCristian Dumitrescu 			status = rte_swx_ctl_pipeline_table_entry_delete(p->ctl,
9155074e1d5SCristian Dumitrescu 				table_name,
9165074e1d5SCristian Dumitrescu 				entry);
9175074e1d5SCristian Dumitrescu 			if (status)  {
9185074e1d5SCristian Dumitrescu 				snprintf(out, out_size,
9195074e1d5SCristian Dumitrescu 					"Invalid entry in file %s at line %u",
9205074e1d5SCristian Dumitrescu 					file_name_delete, line_id);
9215074e1d5SCristian Dumitrescu 				goto error;
9225074e1d5SCristian Dumitrescu 			}
9235074e1d5SCristian Dumitrescu 		}
9245074e1d5SCristian Dumitrescu 
9255074e1d5SCristian Dumitrescu 	/* Default. */
92603665a48SCristian Dumitrescu 	if (file_default)
9275074e1d5SCristian Dumitrescu 		for (line_id = 1; ; line_id++) {
9285074e1d5SCristian Dumitrescu 			struct rte_swx_table_entry *entry;
9295074e1d5SCristian Dumitrescu 
9305074e1d5SCristian Dumitrescu 			if (fgets(line, 2048, file_default) == NULL)
9315074e1d5SCristian Dumitrescu 				break;
9325074e1d5SCristian Dumitrescu 
9335074e1d5SCristian Dumitrescu 			entry = rte_swx_ctl_pipeline_table_entry_read(p->ctl,
9345074e1d5SCristian Dumitrescu 				table_name,
9355074e1d5SCristian Dumitrescu 				line);
9365074e1d5SCristian Dumitrescu 			if (!entry) {
9375074e1d5SCristian Dumitrescu 				snprintf(out, out_size, MSG_FILE_ERR,
9385074e1d5SCristian Dumitrescu 					file_name_default, line_id);
9395074e1d5SCristian Dumitrescu 				goto error;
9405074e1d5SCristian Dumitrescu 			}
9415074e1d5SCristian Dumitrescu 
9425074e1d5SCristian Dumitrescu 			status = rte_swx_ctl_pipeline_table_default_entry_add(p->ctl,
9435074e1d5SCristian Dumitrescu 				table_name,
9445074e1d5SCristian Dumitrescu 				entry);
9455074e1d5SCristian Dumitrescu 			if (status) {
9465074e1d5SCristian Dumitrescu 				snprintf(out, out_size,
9475074e1d5SCristian Dumitrescu 					"Invalid entry in file %s at line %u",
9485074e1d5SCristian Dumitrescu 					file_name_default, line_id);
9495074e1d5SCristian Dumitrescu 				goto error;
9505074e1d5SCristian Dumitrescu 			}
9515074e1d5SCristian Dumitrescu 		}
9525074e1d5SCristian Dumitrescu 
9535074e1d5SCristian Dumitrescu 	status = rte_swx_ctl_pipeline_commit(p->ctl, 1);
9545074e1d5SCristian Dumitrescu 	if (status) {
9555074e1d5SCristian Dumitrescu 		snprintf(out, out_size, "Commit failed.");
9565074e1d5SCristian Dumitrescu 		goto error;
9575074e1d5SCristian Dumitrescu 	}
9585074e1d5SCristian Dumitrescu 
9595074e1d5SCristian Dumitrescu 
9605074e1d5SCristian Dumitrescu 	rte_swx_ctl_pipeline_table_fprintf(stdout, p->ctl, table_name);
9615074e1d5SCristian Dumitrescu 
96203665a48SCristian Dumitrescu 	free(line);
96303665a48SCristian Dumitrescu 	if (file_add)
96403665a48SCristian Dumitrescu 		fclose(file_add);
96503665a48SCristian Dumitrescu 	if (file_delete)
96603665a48SCristian Dumitrescu 		fclose(file_delete);
96703665a48SCristian Dumitrescu 	if (file_default)
96803665a48SCristian Dumitrescu 		fclose(file_default);
9695074e1d5SCristian Dumitrescu 	return;
9705074e1d5SCristian Dumitrescu 
9715074e1d5SCristian Dumitrescu error:
9725074e1d5SCristian Dumitrescu 	rte_swx_ctl_pipeline_abort(p->ctl);
9735074e1d5SCristian Dumitrescu 	free(line);
9745074e1d5SCristian Dumitrescu 	if (file_add)
9755074e1d5SCristian Dumitrescu 		fclose(file_add);
9765074e1d5SCristian Dumitrescu 	if (file_delete)
9775074e1d5SCristian Dumitrescu 		fclose(file_delete);
9785074e1d5SCristian Dumitrescu 	if (file_default)
9795074e1d5SCristian Dumitrescu 		fclose(file_default);
9805074e1d5SCristian Dumitrescu }
9815074e1d5SCristian Dumitrescu 
9825074e1d5SCristian Dumitrescu static const char cmd_pipeline_stats_help[] =
9835074e1d5SCristian Dumitrescu "pipeline <pipeline_name> stats\n";
9845074e1d5SCristian Dumitrescu 
9855074e1d5SCristian Dumitrescu static void
9865074e1d5SCristian Dumitrescu cmd_pipeline_stats(char **tokens,
9875074e1d5SCristian Dumitrescu 	uint32_t n_tokens,
9885074e1d5SCristian Dumitrescu 	char *out,
9895074e1d5SCristian Dumitrescu 	size_t out_size,
9905074e1d5SCristian Dumitrescu 	void *obj)
9915074e1d5SCristian Dumitrescu {
9925074e1d5SCristian Dumitrescu 	struct rte_swx_ctl_pipeline_info info;
9935074e1d5SCristian Dumitrescu 	struct pipeline *p;
9945074e1d5SCristian Dumitrescu 	uint32_t i;
9955074e1d5SCristian Dumitrescu 	int status;
9965074e1d5SCristian Dumitrescu 
9975074e1d5SCristian Dumitrescu 	if (n_tokens != 3) {
9985074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
9995074e1d5SCristian Dumitrescu 		return;
10005074e1d5SCristian Dumitrescu 	}
10015074e1d5SCristian Dumitrescu 
10025074e1d5SCristian Dumitrescu 	p = pipeline_find(obj, tokens[1]);
10035074e1d5SCristian Dumitrescu 	if (!p || !p->ctl) {
10045074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
10055074e1d5SCristian Dumitrescu 		return;
10065074e1d5SCristian Dumitrescu 	}
10075074e1d5SCristian Dumitrescu 
10085074e1d5SCristian Dumitrescu 	if (strcmp(tokens[2], "stats")) {
10095074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "stats");
10105074e1d5SCristian Dumitrescu 		return;
10115074e1d5SCristian Dumitrescu 	}
10125074e1d5SCristian Dumitrescu 
10135074e1d5SCristian Dumitrescu 	status = rte_swx_ctl_pipeline_info_get(p->p, &info);
10145074e1d5SCristian Dumitrescu 	if (status) {
10155074e1d5SCristian Dumitrescu 		snprintf(out, out_size, "Pipeline info get error.");
10165074e1d5SCristian Dumitrescu 		return;
10175074e1d5SCristian Dumitrescu 	}
10185074e1d5SCristian Dumitrescu 
10195074e1d5SCristian Dumitrescu 	snprintf(out, out_size, "Input ports:\n");
10205074e1d5SCristian Dumitrescu 	out_size -= strlen(out);
10215074e1d5SCristian Dumitrescu 	out += strlen(out);
10225074e1d5SCristian Dumitrescu 
10235074e1d5SCristian Dumitrescu 	for (i = 0; i < info.n_ports_in; i++) {
10245074e1d5SCristian Dumitrescu 		struct rte_swx_port_in_stats stats;
10255074e1d5SCristian Dumitrescu 
10265074e1d5SCristian Dumitrescu 		rte_swx_ctl_pipeline_port_in_stats_read(p->p, i, &stats);
10275074e1d5SCristian Dumitrescu 
10285074e1d5SCristian Dumitrescu 		snprintf(out, out_size, "\tPort %u:"
10295074e1d5SCristian Dumitrescu 			" packets %" PRIu64
10305074e1d5SCristian Dumitrescu 			" bytes %" PRIu64
10315074e1d5SCristian Dumitrescu 			" empty %" PRIu64 "\n",
10325074e1d5SCristian Dumitrescu 			i, stats.n_pkts, stats.n_bytes, stats.n_empty);
10335074e1d5SCristian Dumitrescu 		out_size -= strlen(out);
10345074e1d5SCristian Dumitrescu 		out += strlen(out);
10355074e1d5SCristian Dumitrescu 	}
10365074e1d5SCristian Dumitrescu 
10375074e1d5SCristian Dumitrescu 	snprintf(out, out_size, "Output ports:\n");
10385074e1d5SCristian Dumitrescu 	out_size -= strlen(out);
10395074e1d5SCristian Dumitrescu 	out += strlen(out);
10405074e1d5SCristian Dumitrescu 
10415074e1d5SCristian Dumitrescu 	for (i = 0; i < info.n_ports_out; i++) {
10425074e1d5SCristian Dumitrescu 		struct rte_swx_port_out_stats stats;
10435074e1d5SCristian Dumitrescu 
10445074e1d5SCristian Dumitrescu 		rte_swx_ctl_pipeline_port_out_stats_read(p->p, i, &stats);
10455074e1d5SCristian Dumitrescu 
10465074e1d5SCristian Dumitrescu 		snprintf(out, out_size, "\tPort %u:"
10475074e1d5SCristian Dumitrescu 			" packets %" PRIu64
10485074e1d5SCristian Dumitrescu 			" bytes %" PRIu64 "\n",
10495074e1d5SCristian Dumitrescu 			i, stats.n_pkts, stats.n_bytes);
10505074e1d5SCristian Dumitrescu 		out_size -= strlen(out);
10515074e1d5SCristian Dumitrescu 		out += strlen(out);
10525074e1d5SCristian Dumitrescu 	}
10535074e1d5SCristian Dumitrescu }
10545074e1d5SCristian Dumitrescu 
10555074e1d5SCristian Dumitrescu static const char cmd_thread_pipeline_enable_help[] =
10565074e1d5SCristian Dumitrescu "thread <thread_id> pipeline <pipeline_name> enable\n";
10575074e1d5SCristian Dumitrescu 
10585074e1d5SCristian Dumitrescu static void
10595074e1d5SCristian Dumitrescu cmd_thread_pipeline_enable(char **tokens,
10605074e1d5SCristian Dumitrescu 	uint32_t n_tokens,
10615074e1d5SCristian Dumitrescu 	char *out,
10625074e1d5SCristian Dumitrescu 	size_t out_size,
10635074e1d5SCristian Dumitrescu 	void *obj)
10645074e1d5SCristian Dumitrescu {
10655074e1d5SCristian Dumitrescu 	char *pipeline_name;
10665074e1d5SCristian Dumitrescu 	struct pipeline *p;
10675074e1d5SCristian Dumitrescu 	uint32_t thread_id;
10685074e1d5SCristian Dumitrescu 	int status;
10695074e1d5SCristian Dumitrescu 
10705074e1d5SCristian Dumitrescu 	if (n_tokens != 5) {
10715074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
10725074e1d5SCristian Dumitrescu 		return;
10735074e1d5SCristian Dumitrescu 	}
10745074e1d5SCristian Dumitrescu 
10755074e1d5SCristian Dumitrescu 	if (parser_read_uint32(&thread_id, tokens[1]) != 0) {
10765074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "thread_id");
10775074e1d5SCristian Dumitrescu 		return;
10785074e1d5SCristian Dumitrescu 	}
10795074e1d5SCristian Dumitrescu 
10805074e1d5SCristian Dumitrescu 	if (strcmp(tokens[2], "pipeline") != 0) {
10815074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pipeline");
10825074e1d5SCristian Dumitrescu 		return;
10835074e1d5SCristian Dumitrescu 	}
10845074e1d5SCristian Dumitrescu 
10855074e1d5SCristian Dumitrescu 	pipeline_name = tokens[3];
10865074e1d5SCristian Dumitrescu 	p = pipeline_find(obj, pipeline_name);
10875074e1d5SCristian Dumitrescu 	if (!p || !p->ctl) {
10885074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
10895074e1d5SCristian Dumitrescu 		return;
10905074e1d5SCristian Dumitrescu 	}
10915074e1d5SCristian Dumitrescu 
10925074e1d5SCristian Dumitrescu 	if (strcmp(tokens[4], "enable") != 0) {
10935074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "enable");
10945074e1d5SCristian Dumitrescu 		return;
10955074e1d5SCristian Dumitrescu 	}
10965074e1d5SCristian Dumitrescu 
10975074e1d5SCristian Dumitrescu 	status = thread_pipeline_enable(thread_id, obj, pipeline_name);
10985074e1d5SCristian Dumitrescu 	if (status) {
10995074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_CMD_FAIL, "thread pipeline enable");
11005074e1d5SCristian Dumitrescu 		return;
11015074e1d5SCristian Dumitrescu 	}
11025074e1d5SCristian Dumitrescu }
11035074e1d5SCristian Dumitrescu 
11045074e1d5SCristian Dumitrescu static const char cmd_thread_pipeline_disable_help[] =
11055074e1d5SCristian Dumitrescu "thread <thread_id> pipeline <pipeline_name> disable\n";
11065074e1d5SCristian Dumitrescu 
11075074e1d5SCristian Dumitrescu static void
11085074e1d5SCristian Dumitrescu cmd_thread_pipeline_disable(char **tokens,
11095074e1d5SCristian Dumitrescu 	uint32_t n_tokens,
11105074e1d5SCristian Dumitrescu 	char *out,
11115074e1d5SCristian Dumitrescu 	size_t out_size,
11125074e1d5SCristian Dumitrescu 	void *obj)
11135074e1d5SCristian Dumitrescu {
11145074e1d5SCristian Dumitrescu 	struct pipeline *p;
11155074e1d5SCristian Dumitrescu 	char *pipeline_name;
11165074e1d5SCristian Dumitrescu 	uint32_t thread_id;
11175074e1d5SCristian Dumitrescu 	int status;
11185074e1d5SCristian Dumitrescu 
11195074e1d5SCristian Dumitrescu 	if (n_tokens != 5) {
11205074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
11215074e1d5SCristian Dumitrescu 		return;
11225074e1d5SCristian Dumitrescu 	}
11235074e1d5SCristian Dumitrescu 
11245074e1d5SCristian Dumitrescu 	if (parser_read_uint32(&thread_id, tokens[1]) != 0) {
11255074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "thread_id");
11265074e1d5SCristian Dumitrescu 		return;
11275074e1d5SCristian Dumitrescu 	}
11285074e1d5SCristian Dumitrescu 
11295074e1d5SCristian Dumitrescu 	if (strcmp(tokens[2], "pipeline") != 0) {
11305074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pipeline");
11315074e1d5SCristian Dumitrescu 		return;
11325074e1d5SCristian Dumitrescu 	}
11335074e1d5SCristian Dumitrescu 
11345074e1d5SCristian Dumitrescu 	pipeline_name = tokens[3];
11355074e1d5SCristian Dumitrescu 	p = pipeline_find(obj, pipeline_name);
11365074e1d5SCristian Dumitrescu 	if (!p || !p->ctl) {
11375074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
11385074e1d5SCristian Dumitrescu 		return;
11395074e1d5SCristian Dumitrescu 	}
11405074e1d5SCristian Dumitrescu 
11415074e1d5SCristian Dumitrescu 	if (strcmp(tokens[4], "disable") != 0) {
11425074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "disable");
11435074e1d5SCristian Dumitrescu 		return;
11445074e1d5SCristian Dumitrescu 	}
11455074e1d5SCristian Dumitrescu 
11465074e1d5SCristian Dumitrescu 	status = thread_pipeline_disable(thread_id, obj, pipeline_name);
11475074e1d5SCristian Dumitrescu 	if (status) {
11485074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_CMD_FAIL,
11495074e1d5SCristian Dumitrescu 			"thread pipeline disable");
11505074e1d5SCristian Dumitrescu 		return;
11515074e1d5SCristian Dumitrescu 	}
11525074e1d5SCristian Dumitrescu }
11535074e1d5SCristian Dumitrescu 
11545074e1d5SCristian Dumitrescu static void
11555074e1d5SCristian Dumitrescu cmd_help(char **tokens,
11565074e1d5SCristian Dumitrescu 	 uint32_t n_tokens,
11575074e1d5SCristian Dumitrescu 	 char *out,
11585074e1d5SCristian Dumitrescu 	 size_t out_size,
11595074e1d5SCristian Dumitrescu 	 void *arg __rte_unused)
11605074e1d5SCristian Dumitrescu {
11615074e1d5SCristian Dumitrescu 	tokens++;
11625074e1d5SCristian Dumitrescu 	n_tokens--;
11635074e1d5SCristian Dumitrescu 
11645074e1d5SCristian Dumitrescu 	if (n_tokens == 0) {
11655074e1d5SCristian Dumitrescu 		snprintf(out, out_size,
1166*7fef9ef1SYogesh Jangra 			"Type 'help <command>' for command details.\n\n"
1167*7fef9ef1SYogesh Jangra 			"List of commands:\n"
1168*7fef9ef1SYogesh Jangra 			"\tmempool\n"
1169*7fef9ef1SYogesh Jangra 			"\tlink\n"
1170*7fef9ef1SYogesh Jangra 			"\tpipeline create\n"
1171*7fef9ef1SYogesh Jangra 			"\tpipeline port in\n"
1172*7fef9ef1SYogesh Jangra 			"\tpipeline port out\n"
1173*7fef9ef1SYogesh Jangra 			"\tpipeline build\n"
1174*7fef9ef1SYogesh Jangra 			"\tpipeline table update\n"
1175*7fef9ef1SYogesh Jangra 			"\tpipeline stats\n"
1176*7fef9ef1SYogesh Jangra 			"\tthread pipeline enable\n"
1177*7fef9ef1SYogesh Jangra 			"\tthread pipeline disable\n\n");
11785074e1d5SCristian Dumitrescu 		return;
11795074e1d5SCristian Dumitrescu 	}
11805074e1d5SCristian Dumitrescu 
11815074e1d5SCristian Dumitrescu 	if (strcmp(tokens[0], "mempool") == 0) {
11825074e1d5SCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n", cmd_mempool_help);
11835074e1d5SCristian Dumitrescu 		return;
11845074e1d5SCristian Dumitrescu 	}
11855074e1d5SCristian Dumitrescu 
11865074e1d5SCristian Dumitrescu 	if (strcmp(tokens[0], "link") == 0) {
11875074e1d5SCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n", cmd_link_help);
11885074e1d5SCristian Dumitrescu 		return;
11895074e1d5SCristian Dumitrescu 	}
11905074e1d5SCristian Dumitrescu 
11915074e1d5SCristian Dumitrescu 	if ((strcmp(tokens[0], "pipeline") == 0) &&
1192*7fef9ef1SYogesh Jangra 		(n_tokens == 2) && (strcmp(tokens[1], "create") == 0)) {
11935074e1d5SCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n", cmd_pipeline_create_help);
11945074e1d5SCristian Dumitrescu 		return;
11955074e1d5SCristian Dumitrescu 	}
11965074e1d5SCristian Dumitrescu 
11975074e1d5SCristian Dumitrescu 	if ((strcmp(tokens[0], "pipeline") == 0) &&
1198*7fef9ef1SYogesh Jangra 		(n_tokens == 3) && (strcmp(tokens[1], "port") == 0)) {
1199*7fef9ef1SYogesh Jangra 		if (strcmp(tokens[2], "in") == 0) {
12005074e1d5SCristian Dumitrescu 			snprintf(out, out_size, "\n%s\n",
12015074e1d5SCristian Dumitrescu 				cmd_pipeline_port_in_help);
12025074e1d5SCristian Dumitrescu 			return;
12035074e1d5SCristian Dumitrescu 		}
12045074e1d5SCristian Dumitrescu 
1205*7fef9ef1SYogesh Jangra 		if (strcmp(tokens[2], "out") == 0) {
12065074e1d5SCristian Dumitrescu 			snprintf(out, out_size, "\n%s\n",
12075074e1d5SCristian Dumitrescu 				cmd_pipeline_port_out_help);
12085074e1d5SCristian Dumitrescu 			return;
12095074e1d5SCristian Dumitrescu 		}
12105074e1d5SCristian Dumitrescu 	}
12115074e1d5SCristian Dumitrescu 
12125074e1d5SCristian Dumitrescu 	if ((strcmp(tokens[0], "pipeline") == 0) &&
1213*7fef9ef1SYogesh Jangra 		(n_tokens == 2) && (strcmp(tokens[1], "build") == 0)) {
12145074e1d5SCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n", cmd_pipeline_build_help);
12155074e1d5SCristian Dumitrescu 		return;
12165074e1d5SCristian Dumitrescu 	}
12175074e1d5SCristian Dumitrescu 
12185074e1d5SCristian Dumitrescu 	if ((strcmp(tokens[0], "pipeline") == 0) &&
1219*7fef9ef1SYogesh Jangra 		(n_tokens == 3) &&
1220*7fef9ef1SYogesh Jangra 		(strcmp(tokens[1], "table") == 0) &&
1221*7fef9ef1SYogesh Jangra 		(strcmp(tokens[2], "update") == 0)) {
12225074e1d5SCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n",
12235074e1d5SCristian Dumitrescu 			cmd_pipeline_table_update_help);
12245074e1d5SCristian Dumitrescu 		return;
12255074e1d5SCristian Dumitrescu 	}
12265074e1d5SCristian Dumitrescu 
12275074e1d5SCristian Dumitrescu 	if ((strcmp(tokens[0], "pipeline") == 0) &&
1228*7fef9ef1SYogesh Jangra 		(n_tokens == 2) && (strcmp(tokens[1], "stats") == 0)) {
12295074e1d5SCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n", cmd_pipeline_stats_help);
12305074e1d5SCristian Dumitrescu 		return;
12315074e1d5SCristian Dumitrescu 	}
12325074e1d5SCristian Dumitrescu 
12335074e1d5SCristian Dumitrescu 	if ((n_tokens == 3) &&
12345074e1d5SCristian Dumitrescu 		(strcmp(tokens[0], "thread") == 0) &&
12355074e1d5SCristian Dumitrescu 		(strcmp(tokens[1], "pipeline") == 0)) {
12365074e1d5SCristian Dumitrescu 		if (strcmp(tokens[2], "enable") == 0) {
12375074e1d5SCristian Dumitrescu 			snprintf(out, out_size, "\n%s\n",
12385074e1d5SCristian Dumitrescu 				cmd_thread_pipeline_enable_help);
12395074e1d5SCristian Dumitrescu 			return;
12405074e1d5SCristian Dumitrescu 		}
12415074e1d5SCristian Dumitrescu 
12425074e1d5SCristian Dumitrescu 		if (strcmp(tokens[2], "disable") == 0) {
12435074e1d5SCristian Dumitrescu 			snprintf(out, out_size, "\n%s\n",
12445074e1d5SCristian Dumitrescu 				cmd_thread_pipeline_disable_help);
12455074e1d5SCristian Dumitrescu 			return;
12465074e1d5SCristian Dumitrescu 		}
12475074e1d5SCristian Dumitrescu 	}
12485074e1d5SCristian Dumitrescu 
12495074e1d5SCristian Dumitrescu 	snprintf(out, out_size, "Invalid command\n");
12505074e1d5SCristian Dumitrescu }
12515074e1d5SCristian Dumitrescu 
12525074e1d5SCristian Dumitrescu void
12535074e1d5SCristian Dumitrescu cli_process(char *in, char *out, size_t out_size, void *obj)
12545074e1d5SCristian Dumitrescu {
12555074e1d5SCristian Dumitrescu 	char *tokens[CMD_MAX_TOKENS];
12565074e1d5SCristian Dumitrescu 	uint32_t n_tokens = RTE_DIM(tokens);
12575074e1d5SCristian Dumitrescu 	int status;
12585074e1d5SCristian Dumitrescu 
12595074e1d5SCristian Dumitrescu 	if (is_comment(in))
12605074e1d5SCristian Dumitrescu 		return;
12615074e1d5SCristian Dumitrescu 
12625074e1d5SCristian Dumitrescu 	status = parse_tokenize_string(in, tokens, &n_tokens);
12635074e1d5SCristian Dumitrescu 	if (status) {
12645074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_TOO_MANY, "");
12655074e1d5SCristian Dumitrescu 		return;
12665074e1d5SCristian Dumitrescu 	}
12675074e1d5SCristian Dumitrescu 
12685074e1d5SCristian Dumitrescu 	if (n_tokens == 0)
12695074e1d5SCristian Dumitrescu 		return;
12705074e1d5SCristian Dumitrescu 
12715074e1d5SCristian Dumitrescu 	if (strcmp(tokens[0], "help") == 0) {
12725074e1d5SCristian Dumitrescu 		cmd_help(tokens, n_tokens, out, out_size, obj);
12735074e1d5SCristian Dumitrescu 		return;
12745074e1d5SCristian Dumitrescu 	}
12755074e1d5SCristian Dumitrescu 
12765074e1d5SCristian Dumitrescu 	if (strcmp(tokens[0], "mempool") == 0) {
12775074e1d5SCristian Dumitrescu 		cmd_mempool(tokens, n_tokens, out, out_size, obj);
12785074e1d5SCristian Dumitrescu 		return;
12795074e1d5SCristian Dumitrescu 	}
12805074e1d5SCristian Dumitrescu 
12815074e1d5SCristian Dumitrescu 	if (strcmp(tokens[0], "link") == 0) {
12825074e1d5SCristian Dumitrescu 		if (strcmp(tokens[1], "show") == 0) {
12835074e1d5SCristian Dumitrescu 			cmd_link_show(tokens, n_tokens, out, out_size, obj);
12845074e1d5SCristian Dumitrescu 			return;
12855074e1d5SCristian Dumitrescu 		}
12865074e1d5SCristian Dumitrescu 
12875074e1d5SCristian Dumitrescu 		cmd_link(tokens, n_tokens, out, out_size, obj);
12885074e1d5SCristian Dumitrescu 		return;
12895074e1d5SCristian Dumitrescu 	}
12905074e1d5SCristian Dumitrescu 
12915074e1d5SCristian Dumitrescu 	if (strcmp(tokens[0], "pipeline") == 0) {
12925074e1d5SCristian Dumitrescu 		if ((n_tokens >= 3) &&
12935074e1d5SCristian Dumitrescu 			(strcmp(tokens[2], "create") == 0)) {
12945074e1d5SCristian Dumitrescu 			cmd_pipeline_create(tokens, n_tokens, out, out_size,
12955074e1d5SCristian Dumitrescu 				obj);
12965074e1d5SCristian Dumitrescu 			return;
12975074e1d5SCristian Dumitrescu 		}
12985074e1d5SCristian Dumitrescu 
12995074e1d5SCristian Dumitrescu 		if ((n_tokens >= 4) &&
13005074e1d5SCristian Dumitrescu 			(strcmp(tokens[2], "port") == 0) &&
13015074e1d5SCristian Dumitrescu 			(strcmp(tokens[3], "in") == 0)) {
13025074e1d5SCristian Dumitrescu 			cmd_pipeline_port_in(tokens, n_tokens, out, out_size,
13035074e1d5SCristian Dumitrescu 				obj);
13045074e1d5SCristian Dumitrescu 			return;
13055074e1d5SCristian Dumitrescu 		}
13065074e1d5SCristian Dumitrescu 
13075074e1d5SCristian Dumitrescu 		if ((n_tokens >= 4) &&
13085074e1d5SCristian Dumitrescu 			(strcmp(tokens[2], "port") == 0) &&
13095074e1d5SCristian Dumitrescu 			(strcmp(tokens[3], "out") == 0)) {
13105074e1d5SCristian Dumitrescu 			cmd_pipeline_port_out(tokens, n_tokens, out, out_size,
13115074e1d5SCristian Dumitrescu 				obj);
13125074e1d5SCristian Dumitrescu 			return;
13135074e1d5SCristian Dumitrescu 		}
13145074e1d5SCristian Dumitrescu 
13155074e1d5SCristian Dumitrescu 		if ((n_tokens >= 3) &&
13165074e1d5SCristian Dumitrescu 			(strcmp(tokens[2], "build") == 0)) {
13175074e1d5SCristian Dumitrescu 			cmd_pipeline_build(tokens, n_tokens, out, out_size,
13185074e1d5SCristian Dumitrescu 				obj);
13195074e1d5SCristian Dumitrescu 			return;
13205074e1d5SCristian Dumitrescu 		}
13215074e1d5SCristian Dumitrescu 
13225074e1d5SCristian Dumitrescu 		if ((n_tokens >= 3) &&
13235074e1d5SCristian Dumitrescu 			(strcmp(tokens[2], "table") == 0)) {
13245074e1d5SCristian Dumitrescu 			cmd_pipeline_table_update(tokens, n_tokens, out,
13255074e1d5SCristian Dumitrescu 				out_size, obj);
13265074e1d5SCristian Dumitrescu 			return;
13275074e1d5SCristian Dumitrescu 		}
13285074e1d5SCristian Dumitrescu 
13295074e1d5SCristian Dumitrescu 		if ((n_tokens >= 3) &&
13305074e1d5SCristian Dumitrescu 			(strcmp(tokens[2], "stats") == 0)) {
13315074e1d5SCristian Dumitrescu 			cmd_pipeline_stats(tokens, n_tokens, out, out_size,
13325074e1d5SCristian Dumitrescu 				obj);
13335074e1d5SCristian Dumitrescu 			return;
13345074e1d5SCristian Dumitrescu 		}
13355074e1d5SCristian Dumitrescu 	}
13365074e1d5SCristian Dumitrescu 
13375074e1d5SCristian Dumitrescu 	if (strcmp(tokens[0], "thread") == 0) {
13385074e1d5SCristian Dumitrescu 		if ((n_tokens >= 5) &&
13395074e1d5SCristian Dumitrescu 			(strcmp(tokens[4], "enable") == 0)) {
13405074e1d5SCristian Dumitrescu 			cmd_thread_pipeline_enable(tokens, n_tokens,
13415074e1d5SCristian Dumitrescu 				out, out_size, obj);
13425074e1d5SCristian Dumitrescu 			return;
13435074e1d5SCristian Dumitrescu 		}
13445074e1d5SCristian Dumitrescu 
13455074e1d5SCristian Dumitrescu 		if ((n_tokens >= 5) &&
13465074e1d5SCristian Dumitrescu 			(strcmp(tokens[4], "disable") == 0)) {
13475074e1d5SCristian Dumitrescu 			cmd_thread_pipeline_disable(tokens, n_tokens,
13485074e1d5SCristian Dumitrescu 				out, out_size, obj);
13495074e1d5SCristian Dumitrescu 			return;
13505074e1d5SCristian Dumitrescu 		}
13515074e1d5SCristian Dumitrescu 	}
13525074e1d5SCristian Dumitrescu 
13535074e1d5SCristian Dumitrescu 	snprintf(out, out_size, MSG_CMD_UNKNOWN, tokens[0]);
13545074e1d5SCristian Dumitrescu }
13555074e1d5SCristian Dumitrescu 
13565074e1d5SCristian Dumitrescu int
13575074e1d5SCristian Dumitrescu cli_script_process(const char *file_name,
13585074e1d5SCristian Dumitrescu 	size_t msg_in_len_max,
13595074e1d5SCristian Dumitrescu 	size_t msg_out_len_max,
13605074e1d5SCristian Dumitrescu 	void *obj)
13615074e1d5SCristian Dumitrescu {
13625074e1d5SCristian Dumitrescu 	char *msg_in = NULL, *msg_out = NULL;
13635074e1d5SCristian Dumitrescu 	FILE *f = NULL;
13645074e1d5SCristian Dumitrescu 
13655074e1d5SCristian Dumitrescu 	/* Check input arguments */
13665074e1d5SCristian Dumitrescu 	if ((file_name == NULL) ||
13675074e1d5SCristian Dumitrescu 		(strlen(file_name) == 0) ||
13685074e1d5SCristian Dumitrescu 		(msg_in_len_max == 0) ||
13695074e1d5SCristian Dumitrescu 		(msg_out_len_max == 0))
13705074e1d5SCristian Dumitrescu 		return -EINVAL;
13715074e1d5SCristian Dumitrescu 
13725074e1d5SCristian Dumitrescu 	msg_in = malloc(msg_in_len_max + 1);
13735074e1d5SCristian Dumitrescu 	msg_out = malloc(msg_out_len_max + 1);
13745074e1d5SCristian Dumitrescu 	if ((msg_in == NULL) ||
13755074e1d5SCristian Dumitrescu 		(msg_out == NULL)) {
13765074e1d5SCristian Dumitrescu 		free(msg_out);
13775074e1d5SCristian Dumitrescu 		free(msg_in);
13785074e1d5SCristian Dumitrescu 		return -ENOMEM;
13795074e1d5SCristian Dumitrescu 	}
13805074e1d5SCristian Dumitrescu 
13815074e1d5SCristian Dumitrescu 	/* Open input file */
13825074e1d5SCristian Dumitrescu 	f = fopen(file_name, "r");
13835074e1d5SCristian Dumitrescu 	if (f == NULL) {
13845074e1d5SCristian Dumitrescu 		free(msg_out);
13855074e1d5SCristian Dumitrescu 		free(msg_in);
13865074e1d5SCristian Dumitrescu 		return -EIO;
13875074e1d5SCristian Dumitrescu 	}
13885074e1d5SCristian Dumitrescu 
13895074e1d5SCristian Dumitrescu 	/* Read file */
13905074e1d5SCristian Dumitrescu 	for ( ; ; ) {
13915074e1d5SCristian Dumitrescu 		if (fgets(msg_in, msg_in_len_max + 1, f) == NULL)
13925074e1d5SCristian Dumitrescu 			break;
13935074e1d5SCristian Dumitrescu 
13945074e1d5SCristian Dumitrescu 		printf("%s", msg_in);
13955074e1d5SCristian Dumitrescu 		msg_out[0] = 0;
13965074e1d5SCristian Dumitrescu 
13975074e1d5SCristian Dumitrescu 		cli_process(msg_in,
13985074e1d5SCristian Dumitrescu 			msg_out,
13995074e1d5SCristian Dumitrescu 			msg_out_len_max,
14005074e1d5SCristian Dumitrescu 			obj);
14015074e1d5SCristian Dumitrescu 
14025074e1d5SCristian Dumitrescu 		if (strlen(msg_out))
14035074e1d5SCristian Dumitrescu 			printf("%s", msg_out);
14045074e1d5SCristian Dumitrescu 	}
14055074e1d5SCristian Dumitrescu 
14065074e1d5SCristian Dumitrescu 	/* Close file */
14075074e1d5SCristian Dumitrescu 	fclose(f);
14085074e1d5SCristian Dumitrescu 	free(msg_out);
14095074e1d5SCristian Dumitrescu 	free(msg_in);
14105074e1d5SCristian Dumitrescu 	return 0;
14115074e1d5SCristian Dumitrescu }
1412