xref: /dpdk/examples/pipeline/cli.c (revision ab492f943b296f58ef4d7a256923456142ad9f79)
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>
145074e1d5SCristian Dumitrescu #include <rte_swx_port_ethdev.h>
1577a41301SCristian Dumitrescu #include <rte_swx_port_ring.h>
165074e1d5SCristian Dumitrescu #include <rte_swx_port_source_sink.h>
17e2b8dc52SVenkata Suresh Kumar P #include <rte_swx_port_fd.h>
185074e1d5SCristian Dumitrescu #include <rte_swx_pipeline.h>
195074e1d5SCristian Dumitrescu #include <rte_swx_ctl.h>
205074e1d5SCristian Dumitrescu 
215074e1d5SCristian Dumitrescu #include "cli.h"
225074e1d5SCristian Dumitrescu 
235074e1d5SCristian Dumitrescu #include "obj.h"
245074e1d5SCristian Dumitrescu #include "thread.h"
255074e1d5SCristian Dumitrescu 
265074e1d5SCristian Dumitrescu #ifndef CMD_MAX_TOKENS
275074e1d5SCristian Dumitrescu #define CMD_MAX_TOKENS     256
285074e1d5SCristian Dumitrescu #endif
295074e1d5SCristian Dumitrescu 
306bc14d9fSCristian Dumitrescu #ifndef MAX_LINE_SIZE
316bc14d9fSCristian Dumitrescu #define MAX_LINE_SIZE 2048
326bc14d9fSCristian Dumitrescu #endif
336bc14d9fSCristian Dumitrescu 
345074e1d5SCristian Dumitrescu #define MSG_OUT_OF_MEMORY   "Not enough memory.\n"
355074e1d5SCristian Dumitrescu #define MSG_CMD_UNKNOWN     "Unknown command \"%s\".\n"
365074e1d5SCristian Dumitrescu #define MSG_CMD_UNIMPLEM    "Command \"%s\" not implemented.\n"
375074e1d5SCristian Dumitrescu #define MSG_ARG_NOT_ENOUGH  "Not enough arguments for command \"%s\".\n"
385074e1d5SCristian Dumitrescu #define MSG_ARG_TOO_MANY    "Too many arguments for command \"%s\".\n"
395074e1d5SCristian Dumitrescu #define MSG_ARG_MISMATCH    "Wrong number of arguments for command \"%s\".\n"
405074e1d5SCristian Dumitrescu #define MSG_ARG_NOT_FOUND   "Argument \"%s\" not found.\n"
415074e1d5SCristian Dumitrescu #define MSG_ARG_INVALID     "Invalid value for argument \"%s\".\n"
425074e1d5SCristian Dumitrescu #define MSG_FILE_ERR        "Error in file \"%s\" at line %u.\n"
435074e1d5SCristian Dumitrescu #define MSG_FILE_NOT_ENOUGH "Not enough rules in file \"%s\".\n"
445074e1d5SCristian Dumitrescu #define MSG_CMD_FAIL        "Command \"%s\" failed.\n"
455074e1d5SCristian Dumitrescu 
465074e1d5SCristian Dumitrescu #define skip_white_spaces(pos)			\
475074e1d5SCristian Dumitrescu ({						\
485074e1d5SCristian Dumitrescu 	__typeof__(pos) _p = (pos);		\
495074e1d5SCristian Dumitrescu 	for ( ; isspace(*_p); _p++)		\
505074e1d5SCristian Dumitrescu 		;				\
515074e1d5SCristian Dumitrescu 	_p;					\
525074e1d5SCristian Dumitrescu })
535074e1d5SCristian Dumitrescu 
545074e1d5SCristian Dumitrescu static int
555074e1d5SCristian Dumitrescu parser_read_uint64(uint64_t *value, const char *p)
565074e1d5SCristian Dumitrescu {
575074e1d5SCristian Dumitrescu 	char *next;
585074e1d5SCristian Dumitrescu 	uint64_t val;
595074e1d5SCristian Dumitrescu 
605074e1d5SCristian Dumitrescu 	p = skip_white_spaces(p);
615074e1d5SCristian Dumitrescu 	if (!isdigit(*p))
625074e1d5SCristian Dumitrescu 		return -EINVAL;
635074e1d5SCristian Dumitrescu 
640d644eb6SChurchill Khangar 	val = strtoul(p, &next, 0);
655074e1d5SCristian Dumitrescu 	if (p == next)
665074e1d5SCristian Dumitrescu 		return -EINVAL;
675074e1d5SCristian Dumitrescu 
685074e1d5SCristian Dumitrescu 	p = next;
695074e1d5SCristian Dumitrescu 	switch (*p) {
705074e1d5SCristian Dumitrescu 	case 'T':
715074e1d5SCristian Dumitrescu 		val *= 1024ULL;
725074e1d5SCristian Dumitrescu 		/* fall through */
735074e1d5SCristian Dumitrescu 	case 'G':
745074e1d5SCristian Dumitrescu 		val *= 1024ULL;
755074e1d5SCristian Dumitrescu 		/* fall through */
765074e1d5SCristian Dumitrescu 	case 'M':
775074e1d5SCristian Dumitrescu 		val *= 1024ULL;
785074e1d5SCristian Dumitrescu 		/* fall through */
795074e1d5SCristian Dumitrescu 	case 'k':
805074e1d5SCristian Dumitrescu 	case 'K':
815074e1d5SCristian Dumitrescu 		val *= 1024ULL;
825074e1d5SCristian Dumitrescu 		p++;
835074e1d5SCristian Dumitrescu 		break;
845074e1d5SCristian Dumitrescu 	}
855074e1d5SCristian Dumitrescu 
865074e1d5SCristian Dumitrescu 	p = skip_white_spaces(p);
875074e1d5SCristian Dumitrescu 	if (*p != '\0')
885074e1d5SCristian Dumitrescu 		return -EINVAL;
895074e1d5SCristian Dumitrescu 
905074e1d5SCristian Dumitrescu 	*value = val;
915074e1d5SCristian Dumitrescu 	return 0;
925074e1d5SCristian Dumitrescu }
935074e1d5SCristian Dumitrescu 
945074e1d5SCristian Dumitrescu static int
955074e1d5SCristian Dumitrescu parser_read_uint32(uint32_t *value, const char *p)
965074e1d5SCristian Dumitrescu {
975074e1d5SCristian Dumitrescu 	uint64_t val = 0;
985074e1d5SCristian Dumitrescu 	int ret = parser_read_uint64(&val, p);
995074e1d5SCristian Dumitrescu 
1005074e1d5SCristian Dumitrescu 	if (ret < 0)
1015074e1d5SCristian Dumitrescu 		return ret;
1025074e1d5SCristian Dumitrescu 
1035074e1d5SCristian Dumitrescu 	if (val > UINT32_MAX)
1045074e1d5SCristian Dumitrescu 		return -ERANGE;
1055074e1d5SCristian Dumitrescu 
1065074e1d5SCristian Dumitrescu 	*value = val;
1075074e1d5SCristian Dumitrescu 	return 0;
1085074e1d5SCristian Dumitrescu }
1095074e1d5SCristian Dumitrescu 
1105074e1d5SCristian Dumitrescu #define PARSE_DELIMITER " \f\n\r\t\v"
1115074e1d5SCristian Dumitrescu 
1125074e1d5SCristian Dumitrescu static int
1135074e1d5SCristian Dumitrescu parse_tokenize_string(char *string, char *tokens[], uint32_t *n_tokens)
1145074e1d5SCristian Dumitrescu {
1155074e1d5SCristian Dumitrescu 	uint32_t i;
1165074e1d5SCristian Dumitrescu 
1175074e1d5SCristian Dumitrescu 	if ((string == NULL) ||
1185074e1d5SCristian Dumitrescu 		(tokens == NULL) ||
1195074e1d5SCristian Dumitrescu 		(*n_tokens < 1))
1205074e1d5SCristian Dumitrescu 		return -EINVAL;
1215074e1d5SCristian Dumitrescu 
1225074e1d5SCristian Dumitrescu 	for (i = 0; i < *n_tokens; i++) {
1235074e1d5SCristian Dumitrescu 		tokens[i] = strtok_r(string, PARSE_DELIMITER, &string);
1245074e1d5SCristian Dumitrescu 		if (tokens[i] == NULL)
1255074e1d5SCristian Dumitrescu 			break;
1265074e1d5SCristian Dumitrescu 	}
1275074e1d5SCristian Dumitrescu 
1285074e1d5SCristian Dumitrescu 	if ((i == *n_tokens) && strtok_r(string, PARSE_DELIMITER, &string))
1295074e1d5SCristian Dumitrescu 		return -E2BIG;
1305074e1d5SCristian Dumitrescu 
1315074e1d5SCristian Dumitrescu 	*n_tokens = i;
1325074e1d5SCristian Dumitrescu 	return 0;
1335074e1d5SCristian Dumitrescu }
1345074e1d5SCristian Dumitrescu 
1355074e1d5SCristian Dumitrescu static int
1365074e1d5SCristian Dumitrescu is_comment(char *in)
1375074e1d5SCristian Dumitrescu {
1385074e1d5SCristian Dumitrescu 	if ((strlen(in) && index("!#%;", in[0])) ||
1395074e1d5SCristian Dumitrescu 		(strncmp(in, "//", 2) == 0) ||
1405074e1d5SCristian Dumitrescu 		(strncmp(in, "--", 2) == 0))
1415074e1d5SCristian Dumitrescu 		return 1;
1425074e1d5SCristian Dumitrescu 
1435074e1d5SCristian Dumitrescu 	return 0;
1445074e1d5SCristian Dumitrescu }
1455074e1d5SCristian Dumitrescu 
14683f58a7bSCristian Dumitrescu static void
14783f58a7bSCristian Dumitrescu table_entry_free(struct rte_swx_table_entry *entry)
14883f58a7bSCristian Dumitrescu {
14983f58a7bSCristian Dumitrescu 	if (!entry)
15083f58a7bSCristian Dumitrescu 		return;
15183f58a7bSCristian Dumitrescu 
15283f58a7bSCristian Dumitrescu 	free(entry->key);
15383f58a7bSCristian Dumitrescu 	free(entry->key_mask);
15483f58a7bSCristian Dumitrescu 	free(entry->action_data);
15583f58a7bSCristian Dumitrescu 	free(entry);
15683f58a7bSCristian Dumitrescu }
15783f58a7bSCristian Dumitrescu 
15883f58a7bSCristian Dumitrescu static struct rte_swx_table_entry *
15983f58a7bSCristian Dumitrescu parse_table_entry(struct rte_swx_ctl_pipeline *p,
16083f58a7bSCristian Dumitrescu 		  char *table_name,
16183f58a7bSCristian Dumitrescu 		  char **tokens,
16283f58a7bSCristian Dumitrescu 		  uint32_t n_tokens)
16383f58a7bSCristian Dumitrescu {
16483f58a7bSCristian Dumitrescu 	struct rte_swx_table_entry *entry;
16583f58a7bSCristian Dumitrescu 	char *line;
16683f58a7bSCristian Dumitrescu 	uint32_t i;
16783f58a7bSCristian Dumitrescu 
16883f58a7bSCristian Dumitrescu 	/* Buffer allocation. */
16983f58a7bSCristian Dumitrescu 	line = malloc(MAX_LINE_SIZE);
17083f58a7bSCristian Dumitrescu 	if (!line)
17183f58a7bSCristian Dumitrescu 		return NULL;
17283f58a7bSCristian Dumitrescu 
17383f58a7bSCristian Dumitrescu 	/* Copy tokens to buffer. Since the tokens were initially part of a buffer of size
17483f58a7bSCristian Dumitrescu 	 * MAX_LINE_LENGTH, it is guaranteed that putting back some of them into a buffer of the
17583f58a7bSCristian Dumitrescu 	 * same size separated by a single space will not result in buffer overrun.
17683f58a7bSCristian Dumitrescu 	 */
17783f58a7bSCristian Dumitrescu 	line[0] = 0;
17883f58a7bSCristian Dumitrescu 	for (i = 0; i < n_tokens; i++) {
17983f58a7bSCristian Dumitrescu 		if (i)
18083f58a7bSCristian Dumitrescu 			strcat(line, " ");
18183f58a7bSCristian Dumitrescu 
18283f58a7bSCristian Dumitrescu 		strcat(line, tokens[i]);
18383f58a7bSCristian Dumitrescu 	}
18483f58a7bSCristian Dumitrescu 
18583f58a7bSCristian Dumitrescu 	/* Read the table entry from the input buffer. */
18683f58a7bSCristian Dumitrescu 	entry = rte_swx_ctl_pipeline_table_entry_read(p, table_name, line, NULL);
18783f58a7bSCristian Dumitrescu 
18883f58a7bSCristian Dumitrescu 	/* Buffer free. */
18983f58a7bSCristian Dumitrescu 	free(line);
19083f58a7bSCristian Dumitrescu 
19183f58a7bSCristian Dumitrescu 	return entry;
19283f58a7bSCristian Dumitrescu }
19383f58a7bSCristian Dumitrescu 
1945074e1d5SCristian Dumitrescu static const char cmd_mempool_help[] =
1955074e1d5SCristian Dumitrescu "mempool <mempool_name>\n"
1965074e1d5SCristian Dumitrescu "   buffer <buffer_size>\n"
1975074e1d5SCristian Dumitrescu "   pool <pool_size>\n"
1985074e1d5SCristian Dumitrescu "   cache <cache_size>\n"
1995074e1d5SCristian Dumitrescu "   cpu <cpu_id>\n";
2005074e1d5SCristian Dumitrescu 
2015074e1d5SCristian Dumitrescu static void
2025074e1d5SCristian Dumitrescu cmd_mempool(char **tokens,
2035074e1d5SCristian Dumitrescu 	uint32_t n_tokens,
2045074e1d5SCristian Dumitrescu 	char *out,
2055074e1d5SCristian Dumitrescu 	size_t out_size,
2065074e1d5SCristian Dumitrescu 	void *obj)
2075074e1d5SCristian Dumitrescu {
2085074e1d5SCristian Dumitrescu 	struct mempool_params p;
2095074e1d5SCristian Dumitrescu 	char *name;
2105074e1d5SCristian Dumitrescu 	struct mempool *mempool;
2115074e1d5SCristian Dumitrescu 
2125074e1d5SCristian Dumitrescu 	if (n_tokens != 10) {
2135074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2145074e1d5SCristian Dumitrescu 		return;
2155074e1d5SCristian Dumitrescu 	}
2165074e1d5SCristian Dumitrescu 
2175074e1d5SCristian Dumitrescu 	name = tokens[1];
2185074e1d5SCristian Dumitrescu 
2195074e1d5SCristian Dumitrescu 	if (strcmp(tokens[2], "buffer") != 0) {
2205074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "buffer");
2215074e1d5SCristian Dumitrescu 		return;
2225074e1d5SCristian Dumitrescu 	}
2235074e1d5SCristian Dumitrescu 
2245074e1d5SCristian Dumitrescu 	if (parser_read_uint32(&p.buffer_size, tokens[3]) != 0) {
2255074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "buffer_size");
2265074e1d5SCristian Dumitrescu 		return;
2275074e1d5SCristian Dumitrescu 	}
2285074e1d5SCristian Dumitrescu 
2295074e1d5SCristian Dumitrescu 	if (strcmp(tokens[4], "pool") != 0) {
2305074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pool");
2315074e1d5SCristian Dumitrescu 		return;
2325074e1d5SCristian Dumitrescu 	}
2335074e1d5SCristian Dumitrescu 
2345074e1d5SCristian Dumitrescu 	if (parser_read_uint32(&p.pool_size, tokens[5]) != 0) {
2355074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pool_size");
2365074e1d5SCristian Dumitrescu 		return;
2375074e1d5SCristian Dumitrescu 	}
2385074e1d5SCristian Dumitrescu 
2395074e1d5SCristian Dumitrescu 	if (strcmp(tokens[6], "cache") != 0) {
2405074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cache");
2415074e1d5SCristian Dumitrescu 		return;
2425074e1d5SCristian Dumitrescu 	}
2435074e1d5SCristian Dumitrescu 
2445074e1d5SCristian Dumitrescu 	if (parser_read_uint32(&p.cache_size, tokens[7]) != 0) {
2455074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "cache_size");
2465074e1d5SCristian Dumitrescu 		return;
2475074e1d5SCristian Dumitrescu 	}
2485074e1d5SCristian Dumitrescu 
2495074e1d5SCristian Dumitrescu 	if (strcmp(tokens[8], "cpu") != 0) {
2505074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cpu");
2515074e1d5SCristian Dumitrescu 		return;
2525074e1d5SCristian Dumitrescu 	}
2535074e1d5SCristian Dumitrescu 
2545074e1d5SCristian Dumitrescu 	if (parser_read_uint32(&p.cpu_id, tokens[9]) != 0) {
2555074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "cpu_id");
2565074e1d5SCristian Dumitrescu 		return;
2575074e1d5SCristian Dumitrescu 	}
2585074e1d5SCristian Dumitrescu 
2595074e1d5SCristian Dumitrescu 	mempool = mempool_create(obj, name, &p);
2605074e1d5SCristian Dumitrescu 	if (mempool == NULL) {
2615074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
2625074e1d5SCristian Dumitrescu 		return;
2635074e1d5SCristian Dumitrescu 	}
2645074e1d5SCristian Dumitrescu }
2655074e1d5SCristian Dumitrescu 
266f31c80f8SCristian Dumitrescu static const char cmd_ethdev_help[] =
267f31c80f8SCristian Dumitrescu "ethdev <ethdev_name>\n"
2685074e1d5SCristian Dumitrescu "   rxq <n_queues> <queue_size> <mempool_name>\n"
2695074e1d5SCristian Dumitrescu "   txq <n_queues> <queue_size>\n"
2705074e1d5SCristian Dumitrescu "   promiscuous on | off\n"
2715074e1d5SCristian Dumitrescu "   [rss <qid_0> ... <qid_n>]\n";
2725074e1d5SCristian Dumitrescu 
2735074e1d5SCristian Dumitrescu static void
274f31c80f8SCristian Dumitrescu cmd_ethdev(char **tokens,
2755074e1d5SCristian Dumitrescu 	uint32_t n_tokens,
2765074e1d5SCristian Dumitrescu 	char *out,
2775074e1d5SCristian Dumitrescu 	size_t out_size,
2785074e1d5SCristian Dumitrescu 	void *obj)
2795074e1d5SCristian Dumitrescu {
2805074e1d5SCristian Dumitrescu 	struct link_params p;
2815074e1d5SCristian Dumitrescu 	struct link_params_rss rss;
2825074e1d5SCristian Dumitrescu 	struct link *link;
2835074e1d5SCristian Dumitrescu 	char *name;
2845074e1d5SCristian Dumitrescu 
2855074e1d5SCristian Dumitrescu 	memset(&p, 0, sizeof(p));
2865074e1d5SCristian Dumitrescu 
287f31c80f8SCristian Dumitrescu 	if ((n_tokens < 11) || (n_tokens > 12 + LINK_RXQ_RSS_MAX)) {
2885074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2895074e1d5SCristian Dumitrescu 		return;
2905074e1d5SCristian Dumitrescu 	}
2915074e1d5SCristian Dumitrescu 	name = tokens[1];
2925074e1d5SCristian Dumitrescu 
293f31c80f8SCristian Dumitrescu 	if (strcmp(tokens[2], "rxq") != 0) {
2945074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rxq");
2955074e1d5SCristian Dumitrescu 		return;
2965074e1d5SCristian Dumitrescu 	}
2975074e1d5SCristian Dumitrescu 
298f31c80f8SCristian Dumitrescu 	if (parser_read_uint32(&p.rx.n_queues, tokens[3]) != 0) {
2995074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "n_queues");
3005074e1d5SCristian Dumitrescu 		return;
3015074e1d5SCristian Dumitrescu 	}
302f31c80f8SCristian Dumitrescu 	if (parser_read_uint32(&p.rx.queue_size, tokens[4]) != 0) {
3035074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "queue_size");
3045074e1d5SCristian Dumitrescu 		return;
3055074e1d5SCristian Dumitrescu 	}
3065074e1d5SCristian Dumitrescu 
307f31c80f8SCristian Dumitrescu 	p.rx.mempool_name = tokens[5];
3085074e1d5SCristian Dumitrescu 
309f31c80f8SCristian Dumitrescu 	if (strcmp(tokens[6], "txq") != 0) {
3105074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "txq");
3115074e1d5SCristian Dumitrescu 		return;
3125074e1d5SCristian Dumitrescu 	}
3135074e1d5SCristian Dumitrescu 
314f31c80f8SCristian Dumitrescu 	if (parser_read_uint32(&p.tx.n_queues, tokens[7]) != 0) {
3155074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "n_queues");
3165074e1d5SCristian Dumitrescu 		return;
3175074e1d5SCristian Dumitrescu 	}
3185074e1d5SCristian Dumitrescu 
319f31c80f8SCristian Dumitrescu 	if (parser_read_uint32(&p.tx.queue_size, tokens[8]) != 0) {
3205074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "queue_size");
3215074e1d5SCristian Dumitrescu 		return;
3225074e1d5SCristian Dumitrescu 	}
3235074e1d5SCristian Dumitrescu 
324f31c80f8SCristian Dumitrescu 	if (strcmp(tokens[9], "promiscuous") != 0) {
3255074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "promiscuous");
3265074e1d5SCristian Dumitrescu 		return;
3275074e1d5SCristian Dumitrescu 	}
3285074e1d5SCristian Dumitrescu 
329f31c80f8SCristian Dumitrescu 	if (strcmp(tokens[10], "on") == 0)
3305074e1d5SCristian Dumitrescu 		p.promiscuous = 1;
331f31c80f8SCristian Dumitrescu 	else if (strcmp(tokens[10], "off") == 0)
3325074e1d5SCristian Dumitrescu 		p.promiscuous = 0;
3335074e1d5SCristian Dumitrescu 	else {
3345074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "on or off");
3355074e1d5SCristian Dumitrescu 		return;
3365074e1d5SCristian Dumitrescu 	}
3375074e1d5SCristian Dumitrescu 
3385074e1d5SCristian Dumitrescu 	/* RSS */
3395074e1d5SCristian Dumitrescu 	p.rx.rss = NULL;
340f31c80f8SCristian Dumitrescu 	if (n_tokens > 11) {
3415074e1d5SCristian Dumitrescu 		uint32_t queue_id, i;
3425074e1d5SCristian Dumitrescu 
343f31c80f8SCristian Dumitrescu 		if (strcmp(tokens[11], "rss") != 0) {
3445074e1d5SCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rss");
3455074e1d5SCristian Dumitrescu 			return;
3465074e1d5SCristian Dumitrescu 		}
3475074e1d5SCristian Dumitrescu 
3485074e1d5SCristian Dumitrescu 		p.rx.rss = &rss;
3495074e1d5SCristian Dumitrescu 
3505074e1d5SCristian Dumitrescu 		rss.n_queues = 0;
351f31c80f8SCristian Dumitrescu 		for (i = 12; i < n_tokens; i++) {
3525074e1d5SCristian Dumitrescu 			if (parser_read_uint32(&queue_id, tokens[i]) != 0) {
3535074e1d5SCristian Dumitrescu 				snprintf(out, out_size, MSG_ARG_INVALID,
3545074e1d5SCristian Dumitrescu 					"queue_id");
3555074e1d5SCristian Dumitrescu 				return;
3565074e1d5SCristian Dumitrescu 			}
3575074e1d5SCristian Dumitrescu 
3585074e1d5SCristian Dumitrescu 			rss.queue_id[rss.n_queues] = queue_id;
3595074e1d5SCristian Dumitrescu 			rss.n_queues++;
3605074e1d5SCristian Dumitrescu 		}
3615074e1d5SCristian Dumitrescu 	}
3625074e1d5SCristian Dumitrescu 
3635074e1d5SCristian Dumitrescu 	link = link_create(obj, name, &p);
3645074e1d5SCristian Dumitrescu 	if (link == NULL) {
3655074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
3665074e1d5SCristian Dumitrescu 		return;
3675074e1d5SCristian Dumitrescu 	}
3685074e1d5SCristian Dumitrescu }
3695074e1d5SCristian Dumitrescu 
3705074e1d5SCristian Dumitrescu /* Print the link stats and info */
3715074e1d5SCristian Dumitrescu static void
3725074e1d5SCristian Dumitrescu print_link_info(struct link *link, char *out, size_t out_size)
3735074e1d5SCristian Dumitrescu {
3745074e1d5SCristian Dumitrescu 	struct rte_eth_stats stats;
3755074e1d5SCristian Dumitrescu 	struct rte_ether_addr mac_addr;
3765074e1d5SCristian Dumitrescu 	struct rte_eth_link eth_link;
3775074e1d5SCristian Dumitrescu 	uint16_t mtu;
3785074e1d5SCristian Dumitrescu 	int ret;
3795074e1d5SCristian Dumitrescu 
3805074e1d5SCristian Dumitrescu 	memset(&stats, 0, sizeof(stats));
3815074e1d5SCristian Dumitrescu 	rte_eth_stats_get(link->port_id, &stats);
3825074e1d5SCristian Dumitrescu 
3835074e1d5SCristian Dumitrescu 	ret = rte_eth_macaddr_get(link->port_id, &mac_addr);
3845074e1d5SCristian Dumitrescu 	if (ret != 0) {
3855074e1d5SCristian Dumitrescu 		snprintf(out, out_size, "\n%s: MAC address get failed: %s",
3865074e1d5SCristian Dumitrescu 			 link->name, rte_strerror(-ret));
3875074e1d5SCristian Dumitrescu 		return;
3885074e1d5SCristian Dumitrescu 	}
3895074e1d5SCristian Dumitrescu 
3905074e1d5SCristian Dumitrescu 	ret = rte_eth_link_get(link->port_id, &eth_link);
3915074e1d5SCristian Dumitrescu 	if (ret < 0) {
3925074e1d5SCristian Dumitrescu 		snprintf(out, out_size, "\n%s: link get failed: %s",
3935074e1d5SCristian Dumitrescu 			 link->name, rte_strerror(-ret));
3945074e1d5SCristian Dumitrescu 		return;
3955074e1d5SCristian Dumitrescu 	}
3965074e1d5SCristian Dumitrescu 
3975074e1d5SCristian Dumitrescu 	rte_eth_dev_get_mtu(link->port_id, &mtu);
3985074e1d5SCristian Dumitrescu 
3995074e1d5SCristian Dumitrescu 	snprintf(out, out_size,
4005074e1d5SCristian Dumitrescu 		"\n"
4015074e1d5SCristian Dumitrescu 		"%s: flags=<%s> mtu %u\n"
402c2c4f87bSAman Deep Singh 		"\tether " RTE_ETHER_ADDR_PRT_FMT " rxqueues %u txqueues %u\n"
4035074e1d5SCristian Dumitrescu 		"\tport# %u  speed %s\n"
4045074e1d5SCristian Dumitrescu 		"\tRX packets %" PRIu64"  bytes %" PRIu64"\n"
4055074e1d5SCristian Dumitrescu 		"\tRX errors %" PRIu64"  missed %" PRIu64"  no-mbuf %" PRIu64"\n"
4065074e1d5SCristian Dumitrescu 		"\tTX packets %" PRIu64"  bytes %" PRIu64"\n"
4075074e1d5SCristian Dumitrescu 		"\tTX errors %" PRIu64"\n",
4085074e1d5SCristian Dumitrescu 		link->name,
4095074e1d5SCristian Dumitrescu 		eth_link.link_status == 0 ? "DOWN" : "UP",
4105074e1d5SCristian Dumitrescu 		mtu,
411a7db3afcSAman Deep Singh 		RTE_ETHER_ADDR_BYTES(&mac_addr),
4125074e1d5SCristian Dumitrescu 		link->n_rxq,
4135074e1d5SCristian Dumitrescu 		link->n_txq,
4145074e1d5SCristian Dumitrescu 		link->port_id,
4155074e1d5SCristian Dumitrescu 		rte_eth_link_speed_to_str(eth_link.link_speed),
4165074e1d5SCristian Dumitrescu 		stats.ipackets,
4175074e1d5SCristian Dumitrescu 		stats.ibytes,
4185074e1d5SCristian Dumitrescu 		stats.ierrors,
4195074e1d5SCristian Dumitrescu 		stats.imissed,
4205074e1d5SCristian Dumitrescu 		stats.rx_nombuf,
4215074e1d5SCristian Dumitrescu 		stats.opackets,
4225074e1d5SCristian Dumitrescu 		stats.obytes,
4235074e1d5SCristian Dumitrescu 		stats.oerrors);
4245074e1d5SCristian Dumitrescu }
4255074e1d5SCristian Dumitrescu 
4265074e1d5SCristian Dumitrescu /*
427f31c80f8SCristian Dumitrescu  * ethdev show [<ethdev_name>]
4285074e1d5SCristian Dumitrescu  */
4295074e1d5SCristian Dumitrescu static void
430f31c80f8SCristian Dumitrescu cmd_ethdev_show(char **tokens,
4315074e1d5SCristian Dumitrescu 	      uint32_t n_tokens,
4325074e1d5SCristian Dumitrescu 	      char *out,
4335074e1d5SCristian Dumitrescu 	      size_t out_size,
4345074e1d5SCristian Dumitrescu 	      void *obj)
4355074e1d5SCristian Dumitrescu {
4365074e1d5SCristian Dumitrescu 	struct link *link;
4375074e1d5SCristian Dumitrescu 	char *link_name;
4385074e1d5SCristian Dumitrescu 
4395074e1d5SCristian Dumitrescu 	if (n_tokens != 2 && n_tokens != 3) {
4405074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
4415074e1d5SCristian Dumitrescu 		return;
4425074e1d5SCristian Dumitrescu 	}
4435074e1d5SCristian Dumitrescu 
4445074e1d5SCristian Dumitrescu 	if (n_tokens == 2) {
4455074e1d5SCristian Dumitrescu 		link = link_next(obj, NULL);
4465074e1d5SCristian Dumitrescu 
4475074e1d5SCristian Dumitrescu 		while (link != NULL) {
4485074e1d5SCristian Dumitrescu 			out_size = out_size - strlen(out);
4495074e1d5SCristian Dumitrescu 			out = &out[strlen(out)];
4505074e1d5SCristian Dumitrescu 
4515074e1d5SCristian Dumitrescu 			print_link_info(link, out, out_size);
4525074e1d5SCristian Dumitrescu 			link = link_next(obj, link);
4535074e1d5SCristian Dumitrescu 		}
4545074e1d5SCristian Dumitrescu 	} else {
4555074e1d5SCristian Dumitrescu 		out_size = out_size - strlen(out);
4565074e1d5SCristian Dumitrescu 		out = &out[strlen(out)];
4575074e1d5SCristian Dumitrescu 
4585074e1d5SCristian Dumitrescu 		link_name = tokens[2];
4595074e1d5SCristian Dumitrescu 		link = link_find(obj, link_name);
4605074e1d5SCristian Dumitrescu 
4615074e1d5SCristian Dumitrescu 		if (link == NULL) {
4625074e1d5SCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_INVALID,
4635074e1d5SCristian Dumitrescu 					"Link does not exist");
4645074e1d5SCristian Dumitrescu 			return;
4655074e1d5SCristian Dumitrescu 		}
4665074e1d5SCristian Dumitrescu 		print_link_info(link, out, out_size);
4675074e1d5SCristian Dumitrescu 	}
4685074e1d5SCristian Dumitrescu }
4695074e1d5SCristian Dumitrescu 
47077a41301SCristian Dumitrescu static const char cmd_ring_help[] =
47177a41301SCristian Dumitrescu "ring <ring_name> size <size> numa <numa_node>\n";
47277a41301SCristian Dumitrescu 
47377a41301SCristian Dumitrescu static void
47477a41301SCristian Dumitrescu cmd_ring(char **tokens,
47577a41301SCristian Dumitrescu 	uint32_t n_tokens,
47677a41301SCristian Dumitrescu 	char *out,
47777a41301SCristian Dumitrescu 	size_t out_size,
47877a41301SCristian Dumitrescu 	void *obj)
47977a41301SCristian Dumitrescu {
48077a41301SCristian Dumitrescu 	struct ring_params p;
48177a41301SCristian Dumitrescu 	char *name;
48277a41301SCristian Dumitrescu 	struct ring *ring;
48377a41301SCristian Dumitrescu 
48477a41301SCristian Dumitrescu 	if (n_tokens != 6) {
48577a41301SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
48677a41301SCristian Dumitrescu 		return;
48777a41301SCristian Dumitrescu 	}
48877a41301SCristian Dumitrescu 
48977a41301SCristian Dumitrescu 	name = tokens[1];
49077a41301SCristian Dumitrescu 
49177a41301SCristian Dumitrescu 	if (strcmp(tokens[2], "size") != 0) {
49277a41301SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "size");
49377a41301SCristian Dumitrescu 		return;
49477a41301SCristian Dumitrescu 	}
49577a41301SCristian Dumitrescu 
49677a41301SCristian Dumitrescu 	if (parser_read_uint32(&p.size, tokens[3]) != 0) {
49777a41301SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "size");
49877a41301SCristian Dumitrescu 		return;
49977a41301SCristian Dumitrescu 	}
50077a41301SCristian Dumitrescu 
50177a41301SCristian Dumitrescu 	if (strcmp(tokens[4], "numa") != 0) {
50277a41301SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "numa");
50377a41301SCristian Dumitrescu 		return;
50477a41301SCristian Dumitrescu 	}
50577a41301SCristian Dumitrescu 
50677a41301SCristian Dumitrescu 	if (parser_read_uint32(&p.numa_node, tokens[5]) != 0) {
50777a41301SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "numa_node");
50877a41301SCristian Dumitrescu 		return;
50977a41301SCristian Dumitrescu 	}
51077a41301SCristian Dumitrescu 
51177a41301SCristian Dumitrescu 	ring = ring_create(obj, name, &p);
51277a41301SCristian Dumitrescu 	if (!ring) {
51377a41301SCristian Dumitrescu 		snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
51477a41301SCristian Dumitrescu 		return;
51577a41301SCristian Dumitrescu 	}
51677a41301SCristian Dumitrescu }
51777a41301SCristian Dumitrescu 
5189043f66aSCristian Dumitrescu static const char cmd_pipeline_codegen_help[] =
5199043f66aSCristian Dumitrescu "pipeline codegen <spec_file> <code_file>\n";
5209043f66aSCristian Dumitrescu 
5219043f66aSCristian Dumitrescu static void
5229043f66aSCristian Dumitrescu cmd_pipeline_codegen(char **tokens,
5239043f66aSCristian Dumitrescu 	uint32_t n_tokens,
5249043f66aSCristian Dumitrescu 	char *out,
5259043f66aSCristian Dumitrescu 	size_t out_size,
5269043f66aSCristian Dumitrescu 	void *obj __rte_unused)
5279043f66aSCristian Dumitrescu {
5289043f66aSCristian Dumitrescu 	FILE *spec_file = NULL;
5299043f66aSCristian Dumitrescu 	FILE *code_file = NULL;
5309043f66aSCristian Dumitrescu 	uint32_t err_line;
5319043f66aSCristian Dumitrescu 	const char *err_msg;
5329043f66aSCristian Dumitrescu 	int status;
5339043f66aSCristian Dumitrescu 
5349043f66aSCristian Dumitrescu 	if (n_tokens != 4) {
5359043f66aSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
5369043f66aSCristian Dumitrescu 		return;
5379043f66aSCristian Dumitrescu 	}
5389043f66aSCristian Dumitrescu 
5399043f66aSCristian Dumitrescu 	spec_file = fopen(tokens[2], "r");
5409043f66aSCristian Dumitrescu 	if (!spec_file) {
5419043f66aSCristian Dumitrescu 		snprintf(out, out_size, "Cannot open file %s.\n", tokens[2]);
5429043f66aSCristian Dumitrescu 		return;
5439043f66aSCristian Dumitrescu 	}
5449043f66aSCristian Dumitrescu 
5459043f66aSCristian Dumitrescu 	code_file = fopen(tokens[3], "w");
5469043f66aSCristian Dumitrescu 	if (!code_file) {
5479043f66aSCristian Dumitrescu 		snprintf(out, out_size, "Cannot open file %s.\n", tokens[3]);
548*ab492f94SHarshad Narayane 		fclose(spec_file);
5499043f66aSCristian Dumitrescu 		return;
5509043f66aSCristian Dumitrescu 	}
5519043f66aSCristian Dumitrescu 
5529043f66aSCristian Dumitrescu 	status = rte_swx_pipeline_codegen(spec_file,
5539043f66aSCristian Dumitrescu 					  code_file,
5549043f66aSCristian Dumitrescu 					  &err_line,
5559043f66aSCristian Dumitrescu 					  &err_msg);
5569043f66aSCristian Dumitrescu 
5579043f66aSCristian Dumitrescu 	fclose(spec_file);
5589043f66aSCristian Dumitrescu 	fclose(code_file);
5599043f66aSCristian Dumitrescu 
5609043f66aSCristian Dumitrescu 	if (status) {
5619043f66aSCristian Dumitrescu 		snprintf(out, out_size, "Error %d at line %u: %s\n.",
5629043f66aSCristian Dumitrescu 			status, err_line, err_msg);
5639043f66aSCristian Dumitrescu 		return;
5649043f66aSCristian Dumitrescu 	}
5659043f66aSCristian Dumitrescu }
5666bc14d9fSCristian Dumitrescu 
5676bc14d9fSCristian Dumitrescu static const char cmd_pipeline_libbuild_help[] =
5686bc14d9fSCristian Dumitrescu "pipeline libbuild <code_file> <lib_file>\n";
5696bc14d9fSCristian Dumitrescu 
5706bc14d9fSCristian Dumitrescu static void
5716bc14d9fSCristian Dumitrescu cmd_pipeline_libbuild(char **tokens,
5726bc14d9fSCristian Dumitrescu 	uint32_t n_tokens,
5736bc14d9fSCristian Dumitrescu 	char *out,
5746bc14d9fSCristian Dumitrescu 	size_t out_size,
5756bc14d9fSCristian Dumitrescu 	void *obj __rte_unused)
5766bc14d9fSCristian Dumitrescu {
5776bc14d9fSCristian Dumitrescu 	char *code_file, *lib_file, *obj_file = NULL, *log_file = NULL;
5786bc14d9fSCristian Dumitrescu 	char *install_dir, *cwd = NULL, *buffer = NULL;
5796bc14d9fSCristian Dumitrescu 	size_t length;
5806bc14d9fSCristian Dumitrescu 	int status = 0;
5816bc14d9fSCristian Dumitrescu 
5826bc14d9fSCristian Dumitrescu 	if (n_tokens != 4) {
5836bc14d9fSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
5846bc14d9fSCristian Dumitrescu 		goto free;
5856bc14d9fSCristian Dumitrescu 	}
5866bc14d9fSCristian Dumitrescu 
5876bc14d9fSCristian Dumitrescu 	install_dir = getenv("RTE_INSTALL_DIR");
5886bc14d9fSCristian Dumitrescu 	if (!install_dir) {
5896bc14d9fSCristian Dumitrescu 		cwd = malloc(MAX_LINE_SIZE);
5906bc14d9fSCristian Dumitrescu 		if (!cwd) {
5916bc14d9fSCristian Dumitrescu 			snprintf(out, out_size, MSG_OUT_OF_MEMORY);
5926bc14d9fSCristian Dumitrescu 			goto free;
5936bc14d9fSCristian Dumitrescu 		}
5946bc14d9fSCristian Dumitrescu 
5956bc14d9fSCristian Dumitrescu 		install_dir = getcwd(cwd, MAX_LINE_SIZE);
5966bc14d9fSCristian Dumitrescu 		if (!install_dir) {
5976bc14d9fSCristian Dumitrescu 			snprintf(out, out_size, "Error: Path too long.\n");
5986bc14d9fSCristian Dumitrescu 			goto free;
5996bc14d9fSCristian Dumitrescu 		}
6006bc14d9fSCristian Dumitrescu 	}
6016bc14d9fSCristian Dumitrescu 
6026bc14d9fSCristian Dumitrescu 	snprintf(out, out_size, "Using DPDK source code from \"%s\".\n", install_dir);
6036bc14d9fSCristian Dumitrescu 	out_size -= strlen(out);
6046bc14d9fSCristian Dumitrescu 	out += strlen(out);
6056bc14d9fSCristian Dumitrescu 
6066bc14d9fSCristian Dumitrescu 	code_file = tokens[2];
6076bc14d9fSCristian Dumitrescu 	length = strnlen(code_file, MAX_LINE_SIZE);
6086bc14d9fSCristian Dumitrescu 	if ((length < 3) ||
6096bc14d9fSCristian Dumitrescu 	    (code_file[length - 2] != '.') ||
6106bc14d9fSCristian Dumitrescu 	    (code_file[length - 1] != 'c')) {
6116bc14d9fSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "code_file");
6126bc14d9fSCristian Dumitrescu 		goto free;
6136bc14d9fSCristian Dumitrescu 	}
6146bc14d9fSCristian Dumitrescu 
6156bc14d9fSCristian Dumitrescu 	lib_file = tokens[3];
6166bc14d9fSCristian Dumitrescu 	length = strnlen(lib_file, MAX_LINE_SIZE);
6176bc14d9fSCristian Dumitrescu 	if ((length < 4) ||
6186bc14d9fSCristian Dumitrescu 	    (lib_file[length - 3] != '.') ||
6196bc14d9fSCristian Dumitrescu 	    (lib_file[length - 2] != 's') ||
6206bc14d9fSCristian Dumitrescu 	    (lib_file[length - 1] != 'o')) {
6216bc14d9fSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "lib_file");
6226bc14d9fSCristian Dumitrescu 		goto free;
6236bc14d9fSCristian Dumitrescu 	}
6246bc14d9fSCristian Dumitrescu 
6256bc14d9fSCristian Dumitrescu 	obj_file = malloc(length);
6266bc14d9fSCristian Dumitrescu 	log_file = malloc(length + 2);
6276bc14d9fSCristian Dumitrescu 	if (!obj_file || !log_file) {
6286bc14d9fSCristian Dumitrescu 		snprintf(out, out_size, MSG_OUT_OF_MEMORY);
6296bc14d9fSCristian Dumitrescu 		goto free;
6306bc14d9fSCristian Dumitrescu 	}
6316bc14d9fSCristian Dumitrescu 
6326bc14d9fSCristian Dumitrescu 	memcpy(obj_file, lib_file, length - 2);
6336bc14d9fSCristian Dumitrescu 	obj_file[length - 2] = 'o';
6346bc14d9fSCristian Dumitrescu 	obj_file[length - 1] = 0;
6356bc14d9fSCristian Dumitrescu 
6366bc14d9fSCristian Dumitrescu 	memcpy(log_file, lib_file, length - 2);
6376bc14d9fSCristian Dumitrescu 	log_file[length - 2] = 'l';
6386bc14d9fSCristian Dumitrescu 	log_file[length - 1] = 'o';
6396bc14d9fSCristian Dumitrescu 	log_file[length] = 'g';
6406bc14d9fSCristian Dumitrescu 	log_file[length + 1] = 0;
6416bc14d9fSCristian Dumitrescu 
6426bc14d9fSCristian Dumitrescu 	buffer = malloc(MAX_LINE_SIZE);
6436bc14d9fSCristian Dumitrescu 	if (!buffer) {
6446bc14d9fSCristian Dumitrescu 		snprintf(out, out_size, MSG_OUT_OF_MEMORY);
645b42f3e2fSHarshad Narayane 		goto free;
6466bc14d9fSCristian Dumitrescu 	}
6476bc14d9fSCristian Dumitrescu 
6486bc14d9fSCristian Dumitrescu 	snprintf(buffer,
6496bc14d9fSCristian Dumitrescu 		 MAX_LINE_SIZE,
6506bc14d9fSCristian Dumitrescu 		 "gcc -c -O3 -fpic -Wno-deprecated-declarations -o %s %s "
6516bc14d9fSCristian Dumitrescu 		 "-I %s/lib/pipeline "
6526bc14d9fSCristian Dumitrescu 		 "-I %s/lib/eal/include "
6536bc14d9fSCristian Dumitrescu 		 "-I %s/lib/eal/x86/include "
6546bc14d9fSCristian Dumitrescu 		 "-I %s/lib/eal/include/generic "
6556bc14d9fSCristian Dumitrescu 		 "-I %s/lib/meter "
6566bc14d9fSCristian Dumitrescu 		 "-I %s/lib/port "
6576bc14d9fSCristian Dumitrescu 		 "-I %s/lib/table "
6586bc14d9fSCristian Dumitrescu 		 "-I %s/lib/pipeline "
6596bc14d9fSCristian Dumitrescu 		 "-I %s/config "
6606bc14d9fSCristian Dumitrescu 		 "-I %s/build "
6616bc14d9fSCristian Dumitrescu 		 "-I %s/lib/eal/linux/include "
6626bc14d9fSCristian Dumitrescu 		 ">%s 2>&1 "
6636bc14d9fSCristian Dumitrescu 		 "&& "
6646bc14d9fSCristian Dumitrescu 		 "gcc -shared %s -o %s "
6656bc14d9fSCristian Dumitrescu 		 ">>%s 2>&1",
6666bc14d9fSCristian Dumitrescu 		 obj_file,
6676bc14d9fSCristian Dumitrescu 		 code_file,
6686bc14d9fSCristian Dumitrescu 		 install_dir,
6696bc14d9fSCristian Dumitrescu 		 install_dir,
6706bc14d9fSCristian Dumitrescu 		 install_dir,
6716bc14d9fSCristian Dumitrescu 		 install_dir,
6726bc14d9fSCristian Dumitrescu 		 install_dir,
6736bc14d9fSCristian Dumitrescu 		 install_dir,
6746bc14d9fSCristian Dumitrescu 		 install_dir,
6756bc14d9fSCristian Dumitrescu 		 install_dir,
6766bc14d9fSCristian Dumitrescu 		 install_dir,
6776bc14d9fSCristian Dumitrescu 		 install_dir,
6786bc14d9fSCristian Dumitrescu 		 install_dir,
6796bc14d9fSCristian Dumitrescu 		 log_file,
6806bc14d9fSCristian Dumitrescu 		 obj_file,
6816bc14d9fSCristian Dumitrescu 		 lib_file,
6826bc14d9fSCristian Dumitrescu 		 log_file);
6836bc14d9fSCristian Dumitrescu 
6846bc14d9fSCristian Dumitrescu 	status = system(buffer);
6856bc14d9fSCristian Dumitrescu 	if (status) {
6866bc14d9fSCristian Dumitrescu 		snprintf(out,
6876bc14d9fSCristian Dumitrescu 			 out_size,
6886bc14d9fSCristian Dumitrescu 			 "Library build failed, see file \"%s\" for details.\n",
6896bc14d9fSCristian Dumitrescu 			 log_file);
6906bc14d9fSCristian Dumitrescu 		goto free;
6916bc14d9fSCristian Dumitrescu 	}
6926bc14d9fSCristian Dumitrescu 
6936bc14d9fSCristian Dumitrescu free:
6946bc14d9fSCristian Dumitrescu 	free(cwd);
6956bc14d9fSCristian Dumitrescu 	free(obj_file);
6966bc14d9fSCristian Dumitrescu 	free(log_file);
6976bc14d9fSCristian Dumitrescu 	free(buffer);
6986bc14d9fSCristian Dumitrescu }
6996bc14d9fSCristian Dumitrescu 
7005074e1d5SCristian Dumitrescu static const char cmd_pipeline_build_help[] =
70168b95704SCristian Dumitrescu "pipeline <pipeline_name> build lib <lib_file> io <iospec_file> numa <numa_node>\n";
7025074e1d5SCristian Dumitrescu 
7035074e1d5SCristian Dumitrescu static void
7045074e1d5SCristian Dumitrescu cmd_pipeline_build(char **tokens,
7055074e1d5SCristian Dumitrescu 	uint32_t n_tokens,
7065074e1d5SCristian Dumitrescu 	char *out,
7075074e1d5SCristian Dumitrescu 	size_t out_size,
70868b95704SCristian Dumitrescu 	void *obj __rte_unused)
7095074e1d5SCristian Dumitrescu {
71068b95704SCristian Dumitrescu 	struct rte_swx_pipeline *p = NULL;
71168b95704SCristian Dumitrescu 	struct rte_swx_ctl_pipeline *ctl = NULL;
71268b95704SCristian Dumitrescu 	char *pipeline_name, *lib_file_name, *iospec_file_name;
71368b95704SCristian Dumitrescu 	FILE *iospec_file = NULL;
71468b95704SCristian Dumitrescu 	uint32_t numa_node = 0;
71568b95704SCristian Dumitrescu 	int status = 0;
7165074e1d5SCristian Dumitrescu 
71768b95704SCristian Dumitrescu 	/* Parsing. */
71868b95704SCristian Dumitrescu 	if (n_tokens != 9) {
7195074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
7205074e1d5SCristian Dumitrescu 		return;
7215074e1d5SCristian Dumitrescu 	}
7225074e1d5SCristian Dumitrescu 
72368b95704SCristian Dumitrescu 	pipeline_name = tokens[1];
72468b95704SCristian Dumitrescu 
72568b95704SCristian Dumitrescu 	if (strcmp(tokens[2], "build")) {
72668b95704SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "build");
7275074e1d5SCristian Dumitrescu 		return;
7285074e1d5SCristian Dumitrescu 	}
7295074e1d5SCristian Dumitrescu 
73068b95704SCristian Dumitrescu 	if (strcmp(tokens[3], "lib")) {
73168b95704SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "lib");
7325074e1d5SCristian Dumitrescu 		return;
7335074e1d5SCristian Dumitrescu 	}
7345074e1d5SCristian Dumitrescu 
73568b95704SCristian Dumitrescu 	lib_file_name = tokens[4];
73668b95704SCristian Dumitrescu 
73768b95704SCristian Dumitrescu 	if (strcmp(tokens[5], "io")) {
73868b95704SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "io");
73968b95704SCristian Dumitrescu 		return;
74068b95704SCristian Dumitrescu 	}
74168b95704SCristian Dumitrescu 
74268b95704SCristian Dumitrescu 	iospec_file_name = tokens[6];
74368b95704SCristian Dumitrescu 
74468b95704SCristian Dumitrescu 	if (strcmp(tokens[7], "numa")) {
74568b95704SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "numa");
74668b95704SCristian Dumitrescu 		return;
74768b95704SCristian Dumitrescu 	}
74868b95704SCristian Dumitrescu 
74968b95704SCristian Dumitrescu 	if (parser_read_uint32(&numa_node, tokens[8])) {
75068b95704SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "numa_node");
75168b95704SCristian Dumitrescu 		return;
75268b95704SCristian Dumitrescu 	}
75368b95704SCristian Dumitrescu 
75468b95704SCristian Dumitrescu 	/* I/O spec file open. */
75568b95704SCristian Dumitrescu 	iospec_file = fopen(iospec_file_name, "r");
75668b95704SCristian Dumitrescu 	if (!iospec_file) {
75768b95704SCristian Dumitrescu 		snprintf(out, out_size, "Cannot open file \"%s\".\n", iospec_file_name);
75868b95704SCristian Dumitrescu 		return;
75968b95704SCristian Dumitrescu 	}
76068b95704SCristian Dumitrescu 
76168b95704SCristian Dumitrescu 	status = rte_swx_pipeline_build_from_lib(&p,
76268b95704SCristian Dumitrescu 						 pipeline_name,
76368b95704SCristian Dumitrescu 						 lib_file_name,
76468b95704SCristian Dumitrescu 						 iospec_file,
76568b95704SCristian Dumitrescu 						 (int)numa_node);
7665074e1d5SCristian Dumitrescu 	if (status) {
76768b95704SCristian Dumitrescu 		snprintf(out, out_size, "Pipeline build failed (%d).", status);
76868b95704SCristian Dumitrescu 		goto free;
7695074e1d5SCristian Dumitrescu 	}
7705074e1d5SCristian Dumitrescu 
77168b95704SCristian Dumitrescu 	ctl = rte_swx_ctl_pipeline_create(p);
77268b95704SCristian Dumitrescu 	if (!ctl) {
7735074e1d5SCristian Dumitrescu 		snprintf(out, out_size, "Pipeline control create failed.");
77468b95704SCristian Dumitrescu 		goto free;
7755074e1d5SCristian Dumitrescu 	}
77668b95704SCristian Dumitrescu 
77768b95704SCristian Dumitrescu free:
77868b95704SCristian Dumitrescu 	if (status)
77968b95704SCristian Dumitrescu 		rte_swx_pipeline_free(p);
78068b95704SCristian Dumitrescu 
78168b95704SCristian Dumitrescu 	if (iospec_file)
78268b95704SCristian Dumitrescu 		fclose(iospec_file);
7835074e1d5SCristian Dumitrescu }
7845074e1d5SCristian Dumitrescu 
78575129cebSChurchill Khangar static int
78675129cebSChurchill Khangar pipeline_table_entries_add(struct rte_swx_ctl_pipeline *p,
78775129cebSChurchill Khangar 			   const char *table_name,
78875129cebSChurchill Khangar 			   FILE *file,
78975129cebSChurchill Khangar 			   uint32_t *file_line_number)
79075129cebSChurchill Khangar {
79175129cebSChurchill Khangar 	char *line = NULL;
79275129cebSChurchill Khangar 	uint32_t line_id = 0;
79375129cebSChurchill Khangar 	int status = 0;
79475129cebSChurchill Khangar 
79575129cebSChurchill Khangar 	/* Buffer allocation. */
79675129cebSChurchill Khangar 	line = malloc(MAX_LINE_SIZE);
79775129cebSChurchill Khangar 	if (!line)
79875129cebSChurchill Khangar 		return -ENOMEM;
79975129cebSChurchill Khangar 
80075129cebSChurchill Khangar 	/* File read. */
80175129cebSChurchill Khangar 	for (line_id = 1; ; line_id++) {
80275129cebSChurchill Khangar 		struct rte_swx_table_entry *entry;
80375129cebSChurchill Khangar 		int is_blank_or_comment;
80475129cebSChurchill Khangar 
80575129cebSChurchill Khangar 		if (fgets(line, MAX_LINE_SIZE, file) == NULL)
80675129cebSChurchill Khangar 			break;
80775129cebSChurchill Khangar 
80875129cebSChurchill Khangar 		entry = rte_swx_ctl_pipeline_table_entry_read(p,
80975129cebSChurchill Khangar 							      table_name,
81075129cebSChurchill Khangar 							      line,
81175129cebSChurchill Khangar 							      &is_blank_or_comment);
81275129cebSChurchill Khangar 		if (!entry) {
81375129cebSChurchill Khangar 			if (is_blank_or_comment)
81475129cebSChurchill Khangar 				continue;
81575129cebSChurchill Khangar 
81675129cebSChurchill Khangar 			status = -EINVAL;
81775129cebSChurchill Khangar 			goto error;
81875129cebSChurchill Khangar 		}
81975129cebSChurchill Khangar 
82075129cebSChurchill Khangar 		status = rte_swx_ctl_pipeline_table_entry_add(p,
82175129cebSChurchill Khangar 							      table_name,
82275129cebSChurchill Khangar 							      entry);
82375129cebSChurchill Khangar 		table_entry_free(entry);
82475129cebSChurchill Khangar 		if (status)
82575129cebSChurchill Khangar 			goto error;
82675129cebSChurchill Khangar 	}
82775129cebSChurchill Khangar 
82875129cebSChurchill Khangar error:
82975129cebSChurchill Khangar 	free(line);
83075129cebSChurchill Khangar 	*file_line_number = line_id;
83175129cebSChurchill Khangar 	return status;
83275129cebSChurchill Khangar }
83375129cebSChurchill Khangar 
83475129cebSChurchill Khangar static const char cmd_pipeline_table_add_help[] =
83575129cebSChurchill Khangar "pipeline <pipeline_name> table <table_name> add <file_name>\n";
8365074e1d5SCristian Dumitrescu 
8375074e1d5SCristian Dumitrescu static void
83875129cebSChurchill Khangar cmd_pipeline_table_add(char **tokens,
8395074e1d5SCristian Dumitrescu 		       uint32_t n_tokens,
8405074e1d5SCristian Dumitrescu 		       char *out,
8415074e1d5SCristian Dumitrescu 		       size_t out_size,
842b9559f94SCristian Dumitrescu 		       void *obj __rte_unused)
8435074e1d5SCristian Dumitrescu {
844b9559f94SCristian Dumitrescu 	struct rte_swx_ctl_pipeline *ctl;
84575129cebSChurchill Khangar 	char *pipeline_name, *table_name, *file_name;
84675129cebSChurchill Khangar 	FILE *file = NULL;
84775129cebSChurchill Khangar 	uint32_t file_line_number = 0;
8485074e1d5SCristian Dumitrescu 	int status;
8495074e1d5SCristian Dumitrescu 
85075129cebSChurchill Khangar 	if (n_tokens != 6) {
8515074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
8525074e1d5SCristian Dumitrescu 		return;
8535074e1d5SCristian Dumitrescu 	}
8545074e1d5SCristian Dumitrescu 
8555074e1d5SCristian Dumitrescu 	pipeline_name = tokens[1];
856b9559f94SCristian Dumitrescu 	ctl = rte_swx_ctl_pipeline_find(pipeline_name);
857b9559f94SCristian Dumitrescu 	if (!ctl) {
8585074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
8595074e1d5SCristian Dumitrescu 		return;
8605074e1d5SCristian Dumitrescu 	}
8615074e1d5SCristian Dumitrescu 
86275129cebSChurchill Khangar 	table_name = tokens[3];
86375129cebSChurchill Khangar 
86475129cebSChurchill Khangar 	file_name = tokens[5];
86575129cebSChurchill Khangar 	file = fopen(file_name, "r");
86675129cebSChurchill Khangar 	if (!file) {
86775129cebSChurchill Khangar 		snprintf(out, out_size, "Cannot open file %s.\n", file_name);
86875129cebSChurchill Khangar 		return;
86975129cebSChurchill Khangar 	}
87075129cebSChurchill Khangar 
871b9559f94SCristian Dumitrescu 	status = pipeline_table_entries_add(ctl,
87275129cebSChurchill Khangar 					    table_name,
87375129cebSChurchill Khangar 					    file,
87475129cebSChurchill Khangar 					    &file_line_number);
87575129cebSChurchill Khangar 	if (status)
87675129cebSChurchill Khangar 		snprintf(out, out_size, "Invalid entry in file %s at line %u\n",
87775129cebSChurchill Khangar 			 file_name,
87875129cebSChurchill Khangar 			 file_line_number);
87975129cebSChurchill Khangar 
88075129cebSChurchill Khangar 	fclose(file);
88175129cebSChurchill Khangar }
88275129cebSChurchill Khangar 
88375129cebSChurchill Khangar static int
88475129cebSChurchill Khangar pipeline_table_entries_delete(struct rte_swx_ctl_pipeline *p,
88575129cebSChurchill Khangar 			      const char *table_name,
88675129cebSChurchill Khangar 			      FILE *file,
88775129cebSChurchill Khangar 			      uint32_t *file_line_number)
88875129cebSChurchill Khangar {
88975129cebSChurchill Khangar 	char *line = NULL;
89075129cebSChurchill Khangar 	uint32_t line_id = 0;
89175129cebSChurchill Khangar 	int status = 0;
89275129cebSChurchill Khangar 
89375129cebSChurchill Khangar 	/* Buffer allocation. */
89475129cebSChurchill Khangar 	line = malloc(MAX_LINE_SIZE);
89575129cebSChurchill Khangar 	if (!line)
89675129cebSChurchill Khangar 		return -ENOMEM;
89775129cebSChurchill Khangar 
89875129cebSChurchill Khangar 	/* File read. */
89975129cebSChurchill Khangar 	for (line_id = 1; ; line_id++) {
90075129cebSChurchill Khangar 		struct rte_swx_table_entry *entry;
90175129cebSChurchill Khangar 		int is_blank_or_comment;
90275129cebSChurchill Khangar 
90375129cebSChurchill Khangar 		if (fgets(line, MAX_LINE_SIZE, file) == NULL)
90475129cebSChurchill Khangar 			break;
90575129cebSChurchill Khangar 
90675129cebSChurchill Khangar 		entry = rte_swx_ctl_pipeline_table_entry_read(p,
90775129cebSChurchill Khangar 							      table_name,
90875129cebSChurchill Khangar 							      line,
90975129cebSChurchill Khangar 							      &is_blank_or_comment);
91075129cebSChurchill Khangar 		if (!entry) {
91175129cebSChurchill Khangar 			if (is_blank_or_comment)
91275129cebSChurchill Khangar 				continue;
91375129cebSChurchill Khangar 
91475129cebSChurchill Khangar 			status = -EINVAL;
91575129cebSChurchill Khangar 			goto error;
91675129cebSChurchill Khangar 		}
91775129cebSChurchill Khangar 
91875129cebSChurchill Khangar 		status = rte_swx_ctl_pipeline_table_entry_delete(p,
91975129cebSChurchill Khangar 								 table_name,
92075129cebSChurchill Khangar 								 entry);
92175129cebSChurchill Khangar 		table_entry_free(entry);
92275129cebSChurchill Khangar 		if (status)
92375129cebSChurchill Khangar 			goto error;
92475129cebSChurchill Khangar 	}
92575129cebSChurchill Khangar 
92675129cebSChurchill Khangar error:
92775129cebSChurchill Khangar 	*file_line_number = line_id;
92875129cebSChurchill Khangar 	free(line);
92975129cebSChurchill Khangar 	return status;
93075129cebSChurchill Khangar }
93175129cebSChurchill Khangar 
93275129cebSChurchill Khangar static const char cmd_pipeline_table_delete_help[] =
93375129cebSChurchill Khangar "pipeline <pipeline_name> table <table_name> delete <file_name>\n";
93475129cebSChurchill Khangar 
93575129cebSChurchill Khangar static void
93675129cebSChurchill Khangar cmd_pipeline_table_delete(char **tokens,
93775129cebSChurchill Khangar 			  uint32_t n_tokens,
93875129cebSChurchill Khangar 			  char *out,
93975129cebSChurchill Khangar 			  size_t out_size,
940b9559f94SCristian Dumitrescu 			  void *obj __rte_unused)
94175129cebSChurchill Khangar {
942b9559f94SCristian Dumitrescu 	struct rte_swx_ctl_pipeline *ctl;
94375129cebSChurchill Khangar 	char *pipeline_name, *table_name, *file_name;
94475129cebSChurchill Khangar 	FILE *file = NULL;
94575129cebSChurchill Khangar 	uint32_t file_line_number = 0;
94675129cebSChurchill Khangar 	int status;
94775129cebSChurchill Khangar 
94875129cebSChurchill Khangar 	if (n_tokens != 6) {
94975129cebSChurchill Khangar 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
95075129cebSChurchill Khangar 		return;
95175129cebSChurchill Khangar 	}
95275129cebSChurchill Khangar 
95375129cebSChurchill Khangar 	pipeline_name = tokens[1];
954b9559f94SCristian Dumitrescu 	ctl = rte_swx_ctl_pipeline_find(pipeline_name);
955b9559f94SCristian Dumitrescu 	if (!ctl) {
95675129cebSChurchill Khangar 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
9575074e1d5SCristian Dumitrescu 		return;
9585074e1d5SCristian Dumitrescu 	}
9595074e1d5SCristian Dumitrescu 
9605074e1d5SCristian Dumitrescu 	table_name = tokens[3];
9615074e1d5SCristian Dumitrescu 
96275129cebSChurchill Khangar 	file_name = tokens[5];
96375129cebSChurchill Khangar 	file = fopen(file_name, "r");
96475129cebSChurchill Khangar 	if (!file) {
96575129cebSChurchill Khangar 		snprintf(out, out_size, "Cannot open file %s.\n", file_name);
9665074e1d5SCristian Dumitrescu 		return;
9675074e1d5SCristian Dumitrescu 	}
9685074e1d5SCristian Dumitrescu 
969b9559f94SCristian Dumitrescu 	status = pipeline_table_entries_delete(ctl,
97075129cebSChurchill Khangar 					       table_name,
97175129cebSChurchill Khangar 					       file,
97275129cebSChurchill Khangar 					       &file_line_number);
97375129cebSChurchill Khangar 	if (status)
97475129cebSChurchill Khangar 		snprintf(out, out_size, "Invalid entry in file %s at line %u\n",
97575129cebSChurchill Khangar 			 file_name,
97675129cebSChurchill Khangar 			 file_line_number);
9775074e1d5SCristian Dumitrescu 
97875129cebSChurchill Khangar 	fclose(file);
9795074e1d5SCristian Dumitrescu }
9805074e1d5SCristian Dumitrescu 
98175129cebSChurchill Khangar static int
98275129cebSChurchill Khangar pipeline_table_default_entry_add(struct rte_swx_ctl_pipeline *p,
98375129cebSChurchill Khangar 				 const char *table_name,
98475129cebSChurchill Khangar 				 FILE *file,
98575129cebSChurchill Khangar 				 uint32_t *file_line_number)
98675129cebSChurchill Khangar {
98775129cebSChurchill Khangar 	char *line = NULL;
98875129cebSChurchill Khangar 	uint32_t line_id = 0;
98975129cebSChurchill Khangar 	int status = 0;
9905074e1d5SCristian Dumitrescu 
9915074e1d5SCristian Dumitrescu 	/* Buffer allocation. */
99275129cebSChurchill Khangar 	line = malloc(MAX_LINE_SIZE);
99375129cebSChurchill Khangar 	if (!line)
99475129cebSChurchill Khangar 		return -ENOMEM;
9955074e1d5SCristian Dumitrescu 
99675129cebSChurchill Khangar 	/* File read. */
9975074e1d5SCristian Dumitrescu 	for (line_id = 1; ; line_id++) {
9985074e1d5SCristian Dumitrescu 		struct rte_swx_table_entry *entry;
999cff9a717SCristian Dumitrescu 		int is_blank_or_comment;
10005074e1d5SCristian Dumitrescu 
100175129cebSChurchill Khangar 		if (fgets(line, MAX_LINE_SIZE, file) == NULL)
10025074e1d5SCristian Dumitrescu 			break;
10035074e1d5SCristian Dumitrescu 
100475129cebSChurchill Khangar 		entry = rte_swx_ctl_pipeline_table_entry_read(p,
10055074e1d5SCristian Dumitrescu 							      table_name,
1006cff9a717SCristian Dumitrescu 							      line,
1007cff9a717SCristian Dumitrescu 							      &is_blank_or_comment);
10085074e1d5SCristian Dumitrescu 		if (!entry) {
1009cff9a717SCristian Dumitrescu 			if (is_blank_or_comment)
1010cff9a717SCristian Dumitrescu 				continue;
1011cff9a717SCristian Dumitrescu 
101275129cebSChurchill Khangar 			status = -EINVAL;
10135074e1d5SCristian Dumitrescu 			goto error;
10145074e1d5SCristian Dumitrescu 		}
10155074e1d5SCristian Dumitrescu 
101675129cebSChurchill Khangar 		status = rte_swx_ctl_pipeline_table_default_entry_add(p,
10175074e1d5SCristian Dumitrescu 								      table_name,
10185074e1d5SCristian Dumitrescu 								      entry);
1019275ebefeSCristian Dumitrescu 		table_entry_free(entry);
102075129cebSChurchill Khangar 		if (status)
10215074e1d5SCristian Dumitrescu 			goto error;
10225074e1d5SCristian Dumitrescu 	}
102375129cebSChurchill Khangar 
102475129cebSChurchill Khangar error:
102575129cebSChurchill Khangar 	*file_line_number = line_id;
102675129cebSChurchill Khangar 	free(line);
102775129cebSChurchill Khangar 	return status;
10285074e1d5SCristian Dumitrescu }
10295074e1d5SCristian Dumitrescu 
103075129cebSChurchill Khangar static const char cmd_pipeline_table_default_help[] =
103175129cebSChurchill Khangar "pipeline <pipeline_name> table <table_name> default <file_name>\n";
10325074e1d5SCristian Dumitrescu 
103375129cebSChurchill Khangar static void
103475129cebSChurchill Khangar cmd_pipeline_table_default(char **tokens,
103575129cebSChurchill Khangar 			   uint32_t n_tokens,
103675129cebSChurchill Khangar 			   char *out,
103775129cebSChurchill Khangar 			   size_t out_size,
1038b9559f94SCristian Dumitrescu 			   void *obj __rte_unused)
103975129cebSChurchill Khangar {
1040b9559f94SCristian Dumitrescu 	struct rte_swx_ctl_pipeline *ctl;
104175129cebSChurchill Khangar 	char *pipeline_name, *table_name, *file_name;
104275129cebSChurchill Khangar 	FILE *file = NULL;
104375129cebSChurchill Khangar 	uint32_t file_line_number = 0;
104475129cebSChurchill Khangar 	int status;
10455074e1d5SCristian Dumitrescu 
104675129cebSChurchill Khangar 	if (n_tokens != 6) {
104775129cebSChurchill Khangar 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
104875129cebSChurchill Khangar 		return;
104975129cebSChurchill Khangar 	}
10505074e1d5SCristian Dumitrescu 
105175129cebSChurchill Khangar 	pipeline_name = tokens[1];
1052b9559f94SCristian Dumitrescu 	ctl = rte_swx_ctl_pipeline_find(pipeline_name);
1053b9559f94SCristian Dumitrescu 	if (!ctl) {
105475129cebSChurchill Khangar 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
105575129cebSChurchill Khangar 		return;
105675129cebSChurchill Khangar 	}
105775129cebSChurchill Khangar 
105875129cebSChurchill Khangar 	table_name = tokens[3];
105975129cebSChurchill Khangar 
106075129cebSChurchill Khangar 	file_name = tokens[5];
106175129cebSChurchill Khangar 	file = fopen(file_name, "r");
106275129cebSChurchill Khangar 	if (!file) {
106375129cebSChurchill Khangar 		snprintf(out, out_size, "Cannot open file %s.\n", file_name);
106475129cebSChurchill Khangar 		return;
106575129cebSChurchill Khangar 	}
106675129cebSChurchill Khangar 
1067b9559f94SCristian Dumitrescu 	status = pipeline_table_default_entry_add(ctl,
10685074e1d5SCristian Dumitrescu 						  table_name,
106975129cebSChurchill Khangar 						  file,
107075129cebSChurchill Khangar 						  &file_line_number);
107175129cebSChurchill Khangar 	if (status)
107275129cebSChurchill Khangar 		snprintf(out, out_size, "Invalid entry in file %s at line %u\n",
107375129cebSChurchill Khangar 			 file_name,
107475129cebSChurchill Khangar 			 file_line_number);
1075cff9a717SCristian Dumitrescu 
107675129cebSChurchill Khangar 	fclose(file);
10775074e1d5SCristian Dumitrescu }
10785074e1d5SCristian Dumitrescu 
107975129cebSChurchill Khangar static const char cmd_pipeline_table_show_help[] =
1080a4c1146cSCristian Dumitrescu "pipeline <pipeline_name> table <table_name> show [filename]\n";
108175129cebSChurchill Khangar 
108275129cebSChurchill Khangar static void
108375129cebSChurchill Khangar cmd_pipeline_table_show(char **tokens,
108475129cebSChurchill Khangar 	uint32_t n_tokens,
108575129cebSChurchill Khangar 	char *out,
108675129cebSChurchill Khangar 	size_t out_size,
1087b9559f94SCristian Dumitrescu 	void *obj __rte_unused)
108875129cebSChurchill Khangar {
1089b9559f94SCristian Dumitrescu 	struct rte_swx_ctl_pipeline *ctl;
109075129cebSChurchill Khangar 	char *pipeline_name, *table_name;
1091a4c1146cSCristian Dumitrescu 	FILE *file = NULL;
109275129cebSChurchill Khangar 	int status;
109375129cebSChurchill Khangar 
1094a4c1146cSCristian Dumitrescu 	if (n_tokens != 5 && n_tokens != 6) {
109575129cebSChurchill Khangar 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
109675129cebSChurchill Khangar 		return;
10975074e1d5SCristian Dumitrescu 	}
10985074e1d5SCristian Dumitrescu 
109975129cebSChurchill Khangar 	pipeline_name = tokens[1];
1100b9559f94SCristian Dumitrescu 	ctl = rte_swx_ctl_pipeline_find(pipeline_name);
1101b9559f94SCristian Dumitrescu 	if (!ctl) {
110275129cebSChurchill Khangar 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
110375129cebSChurchill Khangar 		return;
11045074e1d5SCristian Dumitrescu 	}
11055074e1d5SCristian Dumitrescu 
110675129cebSChurchill Khangar 	table_name = tokens[3];
1107a4c1146cSCristian Dumitrescu 	file = (n_tokens == 6) ? fopen(tokens[5], "w") : stdout;
1108a4c1146cSCristian Dumitrescu 	if (!file) {
1109a4c1146cSCristian Dumitrescu 		snprintf(out, out_size, "Cannot open file %s.\n", tokens[5]);
1110a4c1146cSCristian Dumitrescu 		return;
1111a4c1146cSCristian Dumitrescu 	}
1112a4c1146cSCristian Dumitrescu 
1113b9559f94SCristian Dumitrescu 	status = rte_swx_ctl_pipeline_table_fprintf(file, ctl, table_name);
111475129cebSChurchill Khangar 	if (status)
111575129cebSChurchill Khangar 		snprintf(out, out_size, MSG_ARG_INVALID, "table_name");
1116a4c1146cSCristian Dumitrescu 
1117a4c1146cSCristian Dumitrescu 	if (file)
1118a4c1146cSCristian Dumitrescu 		fclose(file);
11195074e1d5SCristian Dumitrescu }
112075129cebSChurchill Khangar 
1121598fe0ddSCristian Dumitrescu static const char cmd_pipeline_selector_group_add_help[] =
1122598fe0ddSCristian Dumitrescu "pipeline <pipeline_name> selector <selector_name> group add\n";
1123598fe0ddSCristian Dumitrescu 
1124598fe0ddSCristian Dumitrescu static void
1125598fe0ddSCristian Dumitrescu cmd_pipeline_selector_group_add(char **tokens,
1126598fe0ddSCristian Dumitrescu 	uint32_t n_tokens,
1127598fe0ddSCristian Dumitrescu 	char *out,
1128598fe0ddSCristian Dumitrescu 	size_t out_size,
1129b9559f94SCristian Dumitrescu 	void *obj __rte_unused)
1130598fe0ddSCristian Dumitrescu {
1131b9559f94SCristian Dumitrescu 	struct rte_swx_ctl_pipeline *ctl;
1132598fe0ddSCristian Dumitrescu 	char *pipeline_name, *selector_name;
1133598fe0ddSCristian Dumitrescu 	uint32_t group_id;
1134598fe0ddSCristian Dumitrescu 	int status;
1135598fe0ddSCristian Dumitrescu 
1136598fe0ddSCristian Dumitrescu 	if (n_tokens != 6) {
1137598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1138598fe0ddSCristian Dumitrescu 		return;
1139598fe0ddSCristian Dumitrescu 	}
1140598fe0ddSCristian Dumitrescu 
1141598fe0ddSCristian Dumitrescu 	pipeline_name = tokens[1];
1142b9559f94SCristian Dumitrescu 	ctl = rte_swx_ctl_pipeline_find(pipeline_name);
1143b9559f94SCristian Dumitrescu 	if (!ctl) {
1144598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
1145598fe0ddSCristian Dumitrescu 		return;
1146598fe0ddSCristian Dumitrescu 	}
1147598fe0ddSCristian Dumitrescu 
1148598fe0ddSCristian Dumitrescu 	if (strcmp(tokens[2], "selector") != 0) {
1149598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "selector");
1150598fe0ddSCristian Dumitrescu 		return;
1151598fe0ddSCristian Dumitrescu 	}
1152598fe0ddSCristian Dumitrescu 
1153598fe0ddSCristian Dumitrescu 	selector_name = tokens[3];
1154598fe0ddSCristian Dumitrescu 
1155598fe0ddSCristian Dumitrescu 	if (strcmp(tokens[4], "group") ||
1156598fe0ddSCristian Dumitrescu 		strcmp(tokens[5], "add")) {
1157598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "group add");
1158598fe0ddSCristian Dumitrescu 		return;
1159598fe0ddSCristian Dumitrescu 	}
1160598fe0ddSCristian Dumitrescu 
1161b9559f94SCristian Dumitrescu 	status = rte_swx_ctl_pipeline_selector_group_add(ctl,
1162598fe0ddSCristian Dumitrescu 		selector_name,
1163598fe0ddSCristian Dumitrescu 		&group_id);
1164598fe0ddSCristian Dumitrescu 	if (status)
1165598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
1166598fe0ddSCristian Dumitrescu 	else
1167598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, "Group ID: %u\n", group_id);
1168598fe0ddSCristian Dumitrescu }
1169598fe0ddSCristian Dumitrescu 
1170598fe0ddSCristian Dumitrescu static const char cmd_pipeline_selector_group_delete_help[] =
1171598fe0ddSCristian Dumitrescu "pipeline <pipeline_name> selector <selector_name> group delete <group_id>\n";
1172598fe0ddSCristian Dumitrescu 
1173598fe0ddSCristian Dumitrescu static void
1174598fe0ddSCristian Dumitrescu cmd_pipeline_selector_group_delete(char **tokens,
1175598fe0ddSCristian Dumitrescu 	uint32_t n_tokens,
1176598fe0ddSCristian Dumitrescu 	char *out,
1177598fe0ddSCristian Dumitrescu 	size_t out_size,
1178b9559f94SCristian Dumitrescu 	void *obj __rte_unused)
1179598fe0ddSCristian Dumitrescu {
1180b9559f94SCristian Dumitrescu 	struct rte_swx_ctl_pipeline *ctl;
1181598fe0ddSCristian Dumitrescu 	char *pipeline_name, *selector_name;
1182598fe0ddSCristian Dumitrescu 	uint32_t group_id;
1183598fe0ddSCristian Dumitrescu 	int status;
1184598fe0ddSCristian Dumitrescu 
1185598fe0ddSCristian Dumitrescu 	if (n_tokens != 7) {
1186598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1187598fe0ddSCristian Dumitrescu 		return;
1188598fe0ddSCristian Dumitrescu 	}
1189598fe0ddSCristian Dumitrescu 
1190598fe0ddSCristian Dumitrescu 	pipeline_name = tokens[1];
1191b9559f94SCristian Dumitrescu 	ctl = rte_swx_ctl_pipeline_find(pipeline_name);
1192b9559f94SCristian Dumitrescu 	if (!ctl) {
1193598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
1194598fe0ddSCristian Dumitrescu 		return;
1195598fe0ddSCristian Dumitrescu 	}
1196598fe0ddSCristian Dumitrescu 
1197598fe0ddSCristian Dumitrescu 	if (strcmp(tokens[2], "selector") != 0) {
1198598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "selector");
1199598fe0ddSCristian Dumitrescu 		return;
1200598fe0ddSCristian Dumitrescu 	}
1201598fe0ddSCristian Dumitrescu 
1202598fe0ddSCristian Dumitrescu 	selector_name = tokens[3];
1203598fe0ddSCristian Dumitrescu 
1204598fe0ddSCristian Dumitrescu 	if (strcmp(tokens[4], "group") ||
1205598fe0ddSCristian Dumitrescu 		strcmp(tokens[5], "delete")) {
1206598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "group delete");
1207598fe0ddSCristian Dumitrescu 		return;
1208598fe0ddSCristian Dumitrescu 	}
1209598fe0ddSCristian Dumitrescu 
1210598fe0ddSCristian Dumitrescu 	if (parser_read_uint32(&group_id, tokens[6]) != 0) {
1211598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "group_id");
1212598fe0ddSCristian Dumitrescu 		return;
1213598fe0ddSCristian Dumitrescu 	}
1214598fe0ddSCristian Dumitrescu 
1215b9559f94SCristian Dumitrescu 	status = rte_swx_ctl_pipeline_selector_group_delete(ctl,
1216598fe0ddSCristian Dumitrescu 		selector_name,
1217598fe0ddSCristian Dumitrescu 		group_id);
1218598fe0ddSCristian Dumitrescu 	if (status)
1219598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
1220598fe0ddSCristian Dumitrescu }
1221598fe0ddSCristian Dumitrescu 
1222598fe0ddSCristian Dumitrescu #define GROUP_MEMBER_INFO_TOKENS_MAX 6
1223598fe0ddSCristian Dumitrescu 
1224598fe0ddSCristian Dumitrescu static int
1225598fe0ddSCristian Dumitrescu token_is_comment(const char *token)
1226598fe0ddSCristian Dumitrescu {
1227598fe0ddSCristian Dumitrescu 	if ((token[0] == '#') ||
1228598fe0ddSCristian Dumitrescu 	    (token[0] == ';') ||
1229598fe0ddSCristian Dumitrescu 	    ((token[0] == '/') && (token[1] == '/')))
1230598fe0ddSCristian Dumitrescu 		return 1; /* TRUE. */
1231598fe0ddSCristian Dumitrescu 
1232598fe0ddSCristian Dumitrescu 	return 0; /* FALSE. */
1233598fe0ddSCristian Dumitrescu }
1234598fe0ddSCristian Dumitrescu 
1235598fe0ddSCristian Dumitrescu static int
1236598fe0ddSCristian Dumitrescu pipeline_selector_group_member_read(const char *string,
1237598fe0ddSCristian Dumitrescu 				      uint32_t *group_id,
1238598fe0ddSCristian Dumitrescu 				      uint32_t *member_id,
1239598fe0ddSCristian Dumitrescu 				      uint32_t *weight,
1240598fe0ddSCristian Dumitrescu 				      int *is_blank_or_comment)
1241598fe0ddSCristian Dumitrescu {
1242598fe0ddSCristian Dumitrescu 	char *token_array[GROUP_MEMBER_INFO_TOKENS_MAX], **tokens;
1243598fe0ddSCristian Dumitrescu 	char *s0 = NULL, *s;
124400b67591SAli Alnubani 	uint32_t n_tokens = 0, group_id_val = 0, member_id_val = 0, weight_val = 0;
1245598fe0ddSCristian Dumitrescu 	int blank_or_comment = 0;
1246598fe0ddSCristian Dumitrescu 
1247598fe0ddSCristian Dumitrescu 	/* Check input arguments. */
1248598fe0ddSCristian Dumitrescu 	if (!string || !string[0])
1249598fe0ddSCristian Dumitrescu 		goto error;
1250598fe0ddSCristian Dumitrescu 
1251598fe0ddSCristian Dumitrescu 	/* Memory allocation. */
1252598fe0ddSCristian Dumitrescu 	s0 = strdup(string);
1253598fe0ddSCristian Dumitrescu 	if (!s0)
1254598fe0ddSCristian Dumitrescu 		goto error;
1255598fe0ddSCristian Dumitrescu 
1256598fe0ddSCristian Dumitrescu 	/* Parse the string into tokens. */
1257598fe0ddSCristian Dumitrescu 	for (s = s0; ; ) {
1258598fe0ddSCristian Dumitrescu 		char *token;
1259598fe0ddSCristian Dumitrescu 
1260598fe0ddSCristian Dumitrescu 		token = strtok_r(s, " \f\n\r\t\v", &s);
1261598fe0ddSCristian Dumitrescu 		if (!token || token_is_comment(token))
1262598fe0ddSCristian Dumitrescu 			break;
1263598fe0ddSCristian Dumitrescu 
1264cfcc7bf8SCristian Dumitrescu 		if (n_tokens >= GROUP_MEMBER_INFO_TOKENS_MAX)
1265598fe0ddSCristian Dumitrescu 			goto error;
1266598fe0ddSCristian Dumitrescu 
1267598fe0ddSCristian Dumitrescu 		token_array[n_tokens] = token;
1268598fe0ddSCristian Dumitrescu 		n_tokens++;
1269598fe0ddSCristian Dumitrescu 	}
1270598fe0ddSCristian Dumitrescu 
1271598fe0ddSCristian Dumitrescu 	if (!n_tokens) {
1272598fe0ddSCristian Dumitrescu 		blank_or_comment = 1;
1273598fe0ddSCristian Dumitrescu 		goto error;
1274598fe0ddSCristian Dumitrescu 	}
1275598fe0ddSCristian Dumitrescu 
1276598fe0ddSCristian Dumitrescu 	tokens = token_array;
1277598fe0ddSCristian Dumitrescu 
1278598fe0ddSCristian Dumitrescu 	if (n_tokens < 4 ||
1279598fe0ddSCristian Dumitrescu 		strcmp(tokens[0], "group") ||
1280598fe0ddSCristian Dumitrescu 		strcmp(tokens[2], "member"))
1281598fe0ddSCristian Dumitrescu 		goto error;
1282598fe0ddSCristian Dumitrescu 
1283598fe0ddSCristian Dumitrescu 	/*
1284598fe0ddSCristian Dumitrescu 	 * Group ID.
1285598fe0ddSCristian Dumitrescu 	 */
1286598fe0ddSCristian Dumitrescu 	if (parser_read_uint32(&group_id_val, tokens[1]) != 0)
1287598fe0ddSCristian Dumitrescu 		goto error;
1288598fe0ddSCristian Dumitrescu 	*group_id = group_id_val;
1289598fe0ddSCristian Dumitrescu 
1290598fe0ddSCristian Dumitrescu 	/*
1291598fe0ddSCristian Dumitrescu 	 * Member ID.
1292598fe0ddSCristian Dumitrescu 	 */
1293598fe0ddSCristian Dumitrescu 	if (parser_read_uint32(&member_id_val, tokens[3]) != 0)
1294598fe0ddSCristian Dumitrescu 		goto error;
1295598fe0ddSCristian Dumitrescu 	*member_id = member_id_val;
1296598fe0ddSCristian Dumitrescu 
1297598fe0ddSCristian Dumitrescu 	tokens += 4;
1298598fe0ddSCristian Dumitrescu 	n_tokens -= 4;
1299598fe0ddSCristian Dumitrescu 
1300598fe0ddSCristian Dumitrescu 	/*
1301598fe0ddSCristian Dumitrescu 	 * Weight.
1302598fe0ddSCristian Dumitrescu 	 */
1303598fe0ddSCristian Dumitrescu 	if (n_tokens && !strcmp(tokens[0], "weight")) {
1304598fe0ddSCristian Dumitrescu 		if (n_tokens < 2)
1305598fe0ddSCristian Dumitrescu 			goto error;
1306598fe0ddSCristian Dumitrescu 
1307598fe0ddSCristian Dumitrescu 		if (parser_read_uint32(&weight_val, tokens[1]) != 0)
1308598fe0ddSCristian Dumitrescu 			goto error;
1309598fe0ddSCristian Dumitrescu 		*weight = weight_val;
1310598fe0ddSCristian Dumitrescu 
1311598fe0ddSCristian Dumitrescu 		tokens += 2;
1312598fe0ddSCristian Dumitrescu 		n_tokens -= 2;
1313598fe0ddSCristian Dumitrescu 	}
1314598fe0ddSCristian Dumitrescu 
1315598fe0ddSCristian Dumitrescu 	if (n_tokens)
1316598fe0ddSCristian Dumitrescu 		goto error;
1317598fe0ddSCristian Dumitrescu 
1318598fe0ddSCristian Dumitrescu 	free(s0);
1319598fe0ddSCristian Dumitrescu 	return 0;
1320598fe0ddSCristian Dumitrescu 
1321598fe0ddSCristian Dumitrescu error:
1322598fe0ddSCristian Dumitrescu 	free(s0);
1323598fe0ddSCristian Dumitrescu 	if (is_blank_or_comment)
1324598fe0ddSCristian Dumitrescu 		*is_blank_or_comment = blank_or_comment;
1325598fe0ddSCristian Dumitrescu 	return -EINVAL;
1326598fe0ddSCristian Dumitrescu }
1327598fe0ddSCristian Dumitrescu 
1328598fe0ddSCristian Dumitrescu static int
1329598fe0ddSCristian Dumitrescu pipeline_selector_group_members_add(struct rte_swx_ctl_pipeline *p,
1330598fe0ddSCristian Dumitrescu 			   const char *selector_name,
1331598fe0ddSCristian Dumitrescu 			   FILE *file,
1332598fe0ddSCristian Dumitrescu 			   uint32_t *file_line_number)
1333598fe0ddSCristian Dumitrescu {
1334598fe0ddSCristian Dumitrescu 	char *line = NULL;
1335598fe0ddSCristian Dumitrescu 	uint32_t line_id = 0;
1336598fe0ddSCristian Dumitrescu 	int status = 0;
1337598fe0ddSCristian Dumitrescu 
1338598fe0ddSCristian Dumitrescu 	/* Buffer allocation. */
1339598fe0ddSCristian Dumitrescu 	line = malloc(MAX_LINE_SIZE);
1340598fe0ddSCristian Dumitrescu 	if (!line)
1341598fe0ddSCristian Dumitrescu 		return -ENOMEM;
1342598fe0ddSCristian Dumitrescu 
1343598fe0ddSCristian Dumitrescu 	/* File read. */
1344598fe0ddSCristian Dumitrescu 	for (line_id = 1; ; line_id++) {
1345598fe0ddSCristian Dumitrescu 		uint32_t group_id, member_id, weight;
1346598fe0ddSCristian Dumitrescu 		int is_blank_or_comment;
1347598fe0ddSCristian Dumitrescu 
1348598fe0ddSCristian Dumitrescu 		if (fgets(line, MAX_LINE_SIZE, file) == NULL)
1349598fe0ddSCristian Dumitrescu 			break;
1350598fe0ddSCristian Dumitrescu 
1351598fe0ddSCristian Dumitrescu 		status = pipeline_selector_group_member_read(line,
1352598fe0ddSCristian Dumitrescu 							      &group_id,
1353598fe0ddSCristian Dumitrescu 							      &member_id,
1354598fe0ddSCristian Dumitrescu 							      &weight,
1355598fe0ddSCristian Dumitrescu 							      &is_blank_or_comment);
1356598fe0ddSCristian Dumitrescu 		if (status) {
1357598fe0ddSCristian Dumitrescu 			if (is_blank_or_comment)
1358598fe0ddSCristian Dumitrescu 				continue;
1359598fe0ddSCristian Dumitrescu 
1360598fe0ddSCristian Dumitrescu 			goto error;
1361598fe0ddSCristian Dumitrescu 		}
1362598fe0ddSCristian Dumitrescu 
1363598fe0ddSCristian Dumitrescu 		status = rte_swx_ctl_pipeline_selector_group_member_add(p,
1364598fe0ddSCristian Dumitrescu 			selector_name,
1365598fe0ddSCristian Dumitrescu 			group_id,
1366598fe0ddSCristian Dumitrescu 			member_id,
1367598fe0ddSCristian Dumitrescu 			weight);
1368598fe0ddSCristian Dumitrescu 		if (status)
1369598fe0ddSCristian Dumitrescu 			goto error;
1370598fe0ddSCristian Dumitrescu 	}
1371598fe0ddSCristian Dumitrescu 
1372598fe0ddSCristian Dumitrescu error:
1373598fe0ddSCristian Dumitrescu 	free(line);
1374598fe0ddSCristian Dumitrescu 	*file_line_number = line_id;
1375598fe0ddSCristian Dumitrescu 	return status;
1376598fe0ddSCristian Dumitrescu }
1377598fe0ddSCristian Dumitrescu 
1378598fe0ddSCristian Dumitrescu static const char cmd_pipeline_selector_group_member_add_help[] =
1379598fe0ddSCristian Dumitrescu "pipeline <pipeline_name> selector <selector_name> group member add <file_name>";
1380598fe0ddSCristian Dumitrescu 
1381598fe0ddSCristian Dumitrescu static void
1382598fe0ddSCristian Dumitrescu cmd_pipeline_selector_group_member_add(char **tokens,
1383598fe0ddSCristian Dumitrescu 	uint32_t n_tokens,
1384598fe0ddSCristian Dumitrescu 	char *out,
1385598fe0ddSCristian Dumitrescu 	size_t out_size,
1386b9559f94SCristian Dumitrescu 	void *obj __rte_unused)
1387598fe0ddSCristian Dumitrescu {
1388b9559f94SCristian Dumitrescu 	struct rte_swx_ctl_pipeline *ctl;
1389598fe0ddSCristian Dumitrescu 	char *pipeline_name, *selector_name, *file_name;
1390598fe0ddSCristian Dumitrescu 	FILE *file = NULL;
1391598fe0ddSCristian Dumitrescu 	uint32_t file_line_number = 0;
1392598fe0ddSCristian Dumitrescu 	int status;
1393598fe0ddSCristian Dumitrescu 
1394598fe0ddSCristian Dumitrescu 	if (n_tokens != 8) {
1395598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1396598fe0ddSCristian Dumitrescu 		return;
1397598fe0ddSCristian Dumitrescu 	}
1398598fe0ddSCristian Dumitrescu 
1399598fe0ddSCristian Dumitrescu 	pipeline_name = tokens[1];
1400b9559f94SCristian Dumitrescu 	ctl = rte_swx_ctl_pipeline_find(pipeline_name);
1401b9559f94SCristian Dumitrescu 	if (!ctl) {
1402598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
1403598fe0ddSCristian Dumitrescu 		return;
1404598fe0ddSCristian Dumitrescu 	}
1405598fe0ddSCristian Dumitrescu 
1406598fe0ddSCristian Dumitrescu 	if (strcmp(tokens[2], "selector") != 0) {
1407598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "selector");
1408598fe0ddSCristian Dumitrescu 		return;
1409598fe0ddSCristian Dumitrescu 	}
1410598fe0ddSCristian Dumitrescu 
1411598fe0ddSCristian Dumitrescu 	selector_name = tokens[3];
1412598fe0ddSCristian Dumitrescu 
1413598fe0ddSCristian Dumitrescu 	if (strcmp(tokens[4], "group") ||
1414598fe0ddSCristian Dumitrescu 		strcmp(tokens[5], "member") ||
1415598fe0ddSCristian Dumitrescu 		strcmp(tokens[6], "add")) {
1416598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "group member add");
1417598fe0ddSCristian Dumitrescu 		return;
1418598fe0ddSCristian Dumitrescu 	}
1419598fe0ddSCristian Dumitrescu 
1420598fe0ddSCristian Dumitrescu 	file_name = tokens[7];
1421598fe0ddSCristian Dumitrescu 	file = fopen(file_name, "r");
1422598fe0ddSCristian Dumitrescu 	if (!file) {
1423598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, "Cannot open file %s.\n", file_name);
1424598fe0ddSCristian Dumitrescu 		return;
1425598fe0ddSCristian Dumitrescu 	}
1426598fe0ddSCristian Dumitrescu 
1427b9559f94SCristian Dumitrescu 	status = pipeline_selector_group_members_add(ctl,
1428598fe0ddSCristian Dumitrescu 					    selector_name,
1429598fe0ddSCristian Dumitrescu 					    file,
1430598fe0ddSCristian Dumitrescu 					    &file_line_number);
1431598fe0ddSCristian Dumitrescu 	if (status)
1432598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, "Invalid entry in file %s at line %u\n",
1433598fe0ddSCristian Dumitrescu 			 file_name,
1434598fe0ddSCristian Dumitrescu 			 file_line_number);
1435598fe0ddSCristian Dumitrescu 
1436598fe0ddSCristian Dumitrescu 	fclose(file);
1437598fe0ddSCristian Dumitrescu }
1438598fe0ddSCristian Dumitrescu 
1439598fe0ddSCristian Dumitrescu static int
1440598fe0ddSCristian Dumitrescu pipeline_selector_group_members_delete(struct rte_swx_ctl_pipeline *p,
1441598fe0ddSCristian Dumitrescu 			   const char *selector_name,
1442598fe0ddSCristian Dumitrescu 			   FILE *file,
1443598fe0ddSCristian Dumitrescu 			   uint32_t *file_line_number)
1444598fe0ddSCristian Dumitrescu {
1445598fe0ddSCristian Dumitrescu 	char *line = NULL;
1446598fe0ddSCristian Dumitrescu 	uint32_t line_id = 0;
1447598fe0ddSCristian Dumitrescu 	int status = 0;
1448598fe0ddSCristian Dumitrescu 
1449598fe0ddSCristian Dumitrescu 	/* Buffer allocation. */
1450598fe0ddSCristian Dumitrescu 	line = malloc(MAX_LINE_SIZE);
1451598fe0ddSCristian Dumitrescu 	if (!line)
1452598fe0ddSCristian Dumitrescu 		return -ENOMEM;
1453598fe0ddSCristian Dumitrescu 
1454598fe0ddSCristian Dumitrescu 	/* File read. */
1455598fe0ddSCristian Dumitrescu 	for (line_id = 1; ; line_id++) {
1456598fe0ddSCristian Dumitrescu 		uint32_t group_id, member_id, weight;
1457598fe0ddSCristian Dumitrescu 		int is_blank_or_comment;
1458598fe0ddSCristian Dumitrescu 
1459598fe0ddSCristian Dumitrescu 		if (fgets(line, MAX_LINE_SIZE, file) == NULL)
1460598fe0ddSCristian Dumitrescu 			break;
1461598fe0ddSCristian Dumitrescu 
1462598fe0ddSCristian Dumitrescu 		status = pipeline_selector_group_member_read(line,
1463598fe0ddSCristian Dumitrescu 							      &group_id,
1464598fe0ddSCristian Dumitrescu 							      &member_id,
1465598fe0ddSCristian Dumitrescu 							      &weight,
1466598fe0ddSCristian Dumitrescu 							      &is_blank_or_comment);
1467598fe0ddSCristian Dumitrescu 		if (status) {
1468598fe0ddSCristian Dumitrescu 			if (is_blank_or_comment)
1469598fe0ddSCristian Dumitrescu 				continue;
1470598fe0ddSCristian Dumitrescu 
1471598fe0ddSCristian Dumitrescu 			goto error;
1472598fe0ddSCristian Dumitrescu 		}
1473598fe0ddSCristian Dumitrescu 
1474598fe0ddSCristian Dumitrescu 		status = rte_swx_ctl_pipeline_selector_group_member_delete(p,
1475598fe0ddSCristian Dumitrescu 			selector_name,
1476598fe0ddSCristian Dumitrescu 			group_id,
1477598fe0ddSCristian Dumitrescu 			member_id);
1478598fe0ddSCristian Dumitrescu 		if (status)
1479598fe0ddSCristian Dumitrescu 			goto error;
1480598fe0ddSCristian Dumitrescu 	}
1481598fe0ddSCristian Dumitrescu 
1482598fe0ddSCristian Dumitrescu error:
1483598fe0ddSCristian Dumitrescu 	free(line);
1484598fe0ddSCristian Dumitrescu 	*file_line_number = line_id;
1485598fe0ddSCristian Dumitrescu 	return status;
1486598fe0ddSCristian Dumitrescu }
1487598fe0ddSCristian Dumitrescu 
1488598fe0ddSCristian Dumitrescu static const char cmd_pipeline_selector_group_member_delete_help[] =
1489598fe0ddSCristian Dumitrescu "pipeline <pipeline_name> selector <selector_name> group member delete <file_name>";
1490598fe0ddSCristian Dumitrescu 
1491598fe0ddSCristian Dumitrescu static void
1492598fe0ddSCristian Dumitrescu cmd_pipeline_selector_group_member_delete(char **tokens,
1493598fe0ddSCristian Dumitrescu 	uint32_t n_tokens,
1494598fe0ddSCristian Dumitrescu 	char *out,
1495598fe0ddSCristian Dumitrescu 	size_t out_size,
1496b9559f94SCristian Dumitrescu 	void *obj __rte_unused)
1497598fe0ddSCristian Dumitrescu {
1498b9559f94SCristian Dumitrescu 	struct rte_swx_ctl_pipeline *ctl;
1499598fe0ddSCristian Dumitrescu 	char *pipeline_name, *selector_name, *file_name;
1500598fe0ddSCristian Dumitrescu 	FILE *file = NULL;
1501598fe0ddSCristian Dumitrescu 	uint32_t file_line_number = 0;
1502598fe0ddSCristian Dumitrescu 	int status;
1503598fe0ddSCristian Dumitrescu 
1504598fe0ddSCristian Dumitrescu 	if (n_tokens != 8) {
1505598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1506598fe0ddSCristian Dumitrescu 		return;
1507598fe0ddSCristian Dumitrescu 	}
1508598fe0ddSCristian Dumitrescu 
1509598fe0ddSCristian Dumitrescu 	pipeline_name = tokens[1];
1510b9559f94SCristian Dumitrescu 	ctl = rte_swx_ctl_pipeline_find(pipeline_name);
1511b9559f94SCristian Dumitrescu 	if (!ctl) {
1512598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
1513598fe0ddSCristian Dumitrescu 		return;
1514598fe0ddSCristian Dumitrescu 	}
1515598fe0ddSCristian Dumitrescu 
1516598fe0ddSCristian Dumitrescu 	if (strcmp(tokens[2], "selector") != 0) {
1517598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "selector");
1518598fe0ddSCristian Dumitrescu 		return;
1519598fe0ddSCristian Dumitrescu 	}
1520598fe0ddSCristian Dumitrescu 
1521598fe0ddSCristian Dumitrescu 	selector_name = tokens[3];
1522598fe0ddSCristian Dumitrescu 
1523598fe0ddSCristian Dumitrescu 	if (strcmp(tokens[4], "group") ||
1524598fe0ddSCristian Dumitrescu 		strcmp(tokens[5], "member") ||
1525598fe0ddSCristian Dumitrescu 		strcmp(tokens[6], "delete")) {
1526598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "group member delete");
1527598fe0ddSCristian Dumitrescu 		return;
1528598fe0ddSCristian Dumitrescu 	}
1529598fe0ddSCristian Dumitrescu 
1530598fe0ddSCristian Dumitrescu 	file_name = tokens[7];
1531598fe0ddSCristian Dumitrescu 	file = fopen(file_name, "r");
1532598fe0ddSCristian Dumitrescu 	if (!file) {
1533598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, "Cannot open file %s.\n", file_name);
1534598fe0ddSCristian Dumitrescu 		return;
1535598fe0ddSCristian Dumitrescu 	}
1536598fe0ddSCristian Dumitrescu 
1537b9559f94SCristian Dumitrescu 	status = pipeline_selector_group_members_delete(ctl,
1538598fe0ddSCristian Dumitrescu 					    selector_name,
1539598fe0ddSCristian Dumitrescu 					    file,
1540598fe0ddSCristian Dumitrescu 					    &file_line_number);
1541598fe0ddSCristian Dumitrescu 	if (status)
1542598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, "Invalid entry in file %s at line %u\n",
1543598fe0ddSCristian Dumitrescu 			 file_name,
1544598fe0ddSCristian Dumitrescu 			 file_line_number);
1545598fe0ddSCristian Dumitrescu 
1546598fe0ddSCristian Dumitrescu 	fclose(file);
1547598fe0ddSCristian Dumitrescu }
1548598fe0ddSCristian Dumitrescu 
1549598fe0ddSCristian Dumitrescu static const char cmd_pipeline_selector_show_help[] =
1550a4c1146cSCristian Dumitrescu "pipeline <pipeline_name> selector <selector_name> show [filename]\n";
1551598fe0ddSCristian Dumitrescu 
1552598fe0ddSCristian Dumitrescu static void
1553598fe0ddSCristian Dumitrescu cmd_pipeline_selector_show(char **tokens,
1554598fe0ddSCristian Dumitrescu 	uint32_t n_tokens,
1555598fe0ddSCristian Dumitrescu 	char *out,
1556598fe0ddSCristian Dumitrescu 	size_t out_size,
1557b9559f94SCristian Dumitrescu 	void *obj __rte_unused)
1558598fe0ddSCristian Dumitrescu {
1559b9559f94SCristian Dumitrescu 	struct rte_swx_ctl_pipeline *ctl;
1560598fe0ddSCristian Dumitrescu 	char *pipeline_name, *selector_name;
1561a4c1146cSCristian Dumitrescu 	FILE *file = NULL;
1562598fe0ddSCristian Dumitrescu 	int status;
1563598fe0ddSCristian Dumitrescu 
1564a4c1146cSCristian Dumitrescu 	if (n_tokens != 5 && n_tokens != 6) {
1565598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1566598fe0ddSCristian Dumitrescu 		return;
1567598fe0ddSCristian Dumitrescu 	}
1568598fe0ddSCristian Dumitrescu 
1569598fe0ddSCristian Dumitrescu 	pipeline_name = tokens[1];
1570b9559f94SCristian Dumitrescu 	ctl = rte_swx_ctl_pipeline_find(pipeline_name);
1571b9559f94SCristian Dumitrescu 	if (!ctl) {
1572598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
1573598fe0ddSCristian Dumitrescu 		return;
1574598fe0ddSCristian Dumitrescu 	}
1575598fe0ddSCristian Dumitrescu 
1576598fe0ddSCristian Dumitrescu 	selector_name = tokens[3];
1577a4c1146cSCristian Dumitrescu 
1578a4c1146cSCristian Dumitrescu 	file = (n_tokens == 6) ? fopen(tokens[5], "w") : stdout;
1579a4c1146cSCristian Dumitrescu 	if (!file) {
1580a4c1146cSCristian Dumitrescu 		snprintf(out, out_size, "Cannot open file %s.\n", tokens[5]);
1581a4c1146cSCristian Dumitrescu 		return;
1582a4c1146cSCristian Dumitrescu 	}
1583a4c1146cSCristian Dumitrescu 
1584b9559f94SCristian Dumitrescu 	status = rte_swx_ctl_pipeline_selector_fprintf(file, ctl, selector_name);
1585598fe0ddSCristian Dumitrescu 	if (status)
1586598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "selector_name");
1587a4c1146cSCristian Dumitrescu 
1588a4c1146cSCristian Dumitrescu 	if (file)
1589a4c1146cSCristian Dumitrescu 		fclose(file);
1590598fe0ddSCristian Dumitrescu }
1591598fe0ddSCristian Dumitrescu 
15928bd4862fSCristian Dumitrescu static int
15938bd4862fSCristian Dumitrescu pipeline_learner_default_entry_add(struct rte_swx_ctl_pipeline *p,
15948bd4862fSCristian Dumitrescu 				   const char *learner_name,
15958bd4862fSCristian Dumitrescu 				   FILE *file,
15968bd4862fSCristian Dumitrescu 				   uint32_t *file_line_number)
15978bd4862fSCristian Dumitrescu {
15988bd4862fSCristian Dumitrescu 	char *line = NULL;
15998bd4862fSCristian Dumitrescu 	uint32_t line_id = 0;
16008bd4862fSCristian Dumitrescu 	int status = 0;
16018bd4862fSCristian Dumitrescu 
16028bd4862fSCristian Dumitrescu 	/* Buffer allocation. */
16038bd4862fSCristian Dumitrescu 	line = malloc(MAX_LINE_SIZE);
16048bd4862fSCristian Dumitrescu 	if (!line)
16058bd4862fSCristian Dumitrescu 		return -ENOMEM;
16068bd4862fSCristian Dumitrescu 
16078bd4862fSCristian Dumitrescu 	/* File read. */
16088bd4862fSCristian Dumitrescu 	for (line_id = 1; ; line_id++) {
16098bd4862fSCristian Dumitrescu 		struct rte_swx_table_entry *entry;
16108bd4862fSCristian Dumitrescu 		int is_blank_or_comment;
16118bd4862fSCristian Dumitrescu 
16128bd4862fSCristian Dumitrescu 		if (fgets(line, MAX_LINE_SIZE, file) == NULL)
16138bd4862fSCristian Dumitrescu 			break;
16148bd4862fSCristian Dumitrescu 
16158bd4862fSCristian Dumitrescu 		entry = rte_swx_ctl_pipeline_learner_default_entry_read(p,
16168bd4862fSCristian Dumitrescu 									learner_name,
16178bd4862fSCristian Dumitrescu 									line,
16188bd4862fSCristian Dumitrescu 									&is_blank_or_comment);
16198bd4862fSCristian Dumitrescu 		if (!entry) {
16208bd4862fSCristian Dumitrescu 			if (is_blank_or_comment)
16218bd4862fSCristian Dumitrescu 				continue;
16228bd4862fSCristian Dumitrescu 
16238bd4862fSCristian Dumitrescu 			status = -EINVAL;
16248bd4862fSCristian Dumitrescu 			goto error;
16258bd4862fSCristian Dumitrescu 		}
16268bd4862fSCristian Dumitrescu 
16278bd4862fSCristian Dumitrescu 		status = rte_swx_ctl_pipeline_learner_default_entry_add(p,
16288bd4862fSCristian Dumitrescu 									learner_name,
16298bd4862fSCristian Dumitrescu 									entry);
16308bd4862fSCristian Dumitrescu 		table_entry_free(entry);
16318bd4862fSCristian Dumitrescu 		if (status)
16328bd4862fSCristian Dumitrescu 			goto error;
16338bd4862fSCristian Dumitrescu 	}
16348bd4862fSCristian Dumitrescu 
16358bd4862fSCristian Dumitrescu error:
16368bd4862fSCristian Dumitrescu 	*file_line_number = line_id;
16378bd4862fSCristian Dumitrescu 	free(line);
16388bd4862fSCristian Dumitrescu 	return status;
16398bd4862fSCristian Dumitrescu }
16408bd4862fSCristian Dumitrescu 
16418bd4862fSCristian Dumitrescu static const char cmd_pipeline_learner_default_help[] =
16428bd4862fSCristian Dumitrescu "pipeline <pipeline_name> learner <learner_name> default <file_name>\n";
16438bd4862fSCristian Dumitrescu 
16448bd4862fSCristian Dumitrescu static void
16458bd4862fSCristian Dumitrescu cmd_pipeline_learner_default(char **tokens,
16468bd4862fSCristian Dumitrescu 			     uint32_t n_tokens,
16478bd4862fSCristian Dumitrescu 			     char *out,
16488bd4862fSCristian Dumitrescu 			     size_t out_size,
1649b9559f94SCristian Dumitrescu 			     void *obj __rte_unused)
16508bd4862fSCristian Dumitrescu {
1651b9559f94SCristian Dumitrescu 	struct rte_swx_ctl_pipeline *ctl;
16528bd4862fSCristian Dumitrescu 	char *pipeline_name, *learner_name, *file_name;
16538bd4862fSCristian Dumitrescu 	FILE *file = NULL;
16548bd4862fSCristian Dumitrescu 	uint32_t file_line_number = 0;
16558bd4862fSCristian Dumitrescu 	int status;
16568bd4862fSCristian Dumitrescu 
16578bd4862fSCristian Dumitrescu 	if (n_tokens != 6) {
16588bd4862fSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
16598bd4862fSCristian Dumitrescu 		return;
16608bd4862fSCristian Dumitrescu 	}
16618bd4862fSCristian Dumitrescu 
16628bd4862fSCristian Dumitrescu 	pipeline_name = tokens[1];
1663b9559f94SCristian Dumitrescu 	ctl = rte_swx_ctl_pipeline_find(pipeline_name);
1664b9559f94SCristian Dumitrescu 	if (!ctl) {
16658bd4862fSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
16668bd4862fSCristian Dumitrescu 		return;
16678bd4862fSCristian Dumitrescu 	}
16688bd4862fSCristian Dumitrescu 
16698bd4862fSCristian Dumitrescu 	learner_name = tokens[3];
16708bd4862fSCristian Dumitrescu 
16718bd4862fSCristian Dumitrescu 	file_name = tokens[5];
16728bd4862fSCristian Dumitrescu 	file = fopen(file_name, "r");
16738bd4862fSCristian Dumitrescu 	if (!file) {
16748bd4862fSCristian Dumitrescu 		snprintf(out, out_size, "Cannot open file %s.\n", file_name);
16758bd4862fSCristian Dumitrescu 		return;
16768bd4862fSCristian Dumitrescu 	}
16778bd4862fSCristian Dumitrescu 
1678b9559f94SCristian Dumitrescu 	status = pipeline_learner_default_entry_add(ctl,
16798bd4862fSCristian Dumitrescu 						    learner_name,
16808bd4862fSCristian Dumitrescu 						    file,
16818bd4862fSCristian Dumitrescu 						    &file_line_number);
16828bd4862fSCristian Dumitrescu 	if (status)
16838bd4862fSCristian Dumitrescu 		snprintf(out, out_size, "Invalid entry in file %s at line %u\n",
16848bd4862fSCristian Dumitrescu 			 file_name,
16858bd4862fSCristian Dumitrescu 			 file_line_number);
16868bd4862fSCristian Dumitrescu 
16878bd4862fSCristian Dumitrescu 	fclose(file);
16888bd4862fSCristian Dumitrescu }
16898bd4862fSCristian Dumitrescu 
169075129cebSChurchill Khangar static const char cmd_pipeline_commit_help[] =
169175129cebSChurchill Khangar "pipeline <pipeline_name> commit\n";
169275129cebSChurchill Khangar 
169375129cebSChurchill Khangar static void
169475129cebSChurchill Khangar cmd_pipeline_commit(char **tokens,
169575129cebSChurchill Khangar 	uint32_t n_tokens,
169675129cebSChurchill Khangar 	char *out,
169775129cebSChurchill Khangar 	size_t out_size,
1698b9559f94SCristian Dumitrescu 	void *obj __rte_unused)
169975129cebSChurchill Khangar {
1700b9559f94SCristian Dumitrescu 	struct rte_swx_ctl_pipeline *ctl;
170175129cebSChurchill Khangar 	char *pipeline_name;
170275129cebSChurchill Khangar 	int status;
170375129cebSChurchill Khangar 
170475129cebSChurchill Khangar 	if (n_tokens != 3) {
170575129cebSChurchill Khangar 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
170675129cebSChurchill Khangar 		return;
170775129cebSChurchill Khangar 	}
170875129cebSChurchill Khangar 
170975129cebSChurchill Khangar 	pipeline_name = tokens[1];
1710b9559f94SCristian Dumitrescu 	ctl = rte_swx_ctl_pipeline_find(pipeline_name);
1711b9559f94SCristian Dumitrescu 	if (!ctl) {
171275129cebSChurchill Khangar 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
171375129cebSChurchill Khangar 		return;
17145074e1d5SCristian Dumitrescu 	}
17155074e1d5SCristian Dumitrescu 
1716b9559f94SCristian Dumitrescu 	status = rte_swx_ctl_pipeline_commit(ctl, 1);
171775129cebSChurchill Khangar 	if (status)
171875129cebSChurchill Khangar 		snprintf(out, out_size, "Commit failed. "
171975129cebSChurchill Khangar 			"Use \"commit\" to retry or \"abort\" to discard the pending work.\n");
17205074e1d5SCristian Dumitrescu }
17215074e1d5SCristian Dumitrescu 
172275129cebSChurchill Khangar static const char cmd_pipeline_abort_help[] =
172375129cebSChurchill Khangar "pipeline <pipeline_name> abort\n";
17245074e1d5SCristian Dumitrescu 
172575129cebSChurchill Khangar static void
172675129cebSChurchill Khangar cmd_pipeline_abort(char **tokens,
172775129cebSChurchill Khangar 	uint32_t n_tokens,
172875129cebSChurchill Khangar 	char *out,
172975129cebSChurchill Khangar 	size_t out_size,
1730b9559f94SCristian Dumitrescu 	void *obj __rte_unused)
173175129cebSChurchill Khangar {
1732b9559f94SCristian Dumitrescu 	struct rte_swx_ctl_pipeline *ctl;
173375129cebSChurchill Khangar 	char *pipeline_name;
17345074e1d5SCristian Dumitrescu 
173575129cebSChurchill Khangar 	if (n_tokens != 3) {
173675129cebSChurchill Khangar 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
17375074e1d5SCristian Dumitrescu 		return;
173875129cebSChurchill Khangar 	}
17395074e1d5SCristian Dumitrescu 
174075129cebSChurchill Khangar 	pipeline_name = tokens[1];
1741b9559f94SCristian Dumitrescu 	ctl = rte_swx_ctl_pipeline_find(pipeline_name);
1742b9559f94SCristian Dumitrescu 	if (!ctl) {
174375129cebSChurchill Khangar 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
174475129cebSChurchill Khangar 		return;
174575129cebSChurchill Khangar 	}
174675129cebSChurchill Khangar 
1747b9559f94SCristian Dumitrescu 	rte_swx_ctl_pipeline_abort(ctl);
17485074e1d5SCristian Dumitrescu }
17495074e1d5SCristian Dumitrescu 
175064cfcebdSCristian Dumitrescu static const char cmd_pipeline_regrd_help[] =
175183f58a7bSCristian Dumitrescu "pipeline <pipeline_name> regrd <register_array_name>\n"
175283f58a7bSCristian Dumitrescu 	"index <index>\n"
175383f58a7bSCristian Dumitrescu 	" | table <table_name> match <field0> ...\n";
175464cfcebdSCristian Dumitrescu 
175564cfcebdSCristian Dumitrescu static void
175664cfcebdSCristian Dumitrescu cmd_pipeline_regrd(char **tokens,
175764cfcebdSCristian Dumitrescu 	uint32_t n_tokens,
175864cfcebdSCristian Dumitrescu 	char *out,
175964cfcebdSCristian Dumitrescu 	size_t out_size,
1760b9559f94SCristian Dumitrescu 	void *obj __rte_unused)
176164cfcebdSCristian Dumitrescu {
1762b9559f94SCristian Dumitrescu 	struct rte_swx_pipeline *p;
176383f58a7bSCristian Dumitrescu 	struct rte_swx_ctl_pipeline *ctl;
176483f58a7bSCristian Dumitrescu 	const char *pipeline_name, *name;
176564cfcebdSCristian Dumitrescu 	uint64_t value;
176664cfcebdSCristian Dumitrescu 	int status;
176764cfcebdSCristian Dumitrescu 
176883f58a7bSCristian Dumitrescu 	if (n_tokens < 5) {
176964cfcebdSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
177064cfcebdSCristian Dumitrescu 		return;
177164cfcebdSCristian Dumitrescu 	}
177264cfcebdSCristian Dumitrescu 
177383f58a7bSCristian Dumitrescu 	pipeline_name = tokens[1];
177483f58a7bSCristian Dumitrescu 	p = rte_swx_pipeline_find(pipeline_name);
177583f58a7bSCristian Dumitrescu 	ctl = rte_swx_ctl_pipeline_find(pipeline_name);
177683f58a7bSCristian Dumitrescu 	if (!p || !ctl) {
177764cfcebdSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
177864cfcebdSCristian Dumitrescu 		return;
177964cfcebdSCristian Dumitrescu 	}
178064cfcebdSCristian Dumitrescu 
178164cfcebdSCristian Dumitrescu 	if (strcmp(tokens[2], "regrd")) {
178264cfcebdSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "regrd");
178364cfcebdSCristian Dumitrescu 		return;
178464cfcebdSCristian Dumitrescu 	}
178564cfcebdSCristian Dumitrescu 
178664cfcebdSCristian Dumitrescu 	name = tokens[3];
178764cfcebdSCristian Dumitrescu 
178883f58a7bSCristian Dumitrescu 	/* index. */
178983f58a7bSCristian Dumitrescu 	if (!strcmp(tokens[4], "index")) {
1790327820afSAli Alnubani 		uint32_t idx = 0;
179183f58a7bSCristian Dumitrescu 
179283f58a7bSCristian Dumitrescu 		if (n_tokens != 6) {
179383f58a7bSCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
179483f58a7bSCristian Dumitrescu 			return;
179583f58a7bSCristian Dumitrescu 		}
179683f58a7bSCristian Dumitrescu 
179783f58a7bSCristian Dumitrescu 		if (parser_read_uint32(&idx, tokens[5])) {
179864cfcebdSCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_INVALID, "index");
179964cfcebdSCristian Dumitrescu 			return;
180064cfcebdSCristian Dumitrescu 		}
180164cfcebdSCristian Dumitrescu 
1802b9559f94SCristian Dumitrescu 		status = rte_swx_ctl_pipeline_regarray_read(p, name, idx, &value);
180364cfcebdSCristian Dumitrescu 		if (status) {
180464cfcebdSCristian Dumitrescu 			snprintf(out, out_size, "Command failed.\n");
180564cfcebdSCristian Dumitrescu 			return;
180664cfcebdSCristian Dumitrescu 		}
180764cfcebdSCristian Dumitrescu 
180864cfcebdSCristian Dumitrescu 		snprintf(out, out_size, "0x%" PRIx64 "\n", value);
180983f58a7bSCristian Dumitrescu 		return;
181083f58a7bSCristian Dumitrescu 	}
181183f58a7bSCristian Dumitrescu 
181283f58a7bSCristian Dumitrescu 	/* table. */
181383f58a7bSCristian Dumitrescu 	if (!strcmp(tokens[4], "table")) {
181483f58a7bSCristian Dumitrescu 		struct rte_swx_table_entry *entry;
181583f58a7bSCristian Dumitrescu 		char *table_name;
181683f58a7bSCristian Dumitrescu 
181783f58a7bSCristian Dumitrescu 		if (n_tokens < 8) {
181883f58a7bSCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
181983f58a7bSCristian Dumitrescu 			return;
182083f58a7bSCristian Dumitrescu 		}
182183f58a7bSCristian Dumitrescu 
182283f58a7bSCristian Dumitrescu 		table_name = tokens[5];
182383f58a7bSCristian Dumitrescu 
182483f58a7bSCristian Dumitrescu 		if (strcmp(tokens[6], "match")) {
182583f58a7bSCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_NOT_FOUND, "match");
182683f58a7bSCristian Dumitrescu 			return;
182783f58a7bSCristian Dumitrescu 		}
182883f58a7bSCristian Dumitrescu 
182983f58a7bSCristian Dumitrescu 		entry = parse_table_entry(ctl, table_name, &tokens[6], n_tokens - 6);
183083f58a7bSCristian Dumitrescu 		if (!entry) {
183183f58a7bSCristian Dumitrescu 			snprintf(out, out_size, "Invalid match tokens.\n");
183283f58a7bSCristian Dumitrescu 			return;
183383f58a7bSCristian Dumitrescu 		}
183483f58a7bSCristian Dumitrescu 
183583f58a7bSCristian Dumitrescu 		status = rte_swx_ctl_pipeline_regarray_read_with_key(p,
183683f58a7bSCristian Dumitrescu 								     name,
183783f58a7bSCristian Dumitrescu 								     table_name,
183883f58a7bSCristian Dumitrescu 								     entry->key,
183983f58a7bSCristian Dumitrescu 								     &value);
184083f58a7bSCristian Dumitrescu 		table_entry_free(entry);
184183f58a7bSCristian Dumitrescu 		if (status) {
184283f58a7bSCristian Dumitrescu 			snprintf(out, out_size, "Command failed.\n");
184383f58a7bSCristian Dumitrescu 			return;
184483f58a7bSCristian Dumitrescu 		}
184583f58a7bSCristian Dumitrescu 
184683f58a7bSCristian Dumitrescu 		snprintf(out, out_size, "0x%" PRIx64 "\n", value);
184783f58a7bSCristian Dumitrescu 		return;
184883f58a7bSCristian Dumitrescu 	}
184983f58a7bSCristian Dumitrescu 
185083f58a7bSCristian Dumitrescu 	/* anything else. */
185183f58a7bSCristian Dumitrescu 	snprintf(out, out_size, "Invalid token %s\n.", tokens[4]);
185283f58a7bSCristian Dumitrescu 	return;
185364cfcebdSCristian Dumitrescu }
185464cfcebdSCristian Dumitrescu 
185564cfcebdSCristian Dumitrescu static const char cmd_pipeline_regwr_help[] =
185683f58a7bSCristian Dumitrescu "pipeline <pipeline_name> regwr <register_array_name> value <value>\n"
185783f58a7bSCristian Dumitrescu 	"index <index>\n"
185883f58a7bSCristian Dumitrescu 	" | table <table_name> match <field0> ...\n";
185964cfcebdSCristian Dumitrescu 
186064cfcebdSCristian Dumitrescu static void
186164cfcebdSCristian Dumitrescu cmd_pipeline_regwr(char **tokens,
186264cfcebdSCristian Dumitrescu 	uint32_t n_tokens,
186364cfcebdSCristian Dumitrescu 	char *out,
186464cfcebdSCristian Dumitrescu 	size_t out_size,
1865b9559f94SCristian Dumitrescu 	void *obj __rte_unused)
186664cfcebdSCristian Dumitrescu {
1867b9559f94SCristian Dumitrescu 	struct rte_swx_pipeline *p;
186883f58a7bSCristian Dumitrescu 	struct rte_swx_ctl_pipeline *ctl;
186983f58a7bSCristian Dumitrescu 	const char *pipeline_name, *name;
187083f58a7bSCristian Dumitrescu 	uint64_t value = 0;
187164cfcebdSCristian Dumitrescu 	int status;
187264cfcebdSCristian Dumitrescu 
187383f58a7bSCristian Dumitrescu 	if (n_tokens < 7) {
187464cfcebdSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
187564cfcebdSCristian Dumitrescu 		return;
187664cfcebdSCristian Dumitrescu 	}
187764cfcebdSCristian Dumitrescu 
187883f58a7bSCristian Dumitrescu 	pipeline_name = tokens[1];
187983f58a7bSCristian Dumitrescu 	p = rte_swx_pipeline_find(pipeline_name);
188083f58a7bSCristian Dumitrescu 	ctl = rte_swx_ctl_pipeline_find(pipeline_name);
188183f58a7bSCristian Dumitrescu 	if (!p || !ctl) {
188264cfcebdSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
188364cfcebdSCristian Dumitrescu 		return;
188464cfcebdSCristian Dumitrescu 	}
188564cfcebdSCristian Dumitrescu 
188664cfcebdSCristian Dumitrescu 	if (strcmp(tokens[2], "regwr")) {
188764cfcebdSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "regwr");
188864cfcebdSCristian Dumitrescu 		return;
188964cfcebdSCristian Dumitrescu 	}
189064cfcebdSCristian Dumitrescu 
189164cfcebdSCristian Dumitrescu 	name = tokens[3];
189264cfcebdSCristian Dumitrescu 
189383f58a7bSCristian Dumitrescu 	if (strcmp(tokens[4], "value")) {
189483f58a7bSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "value");
189564cfcebdSCristian Dumitrescu 		return;
189664cfcebdSCristian Dumitrescu 	}
189764cfcebdSCristian Dumitrescu 
189864cfcebdSCristian Dumitrescu 	if (parser_read_uint64(&value, tokens[5])) {
189964cfcebdSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "value");
190064cfcebdSCristian Dumitrescu 		return;
190164cfcebdSCristian Dumitrescu 	}
190264cfcebdSCristian Dumitrescu 
190383f58a7bSCristian Dumitrescu 	/* index. */
190483f58a7bSCristian Dumitrescu 	if (!strcmp(tokens[6], "index")) {
1905327820afSAli Alnubani 		uint32_t idx = 0;
190683f58a7bSCristian Dumitrescu 
190783f58a7bSCristian Dumitrescu 		if (n_tokens != 8) {
190883f58a7bSCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
190983f58a7bSCristian Dumitrescu 			return;
191083f58a7bSCristian Dumitrescu 		}
191183f58a7bSCristian Dumitrescu 
191283f58a7bSCristian Dumitrescu 		if (parser_read_uint32(&idx, tokens[7])) {
191383f58a7bSCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_INVALID, "index");
191483f58a7bSCristian Dumitrescu 			return;
191583f58a7bSCristian Dumitrescu 		}
191683f58a7bSCristian Dumitrescu 
1917b9559f94SCristian Dumitrescu 		status = rte_swx_ctl_pipeline_regarray_write(p, name, idx, value);
191864cfcebdSCristian Dumitrescu 		if (status) {
191964cfcebdSCristian Dumitrescu 			snprintf(out, out_size, "Command failed.\n");
192064cfcebdSCristian Dumitrescu 			return;
192164cfcebdSCristian Dumitrescu 		}
192283f58a7bSCristian Dumitrescu 
192383f58a7bSCristian Dumitrescu 		snprintf(out, out_size, "0x%" PRIx64 "\n", value);
192483f58a7bSCristian Dumitrescu 		return;
192583f58a7bSCristian Dumitrescu 	}
192683f58a7bSCristian Dumitrescu 
192783f58a7bSCristian Dumitrescu 	/* table. */
192883f58a7bSCristian Dumitrescu 	if (!strcmp(tokens[6], "table")) {
192983f58a7bSCristian Dumitrescu 		struct rte_swx_table_entry *entry;
193083f58a7bSCristian Dumitrescu 		char *table_name;
193183f58a7bSCristian Dumitrescu 
193283f58a7bSCristian Dumitrescu 		if (n_tokens < 10) {
193383f58a7bSCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
193483f58a7bSCristian Dumitrescu 			return;
193583f58a7bSCristian Dumitrescu 		}
193683f58a7bSCristian Dumitrescu 
193783f58a7bSCristian Dumitrescu 		table_name = tokens[7];
193883f58a7bSCristian Dumitrescu 
193983f58a7bSCristian Dumitrescu 		if (strcmp(tokens[8], "match")) {
194083f58a7bSCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_NOT_FOUND, "match");
194183f58a7bSCristian Dumitrescu 			return;
194283f58a7bSCristian Dumitrescu 		}
194383f58a7bSCristian Dumitrescu 
194483f58a7bSCristian Dumitrescu 		entry = parse_table_entry(ctl, table_name, &tokens[8], n_tokens - 8);
194583f58a7bSCristian Dumitrescu 		if (!entry) {
194683f58a7bSCristian Dumitrescu 			snprintf(out, out_size, "Invalid match tokens.\n");
194783f58a7bSCristian Dumitrescu 			return;
194883f58a7bSCristian Dumitrescu 		}
194983f58a7bSCristian Dumitrescu 
195083f58a7bSCristian Dumitrescu 		status = rte_swx_ctl_pipeline_regarray_write_with_key(p,
195183f58a7bSCristian Dumitrescu 								      name,
195283f58a7bSCristian Dumitrescu 								      table_name,
195383f58a7bSCristian Dumitrescu 								      entry->key,
195483f58a7bSCristian Dumitrescu 								      value);
195583f58a7bSCristian Dumitrescu 		table_entry_free(entry);
195683f58a7bSCristian Dumitrescu 		if (status) {
195783f58a7bSCristian Dumitrescu 			snprintf(out, out_size, "Command failed.\n");
195883f58a7bSCristian Dumitrescu 			return;
195983f58a7bSCristian Dumitrescu 		}
196083f58a7bSCristian Dumitrescu 
196183f58a7bSCristian Dumitrescu 		return;
196283f58a7bSCristian Dumitrescu 	}
196383f58a7bSCristian Dumitrescu 
196483f58a7bSCristian Dumitrescu 	/* anything else. */
196583f58a7bSCristian Dumitrescu 	snprintf(out, out_size, "Invalid token %s\n.", tokens[6]);
196683f58a7bSCristian Dumitrescu 	return;
196764cfcebdSCristian Dumitrescu }
196864cfcebdSCristian Dumitrescu 
1969f38913b7SCristian Dumitrescu static const char cmd_pipeline_meter_profile_add_help[] =
1970f38913b7SCristian Dumitrescu "pipeline <pipeline_name> meter profile <profile_name> add "
1971f38913b7SCristian Dumitrescu 	"cir <cir> pir <pir> cbs <cbs> pbs <pbs>\n";
1972f38913b7SCristian Dumitrescu 
1973f38913b7SCristian Dumitrescu static void
1974f38913b7SCristian Dumitrescu cmd_pipeline_meter_profile_add(char **tokens,
1975f38913b7SCristian Dumitrescu 	uint32_t n_tokens,
1976f38913b7SCristian Dumitrescu 	char *out,
1977f38913b7SCristian Dumitrescu 	size_t out_size,
1978b9559f94SCristian Dumitrescu 	void *obj __rte_unused)
1979f38913b7SCristian Dumitrescu {
1980f38913b7SCristian Dumitrescu 	struct rte_meter_trtcm_params params;
1981b9559f94SCristian Dumitrescu 	struct rte_swx_pipeline *p;
1982f38913b7SCristian Dumitrescu 	const char *profile_name;
1983f38913b7SCristian Dumitrescu 	int status;
1984f38913b7SCristian Dumitrescu 
1985f38913b7SCristian Dumitrescu 	if (n_tokens != 14) {
1986f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1987f38913b7SCristian Dumitrescu 		return;
1988f38913b7SCristian Dumitrescu 	}
1989f38913b7SCristian Dumitrescu 
1990b9559f94SCristian Dumitrescu 	p = rte_swx_pipeline_find(tokens[1]);
1991b9559f94SCristian Dumitrescu 	if (!p) {
1992f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
1993f38913b7SCristian Dumitrescu 		return;
1994f38913b7SCristian Dumitrescu 	}
1995f38913b7SCristian Dumitrescu 
1996f38913b7SCristian Dumitrescu 	if (strcmp(tokens[2], "meter")) {
1997f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "meter");
1998f38913b7SCristian Dumitrescu 		return;
1999f38913b7SCristian Dumitrescu 	}
2000f38913b7SCristian Dumitrescu 
2001f38913b7SCristian Dumitrescu 	if (strcmp(tokens[3], "profile")) {
2002f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "profile");
2003f38913b7SCristian Dumitrescu 		return;
2004f38913b7SCristian Dumitrescu 	}
2005f38913b7SCristian Dumitrescu 
2006f38913b7SCristian Dumitrescu 	profile_name = tokens[4];
2007f38913b7SCristian Dumitrescu 
2008f38913b7SCristian Dumitrescu 	if (strcmp(tokens[5], "add")) {
2009f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "add");
2010f38913b7SCristian Dumitrescu 		return;
2011f38913b7SCristian Dumitrescu 	}
2012f38913b7SCristian Dumitrescu 
2013f38913b7SCristian Dumitrescu 	if (strcmp(tokens[6], "cir")) {
2014f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cir");
2015f38913b7SCristian Dumitrescu 		return;
2016f38913b7SCristian Dumitrescu 	}
2017f38913b7SCristian Dumitrescu 
2018f38913b7SCristian Dumitrescu 	if (parser_read_uint64(&params.cir, tokens[7])) {
2019f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "cir");
2020f38913b7SCristian Dumitrescu 		return;
2021f38913b7SCristian Dumitrescu 	}
2022f38913b7SCristian Dumitrescu 
2023f38913b7SCristian Dumitrescu 	if (strcmp(tokens[8], "pir")) {
2024f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pir");
2025f38913b7SCristian Dumitrescu 		return;
2026f38913b7SCristian Dumitrescu 	}
2027f38913b7SCristian Dumitrescu 
2028f38913b7SCristian Dumitrescu 	if (parser_read_uint64(&params.pir, tokens[9])) {
2029f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pir");
2030f38913b7SCristian Dumitrescu 		return;
2031f38913b7SCristian Dumitrescu 	}
2032f38913b7SCristian Dumitrescu 
2033f38913b7SCristian Dumitrescu 	if (strcmp(tokens[10], "cbs")) {
2034f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cbs");
2035f38913b7SCristian Dumitrescu 		return;
2036f38913b7SCristian Dumitrescu 	}
2037f38913b7SCristian Dumitrescu 
2038f38913b7SCristian Dumitrescu 	if (parser_read_uint64(&params.cbs, tokens[11])) {
2039f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "cbs");
2040f38913b7SCristian Dumitrescu 		return;
2041f38913b7SCristian Dumitrescu 	}
2042f38913b7SCristian Dumitrescu 
2043f38913b7SCristian Dumitrescu 	if (strcmp(tokens[12], "pbs")) {
2044f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pbs");
2045f38913b7SCristian Dumitrescu 		return;
2046f38913b7SCristian Dumitrescu 	}
2047f38913b7SCristian Dumitrescu 
2048f38913b7SCristian Dumitrescu 	if (parser_read_uint64(&params.pbs, tokens[13])) {
2049f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pbs");
2050f38913b7SCristian Dumitrescu 		return;
2051f38913b7SCristian Dumitrescu 	}
2052f38913b7SCristian Dumitrescu 
2053b9559f94SCristian Dumitrescu 	status = rte_swx_ctl_meter_profile_add(p, profile_name, &params);
2054f38913b7SCristian Dumitrescu 	if (status) {
2055f38913b7SCristian Dumitrescu 		snprintf(out, out_size, "Command failed.\n");
2056f38913b7SCristian Dumitrescu 		return;
2057f38913b7SCristian Dumitrescu 	}
2058f38913b7SCristian Dumitrescu }
2059f38913b7SCristian Dumitrescu 
2060f38913b7SCristian Dumitrescu static const char cmd_pipeline_meter_profile_delete_help[] =
2061f38913b7SCristian Dumitrescu "pipeline <pipeline_name> meter profile <profile_name> delete\n";
2062f38913b7SCristian Dumitrescu 
2063f38913b7SCristian Dumitrescu static void
2064f38913b7SCristian Dumitrescu cmd_pipeline_meter_profile_delete(char **tokens,
2065f38913b7SCristian Dumitrescu 	uint32_t n_tokens,
2066f38913b7SCristian Dumitrescu 	char *out,
2067f38913b7SCristian Dumitrescu 	size_t out_size,
2068b9559f94SCristian Dumitrescu 	void *obj __rte_unused)
2069f38913b7SCristian Dumitrescu {
2070b9559f94SCristian Dumitrescu 	struct rte_swx_pipeline *p;
2071f38913b7SCristian Dumitrescu 	const char *profile_name;
2072f38913b7SCristian Dumitrescu 	int status;
2073f38913b7SCristian Dumitrescu 
2074f38913b7SCristian Dumitrescu 	if (n_tokens != 6) {
2075f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2076f38913b7SCristian Dumitrescu 		return;
2077f38913b7SCristian Dumitrescu 	}
2078f38913b7SCristian Dumitrescu 
2079b9559f94SCristian Dumitrescu 	p = rte_swx_pipeline_find(tokens[1]);
2080b9559f94SCristian Dumitrescu 	if (!p) {
2081f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
2082f38913b7SCristian Dumitrescu 		return;
2083f38913b7SCristian Dumitrescu 	}
2084f38913b7SCristian Dumitrescu 
2085f38913b7SCristian Dumitrescu 	if (strcmp(tokens[2], "meter")) {
2086f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "meter");
2087f38913b7SCristian Dumitrescu 		return;
2088f38913b7SCristian Dumitrescu 	}
2089f38913b7SCristian Dumitrescu 
2090f38913b7SCristian Dumitrescu 	if (strcmp(tokens[3], "profile")) {
2091f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "profile");
2092f38913b7SCristian Dumitrescu 		return;
2093f38913b7SCristian Dumitrescu 	}
2094f38913b7SCristian Dumitrescu 
2095f38913b7SCristian Dumitrescu 	profile_name = tokens[4];
2096f38913b7SCristian Dumitrescu 
2097f38913b7SCristian Dumitrescu 	if (strcmp(tokens[5], "delete")) {
2098f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "delete");
2099f38913b7SCristian Dumitrescu 		return;
2100f38913b7SCristian Dumitrescu 	}
2101f38913b7SCristian Dumitrescu 
2102b9559f94SCristian Dumitrescu 	status = rte_swx_ctl_meter_profile_delete(p, profile_name);
2103f38913b7SCristian Dumitrescu 	if (status) {
2104f38913b7SCristian Dumitrescu 		snprintf(out, out_size, "Command failed.\n");
2105f38913b7SCristian Dumitrescu 		return;
2106f38913b7SCristian Dumitrescu 	}
2107f38913b7SCristian Dumitrescu }
2108f38913b7SCristian Dumitrescu 
2109f38913b7SCristian Dumitrescu static const char cmd_pipeline_meter_reset_help[] =
211012eda78dSCristian Dumitrescu "pipeline <pipeline_name> meter <meter_array_name> reset\n"
211112eda78dSCristian Dumitrescu 	"index from <index0> to <index1>\n"
211212eda78dSCristian Dumitrescu 	" | table <table_name> match <field0> ...\n";
2113f38913b7SCristian Dumitrescu 
2114f38913b7SCristian Dumitrescu static void
2115f38913b7SCristian Dumitrescu cmd_pipeline_meter_reset(char **tokens,
2116f38913b7SCristian Dumitrescu 	uint32_t n_tokens,
2117f38913b7SCristian Dumitrescu 	char *out,
2118f38913b7SCristian Dumitrescu 	size_t out_size,
2119b9559f94SCristian Dumitrescu 	void *obj __rte_unused)
2120f38913b7SCristian Dumitrescu {
2121b9559f94SCristian Dumitrescu 	struct rte_swx_pipeline *p;
212212eda78dSCristian Dumitrescu 	struct rte_swx_ctl_pipeline *ctl;
212312eda78dSCristian Dumitrescu 	const char *pipeline_name, *name;
2124f38913b7SCristian Dumitrescu 
212512eda78dSCristian Dumitrescu 	if (n_tokens < 6) {
2126f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2127f38913b7SCristian Dumitrescu 		return;
2128f38913b7SCristian Dumitrescu 	}
2129f38913b7SCristian Dumitrescu 
213012eda78dSCristian Dumitrescu 	pipeline_name = tokens[1];
213112eda78dSCristian Dumitrescu 	p = rte_swx_pipeline_find(pipeline_name);
213212eda78dSCristian Dumitrescu 	ctl = rte_swx_ctl_pipeline_find(pipeline_name);
213312eda78dSCristian Dumitrescu 	if (!p || !ctl) {
2134f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
2135f38913b7SCristian Dumitrescu 		return;
2136f38913b7SCristian Dumitrescu 	}
2137f38913b7SCristian Dumitrescu 
2138f38913b7SCristian Dumitrescu 	if (strcmp(tokens[2], "meter")) {
2139f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "meter");
2140f38913b7SCristian Dumitrescu 		return;
2141f38913b7SCristian Dumitrescu 	}
2142f38913b7SCristian Dumitrescu 
2143f38913b7SCristian Dumitrescu 	name = tokens[3];
2144f38913b7SCristian Dumitrescu 
214512eda78dSCristian Dumitrescu 	if (strcmp(tokens[4], "reset")) {
214612eda78dSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "reset");
214712eda78dSCristian Dumitrescu 		return;
214812eda78dSCristian Dumitrescu 	}
214912eda78dSCristian Dumitrescu 
215012eda78dSCristian Dumitrescu 	/* index. */
215112eda78dSCristian Dumitrescu 	if (!strcmp(tokens[5], "index")) {
215212eda78dSCristian Dumitrescu 		uint32_t idx0 = 0, idx1 = 0;
215312eda78dSCristian Dumitrescu 
215412eda78dSCristian Dumitrescu 		if (n_tokens != 10) {
215512eda78dSCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
215612eda78dSCristian Dumitrescu 			return;
215712eda78dSCristian Dumitrescu 		}
215812eda78dSCristian Dumitrescu 
215912eda78dSCristian Dumitrescu 		if (strcmp(tokens[6], "from")) {
2160f38913b7SCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_NOT_FOUND, "from");
2161f38913b7SCristian Dumitrescu 			return;
2162f38913b7SCristian Dumitrescu 		}
2163f38913b7SCristian Dumitrescu 
216412eda78dSCristian Dumitrescu 		if (parser_read_uint32(&idx0, tokens[7])) {
2165f38913b7SCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_INVALID, "index0");
2166f38913b7SCristian Dumitrescu 			return;
2167f38913b7SCristian Dumitrescu 		}
2168f38913b7SCristian Dumitrescu 
216912eda78dSCristian Dumitrescu 		if (strcmp(tokens[8], "to")) {
2170f38913b7SCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_NOT_FOUND, "to");
2171f38913b7SCristian Dumitrescu 			return;
2172f38913b7SCristian Dumitrescu 		}
2173f38913b7SCristian Dumitrescu 
217412eda78dSCristian Dumitrescu 		if (parser_read_uint32(&idx1, tokens[9]) || (idx1 < idx0)) {
2175f38913b7SCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_INVALID, "index1");
2176f38913b7SCristian Dumitrescu 			return;
2177f38913b7SCristian Dumitrescu 		}
2178f38913b7SCristian Dumitrescu 
2179f38913b7SCristian Dumitrescu 		for ( ; idx0 <= idx1; idx0++) {
2180f38913b7SCristian Dumitrescu 			int status;
2181f38913b7SCristian Dumitrescu 
2182b9559f94SCristian Dumitrescu 			status = rte_swx_ctl_meter_reset(p, name, idx0);
2183f38913b7SCristian Dumitrescu 			if (status) {
2184f38913b7SCristian Dumitrescu 				snprintf(out, out_size, "Command failed for index %u.\n", idx0);
2185f38913b7SCristian Dumitrescu 				return;
2186f38913b7SCristian Dumitrescu 			}
2187f38913b7SCristian Dumitrescu 		}
218812eda78dSCristian Dumitrescu 
218912eda78dSCristian Dumitrescu 		return;
219012eda78dSCristian Dumitrescu 	}
219112eda78dSCristian Dumitrescu 
219212eda78dSCristian Dumitrescu 	/* table. */
219312eda78dSCristian Dumitrescu 	if (!strcmp(tokens[5], "table")) {
219412eda78dSCristian Dumitrescu 		struct rte_swx_table_entry *entry;
219512eda78dSCristian Dumitrescu 		char *table_name;
219612eda78dSCristian Dumitrescu 		int status;
219712eda78dSCristian Dumitrescu 
219812eda78dSCristian Dumitrescu 		if (n_tokens < 9) {
219912eda78dSCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
220012eda78dSCristian Dumitrescu 			return;
220112eda78dSCristian Dumitrescu 		}
220212eda78dSCristian Dumitrescu 
220312eda78dSCristian Dumitrescu 		table_name = tokens[6];
220412eda78dSCristian Dumitrescu 
220512eda78dSCristian Dumitrescu 		if (strcmp(tokens[7], "match")) {
220612eda78dSCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_NOT_FOUND, "match");
220712eda78dSCristian Dumitrescu 			return;
220812eda78dSCristian Dumitrescu 		}
220912eda78dSCristian Dumitrescu 
221012eda78dSCristian Dumitrescu 		entry = parse_table_entry(ctl, table_name, &tokens[7], n_tokens - 7);
221112eda78dSCristian Dumitrescu 		if (!entry) {
221212eda78dSCristian Dumitrescu 			snprintf(out, out_size, "Invalid match tokens.\n");
221312eda78dSCristian Dumitrescu 			return;
221412eda78dSCristian Dumitrescu 		}
221512eda78dSCristian Dumitrescu 
221612eda78dSCristian Dumitrescu 		status = rte_swx_ctl_meter_reset_with_key(p, name, table_name, entry->key);
221712eda78dSCristian Dumitrescu 		table_entry_free(entry);
221812eda78dSCristian Dumitrescu 		if (status) {
221912eda78dSCristian Dumitrescu 			snprintf(out, out_size, "Command failed.\n");
222012eda78dSCristian Dumitrescu 			return;
222112eda78dSCristian Dumitrescu 		}
222212eda78dSCristian Dumitrescu 
222312eda78dSCristian Dumitrescu 		return;
222412eda78dSCristian Dumitrescu 	}
222512eda78dSCristian Dumitrescu 
222612eda78dSCristian Dumitrescu 	/* anything else. */
222712eda78dSCristian Dumitrescu 	snprintf(out, out_size, "Invalid token %s\n.", tokens[5]);
222812eda78dSCristian Dumitrescu 	return;
2229f38913b7SCristian Dumitrescu }
2230f38913b7SCristian Dumitrescu 
2231f38913b7SCristian Dumitrescu static const char cmd_pipeline_meter_set_help[] =
223212eda78dSCristian Dumitrescu "pipeline <pipeline_name> meter <meter_array_name> set profile <profile_name>\n"
223312eda78dSCristian Dumitrescu 	"index from <index0> to <index1>\n"
223412eda78dSCristian Dumitrescu 	" | table <table_name> match <field0> ...\n";
2235f38913b7SCristian Dumitrescu 
2236f38913b7SCristian Dumitrescu static void
2237f38913b7SCristian Dumitrescu cmd_pipeline_meter_set(char **tokens,
2238f38913b7SCristian Dumitrescu 	uint32_t n_tokens,
2239f38913b7SCristian Dumitrescu 	char *out,
2240f38913b7SCristian Dumitrescu 	size_t out_size,
2241b9559f94SCristian Dumitrescu 	void *obj __rte_unused)
2242f38913b7SCristian Dumitrescu {
2243b9559f94SCristian Dumitrescu 	struct rte_swx_pipeline *p;
224412eda78dSCristian Dumitrescu 	struct rte_swx_ctl_pipeline *ctl;
224512eda78dSCristian Dumitrescu 	const char *pipeline_name, *name, *profile_name;
2246f38913b7SCristian Dumitrescu 
224712eda78dSCristian Dumitrescu 	if (n_tokens < 8) {
2248f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2249f38913b7SCristian Dumitrescu 		return;
2250f38913b7SCristian Dumitrescu 	}
2251f38913b7SCristian Dumitrescu 
225212eda78dSCristian Dumitrescu 	pipeline_name = tokens[1];
225312eda78dSCristian Dumitrescu 	p = rte_swx_pipeline_find(pipeline_name);
225412eda78dSCristian Dumitrescu 	ctl = rte_swx_ctl_pipeline_find(pipeline_name);
225512eda78dSCristian Dumitrescu 	if (!p || !ctl) {
2256f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
2257f38913b7SCristian Dumitrescu 		return;
2258f38913b7SCristian Dumitrescu 	}
2259f38913b7SCristian Dumitrescu 
2260f38913b7SCristian Dumitrescu 	if (strcmp(tokens[2], "meter")) {
2261f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "meter");
2262f38913b7SCristian Dumitrescu 		return;
2263f38913b7SCristian Dumitrescu 	}
2264f38913b7SCristian Dumitrescu 
2265f38913b7SCristian Dumitrescu 	name = tokens[3];
2266f38913b7SCristian Dumitrescu 
226712eda78dSCristian Dumitrescu 	if (strcmp(tokens[4], "set")) {
2268f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "set");
2269f38913b7SCristian Dumitrescu 		return;
2270f38913b7SCristian Dumitrescu 	}
2271f38913b7SCristian Dumitrescu 
227212eda78dSCristian Dumitrescu 	if (strcmp(tokens[5], "profile")) {
2273f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "profile");
2274f38913b7SCristian Dumitrescu 		return;
2275f38913b7SCristian Dumitrescu 	}
2276f38913b7SCristian Dumitrescu 
227712eda78dSCristian Dumitrescu 	profile_name = tokens[6];
227812eda78dSCristian Dumitrescu 
227912eda78dSCristian Dumitrescu 	/* index. */
228012eda78dSCristian Dumitrescu 	if (!strcmp(tokens[7], "index")) {
228112eda78dSCristian Dumitrescu 		uint32_t idx0 = 0, idx1 = 0;
228212eda78dSCristian Dumitrescu 
228312eda78dSCristian Dumitrescu 		if (n_tokens != 12) {
228412eda78dSCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
228512eda78dSCristian Dumitrescu 			return;
228612eda78dSCristian Dumitrescu 		}
228712eda78dSCristian Dumitrescu 
228812eda78dSCristian Dumitrescu 		if (strcmp(tokens[8], "from")) {
228912eda78dSCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_NOT_FOUND, "from");
229012eda78dSCristian Dumitrescu 			return;
229112eda78dSCristian Dumitrescu 		}
229212eda78dSCristian Dumitrescu 
229312eda78dSCristian Dumitrescu 		if (parser_read_uint32(&idx0, tokens[9])) {
229412eda78dSCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_INVALID, "index0");
229512eda78dSCristian Dumitrescu 			return;
229612eda78dSCristian Dumitrescu 		}
229712eda78dSCristian Dumitrescu 
229812eda78dSCristian Dumitrescu 		if (strcmp(tokens[10], "to")) {
229912eda78dSCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_NOT_FOUND, "to");
230012eda78dSCristian Dumitrescu 			return;
230112eda78dSCristian Dumitrescu 		}
230212eda78dSCristian Dumitrescu 
230312eda78dSCristian Dumitrescu 		if (parser_read_uint32(&idx1, tokens[11]) || (idx1 < idx0)) {
230412eda78dSCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_INVALID, "index1");
230512eda78dSCristian Dumitrescu 			return;
230612eda78dSCristian Dumitrescu 		}
2307f38913b7SCristian Dumitrescu 
2308f38913b7SCristian Dumitrescu 		for ( ; idx0 <= idx1; idx0++) {
2309f38913b7SCristian Dumitrescu 			int status;
2310f38913b7SCristian Dumitrescu 
2311b9559f94SCristian Dumitrescu 			status = rte_swx_ctl_meter_set(p, name, idx0, profile_name);
2312f38913b7SCristian Dumitrescu 			if (status) {
2313f38913b7SCristian Dumitrescu 				snprintf(out, out_size, "Command failed for index %u.\n", idx0);
2314f38913b7SCristian Dumitrescu 				return;
2315f38913b7SCristian Dumitrescu 			}
2316f38913b7SCristian Dumitrescu 		}
231712eda78dSCristian Dumitrescu 
231812eda78dSCristian Dumitrescu 		return;
231912eda78dSCristian Dumitrescu 	}
232012eda78dSCristian Dumitrescu 
232112eda78dSCristian Dumitrescu 	/* table. */
232212eda78dSCristian Dumitrescu 	if (!strcmp(tokens[7], "table")) {
232312eda78dSCristian Dumitrescu 		struct rte_swx_table_entry *entry;
232412eda78dSCristian Dumitrescu 		char *table_name;
232512eda78dSCristian Dumitrescu 		int status;
232612eda78dSCristian Dumitrescu 
232712eda78dSCristian Dumitrescu 		if (n_tokens < 11) {
232812eda78dSCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
232912eda78dSCristian Dumitrescu 			return;
233012eda78dSCristian Dumitrescu 		}
233112eda78dSCristian Dumitrescu 
233212eda78dSCristian Dumitrescu 		table_name = tokens[8];
233312eda78dSCristian Dumitrescu 
233412eda78dSCristian Dumitrescu 		if (strcmp(tokens[9], "match")) {
233512eda78dSCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_NOT_FOUND, "match");
233612eda78dSCristian Dumitrescu 			return;
233712eda78dSCristian Dumitrescu 		}
233812eda78dSCristian Dumitrescu 
233912eda78dSCristian Dumitrescu 		entry = parse_table_entry(ctl, table_name, &tokens[9], n_tokens - 9);
234012eda78dSCristian Dumitrescu 		if (!entry) {
234112eda78dSCristian Dumitrescu 			snprintf(out, out_size, "Invalid match tokens.\n");
234212eda78dSCristian Dumitrescu 			return;
234312eda78dSCristian Dumitrescu 		}
234412eda78dSCristian Dumitrescu 
234512eda78dSCristian Dumitrescu 		status = rte_swx_ctl_meter_set_with_key(p,
234612eda78dSCristian Dumitrescu 							name,
234712eda78dSCristian Dumitrescu 							table_name,
234812eda78dSCristian Dumitrescu 							entry->key,
234912eda78dSCristian Dumitrescu 							profile_name);
235012eda78dSCristian Dumitrescu 		table_entry_free(entry);
235112eda78dSCristian Dumitrescu 		if (status) {
235212eda78dSCristian Dumitrescu 			snprintf(out, out_size, "Command failed.\n");
235312eda78dSCristian Dumitrescu 			return;
235412eda78dSCristian Dumitrescu 		}
235512eda78dSCristian Dumitrescu 
235612eda78dSCristian Dumitrescu 		return;
235712eda78dSCristian Dumitrescu 	}
235812eda78dSCristian Dumitrescu 
235912eda78dSCristian Dumitrescu 	/* anything else. */
236012eda78dSCristian Dumitrescu 	snprintf(out, out_size, "Invalid token %s\n.", tokens[7]);
236112eda78dSCristian Dumitrescu 	return;
2362f38913b7SCristian Dumitrescu }
2363f38913b7SCristian Dumitrescu 
2364f38913b7SCristian Dumitrescu static const char cmd_pipeline_meter_stats_help[] =
236512eda78dSCristian Dumitrescu "pipeline <pipeline_name> meter <meter_array_name> stats\n"
236612eda78dSCristian Dumitrescu 	"index from <index0> to <index1>\n"
236712eda78dSCristian Dumitrescu 	" | table <table_name> match <field0> ...\n";
2368f38913b7SCristian Dumitrescu 
2369f38913b7SCristian Dumitrescu static void
2370f38913b7SCristian Dumitrescu cmd_pipeline_meter_stats(char **tokens,
2371f38913b7SCristian Dumitrescu 	uint32_t n_tokens,
2372f38913b7SCristian Dumitrescu 	char *out,
2373f38913b7SCristian Dumitrescu 	size_t out_size,
2374b9559f94SCristian Dumitrescu 	void *obj __rte_unused)
2375f38913b7SCristian Dumitrescu {
2376f38913b7SCristian Dumitrescu 	struct rte_swx_ctl_meter_stats stats;
2377b9559f94SCristian Dumitrescu 	struct rte_swx_pipeline *p;
237812eda78dSCristian Dumitrescu 	struct rte_swx_ctl_pipeline *ctl;
237912eda78dSCristian Dumitrescu 	const char *pipeline_name, *name;
2380f38913b7SCristian Dumitrescu 
238112eda78dSCristian Dumitrescu 	if (n_tokens < 6) {
2382f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2383f38913b7SCristian Dumitrescu 		return;
2384f38913b7SCristian Dumitrescu 	}
2385f38913b7SCristian Dumitrescu 
238612eda78dSCristian Dumitrescu 	pipeline_name = tokens[1];
238712eda78dSCristian Dumitrescu 	p = rte_swx_pipeline_find(pipeline_name);
238812eda78dSCristian Dumitrescu 	ctl = rte_swx_ctl_pipeline_find(pipeline_name);
238912eda78dSCristian Dumitrescu 	if (!p || !ctl) {
2390f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
2391f38913b7SCristian Dumitrescu 		return;
2392f38913b7SCristian Dumitrescu 	}
2393f38913b7SCristian Dumitrescu 
2394f38913b7SCristian Dumitrescu 	if (strcmp(tokens[2], "meter")) {
2395f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "meter");
2396f38913b7SCristian Dumitrescu 		return;
2397f38913b7SCristian Dumitrescu 	}
2398f38913b7SCristian Dumitrescu 
2399f38913b7SCristian Dumitrescu 	name = tokens[3];
2400f38913b7SCristian Dumitrescu 
240112eda78dSCristian Dumitrescu 	if (strcmp(tokens[4], "stats")) {
240212eda78dSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "stats");
240312eda78dSCristian Dumitrescu 		return;
240412eda78dSCristian Dumitrescu 	}
240512eda78dSCristian Dumitrescu 
240612eda78dSCristian Dumitrescu 	/* index. */
240712eda78dSCristian Dumitrescu 	if (!strcmp(tokens[5], "index")) {
240812eda78dSCristian Dumitrescu 		uint32_t idx0 = 0, idx1 = 0;
240912eda78dSCristian Dumitrescu 
241012eda78dSCristian Dumitrescu 		if (n_tokens != 10) {
241112eda78dSCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
241212eda78dSCristian Dumitrescu 			return;
241312eda78dSCristian Dumitrescu 		}
241412eda78dSCristian Dumitrescu 
241512eda78dSCristian Dumitrescu 		if (strcmp(tokens[6], "from")) {
2416f38913b7SCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_NOT_FOUND, "from");
2417f38913b7SCristian Dumitrescu 			return;
2418f38913b7SCristian Dumitrescu 		}
2419f38913b7SCristian Dumitrescu 
242012eda78dSCristian Dumitrescu 		if (parser_read_uint32(&idx0, tokens[7])) {
2421f38913b7SCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_INVALID, "index0");
2422f38913b7SCristian Dumitrescu 			return;
2423f38913b7SCristian Dumitrescu 		}
2424f38913b7SCristian Dumitrescu 
242512eda78dSCristian Dumitrescu 		if (strcmp(tokens[8], "to")) {
2426f38913b7SCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_NOT_FOUND, "to");
2427f38913b7SCristian Dumitrescu 			return;
2428f38913b7SCristian Dumitrescu 		}
2429f38913b7SCristian Dumitrescu 
243012eda78dSCristian Dumitrescu 		if (parser_read_uint32(&idx1, tokens[9]) || (idx1 < idx0)) {
2431f38913b7SCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_INVALID, "index1");
2432f38913b7SCristian Dumitrescu 			return;
2433f38913b7SCristian Dumitrescu 		}
2434f38913b7SCristian Dumitrescu 
2435f38913b7SCristian Dumitrescu 		/* Table header. */
2436f38913b7SCristian Dumitrescu 		snprintf(out, out_size, "+-%7s-+-%16s-+-%16s-+-%16s-+-%16s-+-%16s-+-%16s-+\n",
2437f38913b7SCristian Dumitrescu 			 "-------",
2438f38913b7SCristian Dumitrescu 			 "----------------", "----------------", "----------------",
2439f38913b7SCristian Dumitrescu 			 "----------------", "----------------", "----------------");
2440f38913b7SCristian Dumitrescu 		out_size -= strlen(out);
2441f38913b7SCristian Dumitrescu 		out += strlen(out);
2442f38913b7SCristian Dumitrescu 
2443f38913b7SCristian Dumitrescu 		snprintf(out, out_size, "| %4s | %16s | %16s | %16s | %16s | %16s | %16s |\n",
2444f38913b7SCristian Dumitrescu 			 "METER #",
2445f38913b7SCristian Dumitrescu 			 "GREEN (packets)", "YELLOW (packets)", "RED (packets)",
2446f38913b7SCristian Dumitrescu 			 "GREEN (bytes)", "YELLOW (bytes)", "RED (bytes)");
2447f38913b7SCristian Dumitrescu 		out_size -= strlen(out);
2448f38913b7SCristian Dumitrescu 		out += strlen(out);
2449f38913b7SCristian Dumitrescu 
2450f38913b7SCristian Dumitrescu 		snprintf(out, out_size, "+-%7s-+-%16s-+-%16s-+-%16s-+-%16s-+-%16s-+-%16s-+\n",
2451f38913b7SCristian Dumitrescu 			 "-------",
2452f38913b7SCristian Dumitrescu 			 "----------------", "----------------", "----------------",
2453f38913b7SCristian Dumitrescu 			 "----------------", "----------------", "----------------");
2454f38913b7SCristian Dumitrescu 		out_size -= strlen(out);
2455f38913b7SCristian Dumitrescu 		out += strlen(out);
2456f38913b7SCristian Dumitrescu 
2457f38913b7SCristian Dumitrescu 		/* Table rows. */
2458f38913b7SCristian Dumitrescu 		for ( ; idx0 <= idx1; idx0++) {
2459f38913b7SCristian Dumitrescu 			int status;
2460f38913b7SCristian Dumitrescu 
2461b9559f94SCristian Dumitrescu 			status = rte_swx_ctl_meter_stats_read(p, name, idx0, &stats);
2462f38913b7SCristian Dumitrescu 			if (status) {
246312eda78dSCristian Dumitrescu 				snprintf(out, out_size, "Meter stats error at index %u.\n", idx0);
2464f38913b7SCristian Dumitrescu 				out_size -= strlen(out);
2465f38913b7SCristian Dumitrescu 				out += strlen(out);
2466f38913b7SCristian Dumitrescu 				return;
2467f38913b7SCristian Dumitrescu 			}
2468f38913b7SCristian Dumitrescu 
2469f38913b7SCristian Dumitrescu 			snprintf(out, out_size, "| %7d | %16" PRIx64 " | %16" PRIx64 " | %16" PRIx64
2470f38913b7SCristian Dumitrescu 				 " | %16" PRIx64 " | %16" PRIx64 " | %16" PRIx64 " |\n",
2471f38913b7SCristian Dumitrescu 				 idx0,
2472f38913b7SCristian Dumitrescu 				 stats.n_pkts[RTE_COLOR_GREEN],
2473f38913b7SCristian Dumitrescu 				 stats.n_pkts[RTE_COLOR_YELLOW],
2474f38913b7SCristian Dumitrescu 				 stats.n_pkts[RTE_COLOR_RED],
2475f38913b7SCristian Dumitrescu 				 stats.n_bytes[RTE_COLOR_GREEN],
2476f38913b7SCristian Dumitrescu 				 stats.n_bytes[RTE_COLOR_YELLOW],
2477f38913b7SCristian Dumitrescu 				 stats.n_bytes[RTE_COLOR_RED]);
2478f38913b7SCristian Dumitrescu 			out_size -= strlen(out);
2479f38913b7SCristian Dumitrescu 			out += strlen(out);
2480f38913b7SCristian Dumitrescu 		}
248112eda78dSCristian Dumitrescu 
248212eda78dSCristian Dumitrescu 		return;
248312eda78dSCristian Dumitrescu 	}
248412eda78dSCristian Dumitrescu 
248512eda78dSCristian Dumitrescu 	/* table. */
248612eda78dSCristian Dumitrescu 	if (!strcmp(tokens[5], "table")) {
248712eda78dSCristian Dumitrescu 		struct rte_swx_table_entry *entry;
248812eda78dSCristian Dumitrescu 		char *table_name;
248912eda78dSCristian Dumitrescu 		int status;
249012eda78dSCristian Dumitrescu 
249112eda78dSCristian Dumitrescu 		if (n_tokens < 9) {
249212eda78dSCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
249312eda78dSCristian Dumitrescu 			return;
249412eda78dSCristian Dumitrescu 		}
249512eda78dSCristian Dumitrescu 
249612eda78dSCristian Dumitrescu 		table_name = tokens[6];
249712eda78dSCristian Dumitrescu 
249812eda78dSCristian Dumitrescu 		if (strcmp(tokens[7], "match")) {
249912eda78dSCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_NOT_FOUND, "match");
250012eda78dSCristian Dumitrescu 			return;
250112eda78dSCristian Dumitrescu 		}
250212eda78dSCristian Dumitrescu 
250312eda78dSCristian Dumitrescu 		entry = parse_table_entry(ctl, table_name, &tokens[7], n_tokens - 7);
250412eda78dSCristian Dumitrescu 		if (!entry) {
250512eda78dSCristian Dumitrescu 			snprintf(out, out_size, "Invalid match tokens.\n");
250612eda78dSCristian Dumitrescu 			return;
250712eda78dSCristian Dumitrescu 		}
250812eda78dSCristian Dumitrescu 
250912eda78dSCristian Dumitrescu 		status = rte_swx_ctl_meter_stats_read_with_key(p,
251012eda78dSCristian Dumitrescu 							name,
251112eda78dSCristian Dumitrescu 							table_name,
251212eda78dSCristian Dumitrescu 							entry->key,
251312eda78dSCristian Dumitrescu 							&stats);
251412eda78dSCristian Dumitrescu 		table_entry_free(entry);
251512eda78dSCristian Dumitrescu 		if (status) {
251612eda78dSCristian Dumitrescu 			snprintf(out, out_size, "Command failed.\n");
251712eda78dSCristian Dumitrescu 			return;
251812eda78dSCristian Dumitrescu 		}
251912eda78dSCristian Dumitrescu 
252012eda78dSCristian Dumitrescu 		/* Table header. */
252112eda78dSCristian Dumitrescu 		snprintf(out, out_size, "+-%7s-+-%16s-+-%16s-+-%16s-+-%16s-+-%16s-+-%16s-+\n",
252212eda78dSCristian Dumitrescu 			 "-------",
252312eda78dSCristian Dumitrescu 			 "----------------", "----------------", "----------------",
252412eda78dSCristian Dumitrescu 			 "----------------", "----------------", "----------------");
252512eda78dSCristian Dumitrescu 		out_size -= strlen(out);
252612eda78dSCristian Dumitrescu 		out += strlen(out);
252712eda78dSCristian Dumitrescu 
252812eda78dSCristian Dumitrescu 		snprintf(out, out_size, "| %4s | %16s | %16s | %16s | %16s | %16s | %16s |\n",
252912eda78dSCristian Dumitrescu 			 "METER #",
253012eda78dSCristian Dumitrescu 			 "GREEN (packets)", "YELLOW (packets)", "RED (packets)",
253112eda78dSCristian Dumitrescu 			 "GREEN (bytes)", "YELLOW (bytes)", "RED (bytes)");
253212eda78dSCristian Dumitrescu 		out_size -= strlen(out);
253312eda78dSCristian Dumitrescu 		out += strlen(out);
253412eda78dSCristian Dumitrescu 
253512eda78dSCristian Dumitrescu 		snprintf(out, out_size, "+-%7s-+-%16s-+-%16s-+-%16s-+-%16s-+-%16s-+-%16s-+\n",
253612eda78dSCristian Dumitrescu 			 "-------",
253712eda78dSCristian Dumitrescu 			 "----------------", "----------------", "----------------",
253812eda78dSCristian Dumitrescu 			 "----------------", "----------------", "----------------");
253912eda78dSCristian Dumitrescu 		out_size -= strlen(out);
254012eda78dSCristian Dumitrescu 		out += strlen(out);
254112eda78dSCristian Dumitrescu 
254212eda78dSCristian Dumitrescu 		/* Table row. */
254312eda78dSCristian Dumitrescu 		snprintf(out, out_size, "| %7d | %16" PRIx64 " | %16" PRIx64 " | %16" PRIx64
254412eda78dSCristian Dumitrescu 			 " | %16" PRIx64 " | %16" PRIx64 " | %16" PRIx64 " |\n",
254512eda78dSCristian Dumitrescu 			 0,
254612eda78dSCristian Dumitrescu 			 stats.n_pkts[RTE_COLOR_GREEN],
254712eda78dSCristian Dumitrescu 			 stats.n_pkts[RTE_COLOR_YELLOW],
254812eda78dSCristian Dumitrescu 			 stats.n_pkts[RTE_COLOR_RED],
254912eda78dSCristian Dumitrescu 			 stats.n_bytes[RTE_COLOR_GREEN],
255012eda78dSCristian Dumitrescu 			 stats.n_bytes[RTE_COLOR_YELLOW],
255112eda78dSCristian Dumitrescu 			 stats.n_bytes[RTE_COLOR_RED]);
255212eda78dSCristian Dumitrescu 		out_size -= strlen(out);
255312eda78dSCristian Dumitrescu 		out += strlen(out);
255412eda78dSCristian Dumitrescu 
255512eda78dSCristian Dumitrescu 		return;
255612eda78dSCristian Dumitrescu 	}
255712eda78dSCristian Dumitrescu 
255812eda78dSCristian Dumitrescu 	/* anything else. */
255912eda78dSCristian Dumitrescu 	snprintf(out, out_size, "Invalid token %s\n.", tokens[5]);
256012eda78dSCristian Dumitrescu 	return;
2561f38913b7SCristian Dumitrescu }
2562f38913b7SCristian Dumitrescu 
25635074e1d5SCristian Dumitrescu static const char cmd_pipeline_stats_help[] =
25645074e1d5SCristian Dumitrescu "pipeline <pipeline_name> stats\n";
25655074e1d5SCristian Dumitrescu 
25665074e1d5SCristian Dumitrescu static void
25675074e1d5SCristian Dumitrescu cmd_pipeline_stats(char **tokens,
25685074e1d5SCristian Dumitrescu 	uint32_t n_tokens,
25695074e1d5SCristian Dumitrescu 	char *out,
25705074e1d5SCristian Dumitrescu 	size_t out_size,
2571b9559f94SCristian Dumitrescu 	void *obj __rte_unused)
25725074e1d5SCristian Dumitrescu {
25735074e1d5SCristian Dumitrescu 	struct rte_swx_ctl_pipeline_info info;
2574b9559f94SCristian Dumitrescu 	struct rte_swx_pipeline *p;
25755074e1d5SCristian Dumitrescu 	uint32_t i;
25765074e1d5SCristian Dumitrescu 	int status;
25775074e1d5SCristian Dumitrescu 
25785074e1d5SCristian Dumitrescu 	if (n_tokens != 3) {
25795074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
25805074e1d5SCristian Dumitrescu 		return;
25815074e1d5SCristian Dumitrescu 	}
25825074e1d5SCristian Dumitrescu 
2583b9559f94SCristian Dumitrescu 	p = rte_swx_pipeline_find(tokens[1]);
2584b9559f94SCristian Dumitrescu 	if (!p) {
25855074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
25865074e1d5SCristian Dumitrescu 		return;
25875074e1d5SCristian Dumitrescu 	}
25885074e1d5SCristian Dumitrescu 
25895074e1d5SCristian Dumitrescu 	if (strcmp(tokens[2], "stats")) {
25905074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "stats");
25915074e1d5SCristian Dumitrescu 		return;
25925074e1d5SCristian Dumitrescu 	}
25935074e1d5SCristian Dumitrescu 
2594b9559f94SCristian Dumitrescu 	status = rte_swx_ctl_pipeline_info_get(p, &info);
25955074e1d5SCristian Dumitrescu 	if (status) {
25965074e1d5SCristian Dumitrescu 		snprintf(out, out_size, "Pipeline info get error.");
25975074e1d5SCristian Dumitrescu 		return;
25985074e1d5SCristian Dumitrescu 	}
25995074e1d5SCristian Dumitrescu 
26005074e1d5SCristian Dumitrescu 	snprintf(out, out_size, "Input ports:\n");
26015074e1d5SCristian Dumitrescu 	out_size -= strlen(out);
26025074e1d5SCristian Dumitrescu 	out += strlen(out);
26035074e1d5SCristian Dumitrescu 
26045074e1d5SCristian Dumitrescu 	for (i = 0; i < info.n_ports_in; i++) {
26055074e1d5SCristian Dumitrescu 		struct rte_swx_port_in_stats stats;
26065074e1d5SCristian Dumitrescu 
2607b9559f94SCristian Dumitrescu 		rte_swx_ctl_pipeline_port_in_stats_read(p, i, &stats);
26085074e1d5SCristian Dumitrescu 
26095074e1d5SCristian Dumitrescu 		snprintf(out, out_size, "\tPort %u:"
26105074e1d5SCristian Dumitrescu 			" packets %" PRIu64
26115074e1d5SCristian Dumitrescu 			" bytes %" PRIu64
26125074e1d5SCristian Dumitrescu 			" empty %" PRIu64 "\n",
26135074e1d5SCristian Dumitrescu 			i, stats.n_pkts, stats.n_bytes, stats.n_empty);
26145074e1d5SCristian Dumitrescu 		out_size -= strlen(out);
26155074e1d5SCristian Dumitrescu 		out += strlen(out);
26165074e1d5SCristian Dumitrescu 	}
26175074e1d5SCristian Dumitrescu 
2618742b0a57SCristian Dumitrescu 	snprintf(out, out_size, "\nOutput ports:\n");
26195074e1d5SCristian Dumitrescu 	out_size -= strlen(out);
26205074e1d5SCristian Dumitrescu 	out += strlen(out);
26215074e1d5SCristian Dumitrescu 
26225074e1d5SCristian Dumitrescu 	for (i = 0; i < info.n_ports_out; i++) {
26235074e1d5SCristian Dumitrescu 		struct rte_swx_port_out_stats stats;
26245074e1d5SCristian Dumitrescu 
2625b9559f94SCristian Dumitrescu 		rte_swx_ctl_pipeline_port_out_stats_read(p, i, &stats);
26265074e1d5SCristian Dumitrescu 
262796b37959SCristian Dumitrescu 		if (i != info.n_ports_out - 1)
262817225455SCristian Dumitrescu 			snprintf(out, out_size, "\tPort %u:", i);
262996b37959SCristian Dumitrescu 		else
263017225455SCristian Dumitrescu 			snprintf(out, out_size, "\tDROP:");
263117225455SCristian Dumitrescu 
263217225455SCristian Dumitrescu 		out_size -= strlen(out);
263317225455SCristian Dumitrescu 		out += strlen(out);
263417225455SCristian Dumitrescu 
263517225455SCristian Dumitrescu 		snprintf(out,
263617225455SCristian Dumitrescu 			out_size,
263796b37959SCristian Dumitrescu 			" packets %" PRIu64
263817225455SCristian Dumitrescu 			" bytes %" PRIu64
263967f707b3SCristian Dumitrescu 			" packets dropped %" PRIu64
264067f707b3SCristian Dumitrescu 			" bytes dropped %" PRIu64
264117225455SCristian Dumitrescu 			" clone %" PRIu64
264217225455SCristian Dumitrescu 			" clonerr %" PRIu64 "\n",
264317225455SCristian Dumitrescu 			stats.n_pkts,
264417225455SCristian Dumitrescu 			stats.n_bytes,
264567f707b3SCristian Dumitrescu 			stats.n_pkts_drop,
264667f707b3SCristian Dumitrescu 			stats.n_bytes_drop,
264717225455SCristian Dumitrescu 			stats.n_pkts_clone,
264817225455SCristian Dumitrescu 			stats.n_pkts_clone_err);
264996b37959SCristian Dumitrescu 
26505074e1d5SCristian Dumitrescu 		out_size -= strlen(out);
26515074e1d5SCristian Dumitrescu 		out += strlen(out);
26525074e1d5SCristian Dumitrescu 	}
2653742b0a57SCristian Dumitrescu 
2654742b0a57SCristian Dumitrescu 	snprintf(out, out_size, "\nTables:\n");
2655742b0a57SCristian Dumitrescu 	out_size -= strlen(out);
2656742b0a57SCristian Dumitrescu 	out += strlen(out);
2657742b0a57SCristian Dumitrescu 
2658742b0a57SCristian Dumitrescu 	for (i = 0; i < info.n_tables; i++) {
2659742b0a57SCristian Dumitrescu 		struct rte_swx_ctl_table_info table_info;
2660742b0a57SCristian Dumitrescu 		uint64_t n_pkts_action[info.n_actions];
2661742b0a57SCristian Dumitrescu 		struct rte_swx_table_stats stats = {
2662742b0a57SCristian Dumitrescu 			.n_pkts_hit = 0,
2663742b0a57SCristian Dumitrescu 			.n_pkts_miss = 0,
2664742b0a57SCristian Dumitrescu 			.n_pkts_action = n_pkts_action,
2665742b0a57SCristian Dumitrescu 		};
2666742b0a57SCristian Dumitrescu 		uint32_t j;
2667742b0a57SCristian Dumitrescu 
2668b9559f94SCristian Dumitrescu 		status = rte_swx_ctl_table_info_get(p, i, &table_info);
2669742b0a57SCristian Dumitrescu 		if (status) {
2670742b0a57SCristian Dumitrescu 			snprintf(out, out_size, "Table info get error.");
2671742b0a57SCristian Dumitrescu 			return;
2672742b0a57SCristian Dumitrescu 		}
2673742b0a57SCristian Dumitrescu 
2674b9559f94SCristian Dumitrescu 		status = rte_swx_ctl_pipeline_table_stats_read(p, table_info.name, &stats);
2675742b0a57SCristian Dumitrescu 		if (status) {
2676742b0a57SCristian Dumitrescu 			snprintf(out, out_size, "Table stats read error.");
2677742b0a57SCristian Dumitrescu 			return;
2678742b0a57SCristian Dumitrescu 		}
2679742b0a57SCristian Dumitrescu 
2680742b0a57SCristian Dumitrescu 		snprintf(out, out_size, "\tTable %s:\n"
2681742b0a57SCristian Dumitrescu 			"\t\tHit (packets): %" PRIu64 "\n"
2682742b0a57SCristian Dumitrescu 			"\t\tMiss (packets): %" PRIu64 "\n",
2683742b0a57SCristian Dumitrescu 			table_info.name,
2684742b0a57SCristian Dumitrescu 			stats.n_pkts_hit,
2685742b0a57SCristian Dumitrescu 			stats.n_pkts_miss);
2686742b0a57SCristian Dumitrescu 		out_size -= strlen(out);
2687742b0a57SCristian Dumitrescu 		out += strlen(out);
2688742b0a57SCristian Dumitrescu 
2689742b0a57SCristian Dumitrescu 		for (j = 0; j < info.n_actions; j++) {
2690742b0a57SCristian Dumitrescu 			struct rte_swx_ctl_action_info action_info;
2691742b0a57SCristian Dumitrescu 
2692b9559f94SCristian Dumitrescu 			status = rte_swx_ctl_action_info_get(p, j, &action_info);
2693742b0a57SCristian Dumitrescu 			if (status) {
2694742b0a57SCristian Dumitrescu 				snprintf(out, out_size, "Action info get error.");
2695742b0a57SCristian Dumitrescu 				return;
2696742b0a57SCristian Dumitrescu 			}
2697742b0a57SCristian Dumitrescu 
2698742b0a57SCristian Dumitrescu 			snprintf(out, out_size, "\t\tAction %s (packets): %" PRIu64 "\n",
2699742b0a57SCristian Dumitrescu 				action_info.name,
2700742b0a57SCristian Dumitrescu 				stats.n_pkts_action[j]);
2701742b0a57SCristian Dumitrescu 			out_size -= strlen(out);
2702742b0a57SCristian Dumitrescu 			out += strlen(out);
2703742b0a57SCristian Dumitrescu 		}
2704742b0a57SCristian Dumitrescu 	}
27058bd4862fSCristian Dumitrescu 
27068bd4862fSCristian Dumitrescu 	snprintf(out, out_size, "\nLearner tables:\n");
27078bd4862fSCristian Dumitrescu 	out_size -= strlen(out);
27088bd4862fSCristian Dumitrescu 	out += strlen(out);
27098bd4862fSCristian Dumitrescu 
27108bd4862fSCristian Dumitrescu 	for (i = 0; i < info.n_learners; i++) {
27118bd4862fSCristian Dumitrescu 		struct rte_swx_ctl_learner_info learner_info;
27128bd4862fSCristian Dumitrescu 		uint64_t n_pkts_action[info.n_actions];
27138bd4862fSCristian Dumitrescu 		struct rte_swx_learner_stats stats = {
27148bd4862fSCristian Dumitrescu 			.n_pkts_hit = 0,
27158bd4862fSCristian Dumitrescu 			.n_pkts_miss = 0,
27168bd4862fSCristian Dumitrescu 			.n_pkts_action = n_pkts_action,
27178bd4862fSCristian Dumitrescu 		};
27188bd4862fSCristian Dumitrescu 		uint32_t j;
27198bd4862fSCristian Dumitrescu 
2720b9559f94SCristian Dumitrescu 		status = rte_swx_ctl_learner_info_get(p, i, &learner_info);
27218bd4862fSCristian Dumitrescu 		if (status) {
27228bd4862fSCristian Dumitrescu 			snprintf(out, out_size, "Learner table info get error.");
27238bd4862fSCristian Dumitrescu 			return;
27248bd4862fSCristian Dumitrescu 		}
27258bd4862fSCristian Dumitrescu 
2726b9559f94SCristian Dumitrescu 		status = rte_swx_ctl_pipeline_learner_stats_read(p, learner_info.name, &stats);
27278bd4862fSCristian Dumitrescu 		if (status) {
27288bd4862fSCristian Dumitrescu 			snprintf(out, out_size, "Learner table stats read error.");
27298bd4862fSCristian Dumitrescu 			return;
27308bd4862fSCristian Dumitrescu 		}
27318bd4862fSCristian Dumitrescu 
27328bd4862fSCristian Dumitrescu 		snprintf(out, out_size, "\tLearner table %s:\n"
27338bd4862fSCristian Dumitrescu 			"\t\tHit (packets): %" PRIu64 "\n"
27348bd4862fSCristian Dumitrescu 			"\t\tMiss (packets): %" PRIu64 "\n"
27358bd4862fSCristian Dumitrescu 			"\t\tLearn OK (packets): %" PRIu64 "\n"
27368bd4862fSCristian Dumitrescu 			"\t\tLearn error (packets): %" PRIu64 "\n"
273780dd28afSCristian Dumitrescu 			"\t\tRearm (packets): %" PRIu64 "\n"
27388bd4862fSCristian Dumitrescu 			"\t\tForget (packets): %" PRIu64 "\n",
27398bd4862fSCristian Dumitrescu 			learner_info.name,
27408bd4862fSCristian Dumitrescu 			stats.n_pkts_hit,
27418bd4862fSCristian Dumitrescu 			stats.n_pkts_miss,
27428bd4862fSCristian Dumitrescu 			stats.n_pkts_learn_ok,
27438bd4862fSCristian Dumitrescu 			stats.n_pkts_learn_err,
274480dd28afSCristian Dumitrescu 			stats.n_pkts_rearm,
27458bd4862fSCristian Dumitrescu 			stats.n_pkts_forget);
27468bd4862fSCristian Dumitrescu 		out_size -= strlen(out);
27478bd4862fSCristian Dumitrescu 		out += strlen(out);
27488bd4862fSCristian Dumitrescu 
27498bd4862fSCristian Dumitrescu 		for (j = 0; j < info.n_actions; j++) {
27508bd4862fSCristian Dumitrescu 			struct rte_swx_ctl_action_info action_info;
27518bd4862fSCristian Dumitrescu 
2752b9559f94SCristian Dumitrescu 			status = rte_swx_ctl_action_info_get(p, j, &action_info);
27538bd4862fSCristian Dumitrescu 			if (status) {
27548bd4862fSCristian Dumitrescu 				snprintf(out, out_size, "Action info get error.");
27558bd4862fSCristian Dumitrescu 				return;
27568bd4862fSCristian Dumitrescu 			}
27578bd4862fSCristian Dumitrescu 
27588bd4862fSCristian Dumitrescu 			snprintf(out, out_size, "\t\tAction %s (packets): %" PRIu64 "\n",
27598bd4862fSCristian Dumitrescu 				action_info.name,
27608bd4862fSCristian Dumitrescu 				stats.n_pkts_action[j]);
27618bd4862fSCristian Dumitrescu 			out_size -= strlen(out);
27628bd4862fSCristian Dumitrescu 			out += strlen(out);
27638bd4862fSCristian Dumitrescu 		}
27648bd4862fSCristian Dumitrescu 	}
27655074e1d5SCristian Dumitrescu }
27665074e1d5SCristian Dumitrescu 
276717225455SCristian Dumitrescu static const char cmd_pipeline_mirror_session_help[] =
276817225455SCristian Dumitrescu "pipeline <pipeline_name> mirror session <session_id> port <port_id> clone fast | slow "
276917225455SCristian Dumitrescu "truncate <truncation_length>\n";
277017225455SCristian Dumitrescu 
277117225455SCristian Dumitrescu static void
277217225455SCristian Dumitrescu cmd_pipeline_mirror_session(char **tokens,
277317225455SCristian Dumitrescu 	uint32_t n_tokens,
277417225455SCristian Dumitrescu 	char *out,
277517225455SCristian Dumitrescu 	size_t out_size,
2776b9559f94SCristian Dumitrescu 	void *obj __rte_unused)
277717225455SCristian Dumitrescu {
277817225455SCristian Dumitrescu 	struct rte_swx_pipeline_mirroring_session_params params;
2779b9559f94SCristian Dumitrescu 	struct rte_swx_pipeline *p;
278077dd857dSAli Alnubani 	uint32_t session_id = 0;
278117225455SCristian Dumitrescu 	int status;
278217225455SCristian Dumitrescu 
278317225455SCristian Dumitrescu 	if (n_tokens != 11) {
278417225455SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
278517225455SCristian Dumitrescu 		return;
278617225455SCristian Dumitrescu 	}
278717225455SCristian Dumitrescu 
278817225455SCristian Dumitrescu 	if (strcmp(tokens[0], "pipeline")) {
278917225455SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pipeline");
279017225455SCristian Dumitrescu 		return;
279117225455SCristian Dumitrescu 	}
279217225455SCristian Dumitrescu 
2793b9559f94SCristian Dumitrescu 	p = rte_swx_pipeline_find(tokens[1]);
2794b9559f94SCristian Dumitrescu 	if (!p) {
279517225455SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
279617225455SCristian Dumitrescu 		return;
279717225455SCristian Dumitrescu 	}
279817225455SCristian Dumitrescu 
279917225455SCristian Dumitrescu 	if (strcmp(tokens[2], "mirror")) {
280017225455SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "mirror");
280117225455SCristian Dumitrescu 		return;
280217225455SCristian Dumitrescu 	}
280317225455SCristian Dumitrescu 
280417225455SCristian Dumitrescu 	if (strcmp(tokens[3], "session")) {
280517225455SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "session");
280617225455SCristian Dumitrescu 		return;
280717225455SCristian Dumitrescu 	}
280817225455SCristian Dumitrescu 
280917225455SCristian Dumitrescu 	if (parser_read_uint32(&session_id, tokens[4])) {
281017225455SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "session_id");
281117225455SCristian Dumitrescu 		return;
281217225455SCristian Dumitrescu 	}
281317225455SCristian Dumitrescu 
281417225455SCristian Dumitrescu 	if (strcmp(tokens[5], "port")) {
281517225455SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
281617225455SCristian Dumitrescu 		return;
281717225455SCristian Dumitrescu 	}
281817225455SCristian Dumitrescu 
281917225455SCristian Dumitrescu 	if (parser_read_uint32(&params.port_id, tokens[6])) {
282017225455SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
282117225455SCristian Dumitrescu 		return;
282217225455SCristian Dumitrescu 	}
282317225455SCristian Dumitrescu 
282417225455SCristian Dumitrescu 	if (strcmp(tokens[7], "clone")) {
282517225455SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "clone");
282617225455SCristian Dumitrescu 		return;
282717225455SCristian Dumitrescu 	}
282817225455SCristian Dumitrescu 
282917225455SCristian Dumitrescu 	if (!strcmp(tokens[8], "fast"))
283017225455SCristian Dumitrescu 		params.fast_clone = 1;
283117225455SCristian Dumitrescu 	else if (!strcmp(tokens[8], "slow"))
283217225455SCristian Dumitrescu 		params.fast_clone = 0;
283317225455SCristian Dumitrescu 	else {
283417225455SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "clone");
283517225455SCristian Dumitrescu 		return;
283617225455SCristian Dumitrescu 	}
283717225455SCristian Dumitrescu 
283817225455SCristian Dumitrescu 	if (strcmp(tokens[9], "truncate")) {
283917225455SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "truncate");
284017225455SCristian Dumitrescu 		return;
284117225455SCristian Dumitrescu 	}
284217225455SCristian Dumitrescu 
284317225455SCristian Dumitrescu 	if (parser_read_uint32(&params.truncation_length, tokens[10])) {
284417225455SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "truncation_length");
284517225455SCristian Dumitrescu 		return;
284617225455SCristian Dumitrescu 	}
284717225455SCristian Dumitrescu 
2848b9559f94SCristian Dumitrescu 	status = rte_swx_ctl_pipeline_mirroring_session_set(p, session_id, &params);
284917225455SCristian Dumitrescu 	if (status) {
285017225455SCristian Dumitrescu 		snprintf(out, out_size, "Command failed!\n");
285117225455SCristian Dumitrescu 		return;
285217225455SCristian Dumitrescu 	}
285317225455SCristian Dumitrescu }
285417225455SCristian Dumitrescu 
28555074e1d5SCristian Dumitrescu static const char cmd_thread_pipeline_enable_help[] =
2856b9559f94SCristian Dumitrescu "thread <thread_id> pipeline <pipeline_name> enable [ period <timer_period_ms> ]\n";
2857b9559f94SCristian Dumitrescu 
2858b9559f94SCristian Dumitrescu #ifndef TIMER_PERIOD_MS_DEFAULT
2859b9559f94SCristian Dumitrescu #define TIMER_PERIOD_MS_DEFAULT 10
2860b9559f94SCristian Dumitrescu #endif
28615074e1d5SCristian Dumitrescu 
28625074e1d5SCristian Dumitrescu static void
28635074e1d5SCristian Dumitrescu cmd_thread_pipeline_enable(char **tokens,
28645074e1d5SCristian Dumitrescu 	uint32_t n_tokens,
28655074e1d5SCristian Dumitrescu 	char *out,
28665074e1d5SCristian Dumitrescu 	size_t out_size,
2867b9559f94SCristian Dumitrescu 	void *obj __rte_unused)
28685074e1d5SCristian Dumitrescu {
28695074e1d5SCristian Dumitrescu 	char *pipeline_name;
2870b9559f94SCristian Dumitrescu 	struct rte_swx_pipeline *p;
2871b9559f94SCristian Dumitrescu 	uint32_t thread_id, timer_period_ms = TIMER_PERIOD_MS_DEFAULT;
28725074e1d5SCristian Dumitrescu 	int status;
28735074e1d5SCristian Dumitrescu 
2874b9559f94SCristian Dumitrescu 	if ((n_tokens != 5) && (n_tokens != 7)) {
28755074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
28765074e1d5SCristian Dumitrescu 		return;
28775074e1d5SCristian Dumitrescu 	}
28785074e1d5SCristian Dumitrescu 
28795074e1d5SCristian Dumitrescu 	if (parser_read_uint32(&thread_id, tokens[1]) != 0) {
28805074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "thread_id");
28815074e1d5SCristian Dumitrescu 		return;
28825074e1d5SCristian Dumitrescu 	}
28835074e1d5SCristian Dumitrescu 
28845074e1d5SCristian Dumitrescu 	if (strcmp(tokens[2], "pipeline") != 0) {
28855074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pipeline");
28865074e1d5SCristian Dumitrescu 		return;
28875074e1d5SCristian Dumitrescu 	}
28885074e1d5SCristian Dumitrescu 
28895074e1d5SCristian Dumitrescu 	pipeline_name = tokens[3];
2890b9559f94SCristian Dumitrescu 	p = rte_swx_pipeline_find(pipeline_name);
2891b9559f94SCristian Dumitrescu 	if (!p) {
28925074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
28935074e1d5SCristian Dumitrescu 		return;
28945074e1d5SCristian Dumitrescu 	}
28955074e1d5SCristian Dumitrescu 
28965074e1d5SCristian Dumitrescu 	if (strcmp(tokens[4], "enable") != 0) {
28975074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "enable");
28985074e1d5SCristian Dumitrescu 		return;
28995074e1d5SCristian Dumitrescu 	}
29005074e1d5SCristian Dumitrescu 
2901b9559f94SCristian Dumitrescu 	if (n_tokens == 7) {
2902b9559f94SCristian Dumitrescu 		if (strcmp(tokens[5], "period") != 0) {
2903b9559f94SCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_NOT_FOUND, "period");
2904b9559f94SCristian Dumitrescu 			return;
2905b9559f94SCristian Dumitrescu 		}
2906b9559f94SCristian Dumitrescu 
2907b9559f94SCristian Dumitrescu 		if (parser_read_uint32(&timer_period_ms, tokens[6]) != 0) {
2908b9559f94SCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_INVALID, "timer_period_ms");
2909b9559f94SCristian Dumitrescu 			return;
2910b9559f94SCristian Dumitrescu 		}
2911b9559f94SCristian Dumitrescu 	}
2912b9559f94SCristian Dumitrescu 
2913b9559f94SCristian Dumitrescu 	status = thread_pipeline_enable(thread_id, p, timer_period_ms);
29145074e1d5SCristian Dumitrescu 	if (status) {
29155074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_CMD_FAIL, "thread pipeline enable");
29165074e1d5SCristian Dumitrescu 		return;
29175074e1d5SCristian Dumitrescu 	}
29185074e1d5SCristian Dumitrescu }
29195074e1d5SCristian Dumitrescu 
29205074e1d5SCristian Dumitrescu static const char cmd_thread_pipeline_disable_help[] =
29215074e1d5SCristian Dumitrescu "thread <thread_id> pipeline <pipeline_name> disable\n";
29225074e1d5SCristian Dumitrescu 
29235074e1d5SCristian Dumitrescu static void
29245074e1d5SCristian Dumitrescu cmd_thread_pipeline_disable(char **tokens,
29255074e1d5SCristian Dumitrescu 	uint32_t n_tokens,
29265074e1d5SCristian Dumitrescu 	char *out,
29275074e1d5SCristian Dumitrescu 	size_t out_size,
2928b9559f94SCristian Dumitrescu 	void *obj __rte_unused)
29295074e1d5SCristian Dumitrescu {
2930b9559f94SCristian Dumitrescu 	struct rte_swx_pipeline *p;
29315074e1d5SCristian Dumitrescu 	char *pipeline_name;
29325074e1d5SCristian Dumitrescu 	uint32_t thread_id;
29335074e1d5SCristian Dumitrescu 	int status;
29345074e1d5SCristian Dumitrescu 
29355074e1d5SCristian Dumitrescu 	if (n_tokens != 5) {
29365074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
29375074e1d5SCristian Dumitrescu 		return;
29385074e1d5SCristian Dumitrescu 	}
29395074e1d5SCristian Dumitrescu 
29405074e1d5SCristian Dumitrescu 	if (parser_read_uint32(&thread_id, tokens[1]) != 0) {
29415074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "thread_id");
29425074e1d5SCristian Dumitrescu 		return;
29435074e1d5SCristian Dumitrescu 	}
29445074e1d5SCristian Dumitrescu 
29455074e1d5SCristian Dumitrescu 	if (strcmp(tokens[2], "pipeline") != 0) {
29465074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pipeline");
29475074e1d5SCristian Dumitrescu 		return;
29485074e1d5SCristian Dumitrescu 	}
29495074e1d5SCristian Dumitrescu 
29505074e1d5SCristian Dumitrescu 	pipeline_name = tokens[3];
2951b9559f94SCristian Dumitrescu 	p = rte_swx_pipeline_find(pipeline_name);
2952b9559f94SCristian Dumitrescu 	if (!p) {
29535074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
29545074e1d5SCristian Dumitrescu 		return;
29555074e1d5SCristian Dumitrescu 	}
29565074e1d5SCristian Dumitrescu 
29575074e1d5SCristian Dumitrescu 	if (strcmp(tokens[4], "disable") != 0) {
29585074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "disable");
29595074e1d5SCristian Dumitrescu 		return;
29605074e1d5SCristian Dumitrescu 	}
29615074e1d5SCristian Dumitrescu 
2962b9559f94SCristian Dumitrescu 	status = thread_pipeline_disable(thread_id, p);
29635074e1d5SCristian Dumitrescu 	if (status) {
29645074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_CMD_FAIL,
29655074e1d5SCristian Dumitrescu 			"thread pipeline disable");
29665074e1d5SCristian Dumitrescu 		return;
29675074e1d5SCristian Dumitrescu 	}
29685074e1d5SCristian Dumitrescu }
29695074e1d5SCristian Dumitrescu 
29705074e1d5SCristian Dumitrescu static void
29715074e1d5SCristian Dumitrescu cmd_help(char **tokens,
29725074e1d5SCristian Dumitrescu 	 uint32_t n_tokens,
29735074e1d5SCristian Dumitrescu 	 char *out,
29745074e1d5SCristian Dumitrescu 	 size_t out_size,
29755074e1d5SCristian Dumitrescu 	 void *arg __rte_unused)
29765074e1d5SCristian Dumitrescu {
29775074e1d5SCristian Dumitrescu 	tokens++;
29785074e1d5SCristian Dumitrescu 	n_tokens--;
29795074e1d5SCristian Dumitrescu 
29805074e1d5SCristian Dumitrescu 	if (n_tokens == 0) {
29815074e1d5SCristian Dumitrescu 		snprintf(out, out_size,
29827fef9ef1SYogesh Jangra 			"Type 'help <command>' for command details.\n\n"
29837fef9ef1SYogesh Jangra 			"List of commands:\n"
29847fef9ef1SYogesh Jangra 			"\tmempool\n"
2985f31c80f8SCristian Dumitrescu 			"\tethdev\n"
29869043f66aSCristian Dumitrescu 			"\tpipeline codegen\n"
29876bc14d9fSCristian Dumitrescu 			"\tpipeline libbuild\n"
29887fef9ef1SYogesh Jangra 			"\tpipeline build\n"
298975129cebSChurchill Khangar 			"\tpipeline table add\n"
299075129cebSChurchill Khangar 			"\tpipeline table delete\n"
299175129cebSChurchill Khangar 			"\tpipeline table default\n"
299275129cebSChurchill Khangar 			"\tpipeline table show\n"
2993598fe0ddSCristian Dumitrescu 			"\tpipeline selector group add\n"
2994598fe0ddSCristian Dumitrescu 			"\tpipeline selector group delete\n"
2995598fe0ddSCristian Dumitrescu 			"\tpipeline selector group member add\n"
2996598fe0ddSCristian Dumitrescu 			"\tpipeline selector group member delete\n"
2997598fe0ddSCristian Dumitrescu 			"\tpipeline selector show\n"
29988bd4862fSCristian Dumitrescu 			"\tpipeline learner default\n"
299975129cebSChurchill Khangar 			"\tpipeline commit\n"
300075129cebSChurchill Khangar 			"\tpipeline abort\n"
300164cfcebdSCristian Dumitrescu 			"\tpipeline regrd\n"
300264cfcebdSCristian Dumitrescu 			"\tpipeline regwr\n"
3003f38913b7SCristian Dumitrescu 			"\tpipeline meter profile add\n"
3004f38913b7SCristian Dumitrescu 			"\tpipeline meter profile delete\n"
3005f38913b7SCristian Dumitrescu 			"\tpipeline meter reset\n"
3006f38913b7SCristian Dumitrescu 			"\tpipeline meter set\n"
3007f38913b7SCristian Dumitrescu 			"\tpipeline meter stats\n"
30087fef9ef1SYogesh Jangra 			"\tpipeline stats\n"
300917225455SCristian Dumitrescu 			"\tpipeline mirror session\n"
30107fef9ef1SYogesh Jangra 			"\tthread pipeline enable\n"
30117fef9ef1SYogesh Jangra 			"\tthread pipeline disable\n\n");
30125074e1d5SCristian Dumitrescu 		return;
30135074e1d5SCristian Dumitrescu 	}
30145074e1d5SCristian Dumitrescu 
30155074e1d5SCristian Dumitrescu 	if (strcmp(tokens[0], "mempool") == 0) {
30165074e1d5SCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n", cmd_mempool_help);
30175074e1d5SCristian Dumitrescu 		return;
30185074e1d5SCristian Dumitrescu 	}
30195074e1d5SCristian Dumitrescu 
3020f31c80f8SCristian Dumitrescu 	if (strcmp(tokens[0], "ethdev") == 0) {
3021f31c80f8SCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n", cmd_ethdev_help);
30225074e1d5SCristian Dumitrescu 		return;
30235074e1d5SCristian Dumitrescu 	}
30245074e1d5SCristian Dumitrescu 
302577a41301SCristian Dumitrescu 	if (strcmp(tokens[0], "ring") == 0) {
302677a41301SCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n", cmd_ring_help);
302777a41301SCristian Dumitrescu 		return;
302877a41301SCristian Dumitrescu 	}
302977a41301SCristian Dumitrescu 
30305074e1d5SCristian Dumitrescu 	if ((strcmp(tokens[0], "pipeline") == 0) &&
30319043f66aSCristian Dumitrescu 		(n_tokens == 2) && (strcmp(tokens[1], "codegen") == 0)) {
30329043f66aSCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n", cmd_pipeline_codegen_help);
30339043f66aSCristian Dumitrescu 		return;
30349043f66aSCristian Dumitrescu 	}
30359043f66aSCristian Dumitrescu 
30369043f66aSCristian Dumitrescu 	if ((strcmp(tokens[0], "pipeline") == 0) &&
30376bc14d9fSCristian Dumitrescu 		(n_tokens == 2) && (strcmp(tokens[1], "libbuild") == 0)) {
30386bc14d9fSCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n", cmd_pipeline_libbuild_help);
30396bc14d9fSCristian Dumitrescu 		return;
30406bc14d9fSCristian Dumitrescu 	}
30416bc14d9fSCristian Dumitrescu 
30426bc14d9fSCristian Dumitrescu 	if ((strcmp(tokens[0], "pipeline") == 0) &&
30437fef9ef1SYogesh Jangra 		(n_tokens == 2) && (strcmp(tokens[1], "build") == 0)) {
30445074e1d5SCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n", cmd_pipeline_build_help);
30455074e1d5SCristian Dumitrescu 		return;
30465074e1d5SCristian Dumitrescu 	}
30475074e1d5SCristian Dumitrescu 
30485074e1d5SCristian Dumitrescu 	if ((strcmp(tokens[0], "pipeline") == 0) &&
30497fef9ef1SYogesh Jangra 		(n_tokens == 3) &&
30507fef9ef1SYogesh Jangra 		(strcmp(tokens[1], "table") == 0) &&
305175129cebSChurchill Khangar 		(strcmp(tokens[2], "add") == 0)) {
30525074e1d5SCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n",
305375129cebSChurchill Khangar 			cmd_pipeline_table_add_help);
305475129cebSChurchill Khangar 		return;
305575129cebSChurchill Khangar 	}
305675129cebSChurchill Khangar 
305775129cebSChurchill Khangar 	if ((strcmp(tokens[0], "pipeline") == 0) &&
305875129cebSChurchill Khangar 		(n_tokens == 3) &&
305975129cebSChurchill Khangar 		(strcmp(tokens[1], "table") == 0) &&
306075129cebSChurchill Khangar 		(strcmp(tokens[2], "delete") == 0)) {
306175129cebSChurchill Khangar 		snprintf(out, out_size, "\n%s\n",
306275129cebSChurchill Khangar 			cmd_pipeline_table_delete_help);
306375129cebSChurchill Khangar 		return;
306475129cebSChurchill Khangar 	}
306575129cebSChurchill Khangar 
306675129cebSChurchill Khangar 	if ((strcmp(tokens[0], "pipeline") == 0) &&
306775129cebSChurchill Khangar 		(n_tokens == 3) &&
306875129cebSChurchill Khangar 		(strcmp(tokens[1], "table") == 0) &&
306975129cebSChurchill Khangar 		(strcmp(tokens[2], "default") == 0)) {
307075129cebSChurchill Khangar 		snprintf(out, out_size, "\n%s\n",
307175129cebSChurchill Khangar 			cmd_pipeline_table_default_help);
307275129cebSChurchill Khangar 		return;
307375129cebSChurchill Khangar 	}
307475129cebSChurchill Khangar 
307575129cebSChurchill Khangar 	if ((strcmp(tokens[0], "pipeline") == 0) &&
307675129cebSChurchill Khangar 		(n_tokens == 3) &&
307775129cebSChurchill Khangar 		(strcmp(tokens[1], "table") == 0) &&
307875129cebSChurchill Khangar 		(strcmp(tokens[2], "show") == 0)) {
307975129cebSChurchill Khangar 		snprintf(out, out_size, "\n%s\n",
308075129cebSChurchill Khangar 			cmd_pipeline_table_show_help);
308175129cebSChurchill Khangar 		return;
308275129cebSChurchill Khangar 	}
308375129cebSChurchill Khangar 
308475129cebSChurchill Khangar 	if ((strcmp(tokens[0], "pipeline") == 0) &&
3085598fe0ddSCristian Dumitrescu 		(n_tokens == 4) &&
3086598fe0ddSCristian Dumitrescu 		(strcmp(tokens[1], "selector") == 0) &&
3087598fe0ddSCristian Dumitrescu 		(strcmp(tokens[2], "group") == 0) &&
3088598fe0ddSCristian Dumitrescu 		(strcmp(tokens[3], "add") == 0)) {
3089598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n",
3090598fe0ddSCristian Dumitrescu 			cmd_pipeline_selector_group_add_help);
3091598fe0ddSCristian Dumitrescu 		return;
3092598fe0ddSCristian Dumitrescu 	}
3093598fe0ddSCristian Dumitrescu 
3094598fe0ddSCristian Dumitrescu 	if ((strcmp(tokens[0], "pipeline") == 0) &&
3095598fe0ddSCristian Dumitrescu 		(n_tokens == 4) &&
3096598fe0ddSCristian Dumitrescu 		(strcmp(tokens[1], "selector") == 0) &&
3097598fe0ddSCristian Dumitrescu 		(strcmp(tokens[2], "group") == 0) &&
3098598fe0ddSCristian Dumitrescu 		(strcmp(tokens[3], "delete") == 0)) {
3099598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n",
3100598fe0ddSCristian Dumitrescu 			cmd_pipeline_selector_group_delete_help);
3101598fe0ddSCristian Dumitrescu 		return;
3102598fe0ddSCristian Dumitrescu 	}
3103598fe0ddSCristian Dumitrescu 
3104598fe0ddSCristian Dumitrescu 	if ((strcmp(tokens[0], "pipeline") == 0) &&
3105598fe0ddSCristian Dumitrescu 		(n_tokens == 5) &&
3106598fe0ddSCristian Dumitrescu 		(strcmp(tokens[1], "selector") == 0) &&
3107598fe0ddSCristian Dumitrescu 		(strcmp(tokens[2], "group") == 0) &&
3108598fe0ddSCristian Dumitrescu 		(strcmp(tokens[3], "member") == 0) &&
3109598fe0ddSCristian Dumitrescu 		(strcmp(tokens[4], "add") == 0)) {
3110598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n",
3111598fe0ddSCristian Dumitrescu 			cmd_pipeline_selector_group_member_add_help);
3112598fe0ddSCristian Dumitrescu 		return;
3113598fe0ddSCristian Dumitrescu 	}
3114598fe0ddSCristian Dumitrescu 
3115598fe0ddSCristian Dumitrescu 	if ((strcmp(tokens[0], "pipeline") == 0) &&
3116598fe0ddSCristian Dumitrescu 		(n_tokens == 5) &&
3117598fe0ddSCristian Dumitrescu 		(strcmp(tokens[1], "selector") == 0) &&
3118598fe0ddSCristian Dumitrescu 		(strcmp(tokens[2], "group") == 0) &&
3119598fe0ddSCristian Dumitrescu 		(strcmp(tokens[3], "member") == 0) &&
3120598fe0ddSCristian Dumitrescu 		(strcmp(tokens[4], "delete") == 0)) {
3121598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n",
3122598fe0ddSCristian Dumitrescu 			cmd_pipeline_selector_group_member_delete_help);
3123598fe0ddSCristian Dumitrescu 		return;
3124598fe0ddSCristian Dumitrescu 	}
3125598fe0ddSCristian Dumitrescu 
3126598fe0ddSCristian Dumitrescu 	if ((strcmp(tokens[0], "pipeline") == 0) &&
3127598fe0ddSCristian Dumitrescu 		(n_tokens == 3) &&
3128598fe0ddSCristian Dumitrescu 		(strcmp(tokens[1], "selector") == 0) &&
3129598fe0ddSCristian Dumitrescu 		(strcmp(tokens[2], "show") == 0)) {
3130598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n",
3131598fe0ddSCristian Dumitrescu 			cmd_pipeline_selector_show_help);
3132598fe0ddSCristian Dumitrescu 		return;
3133598fe0ddSCristian Dumitrescu 	}
3134598fe0ddSCristian Dumitrescu 
3135598fe0ddSCristian Dumitrescu 	if ((strcmp(tokens[0], "pipeline") == 0) &&
31368bd4862fSCristian Dumitrescu 		(n_tokens == 3) &&
31378bd4862fSCristian Dumitrescu 		(strcmp(tokens[1], "learner") == 0) &&
31388bd4862fSCristian Dumitrescu 		(strcmp(tokens[2], "default") == 0)) {
31398bd4862fSCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n",
31408bd4862fSCristian Dumitrescu 			cmd_pipeline_learner_default_help);
31418bd4862fSCristian Dumitrescu 		return;
31428bd4862fSCristian Dumitrescu 	}
31438bd4862fSCristian Dumitrescu 
31448bd4862fSCristian Dumitrescu 	if ((strcmp(tokens[0], "pipeline") == 0) &&
314575129cebSChurchill Khangar 		(n_tokens == 2) &&
314675129cebSChurchill Khangar 		(strcmp(tokens[1], "commit") == 0)) {
314775129cebSChurchill Khangar 		snprintf(out, out_size, "\n%s\n",
314875129cebSChurchill Khangar 			cmd_pipeline_commit_help);
314975129cebSChurchill Khangar 		return;
315075129cebSChurchill Khangar 	}
315175129cebSChurchill Khangar 
315275129cebSChurchill Khangar 	if ((strcmp(tokens[0], "pipeline") == 0) &&
315375129cebSChurchill Khangar 		(n_tokens == 2) &&
315475129cebSChurchill Khangar 		(strcmp(tokens[1], "abort") == 0)) {
315575129cebSChurchill Khangar 		snprintf(out, out_size, "\n%s\n",
315675129cebSChurchill Khangar 			cmd_pipeline_abort_help);
31575074e1d5SCristian Dumitrescu 		return;
31585074e1d5SCristian Dumitrescu 	}
31595074e1d5SCristian Dumitrescu 
31605074e1d5SCristian Dumitrescu 	if ((strcmp(tokens[0], "pipeline") == 0) &&
316164cfcebdSCristian Dumitrescu 		(n_tokens == 2) && (strcmp(tokens[1], "regrd") == 0)) {
316264cfcebdSCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n", cmd_pipeline_regrd_help);
316364cfcebdSCristian Dumitrescu 		return;
316464cfcebdSCristian Dumitrescu 	}
316564cfcebdSCristian Dumitrescu 
316664cfcebdSCristian Dumitrescu 	if ((strcmp(tokens[0], "pipeline") == 0) &&
316764cfcebdSCristian Dumitrescu 		(n_tokens == 2) && (strcmp(tokens[1], "regwr") == 0)) {
316864cfcebdSCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n", cmd_pipeline_regwr_help);
316964cfcebdSCristian Dumitrescu 		return;
317064cfcebdSCristian Dumitrescu 	}
317164cfcebdSCristian Dumitrescu 
3172f38913b7SCristian Dumitrescu 	if (!strcmp(tokens[0], "pipeline") &&
3173f38913b7SCristian Dumitrescu 		(n_tokens == 4) && !strcmp(tokens[1], "meter")
3174f38913b7SCristian Dumitrescu 		&& !strcmp(tokens[2], "profile")
3175f38913b7SCristian Dumitrescu 		&& !strcmp(tokens[3], "add")) {
3176f38913b7SCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n", cmd_pipeline_meter_profile_add_help);
3177f38913b7SCristian Dumitrescu 		return;
3178f38913b7SCristian Dumitrescu 	}
3179f38913b7SCristian Dumitrescu 
3180f38913b7SCristian Dumitrescu 	if (!strcmp(tokens[0], "pipeline") &&
3181f38913b7SCristian Dumitrescu 		(n_tokens == 4) && !strcmp(tokens[1], "meter")
3182f38913b7SCristian Dumitrescu 		&& !strcmp(tokens[2], "profile")
3183f38913b7SCristian Dumitrescu 		&& !strcmp(tokens[3], "delete")) {
3184f38913b7SCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n", cmd_pipeline_meter_profile_delete_help);
3185f38913b7SCristian Dumitrescu 		return;
3186f38913b7SCristian Dumitrescu 	}
3187f38913b7SCristian Dumitrescu 
3188f38913b7SCristian Dumitrescu 	if (!strcmp(tokens[0], "pipeline") &&
3189f38913b7SCristian Dumitrescu 		(n_tokens == 3) && !strcmp(tokens[1], "meter")
3190f38913b7SCristian Dumitrescu 		&& !strcmp(tokens[2], "reset")) {
3191f38913b7SCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n", cmd_pipeline_meter_reset_help);
3192f38913b7SCristian Dumitrescu 		return;
3193f38913b7SCristian Dumitrescu 	}
3194f38913b7SCristian Dumitrescu 
3195f38913b7SCristian Dumitrescu 	if (!strcmp(tokens[0], "pipeline") &&
3196f38913b7SCristian Dumitrescu 		(n_tokens == 3) && !strcmp(tokens[1], "meter")
3197f38913b7SCristian Dumitrescu 		&& !strcmp(tokens[2], "set")) {
3198f38913b7SCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n", cmd_pipeline_meter_set_help);
3199f38913b7SCristian Dumitrescu 		return;
3200f38913b7SCristian Dumitrescu 	}
3201f38913b7SCristian Dumitrescu 
3202f38913b7SCristian Dumitrescu 	if (!strcmp(tokens[0], "pipeline") &&
3203f38913b7SCristian Dumitrescu 		(n_tokens == 3) && !strcmp(tokens[1], "meter")
3204f38913b7SCristian Dumitrescu 		&& !strcmp(tokens[2], "stats")) {
3205f38913b7SCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n", cmd_pipeline_meter_stats_help);
3206f38913b7SCristian Dumitrescu 		return;
3207f38913b7SCristian Dumitrescu 	}
3208f38913b7SCristian Dumitrescu 
320964cfcebdSCristian Dumitrescu 	if ((strcmp(tokens[0], "pipeline") == 0) &&
32107fef9ef1SYogesh Jangra 		(n_tokens == 2) && (strcmp(tokens[1], "stats") == 0)) {
32115074e1d5SCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n", cmd_pipeline_stats_help);
32125074e1d5SCristian Dumitrescu 		return;
32135074e1d5SCristian Dumitrescu 	}
32145074e1d5SCristian Dumitrescu 
321517225455SCristian Dumitrescu 	if (!strcmp(tokens[0], "pipeline") &&
321617225455SCristian Dumitrescu 		(n_tokens == 3) && !strcmp(tokens[1], "mirror")
321717225455SCristian Dumitrescu 		&& !strcmp(tokens[2], "session")) {
321817225455SCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n", cmd_pipeline_mirror_session_help);
321917225455SCristian Dumitrescu 		return;
322017225455SCristian Dumitrescu 	}
322117225455SCristian Dumitrescu 
32225074e1d5SCristian Dumitrescu 	if ((n_tokens == 3) &&
32235074e1d5SCristian Dumitrescu 		(strcmp(tokens[0], "thread") == 0) &&
32245074e1d5SCristian Dumitrescu 		(strcmp(tokens[1], "pipeline") == 0)) {
32255074e1d5SCristian Dumitrescu 		if (strcmp(tokens[2], "enable") == 0) {
32265074e1d5SCristian Dumitrescu 			snprintf(out, out_size, "\n%s\n",
32275074e1d5SCristian Dumitrescu 				cmd_thread_pipeline_enable_help);
32285074e1d5SCristian Dumitrescu 			return;
32295074e1d5SCristian Dumitrescu 		}
32305074e1d5SCristian Dumitrescu 
32315074e1d5SCristian Dumitrescu 		if (strcmp(tokens[2], "disable") == 0) {
32325074e1d5SCristian Dumitrescu 			snprintf(out, out_size, "\n%s\n",
32335074e1d5SCristian Dumitrescu 				cmd_thread_pipeline_disable_help);
32345074e1d5SCristian Dumitrescu 			return;
32355074e1d5SCristian Dumitrescu 		}
32365074e1d5SCristian Dumitrescu 	}
32375074e1d5SCristian Dumitrescu 
32385074e1d5SCristian Dumitrescu 	snprintf(out, out_size, "Invalid command\n");
32395074e1d5SCristian Dumitrescu }
32405074e1d5SCristian Dumitrescu 
32415074e1d5SCristian Dumitrescu void
32425074e1d5SCristian Dumitrescu cli_process(char *in, char *out, size_t out_size, void *obj)
32435074e1d5SCristian Dumitrescu {
32445074e1d5SCristian Dumitrescu 	char *tokens[CMD_MAX_TOKENS];
32455074e1d5SCristian Dumitrescu 	uint32_t n_tokens = RTE_DIM(tokens);
32465074e1d5SCristian Dumitrescu 	int status;
32475074e1d5SCristian Dumitrescu 
32485074e1d5SCristian Dumitrescu 	if (is_comment(in))
32495074e1d5SCristian Dumitrescu 		return;
32505074e1d5SCristian Dumitrescu 
32515074e1d5SCristian Dumitrescu 	status = parse_tokenize_string(in, tokens, &n_tokens);
32525074e1d5SCristian Dumitrescu 	if (status) {
32535074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_TOO_MANY, "");
32545074e1d5SCristian Dumitrescu 		return;
32555074e1d5SCristian Dumitrescu 	}
32565074e1d5SCristian Dumitrescu 
32575074e1d5SCristian Dumitrescu 	if (n_tokens == 0)
32585074e1d5SCristian Dumitrescu 		return;
32595074e1d5SCristian Dumitrescu 
32605074e1d5SCristian Dumitrescu 	if (strcmp(tokens[0], "help") == 0) {
32615074e1d5SCristian Dumitrescu 		cmd_help(tokens, n_tokens, out, out_size, obj);
32625074e1d5SCristian Dumitrescu 		return;
32635074e1d5SCristian Dumitrescu 	}
32645074e1d5SCristian Dumitrescu 
32655074e1d5SCristian Dumitrescu 	if (strcmp(tokens[0], "mempool") == 0) {
32665074e1d5SCristian Dumitrescu 		cmd_mempool(tokens, n_tokens, out, out_size, obj);
32675074e1d5SCristian Dumitrescu 		return;
32685074e1d5SCristian Dumitrescu 	}
32695074e1d5SCristian Dumitrescu 
3270f31c80f8SCristian Dumitrescu 	if (strcmp(tokens[0], "ethdev") == 0) {
3271821848f5SCristian Dumitrescu 		if ((n_tokens >= 2) && (strcmp(tokens[1], "show") == 0)) {
3272f31c80f8SCristian Dumitrescu 			cmd_ethdev_show(tokens, n_tokens, out, out_size, obj);
32735074e1d5SCristian Dumitrescu 			return;
32745074e1d5SCristian Dumitrescu 		}
32755074e1d5SCristian Dumitrescu 
3276f31c80f8SCristian Dumitrescu 		cmd_ethdev(tokens, n_tokens, out, out_size, obj);
32775074e1d5SCristian Dumitrescu 		return;
32785074e1d5SCristian Dumitrescu 	}
32795074e1d5SCristian Dumitrescu 
328077a41301SCristian Dumitrescu 	if (strcmp(tokens[0], "ring") == 0) {
328177a41301SCristian Dumitrescu 		cmd_ring(tokens, n_tokens, out, out_size, obj);
328277a41301SCristian Dumitrescu 		return;
328377a41301SCristian Dumitrescu 	}
328477a41301SCristian Dumitrescu 
32855074e1d5SCristian Dumitrescu 	if (strcmp(tokens[0], "pipeline") == 0) {
32865074e1d5SCristian Dumitrescu 		if ((n_tokens >= 3) &&
32879043f66aSCristian Dumitrescu 			(strcmp(tokens[1], "codegen") == 0)) {
32889043f66aSCristian Dumitrescu 			cmd_pipeline_codegen(tokens, n_tokens, out, out_size,
32899043f66aSCristian Dumitrescu 				obj);
32909043f66aSCristian Dumitrescu 			return;
32919043f66aSCristian Dumitrescu 		}
32929043f66aSCristian Dumitrescu 
32939043f66aSCristian Dumitrescu 		if ((n_tokens >= 3) &&
32946bc14d9fSCristian Dumitrescu 			(strcmp(tokens[1], "libbuild") == 0)) {
32956bc14d9fSCristian Dumitrescu 			cmd_pipeline_libbuild(tokens, n_tokens, out, out_size,
32966bc14d9fSCristian Dumitrescu 				obj);
32976bc14d9fSCristian Dumitrescu 			return;
32986bc14d9fSCristian Dumitrescu 		}
32996bc14d9fSCristian Dumitrescu 
33006bc14d9fSCristian Dumitrescu 		if ((n_tokens >= 3) &&
33015074e1d5SCristian Dumitrescu 			(strcmp(tokens[2], "build") == 0)) {
33025074e1d5SCristian Dumitrescu 			cmd_pipeline_build(tokens, n_tokens, out, out_size,
33035074e1d5SCristian Dumitrescu 				obj);
33045074e1d5SCristian Dumitrescu 			return;
33055074e1d5SCristian Dumitrescu 		}
33065074e1d5SCristian Dumitrescu 
330775129cebSChurchill Khangar 		if ((n_tokens >= 5) &&
330875129cebSChurchill Khangar 			(strcmp(tokens[2], "table") == 0) &&
330975129cebSChurchill Khangar 			(strcmp(tokens[4], "add") == 0)) {
331075129cebSChurchill Khangar 			cmd_pipeline_table_add(tokens, n_tokens, out,
331175129cebSChurchill Khangar 				out_size, obj);
331275129cebSChurchill Khangar 			return;
331375129cebSChurchill Khangar 		}
331475129cebSChurchill Khangar 
331575129cebSChurchill Khangar 		if ((n_tokens >= 5) &&
331675129cebSChurchill Khangar 			(strcmp(tokens[2], "table") == 0) &&
331775129cebSChurchill Khangar 			(strcmp(tokens[4], "delete") == 0)) {
331875129cebSChurchill Khangar 			cmd_pipeline_table_delete(tokens, n_tokens, out,
331975129cebSChurchill Khangar 				out_size, obj);
332075129cebSChurchill Khangar 			return;
332175129cebSChurchill Khangar 		}
332275129cebSChurchill Khangar 
332375129cebSChurchill Khangar 		if ((n_tokens >= 5) &&
332475129cebSChurchill Khangar 			(strcmp(tokens[2], "table") == 0) &&
332575129cebSChurchill Khangar 			(strcmp(tokens[4], "default") == 0)) {
332675129cebSChurchill Khangar 			cmd_pipeline_table_default(tokens, n_tokens, out,
332775129cebSChurchill Khangar 				out_size, obj);
332875129cebSChurchill Khangar 			return;
332975129cebSChurchill Khangar 		}
333075129cebSChurchill Khangar 
333175129cebSChurchill Khangar 		if ((n_tokens >= 5) &&
333275129cebSChurchill Khangar 			(strcmp(tokens[2], "table") == 0) &&
333375129cebSChurchill Khangar 			(strcmp(tokens[4], "show") == 0)) {
333475129cebSChurchill Khangar 			cmd_pipeline_table_show(tokens, n_tokens, out,
333575129cebSChurchill Khangar 				out_size, obj);
333675129cebSChurchill Khangar 			return;
333775129cebSChurchill Khangar 		}
333875129cebSChurchill Khangar 
3339598fe0ddSCristian Dumitrescu 		if ((n_tokens >= 6) &&
3340598fe0ddSCristian Dumitrescu 			(strcmp(tokens[2], "selector") == 0) &&
3341598fe0ddSCristian Dumitrescu 			(strcmp(tokens[4], "group") == 0) &&
3342598fe0ddSCristian Dumitrescu 			(strcmp(tokens[5], "add") == 0)) {
3343598fe0ddSCristian Dumitrescu 			cmd_pipeline_selector_group_add(tokens, n_tokens, out,
3344598fe0ddSCristian Dumitrescu 				out_size, obj);
3345598fe0ddSCristian Dumitrescu 			return;
3346598fe0ddSCristian Dumitrescu 		}
3347598fe0ddSCristian Dumitrescu 
3348598fe0ddSCristian Dumitrescu 		if ((n_tokens >= 6) &&
3349598fe0ddSCristian Dumitrescu 			(strcmp(tokens[2], "selector") == 0) &&
3350598fe0ddSCristian Dumitrescu 			(strcmp(tokens[4], "group") == 0) &&
3351598fe0ddSCristian Dumitrescu 			(strcmp(tokens[5], "delete") == 0)) {
3352598fe0ddSCristian Dumitrescu 			cmd_pipeline_selector_group_delete(tokens, n_tokens, out,
3353598fe0ddSCristian Dumitrescu 				out_size, obj);
3354598fe0ddSCristian Dumitrescu 			return;
3355598fe0ddSCristian Dumitrescu 		}
3356598fe0ddSCristian Dumitrescu 
3357598fe0ddSCristian Dumitrescu 		if ((n_tokens >= 7) &&
3358598fe0ddSCristian Dumitrescu 			(strcmp(tokens[2], "selector") == 0) &&
3359598fe0ddSCristian Dumitrescu 			(strcmp(tokens[4], "group") == 0) &&
3360598fe0ddSCristian Dumitrescu 			(strcmp(tokens[5], "member") == 0) &&
3361598fe0ddSCristian Dumitrescu 			(strcmp(tokens[6], "add") == 0)) {
3362598fe0ddSCristian Dumitrescu 			cmd_pipeline_selector_group_member_add(tokens, n_tokens, out,
3363598fe0ddSCristian Dumitrescu 				out_size, obj);
3364598fe0ddSCristian Dumitrescu 			return;
3365598fe0ddSCristian Dumitrescu 		}
3366598fe0ddSCristian Dumitrescu 
3367598fe0ddSCristian Dumitrescu 		if ((n_tokens >= 7) &&
3368598fe0ddSCristian Dumitrescu 			(strcmp(tokens[2], "selector") == 0) &&
3369598fe0ddSCristian Dumitrescu 			(strcmp(tokens[4], "group") == 0) &&
3370598fe0ddSCristian Dumitrescu 			(strcmp(tokens[5], "member") == 0) &&
3371598fe0ddSCristian Dumitrescu 			(strcmp(tokens[6], "delete") == 0)) {
3372598fe0ddSCristian Dumitrescu 			cmd_pipeline_selector_group_member_delete(tokens, n_tokens, out,
3373598fe0ddSCristian Dumitrescu 				out_size, obj);
3374598fe0ddSCristian Dumitrescu 			return;
3375598fe0ddSCristian Dumitrescu 		}
3376598fe0ddSCristian Dumitrescu 
3377598fe0ddSCristian Dumitrescu 		if ((n_tokens >= 5) &&
3378598fe0ddSCristian Dumitrescu 			(strcmp(tokens[2], "selector") == 0) &&
3379598fe0ddSCristian Dumitrescu 			(strcmp(tokens[4], "show") == 0)) {
3380598fe0ddSCristian Dumitrescu 			cmd_pipeline_selector_show(tokens, n_tokens, out,
3381598fe0ddSCristian Dumitrescu 				out_size, obj);
3382598fe0ddSCristian Dumitrescu 			return;
3383598fe0ddSCristian Dumitrescu 		}
3384598fe0ddSCristian Dumitrescu 
33858bd4862fSCristian Dumitrescu 		if ((n_tokens >= 5) &&
33868bd4862fSCristian Dumitrescu 			(strcmp(tokens[2], "learner") == 0) &&
33878bd4862fSCristian Dumitrescu 			(strcmp(tokens[4], "default") == 0)) {
33888bd4862fSCristian Dumitrescu 			cmd_pipeline_learner_default(tokens, n_tokens, out,
33898bd4862fSCristian Dumitrescu 				out_size, obj);
33908bd4862fSCristian Dumitrescu 			return;
33918bd4862fSCristian Dumitrescu 		}
33928bd4862fSCristian Dumitrescu 
33935074e1d5SCristian Dumitrescu 		if ((n_tokens >= 3) &&
339475129cebSChurchill Khangar 			(strcmp(tokens[2], "commit") == 0)) {
339575129cebSChurchill Khangar 			cmd_pipeline_commit(tokens, n_tokens, out,
339675129cebSChurchill Khangar 				out_size, obj);
339775129cebSChurchill Khangar 			return;
339875129cebSChurchill Khangar 		}
339975129cebSChurchill Khangar 
340075129cebSChurchill Khangar 		if ((n_tokens >= 3) &&
340175129cebSChurchill Khangar 			(strcmp(tokens[2], "abort") == 0)) {
340275129cebSChurchill Khangar 			cmd_pipeline_abort(tokens, n_tokens, out,
34035074e1d5SCristian Dumitrescu 				out_size, obj);
34045074e1d5SCristian Dumitrescu 			return;
34055074e1d5SCristian Dumitrescu 		}
34065074e1d5SCristian Dumitrescu 
34075074e1d5SCristian Dumitrescu 		if ((n_tokens >= 3) &&
340864cfcebdSCristian Dumitrescu 			(strcmp(tokens[2], "regrd") == 0)) {
340964cfcebdSCristian Dumitrescu 			cmd_pipeline_regrd(tokens, n_tokens, out, out_size, obj);
341064cfcebdSCristian Dumitrescu 			return;
341164cfcebdSCristian Dumitrescu 		}
341264cfcebdSCristian Dumitrescu 
341364cfcebdSCristian Dumitrescu 		if ((n_tokens >= 3) &&
341464cfcebdSCristian Dumitrescu 			(strcmp(tokens[2], "regwr") == 0)) {
341564cfcebdSCristian Dumitrescu 			cmd_pipeline_regwr(tokens, n_tokens, out, out_size, obj);
341664cfcebdSCristian Dumitrescu 			return;
341764cfcebdSCristian Dumitrescu 		}
341864cfcebdSCristian Dumitrescu 
3419f38913b7SCristian Dumitrescu 		if ((n_tokens >= 6) &&
3420f38913b7SCristian Dumitrescu 			(strcmp(tokens[2], "meter") == 0) &&
3421f38913b7SCristian Dumitrescu 			(strcmp(tokens[3], "profile") == 0) &&
3422f38913b7SCristian Dumitrescu 			(strcmp(tokens[5], "add") == 0)) {
3423f38913b7SCristian Dumitrescu 			cmd_pipeline_meter_profile_add(tokens, n_tokens, out, out_size, obj);
3424f38913b7SCristian Dumitrescu 			return;
3425f38913b7SCristian Dumitrescu 		}
3426f38913b7SCristian Dumitrescu 
3427f38913b7SCristian Dumitrescu 		if ((n_tokens >= 6) &&
3428f38913b7SCristian Dumitrescu 			(strcmp(tokens[2], "meter") == 0) &&
3429f38913b7SCristian Dumitrescu 			(strcmp(tokens[3], "profile") == 0) &&
3430f38913b7SCristian Dumitrescu 			(strcmp(tokens[5], "delete") == 0)) {
3431f38913b7SCristian Dumitrescu 			cmd_pipeline_meter_profile_delete(tokens, n_tokens, out, out_size, obj);
3432f38913b7SCristian Dumitrescu 			return;
3433f38913b7SCristian Dumitrescu 		}
3434f38913b7SCristian Dumitrescu 
343512eda78dSCristian Dumitrescu 		if (n_tokens >= 9 && !strcmp(tokens[2], "meter") && !strcmp(tokens[4], "reset")) {
3436f38913b7SCristian Dumitrescu 			cmd_pipeline_meter_reset(tokens, n_tokens, out, out_size, obj);
3437f38913b7SCristian Dumitrescu 			return;
3438f38913b7SCristian Dumitrescu 		}
3439f38913b7SCristian Dumitrescu 
344012eda78dSCristian Dumitrescu 		if (n_tokens >= 9 && !strcmp(tokens[2], "meter") && !strcmp(tokens[4], "set")) {
3441f38913b7SCristian Dumitrescu 			cmd_pipeline_meter_set(tokens, n_tokens, out, out_size, obj);
3442f38913b7SCristian Dumitrescu 			return;
3443f38913b7SCristian Dumitrescu 		}
3444f38913b7SCristian Dumitrescu 
344512eda78dSCristian Dumitrescu 		if (n_tokens >= 9 && !strcmp(tokens[2], "meter") && !strcmp(tokens[4], "stats")) {
3446f38913b7SCristian Dumitrescu 			cmd_pipeline_meter_stats(tokens, n_tokens, out, out_size, obj);
3447f38913b7SCristian Dumitrescu 			return;
3448f38913b7SCristian Dumitrescu 		}
3449f38913b7SCristian Dumitrescu 
345064cfcebdSCristian Dumitrescu 		if ((n_tokens >= 3) &&
34515074e1d5SCristian Dumitrescu 			(strcmp(tokens[2], "stats") == 0)) {
34525074e1d5SCristian Dumitrescu 			cmd_pipeline_stats(tokens, n_tokens, out, out_size,
34535074e1d5SCristian Dumitrescu 				obj);
34545074e1d5SCristian Dumitrescu 			return;
34555074e1d5SCristian Dumitrescu 		}
345617225455SCristian Dumitrescu 
345717225455SCristian Dumitrescu 		if ((n_tokens >= 4) &&
345817225455SCristian Dumitrescu 			(strcmp(tokens[2], "mirror") == 0) &&
345917225455SCristian Dumitrescu 			(strcmp(tokens[3], "session") == 0)) {
346017225455SCristian Dumitrescu 			cmd_pipeline_mirror_session(tokens, n_tokens, out, out_size, obj);
346117225455SCristian Dumitrescu 			return;
346217225455SCristian Dumitrescu 		}
34635074e1d5SCristian Dumitrescu 	}
34645074e1d5SCristian Dumitrescu 
34655074e1d5SCristian Dumitrescu 	if (strcmp(tokens[0], "thread") == 0) {
34665074e1d5SCristian Dumitrescu 		if ((n_tokens >= 5) &&
34675074e1d5SCristian Dumitrescu 			(strcmp(tokens[4], "enable") == 0)) {
34685074e1d5SCristian Dumitrescu 			cmd_thread_pipeline_enable(tokens, n_tokens,
34695074e1d5SCristian Dumitrescu 				out, out_size, obj);
34705074e1d5SCristian Dumitrescu 			return;
34715074e1d5SCristian Dumitrescu 		}
34725074e1d5SCristian Dumitrescu 
34735074e1d5SCristian Dumitrescu 		if ((n_tokens >= 5) &&
34745074e1d5SCristian Dumitrescu 			(strcmp(tokens[4], "disable") == 0)) {
34755074e1d5SCristian Dumitrescu 			cmd_thread_pipeline_disable(tokens, n_tokens,
34765074e1d5SCristian Dumitrescu 				out, out_size, obj);
34775074e1d5SCristian Dumitrescu 			return;
34785074e1d5SCristian Dumitrescu 		}
34795074e1d5SCristian Dumitrescu 	}
34805074e1d5SCristian Dumitrescu 
34815074e1d5SCristian Dumitrescu 	snprintf(out, out_size, MSG_CMD_UNKNOWN, tokens[0]);
34825074e1d5SCristian Dumitrescu }
34835074e1d5SCristian Dumitrescu 
34845074e1d5SCristian Dumitrescu int
34855074e1d5SCristian Dumitrescu cli_script_process(const char *file_name,
34865074e1d5SCristian Dumitrescu 	size_t msg_in_len_max,
34875074e1d5SCristian Dumitrescu 	size_t msg_out_len_max,
34885074e1d5SCristian Dumitrescu 	void *obj)
34895074e1d5SCristian Dumitrescu {
34905074e1d5SCristian Dumitrescu 	char *msg_in = NULL, *msg_out = NULL;
34915074e1d5SCristian Dumitrescu 	FILE *f = NULL;
34925074e1d5SCristian Dumitrescu 
34935074e1d5SCristian Dumitrescu 	/* Check input arguments */
34945074e1d5SCristian Dumitrescu 	if ((file_name == NULL) ||
34955074e1d5SCristian Dumitrescu 		(strlen(file_name) == 0) ||
34965074e1d5SCristian Dumitrescu 		(msg_in_len_max == 0) ||
34975074e1d5SCristian Dumitrescu 		(msg_out_len_max == 0))
34985074e1d5SCristian Dumitrescu 		return -EINVAL;
34995074e1d5SCristian Dumitrescu 
35005074e1d5SCristian Dumitrescu 	msg_in = malloc(msg_in_len_max + 1);
35015074e1d5SCristian Dumitrescu 	msg_out = malloc(msg_out_len_max + 1);
35025074e1d5SCristian Dumitrescu 	if ((msg_in == NULL) ||
35035074e1d5SCristian Dumitrescu 		(msg_out == NULL)) {
35045074e1d5SCristian Dumitrescu 		free(msg_out);
35055074e1d5SCristian Dumitrescu 		free(msg_in);
35065074e1d5SCristian Dumitrescu 		return -ENOMEM;
35075074e1d5SCristian Dumitrescu 	}
35085074e1d5SCristian Dumitrescu 
35095074e1d5SCristian Dumitrescu 	/* Open input file */
35105074e1d5SCristian Dumitrescu 	f = fopen(file_name, "r");
35115074e1d5SCristian Dumitrescu 	if (f == NULL) {
35125074e1d5SCristian Dumitrescu 		free(msg_out);
35135074e1d5SCristian Dumitrescu 		free(msg_in);
35145074e1d5SCristian Dumitrescu 		return -EIO;
35155074e1d5SCristian Dumitrescu 	}
35165074e1d5SCristian Dumitrescu 
35175074e1d5SCristian Dumitrescu 	/* Read file */
35185074e1d5SCristian Dumitrescu 	for ( ; ; ) {
35195074e1d5SCristian Dumitrescu 		if (fgets(msg_in, msg_in_len_max + 1, f) == NULL)
35205074e1d5SCristian Dumitrescu 			break;
35215074e1d5SCristian Dumitrescu 
35225074e1d5SCristian Dumitrescu 		printf("%s", msg_in);
35235074e1d5SCristian Dumitrescu 		msg_out[0] = 0;
35245074e1d5SCristian Dumitrescu 
35255074e1d5SCristian Dumitrescu 		cli_process(msg_in,
35265074e1d5SCristian Dumitrescu 			msg_out,
35275074e1d5SCristian Dumitrescu 			msg_out_len_max,
35285074e1d5SCristian Dumitrescu 			obj);
35295074e1d5SCristian Dumitrescu 
35305074e1d5SCristian Dumitrescu 		if (strlen(msg_out))
35315074e1d5SCristian Dumitrescu 			printf("%s", msg_out);
35325074e1d5SCristian Dumitrescu 	}
35335074e1d5SCristian Dumitrescu 
35345074e1d5SCristian Dumitrescu 	/* Close file */
35355074e1d5SCristian Dumitrescu 	fclose(f);
35365074e1d5SCristian Dumitrescu 	free(msg_out);
35375074e1d5SCristian Dumitrescu 	free(msg_in);
35385074e1d5SCristian Dumitrescu 	return 0;
35395074e1d5SCristian Dumitrescu }
3540