xref: /dpdk/examples/pipeline/cli.c (revision 78dffe314cd7bff9cc70385d6e5aaa546b88a6a1)
15074e1d5SCristian Dumitrescu /* SPDX-License-Identifier: BSD-3-Clause
25074e1d5SCristian Dumitrescu  * Copyright(c) 2020 Intel Corporation
35074e1d5SCristian Dumitrescu  */
45074e1d5SCristian Dumitrescu 
572b452c5SDmitry Kozlyuk #include <ctype.h>
65074e1d5SCristian Dumitrescu #include <stdio.h>
75074e1d5SCristian Dumitrescu #include <stdint.h>
85074e1d5SCristian Dumitrescu #include <stdlib.h>
95074e1d5SCristian Dumitrescu #include <string.h>
106bc14d9fSCristian Dumitrescu #include <unistd.h>
115074e1d5SCristian Dumitrescu 
125074e1d5SCristian Dumitrescu #include <rte_common.h>
135074e1d5SCristian Dumitrescu #include <rte_ethdev.h>
14607dd517SCristian Dumitrescu #include <rte_ring.h>
155074e1d5SCristian Dumitrescu #include <rte_swx_port_ethdev.h>
1677a41301SCristian Dumitrescu #include <rte_swx_port_ring.h>
175074e1d5SCristian Dumitrescu #include <rte_swx_port_source_sink.h>
18e2b8dc52SVenkata Suresh Kumar P #include <rte_swx_port_fd.h>
195074e1d5SCristian Dumitrescu #include <rte_swx_pipeline.h>
205074e1d5SCristian Dumitrescu #include <rte_swx_ctl.h>
215074e1d5SCristian Dumitrescu 
225074e1d5SCristian Dumitrescu #include "cli.h"
235074e1d5SCristian Dumitrescu 
245074e1d5SCristian Dumitrescu #include "obj.h"
255074e1d5SCristian Dumitrescu #include "thread.h"
265074e1d5SCristian Dumitrescu 
275074e1d5SCristian Dumitrescu #ifndef CMD_MAX_TOKENS
285074e1d5SCristian Dumitrescu #define CMD_MAX_TOKENS     256
295074e1d5SCristian Dumitrescu #endif
305074e1d5SCristian Dumitrescu 
316bc14d9fSCristian Dumitrescu #ifndef MAX_LINE_SIZE
326bc14d9fSCristian Dumitrescu #define MAX_LINE_SIZE 2048
336bc14d9fSCristian Dumitrescu #endif
346bc14d9fSCristian Dumitrescu 
355074e1d5SCristian Dumitrescu #define MSG_OUT_OF_MEMORY   "Not enough memory.\n"
365074e1d5SCristian Dumitrescu #define MSG_CMD_UNKNOWN     "Unknown command \"%s\".\n"
375074e1d5SCristian Dumitrescu #define MSG_CMD_UNIMPLEM    "Command \"%s\" not implemented.\n"
385074e1d5SCristian Dumitrescu #define MSG_ARG_NOT_ENOUGH  "Not enough arguments for command \"%s\".\n"
395074e1d5SCristian Dumitrescu #define MSG_ARG_TOO_MANY    "Too many arguments for command \"%s\".\n"
405074e1d5SCristian Dumitrescu #define MSG_ARG_MISMATCH    "Wrong number of arguments for command \"%s\".\n"
415074e1d5SCristian Dumitrescu #define MSG_ARG_NOT_FOUND   "Argument \"%s\" not found.\n"
425074e1d5SCristian Dumitrescu #define MSG_ARG_INVALID     "Invalid value for argument \"%s\".\n"
435074e1d5SCristian Dumitrescu #define MSG_FILE_ERR        "Error in file \"%s\" at line %u.\n"
445074e1d5SCristian Dumitrescu #define MSG_FILE_NOT_ENOUGH "Not enough rules in file \"%s\".\n"
455074e1d5SCristian Dumitrescu #define MSG_CMD_FAIL        "Command \"%s\" failed.\n"
465074e1d5SCristian Dumitrescu 
475074e1d5SCristian Dumitrescu #define skip_white_spaces(pos)			\
485074e1d5SCristian Dumitrescu ({						\
495074e1d5SCristian Dumitrescu 	__typeof__(pos) _p = (pos);		\
505074e1d5SCristian Dumitrescu 	for ( ; isspace(*_p); _p++)		\
515074e1d5SCristian Dumitrescu 		;				\
525074e1d5SCristian Dumitrescu 	_p;					\
535074e1d5SCristian Dumitrescu })
545074e1d5SCristian Dumitrescu 
555074e1d5SCristian Dumitrescu static int
565074e1d5SCristian Dumitrescu parser_read_uint64(uint64_t *value, const char *p)
575074e1d5SCristian Dumitrescu {
585074e1d5SCristian Dumitrescu 	char *next;
595074e1d5SCristian Dumitrescu 	uint64_t val;
605074e1d5SCristian Dumitrescu 
615074e1d5SCristian Dumitrescu 	p = skip_white_spaces(p);
625074e1d5SCristian Dumitrescu 	if (!isdigit(*p))
635074e1d5SCristian Dumitrescu 		return -EINVAL;
645074e1d5SCristian Dumitrescu 
650d644eb6SChurchill Khangar 	val = strtoul(p, &next, 0);
665074e1d5SCristian Dumitrescu 	if (p == next)
675074e1d5SCristian Dumitrescu 		return -EINVAL;
685074e1d5SCristian Dumitrescu 
695074e1d5SCristian Dumitrescu 	p = next;
705074e1d5SCristian Dumitrescu 	switch (*p) {
715074e1d5SCristian Dumitrescu 	case 'T':
725074e1d5SCristian Dumitrescu 		val *= 1024ULL;
735074e1d5SCristian Dumitrescu 		/* fall through */
745074e1d5SCristian Dumitrescu 	case 'G':
755074e1d5SCristian Dumitrescu 		val *= 1024ULL;
765074e1d5SCristian Dumitrescu 		/* fall through */
775074e1d5SCristian Dumitrescu 	case 'M':
785074e1d5SCristian Dumitrescu 		val *= 1024ULL;
795074e1d5SCristian Dumitrescu 		/* fall through */
805074e1d5SCristian Dumitrescu 	case 'k':
815074e1d5SCristian Dumitrescu 	case 'K':
825074e1d5SCristian Dumitrescu 		val *= 1024ULL;
835074e1d5SCristian Dumitrescu 		p++;
845074e1d5SCristian Dumitrescu 		break;
855074e1d5SCristian Dumitrescu 	}
865074e1d5SCristian Dumitrescu 
875074e1d5SCristian Dumitrescu 	p = skip_white_spaces(p);
885074e1d5SCristian Dumitrescu 	if (*p != '\0')
895074e1d5SCristian Dumitrescu 		return -EINVAL;
905074e1d5SCristian Dumitrescu 
915074e1d5SCristian Dumitrescu 	*value = val;
925074e1d5SCristian Dumitrescu 	return 0;
935074e1d5SCristian Dumitrescu }
945074e1d5SCristian Dumitrescu 
955074e1d5SCristian Dumitrescu static int
965074e1d5SCristian Dumitrescu parser_read_uint32(uint32_t *value, const char *p)
975074e1d5SCristian Dumitrescu {
985074e1d5SCristian Dumitrescu 	uint64_t val = 0;
995074e1d5SCristian Dumitrescu 	int ret = parser_read_uint64(&val, p);
1005074e1d5SCristian Dumitrescu 
1015074e1d5SCristian Dumitrescu 	if (ret < 0)
1025074e1d5SCristian Dumitrescu 		return ret;
1035074e1d5SCristian Dumitrescu 
1045074e1d5SCristian Dumitrescu 	if (val > UINT32_MAX)
1055074e1d5SCristian Dumitrescu 		return -ERANGE;
1065074e1d5SCristian Dumitrescu 
1075074e1d5SCristian Dumitrescu 	*value = val;
1085074e1d5SCristian Dumitrescu 	return 0;
1095074e1d5SCristian Dumitrescu }
1105074e1d5SCristian Dumitrescu 
1115074e1d5SCristian Dumitrescu #define PARSE_DELIMITER " \f\n\r\t\v"
1125074e1d5SCristian Dumitrescu 
1135074e1d5SCristian Dumitrescu static int
1145074e1d5SCristian Dumitrescu parse_tokenize_string(char *string, char *tokens[], uint32_t *n_tokens)
1155074e1d5SCristian Dumitrescu {
1165074e1d5SCristian Dumitrescu 	uint32_t i;
1175074e1d5SCristian Dumitrescu 
1185074e1d5SCristian Dumitrescu 	if ((string == NULL) ||
1195074e1d5SCristian Dumitrescu 		(tokens == NULL) ||
1205074e1d5SCristian Dumitrescu 		(*n_tokens < 1))
1215074e1d5SCristian Dumitrescu 		return -EINVAL;
1225074e1d5SCristian Dumitrescu 
1235074e1d5SCristian Dumitrescu 	for (i = 0; i < *n_tokens; i++) {
1245074e1d5SCristian Dumitrescu 		tokens[i] = strtok_r(string, PARSE_DELIMITER, &string);
1255074e1d5SCristian Dumitrescu 		if (tokens[i] == NULL)
1265074e1d5SCristian Dumitrescu 			break;
1275074e1d5SCristian Dumitrescu 	}
1285074e1d5SCristian Dumitrescu 
1295074e1d5SCristian Dumitrescu 	if ((i == *n_tokens) && strtok_r(string, PARSE_DELIMITER, &string))
1305074e1d5SCristian Dumitrescu 		return -E2BIG;
1315074e1d5SCristian Dumitrescu 
1325074e1d5SCristian Dumitrescu 	*n_tokens = i;
1335074e1d5SCristian Dumitrescu 	return 0;
1345074e1d5SCristian Dumitrescu }
1355074e1d5SCristian Dumitrescu 
1365074e1d5SCristian Dumitrescu static int
1375074e1d5SCristian Dumitrescu is_comment(char *in)
1385074e1d5SCristian Dumitrescu {
1395074e1d5SCristian Dumitrescu 	if ((strlen(in) && index("!#%;", in[0])) ||
1405074e1d5SCristian Dumitrescu 		(strncmp(in, "//", 2) == 0) ||
1415074e1d5SCristian Dumitrescu 		(strncmp(in, "--", 2) == 0))
1425074e1d5SCristian Dumitrescu 		return 1;
1435074e1d5SCristian Dumitrescu 
1445074e1d5SCristian Dumitrescu 	return 0;
1455074e1d5SCristian Dumitrescu }
1465074e1d5SCristian Dumitrescu 
14783f58a7bSCristian Dumitrescu static void
14883f58a7bSCristian Dumitrescu table_entry_free(struct rte_swx_table_entry *entry)
14983f58a7bSCristian Dumitrescu {
15083f58a7bSCristian Dumitrescu 	if (!entry)
15183f58a7bSCristian Dumitrescu 		return;
15283f58a7bSCristian Dumitrescu 
15383f58a7bSCristian Dumitrescu 	free(entry->key);
15483f58a7bSCristian Dumitrescu 	free(entry->key_mask);
15583f58a7bSCristian Dumitrescu 	free(entry->action_data);
15683f58a7bSCristian Dumitrescu 	free(entry);
15783f58a7bSCristian Dumitrescu }
15883f58a7bSCristian Dumitrescu 
15983f58a7bSCristian Dumitrescu static struct rte_swx_table_entry *
16083f58a7bSCristian Dumitrescu parse_table_entry(struct rte_swx_ctl_pipeline *p,
16183f58a7bSCristian Dumitrescu 		  char *table_name,
16283f58a7bSCristian Dumitrescu 		  char **tokens,
16383f58a7bSCristian Dumitrescu 		  uint32_t n_tokens)
16483f58a7bSCristian Dumitrescu {
16583f58a7bSCristian Dumitrescu 	struct rte_swx_table_entry *entry;
16683f58a7bSCristian Dumitrescu 	char *line;
16783f58a7bSCristian Dumitrescu 	uint32_t i;
16883f58a7bSCristian Dumitrescu 
16983f58a7bSCristian Dumitrescu 	/* Buffer allocation. */
17083f58a7bSCristian Dumitrescu 	line = malloc(MAX_LINE_SIZE);
17183f58a7bSCristian Dumitrescu 	if (!line)
17283f58a7bSCristian Dumitrescu 		return NULL;
17383f58a7bSCristian Dumitrescu 
17483f58a7bSCristian Dumitrescu 	/* Copy tokens to buffer. Since the tokens were initially part of a buffer of size
17583f58a7bSCristian Dumitrescu 	 * MAX_LINE_LENGTH, it is guaranteed that putting back some of them into a buffer of the
17683f58a7bSCristian Dumitrescu 	 * same size separated by a single space will not result in buffer overrun.
17783f58a7bSCristian Dumitrescu 	 */
17883f58a7bSCristian Dumitrescu 	line[0] = 0;
17983f58a7bSCristian Dumitrescu 	for (i = 0; i < n_tokens; i++) {
18083f58a7bSCristian Dumitrescu 		if (i)
18183f58a7bSCristian Dumitrescu 			strcat(line, " ");
18283f58a7bSCristian Dumitrescu 
18383f58a7bSCristian Dumitrescu 		strcat(line, tokens[i]);
18483f58a7bSCristian Dumitrescu 	}
18583f58a7bSCristian Dumitrescu 
18683f58a7bSCristian Dumitrescu 	/* Read the table entry from the input buffer. */
18783f58a7bSCristian Dumitrescu 	entry = rte_swx_ctl_pipeline_table_entry_read(p, table_name, line, NULL);
18883f58a7bSCristian Dumitrescu 
18983f58a7bSCristian Dumitrescu 	/* Buffer free. */
19083f58a7bSCristian Dumitrescu 	free(line);
19183f58a7bSCristian Dumitrescu 
19283f58a7bSCristian Dumitrescu 	return entry;
19383f58a7bSCristian Dumitrescu }
19483f58a7bSCristian Dumitrescu 
1955074e1d5SCristian Dumitrescu static const char cmd_mempool_help[] =
19602d36ef6SCristian Dumitrescu "mempool <mempool_name> "
19702d36ef6SCristian Dumitrescu "meta <mbuf_private_size> "
19802d36ef6SCristian Dumitrescu "pkt <pkt_buffer_size> "
19902d36ef6SCristian Dumitrescu "pool <pool_size> "
20002d36ef6SCristian Dumitrescu "cache <cache_size> "
20102d36ef6SCristian Dumitrescu "numa <numa_node>\n";
2025074e1d5SCristian Dumitrescu 
2035074e1d5SCristian Dumitrescu static void
2045074e1d5SCristian Dumitrescu cmd_mempool(char **tokens,
2055074e1d5SCristian Dumitrescu 	    uint32_t n_tokens,
2065074e1d5SCristian Dumitrescu 	    char *out,
2075074e1d5SCristian Dumitrescu 	    size_t out_size,
20802d36ef6SCristian Dumitrescu 	    void *obj __rte_unused)
2095074e1d5SCristian Dumitrescu {
21002d36ef6SCristian Dumitrescu 	struct rte_mempool *mp;
21102d36ef6SCristian Dumitrescu 	char *mempool_name;
21202d36ef6SCristian Dumitrescu 	uint32_t mbuf_private_size, pkt_buffer_size, pool_size, cache_size, numa_node;
2135074e1d5SCristian Dumitrescu 
21402d36ef6SCristian Dumitrescu 	if (n_tokens != 12) {
2155074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2165074e1d5SCristian Dumitrescu 		return;
2175074e1d5SCristian Dumitrescu 	}
2185074e1d5SCristian Dumitrescu 
21902d36ef6SCristian Dumitrescu 	mempool_name = tokens[1];
2205074e1d5SCristian Dumitrescu 
22102d36ef6SCristian Dumitrescu 	if (strcmp(tokens[2], "meta")) {
22202d36ef6SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "meta");
2235074e1d5SCristian Dumitrescu 		return;
2245074e1d5SCristian Dumitrescu 	}
2255074e1d5SCristian Dumitrescu 
22602d36ef6SCristian Dumitrescu 	if (parser_read_uint32(&mbuf_private_size, tokens[3])) {
22702d36ef6SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "mbuf_private_size");
2285074e1d5SCristian Dumitrescu 		return;
2295074e1d5SCristian Dumitrescu 	}
2305074e1d5SCristian Dumitrescu 
23102d36ef6SCristian Dumitrescu 	if (strcmp(tokens[4], "pkt")) {
23202d36ef6SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pkt");
23302d36ef6SCristian Dumitrescu 		return;
23402d36ef6SCristian Dumitrescu 	}
23502d36ef6SCristian Dumitrescu 
23602d36ef6SCristian Dumitrescu 	if (parser_read_uint32(&pkt_buffer_size, tokens[5])) {
23702d36ef6SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pkt_buffer_size");
23802d36ef6SCristian Dumitrescu 		return;
23902d36ef6SCristian Dumitrescu 	}
24002d36ef6SCristian Dumitrescu 
24102d36ef6SCristian Dumitrescu 	if (strcmp(tokens[6], "pool")) {
2425074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pool");
2435074e1d5SCristian Dumitrescu 		return;
2445074e1d5SCristian Dumitrescu 	}
2455074e1d5SCristian Dumitrescu 
24602d36ef6SCristian Dumitrescu 	if (parser_read_uint32(&pool_size, tokens[7])) {
2475074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pool_size");
2485074e1d5SCristian Dumitrescu 		return;
2495074e1d5SCristian Dumitrescu 	}
2505074e1d5SCristian Dumitrescu 
25102d36ef6SCristian Dumitrescu 	if (strcmp(tokens[8], "cache")) {
2525074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cache");
2535074e1d5SCristian Dumitrescu 		return;
2545074e1d5SCristian Dumitrescu 	}
2555074e1d5SCristian Dumitrescu 
25602d36ef6SCristian Dumitrescu 	if (parser_read_uint32(&cache_size, tokens[9])) {
2575074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "cache_size");
2585074e1d5SCristian Dumitrescu 		return;
2595074e1d5SCristian Dumitrescu 	}
2605074e1d5SCristian Dumitrescu 
26102d36ef6SCristian Dumitrescu 	if (strcmp(tokens[10], "numa")) {
26202d36ef6SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "numa");
2635074e1d5SCristian Dumitrescu 		return;
2645074e1d5SCristian Dumitrescu 	}
2655074e1d5SCristian Dumitrescu 
26602d36ef6SCristian Dumitrescu 	if (parser_read_uint32(&numa_node, tokens[11])) {
26702d36ef6SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "numa_node");
2685074e1d5SCristian Dumitrescu 		return;
2695074e1d5SCristian Dumitrescu 	}
2705074e1d5SCristian Dumitrescu 
27102d36ef6SCristian Dumitrescu 	mp = rte_pktmbuf_pool_create(mempool_name,
27202d36ef6SCristian Dumitrescu 				     pool_size,
27302d36ef6SCristian Dumitrescu 				     cache_size,
27402d36ef6SCristian Dumitrescu 				     mbuf_private_size,
27502d36ef6SCristian Dumitrescu 				     pkt_buffer_size,
27602d36ef6SCristian Dumitrescu 				     numa_node);
27702d36ef6SCristian Dumitrescu 	if (!mp) {
2785074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
2795074e1d5SCristian Dumitrescu 		return;
2805074e1d5SCristian Dumitrescu 	}
2815074e1d5SCristian Dumitrescu }
2825074e1d5SCristian Dumitrescu 
283f31c80f8SCristian Dumitrescu static const char cmd_ethdev_help[] =
284f31c80f8SCristian Dumitrescu "ethdev <ethdev_name>\n"
2855074e1d5SCristian Dumitrescu "   rxq <n_queues> <queue_size> <mempool_name>\n"
2865074e1d5SCristian Dumitrescu "   txq <n_queues> <queue_size>\n"
2875074e1d5SCristian Dumitrescu "   promiscuous on | off\n"
2885074e1d5SCristian Dumitrescu "   [rss <qid_0> ... <qid_n>]\n";
2895074e1d5SCristian Dumitrescu 
2905074e1d5SCristian Dumitrescu static void
291f31c80f8SCristian Dumitrescu cmd_ethdev(char **tokens,
2925074e1d5SCristian Dumitrescu 	uint32_t n_tokens,
2935074e1d5SCristian Dumitrescu 	char *out,
2945074e1d5SCristian Dumitrescu 	size_t out_size,
295*78dffe31SCristian Dumitrescu 	void *obj __rte_unused)
2965074e1d5SCristian Dumitrescu {
297*78dffe31SCristian Dumitrescu 	struct ethdev_params p;
298*78dffe31SCristian Dumitrescu 	struct ethdev_params_rss rss;
2995074e1d5SCristian Dumitrescu 	char *name;
300*78dffe31SCristian Dumitrescu 	int status;
3015074e1d5SCristian Dumitrescu 
3025074e1d5SCristian Dumitrescu 	memset(&p, 0, sizeof(p));
303*78dffe31SCristian Dumitrescu 	memset(&rss, 0, sizeof(rss));
3045074e1d5SCristian Dumitrescu 
305*78dffe31SCristian Dumitrescu 	if (n_tokens < 11 || n_tokens > 12 + ETHDEV_RXQ_RSS_MAX) {
3065074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
3075074e1d5SCristian Dumitrescu 		return;
3085074e1d5SCristian Dumitrescu 	}
3095074e1d5SCristian Dumitrescu 	name = tokens[1];
3105074e1d5SCristian Dumitrescu 
311f31c80f8SCristian Dumitrescu 	if (strcmp(tokens[2], "rxq") != 0) {
3125074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rxq");
3135074e1d5SCristian Dumitrescu 		return;
3145074e1d5SCristian Dumitrescu 	}
3155074e1d5SCristian Dumitrescu 
316f31c80f8SCristian Dumitrescu 	if (parser_read_uint32(&p.rx.n_queues, tokens[3]) != 0) {
3175074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "n_queues");
3185074e1d5SCristian Dumitrescu 		return;
3195074e1d5SCristian Dumitrescu 	}
320f31c80f8SCristian Dumitrescu 	if (parser_read_uint32(&p.rx.queue_size, tokens[4]) != 0) {
3215074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "queue_size");
3225074e1d5SCristian Dumitrescu 		return;
3235074e1d5SCristian Dumitrescu 	}
3245074e1d5SCristian Dumitrescu 
325f31c80f8SCristian Dumitrescu 	p.rx.mempool_name = tokens[5];
3265074e1d5SCristian Dumitrescu 
327f31c80f8SCristian Dumitrescu 	if (strcmp(tokens[6], "txq") != 0) {
3285074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "txq");
3295074e1d5SCristian Dumitrescu 		return;
3305074e1d5SCristian Dumitrescu 	}
3315074e1d5SCristian Dumitrescu 
332f31c80f8SCristian Dumitrescu 	if (parser_read_uint32(&p.tx.n_queues, tokens[7]) != 0) {
3335074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "n_queues");
3345074e1d5SCristian Dumitrescu 		return;
3355074e1d5SCristian Dumitrescu 	}
3365074e1d5SCristian Dumitrescu 
337f31c80f8SCristian Dumitrescu 	if (parser_read_uint32(&p.tx.queue_size, tokens[8]) != 0) {
3385074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "queue_size");
3395074e1d5SCristian Dumitrescu 		return;
3405074e1d5SCristian Dumitrescu 	}
3415074e1d5SCristian Dumitrescu 
342f31c80f8SCristian Dumitrescu 	if (strcmp(tokens[9], "promiscuous") != 0) {
3435074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "promiscuous");
3445074e1d5SCristian Dumitrescu 		return;
3455074e1d5SCristian Dumitrescu 	}
3465074e1d5SCristian Dumitrescu 
347f31c80f8SCristian Dumitrescu 	if (strcmp(tokens[10], "on") == 0)
3485074e1d5SCristian Dumitrescu 		p.promiscuous = 1;
349f31c80f8SCristian Dumitrescu 	else if (strcmp(tokens[10], "off") == 0)
3505074e1d5SCristian Dumitrescu 		p.promiscuous = 0;
3515074e1d5SCristian Dumitrescu 	else {
3525074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "on or off");
3535074e1d5SCristian Dumitrescu 		return;
3545074e1d5SCristian Dumitrescu 	}
3555074e1d5SCristian Dumitrescu 
3565074e1d5SCristian Dumitrescu 	/* RSS */
3575074e1d5SCristian Dumitrescu 	p.rx.rss = NULL;
358f31c80f8SCristian Dumitrescu 	if (n_tokens > 11) {
3595074e1d5SCristian Dumitrescu 		uint32_t queue_id, i;
3605074e1d5SCristian Dumitrescu 
361f31c80f8SCristian Dumitrescu 		if (strcmp(tokens[11], "rss") != 0) {
3625074e1d5SCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rss");
3635074e1d5SCristian Dumitrescu 			return;
3645074e1d5SCristian Dumitrescu 		}
3655074e1d5SCristian Dumitrescu 
3665074e1d5SCristian Dumitrescu 		p.rx.rss = &rss;
3675074e1d5SCristian Dumitrescu 
3685074e1d5SCristian Dumitrescu 		rss.n_queues = 0;
369f31c80f8SCristian Dumitrescu 		for (i = 12; i < n_tokens; i++) {
3705074e1d5SCristian Dumitrescu 			if (parser_read_uint32(&queue_id, tokens[i]) != 0) {
3715074e1d5SCristian Dumitrescu 				snprintf(out, out_size, MSG_ARG_INVALID,
3725074e1d5SCristian Dumitrescu 					"queue_id");
3735074e1d5SCristian Dumitrescu 				return;
3745074e1d5SCristian Dumitrescu 			}
3755074e1d5SCristian Dumitrescu 
3765074e1d5SCristian Dumitrescu 			rss.queue_id[rss.n_queues] = queue_id;
3775074e1d5SCristian Dumitrescu 			rss.n_queues++;
3785074e1d5SCristian Dumitrescu 		}
3795074e1d5SCristian Dumitrescu 	}
3805074e1d5SCristian Dumitrescu 
381*78dffe31SCristian Dumitrescu 	status = ethdev_config(name, &p);
382*78dffe31SCristian Dumitrescu 	if (status) {
3835074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
3845074e1d5SCristian Dumitrescu 		return;
3855074e1d5SCristian Dumitrescu 	}
3865074e1d5SCristian Dumitrescu }
3875074e1d5SCristian Dumitrescu 
3885074e1d5SCristian Dumitrescu static void
389*78dffe31SCristian Dumitrescu ethdev_show(uint16_t port_id, char **out, size_t *out_size)
3905074e1d5SCristian Dumitrescu {
391*78dffe31SCristian Dumitrescu 	char name[RTE_ETH_NAME_MAX_LEN];
392*78dffe31SCristian Dumitrescu 	struct rte_eth_dev_info info;
3935074e1d5SCristian Dumitrescu 	struct rte_eth_stats stats;
394*78dffe31SCristian Dumitrescu 	struct rte_ether_addr addr;
395*78dffe31SCristian Dumitrescu 	struct rte_eth_link link;
396*78dffe31SCristian Dumitrescu 	uint32_t length;
397*78dffe31SCristian Dumitrescu 	uint16_t mtu = 0;
3985074e1d5SCristian Dumitrescu 
399*78dffe31SCristian Dumitrescu 	if (!rte_eth_dev_is_valid_port(port_id))
4005074e1d5SCristian Dumitrescu 		return;
4015074e1d5SCristian Dumitrescu 
402*78dffe31SCristian Dumitrescu 	rte_eth_dev_get_name_by_port(port_id, name);
403*78dffe31SCristian Dumitrescu 	rte_eth_dev_info_get(port_id, &info);
404*78dffe31SCristian Dumitrescu 	rte_eth_stats_get(port_id, &stats);
405*78dffe31SCristian Dumitrescu 	rte_eth_macaddr_get(port_id, &addr);
406*78dffe31SCristian Dumitrescu 	rte_eth_link_get(port_id, &link);
407*78dffe31SCristian Dumitrescu 	rte_eth_dev_get_mtu(port_id, &mtu);
4085074e1d5SCristian Dumitrescu 
409*78dffe31SCristian Dumitrescu 	snprintf(*out, *out_size,
4105074e1d5SCristian Dumitrescu 		 "%s: flags=<%s> mtu %u\n"
411c2c4f87bSAman Deep Singh 		 "\tether " RTE_ETHER_ADDR_PRT_FMT " rxqueues %u txqueues %u\n"
4125074e1d5SCristian Dumitrescu 		 "\tport# %u  speed %s\n"
4135074e1d5SCristian Dumitrescu 		 "\tRX packets %" PRIu64"  bytes %" PRIu64"\n"
4145074e1d5SCristian Dumitrescu 		 "\tRX errors %" PRIu64"  missed %" PRIu64"  no-mbuf %" PRIu64"\n"
4155074e1d5SCristian Dumitrescu 		 "\tTX packets %" PRIu64"  bytes %" PRIu64"\n"
416*78dffe31SCristian Dumitrescu 		 "\tTX errors %" PRIu64"\n\n",
417*78dffe31SCristian Dumitrescu 		 name,
418*78dffe31SCristian Dumitrescu 		 link.link_status ? "UP" : "DOWN",
4195074e1d5SCristian Dumitrescu 		 mtu,
420*78dffe31SCristian Dumitrescu 		 RTE_ETHER_ADDR_BYTES(&addr),
421*78dffe31SCristian Dumitrescu 		 info.nb_rx_queues,
422*78dffe31SCristian Dumitrescu 		 info.nb_tx_queues,
423*78dffe31SCristian Dumitrescu 		 port_id,
424*78dffe31SCristian Dumitrescu 		 rte_eth_link_speed_to_str(link.link_speed),
4255074e1d5SCristian Dumitrescu 		 stats.ipackets,
4265074e1d5SCristian Dumitrescu 		 stats.ibytes,
4275074e1d5SCristian Dumitrescu 		 stats.ierrors,
4285074e1d5SCristian Dumitrescu 		 stats.imissed,
4295074e1d5SCristian Dumitrescu 		 stats.rx_nombuf,
4305074e1d5SCristian Dumitrescu 		 stats.opackets,
4315074e1d5SCristian Dumitrescu 		 stats.obytes,
4325074e1d5SCristian Dumitrescu 		 stats.oerrors);
433*78dffe31SCristian Dumitrescu 
434*78dffe31SCristian Dumitrescu 	length = strlen(*out);
435*78dffe31SCristian Dumitrescu 	*out_size -= length;
436*78dffe31SCristian Dumitrescu 	*out += length;
4375074e1d5SCristian Dumitrescu }
4385074e1d5SCristian Dumitrescu 
439*78dffe31SCristian Dumitrescu 
440*78dffe31SCristian Dumitrescu static char cmd_ethdev_show_help[] =
441*78dffe31SCristian Dumitrescu "ethdev show [ <ethdev_name> ]\n";
442*78dffe31SCristian Dumitrescu 
4435074e1d5SCristian Dumitrescu static void
444f31c80f8SCristian Dumitrescu cmd_ethdev_show(char **tokens,
4455074e1d5SCristian Dumitrescu 	      uint32_t n_tokens,
4465074e1d5SCristian Dumitrescu 	      char *out,
4475074e1d5SCristian Dumitrescu 	      size_t out_size,
448*78dffe31SCristian Dumitrescu 	      void *obj __rte_unused)
4495074e1d5SCristian Dumitrescu {
450*78dffe31SCristian Dumitrescu 	uint16_t port_id;
4515074e1d5SCristian Dumitrescu 
4525074e1d5SCristian Dumitrescu 	if (n_tokens != 2 && n_tokens != 3) {
4535074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
4545074e1d5SCristian Dumitrescu 		return;
4555074e1d5SCristian Dumitrescu 	}
4565074e1d5SCristian Dumitrescu 
457*78dffe31SCristian Dumitrescu 	/* Single device. */
458*78dffe31SCristian Dumitrescu 	if (n_tokens == 3) {
459*78dffe31SCristian Dumitrescu 		int status;
4605074e1d5SCristian Dumitrescu 
461*78dffe31SCristian Dumitrescu 		status = rte_eth_dev_get_port_by_name(tokens[2], &port_id);
462*78dffe31SCristian Dumitrescu 		if (status)
463*78dffe31SCristian Dumitrescu 			snprintf(out, out_size, "Error: Invalid Ethernet device name.\n");
4645074e1d5SCristian Dumitrescu 
465*78dffe31SCristian Dumitrescu 		ethdev_show(port_id, &out, &out_size);
4665074e1d5SCristian Dumitrescu 		return;
4675074e1d5SCristian Dumitrescu 	}
468*78dffe31SCristian Dumitrescu 
469*78dffe31SCristian Dumitrescu 	/*  All devices. */
470*78dffe31SCristian Dumitrescu 	for (port_id = 0; port_id < RTE_MAX_ETHPORTS; port_id++)
471*78dffe31SCristian Dumitrescu 		if (rte_eth_dev_is_valid_port(port_id))
472*78dffe31SCristian Dumitrescu 			ethdev_show(port_id, &out, &out_size);
4735074e1d5SCristian Dumitrescu }
4745074e1d5SCristian Dumitrescu 
47577a41301SCristian Dumitrescu static const char cmd_ring_help[] =
47677a41301SCristian Dumitrescu "ring <ring_name> size <size> numa <numa_node>\n";
47777a41301SCristian Dumitrescu 
47877a41301SCristian Dumitrescu static void
47977a41301SCristian Dumitrescu cmd_ring(char **tokens,
48077a41301SCristian Dumitrescu 	uint32_t n_tokens,
48177a41301SCristian Dumitrescu 	char *out,
48277a41301SCristian Dumitrescu 	size_t out_size,
483607dd517SCristian Dumitrescu 	void *obj __rte_unused)
48477a41301SCristian Dumitrescu {
485607dd517SCristian Dumitrescu 	struct rte_ring *r;
48677a41301SCristian Dumitrescu 	char *name;
487607dd517SCristian Dumitrescu 	uint32_t size, numa_node;
48877a41301SCristian Dumitrescu 
48977a41301SCristian Dumitrescu 	if (n_tokens != 6) {
49077a41301SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
49177a41301SCristian Dumitrescu 		return;
49277a41301SCristian Dumitrescu 	}
49377a41301SCristian Dumitrescu 
49477a41301SCristian Dumitrescu 	name = tokens[1];
49577a41301SCristian Dumitrescu 
496607dd517SCristian Dumitrescu 	if (strcmp(tokens[2], "size")) {
49777a41301SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "size");
49877a41301SCristian Dumitrescu 		return;
49977a41301SCristian Dumitrescu 	}
50077a41301SCristian Dumitrescu 
501607dd517SCristian Dumitrescu 	if (parser_read_uint32(&size, tokens[3])) {
50277a41301SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "size");
50377a41301SCristian Dumitrescu 		return;
50477a41301SCristian Dumitrescu 	}
50577a41301SCristian Dumitrescu 
506607dd517SCristian Dumitrescu 	if (strcmp(tokens[4], "numa")) {
50777a41301SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "numa");
50877a41301SCristian Dumitrescu 		return;
50977a41301SCristian Dumitrescu 	}
51077a41301SCristian Dumitrescu 
511607dd517SCristian Dumitrescu 	if (parser_read_uint32(&numa_node, tokens[5])) {
51277a41301SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "numa_node");
51377a41301SCristian Dumitrescu 		return;
51477a41301SCristian Dumitrescu 	}
51577a41301SCristian Dumitrescu 
516607dd517SCristian Dumitrescu 	r = rte_ring_create(
517607dd517SCristian Dumitrescu 		name,
518607dd517SCristian Dumitrescu 		size,
519607dd517SCristian Dumitrescu 		(int)numa_node,
520607dd517SCristian Dumitrescu 		RING_F_SP_ENQ | RING_F_SC_DEQ);
521607dd517SCristian Dumitrescu 	if (!r) {
52277a41301SCristian Dumitrescu 		snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
52377a41301SCristian Dumitrescu 		return;
52477a41301SCristian Dumitrescu 	}
52577a41301SCristian Dumitrescu }
52677a41301SCristian Dumitrescu 
5279043f66aSCristian Dumitrescu static const char cmd_pipeline_codegen_help[] =
5289043f66aSCristian Dumitrescu "pipeline codegen <spec_file> <code_file>\n";
5299043f66aSCristian Dumitrescu 
5309043f66aSCristian Dumitrescu static void
5319043f66aSCristian Dumitrescu cmd_pipeline_codegen(char **tokens,
5329043f66aSCristian Dumitrescu 	uint32_t n_tokens,
5339043f66aSCristian Dumitrescu 	char *out,
5349043f66aSCristian Dumitrescu 	size_t out_size,
5359043f66aSCristian Dumitrescu 	void *obj __rte_unused)
5369043f66aSCristian Dumitrescu {
5379043f66aSCristian Dumitrescu 	FILE *spec_file = NULL;
5389043f66aSCristian Dumitrescu 	FILE *code_file = NULL;
5399043f66aSCristian Dumitrescu 	uint32_t err_line;
5409043f66aSCristian Dumitrescu 	const char *err_msg;
5419043f66aSCristian Dumitrescu 	int status;
5429043f66aSCristian Dumitrescu 
5439043f66aSCristian Dumitrescu 	if (n_tokens != 4) {
5449043f66aSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
5459043f66aSCristian Dumitrescu 		return;
5469043f66aSCristian Dumitrescu 	}
5479043f66aSCristian Dumitrescu 
5489043f66aSCristian Dumitrescu 	spec_file = fopen(tokens[2], "r");
5499043f66aSCristian Dumitrescu 	if (!spec_file) {
5509043f66aSCristian Dumitrescu 		snprintf(out, out_size, "Cannot open file %s.\n", tokens[2]);
5519043f66aSCristian Dumitrescu 		return;
5529043f66aSCristian Dumitrescu 	}
5539043f66aSCristian Dumitrescu 
5549043f66aSCristian Dumitrescu 	code_file = fopen(tokens[3], "w");
5559043f66aSCristian Dumitrescu 	if (!code_file) {
5569043f66aSCristian Dumitrescu 		snprintf(out, out_size, "Cannot open file %s.\n", tokens[3]);
557ab492f94SHarshad Narayane 		fclose(spec_file);
5589043f66aSCristian Dumitrescu 		return;
5599043f66aSCristian Dumitrescu 	}
5609043f66aSCristian Dumitrescu 
5619043f66aSCristian Dumitrescu 	status = rte_swx_pipeline_codegen(spec_file,
5629043f66aSCristian Dumitrescu 					  code_file,
5639043f66aSCristian Dumitrescu 					  &err_line,
5649043f66aSCristian Dumitrescu 					  &err_msg);
5659043f66aSCristian Dumitrescu 
5669043f66aSCristian Dumitrescu 	fclose(spec_file);
5679043f66aSCristian Dumitrescu 	fclose(code_file);
5689043f66aSCristian Dumitrescu 
5699043f66aSCristian Dumitrescu 	if (status) {
5709043f66aSCristian Dumitrescu 		snprintf(out, out_size, "Error %d at line %u: %s\n.",
5719043f66aSCristian Dumitrescu 			status, err_line, err_msg);
5729043f66aSCristian Dumitrescu 		return;
5739043f66aSCristian Dumitrescu 	}
5749043f66aSCristian Dumitrescu }
5756bc14d9fSCristian Dumitrescu 
5766bc14d9fSCristian Dumitrescu static const char cmd_pipeline_libbuild_help[] =
5776bc14d9fSCristian Dumitrescu "pipeline libbuild <code_file> <lib_file>\n";
5786bc14d9fSCristian Dumitrescu 
5796bc14d9fSCristian Dumitrescu static void
5806bc14d9fSCristian Dumitrescu cmd_pipeline_libbuild(char **tokens,
5816bc14d9fSCristian Dumitrescu 	uint32_t n_tokens,
5826bc14d9fSCristian Dumitrescu 	char *out,
5836bc14d9fSCristian Dumitrescu 	size_t out_size,
5846bc14d9fSCristian Dumitrescu 	void *obj __rte_unused)
5856bc14d9fSCristian Dumitrescu {
5866bc14d9fSCristian Dumitrescu 	char *code_file, *lib_file, *obj_file = NULL, *log_file = NULL;
5876bc14d9fSCristian Dumitrescu 	char *install_dir, *cwd = NULL, *buffer = NULL;
5886bc14d9fSCristian Dumitrescu 	size_t length;
5896bc14d9fSCristian Dumitrescu 	int status = 0;
5906bc14d9fSCristian Dumitrescu 
5916bc14d9fSCristian Dumitrescu 	if (n_tokens != 4) {
5926bc14d9fSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
5936bc14d9fSCristian Dumitrescu 		goto free;
5946bc14d9fSCristian Dumitrescu 	}
5956bc14d9fSCristian Dumitrescu 
5966bc14d9fSCristian Dumitrescu 	install_dir = getenv("RTE_INSTALL_DIR");
5976bc14d9fSCristian Dumitrescu 	if (!install_dir) {
5986bc14d9fSCristian Dumitrescu 		cwd = malloc(MAX_LINE_SIZE);
5996bc14d9fSCristian Dumitrescu 		if (!cwd) {
6006bc14d9fSCristian Dumitrescu 			snprintf(out, out_size, MSG_OUT_OF_MEMORY);
6016bc14d9fSCristian Dumitrescu 			goto free;
6026bc14d9fSCristian Dumitrescu 		}
6036bc14d9fSCristian Dumitrescu 
6046bc14d9fSCristian Dumitrescu 		install_dir = getcwd(cwd, MAX_LINE_SIZE);
6056bc14d9fSCristian Dumitrescu 		if (!install_dir) {
6066bc14d9fSCristian Dumitrescu 			snprintf(out, out_size, "Error: Path too long.\n");
6076bc14d9fSCristian Dumitrescu 			goto free;
6086bc14d9fSCristian Dumitrescu 		}
6096bc14d9fSCristian Dumitrescu 	}
6106bc14d9fSCristian Dumitrescu 
6116bc14d9fSCristian Dumitrescu 	snprintf(out, out_size, "Using DPDK source code from \"%s\".\n", install_dir);
6126bc14d9fSCristian Dumitrescu 	out_size -= strlen(out);
6136bc14d9fSCristian Dumitrescu 	out += strlen(out);
6146bc14d9fSCristian Dumitrescu 
6156bc14d9fSCristian Dumitrescu 	code_file = tokens[2];
6166bc14d9fSCristian Dumitrescu 	length = strnlen(code_file, MAX_LINE_SIZE);
6176bc14d9fSCristian Dumitrescu 	if ((length < 3) ||
6186bc14d9fSCristian Dumitrescu 	    (code_file[length - 2] != '.') ||
6196bc14d9fSCristian Dumitrescu 	    (code_file[length - 1] != 'c')) {
6206bc14d9fSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "code_file");
6216bc14d9fSCristian Dumitrescu 		goto free;
6226bc14d9fSCristian Dumitrescu 	}
6236bc14d9fSCristian Dumitrescu 
6246bc14d9fSCristian Dumitrescu 	lib_file = tokens[3];
6256bc14d9fSCristian Dumitrescu 	length = strnlen(lib_file, MAX_LINE_SIZE);
6266bc14d9fSCristian Dumitrescu 	if ((length < 4) ||
6276bc14d9fSCristian Dumitrescu 	    (lib_file[length - 3] != '.') ||
6286bc14d9fSCristian Dumitrescu 	    (lib_file[length - 2] != 's') ||
6296bc14d9fSCristian Dumitrescu 	    (lib_file[length - 1] != 'o')) {
6306bc14d9fSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "lib_file");
6316bc14d9fSCristian Dumitrescu 		goto free;
6326bc14d9fSCristian Dumitrescu 	}
6336bc14d9fSCristian Dumitrescu 
6346bc14d9fSCristian Dumitrescu 	obj_file = malloc(length);
6356bc14d9fSCristian Dumitrescu 	log_file = malloc(length + 2);
6366bc14d9fSCristian Dumitrescu 	if (!obj_file || !log_file) {
6376bc14d9fSCristian Dumitrescu 		snprintf(out, out_size, MSG_OUT_OF_MEMORY);
6386bc14d9fSCristian Dumitrescu 		goto free;
6396bc14d9fSCristian Dumitrescu 	}
6406bc14d9fSCristian Dumitrescu 
6416bc14d9fSCristian Dumitrescu 	memcpy(obj_file, lib_file, length - 2);
6426bc14d9fSCristian Dumitrescu 	obj_file[length - 2] = 'o';
6436bc14d9fSCristian Dumitrescu 	obj_file[length - 1] = 0;
6446bc14d9fSCristian Dumitrescu 
6456bc14d9fSCristian Dumitrescu 	memcpy(log_file, lib_file, length - 2);
6466bc14d9fSCristian Dumitrescu 	log_file[length - 2] = 'l';
6476bc14d9fSCristian Dumitrescu 	log_file[length - 1] = 'o';
6486bc14d9fSCristian Dumitrescu 	log_file[length] = 'g';
6496bc14d9fSCristian Dumitrescu 	log_file[length + 1] = 0;
6506bc14d9fSCristian Dumitrescu 
6516bc14d9fSCristian Dumitrescu 	buffer = malloc(MAX_LINE_SIZE);
6526bc14d9fSCristian Dumitrescu 	if (!buffer) {
6536bc14d9fSCristian Dumitrescu 		snprintf(out, out_size, MSG_OUT_OF_MEMORY);
654b42f3e2fSHarshad Narayane 		goto free;
6556bc14d9fSCristian Dumitrescu 	}
6566bc14d9fSCristian Dumitrescu 
6576bc14d9fSCristian Dumitrescu 	snprintf(buffer,
6586bc14d9fSCristian Dumitrescu 		 MAX_LINE_SIZE,
6596bc14d9fSCristian Dumitrescu 		 "gcc -c -O3 -fpic -Wno-deprecated-declarations -o %s %s "
6606bc14d9fSCristian Dumitrescu 		 "-I %s/lib/pipeline "
6616bc14d9fSCristian Dumitrescu 		 "-I %s/lib/eal/include "
6626bc14d9fSCristian Dumitrescu 		 "-I %s/lib/eal/x86/include "
6636bc14d9fSCristian Dumitrescu 		 "-I %s/lib/eal/include/generic "
6646bc14d9fSCristian Dumitrescu 		 "-I %s/lib/meter "
6656bc14d9fSCristian Dumitrescu 		 "-I %s/lib/port "
6666bc14d9fSCristian Dumitrescu 		 "-I %s/lib/table "
6676bc14d9fSCristian Dumitrescu 		 "-I %s/lib/pipeline "
6686bc14d9fSCristian Dumitrescu 		 "-I %s/config "
6696bc14d9fSCristian Dumitrescu 		 "-I %s/build "
6706bc14d9fSCristian Dumitrescu 		 "-I %s/lib/eal/linux/include "
6716bc14d9fSCristian Dumitrescu 		 ">%s 2>&1 "
6726bc14d9fSCristian Dumitrescu 		 "&& "
6736bc14d9fSCristian Dumitrescu 		 "gcc -shared %s -o %s "
6746bc14d9fSCristian Dumitrescu 		 ">>%s 2>&1",
6756bc14d9fSCristian Dumitrescu 		 obj_file,
6766bc14d9fSCristian Dumitrescu 		 code_file,
6776bc14d9fSCristian Dumitrescu 		 install_dir,
6786bc14d9fSCristian Dumitrescu 		 install_dir,
6796bc14d9fSCristian Dumitrescu 		 install_dir,
6806bc14d9fSCristian Dumitrescu 		 install_dir,
6816bc14d9fSCristian Dumitrescu 		 install_dir,
6826bc14d9fSCristian Dumitrescu 		 install_dir,
6836bc14d9fSCristian Dumitrescu 		 install_dir,
6846bc14d9fSCristian Dumitrescu 		 install_dir,
6856bc14d9fSCristian Dumitrescu 		 install_dir,
6866bc14d9fSCristian Dumitrescu 		 install_dir,
6876bc14d9fSCristian Dumitrescu 		 install_dir,
6886bc14d9fSCristian Dumitrescu 		 log_file,
6896bc14d9fSCristian Dumitrescu 		 obj_file,
6906bc14d9fSCristian Dumitrescu 		 lib_file,
6916bc14d9fSCristian Dumitrescu 		 log_file);
6926bc14d9fSCristian Dumitrescu 
6936bc14d9fSCristian Dumitrescu 	status = system(buffer);
6946bc14d9fSCristian Dumitrescu 	if (status) {
6956bc14d9fSCristian Dumitrescu 		snprintf(out,
6966bc14d9fSCristian Dumitrescu 			 out_size,
6976bc14d9fSCristian Dumitrescu 			 "Library build failed, see file \"%s\" for details.\n",
6986bc14d9fSCristian Dumitrescu 			 log_file);
6996bc14d9fSCristian Dumitrescu 		goto free;
7006bc14d9fSCristian Dumitrescu 	}
7016bc14d9fSCristian Dumitrescu 
7026bc14d9fSCristian Dumitrescu free:
7036bc14d9fSCristian Dumitrescu 	free(cwd);
7046bc14d9fSCristian Dumitrescu 	free(obj_file);
7056bc14d9fSCristian Dumitrescu 	free(log_file);
7066bc14d9fSCristian Dumitrescu 	free(buffer);
7076bc14d9fSCristian Dumitrescu }
7086bc14d9fSCristian Dumitrescu 
7095074e1d5SCristian Dumitrescu static const char cmd_pipeline_build_help[] =
71068b95704SCristian Dumitrescu "pipeline <pipeline_name> build lib <lib_file> io <iospec_file> numa <numa_node>\n";
7115074e1d5SCristian Dumitrescu 
7125074e1d5SCristian Dumitrescu static void
7135074e1d5SCristian Dumitrescu cmd_pipeline_build(char **tokens,
7145074e1d5SCristian Dumitrescu 	uint32_t n_tokens,
7155074e1d5SCristian Dumitrescu 	char *out,
7165074e1d5SCristian Dumitrescu 	size_t out_size,
71768b95704SCristian Dumitrescu 	void *obj __rte_unused)
7185074e1d5SCristian Dumitrescu {
71968b95704SCristian Dumitrescu 	struct rte_swx_pipeline *p = NULL;
72068b95704SCristian Dumitrescu 	struct rte_swx_ctl_pipeline *ctl = NULL;
72168b95704SCristian Dumitrescu 	char *pipeline_name, *lib_file_name, *iospec_file_name;
72268b95704SCristian Dumitrescu 	FILE *iospec_file = NULL;
72368b95704SCristian Dumitrescu 	uint32_t numa_node = 0;
72468b95704SCristian Dumitrescu 	int status = 0;
7255074e1d5SCristian Dumitrescu 
72668b95704SCristian Dumitrescu 	/* Parsing. */
72768b95704SCristian Dumitrescu 	if (n_tokens != 9) {
7285074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
7295074e1d5SCristian Dumitrescu 		return;
7305074e1d5SCristian Dumitrescu 	}
7315074e1d5SCristian Dumitrescu 
73268b95704SCristian Dumitrescu 	pipeline_name = tokens[1];
73368b95704SCristian Dumitrescu 
73468b95704SCristian Dumitrescu 	if (strcmp(tokens[2], "build")) {
73568b95704SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "build");
7365074e1d5SCristian Dumitrescu 		return;
7375074e1d5SCristian Dumitrescu 	}
7385074e1d5SCristian Dumitrescu 
73968b95704SCristian Dumitrescu 	if (strcmp(tokens[3], "lib")) {
74068b95704SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "lib");
7415074e1d5SCristian Dumitrescu 		return;
7425074e1d5SCristian Dumitrescu 	}
7435074e1d5SCristian Dumitrescu 
74468b95704SCristian Dumitrescu 	lib_file_name = tokens[4];
74568b95704SCristian Dumitrescu 
74668b95704SCristian Dumitrescu 	if (strcmp(tokens[5], "io")) {
74768b95704SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "io");
74868b95704SCristian Dumitrescu 		return;
74968b95704SCristian Dumitrescu 	}
75068b95704SCristian Dumitrescu 
75168b95704SCristian Dumitrescu 	iospec_file_name = tokens[6];
75268b95704SCristian Dumitrescu 
75368b95704SCristian Dumitrescu 	if (strcmp(tokens[7], "numa")) {
75468b95704SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "numa");
75568b95704SCristian Dumitrescu 		return;
75668b95704SCristian Dumitrescu 	}
75768b95704SCristian Dumitrescu 
75868b95704SCristian Dumitrescu 	if (parser_read_uint32(&numa_node, tokens[8])) {
75968b95704SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "numa_node");
76068b95704SCristian Dumitrescu 		return;
76168b95704SCristian Dumitrescu 	}
76268b95704SCristian Dumitrescu 
76368b95704SCristian Dumitrescu 	/* I/O spec file open. */
76468b95704SCristian Dumitrescu 	iospec_file = fopen(iospec_file_name, "r");
76568b95704SCristian Dumitrescu 	if (!iospec_file) {
76668b95704SCristian Dumitrescu 		snprintf(out, out_size, "Cannot open file \"%s\".\n", iospec_file_name);
76768b95704SCristian Dumitrescu 		return;
76868b95704SCristian Dumitrescu 	}
76968b95704SCristian Dumitrescu 
77068b95704SCristian Dumitrescu 	status = rte_swx_pipeline_build_from_lib(&p,
77168b95704SCristian Dumitrescu 						 pipeline_name,
77268b95704SCristian Dumitrescu 						 lib_file_name,
77368b95704SCristian Dumitrescu 						 iospec_file,
77468b95704SCristian Dumitrescu 						 (int)numa_node);
7755074e1d5SCristian Dumitrescu 	if (status) {
77668b95704SCristian Dumitrescu 		snprintf(out, out_size, "Pipeline build failed (%d).", status);
77768b95704SCristian Dumitrescu 		goto free;
7785074e1d5SCristian Dumitrescu 	}
7795074e1d5SCristian Dumitrescu 
78068b95704SCristian Dumitrescu 	ctl = rte_swx_ctl_pipeline_create(p);
78168b95704SCristian Dumitrescu 	if (!ctl) {
7825074e1d5SCristian Dumitrescu 		snprintf(out, out_size, "Pipeline control create failed.");
78368b95704SCristian Dumitrescu 		goto free;
7845074e1d5SCristian Dumitrescu 	}
78568b95704SCristian Dumitrescu 
78668b95704SCristian Dumitrescu free:
78768b95704SCristian Dumitrescu 	if (status)
78868b95704SCristian Dumitrescu 		rte_swx_pipeline_free(p);
78968b95704SCristian Dumitrescu 
79068b95704SCristian Dumitrescu 	if (iospec_file)
79168b95704SCristian Dumitrescu 		fclose(iospec_file);
7925074e1d5SCristian Dumitrescu }
7935074e1d5SCristian Dumitrescu 
79475129cebSChurchill Khangar static int
79575129cebSChurchill Khangar pipeline_table_entries_add(struct rte_swx_ctl_pipeline *p,
79675129cebSChurchill Khangar 			   const char *table_name,
79775129cebSChurchill Khangar 			   FILE *file,
79875129cebSChurchill Khangar 			   uint32_t *file_line_number)
79975129cebSChurchill Khangar {
80075129cebSChurchill Khangar 	char *line = NULL;
80175129cebSChurchill Khangar 	uint32_t line_id = 0;
80275129cebSChurchill Khangar 	int status = 0;
80375129cebSChurchill Khangar 
80475129cebSChurchill Khangar 	/* Buffer allocation. */
80575129cebSChurchill Khangar 	line = malloc(MAX_LINE_SIZE);
80675129cebSChurchill Khangar 	if (!line)
80775129cebSChurchill Khangar 		return -ENOMEM;
80875129cebSChurchill Khangar 
80975129cebSChurchill Khangar 	/* File read. */
81075129cebSChurchill Khangar 	for (line_id = 1; ; line_id++) {
81175129cebSChurchill Khangar 		struct rte_swx_table_entry *entry;
81275129cebSChurchill Khangar 		int is_blank_or_comment;
81375129cebSChurchill Khangar 
81475129cebSChurchill Khangar 		if (fgets(line, MAX_LINE_SIZE, file) == NULL)
81575129cebSChurchill Khangar 			break;
81675129cebSChurchill Khangar 
81775129cebSChurchill Khangar 		entry = rte_swx_ctl_pipeline_table_entry_read(p,
81875129cebSChurchill Khangar 							      table_name,
81975129cebSChurchill Khangar 							      line,
82075129cebSChurchill Khangar 							      &is_blank_or_comment);
82175129cebSChurchill Khangar 		if (!entry) {
82275129cebSChurchill Khangar 			if (is_blank_or_comment)
82375129cebSChurchill Khangar 				continue;
82475129cebSChurchill Khangar 
82575129cebSChurchill Khangar 			status = -EINVAL;
82675129cebSChurchill Khangar 			goto error;
82775129cebSChurchill Khangar 		}
82875129cebSChurchill Khangar 
82975129cebSChurchill Khangar 		status = rte_swx_ctl_pipeline_table_entry_add(p,
83075129cebSChurchill Khangar 							      table_name,
83175129cebSChurchill Khangar 							      entry);
83275129cebSChurchill Khangar 		table_entry_free(entry);
83375129cebSChurchill Khangar 		if (status)
83475129cebSChurchill Khangar 			goto error;
83575129cebSChurchill Khangar 	}
83675129cebSChurchill Khangar 
83775129cebSChurchill Khangar error:
83875129cebSChurchill Khangar 	free(line);
83975129cebSChurchill Khangar 	*file_line_number = line_id;
84075129cebSChurchill Khangar 	return status;
84175129cebSChurchill Khangar }
84275129cebSChurchill Khangar 
84375129cebSChurchill Khangar static const char cmd_pipeline_table_add_help[] =
84475129cebSChurchill Khangar "pipeline <pipeline_name> table <table_name> add <file_name>\n";
8455074e1d5SCristian Dumitrescu 
8465074e1d5SCristian Dumitrescu static void
84775129cebSChurchill Khangar cmd_pipeline_table_add(char **tokens,
8485074e1d5SCristian Dumitrescu 		       uint32_t n_tokens,
8495074e1d5SCristian Dumitrescu 		       char *out,
8505074e1d5SCristian Dumitrescu 		       size_t out_size,
851b9559f94SCristian Dumitrescu 		       void *obj __rte_unused)
8525074e1d5SCristian Dumitrescu {
853b9559f94SCristian Dumitrescu 	struct rte_swx_ctl_pipeline *ctl;
85475129cebSChurchill Khangar 	char *pipeline_name, *table_name, *file_name;
85575129cebSChurchill Khangar 	FILE *file = NULL;
85675129cebSChurchill Khangar 	uint32_t file_line_number = 0;
8575074e1d5SCristian Dumitrescu 	int status;
8585074e1d5SCristian Dumitrescu 
85975129cebSChurchill Khangar 	if (n_tokens != 6) {
8605074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
8615074e1d5SCristian Dumitrescu 		return;
8625074e1d5SCristian Dumitrescu 	}
8635074e1d5SCristian Dumitrescu 
8645074e1d5SCristian Dumitrescu 	pipeline_name = tokens[1];
865b9559f94SCristian Dumitrescu 	ctl = rte_swx_ctl_pipeline_find(pipeline_name);
866b9559f94SCristian Dumitrescu 	if (!ctl) {
8675074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
8685074e1d5SCristian Dumitrescu 		return;
8695074e1d5SCristian Dumitrescu 	}
8705074e1d5SCristian Dumitrescu 
87175129cebSChurchill Khangar 	table_name = tokens[3];
87275129cebSChurchill Khangar 
87375129cebSChurchill Khangar 	file_name = tokens[5];
87475129cebSChurchill Khangar 	file = fopen(file_name, "r");
87575129cebSChurchill Khangar 	if (!file) {
87675129cebSChurchill Khangar 		snprintf(out, out_size, "Cannot open file %s.\n", file_name);
87775129cebSChurchill Khangar 		return;
87875129cebSChurchill Khangar 	}
87975129cebSChurchill Khangar 
880b9559f94SCristian Dumitrescu 	status = pipeline_table_entries_add(ctl,
88175129cebSChurchill Khangar 					    table_name,
88275129cebSChurchill Khangar 					    file,
88375129cebSChurchill Khangar 					    &file_line_number);
88475129cebSChurchill Khangar 	if (status)
88575129cebSChurchill Khangar 		snprintf(out, out_size, "Invalid entry in file %s at line %u\n",
88675129cebSChurchill Khangar 			 file_name,
88775129cebSChurchill Khangar 			 file_line_number);
88875129cebSChurchill Khangar 
88975129cebSChurchill Khangar 	fclose(file);
89075129cebSChurchill Khangar }
89175129cebSChurchill Khangar 
89275129cebSChurchill Khangar static int
89375129cebSChurchill Khangar pipeline_table_entries_delete(struct rte_swx_ctl_pipeline *p,
89475129cebSChurchill Khangar 			      const char *table_name,
89575129cebSChurchill Khangar 			      FILE *file,
89675129cebSChurchill Khangar 			      uint32_t *file_line_number)
89775129cebSChurchill Khangar {
89875129cebSChurchill Khangar 	char *line = NULL;
89975129cebSChurchill Khangar 	uint32_t line_id = 0;
90075129cebSChurchill Khangar 	int status = 0;
90175129cebSChurchill Khangar 
90275129cebSChurchill Khangar 	/* Buffer allocation. */
90375129cebSChurchill Khangar 	line = malloc(MAX_LINE_SIZE);
90475129cebSChurchill Khangar 	if (!line)
90575129cebSChurchill Khangar 		return -ENOMEM;
90675129cebSChurchill Khangar 
90775129cebSChurchill Khangar 	/* File read. */
90875129cebSChurchill Khangar 	for (line_id = 1; ; line_id++) {
90975129cebSChurchill Khangar 		struct rte_swx_table_entry *entry;
91075129cebSChurchill Khangar 		int is_blank_or_comment;
91175129cebSChurchill Khangar 
91275129cebSChurchill Khangar 		if (fgets(line, MAX_LINE_SIZE, file) == NULL)
91375129cebSChurchill Khangar 			break;
91475129cebSChurchill Khangar 
91575129cebSChurchill Khangar 		entry = rte_swx_ctl_pipeline_table_entry_read(p,
91675129cebSChurchill Khangar 							      table_name,
91775129cebSChurchill Khangar 							      line,
91875129cebSChurchill Khangar 							      &is_blank_or_comment);
91975129cebSChurchill Khangar 		if (!entry) {
92075129cebSChurchill Khangar 			if (is_blank_or_comment)
92175129cebSChurchill Khangar 				continue;
92275129cebSChurchill Khangar 
92375129cebSChurchill Khangar 			status = -EINVAL;
92475129cebSChurchill Khangar 			goto error;
92575129cebSChurchill Khangar 		}
92675129cebSChurchill Khangar 
92775129cebSChurchill Khangar 		status = rte_swx_ctl_pipeline_table_entry_delete(p,
92875129cebSChurchill Khangar 								 table_name,
92975129cebSChurchill Khangar 								 entry);
93075129cebSChurchill Khangar 		table_entry_free(entry);
93175129cebSChurchill Khangar 		if (status)
93275129cebSChurchill Khangar 			goto error;
93375129cebSChurchill Khangar 	}
93475129cebSChurchill Khangar 
93575129cebSChurchill Khangar error:
93675129cebSChurchill Khangar 	*file_line_number = line_id;
93775129cebSChurchill Khangar 	free(line);
93875129cebSChurchill Khangar 	return status;
93975129cebSChurchill Khangar }
94075129cebSChurchill Khangar 
94175129cebSChurchill Khangar static const char cmd_pipeline_table_delete_help[] =
94275129cebSChurchill Khangar "pipeline <pipeline_name> table <table_name> delete <file_name>\n";
94375129cebSChurchill Khangar 
94475129cebSChurchill Khangar static void
94575129cebSChurchill Khangar cmd_pipeline_table_delete(char **tokens,
94675129cebSChurchill Khangar 			  uint32_t n_tokens,
94775129cebSChurchill Khangar 			  char *out,
94875129cebSChurchill Khangar 			  size_t out_size,
949b9559f94SCristian Dumitrescu 			  void *obj __rte_unused)
95075129cebSChurchill Khangar {
951b9559f94SCristian Dumitrescu 	struct rte_swx_ctl_pipeline *ctl;
95275129cebSChurchill Khangar 	char *pipeline_name, *table_name, *file_name;
95375129cebSChurchill Khangar 	FILE *file = NULL;
95475129cebSChurchill Khangar 	uint32_t file_line_number = 0;
95575129cebSChurchill Khangar 	int status;
95675129cebSChurchill Khangar 
95775129cebSChurchill Khangar 	if (n_tokens != 6) {
95875129cebSChurchill Khangar 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
95975129cebSChurchill Khangar 		return;
96075129cebSChurchill Khangar 	}
96175129cebSChurchill Khangar 
96275129cebSChurchill Khangar 	pipeline_name = tokens[1];
963b9559f94SCristian Dumitrescu 	ctl = rte_swx_ctl_pipeline_find(pipeline_name);
964b9559f94SCristian Dumitrescu 	if (!ctl) {
96575129cebSChurchill Khangar 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
9665074e1d5SCristian Dumitrescu 		return;
9675074e1d5SCristian Dumitrescu 	}
9685074e1d5SCristian Dumitrescu 
9695074e1d5SCristian Dumitrescu 	table_name = tokens[3];
9705074e1d5SCristian Dumitrescu 
97175129cebSChurchill Khangar 	file_name = tokens[5];
97275129cebSChurchill Khangar 	file = fopen(file_name, "r");
97375129cebSChurchill Khangar 	if (!file) {
97475129cebSChurchill Khangar 		snprintf(out, out_size, "Cannot open file %s.\n", file_name);
9755074e1d5SCristian Dumitrescu 		return;
9765074e1d5SCristian Dumitrescu 	}
9775074e1d5SCristian Dumitrescu 
978b9559f94SCristian Dumitrescu 	status = pipeline_table_entries_delete(ctl,
97975129cebSChurchill Khangar 					       table_name,
98075129cebSChurchill Khangar 					       file,
98175129cebSChurchill Khangar 					       &file_line_number);
98275129cebSChurchill Khangar 	if (status)
98375129cebSChurchill Khangar 		snprintf(out, out_size, "Invalid entry in file %s at line %u\n",
98475129cebSChurchill Khangar 			 file_name,
98575129cebSChurchill Khangar 			 file_line_number);
9865074e1d5SCristian Dumitrescu 
98775129cebSChurchill Khangar 	fclose(file);
9885074e1d5SCristian Dumitrescu }
9895074e1d5SCristian Dumitrescu 
99075129cebSChurchill Khangar static int
99175129cebSChurchill Khangar pipeline_table_default_entry_add(struct rte_swx_ctl_pipeline *p,
99275129cebSChurchill Khangar 				 const char *table_name,
99375129cebSChurchill Khangar 				 FILE *file,
99475129cebSChurchill Khangar 				 uint32_t *file_line_number)
99575129cebSChurchill Khangar {
99675129cebSChurchill Khangar 	char *line = NULL;
99775129cebSChurchill Khangar 	uint32_t line_id = 0;
99875129cebSChurchill Khangar 	int status = 0;
9995074e1d5SCristian Dumitrescu 
10005074e1d5SCristian Dumitrescu 	/* Buffer allocation. */
100175129cebSChurchill Khangar 	line = malloc(MAX_LINE_SIZE);
100275129cebSChurchill Khangar 	if (!line)
100375129cebSChurchill Khangar 		return -ENOMEM;
10045074e1d5SCristian Dumitrescu 
100575129cebSChurchill Khangar 	/* File read. */
10065074e1d5SCristian Dumitrescu 	for (line_id = 1; ; line_id++) {
10075074e1d5SCristian Dumitrescu 		struct rte_swx_table_entry *entry;
1008cff9a717SCristian Dumitrescu 		int is_blank_or_comment;
10095074e1d5SCristian Dumitrescu 
101075129cebSChurchill Khangar 		if (fgets(line, MAX_LINE_SIZE, file) == NULL)
10115074e1d5SCristian Dumitrescu 			break;
10125074e1d5SCristian Dumitrescu 
101375129cebSChurchill Khangar 		entry = rte_swx_ctl_pipeline_table_entry_read(p,
10145074e1d5SCristian Dumitrescu 							      table_name,
1015cff9a717SCristian Dumitrescu 							      line,
1016cff9a717SCristian Dumitrescu 							      &is_blank_or_comment);
10175074e1d5SCristian Dumitrescu 		if (!entry) {
1018cff9a717SCristian Dumitrescu 			if (is_blank_or_comment)
1019cff9a717SCristian Dumitrescu 				continue;
1020cff9a717SCristian Dumitrescu 
102175129cebSChurchill Khangar 			status = -EINVAL;
10225074e1d5SCristian Dumitrescu 			goto error;
10235074e1d5SCristian Dumitrescu 		}
10245074e1d5SCristian Dumitrescu 
102575129cebSChurchill Khangar 		status = rte_swx_ctl_pipeline_table_default_entry_add(p,
10265074e1d5SCristian Dumitrescu 								      table_name,
10275074e1d5SCristian Dumitrescu 								      entry);
1028275ebefeSCristian Dumitrescu 		table_entry_free(entry);
102975129cebSChurchill Khangar 		if (status)
10305074e1d5SCristian Dumitrescu 			goto error;
10315074e1d5SCristian Dumitrescu 	}
103275129cebSChurchill Khangar 
103375129cebSChurchill Khangar error:
103475129cebSChurchill Khangar 	*file_line_number = line_id;
103575129cebSChurchill Khangar 	free(line);
103675129cebSChurchill Khangar 	return status;
10375074e1d5SCristian Dumitrescu }
10385074e1d5SCristian Dumitrescu 
103975129cebSChurchill Khangar static const char cmd_pipeline_table_default_help[] =
104075129cebSChurchill Khangar "pipeline <pipeline_name> table <table_name> default <file_name>\n";
10415074e1d5SCristian Dumitrescu 
104275129cebSChurchill Khangar static void
104375129cebSChurchill Khangar cmd_pipeline_table_default(char **tokens,
104475129cebSChurchill Khangar 			   uint32_t n_tokens,
104575129cebSChurchill Khangar 			   char *out,
104675129cebSChurchill Khangar 			   size_t out_size,
1047b9559f94SCristian Dumitrescu 			   void *obj __rte_unused)
104875129cebSChurchill Khangar {
1049b9559f94SCristian Dumitrescu 	struct rte_swx_ctl_pipeline *ctl;
105075129cebSChurchill Khangar 	char *pipeline_name, *table_name, *file_name;
105175129cebSChurchill Khangar 	FILE *file = NULL;
105275129cebSChurchill Khangar 	uint32_t file_line_number = 0;
105375129cebSChurchill Khangar 	int status;
10545074e1d5SCristian Dumitrescu 
105575129cebSChurchill Khangar 	if (n_tokens != 6) {
105675129cebSChurchill Khangar 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
105775129cebSChurchill Khangar 		return;
105875129cebSChurchill Khangar 	}
10595074e1d5SCristian Dumitrescu 
106075129cebSChurchill Khangar 	pipeline_name = tokens[1];
1061b9559f94SCristian Dumitrescu 	ctl = rte_swx_ctl_pipeline_find(pipeline_name);
1062b9559f94SCristian Dumitrescu 	if (!ctl) {
106375129cebSChurchill Khangar 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
106475129cebSChurchill Khangar 		return;
106575129cebSChurchill Khangar 	}
106675129cebSChurchill Khangar 
106775129cebSChurchill Khangar 	table_name = tokens[3];
106875129cebSChurchill Khangar 
106975129cebSChurchill Khangar 	file_name = tokens[5];
107075129cebSChurchill Khangar 	file = fopen(file_name, "r");
107175129cebSChurchill Khangar 	if (!file) {
107275129cebSChurchill Khangar 		snprintf(out, out_size, "Cannot open file %s.\n", file_name);
107375129cebSChurchill Khangar 		return;
107475129cebSChurchill Khangar 	}
107575129cebSChurchill Khangar 
1076b9559f94SCristian Dumitrescu 	status = pipeline_table_default_entry_add(ctl,
10775074e1d5SCristian Dumitrescu 						  table_name,
107875129cebSChurchill Khangar 						  file,
107975129cebSChurchill Khangar 						  &file_line_number);
108075129cebSChurchill Khangar 	if (status)
108175129cebSChurchill Khangar 		snprintf(out, out_size, "Invalid entry in file %s at line %u\n",
108275129cebSChurchill Khangar 			 file_name,
108375129cebSChurchill Khangar 			 file_line_number);
1084cff9a717SCristian Dumitrescu 
108575129cebSChurchill Khangar 	fclose(file);
10865074e1d5SCristian Dumitrescu }
10875074e1d5SCristian Dumitrescu 
108875129cebSChurchill Khangar static const char cmd_pipeline_table_show_help[] =
1089a4c1146cSCristian Dumitrescu "pipeline <pipeline_name> table <table_name> show [filename]\n";
109075129cebSChurchill Khangar 
109175129cebSChurchill Khangar static void
109275129cebSChurchill Khangar cmd_pipeline_table_show(char **tokens,
109375129cebSChurchill Khangar 	uint32_t n_tokens,
109475129cebSChurchill Khangar 	char *out,
109575129cebSChurchill Khangar 	size_t out_size,
1096b9559f94SCristian Dumitrescu 	void *obj __rte_unused)
109775129cebSChurchill Khangar {
1098b9559f94SCristian Dumitrescu 	struct rte_swx_ctl_pipeline *ctl;
109975129cebSChurchill Khangar 	char *pipeline_name, *table_name;
1100a4c1146cSCristian Dumitrescu 	FILE *file = NULL;
110175129cebSChurchill Khangar 	int status;
110275129cebSChurchill Khangar 
1103a4c1146cSCristian Dumitrescu 	if (n_tokens != 5 && n_tokens != 6) {
110475129cebSChurchill Khangar 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
110575129cebSChurchill Khangar 		return;
11065074e1d5SCristian Dumitrescu 	}
11075074e1d5SCristian Dumitrescu 
110875129cebSChurchill Khangar 	pipeline_name = tokens[1];
1109b9559f94SCristian Dumitrescu 	ctl = rte_swx_ctl_pipeline_find(pipeline_name);
1110b9559f94SCristian Dumitrescu 	if (!ctl) {
111175129cebSChurchill Khangar 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
111275129cebSChurchill Khangar 		return;
11135074e1d5SCristian Dumitrescu 	}
11145074e1d5SCristian Dumitrescu 
111575129cebSChurchill Khangar 	table_name = tokens[3];
1116a4c1146cSCristian Dumitrescu 	file = (n_tokens == 6) ? fopen(tokens[5], "w") : stdout;
1117a4c1146cSCristian Dumitrescu 	if (!file) {
1118a4c1146cSCristian Dumitrescu 		snprintf(out, out_size, "Cannot open file %s.\n", tokens[5]);
1119a4c1146cSCristian Dumitrescu 		return;
1120a4c1146cSCristian Dumitrescu 	}
1121a4c1146cSCristian Dumitrescu 
1122b9559f94SCristian Dumitrescu 	status = rte_swx_ctl_pipeline_table_fprintf(file, ctl, table_name);
112375129cebSChurchill Khangar 	if (status)
112475129cebSChurchill Khangar 		snprintf(out, out_size, MSG_ARG_INVALID, "table_name");
1125a4c1146cSCristian Dumitrescu 
1126a4c1146cSCristian Dumitrescu 	if (file)
1127a4c1146cSCristian Dumitrescu 		fclose(file);
11285074e1d5SCristian Dumitrescu }
112975129cebSChurchill Khangar 
1130598fe0ddSCristian Dumitrescu static const char cmd_pipeline_selector_group_add_help[] =
1131598fe0ddSCristian Dumitrescu "pipeline <pipeline_name> selector <selector_name> group add\n";
1132598fe0ddSCristian Dumitrescu 
1133598fe0ddSCristian Dumitrescu static void
1134598fe0ddSCristian Dumitrescu cmd_pipeline_selector_group_add(char **tokens,
1135598fe0ddSCristian Dumitrescu 	uint32_t n_tokens,
1136598fe0ddSCristian Dumitrescu 	char *out,
1137598fe0ddSCristian Dumitrescu 	size_t out_size,
1138b9559f94SCristian Dumitrescu 	void *obj __rte_unused)
1139598fe0ddSCristian Dumitrescu {
1140b9559f94SCristian Dumitrescu 	struct rte_swx_ctl_pipeline *ctl;
1141598fe0ddSCristian Dumitrescu 	char *pipeline_name, *selector_name;
1142598fe0ddSCristian Dumitrescu 	uint32_t group_id;
1143598fe0ddSCristian Dumitrescu 	int status;
1144598fe0ddSCristian Dumitrescu 
1145598fe0ddSCristian Dumitrescu 	if (n_tokens != 6) {
1146598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1147598fe0ddSCristian Dumitrescu 		return;
1148598fe0ddSCristian Dumitrescu 	}
1149598fe0ddSCristian Dumitrescu 
1150598fe0ddSCristian Dumitrescu 	pipeline_name = tokens[1];
1151b9559f94SCristian Dumitrescu 	ctl = rte_swx_ctl_pipeline_find(pipeline_name);
1152b9559f94SCristian Dumitrescu 	if (!ctl) {
1153598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
1154598fe0ddSCristian Dumitrescu 		return;
1155598fe0ddSCristian Dumitrescu 	}
1156598fe0ddSCristian Dumitrescu 
1157598fe0ddSCristian Dumitrescu 	if (strcmp(tokens[2], "selector") != 0) {
1158598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "selector");
1159598fe0ddSCristian Dumitrescu 		return;
1160598fe0ddSCristian Dumitrescu 	}
1161598fe0ddSCristian Dumitrescu 
1162598fe0ddSCristian Dumitrescu 	selector_name = tokens[3];
1163598fe0ddSCristian Dumitrescu 
1164598fe0ddSCristian Dumitrescu 	if (strcmp(tokens[4], "group") ||
1165598fe0ddSCristian Dumitrescu 		strcmp(tokens[5], "add")) {
1166598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "group add");
1167598fe0ddSCristian Dumitrescu 		return;
1168598fe0ddSCristian Dumitrescu 	}
1169598fe0ddSCristian Dumitrescu 
1170b9559f94SCristian Dumitrescu 	status = rte_swx_ctl_pipeline_selector_group_add(ctl,
1171598fe0ddSCristian Dumitrescu 		selector_name,
1172598fe0ddSCristian Dumitrescu 		&group_id);
1173598fe0ddSCristian Dumitrescu 	if (status)
1174598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
1175598fe0ddSCristian Dumitrescu 	else
1176598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, "Group ID: %u\n", group_id);
1177598fe0ddSCristian Dumitrescu }
1178598fe0ddSCristian Dumitrescu 
1179598fe0ddSCristian Dumitrescu static const char cmd_pipeline_selector_group_delete_help[] =
1180598fe0ddSCristian Dumitrescu "pipeline <pipeline_name> selector <selector_name> group delete <group_id>\n";
1181598fe0ddSCristian Dumitrescu 
1182598fe0ddSCristian Dumitrescu static void
1183598fe0ddSCristian Dumitrescu cmd_pipeline_selector_group_delete(char **tokens,
1184598fe0ddSCristian Dumitrescu 	uint32_t n_tokens,
1185598fe0ddSCristian Dumitrescu 	char *out,
1186598fe0ddSCristian Dumitrescu 	size_t out_size,
1187b9559f94SCristian Dumitrescu 	void *obj __rte_unused)
1188598fe0ddSCristian Dumitrescu {
1189b9559f94SCristian Dumitrescu 	struct rte_swx_ctl_pipeline *ctl;
1190598fe0ddSCristian Dumitrescu 	char *pipeline_name, *selector_name;
1191598fe0ddSCristian Dumitrescu 	uint32_t group_id;
1192598fe0ddSCristian Dumitrescu 	int status;
1193598fe0ddSCristian Dumitrescu 
1194598fe0ddSCristian Dumitrescu 	if (n_tokens != 7) {
1195598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1196598fe0ddSCristian Dumitrescu 		return;
1197598fe0ddSCristian Dumitrescu 	}
1198598fe0ddSCristian Dumitrescu 
1199598fe0ddSCristian Dumitrescu 	pipeline_name = tokens[1];
1200b9559f94SCristian Dumitrescu 	ctl = rte_swx_ctl_pipeline_find(pipeline_name);
1201b9559f94SCristian Dumitrescu 	if (!ctl) {
1202598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
1203598fe0ddSCristian Dumitrescu 		return;
1204598fe0ddSCristian Dumitrescu 	}
1205598fe0ddSCristian Dumitrescu 
1206598fe0ddSCristian Dumitrescu 	if (strcmp(tokens[2], "selector") != 0) {
1207598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "selector");
1208598fe0ddSCristian Dumitrescu 		return;
1209598fe0ddSCristian Dumitrescu 	}
1210598fe0ddSCristian Dumitrescu 
1211598fe0ddSCristian Dumitrescu 	selector_name = tokens[3];
1212598fe0ddSCristian Dumitrescu 
1213598fe0ddSCristian Dumitrescu 	if (strcmp(tokens[4], "group") ||
1214598fe0ddSCristian Dumitrescu 		strcmp(tokens[5], "delete")) {
1215598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "group delete");
1216598fe0ddSCristian Dumitrescu 		return;
1217598fe0ddSCristian Dumitrescu 	}
1218598fe0ddSCristian Dumitrescu 
1219598fe0ddSCristian Dumitrescu 	if (parser_read_uint32(&group_id, tokens[6]) != 0) {
1220598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "group_id");
1221598fe0ddSCristian Dumitrescu 		return;
1222598fe0ddSCristian Dumitrescu 	}
1223598fe0ddSCristian Dumitrescu 
1224b9559f94SCristian Dumitrescu 	status = rte_swx_ctl_pipeline_selector_group_delete(ctl,
1225598fe0ddSCristian Dumitrescu 		selector_name,
1226598fe0ddSCristian Dumitrescu 		group_id);
1227598fe0ddSCristian Dumitrescu 	if (status)
1228598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
1229598fe0ddSCristian Dumitrescu }
1230598fe0ddSCristian Dumitrescu 
1231598fe0ddSCristian Dumitrescu #define GROUP_MEMBER_INFO_TOKENS_MAX 6
1232598fe0ddSCristian Dumitrescu 
1233598fe0ddSCristian Dumitrescu static int
1234598fe0ddSCristian Dumitrescu token_is_comment(const char *token)
1235598fe0ddSCristian Dumitrescu {
1236598fe0ddSCristian Dumitrescu 	if ((token[0] == '#') ||
1237598fe0ddSCristian Dumitrescu 	    (token[0] == ';') ||
1238598fe0ddSCristian Dumitrescu 	    ((token[0] == '/') && (token[1] == '/')))
1239598fe0ddSCristian Dumitrescu 		return 1; /* TRUE. */
1240598fe0ddSCristian Dumitrescu 
1241598fe0ddSCristian Dumitrescu 	return 0; /* FALSE. */
1242598fe0ddSCristian Dumitrescu }
1243598fe0ddSCristian Dumitrescu 
1244598fe0ddSCristian Dumitrescu static int
1245598fe0ddSCristian Dumitrescu pipeline_selector_group_member_read(const char *string,
1246598fe0ddSCristian Dumitrescu 				      uint32_t *group_id,
1247598fe0ddSCristian Dumitrescu 				      uint32_t *member_id,
1248598fe0ddSCristian Dumitrescu 				      uint32_t *weight,
1249598fe0ddSCristian Dumitrescu 				      int *is_blank_or_comment)
1250598fe0ddSCristian Dumitrescu {
1251598fe0ddSCristian Dumitrescu 	char *token_array[GROUP_MEMBER_INFO_TOKENS_MAX], **tokens;
1252598fe0ddSCristian Dumitrescu 	char *s0 = NULL, *s;
125300b67591SAli Alnubani 	uint32_t n_tokens = 0, group_id_val = 0, member_id_val = 0, weight_val = 0;
1254598fe0ddSCristian Dumitrescu 	int blank_or_comment = 0;
1255598fe0ddSCristian Dumitrescu 
1256598fe0ddSCristian Dumitrescu 	/* Check input arguments. */
1257598fe0ddSCristian Dumitrescu 	if (!string || !string[0])
1258598fe0ddSCristian Dumitrescu 		goto error;
1259598fe0ddSCristian Dumitrescu 
1260598fe0ddSCristian Dumitrescu 	/* Memory allocation. */
1261598fe0ddSCristian Dumitrescu 	s0 = strdup(string);
1262598fe0ddSCristian Dumitrescu 	if (!s0)
1263598fe0ddSCristian Dumitrescu 		goto error;
1264598fe0ddSCristian Dumitrescu 
1265598fe0ddSCristian Dumitrescu 	/* Parse the string into tokens. */
1266598fe0ddSCristian Dumitrescu 	for (s = s0; ; ) {
1267598fe0ddSCristian Dumitrescu 		char *token;
1268598fe0ddSCristian Dumitrescu 
1269598fe0ddSCristian Dumitrescu 		token = strtok_r(s, " \f\n\r\t\v", &s);
1270598fe0ddSCristian Dumitrescu 		if (!token || token_is_comment(token))
1271598fe0ddSCristian Dumitrescu 			break;
1272598fe0ddSCristian Dumitrescu 
1273cfcc7bf8SCristian Dumitrescu 		if (n_tokens >= GROUP_MEMBER_INFO_TOKENS_MAX)
1274598fe0ddSCristian Dumitrescu 			goto error;
1275598fe0ddSCristian Dumitrescu 
1276598fe0ddSCristian Dumitrescu 		token_array[n_tokens] = token;
1277598fe0ddSCristian Dumitrescu 		n_tokens++;
1278598fe0ddSCristian Dumitrescu 	}
1279598fe0ddSCristian Dumitrescu 
1280598fe0ddSCristian Dumitrescu 	if (!n_tokens) {
1281598fe0ddSCristian Dumitrescu 		blank_or_comment = 1;
1282598fe0ddSCristian Dumitrescu 		goto error;
1283598fe0ddSCristian Dumitrescu 	}
1284598fe0ddSCristian Dumitrescu 
1285598fe0ddSCristian Dumitrescu 	tokens = token_array;
1286598fe0ddSCristian Dumitrescu 
1287598fe0ddSCristian Dumitrescu 	if (n_tokens < 4 ||
1288598fe0ddSCristian Dumitrescu 		strcmp(tokens[0], "group") ||
1289598fe0ddSCristian Dumitrescu 		strcmp(tokens[2], "member"))
1290598fe0ddSCristian Dumitrescu 		goto error;
1291598fe0ddSCristian Dumitrescu 
1292598fe0ddSCristian Dumitrescu 	/*
1293598fe0ddSCristian Dumitrescu 	 * Group ID.
1294598fe0ddSCristian Dumitrescu 	 */
1295598fe0ddSCristian Dumitrescu 	if (parser_read_uint32(&group_id_val, tokens[1]) != 0)
1296598fe0ddSCristian Dumitrescu 		goto error;
1297598fe0ddSCristian Dumitrescu 	*group_id = group_id_val;
1298598fe0ddSCristian Dumitrescu 
1299598fe0ddSCristian Dumitrescu 	/*
1300598fe0ddSCristian Dumitrescu 	 * Member ID.
1301598fe0ddSCristian Dumitrescu 	 */
1302598fe0ddSCristian Dumitrescu 	if (parser_read_uint32(&member_id_val, tokens[3]) != 0)
1303598fe0ddSCristian Dumitrescu 		goto error;
1304598fe0ddSCristian Dumitrescu 	*member_id = member_id_val;
1305598fe0ddSCristian Dumitrescu 
1306598fe0ddSCristian Dumitrescu 	tokens += 4;
1307598fe0ddSCristian Dumitrescu 	n_tokens -= 4;
1308598fe0ddSCristian Dumitrescu 
1309598fe0ddSCristian Dumitrescu 	/*
1310598fe0ddSCristian Dumitrescu 	 * Weight.
1311598fe0ddSCristian Dumitrescu 	 */
1312598fe0ddSCristian Dumitrescu 	if (n_tokens && !strcmp(tokens[0], "weight")) {
1313598fe0ddSCristian Dumitrescu 		if (n_tokens < 2)
1314598fe0ddSCristian Dumitrescu 			goto error;
1315598fe0ddSCristian Dumitrescu 
1316598fe0ddSCristian Dumitrescu 		if (parser_read_uint32(&weight_val, tokens[1]) != 0)
1317598fe0ddSCristian Dumitrescu 			goto error;
1318598fe0ddSCristian Dumitrescu 		*weight = weight_val;
1319598fe0ddSCristian Dumitrescu 
1320598fe0ddSCristian Dumitrescu 		tokens += 2;
1321598fe0ddSCristian Dumitrescu 		n_tokens -= 2;
1322598fe0ddSCristian Dumitrescu 	}
1323598fe0ddSCristian Dumitrescu 
1324598fe0ddSCristian Dumitrescu 	if (n_tokens)
1325598fe0ddSCristian Dumitrescu 		goto error;
1326598fe0ddSCristian Dumitrescu 
1327598fe0ddSCristian Dumitrescu 	free(s0);
1328598fe0ddSCristian Dumitrescu 	return 0;
1329598fe0ddSCristian Dumitrescu 
1330598fe0ddSCristian Dumitrescu error:
1331598fe0ddSCristian Dumitrescu 	free(s0);
1332598fe0ddSCristian Dumitrescu 	if (is_blank_or_comment)
1333598fe0ddSCristian Dumitrescu 		*is_blank_or_comment = blank_or_comment;
1334598fe0ddSCristian Dumitrescu 	return -EINVAL;
1335598fe0ddSCristian Dumitrescu }
1336598fe0ddSCristian Dumitrescu 
1337598fe0ddSCristian Dumitrescu static int
1338598fe0ddSCristian Dumitrescu pipeline_selector_group_members_add(struct rte_swx_ctl_pipeline *p,
1339598fe0ddSCristian Dumitrescu 			   const char *selector_name,
1340598fe0ddSCristian Dumitrescu 			   FILE *file,
1341598fe0ddSCristian Dumitrescu 			   uint32_t *file_line_number)
1342598fe0ddSCristian Dumitrescu {
1343598fe0ddSCristian Dumitrescu 	char *line = NULL;
1344598fe0ddSCristian Dumitrescu 	uint32_t line_id = 0;
1345598fe0ddSCristian Dumitrescu 	int status = 0;
1346598fe0ddSCristian Dumitrescu 
1347598fe0ddSCristian Dumitrescu 	/* Buffer allocation. */
1348598fe0ddSCristian Dumitrescu 	line = malloc(MAX_LINE_SIZE);
1349598fe0ddSCristian Dumitrescu 	if (!line)
1350598fe0ddSCristian Dumitrescu 		return -ENOMEM;
1351598fe0ddSCristian Dumitrescu 
1352598fe0ddSCristian Dumitrescu 	/* File read. */
1353598fe0ddSCristian Dumitrescu 	for (line_id = 1; ; line_id++) {
1354598fe0ddSCristian Dumitrescu 		uint32_t group_id, member_id, weight;
1355598fe0ddSCristian Dumitrescu 		int is_blank_or_comment;
1356598fe0ddSCristian Dumitrescu 
1357598fe0ddSCristian Dumitrescu 		if (fgets(line, MAX_LINE_SIZE, file) == NULL)
1358598fe0ddSCristian Dumitrescu 			break;
1359598fe0ddSCristian Dumitrescu 
1360598fe0ddSCristian Dumitrescu 		status = pipeline_selector_group_member_read(line,
1361598fe0ddSCristian Dumitrescu 							      &group_id,
1362598fe0ddSCristian Dumitrescu 							      &member_id,
1363598fe0ddSCristian Dumitrescu 							      &weight,
1364598fe0ddSCristian Dumitrescu 							      &is_blank_or_comment);
1365598fe0ddSCristian Dumitrescu 		if (status) {
1366598fe0ddSCristian Dumitrescu 			if (is_blank_or_comment)
1367598fe0ddSCristian Dumitrescu 				continue;
1368598fe0ddSCristian Dumitrescu 
1369598fe0ddSCristian Dumitrescu 			goto error;
1370598fe0ddSCristian Dumitrescu 		}
1371598fe0ddSCristian Dumitrescu 
1372598fe0ddSCristian Dumitrescu 		status = rte_swx_ctl_pipeline_selector_group_member_add(p,
1373598fe0ddSCristian Dumitrescu 			selector_name,
1374598fe0ddSCristian Dumitrescu 			group_id,
1375598fe0ddSCristian Dumitrescu 			member_id,
1376598fe0ddSCristian Dumitrescu 			weight);
1377598fe0ddSCristian Dumitrescu 		if (status)
1378598fe0ddSCristian Dumitrescu 			goto error;
1379598fe0ddSCristian Dumitrescu 	}
1380598fe0ddSCristian Dumitrescu 
1381598fe0ddSCristian Dumitrescu error:
1382598fe0ddSCristian Dumitrescu 	free(line);
1383598fe0ddSCristian Dumitrescu 	*file_line_number = line_id;
1384598fe0ddSCristian Dumitrescu 	return status;
1385598fe0ddSCristian Dumitrescu }
1386598fe0ddSCristian Dumitrescu 
1387598fe0ddSCristian Dumitrescu static const char cmd_pipeline_selector_group_member_add_help[] =
1388598fe0ddSCristian Dumitrescu "pipeline <pipeline_name> selector <selector_name> group member add <file_name>";
1389598fe0ddSCristian Dumitrescu 
1390598fe0ddSCristian Dumitrescu static void
1391598fe0ddSCristian Dumitrescu cmd_pipeline_selector_group_member_add(char **tokens,
1392598fe0ddSCristian Dumitrescu 	uint32_t n_tokens,
1393598fe0ddSCristian Dumitrescu 	char *out,
1394598fe0ddSCristian Dumitrescu 	size_t out_size,
1395b9559f94SCristian Dumitrescu 	void *obj __rte_unused)
1396598fe0ddSCristian Dumitrescu {
1397b9559f94SCristian Dumitrescu 	struct rte_swx_ctl_pipeline *ctl;
1398598fe0ddSCristian Dumitrescu 	char *pipeline_name, *selector_name, *file_name;
1399598fe0ddSCristian Dumitrescu 	FILE *file = NULL;
1400598fe0ddSCristian Dumitrescu 	uint32_t file_line_number = 0;
1401598fe0ddSCristian Dumitrescu 	int status;
1402598fe0ddSCristian Dumitrescu 
1403598fe0ddSCristian Dumitrescu 	if (n_tokens != 8) {
1404598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1405598fe0ddSCristian Dumitrescu 		return;
1406598fe0ddSCristian Dumitrescu 	}
1407598fe0ddSCristian Dumitrescu 
1408598fe0ddSCristian Dumitrescu 	pipeline_name = tokens[1];
1409b9559f94SCristian Dumitrescu 	ctl = rte_swx_ctl_pipeline_find(pipeline_name);
1410b9559f94SCristian Dumitrescu 	if (!ctl) {
1411598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
1412598fe0ddSCristian Dumitrescu 		return;
1413598fe0ddSCristian Dumitrescu 	}
1414598fe0ddSCristian Dumitrescu 
1415598fe0ddSCristian Dumitrescu 	if (strcmp(tokens[2], "selector") != 0) {
1416598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "selector");
1417598fe0ddSCristian Dumitrescu 		return;
1418598fe0ddSCristian Dumitrescu 	}
1419598fe0ddSCristian Dumitrescu 
1420598fe0ddSCristian Dumitrescu 	selector_name = tokens[3];
1421598fe0ddSCristian Dumitrescu 
1422598fe0ddSCristian Dumitrescu 	if (strcmp(tokens[4], "group") ||
1423598fe0ddSCristian Dumitrescu 		strcmp(tokens[5], "member") ||
1424598fe0ddSCristian Dumitrescu 		strcmp(tokens[6], "add")) {
1425598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "group member add");
1426598fe0ddSCristian Dumitrescu 		return;
1427598fe0ddSCristian Dumitrescu 	}
1428598fe0ddSCristian Dumitrescu 
1429598fe0ddSCristian Dumitrescu 	file_name = tokens[7];
1430598fe0ddSCristian Dumitrescu 	file = fopen(file_name, "r");
1431598fe0ddSCristian Dumitrescu 	if (!file) {
1432598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, "Cannot open file %s.\n", file_name);
1433598fe0ddSCristian Dumitrescu 		return;
1434598fe0ddSCristian Dumitrescu 	}
1435598fe0ddSCristian Dumitrescu 
1436b9559f94SCristian Dumitrescu 	status = pipeline_selector_group_members_add(ctl,
1437598fe0ddSCristian Dumitrescu 					    selector_name,
1438598fe0ddSCristian Dumitrescu 					    file,
1439598fe0ddSCristian Dumitrescu 					    &file_line_number);
1440598fe0ddSCristian Dumitrescu 	if (status)
1441598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, "Invalid entry in file %s at line %u\n",
1442598fe0ddSCristian Dumitrescu 			 file_name,
1443598fe0ddSCristian Dumitrescu 			 file_line_number);
1444598fe0ddSCristian Dumitrescu 
1445598fe0ddSCristian Dumitrescu 	fclose(file);
1446598fe0ddSCristian Dumitrescu }
1447598fe0ddSCristian Dumitrescu 
1448598fe0ddSCristian Dumitrescu static int
1449598fe0ddSCristian Dumitrescu pipeline_selector_group_members_delete(struct rte_swx_ctl_pipeline *p,
1450598fe0ddSCristian Dumitrescu 			   const char *selector_name,
1451598fe0ddSCristian Dumitrescu 			   FILE *file,
1452598fe0ddSCristian Dumitrescu 			   uint32_t *file_line_number)
1453598fe0ddSCristian Dumitrescu {
1454598fe0ddSCristian Dumitrescu 	char *line = NULL;
1455598fe0ddSCristian Dumitrescu 	uint32_t line_id = 0;
1456598fe0ddSCristian Dumitrescu 	int status = 0;
1457598fe0ddSCristian Dumitrescu 
1458598fe0ddSCristian Dumitrescu 	/* Buffer allocation. */
1459598fe0ddSCristian Dumitrescu 	line = malloc(MAX_LINE_SIZE);
1460598fe0ddSCristian Dumitrescu 	if (!line)
1461598fe0ddSCristian Dumitrescu 		return -ENOMEM;
1462598fe0ddSCristian Dumitrescu 
1463598fe0ddSCristian Dumitrescu 	/* File read. */
1464598fe0ddSCristian Dumitrescu 	for (line_id = 1; ; line_id++) {
1465598fe0ddSCristian Dumitrescu 		uint32_t group_id, member_id, weight;
1466598fe0ddSCristian Dumitrescu 		int is_blank_or_comment;
1467598fe0ddSCristian Dumitrescu 
1468598fe0ddSCristian Dumitrescu 		if (fgets(line, MAX_LINE_SIZE, file) == NULL)
1469598fe0ddSCristian Dumitrescu 			break;
1470598fe0ddSCristian Dumitrescu 
1471598fe0ddSCristian Dumitrescu 		status = pipeline_selector_group_member_read(line,
1472598fe0ddSCristian Dumitrescu 							      &group_id,
1473598fe0ddSCristian Dumitrescu 							      &member_id,
1474598fe0ddSCristian Dumitrescu 							      &weight,
1475598fe0ddSCristian Dumitrescu 							      &is_blank_or_comment);
1476598fe0ddSCristian Dumitrescu 		if (status) {
1477598fe0ddSCristian Dumitrescu 			if (is_blank_or_comment)
1478598fe0ddSCristian Dumitrescu 				continue;
1479598fe0ddSCristian Dumitrescu 
1480598fe0ddSCristian Dumitrescu 			goto error;
1481598fe0ddSCristian Dumitrescu 		}
1482598fe0ddSCristian Dumitrescu 
1483598fe0ddSCristian Dumitrescu 		status = rte_swx_ctl_pipeline_selector_group_member_delete(p,
1484598fe0ddSCristian Dumitrescu 			selector_name,
1485598fe0ddSCristian Dumitrescu 			group_id,
1486598fe0ddSCristian Dumitrescu 			member_id);
1487598fe0ddSCristian Dumitrescu 		if (status)
1488598fe0ddSCristian Dumitrescu 			goto error;
1489598fe0ddSCristian Dumitrescu 	}
1490598fe0ddSCristian Dumitrescu 
1491598fe0ddSCristian Dumitrescu error:
1492598fe0ddSCristian Dumitrescu 	free(line);
1493598fe0ddSCristian Dumitrescu 	*file_line_number = line_id;
1494598fe0ddSCristian Dumitrescu 	return status;
1495598fe0ddSCristian Dumitrescu }
1496598fe0ddSCristian Dumitrescu 
1497598fe0ddSCristian Dumitrescu static const char cmd_pipeline_selector_group_member_delete_help[] =
1498598fe0ddSCristian Dumitrescu "pipeline <pipeline_name> selector <selector_name> group member delete <file_name>";
1499598fe0ddSCristian Dumitrescu 
1500598fe0ddSCristian Dumitrescu static void
1501598fe0ddSCristian Dumitrescu cmd_pipeline_selector_group_member_delete(char **tokens,
1502598fe0ddSCristian Dumitrescu 	uint32_t n_tokens,
1503598fe0ddSCristian Dumitrescu 	char *out,
1504598fe0ddSCristian Dumitrescu 	size_t out_size,
1505b9559f94SCristian Dumitrescu 	void *obj __rte_unused)
1506598fe0ddSCristian Dumitrescu {
1507b9559f94SCristian Dumitrescu 	struct rte_swx_ctl_pipeline *ctl;
1508598fe0ddSCristian Dumitrescu 	char *pipeline_name, *selector_name, *file_name;
1509598fe0ddSCristian Dumitrescu 	FILE *file = NULL;
1510598fe0ddSCristian Dumitrescu 	uint32_t file_line_number = 0;
1511598fe0ddSCristian Dumitrescu 	int status;
1512598fe0ddSCristian Dumitrescu 
1513598fe0ddSCristian Dumitrescu 	if (n_tokens != 8) {
1514598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1515598fe0ddSCristian Dumitrescu 		return;
1516598fe0ddSCristian Dumitrescu 	}
1517598fe0ddSCristian Dumitrescu 
1518598fe0ddSCristian Dumitrescu 	pipeline_name = tokens[1];
1519b9559f94SCristian Dumitrescu 	ctl = rte_swx_ctl_pipeline_find(pipeline_name);
1520b9559f94SCristian Dumitrescu 	if (!ctl) {
1521598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
1522598fe0ddSCristian Dumitrescu 		return;
1523598fe0ddSCristian Dumitrescu 	}
1524598fe0ddSCristian Dumitrescu 
1525598fe0ddSCristian Dumitrescu 	if (strcmp(tokens[2], "selector") != 0) {
1526598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "selector");
1527598fe0ddSCristian Dumitrescu 		return;
1528598fe0ddSCristian Dumitrescu 	}
1529598fe0ddSCristian Dumitrescu 
1530598fe0ddSCristian Dumitrescu 	selector_name = tokens[3];
1531598fe0ddSCristian Dumitrescu 
1532598fe0ddSCristian Dumitrescu 	if (strcmp(tokens[4], "group") ||
1533598fe0ddSCristian Dumitrescu 		strcmp(tokens[5], "member") ||
1534598fe0ddSCristian Dumitrescu 		strcmp(tokens[6], "delete")) {
1535598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "group member delete");
1536598fe0ddSCristian Dumitrescu 		return;
1537598fe0ddSCristian Dumitrescu 	}
1538598fe0ddSCristian Dumitrescu 
1539598fe0ddSCristian Dumitrescu 	file_name = tokens[7];
1540598fe0ddSCristian Dumitrescu 	file = fopen(file_name, "r");
1541598fe0ddSCristian Dumitrescu 	if (!file) {
1542598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, "Cannot open file %s.\n", file_name);
1543598fe0ddSCristian Dumitrescu 		return;
1544598fe0ddSCristian Dumitrescu 	}
1545598fe0ddSCristian Dumitrescu 
1546b9559f94SCristian Dumitrescu 	status = pipeline_selector_group_members_delete(ctl,
1547598fe0ddSCristian Dumitrescu 					    selector_name,
1548598fe0ddSCristian Dumitrescu 					    file,
1549598fe0ddSCristian Dumitrescu 					    &file_line_number);
1550598fe0ddSCristian Dumitrescu 	if (status)
1551598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, "Invalid entry in file %s at line %u\n",
1552598fe0ddSCristian Dumitrescu 			 file_name,
1553598fe0ddSCristian Dumitrescu 			 file_line_number);
1554598fe0ddSCristian Dumitrescu 
1555598fe0ddSCristian Dumitrescu 	fclose(file);
1556598fe0ddSCristian Dumitrescu }
1557598fe0ddSCristian Dumitrescu 
1558598fe0ddSCristian Dumitrescu static const char cmd_pipeline_selector_show_help[] =
1559a4c1146cSCristian Dumitrescu "pipeline <pipeline_name> selector <selector_name> show [filename]\n";
1560598fe0ddSCristian Dumitrescu 
1561598fe0ddSCristian Dumitrescu static void
1562598fe0ddSCristian Dumitrescu cmd_pipeline_selector_show(char **tokens,
1563598fe0ddSCristian Dumitrescu 	uint32_t n_tokens,
1564598fe0ddSCristian Dumitrescu 	char *out,
1565598fe0ddSCristian Dumitrescu 	size_t out_size,
1566b9559f94SCristian Dumitrescu 	void *obj __rte_unused)
1567598fe0ddSCristian Dumitrescu {
1568b9559f94SCristian Dumitrescu 	struct rte_swx_ctl_pipeline *ctl;
1569598fe0ddSCristian Dumitrescu 	char *pipeline_name, *selector_name;
1570a4c1146cSCristian Dumitrescu 	FILE *file = NULL;
1571598fe0ddSCristian Dumitrescu 	int status;
1572598fe0ddSCristian Dumitrescu 
1573a4c1146cSCristian Dumitrescu 	if (n_tokens != 5 && n_tokens != 6) {
1574598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1575598fe0ddSCristian Dumitrescu 		return;
1576598fe0ddSCristian Dumitrescu 	}
1577598fe0ddSCristian Dumitrescu 
1578598fe0ddSCristian Dumitrescu 	pipeline_name = tokens[1];
1579b9559f94SCristian Dumitrescu 	ctl = rte_swx_ctl_pipeline_find(pipeline_name);
1580b9559f94SCristian Dumitrescu 	if (!ctl) {
1581598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
1582598fe0ddSCristian Dumitrescu 		return;
1583598fe0ddSCristian Dumitrescu 	}
1584598fe0ddSCristian Dumitrescu 
1585598fe0ddSCristian Dumitrescu 	selector_name = tokens[3];
1586a4c1146cSCristian Dumitrescu 
1587a4c1146cSCristian Dumitrescu 	file = (n_tokens == 6) ? fopen(tokens[5], "w") : stdout;
1588a4c1146cSCristian Dumitrescu 	if (!file) {
1589a4c1146cSCristian Dumitrescu 		snprintf(out, out_size, "Cannot open file %s.\n", tokens[5]);
1590a4c1146cSCristian Dumitrescu 		return;
1591a4c1146cSCristian Dumitrescu 	}
1592a4c1146cSCristian Dumitrescu 
1593b9559f94SCristian Dumitrescu 	status = rte_swx_ctl_pipeline_selector_fprintf(file, ctl, selector_name);
1594598fe0ddSCristian Dumitrescu 	if (status)
1595598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "selector_name");
1596a4c1146cSCristian Dumitrescu 
1597a4c1146cSCristian Dumitrescu 	if (file)
1598a4c1146cSCristian Dumitrescu 		fclose(file);
1599598fe0ddSCristian Dumitrescu }
1600598fe0ddSCristian Dumitrescu 
16018bd4862fSCristian Dumitrescu static int
16028bd4862fSCristian Dumitrescu pipeline_learner_default_entry_add(struct rte_swx_ctl_pipeline *p,
16038bd4862fSCristian Dumitrescu 				   const char *learner_name,
16048bd4862fSCristian Dumitrescu 				   FILE *file,
16058bd4862fSCristian Dumitrescu 				   uint32_t *file_line_number)
16068bd4862fSCristian Dumitrescu {
16078bd4862fSCristian Dumitrescu 	char *line = NULL;
16088bd4862fSCristian Dumitrescu 	uint32_t line_id = 0;
16098bd4862fSCristian Dumitrescu 	int status = 0;
16108bd4862fSCristian Dumitrescu 
16118bd4862fSCristian Dumitrescu 	/* Buffer allocation. */
16128bd4862fSCristian Dumitrescu 	line = malloc(MAX_LINE_SIZE);
16138bd4862fSCristian Dumitrescu 	if (!line)
16148bd4862fSCristian Dumitrescu 		return -ENOMEM;
16158bd4862fSCristian Dumitrescu 
16168bd4862fSCristian Dumitrescu 	/* File read. */
16178bd4862fSCristian Dumitrescu 	for (line_id = 1; ; line_id++) {
16188bd4862fSCristian Dumitrescu 		struct rte_swx_table_entry *entry;
16198bd4862fSCristian Dumitrescu 		int is_blank_or_comment;
16208bd4862fSCristian Dumitrescu 
16218bd4862fSCristian Dumitrescu 		if (fgets(line, MAX_LINE_SIZE, file) == NULL)
16228bd4862fSCristian Dumitrescu 			break;
16238bd4862fSCristian Dumitrescu 
16248bd4862fSCristian Dumitrescu 		entry = rte_swx_ctl_pipeline_learner_default_entry_read(p,
16258bd4862fSCristian Dumitrescu 									learner_name,
16268bd4862fSCristian Dumitrescu 									line,
16278bd4862fSCristian Dumitrescu 									&is_blank_or_comment);
16288bd4862fSCristian Dumitrescu 		if (!entry) {
16298bd4862fSCristian Dumitrescu 			if (is_blank_or_comment)
16308bd4862fSCristian Dumitrescu 				continue;
16318bd4862fSCristian Dumitrescu 
16328bd4862fSCristian Dumitrescu 			status = -EINVAL;
16338bd4862fSCristian Dumitrescu 			goto error;
16348bd4862fSCristian Dumitrescu 		}
16358bd4862fSCristian Dumitrescu 
16368bd4862fSCristian Dumitrescu 		status = rte_swx_ctl_pipeline_learner_default_entry_add(p,
16378bd4862fSCristian Dumitrescu 									learner_name,
16388bd4862fSCristian Dumitrescu 									entry);
16398bd4862fSCristian Dumitrescu 		table_entry_free(entry);
16408bd4862fSCristian Dumitrescu 		if (status)
16418bd4862fSCristian Dumitrescu 			goto error;
16428bd4862fSCristian Dumitrescu 	}
16438bd4862fSCristian Dumitrescu 
16448bd4862fSCristian Dumitrescu error:
16458bd4862fSCristian Dumitrescu 	*file_line_number = line_id;
16468bd4862fSCristian Dumitrescu 	free(line);
16478bd4862fSCristian Dumitrescu 	return status;
16488bd4862fSCristian Dumitrescu }
16498bd4862fSCristian Dumitrescu 
16508bd4862fSCristian Dumitrescu static const char cmd_pipeline_learner_default_help[] =
16518bd4862fSCristian Dumitrescu "pipeline <pipeline_name> learner <learner_name> default <file_name>\n";
16528bd4862fSCristian Dumitrescu 
16538bd4862fSCristian Dumitrescu static void
16548bd4862fSCristian Dumitrescu cmd_pipeline_learner_default(char **tokens,
16558bd4862fSCristian Dumitrescu 			     uint32_t n_tokens,
16568bd4862fSCristian Dumitrescu 			     char *out,
16578bd4862fSCristian Dumitrescu 			     size_t out_size,
1658b9559f94SCristian Dumitrescu 			     void *obj __rte_unused)
16598bd4862fSCristian Dumitrescu {
1660b9559f94SCristian Dumitrescu 	struct rte_swx_ctl_pipeline *ctl;
16618bd4862fSCristian Dumitrescu 	char *pipeline_name, *learner_name, *file_name;
16628bd4862fSCristian Dumitrescu 	FILE *file = NULL;
16638bd4862fSCristian Dumitrescu 	uint32_t file_line_number = 0;
16648bd4862fSCristian Dumitrescu 	int status;
16658bd4862fSCristian Dumitrescu 
16668bd4862fSCristian Dumitrescu 	if (n_tokens != 6) {
16678bd4862fSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
16688bd4862fSCristian Dumitrescu 		return;
16698bd4862fSCristian Dumitrescu 	}
16708bd4862fSCristian Dumitrescu 
16718bd4862fSCristian Dumitrescu 	pipeline_name = tokens[1];
1672b9559f94SCristian Dumitrescu 	ctl = rte_swx_ctl_pipeline_find(pipeline_name);
1673b9559f94SCristian Dumitrescu 	if (!ctl) {
16748bd4862fSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
16758bd4862fSCristian Dumitrescu 		return;
16768bd4862fSCristian Dumitrescu 	}
16778bd4862fSCristian Dumitrescu 
16788bd4862fSCristian Dumitrescu 	learner_name = tokens[3];
16798bd4862fSCristian Dumitrescu 
16808bd4862fSCristian Dumitrescu 	file_name = tokens[5];
16818bd4862fSCristian Dumitrescu 	file = fopen(file_name, "r");
16828bd4862fSCristian Dumitrescu 	if (!file) {
16838bd4862fSCristian Dumitrescu 		snprintf(out, out_size, "Cannot open file %s.\n", file_name);
16848bd4862fSCristian Dumitrescu 		return;
16858bd4862fSCristian Dumitrescu 	}
16868bd4862fSCristian Dumitrescu 
1687b9559f94SCristian Dumitrescu 	status = pipeline_learner_default_entry_add(ctl,
16888bd4862fSCristian Dumitrescu 						    learner_name,
16898bd4862fSCristian Dumitrescu 						    file,
16908bd4862fSCristian Dumitrescu 						    &file_line_number);
16918bd4862fSCristian Dumitrescu 	if (status)
16928bd4862fSCristian Dumitrescu 		snprintf(out, out_size, "Invalid entry in file %s at line %u\n",
16938bd4862fSCristian Dumitrescu 			 file_name,
16948bd4862fSCristian Dumitrescu 			 file_line_number);
16958bd4862fSCristian Dumitrescu 
16968bd4862fSCristian Dumitrescu 	fclose(file);
16978bd4862fSCristian Dumitrescu }
16988bd4862fSCristian Dumitrescu 
169975129cebSChurchill Khangar static const char cmd_pipeline_commit_help[] =
170075129cebSChurchill Khangar "pipeline <pipeline_name> commit\n";
170175129cebSChurchill Khangar 
170275129cebSChurchill Khangar static void
170375129cebSChurchill Khangar cmd_pipeline_commit(char **tokens,
170475129cebSChurchill Khangar 	uint32_t n_tokens,
170575129cebSChurchill Khangar 	char *out,
170675129cebSChurchill Khangar 	size_t out_size,
1707b9559f94SCristian Dumitrescu 	void *obj __rte_unused)
170875129cebSChurchill Khangar {
1709b9559f94SCristian Dumitrescu 	struct rte_swx_ctl_pipeline *ctl;
171075129cebSChurchill Khangar 	char *pipeline_name;
171175129cebSChurchill Khangar 	int status;
171275129cebSChurchill Khangar 
171375129cebSChurchill Khangar 	if (n_tokens != 3) {
171475129cebSChurchill Khangar 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
171575129cebSChurchill Khangar 		return;
171675129cebSChurchill Khangar 	}
171775129cebSChurchill Khangar 
171875129cebSChurchill Khangar 	pipeline_name = tokens[1];
1719b9559f94SCristian Dumitrescu 	ctl = rte_swx_ctl_pipeline_find(pipeline_name);
1720b9559f94SCristian Dumitrescu 	if (!ctl) {
172175129cebSChurchill Khangar 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
172275129cebSChurchill Khangar 		return;
17235074e1d5SCristian Dumitrescu 	}
17245074e1d5SCristian Dumitrescu 
1725b9559f94SCristian Dumitrescu 	status = rte_swx_ctl_pipeline_commit(ctl, 1);
172675129cebSChurchill Khangar 	if (status)
172775129cebSChurchill Khangar 		snprintf(out, out_size, "Commit failed. "
172875129cebSChurchill Khangar 			"Use \"commit\" to retry or \"abort\" to discard the pending work.\n");
17295074e1d5SCristian Dumitrescu }
17305074e1d5SCristian Dumitrescu 
173175129cebSChurchill Khangar static const char cmd_pipeline_abort_help[] =
173275129cebSChurchill Khangar "pipeline <pipeline_name> abort\n";
17335074e1d5SCristian Dumitrescu 
173475129cebSChurchill Khangar static void
173575129cebSChurchill Khangar cmd_pipeline_abort(char **tokens,
173675129cebSChurchill Khangar 	uint32_t n_tokens,
173775129cebSChurchill Khangar 	char *out,
173875129cebSChurchill Khangar 	size_t out_size,
1739b9559f94SCristian Dumitrescu 	void *obj __rte_unused)
174075129cebSChurchill Khangar {
1741b9559f94SCristian Dumitrescu 	struct rte_swx_ctl_pipeline *ctl;
174275129cebSChurchill Khangar 	char *pipeline_name;
17435074e1d5SCristian Dumitrescu 
174475129cebSChurchill Khangar 	if (n_tokens != 3) {
174575129cebSChurchill Khangar 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
17465074e1d5SCristian Dumitrescu 		return;
174775129cebSChurchill Khangar 	}
17485074e1d5SCristian Dumitrescu 
174975129cebSChurchill Khangar 	pipeline_name = tokens[1];
1750b9559f94SCristian Dumitrescu 	ctl = rte_swx_ctl_pipeline_find(pipeline_name);
1751b9559f94SCristian Dumitrescu 	if (!ctl) {
175275129cebSChurchill Khangar 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
175375129cebSChurchill Khangar 		return;
175475129cebSChurchill Khangar 	}
175575129cebSChurchill Khangar 
1756b9559f94SCristian Dumitrescu 	rte_swx_ctl_pipeline_abort(ctl);
17575074e1d5SCristian Dumitrescu }
17585074e1d5SCristian Dumitrescu 
175964cfcebdSCristian Dumitrescu static const char cmd_pipeline_regrd_help[] =
176083f58a7bSCristian Dumitrescu "pipeline <pipeline_name> regrd <register_array_name>\n"
176183f58a7bSCristian Dumitrescu 	"index <index>\n"
176283f58a7bSCristian Dumitrescu 	" | table <table_name> match <field0> ...\n";
176364cfcebdSCristian Dumitrescu 
176464cfcebdSCristian Dumitrescu static void
176564cfcebdSCristian Dumitrescu cmd_pipeline_regrd(char **tokens,
176664cfcebdSCristian Dumitrescu 	uint32_t n_tokens,
176764cfcebdSCristian Dumitrescu 	char *out,
176864cfcebdSCristian Dumitrescu 	size_t out_size,
1769b9559f94SCristian Dumitrescu 	void *obj __rte_unused)
177064cfcebdSCristian Dumitrescu {
1771b9559f94SCristian Dumitrescu 	struct rte_swx_pipeline *p;
177283f58a7bSCristian Dumitrescu 	struct rte_swx_ctl_pipeline *ctl;
177383f58a7bSCristian Dumitrescu 	const char *pipeline_name, *name;
177464cfcebdSCristian Dumitrescu 	uint64_t value;
177564cfcebdSCristian Dumitrescu 	int status;
177664cfcebdSCristian Dumitrescu 
177783f58a7bSCristian Dumitrescu 	if (n_tokens < 5) {
177864cfcebdSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
177964cfcebdSCristian Dumitrescu 		return;
178064cfcebdSCristian Dumitrescu 	}
178164cfcebdSCristian Dumitrescu 
178283f58a7bSCristian Dumitrescu 	pipeline_name = tokens[1];
178383f58a7bSCristian Dumitrescu 	p = rte_swx_pipeline_find(pipeline_name);
178483f58a7bSCristian Dumitrescu 	ctl = rte_swx_ctl_pipeline_find(pipeline_name);
178583f58a7bSCristian Dumitrescu 	if (!p || !ctl) {
178664cfcebdSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
178764cfcebdSCristian Dumitrescu 		return;
178864cfcebdSCristian Dumitrescu 	}
178964cfcebdSCristian Dumitrescu 
179064cfcebdSCristian Dumitrescu 	if (strcmp(tokens[2], "regrd")) {
179164cfcebdSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "regrd");
179264cfcebdSCristian Dumitrescu 		return;
179364cfcebdSCristian Dumitrescu 	}
179464cfcebdSCristian Dumitrescu 
179564cfcebdSCristian Dumitrescu 	name = tokens[3];
179664cfcebdSCristian Dumitrescu 
179783f58a7bSCristian Dumitrescu 	/* index. */
179883f58a7bSCristian Dumitrescu 	if (!strcmp(tokens[4], "index")) {
1799327820afSAli Alnubani 		uint32_t idx = 0;
180083f58a7bSCristian Dumitrescu 
180183f58a7bSCristian Dumitrescu 		if (n_tokens != 6) {
180283f58a7bSCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
180383f58a7bSCristian Dumitrescu 			return;
180483f58a7bSCristian Dumitrescu 		}
180583f58a7bSCristian Dumitrescu 
180683f58a7bSCristian Dumitrescu 		if (parser_read_uint32(&idx, tokens[5])) {
180764cfcebdSCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_INVALID, "index");
180864cfcebdSCristian Dumitrescu 			return;
180964cfcebdSCristian Dumitrescu 		}
181064cfcebdSCristian Dumitrescu 
1811b9559f94SCristian Dumitrescu 		status = rte_swx_ctl_pipeline_regarray_read(p, name, idx, &value);
181264cfcebdSCristian Dumitrescu 		if (status) {
181364cfcebdSCristian Dumitrescu 			snprintf(out, out_size, "Command failed.\n");
181464cfcebdSCristian Dumitrescu 			return;
181564cfcebdSCristian Dumitrescu 		}
181664cfcebdSCristian Dumitrescu 
181764cfcebdSCristian Dumitrescu 		snprintf(out, out_size, "0x%" PRIx64 "\n", value);
181883f58a7bSCristian Dumitrescu 		return;
181983f58a7bSCristian Dumitrescu 	}
182083f58a7bSCristian Dumitrescu 
182183f58a7bSCristian Dumitrescu 	/* table. */
182283f58a7bSCristian Dumitrescu 	if (!strcmp(tokens[4], "table")) {
182383f58a7bSCristian Dumitrescu 		struct rte_swx_table_entry *entry;
182483f58a7bSCristian Dumitrescu 		char *table_name;
182583f58a7bSCristian Dumitrescu 
182683f58a7bSCristian Dumitrescu 		if (n_tokens < 8) {
182783f58a7bSCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
182883f58a7bSCristian Dumitrescu 			return;
182983f58a7bSCristian Dumitrescu 		}
183083f58a7bSCristian Dumitrescu 
183183f58a7bSCristian Dumitrescu 		table_name = tokens[5];
183283f58a7bSCristian Dumitrescu 
183383f58a7bSCristian Dumitrescu 		if (strcmp(tokens[6], "match")) {
183483f58a7bSCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_NOT_FOUND, "match");
183583f58a7bSCristian Dumitrescu 			return;
183683f58a7bSCristian Dumitrescu 		}
183783f58a7bSCristian Dumitrescu 
183883f58a7bSCristian Dumitrescu 		entry = parse_table_entry(ctl, table_name, &tokens[6], n_tokens - 6);
183983f58a7bSCristian Dumitrescu 		if (!entry) {
184083f58a7bSCristian Dumitrescu 			snprintf(out, out_size, "Invalid match tokens.\n");
184183f58a7bSCristian Dumitrescu 			return;
184283f58a7bSCristian Dumitrescu 		}
184383f58a7bSCristian Dumitrescu 
184483f58a7bSCristian Dumitrescu 		status = rte_swx_ctl_pipeline_regarray_read_with_key(p,
184583f58a7bSCristian Dumitrescu 								     name,
184683f58a7bSCristian Dumitrescu 								     table_name,
184783f58a7bSCristian Dumitrescu 								     entry->key,
184883f58a7bSCristian Dumitrescu 								     &value);
184983f58a7bSCristian Dumitrescu 		table_entry_free(entry);
185083f58a7bSCristian Dumitrescu 		if (status) {
185183f58a7bSCristian Dumitrescu 			snprintf(out, out_size, "Command failed.\n");
185283f58a7bSCristian Dumitrescu 			return;
185383f58a7bSCristian Dumitrescu 		}
185483f58a7bSCristian Dumitrescu 
185583f58a7bSCristian Dumitrescu 		snprintf(out, out_size, "0x%" PRIx64 "\n", value);
185683f58a7bSCristian Dumitrescu 		return;
185783f58a7bSCristian Dumitrescu 	}
185883f58a7bSCristian Dumitrescu 
185983f58a7bSCristian Dumitrescu 	/* anything else. */
186083f58a7bSCristian Dumitrescu 	snprintf(out, out_size, "Invalid token %s\n.", tokens[4]);
186183f58a7bSCristian Dumitrescu 	return;
186264cfcebdSCristian Dumitrescu }
186364cfcebdSCristian Dumitrescu 
186464cfcebdSCristian Dumitrescu static const char cmd_pipeline_regwr_help[] =
186583f58a7bSCristian Dumitrescu "pipeline <pipeline_name> regwr <register_array_name> value <value>\n"
186683f58a7bSCristian Dumitrescu 	"index <index>\n"
186783f58a7bSCristian Dumitrescu 	" | table <table_name> match <field0> ...\n";
186864cfcebdSCristian Dumitrescu 
186964cfcebdSCristian Dumitrescu static void
187064cfcebdSCristian Dumitrescu cmd_pipeline_regwr(char **tokens,
187164cfcebdSCristian Dumitrescu 	uint32_t n_tokens,
187264cfcebdSCristian Dumitrescu 	char *out,
187364cfcebdSCristian Dumitrescu 	size_t out_size,
1874b9559f94SCristian Dumitrescu 	void *obj __rte_unused)
187564cfcebdSCristian Dumitrescu {
1876b9559f94SCristian Dumitrescu 	struct rte_swx_pipeline *p;
187783f58a7bSCristian Dumitrescu 	struct rte_swx_ctl_pipeline *ctl;
187883f58a7bSCristian Dumitrescu 	const char *pipeline_name, *name;
187983f58a7bSCristian Dumitrescu 	uint64_t value = 0;
188064cfcebdSCristian Dumitrescu 	int status;
188164cfcebdSCristian Dumitrescu 
188283f58a7bSCristian Dumitrescu 	if (n_tokens < 7) {
188364cfcebdSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
188464cfcebdSCristian Dumitrescu 		return;
188564cfcebdSCristian Dumitrescu 	}
188664cfcebdSCristian Dumitrescu 
188783f58a7bSCristian Dumitrescu 	pipeline_name = tokens[1];
188883f58a7bSCristian Dumitrescu 	p = rte_swx_pipeline_find(pipeline_name);
188983f58a7bSCristian Dumitrescu 	ctl = rte_swx_ctl_pipeline_find(pipeline_name);
189083f58a7bSCristian Dumitrescu 	if (!p || !ctl) {
189164cfcebdSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
189264cfcebdSCristian Dumitrescu 		return;
189364cfcebdSCristian Dumitrescu 	}
189464cfcebdSCristian Dumitrescu 
189564cfcebdSCristian Dumitrescu 	if (strcmp(tokens[2], "regwr")) {
189664cfcebdSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "regwr");
189764cfcebdSCristian Dumitrescu 		return;
189864cfcebdSCristian Dumitrescu 	}
189964cfcebdSCristian Dumitrescu 
190064cfcebdSCristian Dumitrescu 	name = tokens[3];
190164cfcebdSCristian Dumitrescu 
190283f58a7bSCristian Dumitrescu 	if (strcmp(tokens[4], "value")) {
190383f58a7bSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "value");
190464cfcebdSCristian Dumitrescu 		return;
190564cfcebdSCristian Dumitrescu 	}
190664cfcebdSCristian Dumitrescu 
190764cfcebdSCristian Dumitrescu 	if (parser_read_uint64(&value, tokens[5])) {
190864cfcebdSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "value");
190964cfcebdSCristian Dumitrescu 		return;
191064cfcebdSCristian Dumitrescu 	}
191164cfcebdSCristian Dumitrescu 
191283f58a7bSCristian Dumitrescu 	/* index. */
191383f58a7bSCristian Dumitrescu 	if (!strcmp(tokens[6], "index")) {
1914327820afSAli Alnubani 		uint32_t idx = 0;
191583f58a7bSCristian Dumitrescu 
191683f58a7bSCristian Dumitrescu 		if (n_tokens != 8) {
191783f58a7bSCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
191883f58a7bSCristian Dumitrescu 			return;
191983f58a7bSCristian Dumitrescu 		}
192083f58a7bSCristian Dumitrescu 
192183f58a7bSCristian Dumitrescu 		if (parser_read_uint32(&idx, tokens[7])) {
192283f58a7bSCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_INVALID, "index");
192383f58a7bSCristian Dumitrescu 			return;
192483f58a7bSCristian Dumitrescu 		}
192583f58a7bSCristian Dumitrescu 
1926b9559f94SCristian Dumitrescu 		status = rte_swx_ctl_pipeline_regarray_write(p, name, idx, value);
192764cfcebdSCristian Dumitrescu 		if (status) {
192864cfcebdSCristian Dumitrescu 			snprintf(out, out_size, "Command failed.\n");
192964cfcebdSCristian Dumitrescu 			return;
193064cfcebdSCristian Dumitrescu 		}
193183f58a7bSCristian Dumitrescu 
193283f58a7bSCristian Dumitrescu 		snprintf(out, out_size, "0x%" PRIx64 "\n", value);
193383f58a7bSCristian Dumitrescu 		return;
193483f58a7bSCristian Dumitrescu 	}
193583f58a7bSCristian Dumitrescu 
193683f58a7bSCristian Dumitrescu 	/* table. */
193783f58a7bSCristian Dumitrescu 	if (!strcmp(tokens[6], "table")) {
193883f58a7bSCristian Dumitrescu 		struct rte_swx_table_entry *entry;
193983f58a7bSCristian Dumitrescu 		char *table_name;
194083f58a7bSCristian Dumitrescu 
194183f58a7bSCristian Dumitrescu 		if (n_tokens < 10) {
194283f58a7bSCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
194383f58a7bSCristian Dumitrescu 			return;
194483f58a7bSCristian Dumitrescu 		}
194583f58a7bSCristian Dumitrescu 
194683f58a7bSCristian Dumitrescu 		table_name = tokens[7];
194783f58a7bSCristian Dumitrescu 
194883f58a7bSCristian Dumitrescu 		if (strcmp(tokens[8], "match")) {
194983f58a7bSCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_NOT_FOUND, "match");
195083f58a7bSCristian Dumitrescu 			return;
195183f58a7bSCristian Dumitrescu 		}
195283f58a7bSCristian Dumitrescu 
195383f58a7bSCristian Dumitrescu 		entry = parse_table_entry(ctl, table_name, &tokens[8], n_tokens - 8);
195483f58a7bSCristian Dumitrescu 		if (!entry) {
195583f58a7bSCristian Dumitrescu 			snprintf(out, out_size, "Invalid match tokens.\n");
195683f58a7bSCristian Dumitrescu 			return;
195783f58a7bSCristian Dumitrescu 		}
195883f58a7bSCristian Dumitrescu 
195983f58a7bSCristian Dumitrescu 		status = rte_swx_ctl_pipeline_regarray_write_with_key(p,
196083f58a7bSCristian Dumitrescu 								      name,
196183f58a7bSCristian Dumitrescu 								      table_name,
196283f58a7bSCristian Dumitrescu 								      entry->key,
196383f58a7bSCristian Dumitrescu 								      value);
196483f58a7bSCristian Dumitrescu 		table_entry_free(entry);
196583f58a7bSCristian Dumitrescu 		if (status) {
196683f58a7bSCristian Dumitrescu 			snprintf(out, out_size, "Command failed.\n");
196783f58a7bSCristian Dumitrescu 			return;
196883f58a7bSCristian Dumitrescu 		}
196983f58a7bSCristian Dumitrescu 
197083f58a7bSCristian Dumitrescu 		return;
197183f58a7bSCristian Dumitrescu 	}
197283f58a7bSCristian Dumitrescu 
197383f58a7bSCristian Dumitrescu 	/* anything else. */
197483f58a7bSCristian Dumitrescu 	snprintf(out, out_size, "Invalid token %s\n.", tokens[6]);
197583f58a7bSCristian Dumitrescu 	return;
197664cfcebdSCristian Dumitrescu }
197764cfcebdSCristian Dumitrescu 
1978f38913b7SCristian Dumitrescu static const char cmd_pipeline_meter_profile_add_help[] =
1979f38913b7SCristian Dumitrescu "pipeline <pipeline_name> meter profile <profile_name> add "
1980f38913b7SCristian Dumitrescu 	"cir <cir> pir <pir> cbs <cbs> pbs <pbs>\n";
1981f38913b7SCristian Dumitrescu 
1982f38913b7SCristian Dumitrescu static void
1983f38913b7SCristian Dumitrescu cmd_pipeline_meter_profile_add(char **tokens,
1984f38913b7SCristian Dumitrescu 	uint32_t n_tokens,
1985f38913b7SCristian Dumitrescu 	char *out,
1986f38913b7SCristian Dumitrescu 	size_t out_size,
1987b9559f94SCristian Dumitrescu 	void *obj __rte_unused)
1988f38913b7SCristian Dumitrescu {
1989f38913b7SCristian Dumitrescu 	struct rte_meter_trtcm_params params;
1990b9559f94SCristian Dumitrescu 	struct rte_swx_pipeline *p;
1991f38913b7SCristian Dumitrescu 	const char *profile_name;
1992f38913b7SCristian Dumitrescu 	int status;
1993f38913b7SCristian Dumitrescu 
1994f38913b7SCristian Dumitrescu 	if (n_tokens != 14) {
1995f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1996f38913b7SCristian Dumitrescu 		return;
1997f38913b7SCristian Dumitrescu 	}
1998f38913b7SCristian Dumitrescu 
1999b9559f94SCristian Dumitrescu 	p = rte_swx_pipeline_find(tokens[1]);
2000b9559f94SCristian Dumitrescu 	if (!p) {
2001f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
2002f38913b7SCristian Dumitrescu 		return;
2003f38913b7SCristian Dumitrescu 	}
2004f38913b7SCristian Dumitrescu 
2005f38913b7SCristian Dumitrescu 	if (strcmp(tokens[2], "meter")) {
2006f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "meter");
2007f38913b7SCristian Dumitrescu 		return;
2008f38913b7SCristian Dumitrescu 	}
2009f38913b7SCristian Dumitrescu 
2010f38913b7SCristian Dumitrescu 	if (strcmp(tokens[3], "profile")) {
2011f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "profile");
2012f38913b7SCristian Dumitrescu 		return;
2013f38913b7SCristian Dumitrescu 	}
2014f38913b7SCristian Dumitrescu 
2015f38913b7SCristian Dumitrescu 	profile_name = tokens[4];
2016f38913b7SCristian Dumitrescu 
2017f38913b7SCristian Dumitrescu 	if (strcmp(tokens[5], "add")) {
2018f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "add");
2019f38913b7SCristian Dumitrescu 		return;
2020f38913b7SCristian Dumitrescu 	}
2021f38913b7SCristian Dumitrescu 
2022f38913b7SCristian Dumitrescu 	if (strcmp(tokens[6], "cir")) {
2023f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cir");
2024f38913b7SCristian Dumitrescu 		return;
2025f38913b7SCristian Dumitrescu 	}
2026f38913b7SCristian Dumitrescu 
2027f38913b7SCristian Dumitrescu 	if (parser_read_uint64(&params.cir, tokens[7])) {
2028f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "cir");
2029f38913b7SCristian Dumitrescu 		return;
2030f38913b7SCristian Dumitrescu 	}
2031f38913b7SCristian Dumitrescu 
2032f38913b7SCristian Dumitrescu 	if (strcmp(tokens[8], "pir")) {
2033f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pir");
2034f38913b7SCristian Dumitrescu 		return;
2035f38913b7SCristian Dumitrescu 	}
2036f38913b7SCristian Dumitrescu 
2037f38913b7SCristian Dumitrescu 	if (parser_read_uint64(&params.pir, tokens[9])) {
2038f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pir");
2039f38913b7SCristian Dumitrescu 		return;
2040f38913b7SCristian Dumitrescu 	}
2041f38913b7SCristian Dumitrescu 
2042f38913b7SCristian Dumitrescu 	if (strcmp(tokens[10], "cbs")) {
2043f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cbs");
2044f38913b7SCristian Dumitrescu 		return;
2045f38913b7SCristian Dumitrescu 	}
2046f38913b7SCristian Dumitrescu 
2047f38913b7SCristian Dumitrescu 	if (parser_read_uint64(&params.cbs, tokens[11])) {
2048f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "cbs");
2049f38913b7SCristian Dumitrescu 		return;
2050f38913b7SCristian Dumitrescu 	}
2051f38913b7SCristian Dumitrescu 
2052f38913b7SCristian Dumitrescu 	if (strcmp(tokens[12], "pbs")) {
2053f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pbs");
2054f38913b7SCristian Dumitrescu 		return;
2055f38913b7SCristian Dumitrescu 	}
2056f38913b7SCristian Dumitrescu 
2057f38913b7SCristian Dumitrescu 	if (parser_read_uint64(&params.pbs, tokens[13])) {
2058f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pbs");
2059f38913b7SCristian Dumitrescu 		return;
2060f38913b7SCristian Dumitrescu 	}
2061f38913b7SCristian Dumitrescu 
2062b9559f94SCristian Dumitrescu 	status = rte_swx_ctl_meter_profile_add(p, profile_name, &params);
2063f38913b7SCristian Dumitrescu 	if (status) {
2064f38913b7SCristian Dumitrescu 		snprintf(out, out_size, "Command failed.\n");
2065f38913b7SCristian Dumitrescu 		return;
2066f38913b7SCristian Dumitrescu 	}
2067f38913b7SCristian Dumitrescu }
2068f38913b7SCristian Dumitrescu 
2069f38913b7SCristian Dumitrescu static const char cmd_pipeline_meter_profile_delete_help[] =
2070f38913b7SCristian Dumitrescu "pipeline <pipeline_name> meter profile <profile_name> delete\n";
2071f38913b7SCristian Dumitrescu 
2072f38913b7SCristian Dumitrescu static void
2073f38913b7SCristian Dumitrescu cmd_pipeline_meter_profile_delete(char **tokens,
2074f38913b7SCristian Dumitrescu 	uint32_t n_tokens,
2075f38913b7SCristian Dumitrescu 	char *out,
2076f38913b7SCristian Dumitrescu 	size_t out_size,
2077b9559f94SCristian Dumitrescu 	void *obj __rte_unused)
2078f38913b7SCristian Dumitrescu {
2079b9559f94SCristian Dumitrescu 	struct rte_swx_pipeline *p;
2080f38913b7SCristian Dumitrescu 	const char *profile_name;
2081f38913b7SCristian Dumitrescu 	int status;
2082f38913b7SCristian Dumitrescu 
2083f38913b7SCristian Dumitrescu 	if (n_tokens != 6) {
2084f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2085f38913b7SCristian Dumitrescu 		return;
2086f38913b7SCristian Dumitrescu 	}
2087f38913b7SCristian Dumitrescu 
2088b9559f94SCristian Dumitrescu 	p = rte_swx_pipeline_find(tokens[1]);
2089b9559f94SCristian Dumitrescu 	if (!p) {
2090f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
2091f38913b7SCristian Dumitrescu 		return;
2092f38913b7SCristian Dumitrescu 	}
2093f38913b7SCristian Dumitrescu 
2094f38913b7SCristian Dumitrescu 	if (strcmp(tokens[2], "meter")) {
2095f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "meter");
2096f38913b7SCristian Dumitrescu 		return;
2097f38913b7SCristian Dumitrescu 	}
2098f38913b7SCristian Dumitrescu 
2099f38913b7SCristian Dumitrescu 	if (strcmp(tokens[3], "profile")) {
2100f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "profile");
2101f38913b7SCristian Dumitrescu 		return;
2102f38913b7SCristian Dumitrescu 	}
2103f38913b7SCristian Dumitrescu 
2104f38913b7SCristian Dumitrescu 	profile_name = tokens[4];
2105f38913b7SCristian Dumitrescu 
2106f38913b7SCristian Dumitrescu 	if (strcmp(tokens[5], "delete")) {
2107f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "delete");
2108f38913b7SCristian Dumitrescu 		return;
2109f38913b7SCristian Dumitrescu 	}
2110f38913b7SCristian Dumitrescu 
2111b9559f94SCristian Dumitrescu 	status = rte_swx_ctl_meter_profile_delete(p, profile_name);
2112f38913b7SCristian Dumitrescu 	if (status) {
2113f38913b7SCristian Dumitrescu 		snprintf(out, out_size, "Command failed.\n");
2114f38913b7SCristian Dumitrescu 		return;
2115f38913b7SCristian Dumitrescu 	}
2116f38913b7SCristian Dumitrescu }
2117f38913b7SCristian Dumitrescu 
2118f38913b7SCristian Dumitrescu static const char cmd_pipeline_meter_reset_help[] =
211912eda78dSCristian Dumitrescu "pipeline <pipeline_name> meter <meter_array_name> reset\n"
212012eda78dSCristian Dumitrescu 	"index from <index0> to <index1>\n"
212112eda78dSCristian Dumitrescu 	" | table <table_name> match <field0> ...\n";
2122f38913b7SCristian Dumitrescu 
2123f38913b7SCristian Dumitrescu static void
2124f38913b7SCristian Dumitrescu cmd_pipeline_meter_reset(char **tokens,
2125f38913b7SCristian Dumitrescu 	uint32_t n_tokens,
2126f38913b7SCristian Dumitrescu 	char *out,
2127f38913b7SCristian Dumitrescu 	size_t out_size,
2128b9559f94SCristian Dumitrescu 	void *obj __rte_unused)
2129f38913b7SCristian Dumitrescu {
2130b9559f94SCristian Dumitrescu 	struct rte_swx_pipeline *p;
213112eda78dSCristian Dumitrescu 	struct rte_swx_ctl_pipeline *ctl;
213212eda78dSCristian Dumitrescu 	const char *pipeline_name, *name;
2133f38913b7SCristian Dumitrescu 
213412eda78dSCristian Dumitrescu 	if (n_tokens < 6) {
2135f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2136f38913b7SCristian Dumitrescu 		return;
2137f38913b7SCristian Dumitrescu 	}
2138f38913b7SCristian Dumitrescu 
213912eda78dSCristian Dumitrescu 	pipeline_name = tokens[1];
214012eda78dSCristian Dumitrescu 	p = rte_swx_pipeline_find(pipeline_name);
214112eda78dSCristian Dumitrescu 	ctl = rte_swx_ctl_pipeline_find(pipeline_name);
214212eda78dSCristian Dumitrescu 	if (!p || !ctl) {
2143f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
2144f38913b7SCristian Dumitrescu 		return;
2145f38913b7SCristian Dumitrescu 	}
2146f38913b7SCristian Dumitrescu 
2147f38913b7SCristian Dumitrescu 	if (strcmp(tokens[2], "meter")) {
2148f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "meter");
2149f38913b7SCristian Dumitrescu 		return;
2150f38913b7SCristian Dumitrescu 	}
2151f38913b7SCristian Dumitrescu 
2152f38913b7SCristian Dumitrescu 	name = tokens[3];
2153f38913b7SCristian Dumitrescu 
215412eda78dSCristian Dumitrescu 	if (strcmp(tokens[4], "reset")) {
215512eda78dSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "reset");
215612eda78dSCristian Dumitrescu 		return;
215712eda78dSCristian Dumitrescu 	}
215812eda78dSCristian Dumitrescu 
215912eda78dSCristian Dumitrescu 	/* index. */
216012eda78dSCristian Dumitrescu 	if (!strcmp(tokens[5], "index")) {
216112eda78dSCristian Dumitrescu 		uint32_t idx0 = 0, idx1 = 0;
216212eda78dSCristian Dumitrescu 
216312eda78dSCristian Dumitrescu 		if (n_tokens != 10) {
216412eda78dSCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
216512eda78dSCristian Dumitrescu 			return;
216612eda78dSCristian Dumitrescu 		}
216712eda78dSCristian Dumitrescu 
216812eda78dSCristian Dumitrescu 		if (strcmp(tokens[6], "from")) {
2169f38913b7SCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_NOT_FOUND, "from");
2170f38913b7SCristian Dumitrescu 			return;
2171f38913b7SCristian Dumitrescu 		}
2172f38913b7SCristian Dumitrescu 
217312eda78dSCristian Dumitrescu 		if (parser_read_uint32(&idx0, tokens[7])) {
2174f38913b7SCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_INVALID, "index0");
2175f38913b7SCristian Dumitrescu 			return;
2176f38913b7SCristian Dumitrescu 		}
2177f38913b7SCristian Dumitrescu 
217812eda78dSCristian Dumitrescu 		if (strcmp(tokens[8], "to")) {
2179f38913b7SCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_NOT_FOUND, "to");
2180f38913b7SCristian Dumitrescu 			return;
2181f38913b7SCristian Dumitrescu 		}
2182f38913b7SCristian Dumitrescu 
218312eda78dSCristian Dumitrescu 		if (parser_read_uint32(&idx1, tokens[9]) || (idx1 < idx0)) {
2184f38913b7SCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_INVALID, "index1");
2185f38913b7SCristian Dumitrescu 			return;
2186f38913b7SCristian Dumitrescu 		}
2187f38913b7SCristian Dumitrescu 
2188f38913b7SCristian Dumitrescu 		for ( ; idx0 <= idx1; idx0++) {
2189f38913b7SCristian Dumitrescu 			int status;
2190f38913b7SCristian Dumitrescu 
2191b9559f94SCristian Dumitrescu 			status = rte_swx_ctl_meter_reset(p, name, idx0);
2192f38913b7SCristian Dumitrescu 			if (status) {
2193f38913b7SCristian Dumitrescu 				snprintf(out, out_size, "Command failed for index %u.\n", idx0);
2194f38913b7SCristian Dumitrescu 				return;
2195f38913b7SCristian Dumitrescu 			}
2196f38913b7SCristian Dumitrescu 		}
219712eda78dSCristian Dumitrescu 
219812eda78dSCristian Dumitrescu 		return;
219912eda78dSCristian Dumitrescu 	}
220012eda78dSCristian Dumitrescu 
220112eda78dSCristian Dumitrescu 	/* table. */
220212eda78dSCristian Dumitrescu 	if (!strcmp(tokens[5], "table")) {
220312eda78dSCristian Dumitrescu 		struct rte_swx_table_entry *entry;
220412eda78dSCristian Dumitrescu 		char *table_name;
220512eda78dSCristian Dumitrescu 		int status;
220612eda78dSCristian Dumitrescu 
220712eda78dSCristian Dumitrescu 		if (n_tokens < 9) {
220812eda78dSCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
220912eda78dSCristian Dumitrescu 			return;
221012eda78dSCristian Dumitrescu 		}
221112eda78dSCristian Dumitrescu 
221212eda78dSCristian Dumitrescu 		table_name = tokens[6];
221312eda78dSCristian Dumitrescu 
221412eda78dSCristian Dumitrescu 		if (strcmp(tokens[7], "match")) {
221512eda78dSCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_NOT_FOUND, "match");
221612eda78dSCristian Dumitrescu 			return;
221712eda78dSCristian Dumitrescu 		}
221812eda78dSCristian Dumitrescu 
221912eda78dSCristian Dumitrescu 		entry = parse_table_entry(ctl, table_name, &tokens[7], n_tokens - 7);
222012eda78dSCristian Dumitrescu 		if (!entry) {
222112eda78dSCristian Dumitrescu 			snprintf(out, out_size, "Invalid match tokens.\n");
222212eda78dSCristian Dumitrescu 			return;
222312eda78dSCristian Dumitrescu 		}
222412eda78dSCristian Dumitrescu 
222512eda78dSCristian Dumitrescu 		status = rte_swx_ctl_meter_reset_with_key(p, name, table_name, entry->key);
222612eda78dSCristian Dumitrescu 		table_entry_free(entry);
222712eda78dSCristian Dumitrescu 		if (status) {
222812eda78dSCristian Dumitrescu 			snprintf(out, out_size, "Command failed.\n");
222912eda78dSCristian Dumitrescu 			return;
223012eda78dSCristian Dumitrescu 		}
223112eda78dSCristian Dumitrescu 
223212eda78dSCristian Dumitrescu 		return;
223312eda78dSCristian Dumitrescu 	}
223412eda78dSCristian Dumitrescu 
223512eda78dSCristian Dumitrescu 	/* anything else. */
223612eda78dSCristian Dumitrescu 	snprintf(out, out_size, "Invalid token %s\n.", tokens[5]);
223712eda78dSCristian Dumitrescu 	return;
2238f38913b7SCristian Dumitrescu }
2239f38913b7SCristian Dumitrescu 
2240f38913b7SCristian Dumitrescu static const char cmd_pipeline_meter_set_help[] =
224112eda78dSCristian Dumitrescu "pipeline <pipeline_name> meter <meter_array_name> set profile <profile_name>\n"
224212eda78dSCristian Dumitrescu 	"index from <index0> to <index1>\n"
224312eda78dSCristian Dumitrescu 	" | table <table_name> match <field0> ...\n";
2244f38913b7SCristian Dumitrescu 
2245f38913b7SCristian Dumitrescu static void
2246f38913b7SCristian Dumitrescu cmd_pipeline_meter_set(char **tokens,
2247f38913b7SCristian Dumitrescu 	uint32_t n_tokens,
2248f38913b7SCristian Dumitrescu 	char *out,
2249f38913b7SCristian Dumitrescu 	size_t out_size,
2250b9559f94SCristian Dumitrescu 	void *obj __rte_unused)
2251f38913b7SCristian Dumitrescu {
2252b9559f94SCristian Dumitrescu 	struct rte_swx_pipeline *p;
225312eda78dSCristian Dumitrescu 	struct rte_swx_ctl_pipeline *ctl;
225412eda78dSCristian Dumitrescu 	const char *pipeline_name, *name, *profile_name;
2255f38913b7SCristian Dumitrescu 
225612eda78dSCristian Dumitrescu 	if (n_tokens < 8) {
2257f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2258f38913b7SCristian Dumitrescu 		return;
2259f38913b7SCristian Dumitrescu 	}
2260f38913b7SCristian Dumitrescu 
226112eda78dSCristian Dumitrescu 	pipeline_name = tokens[1];
226212eda78dSCristian Dumitrescu 	p = rte_swx_pipeline_find(pipeline_name);
226312eda78dSCristian Dumitrescu 	ctl = rte_swx_ctl_pipeline_find(pipeline_name);
226412eda78dSCristian Dumitrescu 	if (!p || !ctl) {
2265f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
2266f38913b7SCristian Dumitrescu 		return;
2267f38913b7SCristian Dumitrescu 	}
2268f38913b7SCristian Dumitrescu 
2269f38913b7SCristian Dumitrescu 	if (strcmp(tokens[2], "meter")) {
2270f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "meter");
2271f38913b7SCristian Dumitrescu 		return;
2272f38913b7SCristian Dumitrescu 	}
2273f38913b7SCristian Dumitrescu 
2274f38913b7SCristian Dumitrescu 	name = tokens[3];
2275f38913b7SCristian Dumitrescu 
227612eda78dSCristian Dumitrescu 	if (strcmp(tokens[4], "set")) {
2277f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "set");
2278f38913b7SCristian Dumitrescu 		return;
2279f38913b7SCristian Dumitrescu 	}
2280f38913b7SCristian Dumitrescu 
228112eda78dSCristian Dumitrescu 	if (strcmp(tokens[5], "profile")) {
2282f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "profile");
2283f38913b7SCristian Dumitrescu 		return;
2284f38913b7SCristian Dumitrescu 	}
2285f38913b7SCristian Dumitrescu 
228612eda78dSCristian Dumitrescu 	profile_name = tokens[6];
228712eda78dSCristian Dumitrescu 
228812eda78dSCristian Dumitrescu 	/* index. */
228912eda78dSCristian Dumitrescu 	if (!strcmp(tokens[7], "index")) {
229012eda78dSCristian Dumitrescu 		uint32_t idx0 = 0, idx1 = 0;
229112eda78dSCristian Dumitrescu 
229212eda78dSCristian Dumitrescu 		if (n_tokens != 12) {
229312eda78dSCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
229412eda78dSCristian Dumitrescu 			return;
229512eda78dSCristian Dumitrescu 		}
229612eda78dSCristian Dumitrescu 
229712eda78dSCristian Dumitrescu 		if (strcmp(tokens[8], "from")) {
229812eda78dSCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_NOT_FOUND, "from");
229912eda78dSCristian Dumitrescu 			return;
230012eda78dSCristian Dumitrescu 		}
230112eda78dSCristian Dumitrescu 
230212eda78dSCristian Dumitrescu 		if (parser_read_uint32(&idx0, tokens[9])) {
230312eda78dSCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_INVALID, "index0");
230412eda78dSCristian Dumitrescu 			return;
230512eda78dSCristian Dumitrescu 		}
230612eda78dSCristian Dumitrescu 
230712eda78dSCristian Dumitrescu 		if (strcmp(tokens[10], "to")) {
230812eda78dSCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_NOT_FOUND, "to");
230912eda78dSCristian Dumitrescu 			return;
231012eda78dSCristian Dumitrescu 		}
231112eda78dSCristian Dumitrescu 
231212eda78dSCristian Dumitrescu 		if (parser_read_uint32(&idx1, tokens[11]) || (idx1 < idx0)) {
231312eda78dSCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_INVALID, "index1");
231412eda78dSCristian Dumitrescu 			return;
231512eda78dSCristian Dumitrescu 		}
2316f38913b7SCristian Dumitrescu 
2317f38913b7SCristian Dumitrescu 		for ( ; idx0 <= idx1; idx0++) {
2318f38913b7SCristian Dumitrescu 			int status;
2319f38913b7SCristian Dumitrescu 
2320b9559f94SCristian Dumitrescu 			status = rte_swx_ctl_meter_set(p, name, idx0, profile_name);
2321f38913b7SCristian Dumitrescu 			if (status) {
2322f38913b7SCristian Dumitrescu 				snprintf(out, out_size, "Command failed for index %u.\n", idx0);
2323f38913b7SCristian Dumitrescu 				return;
2324f38913b7SCristian Dumitrescu 			}
2325f38913b7SCristian Dumitrescu 		}
232612eda78dSCristian Dumitrescu 
232712eda78dSCristian Dumitrescu 		return;
232812eda78dSCristian Dumitrescu 	}
232912eda78dSCristian Dumitrescu 
233012eda78dSCristian Dumitrescu 	/* table. */
233112eda78dSCristian Dumitrescu 	if (!strcmp(tokens[7], "table")) {
233212eda78dSCristian Dumitrescu 		struct rte_swx_table_entry *entry;
233312eda78dSCristian Dumitrescu 		char *table_name;
233412eda78dSCristian Dumitrescu 		int status;
233512eda78dSCristian Dumitrescu 
233612eda78dSCristian Dumitrescu 		if (n_tokens < 11) {
233712eda78dSCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
233812eda78dSCristian Dumitrescu 			return;
233912eda78dSCristian Dumitrescu 		}
234012eda78dSCristian Dumitrescu 
234112eda78dSCristian Dumitrescu 		table_name = tokens[8];
234212eda78dSCristian Dumitrescu 
234312eda78dSCristian Dumitrescu 		if (strcmp(tokens[9], "match")) {
234412eda78dSCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_NOT_FOUND, "match");
234512eda78dSCristian Dumitrescu 			return;
234612eda78dSCristian Dumitrescu 		}
234712eda78dSCristian Dumitrescu 
234812eda78dSCristian Dumitrescu 		entry = parse_table_entry(ctl, table_name, &tokens[9], n_tokens - 9);
234912eda78dSCristian Dumitrescu 		if (!entry) {
235012eda78dSCristian Dumitrescu 			snprintf(out, out_size, "Invalid match tokens.\n");
235112eda78dSCristian Dumitrescu 			return;
235212eda78dSCristian Dumitrescu 		}
235312eda78dSCristian Dumitrescu 
235412eda78dSCristian Dumitrescu 		status = rte_swx_ctl_meter_set_with_key(p,
235512eda78dSCristian Dumitrescu 							name,
235612eda78dSCristian Dumitrescu 							table_name,
235712eda78dSCristian Dumitrescu 							entry->key,
235812eda78dSCristian Dumitrescu 							profile_name);
235912eda78dSCristian Dumitrescu 		table_entry_free(entry);
236012eda78dSCristian Dumitrescu 		if (status) {
236112eda78dSCristian Dumitrescu 			snprintf(out, out_size, "Command failed.\n");
236212eda78dSCristian Dumitrescu 			return;
236312eda78dSCristian Dumitrescu 		}
236412eda78dSCristian Dumitrescu 
236512eda78dSCristian Dumitrescu 		return;
236612eda78dSCristian Dumitrescu 	}
236712eda78dSCristian Dumitrescu 
236812eda78dSCristian Dumitrescu 	/* anything else. */
236912eda78dSCristian Dumitrescu 	snprintf(out, out_size, "Invalid token %s\n.", tokens[7]);
237012eda78dSCristian Dumitrescu 	return;
2371f38913b7SCristian Dumitrescu }
2372f38913b7SCristian Dumitrescu 
2373f38913b7SCristian Dumitrescu static const char cmd_pipeline_meter_stats_help[] =
237412eda78dSCristian Dumitrescu "pipeline <pipeline_name> meter <meter_array_name> stats\n"
237512eda78dSCristian Dumitrescu 	"index from <index0> to <index1>\n"
237612eda78dSCristian Dumitrescu 	" | table <table_name> match <field0> ...\n";
2377f38913b7SCristian Dumitrescu 
2378f38913b7SCristian Dumitrescu static void
2379f38913b7SCristian Dumitrescu cmd_pipeline_meter_stats(char **tokens,
2380f38913b7SCristian Dumitrescu 	uint32_t n_tokens,
2381f38913b7SCristian Dumitrescu 	char *out,
2382f38913b7SCristian Dumitrescu 	size_t out_size,
2383b9559f94SCristian Dumitrescu 	void *obj __rte_unused)
2384f38913b7SCristian Dumitrescu {
2385f38913b7SCristian Dumitrescu 	struct rte_swx_ctl_meter_stats stats;
2386b9559f94SCristian Dumitrescu 	struct rte_swx_pipeline *p;
238712eda78dSCristian Dumitrescu 	struct rte_swx_ctl_pipeline *ctl;
238812eda78dSCristian Dumitrescu 	const char *pipeline_name, *name;
2389f38913b7SCristian Dumitrescu 
239012eda78dSCristian Dumitrescu 	if (n_tokens < 6) {
2391f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2392f38913b7SCristian Dumitrescu 		return;
2393f38913b7SCristian Dumitrescu 	}
2394f38913b7SCristian Dumitrescu 
239512eda78dSCristian Dumitrescu 	pipeline_name = tokens[1];
239612eda78dSCristian Dumitrescu 	p = rte_swx_pipeline_find(pipeline_name);
239712eda78dSCristian Dumitrescu 	ctl = rte_swx_ctl_pipeline_find(pipeline_name);
239812eda78dSCristian Dumitrescu 	if (!p || !ctl) {
2399f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
2400f38913b7SCristian Dumitrescu 		return;
2401f38913b7SCristian Dumitrescu 	}
2402f38913b7SCristian Dumitrescu 
2403f38913b7SCristian Dumitrescu 	if (strcmp(tokens[2], "meter")) {
2404f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "meter");
2405f38913b7SCristian Dumitrescu 		return;
2406f38913b7SCristian Dumitrescu 	}
2407f38913b7SCristian Dumitrescu 
2408f38913b7SCristian Dumitrescu 	name = tokens[3];
2409f38913b7SCristian Dumitrescu 
241012eda78dSCristian Dumitrescu 	if (strcmp(tokens[4], "stats")) {
241112eda78dSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "stats");
241212eda78dSCristian Dumitrescu 		return;
241312eda78dSCristian Dumitrescu 	}
241412eda78dSCristian Dumitrescu 
241512eda78dSCristian Dumitrescu 	/* index. */
241612eda78dSCristian Dumitrescu 	if (!strcmp(tokens[5], "index")) {
241712eda78dSCristian Dumitrescu 		uint32_t idx0 = 0, idx1 = 0;
241812eda78dSCristian Dumitrescu 
241912eda78dSCristian Dumitrescu 		if (n_tokens != 10) {
242012eda78dSCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
242112eda78dSCristian Dumitrescu 			return;
242212eda78dSCristian Dumitrescu 		}
242312eda78dSCristian Dumitrescu 
242412eda78dSCristian Dumitrescu 		if (strcmp(tokens[6], "from")) {
2425f38913b7SCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_NOT_FOUND, "from");
2426f38913b7SCristian Dumitrescu 			return;
2427f38913b7SCristian Dumitrescu 		}
2428f38913b7SCristian Dumitrescu 
242912eda78dSCristian Dumitrescu 		if (parser_read_uint32(&idx0, tokens[7])) {
2430f38913b7SCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_INVALID, "index0");
2431f38913b7SCristian Dumitrescu 			return;
2432f38913b7SCristian Dumitrescu 		}
2433f38913b7SCristian Dumitrescu 
243412eda78dSCristian Dumitrescu 		if (strcmp(tokens[8], "to")) {
2435f38913b7SCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_NOT_FOUND, "to");
2436f38913b7SCristian Dumitrescu 			return;
2437f38913b7SCristian Dumitrescu 		}
2438f38913b7SCristian Dumitrescu 
243912eda78dSCristian Dumitrescu 		if (parser_read_uint32(&idx1, tokens[9]) || (idx1 < idx0)) {
2440f38913b7SCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_INVALID, "index1");
2441f38913b7SCristian Dumitrescu 			return;
2442f38913b7SCristian Dumitrescu 		}
2443f38913b7SCristian Dumitrescu 
2444f38913b7SCristian Dumitrescu 		/* Table header. */
2445f38913b7SCristian Dumitrescu 		snprintf(out, out_size, "+-%7s-+-%16s-+-%16s-+-%16s-+-%16s-+-%16s-+-%16s-+\n",
2446f38913b7SCristian Dumitrescu 			 "-------",
2447f38913b7SCristian Dumitrescu 			 "----------------", "----------------", "----------------",
2448f38913b7SCristian Dumitrescu 			 "----------------", "----------------", "----------------");
2449f38913b7SCristian Dumitrescu 		out_size -= strlen(out);
2450f38913b7SCristian Dumitrescu 		out += strlen(out);
2451f38913b7SCristian Dumitrescu 
2452f38913b7SCristian Dumitrescu 		snprintf(out, out_size, "| %4s | %16s | %16s | %16s | %16s | %16s | %16s |\n",
2453f38913b7SCristian Dumitrescu 			 "METER #",
2454f38913b7SCristian Dumitrescu 			 "GREEN (packets)", "YELLOW (packets)", "RED (packets)",
2455f38913b7SCristian Dumitrescu 			 "GREEN (bytes)", "YELLOW (bytes)", "RED (bytes)");
2456f38913b7SCristian Dumitrescu 		out_size -= strlen(out);
2457f38913b7SCristian Dumitrescu 		out += strlen(out);
2458f38913b7SCristian Dumitrescu 
2459f38913b7SCristian Dumitrescu 		snprintf(out, out_size, "+-%7s-+-%16s-+-%16s-+-%16s-+-%16s-+-%16s-+-%16s-+\n",
2460f38913b7SCristian Dumitrescu 			 "-------",
2461f38913b7SCristian Dumitrescu 			 "----------------", "----------------", "----------------",
2462f38913b7SCristian Dumitrescu 			 "----------------", "----------------", "----------------");
2463f38913b7SCristian Dumitrescu 		out_size -= strlen(out);
2464f38913b7SCristian Dumitrescu 		out += strlen(out);
2465f38913b7SCristian Dumitrescu 
2466f38913b7SCristian Dumitrescu 		/* Table rows. */
2467f38913b7SCristian Dumitrescu 		for ( ; idx0 <= idx1; idx0++) {
2468f38913b7SCristian Dumitrescu 			int status;
2469f38913b7SCristian Dumitrescu 
2470b9559f94SCristian Dumitrescu 			status = rte_swx_ctl_meter_stats_read(p, name, idx0, &stats);
2471f38913b7SCristian Dumitrescu 			if (status) {
247212eda78dSCristian Dumitrescu 				snprintf(out, out_size, "Meter stats error at index %u.\n", idx0);
2473f38913b7SCristian Dumitrescu 				out_size -= strlen(out);
2474f38913b7SCristian Dumitrescu 				out += strlen(out);
2475f38913b7SCristian Dumitrescu 				return;
2476f38913b7SCristian Dumitrescu 			}
2477f38913b7SCristian Dumitrescu 
2478f38913b7SCristian Dumitrescu 			snprintf(out, out_size, "| %7d | %16" PRIx64 " | %16" PRIx64 " | %16" PRIx64
2479f38913b7SCristian Dumitrescu 				 " | %16" PRIx64 " | %16" PRIx64 " | %16" PRIx64 " |\n",
2480f38913b7SCristian Dumitrescu 				 idx0,
2481f38913b7SCristian Dumitrescu 				 stats.n_pkts[RTE_COLOR_GREEN],
2482f38913b7SCristian Dumitrescu 				 stats.n_pkts[RTE_COLOR_YELLOW],
2483f38913b7SCristian Dumitrescu 				 stats.n_pkts[RTE_COLOR_RED],
2484f38913b7SCristian Dumitrescu 				 stats.n_bytes[RTE_COLOR_GREEN],
2485f38913b7SCristian Dumitrescu 				 stats.n_bytes[RTE_COLOR_YELLOW],
2486f38913b7SCristian Dumitrescu 				 stats.n_bytes[RTE_COLOR_RED]);
2487f38913b7SCristian Dumitrescu 			out_size -= strlen(out);
2488f38913b7SCristian Dumitrescu 			out += strlen(out);
2489f38913b7SCristian Dumitrescu 		}
249012eda78dSCristian Dumitrescu 
249112eda78dSCristian Dumitrescu 		return;
249212eda78dSCristian Dumitrescu 	}
249312eda78dSCristian Dumitrescu 
249412eda78dSCristian Dumitrescu 	/* table. */
249512eda78dSCristian Dumitrescu 	if (!strcmp(tokens[5], "table")) {
249612eda78dSCristian Dumitrescu 		struct rte_swx_table_entry *entry;
249712eda78dSCristian Dumitrescu 		char *table_name;
249812eda78dSCristian Dumitrescu 		int status;
249912eda78dSCristian Dumitrescu 
250012eda78dSCristian Dumitrescu 		if (n_tokens < 9) {
250112eda78dSCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
250212eda78dSCristian Dumitrescu 			return;
250312eda78dSCristian Dumitrescu 		}
250412eda78dSCristian Dumitrescu 
250512eda78dSCristian Dumitrescu 		table_name = tokens[6];
250612eda78dSCristian Dumitrescu 
250712eda78dSCristian Dumitrescu 		if (strcmp(tokens[7], "match")) {
250812eda78dSCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_NOT_FOUND, "match");
250912eda78dSCristian Dumitrescu 			return;
251012eda78dSCristian Dumitrescu 		}
251112eda78dSCristian Dumitrescu 
251212eda78dSCristian Dumitrescu 		entry = parse_table_entry(ctl, table_name, &tokens[7], n_tokens - 7);
251312eda78dSCristian Dumitrescu 		if (!entry) {
251412eda78dSCristian Dumitrescu 			snprintf(out, out_size, "Invalid match tokens.\n");
251512eda78dSCristian Dumitrescu 			return;
251612eda78dSCristian Dumitrescu 		}
251712eda78dSCristian Dumitrescu 
251812eda78dSCristian Dumitrescu 		status = rte_swx_ctl_meter_stats_read_with_key(p,
251912eda78dSCristian Dumitrescu 							name,
252012eda78dSCristian Dumitrescu 							table_name,
252112eda78dSCristian Dumitrescu 							entry->key,
252212eda78dSCristian Dumitrescu 							&stats);
252312eda78dSCristian Dumitrescu 		table_entry_free(entry);
252412eda78dSCristian Dumitrescu 		if (status) {
252512eda78dSCristian Dumitrescu 			snprintf(out, out_size, "Command failed.\n");
252612eda78dSCristian Dumitrescu 			return;
252712eda78dSCristian Dumitrescu 		}
252812eda78dSCristian Dumitrescu 
252912eda78dSCristian Dumitrescu 		/* Table header. */
253012eda78dSCristian Dumitrescu 		snprintf(out, out_size, "+-%7s-+-%16s-+-%16s-+-%16s-+-%16s-+-%16s-+-%16s-+\n",
253112eda78dSCristian Dumitrescu 			 "-------",
253212eda78dSCristian Dumitrescu 			 "----------------", "----------------", "----------------",
253312eda78dSCristian Dumitrescu 			 "----------------", "----------------", "----------------");
253412eda78dSCristian Dumitrescu 		out_size -= strlen(out);
253512eda78dSCristian Dumitrescu 		out += strlen(out);
253612eda78dSCristian Dumitrescu 
253712eda78dSCristian Dumitrescu 		snprintf(out, out_size, "| %4s | %16s | %16s | %16s | %16s | %16s | %16s |\n",
253812eda78dSCristian Dumitrescu 			 "METER #",
253912eda78dSCristian Dumitrescu 			 "GREEN (packets)", "YELLOW (packets)", "RED (packets)",
254012eda78dSCristian Dumitrescu 			 "GREEN (bytes)", "YELLOW (bytes)", "RED (bytes)");
254112eda78dSCristian Dumitrescu 		out_size -= strlen(out);
254212eda78dSCristian Dumitrescu 		out += strlen(out);
254312eda78dSCristian Dumitrescu 
254412eda78dSCristian Dumitrescu 		snprintf(out, out_size, "+-%7s-+-%16s-+-%16s-+-%16s-+-%16s-+-%16s-+-%16s-+\n",
254512eda78dSCristian Dumitrescu 			 "-------",
254612eda78dSCristian Dumitrescu 			 "----------------", "----------------", "----------------",
254712eda78dSCristian Dumitrescu 			 "----------------", "----------------", "----------------");
254812eda78dSCristian Dumitrescu 		out_size -= strlen(out);
254912eda78dSCristian Dumitrescu 		out += strlen(out);
255012eda78dSCristian Dumitrescu 
255112eda78dSCristian Dumitrescu 		/* Table row. */
255212eda78dSCristian Dumitrescu 		snprintf(out, out_size, "| %7d | %16" PRIx64 " | %16" PRIx64 " | %16" PRIx64
255312eda78dSCristian Dumitrescu 			 " | %16" PRIx64 " | %16" PRIx64 " | %16" PRIx64 " |\n",
255412eda78dSCristian Dumitrescu 			 0,
255512eda78dSCristian Dumitrescu 			 stats.n_pkts[RTE_COLOR_GREEN],
255612eda78dSCristian Dumitrescu 			 stats.n_pkts[RTE_COLOR_YELLOW],
255712eda78dSCristian Dumitrescu 			 stats.n_pkts[RTE_COLOR_RED],
255812eda78dSCristian Dumitrescu 			 stats.n_bytes[RTE_COLOR_GREEN],
255912eda78dSCristian Dumitrescu 			 stats.n_bytes[RTE_COLOR_YELLOW],
256012eda78dSCristian Dumitrescu 			 stats.n_bytes[RTE_COLOR_RED]);
256112eda78dSCristian Dumitrescu 		out_size -= strlen(out);
256212eda78dSCristian Dumitrescu 		out += strlen(out);
256312eda78dSCristian Dumitrescu 
256412eda78dSCristian Dumitrescu 		return;
256512eda78dSCristian Dumitrescu 	}
256612eda78dSCristian Dumitrescu 
256712eda78dSCristian Dumitrescu 	/* anything else. */
256812eda78dSCristian Dumitrescu 	snprintf(out, out_size, "Invalid token %s\n.", tokens[5]);
256912eda78dSCristian Dumitrescu 	return;
2570f38913b7SCristian Dumitrescu }
2571f38913b7SCristian Dumitrescu 
25725074e1d5SCristian Dumitrescu static const char cmd_pipeline_stats_help[] =
25735074e1d5SCristian Dumitrescu "pipeline <pipeline_name> stats\n";
25745074e1d5SCristian Dumitrescu 
25755074e1d5SCristian Dumitrescu static void
25765074e1d5SCristian Dumitrescu cmd_pipeline_stats(char **tokens,
25775074e1d5SCristian Dumitrescu 	uint32_t n_tokens,
25785074e1d5SCristian Dumitrescu 	char *out,
25795074e1d5SCristian Dumitrescu 	size_t out_size,
2580b9559f94SCristian Dumitrescu 	void *obj __rte_unused)
25815074e1d5SCristian Dumitrescu {
25825074e1d5SCristian Dumitrescu 	struct rte_swx_ctl_pipeline_info info;
2583b9559f94SCristian Dumitrescu 	struct rte_swx_pipeline *p;
25845074e1d5SCristian Dumitrescu 	uint32_t i;
25855074e1d5SCristian Dumitrescu 	int status;
25865074e1d5SCristian Dumitrescu 
25875074e1d5SCristian Dumitrescu 	if (n_tokens != 3) {
25885074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
25895074e1d5SCristian Dumitrescu 		return;
25905074e1d5SCristian Dumitrescu 	}
25915074e1d5SCristian Dumitrescu 
2592b9559f94SCristian Dumitrescu 	p = rte_swx_pipeline_find(tokens[1]);
2593b9559f94SCristian Dumitrescu 	if (!p) {
25945074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
25955074e1d5SCristian Dumitrescu 		return;
25965074e1d5SCristian Dumitrescu 	}
25975074e1d5SCristian Dumitrescu 
25985074e1d5SCristian Dumitrescu 	if (strcmp(tokens[2], "stats")) {
25995074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "stats");
26005074e1d5SCristian Dumitrescu 		return;
26015074e1d5SCristian Dumitrescu 	}
26025074e1d5SCristian Dumitrescu 
2603b9559f94SCristian Dumitrescu 	status = rte_swx_ctl_pipeline_info_get(p, &info);
26045074e1d5SCristian Dumitrescu 	if (status) {
26055074e1d5SCristian Dumitrescu 		snprintf(out, out_size, "Pipeline info get error.");
26065074e1d5SCristian Dumitrescu 		return;
26075074e1d5SCristian Dumitrescu 	}
26085074e1d5SCristian Dumitrescu 
26095074e1d5SCristian Dumitrescu 	snprintf(out, out_size, "Input ports:\n");
26105074e1d5SCristian Dumitrescu 	out_size -= strlen(out);
26115074e1d5SCristian Dumitrescu 	out += strlen(out);
26125074e1d5SCristian Dumitrescu 
26135074e1d5SCristian Dumitrescu 	for (i = 0; i < info.n_ports_in; i++) {
26145074e1d5SCristian Dumitrescu 		struct rte_swx_port_in_stats stats;
26155074e1d5SCristian Dumitrescu 
2616b9559f94SCristian Dumitrescu 		rte_swx_ctl_pipeline_port_in_stats_read(p, i, &stats);
26175074e1d5SCristian Dumitrescu 
26185074e1d5SCristian Dumitrescu 		snprintf(out, out_size, "\tPort %u:"
26195074e1d5SCristian Dumitrescu 			" packets %" PRIu64
26205074e1d5SCristian Dumitrescu 			" bytes %" PRIu64
26215074e1d5SCristian Dumitrescu 			" empty %" PRIu64 "\n",
26225074e1d5SCristian Dumitrescu 			i, stats.n_pkts, stats.n_bytes, stats.n_empty);
26235074e1d5SCristian Dumitrescu 		out_size -= strlen(out);
26245074e1d5SCristian Dumitrescu 		out += strlen(out);
26255074e1d5SCristian Dumitrescu 	}
26265074e1d5SCristian Dumitrescu 
2627742b0a57SCristian Dumitrescu 	snprintf(out, out_size, "\nOutput ports:\n");
26285074e1d5SCristian Dumitrescu 	out_size -= strlen(out);
26295074e1d5SCristian Dumitrescu 	out += strlen(out);
26305074e1d5SCristian Dumitrescu 
26315074e1d5SCristian Dumitrescu 	for (i = 0; i < info.n_ports_out; i++) {
26325074e1d5SCristian Dumitrescu 		struct rte_swx_port_out_stats stats;
26335074e1d5SCristian Dumitrescu 
2634b9559f94SCristian Dumitrescu 		rte_swx_ctl_pipeline_port_out_stats_read(p, i, &stats);
26355074e1d5SCristian Dumitrescu 
263696b37959SCristian Dumitrescu 		if (i != info.n_ports_out - 1)
263717225455SCristian Dumitrescu 			snprintf(out, out_size, "\tPort %u:", i);
263896b37959SCristian Dumitrescu 		else
263917225455SCristian Dumitrescu 			snprintf(out, out_size, "\tDROP:");
264017225455SCristian Dumitrescu 
264117225455SCristian Dumitrescu 		out_size -= strlen(out);
264217225455SCristian Dumitrescu 		out += strlen(out);
264317225455SCristian Dumitrescu 
264417225455SCristian Dumitrescu 		snprintf(out,
264517225455SCristian Dumitrescu 			out_size,
264696b37959SCristian Dumitrescu 			" packets %" PRIu64
264717225455SCristian Dumitrescu 			" bytes %" PRIu64
264867f707b3SCristian Dumitrescu 			" packets dropped %" PRIu64
264967f707b3SCristian Dumitrescu 			" bytes dropped %" PRIu64
265017225455SCristian Dumitrescu 			" clone %" PRIu64
265117225455SCristian Dumitrescu 			" clonerr %" PRIu64 "\n",
265217225455SCristian Dumitrescu 			stats.n_pkts,
265317225455SCristian Dumitrescu 			stats.n_bytes,
265467f707b3SCristian Dumitrescu 			stats.n_pkts_drop,
265567f707b3SCristian Dumitrescu 			stats.n_bytes_drop,
265617225455SCristian Dumitrescu 			stats.n_pkts_clone,
265717225455SCristian Dumitrescu 			stats.n_pkts_clone_err);
265896b37959SCristian Dumitrescu 
26595074e1d5SCristian Dumitrescu 		out_size -= strlen(out);
26605074e1d5SCristian Dumitrescu 		out += strlen(out);
26615074e1d5SCristian Dumitrescu 	}
2662742b0a57SCristian Dumitrescu 
2663742b0a57SCristian Dumitrescu 	snprintf(out, out_size, "\nTables:\n");
2664742b0a57SCristian Dumitrescu 	out_size -= strlen(out);
2665742b0a57SCristian Dumitrescu 	out += strlen(out);
2666742b0a57SCristian Dumitrescu 
2667742b0a57SCristian Dumitrescu 	for (i = 0; i < info.n_tables; i++) {
2668742b0a57SCristian Dumitrescu 		struct rte_swx_ctl_table_info table_info;
2669742b0a57SCristian Dumitrescu 		uint64_t n_pkts_action[info.n_actions];
2670742b0a57SCristian Dumitrescu 		struct rte_swx_table_stats stats = {
2671742b0a57SCristian Dumitrescu 			.n_pkts_hit = 0,
2672742b0a57SCristian Dumitrescu 			.n_pkts_miss = 0,
2673742b0a57SCristian Dumitrescu 			.n_pkts_action = n_pkts_action,
2674742b0a57SCristian Dumitrescu 		};
2675742b0a57SCristian Dumitrescu 		uint32_t j;
2676742b0a57SCristian Dumitrescu 
2677b9559f94SCristian Dumitrescu 		status = rte_swx_ctl_table_info_get(p, i, &table_info);
2678742b0a57SCristian Dumitrescu 		if (status) {
2679742b0a57SCristian Dumitrescu 			snprintf(out, out_size, "Table info get error.");
2680742b0a57SCristian Dumitrescu 			return;
2681742b0a57SCristian Dumitrescu 		}
2682742b0a57SCristian Dumitrescu 
2683b9559f94SCristian Dumitrescu 		status = rte_swx_ctl_pipeline_table_stats_read(p, table_info.name, &stats);
2684742b0a57SCristian Dumitrescu 		if (status) {
2685742b0a57SCristian Dumitrescu 			snprintf(out, out_size, "Table stats read error.");
2686742b0a57SCristian Dumitrescu 			return;
2687742b0a57SCristian Dumitrescu 		}
2688742b0a57SCristian Dumitrescu 
2689742b0a57SCristian Dumitrescu 		snprintf(out, out_size, "\tTable %s:\n"
2690742b0a57SCristian Dumitrescu 			"\t\tHit (packets): %" PRIu64 "\n"
2691742b0a57SCristian Dumitrescu 			"\t\tMiss (packets): %" PRIu64 "\n",
2692742b0a57SCristian Dumitrescu 			table_info.name,
2693742b0a57SCristian Dumitrescu 			stats.n_pkts_hit,
2694742b0a57SCristian Dumitrescu 			stats.n_pkts_miss);
2695742b0a57SCristian Dumitrescu 		out_size -= strlen(out);
2696742b0a57SCristian Dumitrescu 		out += strlen(out);
2697742b0a57SCristian Dumitrescu 
2698742b0a57SCristian Dumitrescu 		for (j = 0; j < info.n_actions; j++) {
2699742b0a57SCristian Dumitrescu 			struct rte_swx_ctl_action_info action_info;
2700742b0a57SCristian Dumitrescu 
2701b9559f94SCristian Dumitrescu 			status = rte_swx_ctl_action_info_get(p, j, &action_info);
2702742b0a57SCristian Dumitrescu 			if (status) {
2703742b0a57SCristian Dumitrescu 				snprintf(out, out_size, "Action info get error.");
2704742b0a57SCristian Dumitrescu 				return;
2705742b0a57SCristian Dumitrescu 			}
2706742b0a57SCristian Dumitrescu 
2707742b0a57SCristian Dumitrescu 			snprintf(out, out_size, "\t\tAction %s (packets): %" PRIu64 "\n",
2708742b0a57SCristian Dumitrescu 				action_info.name,
2709742b0a57SCristian Dumitrescu 				stats.n_pkts_action[j]);
2710742b0a57SCristian Dumitrescu 			out_size -= strlen(out);
2711742b0a57SCristian Dumitrescu 			out += strlen(out);
2712742b0a57SCristian Dumitrescu 		}
2713742b0a57SCristian Dumitrescu 	}
27148bd4862fSCristian Dumitrescu 
27158bd4862fSCristian Dumitrescu 	snprintf(out, out_size, "\nLearner tables:\n");
27168bd4862fSCristian Dumitrescu 	out_size -= strlen(out);
27178bd4862fSCristian Dumitrescu 	out += strlen(out);
27188bd4862fSCristian Dumitrescu 
27198bd4862fSCristian Dumitrescu 	for (i = 0; i < info.n_learners; i++) {
27208bd4862fSCristian Dumitrescu 		struct rte_swx_ctl_learner_info learner_info;
27218bd4862fSCristian Dumitrescu 		uint64_t n_pkts_action[info.n_actions];
27228bd4862fSCristian Dumitrescu 		struct rte_swx_learner_stats stats = {
27238bd4862fSCristian Dumitrescu 			.n_pkts_hit = 0,
27248bd4862fSCristian Dumitrescu 			.n_pkts_miss = 0,
27258bd4862fSCristian Dumitrescu 			.n_pkts_action = n_pkts_action,
27268bd4862fSCristian Dumitrescu 		};
27278bd4862fSCristian Dumitrescu 		uint32_t j;
27288bd4862fSCristian Dumitrescu 
2729b9559f94SCristian Dumitrescu 		status = rte_swx_ctl_learner_info_get(p, i, &learner_info);
27308bd4862fSCristian Dumitrescu 		if (status) {
27318bd4862fSCristian Dumitrescu 			snprintf(out, out_size, "Learner table info get error.");
27328bd4862fSCristian Dumitrescu 			return;
27338bd4862fSCristian Dumitrescu 		}
27348bd4862fSCristian Dumitrescu 
2735b9559f94SCristian Dumitrescu 		status = rte_swx_ctl_pipeline_learner_stats_read(p, learner_info.name, &stats);
27368bd4862fSCristian Dumitrescu 		if (status) {
27378bd4862fSCristian Dumitrescu 			snprintf(out, out_size, "Learner table stats read error.");
27388bd4862fSCristian Dumitrescu 			return;
27398bd4862fSCristian Dumitrescu 		}
27408bd4862fSCristian Dumitrescu 
27418bd4862fSCristian Dumitrescu 		snprintf(out, out_size, "\tLearner table %s:\n"
27428bd4862fSCristian Dumitrescu 			"\t\tHit (packets): %" PRIu64 "\n"
27438bd4862fSCristian Dumitrescu 			"\t\tMiss (packets): %" PRIu64 "\n"
27448bd4862fSCristian Dumitrescu 			"\t\tLearn OK (packets): %" PRIu64 "\n"
27458bd4862fSCristian Dumitrescu 			"\t\tLearn error (packets): %" PRIu64 "\n"
274680dd28afSCristian Dumitrescu 			"\t\tRearm (packets): %" PRIu64 "\n"
27478bd4862fSCristian Dumitrescu 			"\t\tForget (packets): %" PRIu64 "\n",
27488bd4862fSCristian Dumitrescu 			learner_info.name,
27498bd4862fSCristian Dumitrescu 			stats.n_pkts_hit,
27508bd4862fSCristian Dumitrescu 			stats.n_pkts_miss,
27518bd4862fSCristian Dumitrescu 			stats.n_pkts_learn_ok,
27528bd4862fSCristian Dumitrescu 			stats.n_pkts_learn_err,
275380dd28afSCristian Dumitrescu 			stats.n_pkts_rearm,
27548bd4862fSCristian Dumitrescu 			stats.n_pkts_forget);
27558bd4862fSCristian Dumitrescu 		out_size -= strlen(out);
27568bd4862fSCristian Dumitrescu 		out += strlen(out);
27578bd4862fSCristian Dumitrescu 
27588bd4862fSCristian Dumitrescu 		for (j = 0; j < info.n_actions; j++) {
27598bd4862fSCristian Dumitrescu 			struct rte_swx_ctl_action_info action_info;
27608bd4862fSCristian Dumitrescu 
2761b9559f94SCristian Dumitrescu 			status = rte_swx_ctl_action_info_get(p, j, &action_info);
27628bd4862fSCristian Dumitrescu 			if (status) {
27638bd4862fSCristian Dumitrescu 				snprintf(out, out_size, "Action info get error.");
27648bd4862fSCristian Dumitrescu 				return;
27658bd4862fSCristian Dumitrescu 			}
27668bd4862fSCristian Dumitrescu 
27678bd4862fSCristian Dumitrescu 			snprintf(out, out_size, "\t\tAction %s (packets): %" PRIu64 "\n",
27688bd4862fSCristian Dumitrescu 				action_info.name,
27698bd4862fSCristian Dumitrescu 				stats.n_pkts_action[j]);
27708bd4862fSCristian Dumitrescu 			out_size -= strlen(out);
27718bd4862fSCristian Dumitrescu 			out += strlen(out);
27728bd4862fSCristian Dumitrescu 		}
27738bd4862fSCristian Dumitrescu 	}
27745074e1d5SCristian Dumitrescu }
27755074e1d5SCristian Dumitrescu 
277617225455SCristian Dumitrescu static const char cmd_pipeline_mirror_session_help[] =
277717225455SCristian Dumitrescu "pipeline <pipeline_name> mirror session <session_id> port <port_id> clone fast | slow "
277817225455SCristian Dumitrescu "truncate <truncation_length>\n";
277917225455SCristian Dumitrescu 
278017225455SCristian Dumitrescu static void
278117225455SCristian Dumitrescu cmd_pipeline_mirror_session(char **tokens,
278217225455SCristian Dumitrescu 	uint32_t n_tokens,
278317225455SCristian Dumitrescu 	char *out,
278417225455SCristian Dumitrescu 	size_t out_size,
2785b9559f94SCristian Dumitrescu 	void *obj __rte_unused)
278617225455SCristian Dumitrescu {
278717225455SCristian Dumitrescu 	struct rte_swx_pipeline_mirroring_session_params params;
2788b9559f94SCristian Dumitrescu 	struct rte_swx_pipeline *p;
278977dd857dSAli Alnubani 	uint32_t session_id = 0;
279017225455SCristian Dumitrescu 	int status;
279117225455SCristian Dumitrescu 
279217225455SCristian Dumitrescu 	if (n_tokens != 11) {
279317225455SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
279417225455SCristian Dumitrescu 		return;
279517225455SCristian Dumitrescu 	}
279617225455SCristian Dumitrescu 
279717225455SCristian Dumitrescu 	if (strcmp(tokens[0], "pipeline")) {
279817225455SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pipeline");
279917225455SCristian Dumitrescu 		return;
280017225455SCristian Dumitrescu 	}
280117225455SCristian Dumitrescu 
2802b9559f94SCristian Dumitrescu 	p = rte_swx_pipeline_find(tokens[1]);
2803b9559f94SCristian Dumitrescu 	if (!p) {
280417225455SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
280517225455SCristian Dumitrescu 		return;
280617225455SCristian Dumitrescu 	}
280717225455SCristian Dumitrescu 
280817225455SCristian Dumitrescu 	if (strcmp(tokens[2], "mirror")) {
280917225455SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "mirror");
281017225455SCristian Dumitrescu 		return;
281117225455SCristian Dumitrescu 	}
281217225455SCristian Dumitrescu 
281317225455SCristian Dumitrescu 	if (strcmp(tokens[3], "session")) {
281417225455SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "session");
281517225455SCristian Dumitrescu 		return;
281617225455SCristian Dumitrescu 	}
281717225455SCristian Dumitrescu 
281817225455SCristian Dumitrescu 	if (parser_read_uint32(&session_id, tokens[4])) {
281917225455SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "session_id");
282017225455SCristian Dumitrescu 		return;
282117225455SCristian Dumitrescu 	}
282217225455SCristian Dumitrescu 
282317225455SCristian Dumitrescu 	if (strcmp(tokens[5], "port")) {
282417225455SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
282517225455SCristian Dumitrescu 		return;
282617225455SCristian Dumitrescu 	}
282717225455SCristian Dumitrescu 
282817225455SCristian Dumitrescu 	if (parser_read_uint32(&params.port_id, tokens[6])) {
282917225455SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
283017225455SCristian Dumitrescu 		return;
283117225455SCristian Dumitrescu 	}
283217225455SCristian Dumitrescu 
283317225455SCristian Dumitrescu 	if (strcmp(tokens[7], "clone")) {
283417225455SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "clone");
283517225455SCristian Dumitrescu 		return;
283617225455SCristian Dumitrescu 	}
283717225455SCristian Dumitrescu 
283817225455SCristian Dumitrescu 	if (!strcmp(tokens[8], "fast"))
283917225455SCristian Dumitrescu 		params.fast_clone = 1;
284017225455SCristian Dumitrescu 	else if (!strcmp(tokens[8], "slow"))
284117225455SCristian Dumitrescu 		params.fast_clone = 0;
284217225455SCristian Dumitrescu 	else {
284317225455SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "clone");
284417225455SCristian Dumitrescu 		return;
284517225455SCristian Dumitrescu 	}
284617225455SCristian Dumitrescu 
284717225455SCristian Dumitrescu 	if (strcmp(tokens[9], "truncate")) {
284817225455SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "truncate");
284917225455SCristian Dumitrescu 		return;
285017225455SCristian Dumitrescu 	}
285117225455SCristian Dumitrescu 
285217225455SCristian Dumitrescu 	if (parser_read_uint32(&params.truncation_length, tokens[10])) {
285317225455SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "truncation_length");
285417225455SCristian Dumitrescu 		return;
285517225455SCristian Dumitrescu 	}
285617225455SCristian Dumitrescu 
2857b9559f94SCristian Dumitrescu 	status = rte_swx_ctl_pipeline_mirroring_session_set(p, session_id, &params);
285817225455SCristian Dumitrescu 	if (status) {
285917225455SCristian Dumitrescu 		snprintf(out, out_size, "Command failed!\n");
286017225455SCristian Dumitrescu 		return;
286117225455SCristian Dumitrescu 	}
286217225455SCristian Dumitrescu }
286317225455SCristian Dumitrescu 
28645074e1d5SCristian Dumitrescu static const char cmd_thread_pipeline_enable_help[] =
2865b9559f94SCristian Dumitrescu "thread <thread_id> pipeline <pipeline_name> enable [ period <timer_period_ms> ]\n";
2866b9559f94SCristian Dumitrescu 
2867b9559f94SCristian Dumitrescu #ifndef TIMER_PERIOD_MS_DEFAULT
2868b9559f94SCristian Dumitrescu #define TIMER_PERIOD_MS_DEFAULT 10
2869b9559f94SCristian Dumitrescu #endif
28705074e1d5SCristian Dumitrescu 
28715074e1d5SCristian Dumitrescu static void
28725074e1d5SCristian Dumitrescu cmd_thread_pipeline_enable(char **tokens,
28735074e1d5SCristian Dumitrescu 	uint32_t n_tokens,
28745074e1d5SCristian Dumitrescu 	char *out,
28755074e1d5SCristian Dumitrescu 	size_t out_size,
2876b9559f94SCristian Dumitrescu 	void *obj __rte_unused)
28775074e1d5SCristian Dumitrescu {
28785074e1d5SCristian Dumitrescu 	char *pipeline_name;
2879b9559f94SCristian Dumitrescu 	struct rte_swx_pipeline *p;
2880b9559f94SCristian Dumitrescu 	uint32_t thread_id, timer_period_ms = TIMER_PERIOD_MS_DEFAULT;
28815074e1d5SCristian Dumitrescu 	int status;
28825074e1d5SCristian Dumitrescu 
2883b9559f94SCristian Dumitrescu 	if ((n_tokens != 5) && (n_tokens != 7)) {
28845074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
28855074e1d5SCristian Dumitrescu 		return;
28865074e1d5SCristian Dumitrescu 	}
28875074e1d5SCristian Dumitrescu 
28885074e1d5SCristian Dumitrescu 	if (parser_read_uint32(&thread_id, tokens[1]) != 0) {
28895074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "thread_id");
28905074e1d5SCristian Dumitrescu 		return;
28915074e1d5SCristian Dumitrescu 	}
28925074e1d5SCristian Dumitrescu 
28935074e1d5SCristian Dumitrescu 	if (strcmp(tokens[2], "pipeline") != 0) {
28945074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pipeline");
28955074e1d5SCristian Dumitrescu 		return;
28965074e1d5SCristian Dumitrescu 	}
28975074e1d5SCristian Dumitrescu 
28985074e1d5SCristian Dumitrescu 	pipeline_name = tokens[3];
2899b9559f94SCristian Dumitrescu 	p = rte_swx_pipeline_find(pipeline_name);
2900b9559f94SCristian Dumitrescu 	if (!p) {
29015074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
29025074e1d5SCristian Dumitrescu 		return;
29035074e1d5SCristian Dumitrescu 	}
29045074e1d5SCristian Dumitrescu 
29055074e1d5SCristian Dumitrescu 	if (strcmp(tokens[4], "enable") != 0) {
29065074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "enable");
29075074e1d5SCristian Dumitrescu 		return;
29085074e1d5SCristian Dumitrescu 	}
29095074e1d5SCristian Dumitrescu 
2910b9559f94SCristian Dumitrescu 	if (n_tokens == 7) {
2911b9559f94SCristian Dumitrescu 		if (strcmp(tokens[5], "period") != 0) {
2912b9559f94SCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_NOT_FOUND, "period");
2913b9559f94SCristian Dumitrescu 			return;
2914b9559f94SCristian Dumitrescu 		}
2915b9559f94SCristian Dumitrescu 
2916b9559f94SCristian Dumitrescu 		if (parser_read_uint32(&timer_period_ms, tokens[6]) != 0) {
2917b9559f94SCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_INVALID, "timer_period_ms");
2918b9559f94SCristian Dumitrescu 			return;
2919b9559f94SCristian Dumitrescu 		}
2920b9559f94SCristian Dumitrescu 	}
2921b9559f94SCristian Dumitrescu 
2922b9559f94SCristian Dumitrescu 	status = thread_pipeline_enable(thread_id, p, timer_period_ms);
29235074e1d5SCristian Dumitrescu 	if (status) {
29245074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_CMD_FAIL, "thread pipeline enable");
29255074e1d5SCristian Dumitrescu 		return;
29265074e1d5SCristian Dumitrescu 	}
29275074e1d5SCristian Dumitrescu }
29285074e1d5SCristian Dumitrescu 
29295074e1d5SCristian Dumitrescu static const char cmd_thread_pipeline_disable_help[] =
29305074e1d5SCristian Dumitrescu "thread <thread_id> pipeline <pipeline_name> disable\n";
29315074e1d5SCristian Dumitrescu 
29325074e1d5SCristian Dumitrescu static void
29335074e1d5SCristian Dumitrescu cmd_thread_pipeline_disable(char **tokens,
29345074e1d5SCristian Dumitrescu 	uint32_t n_tokens,
29355074e1d5SCristian Dumitrescu 	char *out,
29365074e1d5SCristian Dumitrescu 	size_t out_size,
2937b9559f94SCristian Dumitrescu 	void *obj __rte_unused)
29385074e1d5SCristian Dumitrescu {
2939b9559f94SCristian Dumitrescu 	struct rte_swx_pipeline *p;
29405074e1d5SCristian Dumitrescu 	char *pipeline_name;
29415074e1d5SCristian Dumitrescu 	uint32_t thread_id;
29425074e1d5SCristian Dumitrescu 	int status;
29435074e1d5SCristian Dumitrescu 
29445074e1d5SCristian Dumitrescu 	if (n_tokens != 5) {
29455074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
29465074e1d5SCristian Dumitrescu 		return;
29475074e1d5SCristian Dumitrescu 	}
29485074e1d5SCristian Dumitrescu 
29495074e1d5SCristian Dumitrescu 	if (parser_read_uint32(&thread_id, tokens[1]) != 0) {
29505074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "thread_id");
29515074e1d5SCristian Dumitrescu 		return;
29525074e1d5SCristian Dumitrescu 	}
29535074e1d5SCristian Dumitrescu 
29545074e1d5SCristian Dumitrescu 	if (strcmp(tokens[2], "pipeline") != 0) {
29555074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pipeline");
29565074e1d5SCristian Dumitrescu 		return;
29575074e1d5SCristian Dumitrescu 	}
29585074e1d5SCristian Dumitrescu 
29595074e1d5SCristian Dumitrescu 	pipeline_name = tokens[3];
2960b9559f94SCristian Dumitrescu 	p = rte_swx_pipeline_find(pipeline_name);
2961b9559f94SCristian Dumitrescu 	if (!p) {
29625074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
29635074e1d5SCristian Dumitrescu 		return;
29645074e1d5SCristian Dumitrescu 	}
29655074e1d5SCristian Dumitrescu 
29665074e1d5SCristian Dumitrescu 	if (strcmp(tokens[4], "disable") != 0) {
29675074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "disable");
29685074e1d5SCristian Dumitrescu 		return;
29695074e1d5SCristian Dumitrescu 	}
29705074e1d5SCristian Dumitrescu 
2971b9559f94SCristian Dumitrescu 	status = thread_pipeline_disable(thread_id, p);
29725074e1d5SCristian Dumitrescu 	if (status) {
29735074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_CMD_FAIL,
29745074e1d5SCristian Dumitrescu 			"thread pipeline disable");
29755074e1d5SCristian Dumitrescu 		return;
29765074e1d5SCristian Dumitrescu 	}
29775074e1d5SCristian Dumitrescu }
29785074e1d5SCristian Dumitrescu 
29795074e1d5SCristian Dumitrescu static void
29805074e1d5SCristian Dumitrescu cmd_help(char **tokens,
29815074e1d5SCristian Dumitrescu 	 uint32_t n_tokens,
29825074e1d5SCristian Dumitrescu 	 char *out,
29835074e1d5SCristian Dumitrescu 	 size_t out_size,
29845074e1d5SCristian Dumitrescu 	 void *arg __rte_unused)
29855074e1d5SCristian Dumitrescu {
29865074e1d5SCristian Dumitrescu 	tokens++;
29875074e1d5SCristian Dumitrescu 	n_tokens--;
29885074e1d5SCristian Dumitrescu 
29895074e1d5SCristian Dumitrescu 	if (n_tokens == 0) {
29905074e1d5SCristian Dumitrescu 		snprintf(out, out_size,
29917fef9ef1SYogesh Jangra 			"Type 'help <command>' for command details.\n\n"
29927fef9ef1SYogesh Jangra 			"List of commands:\n"
29937fef9ef1SYogesh Jangra 			"\tmempool\n"
2994f31c80f8SCristian Dumitrescu 			"\tethdev\n"
2995*78dffe31SCristian Dumitrescu 			"\tethdev show\n"
2996607dd517SCristian Dumitrescu 			"\tring\n"
29979043f66aSCristian Dumitrescu 			"\tpipeline codegen\n"
29986bc14d9fSCristian Dumitrescu 			"\tpipeline libbuild\n"
29997fef9ef1SYogesh Jangra 			"\tpipeline build\n"
300075129cebSChurchill Khangar 			"\tpipeline table add\n"
300175129cebSChurchill Khangar 			"\tpipeline table delete\n"
300275129cebSChurchill Khangar 			"\tpipeline table default\n"
300375129cebSChurchill Khangar 			"\tpipeline table show\n"
3004598fe0ddSCristian Dumitrescu 			"\tpipeline selector group add\n"
3005598fe0ddSCristian Dumitrescu 			"\tpipeline selector group delete\n"
3006598fe0ddSCristian Dumitrescu 			"\tpipeline selector group member add\n"
3007598fe0ddSCristian Dumitrescu 			"\tpipeline selector group member delete\n"
3008598fe0ddSCristian Dumitrescu 			"\tpipeline selector show\n"
30098bd4862fSCristian Dumitrescu 			"\tpipeline learner default\n"
301075129cebSChurchill Khangar 			"\tpipeline commit\n"
301175129cebSChurchill Khangar 			"\tpipeline abort\n"
301264cfcebdSCristian Dumitrescu 			"\tpipeline regrd\n"
301364cfcebdSCristian Dumitrescu 			"\tpipeline regwr\n"
3014f38913b7SCristian Dumitrescu 			"\tpipeline meter profile add\n"
3015f38913b7SCristian Dumitrescu 			"\tpipeline meter profile delete\n"
3016f38913b7SCristian Dumitrescu 			"\tpipeline meter reset\n"
3017f38913b7SCristian Dumitrescu 			"\tpipeline meter set\n"
3018f38913b7SCristian Dumitrescu 			"\tpipeline meter stats\n"
30197fef9ef1SYogesh Jangra 			"\tpipeline stats\n"
302017225455SCristian Dumitrescu 			"\tpipeline mirror session\n"
30217fef9ef1SYogesh Jangra 			"\tthread pipeline enable\n"
30227fef9ef1SYogesh Jangra 			"\tthread pipeline disable\n\n");
30235074e1d5SCristian Dumitrescu 		return;
30245074e1d5SCristian Dumitrescu 	}
30255074e1d5SCristian Dumitrescu 
30265074e1d5SCristian Dumitrescu 	if (strcmp(tokens[0], "mempool") == 0) {
30275074e1d5SCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n", cmd_mempool_help);
30285074e1d5SCristian Dumitrescu 		return;
30295074e1d5SCristian Dumitrescu 	}
30305074e1d5SCristian Dumitrescu 
3031*78dffe31SCristian Dumitrescu 	if (!strcmp(tokens[0], "ethdev")) {
3032*78dffe31SCristian Dumitrescu 		if (n_tokens == 1) {
3033f31c80f8SCristian Dumitrescu 			snprintf(out, out_size, "\n%s\n", cmd_ethdev_help);
30345074e1d5SCristian Dumitrescu 			return;
30355074e1d5SCristian Dumitrescu 		}
30365074e1d5SCristian Dumitrescu 
3037*78dffe31SCristian Dumitrescu 		if (n_tokens == 2 && !strcmp(tokens[1], "show")) {
3038*78dffe31SCristian Dumitrescu 			snprintf(out, out_size, "\n%s\n", cmd_ethdev_show_help);
3039*78dffe31SCristian Dumitrescu 			return;
3040*78dffe31SCristian Dumitrescu 		}
3041*78dffe31SCristian Dumitrescu 	}
3042*78dffe31SCristian Dumitrescu 
304377a41301SCristian Dumitrescu 	if (strcmp(tokens[0], "ring") == 0) {
304477a41301SCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n", cmd_ring_help);
304577a41301SCristian Dumitrescu 		return;
304677a41301SCristian Dumitrescu 	}
304777a41301SCristian Dumitrescu 
30485074e1d5SCristian Dumitrescu 	if ((strcmp(tokens[0], "pipeline") == 0) &&
30499043f66aSCristian Dumitrescu 		(n_tokens == 2) && (strcmp(tokens[1], "codegen") == 0)) {
30509043f66aSCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n", cmd_pipeline_codegen_help);
30519043f66aSCristian Dumitrescu 		return;
30529043f66aSCristian Dumitrescu 	}
30539043f66aSCristian Dumitrescu 
30549043f66aSCristian Dumitrescu 	if ((strcmp(tokens[0], "pipeline") == 0) &&
30556bc14d9fSCristian Dumitrescu 		(n_tokens == 2) && (strcmp(tokens[1], "libbuild") == 0)) {
30566bc14d9fSCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n", cmd_pipeline_libbuild_help);
30576bc14d9fSCristian Dumitrescu 		return;
30586bc14d9fSCristian Dumitrescu 	}
30596bc14d9fSCristian Dumitrescu 
30606bc14d9fSCristian Dumitrescu 	if ((strcmp(tokens[0], "pipeline") == 0) &&
30617fef9ef1SYogesh Jangra 		(n_tokens == 2) && (strcmp(tokens[1], "build") == 0)) {
30625074e1d5SCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n", cmd_pipeline_build_help);
30635074e1d5SCristian Dumitrescu 		return;
30645074e1d5SCristian Dumitrescu 	}
30655074e1d5SCristian Dumitrescu 
30665074e1d5SCristian Dumitrescu 	if ((strcmp(tokens[0], "pipeline") == 0) &&
30677fef9ef1SYogesh Jangra 		(n_tokens == 3) &&
30687fef9ef1SYogesh Jangra 		(strcmp(tokens[1], "table") == 0) &&
306975129cebSChurchill Khangar 		(strcmp(tokens[2], "add") == 0)) {
30705074e1d5SCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n",
307175129cebSChurchill Khangar 			cmd_pipeline_table_add_help);
307275129cebSChurchill Khangar 		return;
307375129cebSChurchill Khangar 	}
307475129cebSChurchill Khangar 
307575129cebSChurchill Khangar 	if ((strcmp(tokens[0], "pipeline") == 0) &&
307675129cebSChurchill Khangar 		(n_tokens == 3) &&
307775129cebSChurchill Khangar 		(strcmp(tokens[1], "table") == 0) &&
307875129cebSChurchill Khangar 		(strcmp(tokens[2], "delete") == 0)) {
307975129cebSChurchill Khangar 		snprintf(out, out_size, "\n%s\n",
308075129cebSChurchill Khangar 			cmd_pipeline_table_delete_help);
308175129cebSChurchill Khangar 		return;
308275129cebSChurchill Khangar 	}
308375129cebSChurchill Khangar 
308475129cebSChurchill Khangar 	if ((strcmp(tokens[0], "pipeline") == 0) &&
308575129cebSChurchill Khangar 		(n_tokens == 3) &&
308675129cebSChurchill Khangar 		(strcmp(tokens[1], "table") == 0) &&
308775129cebSChurchill Khangar 		(strcmp(tokens[2], "default") == 0)) {
308875129cebSChurchill Khangar 		snprintf(out, out_size, "\n%s\n",
308975129cebSChurchill Khangar 			cmd_pipeline_table_default_help);
309075129cebSChurchill Khangar 		return;
309175129cebSChurchill Khangar 	}
309275129cebSChurchill Khangar 
309375129cebSChurchill Khangar 	if ((strcmp(tokens[0], "pipeline") == 0) &&
309475129cebSChurchill Khangar 		(n_tokens == 3) &&
309575129cebSChurchill Khangar 		(strcmp(tokens[1], "table") == 0) &&
309675129cebSChurchill Khangar 		(strcmp(tokens[2], "show") == 0)) {
309775129cebSChurchill Khangar 		snprintf(out, out_size, "\n%s\n",
309875129cebSChurchill Khangar 			cmd_pipeline_table_show_help);
309975129cebSChurchill Khangar 		return;
310075129cebSChurchill Khangar 	}
310175129cebSChurchill Khangar 
310275129cebSChurchill Khangar 	if ((strcmp(tokens[0], "pipeline") == 0) &&
3103598fe0ddSCristian Dumitrescu 		(n_tokens == 4) &&
3104598fe0ddSCristian Dumitrescu 		(strcmp(tokens[1], "selector") == 0) &&
3105598fe0ddSCristian Dumitrescu 		(strcmp(tokens[2], "group") == 0) &&
3106598fe0ddSCristian Dumitrescu 		(strcmp(tokens[3], "add") == 0)) {
3107598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n",
3108598fe0ddSCristian Dumitrescu 			cmd_pipeline_selector_group_add_help);
3109598fe0ddSCristian Dumitrescu 		return;
3110598fe0ddSCristian Dumitrescu 	}
3111598fe0ddSCristian Dumitrescu 
3112598fe0ddSCristian Dumitrescu 	if ((strcmp(tokens[0], "pipeline") == 0) &&
3113598fe0ddSCristian Dumitrescu 		(n_tokens == 4) &&
3114598fe0ddSCristian Dumitrescu 		(strcmp(tokens[1], "selector") == 0) &&
3115598fe0ddSCristian Dumitrescu 		(strcmp(tokens[2], "group") == 0) &&
3116598fe0ddSCristian Dumitrescu 		(strcmp(tokens[3], "delete") == 0)) {
3117598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n",
3118598fe0ddSCristian Dumitrescu 			cmd_pipeline_selector_group_delete_help);
3119598fe0ddSCristian Dumitrescu 		return;
3120598fe0ddSCristian Dumitrescu 	}
3121598fe0ddSCristian Dumitrescu 
3122598fe0ddSCristian Dumitrescu 	if ((strcmp(tokens[0], "pipeline") == 0) &&
3123598fe0ddSCristian Dumitrescu 		(n_tokens == 5) &&
3124598fe0ddSCristian Dumitrescu 		(strcmp(tokens[1], "selector") == 0) &&
3125598fe0ddSCristian Dumitrescu 		(strcmp(tokens[2], "group") == 0) &&
3126598fe0ddSCristian Dumitrescu 		(strcmp(tokens[3], "member") == 0) &&
3127598fe0ddSCristian Dumitrescu 		(strcmp(tokens[4], "add") == 0)) {
3128598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n",
3129598fe0ddSCristian Dumitrescu 			cmd_pipeline_selector_group_member_add_help);
3130598fe0ddSCristian Dumitrescu 		return;
3131598fe0ddSCristian Dumitrescu 	}
3132598fe0ddSCristian Dumitrescu 
3133598fe0ddSCristian Dumitrescu 	if ((strcmp(tokens[0], "pipeline") == 0) &&
3134598fe0ddSCristian Dumitrescu 		(n_tokens == 5) &&
3135598fe0ddSCristian Dumitrescu 		(strcmp(tokens[1], "selector") == 0) &&
3136598fe0ddSCristian Dumitrescu 		(strcmp(tokens[2], "group") == 0) &&
3137598fe0ddSCristian Dumitrescu 		(strcmp(tokens[3], "member") == 0) &&
3138598fe0ddSCristian Dumitrescu 		(strcmp(tokens[4], "delete") == 0)) {
3139598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n",
3140598fe0ddSCristian Dumitrescu 			cmd_pipeline_selector_group_member_delete_help);
3141598fe0ddSCristian Dumitrescu 		return;
3142598fe0ddSCristian Dumitrescu 	}
3143598fe0ddSCristian Dumitrescu 
3144598fe0ddSCristian Dumitrescu 	if ((strcmp(tokens[0], "pipeline") == 0) &&
3145598fe0ddSCristian Dumitrescu 		(n_tokens == 3) &&
3146598fe0ddSCristian Dumitrescu 		(strcmp(tokens[1], "selector") == 0) &&
3147598fe0ddSCristian Dumitrescu 		(strcmp(tokens[2], "show") == 0)) {
3148598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n",
3149598fe0ddSCristian Dumitrescu 			cmd_pipeline_selector_show_help);
3150598fe0ddSCristian Dumitrescu 		return;
3151598fe0ddSCristian Dumitrescu 	}
3152598fe0ddSCristian Dumitrescu 
3153598fe0ddSCristian Dumitrescu 	if ((strcmp(tokens[0], "pipeline") == 0) &&
31548bd4862fSCristian Dumitrescu 		(n_tokens == 3) &&
31558bd4862fSCristian Dumitrescu 		(strcmp(tokens[1], "learner") == 0) &&
31568bd4862fSCristian Dumitrescu 		(strcmp(tokens[2], "default") == 0)) {
31578bd4862fSCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n",
31588bd4862fSCristian Dumitrescu 			cmd_pipeline_learner_default_help);
31598bd4862fSCristian Dumitrescu 		return;
31608bd4862fSCristian Dumitrescu 	}
31618bd4862fSCristian Dumitrescu 
31628bd4862fSCristian Dumitrescu 	if ((strcmp(tokens[0], "pipeline") == 0) &&
316375129cebSChurchill Khangar 		(n_tokens == 2) &&
316475129cebSChurchill Khangar 		(strcmp(tokens[1], "commit") == 0)) {
316575129cebSChurchill Khangar 		snprintf(out, out_size, "\n%s\n",
316675129cebSChurchill Khangar 			cmd_pipeline_commit_help);
316775129cebSChurchill Khangar 		return;
316875129cebSChurchill Khangar 	}
316975129cebSChurchill Khangar 
317075129cebSChurchill Khangar 	if ((strcmp(tokens[0], "pipeline") == 0) &&
317175129cebSChurchill Khangar 		(n_tokens == 2) &&
317275129cebSChurchill Khangar 		(strcmp(tokens[1], "abort") == 0)) {
317375129cebSChurchill Khangar 		snprintf(out, out_size, "\n%s\n",
317475129cebSChurchill Khangar 			cmd_pipeline_abort_help);
31755074e1d5SCristian Dumitrescu 		return;
31765074e1d5SCristian Dumitrescu 	}
31775074e1d5SCristian Dumitrescu 
31785074e1d5SCristian Dumitrescu 	if ((strcmp(tokens[0], "pipeline") == 0) &&
317964cfcebdSCristian Dumitrescu 		(n_tokens == 2) && (strcmp(tokens[1], "regrd") == 0)) {
318064cfcebdSCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n", cmd_pipeline_regrd_help);
318164cfcebdSCristian Dumitrescu 		return;
318264cfcebdSCristian Dumitrescu 	}
318364cfcebdSCristian Dumitrescu 
318464cfcebdSCristian Dumitrescu 	if ((strcmp(tokens[0], "pipeline") == 0) &&
318564cfcebdSCristian Dumitrescu 		(n_tokens == 2) && (strcmp(tokens[1], "regwr") == 0)) {
318664cfcebdSCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n", cmd_pipeline_regwr_help);
318764cfcebdSCristian Dumitrescu 		return;
318864cfcebdSCristian Dumitrescu 	}
318964cfcebdSCristian Dumitrescu 
3190f38913b7SCristian Dumitrescu 	if (!strcmp(tokens[0], "pipeline") &&
3191f38913b7SCristian Dumitrescu 		(n_tokens == 4) && !strcmp(tokens[1], "meter")
3192f38913b7SCristian Dumitrescu 		&& !strcmp(tokens[2], "profile")
3193f38913b7SCristian Dumitrescu 		&& !strcmp(tokens[3], "add")) {
3194f38913b7SCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n", cmd_pipeline_meter_profile_add_help);
3195f38913b7SCristian Dumitrescu 		return;
3196f38913b7SCristian Dumitrescu 	}
3197f38913b7SCristian Dumitrescu 
3198f38913b7SCristian Dumitrescu 	if (!strcmp(tokens[0], "pipeline") &&
3199f38913b7SCristian Dumitrescu 		(n_tokens == 4) && !strcmp(tokens[1], "meter")
3200f38913b7SCristian Dumitrescu 		&& !strcmp(tokens[2], "profile")
3201f38913b7SCristian Dumitrescu 		&& !strcmp(tokens[3], "delete")) {
3202f38913b7SCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n", cmd_pipeline_meter_profile_delete_help);
3203f38913b7SCristian Dumitrescu 		return;
3204f38913b7SCristian Dumitrescu 	}
3205f38913b7SCristian Dumitrescu 
3206f38913b7SCristian Dumitrescu 	if (!strcmp(tokens[0], "pipeline") &&
3207f38913b7SCristian Dumitrescu 		(n_tokens == 3) && !strcmp(tokens[1], "meter")
3208f38913b7SCristian Dumitrescu 		&& !strcmp(tokens[2], "reset")) {
3209f38913b7SCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n", cmd_pipeline_meter_reset_help);
3210f38913b7SCristian Dumitrescu 		return;
3211f38913b7SCristian Dumitrescu 	}
3212f38913b7SCristian Dumitrescu 
3213f38913b7SCristian Dumitrescu 	if (!strcmp(tokens[0], "pipeline") &&
3214f38913b7SCristian Dumitrescu 		(n_tokens == 3) && !strcmp(tokens[1], "meter")
3215f38913b7SCristian Dumitrescu 		&& !strcmp(tokens[2], "set")) {
3216f38913b7SCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n", cmd_pipeline_meter_set_help);
3217f38913b7SCristian Dumitrescu 		return;
3218f38913b7SCristian Dumitrescu 	}
3219f38913b7SCristian Dumitrescu 
3220f38913b7SCristian Dumitrescu 	if (!strcmp(tokens[0], "pipeline") &&
3221f38913b7SCristian Dumitrescu 		(n_tokens == 3) && !strcmp(tokens[1], "meter")
3222f38913b7SCristian Dumitrescu 		&& !strcmp(tokens[2], "stats")) {
3223f38913b7SCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n", cmd_pipeline_meter_stats_help);
3224f38913b7SCristian Dumitrescu 		return;
3225f38913b7SCristian Dumitrescu 	}
3226f38913b7SCristian Dumitrescu 
322764cfcebdSCristian Dumitrescu 	if ((strcmp(tokens[0], "pipeline") == 0) &&
32287fef9ef1SYogesh Jangra 		(n_tokens == 2) && (strcmp(tokens[1], "stats") == 0)) {
32295074e1d5SCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n", cmd_pipeline_stats_help);
32305074e1d5SCristian Dumitrescu 		return;
32315074e1d5SCristian Dumitrescu 	}
32325074e1d5SCristian Dumitrescu 
323317225455SCristian Dumitrescu 	if (!strcmp(tokens[0], "pipeline") &&
323417225455SCristian Dumitrescu 		(n_tokens == 3) && !strcmp(tokens[1], "mirror")
323517225455SCristian Dumitrescu 		&& !strcmp(tokens[2], "session")) {
323617225455SCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n", cmd_pipeline_mirror_session_help);
323717225455SCristian Dumitrescu 		return;
323817225455SCristian Dumitrescu 	}
323917225455SCristian Dumitrescu 
32405074e1d5SCristian Dumitrescu 	if ((n_tokens == 3) &&
32415074e1d5SCristian Dumitrescu 		(strcmp(tokens[0], "thread") == 0) &&
32425074e1d5SCristian Dumitrescu 		(strcmp(tokens[1], "pipeline") == 0)) {
32435074e1d5SCristian Dumitrescu 		if (strcmp(tokens[2], "enable") == 0) {
32445074e1d5SCristian Dumitrescu 			snprintf(out, out_size, "\n%s\n",
32455074e1d5SCristian Dumitrescu 				cmd_thread_pipeline_enable_help);
32465074e1d5SCristian Dumitrescu 			return;
32475074e1d5SCristian Dumitrescu 		}
32485074e1d5SCristian Dumitrescu 
32495074e1d5SCristian Dumitrescu 		if (strcmp(tokens[2], "disable") == 0) {
32505074e1d5SCristian Dumitrescu 			snprintf(out, out_size, "\n%s\n",
32515074e1d5SCristian Dumitrescu 				cmd_thread_pipeline_disable_help);
32525074e1d5SCristian Dumitrescu 			return;
32535074e1d5SCristian Dumitrescu 		}
32545074e1d5SCristian Dumitrescu 	}
32555074e1d5SCristian Dumitrescu 
32565074e1d5SCristian Dumitrescu 	snprintf(out, out_size, "Invalid command\n");
32575074e1d5SCristian Dumitrescu }
32585074e1d5SCristian Dumitrescu 
32595074e1d5SCristian Dumitrescu void
32605074e1d5SCristian Dumitrescu cli_process(char *in, char *out, size_t out_size, void *obj)
32615074e1d5SCristian Dumitrescu {
32625074e1d5SCristian Dumitrescu 	char *tokens[CMD_MAX_TOKENS];
32635074e1d5SCristian Dumitrescu 	uint32_t n_tokens = RTE_DIM(tokens);
32645074e1d5SCristian Dumitrescu 	int status;
32655074e1d5SCristian Dumitrescu 
32665074e1d5SCristian Dumitrescu 	if (is_comment(in))
32675074e1d5SCristian Dumitrescu 		return;
32685074e1d5SCristian Dumitrescu 
32695074e1d5SCristian Dumitrescu 	status = parse_tokenize_string(in, tokens, &n_tokens);
32705074e1d5SCristian Dumitrescu 	if (status) {
32715074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_TOO_MANY, "");
32725074e1d5SCristian Dumitrescu 		return;
32735074e1d5SCristian Dumitrescu 	}
32745074e1d5SCristian Dumitrescu 
32755074e1d5SCristian Dumitrescu 	if (n_tokens == 0)
32765074e1d5SCristian Dumitrescu 		return;
32775074e1d5SCristian Dumitrescu 
32785074e1d5SCristian Dumitrescu 	if (strcmp(tokens[0], "help") == 0) {
32795074e1d5SCristian Dumitrescu 		cmd_help(tokens, n_tokens, out, out_size, obj);
32805074e1d5SCristian Dumitrescu 		return;
32815074e1d5SCristian Dumitrescu 	}
32825074e1d5SCristian Dumitrescu 
32835074e1d5SCristian Dumitrescu 	if (strcmp(tokens[0], "mempool") == 0) {
32845074e1d5SCristian Dumitrescu 		cmd_mempool(tokens, n_tokens, out, out_size, obj);
32855074e1d5SCristian Dumitrescu 		return;
32865074e1d5SCristian Dumitrescu 	}
32875074e1d5SCristian Dumitrescu 
3288f31c80f8SCristian Dumitrescu 	if (strcmp(tokens[0], "ethdev") == 0) {
3289821848f5SCristian Dumitrescu 		if ((n_tokens >= 2) && (strcmp(tokens[1], "show") == 0)) {
3290f31c80f8SCristian Dumitrescu 			cmd_ethdev_show(tokens, n_tokens, out, out_size, obj);
32915074e1d5SCristian Dumitrescu 			return;
32925074e1d5SCristian Dumitrescu 		}
32935074e1d5SCristian Dumitrescu 
3294f31c80f8SCristian Dumitrescu 		cmd_ethdev(tokens, n_tokens, out, out_size, obj);
32955074e1d5SCristian Dumitrescu 		return;
32965074e1d5SCristian Dumitrescu 	}
32975074e1d5SCristian Dumitrescu 
329877a41301SCristian Dumitrescu 	if (strcmp(tokens[0], "ring") == 0) {
329977a41301SCristian Dumitrescu 		cmd_ring(tokens, n_tokens, out, out_size, obj);
330077a41301SCristian Dumitrescu 		return;
330177a41301SCristian Dumitrescu 	}
330277a41301SCristian Dumitrescu 
33035074e1d5SCristian Dumitrescu 	if (strcmp(tokens[0], "pipeline") == 0) {
33045074e1d5SCristian Dumitrescu 		if ((n_tokens >= 3) &&
33059043f66aSCristian Dumitrescu 			(strcmp(tokens[1], "codegen") == 0)) {
33069043f66aSCristian Dumitrescu 			cmd_pipeline_codegen(tokens, n_tokens, out, out_size,
33079043f66aSCristian Dumitrescu 				obj);
33089043f66aSCristian Dumitrescu 			return;
33099043f66aSCristian Dumitrescu 		}
33109043f66aSCristian Dumitrescu 
33119043f66aSCristian Dumitrescu 		if ((n_tokens >= 3) &&
33126bc14d9fSCristian Dumitrescu 			(strcmp(tokens[1], "libbuild") == 0)) {
33136bc14d9fSCristian Dumitrescu 			cmd_pipeline_libbuild(tokens, n_tokens, out, out_size,
33146bc14d9fSCristian Dumitrescu 				obj);
33156bc14d9fSCristian Dumitrescu 			return;
33166bc14d9fSCristian Dumitrescu 		}
33176bc14d9fSCristian Dumitrescu 
33186bc14d9fSCristian Dumitrescu 		if ((n_tokens >= 3) &&
33195074e1d5SCristian Dumitrescu 			(strcmp(tokens[2], "build") == 0)) {
33205074e1d5SCristian Dumitrescu 			cmd_pipeline_build(tokens, n_tokens, out, out_size,
33215074e1d5SCristian Dumitrescu 				obj);
33225074e1d5SCristian Dumitrescu 			return;
33235074e1d5SCristian Dumitrescu 		}
33245074e1d5SCristian Dumitrescu 
332575129cebSChurchill Khangar 		if ((n_tokens >= 5) &&
332675129cebSChurchill Khangar 			(strcmp(tokens[2], "table") == 0) &&
332775129cebSChurchill Khangar 			(strcmp(tokens[4], "add") == 0)) {
332875129cebSChurchill Khangar 			cmd_pipeline_table_add(tokens, n_tokens, out,
332975129cebSChurchill Khangar 				out_size, obj);
333075129cebSChurchill Khangar 			return;
333175129cebSChurchill Khangar 		}
333275129cebSChurchill Khangar 
333375129cebSChurchill Khangar 		if ((n_tokens >= 5) &&
333475129cebSChurchill Khangar 			(strcmp(tokens[2], "table") == 0) &&
333575129cebSChurchill Khangar 			(strcmp(tokens[4], "delete") == 0)) {
333675129cebSChurchill Khangar 			cmd_pipeline_table_delete(tokens, n_tokens, out,
333775129cebSChurchill Khangar 				out_size, obj);
333875129cebSChurchill Khangar 			return;
333975129cebSChurchill Khangar 		}
334075129cebSChurchill Khangar 
334175129cebSChurchill Khangar 		if ((n_tokens >= 5) &&
334275129cebSChurchill Khangar 			(strcmp(tokens[2], "table") == 0) &&
334375129cebSChurchill Khangar 			(strcmp(tokens[4], "default") == 0)) {
334475129cebSChurchill Khangar 			cmd_pipeline_table_default(tokens, n_tokens, out,
334575129cebSChurchill Khangar 				out_size, obj);
334675129cebSChurchill Khangar 			return;
334775129cebSChurchill Khangar 		}
334875129cebSChurchill Khangar 
334975129cebSChurchill Khangar 		if ((n_tokens >= 5) &&
335075129cebSChurchill Khangar 			(strcmp(tokens[2], "table") == 0) &&
335175129cebSChurchill Khangar 			(strcmp(tokens[4], "show") == 0)) {
335275129cebSChurchill Khangar 			cmd_pipeline_table_show(tokens, n_tokens, out,
335375129cebSChurchill Khangar 				out_size, obj);
335475129cebSChurchill Khangar 			return;
335575129cebSChurchill Khangar 		}
335675129cebSChurchill Khangar 
3357598fe0ddSCristian Dumitrescu 		if ((n_tokens >= 6) &&
3358598fe0ddSCristian Dumitrescu 			(strcmp(tokens[2], "selector") == 0) &&
3359598fe0ddSCristian Dumitrescu 			(strcmp(tokens[4], "group") == 0) &&
3360598fe0ddSCristian Dumitrescu 			(strcmp(tokens[5], "add") == 0)) {
3361598fe0ddSCristian Dumitrescu 			cmd_pipeline_selector_group_add(tokens, n_tokens, out,
3362598fe0ddSCristian Dumitrescu 				out_size, obj);
3363598fe0ddSCristian Dumitrescu 			return;
3364598fe0ddSCristian Dumitrescu 		}
3365598fe0ddSCristian Dumitrescu 
3366598fe0ddSCristian Dumitrescu 		if ((n_tokens >= 6) &&
3367598fe0ddSCristian Dumitrescu 			(strcmp(tokens[2], "selector") == 0) &&
3368598fe0ddSCristian Dumitrescu 			(strcmp(tokens[4], "group") == 0) &&
3369598fe0ddSCristian Dumitrescu 			(strcmp(tokens[5], "delete") == 0)) {
3370598fe0ddSCristian Dumitrescu 			cmd_pipeline_selector_group_delete(tokens, n_tokens, out,
3371598fe0ddSCristian Dumitrescu 				out_size, obj);
3372598fe0ddSCristian Dumitrescu 			return;
3373598fe0ddSCristian Dumitrescu 		}
3374598fe0ddSCristian Dumitrescu 
3375598fe0ddSCristian Dumitrescu 		if ((n_tokens >= 7) &&
3376598fe0ddSCristian Dumitrescu 			(strcmp(tokens[2], "selector") == 0) &&
3377598fe0ddSCristian Dumitrescu 			(strcmp(tokens[4], "group") == 0) &&
3378598fe0ddSCristian Dumitrescu 			(strcmp(tokens[5], "member") == 0) &&
3379598fe0ddSCristian Dumitrescu 			(strcmp(tokens[6], "add") == 0)) {
3380598fe0ddSCristian Dumitrescu 			cmd_pipeline_selector_group_member_add(tokens, n_tokens, out,
3381598fe0ddSCristian Dumitrescu 				out_size, obj);
3382598fe0ddSCristian Dumitrescu 			return;
3383598fe0ddSCristian Dumitrescu 		}
3384598fe0ddSCristian Dumitrescu 
3385598fe0ddSCristian Dumitrescu 		if ((n_tokens >= 7) &&
3386598fe0ddSCristian Dumitrescu 			(strcmp(tokens[2], "selector") == 0) &&
3387598fe0ddSCristian Dumitrescu 			(strcmp(tokens[4], "group") == 0) &&
3388598fe0ddSCristian Dumitrescu 			(strcmp(tokens[5], "member") == 0) &&
3389598fe0ddSCristian Dumitrescu 			(strcmp(tokens[6], "delete") == 0)) {
3390598fe0ddSCristian Dumitrescu 			cmd_pipeline_selector_group_member_delete(tokens, n_tokens, out,
3391598fe0ddSCristian Dumitrescu 				out_size, obj);
3392598fe0ddSCristian Dumitrescu 			return;
3393598fe0ddSCristian Dumitrescu 		}
3394598fe0ddSCristian Dumitrescu 
3395598fe0ddSCristian Dumitrescu 		if ((n_tokens >= 5) &&
3396598fe0ddSCristian Dumitrescu 			(strcmp(tokens[2], "selector") == 0) &&
3397598fe0ddSCristian Dumitrescu 			(strcmp(tokens[4], "show") == 0)) {
3398598fe0ddSCristian Dumitrescu 			cmd_pipeline_selector_show(tokens, n_tokens, out,
3399598fe0ddSCristian Dumitrescu 				out_size, obj);
3400598fe0ddSCristian Dumitrescu 			return;
3401598fe0ddSCristian Dumitrescu 		}
3402598fe0ddSCristian Dumitrescu 
34038bd4862fSCristian Dumitrescu 		if ((n_tokens >= 5) &&
34048bd4862fSCristian Dumitrescu 			(strcmp(tokens[2], "learner") == 0) &&
34058bd4862fSCristian Dumitrescu 			(strcmp(tokens[4], "default") == 0)) {
34068bd4862fSCristian Dumitrescu 			cmd_pipeline_learner_default(tokens, n_tokens, out,
34078bd4862fSCristian Dumitrescu 				out_size, obj);
34088bd4862fSCristian Dumitrescu 			return;
34098bd4862fSCristian Dumitrescu 		}
34108bd4862fSCristian Dumitrescu 
34115074e1d5SCristian Dumitrescu 		if ((n_tokens >= 3) &&
341275129cebSChurchill Khangar 			(strcmp(tokens[2], "commit") == 0)) {
341375129cebSChurchill Khangar 			cmd_pipeline_commit(tokens, n_tokens, out,
341475129cebSChurchill Khangar 				out_size, obj);
341575129cebSChurchill Khangar 			return;
341675129cebSChurchill Khangar 		}
341775129cebSChurchill Khangar 
341875129cebSChurchill Khangar 		if ((n_tokens >= 3) &&
341975129cebSChurchill Khangar 			(strcmp(tokens[2], "abort") == 0)) {
342075129cebSChurchill Khangar 			cmd_pipeline_abort(tokens, n_tokens, out,
34215074e1d5SCristian Dumitrescu 				out_size, obj);
34225074e1d5SCristian Dumitrescu 			return;
34235074e1d5SCristian Dumitrescu 		}
34245074e1d5SCristian Dumitrescu 
34255074e1d5SCristian Dumitrescu 		if ((n_tokens >= 3) &&
342664cfcebdSCristian Dumitrescu 			(strcmp(tokens[2], "regrd") == 0)) {
342764cfcebdSCristian Dumitrescu 			cmd_pipeline_regrd(tokens, n_tokens, out, out_size, obj);
342864cfcebdSCristian Dumitrescu 			return;
342964cfcebdSCristian Dumitrescu 		}
343064cfcebdSCristian Dumitrescu 
343164cfcebdSCristian Dumitrescu 		if ((n_tokens >= 3) &&
343264cfcebdSCristian Dumitrescu 			(strcmp(tokens[2], "regwr") == 0)) {
343364cfcebdSCristian Dumitrescu 			cmd_pipeline_regwr(tokens, n_tokens, out, out_size, obj);
343464cfcebdSCristian Dumitrescu 			return;
343564cfcebdSCristian Dumitrescu 		}
343664cfcebdSCristian Dumitrescu 
3437f38913b7SCristian Dumitrescu 		if ((n_tokens >= 6) &&
3438f38913b7SCristian Dumitrescu 			(strcmp(tokens[2], "meter") == 0) &&
3439f38913b7SCristian Dumitrescu 			(strcmp(tokens[3], "profile") == 0) &&
3440f38913b7SCristian Dumitrescu 			(strcmp(tokens[5], "add") == 0)) {
3441f38913b7SCristian Dumitrescu 			cmd_pipeline_meter_profile_add(tokens, n_tokens, out, out_size, obj);
3442f38913b7SCristian Dumitrescu 			return;
3443f38913b7SCristian Dumitrescu 		}
3444f38913b7SCristian Dumitrescu 
3445f38913b7SCristian Dumitrescu 		if ((n_tokens >= 6) &&
3446f38913b7SCristian Dumitrescu 			(strcmp(tokens[2], "meter") == 0) &&
3447f38913b7SCristian Dumitrescu 			(strcmp(tokens[3], "profile") == 0) &&
3448f38913b7SCristian Dumitrescu 			(strcmp(tokens[5], "delete") == 0)) {
3449f38913b7SCristian Dumitrescu 			cmd_pipeline_meter_profile_delete(tokens, n_tokens, out, out_size, obj);
3450f38913b7SCristian Dumitrescu 			return;
3451f38913b7SCristian Dumitrescu 		}
3452f38913b7SCristian Dumitrescu 
345312eda78dSCristian Dumitrescu 		if (n_tokens >= 9 && !strcmp(tokens[2], "meter") && !strcmp(tokens[4], "reset")) {
3454f38913b7SCristian Dumitrescu 			cmd_pipeline_meter_reset(tokens, n_tokens, out, out_size, obj);
3455f38913b7SCristian Dumitrescu 			return;
3456f38913b7SCristian Dumitrescu 		}
3457f38913b7SCristian Dumitrescu 
345812eda78dSCristian Dumitrescu 		if (n_tokens >= 9 && !strcmp(tokens[2], "meter") && !strcmp(tokens[4], "set")) {
3459f38913b7SCristian Dumitrescu 			cmd_pipeline_meter_set(tokens, n_tokens, out, out_size, obj);
3460f38913b7SCristian Dumitrescu 			return;
3461f38913b7SCristian Dumitrescu 		}
3462f38913b7SCristian Dumitrescu 
346312eda78dSCristian Dumitrescu 		if (n_tokens >= 9 && !strcmp(tokens[2], "meter") && !strcmp(tokens[4], "stats")) {
3464f38913b7SCristian Dumitrescu 			cmd_pipeline_meter_stats(tokens, n_tokens, out, out_size, obj);
3465f38913b7SCristian Dumitrescu 			return;
3466f38913b7SCristian Dumitrescu 		}
3467f38913b7SCristian Dumitrescu 
346864cfcebdSCristian Dumitrescu 		if ((n_tokens >= 3) &&
34695074e1d5SCristian Dumitrescu 			(strcmp(tokens[2], "stats") == 0)) {
34705074e1d5SCristian Dumitrescu 			cmd_pipeline_stats(tokens, n_tokens, out, out_size,
34715074e1d5SCristian Dumitrescu 				obj);
34725074e1d5SCristian Dumitrescu 			return;
34735074e1d5SCristian Dumitrescu 		}
347417225455SCristian Dumitrescu 
347517225455SCristian Dumitrescu 		if ((n_tokens >= 4) &&
347617225455SCristian Dumitrescu 			(strcmp(tokens[2], "mirror") == 0) &&
347717225455SCristian Dumitrescu 			(strcmp(tokens[3], "session") == 0)) {
347817225455SCristian Dumitrescu 			cmd_pipeline_mirror_session(tokens, n_tokens, out, out_size, obj);
347917225455SCristian Dumitrescu 			return;
348017225455SCristian Dumitrescu 		}
34815074e1d5SCristian Dumitrescu 	}
34825074e1d5SCristian Dumitrescu 
34835074e1d5SCristian Dumitrescu 	if (strcmp(tokens[0], "thread") == 0) {
34845074e1d5SCristian Dumitrescu 		if ((n_tokens >= 5) &&
34855074e1d5SCristian Dumitrescu 			(strcmp(tokens[4], "enable") == 0)) {
34865074e1d5SCristian Dumitrescu 			cmd_thread_pipeline_enable(tokens, n_tokens,
34875074e1d5SCristian Dumitrescu 				out, out_size, obj);
34885074e1d5SCristian Dumitrescu 			return;
34895074e1d5SCristian Dumitrescu 		}
34905074e1d5SCristian Dumitrescu 
34915074e1d5SCristian Dumitrescu 		if ((n_tokens >= 5) &&
34925074e1d5SCristian Dumitrescu 			(strcmp(tokens[4], "disable") == 0)) {
34935074e1d5SCristian Dumitrescu 			cmd_thread_pipeline_disable(tokens, n_tokens,
34945074e1d5SCristian Dumitrescu 				out, out_size, obj);
34955074e1d5SCristian Dumitrescu 			return;
34965074e1d5SCristian Dumitrescu 		}
34975074e1d5SCristian Dumitrescu 	}
34985074e1d5SCristian Dumitrescu 
34995074e1d5SCristian Dumitrescu 	snprintf(out, out_size, MSG_CMD_UNKNOWN, tokens[0]);
35005074e1d5SCristian Dumitrescu }
35015074e1d5SCristian Dumitrescu 
35025074e1d5SCristian Dumitrescu int
35035074e1d5SCristian Dumitrescu cli_script_process(const char *file_name,
35045074e1d5SCristian Dumitrescu 	size_t msg_in_len_max,
35055074e1d5SCristian Dumitrescu 	size_t msg_out_len_max,
35065074e1d5SCristian Dumitrescu 	void *obj)
35075074e1d5SCristian Dumitrescu {
35085074e1d5SCristian Dumitrescu 	char *msg_in = NULL, *msg_out = NULL;
35095074e1d5SCristian Dumitrescu 	FILE *f = NULL;
35105074e1d5SCristian Dumitrescu 
35115074e1d5SCristian Dumitrescu 	/* Check input arguments */
35125074e1d5SCristian Dumitrescu 	if ((file_name == NULL) ||
35135074e1d5SCristian Dumitrescu 		(strlen(file_name) == 0) ||
35145074e1d5SCristian Dumitrescu 		(msg_in_len_max == 0) ||
35155074e1d5SCristian Dumitrescu 		(msg_out_len_max == 0))
35165074e1d5SCristian Dumitrescu 		return -EINVAL;
35175074e1d5SCristian Dumitrescu 
35185074e1d5SCristian Dumitrescu 	msg_in = malloc(msg_in_len_max + 1);
35195074e1d5SCristian Dumitrescu 	msg_out = malloc(msg_out_len_max + 1);
35205074e1d5SCristian Dumitrescu 	if ((msg_in == NULL) ||
35215074e1d5SCristian Dumitrescu 		(msg_out == NULL)) {
35225074e1d5SCristian Dumitrescu 		free(msg_out);
35235074e1d5SCristian Dumitrescu 		free(msg_in);
35245074e1d5SCristian Dumitrescu 		return -ENOMEM;
35255074e1d5SCristian Dumitrescu 	}
35265074e1d5SCristian Dumitrescu 
35275074e1d5SCristian Dumitrescu 	/* Open input file */
35285074e1d5SCristian Dumitrescu 	f = fopen(file_name, "r");
35295074e1d5SCristian Dumitrescu 	if (f == NULL) {
35305074e1d5SCristian Dumitrescu 		free(msg_out);
35315074e1d5SCristian Dumitrescu 		free(msg_in);
35325074e1d5SCristian Dumitrescu 		return -EIO;
35335074e1d5SCristian Dumitrescu 	}
35345074e1d5SCristian Dumitrescu 
35355074e1d5SCristian Dumitrescu 	/* Read file */
35365074e1d5SCristian Dumitrescu 	for ( ; ; ) {
35375074e1d5SCristian Dumitrescu 		if (fgets(msg_in, msg_in_len_max + 1, f) == NULL)
35385074e1d5SCristian Dumitrescu 			break;
35395074e1d5SCristian Dumitrescu 
35405074e1d5SCristian Dumitrescu 		printf("%s", msg_in);
35415074e1d5SCristian Dumitrescu 		msg_out[0] = 0;
35425074e1d5SCristian Dumitrescu 
35435074e1d5SCristian Dumitrescu 		cli_process(msg_in,
35445074e1d5SCristian Dumitrescu 			msg_out,
35455074e1d5SCristian Dumitrescu 			msg_out_len_max,
35465074e1d5SCristian Dumitrescu 			obj);
35475074e1d5SCristian Dumitrescu 
35485074e1d5SCristian Dumitrescu 		if (strlen(msg_out))
35495074e1d5SCristian Dumitrescu 			printf("%s", msg_out);
35505074e1d5SCristian Dumitrescu 	}
35515074e1d5SCristian Dumitrescu 
35525074e1d5SCristian Dumitrescu 	/* Close file */
35535074e1d5SCristian Dumitrescu 	fclose(f);
35545074e1d5SCristian Dumitrescu 	free(msg_out);
35555074e1d5SCristian Dumitrescu 	free(msg_in);
35565074e1d5SCristian Dumitrescu 	return 0;
35575074e1d5SCristian Dumitrescu }
3558