xref: /dpdk/drivers/net/softnic/rte_eth_softnic_cli.c (revision a1f7065d0fc7097319f2a81fcc595f8748cb86a8)
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2010-2018 Intel Corporation
3  */
4 
5 #include <stdio.h>
6 #include <stdint.h>
7 #include <stdlib.h>
8 #include <string.h>
9 
10 #include <rte_common.h>
11 #include <rte_cycles.h>
12 #include <rte_string_fns.h>
13 
14 #include "rte_eth_softnic_internals.h"
15 #include "parser.h"
16 
17 #ifndef CMD_MAX_TOKENS
18 #define CMD_MAX_TOKENS     256
19 #endif
20 
21 #define MSG_OUT_OF_MEMORY   "Not enough memory.\n"
22 #define MSG_CMD_UNKNOWN     "Unknown command \"%s\".\n"
23 #define MSG_CMD_UNIMPLEM    "Command \"%s\" not implemented.\n"
24 #define MSG_ARG_NOT_ENOUGH  "Not enough arguments for command \"%s\".\n"
25 #define MSG_ARG_TOO_MANY    "Too many arguments for command \"%s\".\n"
26 #define MSG_ARG_MISMATCH    "Wrong number of arguments for command \"%s\".\n"
27 #define MSG_ARG_NOT_FOUND   "Argument \"%s\" not found.\n"
28 #define MSG_ARG_INVALID     "Invalid value for argument \"%s\".\n"
29 #define MSG_FILE_ERR        "Error in file \"%s\" at line %u.\n"
30 #define MSG_FILE_NOT_ENOUGH "Not enough rules in file \"%s\".\n"
31 #define MSG_CMD_FAIL        "Command \"%s\" failed.\n"
32 
33 static int
34 is_comment(char *in)
35 {
36 	if ((strlen(in) && index("!#%;", in[0])) ||
37 		(strncmp(in, "//", 2) == 0) ||
38 		(strncmp(in, "--", 2) == 0))
39 		return 1;
40 
41 	return 0;
42 }
43 
44 /**
45  * mempool <mempool_name>
46  *  buffer <buffer_size>
47  *  pool <pool_size>
48  *  cache <cache_size>
49  */
50 static void
51 cmd_mempool(struct pmd_internals *softnic,
52 	char **tokens,
53 	uint32_t n_tokens,
54 	char *out,
55 	size_t out_size)
56 {
57 	struct softnic_mempool_params p;
58 	char *name;
59 	struct softnic_mempool *mempool;
60 
61 	if (n_tokens != 8) {
62 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
63 		return;
64 	}
65 
66 	name = tokens[1];
67 
68 	if (strcmp(tokens[2], "buffer") != 0) {
69 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "buffer");
70 		return;
71 	}
72 
73 	if (softnic_parser_read_uint32(&p.buffer_size, tokens[3]) != 0) {
74 		snprintf(out, out_size, MSG_ARG_INVALID, "buffer_size");
75 		return;
76 	}
77 
78 	if (strcmp(tokens[4], "pool") != 0) {
79 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pool");
80 		return;
81 	}
82 
83 	if (softnic_parser_read_uint32(&p.pool_size, tokens[5]) != 0) {
84 		snprintf(out, out_size, MSG_ARG_INVALID, "pool_size");
85 		return;
86 	}
87 
88 	if (strcmp(tokens[6], "cache") != 0) {
89 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cache");
90 		return;
91 	}
92 
93 	if (softnic_parser_read_uint32(&p.cache_size, tokens[7]) != 0) {
94 		snprintf(out, out_size, MSG_ARG_INVALID, "cache_size");
95 		return;
96 	}
97 
98 	mempool = softnic_mempool_create(softnic, name, &p);
99 	if (mempool == NULL) {
100 		snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
101 		return;
102 	}
103 }
104 
105 /**
106  * swq <swq_name>
107  *  size <size>
108  */
109 static void
110 cmd_swq(struct pmd_internals *softnic,
111 	char **tokens,
112 	uint32_t n_tokens,
113 	char *out,
114 	size_t out_size)
115 {
116 	struct softnic_swq_params p;
117 	char *name;
118 	struct softnic_swq *swq;
119 
120 	if (n_tokens != 4) {
121 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
122 		return;
123 	}
124 
125 	name = tokens[1];
126 
127 	if (strcmp(tokens[2], "size") != 0) {
128 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "size");
129 		return;
130 	}
131 
132 	if (softnic_parser_read_uint32(&p.size, tokens[3]) != 0) {
133 		snprintf(out, out_size, MSG_ARG_INVALID, "size");
134 		return;
135 	}
136 
137 	swq = softnic_swq_create(softnic, name, &p);
138 	if (swq == NULL) {
139 		snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
140 		return;
141 	}
142 }
143 
144 /**
145  * thread <thread_id> pipeline <pipeline_name> enable
146  */
147 static void
148 cmd_softnic_thread_pipeline_enable(struct pmd_internals *softnic,
149 	char **tokens,
150 	uint32_t n_tokens,
151 	char *out,
152 	size_t out_size)
153 {
154 	char *pipeline_name;
155 	struct pipeline *p;
156 	uint32_t thread_id;
157 	int status;
158 
159 	if (n_tokens != 5) {
160 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
161 		return;
162 	}
163 
164 	if (softnic_parser_read_uint32(&thread_id, tokens[1]) != 0) {
165 		snprintf(out, out_size, MSG_ARG_INVALID, "thread_id");
166 		return;
167 	}
168 
169 	if (strcmp(tokens[2], "pipeline") != 0) {
170 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pipeline");
171 		return;
172 	}
173 
174 	pipeline_name = tokens[3];
175 	p = softnic_pipeline_find(softnic, pipeline_name);
176 	if (!p) {
177 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
178 		return;
179 	}
180 
181 	if (strcmp(tokens[4], "enable") != 0) {
182 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "enable");
183 		return;
184 	}
185 
186 	status = softnic_thread_pipeline_enable(softnic, thread_id, p);
187 	if (status) {
188 		snprintf(out, out_size, MSG_CMD_FAIL, "thread pipeline enable");
189 		return;
190 	}
191 }
192 
193 /**
194  * thread <thread_id> pipeline <pipeline_name> disable
195  */
196 static void
197 cmd_softnic_thread_pipeline_disable(struct pmd_internals *softnic,
198 	char **tokens,
199 	uint32_t n_tokens,
200 	char *out,
201 	size_t out_size)
202 {
203 	char *pipeline_name;
204 	struct pipeline *p;
205 	uint32_t thread_id;
206 	int status;
207 
208 	if (n_tokens != 5) {
209 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
210 		return;
211 	}
212 
213 	if (softnic_parser_read_uint32(&thread_id, tokens[1]) != 0) {
214 		snprintf(out, out_size, MSG_ARG_INVALID, "thread_id");
215 		return;
216 	}
217 
218 	if (strcmp(tokens[2], "pipeline") != 0) {
219 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pipeline");
220 		return;
221 	}
222 
223 	pipeline_name = tokens[3];
224 	p = softnic_pipeline_find(softnic, pipeline_name);
225 	if (!p) {
226 		snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
227 		return;
228 	}
229 
230 	if (strcmp(tokens[4], "disable") != 0) {
231 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "disable");
232 		return;
233 	}
234 
235 	status = softnic_thread_pipeline_disable(softnic, thread_id, p);
236 	if (status) {
237 		snprintf(out, out_size, MSG_CMD_FAIL,
238 			"thread pipeline disable");
239 		return;
240 	}
241 }
242 
243 void
244 softnic_cli_process(char *in, char *out, size_t out_size, void *arg)
245 {
246 	char *tokens[CMD_MAX_TOKENS];
247 	uint32_t n_tokens = RTE_DIM(tokens);
248 	struct pmd_internals *softnic = arg;
249 	int status;
250 
251 	if (is_comment(in))
252 		return;
253 
254 	status = softnic_parse_tokenize_string(in, tokens, &n_tokens);
255 	if (status) {
256 		snprintf(out, out_size, MSG_ARG_TOO_MANY, "");
257 		return;
258 	}
259 
260 	if (n_tokens == 0)
261 		return;
262 
263 	if (strcmp(tokens[0], "mempool") == 0) {
264 		cmd_mempool(softnic, tokens, n_tokens, out, out_size);
265 		return;
266 	}
267 
268 	if (strcmp(tokens[0], "swq") == 0) {
269 		cmd_swq(softnic, tokens, n_tokens, out, out_size);
270 		return;
271 	}
272 
273 	if (strcmp(tokens[0], "thread") == 0) {
274 		if (n_tokens >= 5 &&
275 			(strcmp(tokens[4], "enable") == 0)) {
276 			cmd_softnic_thread_pipeline_enable(softnic, tokens, n_tokens,
277 				out, out_size);
278 			return;
279 		}
280 
281 		if (n_tokens >= 5 &&
282 			(strcmp(tokens[4], "disable") == 0)) {
283 			cmd_softnic_thread_pipeline_disable(softnic, tokens, n_tokens,
284 				out, out_size);
285 			return;
286 		}
287 	}
288 
289 	snprintf(out, out_size, MSG_CMD_UNKNOWN, tokens[0]);
290 }
291 
292 int
293 softnic_cli_script_process(struct pmd_internals *softnic,
294 	const char *file_name,
295 	size_t msg_in_len_max,
296 	size_t msg_out_len_max)
297 {
298 	char *msg_in = NULL, *msg_out = NULL;
299 	FILE *f = NULL;
300 
301 	/* Check input arguments */
302 	if (file_name == NULL ||
303 		(strlen(file_name) == 0) ||
304 		msg_in_len_max == 0 ||
305 		msg_out_len_max == 0)
306 		return -EINVAL;
307 
308 	msg_in = malloc(msg_in_len_max + 1);
309 	msg_out = malloc(msg_out_len_max + 1);
310 	if (msg_in == NULL ||
311 		msg_out == NULL) {
312 		free(msg_out);
313 		free(msg_in);
314 		return -ENOMEM;
315 	}
316 
317 	/* Open input file */
318 	f = fopen(file_name, "r");
319 	if (f == NULL) {
320 		free(msg_out);
321 		free(msg_in);
322 		return -EIO;
323 	}
324 
325 	/* Read file */
326 	for ( ; ; ) {
327 		if (fgets(msg_in, msg_in_len_max + 1, f) == NULL)
328 			break;
329 
330 		printf("%s", msg_in);
331 		msg_out[0] = 0;
332 
333 		softnic_cli_process(msg_in,
334 			msg_out,
335 			msg_out_len_max,
336 			softnic);
337 
338 		if (strlen(msg_out))
339 			printf("%s", msg_out);
340 	}
341 
342 	/* Close file */
343 	fclose(f);
344 	free(msg_out);
345 	free(msg_in);
346 	return 0;
347 }
348