xref: /dpdk/drivers/net/softnic/rte_eth_softnic_cli.c (revision 96893df75bf50a82cabd8debe3492d564a5d13d5)
131ce8d88SJasvinder Singh /* SPDX-License-Identifier: BSD-3-Clause
231ce8d88SJasvinder Singh  * Copyright(c) 2010-2018 Intel Corporation
331ce8d88SJasvinder Singh  */
431ce8d88SJasvinder Singh 
531ce8d88SJasvinder Singh #include <stdio.h>
631ce8d88SJasvinder Singh #include <stdint.h>
731ce8d88SJasvinder Singh #include <stdlib.h>
831ce8d88SJasvinder Singh #include <string.h>
902270033SCristian Dumitrescu #include <unistd.h>
1031ce8d88SJasvinder Singh 
11ee19326aSJasvinder Singh #include <rte_common.h>
12ee19326aSJasvinder Singh #include <rte_cycles.h>
13babdea59SFan Zhang #include <rte_string_fns.h>
14ee19326aSJasvinder Singh 
1531ce8d88SJasvinder Singh #include "rte_eth_softnic_internals.h"
1631ce8d88SJasvinder Singh 
1731ce8d88SJasvinder Singh #ifndef CMD_MAX_TOKENS
1831ce8d88SJasvinder Singh #define CMD_MAX_TOKENS     256
1931ce8d88SJasvinder Singh #endif
2031ce8d88SJasvinder Singh 
2102270033SCristian Dumitrescu #ifndef MAX_LINE_SIZE
2202270033SCristian Dumitrescu #define MAX_LINE_SIZE 2048
2302270033SCristian Dumitrescu #endif
2402270033SCristian Dumitrescu 
2531ce8d88SJasvinder Singh #define MSG_OUT_OF_MEMORY   "Not enough memory.\n"
2631ce8d88SJasvinder Singh #define MSG_CMD_UNKNOWN     "Unknown command \"%s\".\n"
2731ce8d88SJasvinder Singh #define MSG_CMD_UNIMPLEM    "Command \"%s\" not implemented.\n"
2831ce8d88SJasvinder Singh #define MSG_ARG_NOT_ENOUGH  "Not enough arguments for command \"%s\".\n"
2931ce8d88SJasvinder Singh #define MSG_ARG_TOO_MANY    "Too many arguments for command \"%s\".\n"
3031ce8d88SJasvinder Singh #define MSG_ARG_MISMATCH    "Wrong number of arguments for command \"%s\".\n"
3131ce8d88SJasvinder Singh #define MSG_ARG_NOT_FOUND   "Argument \"%s\" not found.\n"
3231ce8d88SJasvinder Singh #define MSG_ARG_INVALID     "Invalid value for argument \"%s\".\n"
3331ce8d88SJasvinder Singh #define MSG_FILE_ERR        "Error in file \"%s\" at line %u.\n"
3431ce8d88SJasvinder Singh #define MSG_FILE_NOT_ENOUGH "Not enough rules in file \"%s\".\n"
3531ce8d88SJasvinder Singh #define MSG_CMD_FAIL        "Command \"%s\" failed.\n"
3631ce8d88SJasvinder Singh 
3731ce8d88SJasvinder Singh static int
parser_read_uint64(uint64_t * value,char * p)38c7683010SCristian Dumitrescu parser_read_uint64(uint64_t *value, char *p)
39c7683010SCristian Dumitrescu {
40c7683010SCristian Dumitrescu 	uint64_t val = 0;
41c7683010SCristian Dumitrescu 
42c7683010SCristian Dumitrescu 	if (!value || !p || !p[0])
43c7683010SCristian Dumitrescu 		return -EINVAL;
44c7683010SCristian Dumitrescu 
45c7683010SCristian Dumitrescu 	val = strtoull(p, &p, 0);
46c7683010SCristian Dumitrescu 	if (p[0])
47c7683010SCristian Dumitrescu 		return -EINVAL;
48c7683010SCristian Dumitrescu 
49c7683010SCristian Dumitrescu 	*value = val;
50c7683010SCristian Dumitrescu 	return 0;
51c7683010SCristian Dumitrescu }
52c7683010SCristian Dumitrescu 
53c7683010SCristian Dumitrescu static int
parser_read_uint32(uint32_t * value,char * p)54d5854eb4SCristian Dumitrescu parser_read_uint32(uint32_t *value, char *p)
55d5854eb4SCristian Dumitrescu {
56d5854eb4SCristian Dumitrescu 	uint32_t val = 0;
57d5854eb4SCristian Dumitrescu 
58d5854eb4SCristian Dumitrescu 	if (!value || !p || !p[0])
59d5854eb4SCristian Dumitrescu 		return -EINVAL;
60d5854eb4SCristian Dumitrescu 
61d5854eb4SCristian Dumitrescu 	val = strtoul(p, &p, 0);
62d5854eb4SCristian Dumitrescu 	if (p[0])
63d5854eb4SCristian Dumitrescu 		return -EINVAL;
64d5854eb4SCristian Dumitrescu 
65d5854eb4SCristian Dumitrescu 	*value = val;
66d5854eb4SCristian Dumitrescu 	return 0;
67d5854eb4SCristian Dumitrescu }
68d5854eb4SCristian Dumitrescu 
69d5854eb4SCristian Dumitrescu #define PARSE_DELIMITER " \f\n\r\t\v"
70d5854eb4SCristian Dumitrescu 
71d5854eb4SCristian Dumitrescu static int
parse_tokenize_string(char * string,char * tokens[],uint32_t * n_tokens)72d5854eb4SCristian Dumitrescu parse_tokenize_string(char *string, char *tokens[], uint32_t *n_tokens)
73d5854eb4SCristian Dumitrescu {
74d5854eb4SCristian Dumitrescu 	uint32_t i;
75d5854eb4SCristian Dumitrescu 
76d5854eb4SCristian Dumitrescu 	if (!string || !tokens || !n_tokens || !*n_tokens)
77d5854eb4SCristian Dumitrescu 		return -EINVAL;
78d5854eb4SCristian Dumitrescu 
79d5854eb4SCristian Dumitrescu 	for (i = 0; i < *n_tokens; i++) {
80d5854eb4SCristian Dumitrescu 		tokens[i] = strtok_r(string, PARSE_DELIMITER, &string);
81d5854eb4SCristian Dumitrescu 		if (!tokens[i])
82d5854eb4SCristian Dumitrescu 			break;
83d5854eb4SCristian Dumitrescu 	}
84d5854eb4SCristian Dumitrescu 
85d5854eb4SCristian Dumitrescu 	if (i == *n_tokens && strtok_r(string, PARSE_DELIMITER, &string))
86d5854eb4SCristian Dumitrescu 		return -E2BIG;
87d5854eb4SCristian Dumitrescu 
88d5854eb4SCristian Dumitrescu 	*n_tokens = i;
89d5854eb4SCristian Dumitrescu 	return 0;
90d5854eb4SCristian Dumitrescu }
91d5854eb4SCristian Dumitrescu 
92d5854eb4SCristian Dumitrescu static int
is_comment(char * in)9331ce8d88SJasvinder Singh is_comment(char *in)
9431ce8d88SJasvinder Singh {
9531ce8d88SJasvinder Singh 	if ((strlen(in) && index("!#%;", in[0])) ||
9631ce8d88SJasvinder Singh 		(strncmp(in, "//", 2) == 0) ||
9731ce8d88SJasvinder Singh 		(strncmp(in, "--", 2) == 0))
9831ce8d88SJasvinder Singh 		return 1;
9931ce8d88SJasvinder Singh 
10031ce8d88SJasvinder Singh 	return 0;
10131ce8d88SJasvinder Singh }
10231ce8d88SJasvinder Singh 
103202905f3SJasvinder Singh /**
104202905f3SJasvinder Singh  * mempool <mempool_name>
105202905f3SJasvinder Singh  *  buffer <buffer_size>
106202905f3SJasvinder Singh  *  pool <pool_size>
107202905f3SJasvinder Singh  *  cache <cache_size>
108202905f3SJasvinder Singh  */
109202905f3SJasvinder Singh static void
cmd_mempool(struct pmd_internals * softnic,char ** tokens,uint32_t n_tokens,char * out,size_t out_size)110202905f3SJasvinder Singh cmd_mempool(struct pmd_internals *softnic,
111202905f3SJasvinder Singh 	char **tokens,
112202905f3SJasvinder Singh 	uint32_t n_tokens,
113202905f3SJasvinder Singh 	char *out,
114202905f3SJasvinder Singh 	size_t out_size)
115202905f3SJasvinder Singh {
116202905f3SJasvinder Singh 	struct softnic_mempool_params p;
117202905f3SJasvinder Singh 	char *name;
118202905f3SJasvinder Singh 	struct softnic_mempool *mempool;
119202905f3SJasvinder Singh 
120202905f3SJasvinder Singh 	if (n_tokens != 8) {
121202905f3SJasvinder Singh 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
122202905f3SJasvinder Singh 		return;
123202905f3SJasvinder Singh 	}
124202905f3SJasvinder Singh 
125202905f3SJasvinder Singh 	name = tokens[1];
126202905f3SJasvinder Singh 
127202905f3SJasvinder Singh 	if (strcmp(tokens[2], "buffer") != 0) {
128202905f3SJasvinder Singh 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "buffer");
129202905f3SJasvinder Singh 		return;
130202905f3SJasvinder Singh 	}
131202905f3SJasvinder Singh 
132d5854eb4SCristian Dumitrescu 	if (parser_read_uint32(&p.buffer_size, tokens[3]) != 0) {
133202905f3SJasvinder Singh 		snprintf(out, out_size, MSG_ARG_INVALID, "buffer_size");
134202905f3SJasvinder Singh 		return;
135202905f3SJasvinder Singh 	}
136202905f3SJasvinder Singh 
137202905f3SJasvinder Singh 	if (strcmp(tokens[4], "pool") != 0) {
138202905f3SJasvinder Singh 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pool");
139202905f3SJasvinder Singh 		return;
140202905f3SJasvinder Singh 	}
141202905f3SJasvinder Singh 
142d5854eb4SCristian Dumitrescu 	if (parser_read_uint32(&p.pool_size, tokens[5]) != 0) {
143202905f3SJasvinder Singh 		snprintf(out, out_size, MSG_ARG_INVALID, "pool_size");
144202905f3SJasvinder Singh 		return;
145202905f3SJasvinder Singh 	}
146202905f3SJasvinder Singh 
147202905f3SJasvinder Singh 	if (strcmp(tokens[6], "cache") != 0) {
148202905f3SJasvinder Singh 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cache");
149202905f3SJasvinder Singh 		return;
150202905f3SJasvinder Singh 	}
151202905f3SJasvinder Singh 
152d5854eb4SCristian Dumitrescu 	if (parser_read_uint32(&p.cache_size, tokens[7]) != 0) {
153202905f3SJasvinder Singh 		snprintf(out, out_size, MSG_ARG_INVALID, "cache_size");
154202905f3SJasvinder Singh 		return;
155202905f3SJasvinder Singh 	}
156202905f3SJasvinder Singh 
157202905f3SJasvinder Singh 	mempool = softnic_mempool_create(softnic, name, &p);
158202905f3SJasvinder Singh 	if (mempool == NULL) {
159202905f3SJasvinder Singh 		snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
160202905f3SJasvinder Singh 		return;
161202905f3SJasvinder Singh 	}
162202905f3SJasvinder Singh }
163202905f3SJasvinder Singh 
164202905f3SJasvinder Singh /**
165202905f3SJasvinder Singh  * swq <swq_name>
166202905f3SJasvinder Singh  *  size <size>
167202905f3SJasvinder Singh  */
168202905f3SJasvinder Singh static void
cmd_swq(struct pmd_internals * softnic,char ** tokens,uint32_t n_tokens,char * out,size_t out_size)169202905f3SJasvinder Singh cmd_swq(struct pmd_internals *softnic,
170202905f3SJasvinder Singh 	char **tokens,
171202905f3SJasvinder Singh 	uint32_t n_tokens,
172202905f3SJasvinder Singh 	char *out,
173202905f3SJasvinder Singh 	size_t out_size)
174202905f3SJasvinder Singh {
175202905f3SJasvinder Singh 	struct softnic_swq_params p;
176202905f3SJasvinder Singh 	char *name;
177202905f3SJasvinder Singh 	struct softnic_swq *swq;
178202905f3SJasvinder Singh 
179202905f3SJasvinder Singh 	if (n_tokens != 4) {
180202905f3SJasvinder Singh 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
181202905f3SJasvinder Singh 		return;
182202905f3SJasvinder Singh 	}
183202905f3SJasvinder Singh 
184202905f3SJasvinder Singh 	name = tokens[1];
185202905f3SJasvinder Singh 
186202905f3SJasvinder Singh 	if (strcmp(tokens[2], "size") != 0) {
187202905f3SJasvinder Singh 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "size");
188202905f3SJasvinder Singh 		return;
189202905f3SJasvinder Singh 	}
190202905f3SJasvinder Singh 
191d5854eb4SCristian Dumitrescu 	if (parser_read_uint32(&p.size, tokens[3]) != 0) {
192202905f3SJasvinder Singh 		snprintf(out, out_size, MSG_ARG_INVALID, "size");
193202905f3SJasvinder Singh 		return;
194202905f3SJasvinder Singh 	}
195202905f3SJasvinder Singh 
196202905f3SJasvinder Singh 	swq = softnic_swq_create(softnic, name, &p);
197202905f3SJasvinder Singh 	if (swq == NULL) {
198202905f3SJasvinder Singh 		snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
199202905f3SJasvinder Singh 		return;
200202905f3SJasvinder Singh 	}
201202905f3SJasvinder Singh }
202202905f3SJasvinder Singh 
203202905f3SJasvinder Singh /**
204e3be2495SCristian Dumitrescu  * pipeline codegen <spec_file> <code_file>
205e3be2495SCristian Dumitrescu  */
206e3be2495SCristian Dumitrescu static void
cmd_softnic_pipeline_codegen(struct pmd_internals * softnic __rte_unused,char ** tokens,uint32_t n_tokens,char * out,size_t out_size)207e3be2495SCristian Dumitrescu cmd_softnic_pipeline_codegen(struct pmd_internals *softnic __rte_unused,
208e3be2495SCristian Dumitrescu 	char **tokens,
209e3be2495SCristian Dumitrescu 	uint32_t n_tokens,
210e3be2495SCristian Dumitrescu 	char *out,
211e3be2495SCristian Dumitrescu 	size_t out_size)
212e3be2495SCristian Dumitrescu {
213e3be2495SCristian Dumitrescu 	FILE *spec_file = NULL;
214e3be2495SCristian Dumitrescu 	FILE *code_file = NULL;
215e3be2495SCristian Dumitrescu 	uint32_t err_line;
216e3be2495SCristian Dumitrescu 	const char *err_msg;
217e3be2495SCristian Dumitrescu 	int status;
218e3be2495SCristian Dumitrescu 
219e3be2495SCristian Dumitrescu 	if (n_tokens != 4) {
220e3be2495SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
221e3be2495SCristian Dumitrescu 		return;
222e3be2495SCristian Dumitrescu 	}
223e3be2495SCristian Dumitrescu 
224e3be2495SCristian Dumitrescu 	spec_file = fopen(tokens[2], "r");
225e3be2495SCristian Dumitrescu 	if (!spec_file) {
226e3be2495SCristian Dumitrescu 		snprintf(out, out_size, "Cannot open file %s.\n", tokens[2]);
227e3be2495SCristian Dumitrescu 		return;
228e3be2495SCristian Dumitrescu 	}
229e3be2495SCristian Dumitrescu 
230e3be2495SCristian Dumitrescu 	code_file = fopen(tokens[3], "w");
231e3be2495SCristian Dumitrescu 	if (!code_file) {
232e3be2495SCristian Dumitrescu 		snprintf(out, out_size, "Cannot open file %s.\n", tokens[3]);
233357d87e8SHarshad Narayane 		fclose(spec_file);
234e3be2495SCristian Dumitrescu 		return;
235e3be2495SCristian Dumitrescu 	}
236e3be2495SCristian Dumitrescu 
237e3be2495SCristian Dumitrescu 	status = rte_swx_pipeline_codegen(spec_file,
238e3be2495SCristian Dumitrescu 					  code_file,
239e3be2495SCristian Dumitrescu 					  &err_line,
240e3be2495SCristian Dumitrescu 					  &err_msg);
241e3be2495SCristian Dumitrescu 
242e3be2495SCristian Dumitrescu 	fclose(spec_file);
243e3be2495SCristian Dumitrescu 	fclose(code_file);
244e3be2495SCristian Dumitrescu 
245e3be2495SCristian Dumitrescu 	if (status) {
246e3be2495SCristian Dumitrescu 		snprintf(out, out_size, "Error %d at line %u: %s\n.",
247e3be2495SCristian Dumitrescu 			status, err_line, err_msg);
248e3be2495SCristian Dumitrescu 		return;
249e3be2495SCristian Dumitrescu 	}
250e3be2495SCristian Dumitrescu }
251e3be2495SCristian Dumitrescu 
252e3be2495SCristian Dumitrescu /**
25302270033SCristian Dumitrescu  * pipeline libbuild <code_file> <lib_file>
25402270033SCristian Dumitrescu  */
25502270033SCristian Dumitrescu static void
cmd_softnic_pipeline_libbuild(struct pmd_internals * softnic __rte_unused,char ** tokens,uint32_t n_tokens,char * out,size_t out_size)25602270033SCristian Dumitrescu cmd_softnic_pipeline_libbuild(struct pmd_internals *softnic __rte_unused,
25702270033SCristian Dumitrescu 	char **tokens,
25802270033SCristian Dumitrescu 	uint32_t n_tokens,
25902270033SCristian Dumitrescu 	char *out,
26002270033SCristian Dumitrescu 	size_t out_size)
26102270033SCristian Dumitrescu {
26202270033SCristian Dumitrescu 	char *code_file, *lib_file, *obj_file = NULL, *log_file = NULL;
26302270033SCristian Dumitrescu 	char *install_dir, *cwd = NULL, *buffer = NULL;
26402270033SCristian Dumitrescu 	size_t length;
26502270033SCristian Dumitrescu 	int status = 0;
26602270033SCristian Dumitrescu 
26702270033SCristian Dumitrescu 	if (n_tokens != 4) {
26802270033SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
26902270033SCristian Dumitrescu 		goto free;
27002270033SCristian Dumitrescu 	}
27102270033SCristian Dumitrescu 
27202270033SCristian Dumitrescu 	install_dir = getenv("RTE_INSTALL_DIR");
27302270033SCristian Dumitrescu 	if (!install_dir) {
27402270033SCristian Dumitrescu 		cwd = malloc(MAX_LINE_SIZE);
27502270033SCristian Dumitrescu 		if (!cwd) {
27602270033SCristian Dumitrescu 			snprintf(out, out_size, MSG_OUT_OF_MEMORY);
27702270033SCristian Dumitrescu 			goto free;
27802270033SCristian Dumitrescu 		}
27902270033SCristian Dumitrescu 
28002270033SCristian Dumitrescu 		install_dir = getcwd(cwd, MAX_LINE_SIZE);
28102270033SCristian Dumitrescu 		if (!install_dir) {
28202270033SCristian Dumitrescu 			snprintf(out, out_size, "Error: Path too long.\n");
28302270033SCristian Dumitrescu 			goto free;
28402270033SCristian Dumitrescu 		}
28502270033SCristian Dumitrescu 	}
28602270033SCristian Dumitrescu 
28702270033SCristian Dumitrescu 	snprintf(out, out_size, "Using DPDK source code from \"%s\".\n", install_dir);
28802270033SCristian Dumitrescu 	out_size -= strlen(out);
28902270033SCristian Dumitrescu 	out += strlen(out);
29002270033SCristian Dumitrescu 
29102270033SCristian Dumitrescu 	code_file = tokens[2];
29202270033SCristian Dumitrescu 	length = strnlen(code_file, MAX_LINE_SIZE);
29302270033SCristian Dumitrescu 	if (length < 3 ||
29402270033SCristian Dumitrescu 	    code_file[length - 2] != '.' ||
29502270033SCristian Dumitrescu 	    code_file[length - 1] != 'c') {
29602270033SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "code_file");
29702270033SCristian Dumitrescu 		goto free;
29802270033SCristian Dumitrescu 	}
29902270033SCristian Dumitrescu 
30002270033SCristian Dumitrescu 	lib_file = tokens[3];
30102270033SCristian Dumitrescu 	length = strnlen(lib_file, MAX_LINE_SIZE);
30202270033SCristian Dumitrescu 	if (length < 4 ||
30302270033SCristian Dumitrescu 	    lib_file[length - 3] != '.' ||
30402270033SCristian Dumitrescu 	    lib_file[length - 2] != 's' ||
30502270033SCristian Dumitrescu 	    lib_file[length - 1] != 'o') {
30602270033SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "lib_file");
30702270033SCristian Dumitrescu 		goto free;
30802270033SCristian Dumitrescu 	}
30902270033SCristian Dumitrescu 
31002270033SCristian Dumitrescu 	obj_file = malloc(length);
31102270033SCristian Dumitrescu 	log_file = malloc(length + 2);
31202270033SCristian Dumitrescu 	if (!obj_file || !log_file) {
31302270033SCristian Dumitrescu 		snprintf(out, out_size, MSG_OUT_OF_MEMORY);
31402270033SCristian Dumitrescu 		goto free;
31502270033SCristian Dumitrescu 	}
31602270033SCristian Dumitrescu 
31702270033SCristian Dumitrescu 	memcpy(obj_file, lib_file, length - 2);
31802270033SCristian Dumitrescu 	obj_file[length - 2] = 'o';
31902270033SCristian Dumitrescu 	obj_file[length - 1] = 0;
32002270033SCristian Dumitrescu 
32102270033SCristian Dumitrescu 	memcpy(log_file, lib_file, length - 2);
32202270033SCristian Dumitrescu 	log_file[length - 2] = 'l';
32302270033SCristian Dumitrescu 	log_file[length - 1] = 'o';
32402270033SCristian Dumitrescu 	log_file[length] = 'g';
32502270033SCristian Dumitrescu 	log_file[length + 1] = 0;
32602270033SCristian Dumitrescu 
32702270033SCristian Dumitrescu 	buffer = malloc(MAX_LINE_SIZE);
32802270033SCristian Dumitrescu 	if (!buffer) {
32902270033SCristian Dumitrescu 		snprintf(out, out_size, MSG_OUT_OF_MEMORY);
330167756c1SHarshad Narayane 		goto free;
33102270033SCristian Dumitrescu 	}
33202270033SCristian Dumitrescu 
33302270033SCristian Dumitrescu 	snprintf(buffer,
33402270033SCristian Dumitrescu 		 MAX_LINE_SIZE,
33502270033SCristian Dumitrescu 		 "gcc -c -O3 -fpic -Wno-deprecated-declarations -o %s %s "
33602270033SCristian Dumitrescu 		 "-I %s/lib/pipeline "
33702270033SCristian Dumitrescu 		 "-I %s/lib/eal/include "
33802270033SCristian Dumitrescu 		 "-I %s/lib/eal/x86/include "
33902270033SCristian Dumitrescu 		 "-I %s/lib/eal/include/generic "
340*96893df7SCristian Dumitrescu 		 "-I %s/lib/log "
34102270033SCristian Dumitrescu 		 "-I %s/lib/meter "
34202270033SCristian Dumitrescu 		 "-I %s/lib/port "
34302270033SCristian Dumitrescu 		 "-I %s/lib/table "
34402270033SCristian Dumitrescu 		 "-I %s/lib/pipeline "
34502270033SCristian Dumitrescu 		 "-I %s/config "
34602270033SCristian Dumitrescu 		 "-I %s/build "
34702270033SCristian Dumitrescu 		 "-I %s/lib/eal/linux/include "
34802270033SCristian Dumitrescu 		 ">%s 2>&1 "
34902270033SCristian Dumitrescu 		 "&& "
35002270033SCristian Dumitrescu 		 "gcc -shared %s -o %s "
35102270033SCristian Dumitrescu 		 ">>%s 2>&1",
35202270033SCristian Dumitrescu 		 obj_file,
35302270033SCristian Dumitrescu 		 code_file,
35402270033SCristian Dumitrescu 		 install_dir,
35502270033SCristian Dumitrescu 		 install_dir,
35602270033SCristian Dumitrescu 		 install_dir,
35702270033SCristian Dumitrescu 		 install_dir,
35802270033SCristian Dumitrescu 		 install_dir,
35902270033SCristian Dumitrescu 		 install_dir,
36002270033SCristian Dumitrescu 		 install_dir,
36102270033SCristian Dumitrescu 		 install_dir,
36202270033SCristian Dumitrescu 		 install_dir,
36302270033SCristian Dumitrescu 		 install_dir,
36402270033SCristian Dumitrescu 		 install_dir,
365*96893df7SCristian Dumitrescu 		 install_dir,
36602270033SCristian Dumitrescu 		 log_file,
36702270033SCristian Dumitrescu 		 obj_file,
36802270033SCristian Dumitrescu 		 lib_file,
36902270033SCristian Dumitrescu 		 log_file);
37002270033SCristian Dumitrescu 
37102270033SCristian Dumitrescu 	status = system(buffer);
37202270033SCristian Dumitrescu 	if (status) {
37302270033SCristian Dumitrescu 		snprintf(out,
37402270033SCristian Dumitrescu 			 out_size,
37502270033SCristian Dumitrescu 			 "Library build failed, see file \"%s\" for details.\n",
37602270033SCristian Dumitrescu 			 log_file);
37702270033SCristian Dumitrescu 		goto free;
37802270033SCristian Dumitrescu 	}
37902270033SCristian Dumitrescu 
38002270033SCristian Dumitrescu free:
38102270033SCristian Dumitrescu 	free(cwd);
38202270033SCristian Dumitrescu 	free(obj_file);
38302270033SCristian Dumitrescu 	free(log_file);
38402270033SCristian Dumitrescu 	free(buffer);
38502270033SCristian Dumitrescu }
38602270033SCristian Dumitrescu 
38702270033SCristian Dumitrescu /**
38800dfff03SCristian Dumitrescu  * pipeline <pipeline_name> build lib <lib_file> io <iospec_file> numa <numa_node>
38900dfff03SCristian Dumitrescu  */
39000dfff03SCristian Dumitrescu static void
cmd_softnic_pipeline_build(struct pmd_internals * softnic,char ** tokens,uint32_t n_tokens,char * out,size_t out_size)39100dfff03SCristian Dumitrescu cmd_softnic_pipeline_build(struct pmd_internals *softnic,
39200dfff03SCristian Dumitrescu 	char **tokens,
39300dfff03SCristian Dumitrescu 	uint32_t n_tokens,
39400dfff03SCristian Dumitrescu 	char *out,
39500dfff03SCristian Dumitrescu 	size_t out_size)
39600dfff03SCristian Dumitrescu {
39700dfff03SCristian Dumitrescu 	struct pipeline *p = NULL;
39800dfff03SCristian Dumitrescu 	char *pipeline_name, *lib_file_name, *iospec_file_name;
39900dfff03SCristian Dumitrescu 	uint32_t numa_node = 0;
40000dfff03SCristian Dumitrescu 
40100dfff03SCristian Dumitrescu 	/* Parsing. */
40200dfff03SCristian Dumitrescu 	if (n_tokens != 9) {
40300dfff03SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
40400dfff03SCristian Dumitrescu 		return;
40500dfff03SCristian Dumitrescu 	}
40600dfff03SCristian Dumitrescu 
40700dfff03SCristian Dumitrescu 	pipeline_name = tokens[1];
40800dfff03SCristian Dumitrescu 
40900dfff03SCristian Dumitrescu 	if (strcmp(tokens[2], "build")) {
41000dfff03SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "build");
41100dfff03SCristian Dumitrescu 		return;
41200dfff03SCristian Dumitrescu 	}
41300dfff03SCristian Dumitrescu 
41400dfff03SCristian Dumitrescu 	if (strcmp(tokens[3], "lib")) {
41500dfff03SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "lib");
41600dfff03SCristian Dumitrescu 		return;
41700dfff03SCristian Dumitrescu 	}
41800dfff03SCristian Dumitrescu 
41900dfff03SCristian Dumitrescu 	lib_file_name = tokens[4];
42000dfff03SCristian Dumitrescu 
42100dfff03SCristian Dumitrescu 	if (strcmp(tokens[5], "io")) {
42200dfff03SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "io");
42300dfff03SCristian Dumitrescu 		return;
42400dfff03SCristian Dumitrescu 	}
42500dfff03SCristian Dumitrescu 
42600dfff03SCristian Dumitrescu 	iospec_file_name = tokens[6];
42700dfff03SCristian Dumitrescu 
42800dfff03SCristian Dumitrescu 	if (strcmp(tokens[7], "numa")) {
42900dfff03SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "numa");
43000dfff03SCristian Dumitrescu 		return;
43100dfff03SCristian Dumitrescu 	}
43200dfff03SCristian Dumitrescu 
43300dfff03SCristian Dumitrescu 	if (parser_read_uint32(&numa_node, tokens[8])) {
43400dfff03SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "numa_node");
43500dfff03SCristian Dumitrescu 		return;
43600dfff03SCristian Dumitrescu 	}
43700dfff03SCristian Dumitrescu 
43800dfff03SCristian Dumitrescu 	/* Pipeline create. */
43900dfff03SCristian Dumitrescu 	p = softnic_pipeline_create(softnic,
44000dfff03SCristian Dumitrescu 				    pipeline_name,
44100dfff03SCristian Dumitrescu 				    lib_file_name,
44200dfff03SCristian Dumitrescu 				    iospec_file_name,
44300dfff03SCristian Dumitrescu 				    (int)numa_node);
44400dfff03SCristian Dumitrescu 	if (!p)
44500dfff03SCristian Dumitrescu 		snprintf(out, out_size, "Pipeline creation failed.\n");
44600dfff03SCristian Dumitrescu }
44700dfff03SCristian Dumitrescu 
448d8141864SCristian Dumitrescu static void
table_entry_free(struct rte_swx_table_entry * entry)449d8141864SCristian Dumitrescu table_entry_free(struct rte_swx_table_entry *entry)
450d8141864SCristian Dumitrescu {
451d8141864SCristian Dumitrescu 	if (!entry)
452d8141864SCristian Dumitrescu 		return;
453d8141864SCristian Dumitrescu 
454d8141864SCristian Dumitrescu 	free(entry->key);
455d8141864SCristian Dumitrescu 	free(entry->key_mask);
456d8141864SCristian Dumitrescu 	free(entry->action_data);
457d8141864SCristian Dumitrescu 	free(entry);
458d8141864SCristian Dumitrescu }
459d8141864SCristian Dumitrescu 
460d8141864SCristian Dumitrescu static int
pipeline_table_entries_add(struct rte_swx_ctl_pipeline * p,const char * table_name,FILE * file,uint32_t * file_line_number)461d8141864SCristian Dumitrescu pipeline_table_entries_add(struct rte_swx_ctl_pipeline *p,
462d8141864SCristian Dumitrescu 			   const char *table_name,
463d8141864SCristian Dumitrescu 			   FILE *file,
464d8141864SCristian Dumitrescu 			   uint32_t *file_line_number)
465d8141864SCristian Dumitrescu {
466d8141864SCristian Dumitrescu 	char *line = NULL;
467d8141864SCristian Dumitrescu 	uint32_t line_id = 0;
468d8141864SCristian Dumitrescu 	int status = 0;
469d8141864SCristian Dumitrescu 
470d8141864SCristian Dumitrescu 	/* Buffer allocation. */
471d8141864SCristian Dumitrescu 	line = malloc(MAX_LINE_SIZE);
472d8141864SCristian Dumitrescu 	if (!line)
473d8141864SCristian Dumitrescu 		return -ENOMEM;
474d8141864SCristian Dumitrescu 
475d8141864SCristian Dumitrescu 	/* File read. */
476d8141864SCristian Dumitrescu 	for (line_id = 1; ; line_id++) {
477d8141864SCristian Dumitrescu 		struct rte_swx_table_entry *entry;
478d8141864SCristian Dumitrescu 		int is_blank_or_comment;
479d8141864SCristian Dumitrescu 
480d8141864SCristian Dumitrescu 		if (fgets(line, MAX_LINE_SIZE, file) == NULL)
481d8141864SCristian Dumitrescu 			break;
482d8141864SCristian Dumitrescu 
483d8141864SCristian Dumitrescu 		entry = rte_swx_ctl_pipeline_table_entry_read(p,
484d8141864SCristian Dumitrescu 							      table_name,
485d8141864SCristian Dumitrescu 							      line,
486d8141864SCristian Dumitrescu 							      &is_blank_or_comment);
487d8141864SCristian Dumitrescu 		if (!entry) {
488d8141864SCristian Dumitrescu 			if (is_blank_or_comment)
489d8141864SCristian Dumitrescu 				continue;
490d8141864SCristian Dumitrescu 
491d8141864SCristian Dumitrescu 			status = -EINVAL;
492d8141864SCristian Dumitrescu 			goto error;
493d8141864SCristian Dumitrescu 		}
494d8141864SCristian Dumitrescu 
495d8141864SCristian Dumitrescu 		status = rte_swx_ctl_pipeline_table_entry_add(p,
496d8141864SCristian Dumitrescu 							      table_name,
497d8141864SCristian Dumitrescu 							      entry);
498d8141864SCristian Dumitrescu 		table_entry_free(entry);
499d8141864SCristian Dumitrescu 		if (status)
500d8141864SCristian Dumitrescu 			goto error;
501d8141864SCristian Dumitrescu 	}
502d8141864SCristian Dumitrescu 
503d8141864SCristian Dumitrescu error:
504d8141864SCristian Dumitrescu 	free(line);
505d8141864SCristian Dumitrescu 	*file_line_number = line_id;
506d8141864SCristian Dumitrescu 	return status;
507d8141864SCristian Dumitrescu }
508d8141864SCristian Dumitrescu 
509d8141864SCristian Dumitrescu /**
510d8141864SCristian Dumitrescu  * pipeline <pipeline_name> table <table_name> add <file_name>
511d8141864SCristian Dumitrescu  */
512d8141864SCristian Dumitrescu static void
cmd_softnic_pipeline_table_add(struct pmd_internals * softnic,char ** tokens,uint32_t n_tokens,char * out,size_t out_size)513d8141864SCristian Dumitrescu cmd_softnic_pipeline_table_add(struct pmd_internals *softnic,
514d8141864SCristian Dumitrescu 	char **tokens,
515d8141864SCristian Dumitrescu 	uint32_t n_tokens,
516d8141864SCristian Dumitrescu 	char *out,
517d8141864SCristian Dumitrescu 	size_t out_size)
518d8141864SCristian Dumitrescu {
519d8141864SCristian Dumitrescu 	struct pipeline *p;
520d8141864SCristian Dumitrescu 	char *pipeline_name, *table_name, *file_name;
521d8141864SCristian Dumitrescu 	FILE *file = NULL;
522d8141864SCristian Dumitrescu 	uint32_t file_line_number = 0;
523d8141864SCristian Dumitrescu 	int status;
524d8141864SCristian Dumitrescu 
525d8141864SCristian Dumitrescu 	if (n_tokens != 6) {
526d8141864SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
527d8141864SCristian Dumitrescu 		return;
528d8141864SCristian Dumitrescu 	}
529d8141864SCristian Dumitrescu 
530d8141864SCristian Dumitrescu 	pipeline_name = tokens[1];
531d8141864SCristian Dumitrescu 	p = softnic_pipeline_find(softnic, pipeline_name);
532d8141864SCristian Dumitrescu 	if (!p) {
533d8141864SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
534d8141864SCristian Dumitrescu 		return;
535d8141864SCristian Dumitrescu 	}
536d8141864SCristian Dumitrescu 
537d8141864SCristian Dumitrescu 	table_name = tokens[3];
538d8141864SCristian Dumitrescu 
539d8141864SCristian Dumitrescu 	file_name = tokens[5];
540d8141864SCristian Dumitrescu 	file = fopen(file_name, "r");
541d8141864SCristian Dumitrescu 	if (!file) {
542d8141864SCristian Dumitrescu 		snprintf(out, out_size, "Cannot open file %s.\n", file_name);
543d8141864SCristian Dumitrescu 		return;
544d8141864SCristian Dumitrescu 	}
545d8141864SCristian Dumitrescu 
546d8141864SCristian Dumitrescu 	status = pipeline_table_entries_add(p->ctl,
547d8141864SCristian Dumitrescu 					    table_name,
548d8141864SCristian Dumitrescu 					    file,
549d8141864SCristian Dumitrescu 					    &file_line_number);
550d8141864SCristian Dumitrescu 	if (status)
551d8141864SCristian Dumitrescu 		snprintf(out, out_size, "Invalid entry in file %s at line %u\n",
552d8141864SCristian Dumitrescu 			 file_name,
553d8141864SCristian Dumitrescu 			 file_line_number);
554d8141864SCristian Dumitrescu 
555d8141864SCristian Dumitrescu 	fclose(file);
556d8141864SCristian Dumitrescu }
557d8141864SCristian Dumitrescu 
558d8141864SCristian Dumitrescu static int
pipeline_table_entries_delete(struct rte_swx_ctl_pipeline * p,const char * table_name,FILE * file,uint32_t * file_line_number)559d8141864SCristian Dumitrescu pipeline_table_entries_delete(struct rte_swx_ctl_pipeline *p,
560d8141864SCristian Dumitrescu 			      const char *table_name,
561d8141864SCristian Dumitrescu 			      FILE *file,
562d8141864SCristian Dumitrescu 			      uint32_t *file_line_number)
563d8141864SCristian Dumitrescu {
564d8141864SCristian Dumitrescu 	char *line = NULL;
565d8141864SCristian Dumitrescu 	uint32_t line_id = 0;
566d8141864SCristian Dumitrescu 	int status = 0;
567d8141864SCristian Dumitrescu 
568d8141864SCristian Dumitrescu 	/* Buffer allocation. */
569d8141864SCristian Dumitrescu 	line = malloc(MAX_LINE_SIZE);
570d8141864SCristian Dumitrescu 	if (!line)
571d8141864SCristian Dumitrescu 		return -ENOMEM;
572d8141864SCristian Dumitrescu 
573d8141864SCristian Dumitrescu 	/* File read. */
574d8141864SCristian Dumitrescu 	for (line_id = 1; ; line_id++) {
575d8141864SCristian Dumitrescu 		struct rte_swx_table_entry *entry;
576d8141864SCristian Dumitrescu 		int is_blank_or_comment;
577d8141864SCristian Dumitrescu 
578d8141864SCristian Dumitrescu 		if (fgets(line, MAX_LINE_SIZE, file) == NULL)
579d8141864SCristian Dumitrescu 			break;
580d8141864SCristian Dumitrescu 
581d8141864SCristian Dumitrescu 		entry = rte_swx_ctl_pipeline_table_entry_read(p,
582d8141864SCristian Dumitrescu 							      table_name,
583d8141864SCristian Dumitrescu 							      line,
584d8141864SCristian Dumitrescu 							      &is_blank_or_comment);
585d8141864SCristian Dumitrescu 		if (!entry) {
586d8141864SCristian Dumitrescu 			if (is_blank_or_comment)
587d8141864SCristian Dumitrescu 				continue;
588d8141864SCristian Dumitrescu 
589d8141864SCristian Dumitrescu 			status = -EINVAL;
590d8141864SCristian Dumitrescu 			goto error;
591d8141864SCristian Dumitrescu 		}
592d8141864SCristian Dumitrescu 
593d8141864SCristian Dumitrescu 		status = rte_swx_ctl_pipeline_table_entry_delete(p,
594d8141864SCristian Dumitrescu 								 table_name,
595d8141864SCristian Dumitrescu 								 entry);
596d8141864SCristian Dumitrescu 		table_entry_free(entry);
597d8141864SCristian Dumitrescu 		if (status)
598d8141864SCristian Dumitrescu 			goto error;
599d8141864SCristian Dumitrescu 	}
600d8141864SCristian Dumitrescu 
601d8141864SCristian Dumitrescu error:
602d8141864SCristian Dumitrescu 	*file_line_number = line_id;
603d8141864SCristian Dumitrescu 	free(line);
604d8141864SCristian Dumitrescu 	return status;
605d8141864SCristian Dumitrescu }
606d8141864SCristian Dumitrescu 
607d8141864SCristian Dumitrescu /**
608d8141864SCristian Dumitrescu  * pipeline <pipeline_name> table <table_name> delete <file_name>
609d8141864SCristian Dumitrescu  */
610d8141864SCristian Dumitrescu static void
cmd_softnic_pipeline_table_delete(struct pmd_internals * softnic,char ** tokens,uint32_t n_tokens,char * out,size_t out_size)611d8141864SCristian Dumitrescu cmd_softnic_pipeline_table_delete(struct pmd_internals *softnic,
612d8141864SCristian Dumitrescu 	char **tokens,
613d8141864SCristian Dumitrescu 	uint32_t n_tokens,
614d8141864SCristian Dumitrescu 	char *out,
615d8141864SCristian Dumitrescu 	size_t out_size)
616d8141864SCristian Dumitrescu {
617d8141864SCristian Dumitrescu 	struct pipeline *p;
618d8141864SCristian Dumitrescu 	char *pipeline_name, *table_name, *file_name;
619d8141864SCristian Dumitrescu 	FILE *file = NULL;
620d8141864SCristian Dumitrescu 	uint32_t file_line_number = 0;
621d8141864SCristian Dumitrescu 	int status;
622d8141864SCristian Dumitrescu 
623d8141864SCristian Dumitrescu 	if (n_tokens != 6) {
624d8141864SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
625d8141864SCristian Dumitrescu 		return;
626d8141864SCristian Dumitrescu 	}
627d8141864SCristian Dumitrescu 
628d8141864SCristian Dumitrescu 	pipeline_name = tokens[1];
629d8141864SCristian Dumitrescu 	p = softnic_pipeline_find(softnic, pipeline_name);
630d8141864SCristian Dumitrescu 	if (!p) {
631d8141864SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
632d8141864SCristian Dumitrescu 		return;
633d8141864SCristian Dumitrescu 	}
634d8141864SCristian Dumitrescu 
635d8141864SCristian Dumitrescu 	table_name = tokens[3];
636d8141864SCristian Dumitrescu 
637d8141864SCristian Dumitrescu 	file_name = tokens[5];
638d8141864SCristian Dumitrescu 	file = fopen(file_name, "r");
639d8141864SCristian Dumitrescu 	if (!file) {
640d8141864SCristian Dumitrescu 		snprintf(out, out_size, "Cannot open file %s.\n", file_name);
641d8141864SCristian Dumitrescu 		return;
642d8141864SCristian Dumitrescu 	}
643d8141864SCristian Dumitrescu 
644d8141864SCristian Dumitrescu 	status = pipeline_table_entries_delete(p->ctl,
645d8141864SCristian Dumitrescu 					       table_name,
646d8141864SCristian Dumitrescu 					       file,
647d8141864SCristian Dumitrescu 					       &file_line_number);
648d8141864SCristian Dumitrescu 	if (status)
649d8141864SCristian Dumitrescu 		snprintf(out, out_size, "Invalid entry in file %s at line %u\n",
650d8141864SCristian Dumitrescu 			 file_name,
651d8141864SCristian Dumitrescu 			 file_line_number);
652d8141864SCristian Dumitrescu 
653d8141864SCristian Dumitrescu 	fclose(file);
654d8141864SCristian Dumitrescu }
655d8141864SCristian Dumitrescu 
656d8141864SCristian Dumitrescu static int
pipeline_table_default_entry_add(struct rte_swx_ctl_pipeline * p,const char * table_name,FILE * file,uint32_t * file_line_number)657d8141864SCristian Dumitrescu pipeline_table_default_entry_add(struct rte_swx_ctl_pipeline *p,
658d8141864SCristian Dumitrescu 				 const char *table_name,
659d8141864SCristian Dumitrescu 				 FILE *file,
660d8141864SCristian Dumitrescu 				 uint32_t *file_line_number)
661d8141864SCristian Dumitrescu {
662d8141864SCristian Dumitrescu 	char *line = NULL;
663d8141864SCristian Dumitrescu 	uint32_t line_id = 0;
664d8141864SCristian Dumitrescu 	int status = 0;
665d8141864SCristian Dumitrescu 
666d8141864SCristian Dumitrescu 	/* Buffer allocation. */
667d8141864SCristian Dumitrescu 	line = malloc(MAX_LINE_SIZE);
668d8141864SCristian Dumitrescu 	if (!line)
669d8141864SCristian Dumitrescu 		return -ENOMEM;
670d8141864SCristian Dumitrescu 
671d8141864SCristian Dumitrescu 	/* File read. */
672d8141864SCristian Dumitrescu 	for (line_id = 1; ; line_id++) {
673d8141864SCristian Dumitrescu 		struct rte_swx_table_entry *entry;
674d8141864SCristian Dumitrescu 		int is_blank_or_comment;
675d8141864SCristian Dumitrescu 
676d8141864SCristian Dumitrescu 		if (fgets(line, MAX_LINE_SIZE, file) == NULL)
677d8141864SCristian Dumitrescu 			break;
678d8141864SCristian Dumitrescu 
679d8141864SCristian Dumitrescu 		entry = rte_swx_ctl_pipeline_table_entry_read(p,
680d8141864SCristian Dumitrescu 							      table_name,
681d8141864SCristian Dumitrescu 							      line,
682d8141864SCristian Dumitrescu 							      &is_blank_or_comment);
683d8141864SCristian Dumitrescu 		if (!entry) {
684d8141864SCristian Dumitrescu 			if (is_blank_or_comment)
685d8141864SCristian Dumitrescu 				continue;
686d8141864SCristian Dumitrescu 
687d8141864SCristian Dumitrescu 			status = -EINVAL;
688d8141864SCristian Dumitrescu 			goto error;
689d8141864SCristian Dumitrescu 		}
690d8141864SCristian Dumitrescu 
691d8141864SCristian Dumitrescu 		status = rte_swx_ctl_pipeline_table_default_entry_add(p,
692d8141864SCristian Dumitrescu 								      table_name,
693d8141864SCristian Dumitrescu 								      entry);
694d8141864SCristian Dumitrescu 		table_entry_free(entry);
695d8141864SCristian Dumitrescu 		if (status)
696d8141864SCristian Dumitrescu 			goto error;
697d8141864SCristian Dumitrescu 	}
698d8141864SCristian Dumitrescu 
699d8141864SCristian Dumitrescu error:
700d8141864SCristian Dumitrescu 	*file_line_number = line_id;
701d8141864SCristian Dumitrescu 	free(line);
702d8141864SCristian Dumitrescu 	return status;
703d8141864SCristian Dumitrescu }
704d8141864SCristian Dumitrescu 
705d8141864SCristian Dumitrescu /**
706d8141864SCristian Dumitrescu  * pipeline <pipeline_name> table <table_name> default <file_name>
707d8141864SCristian Dumitrescu  */
708d8141864SCristian Dumitrescu static void
cmd_softnic_pipeline_table_default(struct pmd_internals * softnic,char ** tokens,uint32_t n_tokens,char * out,size_t out_size)709d8141864SCristian Dumitrescu cmd_softnic_pipeline_table_default(struct pmd_internals *softnic,
710d8141864SCristian Dumitrescu 	char **tokens,
711d8141864SCristian Dumitrescu 	uint32_t n_tokens,
712d8141864SCristian Dumitrescu 	char *out,
713d8141864SCristian Dumitrescu 	size_t out_size)
714d8141864SCristian Dumitrescu {
715d8141864SCristian Dumitrescu 	struct pipeline *p;
716d8141864SCristian Dumitrescu 	char *pipeline_name, *table_name, *file_name;
717d8141864SCristian Dumitrescu 	FILE *file = NULL;
718d8141864SCristian Dumitrescu 	uint32_t file_line_number = 0;
719d8141864SCristian Dumitrescu 	int status;
720d8141864SCristian Dumitrescu 
721d8141864SCristian Dumitrescu 	if (n_tokens != 6) {
722d8141864SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
723d8141864SCristian Dumitrescu 		return;
724d8141864SCristian Dumitrescu 	}
725d8141864SCristian Dumitrescu 
726d8141864SCristian Dumitrescu 	pipeline_name = tokens[1];
727d8141864SCristian Dumitrescu 	p = softnic_pipeline_find(softnic, pipeline_name);
728d8141864SCristian Dumitrescu 	if (!p) {
729d8141864SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
730d8141864SCristian Dumitrescu 		return;
731d8141864SCristian Dumitrescu 	}
732d8141864SCristian Dumitrescu 
733d8141864SCristian Dumitrescu 	table_name = tokens[3];
734d8141864SCristian Dumitrescu 
735d8141864SCristian Dumitrescu 	file_name = tokens[5];
736d8141864SCristian Dumitrescu 	file = fopen(file_name, "r");
737d8141864SCristian Dumitrescu 	if (!file) {
738d8141864SCristian Dumitrescu 		snprintf(out, out_size, "Cannot open file %s.\n", file_name);
739d8141864SCristian Dumitrescu 		return;
740d8141864SCristian Dumitrescu 	}
741d8141864SCristian Dumitrescu 
742d8141864SCristian Dumitrescu 	status = pipeline_table_default_entry_add(p->ctl,
743d8141864SCristian Dumitrescu 						  table_name,
744d8141864SCristian Dumitrescu 						  file,
745d8141864SCristian Dumitrescu 						  &file_line_number);
746d8141864SCristian Dumitrescu 	if (status)
747d8141864SCristian Dumitrescu 		snprintf(out, out_size, "Invalid entry in file %s at line %u\n",
748d8141864SCristian Dumitrescu 			 file_name,
749d8141864SCristian Dumitrescu 			 file_line_number);
750d8141864SCristian Dumitrescu 
751d8141864SCristian Dumitrescu 	fclose(file);
752d8141864SCristian Dumitrescu }
753d8141864SCristian Dumitrescu 
754d8141864SCristian Dumitrescu /**
755d8141864SCristian Dumitrescu  * pipeline <pipeline_name> table <table_name> show [filename]
756d8141864SCristian Dumitrescu  */
757d8141864SCristian Dumitrescu static void
cmd_softnic_pipeline_table_show(struct pmd_internals * softnic __rte_unused,char ** tokens,uint32_t n_tokens,char * out,size_t out_size)758d8141864SCristian Dumitrescu cmd_softnic_pipeline_table_show(struct pmd_internals *softnic __rte_unused,
759d8141864SCristian Dumitrescu 	char **tokens,
760d8141864SCristian Dumitrescu 	uint32_t n_tokens,
761d8141864SCristian Dumitrescu 	char *out,
762d8141864SCristian Dumitrescu 	size_t out_size)
763d8141864SCristian Dumitrescu {
764d8141864SCristian Dumitrescu 	struct pipeline *p;
765d8141864SCristian Dumitrescu 	char *pipeline_name, *table_name;
766d8141864SCristian Dumitrescu 	FILE *file = NULL;
767d8141864SCristian Dumitrescu 	int status;
768d8141864SCristian Dumitrescu 
769d8141864SCristian Dumitrescu 	if (n_tokens != 5 && n_tokens != 6) {
770d8141864SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
771d8141864SCristian Dumitrescu 		return;
772d8141864SCristian Dumitrescu 	}
773d8141864SCristian Dumitrescu 
774d8141864SCristian Dumitrescu 	pipeline_name = tokens[1];
775d8141864SCristian Dumitrescu 	p = softnic_pipeline_find(softnic, pipeline_name);
776d8141864SCristian Dumitrescu 	if (!p) {
777d8141864SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
778d8141864SCristian Dumitrescu 		return;
779d8141864SCristian Dumitrescu 	}
780d8141864SCristian Dumitrescu 
781d8141864SCristian Dumitrescu 	table_name = tokens[3];
782d8141864SCristian Dumitrescu 	file = (n_tokens == 6) ? fopen(tokens[5], "w") : stdout;
783d8141864SCristian Dumitrescu 	if (!file) {
784d8141864SCristian Dumitrescu 		snprintf(out, out_size, "Cannot open file %s.\n", tokens[5]);
785d8141864SCristian Dumitrescu 		return;
786d8141864SCristian Dumitrescu 	}
787d8141864SCristian Dumitrescu 
788d8141864SCristian Dumitrescu 	status = rte_swx_ctl_pipeline_table_fprintf(file, p->ctl, table_name);
789d8141864SCristian Dumitrescu 	if (status)
790d8141864SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "table_name");
791d8141864SCristian Dumitrescu 
792d8141864SCristian Dumitrescu 	if (file)
793d8141864SCristian Dumitrescu 		fclose(file);
794d8141864SCristian Dumitrescu }
795d8141864SCristian Dumitrescu 
79600dfff03SCristian Dumitrescu /**
797e9c35c60SCristian Dumitrescu  * pipeline <pipeline_name> selector <selector_name> group add
798e9c35c60SCristian Dumitrescu  */
799e9c35c60SCristian Dumitrescu static void
cmd_softnic_pipeline_selector_group_add(struct pmd_internals * softnic,char ** tokens,uint32_t n_tokens,char * out,size_t out_size)800e9c35c60SCristian Dumitrescu cmd_softnic_pipeline_selector_group_add(struct pmd_internals *softnic,
801e9c35c60SCristian Dumitrescu 	char **tokens,
802e9c35c60SCristian Dumitrescu 	uint32_t n_tokens,
803e9c35c60SCristian Dumitrescu 	char *out,
804e9c35c60SCristian Dumitrescu 	size_t out_size)
805e9c35c60SCristian Dumitrescu {
806e9c35c60SCristian Dumitrescu 	struct pipeline *p;
807e9c35c60SCristian Dumitrescu 	char *pipeline_name, *selector_name;
808e9c35c60SCristian Dumitrescu 	uint32_t group_id;
809e9c35c60SCristian Dumitrescu 	int status;
810e9c35c60SCristian Dumitrescu 
811e9c35c60SCristian Dumitrescu 	if (n_tokens != 6) {
812e9c35c60SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
813e9c35c60SCristian Dumitrescu 		return;
814e9c35c60SCristian Dumitrescu 	}
815e9c35c60SCristian Dumitrescu 
816e9c35c60SCristian Dumitrescu 	pipeline_name = tokens[1];
817e9c35c60SCristian Dumitrescu 	p = softnic_pipeline_find(softnic, pipeline_name);
818e9c35c60SCristian Dumitrescu 	if (!p) {
819e9c35c60SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
820e9c35c60SCristian Dumitrescu 		return;
821e9c35c60SCristian Dumitrescu 	}
822e9c35c60SCristian Dumitrescu 
823e9c35c60SCristian Dumitrescu 	if (strcmp(tokens[2], "selector") != 0) {
824e9c35c60SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "selector");
825e9c35c60SCristian Dumitrescu 		return;
826e9c35c60SCristian Dumitrescu 	}
827e9c35c60SCristian Dumitrescu 
828e9c35c60SCristian Dumitrescu 	selector_name = tokens[3];
829e9c35c60SCristian Dumitrescu 
830e9c35c60SCristian Dumitrescu 	if (strcmp(tokens[4], "group") ||
831e9c35c60SCristian Dumitrescu 		strcmp(tokens[5], "add")) {
832e9c35c60SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "group add");
833e9c35c60SCristian Dumitrescu 		return;
834e9c35c60SCristian Dumitrescu 	}
835e9c35c60SCristian Dumitrescu 
836e9c35c60SCristian Dumitrescu 	status = rte_swx_ctl_pipeline_selector_group_add(p->ctl,
837e9c35c60SCristian Dumitrescu 		selector_name,
838e9c35c60SCristian Dumitrescu 		&group_id);
839e9c35c60SCristian Dumitrescu 	if (status)
840e9c35c60SCristian Dumitrescu 		snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
841e9c35c60SCristian Dumitrescu 	else
842e9c35c60SCristian Dumitrescu 		snprintf(out, out_size, "Group ID: %u\n", group_id);
843e9c35c60SCristian Dumitrescu }
844e9c35c60SCristian Dumitrescu 
845e9c35c60SCristian Dumitrescu /**
846e9c35c60SCristian Dumitrescu  * pipeline <pipeline_name> selector <selector_name> group delete <group_id>
847e9c35c60SCristian Dumitrescu  */
848e9c35c60SCristian Dumitrescu static void
cmd_softnic_pipeline_selector_group_delete(struct pmd_internals * softnic,char ** tokens,uint32_t n_tokens,char * out,size_t out_size)849e9c35c60SCristian Dumitrescu cmd_softnic_pipeline_selector_group_delete(struct pmd_internals *softnic,
850e9c35c60SCristian Dumitrescu 	char **tokens,
851e9c35c60SCristian Dumitrescu 	uint32_t n_tokens,
852e9c35c60SCristian Dumitrescu 	char *out,
853e9c35c60SCristian Dumitrescu 	size_t out_size)
854e9c35c60SCristian Dumitrescu {
855e9c35c60SCristian Dumitrescu 	struct pipeline *p;
856e9c35c60SCristian Dumitrescu 	char *pipeline_name, *selector_name;
857e9c35c60SCristian Dumitrescu 	uint32_t group_id;
858e9c35c60SCristian Dumitrescu 	int status;
859e9c35c60SCristian Dumitrescu 
860e9c35c60SCristian Dumitrescu 	if (n_tokens != 7) {
861e9c35c60SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
862e9c35c60SCristian Dumitrescu 		return;
863e9c35c60SCristian Dumitrescu 	}
864e9c35c60SCristian Dumitrescu 
865e9c35c60SCristian Dumitrescu 	pipeline_name = tokens[1];
866e9c35c60SCristian Dumitrescu 	p = softnic_pipeline_find(softnic, pipeline_name);
867e9c35c60SCristian Dumitrescu 	if (!p) {
868e9c35c60SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
869e9c35c60SCristian Dumitrescu 		return;
870e9c35c60SCristian Dumitrescu 	}
871e9c35c60SCristian Dumitrescu 
872e9c35c60SCristian Dumitrescu 	if (strcmp(tokens[2], "selector") != 0) {
873e9c35c60SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "selector");
874e9c35c60SCristian Dumitrescu 		return;
875e9c35c60SCristian Dumitrescu 	}
876e9c35c60SCristian Dumitrescu 
877e9c35c60SCristian Dumitrescu 	selector_name = tokens[3];
878e9c35c60SCristian Dumitrescu 
879e9c35c60SCristian Dumitrescu 	if (strcmp(tokens[4], "group") ||
880e9c35c60SCristian Dumitrescu 		strcmp(tokens[5], "delete")) {
881e9c35c60SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "group delete");
882e9c35c60SCristian Dumitrescu 		return;
883e9c35c60SCristian Dumitrescu 	}
884e9c35c60SCristian Dumitrescu 
885e9c35c60SCristian Dumitrescu 	if (parser_read_uint32(&group_id, tokens[6]) != 0) {
886e9c35c60SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "group_id");
887e9c35c60SCristian Dumitrescu 		return;
888e9c35c60SCristian Dumitrescu 	}
889e9c35c60SCristian Dumitrescu 
890e9c35c60SCristian Dumitrescu 	status = rte_swx_ctl_pipeline_selector_group_delete(p->ctl,
891e9c35c60SCristian Dumitrescu 		selector_name,
892e9c35c60SCristian Dumitrescu 		group_id);
893e9c35c60SCristian Dumitrescu 	if (status)
894e9c35c60SCristian Dumitrescu 		snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
895e9c35c60SCristian Dumitrescu }
896e9c35c60SCristian Dumitrescu 
897e9c35c60SCristian Dumitrescu #define GROUP_MEMBER_INFO_TOKENS_MAX 6
898e9c35c60SCristian Dumitrescu 
899e9c35c60SCristian Dumitrescu static int
token_is_comment(const char * token)900e9c35c60SCristian Dumitrescu token_is_comment(const char *token)
901e9c35c60SCristian Dumitrescu {
902e9c35c60SCristian Dumitrescu 	if ((token[0] == '#') ||
903e9c35c60SCristian Dumitrescu 	    (token[0] == ';') ||
904e9c35c60SCristian Dumitrescu 	    ((token[0] == '/') && (token[1] == '/')))
905e9c35c60SCristian Dumitrescu 		return 1; /* TRUE. */
906e9c35c60SCristian Dumitrescu 
907e9c35c60SCristian Dumitrescu 	return 0; /* FALSE. */
908e9c35c60SCristian Dumitrescu }
909e9c35c60SCristian Dumitrescu 
910e9c35c60SCristian Dumitrescu static int
pipeline_selector_group_member_read(const char * string,uint32_t * group_id,uint32_t * member_id,uint32_t * weight,int * is_blank_or_comment)911e9c35c60SCristian Dumitrescu pipeline_selector_group_member_read(const char *string,
912e9c35c60SCristian Dumitrescu 				    uint32_t *group_id,
913e9c35c60SCristian Dumitrescu 				    uint32_t *member_id,
914e9c35c60SCristian Dumitrescu 				    uint32_t *weight,
915e9c35c60SCristian Dumitrescu 				    int *is_blank_or_comment)
916e9c35c60SCristian Dumitrescu {
917e9c35c60SCristian Dumitrescu 	char *token_array[GROUP_MEMBER_INFO_TOKENS_MAX], **tokens;
918e9c35c60SCristian Dumitrescu 	char *s0 = NULL, *s;
919e9c35c60SCristian Dumitrescu 	uint32_t n_tokens = 0, group_id_val = 0, member_id_val = 0, weight_val = 0;
920e9c35c60SCristian Dumitrescu 	int blank_or_comment = 0;
921e9c35c60SCristian Dumitrescu 
922e9c35c60SCristian Dumitrescu 	/* Check input arguments. */
923e9c35c60SCristian Dumitrescu 	if (!string || !string[0])
924e9c35c60SCristian Dumitrescu 		goto error;
925e9c35c60SCristian Dumitrescu 
926e9c35c60SCristian Dumitrescu 	/* Memory allocation. */
927e9c35c60SCristian Dumitrescu 	s0 = strdup(string);
928e9c35c60SCristian Dumitrescu 	if (!s0)
929e9c35c60SCristian Dumitrescu 		goto error;
930e9c35c60SCristian Dumitrescu 
931e9c35c60SCristian Dumitrescu 	/* Parse the string into tokens. */
932e9c35c60SCristian Dumitrescu 	for (s = s0; ; ) {
933e9c35c60SCristian Dumitrescu 		char *token;
934e9c35c60SCristian Dumitrescu 
935e9c35c60SCristian Dumitrescu 		token = strtok_r(s, " \f\n\r\t\v", &s);
936e9c35c60SCristian Dumitrescu 		if (!token || token_is_comment(token))
937e9c35c60SCristian Dumitrescu 			break;
938e9c35c60SCristian Dumitrescu 
939e9c35c60SCristian Dumitrescu 		if (n_tokens >= GROUP_MEMBER_INFO_TOKENS_MAX)
940e9c35c60SCristian Dumitrescu 			goto error;
941e9c35c60SCristian Dumitrescu 
942e9c35c60SCristian Dumitrescu 		token_array[n_tokens] = token;
943e9c35c60SCristian Dumitrescu 		n_tokens++;
944e9c35c60SCristian Dumitrescu 	}
945e9c35c60SCristian Dumitrescu 
946e9c35c60SCristian Dumitrescu 	if (!n_tokens) {
947e9c35c60SCristian Dumitrescu 		blank_or_comment = 1;
948e9c35c60SCristian Dumitrescu 		goto error;
949e9c35c60SCristian Dumitrescu 	}
950e9c35c60SCristian Dumitrescu 
951e9c35c60SCristian Dumitrescu 	tokens = token_array;
952e9c35c60SCristian Dumitrescu 
953e9c35c60SCristian Dumitrescu 	if (n_tokens < 4 ||
954e9c35c60SCristian Dumitrescu 		strcmp(tokens[0], "group") ||
955e9c35c60SCristian Dumitrescu 		strcmp(tokens[2], "member"))
956e9c35c60SCristian Dumitrescu 		goto error;
957e9c35c60SCristian Dumitrescu 
958e9c35c60SCristian Dumitrescu 	/*
959e9c35c60SCristian Dumitrescu 	 * Group ID.
960e9c35c60SCristian Dumitrescu 	 */
961e9c35c60SCristian Dumitrescu 	if (parser_read_uint32(&group_id_val, tokens[1]) != 0)
962e9c35c60SCristian Dumitrescu 		goto error;
963e9c35c60SCristian Dumitrescu 	*group_id = group_id_val;
964e9c35c60SCristian Dumitrescu 
965e9c35c60SCristian Dumitrescu 	/*
966e9c35c60SCristian Dumitrescu 	 * Member ID.
967e9c35c60SCristian Dumitrescu 	 */
968e9c35c60SCristian Dumitrescu 	if (parser_read_uint32(&member_id_val, tokens[3]) != 0)
969e9c35c60SCristian Dumitrescu 		goto error;
970e9c35c60SCristian Dumitrescu 	*member_id = member_id_val;
971e9c35c60SCristian Dumitrescu 
972e9c35c60SCristian Dumitrescu 	tokens += 4;
973e9c35c60SCristian Dumitrescu 	n_tokens -= 4;
974e9c35c60SCristian Dumitrescu 
975e9c35c60SCristian Dumitrescu 	/*
976e9c35c60SCristian Dumitrescu 	 * Weight.
977e9c35c60SCristian Dumitrescu 	 */
978e9c35c60SCristian Dumitrescu 	if (n_tokens && !strcmp(tokens[0], "weight")) {
979e9c35c60SCristian Dumitrescu 		if (n_tokens < 2)
980e9c35c60SCristian Dumitrescu 			goto error;
981e9c35c60SCristian Dumitrescu 
982e9c35c60SCristian Dumitrescu 		if (parser_read_uint32(&weight_val, tokens[1]) != 0)
983e9c35c60SCristian Dumitrescu 			goto error;
984e9c35c60SCristian Dumitrescu 		*weight = weight_val;
985e9c35c60SCristian Dumitrescu 
986e9c35c60SCristian Dumitrescu 		tokens += 2;
987e9c35c60SCristian Dumitrescu 		n_tokens -= 2;
988e9c35c60SCristian Dumitrescu 	}
989e9c35c60SCristian Dumitrescu 
990e9c35c60SCristian Dumitrescu 	if (n_tokens)
991e9c35c60SCristian Dumitrescu 		goto error;
992e9c35c60SCristian Dumitrescu 
993e9c35c60SCristian Dumitrescu 	free(s0);
994e9c35c60SCristian Dumitrescu 	return 0;
995e9c35c60SCristian Dumitrescu 
996e9c35c60SCristian Dumitrescu error:
997e9c35c60SCristian Dumitrescu 	free(s0);
998e9c35c60SCristian Dumitrescu 	if (is_blank_or_comment)
999e9c35c60SCristian Dumitrescu 		*is_blank_or_comment = blank_or_comment;
1000e9c35c60SCristian Dumitrescu 	return -EINVAL;
1001e9c35c60SCristian Dumitrescu }
1002e9c35c60SCristian Dumitrescu 
1003e9c35c60SCristian Dumitrescu static int
pipeline_selector_group_members_add(struct rte_swx_ctl_pipeline * p,const char * selector_name,FILE * file,uint32_t * file_line_number)1004e9c35c60SCristian Dumitrescu pipeline_selector_group_members_add(struct rte_swx_ctl_pipeline *p,
1005e9c35c60SCristian Dumitrescu 				    const char *selector_name,
1006e9c35c60SCristian Dumitrescu 				    FILE *file,
1007e9c35c60SCristian Dumitrescu 				    uint32_t *file_line_number)
1008e9c35c60SCristian Dumitrescu {
1009e9c35c60SCristian Dumitrescu 	char *line = NULL;
1010e9c35c60SCristian Dumitrescu 	uint32_t line_id = 0;
1011e9c35c60SCristian Dumitrescu 	int status = 0;
1012e9c35c60SCristian Dumitrescu 
1013e9c35c60SCristian Dumitrescu 	/* Buffer allocation. */
1014e9c35c60SCristian Dumitrescu 	line = malloc(MAX_LINE_SIZE);
1015e9c35c60SCristian Dumitrescu 	if (!line)
1016e9c35c60SCristian Dumitrescu 		return -ENOMEM;
1017e9c35c60SCristian Dumitrescu 
1018e9c35c60SCristian Dumitrescu 	/* File read. */
1019e9c35c60SCristian Dumitrescu 	for (line_id = 1; ; line_id++) {
1020e9c35c60SCristian Dumitrescu 		uint32_t group_id, member_id, weight;
1021e9c35c60SCristian Dumitrescu 		int is_blank_or_comment;
1022e9c35c60SCristian Dumitrescu 
1023e9c35c60SCristian Dumitrescu 		if (fgets(line, MAX_LINE_SIZE, file) == NULL)
1024e9c35c60SCristian Dumitrescu 			break;
1025e9c35c60SCristian Dumitrescu 
1026e9c35c60SCristian Dumitrescu 		status = pipeline_selector_group_member_read(line,
1027e9c35c60SCristian Dumitrescu 							     &group_id,
1028e9c35c60SCristian Dumitrescu 							     &member_id,
1029e9c35c60SCristian Dumitrescu 							     &weight,
1030e9c35c60SCristian Dumitrescu 							     &is_blank_or_comment);
1031e9c35c60SCristian Dumitrescu 		if (status) {
1032e9c35c60SCristian Dumitrescu 			if (is_blank_or_comment)
1033e9c35c60SCristian Dumitrescu 				continue;
1034e9c35c60SCristian Dumitrescu 
1035e9c35c60SCristian Dumitrescu 			goto error;
1036e9c35c60SCristian Dumitrescu 		}
1037e9c35c60SCristian Dumitrescu 
1038e9c35c60SCristian Dumitrescu 		status = rte_swx_ctl_pipeline_selector_group_member_add(p,
1039e9c35c60SCristian Dumitrescu 			selector_name,
1040e9c35c60SCristian Dumitrescu 			group_id,
1041e9c35c60SCristian Dumitrescu 			member_id,
1042e9c35c60SCristian Dumitrescu 			weight);
1043e9c35c60SCristian Dumitrescu 		if (status)
1044e9c35c60SCristian Dumitrescu 			goto error;
1045e9c35c60SCristian Dumitrescu 	}
1046e9c35c60SCristian Dumitrescu 
1047e9c35c60SCristian Dumitrescu error:
1048e9c35c60SCristian Dumitrescu 	free(line);
1049e9c35c60SCristian Dumitrescu 	*file_line_number = line_id;
1050e9c35c60SCristian Dumitrescu 	return status;
1051e9c35c60SCristian Dumitrescu }
1052e9c35c60SCristian Dumitrescu 
1053e9c35c60SCristian Dumitrescu /**
1054e9c35c60SCristian Dumitrescu  * pipeline <pipeline_name> selector <selector_name> group member add <file_name>
1055e9c35c60SCristian Dumitrescu  */
1056e9c35c60SCristian Dumitrescu static void
cmd_softnic_pipeline_selector_group_member_add(struct pmd_internals * softnic,char ** tokens,uint32_t n_tokens,char * out,size_t out_size)1057e9c35c60SCristian Dumitrescu cmd_softnic_pipeline_selector_group_member_add(struct pmd_internals *softnic,
1058e9c35c60SCristian Dumitrescu 	char **tokens,
1059e9c35c60SCristian Dumitrescu 	uint32_t n_tokens,
1060e9c35c60SCristian Dumitrescu 	char *out,
1061e9c35c60SCristian Dumitrescu 	size_t out_size)
1062e9c35c60SCristian Dumitrescu {
1063e9c35c60SCristian Dumitrescu 	struct pipeline *p;
1064e9c35c60SCristian Dumitrescu 	char *pipeline_name, *selector_name, *file_name;
1065e9c35c60SCristian Dumitrescu 	FILE *file = NULL;
1066e9c35c60SCristian Dumitrescu 	uint32_t file_line_number = 0;
1067e9c35c60SCristian Dumitrescu 	int status;
1068e9c35c60SCristian Dumitrescu 
1069e9c35c60SCristian Dumitrescu 	if (n_tokens != 8) {
1070e9c35c60SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1071e9c35c60SCristian Dumitrescu 		return;
1072e9c35c60SCristian Dumitrescu 	}
1073e9c35c60SCristian Dumitrescu 
1074e9c35c60SCristian Dumitrescu 	pipeline_name = tokens[1];
1075e9c35c60SCristian Dumitrescu 	p = softnic_pipeline_find(softnic, pipeline_name);
1076e9c35c60SCristian Dumitrescu 	if (!p) {
1077e9c35c60SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
1078e9c35c60SCristian Dumitrescu 		return;
1079e9c35c60SCristian Dumitrescu 	}
1080e9c35c60SCristian Dumitrescu 
1081e9c35c60SCristian Dumitrescu 	if (strcmp(tokens[2], "selector") != 0) {
1082e9c35c60SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "selector");
1083e9c35c60SCristian Dumitrescu 		return;
1084e9c35c60SCristian Dumitrescu 	}
1085e9c35c60SCristian Dumitrescu 
1086e9c35c60SCristian Dumitrescu 	selector_name = tokens[3];
1087e9c35c60SCristian Dumitrescu 
1088e9c35c60SCristian Dumitrescu 	if (strcmp(tokens[4], "group") ||
1089e9c35c60SCristian Dumitrescu 		strcmp(tokens[5], "member") ||
1090e9c35c60SCristian Dumitrescu 		strcmp(tokens[6], "add")) {
1091e9c35c60SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "group member add");
1092e9c35c60SCristian Dumitrescu 		return;
1093e9c35c60SCristian Dumitrescu 	}
1094e9c35c60SCristian Dumitrescu 
1095e9c35c60SCristian Dumitrescu 	file_name = tokens[7];
1096e9c35c60SCristian Dumitrescu 	file = fopen(file_name, "r");
1097e9c35c60SCristian Dumitrescu 	if (!file) {
1098e9c35c60SCristian Dumitrescu 		snprintf(out, out_size, "Cannot open file %s.\n", file_name);
1099e9c35c60SCristian Dumitrescu 		return;
1100e9c35c60SCristian Dumitrescu 	}
1101e9c35c60SCristian Dumitrescu 
1102e9c35c60SCristian Dumitrescu 	status = pipeline_selector_group_members_add(p->ctl,
1103e9c35c60SCristian Dumitrescu 		selector_name,
1104e9c35c60SCristian Dumitrescu 		file,
1105e9c35c60SCristian Dumitrescu 		&file_line_number);
1106e9c35c60SCristian Dumitrescu 	if (status)
1107e9c35c60SCristian Dumitrescu 		snprintf(out, out_size, "Invalid entry in file %s at line %u\n",
1108e9c35c60SCristian Dumitrescu 			 file_name,
1109e9c35c60SCristian Dumitrescu 			 file_line_number);
1110e9c35c60SCristian Dumitrescu 
1111e9c35c60SCristian Dumitrescu 	fclose(file);
1112e9c35c60SCristian Dumitrescu }
1113e9c35c60SCristian Dumitrescu 
1114e9c35c60SCristian Dumitrescu static int
pipeline_selector_group_members_delete(struct rte_swx_ctl_pipeline * p,const char * selector_name,FILE * file,uint32_t * file_line_number)1115e9c35c60SCristian Dumitrescu pipeline_selector_group_members_delete(struct rte_swx_ctl_pipeline *p,
1116e9c35c60SCristian Dumitrescu 				       const char *selector_name,
1117e9c35c60SCristian Dumitrescu 				       FILE *file,
1118e9c35c60SCristian Dumitrescu 				       uint32_t *file_line_number)
1119e9c35c60SCristian Dumitrescu {
1120e9c35c60SCristian Dumitrescu 	char *line = NULL;
1121e9c35c60SCristian Dumitrescu 	uint32_t line_id = 0;
1122e9c35c60SCristian Dumitrescu 	int status = 0;
1123e9c35c60SCristian Dumitrescu 
1124e9c35c60SCristian Dumitrescu 	/* Buffer allocation. */
1125e9c35c60SCristian Dumitrescu 	line = malloc(MAX_LINE_SIZE);
1126e9c35c60SCristian Dumitrescu 	if (!line)
1127e9c35c60SCristian Dumitrescu 		return -ENOMEM;
1128e9c35c60SCristian Dumitrescu 
1129e9c35c60SCristian Dumitrescu 	/* File read. */
1130e9c35c60SCristian Dumitrescu 	for (line_id = 1; ; line_id++) {
1131e9c35c60SCristian Dumitrescu 		uint32_t group_id, member_id, weight;
1132e9c35c60SCristian Dumitrescu 		int is_blank_or_comment;
1133e9c35c60SCristian Dumitrescu 
1134e9c35c60SCristian Dumitrescu 		if (fgets(line, MAX_LINE_SIZE, file) == NULL)
1135e9c35c60SCristian Dumitrescu 			break;
1136e9c35c60SCristian Dumitrescu 
1137e9c35c60SCristian Dumitrescu 		status = pipeline_selector_group_member_read(line,
1138e9c35c60SCristian Dumitrescu 							     &group_id,
1139e9c35c60SCristian Dumitrescu 							     &member_id,
1140e9c35c60SCristian Dumitrescu 							     &weight,
1141e9c35c60SCristian Dumitrescu 							     &is_blank_or_comment);
1142e9c35c60SCristian Dumitrescu 		if (status) {
1143e9c35c60SCristian Dumitrescu 			if (is_blank_or_comment)
1144e9c35c60SCristian Dumitrescu 				continue;
1145e9c35c60SCristian Dumitrescu 
1146e9c35c60SCristian Dumitrescu 			goto error;
1147e9c35c60SCristian Dumitrescu 		}
1148e9c35c60SCristian Dumitrescu 
1149e9c35c60SCristian Dumitrescu 		status = rte_swx_ctl_pipeline_selector_group_member_delete(p,
1150e9c35c60SCristian Dumitrescu 			selector_name,
1151e9c35c60SCristian Dumitrescu 			group_id,
1152e9c35c60SCristian Dumitrescu 			member_id);
1153e9c35c60SCristian Dumitrescu 		if (status)
1154e9c35c60SCristian Dumitrescu 			goto error;
1155e9c35c60SCristian Dumitrescu 	}
1156e9c35c60SCristian Dumitrescu 
1157e9c35c60SCristian Dumitrescu error:
1158e9c35c60SCristian Dumitrescu 	free(line);
1159e9c35c60SCristian Dumitrescu 	*file_line_number = line_id;
1160e9c35c60SCristian Dumitrescu 	return status;
1161e9c35c60SCristian Dumitrescu }
1162e9c35c60SCristian Dumitrescu 
1163e9c35c60SCristian Dumitrescu /**
1164e9c35c60SCristian Dumitrescu  * pipeline <pipeline_name> selector <selector_name> group member delete <file_name>
1165e9c35c60SCristian Dumitrescu  */
1166e9c35c60SCristian Dumitrescu static void
cmd_softnic_pipeline_selector_group_member_delete(struct pmd_internals * softnic,char ** tokens,uint32_t n_tokens,char * out,size_t out_size)1167e9c35c60SCristian Dumitrescu cmd_softnic_pipeline_selector_group_member_delete(struct pmd_internals *softnic,
1168e9c35c60SCristian Dumitrescu 	char **tokens,
1169e9c35c60SCristian Dumitrescu 	uint32_t n_tokens,
1170e9c35c60SCristian Dumitrescu 	char *out,
1171e9c35c60SCristian Dumitrescu 	size_t out_size)
1172e9c35c60SCristian Dumitrescu {
1173e9c35c60SCristian Dumitrescu 	struct pipeline *p;
1174e9c35c60SCristian Dumitrescu 	char *pipeline_name, *selector_name, *file_name;
1175e9c35c60SCristian Dumitrescu 	FILE *file = NULL;
1176e9c35c60SCristian Dumitrescu 	uint32_t file_line_number = 0;
1177e9c35c60SCristian Dumitrescu 	int status;
1178e9c35c60SCristian Dumitrescu 
1179e9c35c60SCristian Dumitrescu 	if (n_tokens != 8) {
1180e9c35c60SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1181e9c35c60SCristian Dumitrescu 		return;
1182e9c35c60SCristian Dumitrescu 	}
1183e9c35c60SCristian Dumitrescu 
1184e9c35c60SCristian Dumitrescu 	pipeline_name = tokens[1];
1185e9c35c60SCristian Dumitrescu 	p = softnic_pipeline_find(softnic, pipeline_name);
1186e9c35c60SCristian Dumitrescu 	if (!p) {
1187e9c35c60SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
1188e9c35c60SCristian Dumitrescu 		return;
1189e9c35c60SCristian Dumitrescu 	}
1190e9c35c60SCristian Dumitrescu 
1191e9c35c60SCristian Dumitrescu 	if (strcmp(tokens[2], "selector") != 0) {
1192e9c35c60SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "selector");
1193e9c35c60SCristian Dumitrescu 		return;
1194e9c35c60SCristian Dumitrescu 	}
1195e9c35c60SCristian Dumitrescu 
1196e9c35c60SCristian Dumitrescu 	selector_name = tokens[3];
1197e9c35c60SCristian Dumitrescu 
1198e9c35c60SCristian Dumitrescu 	if (strcmp(tokens[4], "group") ||
1199e9c35c60SCristian Dumitrescu 		strcmp(tokens[5], "member") ||
1200e9c35c60SCristian Dumitrescu 		strcmp(tokens[6], "delete")) {
1201e9c35c60SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "group member delete");
1202e9c35c60SCristian Dumitrescu 		return;
1203e9c35c60SCristian Dumitrescu 	}
1204e9c35c60SCristian Dumitrescu 
1205e9c35c60SCristian Dumitrescu 	file_name = tokens[7];
1206e9c35c60SCristian Dumitrescu 	file = fopen(file_name, "r");
1207e9c35c60SCristian Dumitrescu 	if (!file) {
1208e9c35c60SCristian Dumitrescu 		snprintf(out, out_size, "Cannot open file %s.\n", file_name);
1209e9c35c60SCristian Dumitrescu 		return;
1210e9c35c60SCristian Dumitrescu 	}
1211e9c35c60SCristian Dumitrescu 
1212e9c35c60SCristian Dumitrescu 	status = pipeline_selector_group_members_delete(p->ctl,
1213e9c35c60SCristian Dumitrescu 							selector_name,
1214e9c35c60SCristian Dumitrescu 							file,
1215e9c35c60SCristian Dumitrescu 							&file_line_number);
1216e9c35c60SCristian Dumitrescu 	if (status)
1217e9c35c60SCristian Dumitrescu 		snprintf(out, out_size, "Invalid entry in file %s at line %u\n",
1218e9c35c60SCristian Dumitrescu 			 file_name,
1219e9c35c60SCristian Dumitrescu 			 file_line_number);
1220e9c35c60SCristian Dumitrescu 
1221e9c35c60SCristian Dumitrescu 	fclose(file);
1222e9c35c60SCristian Dumitrescu }
1223e9c35c60SCristian Dumitrescu 
1224e9c35c60SCristian Dumitrescu /**
1225e9c35c60SCristian Dumitrescu  * pipeline <pipeline_name> selector <selector_name> show [filename]
1226e9c35c60SCristian Dumitrescu  */
1227e9c35c60SCristian Dumitrescu static void
cmd_softnic_pipeline_selector_show(struct pmd_internals * softnic,char ** tokens,uint32_t n_tokens,char * out,size_t out_size)1228e9c35c60SCristian Dumitrescu cmd_softnic_pipeline_selector_show(struct pmd_internals *softnic,
1229e9c35c60SCristian Dumitrescu 	char **tokens,
1230e9c35c60SCristian Dumitrescu 	uint32_t n_tokens,
1231e9c35c60SCristian Dumitrescu 	char *out,
1232e9c35c60SCristian Dumitrescu 	size_t out_size)
1233e9c35c60SCristian Dumitrescu {
1234e9c35c60SCristian Dumitrescu 	struct pipeline *p;
1235e9c35c60SCristian Dumitrescu 	char *pipeline_name, *selector_name;
1236e9c35c60SCristian Dumitrescu 	FILE *file = NULL;
1237e9c35c60SCristian Dumitrescu 	int status;
1238e9c35c60SCristian Dumitrescu 
1239e9c35c60SCristian Dumitrescu 	if (n_tokens != 5 && n_tokens != 6) {
1240e9c35c60SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1241e9c35c60SCristian Dumitrescu 		return;
1242e9c35c60SCristian Dumitrescu 	}
1243e9c35c60SCristian Dumitrescu 
1244e9c35c60SCristian Dumitrescu 	pipeline_name = tokens[1];
1245e9c35c60SCristian Dumitrescu 	p = softnic_pipeline_find(softnic, pipeline_name);
1246e9c35c60SCristian Dumitrescu 	if (!p) {
1247e9c35c60SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
1248e9c35c60SCristian Dumitrescu 		return;
1249e9c35c60SCristian Dumitrescu 	}
1250e9c35c60SCristian Dumitrescu 
1251e9c35c60SCristian Dumitrescu 	selector_name = tokens[3];
1252e9c35c60SCristian Dumitrescu 
1253e9c35c60SCristian Dumitrescu 	file = (n_tokens == 6) ? fopen(tokens[5], "w") : stdout;
1254e9c35c60SCristian Dumitrescu 	if (!file) {
1255e9c35c60SCristian Dumitrescu 		snprintf(out, out_size, "Cannot open file %s.\n", tokens[5]);
1256e9c35c60SCristian Dumitrescu 		return;
1257e9c35c60SCristian Dumitrescu 	}
1258e9c35c60SCristian Dumitrescu 
1259e9c35c60SCristian Dumitrescu 	status = rte_swx_ctl_pipeline_selector_fprintf(file, p->ctl, selector_name);
1260e9c35c60SCristian Dumitrescu 	if (status)
1261e9c35c60SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "selector_name");
1262e9c35c60SCristian Dumitrescu 
1263e9c35c60SCristian Dumitrescu 	if (file)
1264e9c35c60SCristian Dumitrescu 		fclose(file);
1265e9c35c60SCristian Dumitrescu }
1266e9c35c60SCristian Dumitrescu 
12673f14baa0SCristian Dumitrescu static int
pipeline_learner_default_entry_add(struct rte_swx_ctl_pipeline * p,const char * learner_name,FILE * file,uint32_t * file_line_number)12683f14baa0SCristian Dumitrescu pipeline_learner_default_entry_add(struct rte_swx_ctl_pipeline *p,
12693f14baa0SCristian Dumitrescu 				   const char *learner_name,
12703f14baa0SCristian Dumitrescu 				   FILE *file,
12713f14baa0SCristian Dumitrescu 				   uint32_t *file_line_number)
12723f14baa0SCristian Dumitrescu {
12733f14baa0SCristian Dumitrescu 	char *line = NULL;
12743f14baa0SCristian Dumitrescu 	uint32_t line_id = 0;
12753f14baa0SCristian Dumitrescu 	int status = 0;
12763f14baa0SCristian Dumitrescu 
12773f14baa0SCristian Dumitrescu 	/* Buffer allocation. */
12783f14baa0SCristian Dumitrescu 	line = malloc(MAX_LINE_SIZE);
12793f14baa0SCristian Dumitrescu 	if (!line)
12803f14baa0SCristian Dumitrescu 		return -ENOMEM;
12813f14baa0SCristian Dumitrescu 
12823f14baa0SCristian Dumitrescu 	/* File read. */
12833f14baa0SCristian Dumitrescu 	for (line_id = 1; ; line_id++) {
12843f14baa0SCristian Dumitrescu 		struct rte_swx_table_entry *entry;
12853f14baa0SCristian Dumitrescu 		int is_blank_or_comment;
12863f14baa0SCristian Dumitrescu 
12873f14baa0SCristian Dumitrescu 		if (fgets(line, MAX_LINE_SIZE, file) == NULL)
12883f14baa0SCristian Dumitrescu 			break;
12893f14baa0SCristian Dumitrescu 
12903f14baa0SCristian Dumitrescu 		entry = rte_swx_ctl_pipeline_learner_default_entry_read(p,
12913f14baa0SCristian Dumitrescu 									learner_name,
12923f14baa0SCristian Dumitrescu 									line,
12933f14baa0SCristian Dumitrescu 									&is_blank_or_comment);
12943f14baa0SCristian Dumitrescu 		if (!entry) {
12953f14baa0SCristian Dumitrescu 			if (is_blank_or_comment)
12963f14baa0SCristian Dumitrescu 				continue;
12973f14baa0SCristian Dumitrescu 
12983f14baa0SCristian Dumitrescu 			status = -EINVAL;
12993f14baa0SCristian Dumitrescu 			goto error;
13003f14baa0SCristian Dumitrescu 		}
13013f14baa0SCristian Dumitrescu 
13023f14baa0SCristian Dumitrescu 		status = rte_swx_ctl_pipeline_learner_default_entry_add(p,
13033f14baa0SCristian Dumitrescu 									learner_name,
13043f14baa0SCristian Dumitrescu 									entry);
13053f14baa0SCristian Dumitrescu 		table_entry_free(entry);
13063f14baa0SCristian Dumitrescu 		if (status)
13073f14baa0SCristian Dumitrescu 			goto error;
13083f14baa0SCristian Dumitrescu 	}
13093f14baa0SCristian Dumitrescu 
13103f14baa0SCristian Dumitrescu error:
13113f14baa0SCristian Dumitrescu 	*file_line_number = line_id;
13123f14baa0SCristian Dumitrescu 	free(line);
13133f14baa0SCristian Dumitrescu 	return status;
13143f14baa0SCristian Dumitrescu }
13153f14baa0SCristian Dumitrescu 
13163f14baa0SCristian Dumitrescu /**
13173f14baa0SCristian Dumitrescu  * pipeline <pipeline_name> learner <learner_name> default <file_name>
13183f14baa0SCristian Dumitrescu  */
13193f14baa0SCristian Dumitrescu static void
cmd_softnic_pipeline_learner_default(struct pmd_internals * softnic,char ** tokens,uint32_t n_tokens,char * out,size_t out_size)13203f14baa0SCristian Dumitrescu cmd_softnic_pipeline_learner_default(struct pmd_internals *softnic,
13213f14baa0SCristian Dumitrescu 	char **tokens,
13223f14baa0SCristian Dumitrescu 	uint32_t n_tokens,
13233f14baa0SCristian Dumitrescu 	char *out,
13243f14baa0SCristian Dumitrescu 	size_t out_size)
13253f14baa0SCristian Dumitrescu {
13263f14baa0SCristian Dumitrescu 	struct pipeline *p;
13273f14baa0SCristian Dumitrescu 	char *pipeline_name, *learner_name, *file_name;
13283f14baa0SCristian Dumitrescu 	FILE *file = NULL;
13293f14baa0SCristian Dumitrescu 	uint32_t file_line_number = 0;
13303f14baa0SCristian Dumitrescu 	int status;
13313f14baa0SCristian Dumitrescu 
13323f14baa0SCristian Dumitrescu 	if (n_tokens != 6) {
13333f14baa0SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
13343f14baa0SCristian Dumitrescu 		return;
13353f14baa0SCristian Dumitrescu 	}
13363f14baa0SCristian Dumitrescu 
13373f14baa0SCristian Dumitrescu 	pipeline_name = tokens[1];
13383f14baa0SCristian Dumitrescu 	p = softnic_pipeline_find(softnic, pipeline_name);
13393f14baa0SCristian Dumitrescu 	if (!p) {
13403f14baa0SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
13413f14baa0SCristian Dumitrescu 		return;
13423f14baa0SCristian Dumitrescu 	}
13433f14baa0SCristian Dumitrescu 
13443f14baa0SCristian Dumitrescu 	learner_name = tokens[3];
13453f14baa0SCristian Dumitrescu 
13463f14baa0SCristian Dumitrescu 	file_name = tokens[5];
13473f14baa0SCristian Dumitrescu 	file = fopen(file_name, "r");
13483f14baa0SCristian Dumitrescu 	if (!file) {
13493f14baa0SCristian Dumitrescu 		snprintf(out, out_size, "Cannot open file %s.\n", file_name);
13503f14baa0SCristian Dumitrescu 		return;
13513f14baa0SCristian Dumitrescu 	}
13523f14baa0SCristian Dumitrescu 
13533f14baa0SCristian Dumitrescu 	status = pipeline_learner_default_entry_add(p->ctl,
13543f14baa0SCristian Dumitrescu 						    learner_name,
13553f14baa0SCristian Dumitrescu 						    file,
13563f14baa0SCristian Dumitrescu 						    &file_line_number);
13573f14baa0SCristian Dumitrescu 	if (status)
13583f14baa0SCristian Dumitrescu 		snprintf(out, out_size, "Invalid entry in file %s at line %u\n",
13593f14baa0SCristian Dumitrescu 			 file_name,
13603f14baa0SCristian Dumitrescu 			 file_line_number);
13613f14baa0SCristian Dumitrescu 
13623f14baa0SCristian Dumitrescu 	fclose(file);
13633f14baa0SCristian Dumitrescu }
13643f14baa0SCristian Dumitrescu 
1365e9c35c60SCristian Dumitrescu /**
1366b4647f3aSCristian Dumitrescu  * pipeline <pipeline_name> commit
1367b4647f3aSCristian Dumitrescu  */
1368b4647f3aSCristian Dumitrescu static void
cmd_softnic_pipeline_commit(struct pmd_internals * softnic,char ** tokens,uint32_t n_tokens,char * out,size_t out_size)1369b4647f3aSCristian Dumitrescu cmd_softnic_pipeline_commit(struct pmd_internals *softnic,
1370b4647f3aSCristian Dumitrescu 	char **tokens,
1371b4647f3aSCristian Dumitrescu 	uint32_t n_tokens,
1372b4647f3aSCristian Dumitrescu 	char *out,
1373b4647f3aSCristian Dumitrescu 	size_t out_size)
1374b4647f3aSCristian Dumitrescu {
1375b4647f3aSCristian Dumitrescu 	struct pipeline *p;
1376b4647f3aSCristian Dumitrescu 	char *pipeline_name;
1377b4647f3aSCristian Dumitrescu 	int status;
1378b4647f3aSCristian Dumitrescu 
1379b4647f3aSCristian Dumitrescu 	if (n_tokens != 3) {
1380b4647f3aSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1381b4647f3aSCristian Dumitrescu 		return;
1382b4647f3aSCristian Dumitrescu 	}
1383b4647f3aSCristian Dumitrescu 
1384b4647f3aSCristian Dumitrescu 	pipeline_name = tokens[1];
1385b4647f3aSCristian Dumitrescu 	p = softnic_pipeline_find(softnic, pipeline_name);
1386b4647f3aSCristian Dumitrescu 	if (!p) {
1387b4647f3aSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
1388b4647f3aSCristian Dumitrescu 		return;
1389b4647f3aSCristian Dumitrescu 	}
1390b4647f3aSCristian Dumitrescu 
1391b4647f3aSCristian Dumitrescu 	status = rte_swx_ctl_pipeline_commit(p->ctl, 1);
1392b4647f3aSCristian Dumitrescu 	if (status)
1393b4647f3aSCristian Dumitrescu 		snprintf(out, out_size, "Commit failed. "
1394b4647f3aSCristian Dumitrescu 			"Use \"commit\" to retry or \"abort\" to discard the pending work.\n");
1395b4647f3aSCristian Dumitrescu }
1396b4647f3aSCristian Dumitrescu 
1397b4647f3aSCristian Dumitrescu /**
1398b4647f3aSCristian Dumitrescu  * pipeline <pipeline_name> abort
1399b4647f3aSCristian Dumitrescu  */
1400b4647f3aSCristian Dumitrescu static void
cmd_softnic_pipeline_abort(struct pmd_internals * softnic,char ** tokens,uint32_t n_tokens,char * out,size_t out_size)1401b4647f3aSCristian Dumitrescu cmd_softnic_pipeline_abort(struct pmd_internals *softnic,
1402b4647f3aSCristian Dumitrescu 	char **tokens,
1403b4647f3aSCristian Dumitrescu 	uint32_t n_tokens,
1404b4647f3aSCristian Dumitrescu 	char *out,
1405b4647f3aSCristian Dumitrescu 	size_t out_size)
1406b4647f3aSCristian Dumitrescu {
1407b4647f3aSCristian Dumitrescu 	struct pipeline *p;
1408b4647f3aSCristian Dumitrescu 	char *pipeline_name;
1409b4647f3aSCristian Dumitrescu 
1410b4647f3aSCristian Dumitrescu 	if (n_tokens != 3) {
1411b4647f3aSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1412b4647f3aSCristian Dumitrescu 		return;
1413b4647f3aSCristian Dumitrescu 	}
1414b4647f3aSCristian Dumitrescu 
1415b4647f3aSCristian Dumitrescu 	pipeline_name = tokens[1];
1416b4647f3aSCristian Dumitrescu 	p = softnic_pipeline_find(softnic, pipeline_name);
1417b4647f3aSCristian Dumitrescu 	if (!p) {
1418b4647f3aSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
1419b4647f3aSCristian Dumitrescu 		return;
1420b4647f3aSCristian Dumitrescu 	}
1421b4647f3aSCristian Dumitrescu 
1422b4647f3aSCristian Dumitrescu 	rte_swx_ctl_pipeline_abort(p->ctl);
1423b4647f3aSCristian Dumitrescu }
1424b4647f3aSCristian Dumitrescu 
1425b4647f3aSCristian Dumitrescu /**
1426c7683010SCristian Dumitrescu  * pipeline <pipeline_name> regrd <register_array_name> <index>
1427c7683010SCristian Dumitrescu  */
1428c7683010SCristian Dumitrescu static void
cmd_softnic_pipeline_regrd(struct pmd_internals * softnic,char ** tokens,uint32_t n_tokens,char * out,size_t out_size)1429c7683010SCristian Dumitrescu cmd_softnic_pipeline_regrd(struct pmd_internals *softnic,
1430c7683010SCristian Dumitrescu 	char **tokens,
1431c7683010SCristian Dumitrescu 	uint32_t n_tokens,
1432c7683010SCristian Dumitrescu 	char *out,
1433c7683010SCristian Dumitrescu 	size_t out_size)
1434c7683010SCristian Dumitrescu {
1435c7683010SCristian Dumitrescu 	struct pipeline *p;
1436c7683010SCristian Dumitrescu 	const char *pipeline_name, *name;
1437c7683010SCristian Dumitrescu 	uint64_t value;
1438c7683010SCristian Dumitrescu 	uint32_t idx;
1439c7683010SCristian Dumitrescu 	int status;
1440c7683010SCristian Dumitrescu 
1441c7683010SCristian Dumitrescu 	if (n_tokens != 5) {
1442c7683010SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1443c7683010SCristian Dumitrescu 		return;
1444c7683010SCristian Dumitrescu 	}
1445c7683010SCristian Dumitrescu 
1446c7683010SCristian Dumitrescu 	pipeline_name = tokens[1];
1447c7683010SCristian Dumitrescu 	p = softnic_pipeline_find(softnic, pipeline_name);
1448c7683010SCristian Dumitrescu 	if (!p) {
1449c7683010SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
1450c7683010SCristian Dumitrescu 		return;
1451c7683010SCristian Dumitrescu 	}
1452c7683010SCristian Dumitrescu 
1453c7683010SCristian Dumitrescu 	if (strcmp(tokens[2], "regrd")) {
1454c7683010SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "regrd");
1455c7683010SCristian Dumitrescu 		return;
1456c7683010SCristian Dumitrescu 	}
1457c7683010SCristian Dumitrescu 
1458c7683010SCristian Dumitrescu 	name = tokens[3];
1459c7683010SCristian Dumitrescu 
1460c7683010SCristian Dumitrescu 	if (parser_read_uint32(&idx, tokens[4])) {
1461c7683010SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "index");
1462c7683010SCristian Dumitrescu 		return;
1463c7683010SCristian Dumitrescu 	}
1464c7683010SCristian Dumitrescu 
1465c7683010SCristian Dumitrescu 	status = rte_swx_ctl_pipeline_regarray_read(p->p, name, idx, &value);
1466c7683010SCristian Dumitrescu 	if (status) {
1467c7683010SCristian Dumitrescu 		snprintf(out, out_size, "Command failed.\n");
1468c7683010SCristian Dumitrescu 		return;
1469c7683010SCristian Dumitrescu 	}
1470c7683010SCristian Dumitrescu 
1471c7683010SCristian Dumitrescu 	snprintf(out, out_size, "0x%" PRIx64 "\n", value);
1472c7683010SCristian Dumitrescu }
1473c7683010SCristian Dumitrescu 
1474c7683010SCristian Dumitrescu /**
1475c7683010SCristian Dumitrescu  * pipeline <pipeline_name> regwr <register_array_name> <index> <value>
1476c7683010SCristian Dumitrescu  */
1477c7683010SCristian Dumitrescu static void
cmd_softnic_pipeline_regwr(struct pmd_internals * softnic,char ** tokens,uint32_t n_tokens,char * out,size_t out_size)1478c7683010SCristian Dumitrescu cmd_softnic_pipeline_regwr(struct pmd_internals *softnic,
1479c7683010SCristian Dumitrescu 	char **tokens,
1480c7683010SCristian Dumitrescu 	uint32_t n_tokens,
1481c7683010SCristian Dumitrescu 	char *out,
1482c7683010SCristian Dumitrescu 	size_t out_size)
1483c7683010SCristian Dumitrescu {
1484c7683010SCristian Dumitrescu 	struct pipeline *p;
1485c7683010SCristian Dumitrescu 	const char *pipeline_name, *name;
1486c7683010SCristian Dumitrescu 	uint64_t value;
1487c7683010SCristian Dumitrescu 	uint32_t idx;
1488c7683010SCristian Dumitrescu 	int status;
1489c7683010SCristian Dumitrescu 
1490c7683010SCristian Dumitrescu 	if (n_tokens != 6) {
1491c7683010SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1492c7683010SCristian Dumitrescu 		return;
1493c7683010SCristian Dumitrescu 	}
1494c7683010SCristian Dumitrescu 
1495c7683010SCristian Dumitrescu 	pipeline_name = tokens[1];
1496c7683010SCristian Dumitrescu 	p = softnic_pipeline_find(softnic, pipeline_name);
1497c7683010SCristian Dumitrescu 	if (!p) {
1498c7683010SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
1499c7683010SCristian Dumitrescu 		return;
1500c7683010SCristian Dumitrescu 	}
1501c7683010SCristian Dumitrescu 
1502c7683010SCristian Dumitrescu 	if (strcmp(tokens[2], "regwr")) {
1503c7683010SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "regwr");
1504c7683010SCristian Dumitrescu 		return;
1505c7683010SCristian Dumitrescu 	}
1506c7683010SCristian Dumitrescu 
1507c7683010SCristian Dumitrescu 	name = tokens[3];
1508c7683010SCristian Dumitrescu 
1509c7683010SCristian Dumitrescu 	if (parser_read_uint32(&idx, tokens[4])) {
1510c7683010SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "index");
1511c7683010SCristian Dumitrescu 		return;
1512c7683010SCristian Dumitrescu 	}
1513c7683010SCristian Dumitrescu 
1514c7683010SCristian Dumitrescu 	if (parser_read_uint64(&value, tokens[5])) {
1515c7683010SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "value");
1516c7683010SCristian Dumitrescu 		return;
1517c7683010SCristian Dumitrescu 	}
1518c7683010SCristian Dumitrescu 
1519c7683010SCristian Dumitrescu 	status = rte_swx_ctl_pipeline_regarray_write(p->p, name, idx, value);
1520c7683010SCristian Dumitrescu 	if (status) {
1521c7683010SCristian Dumitrescu 		snprintf(out, out_size, "Command failed.\n");
1522c7683010SCristian Dumitrescu 		return;
1523c7683010SCristian Dumitrescu 	}
1524c7683010SCristian Dumitrescu }
1525c7683010SCristian Dumitrescu 
1526c7683010SCristian Dumitrescu /**
152749b842daSCristian Dumitrescu  * pipeline <pipeline_name> meter profile <profile_name> add cir <cir> pir <pir> cbs <cbs> pbs <pbs>
152849b842daSCristian Dumitrescu  */
152949b842daSCristian Dumitrescu static void
cmd_softnic_pipeline_meter_profile_add(struct pmd_internals * softnic,char ** tokens,uint32_t n_tokens,char * out,size_t out_size)153049b842daSCristian Dumitrescu cmd_softnic_pipeline_meter_profile_add(struct pmd_internals *softnic,
153149b842daSCristian Dumitrescu 	char **tokens,
153249b842daSCristian Dumitrescu 	uint32_t n_tokens,
153349b842daSCristian Dumitrescu 	char *out,
153449b842daSCristian Dumitrescu 	size_t out_size)
153549b842daSCristian Dumitrescu {
153649b842daSCristian Dumitrescu 	struct rte_meter_trtcm_params params;
153749b842daSCristian Dumitrescu 	struct pipeline *p;
153849b842daSCristian Dumitrescu 	const char *profile_name;
153949b842daSCristian Dumitrescu 	int status;
154049b842daSCristian Dumitrescu 
154149b842daSCristian Dumitrescu 	if (n_tokens != 14) {
154249b842daSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
154349b842daSCristian Dumitrescu 		return;
154449b842daSCristian Dumitrescu 	}
154549b842daSCristian Dumitrescu 
154649b842daSCristian Dumitrescu 	p = softnic_pipeline_find(softnic, tokens[1]);
154749b842daSCristian Dumitrescu 	if (!p) {
154849b842daSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
154949b842daSCristian Dumitrescu 		return;
155049b842daSCristian Dumitrescu 	}
155149b842daSCristian Dumitrescu 
155249b842daSCristian Dumitrescu 	if (strcmp(tokens[2], "meter")) {
155349b842daSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "meter");
155449b842daSCristian Dumitrescu 		return;
155549b842daSCristian Dumitrescu 	}
155649b842daSCristian Dumitrescu 
155749b842daSCristian Dumitrescu 	if (strcmp(tokens[3], "profile")) {
155849b842daSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "profile");
155949b842daSCristian Dumitrescu 		return;
156049b842daSCristian Dumitrescu 	}
156149b842daSCristian Dumitrescu 
156249b842daSCristian Dumitrescu 	profile_name = tokens[4];
156349b842daSCristian Dumitrescu 
156449b842daSCristian Dumitrescu 	if (strcmp(tokens[5], "add")) {
156549b842daSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "add");
156649b842daSCristian Dumitrescu 		return;
156749b842daSCristian Dumitrescu 	}
156849b842daSCristian Dumitrescu 
156949b842daSCristian Dumitrescu 	if (strcmp(tokens[6], "cir")) {
157049b842daSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cir");
157149b842daSCristian Dumitrescu 		return;
157249b842daSCristian Dumitrescu 	}
157349b842daSCristian Dumitrescu 
157449b842daSCristian Dumitrescu 	if (parser_read_uint64(&params.cir, tokens[7])) {
157549b842daSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "cir");
157649b842daSCristian Dumitrescu 		return;
157749b842daSCristian Dumitrescu 	}
157849b842daSCristian Dumitrescu 
157949b842daSCristian Dumitrescu 	if (strcmp(tokens[8], "pir")) {
158049b842daSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pir");
158149b842daSCristian Dumitrescu 		return;
158249b842daSCristian Dumitrescu 	}
158349b842daSCristian Dumitrescu 
158449b842daSCristian Dumitrescu 	if (parser_read_uint64(&params.pir, tokens[9])) {
158549b842daSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pir");
158649b842daSCristian Dumitrescu 		return;
158749b842daSCristian Dumitrescu 	}
158849b842daSCristian Dumitrescu 
158949b842daSCristian Dumitrescu 	if (strcmp(tokens[10], "cbs")) {
159049b842daSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cbs");
159149b842daSCristian Dumitrescu 		return;
159249b842daSCristian Dumitrescu 	}
159349b842daSCristian Dumitrescu 
159449b842daSCristian Dumitrescu 	if (parser_read_uint64(&params.cbs, tokens[11])) {
159549b842daSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "cbs");
159649b842daSCristian Dumitrescu 		return;
159749b842daSCristian Dumitrescu 	}
159849b842daSCristian Dumitrescu 
159949b842daSCristian Dumitrescu 	if (strcmp(tokens[12], "pbs")) {
160049b842daSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pbs");
160149b842daSCristian Dumitrescu 		return;
160249b842daSCristian Dumitrescu 	}
160349b842daSCristian Dumitrescu 
160449b842daSCristian Dumitrescu 	if (parser_read_uint64(&params.pbs, tokens[13])) {
160549b842daSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pbs");
160649b842daSCristian Dumitrescu 		return;
160749b842daSCristian Dumitrescu 	}
160849b842daSCristian Dumitrescu 
160949b842daSCristian Dumitrescu 	status = rte_swx_ctl_meter_profile_add(p->p, profile_name, &params);
161049b842daSCristian Dumitrescu 	if (status) {
161149b842daSCristian Dumitrescu 		snprintf(out, out_size, "Command failed.\n");
161249b842daSCristian Dumitrescu 		return;
161349b842daSCristian Dumitrescu 	}
161449b842daSCristian Dumitrescu }
161549b842daSCristian Dumitrescu 
161649b842daSCristian Dumitrescu /**
161749b842daSCristian Dumitrescu  * pipeline <pipeline_name> meter profile <profile_name> delete
161849b842daSCristian Dumitrescu  */
161949b842daSCristian Dumitrescu static void
cmd_softnic_pipeline_meter_profile_delete(struct pmd_internals * softnic,char ** tokens,uint32_t n_tokens,char * out,size_t out_size)162049b842daSCristian Dumitrescu cmd_softnic_pipeline_meter_profile_delete(struct pmd_internals *softnic,
162149b842daSCristian Dumitrescu 	char **tokens,
162249b842daSCristian Dumitrescu 	uint32_t n_tokens,
162349b842daSCristian Dumitrescu 	char *out,
162449b842daSCristian Dumitrescu 	size_t out_size)
162549b842daSCristian Dumitrescu {
162649b842daSCristian Dumitrescu 	struct pipeline *p;
162749b842daSCristian Dumitrescu 	const char *profile_name;
162849b842daSCristian Dumitrescu 	int status;
162949b842daSCristian Dumitrescu 
163049b842daSCristian Dumitrescu 	if (n_tokens != 6) {
163149b842daSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
163249b842daSCristian Dumitrescu 		return;
163349b842daSCristian Dumitrescu 	}
163449b842daSCristian Dumitrescu 
163549b842daSCristian Dumitrescu 	p = softnic_pipeline_find(softnic, tokens[1]);
163649b842daSCristian Dumitrescu 	if (!p) {
163749b842daSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
163849b842daSCristian Dumitrescu 		return;
163949b842daSCristian Dumitrescu 	}
164049b842daSCristian Dumitrescu 
164149b842daSCristian Dumitrescu 	if (strcmp(tokens[2], "meter")) {
164249b842daSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "meter");
164349b842daSCristian Dumitrescu 		return;
164449b842daSCristian Dumitrescu 	}
164549b842daSCristian Dumitrescu 
164649b842daSCristian Dumitrescu 	if (strcmp(tokens[3], "profile")) {
164749b842daSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "profile");
164849b842daSCristian Dumitrescu 		return;
164949b842daSCristian Dumitrescu 	}
165049b842daSCristian Dumitrescu 
165149b842daSCristian Dumitrescu 	profile_name = tokens[4];
165249b842daSCristian Dumitrescu 
165349b842daSCristian Dumitrescu 	if (strcmp(tokens[5], "delete")) {
165449b842daSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "delete");
165549b842daSCristian Dumitrescu 		return;
165649b842daSCristian Dumitrescu 	}
165749b842daSCristian Dumitrescu 
165849b842daSCristian Dumitrescu 	status = rte_swx_ctl_meter_profile_delete(p->p, profile_name);
165949b842daSCristian Dumitrescu 	if (status) {
166049b842daSCristian Dumitrescu 		snprintf(out, out_size, "Command failed.\n");
166149b842daSCristian Dumitrescu 		return;
166249b842daSCristian Dumitrescu 	}
166349b842daSCristian Dumitrescu }
166449b842daSCristian Dumitrescu 
166549b842daSCristian Dumitrescu /**
166649b842daSCristian Dumitrescu  * pipeline <pipeline_name> meter <meter_array_name> from <index0> to <index1> reset
166749b842daSCristian Dumitrescu  */
166849b842daSCristian Dumitrescu static void
cmd_softnic_pipeline_meter_reset(struct pmd_internals * softnic,char ** tokens,uint32_t n_tokens,char * out,size_t out_size)166949b842daSCristian Dumitrescu cmd_softnic_pipeline_meter_reset(struct pmd_internals *softnic,
167049b842daSCristian Dumitrescu 	char **tokens,
167149b842daSCristian Dumitrescu 	uint32_t n_tokens,
167249b842daSCristian Dumitrescu 	char *out,
167349b842daSCristian Dumitrescu 	size_t out_size)
167449b842daSCristian Dumitrescu {
167549b842daSCristian Dumitrescu 	struct pipeline *p;
167649b842daSCristian Dumitrescu 	const char *name;
167749b842daSCristian Dumitrescu 	uint32_t idx0 = 0, idx1 = 0;
167849b842daSCristian Dumitrescu 
167949b842daSCristian Dumitrescu 	if (n_tokens != 9) {
168049b842daSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
168149b842daSCristian Dumitrescu 		return;
168249b842daSCristian Dumitrescu 	}
168349b842daSCristian Dumitrescu 
168449b842daSCristian Dumitrescu 	p = softnic_pipeline_find(softnic, tokens[1]);
168549b842daSCristian Dumitrescu 	if (!p) {
168649b842daSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
168749b842daSCristian Dumitrescu 		return;
168849b842daSCristian Dumitrescu 	}
168949b842daSCristian Dumitrescu 
169049b842daSCristian Dumitrescu 	if (strcmp(tokens[2], "meter")) {
169149b842daSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "meter");
169249b842daSCristian Dumitrescu 		return;
169349b842daSCristian Dumitrescu 	}
169449b842daSCristian Dumitrescu 
169549b842daSCristian Dumitrescu 	name = tokens[3];
169649b842daSCristian Dumitrescu 
169749b842daSCristian Dumitrescu 	if (strcmp(tokens[4], "from")) {
169849b842daSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "from");
169949b842daSCristian Dumitrescu 		return;
170049b842daSCristian Dumitrescu 	}
170149b842daSCristian Dumitrescu 
170249b842daSCristian Dumitrescu 	if (parser_read_uint32(&idx0, tokens[5])) {
170349b842daSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "index0");
170449b842daSCristian Dumitrescu 		return;
170549b842daSCristian Dumitrescu 	}
170649b842daSCristian Dumitrescu 
170749b842daSCristian Dumitrescu 	if (strcmp(tokens[6], "to")) {
170849b842daSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "to");
170949b842daSCristian Dumitrescu 		return;
171049b842daSCristian Dumitrescu 	}
171149b842daSCristian Dumitrescu 
171249b842daSCristian Dumitrescu 	if (parser_read_uint32(&idx1, tokens[7]) || idx1 < idx0) {
171349b842daSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "index1");
171449b842daSCristian Dumitrescu 		return;
171549b842daSCristian Dumitrescu 	}
171649b842daSCristian Dumitrescu 
171749b842daSCristian Dumitrescu 	if (strcmp(tokens[8], "reset")) {
171849b842daSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "reset");
171949b842daSCristian Dumitrescu 		return;
172049b842daSCristian Dumitrescu 	}
172149b842daSCristian Dumitrescu 
172249b842daSCristian Dumitrescu 	for ( ; idx0 <= idx1; idx0++) {
172349b842daSCristian Dumitrescu 		int status;
172449b842daSCristian Dumitrescu 
172549b842daSCristian Dumitrescu 		status = rte_swx_ctl_meter_reset(p->p, name, idx0);
172649b842daSCristian Dumitrescu 		if (status) {
172749b842daSCristian Dumitrescu 			snprintf(out, out_size, "Command failed for index %u.\n", idx0);
172849b842daSCristian Dumitrescu 			return;
172949b842daSCristian Dumitrescu 		}
173049b842daSCristian Dumitrescu 	}
173149b842daSCristian Dumitrescu }
173249b842daSCristian Dumitrescu 
173349b842daSCristian Dumitrescu /**
173449b842daSCristian Dumitrescu  * pipeline <pipeline_name> meter <meter_array_name> from <index0> to <index1> set
173549b842daSCristian Dumitrescu  *	profile <profile_name>
173649b842daSCristian Dumitrescu  */
173749b842daSCristian Dumitrescu static void
cmd_softnic_pipeline_meter_set(struct pmd_internals * softnic,char ** tokens,uint32_t n_tokens,char * out,size_t out_size)173849b842daSCristian Dumitrescu cmd_softnic_pipeline_meter_set(struct pmd_internals *softnic,
173949b842daSCristian Dumitrescu 	char **tokens,
174049b842daSCristian Dumitrescu 	uint32_t n_tokens,
174149b842daSCristian Dumitrescu 	char *out,
174249b842daSCristian Dumitrescu 	size_t out_size)
174349b842daSCristian Dumitrescu {
174449b842daSCristian Dumitrescu 	struct pipeline *p;
174549b842daSCristian Dumitrescu 	const char *name, *profile_name;
174649b842daSCristian Dumitrescu 	uint32_t idx0 = 0, idx1 = 0;
174749b842daSCristian Dumitrescu 
174849b842daSCristian Dumitrescu 	if (n_tokens != 11) {
174949b842daSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
175049b842daSCristian Dumitrescu 		return;
175149b842daSCristian Dumitrescu 	}
175249b842daSCristian Dumitrescu 
175349b842daSCristian Dumitrescu 	p = softnic_pipeline_find(softnic, tokens[1]);
175449b842daSCristian Dumitrescu 	if (!p) {
175549b842daSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
175649b842daSCristian Dumitrescu 		return;
175749b842daSCristian Dumitrescu 	}
175849b842daSCristian Dumitrescu 
175949b842daSCristian Dumitrescu 	if (strcmp(tokens[2], "meter")) {
176049b842daSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "meter");
176149b842daSCristian Dumitrescu 		return;
176249b842daSCristian Dumitrescu 	}
176349b842daSCristian Dumitrescu 
176449b842daSCristian Dumitrescu 	name = tokens[3];
176549b842daSCristian Dumitrescu 
176649b842daSCristian Dumitrescu 	if (strcmp(tokens[4], "from")) {
176749b842daSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "from");
176849b842daSCristian Dumitrescu 		return;
176949b842daSCristian Dumitrescu 	}
177049b842daSCristian Dumitrescu 
177149b842daSCristian Dumitrescu 	if (parser_read_uint32(&idx0, tokens[5])) {
177249b842daSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "index0");
177349b842daSCristian Dumitrescu 		return;
177449b842daSCristian Dumitrescu 	}
177549b842daSCristian Dumitrescu 
177649b842daSCristian Dumitrescu 	if (strcmp(tokens[6], "to")) {
177749b842daSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "to");
177849b842daSCristian Dumitrescu 		return;
177949b842daSCristian Dumitrescu 	}
178049b842daSCristian Dumitrescu 
178149b842daSCristian Dumitrescu 	if (parser_read_uint32(&idx1, tokens[7]) || idx1 < idx0) {
178249b842daSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "index1");
178349b842daSCristian Dumitrescu 		return;
178449b842daSCristian Dumitrescu 	}
178549b842daSCristian Dumitrescu 
178649b842daSCristian Dumitrescu 	if (strcmp(tokens[8], "set")) {
178749b842daSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "set");
178849b842daSCristian Dumitrescu 		return;
178949b842daSCristian Dumitrescu 	}
179049b842daSCristian Dumitrescu 
179149b842daSCristian Dumitrescu 	if (strcmp(tokens[9], "profile")) {
179249b842daSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "profile");
179349b842daSCristian Dumitrescu 		return;
179449b842daSCristian Dumitrescu 	}
179549b842daSCristian Dumitrescu 
179649b842daSCristian Dumitrescu 	profile_name = tokens[10];
179749b842daSCristian Dumitrescu 
179849b842daSCristian Dumitrescu 	for ( ; idx0 <= idx1; idx0++) {
179949b842daSCristian Dumitrescu 		int status;
180049b842daSCristian Dumitrescu 
180149b842daSCristian Dumitrescu 		status = rte_swx_ctl_meter_set(p->p, name, idx0, profile_name);
180249b842daSCristian Dumitrescu 		if (status) {
180349b842daSCristian Dumitrescu 			snprintf(out, out_size, "Command failed for index %u.\n", idx0);
180449b842daSCristian Dumitrescu 			return;
180549b842daSCristian Dumitrescu 		}
180649b842daSCristian Dumitrescu 	}
180749b842daSCristian Dumitrescu }
180849b842daSCristian Dumitrescu 
180949b842daSCristian Dumitrescu /**
181049b842daSCristian Dumitrescu  * pipeline <pipeline_name> meter <meter_array_name> from <index0> to <index1> stats
181149b842daSCristian Dumitrescu  */
181249b842daSCristian Dumitrescu static void
cmd_softnic_pipeline_meter_stats(struct pmd_internals * softnic,char ** tokens,uint32_t n_tokens,char * out,size_t out_size)181349b842daSCristian Dumitrescu cmd_softnic_pipeline_meter_stats(struct pmd_internals *softnic,
181449b842daSCristian Dumitrescu 	char **tokens,
181549b842daSCristian Dumitrescu 	uint32_t n_tokens,
181649b842daSCristian Dumitrescu 	char *out,
181749b842daSCristian Dumitrescu 	size_t out_size)
181849b842daSCristian Dumitrescu {
181949b842daSCristian Dumitrescu 	struct rte_swx_ctl_meter_stats stats;
182049b842daSCristian Dumitrescu 	struct pipeline *p;
182149b842daSCristian Dumitrescu 	const char *name;
182249b842daSCristian Dumitrescu 	uint32_t idx0 = 0, idx1 = 0;
182349b842daSCristian Dumitrescu 
182449b842daSCristian Dumitrescu 	if (n_tokens != 9) {
182549b842daSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
182649b842daSCristian Dumitrescu 		return;
182749b842daSCristian Dumitrescu 	}
182849b842daSCristian Dumitrescu 
182949b842daSCristian Dumitrescu 	p = softnic_pipeline_find(softnic, tokens[1]);
183049b842daSCristian Dumitrescu 	if (!p) {
183149b842daSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
183249b842daSCristian Dumitrescu 		return;
183349b842daSCristian Dumitrescu 	}
183449b842daSCristian Dumitrescu 
183549b842daSCristian Dumitrescu 	if (strcmp(tokens[2], "meter")) {
183649b842daSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "meter");
183749b842daSCristian Dumitrescu 		return;
183849b842daSCristian Dumitrescu 	}
183949b842daSCristian Dumitrescu 
184049b842daSCristian Dumitrescu 	name = tokens[3];
184149b842daSCristian Dumitrescu 
184249b842daSCristian Dumitrescu 	if (strcmp(tokens[4], "from")) {
184349b842daSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "from");
184449b842daSCristian Dumitrescu 		return;
184549b842daSCristian Dumitrescu 	}
184649b842daSCristian Dumitrescu 
184749b842daSCristian Dumitrescu 	if (parser_read_uint32(&idx0, tokens[5])) {
184849b842daSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "index0");
184949b842daSCristian Dumitrescu 		return;
185049b842daSCristian Dumitrescu 	}
185149b842daSCristian Dumitrescu 
185249b842daSCristian Dumitrescu 	if (strcmp(tokens[6], "to")) {
185349b842daSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "to");
185449b842daSCristian Dumitrescu 		return;
185549b842daSCristian Dumitrescu 	}
185649b842daSCristian Dumitrescu 
185749b842daSCristian Dumitrescu 	if (parser_read_uint32(&idx1, tokens[7]) || idx1 < idx0) {
185849b842daSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "index1");
185949b842daSCristian Dumitrescu 		return;
186049b842daSCristian Dumitrescu 	}
186149b842daSCristian Dumitrescu 
186249b842daSCristian Dumitrescu 	if (strcmp(tokens[8], "stats")) {
186349b842daSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "stats");
186449b842daSCristian Dumitrescu 		return;
186549b842daSCristian Dumitrescu 	}
186649b842daSCristian Dumitrescu 
186749b842daSCristian Dumitrescu 	/* Table header. */
186849b842daSCristian Dumitrescu 	snprintf(out, out_size, "+-%7s-+-%16s-+-%16s-+-%16s-+-%16s-+-%16s-+-%16s-+\n",
186949b842daSCristian Dumitrescu 		 "-------",
187049b842daSCristian Dumitrescu 		 "----------------", "----------------", "----------------",
187149b842daSCristian Dumitrescu 		 "----------------", "----------------", "----------------");
187249b842daSCristian Dumitrescu 	out_size -= strlen(out);
187349b842daSCristian Dumitrescu 	out += strlen(out);
187449b842daSCristian Dumitrescu 
187549b842daSCristian Dumitrescu 	snprintf(out, out_size, "| %4s | %16s | %16s | %16s | %16s | %16s | %16s |\n",
187649b842daSCristian Dumitrescu 		 "METER #",
187749b842daSCristian Dumitrescu 		 "GREEN (packets)", "YELLOW (packets)", "RED (packets)",
187849b842daSCristian Dumitrescu 		 "GREEN (bytes)", "YELLOW (bytes)", "RED (bytes)");
187949b842daSCristian Dumitrescu 	out_size -= strlen(out);
188049b842daSCristian Dumitrescu 	out += strlen(out);
188149b842daSCristian Dumitrescu 
188249b842daSCristian Dumitrescu 	snprintf(out, out_size, "+-%7s-+-%16s-+-%16s-+-%16s-+-%16s-+-%16s-+-%16s-+\n",
188349b842daSCristian Dumitrescu 		 "-------",
188449b842daSCristian Dumitrescu 		 "----------------", "----------------", "----------------",
188549b842daSCristian Dumitrescu 		 "----------------", "----------------", "----------------");
188649b842daSCristian Dumitrescu 	out_size -= strlen(out);
188749b842daSCristian Dumitrescu 	out += strlen(out);
188849b842daSCristian Dumitrescu 
188949b842daSCristian Dumitrescu 	/* Table rows. */
189049b842daSCristian Dumitrescu 	for ( ; idx0 <= idx1; idx0++) {
189149b842daSCristian Dumitrescu 		int status;
189249b842daSCristian Dumitrescu 
189349b842daSCristian Dumitrescu 		status = rte_swx_ctl_meter_stats_read(p->p, name, idx0, &stats);
189449b842daSCristian Dumitrescu 		if (status) {
189549b842daSCristian Dumitrescu 			snprintf(out, out_size, "Pipeline meter stats error at index %u.\n", idx0);
189649b842daSCristian Dumitrescu 			out_size -= strlen(out);
189749b842daSCristian Dumitrescu 			out += strlen(out);
189849b842daSCristian Dumitrescu 			return;
189949b842daSCristian Dumitrescu 		}
190049b842daSCristian Dumitrescu 
190149b842daSCristian Dumitrescu 		snprintf(out, out_size, "| %7d | %16" PRIx64 " | %16" PRIx64 " | %16" PRIx64
190249b842daSCristian Dumitrescu 			 " | %16" PRIx64 " | %16" PRIx64 " | %16" PRIx64 " |\n",
190349b842daSCristian Dumitrescu 			 idx0,
190449b842daSCristian Dumitrescu 			 stats.n_pkts[RTE_COLOR_GREEN],
190549b842daSCristian Dumitrescu 			 stats.n_pkts[RTE_COLOR_YELLOW],
190649b842daSCristian Dumitrescu 			 stats.n_pkts[RTE_COLOR_RED],
190749b842daSCristian Dumitrescu 			 stats.n_bytes[RTE_COLOR_GREEN],
190849b842daSCristian Dumitrescu 			 stats.n_bytes[RTE_COLOR_YELLOW],
190949b842daSCristian Dumitrescu 			 stats.n_bytes[RTE_COLOR_RED]);
191049b842daSCristian Dumitrescu 		out_size -= strlen(out);
191149b842daSCristian Dumitrescu 		out += strlen(out);
191249b842daSCristian Dumitrescu 	}
191349b842daSCristian Dumitrescu }
191449b842daSCristian Dumitrescu 
191549b842daSCristian Dumitrescu /**
19164e141bf4SCristian Dumitrescu  * pipeline <pipeline_name> stats
19174e141bf4SCristian Dumitrescu  */
19184e141bf4SCristian Dumitrescu static void
cmd_softnic_pipeline_stats(struct pmd_internals * softnic,char ** tokens,uint32_t n_tokens,char * out,size_t out_size)19194e141bf4SCristian Dumitrescu cmd_softnic_pipeline_stats(struct pmd_internals *softnic,
19204e141bf4SCristian Dumitrescu 	char **tokens,
19214e141bf4SCristian Dumitrescu 	uint32_t n_tokens,
19224e141bf4SCristian Dumitrescu 	char *out,
19234e141bf4SCristian Dumitrescu 	size_t out_size)
19244e141bf4SCristian Dumitrescu {
19254e141bf4SCristian Dumitrescu 	struct rte_swx_ctl_pipeline_info info;
19264e141bf4SCristian Dumitrescu 	struct pipeline *p;
19274e141bf4SCristian Dumitrescu 	uint32_t i;
19284e141bf4SCristian Dumitrescu 	int status;
19294e141bf4SCristian Dumitrescu 
19304e141bf4SCristian Dumitrescu 	if (n_tokens != 3) {
19314e141bf4SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
19324e141bf4SCristian Dumitrescu 		return;
19334e141bf4SCristian Dumitrescu 	}
19344e141bf4SCristian Dumitrescu 
19354e141bf4SCristian Dumitrescu 	p = softnic_pipeline_find(softnic, tokens[1]);
19364e141bf4SCristian Dumitrescu 	if (!p) {
19374e141bf4SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
19384e141bf4SCristian Dumitrescu 		return;
19394e141bf4SCristian Dumitrescu 	}
19404e141bf4SCristian Dumitrescu 
19414e141bf4SCristian Dumitrescu 	if (strcmp(tokens[2], "stats")) {
19424e141bf4SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "stats");
19434e141bf4SCristian Dumitrescu 		return;
19444e141bf4SCristian Dumitrescu 	}
19454e141bf4SCristian Dumitrescu 
19464e141bf4SCristian Dumitrescu 	status = rte_swx_ctl_pipeline_info_get(p->p, &info);
19474e141bf4SCristian Dumitrescu 	if (status) {
19484e141bf4SCristian Dumitrescu 		snprintf(out, out_size, "Pipeline info get error.");
19494e141bf4SCristian Dumitrescu 		return;
19504e141bf4SCristian Dumitrescu 	}
19514e141bf4SCristian Dumitrescu 
19524e141bf4SCristian Dumitrescu 	snprintf(out, out_size, "Input ports:\n");
19534e141bf4SCristian Dumitrescu 	out_size -= strlen(out);
19544e141bf4SCristian Dumitrescu 	out += strlen(out);
19554e141bf4SCristian Dumitrescu 
19564e141bf4SCristian Dumitrescu 	for (i = 0; i < info.n_ports_in; i++) {
19574e141bf4SCristian Dumitrescu 		struct rte_swx_port_in_stats stats;
19584e141bf4SCristian Dumitrescu 
19594e141bf4SCristian Dumitrescu 		rte_swx_ctl_pipeline_port_in_stats_read(p->p, i, &stats);
19604e141bf4SCristian Dumitrescu 
19614e141bf4SCristian Dumitrescu 		snprintf(out, out_size, "\tPort %u:"
19624e141bf4SCristian Dumitrescu 			" packets %" PRIu64
19634e141bf4SCristian Dumitrescu 			" bytes %" PRIu64
19644e141bf4SCristian Dumitrescu 			" empty %" PRIu64 "\n",
19654e141bf4SCristian Dumitrescu 			i, stats.n_pkts, stats.n_bytes, stats.n_empty);
19664e141bf4SCristian Dumitrescu 		out_size -= strlen(out);
19674e141bf4SCristian Dumitrescu 		out += strlen(out);
19684e141bf4SCristian Dumitrescu 	}
19694e141bf4SCristian Dumitrescu 
19704e141bf4SCristian Dumitrescu 	snprintf(out, out_size, "\nOutput ports:\n");
19714e141bf4SCristian Dumitrescu 	out_size -= strlen(out);
19724e141bf4SCristian Dumitrescu 	out += strlen(out);
19734e141bf4SCristian Dumitrescu 
19744e141bf4SCristian Dumitrescu 	for (i = 0; i < info.n_ports_out; i++) {
19754e141bf4SCristian Dumitrescu 		struct rte_swx_port_out_stats stats;
19764e141bf4SCristian Dumitrescu 
19774e141bf4SCristian Dumitrescu 		rte_swx_ctl_pipeline_port_out_stats_read(p->p, i, &stats);
19784e141bf4SCristian Dumitrescu 
19794e141bf4SCristian Dumitrescu 		if (i != info.n_ports_out - 1)
19804e141bf4SCristian Dumitrescu 			snprintf(out, out_size, "\tPort %u:", i);
19814e141bf4SCristian Dumitrescu 		else
19824e141bf4SCristian Dumitrescu 			snprintf(out, out_size, "\tDROP:");
19834e141bf4SCristian Dumitrescu 
19844e141bf4SCristian Dumitrescu 		out_size -= strlen(out);
19854e141bf4SCristian Dumitrescu 		out += strlen(out);
19864e141bf4SCristian Dumitrescu 
19874e141bf4SCristian Dumitrescu 		snprintf(out,
19884e141bf4SCristian Dumitrescu 			out_size,
19894e141bf4SCristian Dumitrescu 			" packets %" PRIu64
19904e141bf4SCristian Dumitrescu 			" bytes %" PRIu64
1991d2384afbSCristian Dumitrescu 			" packets dropped %" PRIu64
1992d2384afbSCristian Dumitrescu 			" bytes dropped %" PRIu64
19934e141bf4SCristian Dumitrescu 			" clone %" PRIu64
19944e141bf4SCristian Dumitrescu 			" clonerr %" PRIu64 "\n",
19954e141bf4SCristian Dumitrescu 			stats.n_pkts,
19964e141bf4SCristian Dumitrescu 			stats.n_bytes,
1997d2384afbSCristian Dumitrescu 			stats.n_pkts_drop,
1998d2384afbSCristian Dumitrescu 			stats.n_bytes_drop,
19994e141bf4SCristian Dumitrescu 			stats.n_pkts_clone,
20004e141bf4SCristian Dumitrescu 			stats.n_pkts_clone_err);
20014e141bf4SCristian Dumitrescu 
20024e141bf4SCristian Dumitrescu 		out_size -= strlen(out);
20034e141bf4SCristian Dumitrescu 		out += strlen(out);
20044e141bf4SCristian Dumitrescu 	}
20054e141bf4SCristian Dumitrescu 
20064e141bf4SCristian Dumitrescu 	snprintf(out, out_size, "\nTables:\n");
20074e141bf4SCristian Dumitrescu 	out_size -= strlen(out);
20084e141bf4SCristian Dumitrescu 	out += strlen(out);
20094e141bf4SCristian Dumitrescu 
20104e141bf4SCristian Dumitrescu 	for (i = 0; i < info.n_tables; i++) {
20114e141bf4SCristian Dumitrescu 		struct rte_swx_ctl_table_info table_info;
20124e141bf4SCristian Dumitrescu 		uint64_t n_pkts_action[info.n_actions];
20134e141bf4SCristian Dumitrescu 		struct rte_swx_table_stats stats = {
20144e141bf4SCristian Dumitrescu 			.n_pkts_hit = 0,
20154e141bf4SCristian Dumitrescu 			.n_pkts_miss = 0,
20164e141bf4SCristian Dumitrescu 			.n_pkts_action = n_pkts_action,
20174e141bf4SCristian Dumitrescu 		};
20184e141bf4SCristian Dumitrescu 		uint32_t j;
20194e141bf4SCristian Dumitrescu 
20204e141bf4SCristian Dumitrescu 		status = rte_swx_ctl_table_info_get(p->p, i, &table_info);
20214e141bf4SCristian Dumitrescu 		if (status) {
20224e141bf4SCristian Dumitrescu 			snprintf(out, out_size, "Table info get error.");
20234e141bf4SCristian Dumitrescu 			return;
20244e141bf4SCristian Dumitrescu 		}
20254e141bf4SCristian Dumitrescu 
20264e141bf4SCristian Dumitrescu 		status = rte_swx_ctl_pipeline_table_stats_read(p->p, table_info.name, &stats);
20274e141bf4SCristian Dumitrescu 		if (status) {
20284e141bf4SCristian Dumitrescu 			snprintf(out, out_size, "Table stats read error.");
20294e141bf4SCristian Dumitrescu 			return;
20304e141bf4SCristian Dumitrescu 		}
20314e141bf4SCristian Dumitrescu 
20324e141bf4SCristian Dumitrescu 		snprintf(out, out_size, "\tTable %s:\n"
20334e141bf4SCristian Dumitrescu 			"\t\tHit (packets): %" PRIu64 "\n"
20344e141bf4SCristian Dumitrescu 			"\t\tMiss (packets): %" PRIu64 "\n",
20354e141bf4SCristian Dumitrescu 			table_info.name,
20364e141bf4SCristian Dumitrescu 			stats.n_pkts_hit,
20374e141bf4SCristian Dumitrescu 			stats.n_pkts_miss);
20384e141bf4SCristian Dumitrescu 		out_size -= strlen(out);
20394e141bf4SCristian Dumitrescu 		out += strlen(out);
20404e141bf4SCristian Dumitrescu 
20414e141bf4SCristian Dumitrescu 		for (j = 0; j < info.n_actions; j++) {
20424e141bf4SCristian Dumitrescu 			struct rte_swx_ctl_action_info action_info;
20434e141bf4SCristian Dumitrescu 
20444e141bf4SCristian Dumitrescu 			status = rte_swx_ctl_action_info_get(p->p, j, &action_info);
20454e141bf4SCristian Dumitrescu 			if (status) {
20464e141bf4SCristian Dumitrescu 				snprintf(out, out_size, "Action info get error.");
20474e141bf4SCristian Dumitrescu 				return;
20484e141bf4SCristian Dumitrescu 			}
20494e141bf4SCristian Dumitrescu 
20504e141bf4SCristian Dumitrescu 			snprintf(out, out_size, "\t\tAction %s (packets): %" PRIu64 "\n",
20514e141bf4SCristian Dumitrescu 				action_info.name,
20524e141bf4SCristian Dumitrescu 				stats.n_pkts_action[j]);
20534e141bf4SCristian Dumitrescu 			out_size -= strlen(out);
20544e141bf4SCristian Dumitrescu 			out += strlen(out);
20554e141bf4SCristian Dumitrescu 		}
20564e141bf4SCristian Dumitrescu 	}
20574e141bf4SCristian Dumitrescu 
20584e141bf4SCristian Dumitrescu 	snprintf(out, out_size, "\nLearner tables:\n");
20594e141bf4SCristian Dumitrescu 	out_size -= strlen(out);
20604e141bf4SCristian Dumitrescu 	out += strlen(out);
20614e141bf4SCristian Dumitrescu 
20624e141bf4SCristian Dumitrescu 	for (i = 0; i < info.n_learners; i++) {
20634e141bf4SCristian Dumitrescu 		struct rte_swx_ctl_learner_info learner_info;
20644e141bf4SCristian Dumitrescu 		uint64_t n_pkts_action[info.n_actions];
20654e141bf4SCristian Dumitrescu 		struct rte_swx_learner_stats stats = {
20664e141bf4SCristian Dumitrescu 			.n_pkts_hit = 0,
20674e141bf4SCristian Dumitrescu 			.n_pkts_miss = 0,
20684e141bf4SCristian Dumitrescu 			.n_pkts_action = n_pkts_action,
20694e141bf4SCristian Dumitrescu 		};
20704e141bf4SCristian Dumitrescu 		uint32_t j;
20714e141bf4SCristian Dumitrescu 
20724e141bf4SCristian Dumitrescu 		status = rte_swx_ctl_learner_info_get(p->p, i, &learner_info);
20734e141bf4SCristian Dumitrescu 		if (status) {
20744e141bf4SCristian Dumitrescu 			snprintf(out, out_size, "Learner table info get error.");
20754e141bf4SCristian Dumitrescu 			return;
20764e141bf4SCristian Dumitrescu 		}
20774e141bf4SCristian Dumitrescu 
20784e141bf4SCristian Dumitrescu 		status = rte_swx_ctl_pipeline_learner_stats_read(p->p, learner_info.name, &stats);
20794e141bf4SCristian Dumitrescu 		if (status) {
20804e141bf4SCristian Dumitrescu 			snprintf(out, out_size, "Learner table stats read error.");
20814e141bf4SCristian Dumitrescu 			return;
20824e141bf4SCristian Dumitrescu 		}
20834e141bf4SCristian Dumitrescu 
20844e141bf4SCristian Dumitrescu 		snprintf(out, out_size, "\tLearner table %s:\n"
20854e141bf4SCristian Dumitrescu 			"\t\tHit (packets): %" PRIu64 "\n"
20864e141bf4SCristian Dumitrescu 			"\t\tMiss (packets): %" PRIu64 "\n"
20874e141bf4SCristian Dumitrescu 			"\t\tLearn OK (packets): %" PRIu64 "\n"
20884e141bf4SCristian Dumitrescu 			"\t\tLearn error (packets): %" PRIu64 "\n"
20894e141bf4SCristian Dumitrescu 			"\t\tRearm (packets): %" PRIu64 "\n"
20904e141bf4SCristian Dumitrescu 			"\t\tForget (packets): %" PRIu64 "\n",
20914e141bf4SCristian Dumitrescu 			learner_info.name,
20924e141bf4SCristian Dumitrescu 			stats.n_pkts_hit,
20934e141bf4SCristian Dumitrescu 			stats.n_pkts_miss,
20944e141bf4SCristian Dumitrescu 			stats.n_pkts_learn_ok,
20954e141bf4SCristian Dumitrescu 			stats.n_pkts_learn_err,
20964e141bf4SCristian Dumitrescu 			stats.n_pkts_rearm,
20974e141bf4SCristian Dumitrescu 			stats.n_pkts_forget);
20984e141bf4SCristian Dumitrescu 		out_size -= strlen(out);
20994e141bf4SCristian Dumitrescu 		out += strlen(out);
21004e141bf4SCristian Dumitrescu 
21014e141bf4SCristian Dumitrescu 		for (j = 0; j < info.n_actions; j++) {
21024e141bf4SCristian Dumitrescu 			struct rte_swx_ctl_action_info action_info;
21034e141bf4SCristian Dumitrescu 
21044e141bf4SCristian Dumitrescu 			status = rte_swx_ctl_action_info_get(p->p, j, &action_info);
21054e141bf4SCristian Dumitrescu 			if (status) {
21064e141bf4SCristian Dumitrescu 				snprintf(out, out_size, "Action info get error.");
21074e141bf4SCristian Dumitrescu 				return;
21084e141bf4SCristian Dumitrescu 			}
21094e141bf4SCristian Dumitrescu 
21104e141bf4SCristian Dumitrescu 			snprintf(out, out_size, "\t\tAction %s (packets): %" PRIu64 "\n",
21114e141bf4SCristian Dumitrescu 				action_info.name,
21124e141bf4SCristian Dumitrescu 				stats.n_pkts_action[j]);
21134e141bf4SCristian Dumitrescu 			out_size -= strlen(out);
21144e141bf4SCristian Dumitrescu 			out += strlen(out);
21154e141bf4SCristian Dumitrescu 		}
21164e141bf4SCristian Dumitrescu 	}
21174e141bf4SCristian Dumitrescu }
21184e141bf4SCristian Dumitrescu 
21194e141bf4SCristian Dumitrescu /**
2120de0a728aSCristian Dumitrescu  * pipeline <pipeline_name> mirror session <session_id> port <port_id> clone fast | slow
2121de0a728aSCristian Dumitrescu  *	truncate <truncation_length>
2122de0a728aSCristian Dumitrescu  */
2123de0a728aSCristian Dumitrescu static void
cmd_softnic_pipeline_mirror_session(struct pmd_internals * softnic,char ** tokens,uint32_t n_tokens,char * out,size_t out_size)2124de0a728aSCristian Dumitrescu cmd_softnic_pipeline_mirror_session(struct pmd_internals *softnic,
2125de0a728aSCristian Dumitrescu 	char **tokens,
2126de0a728aSCristian Dumitrescu 	uint32_t n_tokens,
2127de0a728aSCristian Dumitrescu 	char *out,
2128de0a728aSCristian Dumitrescu 	size_t out_size)
2129de0a728aSCristian Dumitrescu {
2130de0a728aSCristian Dumitrescu 	struct rte_swx_pipeline_mirroring_session_params params;
2131de0a728aSCristian Dumitrescu 	struct pipeline *p;
2132de0a728aSCristian Dumitrescu 	uint32_t session_id = 0;
2133de0a728aSCristian Dumitrescu 	int status;
2134de0a728aSCristian Dumitrescu 
2135de0a728aSCristian Dumitrescu 	if (n_tokens != 11) {
2136de0a728aSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
2137de0a728aSCristian Dumitrescu 		return;
2138de0a728aSCristian Dumitrescu 	}
2139de0a728aSCristian Dumitrescu 
2140de0a728aSCristian Dumitrescu 	if (strcmp(tokens[0], "pipeline")) {
2141de0a728aSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pipeline");
2142de0a728aSCristian Dumitrescu 		return;
2143de0a728aSCristian Dumitrescu 	}
2144de0a728aSCristian Dumitrescu 
2145de0a728aSCristian Dumitrescu 	p = softnic_pipeline_find(softnic, tokens[1]);
2146de0a728aSCristian Dumitrescu 	if (!p) {
2147de0a728aSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
2148de0a728aSCristian Dumitrescu 		return;
2149de0a728aSCristian Dumitrescu 	}
2150de0a728aSCristian Dumitrescu 
2151de0a728aSCristian Dumitrescu 	if (strcmp(tokens[2], "mirror")) {
2152de0a728aSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "mirror");
2153de0a728aSCristian Dumitrescu 		return;
2154de0a728aSCristian Dumitrescu 	}
2155de0a728aSCristian Dumitrescu 
2156de0a728aSCristian Dumitrescu 	if (strcmp(tokens[3], "session")) {
2157de0a728aSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "session");
2158de0a728aSCristian Dumitrescu 		return;
2159de0a728aSCristian Dumitrescu 	}
2160de0a728aSCristian Dumitrescu 
2161de0a728aSCristian Dumitrescu 	if (parser_read_uint32(&session_id, tokens[4])) {
2162de0a728aSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "session_id");
2163de0a728aSCristian Dumitrescu 		return;
2164de0a728aSCristian Dumitrescu 	}
2165de0a728aSCristian Dumitrescu 
2166de0a728aSCristian Dumitrescu 	if (strcmp(tokens[5], "port")) {
2167de0a728aSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
2168de0a728aSCristian Dumitrescu 		return;
2169de0a728aSCristian Dumitrescu 	}
2170de0a728aSCristian Dumitrescu 
2171de0a728aSCristian Dumitrescu 	if (parser_read_uint32(&params.port_id, tokens[6])) {
2172de0a728aSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
2173de0a728aSCristian Dumitrescu 		return;
2174de0a728aSCristian Dumitrescu 	}
2175de0a728aSCristian Dumitrescu 
2176de0a728aSCristian Dumitrescu 	if (strcmp(tokens[7], "clone")) {
2177de0a728aSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "clone");
2178de0a728aSCristian Dumitrescu 		return;
2179de0a728aSCristian Dumitrescu 	}
2180de0a728aSCristian Dumitrescu 
2181de0a728aSCristian Dumitrescu 	if (!strcmp(tokens[8], "fast")) {
2182de0a728aSCristian Dumitrescu 		params.fast_clone = 1;
2183de0a728aSCristian Dumitrescu 	} else if (!strcmp(tokens[8], "slow")) {
2184de0a728aSCristian Dumitrescu 		params.fast_clone = 0;
2185de0a728aSCristian Dumitrescu 	} else {
2186de0a728aSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "clone");
2187de0a728aSCristian Dumitrescu 		return;
2188de0a728aSCristian Dumitrescu 	}
2189de0a728aSCristian Dumitrescu 
2190de0a728aSCristian Dumitrescu 	if (strcmp(tokens[9], "truncate")) {
2191de0a728aSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "truncate");
2192de0a728aSCristian Dumitrescu 		return;
2193de0a728aSCristian Dumitrescu 	}
2194de0a728aSCristian Dumitrescu 
2195de0a728aSCristian Dumitrescu 	if (parser_read_uint32(&params.truncation_length, tokens[10])) {
2196de0a728aSCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "truncation_length");
2197de0a728aSCristian Dumitrescu 		return;
2198de0a728aSCristian Dumitrescu 	}
2199de0a728aSCristian Dumitrescu 
2200de0a728aSCristian Dumitrescu 	status = rte_swx_ctl_pipeline_mirroring_session_set(p->p, session_id, &params);
2201de0a728aSCristian Dumitrescu 	if (status) {
2202de0a728aSCristian Dumitrescu 		snprintf(out, out_size, "Command failed!\n");
2203de0a728aSCristian Dumitrescu 		return;
2204de0a728aSCristian Dumitrescu 	}
2205de0a728aSCristian Dumitrescu }
2206de0a728aSCristian Dumitrescu 
2207de0a728aSCristian Dumitrescu /**
2208e3be2495SCristian Dumitrescu  * thread <thread_id> pipeline <pipeline_name> enable [ period <timer_period_ms> ]
220970709c78SJasvinder Singh  */
221070709c78SJasvinder Singh static void
cmd_softnic_thread_pipeline_enable(struct pmd_internals * softnic,char ** tokens,uint32_t n_tokens,char * out,size_t out_size)221170709c78SJasvinder Singh cmd_softnic_thread_pipeline_enable(struct pmd_internals *softnic,
221270709c78SJasvinder Singh 	char **tokens,
221370709c78SJasvinder Singh 	uint32_t n_tokens,
221470709c78SJasvinder Singh 	char *out,
221570709c78SJasvinder Singh 	size_t out_size)
221670709c78SJasvinder Singh {
221770709c78SJasvinder Singh 	char *pipeline_name;
2218fa0a52a7SCristian Dumitrescu 	struct pipeline *p;
221970709c78SJasvinder Singh 	uint32_t thread_id;
222070709c78SJasvinder Singh 	int status;
222170709c78SJasvinder Singh 
222270709c78SJasvinder Singh 	if (n_tokens != 5) {
222370709c78SJasvinder Singh 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
222470709c78SJasvinder Singh 		return;
222570709c78SJasvinder Singh 	}
222670709c78SJasvinder Singh 
2227d5854eb4SCristian Dumitrescu 	if (parser_read_uint32(&thread_id, tokens[1]) != 0) {
222870709c78SJasvinder Singh 		snprintf(out, out_size, MSG_ARG_INVALID, "thread_id");
222970709c78SJasvinder Singh 		return;
223070709c78SJasvinder Singh 	}
223170709c78SJasvinder Singh 
223270709c78SJasvinder Singh 	if (strcmp(tokens[2], "pipeline") != 0) {
223370709c78SJasvinder Singh 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pipeline");
223470709c78SJasvinder Singh 		return;
223570709c78SJasvinder Singh 	}
223670709c78SJasvinder Singh 
223770709c78SJasvinder Singh 	pipeline_name = tokens[3];
2238fa0a52a7SCristian Dumitrescu 	p = softnic_pipeline_find(softnic, pipeline_name);
2239fa0a52a7SCristian Dumitrescu 	if (!p) {
2240fa0a52a7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
2241fa0a52a7SCristian Dumitrescu 		return;
2242fa0a52a7SCristian Dumitrescu 	}
224370709c78SJasvinder Singh 
224470709c78SJasvinder Singh 	if (strcmp(tokens[4], "enable") != 0) {
224570709c78SJasvinder Singh 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "enable");
224670709c78SJasvinder Singh 		return;
224770709c78SJasvinder Singh 	}
224870709c78SJasvinder Singh 
2249fa0a52a7SCristian Dumitrescu 	status = softnic_thread_pipeline_enable(softnic, thread_id, p);
225070709c78SJasvinder Singh 	if (status) {
225170709c78SJasvinder Singh 		snprintf(out, out_size, MSG_CMD_FAIL, "thread pipeline enable");
225270709c78SJasvinder Singh 		return;
225370709c78SJasvinder Singh 	}
225470709c78SJasvinder Singh }
225570709c78SJasvinder Singh 
225670709c78SJasvinder Singh /**
225770709c78SJasvinder Singh  * thread <thread_id> pipeline <pipeline_name> disable
225870709c78SJasvinder Singh  */
225970709c78SJasvinder Singh static void
cmd_softnic_thread_pipeline_disable(struct pmd_internals * softnic,char ** tokens,uint32_t n_tokens,char * out,size_t out_size)226070709c78SJasvinder Singh cmd_softnic_thread_pipeline_disable(struct pmd_internals *softnic,
226170709c78SJasvinder Singh 	char **tokens,
226270709c78SJasvinder Singh 	uint32_t n_tokens,
226370709c78SJasvinder Singh 	char *out,
226470709c78SJasvinder Singh 	size_t out_size)
226570709c78SJasvinder Singh {
226670709c78SJasvinder Singh 	char *pipeline_name;
2267fa0a52a7SCristian Dumitrescu 	struct pipeline *p;
226870709c78SJasvinder Singh 	uint32_t thread_id;
226970709c78SJasvinder Singh 	int status;
227070709c78SJasvinder Singh 
227170709c78SJasvinder Singh 	if (n_tokens != 5) {
227270709c78SJasvinder Singh 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
227370709c78SJasvinder Singh 		return;
227470709c78SJasvinder Singh 	}
227570709c78SJasvinder Singh 
2276d5854eb4SCristian Dumitrescu 	if (parser_read_uint32(&thread_id, tokens[1]) != 0) {
227770709c78SJasvinder Singh 		snprintf(out, out_size, MSG_ARG_INVALID, "thread_id");
227870709c78SJasvinder Singh 		return;
227970709c78SJasvinder Singh 	}
228070709c78SJasvinder Singh 
228170709c78SJasvinder Singh 	if (strcmp(tokens[2], "pipeline") != 0) {
228270709c78SJasvinder Singh 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pipeline");
228370709c78SJasvinder Singh 		return;
228470709c78SJasvinder Singh 	}
228570709c78SJasvinder Singh 
228670709c78SJasvinder Singh 	pipeline_name = tokens[3];
2287fa0a52a7SCristian Dumitrescu 	p = softnic_pipeline_find(softnic, pipeline_name);
2288fa0a52a7SCristian Dumitrescu 	if (!p) {
2289fa0a52a7SCristian Dumitrescu 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
2290fa0a52a7SCristian Dumitrescu 		return;
2291fa0a52a7SCristian Dumitrescu 	}
229270709c78SJasvinder Singh 
229370709c78SJasvinder Singh 	if (strcmp(tokens[4], "disable") != 0) {
229470709c78SJasvinder Singh 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "disable");
229570709c78SJasvinder Singh 		return;
229670709c78SJasvinder Singh 	}
229770709c78SJasvinder Singh 
2298fa0a52a7SCristian Dumitrescu 	status = softnic_thread_pipeline_disable(softnic, thread_id, p);
229970709c78SJasvinder Singh 	if (status) {
230070709c78SJasvinder Singh 		snprintf(out, out_size, MSG_CMD_FAIL,
230170709c78SJasvinder Singh 			"thread pipeline disable");
230270709c78SJasvinder Singh 		return;
230370709c78SJasvinder Singh 	}
230470709c78SJasvinder Singh }
230570709c78SJasvinder Singh 
230631ce8d88SJasvinder Singh void
softnic_cli_process(char * in,char * out,size_t out_size,void * arg)2307202905f3SJasvinder Singh softnic_cli_process(char *in, char *out, size_t out_size, void *arg)
230831ce8d88SJasvinder Singh {
230931ce8d88SJasvinder Singh 	char *tokens[CMD_MAX_TOKENS];
231031ce8d88SJasvinder Singh 	uint32_t n_tokens = RTE_DIM(tokens);
2311202905f3SJasvinder Singh 	struct pmd_internals *softnic = arg;
231231ce8d88SJasvinder Singh 	int status;
231331ce8d88SJasvinder Singh 
231431ce8d88SJasvinder Singh 	if (is_comment(in))
231531ce8d88SJasvinder Singh 		return;
231631ce8d88SJasvinder Singh 
2317d5854eb4SCristian Dumitrescu 	status = parse_tokenize_string(in, tokens, &n_tokens);
231831ce8d88SJasvinder Singh 	if (status) {
231931ce8d88SJasvinder Singh 		snprintf(out, out_size, MSG_ARG_TOO_MANY, "");
232031ce8d88SJasvinder Singh 		return;
232131ce8d88SJasvinder Singh 	}
232231ce8d88SJasvinder Singh 
232331ce8d88SJasvinder Singh 	if (n_tokens == 0)
232431ce8d88SJasvinder Singh 		return;
232531ce8d88SJasvinder Singh 
2326202905f3SJasvinder Singh 	if (strcmp(tokens[0], "mempool") == 0) {
2327202905f3SJasvinder Singh 		cmd_mempool(softnic, tokens, n_tokens, out, out_size);
2328202905f3SJasvinder Singh 		return;
2329202905f3SJasvinder Singh 	}
2330202905f3SJasvinder Singh 
2331202905f3SJasvinder Singh 	if (strcmp(tokens[0], "swq") == 0) {
2332202905f3SJasvinder Singh 		cmd_swq(softnic, tokens, n_tokens, out, out_size);
2333202905f3SJasvinder Singh 		return;
2334202905f3SJasvinder Singh 	}
2335202905f3SJasvinder Singh 
2336e3be2495SCristian Dumitrescu 	if (!strcmp(tokens[0], "pipeline")) {
2337e3be2495SCristian Dumitrescu 		if (n_tokens >= 2 && !strcmp(tokens[1], "codegen")) {
2338e3be2495SCristian Dumitrescu 			cmd_softnic_pipeline_codegen(softnic, tokens, n_tokens, out, out_size);
2339e3be2495SCristian Dumitrescu 			return;
2340e3be2495SCristian Dumitrescu 		}
234102270033SCristian Dumitrescu 
234202270033SCristian Dumitrescu 		if (n_tokens >= 3 && !strcmp(tokens[1], "libbuild")) {
234302270033SCristian Dumitrescu 			cmd_softnic_pipeline_libbuild(softnic, tokens, n_tokens, out, out_size);
234402270033SCristian Dumitrescu 			return;
234502270033SCristian Dumitrescu 		}
234600dfff03SCristian Dumitrescu 
234700dfff03SCristian Dumitrescu 		if (n_tokens >= 3 && !strcmp(tokens[2], "build")) {
234800dfff03SCristian Dumitrescu 			cmd_softnic_pipeline_build(softnic, tokens, n_tokens, out, out_size);
234900dfff03SCristian Dumitrescu 			return;
235000dfff03SCristian Dumitrescu 		}
2351d8141864SCristian Dumitrescu 
2352d8141864SCristian Dumitrescu 		if (n_tokens >= 5 && !strcmp(tokens[2], "table") && !strcmp(tokens[4], "add")) {
2353d8141864SCristian Dumitrescu 			cmd_softnic_pipeline_table_add(softnic, tokens, n_tokens, out, out_size);
2354d8141864SCristian Dumitrescu 			return;
2355d8141864SCristian Dumitrescu 		}
2356d8141864SCristian Dumitrescu 
2357d8141864SCristian Dumitrescu 		if (n_tokens >= 5 && !strcmp(tokens[2], "table") && !strcmp(tokens[4], "delete")) {
2358d8141864SCristian Dumitrescu 			cmd_softnic_pipeline_table_delete(softnic, tokens, n_tokens,
2359d8141864SCristian Dumitrescu 				out, out_size);
2360d8141864SCristian Dumitrescu 			return;
2361d8141864SCristian Dumitrescu 		}
2362d8141864SCristian Dumitrescu 
2363d8141864SCristian Dumitrescu 		if (n_tokens >= 5 && !strcmp(tokens[2], "table") && !strcmp(tokens[4], "default")) {
2364d8141864SCristian Dumitrescu 			cmd_softnic_pipeline_table_default(softnic, tokens, n_tokens,
2365d8141864SCristian Dumitrescu 				out, out_size);
2366d8141864SCristian Dumitrescu 			return;
2367d8141864SCristian Dumitrescu 		}
2368d8141864SCristian Dumitrescu 
2369d8141864SCristian Dumitrescu 		if (n_tokens >= 5 && !strcmp(tokens[2], "table") && !strcmp(tokens[4], "show")) {
2370d8141864SCristian Dumitrescu 			cmd_softnic_pipeline_table_show(softnic, tokens, n_tokens, out, out_size);
2371d8141864SCristian Dumitrescu 			return;
2372d8141864SCristian Dumitrescu 		}
2373e9c35c60SCristian Dumitrescu 
2374e9c35c60SCristian Dumitrescu 		if (n_tokens >= 6 &&
2375e9c35c60SCristian Dumitrescu 			!strcmp(tokens[2], "selector") &&
2376e9c35c60SCristian Dumitrescu 			!strcmp(tokens[4], "group") &&
2377e9c35c60SCristian Dumitrescu 			!strcmp(tokens[5], "add")) {
2378e9c35c60SCristian Dumitrescu 			cmd_softnic_pipeline_selector_group_add(softnic, tokens, n_tokens,
2379e9c35c60SCristian Dumitrescu 				out, out_size);
2380e9c35c60SCristian Dumitrescu 			return;
2381e9c35c60SCristian Dumitrescu 		}
2382e9c35c60SCristian Dumitrescu 
2383e9c35c60SCristian Dumitrescu 		if (n_tokens >= 6 &&
2384e9c35c60SCristian Dumitrescu 			!strcmp(tokens[2], "selector") &&
2385e9c35c60SCristian Dumitrescu 			!strcmp(tokens[4], "group") &&
2386e9c35c60SCristian Dumitrescu 			!strcmp(tokens[5], "delete")) {
2387e9c35c60SCristian Dumitrescu 			cmd_softnic_pipeline_selector_group_delete(softnic, tokens, n_tokens,
2388e9c35c60SCristian Dumitrescu 				out, out_size);
2389e9c35c60SCristian Dumitrescu 			return;
2390e9c35c60SCristian Dumitrescu 		}
2391e9c35c60SCristian Dumitrescu 
2392e9c35c60SCristian Dumitrescu 		if (n_tokens >= 7 &&
2393e9c35c60SCristian Dumitrescu 			!strcmp(tokens[2], "selector") &&
2394e9c35c60SCristian Dumitrescu 			!strcmp(tokens[4], "group") &&
2395e9c35c60SCristian Dumitrescu 			!strcmp(tokens[5], "member") &&
2396e9c35c60SCristian Dumitrescu 			!strcmp(tokens[6], "add")) {
2397e9c35c60SCristian Dumitrescu 			cmd_softnic_pipeline_selector_group_member_add(softnic, tokens, n_tokens,
2398e9c35c60SCristian Dumitrescu 				out, out_size);
2399e9c35c60SCristian Dumitrescu 			return;
2400e9c35c60SCristian Dumitrescu 		}
2401e9c35c60SCristian Dumitrescu 
2402e9c35c60SCristian Dumitrescu 		if (n_tokens >= 7 &&
2403e9c35c60SCristian Dumitrescu 			!strcmp(tokens[2], "selector") &&
2404e9c35c60SCristian Dumitrescu 			!strcmp(tokens[4], "group") &&
2405e9c35c60SCristian Dumitrescu 			!strcmp(tokens[5], "member") &&
2406e9c35c60SCristian Dumitrescu 			!strcmp(tokens[6], "delete")) {
2407e9c35c60SCristian Dumitrescu 			cmd_softnic_pipeline_selector_group_member_delete(softnic, tokens, n_tokens,
2408e9c35c60SCristian Dumitrescu 				out, out_size);
2409e9c35c60SCristian Dumitrescu 			return;
2410e9c35c60SCristian Dumitrescu 		}
2411e9c35c60SCristian Dumitrescu 
2412e9c35c60SCristian Dumitrescu 		if (n_tokens >= 5 &&
2413e9c35c60SCristian Dumitrescu 			!strcmp(tokens[2], "selector") &&
2414e9c35c60SCristian Dumitrescu 			!strcmp(tokens[4], "show")) {
2415e9c35c60SCristian Dumitrescu 			cmd_softnic_pipeline_selector_show(softnic, tokens, n_tokens,
2416e9c35c60SCristian Dumitrescu 				out, out_size);
2417e9c35c60SCristian Dumitrescu 			return;
2418e9c35c60SCristian Dumitrescu 		}
24193f14baa0SCristian Dumitrescu 
24203f14baa0SCristian Dumitrescu 		if (n_tokens >= 5 &&
24213f14baa0SCristian Dumitrescu 			!strcmp(tokens[2], "learner") &&
24223f14baa0SCristian Dumitrescu 			!strcmp(tokens[4], "default")) {
24233f14baa0SCristian Dumitrescu 			cmd_softnic_pipeline_learner_default(softnic, tokens, n_tokens,
24243f14baa0SCristian Dumitrescu 				out, out_size);
24253f14baa0SCristian Dumitrescu 			return;
24263f14baa0SCristian Dumitrescu 		}
2427b4647f3aSCristian Dumitrescu 
2428b4647f3aSCristian Dumitrescu 		if (n_tokens >= 3 && !strcmp(tokens[2], "commit")) {
2429b4647f3aSCristian Dumitrescu 			cmd_softnic_pipeline_commit(softnic, tokens, n_tokens, out, out_size);
2430b4647f3aSCristian Dumitrescu 			return;
2431b4647f3aSCristian Dumitrescu 		}
2432b4647f3aSCristian Dumitrescu 
2433b4647f3aSCristian Dumitrescu 		if (n_tokens >= 3 && !strcmp(tokens[2], "abort")) {
2434b4647f3aSCristian Dumitrescu 			cmd_softnic_pipeline_abort(softnic, tokens, n_tokens, out, out_size);
2435b4647f3aSCristian Dumitrescu 			return;
2436b4647f3aSCristian Dumitrescu 		}
2437c7683010SCristian Dumitrescu 
2438c7683010SCristian Dumitrescu 		if (n_tokens >= 3 && !strcmp(tokens[2], "regrd")) {
2439c7683010SCristian Dumitrescu 			cmd_softnic_pipeline_regrd(softnic, tokens, n_tokens, out, out_size);
2440c7683010SCristian Dumitrescu 			return;
2441c7683010SCristian Dumitrescu 		}
2442c7683010SCristian Dumitrescu 
2443c7683010SCristian Dumitrescu 		if (n_tokens >= 3 && !strcmp(tokens[2], "regwr")) {
2444c7683010SCristian Dumitrescu 			cmd_softnic_pipeline_regwr(softnic, tokens, n_tokens, out, out_size);
2445c7683010SCristian Dumitrescu 			return;
2446c7683010SCristian Dumitrescu 		}
244749b842daSCristian Dumitrescu 
244849b842daSCristian Dumitrescu 		if (n_tokens >= 6 &&
244949b842daSCristian Dumitrescu 			!strcmp(tokens[2], "meter") &&
245049b842daSCristian Dumitrescu 			!strcmp(tokens[3], "profile") &&
245149b842daSCristian Dumitrescu 			!strcmp(tokens[5], "add")) {
245249b842daSCristian Dumitrescu 			cmd_softnic_pipeline_meter_profile_add(softnic, tokens, n_tokens,
245349b842daSCristian Dumitrescu 				out, out_size);
245449b842daSCristian Dumitrescu 			return;
245549b842daSCristian Dumitrescu 		}
245649b842daSCristian Dumitrescu 
245749b842daSCristian Dumitrescu 		if (n_tokens >= 6 &&
245849b842daSCristian Dumitrescu 			!strcmp(tokens[2], "meter") &&
245949b842daSCristian Dumitrescu 			!strcmp(tokens[3], "profile") &&
246049b842daSCristian Dumitrescu 			!strcmp(tokens[5], "delete")) {
246149b842daSCristian Dumitrescu 			cmd_softnic_pipeline_meter_profile_delete(softnic, tokens, n_tokens,
246249b842daSCristian Dumitrescu 				out, out_size);
246349b842daSCristian Dumitrescu 			return;
246449b842daSCristian Dumitrescu 		}
246549b842daSCristian Dumitrescu 
246649b842daSCristian Dumitrescu 		if (n_tokens >= 9 && !strcmp(tokens[2], "meter") && !strcmp(tokens[8], "reset")) {
246749b842daSCristian Dumitrescu 			cmd_softnic_pipeline_meter_reset(softnic, tokens, n_tokens, out, out_size);
246849b842daSCristian Dumitrescu 			return;
246949b842daSCristian Dumitrescu 		}
247049b842daSCristian Dumitrescu 
247149b842daSCristian Dumitrescu 		if (n_tokens >= 9 && !strcmp(tokens[2], "meter") && !strcmp(tokens[8], "set")) {
247249b842daSCristian Dumitrescu 			cmd_softnic_pipeline_meter_set(softnic, tokens, n_tokens, out, out_size);
247349b842daSCristian Dumitrescu 			return;
247449b842daSCristian Dumitrescu 		}
247549b842daSCristian Dumitrescu 
247649b842daSCristian Dumitrescu 		if (n_tokens >= 9 && !strcmp(tokens[2], "meter") && !strcmp(tokens[8], "stats")) {
247749b842daSCristian Dumitrescu 			cmd_softnic_pipeline_meter_stats(softnic, tokens, n_tokens, out, out_size);
247849b842daSCristian Dumitrescu 			return;
247949b842daSCristian Dumitrescu 		}
248049b842daSCristian Dumitrescu 
24814e141bf4SCristian Dumitrescu 		if (n_tokens >= 3 && !strcmp(tokens[2], "stats")) {
24824e141bf4SCristian Dumitrescu 			cmd_softnic_pipeline_stats(softnic, tokens, n_tokens, out, out_size);
24834e141bf4SCristian Dumitrescu 			return;
24844e141bf4SCristian Dumitrescu 		}
2485de0a728aSCristian Dumitrescu 
2486de0a728aSCristian Dumitrescu 		if (n_tokens >= 4 &&
2487de0a728aSCristian Dumitrescu 			!strcmp(tokens[2], "mirror") &&
2488de0a728aSCristian Dumitrescu 			!strcmp(tokens[3], "session")) {
2489de0a728aSCristian Dumitrescu 			cmd_softnic_pipeline_mirror_session(softnic, tokens, n_tokens,
2490de0a728aSCristian Dumitrescu 				out, out_size);
2491de0a728aSCristian Dumitrescu 			return;
2492de0a728aSCristian Dumitrescu 		}
2493e3be2495SCristian Dumitrescu 	}
2494e3be2495SCristian Dumitrescu 
249570709c78SJasvinder Singh 	if (strcmp(tokens[0], "thread") == 0) {
2496ee19326aSJasvinder Singh 		if (n_tokens >= 5 &&
249770709c78SJasvinder Singh 			(strcmp(tokens[4], "enable") == 0)) {
249870709c78SJasvinder Singh 			cmd_softnic_thread_pipeline_enable(softnic, tokens, n_tokens,
249970709c78SJasvinder Singh 				out, out_size);
250070709c78SJasvinder Singh 			return;
250170709c78SJasvinder Singh 		}
250270709c78SJasvinder Singh 
2503ee19326aSJasvinder Singh 		if (n_tokens >= 5 &&
250470709c78SJasvinder Singh 			(strcmp(tokens[4], "disable") == 0)) {
250570709c78SJasvinder Singh 			cmd_softnic_thread_pipeline_disable(softnic, tokens, n_tokens,
250670709c78SJasvinder Singh 				out, out_size);
250770709c78SJasvinder Singh 			return;
250870709c78SJasvinder Singh 		}
250970709c78SJasvinder Singh 	}
251070709c78SJasvinder Singh 
251131ce8d88SJasvinder Singh 	snprintf(out, out_size, MSG_CMD_UNKNOWN, tokens[0]);
251231ce8d88SJasvinder Singh }
251331ce8d88SJasvinder Singh 
251431ce8d88SJasvinder Singh int
softnic_cli_script_process(struct pmd_internals * softnic,const char * file_name,size_t msg_in_len_max,size_t msg_out_len_max)251531ce8d88SJasvinder Singh softnic_cli_script_process(struct pmd_internals *softnic,
251631ce8d88SJasvinder Singh 	const char *file_name,
251731ce8d88SJasvinder Singh 	size_t msg_in_len_max,
251831ce8d88SJasvinder Singh 	size_t msg_out_len_max)
251931ce8d88SJasvinder Singh {
252031ce8d88SJasvinder Singh 	char *msg_in = NULL, *msg_out = NULL;
252131ce8d88SJasvinder Singh 	FILE *f = NULL;
252231ce8d88SJasvinder Singh 
252331ce8d88SJasvinder Singh 	/* Check input arguments */
252431ce8d88SJasvinder Singh 	if (file_name == NULL ||
2525ee19326aSJasvinder Singh 		(strlen(file_name) == 0) ||
252631ce8d88SJasvinder Singh 		msg_in_len_max == 0 ||
252731ce8d88SJasvinder Singh 		msg_out_len_max == 0)
252831ce8d88SJasvinder Singh 		return -EINVAL;
252931ce8d88SJasvinder Singh 
253031ce8d88SJasvinder Singh 	msg_in = malloc(msg_in_len_max + 1);
253131ce8d88SJasvinder Singh 	msg_out = malloc(msg_out_len_max + 1);
253231ce8d88SJasvinder Singh 	if (msg_in == NULL ||
253331ce8d88SJasvinder Singh 		msg_out == NULL) {
253431ce8d88SJasvinder Singh 		free(msg_out);
253531ce8d88SJasvinder Singh 		free(msg_in);
253631ce8d88SJasvinder Singh 		return -ENOMEM;
253731ce8d88SJasvinder Singh 	}
253831ce8d88SJasvinder Singh 
253931ce8d88SJasvinder Singh 	/* Open input file */
254031ce8d88SJasvinder Singh 	f = fopen(file_name, "r");
254131ce8d88SJasvinder Singh 	if (f == NULL) {
254231ce8d88SJasvinder Singh 		free(msg_out);
254331ce8d88SJasvinder Singh 		free(msg_in);
254431ce8d88SJasvinder Singh 		return -EIO;
254531ce8d88SJasvinder Singh 	}
254631ce8d88SJasvinder Singh 
254731ce8d88SJasvinder Singh 	/* Read file */
254831ce8d88SJasvinder Singh 	for ( ; ; ) {
254931ce8d88SJasvinder Singh 		if (fgets(msg_in, msg_in_len_max + 1, f) == NULL)
255031ce8d88SJasvinder Singh 			break;
255131ce8d88SJasvinder Singh 
255231ce8d88SJasvinder Singh 		printf("%s", msg_in);
255331ce8d88SJasvinder Singh 		msg_out[0] = 0;
255431ce8d88SJasvinder Singh 
255531ce8d88SJasvinder Singh 		softnic_cli_process(msg_in,
255631ce8d88SJasvinder Singh 			msg_out,
255731ce8d88SJasvinder Singh 			msg_out_len_max,
255831ce8d88SJasvinder Singh 			softnic);
255931ce8d88SJasvinder Singh 
256031ce8d88SJasvinder Singh 		if (strlen(msg_out))
256131ce8d88SJasvinder Singh 			printf("%s", msg_out);
256231ce8d88SJasvinder Singh 	}
256331ce8d88SJasvinder Singh 
256431ce8d88SJasvinder Singh 	/* Close file */
256531ce8d88SJasvinder Singh 	fclose(f);
256631ce8d88SJasvinder Singh 	free(msg_out);
256731ce8d88SJasvinder Singh 	free(msg_in);
256831ce8d88SJasvinder Singh 	return 0;
256931ce8d88SJasvinder Singh }
2570