xref: /dpdk/examples/pipeline/cli.c (revision 64cfcebd6890fdc60c12eac09e1f066223a3d4e6)
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>
15e2b8dc52SVenkata 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 
580d644eb6SChurchill Khangar 	val = strtoul(p, &next, 0);
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 
497e2b8dc52SVenkata Suresh Kumar P static const char cmd_tap_help[] =
498e2b8dc52SVenkata Suresh Kumar P "tap <tap_name>\n";
499e2b8dc52SVenkata Suresh Kumar P 
500e2b8dc52SVenkata Suresh Kumar P static void
501e2b8dc52SVenkata Suresh Kumar P cmd_tap(char **tokens,
502e2b8dc52SVenkata Suresh Kumar P 	uint32_t n_tokens,
503e2b8dc52SVenkata Suresh Kumar P 	char *out,
504e2b8dc52SVenkata Suresh Kumar P 	size_t out_size,
505e2b8dc52SVenkata Suresh Kumar P 	void *obj)
506e2b8dc52SVenkata Suresh Kumar P {
507e2b8dc52SVenkata Suresh Kumar P 	struct tap *tap;
508e2b8dc52SVenkata Suresh Kumar P 	char *name;
509e2b8dc52SVenkata Suresh Kumar P 
510e2b8dc52SVenkata Suresh Kumar P 	if (n_tokens < 2) {
511e2b8dc52SVenkata Suresh Kumar P 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
512e2b8dc52SVenkata Suresh Kumar P 		return;
513e2b8dc52SVenkata Suresh Kumar P 	}
514e2b8dc52SVenkata Suresh Kumar P 	name = tokens[1];
515e2b8dc52SVenkata Suresh Kumar P 
516e2b8dc52SVenkata Suresh Kumar P 	tap = tap_create(obj, name);
517e2b8dc52SVenkata Suresh Kumar P 	if (tap == NULL) {
518e2b8dc52SVenkata Suresh Kumar P 		snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
519e2b8dc52SVenkata Suresh Kumar P 		return;
520e2b8dc52SVenkata Suresh Kumar P 	}
521e2b8dc52SVenkata Suresh Kumar P }
522e2b8dc52SVenkata 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"
560e2b8dc52SVenkata Suresh Kumar P "   | source <mempool_name> <file_name>\n"
561e2b8dc52SVenkata 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);
709e2b8dc52SVenkata Suresh Kumar P 	} else if (strcmp(tokens[t0], "tap") == 0) {
710e2b8dc52SVenkata Suresh Kumar P 		struct rte_swx_port_fd_reader_params params;
711e2b8dc52SVenkata Suresh Kumar P 		struct tap *tap;
712e2b8dc52SVenkata Suresh Kumar P 		struct mempool *mp;
713e2b8dc52SVenkata Suresh Kumar P 
714e2b8dc52SVenkata Suresh Kumar P 		if (n_tokens < t0 + 8) {
715e2b8dc52SVenkata Suresh Kumar P 			snprintf(out, out_size, MSG_ARG_MISMATCH,
716e2b8dc52SVenkata Suresh Kumar P 				"pipeline port in tap");
717e2b8dc52SVenkata Suresh Kumar P 			return;
718e2b8dc52SVenkata Suresh Kumar P 		}
719e2b8dc52SVenkata Suresh Kumar P 
720e2b8dc52SVenkata Suresh Kumar P 		tap = tap_find(obj, tokens[t0 + 1]);
721e2b8dc52SVenkata Suresh Kumar P 		if (!tap) {
722e2b8dc52SVenkata Suresh Kumar P 			snprintf(out, out_size, MSG_ARG_INVALID,
723e2b8dc52SVenkata Suresh Kumar P 				"tap_name");
724e2b8dc52SVenkata Suresh Kumar P 			return;
725e2b8dc52SVenkata Suresh Kumar P 		}
726e2b8dc52SVenkata Suresh Kumar P 		params.fd = tap->fd;
727e2b8dc52SVenkata Suresh Kumar P 
728e2b8dc52SVenkata Suresh Kumar P 		if (strcmp(tokens[t0 + 2], "mempool") != 0) {
729e2b8dc52SVenkata Suresh Kumar P 			snprintf(out, out_size, MSG_ARG_NOT_FOUND,
730e2b8dc52SVenkata Suresh Kumar P 				"mempool");
731e2b8dc52SVenkata Suresh Kumar P 			return;
732e2b8dc52SVenkata Suresh Kumar P 		}
733e2b8dc52SVenkata Suresh Kumar P 
734e2b8dc52SVenkata Suresh Kumar P 		mp = mempool_find(obj, tokens[t0 + 3]);
735e2b8dc52SVenkata Suresh Kumar P 		if (!mp) {
736e2b8dc52SVenkata Suresh Kumar P 			snprintf(out, out_size, MSG_ARG_INVALID,
737e2b8dc52SVenkata Suresh Kumar P 				"mempool_name");
738e2b8dc52SVenkata Suresh Kumar P 			return;
739e2b8dc52SVenkata Suresh Kumar P 		}
740e2b8dc52SVenkata Suresh Kumar P 		params.mempool = mp->m;
741e2b8dc52SVenkata Suresh Kumar P 
742e2b8dc52SVenkata Suresh Kumar P 		if (strcmp(tokens[t0 + 4], "mtu") != 0) {
743e2b8dc52SVenkata Suresh Kumar P 			snprintf(out, out_size, MSG_ARG_NOT_FOUND,
744e2b8dc52SVenkata Suresh Kumar P 				"mtu");
745e2b8dc52SVenkata Suresh Kumar P 			return;
746e2b8dc52SVenkata Suresh Kumar P 		}
747e2b8dc52SVenkata Suresh Kumar P 
748e2b8dc52SVenkata Suresh Kumar P 		if (parser_read_uint32(&params.mtu, tokens[t0 + 5]) != 0) {
749e2b8dc52SVenkata Suresh Kumar P 			snprintf(out, out_size, MSG_ARG_INVALID, "mtu");
750e2b8dc52SVenkata Suresh Kumar P 			return;
751e2b8dc52SVenkata Suresh Kumar P 		}
752e2b8dc52SVenkata Suresh Kumar P 
753e2b8dc52SVenkata Suresh Kumar P 		if (strcmp(tokens[t0 + 6], "bsz") != 0) {
754e2b8dc52SVenkata Suresh Kumar P 			snprintf(out, out_size, MSG_ARG_NOT_FOUND, "bsz");
755e2b8dc52SVenkata Suresh Kumar P 			return;
756e2b8dc52SVenkata Suresh Kumar P 		}
757e2b8dc52SVenkata Suresh Kumar P 
758e2b8dc52SVenkata Suresh Kumar P 		if (parser_read_uint32(&params.burst_size, tokens[t0 + 7])) {
759e2b8dc52SVenkata Suresh Kumar P 			snprintf(out, out_size, MSG_ARG_INVALID,
760e2b8dc52SVenkata Suresh Kumar P 				"burst_size");
761e2b8dc52SVenkata Suresh Kumar P 			return;
762e2b8dc52SVenkata Suresh Kumar P 		}
763e2b8dc52SVenkata Suresh Kumar P 
764e2b8dc52SVenkata Suresh Kumar P 		t0 += 8;
765e2b8dc52SVenkata Suresh Kumar P 
766e2b8dc52SVenkata Suresh Kumar P 		status = rte_swx_pipeline_port_in_config(p->p,
767e2b8dc52SVenkata Suresh Kumar P 			port_id,
768e2b8dc52SVenkata Suresh Kumar P 			"fd",
769e2b8dc52SVenkata Suresh Kumar P 			&params);
770e2b8dc52SVenkata 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"
791e2b8dc52SVenkata Suresh Kumar P "   | sink <file_name> | none\n"
792e2b8dc52SVenkata 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);
926e2b8dc52SVenkata Suresh Kumar P 	} else if (strcmp(tokens[t0], "tap") == 0) {
927e2b8dc52SVenkata Suresh Kumar P 		struct rte_swx_port_fd_writer_params params;
928e2b8dc52SVenkata Suresh Kumar P 		struct tap *tap;
929e2b8dc52SVenkata Suresh Kumar P 
930e2b8dc52SVenkata Suresh Kumar P 		if (n_tokens < t0 + 4) {
931e2b8dc52SVenkata Suresh Kumar P 			snprintf(out, out_size, MSG_ARG_MISMATCH,
932e2b8dc52SVenkata Suresh Kumar P 				"pipeline port out tap");
933e2b8dc52SVenkata Suresh Kumar P 			return;
934e2b8dc52SVenkata Suresh Kumar P 		}
935e2b8dc52SVenkata Suresh Kumar P 
936e2b8dc52SVenkata Suresh Kumar P 		tap = tap_find(obj, tokens[t0 + 1]);
937e2b8dc52SVenkata Suresh Kumar P 		if (!tap) {
938e2b8dc52SVenkata Suresh Kumar P 			snprintf(out, out_size, MSG_ARG_INVALID,
939e2b8dc52SVenkata Suresh Kumar P 				"tap_name");
940e2b8dc52SVenkata Suresh Kumar P 			return;
941e2b8dc52SVenkata Suresh Kumar P 		}
942e2b8dc52SVenkata Suresh Kumar P 		params.fd = tap->fd;
943e2b8dc52SVenkata Suresh Kumar P 
944e2b8dc52SVenkata Suresh Kumar P 		if (strcmp(tokens[t0 + 2], "bsz") != 0) {
945e2b8dc52SVenkata Suresh Kumar P 			snprintf(out, out_size, MSG_ARG_NOT_FOUND, "bsz");
946e2b8dc52SVenkata Suresh Kumar P 			return;
947e2b8dc52SVenkata Suresh Kumar P 		}
948e2b8dc52SVenkata Suresh Kumar P 
949e2b8dc52SVenkata Suresh Kumar P 		if (parser_read_uint32(&params.burst_size, tokens[t0 + 3])) {
950e2b8dc52SVenkata Suresh Kumar P 			snprintf(out, out_size, MSG_ARG_INVALID,
951e2b8dc52SVenkata Suresh Kumar P 				"burst_size");
952e2b8dc52SVenkata Suresh Kumar P 			return;
953e2b8dc52SVenkata Suresh Kumar P 		}
954e2b8dc52SVenkata Suresh Kumar P 
955e2b8dc52SVenkata Suresh Kumar P 		t0 += 4;
956e2b8dc52SVenkata Suresh Kumar P 
957e2b8dc52SVenkata Suresh Kumar P 		status = rte_swx_pipeline_port_out_config(p->p,
958e2b8dc52SVenkata Suresh Kumar P 			port_id,
959e2b8dc52SVenkata Suresh Kumar P 			"fd",
960e2b8dc52SVenkata 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 
1259*64cfcebdSCristian Dumitrescu static const char cmd_pipeline_regrd_help[] =
1260*64cfcebdSCristian Dumitrescu "pipeline <pipeline_name> regrd <register_array_name> <index>\n";
1261*64cfcebdSCristian Dumitrescu 
1262*64cfcebdSCristian Dumitrescu static void
1263*64cfcebdSCristian Dumitrescu cmd_pipeline_regrd(char **tokens,
1264*64cfcebdSCristian Dumitrescu 	uint32_t n_tokens,
1265*64cfcebdSCristian Dumitrescu 	char *out,
1266*64cfcebdSCristian Dumitrescu 	size_t out_size,
1267*64cfcebdSCristian Dumitrescu 	void *obj)
1268*64cfcebdSCristian Dumitrescu {
1269*64cfcebdSCristian Dumitrescu 	struct pipeline *p;
1270*64cfcebdSCristian Dumitrescu 	const char *name;
1271*64cfcebdSCristian Dumitrescu 	uint64_t value;
1272*64cfcebdSCristian Dumitrescu 	uint32_t idx;
1273*64cfcebdSCristian Dumitrescu 	int status;
1274*64cfcebdSCristian Dumitrescu 
1275*64cfcebdSCristian Dumitrescu 	if (n_tokens != 5) {
1276*64cfcebdSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1277*64cfcebdSCristian Dumitrescu 		return;
1278*64cfcebdSCristian Dumitrescu 	}
1279*64cfcebdSCristian Dumitrescu 
1280*64cfcebdSCristian Dumitrescu 	p = pipeline_find(obj, tokens[1]);
1281*64cfcebdSCristian Dumitrescu 	if (!p || !p->ctl) {
1282*64cfcebdSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
1283*64cfcebdSCristian Dumitrescu 		return;
1284*64cfcebdSCristian Dumitrescu 	}
1285*64cfcebdSCristian Dumitrescu 
1286*64cfcebdSCristian Dumitrescu 	if (strcmp(tokens[2], "regrd")) {
1287*64cfcebdSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "regrd");
1288*64cfcebdSCristian Dumitrescu 		return;
1289*64cfcebdSCristian Dumitrescu 	}
1290*64cfcebdSCristian Dumitrescu 
1291*64cfcebdSCristian Dumitrescu 	name = tokens[3];
1292*64cfcebdSCristian Dumitrescu 
1293*64cfcebdSCristian Dumitrescu 	if (parser_read_uint32(&idx, tokens[4])) {
1294*64cfcebdSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "index");
1295*64cfcebdSCristian Dumitrescu 		return;
1296*64cfcebdSCristian Dumitrescu 	}
1297*64cfcebdSCristian Dumitrescu 
1298*64cfcebdSCristian Dumitrescu 	status = rte_swx_ctl_pipeline_regarray_read(p->p, name, idx, &value);
1299*64cfcebdSCristian Dumitrescu 	if (status) {
1300*64cfcebdSCristian Dumitrescu 		snprintf(out, out_size, "Command failed.\n");
1301*64cfcebdSCristian Dumitrescu 		return;
1302*64cfcebdSCristian Dumitrescu 	}
1303*64cfcebdSCristian Dumitrescu 
1304*64cfcebdSCristian Dumitrescu 	snprintf(out, out_size, "0x%" PRIx64 "\n", value);
1305*64cfcebdSCristian Dumitrescu }
1306*64cfcebdSCristian Dumitrescu 
1307*64cfcebdSCristian Dumitrescu static const char cmd_pipeline_regwr_help[] =
1308*64cfcebdSCristian Dumitrescu "pipeline <pipeline_name> regwr <register_array_name> <index> <value>\n";
1309*64cfcebdSCristian Dumitrescu 
1310*64cfcebdSCristian Dumitrescu static void
1311*64cfcebdSCristian Dumitrescu cmd_pipeline_regwr(char **tokens,
1312*64cfcebdSCristian Dumitrescu 	uint32_t n_tokens,
1313*64cfcebdSCristian Dumitrescu 	char *out,
1314*64cfcebdSCristian Dumitrescu 	size_t out_size,
1315*64cfcebdSCristian Dumitrescu 	void *obj)
1316*64cfcebdSCristian Dumitrescu {
1317*64cfcebdSCristian Dumitrescu 	struct pipeline *p;
1318*64cfcebdSCristian Dumitrescu 	const char *name;
1319*64cfcebdSCristian Dumitrescu 	uint64_t value;
1320*64cfcebdSCristian Dumitrescu 	uint32_t idx;
1321*64cfcebdSCristian Dumitrescu 	int status;
1322*64cfcebdSCristian Dumitrescu 
1323*64cfcebdSCristian Dumitrescu 	if (n_tokens != 6) {
1324*64cfcebdSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1325*64cfcebdSCristian Dumitrescu 		return;
1326*64cfcebdSCristian Dumitrescu 	}
1327*64cfcebdSCristian Dumitrescu 
1328*64cfcebdSCristian Dumitrescu 	p = pipeline_find(obj, tokens[1]);
1329*64cfcebdSCristian Dumitrescu 	if (!p || !p->ctl) {
1330*64cfcebdSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
1331*64cfcebdSCristian Dumitrescu 		return;
1332*64cfcebdSCristian Dumitrescu 	}
1333*64cfcebdSCristian Dumitrescu 
1334*64cfcebdSCristian Dumitrescu 	if (strcmp(tokens[2], "regwr")) {
1335*64cfcebdSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "regwr");
1336*64cfcebdSCristian Dumitrescu 		return;
1337*64cfcebdSCristian Dumitrescu 	}
1338*64cfcebdSCristian Dumitrescu 
1339*64cfcebdSCristian Dumitrescu 	name = tokens[3];
1340*64cfcebdSCristian Dumitrescu 
1341*64cfcebdSCristian Dumitrescu 	if (parser_read_uint32(&idx, tokens[4])) {
1342*64cfcebdSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "index");
1343*64cfcebdSCristian Dumitrescu 		return;
1344*64cfcebdSCristian Dumitrescu 	}
1345*64cfcebdSCristian Dumitrescu 
1346*64cfcebdSCristian Dumitrescu 	if (parser_read_uint64(&value, tokens[5])) {
1347*64cfcebdSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "value");
1348*64cfcebdSCristian Dumitrescu 		return;
1349*64cfcebdSCristian Dumitrescu 	}
1350*64cfcebdSCristian Dumitrescu 
1351*64cfcebdSCristian Dumitrescu 	status = rte_swx_ctl_pipeline_regarray_write(p->p, name, idx, value);
1352*64cfcebdSCristian Dumitrescu 	if (status) {
1353*64cfcebdSCristian Dumitrescu 		snprintf(out, out_size, "Command failed.\n");
1354*64cfcebdSCristian Dumitrescu 		return;
1355*64cfcebdSCristian Dumitrescu 	}
1356*64cfcebdSCristian Dumitrescu }
1357*64cfcebdSCristian Dumitrescu 
13585074e1d5SCristian Dumitrescu static const char cmd_pipeline_stats_help[] =
13595074e1d5SCristian Dumitrescu "pipeline <pipeline_name> stats\n";
13605074e1d5SCristian Dumitrescu 
13615074e1d5SCristian Dumitrescu static void
13625074e1d5SCristian Dumitrescu cmd_pipeline_stats(char **tokens,
13635074e1d5SCristian Dumitrescu 	uint32_t n_tokens,
13645074e1d5SCristian Dumitrescu 	char *out,
13655074e1d5SCristian Dumitrescu 	size_t out_size,
13665074e1d5SCristian Dumitrescu 	void *obj)
13675074e1d5SCristian Dumitrescu {
13685074e1d5SCristian Dumitrescu 	struct rte_swx_ctl_pipeline_info info;
13695074e1d5SCristian Dumitrescu 	struct pipeline *p;
13705074e1d5SCristian Dumitrescu 	uint32_t i;
13715074e1d5SCristian Dumitrescu 	int status;
13725074e1d5SCristian Dumitrescu 
13735074e1d5SCristian Dumitrescu 	if (n_tokens != 3) {
13745074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
13755074e1d5SCristian Dumitrescu 		return;
13765074e1d5SCristian Dumitrescu 	}
13775074e1d5SCristian Dumitrescu 
13785074e1d5SCristian Dumitrescu 	p = pipeline_find(obj, tokens[1]);
13795074e1d5SCristian Dumitrescu 	if (!p || !p->ctl) {
13805074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
13815074e1d5SCristian Dumitrescu 		return;
13825074e1d5SCristian Dumitrescu 	}
13835074e1d5SCristian Dumitrescu 
13845074e1d5SCristian Dumitrescu 	if (strcmp(tokens[2], "stats")) {
13855074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "stats");
13865074e1d5SCristian Dumitrescu 		return;
13875074e1d5SCristian Dumitrescu 	}
13885074e1d5SCristian Dumitrescu 
13895074e1d5SCristian Dumitrescu 	status = rte_swx_ctl_pipeline_info_get(p->p, &info);
13905074e1d5SCristian Dumitrescu 	if (status) {
13915074e1d5SCristian Dumitrescu 		snprintf(out, out_size, "Pipeline info get error.");
13925074e1d5SCristian Dumitrescu 		return;
13935074e1d5SCristian Dumitrescu 	}
13945074e1d5SCristian Dumitrescu 
13955074e1d5SCristian Dumitrescu 	snprintf(out, out_size, "Input ports:\n");
13965074e1d5SCristian Dumitrescu 	out_size -= strlen(out);
13975074e1d5SCristian Dumitrescu 	out += strlen(out);
13985074e1d5SCristian Dumitrescu 
13995074e1d5SCristian Dumitrescu 	for (i = 0; i < info.n_ports_in; i++) {
14005074e1d5SCristian Dumitrescu 		struct rte_swx_port_in_stats stats;
14015074e1d5SCristian Dumitrescu 
14025074e1d5SCristian Dumitrescu 		rte_swx_ctl_pipeline_port_in_stats_read(p->p, i, &stats);
14035074e1d5SCristian Dumitrescu 
14045074e1d5SCristian Dumitrescu 		snprintf(out, out_size, "\tPort %u:"
14055074e1d5SCristian Dumitrescu 			" packets %" PRIu64
14065074e1d5SCristian Dumitrescu 			" bytes %" PRIu64
14075074e1d5SCristian Dumitrescu 			" empty %" PRIu64 "\n",
14085074e1d5SCristian Dumitrescu 			i, stats.n_pkts, stats.n_bytes, stats.n_empty);
14095074e1d5SCristian Dumitrescu 		out_size -= strlen(out);
14105074e1d5SCristian Dumitrescu 		out += strlen(out);
14115074e1d5SCristian Dumitrescu 	}
14125074e1d5SCristian Dumitrescu 
14135074e1d5SCristian Dumitrescu 	snprintf(out, out_size, "Output ports:\n");
14145074e1d5SCristian Dumitrescu 	out_size -= strlen(out);
14155074e1d5SCristian Dumitrescu 	out += strlen(out);
14165074e1d5SCristian Dumitrescu 
14175074e1d5SCristian Dumitrescu 	for (i = 0; i < info.n_ports_out; i++) {
14185074e1d5SCristian Dumitrescu 		struct rte_swx_port_out_stats stats;
14195074e1d5SCristian Dumitrescu 
14205074e1d5SCristian Dumitrescu 		rte_swx_ctl_pipeline_port_out_stats_read(p->p, i, &stats);
14215074e1d5SCristian Dumitrescu 
14225074e1d5SCristian Dumitrescu 		snprintf(out, out_size, "\tPort %u:"
14235074e1d5SCristian Dumitrescu 			" packets %" PRIu64
14245074e1d5SCristian Dumitrescu 			" bytes %" PRIu64 "\n",
14255074e1d5SCristian Dumitrescu 			i, stats.n_pkts, stats.n_bytes);
14265074e1d5SCristian Dumitrescu 		out_size -= strlen(out);
14275074e1d5SCristian Dumitrescu 		out += strlen(out);
14285074e1d5SCristian Dumitrescu 	}
14295074e1d5SCristian Dumitrescu }
14305074e1d5SCristian Dumitrescu 
14315074e1d5SCristian Dumitrescu static const char cmd_thread_pipeline_enable_help[] =
14325074e1d5SCristian Dumitrescu "thread <thread_id> pipeline <pipeline_name> enable\n";
14335074e1d5SCristian Dumitrescu 
14345074e1d5SCristian Dumitrescu static void
14355074e1d5SCristian Dumitrescu cmd_thread_pipeline_enable(char **tokens,
14365074e1d5SCristian Dumitrescu 	uint32_t n_tokens,
14375074e1d5SCristian Dumitrescu 	char *out,
14385074e1d5SCristian Dumitrescu 	size_t out_size,
14395074e1d5SCristian Dumitrescu 	void *obj)
14405074e1d5SCristian Dumitrescu {
14415074e1d5SCristian Dumitrescu 	char *pipeline_name;
14425074e1d5SCristian Dumitrescu 	struct pipeline *p;
14435074e1d5SCristian Dumitrescu 	uint32_t thread_id;
14445074e1d5SCristian Dumitrescu 	int status;
14455074e1d5SCristian Dumitrescu 
14465074e1d5SCristian Dumitrescu 	if (n_tokens != 5) {
14475074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
14485074e1d5SCristian Dumitrescu 		return;
14495074e1d5SCristian Dumitrescu 	}
14505074e1d5SCristian Dumitrescu 
14515074e1d5SCristian Dumitrescu 	if (parser_read_uint32(&thread_id, tokens[1]) != 0) {
14525074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "thread_id");
14535074e1d5SCristian Dumitrescu 		return;
14545074e1d5SCristian Dumitrescu 	}
14555074e1d5SCristian Dumitrescu 
14565074e1d5SCristian Dumitrescu 	if (strcmp(tokens[2], "pipeline") != 0) {
14575074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pipeline");
14585074e1d5SCristian Dumitrescu 		return;
14595074e1d5SCristian Dumitrescu 	}
14605074e1d5SCristian Dumitrescu 
14615074e1d5SCristian Dumitrescu 	pipeline_name = tokens[3];
14625074e1d5SCristian Dumitrescu 	p = pipeline_find(obj, pipeline_name);
14635074e1d5SCristian Dumitrescu 	if (!p || !p->ctl) {
14645074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
14655074e1d5SCristian Dumitrescu 		return;
14665074e1d5SCristian Dumitrescu 	}
14675074e1d5SCristian Dumitrescu 
14685074e1d5SCristian Dumitrescu 	if (strcmp(tokens[4], "enable") != 0) {
14695074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "enable");
14705074e1d5SCristian Dumitrescu 		return;
14715074e1d5SCristian Dumitrescu 	}
14725074e1d5SCristian Dumitrescu 
14735074e1d5SCristian Dumitrescu 	status = thread_pipeline_enable(thread_id, obj, pipeline_name);
14745074e1d5SCristian Dumitrescu 	if (status) {
14755074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_CMD_FAIL, "thread pipeline enable");
14765074e1d5SCristian Dumitrescu 		return;
14775074e1d5SCristian Dumitrescu 	}
14785074e1d5SCristian Dumitrescu }
14795074e1d5SCristian Dumitrescu 
14805074e1d5SCristian Dumitrescu static const char cmd_thread_pipeline_disable_help[] =
14815074e1d5SCristian Dumitrescu "thread <thread_id> pipeline <pipeline_name> disable\n";
14825074e1d5SCristian Dumitrescu 
14835074e1d5SCristian Dumitrescu static void
14845074e1d5SCristian Dumitrescu cmd_thread_pipeline_disable(char **tokens,
14855074e1d5SCristian Dumitrescu 	uint32_t n_tokens,
14865074e1d5SCristian Dumitrescu 	char *out,
14875074e1d5SCristian Dumitrescu 	size_t out_size,
14885074e1d5SCristian Dumitrescu 	void *obj)
14895074e1d5SCristian Dumitrescu {
14905074e1d5SCristian Dumitrescu 	struct pipeline *p;
14915074e1d5SCristian Dumitrescu 	char *pipeline_name;
14925074e1d5SCristian Dumitrescu 	uint32_t thread_id;
14935074e1d5SCristian Dumitrescu 	int status;
14945074e1d5SCristian Dumitrescu 
14955074e1d5SCristian Dumitrescu 	if (n_tokens != 5) {
14965074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
14975074e1d5SCristian Dumitrescu 		return;
14985074e1d5SCristian Dumitrescu 	}
14995074e1d5SCristian Dumitrescu 
15005074e1d5SCristian Dumitrescu 	if (parser_read_uint32(&thread_id, tokens[1]) != 0) {
15015074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "thread_id");
15025074e1d5SCristian Dumitrescu 		return;
15035074e1d5SCristian Dumitrescu 	}
15045074e1d5SCristian Dumitrescu 
15055074e1d5SCristian Dumitrescu 	if (strcmp(tokens[2], "pipeline") != 0) {
15065074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pipeline");
15075074e1d5SCristian Dumitrescu 		return;
15085074e1d5SCristian Dumitrescu 	}
15095074e1d5SCristian Dumitrescu 
15105074e1d5SCristian Dumitrescu 	pipeline_name = tokens[3];
15115074e1d5SCristian Dumitrescu 	p = pipeline_find(obj, pipeline_name);
15125074e1d5SCristian Dumitrescu 	if (!p || !p->ctl) {
15135074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
15145074e1d5SCristian Dumitrescu 		return;
15155074e1d5SCristian Dumitrescu 	}
15165074e1d5SCristian Dumitrescu 
15175074e1d5SCristian Dumitrescu 	if (strcmp(tokens[4], "disable") != 0) {
15185074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "disable");
15195074e1d5SCristian Dumitrescu 		return;
15205074e1d5SCristian Dumitrescu 	}
15215074e1d5SCristian Dumitrescu 
15225074e1d5SCristian Dumitrescu 	status = thread_pipeline_disable(thread_id, obj, pipeline_name);
15235074e1d5SCristian Dumitrescu 	if (status) {
15245074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_CMD_FAIL,
15255074e1d5SCristian Dumitrescu 			"thread pipeline disable");
15265074e1d5SCristian Dumitrescu 		return;
15275074e1d5SCristian Dumitrescu 	}
15285074e1d5SCristian Dumitrescu }
15295074e1d5SCristian Dumitrescu 
15305074e1d5SCristian Dumitrescu static void
15315074e1d5SCristian Dumitrescu cmd_help(char **tokens,
15325074e1d5SCristian Dumitrescu 	 uint32_t n_tokens,
15335074e1d5SCristian Dumitrescu 	 char *out,
15345074e1d5SCristian Dumitrescu 	 size_t out_size,
15355074e1d5SCristian Dumitrescu 	 void *arg __rte_unused)
15365074e1d5SCristian Dumitrescu {
15375074e1d5SCristian Dumitrescu 	tokens++;
15385074e1d5SCristian Dumitrescu 	n_tokens--;
15395074e1d5SCristian Dumitrescu 
15405074e1d5SCristian Dumitrescu 	if (n_tokens == 0) {
15415074e1d5SCristian Dumitrescu 		snprintf(out, out_size,
15427fef9ef1SYogesh Jangra 			"Type 'help <command>' for command details.\n\n"
15437fef9ef1SYogesh Jangra 			"List of commands:\n"
15447fef9ef1SYogesh Jangra 			"\tmempool\n"
15457fef9ef1SYogesh Jangra 			"\tlink\n"
1546e2b8dc52SVenkata Suresh Kumar P 			"\ttap\n"
15477fef9ef1SYogesh Jangra 			"\tpipeline create\n"
15487fef9ef1SYogesh Jangra 			"\tpipeline port in\n"
15497fef9ef1SYogesh Jangra 			"\tpipeline port out\n"
15507fef9ef1SYogesh Jangra 			"\tpipeline build\n"
15517fef9ef1SYogesh Jangra 			"\tpipeline table update\n"
1552*64cfcebdSCristian Dumitrescu 			"\tpipeline regrd\n"
1553*64cfcebdSCristian Dumitrescu 			"\tpipeline regwr\n"
15547fef9ef1SYogesh Jangra 			"\tpipeline stats\n"
15557fef9ef1SYogesh Jangra 			"\tthread pipeline enable\n"
15567fef9ef1SYogesh Jangra 			"\tthread pipeline disable\n\n");
15575074e1d5SCristian Dumitrescu 		return;
15585074e1d5SCristian Dumitrescu 	}
15595074e1d5SCristian Dumitrescu 
15605074e1d5SCristian Dumitrescu 	if (strcmp(tokens[0], "mempool") == 0) {
15615074e1d5SCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n", cmd_mempool_help);
15625074e1d5SCristian Dumitrescu 		return;
15635074e1d5SCristian Dumitrescu 	}
15645074e1d5SCristian Dumitrescu 
15655074e1d5SCristian Dumitrescu 	if (strcmp(tokens[0], "link") == 0) {
15665074e1d5SCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n", cmd_link_help);
15675074e1d5SCristian Dumitrescu 		return;
15685074e1d5SCristian Dumitrescu 	}
15695074e1d5SCristian Dumitrescu 
157077a41301SCristian Dumitrescu 	if (strcmp(tokens[0], "ring") == 0) {
157177a41301SCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n", cmd_ring_help);
157277a41301SCristian Dumitrescu 		return;
157377a41301SCristian Dumitrescu 	}
157477a41301SCristian Dumitrescu 
1575e2b8dc52SVenkata Suresh Kumar P 	if (strcmp(tokens[0], "tap") == 0) {
1576e2b8dc52SVenkata Suresh Kumar P 		snprintf(out, out_size, "\n%s\n", cmd_tap_help);
1577e2b8dc52SVenkata Suresh Kumar P 		return;
1578e2b8dc52SVenkata Suresh Kumar P 	}
1579e2b8dc52SVenkata Suresh Kumar P 
15805074e1d5SCristian Dumitrescu 	if ((strcmp(tokens[0], "pipeline") == 0) &&
15817fef9ef1SYogesh Jangra 		(n_tokens == 2) && (strcmp(tokens[1], "create") == 0)) {
15825074e1d5SCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n", cmd_pipeline_create_help);
15835074e1d5SCristian Dumitrescu 		return;
15845074e1d5SCristian Dumitrescu 	}
15855074e1d5SCristian Dumitrescu 
15865074e1d5SCristian Dumitrescu 	if ((strcmp(tokens[0], "pipeline") == 0) &&
15877fef9ef1SYogesh Jangra 		(n_tokens == 3) && (strcmp(tokens[1], "port") == 0)) {
15887fef9ef1SYogesh Jangra 		if (strcmp(tokens[2], "in") == 0) {
15895074e1d5SCristian Dumitrescu 			snprintf(out, out_size, "\n%s\n",
15905074e1d5SCristian Dumitrescu 				cmd_pipeline_port_in_help);
15915074e1d5SCristian Dumitrescu 			return;
15925074e1d5SCristian Dumitrescu 		}
15935074e1d5SCristian Dumitrescu 
15947fef9ef1SYogesh Jangra 		if (strcmp(tokens[2], "out") == 0) {
15955074e1d5SCristian Dumitrescu 			snprintf(out, out_size, "\n%s\n",
15965074e1d5SCristian Dumitrescu 				cmd_pipeline_port_out_help);
15975074e1d5SCristian Dumitrescu 			return;
15985074e1d5SCristian Dumitrescu 		}
15995074e1d5SCristian Dumitrescu 	}
16005074e1d5SCristian Dumitrescu 
16015074e1d5SCristian Dumitrescu 	if ((strcmp(tokens[0], "pipeline") == 0) &&
16027fef9ef1SYogesh Jangra 		(n_tokens == 2) && (strcmp(tokens[1], "build") == 0)) {
16035074e1d5SCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n", cmd_pipeline_build_help);
16045074e1d5SCristian Dumitrescu 		return;
16055074e1d5SCristian Dumitrescu 	}
16065074e1d5SCristian Dumitrescu 
16075074e1d5SCristian Dumitrescu 	if ((strcmp(tokens[0], "pipeline") == 0) &&
16087fef9ef1SYogesh Jangra 		(n_tokens == 3) &&
16097fef9ef1SYogesh Jangra 		(strcmp(tokens[1], "table") == 0) &&
16107fef9ef1SYogesh Jangra 		(strcmp(tokens[2], "update") == 0)) {
16115074e1d5SCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n",
16125074e1d5SCristian Dumitrescu 			cmd_pipeline_table_update_help);
16135074e1d5SCristian Dumitrescu 		return;
16145074e1d5SCristian Dumitrescu 	}
16155074e1d5SCristian Dumitrescu 
16165074e1d5SCristian Dumitrescu 	if ((strcmp(tokens[0], "pipeline") == 0) &&
1617*64cfcebdSCristian Dumitrescu 		(n_tokens == 2) && (strcmp(tokens[1], "regrd") == 0)) {
1618*64cfcebdSCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n", cmd_pipeline_regrd_help);
1619*64cfcebdSCristian Dumitrescu 		return;
1620*64cfcebdSCristian Dumitrescu 	}
1621*64cfcebdSCristian Dumitrescu 
1622*64cfcebdSCristian Dumitrescu 	if ((strcmp(tokens[0], "pipeline") == 0) &&
1623*64cfcebdSCristian Dumitrescu 		(n_tokens == 2) && (strcmp(tokens[1], "regwr") == 0)) {
1624*64cfcebdSCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n", cmd_pipeline_regwr_help);
1625*64cfcebdSCristian Dumitrescu 		return;
1626*64cfcebdSCristian Dumitrescu 	}
1627*64cfcebdSCristian Dumitrescu 
1628*64cfcebdSCristian Dumitrescu 	if ((strcmp(tokens[0], "pipeline") == 0) &&
16297fef9ef1SYogesh Jangra 		(n_tokens == 2) && (strcmp(tokens[1], "stats") == 0)) {
16305074e1d5SCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n", cmd_pipeline_stats_help);
16315074e1d5SCristian Dumitrescu 		return;
16325074e1d5SCristian Dumitrescu 	}
16335074e1d5SCristian Dumitrescu 
16345074e1d5SCristian Dumitrescu 	if ((n_tokens == 3) &&
16355074e1d5SCristian Dumitrescu 		(strcmp(tokens[0], "thread") == 0) &&
16365074e1d5SCristian Dumitrescu 		(strcmp(tokens[1], "pipeline") == 0)) {
16375074e1d5SCristian Dumitrescu 		if (strcmp(tokens[2], "enable") == 0) {
16385074e1d5SCristian Dumitrescu 			snprintf(out, out_size, "\n%s\n",
16395074e1d5SCristian Dumitrescu 				cmd_thread_pipeline_enable_help);
16405074e1d5SCristian Dumitrescu 			return;
16415074e1d5SCristian Dumitrescu 		}
16425074e1d5SCristian Dumitrescu 
16435074e1d5SCristian Dumitrescu 		if (strcmp(tokens[2], "disable") == 0) {
16445074e1d5SCristian Dumitrescu 			snprintf(out, out_size, "\n%s\n",
16455074e1d5SCristian Dumitrescu 				cmd_thread_pipeline_disable_help);
16465074e1d5SCristian Dumitrescu 			return;
16475074e1d5SCristian Dumitrescu 		}
16485074e1d5SCristian Dumitrescu 	}
16495074e1d5SCristian Dumitrescu 
16505074e1d5SCristian Dumitrescu 	snprintf(out, out_size, "Invalid command\n");
16515074e1d5SCristian Dumitrescu }
16525074e1d5SCristian Dumitrescu 
16535074e1d5SCristian Dumitrescu void
16545074e1d5SCristian Dumitrescu cli_process(char *in, char *out, size_t out_size, void *obj)
16555074e1d5SCristian Dumitrescu {
16565074e1d5SCristian Dumitrescu 	char *tokens[CMD_MAX_TOKENS];
16575074e1d5SCristian Dumitrescu 	uint32_t n_tokens = RTE_DIM(tokens);
16585074e1d5SCristian Dumitrescu 	int status;
16595074e1d5SCristian Dumitrescu 
16605074e1d5SCristian Dumitrescu 	if (is_comment(in))
16615074e1d5SCristian Dumitrescu 		return;
16625074e1d5SCristian Dumitrescu 
16635074e1d5SCristian Dumitrescu 	status = parse_tokenize_string(in, tokens, &n_tokens);
16645074e1d5SCristian Dumitrescu 	if (status) {
16655074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_TOO_MANY, "");
16665074e1d5SCristian Dumitrescu 		return;
16675074e1d5SCristian Dumitrescu 	}
16685074e1d5SCristian Dumitrescu 
16695074e1d5SCristian Dumitrescu 	if (n_tokens == 0)
16705074e1d5SCristian Dumitrescu 		return;
16715074e1d5SCristian Dumitrescu 
16725074e1d5SCristian Dumitrescu 	if (strcmp(tokens[0], "help") == 0) {
16735074e1d5SCristian Dumitrescu 		cmd_help(tokens, n_tokens, out, out_size, obj);
16745074e1d5SCristian Dumitrescu 		return;
16755074e1d5SCristian Dumitrescu 	}
16765074e1d5SCristian Dumitrescu 
16775074e1d5SCristian Dumitrescu 	if (strcmp(tokens[0], "mempool") == 0) {
16785074e1d5SCristian Dumitrescu 		cmd_mempool(tokens, n_tokens, out, out_size, obj);
16795074e1d5SCristian Dumitrescu 		return;
16805074e1d5SCristian Dumitrescu 	}
16815074e1d5SCristian Dumitrescu 
16825074e1d5SCristian Dumitrescu 	if (strcmp(tokens[0], "link") == 0) {
1683821848f5SCristian Dumitrescu 		if ((n_tokens >= 2) && (strcmp(tokens[1], "show") == 0)) {
16845074e1d5SCristian Dumitrescu 			cmd_link_show(tokens, n_tokens, out, out_size, obj);
16855074e1d5SCristian Dumitrescu 			return;
16865074e1d5SCristian Dumitrescu 		}
16875074e1d5SCristian Dumitrescu 
16885074e1d5SCristian Dumitrescu 		cmd_link(tokens, n_tokens, out, out_size, obj);
16895074e1d5SCristian Dumitrescu 		return;
16905074e1d5SCristian Dumitrescu 	}
16915074e1d5SCristian Dumitrescu 
169277a41301SCristian Dumitrescu 	if (strcmp(tokens[0], "ring") == 0) {
169377a41301SCristian Dumitrescu 		cmd_ring(tokens, n_tokens, out, out_size, obj);
169477a41301SCristian Dumitrescu 		return;
169577a41301SCristian Dumitrescu 	}
169677a41301SCristian Dumitrescu 
1697e2b8dc52SVenkata Suresh Kumar P 	if (strcmp(tokens[0], "tap") == 0) {
1698e2b8dc52SVenkata Suresh Kumar P 		cmd_tap(tokens, n_tokens, out, out_size, obj);
1699e2b8dc52SVenkata Suresh Kumar P 		return;
1700e2b8dc52SVenkata Suresh Kumar P 	}
1701e2b8dc52SVenkata Suresh Kumar P 
17025074e1d5SCristian Dumitrescu 	if (strcmp(tokens[0], "pipeline") == 0) {
17035074e1d5SCristian Dumitrescu 		if ((n_tokens >= 3) &&
17045074e1d5SCristian Dumitrescu 			(strcmp(tokens[2], "create") == 0)) {
17055074e1d5SCristian Dumitrescu 			cmd_pipeline_create(tokens, n_tokens, out, out_size,
17065074e1d5SCristian Dumitrescu 				obj);
17075074e1d5SCristian Dumitrescu 			return;
17085074e1d5SCristian Dumitrescu 		}
17095074e1d5SCristian Dumitrescu 
17105074e1d5SCristian Dumitrescu 		if ((n_tokens >= 4) &&
17115074e1d5SCristian Dumitrescu 			(strcmp(tokens[2], "port") == 0) &&
17125074e1d5SCristian Dumitrescu 			(strcmp(tokens[3], "in") == 0)) {
17135074e1d5SCristian Dumitrescu 			cmd_pipeline_port_in(tokens, n_tokens, out, out_size,
17145074e1d5SCristian Dumitrescu 				obj);
17155074e1d5SCristian Dumitrescu 			return;
17165074e1d5SCristian Dumitrescu 		}
17175074e1d5SCristian Dumitrescu 
17185074e1d5SCristian Dumitrescu 		if ((n_tokens >= 4) &&
17195074e1d5SCristian Dumitrescu 			(strcmp(tokens[2], "port") == 0) &&
17205074e1d5SCristian Dumitrescu 			(strcmp(tokens[3], "out") == 0)) {
17215074e1d5SCristian Dumitrescu 			cmd_pipeline_port_out(tokens, n_tokens, out, out_size,
17225074e1d5SCristian Dumitrescu 				obj);
17235074e1d5SCristian Dumitrescu 			return;
17245074e1d5SCristian Dumitrescu 		}
17255074e1d5SCristian Dumitrescu 
17265074e1d5SCristian Dumitrescu 		if ((n_tokens >= 3) &&
17275074e1d5SCristian Dumitrescu 			(strcmp(tokens[2], "build") == 0)) {
17285074e1d5SCristian Dumitrescu 			cmd_pipeline_build(tokens, n_tokens, out, out_size,
17295074e1d5SCristian Dumitrescu 				obj);
17305074e1d5SCristian Dumitrescu 			return;
17315074e1d5SCristian Dumitrescu 		}
17325074e1d5SCristian Dumitrescu 
17335074e1d5SCristian Dumitrescu 		if ((n_tokens >= 3) &&
17345074e1d5SCristian Dumitrescu 			(strcmp(tokens[2], "table") == 0)) {
17355074e1d5SCristian Dumitrescu 			cmd_pipeline_table_update(tokens, n_tokens, out,
17365074e1d5SCristian Dumitrescu 				out_size, obj);
17375074e1d5SCristian Dumitrescu 			return;
17385074e1d5SCristian Dumitrescu 		}
17395074e1d5SCristian Dumitrescu 
17405074e1d5SCristian Dumitrescu 		if ((n_tokens >= 3) &&
1741*64cfcebdSCristian Dumitrescu 			(strcmp(tokens[2], "regrd") == 0)) {
1742*64cfcebdSCristian Dumitrescu 			cmd_pipeline_regrd(tokens, n_tokens, out, out_size, obj);
1743*64cfcebdSCristian Dumitrescu 			return;
1744*64cfcebdSCristian Dumitrescu 		}
1745*64cfcebdSCristian Dumitrescu 
1746*64cfcebdSCristian Dumitrescu 		if ((n_tokens >= 3) &&
1747*64cfcebdSCristian Dumitrescu 			(strcmp(tokens[2], "regwr") == 0)) {
1748*64cfcebdSCristian Dumitrescu 			cmd_pipeline_regwr(tokens, n_tokens, out, out_size, obj);
1749*64cfcebdSCristian Dumitrescu 			return;
1750*64cfcebdSCristian Dumitrescu 		}
1751*64cfcebdSCristian Dumitrescu 
1752*64cfcebdSCristian Dumitrescu 		if ((n_tokens >= 3) &&
17535074e1d5SCristian Dumitrescu 			(strcmp(tokens[2], "stats") == 0)) {
17545074e1d5SCristian Dumitrescu 			cmd_pipeline_stats(tokens, n_tokens, out, out_size,
17555074e1d5SCristian Dumitrescu 				obj);
17565074e1d5SCristian Dumitrescu 			return;
17575074e1d5SCristian Dumitrescu 		}
17585074e1d5SCristian Dumitrescu 	}
17595074e1d5SCristian Dumitrescu 
17605074e1d5SCristian Dumitrescu 	if (strcmp(tokens[0], "thread") == 0) {
17615074e1d5SCristian Dumitrescu 		if ((n_tokens >= 5) &&
17625074e1d5SCristian Dumitrescu 			(strcmp(tokens[4], "enable") == 0)) {
17635074e1d5SCristian Dumitrescu 			cmd_thread_pipeline_enable(tokens, n_tokens,
17645074e1d5SCristian Dumitrescu 				out, out_size, obj);
17655074e1d5SCristian Dumitrescu 			return;
17665074e1d5SCristian Dumitrescu 		}
17675074e1d5SCristian Dumitrescu 
17685074e1d5SCristian Dumitrescu 		if ((n_tokens >= 5) &&
17695074e1d5SCristian Dumitrescu 			(strcmp(tokens[4], "disable") == 0)) {
17705074e1d5SCristian Dumitrescu 			cmd_thread_pipeline_disable(tokens, n_tokens,
17715074e1d5SCristian Dumitrescu 				out, out_size, obj);
17725074e1d5SCristian Dumitrescu 			return;
17735074e1d5SCristian Dumitrescu 		}
17745074e1d5SCristian Dumitrescu 	}
17755074e1d5SCristian Dumitrescu 
17765074e1d5SCristian Dumitrescu 	snprintf(out, out_size, MSG_CMD_UNKNOWN, tokens[0]);
17775074e1d5SCristian Dumitrescu }
17785074e1d5SCristian Dumitrescu 
17795074e1d5SCristian Dumitrescu int
17805074e1d5SCristian Dumitrescu cli_script_process(const char *file_name,
17815074e1d5SCristian Dumitrescu 	size_t msg_in_len_max,
17825074e1d5SCristian Dumitrescu 	size_t msg_out_len_max,
17835074e1d5SCristian Dumitrescu 	void *obj)
17845074e1d5SCristian Dumitrescu {
17855074e1d5SCristian Dumitrescu 	char *msg_in = NULL, *msg_out = NULL;
17865074e1d5SCristian Dumitrescu 	FILE *f = NULL;
17875074e1d5SCristian Dumitrescu 
17885074e1d5SCristian Dumitrescu 	/* Check input arguments */
17895074e1d5SCristian Dumitrescu 	if ((file_name == NULL) ||
17905074e1d5SCristian Dumitrescu 		(strlen(file_name) == 0) ||
17915074e1d5SCristian Dumitrescu 		(msg_in_len_max == 0) ||
17925074e1d5SCristian Dumitrescu 		(msg_out_len_max == 0))
17935074e1d5SCristian Dumitrescu 		return -EINVAL;
17945074e1d5SCristian Dumitrescu 
17955074e1d5SCristian Dumitrescu 	msg_in = malloc(msg_in_len_max + 1);
17965074e1d5SCristian Dumitrescu 	msg_out = malloc(msg_out_len_max + 1);
17975074e1d5SCristian Dumitrescu 	if ((msg_in == NULL) ||
17985074e1d5SCristian Dumitrescu 		(msg_out == NULL)) {
17995074e1d5SCristian Dumitrescu 		free(msg_out);
18005074e1d5SCristian Dumitrescu 		free(msg_in);
18015074e1d5SCristian Dumitrescu 		return -ENOMEM;
18025074e1d5SCristian Dumitrescu 	}
18035074e1d5SCristian Dumitrescu 
18045074e1d5SCristian Dumitrescu 	/* Open input file */
18055074e1d5SCristian Dumitrescu 	f = fopen(file_name, "r");
18065074e1d5SCristian Dumitrescu 	if (f == NULL) {
18075074e1d5SCristian Dumitrescu 		free(msg_out);
18085074e1d5SCristian Dumitrescu 		free(msg_in);
18095074e1d5SCristian Dumitrescu 		return -EIO;
18105074e1d5SCristian Dumitrescu 	}
18115074e1d5SCristian Dumitrescu 
18125074e1d5SCristian Dumitrescu 	/* Read file */
18135074e1d5SCristian Dumitrescu 	for ( ; ; ) {
18145074e1d5SCristian Dumitrescu 		if (fgets(msg_in, msg_in_len_max + 1, f) == NULL)
18155074e1d5SCristian Dumitrescu 			break;
18165074e1d5SCristian Dumitrescu 
18175074e1d5SCristian Dumitrescu 		printf("%s", msg_in);
18185074e1d5SCristian Dumitrescu 		msg_out[0] = 0;
18195074e1d5SCristian Dumitrescu 
18205074e1d5SCristian Dumitrescu 		cli_process(msg_in,
18215074e1d5SCristian Dumitrescu 			msg_out,
18225074e1d5SCristian Dumitrescu 			msg_out_len_max,
18235074e1d5SCristian Dumitrescu 			obj);
18245074e1d5SCristian Dumitrescu 
18255074e1d5SCristian Dumitrescu 		if (strlen(msg_out))
18265074e1d5SCristian Dumitrescu 			printf("%s", msg_out);
18275074e1d5SCristian Dumitrescu 	}
18285074e1d5SCristian Dumitrescu 
18295074e1d5SCristian Dumitrescu 	/* Close file */
18305074e1d5SCristian Dumitrescu 	fclose(f);
18315074e1d5SCristian Dumitrescu 	free(msg_out);
18325074e1d5SCristian Dumitrescu 	free(msg_in);
18335074e1d5SCristian Dumitrescu 	return 0;
18345074e1d5SCristian Dumitrescu }
1835