xref: /dpdk/examples/pipeline/cli.c (revision e2b8dc5256c0c6d567c136401de67d3249b9086b)
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>
1377a41301SCristian Dumitrescu #include <rte_swx_port_ring.h>
145074e1d5SCristian Dumitrescu #include <rte_swx_port_source_sink.h>
15*e2b8dc52SVenkata Suresh Kumar P #include <rte_swx_port_fd.h>
165074e1d5SCristian Dumitrescu #include <rte_swx_pipeline.h>
175074e1d5SCristian Dumitrescu #include <rte_swx_ctl.h>
185074e1d5SCristian Dumitrescu 
195074e1d5SCristian Dumitrescu #include "cli.h"
205074e1d5SCristian Dumitrescu 
215074e1d5SCristian Dumitrescu #include "obj.h"
225074e1d5SCristian Dumitrescu #include "thread.h"
235074e1d5SCristian Dumitrescu 
245074e1d5SCristian Dumitrescu #ifndef CMD_MAX_TOKENS
255074e1d5SCristian Dumitrescu #define CMD_MAX_TOKENS     256
265074e1d5SCristian Dumitrescu #endif
275074e1d5SCristian Dumitrescu 
285074e1d5SCristian Dumitrescu #define MSG_OUT_OF_MEMORY   "Not enough memory.\n"
295074e1d5SCristian Dumitrescu #define MSG_CMD_UNKNOWN     "Unknown command \"%s\".\n"
305074e1d5SCristian Dumitrescu #define MSG_CMD_UNIMPLEM    "Command \"%s\" not implemented.\n"
315074e1d5SCristian Dumitrescu #define MSG_ARG_NOT_ENOUGH  "Not enough arguments for command \"%s\".\n"
325074e1d5SCristian Dumitrescu #define MSG_ARG_TOO_MANY    "Too many arguments for command \"%s\".\n"
335074e1d5SCristian Dumitrescu #define MSG_ARG_MISMATCH    "Wrong number of arguments for command \"%s\".\n"
345074e1d5SCristian Dumitrescu #define MSG_ARG_NOT_FOUND   "Argument \"%s\" not found.\n"
355074e1d5SCristian Dumitrescu #define MSG_ARG_INVALID     "Invalid value for argument \"%s\".\n"
365074e1d5SCristian Dumitrescu #define MSG_FILE_ERR        "Error in file \"%s\" at line %u.\n"
375074e1d5SCristian Dumitrescu #define MSG_FILE_NOT_ENOUGH "Not enough rules in file \"%s\".\n"
385074e1d5SCristian Dumitrescu #define MSG_CMD_FAIL        "Command \"%s\" failed.\n"
395074e1d5SCristian Dumitrescu 
405074e1d5SCristian Dumitrescu #define skip_white_spaces(pos)			\
415074e1d5SCristian Dumitrescu ({						\
425074e1d5SCristian Dumitrescu 	__typeof__(pos) _p = (pos);		\
435074e1d5SCristian Dumitrescu 	for ( ; isspace(*_p); _p++)		\
445074e1d5SCristian Dumitrescu 		;				\
455074e1d5SCristian Dumitrescu 	_p;					\
465074e1d5SCristian Dumitrescu })
475074e1d5SCristian Dumitrescu 
485074e1d5SCristian Dumitrescu static int
495074e1d5SCristian Dumitrescu parser_read_uint64(uint64_t *value, const char *p)
505074e1d5SCristian Dumitrescu {
515074e1d5SCristian Dumitrescu 	char *next;
525074e1d5SCristian Dumitrescu 	uint64_t val;
535074e1d5SCristian Dumitrescu 
545074e1d5SCristian Dumitrescu 	p = skip_white_spaces(p);
555074e1d5SCristian Dumitrescu 	if (!isdigit(*p))
565074e1d5SCristian Dumitrescu 		return -EINVAL;
575074e1d5SCristian Dumitrescu 
585074e1d5SCristian Dumitrescu 	val = strtoul(p, &next, 10);
595074e1d5SCristian Dumitrescu 	if (p == next)
605074e1d5SCristian Dumitrescu 		return -EINVAL;
615074e1d5SCristian Dumitrescu 
625074e1d5SCristian Dumitrescu 	p = next;
635074e1d5SCristian Dumitrescu 	switch (*p) {
645074e1d5SCristian Dumitrescu 	case 'T':
655074e1d5SCristian Dumitrescu 		val *= 1024ULL;
665074e1d5SCristian Dumitrescu 		/* fall through */
675074e1d5SCristian Dumitrescu 	case 'G':
685074e1d5SCristian Dumitrescu 		val *= 1024ULL;
695074e1d5SCristian Dumitrescu 		/* fall through */
705074e1d5SCristian Dumitrescu 	case 'M':
715074e1d5SCristian Dumitrescu 		val *= 1024ULL;
725074e1d5SCristian Dumitrescu 		/* fall through */
735074e1d5SCristian Dumitrescu 	case 'k':
745074e1d5SCristian Dumitrescu 	case 'K':
755074e1d5SCristian Dumitrescu 		val *= 1024ULL;
765074e1d5SCristian Dumitrescu 		p++;
775074e1d5SCristian Dumitrescu 		break;
785074e1d5SCristian Dumitrescu 	}
795074e1d5SCristian Dumitrescu 
805074e1d5SCristian Dumitrescu 	p = skip_white_spaces(p);
815074e1d5SCristian Dumitrescu 	if (*p != '\0')
825074e1d5SCristian Dumitrescu 		return -EINVAL;
835074e1d5SCristian Dumitrescu 
845074e1d5SCristian Dumitrescu 	*value = val;
855074e1d5SCristian Dumitrescu 	return 0;
865074e1d5SCristian Dumitrescu }
875074e1d5SCristian Dumitrescu 
885074e1d5SCristian Dumitrescu static int
895074e1d5SCristian Dumitrescu parser_read_uint32(uint32_t *value, const char *p)
905074e1d5SCristian Dumitrescu {
915074e1d5SCristian Dumitrescu 	uint64_t val = 0;
925074e1d5SCristian Dumitrescu 	int ret = parser_read_uint64(&val, p);
935074e1d5SCristian Dumitrescu 
945074e1d5SCristian Dumitrescu 	if (ret < 0)
955074e1d5SCristian Dumitrescu 		return ret;
965074e1d5SCristian Dumitrescu 
975074e1d5SCristian Dumitrescu 	if (val > UINT32_MAX)
985074e1d5SCristian Dumitrescu 		return -ERANGE;
995074e1d5SCristian Dumitrescu 
1005074e1d5SCristian Dumitrescu 	*value = val;
1015074e1d5SCristian Dumitrescu 	return 0;
1025074e1d5SCristian Dumitrescu }
1035074e1d5SCristian Dumitrescu 
1045074e1d5SCristian Dumitrescu static int
1055074e1d5SCristian Dumitrescu parser_read_uint16(uint16_t *value, const char *p)
1065074e1d5SCristian Dumitrescu {
1075074e1d5SCristian Dumitrescu 	uint64_t val = 0;
1085074e1d5SCristian Dumitrescu 	int ret = parser_read_uint64(&val, p);
1095074e1d5SCristian Dumitrescu 
1105074e1d5SCristian Dumitrescu 	if (ret < 0)
1115074e1d5SCristian Dumitrescu 		return ret;
1125074e1d5SCristian Dumitrescu 
1135074e1d5SCristian Dumitrescu 	if (val > UINT16_MAX)
1145074e1d5SCristian Dumitrescu 		return -ERANGE;
1155074e1d5SCristian Dumitrescu 
1165074e1d5SCristian Dumitrescu 	*value = val;
1175074e1d5SCristian Dumitrescu 	return 0;
1185074e1d5SCristian Dumitrescu }
1195074e1d5SCristian Dumitrescu 
1205074e1d5SCristian Dumitrescu #define PARSE_DELIMITER " \f\n\r\t\v"
1215074e1d5SCristian Dumitrescu 
1225074e1d5SCristian Dumitrescu static int
1235074e1d5SCristian Dumitrescu parse_tokenize_string(char *string, char *tokens[], uint32_t *n_tokens)
1245074e1d5SCristian Dumitrescu {
1255074e1d5SCristian Dumitrescu 	uint32_t i;
1265074e1d5SCristian Dumitrescu 
1275074e1d5SCristian Dumitrescu 	if ((string == NULL) ||
1285074e1d5SCristian Dumitrescu 		(tokens == NULL) ||
1295074e1d5SCristian Dumitrescu 		(*n_tokens < 1))
1305074e1d5SCristian Dumitrescu 		return -EINVAL;
1315074e1d5SCristian Dumitrescu 
1325074e1d5SCristian Dumitrescu 	for (i = 0; i < *n_tokens; i++) {
1335074e1d5SCristian Dumitrescu 		tokens[i] = strtok_r(string, PARSE_DELIMITER, &string);
1345074e1d5SCristian Dumitrescu 		if (tokens[i] == NULL)
1355074e1d5SCristian Dumitrescu 			break;
1365074e1d5SCristian Dumitrescu 	}
1375074e1d5SCristian Dumitrescu 
1385074e1d5SCristian Dumitrescu 	if ((i == *n_tokens) && strtok_r(string, PARSE_DELIMITER, &string))
1395074e1d5SCristian Dumitrescu 		return -E2BIG;
1405074e1d5SCristian Dumitrescu 
1415074e1d5SCristian Dumitrescu 	*n_tokens = i;
1425074e1d5SCristian Dumitrescu 	return 0;
1435074e1d5SCristian Dumitrescu }
1445074e1d5SCristian Dumitrescu 
1455074e1d5SCristian Dumitrescu static int
1465074e1d5SCristian Dumitrescu is_comment(char *in)
1475074e1d5SCristian Dumitrescu {
1485074e1d5SCristian Dumitrescu 	if ((strlen(in) && index("!#%;", in[0])) ||
1495074e1d5SCristian Dumitrescu 		(strncmp(in, "//", 2) == 0) ||
1505074e1d5SCristian Dumitrescu 		(strncmp(in, "--", 2) == 0))
1515074e1d5SCristian Dumitrescu 		return 1;
1525074e1d5SCristian Dumitrescu 
1535074e1d5SCristian Dumitrescu 	return 0;
1545074e1d5SCristian Dumitrescu }
1555074e1d5SCristian Dumitrescu 
1565074e1d5SCristian Dumitrescu static const char cmd_mempool_help[] =
1575074e1d5SCristian Dumitrescu "mempool <mempool_name>\n"
1585074e1d5SCristian Dumitrescu "   buffer <buffer_size>\n"
1595074e1d5SCristian Dumitrescu "   pool <pool_size>\n"
1605074e1d5SCristian Dumitrescu "   cache <cache_size>\n"
1615074e1d5SCristian Dumitrescu "   cpu <cpu_id>\n";
1625074e1d5SCristian Dumitrescu 
1635074e1d5SCristian Dumitrescu static void
1645074e1d5SCristian Dumitrescu cmd_mempool(char **tokens,
1655074e1d5SCristian Dumitrescu 	uint32_t n_tokens,
1665074e1d5SCristian Dumitrescu 	char *out,
1675074e1d5SCristian Dumitrescu 	size_t out_size,
1685074e1d5SCristian Dumitrescu 	void *obj)
1695074e1d5SCristian Dumitrescu {
1705074e1d5SCristian Dumitrescu 	struct mempool_params p;
1715074e1d5SCristian Dumitrescu 	char *name;
1725074e1d5SCristian Dumitrescu 	struct mempool *mempool;
1735074e1d5SCristian Dumitrescu 
1745074e1d5SCristian Dumitrescu 	if (n_tokens != 10) {
1755074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1765074e1d5SCristian Dumitrescu 		return;
1775074e1d5SCristian Dumitrescu 	}
1785074e1d5SCristian Dumitrescu 
1795074e1d5SCristian Dumitrescu 	name = tokens[1];
1805074e1d5SCristian Dumitrescu 
1815074e1d5SCristian Dumitrescu 	if (strcmp(tokens[2], "buffer") != 0) {
1825074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "buffer");
1835074e1d5SCristian Dumitrescu 		return;
1845074e1d5SCristian Dumitrescu 	}
1855074e1d5SCristian Dumitrescu 
1865074e1d5SCristian Dumitrescu 	if (parser_read_uint32(&p.buffer_size, tokens[3]) != 0) {
1875074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "buffer_size");
1885074e1d5SCristian Dumitrescu 		return;
1895074e1d5SCristian Dumitrescu 	}
1905074e1d5SCristian Dumitrescu 
1915074e1d5SCristian Dumitrescu 	if (strcmp(tokens[4], "pool") != 0) {
1925074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pool");
1935074e1d5SCristian Dumitrescu 		return;
1945074e1d5SCristian Dumitrescu 	}
1955074e1d5SCristian Dumitrescu 
1965074e1d5SCristian Dumitrescu 	if (parser_read_uint32(&p.pool_size, tokens[5]) != 0) {
1975074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pool_size");
1985074e1d5SCristian Dumitrescu 		return;
1995074e1d5SCristian Dumitrescu 	}
2005074e1d5SCristian Dumitrescu 
2015074e1d5SCristian Dumitrescu 	if (strcmp(tokens[6], "cache") != 0) {
2025074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cache");
2035074e1d5SCristian Dumitrescu 		return;
2045074e1d5SCristian Dumitrescu 	}
2055074e1d5SCristian Dumitrescu 
2065074e1d5SCristian Dumitrescu 	if (parser_read_uint32(&p.cache_size, tokens[7]) != 0) {
2075074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "cache_size");
2085074e1d5SCristian Dumitrescu 		return;
2095074e1d5SCristian Dumitrescu 	}
2105074e1d5SCristian Dumitrescu 
2115074e1d5SCristian Dumitrescu 	if (strcmp(tokens[8], "cpu") != 0) {
2125074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cpu");
2135074e1d5SCristian Dumitrescu 		return;
2145074e1d5SCristian Dumitrescu 	}
2155074e1d5SCristian Dumitrescu 
2165074e1d5SCristian Dumitrescu 	if (parser_read_uint32(&p.cpu_id, tokens[9]) != 0) {
2175074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "cpu_id");
2185074e1d5SCristian Dumitrescu 		return;
2195074e1d5SCristian Dumitrescu 	}
2205074e1d5SCristian Dumitrescu 
2215074e1d5SCristian Dumitrescu 	mempool = mempool_create(obj, name, &p);
2225074e1d5SCristian Dumitrescu 	if (mempool == NULL) {
2235074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
2245074e1d5SCristian Dumitrescu 		return;
2255074e1d5SCristian Dumitrescu 	}
2265074e1d5SCristian Dumitrescu }
2275074e1d5SCristian Dumitrescu 
2285074e1d5SCristian Dumitrescu static const char cmd_link_help[] =
2295074e1d5SCristian Dumitrescu "link <link_name>\n"
2305074e1d5SCristian Dumitrescu "   dev <device_name> | port <port_id>\n"
2315074e1d5SCristian Dumitrescu "   rxq <n_queues> <queue_size> <mempool_name>\n"
2325074e1d5SCristian Dumitrescu "   txq <n_queues> <queue_size>\n"
2335074e1d5SCristian Dumitrescu "   promiscuous on | off\n"
2345074e1d5SCristian Dumitrescu "   [rss <qid_0> ... <qid_n>]\n";
2355074e1d5SCristian Dumitrescu 
2365074e1d5SCristian Dumitrescu static void
2375074e1d5SCristian Dumitrescu cmd_link(char **tokens,
2385074e1d5SCristian Dumitrescu 	uint32_t n_tokens,
2395074e1d5SCristian Dumitrescu 	char *out,
2405074e1d5SCristian Dumitrescu 	size_t out_size,
2415074e1d5SCristian Dumitrescu 	void *obj)
2425074e1d5SCristian Dumitrescu {
2435074e1d5SCristian Dumitrescu 	struct link_params p;
2445074e1d5SCristian Dumitrescu 	struct link_params_rss rss;
2455074e1d5SCristian Dumitrescu 	struct link *link;
2465074e1d5SCristian Dumitrescu 	char *name;
2475074e1d5SCristian Dumitrescu 
2485074e1d5SCristian Dumitrescu 	memset(&p, 0, sizeof(p));
2495074e1d5SCristian Dumitrescu 
2505074e1d5SCristian Dumitrescu 	if ((n_tokens < 13) || (n_tokens > 14 + LINK_RXQ_RSS_MAX)) {
2515074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2525074e1d5SCristian Dumitrescu 		return;
2535074e1d5SCristian Dumitrescu 	}
2545074e1d5SCristian Dumitrescu 	name = tokens[1];
2555074e1d5SCristian Dumitrescu 
2565074e1d5SCristian Dumitrescu 	if (strcmp(tokens[2], "dev") == 0)
2575074e1d5SCristian Dumitrescu 		p.dev_name = tokens[3];
2585074e1d5SCristian Dumitrescu 	else if (strcmp(tokens[2], "port") == 0) {
2595074e1d5SCristian Dumitrescu 		p.dev_name = NULL;
2605074e1d5SCristian Dumitrescu 
2615074e1d5SCristian Dumitrescu 		if (parser_read_uint16(&p.port_id, tokens[3]) != 0) {
2625074e1d5SCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
2635074e1d5SCristian Dumitrescu 			return;
2645074e1d5SCristian Dumitrescu 		}
2655074e1d5SCristian Dumitrescu 	} else {
2665074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "dev or port");
2675074e1d5SCristian Dumitrescu 		return;
2685074e1d5SCristian Dumitrescu 	}
2695074e1d5SCristian Dumitrescu 
2705074e1d5SCristian Dumitrescu 	if (strcmp(tokens[4], "rxq") != 0) {
2715074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rxq");
2725074e1d5SCristian Dumitrescu 		return;
2735074e1d5SCristian Dumitrescu 	}
2745074e1d5SCristian Dumitrescu 
2755074e1d5SCristian Dumitrescu 	if (parser_read_uint32(&p.rx.n_queues, tokens[5]) != 0) {
2765074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "n_queues");
2775074e1d5SCristian Dumitrescu 		return;
2785074e1d5SCristian Dumitrescu 	}
2795074e1d5SCristian Dumitrescu 	if (parser_read_uint32(&p.rx.queue_size, tokens[6]) != 0) {
2805074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "queue_size");
2815074e1d5SCristian Dumitrescu 		return;
2825074e1d5SCristian Dumitrescu 	}
2835074e1d5SCristian Dumitrescu 
2845074e1d5SCristian Dumitrescu 	p.rx.mempool_name = tokens[7];
2855074e1d5SCristian Dumitrescu 
2865074e1d5SCristian Dumitrescu 	if (strcmp(tokens[8], "txq") != 0) {
2875074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "txq");
2885074e1d5SCristian Dumitrescu 		return;
2895074e1d5SCristian Dumitrescu 	}
2905074e1d5SCristian Dumitrescu 
2915074e1d5SCristian Dumitrescu 	if (parser_read_uint32(&p.tx.n_queues, tokens[9]) != 0) {
2925074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "n_queues");
2935074e1d5SCristian Dumitrescu 		return;
2945074e1d5SCristian Dumitrescu 	}
2955074e1d5SCristian Dumitrescu 
2965074e1d5SCristian Dumitrescu 	if (parser_read_uint32(&p.tx.queue_size, tokens[10]) != 0) {
2975074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "queue_size");
2985074e1d5SCristian Dumitrescu 		return;
2995074e1d5SCristian Dumitrescu 	}
3005074e1d5SCristian Dumitrescu 
3015074e1d5SCristian Dumitrescu 	if (strcmp(tokens[11], "promiscuous") != 0) {
3025074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "promiscuous");
3035074e1d5SCristian Dumitrescu 		return;
3045074e1d5SCristian Dumitrescu 	}
3055074e1d5SCristian Dumitrescu 
3065074e1d5SCristian Dumitrescu 	if (strcmp(tokens[12], "on") == 0)
3075074e1d5SCristian Dumitrescu 		p.promiscuous = 1;
3085074e1d5SCristian Dumitrescu 	else if (strcmp(tokens[12], "off") == 0)
3095074e1d5SCristian Dumitrescu 		p.promiscuous = 0;
3105074e1d5SCristian Dumitrescu 	else {
3115074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "on or off");
3125074e1d5SCristian Dumitrescu 		return;
3135074e1d5SCristian Dumitrescu 	}
3145074e1d5SCristian Dumitrescu 
3155074e1d5SCristian Dumitrescu 	/* RSS */
3165074e1d5SCristian Dumitrescu 	p.rx.rss = NULL;
3175074e1d5SCristian Dumitrescu 	if (n_tokens > 13) {
3185074e1d5SCristian Dumitrescu 		uint32_t queue_id, i;
3195074e1d5SCristian Dumitrescu 
3205074e1d5SCristian Dumitrescu 		if (strcmp(tokens[13], "rss") != 0) {
3215074e1d5SCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rss");
3225074e1d5SCristian Dumitrescu 			return;
3235074e1d5SCristian Dumitrescu 		}
3245074e1d5SCristian Dumitrescu 
3255074e1d5SCristian Dumitrescu 		p.rx.rss = &rss;
3265074e1d5SCristian Dumitrescu 
3275074e1d5SCristian Dumitrescu 		rss.n_queues = 0;
3285074e1d5SCristian Dumitrescu 		for (i = 14; i < n_tokens; i++) {
3295074e1d5SCristian Dumitrescu 			if (parser_read_uint32(&queue_id, tokens[i]) != 0) {
3305074e1d5SCristian Dumitrescu 				snprintf(out, out_size, MSG_ARG_INVALID,
3315074e1d5SCristian Dumitrescu 					"queue_id");
3325074e1d5SCristian Dumitrescu 				return;
3335074e1d5SCristian Dumitrescu 			}
3345074e1d5SCristian Dumitrescu 
3355074e1d5SCristian Dumitrescu 			rss.queue_id[rss.n_queues] = queue_id;
3365074e1d5SCristian Dumitrescu 			rss.n_queues++;
3375074e1d5SCristian Dumitrescu 		}
3385074e1d5SCristian Dumitrescu 	}
3395074e1d5SCristian Dumitrescu 
3405074e1d5SCristian Dumitrescu 	link = link_create(obj, name, &p);
3415074e1d5SCristian Dumitrescu 	if (link == NULL) {
3425074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
3435074e1d5SCristian Dumitrescu 		return;
3445074e1d5SCristian Dumitrescu 	}
3455074e1d5SCristian Dumitrescu }
3465074e1d5SCristian Dumitrescu 
3475074e1d5SCristian Dumitrescu /* Print the link stats and info */
3485074e1d5SCristian Dumitrescu static void
3495074e1d5SCristian Dumitrescu print_link_info(struct link *link, char *out, size_t out_size)
3505074e1d5SCristian Dumitrescu {
3515074e1d5SCristian Dumitrescu 	struct rte_eth_stats stats;
3525074e1d5SCristian Dumitrescu 	struct rte_ether_addr mac_addr;
3535074e1d5SCristian Dumitrescu 	struct rte_eth_link eth_link;
3545074e1d5SCristian Dumitrescu 	uint16_t mtu;
3555074e1d5SCristian Dumitrescu 	int ret;
3565074e1d5SCristian Dumitrescu 
3575074e1d5SCristian Dumitrescu 	memset(&stats, 0, sizeof(stats));
3585074e1d5SCristian Dumitrescu 	rte_eth_stats_get(link->port_id, &stats);
3595074e1d5SCristian Dumitrescu 
3605074e1d5SCristian Dumitrescu 	ret = rte_eth_macaddr_get(link->port_id, &mac_addr);
3615074e1d5SCristian Dumitrescu 	if (ret != 0) {
3625074e1d5SCristian Dumitrescu 		snprintf(out, out_size, "\n%s: MAC address get failed: %s",
3635074e1d5SCristian Dumitrescu 			 link->name, rte_strerror(-ret));
3645074e1d5SCristian Dumitrescu 		return;
3655074e1d5SCristian Dumitrescu 	}
3665074e1d5SCristian Dumitrescu 
3675074e1d5SCristian Dumitrescu 	ret = rte_eth_link_get(link->port_id, &eth_link);
3685074e1d5SCristian Dumitrescu 	if (ret < 0) {
3695074e1d5SCristian Dumitrescu 		snprintf(out, out_size, "\n%s: link get failed: %s",
3705074e1d5SCristian Dumitrescu 			 link->name, rte_strerror(-ret));
3715074e1d5SCristian Dumitrescu 		return;
3725074e1d5SCristian Dumitrescu 	}
3735074e1d5SCristian Dumitrescu 
3745074e1d5SCristian Dumitrescu 	rte_eth_dev_get_mtu(link->port_id, &mtu);
3755074e1d5SCristian Dumitrescu 
3765074e1d5SCristian Dumitrescu 	snprintf(out, out_size,
3775074e1d5SCristian Dumitrescu 		"\n"
3785074e1d5SCristian Dumitrescu 		"%s: flags=<%s> mtu %u\n"
3795074e1d5SCristian Dumitrescu 		"\tether %02X:%02X:%02X:%02X:%02X:%02X rxqueues %u txqueues %u\n"
3805074e1d5SCristian Dumitrescu 		"\tport# %u  speed %s\n"
3815074e1d5SCristian Dumitrescu 		"\tRX packets %" PRIu64"  bytes %" PRIu64"\n"
3825074e1d5SCristian Dumitrescu 		"\tRX errors %" PRIu64"  missed %" PRIu64"  no-mbuf %" PRIu64"\n"
3835074e1d5SCristian Dumitrescu 		"\tTX packets %" PRIu64"  bytes %" PRIu64"\n"
3845074e1d5SCristian Dumitrescu 		"\tTX errors %" PRIu64"\n",
3855074e1d5SCristian Dumitrescu 		link->name,
3865074e1d5SCristian Dumitrescu 		eth_link.link_status == 0 ? "DOWN" : "UP",
3875074e1d5SCristian Dumitrescu 		mtu,
3885074e1d5SCristian Dumitrescu 		mac_addr.addr_bytes[0], mac_addr.addr_bytes[1],
3895074e1d5SCristian Dumitrescu 		mac_addr.addr_bytes[2], mac_addr.addr_bytes[3],
3905074e1d5SCristian Dumitrescu 		mac_addr.addr_bytes[4], mac_addr.addr_bytes[5],
3915074e1d5SCristian Dumitrescu 		link->n_rxq,
3925074e1d5SCristian Dumitrescu 		link->n_txq,
3935074e1d5SCristian Dumitrescu 		link->port_id,
3945074e1d5SCristian Dumitrescu 		rte_eth_link_speed_to_str(eth_link.link_speed),
3955074e1d5SCristian Dumitrescu 		stats.ipackets,
3965074e1d5SCristian Dumitrescu 		stats.ibytes,
3975074e1d5SCristian Dumitrescu 		stats.ierrors,
3985074e1d5SCristian Dumitrescu 		stats.imissed,
3995074e1d5SCristian Dumitrescu 		stats.rx_nombuf,
4005074e1d5SCristian Dumitrescu 		stats.opackets,
4015074e1d5SCristian Dumitrescu 		stats.obytes,
4025074e1d5SCristian Dumitrescu 		stats.oerrors);
4035074e1d5SCristian Dumitrescu }
4045074e1d5SCristian Dumitrescu 
4055074e1d5SCristian Dumitrescu /*
4065074e1d5SCristian Dumitrescu  * link show [<link_name>]
4075074e1d5SCristian Dumitrescu  */
4085074e1d5SCristian Dumitrescu static void
4095074e1d5SCristian Dumitrescu cmd_link_show(char **tokens,
4105074e1d5SCristian Dumitrescu 	      uint32_t n_tokens,
4115074e1d5SCristian Dumitrescu 	      char *out,
4125074e1d5SCristian Dumitrescu 	      size_t out_size,
4135074e1d5SCristian Dumitrescu 	      void *obj)
4145074e1d5SCristian Dumitrescu {
4155074e1d5SCristian Dumitrescu 	struct link *link;
4165074e1d5SCristian Dumitrescu 	char *link_name;
4175074e1d5SCristian Dumitrescu 
4185074e1d5SCristian Dumitrescu 	if (n_tokens != 2 && n_tokens != 3) {
4195074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
4205074e1d5SCristian Dumitrescu 		return;
4215074e1d5SCristian Dumitrescu 	}
4225074e1d5SCristian Dumitrescu 
4235074e1d5SCristian Dumitrescu 	if (n_tokens == 2) {
4245074e1d5SCristian Dumitrescu 		link = link_next(obj, NULL);
4255074e1d5SCristian Dumitrescu 
4265074e1d5SCristian Dumitrescu 		while (link != NULL) {
4275074e1d5SCristian Dumitrescu 			out_size = out_size - strlen(out);
4285074e1d5SCristian Dumitrescu 			out = &out[strlen(out)];
4295074e1d5SCristian Dumitrescu 
4305074e1d5SCristian Dumitrescu 			print_link_info(link, out, out_size);
4315074e1d5SCristian Dumitrescu 			link = link_next(obj, link);
4325074e1d5SCristian Dumitrescu 		}
4335074e1d5SCristian Dumitrescu 	} else {
4345074e1d5SCristian Dumitrescu 		out_size = out_size - strlen(out);
4355074e1d5SCristian Dumitrescu 		out = &out[strlen(out)];
4365074e1d5SCristian Dumitrescu 
4375074e1d5SCristian Dumitrescu 		link_name = tokens[2];
4385074e1d5SCristian Dumitrescu 		link = link_find(obj, link_name);
4395074e1d5SCristian Dumitrescu 
4405074e1d5SCristian Dumitrescu 		if (link == NULL) {
4415074e1d5SCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_INVALID,
4425074e1d5SCristian Dumitrescu 					"Link does not exist");
4435074e1d5SCristian Dumitrescu 			return;
4445074e1d5SCristian Dumitrescu 		}
4455074e1d5SCristian Dumitrescu 		print_link_info(link, out, out_size);
4465074e1d5SCristian Dumitrescu 	}
4475074e1d5SCristian Dumitrescu }
4485074e1d5SCristian Dumitrescu 
44977a41301SCristian Dumitrescu static const char cmd_ring_help[] =
45077a41301SCristian Dumitrescu "ring <ring_name> size <size> numa <numa_node>\n";
45177a41301SCristian Dumitrescu 
45277a41301SCristian Dumitrescu static void
45377a41301SCristian Dumitrescu cmd_ring(char **tokens,
45477a41301SCristian Dumitrescu 	uint32_t n_tokens,
45577a41301SCristian Dumitrescu 	char *out,
45677a41301SCristian Dumitrescu 	size_t out_size,
45777a41301SCristian Dumitrescu 	void *obj)
45877a41301SCristian Dumitrescu {
45977a41301SCristian Dumitrescu 	struct ring_params p;
46077a41301SCristian Dumitrescu 	char *name;
46177a41301SCristian Dumitrescu 	struct ring *ring;
46277a41301SCristian Dumitrescu 
46377a41301SCristian Dumitrescu 	if (n_tokens != 6) {
46477a41301SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
46577a41301SCristian Dumitrescu 		return;
46677a41301SCristian Dumitrescu 	}
46777a41301SCristian Dumitrescu 
46877a41301SCristian Dumitrescu 	name = tokens[1];
46977a41301SCristian Dumitrescu 
47077a41301SCristian Dumitrescu 	if (strcmp(tokens[2], "size") != 0) {
47177a41301SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "size");
47277a41301SCristian Dumitrescu 		return;
47377a41301SCristian Dumitrescu 	}
47477a41301SCristian Dumitrescu 
47577a41301SCristian Dumitrescu 	if (parser_read_uint32(&p.size, tokens[3]) != 0) {
47677a41301SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "size");
47777a41301SCristian Dumitrescu 		return;
47877a41301SCristian Dumitrescu 	}
47977a41301SCristian Dumitrescu 
48077a41301SCristian Dumitrescu 	if (strcmp(tokens[4], "numa") != 0) {
48177a41301SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "numa");
48277a41301SCristian Dumitrescu 		return;
48377a41301SCristian Dumitrescu 	}
48477a41301SCristian Dumitrescu 
48577a41301SCristian Dumitrescu 	if (parser_read_uint32(&p.numa_node, tokens[5]) != 0) {
48677a41301SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "numa_node");
48777a41301SCristian Dumitrescu 		return;
48877a41301SCristian Dumitrescu 	}
48977a41301SCristian Dumitrescu 
49077a41301SCristian Dumitrescu 	ring = ring_create(obj, name, &p);
49177a41301SCristian Dumitrescu 	if (!ring) {
49277a41301SCristian Dumitrescu 		snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
49377a41301SCristian Dumitrescu 		return;
49477a41301SCristian Dumitrescu 	}
49577a41301SCristian Dumitrescu }
49677a41301SCristian Dumitrescu 
497*e2b8dc52SVenkata Suresh Kumar P static const char cmd_tap_help[] =
498*e2b8dc52SVenkata Suresh Kumar P "tap <tap_name>\n";
499*e2b8dc52SVenkata Suresh Kumar P 
500*e2b8dc52SVenkata Suresh Kumar P static void
501*e2b8dc52SVenkata Suresh Kumar P cmd_tap(char **tokens,
502*e2b8dc52SVenkata Suresh Kumar P 	uint32_t n_tokens,
503*e2b8dc52SVenkata Suresh Kumar P 	char *out,
504*e2b8dc52SVenkata Suresh Kumar P 	size_t out_size,
505*e2b8dc52SVenkata Suresh Kumar P 	void *obj)
506*e2b8dc52SVenkata Suresh Kumar P {
507*e2b8dc52SVenkata Suresh Kumar P 	struct tap *tap;
508*e2b8dc52SVenkata Suresh Kumar P 	char *name;
509*e2b8dc52SVenkata Suresh Kumar P 
510*e2b8dc52SVenkata Suresh Kumar P 	if (n_tokens < 2) {
511*e2b8dc52SVenkata Suresh Kumar P 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
512*e2b8dc52SVenkata Suresh Kumar P 		return;
513*e2b8dc52SVenkata Suresh Kumar P 	}
514*e2b8dc52SVenkata Suresh Kumar P 	name = tokens[1];
515*e2b8dc52SVenkata Suresh Kumar P 
516*e2b8dc52SVenkata Suresh Kumar P 	tap = tap_create(obj, name);
517*e2b8dc52SVenkata Suresh Kumar P 	if (tap == NULL) {
518*e2b8dc52SVenkata Suresh Kumar P 		snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
519*e2b8dc52SVenkata Suresh Kumar P 		return;
520*e2b8dc52SVenkata Suresh Kumar P 	}
521*e2b8dc52SVenkata Suresh Kumar P }
522*e2b8dc52SVenkata Suresh Kumar P 
5235074e1d5SCristian Dumitrescu static const char cmd_pipeline_create_help[] =
5245074e1d5SCristian Dumitrescu "pipeline <pipeline_name> create <numa_node>\n";
5255074e1d5SCristian Dumitrescu 
5265074e1d5SCristian Dumitrescu static void
5275074e1d5SCristian Dumitrescu cmd_pipeline_create(char **tokens,
5285074e1d5SCristian Dumitrescu 	uint32_t n_tokens,
5295074e1d5SCristian Dumitrescu 	char *out,
5305074e1d5SCristian Dumitrescu 	size_t out_size,
5315074e1d5SCristian Dumitrescu 	void *obj)
5325074e1d5SCristian Dumitrescu {
5335074e1d5SCristian Dumitrescu 	struct pipeline *p;
5345074e1d5SCristian Dumitrescu 	char *name;
5355074e1d5SCristian Dumitrescu 	uint32_t numa_node;
5365074e1d5SCristian Dumitrescu 
5375074e1d5SCristian Dumitrescu 	if (n_tokens != 4) {
5385074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
5395074e1d5SCristian Dumitrescu 		return;
5405074e1d5SCristian Dumitrescu 	}
5415074e1d5SCristian Dumitrescu 
5425074e1d5SCristian Dumitrescu 	name = tokens[1];
5435074e1d5SCristian Dumitrescu 
5445074e1d5SCristian Dumitrescu 	if (parser_read_uint32(&numa_node, tokens[3]) != 0) {
5455074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "numa_node");
5465074e1d5SCristian Dumitrescu 		return;
5475074e1d5SCristian Dumitrescu 	}
5485074e1d5SCristian Dumitrescu 
5495074e1d5SCristian Dumitrescu 	p = pipeline_create(obj, name, (int)numa_node);
5505074e1d5SCristian Dumitrescu 	if (!p) {
5515074e1d5SCristian Dumitrescu 		snprintf(out, out_size, "pipeline create error.");
5525074e1d5SCristian Dumitrescu 		return;
5535074e1d5SCristian Dumitrescu 	}
5545074e1d5SCristian Dumitrescu }
5555074e1d5SCristian Dumitrescu 
5565074e1d5SCristian Dumitrescu static const char cmd_pipeline_port_in_help[] =
5575074e1d5SCristian Dumitrescu "pipeline <pipeline_name> port in <port_id>\n"
5585074e1d5SCristian Dumitrescu "   link <link_name> rxq <queue_id> bsz <burst_size>\n"
55977a41301SCristian Dumitrescu "   ring <ring_name> bsz <burst_size>\n"
560*e2b8dc52SVenkata Suresh Kumar P "   | source <mempool_name> <file_name>\n"
561*e2b8dc52SVenkata Suresh Kumar P "   | tap <tap_name> mempool <mempool_name> mtu <mtu> bsz <burst_size>\n";
5625074e1d5SCristian Dumitrescu 
5635074e1d5SCristian Dumitrescu static void
5645074e1d5SCristian Dumitrescu cmd_pipeline_port_in(char **tokens,
5655074e1d5SCristian Dumitrescu 	uint32_t n_tokens,
5665074e1d5SCristian Dumitrescu 	char *out,
5675074e1d5SCristian Dumitrescu 	size_t out_size,
5685074e1d5SCristian Dumitrescu 	void *obj)
5695074e1d5SCristian Dumitrescu {
5705074e1d5SCristian Dumitrescu 	struct pipeline *p;
5715074e1d5SCristian Dumitrescu 	int status;
5725074e1d5SCristian Dumitrescu 	uint32_t port_id = 0, t0;
5735074e1d5SCristian Dumitrescu 
5745074e1d5SCristian Dumitrescu 	if (n_tokens < 6) {
5755074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
5765074e1d5SCristian Dumitrescu 		return;
5775074e1d5SCristian Dumitrescu 	}
5785074e1d5SCristian Dumitrescu 
5795074e1d5SCristian Dumitrescu 	p = pipeline_find(obj, tokens[1]);
5805074e1d5SCristian Dumitrescu 	if (!p || p->ctl) {
5815074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
5825074e1d5SCristian Dumitrescu 		return;
5835074e1d5SCristian Dumitrescu 	}
5845074e1d5SCristian Dumitrescu 
5855074e1d5SCristian Dumitrescu 	if (strcmp(tokens[2], "port") != 0) {
5865074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
5875074e1d5SCristian Dumitrescu 		return;
5885074e1d5SCristian Dumitrescu 	}
5895074e1d5SCristian Dumitrescu 
5905074e1d5SCristian Dumitrescu 	if (strcmp(tokens[3], "in") != 0) {
5915074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "in");
5925074e1d5SCristian Dumitrescu 		return;
5935074e1d5SCristian Dumitrescu 	}
5945074e1d5SCristian Dumitrescu 
5955074e1d5SCristian Dumitrescu 	if (parser_read_uint32(&port_id, tokens[4]) != 0) {
5965074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
5975074e1d5SCristian Dumitrescu 		return;
5985074e1d5SCristian Dumitrescu 	}
5995074e1d5SCristian Dumitrescu 
6005074e1d5SCristian Dumitrescu 	t0 = 5;
6015074e1d5SCristian Dumitrescu 
6025074e1d5SCristian Dumitrescu 	if (strcmp(tokens[t0], "link") == 0) {
6035074e1d5SCristian Dumitrescu 		struct rte_swx_port_ethdev_reader_params params;
6045074e1d5SCristian Dumitrescu 		struct link *link;
6055074e1d5SCristian Dumitrescu 
6065074e1d5SCristian Dumitrescu 		if (n_tokens < t0 + 6) {
6075074e1d5SCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_MISMATCH,
6085074e1d5SCristian Dumitrescu 				"pipeline port in link");
6095074e1d5SCristian Dumitrescu 			return;
6105074e1d5SCristian Dumitrescu 		}
6115074e1d5SCristian Dumitrescu 
6125074e1d5SCristian Dumitrescu 		link = link_find(obj, tokens[t0 + 1]);
6135074e1d5SCristian Dumitrescu 		if (!link) {
6145074e1d5SCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_INVALID,
6155074e1d5SCristian Dumitrescu 				"link_name");
6165074e1d5SCristian Dumitrescu 			return;
6175074e1d5SCristian Dumitrescu 		}
6185074e1d5SCristian Dumitrescu 		params.dev_name = link->dev_name;
6195074e1d5SCristian Dumitrescu 
6205074e1d5SCristian Dumitrescu 		if (strcmp(tokens[t0 + 2], "rxq") != 0) {
6215074e1d5SCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rxq");
6225074e1d5SCristian Dumitrescu 			return;
6235074e1d5SCristian Dumitrescu 		}
6245074e1d5SCristian Dumitrescu 
6255074e1d5SCristian Dumitrescu 		if (parser_read_uint16(&params.queue_id, tokens[t0 + 3]) != 0) {
6265074e1d5SCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_INVALID,
6275074e1d5SCristian Dumitrescu 				"queue_id");
6285074e1d5SCristian Dumitrescu 			return;
6295074e1d5SCristian Dumitrescu 		}
6305074e1d5SCristian Dumitrescu 
6315074e1d5SCristian Dumitrescu 		if (strcmp(tokens[t0 + 4], "bsz") != 0) {
6325074e1d5SCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_NOT_FOUND, "bsz");
6335074e1d5SCristian Dumitrescu 			return;
6345074e1d5SCristian Dumitrescu 		}
6355074e1d5SCristian Dumitrescu 
6365074e1d5SCristian Dumitrescu 		if (parser_read_uint32(&params.burst_size, tokens[t0 + 5])) {
6375074e1d5SCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_INVALID,
6385074e1d5SCristian Dumitrescu 				"burst_size");
6395074e1d5SCristian Dumitrescu 			return;
6405074e1d5SCristian Dumitrescu 		}
6415074e1d5SCristian Dumitrescu 
6425074e1d5SCristian Dumitrescu 		t0 += 6;
6435074e1d5SCristian Dumitrescu 
6445074e1d5SCristian Dumitrescu 		status = rte_swx_pipeline_port_in_config(p->p,
6455074e1d5SCristian Dumitrescu 			port_id,
6465074e1d5SCristian Dumitrescu 			"ethdev",
6475074e1d5SCristian Dumitrescu 			&params);
64877a41301SCristian Dumitrescu 	} else if (strcmp(tokens[t0], "ring") == 0) {
64977a41301SCristian Dumitrescu 		struct rte_swx_port_ring_reader_params params;
65077a41301SCristian Dumitrescu 		struct ring *ring;
65177a41301SCristian Dumitrescu 
65277a41301SCristian Dumitrescu 		if (n_tokens < t0 + 4) {
65377a41301SCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_MISMATCH,
65477a41301SCristian Dumitrescu 				"pipeline port in ring");
65577a41301SCristian Dumitrescu 			return;
65677a41301SCristian Dumitrescu 		}
65777a41301SCristian Dumitrescu 
65877a41301SCristian Dumitrescu 		ring = ring_find(obj, tokens[t0 + 1]);
65977a41301SCristian Dumitrescu 		if (!ring) {
66077a41301SCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_INVALID,
66177a41301SCristian Dumitrescu 				"ring_name");
66277a41301SCristian Dumitrescu 			return;
66377a41301SCristian Dumitrescu 		}
66477a41301SCristian Dumitrescu 		params.name = ring->name;
66577a41301SCristian Dumitrescu 
66677a41301SCristian Dumitrescu 		if (strcmp(tokens[t0 + 2], "bsz") != 0) {
66777a41301SCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_NOT_FOUND, "bsz");
66877a41301SCristian Dumitrescu 			return;
66977a41301SCristian Dumitrescu 		}
67077a41301SCristian Dumitrescu 
67177a41301SCristian Dumitrescu 		if (parser_read_uint32(&params.burst_size, tokens[t0 + 3])) {
67277a41301SCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_INVALID,
67377a41301SCristian Dumitrescu 				"burst_size");
67477a41301SCristian Dumitrescu 			return;
67577a41301SCristian Dumitrescu 		}
67677a41301SCristian Dumitrescu 
67777a41301SCristian Dumitrescu 		t0 += 4;
67877a41301SCristian Dumitrescu 
67977a41301SCristian Dumitrescu 		status = rte_swx_pipeline_port_in_config(p->p,
68077a41301SCristian Dumitrescu 			port_id,
68177a41301SCristian Dumitrescu 			"ring",
68277a41301SCristian Dumitrescu 			&params);
6835074e1d5SCristian Dumitrescu 	} else if (strcmp(tokens[t0], "source") == 0) {
6845074e1d5SCristian Dumitrescu 		struct rte_swx_port_source_params params;
6855074e1d5SCristian Dumitrescu 		struct mempool *mp;
6865074e1d5SCristian Dumitrescu 
6875074e1d5SCristian Dumitrescu 		if (n_tokens < t0 + 3) {
6885074e1d5SCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_MISMATCH,
6895074e1d5SCristian Dumitrescu 				"pipeline port in source");
6905074e1d5SCristian Dumitrescu 			return;
6915074e1d5SCristian Dumitrescu 		}
6925074e1d5SCristian Dumitrescu 
6935074e1d5SCristian Dumitrescu 		mp = mempool_find(obj, tokens[t0 + 1]);
6945074e1d5SCristian Dumitrescu 		if (!mp) {
6955074e1d5SCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_INVALID,
6965074e1d5SCristian Dumitrescu 				"mempool_name");
6975074e1d5SCristian Dumitrescu 			return;
6985074e1d5SCristian Dumitrescu 		}
6995074e1d5SCristian Dumitrescu 		params.pool = mp->m;
7005074e1d5SCristian Dumitrescu 
7015074e1d5SCristian Dumitrescu 		params.file_name = tokens[t0 + 2];
7025074e1d5SCristian Dumitrescu 
7035074e1d5SCristian Dumitrescu 		t0 += 3;
7045074e1d5SCristian Dumitrescu 
7055074e1d5SCristian Dumitrescu 		status = rte_swx_pipeline_port_in_config(p->p,
7065074e1d5SCristian Dumitrescu 			port_id,
7075074e1d5SCristian Dumitrescu 			"source",
7085074e1d5SCristian Dumitrescu 			&params);
709*e2b8dc52SVenkata Suresh Kumar P 	} else if (strcmp(tokens[t0], "tap") == 0) {
710*e2b8dc52SVenkata Suresh Kumar P 		struct rte_swx_port_fd_reader_params params;
711*e2b8dc52SVenkata Suresh Kumar P 		struct tap *tap;
712*e2b8dc52SVenkata Suresh Kumar P 		struct mempool *mp;
713*e2b8dc52SVenkata Suresh Kumar P 
714*e2b8dc52SVenkata Suresh Kumar P 		if (n_tokens < t0 + 8) {
715*e2b8dc52SVenkata Suresh Kumar P 			snprintf(out, out_size, MSG_ARG_MISMATCH,
716*e2b8dc52SVenkata Suresh Kumar P 				"pipeline port in tap");
717*e2b8dc52SVenkata Suresh Kumar P 			return;
718*e2b8dc52SVenkata Suresh Kumar P 		}
719*e2b8dc52SVenkata Suresh Kumar P 
720*e2b8dc52SVenkata Suresh Kumar P 		tap = tap_find(obj, tokens[t0 + 1]);
721*e2b8dc52SVenkata Suresh Kumar P 		if (!tap) {
722*e2b8dc52SVenkata Suresh Kumar P 			snprintf(out, out_size, MSG_ARG_INVALID,
723*e2b8dc52SVenkata Suresh Kumar P 				"tap_name");
724*e2b8dc52SVenkata Suresh Kumar P 			return;
725*e2b8dc52SVenkata Suresh Kumar P 		}
726*e2b8dc52SVenkata Suresh Kumar P 		params.fd = tap->fd;
727*e2b8dc52SVenkata Suresh Kumar P 
728*e2b8dc52SVenkata Suresh Kumar P 		if (strcmp(tokens[t0 + 2], "mempool") != 0) {
729*e2b8dc52SVenkata Suresh Kumar P 			snprintf(out, out_size, MSG_ARG_NOT_FOUND,
730*e2b8dc52SVenkata Suresh Kumar P 				"mempool");
731*e2b8dc52SVenkata Suresh Kumar P 			return;
732*e2b8dc52SVenkata Suresh Kumar P 		}
733*e2b8dc52SVenkata Suresh Kumar P 
734*e2b8dc52SVenkata Suresh Kumar P 		mp = mempool_find(obj, tokens[t0 + 3]);
735*e2b8dc52SVenkata Suresh Kumar P 		if (!mp) {
736*e2b8dc52SVenkata Suresh Kumar P 			snprintf(out, out_size, MSG_ARG_INVALID,
737*e2b8dc52SVenkata Suresh Kumar P 				"mempool_name");
738*e2b8dc52SVenkata Suresh Kumar P 			return;
739*e2b8dc52SVenkata Suresh Kumar P 		}
740*e2b8dc52SVenkata Suresh Kumar P 		params.mempool = mp->m;
741*e2b8dc52SVenkata Suresh Kumar P 
742*e2b8dc52SVenkata Suresh Kumar P 		if (strcmp(tokens[t0 + 4], "mtu") != 0) {
743*e2b8dc52SVenkata Suresh Kumar P 			snprintf(out, out_size, MSG_ARG_NOT_FOUND,
744*e2b8dc52SVenkata Suresh Kumar P 				"mtu");
745*e2b8dc52SVenkata Suresh Kumar P 			return;
746*e2b8dc52SVenkata Suresh Kumar P 		}
747*e2b8dc52SVenkata Suresh Kumar P 
748*e2b8dc52SVenkata Suresh Kumar P 		if (parser_read_uint32(&params.mtu, tokens[t0 + 5]) != 0) {
749*e2b8dc52SVenkata Suresh Kumar P 			snprintf(out, out_size, MSG_ARG_INVALID, "mtu");
750*e2b8dc52SVenkata Suresh Kumar P 			return;
751*e2b8dc52SVenkata Suresh Kumar P 		}
752*e2b8dc52SVenkata Suresh Kumar P 
753*e2b8dc52SVenkata Suresh Kumar P 		if (strcmp(tokens[t0 + 6], "bsz") != 0) {
754*e2b8dc52SVenkata Suresh Kumar P 			snprintf(out, out_size, MSG_ARG_NOT_FOUND, "bsz");
755*e2b8dc52SVenkata Suresh Kumar P 			return;
756*e2b8dc52SVenkata Suresh Kumar P 		}
757*e2b8dc52SVenkata Suresh Kumar P 
758*e2b8dc52SVenkata Suresh Kumar P 		if (parser_read_uint32(&params.burst_size, tokens[t0 + 7])) {
759*e2b8dc52SVenkata Suresh Kumar P 			snprintf(out, out_size, MSG_ARG_INVALID,
760*e2b8dc52SVenkata Suresh Kumar P 				"burst_size");
761*e2b8dc52SVenkata Suresh Kumar P 			return;
762*e2b8dc52SVenkata Suresh Kumar P 		}
763*e2b8dc52SVenkata Suresh Kumar P 
764*e2b8dc52SVenkata Suresh Kumar P 		t0 += 8;
765*e2b8dc52SVenkata Suresh Kumar P 
766*e2b8dc52SVenkata Suresh Kumar P 		status = rte_swx_pipeline_port_in_config(p->p,
767*e2b8dc52SVenkata Suresh Kumar P 			port_id,
768*e2b8dc52SVenkata Suresh Kumar P 			"fd",
769*e2b8dc52SVenkata Suresh Kumar P 			&params);
770*e2b8dc52SVenkata Suresh Kumar P 
7715074e1d5SCristian Dumitrescu 	} else {
7725074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
7735074e1d5SCristian Dumitrescu 		return;
7745074e1d5SCristian Dumitrescu 	}
7755074e1d5SCristian Dumitrescu 
7765074e1d5SCristian Dumitrescu 	if (status) {
7775074e1d5SCristian Dumitrescu 		snprintf(out, out_size, "port in error.");
7785074e1d5SCristian Dumitrescu 		return;
7795074e1d5SCristian Dumitrescu 	}
7805074e1d5SCristian Dumitrescu 
7815074e1d5SCristian Dumitrescu 	if (n_tokens != t0) {
7825074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
7835074e1d5SCristian Dumitrescu 		return;
7845074e1d5SCristian Dumitrescu 	}
7855074e1d5SCristian Dumitrescu }
7865074e1d5SCristian Dumitrescu 
7875074e1d5SCristian Dumitrescu static const char cmd_pipeline_port_out_help[] =
7885074e1d5SCristian Dumitrescu "pipeline <pipeline_name> port out <port_id>\n"
7895074e1d5SCristian Dumitrescu "   link <link_name> txq <txq_id> bsz <burst_size>\n"
79077a41301SCristian Dumitrescu "   ring <ring_name> bsz <burst_size>\n"
791*e2b8dc52SVenkata Suresh Kumar P "   | sink <file_name> | none\n"
792*e2b8dc52SVenkata Suresh Kumar P "   | tap <tap_name> bsz <burst_size>\n";
7935074e1d5SCristian Dumitrescu 
7945074e1d5SCristian Dumitrescu static void
7955074e1d5SCristian Dumitrescu cmd_pipeline_port_out(char **tokens,
7965074e1d5SCristian Dumitrescu 	uint32_t n_tokens,
7975074e1d5SCristian Dumitrescu 	char *out,
7985074e1d5SCristian Dumitrescu 	size_t out_size,
7995074e1d5SCristian Dumitrescu 	void *obj)
8005074e1d5SCristian Dumitrescu {
8015074e1d5SCristian Dumitrescu 	struct pipeline *p;
8025074e1d5SCristian Dumitrescu 	int status;
8035074e1d5SCristian Dumitrescu 	uint32_t port_id = 0, t0;
8045074e1d5SCristian Dumitrescu 
8055074e1d5SCristian Dumitrescu 	if (n_tokens < 6) {
8065074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
8075074e1d5SCristian Dumitrescu 		return;
8085074e1d5SCristian Dumitrescu 	}
8095074e1d5SCristian Dumitrescu 
8105074e1d5SCristian Dumitrescu 	p = pipeline_find(obj, tokens[1]);
8115074e1d5SCristian Dumitrescu 	if (!p || p->ctl) {
8125074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
8135074e1d5SCristian Dumitrescu 		return;
8145074e1d5SCristian Dumitrescu 	}
8155074e1d5SCristian Dumitrescu 
8165074e1d5SCristian Dumitrescu 	if (strcmp(tokens[2], "port") != 0) {
8175074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
8185074e1d5SCristian Dumitrescu 		return;
8195074e1d5SCristian Dumitrescu 	}
8205074e1d5SCristian Dumitrescu 
8215074e1d5SCristian Dumitrescu 	if (strcmp(tokens[3], "out") != 0) {
8225074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "out");
8235074e1d5SCristian Dumitrescu 		return;
8245074e1d5SCristian Dumitrescu 	}
8255074e1d5SCristian Dumitrescu 
8265074e1d5SCristian Dumitrescu 	if (parser_read_uint32(&port_id, tokens[4]) != 0) {
8275074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
8285074e1d5SCristian Dumitrescu 		return;
8295074e1d5SCristian Dumitrescu 	}
8305074e1d5SCristian Dumitrescu 
8315074e1d5SCristian Dumitrescu 	t0 = 5;
8325074e1d5SCristian Dumitrescu 
8335074e1d5SCristian Dumitrescu 	if (strcmp(tokens[t0], "link") == 0) {
8345074e1d5SCristian Dumitrescu 		struct rte_swx_port_ethdev_writer_params params;
8355074e1d5SCristian Dumitrescu 		struct link *link;
8365074e1d5SCristian Dumitrescu 
8375074e1d5SCristian Dumitrescu 		if (n_tokens < t0 + 6) {
8385074e1d5SCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_MISMATCH,
8395074e1d5SCristian Dumitrescu 				"pipeline port out link");
8405074e1d5SCristian Dumitrescu 			return;
8415074e1d5SCristian Dumitrescu 		}
8425074e1d5SCristian Dumitrescu 
8435074e1d5SCristian Dumitrescu 		link = link_find(obj, tokens[t0 + 1]);
8445074e1d5SCristian Dumitrescu 		if (!link) {
8455074e1d5SCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_INVALID,
8465074e1d5SCristian Dumitrescu 				"link_name");
8475074e1d5SCristian Dumitrescu 			return;
8485074e1d5SCristian Dumitrescu 		}
8495074e1d5SCristian Dumitrescu 		params.dev_name = link->dev_name;
8505074e1d5SCristian Dumitrescu 
8515074e1d5SCristian Dumitrescu 		if (strcmp(tokens[t0 + 2], "txq") != 0) {
8525074e1d5SCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_NOT_FOUND, "txq");
8535074e1d5SCristian Dumitrescu 			return;
8545074e1d5SCristian Dumitrescu 		}
8555074e1d5SCristian Dumitrescu 
8565074e1d5SCristian Dumitrescu 		if (parser_read_uint16(&params.queue_id, tokens[t0 + 3]) != 0) {
8575074e1d5SCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_INVALID,
8585074e1d5SCristian Dumitrescu 				"queue_id");
8595074e1d5SCristian Dumitrescu 			return;
8605074e1d5SCristian Dumitrescu 		}
8615074e1d5SCristian Dumitrescu 
8625074e1d5SCristian Dumitrescu 		if (strcmp(tokens[t0 + 4], "bsz") != 0) {
8635074e1d5SCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_NOT_FOUND, "bsz");
8645074e1d5SCristian Dumitrescu 			return;
8655074e1d5SCristian Dumitrescu 		}
8665074e1d5SCristian Dumitrescu 
8675074e1d5SCristian Dumitrescu 		if (parser_read_uint32(&params.burst_size, tokens[t0 + 5])) {
8685074e1d5SCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_INVALID,
8695074e1d5SCristian Dumitrescu 				"burst_size");
8705074e1d5SCristian Dumitrescu 			return;
8715074e1d5SCristian Dumitrescu 		}
8725074e1d5SCristian Dumitrescu 
8735074e1d5SCristian Dumitrescu 		t0 += 6;
8745074e1d5SCristian Dumitrescu 
8755074e1d5SCristian Dumitrescu 		status = rte_swx_pipeline_port_out_config(p->p,
8765074e1d5SCristian Dumitrescu 			port_id,
8775074e1d5SCristian Dumitrescu 			"ethdev",
8785074e1d5SCristian Dumitrescu 			&params);
87977a41301SCristian Dumitrescu 	} else if (strcmp(tokens[t0], "ring") == 0) {
88077a41301SCristian Dumitrescu 		struct rte_swx_port_ring_writer_params params;
88177a41301SCristian Dumitrescu 		struct ring *ring;
88277a41301SCristian Dumitrescu 
88377a41301SCristian Dumitrescu 		if (n_tokens < t0 + 4) {
88477a41301SCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_MISMATCH,
88577a41301SCristian Dumitrescu 				"pipeline port out link");
88677a41301SCristian Dumitrescu 			return;
88777a41301SCristian Dumitrescu 		}
88877a41301SCristian Dumitrescu 
88977a41301SCristian Dumitrescu 		ring = ring_find(obj, tokens[t0 + 1]);
89077a41301SCristian Dumitrescu 		if (!ring) {
89177a41301SCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_INVALID,
89277a41301SCristian Dumitrescu 				"ring_name");
89377a41301SCristian Dumitrescu 			return;
89477a41301SCristian Dumitrescu 		}
89577a41301SCristian Dumitrescu 		params.name = ring->name;
89677a41301SCristian Dumitrescu 
89777a41301SCristian Dumitrescu 		if (strcmp(tokens[t0 + 2], "bsz") != 0) {
89877a41301SCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_NOT_FOUND, "bsz");
89977a41301SCristian Dumitrescu 			return;
90077a41301SCristian Dumitrescu 		}
90177a41301SCristian Dumitrescu 
90277a41301SCristian Dumitrescu 		if (parser_read_uint32(&params.burst_size, tokens[t0 + 3])) {
90377a41301SCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_INVALID,
90477a41301SCristian Dumitrescu 				"burst_size");
90577a41301SCristian Dumitrescu 			return;
90677a41301SCristian Dumitrescu 		}
90777a41301SCristian Dumitrescu 
90877a41301SCristian Dumitrescu 		t0 += 4;
90977a41301SCristian Dumitrescu 
91077a41301SCristian Dumitrescu 		status = rte_swx_pipeline_port_out_config(p->p,
91177a41301SCristian Dumitrescu 			port_id,
91277a41301SCristian Dumitrescu 			"ring",
91377a41301SCristian Dumitrescu 			&params);
9145074e1d5SCristian Dumitrescu 	} else if (strcmp(tokens[t0], "sink") == 0) {
9155074e1d5SCristian Dumitrescu 		struct rte_swx_port_sink_params params;
9165074e1d5SCristian Dumitrescu 
9175074e1d5SCristian Dumitrescu 		params.file_name = strcmp(tokens[t0 + 1], "none") ?
9185074e1d5SCristian Dumitrescu 			tokens[t0 + 1] : NULL;
9195074e1d5SCristian Dumitrescu 
9205074e1d5SCristian Dumitrescu 		t0 += 2;
9215074e1d5SCristian Dumitrescu 
9225074e1d5SCristian Dumitrescu 		status = rte_swx_pipeline_port_out_config(p->p,
9235074e1d5SCristian Dumitrescu 			port_id,
9245074e1d5SCristian Dumitrescu 			"sink",
9255074e1d5SCristian Dumitrescu 			&params);
926*e2b8dc52SVenkata Suresh Kumar P 	} else if (strcmp(tokens[t0], "tap") == 0) {
927*e2b8dc52SVenkata Suresh Kumar P 		struct rte_swx_port_fd_writer_params params;
928*e2b8dc52SVenkata Suresh Kumar P 		struct tap *tap;
929*e2b8dc52SVenkata Suresh Kumar P 
930*e2b8dc52SVenkata Suresh Kumar P 		if (n_tokens < t0 + 4) {
931*e2b8dc52SVenkata Suresh Kumar P 			snprintf(out, out_size, MSG_ARG_MISMATCH,
932*e2b8dc52SVenkata Suresh Kumar P 				"pipeline port out tap");
933*e2b8dc52SVenkata Suresh Kumar P 			return;
934*e2b8dc52SVenkata Suresh Kumar P 		}
935*e2b8dc52SVenkata Suresh Kumar P 
936*e2b8dc52SVenkata Suresh Kumar P 		tap = tap_find(obj, tokens[t0 + 1]);
937*e2b8dc52SVenkata Suresh Kumar P 		if (!tap) {
938*e2b8dc52SVenkata Suresh Kumar P 			snprintf(out, out_size, MSG_ARG_INVALID,
939*e2b8dc52SVenkata Suresh Kumar P 				"tap_name");
940*e2b8dc52SVenkata Suresh Kumar P 			return;
941*e2b8dc52SVenkata Suresh Kumar P 		}
942*e2b8dc52SVenkata Suresh Kumar P 		params.fd = tap->fd;
943*e2b8dc52SVenkata Suresh Kumar P 
944*e2b8dc52SVenkata Suresh Kumar P 		if (strcmp(tokens[t0 + 2], "bsz") != 0) {
945*e2b8dc52SVenkata Suresh Kumar P 			snprintf(out, out_size, MSG_ARG_NOT_FOUND, "bsz");
946*e2b8dc52SVenkata Suresh Kumar P 			return;
947*e2b8dc52SVenkata Suresh Kumar P 		}
948*e2b8dc52SVenkata Suresh Kumar P 
949*e2b8dc52SVenkata Suresh Kumar P 		if (parser_read_uint32(&params.burst_size, tokens[t0 + 3])) {
950*e2b8dc52SVenkata Suresh Kumar P 			snprintf(out, out_size, MSG_ARG_INVALID,
951*e2b8dc52SVenkata Suresh Kumar P 				"burst_size");
952*e2b8dc52SVenkata Suresh Kumar P 			return;
953*e2b8dc52SVenkata Suresh Kumar P 		}
954*e2b8dc52SVenkata Suresh Kumar P 
955*e2b8dc52SVenkata Suresh Kumar P 		t0 += 4;
956*e2b8dc52SVenkata Suresh Kumar P 
957*e2b8dc52SVenkata Suresh Kumar P 		status = rte_swx_pipeline_port_out_config(p->p,
958*e2b8dc52SVenkata Suresh Kumar P 			port_id,
959*e2b8dc52SVenkata Suresh Kumar P 			"fd",
960*e2b8dc52SVenkata Suresh Kumar P 			&params);
9615074e1d5SCristian Dumitrescu 	} else {
9625074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
9635074e1d5SCristian Dumitrescu 		return;
9645074e1d5SCristian Dumitrescu 	}
9655074e1d5SCristian Dumitrescu 
9665074e1d5SCristian Dumitrescu 	if (status) {
9675074e1d5SCristian Dumitrescu 		snprintf(out, out_size, "port out error.");
9685074e1d5SCristian Dumitrescu 		return;
9695074e1d5SCristian Dumitrescu 	}
9705074e1d5SCristian Dumitrescu 
9715074e1d5SCristian Dumitrescu 	if (n_tokens != t0) {
9725074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
9735074e1d5SCristian Dumitrescu 		return;
9745074e1d5SCristian Dumitrescu 	}
9755074e1d5SCristian Dumitrescu }
9765074e1d5SCristian Dumitrescu 
9775074e1d5SCristian Dumitrescu static const char cmd_pipeline_build_help[] =
9785074e1d5SCristian Dumitrescu "pipeline <pipeline_name> build <spec_file>\n";
9795074e1d5SCristian Dumitrescu 
9805074e1d5SCristian Dumitrescu static void
9815074e1d5SCristian Dumitrescu cmd_pipeline_build(char **tokens,
9825074e1d5SCristian Dumitrescu 	uint32_t n_tokens,
9835074e1d5SCristian Dumitrescu 	char *out,
9845074e1d5SCristian Dumitrescu 	size_t out_size,
9855074e1d5SCristian Dumitrescu 	void *obj)
9865074e1d5SCristian Dumitrescu {
9875074e1d5SCristian Dumitrescu 	struct pipeline *p = NULL;
9885074e1d5SCristian Dumitrescu 	FILE *spec = NULL;
9895074e1d5SCristian Dumitrescu 	uint32_t err_line;
9905074e1d5SCristian Dumitrescu 	const char *err_msg;
9915074e1d5SCristian Dumitrescu 	int status;
9925074e1d5SCristian Dumitrescu 
9935074e1d5SCristian Dumitrescu 	if (n_tokens != 4) {
9945074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
9955074e1d5SCristian Dumitrescu 		return;
9965074e1d5SCristian Dumitrescu 	}
9975074e1d5SCristian Dumitrescu 
9985074e1d5SCristian Dumitrescu 	p = pipeline_find(obj, tokens[1]);
9995074e1d5SCristian Dumitrescu 	if (!p || p->ctl) {
10005074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
10015074e1d5SCristian Dumitrescu 		return;
10025074e1d5SCristian Dumitrescu 	}
10035074e1d5SCristian Dumitrescu 
10045074e1d5SCristian Dumitrescu 	spec = fopen(tokens[3], "r");
10055074e1d5SCristian Dumitrescu 	if (!spec) {
10065074e1d5SCristian Dumitrescu 		snprintf(out, out_size, "Cannot open file %s.\n", tokens[3]);
10075074e1d5SCristian Dumitrescu 		return;
10085074e1d5SCristian Dumitrescu 	}
10095074e1d5SCristian Dumitrescu 
10105074e1d5SCristian Dumitrescu 	status = rte_swx_pipeline_build_from_spec(p->p,
10115074e1d5SCristian Dumitrescu 		spec,
10125074e1d5SCristian Dumitrescu 		&err_line,
10135074e1d5SCristian Dumitrescu 		&err_msg);
10145074e1d5SCristian Dumitrescu 	fclose(spec);
10155074e1d5SCristian Dumitrescu 	if (status) {
10165074e1d5SCristian Dumitrescu 		snprintf(out, out_size, "Error %d at line %u: %s\n.",
10175074e1d5SCristian Dumitrescu 			status, err_line, err_msg);
10185074e1d5SCristian Dumitrescu 		return;
10195074e1d5SCristian Dumitrescu 	}
10205074e1d5SCristian Dumitrescu 
10215074e1d5SCristian Dumitrescu 	p->ctl = rte_swx_ctl_pipeline_create(p->p);
10225074e1d5SCristian Dumitrescu 	if (!p->ctl) {
10235074e1d5SCristian Dumitrescu 		snprintf(out, out_size, "Pipeline control create failed.");
10245074e1d5SCristian Dumitrescu 		rte_swx_pipeline_free(p->p);
10255074e1d5SCristian Dumitrescu 		return;
10265074e1d5SCristian Dumitrescu 	}
10275074e1d5SCristian Dumitrescu }
10285074e1d5SCristian Dumitrescu 
1029275ebefeSCristian Dumitrescu static void
1030275ebefeSCristian Dumitrescu table_entry_free(struct rte_swx_table_entry *entry)
1031275ebefeSCristian Dumitrescu {
1032275ebefeSCristian Dumitrescu 	if (!entry)
1033275ebefeSCristian Dumitrescu 		return;
1034275ebefeSCristian Dumitrescu 
1035275ebefeSCristian Dumitrescu 	free(entry->key);
1036275ebefeSCristian Dumitrescu 	free(entry->key_mask);
1037275ebefeSCristian Dumitrescu 	free(entry->action_data);
1038275ebefeSCristian Dumitrescu 	free(entry);
1039275ebefeSCristian Dumitrescu }
1040275ebefeSCristian Dumitrescu 
10415074e1d5SCristian Dumitrescu static const char cmd_pipeline_table_update_help[] =
10425074e1d5SCristian Dumitrescu "pipeline <pipeline_name> table <table_name> update <file_name_add> "
10435074e1d5SCristian Dumitrescu "<file_name_delete> <file_name_default>";
10445074e1d5SCristian Dumitrescu 
10455074e1d5SCristian Dumitrescu static void
10465074e1d5SCristian Dumitrescu cmd_pipeline_table_update(char **tokens,
10475074e1d5SCristian Dumitrescu 	uint32_t n_tokens,
10485074e1d5SCristian Dumitrescu 	char *out,
10495074e1d5SCristian Dumitrescu 	size_t out_size,
10505074e1d5SCristian Dumitrescu 	void *obj)
10515074e1d5SCristian Dumitrescu {
10525074e1d5SCristian Dumitrescu 	struct pipeline *p;
10535074e1d5SCristian Dumitrescu 	char *pipeline_name, *table_name, *line = NULL;
10545074e1d5SCristian Dumitrescu 	char *file_name_add, *file_name_delete, *file_name_default;
10555074e1d5SCristian Dumitrescu 	FILE *file_add = NULL, *file_delete = NULL, *file_default = NULL;
10565074e1d5SCristian Dumitrescu 	uint32_t line_id;
10575074e1d5SCristian Dumitrescu 	int status;
10585074e1d5SCristian Dumitrescu 
10595074e1d5SCristian Dumitrescu 	if (n_tokens != 8) {
10605074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
10615074e1d5SCristian Dumitrescu 		return;
10625074e1d5SCristian Dumitrescu 	}
10635074e1d5SCristian Dumitrescu 
10645074e1d5SCristian Dumitrescu 	pipeline_name = tokens[1];
10655074e1d5SCristian Dumitrescu 	p = pipeline_find(obj, pipeline_name);
10665074e1d5SCristian Dumitrescu 	if (!p || !p->ctl) {
10675074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
10685074e1d5SCristian Dumitrescu 		return;
10695074e1d5SCristian Dumitrescu 	}
10705074e1d5SCristian Dumitrescu 
10715074e1d5SCristian Dumitrescu 	if (strcmp(tokens[2], "table") != 0) {
10725074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
10735074e1d5SCristian Dumitrescu 		return;
10745074e1d5SCristian Dumitrescu 	}
10755074e1d5SCristian Dumitrescu 
10765074e1d5SCristian Dumitrescu 	table_name = tokens[3];
10775074e1d5SCristian Dumitrescu 
10785074e1d5SCristian Dumitrescu 	if (strcmp(tokens[4], "update") != 0) {
10795074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "update");
10805074e1d5SCristian Dumitrescu 		return;
10815074e1d5SCristian Dumitrescu 	}
10825074e1d5SCristian Dumitrescu 
10835074e1d5SCristian Dumitrescu 	file_name_add = tokens[5];
10845074e1d5SCristian Dumitrescu 	file_name_delete = tokens[6];
10855074e1d5SCristian Dumitrescu 	file_name_default = tokens[7];
10865074e1d5SCristian Dumitrescu 
10875074e1d5SCristian Dumitrescu 	/* File open. */
10885074e1d5SCristian Dumitrescu 	if (strcmp(file_name_add, "none")) {
10895074e1d5SCristian Dumitrescu 		file_add = fopen(file_name_add, "r");
10905074e1d5SCristian Dumitrescu 		if (!file_add) {
10915074e1d5SCristian Dumitrescu 			snprintf(out, out_size, "Cannot open file %s",
10925074e1d5SCristian Dumitrescu 				file_name_add);
10935074e1d5SCristian Dumitrescu 			goto error;
10945074e1d5SCristian Dumitrescu 		}
10955074e1d5SCristian Dumitrescu 	}
10965074e1d5SCristian Dumitrescu 
10975074e1d5SCristian Dumitrescu 	if (strcmp(file_name_delete, "none")) {
109864eaee23SCristian Dumitrescu 		file_delete = fopen(file_name_delete, "r");
109964eaee23SCristian Dumitrescu 		if (!file_delete) {
11005074e1d5SCristian Dumitrescu 			snprintf(out, out_size, "Cannot open file %s",
11015074e1d5SCristian Dumitrescu 				file_name_delete);
11025074e1d5SCristian Dumitrescu 			goto error;
11035074e1d5SCristian Dumitrescu 		}
11045074e1d5SCristian Dumitrescu 	}
11055074e1d5SCristian Dumitrescu 
11065074e1d5SCristian Dumitrescu 	if (strcmp(file_name_default, "none")) {
110764eaee23SCristian Dumitrescu 		file_default = fopen(file_name_default, "r");
110864eaee23SCristian Dumitrescu 		if (!file_default) {
11095074e1d5SCristian Dumitrescu 			snprintf(out, out_size, "Cannot open file %s",
11105074e1d5SCristian Dumitrescu 				file_name_default);
11115074e1d5SCristian Dumitrescu 			goto error;
11125074e1d5SCristian Dumitrescu 		}
11135074e1d5SCristian Dumitrescu 	}
11145074e1d5SCristian Dumitrescu 
11155074e1d5SCristian Dumitrescu 	if (!file_add && !file_delete && !file_default) {
11165074e1d5SCristian Dumitrescu 		snprintf(out, out_size, "Nothing to be done.");
11175074e1d5SCristian Dumitrescu 		return;
11185074e1d5SCristian Dumitrescu 	}
11195074e1d5SCristian Dumitrescu 
11205074e1d5SCristian Dumitrescu 	/* Buffer allocation. */
11215074e1d5SCristian Dumitrescu 	line = malloc(2048);
11225074e1d5SCristian Dumitrescu 	if (!line) {
11235074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_OUT_OF_MEMORY);
11245074e1d5SCristian Dumitrescu 		goto error;
11255074e1d5SCristian Dumitrescu 	}
11265074e1d5SCristian Dumitrescu 
11275074e1d5SCristian Dumitrescu 	/* Add. */
112803665a48SCristian Dumitrescu 	if (file_add)
11295074e1d5SCristian Dumitrescu 		for (line_id = 1; ; line_id++) {
11305074e1d5SCristian Dumitrescu 			struct rte_swx_table_entry *entry;
1131cff9a717SCristian Dumitrescu 			int is_blank_or_comment;
11325074e1d5SCristian Dumitrescu 
11335074e1d5SCristian Dumitrescu 			if (fgets(line, 2048, file_add) == NULL)
11345074e1d5SCristian Dumitrescu 				break;
11355074e1d5SCristian Dumitrescu 
11365074e1d5SCristian Dumitrescu 			entry = rte_swx_ctl_pipeline_table_entry_read(p->ctl,
11375074e1d5SCristian Dumitrescu 				table_name,
1138cff9a717SCristian Dumitrescu 				line,
1139cff9a717SCristian Dumitrescu 				&is_blank_or_comment);
11405074e1d5SCristian Dumitrescu 			if (!entry) {
1141cff9a717SCristian Dumitrescu 				if (is_blank_or_comment)
1142cff9a717SCristian Dumitrescu 					continue;
1143cff9a717SCristian Dumitrescu 
11445074e1d5SCristian Dumitrescu 				snprintf(out, out_size, MSG_FILE_ERR,
11455074e1d5SCristian Dumitrescu 					file_name_add, line_id);
11465074e1d5SCristian Dumitrescu 				goto error;
11475074e1d5SCristian Dumitrescu 			}
11485074e1d5SCristian Dumitrescu 
11495074e1d5SCristian Dumitrescu 			status = rte_swx_ctl_pipeline_table_entry_add(p->ctl,
11505074e1d5SCristian Dumitrescu 				table_name,
11515074e1d5SCristian Dumitrescu 				entry);
1152275ebefeSCristian Dumitrescu 			table_entry_free(entry);
11535074e1d5SCristian Dumitrescu 			if (status) {
11545074e1d5SCristian Dumitrescu 				snprintf(out, out_size,
11555074e1d5SCristian Dumitrescu 					"Invalid entry in file %s at line %u",
11565074e1d5SCristian Dumitrescu 					file_name_add, line_id);
11575074e1d5SCristian Dumitrescu 				goto error;
11585074e1d5SCristian Dumitrescu 			}
11595074e1d5SCristian Dumitrescu 		}
11605074e1d5SCristian Dumitrescu 
11615074e1d5SCristian Dumitrescu 
11625074e1d5SCristian Dumitrescu 	/* Delete. */
116303665a48SCristian Dumitrescu 	if (file_delete)
11645074e1d5SCristian Dumitrescu 		for (line_id = 1; ; line_id++) {
11655074e1d5SCristian Dumitrescu 			struct rte_swx_table_entry *entry;
1166cff9a717SCristian Dumitrescu 			int is_blank_or_comment;
11675074e1d5SCristian Dumitrescu 
11685074e1d5SCristian Dumitrescu 			if (fgets(line, 2048, file_delete) == NULL)
11695074e1d5SCristian Dumitrescu 				break;
11705074e1d5SCristian Dumitrescu 
11715074e1d5SCristian Dumitrescu 			entry = rte_swx_ctl_pipeline_table_entry_read(p->ctl,
11725074e1d5SCristian Dumitrescu 				table_name,
1173cff9a717SCristian Dumitrescu 				line,
1174cff9a717SCristian Dumitrescu 				&is_blank_or_comment);
11755074e1d5SCristian Dumitrescu 			if (!entry) {
1176cff9a717SCristian Dumitrescu 				if (is_blank_or_comment)
1177cff9a717SCristian Dumitrescu 					continue;
1178cff9a717SCristian Dumitrescu 
11795074e1d5SCristian Dumitrescu 				snprintf(out, out_size, MSG_FILE_ERR,
11805074e1d5SCristian Dumitrescu 					file_name_delete, line_id);
11815074e1d5SCristian Dumitrescu 				goto error;
11825074e1d5SCristian Dumitrescu 			}
11835074e1d5SCristian Dumitrescu 
11845074e1d5SCristian Dumitrescu 			status = rte_swx_ctl_pipeline_table_entry_delete(p->ctl,
11855074e1d5SCristian Dumitrescu 				table_name,
11865074e1d5SCristian Dumitrescu 				entry);
1187275ebefeSCristian Dumitrescu 			table_entry_free(entry);
11885074e1d5SCristian Dumitrescu 			if (status)  {
11895074e1d5SCristian Dumitrescu 				snprintf(out, out_size,
11905074e1d5SCristian Dumitrescu 					"Invalid entry in file %s at line %u",
11915074e1d5SCristian Dumitrescu 					file_name_delete, line_id);
11925074e1d5SCristian Dumitrescu 				goto error;
11935074e1d5SCristian Dumitrescu 			}
11945074e1d5SCristian Dumitrescu 		}
11955074e1d5SCristian Dumitrescu 
11965074e1d5SCristian Dumitrescu 	/* Default. */
119703665a48SCristian Dumitrescu 	if (file_default)
11985074e1d5SCristian Dumitrescu 		for (line_id = 1; ; line_id++) {
11995074e1d5SCristian Dumitrescu 			struct rte_swx_table_entry *entry;
1200cff9a717SCristian Dumitrescu 			int is_blank_or_comment;
12015074e1d5SCristian Dumitrescu 
12025074e1d5SCristian Dumitrescu 			if (fgets(line, 2048, file_default) == NULL)
12035074e1d5SCristian Dumitrescu 				break;
12045074e1d5SCristian Dumitrescu 
12055074e1d5SCristian Dumitrescu 			entry = rte_swx_ctl_pipeline_table_entry_read(p->ctl,
12065074e1d5SCristian Dumitrescu 				table_name,
1207cff9a717SCristian Dumitrescu 				line,
1208cff9a717SCristian Dumitrescu 				&is_blank_or_comment);
12095074e1d5SCristian Dumitrescu 			if (!entry) {
1210cff9a717SCristian Dumitrescu 				if (is_blank_or_comment)
1211cff9a717SCristian Dumitrescu 					continue;
1212cff9a717SCristian Dumitrescu 
12135074e1d5SCristian Dumitrescu 				snprintf(out, out_size, MSG_FILE_ERR,
12145074e1d5SCristian Dumitrescu 					file_name_default, line_id);
12155074e1d5SCristian Dumitrescu 				goto error;
12165074e1d5SCristian Dumitrescu 			}
12175074e1d5SCristian Dumitrescu 
12185074e1d5SCristian Dumitrescu 			status = rte_swx_ctl_pipeline_table_default_entry_add(p->ctl,
12195074e1d5SCristian Dumitrescu 				table_name,
12205074e1d5SCristian Dumitrescu 				entry);
1221275ebefeSCristian Dumitrescu 			table_entry_free(entry);
12225074e1d5SCristian Dumitrescu 			if (status) {
12235074e1d5SCristian Dumitrescu 				snprintf(out, out_size,
12245074e1d5SCristian Dumitrescu 					"Invalid entry in file %s at line %u",
12255074e1d5SCristian Dumitrescu 					file_name_default, line_id);
12265074e1d5SCristian Dumitrescu 				goto error;
12275074e1d5SCristian Dumitrescu 			}
12285074e1d5SCristian Dumitrescu 		}
12295074e1d5SCristian Dumitrescu 
12305074e1d5SCristian Dumitrescu 	status = rte_swx_ctl_pipeline_commit(p->ctl, 1);
12315074e1d5SCristian Dumitrescu 	if (status) {
12325074e1d5SCristian Dumitrescu 		snprintf(out, out_size, "Commit failed.");
12335074e1d5SCristian Dumitrescu 		goto error;
12345074e1d5SCristian Dumitrescu 	}
12355074e1d5SCristian Dumitrescu 
12365074e1d5SCristian Dumitrescu 
12375074e1d5SCristian Dumitrescu 	rte_swx_ctl_pipeline_table_fprintf(stdout, p->ctl, table_name);
12385074e1d5SCristian Dumitrescu 
123903665a48SCristian Dumitrescu 	free(line);
124003665a48SCristian Dumitrescu 	if (file_add)
124103665a48SCristian Dumitrescu 		fclose(file_add);
124203665a48SCristian Dumitrescu 	if (file_delete)
124303665a48SCristian Dumitrescu 		fclose(file_delete);
124403665a48SCristian Dumitrescu 	if (file_default)
124503665a48SCristian Dumitrescu 		fclose(file_default);
12465074e1d5SCristian Dumitrescu 	return;
12475074e1d5SCristian Dumitrescu 
12485074e1d5SCristian Dumitrescu error:
12495074e1d5SCristian Dumitrescu 	rte_swx_ctl_pipeline_abort(p->ctl);
12505074e1d5SCristian Dumitrescu 	free(line);
12515074e1d5SCristian Dumitrescu 	if (file_add)
12525074e1d5SCristian Dumitrescu 		fclose(file_add);
12535074e1d5SCristian Dumitrescu 	if (file_delete)
12545074e1d5SCristian Dumitrescu 		fclose(file_delete);
12555074e1d5SCristian Dumitrescu 	if (file_default)
12565074e1d5SCristian Dumitrescu 		fclose(file_default);
12575074e1d5SCristian Dumitrescu }
12585074e1d5SCristian Dumitrescu 
12595074e1d5SCristian Dumitrescu static const char cmd_pipeline_stats_help[] =
12605074e1d5SCristian Dumitrescu "pipeline <pipeline_name> stats\n";
12615074e1d5SCristian Dumitrescu 
12625074e1d5SCristian Dumitrescu static void
12635074e1d5SCristian Dumitrescu cmd_pipeline_stats(char **tokens,
12645074e1d5SCristian Dumitrescu 	uint32_t n_tokens,
12655074e1d5SCristian Dumitrescu 	char *out,
12665074e1d5SCristian Dumitrescu 	size_t out_size,
12675074e1d5SCristian Dumitrescu 	void *obj)
12685074e1d5SCristian Dumitrescu {
12695074e1d5SCristian Dumitrescu 	struct rte_swx_ctl_pipeline_info info;
12705074e1d5SCristian Dumitrescu 	struct pipeline *p;
12715074e1d5SCristian Dumitrescu 	uint32_t i;
12725074e1d5SCristian Dumitrescu 	int status;
12735074e1d5SCristian Dumitrescu 
12745074e1d5SCristian Dumitrescu 	if (n_tokens != 3) {
12755074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
12765074e1d5SCristian Dumitrescu 		return;
12775074e1d5SCristian Dumitrescu 	}
12785074e1d5SCristian Dumitrescu 
12795074e1d5SCristian Dumitrescu 	p = pipeline_find(obj, tokens[1]);
12805074e1d5SCristian Dumitrescu 	if (!p || !p->ctl) {
12815074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
12825074e1d5SCristian Dumitrescu 		return;
12835074e1d5SCristian Dumitrescu 	}
12845074e1d5SCristian Dumitrescu 
12855074e1d5SCristian Dumitrescu 	if (strcmp(tokens[2], "stats")) {
12865074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "stats");
12875074e1d5SCristian Dumitrescu 		return;
12885074e1d5SCristian Dumitrescu 	}
12895074e1d5SCristian Dumitrescu 
12905074e1d5SCristian Dumitrescu 	status = rte_swx_ctl_pipeline_info_get(p->p, &info);
12915074e1d5SCristian Dumitrescu 	if (status) {
12925074e1d5SCristian Dumitrescu 		snprintf(out, out_size, "Pipeline info get error.");
12935074e1d5SCristian Dumitrescu 		return;
12945074e1d5SCristian Dumitrescu 	}
12955074e1d5SCristian Dumitrescu 
12965074e1d5SCristian Dumitrescu 	snprintf(out, out_size, "Input ports:\n");
12975074e1d5SCristian Dumitrescu 	out_size -= strlen(out);
12985074e1d5SCristian Dumitrescu 	out += strlen(out);
12995074e1d5SCristian Dumitrescu 
13005074e1d5SCristian Dumitrescu 	for (i = 0; i < info.n_ports_in; i++) {
13015074e1d5SCristian Dumitrescu 		struct rte_swx_port_in_stats stats;
13025074e1d5SCristian Dumitrescu 
13035074e1d5SCristian Dumitrescu 		rte_swx_ctl_pipeline_port_in_stats_read(p->p, i, &stats);
13045074e1d5SCristian Dumitrescu 
13055074e1d5SCristian Dumitrescu 		snprintf(out, out_size, "\tPort %u:"
13065074e1d5SCristian Dumitrescu 			" packets %" PRIu64
13075074e1d5SCristian Dumitrescu 			" bytes %" PRIu64
13085074e1d5SCristian Dumitrescu 			" empty %" PRIu64 "\n",
13095074e1d5SCristian Dumitrescu 			i, stats.n_pkts, stats.n_bytes, stats.n_empty);
13105074e1d5SCristian Dumitrescu 		out_size -= strlen(out);
13115074e1d5SCristian Dumitrescu 		out += strlen(out);
13125074e1d5SCristian Dumitrescu 	}
13135074e1d5SCristian Dumitrescu 
13145074e1d5SCristian Dumitrescu 	snprintf(out, out_size, "Output ports:\n");
13155074e1d5SCristian Dumitrescu 	out_size -= strlen(out);
13165074e1d5SCristian Dumitrescu 	out += strlen(out);
13175074e1d5SCristian Dumitrescu 
13185074e1d5SCristian Dumitrescu 	for (i = 0; i < info.n_ports_out; i++) {
13195074e1d5SCristian Dumitrescu 		struct rte_swx_port_out_stats stats;
13205074e1d5SCristian Dumitrescu 
13215074e1d5SCristian Dumitrescu 		rte_swx_ctl_pipeline_port_out_stats_read(p->p, i, &stats);
13225074e1d5SCristian Dumitrescu 
13235074e1d5SCristian Dumitrescu 		snprintf(out, out_size, "\tPort %u:"
13245074e1d5SCristian Dumitrescu 			" packets %" PRIu64
13255074e1d5SCristian Dumitrescu 			" bytes %" PRIu64 "\n",
13265074e1d5SCristian Dumitrescu 			i, stats.n_pkts, stats.n_bytes);
13275074e1d5SCristian Dumitrescu 		out_size -= strlen(out);
13285074e1d5SCristian Dumitrescu 		out += strlen(out);
13295074e1d5SCristian Dumitrescu 	}
13305074e1d5SCristian Dumitrescu }
13315074e1d5SCristian Dumitrescu 
13325074e1d5SCristian Dumitrescu static const char cmd_thread_pipeline_enable_help[] =
13335074e1d5SCristian Dumitrescu "thread <thread_id> pipeline <pipeline_name> enable\n";
13345074e1d5SCristian Dumitrescu 
13355074e1d5SCristian Dumitrescu static void
13365074e1d5SCristian Dumitrescu cmd_thread_pipeline_enable(char **tokens,
13375074e1d5SCristian Dumitrescu 	uint32_t n_tokens,
13385074e1d5SCristian Dumitrescu 	char *out,
13395074e1d5SCristian Dumitrescu 	size_t out_size,
13405074e1d5SCristian Dumitrescu 	void *obj)
13415074e1d5SCristian Dumitrescu {
13425074e1d5SCristian Dumitrescu 	char *pipeline_name;
13435074e1d5SCristian Dumitrescu 	struct pipeline *p;
13445074e1d5SCristian Dumitrescu 	uint32_t thread_id;
13455074e1d5SCristian Dumitrescu 	int status;
13465074e1d5SCristian Dumitrescu 
13475074e1d5SCristian Dumitrescu 	if (n_tokens != 5) {
13485074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
13495074e1d5SCristian Dumitrescu 		return;
13505074e1d5SCristian Dumitrescu 	}
13515074e1d5SCristian Dumitrescu 
13525074e1d5SCristian Dumitrescu 	if (parser_read_uint32(&thread_id, tokens[1]) != 0) {
13535074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "thread_id");
13545074e1d5SCristian Dumitrescu 		return;
13555074e1d5SCristian Dumitrescu 	}
13565074e1d5SCristian Dumitrescu 
13575074e1d5SCristian Dumitrescu 	if (strcmp(tokens[2], "pipeline") != 0) {
13585074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pipeline");
13595074e1d5SCristian Dumitrescu 		return;
13605074e1d5SCristian Dumitrescu 	}
13615074e1d5SCristian Dumitrescu 
13625074e1d5SCristian Dumitrescu 	pipeline_name = tokens[3];
13635074e1d5SCristian Dumitrescu 	p = pipeline_find(obj, pipeline_name);
13645074e1d5SCristian Dumitrescu 	if (!p || !p->ctl) {
13655074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
13665074e1d5SCristian Dumitrescu 		return;
13675074e1d5SCristian Dumitrescu 	}
13685074e1d5SCristian Dumitrescu 
13695074e1d5SCristian Dumitrescu 	if (strcmp(tokens[4], "enable") != 0) {
13705074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "enable");
13715074e1d5SCristian Dumitrescu 		return;
13725074e1d5SCristian Dumitrescu 	}
13735074e1d5SCristian Dumitrescu 
13745074e1d5SCristian Dumitrescu 	status = thread_pipeline_enable(thread_id, obj, pipeline_name);
13755074e1d5SCristian Dumitrescu 	if (status) {
13765074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_CMD_FAIL, "thread pipeline enable");
13775074e1d5SCristian Dumitrescu 		return;
13785074e1d5SCristian Dumitrescu 	}
13795074e1d5SCristian Dumitrescu }
13805074e1d5SCristian Dumitrescu 
13815074e1d5SCristian Dumitrescu static const char cmd_thread_pipeline_disable_help[] =
13825074e1d5SCristian Dumitrescu "thread <thread_id> pipeline <pipeline_name> disable\n";
13835074e1d5SCristian Dumitrescu 
13845074e1d5SCristian Dumitrescu static void
13855074e1d5SCristian Dumitrescu cmd_thread_pipeline_disable(char **tokens,
13865074e1d5SCristian Dumitrescu 	uint32_t n_tokens,
13875074e1d5SCristian Dumitrescu 	char *out,
13885074e1d5SCristian Dumitrescu 	size_t out_size,
13895074e1d5SCristian Dumitrescu 	void *obj)
13905074e1d5SCristian Dumitrescu {
13915074e1d5SCristian Dumitrescu 	struct pipeline *p;
13925074e1d5SCristian Dumitrescu 	char *pipeline_name;
13935074e1d5SCristian Dumitrescu 	uint32_t thread_id;
13945074e1d5SCristian Dumitrescu 	int status;
13955074e1d5SCristian Dumitrescu 
13965074e1d5SCristian Dumitrescu 	if (n_tokens != 5) {
13975074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
13985074e1d5SCristian Dumitrescu 		return;
13995074e1d5SCristian Dumitrescu 	}
14005074e1d5SCristian Dumitrescu 
14015074e1d5SCristian Dumitrescu 	if (parser_read_uint32(&thread_id, tokens[1]) != 0) {
14025074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "thread_id");
14035074e1d5SCristian Dumitrescu 		return;
14045074e1d5SCristian Dumitrescu 	}
14055074e1d5SCristian Dumitrescu 
14065074e1d5SCristian Dumitrescu 	if (strcmp(tokens[2], "pipeline") != 0) {
14075074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pipeline");
14085074e1d5SCristian Dumitrescu 		return;
14095074e1d5SCristian Dumitrescu 	}
14105074e1d5SCristian Dumitrescu 
14115074e1d5SCristian Dumitrescu 	pipeline_name = tokens[3];
14125074e1d5SCristian Dumitrescu 	p = pipeline_find(obj, pipeline_name);
14135074e1d5SCristian Dumitrescu 	if (!p || !p->ctl) {
14145074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
14155074e1d5SCristian Dumitrescu 		return;
14165074e1d5SCristian Dumitrescu 	}
14175074e1d5SCristian Dumitrescu 
14185074e1d5SCristian Dumitrescu 	if (strcmp(tokens[4], "disable") != 0) {
14195074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "disable");
14205074e1d5SCristian Dumitrescu 		return;
14215074e1d5SCristian Dumitrescu 	}
14225074e1d5SCristian Dumitrescu 
14235074e1d5SCristian Dumitrescu 	status = thread_pipeline_disable(thread_id, obj, pipeline_name);
14245074e1d5SCristian Dumitrescu 	if (status) {
14255074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_CMD_FAIL,
14265074e1d5SCristian Dumitrescu 			"thread pipeline disable");
14275074e1d5SCristian Dumitrescu 		return;
14285074e1d5SCristian Dumitrescu 	}
14295074e1d5SCristian Dumitrescu }
14305074e1d5SCristian Dumitrescu 
14315074e1d5SCristian Dumitrescu static void
14325074e1d5SCristian Dumitrescu cmd_help(char **tokens,
14335074e1d5SCristian Dumitrescu 	 uint32_t n_tokens,
14345074e1d5SCristian Dumitrescu 	 char *out,
14355074e1d5SCristian Dumitrescu 	 size_t out_size,
14365074e1d5SCristian Dumitrescu 	 void *arg __rte_unused)
14375074e1d5SCristian Dumitrescu {
14385074e1d5SCristian Dumitrescu 	tokens++;
14395074e1d5SCristian Dumitrescu 	n_tokens--;
14405074e1d5SCristian Dumitrescu 
14415074e1d5SCristian Dumitrescu 	if (n_tokens == 0) {
14425074e1d5SCristian Dumitrescu 		snprintf(out, out_size,
14437fef9ef1SYogesh Jangra 			"Type 'help <command>' for command details.\n\n"
14447fef9ef1SYogesh Jangra 			"List of commands:\n"
14457fef9ef1SYogesh Jangra 			"\tmempool\n"
14467fef9ef1SYogesh Jangra 			"\tlink\n"
1447*e2b8dc52SVenkata Suresh Kumar P 			"\ttap\n"
14487fef9ef1SYogesh Jangra 			"\tpipeline create\n"
14497fef9ef1SYogesh Jangra 			"\tpipeline port in\n"
14507fef9ef1SYogesh Jangra 			"\tpipeline port out\n"
14517fef9ef1SYogesh Jangra 			"\tpipeline build\n"
14527fef9ef1SYogesh Jangra 			"\tpipeline table update\n"
14537fef9ef1SYogesh Jangra 			"\tpipeline stats\n"
14547fef9ef1SYogesh Jangra 			"\tthread pipeline enable\n"
14557fef9ef1SYogesh Jangra 			"\tthread pipeline disable\n\n");
14565074e1d5SCristian Dumitrescu 		return;
14575074e1d5SCristian Dumitrescu 	}
14585074e1d5SCristian Dumitrescu 
14595074e1d5SCristian Dumitrescu 	if (strcmp(tokens[0], "mempool") == 0) {
14605074e1d5SCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n", cmd_mempool_help);
14615074e1d5SCristian Dumitrescu 		return;
14625074e1d5SCristian Dumitrescu 	}
14635074e1d5SCristian Dumitrescu 
14645074e1d5SCristian Dumitrescu 	if (strcmp(tokens[0], "link") == 0) {
14655074e1d5SCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n", cmd_link_help);
14665074e1d5SCristian Dumitrescu 		return;
14675074e1d5SCristian Dumitrescu 	}
14685074e1d5SCristian Dumitrescu 
146977a41301SCristian Dumitrescu 	if (strcmp(tokens[0], "ring") == 0) {
147077a41301SCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n", cmd_ring_help);
147177a41301SCristian Dumitrescu 		return;
147277a41301SCristian Dumitrescu 	}
147377a41301SCristian Dumitrescu 
1474*e2b8dc52SVenkata Suresh Kumar P 	if (strcmp(tokens[0], "tap") == 0) {
1475*e2b8dc52SVenkata Suresh Kumar P 		snprintf(out, out_size, "\n%s\n", cmd_tap_help);
1476*e2b8dc52SVenkata Suresh Kumar P 		return;
1477*e2b8dc52SVenkata Suresh Kumar P 	}
1478*e2b8dc52SVenkata Suresh Kumar P 
14795074e1d5SCristian Dumitrescu 	if ((strcmp(tokens[0], "pipeline") == 0) &&
14807fef9ef1SYogesh Jangra 		(n_tokens == 2) && (strcmp(tokens[1], "create") == 0)) {
14815074e1d5SCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n", cmd_pipeline_create_help);
14825074e1d5SCristian Dumitrescu 		return;
14835074e1d5SCristian Dumitrescu 	}
14845074e1d5SCristian Dumitrescu 
14855074e1d5SCristian Dumitrescu 	if ((strcmp(tokens[0], "pipeline") == 0) &&
14867fef9ef1SYogesh Jangra 		(n_tokens == 3) && (strcmp(tokens[1], "port") == 0)) {
14877fef9ef1SYogesh Jangra 		if (strcmp(tokens[2], "in") == 0) {
14885074e1d5SCristian Dumitrescu 			snprintf(out, out_size, "\n%s\n",
14895074e1d5SCristian Dumitrescu 				cmd_pipeline_port_in_help);
14905074e1d5SCristian Dumitrescu 			return;
14915074e1d5SCristian Dumitrescu 		}
14925074e1d5SCristian Dumitrescu 
14937fef9ef1SYogesh Jangra 		if (strcmp(tokens[2], "out") == 0) {
14945074e1d5SCristian Dumitrescu 			snprintf(out, out_size, "\n%s\n",
14955074e1d5SCristian Dumitrescu 				cmd_pipeline_port_out_help);
14965074e1d5SCristian Dumitrescu 			return;
14975074e1d5SCristian Dumitrescu 		}
14985074e1d5SCristian Dumitrescu 	}
14995074e1d5SCristian Dumitrescu 
15005074e1d5SCristian Dumitrescu 	if ((strcmp(tokens[0], "pipeline") == 0) &&
15017fef9ef1SYogesh Jangra 		(n_tokens == 2) && (strcmp(tokens[1], "build") == 0)) {
15025074e1d5SCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n", cmd_pipeline_build_help);
15035074e1d5SCristian Dumitrescu 		return;
15045074e1d5SCristian Dumitrescu 	}
15055074e1d5SCristian Dumitrescu 
15065074e1d5SCristian Dumitrescu 	if ((strcmp(tokens[0], "pipeline") == 0) &&
15077fef9ef1SYogesh Jangra 		(n_tokens == 3) &&
15087fef9ef1SYogesh Jangra 		(strcmp(tokens[1], "table") == 0) &&
15097fef9ef1SYogesh Jangra 		(strcmp(tokens[2], "update") == 0)) {
15105074e1d5SCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n",
15115074e1d5SCristian Dumitrescu 			cmd_pipeline_table_update_help);
15125074e1d5SCristian Dumitrescu 		return;
15135074e1d5SCristian Dumitrescu 	}
15145074e1d5SCristian Dumitrescu 
15155074e1d5SCristian Dumitrescu 	if ((strcmp(tokens[0], "pipeline") == 0) &&
15167fef9ef1SYogesh Jangra 		(n_tokens == 2) && (strcmp(tokens[1], "stats") == 0)) {
15175074e1d5SCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n", cmd_pipeline_stats_help);
15185074e1d5SCristian Dumitrescu 		return;
15195074e1d5SCristian Dumitrescu 	}
15205074e1d5SCristian Dumitrescu 
15215074e1d5SCristian Dumitrescu 	if ((n_tokens == 3) &&
15225074e1d5SCristian Dumitrescu 		(strcmp(tokens[0], "thread") == 0) &&
15235074e1d5SCristian Dumitrescu 		(strcmp(tokens[1], "pipeline") == 0)) {
15245074e1d5SCristian Dumitrescu 		if (strcmp(tokens[2], "enable") == 0) {
15255074e1d5SCristian Dumitrescu 			snprintf(out, out_size, "\n%s\n",
15265074e1d5SCristian Dumitrescu 				cmd_thread_pipeline_enable_help);
15275074e1d5SCristian Dumitrescu 			return;
15285074e1d5SCristian Dumitrescu 		}
15295074e1d5SCristian Dumitrescu 
15305074e1d5SCristian Dumitrescu 		if (strcmp(tokens[2], "disable") == 0) {
15315074e1d5SCristian Dumitrescu 			snprintf(out, out_size, "\n%s\n",
15325074e1d5SCristian Dumitrescu 				cmd_thread_pipeline_disable_help);
15335074e1d5SCristian Dumitrescu 			return;
15345074e1d5SCristian Dumitrescu 		}
15355074e1d5SCristian Dumitrescu 	}
15365074e1d5SCristian Dumitrescu 
15375074e1d5SCristian Dumitrescu 	snprintf(out, out_size, "Invalid command\n");
15385074e1d5SCristian Dumitrescu }
15395074e1d5SCristian Dumitrescu 
15405074e1d5SCristian Dumitrescu void
15415074e1d5SCristian Dumitrescu cli_process(char *in, char *out, size_t out_size, void *obj)
15425074e1d5SCristian Dumitrescu {
15435074e1d5SCristian Dumitrescu 	char *tokens[CMD_MAX_TOKENS];
15445074e1d5SCristian Dumitrescu 	uint32_t n_tokens = RTE_DIM(tokens);
15455074e1d5SCristian Dumitrescu 	int status;
15465074e1d5SCristian Dumitrescu 
15475074e1d5SCristian Dumitrescu 	if (is_comment(in))
15485074e1d5SCristian Dumitrescu 		return;
15495074e1d5SCristian Dumitrescu 
15505074e1d5SCristian Dumitrescu 	status = parse_tokenize_string(in, tokens, &n_tokens);
15515074e1d5SCristian Dumitrescu 	if (status) {
15525074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_TOO_MANY, "");
15535074e1d5SCristian Dumitrescu 		return;
15545074e1d5SCristian Dumitrescu 	}
15555074e1d5SCristian Dumitrescu 
15565074e1d5SCristian Dumitrescu 	if (n_tokens == 0)
15575074e1d5SCristian Dumitrescu 		return;
15585074e1d5SCristian Dumitrescu 
15595074e1d5SCristian Dumitrescu 	if (strcmp(tokens[0], "help") == 0) {
15605074e1d5SCristian Dumitrescu 		cmd_help(tokens, n_tokens, out, out_size, obj);
15615074e1d5SCristian Dumitrescu 		return;
15625074e1d5SCristian Dumitrescu 	}
15635074e1d5SCristian Dumitrescu 
15645074e1d5SCristian Dumitrescu 	if (strcmp(tokens[0], "mempool") == 0) {
15655074e1d5SCristian Dumitrescu 		cmd_mempool(tokens, n_tokens, out, out_size, obj);
15665074e1d5SCristian Dumitrescu 		return;
15675074e1d5SCristian Dumitrescu 	}
15685074e1d5SCristian Dumitrescu 
15695074e1d5SCristian Dumitrescu 	if (strcmp(tokens[0], "link") == 0) {
1570821848f5SCristian Dumitrescu 		if ((n_tokens >= 2) && (strcmp(tokens[1], "show") == 0)) {
15715074e1d5SCristian Dumitrescu 			cmd_link_show(tokens, n_tokens, out, out_size, obj);
15725074e1d5SCristian Dumitrescu 			return;
15735074e1d5SCristian Dumitrescu 		}
15745074e1d5SCristian Dumitrescu 
15755074e1d5SCristian Dumitrescu 		cmd_link(tokens, n_tokens, out, out_size, obj);
15765074e1d5SCristian Dumitrescu 		return;
15775074e1d5SCristian Dumitrescu 	}
15785074e1d5SCristian Dumitrescu 
157977a41301SCristian Dumitrescu 	if (strcmp(tokens[0], "ring") == 0) {
158077a41301SCristian Dumitrescu 		cmd_ring(tokens, n_tokens, out, out_size, obj);
158177a41301SCristian Dumitrescu 		return;
158277a41301SCristian Dumitrescu 	}
158377a41301SCristian Dumitrescu 
1584*e2b8dc52SVenkata Suresh Kumar P 	if (strcmp(tokens[0], "tap") == 0) {
1585*e2b8dc52SVenkata Suresh Kumar P 		cmd_tap(tokens, n_tokens, out, out_size, obj);
1586*e2b8dc52SVenkata Suresh Kumar P 		return;
1587*e2b8dc52SVenkata Suresh Kumar P 	}
1588*e2b8dc52SVenkata Suresh Kumar P 
15895074e1d5SCristian Dumitrescu 	if (strcmp(tokens[0], "pipeline") == 0) {
15905074e1d5SCristian Dumitrescu 		if ((n_tokens >= 3) &&
15915074e1d5SCristian Dumitrescu 			(strcmp(tokens[2], "create") == 0)) {
15925074e1d5SCristian Dumitrescu 			cmd_pipeline_create(tokens, n_tokens, out, out_size,
15935074e1d5SCristian Dumitrescu 				obj);
15945074e1d5SCristian Dumitrescu 			return;
15955074e1d5SCristian Dumitrescu 		}
15965074e1d5SCristian Dumitrescu 
15975074e1d5SCristian Dumitrescu 		if ((n_tokens >= 4) &&
15985074e1d5SCristian Dumitrescu 			(strcmp(tokens[2], "port") == 0) &&
15995074e1d5SCristian Dumitrescu 			(strcmp(tokens[3], "in") == 0)) {
16005074e1d5SCristian Dumitrescu 			cmd_pipeline_port_in(tokens, n_tokens, out, out_size,
16015074e1d5SCristian Dumitrescu 				obj);
16025074e1d5SCristian Dumitrescu 			return;
16035074e1d5SCristian Dumitrescu 		}
16045074e1d5SCristian Dumitrescu 
16055074e1d5SCristian Dumitrescu 		if ((n_tokens >= 4) &&
16065074e1d5SCristian Dumitrescu 			(strcmp(tokens[2], "port") == 0) &&
16075074e1d5SCristian Dumitrescu 			(strcmp(tokens[3], "out") == 0)) {
16085074e1d5SCristian Dumitrescu 			cmd_pipeline_port_out(tokens, n_tokens, out, out_size,
16095074e1d5SCristian Dumitrescu 				obj);
16105074e1d5SCristian Dumitrescu 			return;
16115074e1d5SCristian Dumitrescu 		}
16125074e1d5SCristian Dumitrescu 
16135074e1d5SCristian Dumitrescu 		if ((n_tokens >= 3) &&
16145074e1d5SCristian Dumitrescu 			(strcmp(tokens[2], "build") == 0)) {
16155074e1d5SCristian Dumitrescu 			cmd_pipeline_build(tokens, n_tokens, out, out_size,
16165074e1d5SCristian Dumitrescu 				obj);
16175074e1d5SCristian Dumitrescu 			return;
16185074e1d5SCristian Dumitrescu 		}
16195074e1d5SCristian Dumitrescu 
16205074e1d5SCristian Dumitrescu 		if ((n_tokens >= 3) &&
16215074e1d5SCristian Dumitrescu 			(strcmp(tokens[2], "table") == 0)) {
16225074e1d5SCristian Dumitrescu 			cmd_pipeline_table_update(tokens, n_tokens, out,
16235074e1d5SCristian Dumitrescu 				out_size, obj);
16245074e1d5SCristian Dumitrescu 			return;
16255074e1d5SCristian Dumitrescu 		}
16265074e1d5SCristian Dumitrescu 
16275074e1d5SCristian Dumitrescu 		if ((n_tokens >= 3) &&
16285074e1d5SCristian Dumitrescu 			(strcmp(tokens[2], "stats") == 0)) {
16295074e1d5SCristian Dumitrescu 			cmd_pipeline_stats(tokens, n_tokens, out, out_size,
16305074e1d5SCristian Dumitrescu 				obj);
16315074e1d5SCristian Dumitrescu 			return;
16325074e1d5SCristian Dumitrescu 		}
16335074e1d5SCristian Dumitrescu 	}
16345074e1d5SCristian Dumitrescu 
16355074e1d5SCristian Dumitrescu 	if (strcmp(tokens[0], "thread") == 0) {
16365074e1d5SCristian Dumitrescu 		if ((n_tokens >= 5) &&
16375074e1d5SCristian Dumitrescu 			(strcmp(tokens[4], "enable") == 0)) {
16385074e1d5SCristian Dumitrescu 			cmd_thread_pipeline_enable(tokens, n_tokens,
16395074e1d5SCristian Dumitrescu 				out, out_size, obj);
16405074e1d5SCristian Dumitrescu 			return;
16415074e1d5SCristian Dumitrescu 		}
16425074e1d5SCristian Dumitrescu 
16435074e1d5SCristian Dumitrescu 		if ((n_tokens >= 5) &&
16445074e1d5SCristian Dumitrescu 			(strcmp(tokens[4], "disable") == 0)) {
16455074e1d5SCristian Dumitrescu 			cmd_thread_pipeline_disable(tokens, n_tokens,
16465074e1d5SCristian Dumitrescu 				out, out_size, obj);
16475074e1d5SCristian Dumitrescu 			return;
16485074e1d5SCristian Dumitrescu 		}
16495074e1d5SCristian Dumitrescu 	}
16505074e1d5SCristian Dumitrescu 
16515074e1d5SCristian Dumitrescu 	snprintf(out, out_size, MSG_CMD_UNKNOWN, tokens[0]);
16525074e1d5SCristian Dumitrescu }
16535074e1d5SCristian Dumitrescu 
16545074e1d5SCristian Dumitrescu int
16555074e1d5SCristian Dumitrescu cli_script_process(const char *file_name,
16565074e1d5SCristian Dumitrescu 	size_t msg_in_len_max,
16575074e1d5SCristian Dumitrescu 	size_t msg_out_len_max,
16585074e1d5SCristian Dumitrescu 	void *obj)
16595074e1d5SCristian Dumitrescu {
16605074e1d5SCristian Dumitrescu 	char *msg_in = NULL, *msg_out = NULL;
16615074e1d5SCristian Dumitrescu 	FILE *f = NULL;
16625074e1d5SCristian Dumitrescu 
16635074e1d5SCristian Dumitrescu 	/* Check input arguments */
16645074e1d5SCristian Dumitrescu 	if ((file_name == NULL) ||
16655074e1d5SCristian Dumitrescu 		(strlen(file_name) == 0) ||
16665074e1d5SCristian Dumitrescu 		(msg_in_len_max == 0) ||
16675074e1d5SCristian Dumitrescu 		(msg_out_len_max == 0))
16685074e1d5SCristian Dumitrescu 		return -EINVAL;
16695074e1d5SCristian Dumitrescu 
16705074e1d5SCristian Dumitrescu 	msg_in = malloc(msg_in_len_max + 1);
16715074e1d5SCristian Dumitrescu 	msg_out = malloc(msg_out_len_max + 1);
16725074e1d5SCristian Dumitrescu 	if ((msg_in == NULL) ||
16735074e1d5SCristian Dumitrescu 		(msg_out == NULL)) {
16745074e1d5SCristian Dumitrescu 		free(msg_out);
16755074e1d5SCristian Dumitrescu 		free(msg_in);
16765074e1d5SCristian Dumitrescu 		return -ENOMEM;
16775074e1d5SCristian Dumitrescu 	}
16785074e1d5SCristian Dumitrescu 
16795074e1d5SCristian Dumitrescu 	/* Open input file */
16805074e1d5SCristian Dumitrescu 	f = fopen(file_name, "r");
16815074e1d5SCristian Dumitrescu 	if (f == NULL) {
16825074e1d5SCristian Dumitrescu 		free(msg_out);
16835074e1d5SCristian Dumitrescu 		free(msg_in);
16845074e1d5SCristian Dumitrescu 		return -EIO;
16855074e1d5SCristian Dumitrescu 	}
16865074e1d5SCristian Dumitrescu 
16875074e1d5SCristian Dumitrescu 	/* Read file */
16885074e1d5SCristian Dumitrescu 	for ( ; ; ) {
16895074e1d5SCristian Dumitrescu 		if (fgets(msg_in, msg_in_len_max + 1, f) == NULL)
16905074e1d5SCristian Dumitrescu 			break;
16915074e1d5SCristian Dumitrescu 
16925074e1d5SCristian Dumitrescu 		printf("%s", msg_in);
16935074e1d5SCristian Dumitrescu 		msg_out[0] = 0;
16945074e1d5SCristian Dumitrescu 
16955074e1d5SCristian Dumitrescu 		cli_process(msg_in,
16965074e1d5SCristian Dumitrescu 			msg_out,
16975074e1d5SCristian Dumitrescu 			msg_out_len_max,
16985074e1d5SCristian Dumitrescu 			obj);
16995074e1d5SCristian Dumitrescu 
17005074e1d5SCristian Dumitrescu 		if (strlen(msg_out))
17015074e1d5SCristian Dumitrescu 			printf("%s", msg_out);
17025074e1d5SCristian Dumitrescu 	}
17035074e1d5SCristian Dumitrescu 
17045074e1d5SCristian Dumitrescu 	/* Close file */
17055074e1d5SCristian Dumitrescu 	fclose(f);
17065074e1d5SCristian Dumitrescu 	free(msg_out);
17075074e1d5SCristian Dumitrescu 	free(msg_in);
17085074e1d5SCristian Dumitrescu 	return 0;
17095074e1d5SCristian Dumitrescu }
1710