xref: /dpdk/examples/pipeline/cli.c (revision b9559f943c0b2f7cb22ed8c328411177fddfe500)
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>
96bc14d9fSCristian Dumitrescu #include <unistd.h>
105074e1d5SCristian Dumitrescu 
115074e1d5SCristian Dumitrescu #include <rte_common.h>
125074e1d5SCristian Dumitrescu #include <rte_ethdev.h>
135074e1d5SCristian Dumitrescu #include <rte_swx_port_ethdev.h>
1477a41301SCristian Dumitrescu #include <rte_swx_port_ring.h>
155074e1d5SCristian Dumitrescu #include <rte_swx_port_source_sink.h>
16e2b8dc52SVenkata Suresh Kumar P #include <rte_swx_port_fd.h>
175074e1d5SCristian Dumitrescu #include <rte_swx_pipeline.h>
185074e1d5SCristian Dumitrescu #include <rte_swx_ctl.h>
195074e1d5SCristian Dumitrescu 
205074e1d5SCristian Dumitrescu #include "cli.h"
215074e1d5SCristian Dumitrescu 
225074e1d5SCristian Dumitrescu #include "obj.h"
235074e1d5SCristian Dumitrescu #include "thread.h"
245074e1d5SCristian Dumitrescu 
255074e1d5SCristian Dumitrescu #ifndef CMD_MAX_TOKENS
265074e1d5SCristian Dumitrescu #define CMD_MAX_TOKENS     256
275074e1d5SCristian Dumitrescu #endif
285074e1d5SCristian Dumitrescu 
296bc14d9fSCristian Dumitrescu #ifndef MAX_LINE_SIZE
306bc14d9fSCristian Dumitrescu #define MAX_LINE_SIZE 2048
316bc14d9fSCristian Dumitrescu #endif
326bc14d9fSCristian Dumitrescu 
335074e1d5SCristian Dumitrescu #define MSG_OUT_OF_MEMORY   "Not enough memory.\n"
345074e1d5SCristian Dumitrescu #define MSG_CMD_UNKNOWN     "Unknown command \"%s\".\n"
355074e1d5SCristian Dumitrescu #define MSG_CMD_UNIMPLEM    "Command \"%s\" not implemented.\n"
365074e1d5SCristian Dumitrescu #define MSG_ARG_NOT_ENOUGH  "Not enough arguments for command \"%s\".\n"
375074e1d5SCristian Dumitrescu #define MSG_ARG_TOO_MANY    "Too many arguments for command \"%s\".\n"
385074e1d5SCristian Dumitrescu #define MSG_ARG_MISMATCH    "Wrong number of arguments for command \"%s\".\n"
395074e1d5SCristian Dumitrescu #define MSG_ARG_NOT_FOUND   "Argument \"%s\" not found.\n"
405074e1d5SCristian Dumitrescu #define MSG_ARG_INVALID     "Invalid value for argument \"%s\".\n"
415074e1d5SCristian Dumitrescu #define MSG_FILE_ERR        "Error in file \"%s\" at line %u.\n"
425074e1d5SCristian Dumitrescu #define MSG_FILE_NOT_ENOUGH "Not enough rules in file \"%s\".\n"
435074e1d5SCristian Dumitrescu #define MSG_CMD_FAIL        "Command \"%s\" failed.\n"
445074e1d5SCristian Dumitrescu 
455074e1d5SCristian Dumitrescu #define skip_white_spaces(pos)			\
465074e1d5SCristian Dumitrescu ({						\
475074e1d5SCristian Dumitrescu 	__typeof__(pos) _p = (pos);		\
485074e1d5SCristian Dumitrescu 	for ( ; isspace(*_p); _p++)		\
495074e1d5SCristian Dumitrescu 		;				\
505074e1d5SCristian Dumitrescu 	_p;					\
515074e1d5SCristian Dumitrescu })
525074e1d5SCristian Dumitrescu 
535074e1d5SCristian Dumitrescu static int
545074e1d5SCristian Dumitrescu parser_read_uint64(uint64_t *value, const char *p)
555074e1d5SCristian Dumitrescu {
565074e1d5SCristian Dumitrescu 	char *next;
575074e1d5SCristian Dumitrescu 	uint64_t val;
585074e1d5SCristian Dumitrescu 
595074e1d5SCristian Dumitrescu 	p = skip_white_spaces(p);
605074e1d5SCristian Dumitrescu 	if (!isdigit(*p))
615074e1d5SCristian Dumitrescu 		return -EINVAL;
625074e1d5SCristian Dumitrescu 
630d644eb6SChurchill Khangar 	val = strtoul(p, &next, 0);
645074e1d5SCristian Dumitrescu 	if (p == next)
655074e1d5SCristian Dumitrescu 		return -EINVAL;
665074e1d5SCristian Dumitrescu 
675074e1d5SCristian Dumitrescu 	p = next;
685074e1d5SCristian Dumitrescu 	switch (*p) {
695074e1d5SCristian Dumitrescu 	case 'T':
705074e1d5SCristian Dumitrescu 		val *= 1024ULL;
715074e1d5SCristian Dumitrescu 		/* fall through */
725074e1d5SCristian Dumitrescu 	case 'G':
735074e1d5SCristian Dumitrescu 		val *= 1024ULL;
745074e1d5SCristian Dumitrescu 		/* fall through */
755074e1d5SCristian Dumitrescu 	case 'M':
765074e1d5SCristian Dumitrescu 		val *= 1024ULL;
775074e1d5SCristian Dumitrescu 		/* fall through */
785074e1d5SCristian Dumitrescu 	case 'k':
795074e1d5SCristian Dumitrescu 	case 'K':
805074e1d5SCristian Dumitrescu 		val *= 1024ULL;
815074e1d5SCristian Dumitrescu 		p++;
825074e1d5SCristian Dumitrescu 		break;
835074e1d5SCristian Dumitrescu 	}
845074e1d5SCristian Dumitrescu 
855074e1d5SCristian Dumitrescu 	p = skip_white_spaces(p);
865074e1d5SCristian Dumitrescu 	if (*p != '\0')
875074e1d5SCristian Dumitrescu 		return -EINVAL;
885074e1d5SCristian Dumitrescu 
895074e1d5SCristian Dumitrescu 	*value = val;
905074e1d5SCristian Dumitrescu 	return 0;
915074e1d5SCristian Dumitrescu }
925074e1d5SCristian Dumitrescu 
935074e1d5SCristian Dumitrescu static int
945074e1d5SCristian Dumitrescu parser_read_uint32(uint32_t *value, const char *p)
955074e1d5SCristian Dumitrescu {
965074e1d5SCristian Dumitrescu 	uint64_t val = 0;
975074e1d5SCristian Dumitrescu 	int ret = parser_read_uint64(&val, p);
985074e1d5SCristian Dumitrescu 
995074e1d5SCristian Dumitrescu 	if (ret < 0)
1005074e1d5SCristian Dumitrescu 		return ret;
1015074e1d5SCristian Dumitrescu 
1025074e1d5SCristian Dumitrescu 	if (val > UINT32_MAX)
1035074e1d5SCristian Dumitrescu 		return -ERANGE;
1045074e1d5SCristian Dumitrescu 
1055074e1d5SCristian Dumitrescu 	*value = val;
1065074e1d5SCristian Dumitrescu 	return 0;
1075074e1d5SCristian Dumitrescu }
1085074e1d5SCristian Dumitrescu 
1095074e1d5SCristian Dumitrescu static int
1105074e1d5SCristian Dumitrescu parser_read_uint16(uint16_t *value, const char *p)
1115074e1d5SCristian Dumitrescu {
1125074e1d5SCristian Dumitrescu 	uint64_t val = 0;
1135074e1d5SCristian Dumitrescu 	int ret = parser_read_uint64(&val, p);
1145074e1d5SCristian Dumitrescu 
1155074e1d5SCristian Dumitrescu 	if (ret < 0)
1165074e1d5SCristian Dumitrescu 		return ret;
1175074e1d5SCristian Dumitrescu 
1185074e1d5SCristian Dumitrescu 	if (val > UINT16_MAX)
1195074e1d5SCristian Dumitrescu 		return -ERANGE;
1205074e1d5SCristian Dumitrescu 
1215074e1d5SCristian Dumitrescu 	*value = val;
1225074e1d5SCristian Dumitrescu 	return 0;
1235074e1d5SCristian Dumitrescu }
1245074e1d5SCristian Dumitrescu 
1255074e1d5SCristian Dumitrescu #define PARSE_DELIMITER " \f\n\r\t\v"
1265074e1d5SCristian Dumitrescu 
1275074e1d5SCristian Dumitrescu static int
1285074e1d5SCristian Dumitrescu parse_tokenize_string(char *string, char *tokens[], uint32_t *n_tokens)
1295074e1d5SCristian Dumitrescu {
1305074e1d5SCristian Dumitrescu 	uint32_t i;
1315074e1d5SCristian Dumitrescu 
1325074e1d5SCristian Dumitrescu 	if ((string == NULL) ||
1335074e1d5SCristian Dumitrescu 		(tokens == NULL) ||
1345074e1d5SCristian Dumitrescu 		(*n_tokens < 1))
1355074e1d5SCristian Dumitrescu 		return -EINVAL;
1365074e1d5SCristian Dumitrescu 
1375074e1d5SCristian Dumitrescu 	for (i = 0; i < *n_tokens; i++) {
1385074e1d5SCristian Dumitrescu 		tokens[i] = strtok_r(string, PARSE_DELIMITER, &string);
1395074e1d5SCristian Dumitrescu 		if (tokens[i] == NULL)
1405074e1d5SCristian Dumitrescu 			break;
1415074e1d5SCristian Dumitrescu 	}
1425074e1d5SCristian Dumitrescu 
1435074e1d5SCristian Dumitrescu 	if ((i == *n_tokens) && strtok_r(string, PARSE_DELIMITER, &string))
1445074e1d5SCristian Dumitrescu 		return -E2BIG;
1455074e1d5SCristian Dumitrescu 
1465074e1d5SCristian Dumitrescu 	*n_tokens = i;
1475074e1d5SCristian Dumitrescu 	return 0;
1485074e1d5SCristian Dumitrescu }
1495074e1d5SCristian Dumitrescu 
1505074e1d5SCristian Dumitrescu static int
1515074e1d5SCristian Dumitrescu is_comment(char *in)
1525074e1d5SCristian Dumitrescu {
1535074e1d5SCristian Dumitrescu 	if ((strlen(in) && index("!#%;", in[0])) ||
1545074e1d5SCristian Dumitrescu 		(strncmp(in, "//", 2) == 0) ||
1555074e1d5SCristian Dumitrescu 		(strncmp(in, "--", 2) == 0))
1565074e1d5SCristian Dumitrescu 		return 1;
1575074e1d5SCristian Dumitrescu 
1585074e1d5SCristian Dumitrescu 	return 0;
1595074e1d5SCristian Dumitrescu }
1605074e1d5SCristian Dumitrescu 
1615074e1d5SCristian Dumitrescu static const char cmd_mempool_help[] =
1625074e1d5SCristian Dumitrescu "mempool <mempool_name>\n"
1635074e1d5SCristian Dumitrescu "   buffer <buffer_size>\n"
1645074e1d5SCristian Dumitrescu "   pool <pool_size>\n"
1655074e1d5SCristian Dumitrescu "   cache <cache_size>\n"
1665074e1d5SCristian Dumitrescu "   cpu <cpu_id>\n";
1675074e1d5SCristian Dumitrescu 
1685074e1d5SCristian Dumitrescu static void
1695074e1d5SCristian Dumitrescu cmd_mempool(char **tokens,
1705074e1d5SCristian Dumitrescu 	uint32_t n_tokens,
1715074e1d5SCristian Dumitrescu 	char *out,
1725074e1d5SCristian Dumitrescu 	size_t out_size,
1735074e1d5SCristian Dumitrescu 	void *obj)
1745074e1d5SCristian Dumitrescu {
1755074e1d5SCristian Dumitrescu 	struct mempool_params p;
1765074e1d5SCristian Dumitrescu 	char *name;
1775074e1d5SCristian Dumitrescu 	struct mempool *mempool;
1785074e1d5SCristian Dumitrescu 
1795074e1d5SCristian Dumitrescu 	if (n_tokens != 10) {
1805074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1815074e1d5SCristian Dumitrescu 		return;
1825074e1d5SCristian Dumitrescu 	}
1835074e1d5SCristian Dumitrescu 
1845074e1d5SCristian Dumitrescu 	name = tokens[1];
1855074e1d5SCristian Dumitrescu 
1865074e1d5SCristian Dumitrescu 	if (strcmp(tokens[2], "buffer") != 0) {
1875074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "buffer");
1885074e1d5SCristian Dumitrescu 		return;
1895074e1d5SCristian Dumitrescu 	}
1905074e1d5SCristian Dumitrescu 
1915074e1d5SCristian Dumitrescu 	if (parser_read_uint32(&p.buffer_size, tokens[3]) != 0) {
1925074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "buffer_size");
1935074e1d5SCristian Dumitrescu 		return;
1945074e1d5SCristian Dumitrescu 	}
1955074e1d5SCristian Dumitrescu 
1965074e1d5SCristian Dumitrescu 	if (strcmp(tokens[4], "pool") != 0) {
1975074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pool");
1985074e1d5SCristian Dumitrescu 		return;
1995074e1d5SCristian Dumitrescu 	}
2005074e1d5SCristian Dumitrescu 
2015074e1d5SCristian Dumitrescu 	if (parser_read_uint32(&p.pool_size, tokens[5]) != 0) {
2025074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pool_size");
2035074e1d5SCristian Dumitrescu 		return;
2045074e1d5SCristian Dumitrescu 	}
2055074e1d5SCristian Dumitrescu 
2065074e1d5SCristian Dumitrescu 	if (strcmp(tokens[6], "cache") != 0) {
2075074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cache");
2085074e1d5SCristian Dumitrescu 		return;
2095074e1d5SCristian Dumitrescu 	}
2105074e1d5SCristian Dumitrescu 
2115074e1d5SCristian Dumitrescu 	if (parser_read_uint32(&p.cache_size, tokens[7]) != 0) {
2125074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "cache_size");
2135074e1d5SCristian Dumitrescu 		return;
2145074e1d5SCristian Dumitrescu 	}
2155074e1d5SCristian Dumitrescu 
2165074e1d5SCristian Dumitrescu 	if (strcmp(tokens[8], "cpu") != 0) {
2175074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cpu");
2185074e1d5SCristian Dumitrescu 		return;
2195074e1d5SCristian Dumitrescu 	}
2205074e1d5SCristian Dumitrescu 
2215074e1d5SCristian Dumitrescu 	if (parser_read_uint32(&p.cpu_id, tokens[9]) != 0) {
2225074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "cpu_id");
2235074e1d5SCristian Dumitrescu 		return;
2245074e1d5SCristian Dumitrescu 	}
2255074e1d5SCristian Dumitrescu 
2265074e1d5SCristian Dumitrescu 	mempool = mempool_create(obj, name, &p);
2275074e1d5SCristian Dumitrescu 	if (mempool == NULL) {
2285074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
2295074e1d5SCristian Dumitrescu 		return;
2305074e1d5SCristian Dumitrescu 	}
2315074e1d5SCristian Dumitrescu }
2325074e1d5SCristian Dumitrescu 
2335074e1d5SCristian Dumitrescu static const char cmd_link_help[] =
2345074e1d5SCristian Dumitrescu "link <link_name>\n"
2355074e1d5SCristian Dumitrescu "   dev <device_name> | port <port_id>\n"
2365074e1d5SCristian Dumitrescu "   rxq <n_queues> <queue_size> <mempool_name>\n"
2375074e1d5SCristian Dumitrescu "   txq <n_queues> <queue_size>\n"
2385074e1d5SCristian Dumitrescu "   promiscuous on | off\n"
2395074e1d5SCristian Dumitrescu "   [rss <qid_0> ... <qid_n>]\n";
2405074e1d5SCristian Dumitrescu 
2415074e1d5SCristian Dumitrescu static void
2425074e1d5SCristian Dumitrescu cmd_link(char **tokens,
2435074e1d5SCristian Dumitrescu 	uint32_t n_tokens,
2445074e1d5SCristian Dumitrescu 	char *out,
2455074e1d5SCristian Dumitrescu 	size_t out_size,
2465074e1d5SCristian Dumitrescu 	void *obj)
2475074e1d5SCristian Dumitrescu {
2485074e1d5SCristian Dumitrescu 	struct link_params p;
2495074e1d5SCristian Dumitrescu 	struct link_params_rss rss;
2505074e1d5SCristian Dumitrescu 	struct link *link;
2515074e1d5SCristian Dumitrescu 	char *name;
2525074e1d5SCristian Dumitrescu 
2535074e1d5SCristian Dumitrescu 	memset(&p, 0, sizeof(p));
2545074e1d5SCristian Dumitrescu 
2555074e1d5SCristian Dumitrescu 	if ((n_tokens < 13) || (n_tokens > 14 + LINK_RXQ_RSS_MAX)) {
2565074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2575074e1d5SCristian Dumitrescu 		return;
2585074e1d5SCristian Dumitrescu 	}
2595074e1d5SCristian Dumitrescu 	name = tokens[1];
2605074e1d5SCristian Dumitrescu 
2615074e1d5SCristian Dumitrescu 	if (strcmp(tokens[2], "dev") == 0)
2625074e1d5SCristian Dumitrescu 		p.dev_name = tokens[3];
2635074e1d5SCristian Dumitrescu 	else if (strcmp(tokens[2], "port") == 0) {
2645074e1d5SCristian Dumitrescu 		p.dev_name = NULL;
2655074e1d5SCristian Dumitrescu 
2665074e1d5SCristian Dumitrescu 		if (parser_read_uint16(&p.port_id, tokens[3]) != 0) {
2675074e1d5SCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
2685074e1d5SCristian Dumitrescu 			return;
2695074e1d5SCristian Dumitrescu 		}
2705074e1d5SCristian Dumitrescu 	} else {
2715074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "dev or port");
2725074e1d5SCristian Dumitrescu 		return;
2735074e1d5SCristian Dumitrescu 	}
2745074e1d5SCristian Dumitrescu 
2755074e1d5SCristian Dumitrescu 	if (strcmp(tokens[4], "rxq") != 0) {
2765074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rxq");
2775074e1d5SCristian Dumitrescu 		return;
2785074e1d5SCristian Dumitrescu 	}
2795074e1d5SCristian Dumitrescu 
2805074e1d5SCristian Dumitrescu 	if (parser_read_uint32(&p.rx.n_queues, tokens[5]) != 0) {
2815074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "n_queues");
2825074e1d5SCristian Dumitrescu 		return;
2835074e1d5SCristian Dumitrescu 	}
2845074e1d5SCristian Dumitrescu 	if (parser_read_uint32(&p.rx.queue_size, tokens[6]) != 0) {
2855074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "queue_size");
2865074e1d5SCristian Dumitrescu 		return;
2875074e1d5SCristian Dumitrescu 	}
2885074e1d5SCristian Dumitrescu 
2895074e1d5SCristian Dumitrescu 	p.rx.mempool_name = tokens[7];
2905074e1d5SCristian Dumitrescu 
2915074e1d5SCristian Dumitrescu 	if (strcmp(tokens[8], "txq") != 0) {
2925074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "txq");
2935074e1d5SCristian Dumitrescu 		return;
2945074e1d5SCristian Dumitrescu 	}
2955074e1d5SCristian Dumitrescu 
2965074e1d5SCristian Dumitrescu 	if (parser_read_uint32(&p.tx.n_queues, tokens[9]) != 0) {
2975074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "n_queues");
2985074e1d5SCristian Dumitrescu 		return;
2995074e1d5SCristian Dumitrescu 	}
3005074e1d5SCristian Dumitrescu 
3015074e1d5SCristian Dumitrescu 	if (parser_read_uint32(&p.tx.queue_size, tokens[10]) != 0) {
3025074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "queue_size");
3035074e1d5SCristian Dumitrescu 		return;
3045074e1d5SCristian Dumitrescu 	}
3055074e1d5SCristian Dumitrescu 
3065074e1d5SCristian Dumitrescu 	if (strcmp(tokens[11], "promiscuous") != 0) {
3075074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "promiscuous");
3085074e1d5SCristian Dumitrescu 		return;
3095074e1d5SCristian Dumitrescu 	}
3105074e1d5SCristian Dumitrescu 
3115074e1d5SCristian Dumitrescu 	if (strcmp(tokens[12], "on") == 0)
3125074e1d5SCristian Dumitrescu 		p.promiscuous = 1;
3135074e1d5SCristian Dumitrescu 	else if (strcmp(tokens[12], "off") == 0)
3145074e1d5SCristian Dumitrescu 		p.promiscuous = 0;
3155074e1d5SCristian Dumitrescu 	else {
3165074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "on or off");
3175074e1d5SCristian Dumitrescu 		return;
3185074e1d5SCristian Dumitrescu 	}
3195074e1d5SCristian Dumitrescu 
3205074e1d5SCristian Dumitrescu 	/* RSS */
3215074e1d5SCristian Dumitrescu 	p.rx.rss = NULL;
3225074e1d5SCristian Dumitrescu 	if (n_tokens > 13) {
3235074e1d5SCristian Dumitrescu 		uint32_t queue_id, i;
3245074e1d5SCristian Dumitrescu 
3255074e1d5SCristian Dumitrescu 		if (strcmp(tokens[13], "rss") != 0) {
3265074e1d5SCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rss");
3275074e1d5SCristian Dumitrescu 			return;
3285074e1d5SCristian Dumitrescu 		}
3295074e1d5SCristian Dumitrescu 
3305074e1d5SCristian Dumitrescu 		p.rx.rss = &rss;
3315074e1d5SCristian Dumitrescu 
3325074e1d5SCristian Dumitrescu 		rss.n_queues = 0;
3335074e1d5SCristian Dumitrescu 		for (i = 14; i < n_tokens; i++) {
3345074e1d5SCristian Dumitrescu 			if (parser_read_uint32(&queue_id, tokens[i]) != 0) {
3355074e1d5SCristian Dumitrescu 				snprintf(out, out_size, MSG_ARG_INVALID,
3365074e1d5SCristian Dumitrescu 					"queue_id");
3375074e1d5SCristian Dumitrescu 				return;
3385074e1d5SCristian Dumitrescu 			}
3395074e1d5SCristian Dumitrescu 
3405074e1d5SCristian Dumitrescu 			rss.queue_id[rss.n_queues] = queue_id;
3415074e1d5SCristian Dumitrescu 			rss.n_queues++;
3425074e1d5SCristian Dumitrescu 		}
3435074e1d5SCristian Dumitrescu 	}
3445074e1d5SCristian Dumitrescu 
3455074e1d5SCristian Dumitrescu 	link = link_create(obj, name, &p);
3465074e1d5SCristian Dumitrescu 	if (link == NULL) {
3475074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
3485074e1d5SCristian Dumitrescu 		return;
3495074e1d5SCristian Dumitrescu 	}
3505074e1d5SCristian Dumitrescu }
3515074e1d5SCristian Dumitrescu 
3525074e1d5SCristian Dumitrescu /* Print the link stats and info */
3535074e1d5SCristian Dumitrescu static void
3545074e1d5SCristian Dumitrescu print_link_info(struct link *link, char *out, size_t out_size)
3555074e1d5SCristian Dumitrescu {
3565074e1d5SCristian Dumitrescu 	struct rte_eth_stats stats;
3575074e1d5SCristian Dumitrescu 	struct rte_ether_addr mac_addr;
3585074e1d5SCristian Dumitrescu 	struct rte_eth_link eth_link;
3595074e1d5SCristian Dumitrescu 	uint16_t mtu;
3605074e1d5SCristian Dumitrescu 	int ret;
3615074e1d5SCristian Dumitrescu 
3625074e1d5SCristian Dumitrescu 	memset(&stats, 0, sizeof(stats));
3635074e1d5SCristian Dumitrescu 	rte_eth_stats_get(link->port_id, &stats);
3645074e1d5SCristian Dumitrescu 
3655074e1d5SCristian Dumitrescu 	ret = rte_eth_macaddr_get(link->port_id, &mac_addr);
3665074e1d5SCristian Dumitrescu 	if (ret != 0) {
3675074e1d5SCristian Dumitrescu 		snprintf(out, out_size, "\n%s: MAC address get failed: %s",
3685074e1d5SCristian Dumitrescu 			 link->name, rte_strerror(-ret));
3695074e1d5SCristian Dumitrescu 		return;
3705074e1d5SCristian Dumitrescu 	}
3715074e1d5SCristian Dumitrescu 
3725074e1d5SCristian Dumitrescu 	ret = rte_eth_link_get(link->port_id, &eth_link);
3735074e1d5SCristian Dumitrescu 	if (ret < 0) {
3745074e1d5SCristian Dumitrescu 		snprintf(out, out_size, "\n%s: link get failed: %s",
3755074e1d5SCristian Dumitrescu 			 link->name, rte_strerror(-ret));
3765074e1d5SCristian Dumitrescu 		return;
3775074e1d5SCristian Dumitrescu 	}
3785074e1d5SCristian Dumitrescu 
3795074e1d5SCristian Dumitrescu 	rte_eth_dev_get_mtu(link->port_id, &mtu);
3805074e1d5SCristian Dumitrescu 
3815074e1d5SCristian Dumitrescu 	snprintf(out, out_size,
3825074e1d5SCristian Dumitrescu 		"\n"
3835074e1d5SCristian Dumitrescu 		"%s: flags=<%s> mtu %u\n"
384c2c4f87bSAman Deep Singh 		"\tether " RTE_ETHER_ADDR_PRT_FMT " rxqueues %u txqueues %u\n"
3855074e1d5SCristian Dumitrescu 		"\tport# %u  speed %s\n"
3865074e1d5SCristian Dumitrescu 		"\tRX packets %" PRIu64"  bytes %" PRIu64"\n"
3875074e1d5SCristian Dumitrescu 		"\tRX errors %" PRIu64"  missed %" PRIu64"  no-mbuf %" PRIu64"\n"
3885074e1d5SCristian Dumitrescu 		"\tTX packets %" PRIu64"  bytes %" PRIu64"\n"
3895074e1d5SCristian Dumitrescu 		"\tTX errors %" PRIu64"\n",
3905074e1d5SCristian Dumitrescu 		link->name,
3915074e1d5SCristian Dumitrescu 		eth_link.link_status == 0 ? "DOWN" : "UP",
3925074e1d5SCristian Dumitrescu 		mtu,
393a7db3afcSAman Deep Singh 		RTE_ETHER_ADDR_BYTES(&mac_addr),
3945074e1d5SCristian Dumitrescu 		link->n_rxq,
3955074e1d5SCristian Dumitrescu 		link->n_txq,
3965074e1d5SCristian Dumitrescu 		link->port_id,
3975074e1d5SCristian Dumitrescu 		rte_eth_link_speed_to_str(eth_link.link_speed),
3985074e1d5SCristian Dumitrescu 		stats.ipackets,
3995074e1d5SCristian Dumitrescu 		stats.ibytes,
4005074e1d5SCristian Dumitrescu 		stats.ierrors,
4015074e1d5SCristian Dumitrescu 		stats.imissed,
4025074e1d5SCristian Dumitrescu 		stats.rx_nombuf,
4035074e1d5SCristian Dumitrescu 		stats.opackets,
4045074e1d5SCristian Dumitrescu 		stats.obytes,
4055074e1d5SCristian Dumitrescu 		stats.oerrors);
4065074e1d5SCristian Dumitrescu }
4075074e1d5SCristian Dumitrescu 
4085074e1d5SCristian Dumitrescu /*
4095074e1d5SCristian Dumitrescu  * link show [<link_name>]
4105074e1d5SCristian Dumitrescu  */
4115074e1d5SCristian Dumitrescu static void
4125074e1d5SCristian Dumitrescu cmd_link_show(char **tokens,
4135074e1d5SCristian Dumitrescu 	      uint32_t n_tokens,
4145074e1d5SCristian Dumitrescu 	      char *out,
4155074e1d5SCristian Dumitrescu 	      size_t out_size,
4165074e1d5SCristian Dumitrescu 	      void *obj)
4175074e1d5SCristian Dumitrescu {
4185074e1d5SCristian Dumitrescu 	struct link *link;
4195074e1d5SCristian Dumitrescu 	char *link_name;
4205074e1d5SCristian Dumitrescu 
4215074e1d5SCristian Dumitrescu 	if (n_tokens != 2 && n_tokens != 3) {
4225074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
4235074e1d5SCristian Dumitrescu 		return;
4245074e1d5SCristian Dumitrescu 	}
4255074e1d5SCristian Dumitrescu 
4265074e1d5SCristian Dumitrescu 	if (n_tokens == 2) {
4275074e1d5SCristian Dumitrescu 		link = link_next(obj, NULL);
4285074e1d5SCristian Dumitrescu 
4295074e1d5SCristian Dumitrescu 		while (link != NULL) {
4305074e1d5SCristian Dumitrescu 			out_size = out_size - strlen(out);
4315074e1d5SCristian Dumitrescu 			out = &out[strlen(out)];
4325074e1d5SCristian Dumitrescu 
4335074e1d5SCristian Dumitrescu 			print_link_info(link, out, out_size);
4345074e1d5SCristian Dumitrescu 			link = link_next(obj, link);
4355074e1d5SCristian Dumitrescu 		}
4365074e1d5SCristian Dumitrescu 	} else {
4375074e1d5SCristian Dumitrescu 		out_size = out_size - strlen(out);
4385074e1d5SCristian Dumitrescu 		out = &out[strlen(out)];
4395074e1d5SCristian Dumitrescu 
4405074e1d5SCristian Dumitrescu 		link_name = tokens[2];
4415074e1d5SCristian Dumitrescu 		link = link_find(obj, link_name);
4425074e1d5SCristian Dumitrescu 
4435074e1d5SCristian Dumitrescu 		if (link == NULL) {
4445074e1d5SCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_INVALID,
4455074e1d5SCristian Dumitrescu 					"Link does not exist");
4465074e1d5SCristian Dumitrescu 			return;
4475074e1d5SCristian Dumitrescu 		}
4485074e1d5SCristian Dumitrescu 		print_link_info(link, out, out_size);
4495074e1d5SCristian Dumitrescu 	}
4505074e1d5SCristian Dumitrescu }
4515074e1d5SCristian Dumitrescu 
45277a41301SCristian Dumitrescu static const char cmd_ring_help[] =
45377a41301SCristian Dumitrescu "ring <ring_name> size <size> numa <numa_node>\n";
45477a41301SCristian Dumitrescu 
45577a41301SCristian Dumitrescu static void
45677a41301SCristian Dumitrescu cmd_ring(char **tokens,
45777a41301SCristian Dumitrescu 	uint32_t n_tokens,
45877a41301SCristian Dumitrescu 	char *out,
45977a41301SCristian Dumitrescu 	size_t out_size,
46077a41301SCristian Dumitrescu 	void *obj)
46177a41301SCristian Dumitrescu {
46277a41301SCristian Dumitrescu 	struct ring_params p;
46377a41301SCristian Dumitrescu 	char *name;
46477a41301SCristian Dumitrescu 	struct ring *ring;
46577a41301SCristian Dumitrescu 
46677a41301SCristian Dumitrescu 	if (n_tokens != 6) {
46777a41301SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
46877a41301SCristian Dumitrescu 		return;
46977a41301SCristian Dumitrescu 	}
47077a41301SCristian Dumitrescu 
47177a41301SCristian Dumitrescu 	name = tokens[1];
47277a41301SCristian Dumitrescu 
47377a41301SCristian Dumitrescu 	if (strcmp(tokens[2], "size") != 0) {
47477a41301SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "size");
47577a41301SCristian Dumitrescu 		return;
47677a41301SCristian Dumitrescu 	}
47777a41301SCristian Dumitrescu 
47877a41301SCristian Dumitrescu 	if (parser_read_uint32(&p.size, tokens[3]) != 0) {
47977a41301SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "size");
48077a41301SCristian Dumitrescu 		return;
48177a41301SCristian Dumitrescu 	}
48277a41301SCristian Dumitrescu 
48377a41301SCristian Dumitrescu 	if (strcmp(tokens[4], "numa") != 0) {
48477a41301SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "numa");
48577a41301SCristian Dumitrescu 		return;
48677a41301SCristian Dumitrescu 	}
48777a41301SCristian Dumitrescu 
48877a41301SCristian Dumitrescu 	if (parser_read_uint32(&p.numa_node, tokens[5]) != 0) {
48977a41301SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "numa_node");
49077a41301SCristian Dumitrescu 		return;
49177a41301SCristian Dumitrescu 	}
49277a41301SCristian Dumitrescu 
49377a41301SCristian Dumitrescu 	ring = ring_create(obj, name, &p);
49477a41301SCristian Dumitrescu 	if (!ring) {
49577a41301SCristian Dumitrescu 		snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
49677a41301SCristian Dumitrescu 		return;
49777a41301SCristian Dumitrescu 	}
49877a41301SCristian Dumitrescu }
49977a41301SCristian Dumitrescu 
500e2b8dc52SVenkata Suresh Kumar P static const char cmd_tap_help[] =
501e2b8dc52SVenkata Suresh Kumar P "tap <tap_name>\n";
502e2b8dc52SVenkata Suresh Kumar P 
503e2b8dc52SVenkata Suresh Kumar P static void
504e2b8dc52SVenkata Suresh Kumar P cmd_tap(char **tokens,
505e2b8dc52SVenkata Suresh Kumar P 	uint32_t n_tokens,
506e2b8dc52SVenkata Suresh Kumar P 	char *out,
507e2b8dc52SVenkata Suresh Kumar P 	size_t out_size,
508e2b8dc52SVenkata Suresh Kumar P 	void *obj)
509e2b8dc52SVenkata Suresh Kumar P {
510e2b8dc52SVenkata Suresh Kumar P 	struct tap *tap;
511e2b8dc52SVenkata Suresh Kumar P 	char *name;
512e2b8dc52SVenkata Suresh Kumar P 
513e2b8dc52SVenkata Suresh Kumar P 	if (n_tokens < 2) {
514e2b8dc52SVenkata Suresh Kumar P 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
515e2b8dc52SVenkata Suresh Kumar P 		return;
516e2b8dc52SVenkata Suresh Kumar P 	}
517e2b8dc52SVenkata Suresh Kumar P 	name = tokens[1];
518e2b8dc52SVenkata Suresh Kumar P 
519e2b8dc52SVenkata Suresh Kumar P 	tap = tap_create(obj, name);
520e2b8dc52SVenkata Suresh Kumar P 	if (tap == NULL) {
521e2b8dc52SVenkata Suresh Kumar P 		snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
522e2b8dc52SVenkata Suresh Kumar P 		return;
523e2b8dc52SVenkata Suresh Kumar P 	}
524e2b8dc52SVenkata Suresh Kumar P }
525e2b8dc52SVenkata Suresh Kumar P 
5269043f66aSCristian Dumitrescu static const char cmd_pipeline_codegen_help[] =
5279043f66aSCristian Dumitrescu "pipeline codegen <spec_file> <code_file>\n";
5289043f66aSCristian Dumitrescu 
5299043f66aSCristian Dumitrescu static void
5309043f66aSCristian Dumitrescu cmd_pipeline_codegen(char **tokens,
5319043f66aSCristian Dumitrescu 	uint32_t n_tokens,
5329043f66aSCristian Dumitrescu 	char *out,
5339043f66aSCristian Dumitrescu 	size_t out_size,
5349043f66aSCristian Dumitrescu 	void *obj __rte_unused)
5359043f66aSCristian Dumitrescu {
5369043f66aSCristian Dumitrescu 	FILE *spec_file = NULL;
5379043f66aSCristian Dumitrescu 	FILE *code_file = NULL;
5389043f66aSCristian Dumitrescu 	uint32_t err_line;
5399043f66aSCristian Dumitrescu 	const char *err_msg;
5409043f66aSCristian Dumitrescu 	int status;
5419043f66aSCristian Dumitrescu 
5429043f66aSCristian Dumitrescu 	if (n_tokens != 4) {
5439043f66aSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
5449043f66aSCristian Dumitrescu 		return;
5459043f66aSCristian Dumitrescu 	}
5469043f66aSCristian Dumitrescu 
5479043f66aSCristian Dumitrescu 	spec_file = fopen(tokens[2], "r");
5489043f66aSCristian Dumitrescu 	if (!spec_file) {
5499043f66aSCristian Dumitrescu 		snprintf(out, out_size, "Cannot open file %s.\n", tokens[2]);
5509043f66aSCristian Dumitrescu 		return;
5519043f66aSCristian Dumitrescu 	}
5529043f66aSCristian Dumitrescu 
5539043f66aSCristian Dumitrescu 	code_file = fopen(tokens[3], "w");
5549043f66aSCristian Dumitrescu 	if (!code_file) {
5559043f66aSCristian Dumitrescu 		snprintf(out, out_size, "Cannot open file %s.\n", tokens[3]);
5569043f66aSCristian Dumitrescu 		return;
5579043f66aSCristian Dumitrescu 	}
5589043f66aSCristian Dumitrescu 
5599043f66aSCristian Dumitrescu 	status = rte_swx_pipeline_codegen(spec_file,
5609043f66aSCristian Dumitrescu 					  code_file,
5619043f66aSCristian Dumitrescu 					  &err_line,
5629043f66aSCristian Dumitrescu 					  &err_msg);
5639043f66aSCristian Dumitrescu 
5649043f66aSCristian Dumitrescu 	fclose(spec_file);
5659043f66aSCristian Dumitrescu 	fclose(code_file);
5669043f66aSCristian Dumitrescu 
5679043f66aSCristian Dumitrescu 	if (status) {
5689043f66aSCristian Dumitrescu 		snprintf(out, out_size, "Error %d at line %u: %s\n.",
5699043f66aSCristian Dumitrescu 			status, err_line, err_msg);
5709043f66aSCristian Dumitrescu 		return;
5719043f66aSCristian Dumitrescu 	}
5729043f66aSCristian Dumitrescu }
5736bc14d9fSCristian Dumitrescu 
5746bc14d9fSCristian Dumitrescu static const char cmd_pipeline_libbuild_help[] =
5756bc14d9fSCristian Dumitrescu "pipeline libbuild <code_file> <lib_file>\n";
5766bc14d9fSCristian Dumitrescu 
5776bc14d9fSCristian Dumitrescu static void
5786bc14d9fSCristian Dumitrescu cmd_pipeline_libbuild(char **tokens,
5796bc14d9fSCristian Dumitrescu 	uint32_t n_tokens,
5806bc14d9fSCristian Dumitrescu 	char *out,
5816bc14d9fSCristian Dumitrescu 	size_t out_size,
5826bc14d9fSCristian Dumitrescu 	void *obj __rte_unused)
5836bc14d9fSCristian Dumitrescu {
5846bc14d9fSCristian Dumitrescu 	char *code_file, *lib_file, *obj_file = NULL, *log_file = NULL;
5856bc14d9fSCristian Dumitrescu 	char *install_dir, *cwd = NULL, *buffer = NULL;
5866bc14d9fSCristian Dumitrescu 	size_t length;
5876bc14d9fSCristian Dumitrescu 	int status = 0;
5886bc14d9fSCristian Dumitrescu 
5896bc14d9fSCristian Dumitrescu 	if (n_tokens != 4) {
5906bc14d9fSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
5916bc14d9fSCristian Dumitrescu 		goto free;
5926bc14d9fSCristian Dumitrescu 	}
5936bc14d9fSCristian Dumitrescu 
5946bc14d9fSCristian Dumitrescu 	install_dir = getenv("RTE_INSTALL_DIR");
5956bc14d9fSCristian Dumitrescu 	if (!install_dir) {
5966bc14d9fSCristian Dumitrescu 		cwd = malloc(MAX_LINE_SIZE);
5976bc14d9fSCristian Dumitrescu 		if (!cwd) {
5986bc14d9fSCristian Dumitrescu 			snprintf(out, out_size, MSG_OUT_OF_MEMORY);
5996bc14d9fSCristian Dumitrescu 			goto free;
6006bc14d9fSCristian Dumitrescu 		}
6016bc14d9fSCristian Dumitrescu 
6026bc14d9fSCristian Dumitrescu 		install_dir = getcwd(cwd, MAX_LINE_SIZE);
6036bc14d9fSCristian Dumitrescu 		if (!install_dir) {
6046bc14d9fSCristian Dumitrescu 			snprintf(out, out_size, "Error: Path too long.\n");
6056bc14d9fSCristian Dumitrescu 			goto free;
6066bc14d9fSCristian Dumitrescu 		}
6076bc14d9fSCristian Dumitrescu 	}
6086bc14d9fSCristian Dumitrescu 
6096bc14d9fSCristian Dumitrescu 	snprintf(out, out_size, "Using DPDK source code from \"%s\".\n", install_dir);
6106bc14d9fSCristian Dumitrescu 	out_size -= strlen(out);
6116bc14d9fSCristian Dumitrescu 	out += strlen(out);
6126bc14d9fSCristian Dumitrescu 
6136bc14d9fSCristian Dumitrescu 	code_file = tokens[2];
6146bc14d9fSCristian Dumitrescu 	length = strnlen(code_file, MAX_LINE_SIZE);
6156bc14d9fSCristian Dumitrescu 	if ((length < 3) ||
6166bc14d9fSCristian Dumitrescu 	    (code_file[length - 2] != '.') ||
6176bc14d9fSCristian Dumitrescu 	    (code_file[length - 1] != 'c')) {
6186bc14d9fSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "code_file");
6196bc14d9fSCristian Dumitrescu 		goto free;
6206bc14d9fSCristian Dumitrescu 	}
6216bc14d9fSCristian Dumitrescu 
6226bc14d9fSCristian Dumitrescu 	lib_file = tokens[3];
6236bc14d9fSCristian Dumitrescu 	length = strnlen(lib_file, MAX_LINE_SIZE);
6246bc14d9fSCristian Dumitrescu 	if ((length < 4) ||
6256bc14d9fSCristian Dumitrescu 	    (lib_file[length - 3] != '.') ||
6266bc14d9fSCristian Dumitrescu 	    (lib_file[length - 2] != 's') ||
6276bc14d9fSCristian Dumitrescu 	    (lib_file[length - 1] != 'o')) {
6286bc14d9fSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "lib_file");
6296bc14d9fSCristian Dumitrescu 		goto free;
6306bc14d9fSCristian Dumitrescu 	}
6316bc14d9fSCristian Dumitrescu 
6326bc14d9fSCristian Dumitrescu 	obj_file = malloc(length);
6336bc14d9fSCristian Dumitrescu 	log_file = malloc(length + 2);
6346bc14d9fSCristian Dumitrescu 	if (!obj_file || !log_file) {
6356bc14d9fSCristian Dumitrescu 		snprintf(out, out_size, MSG_OUT_OF_MEMORY);
6366bc14d9fSCristian Dumitrescu 		goto free;
6376bc14d9fSCristian Dumitrescu 	}
6386bc14d9fSCristian Dumitrescu 
6396bc14d9fSCristian Dumitrescu 	memcpy(obj_file, lib_file, length - 2);
6406bc14d9fSCristian Dumitrescu 	obj_file[length - 2] = 'o';
6416bc14d9fSCristian Dumitrescu 	obj_file[length - 1] = 0;
6426bc14d9fSCristian Dumitrescu 
6436bc14d9fSCristian Dumitrescu 	memcpy(log_file, lib_file, length - 2);
6446bc14d9fSCristian Dumitrescu 	log_file[length - 2] = 'l';
6456bc14d9fSCristian Dumitrescu 	log_file[length - 1] = 'o';
6466bc14d9fSCristian Dumitrescu 	log_file[length] = 'g';
6476bc14d9fSCristian Dumitrescu 	log_file[length + 1] = 0;
6486bc14d9fSCristian Dumitrescu 
6496bc14d9fSCristian Dumitrescu 	buffer = malloc(MAX_LINE_SIZE);
6506bc14d9fSCristian Dumitrescu 	if (!buffer) {
6516bc14d9fSCristian Dumitrescu 		snprintf(out, out_size, MSG_OUT_OF_MEMORY);
6526bc14d9fSCristian Dumitrescu 		return;
6536bc14d9fSCristian Dumitrescu 	}
6546bc14d9fSCristian Dumitrescu 
6556bc14d9fSCristian Dumitrescu 	snprintf(buffer,
6566bc14d9fSCristian Dumitrescu 		 MAX_LINE_SIZE,
6576bc14d9fSCristian Dumitrescu 		 "gcc -c -O3 -fpic -Wno-deprecated-declarations -o %s %s "
6586bc14d9fSCristian Dumitrescu 		 "-I %s/lib/pipeline "
6596bc14d9fSCristian Dumitrescu 		 "-I %s/lib/eal/include "
6606bc14d9fSCristian Dumitrescu 		 "-I %s/lib/eal/x86/include "
6616bc14d9fSCristian Dumitrescu 		 "-I %s/lib/eal/include/generic "
6626bc14d9fSCristian Dumitrescu 		 "-I %s/lib/meter "
6636bc14d9fSCristian Dumitrescu 		 "-I %s/lib/port "
6646bc14d9fSCristian Dumitrescu 		 "-I %s/lib/table "
6656bc14d9fSCristian Dumitrescu 		 "-I %s/lib/pipeline "
6666bc14d9fSCristian Dumitrescu 		 "-I %s/config "
6676bc14d9fSCristian Dumitrescu 		 "-I %s/build "
6686bc14d9fSCristian Dumitrescu 		 "-I %s/lib/eal/linux/include "
6696bc14d9fSCristian Dumitrescu 		 ">%s 2>&1 "
6706bc14d9fSCristian Dumitrescu 		 "&& "
6716bc14d9fSCristian Dumitrescu 		 "gcc -shared %s -o %s "
6726bc14d9fSCristian Dumitrescu 		 ">>%s 2>&1",
6736bc14d9fSCristian Dumitrescu 		 obj_file,
6746bc14d9fSCristian Dumitrescu 		 code_file,
6756bc14d9fSCristian Dumitrescu 		 install_dir,
6766bc14d9fSCristian Dumitrescu 		 install_dir,
6776bc14d9fSCristian Dumitrescu 		 install_dir,
6786bc14d9fSCristian Dumitrescu 		 install_dir,
6796bc14d9fSCristian Dumitrescu 		 install_dir,
6806bc14d9fSCristian Dumitrescu 		 install_dir,
6816bc14d9fSCristian Dumitrescu 		 install_dir,
6826bc14d9fSCristian Dumitrescu 		 install_dir,
6836bc14d9fSCristian Dumitrescu 		 install_dir,
6846bc14d9fSCristian Dumitrescu 		 install_dir,
6856bc14d9fSCristian Dumitrescu 		 install_dir,
6866bc14d9fSCristian Dumitrescu 		 log_file,
6876bc14d9fSCristian Dumitrescu 		 obj_file,
6886bc14d9fSCristian Dumitrescu 		 lib_file,
6896bc14d9fSCristian Dumitrescu 		 log_file);
6906bc14d9fSCristian Dumitrescu 
6916bc14d9fSCristian Dumitrescu 	status = system(buffer);
6926bc14d9fSCristian Dumitrescu 	if (status) {
6936bc14d9fSCristian Dumitrescu 		snprintf(out,
6946bc14d9fSCristian Dumitrescu 			 out_size,
6956bc14d9fSCristian Dumitrescu 			 "Library build failed, see file \"%s\" for details.\n",
6966bc14d9fSCristian Dumitrescu 			 log_file);
6976bc14d9fSCristian Dumitrescu 		goto free;
6986bc14d9fSCristian Dumitrescu 	}
6996bc14d9fSCristian Dumitrescu 
7006bc14d9fSCristian Dumitrescu free:
7016bc14d9fSCristian Dumitrescu 	free(cwd);
7026bc14d9fSCristian Dumitrescu 	free(obj_file);
7036bc14d9fSCristian Dumitrescu 	free(log_file);
7046bc14d9fSCristian Dumitrescu 	free(buffer);
7056bc14d9fSCristian Dumitrescu }
7066bc14d9fSCristian Dumitrescu 
7075074e1d5SCristian Dumitrescu static const char cmd_pipeline_build_help[] =
70868b95704SCristian Dumitrescu "pipeline <pipeline_name> build lib <lib_file> io <iospec_file> numa <numa_node>\n";
7095074e1d5SCristian Dumitrescu 
7105074e1d5SCristian Dumitrescu static void
7115074e1d5SCristian Dumitrescu cmd_pipeline_build(char **tokens,
7125074e1d5SCristian Dumitrescu 	uint32_t n_tokens,
7135074e1d5SCristian Dumitrescu 	char *out,
7145074e1d5SCristian Dumitrescu 	size_t out_size,
71568b95704SCristian Dumitrescu 	void *obj __rte_unused)
7165074e1d5SCristian Dumitrescu {
71768b95704SCristian Dumitrescu 	struct rte_swx_pipeline *p = NULL;
71868b95704SCristian Dumitrescu 	struct rte_swx_ctl_pipeline *ctl = NULL;
71968b95704SCristian Dumitrescu 	char *pipeline_name, *lib_file_name, *iospec_file_name;
72068b95704SCristian Dumitrescu 	FILE *iospec_file = NULL;
72168b95704SCristian Dumitrescu 	uint32_t numa_node = 0;
72268b95704SCristian Dumitrescu 	int status = 0;
7235074e1d5SCristian Dumitrescu 
72468b95704SCristian Dumitrescu 	/* Parsing. */
72568b95704SCristian Dumitrescu 	if (n_tokens != 9) {
7265074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
7275074e1d5SCristian Dumitrescu 		return;
7285074e1d5SCristian Dumitrescu 	}
7295074e1d5SCristian Dumitrescu 
73068b95704SCristian Dumitrescu 	pipeline_name = tokens[1];
73168b95704SCristian Dumitrescu 
73268b95704SCristian Dumitrescu 	if (strcmp(tokens[2], "build")) {
73368b95704SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "build");
7345074e1d5SCristian Dumitrescu 		return;
7355074e1d5SCristian Dumitrescu 	}
7365074e1d5SCristian Dumitrescu 
73768b95704SCristian Dumitrescu 	if (strcmp(tokens[3], "lib")) {
73868b95704SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "lib");
7395074e1d5SCristian Dumitrescu 		return;
7405074e1d5SCristian Dumitrescu 	}
7415074e1d5SCristian Dumitrescu 
74268b95704SCristian Dumitrescu 	lib_file_name = tokens[4];
74368b95704SCristian Dumitrescu 
74468b95704SCristian Dumitrescu 	if (strcmp(tokens[5], "io")) {
74568b95704SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "io");
74668b95704SCristian Dumitrescu 		return;
74768b95704SCristian Dumitrescu 	}
74868b95704SCristian Dumitrescu 
74968b95704SCristian Dumitrescu 	iospec_file_name = tokens[6];
75068b95704SCristian Dumitrescu 
75168b95704SCristian Dumitrescu 	if (strcmp(tokens[7], "numa")) {
75268b95704SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "numa");
75368b95704SCristian Dumitrescu 		return;
75468b95704SCristian Dumitrescu 	}
75568b95704SCristian Dumitrescu 
75668b95704SCristian Dumitrescu 	if (parser_read_uint32(&numa_node, tokens[8])) {
75768b95704SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "numa_node");
75868b95704SCristian Dumitrescu 		return;
75968b95704SCristian Dumitrescu 	}
76068b95704SCristian Dumitrescu 
76168b95704SCristian Dumitrescu 	/* I/O spec file open. */
76268b95704SCristian Dumitrescu 	iospec_file = fopen(iospec_file_name, "r");
76368b95704SCristian Dumitrescu 	if (!iospec_file) {
76468b95704SCristian Dumitrescu 		snprintf(out, out_size, "Cannot open file \"%s\".\n", iospec_file_name);
76568b95704SCristian Dumitrescu 		return;
76668b95704SCristian Dumitrescu 	}
76768b95704SCristian Dumitrescu 
76868b95704SCristian Dumitrescu 	status = rte_swx_pipeline_build_from_lib(&p,
76968b95704SCristian Dumitrescu 						 pipeline_name,
77068b95704SCristian Dumitrescu 						 lib_file_name,
77168b95704SCristian Dumitrescu 						 iospec_file,
77268b95704SCristian Dumitrescu 						 (int)numa_node);
7735074e1d5SCristian Dumitrescu 	if (status) {
77468b95704SCristian Dumitrescu 		snprintf(out, out_size, "Pipeline build failed (%d).", status);
77568b95704SCristian Dumitrescu 		goto free;
7765074e1d5SCristian Dumitrescu 	}
7775074e1d5SCristian Dumitrescu 
77868b95704SCristian Dumitrescu 	ctl = rte_swx_ctl_pipeline_create(p);
77968b95704SCristian Dumitrescu 	if (!ctl) {
7805074e1d5SCristian Dumitrescu 		snprintf(out, out_size, "Pipeline control create failed.");
78168b95704SCristian Dumitrescu 		goto free;
7825074e1d5SCristian Dumitrescu 	}
78368b95704SCristian Dumitrescu 
78468b95704SCristian Dumitrescu free:
78568b95704SCristian Dumitrescu 	if (status)
78668b95704SCristian Dumitrescu 		rte_swx_pipeline_free(p);
78768b95704SCristian Dumitrescu 
78868b95704SCristian Dumitrescu 	if (iospec_file)
78968b95704SCristian Dumitrescu 		fclose(iospec_file);
7905074e1d5SCristian Dumitrescu }
7915074e1d5SCristian Dumitrescu 
792275ebefeSCristian Dumitrescu static void
793275ebefeSCristian Dumitrescu table_entry_free(struct rte_swx_table_entry *entry)
794275ebefeSCristian Dumitrescu {
795275ebefeSCristian Dumitrescu 	if (!entry)
796275ebefeSCristian Dumitrescu 		return;
797275ebefeSCristian Dumitrescu 
798275ebefeSCristian Dumitrescu 	free(entry->key);
799275ebefeSCristian Dumitrescu 	free(entry->key_mask);
800275ebefeSCristian Dumitrescu 	free(entry->action_data);
801275ebefeSCristian Dumitrescu 	free(entry);
802275ebefeSCristian Dumitrescu }
803275ebefeSCristian Dumitrescu 
80475129cebSChurchill Khangar static int
80575129cebSChurchill Khangar pipeline_table_entries_add(struct rte_swx_ctl_pipeline *p,
80675129cebSChurchill Khangar 			   const char *table_name,
80775129cebSChurchill Khangar 			   FILE *file,
80875129cebSChurchill Khangar 			   uint32_t *file_line_number)
80975129cebSChurchill Khangar {
81075129cebSChurchill Khangar 	char *line = NULL;
81175129cebSChurchill Khangar 	uint32_t line_id = 0;
81275129cebSChurchill Khangar 	int status = 0;
81375129cebSChurchill Khangar 
81475129cebSChurchill Khangar 	/* Buffer allocation. */
81575129cebSChurchill Khangar 	line = malloc(MAX_LINE_SIZE);
81675129cebSChurchill Khangar 	if (!line)
81775129cebSChurchill Khangar 		return -ENOMEM;
81875129cebSChurchill Khangar 
81975129cebSChurchill Khangar 	/* File read. */
82075129cebSChurchill Khangar 	for (line_id = 1; ; line_id++) {
82175129cebSChurchill Khangar 		struct rte_swx_table_entry *entry;
82275129cebSChurchill Khangar 		int is_blank_or_comment;
82375129cebSChurchill Khangar 
82475129cebSChurchill Khangar 		if (fgets(line, MAX_LINE_SIZE, file) == NULL)
82575129cebSChurchill Khangar 			break;
82675129cebSChurchill Khangar 
82775129cebSChurchill Khangar 		entry = rte_swx_ctl_pipeline_table_entry_read(p,
82875129cebSChurchill Khangar 							      table_name,
82975129cebSChurchill Khangar 							      line,
83075129cebSChurchill Khangar 							      &is_blank_or_comment);
83175129cebSChurchill Khangar 		if (!entry) {
83275129cebSChurchill Khangar 			if (is_blank_or_comment)
83375129cebSChurchill Khangar 				continue;
83475129cebSChurchill Khangar 
83575129cebSChurchill Khangar 			status = -EINVAL;
83675129cebSChurchill Khangar 			goto error;
83775129cebSChurchill Khangar 		}
83875129cebSChurchill Khangar 
83975129cebSChurchill Khangar 		status = rte_swx_ctl_pipeline_table_entry_add(p,
84075129cebSChurchill Khangar 							      table_name,
84175129cebSChurchill Khangar 							      entry);
84275129cebSChurchill Khangar 		table_entry_free(entry);
84375129cebSChurchill Khangar 		if (status)
84475129cebSChurchill Khangar 			goto error;
84575129cebSChurchill Khangar 	}
84675129cebSChurchill Khangar 
84775129cebSChurchill Khangar error:
84875129cebSChurchill Khangar 	free(line);
84975129cebSChurchill Khangar 	*file_line_number = line_id;
85075129cebSChurchill Khangar 	return status;
85175129cebSChurchill Khangar }
85275129cebSChurchill Khangar 
85375129cebSChurchill Khangar static const char cmd_pipeline_table_add_help[] =
85475129cebSChurchill Khangar "pipeline <pipeline_name> table <table_name> add <file_name>\n";
8555074e1d5SCristian Dumitrescu 
8565074e1d5SCristian Dumitrescu static void
85775129cebSChurchill Khangar cmd_pipeline_table_add(char **tokens,
8585074e1d5SCristian Dumitrescu 		       uint32_t n_tokens,
8595074e1d5SCristian Dumitrescu 		       char *out,
8605074e1d5SCristian Dumitrescu 		       size_t out_size,
861*b9559f94SCristian Dumitrescu 		       void *obj __rte_unused)
8625074e1d5SCristian Dumitrescu {
863*b9559f94SCristian Dumitrescu 	struct rte_swx_ctl_pipeline *ctl;
86475129cebSChurchill Khangar 	char *pipeline_name, *table_name, *file_name;
86575129cebSChurchill Khangar 	FILE *file = NULL;
86675129cebSChurchill Khangar 	uint32_t file_line_number = 0;
8675074e1d5SCristian Dumitrescu 	int status;
8685074e1d5SCristian Dumitrescu 
86975129cebSChurchill Khangar 	if (n_tokens != 6) {
8705074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
8715074e1d5SCristian Dumitrescu 		return;
8725074e1d5SCristian Dumitrescu 	}
8735074e1d5SCristian Dumitrescu 
8745074e1d5SCristian Dumitrescu 	pipeline_name = tokens[1];
875*b9559f94SCristian Dumitrescu 	ctl = rte_swx_ctl_pipeline_find(pipeline_name);
876*b9559f94SCristian Dumitrescu 	if (!ctl) {
8775074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
8785074e1d5SCristian Dumitrescu 		return;
8795074e1d5SCristian Dumitrescu 	}
8805074e1d5SCristian Dumitrescu 
88175129cebSChurchill Khangar 	table_name = tokens[3];
88275129cebSChurchill Khangar 
88375129cebSChurchill Khangar 	file_name = tokens[5];
88475129cebSChurchill Khangar 	file = fopen(file_name, "r");
88575129cebSChurchill Khangar 	if (!file) {
88675129cebSChurchill Khangar 		snprintf(out, out_size, "Cannot open file %s.\n", file_name);
88775129cebSChurchill Khangar 		return;
88875129cebSChurchill Khangar 	}
88975129cebSChurchill Khangar 
890*b9559f94SCristian Dumitrescu 	status = pipeline_table_entries_add(ctl,
89175129cebSChurchill Khangar 					    table_name,
89275129cebSChurchill Khangar 					    file,
89375129cebSChurchill Khangar 					    &file_line_number);
89475129cebSChurchill Khangar 	if (status)
89575129cebSChurchill Khangar 		snprintf(out, out_size, "Invalid entry in file %s at line %u\n",
89675129cebSChurchill Khangar 			 file_name,
89775129cebSChurchill Khangar 			 file_line_number);
89875129cebSChurchill Khangar 
89975129cebSChurchill Khangar 	fclose(file);
90075129cebSChurchill Khangar }
90175129cebSChurchill Khangar 
90275129cebSChurchill Khangar static int
90375129cebSChurchill Khangar pipeline_table_entries_delete(struct rte_swx_ctl_pipeline *p,
90475129cebSChurchill Khangar 			      const char *table_name,
90575129cebSChurchill Khangar 			      FILE *file,
90675129cebSChurchill Khangar 			      uint32_t *file_line_number)
90775129cebSChurchill Khangar {
90875129cebSChurchill Khangar 	char *line = NULL;
90975129cebSChurchill Khangar 	uint32_t line_id = 0;
91075129cebSChurchill Khangar 	int status = 0;
91175129cebSChurchill Khangar 
91275129cebSChurchill Khangar 	/* Buffer allocation. */
91375129cebSChurchill Khangar 	line = malloc(MAX_LINE_SIZE);
91475129cebSChurchill Khangar 	if (!line)
91575129cebSChurchill Khangar 		return -ENOMEM;
91675129cebSChurchill Khangar 
91775129cebSChurchill Khangar 	/* File read. */
91875129cebSChurchill Khangar 	for (line_id = 1; ; line_id++) {
91975129cebSChurchill Khangar 		struct rte_swx_table_entry *entry;
92075129cebSChurchill Khangar 		int is_blank_or_comment;
92175129cebSChurchill Khangar 
92275129cebSChurchill Khangar 		if (fgets(line, MAX_LINE_SIZE, file) == NULL)
92375129cebSChurchill Khangar 			break;
92475129cebSChurchill Khangar 
92575129cebSChurchill Khangar 		entry = rte_swx_ctl_pipeline_table_entry_read(p,
92675129cebSChurchill Khangar 							      table_name,
92775129cebSChurchill Khangar 							      line,
92875129cebSChurchill Khangar 							      &is_blank_or_comment);
92975129cebSChurchill Khangar 		if (!entry) {
93075129cebSChurchill Khangar 			if (is_blank_or_comment)
93175129cebSChurchill Khangar 				continue;
93275129cebSChurchill Khangar 
93375129cebSChurchill Khangar 			status = -EINVAL;
93475129cebSChurchill Khangar 			goto error;
93575129cebSChurchill Khangar 		}
93675129cebSChurchill Khangar 
93775129cebSChurchill Khangar 		status = rte_swx_ctl_pipeline_table_entry_delete(p,
93875129cebSChurchill Khangar 								 table_name,
93975129cebSChurchill Khangar 								 entry);
94075129cebSChurchill Khangar 		table_entry_free(entry);
94175129cebSChurchill Khangar 		if (status)
94275129cebSChurchill Khangar 			goto error;
94375129cebSChurchill Khangar 	}
94475129cebSChurchill Khangar 
94575129cebSChurchill Khangar error:
94675129cebSChurchill Khangar 	*file_line_number = line_id;
94775129cebSChurchill Khangar 	free(line);
94875129cebSChurchill Khangar 	return status;
94975129cebSChurchill Khangar }
95075129cebSChurchill Khangar 
95175129cebSChurchill Khangar static const char cmd_pipeline_table_delete_help[] =
95275129cebSChurchill Khangar "pipeline <pipeline_name> table <table_name> delete <file_name>\n";
95375129cebSChurchill Khangar 
95475129cebSChurchill Khangar static void
95575129cebSChurchill Khangar cmd_pipeline_table_delete(char **tokens,
95675129cebSChurchill Khangar 			  uint32_t n_tokens,
95775129cebSChurchill Khangar 			  char *out,
95875129cebSChurchill Khangar 			  size_t out_size,
959*b9559f94SCristian Dumitrescu 			  void *obj __rte_unused)
96075129cebSChurchill Khangar {
961*b9559f94SCristian Dumitrescu 	struct rte_swx_ctl_pipeline *ctl;
96275129cebSChurchill Khangar 	char *pipeline_name, *table_name, *file_name;
96375129cebSChurchill Khangar 	FILE *file = NULL;
96475129cebSChurchill Khangar 	uint32_t file_line_number = 0;
96575129cebSChurchill Khangar 	int status;
96675129cebSChurchill Khangar 
96775129cebSChurchill Khangar 	if (n_tokens != 6) {
96875129cebSChurchill Khangar 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
96975129cebSChurchill Khangar 		return;
97075129cebSChurchill Khangar 	}
97175129cebSChurchill Khangar 
97275129cebSChurchill Khangar 	pipeline_name = tokens[1];
973*b9559f94SCristian Dumitrescu 	ctl = rte_swx_ctl_pipeline_find(pipeline_name);
974*b9559f94SCristian Dumitrescu 	if (!ctl) {
97575129cebSChurchill Khangar 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
9765074e1d5SCristian Dumitrescu 		return;
9775074e1d5SCristian Dumitrescu 	}
9785074e1d5SCristian Dumitrescu 
9795074e1d5SCristian Dumitrescu 	table_name = tokens[3];
9805074e1d5SCristian Dumitrescu 
98175129cebSChurchill Khangar 	file_name = tokens[5];
98275129cebSChurchill Khangar 	file = fopen(file_name, "r");
98375129cebSChurchill Khangar 	if (!file) {
98475129cebSChurchill Khangar 		snprintf(out, out_size, "Cannot open file %s.\n", file_name);
9855074e1d5SCristian Dumitrescu 		return;
9865074e1d5SCristian Dumitrescu 	}
9875074e1d5SCristian Dumitrescu 
988*b9559f94SCristian Dumitrescu 	status = pipeline_table_entries_delete(ctl,
98975129cebSChurchill Khangar 					       table_name,
99075129cebSChurchill Khangar 					       file,
99175129cebSChurchill Khangar 					       &file_line_number);
99275129cebSChurchill Khangar 	if (status)
99375129cebSChurchill Khangar 		snprintf(out, out_size, "Invalid entry in file %s at line %u\n",
99475129cebSChurchill Khangar 			 file_name,
99575129cebSChurchill Khangar 			 file_line_number);
9965074e1d5SCristian Dumitrescu 
99775129cebSChurchill Khangar 	fclose(file);
9985074e1d5SCristian Dumitrescu }
9995074e1d5SCristian Dumitrescu 
100075129cebSChurchill Khangar static int
100175129cebSChurchill Khangar pipeline_table_default_entry_add(struct rte_swx_ctl_pipeline *p,
100275129cebSChurchill Khangar 				 const char *table_name,
100375129cebSChurchill Khangar 				 FILE *file,
100475129cebSChurchill Khangar 				 uint32_t *file_line_number)
100575129cebSChurchill Khangar {
100675129cebSChurchill Khangar 	char *line = NULL;
100775129cebSChurchill Khangar 	uint32_t line_id = 0;
100875129cebSChurchill Khangar 	int status = 0;
10095074e1d5SCristian Dumitrescu 
10105074e1d5SCristian Dumitrescu 	/* Buffer allocation. */
101175129cebSChurchill Khangar 	line = malloc(MAX_LINE_SIZE);
101275129cebSChurchill Khangar 	if (!line)
101375129cebSChurchill Khangar 		return -ENOMEM;
10145074e1d5SCristian Dumitrescu 
101575129cebSChurchill Khangar 	/* File read. */
10165074e1d5SCristian Dumitrescu 	for (line_id = 1; ; line_id++) {
10175074e1d5SCristian Dumitrescu 		struct rte_swx_table_entry *entry;
1018cff9a717SCristian Dumitrescu 		int is_blank_or_comment;
10195074e1d5SCristian Dumitrescu 
102075129cebSChurchill Khangar 		if (fgets(line, MAX_LINE_SIZE, file) == NULL)
10215074e1d5SCristian Dumitrescu 			break;
10225074e1d5SCristian Dumitrescu 
102375129cebSChurchill Khangar 		entry = rte_swx_ctl_pipeline_table_entry_read(p,
10245074e1d5SCristian Dumitrescu 							      table_name,
1025cff9a717SCristian Dumitrescu 							      line,
1026cff9a717SCristian Dumitrescu 							      &is_blank_or_comment);
10275074e1d5SCristian Dumitrescu 		if (!entry) {
1028cff9a717SCristian Dumitrescu 			if (is_blank_or_comment)
1029cff9a717SCristian Dumitrescu 				continue;
1030cff9a717SCristian Dumitrescu 
103175129cebSChurchill Khangar 			status = -EINVAL;
10325074e1d5SCristian Dumitrescu 			goto error;
10335074e1d5SCristian Dumitrescu 		}
10345074e1d5SCristian Dumitrescu 
103575129cebSChurchill Khangar 		status = rte_swx_ctl_pipeline_table_default_entry_add(p,
10365074e1d5SCristian Dumitrescu 								      table_name,
10375074e1d5SCristian Dumitrescu 								      entry);
1038275ebefeSCristian Dumitrescu 		table_entry_free(entry);
103975129cebSChurchill Khangar 		if (status)
10405074e1d5SCristian Dumitrescu 			goto error;
10415074e1d5SCristian Dumitrescu 	}
104275129cebSChurchill Khangar 
104375129cebSChurchill Khangar error:
104475129cebSChurchill Khangar 	*file_line_number = line_id;
104575129cebSChurchill Khangar 	free(line);
104675129cebSChurchill Khangar 	return status;
10475074e1d5SCristian Dumitrescu }
10485074e1d5SCristian Dumitrescu 
104975129cebSChurchill Khangar static const char cmd_pipeline_table_default_help[] =
105075129cebSChurchill Khangar "pipeline <pipeline_name> table <table_name> default <file_name>\n";
10515074e1d5SCristian Dumitrescu 
105275129cebSChurchill Khangar static void
105375129cebSChurchill Khangar cmd_pipeline_table_default(char **tokens,
105475129cebSChurchill Khangar 			   uint32_t n_tokens,
105575129cebSChurchill Khangar 			   char *out,
105675129cebSChurchill Khangar 			   size_t out_size,
1057*b9559f94SCristian Dumitrescu 			   void *obj __rte_unused)
105875129cebSChurchill Khangar {
1059*b9559f94SCristian Dumitrescu 	struct rte_swx_ctl_pipeline *ctl;
106075129cebSChurchill Khangar 	char *pipeline_name, *table_name, *file_name;
106175129cebSChurchill Khangar 	FILE *file = NULL;
106275129cebSChurchill Khangar 	uint32_t file_line_number = 0;
106375129cebSChurchill Khangar 	int status;
10645074e1d5SCristian Dumitrescu 
106575129cebSChurchill Khangar 	if (n_tokens != 6) {
106675129cebSChurchill Khangar 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
106775129cebSChurchill Khangar 		return;
106875129cebSChurchill Khangar 	}
10695074e1d5SCristian Dumitrescu 
107075129cebSChurchill Khangar 	pipeline_name = tokens[1];
1071*b9559f94SCristian Dumitrescu 	ctl = rte_swx_ctl_pipeline_find(pipeline_name);
1072*b9559f94SCristian Dumitrescu 	if (!ctl) {
107375129cebSChurchill Khangar 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
107475129cebSChurchill Khangar 		return;
107575129cebSChurchill Khangar 	}
107675129cebSChurchill Khangar 
107775129cebSChurchill Khangar 	table_name = tokens[3];
107875129cebSChurchill Khangar 
107975129cebSChurchill Khangar 	file_name = tokens[5];
108075129cebSChurchill Khangar 	file = fopen(file_name, "r");
108175129cebSChurchill Khangar 	if (!file) {
108275129cebSChurchill Khangar 		snprintf(out, out_size, "Cannot open file %s.\n", file_name);
108375129cebSChurchill Khangar 		return;
108475129cebSChurchill Khangar 	}
108575129cebSChurchill Khangar 
1086*b9559f94SCristian Dumitrescu 	status = pipeline_table_default_entry_add(ctl,
10875074e1d5SCristian Dumitrescu 						  table_name,
108875129cebSChurchill Khangar 						  file,
108975129cebSChurchill Khangar 						  &file_line_number);
109075129cebSChurchill Khangar 	if (status)
109175129cebSChurchill Khangar 		snprintf(out, out_size, "Invalid entry in file %s at line %u\n",
109275129cebSChurchill Khangar 			 file_name,
109375129cebSChurchill Khangar 			 file_line_number);
1094cff9a717SCristian Dumitrescu 
109575129cebSChurchill Khangar 	fclose(file);
10965074e1d5SCristian Dumitrescu }
10975074e1d5SCristian Dumitrescu 
109875129cebSChurchill Khangar static const char cmd_pipeline_table_show_help[] =
1099a4c1146cSCristian Dumitrescu "pipeline <pipeline_name> table <table_name> show [filename]\n";
110075129cebSChurchill Khangar 
110175129cebSChurchill Khangar static void
110275129cebSChurchill Khangar cmd_pipeline_table_show(char **tokens,
110375129cebSChurchill Khangar 	uint32_t n_tokens,
110475129cebSChurchill Khangar 	char *out,
110575129cebSChurchill Khangar 	size_t out_size,
1106*b9559f94SCristian Dumitrescu 	void *obj __rte_unused)
110775129cebSChurchill Khangar {
1108*b9559f94SCristian Dumitrescu 	struct rte_swx_ctl_pipeline *ctl;
110975129cebSChurchill Khangar 	char *pipeline_name, *table_name;
1110a4c1146cSCristian Dumitrescu 	FILE *file = NULL;
111175129cebSChurchill Khangar 	int status;
111275129cebSChurchill Khangar 
1113a4c1146cSCristian Dumitrescu 	if (n_tokens != 5 && n_tokens != 6) {
111475129cebSChurchill Khangar 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
111575129cebSChurchill Khangar 		return;
11165074e1d5SCristian Dumitrescu 	}
11175074e1d5SCristian Dumitrescu 
111875129cebSChurchill Khangar 	pipeline_name = tokens[1];
1119*b9559f94SCristian Dumitrescu 	ctl = rte_swx_ctl_pipeline_find(pipeline_name);
1120*b9559f94SCristian Dumitrescu 	if (!ctl) {
112175129cebSChurchill Khangar 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
112275129cebSChurchill Khangar 		return;
11235074e1d5SCristian Dumitrescu 	}
11245074e1d5SCristian Dumitrescu 
112575129cebSChurchill Khangar 	table_name = tokens[3];
1126a4c1146cSCristian Dumitrescu 	file = (n_tokens == 6) ? fopen(tokens[5], "w") : stdout;
1127a4c1146cSCristian Dumitrescu 	if (!file) {
1128a4c1146cSCristian Dumitrescu 		snprintf(out, out_size, "Cannot open file %s.\n", tokens[5]);
1129a4c1146cSCristian Dumitrescu 		return;
1130a4c1146cSCristian Dumitrescu 	}
1131a4c1146cSCristian Dumitrescu 
1132*b9559f94SCristian Dumitrescu 	status = rte_swx_ctl_pipeline_table_fprintf(file, ctl, table_name);
113375129cebSChurchill Khangar 	if (status)
113475129cebSChurchill Khangar 		snprintf(out, out_size, MSG_ARG_INVALID, "table_name");
1135a4c1146cSCristian Dumitrescu 
1136a4c1146cSCristian Dumitrescu 	if (file)
1137a4c1146cSCristian Dumitrescu 		fclose(file);
11385074e1d5SCristian Dumitrescu }
113975129cebSChurchill Khangar 
1140598fe0ddSCristian Dumitrescu static const char cmd_pipeline_selector_group_add_help[] =
1141598fe0ddSCristian Dumitrescu "pipeline <pipeline_name> selector <selector_name> group add\n";
1142598fe0ddSCristian Dumitrescu 
1143598fe0ddSCristian Dumitrescu static void
1144598fe0ddSCristian Dumitrescu cmd_pipeline_selector_group_add(char **tokens,
1145598fe0ddSCristian Dumitrescu 	uint32_t n_tokens,
1146598fe0ddSCristian Dumitrescu 	char *out,
1147598fe0ddSCristian Dumitrescu 	size_t out_size,
1148*b9559f94SCristian Dumitrescu 	void *obj __rte_unused)
1149598fe0ddSCristian Dumitrescu {
1150*b9559f94SCristian Dumitrescu 	struct rte_swx_ctl_pipeline *ctl;
1151598fe0ddSCristian Dumitrescu 	char *pipeline_name, *selector_name;
1152598fe0ddSCristian Dumitrescu 	uint32_t group_id;
1153598fe0ddSCristian Dumitrescu 	int status;
1154598fe0ddSCristian Dumitrescu 
1155598fe0ddSCristian Dumitrescu 	if (n_tokens != 6) {
1156598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1157598fe0ddSCristian Dumitrescu 		return;
1158598fe0ddSCristian Dumitrescu 	}
1159598fe0ddSCristian Dumitrescu 
1160598fe0ddSCristian Dumitrescu 	pipeline_name = tokens[1];
1161*b9559f94SCristian Dumitrescu 	ctl = rte_swx_ctl_pipeline_find(pipeline_name);
1162*b9559f94SCristian Dumitrescu 	if (!ctl) {
1163598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
1164598fe0ddSCristian Dumitrescu 		return;
1165598fe0ddSCristian Dumitrescu 	}
1166598fe0ddSCristian Dumitrescu 
1167598fe0ddSCristian Dumitrescu 	if (strcmp(tokens[2], "selector") != 0) {
1168598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "selector");
1169598fe0ddSCristian Dumitrescu 		return;
1170598fe0ddSCristian Dumitrescu 	}
1171598fe0ddSCristian Dumitrescu 
1172598fe0ddSCristian Dumitrescu 	selector_name = tokens[3];
1173598fe0ddSCristian Dumitrescu 
1174598fe0ddSCristian Dumitrescu 	if (strcmp(tokens[4], "group") ||
1175598fe0ddSCristian Dumitrescu 		strcmp(tokens[5], "add")) {
1176598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "group add");
1177598fe0ddSCristian Dumitrescu 		return;
1178598fe0ddSCristian Dumitrescu 	}
1179598fe0ddSCristian Dumitrescu 
1180*b9559f94SCristian Dumitrescu 	status = rte_swx_ctl_pipeline_selector_group_add(ctl,
1181598fe0ddSCristian Dumitrescu 		selector_name,
1182598fe0ddSCristian Dumitrescu 		&group_id);
1183598fe0ddSCristian Dumitrescu 	if (status)
1184598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
1185598fe0ddSCristian Dumitrescu 	else
1186598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, "Group ID: %u\n", group_id);
1187598fe0ddSCristian Dumitrescu }
1188598fe0ddSCristian Dumitrescu 
1189598fe0ddSCristian Dumitrescu static const char cmd_pipeline_selector_group_delete_help[] =
1190598fe0ddSCristian Dumitrescu "pipeline <pipeline_name> selector <selector_name> group delete <group_id>\n";
1191598fe0ddSCristian Dumitrescu 
1192598fe0ddSCristian Dumitrescu static void
1193598fe0ddSCristian Dumitrescu cmd_pipeline_selector_group_delete(char **tokens,
1194598fe0ddSCristian Dumitrescu 	uint32_t n_tokens,
1195598fe0ddSCristian Dumitrescu 	char *out,
1196598fe0ddSCristian Dumitrescu 	size_t out_size,
1197*b9559f94SCristian Dumitrescu 	void *obj __rte_unused)
1198598fe0ddSCristian Dumitrescu {
1199*b9559f94SCristian Dumitrescu 	struct rte_swx_ctl_pipeline *ctl;
1200598fe0ddSCristian Dumitrescu 	char *pipeline_name, *selector_name;
1201598fe0ddSCristian Dumitrescu 	uint32_t group_id;
1202598fe0ddSCristian Dumitrescu 	int status;
1203598fe0ddSCristian Dumitrescu 
1204598fe0ddSCristian Dumitrescu 	if (n_tokens != 7) {
1205598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1206598fe0ddSCristian Dumitrescu 		return;
1207598fe0ddSCristian Dumitrescu 	}
1208598fe0ddSCristian Dumitrescu 
1209598fe0ddSCristian Dumitrescu 	pipeline_name = tokens[1];
1210*b9559f94SCristian Dumitrescu 	ctl = rte_swx_ctl_pipeline_find(pipeline_name);
1211*b9559f94SCristian Dumitrescu 	if (!ctl) {
1212598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
1213598fe0ddSCristian Dumitrescu 		return;
1214598fe0ddSCristian Dumitrescu 	}
1215598fe0ddSCristian Dumitrescu 
1216598fe0ddSCristian Dumitrescu 	if (strcmp(tokens[2], "selector") != 0) {
1217598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "selector");
1218598fe0ddSCristian Dumitrescu 		return;
1219598fe0ddSCristian Dumitrescu 	}
1220598fe0ddSCristian Dumitrescu 
1221598fe0ddSCristian Dumitrescu 	selector_name = tokens[3];
1222598fe0ddSCristian Dumitrescu 
1223598fe0ddSCristian Dumitrescu 	if (strcmp(tokens[4], "group") ||
1224598fe0ddSCristian Dumitrescu 		strcmp(tokens[5], "delete")) {
1225598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "group delete");
1226598fe0ddSCristian Dumitrescu 		return;
1227598fe0ddSCristian Dumitrescu 	}
1228598fe0ddSCristian Dumitrescu 
1229598fe0ddSCristian Dumitrescu 	if (parser_read_uint32(&group_id, tokens[6]) != 0) {
1230598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "group_id");
1231598fe0ddSCristian Dumitrescu 		return;
1232598fe0ddSCristian Dumitrescu 	}
1233598fe0ddSCristian Dumitrescu 
1234*b9559f94SCristian Dumitrescu 	status = rte_swx_ctl_pipeline_selector_group_delete(ctl,
1235598fe0ddSCristian Dumitrescu 		selector_name,
1236598fe0ddSCristian Dumitrescu 		group_id);
1237598fe0ddSCristian Dumitrescu 	if (status)
1238598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
1239598fe0ddSCristian Dumitrescu }
1240598fe0ddSCristian Dumitrescu 
1241598fe0ddSCristian Dumitrescu #define GROUP_MEMBER_INFO_TOKENS_MAX 6
1242598fe0ddSCristian Dumitrescu 
1243598fe0ddSCristian Dumitrescu static int
1244598fe0ddSCristian Dumitrescu token_is_comment(const char *token)
1245598fe0ddSCristian Dumitrescu {
1246598fe0ddSCristian Dumitrescu 	if ((token[0] == '#') ||
1247598fe0ddSCristian Dumitrescu 	    (token[0] == ';') ||
1248598fe0ddSCristian Dumitrescu 	    ((token[0] == '/') && (token[1] == '/')))
1249598fe0ddSCristian Dumitrescu 		return 1; /* TRUE. */
1250598fe0ddSCristian Dumitrescu 
1251598fe0ddSCristian Dumitrescu 	return 0; /* FALSE. */
1252598fe0ddSCristian Dumitrescu }
1253598fe0ddSCristian Dumitrescu 
1254598fe0ddSCristian Dumitrescu static int
1255598fe0ddSCristian Dumitrescu pipeline_selector_group_member_read(const char *string,
1256598fe0ddSCristian Dumitrescu 				      uint32_t *group_id,
1257598fe0ddSCristian Dumitrescu 				      uint32_t *member_id,
1258598fe0ddSCristian Dumitrescu 				      uint32_t *weight,
1259598fe0ddSCristian Dumitrescu 				      int *is_blank_or_comment)
1260598fe0ddSCristian Dumitrescu {
1261598fe0ddSCristian Dumitrescu 	char *token_array[GROUP_MEMBER_INFO_TOKENS_MAX], **tokens;
1262598fe0ddSCristian Dumitrescu 	char *s0 = NULL, *s;
126300b67591SAli Alnubani 	uint32_t n_tokens = 0, group_id_val = 0, member_id_val = 0, weight_val = 0;
1264598fe0ddSCristian Dumitrescu 	int blank_or_comment = 0;
1265598fe0ddSCristian Dumitrescu 
1266598fe0ddSCristian Dumitrescu 	/* Check input arguments. */
1267598fe0ddSCristian Dumitrescu 	if (!string || !string[0])
1268598fe0ddSCristian Dumitrescu 		goto error;
1269598fe0ddSCristian Dumitrescu 
1270598fe0ddSCristian Dumitrescu 	/* Memory allocation. */
1271598fe0ddSCristian Dumitrescu 	s0 = strdup(string);
1272598fe0ddSCristian Dumitrescu 	if (!s0)
1273598fe0ddSCristian Dumitrescu 		goto error;
1274598fe0ddSCristian Dumitrescu 
1275598fe0ddSCristian Dumitrescu 	/* Parse the string into tokens. */
1276598fe0ddSCristian Dumitrescu 	for (s = s0; ; ) {
1277598fe0ddSCristian Dumitrescu 		char *token;
1278598fe0ddSCristian Dumitrescu 
1279598fe0ddSCristian Dumitrescu 		token = strtok_r(s, " \f\n\r\t\v", &s);
1280598fe0ddSCristian Dumitrescu 		if (!token || token_is_comment(token))
1281598fe0ddSCristian Dumitrescu 			break;
1282598fe0ddSCristian Dumitrescu 
1283cfcc7bf8SCristian Dumitrescu 		if (n_tokens >= GROUP_MEMBER_INFO_TOKENS_MAX)
1284598fe0ddSCristian Dumitrescu 			goto error;
1285598fe0ddSCristian Dumitrescu 
1286598fe0ddSCristian Dumitrescu 		token_array[n_tokens] = token;
1287598fe0ddSCristian Dumitrescu 		n_tokens++;
1288598fe0ddSCristian Dumitrescu 	}
1289598fe0ddSCristian Dumitrescu 
1290598fe0ddSCristian Dumitrescu 	if (!n_tokens) {
1291598fe0ddSCristian Dumitrescu 		blank_or_comment = 1;
1292598fe0ddSCristian Dumitrescu 		goto error;
1293598fe0ddSCristian Dumitrescu 	}
1294598fe0ddSCristian Dumitrescu 
1295598fe0ddSCristian Dumitrescu 	tokens = token_array;
1296598fe0ddSCristian Dumitrescu 
1297598fe0ddSCristian Dumitrescu 	if (n_tokens < 4 ||
1298598fe0ddSCristian Dumitrescu 		strcmp(tokens[0], "group") ||
1299598fe0ddSCristian Dumitrescu 		strcmp(tokens[2], "member"))
1300598fe0ddSCristian Dumitrescu 		goto error;
1301598fe0ddSCristian Dumitrescu 
1302598fe0ddSCristian Dumitrescu 	/*
1303598fe0ddSCristian Dumitrescu 	 * Group ID.
1304598fe0ddSCristian Dumitrescu 	 */
1305598fe0ddSCristian Dumitrescu 	if (parser_read_uint32(&group_id_val, tokens[1]) != 0)
1306598fe0ddSCristian Dumitrescu 		goto error;
1307598fe0ddSCristian Dumitrescu 	*group_id = group_id_val;
1308598fe0ddSCristian Dumitrescu 
1309598fe0ddSCristian Dumitrescu 	/*
1310598fe0ddSCristian Dumitrescu 	 * Member ID.
1311598fe0ddSCristian Dumitrescu 	 */
1312598fe0ddSCristian Dumitrescu 	if (parser_read_uint32(&member_id_val, tokens[3]) != 0)
1313598fe0ddSCristian Dumitrescu 		goto error;
1314598fe0ddSCristian Dumitrescu 	*member_id = member_id_val;
1315598fe0ddSCristian Dumitrescu 
1316598fe0ddSCristian Dumitrescu 	tokens += 4;
1317598fe0ddSCristian Dumitrescu 	n_tokens -= 4;
1318598fe0ddSCristian Dumitrescu 
1319598fe0ddSCristian Dumitrescu 	/*
1320598fe0ddSCristian Dumitrescu 	 * Weight.
1321598fe0ddSCristian Dumitrescu 	 */
1322598fe0ddSCristian Dumitrescu 	if (n_tokens && !strcmp(tokens[0], "weight")) {
1323598fe0ddSCristian Dumitrescu 		if (n_tokens < 2)
1324598fe0ddSCristian Dumitrescu 			goto error;
1325598fe0ddSCristian Dumitrescu 
1326598fe0ddSCristian Dumitrescu 		if (parser_read_uint32(&weight_val, tokens[1]) != 0)
1327598fe0ddSCristian Dumitrescu 			goto error;
1328598fe0ddSCristian Dumitrescu 		*weight = weight_val;
1329598fe0ddSCristian Dumitrescu 
1330598fe0ddSCristian Dumitrescu 		tokens += 2;
1331598fe0ddSCristian Dumitrescu 		n_tokens -= 2;
1332598fe0ddSCristian Dumitrescu 	}
1333598fe0ddSCristian Dumitrescu 
1334598fe0ddSCristian Dumitrescu 	if (n_tokens)
1335598fe0ddSCristian Dumitrescu 		goto error;
1336598fe0ddSCristian Dumitrescu 
1337598fe0ddSCristian Dumitrescu 	free(s0);
1338598fe0ddSCristian Dumitrescu 	return 0;
1339598fe0ddSCristian Dumitrescu 
1340598fe0ddSCristian Dumitrescu error:
1341598fe0ddSCristian Dumitrescu 	free(s0);
1342598fe0ddSCristian Dumitrescu 	if (is_blank_or_comment)
1343598fe0ddSCristian Dumitrescu 		*is_blank_or_comment = blank_or_comment;
1344598fe0ddSCristian Dumitrescu 	return -EINVAL;
1345598fe0ddSCristian Dumitrescu }
1346598fe0ddSCristian Dumitrescu 
1347598fe0ddSCristian Dumitrescu static int
1348598fe0ddSCristian Dumitrescu pipeline_selector_group_members_add(struct rte_swx_ctl_pipeline *p,
1349598fe0ddSCristian Dumitrescu 			   const char *selector_name,
1350598fe0ddSCristian Dumitrescu 			   FILE *file,
1351598fe0ddSCristian Dumitrescu 			   uint32_t *file_line_number)
1352598fe0ddSCristian Dumitrescu {
1353598fe0ddSCristian Dumitrescu 	char *line = NULL;
1354598fe0ddSCristian Dumitrescu 	uint32_t line_id = 0;
1355598fe0ddSCristian Dumitrescu 	int status = 0;
1356598fe0ddSCristian Dumitrescu 
1357598fe0ddSCristian Dumitrescu 	/* Buffer allocation. */
1358598fe0ddSCristian Dumitrescu 	line = malloc(MAX_LINE_SIZE);
1359598fe0ddSCristian Dumitrescu 	if (!line)
1360598fe0ddSCristian Dumitrescu 		return -ENOMEM;
1361598fe0ddSCristian Dumitrescu 
1362598fe0ddSCristian Dumitrescu 	/* File read. */
1363598fe0ddSCristian Dumitrescu 	for (line_id = 1; ; line_id++) {
1364598fe0ddSCristian Dumitrescu 		uint32_t group_id, member_id, weight;
1365598fe0ddSCristian Dumitrescu 		int is_blank_or_comment;
1366598fe0ddSCristian Dumitrescu 
1367598fe0ddSCristian Dumitrescu 		if (fgets(line, MAX_LINE_SIZE, file) == NULL)
1368598fe0ddSCristian Dumitrescu 			break;
1369598fe0ddSCristian Dumitrescu 
1370598fe0ddSCristian Dumitrescu 		status = pipeline_selector_group_member_read(line,
1371598fe0ddSCristian Dumitrescu 							      &group_id,
1372598fe0ddSCristian Dumitrescu 							      &member_id,
1373598fe0ddSCristian Dumitrescu 							      &weight,
1374598fe0ddSCristian Dumitrescu 							      &is_blank_or_comment);
1375598fe0ddSCristian Dumitrescu 		if (status) {
1376598fe0ddSCristian Dumitrescu 			if (is_blank_or_comment)
1377598fe0ddSCristian Dumitrescu 				continue;
1378598fe0ddSCristian Dumitrescu 
1379598fe0ddSCristian Dumitrescu 			goto error;
1380598fe0ddSCristian Dumitrescu 		}
1381598fe0ddSCristian Dumitrescu 
1382598fe0ddSCristian Dumitrescu 		status = rte_swx_ctl_pipeline_selector_group_member_add(p,
1383598fe0ddSCristian Dumitrescu 			selector_name,
1384598fe0ddSCristian Dumitrescu 			group_id,
1385598fe0ddSCristian Dumitrescu 			member_id,
1386598fe0ddSCristian Dumitrescu 			weight);
1387598fe0ddSCristian Dumitrescu 		if (status)
1388598fe0ddSCristian Dumitrescu 			goto error;
1389598fe0ddSCristian Dumitrescu 	}
1390598fe0ddSCristian Dumitrescu 
1391598fe0ddSCristian Dumitrescu error:
1392598fe0ddSCristian Dumitrescu 	free(line);
1393598fe0ddSCristian Dumitrescu 	*file_line_number = line_id;
1394598fe0ddSCristian Dumitrescu 	return status;
1395598fe0ddSCristian Dumitrescu }
1396598fe0ddSCristian Dumitrescu 
1397598fe0ddSCristian Dumitrescu static const char cmd_pipeline_selector_group_member_add_help[] =
1398598fe0ddSCristian Dumitrescu "pipeline <pipeline_name> selector <selector_name> group member add <file_name>";
1399598fe0ddSCristian Dumitrescu 
1400598fe0ddSCristian Dumitrescu static void
1401598fe0ddSCristian Dumitrescu cmd_pipeline_selector_group_member_add(char **tokens,
1402598fe0ddSCristian Dumitrescu 	uint32_t n_tokens,
1403598fe0ddSCristian Dumitrescu 	char *out,
1404598fe0ddSCristian Dumitrescu 	size_t out_size,
1405*b9559f94SCristian Dumitrescu 	void *obj __rte_unused)
1406598fe0ddSCristian Dumitrescu {
1407*b9559f94SCristian Dumitrescu 	struct rte_swx_ctl_pipeline *ctl;
1408598fe0ddSCristian Dumitrescu 	char *pipeline_name, *selector_name, *file_name;
1409598fe0ddSCristian Dumitrescu 	FILE *file = NULL;
1410598fe0ddSCristian Dumitrescu 	uint32_t file_line_number = 0;
1411598fe0ddSCristian Dumitrescu 	int status;
1412598fe0ddSCristian Dumitrescu 
1413598fe0ddSCristian Dumitrescu 	if (n_tokens != 8) {
1414598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1415598fe0ddSCristian Dumitrescu 		return;
1416598fe0ddSCristian Dumitrescu 	}
1417598fe0ddSCristian Dumitrescu 
1418598fe0ddSCristian Dumitrescu 	pipeline_name = tokens[1];
1419*b9559f94SCristian Dumitrescu 	ctl = rte_swx_ctl_pipeline_find(pipeline_name);
1420*b9559f94SCristian Dumitrescu 	if (!ctl) {
1421598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
1422598fe0ddSCristian Dumitrescu 		return;
1423598fe0ddSCristian Dumitrescu 	}
1424598fe0ddSCristian Dumitrescu 
1425598fe0ddSCristian Dumitrescu 	if (strcmp(tokens[2], "selector") != 0) {
1426598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "selector");
1427598fe0ddSCristian Dumitrescu 		return;
1428598fe0ddSCristian Dumitrescu 	}
1429598fe0ddSCristian Dumitrescu 
1430598fe0ddSCristian Dumitrescu 	selector_name = tokens[3];
1431598fe0ddSCristian Dumitrescu 
1432598fe0ddSCristian Dumitrescu 	if (strcmp(tokens[4], "group") ||
1433598fe0ddSCristian Dumitrescu 		strcmp(tokens[5], "member") ||
1434598fe0ddSCristian Dumitrescu 		strcmp(tokens[6], "add")) {
1435598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "group member add");
1436598fe0ddSCristian Dumitrescu 		return;
1437598fe0ddSCristian Dumitrescu 	}
1438598fe0ddSCristian Dumitrescu 
1439598fe0ddSCristian Dumitrescu 	file_name = tokens[7];
1440598fe0ddSCristian Dumitrescu 	file = fopen(file_name, "r");
1441598fe0ddSCristian Dumitrescu 	if (!file) {
1442598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, "Cannot open file %s.\n", file_name);
1443598fe0ddSCristian Dumitrescu 		return;
1444598fe0ddSCristian Dumitrescu 	}
1445598fe0ddSCristian Dumitrescu 
1446*b9559f94SCristian Dumitrescu 	status = pipeline_selector_group_members_add(ctl,
1447598fe0ddSCristian Dumitrescu 					    selector_name,
1448598fe0ddSCristian Dumitrescu 					    file,
1449598fe0ddSCristian Dumitrescu 					    &file_line_number);
1450598fe0ddSCristian Dumitrescu 	if (status)
1451598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, "Invalid entry in file %s at line %u\n",
1452598fe0ddSCristian Dumitrescu 			 file_name,
1453598fe0ddSCristian Dumitrescu 			 file_line_number);
1454598fe0ddSCristian Dumitrescu 
1455598fe0ddSCristian Dumitrescu 	fclose(file);
1456598fe0ddSCristian Dumitrescu }
1457598fe0ddSCristian Dumitrescu 
1458598fe0ddSCristian Dumitrescu static int
1459598fe0ddSCristian Dumitrescu pipeline_selector_group_members_delete(struct rte_swx_ctl_pipeline *p,
1460598fe0ddSCristian Dumitrescu 			   const char *selector_name,
1461598fe0ddSCristian Dumitrescu 			   FILE *file,
1462598fe0ddSCristian Dumitrescu 			   uint32_t *file_line_number)
1463598fe0ddSCristian Dumitrescu {
1464598fe0ddSCristian Dumitrescu 	char *line = NULL;
1465598fe0ddSCristian Dumitrescu 	uint32_t line_id = 0;
1466598fe0ddSCristian Dumitrescu 	int status = 0;
1467598fe0ddSCristian Dumitrescu 
1468598fe0ddSCristian Dumitrescu 	/* Buffer allocation. */
1469598fe0ddSCristian Dumitrescu 	line = malloc(MAX_LINE_SIZE);
1470598fe0ddSCristian Dumitrescu 	if (!line)
1471598fe0ddSCristian Dumitrescu 		return -ENOMEM;
1472598fe0ddSCristian Dumitrescu 
1473598fe0ddSCristian Dumitrescu 	/* File read. */
1474598fe0ddSCristian Dumitrescu 	for (line_id = 1; ; line_id++) {
1475598fe0ddSCristian Dumitrescu 		uint32_t group_id, member_id, weight;
1476598fe0ddSCristian Dumitrescu 		int is_blank_or_comment;
1477598fe0ddSCristian Dumitrescu 
1478598fe0ddSCristian Dumitrescu 		if (fgets(line, MAX_LINE_SIZE, file) == NULL)
1479598fe0ddSCristian Dumitrescu 			break;
1480598fe0ddSCristian Dumitrescu 
1481598fe0ddSCristian Dumitrescu 		status = pipeline_selector_group_member_read(line,
1482598fe0ddSCristian Dumitrescu 							      &group_id,
1483598fe0ddSCristian Dumitrescu 							      &member_id,
1484598fe0ddSCristian Dumitrescu 							      &weight,
1485598fe0ddSCristian Dumitrescu 							      &is_blank_or_comment);
1486598fe0ddSCristian Dumitrescu 		if (status) {
1487598fe0ddSCristian Dumitrescu 			if (is_blank_or_comment)
1488598fe0ddSCristian Dumitrescu 				continue;
1489598fe0ddSCristian Dumitrescu 
1490598fe0ddSCristian Dumitrescu 			goto error;
1491598fe0ddSCristian Dumitrescu 		}
1492598fe0ddSCristian Dumitrescu 
1493598fe0ddSCristian Dumitrescu 		status = rte_swx_ctl_pipeline_selector_group_member_delete(p,
1494598fe0ddSCristian Dumitrescu 			selector_name,
1495598fe0ddSCristian Dumitrescu 			group_id,
1496598fe0ddSCristian Dumitrescu 			member_id);
1497598fe0ddSCristian Dumitrescu 		if (status)
1498598fe0ddSCristian Dumitrescu 			goto error;
1499598fe0ddSCristian Dumitrescu 	}
1500598fe0ddSCristian Dumitrescu 
1501598fe0ddSCristian Dumitrescu error:
1502598fe0ddSCristian Dumitrescu 	free(line);
1503598fe0ddSCristian Dumitrescu 	*file_line_number = line_id;
1504598fe0ddSCristian Dumitrescu 	return status;
1505598fe0ddSCristian Dumitrescu }
1506598fe0ddSCristian Dumitrescu 
1507598fe0ddSCristian Dumitrescu static const char cmd_pipeline_selector_group_member_delete_help[] =
1508598fe0ddSCristian Dumitrescu "pipeline <pipeline_name> selector <selector_name> group member delete <file_name>";
1509598fe0ddSCristian Dumitrescu 
1510598fe0ddSCristian Dumitrescu static void
1511598fe0ddSCristian Dumitrescu cmd_pipeline_selector_group_member_delete(char **tokens,
1512598fe0ddSCristian Dumitrescu 	uint32_t n_tokens,
1513598fe0ddSCristian Dumitrescu 	char *out,
1514598fe0ddSCristian Dumitrescu 	size_t out_size,
1515*b9559f94SCristian Dumitrescu 	void *obj __rte_unused)
1516598fe0ddSCristian Dumitrescu {
1517*b9559f94SCristian Dumitrescu 	struct rte_swx_ctl_pipeline *ctl;
1518598fe0ddSCristian Dumitrescu 	char *pipeline_name, *selector_name, *file_name;
1519598fe0ddSCristian Dumitrescu 	FILE *file = NULL;
1520598fe0ddSCristian Dumitrescu 	uint32_t file_line_number = 0;
1521598fe0ddSCristian Dumitrescu 	int status;
1522598fe0ddSCristian Dumitrescu 
1523598fe0ddSCristian Dumitrescu 	if (n_tokens != 8) {
1524598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1525598fe0ddSCristian Dumitrescu 		return;
1526598fe0ddSCristian Dumitrescu 	}
1527598fe0ddSCristian Dumitrescu 
1528598fe0ddSCristian Dumitrescu 	pipeline_name = tokens[1];
1529*b9559f94SCristian Dumitrescu 	ctl = rte_swx_ctl_pipeline_find(pipeline_name);
1530*b9559f94SCristian Dumitrescu 	if (!ctl) {
1531598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
1532598fe0ddSCristian Dumitrescu 		return;
1533598fe0ddSCristian Dumitrescu 	}
1534598fe0ddSCristian Dumitrescu 
1535598fe0ddSCristian Dumitrescu 	if (strcmp(tokens[2], "selector") != 0) {
1536598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "selector");
1537598fe0ddSCristian Dumitrescu 		return;
1538598fe0ddSCristian Dumitrescu 	}
1539598fe0ddSCristian Dumitrescu 
1540598fe0ddSCristian Dumitrescu 	selector_name = tokens[3];
1541598fe0ddSCristian Dumitrescu 
1542598fe0ddSCristian Dumitrescu 	if (strcmp(tokens[4], "group") ||
1543598fe0ddSCristian Dumitrescu 		strcmp(tokens[5], "member") ||
1544598fe0ddSCristian Dumitrescu 		strcmp(tokens[6], "delete")) {
1545598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "group member delete");
1546598fe0ddSCristian Dumitrescu 		return;
1547598fe0ddSCristian Dumitrescu 	}
1548598fe0ddSCristian Dumitrescu 
1549598fe0ddSCristian Dumitrescu 	file_name = tokens[7];
1550598fe0ddSCristian Dumitrescu 	file = fopen(file_name, "r");
1551598fe0ddSCristian Dumitrescu 	if (!file) {
1552598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, "Cannot open file %s.\n", file_name);
1553598fe0ddSCristian Dumitrescu 		return;
1554598fe0ddSCristian Dumitrescu 	}
1555598fe0ddSCristian Dumitrescu 
1556*b9559f94SCristian Dumitrescu 	status = pipeline_selector_group_members_delete(ctl,
1557598fe0ddSCristian Dumitrescu 					    selector_name,
1558598fe0ddSCristian Dumitrescu 					    file,
1559598fe0ddSCristian Dumitrescu 					    &file_line_number);
1560598fe0ddSCristian Dumitrescu 	if (status)
1561598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, "Invalid entry in file %s at line %u\n",
1562598fe0ddSCristian Dumitrescu 			 file_name,
1563598fe0ddSCristian Dumitrescu 			 file_line_number);
1564598fe0ddSCristian Dumitrescu 
1565598fe0ddSCristian Dumitrescu 	fclose(file);
1566598fe0ddSCristian Dumitrescu }
1567598fe0ddSCristian Dumitrescu 
1568598fe0ddSCristian Dumitrescu static const char cmd_pipeline_selector_show_help[] =
1569a4c1146cSCristian Dumitrescu "pipeline <pipeline_name> selector <selector_name> show [filename]\n";
1570598fe0ddSCristian Dumitrescu 
1571598fe0ddSCristian Dumitrescu static void
1572598fe0ddSCristian Dumitrescu cmd_pipeline_selector_show(char **tokens,
1573598fe0ddSCristian Dumitrescu 	uint32_t n_tokens,
1574598fe0ddSCristian Dumitrescu 	char *out,
1575598fe0ddSCristian Dumitrescu 	size_t out_size,
1576*b9559f94SCristian Dumitrescu 	void *obj __rte_unused)
1577598fe0ddSCristian Dumitrescu {
1578*b9559f94SCristian Dumitrescu 	struct rte_swx_ctl_pipeline *ctl;
1579598fe0ddSCristian Dumitrescu 	char *pipeline_name, *selector_name;
1580a4c1146cSCristian Dumitrescu 	FILE *file = NULL;
1581598fe0ddSCristian Dumitrescu 	int status;
1582598fe0ddSCristian Dumitrescu 
1583a4c1146cSCristian Dumitrescu 	if (n_tokens != 5 && n_tokens != 6) {
1584598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1585598fe0ddSCristian Dumitrescu 		return;
1586598fe0ddSCristian Dumitrescu 	}
1587598fe0ddSCristian Dumitrescu 
1588598fe0ddSCristian Dumitrescu 	pipeline_name = tokens[1];
1589*b9559f94SCristian Dumitrescu 	ctl = rte_swx_ctl_pipeline_find(pipeline_name);
1590*b9559f94SCristian Dumitrescu 	if (!ctl) {
1591598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
1592598fe0ddSCristian Dumitrescu 		return;
1593598fe0ddSCristian Dumitrescu 	}
1594598fe0ddSCristian Dumitrescu 
1595598fe0ddSCristian Dumitrescu 	selector_name = tokens[3];
1596a4c1146cSCristian Dumitrescu 
1597a4c1146cSCristian Dumitrescu 	file = (n_tokens == 6) ? fopen(tokens[5], "w") : stdout;
1598a4c1146cSCristian Dumitrescu 	if (!file) {
1599a4c1146cSCristian Dumitrescu 		snprintf(out, out_size, "Cannot open file %s.\n", tokens[5]);
1600a4c1146cSCristian Dumitrescu 		return;
1601a4c1146cSCristian Dumitrescu 	}
1602a4c1146cSCristian Dumitrescu 
1603*b9559f94SCristian Dumitrescu 	status = rte_swx_ctl_pipeline_selector_fprintf(file, ctl, selector_name);
1604598fe0ddSCristian Dumitrescu 	if (status)
1605598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "selector_name");
1606a4c1146cSCristian Dumitrescu 
1607a4c1146cSCristian Dumitrescu 	if (file)
1608a4c1146cSCristian Dumitrescu 		fclose(file);
1609598fe0ddSCristian Dumitrescu }
1610598fe0ddSCristian Dumitrescu 
16118bd4862fSCristian Dumitrescu static int
16128bd4862fSCristian Dumitrescu pipeline_learner_default_entry_add(struct rte_swx_ctl_pipeline *p,
16138bd4862fSCristian Dumitrescu 				   const char *learner_name,
16148bd4862fSCristian Dumitrescu 				   FILE *file,
16158bd4862fSCristian Dumitrescu 				   uint32_t *file_line_number)
16168bd4862fSCristian Dumitrescu {
16178bd4862fSCristian Dumitrescu 	char *line = NULL;
16188bd4862fSCristian Dumitrescu 	uint32_t line_id = 0;
16198bd4862fSCristian Dumitrescu 	int status = 0;
16208bd4862fSCristian Dumitrescu 
16218bd4862fSCristian Dumitrescu 	/* Buffer allocation. */
16228bd4862fSCristian Dumitrescu 	line = malloc(MAX_LINE_SIZE);
16238bd4862fSCristian Dumitrescu 	if (!line)
16248bd4862fSCristian Dumitrescu 		return -ENOMEM;
16258bd4862fSCristian Dumitrescu 
16268bd4862fSCristian Dumitrescu 	/* File read. */
16278bd4862fSCristian Dumitrescu 	for (line_id = 1; ; line_id++) {
16288bd4862fSCristian Dumitrescu 		struct rte_swx_table_entry *entry;
16298bd4862fSCristian Dumitrescu 		int is_blank_or_comment;
16308bd4862fSCristian Dumitrescu 
16318bd4862fSCristian Dumitrescu 		if (fgets(line, MAX_LINE_SIZE, file) == NULL)
16328bd4862fSCristian Dumitrescu 			break;
16338bd4862fSCristian Dumitrescu 
16348bd4862fSCristian Dumitrescu 		entry = rte_swx_ctl_pipeline_learner_default_entry_read(p,
16358bd4862fSCristian Dumitrescu 									learner_name,
16368bd4862fSCristian Dumitrescu 									line,
16378bd4862fSCristian Dumitrescu 									&is_blank_or_comment);
16388bd4862fSCristian Dumitrescu 		if (!entry) {
16398bd4862fSCristian Dumitrescu 			if (is_blank_or_comment)
16408bd4862fSCristian Dumitrescu 				continue;
16418bd4862fSCristian Dumitrescu 
16428bd4862fSCristian Dumitrescu 			status = -EINVAL;
16438bd4862fSCristian Dumitrescu 			goto error;
16448bd4862fSCristian Dumitrescu 		}
16458bd4862fSCristian Dumitrescu 
16468bd4862fSCristian Dumitrescu 		status = rte_swx_ctl_pipeline_learner_default_entry_add(p,
16478bd4862fSCristian Dumitrescu 									learner_name,
16488bd4862fSCristian Dumitrescu 									entry);
16498bd4862fSCristian Dumitrescu 		table_entry_free(entry);
16508bd4862fSCristian Dumitrescu 		if (status)
16518bd4862fSCristian Dumitrescu 			goto error;
16528bd4862fSCristian Dumitrescu 	}
16538bd4862fSCristian Dumitrescu 
16548bd4862fSCristian Dumitrescu error:
16558bd4862fSCristian Dumitrescu 	*file_line_number = line_id;
16568bd4862fSCristian Dumitrescu 	free(line);
16578bd4862fSCristian Dumitrescu 	return status;
16588bd4862fSCristian Dumitrescu }
16598bd4862fSCristian Dumitrescu 
16608bd4862fSCristian Dumitrescu static const char cmd_pipeline_learner_default_help[] =
16618bd4862fSCristian Dumitrescu "pipeline <pipeline_name> learner <learner_name> default <file_name>\n";
16628bd4862fSCristian Dumitrescu 
16638bd4862fSCristian Dumitrescu static void
16648bd4862fSCristian Dumitrescu cmd_pipeline_learner_default(char **tokens,
16658bd4862fSCristian Dumitrescu 			     uint32_t n_tokens,
16668bd4862fSCristian Dumitrescu 			     char *out,
16678bd4862fSCristian Dumitrescu 			     size_t out_size,
1668*b9559f94SCristian Dumitrescu 			     void *obj __rte_unused)
16698bd4862fSCristian Dumitrescu {
1670*b9559f94SCristian Dumitrescu 	struct rte_swx_ctl_pipeline *ctl;
16718bd4862fSCristian Dumitrescu 	char *pipeline_name, *learner_name, *file_name;
16728bd4862fSCristian Dumitrescu 	FILE *file = NULL;
16738bd4862fSCristian Dumitrescu 	uint32_t file_line_number = 0;
16748bd4862fSCristian Dumitrescu 	int status;
16758bd4862fSCristian Dumitrescu 
16768bd4862fSCristian Dumitrescu 	if (n_tokens != 6) {
16778bd4862fSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
16788bd4862fSCristian Dumitrescu 		return;
16798bd4862fSCristian Dumitrescu 	}
16808bd4862fSCristian Dumitrescu 
16818bd4862fSCristian Dumitrescu 	pipeline_name = tokens[1];
1682*b9559f94SCristian Dumitrescu 	ctl = rte_swx_ctl_pipeline_find(pipeline_name);
1683*b9559f94SCristian Dumitrescu 	if (!ctl) {
16848bd4862fSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
16858bd4862fSCristian Dumitrescu 		return;
16868bd4862fSCristian Dumitrescu 	}
16878bd4862fSCristian Dumitrescu 
16888bd4862fSCristian Dumitrescu 	learner_name = tokens[3];
16898bd4862fSCristian Dumitrescu 
16908bd4862fSCristian Dumitrescu 	file_name = tokens[5];
16918bd4862fSCristian Dumitrescu 	file = fopen(file_name, "r");
16928bd4862fSCristian Dumitrescu 	if (!file) {
16938bd4862fSCristian Dumitrescu 		snprintf(out, out_size, "Cannot open file %s.\n", file_name);
16948bd4862fSCristian Dumitrescu 		return;
16958bd4862fSCristian Dumitrescu 	}
16968bd4862fSCristian Dumitrescu 
1697*b9559f94SCristian Dumitrescu 	status = pipeline_learner_default_entry_add(ctl,
16988bd4862fSCristian Dumitrescu 						    learner_name,
16998bd4862fSCristian Dumitrescu 						    file,
17008bd4862fSCristian Dumitrescu 						    &file_line_number);
17018bd4862fSCristian Dumitrescu 	if (status)
17028bd4862fSCristian Dumitrescu 		snprintf(out, out_size, "Invalid entry in file %s at line %u\n",
17038bd4862fSCristian Dumitrescu 			 file_name,
17048bd4862fSCristian Dumitrescu 			 file_line_number);
17058bd4862fSCristian Dumitrescu 
17068bd4862fSCristian Dumitrescu 	fclose(file);
17078bd4862fSCristian Dumitrescu }
17088bd4862fSCristian Dumitrescu 
170975129cebSChurchill Khangar static const char cmd_pipeline_commit_help[] =
171075129cebSChurchill Khangar "pipeline <pipeline_name> commit\n";
171175129cebSChurchill Khangar 
171275129cebSChurchill Khangar static void
171375129cebSChurchill Khangar cmd_pipeline_commit(char **tokens,
171475129cebSChurchill Khangar 	uint32_t n_tokens,
171575129cebSChurchill Khangar 	char *out,
171675129cebSChurchill Khangar 	size_t out_size,
1717*b9559f94SCristian Dumitrescu 	void *obj __rte_unused)
171875129cebSChurchill Khangar {
1719*b9559f94SCristian Dumitrescu 	struct rte_swx_ctl_pipeline *ctl;
172075129cebSChurchill Khangar 	char *pipeline_name;
172175129cebSChurchill Khangar 	int status;
172275129cebSChurchill Khangar 
172375129cebSChurchill Khangar 	if (n_tokens != 3) {
172475129cebSChurchill Khangar 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
172575129cebSChurchill Khangar 		return;
172675129cebSChurchill Khangar 	}
172775129cebSChurchill Khangar 
172875129cebSChurchill Khangar 	pipeline_name = tokens[1];
1729*b9559f94SCristian Dumitrescu 	ctl = rte_swx_ctl_pipeline_find(pipeline_name);
1730*b9559f94SCristian Dumitrescu 	if (!ctl) {
173175129cebSChurchill Khangar 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
173275129cebSChurchill Khangar 		return;
17335074e1d5SCristian Dumitrescu 	}
17345074e1d5SCristian Dumitrescu 
1735*b9559f94SCristian Dumitrescu 	status = rte_swx_ctl_pipeline_commit(ctl, 1);
173675129cebSChurchill Khangar 	if (status)
173775129cebSChurchill Khangar 		snprintf(out, out_size, "Commit failed. "
173875129cebSChurchill Khangar 			"Use \"commit\" to retry or \"abort\" to discard the pending work.\n");
17395074e1d5SCristian Dumitrescu }
17405074e1d5SCristian Dumitrescu 
174175129cebSChurchill Khangar static const char cmd_pipeline_abort_help[] =
174275129cebSChurchill Khangar "pipeline <pipeline_name> abort\n";
17435074e1d5SCristian Dumitrescu 
174475129cebSChurchill Khangar static void
174575129cebSChurchill Khangar cmd_pipeline_abort(char **tokens,
174675129cebSChurchill Khangar 	uint32_t n_tokens,
174775129cebSChurchill Khangar 	char *out,
174875129cebSChurchill Khangar 	size_t out_size,
1749*b9559f94SCristian Dumitrescu 	void *obj __rte_unused)
175075129cebSChurchill Khangar {
1751*b9559f94SCristian Dumitrescu 	struct rte_swx_ctl_pipeline *ctl;
175275129cebSChurchill Khangar 	char *pipeline_name;
17535074e1d5SCristian Dumitrescu 
175475129cebSChurchill Khangar 	if (n_tokens != 3) {
175575129cebSChurchill Khangar 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
17565074e1d5SCristian Dumitrescu 		return;
175775129cebSChurchill Khangar 	}
17585074e1d5SCristian Dumitrescu 
175975129cebSChurchill Khangar 	pipeline_name = tokens[1];
1760*b9559f94SCristian Dumitrescu 	ctl = rte_swx_ctl_pipeline_find(pipeline_name);
1761*b9559f94SCristian Dumitrescu 	if (!ctl) {
176275129cebSChurchill Khangar 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
176375129cebSChurchill Khangar 		return;
176475129cebSChurchill Khangar 	}
176575129cebSChurchill Khangar 
1766*b9559f94SCristian Dumitrescu 	rte_swx_ctl_pipeline_abort(ctl);
17675074e1d5SCristian Dumitrescu }
17685074e1d5SCristian Dumitrescu 
176964cfcebdSCristian Dumitrescu static const char cmd_pipeline_regrd_help[] =
177064cfcebdSCristian Dumitrescu "pipeline <pipeline_name> regrd <register_array_name> <index>\n";
177164cfcebdSCristian Dumitrescu 
177264cfcebdSCristian Dumitrescu static void
177364cfcebdSCristian Dumitrescu cmd_pipeline_regrd(char **tokens,
177464cfcebdSCristian Dumitrescu 	uint32_t n_tokens,
177564cfcebdSCristian Dumitrescu 	char *out,
177664cfcebdSCristian Dumitrescu 	size_t out_size,
1777*b9559f94SCristian Dumitrescu 	void *obj __rte_unused)
177864cfcebdSCristian Dumitrescu {
1779*b9559f94SCristian Dumitrescu 	struct rte_swx_pipeline *p;
178064cfcebdSCristian Dumitrescu 	const char *name;
178164cfcebdSCristian Dumitrescu 	uint64_t value;
178264cfcebdSCristian Dumitrescu 	uint32_t idx;
178364cfcebdSCristian Dumitrescu 	int status;
178464cfcebdSCristian Dumitrescu 
178564cfcebdSCristian Dumitrescu 	if (n_tokens != 5) {
178664cfcebdSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
178764cfcebdSCristian Dumitrescu 		return;
178864cfcebdSCristian Dumitrescu 	}
178964cfcebdSCristian Dumitrescu 
1790*b9559f94SCristian Dumitrescu 	p = rte_swx_pipeline_find(tokens[1]);
1791*b9559f94SCristian Dumitrescu 	if (!p) {
179264cfcebdSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
179364cfcebdSCristian Dumitrescu 		return;
179464cfcebdSCristian Dumitrescu 	}
179564cfcebdSCristian Dumitrescu 
179664cfcebdSCristian Dumitrescu 	if (strcmp(tokens[2], "regrd")) {
179764cfcebdSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "regrd");
179864cfcebdSCristian Dumitrescu 		return;
179964cfcebdSCristian Dumitrescu 	}
180064cfcebdSCristian Dumitrescu 
180164cfcebdSCristian Dumitrescu 	name = tokens[3];
180264cfcebdSCristian Dumitrescu 
180364cfcebdSCristian Dumitrescu 	if (parser_read_uint32(&idx, tokens[4])) {
180464cfcebdSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "index");
180564cfcebdSCristian Dumitrescu 		return;
180664cfcebdSCristian Dumitrescu 	}
180764cfcebdSCristian Dumitrescu 
1808*b9559f94SCristian Dumitrescu 	status = rte_swx_ctl_pipeline_regarray_read(p, name, idx, &value);
180964cfcebdSCristian Dumitrescu 	if (status) {
181064cfcebdSCristian Dumitrescu 		snprintf(out, out_size, "Command failed.\n");
181164cfcebdSCristian Dumitrescu 		return;
181264cfcebdSCristian Dumitrescu 	}
181364cfcebdSCristian Dumitrescu 
181464cfcebdSCristian Dumitrescu 	snprintf(out, out_size, "0x%" PRIx64 "\n", value);
181564cfcebdSCristian Dumitrescu }
181664cfcebdSCristian Dumitrescu 
181764cfcebdSCristian Dumitrescu static const char cmd_pipeline_regwr_help[] =
181864cfcebdSCristian Dumitrescu "pipeline <pipeline_name> regwr <register_array_name> <index> <value>\n";
181964cfcebdSCristian Dumitrescu 
182064cfcebdSCristian Dumitrescu static void
182164cfcebdSCristian Dumitrescu cmd_pipeline_regwr(char **tokens,
182264cfcebdSCristian Dumitrescu 	uint32_t n_tokens,
182364cfcebdSCristian Dumitrescu 	char *out,
182464cfcebdSCristian Dumitrescu 	size_t out_size,
1825*b9559f94SCristian Dumitrescu 	void *obj __rte_unused)
182664cfcebdSCristian Dumitrescu {
1827*b9559f94SCristian Dumitrescu 	struct rte_swx_pipeline *p;
182864cfcebdSCristian Dumitrescu 	const char *name;
182964cfcebdSCristian Dumitrescu 	uint64_t value;
183064cfcebdSCristian Dumitrescu 	uint32_t idx;
183164cfcebdSCristian Dumitrescu 	int status;
183264cfcebdSCristian Dumitrescu 
183364cfcebdSCristian Dumitrescu 	if (n_tokens != 6) {
183464cfcebdSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
183564cfcebdSCristian Dumitrescu 		return;
183664cfcebdSCristian Dumitrescu 	}
183764cfcebdSCristian Dumitrescu 
1838*b9559f94SCristian Dumitrescu 	p = rte_swx_pipeline_find(tokens[1]);
1839*b9559f94SCristian Dumitrescu 	if (!p) {
184064cfcebdSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
184164cfcebdSCristian Dumitrescu 		return;
184264cfcebdSCristian Dumitrescu 	}
184364cfcebdSCristian Dumitrescu 
184464cfcebdSCristian Dumitrescu 	if (strcmp(tokens[2], "regwr")) {
184564cfcebdSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "regwr");
184664cfcebdSCristian Dumitrescu 		return;
184764cfcebdSCristian Dumitrescu 	}
184864cfcebdSCristian Dumitrescu 
184964cfcebdSCristian Dumitrescu 	name = tokens[3];
185064cfcebdSCristian Dumitrescu 
185164cfcebdSCristian Dumitrescu 	if (parser_read_uint32(&idx, tokens[4])) {
185264cfcebdSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "index");
185364cfcebdSCristian Dumitrescu 		return;
185464cfcebdSCristian Dumitrescu 	}
185564cfcebdSCristian Dumitrescu 
185664cfcebdSCristian Dumitrescu 	if (parser_read_uint64(&value, tokens[5])) {
185764cfcebdSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "value");
185864cfcebdSCristian Dumitrescu 		return;
185964cfcebdSCristian Dumitrescu 	}
186064cfcebdSCristian Dumitrescu 
1861*b9559f94SCristian Dumitrescu 	status = rte_swx_ctl_pipeline_regarray_write(p, name, idx, value);
186264cfcebdSCristian Dumitrescu 	if (status) {
186364cfcebdSCristian Dumitrescu 		snprintf(out, out_size, "Command failed.\n");
186464cfcebdSCristian Dumitrescu 		return;
186564cfcebdSCristian Dumitrescu 	}
186664cfcebdSCristian Dumitrescu }
186764cfcebdSCristian Dumitrescu 
1868f38913b7SCristian Dumitrescu static const char cmd_pipeline_meter_profile_add_help[] =
1869f38913b7SCristian Dumitrescu "pipeline <pipeline_name> meter profile <profile_name> add "
1870f38913b7SCristian Dumitrescu 	"cir <cir> pir <pir> cbs <cbs> pbs <pbs>\n";
1871f38913b7SCristian Dumitrescu 
1872f38913b7SCristian Dumitrescu static void
1873f38913b7SCristian Dumitrescu cmd_pipeline_meter_profile_add(char **tokens,
1874f38913b7SCristian Dumitrescu 	uint32_t n_tokens,
1875f38913b7SCristian Dumitrescu 	char *out,
1876f38913b7SCristian Dumitrescu 	size_t out_size,
1877*b9559f94SCristian Dumitrescu 	void *obj __rte_unused)
1878f38913b7SCristian Dumitrescu {
1879f38913b7SCristian Dumitrescu 	struct rte_meter_trtcm_params params;
1880*b9559f94SCristian Dumitrescu 	struct rte_swx_pipeline *p;
1881f38913b7SCristian Dumitrescu 	const char *profile_name;
1882f38913b7SCristian Dumitrescu 	int status;
1883f38913b7SCristian Dumitrescu 
1884f38913b7SCristian Dumitrescu 	if (n_tokens != 14) {
1885f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1886f38913b7SCristian Dumitrescu 		return;
1887f38913b7SCristian Dumitrescu 	}
1888f38913b7SCristian Dumitrescu 
1889*b9559f94SCristian Dumitrescu 	p = rte_swx_pipeline_find(tokens[1]);
1890*b9559f94SCristian Dumitrescu 	if (!p) {
1891f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
1892f38913b7SCristian Dumitrescu 		return;
1893f38913b7SCristian Dumitrescu 	}
1894f38913b7SCristian Dumitrescu 
1895f38913b7SCristian Dumitrescu 	if (strcmp(tokens[2], "meter")) {
1896f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "meter");
1897f38913b7SCristian Dumitrescu 		return;
1898f38913b7SCristian Dumitrescu 	}
1899f38913b7SCristian Dumitrescu 
1900f38913b7SCristian Dumitrescu 	if (strcmp(tokens[3], "profile")) {
1901f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "profile");
1902f38913b7SCristian Dumitrescu 		return;
1903f38913b7SCristian Dumitrescu 	}
1904f38913b7SCristian Dumitrescu 
1905f38913b7SCristian Dumitrescu 	profile_name = tokens[4];
1906f38913b7SCristian Dumitrescu 
1907f38913b7SCristian Dumitrescu 	if (strcmp(tokens[5], "add")) {
1908f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "add");
1909f38913b7SCristian Dumitrescu 		return;
1910f38913b7SCristian Dumitrescu 	}
1911f38913b7SCristian Dumitrescu 
1912f38913b7SCristian Dumitrescu 	if (strcmp(tokens[6], "cir")) {
1913f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cir");
1914f38913b7SCristian Dumitrescu 		return;
1915f38913b7SCristian Dumitrescu 	}
1916f38913b7SCristian Dumitrescu 
1917f38913b7SCristian Dumitrescu 	if (parser_read_uint64(&params.cir, tokens[7])) {
1918f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "cir");
1919f38913b7SCristian Dumitrescu 		return;
1920f38913b7SCristian Dumitrescu 	}
1921f38913b7SCristian Dumitrescu 
1922f38913b7SCristian Dumitrescu 	if (strcmp(tokens[8], "pir")) {
1923f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pir");
1924f38913b7SCristian Dumitrescu 		return;
1925f38913b7SCristian Dumitrescu 	}
1926f38913b7SCristian Dumitrescu 
1927f38913b7SCristian Dumitrescu 	if (parser_read_uint64(&params.pir, tokens[9])) {
1928f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pir");
1929f38913b7SCristian Dumitrescu 		return;
1930f38913b7SCristian Dumitrescu 	}
1931f38913b7SCristian Dumitrescu 
1932f38913b7SCristian Dumitrescu 	if (strcmp(tokens[10], "cbs")) {
1933f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cbs");
1934f38913b7SCristian Dumitrescu 		return;
1935f38913b7SCristian Dumitrescu 	}
1936f38913b7SCristian Dumitrescu 
1937f38913b7SCristian Dumitrescu 	if (parser_read_uint64(&params.cbs, tokens[11])) {
1938f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "cbs");
1939f38913b7SCristian Dumitrescu 		return;
1940f38913b7SCristian Dumitrescu 	}
1941f38913b7SCristian Dumitrescu 
1942f38913b7SCristian Dumitrescu 	if (strcmp(tokens[12], "pbs")) {
1943f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pbs");
1944f38913b7SCristian Dumitrescu 		return;
1945f38913b7SCristian Dumitrescu 	}
1946f38913b7SCristian Dumitrescu 
1947f38913b7SCristian Dumitrescu 	if (parser_read_uint64(&params.pbs, tokens[13])) {
1948f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pbs");
1949f38913b7SCristian Dumitrescu 		return;
1950f38913b7SCristian Dumitrescu 	}
1951f38913b7SCristian Dumitrescu 
1952*b9559f94SCristian Dumitrescu 	status = rte_swx_ctl_meter_profile_add(p, profile_name, &params);
1953f38913b7SCristian Dumitrescu 	if (status) {
1954f38913b7SCristian Dumitrescu 		snprintf(out, out_size, "Command failed.\n");
1955f38913b7SCristian Dumitrescu 		return;
1956f38913b7SCristian Dumitrescu 	}
1957f38913b7SCristian Dumitrescu }
1958f38913b7SCristian Dumitrescu 
1959f38913b7SCristian Dumitrescu static const char cmd_pipeline_meter_profile_delete_help[] =
1960f38913b7SCristian Dumitrescu "pipeline <pipeline_name> meter profile <profile_name> delete\n";
1961f38913b7SCristian Dumitrescu 
1962f38913b7SCristian Dumitrescu static void
1963f38913b7SCristian Dumitrescu cmd_pipeline_meter_profile_delete(char **tokens,
1964f38913b7SCristian Dumitrescu 	uint32_t n_tokens,
1965f38913b7SCristian Dumitrescu 	char *out,
1966f38913b7SCristian Dumitrescu 	size_t out_size,
1967*b9559f94SCristian Dumitrescu 	void *obj __rte_unused)
1968f38913b7SCristian Dumitrescu {
1969*b9559f94SCristian Dumitrescu 	struct rte_swx_pipeline *p;
1970f38913b7SCristian Dumitrescu 	const char *profile_name;
1971f38913b7SCristian Dumitrescu 	int status;
1972f38913b7SCristian Dumitrescu 
1973f38913b7SCristian Dumitrescu 	if (n_tokens != 6) {
1974f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1975f38913b7SCristian Dumitrescu 		return;
1976f38913b7SCristian Dumitrescu 	}
1977f38913b7SCristian Dumitrescu 
1978*b9559f94SCristian Dumitrescu 	p = rte_swx_pipeline_find(tokens[1]);
1979*b9559f94SCristian Dumitrescu 	if (!p) {
1980f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
1981f38913b7SCristian Dumitrescu 		return;
1982f38913b7SCristian Dumitrescu 	}
1983f38913b7SCristian Dumitrescu 
1984f38913b7SCristian Dumitrescu 	if (strcmp(tokens[2], "meter")) {
1985f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "meter");
1986f38913b7SCristian Dumitrescu 		return;
1987f38913b7SCristian Dumitrescu 	}
1988f38913b7SCristian Dumitrescu 
1989f38913b7SCristian Dumitrescu 	if (strcmp(tokens[3], "profile")) {
1990f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "profile");
1991f38913b7SCristian Dumitrescu 		return;
1992f38913b7SCristian Dumitrescu 	}
1993f38913b7SCristian Dumitrescu 
1994f38913b7SCristian Dumitrescu 	profile_name = tokens[4];
1995f38913b7SCristian Dumitrescu 
1996f38913b7SCristian Dumitrescu 	if (strcmp(tokens[5], "delete")) {
1997f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "delete");
1998f38913b7SCristian Dumitrescu 		return;
1999f38913b7SCristian Dumitrescu 	}
2000f38913b7SCristian Dumitrescu 
2001*b9559f94SCristian Dumitrescu 	status = rte_swx_ctl_meter_profile_delete(p, profile_name);
2002f38913b7SCristian Dumitrescu 	if (status) {
2003f38913b7SCristian Dumitrescu 		snprintf(out, out_size, "Command failed.\n");
2004f38913b7SCristian Dumitrescu 		return;
2005f38913b7SCristian Dumitrescu 	}
2006f38913b7SCristian Dumitrescu }
2007f38913b7SCristian Dumitrescu 
2008f38913b7SCristian Dumitrescu static const char cmd_pipeline_meter_reset_help[] =
2009f38913b7SCristian Dumitrescu "pipeline <pipeline_name> meter <meter_array_name> from <index0> to <index1> "
2010f38913b7SCristian Dumitrescu 	"reset\n";
2011f38913b7SCristian Dumitrescu 
2012f38913b7SCristian Dumitrescu static void
2013f38913b7SCristian Dumitrescu cmd_pipeline_meter_reset(char **tokens,
2014f38913b7SCristian Dumitrescu 	uint32_t n_tokens,
2015f38913b7SCristian Dumitrescu 	char *out,
2016f38913b7SCristian Dumitrescu 	size_t out_size,
2017*b9559f94SCristian Dumitrescu 	void *obj __rte_unused)
2018f38913b7SCristian Dumitrescu {
2019*b9559f94SCristian Dumitrescu 	struct rte_swx_pipeline *p;
2020f38913b7SCristian Dumitrescu 	const char *name;
202100b67591SAli Alnubani 	uint32_t idx0 = 0, idx1 = 0;
2022f38913b7SCristian Dumitrescu 
2023f38913b7SCristian Dumitrescu 	if (n_tokens != 9) {
2024f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2025f38913b7SCristian Dumitrescu 		return;
2026f38913b7SCristian Dumitrescu 	}
2027f38913b7SCristian Dumitrescu 
2028*b9559f94SCristian Dumitrescu 	p = rte_swx_pipeline_find(tokens[1]);
2029*b9559f94SCristian Dumitrescu 	if (!p) {
2030f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
2031f38913b7SCristian Dumitrescu 		return;
2032f38913b7SCristian Dumitrescu 	}
2033f38913b7SCristian Dumitrescu 
2034f38913b7SCristian Dumitrescu 	if (strcmp(tokens[2], "meter")) {
2035f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "meter");
2036f38913b7SCristian Dumitrescu 		return;
2037f38913b7SCristian Dumitrescu 	}
2038f38913b7SCristian Dumitrescu 
2039f38913b7SCristian Dumitrescu 	name = tokens[3];
2040f38913b7SCristian Dumitrescu 
2041f38913b7SCristian Dumitrescu 	if (strcmp(tokens[4], "from")) {
2042f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "from");
2043f38913b7SCristian Dumitrescu 		return;
2044f38913b7SCristian Dumitrescu 	}
2045f38913b7SCristian Dumitrescu 
2046f38913b7SCristian Dumitrescu 	if (parser_read_uint32(&idx0, tokens[5])) {
2047f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "index0");
2048f38913b7SCristian Dumitrescu 		return;
2049f38913b7SCristian Dumitrescu 	}
2050f38913b7SCristian Dumitrescu 
2051f38913b7SCristian Dumitrescu 	if (strcmp(tokens[6], "to")) {
2052f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "to");
2053f38913b7SCristian Dumitrescu 		return;
2054f38913b7SCristian Dumitrescu 	}
2055f38913b7SCristian Dumitrescu 
2056f38913b7SCristian Dumitrescu 	if (parser_read_uint32(&idx1, tokens[7]) || (idx1 < idx0)) {
2057f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "index1");
2058f38913b7SCristian Dumitrescu 		return;
2059f38913b7SCristian Dumitrescu 	}
2060f38913b7SCristian Dumitrescu 
2061f38913b7SCristian Dumitrescu 	if (strcmp(tokens[8], "reset")) {
2062f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "reset");
2063f38913b7SCristian Dumitrescu 		return;
2064f38913b7SCristian Dumitrescu 	}
2065f38913b7SCristian Dumitrescu 
2066f38913b7SCristian Dumitrescu 	for ( ; idx0 <= idx1; idx0++) {
2067f38913b7SCristian Dumitrescu 		int status;
2068f38913b7SCristian Dumitrescu 
2069*b9559f94SCristian Dumitrescu 		status = rte_swx_ctl_meter_reset(p, name, idx0);
2070f38913b7SCristian Dumitrescu 		if (status) {
2071f38913b7SCristian Dumitrescu 			snprintf(out, out_size, "Command failed for index %u.\n", idx0);
2072f38913b7SCristian Dumitrescu 			return;
2073f38913b7SCristian Dumitrescu 		}
2074f38913b7SCristian Dumitrescu 	}
2075f38913b7SCristian Dumitrescu }
2076f38913b7SCristian Dumitrescu 
2077f38913b7SCristian Dumitrescu static const char cmd_pipeline_meter_set_help[] =
2078f38913b7SCristian Dumitrescu "pipeline <pipeline_name> meter <meter_array_name> from <index0> to <index1> "
2079f38913b7SCristian Dumitrescu 	"set profile <profile_name>\n";
2080f38913b7SCristian Dumitrescu 
2081f38913b7SCristian Dumitrescu static void
2082f38913b7SCristian Dumitrescu cmd_pipeline_meter_set(char **tokens,
2083f38913b7SCristian Dumitrescu 	uint32_t n_tokens,
2084f38913b7SCristian Dumitrescu 	char *out,
2085f38913b7SCristian Dumitrescu 	size_t out_size,
2086*b9559f94SCristian Dumitrescu 	void *obj __rte_unused)
2087f38913b7SCristian Dumitrescu {
2088*b9559f94SCristian Dumitrescu 	struct rte_swx_pipeline *p;
2089f38913b7SCristian Dumitrescu 	const char *name, *profile_name;
209000b67591SAli Alnubani 	uint32_t idx0 = 0, idx1 = 0;
2091f38913b7SCristian Dumitrescu 
2092f38913b7SCristian Dumitrescu 	if (n_tokens != 11) {
2093f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2094f38913b7SCristian Dumitrescu 		return;
2095f38913b7SCristian Dumitrescu 	}
2096f38913b7SCristian Dumitrescu 
2097*b9559f94SCristian Dumitrescu 	p = rte_swx_pipeline_find(tokens[1]);
2098*b9559f94SCristian Dumitrescu 	if (!p) {
2099f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
2100f38913b7SCristian Dumitrescu 		return;
2101f38913b7SCristian Dumitrescu 	}
2102f38913b7SCristian Dumitrescu 
2103f38913b7SCristian Dumitrescu 	if (strcmp(tokens[2], "meter")) {
2104f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "meter");
2105f38913b7SCristian Dumitrescu 		return;
2106f38913b7SCristian Dumitrescu 	}
2107f38913b7SCristian Dumitrescu 
2108f38913b7SCristian Dumitrescu 	name = tokens[3];
2109f38913b7SCristian Dumitrescu 
2110f38913b7SCristian Dumitrescu 	if (strcmp(tokens[4], "from")) {
2111f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "from");
2112f38913b7SCristian Dumitrescu 		return;
2113f38913b7SCristian Dumitrescu 	}
2114f38913b7SCristian Dumitrescu 
2115f38913b7SCristian Dumitrescu 	if (parser_read_uint32(&idx0, tokens[5])) {
2116f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "index0");
2117f38913b7SCristian Dumitrescu 		return;
2118f38913b7SCristian Dumitrescu 	}
2119f38913b7SCristian Dumitrescu 
2120f38913b7SCristian Dumitrescu 	if (strcmp(tokens[6], "to")) {
2121f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "to");
2122f38913b7SCristian Dumitrescu 		return;
2123f38913b7SCristian Dumitrescu 	}
2124f38913b7SCristian Dumitrescu 
2125f38913b7SCristian Dumitrescu 	if (parser_read_uint32(&idx1, tokens[7]) || (idx1 < idx0)) {
2126f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "index1");
2127f38913b7SCristian Dumitrescu 		return;
2128f38913b7SCristian Dumitrescu 	}
2129f38913b7SCristian Dumitrescu 
2130f38913b7SCristian Dumitrescu 	if (strcmp(tokens[8], "set")) {
2131f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "set");
2132f38913b7SCristian Dumitrescu 		return;
2133f38913b7SCristian Dumitrescu 	}
2134f38913b7SCristian Dumitrescu 
2135f38913b7SCristian Dumitrescu 	if (strcmp(tokens[9], "profile")) {
2136f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "profile");
2137f38913b7SCristian Dumitrescu 		return;
2138f38913b7SCristian Dumitrescu 	}
2139f38913b7SCristian Dumitrescu 
2140f38913b7SCristian Dumitrescu 	profile_name = tokens[10];
2141f38913b7SCristian Dumitrescu 
2142f38913b7SCristian Dumitrescu 	for ( ; idx0 <= idx1; idx0++) {
2143f38913b7SCristian Dumitrescu 		int status;
2144f38913b7SCristian Dumitrescu 
2145*b9559f94SCristian Dumitrescu 		status = rte_swx_ctl_meter_set(p, name, idx0, profile_name);
2146f38913b7SCristian Dumitrescu 		if (status) {
2147f38913b7SCristian Dumitrescu 			snprintf(out, out_size, "Command failed for index %u.\n", idx0);
2148f38913b7SCristian Dumitrescu 			return;
2149f38913b7SCristian Dumitrescu 		}
2150f38913b7SCristian Dumitrescu 	}
2151f38913b7SCristian Dumitrescu }
2152f38913b7SCristian Dumitrescu 
2153f38913b7SCristian Dumitrescu static const char cmd_pipeline_meter_stats_help[] =
2154f38913b7SCristian Dumitrescu "pipeline <pipeline_name> meter <meter_array_name> from <index0> to <index1> "
2155f38913b7SCristian Dumitrescu 	"stats\n";
2156f38913b7SCristian Dumitrescu 
2157f38913b7SCristian Dumitrescu static void
2158f38913b7SCristian Dumitrescu cmd_pipeline_meter_stats(char **tokens,
2159f38913b7SCristian Dumitrescu 	uint32_t n_tokens,
2160f38913b7SCristian Dumitrescu 	char *out,
2161f38913b7SCristian Dumitrescu 	size_t out_size,
2162*b9559f94SCristian Dumitrescu 	void *obj __rte_unused)
2163f38913b7SCristian Dumitrescu {
2164f38913b7SCristian Dumitrescu 	struct rte_swx_ctl_meter_stats stats;
2165*b9559f94SCristian Dumitrescu 	struct rte_swx_pipeline *p;
2166f38913b7SCristian Dumitrescu 	const char *name;
216700b67591SAli Alnubani 	uint32_t idx0 = 0, idx1 = 0;
2168f38913b7SCristian Dumitrescu 
2169f38913b7SCristian Dumitrescu 	if (n_tokens != 9) {
2170f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2171f38913b7SCristian Dumitrescu 		return;
2172f38913b7SCristian Dumitrescu 	}
2173f38913b7SCristian Dumitrescu 
2174*b9559f94SCristian Dumitrescu 	p = rte_swx_pipeline_find(tokens[1]);
2175*b9559f94SCristian Dumitrescu 	if (!p) {
2176f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
2177f38913b7SCristian Dumitrescu 		return;
2178f38913b7SCristian Dumitrescu 	}
2179f38913b7SCristian Dumitrescu 
2180f38913b7SCristian Dumitrescu 	if (strcmp(tokens[2], "meter")) {
2181f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "meter");
2182f38913b7SCristian Dumitrescu 		return;
2183f38913b7SCristian Dumitrescu 	}
2184f38913b7SCristian Dumitrescu 
2185f38913b7SCristian Dumitrescu 	name = tokens[3];
2186f38913b7SCristian Dumitrescu 
2187f38913b7SCristian Dumitrescu 	if (strcmp(tokens[4], "from")) {
2188f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "from");
2189f38913b7SCristian Dumitrescu 		return;
2190f38913b7SCristian Dumitrescu 	}
2191f38913b7SCristian Dumitrescu 
2192f38913b7SCristian Dumitrescu 	if (parser_read_uint32(&idx0, tokens[5])) {
2193f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "index0");
2194f38913b7SCristian Dumitrescu 		return;
2195f38913b7SCristian Dumitrescu 	}
2196f38913b7SCristian Dumitrescu 
2197f38913b7SCristian Dumitrescu 	if (strcmp(tokens[6], "to")) {
2198f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "to");
2199f38913b7SCristian Dumitrescu 		return;
2200f38913b7SCristian Dumitrescu 	}
2201f38913b7SCristian Dumitrescu 
2202f38913b7SCristian Dumitrescu 	if (parser_read_uint32(&idx1, tokens[7]) || (idx1 < idx0)) {
2203f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "index1");
2204f38913b7SCristian Dumitrescu 		return;
2205f38913b7SCristian Dumitrescu 	}
2206f38913b7SCristian Dumitrescu 
2207f38913b7SCristian Dumitrescu 	if (strcmp(tokens[8], "stats")) {
2208f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "stats");
2209f38913b7SCristian Dumitrescu 		return;
2210f38913b7SCristian Dumitrescu 	}
2211f38913b7SCristian Dumitrescu 
2212f38913b7SCristian Dumitrescu 	/* Table header. */
2213f38913b7SCristian Dumitrescu 	snprintf(out, out_size, "+-%7s-+-%16s-+-%16s-+-%16s-+-%16s-+-%16s-+-%16s-+\n",
2214f38913b7SCristian Dumitrescu 		 "-------",
2215f38913b7SCristian Dumitrescu 		 "----------------", "----------------", "----------------",
2216f38913b7SCristian Dumitrescu 		 "----------------", "----------------", "----------------");
2217f38913b7SCristian Dumitrescu 	out_size -= strlen(out);
2218f38913b7SCristian Dumitrescu 	out += strlen(out);
2219f38913b7SCristian Dumitrescu 
2220f38913b7SCristian Dumitrescu 	snprintf(out, out_size, "| %4s | %16s | %16s | %16s | %16s | %16s | %16s |\n",
2221f38913b7SCristian Dumitrescu 		 "METER #",
2222f38913b7SCristian Dumitrescu 		 "GREEN (packets)", "YELLOW (packets)", "RED (packets)",
2223f38913b7SCristian Dumitrescu 		 "GREEN (bytes)", "YELLOW (bytes)", "RED (bytes)");
2224f38913b7SCristian Dumitrescu 	out_size -= strlen(out);
2225f38913b7SCristian Dumitrescu 	out += strlen(out);
2226f38913b7SCristian Dumitrescu 
2227f38913b7SCristian Dumitrescu 	snprintf(out, out_size, "+-%7s-+-%16s-+-%16s-+-%16s-+-%16s-+-%16s-+-%16s-+\n",
2228f38913b7SCristian Dumitrescu 		 "-------",
2229f38913b7SCristian Dumitrescu 		 "----------------", "----------------", "----------------",
2230f38913b7SCristian Dumitrescu 		 "----------------", "----------------", "----------------");
2231f38913b7SCristian Dumitrescu 	out_size -= strlen(out);
2232f38913b7SCristian Dumitrescu 	out += strlen(out);
2233f38913b7SCristian Dumitrescu 
2234f38913b7SCristian Dumitrescu 	/* Table rows. */
2235f38913b7SCristian Dumitrescu 	for ( ; idx0 <= idx1; idx0++) {
2236f38913b7SCristian Dumitrescu 		int status;
2237f38913b7SCristian Dumitrescu 
2238*b9559f94SCristian Dumitrescu 		status = rte_swx_ctl_meter_stats_read(p, name, idx0, &stats);
2239f38913b7SCristian Dumitrescu 		if (status) {
2240f38913b7SCristian Dumitrescu 			snprintf(out, out_size, "Pipeline meter stats error at index %u.\n", idx0);
2241f38913b7SCristian Dumitrescu 			out_size -= strlen(out);
2242f38913b7SCristian Dumitrescu 			out += strlen(out);
2243f38913b7SCristian Dumitrescu 			return;
2244f38913b7SCristian Dumitrescu 		}
2245f38913b7SCristian Dumitrescu 
2246f38913b7SCristian Dumitrescu 		snprintf(out, out_size, "| %7d | %16" PRIx64 " | %16" PRIx64 " | %16" PRIx64
2247f38913b7SCristian Dumitrescu 			 " | %16" PRIx64 " | %16" PRIx64 " | %16" PRIx64 " |\n",
2248f38913b7SCristian Dumitrescu 			 idx0,
2249f38913b7SCristian Dumitrescu 			 stats.n_pkts[RTE_COLOR_GREEN],
2250f38913b7SCristian Dumitrescu 			 stats.n_pkts[RTE_COLOR_YELLOW],
2251f38913b7SCristian Dumitrescu 			 stats.n_pkts[RTE_COLOR_RED],
2252f38913b7SCristian Dumitrescu 			 stats.n_bytes[RTE_COLOR_GREEN],
2253f38913b7SCristian Dumitrescu 			 stats.n_bytes[RTE_COLOR_YELLOW],
2254f38913b7SCristian Dumitrescu 			 stats.n_bytes[RTE_COLOR_RED]);
2255f38913b7SCristian Dumitrescu 		out_size -= strlen(out);
2256f38913b7SCristian Dumitrescu 		out += strlen(out);
2257f38913b7SCristian Dumitrescu 	}
2258f38913b7SCristian Dumitrescu }
2259f38913b7SCristian Dumitrescu 
22605074e1d5SCristian Dumitrescu static const char cmd_pipeline_stats_help[] =
22615074e1d5SCristian Dumitrescu "pipeline <pipeline_name> stats\n";
22625074e1d5SCristian Dumitrescu 
22635074e1d5SCristian Dumitrescu static void
22645074e1d5SCristian Dumitrescu cmd_pipeline_stats(char **tokens,
22655074e1d5SCristian Dumitrescu 	uint32_t n_tokens,
22665074e1d5SCristian Dumitrescu 	char *out,
22675074e1d5SCristian Dumitrescu 	size_t out_size,
2268*b9559f94SCristian Dumitrescu 	void *obj __rte_unused)
22695074e1d5SCristian Dumitrescu {
22705074e1d5SCristian Dumitrescu 	struct rte_swx_ctl_pipeline_info info;
2271*b9559f94SCristian Dumitrescu 	struct rte_swx_pipeline *p;
22725074e1d5SCristian Dumitrescu 	uint32_t i;
22735074e1d5SCristian Dumitrescu 	int status;
22745074e1d5SCristian Dumitrescu 
22755074e1d5SCristian Dumitrescu 	if (n_tokens != 3) {
22765074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
22775074e1d5SCristian Dumitrescu 		return;
22785074e1d5SCristian Dumitrescu 	}
22795074e1d5SCristian Dumitrescu 
2280*b9559f94SCristian Dumitrescu 	p = rte_swx_pipeline_find(tokens[1]);
2281*b9559f94SCristian Dumitrescu 	if (!p) {
22825074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
22835074e1d5SCristian Dumitrescu 		return;
22845074e1d5SCristian Dumitrescu 	}
22855074e1d5SCristian Dumitrescu 
22865074e1d5SCristian Dumitrescu 	if (strcmp(tokens[2], "stats")) {
22875074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "stats");
22885074e1d5SCristian Dumitrescu 		return;
22895074e1d5SCristian Dumitrescu 	}
22905074e1d5SCristian Dumitrescu 
2291*b9559f94SCristian Dumitrescu 	status = rte_swx_ctl_pipeline_info_get(p, &info);
22925074e1d5SCristian Dumitrescu 	if (status) {
22935074e1d5SCristian Dumitrescu 		snprintf(out, out_size, "Pipeline info get error.");
22945074e1d5SCristian Dumitrescu 		return;
22955074e1d5SCristian Dumitrescu 	}
22965074e1d5SCristian Dumitrescu 
22975074e1d5SCristian Dumitrescu 	snprintf(out, out_size, "Input ports:\n");
22985074e1d5SCristian Dumitrescu 	out_size -= strlen(out);
22995074e1d5SCristian Dumitrescu 	out += strlen(out);
23005074e1d5SCristian Dumitrescu 
23015074e1d5SCristian Dumitrescu 	for (i = 0; i < info.n_ports_in; i++) {
23025074e1d5SCristian Dumitrescu 		struct rte_swx_port_in_stats stats;
23035074e1d5SCristian Dumitrescu 
2304*b9559f94SCristian Dumitrescu 		rte_swx_ctl_pipeline_port_in_stats_read(p, i, &stats);
23055074e1d5SCristian Dumitrescu 
23065074e1d5SCristian Dumitrescu 		snprintf(out, out_size, "\tPort %u:"
23075074e1d5SCristian Dumitrescu 			" packets %" PRIu64
23085074e1d5SCristian Dumitrescu 			" bytes %" PRIu64
23095074e1d5SCristian Dumitrescu 			" empty %" PRIu64 "\n",
23105074e1d5SCristian Dumitrescu 			i, stats.n_pkts, stats.n_bytes, stats.n_empty);
23115074e1d5SCristian Dumitrescu 		out_size -= strlen(out);
23125074e1d5SCristian Dumitrescu 		out += strlen(out);
23135074e1d5SCristian Dumitrescu 	}
23145074e1d5SCristian Dumitrescu 
2315742b0a57SCristian Dumitrescu 	snprintf(out, out_size, "\nOutput ports:\n");
23165074e1d5SCristian Dumitrescu 	out_size -= strlen(out);
23175074e1d5SCristian Dumitrescu 	out += strlen(out);
23185074e1d5SCristian Dumitrescu 
23195074e1d5SCristian Dumitrescu 	for (i = 0; i < info.n_ports_out; i++) {
23205074e1d5SCristian Dumitrescu 		struct rte_swx_port_out_stats stats;
23215074e1d5SCristian Dumitrescu 
2322*b9559f94SCristian Dumitrescu 		rte_swx_ctl_pipeline_port_out_stats_read(p, i, &stats);
23235074e1d5SCristian Dumitrescu 
232496b37959SCristian Dumitrescu 		if (i != info.n_ports_out - 1)
232517225455SCristian Dumitrescu 			snprintf(out, out_size, "\tPort %u:", i);
232696b37959SCristian Dumitrescu 		else
232717225455SCristian Dumitrescu 			snprintf(out, out_size, "\tDROP:");
232817225455SCristian Dumitrescu 
232917225455SCristian Dumitrescu 		out_size -= strlen(out);
233017225455SCristian Dumitrescu 		out += strlen(out);
233117225455SCristian Dumitrescu 
233217225455SCristian Dumitrescu 		snprintf(out,
233317225455SCristian Dumitrescu 			out_size,
233496b37959SCristian Dumitrescu 			" packets %" PRIu64
233517225455SCristian Dumitrescu 			" bytes %" PRIu64
233617225455SCristian Dumitrescu 			" clone %" PRIu64
233717225455SCristian Dumitrescu 			" clonerr %" PRIu64 "\n",
233817225455SCristian Dumitrescu 			stats.n_pkts,
233917225455SCristian Dumitrescu 			stats.n_bytes,
234017225455SCristian Dumitrescu 			stats.n_pkts_clone,
234117225455SCristian Dumitrescu 			stats.n_pkts_clone_err);
234296b37959SCristian Dumitrescu 
23435074e1d5SCristian Dumitrescu 		out_size -= strlen(out);
23445074e1d5SCristian Dumitrescu 		out += strlen(out);
23455074e1d5SCristian Dumitrescu 	}
2346742b0a57SCristian Dumitrescu 
2347742b0a57SCristian Dumitrescu 	snprintf(out, out_size, "\nTables:\n");
2348742b0a57SCristian Dumitrescu 	out_size -= strlen(out);
2349742b0a57SCristian Dumitrescu 	out += strlen(out);
2350742b0a57SCristian Dumitrescu 
2351742b0a57SCristian Dumitrescu 	for (i = 0; i < info.n_tables; i++) {
2352742b0a57SCristian Dumitrescu 		struct rte_swx_ctl_table_info table_info;
2353742b0a57SCristian Dumitrescu 		uint64_t n_pkts_action[info.n_actions];
2354742b0a57SCristian Dumitrescu 		struct rte_swx_table_stats stats = {
2355742b0a57SCristian Dumitrescu 			.n_pkts_hit = 0,
2356742b0a57SCristian Dumitrescu 			.n_pkts_miss = 0,
2357742b0a57SCristian Dumitrescu 			.n_pkts_action = n_pkts_action,
2358742b0a57SCristian Dumitrescu 		};
2359742b0a57SCristian Dumitrescu 		uint32_t j;
2360742b0a57SCristian Dumitrescu 
2361*b9559f94SCristian Dumitrescu 		status = rte_swx_ctl_table_info_get(p, i, &table_info);
2362742b0a57SCristian Dumitrescu 		if (status) {
2363742b0a57SCristian Dumitrescu 			snprintf(out, out_size, "Table info get error.");
2364742b0a57SCristian Dumitrescu 			return;
2365742b0a57SCristian Dumitrescu 		}
2366742b0a57SCristian Dumitrescu 
2367*b9559f94SCristian Dumitrescu 		status = rte_swx_ctl_pipeline_table_stats_read(p, table_info.name, &stats);
2368742b0a57SCristian Dumitrescu 		if (status) {
2369742b0a57SCristian Dumitrescu 			snprintf(out, out_size, "Table stats read error.");
2370742b0a57SCristian Dumitrescu 			return;
2371742b0a57SCristian Dumitrescu 		}
2372742b0a57SCristian Dumitrescu 
2373742b0a57SCristian Dumitrescu 		snprintf(out, out_size, "\tTable %s:\n"
2374742b0a57SCristian Dumitrescu 			"\t\tHit (packets): %" PRIu64 "\n"
2375742b0a57SCristian Dumitrescu 			"\t\tMiss (packets): %" PRIu64 "\n",
2376742b0a57SCristian Dumitrescu 			table_info.name,
2377742b0a57SCristian Dumitrescu 			stats.n_pkts_hit,
2378742b0a57SCristian Dumitrescu 			stats.n_pkts_miss);
2379742b0a57SCristian Dumitrescu 		out_size -= strlen(out);
2380742b0a57SCristian Dumitrescu 		out += strlen(out);
2381742b0a57SCristian Dumitrescu 
2382742b0a57SCristian Dumitrescu 		for (j = 0; j < info.n_actions; j++) {
2383742b0a57SCristian Dumitrescu 			struct rte_swx_ctl_action_info action_info;
2384742b0a57SCristian Dumitrescu 
2385*b9559f94SCristian Dumitrescu 			status = rte_swx_ctl_action_info_get(p, j, &action_info);
2386742b0a57SCristian Dumitrescu 			if (status) {
2387742b0a57SCristian Dumitrescu 				snprintf(out, out_size, "Action info get error.");
2388742b0a57SCristian Dumitrescu 				return;
2389742b0a57SCristian Dumitrescu 			}
2390742b0a57SCristian Dumitrescu 
2391742b0a57SCristian Dumitrescu 			snprintf(out, out_size, "\t\tAction %s (packets): %" PRIu64 "\n",
2392742b0a57SCristian Dumitrescu 				action_info.name,
2393742b0a57SCristian Dumitrescu 				stats.n_pkts_action[j]);
2394742b0a57SCristian Dumitrescu 			out_size -= strlen(out);
2395742b0a57SCristian Dumitrescu 			out += strlen(out);
2396742b0a57SCristian Dumitrescu 		}
2397742b0a57SCristian Dumitrescu 	}
23988bd4862fSCristian Dumitrescu 
23998bd4862fSCristian Dumitrescu 	snprintf(out, out_size, "\nLearner tables:\n");
24008bd4862fSCristian Dumitrescu 	out_size -= strlen(out);
24018bd4862fSCristian Dumitrescu 	out += strlen(out);
24028bd4862fSCristian Dumitrescu 
24038bd4862fSCristian Dumitrescu 	for (i = 0; i < info.n_learners; i++) {
24048bd4862fSCristian Dumitrescu 		struct rte_swx_ctl_learner_info learner_info;
24058bd4862fSCristian Dumitrescu 		uint64_t n_pkts_action[info.n_actions];
24068bd4862fSCristian Dumitrescu 		struct rte_swx_learner_stats stats = {
24078bd4862fSCristian Dumitrescu 			.n_pkts_hit = 0,
24088bd4862fSCristian Dumitrescu 			.n_pkts_miss = 0,
24098bd4862fSCristian Dumitrescu 			.n_pkts_action = n_pkts_action,
24108bd4862fSCristian Dumitrescu 		};
24118bd4862fSCristian Dumitrescu 		uint32_t j;
24128bd4862fSCristian Dumitrescu 
2413*b9559f94SCristian Dumitrescu 		status = rte_swx_ctl_learner_info_get(p, i, &learner_info);
24148bd4862fSCristian Dumitrescu 		if (status) {
24158bd4862fSCristian Dumitrescu 			snprintf(out, out_size, "Learner table info get error.");
24168bd4862fSCristian Dumitrescu 			return;
24178bd4862fSCristian Dumitrescu 		}
24188bd4862fSCristian Dumitrescu 
2419*b9559f94SCristian Dumitrescu 		status = rte_swx_ctl_pipeline_learner_stats_read(p, learner_info.name, &stats);
24208bd4862fSCristian Dumitrescu 		if (status) {
24218bd4862fSCristian Dumitrescu 			snprintf(out, out_size, "Learner table stats read error.");
24228bd4862fSCristian Dumitrescu 			return;
24238bd4862fSCristian Dumitrescu 		}
24248bd4862fSCristian Dumitrescu 
24258bd4862fSCristian Dumitrescu 		snprintf(out, out_size, "\tLearner table %s:\n"
24268bd4862fSCristian Dumitrescu 			"\t\tHit (packets): %" PRIu64 "\n"
24278bd4862fSCristian Dumitrescu 			"\t\tMiss (packets): %" PRIu64 "\n"
24288bd4862fSCristian Dumitrescu 			"\t\tLearn OK (packets): %" PRIu64 "\n"
24298bd4862fSCristian Dumitrescu 			"\t\tLearn error (packets): %" PRIu64 "\n"
243080dd28afSCristian Dumitrescu 			"\t\tRearm (packets): %" PRIu64 "\n"
24318bd4862fSCristian Dumitrescu 			"\t\tForget (packets): %" PRIu64 "\n",
24328bd4862fSCristian Dumitrescu 			learner_info.name,
24338bd4862fSCristian Dumitrescu 			stats.n_pkts_hit,
24348bd4862fSCristian Dumitrescu 			stats.n_pkts_miss,
24358bd4862fSCristian Dumitrescu 			stats.n_pkts_learn_ok,
24368bd4862fSCristian Dumitrescu 			stats.n_pkts_learn_err,
243780dd28afSCristian Dumitrescu 			stats.n_pkts_rearm,
24388bd4862fSCristian Dumitrescu 			stats.n_pkts_forget);
24398bd4862fSCristian Dumitrescu 		out_size -= strlen(out);
24408bd4862fSCristian Dumitrescu 		out += strlen(out);
24418bd4862fSCristian Dumitrescu 
24428bd4862fSCristian Dumitrescu 		for (j = 0; j < info.n_actions; j++) {
24438bd4862fSCristian Dumitrescu 			struct rte_swx_ctl_action_info action_info;
24448bd4862fSCristian Dumitrescu 
2445*b9559f94SCristian Dumitrescu 			status = rte_swx_ctl_action_info_get(p, j, &action_info);
24468bd4862fSCristian Dumitrescu 			if (status) {
24478bd4862fSCristian Dumitrescu 				snprintf(out, out_size, "Action info get error.");
24488bd4862fSCristian Dumitrescu 				return;
24498bd4862fSCristian Dumitrescu 			}
24508bd4862fSCristian Dumitrescu 
24518bd4862fSCristian Dumitrescu 			snprintf(out, out_size, "\t\tAction %s (packets): %" PRIu64 "\n",
24528bd4862fSCristian Dumitrescu 				action_info.name,
24538bd4862fSCristian Dumitrescu 				stats.n_pkts_action[j]);
24548bd4862fSCristian Dumitrescu 			out_size -= strlen(out);
24558bd4862fSCristian Dumitrescu 			out += strlen(out);
24568bd4862fSCristian Dumitrescu 		}
24578bd4862fSCristian Dumitrescu 	}
24585074e1d5SCristian Dumitrescu }
24595074e1d5SCristian Dumitrescu 
246017225455SCristian Dumitrescu static const char cmd_pipeline_mirror_session_help[] =
246117225455SCristian Dumitrescu "pipeline <pipeline_name> mirror session <session_id> port <port_id> clone fast | slow "
246217225455SCristian Dumitrescu "truncate <truncation_length>\n";
246317225455SCristian Dumitrescu 
246417225455SCristian Dumitrescu static void
246517225455SCristian Dumitrescu cmd_pipeline_mirror_session(char **tokens,
246617225455SCristian Dumitrescu 	uint32_t n_tokens,
246717225455SCristian Dumitrescu 	char *out,
246817225455SCristian Dumitrescu 	size_t out_size,
2469*b9559f94SCristian Dumitrescu 	void *obj __rte_unused)
247017225455SCristian Dumitrescu {
247117225455SCristian Dumitrescu 	struct rte_swx_pipeline_mirroring_session_params params;
2472*b9559f94SCristian Dumitrescu 	struct rte_swx_pipeline *p;
247377dd857dSAli Alnubani 	uint32_t session_id = 0;
247417225455SCristian Dumitrescu 	int status;
247517225455SCristian Dumitrescu 
247617225455SCristian Dumitrescu 	if (n_tokens != 11) {
247717225455SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
247817225455SCristian Dumitrescu 		return;
247917225455SCristian Dumitrescu 	}
248017225455SCristian Dumitrescu 
248117225455SCristian Dumitrescu 	if (strcmp(tokens[0], "pipeline")) {
248217225455SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pipeline");
248317225455SCristian Dumitrescu 		return;
248417225455SCristian Dumitrescu 	}
248517225455SCristian Dumitrescu 
2486*b9559f94SCristian Dumitrescu 	p = rte_swx_pipeline_find(tokens[1]);
2487*b9559f94SCristian Dumitrescu 	if (!p) {
248817225455SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
248917225455SCristian Dumitrescu 		return;
249017225455SCristian Dumitrescu 	}
249117225455SCristian Dumitrescu 
249217225455SCristian Dumitrescu 	if (strcmp(tokens[2], "mirror")) {
249317225455SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "mirror");
249417225455SCristian Dumitrescu 		return;
249517225455SCristian Dumitrescu 	}
249617225455SCristian Dumitrescu 
249717225455SCristian Dumitrescu 	if (strcmp(tokens[3], "session")) {
249817225455SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "session");
249917225455SCristian Dumitrescu 		return;
250017225455SCristian Dumitrescu 	}
250117225455SCristian Dumitrescu 
250217225455SCristian Dumitrescu 	if (parser_read_uint32(&session_id, tokens[4])) {
250317225455SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "session_id");
250417225455SCristian Dumitrescu 		return;
250517225455SCristian Dumitrescu 	}
250617225455SCristian Dumitrescu 
250717225455SCristian Dumitrescu 	if (strcmp(tokens[5], "port")) {
250817225455SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
250917225455SCristian Dumitrescu 		return;
251017225455SCristian Dumitrescu 	}
251117225455SCristian Dumitrescu 
251217225455SCristian Dumitrescu 	if (parser_read_uint32(&params.port_id, tokens[6])) {
251317225455SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
251417225455SCristian Dumitrescu 		return;
251517225455SCristian Dumitrescu 	}
251617225455SCristian Dumitrescu 
251717225455SCristian Dumitrescu 	if (strcmp(tokens[7], "clone")) {
251817225455SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "clone");
251917225455SCristian Dumitrescu 		return;
252017225455SCristian Dumitrescu 	}
252117225455SCristian Dumitrescu 
252217225455SCristian Dumitrescu 	if (!strcmp(tokens[8], "fast"))
252317225455SCristian Dumitrescu 		params.fast_clone = 1;
252417225455SCristian Dumitrescu 	else if (!strcmp(tokens[8], "slow"))
252517225455SCristian Dumitrescu 		params.fast_clone = 0;
252617225455SCristian Dumitrescu 	else {
252717225455SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "clone");
252817225455SCristian Dumitrescu 		return;
252917225455SCristian Dumitrescu 	}
253017225455SCristian Dumitrescu 
253117225455SCristian Dumitrescu 	if (strcmp(tokens[9], "truncate")) {
253217225455SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "truncate");
253317225455SCristian Dumitrescu 		return;
253417225455SCristian Dumitrescu 	}
253517225455SCristian Dumitrescu 
253617225455SCristian Dumitrescu 	if (parser_read_uint32(&params.truncation_length, tokens[10])) {
253717225455SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "truncation_length");
253817225455SCristian Dumitrescu 		return;
253917225455SCristian Dumitrescu 	}
254017225455SCristian Dumitrescu 
2541*b9559f94SCristian Dumitrescu 	status = rte_swx_ctl_pipeline_mirroring_session_set(p, session_id, &params);
254217225455SCristian Dumitrescu 	if (status) {
254317225455SCristian Dumitrescu 		snprintf(out, out_size, "Command failed!\n");
254417225455SCristian Dumitrescu 		return;
254517225455SCristian Dumitrescu 	}
254617225455SCristian Dumitrescu }
254717225455SCristian Dumitrescu 
25485074e1d5SCristian Dumitrescu static const char cmd_thread_pipeline_enable_help[] =
2549*b9559f94SCristian Dumitrescu "thread <thread_id> pipeline <pipeline_name> enable [ period <timer_period_ms> ]\n";
2550*b9559f94SCristian Dumitrescu 
2551*b9559f94SCristian Dumitrescu #ifndef TIMER_PERIOD_MS_DEFAULT
2552*b9559f94SCristian Dumitrescu #define TIMER_PERIOD_MS_DEFAULT 10
2553*b9559f94SCristian Dumitrescu #endif
25545074e1d5SCristian Dumitrescu 
25555074e1d5SCristian Dumitrescu static void
25565074e1d5SCristian Dumitrescu cmd_thread_pipeline_enable(char **tokens,
25575074e1d5SCristian Dumitrescu 	uint32_t n_tokens,
25585074e1d5SCristian Dumitrescu 	char *out,
25595074e1d5SCristian Dumitrescu 	size_t out_size,
2560*b9559f94SCristian Dumitrescu 	void *obj __rte_unused)
25615074e1d5SCristian Dumitrescu {
25625074e1d5SCristian Dumitrescu 	char *pipeline_name;
2563*b9559f94SCristian Dumitrescu 	struct rte_swx_pipeline *p;
2564*b9559f94SCristian Dumitrescu 	uint32_t thread_id, timer_period_ms = TIMER_PERIOD_MS_DEFAULT;
25655074e1d5SCristian Dumitrescu 	int status;
25665074e1d5SCristian Dumitrescu 
2567*b9559f94SCristian Dumitrescu 	if ((n_tokens != 5) && (n_tokens != 7)) {
25685074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
25695074e1d5SCristian Dumitrescu 		return;
25705074e1d5SCristian Dumitrescu 	}
25715074e1d5SCristian Dumitrescu 
25725074e1d5SCristian Dumitrescu 	if (parser_read_uint32(&thread_id, tokens[1]) != 0) {
25735074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "thread_id");
25745074e1d5SCristian Dumitrescu 		return;
25755074e1d5SCristian Dumitrescu 	}
25765074e1d5SCristian Dumitrescu 
25775074e1d5SCristian Dumitrescu 	if (strcmp(tokens[2], "pipeline") != 0) {
25785074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pipeline");
25795074e1d5SCristian Dumitrescu 		return;
25805074e1d5SCristian Dumitrescu 	}
25815074e1d5SCristian Dumitrescu 
25825074e1d5SCristian Dumitrescu 	pipeline_name = tokens[3];
2583*b9559f94SCristian Dumitrescu 	p = rte_swx_pipeline_find(pipeline_name);
2584*b9559f94SCristian Dumitrescu 	if (!p) {
25855074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
25865074e1d5SCristian Dumitrescu 		return;
25875074e1d5SCristian Dumitrescu 	}
25885074e1d5SCristian Dumitrescu 
25895074e1d5SCristian Dumitrescu 	if (strcmp(tokens[4], "enable") != 0) {
25905074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "enable");
25915074e1d5SCristian Dumitrescu 		return;
25925074e1d5SCristian Dumitrescu 	}
25935074e1d5SCristian Dumitrescu 
2594*b9559f94SCristian Dumitrescu 	if (n_tokens == 7) {
2595*b9559f94SCristian Dumitrescu 		if (strcmp(tokens[5], "period") != 0) {
2596*b9559f94SCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_NOT_FOUND, "period");
2597*b9559f94SCristian Dumitrescu 			return;
2598*b9559f94SCristian Dumitrescu 		}
2599*b9559f94SCristian Dumitrescu 
2600*b9559f94SCristian Dumitrescu 		if (parser_read_uint32(&timer_period_ms, tokens[6]) != 0) {
2601*b9559f94SCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_INVALID, "timer_period_ms");
2602*b9559f94SCristian Dumitrescu 			return;
2603*b9559f94SCristian Dumitrescu 		}
2604*b9559f94SCristian Dumitrescu 	}
2605*b9559f94SCristian Dumitrescu 
2606*b9559f94SCristian Dumitrescu 	status = thread_pipeline_enable(thread_id, p, timer_period_ms);
26075074e1d5SCristian Dumitrescu 	if (status) {
26085074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_CMD_FAIL, "thread pipeline enable");
26095074e1d5SCristian Dumitrescu 		return;
26105074e1d5SCristian Dumitrescu 	}
26115074e1d5SCristian Dumitrescu }
26125074e1d5SCristian Dumitrescu 
26135074e1d5SCristian Dumitrescu static const char cmd_thread_pipeline_disable_help[] =
26145074e1d5SCristian Dumitrescu "thread <thread_id> pipeline <pipeline_name> disable\n";
26155074e1d5SCristian Dumitrescu 
26165074e1d5SCristian Dumitrescu static void
26175074e1d5SCristian Dumitrescu cmd_thread_pipeline_disable(char **tokens,
26185074e1d5SCristian Dumitrescu 	uint32_t n_tokens,
26195074e1d5SCristian Dumitrescu 	char *out,
26205074e1d5SCristian Dumitrescu 	size_t out_size,
2621*b9559f94SCristian Dumitrescu 	void *obj __rte_unused)
26225074e1d5SCristian Dumitrescu {
2623*b9559f94SCristian Dumitrescu 	struct rte_swx_pipeline *p;
26245074e1d5SCristian Dumitrescu 	char *pipeline_name;
26255074e1d5SCristian Dumitrescu 	uint32_t thread_id;
26265074e1d5SCristian Dumitrescu 	int status;
26275074e1d5SCristian Dumitrescu 
26285074e1d5SCristian Dumitrescu 	if (n_tokens != 5) {
26295074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
26305074e1d5SCristian Dumitrescu 		return;
26315074e1d5SCristian Dumitrescu 	}
26325074e1d5SCristian Dumitrescu 
26335074e1d5SCristian Dumitrescu 	if (parser_read_uint32(&thread_id, tokens[1]) != 0) {
26345074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "thread_id");
26355074e1d5SCristian Dumitrescu 		return;
26365074e1d5SCristian Dumitrescu 	}
26375074e1d5SCristian Dumitrescu 
26385074e1d5SCristian Dumitrescu 	if (strcmp(tokens[2], "pipeline") != 0) {
26395074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pipeline");
26405074e1d5SCristian Dumitrescu 		return;
26415074e1d5SCristian Dumitrescu 	}
26425074e1d5SCristian Dumitrescu 
26435074e1d5SCristian Dumitrescu 	pipeline_name = tokens[3];
2644*b9559f94SCristian Dumitrescu 	p = rte_swx_pipeline_find(pipeline_name);
2645*b9559f94SCristian Dumitrescu 	if (!p) {
26465074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
26475074e1d5SCristian Dumitrescu 		return;
26485074e1d5SCristian Dumitrescu 	}
26495074e1d5SCristian Dumitrescu 
26505074e1d5SCristian Dumitrescu 	if (strcmp(tokens[4], "disable") != 0) {
26515074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "disable");
26525074e1d5SCristian Dumitrescu 		return;
26535074e1d5SCristian Dumitrescu 	}
26545074e1d5SCristian Dumitrescu 
2655*b9559f94SCristian Dumitrescu 	status = thread_pipeline_disable(thread_id, p);
26565074e1d5SCristian Dumitrescu 	if (status) {
26575074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_CMD_FAIL,
26585074e1d5SCristian Dumitrescu 			"thread pipeline disable");
26595074e1d5SCristian Dumitrescu 		return;
26605074e1d5SCristian Dumitrescu 	}
26615074e1d5SCristian Dumitrescu }
26625074e1d5SCristian Dumitrescu 
26635074e1d5SCristian Dumitrescu static void
26645074e1d5SCristian Dumitrescu cmd_help(char **tokens,
26655074e1d5SCristian Dumitrescu 	 uint32_t n_tokens,
26665074e1d5SCristian Dumitrescu 	 char *out,
26675074e1d5SCristian Dumitrescu 	 size_t out_size,
26685074e1d5SCristian Dumitrescu 	 void *arg __rte_unused)
26695074e1d5SCristian Dumitrescu {
26705074e1d5SCristian Dumitrescu 	tokens++;
26715074e1d5SCristian Dumitrescu 	n_tokens--;
26725074e1d5SCristian Dumitrescu 
26735074e1d5SCristian Dumitrescu 	if (n_tokens == 0) {
26745074e1d5SCristian Dumitrescu 		snprintf(out, out_size,
26757fef9ef1SYogesh Jangra 			"Type 'help <command>' for command details.\n\n"
26767fef9ef1SYogesh Jangra 			"List of commands:\n"
26777fef9ef1SYogesh Jangra 			"\tmempool\n"
26787fef9ef1SYogesh Jangra 			"\tlink\n"
2679e2b8dc52SVenkata Suresh Kumar P 			"\ttap\n"
26809043f66aSCristian Dumitrescu 			"\tpipeline codegen\n"
26816bc14d9fSCristian Dumitrescu 			"\tpipeline libbuild\n"
26827fef9ef1SYogesh Jangra 			"\tpipeline build\n"
268375129cebSChurchill Khangar 			"\tpipeline table add\n"
268475129cebSChurchill Khangar 			"\tpipeline table delete\n"
268575129cebSChurchill Khangar 			"\tpipeline table default\n"
268675129cebSChurchill Khangar 			"\tpipeline table show\n"
2687598fe0ddSCristian Dumitrescu 			"\tpipeline selector group add\n"
2688598fe0ddSCristian Dumitrescu 			"\tpipeline selector group delete\n"
2689598fe0ddSCristian Dumitrescu 			"\tpipeline selector group member add\n"
2690598fe0ddSCristian Dumitrescu 			"\tpipeline selector group member delete\n"
2691598fe0ddSCristian Dumitrescu 			"\tpipeline selector show\n"
26928bd4862fSCristian Dumitrescu 			"\tpipeline learner default\n"
269375129cebSChurchill Khangar 			"\tpipeline commit\n"
269475129cebSChurchill Khangar 			"\tpipeline abort\n"
269564cfcebdSCristian Dumitrescu 			"\tpipeline regrd\n"
269664cfcebdSCristian Dumitrescu 			"\tpipeline regwr\n"
2697f38913b7SCristian Dumitrescu 			"\tpipeline meter profile add\n"
2698f38913b7SCristian Dumitrescu 			"\tpipeline meter profile delete\n"
2699f38913b7SCristian Dumitrescu 			"\tpipeline meter reset\n"
2700f38913b7SCristian Dumitrescu 			"\tpipeline meter set\n"
2701f38913b7SCristian Dumitrescu 			"\tpipeline meter stats\n"
27027fef9ef1SYogesh Jangra 			"\tpipeline stats\n"
270317225455SCristian Dumitrescu 			"\tpipeline mirror session\n"
27047fef9ef1SYogesh Jangra 			"\tthread pipeline enable\n"
27057fef9ef1SYogesh Jangra 			"\tthread pipeline disable\n\n");
27065074e1d5SCristian Dumitrescu 		return;
27075074e1d5SCristian Dumitrescu 	}
27085074e1d5SCristian Dumitrescu 
27095074e1d5SCristian Dumitrescu 	if (strcmp(tokens[0], "mempool") == 0) {
27105074e1d5SCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n", cmd_mempool_help);
27115074e1d5SCristian Dumitrescu 		return;
27125074e1d5SCristian Dumitrescu 	}
27135074e1d5SCristian Dumitrescu 
27145074e1d5SCristian Dumitrescu 	if (strcmp(tokens[0], "link") == 0) {
27155074e1d5SCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n", cmd_link_help);
27165074e1d5SCristian Dumitrescu 		return;
27175074e1d5SCristian Dumitrescu 	}
27185074e1d5SCristian Dumitrescu 
271977a41301SCristian Dumitrescu 	if (strcmp(tokens[0], "ring") == 0) {
272077a41301SCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n", cmd_ring_help);
272177a41301SCristian Dumitrescu 		return;
272277a41301SCristian Dumitrescu 	}
272377a41301SCristian Dumitrescu 
2724e2b8dc52SVenkata Suresh Kumar P 	if (strcmp(tokens[0], "tap") == 0) {
2725e2b8dc52SVenkata Suresh Kumar P 		snprintf(out, out_size, "\n%s\n", cmd_tap_help);
2726e2b8dc52SVenkata Suresh Kumar P 		return;
2727e2b8dc52SVenkata Suresh Kumar P 	}
2728e2b8dc52SVenkata Suresh Kumar P 
27295074e1d5SCristian Dumitrescu 	if ((strcmp(tokens[0], "pipeline") == 0) &&
27309043f66aSCristian Dumitrescu 		(n_tokens == 2) && (strcmp(tokens[1], "codegen") == 0)) {
27319043f66aSCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n", cmd_pipeline_codegen_help);
27329043f66aSCristian Dumitrescu 		return;
27339043f66aSCristian Dumitrescu 	}
27349043f66aSCristian Dumitrescu 
27359043f66aSCristian Dumitrescu 	if ((strcmp(tokens[0], "pipeline") == 0) &&
27366bc14d9fSCristian Dumitrescu 		(n_tokens == 2) && (strcmp(tokens[1], "libbuild") == 0)) {
27376bc14d9fSCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n", cmd_pipeline_libbuild_help);
27386bc14d9fSCristian Dumitrescu 		return;
27396bc14d9fSCristian Dumitrescu 	}
27406bc14d9fSCristian Dumitrescu 
27416bc14d9fSCristian Dumitrescu 	if ((strcmp(tokens[0], "pipeline") == 0) &&
27427fef9ef1SYogesh Jangra 		(n_tokens == 2) && (strcmp(tokens[1], "build") == 0)) {
27435074e1d5SCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n", cmd_pipeline_build_help);
27445074e1d5SCristian Dumitrescu 		return;
27455074e1d5SCristian Dumitrescu 	}
27465074e1d5SCristian Dumitrescu 
27475074e1d5SCristian Dumitrescu 	if ((strcmp(tokens[0], "pipeline") == 0) &&
27487fef9ef1SYogesh Jangra 		(n_tokens == 3) &&
27497fef9ef1SYogesh Jangra 		(strcmp(tokens[1], "table") == 0) &&
275075129cebSChurchill Khangar 		(strcmp(tokens[2], "add") == 0)) {
27515074e1d5SCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n",
275275129cebSChurchill Khangar 			cmd_pipeline_table_add_help);
275375129cebSChurchill Khangar 		return;
275475129cebSChurchill Khangar 	}
275575129cebSChurchill Khangar 
275675129cebSChurchill Khangar 	if ((strcmp(tokens[0], "pipeline") == 0) &&
275775129cebSChurchill Khangar 		(n_tokens == 3) &&
275875129cebSChurchill Khangar 		(strcmp(tokens[1], "table") == 0) &&
275975129cebSChurchill Khangar 		(strcmp(tokens[2], "delete") == 0)) {
276075129cebSChurchill Khangar 		snprintf(out, out_size, "\n%s\n",
276175129cebSChurchill Khangar 			cmd_pipeline_table_delete_help);
276275129cebSChurchill Khangar 		return;
276375129cebSChurchill Khangar 	}
276475129cebSChurchill Khangar 
276575129cebSChurchill Khangar 	if ((strcmp(tokens[0], "pipeline") == 0) &&
276675129cebSChurchill Khangar 		(n_tokens == 3) &&
276775129cebSChurchill Khangar 		(strcmp(tokens[1], "table") == 0) &&
276875129cebSChurchill Khangar 		(strcmp(tokens[2], "default") == 0)) {
276975129cebSChurchill Khangar 		snprintf(out, out_size, "\n%s\n",
277075129cebSChurchill Khangar 			cmd_pipeline_table_default_help);
277175129cebSChurchill Khangar 		return;
277275129cebSChurchill Khangar 	}
277375129cebSChurchill Khangar 
277475129cebSChurchill Khangar 	if ((strcmp(tokens[0], "pipeline") == 0) &&
277575129cebSChurchill Khangar 		(n_tokens == 3) &&
277675129cebSChurchill Khangar 		(strcmp(tokens[1], "table") == 0) &&
277775129cebSChurchill Khangar 		(strcmp(tokens[2], "show") == 0)) {
277875129cebSChurchill Khangar 		snprintf(out, out_size, "\n%s\n",
277975129cebSChurchill Khangar 			cmd_pipeline_table_show_help);
278075129cebSChurchill Khangar 		return;
278175129cebSChurchill Khangar 	}
278275129cebSChurchill Khangar 
278375129cebSChurchill Khangar 	if ((strcmp(tokens[0], "pipeline") == 0) &&
2784598fe0ddSCristian Dumitrescu 		(n_tokens == 4) &&
2785598fe0ddSCristian Dumitrescu 		(strcmp(tokens[1], "selector") == 0) &&
2786598fe0ddSCristian Dumitrescu 		(strcmp(tokens[2], "group") == 0) &&
2787598fe0ddSCristian Dumitrescu 		(strcmp(tokens[3], "add") == 0)) {
2788598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n",
2789598fe0ddSCristian Dumitrescu 			cmd_pipeline_selector_group_add_help);
2790598fe0ddSCristian Dumitrescu 		return;
2791598fe0ddSCristian Dumitrescu 	}
2792598fe0ddSCristian Dumitrescu 
2793598fe0ddSCristian Dumitrescu 	if ((strcmp(tokens[0], "pipeline") == 0) &&
2794598fe0ddSCristian Dumitrescu 		(n_tokens == 4) &&
2795598fe0ddSCristian Dumitrescu 		(strcmp(tokens[1], "selector") == 0) &&
2796598fe0ddSCristian Dumitrescu 		(strcmp(tokens[2], "group") == 0) &&
2797598fe0ddSCristian Dumitrescu 		(strcmp(tokens[3], "delete") == 0)) {
2798598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n",
2799598fe0ddSCristian Dumitrescu 			cmd_pipeline_selector_group_delete_help);
2800598fe0ddSCristian Dumitrescu 		return;
2801598fe0ddSCristian Dumitrescu 	}
2802598fe0ddSCristian Dumitrescu 
2803598fe0ddSCristian Dumitrescu 	if ((strcmp(tokens[0], "pipeline") == 0) &&
2804598fe0ddSCristian Dumitrescu 		(n_tokens == 5) &&
2805598fe0ddSCristian Dumitrescu 		(strcmp(tokens[1], "selector") == 0) &&
2806598fe0ddSCristian Dumitrescu 		(strcmp(tokens[2], "group") == 0) &&
2807598fe0ddSCristian Dumitrescu 		(strcmp(tokens[3], "member") == 0) &&
2808598fe0ddSCristian Dumitrescu 		(strcmp(tokens[4], "add") == 0)) {
2809598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n",
2810598fe0ddSCristian Dumitrescu 			cmd_pipeline_selector_group_member_add_help);
2811598fe0ddSCristian Dumitrescu 		return;
2812598fe0ddSCristian Dumitrescu 	}
2813598fe0ddSCristian Dumitrescu 
2814598fe0ddSCristian Dumitrescu 	if ((strcmp(tokens[0], "pipeline") == 0) &&
2815598fe0ddSCristian Dumitrescu 		(n_tokens == 5) &&
2816598fe0ddSCristian Dumitrescu 		(strcmp(tokens[1], "selector") == 0) &&
2817598fe0ddSCristian Dumitrescu 		(strcmp(tokens[2], "group") == 0) &&
2818598fe0ddSCristian Dumitrescu 		(strcmp(tokens[3], "member") == 0) &&
2819598fe0ddSCristian Dumitrescu 		(strcmp(tokens[4], "delete") == 0)) {
2820598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n",
2821598fe0ddSCristian Dumitrescu 			cmd_pipeline_selector_group_member_delete_help);
2822598fe0ddSCristian Dumitrescu 		return;
2823598fe0ddSCristian Dumitrescu 	}
2824598fe0ddSCristian Dumitrescu 
2825598fe0ddSCristian Dumitrescu 	if ((strcmp(tokens[0], "pipeline") == 0) &&
2826598fe0ddSCristian Dumitrescu 		(n_tokens == 3) &&
2827598fe0ddSCristian Dumitrescu 		(strcmp(tokens[1], "selector") == 0) &&
2828598fe0ddSCristian Dumitrescu 		(strcmp(tokens[2], "show") == 0)) {
2829598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n",
2830598fe0ddSCristian Dumitrescu 			cmd_pipeline_selector_show_help);
2831598fe0ddSCristian Dumitrescu 		return;
2832598fe0ddSCristian Dumitrescu 	}
2833598fe0ddSCristian Dumitrescu 
2834598fe0ddSCristian Dumitrescu 	if ((strcmp(tokens[0], "pipeline") == 0) &&
28358bd4862fSCristian Dumitrescu 		(n_tokens == 3) &&
28368bd4862fSCristian Dumitrescu 		(strcmp(tokens[1], "learner") == 0) &&
28378bd4862fSCristian Dumitrescu 		(strcmp(tokens[2], "default") == 0)) {
28388bd4862fSCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n",
28398bd4862fSCristian Dumitrescu 			cmd_pipeline_learner_default_help);
28408bd4862fSCristian Dumitrescu 		return;
28418bd4862fSCristian Dumitrescu 	}
28428bd4862fSCristian Dumitrescu 
28438bd4862fSCristian Dumitrescu 	if ((strcmp(tokens[0], "pipeline") == 0) &&
284475129cebSChurchill Khangar 		(n_tokens == 2) &&
284575129cebSChurchill Khangar 		(strcmp(tokens[1], "commit") == 0)) {
284675129cebSChurchill Khangar 		snprintf(out, out_size, "\n%s\n",
284775129cebSChurchill Khangar 			cmd_pipeline_commit_help);
284875129cebSChurchill Khangar 		return;
284975129cebSChurchill Khangar 	}
285075129cebSChurchill Khangar 
285175129cebSChurchill Khangar 	if ((strcmp(tokens[0], "pipeline") == 0) &&
285275129cebSChurchill Khangar 		(n_tokens == 2) &&
285375129cebSChurchill Khangar 		(strcmp(tokens[1], "abort") == 0)) {
285475129cebSChurchill Khangar 		snprintf(out, out_size, "\n%s\n",
285575129cebSChurchill Khangar 			cmd_pipeline_abort_help);
28565074e1d5SCristian Dumitrescu 		return;
28575074e1d5SCristian Dumitrescu 	}
28585074e1d5SCristian Dumitrescu 
28595074e1d5SCristian Dumitrescu 	if ((strcmp(tokens[0], "pipeline") == 0) &&
286064cfcebdSCristian Dumitrescu 		(n_tokens == 2) && (strcmp(tokens[1], "regrd") == 0)) {
286164cfcebdSCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n", cmd_pipeline_regrd_help);
286264cfcebdSCristian Dumitrescu 		return;
286364cfcebdSCristian Dumitrescu 	}
286464cfcebdSCristian Dumitrescu 
286564cfcebdSCristian Dumitrescu 	if ((strcmp(tokens[0], "pipeline") == 0) &&
286664cfcebdSCristian Dumitrescu 		(n_tokens == 2) && (strcmp(tokens[1], "regwr") == 0)) {
286764cfcebdSCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n", cmd_pipeline_regwr_help);
286864cfcebdSCristian Dumitrescu 		return;
286964cfcebdSCristian Dumitrescu 	}
287064cfcebdSCristian Dumitrescu 
2871f38913b7SCristian Dumitrescu 	if (!strcmp(tokens[0], "pipeline") &&
2872f38913b7SCristian Dumitrescu 		(n_tokens == 4) && !strcmp(tokens[1], "meter")
2873f38913b7SCristian Dumitrescu 		&& !strcmp(tokens[2], "profile")
2874f38913b7SCristian Dumitrescu 		&& !strcmp(tokens[3], "add")) {
2875f38913b7SCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n", cmd_pipeline_meter_profile_add_help);
2876f38913b7SCristian Dumitrescu 		return;
2877f38913b7SCristian Dumitrescu 	}
2878f38913b7SCristian Dumitrescu 
2879f38913b7SCristian Dumitrescu 	if (!strcmp(tokens[0], "pipeline") &&
2880f38913b7SCristian Dumitrescu 		(n_tokens == 4) && !strcmp(tokens[1], "meter")
2881f38913b7SCristian Dumitrescu 		&& !strcmp(tokens[2], "profile")
2882f38913b7SCristian Dumitrescu 		&& !strcmp(tokens[3], "delete")) {
2883f38913b7SCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n", cmd_pipeline_meter_profile_delete_help);
2884f38913b7SCristian Dumitrescu 		return;
2885f38913b7SCristian Dumitrescu 	}
2886f38913b7SCristian Dumitrescu 
2887f38913b7SCristian Dumitrescu 	if (!strcmp(tokens[0], "pipeline") &&
2888f38913b7SCristian Dumitrescu 		(n_tokens == 3) && !strcmp(tokens[1], "meter")
2889f38913b7SCristian Dumitrescu 		&& !strcmp(tokens[2], "reset")) {
2890f38913b7SCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n", cmd_pipeline_meter_reset_help);
2891f38913b7SCristian Dumitrescu 		return;
2892f38913b7SCristian Dumitrescu 	}
2893f38913b7SCristian Dumitrescu 
2894f38913b7SCristian Dumitrescu 	if (!strcmp(tokens[0], "pipeline") &&
2895f38913b7SCristian Dumitrescu 		(n_tokens == 3) && !strcmp(tokens[1], "meter")
2896f38913b7SCristian Dumitrescu 		&& !strcmp(tokens[2], "set")) {
2897f38913b7SCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n", cmd_pipeline_meter_set_help);
2898f38913b7SCristian Dumitrescu 		return;
2899f38913b7SCristian Dumitrescu 	}
2900f38913b7SCristian Dumitrescu 
2901f38913b7SCristian Dumitrescu 	if (!strcmp(tokens[0], "pipeline") &&
2902f38913b7SCristian Dumitrescu 		(n_tokens == 3) && !strcmp(tokens[1], "meter")
2903f38913b7SCristian Dumitrescu 		&& !strcmp(tokens[2], "stats")) {
2904f38913b7SCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n", cmd_pipeline_meter_stats_help);
2905f38913b7SCristian Dumitrescu 		return;
2906f38913b7SCristian Dumitrescu 	}
2907f38913b7SCristian Dumitrescu 
290864cfcebdSCristian Dumitrescu 	if ((strcmp(tokens[0], "pipeline") == 0) &&
29097fef9ef1SYogesh Jangra 		(n_tokens == 2) && (strcmp(tokens[1], "stats") == 0)) {
29105074e1d5SCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n", cmd_pipeline_stats_help);
29115074e1d5SCristian Dumitrescu 		return;
29125074e1d5SCristian Dumitrescu 	}
29135074e1d5SCristian Dumitrescu 
291417225455SCristian Dumitrescu 	if (!strcmp(tokens[0], "pipeline") &&
291517225455SCristian Dumitrescu 		(n_tokens == 3) && !strcmp(tokens[1], "mirror")
291617225455SCristian Dumitrescu 		&& !strcmp(tokens[2], "session")) {
291717225455SCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n", cmd_pipeline_mirror_session_help);
291817225455SCristian Dumitrescu 		return;
291917225455SCristian Dumitrescu 	}
292017225455SCristian Dumitrescu 
29215074e1d5SCristian Dumitrescu 	if ((n_tokens == 3) &&
29225074e1d5SCristian Dumitrescu 		(strcmp(tokens[0], "thread") == 0) &&
29235074e1d5SCristian Dumitrescu 		(strcmp(tokens[1], "pipeline") == 0)) {
29245074e1d5SCristian Dumitrescu 		if (strcmp(tokens[2], "enable") == 0) {
29255074e1d5SCristian Dumitrescu 			snprintf(out, out_size, "\n%s\n",
29265074e1d5SCristian Dumitrescu 				cmd_thread_pipeline_enable_help);
29275074e1d5SCristian Dumitrescu 			return;
29285074e1d5SCristian Dumitrescu 		}
29295074e1d5SCristian Dumitrescu 
29305074e1d5SCristian Dumitrescu 		if (strcmp(tokens[2], "disable") == 0) {
29315074e1d5SCristian Dumitrescu 			snprintf(out, out_size, "\n%s\n",
29325074e1d5SCristian Dumitrescu 				cmd_thread_pipeline_disable_help);
29335074e1d5SCristian Dumitrescu 			return;
29345074e1d5SCristian Dumitrescu 		}
29355074e1d5SCristian Dumitrescu 	}
29365074e1d5SCristian Dumitrescu 
29375074e1d5SCristian Dumitrescu 	snprintf(out, out_size, "Invalid command\n");
29385074e1d5SCristian Dumitrescu }
29395074e1d5SCristian Dumitrescu 
29405074e1d5SCristian Dumitrescu void
29415074e1d5SCristian Dumitrescu cli_process(char *in, char *out, size_t out_size, void *obj)
29425074e1d5SCristian Dumitrescu {
29435074e1d5SCristian Dumitrescu 	char *tokens[CMD_MAX_TOKENS];
29445074e1d5SCristian Dumitrescu 	uint32_t n_tokens = RTE_DIM(tokens);
29455074e1d5SCristian Dumitrescu 	int status;
29465074e1d5SCristian Dumitrescu 
29475074e1d5SCristian Dumitrescu 	if (is_comment(in))
29485074e1d5SCristian Dumitrescu 		return;
29495074e1d5SCristian Dumitrescu 
29505074e1d5SCristian Dumitrescu 	status = parse_tokenize_string(in, tokens, &n_tokens);
29515074e1d5SCristian Dumitrescu 	if (status) {
29525074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_TOO_MANY, "");
29535074e1d5SCristian Dumitrescu 		return;
29545074e1d5SCristian Dumitrescu 	}
29555074e1d5SCristian Dumitrescu 
29565074e1d5SCristian Dumitrescu 	if (n_tokens == 0)
29575074e1d5SCristian Dumitrescu 		return;
29585074e1d5SCristian Dumitrescu 
29595074e1d5SCristian Dumitrescu 	if (strcmp(tokens[0], "help") == 0) {
29605074e1d5SCristian Dumitrescu 		cmd_help(tokens, n_tokens, out, out_size, obj);
29615074e1d5SCristian Dumitrescu 		return;
29625074e1d5SCristian Dumitrescu 	}
29635074e1d5SCristian Dumitrescu 
29645074e1d5SCristian Dumitrescu 	if (strcmp(tokens[0], "mempool") == 0) {
29655074e1d5SCristian Dumitrescu 		cmd_mempool(tokens, n_tokens, out, out_size, obj);
29665074e1d5SCristian Dumitrescu 		return;
29675074e1d5SCristian Dumitrescu 	}
29685074e1d5SCristian Dumitrescu 
29695074e1d5SCristian Dumitrescu 	if (strcmp(tokens[0], "link") == 0) {
2970821848f5SCristian Dumitrescu 		if ((n_tokens >= 2) && (strcmp(tokens[1], "show") == 0)) {
29715074e1d5SCristian Dumitrescu 			cmd_link_show(tokens, n_tokens, out, out_size, obj);
29725074e1d5SCristian Dumitrescu 			return;
29735074e1d5SCristian Dumitrescu 		}
29745074e1d5SCristian Dumitrescu 
29755074e1d5SCristian Dumitrescu 		cmd_link(tokens, n_tokens, out, out_size, obj);
29765074e1d5SCristian Dumitrescu 		return;
29775074e1d5SCristian Dumitrescu 	}
29785074e1d5SCristian Dumitrescu 
297977a41301SCristian Dumitrescu 	if (strcmp(tokens[0], "ring") == 0) {
298077a41301SCristian Dumitrescu 		cmd_ring(tokens, n_tokens, out, out_size, obj);
298177a41301SCristian Dumitrescu 		return;
298277a41301SCristian Dumitrescu 	}
298377a41301SCristian Dumitrescu 
2984e2b8dc52SVenkata Suresh Kumar P 	if (strcmp(tokens[0], "tap") == 0) {
2985e2b8dc52SVenkata Suresh Kumar P 		cmd_tap(tokens, n_tokens, out, out_size, obj);
2986e2b8dc52SVenkata Suresh Kumar P 		return;
2987e2b8dc52SVenkata Suresh Kumar P 	}
2988e2b8dc52SVenkata Suresh Kumar P 
29895074e1d5SCristian Dumitrescu 	if (strcmp(tokens[0], "pipeline") == 0) {
29905074e1d5SCristian Dumitrescu 		if ((n_tokens >= 3) &&
29919043f66aSCristian Dumitrescu 			(strcmp(tokens[1], "codegen") == 0)) {
29929043f66aSCristian Dumitrescu 			cmd_pipeline_codegen(tokens, n_tokens, out, out_size,
29939043f66aSCristian Dumitrescu 				obj);
29949043f66aSCristian Dumitrescu 			return;
29959043f66aSCristian Dumitrescu 		}
29969043f66aSCristian Dumitrescu 
29979043f66aSCristian Dumitrescu 		if ((n_tokens >= 3) &&
29986bc14d9fSCristian Dumitrescu 			(strcmp(tokens[1], "libbuild") == 0)) {
29996bc14d9fSCristian Dumitrescu 			cmd_pipeline_libbuild(tokens, n_tokens, out, out_size,
30006bc14d9fSCristian Dumitrescu 				obj);
30016bc14d9fSCristian Dumitrescu 			return;
30026bc14d9fSCristian Dumitrescu 		}
30036bc14d9fSCristian Dumitrescu 
30046bc14d9fSCristian Dumitrescu 		if ((n_tokens >= 3) &&
30055074e1d5SCristian Dumitrescu 			(strcmp(tokens[2], "build") == 0)) {
30065074e1d5SCristian Dumitrescu 			cmd_pipeline_build(tokens, n_tokens, out, out_size,
30075074e1d5SCristian Dumitrescu 				obj);
30085074e1d5SCristian Dumitrescu 			return;
30095074e1d5SCristian Dumitrescu 		}
30105074e1d5SCristian Dumitrescu 
301175129cebSChurchill Khangar 		if ((n_tokens >= 5) &&
301275129cebSChurchill Khangar 			(strcmp(tokens[2], "table") == 0) &&
301375129cebSChurchill Khangar 			(strcmp(tokens[4], "add") == 0)) {
301475129cebSChurchill Khangar 			cmd_pipeline_table_add(tokens, n_tokens, out,
301575129cebSChurchill Khangar 				out_size, obj);
301675129cebSChurchill Khangar 			return;
301775129cebSChurchill Khangar 		}
301875129cebSChurchill Khangar 
301975129cebSChurchill Khangar 		if ((n_tokens >= 5) &&
302075129cebSChurchill Khangar 			(strcmp(tokens[2], "table") == 0) &&
302175129cebSChurchill Khangar 			(strcmp(tokens[4], "delete") == 0)) {
302275129cebSChurchill Khangar 			cmd_pipeline_table_delete(tokens, n_tokens, out,
302375129cebSChurchill Khangar 				out_size, obj);
302475129cebSChurchill Khangar 			return;
302575129cebSChurchill Khangar 		}
302675129cebSChurchill Khangar 
302775129cebSChurchill Khangar 		if ((n_tokens >= 5) &&
302875129cebSChurchill Khangar 			(strcmp(tokens[2], "table") == 0) &&
302975129cebSChurchill Khangar 			(strcmp(tokens[4], "default") == 0)) {
303075129cebSChurchill Khangar 			cmd_pipeline_table_default(tokens, n_tokens, out,
303175129cebSChurchill Khangar 				out_size, obj);
303275129cebSChurchill Khangar 			return;
303375129cebSChurchill Khangar 		}
303475129cebSChurchill Khangar 
303575129cebSChurchill Khangar 		if ((n_tokens >= 5) &&
303675129cebSChurchill Khangar 			(strcmp(tokens[2], "table") == 0) &&
303775129cebSChurchill Khangar 			(strcmp(tokens[4], "show") == 0)) {
303875129cebSChurchill Khangar 			cmd_pipeline_table_show(tokens, n_tokens, out,
303975129cebSChurchill Khangar 				out_size, obj);
304075129cebSChurchill Khangar 			return;
304175129cebSChurchill Khangar 		}
304275129cebSChurchill Khangar 
3043598fe0ddSCristian Dumitrescu 		if ((n_tokens >= 6) &&
3044598fe0ddSCristian Dumitrescu 			(strcmp(tokens[2], "selector") == 0) &&
3045598fe0ddSCristian Dumitrescu 			(strcmp(tokens[4], "group") == 0) &&
3046598fe0ddSCristian Dumitrescu 			(strcmp(tokens[5], "add") == 0)) {
3047598fe0ddSCristian Dumitrescu 			cmd_pipeline_selector_group_add(tokens, n_tokens, out,
3048598fe0ddSCristian Dumitrescu 				out_size, obj);
3049598fe0ddSCristian Dumitrescu 			return;
3050598fe0ddSCristian Dumitrescu 		}
3051598fe0ddSCristian Dumitrescu 
3052598fe0ddSCristian Dumitrescu 		if ((n_tokens >= 6) &&
3053598fe0ddSCristian Dumitrescu 			(strcmp(tokens[2], "selector") == 0) &&
3054598fe0ddSCristian Dumitrescu 			(strcmp(tokens[4], "group") == 0) &&
3055598fe0ddSCristian Dumitrescu 			(strcmp(tokens[5], "delete") == 0)) {
3056598fe0ddSCristian Dumitrescu 			cmd_pipeline_selector_group_delete(tokens, n_tokens, out,
3057598fe0ddSCristian Dumitrescu 				out_size, obj);
3058598fe0ddSCristian Dumitrescu 			return;
3059598fe0ddSCristian Dumitrescu 		}
3060598fe0ddSCristian Dumitrescu 
3061598fe0ddSCristian Dumitrescu 		if ((n_tokens >= 7) &&
3062598fe0ddSCristian Dumitrescu 			(strcmp(tokens[2], "selector") == 0) &&
3063598fe0ddSCristian Dumitrescu 			(strcmp(tokens[4], "group") == 0) &&
3064598fe0ddSCristian Dumitrescu 			(strcmp(tokens[5], "member") == 0) &&
3065598fe0ddSCristian Dumitrescu 			(strcmp(tokens[6], "add") == 0)) {
3066598fe0ddSCristian Dumitrescu 			cmd_pipeline_selector_group_member_add(tokens, n_tokens, out,
3067598fe0ddSCristian Dumitrescu 				out_size, obj);
3068598fe0ddSCristian Dumitrescu 			return;
3069598fe0ddSCristian Dumitrescu 		}
3070598fe0ddSCristian Dumitrescu 
3071598fe0ddSCristian Dumitrescu 		if ((n_tokens >= 7) &&
3072598fe0ddSCristian Dumitrescu 			(strcmp(tokens[2], "selector") == 0) &&
3073598fe0ddSCristian Dumitrescu 			(strcmp(tokens[4], "group") == 0) &&
3074598fe0ddSCristian Dumitrescu 			(strcmp(tokens[5], "member") == 0) &&
3075598fe0ddSCristian Dumitrescu 			(strcmp(tokens[6], "delete") == 0)) {
3076598fe0ddSCristian Dumitrescu 			cmd_pipeline_selector_group_member_delete(tokens, n_tokens, out,
3077598fe0ddSCristian Dumitrescu 				out_size, obj);
3078598fe0ddSCristian Dumitrescu 			return;
3079598fe0ddSCristian Dumitrescu 		}
3080598fe0ddSCristian Dumitrescu 
3081598fe0ddSCristian Dumitrescu 		if ((n_tokens >= 5) &&
3082598fe0ddSCristian Dumitrescu 			(strcmp(tokens[2], "selector") == 0) &&
3083598fe0ddSCristian Dumitrescu 			(strcmp(tokens[4], "show") == 0)) {
3084598fe0ddSCristian Dumitrescu 			cmd_pipeline_selector_show(tokens, n_tokens, out,
3085598fe0ddSCristian Dumitrescu 				out_size, obj);
3086598fe0ddSCristian Dumitrescu 			return;
3087598fe0ddSCristian Dumitrescu 		}
3088598fe0ddSCristian Dumitrescu 
30898bd4862fSCristian Dumitrescu 		if ((n_tokens >= 5) &&
30908bd4862fSCristian Dumitrescu 			(strcmp(tokens[2], "learner") == 0) &&
30918bd4862fSCristian Dumitrescu 			(strcmp(tokens[4], "default") == 0)) {
30928bd4862fSCristian Dumitrescu 			cmd_pipeline_learner_default(tokens, n_tokens, out,
30938bd4862fSCristian Dumitrescu 				out_size, obj);
30948bd4862fSCristian Dumitrescu 			return;
30958bd4862fSCristian Dumitrescu 		}
30968bd4862fSCristian Dumitrescu 
30975074e1d5SCristian Dumitrescu 		if ((n_tokens >= 3) &&
309875129cebSChurchill Khangar 			(strcmp(tokens[2], "commit") == 0)) {
309975129cebSChurchill Khangar 			cmd_pipeline_commit(tokens, n_tokens, out,
310075129cebSChurchill Khangar 				out_size, obj);
310175129cebSChurchill Khangar 			return;
310275129cebSChurchill Khangar 		}
310375129cebSChurchill Khangar 
310475129cebSChurchill Khangar 		if ((n_tokens >= 3) &&
310575129cebSChurchill Khangar 			(strcmp(tokens[2], "abort") == 0)) {
310675129cebSChurchill Khangar 			cmd_pipeline_abort(tokens, n_tokens, out,
31075074e1d5SCristian Dumitrescu 				out_size, obj);
31085074e1d5SCristian Dumitrescu 			return;
31095074e1d5SCristian Dumitrescu 		}
31105074e1d5SCristian Dumitrescu 
31115074e1d5SCristian Dumitrescu 		if ((n_tokens >= 3) &&
311264cfcebdSCristian Dumitrescu 			(strcmp(tokens[2], "regrd") == 0)) {
311364cfcebdSCristian Dumitrescu 			cmd_pipeline_regrd(tokens, n_tokens, out, out_size, obj);
311464cfcebdSCristian Dumitrescu 			return;
311564cfcebdSCristian Dumitrescu 		}
311664cfcebdSCristian Dumitrescu 
311764cfcebdSCristian Dumitrescu 		if ((n_tokens >= 3) &&
311864cfcebdSCristian Dumitrescu 			(strcmp(tokens[2], "regwr") == 0)) {
311964cfcebdSCristian Dumitrescu 			cmd_pipeline_regwr(tokens, n_tokens, out, out_size, obj);
312064cfcebdSCristian Dumitrescu 			return;
312164cfcebdSCristian Dumitrescu 		}
312264cfcebdSCristian Dumitrescu 
3123f38913b7SCristian Dumitrescu 		if ((n_tokens >= 6) &&
3124f38913b7SCristian Dumitrescu 			(strcmp(tokens[2], "meter") == 0) &&
3125f38913b7SCristian Dumitrescu 			(strcmp(tokens[3], "profile") == 0) &&
3126f38913b7SCristian Dumitrescu 			(strcmp(tokens[5], "add") == 0)) {
3127f38913b7SCristian Dumitrescu 			cmd_pipeline_meter_profile_add(tokens, n_tokens, out, out_size, obj);
3128f38913b7SCristian Dumitrescu 			return;
3129f38913b7SCristian Dumitrescu 		}
3130f38913b7SCristian Dumitrescu 
3131f38913b7SCristian Dumitrescu 		if ((n_tokens >= 6) &&
3132f38913b7SCristian Dumitrescu 			(strcmp(tokens[2], "meter") == 0) &&
3133f38913b7SCristian Dumitrescu 			(strcmp(tokens[3], "profile") == 0) &&
3134f38913b7SCristian Dumitrescu 			(strcmp(tokens[5], "delete") == 0)) {
3135f38913b7SCristian Dumitrescu 			cmd_pipeline_meter_profile_delete(tokens, n_tokens, out, out_size, obj);
3136f38913b7SCristian Dumitrescu 			return;
3137f38913b7SCristian Dumitrescu 		}
3138f38913b7SCristian Dumitrescu 
3139f38913b7SCristian Dumitrescu 		if ((n_tokens >= 9) &&
3140f38913b7SCristian Dumitrescu 			(strcmp(tokens[2], "meter") == 0) &&
3141f38913b7SCristian Dumitrescu 			(strcmp(tokens[8], "reset") == 0)) {
3142f38913b7SCristian Dumitrescu 			cmd_pipeline_meter_reset(tokens, n_tokens, out, out_size, obj);
3143f38913b7SCristian Dumitrescu 			return;
3144f38913b7SCristian Dumitrescu 		}
3145f38913b7SCristian Dumitrescu 
3146f38913b7SCristian Dumitrescu 		if ((n_tokens >= 9) &&
3147f38913b7SCristian Dumitrescu 			(strcmp(tokens[2], "meter") == 0) &&
3148f38913b7SCristian Dumitrescu 			(strcmp(tokens[8], "set") == 0)) {
3149f38913b7SCristian Dumitrescu 			cmd_pipeline_meter_set(tokens, n_tokens, out, out_size, obj);
3150f38913b7SCristian Dumitrescu 			return;
3151f38913b7SCristian Dumitrescu 		}
3152f38913b7SCristian Dumitrescu 
3153f38913b7SCristian Dumitrescu 		if ((n_tokens >= 9) &&
3154f38913b7SCristian Dumitrescu 			(strcmp(tokens[2], "meter") == 0) &&
3155f38913b7SCristian Dumitrescu 			(strcmp(tokens[8], "stats") == 0)) {
3156f38913b7SCristian Dumitrescu 			cmd_pipeline_meter_stats(tokens, n_tokens, out, out_size, obj);
3157f38913b7SCristian Dumitrescu 			return;
3158f38913b7SCristian Dumitrescu 		}
3159f38913b7SCristian Dumitrescu 
316064cfcebdSCristian Dumitrescu 		if ((n_tokens >= 3) &&
31615074e1d5SCristian Dumitrescu 			(strcmp(tokens[2], "stats") == 0)) {
31625074e1d5SCristian Dumitrescu 			cmd_pipeline_stats(tokens, n_tokens, out, out_size,
31635074e1d5SCristian Dumitrescu 				obj);
31645074e1d5SCristian Dumitrescu 			return;
31655074e1d5SCristian Dumitrescu 		}
316617225455SCristian Dumitrescu 
316717225455SCristian Dumitrescu 		if ((n_tokens >= 4) &&
316817225455SCristian Dumitrescu 			(strcmp(tokens[2], "mirror") == 0) &&
316917225455SCristian Dumitrescu 			(strcmp(tokens[3], "session") == 0)) {
317017225455SCristian Dumitrescu 			cmd_pipeline_mirror_session(tokens, n_tokens, out, out_size, obj);
317117225455SCristian Dumitrescu 			return;
317217225455SCristian Dumitrescu 		}
31735074e1d5SCristian Dumitrescu 	}
31745074e1d5SCristian Dumitrescu 
31755074e1d5SCristian Dumitrescu 	if (strcmp(tokens[0], "thread") == 0) {
31765074e1d5SCristian Dumitrescu 		if ((n_tokens >= 5) &&
31775074e1d5SCristian Dumitrescu 			(strcmp(tokens[4], "enable") == 0)) {
31785074e1d5SCristian Dumitrescu 			cmd_thread_pipeline_enable(tokens, n_tokens,
31795074e1d5SCristian Dumitrescu 				out, out_size, obj);
31805074e1d5SCristian Dumitrescu 			return;
31815074e1d5SCristian Dumitrescu 		}
31825074e1d5SCristian Dumitrescu 
31835074e1d5SCristian Dumitrescu 		if ((n_tokens >= 5) &&
31845074e1d5SCristian Dumitrescu 			(strcmp(tokens[4], "disable") == 0)) {
31855074e1d5SCristian Dumitrescu 			cmd_thread_pipeline_disable(tokens, n_tokens,
31865074e1d5SCristian Dumitrescu 				out, out_size, obj);
31875074e1d5SCristian Dumitrescu 			return;
31885074e1d5SCristian Dumitrescu 		}
31895074e1d5SCristian Dumitrescu 	}
31905074e1d5SCristian Dumitrescu 
31915074e1d5SCristian Dumitrescu 	snprintf(out, out_size, MSG_CMD_UNKNOWN, tokens[0]);
31925074e1d5SCristian Dumitrescu }
31935074e1d5SCristian Dumitrescu 
31945074e1d5SCristian Dumitrescu int
31955074e1d5SCristian Dumitrescu cli_script_process(const char *file_name,
31965074e1d5SCristian Dumitrescu 	size_t msg_in_len_max,
31975074e1d5SCristian Dumitrescu 	size_t msg_out_len_max,
31985074e1d5SCristian Dumitrescu 	void *obj)
31995074e1d5SCristian Dumitrescu {
32005074e1d5SCristian Dumitrescu 	char *msg_in = NULL, *msg_out = NULL;
32015074e1d5SCristian Dumitrescu 	FILE *f = NULL;
32025074e1d5SCristian Dumitrescu 
32035074e1d5SCristian Dumitrescu 	/* Check input arguments */
32045074e1d5SCristian Dumitrescu 	if ((file_name == NULL) ||
32055074e1d5SCristian Dumitrescu 		(strlen(file_name) == 0) ||
32065074e1d5SCristian Dumitrescu 		(msg_in_len_max == 0) ||
32075074e1d5SCristian Dumitrescu 		(msg_out_len_max == 0))
32085074e1d5SCristian Dumitrescu 		return -EINVAL;
32095074e1d5SCristian Dumitrescu 
32105074e1d5SCristian Dumitrescu 	msg_in = malloc(msg_in_len_max + 1);
32115074e1d5SCristian Dumitrescu 	msg_out = malloc(msg_out_len_max + 1);
32125074e1d5SCristian Dumitrescu 	if ((msg_in == NULL) ||
32135074e1d5SCristian Dumitrescu 		(msg_out == NULL)) {
32145074e1d5SCristian Dumitrescu 		free(msg_out);
32155074e1d5SCristian Dumitrescu 		free(msg_in);
32165074e1d5SCristian Dumitrescu 		return -ENOMEM;
32175074e1d5SCristian Dumitrescu 	}
32185074e1d5SCristian Dumitrescu 
32195074e1d5SCristian Dumitrescu 	/* Open input file */
32205074e1d5SCristian Dumitrescu 	f = fopen(file_name, "r");
32215074e1d5SCristian Dumitrescu 	if (f == NULL) {
32225074e1d5SCristian Dumitrescu 		free(msg_out);
32235074e1d5SCristian Dumitrescu 		free(msg_in);
32245074e1d5SCristian Dumitrescu 		return -EIO;
32255074e1d5SCristian Dumitrescu 	}
32265074e1d5SCristian Dumitrescu 
32275074e1d5SCristian Dumitrescu 	/* Read file */
32285074e1d5SCristian Dumitrescu 	for ( ; ; ) {
32295074e1d5SCristian Dumitrescu 		if (fgets(msg_in, msg_in_len_max + 1, f) == NULL)
32305074e1d5SCristian Dumitrescu 			break;
32315074e1d5SCristian Dumitrescu 
32325074e1d5SCristian Dumitrescu 		printf("%s", msg_in);
32335074e1d5SCristian Dumitrescu 		msg_out[0] = 0;
32345074e1d5SCristian Dumitrescu 
32355074e1d5SCristian Dumitrescu 		cli_process(msg_in,
32365074e1d5SCristian Dumitrescu 			msg_out,
32375074e1d5SCristian Dumitrescu 			msg_out_len_max,
32385074e1d5SCristian Dumitrescu 			obj);
32395074e1d5SCristian Dumitrescu 
32405074e1d5SCristian Dumitrescu 		if (strlen(msg_out))
32415074e1d5SCristian Dumitrescu 			printf("%s", msg_out);
32425074e1d5SCristian Dumitrescu 	}
32435074e1d5SCristian Dumitrescu 
32445074e1d5SCristian Dumitrescu 	/* Close file */
32455074e1d5SCristian Dumitrescu 	fclose(f);
32465074e1d5SCristian Dumitrescu 	free(msg_out);
32475074e1d5SCristian Dumitrescu 	free(msg_in);
32485074e1d5SCristian Dumitrescu 	return 0;
32495074e1d5SCristian Dumitrescu }
3250