xref: /dpdk/examples/pipeline/cli.c (revision 821848f5192c6b6be954fa9f04c0e6a470cff2b6)
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"
4837fef9ef1SYogesh 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 
782275ebefeSCristian Dumitrescu static void
783275ebefeSCristian Dumitrescu table_entry_free(struct rte_swx_table_entry *entry)
784275ebefeSCristian Dumitrescu {
785275ebefeSCristian Dumitrescu 	if (!entry)
786275ebefeSCristian Dumitrescu 		return;
787275ebefeSCristian Dumitrescu 
788275ebefeSCristian Dumitrescu 	free(entry->key);
789275ebefeSCristian Dumitrescu 	free(entry->key_mask);
790275ebefeSCristian Dumitrescu 	free(entry->action_data);
791275ebefeSCristian Dumitrescu 	free(entry);
792275ebefeSCristian Dumitrescu }
793275ebefeSCristian Dumitrescu 
7945074e1d5SCristian Dumitrescu static const char cmd_pipeline_table_update_help[] =
7955074e1d5SCristian Dumitrescu "pipeline <pipeline_name> table <table_name> update <file_name_add> "
7965074e1d5SCristian Dumitrescu "<file_name_delete> <file_name_default>";
7975074e1d5SCristian Dumitrescu 
7985074e1d5SCristian Dumitrescu static void
7995074e1d5SCristian Dumitrescu cmd_pipeline_table_update(char **tokens,
8005074e1d5SCristian Dumitrescu 	uint32_t n_tokens,
8015074e1d5SCristian Dumitrescu 	char *out,
8025074e1d5SCristian Dumitrescu 	size_t out_size,
8035074e1d5SCristian Dumitrescu 	void *obj)
8045074e1d5SCristian Dumitrescu {
8055074e1d5SCristian Dumitrescu 	struct pipeline *p;
8065074e1d5SCristian Dumitrescu 	char *pipeline_name, *table_name, *line = NULL;
8075074e1d5SCristian Dumitrescu 	char *file_name_add, *file_name_delete, *file_name_default;
8085074e1d5SCristian Dumitrescu 	FILE *file_add = NULL, *file_delete = NULL, *file_default = NULL;
8095074e1d5SCristian Dumitrescu 	uint32_t line_id;
8105074e1d5SCristian Dumitrescu 	int status;
8115074e1d5SCristian Dumitrescu 
8125074e1d5SCristian Dumitrescu 	if (n_tokens != 8) {
8135074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
8145074e1d5SCristian Dumitrescu 		return;
8155074e1d5SCristian Dumitrescu 	}
8165074e1d5SCristian Dumitrescu 
8175074e1d5SCristian Dumitrescu 	pipeline_name = tokens[1];
8185074e1d5SCristian Dumitrescu 	p = pipeline_find(obj, pipeline_name);
8195074e1d5SCristian Dumitrescu 	if (!p || !p->ctl) {
8205074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
8215074e1d5SCristian Dumitrescu 		return;
8225074e1d5SCristian Dumitrescu 	}
8235074e1d5SCristian Dumitrescu 
8245074e1d5SCristian Dumitrescu 	if (strcmp(tokens[2], "table") != 0) {
8255074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
8265074e1d5SCristian Dumitrescu 		return;
8275074e1d5SCristian Dumitrescu 	}
8285074e1d5SCristian Dumitrescu 
8295074e1d5SCristian Dumitrescu 	table_name = tokens[3];
8305074e1d5SCristian Dumitrescu 
8315074e1d5SCristian Dumitrescu 	if (strcmp(tokens[4], "update") != 0) {
8325074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "update");
8335074e1d5SCristian Dumitrescu 		return;
8345074e1d5SCristian Dumitrescu 	}
8355074e1d5SCristian Dumitrescu 
8365074e1d5SCristian Dumitrescu 	file_name_add = tokens[5];
8375074e1d5SCristian Dumitrescu 	file_name_delete = tokens[6];
8385074e1d5SCristian Dumitrescu 	file_name_default = tokens[7];
8395074e1d5SCristian Dumitrescu 
8405074e1d5SCristian Dumitrescu 	/* File open. */
8415074e1d5SCristian Dumitrescu 	if (strcmp(file_name_add, "none")) {
8425074e1d5SCristian Dumitrescu 		file_add = fopen(file_name_add, "r");
8435074e1d5SCristian Dumitrescu 		if (!file_add) {
8445074e1d5SCristian Dumitrescu 			snprintf(out, out_size, "Cannot open file %s",
8455074e1d5SCristian Dumitrescu 				file_name_add);
8465074e1d5SCristian Dumitrescu 			goto error;
8475074e1d5SCristian Dumitrescu 		}
8485074e1d5SCristian Dumitrescu 	}
8495074e1d5SCristian Dumitrescu 
8505074e1d5SCristian Dumitrescu 	if (strcmp(file_name_delete, "none")) {
85164eaee23SCristian Dumitrescu 		file_delete = fopen(file_name_delete, "r");
85264eaee23SCristian Dumitrescu 		if (!file_delete) {
8535074e1d5SCristian Dumitrescu 			snprintf(out, out_size, "Cannot open file %s",
8545074e1d5SCristian Dumitrescu 				file_name_delete);
8555074e1d5SCristian Dumitrescu 			goto error;
8565074e1d5SCristian Dumitrescu 		}
8575074e1d5SCristian Dumitrescu 	}
8585074e1d5SCristian Dumitrescu 
8595074e1d5SCristian Dumitrescu 	if (strcmp(file_name_default, "none")) {
86064eaee23SCristian Dumitrescu 		file_default = fopen(file_name_default, "r");
86164eaee23SCristian Dumitrescu 		if (!file_default) {
8625074e1d5SCristian Dumitrescu 			snprintf(out, out_size, "Cannot open file %s",
8635074e1d5SCristian Dumitrescu 				file_name_default);
8645074e1d5SCristian Dumitrescu 			goto error;
8655074e1d5SCristian Dumitrescu 		}
8665074e1d5SCristian Dumitrescu 	}
8675074e1d5SCristian Dumitrescu 
8685074e1d5SCristian Dumitrescu 	if (!file_add && !file_delete && !file_default) {
8695074e1d5SCristian Dumitrescu 		snprintf(out, out_size, "Nothing to be done.");
8705074e1d5SCristian Dumitrescu 		return;
8715074e1d5SCristian Dumitrescu 	}
8725074e1d5SCristian Dumitrescu 
8735074e1d5SCristian Dumitrescu 	/* Buffer allocation. */
8745074e1d5SCristian Dumitrescu 	line = malloc(2048);
8755074e1d5SCristian Dumitrescu 	if (!line) {
8765074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_OUT_OF_MEMORY);
8775074e1d5SCristian Dumitrescu 		goto error;
8785074e1d5SCristian Dumitrescu 	}
8795074e1d5SCristian Dumitrescu 
8805074e1d5SCristian Dumitrescu 	/* Add. */
88103665a48SCristian Dumitrescu 	if (file_add)
8825074e1d5SCristian Dumitrescu 		for (line_id = 1; ; line_id++) {
8835074e1d5SCristian Dumitrescu 			struct rte_swx_table_entry *entry;
8845074e1d5SCristian Dumitrescu 
8855074e1d5SCristian Dumitrescu 			if (fgets(line, 2048, file_add) == NULL)
8865074e1d5SCristian Dumitrescu 				break;
8875074e1d5SCristian Dumitrescu 
8885074e1d5SCristian Dumitrescu 			entry = rte_swx_ctl_pipeline_table_entry_read(p->ctl,
8895074e1d5SCristian Dumitrescu 				table_name,
8905074e1d5SCristian Dumitrescu 				line);
8915074e1d5SCristian Dumitrescu 			if (!entry) {
8925074e1d5SCristian Dumitrescu 				snprintf(out, out_size, MSG_FILE_ERR,
8935074e1d5SCristian Dumitrescu 					file_name_add, line_id);
8945074e1d5SCristian Dumitrescu 				goto error;
8955074e1d5SCristian Dumitrescu 			}
8965074e1d5SCristian Dumitrescu 
8975074e1d5SCristian Dumitrescu 			status = rte_swx_ctl_pipeline_table_entry_add(p->ctl,
8985074e1d5SCristian Dumitrescu 				table_name,
8995074e1d5SCristian Dumitrescu 				entry);
900275ebefeSCristian Dumitrescu 			table_entry_free(entry);
9015074e1d5SCristian Dumitrescu 			if (status) {
9025074e1d5SCristian Dumitrescu 				snprintf(out, out_size,
9035074e1d5SCristian Dumitrescu 					"Invalid entry in file %s at line %u",
9045074e1d5SCristian Dumitrescu 					file_name_add, line_id);
9055074e1d5SCristian Dumitrescu 				goto error;
9065074e1d5SCristian Dumitrescu 			}
9075074e1d5SCristian Dumitrescu 		}
9085074e1d5SCristian Dumitrescu 
9095074e1d5SCristian Dumitrescu 
9105074e1d5SCristian Dumitrescu 	/* Delete. */
91103665a48SCristian Dumitrescu 	if (file_delete)
9125074e1d5SCristian Dumitrescu 		for (line_id = 1; ; line_id++) {
9135074e1d5SCristian Dumitrescu 			struct rte_swx_table_entry *entry;
9145074e1d5SCristian Dumitrescu 
9155074e1d5SCristian Dumitrescu 			if (fgets(line, 2048, file_delete) == NULL)
9165074e1d5SCristian Dumitrescu 				break;
9175074e1d5SCristian Dumitrescu 
9185074e1d5SCristian Dumitrescu 			entry = rte_swx_ctl_pipeline_table_entry_read(p->ctl,
9195074e1d5SCristian Dumitrescu 				table_name,
9205074e1d5SCristian Dumitrescu 				line);
9215074e1d5SCristian Dumitrescu 			if (!entry) {
9225074e1d5SCristian Dumitrescu 				snprintf(out, out_size, MSG_FILE_ERR,
9235074e1d5SCristian Dumitrescu 					file_name_delete, line_id);
9245074e1d5SCristian Dumitrescu 				goto error;
9255074e1d5SCristian Dumitrescu 			}
9265074e1d5SCristian Dumitrescu 
9275074e1d5SCristian Dumitrescu 			status = rte_swx_ctl_pipeline_table_entry_delete(p->ctl,
9285074e1d5SCristian Dumitrescu 				table_name,
9295074e1d5SCristian Dumitrescu 				entry);
930275ebefeSCristian Dumitrescu 			table_entry_free(entry);
9315074e1d5SCristian Dumitrescu 			if (status)  {
9325074e1d5SCristian Dumitrescu 				snprintf(out, out_size,
9335074e1d5SCristian Dumitrescu 					"Invalid entry in file %s at line %u",
9345074e1d5SCristian Dumitrescu 					file_name_delete, line_id);
9355074e1d5SCristian Dumitrescu 				goto error;
9365074e1d5SCristian Dumitrescu 			}
9375074e1d5SCristian Dumitrescu 		}
9385074e1d5SCristian Dumitrescu 
9395074e1d5SCristian Dumitrescu 	/* Default. */
94003665a48SCristian Dumitrescu 	if (file_default)
9415074e1d5SCristian Dumitrescu 		for (line_id = 1; ; line_id++) {
9425074e1d5SCristian Dumitrescu 			struct rte_swx_table_entry *entry;
9435074e1d5SCristian Dumitrescu 
9445074e1d5SCristian Dumitrescu 			if (fgets(line, 2048, file_default) == NULL)
9455074e1d5SCristian Dumitrescu 				break;
9465074e1d5SCristian Dumitrescu 
9475074e1d5SCristian Dumitrescu 			entry = rte_swx_ctl_pipeline_table_entry_read(p->ctl,
9485074e1d5SCristian Dumitrescu 				table_name,
9495074e1d5SCristian Dumitrescu 				line);
9505074e1d5SCristian Dumitrescu 			if (!entry) {
9515074e1d5SCristian Dumitrescu 				snprintf(out, out_size, MSG_FILE_ERR,
9525074e1d5SCristian Dumitrescu 					file_name_default, line_id);
9535074e1d5SCristian Dumitrescu 				goto error;
9545074e1d5SCristian Dumitrescu 			}
9555074e1d5SCristian Dumitrescu 
9565074e1d5SCristian Dumitrescu 			status = rte_swx_ctl_pipeline_table_default_entry_add(p->ctl,
9575074e1d5SCristian Dumitrescu 				table_name,
9585074e1d5SCristian Dumitrescu 				entry);
959275ebefeSCristian Dumitrescu 			table_entry_free(entry);
9605074e1d5SCristian Dumitrescu 			if (status) {
9615074e1d5SCristian Dumitrescu 				snprintf(out, out_size,
9625074e1d5SCristian Dumitrescu 					"Invalid entry in file %s at line %u",
9635074e1d5SCristian Dumitrescu 					file_name_default, line_id);
9645074e1d5SCristian Dumitrescu 				goto error;
9655074e1d5SCristian Dumitrescu 			}
9665074e1d5SCristian Dumitrescu 		}
9675074e1d5SCristian Dumitrescu 
9685074e1d5SCristian Dumitrescu 	status = rte_swx_ctl_pipeline_commit(p->ctl, 1);
9695074e1d5SCristian Dumitrescu 	if (status) {
9705074e1d5SCristian Dumitrescu 		snprintf(out, out_size, "Commit failed.");
9715074e1d5SCristian Dumitrescu 		goto error;
9725074e1d5SCristian Dumitrescu 	}
9735074e1d5SCristian Dumitrescu 
9745074e1d5SCristian Dumitrescu 
9755074e1d5SCristian Dumitrescu 	rte_swx_ctl_pipeline_table_fprintf(stdout, p->ctl, table_name);
9765074e1d5SCristian Dumitrescu 
97703665a48SCristian Dumitrescu 	free(line);
97803665a48SCristian Dumitrescu 	if (file_add)
97903665a48SCristian Dumitrescu 		fclose(file_add);
98003665a48SCristian Dumitrescu 	if (file_delete)
98103665a48SCristian Dumitrescu 		fclose(file_delete);
98203665a48SCristian Dumitrescu 	if (file_default)
98303665a48SCristian Dumitrescu 		fclose(file_default);
9845074e1d5SCristian Dumitrescu 	return;
9855074e1d5SCristian Dumitrescu 
9865074e1d5SCristian Dumitrescu error:
9875074e1d5SCristian Dumitrescu 	rte_swx_ctl_pipeline_abort(p->ctl);
9885074e1d5SCristian Dumitrescu 	free(line);
9895074e1d5SCristian Dumitrescu 	if (file_add)
9905074e1d5SCristian Dumitrescu 		fclose(file_add);
9915074e1d5SCristian Dumitrescu 	if (file_delete)
9925074e1d5SCristian Dumitrescu 		fclose(file_delete);
9935074e1d5SCristian Dumitrescu 	if (file_default)
9945074e1d5SCristian Dumitrescu 		fclose(file_default);
9955074e1d5SCristian Dumitrescu }
9965074e1d5SCristian Dumitrescu 
9975074e1d5SCristian Dumitrescu static const char cmd_pipeline_stats_help[] =
9985074e1d5SCristian Dumitrescu "pipeline <pipeline_name> stats\n";
9995074e1d5SCristian Dumitrescu 
10005074e1d5SCristian Dumitrescu static void
10015074e1d5SCristian Dumitrescu cmd_pipeline_stats(char **tokens,
10025074e1d5SCristian Dumitrescu 	uint32_t n_tokens,
10035074e1d5SCristian Dumitrescu 	char *out,
10045074e1d5SCristian Dumitrescu 	size_t out_size,
10055074e1d5SCristian Dumitrescu 	void *obj)
10065074e1d5SCristian Dumitrescu {
10075074e1d5SCristian Dumitrescu 	struct rte_swx_ctl_pipeline_info info;
10085074e1d5SCristian Dumitrescu 	struct pipeline *p;
10095074e1d5SCristian Dumitrescu 	uint32_t i;
10105074e1d5SCristian Dumitrescu 	int status;
10115074e1d5SCristian Dumitrescu 
10125074e1d5SCristian Dumitrescu 	if (n_tokens != 3) {
10135074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
10145074e1d5SCristian Dumitrescu 		return;
10155074e1d5SCristian Dumitrescu 	}
10165074e1d5SCristian Dumitrescu 
10175074e1d5SCristian Dumitrescu 	p = pipeline_find(obj, tokens[1]);
10185074e1d5SCristian Dumitrescu 	if (!p || !p->ctl) {
10195074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
10205074e1d5SCristian Dumitrescu 		return;
10215074e1d5SCristian Dumitrescu 	}
10225074e1d5SCristian Dumitrescu 
10235074e1d5SCristian Dumitrescu 	if (strcmp(tokens[2], "stats")) {
10245074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "stats");
10255074e1d5SCristian Dumitrescu 		return;
10265074e1d5SCristian Dumitrescu 	}
10275074e1d5SCristian Dumitrescu 
10285074e1d5SCristian Dumitrescu 	status = rte_swx_ctl_pipeline_info_get(p->p, &info);
10295074e1d5SCristian Dumitrescu 	if (status) {
10305074e1d5SCristian Dumitrescu 		snprintf(out, out_size, "Pipeline info get error.");
10315074e1d5SCristian Dumitrescu 		return;
10325074e1d5SCristian Dumitrescu 	}
10335074e1d5SCristian Dumitrescu 
10345074e1d5SCristian Dumitrescu 	snprintf(out, out_size, "Input ports:\n");
10355074e1d5SCristian Dumitrescu 	out_size -= strlen(out);
10365074e1d5SCristian Dumitrescu 	out += strlen(out);
10375074e1d5SCristian Dumitrescu 
10385074e1d5SCristian Dumitrescu 	for (i = 0; i < info.n_ports_in; i++) {
10395074e1d5SCristian Dumitrescu 		struct rte_swx_port_in_stats stats;
10405074e1d5SCristian Dumitrescu 
10415074e1d5SCristian Dumitrescu 		rte_swx_ctl_pipeline_port_in_stats_read(p->p, i, &stats);
10425074e1d5SCristian Dumitrescu 
10435074e1d5SCristian Dumitrescu 		snprintf(out, out_size, "\tPort %u:"
10445074e1d5SCristian Dumitrescu 			" packets %" PRIu64
10455074e1d5SCristian Dumitrescu 			" bytes %" PRIu64
10465074e1d5SCristian Dumitrescu 			" empty %" PRIu64 "\n",
10475074e1d5SCristian Dumitrescu 			i, stats.n_pkts, stats.n_bytes, stats.n_empty);
10485074e1d5SCristian Dumitrescu 		out_size -= strlen(out);
10495074e1d5SCristian Dumitrescu 		out += strlen(out);
10505074e1d5SCristian Dumitrescu 	}
10515074e1d5SCristian Dumitrescu 
10525074e1d5SCristian Dumitrescu 	snprintf(out, out_size, "Output ports:\n");
10535074e1d5SCristian Dumitrescu 	out_size -= strlen(out);
10545074e1d5SCristian Dumitrescu 	out += strlen(out);
10555074e1d5SCristian Dumitrescu 
10565074e1d5SCristian Dumitrescu 	for (i = 0; i < info.n_ports_out; i++) {
10575074e1d5SCristian Dumitrescu 		struct rte_swx_port_out_stats stats;
10585074e1d5SCristian Dumitrescu 
10595074e1d5SCristian Dumitrescu 		rte_swx_ctl_pipeline_port_out_stats_read(p->p, i, &stats);
10605074e1d5SCristian Dumitrescu 
10615074e1d5SCristian Dumitrescu 		snprintf(out, out_size, "\tPort %u:"
10625074e1d5SCristian Dumitrescu 			" packets %" PRIu64
10635074e1d5SCristian Dumitrescu 			" bytes %" PRIu64 "\n",
10645074e1d5SCristian Dumitrescu 			i, stats.n_pkts, stats.n_bytes);
10655074e1d5SCristian Dumitrescu 		out_size -= strlen(out);
10665074e1d5SCristian Dumitrescu 		out += strlen(out);
10675074e1d5SCristian Dumitrescu 	}
10685074e1d5SCristian Dumitrescu }
10695074e1d5SCristian Dumitrescu 
10705074e1d5SCristian Dumitrescu static const char cmd_thread_pipeline_enable_help[] =
10715074e1d5SCristian Dumitrescu "thread <thread_id> pipeline <pipeline_name> enable\n";
10725074e1d5SCristian Dumitrescu 
10735074e1d5SCristian Dumitrescu static void
10745074e1d5SCristian Dumitrescu cmd_thread_pipeline_enable(char **tokens,
10755074e1d5SCristian Dumitrescu 	uint32_t n_tokens,
10765074e1d5SCristian Dumitrescu 	char *out,
10775074e1d5SCristian Dumitrescu 	size_t out_size,
10785074e1d5SCristian Dumitrescu 	void *obj)
10795074e1d5SCristian Dumitrescu {
10805074e1d5SCristian Dumitrescu 	char *pipeline_name;
10815074e1d5SCristian Dumitrescu 	struct pipeline *p;
10825074e1d5SCristian Dumitrescu 	uint32_t thread_id;
10835074e1d5SCristian Dumitrescu 	int status;
10845074e1d5SCristian Dumitrescu 
10855074e1d5SCristian Dumitrescu 	if (n_tokens != 5) {
10865074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
10875074e1d5SCristian Dumitrescu 		return;
10885074e1d5SCristian Dumitrescu 	}
10895074e1d5SCristian Dumitrescu 
10905074e1d5SCristian Dumitrescu 	if (parser_read_uint32(&thread_id, tokens[1]) != 0) {
10915074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "thread_id");
10925074e1d5SCristian Dumitrescu 		return;
10935074e1d5SCristian Dumitrescu 	}
10945074e1d5SCristian Dumitrescu 
10955074e1d5SCristian Dumitrescu 	if (strcmp(tokens[2], "pipeline") != 0) {
10965074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pipeline");
10975074e1d5SCristian Dumitrescu 		return;
10985074e1d5SCristian Dumitrescu 	}
10995074e1d5SCristian Dumitrescu 
11005074e1d5SCristian Dumitrescu 	pipeline_name = tokens[3];
11015074e1d5SCristian Dumitrescu 	p = pipeline_find(obj, pipeline_name);
11025074e1d5SCristian Dumitrescu 	if (!p || !p->ctl) {
11035074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
11045074e1d5SCristian Dumitrescu 		return;
11055074e1d5SCristian Dumitrescu 	}
11065074e1d5SCristian Dumitrescu 
11075074e1d5SCristian Dumitrescu 	if (strcmp(tokens[4], "enable") != 0) {
11085074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "enable");
11095074e1d5SCristian Dumitrescu 		return;
11105074e1d5SCristian Dumitrescu 	}
11115074e1d5SCristian Dumitrescu 
11125074e1d5SCristian Dumitrescu 	status = thread_pipeline_enable(thread_id, obj, pipeline_name);
11135074e1d5SCristian Dumitrescu 	if (status) {
11145074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_CMD_FAIL, "thread pipeline enable");
11155074e1d5SCristian Dumitrescu 		return;
11165074e1d5SCristian Dumitrescu 	}
11175074e1d5SCristian Dumitrescu }
11185074e1d5SCristian Dumitrescu 
11195074e1d5SCristian Dumitrescu static const char cmd_thread_pipeline_disable_help[] =
11205074e1d5SCristian Dumitrescu "thread <thread_id> pipeline <pipeline_name> disable\n";
11215074e1d5SCristian Dumitrescu 
11225074e1d5SCristian Dumitrescu static void
11235074e1d5SCristian Dumitrescu cmd_thread_pipeline_disable(char **tokens,
11245074e1d5SCristian Dumitrescu 	uint32_t n_tokens,
11255074e1d5SCristian Dumitrescu 	char *out,
11265074e1d5SCristian Dumitrescu 	size_t out_size,
11275074e1d5SCristian Dumitrescu 	void *obj)
11285074e1d5SCristian Dumitrescu {
11295074e1d5SCristian Dumitrescu 	struct pipeline *p;
11305074e1d5SCristian Dumitrescu 	char *pipeline_name;
11315074e1d5SCristian Dumitrescu 	uint32_t thread_id;
11325074e1d5SCristian Dumitrescu 	int status;
11335074e1d5SCristian Dumitrescu 
11345074e1d5SCristian Dumitrescu 	if (n_tokens != 5) {
11355074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
11365074e1d5SCristian Dumitrescu 		return;
11375074e1d5SCristian Dumitrescu 	}
11385074e1d5SCristian Dumitrescu 
11395074e1d5SCristian Dumitrescu 	if (parser_read_uint32(&thread_id, tokens[1]) != 0) {
11405074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "thread_id");
11415074e1d5SCristian Dumitrescu 		return;
11425074e1d5SCristian Dumitrescu 	}
11435074e1d5SCristian Dumitrescu 
11445074e1d5SCristian Dumitrescu 	if (strcmp(tokens[2], "pipeline") != 0) {
11455074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pipeline");
11465074e1d5SCristian Dumitrescu 		return;
11475074e1d5SCristian Dumitrescu 	}
11485074e1d5SCristian Dumitrescu 
11495074e1d5SCristian Dumitrescu 	pipeline_name = tokens[3];
11505074e1d5SCristian Dumitrescu 	p = pipeline_find(obj, pipeline_name);
11515074e1d5SCristian Dumitrescu 	if (!p || !p->ctl) {
11525074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
11535074e1d5SCristian Dumitrescu 		return;
11545074e1d5SCristian Dumitrescu 	}
11555074e1d5SCristian Dumitrescu 
11565074e1d5SCristian Dumitrescu 	if (strcmp(tokens[4], "disable") != 0) {
11575074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "disable");
11585074e1d5SCristian Dumitrescu 		return;
11595074e1d5SCristian Dumitrescu 	}
11605074e1d5SCristian Dumitrescu 
11615074e1d5SCristian Dumitrescu 	status = thread_pipeline_disable(thread_id, obj, pipeline_name);
11625074e1d5SCristian Dumitrescu 	if (status) {
11635074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_CMD_FAIL,
11645074e1d5SCristian Dumitrescu 			"thread pipeline disable");
11655074e1d5SCristian Dumitrescu 		return;
11665074e1d5SCristian Dumitrescu 	}
11675074e1d5SCristian Dumitrescu }
11685074e1d5SCristian Dumitrescu 
11695074e1d5SCristian Dumitrescu static void
11705074e1d5SCristian Dumitrescu cmd_help(char **tokens,
11715074e1d5SCristian Dumitrescu 	 uint32_t n_tokens,
11725074e1d5SCristian Dumitrescu 	 char *out,
11735074e1d5SCristian Dumitrescu 	 size_t out_size,
11745074e1d5SCristian Dumitrescu 	 void *arg __rte_unused)
11755074e1d5SCristian Dumitrescu {
11765074e1d5SCristian Dumitrescu 	tokens++;
11775074e1d5SCristian Dumitrescu 	n_tokens--;
11785074e1d5SCristian Dumitrescu 
11795074e1d5SCristian Dumitrescu 	if (n_tokens == 0) {
11805074e1d5SCristian Dumitrescu 		snprintf(out, out_size,
11817fef9ef1SYogesh Jangra 			"Type 'help <command>' for command details.\n\n"
11827fef9ef1SYogesh Jangra 			"List of commands:\n"
11837fef9ef1SYogesh Jangra 			"\tmempool\n"
11847fef9ef1SYogesh Jangra 			"\tlink\n"
11857fef9ef1SYogesh Jangra 			"\tpipeline create\n"
11867fef9ef1SYogesh Jangra 			"\tpipeline port in\n"
11877fef9ef1SYogesh Jangra 			"\tpipeline port out\n"
11887fef9ef1SYogesh Jangra 			"\tpipeline build\n"
11897fef9ef1SYogesh Jangra 			"\tpipeline table update\n"
11907fef9ef1SYogesh Jangra 			"\tpipeline stats\n"
11917fef9ef1SYogesh Jangra 			"\tthread pipeline enable\n"
11927fef9ef1SYogesh Jangra 			"\tthread pipeline disable\n\n");
11935074e1d5SCristian Dumitrescu 		return;
11945074e1d5SCristian Dumitrescu 	}
11955074e1d5SCristian Dumitrescu 
11965074e1d5SCristian Dumitrescu 	if (strcmp(tokens[0], "mempool") == 0) {
11975074e1d5SCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n", cmd_mempool_help);
11985074e1d5SCristian Dumitrescu 		return;
11995074e1d5SCristian Dumitrescu 	}
12005074e1d5SCristian Dumitrescu 
12015074e1d5SCristian Dumitrescu 	if (strcmp(tokens[0], "link") == 0) {
12025074e1d5SCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n", cmd_link_help);
12035074e1d5SCristian Dumitrescu 		return;
12045074e1d5SCristian Dumitrescu 	}
12055074e1d5SCristian Dumitrescu 
12065074e1d5SCristian Dumitrescu 	if ((strcmp(tokens[0], "pipeline") == 0) &&
12077fef9ef1SYogesh Jangra 		(n_tokens == 2) && (strcmp(tokens[1], "create") == 0)) {
12085074e1d5SCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n", cmd_pipeline_create_help);
12095074e1d5SCristian Dumitrescu 		return;
12105074e1d5SCristian Dumitrescu 	}
12115074e1d5SCristian Dumitrescu 
12125074e1d5SCristian Dumitrescu 	if ((strcmp(tokens[0], "pipeline") == 0) &&
12137fef9ef1SYogesh Jangra 		(n_tokens == 3) && (strcmp(tokens[1], "port") == 0)) {
12147fef9ef1SYogesh Jangra 		if (strcmp(tokens[2], "in") == 0) {
12155074e1d5SCristian Dumitrescu 			snprintf(out, out_size, "\n%s\n",
12165074e1d5SCristian Dumitrescu 				cmd_pipeline_port_in_help);
12175074e1d5SCristian Dumitrescu 			return;
12185074e1d5SCristian Dumitrescu 		}
12195074e1d5SCristian Dumitrescu 
12207fef9ef1SYogesh Jangra 		if (strcmp(tokens[2], "out") == 0) {
12215074e1d5SCristian Dumitrescu 			snprintf(out, out_size, "\n%s\n",
12225074e1d5SCristian Dumitrescu 				cmd_pipeline_port_out_help);
12235074e1d5SCristian Dumitrescu 			return;
12245074e1d5SCristian Dumitrescu 		}
12255074e1d5SCristian Dumitrescu 	}
12265074e1d5SCristian Dumitrescu 
12275074e1d5SCristian Dumitrescu 	if ((strcmp(tokens[0], "pipeline") == 0) &&
12287fef9ef1SYogesh Jangra 		(n_tokens == 2) && (strcmp(tokens[1], "build") == 0)) {
12295074e1d5SCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n", cmd_pipeline_build_help);
12305074e1d5SCristian Dumitrescu 		return;
12315074e1d5SCristian Dumitrescu 	}
12325074e1d5SCristian Dumitrescu 
12335074e1d5SCristian Dumitrescu 	if ((strcmp(tokens[0], "pipeline") == 0) &&
12347fef9ef1SYogesh Jangra 		(n_tokens == 3) &&
12357fef9ef1SYogesh Jangra 		(strcmp(tokens[1], "table") == 0) &&
12367fef9ef1SYogesh Jangra 		(strcmp(tokens[2], "update") == 0)) {
12375074e1d5SCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n",
12385074e1d5SCristian Dumitrescu 			cmd_pipeline_table_update_help);
12395074e1d5SCristian Dumitrescu 		return;
12405074e1d5SCristian Dumitrescu 	}
12415074e1d5SCristian Dumitrescu 
12425074e1d5SCristian Dumitrescu 	if ((strcmp(tokens[0], "pipeline") == 0) &&
12437fef9ef1SYogesh Jangra 		(n_tokens == 2) && (strcmp(tokens[1], "stats") == 0)) {
12445074e1d5SCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n", cmd_pipeline_stats_help);
12455074e1d5SCristian Dumitrescu 		return;
12465074e1d5SCristian Dumitrescu 	}
12475074e1d5SCristian Dumitrescu 
12485074e1d5SCristian Dumitrescu 	if ((n_tokens == 3) &&
12495074e1d5SCristian Dumitrescu 		(strcmp(tokens[0], "thread") == 0) &&
12505074e1d5SCristian Dumitrescu 		(strcmp(tokens[1], "pipeline") == 0)) {
12515074e1d5SCristian Dumitrescu 		if (strcmp(tokens[2], "enable") == 0) {
12525074e1d5SCristian Dumitrescu 			snprintf(out, out_size, "\n%s\n",
12535074e1d5SCristian Dumitrescu 				cmd_thread_pipeline_enable_help);
12545074e1d5SCristian Dumitrescu 			return;
12555074e1d5SCristian Dumitrescu 		}
12565074e1d5SCristian Dumitrescu 
12575074e1d5SCristian Dumitrescu 		if (strcmp(tokens[2], "disable") == 0) {
12585074e1d5SCristian Dumitrescu 			snprintf(out, out_size, "\n%s\n",
12595074e1d5SCristian Dumitrescu 				cmd_thread_pipeline_disable_help);
12605074e1d5SCristian Dumitrescu 			return;
12615074e1d5SCristian Dumitrescu 		}
12625074e1d5SCristian Dumitrescu 	}
12635074e1d5SCristian Dumitrescu 
12645074e1d5SCristian Dumitrescu 	snprintf(out, out_size, "Invalid command\n");
12655074e1d5SCristian Dumitrescu }
12665074e1d5SCristian Dumitrescu 
12675074e1d5SCristian Dumitrescu void
12685074e1d5SCristian Dumitrescu cli_process(char *in, char *out, size_t out_size, void *obj)
12695074e1d5SCristian Dumitrescu {
12705074e1d5SCristian Dumitrescu 	char *tokens[CMD_MAX_TOKENS];
12715074e1d5SCristian Dumitrescu 	uint32_t n_tokens = RTE_DIM(tokens);
12725074e1d5SCristian Dumitrescu 	int status;
12735074e1d5SCristian Dumitrescu 
12745074e1d5SCristian Dumitrescu 	if (is_comment(in))
12755074e1d5SCristian Dumitrescu 		return;
12765074e1d5SCristian Dumitrescu 
12775074e1d5SCristian Dumitrescu 	status = parse_tokenize_string(in, tokens, &n_tokens);
12785074e1d5SCristian Dumitrescu 	if (status) {
12795074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_TOO_MANY, "");
12805074e1d5SCristian Dumitrescu 		return;
12815074e1d5SCristian Dumitrescu 	}
12825074e1d5SCristian Dumitrescu 
12835074e1d5SCristian Dumitrescu 	if (n_tokens == 0)
12845074e1d5SCristian Dumitrescu 		return;
12855074e1d5SCristian Dumitrescu 
12865074e1d5SCristian Dumitrescu 	if (strcmp(tokens[0], "help") == 0) {
12875074e1d5SCristian Dumitrescu 		cmd_help(tokens, n_tokens, out, out_size, obj);
12885074e1d5SCristian Dumitrescu 		return;
12895074e1d5SCristian Dumitrescu 	}
12905074e1d5SCristian Dumitrescu 
12915074e1d5SCristian Dumitrescu 	if (strcmp(tokens[0], "mempool") == 0) {
12925074e1d5SCristian Dumitrescu 		cmd_mempool(tokens, n_tokens, out, out_size, obj);
12935074e1d5SCristian Dumitrescu 		return;
12945074e1d5SCristian Dumitrescu 	}
12955074e1d5SCristian Dumitrescu 
12965074e1d5SCristian Dumitrescu 	if (strcmp(tokens[0], "link") == 0) {
1297*821848f5SCristian Dumitrescu 		if ((n_tokens >= 2) && (strcmp(tokens[1], "show") == 0)) {
12985074e1d5SCristian Dumitrescu 			cmd_link_show(tokens, n_tokens, out, out_size, obj);
12995074e1d5SCristian Dumitrescu 			return;
13005074e1d5SCristian Dumitrescu 		}
13015074e1d5SCristian Dumitrescu 
13025074e1d5SCristian Dumitrescu 		cmd_link(tokens, n_tokens, out, out_size, obj);
13035074e1d5SCristian Dumitrescu 		return;
13045074e1d5SCristian Dumitrescu 	}
13055074e1d5SCristian Dumitrescu 
13065074e1d5SCristian Dumitrescu 	if (strcmp(tokens[0], "pipeline") == 0) {
13075074e1d5SCristian Dumitrescu 		if ((n_tokens >= 3) &&
13085074e1d5SCristian Dumitrescu 			(strcmp(tokens[2], "create") == 0)) {
13095074e1d5SCristian Dumitrescu 			cmd_pipeline_create(tokens, n_tokens, out, out_size,
13105074e1d5SCristian Dumitrescu 				obj);
13115074e1d5SCristian Dumitrescu 			return;
13125074e1d5SCristian Dumitrescu 		}
13135074e1d5SCristian Dumitrescu 
13145074e1d5SCristian Dumitrescu 		if ((n_tokens >= 4) &&
13155074e1d5SCristian Dumitrescu 			(strcmp(tokens[2], "port") == 0) &&
13165074e1d5SCristian Dumitrescu 			(strcmp(tokens[3], "in") == 0)) {
13175074e1d5SCristian Dumitrescu 			cmd_pipeline_port_in(tokens, n_tokens, out, out_size,
13185074e1d5SCristian Dumitrescu 				obj);
13195074e1d5SCristian Dumitrescu 			return;
13205074e1d5SCristian Dumitrescu 		}
13215074e1d5SCristian Dumitrescu 
13225074e1d5SCristian Dumitrescu 		if ((n_tokens >= 4) &&
13235074e1d5SCristian Dumitrescu 			(strcmp(tokens[2], "port") == 0) &&
13245074e1d5SCristian Dumitrescu 			(strcmp(tokens[3], "out") == 0)) {
13255074e1d5SCristian Dumitrescu 			cmd_pipeline_port_out(tokens, n_tokens, out, out_size,
13265074e1d5SCristian Dumitrescu 				obj);
13275074e1d5SCristian Dumitrescu 			return;
13285074e1d5SCristian Dumitrescu 		}
13295074e1d5SCristian Dumitrescu 
13305074e1d5SCristian Dumitrescu 		if ((n_tokens >= 3) &&
13315074e1d5SCristian Dumitrescu 			(strcmp(tokens[2], "build") == 0)) {
13325074e1d5SCristian Dumitrescu 			cmd_pipeline_build(tokens, n_tokens, out, out_size,
13335074e1d5SCristian Dumitrescu 				obj);
13345074e1d5SCristian Dumitrescu 			return;
13355074e1d5SCristian Dumitrescu 		}
13365074e1d5SCristian Dumitrescu 
13375074e1d5SCristian Dumitrescu 		if ((n_tokens >= 3) &&
13385074e1d5SCristian Dumitrescu 			(strcmp(tokens[2], "table") == 0)) {
13395074e1d5SCristian Dumitrescu 			cmd_pipeline_table_update(tokens, n_tokens, out,
13405074e1d5SCristian Dumitrescu 				out_size, obj);
13415074e1d5SCristian Dumitrescu 			return;
13425074e1d5SCristian Dumitrescu 		}
13435074e1d5SCristian Dumitrescu 
13445074e1d5SCristian Dumitrescu 		if ((n_tokens >= 3) &&
13455074e1d5SCristian Dumitrescu 			(strcmp(tokens[2], "stats") == 0)) {
13465074e1d5SCristian Dumitrescu 			cmd_pipeline_stats(tokens, n_tokens, out, out_size,
13475074e1d5SCristian Dumitrescu 				obj);
13485074e1d5SCristian Dumitrescu 			return;
13495074e1d5SCristian Dumitrescu 		}
13505074e1d5SCristian Dumitrescu 	}
13515074e1d5SCristian Dumitrescu 
13525074e1d5SCristian Dumitrescu 	if (strcmp(tokens[0], "thread") == 0) {
13535074e1d5SCristian Dumitrescu 		if ((n_tokens >= 5) &&
13545074e1d5SCristian Dumitrescu 			(strcmp(tokens[4], "enable") == 0)) {
13555074e1d5SCristian Dumitrescu 			cmd_thread_pipeline_enable(tokens, n_tokens,
13565074e1d5SCristian Dumitrescu 				out, out_size, obj);
13575074e1d5SCristian Dumitrescu 			return;
13585074e1d5SCristian Dumitrescu 		}
13595074e1d5SCristian Dumitrescu 
13605074e1d5SCristian Dumitrescu 		if ((n_tokens >= 5) &&
13615074e1d5SCristian Dumitrescu 			(strcmp(tokens[4], "disable") == 0)) {
13625074e1d5SCristian Dumitrescu 			cmd_thread_pipeline_disable(tokens, n_tokens,
13635074e1d5SCristian Dumitrescu 				out, out_size, obj);
13645074e1d5SCristian Dumitrescu 			return;
13655074e1d5SCristian Dumitrescu 		}
13665074e1d5SCristian Dumitrescu 	}
13675074e1d5SCristian Dumitrescu 
13685074e1d5SCristian Dumitrescu 	snprintf(out, out_size, MSG_CMD_UNKNOWN, tokens[0]);
13695074e1d5SCristian Dumitrescu }
13705074e1d5SCristian Dumitrescu 
13715074e1d5SCristian Dumitrescu int
13725074e1d5SCristian Dumitrescu cli_script_process(const char *file_name,
13735074e1d5SCristian Dumitrescu 	size_t msg_in_len_max,
13745074e1d5SCristian Dumitrescu 	size_t msg_out_len_max,
13755074e1d5SCristian Dumitrescu 	void *obj)
13765074e1d5SCristian Dumitrescu {
13775074e1d5SCristian Dumitrescu 	char *msg_in = NULL, *msg_out = NULL;
13785074e1d5SCristian Dumitrescu 	FILE *f = NULL;
13795074e1d5SCristian Dumitrescu 
13805074e1d5SCristian Dumitrescu 	/* Check input arguments */
13815074e1d5SCristian Dumitrescu 	if ((file_name == NULL) ||
13825074e1d5SCristian Dumitrescu 		(strlen(file_name) == 0) ||
13835074e1d5SCristian Dumitrescu 		(msg_in_len_max == 0) ||
13845074e1d5SCristian Dumitrescu 		(msg_out_len_max == 0))
13855074e1d5SCristian Dumitrescu 		return -EINVAL;
13865074e1d5SCristian Dumitrescu 
13875074e1d5SCristian Dumitrescu 	msg_in = malloc(msg_in_len_max + 1);
13885074e1d5SCristian Dumitrescu 	msg_out = malloc(msg_out_len_max + 1);
13895074e1d5SCristian Dumitrescu 	if ((msg_in == NULL) ||
13905074e1d5SCristian Dumitrescu 		(msg_out == NULL)) {
13915074e1d5SCristian Dumitrescu 		free(msg_out);
13925074e1d5SCristian Dumitrescu 		free(msg_in);
13935074e1d5SCristian Dumitrescu 		return -ENOMEM;
13945074e1d5SCristian Dumitrescu 	}
13955074e1d5SCristian Dumitrescu 
13965074e1d5SCristian Dumitrescu 	/* Open input file */
13975074e1d5SCristian Dumitrescu 	f = fopen(file_name, "r");
13985074e1d5SCristian Dumitrescu 	if (f == NULL) {
13995074e1d5SCristian Dumitrescu 		free(msg_out);
14005074e1d5SCristian Dumitrescu 		free(msg_in);
14015074e1d5SCristian Dumitrescu 		return -EIO;
14025074e1d5SCristian Dumitrescu 	}
14035074e1d5SCristian Dumitrescu 
14045074e1d5SCristian Dumitrescu 	/* Read file */
14055074e1d5SCristian Dumitrescu 	for ( ; ; ) {
14065074e1d5SCristian Dumitrescu 		if (fgets(msg_in, msg_in_len_max + 1, f) == NULL)
14075074e1d5SCristian Dumitrescu 			break;
14085074e1d5SCristian Dumitrescu 
14095074e1d5SCristian Dumitrescu 		printf("%s", msg_in);
14105074e1d5SCristian Dumitrescu 		msg_out[0] = 0;
14115074e1d5SCristian Dumitrescu 
14125074e1d5SCristian Dumitrescu 		cli_process(msg_in,
14135074e1d5SCristian Dumitrescu 			msg_out,
14145074e1d5SCristian Dumitrescu 			msg_out_len_max,
14155074e1d5SCristian Dumitrescu 			obj);
14165074e1d5SCristian Dumitrescu 
14175074e1d5SCristian Dumitrescu 		if (strlen(msg_out))
14185074e1d5SCristian Dumitrescu 			printf("%s", msg_out);
14195074e1d5SCristian Dumitrescu 	}
14205074e1d5SCristian Dumitrescu 
14215074e1d5SCristian Dumitrescu 	/* Close file */
14225074e1d5SCristian Dumitrescu 	fclose(f);
14235074e1d5SCristian Dumitrescu 	free(msg_out);
14245074e1d5SCristian Dumitrescu 	free(msg_in);
14255074e1d5SCristian Dumitrescu 	return 0;
14265074e1d5SCristian Dumitrescu }
1427