xref: /dpdk/examples/pipeline/cli.c (revision f31c80f833b099c8862528c31dba56d4e1c0e567)
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 #define PARSE_DELIMITER " \f\n\r\t\v"
1105074e1d5SCristian Dumitrescu 
1115074e1d5SCristian Dumitrescu static int
1125074e1d5SCristian Dumitrescu parse_tokenize_string(char *string, char *tokens[], uint32_t *n_tokens)
1135074e1d5SCristian Dumitrescu {
1145074e1d5SCristian Dumitrescu 	uint32_t i;
1155074e1d5SCristian Dumitrescu 
1165074e1d5SCristian Dumitrescu 	if ((string == NULL) ||
1175074e1d5SCristian Dumitrescu 		(tokens == NULL) ||
1185074e1d5SCristian Dumitrescu 		(*n_tokens < 1))
1195074e1d5SCristian Dumitrescu 		return -EINVAL;
1205074e1d5SCristian Dumitrescu 
1215074e1d5SCristian Dumitrescu 	for (i = 0; i < *n_tokens; i++) {
1225074e1d5SCristian Dumitrescu 		tokens[i] = strtok_r(string, PARSE_DELIMITER, &string);
1235074e1d5SCristian Dumitrescu 		if (tokens[i] == NULL)
1245074e1d5SCristian Dumitrescu 			break;
1255074e1d5SCristian Dumitrescu 	}
1265074e1d5SCristian Dumitrescu 
1275074e1d5SCristian Dumitrescu 	if ((i == *n_tokens) && strtok_r(string, PARSE_DELIMITER, &string))
1285074e1d5SCristian Dumitrescu 		return -E2BIG;
1295074e1d5SCristian Dumitrescu 
1305074e1d5SCristian Dumitrescu 	*n_tokens = i;
1315074e1d5SCristian Dumitrescu 	return 0;
1325074e1d5SCristian Dumitrescu }
1335074e1d5SCristian Dumitrescu 
1345074e1d5SCristian Dumitrescu static int
1355074e1d5SCristian Dumitrescu is_comment(char *in)
1365074e1d5SCristian Dumitrescu {
1375074e1d5SCristian Dumitrescu 	if ((strlen(in) && index("!#%;", in[0])) ||
1385074e1d5SCristian Dumitrescu 		(strncmp(in, "//", 2) == 0) ||
1395074e1d5SCristian Dumitrescu 		(strncmp(in, "--", 2) == 0))
1405074e1d5SCristian Dumitrescu 		return 1;
1415074e1d5SCristian Dumitrescu 
1425074e1d5SCristian Dumitrescu 	return 0;
1435074e1d5SCristian Dumitrescu }
1445074e1d5SCristian Dumitrescu 
1455074e1d5SCristian Dumitrescu static const char cmd_mempool_help[] =
1465074e1d5SCristian Dumitrescu "mempool <mempool_name>\n"
1475074e1d5SCristian Dumitrescu "   buffer <buffer_size>\n"
1485074e1d5SCristian Dumitrescu "   pool <pool_size>\n"
1495074e1d5SCristian Dumitrescu "   cache <cache_size>\n"
1505074e1d5SCristian Dumitrescu "   cpu <cpu_id>\n";
1515074e1d5SCristian Dumitrescu 
1525074e1d5SCristian Dumitrescu static void
1535074e1d5SCristian Dumitrescu cmd_mempool(char **tokens,
1545074e1d5SCristian Dumitrescu 	uint32_t n_tokens,
1555074e1d5SCristian Dumitrescu 	char *out,
1565074e1d5SCristian Dumitrescu 	size_t out_size,
1575074e1d5SCristian Dumitrescu 	void *obj)
1585074e1d5SCristian Dumitrescu {
1595074e1d5SCristian Dumitrescu 	struct mempool_params p;
1605074e1d5SCristian Dumitrescu 	char *name;
1615074e1d5SCristian Dumitrescu 	struct mempool *mempool;
1625074e1d5SCristian Dumitrescu 
1635074e1d5SCristian Dumitrescu 	if (n_tokens != 10) {
1645074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1655074e1d5SCristian Dumitrescu 		return;
1665074e1d5SCristian Dumitrescu 	}
1675074e1d5SCristian Dumitrescu 
1685074e1d5SCristian Dumitrescu 	name = tokens[1];
1695074e1d5SCristian Dumitrescu 
1705074e1d5SCristian Dumitrescu 	if (strcmp(tokens[2], "buffer") != 0) {
1715074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "buffer");
1725074e1d5SCristian Dumitrescu 		return;
1735074e1d5SCristian Dumitrescu 	}
1745074e1d5SCristian Dumitrescu 
1755074e1d5SCristian Dumitrescu 	if (parser_read_uint32(&p.buffer_size, tokens[3]) != 0) {
1765074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "buffer_size");
1775074e1d5SCristian Dumitrescu 		return;
1785074e1d5SCristian Dumitrescu 	}
1795074e1d5SCristian Dumitrescu 
1805074e1d5SCristian Dumitrescu 	if (strcmp(tokens[4], "pool") != 0) {
1815074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pool");
1825074e1d5SCristian Dumitrescu 		return;
1835074e1d5SCristian Dumitrescu 	}
1845074e1d5SCristian Dumitrescu 
1855074e1d5SCristian Dumitrescu 	if (parser_read_uint32(&p.pool_size, tokens[5]) != 0) {
1865074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pool_size");
1875074e1d5SCristian Dumitrescu 		return;
1885074e1d5SCristian Dumitrescu 	}
1895074e1d5SCristian Dumitrescu 
1905074e1d5SCristian Dumitrescu 	if (strcmp(tokens[6], "cache") != 0) {
1915074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cache");
1925074e1d5SCristian Dumitrescu 		return;
1935074e1d5SCristian Dumitrescu 	}
1945074e1d5SCristian Dumitrescu 
1955074e1d5SCristian Dumitrescu 	if (parser_read_uint32(&p.cache_size, tokens[7]) != 0) {
1965074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "cache_size");
1975074e1d5SCristian Dumitrescu 		return;
1985074e1d5SCristian Dumitrescu 	}
1995074e1d5SCristian Dumitrescu 
2005074e1d5SCristian Dumitrescu 	if (strcmp(tokens[8], "cpu") != 0) {
2015074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cpu");
2025074e1d5SCristian Dumitrescu 		return;
2035074e1d5SCristian Dumitrescu 	}
2045074e1d5SCristian Dumitrescu 
2055074e1d5SCristian Dumitrescu 	if (parser_read_uint32(&p.cpu_id, tokens[9]) != 0) {
2065074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "cpu_id");
2075074e1d5SCristian Dumitrescu 		return;
2085074e1d5SCristian Dumitrescu 	}
2095074e1d5SCristian Dumitrescu 
2105074e1d5SCristian Dumitrescu 	mempool = mempool_create(obj, name, &p);
2115074e1d5SCristian Dumitrescu 	if (mempool == NULL) {
2125074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
2135074e1d5SCristian Dumitrescu 		return;
2145074e1d5SCristian Dumitrescu 	}
2155074e1d5SCristian Dumitrescu }
2165074e1d5SCristian Dumitrescu 
217*f31c80f8SCristian Dumitrescu static const char cmd_ethdev_help[] =
218*f31c80f8SCristian Dumitrescu "ethdev <ethdev_name>\n"
2195074e1d5SCristian Dumitrescu "   rxq <n_queues> <queue_size> <mempool_name>\n"
2205074e1d5SCristian Dumitrescu "   txq <n_queues> <queue_size>\n"
2215074e1d5SCristian Dumitrescu "   promiscuous on | off\n"
2225074e1d5SCristian Dumitrescu "   [rss <qid_0> ... <qid_n>]\n";
2235074e1d5SCristian Dumitrescu 
2245074e1d5SCristian Dumitrescu static void
225*f31c80f8SCristian Dumitrescu cmd_ethdev(char **tokens,
2265074e1d5SCristian Dumitrescu 	uint32_t n_tokens,
2275074e1d5SCristian Dumitrescu 	char *out,
2285074e1d5SCristian Dumitrescu 	size_t out_size,
2295074e1d5SCristian Dumitrescu 	void *obj)
2305074e1d5SCristian Dumitrescu {
2315074e1d5SCristian Dumitrescu 	struct link_params p;
2325074e1d5SCristian Dumitrescu 	struct link_params_rss rss;
2335074e1d5SCristian Dumitrescu 	struct link *link;
2345074e1d5SCristian Dumitrescu 	char *name;
2355074e1d5SCristian Dumitrescu 
2365074e1d5SCristian Dumitrescu 	memset(&p, 0, sizeof(p));
2375074e1d5SCristian Dumitrescu 
238*f31c80f8SCristian Dumitrescu 	if ((n_tokens < 11) || (n_tokens > 12 + LINK_RXQ_RSS_MAX)) {
2395074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2405074e1d5SCristian Dumitrescu 		return;
2415074e1d5SCristian Dumitrescu 	}
2425074e1d5SCristian Dumitrescu 	name = tokens[1];
2435074e1d5SCristian Dumitrescu 
244*f31c80f8SCristian Dumitrescu 	if (strcmp(tokens[2], "rxq") != 0) {
2455074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rxq");
2465074e1d5SCristian Dumitrescu 		return;
2475074e1d5SCristian Dumitrescu 	}
2485074e1d5SCristian Dumitrescu 
249*f31c80f8SCristian Dumitrescu 	if (parser_read_uint32(&p.rx.n_queues, tokens[3]) != 0) {
2505074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "n_queues");
2515074e1d5SCristian Dumitrescu 		return;
2525074e1d5SCristian Dumitrescu 	}
253*f31c80f8SCristian Dumitrescu 	if (parser_read_uint32(&p.rx.queue_size, tokens[4]) != 0) {
2545074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "queue_size");
2555074e1d5SCristian Dumitrescu 		return;
2565074e1d5SCristian Dumitrescu 	}
2575074e1d5SCristian Dumitrescu 
258*f31c80f8SCristian Dumitrescu 	p.rx.mempool_name = tokens[5];
2595074e1d5SCristian Dumitrescu 
260*f31c80f8SCristian Dumitrescu 	if (strcmp(tokens[6], "txq") != 0) {
2615074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "txq");
2625074e1d5SCristian Dumitrescu 		return;
2635074e1d5SCristian Dumitrescu 	}
2645074e1d5SCristian Dumitrescu 
265*f31c80f8SCristian Dumitrescu 	if (parser_read_uint32(&p.tx.n_queues, tokens[7]) != 0) {
2665074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "n_queues");
2675074e1d5SCristian Dumitrescu 		return;
2685074e1d5SCristian Dumitrescu 	}
2695074e1d5SCristian Dumitrescu 
270*f31c80f8SCristian Dumitrescu 	if (parser_read_uint32(&p.tx.queue_size, tokens[8]) != 0) {
2715074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "queue_size");
2725074e1d5SCristian Dumitrescu 		return;
2735074e1d5SCristian Dumitrescu 	}
2745074e1d5SCristian Dumitrescu 
275*f31c80f8SCristian Dumitrescu 	if (strcmp(tokens[9], "promiscuous") != 0) {
2765074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "promiscuous");
2775074e1d5SCristian Dumitrescu 		return;
2785074e1d5SCristian Dumitrescu 	}
2795074e1d5SCristian Dumitrescu 
280*f31c80f8SCristian Dumitrescu 	if (strcmp(tokens[10], "on") == 0)
2815074e1d5SCristian Dumitrescu 		p.promiscuous = 1;
282*f31c80f8SCristian Dumitrescu 	else if (strcmp(tokens[10], "off") == 0)
2835074e1d5SCristian Dumitrescu 		p.promiscuous = 0;
2845074e1d5SCristian Dumitrescu 	else {
2855074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "on or off");
2865074e1d5SCristian Dumitrescu 		return;
2875074e1d5SCristian Dumitrescu 	}
2885074e1d5SCristian Dumitrescu 
2895074e1d5SCristian Dumitrescu 	/* RSS */
2905074e1d5SCristian Dumitrescu 	p.rx.rss = NULL;
291*f31c80f8SCristian Dumitrescu 	if (n_tokens > 11) {
2925074e1d5SCristian Dumitrescu 		uint32_t queue_id, i;
2935074e1d5SCristian Dumitrescu 
294*f31c80f8SCristian Dumitrescu 		if (strcmp(tokens[11], "rss") != 0) {
2955074e1d5SCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rss");
2965074e1d5SCristian Dumitrescu 			return;
2975074e1d5SCristian Dumitrescu 		}
2985074e1d5SCristian Dumitrescu 
2995074e1d5SCristian Dumitrescu 		p.rx.rss = &rss;
3005074e1d5SCristian Dumitrescu 
3015074e1d5SCristian Dumitrescu 		rss.n_queues = 0;
302*f31c80f8SCristian Dumitrescu 		for (i = 12; i < n_tokens; i++) {
3035074e1d5SCristian Dumitrescu 			if (parser_read_uint32(&queue_id, tokens[i]) != 0) {
3045074e1d5SCristian Dumitrescu 				snprintf(out, out_size, MSG_ARG_INVALID,
3055074e1d5SCristian Dumitrescu 					"queue_id");
3065074e1d5SCristian Dumitrescu 				return;
3075074e1d5SCristian Dumitrescu 			}
3085074e1d5SCristian Dumitrescu 
3095074e1d5SCristian Dumitrescu 			rss.queue_id[rss.n_queues] = queue_id;
3105074e1d5SCristian Dumitrescu 			rss.n_queues++;
3115074e1d5SCristian Dumitrescu 		}
3125074e1d5SCristian Dumitrescu 	}
3135074e1d5SCristian Dumitrescu 
3145074e1d5SCristian Dumitrescu 	link = link_create(obj, name, &p);
3155074e1d5SCristian Dumitrescu 	if (link == NULL) {
3165074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
3175074e1d5SCristian Dumitrescu 		return;
3185074e1d5SCristian Dumitrescu 	}
3195074e1d5SCristian Dumitrescu }
3205074e1d5SCristian Dumitrescu 
3215074e1d5SCristian Dumitrescu /* Print the link stats and info */
3225074e1d5SCristian Dumitrescu static void
3235074e1d5SCristian Dumitrescu print_link_info(struct link *link, char *out, size_t out_size)
3245074e1d5SCristian Dumitrescu {
3255074e1d5SCristian Dumitrescu 	struct rte_eth_stats stats;
3265074e1d5SCristian Dumitrescu 	struct rte_ether_addr mac_addr;
3275074e1d5SCristian Dumitrescu 	struct rte_eth_link eth_link;
3285074e1d5SCristian Dumitrescu 	uint16_t mtu;
3295074e1d5SCristian Dumitrescu 	int ret;
3305074e1d5SCristian Dumitrescu 
3315074e1d5SCristian Dumitrescu 	memset(&stats, 0, sizeof(stats));
3325074e1d5SCristian Dumitrescu 	rte_eth_stats_get(link->port_id, &stats);
3335074e1d5SCristian Dumitrescu 
3345074e1d5SCristian Dumitrescu 	ret = rte_eth_macaddr_get(link->port_id, &mac_addr);
3355074e1d5SCristian Dumitrescu 	if (ret != 0) {
3365074e1d5SCristian Dumitrescu 		snprintf(out, out_size, "\n%s: MAC address get failed: %s",
3375074e1d5SCristian Dumitrescu 			 link->name, rte_strerror(-ret));
3385074e1d5SCristian Dumitrescu 		return;
3395074e1d5SCristian Dumitrescu 	}
3405074e1d5SCristian Dumitrescu 
3415074e1d5SCristian Dumitrescu 	ret = rte_eth_link_get(link->port_id, &eth_link);
3425074e1d5SCristian Dumitrescu 	if (ret < 0) {
3435074e1d5SCristian Dumitrescu 		snprintf(out, out_size, "\n%s: link get failed: %s",
3445074e1d5SCristian Dumitrescu 			 link->name, rte_strerror(-ret));
3455074e1d5SCristian Dumitrescu 		return;
3465074e1d5SCristian Dumitrescu 	}
3475074e1d5SCristian Dumitrescu 
3485074e1d5SCristian Dumitrescu 	rte_eth_dev_get_mtu(link->port_id, &mtu);
3495074e1d5SCristian Dumitrescu 
3505074e1d5SCristian Dumitrescu 	snprintf(out, out_size,
3515074e1d5SCristian Dumitrescu 		"\n"
3525074e1d5SCristian Dumitrescu 		"%s: flags=<%s> mtu %u\n"
353c2c4f87bSAman Deep Singh 		"\tether " RTE_ETHER_ADDR_PRT_FMT " rxqueues %u txqueues %u\n"
3545074e1d5SCristian Dumitrescu 		"\tport# %u  speed %s\n"
3555074e1d5SCristian Dumitrescu 		"\tRX packets %" PRIu64"  bytes %" PRIu64"\n"
3565074e1d5SCristian Dumitrescu 		"\tRX errors %" PRIu64"  missed %" PRIu64"  no-mbuf %" PRIu64"\n"
3575074e1d5SCristian Dumitrescu 		"\tTX packets %" PRIu64"  bytes %" PRIu64"\n"
3585074e1d5SCristian Dumitrescu 		"\tTX errors %" PRIu64"\n",
3595074e1d5SCristian Dumitrescu 		link->name,
3605074e1d5SCristian Dumitrescu 		eth_link.link_status == 0 ? "DOWN" : "UP",
3615074e1d5SCristian Dumitrescu 		mtu,
362a7db3afcSAman Deep Singh 		RTE_ETHER_ADDR_BYTES(&mac_addr),
3635074e1d5SCristian Dumitrescu 		link->n_rxq,
3645074e1d5SCristian Dumitrescu 		link->n_txq,
3655074e1d5SCristian Dumitrescu 		link->port_id,
3665074e1d5SCristian Dumitrescu 		rte_eth_link_speed_to_str(eth_link.link_speed),
3675074e1d5SCristian Dumitrescu 		stats.ipackets,
3685074e1d5SCristian Dumitrescu 		stats.ibytes,
3695074e1d5SCristian Dumitrescu 		stats.ierrors,
3705074e1d5SCristian Dumitrescu 		stats.imissed,
3715074e1d5SCristian Dumitrescu 		stats.rx_nombuf,
3725074e1d5SCristian Dumitrescu 		stats.opackets,
3735074e1d5SCristian Dumitrescu 		stats.obytes,
3745074e1d5SCristian Dumitrescu 		stats.oerrors);
3755074e1d5SCristian Dumitrescu }
3765074e1d5SCristian Dumitrescu 
3775074e1d5SCristian Dumitrescu /*
378*f31c80f8SCristian Dumitrescu  * ethdev show [<ethdev_name>]
3795074e1d5SCristian Dumitrescu  */
3805074e1d5SCristian Dumitrescu static void
381*f31c80f8SCristian Dumitrescu cmd_ethdev_show(char **tokens,
3825074e1d5SCristian Dumitrescu 	      uint32_t n_tokens,
3835074e1d5SCristian Dumitrescu 	      char *out,
3845074e1d5SCristian Dumitrescu 	      size_t out_size,
3855074e1d5SCristian Dumitrescu 	      void *obj)
3865074e1d5SCristian Dumitrescu {
3875074e1d5SCristian Dumitrescu 	struct link *link;
3885074e1d5SCristian Dumitrescu 	char *link_name;
3895074e1d5SCristian Dumitrescu 
3905074e1d5SCristian Dumitrescu 	if (n_tokens != 2 && n_tokens != 3) {
3915074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
3925074e1d5SCristian Dumitrescu 		return;
3935074e1d5SCristian Dumitrescu 	}
3945074e1d5SCristian Dumitrescu 
3955074e1d5SCristian Dumitrescu 	if (n_tokens == 2) {
3965074e1d5SCristian Dumitrescu 		link = link_next(obj, NULL);
3975074e1d5SCristian Dumitrescu 
3985074e1d5SCristian Dumitrescu 		while (link != NULL) {
3995074e1d5SCristian Dumitrescu 			out_size = out_size - strlen(out);
4005074e1d5SCristian Dumitrescu 			out = &out[strlen(out)];
4015074e1d5SCristian Dumitrescu 
4025074e1d5SCristian Dumitrescu 			print_link_info(link, out, out_size);
4035074e1d5SCristian Dumitrescu 			link = link_next(obj, link);
4045074e1d5SCristian Dumitrescu 		}
4055074e1d5SCristian Dumitrescu 	} else {
4065074e1d5SCristian Dumitrescu 		out_size = out_size - strlen(out);
4075074e1d5SCristian Dumitrescu 		out = &out[strlen(out)];
4085074e1d5SCristian Dumitrescu 
4095074e1d5SCristian Dumitrescu 		link_name = tokens[2];
4105074e1d5SCristian Dumitrescu 		link = link_find(obj, link_name);
4115074e1d5SCristian Dumitrescu 
4125074e1d5SCristian Dumitrescu 		if (link == NULL) {
4135074e1d5SCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_INVALID,
4145074e1d5SCristian Dumitrescu 					"Link does not exist");
4155074e1d5SCristian Dumitrescu 			return;
4165074e1d5SCristian Dumitrescu 		}
4175074e1d5SCristian Dumitrescu 		print_link_info(link, out, out_size);
4185074e1d5SCristian Dumitrescu 	}
4195074e1d5SCristian Dumitrescu }
4205074e1d5SCristian Dumitrescu 
42177a41301SCristian Dumitrescu static const char cmd_ring_help[] =
42277a41301SCristian Dumitrescu "ring <ring_name> size <size> numa <numa_node>\n";
42377a41301SCristian Dumitrescu 
42477a41301SCristian Dumitrescu static void
42577a41301SCristian Dumitrescu cmd_ring(char **tokens,
42677a41301SCristian Dumitrescu 	uint32_t n_tokens,
42777a41301SCristian Dumitrescu 	char *out,
42877a41301SCristian Dumitrescu 	size_t out_size,
42977a41301SCristian Dumitrescu 	void *obj)
43077a41301SCristian Dumitrescu {
43177a41301SCristian Dumitrescu 	struct ring_params p;
43277a41301SCristian Dumitrescu 	char *name;
43377a41301SCristian Dumitrescu 	struct ring *ring;
43477a41301SCristian Dumitrescu 
43577a41301SCristian Dumitrescu 	if (n_tokens != 6) {
43677a41301SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
43777a41301SCristian Dumitrescu 		return;
43877a41301SCristian Dumitrescu 	}
43977a41301SCristian Dumitrescu 
44077a41301SCristian Dumitrescu 	name = tokens[1];
44177a41301SCristian Dumitrescu 
44277a41301SCristian Dumitrescu 	if (strcmp(tokens[2], "size") != 0) {
44377a41301SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "size");
44477a41301SCristian Dumitrescu 		return;
44577a41301SCristian Dumitrescu 	}
44677a41301SCristian Dumitrescu 
44777a41301SCristian Dumitrescu 	if (parser_read_uint32(&p.size, tokens[3]) != 0) {
44877a41301SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "size");
44977a41301SCristian Dumitrescu 		return;
45077a41301SCristian Dumitrescu 	}
45177a41301SCristian Dumitrescu 
45277a41301SCristian Dumitrescu 	if (strcmp(tokens[4], "numa") != 0) {
45377a41301SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "numa");
45477a41301SCristian Dumitrescu 		return;
45577a41301SCristian Dumitrescu 	}
45677a41301SCristian Dumitrescu 
45777a41301SCristian Dumitrescu 	if (parser_read_uint32(&p.numa_node, tokens[5]) != 0) {
45877a41301SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "numa_node");
45977a41301SCristian Dumitrescu 		return;
46077a41301SCristian Dumitrescu 	}
46177a41301SCristian Dumitrescu 
46277a41301SCristian Dumitrescu 	ring = ring_create(obj, name, &p);
46377a41301SCristian Dumitrescu 	if (!ring) {
46477a41301SCristian Dumitrescu 		snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
46577a41301SCristian Dumitrescu 		return;
46677a41301SCristian Dumitrescu 	}
46777a41301SCristian Dumitrescu }
46877a41301SCristian Dumitrescu 
469e2b8dc52SVenkata Suresh Kumar P static const char cmd_tap_help[] =
470e2b8dc52SVenkata Suresh Kumar P "tap <tap_name>\n";
471e2b8dc52SVenkata Suresh Kumar P 
472e2b8dc52SVenkata Suresh Kumar P static void
473e2b8dc52SVenkata Suresh Kumar P cmd_tap(char **tokens,
474e2b8dc52SVenkata Suresh Kumar P 	uint32_t n_tokens,
475e2b8dc52SVenkata Suresh Kumar P 	char *out,
476e2b8dc52SVenkata Suresh Kumar P 	size_t out_size,
477e2b8dc52SVenkata Suresh Kumar P 	void *obj)
478e2b8dc52SVenkata Suresh Kumar P {
479e2b8dc52SVenkata Suresh Kumar P 	struct tap *tap;
480e2b8dc52SVenkata Suresh Kumar P 	char *name;
481e2b8dc52SVenkata Suresh Kumar P 
482e2b8dc52SVenkata Suresh Kumar P 	if (n_tokens < 2) {
483e2b8dc52SVenkata Suresh Kumar P 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
484e2b8dc52SVenkata Suresh Kumar P 		return;
485e2b8dc52SVenkata Suresh Kumar P 	}
486e2b8dc52SVenkata Suresh Kumar P 	name = tokens[1];
487e2b8dc52SVenkata Suresh Kumar P 
488e2b8dc52SVenkata Suresh Kumar P 	tap = tap_create(obj, name);
489e2b8dc52SVenkata Suresh Kumar P 	if (tap == NULL) {
490e2b8dc52SVenkata Suresh Kumar P 		snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
491e2b8dc52SVenkata Suresh Kumar P 		return;
492e2b8dc52SVenkata Suresh Kumar P 	}
493e2b8dc52SVenkata Suresh Kumar P }
494e2b8dc52SVenkata Suresh Kumar P 
4959043f66aSCristian Dumitrescu static const char cmd_pipeline_codegen_help[] =
4969043f66aSCristian Dumitrescu "pipeline codegen <spec_file> <code_file>\n";
4979043f66aSCristian Dumitrescu 
4989043f66aSCristian Dumitrescu static void
4999043f66aSCristian Dumitrescu cmd_pipeline_codegen(char **tokens,
5009043f66aSCristian Dumitrescu 	uint32_t n_tokens,
5019043f66aSCristian Dumitrescu 	char *out,
5029043f66aSCristian Dumitrescu 	size_t out_size,
5039043f66aSCristian Dumitrescu 	void *obj __rte_unused)
5049043f66aSCristian Dumitrescu {
5059043f66aSCristian Dumitrescu 	FILE *spec_file = NULL;
5069043f66aSCristian Dumitrescu 	FILE *code_file = NULL;
5079043f66aSCristian Dumitrescu 	uint32_t err_line;
5089043f66aSCristian Dumitrescu 	const char *err_msg;
5099043f66aSCristian Dumitrescu 	int status;
5109043f66aSCristian Dumitrescu 
5119043f66aSCristian Dumitrescu 	if (n_tokens != 4) {
5129043f66aSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
5139043f66aSCristian Dumitrescu 		return;
5149043f66aSCristian Dumitrescu 	}
5159043f66aSCristian Dumitrescu 
5169043f66aSCristian Dumitrescu 	spec_file = fopen(tokens[2], "r");
5179043f66aSCristian Dumitrescu 	if (!spec_file) {
5189043f66aSCristian Dumitrescu 		snprintf(out, out_size, "Cannot open file %s.\n", tokens[2]);
5199043f66aSCristian Dumitrescu 		return;
5209043f66aSCristian Dumitrescu 	}
5219043f66aSCristian Dumitrescu 
5229043f66aSCristian Dumitrescu 	code_file = fopen(tokens[3], "w");
5239043f66aSCristian Dumitrescu 	if (!code_file) {
5249043f66aSCristian Dumitrescu 		snprintf(out, out_size, "Cannot open file %s.\n", tokens[3]);
5259043f66aSCristian Dumitrescu 		return;
5269043f66aSCristian Dumitrescu 	}
5279043f66aSCristian Dumitrescu 
5289043f66aSCristian Dumitrescu 	status = rte_swx_pipeline_codegen(spec_file,
5299043f66aSCristian Dumitrescu 					  code_file,
5309043f66aSCristian Dumitrescu 					  &err_line,
5319043f66aSCristian Dumitrescu 					  &err_msg);
5329043f66aSCristian Dumitrescu 
5339043f66aSCristian Dumitrescu 	fclose(spec_file);
5349043f66aSCristian Dumitrescu 	fclose(code_file);
5359043f66aSCristian Dumitrescu 
5369043f66aSCristian Dumitrescu 	if (status) {
5379043f66aSCristian Dumitrescu 		snprintf(out, out_size, "Error %d at line %u: %s\n.",
5389043f66aSCristian Dumitrescu 			status, err_line, err_msg);
5399043f66aSCristian Dumitrescu 		return;
5409043f66aSCristian Dumitrescu 	}
5419043f66aSCristian Dumitrescu }
5426bc14d9fSCristian Dumitrescu 
5436bc14d9fSCristian Dumitrescu static const char cmd_pipeline_libbuild_help[] =
5446bc14d9fSCristian Dumitrescu "pipeline libbuild <code_file> <lib_file>\n";
5456bc14d9fSCristian Dumitrescu 
5466bc14d9fSCristian Dumitrescu static void
5476bc14d9fSCristian Dumitrescu cmd_pipeline_libbuild(char **tokens,
5486bc14d9fSCristian Dumitrescu 	uint32_t n_tokens,
5496bc14d9fSCristian Dumitrescu 	char *out,
5506bc14d9fSCristian Dumitrescu 	size_t out_size,
5516bc14d9fSCristian Dumitrescu 	void *obj __rte_unused)
5526bc14d9fSCristian Dumitrescu {
5536bc14d9fSCristian Dumitrescu 	char *code_file, *lib_file, *obj_file = NULL, *log_file = NULL;
5546bc14d9fSCristian Dumitrescu 	char *install_dir, *cwd = NULL, *buffer = NULL;
5556bc14d9fSCristian Dumitrescu 	size_t length;
5566bc14d9fSCristian Dumitrescu 	int status = 0;
5576bc14d9fSCristian Dumitrescu 
5586bc14d9fSCristian Dumitrescu 	if (n_tokens != 4) {
5596bc14d9fSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
5606bc14d9fSCristian Dumitrescu 		goto free;
5616bc14d9fSCristian Dumitrescu 	}
5626bc14d9fSCristian Dumitrescu 
5636bc14d9fSCristian Dumitrescu 	install_dir = getenv("RTE_INSTALL_DIR");
5646bc14d9fSCristian Dumitrescu 	if (!install_dir) {
5656bc14d9fSCristian Dumitrescu 		cwd = malloc(MAX_LINE_SIZE);
5666bc14d9fSCristian Dumitrescu 		if (!cwd) {
5676bc14d9fSCristian Dumitrescu 			snprintf(out, out_size, MSG_OUT_OF_MEMORY);
5686bc14d9fSCristian Dumitrescu 			goto free;
5696bc14d9fSCristian Dumitrescu 		}
5706bc14d9fSCristian Dumitrescu 
5716bc14d9fSCristian Dumitrescu 		install_dir = getcwd(cwd, MAX_LINE_SIZE);
5726bc14d9fSCristian Dumitrescu 		if (!install_dir) {
5736bc14d9fSCristian Dumitrescu 			snprintf(out, out_size, "Error: Path too long.\n");
5746bc14d9fSCristian Dumitrescu 			goto free;
5756bc14d9fSCristian Dumitrescu 		}
5766bc14d9fSCristian Dumitrescu 	}
5776bc14d9fSCristian Dumitrescu 
5786bc14d9fSCristian Dumitrescu 	snprintf(out, out_size, "Using DPDK source code from \"%s\".\n", install_dir);
5796bc14d9fSCristian Dumitrescu 	out_size -= strlen(out);
5806bc14d9fSCristian Dumitrescu 	out += strlen(out);
5816bc14d9fSCristian Dumitrescu 
5826bc14d9fSCristian Dumitrescu 	code_file = tokens[2];
5836bc14d9fSCristian Dumitrescu 	length = strnlen(code_file, MAX_LINE_SIZE);
5846bc14d9fSCristian Dumitrescu 	if ((length < 3) ||
5856bc14d9fSCristian Dumitrescu 	    (code_file[length - 2] != '.') ||
5866bc14d9fSCristian Dumitrescu 	    (code_file[length - 1] != 'c')) {
5876bc14d9fSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "code_file");
5886bc14d9fSCristian Dumitrescu 		goto free;
5896bc14d9fSCristian Dumitrescu 	}
5906bc14d9fSCristian Dumitrescu 
5916bc14d9fSCristian Dumitrescu 	lib_file = tokens[3];
5926bc14d9fSCristian Dumitrescu 	length = strnlen(lib_file, MAX_LINE_SIZE);
5936bc14d9fSCristian Dumitrescu 	if ((length < 4) ||
5946bc14d9fSCristian Dumitrescu 	    (lib_file[length - 3] != '.') ||
5956bc14d9fSCristian Dumitrescu 	    (lib_file[length - 2] != 's') ||
5966bc14d9fSCristian Dumitrescu 	    (lib_file[length - 1] != 'o')) {
5976bc14d9fSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "lib_file");
5986bc14d9fSCristian Dumitrescu 		goto free;
5996bc14d9fSCristian Dumitrescu 	}
6006bc14d9fSCristian Dumitrescu 
6016bc14d9fSCristian Dumitrescu 	obj_file = malloc(length);
6026bc14d9fSCristian Dumitrescu 	log_file = malloc(length + 2);
6036bc14d9fSCristian Dumitrescu 	if (!obj_file || !log_file) {
6046bc14d9fSCristian Dumitrescu 		snprintf(out, out_size, MSG_OUT_OF_MEMORY);
6056bc14d9fSCristian Dumitrescu 		goto free;
6066bc14d9fSCristian Dumitrescu 	}
6076bc14d9fSCristian Dumitrescu 
6086bc14d9fSCristian Dumitrescu 	memcpy(obj_file, lib_file, length - 2);
6096bc14d9fSCristian Dumitrescu 	obj_file[length - 2] = 'o';
6106bc14d9fSCristian Dumitrescu 	obj_file[length - 1] = 0;
6116bc14d9fSCristian Dumitrescu 
6126bc14d9fSCristian Dumitrescu 	memcpy(log_file, lib_file, length - 2);
6136bc14d9fSCristian Dumitrescu 	log_file[length - 2] = 'l';
6146bc14d9fSCristian Dumitrescu 	log_file[length - 1] = 'o';
6156bc14d9fSCristian Dumitrescu 	log_file[length] = 'g';
6166bc14d9fSCristian Dumitrescu 	log_file[length + 1] = 0;
6176bc14d9fSCristian Dumitrescu 
6186bc14d9fSCristian Dumitrescu 	buffer = malloc(MAX_LINE_SIZE);
6196bc14d9fSCristian Dumitrescu 	if (!buffer) {
6206bc14d9fSCristian Dumitrescu 		snprintf(out, out_size, MSG_OUT_OF_MEMORY);
6216bc14d9fSCristian Dumitrescu 		return;
6226bc14d9fSCristian Dumitrescu 	}
6236bc14d9fSCristian Dumitrescu 
6246bc14d9fSCristian Dumitrescu 	snprintf(buffer,
6256bc14d9fSCristian Dumitrescu 		 MAX_LINE_SIZE,
6266bc14d9fSCristian Dumitrescu 		 "gcc -c -O3 -fpic -Wno-deprecated-declarations -o %s %s "
6276bc14d9fSCristian Dumitrescu 		 "-I %s/lib/pipeline "
6286bc14d9fSCristian Dumitrescu 		 "-I %s/lib/eal/include "
6296bc14d9fSCristian Dumitrescu 		 "-I %s/lib/eal/x86/include "
6306bc14d9fSCristian Dumitrescu 		 "-I %s/lib/eal/include/generic "
6316bc14d9fSCristian Dumitrescu 		 "-I %s/lib/meter "
6326bc14d9fSCristian Dumitrescu 		 "-I %s/lib/port "
6336bc14d9fSCristian Dumitrescu 		 "-I %s/lib/table "
6346bc14d9fSCristian Dumitrescu 		 "-I %s/lib/pipeline "
6356bc14d9fSCristian Dumitrescu 		 "-I %s/config "
6366bc14d9fSCristian Dumitrescu 		 "-I %s/build "
6376bc14d9fSCristian Dumitrescu 		 "-I %s/lib/eal/linux/include "
6386bc14d9fSCristian Dumitrescu 		 ">%s 2>&1 "
6396bc14d9fSCristian Dumitrescu 		 "&& "
6406bc14d9fSCristian Dumitrescu 		 "gcc -shared %s -o %s "
6416bc14d9fSCristian Dumitrescu 		 ">>%s 2>&1",
6426bc14d9fSCristian Dumitrescu 		 obj_file,
6436bc14d9fSCristian Dumitrescu 		 code_file,
6446bc14d9fSCristian Dumitrescu 		 install_dir,
6456bc14d9fSCristian Dumitrescu 		 install_dir,
6466bc14d9fSCristian Dumitrescu 		 install_dir,
6476bc14d9fSCristian Dumitrescu 		 install_dir,
6486bc14d9fSCristian Dumitrescu 		 install_dir,
6496bc14d9fSCristian Dumitrescu 		 install_dir,
6506bc14d9fSCristian Dumitrescu 		 install_dir,
6516bc14d9fSCristian Dumitrescu 		 install_dir,
6526bc14d9fSCristian Dumitrescu 		 install_dir,
6536bc14d9fSCristian Dumitrescu 		 install_dir,
6546bc14d9fSCristian Dumitrescu 		 install_dir,
6556bc14d9fSCristian Dumitrescu 		 log_file,
6566bc14d9fSCristian Dumitrescu 		 obj_file,
6576bc14d9fSCristian Dumitrescu 		 lib_file,
6586bc14d9fSCristian Dumitrescu 		 log_file);
6596bc14d9fSCristian Dumitrescu 
6606bc14d9fSCristian Dumitrescu 	status = system(buffer);
6616bc14d9fSCristian Dumitrescu 	if (status) {
6626bc14d9fSCristian Dumitrescu 		snprintf(out,
6636bc14d9fSCristian Dumitrescu 			 out_size,
6646bc14d9fSCristian Dumitrescu 			 "Library build failed, see file \"%s\" for details.\n",
6656bc14d9fSCristian Dumitrescu 			 log_file);
6666bc14d9fSCristian Dumitrescu 		goto free;
6676bc14d9fSCristian Dumitrescu 	}
6686bc14d9fSCristian Dumitrescu 
6696bc14d9fSCristian Dumitrescu free:
6706bc14d9fSCristian Dumitrescu 	free(cwd);
6716bc14d9fSCristian Dumitrescu 	free(obj_file);
6726bc14d9fSCristian Dumitrescu 	free(log_file);
6736bc14d9fSCristian Dumitrescu 	free(buffer);
6746bc14d9fSCristian Dumitrescu }
6756bc14d9fSCristian Dumitrescu 
6765074e1d5SCristian Dumitrescu static const char cmd_pipeline_build_help[] =
67768b95704SCristian Dumitrescu "pipeline <pipeline_name> build lib <lib_file> io <iospec_file> numa <numa_node>\n";
6785074e1d5SCristian Dumitrescu 
6795074e1d5SCristian Dumitrescu static void
6805074e1d5SCristian Dumitrescu cmd_pipeline_build(char **tokens,
6815074e1d5SCristian Dumitrescu 	uint32_t n_tokens,
6825074e1d5SCristian Dumitrescu 	char *out,
6835074e1d5SCristian Dumitrescu 	size_t out_size,
68468b95704SCristian Dumitrescu 	void *obj __rte_unused)
6855074e1d5SCristian Dumitrescu {
68668b95704SCristian Dumitrescu 	struct rte_swx_pipeline *p = NULL;
68768b95704SCristian Dumitrescu 	struct rte_swx_ctl_pipeline *ctl = NULL;
68868b95704SCristian Dumitrescu 	char *pipeline_name, *lib_file_name, *iospec_file_name;
68968b95704SCristian Dumitrescu 	FILE *iospec_file = NULL;
69068b95704SCristian Dumitrescu 	uint32_t numa_node = 0;
69168b95704SCristian Dumitrescu 	int status = 0;
6925074e1d5SCristian Dumitrescu 
69368b95704SCristian Dumitrescu 	/* Parsing. */
69468b95704SCristian Dumitrescu 	if (n_tokens != 9) {
6955074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
6965074e1d5SCristian Dumitrescu 		return;
6975074e1d5SCristian Dumitrescu 	}
6985074e1d5SCristian Dumitrescu 
69968b95704SCristian Dumitrescu 	pipeline_name = tokens[1];
70068b95704SCristian Dumitrescu 
70168b95704SCristian Dumitrescu 	if (strcmp(tokens[2], "build")) {
70268b95704SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "build");
7035074e1d5SCristian Dumitrescu 		return;
7045074e1d5SCristian Dumitrescu 	}
7055074e1d5SCristian Dumitrescu 
70668b95704SCristian Dumitrescu 	if (strcmp(tokens[3], "lib")) {
70768b95704SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "lib");
7085074e1d5SCristian Dumitrescu 		return;
7095074e1d5SCristian Dumitrescu 	}
7105074e1d5SCristian Dumitrescu 
71168b95704SCristian Dumitrescu 	lib_file_name = tokens[4];
71268b95704SCristian Dumitrescu 
71368b95704SCristian Dumitrescu 	if (strcmp(tokens[5], "io")) {
71468b95704SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "io");
71568b95704SCristian Dumitrescu 		return;
71668b95704SCristian Dumitrescu 	}
71768b95704SCristian Dumitrescu 
71868b95704SCristian Dumitrescu 	iospec_file_name = tokens[6];
71968b95704SCristian Dumitrescu 
72068b95704SCristian Dumitrescu 	if (strcmp(tokens[7], "numa")) {
72168b95704SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "numa");
72268b95704SCristian Dumitrescu 		return;
72368b95704SCristian Dumitrescu 	}
72468b95704SCristian Dumitrescu 
72568b95704SCristian Dumitrescu 	if (parser_read_uint32(&numa_node, tokens[8])) {
72668b95704SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "numa_node");
72768b95704SCristian Dumitrescu 		return;
72868b95704SCristian Dumitrescu 	}
72968b95704SCristian Dumitrescu 
73068b95704SCristian Dumitrescu 	/* I/O spec file open. */
73168b95704SCristian Dumitrescu 	iospec_file = fopen(iospec_file_name, "r");
73268b95704SCristian Dumitrescu 	if (!iospec_file) {
73368b95704SCristian Dumitrescu 		snprintf(out, out_size, "Cannot open file \"%s\".\n", iospec_file_name);
73468b95704SCristian Dumitrescu 		return;
73568b95704SCristian Dumitrescu 	}
73668b95704SCristian Dumitrescu 
73768b95704SCristian Dumitrescu 	status = rte_swx_pipeline_build_from_lib(&p,
73868b95704SCristian Dumitrescu 						 pipeline_name,
73968b95704SCristian Dumitrescu 						 lib_file_name,
74068b95704SCristian Dumitrescu 						 iospec_file,
74168b95704SCristian Dumitrescu 						 (int)numa_node);
7425074e1d5SCristian Dumitrescu 	if (status) {
74368b95704SCristian Dumitrescu 		snprintf(out, out_size, "Pipeline build failed (%d).", status);
74468b95704SCristian Dumitrescu 		goto free;
7455074e1d5SCristian Dumitrescu 	}
7465074e1d5SCristian Dumitrescu 
74768b95704SCristian Dumitrescu 	ctl = rte_swx_ctl_pipeline_create(p);
74868b95704SCristian Dumitrescu 	if (!ctl) {
7495074e1d5SCristian Dumitrescu 		snprintf(out, out_size, "Pipeline control create failed.");
75068b95704SCristian Dumitrescu 		goto free;
7515074e1d5SCristian Dumitrescu 	}
75268b95704SCristian Dumitrescu 
75368b95704SCristian Dumitrescu free:
75468b95704SCristian Dumitrescu 	if (status)
75568b95704SCristian Dumitrescu 		rte_swx_pipeline_free(p);
75668b95704SCristian Dumitrescu 
75768b95704SCristian Dumitrescu 	if (iospec_file)
75868b95704SCristian Dumitrescu 		fclose(iospec_file);
7595074e1d5SCristian Dumitrescu }
7605074e1d5SCristian Dumitrescu 
761275ebefeSCristian Dumitrescu static void
762275ebefeSCristian Dumitrescu table_entry_free(struct rte_swx_table_entry *entry)
763275ebefeSCristian Dumitrescu {
764275ebefeSCristian Dumitrescu 	if (!entry)
765275ebefeSCristian Dumitrescu 		return;
766275ebefeSCristian Dumitrescu 
767275ebefeSCristian Dumitrescu 	free(entry->key);
768275ebefeSCristian Dumitrescu 	free(entry->key_mask);
769275ebefeSCristian Dumitrescu 	free(entry->action_data);
770275ebefeSCristian Dumitrescu 	free(entry);
771275ebefeSCristian Dumitrescu }
772275ebefeSCristian Dumitrescu 
77375129cebSChurchill Khangar static int
77475129cebSChurchill Khangar pipeline_table_entries_add(struct rte_swx_ctl_pipeline *p,
77575129cebSChurchill Khangar 			   const char *table_name,
77675129cebSChurchill Khangar 			   FILE *file,
77775129cebSChurchill Khangar 			   uint32_t *file_line_number)
77875129cebSChurchill Khangar {
77975129cebSChurchill Khangar 	char *line = NULL;
78075129cebSChurchill Khangar 	uint32_t line_id = 0;
78175129cebSChurchill Khangar 	int status = 0;
78275129cebSChurchill Khangar 
78375129cebSChurchill Khangar 	/* Buffer allocation. */
78475129cebSChurchill Khangar 	line = malloc(MAX_LINE_SIZE);
78575129cebSChurchill Khangar 	if (!line)
78675129cebSChurchill Khangar 		return -ENOMEM;
78775129cebSChurchill Khangar 
78875129cebSChurchill Khangar 	/* File read. */
78975129cebSChurchill Khangar 	for (line_id = 1; ; line_id++) {
79075129cebSChurchill Khangar 		struct rte_swx_table_entry *entry;
79175129cebSChurchill Khangar 		int is_blank_or_comment;
79275129cebSChurchill Khangar 
79375129cebSChurchill Khangar 		if (fgets(line, MAX_LINE_SIZE, file) == NULL)
79475129cebSChurchill Khangar 			break;
79575129cebSChurchill Khangar 
79675129cebSChurchill Khangar 		entry = rte_swx_ctl_pipeline_table_entry_read(p,
79775129cebSChurchill Khangar 							      table_name,
79875129cebSChurchill Khangar 							      line,
79975129cebSChurchill Khangar 							      &is_blank_or_comment);
80075129cebSChurchill Khangar 		if (!entry) {
80175129cebSChurchill Khangar 			if (is_blank_or_comment)
80275129cebSChurchill Khangar 				continue;
80375129cebSChurchill Khangar 
80475129cebSChurchill Khangar 			status = -EINVAL;
80575129cebSChurchill Khangar 			goto error;
80675129cebSChurchill Khangar 		}
80775129cebSChurchill Khangar 
80875129cebSChurchill Khangar 		status = rte_swx_ctl_pipeline_table_entry_add(p,
80975129cebSChurchill Khangar 							      table_name,
81075129cebSChurchill Khangar 							      entry);
81175129cebSChurchill Khangar 		table_entry_free(entry);
81275129cebSChurchill Khangar 		if (status)
81375129cebSChurchill Khangar 			goto error;
81475129cebSChurchill Khangar 	}
81575129cebSChurchill Khangar 
81675129cebSChurchill Khangar error:
81775129cebSChurchill Khangar 	free(line);
81875129cebSChurchill Khangar 	*file_line_number = line_id;
81975129cebSChurchill Khangar 	return status;
82075129cebSChurchill Khangar }
82175129cebSChurchill Khangar 
82275129cebSChurchill Khangar static const char cmd_pipeline_table_add_help[] =
82375129cebSChurchill Khangar "pipeline <pipeline_name> table <table_name> add <file_name>\n";
8245074e1d5SCristian Dumitrescu 
8255074e1d5SCristian Dumitrescu static void
82675129cebSChurchill Khangar cmd_pipeline_table_add(char **tokens,
8275074e1d5SCristian Dumitrescu 		       uint32_t n_tokens,
8285074e1d5SCristian Dumitrescu 		       char *out,
8295074e1d5SCristian Dumitrescu 		       size_t out_size,
830b9559f94SCristian Dumitrescu 		       void *obj __rte_unused)
8315074e1d5SCristian Dumitrescu {
832b9559f94SCristian Dumitrescu 	struct rte_swx_ctl_pipeline *ctl;
83375129cebSChurchill Khangar 	char *pipeline_name, *table_name, *file_name;
83475129cebSChurchill Khangar 	FILE *file = NULL;
83575129cebSChurchill Khangar 	uint32_t file_line_number = 0;
8365074e1d5SCristian Dumitrescu 	int status;
8375074e1d5SCristian Dumitrescu 
83875129cebSChurchill Khangar 	if (n_tokens != 6) {
8395074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
8405074e1d5SCristian Dumitrescu 		return;
8415074e1d5SCristian Dumitrescu 	}
8425074e1d5SCristian Dumitrescu 
8435074e1d5SCristian Dumitrescu 	pipeline_name = tokens[1];
844b9559f94SCristian Dumitrescu 	ctl = rte_swx_ctl_pipeline_find(pipeline_name);
845b9559f94SCristian Dumitrescu 	if (!ctl) {
8465074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
8475074e1d5SCristian Dumitrescu 		return;
8485074e1d5SCristian Dumitrescu 	}
8495074e1d5SCristian Dumitrescu 
85075129cebSChurchill Khangar 	table_name = tokens[3];
85175129cebSChurchill Khangar 
85275129cebSChurchill Khangar 	file_name = tokens[5];
85375129cebSChurchill Khangar 	file = fopen(file_name, "r");
85475129cebSChurchill Khangar 	if (!file) {
85575129cebSChurchill Khangar 		snprintf(out, out_size, "Cannot open file %s.\n", file_name);
85675129cebSChurchill Khangar 		return;
85775129cebSChurchill Khangar 	}
85875129cebSChurchill Khangar 
859b9559f94SCristian Dumitrescu 	status = pipeline_table_entries_add(ctl,
86075129cebSChurchill Khangar 					    table_name,
86175129cebSChurchill Khangar 					    file,
86275129cebSChurchill Khangar 					    &file_line_number);
86375129cebSChurchill Khangar 	if (status)
86475129cebSChurchill Khangar 		snprintf(out, out_size, "Invalid entry in file %s at line %u\n",
86575129cebSChurchill Khangar 			 file_name,
86675129cebSChurchill Khangar 			 file_line_number);
86775129cebSChurchill Khangar 
86875129cebSChurchill Khangar 	fclose(file);
86975129cebSChurchill Khangar }
87075129cebSChurchill Khangar 
87175129cebSChurchill Khangar static int
87275129cebSChurchill Khangar pipeline_table_entries_delete(struct rte_swx_ctl_pipeline *p,
87375129cebSChurchill Khangar 			      const char *table_name,
87475129cebSChurchill Khangar 			      FILE *file,
87575129cebSChurchill Khangar 			      uint32_t *file_line_number)
87675129cebSChurchill Khangar {
87775129cebSChurchill Khangar 	char *line = NULL;
87875129cebSChurchill Khangar 	uint32_t line_id = 0;
87975129cebSChurchill Khangar 	int status = 0;
88075129cebSChurchill Khangar 
88175129cebSChurchill Khangar 	/* Buffer allocation. */
88275129cebSChurchill Khangar 	line = malloc(MAX_LINE_SIZE);
88375129cebSChurchill Khangar 	if (!line)
88475129cebSChurchill Khangar 		return -ENOMEM;
88575129cebSChurchill Khangar 
88675129cebSChurchill Khangar 	/* File read. */
88775129cebSChurchill Khangar 	for (line_id = 1; ; line_id++) {
88875129cebSChurchill Khangar 		struct rte_swx_table_entry *entry;
88975129cebSChurchill Khangar 		int is_blank_or_comment;
89075129cebSChurchill Khangar 
89175129cebSChurchill Khangar 		if (fgets(line, MAX_LINE_SIZE, file) == NULL)
89275129cebSChurchill Khangar 			break;
89375129cebSChurchill Khangar 
89475129cebSChurchill Khangar 		entry = rte_swx_ctl_pipeline_table_entry_read(p,
89575129cebSChurchill Khangar 							      table_name,
89675129cebSChurchill Khangar 							      line,
89775129cebSChurchill Khangar 							      &is_blank_or_comment);
89875129cebSChurchill Khangar 		if (!entry) {
89975129cebSChurchill Khangar 			if (is_blank_or_comment)
90075129cebSChurchill Khangar 				continue;
90175129cebSChurchill Khangar 
90275129cebSChurchill Khangar 			status = -EINVAL;
90375129cebSChurchill Khangar 			goto error;
90475129cebSChurchill Khangar 		}
90575129cebSChurchill Khangar 
90675129cebSChurchill Khangar 		status = rte_swx_ctl_pipeline_table_entry_delete(p,
90775129cebSChurchill Khangar 								 table_name,
90875129cebSChurchill Khangar 								 entry);
90975129cebSChurchill Khangar 		table_entry_free(entry);
91075129cebSChurchill Khangar 		if (status)
91175129cebSChurchill Khangar 			goto error;
91275129cebSChurchill Khangar 	}
91375129cebSChurchill Khangar 
91475129cebSChurchill Khangar error:
91575129cebSChurchill Khangar 	*file_line_number = line_id;
91675129cebSChurchill Khangar 	free(line);
91775129cebSChurchill Khangar 	return status;
91875129cebSChurchill Khangar }
91975129cebSChurchill Khangar 
92075129cebSChurchill Khangar static const char cmd_pipeline_table_delete_help[] =
92175129cebSChurchill Khangar "pipeline <pipeline_name> table <table_name> delete <file_name>\n";
92275129cebSChurchill Khangar 
92375129cebSChurchill Khangar static void
92475129cebSChurchill Khangar cmd_pipeline_table_delete(char **tokens,
92575129cebSChurchill Khangar 			  uint32_t n_tokens,
92675129cebSChurchill Khangar 			  char *out,
92775129cebSChurchill Khangar 			  size_t out_size,
928b9559f94SCristian Dumitrescu 			  void *obj __rte_unused)
92975129cebSChurchill Khangar {
930b9559f94SCristian Dumitrescu 	struct rte_swx_ctl_pipeline *ctl;
93175129cebSChurchill Khangar 	char *pipeline_name, *table_name, *file_name;
93275129cebSChurchill Khangar 	FILE *file = NULL;
93375129cebSChurchill Khangar 	uint32_t file_line_number = 0;
93475129cebSChurchill Khangar 	int status;
93575129cebSChurchill Khangar 
93675129cebSChurchill Khangar 	if (n_tokens != 6) {
93775129cebSChurchill Khangar 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
93875129cebSChurchill Khangar 		return;
93975129cebSChurchill Khangar 	}
94075129cebSChurchill Khangar 
94175129cebSChurchill Khangar 	pipeline_name = tokens[1];
942b9559f94SCristian Dumitrescu 	ctl = rte_swx_ctl_pipeline_find(pipeline_name);
943b9559f94SCristian Dumitrescu 	if (!ctl) {
94475129cebSChurchill Khangar 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
9455074e1d5SCristian Dumitrescu 		return;
9465074e1d5SCristian Dumitrescu 	}
9475074e1d5SCristian Dumitrescu 
9485074e1d5SCristian Dumitrescu 	table_name = tokens[3];
9495074e1d5SCristian Dumitrescu 
95075129cebSChurchill Khangar 	file_name = tokens[5];
95175129cebSChurchill Khangar 	file = fopen(file_name, "r");
95275129cebSChurchill Khangar 	if (!file) {
95375129cebSChurchill Khangar 		snprintf(out, out_size, "Cannot open file %s.\n", file_name);
9545074e1d5SCristian Dumitrescu 		return;
9555074e1d5SCristian Dumitrescu 	}
9565074e1d5SCristian Dumitrescu 
957b9559f94SCristian Dumitrescu 	status = pipeline_table_entries_delete(ctl,
95875129cebSChurchill Khangar 					       table_name,
95975129cebSChurchill Khangar 					       file,
96075129cebSChurchill Khangar 					       &file_line_number);
96175129cebSChurchill Khangar 	if (status)
96275129cebSChurchill Khangar 		snprintf(out, out_size, "Invalid entry in file %s at line %u\n",
96375129cebSChurchill Khangar 			 file_name,
96475129cebSChurchill Khangar 			 file_line_number);
9655074e1d5SCristian Dumitrescu 
96675129cebSChurchill Khangar 	fclose(file);
9675074e1d5SCristian Dumitrescu }
9685074e1d5SCristian Dumitrescu 
96975129cebSChurchill Khangar static int
97075129cebSChurchill Khangar pipeline_table_default_entry_add(struct rte_swx_ctl_pipeline *p,
97175129cebSChurchill Khangar 				 const char *table_name,
97275129cebSChurchill Khangar 				 FILE *file,
97375129cebSChurchill Khangar 				 uint32_t *file_line_number)
97475129cebSChurchill Khangar {
97575129cebSChurchill Khangar 	char *line = NULL;
97675129cebSChurchill Khangar 	uint32_t line_id = 0;
97775129cebSChurchill Khangar 	int status = 0;
9785074e1d5SCristian Dumitrescu 
9795074e1d5SCristian Dumitrescu 	/* Buffer allocation. */
98075129cebSChurchill Khangar 	line = malloc(MAX_LINE_SIZE);
98175129cebSChurchill Khangar 	if (!line)
98275129cebSChurchill Khangar 		return -ENOMEM;
9835074e1d5SCristian Dumitrescu 
98475129cebSChurchill Khangar 	/* File read. */
9855074e1d5SCristian Dumitrescu 	for (line_id = 1; ; line_id++) {
9865074e1d5SCristian Dumitrescu 		struct rte_swx_table_entry *entry;
987cff9a717SCristian Dumitrescu 		int is_blank_or_comment;
9885074e1d5SCristian Dumitrescu 
98975129cebSChurchill Khangar 		if (fgets(line, MAX_LINE_SIZE, file) == NULL)
9905074e1d5SCristian Dumitrescu 			break;
9915074e1d5SCristian Dumitrescu 
99275129cebSChurchill Khangar 		entry = rte_swx_ctl_pipeline_table_entry_read(p,
9935074e1d5SCristian Dumitrescu 							      table_name,
994cff9a717SCristian Dumitrescu 							      line,
995cff9a717SCristian Dumitrescu 							      &is_blank_or_comment);
9965074e1d5SCristian Dumitrescu 		if (!entry) {
997cff9a717SCristian Dumitrescu 			if (is_blank_or_comment)
998cff9a717SCristian Dumitrescu 				continue;
999cff9a717SCristian Dumitrescu 
100075129cebSChurchill Khangar 			status = -EINVAL;
10015074e1d5SCristian Dumitrescu 			goto error;
10025074e1d5SCristian Dumitrescu 		}
10035074e1d5SCristian Dumitrescu 
100475129cebSChurchill Khangar 		status = rte_swx_ctl_pipeline_table_default_entry_add(p,
10055074e1d5SCristian Dumitrescu 								      table_name,
10065074e1d5SCristian Dumitrescu 								      entry);
1007275ebefeSCristian Dumitrescu 		table_entry_free(entry);
100875129cebSChurchill Khangar 		if (status)
10095074e1d5SCristian Dumitrescu 			goto error;
10105074e1d5SCristian Dumitrescu 	}
101175129cebSChurchill Khangar 
101275129cebSChurchill Khangar error:
101375129cebSChurchill Khangar 	*file_line_number = line_id;
101475129cebSChurchill Khangar 	free(line);
101575129cebSChurchill Khangar 	return status;
10165074e1d5SCristian Dumitrescu }
10175074e1d5SCristian Dumitrescu 
101875129cebSChurchill Khangar static const char cmd_pipeline_table_default_help[] =
101975129cebSChurchill Khangar "pipeline <pipeline_name> table <table_name> default <file_name>\n";
10205074e1d5SCristian Dumitrescu 
102175129cebSChurchill Khangar static void
102275129cebSChurchill Khangar cmd_pipeline_table_default(char **tokens,
102375129cebSChurchill Khangar 			   uint32_t n_tokens,
102475129cebSChurchill Khangar 			   char *out,
102575129cebSChurchill Khangar 			   size_t out_size,
1026b9559f94SCristian Dumitrescu 			   void *obj __rte_unused)
102775129cebSChurchill Khangar {
1028b9559f94SCristian Dumitrescu 	struct rte_swx_ctl_pipeline *ctl;
102975129cebSChurchill Khangar 	char *pipeline_name, *table_name, *file_name;
103075129cebSChurchill Khangar 	FILE *file = NULL;
103175129cebSChurchill Khangar 	uint32_t file_line_number = 0;
103275129cebSChurchill Khangar 	int status;
10335074e1d5SCristian Dumitrescu 
103475129cebSChurchill Khangar 	if (n_tokens != 6) {
103575129cebSChurchill Khangar 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
103675129cebSChurchill Khangar 		return;
103775129cebSChurchill Khangar 	}
10385074e1d5SCristian Dumitrescu 
103975129cebSChurchill Khangar 	pipeline_name = tokens[1];
1040b9559f94SCristian Dumitrescu 	ctl = rte_swx_ctl_pipeline_find(pipeline_name);
1041b9559f94SCristian Dumitrescu 	if (!ctl) {
104275129cebSChurchill Khangar 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
104375129cebSChurchill Khangar 		return;
104475129cebSChurchill Khangar 	}
104575129cebSChurchill Khangar 
104675129cebSChurchill Khangar 	table_name = tokens[3];
104775129cebSChurchill Khangar 
104875129cebSChurchill Khangar 	file_name = tokens[5];
104975129cebSChurchill Khangar 	file = fopen(file_name, "r");
105075129cebSChurchill Khangar 	if (!file) {
105175129cebSChurchill Khangar 		snprintf(out, out_size, "Cannot open file %s.\n", file_name);
105275129cebSChurchill Khangar 		return;
105375129cebSChurchill Khangar 	}
105475129cebSChurchill Khangar 
1055b9559f94SCristian Dumitrescu 	status = pipeline_table_default_entry_add(ctl,
10565074e1d5SCristian Dumitrescu 						  table_name,
105775129cebSChurchill Khangar 						  file,
105875129cebSChurchill Khangar 						  &file_line_number);
105975129cebSChurchill Khangar 	if (status)
106075129cebSChurchill Khangar 		snprintf(out, out_size, "Invalid entry in file %s at line %u\n",
106175129cebSChurchill Khangar 			 file_name,
106275129cebSChurchill Khangar 			 file_line_number);
1063cff9a717SCristian Dumitrescu 
106475129cebSChurchill Khangar 	fclose(file);
10655074e1d5SCristian Dumitrescu }
10665074e1d5SCristian Dumitrescu 
106775129cebSChurchill Khangar static const char cmd_pipeline_table_show_help[] =
1068a4c1146cSCristian Dumitrescu "pipeline <pipeline_name> table <table_name> show [filename]\n";
106975129cebSChurchill Khangar 
107075129cebSChurchill Khangar static void
107175129cebSChurchill Khangar cmd_pipeline_table_show(char **tokens,
107275129cebSChurchill Khangar 	uint32_t n_tokens,
107375129cebSChurchill Khangar 	char *out,
107475129cebSChurchill Khangar 	size_t out_size,
1075b9559f94SCristian Dumitrescu 	void *obj __rte_unused)
107675129cebSChurchill Khangar {
1077b9559f94SCristian Dumitrescu 	struct rte_swx_ctl_pipeline *ctl;
107875129cebSChurchill Khangar 	char *pipeline_name, *table_name;
1079a4c1146cSCristian Dumitrescu 	FILE *file = NULL;
108075129cebSChurchill Khangar 	int status;
108175129cebSChurchill Khangar 
1082a4c1146cSCristian Dumitrescu 	if (n_tokens != 5 && n_tokens != 6) {
108375129cebSChurchill Khangar 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
108475129cebSChurchill Khangar 		return;
10855074e1d5SCristian Dumitrescu 	}
10865074e1d5SCristian Dumitrescu 
108775129cebSChurchill Khangar 	pipeline_name = tokens[1];
1088b9559f94SCristian Dumitrescu 	ctl = rte_swx_ctl_pipeline_find(pipeline_name);
1089b9559f94SCristian Dumitrescu 	if (!ctl) {
109075129cebSChurchill Khangar 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
109175129cebSChurchill Khangar 		return;
10925074e1d5SCristian Dumitrescu 	}
10935074e1d5SCristian Dumitrescu 
109475129cebSChurchill Khangar 	table_name = tokens[3];
1095a4c1146cSCristian Dumitrescu 	file = (n_tokens == 6) ? fopen(tokens[5], "w") : stdout;
1096a4c1146cSCristian Dumitrescu 	if (!file) {
1097a4c1146cSCristian Dumitrescu 		snprintf(out, out_size, "Cannot open file %s.\n", tokens[5]);
1098a4c1146cSCristian Dumitrescu 		return;
1099a4c1146cSCristian Dumitrescu 	}
1100a4c1146cSCristian Dumitrescu 
1101b9559f94SCristian Dumitrescu 	status = rte_swx_ctl_pipeline_table_fprintf(file, ctl, table_name);
110275129cebSChurchill Khangar 	if (status)
110375129cebSChurchill Khangar 		snprintf(out, out_size, MSG_ARG_INVALID, "table_name");
1104a4c1146cSCristian Dumitrescu 
1105a4c1146cSCristian Dumitrescu 	if (file)
1106a4c1146cSCristian Dumitrescu 		fclose(file);
11075074e1d5SCristian Dumitrescu }
110875129cebSChurchill Khangar 
1109598fe0ddSCristian Dumitrescu static const char cmd_pipeline_selector_group_add_help[] =
1110598fe0ddSCristian Dumitrescu "pipeline <pipeline_name> selector <selector_name> group add\n";
1111598fe0ddSCristian Dumitrescu 
1112598fe0ddSCristian Dumitrescu static void
1113598fe0ddSCristian Dumitrescu cmd_pipeline_selector_group_add(char **tokens,
1114598fe0ddSCristian Dumitrescu 	uint32_t n_tokens,
1115598fe0ddSCristian Dumitrescu 	char *out,
1116598fe0ddSCristian Dumitrescu 	size_t out_size,
1117b9559f94SCristian Dumitrescu 	void *obj __rte_unused)
1118598fe0ddSCristian Dumitrescu {
1119b9559f94SCristian Dumitrescu 	struct rte_swx_ctl_pipeline *ctl;
1120598fe0ddSCristian Dumitrescu 	char *pipeline_name, *selector_name;
1121598fe0ddSCristian Dumitrescu 	uint32_t group_id;
1122598fe0ddSCristian Dumitrescu 	int status;
1123598fe0ddSCristian Dumitrescu 
1124598fe0ddSCristian Dumitrescu 	if (n_tokens != 6) {
1125598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1126598fe0ddSCristian Dumitrescu 		return;
1127598fe0ddSCristian Dumitrescu 	}
1128598fe0ddSCristian Dumitrescu 
1129598fe0ddSCristian Dumitrescu 	pipeline_name = tokens[1];
1130b9559f94SCristian Dumitrescu 	ctl = rte_swx_ctl_pipeline_find(pipeline_name);
1131b9559f94SCristian Dumitrescu 	if (!ctl) {
1132598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
1133598fe0ddSCristian Dumitrescu 		return;
1134598fe0ddSCristian Dumitrescu 	}
1135598fe0ddSCristian Dumitrescu 
1136598fe0ddSCristian Dumitrescu 	if (strcmp(tokens[2], "selector") != 0) {
1137598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "selector");
1138598fe0ddSCristian Dumitrescu 		return;
1139598fe0ddSCristian Dumitrescu 	}
1140598fe0ddSCristian Dumitrescu 
1141598fe0ddSCristian Dumitrescu 	selector_name = tokens[3];
1142598fe0ddSCristian Dumitrescu 
1143598fe0ddSCristian Dumitrescu 	if (strcmp(tokens[4], "group") ||
1144598fe0ddSCristian Dumitrescu 		strcmp(tokens[5], "add")) {
1145598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "group add");
1146598fe0ddSCristian Dumitrescu 		return;
1147598fe0ddSCristian Dumitrescu 	}
1148598fe0ddSCristian Dumitrescu 
1149b9559f94SCristian Dumitrescu 	status = rte_swx_ctl_pipeline_selector_group_add(ctl,
1150598fe0ddSCristian Dumitrescu 		selector_name,
1151598fe0ddSCristian Dumitrescu 		&group_id);
1152598fe0ddSCristian Dumitrescu 	if (status)
1153598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
1154598fe0ddSCristian Dumitrescu 	else
1155598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, "Group ID: %u\n", group_id);
1156598fe0ddSCristian Dumitrescu }
1157598fe0ddSCristian Dumitrescu 
1158598fe0ddSCristian Dumitrescu static const char cmd_pipeline_selector_group_delete_help[] =
1159598fe0ddSCristian Dumitrescu "pipeline <pipeline_name> selector <selector_name> group delete <group_id>\n";
1160598fe0ddSCristian Dumitrescu 
1161598fe0ddSCristian Dumitrescu static void
1162598fe0ddSCristian Dumitrescu cmd_pipeline_selector_group_delete(char **tokens,
1163598fe0ddSCristian Dumitrescu 	uint32_t n_tokens,
1164598fe0ddSCristian Dumitrescu 	char *out,
1165598fe0ddSCristian Dumitrescu 	size_t out_size,
1166b9559f94SCristian Dumitrescu 	void *obj __rte_unused)
1167598fe0ddSCristian Dumitrescu {
1168b9559f94SCristian Dumitrescu 	struct rte_swx_ctl_pipeline *ctl;
1169598fe0ddSCristian Dumitrescu 	char *pipeline_name, *selector_name;
1170598fe0ddSCristian Dumitrescu 	uint32_t group_id;
1171598fe0ddSCristian Dumitrescu 	int status;
1172598fe0ddSCristian Dumitrescu 
1173598fe0ddSCristian Dumitrescu 	if (n_tokens != 7) {
1174598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1175598fe0ddSCristian Dumitrescu 		return;
1176598fe0ddSCristian Dumitrescu 	}
1177598fe0ddSCristian Dumitrescu 
1178598fe0ddSCristian Dumitrescu 	pipeline_name = tokens[1];
1179b9559f94SCristian Dumitrescu 	ctl = rte_swx_ctl_pipeline_find(pipeline_name);
1180b9559f94SCristian Dumitrescu 	if (!ctl) {
1181598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
1182598fe0ddSCristian Dumitrescu 		return;
1183598fe0ddSCristian Dumitrescu 	}
1184598fe0ddSCristian Dumitrescu 
1185598fe0ddSCristian Dumitrescu 	if (strcmp(tokens[2], "selector") != 0) {
1186598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "selector");
1187598fe0ddSCristian Dumitrescu 		return;
1188598fe0ddSCristian Dumitrescu 	}
1189598fe0ddSCristian Dumitrescu 
1190598fe0ddSCristian Dumitrescu 	selector_name = tokens[3];
1191598fe0ddSCristian Dumitrescu 
1192598fe0ddSCristian Dumitrescu 	if (strcmp(tokens[4], "group") ||
1193598fe0ddSCristian Dumitrescu 		strcmp(tokens[5], "delete")) {
1194598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "group delete");
1195598fe0ddSCristian Dumitrescu 		return;
1196598fe0ddSCristian Dumitrescu 	}
1197598fe0ddSCristian Dumitrescu 
1198598fe0ddSCristian Dumitrescu 	if (parser_read_uint32(&group_id, tokens[6]) != 0) {
1199598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "group_id");
1200598fe0ddSCristian Dumitrescu 		return;
1201598fe0ddSCristian Dumitrescu 	}
1202598fe0ddSCristian Dumitrescu 
1203b9559f94SCristian Dumitrescu 	status = rte_swx_ctl_pipeline_selector_group_delete(ctl,
1204598fe0ddSCristian Dumitrescu 		selector_name,
1205598fe0ddSCristian Dumitrescu 		group_id);
1206598fe0ddSCristian Dumitrescu 	if (status)
1207598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
1208598fe0ddSCristian Dumitrescu }
1209598fe0ddSCristian Dumitrescu 
1210598fe0ddSCristian Dumitrescu #define GROUP_MEMBER_INFO_TOKENS_MAX 6
1211598fe0ddSCristian Dumitrescu 
1212598fe0ddSCristian Dumitrescu static int
1213598fe0ddSCristian Dumitrescu token_is_comment(const char *token)
1214598fe0ddSCristian Dumitrescu {
1215598fe0ddSCristian Dumitrescu 	if ((token[0] == '#') ||
1216598fe0ddSCristian Dumitrescu 	    (token[0] == ';') ||
1217598fe0ddSCristian Dumitrescu 	    ((token[0] == '/') && (token[1] == '/')))
1218598fe0ddSCristian Dumitrescu 		return 1; /* TRUE. */
1219598fe0ddSCristian Dumitrescu 
1220598fe0ddSCristian Dumitrescu 	return 0; /* FALSE. */
1221598fe0ddSCristian Dumitrescu }
1222598fe0ddSCristian Dumitrescu 
1223598fe0ddSCristian Dumitrescu static int
1224598fe0ddSCristian Dumitrescu pipeline_selector_group_member_read(const char *string,
1225598fe0ddSCristian Dumitrescu 				      uint32_t *group_id,
1226598fe0ddSCristian Dumitrescu 				      uint32_t *member_id,
1227598fe0ddSCristian Dumitrescu 				      uint32_t *weight,
1228598fe0ddSCristian Dumitrescu 				      int *is_blank_or_comment)
1229598fe0ddSCristian Dumitrescu {
1230598fe0ddSCristian Dumitrescu 	char *token_array[GROUP_MEMBER_INFO_TOKENS_MAX], **tokens;
1231598fe0ddSCristian Dumitrescu 	char *s0 = NULL, *s;
123200b67591SAli Alnubani 	uint32_t n_tokens = 0, group_id_val = 0, member_id_val = 0, weight_val = 0;
1233598fe0ddSCristian Dumitrescu 	int blank_or_comment = 0;
1234598fe0ddSCristian Dumitrescu 
1235598fe0ddSCristian Dumitrescu 	/* Check input arguments. */
1236598fe0ddSCristian Dumitrescu 	if (!string || !string[0])
1237598fe0ddSCristian Dumitrescu 		goto error;
1238598fe0ddSCristian Dumitrescu 
1239598fe0ddSCristian Dumitrescu 	/* Memory allocation. */
1240598fe0ddSCristian Dumitrescu 	s0 = strdup(string);
1241598fe0ddSCristian Dumitrescu 	if (!s0)
1242598fe0ddSCristian Dumitrescu 		goto error;
1243598fe0ddSCristian Dumitrescu 
1244598fe0ddSCristian Dumitrescu 	/* Parse the string into tokens. */
1245598fe0ddSCristian Dumitrescu 	for (s = s0; ; ) {
1246598fe0ddSCristian Dumitrescu 		char *token;
1247598fe0ddSCristian Dumitrescu 
1248598fe0ddSCristian Dumitrescu 		token = strtok_r(s, " \f\n\r\t\v", &s);
1249598fe0ddSCristian Dumitrescu 		if (!token || token_is_comment(token))
1250598fe0ddSCristian Dumitrescu 			break;
1251598fe0ddSCristian Dumitrescu 
1252cfcc7bf8SCristian Dumitrescu 		if (n_tokens >= GROUP_MEMBER_INFO_TOKENS_MAX)
1253598fe0ddSCristian Dumitrescu 			goto error;
1254598fe0ddSCristian Dumitrescu 
1255598fe0ddSCristian Dumitrescu 		token_array[n_tokens] = token;
1256598fe0ddSCristian Dumitrescu 		n_tokens++;
1257598fe0ddSCristian Dumitrescu 	}
1258598fe0ddSCristian Dumitrescu 
1259598fe0ddSCristian Dumitrescu 	if (!n_tokens) {
1260598fe0ddSCristian Dumitrescu 		blank_or_comment = 1;
1261598fe0ddSCristian Dumitrescu 		goto error;
1262598fe0ddSCristian Dumitrescu 	}
1263598fe0ddSCristian Dumitrescu 
1264598fe0ddSCristian Dumitrescu 	tokens = token_array;
1265598fe0ddSCristian Dumitrescu 
1266598fe0ddSCristian Dumitrescu 	if (n_tokens < 4 ||
1267598fe0ddSCristian Dumitrescu 		strcmp(tokens[0], "group") ||
1268598fe0ddSCristian Dumitrescu 		strcmp(tokens[2], "member"))
1269598fe0ddSCristian Dumitrescu 		goto error;
1270598fe0ddSCristian Dumitrescu 
1271598fe0ddSCristian Dumitrescu 	/*
1272598fe0ddSCristian Dumitrescu 	 * Group ID.
1273598fe0ddSCristian Dumitrescu 	 */
1274598fe0ddSCristian Dumitrescu 	if (parser_read_uint32(&group_id_val, tokens[1]) != 0)
1275598fe0ddSCristian Dumitrescu 		goto error;
1276598fe0ddSCristian Dumitrescu 	*group_id = group_id_val;
1277598fe0ddSCristian Dumitrescu 
1278598fe0ddSCristian Dumitrescu 	/*
1279598fe0ddSCristian Dumitrescu 	 * Member ID.
1280598fe0ddSCristian Dumitrescu 	 */
1281598fe0ddSCristian Dumitrescu 	if (parser_read_uint32(&member_id_val, tokens[3]) != 0)
1282598fe0ddSCristian Dumitrescu 		goto error;
1283598fe0ddSCristian Dumitrescu 	*member_id = member_id_val;
1284598fe0ddSCristian Dumitrescu 
1285598fe0ddSCristian Dumitrescu 	tokens += 4;
1286598fe0ddSCristian Dumitrescu 	n_tokens -= 4;
1287598fe0ddSCristian Dumitrescu 
1288598fe0ddSCristian Dumitrescu 	/*
1289598fe0ddSCristian Dumitrescu 	 * Weight.
1290598fe0ddSCristian Dumitrescu 	 */
1291598fe0ddSCristian Dumitrescu 	if (n_tokens && !strcmp(tokens[0], "weight")) {
1292598fe0ddSCristian Dumitrescu 		if (n_tokens < 2)
1293598fe0ddSCristian Dumitrescu 			goto error;
1294598fe0ddSCristian Dumitrescu 
1295598fe0ddSCristian Dumitrescu 		if (parser_read_uint32(&weight_val, tokens[1]) != 0)
1296598fe0ddSCristian Dumitrescu 			goto error;
1297598fe0ddSCristian Dumitrescu 		*weight = weight_val;
1298598fe0ddSCristian Dumitrescu 
1299598fe0ddSCristian Dumitrescu 		tokens += 2;
1300598fe0ddSCristian Dumitrescu 		n_tokens -= 2;
1301598fe0ddSCristian Dumitrescu 	}
1302598fe0ddSCristian Dumitrescu 
1303598fe0ddSCristian Dumitrescu 	if (n_tokens)
1304598fe0ddSCristian Dumitrescu 		goto error;
1305598fe0ddSCristian Dumitrescu 
1306598fe0ddSCristian Dumitrescu 	free(s0);
1307598fe0ddSCristian Dumitrescu 	return 0;
1308598fe0ddSCristian Dumitrescu 
1309598fe0ddSCristian Dumitrescu error:
1310598fe0ddSCristian Dumitrescu 	free(s0);
1311598fe0ddSCristian Dumitrescu 	if (is_blank_or_comment)
1312598fe0ddSCristian Dumitrescu 		*is_blank_or_comment = blank_or_comment;
1313598fe0ddSCristian Dumitrescu 	return -EINVAL;
1314598fe0ddSCristian Dumitrescu }
1315598fe0ddSCristian Dumitrescu 
1316598fe0ddSCristian Dumitrescu static int
1317598fe0ddSCristian Dumitrescu pipeline_selector_group_members_add(struct rte_swx_ctl_pipeline *p,
1318598fe0ddSCristian Dumitrescu 			   const char *selector_name,
1319598fe0ddSCristian Dumitrescu 			   FILE *file,
1320598fe0ddSCristian Dumitrescu 			   uint32_t *file_line_number)
1321598fe0ddSCristian Dumitrescu {
1322598fe0ddSCristian Dumitrescu 	char *line = NULL;
1323598fe0ddSCristian Dumitrescu 	uint32_t line_id = 0;
1324598fe0ddSCristian Dumitrescu 	int status = 0;
1325598fe0ddSCristian Dumitrescu 
1326598fe0ddSCristian Dumitrescu 	/* Buffer allocation. */
1327598fe0ddSCristian Dumitrescu 	line = malloc(MAX_LINE_SIZE);
1328598fe0ddSCristian Dumitrescu 	if (!line)
1329598fe0ddSCristian Dumitrescu 		return -ENOMEM;
1330598fe0ddSCristian Dumitrescu 
1331598fe0ddSCristian Dumitrescu 	/* File read. */
1332598fe0ddSCristian Dumitrescu 	for (line_id = 1; ; line_id++) {
1333598fe0ddSCristian Dumitrescu 		uint32_t group_id, member_id, weight;
1334598fe0ddSCristian Dumitrescu 		int is_blank_or_comment;
1335598fe0ddSCristian Dumitrescu 
1336598fe0ddSCristian Dumitrescu 		if (fgets(line, MAX_LINE_SIZE, file) == NULL)
1337598fe0ddSCristian Dumitrescu 			break;
1338598fe0ddSCristian Dumitrescu 
1339598fe0ddSCristian Dumitrescu 		status = pipeline_selector_group_member_read(line,
1340598fe0ddSCristian Dumitrescu 							      &group_id,
1341598fe0ddSCristian Dumitrescu 							      &member_id,
1342598fe0ddSCristian Dumitrescu 							      &weight,
1343598fe0ddSCristian Dumitrescu 							      &is_blank_or_comment);
1344598fe0ddSCristian Dumitrescu 		if (status) {
1345598fe0ddSCristian Dumitrescu 			if (is_blank_or_comment)
1346598fe0ddSCristian Dumitrescu 				continue;
1347598fe0ddSCristian Dumitrescu 
1348598fe0ddSCristian Dumitrescu 			goto error;
1349598fe0ddSCristian Dumitrescu 		}
1350598fe0ddSCristian Dumitrescu 
1351598fe0ddSCristian Dumitrescu 		status = rte_swx_ctl_pipeline_selector_group_member_add(p,
1352598fe0ddSCristian Dumitrescu 			selector_name,
1353598fe0ddSCristian Dumitrescu 			group_id,
1354598fe0ddSCristian Dumitrescu 			member_id,
1355598fe0ddSCristian Dumitrescu 			weight);
1356598fe0ddSCristian Dumitrescu 		if (status)
1357598fe0ddSCristian Dumitrescu 			goto error;
1358598fe0ddSCristian Dumitrescu 	}
1359598fe0ddSCristian Dumitrescu 
1360598fe0ddSCristian Dumitrescu error:
1361598fe0ddSCristian Dumitrescu 	free(line);
1362598fe0ddSCristian Dumitrescu 	*file_line_number = line_id;
1363598fe0ddSCristian Dumitrescu 	return status;
1364598fe0ddSCristian Dumitrescu }
1365598fe0ddSCristian Dumitrescu 
1366598fe0ddSCristian Dumitrescu static const char cmd_pipeline_selector_group_member_add_help[] =
1367598fe0ddSCristian Dumitrescu "pipeline <pipeline_name> selector <selector_name> group member add <file_name>";
1368598fe0ddSCristian Dumitrescu 
1369598fe0ddSCristian Dumitrescu static void
1370598fe0ddSCristian Dumitrescu cmd_pipeline_selector_group_member_add(char **tokens,
1371598fe0ddSCristian Dumitrescu 	uint32_t n_tokens,
1372598fe0ddSCristian Dumitrescu 	char *out,
1373598fe0ddSCristian Dumitrescu 	size_t out_size,
1374b9559f94SCristian Dumitrescu 	void *obj __rte_unused)
1375598fe0ddSCristian Dumitrescu {
1376b9559f94SCristian Dumitrescu 	struct rte_swx_ctl_pipeline *ctl;
1377598fe0ddSCristian Dumitrescu 	char *pipeline_name, *selector_name, *file_name;
1378598fe0ddSCristian Dumitrescu 	FILE *file = NULL;
1379598fe0ddSCristian Dumitrescu 	uint32_t file_line_number = 0;
1380598fe0ddSCristian Dumitrescu 	int status;
1381598fe0ddSCristian Dumitrescu 
1382598fe0ddSCristian Dumitrescu 	if (n_tokens != 8) {
1383598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1384598fe0ddSCristian Dumitrescu 		return;
1385598fe0ddSCristian Dumitrescu 	}
1386598fe0ddSCristian Dumitrescu 
1387598fe0ddSCristian Dumitrescu 	pipeline_name = tokens[1];
1388b9559f94SCristian Dumitrescu 	ctl = rte_swx_ctl_pipeline_find(pipeline_name);
1389b9559f94SCristian Dumitrescu 	if (!ctl) {
1390598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
1391598fe0ddSCristian Dumitrescu 		return;
1392598fe0ddSCristian Dumitrescu 	}
1393598fe0ddSCristian Dumitrescu 
1394598fe0ddSCristian Dumitrescu 	if (strcmp(tokens[2], "selector") != 0) {
1395598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "selector");
1396598fe0ddSCristian Dumitrescu 		return;
1397598fe0ddSCristian Dumitrescu 	}
1398598fe0ddSCristian Dumitrescu 
1399598fe0ddSCristian Dumitrescu 	selector_name = tokens[3];
1400598fe0ddSCristian Dumitrescu 
1401598fe0ddSCristian Dumitrescu 	if (strcmp(tokens[4], "group") ||
1402598fe0ddSCristian Dumitrescu 		strcmp(tokens[5], "member") ||
1403598fe0ddSCristian Dumitrescu 		strcmp(tokens[6], "add")) {
1404598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "group member add");
1405598fe0ddSCristian Dumitrescu 		return;
1406598fe0ddSCristian Dumitrescu 	}
1407598fe0ddSCristian Dumitrescu 
1408598fe0ddSCristian Dumitrescu 	file_name = tokens[7];
1409598fe0ddSCristian Dumitrescu 	file = fopen(file_name, "r");
1410598fe0ddSCristian Dumitrescu 	if (!file) {
1411598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, "Cannot open file %s.\n", file_name);
1412598fe0ddSCristian Dumitrescu 		return;
1413598fe0ddSCristian Dumitrescu 	}
1414598fe0ddSCristian Dumitrescu 
1415b9559f94SCristian Dumitrescu 	status = pipeline_selector_group_members_add(ctl,
1416598fe0ddSCristian Dumitrescu 					    selector_name,
1417598fe0ddSCristian Dumitrescu 					    file,
1418598fe0ddSCristian Dumitrescu 					    &file_line_number);
1419598fe0ddSCristian Dumitrescu 	if (status)
1420598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, "Invalid entry in file %s at line %u\n",
1421598fe0ddSCristian Dumitrescu 			 file_name,
1422598fe0ddSCristian Dumitrescu 			 file_line_number);
1423598fe0ddSCristian Dumitrescu 
1424598fe0ddSCristian Dumitrescu 	fclose(file);
1425598fe0ddSCristian Dumitrescu }
1426598fe0ddSCristian Dumitrescu 
1427598fe0ddSCristian Dumitrescu static int
1428598fe0ddSCristian Dumitrescu pipeline_selector_group_members_delete(struct rte_swx_ctl_pipeline *p,
1429598fe0ddSCristian Dumitrescu 			   const char *selector_name,
1430598fe0ddSCristian Dumitrescu 			   FILE *file,
1431598fe0ddSCristian Dumitrescu 			   uint32_t *file_line_number)
1432598fe0ddSCristian Dumitrescu {
1433598fe0ddSCristian Dumitrescu 	char *line = NULL;
1434598fe0ddSCristian Dumitrescu 	uint32_t line_id = 0;
1435598fe0ddSCristian Dumitrescu 	int status = 0;
1436598fe0ddSCristian Dumitrescu 
1437598fe0ddSCristian Dumitrescu 	/* Buffer allocation. */
1438598fe0ddSCristian Dumitrescu 	line = malloc(MAX_LINE_SIZE);
1439598fe0ddSCristian Dumitrescu 	if (!line)
1440598fe0ddSCristian Dumitrescu 		return -ENOMEM;
1441598fe0ddSCristian Dumitrescu 
1442598fe0ddSCristian Dumitrescu 	/* File read. */
1443598fe0ddSCristian Dumitrescu 	for (line_id = 1; ; line_id++) {
1444598fe0ddSCristian Dumitrescu 		uint32_t group_id, member_id, weight;
1445598fe0ddSCristian Dumitrescu 		int is_blank_or_comment;
1446598fe0ddSCristian Dumitrescu 
1447598fe0ddSCristian Dumitrescu 		if (fgets(line, MAX_LINE_SIZE, file) == NULL)
1448598fe0ddSCristian Dumitrescu 			break;
1449598fe0ddSCristian Dumitrescu 
1450598fe0ddSCristian Dumitrescu 		status = pipeline_selector_group_member_read(line,
1451598fe0ddSCristian Dumitrescu 							      &group_id,
1452598fe0ddSCristian Dumitrescu 							      &member_id,
1453598fe0ddSCristian Dumitrescu 							      &weight,
1454598fe0ddSCristian Dumitrescu 							      &is_blank_or_comment);
1455598fe0ddSCristian Dumitrescu 		if (status) {
1456598fe0ddSCristian Dumitrescu 			if (is_blank_or_comment)
1457598fe0ddSCristian Dumitrescu 				continue;
1458598fe0ddSCristian Dumitrescu 
1459598fe0ddSCristian Dumitrescu 			goto error;
1460598fe0ddSCristian Dumitrescu 		}
1461598fe0ddSCristian Dumitrescu 
1462598fe0ddSCristian Dumitrescu 		status = rte_swx_ctl_pipeline_selector_group_member_delete(p,
1463598fe0ddSCristian Dumitrescu 			selector_name,
1464598fe0ddSCristian Dumitrescu 			group_id,
1465598fe0ddSCristian Dumitrescu 			member_id);
1466598fe0ddSCristian Dumitrescu 		if (status)
1467598fe0ddSCristian Dumitrescu 			goto error;
1468598fe0ddSCristian Dumitrescu 	}
1469598fe0ddSCristian Dumitrescu 
1470598fe0ddSCristian Dumitrescu error:
1471598fe0ddSCristian Dumitrescu 	free(line);
1472598fe0ddSCristian Dumitrescu 	*file_line_number = line_id;
1473598fe0ddSCristian Dumitrescu 	return status;
1474598fe0ddSCristian Dumitrescu }
1475598fe0ddSCristian Dumitrescu 
1476598fe0ddSCristian Dumitrescu static const char cmd_pipeline_selector_group_member_delete_help[] =
1477598fe0ddSCristian Dumitrescu "pipeline <pipeline_name> selector <selector_name> group member delete <file_name>";
1478598fe0ddSCristian Dumitrescu 
1479598fe0ddSCristian Dumitrescu static void
1480598fe0ddSCristian Dumitrescu cmd_pipeline_selector_group_member_delete(char **tokens,
1481598fe0ddSCristian Dumitrescu 	uint32_t n_tokens,
1482598fe0ddSCristian Dumitrescu 	char *out,
1483598fe0ddSCristian Dumitrescu 	size_t out_size,
1484b9559f94SCristian Dumitrescu 	void *obj __rte_unused)
1485598fe0ddSCristian Dumitrescu {
1486b9559f94SCristian Dumitrescu 	struct rte_swx_ctl_pipeline *ctl;
1487598fe0ddSCristian Dumitrescu 	char *pipeline_name, *selector_name, *file_name;
1488598fe0ddSCristian Dumitrescu 	FILE *file = NULL;
1489598fe0ddSCristian Dumitrescu 	uint32_t file_line_number = 0;
1490598fe0ddSCristian Dumitrescu 	int status;
1491598fe0ddSCristian Dumitrescu 
1492598fe0ddSCristian Dumitrescu 	if (n_tokens != 8) {
1493598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1494598fe0ddSCristian Dumitrescu 		return;
1495598fe0ddSCristian Dumitrescu 	}
1496598fe0ddSCristian Dumitrescu 
1497598fe0ddSCristian Dumitrescu 	pipeline_name = tokens[1];
1498b9559f94SCristian Dumitrescu 	ctl = rte_swx_ctl_pipeline_find(pipeline_name);
1499b9559f94SCristian Dumitrescu 	if (!ctl) {
1500598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
1501598fe0ddSCristian Dumitrescu 		return;
1502598fe0ddSCristian Dumitrescu 	}
1503598fe0ddSCristian Dumitrescu 
1504598fe0ddSCristian Dumitrescu 	if (strcmp(tokens[2], "selector") != 0) {
1505598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "selector");
1506598fe0ddSCristian Dumitrescu 		return;
1507598fe0ddSCristian Dumitrescu 	}
1508598fe0ddSCristian Dumitrescu 
1509598fe0ddSCristian Dumitrescu 	selector_name = tokens[3];
1510598fe0ddSCristian Dumitrescu 
1511598fe0ddSCristian Dumitrescu 	if (strcmp(tokens[4], "group") ||
1512598fe0ddSCristian Dumitrescu 		strcmp(tokens[5], "member") ||
1513598fe0ddSCristian Dumitrescu 		strcmp(tokens[6], "delete")) {
1514598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "group member delete");
1515598fe0ddSCristian Dumitrescu 		return;
1516598fe0ddSCristian Dumitrescu 	}
1517598fe0ddSCristian Dumitrescu 
1518598fe0ddSCristian Dumitrescu 	file_name = tokens[7];
1519598fe0ddSCristian Dumitrescu 	file = fopen(file_name, "r");
1520598fe0ddSCristian Dumitrescu 	if (!file) {
1521598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, "Cannot open file %s.\n", file_name);
1522598fe0ddSCristian Dumitrescu 		return;
1523598fe0ddSCristian Dumitrescu 	}
1524598fe0ddSCristian Dumitrescu 
1525b9559f94SCristian Dumitrescu 	status = pipeline_selector_group_members_delete(ctl,
1526598fe0ddSCristian Dumitrescu 					    selector_name,
1527598fe0ddSCristian Dumitrescu 					    file,
1528598fe0ddSCristian Dumitrescu 					    &file_line_number);
1529598fe0ddSCristian Dumitrescu 	if (status)
1530598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, "Invalid entry in file %s at line %u\n",
1531598fe0ddSCristian Dumitrescu 			 file_name,
1532598fe0ddSCristian Dumitrescu 			 file_line_number);
1533598fe0ddSCristian Dumitrescu 
1534598fe0ddSCristian Dumitrescu 	fclose(file);
1535598fe0ddSCristian Dumitrescu }
1536598fe0ddSCristian Dumitrescu 
1537598fe0ddSCristian Dumitrescu static const char cmd_pipeline_selector_show_help[] =
1538a4c1146cSCristian Dumitrescu "pipeline <pipeline_name> selector <selector_name> show [filename]\n";
1539598fe0ddSCristian Dumitrescu 
1540598fe0ddSCristian Dumitrescu static void
1541598fe0ddSCristian Dumitrescu cmd_pipeline_selector_show(char **tokens,
1542598fe0ddSCristian Dumitrescu 	uint32_t n_tokens,
1543598fe0ddSCristian Dumitrescu 	char *out,
1544598fe0ddSCristian Dumitrescu 	size_t out_size,
1545b9559f94SCristian Dumitrescu 	void *obj __rte_unused)
1546598fe0ddSCristian Dumitrescu {
1547b9559f94SCristian Dumitrescu 	struct rte_swx_ctl_pipeline *ctl;
1548598fe0ddSCristian Dumitrescu 	char *pipeline_name, *selector_name;
1549a4c1146cSCristian Dumitrescu 	FILE *file = NULL;
1550598fe0ddSCristian Dumitrescu 	int status;
1551598fe0ddSCristian Dumitrescu 
1552a4c1146cSCristian Dumitrescu 	if (n_tokens != 5 && n_tokens != 6) {
1553598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1554598fe0ddSCristian Dumitrescu 		return;
1555598fe0ddSCristian Dumitrescu 	}
1556598fe0ddSCristian Dumitrescu 
1557598fe0ddSCristian Dumitrescu 	pipeline_name = tokens[1];
1558b9559f94SCristian Dumitrescu 	ctl = rte_swx_ctl_pipeline_find(pipeline_name);
1559b9559f94SCristian Dumitrescu 	if (!ctl) {
1560598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
1561598fe0ddSCristian Dumitrescu 		return;
1562598fe0ddSCristian Dumitrescu 	}
1563598fe0ddSCristian Dumitrescu 
1564598fe0ddSCristian Dumitrescu 	selector_name = tokens[3];
1565a4c1146cSCristian Dumitrescu 
1566a4c1146cSCristian Dumitrescu 	file = (n_tokens == 6) ? fopen(tokens[5], "w") : stdout;
1567a4c1146cSCristian Dumitrescu 	if (!file) {
1568a4c1146cSCristian Dumitrescu 		snprintf(out, out_size, "Cannot open file %s.\n", tokens[5]);
1569a4c1146cSCristian Dumitrescu 		return;
1570a4c1146cSCristian Dumitrescu 	}
1571a4c1146cSCristian Dumitrescu 
1572b9559f94SCristian Dumitrescu 	status = rte_swx_ctl_pipeline_selector_fprintf(file, ctl, selector_name);
1573598fe0ddSCristian Dumitrescu 	if (status)
1574598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "selector_name");
1575a4c1146cSCristian Dumitrescu 
1576a4c1146cSCristian Dumitrescu 	if (file)
1577a4c1146cSCristian Dumitrescu 		fclose(file);
1578598fe0ddSCristian Dumitrescu }
1579598fe0ddSCristian Dumitrescu 
15808bd4862fSCristian Dumitrescu static int
15818bd4862fSCristian Dumitrescu pipeline_learner_default_entry_add(struct rte_swx_ctl_pipeline *p,
15828bd4862fSCristian Dumitrescu 				   const char *learner_name,
15838bd4862fSCristian Dumitrescu 				   FILE *file,
15848bd4862fSCristian Dumitrescu 				   uint32_t *file_line_number)
15858bd4862fSCristian Dumitrescu {
15868bd4862fSCristian Dumitrescu 	char *line = NULL;
15878bd4862fSCristian Dumitrescu 	uint32_t line_id = 0;
15888bd4862fSCristian Dumitrescu 	int status = 0;
15898bd4862fSCristian Dumitrescu 
15908bd4862fSCristian Dumitrescu 	/* Buffer allocation. */
15918bd4862fSCristian Dumitrescu 	line = malloc(MAX_LINE_SIZE);
15928bd4862fSCristian Dumitrescu 	if (!line)
15938bd4862fSCristian Dumitrescu 		return -ENOMEM;
15948bd4862fSCristian Dumitrescu 
15958bd4862fSCristian Dumitrescu 	/* File read. */
15968bd4862fSCristian Dumitrescu 	for (line_id = 1; ; line_id++) {
15978bd4862fSCristian Dumitrescu 		struct rte_swx_table_entry *entry;
15988bd4862fSCristian Dumitrescu 		int is_blank_or_comment;
15998bd4862fSCristian Dumitrescu 
16008bd4862fSCristian Dumitrescu 		if (fgets(line, MAX_LINE_SIZE, file) == NULL)
16018bd4862fSCristian Dumitrescu 			break;
16028bd4862fSCristian Dumitrescu 
16038bd4862fSCristian Dumitrescu 		entry = rte_swx_ctl_pipeline_learner_default_entry_read(p,
16048bd4862fSCristian Dumitrescu 									learner_name,
16058bd4862fSCristian Dumitrescu 									line,
16068bd4862fSCristian Dumitrescu 									&is_blank_or_comment);
16078bd4862fSCristian Dumitrescu 		if (!entry) {
16088bd4862fSCristian Dumitrescu 			if (is_blank_or_comment)
16098bd4862fSCristian Dumitrescu 				continue;
16108bd4862fSCristian Dumitrescu 
16118bd4862fSCristian Dumitrescu 			status = -EINVAL;
16128bd4862fSCristian Dumitrescu 			goto error;
16138bd4862fSCristian Dumitrescu 		}
16148bd4862fSCristian Dumitrescu 
16158bd4862fSCristian Dumitrescu 		status = rte_swx_ctl_pipeline_learner_default_entry_add(p,
16168bd4862fSCristian Dumitrescu 									learner_name,
16178bd4862fSCristian Dumitrescu 									entry);
16188bd4862fSCristian Dumitrescu 		table_entry_free(entry);
16198bd4862fSCristian Dumitrescu 		if (status)
16208bd4862fSCristian Dumitrescu 			goto error;
16218bd4862fSCristian Dumitrescu 	}
16228bd4862fSCristian Dumitrescu 
16238bd4862fSCristian Dumitrescu error:
16248bd4862fSCristian Dumitrescu 	*file_line_number = line_id;
16258bd4862fSCristian Dumitrescu 	free(line);
16268bd4862fSCristian Dumitrescu 	return status;
16278bd4862fSCristian Dumitrescu }
16288bd4862fSCristian Dumitrescu 
16298bd4862fSCristian Dumitrescu static const char cmd_pipeline_learner_default_help[] =
16308bd4862fSCristian Dumitrescu "pipeline <pipeline_name> learner <learner_name> default <file_name>\n";
16318bd4862fSCristian Dumitrescu 
16328bd4862fSCristian Dumitrescu static void
16338bd4862fSCristian Dumitrescu cmd_pipeline_learner_default(char **tokens,
16348bd4862fSCristian Dumitrescu 			     uint32_t n_tokens,
16358bd4862fSCristian Dumitrescu 			     char *out,
16368bd4862fSCristian Dumitrescu 			     size_t out_size,
1637b9559f94SCristian Dumitrescu 			     void *obj __rte_unused)
16388bd4862fSCristian Dumitrescu {
1639b9559f94SCristian Dumitrescu 	struct rte_swx_ctl_pipeline *ctl;
16408bd4862fSCristian Dumitrescu 	char *pipeline_name, *learner_name, *file_name;
16418bd4862fSCristian Dumitrescu 	FILE *file = NULL;
16428bd4862fSCristian Dumitrescu 	uint32_t file_line_number = 0;
16438bd4862fSCristian Dumitrescu 	int status;
16448bd4862fSCristian Dumitrescu 
16458bd4862fSCristian Dumitrescu 	if (n_tokens != 6) {
16468bd4862fSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
16478bd4862fSCristian Dumitrescu 		return;
16488bd4862fSCristian Dumitrescu 	}
16498bd4862fSCristian Dumitrescu 
16508bd4862fSCristian Dumitrescu 	pipeline_name = tokens[1];
1651b9559f94SCristian Dumitrescu 	ctl = rte_swx_ctl_pipeline_find(pipeline_name);
1652b9559f94SCristian Dumitrescu 	if (!ctl) {
16538bd4862fSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
16548bd4862fSCristian Dumitrescu 		return;
16558bd4862fSCristian Dumitrescu 	}
16568bd4862fSCristian Dumitrescu 
16578bd4862fSCristian Dumitrescu 	learner_name = tokens[3];
16588bd4862fSCristian Dumitrescu 
16598bd4862fSCristian Dumitrescu 	file_name = tokens[5];
16608bd4862fSCristian Dumitrescu 	file = fopen(file_name, "r");
16618bd4862fSCristian Dumitrescu 	if (!file) {
16628bd4862fSCristian Dumitrescu 		snprintf(out, out_size, "Cannot open file %s.\n", file_name);
16638bd4862fSCristian Dumitrescu 		return;
16648bd4862fSCristian Dumitrescu 	}
16658bd4862fSCristian Dumitrescu 
1666b9559f94SCristian Dumitrescu 	status = pipeline_learner_default_entry_add(ctl,
16678bd4862fSCristian Dumitrescu 						    learner_name,
16688bd4862fSCristian Dumitrescu 						    file,
16698bd4862fSCristian Dumitrescu 						    &file_line_number);
16708bd4862fSCristian Dumitrescu 	if (status)
16718bd4862fSCristian Dumitrescu 		snprintf(out, out_size, "Invalid entry in file %s at line %u\n",
16728bd4862fSCristian Dumitrescu 			 file_name,
16738bd4862fSCristian Dumitrescu 			 file_line_number);
16748bd4862fSCristian Dumitrescu 
16758bd4862fSCristian Dumitrescu 	fclose(file);
16768bd4862fSCristian Dumitrescu }
16778bd4862fSCristian Dumitrescu 
167875129cebSChurchill Khangar static const char cmd_pipeline_commit_help[] =
167975129cebSChurchill Khangar "pipeline <pipeline_name> commit\n";
168075129cebSChurchill Khangar 
168175129cebSChurchill Khangar static void
168275129cebSChurchill Khangar cmd_pipeline_commit(char **tokens,
168375129cebSChurchill Khangar 	uint32_t n_tokens,
168475129cebSChurchill Khangar 	char *out,
168575129cebSChurchill Khangar 	size_t out_size,
1686b9559f94SCristian Dumitrescu 	void *obj __rte_unused)
168775129cebSChurchill Khangar {
1688b9559f94SCristian Dumitrescu 	struct rte_swx_ctl_pipeline *ctl;
168975129cebSChurchill Khangar 	char *pipeline_name;
169075129cebSChurchill Khangar 	int status;
169175129cebSChurchill Khangar 
169275129cebSChurchill Khangar 	if (n_tokens != 3) {
169375129cebSChurchill Khangar 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
169475129cebSChurchill Khangar 		return;
169575129cebSChurchill Khangar 	}
169675129cebSChurchill Khangar 
169775129cebSChurchill Khangar 	pipeline_name = tokens[1];
1698b9559f94SCristian Dumitrescu 	ctl = rte_swx_ctl_pipeline_find(pipeline_name);
1699b9559f94SCristian Dumitrescu 	if (!ctl) {
170075129cebSChurchill Khangar 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
170175129cebSChurchill Khangar 		return;
17025074e1d5SCristian Dumitrescu 	}
17035074e1d5SCristian Dumitrescu 
1704b9559f94SCristian Dumitrescu 	status = rte_swx_ctl_pipeline_commit(ctl, 1);
170575129cebSChurchill Khangar 	if (status)
170675129cebSChurchill Khangar 		snprintf(out, out_size, "Commit failed. "
170775129cebSChurchill Khangar 			"Use \"commit\" to retry or \"abort\" to discard the pending work.\n");
17085074e1d5SCristian Dumitrescu }
17095074e1d5SCristian Dumitrescu 
171075129cebSChurchill Khangar static const char cmd_pipeline_abort_help[] =
171175129cebSChurchill Khangar "pipeline <pipeline_name> abort\n";
17125074e1d5SCristian Dumitrescu 
171375129cebSChurchill Khangar static void
171475129cebSChurchill Khangar cmd_pipeline_abort(char **tokens,
171575129cebSChurchill Khangar 	uint32_t n_tokens,
171675129cebSChurchill Khangar 	char *out,
171775129cebSChurchill Khangar 	size_t out_size,
1718b9559f94SCristian Dumitrescu 	void *obj __rte_unused)
171975129cebSChurchill Khangar {
1720b9559f94SCristian Dumitrescu 	struct rte_swx_ctl_pipeline *ctl;
172175129cebSChurchill Khangar 	char *pipeline_name;
17225074e1d5SCristian Dumitrescu 
172375129cebSChurchill Khangar 	if (n_tokens != 3) {
172475129cebSChurchill Khangar 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
17255074e1d5SCristian Dumitrescu 		return;
172675129cebSChurchill Khangar 	}
17275074e1d5SCristian Dumitrescu 
172875129cebSChurchill Khangar 	pipeline_name = tokens[1];
1729b9559f94SCristian Dumitrescu 	ctl = rte_swx_ctl_pipeline_find(pipeline_name);
1730b9559f94SCristian Dumitrescu 	if (!ctl) {
173175129cebSChurchill Khangar 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
173275129cebSChurchill Khangar 		return;
173375129cebSChurchill Khangar 	}
173475129cebSChurchill Khangar 
1735b9559f94SCristian Dumitrescu 	rte_swx_ctl_pipeline_abort(ctl);
17365074e1d5SCristian Dumitrescu }
17375074e1d5SCristian Dumitrescu 
173864cfcebdSCristian Dumitrescu static const char cmd_pipeline_regrd_help[] =
173964cfcebdSCristian Dumitrescu "pipeline <pipeline_name> regrd <register_array_name> <index>\n";
174064cfcebdSCristian Dumitrescu 
174164cfcebdSCristian Dumitrescu static void
174264cfcebdSCristian Dumitrescu cmd_pipeline_regrd(char **tokens,
174364cfcebdSCristian Dumitrescu 	uint32_t n_tokens,
174464cfcebdSCristian Dumitrescu 	char *out,
174564cfcebdSCristian Dumitrescu 	size_t out_size,
1746b9559f94SCristian Dumitrescu 	void *obj __rte_unused)
174764cfcebdSCristian Dumitrescu {
1748b9559f94SCristian Dumitrescu 	struct rte_swx_pipeline *p;
174964cfcebdSCristian Dumitrescu 	const char *name;
175064cfcebdSCristian Dumitrescu 	uint64_t value;
175164cfcebdSCristian Dumitrescu 	uint32_t idx;
175264cfcebdSCristian Dumitrescu 	int status;
175364cfcebdSCristian Dumitrescu 
175464cfcebdSCristian Dumitrescu 	if (n_tokens != 5) {
175564cfcebdSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
175664cfcebdSCristian Dumitrescu 		return;
175764cfcebdSCristian Dumitrescu 	}
175864cfcebdSCristian Dumitrescu 
1759b9559f94SCristian Dumitrescu 	p = rte_swx_pipeline_find(tokens[1]);
1760b9559f94SCristian Dumitrescu 	if (!p) {
176164cfcebdSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
176264cfcebdSCristian Dumitrescu 		return;
176364cfcebdSCristian Dumitrescu 	}
176464cfcebdSCristian Dumitrescu 
176564cfcebdSCristian Dumitrescu 	if (strcmp(tokens[2], "regrd")) {
176664cfcebdSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "regrd");
176764cfcebdSCristian Dumitrescu 		return;
176864cfcebdSCristian Dumitrescu 	}
176964cfcebdSCristian Dumitrescu 
177064cfcebdSCristian Dumitrescu 	name = tokens[3];
177164cfcebdSCristian Dumitrescu 
177264cfcebdSCristian Dumitrescu 	if (parser_read_uint32(&idx, tokens[4])) {
177364cfcebdSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "index");
177464cfcebdSCristian Dumitrescu 		return;
177564cfcebdSCristian Dumitrescu 	}
177664cfcebdSCristian Dumitrescu 
1777b9559f94SCristian Dumitrescu 	status = rte_swx_ctl_pipeline_regarray_read(p, name, idx, &value);
177864cfcebdSCristian Dumitrescu 	if (status) {
177964cfcebdSCristian Dumitrescu 		snprintf(out, out_size, "Command failed.\n");
178064cfcebdSCristian Dumitrescu 		return;
178164cfcebdSCristian Dumitrescu 	}
178264cfcebdSCristian Dumitrescu 
178364cfcebdSCristian Dumitrescu 	snprintf(out, out_size, "0x%" PRIx64 "\n", value);
178464cfcebdSCristian Dumitrescu }
178564cfcebdSCristian Dumitrescu 
178664cfcebdSCristian Dumitrescu static const char cmd_pipeline_regwr_help[] =
178764cfcebdSCristian Dumitrescu "pipeline <pipeline_name> regwr <register_array_name> <index> <value>\n";
178864cfcebdSCristian Dumitrescu 
178964cfcebdSCristian Dumitrescu static void
179064cfcebdSCristian Dumitrescu cmd_pipeline_regwr(char **tokens,
179164cfcebdSCristian Dumitrescu 	uint32_t n_tokens,
179264cfcebdSCristian Dumitrescu 	char *out,
179364cfcebdSCristian Dumitrescu 	size_t out_size,
1794b9559f94SCristian Dumitrescu 	void *obj __rte_unused)
179564cfcebdSCristian Dumitrescu {
1796b9559f94SCristian Dumitrescu 	struct rte_swx_pipeline *p;
179764cfcebdSCristian Dumitrescu 	const char *name;
179864cfcebdSCristian Dumitrescu 	uint64_t value;
179964cfcebdSCristian Dumitrescu 	uint32_t idx;
180064cfcebdSCristian Dumitrescu 	int status;
180164cfcebdSCristian Dumitrescu 
180264cfcebdSCristian Dumitrescu 	if (n_tokens != 6) {
180364cfcebdSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
180464cfcebdSCristian Dumitrescu 		return;
180564cfcebdSCristian Dumitrescu 	}
180664cfcebdSCristian Dumitrescu 
1807b9559f94SCristian Dumitrescu 	p = rte_swx_pipeline_find(tokens[1]);
1808b9559f94SCristian Dumitrescu 	if (!p) {
180964cfcebdSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
181064cfcebdSCristian Dumitrescu 		return;
181164cfcebdSCristian Dumitrescu 	}
181264cfcebdSCristian Dumitrescu 
181364cfcebdSCristian Dumitrescu 	if (strcmp(tokens[2], "regwr")) {
181464cfcebdSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "regwr");
181564cfcebdSCristian Dumitrescu 		return;
181664cfcebdSCristian Dumitrescu 	}
181764cfcebdSCristian Dumitrescu 
181864cfcebdSCristian Dumitrescu 	name = tokens[3];
181964cfcebdSCristian Dumitrescu 
182064cfcebdSCristian Dumitrescu 	if (parser_read_uint32(&idx, tokens[4])) {
182164cfcebdSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "index");
182264cfcebdSCristian Dumitrescu 		return;
182364cfcebdSCristian Dumitrescu 	}
182464cfcebdSCristian Dumitrescu 
182564cfcebdSCristian Dumitrescu 	if (parser_read_uint64(&value, tokens[5])) {
182664cfcebdSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "value");
182764cfcebdSCristian Dumitrescu 		return;
182864cfcebdSCristian Dumitrescu 	}
182964cfcebdSCristian Dumitrescu 
1830b9559f94SCristian Dumitrescu 	status = rte_swx_ctl_pipeline_regarray_write(p, name, idx, value);
183164cfcebdSCristian Dumitrescu 	if (status) {
183264cfcebdSCristian Dumitrescu 		snprintf(out, out_size, "Command failed.\n");
183364cfcebdSCristian Dumitrescu 		return;
183464cfcebdSCristian Dumitrescu 	}
183564cfcebdSCristian Dumitrescu }
183664cfcebdSCristian Dumitrescu 
1837f38913b7SCristian Dumitrescu static const char cmd_pipeline_meter_profile_add_help[] =
1838f38913b7SCristian Dumitrescu "pipeline <pipeline_name> meter profile <profile_name> add "
1839f38913b7SCristian Dumitrescu 	"cir <cir> pir <pir> cbs <cbs> pbs <pbs>\n";
1840f38913b7SCristian Dumitrescu 
1841f38913b7SCristian Dumitrescu static void
1842f38913b7SCristian Dumitrescu cmd_pipeline_meter_profile_add(char **tokens,
1843f38913b7SCristian Dumitrescu 	uint32_t n_tokens,
1844f38913b7SCristian Dumitrescu 	char *out,
1845f38913b7SCristian Dumitrescu 	size_t out_size,
1846b9559f94SCristian Dumitrescu 	void *obj __rte_unused)
1847f38913b7SCristian Dumitrescu {
1848f38913b7SCristian Dumitrescu 	struct rte_meter_trtcm_params params;
1849b9559f94SCristian Dumitrescu 	struct rte_swx_pipeline *p;
1850f38913b7SCristian Dumitrescu 	const char *profile_name;
1851f38913b7SCristian Dumitrescu 	int status;
1852f38913b7SCristian Dumitrescu 
1853f38913b7SCristian Dumitrescu 	if (n_tokens != 14) {
1854f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1855f38913b7SCristian Dumitrescu 		return;
1856f38913b7SCristian Dumitrescu 	}
1857f38913b7SCristian Dumitrescu 
1858b9559f94SCristian Dumitrescu 	p = rte_swx_pipeline_find(tokens[1]);
1859b9559f94SCristian Dumitrescu 	if (!p) {
1860f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
1861f38913b7SCristian Dumitrescu 		return;
1862f38913b7SCristian Dumitrescu 	}
1863f38913b7SCristian Dumitrescu 
1864f38913b7SCristian Dumitrescu 	if (strcmp(tokens[2], "meter")) {
1865f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "meter");
1866f38913b7SCristian Dumitrescu 		return;
1867f38913b7SCristian Dumitrescu 	}
1868f38913b7SCristian Dumitrescu 
1869f38913b7SCristian Dumitrescu 	if (strcmp(tokens[3], "profile")) {
1870f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "profile");
1871f38913b7SCristian Dumitrescu 		return;
1872f38913b7SCristian Dumitrescu 	}
1873f38913b7SCristian Dumitrescu 
1874f38913b7SCristian Dumitrescu 	profile_name = tokens[4];
1875f38913b7SCristian Dumitrescu 
1876f38913b7SCristian Dumitrescu 	if (strcmp(tokens[5], "add")) {
1877f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "add");
1878f38913b7SCristian Dumitrescu 		return;
1879f38913b7SCristian Dumitrescu 	}
1880f38913b7SCristian Dumitrescu 
1881f38913b7SCristian Dumitrescu 	if (strcmp(tokens[6], "cir")) {
1882f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cir");
1883f38913b7SCristian Dumitrescu 		return;
1884f38913b7SCristian Dumitrescu 	}
1885f38913b7SCristian Dumitrescu 
1886f38913b7SCristian Dumitrescu 	if (parser_read_uint64(&params.cir, tokens[7])) {
1887f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "cir");
1888f38913b7SCristian Dumitrescu 		return;
1889f38913b7SCristian Dumitrescu 	}
1890f38913b7SCristian Dumitrescu 
1891f38913b7SCristian Dumitrescu 	if (strcmp(tokens[8], "pir")) {
1892f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pir");
1893f38913b7SCristian Dumitrescu 		return;
1894f38913b7SCristian Dumitrescu 	}
1895f38913b7SCristian Dumitrescu 
1896f38913b7SCristian Dumitrescu 	if (parser_read_uint64(&params.pir, tokens[9])) {
1897f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pir");
1898f38913b7SCristian Dumitrescu 		return;
1899f38913b7SCristian Dumitrescu 	}
1900f38913b7SCristian Dumitrescu 
1901f38913b7SCristian Dumitrescu 	if (strcmp(tokens[10], "cbs")) {
1902f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cbs");
1903f38913b7SCristian Dumitrescu 		return;
1904f38913b7SCristian Dumitrescu 	}
1905f38913b7SCristian Dumitrescu 
1906f38913b7SCristian Dumitrescu 	if (parser_read_uint64(&params.cbs, tokens[11])) {
1907f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "cbs");
1908f38913b7SCristian Dumitrescu 		return;
1909f38913b7SCristian Dumitrescu 	}
1910f38913b7SCristian Dumitrescu 
1911f38913b7SCristian Dumitrescu 	if (strcmp(tokens[12], "pbs")) {
1912f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pbs");
1913f38913b7SCristian Dumitrescu 		return;
1914f38913b7SCristian Dumitrescu 	}
1915f38913b7SCristian Dumitrescu 
1916f38913b7SCristian Dumitrescu 	if (parser_read_uint64(&params.pbs, tokens[13])) {
1917f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pbs");
1918f38913b7SCristian Dumitrescu 		return;
1919f38913b7SCristian Dumitrescu 	}
1920f38913b7SCristian Dumitrescu 
1921b9559f94SCristian Dumitrescu 	status = rte_swx_ctl_meter_profile_add(p, profile_name, &params);
1922f38913b7SCristian Dumitrescu 	if (status) {
1923f38913b7SCristian Dumitrescu 		snprintf(out, out_size, "Command failed.\n");
1924f38913b7SCristian Dumitrescu 		return;
1925f38913b7SCristian Dumitrescu 	}
1926f38913b7SCristian Dumitrescu }
1927f38913b7SCristian Dumitrescu 
1928f38913b7SCristian Dumitrescu static const char cmd_pipeline_meter_profile_delete_help[] =
1929f38913b7SCristian Dumitrescu "pipeline <pipeline_name> meter profile <profile_name> delete\n";
1930f38913b7SCristian Dumitrescu 
1931f38913b7SCristian Dumitrescu static void
1932f38913b7SCristian Dumitrescu cmd_pipeline_meter_profile_delete(char **tokens,
1933f38913b7SCristian Dumitrescu 	uint32_t n_tokens,
1934f38913b7SCristian Dumitrescu 	char *out,
1935f38913b7SCristian Dumitrescu 	size_t out_size,
1936b9559f94SCristian Dumitrescu 	void *obj __rte_unused)
1937f38913b7SCristian Dumitrescu {
1938b9559f94SCristian Dumitrescu 	struct rte_swx_pipeline *p;
1939f38913b7SCristian Dumitrescu 	const char *profile_name;
1940f38913b7SCristian Dumitrescu 	int status;
1941f38913b7SCristian Dumitrescu 
1942f38913b7SCristian Dumitrescu 	if (n_tokens != 6) {
1943f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1944f38913b7SCristian Dumitrescu 		return;
1945f38913b7SCristian Dumitrescu 	}
1946f38913b7SCristian Dumitrescu 
1947b9559f94SCristian Dumitrescu 	p = rte_swx_pipeline_find(tokens[1]);
1948b9559f94SCristian Dumitrescu 	if (!p) {
1949f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
1950f38913b7SCristian Dumitrescu 		return;
1951f38913b7SCristian Dumitrescu 	}
1952f38913b7SCristian Dumitrescu 
1953f38913b7SCristian Dumitrescu 	if (strcmp(tokens[2], "meter")) {
1954f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "meter");
1955f38913b7SCristian Dumitrescu 		return;
1956f38913b7SCristian Dumitrescu 	}
1957f38913b7SCristian Dumitrescu 
1958f38913b7SCristian Dumitrescu 	if (strcmp(tokens[3], "profile")) {
1959f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "profile");
1960f38913b7SCristian Dumitrescu 		return;
1961f38913b7SCristian Dumitrescu 	}
1962f38913b7SCristian Dumitrescu 
1963f38913b7SCristian Dumitrescu 	profile_name = tokens[4];
1964f38913b7SCristian Dumitrescu 
1965f38913b7SCristian Dumitrescu 	if (strcmp(tokens[5], "delete")) {
1966f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "delete");
1967f38913b7SCristian Dumitrescu 		return;
1968f38913b7SCristian Dumitrescu 	}
1969f38913b7SCristian Dumitrescu 
1970b9559f94SCristian Dumitrescu 	status = rte_swx_ctl_meter_profile_delete(p, profile_name);
1971f38913b7SCristian Dumitrescu 	if (status) {
1972f38913b7SCristian Dumitrescu 		snprintf(out, out_size, "Command failed.\n");
1973f38913b7SCristian Dumitrescu 		return;
1974f38913b7SCristian Dumitrescu 	}
1975f38913b7SCristian Dumitrescu }
1976f38913b7SCristian Dumitrescu 
1977f38913b7SCristian Dumitrescu static const char cmd_pipeline_meter_reset_help[] =
1978f38913b7SCristian Dumitrescu "pipeline <pipeline_name> meter <meter_array_name> from <index0> to <index1> "
1979f38913b7SCristian Dumitrescu 	"reset\n";
1980f38913b7SCristian Dumitrescu 
1981f38913b7SCristian Dumitrescu static void
1982f38913b7SCristian Dumitrescu cmd_pipeline_meter_reset(char **tokens,
1983f38913b7SCristian Dumitrescu 	uint32_t n_tokens,
1984f38913b7SCristian Dumitrescu 	char *out,
1985f38913b7SCristian Dumitrescu 	size_t out_size,
1986b9559f94SCristian Dumitrescu 	void *obj __rte_unused)
1987f38913b7SCristian Dumitrescu {
1988b9559f94SCristian Dumitrescu 	struct rte_swx_pipeline *p;
1989f38913b7SCristian Dumitrescu 	const char *name;
199000b67591SAli Alnubani 	uint32_t idx0 = 0, idx1 = 0;
1991f38913b7SCristian Dumitrescu 
1992f38913b7SCristian Dumitrescu 	if (n_tokens != 9) {
1993f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1994f38913b7SCristian Dumitrescu 		return;
1995f38913b7SCristian Dumitrescu 	}
1996f38913b7SCristian Dumitrescu 
1997b9559f94SCristian Dumitrescu 	p = rte_swx_pipeline_find(tokens[1]);
1998b9559f94SCristian Dumitrescu 	if (!p) {
1999f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
2000f38913b7SCristian Dumitrescu 		return;
2001f38913b7SCristian Dumitrescu 	}
2002f38913b7SCristian Dumitrescu 
2003f38913b7SCristian Dumitrescu 	if (strcmp(tokens[2], "meter")) {
2004f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "meter");
2005f38913b7SCristian Dumitrescu 		return;
2006f38913b7SCristian Dumitrescu 	}
2007f38913b7SCristian Dumitrescu 
2008f38913b7SCristian Dumitrescu 	name = tokens[3];
2009f38913b7SCristian Dumitrescu 
2010f38913b7SCristian Dumitrescu 	if (strcmp(tokens[4], "from")) {
2011f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "from");
2012f38913b7SCristian Dumitrescu 		return;
2013f38913b7SCristian Dumitrescu 	}
2014f38913b7SCristian Dumitrescu 
2015f38913b7SCristian Dumitrescu 	if (parser_read_uint32(&idx0, tokens[5])) {
2016f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "index0");
2017f38913b7SCristian Dumitrescu 		return;
2018f38913b7SCristian Dumitrescu 	}
2019f38913b7SCristian Dumitrescu 
2020f38913b7SCristian Dumitrescu 	if (strcmp(tokens[6], "to")) {
2021f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "to");
2022f38913b7SCristian Dumitrescu 		return;
2023f38913b7SCristian Dumitrescu 	}
2024f38913b7SCristian Dumitrescu 
2025f38913b7SCristian Dumitrescu 	if (parser_read_uint32(&idx1, tokens[7]) || (idx1 < idx0)) {
2026f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "index1");
2027f38913b7SCristian Dumitrescu 		return;
2028f38913b7SCristian Dumitrescu 	}
2029f38913b7SCristian Dumitrescu 
2030f38913b7SCristian Dumitrescu 	if (strcmp(tokens[8], "reset")) {
2031f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "reset");
2032f38913b7SCristian Dumitrescu 		return;
2033f38913b7SCristian Dumitrescu 	}
2034f38913b7SCristian Dumitrescu 
2035f38913b7SCristian Dumitrescu 	for ( ; idx0 <= idx1; idx0++) {
2036f38913b7SCristian Dumitrescu 		int status;
2037f38913b7SCristian Dumitrescu 
2038b9559f94SCristian Dumitrescu 		status = rte_swx_ctl_meter_reset(p, name, idx0);
2039f38913b7SCristian Dumitrescu 		if (status) {
2040f38913b7SCristian Dumitrescu 			snprintf(out, out_size, "Command failed for index %u.\n", idx0);
2041f38913b7SCristian Dumitrescu 			return;
2042f38913b7SCristian Dumitrescu 		}
2043f38913b7SCristian Dumitrescu 	}
2044f38913b7SCristian Dumitrescu }
2045f38913b7SCristian Dumitrescu 
2046f38913b7SCristian Dumitrescu static const char cmd_pipeline_meter_set_help[] =
2047f38913b7SCristian Dumitrescu "pipeline <pipeline_name> meter <meter_array_name> from <index0> to <index1> "
2048f38913b7SCristian Dumitrescu 	"set profile <profile_name>\n";
2049f38913b7SCristian Dumitrescu 
2050f38913b7SCristian Dumitrescu static void
2051f38913b7SCristian Dumitrescu cmd_pipeline_meter_set(char **tokens,
2052f38913b7SCristian Dumitrescu 	uint32_t n_tokens,
2053f38913b7SCristian Dumitrescu 	char *out,
2054f38913b7SCristian Dumitrescu 	size_t out_size,
2055b9559f94SCristian Dumitrescu 	void *obj __rte_unused)
2056f38913b7SCristian Dumitrescu {
2057b9559f94SCristian Dumitrescu 	struct rte_swx_pipeline *p;
2058f38913b7SCristian Dumitrescu 	const char *name, *profile_name;
205900b67591SAli Alnubani 	uint32_t idx0 = 0, idx1 = 0;
2060f38913b7SCristian Dumitrescu 
2061f38913b7SCristian Dumitrescu 	if (n_tokens != 11) {
2062f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2063f38913b7SCristian Dumitrescu 		return;
2064f38913b7SCristian Dumitrescu 	}
2065f38913b7SCristian Dumitrescu 
2066b9559f94SCristian Dumitrescu 	p = rte_swx_pipeline_find(tokens[1]);
2067b9559f94SCristian Dumitrescu 	if (!p) {
2068f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
2069f38913b7SCristian Dumitrescu 		return;
2070f38913b7SCristian Dumitrescu 	}
2071f38913b7SCristian Dumitrescu 
2072f38913b7SCristian Dumitrescu 	if (strcmp(tokens[2], "meter")) {
2073f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "meter");
2074f38913b7SCristian Dumitrescu 		return;
2075f38913b7SCristian Dumitrescu 	}
2076f38913b7SCristian Dumitrescu 
2077f38913b7SCristian Dumitrescu 	name = tokens[3];
2078f38913b7SCristian Dumitrescu 
2079f38913b7SCristian Dumitrescu 	if (strcmp(tokens[4], "from")) {
2080f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "from");
2081f38913b7SCristian Dumitrescu 		return;
2082f38913b7SCristian Dumitrescu 	}
2083f38913b7SCristian Dumitrescu 
2084f38913b7SCristian Dumitrescu 	if (parser_read_uint32(&idx0, tokens[5])) {
2085f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "index0");
2086f38913b7SCristian Dumitrescu 		return;
2087f38913b7SCristian Dumitrescu 	}
2088f38913b7SCristian Dumitrescu 
2089f38913b7SCristian Dumitrescu 	if (strcmp(tokens[6], "to")) {
2090f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "to");
2091f38913b7SCristian Dumitrescu 		return;
2092f38913b7SCristian Dumitrescu 	}
2093f38913b7SCristian Dumitrescu 
2094f38913b7SCristian Dumitrescu 	if (parser_read_uint32(&idx1, tokens[7]) || (idx1 < idx0)) {
2095f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "index1");
2096f38913b7SCristian Dumitrescu 		return;
2097f38913b7SCristian Dumitrescu 	}
2098f38913b7SCristian Dumitrescu 
2099f38913b7SCristian Dumitrescu 	if (strcmp(tokens[8], "set")) {
2100f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "set");
2101f38913b7SCristian Dumitrescu 		return;
2102f38913b7SCristian Dumitrescu 	}
2103f38913b7SCristian Dumitrescu 
2104f38913b7SCristian Dumitrescu 	if (strcmp(tokens[9], "profile")) {
2105f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "profile");
2106f38913b7SCristian Dumitrescu 		return;
2107f38913b7SCristian Dumitrescu 	}
2108f38913b7SCristian Dumitrescu 
2109f38913b7SCristian Dumitrescu 	profile_name = tokens[10];
2110f38913b7SCristian Dumitrescu 
2111f38913b7SCristian Dumitrescu 	for ( ; idx0 <= idx1; idx0++) {
2112f38913b7SCristian Dumitrescu 		int status;
2113f38913b7SCristian Dumitrescu 
2114b9559f94SCristian Dumitrescu 		status = rte_swx_ctl_meter_set(p, name, idx0, profile_name);
2115f38913b7SCristian Dumitrescu 		if (status) {
2116f38913b7SCristian Dumitrescu 			snprintf(out, out_size, "Command failed for index %u.\n", idx0);
2117f38913b7SCristian Dumitrescu 			return;
2118f38913b7SCristian Dumitrescu 		}
2119f38913b7SCristian Dumitrescu 	}
2120f38913b7SCristian Dumitrescu }
2121f38913b7SCristian Dumitrescu 
2122f38913b7SCristian Dumitrescu static const char cmd_pipeline_meter_stats_help[] =
2123f38913b7SCristian Dumitrescu "pipeline <pipeline_name> meter <meter_array_name> from <index0> to <index1> "
2124f38913b7SCristian Dumitrescu 	"stats\n";
2125f38913b7SCristian Dumitrescu 
2126f38913b7SCristian Dumitrescu static void
2127f38913b7SCristian Dumitrescu cmd_pipeline_meter_stats(char **tokens,
2128f38913b7SCristian Dumitrescu 	uint32_t n_tokens,
2129f38913b7SCristian Dumitrescu 	char *out,
2130f38913b7SCristian Dumitrescu 	size_t out_size,
2131b9559f94SCristian Dumitrescu 	void *obj __rte_unused)
2132f38913b7SCristian Dumitrescu {
2133f38913b7SCristian Dumitrescu 	struct rte_swx_ctl_meter_stats stats;
2134b9559f94SCristian Dumitrescu 	struct rte_swx_pipeline *p;
2135f38913b7SCristian Dumitrescu 	const char *name;
213600b67591SAli Alnubani 	uint32_t idx0 = 0, idx1 = 0;
2137f38913b7SCristian Dumitrescu 
2138f38913b7SCristian Dumitrescu 	if (n_tokens != 9) {
2139f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2140f38913b7SCristian Dumitrescu 		return;
2141f38913b7SCristian Dumitrescu 	}
2142f38913b7SCristian Dumitrescu 
2143b9559f94SCristian Dumitrescu 	p = rte_swx_pipeline_find(tokens[1]);
2144b9559f94SCristian Dumitrescu 	if (!p) {
2145f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
2146f38913b7SCristian Dumitrescu 		return;
2147f38913b7SCristian Dumitrescu 	}
2148f38913b7SCristian Dumitrescu 
2149f38913b7SCristian Dumitrescu 	if (strcmp(tokens[2], "meter")) {
2150f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "meter");
2151f38913b7SCristian Dumitrescu 		return;
2152f38913b7SCristian Dumitrescu 	}
2153f38913b7SCristian Dumitrescu 
2154f38913b7SCristian Dumitrescu 	name = tokens[3];
2155f38913b7SCristian Dumitrescu 
2156f38913b7SCristian Dumitrescu 	if (strcmp(tokens[4], "from")) {
2157f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "from");
2158f38913b7SCristian Dumitrescu 		return;
2159f38913b7SCristian Dumitrescu 	}
2160f38913b7SCristian Dumitrescu 
2161f38913b7SCristian Dumitrescu 	if (parser_read_uint32(&idx0, tokens[5])) {
2162f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "index0");
2163f38913b7SCristian Dumitrescu 		return;
2164f38913b7SCristian Dumitrescu 	}
2165f38913b7SCristian Dumitrescu 
2166f38913b7SCristian Dumitrescu 	if (strcmp(tokens[6], "to")) {
2167f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "to");
2168f38913b7SCristian Dumitrescu 		return;
2169f38913b7SCristian Dumitrescu 	}
2170f38913b7SCristian Dumitrescu 
2171f38913b7SCristian Dumitrescu 	if (parser_read_uint32(&idx1, tokens[7]) || (idx1 < idx0)) {
2172f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "index1");
2173f38913b7SCristian Dumitrescu 		return;
2174f38913b7SCristian Dumitrescu 	}
2175f38913b7SCristian Dumitrescu 
2176f38913b7SCristian Dumitrescu 	if (strcmp(tokens[8], "stats")) {
2177f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "stats");
2178f38913b7SCristian Dumitrescu 		return;
2179f38913b7SCristian Dumitrescu 	}
2180f38913b7SCristian Dumitrescu 
2181f38913b7SCristian Dumitrescu 	/* Table header. */
2182f38913b7SCristian Dumitrescu 	snprintf(out, out_size, "+-%7s-+-%16s-+-%16s-+-%16s-+-%16s-+-%16s-+-%16s-+\n",
2183f38913b7SCristian Dumitrescu 		 "-------",
2184f38913b7SCristian Dumitrescu 		 "----------------", "----------------", "----------------",
2185f38913b7SCristian Dumitrescu 		 "----------------", "----------------", "----------------");
2186f38913b7SCristian Dumitrescu 	out_size -= strlen(out);
2187f38913b7SCristian Dumitrescu 	out += strlen(out);
2188f38913b7SCristian Dumitrescu 
2189f38913b7SCristian Dumitrescu 	snprintf(out, out_size, "| %4s | %16s | %16s | %16s | %16s | %16s | %16s |\n",
2190f38913b7SCristian Dumitrescu 		 "METER #",
2191f38913b7SCristian Dumitrescu 		 "GREEN (packets)", "YELLOW (packets)", "RED (packets)",
2192f38913b7SCristian Dumitrescu 		 "GREEN (bytes)", "YELLOW (bytes)", "RED (bytes)");
2193f38913b7SCristian Dumitrescu 	out_size -= strlen(out);
2194f38913b7SCristian Dumitrescu 	out += strlen(out);
2195f38913b7SCristian Dumitrescu 
2196f38913b7SCristian Dumitrescu 	snprintf(out, out_size, "+-%7s-+-%16s-+-%16s-+-%16s-+-%16s-+-%16s-+-%16s-+\n",
2197f38913b7SCristian Dumitrescu 		 "-------",
2198f38913b7SCristian Dumitrescu 		 "----------------", "----------------", "----------------",
2199f38913b7SCristian Dumitrescu 		 "----------------", "----------------", "----------------");
2200f38913b7SCristian Dumitrescu 	out_size -= strlen(out);
2201f38913b7SCristian Dumitrescu 	out += strlen(out);
2202f38913b7SCristian Dumitrescu 
2203f38913b7SCristian Dumitrescu 	/* Table rows. */
2204f38913b7SCristian Dumitrescu 	for ( ; idx0 <= idx1; idx0++) {
2205f38913b7SCristian Dumitrescu 		int status;
2206f38913b7SCristian Dumitrescu 
2207b9559f94SCristian Dumitrescu 		status = rte_swx_ctl_meter_stats_read(p, name, idx0, &stats);
2208f38913b7SCristian Dumitrescu 		if (status) {
2209f38913b7SCristian Dumitrescu 			snprintf(out, out_size, "Pipeline meter stats error at index %u.\n", idx0);
2210f38913b7SCristian Dumitrescu 			out_size -= strlen(out);
2211f38913b7SCristian Dumitrescu 			out += strlen(out);
2212f38913b7SCristian Dumitrescu 			return;
2213f38913b7SCristian Dumitrescu 		}
2214f38913b7SCristian Dumitrescu 
2215f38913b7SCristian Dumitrescu 		snprintf(out, out_size, "| %7d | %16" PRIx64 " | %16" PRIx64 " | %16" PRIx64
2216f38913b7SCristian Dumitrescu 			 " | %16" PRIx64 " | %16" PRIx64 " | %16" PRIx64 " |\n",
2217f38913b7SCristian Dumitrescu 			 idx0,
2218f38913b7SCristian Dumitrescu 			 stats.n_pkts[RTE_COLOR_GREEN],
2219f38913b7SCristian Dumitrescu 			 stats.n_pkts[RTE_COLOR_YELLOW],
2220f38913b7SCristian Dumitrescu 			 stats.n_pkts[RTE_COLOR_RED],
2221f38913b7SCristian Dumitrescu 			 stats.n_bytes[RTE_COLOR_GREEN],
2222f38913b7SCristian Dumitrescu 			 stats.n_bytes[RTE_COLOR_YELLOW],
2223f38913b7SCristian Dumitrescu 			 stats.n_bytes[RTE_COLOR_RED]);
2224f38913b7SCristian Dumitrescu 		out_size -= strlen(out);
2225f38913b7SCristian Dumitrescu 		out += strlen(out);
2226f38913b7SCristian Dumitrescu 	}
2227f38913b7SCristian Dumitrescu }
2228f38913b7SCristian Dumitrescu 
22295074e1d5SCristian Dumitrescu static const char cmd_pipeline_stats_help[] =
22305074e1d5SCristian Dumitrescu "pipeline <pipeline_name> stats\n";
22315074e1d5SCristian Dumitrescu 
22325074e1d5SCristian Dumitrescu static void
22335074e1d5SCristian Dumitrescu cmd_pipeline_stats(char **tokens,
22345074e1d5SCristian Dumitrescu 	uint32_t n_tokens,
22355074e1d5SCristian Dumitrescu 	char *out,
22365074e1d5SCristian Dumitrescu 	size_t out_size,
2237b9559f94SCristian Dumitrescu 	void *obj __rte_unused)
22385074e1d5SCristian Dumitrescu {
22395074e1d5SCristian Dumitrescu 	struct rte_swx_ctl_pipeline_info info;
2240b9559f94SCristian Dumitrescu 	struct rte_swx_pipeline *p;
22415074e1d5SCristian Dumitrescu 	uint32_t i;
22425074e1d5SCristian Dumitrescu 	int status;
22435074e1d5SCristian Dumitrescu 
22445074e1d5SCristian Dumitrescu 	if (n_tokens != 3) {
22455074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
22465074e1d5SCristian Dumitrescu 		return;
22475074e1d5SCristian Dumitrescu 	}
22485074e1d5SCristian Dumitrescu 
2249b9559f94SCristian Dumitrescu 	p = rte_swx_pipeline_find(tokens[1]);
2250b9559f94SCristian Dumitrescu 	if (!p) {
22515074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
22525074e1d5SCristian Dumitrescu 		return;
22535074e1d5SCristian Dumitrescu 	}
22545074e1d5SCristian Dumitrescu 
22555074e1d5SCristian Dumitrescu 	if (strcmp(tokens[2], "stats")) {
22565074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "stats");
22575074e1d5SCristian Dumitrescu 		return;
22585074e1d5SCristian Dumitrescu 	}
22595074e1d5SCristian Dumitrescu 
2260b9559f94SCristian Dumitrescu 	status = rte_swx_ctl_pipeline_info_get(p, &info);
22615074e1d5SCristian Dumitrescu 	if (status) {
22625074e1d5SCristian Dumitrescu 		snprintf(out, out_size, "Pipeline info get error.");
22635074e1d5SCristian Dumitrescu 		return;
22645074e1d5SCristian Dumitrescu 	}
22655074e1d5SCristian Dumitrescu 
22665074e1d5SCristian Dumitrescu 	snprintf(out, out_size, "Input ports:\n");
22675074e1d5SCristian Dumitrescu 	out_size -= strlen(out);
22685074e1d5SCristian Dumitrescu 	out += strlen(out);
22695074e1d5SCristian Dumitrescu 
22705074e1d5SCristian Dumitrescu 	for (i = 0; i < info.n_ports_in; i++) {
22715074e1d5SCristian Dumitrescu 		struct rte_swx_port_in_stats stats;
22725074e1d5SCristian Dumitrescu 
2273b9559f94SCristian Dumitrescu 		rte_swx_ctl_pipeline_port_in_stats_read(p, i, &stats);
22745074e1d5SCristian Dumitrescu 
22755074e1d5SCristian Dumitrescu 		snprintf(out, out_size, "\tPort %u:"
22765074e1d5SCristian Dumitrescu 			" packets %" PRIu64
22775074e1d5SCristian Dumitrescu 			" bytes %" PRIu64
22785074e1d5SCristian Dumitrescu 			" empty %" PRIu64 "\n",
22795074e1d5SCristian Dumitrescu 			i, stats.n_pkts, stats.n_bytes, stats.n_empty);
22805074e1d5SCristian Dumitrescu 		out_size -= strlen(out);
22815074e1d5SCristian Dumitrescu 		out += strlen(out);
22825074e1d5SCristian Dumitrescu 	}
22835074e1d5SCristian Dumitrescu 
2284742b0a57SCristian Dumitrescu 	snprintf(out, out_size, "\nOutput ports:\n");
22855074e1d5SCristian Dumitrescu 	out_size -= strlen(out);
22865074e1d5SCristian Dumitrescu 	out += strlen(out);
22875074e1d5SCristian Dumitrescu 
22885074e1d5SCristian Dumitrescu 	for (i = 0; i < info.n_ports_out; i++) {
22895074e1d5SCristian Dumitrescu 		struct rte_swx_port_out_stats stats;
22905074e1d5SCristian Dumitrescu 
2291b9559f94SCristian Dumitrescu 		rte_swx_ctl_pipeline_port_out_stats_read(p, i, &stats);
22925074e1d5SCristian Dumitrescu 
229396b37959SCristian Dumitrescu 		if (i != info.n_ports_out - 1)
229417225455SCristian Dumitrescu 			snprintf(out, out_size, "\tPort %u:", i);
229596b37959SCristian Dumitrescu 		else
229617225455SCristian Dumitrescu 			snprintf(out, out_size, "\tDROP:");
229717225455SCristian Dumitrescu 
229817225455SCristian Dumitrescu 		out_size -= strlen(out);
229917225455SCristian Dumitrescu 		out += strlen(out);
230017225455SCristian Dumitrescu 
230117225455SCristian Dumitrescu 		snprintf(out,
230217225455SCristian Dumitrescu 			out_size,
230396b37959SCristian Dumitrescu 			" packets %" PRIu64
230417225455SCristian Dumitrescu 			" bytes %" PRIu64
230517225455SCristian Dumitrescu 			" clone %" PRIu64
230617225455SCristian Dumitrescu 			" clonerr %" PRIu64 "\n",
230717225455SCristian Dumitrescu 			stats.n_pkts,
230817225455SCristian Dumitrescu 			stats.n_bytes,
230917225455SCristian Dumitrescu 			stats.n_pkts_clone,
231017225455SCristian Dumitrescu 			stats.n_pkts_clone_err);
231196b37959SCristian Dumitrescu 
23125074e1d5SCristian Dumitrescu 		out_size -= strlen(out);
23135074e1d5SCristian Dumitrescu 		out += strlen(out);
23145074e1d5SCristian Dumitrescu 	}
2315742b0a57SCristian Dumitrescu 
2316742b0a57SCristian Dumitrescu 	snprintf(out, out_size, "\nTables:\n");
2317742b0a57SCristian Dumitrescu 	out_size -= strlen(out);
2318742b0a57SCristian Dumitrescu 	out += strlen(out);
2319742b0a57SCristian Dumitrescu 
2320742b0a57SCristian Dumitrescu 	for (i = 0; i < info.n_tables; i++) {
2321742b0a57SCristian Dumitrescu 		struct rte_swx_ctl_table_info table_info;
2322742b0a57SCristian Dumitrescu 		uint64_t n_pkts_action[info.n_actions];
2323742b0a57SCristian Dumitrescu 		struct rte_swx_table_stats stats = {
2324742b0a57SCristian Dumitrescu 			.n_pkts_hit = 0,
2325742b0a57SCristian Dumitrescu 			.n_pkts_miss = 0,
2326742b0a57SCristian Dumitrescu 			.n_pkts_action = n_pkts_action,
2327742b0a57SCristian Dumitrescu 		};
2328742b0a57SCristian Dumitrescu 		uint32_t j;
2329742b0a57SCristian Dumitrescu 
2330b9559f94SCristian Dumitrescu 		status = rte_swx_ctl_table_info_get(p, i, &table_info);
2331742b0a57SCristian Dumitrescu 		if (status) {
2332742b0a57SCristian Dumitrescu 			snprintf(out, out_size, "Table info get error.");
2333742b0a57SCristian Dumitrescu 			return;
2334742b0a57SCristian Dumitrescu 		}
2335742b0a57SCristian Dumitrescu 
2336b9559f94SCristian Dumitrescu 		status = rte_swx_ctl_pipeline_table_stats_read(p, table_info.name, &stats);
2337742b0a57SCristian Dumitrescu 		if (status) {
2338742b0a57SCristian Dumitrescu 			snprintf(out, out_size, "Table stats read error.");
2339742b0a57SCristian Dumitrescu 			return;
2340742b0a57SCristian Dumitrescu 		}
2341742b0a57SCristian Dumitrescu 
2342742b0a57SCristian Dumitrescu 		snprintf(out, out_size, "\tTable %s:\n"
2343742b0a57SCristian Dumitrescu 			"\t\tHit (packets): %" PRIu64 "\n"
2344742b0a57SCristian Dumitrescu 			"\t\tMiss (packets): %" PRIu64 "\n",
2345742b0a57SCristian Dumitrescu 			table_info.name,
2346742b0a57SCristian Dumitrescu 			stats.n_pkts_hit,
2347742b0a57SCristian Dumitrescu 			stats.n_pkts_miss);
2348742b0a57SCristian Dumitrescu 		out_size -= strlen(out);
2349742b0a57SCristian Dumitrescu 		out += strlen(out);
2350742b0a57SCristian Dumitrescu 
2351742b0a57SCristian Dumitrescu 		for (j = 0; j < info.n_actions; j++) {
2352742b0a57SCristian Dumitrescu 			struct rte_swx_ctl_action_info action_info;
2353742b0a57SCristian Dumitrescu 
2354b9559f94SCristian Dumitrescu 			status = rte_swx_ctl_action_info_get(p, j, &action_info);
2355742b0a57SCristian Dumitrescu 			if (status) {
2356742b0a57SCristian Dumitrescu 				snprintf(out, out_size, "Action info get error.");
2357742b0a57SCristian Dumitrescu 				return;
2358742b0a57SCristian Dumitrescu 			}
2359742b0a57SCristian Dumitrescu 
2360742b0a57SCristian Dumitrescu 			snprintf(out, out_size, "\t\tAction %s (packets): %" PRIu64 "\n",
2361742b0a57SCristian Dumitrescu 				action_info.name,
2362742b0a57SCristian Dumitrescu 				stats.n_pkts_action[j]);
2363742b0a57SCristian Dumitrescu 			out_size -= strlen(out);
2364742b0a57SCristian Dumitrescu 			out += strlen(out);
2365742b0a57SCristian Dumitrescu 		}
2366742b0a57SCristian Dumitrescu 	}
23678bd4862fSCristian Dumitrescu 
23688bd4862fSCristian Dumitrescu 	snprintf(out, out_size, "\nLearner tables:\n");
23698bd4862fSCristian Dumitrescu 	out_size -= strlen(out);
23708bd4862fSCristian Dumitrescu 	out += strlen(out);
23718bd4862fSCristian Dumitrescu 
23728bd4862fSCristian Dumitrescu 	for (i = 0; i < info.n_learners; i++) {
23738bd4862fSCristian Dumitrescu 		struct rte_swx_ctl_learner_info learner_info;
23748bd4862fSCristian Dumitrescu 		uint64_t n_pkts_action[info.n_actions];
23758bd4862fSCristian Dumitrescu 		struct rte_swx_learner_stats stats = {
23768bd4862fSCristian Dumitrescu 			.n_pkts_hit = 0,
23778bd4862fSCristian Dumitrescu 			.n_pkts_miss = 0,
23788bd4862fSCristian Dumitrescu 			.n_pkts_action = n_pkts_action,
23798bd4862fSCristian Dumitrescu 		};
23808bd4862fSCristian Dumitrescu 		uint32_t j;
23818bd4862fSCristian Dumitrescu 
2382b9559f94SCristian Dumitrescu 		status = rte_swx_ctl_learner_info_get(p, i, &learner_info);
23838bd4862fSCristian Dumitrescu 		if (status) {
23848bd4862fSCristian Dumitrescu 			snprintf(out, out_size, "Learner table info get error.");
23858bd4862fSCristian Dumitrescu 			return;
23868bd4862fSCristian Dumitrescu 		}
23878bd4862fSCristian Dumitrescu 
2388b9559f94SCristian Dumitrescu 		status = rte_swx_ctl_pipeline_learner_stats_read(p, learner_info.name, &stats);
23898bd4862fSCristian Dumitrescu 		if (status) {
23908bd4862fSCristian Dumitrescu 			snprintf(out, out_size, "Learner table stats read error.");
23918bd4862fSCristian Dumitrescu 			return;
23928bd4862fSCristian Dumitrescu 		}
23938bd4862fSCristian Dumitrescu 
23948bd4862fSCristian Dumitrescu 		snprintf(out, out_size, "\tLearner table %s:\n"
23958bd4862fSCristian Dumitrescu 			"\t\tHit (packets): %" PRIu64 "\n"
23968bd4862fSCristian Dumitrescu 			"\t\tMiss (packets): %" PRIu64 "\n"
23978bd4862fSCristian Dumitrescu 			"\t\tLearn OK (packets): %" PRIu64 "\n"
23988bd4862fSCristian Dumitrescu 			"\t\tLearn error (packets): %" PRIu64 "\n"
239980dd28afSCristian Dumitrescu 			"\t\tRearm (packets): %" PRIu64 "\n"
24008bd4862fSCristian Dumitrescu 			"\t\tForget (packets): %" PRIu64 "\n",
24018bd4862fSCristian Dumitrescu 			learner_info.name,
24028bd4862fSCristian Dumitrescu 			stats.n_pkts_hit,
24038bd4862fSCristian Dumitrescu 			stats.n_pkts_miss,
24048bd4862fSCristian Dumitrescu 			stats.n_pkts_learn_ok,
24058bd4862fSCristian Dumitrescu 			stats.n_pkts_learn_err,
240680dd28afSCristian Dumitrescu 			stats.n_pkts_rearm,
24078bd4862fSCristian Dumitrescu 			stats.n_pkts_forget);
24088bd4862fSCristian Dumitrescu 		out_size -= strlen(out);
24098bd4862fSCristian Dumitrescu 		out += strlen(out);
24108bd4862fSCristian Dumitrescu 
24118bd4862fSCristian Dumitrescu 		for (j = 0; j < info.n_actions; j++) {
24128bd4862fSCristian Dumitrescu 			struct rte_swx_ctl_action_info action_info;
24138bd4862fSCristian Dumitrescu 
2414b9559f94SCristian Dumitrescu 			status = rte_swx_ctl_action_info_get(p, j, &action_info);
24158bd4862fSCristian Dumitrescu 			if (status) {
24168bd4862fSCristian Dumitrescu 				snprintf(out, out_size, "Action info get error.");
24178bd4862fSCristian Dumitrescu 				return;
24188bd4862fSCristian Dumitrescu 			}
24198bd4862fSCristian Dumitrescu 
24208bd4862fSCristian Dumitrescu 			snprintf(out, out_size, "\t\tAction %s (packets): %" PRIu64 "\n",
24218bd4862fSCristian Dumitrescu 				action_info.name,
24228bd4862fSCristian Dumitrescu 				stats.n_pkts_action[j]);
24238bd4862fSCristian Dumitrescu 			out_size -= strlen(out);
24248bd4862fSCristian Dumitrescu 			out += strlen(out);
24258bd4862fSCristian Dumitrescu 		}
24268bd4862fSCristian Dumitrescu 	}
24275074e1d5SCristian Dumitrescu }
24285074e1d5SCristian Dumitrescu 
242917225455SCristian Dumitrescu static const char cmd_pipeline_mirror_session_help[] =
243017225455SCristian Dumitrescu "pipeline <pipeline_name> mirror session <session_id> port <port_id> clone fast | slow "
243117225455SCristian Dumitrescu "truncate <truncation_length>\n";
243217225455SCristian Dumitrescu 
243317225455SCristian Dumitrescu static void
243417225455SCristian Dumitrescu cmd_pipeline_mirror_session(char **tokens,
243517225455SCristian Dumitrescu 	uint32_t n_tokens,
243617225455SCristian Dumitrescu 	char *out,
243717225455SCristian Dumitrescu 	size_t out_size,
2438b9559f94SCristian Dumitrescu 	void *obj __rte_unused)
243917225455SCristian Dumitrescu {
244017225455SCristian Dumitrescu 	struct rte_swx_pipeline_mirroring_session_params params;
2441b9559f94SCristian Dumitrescu 	struct rte_swx_pipeline *p;
244277dd857dSAli Alnubani 	uint32_t session_id = 0;
244317225455SCristian Dumitrescu 	int status;
244417225455SCristian Dumitrescu 
244517225455SCristian Dumitrescu 	if (n_tokens != 11) {
244617225455SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
244717225455SCristian Dumitrescu 		return;
244817225455SCristian Dumitrescu 	}
244917225455SCristian Dumitrescu 
245017225455SCristian Dumitrescu 	if (strcmp(tokens[0], "pipeline")) {
245117225455SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pipeline");
245217225455SCristian Dumitrescu 		return;
245317225455SCristian Dumitrescu 	}
245417225455SCristian Dumitrescu 
2455b9559f94SCristian Dumitrescu 	p = rte_swx_pipeline_find(tokens[1]);
2456b9559f94SCristian Dumitrescu 	if (!p) {
245717225455SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
245817225455SCristian Dumitrescu 		return;
245917225455SCristian Dumitrescu 	}
246017225455SCristian Dumitrescu 
246117225455SCristian Dumitrescu 	if (strcmp(tokens[2], "mirror")) {
246217225455SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "mirror");
246317225455SCristian Dumitrescu 		return;
246417225455SCristian Dumitrescu 	}
246517225455SCristian Dumitrescu 
246617225455SCristian Dumitrescu 	if (strcmp(tokens[3], "session")) {
246717225455SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "session");
246817225455SCristian Dumitrescu 		return;
246917225455SCristian Dumitrescu 	}
247017225455SCristian Dumitrescu 
247117225455SCristian Dumitrescu 	if (parser_read_uint32(&session_id, tokens[4])) {
247217225455SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "session_id");
247317225455SCristian Dumitrescu 		return;
247417225455SCristian Dumitrescu 	}
247517225455SCristian Dumitrescu 
247617225455SCristian Dumitrescu 	if (strcmp(tokens[5], "port")) {
247717225455SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
247817225455SCristian Dumitrescu 		return;
247917225455SCristian Dumitrescu 	}
248017225455SCristian Dumitrescu 
248117225455SCristian Dumitrescu 	if (parser_read_uint32(&params.port_id, tokens[6])) {
248217225455SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
248317225455SCristian Dumitrescu 		return;
248417225455SCristian Dumitrescu 	}
248517225455SCristian Dumitrescu 
248617225455SCristian Dumitrescu 	if (strcmp(tokens[7], "clone")) {
248717225455SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "clone");
248817225455SCristian Dumitrescu 		return;
248917225455SCristian Dumitrescu 	}
249017225455SCristian Dumitrescu 
249117225455SCristian Dumitrescu 	if (!strcmp(tokens[8], "fast"))
249217225455SCristian Dumitrescu 		params.fast_clone = 1;
249317225455SCristian Dumitrescu 	else if (!strcmp(tokens[8], "slow"))
249417225455SCristian Dumitrescu 		params.fast_clone = 0;
249517225455SCristian Dumitrescu 	else {
249617225455SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "clone");
249717225455SCristian Dumitrescu 		return;
249817225455SCristian Dumitrescu 	}
249917225455SCristian Dumitrescu 
250017225455SCristian Dumitrescu 	if (strcmp(tokens[9], "truncate")) {
250117225455SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "truncate");
250217225455SCristian Dumitrescu 		return;
250317225455SCristian Dumitrescu 	}
250417225455SCristian Dumitrescu 
250517225455SCristian Dumitrescu 	if (parser_read_uint32(&params.truncation_length, tokens[10])) {
250617225455SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "truncation_length");
250717225455SCristian Dumitrescu 		return;
250817225455SCristian Dumitrescu 	}
250917225455SCristian Dumitrescu 
2510b9559f94SCristian Dumitrescu 	status = rte_swx_ctl_pipeline_mirroring_session_set(p, session_id, &params);
251117225455SCristian Dumitrescu 	if (status) {
251217225455SCristian Dumitrescu 		snprintf(out, out_size, "Command failed!\n");
251317225455SCristian Dumitrescu 		return;
251417225455SCristian Dumitrescu 	}
251517225455SCristian Dumitrescu }
251617225455SCristian Dumitrescu 
25175074e1d5SCristian Dumitrescu static const char cmd_thread_pipeline_enable_help[] =
2518b9559f94SCristian Dumitrescu "thread <thread_id> pipeline <pipeline_name> enable [ period <timer_period_ms> ]\n";
2519b9559f94SCristian Dumitrescu 
2520b9559f94SCristian Dumitrescu #ifndef TIMER_PERIOD_MS_DEFAULT
2521b9559f94SCristian Dumitrescu #define TIMER_PERIOD_MS_DEFAULT 10
2522b9559f94SCristian Dumitrescu #endif
25235074e1d5SCristian Dumitrescu 
25245074e1d5SCristian Dumitrescu static void
25255074e1d5SCristian Dumitrescu cmd_thread_pipeline_enable(char **tokens,
25265074e1d5SCristian Dumitrescu 	uint32_t n_tokens,
25275074e1d5SCristian Dumitrescu 	char *out,
25285074e1d5SCristian Dumitrescu 	size_t out_size,
2529b9559f94SCristian Dumitrescu 	void *obj __rte_unused)
25305074e1d5SCristian Dumitrescu {
25315074e1d5SCristian Dumitrescu 	char *pipeline_name;
2532b9559f94SCristian Dumitrescu 	struct rte_swx_pipeline *p;
2533b9559f94SCristian Dumitrescu 	uint32_t thread_id, timer_period_ms = TIMER_PERIOD_MS_DEFAULT;
25345074e1d5SCristian Dumitrescu 	int status;
25355074e1d5SCristian Dumitrescu 
2536b9559f94SCristian Dumitrescu 	if ((n_tokens != 5) && (n_tokens != 7)) {
25375074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
25385074e1d5SCristian Dumitrescu 		return;
25395074e1d5SCristian Dumitrescu 	}
25405074e1d5SCristian Dumitrescu 
25415074e1d5SCristian Dumitrescu 	if (parser_read_uint32(&thread_id, tokens[1]) != 0) {
25425074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "thread_id");
25435074e1d5SCristian Dumitrescu 		return;
25445074e1d5SCristian Dumitrescu 	}
25455074e1d5SCristian Dumitrescu 
25465074e1d5SCristian Dumitrescu 	if (strcmp(tokens[2], "pipeline") != 0) {
25475074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pipeline");
25485074e1d5SCristian Dumitrescu 		return;
25495074e1d5SCristian Dumitrescu 	}
25505074e1d5SCristian Dumitrescu 
25515074e1d5SCristian Dumitrescu 	pipeline_name = tokens[3];
2552b9559f94SCristian Dumitrescu 	p = rte_swx_pipeline_find(pipeline_name);
2553b9559f94SCristian Dumitrescu 	if (!p) {
25545074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
25555074e1d5SCristian Dumitrescu 		return;
25565074e1d5SCristian Dumitrescu 	}
25575074e1d5SCristian Dumitrescu 
25585074e1d5SCristian Dumitrescu 	if (strcmp(tokens[4], "enable") != 0) {
25595074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "enable");
25605074e1d5SCristian Dumitrescu 		return;
25615074e1d5SCristian Dumitrescu 	}
25625074e1d5SCristian Dumitrescu 
2563b9559f94SCristian Dumitrescu 	if (n_tokens == 7) {
2564b9559f94SCristian Dumitrescu 		if (strcmp(tokens[5], "period") != 0) {
2565b9559f94SCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_NOT_FOUND, "period");
2566b9559f94SCristian Dumitrescu 			return;
2567b9559f94SCristian Dumitrescu 		}
2568b9559f94SCristian Dumitrescu 
2569b9559f94SCristian Dumitrescu 		if (parser_read_uint32(&timer_period_ms, tokens[6]) != 0) {
2570b9559f94SCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_INVALID, "timer_period_ms");
2571b9559f94SCristian Dumitrescu 			return;
2572b9559f94SCristian Dumitrescu 		}
2573b9559f94SCristian Dumitrescu 	}
2574b9559f94SCristian Dumitrescu 
2575b9559f94SCristian Dumitrescu 	status = thread_pipeline_enable(thread_id, p, timer_period_ms);
25765074e1d5SCristian Dumitrescu 	if (status) {
25775074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_CMD_FAIL, "thread pipeline enable");
25785074e1d5SCristian Dumitrescu 		return;
25795074e1d5SCristian Dumitrescu 	}
25805074e1d5SCristian Dumitrescu }
25815074e1d5SCristian Dumitrescu 
25825074e1d5SCristian Dumitrescu static const char cmd_thread_pipeline_disable_help[] =
25835074e1d5SCristian Dumitrescu "thread <thread_id> pipeline <pipeline_name> disable\n";
25845074e1d5SCristian Dumitrescu 
25855074e1d5SCristian Dumitrescu static void
25865074e1d5SCristian Dumitrescu cmd_thread_pipeline_disable(char **tokens,
25875074e1d5SCristian Dumitrescu 	uint32_t n_tokens,
25885074e1d5SCristian Dumitrescu 	char *out,
25895074e1d5SCristian Dumitrescu 	size_t out_size,
2590b9559f94SCristian Dumitrescu 	void *obj __rte_unused)
25915074e1d5SCristian Dumitrescu {
2592b9559f94SCristian Dumitrescu 	struct rte_swx_pipeline *p;
25935074e1d5SCristian Dumitrescu 	char *pipeline_name;
25945074e1d5SCristian Dumitrescu 	uint32_t thread_id;
25955074e1d5SCristian Dumitrescu 	int status;
25965074e1d5SCristian Dumitrescu 
25975074e1d5SCristian Dumitrescu 	if (n_tokens != 5) {
25985074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
25995074e1d5SCristian Dumitrescu 		return;
26005074e1d5SCristian Dumitrescu 	}
26015074e1d5SCristian Dumitrescu 
26025074e1d5SCristian Dumitrescu 	if (parser_read_uint32(&thread_id, tokens[1]) != 0) {
26035074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "thread_id");
26045074e1d5SCristian Dumitrescu 		return;
26055074e1d5SCristian Dumitrescu 	}
26065074e1d5SCristian Dumitrescu 
26075074e1d5SCristian Dumitrescu 	if (strcmp(tokens[2], "pipeline") != 0) {
26085074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pipeline");
26095074e1d5SCristian Dumitrescu 		return;
26105074e1d5SCristian Dumitrescu 	}
26115074e1d5SCristian Dumitrescu 
26125074e1d5SCristian Dumitrescu 	pipeline_name = tokens[3];
2613b9559f94SCristian Dumitrescu 	p = rte_swx_pipeline_find(pipeline_name);
2614b9559f94SCristian Dumitrescu 	if (!p) {
26155074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
26165074e1d5SCristian Dumitrescu 		return;
26175074e1d5SCristian Dumitrescu 	}
26185074e1d5SCristian Dumitrescu 
26195074e1d5SCristian Dumitrescu 	if (strcmp(tokens[4], "disable") != 0) {
26205074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "disable");
26215074e1d5SCristian Dumitrescu 		return;
26225074e1d5SCristian Dumitrescu 	}
26235074e1d5SCristian Dumitrescu 
2624b9559f94SCristian Dumitrescu 	status = thread_pipeline_disable(thread_id, p);
26255074e1d5SCristian Dumitrescu 	if (status) {
26265074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_CMD_FAIL,
26275074e1d5SCristian Dumitrescu 			"thread pipeline disable");
26285074e1d5SCristian Dumitrescu 		return;
26295074e1d5SCristian Dumitrescu 	}
26305074e1d5SCristian Dumitrescu }
26315074e1d5SCristian Dumitrescu 
26325074e1d5SCristian Dumitrescu static void
26335074e1d5SCristian Dumitrescu cmd_help(char **tokens,
26345074e1d5SCristian Dumitrescu 	 uint32_t n_tokens,
26355074e1d5SCristian Dumitrescu 	 char *out,
26365074e1d5SCristian Dumitrescu 	 size_t out_size,
26375074e1d5SCristian Dumitrescu 	 void *arg __rte_unused)
26385074e1d5SCristian Dumitrescu {
26395074e1d5SCristian Dumitrescu 	tokens++;
26405074e1d5SCristian Dumitrescu 	n_tokens--;
26415074e1d5SCristian Dumitrescu 
26425074e1d5SCristian Dumitrescu 	if (n_tokens == 0) {
26435074e1d5SCristian Dumitrescu 		snprintf(out, out_size,
26447fef9ef1SYogesh Jangra 			"Type 'help <command>' for command details.\n\n"
26457fef9ef1SYogesh Jangra 			"List of commands:\n"
26467fef9ef1SYogesh Jangra 			"\tmempool\n"
2647*f31c80f8SCristian Dumitrescu 			"\tethdev\n"
2648e2b8dc52SVenkata Suresh Kumar P 			"\ttap\n"
26499043f66aSCristian Dumitrescu 			"\tpipeline codegen\n"
26506bc14d9fSCristian Dumitrescu 			"\tpipeline libbuild\n"
26517fef9ef1SYogesh Jangra 			"\tpipeline build\n"
265275129cebSChurchill Khangar 			"\tpipeline table add\n"
265375129cebSChurchill Khangar 			"\tpipeline table delete\n"
265475129cebSChurchill Khangar 			"\tpipeline table default\n"
265575129cebSChurchill Khangar 			"\tpipeline table show\n"
2656598fe0ddSCristian Dumitrescu 			"\tpipeline selector group add\n"
2657598fe0ddSCristian Dumitrescu 			"\tpipeline selector group delete\n"
2658598fe0ddSCristian Dumitrescu 			"\tpipeline selector group member add\n"
2659598fe0ddSCristian Dumitrescu 			"\tpipeline selector group member delete\n"
2660598fe0ddSCristian Dumitrescu 			"\tpipeline selector show\n"
26618bd4862fSCristian Dumitrescu 			"\tpipeline learner default\n"
266275129cebSChurchill Khangar 			"\tpipeline commit\n"
266375129cebSChurchill Khangar 			"\tpipeline abort\n"
266464cfcebdSCristian Dumitrescu 			"\tpipeline regrd\n"
266564cfcebdSCristian Dumitrescu 			"\tpipeline regwr\n"
2666f38913b7SCristian Dumitrescu 			"\tpipeline meter profile add\n"
2667f38913b7SCristian Dumitrescu 			"\tpipeline meter profile delete\n"
2668f38913b7SCristian Dumitrescu 			"\tpipeline meter reset\n"
2669f38913b7SCristian Dumitrescu 			"\tpipeline meter set\n"
2670f38913b7SCristian Dumitrescu 			"\tpipeline meter stats\n"
26717fef9ef1SYogesh Jangra 			"\tpipeline stats\n"
267217225455SCristian Dumitrescu 			"\tpipeline mirror session\n"
26737fef9ef1SYogesh Jangra 			"\tthread pipeline enable\n"
26747fef9ef1SYogesh Jangra 			"\tthread pipeline disable\n\n");
26755074e1d5SCristian Dumitrescu 		return;
26765074e1d5SCristian Dumitrescu 	}
26775074e1d5SCristian Dumitrescu 
26785074e1d5SCristian Dumitrescu 	if (strcmp(tokens[0], "mempool") == 0) {
26795074e1d5SCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n", cmd_mempool_help);
26805074e1d5SCristian Dumitrescu 		return;
26815074e1d5SCristian Dumitrescu 	}
26825074e1d5SCristian Dumitrescu 
2683*f31c80f8SCristian Dumitrescu 	if (strcmp(tokens[0], "ethdev") == 0) {
2684*f31c80f8SCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n", cmd_ethdev_help);
26855074e1d5SCristian Dumitrescu 		return;
26865074e1d5SCristian Dumitrescu 	}
26875074e1d5SCristian Dumitrescu 
268877a41301SCristian Dumitrescu 	if (strcmp(tokens[0], "ring") == 0) {
268977a41301SCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n", cmd_ring_help);
269077a41301SCristian Dumitrescu 		return;
269177a41301SCristian Dumitrescu 	}
269277a41301SCristian Dumitrescu 
2693e2b8dc52SVenkata Suresh Kumar P 	if (strcmp(tokens[0], "tap") == 0) {
2694e2b8dc52SVenkata Suresh Kumar P 		snprintf(out, out_size, "\n%s\n", cmd_tap_help);
2695e2b8dc52SVenkata Suresh Kumar P 		return;
2696e2b8dc52SVenkata Suresh Kumar P 	}
2697e2b8dc52SVenkata Suresh Kumar P 
26985074e1d5SCristian Dumitrescu 	if ((strcmp(tokens[0], "pipeline") == 0) &&
26999043f66aSCristian Dumitrescu 		(n_tokens == 2) && (strcmp(tokens[1], "codegen") == 0)) {
27009043f66aSCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n", cmd_pipeline_codegen_help);
27019043f66aSCristian Dumitrescu 		return;
27029043f66aSCristian Dumitrescu 	}
27039043f66aSCristian Dumitrescu 
27049043f66aSCristian Dumitrescu 	if ((strcmp(tokens[0], "pipeline") == 0) &&
27056bc14d9fSCristian Dumitrescu 		(n_tokens == 2) && (strcmp(tokens[1], "libbuild") == 0)) {
27066bc14d9fSCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n", cmd_pipeline_libbuild_help);
27076bc14d9fSCristian Dumitrescu 		return;
27086bc14d9fSCristian Dumitrescu 	}
27096bc14d9fSCristian Dumitrescu 
27106bc14d9fSCristian Dumitrescu 	if ((strcmp(tokens[0], "pipeline") == 0) &&
27117fef9ef1SYogesh Jangra 		(n_tokens == 2) && (strcmp(tokens[1], "build") == 0)) {
27125074e1d5SCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n", cmd_pipeline_build_help);
27135074e1d5SCristian Dumitrescu 		return;
27145074e1d5SCristian Dumitrescu 	}
27155074e1d5SCristian Dumitrescu 
27165074e1d5SCristian Dumitrescu 	if ((strcmp(tokens[0], "pipeline") == 0) &&
27177fef9ef1SYogesh Jangra 		(n_tokens == 3) &&
27187fef9ef1SYogesh Jangra 		(strcmp(tokens[1], "table") == 0) &&
271975129cebSChurchill Khangar 		(strcmp(tokens[2], "add") == 0)) {
27205074e1d5SCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n",
272175129cebSChurchill Khangar 			cmd_pipeline_table_add_help);
272275129cebSChurchill Khangar 		return;
272375129cebSChurchill Khangar 	}
272475129cebSChurchill Khangar 
272575129cebSChurchill Khangar 	if ((strcmp(tokens[0], "pipeline") == 0) &&
272675129cebSChurchill Khangar 		(n_tokens == 3) &&
272775129cebSChurchill Khangar 		(strcmp(tokens[1], "table") == 0) &&
272875129cebSChurchill Khangar 		(strcmp(tokens[2], "delete") == 0)) {
272975129cebSChurchill Khangar 		snprintf(out, out_size, "\n%s\n",
273075129cebSChurchill Khangar 			cmd_pipeline_table_delete_help);
273175129cebSChurchill Khangar 		return;
273275129cebSChurchill Khangar 	}
273375129cebSChurchill Khangar 
273475129cebSChurchill Khangar 	if ((strcmp(tokens[0], "pipeline") == 0) &&
273575129cebSChurchill Khangar 		(n_tokens == 3) &&
273675129cebSChurchill Khangar 		(strcmp(tokens[1], "table") == 0) &&
273775129cebSChurchill Khangar 		(strcmp(tokens[2], "default") == 0)) {
273875129cebSChurchill Khangar 		snprintf(out, out_size, "\n%s\n",
273975129cebSChurchill Khangar 			cmd_pipeline_table_default_help);
274075129cebSChurchill Khangar 		return;
274175129cebSChurchill Khangar 	}
274275129cebSChurchill Khangar 
274375129cebSChurchill Khangar 	if ((strcmp(tokens[0], "pipeline") == 0) &&
274475129cebSChurchill Khangar 		(n_tokens == 3) &&
274575129cebSChurchill Khangar 		(strcmp(tokens[1], "table") == 0) &&
274675129cebSChurchill Khangar 		(strcmp(tokens[2], "show") == 0)) {
274775129cebSChurchill Khangar 		snprintf(out, out_size, "\n%s\n",
274875129cebSChurchill Khangar 			cmd_pipeline_table_show_help);
274975129cebSChurchill Khangar 		return;
275075129cebSChurchill Khangar 	}
275175129cebSChurchill Khangar 
275275129cebSChurchill Khangar 	if ((strcmp(tokens[0], "pipeline") == 0) &&
2753598fe0ddSCristian Dumitrescu 		(n_tokens == 4) &&
2754598fe0ddSCristian Dumitrescu 		(strcmp(tokens[1], "selector") == 0) &&
2755598fe0ddSCristian Dumitrescu 		(strcmp(tokens[2], "group") == 0) &&
2756598fe0ddSCristian Dumitrescu 		(strcmp(tokens[3], "add") == 0)) {
2757598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n",
2758598fe0ddSCristian Dumitrescu 			cmd_pipeline_selector_group_add_help);
2759598fe0ddSCristian Dumitrescu 		return;
2760598fe0ddSCristian Dumitrescu 	}
2761598fe0ddSCristian Dumitrescu 
2762598fe0ddSCristian Dumitrescu 	if ((strcmp(tokens[0], "pipeline") == 0) &&
2763598fe0ddSCristian Dumitrescu 		(n_tokens == 4) &&
2764598fe0ddSCristian Dumitrescu 		(strcmp(tokens[1], "selector") == 0) &&
2765598fe0ddSCristian Dumitrescu 		(strcmp(tokens[2], "group") == 0) &&
2766598fe0ddSCristian Dumitrescu 		(strcmp(tokens[3], "delete") == 0)) {
2767598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n",
2768598fe0ddSCristian Dumitrescu 			cmd_pipeline_selector_group_delete_help);
2769598fe0ddSCristian Dumitrescu 		return;
2770598fe0ddSCristian Dumitrescu 	}
2771598fe0ddSCristian Dumitrescu 
2772598fe0ddSCristian Dumitrescu 	if ((strcmp(tokens[0], "pipeline") == 0) &&
2773598fe0ddSCristian Dumitrescu 		(n_tokens == 5) &&
2774598fe0ddSCristian Dumitrescu 		(strcmp(tokens[1], "selector") == 0) &&
2775598fe0ddSCristian Dumitrescu 		(strcmp(tokens[2], "group") == 0) &&
2776598fe0ddSCristian Dumitrescu 		(strcmp(tokens[3], "member") == 0) &&
2777598fe0ddSCristian Dumitrescu 		(strcmp(tokens[4], "add") == 0)) {
2778598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n",
2779598fe0ddSCristian Dumitrescu 			cmd_pipeline_selector_group_member_add_help);
2780598fe0ddSCristian Dumitrescu 		return;
2781598fe0ddSCristian Dumitrescu 	}
2782598fe0ddSCristian Dumitrescu 
2783598fe0ddSCristian Dumitrescu 	if ((strcmp(tokens[0], "pipeline") == 0) &&
2784598fe0ddSCristian Dumitrescu 		(n_tokens == 5) &&
2785598fe0ddSCristian Dumitrescu 		(strcmp(tokens[1], "selector") == 0) &&
2786598fe0ddSCristian Dumitrescu 		(strcmp(tokens[2], "group") == 0) &&
2787598fe0ddSCristian Dumitrescu 		(strcmp(tokens[3], "member") == 0) &&
2788598fe0ddSCristian Dumitrescu 		(strcmp(tokens[4], "delete") == 0)) {
2789598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n",
2790598fe0ddSCristian Dumitrescu 			cmd_pipeline_selector_group_member_delete_help);
2791598fe0ddSCristian Dumitrescu 		return;
2792598fe0ddSCristian Dumitrescu 	}
2793598fe0ddSCristian Dumitrescu 
2794598fe0ddSCristian Dumitrescu 	if ((strcmp(tokens[0], "pipeline") == 0) &&
2795598fe0ddSCristian Dumitrescu 		(n_tokens == 3) &&
2796598fe0ddSCristian Dumitrescu 		(strcmp(tokens[1], "selector") == 0) &&
2797598fe0ddSCristian Dumitrescu 		(strcmp(tokens[2], "show") == 0)) {
2798598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n",
2799598fe0ddSCristian Dumitrescu 			cmd_pipeline_selector_show_help);
2800598fe0ddSCristian Dumitrescu 		return;
2801598fe0ddSCristian Dumitrescu 	}
2802598fe0ddSCristian Dumitrescu 
2803598fe0ddSCristian Dumitrescu 	if ((strcmp(tokens[0], "pipeline") == 0) &&
28048bd4862fSCristian Dumitrescu 		(n_tokens == 3) &&
28058bd4862fSCristian Dumitrescu 		(strcmp(tokens[1], "learner") == 0) &&
28068bd4862fSCristian Dumitrescu 		(strcmp(tokens[2], "default") == 0)) {
28078bd4862fSCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n",
28088bd4862fSCristian Dumitrescu 			cmd_pipeline_learner_default_help);
28098bd4862fSCristian Dumitrescu 		return;
28108bd4862fSCristian Dumitrescu 	}
28118bd4862fSCristian Dumitrescu 
28128bd4862fSCristian Dumitrescu 	if ((strcmp(tokens[0], "pipeline") == 0) &&
281375129cebSChurchill Khangar 		(n_tokens == 2) &&
281475129cebSChurchill Khangar 		(strcmp(tokens[1], "commit") == 0)) {
281575129cebSChurchill Khangar 		snprintf(out, out_size, "\n%s\n",
281675129cebSChurchill Khangar 			cmd_pipeline_commit_help);
281775129cebSChurchill Khangar 		return;
281875129cebSChurchill Khangar 	}
281975129cebSChurchill Khangar 
282075129cebSChurchill Khangar 	if ((strcmp(tokens[0], "pipeline") == 0) &&
282175129cebSChurchill Khangar 		(n_tokens == 2) &&
282275129cebSChurchill Khangar 		(strcmp(tokens[1], "abort") == 0)) {
282375129cebSChurchill Khangar 		snprintf(out, out_size, "\n%s\n",
282475129cebSChurchill Khangar 			cmd_pipeline_abort_help);
28255074e1d5SCristian Dumitrescu 		return;
28265074e1d5SCristian Dumitrescu 	}
28275074e1d5SCristian Dumitrescu 
28285074e1d5SCristian Dumitrescu 	if ((strcmp(tokens[0], "pipeline") == 0) &&
282964cfcebdSCristian Dumitrescu 		(n_tokens == 2) && (strcmp(tokens[1], "regrd") == 0)) {
283064cfcebdSCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n", cmd_pipeline_regrd_help);
283164cfcebdSCristian Dumitrescu 		return;
283264cfcebdSCristian Dumitrescu 	}
283364cfcebdSCristian Dumitrescu 
283464cfcebdSCristian Dumitrescu 	if ((strcmp(tokens[0], "pipeline") == 0) &&
283564cfcebdSCristian Dumitrescu 		(n_tokens == 2) && (strcmp(tokens[1], "regwr") == 0)) {
283664cfcebdSCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n", cmd_pipeline_regwr_help);
283764cfcebdSCristian Dumitrescu 		return;
283864cfcebdSCristian Dumitrescu 	}
283964cfcebdSCristian Dumitrescu 
2840f38913b7SCristian Dumitrescu 	if (!strcmp(tokens[0], "pipeline") &&
2841f38913b7SCristian Dumitrescu 		(n_tokens == 4) && !strcmp(tokens[1], "meter")
2842f38913b7SCristian Dumitrescu 		&& !strcmp(tokens[2], "profile")
2843f38913b7SCristian Dumitrescu 		&& !strcmp(tokens[3], "add")) {
2844f38913b7SCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n", cmd_pipeline_meter_profile_add_help);
2845f38913b7SCristian Dumitrescu 		return;
2846f38913b7SCristian Dumitrescu 	}
2847f38913b7SCristian Dumitrescu 
2848f38913b7SCristian Dumitrescu 	if (!strcmp(tokens[0], "pipeline") &&
2849f38913b7SCristian Dumitrescu 		(n_tokens == 4) && !strcmp(tokens[1], "meter")
2850f38913b7SCristian Dumitrescu 		&& !strcmp(tokens[2], "profile")
2851f38913b7SCristian Dumitrescu 		&& !strcmp(tokens[3], "delete")) {
2852f38913b7SCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n", cmd_pipeline_meter_profile_delete_help);
2853f38913b7SCristian Dumitrescu 		return;
2854f38913b7SCristian Dumitrescu 	}
2855f38913b7SCristian Dumitrescu 
2856f38913b7SCristian Dumitrescu 	if (!strcmp(tokens[0], "pipeline") &&
2857f38913b7SCristian Dumitrescu 		(n_tokens == 3) && !strcmp(tokens[1], "meter")
2858f38913b7SCristian Dumitrescu 		&& !strcmp(tokens[2], "reset")) {
2859f38913b7SCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n", cmd_pipeline_meter_reset_help);
2860f38913b7SCristian Dumitrescu 		return;
2861f38913b7SCristian Dumitrescu 	}
2862f38913b7SCristian Dumitrescu 
2863f38913b7SCristian Dumitrescu 	if (!strcmp(tokens[0], "pipeline") &&
2864f38913b7SCristian Dumitrescu 		(n_tokens == 3) && !strcmp(tokens[1], "meter")
2865f38913b7SCristian Dumitrescu 		&& !strcmp(tokens[2], "set")) {
2866f38913b7SCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n", cmd_pipeline_meter_set_help);
2867f38913b7SCristian Dumitrescu 		return;
2868f38913b7SCristian Dumitrescu 	}
2869f38913b7SCristian Dumitrescu 
2870f38913b7SCristian Dumitrescu 	if (!strcmp(tokens[0], "pipeline") &&
2871f38913b7SCristian Dumitrescu 		(n_tokens == 3) && !strcmp(tokens[1], "meter")
2872f38913b7SCristian Dumitrescu 		&& !strcmp(tokens[2], "stats")) {
2873f38913b7SCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n", cmd_pipeline_meter_stats_help);
2874f38913b7SCristian Dumitrescu 		return;
2875f38913b7SCristian Dumitrescu 	}
2876f38913b7SCristian Dumitrescu 
287764cfcebdSCristian Dumitrescu 	if ((strcmp(tokens[0], "pipeline") == 0) &&
28787fef9ef1SYogesh Jangra 		(n_tokens == 2) && (strcmp(tokens[1], "stats") == 0)) {
28795074e1d5SCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n", cmd_pipeline_stats_help);
28805074e1d5SCristian Dumitrescu 		return;
28815074e1d5SCristian Dumitrescu 	}
28825074e1d5SCristian Dumitrescu 
288317225455SCristian Dumitrescu 	if (!strcmp(tokens[0], "pipeline") &&
288417225455SCristian Dumitrescu 		(n_tokens == 3) && !strcmp(tokens[1], "mirror")
288517225455SCristian Dumitrescu 		&& !strcmp(tokens[2], "session")) {
288617225455SCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n", cmd_pipeline_mirror_session_help);
288717225455SCristian Dumitrescu 		return;
288817225455SCristian Dumitrescu 	}
288917225455SCristian Dumitrescu 
28905074e1d5SCristian Dumitrescu 	if ((n_tokens == 3) &&
28915074e1d5SCristian Dumitrescu 		(strcmp(tokens[0], "thread") == 0) &&
28925074e1d5SCristian Dumitrescu 		(strcmp(tokens[1], "pipeline") == 0)) {
28935074e1d5SCristian Dumitrescu 		if (strcmp(tokens[2], "enable") == 0) {
28945074e1d5SCristian Dumitrescu 			snprintf(out, out_size, "\n%s\n",
28955074e1d5SCristian Dumitrescu 				cmd_thread_pipeline_enable_help);
28965074e1d5SCristian Dumitrescu 			return;
28975074e1d5SCristian Dumitrescu 		}
28985074e1d5SCristian Dumitrescu 
28995074e1d5SCristian Dumitrescu 		if (strcmp(tokens[2], "disable") == 0) {
29005074e1d5SCristian Dumitrescu 			snprintf(out, out_size, "\n%s\n",
29015074e1d5SCristian Dumitrescu 				cmd_thread_pipeline_disable_help);
29025074e1d5SCristian Dumitrescu 			return;
29035074e1d5SCristian Dumitrescu 		}
29045074e1d5SCristian Dumitrescu 	}
29055074e1d5SCristian Dumitrescu 
29065074e1d5SCristian Dumitrescu 	snprintf(out, out_size, "Invalid command\n");
29075074e1d5SCristian Dumitrescu }
29085074e1d5SCristian Dumitrescu 
29095074e1d5SCristian Dumitrescu void
29105074e1d5SCristian Dumitrescu cli_process(char *in, char *out, size_t out_size, void *obj)
29115074e1d5SCristian Dumitrescu {
29125074e1d5SCristian Dumitrescu 	char *tokens[CMD_MAX_TOKENS];
29135074e1d5SCristian Dumitrescu 	uint32_t n_tokens = RTE_DIM(tokens);
29145074e1d5SCristian Dumitrescu 	int status;
29155074e1d5SCristian Dumitrescu 
29165074e1d5SCristian Dumitrescu 	if (is_comment(in))
29175074e1d5SCristian Dumitrescu 		return;
29185074e1d5SCristian Dumitrescu 
29195074e1d5SCristian Dumitrescu 	status = parse_tokenize_string(in, tokens, &n_tokens);
29205074e1d5SCristian Dumitrescu 	if (status) {
29215074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_TOO_MANY, "");
29225074e1d5SCristian Dumitrescu 		return;
29235074e1d5SCristian Dumitrescu 	}
29245074e1d5SCristian Dumitrescu 
29255074e1d5SCristian Dumitrescu 	if (n_tokens == 0)
29265074e1d5SCristian Dumitrescu 		return;
29275074e1d5SCristian Dumitrescu 
29285074e1d5SCristian Dumitrescu 	if (strcmp(tokens[0], "help") == 0) {
29295074e1d5SCristian Dumitrescu 		cmd_help(tokens, n_tokens, out, out_size, obj);
29305074e1d5SCristian Dumitrescu 		return;
29315074e1d5SCristian Dumitrescu 	}
29325074e1d5SCristian Dumitrescu 
29335074e1d5SCristian Dumitrescu 	if (strcmp(tokens[0], "mempool") == 0) {
29345074e1d5SCristian Dumitrescu 		cmd_mempool(tokens, n_tokens, out, out_size, obj);
29355074e1d5SCristian Dumitrescu 		return;
29365074e1d5SCristian Dumitrescu 	}
29375074e1d5SCristian Dumitrescu 
2938*f31c80f8SCristian Dumitrescu 	if (strcmp(tokens[0], "ethdev") == 0) {
2939821848f5SCristian Dumitrescu 		if ((n_tokens >= 2) && (strcmp(tokens[1], "show") == 0)) {
2940*f31c80f8SCristian Dumitrescu 			cmd_ethdev_show(tokens, n_tokens, out, out_size, obj);
29415074e1d5SCristian Dumitrescu 			return;
29425074e1d5SCristian Dumitrescu 		}
29435074e1d5SCristian Dumitrescu 
2944*f31c80f8SCristian Dumitrescu 		cmd_ethdev(tokens, n_tokens, out, out_size, obj);
29455074e1d5SCristian Dumitrescu 		return;
29465074e1d5SCristian Dumitrescu 	}
29475074e1d5SCristian Dumitrescu 
294877a41301SCristian Dumitrescu 	if (strcmp(tokens[0], "ring") == 0) {
294977a41301SCristian Dumitrescu 		cmd_ring(tokens, n_tokens, out, out_size, obj);
295077a41301SCristian Dumitrescu 		return;
295177a41301SCristian Dumitrescu 	}
295277a41301SCristian Dumitrescu 
2953e2b8dc52SVenkata Suresh Kumar P 	if (strcmp(tokens[0], "tap") == 0) {
2954e2b8dc52SVenkata Suresh Kumar P 		cmd_tap(tokens, n_tokens, out, out_size, obj);
2955e2b8dc52SVenkata Suresh Kumar P 		return;
2956e2b8dc52SVenkata Suresh Kumar P 	}
2957e2b8dc52SVenkata Suresh Kumar P 
29585074e1d5SCristian Dumitrescu 	if (strcmp(tokens[0], "pipeline") == 0) {
29595074e1d5SCristian Dumitrescu 		if ((n_tokens >= 3) &&
29609043f66aSCristian Dumitrescu 			(strcmp(tokens[1], "codegen") == 0)) {
29619043f66aSCristian Dumitrescu 			cmd_pipeline_codegen(tokens, n_tokens, out, out_size,
29629043f66aSCristian Dumitrescu 				obj);
29639043f66aSCristian Dumitrescu 			return;
29649043f66aSCristian Dumitrescu 		}
29659043f66aSCristian Dumitrescu 
29669043f66aSCristian Dumitrescu 		if ((n_tokens >= 3) &&
29676bc14d9fSCristian Dumitrescu 			(strcmp(tokens[1], "libbuild") == 0)) {
29686bc14d9fSCristian Dumitrescu 			cmd_pipeline_libbuild(tokens, n_tokens, out, out_size,
29696bc14d9fSCristian Dumitrescu 				obj);
29706bc14d9fSCristian Dumitrescu 			return;
29716bc14d9fSCristian Dumitrescu 		}
29726bc14d9fSCristian Dumitrescu 
29736bc14d9fSCristian Dumitrescu 		if ((n_tokens >= 3) &&
29745074e1d5SCristian Dumitrescu 			(strcmp(tokens[2], "build") == 0)) {
29755074e1d5SCristian Dumitrescu 			cmd_pipeline_build(tokens, n_tokens, out, out_size,
29765074e1d5SCristian Dumitrescu 				obj);
29775074e1d5SCristian Dumitrescu 			return;
29785074e1d5SCristian Dumitrescu 		}
29795074e1d5SCristian Dumitrescu 
298075129cebSChurchill Khangar 		if ((n_tokens >= 5) &&
298175129cebSChurchill Khangar 			(strcmp(tokens[2], "table") == 0) &&
298275129cebSChurchill Khangar 			(strcmp(tokens[4], "add") == 0)) {
298375129cebSChurchill Khangar 			cmd_pipeline_table_add(tokens, n_tokens, out,
298475129cebSChurchill Khangar 				out_size, obj);
298575129cebSChurchill Khangar 			return;
298675129cebSChurchill Khangar 		}
298775129cebSChurchill Khangar 
298875129cebSChurchill Khangar 		if ((n_tokens >= 5) &&
298975129cebSChurchill Khangar 			(strcmp(tokens[2], "table") == 0) &&
299075129cebSChurchill Khangar 			(strcmp(tokens[4], "delete") == 0)) {
299175129cebSChurchill Khangar 			cmd_pipeline_table_delete(tokens, n_tokens, out,
299275129cebSChurchill Khangar 				out_size, obj);
299375129cebSChurchill Khangar 			return;
299475129cebSChurchill Khangar 		}
299575129cebSChurchill Khangar 
299675129cebSChurchill Khangar 		if ((n_tokens >= 5) &&
299775129cebSChurchill Khangar 			(strcmp(tokens[2], "table") == 0) &&
299875129cebSChurchill Khangar 			(strcmp(tokens[4], "default") == 0)) {
299975129cebSChurchill Khangar 			cmd_pipeline_table_default(tokens, n_tokens, out,
300075129cebSChurchill Khangar 				out_size, obj);
300175129cebSChurchill Khangar 			return;
300275129cebSChurchill Khangar 		}
300375129cebSChurchill Khangar 
300475129cebSChurchill Khangar 		if ((n_tokens >= 5) &&
300575129cebSChurchill Khangar 			(strcmp(tokens[2], "table") == 0) &&
300675129cebSChurchill Khangar 			(strcmp(tokens[4], "show") == 0)) {
300775129cebSChurchill Khangar 			cmd_pipeline_table_show(tokens, n_tokens, out,
300875129cebSChurchill Khangar 				out_size, obj);
300975129cebSChurchill Khangar 			return;
301075129cebSChurchill Khangar 		}
301175129cebSChurchill Khangar 
3012598fe0ddSCristian Dumitrescu 		if ((n_tokens >= 6) &&
3013598fe0ddSCristian Dumitrescu 			(strcmp(tokens[2], "selector") == 0) &&
3014598fe0ddSCristian Dumitrescu 			(strcmp(tokens[4], "group") == 0) &&
3015598fe0ddSCristian Dumitrescu 			(strcmp(tokens[5], "add") == 0)) {
3016598fe0ddSCristian Dumitrescu 			cmd_pipeline_selector_group_add(tokens, n_tokens, out,
3017598fe0ddSCristian Dumitrescu 				out_size, obj);
3018598fe0ddSCristian Dumitrescu 			return;
3019598fe0ddSCristian Dumitrescu 		}
3020598fe0ddSCristian Dumitrescu 
3021598fe0ddSCristian Dumitrescu 		if ((n_tokens >= 6) &&
3022598fe0ddSCristian Dumitrescu 			(strcmp(tokens[2], "selector") == 0) &&
3023598fe0ddSCristian Dumitrescu 			(strcmp(tokens[4], "group") == 0) &&
3024598fe0ddSCristian Dumitrescu 			(strcmp(tokens[5], "delete") == 0)) {
3025598fe0ddSCristian Dumitrescu 			cmd_pipeline_selector_group_delete(tokens, n_tokens, out,
3026598fe0ddSCristian Dumitrescu 				out_size, obj);
3027598fe0ddSCristian Dumitrescu 			return;
3028598fe0ddSCristian Dumitrescu 		}
3029598fe0ddSCristian Dumitrescu 
3030598fe0ddSCristian Dumitrescu 		if ((n_tokens >= 7) &&
3031598fe0ddSCristian Dumitrescu 			(strcmp(tokens[2], "selector") == 0) &&
3032598fe0ddSCristian Dumitrescu 			(strcmp(tokens[4], "group") == 0) &&
3033598fe0ddSCristian Dumitrescu 			(strcmp(tokens[5], "member") == 0) &&
3034598fe0ddSCristian Dumitrescu 			(strcmp(tokens[6], "add") == 0)) {
3035598fe0ddSCristian Dumitrescu 			cmd_pipeline_selector_group_member_add(tokens, n_tokens, out,
3036598fe0ddSCristian Dumitrescu 				out_size, obj);
3037598fe0ddSCristian Dumitrescu 			return;
3038598fe0ddSCristian Dumitrescu 		}
3039598fe0ddSCristian Dumitrescu 
3040598fe0ddSCristian Dumitrescu 		if ((n_tokens >= 7) &&
3041598fe0ddSCristian Dumitrescu 			(strcmp(tokens[2], "selector") == 0) &&
3042598fe0ddSCristian Dumitrescu 			(strcmp(tokens[4], "group") == 0) &&
3043598fe0ddSCristian Dumitrescu 			(strcmp(tokens[5], "member") == 0) &&
3044598fe0ddSCristian Dumitrescu 			(strcmp(tokens[6], "delete") == 0)) {
3045598fe0ddSCristian Dumitrescu 			cmd_pipeline_selector_group_member_delete(tokens, n_tokens, out,
3046598fe0ddSCristian Dumitrescu 				out_size, obj);
3047598fe0ddSCristian Dumitrescu 			return;
3048598fe0ddSCristian Dumitrescu 		}
3049598fe0ddSCristian Dumitrescu 
3050598fe0ddSCristian Dumitrescu 		if ((n_tokens >= 5) &&
3051598fe0ddSCristian Dumitrescu 			(strcmp(tokens[2], "selector") == 0) &&
3052598fe0ddSCristian Dumitrescu 			(strcmp(tokens[4], "show") == 0)) {
3053598fe0ddSCristian Dumitrescu 			cmd_pipeline_selector_show(tokens, n_tokens, out,
3054598fe0ddSCristian Dumitrescu 				out_size, obj);
3055598fe0ddSCristian Dumitrescu 			return;
3056598fe0ddSCristian Dumitrescu 		}
3057598fe0ddSCristian Dumitrescu 
30588bd4862fSCristian Dumitrescu 		if ((n_tokens >= 5) &&
30598bd4862fSCristian Dumitrescu 			(strcmp(tokens[2], "learner") == 0) &&
30608bd4862fSCristian Dumitrescu 			(strcmp(tokens[4], "default") == 0)) {
30618bd4862fSCristian Dumitrescu 			cmd_pipeline_learner_default(tokens, n_tokens, out,
30628bd4862fSCristian Dumitrescu 				out_size, obj);
30638bd4862fSCristian Dumitrescu 			return;
30648bd4862fSCristian Dumitrescu 		}
30658bd4862fSCristian Dumitrescu 
30665074e1d5SCristian Dumitrescu 		if ((n_tokens >= 3) &&
306775129cebSChurchill Khangar 			(strcmp(tokens[2], "commit") == 0)) {
306875129cebSChurchill Khangar 			cmd_pipeline_commit(tokens, n_tokens, out,
306975129cebSChurchill Khangar 				out_size, obj);
307075129cebSChurchill Khangar 			return;
307175129cebSChurchill Khangar 		}
307275129cebSChurchill Khangar 
307375129cebSChurchill Khangar 		if ((n_tokens >= 3) &&
307475129cebSChurchill Khangar 			(strcmp(tokens[2], "abort") == 0)) {
307575129cebSChurchill Khangar 			cmd_pipeline_abort(tokens, n_tokens, out,
30765074e1d5SCristian Dumitrescu 				out_size, obj);
30775074e1d5SCristian Dumitrescu 			return;
30785074e1d5SCristian Dumitrescu 		}
30795074e1d5SCristian Dumitrescu 
30805074e1d5SCristian Dumitrescu 		if ((n_tokens >= 3) &&
308164cfcebdSCristian Dumitrescu 			(strcmp(tokens[2], "regrd") == 0)) {
308264cfcebdSCristian Dumitrescu 			cmd_pipeline_regrd(tokens, n_tokens, out, out_size, obj);
308364cfcebdSCristian Dumitrescu 			return;
308464cfcebdSCristian Dumitrescu 		}
308564cfcebdSCristian Dumitrescu 
308664cfcebdSCristian Dumitrescu 		if ((n_tokens >= 3) &&
308764cfcebdSCristian Dumitrescu 			(strcmp(tokens[2], "regwr") == 0)) {
308864cfcebdSCristian Dumitrescu 			cmd_pipeline_regwr(tokens, n_tokens, out, out_size, obj);
308964cfcebdSCristian Dumitrescu 			return;
309064cfcebdSCristian Dumitrescu 		}
309164cfcebdSCristian Dumitrescu 
3092f38913b7SCristian Dumitrescu 		if ((n_tokens >= 6) &&
3093f38913b7SCristian Dumitrescu 			(strcmp(tokens[2], "meter") == 0) &&
3094f38913b7SCristian Dumitrescu 			(strcmp(tokens[3], "profile") == 0) &&
3095f38913b7SCristian Dumitrescu 			(strcmp(tokens[5], "add") == 0)) {
3096f38913b7SCristian Dumitrescu 			cmd_pipeline_meter_profile_add(tokens, n_tokens, out, out_size, obj);
3097f38913b7SCristian Dumitrescu 			return;
3098f38913b7SCristian Dumitrescu 		}
3099f38913b7SCristian Dumitrescu 
3100f38913b7SCristian Dumitrescu 		if ((n_tokens >= 6) &&
3101f38913b7SCristian Dumitrescu 			(strcmp(tokens[2], "meter") == 0) &&
3102f38913b7SCristian Dumitrescu 			(strcmp(tokens[3], "profile") == 0) &&
3103f38913b7SCristian Dumitrescu 			(strcmp(tokens[5], "delete") == 0)) {
3104f38913b7SCristian Dumitrescu 			cmd_pipeline_meter_profile_delete(tokens, n_tokens, out, out_size, obj);
3105f38913b7SCristian Dumitrescu 			return;
3106f38913b7SCristian Dumitrescu 		}
3107f38913b7SCristian Dumitrescu 
3108f38913b7SCristian Dumitrescu 		if ((n_tokens >= 9) &&
3109f38913b7SCristian Dumitrescu 			(strcmp(tokens[2], "meter") == 0) &&
3110f38913b7SCristian Dumitrescu 			(strcmp(tokens[8], "reset") == 0)) {
3111f38913b7SCristian Dumitrescu 			cmd_pipeline_meter_reset(tokens, n_tokens, out, out_size, obj);
3112f38913b7SCristian Dumitrescu 			return;
3113f38913b7SCristian Dumitrescu 		}
3114f38913b7SCristian Dumitrescu 
3115f38913b7SCristian Dumitrescu 		if ((n_tokens >= 9) &&
3116f38913b7SCristian Dumitrescu 			(strcmp(tokens[2], "meter") == 0) &&
3117f38913b7SCristian Dumitrescu 			(strcmp(tokens[8], "set") == 0)) {
3118f38913b7SCristian Dumitrescu 			cmd_pipeline_meter_set(tokens, n_tokens, out, out_size, obj);
3119f38913b7SCristian Dumitrescu 			return;
3120f38913b7SCristian Dumitrescu 		}
3121f38913b7SCristian Dumitrescu 
3122f38913b7SCristian Dumitrescu 		if ((n_tokens >= 9) &&
3123f38913b7SCristian Dumitrescu 			(strcmp(tokens[2], "meter") == 0) &&
3124f38913b7SCristian Dumitrescu 			(strcmp(tokens[8], "stats") == 0)) {
3125f38913b7SCristian Dumitrescu 			cmd_pipeline_meter_stats(tokens, n_tokens, out, out_size, obj);
3126f38913b7SCristian Dumitrescu 			return;
3127f38913b7SCristian Dumitrescu 		}
3128f38913b7SCristian Dumitrescu 
312964cfcebdSCristian Dumitrescu 		if ((n_tokens >= 3) &&
31305074e1d5SCristian Dumitrescu 			(strcmp(tokens[2], "stats") == 0)) {
31315074e1d5SCristian Dumitrescu 			cmd_pipeline_stats(tokens, n_tokens, out, out_size,
31325074e1d5SCristian Dumitrescu 				obj);
31335074e1d5SCristian Dumitrescu 			return;
31345074e1d5SCristian Dumitrescu 		}
313517225455SCristian Dumitrescu 
313617225455SCristian Dumitrescu 		if ((n_tokens >= 4) &&
313717225455SCristian Dumitrescu 			(strcmp(tokens[2], "mirror") == 0) &&
313817225455SCristian Dumitrescu 			(strcmp(tokens[3], "session") == 0)) {
313917225455SCristian Dumitrescu 			cmd_pipeline_mirror_session(tokens, n_tokens, out, out_size, obj);
314017225455SCristian Dumitrescu 			return;
314117225455SCristian Dumitrescu 		}
31425074e1d5SCristian Dumitrescu 	}
31435074e1d5SCristian Dumitrescu 
31445074e1d5SCristian Dumitrescu 	if (strcmp(tokens[0], "thread") == 0) {
31455074e1d5SCristian Dumitrescu 		if ((n_tokens >= 5) &&
31465074e1d5SCristian Dumitrescu 			(strcmp(tokens[4], "enable") == 0)) {
31475074e1d5SCristian Dumitrescu 			cmd_thread_pipeline_enable(tokens, n_tokens,
31485074e1d5SCristian Dumitrescu 				out, out_size, obj);
31495074e1d5SCristian Dumitrescu 			return;
31505074e1d5SCristian Dumitrescu 		}
31515074e1d5SCristian Dumitrescu 
31525074e1d5SCristian Dumitrescu 		if ((n_tokens >= 5) &&
31535074e1d5SCristian Dumitrescu 			(strcmp(tokens[4], "disable") == 0)) {
31545074e1d5SCristian Dumitrescu 			cmd_thread_pipeline_disable(tokens, n_tokens,
31555074e1d5SCristian Dumitrescu 				out, out_size, obj);
31565074e1d5SCristian Dumitrescu 			return;
31575074e1d5SCristian Dumitrescu 		}
31585074e1d5SCristian Dumitrescu 	}
31595074e1d5SCristian Dumitrescu 
31605074e1d5SCristian Dumitrescu 	snprintf(out, out_size, MSG_CMD_UNKNOWN, tokens[0]);
31615074e1d5SCristian Dumitrescu }
31625074e1d5SCristian Dumitrescu 
31635074e1d5SCristian Dumitrescu int
31645074e1d5SCristian Dumitrescu cli_script_process(const char *file_name,
31655074e1d5SCristian Dumitrescu 	size_t msg_in_len_max,
31665074e1d5SCristian Dumitrescu 	size_t msg_out_len_max,
31675074e1d5SCristian Dumitrescu 	void *obj)
31685074e1d5SCristian Dumitrescu {
31695074e1d5SCristian Dumitrescu 	char *msg_in = NULL, *msg_out = NULL;
31705074e1d5SCristian Dumitrescu 	FILE *f = NULL;
31715074e1d5SCristian Dumitrescu 
31725074e1d5SCristian Dumitrescu 	/* Check input arguments */
31735074e1d5SCristian Dumitrescu 	if ((file_name == NULL) ||
31745074e1d5SCristian Dumitrescu 		(strlen(file_name) == 0) ||
31755074e1d5SCristian Dumitrescu 		(msg_in_len_max == 0) ||
31765074e1d5SCristian Dumitrescu 		(msg_out_len_max == 0))
31775074e1d5SCristian Dumitrescu 		return -EINVAL;
31785074e1d5SCristian Dumitrescu 
31795074e1d5SCristian Dumitrescu 	msg_in = malloc(msg_in_len_max + 1);
31805074e1d5SCristian Dumitrescu 	msg_out = malloc(msg_out_len_max + 1);
31815074e1d5SCristian Dumitrescu 	if ((msg_in == NULL) ||
31825074e1d5SCristian Dumitrescu 		(msg_out == NULL)) {
31835074e1d5SCristian Dumitrescu 		free(msg_out);
31845074e1d5SCristian Dumitrescu 		free(msg_in);
31855074e1d5SCristian Dumitrescu 		return -ENOMEM;
31865074e1d5SCristian Dumitrescu 	}
31875074e1d5SCristian Dumitrescu 
31885074e1d5SCristian Dumitrescu 	/* Open input file */
31895074e1d5SCristian Dumitrescu 	f = fopen(file_name, "r");
31905074e1d5SCristian Dumitrescu 	if (f == NULL) {
31915074e1d5SCristian Dumitrescu 		free(msg_out);
31925074e1d5SCristian Dumitrescu 		free(msg_in);
31935074e1d5SCristian Dumitrescu 		return -EIO;
31945074e1d5SCristian Dumitrescu 	}
31955074e1d5SCristian Dumitrescu 
31965074e1d5SCristian Dumitrescu 	/* Read file */
31975074e1d5SCristian Dumitrescu 	for ( ; ; ) {
31985074e1d5SCristian Dumitrescu 		if (fgets(msg_in, msg_in_len_max + 1, f) == NULL)
31995074e1d5SCristian Dumitrescu 			break;
32005074e1d5SCristian Dumitrescu 
32015074e1d5SCristian Dumitrescu 		printf("%s", msg_in);
32025074e1d5SCristian Dumitrescu 		msg_out[0] = 0;
32035074e1d5SCristian Dumitrescu 
32045074e1d5SCristian Dumitrescu 		cli_process(msg_in,
32055074e1d5SCristian Dumitrescu 			msg_out,
32065074e1d5SCristian Dumitrescu 			msg_out_len_max,
32075074e1d5SCristian Dumitrescu 			obj);
32085074e1d5SCristian Dumitrescu 
32095074e1d5SCristian Dumitrescu 		if (strlen(msg_out))
32105074e1d5SCristian Dumitrescu 			printf("%s", msg_out);
32115074e1d5SCristian Dumitrescu 	}
32125074e1d5SCristian Dumitrescu 
32135074e1d5SCristian Dumitrescu 	/* Close file */
32145074e1d5SCristian Dumitrescu 	fclose(f);
32155074e1d5SCristian Dumitrescu 	free(msg_out);
32165074e1d5SCristian Dumitrescu 	free(msg_in);
32175074e1d5SCristian Dumitrescu 	return 0;
32185074e1d5SCristian Dumitrescu }
3219