xref: /dpdk/examples/pipeline/cli.c (revision 8bd4862f297bf43356f12fb5b1aa050a545654fb)
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"
379c2c4f87bSAman Deep Singh 		"\tether " RTE_ETHER_ADDR_PRT_FMT " 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,
388a7db3afcSAman Deep Singh 		RTE_ETHER_ADDR_BYTES(&mac_addr),
3895074e1d5SCristian Dumitrescu 		link->n_rxq,
3905074e1d5SCristian Dumitrescu 		link->n_txq,
3915074e1d5SCristian Dumitrescu 		link->port_id,
3925074e1d5SCristian Dumitrescu 		rte_eth_link_speed_to_str(eth_link.link_speed),
3935074e1d5SCristian Dumitrescu 		stats.ipackets,
3945074e1d5SCristian Dumitrescu 		stats.ibytes,
3955074e1d5SCristian Dumitrescu 		stats.ierrors,
3965074e1d5SCristian Dumitrescu 		stats.imissed,
3975074e1d5SCristian Dumitrescu 		stats.rx_nombuf,
3985074e1d5SCristian Dumitrescu 		stats.opackets,
3995074e1d5SCristian Dumitrescu 		stats.obytes,
4005074e1d5SCristian Dumitrescu 		stats.oerrors);
4015074e1d5SCristian Dumitrescu }
4025074e1d5SCristian Dumitrescu 
4035074e1d5SCristian Dumitrescu /*
4045074e1d5SCristian Dumitrescu  * link show [<link_name>]
4055074e1d5SCristian Dumitrescu  */
4065074e1d5SCristian Dumitrescu static void
4075074e1d5SCristian Dumitrescu cmd_link_show(char **tokens,
4085074e1d5SCristian Dumitrescu 	      uint32_t n_tokens,
4095074e1d5SCristian Dumitrescu 	      char *out,
4105074e1d5SCristian Dumitrescu 	      size_t out_size,
4115074e1d5SCristian Dumitrescu 	      void *obj)
4125074e1d5SCristian Dumitrescu {
4135074e1d5SCristian Dumitrescu 	struct link *link;
4145074e1d5SCristian Dumitrescu 	char *link_name;
4155074e1d5SCristian Dumitrescu 
4165074e1d5SCristian Dumitrescu 	if (n_tokens != 2 && n_tokens != 3) {
4175074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
4185074e1d5SCristian Dumitrescu 		return;
4195074e1d5SCristian Dumitrescu 	}
4205074e1d5SCristian Dumitrescu 
4215074e1d5SCristian Dumitrescu 	if (n_tokens == 2) {
4225074e1d5SCristian Dumitrescu 		link = link_next(obj, NULL);
4235074e1d5SCristian Dumitrescu 
4245074e1d5SCristian Dumitrescu 		while (link != NULL) {
4255074e1d5SCristian Dumitrescu 			out_size = out_size - strlen(out);
4265074e1d5SCristian Dumitrescu 			out = &out[strlen(out)];
4275074e1d5SCristian Dumitrescu 
4285074e1d5SCristian Dumitrescu 			print_link_info(link, out, out_size);
4295074e1d5SCristian Dumitrescu 			link = link_next(obj, link);
4305074e1d5SCristian Dumitrescu 		}
4315074e1d5SCristian Dumitrescu 	} else {
4325074e1d5SCristian Dumitrescu 		out_size = out_size - strlen(out);
4335074e1d5SCristian Dumitrescu 		out = &out[strlen(out)];
4345074e1d5SCristian Dumitrescu 
4355074e1d5SCristian Dumitrescu 		link_name = tokens[2];
4365074e1d5SCristian Dumitrescu 		link = link_find(obj, link_name);
4375074e1d5SCristian Dumitrescu 
4385074e1d5SCristian Dumitrescu 		if (link == NULL) {
4395074e1d5SCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_INVALID,
4405074e1d5SCristian Dumitrescu 					"Link does not exist");
4415074e1d5SCristian Dumitrescu 			return;
4425074e1d5SCristian Dumitrescu 		}
4435074e1d5SCristian Dumitrescu 		print_link_info(link, out, out_size);
4445074e1d5SCristian Dumitrescu 	}
4455074e1d5SCristian Dumitrescu }
4465074e1d5SCristian Dumitrescu 
44777a41301SCristian Dumitrescu static const char cmd_ring_help[] =
44877a41301SCristian Dumitrescu "ring <ring_name> size <size> numa <numa_node>\n";
44977a41301SCristian Dumitrescu 
45077a41301SCristian Dumitrescu static void
45177a41301SCristian Dumitrescu cmd_ring(char **tokens,
45277a41301SCristian Dumitrescu 	uint32_t n_tokens,
45377a41301SCristian Dumitrescu 	char *out,
45477a41301SCristian Dumitrescu 	size_t out_size,
45577a41301SCristian Dumitrescu 	void *obj)
45677a41301SCristian Dumitrescu {
45777a41301SCristian Dumitrescu 	struct ring_params p;
45877a41301SCristian Dumitrescu 	char *name;
45977a41301SCristian Dumitrescu 	struct ring *ring;
46077a41301SCristian Dumitrescu 
46177a41301SCristian Dumitrescu 	if (n_tokens != 6) {
46277a41301SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
46377a41301SCristian Dumitrescu 		return;
46477a41301SCristian Dumitrescu 	}
46577a41301SCristian Dumitrescu 
46677a41301SCristian Dumitrescu 	name = tokens[1];
46777a41301SCristian Dumitrescu 
46877a41301SCristian Dumitrescu 	if (strcmp(tokens[2], "size") != 0) {
46977a41301SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "size");
47077a41301SCristian Dumitrescu 		return;
47177a41301SCristian Dumitrescu 	}
47277a41301SCristian Dumitrescu 
47377a41301SCristian Dumitrescu 	if (parser_read_uint32(&p.size, tokens[3]) != 0) {
47477a41301SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "size");
47577a41301SCristian Dumitrescu 		return;
47677a41301SCristian Dumitrescu 	}
47777a41301SCristian Dumitrescu 
47877a41301SCristian Dumitrescu 	if (strcmp(tokens[4], "numa") != 0) {
47977a41301SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "numa");
48077a41301SCristian Dumitrescu 		return;
48177a41301SCristian Dumitrescu 	}
48277a41301SCristian Dumitrescu 
48377a41301SCristian Dumitrescu 	if (parser_read_uint32(&p.numa_node, tokens[5]) != 0) {
48477a41301SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "numa_node");
48577a41301SCristian Dumitrescu 		return;
48677a41301SCristian Dumitrescu 	}
48777a41301SCristian Dumitrescu 
48877a41301SCristian Dumitrescu 	ring = ring_create(obj, name, &p);
48977a41301SCristian Dumitrescu 	if (!ring) {
49077a41301SCristian Dumitrescu 		snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
49177a41301SCristian Dumitrescu 		return;
49277a41301SCristian Dumitrescu 	}
49377a41301SCristian Dumitrescu }
49477a41301SCristian Dumitrescu 
495e2b8dc52SVenkata Suresh Kumar P static const char cmd_tap_help[] =
496e2b8dc52SVenkata Suresh Kumar P "tap <tap_name>\n";
497e2b8dc52SVenkata Suresh Kumar P 
498e2b8dc52SVenkata Suresh Kumar P static void
499e2b8dc52SVenkata Suresh Kumar P cmd_tap(char **tokens,
500e2b8dc52SVenkata Suresh Kumar P 	uint32_t n_tokens,
501e2b8dc52SVenkata Suresh Kumar P 	char *out,
502e2b8dc52SVenkata Suresh Kumar P 	size_t out_size,
503e2b8dc52SVenkata Suresh Kumar P 	void *obj)
504e2b8dc52SVenkata Suresh Kumar P {
505e2b8dc52SVenkata Suresh Kumar P 	struct tap *tap;
506e2b8dc52SVenkata Suresh Kumar P 	char *name;
507e2b8dc52SVenkata Suresh Kumar P 
508e2b8dc52SVenkata Suresh Kumar P 	if (n_tokens < 2) {
509e2b8dc52SVenkata Suresh Kumar P 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
510e2b8dc52SVenkata Suresh Kumar P 		return;
511e2b8dc52SVenkata Suresh Kumar P 	}
512e2b8dc52SVenkata Suresh Kumar P 	name = tokens[1];
513e2b8dc52SVenkata Suresh Kumar P 
514e2b8dc52SVenkata Suresh Kumar P 	tap = tap_create(obj, name);
515e2b8dc52SVenkata Suresh Kumar P 	if (tap == NULL) {
516e2b8dc52SVenkata Suresh Kumar P 		snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
517e2b8dc52SVenkata Suresh Kumar P 		return;
518e2b8dc52SVenkata Suresh Kumar P 	}
519e2b8dc52SVenkata Suresh Kumar P }
520e2b8dc52SVenkata Suresh Kumar P 
5215074e1d5SCristian Dumitrescu static const char cmd_pipeline_create_help[] =
5225074e1d5SCristian Dumitrescu "pipeline <pipeline_name> create <numa_node>\n";
5235074e1d5SCristian Dumitrescu 
5245074e1d5SCristian Dumitrescu static void
5255074e1d5SCristian Dumitrescu cmd_pipeline_create(char **tokens,
5265074e1d5SCristian Dumitrescu 	uint32_t n_tokens,
5275074e1d5SCristian Dumitrescu 	char *out,
5285074e1d5SCristian Dumitrescu 	size_t out_size,
5295074e1d5SCristian Dumitrescu 	void *obj)
5305074e1d5SCristian Dumitrescu {
5315074e1d5SCristian Dumitrescu 	struct pipeline *p;
5325074e1d5SCristian Dumitrescu 	char *name;
5335074e1d5SCristian Dumitrescu 	uint32_t numa_node;
5345074e1d5SCristian Dumitrescu 
5355074e1d5SCristian Dumitrescu 	if (n_tokens != 4) {
5365074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
5375074e1d5SCristian Dumitrescu 		return;
5385074e1d5SCristian Dumitrescu 	}
5395074e1d5SCristian Dumitrescu 
5405074e1d5SCristian Dumitrescu 	name = tokens[1];
5415074e1d5SCristian Dumitrescu 
5425074e1d5SCristian Dumitrescu 	if (parser_read_uint32(&numa_node, tokens[3]) != 0) {
5435074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "numa_node");
5445074e1d5SCristian Dumitrescu 		return;
5455074e1d5SCristian Dumitrescu 	}
5465074e1d5SCristian Dumitrescu 
5475074e1d5SCristian Dumitrescu 	p = pipeline_create(obj, name, (int)numa_node);
5485074e1d5SCristian Dumitrescu 	if (!p) {
5495074e1d5SCristian Dumitrescu 		snprintf(out, out_size, "pipeline create error.");
5505074e1d5SCristian Dumitrescu 		return;
5515074e1d5SCristian Dumitrescu 	}
5525074e1d5SCristian Dumitrescu }
5535074e1d5SCristian Dumitrescu 
5545074e1d5SCristian Dumitrescu static const char cmd_pipeline_port_in_help[] =
5555074e1d5SCristian Dumitrescu "pipeline <pipeline_name> port in <port_id>\n"
5565074e1d5SCristian Dumitrescu "   link <link_name> rxq <queue_id> bsz <burst_size>\n"
55777a41301SCristian Dumitrescu "   ring <ring_name> bsz <burst_size>\n"
558e2b8dc52SVenkata Suresh Kumar P "   | source <mempool_name> <file_name>\n"
559e2b8dc52SVenkata Suresh Kumar P "   | tap <tap_name> mempool <mempool_name> mtu <mtu> bsz <burst_size>\n";
5605074e1d5SCristian Dumitrescu 
5615074e1d5SCristian Dumitrescu static void
5625074e1d5SCristian Dumitrescu cmd_pipeline_port_in(char **tokens,
5635074e1d5SCristian Dumitrescu 	uint32_t n_tokens,
5645074e1d5SCristian Dumitrescu 	char *out,
5655074e1d5SCristian Dumitrescu 	size_t out_size,
5665074e1d5SCristian Dumitrescu 	void *obj)
5675074e1d5SCristian Dumitrescu {
5685074e1d5SCristian Dumitrescu 	struct pipeline *p;
5695074e1d5SCristian Dumitrescu 	int status;
5705074e1d5SCristian Dumitrescu 	uint32_t port_id = 0, t0;
5715074e1d5SCristian Dumitrescu 
5725074e1d5SCristian Dumitrescu 	if (n_tokens < 6) {
5735074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
5745074e1d5SCristian Dumitrescu 		return;
5755074e1d5SCristian Dumitrescu 	}
5765074e1d5SCristian Dumitrescu 
5775074e1d5SCristian Dumitrescu 	p = pipeline_find(obj, tokens[1]);
5785074e1d5SCristian Dumitrescu 	if (!p || p->ctl) {
5795074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
5805074e1d5SCristian Dumitrescu 		return;
5815074e1d5SCristian Dumitrescu 	}
5825074e1d5SCristian Dumitrescu 
5835074e1d5SCristian Dumitrescu 	if (strcmp(tokens[2], "port") != 0) {
5845074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
5855074e1d5SCristian Dumitrescu 		return;
5865074e1d5SCristian Dumitrescu 	}
5875074e1d5SCristian Dumitrescu 
5885074e1d5SCristian Dumitrescu 	if (strcmp(tokens[3], "in") != 0) {
5895074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "in");
5905074e1d5SCristian Dumitrescu 		return;
5915074e1d5SCristian Dumitrescu 	}
5925074e1d5SCristian Dumitrescu 
5935074e1d5SCristian Dumitrescu 	if (parser_read_uint32(&port_id, tokens[4]) != 0) {
5945074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
5955074e1d5SCristian Dumitrescu 		return;
5965074e1d5SCristian Dumitrescu 	}
5975074e1d5SCristian Dumitrescu 
5985074e1d5SCristian Dumitrescu 	t0 = 5;
5995074e1d5SCristian Dumitrescu 
6005074e1d5SCristian Dumitrescu 	if (strcmp(tokens[t0], "link") == 0) {
6015074e1d5SCristian Dumitrescu 		struct rte_swx_port_ethdev_reader_params params;
6025074e1d5SCristian Dumitrescu 		struct link *link;
6035074e1d5SCristian Dumitrescu 
6045074e1d5SCristian Dumitrescu 		if (n_tokens < t0 + 6) {
6055074e1d5SCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_MISMATCH,
6065074e1d5SCristian Dumitrescu 				"pipeline port in link");
6075074e1d5SCristian Dumitrescu 			return;
6085074e1d5SCristian Dumitrescu 		}
6095074e1d5SCristian Dumitrescu 
6105074e1d5SCristian Dumitrescu 		link = link_find(obj, tokens[t0 + 1]);
6115074e1d5SCristian Dumitrescu 		if (!link) {
6125074e1d5SCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_INVALID,
6135074e1d5SCristian Dumitrescu 				"link_name");
6145074e1d5SCristian Dumitrescu 			return;
6155074e1d5SCristian Dumitrescu 		}
6165074e1d5SCristian Dumitrescu 		params.dev_name = link->dev_name;
6175074e1d5SCristian Dumitrescu 
6185074e1d5SCristian Dumitrescu 		if (strcmp(tokens[t0 + 2], "rxq") != 0) {
6195074e1d5SCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rxq");
6205074e1d5SCristian Dumitrescu 			return;
6215074e1d5SCristian Dumitrescu 		}
6225074e1d5SCristian Dumitrescu 
6235074e1d5SCristian Dumitrescu 		if (parser_read_uint16(&params.queue_id, tokens[t0 + 3]) != 0) {
6245074e1d5SCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_INVALID,
6255074e1d5SCristian Dumitrescu 				"queue_id");
6265074e1d5SCristian Dumitrescu 			return;
6275074e1d5SCristian Dumitrescu 		}
6285074e1d5SCristian Dumitrescu 
6295074e1d5SCristian Dumitrescu 		if (strcmp(tokens[t0 + 4], "bsz") != 0) {
6305074e1d5SCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_NOT_FOUND, "bsz");
6315074e1d5SCristian Dumitrescu 			return;
6325074e1d5SCristian Dumitrescu 		}
6335074e1d5SCristian Dumitrescu 
6345074e1d5SCristian Dumitrescu 		if (parser_read_uint32(&params.burst_size, tokens[t0 + 5])) {
6355074e1d5SCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_INVALID,
6365074e1d5SCristian Dumitrescu 				"burst_size");
6375074e1d5SCristian Dumitrescu 			return;
6385074e1d5SCristian Dumitrescu 		}
6395074e1d5SCristian Dumitrescu 
6405074e1d5SCristian Dumitrescu 		t0 += 6;
6415074e1d5SCristian Dumitrescu 
6425074e1d5SCristian Dumitrescu 		status = rte_swx_pipeline_port_in_config(p->p,
6435074e1d5SCristian Dumitrescu 			port_id,
6445074e1d5SCristian Dumitrescu 			"ethdev",
6455074e1d5SCristian Dumitrescu 			&params);
64677a41301SCristian Dumitrescu 	} else if (strcmp(tokens[t0], "ring") == 0) {
64777a41301SCristian Dumitrescu 		struct rte_swx_port_ring_reader_params params;
64877a41301SCristian Dumitrescu 		struct ring *ring;
64977a41301SCristian Dumitrescu 
65077a41301SCristian Dumitrescu 		if (n_tokens < t0 + 4) {
65177a41301SCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_MISMATCH,
65277a41301SCristian Dumitrescu 				"pipeline port in ring");
65377a41301SCristian Dumitrescu 			return;
65477a41301SCristian Dumitrescu 		}
65577a41301SCristian Dumitrescu 
65677a41301SCristian Dumitrescu 		ring = ring_find(obj, tokens[t0 + 1]);
65777a41301SCristian Dumitrescu 		if (!ring) {
65877a41301SCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_INVALID,
65977a41301SCristian Dumitrescu 				"ring_name");
66077a41301SCristian Dumitrescu 			return;
66177a41301SCristian Dumitrescu 		}
66277a41301SCristian Dumitrescu 		params.name = ring->name;
66377a41301SCristian Dumitrescu 
66477a41301SCristian Dumitrescu 		if (strcmp(tokens[t0 + 2], "bsz") != 0) {
66577a41301SCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_NOT_FOUND, "bsz");
66677a41301SCristian Dumitrescu 			return;
66777a41301SCristian Dumitrescu 		}
66877a41301SCristian Dumitrescu 
66977a41301SCristian Dumitrescu 		if (parser_read_uint32(&params.burst_size, tokens[t0 + 3])) {
67077a41301SCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_INVALID,
67177a41301SCristian Dumitrescu 				"burst_size");
67277a41301SCristian Dumitrescu 			return;
67377a41301SCristian Dumitrescu 		}
67477a41301SCristian Dumitrescu 
67577a41301SCristian Dumitrescu 		t0 += 4;
67677a41301SCristian Dumitrescu 
67777a41301SCristian Dumitrescu 		status = rte_swx_pipeline_port_in_config(p->p,
67877a41301SCristian Dumitrescu 			port_id,
67977a41301SCristian Dumitrescu 			"ring",
68077a41301SCristian Dumitrescu 			&params);
6815074e1d5SCristian Dumitrescu 	} else if (strcmp(tokens[t0], "source") == 0) {
6825074e1d5SCristian Dumitrescu 		struct rte_swx_port_source_params params;
6835074e1d5SCristian Dumitrescu 		struct mempool *mp;
6845074e1d5SCristian Dumitrescu 
6855074e1d5SCristian Dumitrescu 		if (n_tokens < t0 + 3) {
6865074e1d5SCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_MISMATCH,
6875074e1d5SCristian Dumitrescu 				"pipeline port in source");
6885074e1d5SCristian Dumitrescu 			return;
6895074e1d5SCristian Dumitrescu 		}
6905074e1d5SCristian Dumitrescu 
6915074e1d5SCristian Dumitrescu 		mp = mempool_find(obj, tokens[t0 + 1]);
6925074e1d5SCristian Dumitrescu 		if (!mp) {
6935074e1d5SCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_INVALID,
6945074e1d5SCristian Dumitrescu 				"mempool_name");
6955074e1d5SCristian Dumitrescu 			return;
6965074e1d5SCristian Dumitrescu 		}
6975074e1d5SCristian Dumitrescu 		params.pool = mp->m;
6985074e1d5SCristian Dumitrescu 
6995074e1d5SCristian Dumitrescu 		params.file_name = tokens[t0 + 2];
7005074e1d5SCristian Dumitrescu 
7015074e1d5SCristian Dumitrescu 		t0 += 3;
7025074e1d5SCristian Dumitrescu 
7035074e1d5SCristian Dumitrescu 		status = rte_swx_pipeline_port_in_config(p->p,
7045074e1d5SCristian Dumitrescu 			port_id,
7055074e1d5SCristian Dumitrescu 			"source",
7065074e1d5SCristian Dumitrescu 			&params);
707e2b8dc52SVenkata Suresh Kumar P 	} else if (strcmp(tokens[t0], "tap") == 0) {
708e2b8dc52SVenkata Suresh Kumar P 		struct rte_swx_port_fd_reader_params params;
709e2b8dc52SVenkata Suresh Kumar P 		struct tap *tap;
710e2b8dc52SVenkata Suresh Kumar P 		struct mempool *mp;
711e2b8dc52SVenkata Suresh Kumar P 
712e2b8dc52SVenkata Suresh Kumar P 		if (n_tokens < t0 + 8) {
713e2b8dc52SVenkata Suresh Kumar P 			snprintf(out, out_size, MSG_ARG_MISMATCH,
714e2b8dc52SVenkata Suresh Kumar P 				"pipeline port in tap");
715e2b8dc52SVenkata Suresh Kumar P 			return;
716e2b8dc52SVenkata Suresh Kumar P 		}
717e2b8dc52SVenkata Suresh Kumar P 
718e2b8dc52SVenkata Suresh Kumar P 		tap = tap_find(obj, tokens[t0 + 1]);
719e2b8dc52SVenkata Suresh Kumar P 		if (!tap) {
720e2b8dc52SVenkata Suresh Kumar P 			snprintf(out, out_size, MSG_ARG_INVALID,
721e2b8dc52SVenkata Suresh Kumar P 				"tap_name");
722e2b8dc52SVenkata Suresh Kumar P 			return;
723e2b8dc52SVenkata Suresh Kumar P 		}
724e2b8dc52SVenkata Suresh Kumar P 		params.fd = tap->fd;
725e2b8dc52SVenkata Suresh Kumar P 
726e2b8dc52SVenkata Suresh Kumar P 		if (strcmp(tokens[t0 + 2], "mempool") != 0) {
727e2b8dc52SVenkata Suresh Kumar P 			snprintf(out, out_size, MSG_ARG_NOT_FOUND,
728e2b8dc52SVenkata Suresh Kumar P 				"mempool");
729e2b8dc52SVenkata Suresh Kumar P 			return;
730e2b8dc52SVenkata Suresh Kumar P 		}
731e2b8dc52SVenkata Suresh Kumar P 
732e2b8dc52SVenkata Suresh Kumar P 		mp = mempool_find(obj, tokens[t0 + 3]);
733e2b8dc52SVenkata Suresh Kumar P 		if (!mp) {
734e2b8dc52SVenkata Suresh Kumar P 			snprintf(out, out_size, MSG_ARG_INVALID,
735e2b8dc52SVenkata Suresh Kumar P 				"mempool_name");
736e2b8dc52SVenkata Suresh Kumar P 			return;
737e2b8dc52SVenkata Suresh Kumar P 		}
738e2b8dc52SVenkata Suresh Kumar P 		params.mempool = mp->m;
739e2b8dc52SVenkata Suresh Kumar P 
740e2b8dc52SVenkata Suresh Kumar P 		if (strcmp(tokens[t0 + 4], "mtu") != 0) {
741e2b8dc52SVenkata Suresh Kumar P 			snprintf(out, out_size, MSG_ARG_NOT_FOUND,
742e2b8dc52SVenkata Suresh Kumar P 				"mtu");
743e2b8dc52SVenkata Suresh Kumar P 			return;
744e2b8dc52SVenkata Suresh Kumar P 		}
745e2b8dc52SVenkata Suresh Kumar P 
746e2b8dc52SVenkata Suresh Kumar P 		if (parser_read_uint32(&params.mtu, tokens[t0 + 5]) != 0) {
747e2b8dc52SVenkata Suresh Kumar P 			snprintf(out, out_size, MSG_ARG_INVALID, "mtu");
748e2b8dc52SVenkata Suresh Kumar P 			return;
749e2b8dc52SVenkata Suresh Kumar P 		}
750e2b8dc52SVenkata Suresh Kumar P 
751e2b8dc52SVenkata Suresh Kumar P 		if (strcmp(tokens[t0 + 6], "bsz") != 0) {
752e2b8dc52SVenkata Suresh Kumar P 			snprintf(out, out_size, MSG_ARG_NOT_FOUND, "bsz");
753e2b8dc52SVenkata Suresh Kumar P 			return;
754e2b8dc52SVenkata Suresh Kumar P 		}
755e2b8dc52SVenkata Suresh Kumar P 
756e2b8dc52SVenkata Suresh Kumar P 		if (parser_read_uint32(&params.burst_size, tokens[t0 + 7])) {
757e2b8dc52SVenkata Suresh Kumar P 			snprintf(out, out_size, MSG_ARG_INVALID,
758e2b8dc52SVenkata Suresh Kumar P 				"burst_size");
759e2b8dc52SVenkata Suresh Kumar P 			return;
760e2b8dc52SVenkata Suresh Kumar P 		}
761e2b8dc52SVenkata Suresh Kumar P 
762e2b8dc52SVenkata Suresh Kumar P 		t0 += 8;
763e2b8dc52SVenkata Suresh Kumar P 
764e2b8dc52SVenkata Suresh Kumar P 		status = rte_swx_pipeline_port_in_config(p->p,
765e2b8dc52SVenkata Suresh Kumar P 			port_id,
766e2b8dc52SVenkata Suresh Kumar P 			"fd",
767e2b8dc52SVenkata Suresh Kumar P 			&params);
768e2b8dc52SVenkata Suresh Kumar P 
7695074e1d5SCristian Dumitrescu 	} else {
7705074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
7715074e1d5SCristian Dumitrescu 		return;
7725074e1d5SCristian Dumitrescu 	}
7735074e1d5SCristian Dumitrescu 
7745074e1d5SCristian Dumitrescu 	if (status) {
7755074e1d5SCristian Dumitrescu 		snprintf(out, out_size, "port in error.");
7765074e1d5SCristian Dumitrescu 		return;
7775074e1d5SCristian Dumitrescu 	}
7785074e1d5SCristian Dumitrescu 
7795074e1d5SCristian Dumitrescu 	if (n_tokens != t0) {
7805074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
7815074e1d5SCristian Dumitrescu 		return;
7825074e1d5SCristian Dumitrescu 	}
7835074e1d5SCristian Dumitrescu }
7845074e1d5SCristian Dumitrescu 
7855074e1d5SCristian Dumitrescu static const char cmd_pipeline_port_out_help[] =
7865074e1d5SCristian Dumitrescu "pipeline <pipeline_name> port out <port_id>\n"
7875074e1d5SCristian Dumitrescu "   link <link_name> txq <txq_id> bsz <burst_size>\n"
78877a41301SCristian Dumitrescu "   ring <ring_name> bsz <burst_size>\n"
789e2b8dc52SVenkata Suresh Kumar P "   | sink <file_name> | none\n"
790e2b8dc52SVenkata Suresh Kumar P "   | tap <tap_name> bsz <burst_size>\n";
7915074e1d5SCristian Dumitrescu 
7925074e1d5SCristian Dumitrescu static void
7935074e1d5SCristian Dumitrescu cmd_pipeline_port_out(char **tokens,
7945074e1d5SCristian Dumitrescu 	uint32_t n_tokens,
7955074e1d5SCristian Dumitrescu 	char *out,
7965074e1d5SCristian Dumitrescu 	size_t out_size,
7975074e1d5SCristian Dumitrescu 	void *obj)
7985074e1d5SCristian Dumitrescu {
7995074e1d5SCristian Dumitrescu 	struct pipeline *p;
8005074e1d5SCristian Dumitrescu 	int status;
8015074e1d5SCristian Dumitrescu 	uint32_t port_id = 0, t0;
8025074e1d5SCristian Dumitrescu 
8035074e1d5SCristian Dumitrescu 	if (n_tokens < 6) {
8045074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
8055074e1d5SCristian Dumitrescu 		return;
8065074e1d5SCristian Dumitrescu 	}
8075074e1d5SCristian Dumitrescu 
8085074e1d5SCristian Dumitrescu 	p = pipeline_find(obj, tokens[1]);
8095074e1d5SCristian Dumitrescu 	if (!p || p->ctl) {
8105074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
8115074e1d5SCristian Dumitrescu 		return;
8125074e1d5SCristian Dumitrescu 	}
8135074e1d5SCristian Dumitrescu 
8145074e1d5SCristian Dumitrescu 	if (strcmp(tokens[2], "port") != 0) {
8155074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
8165074e1d5SCristian Dumitrescu 		return;
8175074e1d5SCristian Dumitrescu 	}
8185074e1d5SCristian Dumitrescu 
8195074e1d5SCristian Dumitrescu 	if (strcmp(tokens[3], "out") != 0) {
8205074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "out");
8215074e1d5SCristian Dumitrescu 		return;
8225074e1d5SCristian Dumitrescu 	}
8235074e1d5SCristian Dumitrescu 
8245074e1d5SCristian Dumitrescu 	if (parser_read_uint32(&port_id, tokens[4]) != 0) {
8255074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
8265074e1d5SCristian Dumitrescu 		return;
8275074e1d5SCristian Dumitrescu 	}
8285074e1d5SCristian Dumitrescu 
8295074e1d5SCristian Dumitrescu 	t0 = 5;
8305074e1d5SCristian Dumitrescu 
8315074e1d5SCristian Dumitrescu 	if (strcmp(tokens[t0], "link") == 0) {
8325074e1d5SCristian Dumitrescu 		struct rte_swx_port_ethdev_writer_params params;
8335074e1d5SCristian Dumitrescu 		struct link *link;
8345074e1d5SCristian Dumitrescu 
8355074e1d5SCristian Dumitrescu 		if (n_tokens < t0 + 6) {
8365074e1d5SCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_MISMATCH,
8375074e1d5SCristian Dumitrescu 				"pipeline port out link");
8385074e1d5SCristian Dumitrescu 			return;
8395074e1d5SCristian Dumitrescu 		}
8405074e1d5SCristian Dumitrescu 
8415074e1d5SCristian Dumitrescu 		link = link_find(obj, tokens[t0 + 1]);
8425074e1d5SCristian Dumitrescu 		if (!link) {
8435074e1d5SCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_INVALID,
8445074e1d5SCristian Dumitrescu 				"link_name");
8455074e1d5SCristian Dumitrescu 			return;
8465074e1d5SCristian Dumitrescu 		}
8475074e1d5SCristian Dumitrescu 		params.dev_name = link->dev_name;
8485074e1d5SCristian Dumitrescu 
8495074e1d5SCristian Dumitrescu 		if (strcmp(tokens[t0 + 2], "txq") != 0) {
8505074e1d5SCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_NOT_FOUND, "txq");
8515074e1d5SCristian Dumitrescu 			return;
8525074e1d5SCristian Dumitrescu 		}
8535074e1d5SCristian Dumitrescu 
8545074e1d5SCristian Dumitrescu 		if (parser_read_uint16(&params.queue_id, tokens[t0 + 3]) != 0) {
8555074e1d5SCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_INVALID,
8565074e1d5SCristian Dumitrescu 				"queue_id");
8575074e1d5SCristian Dumitrescu 			return;
8585074e1d5SCristian Dumitrescu 		}
8595074e1d5SCristian Dumitrescu 
8605074e1d5SCristian Dumitrescu 		if (strcmp(tokens[t0 + 4], "bsz") != 0) {
8615074e1d5SCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_NOT_FOUND, "bsz");
8625074e1d5SCristian Dumitrescu 			return;
8635074e1d5SCristian Dumitrescu 		}
8645074e1d5SCristian Dumitrescu 
8655074e1d5SCristian Dumitrescu 		if (parser_read_uint32(&params.burst_size, tokens[t0 + 5])) {
8665074e1d5SCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_INVALID,
8675074e1d5SCristian Dumitrescu 				"burst_size");
8685074e1d5SCristian Dumitrescu 			return;
8695074e1d5SCristian Dumitrescu 		}
8705074e1d5SCristian Dumitrescu 
8715074e1d5SCristian Dumitrescu 		t0 += 6;
8725074e1d5SCristian Dumitrescu 
8735074e1d5SCristian Dumitrescu 		status = rte_swx_pipeline_port_out_config(p->p,
8745074e1d5SCristian Dumitrescu 			port_id,
8755074e1d5SCristian Dumitrescu 			"ethdev",
8765074e1d5SCristian Dumitrescu 			&params);
87777a41301SCristian Dumitrescu 	} else if (strcmp(tokens[t0], "ring") == 0) {
87877a41301SCristian Dumitrescu 		struct rte_swx_port_ring_writer_params params;
87977a41301SCristian Dumitrescu 		struct ring *ring;
88077a41301SCristian Dumitrescu 
88177a41301SCristian Dumitrescu 		if (n_tokens < t0 + 4) {
88277a41301SCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_MISMATCH,
88377a41301SCristian Dumitrescu 				"pipeline port out link");
88477a41301SCristian Dumitrescu 			return;
88577a41301SCristian Dumitrescu 		}
88677a41301SCristian Dumitrescu 
88777a41301SCristian Dumitrescu 		ring = ring_find(obj, tokens[t0 + 1]);
88877a41301SCristian Dumitrescu 		if (!ring) {
88977a41301SCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_INVALID,
89077a41301SCristian Dumitrescu 				"ring_name");
89177a41301SCristian Dumitrescu 			return;
89277a41301SCristian Dumitrescu 		}
89377a41301SCristian Dumitrescu 		params.name = ring->name;
89477a41301SCristian Dumitrescu 
89577a41301SCristian Dumitrescu 		if (strcmp(tokens[t0 + 2], "bsz") != 0) {
89677a41301SCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_NOT_FOUND, "bsz");
89777a41301SCristian Dumitrescu 			return;
89877a41301SCristian Dumitrescu 		}
89977a41301SCristian Dumitrescu 
90077a41301SCristian Dumitrescu 		if (parser_read_uint32(&params.burst_size, tokens[t0 + 3])) {
90177a41301SCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_INVALID,
90277a41301SCristian Dumitrescu 				"burst_size");
90377a41301SCristian Dumitrescu 			return;
90477a41301SCristian Dumitrescu 		}
90577a41301SCristian Dumitrescu 
90677a41301SCristian Dumitrescu 		t0 += 4;
90777a41301SCristian Dumitrescu 
90877a41301SCristian Dumitrescu 		status = rte_swx_pipeline_port_out_config(p->p,
90977a41301SCristian Dumitrescu 			port_id,
91077a41301SCristian Dumitrescu 			"ring",
91177a41301SCristian Dumitrescu 			&params);
9125074e1d5SCristian Dumitrescu 	} else if (strcmp(tokens[t0], "sink") == 0) {
9135074e1d5SCristian Dumitrescu 		struct rte_swx_port_sink_params params;
9145074e1d5SCristian Dumitrescu 
9155074e1d5SCristian Dumitrescu 		params.file_name = strcmp(tokens[t0 + 1], "none") ?
9165074e1d5SCristian Dumitrescu 			tokens[t0 + 1] : NULL;
9175074e1d5SCristian Dumitrescu 
9185074e1d5SCristian Dumitrescu 		t0 += 2;
9195074e1d5SCristian Dumitrescu 
9205074e1d5SCristian Dumitrescu 		status = rte_swx_pipeline_port_out_config(p->p,
9215074e1d5SCristian Dumitrescu 			port_id,
9225074e1d5SCristian Dumitrescu 			"sink",
9235074e1d5SCristian Dumitrescu 			&params);
924e2b8dc52SVenkata Suresh Kumar P 	} else if (strcmp(tokens[t0], "tap") == 0) {
925e2b8dc52SVenkata Suresh Kumar P 		struct rte_swx_port_fd_writer_params params;
926e2b8dc52SVenkata Suresh Kumar P 		struct tap *tap;
927e2b8dc52SVenkata Suresh Kumar P 
928e2b8dc52SVenkata Suresh Kumar P 		if (n_tokens < t0 + 4) {
929e2b8dc52SVenkata Suresh Kumar P 			snprintf(out, out_size, MSG_ARG_MISMATCH,
930e2b8dc52SVenkata Suresh Kumar P 				"pipeline port out tap");
931e2b8dc52SVenkata Suresh Kumar P 			return;
932e2b8dc52SVenkata Suresh Kumar P 		}
933e2b8dc52SVenkata Suresh Kumar P 
934e2b8dc52SVenkata Suresh Kumar P 		tap = tap_find(obj, tokens[t0 + 1]);
935e2b8dc52SVenkata Suresh Kumar P 		if (!tap) {
936e2b8dc52SVenkata Suresh Kumar P 			snprintf(out, out_size, MSG_ARG_INVALID,
937e2b8dc52SVenkata Suresh Kumar P 				"tap_name");
938e2b8dc52SVenkata Suresh Kumar P 			return;
939e2b8dc52SVenkata Suresh Kumar P 		}
940e2b8dc52SVenkata Suresh Kumar P 		params.fd = tap->fd;
941e2b8dc52SVenkata Suresh Kumar P 
942e2b8dc52SVenkata Suresh Kumar P 		if (strcmp(tokens[t0 + 2], "bsz") != 0) {
943e2b8dc52SVenkata Suresh Kumar P 			snprintf(out, out_size, MSG_ARG_NOT_FOUND, "bsz");
944e2b8dc52SVenkata Suresh Kumar P 			return;
945e2b8dc52SVenkata Suresh Kumar P 		}
946e2b8dc52SVenkata Suresh Kumar P 
947e2b8dc52SVenkata Suresh Kumar P 		if (parser_read_uint32(&params.burst_size, tokens[t0 + 3])) {
948e2b8dc52SVenkata Suresh Kumar P 			snprintf(out, out_size, MSG_ARG_INVALID,
949e2b8dc52SVenkata Suresh Kumar P 				"burst_size");
950e2b8dc52SVenkata Suresh Kumar P 			return;
951e2b8dc52SVenkata Suresh Kumar P 		}
952e2b8dc52SVenkata Suresh Kumar P 
953e2b8dc52SVenkata Suresh Kumar P 		t0 += 4;
954e2b8dc52SVenkata Suresh Kumar P 
955e2b8dc52SVenkata Suresh Kumar P 		status = rte_swx_pipeline_port_out_config(p->p,
956e2b8dc52SVenkata Suresh Kumar P 			port_id,
957e2b8dc52SVenkata Suresh Kumar P 			"fd",
958e2b8dc52SVenkata Suresh Kumar P 			&params);
9595074e1d5SCristian Dumitrescu 	} else {
9605074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
9615074e1d5SCristian Dumitrescu 		return;
9625074e1d5SCristian Dumitrescu 	}
9635074e1d5SCristian Dumitrescu 
9645074e1d5SCristian Dumitrescu 	if (status) {
9655074e1d5SCristian Dumitrescu 		snprintf(out, out_size, "port out error.");
9665074e1d5SCristian Dumitrescu 		return;
9675074e1d5SCristian Dumitrescu 	}
9685074e1d5SCristian Dumitrescu 
9695074e1d5SCristian Dumitrescu 	if (n_tokens != t0) {
9705074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
9715074e1d5SCristian Dumitrescu 		return;
9725074e1d5SCristian Dumitrescu 	}
9735074e1d5SCristian Dumitrescu }
9745074e1d5SCristian Dumitrescu 
9755074e1d5SCristian Dumitrescu static const char cmd_pipeline_build_help[] =
9765074e1d5SCristian Dumitrescu "pipeline <pipeline_name> build <spec_file>\n";
9775074e1d5SCristian Dumitrescu 
9785074e1d5SCristian Dumitrescu static void
9795074e1d5SCristian Dumitrescu cmd_pipeline_build(char **tokens,
9805074e1d5SCristian Dumitrescu 	uint32_t n_tokens,
9815074e1d5SCristian Dumitrescu 	char *out,
9825074e1d5SCristian Dumitrescu 	size_t out_size,
9835074e1d5SCristian Dumitrescu 	void *obj)
9845074e1d5SCristian Dumitrescu {
9855074e1d5SCristian Dumitrescu 	struct pipeline *p = NULL;
9865074e1d5SCristian Dumitrescu 	FILE *spec = NULL;
9875074e1d5SCristian Dumitrescu 	uint32_t err_line;
9885074e1d5SCristian Dumitrescu 	const char *err_msg;
9895074e1d5SCristian Dumitrescu 	int status;
9905074e1d5SCristian Dumitrescu 
9915074e1d5SCristian Dumitrescu 	if (n_tokens != 4) {
9925074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
9935074e1d5SCristian Dumitrescu 		return;
9945074e1d5SCristian Dumitrescu 	}
9955074e1d5SCristian Dumitrescu 
9965074e1d5SCristian Dumitrescu 	p = pipeline_find(obj, tokens[1]);
9975074e1d5SCristian Dumitrescu 	if (!p || p->ctl) {
9985074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
9995074e1d5SCristian Dumitrescu 		return;
10005074e1d5SCristian Dumitrescu 	}
10015074e1d5SCristian Dumitrescu 
10025074e1d5SCristian Dumitrescu 	spec = fopen(tokens[3], "r");
10035074e1d5SCristian Dumitrescu 	if (!spec) {
10045074e1d5SCristian Dumitrescu 		snprintf(out, out_size, "Cannot open file %s.\n", tokens[3]);
10055074e1d5SCristian Dumitrescu 		return;
10065074e1d5SCristian Dumitrescu 	}
10075074e1d5SCristian Dumitrescu 
10085074e1d5SCristian Dumitrescu 	status = rte_swx_pipeline_build_from_spec(p->p,
10095074e1d5SCristian Dumitrescu 		spec,
10105074e1d5SCristian Dumitrescu 		&err_line,
10115074e1d5SCristian Dumitrescu 		&err_msg);
10125074e1d5SCristian Dumitrescu 	fclose(spec);
10135074e1d5SCristian Dumitrescu 	if (status) {
10145074e1d5SCristian Dumitrescu 		snprintf(out, out_size, "Error %d at line %u: %s\n.",
10155074e1d5SCristian Dumitrescu 			status, err_line, err_msg);
10165074e1d5SCristian Dumitrescu 		return;
10175074e1d5SCristian Dumitrescu 	}
10185074e1d5SCristian Dumitrescu 
10195074e1d5SCristian Dumitrescu 	p->ctl = rte_swx_ctl_pipeline_create(p->p);
10205074e1d5SCristian Dumitrescu 	if (!p->ctl) {
10215074e1d5SCristian Dumitrescu 		snprintf(out, out_size, "Pipeline control create failed.");
10225074e1d5SCristian Dumitrescu 		rte_swx_pipeline_free(p->p);
10235074e1d5SCristian Dumitrescu 		return;
10245074e1d5SCristian Dumitrescu 	}
10255074e1d5SCristian Dumitrescu }
10265074e1d5SCristian Dumitrescu 
1027275ebefeSCristian Dumitrescu static void
1028275ebefeSCristian Dumitrescu table_entry_free(struct rte_swx_table_entry *entry)
1029275ebefeSCristian Dumitrescu {
1030275ebefeSCristian Dumitrescu 	if (!entry)
1031275ebefeSCristian Dumitrescu 		return;
1032275ebefeSCristian Dumitrescu 
1033275ebefeSCristian Dumitrescu 	free(entry->key);
1034275ebefeSCristian Dumitrescu 	free(entry->key_mask);
1035275ebefeSCristian Dumitrescu 	free(entry->action_data);
1036275ebefeSCristian Dumitrescu 	free(entry);
1037275ebefeSCristian Dumitrescu }
1038275ebefeSCristian Dumitrescu 
103975129cebSChurchill Khangar #ifndef MAX_LINE_SIZE
104075129cebSChurchill Khangar #define MAX_LINE_SIZE 2048
104175129cebSChurchill Khangar #endif
104275129cebSChurchill Khangar 
104375129cebSChurchill Khangar static int
104475129cebSChurchill Khangar pipeline_table_entries_add(struct rte_swx_ctl_pipeline *p,
104575129cebSChurchill Khangar 			   const char *table_name,
104675129cebSChurchill Khangar 			   FILE *file,
104775129cebSChurchill Khangar 			   uint32_t *file_line_number)
104875129cebSChurchill Khangar {
104975129cebSChurchill Khangar 	char *line = NULL;
105075129cebSChurchill Khangar 	uint32_t line_id = 0;
105175129cebSChurchill Khangar 	int status = 0;
105275129cebSChurchill Khangar 
105375129cebSChurchill Khangar 	/* Buffer allocation. */
105475129cebSChurchill Khangar 	line = malloc(MAX_LINE_SIZE);
105575129cebSChurchill Khangar 	if (!line)
105675129cebSChurchill Khangar 		return -ENOMEM;
105775129cebSChurchill Khangar 
105875129cebSChurchill Khangar 	/* File read. */
105975129cebSChurchill Khangar 	for (line_id = 1; ; line_id++) {
106075129cebSChurchill Khangar 		struct rte_swx_table_entry *entry;
106175129cebSChurchill Khangar 		int is_blank_or_comment;
106275129cebSChurchill Khangar 
106375129cebSChurchill Khangar 		if (fgets(line, MAX_LINE_SIZE, file) == NULL)
106475129cebSChurchill Khangar 			break;
106575129cebSChurchill Khangar 
106675129cebSChurchill Khangar 		entry = rte_swx_ctl_pipeline_table_entry_read(p,
106775129cebSChurchill Khangar 							      table_name,
106875129cebSChurchill Khangar 							      line,
106975129cebSChurchill Khangar 							      &is_blank_or_comment);
107075129cebSChurchill Khangar 		if (!entry) {
107175129cebSChurchill Khangar 			if (is_blank_or_comment)
107275129cebSChurchill Khangar 				continue;
107375129cebSChurchill Khangar 
107475129cebSChurchill Khangar 			status = -EINVAL;
107575129cebSChurchill Khangar 			goto error;
107675129cebSChurchill Khangar 		}
107775129cebSChurchill Khangar 
107875129cebSChurchill Khangar 		status = rte_swx_ctl_pipeline_table_entry_add(p,
107975129cebSChurchill Khangar 							      table_name,
108075129cebSChurchill Khangar 							      entry);
108175129cebSChurchill Khangar 		table_entry_free(entry);
108275129cebSChurchill Khangar 		if (status)
108375129cebSChurchill Khangar 			goto error;
108475129cebSChurchill Khangar 	}
108575129cebSChurchill Khangar 
108675129cebSChurchill Khangar error:
108775129cebSChurchill Khangar 	free(line);
108875129cebSChurchill Khangar 	*file_line_number = line_id;
108975129cebSChurchill Khangar 	return status;
109075129cebSChurchill Khangar }
109175129cebSChurchill Khangar 
109275129cebSChurchill Khangar static const char cmd_pipeline_table_add_help[] =
109375129cebSChurchill Khangar "pipeline <pipeline_name> table <table_name> add <file_name>\n";
10945074e1d5SCristian Dumitrescu 
10955074e1d5SCristian Dumitrescu static void
109675129cebSChurchill Khangar cmd_pipeline_table_add(char **tokens,
10975074e1d5SCristian Dumitrescu 		       uint32_t n_tokens,
10985074e1d5SCristian Dumitrescu 		       char *out,
10995074e1d5SCristian Dumitrescu 		       size_t out_size,
11005074e1d5SCristian Dumitrescu 		       void *obj)
11015074e1d5SCristian Dumitrescu {
11025074e1d5SCristian Dumitrescu 	struct pipeline *p;
110375129cebSChurchill Khangar 	char *pipeline_name, *table_name, *file_name;
110475129cebSChurchill Khangar 	FILE *file = NULL;
110575129cebSChurchill Khangar 	uint32_t file_line_number = 0;
11065074e1d5SCristian Dumitrescu 	int status;
11075074e1d5SCristian Dumitrescu 
110875129cebSChurchill Khangar 	if (n_tokens != 6) {
11095074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
11105074e1d5SCristian Dumitrescu 		return;
11115074e1d5SCristian Dumitrescu 	}
11125074e1d5SCristian Dumitrescu 
11135074e1d5SCristian Dumitrescu 	pipeline_name = tokens[1];
11145074e1d5SCristian Dumitrescu 	p = pipeline_find(obj, pipeline_name);
11155074e1d5SCristian Dumitrescu 	if (!p || !p->ctl) {
11165074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
11175074e1d5SCristian Dumitrescu 		return;
11185074e1d5SCristian Dumitrescu 	}
11195074e1d5SCristian Dumitrescu 
112075129cebSChurchill Khangar 	table_name = tokens[3];
112175129cebSChurchill Khangar 
112275129cebSChurchill Khangar 	file_name = tokens[5];
112375129cebSChurchill Khangar 	file = fopen(file_name, "r");
112475129cebSChurchill Khangar 	if (!file) {
112575129cebSChurchill Khangar 		snprintf(out, out_size, "Cannot open file %s.\n", file_name);
112675129cebSChurchill Khangar 		return;
112775129cebSChurchill Khangar 	}
112875129cebSChurchill Khangar 
112975129cebSChurchill Khangar 	status = pipeline_table_entries_add(p->ctl,
113075129cebSChurchill Khangar 					    table_name,
113175129cebSChurchill Khangar 					    file,
113275129cebSChurchill Khangar 					    &file_line_number);
113375129cebSChurchill Khangar 	if (status)
113475129cebSChurchill Khangar 		snprintf(out, out_size, "Invalid entry in file %s at line %u\n",
113575129cebSChurchill Khangar 			 file_name,
113675129cebSChurchill Khangar 			 file_line_number);
113775129cebSChurchill Khangar 
113875129cebSChurchill Khangar 	fclose(file);
113975129cebSChurchill Khangar }
114075129cebSChurchill Khangar 
114175129cebSChurchill Khangar static int
114275129cebSChurchill Khangar pipeline_table_entries_delete(struct rte_swx_ctl_pipeline *p,
114375129cebSChurchill Khangar 			      const char *table_name,
114475129cebSChurchill Khangar 			      FILE *file,
114575129cebSChurchill Khangar 			      uint32_t *file_line_number)
114675129cebSChurchill Khangar {
114775129cebSChurchill Khangar 	char *line = NULL;
114875129cebSChurchill Khangar 	uint32_t line_id = 0;
114975129cebSChurchill Khangar 	int status = 0;
115075129cebSChurchill Khangar 
115175129cebSChurchill Khangar 	/* Buffer allocation. */
115275129cebSChurchill Khangar 	line = malloc(MAX_LINE_SIZE);
115375129cebSChurchill Khangar 	if (!line)
115475129cebSChurchill Khangar 		return -ENOMEM;
115575129cebSChurchill Khangar 
115675129cebSChurchill Khangar 	/* File read. */
115775129cebSChurchill Khangar 	for (line_id = 1; ; line_id++) {
115875129cebSChurchill Khangar 		struct rte_swx_table_entry *entry;
115975129cebSChurchill Khangar 		int is_blank_or_comment;
116075129cebSChurchill Khangar 
116175129cebSChurchill Khangar 		if (fgets(line, MAX_LINE_SIZE, file) == NULL)
116275129cebSChurchill Khangar 			break;
116375129cebSChurchill Khangar 
116475129cebSChurchill Khangar 		entry = rte_swx_ctl_pipeline_table_entry_read(p,
116575129cebSChurchill Khangar 							      table_name,
116675129cebSChurchill Khangar 							      line,
116775129cebSChurchill Khangar 							      &is_blank_or_comment);
116875129cebSChurchill Khangar 		if (!entry) {
116975129cebSChurchill Khangar 			if (is_blank_or_comment)
117075129cebSChurchill Khangar 				continue;
117175129cebSChurchill Khangar 
117275129cebSChurchill Khangar 			status = -EINVAL;
117375129cebSChurchill Khangar 			goto error;
117475129cebSChurchill Khangar 		}
117575129cebSChurchill Khangar 
117675129cebSChurchill Khangar 		status = rte_swx_ctl_pipeline_table_entry_delete(p,
117775129cebSChurchill Khangar 								 table_name,
117875129cebSChurchill Khangar 								 entry);
117975129cebSChurchill Khangar 		table_entry_free(entry);
118075129cebSChurchill Khangar 		if (status)
118175129cebSChurchill Khangar 			goto error;
118275129cebSChurchill Khangar 	}
118375129cebSChurchill Khangar 
118475129cebSChurchill Khangar error:
118575129cebSChurchill Khangar 	*file_line_number = line_id;
118675129cebSChurchill Khangar 	free(line);
118775129cebSChurchill Khangar 	return status;
118875129cebSChurchill Khangar }
118975129cebSChurchill Khangar 
119075129cebSChurchill Khangar static const char cmd_pipeline_table_delete_help[] =
119175129cebSChurchill Khangar "pipeline <pipeline_name> table <table_name> delete <file_name>\n";
119275129cebSChurchill Khangar 
119375129cebSChurchill Khangar static void
119475129cebSChurchill Khangar cmd_pipeline_table_delete(char **tokens,
119575129cebSChurchill Khangar 			  uint32_t n_tokens,
119675129cebSChurchill Khangar 			  char *out,
119775129cebSChurchill Khangar 			  size_t out_size,
119875129cebSChurchill Khangar 			  void *obj)
119975129cebSChurchill Khangar {
120075129cebSChurchill Khangar 	struct pipeline *p;
120175129cebSChurchill Khangar 	char *pipeline_name, *table_name, *file_name;
120275129cebSChurchill Khangar 	FILE *file = NULL;
120375129cebSChurchill Khangar 	uint32_t file_line_number = 0;
120475129cebSChurchill Khangar 	int status;
120575129cebSChurchill Khangar 
120675129cebSChurchill Khangar 	if (n_tokens != 6) {
120775129cebSChurchill Khangar 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
120875129cebSChurchill Khangar 		return;
120975129cebSChurchill Khangar 	}
121075129cebSChurchill Khangar 
121175129cebSChurchill Khangar 	pipeline_name = tokens[1];
121275129cebSChurchill Khangar 	p = pipeline_find(obj, pipeline_name);
121375129cebSChurchill Khangar 	if (!p || !p->ctl) {
121475129cebSChurchill Khangar 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
12155074e1d5SCristian Dumitrescu 		return;
12165074e1d5SCristian Dumitrescu 	}
12175074e1d5SCristian Dumitrescu 
12185074e1d5SCristian Dumitrescu 	table_name = tokens[3];
12195074e1d5SCristian Dumitrescu 
122075129cebSChurchill Khangar 	file_name = tokens[5];
122175129cebSChurchill Khangar 	file = fopen(file_name, "r");
122275129cebSChurchill Khangar 	if (!file) {
122375129cebSChurchill Khangar 		snprintf(out, out_size, "Cannot open file %s.\n", file_name);
12245074e1d5SCristian Dumitrescu 		return;
12255074e1d5SCristian Dumitrescu 	}
12265074e1d5SCristian Dumitrescu 
122775129cebSChurchill Khangar 	status = pipeline_table_entries_delete(p->ctl,
122875129cebSChurchill Khangar 					       table_name,
122975129cebSChurchill Khangar 					       file,
123075129cebSChurchill Khangar 					       &file_line_number);
123175129cebSChurchill Khangar 	if (status)
123275129cebSChurchill Khangar 		snprintf(out, out_size, "Invalid entry in file %s at line %u\n",
123375129cebSChurchill Khangar 			 file_name,
123475129cebSChurchill Khangar 			 file_line_number);
12355074e1d5SCristian Dumitrescu 
123675129cebSChurchill Khangar 	fclose(file);
12375074e1d5SCristian Dumitrescu }
12385074e1d5SCristian Dumitrescu 
123975129cebSChurchill Khangar static int
124075129cebSChurchill Khangar pipeline_table_default_entry_add(struct rte_swx_ctl_pipeline *p,
124175129cebSChurchill Khangar 				 const char *table_name,
124275129cebSChurchill Khangar 				 FILE *file,
124375129cebSChurchill Khangar 				 uint32_t *file_line_number)
124475129cebSChurchill Khangar {
124575129cebSChurchill Khangar 	char *line = NULL;
124675129cebSChurchill Khangar 	uint32_t line_id = 0;
124775129cebSChurchill Khangar 	int status = 0;
12485074e1d5SCristian Dumitrescu 
12495074e1d5SCristian Dumitrescu 	/* Buffer allocation. */
125075129cebSChurchill Khangar 	line = malloc(MAX_LINE_SIZE);
125175129cebSChurchill Khangar 	if (!line)
125275129cebSChurchill Khangar 		return -ENOMEM;
12535074e1d5SCristian Dumitrescu 
125475129cebSChurchill Khangar 	/* File read. */
12555074e1d5SCristian Dumitrescu 	for (line_id = 1; ; line_id++) {
12565074e1d5SCristian Dumitrescu 		struct rte_swx_table_entry *entry;
1257cff9a717SCristian Dumitrescu 		int is_blank_or_comment;
12585074e1d5SCristian Dumitrescu 
125975129cebSChurchill Khangar 		if (fgets(line, MAX_LINE_SIZE, file) == NULL)
12605074e1d5SCristian Dumitrescu 			break;
12615074e1d5SCristian Dumitrescu 
126275129cebSChurchill Khangar 		entry = rte_swx_ctl_pipeline_table_entry_read(p,
12635074e1d5SCristian Dumitrescu 							      table_name,
1264cff9a717SCristian Dumitrescu 							      line,
1265cff9a717SCristian Dumitrescu 							      &is_blank_or_comment);
12665074e1d5SCristian Dumitrescu 		if (!entry) {
1267cff9a717SCristian Dumitrescu 			if (is_blank_or_comment)
1268cff9a717SCristian Dumitrescu 				continue;
1269cff9a717SCristian Dumitrescu 
127075129cebSChurchill Khangar 			status = -EINVAL;
12715074e1d5SCristian Dumitrescu 			goto error;
12725074e1d5SCristian Dumitrescu 		}
12735074e1d5SCristian Dumitrescu 
127475129cebSChurchill Khangar 		status = rte_swx_ctl_pipeline_table_default_entry_add(p,
12755074e1d5SCristian Dumitrescu 								      table_name,
12765074e1d5SCristian Dumitrescu 								      entry);
1277275ebefeSCristian Dumitrescu 		table_entry_free(entry);
127875129cebSChurchill Khangar 		if (status)
12795074e1d5SCristian Dumitrescu 			goto error;
12805074e1d5SCristian Dumitrescu 	}
128175129cebSChurchill Khangar 
128275129cebSChurchill Khangar error:
128375129cebSChurchill Khangar 	*file_line_number = line_id;
128475129cebSChurchill Khangar 	free(line);
128575129cebSChurchill Khangar 	return status;
12865074e1d5SCristian Dumitrescu }
12875074e1d5SCristian Dumitrescu 
128875129cebSChurchill Khangar static const char cmd_pipeline_table_default_help[] =
128975129cebSChurchill Khangar "pipeline <pipeline_name> table <table_name> default <file_name>\n";
12905074e1d5SCristian Dumitrescu 
129175129cebSChurchill Khangar static void
129275129cebSChurchill Khangar cmd_pipeline_table_default(char **tokens,
129375129cebSChurchill Khangar 			   uint32_t n_tokens,
129475129cebSChurchill Khangar 			   char *out,
129575129cebSChurchill Khangar 			   size_t out_size,
129675129cebSChurchill Khangar 			   void *obj)
129775129cebSChurchill Khangar {
129875129cebSChurchill Khangar 	struct pipeline *p;
129975129cebSChurchill Khangar 	char *pipeline_name, *table_name, *file_name;
130075129cebSChurchill Khangar 	FILE *file = NULL;
130175129cebSChurchill Khangar 	uint32_t file_line_number = 0;
130275129cebSChurchill Khangar 	int status;
13035074e1d5SCristian Dumitrescu 
130475129cebSChurchill Khangar 	if (n_tokens != 6) {
130575129cebSChurchill Khangar 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
130675129cebSChurchill Khangar 		return;
130775129cebSChurchill Khangar 	}
13085074e1d5SCristian Dumitrescu 
130975129cebSChurchill Khangar 	pipeline_name = tokens[1];
131075129cebSChurchill Khangar 	p = pipeline_find(obj, pipeline_name);
131175129cebSChurchill Khangar 	if (!p || !p->ctl) {
131275129cebSChurchill Khangar 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
131375129cebSChurchill Khangar 		return;
131475129cebSChurchill Khangar 	}
131575129cebSChurchill Khangar 
131675129cebSChurchill Khangar 	table_name = tokens[3];
131775129cebSChurchill Khangar 
131875129cebSChurchill Khangar 	file_name = tokens[5];
131975129cebSChurchill Khangar 	file = fopen(file_name, "r");
132075129cebSChurchill Khangar 	if (!file) {
132175129cebSChurchill Khangar 		snprintf(out, out_size, "Cannot open file %s.\n", file_name);
132275129cebSChurchill Khangar 		return;
132375129cebSChurchill Khangar 	}
132475129cebSChurchill Khangar 
132575129cebSChurchill Khangar 	status = pipeline_table_default_entry_add(p->ctl,
13265074e1d5SCristian Dumitrescu 						  table_name,
132775129cebSChurchill Khangar 						  file,
132875129cebSChurchill Khangar 						  &file_line_number);
132975129cebSChurchill Khangar 	if (status)
133075129cebSChurchill Khangar 		snprintf(out, out_size, "Invalid entry in file %s at line %u\n",
133175129cebSChurchill Khangar 			 file_name,
133275129cebSChurchill Khangar 			 file_line_number);
1333cff9a717SCristian Dumitrescu 
133475129cebSChurchill Khangar 	fclose(file);
13355074e1d5SCristian Dumitrescu }
13365074e1d5SCristian Dumitrescu 
133775129cebSChurchill Khangar static const char cmd_pipeline_table_show_help[] =
133875129cebSChurchill Khangar "pipeline <pipeline_name> table <table_name> show\n";
133975129cebSChurchill Khangar 
134075129cebSChurchill Khangar static void
134175129cebSChurchill Khangar cmd_pipeline_table_show(char **tokens,
134275129cebSChurchill Khangar 	uint32_t n_tokens,
134375129cebSChurchill Khangar 	char *out,
134475129cebSChurchill Khangar 	size_t out_size,
134575129cebSChurchill Khangar 	void *obj)
134675129cebSChurchill Khangar {
134775129cebSChurchill Khangar 	struct pipeline *p;
134875129cebSChurchill Khangar 	char *pipeline_name, *table_name;
134975129cebSChurchill Khangar 	int status;
135075129cebSChurchill Khangar 
135175129cebSChurchill Khangar 	if (n_tokens != 5) {
135275129cebSChurchill Khangar 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
135375129cebSChurchill Khangar 		return;
13545074e1d5SCristian Dumitrescu 	}
13555074e1d5SCristian Dumitrescu 
135675129cebSChurchill Khangar 	pipeline_name = tokens[1];
135775129cebSChurchill Khangar 	p = pipeline_find(obj, pipeline_name);
135875129cebSChurchill Khangar 	if (!p || !p->ctl) {
135975129cebSChurchill Khangar 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
136075129cebSChurchill Khangar 		return;
13615074e1d5SCristian Dumitrescu 	}
13625074e1d5SCristian Dumitrescu 
136375129cebSChurchill Khangar 	table_name = tokens[3];
136475129cebSChurchill Khangar 	status = rte_swx_ctl_pipeline_table_fprintf(stdout, p->ctl, table_name);
136575129cebSChurchill Khangar 	if (status)
136675129cebSChurchill Khangar 		snprintf(out, out_size, MSG_ARG_INVALID, "table_name");
13675074e1d5SCristian Dumitrescu }
136875129cebSChurchill Khangar 
1369598fe0ddSCristian Dumitrescu static const char cmd_pipeline_selector_group_add_help[] =
1370598fe0ddSCristian Dumitrescu "pipeline <pipeline_name> selector <selector_name> group add\n";
1371598fe0ddSCristian Dumitrescu 
1372598fe0ddSCristian Dumitrescu static void
1373598fe0ddSCristian Dumitrescu cmd_pipeline_selector_group_add(char **tokens,
1374598fe0ddSCristian Dumitrescu 	uint32_t n_tokens,
1375598fe0ddSCristian Dumitrescu 	char *out,
1376598fe0ddSCristian Dumitrescu 	size_t out_size,
1377598fe0ddSCristian Dumitrescu 	void *obj)
1378598fe0ddSCristian Dumitrescu {
1379598fe0ddSCristian Dumitrescu 	struct pipeline *p;
1380598fe0ddSCristian Dumitrescu 	char *pipeline_name, *selector_name;
1381598fe0ddSCristian Dumitrescu 	uint32_t group_id;
1382598fe0ddSCristian Dumitrescu 	int status;
1383598fe0ddSCristian Dumitrescu 
1384598fe0ddSCristian Dumitrescu 	if (n_tokens != 6) {
1385598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1386598fe0ddSCristian Dumitrescu 		return;
1387598fe0ddSCristian Dumitrescu 	}
1388598fe0ddSCristian Dumitrescu 
1389598fe0ddSCristian Dumitrescu 	pipeline_name = tokens[1];
1390598fe0ddSCristian Dumitrescu 	p = pipeline_find(obj, pipeline_name);
1391598fe0ddSCristian Dumitrescu 	if (!p || !p->ctl) {
1392598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
1393598fe0ddSCristian Dumitrescu 		return;
1394598fe0ddSCristian Dumitrescu 	}
1395598fe0ddSCristian Dumitrescu 
1396598fe0ddSCristian Dumitrescu 	if (strcmp(tokens[2], "selector") != 0) {
1397598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "selector");
1398598fe0ddSCristian Dumitrescu 		return;
1399598fe0ddSCristian Dumitrescu 	}
1400598fe0ddSCristian Dumitrescu 
1401598fe0ddSCristian Dumitrescu 	selector_name = tokens[3];
1402598fe0ddSCristian Dumitrescu 
1403598fe0ddSCristian Dumitrescu 	if (strcmp(tokens[4], "group") ||
1404598fe0ddSCristian Dumitrescu 		strcmp(tokens[5], "add")) {
1405598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "group add");
1406598fe0ddSCristian Dumitrescu 		return;
1407598fe0ddSCristian Dumitrescu 	}
1408598fe0ddSCristian Dumitrescu 
1409598fe0ddSCristian Dumitrescu 	status = rte_swx_ctl_pipeline_selector_group_add(p->ctl,
1410598fe0ddSCristian Dumitrescu 		selector_name,
1411598fe0ddSCristian Dumitrescu 		&group_id);
1412598fe0ddSCristian Dumitrescu 	if (status)
1413598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
1414598fe0ddSCristian Dumitrescu 	else
1415598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, "Group ID: %u\n", group_id);
1416598fe0ddSCristian Dumitrescu }
1417598fe0ddSCristian Dumitrescu 
1418598fe0ddSCristian Dumitrescu static const char cmd_pipeline_selector_group_delete_help[] =
1419598fe0ddSCristian Dumitrescu "pipeline <pipeline_name> selector <selector_name> group delete <group_id>\n";
1420598fe0ddSCristian Dumitrescu 
1421598fe0ddSCristian Dumitrescu static void
1422598fe0ddSCristian Dumitrescu cmd_pipeline_selector_group_delete(char **tokens,
1423598fe0ddSCristian Dumitrescu 	uint32_t n_tokens,
1424598fe0ddSCristian Dumitrescu 	char *out,
1425598fe0ddSCristian Dumitrescu 	size_t out_size,
1426598fe0ddSCristian Dumitrescu 	void *obj)
1427598fe0ddSCristian Dumitrescu {
1428598fe0ddSCristian Dumitrescu 	struct pipeline *p;
1429598fe0ddSCristian Dumitrescu 	char *pipeline_name, *selector_name;
1430598fe0ddSCristian Dumitrescu 	uint32_t group_id;
1431598fe0ddSCristian Dumitrescu 	int status;
1432598fe0ddSCristian Dumitrescu 
1433598fe0ddSCristian Dumitrescu 	if (n_tokens != 7) {
1434598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1435598fe0ddSCristian Dumitrescu 		return;
1436598fe0ddSCristian Dumitrescu 	}
1437598fe0ddSCristian Dumitrescu 
1438598fe0ddSCristian Dumitrescu 	pipeline_name = tokens[1];
1439598fe0ddSCristian Dumitrescu 	p = pipeline_find(obj, pipeline_name);
1440598fe0ddSCristian Dumitrescu 	if (!p || !p->ctl) {
1441598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
1442598fe0ddSCristian Dumitrescu 		return;
1443598fe0ddSCristian Dumitrescu 	}
1444598fe0ddSCristian Dumitrescu 
1445598fe0ddSCristian Dumitrescu 	if (strcmp(tokens[2], "selector") != 0) {
1446598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "selector");
1447598fe0ddSCristian Dumitrescu 		return;
1448598fe0ddSCristian Dumitrescu 	}
1449598fe0ddSCristian Dumitrescu 
1450598fe0ddSCristian Dumitrescu 	selector_name = tokens[3];
1451598fe0ddSCristian Dumitrescu 
1452598fe0ddSCristian Dumitrescu 	if (strcmp(tokens[4], "group") ||
1453598fe0ddSCristian Dumitrescu 		strcmp(tokens[5], "delete")) {
1454598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "group delete");
1455598fe0ddSCristian Dumitrescu 		return;
1456598fe0ddSCristian Dumitrescu 	}
1457598fe0ddSCristian Dumitrescu 
1458598fe0ddSCristian Dumitrescu 	if (parser_read_uint32(&group_id, tokens[6]) != 0) {
1459598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "group_id");
1460598fe0ddSCristian Dumitrescu 		return;
1461598fe0ddSCristian Dumitrescu 	}
1462598fe0ddSCristian Dumitrescu 
1463598fe0ddSCristian Dumitrescu 	status = rte_swx_ctl_pipeline_selector_group_delete(p->ctl,
1464598fe0ddSCristian Dumitrescu 		selector_name,
1465598fe0ddSCristian Dumitrescu 		group_id);
1466598fe0ddSCristian Dumitrescu 	if (status)
1467598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
1468598fe0ddSCristian Dumitrescu }
1469598fe0ddSCristian Dumitrescu 
1470598fe0ddSCristian Dumitrescu #define GROUP_MEMBER_INFO_TOKENS_MAX 6
1471598fe0ddSCristian Dumitrescu 
1472598fe0ddSCristian Dumitrescu static int
1473598fe0ddSCristian Dumitrescu token_is_comment(const char *token)
1474598fe0ddSCristian Dumitrescu {
1475598fe0ddSCristian Dumitrescu 	if ((token[0] == '#') ||
1476598fe0ddSCristian Dumitrescu 	    (token[0] == ';') ||
1477598fe0ddSCristian Dumitrescu 	    ((token[0] == '/') && (token[1] == '/')))
1478598fe0ddSCristian Dumitrescu 		return 1; /* TRUE. */
1479598fe0ddSCristian Dumitrescu 
1480598fe0ddSCristian Dumitrescu 	return 0; /* FALSE. */
1481598fe0ddSCristian Dumitrescu }
1482598fe0ddSCristian Dumitrescu 
1483598fe0ddSCristian Dumitrescu static int
1484598fe0ddSCristian Dumitrescu pipeline_selector_group_member_read(const char *string,
1485598fe0ddSCristian Dumitrescu 				      uint32_t *group_id,
1486598fe0ddSCristian Dumitrescu 				      uint32_t *member_id,
1487598fe0ddSCristian Dumitrescu 				      uint32_t *weight,
1488598fe0ddSCristian Dumitrescu 				      int *is_blank_or_comment)
1489598fe0ddSCristian Dumitrescu {
1490598fe0ddSCristian Dumitrescu 	char *token_array[GROUP_MEMBER_INFO_TOKENS_MAX], **tokens;
1491598fe0ddSCristian Dumitrescu 	char *s0 = NULL, *s;
149200b67591SAli Alnubani 	uint32_t n_tokens = 0, group_id_val = 0, member_id_val = 0, weight_val = 0;
1493598fe0ddSCristian Dumitrescu 	int blank_or_comment = 0;
1494598fe0ddSCristian Dumitrescu 
1495598fe0ddSCristian Dumitrescu 	/* Check input arguments. */
1496598fe0ddSCristian Dumitrescu 	if (!string || !string[0])
1497598fe0ddSCristian Dumitrescu 		goto error;
1498598fe0ddSCristian Dumitrescu 
1499598fe0ddSCristian Dumitrescu 	/* Memory allocation. */
1500598fe0ddSCristian Dumitrescu 	s0 = strdup(string);
1501598fe0ddSCristian Dumitrescu 	if (!s0)
1502598fe0ddSCristian Dumitrescu 		goto error;
1503598fe0ddSCristian Dumitrescu 
1504598fe0ddSCristian Dumitrescu 	/* Parse the string into tokens. */
1505598fe0ddSCristian Dumitrescu 	for (s = s0; ; ) {
1506598fe0ddSCristian Dumitrescu 		char *token;
1507598fe0ddSCristian Dumitrescu 
1508598fe0ddSCristian Dumitrescu 		token = strtok_r(s, " \f\n\r\t\v", &s);
1509598fe0ddSCristian Dumitrescu 		if (!token || token_is_comment(token))
1510598fe0ddSCristian Dumitrescu 			break;
1511598fe0ddSCristian Dumitrescu 
1512cfcc7bf8SCristian Dumitrescu 		if (n_tokens >= GROUP_MEMBER_INFO_TOKENS_MAX)
1513598fe0ddSCristian Dumitrescu 			goto error;
1514598fe0ddSCristian Dumitrescu 
1515598fe0ddSCristian Dumitrescu 		token_array[n_tokens] = token;
1516598fe0ddSCristian Dumitrescu 		n_tokens++;
1517598fe0ddSCristian Dumitrescu 	}
1518598fe0ddSCristian Dumitrescu 
1519598fe0ddSCristian Dumitrescu 	if (!n_tokens) {
1520598fe0ddSCristian Dumitrescu 		blank_or_comment = 1;
1521598fe0ddSCristian Dumitrescu 		goto error;
1522598fe0ddSCristian Dumitrescu 	}
1523598fe0ddSCristian Dumitrescu 
1524598fe0ddSCristian Dumitrescu 	tokens = token_array;
1525598fe0ddSCristian Dumitrescu 
1526598fe0ddSCristian Dumitrescu 	if (n_tokens < 4 ||
1527598fe0ddSCristian Dumitrescu 		strcmp(tokens[0], "group") ||
1528598fe0ddSCristian Dumitrescu 		strcmp(tokens[2], "member"))
1529598fe0ddSCristian Dumitrescu 		goto error;
1530598fe0ddSCristian Dumitrescu 
1531598fe0ddSCristian Dumitrescu 	/*
1532598fe0ddSCristian Dumitrescu 	 * Group ID.
1533598fe0ddSCristian Dumitrescu 	 */
1534598fe0ddSCristian Dumitrescu 	if (parser_read_uint32(&group_id_val, tokens[1]) != 0)
1535598fe0ddSCristian Dumitrescu 		goto error;
1536598fe0ddSCristian Dumitrescu 	*group_id = group_id_val;
1537598fe0ddSCristian Dumitrescu 
1538598fe0ddSCristian Dumitrescu 	/*
1539598fe0ddSCristian Dumitrescu 	 * Member ID.
1540598fe0ddSCristian Dumitrescu 	 */
1541598fe0ddSCristian Dumitrescu 	if (parser_read_uint32(&member_id_val, tokens[3]) != 0)
1542598fe0ddSCristian Dumitrescu 		goto error;
1543598fe0ddSCristian Dumitrescu 	*member_id = member_id_val;
1544598fe0ddSCristian Dumitrescu 
1545598fe0ddSCristian Dumitrescu 	tokens += 4;
1546598fe0ddSCristian Dumitrescu 	n_tokens -= 4;
1547598fe0ddSCristian Dumitrescu 
1548598fe0ddSCristian Dumitrescu 	/*
1549598fe0ddSCristian Dumitrescu 	 * Weight.
1550598fe0ddSCristian Dumitrescu 	 */
1551598fe0ddSCristian Dumitrescu 	if (n_tokens && !strcmp(tokens[0], "weight")) {
1552598fe0ddSCristian Dumitrescu 		if (n_tokens < 2)
1553598fe0ddSCristian Dumitrescu 			goto error;
1554598fe0ddSCristian Dumitrescu 
1555598fe0ddSCristian Dumitrescu 		if (parser_read_uint32(&weight_val, tokens[1]) != 0)
1556598fe0ddSCristian Dumitrescu 			goto error;
1557598fe0ddSCristian Dumitrescu 		*weight = weight_val;
1558598fe0ddSCristian Dumitrescu 
1559598fe0ddSCristian Dumitrescu 		tokens += 2;
1560598fe0ddSCristian Dumitrescu 		n_tokens -= 2;
1561598fe0ddSCristian Dumitrescu 	}
1562598fe0ddSCristian Dumitrescu 
1563598fe0ddSCristian Dumitrescu 	if (n_tokens)
1564598fe0ddSCristian Dumitrescu 		goto error;
1565598fe0ddSCristian Dumitrescu 
1566598fe0ddSCristian Dumitrescu 	free(s0);
1567598fe0ddSCristian Dumitrescu 	return 0;
1568598fe0ddSCristian Dumitrescu 
1569598fe0ddSCristian Dumitrescu error:
1570598fe0ddSCristian Dumitrescu 	free(s0);
1571598fe0ddSCristian Dumitrescu 	if (is_blank_or_comment)
1572598fe0ddSCristian Dumitrescu 		*is_blank_or_comment = blank_or_comment;
1573598fe0ddSCristian Dumitrescu 	return -EINVAL;
1574598fe0ddSCristian Dumitrescu }
1575598fe0ddSCristian Dumitrescu 
1576598fe0ddSCristian Dumitrescu static int
1577598fe0ddSCristian Dumitrescu pipeline_selector_group_members_add(struct rte_swx_ctl_pipeline *p,
1578598fe0ddSCristian Dumitrescu 			   const char *selector_name,
1579598fe0ddSCristian Dumitrescu 			   FILE *file,
1580598fe0ddSCristian Dumitrescu 			   uint32_t *file_line_number)
1581598fe0ddSCristian Dumitrescu {
1582598fe0ddSCristian Dumitrescu 	char *line = NULL;
1583598fe0ddSCristian Dumitrescu 	uint32_t line_id = 0;
1584598fe0ddSCristian Dumitrescu 	int status = 0;
1585598fe0ddSCristian Dumitrescu 
1586598fe0ddSCristian Dumitrescu 	/* Buffer allocation. */
1587598fe0ddSCristian Dumitrescu 	line = malloc(MAX_LINE_SIZE);
1588598fe0ddSCristian Dumitrescu 	if (!line)
1589598fe0ddSCristian Dumitrescu 		return -ENOMEM;
1590598fe0ddSCristian Dumitrescu 
1591598fe0ddSCristian Dumitrescu 	/* File read. */
1592598fe0ddSCristian Dumitrescu 	for (line_id = 1; ; line_id++) {
1593598fe0ddSCristian Dumitrescu 		uint32_t group_id, member_id, weight;
1594598fe0ddSCristian Dumitrescu 		int is_blank_or_comment;
1595598fe0ddSCristian Dumitrescu 
1596598fe0ddSCristian Dumitrescu 		if (fgets(line, MAX_LINE_SIZE, file) == NULL)
1597598fe0ddSCristian Dumitrescu 			break;
1598598fe0ddSCristian Dumitrescu 
1599598fe0ddSCristian Dumitrescu 		status = pipeline_selector_group_member_read(line,
1600598fe0ddSCristian Dumitrescu 							      &group_id,
1601598fe0ddSCristian Dumitrescu 							      &member_id,
1602598fe0ddSCristian Dumitrescu 							      &weight,
1603598fe0ddSCristian Dumitrescu 							      &is_blank_or_comment);
1604598fe0ddSCristian Dumitrescu 		if (status) {
1605598fe0ddSCristian Dumitrescu 			if (is_blank_or_comment)
1606598fe0ddSCristian Dumitrescu 				continue;
1607598fe0ddSCristian Dumitrescu 
1608598fe0ddSCristian Dumitrescu 			goto error;
1609598fe0ddSCristian Dumitrescu 		}
1610598fe0ddSCristian Dumitrescu 
1611598fe0ddSCristian Dumitrescu 		status = rte_swx_ctl_pipeline_selector_group_member_add(p,
1612598fe0ddSCristian Dumitrescu 			selector_name,
1613598fe0ddSCristian Dumitrescu 			group_id,
1614598fe0ddSCristian Dumitrescu 			member_id,
1615598fe0ddSCristian Dumitrescu 			weight);
1616598fe0ddSCristian Dumitrescu 		if (status)
1617598fe0ddSCristian Dumitrescu 			goto error;
1618598fe0ddSCristian Dumitrescu 	}
1619598fe0ddSCristian Dumitrescu 
1620598fe0ddSCristian Dumitrescu error:
1621598fe0ddSCristian Dumitrescu 	free(line);
1622598fe0ddSCristian Dumitrescu 	*file_line_number = line_id;
1623598fe0ddSCristian Dumitrescu 	return status;
1624598fe0ddSCristian Dumitrescu }
1625598fe0ddSCristian Dumitrescu 
1626598fe0ddSCristian Dumitrescu static const char cmd_pipeline_selector_group_member_add_help[] =
1627598fe0ddSCristian Dumitrescu "pipeline <pipeline_name> selector <selector_name> group member add <file_name>";
1628598fe0ddSCristian Dumitrescu 
1629598fe0ddSCristian Dumitrescu static void
1630598fe0ddSCristian Dumitrescu cmd_pipeline_selector_group_member_add(char **tokens,
1631598fe0ddSCristian Dumitrescu 	uint32_t n_tokens,
1632598fe0ddSCristian Dumitrescu 	char *out,
1633598fe0ddSCristian Dumitrescu 	size_t out_size,
1634598fe0ddSCristian Dumitrescu 	void *obj)
1635598fe0ddSCristian Dumitrescu {
1636598fe0ddSCristian Dumitrescu 	struct pipeline *p;
1637598fe0ddSCristian Dumitrescu 	char *pipeline_name, *selector_name, *file_name;
1638598fe0ddSCristian Dumitrescu 	FILE *file = NULL;
1639598fe0ddSCristian Dumitrescu 	uint32_t file_line_number = 0;
1640598fe0ddSCristian Dumitrescu 	int status;
1641598fe0ddSCristian Dumitrescu 
1642598fe0ddSCristian Dumitrescu 	if (n_tokens != 8) {
1643598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1644598fe0ddSCristian Dumitrescu 		return;
1645598fe0ddSCristian Dumitrescu 	}
1646598fe0ddSCristian Dumitrescu 
1647598fe0ddSCristian Dumitrescu 	pipeline_name = tokens[1];
1648598fe0ddSCristian Dumitrescu 	p = pipeline_find(obj, pipeline_name);
1649598fe0ddSCristian Dumitrescu 	if (!p || !p->ctl) {
1650598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
1651598fe0ddSCristian Dumitrescu 		return;
1652598fe0ddSCristian Dumitrescu 	}
1653598fe0ddSCristian Dumitrescu 
1654598fe0ddSCristian Dumitrescu 	if (strcmp(tokens[2], "selector") != 0) {
1655598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "selector");
1656598fe0ddSCristian Dumitrescu 		return;
1657598fe0ddSCristian Dumitrescu 	}
1658598fe0ddSCristian Dumitrescu 
1659598fe0ddSCristian Dumitrescu 	selector_name = tokens[3];
1660598fe0ddSCristian Dumitrescu 
1661598fe0ddSCristian Dumitrescu 	if (strcmp(tokens[4], "group") ||
1662598fe0ddSCristian Dumitrescu 		strcmp(tokens[5], "member") ||
1663598fe0ddSCristian Dumitrescu 		strcmp(tokens[6], "add")) {
1664598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "group member add");
1665598fe0ddSCristian Dumitrescu 		return;
1666598fe0ddSCristian Dumitrescu 	}
1667598fe0ddSCristian Dumitrescu 
1668598fe0ddSCristian Dumitrescu 	file_name = tokens[7];
1669598fe0ddSCristian Dumitrescu 	file = fopen(file_name, "r");
1670598fe0ddSCristian Dumitrescu 	if (!file) {
1671598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, "Cannot open file %s.\n", file_name);
1672598fe0ddSCristian Dumitrescu 		return;
1673598fe0ddSCristian Dumitrescu 	}
1674598fe0ddSCristian Dumitrescu 
1675598fe0ddSCristian Dumitrescu 	status = pipeline_selector_group_members_add(p->ctl,
1676598fe0ddSCristian Dumitrescu 					    selector_name,
1677598fe0ddSCristian Dumitrescu 					    file,
1678598fe0ddSCristian Dumitrescu 					    &file_line_number);
1679598fe0ddSCristian Dumitrescu 	if (status)
1680598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, "Invalid entry in file %s at line %u\n",
1681598fe0ddSCristian Dumitrescu 			 file_name,
1682598fe0ddSCristian Dumitrescu 			 file_line_number);
1683598fe0ddSCristian Dumitrescu 
1684598fe0ddSCristian Dumitrescu 	fclose(file);
1685598fe0ddSCristian Dumitrescu }
1686598fe0ddSCristian Dumitrescu 
1687598fe0ddSCristian Dumitrescu static int
1688598fe0ddSCristian Dumitrescu pipeline_selector_group_members_delete(struct rte_swx_ctl_pipeline *p,
1689598fe0ddSCristian Dumitrescu 			   const char *selector_name,
1690598fe0ddSCristian Dumitrescu 			   FILE *file,
1691598fe0ddSCristian Dumitrescu 			   uint32_t *file_line_number)
1692598fe0ddSCristian Dumitrescu {
1693598fe0ddSCristian Dumitrescu 	char *line = NULL;
1694598fe0ddSCristian Dumitrescu 	uint32_t line_id = 0;
1695598fe0ddSCristian Dumitrescu 	int status = 0;
1696598fe0ddSCristian Dumitrescu 
1697598fe0ddSCristian Dumitrescu 	/* Buffer allocation. */
1698598fe0ddSCristian Dumitrescu 	line = malloc(MAX_LINE_SIZE);
1699598fe0ddSCristian Dumitrescu 	if (!line)
1700598fe0ddSCristian Dumitrescu 		return -ENOMEM;
1701598fe0ddSCristian Dumitrescu 
1702598fe0ddSCristian Dumitrescu 	/* File read. */
1703598fe0ddSCristian Dumitrescu 	for (line_id = 1; ; line_id++) {
1704598fe0ddSCristian Dumitrescu 		uint32_t group_id, member_id, weight;
1705598fe0ddSCristian Dumitrescu 		int is_blank_or_comment;
1706598fe0ddSCristian Dumitrescu 
1707598fe0ddSCristian Dumitrescu 		if (fgets(line, MAX_LINE_SIZE, file) == NULL)
1708598fe0ddSCristian Dumitrescu 			break;
1709598fe0ddSCristian Dumitrescu 
1710598fe0ddSCristian Dumitrescu 		status = pipeline_selector_group_member_read(line,
1711598fe0ddSCristian Dumitrescu 							      &group_id,
1712598fe0ddSCristian Dumitrescu 							      &member_id,
1713598fe0ddSCristian Dumitrescu 							      &weight,
1714598fe0ddSCristian Dumitrescu 							      &is_blank_or_comment);
1715598fe0ddSCristian Dumitrescu 		if (status) {
1716598fe0ddSCristian Dumitrescu 			if (is_blank_or_comment)
1717598fe0ddSCristian Dumitrescu 				continue;
1718598fe0ddSCristian Dumitrescu 
1719598fe0ddSCristian Dumitrescu 			goto error;
1720598fe0ddSCristian Dumitrescu 		}
1721598fe0ddSCristian Dumitrescu 
1722598fe0ddSCristian Dumitrescu 		status = rte_swx_ctl_pipeline_selector_group_member_delete(p,
1723598fe0ddSCristian Dumitrescu 			selector_name,
1724598fe0ddSCristian Dumitrescu 			group_id,
1725598fe0ddSCristian Dumitrescu 			member_id);
1726598fe0ddSCristian Dumitrescu 		if (status)
1727598fe0ddSCristian Dumitrescu 			goto error;
1728598fe0ddSCristian Dumitrescu 	}
1729598fe0ddSCristian Dumitrescu 
1730598fe0ddSCristian Dumitrescu error:
1731598fe0ddSCristian Dumitrescu 	free(line);
1732598fe0ddSCristian Dumitrescu 	*file_line_number = line_id;
1733598fe0ddSCristian Dumitrescu 	return status;
1734598fe0ddSCristian Dumitrescu }
1735598fe0ddSCristian Dumitrescu 
1736598fe0ddSCristian Dumitrescu static const char cmd_pipeline_selector_group_member_delete_help[] =
1737598fe0ddSCristian Dumitrescu "pipeline <pipeline_name> selector <selector_name> group member delete <file_name>";
1738598fe0ddSCristian Dumitrescu 
1739598fe0ddSCristian Dumitrescu static void
1740598fe0ddSCristian Dumitrescu cmd_pipeline_selector_group_member_delete(char **tokens,
1741598fe0ddSCristian Dumitrescu 	uint32_t n_tokens,
1742598fe0ddSCristian Dumitrescu 	char *out,
1743598fe0ddSCristian Dumitrescu 	size_t out_size,
1744598fe0ddSCristian Dumitrescu 	void *obj)
1745598fe0ddSCristian Dumitrescu {
1746598fe0ddSCristian Dumitrescu 	struct pipeline *p;
1747598fe0ddSCristian Dumitrescu 	char *pipeline_name, *selector_name, *file_name;
1748598fe0ddSCristian Dumitrescu 	FILE *file = NULL;
1749598fe0ddSCristian Dumitrescu 	uint32_t file_line_number = 0;
1750598fe0ddSCristian Dumitrescu 	int status;
1751598fe0ddSCristian Dumitrescu 
1752598fe0ddSCristian Dumitrescu 	if (n_tokens != 8) {
1753598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1754598fe0ddSCristian Dumitrescu 		return;
1755598fe0ddSCristian Dumitrescu 	}
1756598fe0ddSCristian Dumitrescu 
1757598fe0ddSCristian Dumitrescu 	pipeline_name = tokens[1];
1758598fe0ddSCristian Dumitrescu 	p = pipeline_find(obj, pipeline_name);
1759598fe0ddSCristian Dumitrescu 	if (!p || !p->ctl) {
1760598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
1761598fe0ddSCristian Dumitrescu 		return;
1762598fe0ddSCristian Dumitrescu 	}
1763598fe0ddSCristian Dumitrescu 
1764598fe0ddSCristian Dumitrescu 	if (strcmp(tokens[2], "selector") != 0) {
1765598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "selector");
1766598fe0ddSCristian Dumitrescu 		return;
1767598fe0ddSCristian Dumitrescu 	}
1768598fe0ddSCristian Dumitrescu 
1769598fe0ddSCristian Dumitrescu 	selector_name = tokens[3];
1770598fe0ddSCristian Dumitrescu 
1771598fe0ddSCristian Dumitrescu 	if (strcmp(tokens[4], "group") ||
1772598fe0ddSCristian Dumitrescu 		strcmp(tokens[5], "member") ||
1773598fe0ddSCristian Dumitrescu 		strcmp(tokens[6], "delete")) {
1774598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "group member delete");
1775598fe0ddSCristian Dumitrescu 		return;
1776598fe0ddSCristian Dumitrescu 	}
1777598fe0ddSCristian Dumitrescu 
1778598fe0ddSCristian Dumitrescu 	file_name = tokens[7];
1779598fe0ddSCristian Dumitrescu 	file = fopen(file_name, "r");
1780598fe0ddSCristian Dumitrescu 	if (!file) {
1781598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, "Cannot open file %s.\n", file_name);
1782598fe0ddSCristian Dumitrescu 		return;
1783598fe0ddSCristian Dumitrescu 	}
1784598fe0ddSCristian Dumitrescu 
1785598fe0ddSCristian Dumitrescu 	status = pipeline_selector_group_members_delete(p->ctl,
1786598fe0ddSCristian Dumitrescu 					    selector_name,
1787598fe0ddSCristian Dumitrescu 					    file,
1788598fe0ddSCristian Dumitrescu 					    &file_line_number);
1789598fe0ddSCristian Dumitrescu 	if (status)
1790598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, "Invalid entry in file %s at line %u\n",
1791598fe0ddSCristian Dumitrescu 			 file_name,
1792598fe0ddSCristian Dumitrescu 			 file_line_number);
1793598fe0ddSCristian Dumitrescu 
1794598fe0ddSCristian Dumitrescu 	fclose(file);
1795598fe0ddSCristian Dumitrescu }
1796598fe0ddSCristian Dumitrescu 
1797598fe0ddSCristian Dumitrescu static const char cmd_pipeline_selector_show_help[] =
1798598fe0ddSCristian Dumitrescu "pipeline <pipeline_name> selector <selector_name> show\n";
1799598fe0ddSCristian Dumitrescu 
1800598fe0ddSCristian Dumitrescu static void
1801598fe0ddSCristian Dumitrescu cmd_pipeline_selector_show(char **tokens,
1802598fe0ddSCristian Dumitrescu 	uint32_t n_tokens,
1803598fe0ddSCristian Dumitrescu 	char *out,
1804598fe0ddSCristian Dumitrescu 	size_t out_size,
1805598fe0ddSCristian Dumitrescu 	void *obj)
1806598fe0ddSCristian Dumitrescu {
1807598fe0ddSCristian Dumitrescu 	struct pipeline *p;
1808598fe0ddSCristian Dumitrescu 	char *pipeline_name, *selector_name;
1809598fe0ddSCristian Dumitrescu 	int status;
1810598fe0ddSCristian Dumitrescu 
1811598fe0ddSCristian Dumitrescu 	if (n_tokens != 5) {
1812598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1813598fe0ddSCristian Dumitrescu 		return;
1814598fe0ddSCristian Dumitrescu 	}
1815598fe0ddSCristian Dumitrescu 
1816598fe0ddSCristian Dumitrescu 	pipeline_name = tokens[1];
1817598fe0ddSCristian Dumitrescu 	p = pipeline_find(obj, pipeline_name);
1818598fe0ddSCristian Dumitrescu 	if (!p || !p->ctl) {
1819598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
1820598fe0ddSCristian Dumitrescu 		return;
1821598fe0ddSCristian Dumitrescu 	}
1822598fe0ddSCristian Dumitrescu 
1823598fe0ddSCristian Dumitrescu 	selector_name = tokens[3];
1824598fe0ddSCristian Dumitrescu 	status = rte_swx_ctl_pipeline_selector_fprintf(stdout,
1825598fe0ddSCristian Dumitrescu 		p->ctl, selector_name);
1826598fe0ddSCristian Dumitrescu 	if (status)
1827598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "selector_name");
1828598fe0ddSCristian Dumitrescu }
1829598fe0ddSCristian Dumitrescu 
1830*8bd4862fSCristian Dumitrescu static int
1831*8bd4862fSCristian Dumitrescu pipeline_learner_default_entry_add(struct rte_swx_ctl_pipeline *p,
1832*8bd4862fSCristian Dumitrescu 				   const char *learner_name,
1833*8bd4862fSCristian Dumitrescu 				   FILE *file,
1834*8bd4862fSCristian Dumitrescu 				   uint32_t *file_line_number)
1835*8bd4862fSCristian Dumitrescu {
1836*8bd4862fSCristian Dumitrescu 	char *line = NULL;
1837*8bd4862fSCristian Dumitrescu 	uint32_t line_id = 0;
1838*8bd4862fSCristian Dumitrescu 	int status = 0;
1839*8bd4862fSCristian Dumitrescu 
1840*8bd4862fSCristian Dumitrescu 	/* Buffer allocation. */
1841*8bd4862fSCristian Dumitrescu 	line = malloc(MAX_LINE_SIZE);
1842*8bd4862fSCristian Dumitrescu 	if (!line)
1843*8bd4862fSCristian Dumitrescu 		return -ENOMEM;
1844*8bd4862fSCristian Dumitrescu 
1845*8bd4862fSCristian Dumitrescu 	/* File read. */
1846*8bd4862fSCristian Dumitrescu 	for (line_id = 1; ; line_id++) {
1847*8bd4862fSCristian Dumitrescu 		struct rte_swx_table_entry *entry;
1848*8bd4862fSCristian Dumitrescu 		int is_blank_or_comment;
1849*8bd4862fSCristian Dumitrescu 
1850*8bd4862fSCristian Dumitrescu 		if (fgets(line, MAX_LINE_SIZE, file) == NULL)
1851*8bd4862fSCristian Dumitrescu 			break;
1852*8bd4862fSCristian Dumitrescu 
1853*8bd4862fSCristian Dumitrescu 		entry = rte_swx_ctl_pipeline_learner_default_entry_read(p,
1854*8bd4862fSCristian Dumitrescu 									learner_name,
1855*8bd4862fSCristian Dumitrescu 									line,
1856*8bd4862fSCristian Dumitrescu 									&is_blank_or_comment);
1857*8bd4862fSCristian Dumitrescu 		if (!entry) {
1858*8bd4862fSCristian Dumitrescu 			if (is_blank_or_comment)
1859*8bd4862fSCristian Dumitrescu 				continue;
1860*8bd4862fSCristian Dumitrescu 
1861*8bd4862fSCristian Dumitrescu 			status = -EINVAL;
1862*8bd4862fSCristian Dumitrescu 			goto error;
1863*8bd4862fSCristian Dumitrescu 		}
1864*8bd4862fSCristian Dumitrescu 
1865*8bd4862fSCristian Dumitrescu 		status = rte_swx_ctl_pipeline_learner_default_entry_add(p,
1866*8bd4862fSCristian Dumitrescu 									learner_name,
1867*8bd4862fSCristian Dumitrescu 									entry);
1868*8bd4862fSCristian Dumitrescu 		table_entry_free(entry);
1869*8bd4862fSCristian Dumitrescu 		if (status)
1870*8bd4862fSCristian Dumitrescu 			goto error;
1871*8bd4862fSCristian Dumitrescu 	}
1872*8bd4862fSCristian Dumitrescu 
1873*8bd4862fSCristian Dumitrescu error:
1874*8bd4862fSCristian Dumitrescu 	*file_line_number = line_id;
1875*8bd4862fSCristian Dumitrescu 	free(line);
1876*8bd4862fSCristian Dumitrescu 	return status;
1877*8bd4862fSCristian Dumitrescu }
1878*8bd4862fSCristian Dumitrescu 
1879*8bd4862fSCristian Dumitrescu static const char cmd_pipeline_learner_default_help[] =
1880*8bd4862fSCristian Dumitrescu "pipeline <pipeline_name> learner <learner_name> default <file_name>\n";
1881*8bd4862fSCristian Dumitrescu 
1882*8bd4862fSCristian Dumitrescu static void
1883*8bd4862fSCristian Dumitrescu cmd_pipeline_learner_default(char **tokens,
1884*8bd4862fSCristian Dumitrescu 			     uint32_t n_tokens,
1885*8bd4862fSCristian Dumitrescu 			     char *out,
1886*8bd4862fSCristian Dumitrescu 			     size_t out_size,
1887*8bd4862fSCristian Dumitrescu 			     void *obj)
1888*8bd4862fSCristian Dumitrescu {
1889*8bd4862fSCristian Dumitrescu 	struct pipeline *p;
1890*8bd4862fSCristian Dumitrescu 	char *pipeline_name, *learner_name, *file_name;
1891*8bd4862fSCristian Dumitrescu 	FILE *file = NULL;
1892*8bd4862fSCristian Dumitrescu 	uint32_t file_line_number = 0;
1893*8bd4862fSCristian Dumitrescu 	int status;
1894*8bd4862fSCristian Dumitrescu 
1895*8bd4862fSCristian Dumitrescu 	if (n_tokens != 6) {
1896*8bd4862fSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1897*8bd4862fSCristian Dumitrescu 		return;
1898*8bd4862fSCristian Dumitrescu 	}
1899*8bd4862fSCristian Dumitrescu 
1900*8bd4862fSCristian Dumitrescu 	pipeline_name = tokens[1];
1901*8bd4862fSCristian Dumitrescu 	p = pipeline_find(obj, pipeline_name);
1902*8bd4862fSCristian Dumitrescu 	if (!p || !p->ctl) {
1903*8bd4862fSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
1904*8bd4862fSCristian Dumitrescu 		return;
1905*8bd4862fSCristian Dumitrescu 	}
1906*8bd4862fSCristian Dumitrescu 
1907*8bd4862fSCristian Dumitrescu 	learner_name = tokens[3];
1908*8bd4862fSCristian Dumitrescu 
1909*8bd4862fSCristian Dumitrescu 	file_name = tokens[5];
1910*8bd4862fSCristian Dumitrescu 	file = fopen(file_name, "r");
1911*8bd4862fSCristian Dumitrescu 	if (!file) {
1912*8bd4862fSCristian Dumitrescu 		snprintf(out, out_size, "Cannot open file %s.\n", file_name);
1913*8bd4862fSCristian Dumitrescu 		return;
1914*8bd4862fSCristian Dumitrescu 	}
1915*8bd4862fSCristian Dumitrescu 
1916*8bd4862fSCristian Dumitrescu 	status = pipeline_learner_default_entry_add(p->ctl,
1917*8bd4862fSCristian Dumitrescu 						    learner_name,
1918*8bd4862fSCristian Dumitrescu 						    file,
1919*8bd4862fSCristian Dumitrescu 						    &file_line_number);
1920*8bd4862fSCristian Dumitrescu 	if (status)
1921*8bd4862fSCristian Dumitrescu 		snprintf(out, out_size, "Invalid entry in file %s at line %u\n",
1922*8bd4862fSCristian Dumitrescu 			 file_name,
1923*8bd4862fSCristian Dumitrescu 			 file_line_number);
1924*8bd4862fSCristian Dumitrescu 
1925*8bd4862fSCristian Dumitrescu 	fclose(file);
1926*8bd4862fSCristian Dumitrescu }
1927*8bd4862fSCristian Dumitrescu 
192875129cebSChurchill Khangar static const char cmd_pipeline_commit_help[] =
192975129cebSChurchill Khangar "pipeline <pipeline_name> commit\n";
193075129cebSChurchill Khangar 
193175129cebSChurchill Khangar static void
193275129cebSChurchill Khangar cmd_pipeline_commit(char **tokens,
193375129cebSChurchill Khangar 	uint32_t n_tokens,
193475129cebSChurchill Khangar 	char *out,
193575129cebSChurchill Khangar 	size_t out_size,
193675129cebSChurchill Khangar 	void *obj)
193775129cebSChurchill Khangar {
193875129cebSChurchill Khangar 	struct pipeline *p;
193975129cebSChurchill Khangar 	char *pipeline_name;
194075129cebSChurchill Khangar 	int status;
194175129cebSChurchill Khangar 
194275129cebSChurchill Khangar 	if (n_tokens != 3) {
194375129cebSChurchill Khangar 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
194475129cebSChurchill Khangar 		return;
194575129cebSChurchill Khangar 	}
194675129cebSChurchill Khangar 
194775129cebSChurchill Khangar 	pipeline_name = tokens[1];
194875129cebSChurchill Khangar 	p = pipeline_find(obj, pipeline_name);
194975129cebSChurchill Khangar 	if (!p || !p->ctl) {
195075129cebSChurchill Khangar 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
195175129cebSChurchill Khangar 		return;
19525074e1d5SCristian Dumitrescu 	}
19535074e1d5SCristian Dumitrescu 
19545074e1d5SCristian Dumitrescu 	status = rte_swx_ctl_pipeline_commit(p->ctl, 1);
195575129cebSChurchill Khangar 	if (status)
195675129cebSChurchill Khangar 		snprintf(out, out_size, "Commit failed. "
195775129cebSChurchill Khangar 			"Use \"commit\" to retry or \"abort\" to discard the pending work.\n");
19585074e1d5SCristian Dumitrescu }
19595074e1d5SCristian Dumitrescu 
196075129cebSChurchill Khangar static const char cmd_pipeline_abort_help[] =
196175129cebSChurchill Khangar "pipeline <pipeline_name> abort\n";
19625074e1d5SCristian Dumitrescu 
196375129cebSChurchill Khangar static void
196475129cebSChurchill Khangar cmd_pipeline_abort(char **tokens,
196575129cebSChurchill Khangar 	uint32_t n_tokens,
196675129cebSChurchill Khangar 	char *out,
196775129cebSChurchill Khangar 	size_t out_size,
196875129cebSChurchill Khangar 	void *obj)
196975129cebSChurchill Khangar {
197075129cebSChurchill Khangar 	struct pipeline *p;
197175129cebSChurchill Khangar 	char *pipeline_name;
19725074e1d5SCristian Dumitrescu 
197375129cebSChurchill Khangar 	if (n_tokens != 3) {
197475129cebSChurchill Khangar 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
19755074e1d5SCristian Dumitrescu 		return;
197675129cebSChurchill Khangar 	}
19775074e1d5SCristian Dumitrescu 
197875129cebSChurchill Khangar 	pipeline_name = tokens[1];
197975129cebSChurchill Khangar 	p = pipeline_find(obj, pipeline_name);
198075129cebSChurchill Khangar 	if (!p || !p->ctl) {
198175129cebSChurchill Khangar 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
198275129cebSChurchill Khangar 		return;
198375129cebSChurchill Khangar 	}
198475129cebSChurchill Khangar 
19855074e1d5SCristian Dumitrescu 	rte_swx_ctl_pipeline_abort(p->ctl);
19865074e1d5SCristian Dumitrescu }
19875074e1d5SCristian Dumitrescu 
198864cfcebdSCristian Dumitrescu static const char cmd_pipeline_regrd_help[] =
198964cfcebdSCristian Dumitrescu "pipeline <pipeline_name> regrd <register_array_name> <index>\n";
199064cfcebdSCristian Dumitrescu 
199164cfcebdSCristian Dumitrescu static void
199264cfcebdSCristian Dumitrescu cmd_pipeline_regrd(char **tokens,
199364cfcebdSCristian Dumitrescu 	uint32_t n_tokens,
199464cfcebdSCristian Dumitrescu 	char *out,
199564cfcebdSCristian Dumitrescu 	size_t out_size,
199664cfcebdSCristian Dumitrescu 	void *obj)
199764cfcebdSCristian Dumitrescu {
199864cfcebdSCristian Dumitrescu 	struct pipeline *p;
199964cfcebdSCristian Dumitrescu 	const char *name;
200064cfcebdSCristian Dumitrescu 	uint64_t value;
200164cfcebdSCristian Dumitrescu 	uint32_t idx;
200264cfcebdSCristian Dumitrescu 	int status;
200364cfcebdSCristian Dumitrescu 
200464cfcebdSCristian Dumitrescu 	if (n_tokens != 5) {
200564cfcebdSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
200664cfcebdSCristian Dumitrescu 		return;
200764cfcebdSCristian Dumitrescu 	}
200864cfcebdSCristian Dumitrescu 
200964cfcebdSCristian Dumitrescu 	p = pipeline_find(obj, tokens[1]);
201064cfcebdSCristian Dumitrescu 	if (!p || !p->ctl) {
201164cfcebdSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
201264cfcebdSCristian Dumitrescu 		return;
201364cfcebdSCristian Dumitrescu 	}
201464cfcebdSCristian Dumitrescu 
201564cfcebdSCristian Dumitrescu 	if (strcmp(tokens[2], "regrd")) {
201664cfcebdSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "regrd");
201764cfcebdSCristian Dumitrescu 		return;
201864cfcebdSCristian Dumitrescu 	}
201964cfcebdSCristian Dumitrescu 
202064cfcebdSCristian Dumitrescu 	name = tokens[3];
202164cfcebdSCristian Dumitrescu 
202264cfcebdSCristian Dumitrescu 	if (parser_read_uint32(&idx, tokens[4])) {
202364cfcebdSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "index");
202464cfcebdSCristian Dumitrescu 		return;
202564cfcebdSCristian Dumitrescu 	}
202664cfcebdSCristian Dumitrescu 
202764cfcebdSCristian Dumitrescu 	status = rte_swx_ctl_pipeline_regarray_read(p->p, name, idx, &value);
202864cfcebdSCristian Dumitrescu 	if (status) {
202964cfcebdSCristian Dumitrescu 		snprintf(out, out_size, "Command failed.\n");
203064cfcebdSCristian Dumitrescu 		return;
203164cfcebdSCristian Dumitrescu 	}
203264cfcebdSCristian Dumitrescu 
203364cfcebdSCristian Dumitrescu 	snprintf(out, out_size, "0x%" PRIx64 "\n", value);
203464cfcebdSCristian Dumitrescu }
203564cfcebdSCristian Dumitrescu 
203664cfcebdSCristian Dumitrescu static const char cmd_pipeline_regwr_help[] =
203764cfcebdSCristian Dumitrescu "pipeline <pipeline_name> regwr <register_array_name> <index> <value>\n";
203864cfcebdSCristian Dumitrescu 
203964cfcebdSCristian Dumitrescu static void
204064cfcebdSCristian Dumitrescu cmd_pipeline_regwr(char **tokens,
204164cfcebdSCristian Dumitrescu 	uint32_t n_tokens,
204264cfcebdSCristian Dumitrescu 	char *out,
204364cfcebdSCristian Dumitrescu 	size_t out_size,
204464cfcebdSCristian Dumitrescu 	void *obj)
204564cfcebdSCristian Dumitrescu {
204664cfcebdSCristian Dumitrescu 	struct pipeline *p;
204764cfcebdSCristian Dumitrescu 	const char *name;
204864cfcebdSCristian Dumitrescu 	uint64_t value;
204964cfcebdSCristian Dumitrescu 	uint32_t idx;
205064cfcebdSCristian Dumitrescu 	int status;
205164cfcebdSCristian Dumitrescu 
205264cfcebdSCristian Dumitrescu 	if (n_tokens != 6) {
205364cfcebdSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
205464cfcebdSCristian Dumitrescu 		return;
205564cfcebdSCristian Dumitrescu 	}
205664cfcebdSCristian Dumitrescu 
205764cfcebdSCristian Dumitrescu 	p = pipeline_find(obj, tokens[1]);
205864cfcebdSCristian Dumitrescu 	if (!p || !p->ctl) {
205964cfcebdSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
206064cfcebdSCristian Dumitrescu 		return;
206164cfcebdSCristian Dumitrescu 	}
206264cfcebdSCristian Dumitrescu 
206364cfcebdSCristian Dumitrescu 	if (strcmp(tokens[2], "regwr")) {
206464cfcebdSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "regwr");
206564cfcebdSCristian Dumitrescu 		return;
206664cfcebdSCristian Dumitrescu 	}
206764cfcebdSCristian Dumitrescu 
206864cfcebdSCristian Dumitrescu 	name = tokens[3];
206964cfcebdSCristian Dumitrescu 
207064cfcebdSCristian Dumitrescu 	if (parser_read_uint32(&idx, tokens[4])) {
207164cfcebdSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "index");
207264cfcebdSCristian Dumitrescu 		return;
207364cfcebdSCristian Dumitrescu 	}
207464cfcebdSCristian Dumitrescu 
207564cfcebdSCristian Dumitrescu 	if (parser_read_uint64(&value, tokens[5])) {
207664cfcebdSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "value");
207764cfcebdSCristian Dumitrescu 		return;
207864cfcebdSCristian Dumitrescu 	}
207964cfcebdSCristian Dumitrescu 
208064cfcebdSCristian Dumitrescu 	status = rte_swx_ctl_pipeline_regarray_write(p->p, name, idx, value);
208164cfcebdSCristian Dumitrescu 	if (status) {
208264cfcebdSCristian Dumitrescu 		snprintf(out, out_size, "Command failed.\n");
208364cfcebdSCristian Dumitrescu 		return;
208464cfcebdSCristian Dumitrescu 	}
208564cfcebdSCristian Dumitrescu }
208664cfcebdSCristian Dumitrescu 
2087f38913b7SCristian Dumitrescu static const char cmd_pipeline_meter_profile_add_help[] =
2088f38913b7SCristian Dumitrescu "pipeline <pipeline_name> meter profile <profile_name> add "
2089f38913b7SCristian Dumitrescu 	"cir <cir> pir <pir> cbs <cbs> pbs <pbs>\n";
2090f38913b7SCristian Dumitrescu 
2091f38913b7SCristian Dumitrescu static void
2092f38913b7SCristian Dumitrescu cmd_pipeline_meter_profile_add(char **tokens,
2093f38913b7SCristian Dumitrescu 	uint32_t n_tokens,
2094f38913b7SCristian Dumitrescu 	char *out,
2095f38913b7SCristian Dumitrescu 	size_t out_size,
2096f38913b7SCristian Dumitrescu 	void *obj)
2097f38913b7SCristian Dumitrescu {
2098f38913b7SCristian Dumitrescu 	struct rte_meter_trtcm_params params;
2099f38913b7SCristian Dumitrescu 	struct pipeline *p;
2100f38913b7SCristian Dumitrescu 	const char *profile_name;
2101f38913b7SCristian Dumitrescu 	int status;
2102f38913b7SCristian Dumitrescu 
2103f38913b7SCristian Dumitrescu 	if (n_tokens != 14) {
2104f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2105f38913b7SCristian Dumitrescu 		return;
2106f38913b7SCristian Dumitrescu 	}
2107f38913b7SCristian Dumitrescu 
2108f38913b7SCristian Dumitrescu 	p = pipeline_find(obj, tokens[1]);
2109f38913b7SCristian Dumitrescu 	if (!p || !p->ctl) {
2110f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
2111f38913b7SCristian Dumitrescu 		return;
2112f38913b7SCristian Dumitrescu 	}
2113f38913b7SCristian Dumitrescu 
2114f38913b7SCristian Dumitrescu 	if (strcmp(tokens[2], "meter")) {
2115f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "meter");
2116f38913b7SCristian Dumitrescu 		return;
2117f38913b7SCristian Dumitrescu 	}
2118f38913b7SCristian Dumitrescu 
2119f38913b7SCristian Dumitrescu 	if (strcmp(tokens[3], "profile")) {
2120f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "profile");
2121f38913b7SCristian Dumitrescu 		return;
2122f38913b7SCristian Dumitrescu 	}
2123f38913b7SCristian Dumitrescu 
2124f38913b7SCristian Dumitrescu 	profile_name = tokens[4];
2125f38913b7SCristian Dumitrescu 
2126f38913b7SCristian Dumitrescu 	if (strcmp(tokens[5], "add")) {
2127f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "add");
2128f38913b7SCristian Dumitrescu 		return;
2129f38913b7SCristian Dumitrescu 	}
2130f38913b7SCristian Dumitrescu 
2131f38913b7SCristian Dumitrescu 	if (strcmp(tokens[6], "cir")) {
2132f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cir");
2133f38913b7SCristian Dumitrescu 		return;
2134f38913b7SCristian Dumitrescu 	}
2135f38913b7SCristian Dumitrescu 
2136f38913b7SCristian Dumitrescu 	if (parser_read_uint64(&params.cir, tokens[7])) {
2137f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "cir");
2138f38913b7SCristian Dumitrescu 		return;
2139f38913b7SCristian Dumitrescu 	}
2140f38913b7SCristian Dumitrescu 
2141f38913b7SCristian Dumitrescu 	if (strcmp(tokens[8], "pir")) {
2142f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pir");
2143f38913b7SCristian Dumitrescu 		return;
2144f38913b7SCristian Dumitrescu 	}
2145f38913b7SCristian Dumitrescu 
2146f38913b7SCristian Dumitrescu 	if (parser_read_uint64(&params.pir, tokens[9])) {
2147f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pir");
2148f38913b7SCristian Dumitrescu 		return;
2149f38913b7SCristian Dumitrescu 	}
2150f38913b7SCristian Dumitrescu 
2151f38913b7SCristian Dumitrescu 	if (strcmp(tokens[10], "cbs")) {
2152f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cbs");
2153f38913b7SCristian Dumitrescu 		return;
2154f38913b7SCristian Dumitrescu 	}
2155f38913b7SCristian Dumitrescu 
2156f38913b7SCristian Dumitrescu 	if (parser_read_uint64(&params.cbs, tokens[11])) {
2157f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "cbs");
2158f38913b7SCristian Dumitrescu 		return;
2159f38913b7SCristian Dumitrescu 	}
2160f38913b7SCristian Dumitrescu 
2161f38913b7SCristian Dumitrescu 	if (strcmp(tokens[12], "pbs")) {
2162f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pbs");
2163f38913b7SCristian Dumitrescu 		return;
2164f38913b7SCristian Dumitrescu 	}
2165f38913b7SCristian Dumitrescu 
2166f38913b7SCristian Dumitrescu 	if (parser_read_uint64(&params.pbs, tokens[13])) {
2167f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pbs");
2168f38913b7SCristian Dumitrescu 		return;
2169f38913b7SCristian Dumitrescu 	}
2170f38913b7SCristian Dumitrescu 
2171f38913b7SCristian Dumitrescu 	status = rte_swx_ctl_meter_profile_add(p->p, profile_name, &params);
2172f38913b7SCristian Dumitrescu 	if (status) {
2173f38913b7SCristian Dumitrescu 		snprintf(out, out_size, "Command failed.\n");
2174f38913b7SCristian Dumitrescu 		return;
2175f38913b7SCristian Dumitrescu 	}
2176f38913b7SCristian Dumitrescu }
2177f38913b7SCristian Dumitrescu 
2178f38913b7SCristian Dumitrescu static const char cmd_pipeline_meter_profile_delete_help[] =
2179f38913b7SCristian Dumitrescu "pipeline <pipeline_name> meter profile <profile_name> delete\n";
2180f38913b7SCristian Dumitrescu 
2181f38913b7SCristian Dumitrescu static void
2182f38913b7SCristian Dumitrescu cmd_pipeline_meter_profile_delete(char **tokens,
2183f38913b7SCristian Dumitrescu 	uint32_t n_tokens,
2184f38913b7SCristian Dumitrescu 	char *out,
2185f38913b7SCristian Dumitrescu 	size_t out_size,
2186f38913b7SCristian Dumitrescu 	void *obj)
2187f38913b7SCristian Dumitrescu {
2188f38913b7SCristian Dumitrescu 	struct pipeline *p;
2189f38913b7SCristian Dumitrescu 	const char *profile_name;
2190f38913b7SCristian Dumitrescu 	int status;
2191f38913b7SCristian Dumitrescu 
2192f38913b7SCristian Dumitrescu 	if (n_tokens != 6) {
2193f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2194f38913b7SCristian Dumitrescu 		return;
2195f38913b7SCristian Dumitrescu 	}
2196f38913b7SCristian Dumitrescu 
2197f38913b7SCristian Dumitrescu 	p = pipeline_find(obj, tokens[1]);
2198f38913b7SCristian Dumitrescu 	if (!p || !p->ctl) {
2199f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
2200f38913b7SCristian Dumitrescu 		return;
2201f38913b7SCristian Dumitrescu 	}
2202f38913b7SCristian Dumitrescu 
2203f38913b7SCristian Dumitrescu 	if (strcmp(tokens[2], "meter")) {
2204f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "meter");
2205f38913b7SCristian Dumitrescu 		return;
2206f38913b7SCristian Dumitrescu 	}
2207f38913b7SCristian Dumitrescu 
2208f38913b7SCristian Dumitrescu 	if (strcmp(tokens[3], "profile")) {
2209f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "profile");
2210f38913b7SCristian Dumitrescu 		return;
2211f38913b7SCristian Dumitrescu 	}
2212f38913b7SCristian Dumitrescu 
2213f38913b7SCristian Dumitrescu 	profile_name = tokens[4];
2214f38913b7SCristian Dumitrescu 
2215f38913b7SCristian Dumitrescu 	if (strcmp(tokens[5], "delete")) {
2216f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "delete");
2217f38913b7SCristian Dumitrescu 		return;
2218f38913b7SCristian Dumitrescu 	}
2219f38913b7SCristian Dumitrescu 
2220f38913b7SCristian Dumitrescu 	status = rte_swx_ctl_meter_profile_delete(p->p, profile_name);
2221f38913b7SCristian Dumitrescu 	if (status) {
2222f38913b7SCristian Dumitrescu 		snprintf(out, out_size, "Command failed.\n");
2223f38913b7SCristian Dumitrescu 		return;
2224f38913b7SCristian Dumitrescu 	}
2225f38913b7SCristian Dumitrescu }
2226f38913b7SCristian Dumitrescu 
2227f38913b7SCristian Dumitrescu static const char cmd_pipeline_meter_reset_help[] =
2228f38913b7SCristian Dumitrescu "pipeline <pipeline_name> meter <meter_array_name> from <index0> to <index1> "
2229f38913b7SCristian Dumitrescu 	"reset\n";
2230f38913b7SCristian Dumitrescu 
2231f38913b7SCristian Dumitrescu static void
2232f38913b7SCristian Dumitrescu cmd_pipeline_meter_reset(char **tokens,
2233f38913b7SCristian Dumitrescu 	uint32_t n_tokens,
2234f38913b7SCristian Dumitrescu 	char *out,
2235f38913b7SCristian Dumitrescu 	size_t out_size,
2236f38913b7SCristian Dumitrescu 	void *obj)
2237f38913b7SCristian Dumitrescu {
2238f38913b7SCristian Dumitrescu 	struct pipeline *p;
2239f38913b7SCristian Dumitrescu 	const char *name;
224000b67591SAli Alnubani 	uint32_t idx0 = 0, idx1 = 0;
2241f38913b7SCristian Dumitrescu 
2242f38913b7SCristian Dumitrescu 	if (n_tokens != 9) {
2243f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2244f38913b7SCristian Dumitrescu 		return;
2245f38913b7SCristian Dumitrescu 	}
2246f38913b7SCristian Dumitrescu 
2247f38913b7SCristian Dumitrescu 	p = pipeline_find(obj, tokens[1]);
2248f38913b7SCristian Dumitrescu 	if (!p || !p->ctl) {
2249f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
2250f38913b7SCristian Dumitrescu 		return;
2251f38913b7SCristian Dumitrescu 	}
2252f38913b7SCristian Dumitrescu 
2253f38913b7SCristian Dumitrescu 	if (strcmp(tokens[2], "meter")) {
2254f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "meter");
2255f38913b7SCristian Dumitrescu 		return;
2256f38913b7SCristian Dumitrescu 	}
2257f38913b7SCristian Dumitrescu 
2258f38913b7SCristian Dumitrescu 	name = tokens[3];
2259f38913b7SCristian Dumitrescu 
2260f38913b7SCristian Dumitrescu 	if (strcmp(tokens[4], "from")) {
2261f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "from");
2262f38913b7SCristian Dumitrescu 		return;
2263f38913b7SCristian Dumitrescu 	}
2264f38913b7SCristian Dumitrescu 
2265f38913b7SCristian Dumitrescu 	if (parser_read_uint32(&idx0, tokens[5])) {
2266f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "index0");
2267f38913b7SCristian Dumitrescu 		return;
2268f38913b7SCristian Dumitrescu 	}
2269f38913b7SCristian Dumitrescu 
2270f38913b7SCristian Dumitrescu 	if (strcmp(tokens[6], "to")) {
2271f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "to");
2272f38913b7SCristian Dumitrescu 		return;
2273f38913b7SCristian Dumitrescu 	}
2274f38913b7SCristian Dumitrescu 
2275f38913b7SCristian Dumitrescu 	if (parser_read_uint32(&idx1, tokens[7]) || (idx1 < idx0)) {
2276f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "index1");
2277f38913b7SCristian Dumitrescu 		return;
2278f38913b7SCristian Dumitrescu 	}
2279f38913b7SCristian Dumitrescu 
2280f38913b7SCristian Dumitrescu 	if (strcmp(tokens[8], "reset")) {
2281f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "reset");
2282f38913b7SCristian Dumitrescu 		return;
2283f38913b7SCristian Dumitrescu 	}
2284f38913b7SCristian Dumitrescu 
2285f38913b7SCristian Dumitrescu 	for ( ; idx0 <= idx1; idx0++) {
2286f38913b7SCristian Dumitrescu 		int status;
2287f38913b7SCristian Dumitrescu 
2288f38913b7SCristian Dumitrescu 		status = rte_swx_ctl_meter_reset(p->p, name, idx0);
2289f38913b7SCristian Dumitrescu 		if (status) {
2290f38913b7SCristian Dumitrescu 			snprintf(out, out_size, "Command failed for index %u.\n", idx0);
2291f38913b7SCristian Dumitrescu 			return;
2292f38913b7SCristian Dumitrescu 		}
2293f38913b7SCristian Dumitrescu 	}
2294f38913b7SCristian Dumitrescu }
2295f38913b7SCristian Dumitrescu 
2296f38913b7SCristian Dumitrescu static const char cmd_pipeline_meter_set_help[] =
2297f38913b7SCristian Dumitrescu "pipeline <pipeline_name> meter <meter_array_name> from <index0> to <index1> "
2298f38913b7SCristian Dumitrescu 	"set profile <profile_name>\n";
2299f38913b7SCristian Dumitrescu 
2300f38913b7SCristian Dumitrescu static void
2301f38913b7SCristian Dumitrescu cmd_pipeline_meter_set(char **tokens,
2302f38913b7SCristian Dumitrescu 	uint32_t n_tokens,
2303f38913b7SCristian Dumitrescu 	char *out,
2304f38913b7SCristian Dumitrescu 	size_t out_size,
2305f38913b7SCristian Dumitrescu 	void *obj)
2306f38913b7SCristian Dumitrescu {
2307f38913b7SCristian Dumitrescu 	struct pipeline *p;
2308f38913b7SCristian Dumitrescu 	const char *name, *profile_name;
230900b67591SAli Alnubani 	uint32_t idx0 = 0, idx1 = 0;
2310f38913b7SCristian Dumitrescu 
2311f38913b7SCristian Dumitrescu 	if (n_tokens != 11) {
2312f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2313f38913b7SCristian Dumitrescu 		return;
2314f38913b7SCristian Dumitrescu 	}
2315f38913b7SCristian Dumitrescu 
2316f38913b7SCristian Dumitrescu 	p = pipeline_find(obj, tokens[1]);
2317f38913b7SCristian Dumitrescu 	if (!p || !p->ctl) {
2318f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
2319f38913b7SCristian Dumitrescu 		return;
2320f38913b7SCristian Dumitrescu 	}
2321f38913b7SCristian Dumitrescu 
2322f38913b7SCristian Dumitrescu 	if (strcmp(tokens[2], "meter")) {
2323f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "meter");
2324f38913b7SCristian Dumitrescu 		return;
2325f38913b7SCristian Dumitrescu 	}
2326f38913b7SCristian Dumitrescu 
2327f38913b7SCristian Dumitrescu 	name = tokens[3];
2328f38913b7SCristian Dumitrescu 
2329f38913b7SCristian Dumitrescu 	if (strcmp(tokens[4], "from")) {
2330f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "from");
2331f38913b7SCristian Dumitrescu 		return;
2332f38913b7SCristian Dumitrescu 	}
2333f38913b7SCristian Dumitrescu 
2334f38913b7SCristian Dumitrescu 	if (parser_read_uint32(&idx0, tokens[5])) {
2335f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "index0");
2336f38913b7SCristian Dumitrescu 		return;
2337f38913b7SCristian Dumitrescu 	}
2338f38913b7SCristian Dumitrescu 
2339f38913b7SCristian Dumitrescu 	if (strcmp(tokens[6], "to")) {
2340f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "to");
2341f38913b7SCristian Dumitrescu 		return;
2342f38913b7SCristian Dumitrescu 	}
2343f38913b7SCristian Dumitrescu 
2344f38913b7SCristian Dumitrescu 	if (parser_read_uint32(&idx1, tokens[7]) || (idx1 < idx0)) {
2345f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "index1");
2346f38913b7SCristian Dumitrescu 		return;
2347f38913b7SCristian Dumitrescu 	}
2348f38913b7SCristian Dumitrescu 
2349f38913b7SCristian Dumitrescu 	if (strcmp(tokens[8], "set")) {
2350f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "set");
2351f38913b7SCristian Dumitrescu 		return;
2352f38913b7SCristian Dumitrescu 	}
2353f38913b7SCristian Dumitrescu 
2354f38913b7SCristian Dumitrescu 	if (strcmp(tokens[9], "profile")) {
2355f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "profile");
2356f38913b7SCristian Dumitrescu 		return;
2357f38913b7SCristian Dumitrescu 	}
2358f38913b7SCristian Dumitrescu 
2359f38913b7SCristian Dumitrescu 	profile_name = tokens[10];
2360f38913b7SCristian Dumitrescu 
2361f38913b7SCristian Dumitrescu 	for ( ; idx0 <= idx1; idx0++) {
2362f38913b7SCristian Dumitrescu 		int status;
2363f38913b7SCristian Dumitrescu 
2364f38913b7SCristian Dumitrescu 		status = rte_swx_ctl_meter_set(p->p, name, idx0, profile_name);
2365f38913b7SCristian Dumitrescu 		if (status) {
2366f38913b7SCristian Dumitrescu 			snprintf(out, out_size, "Command failed for index %u.\n", idx0);
2367f38913b7SCristian Dumitrescu 			return;
2368f38913b7SCristian Dumitrescu 		}
2369f38913b7SCristian Dumitrescu 	}
2370f38913b7SCristian Dumitrescu }
2371f38913b7SCristian Dumitrescu 
2372f38913b7SCristian Dumitrescu static const char cmd_pipeline_meter_stats_help[] =
2373f38913b7SCristian Dumitrescu "pipeline <pipeline_name> meter <meter_array_name> from <index0> to <index1> "
2374f38913b7SCristian Dumitrescu 	"stats\n";
2375f38913b7SCristian Dumitrescu 
2376f38913b7SCristian Dumitrescu static void
2377f38913b7SCristian Dumitrescu cmd_pipeline_meter_stats(char **tokens,
2378f38913b7SCristian Dumitrescu 	uint32_t n_tokens,
2379f38913b7SCristian Dumitrescu 	char *out,
2380f38913b7SCristian Dumitrescu 	size_t out_size,
2381f38913b7SCristian Dumitrescu 	void *obj)
2382f38913b7SCristian Dumitrescu {
2383f38913b7SCristian Dumitrescu 	struct rte_swx_ctl_meter_stats stats;
2384f38913b7SCristian Dumitrescu 	struct pipeline *p;
2385f38913b7SCristian Dumitrescu 	const char *name;
238600b67591SAli Alnubani 	uint32_t idx0 = 0, idx1 = 0;
2387f38913b7SCristian Dumitrescu 
2388f38913b7SCristian Dumitrescu 	if (n_tokens != 9) {
2389f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2390f38913b7SCristian Dumitrescu 		return;
2391f38913b7SCristian Dumitrescu 	}
2392f38913b7SCristian Dumitrescu 
2393f38913b7SCristian Dumitrescu 	p = pipeline_find(obj, tokens[1]);
2394f38913b7SCristian Dumitrescu 	if (!p || !p->ctl) {
2395f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
2396f38913b7SCristian Dumitrescu 		return;
2397f38913b7SCristian Dumitrescu 	}
2398f38913b7SCristian Dumitrescu 
2399f38913b7SCristian Dumitrescu 	if (strcmp(tokens[2], "meter")) {
2400f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "meter");
2401f38913b7SCristian Dumitrescu 		return;
2402f38913b7SCristian Dumitrescu 	}
2403f38913b7SCristian Dumitrescu 
2404f38913b7SCristian Dumitrescu 	name = tokens[3];
2405f38913b7SCristian Dumitrescu 
2406f38913b7SCristian Dumitrescu 	if (strcmp(tokens[4], "from")) {
2407f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "from");
2408f38913b7SCristian Dumitrescu 		return;
2409f38913b7SCristian Dumitrescu 	}
2410f38913b7SCristian Dumitrescu 
2411f38913b7SCristian Dumitrescu 	if (parser_read_uint32(&idx0, tokens[5])) {
2412f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "index0");
2413f38913b7SCristian Dumitrescu 		return;
2414f38913b7SCristian Dumitrescu 	}
2415f38913b7SCristian Dumitrescu 
2416f38913b7SCristian Dumitrescu 	if (strcmp(tokens[6], "to")) {
2417f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "to");
2418f38913b7SCristian Dumitrescu 		return;
2419f38913b7SCristian Dumitrescu 	}
2420f38913b7SCristian Dumitrescu 
2421f38913b7SCristian Dumitrescu 	if (parser_read_uint32(&idx1, tokens[7]) || (idx1 < idx0)) {
2422f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "index1");
2423f38913b7SCristian Dumitrescu 		return;
2424f38913b7SCristian Dumitrescu 	}
2425f38913b7SCristian Dumitrescu 
2426f38913b7SCristian Dumitrescu 	if (strcmp(tokens[8], "stats")) {
2427f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "stats");
2428f38913b7SCristian Dumitrescu 		return;
2429f38913b7SCristian Dumitrescu 	}
2430f38913b7SCristian Dumitrescu 
2431f38913b7SCristian Dumitrescu 	/* Table header. */
2432f38913b7SCristian Dumitrescu 	snprintf(out, out_size, "+-%7s-+-%16s-+-%16s-+-%16s-+-%16s-+-%16s-+-%16s-+\n",
2433f38913b7SCristian Dumitrescu 		 "-------",
2434f38913b7SCristian Dumitrescu 		 "----------------", "----------------", "----------------",
2435f38913b7SCristian Dumitrescu 		 "----------------", "----------------", "----------------");
2436f38913b7SCristian Dumitrescu 	out_size -= strlen(out);
2437f38913b7SCristian Dumitrescu 	out += strlen(out);
2438f38913b7SCristian Dumitrescu 
2439f38913b7SCristian Dumitrescu 	snprintf(out, out_size, "| %4s | %16s | %16s | %16s | %16s | %16s | %16s |\n",
2440f38913b7SCristian Dumitrescu 		 "METER #",
2441f38913b7SCristian Dumitrescu 		 "GREEN (packets)", "YELLOW (packets)", "RED (packets)",
2442f38913b7SCristian Dumitrescu 		 "GREEN (bytes)", "YELLOW (bytes)", "RED (bytes)");
2443f38913b7SCristian Dumitrescu 	out_size -= strlen(out);
2444f38913b7SCristian Dumitrescu 	out += strlen(out);
2445f38913b7SCristian Dumitrescu 
2446f38913b7SCristian Dumitrescu 	snprintf(out, out_size, "+-%7s-+-%16s-+-%16s-+-%16s-+-%16s-+-%16s-+-%16s-+\n",
2447f38913b7SCristian Dumitrescu 		 "-------",
2448f38913b7SCristian Dumitrescu 		 "----------------", "----------------", "----------------",
2449f38913b7SCristian Dumitrescu 		 "----------------", "----------------", "----------------");
2450f38913b7SCristian Dumitrescu 	out_size -= strlen(out);
2451f38913b7SCristian Dumitrescu 	out += strlen(out);
2452f38913b7SCristian Dumitrescu 
2453f38913b7SCristian Dumitrescu 	/* Table rows. */
2454f38913b7SCristian Dumitrescu 	for ( ; idx0 <= idx1; idx0++) {
2455f38913b7SCristian Dumitrescu 		int status;
2456f38913b7SCristian Dumitrescu 
2457f38913b7SCristian Dumitrescu 		status = rte_swx_ctl_meter_stats_read(p->p, name, idx0, &stats);
2458f38913b7SCristian Dumitrescu 		if (status) {
2459f38913b7SCristian Dumitrescu 			snprintf(out, out_size, "Pipeline meter stats error at index %u.\n", idx0);
2460f38913b7SCristian Dumitrescu 			out_size -= strlen(out);
2461f38913b7SCristian Dumitrescu 			out += strlen(out);
2462f38913b7SCristian Dumitrescu 			return;
2463f38913b7SCristian Dumitrescu 		}
2464f38913b7SCristian Dumitrescu 
2465f38913b7SCristian Dumitrescu 		snprintf(out, out_size, "| %7d | %16" PRIx64 " | %16" PRIx64 " | %16" PRIx64
2466f38913b7SCristian Dumitrescu 			 " | %16" PRIx64 " | %16" PRIx64 " | %16" PRIx64 " |\n",
2467f38913b7SCristian Dumitrescu 			 idx0,
2468f38913b7SCristian Dumitrescu 			 stats.n_pkts[RTE_COLOR_GREEN],
2469f38913b7SCristian Dumitrescu 			 stats.n_pkts[RTE_COLOR_YELLOW],
2470f38913b7SCristian Dumitrescu 			 stats.n_pkts[RTE_COLOR_RED],
2471f38913b7SCristian Dumitrescu 			 stats.n_bytes[RTE_COLOR_GREEN],
2472f38913b7SCristian Dumitrescu 			 stats.n_bytes[RTE_COLOR_YELLOW],
2473f38913b7SCristian Dumitrescu 			 stats.n_bytes[RTE_COLOR_RED]);
2474f38913b7SCristian Dumitrescu 		out_size -= strlen(out);
2475f38913b7SCristian Dumitrescu 		out += strlen(out);
2476f38913b7SCristian Dumitrescu 	}
2477f38913b7SCristian Dumitrescu }
2478f38913b7SCristian Dumitrescu 
24795074e1d5SCristian Dumitrescu static const char cmd_pipeline_stats_help[] =
24805074e1d5SCristian Dumitrescu "pipeline <pipeline_name> stats\n";
24815074e1d5SCristian Dumitrescu 
24825074e1d5SCristian Dumitrescu static void
24835074e1d5SCristian Dumitrescu cmd_pipeline_stats(char **tokens,
24845074e1d5SCristian Dumitrescu 	uint32_t n_tokens,
24855074e1d5SCristian Dumitrescu 	char *out,
24865074e1d5SCristian Dumitrescu 	size_t out_size,
24875074e1d5SCristian Dumitrescu 	void *obj)
24885074e1d5SCristian Dumitrescu {
24895074e1d5SCristian Dumitrescu 	struct rte_swx_ctl_pipeline_info info;
24905074e1d5SCristian Dumitrescu 	struct pipeline *p;
24915074e1d5SCristian Dumitrescu 	uint32_t i;
24925074e1d5SCristian Dumitrescu 	int status;
24935074e1d5SCristian Dumitrescu 
24945074e1d5SCristian Dumitrescu 	if (n_tokens != 3) {
24955074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
24965074e1d5SCristian Dumitrescu 		return;
24975074e1d5SCristian Dumitrescu 	}
24985074e1d5SCristian Dumitrescu 
24995074e1d5SCristian Dumitrescu 	p = pipeline_find(obj, tokens[1]);
25005074e1d5SCristian Dumitrescu 	if (!p || !p->ctl) {
25015074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
25025074e1d5SCristian Dumitrescu 		return;
25035074e1d5SCristian Dumitrescu 	}
25045074e1d5SCristian Dumitrescu 
25055074e1d5SCristian Dumitrescu 	if (strcmp(tokens[2], "stats")) {
25065074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "stats");
25075074e1d5SCristian Dumitrescu 		return;
25085074e1d5SCristian Dumitrescu 	}
25095074e1d5SCristian Dumitrescu 
25105074e1d5SCristian Dumitrescu 	status = rte_swx_ctl_pipeline_info_get(p->p, &info);
25115074e1d5SCristian Dumitrescu 	if (status) {
25125074e1d5SCristian Dumitrescu 		snprintf(out, out_size, "Pipeline info get error.");
25135074e1d5SCristian Dumitrescu 		return;
25145074e1d5SCristian Dumitrescu 	}
25155074e1d5SCristian Dumitrescu 
25165074e1d5SCristian Dumitrescu 	snprintf(out, out_size, "Input ports:\n");
25175074e1d5SCristian Dumitrescu 	out_size -= strlen(out);
25185074e1d5SCristian Dumitrescu 	out += strlen(out);
25195074e1d5SCristian Dumitrescu 
25205074e1d5SCristian Dumitrescu 	for (i = 0; i < info.n_ports_in; i++) {
25215074e1d5SCristian Dumitrescu 		struct rte_swx_port_in_stats stats;
25225074e1d5SCristian Dumitrescu 
25235074e1d5SCristian Dumitrescu 		rte_swx_ctl_pipeline_port_in_stats_read(p->p, i, &stats);
25245074e1d5SCristian Dumitrescu 
25255074e1d5SCristian Dumitrescu 		snprintf(out, out_size, "\tPort %u:"
25265074e1d5SCristian Dumitrescu 			" packets %" PRIu64
25275074e1d5SCristian Dumitrescu 			" bytes %" PRIu64
25285074e1d5SCristian Dumitrescu 			" empty %" PRIu64 "\n",
25295074e1d5SCristian Dumitrescu 			i, stats.n_pkts, stats.n_bytes, stats.n_empty);
25305074e1d5SCristian Dumitrescu 		out_size -= strlen(out);
25315074e1d5SCristian Dumitrescu 		out += strlen(out);
25325074e1d5SCristian Dumitrescu 	}
25335074e1d5SCristian Dumitrescu 
2534742b0a57SCristian Dumitrescu 	snprintf(out, out_size, "\nOutput ports:\n");
25355074e1d5SCristian Dumitrescu 	out_size -= strlen(out);
25365074e1d5SCristian Dumitrescu 	out += strlen(out);
25375074e1d5SCristian Dumitrescu 
25385074e1d5SCristian Dumitrescu 	for (i = 0; i < info.n_ports_out; i++) {
25395074e1d5SCristian Dumitrescu 		struct rte_swx_port_out_stats stats;
25405074e1d5SCristian Dumitrescu 
25415074e1d5SCristian Dumitrescu 		rte_swx_ctl_pipeline_port_out_stats_read(p->p, i, &stats);
25425074e1d5SCristian Dumitrescu 
25435074e1d5SCristian Dumitrescu 		snprintf(out, out_size, "\tPort %u:"
25445074e1d5SCristian Dumitrescu 			" packets %" PRIu64
25455074e1d5SCristian Dumitrescu 			" bytes %" PRIu64 "\n",
25465074e1d5SCristian Dumitrescu 			i, stats.n_pkts, stats.n_bytes);
25475074e1d5SCristian Dumitrescu 		out_size -= strlen(out);
25485074e1d5SCristian Dumitrescu 		out += strlen(out);
25495074e1d5SCristian Dumitrescu 	}
2550742b0a57SCristian Dumitrescu 
2551742b0a57SCristian Dumitrescu 	snprintf(out, out_size, "\nTables:\n");
2552742b0a57SCristian Dumitrescu 	out_size -= strlen(out);
2553742b0a57SCristian Dumitrescu 	out += strlen(out);
2554742b0a57SCristian Dumitrescu 
2555742b0a57SCristian Dumitrescu 	for (i = 0; i < info.n_tables; i++) {
2556742b0a57SCristian Dumitrescu 		struct rte_swx_ctl_table_info table_info;
2557742b0a57SCristian Dumitrescu 		uint64_t n_pkts_action[info.n_actions];
2558742b0a57SCristian Dumitrescu 		struct rte_swx_table_stats stats = {
2559742b0a57SCristian Dumitrescu 			.n_pkts_hit = 0,
2560742b0a57SCristian Dumitrescu 			.n_pkts_miss = 0,
2561742b0a57SCristian Dumitrescu 			.n_pkts_action = n_pkts_action,
2562742b0a57SCristian Dumitrescu 		};
2563742b0a57SCristian Dumitrescu 		uint32_t j;
2564742b0a57SCristian Dumitrescu 
2565742b0a57SCristian Dumitrescu 		status = rte_swx_ctl_table_info_get(p->p, i, &table_info);
2566742b0a57SCristian Dumitrescu 		if (status) {
2567742b0a57SCristian Dumitrescu 			snprintf(out, out_size, "Table info get error.");
2568742b0a57SCristian Dumitrescu 			return;
2569742b0a57SCristian Dumitrescu 		}
2570742b0a57SCristian Dumitrescu 
2571742b0a57SCristian Dumitrescu 		status = rte_swx_ctl_pipeline_table_stats_read(p->p, table_info.name, &stats);
2572742b0a57SCristian Dumitrescu 		if (status) {
2573742b0a57SCristian Dumitrescu 			snprintf(out, out_size, "Table stats read error.");
2574742b0a57SCristian Dumitrescu 			return;
2575742b0a57SCristian Dumitrescu 		}
2576742b0a57SCristian Dumitrescu 
2577742b0a57SCristian Dumitrescu 		snprintf(out, out_size, "\tTable %s:\n"
2578742b0a57SCristian Dumitrescu 			"\t\tHit (packets): %" PRIu64 "\n"
2579742b0a57SCristian Dumitrescu 			"\t\tMiss (packets): %" PRIu64 "\n",
2580742b0a57SCristian Dumitrescu 			table_info.name,
2581742b0a57SCristian Dumitrescu 			stats.n_pkts_hit,
2582742b0a57SCristian Dumitrescu 			stats.n_pkts_miss);
2583742b0a57SCristian Dumitrescu 		out_size -= strlen(out);
2584742b0a57SCristian Dumitrescu 		out += strlen(out);
2585742b0a57SCristian Dumitrescu 
2586742b0a57SCristian Dumitrescu 		for (j = 0; j < info.n_actions; j++) {
2587742b0a57SCristian Dumitrescu 			struct rte_swx_ctl_action_info action_info;
2588742b0a57SCristian Dumitrescu 
2589742b0a57SCristian Dumitrescu 			status = rte_swx_ctl_action_info_get(p->p, j, &action_info);
2590742b0a57SCristian Dumitrescu 			if (status) {
2591742b0a57SCristian Dumitrescu 				snprintf(out, out_size, "Action info get error.");
2592742b0a57SCristian Dumitrescu 				return;
2593742b0a57SCristian Dumitrescu 			}
2594742b0a57SCristian Dumitrescu 
2595742b0a57SCristian Dumitrescu 			snprintf(out, out_size, "\t\tAction %s (packets): %" PRIu64 "\n",
2596742b0a57SCristian Dumitrescu 				action_info.name,
2597742b0a57SCristian Dumitrescu 				stats.n_pkts_action[j]);
2598742b0a57SCristian Dumitrescu 			out_size -= strlen(out);
2599742b0a57SCristian Dumitrescu 			out += strlen(out);
2600742b0a57SCristian Dumitrescu 		}
2601742b0a57SCristian Dumitrescu 	}
2602*8bd4862fSCristian Dumitrescu 
2603*8bd4862fSCristian Dumitrescu 	snprintf(out, out_size, "\nLearner tables:\n");
2604*8bd4862fSCristian Dumitrescu 	out_size -= strlen(out);
2605*8bd4862fSCristian Dumitrescu 	out += strlen(out);
2606*8bd4862fSCristian Dumitrescu 
2607*8bd4862fSCristian Dumitrescu 	for (i = 0; i < info.n_learners; i++) {
2608*8bd4862fSCristian Dumitrescu 		struct rte_swx_ctl_learner_info learner_info;
2609*8bd4862fSCristian Dumitrescu 		uint64_t n_pkts_action[info.n_actions];
2610*8bd4862fSCristian Dumitrescu 		struct rte_swx_learner_stats stats = {
2611*8bd4862fSCristian Dumitrescu 			.n_pkts_hit = 0,
2612*8bd4862fSCristian Dumitrescu 			.n_pkts_miss = 0,
2613*8bd4862fSCristian Dumitrescu 			.n_pkts_action = n_pkts_action,
2614*8bd4862fSCristian Dumitrescu 		};
2615*8bd4862fSCristian Dumitrescu 		uint32_t j;
2616*8bd4862fSCristian Dumitrescu 
2617*8bd4862fSCristian Dumitrescu 		status = rte_swx_ctl_learner_info_get(p->p, i, &learner_info);
2618*8bd4862fSCristian Dumitrescu 		if (status) {
2619*8bd4862fSCristian Dumitrescu 			snprintf(out, out_size, "Learner table info get error.");
2620*8bd4862fSCristian Dumitrescu 			return;
2621*8bd4862fSCristian Dumitrescu 		}
2622*8bd4862fSCristian Dumitrescu 
2623*8bd4862fSCristian Dumitrescu 		status = rte_swx_ctl_pipeline_learner_stats_read(p->p, learner_info.name, &stats);
2624*8bd4862fSCristian Dumitrescu 		if (status) {
2625*8bd4862fSCristian Dumitrescu 			snprintf(out, out_size, "Learner table stats read error.");
2626*8bd4862fSCristian Dumitrescu 			return;
2627*8bd4862fSCristian Dumitrescu 		}
2628*8bd4862fSCristian Dumitrescu 
2629*8bd4862fSCristian Dumitrescu 		snprintf(out, out_size, "\tLearner table %s:\n"
2630*8bd4862fSCristian Dumitrescu 			"\t\tHit (packets): %" PRIu64 "\n"
2631*8bd4862fSCristian Dumitrescu 			"\t\tMiss (packets): %" PRIu64 "\n"
2632*8bd4862fSCristian Dumitrescu 			"\t\tLearn OK (packets): %" PRIu64 "\n"
2633*8bd4862fSCristian Dumitrescu 			"\t\tLearn error (packets): %" PRIu64 "\n"
2634*8bd4862fSCristian Dumitrescu 			"\t\tForget (packets): %" PRIu64 "\n",
2635*8bd4862fSCristian Dumitrescu 			learner_info.name,
2636*8bd4862fSCristian Dumitrescu 			stats.n_pkts_hit,
2637*8bd4862fSCristian Dumitrescu 			stats.n_pkts_miss,
2638*8bd4862fSCristian Dumitrescu 			stats.n_pkts_learn_ok,
2639*8bd4862fSCristian Dumitrescu 			stats.n_pkts_learn_err,
2640*8bd4862fSCristian Dumitrescu 			stats.n_pkts_forget);
2641*8bd4862fSCristian Dumitrescu 		out_size -= strlen(out);
2642*8bd4862fSCristian Dumitrescu 		out += strlen(out);
2643*8bd4862fSCristian Dumitrescu 
2644*8bd4862fSCristian Dumitrescu 		for (j = 0; j < info.n_actions; j++) {
2645*8bd4862fSCristian Dumitrescu 			struct rte_swx_ctl_action_info action_info;
2646*8bd4862fSCristian Dumitrescu 
2647*8bd4862fSCristian Dumitrescu 			status = rte_swx_ctl_action_info_get(p->p, j, &action_info);
2648*8bd4862fSCristian Dumitrescu 			if (status) {
2649*8bd4862fSCristian Dumitrescu 				snprintf(out, out_size, "Action info get error.");
2650*8bd4862fSCristian Dumitrescu 				return;
2651*8bd4862fSCristian Dumitrescu 			}
2652*8bd4862fSCristian Dumitrescu 
2653*8bd4862fSCristian Dumitrescu 			snprintf(out, out_size, "\t\tAction %s (packets): %" PRIu64 "\n",
2654*8bd4862fSCristian Dumitrescu 				action_info.name,
2655*8bd4862fSCristian Dumitrescu 				stats.n_pkts_action[j]);
2656*8bd4862fSCristian Dumitrescu 			out_size -= strlen(out);
2657*8bd4862fSCristian Dumitrescu 			out += strlen(out);
2658*8bd4862fSCristian Dumitrescu 		}
2659*8bd4862fSCristian Dumitrescu 	}
26605074e1d5SCristian Dumitrescu }
26615074e1d5SCristian Dumitrescu 
26625074e1d5SCristian Dumitrescu static const char cmd_thread_pipeline_enable_help[] =
26635074e1d5SCristian Dumitrescu "thread <thread_id> pipeline <pipeline_name> enable\n";
26645074e1d5SCristian Dumitrescu 
26655074e1d5SCristian Dumitrescu static void
26665074e1d5SCristian Dumitrescu cmd_thread_pipeline_enable(char **tokens,
26675074e1d5SCristian Dumitrescu 	uint32_t n_tokens,
26685074e1d5SCristian Dumitrescu 	char *out,
26695074e1d5SCristian Dumitrescu 	size_t out_size,
26705074e1d5SCristian Dumitrescu 	void *obj)
26715074e1d5SCristian Dumitrescu {
26725074e1d5SCristian Dumitrescu 	char *pipeline_name;
26735074e1d5SCristian Dumitrescu 	struct pipeline *p;
26745074e1d5SCristian Dumitrescu 	uint32_t thread_id;
26755074e1d5SCristian Dumitrescu 	int status;
26765074e1d5SCristian Dumitrescu 
26775074e1d5SCristian Dumitrescu 	if (n_tokens != 5) {
26785074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
26795074e1d5SCristian Dumitrescu 		return;
26805074e1d5SCristian Dumitrescu 	}
26815074e1d5SCristian Dumitrescu 
26825074e1d5SCristian Dumitrescu 	if (parser_read_uint32(&thread_id, tokens[1]) != 0) {
26835074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "thread_id");
26845074e1d5SCristian Dumitrescu 		return;
26855074e1d5SCristian Dumitrescu 	}
26865074e1d5SCristian Dumitrescu 
26875074e1d5SCristian Dumitrescu 	if (strcmp(tokens[2], "pipeline") != 0) {
26885074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pipeline");
26895074e1d5SCristian Dumitrescu 		return;
26905074e1d5SCristian Dumitrescu 	}
26915074e1d5SCristian Dumitrescu 
26925074e1d5SCristian Dumitrescu 	pipeline_name = tokens[3];
26935074e1d5SCristian Dumitrescu 	p = pipeline_find(obj, pipeline_name);
26945074e1d5SCristian Dumitrescu 	if (!p || !p->ctl) {
26955074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
26965074e1d5SCristian Dumitrescu 		return;
26975074e1d5SCristian Dumitrescu 	}
26985074e1d5SCristian Dumitrescu 
26995074e1d5SCristian Dumitrescu 	if (strcmp(tokens[4], "enable") != 0) {
27005074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "enable");
27015074e1d5SCristian Dumitrescu 		return;
27025074e1d5SCristian Dumitrescu 	}
27035074e1d5SCristian Dumitrescu 
27045074e1d5SCristian Dumitrescu 	status = thread_pipeline_enable(thread_id, obj, pipeline_name);
27055074e1d5SCristian Dumitrescu 	if (status) {
27065074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_CMD_FAIL, "thread pipeline enable");
27075074e1d5SCristian Dumitrescu 		return;
27085074e1d5SCristian Dumitrescu 	}
27095074e1d5SCristian Dumitrescu }
27105074e1d5SCristian Dumitrescu 
27115074e1d5SCristian Dumitrescu static const char cmd_thread_pipeline_disable_help[] =
27125074e1d5SCristian Dumitrescu "thread <thread_id> pipeline <pipeline_name> disable\n";
27135074e1d5SCristian Dumitrescu 
27145074e1d5SCristian Dumitrescu static void
27155074e1d5SCristian Dumitrescu cmd_thread_pipeline_disable(char **tokens,
27165074e1d5SCristian Dumitrescu 	uint32_t n_tokens,
27175074e1d5SCristian Dumitrescu 	char *out,
27185074e1d5SCristian Dumitrescu 	size_t out_size,
27195074e1d5SCristian Dumitrescu 	void *obj)
27205074e1d5SCristian Dumitrescu {
27215074e1d5SCristian Dumitrescu 	struct pipeline *p;
27225074e1d5SCristian Dumitrescu 	char *pipeline_name;
27235074e1d5SCristian Dumitrescu 	uint32_t thread_id;
27245074e1d5SCristian Dumitrescu 	int status;
27255074e1d5SCristian Dumitrescu 
27265074e1d5SCristian Dumitrescu 	if (n_tokens != 5) {
27275074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
27285074e1d5SCristian Dumitrescu 		return;
27295074e1d5SCristian Dumitrescu 	}
27305074e1d5SCristian Dumitrescu 
27315074e1d5SCristian Dumitrescu 	if (parser_read_uint32(&thread_id, tokens[1]) != 0) {
27325074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "thread_id");
27335074e1d5SCristian Dumitrescu 		return;
27345074e1d5SCristian Dumitrescu 	}
27355074e1d5SCristian Dumitrescu 
27365074e1d5SCristian Dumitrescu 	if (strcmp(tokens[2], "pipeline") != 0) {
27375074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pipeline");
27385074e1d5SCristian Dumitrescu 		return;
27395074e1d5SCristian Dumitrescu 	}
27405074e1d5SCristian Dumitrescu 
27415074e1d5SCristian Dumitrescu 	pipeline_name = tokens[3];
27425074e1d5SCristian Dumitrescu 	p = pipeline_find(obj, pipeline_name);
27435074e1d5SCristian Dumitrescu 	if (!p || !p->ctl) {
27445074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
27455074e1d5SCristian Dumitrescu 		return;
27465074e1d5SCristian Dumitrescu 	}
27475074e1d5SCristian Dumitrescu 
27485074e1d5SCristian Dumitrescu 	if (strcmp(tokens[4], "disable") != 0) {
27495074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "disable");
27505074e1d5SCristian Dumitrescu 		return;
27515074e1d5SCristian Dumitrescu 	}
27525074e1d5SCristian Dumitrescu 
27535074e1d5SCristian Dumitrescu 	status = thread_pipeline_disable(thread_id, obj, pipeline_name);
27545074e1d5SCristian Dumitrescu 	if (status) {
27555074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_CMD_FAIL,
27565074e1d5SCristian Dumitrescu 			"thread pipeline disable");
27575074e1d5SCristian Dumitrescu 		return;
27585074e1d5SCristian Dumitrescu 	}
27595074e1d5SCristian Dumitrescu }
27605074e1d5SCristian Dumitrescu 
27615074e1d5SCristian Dumitrescu static void
27625074e1d5SCristian Dumitrescu cmd_help(char **tokens,
27635074e1d5SCristian Dumitrescu 	 uint32_t n_tokens,
27645074e1d5SCristian Dumitrescu 	 char *out,
27655074e1d5SCristian Dumitrescu 	 size_t out_size,
27665074e1d5SCristian Dumitrescu 	 void *arg __rte_unused)
27675074e1d5SCristian Dumitrescu {
27685074e1d5SCristian Dumitrescu 	tokens++;
27695074e1d5SCristian Dumitrescu 	n_tokens--;
27705074e1d5SCristian Dumitrescu 
27715074e1d5SCristian Dumitrescu 	if (n_tokens == 0) {
27725074e1d5SCristian Dumitrescu 		snprintf(out, out_size,
27737fef9ef1SYogesh Jangra 			"Type 'help <command>' for command details.\n\n"
27747fef9ef1SYogesh Jangra 			"List of commands:\n"
27757fef9ef1SYogesh Jangra 			"\tmempool\n"
27767fef9ef1SYogesh Jangra 			"\tlink\n"
2777e2b8dc52SVenkata Suresh Kumar P 			"\ttap\n"
27787fef9ef1SYogesh Jangra 			"\tpipeline create\n"
27797fef9ef1SYogesh Jangra 			"\tpipeline port in\n"
27807fef9ef1SYogesh Jangra 			"\tpipeline port out\n"
27817fef9ef1SYogesh Jangra 			"\tpipeline build\n"
278275129cebSChurchill Khangar 			"\tpipeline table add\n"
278375129cebSChurchill Khangar 			"\tpipeline table delete\n"
278475129cebSChurchill Khangar 			"\tpipeline table default\n"
278575129cebSChurchill Khangar 			"\tpipeline table show\n"
2786598fe0ddSCristian Dumitrescu 			"\tpipeline selector group add\n"
2787598fe0ddSCristian Dumitrescu 			"\tpipeline selector group delete\n"
2788598fe0ddSCristian Dumitrescu 			"\tpipeline selector group member add\n"
2789598fe0ddSCristian Dumitrescu 			"\tpipeline selector group member delete\n"
2790598fe0ddSCristian Dumitrescu 			"\tpipeline selector show\n"
2791*8bd4862fSCristian Dumitrescu 			"\tpipeline learner default\n"
279275129cebSChurchill Khangar 			"\tpipeline commit\n"
279375129cebSChurchill Khangar 			"\tpipeline abort\n"
279464cfcebdSCristian Dumitrescu 			"\tpipeline regrd\n"
279564cfcebdSCristian Dumitrescu 			"\tpipeline regwr\n"
2796f38913b7SCristian Dumitrescu 			"\tpipeline meter profile add\n"
2797f38913b7SCristian Dumitrescu 			"\tpipeline meter profile delete\n"
2798f38913b7SCristian Dumitrescu 			"\tpipeline meter reset\n"
2799f38913b7SCristian Dumitrescu 			"\tpipeline meter set\n"
2800f38913b7SCristian Dumitrescu 			"\tpipeline meter stats\n"
28017fef9ef1SYogesh Jangra 			"\tpipeline stats\n"
28027fef9ef1SYogesh Jangra 			"\tthread pipeline enable\n"
28037fef9ef1SYogesh Jangra 			"\tthread pipeline disable\n\n");
28045074e1d5SCristian Dumitrescu 		return;
28055074e1d5SCristian Dumitrescu 	}
28065074e1d5SCristian Dumitrescu 
28075074e1d5SCristian Dumitrescu 	if (strcmp(tokens[0], "mempool") == 0) {
28085074e1d5SCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n", cmd_mempool_help);
28095074e1d5SCristian Dumitrescu 		return;
28105074e1d5SCristian Dumitrescu 	}
28115074e1d5SCristian Dumitrescu 
28125074e1d5SCristian Dumitrescu 	if (strcmp(tokens[0], "link") == 0) {
28135074e1d5SCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n", cmd_link_help);
28145074e1d5SCristian Dumitrescu 		return;
28155074e1d5SCristian Dumitrescu 	}
28165074e1d5SCristian Dumitrescu 
281777a41301SCristian Dumitrescu 	if (strcmp(tokens[0], "ring") == 0) {
281877a41301SCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n", cmd_ring_help);
281977a41301SCristian Dumitrescu 		return;
282077a41301SCristian Dumitrescu 	}
282177a41301SCristian Dumitrescu 
2822e2b8dc52SVenkata Suresh Kumar P 	if (strcmp(tokens[0], "tap") == 0) {
2823e2b8dc52SVenkata Suresh Kumar P 		snprintf(out, out_size, "\n%s\n", cmd_tap_help);
2824e2b8dc52SVenkata Suresh Kumar P 		return;
2825e2b8dc52SVenkata Suresh Kumar P 	}
2826e2b8dc52SVenkata Suresh Kumar P 
28275074e1d5SCristian Dumitrescu 	if ((strcmp(tokens[0], "pipeline") == 0) &&
28287fef9ef1SYogesh Jangra 		(n_tokens == 2) && (strcmp(tokens[1], "create") == 0)) {
28295074e1d5SCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n", cmd_pipeline_create_help);
28305074e1d5SCristian Dumitrescu 		return;
28315074e1d5SCristian Dumitrescu 	}
28325074e1d5SCristian Dumitrescu 
28335074e1d5SCristian Dumitrescu 	if ((strcmp(tokens[0], "pipeline") == 0) &&
28347fef9ef1SYogesh Jangra 		(n_tokens == 3) && (strcmp(tokens[1], "port") == 0)) {
28357fef9ef1SYogesh Jangra 		if (strcmp(tokens[2], "in") == 0) {
28365074e1d5SCristian Dumitrescu 			snprintf(out, out_size, "\n%s\n",
28375074e1d5SCristian Dumitrescu 				cmd_pipeline_port_in_help);
28385074e1d5SCristian Dumitrescu 			return;
28395074e1d5SCristian Dumitrescu 		}
28405074e1d5SCristian Dumitrescu 
28417fef9ef1SYogesh Jangra 		if (strcmp(tokens[2], "out") == 0) {
28425074e1d5SCristian Dumitrescu 			snprintf(out, out_size, "\n%s\n",
28435074e1d5SCristian Dumitrescu 				cmd_pipeline_port_out_help);
28445074e1d5SCristian Dumitrescu 			return;
28455074e1d5SCristian Dumitrescu 		}
28465074e1d5SCristian Dumitrescu 	}
28475074e1d5SCristian Dumitrescu 
28485074e1d5SCristian Dumitrescu 	if ((strcmp(tokens[0], "pipeline") == 0) &&
28497fef9ef1SYogesh Jangra 		(n_tokens == 2) && (strcmp(tokens[1], "build") == 0)) {
28505074e1d5SCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n", cmd_pipeline_build_help);
28515074e1d5SCristian Dumitrescu 		return;
28525074e1d5SCristian Dumitrescu 	}
28535074e1d5SCristian Dumitrescu 
28545074e1d5SCristian Dumitrescu 	if ((strcmp(tokens[0], "pipeline") == 0) &&
28557fef9ef1SYogesh Jangra 		(n_tokens == 3) &&
28567fef9ef1SYogesh Jangra 		(strcmp(tokens[1], "table") == 0) &&
285775129cebSChurchill Khangar 		(strcmp(tokens[2], "add") == 0)) {
28585074e1d5SCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n",
285975129cebSChurchill Khangar 			cmd_pipeline_table_add_help);
286075129cebSChurchill Khangar 		return;
286175129cebSChurchill Khangar 	}
286275129cebSChurchill Khangar 
286375129cebSChurchill Khangar 	if ((strcmp(tokens[0], "pipeline") == 0) &&
286475129cebSChurchill Khangar 		(n_tokens == 3) &&
286575129cebSChurchill Khangar 		(strcmp(tokens[1], "table") == 0) &&
286675129cebSChurchill Khangar 		(strcmp(tokens[2], "delete") == 0)) {
286775129cebSChurchill Khangar 		snprintf(out, out_size, "\n%s\n",
286875129cebSChurchill Khangar 			cmd_pipeline_table_delete_help);
286975129cebSChurchill Khangar 		return;
287075129cebSChurchill Khangar 	}
287175129cebSChurchill Khangar 
287275129cebSChurchill Khangar 	if ((strcmp(tokens[0], "pipeline") == 0) &&
287375129cebSChurchill Khangar 		(n_tokens == 3) &&
287475129cebSChurchill Khangar 		(strcmp(tokens[1], "table") == 0) &&
287575129cebSChurchill Khangar 		(strcmp(tokens[2], "default") == 0)) {
287675129cebSChurchill Khangar 		snprintf(out, out_size, "\n%s\n",
287775129cebSChurchill Khangar 			cmd_pipeline_table_default_help);
287875129cebSChurchill Khangar 		return;
287975129cebSChurchill Khangar 	}
288075129cebSChurchill Khangar 
288175129cebSChurchill Khangar 	if ((strcmp(tokens[0], "pipeline") == 0) &&
288275129cebSChurchill Khangar 		(n_tokens == 3) &&
288375129cebSChurchill Khangar 		(strcmp(tokens[1], "table") == 0) &&
288475129cebSChurchill Khangar 		(strcmp(tokens[2], "show") == 0)) {
288575129cebSChurchill Khangar 		snprintf(out, out_size, "\n%s\n",
288675129cebSChurchill Khangar 			cmd_pipeline_table_show_help);
288775129cebSChurchill Khangar 		return;
288875129cebSChurchill Khangar 	}
288975129cebSChurchill Khangar 
289075129cebSChurchill Khangar 	if ((strcmp(tokens[0], "pipeline") == 0) &&
2891598fe0ddSCristian Dumitrescu 		(n_tokens == 4) &&
2892598fe0ddSCristian Dumitrescu 		(strcmp(tokens[1], "selector") == 0) &&
2893598fe0ddSCristian Dumitrescu 		(strcmp(tokens[2], "group") == 0) &&
2894598fe0ddSCristian Dumitrescu 		(strcmp(tokens[3], "add") == 0)) {
2895598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n",
2896598fe0ddSCristian Dumitrescu 			cmd_pipeline_selector_group_add_help);
2897598fe0ddSCristian Dumitrescu 		return;
2898598fe0ddSCristian Dumitrescu 	}
2899598fe0ddSCristian Dumitrescu 
2900598fe0ddSCristian Dumitrescu 	if ((strcmp(tokens[0], "pipeline") == 0) &&
2901598fe0ddSCristian Dumitrescu 		(n_tokens == 4) &&
2902598fe0ddSCristian Dumitrescu 		(strcmp(tokens[1], "selector") == 0) &&
2903598fe0ddSCristian Dumitrescu 		(strcmp(tokens[2], "group") == 0) &&
2904598fe0ddSCristian Dumitrescu 		(strcmp(tokens[3], "delete") == 0)) {
2905598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n",
2906598fe0ddSCristian Dumitrescu 			cmd_pipeline_selector_group_delete_help);
2907598fe0ddSCristian Dumitrescu 		return;
2908598fe0ddSCristian Dumitrescu 	}
2909598fe0ddSCristian Dumitrescu 
2910598fe0ddSCristian Dumitrescu 	if ((strcmp(tokens[0], "pipeline") == 0) &&
2911598fe0ddSCristian Dumitrescu 		(n_tokens == 5) &&
2912598fe0ddSCristian Dumitrescu 		(strcmp(tokens[1], "selector") == 0) &&
2913598fe0ddSCristian Dumitrescu 		(strcmp(tokens[2], "group") == 0) &&
2914598fe0ddSCristian Dumitrescu 		(strcmp(tokens[3], "member") == 0) &&
2915598fe0ddSCristian Dumitrescu 		(strcmp(tokens[4], "add") == 0)) {
2916598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n",
2917598fe0ddSCristian Dumitrescu 			cmd_pipeline_selector_group_member_add_help);
2918598fe0ddSCristian Dumitrescu 		return;
2919598fe0ddSCristian Dumitrescu 	}
2920598fe0ddSCristian Dumitrescu 
2921598fe0ddSCristian Dumitrescu 	if ((strcmp(tokens[0], "pipeline") == 0) &&
2922598fe0ddSCristian Dumitrescu 		(n_tokens == 5) &&
2923598fe0ddSCristian Dumitrescu 		(strcmp(tokens[1], "selector") == 0) &&
2924598fe0ddSCristian Dumitrescu 		(strcmp(tokens[2], "group") == 0) &&
2925598fe0ddSCristian Dumitrescu 		(strcmp(tokens[3], "member") == 0) &&
2926598fe0ddSCristian Dumitrescu 		(strcmp(tokens[4], "delete") == 0)) {
2927598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n",
2928598fe0ddSCristian Dumitrescu 			cmd_pipeline_selector_group_member_delete_help);
2929598fe0ddSCristian Dumitrescu 		return;
2930598fe0ddSCristian Dumitrescu 	}
2931598fe0ddSCristian Dumitrescu 
2932598fe0ddSCristian Dumitrescu 	if ((strcmp(tokens[0], "pipeline") == 0) &&
2933598fe0ddSCristian Dumitrescu 		(n_tokens == 3) &&
2934598fe0ddSCristian Dumitrescu 		(strcmp(tokens[1], "selector") == 0) &&
2935598fe0ddSCristian Dumitrescu 		(strcmp(tokens[2], "show") == 0)) {
2936598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n",
2937598fe0ddSCristian Dumitrescu 			cmd_pipeline_selector_show_help);
2938598fe0ddSCristian Dumitrescu 		return;
2939598fe0ddSCristian Dumitrescu 	}
2940598fe0ddSCristian Dumitrescu 
2941598fe0ddSCristian Dumitrescu 	if ((strcmp(tokens[0], "pipeline") == 0) &&
2942*8bd4862fSCristian Dumitrescu 		(n_tokens == 3) &&
2943*8bd4862fSCristian Dumitrescu 		(strcmp(tokens[1], "learner") == 0) &&
2944*8bd4862fSCristian Dumitrescu 		(strcmp(tokens[2], "default") == 0)) {
2945*8bd4862fSCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n",
2946*8bd4862fSCristian Dumitrescu 			cmd_pipeline_learner_default_help);
2947*8bd4862fSCristian Dumitrescu 		return;
2948*8bd4862fSCristian Dumitrescu 	}
2949*8bd4862fSCristian Dumitrescu 
2950*8bd4862fSCristian Dumitrescu 	if ((strcmp(tokens[0], "pipeline") == 0) &&
295175129cebSChurchill Khangar 		(n_tokens == 2) &&
295275129cebSChurchill Khangar 		(strcmp(tokens[1], "commit") == 0)) {
295375129cebSChurchill Khangar 		snprintf(out, out_size, "\n%s\n",
295475129cebSChurchill Khangar 			cmd_pipeline_commit_help);
295575129cebSChurchill Khangar 		return;
295675129cebSChurchill Khangar 	}
295775129cebSChurchill Khangar 
295875129cebSChurchill Khangar 	if ((strcmp(tokens[0], "pipeline") == 0) &&
295975129cebSChurchill Khangar 		(n_tokens == 2) &&
296075129cebSChurchill Khangar 		(strcmp(tokens[1], "abort") == 0)) {
296175129cebSChurchill Khangar 		snprintf(out, out_size, "\n%s\n",
296275129cebSChurchill Khangar 			cmd_pipeline_abort_help);
29635074e1d5SCristian Dumitrescu 		return;
29645074e1d5SCristian Dumitrescu 	}
29655074e1d5SCristian Dumitrescu 
29665074e1d5SCristian Dumitrescu 	if ((strcmp(tokens[0], "pipeline") == 0) &&
296764cfcebdSCristian Dumitrescu 		(n_tokens == 2) && (strcmp(tokens[1], "regrd") == 0)) {
296864cfcebdSCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n", cmd_pipeline_regrd_help);
296964cfcebdSCristian Dumitrescu 		return;
297064cfcebdSCristian Dumitrescu 	}
297164cfcebdSCristian Dumitrescu 
297264cfcebdSCristian Dumitrescu 	if ((strcmp(tokens[0], "pipeline") == 0) &&
297364cfcebdSCristian Dumitrescu 		(n_tokens == 2) && (strcmp(tokens[1], "regwr") == 0)) {
297464cfcebdSCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n", cmd_pipeline_regwr_help);
297564cfcebdSCristian Dumitrescu 		return;
297664cfcebdSCristian Dumitrescu 	}
297764cfcebdSCristian Dumitrescu 
2978f38913b7SCristian Dumitrescu 	if (!strcmp(tokens[0], "pipeline") &&
2979f38913b7SCristian Dumitrescu 		(n_tokens == 4) && !strcmp(tokens[1], "meter")
2980f38913b7SCristian Dumitrescu 		&& !strcmp(tokens[2], "profile")
2981f38913b7SCristian Dumitrescu 		&& !strcmp(tokens[3], "add")) {
2982f38913b7SCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n", cmd_pipeline_meter_profile_add_help);
2983f38913b7SCristian Dumitrescu 		return;
2984f38913b7SCristian Dumitrescu 	}
2985f38913b7SCristian Dumitrescu 
2986f38913b7SCristian Dumitrescu 	if (!strcmp(tokens[0], "pipeline") &&
2987f38913b7SCristian Dumitrescu 		(n_tokens == 4) && !strcmp(tokens[1], "meter")
2988f38913b7SCristian Dumitrescu 		&& !strcmp(tokens[2], "profile")
2989f38913b7SCristian Dumitrescu 		&& !strcmp(tokens[3], "delete")) {
2990f38913b7SCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n", cmd_pipeline_meter_profile_delete_help);
2991f38913b7SCristian Dumitrescu 		return;
2992f38913b7SCristian Dumitrescu 	}
2993f38913b7SCristian Dumitrescu 
2994f38913b7SCristian Dumitrescu 	if (!strcmp(tokens[0], "pipeline") &&
2995f38913b7SCristian Dumitrescu 		(n_tokens == 3) && !strcmp(tokens[1], "meter")
2996f38913b7SCristian Dumitrescu 		&& !strcmp(tokens[2], "reset")) {
2997f38913b7SCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n", cmd_pipeline_meter_reset_help);
2998f38913b7SCristian Dumitrescu 		return;
2999f38913b7SCristian Dumitrescu 	}
3000f38913b7SCristian Dumitrescu 
3001f38913b7SCristian Dumitrescu 	if (!strcmp(tokens[0], "pipeline") &&
3002f38913b7SCristian Dumitrescu 		(n_tokens == 3) && !strcmp(tokens[1], "meter")
3003f38913b7SCristian Dumitrescu 		&& !strcmp(tokens[2], "set")) {
3004f38913b7SCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n", cmd_pipeline_meter_set_help);
3005f38913b7SCristian Dumitrescu 		return;
3006f38913b7SCristian Dumitrescu 	}
3007f38913b7SCristian Dumitrescu 
3008f38913b7SCristian Dumitrescu 	if (!strcmp(tokens[0], "pipeline") &&
3009f38913b7SCristian Dumitrescu 		(n_tokens == 3) && !strcmp(tokens[1], "meter")
3010f38913b7SCristian Dumitrescu 		&& !strcmp(tokens[2], "stats")) {
3011f38913b7SCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n", cmd_pipeline_meter_stats_help);
3012f38913b7SCristian Dumitrescu 		return;
3013f38913b7SCristian Dumitrescu 	}
3014f38913b7SCristian Dumitrescu 
301564cfcebdSCristian Dumitrescu 	if ((strcmp(tokens[0], "pipeline") == 0) &&
30167fef9ef1SYogesh Jangra 		(n_tokens == 2) && (strcmp(tokens[1], "stats") == 0)) {
30175074e1d5SCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n", cmd_pipeline_stats_help);
30185074e1d5SCristian Dumitrescu 		return;
30195074e1d5SCristian Dumitrescu 	}
30205074e1d5SCristian Dumitrescu 
30215074e1d5SCristian Dumitrescu 	if ((n_tokens == 3) &&
30225074e1d5SCristian Dumitrescu 		(strcmp(tokens[0], "thread") == 0) &&
30235074e1d5SCristian Dumitrescu 		(strcmp(tokens[1], "pipeline") == 0)) {
30245074e1d5SCristian Dumitrescu 		if (strcmp(tokens[2], "enable") == 0) {
30255074e1d5SCristian Dumitrescu 			snprintf(out, out_size, "\n%s\n",
30265074e1d5SCristian Dumitrescu 				cmd_thread_pipeline_enable_help);
30275074e1d5SCristian Dumitrescu 			return;
30285074e1d5SCristian Dumitrescu 		}
30295074e1d5SCristian Dumitrescu 
30305074e1d5SCristian Dumitrescu 		if (strcmp(tokens[2], "disable") == 0) {
30315074e1d5SCristian Dumitrescu 			snprintf(out, out_size, "\n%s\n",
30325074e1d5SCristian Dumitrescu 				cmd_thread_pipeline_disable_help);
30335074e1d5SCristian Dumitrescu 			return;
30345074e1d5SCristian Dumitrescu 		}
30355074e1d5SCristian Dumitrescu 	}
30365074e1d5SCristian Dumitrescu 
30375074e1d5SCristian Dumitrescu 	snprintf(out, out_size, "Invalid command\n");
30385074e1d5SCristian Dumitrescu }
30395074e1d5SCristian Dumitrescu 
30405074e1d5SCristian Dumitrescu void
30415074e1d5SCristian Dumitrescu cli_process(char *in, char *out, size_t out_size, void *obj)
30425074e1d5SCristian Dumitrescu {
30435074e1d5SCristian Dumitrescu 	char *tokens[CMD_MAX_TOKENS];
30445074e1d5SCristian Dumitrescu 	uint32_t n_tokens = RTE_DIM(tokens);
30455074e1d5SCristian Dumitrescu 	int status;
30465074e1d5SCristian Dumitrescu 
30475074e1d5SCristian Dumitrescu 	if (is_comment(in))
30485074e1d5SCristian Dumitrescu 		return;
30495074e1d5SCristian Dumitrescu 
30505074e1d5SCristian Dumitrescu 	status = parse_tokenize_string(in, tokens, &n_tokens);
30515074e1d5SCristian Dumitrescu 	if (status) {
30525074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_TOO_MANY, "");
30535074e1d5SCristian Dumitrescu 		return;
30545074e1d5SCristian Dumitrescu 	}
30555074e1d5SCristian Dumitrescu 
30565074e1d5SCristian Dumitrescu 	if (n_tokens == 0)
30575074e1d5SCristian Dumitrescu 		return;
30585074e1d5SCristian Dumitrescu 
30595074e1d5SCristian Dumitrescu 	if (strcmp(tokens[0], "help") == 0) {
30605074e1d5SCristian Dumitrescu 		cmd_help(tokens, n_tokens, out, out_size, obj);
30615074e1d5SCristian Dumitrescu 		return;
30625074e1d5SCristian Dumitrescu 	}
30635074e1d5SCristian Dumitrescu 
30645074e1d5SCristian Dumitrescu 	if (strcmp(tokens[0], "mempool") == 0) {
30655074e1d5SCristian Dumitrescu 		cmd_mempool(tokens, n_tokens, out, out_size, obj);
30665074e1d5SCristian Dumitrescu 		return;
30675074e1d5SCristian Dumitrescu 	}
30685074e1d5SCristian Dumitrescu 
30695074e1d5SCristian Dumitrescu 	if (strcmp(tokens[0], "link") == 0) {
3070821848f5SCristian Dumitrescu 		if ((n_tokens >= 2) && (strcmp(tokens[1], "show") == 0)) {
30715074e1d5SCristian Dumitrescu 			cmd_link_show(tokens, n_tokens, out, out_size, obj);
30725074e1d5SCristian Dumitrescu 			return;
30735074e1d5SCristian Dumitrescu 		}
30745074e1d5SCristian Dumitrescu 
30755074e1d5SCristian Dumitrescu 		cmd_link(tokens, n_tokens, out, out_size, obj);
30765074e1d5SCristian Dumitrescu 		return;
30775074e1d5SCristian Dumitrescu 	}
30785074e1d5SCristian Dumitrescu 
307977a41301SCristian Dumitrescu 	if (strcmp(tokens[0], "ring") == 0) {
308077a41301SCristian Dumitrescu 		cmd_ring(tokens, n_tokens, out, out_size, obj);
308177a41301SCristian Dumitrescu 		return;
308277a41301SCristian Dumitrescu 	}
308377a41301SCristian Dumitrescu 
3084e2b8dc52SVenkata Suresh Kumar P 	if (strcmp(tokens[0], "tap") == 0) {
3085e2b8dc52SVenkata Suresh Kumar P 		cmd_tap(tokens, n_tokens, out, out_size, obj);
3086e2b8dc52SVenkata Suresh Kumar P 		return;
3087e2b8dc52SVenkata Suresh Kumar P 	}
3088e2b8dc52SVenkata Suresh Kumar P 
30895074e1d5SCristian Dumitrescu 	if (strcmp(tokens[0], "pipeline") == 0) {
30905074e1d5SCristian Dumitrescu 		if ((n_tokens >= 3) &&
30915074e1d5SCristian Dumitrescu 			(strcmp(tokens[2], "create") == 0)) {
30925074e1d5SCristian Dumitrescu 			cmd_pipeline_create(tokens, n_tokens, out, out_size,
30935074e1d5SCristian Dumitrescu 				obj);
30945074e1d5SCristian Dumitrescu 			return;
30955074e1d5SCristian Dumitrescu 		}
30965074e1d5SCristian Dumitrescu 
30975074e1d5SCristian Dumitrescu 		if ((n_tokens >= 4) &&
30985074e1d5SCristian Dumitrescu 			(strcmp(tokens[2], "port") == 0) &&
30995074e1d5SCristian Dumitrescu 			(strcmp(tokens[3], "in") == 0)) {
31005074e1d5SCristian Dumitrescu 			cmd_pipeline_port_in(tokens, n_tokens, out, out_size,
31015074e1d5SCristian Dumitrescu 				obj);
31025074e1d5SCristian Dumitrescu 			return;
31035074e1d5SCristian Dumitrescu 		}
31045074e1d5SCristian Dumitrescu 
31055074e1d5SCristian Dumitrescu 		if ((n_tokens >= 4) &&
31065074e1d5SCristian Dumitrescu 			(strcmp(tokens[2], "port") == 0) &&
31075074e1d5SCristian Dumitrescu 			(strcmp(tokens[3], "out") == 0)) {
31085074e1d5SCristian Dumitrescu 			cmd_pipeline_port_out(tokens, n_tokens, out, out_size,
31095074e1d5SCristian Dumitrescu 				obj);
31105074e1d5SCristian Dumitrescu 			return;
31115074e1d5SCristian Dumitrescu 		}
31125074e1d5SCristian Dumitrescu 
31135074e1d5SCristian Dumitrescu 		if ((n_tokens >= 3) &&
31145074e1d5SCristian Dumitrescu 			(strcmp(tokens[2], "build") == 0)) {
31155074e1d5SCristian Dumitrescu 			cmd_pipeline_build(tokens, n_tokens, out, out_size,
31165074e1d5SCristian Dumitrescu 				obj);
31175074e1d5SCristian Dumitrescu 			return;
31185074e1d5SCristian Dumitrescu 		}
31195074e1d5SCristian Dumitrescu 
312075129cebSChurchill Khangar 		if ((n_tokens >= 5) &&
312175129cebSChurchill Khangar 			(strcmp(tokens[2], "table") == 0) &&
312275129cebSChurchill Khangar 			(strcmp(tokens[4], "add") == 0)) {
312375129cebSChurchill Khangar 			cmd_pipeline_table_add(tokens, n_tokens, out,
312475129cebSChurchill Khangar 				out_size, obj);
312575129cebSChurchill Khangar 			return;
312675129cebSChurchill Khangar 		}
312775129cebSChurchill Khangar 
312875129cebSChurchill Khangar 		if ((n_tokens >= 5) &&
312975129cebSChurchill Khangar 			(strcmp(tokens[2], "table") == 0) &&
313075129cebSChurchill Khangar 			(strcmp(tokens[4], "delete") == 0)) {
313175129cebSChurchill Khangar 			cmd_pipeline_table_delete(tokens, n_tokens, out,
313275129cebSChurchill Khangar 				out_size, obj);
313375129cebSChurchill Khangar 			return;
313475129cebSChurchill Khangar 		}
313575129cebSChurchill Khangar 
313675129cebSChurchill Khangar 		if ((n_tokens >= 5) &&
313775129cebSChurchill Khangar 			(strcmp(tokens[2], "table") == 0) &&
313875129cebSChurchill Khangar 			(strcmp(tokens[4], "default") == 0)) {
313975129cebSChurchill Khangar 			cmd_pipeline_table_default(tokens, n_tokens, out,
314075129cebSChurchill Khangar 				out_size, obj);
314175129cebSChurchill Khangar 			return;
314275129cebSChurchill Khangar 		}
314375129cebSChurchill Khangar 
314475129cebSChurchill Khangar 		if ((n_tokens >= 5) &&
314575129cebSChurchill Khangar 			(strcmp(tokens[2], "table") == 0) &&
314675129cebSChurchill Khangar 			(strcmp(tokens[4], "show") == 0)) {
314775129cebSChurchill Khangar 			cmd_pipeline_table_show(tokens, n_tokens, out,
314875129cebSChurchill Khangar 				out_size, obj);
314975129cebSChurchill Khangar 			return;
315075129cebSChurchill Khangar 		}
315175129cebSChurchill Khangar 
3152598fe0ddSCristian Dumitrescu 		if ((n_tokens >= 6) &&
3153598fe0ddSCristian Dumitrescu 			(strcmp(tokens[2], "selector") == 0) &&
3154598fe0ddSCristian Dumitrescu 			(strcmp(tokens[4], "group") == 0) &&
3155598fe0ddSCristian Dumitrescu 			(strcmp(tokens[5], "add") == 0)) {
3156598fe0ddSCristian Dumitrescu 			cmd_pipeline_selector_group_add(tokens, n_tokens, out,
3157598fe0ddSCristian Dumitrescu 				out_size, obj);
3158598fe0ddSCristian Dumitrescu 			return;
3159598fe0ddSCristian Dumitrescu 		}
3160598fe0ddSCristian Dumitrescu 
3161598fe0ddSCristian Dumitrescu 		if ((n_tokens >= 6) &&
3162598fe0ddSCristian Dumitrescu 			(strcmp(tokens[2], "selector") == 0) &&
3163598fe0ddSCristian Dumitrescu 			(strcmp(tokens[4], "group") == 0) &&
3164598fe0ddSCristian Dumitrescu 			(strcmp(tokens[5], "delete") == 0)) {
3165598fe0ddSCristian Dumitrescu 			cmd_pipeline_selector_group_delete(tokens, n_tokens, out,
3166598fe0ddSCristian Dumitrescu 				out_size, obj);
3167598fe0ddSCristian Dumitrescu 			return;
3168598fe0ddSCristian Dumitrescu 		}
3169598fe0ddSCristian Dumitrescu 
3170598fe0ddSCristian Dumitrescu 		if ((n_tokens >= 7) &&
3171598fe0ddSCristian Dumitrescu 			(strcmp(tokens[2], "selector") == 0) &&
3172598fe0ddSCristian Dumitrescu 			(strcmp(tokens[4], "group") == 0) &&
3173598fe0ddSCristian Dumitrescu 			(strcmp(tokens[5], "member") == 0) &&
3174598fe0ddSCristian Dumitrescu 			(strcmp(tokens[6], "add") == 0)) {
3175598fe0ddSCristian Dumitrescu 			cmd_pipeline_selector_group_member_add(tokens, n_tokens, out,
3176598fe0ddSCristian Dumitrescu 				out_size, obj);
3177598fe0ddSCristian Dumitrescu 			return;
3178598fe0ddSCristian Dumitrescu 		}
3179598fe0ddSCristian Dumitrescu 
3180598fe0ddSCristian Dumitrescu 		if ((n_tokens >= 7) &&
3181598fe0ddSCristian Dumitrescu 			(strcmp(tokens[2], "selector") == 0) &&
3182598fe0ddSCristian Dumitrescu 			(strcmp(tokens[4], "group") == 0) &&
3183598fe0ddSCristian Dumitrescu 			(strcmp(tokens[5], "member") == 0) &&
3184598fe0ddSCristian Dumitrescu 			(strcmp(tokens[6], "delete") == 0)) {
3185598fe0ddSCristian Dumitrescu 			cmd_pipeline_selector_group_member_delete(tokens, n_tokens, out,
3186598fe0ddSCristian Dumitrescu 				out_size, obj);
3187598fe0ddSCristian Dumitrescu 			return;
3188598fe0ddSCristian Dumitrescu 		}
3189598fe0ddSCristian Dumitrescu 
3190598fe0ddSCristian Dumitrescu 		if ((n_tokens >= 5) &&
3191598fe0ddSCristian Dumitrescu 			(strcmp(tokens[2], "selector") == 0) &&
3192598fe0ddSCristian Dumitrescu 			(strcmp(tokens[4], "show") == 0)) {
3193598fe0ddSCristian Dumitrescu 			cmd_pipeline_selector_show(tokens, n_tokens, out,
3194598fe0ddSCristian Dumitrescu 				out_size, obj);
3195598fe0ddSCristian Dumitrescu 			return;
3196598fe0ddSCristian Dumitrescu 		}
3197598fe0ddSCristian Dumitrescu 
3198*8bd4862fSCristian Dumitrescu 		if ((n_tokens >= 5) &&
3199*8bd4862fSCristian Dumitrescu 			(strcmp(tokens[2], "learner") == 0) &&
3200*8bd4862fSCristian Dumitrescu 			(strcmp(tokens[4], "default") == 0)) {
3201*8bd4862fSCristian Dumitrescu 			cmd_pipeline_learner_default(tokens, n_tokens, out,
3202*8bd4862fSCristian Dumitrescu 				out_size, obj);
3203*8bd4862fSCristian Dumitrescu 			return;
3204*8bd4862fSCristian Dumitrescu 		}
3205*8bd4862fSCristian Dumitrescu 
32065074e1d5SCristian Dumitrescu 		if ((n_tokens >= 3) &&
320775129cebSChurchill Khangar 			(strcmp(tokens[2], "commit") == 0)) {
320875129cebSChurchill Khangar 			cmd_pipeline_commit(tokens, n_tokens, out,
320975129cebSChurchill Khangar 				out_size, obj);
321075129cebSChurchill Khangar 			return;
321175129cebSChurchill Khangar 		}
321275129cebSChurchill Khangar 
321375129cebSChurchill Khangar 		if ((n_tokens >= 3) &&
321475129cebSChurchill Khangar 			(strcmp(tokens[2], "abort") == 0)) {
321575129cebSChurchill Khangar 			cmd_pipeline_abort(tokens, n_tokens, out,
32165074e1d5SCristian Dumitrescu 				out_size, obj);
32175074e1d5SCristian Dumitrescu 			return;
32185074e1d5SCristian Dumitrescu 		}
32195074e1d5SCristian Dumitrescu 
32205074e1d5SCristian Dumitrescu 		if ((n_tokens >= 3) &&
322164cfcebdSCristian Dumitrescu 			(strcmp(tokens[2], "regrd") == 0)) {
322264cfcebdSCristian Dumitrescu 			cmd_pipeline_regrd(tokens, n_tokens, out, out_size, obj);
322364cfcebdSCristian Dumitrescu 			return;
322464cfcebdSCristian Dumitrescu 		}
322564cfcebdSCristian Dumitrescu 
322664cfcebdSCristian Dumitrescu 		if ((n_tokens >= 3) &&
322764cfcebdSCristian Dumitrescu 			(strcmp(tokens[2], "regwr") == 0)) {
322864cfcebdSCristian Dumitrescu 			cmd_pipeline_regwr(tokens, n_tokens, out, out_size, obj);
322964cfcebdSCristian Dumitrescu 			return;
323064cfcebdSCristian Dumitrescu 		}
323164cfcebdSCristian Dumitrescu 
3232f38913b7SCristian Dumitrescu 		if ((n_tokens >= 6) &&
3233f38913b7SCristian Dumitrescu 			(strcmp(tokens[2], "meter") == 0) &&
3234f38913b7SCristian Dumitrescu 			(strcmp(tokens[3], "profile") == 0) &&
3235f38913b7SCristian Dumitrescu 			(strcmp(tokens[5], "add") == 0)) {
3236f38913b7SCristian Dumitrescu 			cmd_pipeline_meter_profile_add(tokens, n_tokens, out, out_size, obj);
3237f38913b7SCristian Dumitrescu 			return;
3238f38913b7SCristian Dumitrescu 		}
3239f38913b7SCristian Dumitrescu 
3240f38913b7SCristian Dumitrescu 		if ((n_tokens >= 6) &&
3241f38913b7SCristian Dumitrescu 			(strcmp(tokens[2], "meter") == 0) &&
3242f38913b7SCristian Dumitrescu 			(strcmp(tokens[3], "profile") == 0) &&
3243f38913b7SCristian Dumitrescu 			(strcmp(tokens[5], "delete") == 0)) {
3244f38913b7SCristian Dumitrescu 			cmd_pipeline_meter_profile_delete(tokens, n_tokens, out, out_size, obj);
3245f38913b7SCristian Dumitrescu 			return;
3246f38913b7SCristian Dumitrescu 		}
3247f38913b7SCristian Dumitrescu 
3248f38913b7SCristian Dumitrescu 		if ((n_tokens >= 9) &&
3249f38913b7SCristian Dumitrescu 			(strcmp(tokens[2], "meter") == 0) &&
3250f38913b7SCristian Dumitrescu 			(strcmp(tokens[8], "reset") == 0)) {
3251f38913b7SCristian Dumitrescu 			cmd_pipeline_meter_reset(tokens, n_tokens, out, out_size, obj);
3252f38913b7SCristian Dumitrescu 			return;
3253f38913b7SCristian Dumitrescu 		}
3254f38913b7SCristian Dumitrescu 
3255f38913b7SCristian Dumitrescu 		if ((n_tokens >= 9) &&
3256f38913b7SCristian Dumitrescu 			(strcmp(tokens[2], "meter") == 0) &&
3257f38913b7SCristian Dumitrescu 			(strcmp(tokens[8], "set") == 0)) {
3258f38913b7SCristian Dumitrescu 			cmd_pipeline_meter_set(tokens, n_tokens, out, out_size, obj);
3259f38913b7SCristian Dumitrescu 			return;
3260f38913b7SCristian Dumitrescu 		}
3261f38913b7SCristian Dumitrescu 
3262f38913b7SCristian Dumitrescu 		if ((n_tokens >= 9) &&
3263f38913b7SCristian Dumitrescu 			(strcmp(tokens[2], "meter") == 0) &&
3264f38913b7SCristian Dumitrescu 			(strcmp(tokens[8], "stats") == 0)) {
3265f38913b7SCristian Dumitrescu 			cmd_pipeline_meter_stats(tokens, n_tokens, out, out_size, obj);
3266f38913b7SCristian Dumitrescu 			return;
3267f38913b7SCristian Dumitrescu 		}
3268f38913b7SCristian Dumitrescu 
326964cfcebdSCristian Dumitrescu 		if ((n_tokens >= 3) &&
32705074e1d5SCristian Dumitrescu 			(strcmp(tokens[2], "stats") == 0)) {
32715074e1d5SCristian Dumitrescu 			cmd_pipeline_stats(tokens, n_tokens, out, out_size,
32725074e1d5SCristian Dumitrescu 				obj);
32735074e1d5SCristian Dumitrescu 			return;
32745074e1d5SCristian Dumitrescu 		}
32755074e1d5SCristian Dumitrescu 	}
32765074e1d5SCristian Dumitrescu 
32775074e1d5SCristian Dumitrescu 	if (strcmp(tokens[0], "thread") == 0) {
32785074e1d5SCristian Dumitrescu 		if ((n_tokens >= 5) &&
32795074e1d5SCristian Dumitrescu 			(strcmp(tokens[4], "enable") == 0)) {
32805074e1d5SCristian Dumitrescu 			cmd_thread_pipeline_enable(tokens, n_tokens,
32815074e1d5SCristian Dumitrescu 				out, out_size, obj);
32825074e1d5SCristian Dumitrescu 			return;
32835074e1d5SCristian Dumitrescu 		}
32845074e1d5SCristian Dumitrescu 
32855074e1d5SCristian Dumitrescu 		if ((n_tokens >= 5) &&
32865074e1d5SCristian Dumitrescu 			(strcmp(tokens[4], "disable") == 0)) {
32875074e1d5SCristian Dumitrescu 			cmd_thread_pipeline_disable(tokens, n_tokens,
32885074e1d5SCristian Dumitrescu 				out, out_size, obj);
32895074e1d5SCristian Dumitrescu 			return;
32905074e1d5SCristian Dumitrescu 		}
32915074e1d5SCristian Dumitrescu 	}
32925074e1d5SCristian Dumitrescu 
32935074e1d5SCristian Dumitrescu 	snprintf(out, out_size, MSG_CMD_UNKNOWN, tokens[0]);
32945074e1d5SCristian Dumitrescu }
32955074e1d5SCristian Dumitrescu 
32965074e1d5SCristian Dumitrescu int
32975074e1d5SCristian Dumitrescu cli_script_process(const char *file_name,
32985074e1d5SCristian Dumitrescu 	size_t msg_in_len_max,
32995074e1d5SCristian Dumitrescu 	size_t msg_out_len_max,
33005074e1d5SCristian Dumitrescu 	void *obj)
33015074e1d5SCristian Dumitrescu {
33025074e1d5SCristian Dumitrescu 	char *msg_in = NULL, *msg_out = NULL;
33035074e1d5SCristian Dumitrescu 	FILE *f = NULL;
33045074e1d5SCristian Dumitrescu 
33055074e1d5SCristian Dumitrescu 	/* Check input arguments */
33065074e1d5SCristian Dumitrescu 	if ((file_name == NULL) ||
33075074e1d5SCristian Dumitrescu 		(strlen(file_name) == 0) ||
33085074e1d5SCristian Dumitrescu 		(msg_in_len_max == 0) ||
33095074e1d5SCristian Dumitrescu 		(msg_out_len_max == 0))
33105074e1d5SCristian Dumitrescu 		return -EINVAL;
33115074e1d5SCristian Dumitrescu 
33125074e1d5SCristian Dumitrescu 	msg_in = malloc(msg_in_len_max + 1);
33135074e1d5SCristian Dumitrescu 	msg_out = malloc(msg_out_len_max + 1);
33145074e1d5SCristian Dumitrescu 	if ((msg_in == NULL) ||
33155074e1d5SCristian Dumitrescu 		(msg_out == NULL)) {
33165074e1d5SCristian Dumitrescu 		free(msg_out);
33175074e1d5SCristian Dumitrescu 		free(msg_in);
33185074e1d5SCristian Dumitrescu 		return -ENOMEM;
33195074e1d5SCristian Dumitrescu 	}
33205074e1d5SCristian Dumitrescu 
33215074e1d5SCristian Dumitrescu 	/* Open input file */
33225074e1d5SCristian Dumitrescu 	f = fopen(file_name, "r");
33235074e1d5SCristian Dumitrescu 	if (f == NULL) {
33245074e1d5SCristian Dumitrescu 		free(msg_out);
33255074e1d5SCristian Dumitrescu 		free(msg_in);
33265074e1d5SCristian Dumitrescu 		return -EIO;
33275074e1d5SCristian Dumitrescu 	}
33285074e1d5SCristian Dumitrescu 
33295074e1d5SCristian Dumitrescu 	/* Read file */
33305074e1d5SCristian Dumitrescu 	for ( ; ; ) {
33315074e1d5SCristian Dumitrescu 		if (fgets(msg_in, msg_in_len_max + 1, f) == NULL)
33325074e1d5SCristian Dumitrescu 			break;
33335074e1d5SCristian Dumitrescu 
33345074e1d5SCristian Dumitrescu 		printf("%s", msg_in);
33355074e1d5SCristian Dumitrescu 		msg_out[0] = 0;
33365074e1d5SCristian Dumitrescu 
33375074e1d5SCristian Dumitrescu 		cli_process(msg_in,
33385074e1d5SCristian Dumitrescu 			msg_out,
33395074e1d5SCristian Dumitrescu 			msg_out_len_max,
33405074e1d5SCristian Dumitrescu 			obj);
33415074e1d5SCristian Dumitrescu 
33425074e1d5SCristian Dumitrescu 		if (strlen(msg_out))
33435074e1d5SCristian Dumitrescu 			printf("%s", msg_out);
33445074e1d5SCristian Dumitrescu 	}
33455074e1d5SCristian Dumitrescu 
33465074e1d5SCristian Dumitrescu 	/* Close file */
33475074e1d5SCristian Dumitrescu 	fclose(f);
33485074e1d5SCristian Dumitrescu 	free(msg_out);
33495074e1d5SCristian Dumitrescu 	free(msg_in);
33505074e1d5SCristian Dumitrescu 	return 0;
33515074e1d5SCristian Dumitrescu }
3352