xref: /dpdk/examples/pipeline/cli.c (revision 607dd51717d62851316ad6a34f2ce36020597f8d)
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>
14*607dd517SCristian 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,
2955074e1d5SCristian Dumitrescu 	void *obj)
2965074e1d5SCristian Dumitrescu {
2975074e1d5SCristian Dumitrescu 	struct link_params p;
2985074e1d5SCristian Dumitrescu 	struct link_params_rss rss;
2995074e1d5SCristian Dumitrescu 	struct link *link;
3005074e1d5SCristian Dumitrescu 	char *name;
3015074e1d5SCristian Dumitrescu 
3025074e1d5SCristian Dumitrescu 	memset(&p, 0, sizeof(p));
3035074e1d5SCristian Dumitrescu 
304f31c80f8SCristian Dumitrescu 	if ((n_tokens < 11) || (n_tokens > 12 + LINK_RXQ_RSS_MAX)) {
3055074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
3065074e1d5SCristian Dumitrescu 		return;
3075074e1d5SCristian Dumitrescu 	}
3085074e1d5SCristian Dumitrescu 	name = tokens[1];
3095074e1d5SCristian Dumitrescu 
310f31c80f8SCristian Dumitrescu 	if (strcmp(tokens[2], "rxq") != 0) {
3115074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rxq");
3125074e1d5SCristian Dumitrescu 		return;
3135074e1d5SCristian Dumitrescu 	}
3145074e1d5SCristian Dumitrescu 
315f31c80f8SCristian Dumitrescu 	if (parser_read_uint32(&p.rx.n_queues, tokens[3]) != 0) {
3165074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "n_queues");
3175074e1d5SCristian Dumitrescu 		return;
3185074e1d5SCristian Dumitrescu 	}
319f31c80f8SCristian Dumitrescu 	if (parser_read_uint32(&p.rx.queue_size, tokens[4]) != 0) {
3205074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "queue_size");
3215074e1d5SCristian Dumitrescu 		return;
3225074e1d5SCristian Dumitrescu 	}
3235074e1d5SCristian Dumitrescu 
324f31c80f8SCristian Dumitrescu 	p.rx.mempool_name = tokens[5];
3255074e1d5SCristian Dumitrescu 
326f31c80f8SCristian Dumitrescu 	if (strcmp(tokens[6], "txq") != 0) {
3275074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "txq");
3285074e1d5SCristian Dumitrescu 		return;
3295074e1d5SCristian Dumitrescu 	}
3305074e1d5SCristian Dumitrescu 
331f31c80f8SCristian Dumitrescu 	if (parser_read_uint32(&p.tx.n_queues, tokens[7]) != 0) {
3325074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "n_queues");
3335074e1d5SCristian Dumitrescu 		return;
3345074e1d5SCristian Dumitrescu 	}
3355074e1d5SCristian Dumitrescu 
336f31c80f8SCristian Dumitrescu 	if (parser_read_uint32(&p.tx.queue_size, tokens[8]) != 0) {
3375074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "queue_size");
3385074e1d5SCristian Dumitrescu 		return;
3395074e1d5SCristian Dumitrescu 	}
3405074e1d5SCristian Dumitrescu 
341f31c80f8SCristian Dumitrescu 	if (strcmp(tokens[9], "promiscuous") != 0) {
3425074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "promiscuous");
3435074e1d5SCristian Dumitrescu 		return;
3445074e1d5SCristian Dumitrescu 	}
3455074e1d5SCristian Dumitrescu 
346f31c80f8SCristian Dumitrescu 	if (strcmp(tokens[10], "on") == 0)
3475074e1d5SCristian Dumitrescu 		p.promiscuous = 1;
348f31c80f8SCristian Dumitrescu 	else if (strcmp(tokens[10], "off") == 0)
3495074e1d5SCristian Dumitrescu 		p.promiscuous = 0;
3505074e1d5SCristian Dumitrescu 	else {
3515074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "on or off");
3525074e1d5SCristian Dumitrescu 		return;
3535074e1d5SCristian Dumitrescu 	}
3545074e1d5SCristian Dumitrescu 
3555074e1d5SCristian Dumitrescu 	/* RSS */
3565074e1d5SCristian Dumitrescu 	p.rx.rss = NULL;
357f31c80f8SCristian Dumitrescu 	if (n_tokens > 11) {
3585074e1d5SCristian Dumitrescu 		uint32_t queue_id, i;
3595074e1d5SCristian Dumitrescu 
360f31c80f8SCristian Dumitrescu 		if (strcmp(tokens[11], "rss") != 0) {
3615074e1d5SCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rss");
3625074e1d5SCristian Dumitrescu 			return;
3635074e1d5SCristian Dumitrescu 		}
3645074e1d5SCristian Dumitrescu 
3655074e1d5SCristian Dumitrescu 		p.rx.rss = &rss;
3665074e1d5SCristian Dumitrescu 
3675074e1d5SCristian Dumitrescu 		rss.n_queues = 0;
368f31c80f8SCristian Dumitrescu 		for (i = 12; i < n_tokens; i++) {
3695074e1d5SCristian Dumitrescu 			if (parser_read_uint32(&queue_id, tokens[i]) != 0) {
3705074e1d5SCristian Dumitrescu 				snprintf(out, out_size, MSG_ARG_INVALID,
3715074e1d5SCristian Dumitrescu 					"queue_id");
3725074e1d5SCristian Dumitrescu 				return;
3735074e1d5SCristian Dumitrescu 			}
3745074e1d5SCristian Dumitrescu 
3755074e1d5SCristian Dumitrescu 			rss.queue_id[rss.n_queues] = queue_id;
3765074e1d5SCristian Dumitrescu 			rss.n_queues++;
3775074e1d5SCristian Dumitrescu 		}
3785074e1d5SCristian Dumitrescu 	}
3795074e1d5SCristian Dumitrescu 
3805074e1d5SCristian Dumitrescu 	link = link_create(obj, name, &p);
3815074e1d5SCristian Dumitrescu 	if (link == NULL) {
3825074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
3835074e1d5SCristian Dumitrescu 		return;
3845074e1d5SCristian Dumitrescu 	}
3855074e1d5SCristian Dumitrescu }
3865074e1d5SCristian Dumitrescu 
3875074e1d5SCristian Dumitrescu /* Print the link stats and info */
3885074e1d5SCristian Dumitrescu static void
3895074e1d5SCristian Dumitrescu print_link_info(struct link *link, char *out, size_t out_size)
3905074e1d5SCristian Dumitrescu {
3915074e1d5SCristian Dumitrescu 	struct rte_eth_stats stats;
3925074e1d5SCristian Dumitrescu 	struct rte_ether_addr mac_addr;
3935074e1d5SCristian Dumitrescu 	struct rte_eth_link eth_link;
3945074e1d5SCristian Dumitrescu 	uint16_t mtu;
3955074e1d5SCristian Dumitrescu 	int ret;
3965074e1d5SCristian Dumitrescu 
3975074e1d5SCristian Dumitrescu 	memset(&stats, 0, sizeof(stats));
3985074e1d5SCristian Dumitrescu 	rte_eth_stats_get(link->port_id, &stats);
3995074e1d5SCristian Dumitrescu 
4005074e1d5SCristian Dumitrescu 	ret = rte_eth_macaddr_get(link->port_id, &mac_addr);
4015074e1d5SCristian Dumitrescu 	if (ret != 0) {
4025074e1d5SCristian Dumitrescu 		snprintf(out, out_size, "\n%s: MAC address get failed: %s",
4035074e1d5SCristian Dumitrescu 			 link->name, rte_strerror(-ret));
4045074e1d5SCristian Dumitrescu 		return;
4055074e1d5SCristian Dumitrescu 	}
4065074e1d5SCristian Dumitrescu 
4075074e1d5SCristian Dumitrescu 	ret = rte_eth_link_get(link->port_id, &eth_link);
4085074e1d5SCristian Dumitrescu 	if (ret < 0) {
4095074e1d5SCristian Dumitrescu 		snprintf(out, out_size, "\n%s: link get failed: %s",
4105074e1d5SCristian Dumitrescu 			 link->name, rte_strerror(-ret));
4115074e1d5SCristian Dumitrescu 		return;
4125074e1d5SCristian Dumitrescu 	}
4135074e1d5SCristian Dumitrescu 
4145074e1d5SCristian Dumitrescu 	rte_eth_dev_get_mtu(link->port_id, &mtu);
4155074e1d5SCristian Dumitrescu 
4165074e1d5SCristian Dumitrescu 	snprintf(out, out_size,
4175074e1d5SCristian Dumitrescu 		"\n"
4185074e1d5SCristian Dumitrescu 		"%s: flags=<%s> mtu %u\n"
419c2c4f87bSAman Deep Singh 		"\tether " RTE_ETHER_ADDR_PRT_FMT " rxqueues %u txqueues %u\n"
4205074e1d5SCristian Dumitrescu 		"\tport# %u  speed %s\n"
4215074e1d5SCristian Dumitrescu 		"\tRX packets %" PRIu64"  bytes %" PRIu64"\n"
4225074e1d5SCristian Dumitrescu 		"\tRX errors %" PRIu64"  missed %" PRIu64"  no-mbuf %" PRIu64"\n"
4235074e1d5SCristian Dumitrescu 		"\tTX packets %" PRIu64"  bytes %" PRIu64"\n"
4245074e1d5SCristian Dumitrescu 		"\tTX errors %" PRIu64"\n",
4255074e1d5SCristian Dumitrescu 		link->name,
4265074e1d5SCristian Dumitrescu 		eth_link.link_status == 0 ? "DOWN" : "UP",
4275074e1d5SCristian Dumitrescu 		mtu,
428a7db3afcSAman Deep Singh 		RTE_ETHER_ADDR_BYTES(&mac_addr),
4295074e1d5SCristian Dumitrescu 		link->n_rxq,
4305074e1d5SCristian Dumitrescu 		link->n_txq,
4315074e1d5SCristian Dumitrescu 		link->port_id,
4325074e1d5SCristian Dumitrescu 		rte_eth_link_speed_to_str(eth_link.link_speed),
4335074e1d5SCristian Dumitrescu 		stats.ipackets,
4345074e1d5SCristian Dumitrescu 		stats.ibytes,
4355074e1d5SCristian Dumitrescu 		stats.ierrors,
4365074e1d5SCristian Dumitrescu 		stats.imissed,
4375074e1d5SCristian Dumitrescu 		stats.rx_nombuf,
4385074e1d5SCristian Dumitrescu 		stats.opackets,
4395074e1d5SCristian Dumitrescu 		stats.obytes,
4405074e1d5SCristian Dumitrescu 		stats.oerrors);
4415074e1d5SCristian Dumitrescu }
4425074e1d5SCristian Dumitrescu 
4435074e1d5SCristian Dumitrescu /*
444f31c80f8SCristian Dumitrescu  * ethdev show [<ethdev_name>]
4455074e1d5SCristian Dumitrescu  */
4465074e1d5SCristian Dumitrescu static void
447f31c80f8SCristian Dumitrescu cmd_ethdev_show(char **tokens,
4485074e1d5SCristian Dumitrescu 	      uint32_t n_tokens,
4495074e1d5SCristian Dumitrescu 	      char *out,
4505074e1d5SCristian Dumitrescu 	      size_t out_size,
4515074e1d5SCristian Dumitrescu 	      void *obj)
4525074e1d5SCristian Dumitrescu {
4535074e1d5SCristian Dumitrescu 	struct link *link;
4545074e1d5SCristian Dumitrescu 	char *link_name;
4555074e1d5SCristian Dumitrescu 
4565074e1d5SCristian Dumitrescu 	if (n_tokens != 2 && n_tokens != 3) {
4575074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
4585074e1d5SCristian Dumitrescu 		return;
4595074e1d5SCristian Dumitrescu 	}
4605074e1d5SCristian Dumitrescu 
4615074e1d5SCristian Dumitrescu 	if (n_tokens == 2) {
4625074e1d5SCristian Dumitrescu 		link = link_next(obj, NULL);
4635074e1d5SCristian Dumitrescu 
4645074e1d5SCristian Dumitrescu 		while (link != NULL) {
4655074e1d5SCristian Dumitrescu 			out_size = out_size - strlen(out);
4665074e1d5SCristian Dumitrescu 			out = &out[strlen(out)];
4675074e1d5SCristian Dumitrescu 
4685074e1d5SCristian Dumitrescu 			print_link_info(link, out, out_size);
4695074e1d5SCristian Dumitrescu 			link = link_next(obj, link);
4705074e1d5SCristian Dumitrescu 		}
4715074e1d5SCristian Dumitrescu 	} else {
4725074e1d5SCristian Dumitrescu 		out_size = out_size - strlen(out);
4735074e1d5SCristian Dumitrescu 		out = &out[strlen(out)];
4745074e1d5SCristian Dumitrescu 
4755074e1d5SCristian Dumitrescu 		link_name = tokens[2];
4765074e1d5SCristian Dumitrescu 		link = link_find(obj, link_name);
4775074e1d5SCristian Dumitrescu 
4785074e1d5SCristian Dumitrescu 		if (link == NULL) {
4795074e1d5SCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_INVALID,
4805074e1d5SCristian Dumitrescu 					"Link does not exist");
4815074e1d5SCristian Dumitrescu 			return;
4825074e1d5SCristian Dumitrescu 		}
4835074e1d5SCristian Dumitrescu 		print_link_info(link, out, out_size);
4845074e1d5SCristian Dumitrescu 	}
4855074e1d5SCristian Dumitrescu }
4865074e1d5SCristian Dumitrescu 
48777a41301SCristian Dumitrescu static const char cmd_ring_help[] =
48877a41301SCristian Dumitrescu "ring <ring_name> size <size> numa <numa_node>\n";
48977a41301SCristian Dumitrescu 
49077a41301SCristian Dumitrescu static void
49177a41301SCristian Dumitrescu cmd_ring(char **tokens,
49277a41301SCristian Dumitrescu 	uint32_t n_tokens,
49377a41301SCristian Dumitrescu 	char *out,
49477a41301SCristian Dumitrescu 	size_t out_size,
495*607dd517SCristian Dumitrescu 	void *obj __rte_unused)
49677a41301SCristian Dumitrescu {
497*607dd517SCristian Dumitrescu 	struct rte_ring *r;
49877a41301SCristian Dumitrescu 	char *name;
499*607dd517SCristian Dumitrescu 	uint32_t size, numa_node;
50077a41301SCristian Dumitrescu 
50177a41301SCristian Dumitrescu 	if (n_tokens != 6) {
50277a41301SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
50377a41301SCristian Dumitrescu 		return;
50477a41301SCristian Dumitrescu 	}
50577a41301SCristian Dumitrescu 
50677a41301SCristian Dumitrescu 	name = tokens[1];
50777a41301SCristian Dumitrescu 
508*607dd517SCristian Dumitrescu 	if (strcmp(tokens[2], "size")) {
50977a41301SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "size");
51077a41301SCristian Dumitrescu 		return;
51177a41301SCristian Dumitrescu 	}
51277a41301SCristian Dumitrescu 
513*607dd517SCristian Dumitrescu 	if (parser_read_uint32(&size, tokens[3])) {
51477a41301SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "size");
51577a41301SCristian Dumitrescu 		return;
51677a41301SCristian Dumitrescu 	}
51777a41301SCristian Dumitrescu 
518*607dd517SCristian Dumitrescu 	if (strcmp(tokens[4], "numa")) {
51977a41301SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "numa");
52077a41301SCristian Dumitrescu 		return;
52177a41301SCristian Dumitrescu 	}
52277a41301SCristian Dumitrescu 
523*607dd517SCristian Dumitrescu 	if (parser_read_uint32(&numa_node, tokens[5])) {
52477a41301SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "numa_node");
52577a41301SCristian Dumitrescu 		return;
52677a41301SCristian Dumitrescu 	}
52777a41301SCristian Dumitrescu 
528*607dd517SCristian Dumitrescu 	r = rte_ring_create(
529*607dd517SCristian Dumitrescu 		name,
530*607dd517SCristian Dumitrescu 		size,
531*607dd517SCristian Dumitrescu 		(int)numa_node,
532*607dd517SCristian Dumitrescu 		RING_F_SP_ENQ | RING_F_SC_DEQ);
533*607dd517SCristian Dumitrescu 	if (!r) {
53477a41301SCristian Dumitrescu 		snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
53577a41301SCristian Dumitrescu 		return;
53677a41301SCristian Dumitrescu 	}
53777a41301SCristian Dumitrescu }
53877a41301SCristian Dumitrescu 
5399043f66aSCristian Dumitrescu static const char cmd_pipeline_codegen_help[] =
5409043f66aSCristian Dumitrescu "pipeline codegen <spec_file> <code_file>\n";
5419043f66aSCristian Dumitrescu 
5429043f66aSCristian Dumitrescu static void
5439043f66aSCristian Dumitrescu cmd_pipeline_codegen(char **tokens,
5449043f66aSCristian Dumitrescu 	uint32_t n_tokens,
5459043f66aSCristian Dumitrescu 	char *out,
5469043f66aSCristian Dumitrescu 	size_t out_size,
5479043f66aSCristian Dumitrescu 	void *obj __rte_unused)
5489043f66aSCristian Dumitrescu {
5499043f66aSCristian Dumitrescu 	FILE *spec_file = NULL;
5509043f66aSCristian Dumitrescu 	FILE *code_file = NULL;
5519043f66aSCristian Dumitrescu 	uint32_t err_line;
5529043f66aSCristian Dumitrescu 	const char *err_msg;
5539043f66aSCristian Dumitrescu 	int status;
5549043f66aSCristian Dumitrescu 
5559043f66aSCristian Dumitrescu 	if (n_tokens != 4) {
5569043f66aSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
5579043f66aSCristian Dumitrescu 		return;
5589043f66aSCristian Dumitrescu 	}
5599043f66aSCristian Dumitrescu 
5609043f66aSCristian Dumitrescu 	spec_file = fopen(tokens[2], "r");
5619043f66aSCristian Dumitrescu 	if (!spec_file) {
5629043f66aSCristian Dumitrescu 		snprintf(out, out_size, "Cannot open file %s.\n", tokens[2]);
5639043f66aSCristian Dumitrescu 		return;
5649043f66aSCristian Dumitrescu 	}
5659043f66aSCristian Dumitrescu 
5669043f66aSCristian Dumitrescu 	code_file = fopen(tokens[3], "w");
5679043f66aSCristian Dumitrescu 	if (!code_file) {
5689043f66aSCristian Dumitrescu 		snprintf(out, out_size, "Cannot open file %s.\n", tokens[3]);
569ab492f94SHarshad Narayane 		fclose(spec_file);
5709043f66aSCristian Dumitrescu 		return;
5719043f66aSCristian Dumitrescu 	}
5729043f66aSCristian Dumitrescu 
5739043f66aSCristian Dumitrescu 	status = rte_swx_pipeline_codegen(spec_file,
5749043f66aSCristian Dumitrescu 					  code_file,
5759043f66aSCristian Dumitrescu 					  &err_line,
5769043f66aSCristian Dumitrescu 					  &err_msg);
5779043f66aSCristian Dumitrescu 
5789043f66aSCristian Dumitrescu 	fclose(spec_file);
5799043f66aSCristian Dumitrescu 	fclose(code_file);
5809043f66aSCristian Dumitrescu 
5819043f66aSCristian Dumitrescu 	if (status) {
5829043f66aSCristian Dumitrescu 		snprintf(out, out_size, "Error %d at line %u: %s\n.",
5839043f66aSCristian Dumitrescu 			status, err_line, err_msg);
5849043f66aSCristian Dumitrescu 		return;
5859043f66aSCristian Dumitrescu 	}
5869043f66aSCristian Dumitrescu }
5876bc14d9fSCristian Dumitrescu 
5886bc14d9fSCristian Dumitrescu static const char cmd_pipeline_libbuild_help[] =
5896bc14d9fSCristian Dumitrescu "pipeline libbuild <code_file> <lib_file>\n";
5906bc14d9fSCristian Dumitrescu 
5916bc14d9fSCristian Dumitrescu static void
5926bc14d9fSCristian Dumitrescu cmd_pipeline_libbuild(char **tokens,
5936bc14d9fSCristian Dumitrescu 	uint32_t n_tokens,
5946bc14d9fSCristian Dumitrescu 	char *out,
5956bc14d9fSCristian Dumitrescu 	size_t out_size,
5966bc14d9fSCristian Dumitrescu 	void *obj __rte_unused)
5976bc14d9fSCristian Dumitrescu {
5986bc14d9fSCristian Dumitrescu 	char *code_file, *lib_file, *obj_file = NULL, *log_file = NULL;
5996bc14d9fSCristian Dumitrescu 	char *install_dir, *cwd = NULL, *buffer = NULL;
6006bc14d9fSCristian Dumitrescu 	size_t length;
6016bc14d9fSCristian Dumitrescu 	int status = 0;
6026bc14d9fSCristian Dumitrescu 
6036bc14d9fSCristian Dumitrescu 	if (n_tokens != 4) {
6046bc14d9fSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
6056bc14d9fSCristian Dumitrescu 		goto free;
6066bc14d9fSCristian Dumitrescu 	}
6076bc14d9fSCristian Dumitrescu 
6086bc14d9fSCristian Dumitrescu 	install_dir = getenv("RTE_INSTALL_DIR");
6096bc14d9fSCristian Dumitrescu 	if (!install_dir) {
6106bc14d9fSCristian Dumitrescu 		cwd = malloc(MAX_LINE_SIZE);
6116bc14d9fSCristian Dumitrescu 		if (!cwd) {
6126bc14d9fSCristian Dumitrescu 			snprintf(out, out_size, MSG_OUT_OF_MEMORY);
6136bc14d9fSCristian Dumitrescu 			goto free;
6146bc14d9fSCristian Dumitrescu 		}
6156bc14d9fSCristian Dumitrescu 
6166bc14d9fSCristian Dumitrescu 		install_dir = getcwd(cwd, MAX_LINE_SIZE);
6176bc14d9fSCristian Dumitrescu 		if (!install_dir) {
6186bc14d9fSCristian Dumitrescu 			snprintf(out, out_size, "Error: Path too long.\n");
6196bc14d9fSCristian Dumitrescu 			goto free;
6206bc14d9fSCristian Dumitrescu 		}
6216bc14d9fSCristian Dumitrescu 	}
6226bc14d9fSCristian Dumitrescu 
6236bc14d9fSCristian Dumitrescu 	snprintf(out, out_size, "Using DPDK source code from \"%s\".\n", install_dir);
6246bc14d9fSCristian Dumitrescu 	out_size -= strlen(out);
6256bc14d9fSCristian Dumitrescu 	out += strlen(out);
6266bc14d9fSCristian Dumitrescu 
6276bc14d9fSCristian Dumitrescu 	code_file = tokens[2];
6286bc14d9fSCristian Dumitrescu 	length = strnlen(code_file, MAX_LINE_SIZE);
6296bc14d9fSCristian Dumitrescu 	if ((length < 3) ||
6306bc14d9fSCristian Dumitrescu 	    (code_file[length - 2] != '.') ||
6316bc14d9fSCristian Dumitrescu 	    (code_file[length - 1] != 'c')) {
6326bc14d9fSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "code_file");
6336bc14d9fSCristian Dumitrescu 		goto free;
6346bc14d9fSCristian Dumitrescu 	}
6356bc14d9fSCristian Dumitrescu 
6366bc14d9fSCristian Dumitrescu 	lib_file = tokens[3];
6376bc14d9fSCristian Dumitrescu 	length = strnlen(lib_file, MAX_LINE_SIZE);
6386bc14d9fSCristian Dumitrescu 	if ((length < 4) ||
6396bc14d9fSCristian Dumitrescu 	    (lib_file[length - 3] != '.') ||
6406bc14d9fSCristian Dumitrescu 	    (lib_file[length - 2] != 's') ||
6416bc14d9fSCristian Dumitrescu 	    (lib_file[length - 1] != 'o')) {
6426bc14d9fSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "lib_file");
6436bc14d9fSCristian Dumitrescu 		goto free;
6446bc14d9fSCristian Dumitrescu 	}
6456bc14d9fSCristian Dumitrescu 
6466bc14d9fSCristian Dumitrescu 	obj_file = malloc(length);
6476bc14d9fSCristian Dumitrescu 	log_file = malloc(length + 2);
6486bc14d9fSCristian Dumitrescu 	if (!obj_file || !log_file) {
6496bc14d9fSCristian Dumitrescu 		snprintf(out, out_size, MSG_OUT_OF_MEMORY);
6506bc14d9fSCristian Dumitrescu 		goto free;
6516bc14d9fSCristian Dumitrescu 	}
6526bc14d9fSCristian Dumitrescu 
6536bc14d9fSCristian Dumitrescu 	memcpy(obj_file, lib_file, length - 2);
6546bc14d9fSCristian Dumitrescu 	obj_file[length - 2] = 'o';
6556bc14d9fSCristian Dumitrescu 	obj_file[length - 1] = 0;
6566bc14d9fSCristian Dumitrescu 
6576bc14d9fSCristian Dumitrescu 	memcpy(log_file, lib_file, length - 2);
6586bc14d9fSCristian Dumitrescu 	log_file[length - 2] = 'l';
6596bc14d9fSCristian Dumitrescu 	log_file[length - 1] = 'o';
6606bc14d9fSCristian Dumitrescu 	log_file[length] = 'g';
6616bc14d9fSCristian Dumitrescu 	log_file[length + 1] = 0;
6626bc14d9fSCristian Dumitrescu 
6636bc14d9fSCristian Dumitrescu 	buffer = malloc(MAX_LINE_SIZE);
6646bc14d9fSCristian Dumitrescu 	if (!buffer) {
6656bc14d9fSCristian Dumitrescu 		snprintf(out, out_size, MSG_OUT_OF_MEMORY);
666b42f3e2fSHarshad Narayane 		goto free;
6676bc14d9fSCristian Dumitrescu 	}
6686bc14d9fSCristian Dumitrescu 
6696bc14d9fSCristian Dumitrescu 	snprintf(buffer,
6706bc14d9fSCristian Dumitrescu 		 MAX_LINE_SIZE,
6716bc14d9fSCristian Dumitrescu 		 "gcc -c -O3 -fpic -Wno-deprecated-declarations -o %s %s "
6726bc14d9fSCristian Dumitrescu 		 "-I %s/lib/pipeline "
6736bc14d9fSCristian Dumitrescu 		 "-I %s/lib/eal/include "
6746bc14d9fSCristian Dumitrescu 		 "-I %s/lib/eal/x86/include "
6756bc14d9fSCristian Dumitrescu 		 "-I %s/lib/eal/include/generic "
6766bc14d9fSCristian Dumitrescu 		 "-I %s/lib/meter "
6776bc14d9fSCristian Dumitrescu 		 "-I %s/lib/port "
6786bc14d9fSCristian Dumitrescu 		 "-I %s/lib/table "
6796bc14d9fSCristian Dumitrescu 		 "-I %s/lib/pipeline "
6806bc14d9fSCristian Dumitrescu 		 "-I %s/config "
6816bc14d9fSCristian Dumitrescu 		 "-I %s/build "
6826bc14d9fSCristian Dumitrescu 		 "-I %s/lib/eal/linux/include "
6836bc14d9fSCristian Dumitrescu 		 ">%s 2>&1 "
6846bc14d9fSCristian Dumitrescu 		 "&& "
6856bc14d9fSCristian Dumitrescu 		 "gcc -shared %s -o %s "
6866bc14d9fSCristian Dumitrescu 		 ">>%s 2>&1",
6876bc14d9fSCristian Dumitrescu 		 obj_file,
6886bc14d9fSCristian Dumitrescu 		 code_file,
6896bc14d9fSCristian Dumitrescu 		 install_dir,
6906bc14d9fSCristian Dumitrescu 		 install_dir,
6916bc14d9fSCristian Dumitrescu 		 install_dir,
6926bc14d9fSCristian Dumitrescu 		 install_dir,
6936bc14d9fSCristian Dumitrescu 		 install_dir,
6946bc14d9fSCristian Dumitrescu 		 install_dir,
6956bc14d9fSCristian Dumitrescu 		 install_dir,
6966bc14d9fSCristian Dumitrescu 		 install_dir,
6976bc14d9fSCristian Dumitrescu 		 install_dir,
6986bc14d9fSCristian Dumitrescu 		 install_dir,
6996bc14d9fSCristian Dumitrescu 		 install_dir,
7006bc14d9fSCristian Dumitrescu 		 log_file,
7016bc14d9fSCristian Dumitrescu 		 obj_file,
7026bc14d9fSCristian Dumitrescu 		 lib_file,
7036bc14d9fSCristian Dumitrescu 		 log_file);
7046bc14d9fSCristian Dumitrescu 
7056bc14d9fSCristian Dumitrescu 	status = system(buffer);
7066bc14d9fSCristian Dumitrescu 	if (status) {
7076bc14d9fSCristian Dumitrescu 		snprintf(out,
7086bc14d9fSCristian Dumitrescu 			 out_size,
7096bc14d9fSCristian Dumitrescu 			 "Library build failed, see file \"%s\" for details.\n",
7106bc14d9fSCristian Dumitrescu 			 log_file);
7116bc14d9fSCristian Dumitrescu 		goto free;
7126bc14d9fSCristian Dumitrescu 	}
7136bc14d9fSCristian Dumitrescu 
7146bc14d9fSCristian Dumitrescu free:
7156bc14d9fSCristian Dumitrescu 	free(cwd);
7166bc14d9fSCristian Dumitrescu 	free(obj_file);
7176bc14d9fSCristian Dumitrescu 	free(log_file);
7186bc14d9fSCristian Dumitrescu 	free(buffer);
7196bc14d9fSCristian Dumitrescu }
7206bc14d9fSCristian Dumitrescu 
7215074e1d5SCristian Dumitrescu static const char cmd_pipeline_build_help[] =
72268b95704SCristian Dumitrescu "pipeline <pipeline_name> build lib <lib_file> io <iospec_file> numa <numa_node>\n";
7235074e1d5SCristian Dumitrescu 
7245074e1d5SCristian Dumitrescu static void
7255074e1d5SCristian Dumitrescu cmd_pipeline_build(char **tokens,
7265074e1d5SCristian Dumitrescu 	uint32_t n_tokens,
7275074e1d5SCristian Dumitrescu 	char *out,
7285074e1d5SCristian Dumitrescu 	size_t out_size,
72968b95704SCristian Dumitrescu 	void *obj __rte_unused)
7305074e1d5SCristian Dumitrescu {
73168b95704SCristian Dumitrescu 	struct rte_swx_pipeline *p = NULL;
73268b95704SCristian Dumitrescu 	struct rte_swx_ctl_pipeline *ctl = NULL;
73368b95704SCristian Dumitrescu 	char *pipeline_name, *lib_file_name, *iospec_file_name;
73468b95704SCristian Dumitrescu 	FILE *iospec_file = NULL;
73568b95704SCristian Dumitrescu 	uint32_t numa_node = 0;
73668b95704SCristian Dumitrescu 	int status = 0;
7375074e1d5SCristian Dumitrescu 
73868b95704SCristian Dumitrescu 	/* Parsing. */
73968b95704SCristian Dumitrescu 	if (n_tokens != 9) {
7405074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
7415074e1d5SCristian Dumitrescu 		return;
7425074e1d5SCristian Dumitrescu 	}
7435074e1d5SCristian Dumitrescu 
74468b95704SCristian Dumitrescu 	pipeline_name = tokens[1];
74568b95704SCristian Dumitrescu 
74668b95704SCristian Dumitrescu 	if (strcmp(tokens[2], "build")) {
74768b95704SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "build");
7485074e1d5SCristian Dumitrescu 		return;
7495074e1d5SCristian Dumitrescu 	}
7505074e1d5SCristian Dumitrescu 
75168b95704SCristian Dumitrescu 	if (strcmp(tokens[3], "lib")) {
75268b95704SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "lib");
7535074e1d5SCristian Dumitrescu 		return;
7545074e1d5SCristian Dumitrescu 	}
7555074e1d5SCristian Dumitrescu 
75668b95704SCristian Dumitrescu 	lib_file_name = tokens[4];
75768b95704SCristian Dumitrescu 
75868b95704SCristian Dumitrescu 	if (strcmp(tokens[5], "io")) {
75968b95704SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "io");
76068b95704SCristian Dumitrescu 		return;
76168b95704SCristian Dumitrescu 	}
76268b95704SCristian Dumitrescu 
76368b95704SCristian Dumitrescu 	iospec_file_name = tokens[6];
76468b95704SCristian Dumitrescu 
76568b95704SCristian Dumitrescu 	if (strcmp(tokens[7], "numa")) {
76668b95704SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "numa");
76768b95704SCristian Dumitrescu 		return;
76868b95704SCristian Dumitrescu 	}
76968b95704SCristian Dumitrescu 
77068b95704SCristian Dumitrescu 	if (parser_read_uint32(&numa_node, tokens[8])) {
77168b95704SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "numa_node");
77268b95704SCristian Dumitrescu 		return;
77368b95704SCristian Dumitrescu 	}
77468b95704SCristian Dumitrescu 
77568b95704SCristian Dumitrescu 	/* I/O spec file open. */
77668b95704SCristian Dumitrescu 	iospec_file = fopen(iospec_file_name, "r");
77768b95704SCristian Dumitrescu 	if (!iospec_file) {
77868b95704SCristian Dumitrescu 		snprintf(out, out_size, "Cannot open file \"%s\".\n", iospec_file_name);
77968b95704SCristian Dumitrescu 		return;
78068b95704SCristian Dumitrescu 	}
78168b95704SCristian Dumitrescu 
78268b95704SCristian Dumitrescu 	status = rte_swx_pipeline_build_from_lib(&p,
78368b95704SCristian Dumitrescu 						 pipeline_name,
78468b95704SCristian Dumitrescu 						 lib_file_name,
78568b95704SCristian Dumitrescu 						 iospec_file,
78668b95704SCristian Dumitrescu 						 (int)numa_node);
7875074e1d5SCristian Dumitrescu 	if (status) {
78868b95704SCristian Dumitrescu 		snprintf(out, out_size, "Pipeline build failed (%d).", status);
78968b95704SCristian Dumitrescu 		goto free;
7905074e1d5SCristian Dumitrescu 	}
7915074e1d5SCristian Dumitrescu 
79268b95704SCristian Dumitrescu 	ctl = rte_swx_ctl_pipeline_create(p);
79368b95704SCristian Dumitrescu 	if (!ctl) {
7945074e1d5SCristian Dumitrescu 		snprintf(out, out_size, "Pipeline control create failed.");
79568b95704SCristian Dumitrescu 		goto free;
7965074e1d5SCristian Dumitrescu 	}
79768b95704SCristian Dumitrescu 
79868b95704SCristian Dumitrescu free:
79968b95704SCristian Dumitrescu 	if (status)
80068b95704SCristian Dumitrescu 		rte_swx_pipeline_free(p);
80168b95704SCristian Dumitrescu 
80268b95704SCristian Dumitrescu 	if (iospec_file)
80368b95704SCristian Dumitrescu 		fclose(iospec_file);
8045074e1d5SCristian Dumitrescu }
8055074e1d5SCristian Dumitrescu 
80675129cebSChurchill Khangar static int
80775129cebSChurchill Khangar pipeline_table_entries_add(struct rte_swx_ctl_pipeline *p,
80875129cebSChurchill Khangar 			   const char *table_name,
80975129cebSChurchill Khangar 			   FILE *file,
81075129cebSChurchill Khangar 			   uint32_t *file_line_number)
81175129cebSChurchill Khangar {
81275129cebSChurchill Khangar 	char *line = NULL;
81375129cebSChurchill Khangar 	uint32_t line_id = 0;
81475129cebSChurchill Khangar 	int status = 0;
81575129cebSChurchill Khangar 
81675129cebSChurchill Khangar 	/* Buffer allocation. */
81775129cebSChurchill Khangar 	line = malloc(MAX_LINE_SIZE);
81875129cebSChurchill Khangar 	if (!line)
81975129cebSChurchill Khangar 		return -ENOMEM;
82075129cebSChurchill Khangar 
82175129cebSChurchill Khangar 	/* File read. */
82275129cebSChurchill Khangar 	for (line_id = 1; ; line_id++) {
82375129cebSChurchill Khangar 		struct rte_swx_table_entry *entry;
82475129cebSChurchill Khangar 		int is_blank_or_comment;
82575129cebSChurchill Khangar 
82675129cebSChurchill Khangar 		if (fgets(line, MAX_LINE_SIZE, file) == NULL)
82775129cebSChurchill Khangar 			break;
82875129cebSChurchill Khangar 
82975129cebSChurchill Khangar 		entry = rte_swx_ctl_pipeline_table_entry_read(p,
83075129cebSChurchill Khangar 							      table_name,
83175129cebSChurchill Khangar 							      line,
83275129cebSChurchill Khangar 							      &is_blank_or_comment);
83375129cebSChurchill Khangar 		if (!entry) {
83475129cebSChurchill Khangar 			if (is_blank_or_comment)
83575129cebSChurchill Khangar 				continue;
83675129cebSChurchill Khangar 
83775129cebSChurchill Khangar 			status = -EINVAL;
83875129cebSChurchill Khangar 			goto error;
83975129cebSChurchill Khangar 		}
84075129cebSChurchill Khangar 
84175129cebSChurchill Khangar 		status = rte_swx_ctl_pipeline_table_entry_add(p,
84275129cebSChurchill Khangar 							      table_name,
84375129cebSChurchill Khangar 							      entry);
84475129cebSChurchill Khangar 		table_entry_free(entry);
84575129cebSChurchill Khangar 		if (status)
84675129cebSChurchill Khangar 			goto error;
84775129cebSChurchill Khangar 	}
84875129cebSChurchill Khangar 
84975129cebSChurchill Khangar error:
85075129cebSChurchill Khangar 	free(line);
85175129cebSChurchill Khangar 	*file_line_number = line_id;
85275129cebSChurchill Khangar 	return status;
85375129cebSChurchill Khangar }
85475129cebSChurchill Khangar 
85575129cebSChurchill Khangar static const char cmd_pipeline_table_add_help[] =
85675129cebSChurchill Khangar "pipeline <pipeline_name> table <table_name> add <file_name>\n";
8575074e1d5SCristian Dumitrescu 
8585074e1d5SCristian Dumitrescu static void
85975129cebSChurchill Khangar cmd_pipeline_table_add(char **tokens,
8605074e1d5SCristian Dumitrescu 		       uint32_t n_tokens,
8615074e1d5SCristian Dumitrescu 		       char *out,
8625074e1d5SCristian Dumitrescu 		       size_t out_size,
863b9559f94SCristian Dumitrescu 		       void *obj __rte_unused)
8645074e1d5SCristian Dumitrescu {
865b9559f94SCristian Dumitrescu 	struct rte_swx_ctl_pipeline *ctl;
86675129cebSChurchill Khangar 	char *pipeline_name, *table_name, *file_name;
86775129cebSChurchill Khangar 	FILE *file = NULL;
86875129cebSChurchill Khangar 	uint32_t file_line_number = 0;
8695074e1d5SCristian Dumitrescu 	int status;
8705074e1d5SCristian Dumitrescu 
87175129cebSChurchill Khangar 	if (n_tokens != 6) {
8725074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
8735074e1d5SCristian Dumitrescu 		return;
8745074e1d5SCristian Dumitrescu 	}
8755074e1d5SCristian Dumitrescu 
8765074e1d5SCristian Dumitrescu 	pipeline_name = tokens[1];
877b9559f94SCristian Dumitrescu 	ctl = rte_swx_ctl_pipeline_find(pipeline_name);
878b9559f94SCristian Dumitrescu 	if (!ctl) {
8795074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
8805074e1d5SCristian Dumitrescu 		return;
8815074e1d5SCristian Dumitrescu 	}
8825074e1d5SCristian Dumitrescu 
88375129cebSChurchill Khangar 	table_name = tokens[3];
88475129cebSChurchill Khangar 
88575129cebSChurchill Khangar 	file_name = tokens[5];
88675129cebSChurchill Khangar 	file = fopen(file_name, "r");
88775129cebSChurchill Khangar 	if (!file) {
88875129cebSChurchill Khangar 		snprintf(out, out_size, "Cannot open file %s.\n", file_name);
88975129cebSChurchill Khangar 		return;
89075129cebSChurchill Khangar 	}
89175129cebSChurchill Khangar 
892b9559f94SCristian Dumitrescu 	status = pipeline_table_entries_add(ctl,
89375129cebSChurchill Khangar 					    table_name,
89475129cebSChurchill Khangar 					    file,
89575129cebSChurchill Khangar 					    &file_line_number);
89675129cebSChurchill Khangar 	if (status)
89775129cebSChurchill Khangar 		snprintf(out, out_size, "Invalid entry in file %s at line %u\n",
89875129cebSChurchill Khangar 			 file_name,
89975129cebSChurchill Khangar 			 file_line_number);
90075129cebSChurchill Khangar 
90175129cebSChurchill Khangar 	fclose(file);
90275129cebSChurchill Khangar }
90375129cebSChurchill Khangar 
90475129cebSChurchill Khangar static int
90575129cebSChurchill Khangar pipeline_table_entries_delete(struct rte_swx_ctl_pipeline *p,
90675129cebSChurchill Khangar 			      const char *table_name,
90775129cebSChurchill Khangar 			      FILE *file,
90875129cebSChurchill Khangar 			      uint32_t *file_line_number)
90975129cebSChurchill Khangar {
91075129cebSChurchill Khangar 	char *line = NULL;
91175129cebSChurchill Khangar 	uint32_t line_id = 0;
91275129cebSChurchill Khangar 	int status = 0;
91375129cebSChurchill Khangar 
91475129cebSChurchill Khangar 	/* Buffer allocation. */
91575129cebSChurchill Khangar 	line = malloc(MAX_LINE_SIZE);
91675129cebSChurchill Khangar 	if (!line)
91775129cebSChurchill Khangar 		return -ENOMEM;
91875129cebSChurchill Khangar 
91975129cebSChurchill Khangar 	/* File read. */
92075129cebSChurchill Khangar 	for (line_id = 1; ; line_id++) {
92175129cebSChurchill Khangar 		struct rte_swx_table_entry *entry;
92275129cebSChurchill Khangar 		int is_blank_or_comment;
92375129cebSChurchill Khangar 
92475129cebSChurchill Khangar 		if (fgets(line, MAX_LINE_SIZE, file) == NULL)
92575129cebSChurchill Khangar 			break;
92675129cebSChurchill Khangar 
92775129cebSChurchill Khangar 		entry = rte_swx_ctl_pipeline_table_entry_read(p,
92875129cebSChurchill Khangar 							      table_name,
92975129cebSChurchill Khangar 							      line,
93075129cebSChurchill Khangar 							      &is_blank_or_comment);
93175129cebSChurchill Khangar 		if (!entry) {
93275129cebSChurchill Khangar 			if (is_blank_or_comment)
93375129cebSChurchill Khangar 				continue;
93475129cebSChurchill Khangar 
93575129cebSChurchill Khangar 			status = -EINVAL;
93675129cebSChurchill Khangar 			goto error;
93775129cebSChurchill Khangar 		}
93875129cebSChurchill Khangar 
93975129cebSChurchill Khangar 		status = rte_swx_ctl_pipeline_table_entry_delete(p,
94075129cebSChurchill Khangar 								 table_name,
94175129cebSChurchill Khangar 								 entry);
94275129cebSChurchill Khangar 		table_entry_free(entry);
94375129cebSChurchill Khangar 		if (status)
94475129cebSChurchill Khangar 			goto error;
94575129cebSChurchill Khangar 	}
94675129cebSChurchill Khangar 
94775129cebSChurchill Khangar error:
94875129cebSChurchill Khangar 	*file_line_number = line_id;
94975129cebSChurchill Khangar 	free(line);
95075129cebSChurchill Khangar 	return status;
95175129cebSChurchill Khangar }
95275129cebSChurchill Khangar 
95375129cebSChurchill Khangar static const char cmd_pipeline_table_delete_help[] =
95475129cebSChurchill Khangar "pipeline <pipeline_name> table <table_name> delete <file_name>\n";
95575129cebSChurchill Khangar 
95675129cebSChurchill Khangar static void
95775129cebSChurchill Khangar cmd_pipeline_table_delete(char **tokens,
95875129cebSChurchill Khangar 			  uint32_t n_tokens,
95975129cebSChurchill Khangar 			  char *out,
96075129cebSChurchill Khangar 			  size_t out_size,
961b9559f94SCristian Dumitrescu 			  void *obj __rte_unused)
96275129cebSChurchill Khangar {
963b9559f94SCristian Dumitrescu 	struct rte_swx_ctl_pipeline *ctl;
96475129cebSChurchill Khangar 	char *pipeline_name, *table_name, *file_name;
96575129cebSChurchill Khangar 	FILE *file = NULL;
96675129cebSChurchill Khangar 	uint32_t file_line_number = 0;
96775129cebSChurchill Khangar 	int status;
96875129cebSChurchill Khangar 
96975129cebSChurchill Khangar 	if (n_tokens != 6) {
97075129cebSChurchill Khangar 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
97175129cebSChurchill Khangar 		return;
97275129cebSChurchill Khangar 	}
97375129cebSChurchill Khangar 
97475129cebSChurchill Khangar 	pipeline_name = tokens[1];
975b9559f94SCristian Dumitrescu 	ctl = rte_swx_ctl_pipeline_find(pipeline_name);
976b9559f94SCristian Dumitrescu 	if (!ctl) {
97775129cebSChurchill Khangar 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
9785074e1d5SCristian Dumitrescu 		return;
9795074e1d5SCristian Dumitrescu 	}
9805074e1d5SCristian Dumitrescu 
9815074e1d5SCristian Dumitrescu 	table_name = tokens[3];
9825074e1d5SCristian Dumitrescu 
98375129cebSChurchill Khangar 	file_name = tokens[5];
98475129cebSChurchill Khangar 	file = fopen(file_name, "r");
98575129cebSChurchill Khangar 	if (!file) {
98675129cebSChurchill Khangar 		snprintf(out, out_size, "Cannot open file %s.\n", file_name);
9875074e1d5SCristian Dumitrescu 		return;
9885074e1d5SCristian Dumitrescu 	}
9895074e1d5SCristian Dumitrescu 
990b9559f94SCristian Dumitrescu 	status = pipeline_table_entries_delete(ctl,
99175129cebSChurchill Khangar 					       table_name,
99275129cebSChurchill Khangar 					       file,
99375129cebSChurchill Khangar 					       &file_line_number);
99475129cebSChurchill Khangar 	if (status)
99575129cebSChurchill Khangar 		snprintf(out, out_size, "Invalid entry in file %s at line %u\n",
99675129cebSChurchill Khangar 			 file_name,
99775129cebSChurchill Khangar 			 file_line_number);
9985074e1d5SCristian Dumitrescu 
99975129cebSChurchill Khangar 	fclose(file);
10005074e1d5SCristian Dumitrescu }
10015074e1d5SCristian Dumitrescu 
100275129cebSChurchill Khangar static int
100375129cebSChurchill Khangar pipeline_table_default_entry_add(struct rte_swx_ctl_pipeline *p,
100475129cebSChurchill Khangar 				 const char *table_name,
100575129cebSChurchill Khangar 				 FILE *file,
100675129cebSChurchill Khangar 				 uint32_t *file_line_number)
100775129cebSChurchill Khangar {
100875129cebSChurchill Khangar 	char *line = NULL;
100975129cebSChurchill Khangar 	uint32_t line_id = 0;
101075129cebSChurchill Khangar 	int status = 0;
10115074e1d5SCristian Dumitrescu 
10125074e1d5SCristian Dumitrescu 	/* Buffer allocation. */
101375129cebSChurchill Khangar 	line = malloc(MAX_LINE_SIZE);
101475129cebSChurchill Khangar 	if (!line)
101575129cebSChurchill Khangar 		return -ENOMEM;
10165074e1d5SCristian Dumitrescu 
101775129cebSChurchill Khangar 	/* File read. */
10185074e1d5SCristian Dumitrescu 	for (line_id = 1; ; line_id++) {
10195074e1d5SCristian Dumitrescu 		struct rte_swx_table_entry *entry;
1020cff9a717SCristian Dumitrescu 		int is_blank_or_comment;
10215074e1d5SCristian Dumitrescu 
102275129cebSChurchill Khangar 		if (fgets(line, MAX_LINE_SIZE, file) == NULL)
10235074e1d5SCristian Dumitrescu 			break;
10245074e1d5SCristian Dumitrescu 
102575129cebSChurchill Khangar 		entry = rte_swx_ctl_pipeline_table_entry_read(p,
10265074e1d5SCristian Dumitrescu 							      table_name,
1027cff9a717SCristian Dumitrescu 							      line,
1028cff9a717SCristian Dumitrescu 							      &is_blank_or_comment);
10295074e1d5SCristian Dumitrescu 		if (!entry) {
1030cff9a717SCristian Dumitrescu 			if (is_blank_or_comment)
1031cff9a717SCristian Dumitrescu 				continue;
1032cff9a717SCristian Dumitrescu 
103375129cebSChurchill Khangar 			status = -EINVAL;
10345074e1d5SCristian Dumitrescu 			goto error;
10355074e1d5SCristian Dumitrescu 		}
10365074e1d5SCristian Dumitrescu 
103775129cebSChurchill Khangar 		status = rte_swx_ctl_pipeline_table_default_entry_add(p,
10385074e1d5SCristian Dumitrescu 								      table_name,
10395074e1d5SCristian Dumitrescu 								      entry);
1040275ebefeSCristian Dumitrescu 		table_entry_free(entry);
104175129cebSChurchill Khangar 		if (status)
10425074e1d5SCristian Dumitrescu 			goto error;
10435074e1d5SCristian Dumitrescu 	}
104475129cebSChurchill Khangar 
104575129cebSChurchill Khangar error:
104675129cebSChurchill Khangar 	*file_line_number = line_id;
104775129cebSChurchill Khangar 	free(line);
104875129cebSChurchill Khangar 	return status;
10495074e1d5SCristian Dumitrescu }
10505074e1d5SCristian Dumitrescu 
105175129cebSChurchill Khangar static const char cmd_pipeline_table_default_help[] =
105275129cebSChurchill Khangar "pipeline <pipeline_name> table <table_name> default <file_name>\n";
10535074e1d5SCristian Dumitrescu 
105475129cebSChurchill Khangar static void
105575129cebSChurchill Khangar cmd_pipeline_table_default(char **tokens,
105675129cebSChurchill Khangar 			   uint32_t n_tokens,
105775129cebSChurchill Khangar 			   char *out,
105875129cebSChurchill Khangar 			   size_t out_size,
1059b9559f94SCristian Dumitrescu 			   void *obj __rte_unused)
106075129cebSChurchill Khangar {
1061b9559f94SCristian Dumitrescu 	struct rte_swx_ctl_pipeline *ctl;
106275129cebSChurchill Khangar 	char *pipeline_name, *table_name, *file_name;
106375129cebSChurchill Khangar 	FILE *file = NULL;
106475129cebSChurchill Khangar 	uint32_t file_line_number = 0;
106575129cebSChurchill Khangar 	int status;
10665074e1d5SCristian Dumitrescu 
106775129cebSChurchill Khangar 	if (n_tokens != 6) {
106875129cebSChurchill Khangar 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
106975129cebSChurchill Khangar 		return;
107075129cebSChurchill Khangar 	}
10715074e1d5SCristian Dumitrescu 
107275129cebSChurchill Khangar 	pipeline_name = tokens[1];
1073b9559f94SCristian Dumitrescu 	ctl = rte_swx_ctl_pipeline_find(pipeline_name);
1074b9559f94SCristian Dumitrescu 	if (!ctl) {
107575129cebSChurchill Khangar 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
107675129cebSChurchill Khangar 		return;
107775129cebSChurchill Khangar 	}
107875129cebSChurchill Khangar 
107975129cebSChurchill Khangar 	table_name = tokens[3];
108075129cebSChurchill Khangar 
108175129cebSChurchill Khangar 	file_name = tokens[5];
108275129cebSChurchill Khangar 	file = fopen(file_name, "r");
108375129cebSChurchill Khangar 	if (!file) {
108475129cebSChurchill Khangar 		snprintf(out, out_size, "Cannot open file %s.\n", file_name);
108575129cebSChurchill Khangar 		return;
108675129cebSChurchill Khangar 	}
108775129cebSChurchill Khangar 
1088b9559f94SCristian Dumitrescu 	status = pipeline_table_default_entry_add(ctl,
10895074e1d5SCristian Dumitrescu 						  table_name,
109075129cebSChurchill Khangar 						  file,
109175129cebSChurchill Khangar 						  &file_line_number);
109275129cebSChurchill Khangar 	if (status)
109375129cebSChurchill Khangar 		snprintf(out, out_size, "Invalid entry in file %s at line %u\n",
109475129cebSChurchill Khangar 			 file_name,
109575129cebSChurchill Khangar 			 file_line_number);
1096cff9a717SCristian Dumitrescu 
109775129cebSChurchill Khangar 	fclose(file);
10985074e1d5SCristian Dumitrescu }
10995074e1d5SCristian Dumitrescu 
110075129cebSChurchill Khangar static const char cmd_pipeline_table_show_help[] =
1101a4c1146cSCristian Dumitrescu "pipeline <pipeline_name> table <table_name> show [filename]\n";
110275129cebSChurchill Khangar 
110375129cebSChurchill Khangar static void
110475129cebSChurchill Khangar cmd_pipeline_table_show(char **tokens,
110575129cebSChurchill Khangar 	uint32_t n_tokens,
110675129cebSChurchill Khangar 	char *out,
110775129cebSChurchill Khangar 	size_t out_size,
1108b9559f94SCristian Dumitrescu 	void *obj __rte_unused)
110975129cebSChurchill Khangar {
1110b9559f94SCristian Dumitrescu 	struct rte_swx_ctl_pipeline *ctl;
111175129cebSChurchill Khangar 	char *pipeline_name, *table_name;
1112a4c1146cSCristian Dumitrescu 	FILE *file = NULL;
111375129cebSChurchill Khangar 	int status;
111475129cebSChurchill Khangar 
1115a4c1146cSCristian Dumitrescu 	if (n_tokens != 5 && n_tokens != 6) {
111675129cebSChurchill Khangar 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
111775129cebSChurchill Khangar 		return;
11185074e1d5SCristian Dumitrescu 	}
11195074e1d5SCristian Dumitrescu 
112075129cebSChurchill Khangar 	pipeline_name = tokens[1];
1121b9559f94SCristian Dumitrescu 	ctl = rte_swx_ctl_pipeline_find(pipeline_name);
1122b9559f94SCristian Dumitrescu 	if (!ctl) {
112375129cebSChurchill Khangar 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
112475129cebSChurchill Khangar 		return;
11255074e1d5SCristian Dumitrescu 	}
11265074e1d5SCristian Dumitrescu 
112775129cebSChurchill Khangar 	table_name = tokens[3];
1128a4c1146cSCristian Dumitrescu 	file = (n_tokens == 6) ? fopen(tokens[5], "w") : stdout;
1129a4c1146cSCristian Dumitrescu 	if (!file) {
1130a4c1146cSCristian Dumitrescu 		snprintf(out, out_size, "Cannot open file %s.\n", tokens[5]);
1131a4c1146cSCristian Dumitrescu 		return;
1132a4c1146cSCristian Dumitrescu 	}
1133a4c1146cSCristian Dumitrescu 
1134b9559f94SCristian Dumitrescu 	status = rte_swx_ctl_pipeline_table_fprintf(file, ctl, table_name);
113575129cebSChurchill Khangar 	if (status)
113675129cebSChurchill Khangar 		snprintf(out, out_size, MSG_ARG_INVALID, "table_name");
1137a4c1146cSCristian Dumitrescu 
1138a4c1146cSCristian Dumitrescu 	if (file)
1139a4c1146cSCristian Dumitrescu 		fclose(file);
11405074e1d5SCristian Dumitrescu }
114175129cebSChurchill Khangar 
1142598fe0ddSCristian Dumitrescu static const char cmd_pipeline_selector_group_add_help[] =
1143598fe0ddSCristian Dumitrescu "pipeline <pipeline_name> selector <selector_name> group add\n";
1144598fe0ddSCristian Dumitrescu 
1145598fe0ddSCristian Dumitrescu static void
1146598fe0ddSCristian Dumitrescu cmd_pipeline_selector_group_add(char **tokens,
1147598fe0ddSCristian Dumitrescu 	uint32_t n_tokens,
1148598fe0ddSCristian Dumitrescu 	char *out,
1149598fe0ddSCristian Dumitrescu 	size_t out_size,
1150b9559f94SCristian Dumitrescu 	void *obj __rte_unused)
1151598fe0ddSCristian Dumitrescu {
1152b9559f94SCristian Dumitrescu 	struct rte_swx_ctl_pipeline *ctl;
1153598fe0ddSCristian Dumitrescu 	char *pipeline_name, *selector_name;
1154598fe0ddSCristian Dumitrescu 	uint32_t group_id;
1155598fe0ddSCristian Dumitrescu 	int status;
1156598fe0ddSCristian Dumitrescu 
1157598fe0ddSCristian Dumitrescu 	if (n_tokens != 6) {
1158598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1159598fe0ddSCristian Dumitrescu 		return;
1160598fe0ddSCristian Dumitrescu 	}
1161598fe0ddSCristian Dumitrescu 
1162598fe0ddSCristian Dumitrescu 	pipeline_name = tokens[1];
1163b9559f94SCristian Dumitrescu 	ctl = rte_swx_ctl_pipeline_find(pipeline_name);
1164b9559f94SCristian Dumitrescu 	if (!ctl) {
1165598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
1166598fe0ddSCristian Dumitrescu 		return;
1167598fe0ddSCristian Dumitrescu 	}
1168598fe0ddSCristian Dumitrescu 
1169598fe0ddSCristian Dumitrescu 	if (strcmp(tokens[2], "selector") != 0) {
1170598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "selector");
1171598fe0ddSCristian Dumitrescu 		return;
1172598fe0ddSCristian Dumitrescu 	}
1173598fe0ddSCristian Dumitrescu 
1174598fe0ddSCristian Dumitrescu 	selector_name = tokens[3];
1175598fe0ddSCristian Dumitrescu 
1176598fe0ddSCristian Dumitrescu 	if (strcmp(tokens[4], "group") ||
1177598fe0ddSCristian Dumitrescu 		strcmp(tokens[5], "add")) {
1178598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "group add");
1179598fe0ddSCristian Dumitrescu 		return;
1180598fe0ddSCristian Dumitrescu 	}
1181598fe0ddSCristian Dumitrescu 
1182b9559f94SCristian Dumitrescu 	status = rte_swx_ctl_pipeline_selector_group_add(ctl,
1183598fe0ddSCristian Dumitrescu 		selector_name,
1184598fe0ddSCristian Dumitrescu 		&group_id);
1185598fe0ddSCristian Dumitrescu 	if (status)
1186598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
1187598fe0ddSCristian Dumitrescu 	else
1188598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, "Group ID: %u\n", group_id);
1189598fe0ddSCristian Dumitrescu }
1190598fe0ddSCristian Dumitrescu 
1191598fe0ddSCristian Dumitrescu static const char cmd_pipeline_selector_group_delete_help[] =
1192598fe0ddSCristian Dumitrescu "pipeline <pipeline_name> selector <selector_name> group delete <group_id>\n";
1193598fe0ddSCristian Dumitrescu 
1194598fe0ddSCristian Dumitrescu static void
1195598fe0ddSCristian Dumitrescu cmd_pipeline_selector_group_delete(char **tokens,
1196598fe0ddSCristian Dumitrescu 	uint32_t n_tokens,
1197598fe0ddSCristian Dumitrescu 	char *out,
1198598fe0ddSCristian Dumitrescu 	size_t out_size,
1199b9559f94SCristian Dumitrescu 	void *obj __rte_unused)
1200598fe0ddSCristian Dumitrescu {
1201b9559f94SCristian Dumitrescu 	struct rte_swx_ctl_pipeline *ctl;
1202598fe0ddSCristian Dumitrescu 	char *pipeline_name, *selector_name;
1203598fe0ddSCristian Dumitrescu 	uint32_t group_id;
1204598fe0ddSCristian Dumitrescu 	int status;
1205598fe0ddSCristian Dumitrescu 
1206598fe0ddSCristian Dumitrescu 	if (n_tokens != 7) {
1207598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1208598fe0ddSCristian Dumitrescu 		return;
1209598fe0ddSCristian Dumitrescu 	}
1210598fe0ddSCristian Dumitrescu 
1211598fe0ddSCristian Dumitrescu 	pipeline_name = tokens[1];
1212b9559f94SCristian Dumitrescu 	ctl = rte_swx_ctl_pipeline_find(pipeline_name);
1213b9559f94SCristian Dumitrescu 	if (!ctl) {
1214598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
1215598fe0ddSCristian Dumitrescu 		return;
1216598fe0ddSCristian Dumitrescu 	}
1217598fe0ddSCristian Dumitrescu 
1218598fe0ddSCristian Dumitrescu 	if (strcmp(tokens[2], "selector") != 0) {
1219598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "selector");
1220598fe0ddSCristian Dumitrescu 		return;
1221598fe0ddSCristian Dumitrescu 	}
1222598fe0ddSCristian Dumitrescu 
1223598fe0ddSCristian Dumitrescu 	selector_name = tokens[3];
1224598fe0ddSCristian Dumitrescu 
1225598fe0ddSCristian Dumitrescu 	if (strcmp(tokens[4], "group") ||
1226598fe0ddSCristian Dumitrescu 		strcmp(tokens[5], "delete")) {
1227598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "group delete");
1228598fe0ddSCristian Dumitrescu 		return;
1229598fe0ddSCristian Dumitrescu 	}
1230598fe0ddSCristian Dumitrescu 
1231598fe0ddSCristian Dumitrescu 	if (parser_read_uint32(&group_id, tokens[6]) != 0) {
1232598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "group_id");
1233598fe0ddSCristian Dumitrescu 		return;
1234598fe0ddSCristian Dumitrescu 	}
1235598fe0ddSCristian Dumitrescu 
1236b9559f94SCristian Dumitrescu 	status = rte_swx_ctl_pipeline_selector_group_delete(ctl,
1237598fe0ddSCristian Dumitrescu 		selector_name,
1238598fe0ddSCristian Dumitrescu 		group_id);
1239598fe0ddSCristian Dumitrescu 	if (status)
1240598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
1241598fe0ddSCristian Dumitrescu }
1242598fe0ddSCristian Dumitrescu 
1243598fe0ddSCristian Dumitrescu #define GROUP_MEMBER_INFO_TOKENS_MAX 6
1244598fe0ddSCristian Dumitrescu 
1245598fe0ddSCristian Dumitrescu static int
1246598fe0ddSCristian Dumitrescu token_is_comment(const char *token)
1247598fe0ddSCristian Dumitrescu {
1248598fe0ddSCristian Dumitrescu 	if ((token[0] == '#') ||
1249598fe0ddSCristian Dumitrescu 	    (token[0] == ';') ||
1250598fe0ddSCristian Dumitrescu 	    ((token[0] == '/') && (token[1] == '/')))
1251598fe0ddSCristian Dumitrescu 		return 1; /* TRUE. */
1252598fe0ddSCristian Dumitrescu 
1253598fe0ddSCristian Dumitrescu 	return 0; /* FALSE. */
1254598fe0ddSCristian Dumitrescu }
1255598fe0ddSCristian Dumitrescu 
1256598fe0ddSCristian Dumitrescu static int
1257598fe0ddSCristian Dumitrescu pipeline_selector_group_member_read(const char *string,
1258598fe0ddSCristian Dumitrescu 				      uint32_t *group_id,
1259598fe0ddSCristian Dumitrescu 				      uint32_t *member_id,
1260598fe0ddSCristian Dumitrescu 				      uint32_t *weight,
1261598fe0ddSCristian Dumitrescu 				      int *is_blank_or_comment)
1262598fe0ddSCristian Dumitrescu {
1263598fe0ddSCristian Dumitrescu 	char *token_array[GROUP_MEMBER_INFO_TOKENS_MAX], **tokens;
1264598fe0ddSCristian Dumitrescu 	char *s0 = NULL, *s;
126500b67591SAli Alnubani 	uint32_t n_tokens = 0, group_id_val = 0, member_id_val = 0, weight_val = 0;
1266598fe0ddSCristian Dumitrescu 	int blank_or_comment = 0;
1267598fe0ddSCristian Dumitrescu 
1268598fe0ddSCristian Dumitrescu 	/* Check input arguments. */
1269598fe0ddSCristian Dumitrescu 	if (!string || !string[0])
1270598fe0ddSCristian Dumitrescu 		goto error;
1271598fe0ddSCristian Dumitrescu 
1272598fe0ddSCristian Dumitrescu 	/* Memory allocation. */
1273598fe0ddSCristian Dumitrescu 	s0 = strdup(string);
1274598fe0ddSCristian Dumitrescu 	if (!s0)
1275598fe0ddSCristian Dumitrescu 		goto error;
1276598fe0ddSCristian Dumitrescu 
1277598fe0ddSCristian Dumitrescu 	/* Parse the string into tokens. */
1278598fe0ddSCristian Dumitrescu 	for (s = s0; ; ) {
1279598fe0ddSCristian Dumitrescu 		char *token;
1280598fe0ddSCristian Dumitrescu 
1281598fe0ddSCristian Dumitrescu 		token = strtok_r(s, " \f\n\r\t\v", &s);
1282598fe0ddSCristian Dumitrescu 		if (!token || token_is_comment(token))
1283598fe0ddSCristian Dumitrescu 			break;
1284598fe0ddSCristian Dumitrescu 
1285cfcc7bf8SCristian Dumitrescu 		if (n_tokens >= GROUP_MEMBER_INFO_TOKENS_MAX)
1286598fe0ddSCristian Dumitrescu 			goto error;
1287598fe0ddSCristian Dumitrescu 
1288598fe0ddSCristian Dumitrescu 		token_array[n_tokens] = token;
1289598fe0ddSCristian Dumitrescu 		n_tokens++;
1290598fe0ddSCristian Dumitrescu 	}
1291598fe0ddSCristian Dumitrescu 
1292598fe0ddSCristian Dumitrescu 	if (!n_tokens) {
1293598fe0ddSCristian Dumitrescu 		blank_or_comment = 1;
1294598fe0ddSCristian Dumitrescu 		goto error;
1295598fe0ddSCristian Dumitrescu 	}
1296598fe0ddSCristian Dumitrescu 
1297598fe0ddSCristian Dumitrescu 	tokens = token_array;
1298598fe0ddSCristian Dumitrescu 
1299598fe0ddSCristian Dumitrescu 	if (n_tokens < 4 ||
1300598fe0ddSCristian Dumitrescu 		strcmp(tokens[0], "group") ||
1301598fe0ddSCristian Dumitrescu 		strcmp(tokens[2], "member"))
1302598fe0ddSCristian Dumitrescu 		goto error;
1303598fe0ddSCristian Dumitrescu 
1304598fe0ddSCristian Dumitrescu 	/*
1305598fe0ddSCristian Dumitrescu 	 * Group ID.
1306598fe0ddSCristian Dumitrescu 	 */
1307598fe0ddSCristian Dumitrescu 	if (parser_read_uint32(&group_id_val, tokens[1]) != 0)
1308598fe0ddSCristian Dumitrescu 		goto error;
1309598fe0ddSCristian Dumitrescu 	*group_id = group_id_val;
1310598fe0ddSCristian Dumitrescu 
1311598fe0ddSCristian Dumitrescu 	/*
1312598fe0ddSCristian Dumitrescu 	 * Member ID.
1313598fe0ddSCristian Dumitrescu 	 */
1314598fe0ddSCristian Dumitrescu 	if (parser_read_uint32(&member_id_val, tokens[3]) != 0)
1315598fe0ddSCristian Dumitrescu 		goto error;
1316598fe0ddSCristian Dumitrescu 	*member_id = member_id_val;
1317598fe0ddSCristian Dumitrescu 
1318598fe0ddSCristian Dumitrescu 	tokens += 4;
1319598fe0ddSCristian Dumitrescu 	n_tokens -= 4;
1320598fe0ddSCristian Dumitrescu 
1321598fe0ddSCristian Dumitrescu 	/*
1322598fe0ddSCristian Dumitrescu 	 * Weight.
1323598fe0ddSCristian Dumitrescu 	 */
1324598fe0ddSCristian Dumitrescu 	if (n_tokens && !strcmp(tokens[0], "weight")) {
1325598fe0ddSCristian Dumitrescu 		if (n_tokens < 2)
1326598fe0ddSCristian Dumitrescu 			goto error;
1327598fe0ddSCristian Dumitrescu 
1328598fe0ddSCristian Dumitrescu 		if (parser_read_uint32(&weight_val, tokens[1]) != 0)
1329598fe0ddSCristian Dumitrescu 			goto error;
1330598fe0ddSCristian Dumitrescu 		*weight = weight_val;
1331598fe0ddSCristian Dumitrescu 
1332598fe0ddSCristian Dumitrescu 		tokens += 2;
1333598fe0ddSCristian Dumitrescu 		n_tokens -= 2;
1334598fe0ddSCristian Dumitrescu 	}
1335598fe0ddSCristian Dumitrescu 
1336598fe0ddSCristian Dumitrescu 	if (n_tokens)
1337598fe0ddSCristian Dumitrescu 		goto error;
1338598fe0ddSCristian Dumitrescu 
1339598fe0ddSCristian Dumitrescu 	free(s0);
1340598fe0ddSCristian Dumitrescu 	return 0;
1341598fe0ddSCristian Dumitrescu 
1342598fe0ddSCristian Dumitrescu error:
1343598fe0ddSCristian Dumitrescu 	free(s0);
1344598fe0ddSCristian Dumitrescu 	if (is_blank_or_comment)
1345598fe0ddSCristian Dumitrescu 		*is_blank_or_comment = blank_or_comment;
1346598fe0ddSCristian Dumitrescu 	return -EINVAL;
1347598fe0ddSCristian Dumitrescu }
1348598fe0ddSCristian Dumitrescu 
1349598fe0ddSCristian Dumitrescu static int
1350598fe0ddSCristian Dumitrescu pipeline_selector_group_members_add(struct rte_swx_ctl_pipeline *p,
1351598fe0ddSCristian Dumitrescu 			   const char *selector_name,
1352598fe0ddSCristian Dumitrescu 			   FILE *file,
1353598fe0ddSCristian Dumitrescu 			   uint32_t *file_line_number)
1354598fe0ddSCristian Dumitrescu {
1355598fe0ddSCristian Dumitrescu 	char *line = NULL;
1356598fe0ddSCristian Dumitrescu 	uint32_t line_id = 0;
1357598fe0ddSCristian Dumitrescu 	int status = 0;
1358598fe0ddSCristian Dumitrescu 
1359598fe0ddSCristian Dumitrescu 	/* Buffer allocation. */
1360598fe0ddSCristian Dumitrescu 	line = malloc(MAX_LINE_SIZE);
1361598fe0ddSCristian Dumitrescu 	if (!line)
1362598fe0ddSCristian Dumitrescu 		return -ENOMEM;
1363598fe0ddSCristian Dumitrescu 
1364598fe0ddSCristian Dumitrescu 	/* File read. */
1365598fe0ddSCristian Dumitrescu 	for (line_id = 1; ; line_id++) {
1366598fe0ddSCristian Dumitrescu 		uint32_t group_id, member_id, weight;
1367598fe0ddSCristian Dumitrescu 		int is_blank_or_comment;
1368598fe0ddSCristian Dumitrescu 
1369598fe0ddSCristian Dumitrescu 		if (fgets(line, MAX_LINE_SIZE, file) == NULL)
1370598fe0ddSCristian Dumitrescu 			break;
1371598fe0ddSCristian Dumitrescu 
1372598fe0ddSCristian Dumitrescu 		status = pipeline_selector_group_member_read(line,
1373598fe0ddSCristian Dumitrescu 							      &group_id,
1374598fe0ddSCristian Dumitrescu 							      &member_id,
1375598fe0ddSCristian Dumitrescu 							      &weight,
1376598fe0ddSCristian Dumitrescu 							      &is_blank_or_comment);
1377598fe0ddSCristian Dumitrescu 		if (status) {
1378598fe0ddSCristian Dumitrescu 			if (is_blank_or_comment)
1379598fe0ddSCristian Dumitrescu 				continue;
1380598fe0ddSCristian Dumitrescu 
1381598fe0ddSCristian Dumitrescu 			goto error;
1382598fe0ddSCristian Dumitrescu 		}
1383598fe0ddSCristian Dumitrescu 
1384598fe0ddSCristian Dumitrescu 		status = rte_swx_ctl_pipeline_selector_group_member_add(p,
1385598fe0ddSCristian Dumitrescu 			selector_name,
1386598fe0ddSCristian Dumitrescu 			group_id,
1387598fe0ddSCristian Dumitrescu 			member_id,
1388598fe0ddSCristian Dumitrescu 			weight);
1389598fe0ddSCristian Dumitrescu 		if (status)
1390598fe0ddSCristian Dumitrescu 			goto error;
1391598fe0ddSCristian Dumitrescu 	}
1392598fe0ddSCristian Dumitrescu 
1393598fe0ddSCristian Dumitrescu error:
1394598fe0ddSCristian Dumitrescu 	free(line);
1395598fe0ddSCristian Dumitrescu 	*file_line_number = line_id;
1396598fe0ddSCristian Dumitrescu 	return status;
1397598fe0ddSCristian Dumitrescu }
1398598fe0ddSCristian Dumitrescu 
1399598fe0ddSCristian Dumitrescu static const char cmd_pipeline_selector_group_member_add_help[] =
1400598fe0ddSCristian Dumitrescu "pipeline <pipeline_name> selector <selector_name> group member add <file_name>";
1401598fe0ddSCristian Dumitrescu 
1402598fe0ddSCristian Dumitrescu static void
1403598fe0ddSCristian Dumitrescu cmd_pipeline_selector_group_member_add(char **tokens,
1404598fe0ddSCristian Dumitrescu 	uint32_t n_tokens,
1405598fe0ddSCristian Dumitrescu 	char *out,
1406598fe0ddSCristian Dumitrescu 	size_t out_size,
1407b9559f94SCristian Dumitrescu 	void *obj __rte_unused)
1408598fe0ddSCristian Dumitrescu {
1409b9559f94SCristian Dumitrescu 	struct rte_swx_ctl_pipeline *ctl;
1410598fe0ddSCristian Dumitrescu 	char *pipeline_name, *selector_name, *file_name;
1411598fe0ddSCristian Dumitrescu 	FILE *file = NULL;
1412598fe0ddSCristian Dumitrescu 	uint32_t file_line_number = 0;
1413598fe0ddSCristian Dumitrescu 	int status;
1414598fe0ddSCristian Dumitrescu 
1415598fe0ddSCristian Dumitrescu 	if (n_tokens != 8) {
1416598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1417598fe0ddSCristian Dumitrescu 		return;
1418598fe0ddSCristian Dumitrescu 	}
1419598fe0ddSCristian Dumitrescu 
1420598fe0ddSCristian Dumitrescu 	pipeline_name = tokens[1];
1421b9559f94SCristian Dumitrescu 	ctl = rte_swx_ctl_pipeline_find(pipeline_name);
1422b9559f94SCristian Dumitrescu 	if (!ctl) {
1423598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
1424598fe0ddSCristian Dumitrescu 		return;
1425598fe0ddSCristian Dumitrescu 	}
1426598fe0ddSCristian Dumitrescu 
1427598fe0ddSCristian Dumitrescu 	if (strcmp(tokens[2], "selector") != 0) {
1428598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "selector");
1429598fe0ddSCristian Dumitrescu 		return;
1430598fe0ddSCristian Dumitrescu 	}
1431598fe0ddSCristian Dumitrescu 
1432598fe0ddSCristian Dumitrescu 	selector_name = tokens[3];
1433598fe0ddSCristian Dumitrescu 
1434598fe0ddSCristian Dumitrescu 	if (strcmp(tokens[4], "group") ||
1435598fe0ddSCristian Dumitrescu 		strcmp(tokens[5], "member") ||
1436598fe0ddSCristian Dumitrescu 		strcmp(tokens[6], "add")) {
1437598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "group member add");
1438598fe0ddSCristian Dumitrescu 		return;
1439598fe0ddSCristian Dumitrescu 	}
1440598fe0ddSCristian Dumitrescu 
1441598fe0ddSCristian Dumitrescu 	file_name = tokens[7];
1442598fe0ddSCristian Dumitrescu 	file = fopen(file_name, "r");
1443598fe0ddSCristian Dumitrescu 	if (!file) {
1444598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, "Cannot open file %s.\n", file_name);
1445598fe0ddSCristian Dumitrescu 		return;
1446598fe0ddSCristian Dumitrescu 	}
1447598fe0ddSCristian Dumitrescu 
1448b9559f94SCristian Dumitrescu 	status = pipeline_selector_group_members_add(ctl,
1449598fe0ddSCristian Dumitrescu 					    selector_name,
1450598fe0ddSCristian Dumitrescu 					    file,
1451598fe0ddSCristian Dumitrescu 					    &file_line_number);
1452598fe0ddSCristian Dumitrescu 	if (status)
1453598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, "Invalid entry in file %s at line %u\n",
1454598fe0ddSCristian Dumitrescu 			 file_name,
1455598fe0ddSCristian Dumitrescu 			 file_line_number);
1456598fe0ddSCristian Dumitrescu 
1457598fe0ddSCristian Dumitrescu 	fclose(file);
1458598fe0ddSCristian Dumitrescu }
1459598fe0ddSCristian Dumitrescu 
1460598fe0ddSCristian Dumitrescu static int
1461598fe0ddSCristian Dumitrescu pipeline_selector_group_members_delete(struct rte_swx_ctl_pipeline *p,
1462598fe0ddSCristian Dumitrescu 			   const char *selector_name,
1463598fe0ddSCristian Dumitrescu 			   FILE *file,
1464598fe0ddSCristian Dumitrescu 			   uint32_t *file_line_number)
1465598fe0ddSCristian Dumitrescu {
1466598fe0ddSCristian Dumitrescu 	char *line = NULL;
1467598fe0ddSCristian Dumitrescu 	uint32_t line_id = 0;
1468598fe0ddSCristian Dumitrescu 	int status = 0;
1469598fe0ddSCristian Dumitrescu 
1470598fe0ddSCristian Dumitrescu 	/* Buffer allocation. */
1471598fe0ddSCristian Dumitrescu 	line = malloc(MAX_LINE_SIZE);
1472598fe0ddSCristian Dumitrescu 	if (!line)
1473598fe0ddSCristian Dumitrescu 		return -ENOMEM;
1474598fe0ddSCristian Dumitrescu 
1475598fe0ddSCristian Dumitrescu 	/* File read. */
1476598fe0ddSCristian Dumitrescu 	for (line_id = 1; ; line_id++) {
1477598fe0ddSCristian Dumitrescu 		uint32_t group_id, member_id, weight;
1478598fe0ddSCristian Dumitrescu 		int is_blank_or_comment;
1479598fe0ddSCristian Dumitrescu 
1480598fe0ddSCristian Dumitrescu 		if (fgets(line, MAX_LINE_SIZE, file) == NULL)
1481598fe0ddSCristian Dumitrescu 			break;
1482598fe0ddSCristian Dumitrescu 
1483598fe0ddSCristian Dumitrescu 		status = pipeline_selector_group_member_read(line,
1484598fe0ddSCristian Dumitrescu 							      &group_id,
1485598fe0ddSCristian Dumitrescu 							      &member_id,
1486598fe0ddSCristian Dumitrescu 							      &weight,
1487598fe0ddSCristian Dumitrescu 							      &is_blank_or_comment);
1488598fe0ddSCristian Dumitrescu 		if (status) {
1489598fe0ddSCristian Dumitrescu 			if (is_blank_or_comment)
1490598fe0ddSCristian Dumitrescu 				continue;
1491598fe0ddSCristian Dumitrescu 
1492598fe0ddSCristian Dumitrescu 			goto error;
1493598fe0ddSCristian Dumitrescu 		}
1494598fe0ddSCristian Dumitrescu 
1495598fe0ddSCristian Dumitrescu 		status = rte_swx_ctl_pipeline_selector_group_member_delete(p,
1496598fe0ddSCristian Dumitrescu 			selector_name,
1497598fe0ddSCristian Dumitrescu 			group_id,
1498598fe0ddSCristian Dumitrescu 			member_id);
1499598fe0ddSCristian Dumitrescu 		if (status)
1500598fe0ddSCristian Dumitrescu 			goto error;
1501598fe0ddSCristian Dumitrescu 	}
1502598fe0ddSCristian Dumitrescu 
1503598fe0ddSCristian Dumitrescu error:
1504598fe0ddSCristian Dumitrescu 	free(line);
1505598fe0ddSCristian Dumitrescu 	*file_line_number = line_id;
1506598fe0ddSCristian Dumitrescu 	return status;
1507598fe0ddSCristian Dumitrescu }
1508598fe0ddSCristian Dumitrescu 
1509598fe0ddSCristian Dumitrescu static const char cmd_pipeline_selector_group_member_delete_help[] =
1510598fe0ddSCristian Dumitrescu "pipeline <pipeline_name> selector <selector_name> group member delete <file_name>";
1511598fe0ddSCristian Dumitrescu 
1512598fe0ddSCristian Dumitrescu static void
1513598fe0ddSCristian Dumitrescu cmd_pipeline_selector_group_member_delete(char **tokens,
1514598fe0ddSCristian Dumitrescu 	uint32_t n_tokens,
1515598fe0ddSCristian Dumitrescu 	char *out,
1516598fe0ddSCristian Dumitrescu 	size_t out_size,
1517b9559f94SCristian Dumitrescu 	void *obj __rte_unused)
1518598fe0ddSCristian Dumitrescu {
1519b9559f94SCristian Dumitrescu 	struct rte_swx_ctl_pipeline *ctl;
1520598fe0ddSCristian Dumitrescu 	char *pipeline_name, *selector_name, *file_name;
1521598fe0ddSCristian Dumitrescu 	FILE *file = NULL;
1522598fe0ddSCristian Dumitrescu 	uint32_t file_line_number = 0;
1523598fe0ddSCristian Dumitrescu 	int status;
1524598fe0ddSCristian Dumitrescu 
1525598fe0ddSCristian Dumitrescu 	if (n_tokens != 8) {
1526598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1527598fe0ddSCristian Dumitrescu 		return;
1528598fe0ddSCristian Dumitrescu 	}
1529598fe0ddSCristian Dumitrescu 
1530598fe0ddSCristian Dumitrescu 	pipeline_name = tokens[1];
1531b9559f94SCristian Dumitrescu 	ctl = rte_swx_ctl_pipeline_find(pipeline_name);
1532b9559f94SCristian Dumitrescu 	if (!ctl) {
1533598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
1534598fe0ddSCristian Dumitrescu 		return;
1535598fe0ddSCristian Dumitrescu 	}
1536598fe0ddSCristian Dumitrescu 
1537598fe0ddSCristian Dumitrescu 	if (strcmp(tokens[2], "selector") != 0) {
1538598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "selector");
1539598fe0ddSCristian Dumitrescu 		return;
1540598fe0ddSCristian Dumitrescu 	}
1541598fe0ddSCristian Dumitrescu 
1542598fe0ddSCristian Dumitrescu 	selector_name = tokens[3];
1543598fe0ddSCristian Dumitrescu 
1544598fe0ddSCristian Dumitrescu 	if (strcmp(tokens[4], "group") ||
1545598fe0ddSCristian Dumitrescu 		strcmp(tokens[5], "member") ||
1546598fe0ddSCristian Dumitrescu 		strcmp(tokens[6], "delete")) {
1547598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "group member delete");
1548598fe0ddSCristian Dumitrescu 		return;
1549598fe0ddSCristian Dumitrescu 	}
1550598fe0ddSCristian Dumitrescu 
1551598fe0ddSCristian Dumitrescu 	file_name = tokens[7];
1552598fe0ddSCristian Dumitrescu 	file = fopen(file_name, "r");
1553598fe0ddSCristian Dumitrescu 	if (!file) {
1554598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, "Cannot open file %s.\n", file_name);
1555598fe0ddSCristian Dumitrescu 		return;
1556598fe0ddSCristian Dumitrescu 	}
1557598fe0ddSCristian Dumitrescu 
1558b9559f94SCristian Dumitrescu 	status = pipeline_selector_group_members_delete(ctl,
1559598fe0ddSCristian Dumitrescu 					    selector_name,
1560598fe0ddSCristian Dumitrescu 					    file,
1561598fe0ddSCristian Dumitrescu 					    &file_line_number);
1562598fe0ddSCristian Dumitrescu 	if (status)
1563598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, "Invalid entry in file %s at line %u\n",
1564598fe0ddSCristian Dumitrescu 			 file_name,
1565598fe0ddSCristian Dumitrescu 			 file_line_number);
1566598fe0ddSCristian Dumitrescu 
1567598fe0ddSCristian Dumitrescu 	fclose(file);
1568598fe0ddSCristian Dumitrescu }
1569598fe0ddSCristian Dumitrescu 
1570598fe0ddSCristian Dumitrescu static const char cmd_pipeline_selector_show_help[] =
1571a4c1146cSCristian Dumitrescu "pipeline <pipeline_name> selector <selector_name> show [filename]\n";
1572598fe0ddSCristian Dumitrescu 
1573598fe0ddSCristian Dumitrescu static void
1574598fe0ddSCristian Dumitrescu cmd_pipeline_selector_show(char **tokens,
1575598fe0ddSCristian Dumitrescu 	uint32_t n_tokens,
1576598fe0ddSCristian Dumitrescu 	char *out,
1577598fe0ddSCristian Dumitrescu 	size_t out_size,
1578b9559f94SCristian Dumitrescu 	void *obj __rte_unused)
1579598fe0ddSCristian Dumitrescu {
1580b9559f94SCristian Dumitrescu 	struct rte_swx_ctl_pipeline *ctl;
1581598fe0ddSCristian Dumitrescu 	char *pipeline_name, *selector_name;
1582a4c1146cSCristian Dumitrescu 	FILE *file = NULL;
1583598fe0ddSCristian Dumitrescu 	int status;
1584598fe0ddSCristian Dumitrescu 
1585a4c1146cSCristian Dumitrescu 	if (n_tokens != 5 && n_tokens != 6) {
1586598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1587598fe0ddSCristian Dumitrescu 		return;
1588598fe0ddSCristian Dumitrescu 	}
1589598fe0ddSCristian Dumitrescu 
1590598fe0ddSCristian Dumitrescu 	pipeline_name = tokens[1];
1591b9559f94SCristian Dumitrescu 	ctl = rte_swx_ctl_pipeline_find(pipeline_name);
1592b9559f94SCristian Dumitrescu 	if (!ctl) {
1593598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
1594598fe0ddSCristian Dumitrescu 		return;
1595598fe0ddSCristian Dumitrescu 	}
1596598fe0ddSCristian Dumitrescu 
1597598fe0ddSCristian Dumitrescu 	selector_name = tokens[3];
1598a4c1146cSCristian Dumitrescu 
1599a4c1146cSCristian Dumitrescu 	file = (n_tokens == 6) ? fopen(tokens[5], "w") : stdout;
1600a4c1146cSCristian Dumitrescu 	if (!file) {
1601a4c1146cSCristian Dumitrescu 		snprintf(out, out_size, "Cannot open file %s.\n", tokens[5]);
1602a4c1146cSCristian Dumitrescu 		return;
1603a4c1146cSCristian Dumitrescu 	}
1604a4c1146cSCristian Dumitrescu 
1605b9559f94SCristian Dumitrescu 	status = rte_swx_ctl_pipeline_selector_fprintf(file, ctl, selector_name);
1606598fe0ddSCristian Dumitrescu 	if (status)
1607598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "selector_name");
1608a4c1146cSCristian Dumitrescu 
1609a4c1146cSCristian Dumitrescu 	if (file)
1610a4c1146cSCristian Dumitrescu 		fclose(file);
1611598fe0ddSCristian Dumitrescu }
1612598fe0ddSCristian Dumitrescu 
16138bd4862fSCristian Dumitrescu static int
16148bd4862fSCristian Dumitrescu pipeline_learner_default_entry_add(struct rte_swx_ctl_pipeline *p,
16158bd4862fSCristian Dumitrescu 				   const char *learner_name,
16168bd4862fSCristian Dumitrescu 				   FILE *file,
16178bd4862fSCristian Dumitrescu 				   uint32_t *file_line_number)
16188bd4862fSCristian Dumitrescu {
16198bd4862fSCristian Dumitrescu 	char *line = NULL;
16208bd4862fSCristian Dumitrescu 	uint32_t line_id = 0;
16218bd4862fSCristian Dumitrescu 	int status = 0;
16228bd4862fSCristian Dumitrescu 
16238bd4862fSCristian Dumitrescu 	/* Buffer allocation. */
16248bd4862fSCristian Dumitrescu 	line = malloc(MAX_LINE_SIZE);
16258bd4862fSCristian Dumitrescu 	if (!line)
16268bd4862fSCristian Dumitrescu 		return -ENOMEM;
16278bd4862fSCristian Dumitrescu 
16288bd4862fSCristian Dumitrescu 	/* File read. */
16298bd4862fSCristian Dumitrescu 	for (line_id = 1; ; line_id++) {
16308bd4862fSCristian Dumitrescu 		struct rte_swx_table_entry *entry;
16318bd4862fSCristian Dumitrescu 		int is_blank_or_comment;
16328bd4862fSCristian Dumitrescu 
16338bd4862fSCristian Dumitrescu 		if (fgets(line, MAX_LINE_SIZE, file) == NULL)
16348bd4862fSCristian Dumitrescu 			break;
16358bd4862fSCristian Dumitrescu 
16368bd4862fSCristian Dumitrescu 		entry = rte_swx_ctl_pipeline_learner_default_entry_read(p,
16378bd4862fSCristian Dumitrescu 									learner_name,
16388bd4862fSCristian Dumitrescu 									line,
16398bd4862fSCristian Dumitrescu 									&is_blank_or_comment);
16408bd4862fSCristian Dumitrescu 		if (!entry) {
16418bd4862fSCristian Dumitrescu 			if (is_blank_or_comment)
16428bd4862fSCristian Dumitrescu 				continue;
16438bd4862fSCristian Dumitrescu 
16448bd4862fSCristian Dumitrescu 			status = -EINVAL;
16458bd4862fSCristian Dumitrescu 			goto error;
16468bd4862fSCristian Dumitrescu 		}
16478bd4862fSCristian Dumitrescu 
16488bd4862fSCristian Dumitrescu 		status = rte_swx_ctl_pipeline_learner_default_entry_add(p,
16498bd4862fSCristian Dumitrescu 									learner_name,
16508bd4862fSCristian Dumitrescu 									entry);
16518bd4862fSCristian Dumitrescu 		table_entry_free(entry);
16528bd4862fSCristian Dumitrescu 		if (status)
16538bd4862fSCristian Dumitrescu 			goto error;
16548bd4862fSCristian Dumitrescu 	}
16558bd4862fSCristian Dumitrescu 
16568bd4862fSCristian Dumitrescu error:
16578bd4862fSCristian Dumitrescu 	*file_line_number = line_id;
16588bd4862fSCristian Dumitrescu 	free(line);
16598bd4862fSCristian Dumitrescu 	return status;
16608bd4862fSCristian Dumitrescu }
16618bd4862fSCristian Dumitrescu 
16628bd4862fSCristian Dumitrescu static const char cmd_pipeline_learner_default_help[] =
16638bd4862fSCristian Dumitrescu "pipeline <pipeline_name> learner <learner_name> default <file_name>\n";
16648bd4862fSCristian Dumitrescu 
16658bd4862fSCristian Dumitrescu static void
16668bd4862fSCristian Dumitrescu cmd_pipeline_learner_default(char **tokens,
16678bd4862fSCristian Dumitrescu 			     uint32_t n_tokens,
16688bd4862fSCristian Dumitrescu 			     char *out,
16698bd4862fSCristian Dumitrescu 			     size_t out_size,
1670b9559f94SCristian Dumitrescu 			     void *obj __rte_unused)
16718bd4862fSCristian Dumitrescu {
1672b9559f94SCristian Dumitrescu 	struct rte_swx_ctl_pipeline *ctl;
16738bd4862fSCristian Dumitrescu 	char *pipeline_name, *learner_name, *file_name;
16748bd4862fSCristian Dumitrescu 	FILE *file = NULL;
16758bd4862fSCristian Dumitrescu 	uint32_t file_line_number = 0;
16768bd4862fSCristian Dumitrescu 	int status;
16778bd4862fSCristian Dumitrescu 
16788bd4862fSCristian Dumitrescu 	if (n_tokens != 6) {
16798bd4862fSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
16808bd4862fSCristian Dumitrescu 		return;
16818bd4862fSCristian Dumitrescu 	}
16828bd4862fSCristian Dumitrescu 
16838bd4862fSCristian Dumitrescu 	pipeline_name = tokens[1];
1684b9559f94SCristian Dumitrescu 	ctl = rte_swx_ctl_pipeline_find(pipeline_name);
1685b9559f94SCristian Dumitrescu 	if (!ctl) {
16868bd4862fSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
16878bd4862fSCristian Dumitrescu 		return;
16888bd4862fSCristian Dumitrescu 	}
16898bd4862fSCristian Dumitrescu 
16908bd4862fSCristian Dumitrescu 	learner_name = tokens[3];
16918bd4862fSCristian Dumitrescu 
16928bd4862fSCristian Dumitrescu 	file_name = tokens[5];
16938bd4862fSCristian Dumitrescu 	file = fopen(file_name, "r");
16948bd4862fSCristian Dumitrescu 	if (!file) {
16958bd4862fSCristian Dumitrescu 		snprintf(out, out_size, "Cannot open file %s.\n", file_name);
16968bd4862fSCristian Dumitrescu 		return;
16978bd4862fSCristian Dumitrescu 	}
16988bd4862fSCristian Dumitrescu 
1699b9559f94SCristian Dumitrescu 	status = pipeline_learner_default_entry_add(ctl,
17008bd4862fSCristian Dumitrescu 						    learner_name,
17018bd4862fSCristian Dumitrescu 						    file,
17028bd4862fSCristian Dumitrescu 						    &file_line_number);
17038bd4862fSCristian Dumitrescu 	if (status)
17048bd4862fSCristian Dumitrescu 		snprintf(out, out_size, "Invalid entry in file %s at line %u\n",
17058bd4862fSCristian Dumitrescu 			 file_name,
17068bd4862fSCristian Dumitrescu 			 file_line_number);
17078bd4862fSCristian Dumitrescu 
17088bd4862fSCristian Dumitrescu 	fclose(file);
17098bd4862fSCristian Dumitrescu }
17108bd4862fSCristian Dumitrescu 
171175129cebSChurchill Khangar static const char cmd_pipeline_commit_help[] =
171275129cebSChurchill Khangar "pipeline <pipeline_name> commit\n";
171375129cebSChurchill Khangar 
171475129cebSChurchill Khangar static void
171575129cebSChurchill Khangar cmd_pipeline_commit(char **tokens,
171675129cebSChurchill Khangar 	uint32_t n_tokens,
171775129cebSChurchill Khangar 	char *out,
171875129cebSChurchill Khangar 	size_t out_size,
1719b9559f94SCristian Dumitrescu 	void *obj __rte_unused)
172075129cebSChurchill Khangar {
1721b9559f94SCristian Dumitrescu 	struct rte_swx_ctl_pipeline *ctl;
172275129cebSChurchill Khangar 	char *pipeline_name;
172375129cebSChurchill Khangar 	int status;
172475129cebSChurchill Khangar 
172575129cebSChurchill Khangar 	if (n_tokens != 3) {
172675129cebSChurchill Khangar 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
172775129cebSChurchill Khangar 		return;
172875129cebSChurchill Khangar 	}
172975129cebSChurchill Khangar 
173075129cebSChurchill Khangar 	pipeline_name = tokens[1];
1731b9559f94SCristian Dumitrescu 	ctl = rte_swx_ctl_pipeline_find(pipeline_name);
1732b9559f94SCristian Dumitrescu 	if (!ctl) {
173375129cebSChurchill Khangar 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
173475129cebSChurchill Khangar 		return;
17355074e1d5SCristian Dumitrescu 	}
17365074e1d5SCristian Dumitrescu 
1737b9559f94SCristian Dumitrescu 	status = rte_swx_ctl_pipeline_commit(ctl, 1);
173875129cebSChurchill Khangar 	if (status)
173975129cebSChurchill Khangar 		snprintf(out, out_size, "Commit failed. "
174075129cebSChurchill Khangar 			"Use \"commit\" to retry or \"abort\" to discard the pending work.\n");
17415074e1d5SCristian Dumitrescu }
17425074e1d5SCristian Dumitrescu 
174375129cebSChurchill Khangar static const char cmd_pipeline_abort_help[] =
174475129cebSChurchill Khangar "pipeline <pipeline_name> abort\n";
17455074e1d5SCristian Dumitrescu 
174675129cebSChurchill Khangar static void
174775129cebSChurchill Khangar cmd_pipeline_abort(char **tokens,
174875129cebSChurchill Khangar 	uint32_t n_tokens,
174975129cebSChurchill Khangar 	char *out,
175075129cebSChurchill Khangar 	size_t out_size,
1751b9559f94SCristian Dumitrescu 	void *obj __rte_unused)
175275129cebSChurchill Khangar {
1753b9559f94SCristian Dumitrescu 	struct rte_swx_ctl_pipeline *ctl;
175475129cebSChurchill Khangar 	char *pipeline_name;
17555074e1d5SCristian Dumitrescu 
175675129cebSChurchill Khangar 	if (n_tokens != 3) {
175775129cebSChurchill Khangar 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
17585074e1d5SCristian Dumitrescu 		return;
175975129cebSChurchill Khangar 	}
17605074e1d5SCristian Dumitrescu 
176175129cebSChurchill Khangar 	pipeline_name = tokens[1];
1762b9559f94SCristian Dumitrescu 	ctl = rte_swx_ctl_pipeline_find(pipeline_name);
1763b9559f94SCristian Dumitrescu 	if (!ctl) {
176475129cebSChurchill Khangar 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
176575129cebSChurchill Khangar 		return;
176675129cebSChurchill Khangar 	}
176775129cebSChurchill Khangar 
1768b9559f94SCristian Dumitrescu 	rte_swx_ctl_pipeline_abort(ctl);
17695074e1d5SCristian Dumitrescu }
17705074e1d5SCristian Dumitrescu 
177164cfcebdSCristian Dumitrescu static const char cmd_pipeline_regrd_help[] =
177283f58a7bSCristian Dumitrescu "pipeline <pipeline_name> regrd <register_array_name>\n"
177383f58a7bSCristian Dumitrescu 	"index <index>\n"
177483f58a7bSCristian Dumitrescu 	" | table <table_name> match <field0> ...\n";
177564cfcebdSCristian Dumitrescu 
177664cfcebdSCristian Dumitrescu static void
177764cfcebdSCristian Dumitrescu cmd_pipeline_regrd(char **tokens,
177864cfcebdSCristian Dumitrescu 	uint32_t n_tokens,
177964cfcebdSCristian Dumitrescu 	char *out,
178064cfcebdSCristian Dumitrescu 	size_t out_size,
1781b9559f94SCristian Dumitrescu 	void *obj __rte_unused)
178264cfcebdSCristian Dumitrescu {
1783b9559f94SCristian Dumitrescu 	struct rte_swx_pipeline *p;
178483f58a7bSCristian Dumitrescu 	struct rte_swx_ctl_pipeline *ctl;
178583f58a7bSCristian Dumitrescu 	const char *pipeline_name, *name;
178664cfcebdSCristian Dumitrescu 	uint64_t value;
178764cfcebdSCristian Dumitrescu 	int status;
178864cfcebdSCristian Dumitrescu 
178983f58a7bSCristian Dumitrescu 	if (n_tokens < 5) {
179064cfcebdSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
179164cfcebdSCristian Dumitrescu 		return;
179264cfcebdSCristian Dumitrescu 	}
179364cfcebdSCristian Dumitrescu 
179483f58a7bSCristian Dumitrescu 	pipeline_name = tokens[1];
179583f58a7bSCristian Dumitrescu 	p = rte_swx_pipeline_find(pipeline_name);
179683f58a7bSCristian Dumitrescu 	ctl = rte_swx_ctl_pipeline_find(pipeline_name);
179783f58a7bSCristian Dumitrescu 	if (!p || !ctl) {
179864cfcebdSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
179964cfcebdSCristian Dumitrescu 		return;
180064cfcebdSCristian Dumitrescu 	}
180164cfcebdSCristian Dumitrescu 
180264cfcebdSCristian Dumitrescu 	if (strcmp(tokens[2], "regrd")) {
180364cfcebdSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "regrd");
180464cfcebdSCristian Dumitrescu 		return;
180564cfcebdSCristian Dumitrescu 	}
180664cfcebdSCristian Dumitrescu 
180764cfcebdSCristian Dumitrescu 	name = tokens[3];
180864cfcebdSCristian Dumitrescu 
180983f58a7bSCristian Dumitrescu 	/* index. */
181083f58a7bSCristian Dumitrescu 	if (!strcmp(tokens[4], "index")) {
1811327820afSAli Alnubani 		uint32_t idx = 0;
181283f58a7bSCristian Dumitrescu 
181383f58a7bSCristian Dumitrescu 		if (n_tokens != 6) {
181483f58a7bSCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
181583f58a7bSCristian Dumitrescu 			return;
181683f58a7bSCristian Dumitrescu 		}
181783f58a7bSCristian Dumitrescu 
181883f58a7bSCristian Dumitrescu 		if (parser_read_uint32(&idx, tokens[5])) {
181964cfcebdSCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_INVALID, "index");
182064cfcebdSCristian Dumitrescu 			return;
182164cfcebdSCristian Dumitrescu 		}
182264cfcebdSCristian Dumitrescu 
1823b9559f94SCristian Dumitrescu 		status = rte_swx_ctl_pipeline_regarray_read(p, name, idx, &value);
182464cfcebdSCristian Dumitrescu 		if (status) {
182564cfcebdSCristian Dumitrescu 			snprintf(out, out_size, "Command failed.\n");
182664cfcebdSCristian Dumitrescu 			return;
182764cfcebdSCristian Dumitrescu 		}
182864cfcebdSCristian Dumitrescu 
182964cfcebdSCristian Dumitrescu 		snprintf(out, out_size, "0x%" PRIx64 "\n", value);
183083f58a7bSCristian Dumitrescu 		return;
183183f58a7bSCristian Dumitrescu 	}
183283f58a7bSCristian Dumitrescu 
183383f58a7bSCristian Dumitrescu 	/* table. */
183483f58a7bSCristian Dumitrescu 	if (!strcmp(tokens[4], "table")) {
183583f58a7bSCristian Dumitrescu 		struct rte_swx_table_entry *entry;
183683f58a7bSCristian Dumitrescu 		char *table_name;
183783f58a7bSCristian Dumitrescu 
183883f58a7bSCristian Dumitrescu 		if (n_tokens < 8) {
183983f58a7bSCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
184083f58a7bSCristian Dumitrescu 			return;
184183f58a7bSCristian Dumitrescu 		}
184283f58a7bSCristian Dumitrescu 
184383f58a7bSCristian Dumitrescu 		table_name = tokens[5];
184483f58a7bSCristian Dumitrescu 
184583f58a7bSCristian Dumitrescu 		if (strcmp(tokens[6], "match")) {
184683f58a7bSCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_NOT_FOUND, "match");
184783f58a7bSCristian Dumitrescu 			return;
184883f58a7bSCristian Dumitrescu 		}
184983f58a7bSCristian Dumitrescu 
185083f58a7bSCristian Dumitrescu 		entry = parse_table_entry(ctl, table_name, &tokens[6], n_tokens - 6);
185183f58a7bSCristian Dumitrescu 		if (!entry) {
185283f58a7bSCristian Dumitrescu 			snprintf(out, out_size, "Invalid match tokens.\n");
185383f58a7bSCristian Dumitrescu 			return;
185483f58a7bSCristian Dumitrescu 		}
185583f58a7bSCristian Dumitrescu 
185683f58a7bSCristian Dumitrescu 		status = rte_swx_ctl_pipeline_regarray_read_with_key(p,
185783f58a7bSCristian Dumitrescu 								     name,
185883f58a7bSCristian Dumitrescu 								     table_name,
185983f58a7bSCristian Dumitrescu 								     entry->key,
186083f58a7bSCristian Dumitrescu 								     &value);
186183f58a7bSCristian Dumitrescu 		table_entry_free(entry);
186283f58a7bSCristian Dumitrescu 		if (status) {
186383f58a7bSCristian Dumitrescu 			snprintf(out, out_size, "Command failed.\n");
186483f58a7bSCristian Dumitrescu 			return;
186583f58a7bSCristian Dumitrescu 		}
186683f58a7bSCristian Dumitrescu 
186783f58a7bSCristian Dumitrescu 		snprintf(out, out_size, "0x%" PRIx64 "\n", value);
186883f58a7bSCristian Dumitrescu 		return;
186983f58a7bSCristian Dumitrescu 	}
187083f58a7bSCristian Dumitrescu 
187183f58a7bSCristian Dumitrescu 	/* anything else. */
187283f58a7bSCristian Dumitrescu 	snprintf(out, out_size, "Invalid token %s\n.", tokens[4]);
187383f58a7bSCristian Dumitrescu 	return;
187464cfcebdSCristian Dumitrescu }
187564cfcebdSCristian Dumitrescu 
187664cfcebdSCristian Dumitrescu static const char cmd_pipeline_regwr_help[] =
187783f58a7bSCristian Dumitrescu "pipeline <pipeline_name> regwr <register_array_name> value <value>\n"
187883f58a7bSCristian Dumitrescu 	"index <index>\n"
187983f58a7bSCristian Dumitrescu 	" | table <table_name> match <field0> ...\n";
188064cfcebdSCristian Dumitrescu 
188164cfcebdSCristian Dumitrescu static void
188264cfcebdSCristian Dumitrescu cmd_pipeline_regwr(char **tokens,
188364cfcebdSCristian Dumitrescu 	uint32_t n_tokens,
188464cfcebdSCristian Dumitrescu 	char *out,
188564cfcebdSCristian Dumitrescu 	size_t out_size,
1886b9559f94SCristian Dumitrescu 	void *obj __rte_unused)
188764cfcebdSCristian Dumitrescu {
1888b9559f94SCristian Dumitrescu 	struct rte_swx_pipeline *p;
188983f58a7bSCristian Dumitrescu 	struct rte_swx_ctl_pipeline *ctl;
189083f58a7bSCristian Dumitrescu 	const char *pipeline_name, *name;
189183f58a7bSCristian Dumitrescu 	uint64_t value = 0;
189264cfcebdSCristian Dumitrescu 	int status;
189364cfcebdSCristian Dumitrescu 
189483f58a7bSCristian Dumitrescu 	if (n_tokens < 7) {
189564cfcebdSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
189664cfcebdSCristian Dumitrescu 		return;
189764cfcebdSCristian Dumitrescu 	}
189864cfcebdSCristian Dumitrescu 
189983f58a7bSCristian Dumitrescu 	pipeline_name = tokens[1];
190083f58a7bSCristian Dumitrescu 	p = rte_swx_pipeline_find(pipeline_name);
190183f58a7bSCristian Dumitrescu 	ctl = rte_swx_ctl_pipeline_find(pipeline_name);
190283f58a7bSCristian Dumitrescu 	if (!p || !ctl) {
190364cfcebdSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
190464cfcebdSCristian Dumitrescu 		return;
190564cfcebdSCristian Dumitrescu 	}
190664cfcebdSCristian Dumitrescu 
190764cfcebdSCristian Dumitrescu 	if (strcmp(tokens[2], "regwr")) {
190864cfcebdSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "regwr");
190964cfcebdSCristian Dumitrescu 		return;
191064cfcebdSCristian Dumitrescu 	}
191164cfcebdSCristian Dumitrescu 
191264cfcebdSCristian Dumitrescu 	name = tokens[3];
191364cfcebdSCristian Dumitrescu 
191483f58a7bSCristian Dumitrescu 	if (strcmp(tokens[4], "value")) {
191583f58a7bSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "value");
191664cfcebdSCristian Dumitrescu 		return;
191764cfcebdSCristian Dumitrescu 	}
191864cfcebdSCristian Dumitrescu 
191964cfcebdSCristian Dumitrescu 	if (parser_read_uint64(&value, tokens[5])) {
192064cfcebdSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "value");
192164cfcebdSCristian Dumitrescu 		return;
192264cfcebdSCristian Dumitrescu 	}
192364cfcebdSCristian Dumitrescu 
192483f58a7bSCristian Dumitrescu 	/* index. */
192583f58a7bSCristian Dumitrescu 	if (!strcmp(tokens[6], "index")) {
1926327820afSAli Alnubani 		uint32_t idx = 0;
192783f58a7bSCristian Dumitrescu 
192883f58a7bSCristian Dumitrescu 		if (n_tokens != 8) {
192983f58a7bSCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
193083f58a7bSCristian Dumitrescu 			return;
193183f58a7bSCristian Dumitrescu 		}
193283f58a7bSCristian Dumitrescu 
193383f58a7bSCristian Dumitrescu 		if (parser_read_uint32(&idx, tokens[7])) {
193483f58a7bSCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_INVALID, "index");
193583f58a7bSCristian Dumitrescu 			return;
193683f58a7bSCristian Dumitrescu 		}
193783f58a7bSCristian Dumitrescu 
1938b9559f94SCristian Dumitrescu 		status = rte_swx_ctl_pipeline_regarray_write(p, name, idx, value);
193964cfcebdSCristian Dumitrescu 		if (status) {
194064cfcebdSCristian Dumitrescu 			snprintf(out, out_size, "Command failed.\n");
194164cfcebdSCristian Dumitrescu 			return;
194264cfcebdSCristian Dumitrescu 		}
194383f58a7bSCristian Dumitrescu 
194483f58a7bSCristian Dumitrescu 		snprintf(out, out_size, "0x%" PRIx64 "\n", value);
194583f58a7bSCristian Dumitrescu 		return;
194683f58a7bSCristian Dumitrescu 	}
194783f58a7bSCristian Dumitrescu 
194883f58a7bSCristian Dumitrescu 	/* table. */
194983f58a7bSCristian Dumitrescu 	if (!strcmp(tokens[6], "table")) {
195083f58a7bSCristian Dumitrescu 		struct rte_swx_table_entry *entry;
195183f58a7bSCristian Dumitrescu 		char *table_name;
195283f58a7bSCristian Dumitrescu 
195383f58a7bSCristian Dumitrescu 		if (n_tokens < 10) {
195483f58a7bSCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
195583f58a7bSCristian Dumitrescu 			return;
195683f58a7bSCristian Dumitrescu 		}
195783f58a7bSCristian Dumitrescu 
195883f58a7bSCristian Dumitrescu 		table_name = tokens[7];
195983f58a7bSCristian Dumitrescu 
196083f58a7bSCristian Dumitrescu 		if (strcmp(tokens[8], "match")) {
196183f58a7bSCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_NOT_FOUND, "match");
196283f58a7bSCristian Dumitrescu 			return;
196383f58a7bSCristian Dumitrescu 		}
196483f58a7bSCristian Dumitrescu 
196583f58a7bSCristian Dumitrescu 		entry = parse_table_entry(ctl, table_name, &tokens[8], n_tokens - 8);
196683f58a7bSCristian Dumitrescu 		if (!entry) {
196783f58a7bSCristian Dumitrescu 			snprintf(out, out_size, "Invalid match tokens.\n");
196883f58a7bSCristian Dumitrescu 			return;
196983f58a7bSCristian Dumitrescu 		}
197083f58a7bSCristian Dumitrescu 
197183f58a7bSCristian Dumitrescu 		status = rte_swx_ctl_pipeline_regarray_write_with_key(p,
197283f58a7bSCristian Dumitrescu 								      name,
197383f58a7bSCristian Dumitrescu 								      table_name,
197483f58a7bSCristian Dumitrescu 								      entry->key,
197583f58a7bSCristian Dumitrescu 								      value);
197683f58a7bSCristian Dumitrescu 		table_entry_free(entry);
197783f58a7bSCristian Dumitrescu 		if (status) {
197883f58a7bSCristian Dumitrescu 			snprintf(out, out_size, "Command failed.\n");
197983f58a7bSCristian Dumitrescu 			return;
198083f58a7bSCristian Dumitrescu 		}
198183f58a7bSCristian Dumitrescu 
198283f58a7bSCristian Dumitrescu 		return;
198383f58a7bSCristian Dumitrescu 	}
198483f58a7bSCristian Dumitrescu 
198583f58a7bSCristian Dumitrescu 	/* anything else. */
198683f58a7bSCristian Dumitrescu 	snprintf(out, out_size, "Invalid token %s\n.", tokens[6]);
198783f58a7bSCristian Dumitrescu 	return;
198864cfcebdSCristian Dumitrescu }
198964cfcebdSCristian Dumitrescu 
1990f38913b7SCristian Dumitrescu static const char cmd_pipeline_meter_profile_add_help[] =
1991f38913b7SCristian Dumitrescu "pipeline <pipeline_name> meter profile <profile_name> add "
1992f38913b7SCristian Dumitrescu 	"cir <cir> pir <pir> cbs <cbs> pbs <pbs>\n";
1993f38913b7SCristian Dumitrescu 
1994f38913b7SCristian Dumitrescu static void
1995f38913b7SCristian Dumitrescu cmd_pipeline_meter_profile_add(char **tokens,
1996f38913b7SCristian Dumitrescu 	uint32_t n_tokens,
1997f38913b7SCristian Dumitrescu 	char *out,
1998f38913b7SCristian Dumitrescu 	size_t out_size,
1999b9559f94SCristian Dumitrescu 	void *obj __rte_unused)
2000f38913b7SCristian Dumitrescu {
2001f38913b7SCristian Dumitrescu 	struct rte_meter_trtcm_params params;
2002b9559f94SCristian Dumitrescu 	struct rte_swx_pipeline *p;
2003f38913b7SCristian Dumitrescu 	const char *profile_name;
2004f38913b7SCristian Dumitrescu 	int status;
2005f38913b7SCristian Dumitrescu 
2006f38913b7SCristian Dumitrescu 	if (n_tokens != 14) {
2007f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2008f38913b7SCristian Dumitrescu 		return;
2009f38913b7SCristian Dumitrescu 	}
2010f38913b7SCristian Dumitrescu 
2011b9559f94SCristian Dumitrescu 	p = rte_swx_pipeline_find(tokens[1]);
2012b9559f94SCristian Dumitrescu 	if (!p) {
2013f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
2014f38913b7SCristian Dumitrescu 		return;
2015f38913b7SCristian Dumitrescu 	}
2016f38913b7SCristian Dumitrescu 
2017f38913b7SCristian Dumitrescu 	if (strcmp(tokens[2], "meter")) {
2018f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "meter");
2019f38913b7SCristian Dumitrescu 		return;
2020f38913b7SCristian Dumitrescu 	}
2021f38913b7SCristian Dumitrescu 
2022f38913b7SCristian Dumitrescu 	if (strcmp(tokens[3], "profile")) {
2023f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "profile");
2024f38913b7SCristian Dumitrescu 		return;
2025f38913b7SCristian Dumitrescu 	}
2026f38913b7SCristian Dumitrescu 
2027f38913b7SCristian Dumitrescu 	profile_name = tokens[4];
2028f38913b7SCristian Dumitrescu 
2029f38913b7SCristian Dumitrescu 	if (strcmp(tokens[5], "add")) {
2030f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "add");
2031f38913b7SCristian Dumitrescu 		return;
2032f38913b7SCristian Dumitrescu 	}
2033f38913b7SCristian Dumitrescu 
2034f38913b7SCristian Dumitrescu 	if (strcmp(tokens[6], "cir")) {
2035f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cir");
2036f38913b7SCristian Dumitrescu 		return;
2037f38913b7SCristian Dumitrescu 	}
2038f38913b7SCristian Dumitrescu 
2039f38913b7SCristian Dumitrescu 	if (parser_read_uint64(&params.cir, tokens[7])) {
2040f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "cir");
2041f38913b7SCristian Dumitrescu 		return;
2042f38913b7SCristian Dumitrescu 	}
2043f38913b7SCristian Dumitrescu 
2044f38913b7SCristian Dumitrescu 	if (strcmp(tokens[8], "pir")) {
2045f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pir");
2046f38913b7SCristian Dumitrescu 		return;
2047f38913b7SCristian Dumitrescu 	}
2048f38913b7SCristian Dumitrescu 
2049f38913b7SCristian Dumitrescu 	if (parser_read_uint64(&params.pir, tokens[9])) {
2050f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pir");
2051f38913b7SCristian Dumitrescu 		return;
2052f38913b7SCristian Dumitrescu 	}
2053f38913b7SCristian Dumitrescu 
2054f38913b7SCristian Dumitrescu 	if (strcmp(tokens[10], "cbs")) {
2055f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cbs");
2056f38913b7SCristian Dumitrescu 		return;
2057f38913b7SCristian Dumitrescu 	}
2058f38913b7SCristian Dumitrescu 
2059f38913b7SCristian Dumitrescu 	if (parser_read_uint64(&params.cbs, tokens[11])) {
2060f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "cbs");
2061f38913b7SCristian Dumitrescu 		return;
2062f38913b7SCristian Dumitrescu 	}
2063f38913b7SCristian Dumitrescu 
2064f38913b7SCristian Dumitrescu 	if (strcmp(tokens[12], "pbs")) {
2065f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pbs");
2066f38913b7SCristian Dumitrescu 		return;
2067f38913b7SCristian Dumitrescu 	}
2068f38913b7SCristian Dumitrescu 
2069f38913b7SCristian Dumitrescu 	if (parser_read_uint64(&params.pbs, tokens[13])) {
2070f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pbs");
2071f38913b7SCristian Dumitrescu 		return;
2072f38913b7SCristian Dumitrescu 	}
2073f38913b7SCristian Dumitrescu 
2074b9559f94SCristian Dumitrescu 	status = rte_swx_ctl_meter_profile_add(p, profile_name, &params);
2075f38913b7SCristian Dumitrescu 	if (status) {
2076f38913b7SCristian Dumitrescu 		snprintf(out, out_size, "Command failed.\n");
2077f38913b7SCristian Dumitrescu 		return;
2078f38913b7SCristian Dumitrescu 	}
2079f38913b7SCristian Dumitrescu }
2080f38913b7SCristian Dumitrescu 
2081f38913b7SCristian Dumitrescu static const char cmd_pipeline_meter_profile_delete_help[] =
2082f38913b7SCristian Dumitrescu "pipeline <pipeline_name> meter profile <profile_name> delete\n";
2083f38913b7SCristian Dumitrescu 
2084f38913b7SCristian Dumitrescu static void
2085f38913b7SCristian Dumitrescu cmd_pipeline_meter_profile_delete(char **tokens,
2086f38913b7SCristian Dumitrescu 	uint32_t n_tokens,
2087f38913b7SCristian Dumitrescu 	char *out,
2088f38913b7SCristian Dumitrescu 	size_t out_size,
2089b9559f94SCristian Dumitrescu 	void *obj __rte_unused)
2090f38913b7SCristian Dumitrescu {
2091b9559f94SCristian Dumitrescu 	struct rte_swx_pipeline *p;
2092f38913b7SCristian Dumitrescu 	const char *profile_name;
2093f38913b7SCristian Dumitrescu 	int status;
2094f38913b7SCristian Dumitrescu 
2095f38913b7SCristian Dumitrescu 	if (n_tokens != 6) {
2096f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2097f38913b7SCristian Dumitrescu 		return;
2098f38913b7SCristian Dumitrescu 	}
2099f38913b7SCristian Dumitrescu 
2100b9559f94SCristian Dumitrescu 	p = rte_swx_pipeline_find(tokens[1]);
2101b9559f94SCristian Dumitrescu 	if (!p) {
2102f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
2103f38913b7SCristian Dumitrescu 		return;
2104f38913b7SCristian Dumitrescu 	}
2105f38913b7SCristian Dumitrescu 
2106f38913b7SCristian Dumitrescu 	if (strcmp(tokens[2], "meter")) {
2107f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "meter");
2108f38913b7SCristian Dumitrescu 		return;
2109f38913b7SCristian Dumitrescu 	}
2110f38913b7SCristian Dumitrescu 
2111f38913b7SCristian Dumitrescu 	if (strcmp(tokens[3], "profile")) {
2112f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "profile");
2113f38913b7SCristian Dumitrescu 		return;
2114f38913b7SCristian Dumitrescu 	}
2115f38913b7SCristian Dumitrescu 
2116f38913b7SCristian Dumitrescu 	profile_name = tokens[4];
2117f38913b7SCristian Dumitrescu 
2118f38913b7SCristian Dumitrescu 	if (strcmp(tokens[5], "delete")) {
2119f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "delete");
2120f38913b7SCristian Dumitrescu 		return;
2121f38913b7SCristian Dumitrescu 	}
2122f38913b7SCristian Dumitrescu 
2123b9559f94SCristian Dumitrescu 	status = rte_swx_ctl_meter_profile_delete(p, profile_name);
2124f38913b7SCristian Dumitrescu 	if (status) {
2125f38913b7SCristian Dumitrescu 		snprintf(out, out_size, "Command failed.\n");
2126f38913b7SCristian Dumitrescu 		return;
2127f38913b7SCristian Dumitrescu 	}
2128f38913b7SCristian Dumitrescu }
2129f38913b7SCristian Dumitrescu 
2130f38913b7SCristian Dumitrescu static const char cmd_pipeline_meter_reset_help[] =
213112eda78dSCristian Dumitrescu "pipeline <pipeline_name> meter <meter_array_name> reset\n"
213212eda78dSCristian Dumitrescu 	"index from <index0> to <index1>\n"
213312eda78dSCristian Dumitrescu 	" | table <table_name> match <field0> ...\n";
2134f38913b7SCristian Dumitrescu 
2135f38913b7SCristian Dumitrescu static void
2136f38913b7SCristian Dumitrescu cmd_pipeline_meter_reset(char **tokens,
2137f38913b7SCristian Dumitrescu 	uint32_t n_tokens,
2138f38913b7SCristian Dumitrescu 	char *out,
2139f38913b7SCristian Dumitrescu 	size_t out_size,
2140b9559f94SCristian Dumitrescu 	void *obj __rte_unused)
2141f38913b7SCristian Dumitrescu {
2142b9559f94SCristian Dumitrescu 	struct rte_swx_pipeline *p;
214312eda78dSCristian Dumitrescu 	struct rte_swx_ctl_pipeline *ctl;
214412eda78dSCristian Dumitrescu 	const char *pipeline_name, *name;
2145f38913b7SCristian Dumitrescu 
214612eda78dSCristian Dumitrescu 	if (n_tokens < 6) {
2147f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2148f38913b7SCristian Dumitrescu 		return;
2149f38913b7SCristian Dumitrescu 	}
2150f38913b7SCristian Dumitrescu 
215112eda78dSCristian Dumitrescu 	pipeline_name = tokens[1];
215212eda78dSCristian Dumitrescu 	p = rte_swx_pipeline_find(pipeline_name);
215312eda78dSCristian Dumitrescu 	ctl = rte_swx_ctl_pipeline_find(pipeline_name);
215412eda78dSCristian Dumitrescu 	if (!p || !ctl) {
2155f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
2156f38913b7SCristian Dumitrescu 		return;
2157f38913b7SCristian Dumitrescu 	}
2158f38913b7SCristian Dumitrescu 
2159f38913b7SCristian Dumitrescu 	if (strcmp(tokens[2], "meter")) {
2160f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "meter");
2161f38913b7SCristian Dumitrescu 		return;
2162f38913b7SCristian Dumitrescu 	}
2163f38913b7SCristian Dumitrescu 
2164f38913b7SCristian Dumitrescu 	name = tokens[3];
2165f38913b7SCristian Dumitrescu 
216612eda78dSCristian Dumitrescu 	if (strcmp(tokens[4], "reset")) {
216712eda78dSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "reset");
216812eda78dSCristian Dumitrescu 		return;
216912eda78dSCristian Dumitrescu 	}
217012eda78dSCristian Dumitrescu 
217112eda78dSCristian Dumitrescu 	/* index. */
217212eda78dSCristian Dumitrescu 	if (!strcmp(tokens[5], "index")) {
217312eda78dSCristian Dumitrescu 		uint32_t idx0 = 0, idx1 = 0;
217412eda78dSCristian Dumitrescu 
217512eda78dSCristian Dumitrescu 		if (n_tokens != 10) {
217612eda78dSCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
217712eda78dSCristian Dumitrescu 			return;
217812eda78dSCristian Dumitrescu 		}
217912eda78dSCristian Dumitrescu 
218012eda78dSCristian Dumitrescu 		if (strcmp(tokens[6], "from")) {
2181f38913b7SCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_NOT_FOUND, "from");
2182f38913b7SCristian Dumitrescu 			return;
2183f38913b7SCristian Dumitrescu 		}
2184f38913b7SCristian Dumitrescu 
218512eda78dSCristian Dumitrescu 		if (parser_read_uint32(&idx0, tokens[7])) {
2186f38913b7SCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_INVALID, "index0");
2187f38913b7SCristian Dumitrescu 			return;
2188f38913b7SCristian Dumitrescu 		}
2189f38913b7SCristian Dumitrescu 
219012eda78dSCristian Dumitrescu 		if (strcmp(tokens[8], "to")) {
2191f38913b7SCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_NOT_FOUND, "to");
2192f38913b7SCristian Dumitrescu 			return;
2193f38913b7SCristian Dumitrescu 		}
2194f38913b7SCristian Dumitrescu 
219512eda78dSCristian Dumitrescu 		if (parser_read_uint32(&idx1, tokens[9]) || (idx1 < idx0)) {
2196f38913b7SCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_INVALID, "index1");
2197f38913b7SCristian Dumitrescu 			return;
2198f38913b7SCristian Dumitrescu 		}
2199f38913b7SCristian Dumitrescu 
2200f38913b7SCristian Dumitrescu 		for ( ; idx0 <= idx1; idx0++) {
2201f38913b7SCristian Dumitrescu 			int status;
2202f38913b7SCristian Dumitrescu 
2203b9559f94SCristian Dumitrescu 			status = rte_swx_ctl_meter_reset(p, name, idx0);
2204f38913b7SCristian Dumitrescu 			if (status) {
2205f38913b7SCristian Dumitrescu 				snprintf(out, out_size, "Command failed for index %u.\n", idx0);
2206f38913b7SCristian Dumitrescu 				return;
2207f38913b7SCristian Dumitrescu 			}
2208f38913b7SCristian Dumitrescu 		}
220912eda78dSCristian Dumitrescu 
221012eda78dSCristian Dumitrescu 		return;
221112eda78dSCristian Dumitrescu 	}
221212eda78dSCristian Dumitrescu 
221312eda78dSCristian Dumitrescu 	/* table. */
221412eda78dSCristian Dumitrescu 	if (!strcmp(tokens[5], "table")) {
221512eda78dSCristian Dumitrescu 		struct rte_swx_table_entry *entry;
221612eda78dSCristian Dumitrescu 		char *table_name;
221712eda78dSCristian Dumitrescu 		int status;
221812eda78dSCristian Dumitrescu 
221912eda78dSCristian Dumitrescu 		if (n_tokens < 9) {
222012eda78dSCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
222112eda78dSCristian Dumitrescu 			return;
222212eda78dSCristian Dumitrescu 		}
222312eda78dSCristian Dumitrescu 
222412eda78dSCristian Dumitrescu 		table_name = tokens[6];
222512eda78dSCristian Dumitrescu 
222612eda78dSCristian Dumitrescu 		if (strcmp(tokens[7], "match")) {
222712eda78dSCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_NOT_FOUND, "match");
222812eda78dSCristian Dumitrescu 			return;
222912eda78dSCristian Dumitrescu 		}
223012eda78dSCristian Dumitrescu 
223112eda78dSCristian Dumitrescu 		entry = parse_table_entry(ctl, table_name, &tokens[7], n_tokens - 7);
223212eda78dSCristian Dumitrescu 		if (!entry) {
223312eda78dSCristian Dumitrescu 			snprintf(out, out_size, "Invalid match tokens.\n");
223412eda78dSCristian Dumitrescu 			return;
223512eda78dSCristian Dumitrescu 		}
223612eda78dSCristian Dumitrescu 
223712eda78dSCristian Dumitrescu 		status = rte_swx_ctl_meter_reset_with_key(p, name, table_name, entry->key);
223812eda78dSCristian Dumitrescu 		table_entry_free(entry);
223912eda78dSCristian Dumitrescu 		if (status) {
224012eda78dSCristian Dumitrescu 			snprintf(out, out_size, "Command failed.\n");
224112eda78dSCristian Dumitrescu 			return;
224212eda78dSCristian Dumitrescu 		}
224312eda78dSCristian Dumitrescu 
224412eda78dSCristian Dumitrescu 		return;
224512eda78dSCristian Dumitrescu 	}
224612eda78dSCristian Dumitrescu 
224712eda78dSCristian Dumitrescu 	/* anything else. */
224812eda78dSCristian Dumitrescu 	snprintf(out, out_size, "Invalid token %s\n.", tokens[5]);
224912eda78dSCristian Dumitrescu 	return;
2250f38913b7SCristian Dumitrescu }
2251f38913b7SCristian Dumitrescu 
2252f38913b7SCristian Dumitrescu static const char cmd_pipeline_meter_set_help[] =
225312eda78dSCristian Dumitrescu "pipeline <pipeline_name> meter <meter_array_name> set profile <profile_name>\n"
225412eda78dSCristian Dumitrescu 	"index from <index0> to <index1>\n"
225512eda78dSCristian Dumitrescu 	" | table <table_name> match <field0> ...\n";
2256f38913b7SCristian Dumitrescu 
2257f38913b7SCristian Dumitrescu static void
2258f38913b7SCristian Dumitrescu cmd_pipeline_meter_set(char **tokens,
2259f38913b7SCristian Dumitrescu 	uint32_t n_tokens,
2260f38913b7SCristian Dumitrescu 	char *out,
2261f38913b7SCristian Dumitrescu 	size_t out_size,
2262b9559f94SCristian Dumitrescu 	void *obj __rte_unused)
2263f38913b7SCristian Dumitrescu {
2264b9559f94SCristian Dumitrescu 	struct rte_swx_pipeline *p;
226512eda78dSCristian Dumitrescu 	struct rte_swx_ctl_pipeline *ctl;
226612eda78dSCristian Dumitrescu 	const char *pipeline_name, *name, *profile_name;
2267f38913b7SCristian Dumitrescu 
226812eda78dSCristian Dumitrescu 	if (n_tokens < 8) {
2269f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2270f38913b7SCristian Dumitrescu 		return;
2271f38913b7SCristian Dumitrescu 	}
2272f38913b7SCristian Dumitrescu 
227312eda78dSCristian Dumitrescu 	pipeline_name = tokens[1];
227412eda78dSCristian Dumitrescu 	p = rte_swx_pipeline_find(pipeline_name);
227512eda78dSCristian Dumitrescu 	ctl = rte_swx_ctl_pipeline_find(pipeline_name);
227612eda78dSCristian Dumitrescu 	if (!p || !ctl) {
2277f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
2278f38913b7SCristian Dumitrescu 		return;
2279f38913b7SCristian Dumitrescu 	}
2280f38913b7SCristian Dumitrescu 
2281f38913b7SCristian Dumitrescu 	if (strcmp(tokens[2], "meter")) {
2282f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "meter");
2283f38913b7SCristian Dumitrescu 		return;
2284f38913b7SCristian Dumitrescu 	}
2285f38913b7SCristian Dumitrescu 
2286f38913b7SCristian Dumitrescu 	name = tokens[3];
2287f38913b7SCristian Dumitrescu 
228812eda78dSCristian Dumitrescu 	if (strcmp(tokens[4], "set")) {
2289f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "set");
2290f38913b7SCristian Dumitrescu 		return;
2291f38913b7SCristian Dumitrescu 	}
2292f38913b7SCristian Dumitrescu 
229312eda78dSCristian Dumitrescu 	if (strcmp(tokens[5], "profile")) {
2294f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "profile");
2295f38913b7SCristian Dumitrescu 		return;
2296f38913b7SCristian Dumitrescu 	}
2297f38913b7SCristian Dumitrescu 
229812eda78dSCristian Dumitrescu 	profile_name = tokens[6];
229912eda78dSCristian Dumitrescu 
230012eda78dSCristian Dumitrescu 	/* index. */
230112eda78dSCristian Dumitrescu 	if (!strcmp(tokens[7], "index")) {
230212eda78dSCristian Dumitrescu 		uint32_t idx0 = 0, idx1 = 0;
230312eda78dSCristian Dumitrescu 
230412eda78dSCristian Dumitrescu 		if (n_tokens != 12) {
230512eda78dSCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
230612eda78dSCristian Dumitrescu 			return;
230712eda78dSCristian Dumitrescu 		}
230812eda78dSCristian Dumitrescu 
230912eda78dSCristian Dumitrescu 		if (strcmp(tokens[8], "from")) {
231012eda78dSCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_NOT_FOUND, "from");
231112eda78dSCristian Dumitrescu 			return;
231212eda78dSCristian Dumitrescu 		}
231312eda78dSCristian Dumitrescu 
231412eda78dSCristian Dumitrescu 		if (parser_read_uint32(&idx0, tokens[9])) {
231512eda78dSCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_INVALID, "index0");
231612eda78dSCristian Dumitrescu 			return;
231712eda78dSCristian Dumitrescu 		}
231812eda78dSCristian Dumitrescu 
231912eda78dSCristian Dumitrescu 		if (strcmp(tokens[10], "to")) {
232012eda78dSCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_NOT_FOUND, "to");
232112eda78dSCristian Dumitrescu 			return;
232212eda78dSCristian Dumitrescu 		}
232312eda78dSCristian Dumitrescu 
232412eda78dSCristian Dumitrescu 		if (parser_read_uint32(&idx1, tokens[11]) || (idx1 < idx0)) {
232512eda78dSCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_INVALID, "index1");
232612eda78dSCristian Dumitrescu 			return;
232712eda78dSCristian Dumitrescu 		}
2328f38913b7SCristian Dumitrescu 
2329f38913b7SCristian Dumitrescu 		for ( ; idx0 <= idx1; idx0++) {
2330f38913b7SCristian Dumitrescu 			int status;
2331f38913b7SCristian Dumitrescu 
2332b9559f94SCristian Dumitrescu 			status = rte_swx_ctl_meter_set(p, name, idx0, profile_name);
2333f38913b7SCristian Dumitrescu 			if (status) {
2334f38913b7SCristian Dumitrescu 				snprintf(out, out_size, "Command failed for index %u.\n", idx0);
2335f38913b7SCristian Dumitrescu 				return;
2336f38913b7SCristian Dumitrescu 			}
2337f38913b7SCristian Dumitrescu 		}
233812eda78dSCristian Dumitrescu 
233912eda78dSCristian Dumitrescu 		return;
234012eda78dSCristian Dumitrescu 	}
234112eda78dSCristian Dumitrescu 
234212eda78dSCristian Dumitrescu 	/* table. */
234312eda78dSCristian Dumitrescu 	if (!strcmp(tokens[7], "table")) {
234412eda78dSCristian Dumitrescu 		struct rte_swx_table_entry *entry;
234512eda78dSCristian Dumitrescu 		char *table_name;
234612eda78dSCristian Dumitrescu 		int status;
234712eda78dSCristian Dumitrescu 
234812eda78dSCristian Dumitrescu 		if (n_tokens < 11) {
234912eda78dSCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
235012eda78dSCristian Dumitrescu 			return;
235112eda78dSCristian Dumitrescu 		}
235212eda78dSCristian Dumitrescu 
235312eda78dSCristian Dumitrescu 		table_name = tokens[8];
235412eda78dSCristian Dumitrescu 
235512eda78dSCristian Dumitrescu 		if (strcmp(tokens[9], "match")) {
235612eda78dSCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_NOT_FOUND, "match");
235712eda78dSCristian Dumitrescu 			return;
235812eda78dSCristian Dumitrescu 		}
235912eda78dSCristian Dumitrescu 
236012eda78dSCristian Dumitrescu 		entry = parse_table_entry(ctl, table_name, &tokens[9], n_tokens - 9);
236112eda78dSCristian Dumitrescu 		if (!entry) {
236212eda78dSCristian Dumitrescu 			snprintf(out, out_size, "Invalid match tokens.\n");
236312eda78dSCristian Dumitrescu 			return;
236412eda78dSCristian Dumitrescu 		}
236512eda78dSCristian Dumitrescu 
236612eda78dSCristian Dumitrescu 		status = rte_swx_ctl_meter_set_with_key(p,
236712eda78dSCristian Dumitrescu 							name,
236812eda78dSCristian Dumitrescu 							table_name,
236912eda78dSCristian Dumitrescu 							entry->key,
237012eda78dSCristian Dumitrescu 							profile_name);
237112eda78dSCristian Dumitrescu 		table_entry_free(entry);
237212eda78dSCristian Dumitrescu 		if (status) {
237312eda78dSCristian Dumitrescu 			snprintf(out, out_size, "Command failed.\n");
237412eda78dSCristian Dumitrescu 			return;
237512eda78dSCristian Dumitrescu 		}
237612eda78dSCristian Dumitrescu 
237712eda78dSCristian Dumitrescu 		return;
237812eda78dSCristian Dumitrescu 	}
237912eda78dSCristian Dumitrescu 
238012eda78dSCristian Dumitrescu 	/* anything else. */
238112eda78dSCristian Dumitrescu 	snprintf(out, out_size, "Invalid token %s\n.", tokens[7]);
238212eda78dSCristian Dumitrescu 	return;
2383f38913b7SCristian Dumitrescu }
2384f38913b7SCristian Dumitrescu 
2385f38913b7SCristian Dumitrescu static const char cmd_pipeline_meter_stats_help[] =
238612eda78dSCristian Dumitrescu "pipeline <pipeline_name> meter <meter_array_name> stats\n"
238712eda78dSCristian Dumitrescu 	"index from <index0> to <index1>\n"
238812eda78dSCristian Dumitrescu 	" | table <table_name> match <field0> ...\n";
2389f38913b7SCristian Dumitrescu 
2390f38913b7SCristian Dumitrescu static void
2391f38913b7SCristian Dumitrescu cmd_pipeline_meter_stats(char **tokens,
2392f38913b7SCristian Dumitrescu 	uint32_t n_tokens,
2393f38913b7SCristian Dumitrescu 	char *out,
2394f38913b7SCristian Dumitrescu 	size_t out_size,
2395b9559f94SCristian Dumitrescu 	void *obj __rte_unused)
2396f38913b7SCristian Dumitrescu {
2397f38913b7SCristian Dumitrescu 	struct rte_swx_ctl_meter_stats stats;
2398b9559f94SCristian Dumitrescu 	struct rte_swx_pipeline *p;
239912eda78dSCristian Dumitrescu 	struct rte_swx_ctl_pipeline *ctl;
240012eda78dSCristian Dumitrescu 	const char *pipeline_name, *name;
2401f38913b7SCristian Dumitrescu 
240212eda78dSCristian Dumitrescu 	if (n_tokens < 6) {
2403f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2404f38913b7SCristian Dumitrescu 		return;
2405f38913b7SCristian Dumitrescu 	}
2406f38913b7SCristian Dumitrescu 
240712eda78dSCristian Dumitrescu 	pipeline_name = tokens[1];
240812eda78dSCristian Dumitrescu 	p = rte_swx_pipeline_find(pipeline_name);
240912eda78dSCristian Dumitrescu 	ctl = rte_swx_ctl_pipeline_find(pipeline_name);
241012eda78dSCristian Dumitrescu 	if (!p || !ctl) {
2411f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
2412f38913b7SCristian Dumitrescu 		return;
2413f38913b7SCristian Dumitrescu 	}
2414f38913b7SCristian Dumitrescu 
2415f38913b7SCristian Dumitrescu 	if (strcmp(tokens[2], "meter")) {
2416f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "meter");
2417f38913b7SCristian Dumitrescu 		return;
2418f38913b7SCristian Dumitrescu 	}
2419f38913b7SCristian Dumitrescu 
2420f38913b7SCristian Dumitrescu 	name = tokens[3];
2421f38913b7SCristian Dumitrescu 
242212eda78dSCristian Dumitrescu 	if (strcmp(tokens[4], "stats")) {
242312eda78dSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "stats");
242412eda78dSCristian Dumitrescu 		return;
242512eda78dSCristian Dumitrescu 	}
242612eda78dSCristian Dumitrescu 
242712eda78dSCristian Dumitrescu 	/* index. */
242812eda78dSCristian Dumitrescu 	if (!strcmp(tokens[5], "index")) {
242912eda78dSCristian Dumitrescu 		uint32_t idx0 = 0, idx1 = 0;
243012eda78dSCristian Dumitrescu 
243112eda78dSCristian Dumitrescu 		if (n_tokens != 10) {
243212eda78dSCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
243312eda78dSCristian Dumitrescu 			return;
243412eda78dSCristian Dumitrescu 		}
243512eda78dSCristian Dumitrescu 
243612eda78dSCristian Dumitrescu 		if (strcmp(tokens[6], "from")) {
2437f38913b7SCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_NOT_FOUND, "from");
2438f38913b7SCristian Dumitrescu 			return;
2439f38913b7SCristian Dumitrescu 		}
2440f38913b7SCristian Dumitrescu 
244112eda78dSCristian Dumitrescu 		if (parser_read_uint32(&idx0, tokens[7])) {
2442f38913b7SCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_INVALID, "index0");
2443f38913b7SCristian Dumitrescu 			return;
2444f38913b7SCristian Dumitrescu 		}
2445f38913b7SCristian Dumitrescu 
244612eda78dSCristian Dumitrescu 		if (strcmp(tokens[8], "to")) {
2447f38913b7SCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_NOT_FOUND, "to");
2448f38913b7SCristian Dumitrescu 			return;
2449f38913b7SCristian Dumitrescu 		}
2450f38913b7SCristian Dumitrescu 
245112eda78dSCristian Dumitrescu 		if (parser_read_uint32(&idx1, tokens[9]) || (idx1 < idx0)) {
2452f38913b7SCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_INVALID, "index1");
2453f38913b7SCristian Dumitrescu 			return;
2454f38913b7SCristian Dumitrescu 		}
2455f38913b7SCristian Dumitrescu 
2456f38913b7SCristian Dumitrescu 		/* Table header. */
2457f38913b7SCristian Dumitrescu 		snprintf(out, out_size, "+-%7s-+-%16s-+-%16s-+-%16s-+-%16s-+-%16s-+-%16s-+\n",
2458f38913b7SCristian Dumitrescu 			 "-------",
2459f38913b7SCristian Dumitrescu 			 "----------------", "----------------", "----------------",
2460f38913b7SCristian Dumitrescu 			 "----------------", "----------------", "----------------");
2461f38913b7SCristian Dumitrescu 		out_size -= strlen(out);
2462f38913b7SCristian Dumitrescu 		out += strlen(out);
2463f38913b7SCristian Dumitrescu 
2464f38913b7SCristian Dumitrescu 		snprintf(out, out_size, "| %4s | %16s | %16s | %16s | %16s | %16s | %16s |\n",
2465f38913b7SCristian Dumitrescu 			 "METER #",
2466f38913b7SCristian Dumitrescu 			 "GREEN (packets)", "YELLOW (packets)", "RED (packets)",
2467f38913b7SCristian Dumitrescu 			 "GREEN (bytes)", "YELLOW (bytes)", "RED (bytes)");
2468f38913b7SCristian Dumitrescu 		out_size -= strlen(out);
2469f38913b7SCristian Dumitrescu 		out += strlen(out);
2470f38913b7SCristian Dumitrescu 
2471f38913b7SCristian Dumitrescu 		snprintf(out, out_size, "+-%7s-+-%16s-+-%16s-+-%16s-+-%16s-+-%16s-+-%16s-+\n",
2472f38913b7SCristian Dumitrescu 			 "-------",
2473f38913b7SCristian Dumitrescu 			 "----------------", "----------------", "----------------",
2474f38913b7SCristian Dumitrescu 			 "----------------", "----------------", "----------------");
2475f38913b7SCristian Dumitrescu 		out_size -= strlen(out);
2476f38913b7SCristian Dumitrescu 		out += strlen(out);
2477f38913b7SCristian Dumitrescu 
2478f38913b7SCristian Dumitrescu 		/* Table rows. */
2479f38913b7SCristian Dumitrescu 		for ( ; idx0 <= idx1; idx0++) {
2480f38913b7SCristian Dumitrescu 			int status;
2481f38913b7SCristian Dumitrescu 
2482b9559f94SCristian Dumitrescu 			status = rte_swx_ctl_meter_stats_read(p, name, idx0, &stats);
2483f38913b7SCristian Dumitrescu 			if (status) {
248412eda78dSCristian Dumitrescu 				snprintf(out, out_size, "Meter stats error at index %u.\n", idx0);
2485f38913b7SCristian Dumitrescu 				out_size -= strlen(out);
2486f38913b7SCristian Dumitrescu 				out += strlen(out);
2487f38913b7SCristian Dumitrescu 				return;
2488f38913b7SCristian Dumitrescu 			}
2489f38913b7SCristian Dumitrescu 
2490f38913b7SCristian Dumitrescu 			snprintf(out, out_size, "| %7d | %16" PRIx64 " | %16" PRIx64 " | %16" PRIx64
2491f38913b7SCristian Dumitrescu 				 " | %16" PRIx64 " | %16" PRIx64 " | %16" PRIx64 " |\n",
2492f38913b7SCristian Dumitrescu 				 idx0,
2493f38913b7SCristian Dumitrescu 				 stats.n_pkts[RTE_COLOR_GREEN],
2494f38913b7SCristian Dumitrescu 				 stats.n_pkts[RTE_COLOR_YELLOW],
2495f38913b7SCristian Dumitrescu 				 stats.n_pkts[RTE_COLOR_RED],
2496f38913b7SCristian Dumitrescu 				 stats.n_bytes[RTE_COLOR_GREEN],
2497f38913b7SCristian Dumitrescu 				 stats.n_bytes[RTE_COLOR_YELLOW],
2498f38913b7SCristian Dumitrescu 				 stats.n_bytes[RTE_COLOR_RED]);
2499f38913b7SCristian Dumitrescu 			out_size -= strlen(out);
2500f38913b7SCristian Dumitrescu 			out += strlen(out);
2501f38913b7SCristian Dumitrescu 		}
250212eda78dSCristian Dumitrescu 
250312eda78dSCristian Dumitrescu 		return;
250412eda78dSCristian Dumitrescu 	}
250512eda78dSCristian Dumitrescu 
250612eda78dSCristian Dumitrescu 	/* table. */
250712eda78dSCristian Dumitrescu 	if (!strcmp(tokens[5], "table")) {
250812eda78dSCristian Dumitrescu 		struct rte_swx_table_entry *entry;
250912eda78dSCristian Dumitrescu 		char *table_name;
251012eda78dSCristian Dumitrescu 		int status;
251112eda78dSCristian Dumitrescu 
251212eda78dSCristian Dumitrescu 		if (n_tokens < 9) {
251312eda78dSCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
251412eda78dSCristian Dumitrescu 			return;
251512eda78dSCristian Dumitrescu 		}
251612eda78dSCristian Dumitrescu 
251712eda78dSCristian Dumitrescu 		table_name = tokens[6];
251812eda78dSCristian Dumitrescu 
251912eda78dSCristian Dumitrescu 		if (strcmp(tokens[7], "match")) {
252012eda78dSCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_NOT_FOUND, "match");
252112eda78dSCristian Dumitrescu 			return;
252212eda78dSCristian Dumitrescu 		}
252312eda78dSCristian Dumitrescu 
252412eda78dSCristian Dumitrescu 		entry = parse_table_entry(ctl, table_name, &tokens[7], n_tokens - 7);
252512eda78dSCristian Dumitrescu 		if (!entry) {
252612eda78dSCristian Dumitrescu 			snprintf(out, out_size, "Invalid match tokens.\n");
252712eda78dSCristian Dumitrescu 			return;
252812eda78dSCristian Dumitrescu 		}
252912eda78dSCristian Dumitrescu 
253012eda78dSCristian Dumitrescu 		status = rte_swx_ctl_meter_stats_read_with_key(p,
253112eda78dSCristian Dumitrescu 							name,
253212eda78dSCristian Dumitrescu 							table_name,
253312eda78dSCristian Dumitrescu 							entry->key,
253412eda78dSCristian Dumitrescu 							&stats);
253512eda78dSCristian Dumitrescu 		table_entry_free(entry);
253612eda78dSCristian Dumitrescu 		if (status) {
253712eda78dSCristian Dumitrescu 			snprintf(out, out_size, "Command failed.\n");
253812eda78dSCristian Dumitrescu 			return;
253912eda78dSCristian Dumitrescu 		}
254012eda78dSCristian Dumitrescu 
254112eda78dSCristian Dumitrescu 		/* Table header. */
254212eda78dSCristian Dumitrescu 		snprintf(out, out_size, "+-%7s-+-%16s-+-%16s-+-%16s-+-%16s-+-%16s-+-%16s-+\n",
254312eda78dSCristian Dumitrescu 			 "-------",
254412eda78dSCristian Dumitrescu 			 "----------------", "----------------", "----------------",
254512eda78dSCristian Dumitrescu 			 "----------------", "----------------", "----------------");
254612eda78dSCristian Dumitrescu 		out_size -= strlen(out);
254712eda78dSCristian Dumitrescu 		out += strlen(out);
254812eda78dSCristian Dumitrescu 
254912eda78dSCristian Dumitrescu 		snprintf(out, out_size, "| %4s | %16s | %16s | %16s | %16s | %16s | %16s |\n",
255012eda78dSCristian Dumitrescu 			 "METER #",
255112eda78dSCristian Dumitrescu 			 "GREEN (packets)", "YELLOW (packets)", "RED (packets)",
255212eda78dSCristian Dumitrescu 			 "GREEN (bytes)", "YELLOW (bytes)", "RED (bytes)");
255312eda78dSCristian Dumitrescu 		out_size -= strlen(out);
255412eda78dSCristian Dumitrescu 		out += strlen(out);
255512eda78dSCristian Dumitrescu 
255612eda78dSCristian Dumitrescu 		snprintf(out, out_size, "+-%7s-+-%16s-+-%16s-+-%16s-+-%16s-+-%16s-+-%16s-+\n",
255712eda78dSCristian Dumitrescu 			 "-------",
255812eda78dSCristian Dumitrescu 			 "----------------", "----------------", "----------------",
255912eda78dSCristian Dumitrescu 			 "----------------", "----------------", "----------------");
256012eda78dSCristian Dumitrescu 		out_size -= strlen(out);
256112eda78dSCristian Dumitrescu 		out += strlen(out);
256212eda78dSCristian Dumitrescu 
256312eda78dSCristian Dumitrescu 		/* Table row. */
256412eda78dSCristian Dumitrescu 		snprintf(out, out_size, "| %7d | %16" PRIx64 " | %16" PRIx64 " | %16" PRIx64
256512eda78dSCristian Dumitrescu 			 " | %16" PRIx64 " | %16" PRIx64 " | %16" PRIx64 " |\n",
256612eda78dSCristian Dumitrescu 			 0,
256712eda78dSCristian Dumitrescu 			 stats.n_pkts[RTE_COLOR_GREEN],
256812eda78dSCristian Dumitrescu 			 stats.n_pkts[RTE_COLOR_YELLOW],
256912eda78dSCristian Dumitrescu 			 stats.n_pkts[RTE_COLOR_RED],
257012eda78dSCristian Dumitrescu 			 stats.n_bytes[RTE_COLOR_GREEN],
257112eda78dSCristian Dumitrescu 			 stats.n_bytes[RTE_COLOR_YELLOW],
257212eda78dSCristian Dumitrescu 			 stats.n_bytes[RTE_COLOR_RED]);
257312eda78dSCristian Dumitrescu 		out_size -= strlen(out);
257412eda78dSCristian Dumitrescu 		out += strlen(out);
257512eda78dSCristian Dumitrescu 
257612eda78dSCristian Dumitrescu 		return;
257712eda78dSCristian Dumitrescu 	}
257812eda78dSCristian Dumitrescu 
257912eda78dSCristian Dumitrescu 	/* anything else. */
258012eda78dSCristian Dumitrescu 	snprintf(out, out_size, "Invalid token %s\n.", tokens[5]);
258112eda78dSCristian Dumitrescu 	return;
2582f38913b7SCristian Dumitrescu }
2583f38913b7SCristian Dumitrescu 
25845074e1d5SCristian Dumitrescu static const char cmd_pipeline_stats_help[] =
25855074e1d5SCristian Dumitrescu "pipeline <pipeline_name> stats\n";
25865074e1d5SCristian Dumitrescu 
25875074e1d5SCristian Dumitrescu static void
25885074e1d5SCristian Dumitrescu cmd_pipeline_stats(char **tokens,
25895074e1d5SCristian Dumitrescu 	uint32_t n_tokens,
25905074e1d5SCristian Dumitrescu 	char *out,
25915074e1d5SCristian Dumitrescu 	size_t out_size,
2592b9559f94SCristian Dumitrescu 	void *obj __rte_unused)
25935074e1d5SCristian Dumitrescu {
25945074e1d5SCristian Dumitrescu 	struct rte_swx_ctl_pipeline_info info;
2595b9559f94SCristian Dumitrescu 	struct rte_swx_pipeline *p;
25965074e1d5SCristian Dumitrescu 	uint32_t i;
25975074e1d5SCristian Dumitrescu 	int status;
25985074e1d5SCristian Dumitrescu 
25995074e1d5SCristian Dumitrescu 	if (n_tokens != 3) {
26005074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
26015074e1d5SCristian Dumitrescu 		return;
26025074e1d5SCristian Dumitrescu 	}
26035074e1d5SCristian Dumitrescu 
2604b9559f94SCristian Dumitrescu 	p = rte_swx_pipeline_find(tokens[1]);
2605b9559f94SCristian Dumitrescu 	if (!p) {
26065074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
26075074e1d5SCristian Dumitrescu 		return;
26085074e1d5SCristian Dumitrescu 	}
26095074e1d5SCristian Dumitrescu 
26105074e1d5SCristian Dumitrescu 	if (strcmp(tokens[2], "stats")) {
26115074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "stats");
26125074e1d5SCristian Dumitrescu 		return;
26135074e1d5SCristian Dumitrescu 	}
26145074e1d5SCristian Dumitrescu 
2615b9559f94SCristian Dumitrescu 	status = rte_swx_ctl_pipeline_info_get(p, &info);
26165074e1d5SCristian Dumitrescu 	if (status) {
26175074e1d5SCristian Dumitrescu 		snprintf(out, out_size, "Pipeline info get error.");
26185074e1d5SCristian Dumitrescu 		return;
26195074e1d5SCristian Dumitrescu 	}
26205074e1d5SCristian Dumitrescu 
26215074e1d5SCristian Dumitrescu 	snprintf(out, out_size, "Input ports:\n");
26225074e1d5SCristian Dumitrescu 	out_size -= strlen(out);
26235074e1d5SCristian Dumitrescu 	out += strlen(out);
26245074e1d5SCristian Dumitrescu 
26255074e1d5SCristian Dumitrescu 	for (i = 0; i < info.n_ports_in; i++) {
26265074e1d5SCristian Dumitrescu 		struct rte_swx_port_in_stats stats;
26275074e1d5SCristian Dumitrescu 
2628b9559f94SCristian Dumitrescu 		rte_swx_ctl_pipeline_port_in_stats_read(p, i, &stats);
26295074e1d5SCristian Dumitrescu 
26305074e1d5SCristian Dumitrescu 		snprintf(out, out_size, "\tPort %u:"
26315074e1d5SCristian Dumitrescu 			" packets %" PRIu64
26325074e1d5SCristian Dumitrescu 			" bytes %" PRIu64
26335074e1d5SCristian Dumitrescu 			" empty %" PRIu64 "\n",
26345074e1d5SCristian Dumitrescu 			i, stats.n_pkts, stats.n_bytes, stats.n_empty);
26355074e1d5SCristian Dumitrescu 		out_size -= strlen(out);
26365074e1d5SCristian Dumitrescu 		out += strlen(out);
26375074e1d5SCristian Dumitrescu 	}
26385074e1d5SCristian Dumitrescu 
2639742b0a57SCristian Dumitrescu 	snprintf(out, out_size, "\nOutput ports:\n");
26405074e1d5SCristian Dumitrescu 	out_size -= strlen(out);
26415074e1d5SCristian Dumitrescu 	out += strlen(out);
26425074e1d5SCristian Dumitrescu 
26435074e1d5SCristian Dumitrescu 	for (i = 0; i < info.n_ports_out; i++) {
26445074e1d5SCristian Dumitrescu 		struct rte_swx_port_out_stats stats;
26455074e1d5SCristian Dumitrescu 
2646b9559f94SCristian Dumitrescu 		rte_swx_ctl_pipeline_port_out_stats_read(p, i, &stats);
26475074e1d5SCristian Dumitrescu 
264896b37959SCristian Dumitrescu 		if (i != info.n_ports_out - 1)
264917225455SCristian Dumitrescu 			snprintf(out, out_size, "\tPort %u:", i);
265096b37959SCristian Dumitrescu 		else
265117225455SCristian Dumitrescu 			snprintf(out, out_size, "\tDROP:");
265217225455SCristian Dumitrescu 
265317225455SCristian Dumitrescu 		out_size -= strlen(out);
265417225455SCristian Dumitrescu 		out += strlen(out);
265517225455SCristian Dumitrescu 
265617225455SCristian Dumitrescu 		snprintf(out,
265717225455SCristian Dumitrescu 			out_size,
265896b37959SCristian Dumitrescu 			" packets %" PRIu64
265917225455SCristian Dumitrescu 			" bytes %" PRIu64
266067f707b3SCristian Dumitrescu 			" packets dropped %" PRIu64
266167f707b3SCristian Dumitrescu 			" bytes dropped %" PRIu64
266217225455SCristian Dumitrescu 			" clone %" PRIu64
266317225455SCristian Dumitrescu 			" clonerr %" PRIu64 "\n",
266417225455SCristian Dumitrescu 			stats.n_pkts,
266517225455SCristian Dumitrescu 			stats.n_bytes,
266667f707b3SCristian Dumitrescu 			stats.n_pkts_drop,
266767f707b3SCristian Dumitrescu 			stats.n_bytes_drop,
266817225455SCristian Dumitrescu 			stats.n_pkts_clone,
266917225455SCristian Dumitrescu 			stats.n_pkts_clone_err);
267096b37959SCristian Dumitrescu 
26715074e1d5SCristian Dumitrescu 		out_size -= strlen(out);
26725074e1d5SCristian Dumitrescu 		out += strlen(out);
26735074e1d5SCristian Dumitrescu 	}
2674742b0a57SCristian Dumitrescu 
2675742b0a57SCristian Dumitrescu 	snprintf(out, out_size, "\nTables:\n");
2676742b0a57SCristian Dumitrescu 	out_size -= strlen(out);
2677742b0a57SCristian Dumitrescu 	out += strlen(out);
2678742b0a57SCristian Dumitrescu 
2679742b0a57SCristian Dumitrescu 	for (i = 0; i < info.n_tables; i++) {
2680742b0a57SCristian Dumitrescu 		struct rte_swx_ctl_table_info table_info;
2681742b0a57SCristian Dumitrescu 		uint64_t n_pkts_action[info.n_actions];
2682742b0a57SCristian Dumitrescu 		struct rte_swx_table_stats stats = {
2683742b0a57SCristian Dumitrescu 			.n_pkts_hit = 0,
2684742b0a57SCristian Dumitrescu 			.n_pkts_miss = 0,
2685742b0a57SCristian Dumitrescu 			.n_pkts_action = n_pkts_action,
2686742b0a57SCristian Dumitrescu 		};
2687742b0a57SCristian Dumitrescu 		uint32_t j;
2688742b0a57SCristian Dumitrescu 
2689b9559f94SCristian Dumitrescu 		status = rte_swx_ctl_table_info_get(p, i, &table_info);
2690742b0a57SCristian Dumitrescu 		if (status) {
2691742b0a57SCristian Dumitrescu 			snprintf(out, out_size, "Table info get error.");
2692742b0a57SCristian Dumitrescu 			return;
2693742b0a57SCristian Dumitrescu 		}
2694742b0a57SCristian Dumitrescu 
2695b9559f94SCristian Dumitrescu 		status = rte_swx_ctl_pipeline_table_stats_read(p, table_info.name, &stats);
2696742b0a57SCristian Dumitrescu 		if (status) {
2697742b0a57SCristian Dumitrescu 			snprintf(out, out_size, "Table stats read error.");
2698742b0a57SCristian Dumitrescu 			return;
2699742b0a57SCristian Dumitrescu 		}
2700742b0a57SCristian Dumitrescu 
2701742b0a57SCristian Dumitrescu 		snprintf(out, out_size, "\tTable %s:\n"
2702742b0a57SCristian Dumitrescu 			"\t\tHit (packets): %" PRIu64 "\n"
2703742b0a57SCristian Dumitrescu 			"\t\tMiss (packets): %" PRIu64 "\n",
2704742b0a57SCristian Dumitrescu 			table_info.name,
2705742b0a57SCristian Dumitrescu 			stats.n_pkts_hit,
2706742b0a57SCristian Dumitrescu 			stats.n_pkts_miss);
2707742b0a57SCristian Dumitrescu 		out_size -= strlen(out);
2708742b0a57SCristian Dumitrescu 		out += strlen(out);
2709742b0a57SCristian Dumitrescu 
2710742b0a57SCristian Dumitrescu 		for (j = 0; j < info.n_actions; j++) {
2711742b0a57SCristian Dumitrescu 			struct rte_swx_ctl_action_info action_info;
2712742b0a57SCristian Dumitrescu 
2713b9559f94SCristian Dumitrescu 			status = rte_swx_ctl_action_info_get(p, j, &action_info);
2714742b0a57SCristian Dumitrescu 			if (status) {
2715742b0a57SCristian Dumitrescu 				snprintf(out, out_size, "Action info get error.");
2716742b0a57SCristian Dumitrescu 				return;
2717742b0a57SCristian Dumitrescu 			}
2718742b0a57SCristian Dumitrescu 
2719742b0a57SCristian Dumitrescu 			snprintf(out, out_size, "\t\tAction %s (packets): %" PRIu64 "\n",
2720742b0a57SCristian Dumitrescu 				action_info.name,
2721742b0a57SCristian Dumitrescu 				stats.n_pkts_action[j]);
2722742b0a57SCristian Dumitrescu 			out_size -= strlen(out);
2723742b0a57SCristian Dumitrescu 			out += strlen(out);
2724742b0a57SCristian Dumitrescu 		}
2725742b0a57SCristian Dumitrescu 	}
27268bd4862fSCristian Dumitrescu 
27278bd4862fSCristian Dumitrescu 	snprintf(out, out_size, "\nLearner tables:\n");
27288bd4862fSCristian Dumitrescu 	out_size -= strlen(out);
27298bd4862fSCristian Dumitrescu 	out += strlen(out);
27308bd4862fSCristian Dumitrescu 
27318bd4862fSCristian Dumitrescu 	for (i = 0; i < info.n_learners; i++) {
27328bd4862fSCristian Dumitrescu 		struct rte_swx_ctl_learner_info learner_info;
27338bd4862fSCristian Dumitrescu 		uint64_t n_pkts_action[info.n_actions];
27348bd4862fSCristian Dumitrescu 		struct rte_swx_learner_stats stats = {
27358bd4862fSCristian Dumitrescu 			.n_pkts_hit = 0,
27368bd4862fSCristian Dumitrescu 			.n_pkts_miss = 0,
27378bd4862fSCristian Dumitrescu 			.n_pkts_action = n_pkts_action,
27388bd4862fSCristian Dumitrescu 		};
27398bd4862fSCristian Dumitrescu 		uint32_t j;
27408bd4862fSCristian Dumitrescu 
2741b9559f94SCristian Dumitrescu 		status = rte_swx_ctl_learner_info_get(p, i, &learner_info);
27428bd4862fSCristian Dumitrescu 		if (status) {
27438bd4862fSCristian Dumitrescu 			snprintf(out, out_size, "Learner table info get error.");
27448bd4862fSCristian Dumitrescu 			return;
27458bd4862fSCristian Dumitrescu 		}
27468bd4862fSCristian Dumitrescu 
2747b9559f94SCristian Dumitrescu 		status = rte_swx_ctl_pipeline_learner_stats_read(p, learner_info.name, &stats);
27488bd4862fSCristian Dumitrescu 		if (status) {
27498bd4862fSCristian Dumitrescu 			snprintf(out, out_size, "Learner table stats read error.");
27508bd4862fSCristian Dumitrescu 			return;
27518bd4862fSCristian Dumitrescu 		}
27528bd4862fSCristian Dumitrescu 
27538bd4862fSCristian Dumitrescu 		snprintf(out, out_size, "\tLearner table %s:\n"
27548bd4862fSCristian Dumitrescu 			"\t\tHit (packets): %" PRIu64 "\n"
27558bd4862fSCristian Dumitrescu 			"\t\tMiss (packets): %" PRIu64 "\n"
27568bd4862fSCristian Dumitrescu 			"\t\tLearn OK (packets): %" PRIu64 "\n"
27578bd4862fSCristian Dumitrescu 			"\t\tLearn error (packets): %" PRIu64 "\n"
275880dd28afSCristian Dumitrescu 			"\t\tRearm (packets): %" PRIu64 "\n"
27598bd4862fSCristian Dumitrescu 			"\t\tForget (packets): %" PRIu64 "\n",
27608bd4862fSCristian Dumitrescu 			learner_info.name,
27618bd4862fSCristian Dumitrescu 			stats.n_pkts_hit,
27628bd4862fSCristian Dumitrescu 			stats.n_pkts_miss,
27638bd4862fSCristian Dumitrescu 			stats.n_pkts_learn_ok,
27648bd4862fSCristian Dumitrescu 			stats.n_pkts_learn_err,
276580dd28afSCristian Dumitrescu 			stats.n_pkts_rearm,
27668bd4862fSCristian Dumitrescu 			stats.n_pkts_forget);
27678bd4862fSCristian Dumitrescu 		out_size -= strlen(out);
27688bd4862fSCristian Dumitrescu 		out += strlen(out);
27698bd4862fSCristian Dumitrescu 
27708bd4862fSCristian Dumitrescu 		for (j = 0; j < info.n_actions; j++) {
27718bd4862fSCristian Dumitrescu 			struct rte_swx_ctl_action_info action_info;
27728bd4862fSCristian Dumitrescu 
2773b9559f94SCristian Dumitrescu 			status = rte_swx_ctl_action_info_get(p, j, &action_info);
27748bd4862fSCristian Dumitrescu 			if (status) {
27758bd4862fSCristian Dumitrescu 				snprintf(out, out_size, "Action info get error.");
27768bd4862fSCristian Dumitrescu 				return;
27778bd4862fSCristian Dumitrescu 			}
27788bd4862fSCristian Dumitrescu 
27798bd4862fSCristian Dumitrescu 			snprintf(out, out_size, "\t\tAction %s (packets): %" PRIu64 "\n",
27808bd4862fSCristian Dumitrescu 				action_info.name,
27818bd4862fSCristian Dumitrescu 				stats.n_pkts_action[j]);
27828bd4862fSCristian Dumitrescu 			out_size -= strlen(out);
27838bd4862fSCristian Dumitrescu 			out += strlen(out);
27848bd4862fSCristian Dumitrescu 		}
27858bd4862fSCristian Dumitrescu 	}
27865074e1d5SCristian Dumitrescu }
27875074e1d5SCristian Dumitrescu 
278817225455SCristian Dumitrescu static const char cmd_pipeline_mirror_session_help[] =
278917225455SCristian Dumitrescu "pipeline <pipeline_name> mirror session <session_id> port <port_id> clone fast | slow "
279017225455SCristian Dumitrescu "truncate <truncation_length>\n";
279117225455SCristian Dumitrescu 
279217225455SCristian Dumitrescu static void
279317225455SCristian Dumitrescu cmd_pipeline_mirror_session(char **tokens,
279417225455SCristian Dumitrescu 	uint32_t n_tokens,
279517225455SCristian Dumitrescu 	char *out,
279617225455SCristian Dumitrescu 	size_t out_size,
2797b9559f94SCristian Dumitrescu 	void *obj __rte_unused)
279817225455SCristian Dumitrescu {
279917225455SCristian Dumitrescu 	struct rte_swx_pipeline_mirroring_session_params params;
2800b9559f94SCristian Dumitrescu 	struct rte_swx_pipeline *p;
280177dd857dSAli Alnubani 	uint32_t session_id = 0;
280217225455SCristian Dumitrescu 	int status;
280317225455SCristian Dumitrescu 
280417225455SCristian Dumitrescu 	if (n_tokens != 11) {
280517225455SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
280617225455SCristian Dumitrescu 		return;
280717225455SCristian Dumitrescu 	}
280817225455SCristian Dumitrescu 
280917225455SCristian Dumitrescu 	if (strcmp(tokens[0], "pipeline")) {
281017225455SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pipeline");
281117225455SCristian Dumitrescu 		return;
281217225455SCristian Dumitrescu 	}
281317225455SCristian Dumitrescu 
2814b9559f94SCristian Dumitrescu 	p = rte_swx_pipeline_find(tokens[1]);
2815b9559f94SCristian Dumitrescu 	if (!p) {
281617225455SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
281717225455SCristian Dumitrescu 		return;
281817225455SCristian Dumitrescu 	}
281917225455SCristian Dumitrescu 
282017225455SCristian Dumitrescu 	if (strcmp(tokens[2], "mirror")) {
282117225455SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "mirror");
282217225455SCristian Dumitrescu 		return;
282317225455SCristian Dumitrescu 	}
282417225455SCristian Dumitrescu 
282517225455SCristian Dumitrescu 	if (strcmp(tokens[3], "session")) {
282617225455SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "session");
282717225455SCristian Dumitrescu 		return;
282817225455SCristian Dumitrescu 	}
282917225455SCristian Dumitrescu 
283017225455SCristian Dumitrescu 	if (parser_read_uint32(&session_id, tokens[4])) {
283117225455SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "session_id");
283217225455SCristian Dumitrescu 		return;
283317225455SCristian Dumitrescu 	}
283417225455SCristian Dumitrescu 
283517225455SCristian Dumitrescu 	if (strcmp(tokens[5], "port")) {
283617225455SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
283717225455SCristian Dumitrescu 		return;
283817225455SCristian Dumitrescu 	}
283917225455SCristian Dumitrescu 
284017225455SCristian Dumitrescu 	if (parser_read_uint32(&params.port_id, tokens[6])) {
284117225455SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
284217225455SCristian Dumitrescu 		return;
284317225455SCristian Dumitrescu 	}
284417225455SCristian Dumitrescu 
284517225455SCristian Dumitrescu 	if (strcmp(tokens[7], "clone")) {
284617225455SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "clone");
284717225455SCristian Dumitrescu 		return;
284817225455SCristian Dumitrescu 	}
284917225455SCristian Dumitrescu 
285017225455SCristian Dumitrescu 	if (!strcmp(tokens[8], "fast"))
285117225455SCristian Dumitrescu 		params.fast_clone = 1;
285217225455SCristian Dumitrescu 	else if (!strcmp(tokens[8], "slow"))
285317225455SCristian Dumitrescu 		params.fast_clone = 0;
285417225455SCristian Dumitrescu 	else {
285517225455SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "clone");
285617225455SCristian Dumitrescu 		return;
285717225455SCristian Dumitrescu 	}
285817225455SCristian Dumitrescu 
285917225455SCristian Dumitrescu 	if (strcmp(tokens[9], "truncate")) {
286017225455SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "truncate");
286117225455SCristian Dumitrescu 		return;
286217225455SCristian Dumitrescu 	}
286317225455SCristian Dumitrescu 
286417225455SCristian Dumitrescu 	if (parser_read_uint32(&params.truncation_length, tokens[10])) {
286517225455SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "truncation_length");
286617225455SCristian Dumitrescu 		return;
286717225455SCristian Dumitrescu 	}
286817225455SCristian Dumitrescu 
2869b9559f94SCristian Dumitrescu 	status = rte_swx_ctl_pipeline_mirroring_session_set(p, session_id, &params);
287017225455SCristian Dumitrescu 	if (status) {
287117225455SCristian Dumitrescu 		snprintf(out, out_size, "Command failed!\n");
287217225455SCristian Dumitrescu 		return;
287317225455SCristian Dumitrescu 	}
287417225455SCristian Dumitrescu }
287517225455SCristian Dumitrescu 
28765074e1d5SCristian Dumitrescu static const char cmd_thread_pipeline_enable_help[] =
2877b9559f94SCristian Dumitrescu "thread <thread_id> pipeline <pipeline_name> enable [ period <timer_period_ms> ]\n";
2878b9559f94SCristian Dumitrescu 
2879b9559f94SCristian Dumitrescu #ifndef TIMER_PERIOD_MS_DEFAULT
2880b9559f94SCristian Dumitrescu #define TIMER_PERIOD_MS_DEFAULT 10
2881b9559f94SCristian Dumitrescu #endif
28825074e1d5SCristian Dumitrescu 
28835074e1d5SCristian Dumitrescu static void
28845074e1d5SCristian Dumitrescu cmd_thread_pipeline_enable(char **tokens,
28855074e1d5SCristian Dumitrescu 	uint32_t n_tokens,
28865074e1d5SCristian Dumitrescu 	char *out,
28875074e1d5SCristian Dumitrescu 	size_t out_size,
2888b9559f94SCristian Dumitrescu 	void *obj __rte_unused)
28895074e1d5SCristian Dumitrescu {
28905074e1d5SCristian Dumitrescu 	char *pipeline_name;
2891b9559f94SCristian Dumitrescu 	struct rte_swx_pipeline *p;
2892b9559f94SCristian Dumitrescu 	uint32_t thread_id, timer_period_ms = TIMER_PERIOD_MS_DEFAULT;
28935074e1d5SCristian Dumitrescu 	int status;
28945074e1d5SCristian Dumitrescu 
2895b9559f94SCristian Dumitrescu 	if ((n_tokens != 5) && (n_tokens != 7)) {
28965074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
28975074e1d5SCristian Dumitrescu 		return;
28985074e1d5SCristian Dumitrescu 	}
28995074e1d5SCristian Dumitrescu 
29005074e1d5SCristian Dumitrescu 	if (parser_read_uint32(&thread_id, tokens[1]) != 0) {
29015074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "thread_id");
29025074e1d5SCristian Dumitrescu 		return;
29035074e1d5SCristian Dumitrescu 	}
29045074e1d5SCristian Dumitrescu 
29055074e1d5SCristian Dumitrescu 	if (strcmp(tokens[2], "pipeline") != 0) {
29065074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pipeline");
29075074e1d5SCristian Dumitrescu 		return;
29085074e1d5SCristian Dumitrescu 	}
29095074e1d5SCristian Dumitrescu 
29105074e1d5SCristian Dumitrescu 	pipeline_name = tokens[3];
2911b9559f94SCristian Dumitrescu 	p = rte_swx_pipeline_find(pipeline_name);
2912b9559f94SCristian Dumitrescu 	if (!p) {
29135074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
29145074e1d5SCristian Dumitrescu 		return;
29155074e1d5SCristian Dumitrescu 	}
29165074e1d5SCristian Dumitrescu 
29175074e1d5SCristian Dumitrescu 	if (strcmp(tokens[4], "enable") != 0) {
29185074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "enable");
29195074e1d5SCristian Dumitrescu 		return;
29205074e1d5SCristian Dumitrescu 	}
29215074e1d5SCristian Dumitrescu 
2922b9559f94SCristian Dumitrescu 	if (n_tokens == 7) {
2923b9559f94SCristian Dumitrescu 		if (strcmp(tokens[5], "period") != 0) {
2924b9559f94SCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_NOT_FOUND, "period");
2925b9559f94SCristian Dumitrescu 			return;
2926b9559f94SCristian Dumitrescu 		}
2927b9559f94SCristian Dumitrescu 
2928b9559f94SCristian Dumitrescu 		if (parser_read_uint32(&timer_period_ms, tokens[6]) != 0) {
2929b9559f94SCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_INVALID, "timer_period_ms");
2930b9559f94SCristian Dumitrescu 			return;
2931b9559f94SCristian Dumitrescu 		}
2932b9559f94SCristian Dumitrescu 	}
2933b9559f94SCristian Dumitrescu 
2934b9559f94SCristian Dumitrescu 	status = thread_pipeline_enable(thread_id, p, timer_period_ms);
29355074e1d5SCristian Dumitrescu 	if (status) {
29365074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_CMD_FAIL, "thread pipeline enable");
29375074e1d5SCristian Dumitrescu 		return;
29385074e1d5SCristian Dumitrescu 	}
29395074e1d5SCristian Dumitrescu }
29405074e1d5SCristian Dumitrescu 
29415074e1d5SCristian Dumitrescu static const char cmd_thread_pipeline_disable_help[] =
29425074e1d5SCristian Dumitrescu "thread <thread_id> pipeline <pipeline_name> disable\n";
29435074e1d5SCristian Dumitrescu 
29445074e1d5SCristian Dumitrescu static void
29455074e1d5SCristian Dumitrescu cmd_thread_pipeline_disable(char **tokens,
29465074e1d5SCristian Dumitrescu 	uint32_t n_tokens,
29475074e1d5SCristian Dumitrescu 	char *out,
29485074e1d5SCristian Dumitrescu 	size_t out_size,
2949b9559f94SCristian Dumitrescu 	void *obj __rte_unused)
29505074e1d5SCristian Dumitrescu {
2951b9559f94SCristian Dumitrescu 	struct rte_swx_pipeline *p;
29525074e1d5SCristian Dumitrescu 	char *pipeline_name;
29535074e1d5SCristian Dumitrescu 	uint32_t thread_id;
29545074e1d5SCristian Dumitrescu 	int status;
29555074e1d5SCristian Dumitrescu 
29565074e1d5SCristian Dumitrescu 	if (n_tokens != 5) {
29575074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
29585074e1d5SCristian Dumitrescu 		return;
29595074e1d5SCristian Dumitrescu 	}
29605074e1d5SCristian Dumitrescu 
29615074e1d5SCristian Dumitrescu 	if (parser_read_uint32(&thread_id, tokens[1]) != 0) {
29625074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "thread_id");
29635074e1d5SCristian Dumitrescu 		return;
29645074e1d5SCristian Dumitrescu 	}
29655074e1d5SCristian Dumitrescu 
29665074e1d5SCristian Dumitrescu 	if (strcmp(tokens[2], "pipeline") != 0) {
29675074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pipeline");
29685074e1d5SCristian Dumitrescu 		return;
29695074e1d5SCristian Dumitrescu 	}
29705074e1d5SCristian Dumitrescu 
29715074e1d5SCristian Dumitrescu 	pipeline_name = tokens[3];
2972b9559f94SCristian Dumitrescu 	p = rte_swx_pipeline_find(pipeline_name);
2973b9559f94SCristian Dumitrescu 	if (!p) {
29745074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
29755074e1d5SCristian Dumitrescu 		return;
29765074e1d5SCristian Dumitrescu 	}
29775074e1d5SCristian Dumitrescu 
29785074e1d5SCristian Dumitrescu 	if (strcmp(tokens[4], "disable") != 0) {
29795074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "disable");
29805074e1d5SCristian Dumitrescu 		return;
29815074e1d5SCristian Dumitrescu 	}
29825074e1d5SCristian Dumitrescu 
2983b9559f94SCristian Dumitrescu 	status = thread_pipeline_disable(thread_id, p);
29845074e1d5SCristian Dumitrescu 	if (status) {
29855074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_CMD_FAIL,
29865074e1d5SCristian Dumitrescu 			"thread pipeline disable");
29875074e1d5SCristian Dumitrescu 		return;
29885074e1d5SCristian Dumitrescu 	}
29895074e1d5SCristian Dumitrescu }
29905074e1d5SCristian Dumitrescu 
29915074e1d5SCristian Dumitrescu static void
29925074e1d5SCristian Dumitrescu cmd_help(char **tokens,
29935074e1d5SCristian Dumitrescu 	 uint32_t n_tokens,
29945074e1d5SCristian Dumitrescu 	 char *out,
29955074e1d5SCristian Dumitrescu 	 size_t out_size,
29965074e1d5SCristian Dumitrescu 	 void *arg __rte_unused)
29975074e1d5SCristian Dumitrescu {
29985074e1d5SCristian Dumitrescu 	tokens++;
29995074e1d5SCristian Dumitrescu 	n_tokens--;
30005074e1d5SCristian Dumitrescu 
30015074e1d5SCristian Dumitrescu 	if (n_tokens == 0) {
30025074e1d5SCristian Dumitrescu 		snprintf(out, out_size,
30037fef9ef1SYogesh Jangra 			"Type 'help <command>' for command details.\n\n"
30047fef9ef1SYogesh Jangra 			"List of commands:\n"
30057fef9ef1SYogesh Jangra 			"\tmempool\n"
3006f31c80f8SCristian Dumitrescu 			"\tethdev\n"
3007*607dd517SCristian Dumitrescu 			"\tring\n"
30089043f66aSCristian Dumitrescu 			"\tpipeline codegen\n"
30096bc14d9fSCristian Dumitrescu 			"\tpipeline libbuild\n"
30107fef9ef1SYogesh Jangra 			"\tpipeline build\n"
301175129cebSChurchill Khangar 			"\tpipeline table add\n"
301275129cebSChurchill Khangar 			"\tpipeline table delete\n"
301375129cebSChurchill Khangar 			"\tpipeline table default\n"
301475129cebSChurchill Khangar 			"\tpipeline table show\n"
3015598fe0ddSCristian Dumitrescu 			"\tpipeline selector group add\n"
3016598fe0ddSCristian Dumitrescu 			"\tpipeline selector group delete\n"
3017598fe0ddSCristian Dumitrescu 			"\tpipeline selector group member add\n"
3018598fe0ddSCristian Dumitrescu 			"\tpipeline selector group member delete\n"
3019598fe0ddSCristian Dumitrescu 			"\tpipeline selector show\n"
30208bd4862fSCristian Dumitrescu 			"\tpipeline learner default\n"
302175129cebSChurchill Khangar 			"\tpipeline commit\n"
302275129cebSChurchill Khangar 			"\tpipeline abort\n"
302364cfcebdSCristian Dumitrescu 			"\tpipeline regrd\n"
302464cfcebdSCristian Dumitrescu 			"\tpipeline regwr\n"
3025f38913b7SCristian Dumitrescu 			"\tpipeline meter profile add\n"
3026f38913b7SCristian Dumitrescu 			"\tpipeline meter profile delete\n"
3027f38913b7SCristian Dumitrescu 			"\tpipeline meter reset\n"
3028f38913b7SCristian Dumitrescu 			"\tpipeline meter set\n"
3029f38913b7SCristian Dumitrescu 			"\tpipeline meter stats\n"
30307fef9ef1SYogesh Jangra 			"\tpipeline stats\n"
303117225455SCristian Dumitrescu 			"\tpipeline mirror session\n"
30327fef9ef1SYogesh Jangra 			"\tthread pipeline enable\n"
30337fef9ef1SYogesh Jangra 			"\tthread pipeline disable\n\n");
30345074e1d5SCristian Dumitrescu 		return;
30355074e1d5SCristian Dumitrescu 	}
30365074e1d5SCristian Dumitrescu 
30375074e1d5SCristian Dumitrescu 	if (strcmp(tokens[0], "mempool") == 0) {
30385074e1d5SCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n", cmd_mempool_help);
30395074e1d5SCristian Dumitrescu 		return;
30405074e1d5SCristian Dumitrescu 	}
30415074e1d5SCristian Dumitrescu 
3042f31c80f8SCristian Dumitrescu 	if (strcmp(tokens[0], "ethdev") == 0) {
3043f31c80f8SCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n", cmd_ethdev_help);
30445074e1d5SCristian Dumitrescu 		return;
30455074e1d5SCristian Dumitrescu 	}
30465074e1d5SCristian Dumitrescu 
304777a41301SCristian Dumitrescu 	if (strcmp(tokens[0], "ring") == 0) {
304877a41301SCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n", cmd_ring_help);
304977a41301SCristian Dumitrescu 		return;
305077a41301SCristian Dumitrescu 	}
305177a41301SCristian Dumitrescu 
30525074e1d5SCristian Dumitrescu 	if ((strcmp(tokens[0], "pipeline") == 0) &&
30539043f66aSCristian Dumitrescu 		(n_tokens == 2) && (strcmp(tokens[1], "codegen") == 0)) {
30549043f66aSCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n", cmd_pipeline_codegen_help);
30559043f66aSCristian Dumitrescu 		return;
30569043f66aSCristian Dumitrescu 	}
30579043f66aSCristian Dumitrescu 
30589043f66aSCristian Dumitrescu 	if ((strcmp(tokens[0], "pipeline") == 0) &&
30596bc14d9fSCristian Dumitrescu 		(n_tokens == 2) && (strcmp(tokens[1], "libbuild") == 0)) {
30606bc14d9fSCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n", cmd_pipeline_libbuild_help);
30616bc14d9fSCristian Dumitrescu 		return;
30626bc14d9fSCristian Dumitrescu 	}
30636bc14d9fSCristian Dumitrescu 
30646bc14d9fSCristian Dumitrescu 	if ((strcmp(tokens[0], "pipeline") == 0) &&
30657fef9ef1SYogesh Jangra 		(n_tokens == 2) && (strcmp(tokens[1], "build") == 0)) {
30665074e1d5SCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n", cmd_pipeline_build_help);
30675074e1d5SCristian Dumitrescu 		return;
30685074e1d5SCristian Dumitrescu 	}
30695074e1d5SCristian Dumitrescu 
30705074e1d5SCristian Dumitrescu 	if ((strcmp(tokens[0], "pipeline") == 0) &&
30717fef9ef1SYogesh Jangra 		(n_tokens == 3) &&
30727fef9ef1SYogesh Jangra 		(strcmp(tokens[1], "table") == 0) &&
307375129cebSChurchill Khangar 		(strcmp(tokens[2], "add") == 0)) {
30745074e1d5SCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n",
307575129cebSChurchill Khangar 			cmd_pipeline_table_add_help);
307675129cebSChurchill Khangar 		return;
307775129cebSChurchill Khangar 	}
307875129cebSChurchill Khangar 
307975129cebSChurchill Khangar 	if ((strcmp(tokens[0], "pipeline") == 0) &&
308075129cebSChurchill Khangar 		(n_tokens == 3) &&
308175129cebSChurchill Khangar 		(strcmp(tokens[1], "table") == 0) &&
308275129cebSChurchill Khangar 		(strcmp(tokens[2], "delete") == 0)) {
308375129cebSChurchill Khangar 		snprintf(out, out_size, "\n%s\n",
308475129cebSChurchill Khangar 			cmd_pipeline_table_delete_help);
308575129cebSChurchill Khangar 		return;
308675129cebSChurchill Khangar 	}
308775129cebSChurchill Khangar 
308875129cebSChurchill Khangar 	if ((strcmp(tokens[0], "pipeline") == 0) &&
308975129cebSChurchill Khangar 		(n_tokens == 3) &&
309075129cebSChurchill Khangar 		(strcmp(tokens[1], "table") == 0) &&
309175129cebSChurchill Khangar 		(strcmp(tokens[2], "default") == 0)) {
309275129cebSChurchill Khangar 		snprintf(out, out_size, "\n%s\n",
309375129cebSChurchill Khangar 			cmd_pipeline_table_default_help);
309475129cebSChurchill Khangar 		return;
309575129cebSChurchill Khangar 	}
309675129cebSChurchill Khangar 
309775129cebSChurchill Khangar 	if ((strcmp(tokens[0], "pipeline") == 0) &&
309875129cebSChurchill Khangar 		(n_tokens == 3) &&
309975129cebSChurchill Khangar 		(strcmp(tokens[1], "table") == 0) &&
310075129cebSChurchill Khangar 		(strcmp(tokens[2], "show") == 0)) {
310175129cebSChurchill Khangar 		snprintf(out, out_size, "\n%s\n",
310275129cebSChurchill Khangar 			cmd_pipeline_table_show_help);
310375129cebSChurchill Khangar 		return;
310475129cebSChurchill Khangar 	}
310575129cebSChurchill Khangar 
310675129cebSChurchill Khangar 	if ((strcmp(tokens[0], "pipeline") == 0) &&
3107598fe0ddSCristian Dumitrescu 		(n_tokens == 4) &&
3108598fe0ddSCristian Dumitrescu 		(strcmp(tokens[1], "selector") == 0) &&
3109598fe0ddSCristian Dumitrescu 		(strcmp(tokens[2], "group") == 0) &&
3110598fe0ddSCristian Dumitrescu 		(strcmp(tokens[3], "add") == 0)) {
3111598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n",
3112598fe0ddSCristian Dumitrescu 			cmd_pipeline_selector_group_add_help);
3113598fe0ddSCristian Dumitrescu 		return;
3114598fe0ddSCristian Dumitrescu 	}
3115598fe0ddSCristian Dumitrescu 
3116598fe0ddSCristian Dumitrescu 	if ((strcmp(tokens[0], "pipeline") == 0) &&
3117598fe0ddSCristian Dumitrescu 		(n_tokens == 4) &&
3118598fe0ddSCristian Dumitrescu 		(strcmp(tokens[1], "selector") == 0) &&
3119598fe0ddSCristian Dumitrescu 		(strcmp(tokens[2], "group") == 0) &&
3120598fe0ddSCristian Dumitrescu 		(strcmp(tokens[3], "delete") == 0)) {
3121598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n",
3122598fe0ddSCristian Dumitrescu 			cmd_pipeline_selector_group_delete_help);
3123598fe0ddSCristian Dumitrescu 		return;
3124598fe0ddSCristian Dumitrescu 	}
3125598fe0ddSCristian Dumitrescu 
3126598fe0ddSCristian Dumitrescu 	if ((strcmp(tokens[0], "pipeline") == 0) &&
3127598fe0ddSCristian Dumitrescu 		(n_tokens == 5) &&
3128598fe0ddSCristian Dumitrescu 		(strcmp(tokens[1], "selector") == 0) &&
3129598fe0ddSCristian Dumitrescu 		(strcmp(tokens[2], "group") == 0) &&
3130598fe0ddSCristian Dumitrescu 		(strcmp(tokens[3], "member") == 0) &&
3131598fe0ddSCristian Dumitrescu 		(strcmp(tokens[4], "add") == 0)) {
3132598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n",
3133598fe0ddSCristian Dumitrescu 			cmd_pipeline_selector_group_member_add_help);
3134598fe0ddSCristian Dumitrescu 		return;
3135598fe0ddSCristian Dumitrescu 	}
3136598fe0ddSCristian Dumitrescu 
3137598fe0ddSCristian Dumitrescu 	if ((strcmp(tokens[0], "pipeline") == 0) &&
3138598fe0ddSCristian Dumitrescu 		(n_tokens == 5) &&
3139598fe0ddSCristian Dumitrescu 		(strcmp(tokens[1], "selector") == 0) &&
3140598fe0ddSCristian Dumitrescu 		(strcmp(tokens[2], "group") == 0) &&
3141598fe0ddSCristian Dumitrescu 		(strcmp(tokens[3], "member") == 0) &&
3142598fe0ddSCristian Dumitrescu 		(strcmp(tokens[4], "delete") == 0)) {
3143598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n",
3144598fe0ddSCristian Dumitrescu 			cmd_pipeline_selector_group_member_delete_help);
3145598fe0ddSCristian Dumitrescu 		return;
3146598fe0ddSCristian Dumitrescu 	}
3147598fe0ddSCristian Dumitrescu 
3148598fe0ddSCristian Dumitrescu 	if ((strcmp(tokens[0], "pipeline") == 0) &&
3149598fe0ddSCristian Dumitrescu 		(n_tokens == 3) &&
3150598fe0ddSCristian Dumitrescu 		(strcmp(tokens[1], "selector") == 0) &&
3151598fe0ddSCristian Dumitrescu 		(strcmp(tokens[2], "show") == 0)) {
3152598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n",
3153598fe0ddSCristian Dumitrescu 			cmd_pipeline_selector_show_help);
3154598fe0ddSCristian Dumitrescu 		return;
3155598fe0ddSCristian Dumitrescu 	}
3156598fe0ddSCristian Dumitrescu 
3157598fe0ddSCristian Dumitrescu 	if ((strcmp(tokens[0], "pipeline") == 0) &&
31588bd4862fSCristian Dumitrescu 		(n_tokens == 3) &&
31598bd4862fSCristian Dumitrescu 		(strcmp(tokens[1], "learner") == 0) &&
31608bd4862fSCristian Dumitrescu 		(strcmp(tokens[2], "default") == 0)) {
31618bd4862fSCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n",
31628bd4862fSCristian Dumitrescu 			cmd_pipeline_learner_default_help);
31638bd4862fSCristian Dumitrescu 		return;
31648bd4862fSCristian Dumitrescu 	}
31658bd4862fSCristian Dumitrescu 
31668bd4862fSCristian Dumitrescu 	if ((strcmp(tokens[0], "pipeline") == 0) &&
316775129cebSChurchill Khangar 		(n_tokens == 2) &&
316875129cebSChurchill Khangar 		(strcmp(tokens[1], "commit") == 0)) {
316975129cebSChurchill Khangar 		snprintf(out, out_size, "\n%s\n",
317075129cebSChurchill Khangar 			cmd_pipeline_commit_help);
317175129cebSChurchill Khangar 		return;
317275129cebSChurchill Khangar 	}
317375129cebSChurchill Khangar 
317475129cebSChurchill Khangar 	if ((strcmp(tokens[0], "pipeline") == 0) &&
317575129cebSChurchill Khangar 		(n_tokens == 2) &&
317675129cebSChurchill Khangar 		(strcmp(tokens[1], "abort") == 0)) {
317775129cebSChurchill Khangar 		snprintf(out, out_size, "\n%s\n",
317875129cebSChurchill Khangar 			cmd_pipeline_abort_help);
31795074e1d5SCristian Dumitrescu 		return;
31805074e1d5SCristian Dumitrescu 	}
31815074e1d5SCristian Dumitrescu 
31825074e1d5SCristian Dumitrescu 	if ((strcmp(tokens[0], "pipeline") == 0) &&
318364cfcebdSCristian Dumitrescu 		(n_tokens == 2) && (strcmp(tokens[1], "regrd") == 0)) {
318464cfcebdSCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n", cmd_pipeline_regrd_help);
318564cfcebdSCristian Dumitrescu 		return;
318664cfcebdSCristian Dumitrescu 	}
318764cfcebdSCristian Dumitrescu 
318864cfcebdSCristian Dumitrescu 	if ((strcmp(tokens[0], "pipeline") == 0) &&
318964cfcebdSCristian Dumitrescu 		(n_tokens == 2) && (strcmp(tokens[1], "regwr") == 0)) {
319064cfcebdSCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n", cmd_pipeline_regwr_help);
319164cfcebdSCristian Dumitrescu 		return;
319264cfcebdSCristian Dumitrescu 	}
319364cfcebdSCristian Dumitrescu 
3194f38913b7SCristian Dumitrescu 	if (!strcmp(tokens[0], "pipeline") &&
3195f38913b7SCristian Dumitrescu 		(n_tokens == 4) && !strcmp(tokens[1], "meter")
3196f38913b7SCristian Dumitrescu 		&& !strcmp(tokens[2], "profile")
3197f38913b7SCristian Dumitrescu 		&& !strcmp(tokens[3], "add")) {
3198f38913b7SCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n", cmd_pipeline_meter_profile_add_help);
3199f38913b7SCristian Dumitrescu 		return;
3200f38913b7SCristian Dumitrescu 	}
3201f38913b7SCristian Dumitrescu 
3202f38913b7SCristian Dumitrescu 	if (!strcmp(tokens[0], "pipeline") &&
3203f38913b7SCristian Dumitrescu 		(n_tokens == 4) && !strcmp(tokens[1], "meter")
3204f38913b7SCristian Dumitrescu 		&& !strcmp(tokens[2], "profile")
3205f38913b7SCristian Dumitrescu 		&& !strcmp(tokens[3], "delete")) {
3206f38913b7SCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n", cmd_pipeline_meter_profile_delete_help);
3207f38913b7SCristian Dumitrescu 		return;
3208f38913b7SCristian Dumitrescu 	}
3209f38913b7SCristian Dumitrescu 
3210f38913b7SCristian Dumitrescu 	if (!strcmp(tokens[0], "pipeline") &&
3211f38913b7SCristian Dumitrescu 		(n_tokens == 3) && !strcmp(tokens[1], "meter")
3212f38913b7SCristian Dumitrescu 		&& !strcmp(tokens[2], "reset")) {
3213f38913b7SCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n", cmd_pipeline_meter_reset_help);
3214f38913b7SCristian Dumitrescu 		return;
3215f38913b7SCristian Dumitrescu 	}
3216f38913b7SCristian Dumitrescu 
3217f38913b7SCristian Dumitrescu 	if (!strcmp(tokens[0], "pipeline") &&
3218f38913b7SCristian Dumitrescu 		(n_tokens == 3) && !strcmp(tokens[1], "meter")
3219f38913b7SCristian Dumitrescu 		&& !strcmp(tokens[2], "set")) {
3220f38913b7SCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n", cmd_pipeline_meter_set_help);
3221f38913b7SCristian Dumitrescu 		return;
3222f38913b7SCristian Dumitrescu 	}
3223f38913b7SCristian Dumitrescu 
3224f38913b7SCristian Dumitrescu 	if (!strcmp(tokens[0], "pipeline") &&
3225f38913b7SCristian Dumitrescu 		(n_tokens == 3) && !strcmp(tokens[1], "meter")
3226f38913b7SCristian Dumitrescu 		&& !strcmp(tokens[2], "stats")) {
3227f38913b7SCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n", cmd_pipeline_meter_stats_help);
3228f38913b7SCristian Dumitrescu 		return;
3229f38913b7SCristian Dumitrescu 	}
3230f38913b7SCristian Dumitrescu 
323164cfcebdSCristian Dumitrescu 	if ((strcmp(tokens[0], "pipeline") == 0) &&
32327fef9ef1SYogesh Jangra 		(n_tokens == 2) && (strcmp(tokens[1], "stats") == 0)) {
32335074e1d5SCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n", cmd_pipeline_stats_help);
32345074e1d5SCristian Dumitrescu 		return;
32355074e1d5SCristian Dumitrescu 	}
32365074e1d5SCristian Dumitrescu 
323717225455SCristian Dumitrescu 	if (!strcmp(tokens[0], "pipeline") &&
323817225455SCristian Dumitrescu 		(n_tokens == 3) && !strcmp(tokens[1], "mirror")
323917225455SCristian Dumitrescu 		&& !strcmp(tokens[2], "session")) {
324017225455SCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n", cmd_pipeline_mirror_session_help);
324117225455SCristian Dumitrescu 		return;
324217225455SCristian Dumitrescu 	}
324317225455SCristian Dumitrescu 
32445074e1d5SCristian Dumitrescu 	if ((n_tokens == 3) &&
32455074e1d5SCristian Dumitrescu 		(strcmp(tokens[0], "thread") == 0) &&
32465074e1d5SCristian Dumitrescu 		(strcmp(tokens[1], "pipeline") == 0)) {
32475074e1d5SCristian Dumitrescu 		if (strcmp(tokens[2], "enable") == 0) {
32485074e1d5SCristian Dumitrescu 			snprintf(out, out_size, "\n%s\n",
32495074e1d5SCristian Dumitrescu 				cmd_thread_pipeline_enable_help);
32505074e1d5SCristian Dumitrescu 			return;
32515074e1d5SCristian Dumitrescu 		}
32525074e1d5SCristian Dumitrescu 
32535074e1d5SCristian Dumitrescu 		if (strcmp(tokens[2], "disable") == 0) {
32545074e1d5SCristian Dumitrescu 			snprintf(out, out_size, "\n%s\n",
32555074e1d5SCristian Dumitrescu 				cmd_thread_pipeline_disable_help);
32565074e1d5SCristian Dumitrescu 			return;
32575074e1d5SCristian Dumitrescu 		}
32585074e1d5SCristian Dumitrescu 	}
32595074e1d5SCristian Dumitrescu 
32605074e1d5SCristian Dumitrescu 	snprintf(out, out_size, "Invalid command\n");
32615074e1d5SCristian Dumitrescu }
32625074e1d5SCristian Dumitrescu 
32635074e1d5SCristian Dumitrescu void
32645074e1d5SCristian Dumitrescu cli_process(char *in, char *out, size_t out_size, void *obj)
32655074e1d5SCristian Dumitrescu {
32665074e1d5SCristian Dumitrescu 	char *tokens[CMD_MAX_TOKENS];
32675074e1d5SCristian Dumitrescu 	uint32_t n_tokens = RTE_DIM(tokens);
32685074e1d5SCristian Dumitrescu 	int status;
32695074e1d5SCristian Dumitrescu 
32705074e1d5SCristian Dumitrescu 	if (is_comment(in))
32715074e1d5SCristian Dumitrescu 		return;
32725074e1d5SCristian Dumitrescu 
32735074e1d5SCristian Dumitrescu 	status = parse_tokenize_string(in, tokens, &n_tokens);
32745074e1d5SCristian Dumitrescu 	if (status) {
32755074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_TOO_MANY, "");
32765074e1d5SCristian Dumitrescu 		return;
32775074e1d5SCristian Dumitrescu 	}
32785074e1d5SCristian Dumitrescu 
32795074e1d5SCristian Dumitrescu 	if (n_tokens == 0)
32805074e1d5SCristian Dumitrescu 		return;
32815074e1d5SCristian Dumitrescu 
32825074e1d5SCristian Dumitrescu 	if (strcmp(tokens[0], "help") == 0) {
32835074e1d5SCristian Dumitrescu 		cmd_help(tokens, n_tokens, out, out_size, obj);
32845074e1d5SCristian Dumitrescu 		return;
32855074e1d5SCristian Dumitrescu 	}
32865074e1d5SCristian Dumitrescu 
32875074e1d5SCristian Dumitrescu 	if (strcmp(tokens[0], "mempool") == 0) {
32885074e1d5SCristian Dumitrescu 		cmd_mempool(tokens, n_tokens, out, out_size, obj);
32895074e1d5SCristian Dumitrescu 		return;
32905074e1d5SCristian Dumitrescu 	}
32915074e1d5SCristian Dumitrescu 
3292f31c80f8SCristian Dumitrescu 	if (strcmp(tokens[0], "ethdev") == 0) {
3293821848f5SCristian Dumitrescu 		if ((n_tokens >= 2) && (strcmp(tokens[1], "show") == 0)) {
3294f31c80f8SCristian Dumitrescu 			cmd_ethdev_show(tokens, n_tokens, out, out_size, obj);
32955074e1d5SCristian Dumitrescu 			return;
32965074e1d5SCristian Dumitrescu 		}
32975074e1d5SCristian Dumitrescu 
3298f31c80f8SCristian Dumitrescu 		cmd_ethdev(tokens, n_tokens, out, out_size, obj);
32995074e1d5SCristian Dumitrescu 		return;
33005074e1d5SCristian Dumitrescu 	}
33015074e1d5SCristian Dumitrescu 
330277a41301SCristian Dumitrescu 	if (strcmp(tokens[0], "ring") == 0) {
330377a41301SCristian Dumitrescu 		cmd_ring(tokens, n_tokens, out, out_size, obj);
330477a41301SCristian Dumitrescu 		return;
330577a41301SCristian Dumitrescu 	}
330677a41301SCristian Dumitrescu 
33075074e1d5SCristian Dumitrescu 	if (strcmp(tokens[0], "pipeline") == 0) {
33085074e1d5SCristian Dumitrescu 		if ((n_tokens >= 3) &&
33099043f66aSCristian Dumitrescu 			(strcmp(tokens[1], "codegen") == 0)) {
33109043f66aSCristian Dumitrescu 			cmd_pipeline_codegen(tokens, n_tokens, out, out_size,
33119043f66aSCristian Dumitrescu 				obj);
33129043f66aSCristian Dumitrescu 			return;
33139043f66aSCristian Dumitrescu 		}
33149043f66aSCristian Dumitrescu 
33159043f66aSCristian Dumitrescu 		if ((n_tokens >= 3) &&
33166bc14d9fSCristian Dumitrescu 			(strcmp(tokens[1], "libbuild") == 0)) {
33176bc14d9fSCristian Dumitrescu 			cmd_pipeline_libbuild(tokens, n_tokens, out, out_size,
33186bc14d9fSCristian Dumitrescu 				obj);
33196bc14d9fSCristian Dumitrescu 			return;
33206bc14d9fSCristian Dumitrescu 		}
33216bc14d9fSCristian Dumitrescu 
33226bc14d9fSCristian Dumitrescu 		if ((n_tokens >= 3) &&
33235074e1d5SCristian Dumitrescu 			(strcmp(tokens[2], "build") == 0)) {
33245074e1d5SCristian Dumitrescu 			cmd_pipeline_build(tokens, n_tokens, out, out_size,
33255074e1d5SCristian Dumitrescu 				obj);
33265074e1d5SCristian Dumitrescu 			return;
33275074e1d5SCristian Dumitrescu 		}
33285074e1d5SCristian Dumitrescu 
332975129cebSChurchill Khangar 		if ((n_tokens >= 5) &&
333075129cebSChurchill Khangar 			(strcmp(tokens[2], "table") == 0) &&
333175129cebSChurchill Khangar 			(strcmp(tokens[4], "add") == 0)) {
333275129cebSChurchill Khangar 			cmd_pipeline_table_add(tokens, n_tokens, out,
333375129cebSChurchill Khangar 				out_size, obj);
333475129cebSChurchill Khangar 			return;
333575129cebSChurchill Khangar 		}
333675129cebSChurchill Khangar 
333775129cebSChurchill Khangar 		if ((n_tokens >= 5) &&
333875129cebSChurchill Khangar 			(strcmp(tokens[2], "table") == 0) &&
333975129cebSChurchill Khangar 			(strcmp(tokens[4], "delete") == 0)) {
334075129cebSChurchill Khangar 			cmd_pipeline_table_delete(tokens, n_tokens, out,
334175129cebSChurchill Khangar 				out_size, obj);
334275129cebSChurchill Khangar 			return;
334375129cebSChurchill Khangar 		}
334475129cebSChurchill Khangar 
334575129cebSChurchill Khangar 		if ((n_tokens >= 5) &&
334675129cebSChurchill Khangar 			(strcmp(tokens[2], "table") == 0) &&
334775129cebSChurchill Khangar 			(strcmp(tokens[4], "default") == 0)) {
334875129cebSChurchill Khangar 			cmd_pipeline_table_default(tokens, n_tokens, out,
334975129cebSChurchill Khangar 				out_size, obj);
335075129cebSChurchill Khangar 			return;
335175129cebSChurchill Khangar 		}
335275129cebSChurchill Khangar 
335375129cebSChurchill Khangar 		if ((n_tokens >= 5) &&
335475129cebSChurchill Khangar 			(strcmp(tokens[2], "table") == 0) &&
335575129cebSChurchill Khangar 			(strcmp(tokens[4], "show") == 0)) {
335675129cebSChurchill Khangar 			cmd_pipeline_table_show(tokens, n_tokens, out,
335775129cebSChurchill Khangar 				out_size, obj);
335875129cebSChurchill Khangar 			return;
335975129cebSChurchill Khangar 		}
336075129cebSChurchill Khangar 
3361598fe0ddSCristian Dumitrescu 		if ((n_tokens >= 6) &&
3362598fe0ddSCristian Dumitrescu 			(strcmp(tokens[2], "selector") == 0) &&
3363598fe0ddSCristian Dumitrescu 			(strcmp(tokens[4], "group") == 0) &&
3364598fe0ddSCristian Dumitrescu 			(strcmp(tokens[5], "add") == 0)) {
3365598fe0ddSCristian Dumitrescu 			cmd_pipeline_selector_group_add(tokens, n_tokens, out,
3366598fe0ddSCristian Dumitrescu 				out_size, obj);
3367598fe0ddSCristian Dumitrescu 			return;
3368598fe0ddSCristian Dumitrescu 		}
3369598fe0ddSCristian Dumitrescu 
3370598fe0ddSCristian Dumitrescu 		if ((n_tokens >= 6) &&
3371598fe0ddSCristian Dumitrescu 			(strcmp(tokens[2], "selector") == 0) &&
3372598fe0ddSCristian Dumitrescu 			(strcmp(tokens[4], "group") == 0) &&
3373598fe0ddSCristian Dumitrescu 			(strcmp(tokens[5], "delete") == 0)) {
3374598fe0ddSCristian Dumitrescu 			cmd_pipeline_selector_group_delete(tokens, n_tokens, out,
3375598fe0ddSCristian Dumitrescu 				out_size, obj);
3376598fe0ddSCristian Dumitrescu 			return;
3377598fe0ddSCristian Dumitrescu 		}
3378598fe0ddSCristian Dumitrescu 
3379598fe0ddSCristian Dumitrescu 		if ((n_tokens >= 7) &&
3380598fe0ddSCristian Dumitrescu 			(strcmp(tokens[2], "selector") == 0) &&
3381598fe0ddSCristian Dumitrescu 			(strcmp(tokens[4], "group") == 0) &&
3382598fe0ddSCristian Dumitrescu 			(strcmp(tokens[5], "member") == 0) &&
3383598fe0ddSCristian Dumitrescu 			(strcmp(tokens[6], "add") == 0)) {
3384598fe0ddSCristian Dumitrescu 			cmd_pipeline_selector_group_member_add(tokens, n_tokens, out,
3385598fe0ddSCristian Dumitrescu 				out_size, obj);
3386598fe0ddSCristian Dumitrescu 			return;
3387598fe0ddSCristian Dumitrescu 		}
3388598fe0ddSCristian Dumitrescu 
3389598fe0ddSCristian Dumitrescu 		if ((n_tokens >= 7) &&
3390598fe0ddSCristian Dumitrescu 			(strcmp(tokens[2], "selector") == 0) &&
3391598fe0ddSCristian Dumitrescu 			(strcmp(tokens[4], "group") == 0) &&
3392598fe0ddSCristian Dumitrescu 			(strcmp(tokens[5], "member") == 0) &&
3393598fe0ddSCristian Dumitrescu 			(strcmp(tokens[6], "delete") == 0)) {
3394598fe0ddSCristian Dumitrescu 			cmd_pipeline_selector_group_member_delete(tokens, n_tokens, out,
3395598fe0ddSCristian Dumitrescu 				out_size, obj);
3396598fe0ddSCristian Dumitrescu 			return;
3397598fe0ddSCristian Dumitrescu 		}
3398598fe0ddSCristian Dumitrescu 
3399598fe0ddSCristian Dumitrescu 		if ((n_tokens >= 5) &&
3400598fe0ddSCristian Dumitrescu 			(strcmp(tokens[2], "selector") == 0) &&
3401598fe0ddSCristian Dumitrescu 			(strcmp(tokens[4], "show") == 0)) {
3402598fe0ddSCristian Dumitrescu 			cmd_pipeline_selector_show(tokens, n_tokens, out,
3403598fe0ddSCristian Dumitrescu 				out_size, obj);
3404598fe0ddSCristian Dumitrescu 			return;
3405598fe0ddSCristian Dumitrescu 		}
3406598fe0ddSCristian Dumitrescu 
34078bd4862fSCristian Dumitrescu 		if ((n_tokens >= 5) &&
34088bd4862fSCristian Dumitrescu 			(strcmp(tokens[2], "learner") == 0) &&
34098bd4862fSCristian Dumitrescu 			(strcmp(tokens[4], "default") == 0)) {
34108bd4862fSCristian Dumitrescu 			cmd_pipeline_learner_default(tokens, n_tokens, out,
34118bd4862fSCristian Dumitrescu 				out_size, obj);
34128bd4862fSCristian Dumitrescu 			return;
34138bd4862fSCristian Dumitrescu 		}
34148bd4862fSCristian Dumitrescu 
34155074e1d5SCristian Dumitrescu 		if ((n_tokens >= 3) &&
341675129cebSChurchill Khangar 			(strcmp(tokens[2], "commit") == 0)) {
341775129cebSChurchill Khangar 			cmd_pipeline_commit(tokens, n_tokens, out,
341875129cebSChurchill Khangar 				out_size, obj);
341975129cebSChurchill Khangar 			return;
342075129cebSChurchill Khangar 		}
342175129cebSChurchill Khangar 
342275129cebSChurchill Khangar 		if ((n_tokens >= 3) &&
342375129cebSChurchill Khangar 			(strcmp(tokens[2], "abort") == 0)) {
342475129cebSChurchill Khangar 			cmd_pipeline_abort(tokens, n_tokens, out,
34255074e1d5SCristian Dumitrescu 				out_size, obj);
34265074e1d5SCristian Dumitrescu 			return;
34275074e1d5SCristian Dumitrescu 		}
34285074e1d5SCristian Dumitrescu 
34295074e1d5SCristian Dumitrescu 		if ((n_tokens >= 3) &&
343064cfcebdSCristian Dumitrescu 			(strcmp(tokens[2], "regrd") == 0)) {
343164cfcebdSCristian Dumitrescu 			cmd_pipeline_regrd(tokens, n_tokens, out, out_size, obj);
343264cfcebdSCristian Dumitrescu 			return;
343364cfcebdSCristian Dumitrescu 		}
343464cfcebdSCristian Dumitrescu 
343564cfcebdSCristian Dumitrescu 		if ((n_tokens >= 3) &&
343664cfcebdSCristian Dumitrescu 			(strcmp(tokens[2], "regwr") == 0)) {
343764cfcebdSCristian Dumitrescu 			cmd_pipeline_regwr(tokens, n_tokens, out, out_size, obj);
343864cfcebdSCristian Dumitrescu 			return;
343964cfcebdSCristian Dumitrescu 		}
344064cfcebdSCristian Dumitrescu 
3441f38913b7SCristian Dumitrescu 		if ((n_tokens >= 6) &&
3442f38913b7SCristian Dumitrescu 			(strcmp(tokens[2], "meter") == 0) &&
3443f38913b7SCristian Dumitrescu 			(strcmp(tokens[3], "profile") == 0) &&
3444f38913b7SCristian Dumitrescu 			(strcmp(tokens[5], "add") == 0)) {
3445f38913b7SCristian Dumitrescu 			cmd_pipeline_meter_profile_add(tokens, n_tokens, out, out_size, obj);
3446f38913b7SCristian Dumitrescu 			return;
3447f38913b7SCristian Dumitrescu 		}
3448f38913b7SCristian Dumitrescu 
3449f38913b7SCristian Dumitrescu 		if ((n_tokens >= 6) &&
3450f38913b7SCristian Dumitrescu 			(strcmp(tokens[2], "meter") == 0) &&
3451f38913b7SCristian Dumitrescu 			(strcmp(tokens[3], "profile") == 0) &&
3452f38913b7SCristian Dumitrescu 			(strcmp(tokens[5], "delete") == 0)) {
3453f38913b7SCristian Dumitrescu 			cmd_pipeline_meter_profile_delete(tokens, n_tokens, out, out_size, obj);
3454f38913b7SCristian Dumitrescu 			return;
3455f38913b7SCristian Dumitrescu 		}
3456f38913b7SCristian Dumitrescu 
345712eda78dSCristian Dumitrescu 		if (n_tokens >= 9 && !strcmp(tokens[2], "meter") && !strcmp(tokens[4], "reset")) {
3458f38913b7SCristian Dumitrescu 			cmd_pipeline_meter_reset(tokens, n_tokens, out, out_size, obj);
3459f38913b7SCristian Dumitrescu 			return;
3460f38913b7SCristian Dumitrescu 		}
3461f38913b7SCristian Dumitrescu 
346212eda78dSCristian Dumitrescu 		if (n_tokens >= 9 && !strcmp(tokens[2], "meter") && !strcmp(tokens[4], "set")) {
3463f38913b7SCristian Dumitrescu 			cmd_pipeline_meter_set(tokens, n_tokens, out, out_size, obj);
3464f38913b7SCristian Dumitrescu 			return;
3465f38913b7SCristian Dumitrescu 		}
3466f38913b7SCristian Dumitrescu 
346712eda78dSCristian Dumitrescu 		if (n_tokens >= 9 && !strcmp(tokens[2], "meter") && !strcmp(tokens[4], "stats")) {
3468f38913b7SCristian Dumitrescu 			cmd_pipeline_meter_stats(tokens, n_tokens, out, out_size, obj);
3469f38913b7SCristian Dumitrescu 			return;
3470f38913b7SCristian Dumitrescu 		}
3471f38913b7SCristian Dumitrescu 
347264cfcebdSCristian Dumitrescu 		if ((n_tokens >= 3) &&
34735074e1d5SCristian Dumitrescu 			(strcmp(tokens[2], "stats") == 0)) {
34745074e1d5SCristian Dumitrescu 			cmd_pipeline_stats(tokens, n_tokens, out, out_size,
34755074e1d5SCristian Dumitrescu 				obj);
34765074e1d5SCristian Dumitrescu 			return;
34775074e1d5SCristian Dumitrescu 		}
347817225455SCristian Dumitrescu 
347917225455SCristian Dumitrescu 		if ((n_tokens >= 4) &&
348017225455SCristian Dumitrescu 			(strcmp(tokens[2], "mirror") == 0) &&
348117225455SCristian Dumitrescu 			(strcmp(tokens[3], "session") == 0)) {
348217225455SCristian Dumitrescu 			cmd_pipeline_mirror_session(tokens, n_tokens, out, out_size, obj);
348317225455SCristian Dumitrescu 			return;
348417225455SCristian Dumitrescu 		}
34855074e1d5SCristian Dumitrescu 	}
34865074e1d5SCristian Dumitrescu 
34875074e1d5SCristian Dumitrescu 	if (strcmp(tokens[0], "thread") == 0) {
34885074e1d5SCristian Dumitrescu 		if ((n_tokens >= 5) &&
34895074e1d5SCristian Dumitrescu 			(strcmp(tokens[4], "enable") == 0)) {
34905074e1d5SCristian Dumitrescu 			cmd_thread_pipeline_enable(tokens, n_tokens,
34915074e1d5SCristian Dumitrescu 				out, out_size, obj);
34925074e1d5SCristian Dumitrescu 			return;
34935074e1d5SCristian Dumitrescu 		}
34945074e1d5SCristian Dumitrescu 
34955074e1d5SCristian Dumitrescu 		if ((n_tokens >= 5) &&
34965074e1d5SCristian Dumitrescu 			(strcmp(tokens[4], "disable") == 0)) {
34975074e1d5SCristian Dumitrescu 			cmd_thread_pipeline_disable(tokens, n_tokens,
34985074e1d5SCristian Dumitrescu 				out, out_size, obj);
34995074e1d5SCristian Dumitrescu 			return;
35005074e1d5SCristian Dumitrescu 		}
35015074e1d5SCristian Dumitrescu 	}
35025074e1d5SCristian Dumitrescu 
35035074e1d5SCristian Dumitrescu 	snprintf(out, out_size, MSG_CMD_UNKNOWN, tokens[0]);
35045074e1d5SCristian Dumitrescu }
35055074e1d5SCristian Dumitrescu 
35065074e1d5SCristian Dumitrescu int
35075074e1d5SCristian Dumitrescu cli_script_process(const char *file_name,
35085074e1d5SCristian Dumitrescu 	size_t msg_in_len_max,
35095074e1d5SCristian Dumitrescu 	size_t msg_out_len_max,
35105074e1d5SCristian Dumitrescu 	void *obj)
35115074e1d5SCristian Dumitrescu {
35125074e1d5SCristian Dumitrescu 	char *msg_in = NULL, *msg_out = NULL;
35135074e1d5SCristian Dumitrescu 	FILE *f = NULL;
35145074e1d5SCristian Dumitrescu 
35155074e1d5SCristian Dumitrescu 	/* Check input arguments */
35165074e1d5SCristian Dumitrescu 	if ((file_name == NULL) ||
35175074e1d5SCristian Dumitrescu 		(strlen(file_name) == 0) ||
35185074e1d5SCristian Dumitrescu 		(msg_in_len_max == 0) ||
35195074e1d5SCristian Dumitrescu 		(msg_out_len_max == 0))
35205074e1d5SCristian Dumitrescu 		return -EINVAL;
35215074e1d5SCristian Dumitrescu 
35225074e1d5SCristian Dumitrescu 	msg_in = malloc(msg_in_len_max + 1);
35235074e1d5SCristian Dumitrescu 	msg_out = malloc(msg_out_len_max + 1);
35245074e1d5SCristian Dumitrescu 	if ((msg_in == NULL) ||
35255074e1d5SCristian Dumitrescu 		(msg_out == NULL)) {
35265074e1d5SCristian Dumitrescu 		free(msg_out);
35275074e1d5SCristian Dumitrescu 		free(msg_in);
35285074e1d5SCristian Dumitrescu 		return -ENOMEM;
35295074e1d5SCristian Dumitrescu 	}
35305074e1d5SCristian Dumitrescu 
35315074e1d5SCristian Dumitrescu 	/* Open input file */
35325074e1d5SCristian Dumitrescu 	f = fopen(file_name, "r");
35335074e1d5SCristian Dumitrescu 	if (f == NULL) {
35345074e1d5SCristian Dumitrescu 		free(msg_out);
35355074e1d5SCristian Dumitrescu 		free(msg_in);
35365074e1d5SCristian Dumitrescu 		return -EIO;
35375074e1d5SCristian Dumitrescu 	}
35385074e1d5SCristian Dumitrescu 
35395074e1d5SCristian Dumitrescu 	/* Read file */
35405074e1d5SCristian Dumitrescu 	for ( ; ; ) {
35415074e1d5SCristian Dumitrescu 		if (fgets(msg_in, msg_in_len_max + 1, f) == NULL)
35425074e1d5SCristian Dumitrescu 			break;
35435074e1d5SCristian Dumitrescu 
35445074e1d5SCristian Dumitrescu 		printf("%s", msg_in);
35455074e1d5SCristian Dumitrescu 		msg_out[0] = 0;
35465074e1d5SCristian Dumitrescu 
35475074e1d5SCristian Dumitrescu 		cli_process(msg_in,
35485074e1d5SCristian Dumitrescu 			msg_out,
35495074e1d5SCristian Dumitrescu 			msg_out_len_max,
35505074e1d5SCristian Dumitrescu 			obj);
35515074e1d5SCristian Dumitrescu 
35525074e1d5SCristian Dumitrescu 		if (strlen(msg_out))
35535074e1d5SCristian Dumitrescu 			printf("%s", msg_out);
35545074e1d5SCristian Dumitrescu 	}
35555074e1d5SCristian Dumitrescu 
35565074e1d5SCristian Dumitrescu 	/* Close file */
35575074e1d5SCristian Dumitrescu 	fclose(f);
35585074e1d5SCristian Dumitrescu 	free(msg_out);
35595074e1d5SCristian Dumitrescu 	free(msg_in);
35605074e1d5SCristian Dumitrescu 	return 0;
35615074e1d5SCristian Dumitrescu }
3562