xref: /dpdk/examples/pipeline/cli.c (revision 83f58a7b7b0a126e3ffa784e90e6e208e7dbec52)
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 
146*83f58a7bSCristian Dumitrescu static void
147*83f58a7bSCristian Dumitrescu table_entry_free(struct rte_swx_table_entry *entry)
148*83f58a7bSCristian Dumitrescu {
149*83f58a7bSCristian Dumitrescu 	if (!entry)
150*83f58a7bSCristian Dumitrescu 		return;
151*83f58a7bSCristian Dumitrescu 
152*83f58a7bSCristian Dumitrescu 	free(entry->key);
153*83f58a7bSCristian Dumitrescu 	free(entry->key_mask);
154*83f58a7bSCristian Dumitrescu 	free(entry->action_data);
155*83f58a7bSCristian Dumitrescu 	free(entry);
156*83f58a7bSCristian Dumitrescu }
157*83f58a7bSCristian Dumitrescu 
158*83f58a7bSCristian Dumitrescu static struct rte_swx_table_entry *
159*83f58a7bSCristian Dumitrescu parse_table_entry(struct rte_swx_ctl_pipeline *p,
160*83f58a7bSCristian Dumitrescu 		  char *table_name,
161*83f58a7bSCristian Dumitrescu 		  char **tokens,
162*83f58a7bSCristian Dumitrescu 		  uint32_t n_tokens)
163*83f58a7bSCristian Dumitrescu {
164*83f58a7bSCristian Dumitrescu 	struct rte_swx_table_entry *entry;
165*83f58a7bSCristian Dumitrescu 	char *line;
166*83f58a7bSCristian Dumitrescu 	uint32_t i;
167*83f58a7bSCristian Dumitrescu 
168*83f58a7bSCristian Dumitrescu 	/* Buffer allocation. */
169*83f58a7bSCristian Dumitrescu 	line = malloc(MAX_LINE_SIZE);
170*83f58a7bSCristian Dumitrescu 	if (!line)
171*83f58a7bSCristian Dumitrescu 		return NULL;
172*83f58a7bSCristian Dumitrescu 
173*83f58a7bSCristian Dumitrescu 	/* Copy tokens to buffer. Since the tokens were initially part of a buffer of size
174*83f58a7bSCristian Dumitrescu 	 * MAX_LINE_LENGTH, it is guaranteed that putting back some of them into a buffer of the
175*83f58a7bSCristian Dumitrescu 	 * same size separated by a single space will not result in buffer overrun.
176*83f58a7bSCristian Dumitrescu 	 */
177*83f58a7bSCristian Dumitrescu 	line[0] = 0;
178*83f58a7bSCristian Dumitrescu 	for (i = 0; i < n_tokens; i++) {
179*83f58a7bSCristian Dumitrescu 		if (i)
180*83f58a7bSCristian Dumitrescu 			strcat(line, " ");
181*83f58a7bSCristian Dumitrescu 
182*83f58a7bSCristian Dumitrescu 		strcat(line, tokens[i]);
183*83f58a7bSCristian Dumitrescu 	}
184*83f58a7bSCristian Dumitrescu 
185*83f58a7bSCristian Dumitrescu 	/* Read the table entry from the input buffer. */
186*83f58a7bSCristian Dumitrescu 	entry = rte_swx_ctl_pipeline_table_entry_read(p, table_name, line, NULL);
187*83f58a7bSCristian Dumitrescu 
188*83f58a7bSCristian Dumitrescu 	/* Buffer free. */
189*83f58a7bSCristian Dumitrescu 	free(line);
190*83f58a7bSCristian Dumitrescu 
191*83f58a7bSCristian Dumitrescu 	return entry;
192*83f58a7bSCristian Dumitrescu }
193*83f58a7bSCristian 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]);
5489043f66aSCristian Dumitrescu 		return;
5499043f66aSCristian Dumitrescu 	}
5509043f66aSCristian Dumitrescu 
5519043f66aSCristian Dumitrescu 	status = rte_swx_pipeline_codegen(spec_file,
5529043f66aSCristian Dumitrescu 					  code_file,
5539043f66aSCristian Dumitrescu 					  &err_line,
5549043f66aSCristian Dumitrescu 					  &err_msg);
5559043f66aSCristian Dumitrescu 
5569043f66aSCristian Dumitrescu 	fclose(spec_file);
5579043f66aSCristian Dumitrescu 	fclose(code_file);
5589043f66aSCristian Dumitrescu 
5599043f66aSCristian Dumitrescu 	if (status) {
5609043f66aSCristian Dumitrescu 		snprintf(out, out_size, "Error %d at line %u: %s\n.",
5619043f66aSCristian Dumitrescu 			status, err_line, err_msg);
5629043f66aSCristian Dumitrescu 		return;
5639043f66aSCristian Dumitrescu 	}
5649043f66aSCristian Dumitrescu }
5656bc14d9fSCristian Dumitrescu 
5666bc14d9fSCristian Dumitrescu static const char cmd_pipeline_libbuild_help[] =
5676bc14d9fSCristian Dumitrescu "pipeline libbuild <code_file> <lib_file>\n";
5686bc14d9fSCristian Dumitrescu 
5696bc14d9fSCristian Dumitrescu static void
5706bc14d9fSCristian Dumitrescu cmd_pipeline_libbuild(char **tokens,
5716bc14d9fSCristian Dumitrescu 	uint32_t n_tokens,
5726bc14d9fSCristian Dumitrescu 	char *out,
5736bc14d9fSCristian Dumitrescu 	size_t out_size,
5746bc14d9fSCristian Dumitrescu 	void *obj __rte_unused)
5756bc14d9fSCristian Dumitrescu {
5766bc14d9fSCristian Dumitrescu 	char *code_file, *lib_file, *obj_file = NULL, *log_file = NULL;
5776bc14d9fSCristian Dumitrescu 	char *install_dir, *cwd = NULL, *buffer = NULL;
5786bc14d9fSCristian Dumitrescu 	size_t length;
5796bc14d9fSCristian Dumitrescu 	int status = 0;
5806bc14d9fSCristian Dumitrescu 
5816bc14d9fSCristian Dumitrescu 	if (n_tokens != 4) {
5826bc14d9fSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
5836bc14d9fSCristian Dumitrescu 		goto free;
5846bc14d9fSCristian Dumitrescu 	}
5856bc14d9fSCristian Dumitrescu 
5866bc14d9fSCristian Dumitrescu 	install_dir = getenv("RTE_INSTALL_DIR");
5876bc14d9fSCristian Dumitrescu 	if (!install_dir) {
5886bc14d9fSCristian Dumitrescu 		cwd = malloc(MAX_LINE_SIZE);
5896bc14d9fSCristian Dumitrescu 		if (!cwd) {
5906bc14d9fSCristian Dumitrescu 			snprintf(out, out_size, MSG_OUT_OF_MEMORY);
5916bc14d9fSCristian Dumitrescu 			goto free;
5926bc14d9fSCristian Dumitrescu 		}
5936bc14d9fSCristian Dumitrescu 
5946bc14d9fSCristian Dumitrescu 		install_dir = getcwd(cwd, MAX_LINE_SIZE);
5956bc14d9fSCristian Dumitrescu 		if (!install_dir) {
5966bc14d9fSCristian Dumitrescu 			snprintf(out, out_size, "Error: Path too long.\n");
5976bc14d9fSCristian Dumitrescu 			goto free;
5986bc14d9fSCristian Dumitrescu 		}
5996bc14d9fSCristian Dumitrescu 	}
6006bc14d9fSCristian Dumitrescu 
6016bc14d9fSCristian Dumitrescu 	snprintf(out, out_size, "Using DPDK source code from \"%s\".\n", install_dir);
6026bc14d9fSCristian Dumitrescu 	out_size -= strlen(out);
6036bc14d9fSCristian Dumitrescu 	out += strlen(out);
6046bc14d9fSCristian Dumitrescu 
6056bc14d9fSCristian Dumitrescu 	code_file = tokens[2];
6066bc14d9fSCristian Dumitrescu 	length = strnlen(code_file, MAX_LINE_SIZE);
6076bc14d9fSCristian Dumitrescu 	if ((length < 3) ||
6086bc14d9fSCristian Dumitrescu 	    (code_file[length - 2] != '.') ||
6096bc14d9fSCristian Dumitrescu 	    (code_file[length - 1] != 'c')) {
6106bc14d9fSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "code_file");
6116bc14d9fSCristian Dumitrescu 		goto free;
6126bc14d9fSCristian Dumitrescu 	}
6136bc14d9fSCristian Dumitrescu 
6146bc14d9fSCristian Dumitrescu 	lib_file = tokens[3];
6156bc14d9fSCristian Dumitrescu 	length = strnlen(lib_file, MAX_LINE_SIZE);
6166bc14d9fSCristian Dumitrescu 	if ((length < 4) ||
6176bc14d9fSCristian Dumitrescu 	    (lib_file[length - 3] != '.') ||
6186bc14d9fSCristian Dumitrescu 	    (lib_file[length - 2] != 's') ||
6196bc14d9fSCristian Dumitrescu 	    (lib_file[length - 1] != 'o')) {
6206bc14d9fSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "lib_file");
6216bc14d9fSCristian Dumitrescu 		goto free;
6226bc14d9fSCristian Dumitrescu 	}
6236bc14d9fSCristian Dumitrescu 
6246bc14d9fSCristian Dumitrescu 	obj_file = malloc(length);
6256bc14d9fSCristian Dumitrescu 	log_file = malloc(length + 2);
6266bc14d9fSCristian Dumitrescu 	if (!obj_file || !log_file) {
6276bc14d9fSCristian Dumitrescu 		snprintf(out, out_size, MSG_OUT_OF_MEMORY);
6286bc14d9fSCristian Dumitrescu 		goto free;
6296bc14d9fSCristian Dumitrescu 	}
6306bc14d9fSCristian Dumitrescu 
6316bc14d9fSCristian Dumitrescu 	memcpy(obj_file, lib_file, length - 2);
6326bc14d9fSCristian Dumitrescu 	obj_file[length - 2] = 'o';
6336bc14d9fSCristian Dumitrescu 	obj_file[length - 1] = 0;
6346bc14d9fSCristian Dumitrescu 
6356bc14d9fSCristian Dumitrescu 	memcpy(log_file, lib_file, length - 2);
6366bc14d9fSCristian Dumitrescu 	log_file[length - 2] = 'l';
6376bc14d9fSCristian Dumitrescu 	log_file[length - 1] = 'o';
6386bc14d9fSCristian Dumitrescu 	log_file[length] = 'g';
6396bc14d9fSCristian Dumitrescu 	log_file[length + 1] = 0;
6406bc14d9fSCristian Dumitrescu 
6416bc14d9fSCristian Dumitrescu 	buffer = malloc(MAX_LINE_SIZE);
6426bc14d9fSCristian Dumitrescu 	if (!buffer) {
6436bc14d9fSCristian Dumitrescu 		snprintf(out, out_size, MSG_OUT_OF_MEMORY);
6446bc14d9fSCristian Dumitrescu 		return;
6456bc14d9fSCristian Dumitrescu 	}
6466bc14d9fSCristian Dumitrescu 
6476bc14d9fSCristian Dumitrescu 	snprintf(buffer,
6486bc14d9fSCristian Dumitrescu 		 MAX_LINE_SIZE,
6496bc14d9fSCristian Dumitrescu 		 "gcc -c -O3 -fpic -Wno-deprecated-declarations -o %s %s "
6506bc14d9fSCristian Dumitrescu 		 "-I %s/lib/pipeline "
6516bc14d9fSCristian Dumitrescu 		 "-I %s/lib/eal/include "
6526bc14d9fSCristian Dumitrescu 		 "-I %s/lib/eal/x86/include "
6536bc14d9fSCristian Dumitrescu 		 "-I %s/lib/eal/include/generic "
6546bc14d9fSCristian Dumitrescu 		 "-I %s/lib/meter "
6556bc14d9fSCristian Dumitrescu 		 "-I %s/lib/port "
6566bc14d9fSCristian Dumitrescu 		 "-I %s/lib/table "
6576bc14d9fSCristian Dumitrescu 		 "-I %s/lib/pipeline "
6586bc14d9fSCristian Dumitrescu 		 "-I %s/config "
6596bc14d9fSCristian Dumitrescu 		 "-I %s/build "
6606bc14d9fSCristian Dumitrescu 		 "-I %s/lib/eal/linux/include "
6616bc14d9fSCristian Dumitrescu 		 ">%s 2>&1 "
6626bc14d9fSCristian Dumitrescu 		 "&& "
6636bc14d9fSCristian Dumitrescu 		 "gcc -shared %s -o %s "
6646bc14d9fSCristian Dumitrescu 		 ">>%s 2>&1",
6656bc14d9fSCristian Dumitrescu 		 obj_file,
6666bc14d9fSCristian Dumitrescu 		 code_file,
6676bc14d9fSCristian Dumitrescu 		 install_dir,
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 		 log_file,
6796bc14d9fSCristian Dumitrescu 		 obj_file,
6806bc14d9fSCristian Dumitrescu 		 lib_file,
6816bc14d9fSCristian Dumitrescu 		 log_file);
6826bc14d9fSCristian Dumitrescu 
6836bc14d9fSCristian Dumitrescu 	status = system(buffer);
6846bc14d9fSCristian Dumitrescu 	if (status) {
6856bc14d9fSCristian Dumitrescu 		snprintf(out,
6866bc14d9fSCristian Dumitrescu 			 out_size,
6876bc14d9fSCristian Dumitrescu 			 "Library build failed, see file \"%s\" for details.\n",
6886bc14d9fSCristian Dumitrescu 			 log_file);
6896bc14d9fSCristian Dumitrescu 		goto free;
6906bc14d9fSCristian Dumitrescu 	}
6916bc14d9fSCristian Dumitrescu 
6926bc14d9fSCristian Dumitrescu free:
6936bc14d9fSCristian Dumitrescu 	free(cwd);
6946bc14d9fSCristian Dumitrescu 	free(obj_file);
6956bc14d9fSCristian Dumitrescu 	free(log_file);
6966bc14d9fSCristian Dumitrescu 	free(buffer);
6976bc14d9fSCristian Dumitrescu }
6986bc14d9fSCristian Dumitrescu 
6995074e1d5SCristian Dumitrescu static const char cmd_pipeline_build_help[] =
70068b95704SCristian Dumitrescu "pipeline <pipeline_name> build lib <lib_file> io <iospec_file> numa <numa_node>\n";
7015074e1d5SCristian Dumitrescu 
7025074e1d5SCristian Dumitrescu static void
7035074e1d5SCristian Dumitrescu cmd_pipeline_build(char **tokens,
7045074e1d5SCristian Dumitrescu 	uint32_t n_tokens,
7055074e1d5SCristian Dumitrescu 	char *out,
7065074e1d5SCristian Dumitrescu 	size_t out_size,
70768b95704SCristian Dumitrescu 	void *obj __rte_unused)
7085074e1d5SCristian Dumitrescu {
70968b95704SCristian Dumitrescu 	struct rte_swx_pipeline *p = NULL;
71068b95704SCristian Dumitrescu 	struct rte_swx_ctl_pipeline *ctl = NULL;
71168b95704SCristian Dumitrescu 	char *pipeline_name, *lib_file_name, *iospec_file_name;
71268b95704SCristian Dumitrescu 	FILE *iospec_file = NULL;
71368b95704SCristian Dumitrescu 	uint32_t numa_node = 0;
71468b95704SCristian Dumitrescu 	int status = 0;
7155074e1d5SCristian Dumitrescu 
71668b95704SCristian Dumitrescu 	/* Parsing. */
71768b95704SCristian Dumitrescu 	if (n_tokens != 9) {
7185074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
7195074e1d5SCristian Dumitrescu 		return;
7205074e1d5SCristian Dumitrescu 	}
7215074e1d5SCristian Dumitrescu 
72268b95704SCristian Dumitrescu 	pipeline_name = tokens[1];
72368b95704SCristian Dumitrescu 
72468b95704SCristian Dumitrescu 	if (strcmp(tokens[2], "build")) {
72568b95704SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "build");
7265074e1d5SCristian Dumitrescu 		return;
7275074e1d5SCristian Dumitrescu 	}
7285074e1d5SCristian Dumitrescu 
72968b95704SCristian Dumitrescu 	if (strcmp(tokens[3], "lib")) {
73068b95704SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "lib");
7315074e1d5SCristian Dumitrescu 		return;
7325074e1d5SCristian Dumitrescu 	}
7335074e1d5SCristian Dumitrescu 
73468b95704SCristian Dumitrescu 	lib_file_name = tokens[4];
73568b95704SCristian Dumitrescu 
73668b95704SCristian Dumitrescu 	if (strcmp(tokens[5], "io")) {
73768b95704SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "io");
73868b95704SCristian Dumitrescu 		return;
73968b95704SCristian Dumitrescu 	}
74068b95704SCristian Dumitrescu 
74168b95704SCristian Dumitrescu 	iospec_file_name = tokens[6];
74268b95704SCristian Dumitrescu 
74368b95704SCristian Dumitrescu 	if (strcmp(tokens[7], "numa")) {
74468b95704SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "numa");
74568b95704SCristian Dumitrescu 		return;
74668b95704SCristian Dumitrescu 	}
74768b95704SCristian Dumitrescu 
74868b95704SCristian Dumitrescu 	if (parser_read_uint32(&numa_node, tokens[8])) {
74968b95704SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "numa_node");
75068b95704SCristian Dumitrescu 		return;
75168b95704SCristian Dumitrescu 	}
75268b95704SCristian Dumitrescu 
75368b95704SCristian Dumitrescu 	/* I/O spec file open. */
75468b95704SCristian Dumitrescu 	iospec_file = fopen(iospec_file_name, "r");
75568b95704SCristian Dumitrescu 	if (!iospec_file) {
75668b95704SCristian Dumitrescu 		snprintf(out, out_size, "Cannot open file \"%s\".\n", iospec_file_name);
75768b95704SCristian Dumitrescu 		return;
75868b95704SCristian Dumitrescu 	}
75968b95704SCristian Dumitrescu 
76068b95704SCristian Dumitrescu 	status = rte_swx_pipeline_build_from_lib(&p,
76168b95704SCristian Dumitrescu 						 pipeline_name,
76268b95704SCristian Dumitrescu 						 lib_file_name,
76368b95704SCristian Dumitrescu 						 iospec_file,
76468b95704SCristian Dumitrescu 						 (int)numa_node);
7655074e1d5SCristian Dumitrescu 	if (status) {
76668b95704SCristian Dumitrescu 		snprintf(out, out_size, "Pipeline build failed (%d).", status);
76768b95704SCristian Dumitrescu 		goto free;
7685074e1d5SCristian Dumitrescu 	}
7695074e1d5SCristian Dumitrescu 
77068b95704SCristian Dumitrescu 	ctl = rte_swx_ctl_pipeline_create(p);
77168b95704SCristian Dumitrescu 	if (!ctl) {
7725074e1d5SCristian Dumitrescu 		snprintf(out, out_size, "Pipeline control create failed.");
77368b95704SCristian Dumitrescu 		goto free;
7745074e1d5SCristian Dumitrescu 	}
77568b95704SCristian Dumitrescu 
77668b95704SCristian Dumitrescu free:
77768b95704SCristian Dumitrescu 	if (status)
77868b95704SCristian Dumitrescu 		rte_swx_pipeline_free(p);
77968b95704SCristian Dumitrescu 
78068b95704SCristian Dumitrescu 	if (iospec_file)
78168b95704SCristian Dumitrescu 		fclose(iospec_file);
7825074e1d5SCristian Dumitrescu }
7835074e1d5SCristian Dumitrescu 
78475129cebSChurchill Khangar static int
78575129cebSChurchill Khangar pipeline_table_entries_add(struct rte_swx_ctl_pipeline *p,
78675129cebSChurchill Khangar 			   const char *table_name,
78775129cebSChurchill Khangar 			   FILE *file,
78875129cebSChurchill Khangar 			   uint32_t *file_line_number)
78975129cebSChurchill Khangar {
79075129cebSChurchill Khangar 	char *line = NULL;
79175129cebSChurchill Khangar 	uint32_t line_id = 0;
79275129cebSChurchill Khangar 	int status = 0;
79375129cebSChurchill Khangar 
79475129cebSChurchill Khangar 	/* Buffer allocation. */
79575129cebSChurchill Khangar 	line = malloc(MAX_LINE_SIZE);
79675129cebSChurchill Khangar 	if (!line)
79775129cebSChurchill Khangar 		return -ENOMEM;
79875129cebSChurchill Khangar 
79975129cebSChurchill Khangar 	/* File read. */
80075129cebSChurchill Khangar 	for (line_id = 1; ; line_id++) {
80175129cebSChurchill Khangar 		struct rte_swx_table_entry *entry;
80275129cebSChurchill Khangar 		int is_blank_or_comment;
80375129cebSChurchill Khangar 
80475129cebSChurchill Khangar 		if (fgets(line, MAX_LINE_SIZE, file) == NULL)
80575129cebSChurchill Khangar 			break;
80675129cebSChurchill Khangar 
80775129cebSChurchill Khangar 		entry = rte_swx_ctl_pipeline_table_entry_read(p,
80875129cebSChurchill Khangar 							      table_name,
80975129cebSChurchill Khangar 							      line,
81075129cebSChurchill Khangar 							      &is_blank_or_comment);
81175129cebSChurchill Khangar 		if (!entry) {
81275129cebSChurchill Khangar 			if (is_blank_or_comment)
81375129cebSChurchill Khangar 				continue;
81475129cebSChurchill Khangar 
81575129cebSChurchill Khangar 			status = -EINVAL;
81675129cebSChurchill Khangar 			goto error;
81775129cebSChurchill Khangar 		}
81875129cebSChurchill Khangar 
81975129cebSChurchill Khangar 		status = rte_swx_ctl_pipeline_table_entry_add(p,
82075129cebSChurchill Khangar 							      table_name,
82175129cebSChurchill Khangar 							      entry);
82275129cebSChurchill Khangar 		table_entry_free(entry);
82375129cebSChurchill Khangar 		if (status)
82475129cebSChurchill Khangar 			goto error;
82575129cebSChurchill Khangar 	}
82675129cebSChurchill Khangar 
82775129cebSChurchill Khangar error:
82875129cebSChurchill Khangar 	free(line);
82975129cebSChurchill Khangar 	*file_line_number = line_id;
83075129cebSChurchill Khangar 	return status;
83175129cebSChurchill Khangar }
83275129cebSChurchill Khangar 
83375129cebSChurchill Khangar static const char cmd_pipeline_table_add_help[] =
83475129cebSChurchill Khangar "pipeline <pipeline_name> table <table_name> add <file_name>\n";
8355074e1d5SCristian Dumitrescu 
8365074e1d5SCristian Dumitrescu static void
83775129cebSChurchill Khangar cmd_pipeline_table_add(char **tokens,
8385074e1d5SCristian Dumitrescu 		       uint32_t n_tokens,
8395074e1d5SCristian Dumitrescu 		       char *out,
8405074e1d5SCristian Dumitrescu 		       size_t out_size,
841b9559f94SCristian Dumitrescu 		       void *obj __rte_unused)
8425074e1d5SCristian Dumitrescu {
843b9559f94SCristian Dumitrescu 	struct rte_swx_ctl_pipeline *ctl;
84475129cebSChurchill Khangar 	char *pipeline_name, *table_name, *file_name;
84575129cebSChurchill Khangar 	FILE *file = NULL;
84675129cebSChurchill Khangar 	uint32_t file_line_number = 0;
8475074e1d5SCristian Dumitrescu 	int status;
8485074e1d5SCristian Dumitrescu 
84975129cebSChurchill Khangar 	if (n_tokens != 6) {
8505074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
8515074e1d5SCristian Dumitrescu 		return;
8525074e1d5SCristian Dumitrescu 	}
8535074e1d5SCristian Dumitrescu 
8545074e1d5SCristian Dumitrescu 	pipeline_name = tokens[1];
855b9559f94SCristian Dumitrescu 	ctl = rte_swx_ctl_pipeline_find(pipeline_name);
856b9559f94SCristian Dumitrescu 	if (!ctl) {
8575074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
8585074e1d5SCristian Dumitrescu 		return;
8595074e1d5SCristian Dumitrescu 	}
8605074e1d5SCristian Dumitrescu 
86175129cebSChurchill Khangar 	table_name = tokens[3];
86275129cebSChurchill Khangar 
86375129cebSChurchill Khangar 	file_name = tokens[5];
86475129cebSChurchill Khangar 	file = fopen(file_name, "r");
86575129cebSChurchill Khangar 	if (!file) {
86675129cebSChurchill Khangar 		snprintf(out, out_size, "Cannot open file %s.\n", file_name);
86775129cebSChurchill Khangar 		return;
86875129cebSChurchill Khangar 	}
86975129cebSChurchill Khangar 
870b9559f94SCristian Dumitrescu 	status = pipeline_table_entries_add(ctl,
87175129cebSChurchill Khangar 					    table_name,
87275129cebSChurchill Khangar 					    file,
87375129cebSChurchill Khangar 					    &file_line_number);
87475129cebSChurchill Khangar 	if (status)
87575129cebSChurchill Khangar 		snprintf(out, out_size, "Invalid entry in file %s at line %u\n",
87675129cebSChurchill Khangar 			 file_name,
87775129cebSChurchill Khangar 			 file_line_number);
87875129cebSChurchill Khangar 
87975129cebSChurchill Khangar 	fclose(file);
88075129cebSChurchill Khangar }
88175129cebSChurchill Khangar 
88275129cebSChurchill Khangar static int
88375129cebSChurchill Khangar pipeline_table_entries_delete(struct rte_swx_ctl_pipeline *p,
88475129cebSChurchill Khangar 			      const char *table_name,
88575129cebSChurchill Khangar 			      FILE *file,
88675129cebSChurchill Khangar 			      uint32_t *file_line_number)
88775129cebSChurchill Khangar {
88875129cebSChurchill Khangar 	char *line = NULL;
88975129cebSChurchill Khangar 	uint32_t line_id = 0;
89075129cebSChurchill Khangar 	int status = 0;
89175129cebSChurchill Khangar 
89275129cebSChurchill Khangar 	/* Buffer allocation. */
89375129cebSChurchill Khangar 	line = malloc(MAX_LINE_SIZE);
89475129cebSChurchill Khangar 	if (!line)
89575129cebSChurchill Khangar 		return -ENOMEM;
89675129cebSChurchill Khangar 
89775129cebSChurchill Khangar 	/* File read. */
89875129cebSChurchill Khangar 	for (line_id = 1; ; line_id++) {
89975129cebSChurchill Khangar 		struct rte_swx_table_entry *entry;
90075129cebSChurchill Khangar 		int is_blank_or_comment;
90175129cebSChurchill Khangar 
90275129cebSChurchill Khangar 		if (fgets(line, MAX_LINE_SIZE, file) == NULL)
90375129cebSChurchill Khangar 			break;
90475129cebSChurchill Khangar 
90575129cebSChurchill Khangar 		entry = rte_swx_ctl_pipeline_table_entry_read(p,
90675129cebSChurchill Khangar 							      table_name,
90775129cebSChurchill Khangar 							      line,
90875129cebSChurchill Khangar 							      &is_blank_or_comment);
90975129cebSChurchill Khangar 		if (!entry) {
91075129cebSChurchill Khangar 			if (is_blank_or_comment)
91175129cebSChurchill Khangar 				continue;
91275129cebSChurchill Khangar 
91375129cebSChurchill Khangar 			status = -EINVAL;
91475129cebSChurchill Khangar 			goto error;
91575129cebSChurchill Khangar 		}
91675129cebSChurchill Khangar 
91775129cebSChurchill Khangar 		status = rte_swx_ctl_pipeline_table_entry_delete(p,
91875129cebSChurchill Khangar 								 table_name,
91975129cebSChurchill Khangar 								 entry);
92075129cebSChurchill Khangar 		table_entry_free(entry);
92175129cebSChurchill Khangar 		if (status)
92275129cebSChurchill Khangar 			goto error;
92375129cebSChurchill Khangar 	}
92475129cebSChurchill Khangar 
92575129cebSChurchill Khangar error:
92675129cebSChurchill Khangar 	*file_line_number = line_id;
92775129cebSChurchill Khangar 	free(line);
92875129cebSChurchill Khangar 	return status;
92975129cebSChurchill Khangar }
93075129cebSChurchill Khangar 
93175129cebSChurchill Khangar static const char cmd_pipeline_table_delete_help[] =
93275129cebSChurchill Khangar "pipeline <pipeline_name> table <table_name> delete <file_name>\n";
93375129cebSChurchill Khangar 
93475129cebSChurchill Khangar static void
93575129cebSChurchill Khangar cmd_pipeline_table_delete(char **tokens,
93675129cebSChurchill Khangar 			  uint32_t n_tokens,
93775129cebSChurchill Khangar 			  char *out,
93875129cebSChurchill Khangar 			  size_t out_size,
939b9559f94SCristian Dumitrescu 			  void *obj __rte_unused)
94075129cebSChurchill Khangar {
941b9559f94SCristian Dumitrescu 	struct rte_swx_ctl_pipeline *ctl;
94275129cebSChurchill Khangar 	char *pipeline_name, *table_name, *file_name;
94375129cebSChurchill Khangar 	FILE *file = NULL;
94475129cebSChurchill Khangar 	uint32_t file_line_number = 0;
94575129cebSChurchill Khangar 	int status;
94675129cebSChurchill Khangar 
94775129cebSChurchill Khangar 	if (n_tokens != 6) {
94875129cebSChurchill Khangar 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
94975129cebSChurchill Khangar 		return;
95075129cebSChurchill Khangar 	}
95175129cebSChurchill Khangar 
95275129cebSChurchill Khangar 	pipeline_name = tokens[1];
953b9559f94SCristian Dumitrescu 	ctl = rte_swx_ctl_pipeline_find(pipeline_name);
954b9559f94SCristian Dumitrescu 	if (!ctl) {
95575129cebSChurchill Khangar 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
9565074e1d5SCristian Dumitrescu 		return;
9575074e1d5SCristian Dumitrescu 	}
9585074e1d5SCristian Dumitrescu 
9595074e1d5SCristian Dumitrescu 	table_name = tokens[3];
9605074e1d5SCristian Dumitrescu 
96175129cebSChurchill Khangar 	file_name = tokens[5];
96275129cebSChurchill Khangar 	file = fopen(file_name, "r");
96375129cebSChurchill Khangar 	if (!file) {
96475129cebSChurchill Khangar 		snprintf(out, out_size, "Cannot open file %s.\n", file_name);
9655074e1d5SCristian Dumitrescu 		return;
9665074e1d5SCristian Dumitrescu 	}
9675074e1d5SCristian Dumitrescu 
968b9559f94SCristian Dumitrescu 	status = pipeline_table_entries_delete(ctl,
96975129cebSChurchill Khangar 					       table_name,
97075129cebSChurchill Khangar 					       file,
97175129cebSChurchill Khangar 					       &file_line_number);
97275129cebSChurchill Khangar 	if (status)
97375129cebSChurchill Khangar 		snprintf(out, out_size, "Invalid entry in file %s at line %u\n",
97475129cebSChurchill Khangar 			 file_name,
97575129cebSChurchill Khangar 			 file_line_number);
9765074e1d5SCristian Dumitrescu 
97775129cebSChurchill Khangar 	fclose(file);
9785074e1d5SCristian Dumitrescu }
9795074e1d5SCristian Dumitrescu 
98075129cebSChurchill Khangar static int
98175129cebSChurchill Khangar pipeline_table_default_entry_add(struct rte_swx_ctl_pipeline *p,
98275129cebSChurchill Khangar 				 const char *table_name,
98375129cebSChurchill Khangar 				 FILE *file,
98475129cebSChurchill Khangar 				 uint32_t *file_line_number)
98575129cebSChurchill Khangar {
98675129cebSChurchill Khangar 	char *line = NULL;
98775129cebSChurchill Khangar 	uint32_t line_id = 0;
98875129cebSChurchill Khangar 	int status = 0;
9895074e1d5SCristian Dumitrescu 
9905074e1d5SCristian Dumitrescu 	/* Buffer allocation. */
99175129cebSChurchill Khangar 	line = malloc(MAX_LINE_SIZE);
99275129cebSChurchill Khangar 	if (!line)
99375129cebSChurchill Khangar 		return -ENOMEM;
9945074e1d5SCristian Dumitrescu 
99575129cebSChurchill Khangar 	/* File read. */
9965074e1d5SCristian Dumitrescu 	for (line_id = 1; ; line_id++) {
9975074e1d5SCristian Dumitrescu 		struct rte_swx_table_entry *entry;
998cff9a717SCristian Dumitrescu 		int is_blank_or_comment;
9995074e1d5SCristian Dumitrescu 
100075129cebSChurchill Khangar 		if (fgets(line, MAX_LINE_SIZE, file) == NULL)
10015074e1d5SCristian Dumitrescu 			break;
10025074e1d5SCristian Dumitrescu 
100375129cebSChurchill Khangar 		entry = rte_swx_ctl_pipeline_table_entry_read(p,
10045074e1d5SCristian Dumitrescu 							      table_name,
1005cff9a717SCristian Dumitrescu 							      line,
1006cff9a717SCristian Dumitrescu 							      &is_blank_or_comment);
10075074e1d5SCristian Dumitrescu 		if (!entry) {
1008cff9a717SCristian Dumitrescu 			if (is_blank_or_comment)
1009cff9a717SCristian Dumitrescu 				continue;
1010cff9a717SCristian Dumitrescu 
101175129cebSChurchill Khangar 			status = -EINVAL;
10125074e1d5SCristian Dumitrescu 			goto error;
10135074e1d5SCristian Dumitrescu 		}
10145074e1d5SCristian Dumitrescu 
101575129cebSChurchill Khangar 		status = rte_swx_ctl_pipeline_table_default_entry_add(p,
10165074e1d5SCristian Dumitrescu 								      table_name,
10175074e1d5SCristian Dumitrescu 								      entry);
1018275ebefeSCristian Dumitrescu 		table_entry_free(entry);
101975129cebSChurchill Khangar 		if (status)
10205074e1d5SCristian Dumitrescu 			goto error;
10215074e1d5SCristian Dumitrescu 	}
102275129cebSChurchill Khangar 
102375129cebSChurchill Khangar error:
102475129cebSChurchill Khangar 	*file_line_number = line_id;
102575129cebSChurchill Khangar 	free(line);
102675129cebSChurchill Khangar 	return status;
10275074e1d5SCristian Dumitrescu }
10285074e1d5SCristian Dumitrescu 
102975129cebSChurchill Khangar static const char cmd_pipeline_table_default_help[] =
103075129cebSChurchill Khangar "pipeline <pipeline_name> table <table_name> default <file_name>\n";
10315074e1d5SCristian Dumitrescu 
103275129cebSChurchill Khangar static void
103375129cebSChurchill Khangar cmd_pipeline_table_default(char **tokens,
103475129cebSChurchill Khangar 			   uint32_t n_tokens,
103575129cebSChurchill Khangar 			   char *out,
103675129cebSChurchill Khangar 			   size_t out_size,
1037b9559f94SCristian Dumitrescu 			   void *obj __rte_unused)
103875129cebSChurchill Khangar {
1039b9559f94SCristian Dumitrescu 	struct rte_swx_ctl_pipeline *ctl;
104075129cebSChurchill Khangar 	char *pipeline_name, *table_name, *file_name;
104175129cebSChurchill Khangar 	FILE *file = NULL;
104275129cebSChurchill Khangar 	uint32_t file_line_number = 0;
104375129cebSChurchill Khangar 	int status;
10445074e1d5SCristian Dumitrescu 
104575129cebSChurchill Khangar 	if (n_tokens != 6) {
104675129cebSChurchill Khangar 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
104775129cebSChurchill Khangar 		return;
104875129cebSChurchill Khangar 	}
10495074e1d5SCristian Dumitrescu 
105075129cebSChurchill Khangar 	pipeline_name = tokens[1];
1051b9559f94SCristian Dumitrescu 	ctl = rte_swx_ctl_pipeline_find(pipeline_name);
1052b9559f94SCristian Dumitrescu 	if (!ctl) {
105375129cebSChurchill Khangar 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
105475129cebSChurchill Khangar 		return;
105575129cebSChurchill Khangar 	}
105675129cebSChurchill Khangar 
105775129cebSChurchill Khangar 	table_name = tokens[3];
105875129cebSChurchill Khangar 
105975129cebSChurchill Khangar 	file_name = tokens[5];
106075129cebSChurchill Khangar 	file = fopen(file_name, "r");
106175129cebSChurchill Khangar 	if (!file) {
106275129cebSChurchill Khangar 		snprintf(out, out_size, "Cannot open file %s.\n", file_name);
106375129cebSChurchill Khangar 		return;
106475129cebSChurchill Khangar 	}
106575129cebSChurchill Khangar 
1066b9559f94SCristian Dumitrescu 	status = pipeline_table_default_entry_add(ctl,
10675074e1d5SCristian Dumitrescu 						  table_name,
106875129cebSChurchill Khangar 						  file,
106975129cebSChurchill Khangar 						  &file_line_number);
107075129cebSChurchill Khangar 	if (status)
107175129cebSChurchill Khangar 		snprintf(out, out_size, "Invalid entry in file %s at line %u\n",
107275129cebSChurchill Khangar 			 file_name,
107375129cebSChurchill Khangar 			 file_line_number);
1074cff9a717SCristian Dumitrescu 
107575129cebSChurchill Khangar 	fclose(file);
10765074e1d5SCristian Dumitrescu }
10775074e1d5SCristian Dumitrescu 
107875129cebSChurchill Khangar static const char cmd_pipeline_table_show_help[] =
1079a4c1146cSCristian Dumitrescu "pipeline <pipeline_name> table <table_name> show [filename]\n";
108075129cebSChurchill Khangar 
108175129cebSChurchill Khangar static void
108275129cebSChurchill Khangar cmd_pipeline_table_show(char **tokens,
108375129cebSChurchill Khangar 	uint32_t n_tokens,
108475129cebSChurchill Khangar 	char *out,
108575129cebSChurchill Khangar 	size_t out_size,
1086b9559f94SCristian Dumitrescu 	void *obj __rte_unused)
108775129cebSChurchill Khangar {
1088b9559f94SCristian Dumitrescu 	struct rte_swx_ctl_pipeline *ctl;
108975129cebSChurchill Khangar 	char *pipeline_name, *table_name;
1090a4c1146cSCristian Dumitrescu 	FILE *file = NULL;
109175129cebSChurchill Khangar 	int status;
109275129cebSChurchill Khangar 
1093a4c1146cSCristian Dumitrescu 	if (n_tokens != 5 && n_tokens != 6) {
109475129cebSChurchill Khangar 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
109575129cebSChurchill Khangar 		return;
10965074e1d5SCristian Dumitrescu 	}
10975074e1d5SCristian Dumitrescu 
109875129cebSChurchill Khangar 	pipeline_name = tokens[1];
1099b9559f94SCristian Dumitrescu 	ctl = rte_swx_ctl_pipeline_find(pipeline_name);
1100b9559f94SCristian Dumitrescu 	if (!ctl) {
110175129cebSChurchill Khangar 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
110275129cebSChurchill Khangar 		return;
11035074e1d5SCristian Dumitrescu 	}
11045074e1d5SCristian Dumitrescu 
110575129cebSChurchill Khangar 	table_name = tokens[3];
1106a4c1146cSCristian Dumitrescu 	file = (n_tokens == 6) ? fopen(tokens[5], "w") : stdout;
1107a4c1146cSCristian Dumitrescu 	if (!file) {
1108a4c1146cSCristian Dumitrescu 		snprintf(out, out_size, "Cannot open file %s.\n", tokens[5]);
1109a4c1146cSCristian Dumitrescu 		return;
1110a4c1146cSCristian Dumitrescu 	}
1111a4c1146cSCristian Dumitrescu 
1112b9559f94SCristian Dumitrescu 	status = rte_swx_ctl_pipeline_table_fprintf(file, ctl, table_name);
111375129cebSChurchill Khangar 	if (status)
111475129cebSChurchill Khangar 		snprintf(out, out_size, MSG_ARG_INVALID, "table_name");
1115a4c1146cSCristian Dumitrescu 
1116a4c1146cSCristian Dumitrescu 	if (file)
1117a4c1146cSCristian Dumitrescu 		fclose(file);
11185074e1d5SCristian Dumitrescu }
111975129cebSChurchill Khangar 
1120598fe0ddSCristian Dumitrescu static const char cmd_pipeline_selector_group_add_help[] =
1121598fe0ddSCristian Dumitrescu "pipeline <pipeline_name> selector <selector_name> group add\n";
1122598fe0ddSCristian Dumitrescu 
1123598fe0ddSCristian Dumitrescu static void
1124598fe0ddSCristian Dumitrescu cmd_pipeline_selector_group_add(char **tokens,
1125598fe0ddSCristian Dumitrescu 	uint32_t n_tokens,
1126598fe0ddSCristian Dumitrescu 	char *out,
1127598fe0ddSCristian Dumitrescu 	size_t out_size,
1128b9559f94SCristian Dumitrescu 	void *obj __rte_unused)
1129598fe0ddSCristian Dumitrescu {
1130b9559f94SCristian Dumitrescu 	struct rte_swx_ctl_pipeline *ctl;
1131598fe0ddSCristian Dumitrescu 	char *pipeline_name, *selector_name;
1132598fe0ddSCristian Dumitrescu 	uint32_t group_id;
1133598fe0ddSCristian Dumitrescu 	int status;
1134598fe0ddSCristian Dumitrescu 
1135598fe0ddSCristian Dumitrescu 	if (n_tokens != 6) {
1136598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1137598fe0ddSCristian Dumitrescu 		return;
1138598fe0ddSCristian Dumitrescu 	}
1139598fe0ddSCristian Dumitrescu 
1140598fe0ddSCristian Dumitrescu 	pipeline_name = tokens[1];
1141b9559f94SCristian Dumitrescu 	ctl = rte_swx_ctl_pipeline_find(pipeline_name);
1142b9559f94SCristian Dumitrescu 	if (!ctl) {
1143598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
1144598fe0ddSCristian Dumitrescu 		return;
1145598fe0ddSCristian Dumitrescu 	}
1146598fe0ddSCristian Dumitrescu 
1147598fe0ddSCristian Dumitrescu 	if (strcmp(tokens[2], "selector") != 0) {
1148598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "selector");
1149598fe0ddSCristian Dumitrescu 		return;
1150598fe0ddSCristian Dumitrescu 	}
1151598fe0ddSCristian Dumitrescu 
1152598fe0ddSCristian Dumitrescu 	selector_name = tokens[3];
1153598fe0ddSCristian Dumitrescu 
1154598fe0ddSCristian Dumitrescu 	if (strcmp(tokens[4], "group") ||
1155598fe0ddSCristian Dumitrescu 		strcmp(tokens[5], "add")) {
1156598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "group add");
1157598fe0ddSCristian Dumitrescu 		return;
1158598fe0ddSCristian Dumitrescu 	}
1159598fe0ddSCristian Dumitrescu 
1160b9559f94SCristian Dumitrescu 	status = rte_swx_ctl_pipeline_selector_group_add(ctl,
1161598fe0ddSCristian Dumitrescu 		selector_name,
1162598fe0ddSCristian Dumitrescu 		&group_id);
1163598fe0ddSCristian Dumitrescu 	if (status)
1164598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
1165598fe0ddSCristian Dumitrescu 	else
1166598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, "Group ID: %u\n", group_id);
1167598fe0ddSCristian Dumitrescu }
1168598fe0ddSCristian Dumitrescu 
1169598fe0ddSCristian Dumitrescu static const char cmd_pipeline_selector_group_delete_help[] =
1170598fe0ddSCristian Dumitrescu "pipeline <pipeline_name> selector <selector_name> group delete <group_id>\n";
1171598fe0ddSCristian Dumitrescu 
1172598fe0ddSCristian Dumitrescu static void
1173598fe0ddSCristian Dumitrescu cmd_pipeline_selector_group_delete(char **tokens,
1174598fe0ddSCristian Dumitrescu 	uint32_t n_tokens,
1175598fe0ddSCristian Dumitrescu 	char *out,
1176598fe0ddSCristian Dumitrescu 	size_t out_size,
1177b9559f94SCristian Dumitrescu 	void *obj __rte_unused)
1178598fe0ddSCristian Dumitrescu {
1179b9559f94SCristian Dumitrescu 	struct rte_swx_ctl_pipeline *ctl;
1180598fe0ddSCristian Dumitrescu 	char *pipeline_name, *selector_name;
1181598fe0ddSCristian Dumitrescu 	uint32_t group_id;
1182598fe0ddSCristian Dumitrescu 	int status;
1183598fe0ddSCristian Dumitrescu 
1184598fe0ddSCristian Dumitrescu 	if (n_tokens != 7) {
1185598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1186598fe0ddSCristian Dumitrescu 		return;
1187598fe0ddSCristian Dumitrescu 	}
1188598fe0ddSCristian Dumitrescu 
1189598fe0ddSCristian Dumitrescu 	pipeline_name = tokens[1];
1190b9559f94SCristian Dumitrescu 	ctl = rte_swx_ctl_pipeline_find(pipeline_name);
1191b9559f94SCristian Dumitrescu 	if (!ctl) {
1192598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
1193598fe0ddSCristian Dumitrescu 		return;
1194598fe0ddSCristian Dumitrescu 	}
1195598fe0ddSCristian Dumitrescu 
1196598fe0ddSCristian Dumitrescu 	if (strcmp(tokens[2], "selector") != 0) {
1197598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "selector");
1198598fe0ddSCristian Dumitrescu 		return;
1199598fe0ddSCristian Dumitrescu 	}
1200598fe0ddSCristian Dumitrescu 
1201598fe0ddSCristian Dumitrescu 	selector_name = tokens[3];
1202598fe0ddSCristian Dumitrescu 
1203598fe0ddSCristian Dumitrescu 	if (strcmp(tokens[4], "group") ||
1204598fe0ddSCristian Dumitrescu 		strcmp(tokens[5], "delete")) {
1205598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "group delete");
1206598fe0ddSCristian Dumitrescu 		return;
1207598fe0ddSCristian Dumitrescu 	}
1208598fe0ddSCristian Dumitrescu 
1209598fe0ddSCristian Dumitrescu 	if (parser_read_uint32(&group_id, tokens[6]) != 0) {
1210598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "group_id");
1211598fe0ddSCristian Dumitrescu 		return;
1212598fe0ddSCristian Dumitrescu 	}
1213598fe0ddSCristian Dumitrescu 
1214b9559f94SCristian Dumitrescu 	status = rte_swx_ctl_pipeline_selector_group_delete(ctl,
1215598fe0ddSCristian Dumitrescu 		selector_name,
1216598fe0ddSCristian Dumitrescu 		group_id);
1217598fe0ddSCristian Dumitrescu 	if (status)
1218598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
1219598fe0ddSCristian Dumitrescu }
1220598fe0ddSCristian Dumitrescu 
1221598fe0ddSCristian Dumitrescu #define GROUP_MEMBER_INFO_TOKENS_MAX 6
1222598fe0ddSCristian Dumitrescu 
1223598fe0ddSCristian Dumitrescu static int
1224598fe0ddSCristian Dumitrescu token_is_comment(const char *token)
1225598fe0ddSCristian Dumitrescu {
1226598fe0ddSCristian Dumitrescu 	if ((token[0] == '#') ||
1227598fe0ddSCristian Dumitrescu 	    (token[0] == ';') ||
1228598fe0ddSCristian Dumitrescu 	    ((token[0] == '/') && (token[1] == '/')))
1229598fe0ddSCristian Dumitrescu 		return 1; /* TRUE. */
1230598fe0ddSCristian Dumitrescu 
1231598fe0ddSCristian Dumitrescu 	return 0; /* FALSE. */
1232598fe0ddSCristian Dumitrescu }
1233598fe0ddSCristian Dumitrescu 
1234598fe0ddSCristian Dumitrescu static int
1235598fe0ddSCristian Dumitrescu pipeline_selector_group_member_read(const char *string,
1236598fe0ddSCristian Dumitrescu 				      uint32_t *group_id,
1237598fe0ddSCristian Dumitrescu 				      uint32_t *member_id,
1238598fe0ddSCristian Dumitrescu 				      uint32_t *weight,
1239598fe0ddSCristian Dumitrescu 				      int *is_blank_or_comment)
1240598fe0ddSCristian Dumitrescu {
1241598fe0ddSCristian Dumitrescu 	char *token_array[GROUP_MEMBER_INFO_TOKENS_MAX], **tokens;
1242598fe0ddSCristian Dumitrescu 	char *s0 = NULL, *s;
124300b67591SAli Alnubani 	uint32_t n_tokens = 0, group_id_val = 0, member_id_val = 0, weight_val = 0;
1244598fe0ddSCristian Dumitrescu 	int blank_or_comment = 0;
1245598fe0ddSCristian Dumitrescu 
1246598fe0ddSCristian Dumitrescu 	/* Check input arguments. */
1247598fe0ddSCristian Dumitrescu 	if (!string || !string[0])
1248598fe0ddSCristian Dumitrescu 		goto error;
1249598fe0ddSCristian Dumitrescu 
1250598fe0ddSCristian Dumitrescu 	/* Memory allocation. */
1251598fe0ddSCristian Dumitrescu 	s0 = strdup(string);
1252598fe0ddSCristian Dumitrescu 	if (!s0)
1253598fe0ddSCristian Dumitrescu 		goto error;
1254598fe0ddSCristian Dumitrescu 
1255598fe0ddSCristian Dumitrescu 	/* Parse the string into tokens. */
1256598fe0ddSCristian Dumitrescu 	for (s = s0; ; ) {
1257598fe0ddSCristian Dumitrescu 		char *token;
1258598fe0ddSCristian Dumitrescu 
1259598fe0ddSCristian Dumitrescu 		token = strtok_r(s, " \f\n\r\t\v", &s);
1260598fe0ddSCristian Dumitrescu 		if (!token || token_is_comment(token))
1261598fe0ddSCristian Dumitrescu 			break;
1262598fe0ddSCristian Dumitrescu 
1263cfcc7bf8SCristian Dumitrescu 		if (n_tokens >= GROUP_MEMBER_INFO_TOKENS_MAX)
1264598fe0ddSCristian Dumitrescu 			goto error;
1265598fe0ddSCristian Dumitrescu 
1266598fe0ddSCristian Dumitrescu 		token_array[n_tokens] = token;
1267598fe0ddSCristian Dumitrescu 		n_tokens++;
1268598fe0ddSCristian Dumitrescu 	}
1269598fe0ddSCristian Dumitrescu 
1270598fe0ddSCristian Dumitrescu 	if (!n_tokens) {
1271598fe0ddSCristian Dumitrescu 		blank_or_comment = 1;
1272598fe0ddSCristian Dumitrescu 		goto error;
1273598fe0ddSCristian Dumitrescu 	}
1274598fe0ddSCristian Dumitrescu 
1275598fe0ddSCristian Dumitrescu 	tokens = token_array;
1276598fe0ddSCristian Dumitrescu 
1277598fe0ddSCristian Dumitrescu 	if (n_tokens < 4 ||
1278598fe0ddSCristian Dumitrescu 		strcmp(tokens[0], "group") ||
1279598fe0ddSCristian Dumitrescu 		strcmp(tokens[2], "member"))
1280598fe0ddSCristian Dumitrescu 		goto error;
1281598fe0ddSCristian Dumitrescu 
1282598fe0ddSCristian Dumitrescu 	/*
1283598fe0ddSCristian Dumitrescu 	 * Group ID.
1284598fe0ddSCristian Dumitrescu 	 */
1285598fe0ddSCristian Dumitrescu 	if (parser_read_uint32(&group_id_val, tokens[1]) != 0)
1286598fe0ddSCristian Dumitrescu 		goto error;
1287598fe0ddSCristian Dumitrescu 	*group_id = group_id_val;
1288598fe0ddSCristian Dumitrescu 
1289598fe0ddSCristian Dumitrescu 	/*
1290598fe0ddSCristian Dumitrescu 	 * Member ID.
1291598fe0ddSCristian Dumitrescu 	 */
1292598fe0ddSCristian Dumitrescu 	if (parser_read_uint32(&member_id_val, tokens[3]) != 0)
1293598fe0ddSCristian Dumitrescu 		goto error;
1294598fe0ddSCristian Dumitrescu 	*member_id = member_id_val;
1295598fe0ddSCristian Dumitrescu 
1296598fe0ddSCristian Dumitrescu 	tokens += 4;
1297598fe0ddSCristian Dumitrescu 	n_tokens -= 4;
1298598fe0ddSCristian Dumitrescu 
1299598fe0ddSCristian Dumitrescu 	/*
1300598fe0ddSCristian Dumitrescu 	 * Weight.
1301598fe0ddSCristian Dumitrescu 	 */
1302598fe0ddSCristian Dumitrescu 	if (n_tokens && !strcmp(tokens[0], "weight")) {
1303598fe0ddSCristian Dumitrescu 		if (n_tokens < 2)
1304598fe0ddSCristian Dumitrescu 			goto error;
1305598fe0ddSCristian Dumitrescu 
1306598fe0ddSCristian Dumitrescu 		if (parser_read_uint32(&weight_val, tokens[1]) != 0)
1307598fe0ddSCristian Dumitrescu 			goto error;
1308598fe0ddSCristian Dumitrescu 		*weight = weight_val;
1309598fe0ddSCristian Dumitrescu 
1310598fe0ddSCristian Dumitrescu 		tokens += 2;
1311598fe0ddSCristian Dumitrescu 		n_tokens -= 2;
1312598fe0ddSCristian Dumitrescu 	}
1313598fe0ddSCristian Dumitrescu 
1314598fe0ddSCristian Dumitrescu 	if (n_tokens)
1315598fe0ddSCristian Dumitrescu 		goto error;
1316598fe0ddSCristian Dumitrescu 
1317598fe0ddSCristian Dumitrescu 	free(s0);
1318598fe0ddSCristian Dumitrescu 	return 0;
1319598fe0ddSCristian Dumitrescu 
1320598fe0ddSCristian Dumitrescu error:
1321598fe0ddSCristian Dumitrescu 	free(s0);
1322598fe0ddSCristian Dumitrescu 	if (is_blank_or_comment)
1323598fe0ddSCristian Dumitrescu 		*is_blank_or_comment = blank_or_comment;
1324598fe0ddSCristian Dumitrescu 	return -EINVAL;
1325598fe0ddSCristian Dumitrescu }
1326598fe0ddSCristian Dumitrescu 
1327598fe0ddSCristian Dumitrescu static int
1328598fe0ddSCristian Dumitrescu pipeline_selector_group_members_add(struct rte_swx_ctl_pipeline *p,
1329598fe0ddSCristian Dumitrescu 			   const char *selector_name,
1330598fe0ddSCristian Dumitrescu 			   FILE *file,
1331598fe0ddSCristian Dumitrescu 			   uint32_t *file_line_number)
1332598fe0ddSCristian Dumitrescu {
1333598fe0ddSCristian Dumitrescu 	char *line = NULL;
1334598fe0ddSCristian Dumitrescu 	uint32_t line_id = 0;
1335598fe0ddSCristian Dumitrescu 	int status = 0;
1336598fe0ddSCristian Dumitrescu 
1337598fe0ddSCristian Dumitrescu 	/* Buffer allocation. */
1338598fe0ddSCristian Dumitrescu 	line = malloc(MAX_LINE_SIZE);
1339598fe0ddSCristian Dumitrescu 	if (!line)
1340598fe0ddSCristian Dumitrescu 		return -ENOMEM;
1341598fe0ddSCristian Dumitrescu 
1342598fe0ddSCristian Dumitrescu 	/* File read. */
1343598fe0ddSCristian Dumitrescu 	for (line_id = 1; ; line_id++) {
1344598fe0ddSCristian Dumitrescu 		uint32_t group_id, member_id, weight;
1345598fe0ddSCristian Dumitrescu 		int is_blank_or_comment;
1346598fe0ddSCristian Dumitrescu 
1347598fe0ddSCristian Dumitrescu 		if (fgets(line, MAX_LINE_SIZE, file) == NULL)
1348598fe0ddSCristian Dumitrescu 			break;
1349598fe0ddSCristian Dumitrescu 
1350598fe0ddSCristian Dumitrescu 		status = pipeline_selector_group_member_read(line,
1351598fe0ddSCristian Dumitrescu 							      &group_id,
1352598fe0ddSCristian Dumitrescu 							      &member_id,
1353598fe0ddSCristian Dumitrescu 							      &weight,
1354598fe0ddSCristian Dumitrescu 							      &is_blank_or_comment);
1355598fe0ddSCristian Dumitrescu 		if (status) {
1356598fe0ddSCristian Dumitrescu 			if (is_blank_or_comment)
1357598fe0ddSCristian Dumitrescu 				continue;
1358598fe0ddSCristian Dumitrescu 
1359598fe0ddSCristian Dumitrescu 			goto error;
1360598fe0ddSCristian Dumitrescu 		}
1361598fe0ddSCristian Dumitrescu 
1362598fe0ddSCristian Dumitrescu 		status = rte_swx_ctl_pipeline_selector_group_member_add(p,
1363598fe0ddSCristian Dumitrescu 			selector_name,
1364598fe0ddSCristian Dumitrescu 			group_id,
1365598fe0ddSCristian Dumitrescu 			member_id,
1366598fe0ddSCristian Dumitrescu 			weight);
1367598fe0ddSCristian Dumitrescu 		if (status)
1368598fe0ddSCristian Dumitrescu 			goto error;
1369598fe0ddSCristian Dumitrescu 	}
1370598fe0ddSCristian Dumitrescu 
1371598fe0ddSCristian Dumitrescu error:
1372598fe0ddSCristian Dumitrescu 	free(line);
1373598fe0ddSCristian Dumitrescu 	*file_line_number = line_id;
1374598fe0ddSCristian Dumitrescu 	return status;
1375598fe0ddSCristian Dumitrescu }
1376598fe0ddSCristian Dumitrescu 
1377598fe0ddSCristian Dumitrescu static const char cmd_pipeline_selector_group_member_add_help[] =
1378598fe0ddSCristian Dumitrescu "pipeline <pipeline_name> selector <selector_name> group member add <file_name>";
1379598fe0ddSCristian Dumitrescu 
1380598fe0ddSCristian Dumitrescu static void
1381598fe0ddSCristian Dumitrescu cmd_pipeline_selector_group_member_add(char **tokens,
1382598fe0ddSCristian Dumitrescu 	uint32_t n_tokens,
1383598fe0ddSCristian Dumitrescu 	char *out,
1384598fe0ddSCristian Dumitrescu 	size_t out_size,
1385b9559f94SCristian Dumitrescu 	void *obj __rte_unused)
1386598fe0ddSCristian Dumitrescu {
1387b9559f94SCristian Dumitrescu 	struct rte_swx_ctl_pipeline *ctl;
1388598fe0ddSCristian Dumitrescu 	char *pipeline_name, *selector_name, *file_name;
1389598fe0ddSCristian Dumitrescu 	FILE *file = NULL;
1390598fe0ddSCristian Dumitrescu 	uint32_t file_line_number = 0;
1391598fe0ddSCristian Dumitrescu 	int status;
1392598fe0ddSCristian Dumitrescu 
1393598fe0ddSCristian Dumitrescu 	if (n_tokens != 8) {
1394598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1395598fe0ddSCristian Dumitrescu 		return;
1396598fe0ddSCristian Dumitrescu 	}
1397598fe0ddSCristian Dumitrescu 
1398598fe0ddSCristian Dumitrescu 	pipeline_name = tokens[1];
1399b9559f94SCristian Dumitrescu 	ctl = rte_swx_ctl_pipeline_find(pipeline_name);
1400b9559f94SCristian Dumitrescu 	if (!ctl) {
1401598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
1402598fe0ddSCristian Dumitrescu 		return;
1403598fe0ddSCristian Dumitrescu 	}
1404598fe0ddSCristian Dumitrescu 
1405598fe0ddSCristian Dumitrescu 	if (strcmp(tokens[2], "selector") != 0) {
1406598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "selector");
1407598fe0ddSCristian Dumitrescu 		return;
1408598fe0ddSCristian Dumitrescu 	}
1409598fe0ddSCristian Dumitrescu 
1410598fe0ddSCristian Dumitrescu 	selector_name = tokens[3];
1411598fe0ddSCristian Dumitrescu 
1412598fe0ddSCristian Dumitrescu 	if (strcmp(tokens[4], "group") ||
1413598fe0ddSCristian Dumitrescu 		strcmp(tokens[5], "member") ||
1414598fe0ddSCristian Dumitrescu 		strcmp(tokens[6], "add")) {
1415598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "group member add");
1416598fe0ddSCristian Dumitrescu 		return;
1417598fe0ddSCristian Dumitrescu 	}
1418598fe0ddSCristian Dumitrescu 
1419598fe0ddSCristian Dumitrescu 	file_name = tokens[7];
1420598fe0ddSCristian Dumitrescu 	file = fopen(file_name, "r");
1421598fe0ddSCristian Dumitrescu 	if (!file) {
1422598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, "Cannot open file %s.\n", file_name);
1423598fe0ddSCristian Dumitrescu 		return;
1424598fe0ddSCristian Dumitrescu 	}
1425598fe0ddSCristian Dumitrescu 
1426b9559f94SCristian Dumitrescu 	status = pipeline_selector_group_members_add(ctl,
1427598fe0ddSCristian Dumitrescu 					    selector_name,
1428598fe0ddSCristian Dumitrescu 					    file,
1429598fe0ddSCristian Dumitrescu 					    &file_line_number);
1430598fe0ddSCristian Dumitrescu 	if (status)
1431598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, "Invalid entry in file %s at line %u\n",
1432598fe0ddSCristian Dumitrescu 			 file_name,
1433598fe0ddSCristian Dumitrescu 			 file_line_number);
1434598fe0ddSCristian Dumitrescu 
1435598fe0ddSCristian Dumitrescu 	fclose(file);
1436598fe0ddSCristian Dumitrescu }
1437598fe0ddSCristian Dumitrescu 
1438598fe0ddSCristian Dumitrescu static int
1439598fe0ddSCristian Dumitrescu pipeline_selector_group_members_delete(struct rte_swx_ctl_pipeline *p,
1440598fe0ddSCristian Dumitrescu 			   const char *selector_name,
1441598fe0ddSCristian Dumitrescu 			   FILE *file,
1442598fe0ddSCristian Dumitrescu 			   uint32_t *file_line_number)
1443598fe0ddSCristian Dumitrescu {
1444598fe0ddSCristian Dumitrescu 	char *line = NULL;
1445598fe0ddSCristian Dumitrescu 	uint32_t line_id = 0;
1446598fe0ddSCristian Dumitrescu 	int status = 0;
1447598fe0ddSCristian Dumitrescu 
1448598fe0ddSCristian Dumitrescu 	/* Buffer allocation. */
1449598fe0ddSCristian Dumitrescu 	line = malloc(MAX_LINE_SIZE);
1450598fe0ddSCristian Dumitrescu 	if (!line)
1451598fe0ddSCristian Dumitrescu 		return -ENOMEM;
1452598fe0ddSCristian Dumitrescu 
1453598fe0ddSCristian Dumitrescu 	/* File read. */
1454598fe0ddSCristian Dumitrescu 	for (line_id = 1; ; line_id++) {
1455598fe0ddSCristian Dumitrescu 		uint32_t group_id, member_id, weight;
1456598fe0ddSCristian Dumitrescu 		int is_blank_or_comment;
1457598fe0ddSCristian Dumitrescu 
1458598fe0ddSCristian Dumitrescu 		if (fgets(line, MAX_LINE_SIZE, file) == NULL)
1459598fe0ddSCristian Dumitrescu 			break;
1460598fe0ddSCristian Dumitrescu 
1461598fe0ddSCristian Dumitrescu 		status = pipeline_selector_group_member_read(line,
1462598fe0ddSCristian Dumitrescu 							      &group_id,
1463598fe0ddSCristian Dumitrescu 							      &member_id,
1464598fe0ddSCristian Dumitrescu 							      &weight,
1465598fe0ddSCristian Dumitrescu 							      &is_blank_or_comment);
1466598fe0ddSCristian Dumitrescu 		if (status) {
1467598fe0ddSCristian Dumitrescu 			if (is_blank_or_comment)
1468598fe0ddSCristian Dumitrescu 				continue;
1469598fe0ddSCristian Dumitrescu 
1470598fe0ddSCristian Dumitrescu 			goto error;
1471598fe0ddSCristian Dumitrescu 		}
1472598fe0ddSCristian Dumitrescu 
1473598fe0ddSCristian Dumitrescu 		status = rte_swx_ctl_pipeline_selector_group_member_delete(p,
1474598fe0ddSCristian Dumitrescu 			selector_name,
1475598fe0ddSCristian Dumitrescu 			group_id,
1476598fe0ddSCristian Dumitrescu 			member_id);
1477598fe0ddSCristian Dumitrescu 		if (status)
1478598fe0ddSCristian Dumitrescu 			goto error;
1479598fe0ddSCristian Dumitrescu 	}
1480598fe0ddSCristian Dumitrescu 
1481598fe0ddSCristian Dumitrescu error:
1482598fe0ddSCristian Dumitrescu 	free(line);
1483598fe0ddSCristian Dumitrescu 	*file_line_number = line_id;
1484598fe0ddSCristian Dumitrescu 	return status;
1485598fe0ddSCristian Dumitrescu }
1486598fe0ddSCristian Dumitrescu 
1487598fe0ddSCristian Dumitrescu static const char cmd_pipeline_selector_group_member_delete_help[] =
1488598fe0ddSCristian Dumitrescu "pipeline <pipeline_name> selector <selector_name> group member delete <file_name>";
1489598fe0ddSCristian Dumitrescu 
1490598fe0ddSCristian Dumitrescu static void
1491598fe0ddSCristian Dumitrescu cmd_pipeline_selector_group_member_delete(char **tokens,
1492598fe0ddSCristian Dumitrescu 	uint32_t n_tokens,
1493598fe0ddSCristian Dumitrescu 	char *out,
1494598fe0ddSCristian Dumitrescu 	size_t out_size,
1495b9559f94SCristian Dumitrescu 	void *obj __rte_unused)
1496598fe0ddSCristian Dumitrescu {
1497b9559f94SCristian Dumitrescu 	struct rte_swx_ctl_pipeline *ctl;
1498598fe0ddSCristian Dumitrescu 	char *pipeline_name, *selector_name, *file_name;
1499598fe0ddSCristian Dumitrescu 	FILE *file = NULL;
1500598fe0ddSCristian Dumitrescu 	uint32_t file_line_number = 0;
1501598fe0ddSCristian Dumitrescu 	int status;
1502598fe0ddSCristian Dumitrescu 
1503598fe0ddSCristian Dumitrescu 	if (n_tokens != 8) {
1504598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1505598fe0ddSCristian Dumitrescu 		return;
1506598fe0ddSCristian Dumitrescu 	}
1507598fe0ddSCristian Dumitrescu 
1508598fe0ddSCristian Dumitrescu 	pipeline_name = tokens[1];
1509b9559f94SCristian Dumitrescu 	ctl = rte_swx_ctl_pipeline_find(pipeline_name);
1510b9559f94SCristian Dumitrescu 	if (!ctl) {
1511598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
1512598fe0ddSCristian Dumitrescu 		return;
1513598fe0ddSCristian Dumitrescu 	}
1514598fe0ddSCristian Dumitrescu 
1515598fe0ddSCristian Dumitrescu 	if (strcmp(tokens[2], "selector") != 0) {
1516598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "selector");
1517598fe0ddSCristian Dumitrescu 		return;
1518598fe0ddSCristian Dumitrescu 	}
1519598fe0ddSCristian Dumitrescu 
1520598fe0ddSCristian Dumitrescu 	selector_name = tokens[3];
1521598fe0ddSCristian Dumitrescu 
1522598fe0ddSCristian Dumitrescu 	if (strcmp(tokens[4], "group") ||
1523598fe0ddSCristian Dumitrescu 		strcmp(tokens[5], "member") ||
1524598fe0ddSCristian Dumitrescu 		strcmp(tokens[6], "delete")) {
1525598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "group member delete");
1526598fe0ddSCristian Dumitrescu 		return;
1527598fe0ddSCristian Dumitrescu 	}
1528598fe0ddSCristian Dumitrescu 
1529598fe0ddSCristian Dumitrescu 	file_name = tokens[7];
1530598fe0ddSCristian Dumitrescu 	file = fopen(file_name, "r");
1531598fe0ddSCristian Dumitrescu 	if (!file) {
1532598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, "Cannot open file %s.\n", file_name);
1533598fe0ddSCristian Dumitrescu 		return;
1534598fe0ddSCristian Dumitrescu 	}
1535598fe0ddSCristian Dumitrescu 
1536b9559f94SCristian Dumitrescu 	status = pipeline_selector_group_members_delete(ctl,
1537598fe0ddSCristian Dumitrescu 					    selector_name,
1538598fe0ddSCristian Dumitrescu 					    file,
1539598fe0ddSCristian Dumitrescu 					    &file_line_number);
1540598fe0ddSCristian Dumitrescu 	if (status)
1541598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, "Invalid entry in file %s at line %u\n",
1542598fe0ddSCristian Dumitrescu 			 file_name,
1543598fe0ddSCristian Dumitrescu 			 file_line_number);
1544598fe0ddSCristian Dumitrescu 
1545598fe0ddSCristian Dumitrescu 	fclose(file);
1546598fe0ddSCristian Dumitrescu }
1547598fe0ddSCristian Dumitrescu 
1548598fe0ddSCristian Dumitrescu static const char cmd_pipeline_selector_show_help[] =
1549a4c1146cSCristian Dumitrescu "pipeline <pipeline_name> selector <selector_name> show [filename]\n";
1550598fe0ddSCristian Dumitrescu 
1551598fe0ddSCristian Dumitrescu static void
1552598fe0ddSCristian Dumitrescu cmd_pipeline_selector_show(char **tokens,
1553598fe0ddSCristian Dumitrescu 	uint32_t n_tokens,
1554598fe0ddSCristian Dumitrescu 	char *out,
1555598fe0ddSCristian Dumitrescu 	size_t out_size,
1556b9559f94SCristian Dumitrescu 	void *obj __rte_unused)
1557598fe0ddSCristian Dumitrescu {
1558b9559f94SCristian Dumitrescu 	struct rte_swx_ctl_pipeline *ctl;
1559598fe0ddSCristian Dumitrescu 	char *pipeline_name, *selector_name;
1560a4c1146cSCristian Dumitrescu 	FILE *file = NULL;
1561598fe0ddSCristian Dumitrescu 	int status;
1562598fe0ddSCristian Dumitrescu 
1563a4c1146cSCristian Dumitrescu 	if (n_tokens != 5 && n_tokens != 6) {
1564598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1565598fe0ddSCristian Dumitrescu 		return;
1566598fe0ddSCristian Dumitrescu 	}
1567598fe0ddSCristian Dumitrescu 
1568598fe0ddSCristian Dumitrescu 	pipeline_name = tokens[1];
1569b9559f94SCristian Dumitrescu 	ctl = rte_swx_ctl_pipeline_find(pipeline_name);
1570b9559f94SCristian Dumitrescu 	if (!ctl) {
1571598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
1572598fe0ddSCristian Dumitrescu 		return;
1573598fe0ddSCristian Dumitrescu 	}
1574598fe0ddSCristian Dumitrescu 
1575598fe0ddSCristian Dumitrescu 	selector_name = tokens[3];
1576a4c1146cSCristian Dumitrescu 
1577a4c1146cSCristian Dumitrescu 	file = (n_tokens == 6) ? fopen(tokens[5], "w") : stdout;
1578a4c1146cSCristian Dumitrescu 	if (!file) {
1579a4c1146cSCristian Dumitrescu 		snprintf(out, out_size, "Cannot open file %s.\n", tokens[5]);
1580a4c1146cSCristian Dumitrescu 		return;
1581a4c1146cSCristian Dumitrescu 	}
1582a4c1146cSCristian Dumitrescu 
1583b9559f94SCristian Dumitrescu 	status = rte_swx_ctl_pipeline_selector_fprintf(file, ctl, selector_name);
1584598fe0ddSCristian Dumitrescu 	if (status)
1585598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "selector_name");
1586a4c1146cSCristian Dumitrescu 
1587a4c1146cSCristian Dumitrescu 	if (file)
1588a4c1146cSCristian Dumitrescu 		fclose(file);
1589598fe0ddSCristian Dumitrescu }
1590598fe0ddSCristian Dumitrescu 
15918bd4862fSCristian Dumitrescu static int
15928bd4862fSCristian Dumitrescu pipeline_learner_default_entry_add(struct rte_swx_ctl_pipeline *p,
15938bd4862fSCristian Dumitrescu 				   const char *learner_name,
15948bd4862fSCristian Dumitrescu 				   FILE *file,
15958bd4862fSCristian Dumitrescu 				   uint32_t *file_line_number)
15968bd4862fSCristian Dumitrescu {
15978bd4862fSCristian Dumitrescu 	char *line = NULL;
15988bd4862fSCristian Dumitrescu 	uint32_t line_id = 0;
15998bd4862fSCristian Dumitrescu 	int status = 0;
16008bd4862fSCristian Dumitrescu 
16018bd4862fSCristian Dumitrescu 	/* Buffer allocation. */
16028bd4862fSCristian Dumitrescu 	line = malloc(MAX_LINE_SIZE);
16038bd4862fSCristian Dumitrescu 	if (!line)
16048bd4862fSCristian Dumitrescu 		return -ENOMEM;
16058bd4862fSCristian Dumitrescu 
16068bd4862fSCristian Dumitrescu 	/* File read. */
16078bd4862fSCristian Dumitrescu 	for (line_id = 1; ; line_id++) {
16088bd4862fSCristian Dumitrescu 		struct rte_swx_table_entry *entry;
16098bd4862fSCristian Dumitrescu 		int is_blank_or_comment;
16108bd4862fSCristian Dumitrescu 
16118bd4862fSCristian Dumitrescu 		if (fgets(line, MAX_LINE_SIZE, file) == NULL)
16128bd4862fSCristian Dumitrescu 			break;
16138bd4862fSCristian Dumitrescu 
16148bd4862fSCristian Dumitrescu 		entry = rte_swx_ctl_pipeline_learner_default_entry_read(p,
16158bd4862fSCristian Dumitrescu 									learner_name,
16168bd4862fSCristian Dumitrescu 									line,
16178bd4862fSCristian Dumitrescu 									&is_blank_or_comment);
16188bd4862fSCristian Dumitrescu 		if (!entry) {
16198bd4862fSCristian Dumitrescu 			if (is_blank_or_comment)
16208bd4862fSCristian Dumitrescu 				continue;
16218bd4862fSCristian Dumitrescu 
16228bd4862fSCristian Dumitrescu 			status = -EINVAL;
16238bd4862fSCristian Dumitrescu 			goto error;
16248bd4862fSCristian Dumitrescu 		}
16258bd4862fSCristian Dumitrescu 
16268bd4862fSCristian Dumitrescu 		status = rte_swx_ctl_pipeline_learner_default_entry_add(p,
16278bd4862fSCristian Dumitrescu 									learner_name,
16288bd4862fSCristian Dumitrescu 									entry);
16298bd4862fSCristian Dumitrescu 		table_entry_free(entry);
16308bd4862fSCristian Dumitrescu 		if (status)
16318bd4862fSCristian Dumitrescu 			goto error;
16328bd4862fSCristian Dumitrescu 	}
16338bd4862fSCristian Dumitrescu 
16348bd4862fSCristian Dumitrescu error:
16358bd4862fSCristian Dumitrescu 	*file_line_number = line_id;
16368bd4862fSCristian Dumitrescu 	free(line);
16378bd4862fSCristian Dumitrescu 	return status;
16388bd4862fSCristian Dumitrescu }
16398bd4862fSCristian Dumitrescu 
16408bd4862fSCristian Dumitrescu static const char cmd_pipeline_learner_default_help[] =
16418bd4862fSCristian Dumitrescu "pipeline <pipeline_name> learner <learner_name> default <file_name>\n";
16428bd4862fSCristian Dumitrescu 
16438bd4862fSCristian Dumitrescu static void
16448bd4862fSCristian Dumitrescu cmd_pipeline_learner_default(char **tokens,
16458bd4862fSCristian Dumitrescu 			     uint32_t n_tokens,
16468bd4862fSCristian Dumitrescu 			     char *out,
16478bd4862fSCristian Dumitrescu 			     size_t out_size,
1648b9559f94SCristian Dumitrescu 			     void *obj __rte_unused)
16498bd4862fSCristian Dumitrescu {
1650b9559f94SCristian Dumitrescu 	struct rte_swx_ctl_pipeline *ctl;
16518bd4862fSCristian Dumitrescu 	char *pipeline_name, *learner_name, *file_name;
16528bd4862fSCristian Dumitrescu 	FILE *file = NULL;
16538bd4862fSCristian Dumitrescu 	uint32_t file_line_number = 0;
16548bd4862fSCristian Dumitrescu 	int status;
16558bd4862fSCristian Dumitrescu 
16568bd4862fSCristian Dumitrescu 	if (n_tokens != 6) {
16578bd4862fSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
16588bd4862fSCristian Dumitrescu 		return;
16598bd4862fSCristian Dumitrescu 	}
16608bd4862fSCristian Dumitrescu 
16618bd4862fSCristian Dumitrescu 	pipeline_name = tokens[1];
1662b9559f94SCristian Dumitrescu 	ctl = rte_swx_ctl_pipeline_find(pipeline_name);
1663b9559f94SCristian Dumitrescu 	if (!ctl) {
16648bd4862fSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
16658bd4862fSCristian Dumitrescu 		return;
16668bd4862fSCristian Dumitrescu 	}
16678bd4862fSCristian Dumitrescu 
16688bd4862fSCristian Dumitrescu 	learner_name = tokens[3];
16698bd4862fSCristian Dumitrescu 
16708bd4862fSCristian Dumitrescu 	file_name = tokens[5];
16718bd4862fSCristian Dumitrescu 	file = fopen(file_name, "r");
16728bd4862fSCristian Dumitrescu 	if (!file) {
16738bd4862fSCristian Dumitrescu 		snprintf(out, out_size, "Cannot open file %s.\n", file_name);
16748bd4862fSCristian Dumitrescu 		return;
16758bd4862fSCristian Dumitrescu 	}
16768bd4862fSCristian Dumitrescu 
1677b9559f94SCristian Dumitrescu 	status = pipeline_learner_default_entry_add(ctl,
16788bd4862fSCristian Dumitrescu 						    learner_name,
16798bd4862fSCristian Dumitrescu 						    file,
16808bd4862fSCristian Dumitrescu 						    &file_line_number);
16818bd4862fSCristian Dumitrescu 	if (status)
16828bd4862fSCristian Dumitrescu 		snprintf(out, out_size, "Invalid entry in file %s at line %u\n",
16838bd4862fSCristian Dumitrescu 			 file_name,
16848bd4862fSCristian Dumitrescu 			 file_line_number);
16858bd4862fSCristian Dumitrescu 
16868bd4862fSCristian Dumitrescu 	fclose(file);
16878bd4862fSCristian Dumitrescu }
16888bd4862fSCristian Dumitrescu 
168975129cebSChurchill Khangar static const char cmd_pipeline_commit_help[] =
169075129cebSChurchill Khangar "pipeline <pipeline_name> commit\n";
169175129cebSChurchill Khangar 
169275129cebSChurchill Khangar static void
169375129cebSChurchill Khangar cmd_pipeline_commit(char **tokens,
169475129cebSChurchill Khangar 	uint32_t n_tokens,
169575129cebSChurchill Khangar 	char *out,
169675129cebSChurchill Khangar 	size_t out_size,
1697b9559f94SCristian Dumitrescu 	void *obj __rte_unused)
169875129cebSChurchill Khangar {
1699b9559f94SCristian Dumitrescu 	struct rte_swx_ctl_pipeline *ctl;
170075129cebSChurchill Khangar 	char *pipeline_name;
170175129cebSChurchill Khangar 	int status;
170275129cebSChurchill Khangar 
170375129cebSChurchill Khangar 	if (n_tokens != 3) {
170475129cebSChurchill Khangar 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
170575129cebSChurchill Khangar 		return;
170675129cebSChurchill Khangar 	}
170775129cebSChurchill Khangar 
170875129cebSChurchill Khangar 	pipeline_name = tokens[1];
1709b9559f94SCristian Dumitrescu 	ctl = rte_swx_ctl_pipeline_find(pipeline_name);
1710b9559f94SCristian Dumitrescu 	if (!ctl) {
171175129cebSChurchill Khangar 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
171275129cebSChurchill Khangar 		return;
17135074e1d5SCristian Dumitrescu 	}
17145074e1d5SCristian Dumitrescu 
1715b9559f94SCristian Dumitrescu 	status = rte_swx_ctl_pipeline_commit(ctl, 1);
171675129cebSChurchill Khangar 	if (status)
171775129cebSChurchill Khangar 		snprintf(out, out_size, "Commit failed. "
171875129cebSChurchill Khangar 			"Use \"commit\" to retry or \"abort\" to discard the pending work.\n");
17195074e1d5SCristian Dumitrescu }
17205074e1d5SCristian Dumitrescu 
172175129cebSChurchill Khangar static const char cmd_pipeline_abort_help[] =
172275129cebSChurchill Khangar "pipeline <pipeline_name> abort\n";
17235074e1d5SCristian Dumitrescu 
172475129cebSChurchill Khangar static void
172575129cebSChurchill Khangar cmd_pipeline_abort(char **tokens,
172675129cebSChurchill Khangar 	uint32_t n_tokens,
172775129cebSChurchill Khangar 	char *out,
172875129cebSChurchill Khangar 	size_t out_size,
1729b9559f94SCristian Dumitrescu 	void *obj __rte_unused)
173075129cebSChurchill Khangar {
1731b9559f94SCristian Dumitrescu 	struct rte_swx_ctl_pipeline *ctl;
173275129cebSChurchill Khangar 	char *pipeline_name;
17335074e1d5SCristian Dumitrescu 
173475129cebSChurchill Khangar 	if (n_tokens != 3) {
173575129cebSChurchill Khangar 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
17365074e1d5SCristian Dumitrescu 		return;
173775129cebSChurchill Khangar 	}
17385074e1d5SCristian Dumitrescu 
173975129cebSChurchill Khangar 	pipeline_name = tokens[1];
1740b9559f94SCristian Dumitrescu 	ctl = rte_swx_ctl_pipeline_find(pipeline_name);
1741b9559f94SCristian Dumitrescu 	if (!ctl) {
174275129cebSChurchill Khangar 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
174375129cebSChurchill Khangar 		return;
174475129cebSChurchill Khangar 	}
174575129cebSChurchill Khangar 
1746b9559f94SCristian Dumitrescu 	rte_swx_ctl_pipeline_abort(ctl);
17475074e1d5SCristian Dumitrescu }
17485074e1d5SCristian Dumitrescu 
174964cfcebdSCristian Dumitrescu static const char cmd_pipeline_regrd_help[] =
1750*83f58a7bSCristian Dumitrescu "pipeline <pipeline_name> regrd <register_array_name>\n"
1751*83f58a7bSCristian Dumitrescu 	"index <index>\n"
1752*83f58a7bSCristian Dumitrescu 	" | table <table_name> match <field0> ...\n";
175364cfcebdSCristian Dumitrescu 
175464cfcebdSCristian Dumitrescu static void
175564cfcebdSCristian Dumitrescu cmd_pipeline_regrd(char **tokens,
175664cfcebdSCristian Dumitrescu 	uint32_t n_tokens,
175764cfcebdSCristian Dumitrescu 	char *out,
175864cfcebdSCristian Dumitrescu 	size_t out_size,
1759b9559f94SCristian Dumitrescu 	void *obj __rte_unused)
176064cfcebdSCristian Dumitrescu {
1761b9559f94SCristian Dumitrescu 	struct rte_swx_pipeline *p;
1762*83f58a7bSCristian Dumitrescu 	struct rte_swx_ctl_pipeline *ctl;
1763*83f58a7bSCristian Dumitrescu 	const char *pipeline_name, *name;
176464cfcebdSCristian Dumitrescu 	uint64_t value;
176564cfcebdSCristian Dumitrescu 	int status;
176664cfcebdSCristian Dumitrescu 
1767*83f58a7bSCristian Dumitrescu 	if (n_tokens < 5) {
176864cfcebdSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
176964cfcebdSCristian Dumitrescu 		return;
177064cfcebdSCristian Dumitrescu 	}
177164cfcebdSCristian Dumitrescu 
1772*83f58a7bSCristian Dumitrescu 	pipeline_name = tokens[1];
1773*83f58a7bSCristian Dumitrescu 	p = rte_swx_pipeline_find(pipeline_name);
1774*83f58a7bSCristian Dumitrescu 	ctl = rte_swx_ctl_pipeline_find(pipeline_name);
1775*83f58a7bSCristian Dumitrescu 	if (!p || !ctl) {
177664cfcebdSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
177764cfcebdSCristian Dumitrescu 		return;
177864cfcebdSCristian Dumitrescu 	}
177964cfcebdSCristian Dumitrescu 
178064cfcebdSCristian Dumitrescu 	if (strcmp(tokens[2], "regrd")) {
178164cfcebdSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "regrd");
178264cfcebdSCristian Dumitrescu 		return;
178364cfcebdSCristian Dumitrescu 	}
178464cfcebdSCristian Dumitrescu 
178564cfcebdSCristian Dumitrescu 	name = tokens[3];
178664cfcebdSCristian Dumitrescu 
1787*83f58a7bSCristian Dumitrescu 	/* index. */
1788*83f58a7bSCristian Dumitrescu 	if (!strcmp(tokens[4], "index")) {
1789*83f58a7bSCristian Dumitrescu 		uint32_t idx;
1790*83f58a7bSCristian Dumitrescu 
1791*83f58a7bSCristian Dumitrescu 		if (n_tokens != 6) {
1792*83f58a7bSCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1793*83f58a7bSCristian Dumitrescu 			return;
1794*83f58a7bSCristian Dumitrescu 		}
1795*83f58a7bSCristian Dumitrescu 
1796*83f58a7bSCristian Dumitrescu 		if (parser_read_uint32(&idx, tokens[5])) {
179764cfcebdSCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_INVALID, "index");
179864cfcebdSCristian Dumitrescu 			return;
179964cfcebdSCristian Dumitrescu 		}
180064cfcebdSCristian Dumitrescu 
1801b9559f94SCristian Dumitrescu 		status = rte_swx_ctl_pipeline_regarray_read(p, name, idx, &value);
180264cfcebdSCristian Dumitrescu 		if (status) {
180364cfcebdSCristian Dumitrescu 			snprintf(out, out_size, "Command failed.\n");
180464cfcebdSCristian Dumitrescu 			return;
180564cfcebdSCristian Dumitrescu 		}
180664cfcebdSCristian Dumitrescu 
180764cfcebdSCristian Dumitrescu 		snprintf(out, out_size, "0x%" PRIx64 "\n", value);
1808*83f58a7bSCristian Dumitrescu 		return;
1809*83f58a7bSCristian Dumitrescu 	}
1810*83f58a7bSCristian Dumitrescu 
1811*83f58a7bSCristian Dumitrescu 	/* table. */
1812*83f58a7bSCristian Dumitrescu 	if (!strcmp(tokens[4], "table")) {
1813*83f58a7bSCristian Dumitrescu 		struct rte_swx_table_entry *entry;
1814*83f58a7bSCristian Dumitrescu 		char *table_name;
1815*83f58a7bSCristian Dumitrescu 
1816*83f58a7bSCristian Dumitrescu 		if (n_tokens < 8) {
1817*83f58a7bSCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1818*83f58a7bSCristian Dumitrescu 			return;
1819*83f58a7bSCristian Dumitrescu 		}
1820*83f58a7bSCristian Dumitrescu 
1821*83f58a7bSCristian Dumitrescu 		table_name = tokens[5];
1822*83f58a7bSCristian Dumitrescu 
1823*83f58a7bSCristian Dumitrescu 		if (strcmp(tokens[6], "match")) {
1824*83f58a7bSCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_NOT_FOUND, "match");
1825*83f58a7bSCristian Dumitrescu 			return;
1826*83f58a7bSCristian Dumitrescu 		}
1827*83f58a7bSCristian Dumitrescu 
1828*83f58a7bSCristian Dumitrescu 		entry = parse_table_entry(ctl, table_name, &tokens[6], n_tokens - 6);
1829*83f58a7bSCristian Dumitrescu 		if (!entry) {
1830*83f58a7bSCristian Dumitrescu 			snprintf(out, out_size, "Invalid match tokens.\n");
1831*83f58a7bSCristian Dumitrescu 			return;
1832*83f58a7bSCristian Dumitrescu 		}
1833*83f58a7bSCristian Dumitrescu 
1834*83f58a7bSCristian Dumitrescu 		status = rte_swx_ctl_pipeline_regarray_read_with_key(p,
1835*83f58a7bSCristian Dumitrescu 								     name,
1836*83f58a7bSCristian Dumitrescu 								     table_name,
1837*83f58a7bSCristian Dumitrescu 								     entry->key,
1838*83f58a7bSCristian Dumitrescu 								     &value);
1839*83f58a7bSCristian Dumitrescu 		table_entry_free(entry);
1840*83f58a7bSCristian Dumitrescu 		if (status) {
1841*83f58a7bSCristian Dumitrescu 			snprintf(out, out_size, "Command failed.\n");
1842*83f58a7bSCristian Dumitrescu 			return;
1843*83f58a7bSCristian Dumitrescu 		}
1844*83f58a7bSCristian Dumitrescu 
1845*83f58a7bSCristian Dumitrescu 		snprintf(out, out_size, "0x%" PRIx64 "\n", value);
1846*83f58a7bSCristian Dumitrescu 		return;
1847*83f58a7bSCristian Dumitrescu 	}
1848*83f58a7bSCristian Dumitrescu 
1849*83f58a7bSCristian Dumitrescu 	/* anything else. */
1850*83f58a7bSCristian Dumitrescu 	snprintf(out, out_size, "Invalid token %s\n.", tokens[4]);
1851*83f58a7bSCristian Dumitrescu 	return;
185264cfcebdSCristian Dumitrescu }
185364cfcebdSCristian Dumitrescu 
185464cfcebdSCristian Dumitrescu static const char cmd_pipeline_regwr_help[] =
1855*83f58a7bSCristian Dumitrescu "pipeline <pipeline_name> regwr <register_array_name> value <value>\n"
1856*83f58a7bSCristian Dumitrescu 	"index <index>\n"
1857*83f58a7bSCristian Dumitrescu 	" | table <table_name> match <field0> ...\n";
185864cfcebdSCristian Dumitrescu 
185964cfcebdSCristian Dumitrescu static void
186064cfcebdSCristian Dumitrescu cmd_pipeline_regwr(char **tokens,
186164cfcebdSCristian Dumitrescu 	uint32_t n_tokens,
186264cfcebdSCristian Dumitrescu 	char *out,
186364cfcebdSCristian Dumitrescu 	size_t out_size,
1864b9559f94SCristian Dumitrescu 	void *obj __rte_unused)
186564cfcebdSCristian Dumitrescu {
1866b9559f94SCristian Dumitrescu 	struct rte_swx_pipeline *p;
1867*83f58a7bSCristian Dumitrescu 	struct rte_swx_ctl_pipeline *ctl;
1868*83f58a7bSCristian Dumitrescu 	const char *pipeline_name, *name;
1869*83f58a7bSCristian Dumitrescu 	uint64_t value = 0;
187064cfcebdSCristian Dumitrescu 	int status;
187164cfcebdSCristian Dumitrescu 
1872*83f58a7bSCristian Dumitrescu 	if (n_tokens < 7) {
187364cfcebdSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
187464cfcebdSCristian Dumitrescu 		return;
187564cfcebdSCristian Dumitrescu 	}
187664cfcebdSCristian Dumitrescu 
1877*83f58a7bSCristian Dumitrescu 	pipeline_name = tokens[1];
1878*83f58a7bSCristian Dumitrescu 	p = rte_swx_pipeline_find(pipeline_name);
1879*83f58a7bSCristian Dumitrescu 	ctl = rte_swx_ctl_pipeline_find(pipeline_name);
1880*83f58a7bSCristian Dumitrescu 	if (!p || !ctl) {
188164cfcebdSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
188264cfcebdSCristian Dumitrescu 		return;
188364cfcebdSCristian Dumitrescu 	}
188464cfcebdSCristian Dumitrescu 
188564cfcebdSCristian Dumitrescu 	if (strcmp(tokens[2], "regwr")) {
188664cfcebdSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "regwr");
188764cfcebdSCristian Dumitrescu 		return;
188864cfcebdSCristian Dumitrescu 	}
188964cfcebdSCristian Dumitrescu 
189064cfcebdSCristian Dumitrescu 	name = tokens[3];
189164cfcebdSCristian Dumitrescu 
1892*83f58a7bSCristian Dumitrescu 	if (strcmp(tokens[4], "value")) {
1893*83f58a7bSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "value");
189464cfcebdSCristian Dumitrescu 		return;
189564cfcebdSCristian Dumitrescu 	}
189664cfcebdSCristian Dumitrescu 
189764cfcebdSCristian Dumitrescu 	if (parser_read_uint64(&value, tokens[5])) {
189864cfcebdSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "value");
189964cfcebdSCristian Dumitrescu 		return;
190064cfcebdSCristian Dumitrescu 	}
190164cfcebdSCristian Dumitrescu 
1902*83f58a7bSCristian Dumitrescu 	/* index. */
1903*83f58a7bSCristian Dumitrescu 	if (!strcmp(tokens[6], "index")) {
1904*83f58a7bSCristian Dumitrescu 		uint32_t idx;
1905*83f58a7bSCristian Dumitrescu 
1906*83f58a7bSCristian Dumitrescu 		if (n_tokens != 8) {
1907*83f58a7bSCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1908*83f58a7bSCristian Dumitrescu 			return;
1909*83f58a7bSCristian Dumitrescu 		}
1910*83f58a7bSCristian Dumitrescu 
1911*83f58a7bSCristian Dumitrescu 		if (parser_read_uint32(&idx, tokens[7])) {
1912*83f58a7bSCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_INVALID, "index");
1913*83f58a7bSCristian Dumitrescu 			return;
1914*83f58a7bSCristian Dumitrescu 		}
1915*83f58a7bSCristian Dumitrescu 
1916b9559f94SCristian Dumitrescu 		status = rte_swx_ctl_pipeline_regarray_write(p, name, idx, value);
191764cfcebdSCristian Dumitrescu 		if (status) {
191864cfcebdSCristian Dumitrescu 			snprintf(out, out_size, "Command failed.\n");
191964cfcebdSCristian Dumitrescu 			return;
192064cfcebdSCristian Dumitrescu 		}
1921*83f58a7bSCristian Dumitrescu 
1922*83f58a7bSCristian Dumitrescu 		snprintf(out, out_size, "0x%" PRIx64 "\n", value);
1923*83f58a7bSCristian Dumitrescu 		return;
1924*83f58a7bSCristian Dumitrescu 	}
1925*83f58a7bSCristian Dumitrescu 
1926*83f58a7bSCristian Dumitrescu 	/* table. */
1927*83f58a7bSCristian Dumitrescu 	if (!strcmp(tokens[6], "table")) {
1928*83f58a7bSCristian Dumitrescu 		struct rte_swx_table_entry *entry;
1929*83f58a7bSCristian Dumitrescu 		char *table_name;
1930*83f58a7bSCristian Dumitrescu 
1931*83f58a7bSCristian Dumitrescu 		if (n_tokens < 10) {
1932*83f58a7bSCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1933*83f58a7bSCristian Dumitrescu 			return;
1934*83f58a7bSCristian Dumitrescu 		}
1935*83f58a7bSCristian Dumitrescu 
1936*83f58a7bSCristian Dumitrescu 		table_name = tokens[7];
1937*83f58a7bSCristian Dumitrescu 
1938*83f58a7bSCristian Dumitrescu 		if (strcmp(tokens[8], "match")) {
1939*83f58a7bSCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_NOT_FOUND, "match");
1940*83f58a7bSCristian Dumitrescu 			return;
1941*83f58a7bSCristian Dumitrescu 		}
1942*83f58a7bSCristian Dumitrescu 
1943*83f58a7bSCristian Dumitrescu 		entry = parse_table_entry(ctl, table_name, &tokens[8], n_tokens - 8);
1944*83f58a7bSCristian Dumitrescu 		if (!entry) {
1945*83f58a7bSCristian Dumitrescu 			snprintf(out, out_size, "Invalid match tokens.\n");
1946*83f58a7bSCristian Dumitrescu 			return;
1947*83f58a7bSCristian Dumitrescu 		}
1948*83f58a7bSCristian Dumitrescu 
1949*83f58a7bSCristian Dumitrescu 		status = rte_swx_ctl_pipeline_regarray_write_with_key(p,
1950*83f58a7bSCristian Dumitrescu 								      name,
1951*83f58a7bSCristian Dumitrescu 								      table_name,
1952*83f58a7bSCristian Dumitrescu 								      entry->key,
1953*83f58a7bSCristian Dumitrescu 								      value);
1954*83f58a7bSCristian Dumitrescu 		table_entry_free(entry);
1955*83f58a7bSCristian Dumitrescu 		if (status) {
1956*83f58a7bSCristian Dumitrescu 			snprintf(out, out_size, "Command failed.\n");
1957*83f58a7bSCristian Dumitrescu 			return;
1958*83f58a7bSCristian Dumitrescu 		}
1959*83f58a7bSCristian Dumitrescu 
1960*83f58a7bSCristian Dumitrescu 		return;
1961*83f58a7bSCristian Dumitrescu 	}
1962*83f58a7bSCristian Dumitrescu 
1963*83f58a7bSCristian Dumitrescu 	/* anything else. */
1964*83f58a7bSCristian Dumitrescu 	snprintf(out, out_size, "Invalid token %s\n.", tokens[6]);
1965*83f58a7bSCristian Dumitrescu 	return;
196664cfcebdSCristian Dumitrescu }
196764cfcebdSCristian Dumitrescu 
1968f38913b7SCristian Dumitrescu static const char cmd_pipeline_meter_profile_add_help[] =
1969f38913b7SCristian Dumitrescu "pipeline <pipeline_name> meter profile <profile_name> add "
1970f38913b7SCristian Dumitrescu 	"cir <cir> pir <pir> cbs <cbs> pbs <pbs>\n";
1971f38913b7SCristian Dumitrescu 
1972f38913b7SCristian Dumitrescu static void
1973f38913b7SCristian Dumitrescu cmd_pipeline_meter_profile_add(char **tokens,
1974f38913b7SCristian Dumitrescu 	uint32_t n_tokens,
1975f38913b7SCristian Dumitrescu 	char *out,
1976f38913b7SCristian Dumitrescu 	size_t out_size,
1977b9559f94SCristian Dumitrescu 	void *obj __rte_unused)
1978f38913b7SCristian Dumitrescu {
1979f38913b7SCristian Dumitrescu 	struct rte_meter_trtcm_params params;
1980b9559f94SCristian Dumitrescu 	struct rte_swx_pipeline *p;
1981f38913b7SCristian Dumitrescu 	const char *profile_name;
1982f38913b7SCristian Dumitrescu 	int status;
1983f38913b7SCristian Dumitrescu 
1984f38913b7SCristian Dumitrescu 	if (n_tokens != 14) {
1985f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1986f38913b7SCristian Dumitrescu 		return;
1987f38913b7SCristian Dumitrescu 	}
1988f38913b7SCristian Dumitrescu 
1989b9559f94SCristian Dumitrescu 	p = rte_swx_pipeline_find(tokens[1]);
1990b9559f94SCristian Dumitrescu 	if (!p) {
1991f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
1992f38913b7SCristian Dumitrescu 		return;
1993f38913b7SCristian Dumitrescu 	}
1994f38913b7SCristian Dumitrescu 
1995f38913b7SCristian Dumitrescu 	if (strcmp(tokens[2], "meter")) {
1996f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "meter");
1997f38913b7SCristian Dumitrescu 		return;
1998f38913b7SCristian Dumitrescu 	}
1999f38913b7SCristian Dumitrescu 
2000f38913b7SCristian Dumitrescu 	if (strcmp(tokens[3], "profile")) {
2001f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "profile");
2002f38913b7SCristian Dumitrescu 		return;
2003f38913b7SCristian Dumitrescu 	}
2004f38913b7SCristian Dumitrescu 
2005f38913b7SCristian Dumitrescu 	profile_name = tokens[4];
2006f38913b7SCristian Dumitrescu 
2007f38913b7SCristian Dumitrescu 	if (strcmp(tokens[5], "add")) {
2008f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "add");
2009f38913b7SCristian Dumitrescu 		return;
2010f38913b7SCristian Dumitrescu 	}
2011f38913b7SCristian Dumitrescu 
2012f38913b7SCristian Dumitrescu 	if (strcmp(tokens[6], "cir")) {
2013f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cir");
2014f38913b7SCristian Dumitrescu 		return;
2015f38913b7SCristian Dumitrescu 	}
2016f38913b7SCristian Dumitrescu 
2017f38913b7SCristian Dumitrescu 	if (parser_read_uint64(&params.cir, tokens[7])) {
2018f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "cir");
2019f38913b7SCristian Dumitrescu 		return;
2020f38913b7SCristian Dumitrescu 	}
2021f38913b7SCristian Dumitrescu 
2022f38913b7SCristian Dumitrescu 	if (strcmp(tokens[8], "pir")) {
2023f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pir");
2024f38913b7SCristian Dumitrescu 		return;
2025f38913b7SCristian Dumitrescu 	}
2026f38913b7SCristian Dumitrescu 
2027f38913b7SCristian Dumitrescu 	if (parser_read_uint64(&params.pir, tokens[9])) {
2028f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pir");
2029f38913b7SCristian Dumitrescu 		return;
2030f38913b7SCristian Dumitrescu 	}
2031f38913b7SCristian Dumitrescu 
2032f38913b7SCristian Dumitrescu 	if (strcmp(tokens[10], "cbs")) {
2033f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cbs");
2034f38913b7SCristian Dumitrescu 		return;
2035f38913b7SCristian Dumitrescu 	}
2036f38913b7SCristian Dumitrescu 
2037f38913b7SCristian Dumitrescu 	if (parser_read_uint64(&params.cbs, tokens[11])) {
2038f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "cbs");
2039f38913b7SCristian Dumitrescu 		return;
2040f38913b7SCristian Dumitrescu 	}
2041f38913b7SCristian Dumitrescu 
2042f38913b7SCristian Dumitrescu 	if (strcmp(tokens[12], "pbs")) {
2043f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pbs");
2044f38913b7SCristian Dumitrescu 		return;
2045f38913b7SCristian Dumitrescu 	}
2046f38913b7SCristian Dumitrescu 
2047f38913b7SCristian Dumitrescu 	if (parser_read_uint64(&params.pbs, tokens[13])) {
2048f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pbs");
2049f38913b7SCristian Dumitrescu 		return;
2050f38913b7SCristian Dumitrescu 	}
2051f38913b7SCristian Dumitrescu 
2052b9559f94SCristian Dumitrescu 	status = rte_swx_ctl_meter_profile_add(p, profile_name, &params);
2053f38913b7SCristian Dumitrescu 	if (status) {
2054f38913b7SCristian Dumitrescu 		snprintf(out, out_size, "Command failed.\n");
2055f38913b7SCristian Dumitrescu 		return;
2056f38913b7SCristian Dumitrescu 	}
2057f38913b7SCristian Dumitrescu }
2058f38913b7SCristian Dumitrescu 
2059f38913b7SCristian Dumitrescu static const char cmd_pipeline_meter_profile_delete_help[] =
2060f38913b7SCristian Dumitrescu "pipeline <pipeline_name> meter profile <profile_name> delete\n";
2061f38913b7SCristian Dumitrescu 
2062f38913b7SCristian Dumitrescu static void
2063f38913b7SCristian Dumitrescu cmd_pipeline_meter_profile_delete(char **tokens,
2064f38913b7SCristian Dumitrescu 	uint32_t n_tokens,
2065f38913b7SCristian Dumitrescu 	char *out,
2066f38913b7SCristian Dumitrescu 	size_t out_size,
2067b9559f94SCristian Dumitrescu 	void *obj __rte_unused)
2068f38913b7SCristian Dumitrescu {
2069b9559f94SCristian Dumitrescu 	struct rte_swx_pipeline *p;
2070f38913b7SCristian Dumitrescu 	const char *profile_name;
2071f38913b7SCristian Dumitrescu 	int status;
2072f38913b7SCristian Dumitrescu 
2073f38913b7SCristian Dumitrescu 	if (n_tokens != 6) {
2074f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2075f38913b7SCristian Dumitrescu 		return;
2076f38913b7SCristian Dumitrescu 	}
2077f38913b7SCristian Dumitrescu 
2078b9559f94SCristian Dumitrescu 	p = rte_swx_pipeline_find(tokens[1]);
2079b9559f94SCristian Dumitrescu 	if (!p) {
2080f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
2081f38913b7SCristian Dumitrescu 		return;
2082f38913b7SCristian Dumitrescu 	}
2083f38913b7SCristian Dumitrescu 
2084f38913b7SCristian Dumitrescu 	if (strcmp(tokens[2], "meter")) {
2085f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "meter");
2086f38913b7SCristian Dumitrescu 		return;
2087f38913b7SCristian Dumitrescu 	}
2088f38913b7SCristian Dumitrescu 
2089f38913b7SCristian Dumitrescu 	if (strcmp(tokens[3], "profile")) {
2090f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "profile");
2091f38913b7SCristian Dumitrescu 		return;
2092f38913b7SCristian Dumitrescu 	}
2093f38913b7SCristian Dumitrescu 
2094f38913b7SCristian Dumitrescu 	profile_name = tokens[4];
2095f38913b7SCristian Dumitrescu 
2096f38913b7SCristian Dumitrescu 	if (strcmp(tokens[5], "delete")) {
2097f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "delete");
2098f38913b7SCristian Dumitrescu 		return;
2099f38913b7SCristian Dumitrescu 	}
2100f38913b7SCristian Dumitrescu 
2101b9559f94SCristian Dumitrescu 	status = rte_swx_ctl_meter_profile_delete(p, profile_name);
2102f38913b7SCristian Dumitrescu 	if (status) {
2103f38913b7SCristian Dumitrescu 		snprintf(out, out_size, "Command failed.\n");
2104f38913b7SCristian Dumitrescu 		return;
2105f38913b7SCristian Dumitrescu 	}
2106f38913b7SCristian Dumitrescu }
2107f38913b7SCristian Dumitrescu 
2108f38913b7SCristian Dumitrescu static const char cmd_pipeline_meter_reset_help[] =
2109f38913b7SCristian Dumitrescu "pipeline <pipeline_name> meter <meter_array_name> from <index0> to <index1> "
2110f38913b7SCristian Dumitrescu 	"reset\n";
2111f38913b7SCristian Dumitrescu 
2112f38913b7SCristian Dumitrescu static void
2113f38913b7SCristian Dumitrescu cmd_pipeline_meter_reset(char **tokens,
2114f38913b7SCristian Dumitrescu 	uint32_t n_tokens,
2115f38913b7SCristian Dumitrescu 	char *out,
2116f38913b7SCristian Dumitrescu 	size_t out_size,
2117b9559f94SCristian Dumitrescu 	void *obj __rte_unused)
2118f38913b7SCristian Dumitrescu {
2119b9559f94SCristian Dumitrescu 	struct rte_swx_pipeline *p;
2120f38913b7SCristian Dumitrescu 	const char *name;
212100b67591SAli Alnubani 	uint32_t idx0 = 0, idx1 = 0;
2122f38913b7SCristian Dumitrescu 
2123f38913b7SCristian Dumitrescu 	if (n_tokens != 9) {
2124f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2125f38913b7SCristian Dumitrescu 		return;
2126f38913b7SCristian Dumitrescu 	}
2127f38913b7SCristian Dumitrescu 
2128b9559f94SCristian Dumitrescu 	p = rte_swx_pipeline_find(tokens[1]);
2129b9559f94SCristian Dumitrescu 	if (!p) {
2130f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
2131f38913b7SCristian Dumitrescu 		return;
2132f38913b7SCristian Dumitrescu 	}
2133f38913b7SCristian Dumitrescu 
2134f38913b7SCristian Dumitrescu 	if (strcmp(tokens[2], "meter")) {
2135f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "meter");
2136f38913b7SCristian Dumitrescu 		return;
2137f38913b7SCristian Dumitrescu 	}
2138f38913b7SCristian Dumitrescu 
2139f38913b7SCristian Dumitrescu 	name = tokens[3];
2140f38913b7SCristian Dumitrescu 
2141f38913b7SCristian Dumitrescu 	if (strcmp(tokens[4], "from")) {
2142f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "from");
2143f38913b7SCristian Dumitrescu 		return;
2144f38913b7SCristian Dumitrescu 	}
2145f38913b7SCristian Dumitrescu 
2146f38913b7SCristian Dumitrescu 	if (parser_read_uint32(&idx0, tokens[5])) {
2147f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "index0");
2148f38913b7SCristian Dumitrescu 		return;
2149f38913b7SCristian Dumitrescu 	}
2150f38913b7SCristian Dumitrescu 
2151f38913b7SCristian Dumitrescu 	if (strcmp(tokens[6], "to")) {
2152f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "to");
2153f38913b7SCristian Dumitrescu 		return;
2154f38913b7SCristian Dumitrescu 	}
2155f38913b7SCristian Dumitrescu 
2156f38913b7SCristian Dumitrescu 	if (parser_read_uint32(&idx1, tokens[7]) || (idx1 < idx0)) {
2157f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "index1");
2158f38913b7SCristian Dumitrescu 		return;
2159f38913b7SCristian Dumitrescu 	}
2160f38913b7SCristian Dumitrescu 
2161f38913b7SCristian Dumitrescu 	if (strcmp(tokens[8], "reset")) {
2162f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "reset");
2163f38913b7SCristian Dumitrescu 		return;
2164f38913b7SCristian Dumitrescu 	}
2165f38913b7SCristian Dumitrescu 
2166f38913b7SCristian Dumitrescu 	for ( ; idx0 <= idx1; idx0++) {
2167f38913b7SCristian Dumitrescu 		int status;
2168f38913b7SCristian Dumitrescu 
2169b9559f94SCristian Dumitrescu 		status = rte_swx_ctl_meter_reset(p, name, idx0);
2170f38913b7SCristian Dumitrescu 		if (status) {
2171f38913b7SCristian Dumitrescu 			snprintf(out, out_size, "Command failed for index %u.\n", idx0);
2172f38913b7SCristian Dumitrescu 			return;
2173f38913b7SCristian Dumitrescu 		}
2174f38913b7SCristian Dumitrescu 	}
2175f38913b7SCristian Dumitrescu }
2176f38913b7SCristian Dumitrescu 
2177f38913b7SCristian Dumitrescu static const char cmd_pipeline_meter_set_help[] =
2178f38913b7SCristian Dumitrescu "pipeline <pipeline_name> meter <meter_array_name> from <index0> to <index1> "
2179f38913b7SCristian Dumitrescu 	"set profile <profile_name>\n";
2180f38913b7SCristian Dumitrescu 
2181f38913b7SCristian Dumitrescu static void
2182f38913b7SCristian Dumitrescu cmd_pipeline_meter_set(char **tokens,
2183f38913b7SCristian Dumitrescu 	uint32_t n_tokens,
2184f38913b7SCristian Dumitrescu 	char *out,
2185f38913b7SCristian Dumitrescu 	size_t out_size,
2186b9559f94SCristian Dumitrescu 	void *obj __rte_unused)
2187f38913b7SCristian Dumitrescu {
2188b9559f94SCristian Dumitrescu 	struct rte_swx_pipeline *p;
2189f38913b7SCristian Dumitrescu 	const char *name, *profile_name;
219000b67591SAli Alnubani 	uint32_t idx0 = 0, idx1 = 0;
2191f38913b7SCristian Dumitrescu 
2192f38913b7SCristian Dumitrescu 	if (n_tokens != 11) {
2193f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2194f38913b7SCristian Dumitrescu 		return;
2195f38913b7SCristian Dumitrescu 	}
2196f38913b7SCristian Dumitrescu 
2197b9559f94SCristian Dumitrescu 	p = rte_swx_pipeline_find(tokens[1]);
2198b9559f94SCristian Dumitrescu 	if (!p) {
2199f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
2200f38913b7SCristian Dumitrescu 		return;
2201f38913b7SCristian Dumitrescu 	}
2202f38913b7SCristian Dumitrescu 
2203f38913b7SCristian Dumitrescu 	if (strcmp(tokens[2], "meter")) {
2204f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "meter");
2205f38913b7SCristian Dumitrescu 		return;
2206f38913b7SCristian Dumitrescu 	}
2207f38913b7SCristian Dumitrescu 
2208f38913b7SCristian Dumitrescu 	name = tokens[3];
2209f38913b7SCristian Dumitrescu 
2210f38913b7SCristian Dumitrescu 	if (strcmp(tokens[4], "from")) {
2211f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "from");
2212f38913b7SCristian Dumitrescu 		return;
2213f38913b7SCristian Dumitrescu 	}
2214f38913b7SCristian Dumitrescu 
2215f38913b7SCristian Dumitrescu 	if (parser_read_uint32(&idx0, tokens[5])) {
2216f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "index0");
2217f38913b7SCristian Dumitrescu 		return;
2218f38913b7SCristian Dumitrescu 	}
2219f38913b7SCristian Dumitrescu 
2220f38913b7SCristian Dumitrescu 	if (strcmp(tokens[6], "to")) {
2221f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "to");
2222f38913b7SCristian Dumitrescu 		return;
2223f38913b7SCristian Dumitrescu 	}
2224f38913b7SCristian Dumitrescu 
2225f38913b7SCristian Dumitrescu 	if (parser_read_uint32(&idx1, tokens[7]) || (idx1 < idx0)) {
2226f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "index1");
2227f38913b7SCristian Dumitrescu 		return;
2228f38913b7SCristian Dumitrescu 	}
2229f38913b7SCristian Dumitrescu 
2230f38913b7SCristian Dumitrescu 	if (strcmp(tokens[8], "set")) {
2231f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "set");
2232f38913b7SCristian Dumitrescu 		return;
2233f38913b7SCristian Dumitrescu 	}
2234f38913b7SCristian Dumitrescu 
2235f38913b7SCristian Dumitrescu 	if (strcmp(tokens[9], "profile")) {
2236f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "profile");
2237f38913b7SCristian Dumitrescu 		return;
2238f38913b7SCristian Dumitrescu 	}
2239f38913b7SCristian Dumitrescu 
2240f38913b7SCristian Dumitrescu 	profile_name = tokens[10];
2241f38913b7SCristian Dumitrescu 
2242f38913b7SCristian Dumitrescu 	for ( ; idx0 <= idx1; idx0++) {
2243f38913b7SCristian Dumitrescu 		int status;
2244f38913b7SCristian Dumitrescu 
2245b9559f94SCristian Dumitrescu 		status = rte_swx_ctl_meter_set(p, name, idx0, profile_name);
2246f38913b7SCristian Dumitrescu 		if (status) {
2247f38913b7SCristian Dumitrescu 			snprintf(out, out_size, "Command failed for index %u.\n", idx0);
2248f38913b7SCristian Dumitrescu 			return;
2249f38913b7SCristian Dumitrescu 		}
2250f38913b7SCristian Dumitrescu 	}
2251f38913b7SCristian Dumitrescu }
2252f38913b7SCristian Dumitrescu 
2253f38913b7SCristian Dumitrescu static const char cmd_pipeline_meter_stats_help[] =
2254f38913b7SCristian Dumitrescu "pipeline <pipeline_name> meter <meter_array_name> from <index0> to <index1> "
2255f38913b7SCristian Dumitrescu 	"stats\n";
2256f38913b7SCristian Dumitrescu 
2257f38913b7SCristian Dumitrescu static void
2258f38913b7SCristian Dumitrescu cmd_pipeline_meter_stats(char **tokens,
2259f38913b7SCristian Dumitrescu 	uint32_t n_tokens,
2260f38913b7SCristian Dumitrescu 	char *out,
2261f38913b7SCristian Dumitrescu 	size_t out_size,
2262b9559f94SCristian Dumitrescu 	void *obj __rte_unused)
2263f38913b7SCristian Dumitrescu {
2264f38913b7SCristian Dumitrescu 	struct rte_swx_ctl_meter_stats stats;
2265b9559f94SCristian Dumitrescu 	struct rte_swx_pipeline *p;
2266f38913b7SCristian Dumitrescu 	const char *name;
226700b67591SAli Alnubani 	uint32_t idx0 = 0, idx1 = 0;
2268f38913b7SCristian Dumitrescu 
2269f38913b7SCristian Dumitrescu 	if (n_tokens != 9) {
2270f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2271f38913b7SCristian Dumitrescu 		return;
2272f38913b7SCristian Dumitrescu 	}
2273f38913b7SCristian Dumitrescu 
2274b9559f94SCristian Dumitrescu 	p = rte_swx_pipeline_find(tokens[1]);
2275b9559f94SCristian Dumitrescu 	if (!p) {
2276f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
2277f38913b7SCristian Dumitrescu 		return;
2278f38913b7SCristian Dumitrescu 	}
2279f38913b7SCristian Dumitrescu 
2280f38913b7SCristian Dumitrescu 	if (strcmp(tokens[2], "meter")) {
2281f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "meter");
2282f38913b7SCristian Dumitrescu 		return;
2283f38913b7SCristian Dumitrescu 	}
2284f38913b7SCristian Dumitrescu 
2285f38913b7SCristian Dumitrescu 	name = tokens[3];
2286f38913b7SCristian Dumitrescu 
2287f38913b7SCristian Dumitrescu 	if (strcmp(tokens[4], "from")) {
2288f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "from");
2289f38913b7SCristian Dumitrescu 		return;
2290f38913b7SCristian Dumitrescu 	}
2291f38913b7SCristian Dumitrescu 
2292f38913b7SCristian Dumitrescu 	if (parser_read_uint32(&idx0, tokens[5])) {
2293f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "index0");
2294f38913b7SCristian Dumitrescu 		return;
2295f38913b7SCristian Dumitrescu 	}
2296f38913b7SCristian Dumitrescu 
2297f38913b7SCristian Dumitrescu 	if (strcmp(tokens[6], "to")) {
2298f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "to");
2299f38913b7SCristian Dumitrescu 		return;
2300f38913b7SCristian Dumitrescu 	}
2301f38913b7SCristian Dumitrescu 
2302f38913b7SCristian Dumitrescu 	if (parser_read_uint32(&idx1, tokens[7]) || (idx1 < idx0)) {
2303f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "index1");
2304f38913b7SCristian Dumitrescu 		return;
2305f38913b7SCristian Dumitrescu 	}
2306f38913b7SCristian Dumitrescu 
2307f38913b7SCristian Dumitrescu 	if (strcmp(tokens[8], "stats")) {
2308f38913b7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "stats");
2309f38913b7SCristian Dumitrescu 		return;
2310f38913b7SCristian Dumitrescu 	}
2311f38913b7SCristian Dumitrescu 
2312f38913b7SCristian Dumitrescu 	/* Table header. */
2313f38913b7SCristian Dumitrescu 	snprintf(out, out_size, "+-%7s-+-%16s-+-%16s-+-%16s-+-%16s-+-%16s-+-%16s-+\n",
2314f38913b7SCristian Dumitrescu 		 "-------",
2315f38913b7SCristian Dumitrescu 		 "----------------", "----------------", "----------------",
2316f38913b7SCristian Dumitrescu 		 "----------------", "----------------", "----------------");
2317f38913b7SCristian Dumitrescu 	out_size -= strlen(out);
2318f38913b7SCristian Dumitrescu 	out += strlen(out);
2319f38913b7SCristian Dumitrescu 
2320f38913b7SCristian Dumitrescu 	snprintf(out, out_size, "| %4s | %16s | %16s | %16s | %16s | %16s | %16s |\n",
2321f38913b7SCristian Dumitrescu 		 "METER #",
2322f38913b7SCristian Dumitrescu 		 "GREEN (packets)", "YELLOW (packets)", "RED (packets)",
2323f38913b7SCristian Dumitrescu 		 "GREEN (bytes)", "YELLOW (bytes)", "RED (bytes)");
2324f38913b7SCristian Dumitrescu 	out_size -= strlen(out);
2325f38913b7SCristian Dumitrescu 	out += strlen(out);
2326f38913b7SCristian Dumitrescu 
2327f38913b7SCristian Dumitrescu 	snprintf(out, out_size, "+-%7s-+-%16s-+-%16s-+-%16s-+-%16s-+-%16s-+-%16s-+\n",
2328f38913b7SCristian Dumitrescu 		 "-------",
2329f38913b7SCristian Dumitrescu 		 "----------------", "----------------", "----------------",
2330f38913b7SCristian Dumitrescu 		 "----------------", "----------------", "----------------");
2331f38913b7SCristian Dumitrescu 	out_size -= strlen(out);
2332f38913b7SCristian Dumitrescu 	out += strlen(out);
2333f38913b7SCristian Dumitrescu 
2334f38913b7SCristian Dumitrescu 	/* Table rows. */
2335f38913b7SCristian Dumitrescu 	for ( ; idx0 <= idx1; idx0++) {
2336f38913b7SCristian Dumitrescu 		int status;
2337f38913b7SCristian Dumitrescu 
2338b9559f94SCristian Dumitrescu 		status = rte_swx_ctl_meter_stats_read(p, name, idx0, &stats);
2339f38913b7SCristian Dumitrescu 		if (status) {
2340f38913b7SCristian Dumitrescu 			snprintf(out, out_size, "Pipeline meter stats error at index %u.\n", idx0);
2341f38913b7SCristian Dumitrescu 			out_size -= strlen(out);
2342f38913b7SCristian Dumitrescu 			out += strlen(out);
2343f38913b7SCristian Dumitrescu 			return;
2344f38913b7SCristian Dumitrescu 		}
2345f38913b7SCristian Dumitrescu 
2346f38913b7SCristian Dumitrescu 		snprintf(out, out_size, "| %7d | %16" PRIx64 " | %16" PRIx64 " | %16" PRIx64
2347f38913b7SCristian Dumitrescu 			 " | %16" PRIx64 " | %16" PRIx64 " | %16" PRIx64 " |\n",
2348f38913b7SCristian Dumitrescu 			 idx0,
2349f38913b7SCristian Dumitrescu 			 stats.n_pkts[RTE_COLOR_GREEN],
2350f38913b7SCristian Dumitrescu 			 stats.n_pkts[RTE_COLOR_YELLOW],
2351f38913b7SCristian Dumitrescu 			 stats.n_pkts[RTE_COLOR_RED],
2352f38913b7SCristian Dumitrescu 			 stats.n_bytes[RTE_COLOR_GREEN],
2353f38913b7SCristian Dumitrescu 			 stats.n_bytes[RTE_COLOR_YELLOW],
2354f38913b7SCristian Dumitrescu 			 stats.n_bytes[RTE_COLOR_RED]);
2355f38913b7SCristian Dumitrescu 		out_size -= strlen(out);
2356f38913b7SCristian Dumitrescu 		out += strlen(out);
2357f38913b7SCristian Dumitrescu 	}
2358f38913b7SCristian Dumitrescu }
2359f38913b7SCristian Dumitrescu 
23605074e1d5SCristian Dumitrescu static const char cmd_pipeline_stats_help[] =
23615074e1d5SCristian Dumitrescu "pipeline <pipeline_name> stats\n";
23625074e1d5SCristian Dumitrescu 
23635074e1d5SCristian Dumitrescu static void
23645074e1d5SCristian Dumitrescu cmd_pipeline_stats(char **tokens,
23655074e1d5SCristian Dumitrescu 	uint32_t n_tokens,
23665074e1d5SCristian Dumitrescu 	char *out,
23675074e1d5SCristian Dumitrescu 	size_t out_size,
2368b9559f94SCristian Dumitrescu 	void *obj __rte_unused)
23695074e1d5SCristian Dumitrescu {
23705074e1d5SCristian Dumitrescu 	struct rte_swx_ctl_pipeline_info info;
2371b9559f94SCristian Dumitrescu 	struct rte_swx_pipeline *p;
23725074e1d5SCristian Dumitrescu 	uint32_t i;
23735074e1d5SCristian Dumitrescu 	int status;
23745074e1d5SCristian Dumitrescu 
23755074e1d5SCristian Dumitrescu 	if (n_tokens != 3) {
23765074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
23775074e1d5SCristian Dumitrescu 		return;
23785074e1d5SCristian Dumitrescu 	}
23795074e1d5SCristian Dumitrescu 
2380b9559f94SCristian Dumitrescu 	p = rte_swx_pipeline_find(tokens[1]);
2381b9559f94SCristian Dumitrescu 	if (!p) {
23825074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
23835074e1d5SCristian Dumitrescu 		return;
23845074e1d5SCristian Dumitrescu 	}
23855074e1d5SCristian Dumitrescu 
23865074e1d5SCristian Dumitrescu 	if (strcmp(tokens[2], "stats")) {
23875074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "stats");
23885074e1d5SCristian Dumitrescu 		return;
23895074e1d5SCristian Dumitrescu 	}
23905074e1d5SCristian Dumitrescu 
2391b9559f94SCristian Dumitrescu 	status = rte_swx_ctl_pipeline_info_get(p, &info);
23925074e1d5SCristian Dumitrescu 	if (status) {
23935074e1d5SCristian Dumitrescu 		snprintf(out, out_size, "Pipeline info get error.");
23945074e1d5SCristian Dumitrescu 		return;
23955074e1d5SCristian Dumitrescu 	}
23965074e1d5SCristian Dumitrescu 
23975074e1d5SCristian Dumitrescu 	snprintf(out, out_size, "Input ports:\n");
23985074e1d5SCristian Dumitrescu 	out_size -= strlen(out);
23995074e1d5SCristian Dumitrescu 	out += strlen(out);
24005074e1d5SCristian Dumitrescu 
24015074e1d5SCristian Dumitrescu 	for (i = 0; i < info.n_ports_in; i++) {
24025074e1d5SCristian Dumitrescu 		struct rte_swx_port_in_stats stats;
24035074e1d5SCristian Dumitrescu 
2404b9559f94SCristian Dumitrescu 		rte_swx_ctl_pipeline_port_in_stats_read(p, i, &stats);
24055074e1d5SCristian Dumitrescu 
24065074e1d5SCristian Dumitrescu 		snprintf(out, out_size, "\tPort %u:"
24075074e1d5SCristian Dumitrescu 			" packets %" PRIu64
24085074e1d5SCristian Dumitrescu 			" bytes %" PRIu64
24095074e1d5SCristian Dumitrescu 			" empty %" PRIu64 "\n",
24105074e1d5SCristian Dumitrescu 			i, stats.n_pkts, stats.n_bytes, stats.n_empty);
24115074e1d5SCristian Dumitrescu 		out_size -= strlen(out);
24125074e1d5SCristian Dumitrescu 		out += strlen(out);
24135074e1d5SCristian Dumitrescu 	}
24145074e1d5SCristian Dumitrescu 
2415742b0a57SCristian Dumitrescu 	snprintf(out, out_size, "\nOutput ports:\n");
24165074e1d5SCristian Dumitrescu 	out_size -= strlen(out);
24175074e1d5SCristian Dumitrescu 	out += strlen(out);
24185074e1d5SCristian Dumitrescu 
24195074e1d5SCristian Dumitrescu 	for (i = 0; i < info.n_ports_out; i++) {
24205074e1d5SCristian Dumitrescu 		struct rte_swx_port_out_stats stats;
24215074e1d5SCristian Dumitrescu 
2422b9559f94SCristian Dumitrescu 		rte_swx_ctl_pipeline_port_out_stats_read(p, i, &stats);
24235074e1d5SCristian Dumitrescu 
242496b37959SCristian Dumitrescu 		if (i != info.n_ports_out - 1)
242517225455SCristian Dumitrescu 			snprintf(out, out_size, "\tPort %u:", i);
242696b37959SCristian Dumitrescu 		else
242717225455SCristian Dumitrescu 			snprintf(out, out_size, "\tDROP:");
242817225455SCristian Dumitrescu 
242917225455SCristian Dumitrescu 		out_size -= strlen(out);
243017225455SCristian Dumitrescu 		out += strlen(out);
243117225455SCristian Dumitrescu 
243217225455SCristian Dumitrescu 		snprintf(out,
243317225455SCristian Dumitrescu 			out_size,
243496b37959SCristian Dumitrescu 			" packets %" PRIu64
243517225455SCristian Dumitrescu 			" bytes %" PRIu64
243667f707b3SCristian Dumitrescu 			" packets dropped %" PRIu64
243767f707b3SCristian Dumitrescu 			" bytes dropped %" PRIu64
243817225455SCristian Dumitrescu 			" clone %" PRIu64
243917225455SCristian Dumitrescu 			" clonerr %" PRIu64 "\n",
244017225455SCristian Dumitrescu 			stats.n_pkts,
244117225455SCristian Dumitrescu 			stats.n_bytes,
244267f707b3SCristian Dumitrescu 			stats.n_pkts_drop,
244367f707b3SCristian Dumitrescu 			stats.n_bytes_drop,
244417225455SCristian Dumitrescu 			stats.n_pkts_clone,
244517225455SCristian Dumitrescu 			stats.n_pkts_clone_err);
244696b37959SCristian Dumitrescu 
24475074e1d5SCristian Dumitrescu 		out_size -= strlen(out);
24485074e1d5SCristian Dumitrescu 		out += strlen(out);
24495074e1d5SCristian Dumitrescu 	}
2450742b0a57SCristian Dumitrescu 
2451742b0a57SCristian Dumitrescu 	snprintf(out, out_size, "\nTables:\n");
2452742b0a57SCristian Dumitrescu 	out_size -= strlen(out);
2453742b0a57SCristian Dumitrescu 	out += strlen(out);
2454742b0a57SCristian Dumitrescu 
2455742b0a57SCristian Dumitrescu 	for (i = 0; i < info.n_tables; i++) {
2456742b0a57SCristian Dumitrescu 		struct rte_swx_ctl_table_info table_info;
2457742b0a57SCristian Dumitrescu 		uint64_t n_pkts_action[info.n_actions];
2458742b0a57SCristian Dumitrescu 		struct rte_swx_table_stats stats = {
2459742b0a57SCristian Dumitrescu 			.n_pkts_hit = 0,
2460742b0a57SCristian Dumitrescu 			.n_pkts_miss = 0,
2461742b0a57SCristian Dumitrescu 			.n_pkts_action = n_pkts_action,
2462742b0a57SCristian Dumitrescu 		};
2463742b0a57SCristian Dumitrescu 		uint32_t j;
2464742b0a57SCristian Dumitrescu 
2465b9559f94SCristian Dumitrescu 		status = rte_swx_ctl_table_info_get(p, i, &table_info);
2466742b0a57SCristian Dumitrescu 		if (status) {
2467742b0a57SCristian Dumitrescu 			snprintf(out, out_size, "Table info get error.");
2468742b0a57SCristian Dumitrescu 			return;
2469742b0a57SCristian Dumitrescu 		}
2470742b0a57SCristian Dumitrescu 
2471b9559f94SCristian Dumitrescu 		status = rte_swx_ctl_pipeline_table_stats_read(p, table_info.name, &stats);
2472742b0a57SCristian Dumitrescu 		if (status) {
2473742b0a57SCristian Dumitrescu 			snprintf(out, out_size, "Table stats read error.");
2474742b0a57SCristian Dumitrescu 			return;
2475742b0a57SCristian Dumitrescu 		}
2476742b0a57SCristian Dumitrescu 
2477742b0a57SCristian Dumitrescu 		snprintf(out, out_size, "\tTable %s:\n"
2478742b0a57SCristian Dumitrescu 			"\t\tHit (packets): %" PRIu64 "\n"
2479742b0a57SCristian Dumitrescu 			"\t\tMiss (packets): %" PRIu64 "\n",
2480742b0a57SCristian Dumitrescu 			table_info.name,
2481742b0a57SCristian Dumitrescu 			stats.n_pkts_hit,
2482742b0a57SCristian Dumitrescu 			stats.n_pkts_miss);
2483742b0a57SCristian Dumitrescu 		out_size -= strlen(out);
2484742b0a57SCristian Dumitrescu 		out += strlen(out);
2485742b0a57SCristian Dumitrescu 
2486742b0a57SCristian Dumitrescu 		for (j = 0; j < info.n_actions; j++) {
2487742b0a57SCristian Dumitrescu 			struct rte_swx_ctl_action_info action_info;
2488742b0a57SCristian Dumitrescu 
2489b9559f94SCristian Dumitrescu 			status = rte_swx_ctl_action_info_get(p, j, &action_info);
2490742b0a57SCristian Dumitrescu 			if (status) {
2491742b0a57SCristian Dumitrescu 				snprintf(out, out_size, "Action info get error.");
2492742b0a57SCristian Dumitrescu 				return;
2493742b0a57SCristian Dumitrescu 			}
2494742b0a57SCristian Dumitrescu 
2495742b0a57SCristian Dumitrescu 			snprintf(out, out_size, "\t\tAction %s (packets): %" PRIu64 "\n",
2496742b0a57SCristian Dumitrescu 				action_info.name,
2497742b0a57SCristian Dumitrescu 				stats.n_pkts_action[j]);
2498742b0a57SCristian Dumitrescu 			out_size -= strlen(out);
2499742b0a57SCristian Dumitrescu 			out += strlen(out);
2500742b0a57SCristian Dumitrescu 		}
2501742b0a57SCristian Dumitrescu 	}
25028bd4862fSCristian Dumitrescu 
25038bd4862fSCristian Dumitrescu 	snprintf(out, out_size, "\nLearner tables:\n");
25048bd4862fSCristian Dumitrescu 	out_size -= strlen(out);
25058bd4862fSCristian Dumitrescu 	out += strlen(out);
25068bd4862fSCristian Dumitrescu 
25078bd4862fSCristian Dumitrescu 	for (i = 0; i < info.n_learners; i++) {
25088bd4862fSCristian Dumitrescu 		struct rte_swx_ctl_learner_info learner_info;
25098bd4862fSCristian Dumitrescu 		uint64_t n_pkts_action[info.n_actions];
25108bd4862fSCristian Dumitrescu 		struct rte_swx_learner_stats stats = {
25118bd4862fSCristian Dumitrescu 			.n_pkts_hit = 0,
25128bd4862fSCristian Dumitrescu 			.n_pkts_miss = 0,
25138bd4862fSCristian Dumitrescu 			.n_pkts_action = n_pkts_action,
25148bd4862fSCristian Dumitrescu 		};
25158bd4862fSCristian Dumitrescu 		uint32_t j;
25168bd4862fSCristian Dumitrescu 
2517b9559f94SCristian Dumitrescu 		status = rte_swx_ctl_learner_info_get(p, i, &learner_info);
25188bd4862fSCristian Dumitrescu 		if (status) {
25198bd4862fSCristian Dumitrescu 			snprintf(out, out_size, "Learner table info get error.");
25208bd4862fSCristian Dumitrescu 			return;
25218bd4862fSCristian Dumitrescu 		}
25228bd4862fSCristian Dumitrescu 
2523b9559f94SCristian Dumitrescu 		status = rte_swx_ctl_pipeline_learner_stats_read(p, learner_info.name, &stats);
25248bd4862fSCristian Dumitrescu 		if (status) {
25258bd4862fSCristian Dumitrescu 			snprintf(out, out_size, "Learner table stats read error.");
25268bd4862fSCristian Dumitrescu 			return;
25278bd4862fSCristian Dumitrescu 		}
25288bd4862fSCristian Dumitrescu 
25298bd4862fSCristian Dumitrescu 		snprintf(out, out_size, "\tLearner table %s:\n"
25308bd4862fSCristian Dumitrescu 			"\t\tHit (packets): %" PRIu64 "\n"
25318bd4862fSCristian Dumitrescu 			"\t\tMiss (packets): %" PRIu64 "\n"
25328bd4862fSCristian Dumitrescu 			"\t\tLearn OK (packets): %" PRIu64 "\n"
25338bd4862fSCristian Dumitrescu 			"\t\tLearn error (packets): %" PRIu64 "\n"
253480dd28afSCristian Dumitrescu 			"\t\tRearm (packets): %" PRIu64 "\n"
25358bd4862fSCristian Dumitrescu 			"\t\tForget (packets): %" PRIu64 "\n",
25368bd4862fSCristian Dumitrescu 			learner_info.name,
25378bd4862fSCristian Dumitrescu 			stats.n_pkts_hit,
25388bd4862fSCristian Dumitrescu 			stats.n_pkts_miss,
25398bd4862fSCristian Dumitrescu 			stats.n_pkts_learn_ok,
25408bd4862fSCristian Dumitrescu 			stats.n_pkts_learn_err,
254180dd28afSCristian Dumitrescu 			stats.n_pkts_rearm,
25428bd4862fSCristian Dumitrescu 			stats.n_pkts_forget);
25438bd4862fSCristian Dumitrescu 		out_size -= strlen(out);
25448bd4862fSCristian Dumitrescu 		out += strlen(out);
25458bd4862fSCristian Dumitrescu 
25468bd4862fSCristian Dumitrescu 		for (j = 0; j < info.n_actions; j++) {
25478bd4862fSCristian Dumitrescu 			struct rte_swx_ctl_action_info action_info;
25488bd4862fSCristian Dumitrescu 
2549b9559f94SCristian Dumitrescu 			status = rte_swx_ctl_action_info_get(p, j, &action_info);
25508bd4862fSCristian Dumitrescu 			if (status) {
25518bd4862fSCristian Dumitrescu 				snprintf(out, out_size, "Action info get error.");
25528bd4862fSCristian Dumitrescu 				return;
25538bd4862fSCristian Dumitrescu 			}
25548bd4862fSCristian Dumitrescu 
25558bd4862fSCristian Dumitrescu 			snprintf(out, out_size, "\t\tAction %s (packets): %" PRIu64 "\n",
25568bd4862fSCristian Dumitrescu 				action_info.name,
25578bd4862fSCristian Dumitrescu 				stats.n_pkts_action[j]);
25588bd4862fSCristian Dumitrescu 			out_size -= strlen(out);
25598bd4862fSCristian Dumitrescu 			out += strlen(out);
25608bd4862fSCristian Dumitrescu 		}
25618bd4862fSCristian Dumitrescu 	}
25625074e1d5SCristian Dumitrescu }
25635074e1d5SCristian Dumitrescu 
256417225455SCristian Dumitrescu static const char cmd_pipeline_mirror_session_help[] =
256517225455SCristian Dumitrescu "pipeline <pipeline_name> mirror session <session_id> port <port_id> clone fast | slow "
256617225455SCristian Dumitrescu "truncate <truncation_length>\n";
256717225455SCristian Dumitrescu 
256817225455SCristian Dumitrescu static void
256917225455SCristian Dumitrescu cmd_pipeline_mirror_session(char **tokens,
257017225455SCristian Dumitrescu 	uint32_t n_tokens,
257117225455SCristian Dumitrescu 	char *out,
257217225455SCristian Dumitrescu 	size_t out_size,
2573b9559f94SCristian Dumitrescu 	void *obj __rte_unused)
257417225455SCristian Dumitrescu {
257517225455SCristian Dumitrescu 	struct rte_swx_pipeline_mirroring_session_params params;
2576b9559f94SCristian Dumitrescu 	struct rte_swx_pipeline *p;
257777dd857dSAli Alnubani 	uint32_t session_id = 0;
257817225455SCristian Dumitrescu 	int status;
257917225455SCristian Dumitrescu 
258017225455SCristian Dumitrescu 	if (n_tokens != 11) {
258117225455SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
258217225455SCristian Dumitrescu 		return;
258317225455SCristian Dumitrescu 	}
258417225455SCristian Dumitrescu 
258517225455SCristian Dumitrescu 	if (strcmp(tokens[0], "pipeline")) {
258617225455SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pipeline");
258717225455SCristian Dumitrescu 		return;
258817225455SCristian Dumitrescu 	}
258917225455SCristian Dumitrescu 
2590b9559f94SCristian Dumitrescu 	p = rte_swx_pipeline_find(tokens[1]);
2591b9559f94SCristian Dumitrescu 	if (!p) {
259217225455SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
259317225455SCristian Dumitrescu 		return;
259417225455SCristian Dumitrescu 	}
259517225455SCristian Dumitrescu 
259617225455SCristian Dumitrescu 	if (strcmp(tokens[2], "mirror")) {
259717225455SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "mirror");
259817225455SCristian Dumitrescu 		return;
259917225455SCristian Dumitrescu 	}
260017225455SCristian Dumitrescu 
260117225455SCristian Dumitrescu 	if (strcmp(tokens[3], "session")) {
260217225455SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "session");
260317225455SCristian Dumitrescu 		return;
260417225455SCristian Dumitrescu 	}
260517225455SCristian Dumitrescu 
260617225455SCristian Dumitrescu 	if (parser_read_uint32(&session_id, tokens[4])) {
260717225455SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "session_id");
260817225455SCristian Dumitrescu 		return;
260917225455SCristian Dumitrescu 	}
261017225455SCristian Dumitrescu 
261117225455SCristian Dumitrescu 	if (strcmp(tokens[5], "port")) {
261217225455SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
261317225455SCristian Dumitrescu 		return;
261417225455SCristian Dumitrescu 	}
261517225455SCristian Dumitrescu 
261617225455SCristian Dumitrescu 	if (parser_read_uint32(&params.port_id, tokens[6])) {
261717225455SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
261817225455SCristian Dumitrescu 		return;
261917225455SCristian Dumitrescu 	}
262017225455SCristian Dumitrescu 
262117225455SCristian Dumitrescu 	if (strcmp(tokens[7], "clone")) {
262217225455SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "clone");
262317225455SCristian Dumitrescu 		return;
262417225455SCristian Dumitrescu 	}
262517225455SCristian Dumitrescu 
262617225455SCristian Dumitrescu 	if (!strcmp(tokens[8], "fast"))
262717225455SCristian Dumitrescu 		params.fast_clone = 1;
262817225455SCristian Dumitrescu 	else if (!strcmp(tokens[8], "slow"))
262917225455SCristian Dumitrescu 		params.fast_clone = 0;
263017225455SCristian Dumitrescu 	else {
263117225455SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "clone");
263217225455SCristian Dumitrescu 		return;
263317225455SCristian Dumitrescu 	}
263417225455SCristian Dumitrescu 
263517225455SCristian Dumitrescu 	if (strcmp(tokens[9], "truncate")) {
263617225455SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "truncate");
263717225455SCristian Dumitrescu 		return;
263817225455SCristian Dumitrescu 	}
263917225455SCristian Dumitrescu 
264017225455SCristian Dumitrescu 	if (parser_read_uint32(&params.truncation_length, tokens[10])) {
264117225455SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "truncation_length");
264217225455SCristian Dumitrescu 		return;
264317225455SCristian Dumitrescu 	}
264417225455SCristian Dumitrescu 
2645b9559f94SCristian Dumitrescu 	status = rte_swx_ctl_pipeline_mirroring_session_set(p, session_id, &params);
264617225455SCristian Dumitrescu 	if (status) {
264717225455SCristian Dumitrescu 		snprintf(out, out_size, "Command failed!\n");
264817225455SCristian Dumitrescu 		return;
264917225455SCristian Dumitrescu 	}
265017225455SCristian Dumitrescu }
265117225455SCristian Dumitrescu 
26525074e1d5SCristian Dumitrescu static const char cmd_thread_pipeline_enable_help[] =
2653b9559f94SCristian Dumitrescu "thread <thread_id> pipeline <pipeline_name> enable [ period <timer_period_ms> ]\n";
2654b9559f94SCristian Dumitrescu 
2655b9559f94SCristian Dumitrescu #ifndef TIMER_PERIOD_MS_DEFAULT
2656b9559f94SCristian Dumitrescu #define TIMER_PERIOD_MS_DEFAULT 10
2657b9559f94SCristian Dumitrescu #endif
26585074e1d5SCristian Dumitrescu 
26595074e1d5SCristian Dumitrescu static void
26605074e1d5SCristian Dumitrescu cmd_thread_pipeline_enable(char **tokens,
26615074e1d5SCristian Dumitrescu 	uint32_t n_tokens,
26625074e1d5SCristian Dumitrescu 	char *out,
26635074e1d5SCristian Dumitrescu 	size_t out_size,
2664b9559f94SCristian Dumitrescu 	void *obj __rte_unused)
26655074e1d5SCristian Dumitrescu {
26665074e1d5SCristian Dumitrescu 	char *pipeline_name;
2667b9559f94SCristian Dumitrescu 	struct rte_swx_pipeline *p;
2668b9559f94SCristian Dumitrescu 	uint32_t thread_id, timer_period_ms = TIMER_PERIOD_MS_DEFAULT;
26695074e1d5SCristian Dumitrescu 	int status;
26705074e1d5SCristian Dumitrescu 
2671b9559f94SCristian Dumitrescu 	if ((n_tokens != 5) && (n_tokens != 7)) {
26725074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
26735074e1d5SCristian Dumitrescu 		return;
26745074e1d5SCristian Dumitrescu 	}
26755074e1d5SCristian Dumitrescu 
26765074e1d5SCristian Dumitrescu 	if (parser_read_uint32(&thread_id, tokens[1]) != 0) {
26775074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "thread_id");
26785074e1d5SCristian Dumitrescu 		return;
26795074e1d5SCristian Dumitrescu 	}
26805074e1d5SCristian Dumitrescu 
26815074e1d5SCristian Dumitrescu 	if (strcmp(tokens[2], "pipeline") != 0) {
26825074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pipeline");
26835074e1d5SCristian Dumitrescu 		return;
26845074e1d5SCristian Dumitrescu 	}
26855074e1d5SCristian Dumitrescu 
26865074e1d5SCristian Dumitrescu 	pipeline_name = tokens[3];
2687b9559f94SCristian Dumitrescu 	p = rte_swx_pipeline_find(pipeline_name);
2688b9559f94SCristian Dumitrescu 	if (!p) {
26895074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
26905074e1d5SCristian Dumitrescu 		return;
26915074e1d5SCristian Dumitrescu 	}
26925074e1d5SCristian Dumitrescu 
26935074e1d5SCristian Dumitrescu 	if (strcmp(tokens[4], "enable") != 0) {
26945074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "enable");
26955074e1d5SCristian Dumitrescu 		return;
26965074e1d5SCristian Dumitrescu 	}
26975074e1d5SCristian Dumitrescu 
2698b9559f94SCristian Dumitrescu 	if (n_tokens == 7) {
2699b9559f94SCristian Dumitrescu 		if (strcmp(tokens[5], "period") != 0) {
2700b9559f94SCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_NOT_FOUND, "period");
2701b9559f94SCristian Dumitrescu 			return;
2702b9559f94SCristian Dumitrescu 		}
2703b9559f94SCristian Dumitrescu 
2704b9559f94SCristian Dumitrescu 		if (parser_read_uint32(&timer_period_ms, tokens[6]) != 0) {
2705b9559f94SCristian Dumitrescu 			snprintf(out, out_size, MSG_ARG_INVALID, "timer_period_ms");
2706b9559f94SCristian Dumitrescu 			return;
2707b9559f94SCristian Dumitrescu 		}
2708b9559f94SCristian Dumitrescu 	}
2709b9559f94SCristian Dumitrescu 
2710b9559f94SCristian Dumitrescu 	status = thread_pipeline_enable(thread_id, p, timer_period_ms);
27115074e1d5SCristian Dumitrescu 	if (status) {
27125074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_CMD_FAIL, "thread pipeline enable");
27135074e1d5SCristian Dumitrescu 		return;
27145074e1d5SCristian Dumitrescu 	}
27155074e1d5SCristian Dumitrescu }
27165074e1d5SCristian Dumitrescu 
27175074e1d5SCristian Dumitrescu static const char cmd_thread_pipeline_disable_help[] =
27185074e1d5SCristian Dumitrescu "thread <thread_id> pipeline <pipeline_name> disable\n";
27195074e1d5SCristian Dumitrescu 
27205074e1d5SCristian Dumitrescu static void
27215074e1d5SCristian Dumitrescu cmd_thread_pipeline_disable(char **tokens,
27225074e1d5SCristian Dumitrescu 	uint32_t n_tokens,
27235074e1d5SCristian Dumitrescu 	char *out,
27245074e1d5SCristian Dumitrescu 	size_t out_size,
2725b9559f94SCristian Dumitrescu 	void *obj __rte_unused)
27265074e1d5SCristian Dumitrescu {
2727b9559f94SCristian Dumitrescu 	struct rte_swx_pipeline *p;
27285074e1d5SCristian Dumitrescu 	char *pipeline_name;
27295074e1d5SCristian Dumitrescu 	uint32_t thread_id;
27305074e1d5SCristian Dumitrescu 	int status;
27315074e1d5SCristian Dumitrescu 
27325074e1d5SCristian Dumitrescu 	if (n_tokens != 5) {
27335074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
27345074e1d5SCristian Dumitrescu 		return;
27355074e1d5SCristian Dumitrescu 	}
27365074e1d5SCristian Dumitrescu 
27375074e1d5SCristian Dumitrescu 	if (parser_read_uint32(&thread_id, tokens[1]) != 0) {
27385074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "thread_id");
27395074e1d5SCristian Dumitrescu 		return;
27405074e1d5SCristian Dumitrescu 	}
27415074e1d5SCristian Dumitrescu 
27425074e1d5SCristian Dumitrescu 	if (strcmp(tokens[2], "pipeline") != 0) {
27435074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pipeline");
27445074e1d5SCristian Dumitrescu 		return;
27455074e1d5SCristian Dumitrescu 	}
27465074e1d5SCristian Dumitrescu 
27475074e1d5SCristian Dumitrescu 	pipeline_name = tokens[3];
2748b9559f94SCristian Dumitrescu 	p = rte_swx_pipeline_find(pipeline_name);
2749b9559f94SCristian Dumitrescu 	if (!p) {
27505074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
27515074e1d5SCristian Dumitrescu 		return;
27525074e1d5SCristian Dumitrescu 	}
27535074e1d5SCristian Dumitrescu 
27545074e1d5SCristian Dumitrescu 	if (strcmp(tokens[4], "disable") != 0) {
27555074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "disable");
27565074e1d5SCristian Dumitrescu 		return;
27575074e1d5SCristian Dumitrescu 	}
27585074e1d5SCristian Dumitrescu 
2759b9559f94SCristian Dumitrescu 	status = thread_pipeline_disable(thread_id, p);
27605074e1d5SCristian Dumitrescu 	if (status) {
27615074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_CMD_FAIL,
27625074e1d5SCristian Dumitrescu 			"thread pipeline disable");
27635074e1d5SCristian Dumitrescu 		return;
27645074e1d5SCristian Dumitrescu 	}
27655074e1d5SCristian Dumitrescu }
27665074e1d5SCristian Dumitrescu 
27675074e1d5SCristian Dumitrescu static void
27685074e1d5SCristian Dumitrescu cmd_help(char **tokens,
27695074e1d5SCristian Dumitrescu 	 uint32_t n_tokens,
27705074e1d5SCristian Dumitrescu 	 char *out,
27715074e1d5SCristian Dumitrescu 	 size_t out_size,
27725074e1d5SCristian Dumitrescu 	 void *arg __rte_unused)
27735074e1d5SCristian Dumitrescu {
27745074e1d5SCristian Dumitrescu 	tokens++;
27755074e1d5SCristian Dumitrescu 	n_tokens--;
27765074e1d5SCristian Dumitrescu 
27775074e1d5SCristian Dumitrescu 	if (n_tokens == 0) {
27785074e1d5SCristian Dumitrescu 		snprintf(out, out_size,
27797fef9ef1SYogesh Jangra 			"Type 'help <command>' for command details.\n\n"
27807fef9ef1SYogesh Jangra 			"List of commands:\n"
27817fef9ef1SYogesh Jangra 			"\tmempool\n"
2782f31c80f8SCristian Dumitrescu 			"\tethdev\n"
27839043f66aSCristian Dumitrescu 			"\tpipeline codegen\n"
27846bc14d9fSCristian Dumitrescu 			"\tpipeline libbuild\n"
27857fef9ef1SYogesh Jangra 			"\tpipeline build\n"
278675129cebSChurchill Khangar 			"\tpipeline table add\n"
278775129cebSChurchill Khangar 			"\tpipeline table delete\n"
278875129cebSChurchill Khangar 			"\tpipeline table default\n"
278975129cebSChurchill Khangar 			"\tpipeline table show\n"
2790598fe0ddSCristian Dumitrescu 			"\tpipeline selector group add\n"
2791598fe0ddSCristian Dumitrescu 			"\tpipeline selector group delete\n"
2792598fe0ddSCristian Dumitrescu 			"\tpipeline selector group member add\n"
2793598fe0ddSCristian Dumitrescu 			"\tpipeline selector group member delete\n"
2794598fe0ddSCristian Dumitrescu 			"\tpipeline selector show\n"
27958bd4862fSCristian Dumitrescu 			"\tpipeline learner default\n"
279675129cebSChurchill Khangar 			"\tpipeline commit\n"
279775129cebSChurchill Khangar 			"\tpipeline abort\n"
279864cfcebdSCristian Dumitrescu 			"\tpipeline regrd\n"
279964cfcebdSCristian Dumitrescu 			"\tpipeline regwr\n"
2800f38913b7SCristian Dumitrescu 			"\tpipeline meter profile add\n"
2801f38913b7SCristian Dumitrescu 			"\tpipeline meter profile delete\n"
2802f38913b7SCristian Dumitrescu 			"\tpipeline meter reset\n"
2803f38913b7SCristian Dumitrescu 			"\tpipeline meter set\n"
2804f38913b7SCristian Dumitrescu 			"\tpipeline meter stats\n"
28057fef9ef1SYogesh Jangra 			"\tpipeline stats\n"
280617225455SCristian Dumitrescu 			"\tpipeline mirror session\n"
28077fef9ef1SYogesh Jangra 			"\tthread pipeline enable\n"
28087fef9ef1SYogesh Jangra 			"\tthread pipeline disable\n\n");
28095074e1d5SCristian Dumitrescu 		return;
28105074e1d5SCristian Dumitrescu 	}
28115074e1d5SCristian Dumitrescu 
28125074e1d5SCristian Dumitrescu 	if (strcmp(tokens[0], "mempool") == 0) {
28135074e1d5SCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n", cmd_mempool_help);
28145074e1d5SCristian Dumitrescu 		return;
28155074e1d5SCristian Dumitrescu 	}
28165074e1d5SCristian Dumitrescu 
2817f31c80f8SCristian Dumitrescu 	if (strcmp(tokens[0], "ethdev") == 0) {
2818f31c80f8SCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n", cmd_ethdev_help);
28195074e1d5SCristian Dumitrescu 		return;
28205074e1d5SCristian Dumitrescu 	}
28215074e1d5SCristian Dumitrescu 
282277a41301SCristian Dumitrescu 	if (strcmp(tokens[0], "ring") == 0) {
282377a41301SCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n", cmd_ring_help);
282477a41301SCristian Dumitrescu 		return;
282577a41301SCristian Dumitrescu 	}
282677a41301SCristian Dumitrescu 
28275074e1d5SCristian Dumitrescu 	if ((strcmp(tokens[0], "pipeline") == 0) &&
28289043f66aSCristian Dumitrescu 		(n_tokens == 2) && (strcmp(tokens[1], "codegen") == 0)) {
28299043f66aSCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n", cmd_pipeline_codegen_help);
28309043f66aSCristian Dumitrescu 		return;
28319043f66aSCristian Dumitrescu 	}
28329043f66aSCristian Dumitrescu 
28339043f66aSCristian Dumitrescu 	if ((strcmp(tokens[0], "pipeline") == 0) &&
28346bc14d9fSCristian Dumitrescu 		(n_tokens == 2) && (strcmp(tokens[1], "libbuild") == 0)) {
28356bc14d9fSCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n", cmd_pipeline_libbuild_help);
28366bc14d9fSCristian Dumitrescu 		return;
28376bc14d9fSCristian Dumitrescu 	}
28386bc14d9fSCristian Dumitrescu 
28396bc14d9fSCristian Dumitrescu 	if ((strcmp(tokens[0], "pipeline") == 0) &&
28407fef9ef1SYogesh Jangra 		(n_tokens == 2) && (strcmp(tokens[1], "build") == 0)) {
28415074e1d5SCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n", cmd_pipeline_build_help);
28425074e1d5SCristian Dumitrescu 		return;
28435074e1d5SCristian Dumitrescu 	}
28445074e1d5SCristian Dumitrescu 
28455074e1d5SCristian Dumitrescu 	if ((strcmp(tokens[0], "pipeline") == 0) &&
28467fef9ef1SYogesh Jangra 		(n_tokens == 3) &&
28477fef9ef1SYogesh Jangra 		(strcmp(tokens[1], "table") == 0) &&
284875129cebSChurchill Khangar 		(strcmp(tokens[2], "add") == 0)) {
28495074e1d5SCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n",
285075129cebSChurchill Khangar 			cmd_pipeline_table_add_help);
285175129cebSChurchill Khangar 		return;
285275129cebSChurchill Khangar 	}
285375129cebSChurchill Khangar 
285475129cebSChurchill Khangar 	if ((strcmp(tokens[0], "pipeline") == 0) &&
285575129cebSChurchill Khangar 		(n_tokens == 3) &&
285675129cebSChurchill Khangar 		(strcmp(tokens[1], "table") == 0) &&
285775129cebSChurchill Khangar 		(strcmp(tokens[2], "delete") == 0)) {
285875129cebSChurchill Khangar 		snprintf(out, out_size, "\n%s\n",
285975129cebSChurchill Khangar 			cmd_pipeline_table_delete_help);
286075129cebSChurchill Khangar 		return;
286175129cebSChurchill Khangar 	}
286275129cebSChurchill Khangar 
286375129cebSChurchill Khangar 	if ((strcmp(tokens[0], "pipeline") == 0) &&
286475129cebSChurchill Khangar 		(n_tokens == 3) &&
286575129cebSChurchill Khangar 		(strcmp(tokens[1], "table") == 0) &&
286675129cebSChurchill Khangar 		(strcmp(tokens[2], "default") == 0)) {
286775129cebSChurchill Khangar 		snprintf(out, out_size, "\n%s\n",
286875129cebSChurchill Khangar 			cmd_pipeline_table_default_help);
286975129cebSChurchill Khangar 		return;
287075129cebSChurchill Khangar 	}
287175129cebSChurchill Khangar 
287275129cebSChurchill Khangar 	if ((strcmp(tokens[0], "pipeline") == 0) &&
287375129cebSChurchill Khangar 		(n_tokens == 3) &&
287475129cebSChurchill Khangar 		(strcmp(tokens[1], "table") == 0) &&
287575129cebSChurchill Khangar 		(strcmp(tokens[2], "show") == 0)) {
287675129cebSChurchill Khangar 		snprintf(out, out_size, "\n%s\n",
287775129cebSChurchill Khangar 			cmd_pipeline_table_show_help);
287875129cebSChurchill Khangar 		return;
287975129cebSChurchill Khangar 	}
288075129cebSChurchill Khangar 
288175129cebSChurchill Khangar 	if ((strcmp(tokens[0], "pipeline") == 0) &&
2882598fe0ddSCristian Dumitrescu 		(n_tokens == 4) &&
2883598fe0ddSCristian Dumitrescu 		(strcmp(tokens[1], "selector") == 0) &&
2884598fe0ddSCristian Dumitrescu 		(strcmp(tokens[2], "group") == 0) &&
2885598fe0ddSCristian Dumitrescu 		(strcmp(tokens[3], "add") == 0)) {
2886598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n",
2887598fe0ddSCristian Dumitrescu 			cmd_pipeline_selector_group_add_help);
2888598fe0ddSCristian Dumitrescu 		return;
2889598fe0ddSCristian Dumitrescu 	}
2890598fe0ddSCristian Dumitrescu 
2891598fe0ddSCristian Dumitrescu 	if ((strcmp(tokens[0], "pipeline") == 0) &&
2892598fe0ddSCristian Dumitrescu 		(n_tokens == 4) &&
2893598fe0ddSCristian Dumitrescu 		(strcmp(tokens[1], "selector") == 0) &&
2894598fe0ddSCristian Dumitrescu 		(strcmp(tokens[2], "group") == 0) &&
2895598fe0ddSCristian Dumitrescu 		(strcmp(tokens[3], "delete") == 0)) {
2896598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n",
2897598fe0ddSCristian Dumitrescu 			cmd_pipeline_selector_group_delete_help);
2898598fe0ddSCristian Dumitrescu 		return;
2899598fe0ddSCristian Dumitrescu 	}
2900598fe0ddSCristian Dumitrescu 
2901598fe0ddSCristian Dumitrescu 	if ((strcmp(tokens[0], "pipeline") == 0) &&
2902598fe0ddSCristian Dumitrescu 		(n_tokens == 5) &&
2903598fe0ddSCristian Dumitrescu 		(strcmp(tokens[1], "selector") == 0) &&
2904598fe0ddSCristian Dumitrescu 		(strcmp(tokens[2], "group") == 0) &&
2905598fe0ddSCristian Dumitrescu 		(strcmp(tokens[3], "member") == 0) &&
2906598fe0ddSCristian Dumitrescu 		(strcmp(tokens[4], "add") == 0)) {
2907598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n",
2908598fe0ddSCristian Dumitrescu 			cmd_pipeline_selector_group_member_add_help);
2909598fe0ddSCristian Dumitrescu 		return;
2910598fe0ddSCristian Dumitrescu 	}
2911598fe0ddSCristian Dumitrescu 
2912598fe0ddSCristian Dumitrescu 	if ((strcmp(tokens[0], "pipeline") == 0) &&
2913598fe0ddSCristian Dumitrescu 		(n_tokens == 5) &&
2914598fe0ddSCristian Dumitrescu 		(strcmp(tokens[1], "selector") == 0) &&
2915598fe0ddSCristian Dumitrescu 		(strcmp(tokens[2], "group") == 0) &&
2916598fe0ddSCristian Dumitrescu 		(strcmp(tokens[3], "member") == 0) &&
2917598fe0ddSCristian Dumitrescu 		(strcmp(tokens[4], "delete") == 0)) {
2918598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n",
2919598fe0ddSCristian Dumitrescu 			cmd_pipeline_selector_group_member_delete_help);
2920598fe0ddSCristian Dumitrescu 		return;
2921598fe0ddSCristian Dumitrescu 	}
2922598fe0ddSCristian Dumitrescu 
2923598fe0ddSCristian Dumitrescu 	if ((strcmp(tokens[0], "pipeline") == 0) &&
2924598fe0ddSCristian Dumitrescu 		(n_tokens == 3) &&
2925598fe0ddSCristian Dumitrescu 		(strcmp(tokens[1], "selector") == 0) &&
2926598fe0ddSCristian Dumitrescu 		(strcmp(tokens[2], "show") == 0)) {
2927598fe0ddSCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n",
2928598fe0ddSCristian Dumitrescu 			cmd_pipeline_selector_show_help);
2929598fe0ddSCristian Dumitrescu 		return;
2930598fe0ddSCristian Dumitrescu 	}
2931598fe0ddSCristian Dumitrescu 
2932598fe0ddSCristian Dumitrescu 	if ((strcmp(tokens[0], "pipeline") == 0) &&
29338bd4862fSCristian Dumitrescu 		(n_tokens == 3) &&
29348bd4862fSCristian Dumitrescu 		(strcmp(tokens[1], "learner") == 0) &&
29358bd4862fSCristian Dumitrescu 		(strcmp(tokens[2], "default") == 0)) {
29368bd4862fSCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n",
29378bd4862fSCristian Dumitrescu 			cmd_pipeline_learner_default_help);
29388bd4862fSCristian Dumitrescu 		return;
29398bd4862fSCristian Dumitrescu 	}
29408bd4862fSCristian Dumitrescu 
29418bd4862fSCristian Dumitrescu 	if ((strcmp(tokens[0], "pipeline") == 0) &&
294275129cebSChurchill Khangar 		(n_tokens == 2) &&
294375129cebSChurchill Khangar 		(strcmp(tokens[1], "commit") == 0)) {
294475129cebSChurchill Khangar 		snprintf(out, out_size, "\n%s\n",
294575129cebSChurchill Khangar 			cmd_pipeline_commit_help);
294675129cebSChurchill Khangar 		return;
294775129cebSChurchill Khangar 	}
294875129cebSChurchill Khangar 
294975129cebSChurchill Khangar 	if ((strcmp(tokens[0], "pipeline") == 0) &&
295075129cebSChurchill Khangar 		(n_tokens == 2) &&
295175129cebSChurchill Khangar 		(strcmp(tokens[1], "abort") == 0)) {
295275129cebSChurchill Khangar 		snprintf(out, out_size, "\n%s\n",
295375129cebSChurchill Khangar 			cmd_pipeline_abort_help);
29545074e1d5SCristian Dumitrescu 		return;
29555074e1d5SCristian Dumitrescu 	}
29565074e1d5SCristian Dumitrescu 
29575074e1d5SCristian Dumitrescu 	if ((strcmp(tokens[0], "pipeline") == 0) &&
295864cfcebdSCristian Dumitrescu 		(n_tokens == 2) && (strcmp(tokens[1], "regrd") == 0)) {
295964cfcebdSCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n", cmd_pipeline_regrd_help);
296064cfcebdSCristian Dumitrescu 		return;
296164cfcebdSCristian Dumitrescu 	}
296264cfcebdSCristian Dumitrescu 
296364cfcebdSCristian Dumitrescu 	if ((strcmp(tokens[0], "pipeline") == 0) &&
296464cfcebdSCristian Dumitrescu 		(n_tokens == 2) && (strcmp(tokens[1], "regwr") == 0)) {
296564cfcebdSCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n", cmd_pipeline_regwr_help);
296664cfcebdSCristian Dumitrescu 		return;
296764cfcebdSCristian Dumitrescu 	}
296864cfcebdSCristian Dumitrescu 
2969f38913b7SCristian Dumitrescu 	if (!strcmp(tokens[0], "pipeline") &&
2970f38913b7SCristian Dumitrescu 		(n_tokens == 4) && !strcmp(tokens[1], "meter")
2971f38913b7SCristian Dumitrescu 		&& !strcmp(tokens[2], "profile")
2972f38913b7SCristian Dumitrescu 		&& !strcmp(tokens[3], "add")) {
2973f38913b7SCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n", cmd_pipeline_meter_profile_add_help);
2974f38913b7SCristian Dumitrescu 		return;
2975f38913b7SCristian Dumitrescu 	}
2976f38913b7SCristian Dumitrescu 
2977f38913b7SCristian Dumitrescu 	if (!strcmp(tokens[0], "pipeline") &&
2978f38913b7SCristian Dumitrescu 		(n_tokens == 4) && !strcmp(tokens[1], "meter")
2979f38913b7SCristian Dumitrescu 		&& !strcmp(tokens[2], "profile")
2980f38913b7SCristian Dumitrescu 		&& !strcmp(tokens[3], "delete")) {
2981f38913b7SCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n", cmd_pipeline_meter_profile_delete_help);
2982f38913b7SCristian Dumitrescu 		return;
2983f38913b7SCristian Dumitrescu 	}
2984f38913b7SCristian Dumitrescu 
2985f38913b7SCristian Dumitrescu 	if (!strcmp(tokens[0], "pipeline") &&
2986f38913b7SCristian Dumitrescu 		(n_tokens == 3) && !strcmp(tokens[1], "meter")
2987f38913b7SCristian Dumitrescu 		&& !strcmp(tokens[2], "reset")) {
2988f38913b7SCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n", cmd_pipeline_meter_reset_help);
2989f38913b7SCristian Dumitrescu 		return;
2990f38913b7SCristian Dumitrescu 	}
2991f38913b7SCristian Dumitrescu 
2992f38913b7SCristian Dumitrescu 	if (!strcmp(tokens[0], "pipeline") &&
2993f38913b7SCristian Dumitrescu 		(n_tokens == 3) && !strcmp(tokens[1], "meter")
2994f38913b7SCristian Dumitrescu 		&& !strcmp(tokens[2], "set")) {
2995f38913b7SCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n", cmd_pipeline_meter_set_help);
2996f38913b7SCristian Dumitrescu 		return;
2997f38913b7SCristian Dumitrescu 	}
2998f38913b7SCristian Dumitrescu 
2999f38913b7SCristian Dumitrescu 	if (!strcmp(tokens[0], "pipeline") &&
3000f38913b7SCristian Dumitrescu 		(n_tokens == 3) && !strcmp(tokens[1], "meter")
3001f38913b7SCristian Dumitrescu 		&& !strcmp(tokens[2], "stats")) {
3002f38913b7SCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n", cmd_pipeline_meter_stats_help);
3003f38913b7SCristian Dumitrescu 		return;
3004f38913b7SCristian Dumitrescu 	}
3005f38913b7SCristian Dumitrescu 
300664cfcebdSCristian Dumitrescu 	if ((strcmp(tokens[0], "pipeline") == 0) &&
30077fef9ef1SYogesh Jangra 		(n_tokens == 2) && (strcmp(tokens[1], "stats") == 0)) {
30085074e1d5SCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n", cmd_pipeline_stats_help);
30095074e1d5SCristian Dumitrescu 		return;
30105074e1d5SCristian Dumitrescu 	}
30115074e1d5SCristian Dumitrescu 
301217225455SCristian Dumitrescu 	if (!strcmp(tokens[0], "pipeline") &&
301317225455SCristian Dumitrescu 		(n_tokens == 3) && !strcmp(tokens[1], "mirror")
301417225455SCristian Dumitrescu 		&& !strcmp(tokens[2], "session")) {
301517225455SCristian Dumitrescu 		snprintf(out, out_size, "\n%s\n", cmd_pipeline_mirror_session_help);
301617225455SCristian Dumitrescu 		return;
301717225455SCristian Dumitrescu 	}
301817225455SCristian Dumitrescu 
30195074e1d5SCristian Dumitrescu 	if ((n_tokens == 3) &&
30205074e1d5SCristian Dumitrescu 		(strcmp(tokens[0], "thread") == 0) &&
30215074e1d5SCristian Dumitrescu 		(strcmp(tokens[1], "pipeline") == 0)) {
30225074e1d5SCristian Dumitrescu 		if (strcmp(tokens[2], "enable") == 0) {
30235074e1d5SCristian Dumitrescu 			snprintf(out, out_size, "\n%s\n",
30245074e1d5SCristian Dumitrescu 				cmd_thread_pipeline_enable_help);
30255074e1d5SCristian Dumitrescu 			return;
30265074e1d5SCristian Dumitrescu 		}
30275074e1d5SCristian Dumitrescu 
30285074e1d5SCristian Dumitrescu 		if (strcmp(tokens[2], "disable") == 0) {
30295074e1d5SCristian Dumitrescu 			snprintf(out, out_size, "\n%s\n",
30305074e1d5SCristian Dumitrescu 				cmd_thread_pipeline_disable_help);
30315074e1d5SCristian Dumitrescu 			return;
30325074e1d5SCristian Dumitrescu 		}
30335074e1d5SCristian Dumitrescu 	}
30345074e1d5SCristian Dumitrescu 
30355074e1d5SCristian Dumitrescu 	snprintf(out, out_size, "Invalid command\n");
30365074e1d5SCristian Dumitrescu }
30375074e1d5SCristian Dumitrescu 
30385074e1d5SCristian Dumitrescu void
30395074e1d5SCristian Dumitrescu cli_process(char *in, char *out, size_t out_size, void *obj)
30405074e1d5SCristian Dumitrescu {
30415074e1d5SCristian Dumitrescu 	char *tokens[CMD_MAX_TOKENS];
30425074e1d5SCristian Dumitrescu 	uint32_t n_tokens = RTE_DIM(tokens);
30435074e1d5SCristian Dumitrescu 	int status;
30445074e1d5SCristian Dumitrescu 
30455074e1d5SCristian Dumitrescu 	if (is_comment(in))
30465074e1d5SCristian Dumitrescu 		return;
30475074e1d5SCristian Dumitrescu 
30485074e1d5SCristian Dumitrescu 	status = parse_tokenize_string(in, tokens, &n_tokens);
30495074e1d5SCristian Dumitrescu 	if (status) {
30505074e1d5SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_TOO_MANY, "");
30515074e1d5SCristian Dumitrescu 		return;
30525074e1d5SCristian Dumitrescu 	}
30535074e1d5SCristian Dumitrescu 
30545074e1d5SCristian Dumitrescu 	if (n_tokens == 0)
30555074e1d5SCristian Dumitrescu 		return;
30565074e1d5SCristian Dumitrescu 
30575074e1d5SCristian Dumitrescu 	if (strcmp(tokens[0], "help") == 0) {
30585074e1d5SCristian Dumitrescu 		cmd_help(tokens, n_tokens, out, out_size, obj);
30595074e1d5SCristian Dumitrescu 		return;
30605074e1d5SCristian Dumitrescu 	}
30615074e1d5SCristian Dumitrescu 
30625074e1d5SCristian Dumitrescu 	if (strcmp(tokens[0], "mempool") == 0) {
30635074e1d5SCristian Dumitrescu 		cmd_mempool(tokens, n_tokens, out, out_size, obj);
30645074e1d5SCristian Dumitrescu 		return;
30655074e1d5SCristian Dumitrescu 	}
30665074e1d5SCristian Dumitrescu 
3067f31c80f8SCristian Dumitrescu 	if (strcmp(tokens[0], "ethdev") == 0) {
3068821848f5SCristian Dumitrescu 		if ((n_tokens >= 2) && (strcmp(tokens[1], "show") == 0)) {
3069f31c80f8SCristian Dumitrescu 			cmd_ethdev_show(tokens, n_tokens, out, out_size, obj);
30705074e1d5SCristian Dumitrescu 			return;
30715074e1d5SCristian Dumitrescu 		}
30725074e1d5SCristian Dumitrescu 
3073f31c80f8SCristian Dumitrescu 		cmd_ethdev(tokens, n_tokens, out, out_size, obj);
30745074e1d5SCristian Dumitrescu 		return;
30755074e1d5SCristian Dumitrescu 	}
30765074e1d5SCristian Dumitrescu 
307777a41301SCristian Dumitrescu 	if (strcmp(tokens[0], "ring") == 0) {
307877a41301SCristian Dumitrescu 		cmd_ring(tokens, n_tokens, out, out_size, obj);
307977a41301SCristian Dumitrescu 		return;
308077a41301SCristian Dumitrescu 	}
308177a41301SCristian Dumitrescu 
30825074e1d5SCristian Dumitrescu 	if (strcmp(tokens[0], "pipeline") == 0) {
30835074e1d5SCristian Dumitrescu 		if ((n_tokens >= 3) &&
30849043f66aSCristian Dumitrescu 			(strcmp(tokens[1], "codegen") == 0)) {
30859043f66aSCristian Dumitrescu 			cmd_pipeline_codegen(tokens, n_tokens, out, out_size,
30869043f66aSCristian Dumitrescu 				obj);
30879043f66aSCristian Dumitrescu 			return;
30889043f66aSCristian Dumitrescu 		}
30899043f66aSCristian Dumitrescu 
30909043f66aSCristian Dumitrescu 		if ((n_tokens >= 3) &&
30916bc14d9fSCristian Dumitrescu 			(strcmp(tokens[1], "libbuild") == 0)) {
30926bc14d9fSCristian Dumitrescu 			cmd_pipeline_libbuild(tokens, n_tokens, out, out_size,
30936bc14d9fSCristian Dumitrescu 				obj);
30946bc14d9fSCristian Dumitrescu 			return;
30956bc14d9fSCristian Dumitrescu 		}
30966bc14d9fSCristian Dumitrescu 
30976bc14d9fSCristian Dumitrescu 		if ((n_tokens >= 3) &&
30985074e1d5SCristian Dumitrescu 			(strcmp(tokens[2], "build") == 0)) {
30995074e1d5SCristian Dumitrescu 			cmd_pipeline_build(tokens, n_tokens, out, out_size,
31005074e1d5SCristian Dumitrescu 				obj);
31015074e1d5SCristian Dumitrescu 			return;
31025074e1d5SCristian Dumitrescu 		}
31035074e1d5SCristian Dumitrescu 
310475129cebSChurchill Khangar 		if ((n_tokens >= 5) &&
310575129cebSChurchill Khangar 			(strcmp(tokens[2], "table") == 0) &&
310675129cebSChurchill Khangar 			(strcmp(tokens[4], "add") == 0)) {
310775129cebSChurchill Khangar 			cmd_pipeline_table_add(tokens, n_tokens, out,
310875129cebSChurchill Khangar 				out_size, obj);
310975129cebSChurchill Khangar 			return;
311075129cebSChurchill Khangar 		}
311175129cebSChurchill Khangar 
311275129cebSChurchill Khangar 		if ((n_tokens >= 5) &&
311375129cebSChurchill Khangar 			(strcmp(tokens[2], "table") == 0) &&
311475129cebSChurchill Khangar 			(strcmp(tokens[4], "delete") == 0)) {
311575129cebSChurchill Khangar 			cmd_pipeline_table_delete(tokens, n_tokens, out,
311675129cebSChurchill Khangar 				out_size, obj);
311775129cebSChurchill Khangar 			return;
311875129cebSChurchill Khangar 		}
311975129cebSChurchill Khangar 
312075129cebSChurchill Khangar 		if ((n_tokens >= 5) &&
312175129cebSChurchill Khangar 			(strcmp(tokens[2], "table") == 0) &&
312275129cebSChurchill Khangar 			(strcmp(tokens[4], "default") == 0)) {
312375129cebSChurchill Khangar 			cmd_pipeline_table_default(tokens, n_tokens, out,
312475129cebSChurchill Khangar 				out_size, obj);
312575129cebSChurchill Khangar 			return;
312675129cebSChurchill Khangar 		}
312775129cebSChurchill Khangar 
312875129cebSChurchill Khangar 		if ((n_tokens >= 5) &&
312975129cebSChurchill Khangar 			(strcmp(tokens[2], "table") == 0) &&
313075129cebSChurchill Khangar 			(strcmp(tokens[4], "show") == 0)) {
313175129cebSChurchill Khangar 			cmd_pipeline_table_show(tokens, n_tokens, out,
313275129cebSChurchill Khangar 				out_size, obj);
313375129cebSChurchill Khangar 			return;
313475129cebSChurchill Khangar 		}
313575129cebSChurchill Khangar 
3136598fe0ddSCristian Dumitrescu 		if ((n_tokens >= 6) &&
3137598fe0ddSCristian Dumitrescu 			(strcmp(tokens[2], "selector") == 0) &&
3138598fe0ddSCristian Dumitrescu 			(strcmp(tokens[4], "group") == 0) &&
3139598fe0ddSCristian Dumitrescu 			(strcmp(tokens[5], "add") == 0)) {
3140598fe0ddSCristian Dumitrescu 			cmd_pipeline_selector_group_add(tokens, n_tokens, out,
3141598fe0ddSCristian Dumitrescu 				out_size, obj);
3142598fe0ddSCristian Dumitrescu 			return;
3143598fe0ddSCristian Dumitrescu 		}
3144598fe0ddSCristian Dumitrescu 
3145598fe0ddSCristian Dumitrescu 		if ((n_tokens >= 6) &&
3146598fe0ddSCristian Dumitrescu 			(strcmp(tokens[2], "selector") == 0) &&
3147598fe0ddSCristian Dumitrescu 			(strcmp(tokens[4], "group") == 0) &&
3148598fe0ddSCristian Dumitrescu 			(strcmp(tokens[5], "delete") == 0)) {
3149598fe0ddSCristian Dumitrescu 			cmd_pipeline_selector_group_delete(tokens, n_tokens, out,
3150598fe0ddSCristian Dumitrescu 				out_size, obj);
3151598fe0ddSCristian Dumitrescu 			return;
3152598fe0ddSCristian Dumitrescu 		}
3153598fe0ddSCristian Dumitrescu 
3154598fe0ddSCristian Dumitrescu 		if ((n_tokens >= 7) &&
3155598fe0ddSCristian Dumitrescu 			(strcmp(tokens[2], "selector") == 0) &&
3156598fe0ddSCristian Dumitrescu 			(strcmp(tokens[4], "group") == 0) &&
3157598fe0ddSCristian Dumitrescu 			(strcmp(tokens[5], "member") == 0) &&
3158598fe0ddSCristian Dumitrescu 			(strcmp(tokens[6], "add") == 0)) {
3159598fe0ddSCristian Dumitrescu 			cmd_pipeline_selector_group_member_add(tokens, n_tokens, out,
3160598fe0ddSCristian Dumitrescu 				out_size, obj);
3161598fe0ddSCristian Dumitrescu 			return;
3162598fe0ddSCristian Dumitrescu 		}
3163598fe0ddSCristian Dumitrescu 
3164598fe0ddSCristian Dumitrescu 		if ((n_tokens >= 7) &&
3165598fe0ddSCristian Dumitrescu 			(strcmp(tokens[2], "selector") == 0) &&
3166598fe0ddSCristian Dumitrescu 			(strcmp(tokens[4], "group") == 0) &&
3167598fe0ddSCristian Dumitrescu 			(strcmp(tokens[5], "member") == 0) &&
3168598fe0ddSCristian Dumitrescu 			(strcmp(tokens[6], "delete") == 0)) {
3169598fe0ddSCristian Dumitrescu 			cmd_pipeline_selector_group_member_delete(tokens, n_tokens, out,
3170598fe0ddSCristian Dumitrescu 				out_size, obj);
3171598fe0ddSCristian Dumitrescu 			return;
3172598fe0ddSCristian Dumitrescu 		}
3173598fe0ddSCristian Dumitrescu 
3174598fe0ddSCristian Dumitrescu 		if ((n_tokens >= 5) &&
3175598fe0ddSCristian Dumitrescu 			(strcmp(tokens[2], "selector") == 0) &&
3176598fe0ddSCristian Dumitrescu 			(strcmp(tokens[4], "show") == 0)) {
3177598fe0ddSCristian Dumitrescu 			cmd_pipeline_selector_show(tokens, n_tokens, out,
3178598fe0ddSCristian Dumitrescu 				out_size, obj);
3179598fe0ddSCristian Dumitrescu 			return;
3180598fe0ddSCristian Dumitrescu 		}
3181598fe0ddSCristian Dumitrescu 
31828bd4862fSCristian Dumitrescu 		if ((n_tokens >= 5) &&
31838bd4862fSCristian Dumitrescu 			(strcmp(tokens[2], "learner") == 0) &&
31848bd4862fSCristian Dumitrescu 			(strcmp(tokens[4], "default") == 0)) {
31858bd4862fSCristian Dumitrescu 			cmd_pipeline_learner_default(tokens, n_tokens, out,
31868bd4862fSCristian Dumitrescu 				out_size, obj);
31878bd4862fSCristian Dumitrescu 			return;
31888bd4862fSCristian Dumitrescu 		}
31898bd4862fSCristian Dumitrescu 
31905074e1d5SCristian Dumitrescu 		if ((n_tokens >= 3) &&
319175129cebSChurchill Khangar 			(strcmp(tokens[2], "commit") == 0)) {
319275129cebSChurchill Khangar 			cmd_pipeline_commit(tokens, n_tokens, out,
319375129cebSChurchill Khangar 				out_size, obj);
319475129cebSChurchill Khangar 			return;
319575129cebSChurchill Khangar 		}
319675129cebSChurchill Khangar 
319775129cebSChurchill Khangar 		if ((n_tokens >= 3) &&
319875129cebSChurchill Khangar 			(strcmp(tokens[2], "abort") == 0)) {
319975129cebSChurchill Khangar 			cmd_pipeline_abort(tokens, n_tokens, out,
32005074e1d5SCristian Dumitrescu 				out_size, obj);
32015074e1d5SCristian Dumitrescu 			return;
32025074e1d5SCristian Dumitrescu 		}
32035074e1d5SCristian Dumitrescu 
32045074e1d5SCristian Dumitrescu 		if ((n_tokens >= 3) &&
320564cfcebdSCristian Dumitrescu 			(strcmp(tokens[2], "regrd") == 0)) {
320664cfcebdSCristian Dumitrescu 			cmd_pipeline_regrd(tokens, n_tokens, out, out_size, obj);
320764cfcebdSCristian Dumitrescu 			return;
320864cfcebdSCristian Dumitrescu 		}
320964cfcebdSCristian Dumitrescu 
321064cfcebdSCristian Dumitrescu 		if ((n_tokens >= 3) &&
321164cfcebdSCristian Dumitrescu 			(strcmp(tokens[2], "regwr") == 0)) {
321264cfcebdSCristian Dumitrescu 			cmd_pipeline_regwr(tokens, n_tokens, out, out_size, obj);
321364cfcebdSCristian Dumitrescu 			return;
321464cfcebdSCristian Dumitrescu 		}
321564cfcebdSCristian Dumitrescu 
3216f38913b7SCristian Dumitrescu 		if ((n_tokens >= 6) &&
3217f38913b7SCristian Dumitrescu 			(strcmp(tokens[2], "meter") == 0) &&
3218f38913b7SCristian Dumitrescu 			(strcmp(tokens[3], "profile") == 0) &&
3219f38913b7SCristian Dumitrescu 			(strcmp(tokens[5], "add") == 0)) {
3220f38913b7SCristian Dumitrescu 			cmd_pipeline_meter_profile_add(tokens, n_tokens, out, out_size, obj);
3221f38913b7SCristian Dumitrescu 			return;
3222f38913b7SCristian Dumitrescu 		}
3223f38913b7SCristian Dumitrescu 
3224f38913b7SCristian Dumitrescu 		if ((n_tokens >= 6) &&
3225f38913b7SCristian Dumitrescu 			(strcmp(tokens[2], "meter") == 0) &&
3226f38913b7SCristian Dumitrescu 			(strcmp(tokens[3], "profile") == 0) &&
3227f38913b7SCristian Dumitrescu 			(strcmp(tokens[5], "delete") == 0)) {
3228f38913b7SCristian Dumitrescu 			cmd_pipeline_meter_profile_delete(tokens, n_tokens, out, out_size, obj);
3229f38913b7SCristian Dumitrescu 			return;
3230f38913b7SCristian Dumitrescu 		}
3231f38913b7SCristian Dumitrescu 
3232f38913b7SCristian Dumitrescu 		if ((n_tokens >= 9) &&
3233f38913b7SCristian Dumitrescu 			(strcmp(tokens[2], "meter") == 0) &&
3234f38913b7SCristian Dumitrescu 			(strcmp(tokens[8], "reset") == 0)) {
3235f38913b7SCristian Dumitrescu 			cmd_pipeline_meter_reset(tokens, n_tokens, out, out_size, obj);
3236f38913b7SCristian Dumitrescu 			return;
3237f38913b7SCristian Dumitrescu 		}
3238f38913b7SCristian Dumitrescu 
3239f38913b7SCristian Dumitrescu 		if ((n_tokens >= 9) &&
3240f38913b7SCristian Dumitrescu 			(strcmp(tokens[2], "meter") == 0) &&
3241f38913b7SCristian Dumitrescu 			(strcmp(tokens[8], "set") == 0)) {
3242f38913b7SCristian Dumitrescu 			cmd_pipeline_meter_set(tokens, n_tokens, out, out_size, obj);
3243f38913b7SCristian Dumitrescu 			return;
3244f38913b7SCristian Dumitrescu 		}
3245f38913b7SCristian Dumitrescu 
3246f38913b7SCristian Dumitrescu 		if ((n_tokens >= 9) &&
3247f38913b7SCristian Dumitrescu 			(strcmp(tokens[2], "meter") == 0) &&
3248f38913b7SCristian Dumitrescu 			(strcmp(tokens[8], "stats") == 0)) {
3249f38913b7SCristian Dumitrescu 			cmd_pipeline_meter_stats(tokens, n_tokens, out, out_size, obj);
3250f38913b7SCristian Dumitrescu 			return;
3251f38913b7SCristian Dumitrescu 		}
3252f38913b7SCristian Dumitrescu 
325364cfcebdSCristian Dumitrescu 		if ((n_tokens >= 3) &&
32545074e1d5SCristian Dumitrescu 			(strcmp(tokens[2], "stats") == 0)) {
32555074e1d5SCristian Dumitrescu 			cmd_pipeline_stats(tokens, n_tokens, out, out_size,
32565074e1d5SCristian Dumitrescu 				obj);
32575074e1d5SCristian Dumitrescu 			return;
32585074e1d5SCristian Dumitrescu 		}
325917225455SCristian Dumitrescu 
326017225455SCristian Dumitrescu 		if ((n_tokens >= 4) &&
326117225455SCristian Dumitrescu 			(strcmp(tokens[2], "mirror") == 0) &&
326217225455SCristian Dumitrescu 			(strcmp(tokens[3], "session") == 0)) {
326317225455SCristian Dumitrescu 			cmd_pipeline_mirror_session(tokens, n_tokens, out, out_size, obj);
326417225455SCristian Dumitrescu 			return;
326517225455SCristian Dumitrescu 		}
32665074e1d5SCristian Dumitrescu 	}
32675074e1d5SCristian Dumitrescu 
32685074e1d5SCristian Dumitrescu 	if (strcmp(tokens[0], "thread") == 0) {
32695074e1d5SCristian Dumitrescu 		if ((n_tokens >= 5) &&
32705074e1d5SCristian Dumitrescu 			(strcmp(tokens[4], "enable") == 0)) {
32715074e1d5SCristian Dumitrescu 			cmd_thread_pipeline_enable(tokens, n_tokens,
32725074e1d5SCristian Dumitrescu 				out, out_size, obj);
32735074e1d5SCristian Dumitrescu 			return;
32745074e1d5SCristian Dumitrescu 		}
32755074e1d5SCristian Dumitrescu 
32765074e1d5SCristian Dumitrescu 		if ((n_tokens >= 5) &&
32775074e1d5SCristian Dumitrescu 			(strcmp(tokens[4], "disable") == 0)) {
32785074e1d5SCristian Dumitrescu 			cmd_thread_pipeline_disable(tokens, n_tokens,
32795074e1d5SCristian Dumitrescu 				out, out_size, obj);
32805074e1d5SCristian Dumitrescu 			return;
32815074e1d5SCristian Dumitrescu 		}
32825074e1d5SCristian Dumitrescu 	}
32835074e1d5SCristian Dumitrescu 
32845074e1d5SCristian Dumitrescu 	snprintf(out, out_size, MSG_CMD_UNKNOWN, tokens[0]);
32855074e1d5SCristian Dumitrescu }
32865074e1d5SCristian Dumitrescu 
32875074e1d5SCristian Dumitrescu int
32885074e1d5SCristian Dumitrescu cli_script_process(const char *file_name,
32895074e1d5SCristian Dumitrescu 	size_t msg_in_len_max,
32905074e1d5SCristian Dumitrescu 	size_t msg_out_len_max,
32915074e1d5SCristian Dumitrescu 	void *obj)
32925074e1d5SCristian Dumitrescu {
32935074e1d5SCristian Dumitrescu 	char *msg_in = NULL, *msg_out = NULL;
32945074e1d5SCristian Dumitrescu 	FILE *f = NULL;
32955074e1d5SCristian Dumitrescu 
32965074e1d5SCristian Dumitrescu 	/* Check input arguments */
32975074e1d5SCristian Dumitrescu 	if ((file_name == NULL) ||
32985074e1d5SCristian Dumitrescu 		(strlen(file_name) == 0) ||
32995074e1d5SCristian Dumitrescu 		(msg_in_len_max == 0) ||
33005074e1d5SCristian Dumitrescu 		(msg_out_len_max == 0))
33015074e1d5SCristian Dumitrescu 		return -EINVAL;
33025074e1d5SCristian Dumitrescu 
33035074e1d5SCristian Dumitrescu 	msg_in = malloc(msg_in_len_max + 1);
33045074e1d5SCristian Dumitrescu 	msg_out = malloc(msg_out_len_max + 1);
33055074e1d5SCristian Dumitrescu 	if ((msg_in == NULL) ||
33065074e1d5SCristian Dumitrescu 		(msg_out == NULL)) {
33075074e1d5SCristian Dumitrescu 		free(msg_out);
33085074e1d5SCristian Dumitrescu 		free(msg_in);
33095074e1d5SCristian Dumitrescu 		return -ENOMEM;
33105074e1d5SCristian Dumitrescu 	}
33115074e1d5SCristian Dumitrescu 
33125074e1d5SCristian Dumitrescu 	/* Open input file */
33135074e1d5SCristian Dumitrescu 	f = fopen(file_name, "r");
33145074e1d5SCristian Dumitrescu 	if (f == NULL) {
33155074e1d5SCristian Dumitrescu 		free(msg_out);
33165074e1d5SCristian Dumitrescu 		free(msg_in);
33175074e1d5SCristian Dumitrescu 		return -EIO;
33185074e1d5SCristian Dumitrescu 	}
33195074e1d5SCristian Dumitrescu 
33205074e1d5SCristian Dumitrescu 	/* Read file */
33215074e1d5SCristian Dumitrescu 	for ( ; ; ) {
33225074e1d5SCristian Dumitrescu 		if (fgets(msg_in, msg_in_len_max + 1, f) == NULL)
33235074e1d5SCristian Dumitrescu 			break;
33245074e1d5SCristian Dumitrescu 
33255074e1d5SCristian Dumitrescu 		printf("%s", msg_in);
33265074e1d5SCristian Dumitrescu 		msg_out[0] = 0;
33275074e1d5SCristian Dumitrescu 
33285074e1d5SCristian Dumitrescu 		cli_process(msg_in,
33295074e1d5SCristian Dumitrescu 			msg_out,
33305074e1d5SCristian Dumitrescu 			msg_out_len_max,
33315074e1d5SCristian Dumitrescu 			obj);
33325074e1d5SCristian Dumitrescu 
33335074e1d5SCristian Dumitrescu 		if (strlen(msg_out))
33345074e1d5SCristian Dumitrescu 			printf("%s", msg_out);
33355074e1d5SCristian Dumitrescu 	}
33365074e1d5SCristian Dumitrescu 
33375074e1d5SCristian Dumitrescu 	/* Close file */
33385074e1d5SCristian Dumitrescu 	fclose(f);
33395074e1d5SCristian Dumitrescu 	free(msg_out);
33405074e1d5SCristian Dumitrescu 	free(msg_in);
33415074e1d5SCristian Dumitrescu 	return 0;
33425074e1d5SCristian Dumitrescu }
3343