xref: /dpdk/drivers/net/softnic/rte_eth_softnic_cli.c (revision 202905f3ee4db9df45f00da90da99e0655e60ef6)
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>
931ce8d88SJasvinder Singh 
1031ce8d88SJasvinder Singh #include "rte_eth_softnic_internals.h"
1131ce8d88SJasvinder Singh #include "parser.h"
1231ce8d88SJasvinder Singh 
1331ce8d88SJasvinder Singh #ifndef CMD_MAX_TOKENS
1431ce8d88SJasvinder Singh #define CMD_MAX_TOKENS     256
1531ce8d88SJasvinder Singh #endif
1631ce8d88SJasvinder Singh 
1731ce8d88SJasvinder Singh #define MSG_OUT_OF_MEMORY   "Not enough memory.\n"
1831ce8d88SJasvinder Singh #define MSG_CMD_UNKNOWN     "Unknown command \"%s\".\n"
1931ce8d88SJasvinder Singh #define MSG_CMD_UNIMPLEM    "Command \"%s\" not implemented.\n"
2031ce8d88SJasvinder Singh #define MSG_ARG_NOT_ENOUGH  "Not enough arguments for command \"%s\".\n"
2131ce8d88SJasvinder Singh #define MSG_ARG_TOO_MANY    "Too many arguments for command \"%s\".\n"
2231ce8d88SJasvinder Singh #define MSG_ARG_MISMATCH    "Wrong number of arguments for command \"%s\".\n"
2331ce8d88SJasvinder Singh #define MSG_ARG_NOT_FOUND   "Argument \"%s\" not found.\n"
2431ce8d88SJasvinder Singh #define MSG_ARG_INVALID     "Invalid value for argument \"%s\".\n"
2531ce8d88SJasvinder Singh #define MSG_FILE_ERR        "Error in file \"%s\" at line %u.\n"
2631ce8d88SJasvinder Singh #define MSG_FILE_NOT_ENOUGH "Not enough rules in file \"%s\".\n"
2731ce8d88SJasvinder Singh #define MSG_CMD_FAIL        "Command \"%s\" failed.\n"
2831ce8d88SJasvinder Singh 
2931ce8d88SJasvinder Singh static int
3031ce8d88SJasvinder Singh is_comment(char *in)
3131ce8d88SJasvinder Singh {
3231ce8d88SJasvinder Singh 	if ((strlen(in) && index("!#%;", in[0])) ||
3331ce8d88SJasvinder Singh 		(strncmp(in, "//", 2) == 0) ||
3431ce8d88SJasvinder Singh 		(strncmp(in, "--", 2) == 0))
3531ce8d88SJasvinder Singh 		return 1;
3631ce8d88SJasvinder Singh 
3731ce8d88SJasvinder Singh 	return 0;
3831ce8d88SJasvinder Singh }
3931ce8d88SJasvinder Singh 
40*202905f3SJasvinder Singh /**
41*202905f3SJasvinder Singh  * mempool <mempool_name>
42*202905f3SJasvinder Singh  *  buffer <buffer_size>
43*202905f3SJasvinder Singh  *  pool <pool_size>
44*202905f3SJasvinder Singh  *  cache <cache_size>
45*202905f3SJasvinder Singh  */
46*202905f3SJasvinder Singh static void
47*202905f3SJasvinder Singh cmd_mempool(struct pmd_internals *softnic,
48*202905f3SJasvinder Singh 	char **tokens,
49*202905f3SJasvinder Singh 	uint32_t n_tokens,
50*202905f3SJasvinder Singh 	char *out,
51*202905f3SJasvinder Singh 	size_t out_size)
52*202905f3SJasvinder Singh {
53*202905f3SJasvinder Singh 	struct softnic_mempool_params p;
54*202905f3SJasvinder Singh 	char *name;
55*202905f3SJasvinder Singh 	struct softnic_mempool *mempool;
56*202905f3SJasvinder Singh 
57*202905f3SJasvinder Singh 	if (n_tokens != 8) {
58*202905f3SJasvinder Singh 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
59*202905f3SJasvinder Singh 		return;
60*202905f3SJasvinder Singh 	}
61*202905f3SJasvinder Singh 
62*202905f3SJasvinder Singh 	name = tokens[1];
63*202905f3SJasvinder Singh 
64*202905f3SJasvinder Singh 	if (strcmp(tokens[2], "buffer") != 0) {
65*202905f3SJasvinder Singh 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "buffer");
66*202905f3SJasvinder Singh 		return;
67*202905f3SJasvinder Singh 	}
68*202905f3SJasvinder Singh 
69*202905f3SJasvinder Singh 	if (softnic_parser_read_uint32(&p.buffer_size, tokens[3]) != 0) {
70*202905f3SJasvinder Singh 		snprintf(out, out_size, MSG_ARG_INVALID, "buffer_size");
71*202905f3SJasvinder Singh 		return;
72*202905f3SJasvinder Singh 	}
73*202905f3SJasvinder Singh 
74*202905f3SJasvinder Singh 	if (strcmp(tokens[4], "pool") != 0) {
75*202905f3SJasvinder Singh 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pool");
76*202905f3SJasvinder Singh 		return;
77*202905f3SJasvinder Singh 	}
78*202905f3SJasvinder Singh 
79*202905f3SJasvinder Singh 	if (softnic_parser_read_uint32(&p.pool_size, tokens[5]) != 0) {
80*202905f3SJasvinder Singh 		snprintf(out, out_size, MSG_ARG_INVALID, "pool_size");
81*202905f3SJasvinder Singh 		return;
82*202905f3SJasvinder Singh 	}
83*202905f3SJasvinder Singh 
84*202905f3SJasvinder Singh 	if (strcmp(tokens[6], "cache") != 0) {
85*202905f3SJasvinder Singh 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cache");
86*202905f3SJasvinder Singh 		return;
87*202905f3SJasvinder Singh 	}
88*202905f3SJasvinder Singh 
89*202905f3SJasvinder Singh 	if (softnic_parser_read_uint32(&p.cache_size, tokens[7]) != 0) {
90*202905f3SJasvinder Singh 		snprintf(out, out_size, MSG_ARG_INVALID, "cache_size");
91*202905f3SJasvinder Singh 		return;
92*202905f3SJasvinder Singh 	}
93*202905f3SJasvinder Singh 
94*202905f3SJasvinder Singh 	mempool = softnic_mempool_create(softnic, name, &p);
95*202905f3SJasvinder Singh 	if (mempool == NULL) {
96*202905f3SJasvinder Singh 		snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
97*202905f3SJasvinder Singh 		return;
98*202905f3SJasvinder Singh 	}
99*202905f3SJasvinder Singh }
100*202905f3SJasvinder Singh 
101*202905f3SJasvinder Singh /**
102*202905f3SJasvinder Singh  * link <link_name>
103*202905f3SJasvinder Singh  *    dev <device_name> | port <port_id>
104*202905f3SJasvinder Singh  */
105*202905f3SJasvinder Singh static void
106*202905f3SJasvinder Singh cmd_link(struct pmd_internals *softnic,
107*202905f3SJasvinder Singh 	char **tokens,
108*202905f3SJasvinder Singh 	uint32_t n_tokens,
109*202905f3SJasvinder Singh 	char *out,
110*202905f3SJasvinder Singh 	size_t out_size)
111*202905f3SJasvinder Singh {
112*202905f3SJasvinder Singh 	struct softnic_link_params p;
113*202905f3SJasvinder Singh 	struct softnic_link *link;
114*202905f3SJasvinder Singh 	char *name;
115*202905f3SJasvinder Singh 
116*202905f3SJasvinder Singh 	memset(&p, 0, sizeof(p));
117*202905f3SJasvinder Singh 
118*202905f3SJasvinder Singh 	if (n_tokens != 4) {
119*202905f3SJasvinder Singh 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
120*202905f3SJasvinder Singh 		return;
121*202905f3SJasvinder Singh 	}
122*202905f3SJasvinder Singh 	name = tokens[1];
123*202905f3SJasvinder Singh 
124*202905f3SJasvinder Singh 	if (strcmp(tokens[2], "dev") == 0) {
125*202905f3SJasvinder Singh 		p.dev_name = tokens[3];
126*202905f3SJasvinder Singh 	} else if (strcmp(tokens[2], "port") == 0) {
127*202905f3SJasvinder Singh 		p.dev_name = NULL;
128*202905f3SJasvinder Singh 
129*202905f3SJasvinder Singh 		if (softnic_parser_read_uint16(&p.port_id, tokens[3]) != 0) {
130*202905f3SJasvinder Singh 			snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
131*202905f3SJasvinder Singh 			return;
132*202905f3SJasvinder Singh 		}
133*202905f3SJasvinder Singh 	} else {
134*202905f3SJasvinder Singh 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "dev or port");
135*202905f3SJasvinder Singh 		return;
136*202905f3SJasvinder Singh 	}
137*202905f3SJasvinder Singh 
138*202905f3SJasvinder Singh 	link = softnic_link_create(softnic, name, &p);
139*202905f3SJasvinder Singh 	if (link == NULL) {
140*202905f3SJasvinder Singh 		snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
141*202905f3SJasvinder Singh 		return;
142*202905f3SJasvinder Singh 	}
143*202905f3SJasvinder Singh }
144*202905f3SJasvinder Singh 
145*202905f3SJasvinder Singh /**
146*202905f3SJasvinder Singh  * swq <swq_name>
147*202905f3SJasvinder Singh  *  size <size>
148*202905f3SJasvinder Singh  */
149*202905f3SJasvinder Singh static void
150*202905f3SJasvinder Singh cmd_swq(struct pmd_internals *softnic,
151*202905f3SJasvinder Singh 	char **tokens,
152*202905f3SJasvinder Singh 	uint32_t n_tokens,
153*202905f3SJasvinder Singh 	char *out,
154*202905f3SJasvinder Singh 	size_t out_size)
155*202905f3SJasvinder Singh {
156*202905f3SJasvinder Singh 	struct softnic_swq_params p;
157*202905f3SJasvinder Singh 	char *name;
158*202905f3SJasvinder Singh 	struct softnic_swq *swq;
159*202905f3SJasvinder Singh 
160*202905f3SJasvinder Singh 	if (n_tokens != 4) {
161*202905f3SJasvinder Singh 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
162*202905f3SJasvinder Singh 		return;
163*202905f3SJasvinder Singh 	}
164*202905f3SJasvinder Singh 
165*202905f3SJasvinder Singh 	name = tokens[1];
166*202905f3SJasvinder Singh 
167*202905f3SJasvinder Singh 	if (strcmp(tokens[2], "size") != 0) {
168*202905f3SJasvinder Singh 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "size");
169*202905f3SJasvinder Singh 		return;
170*202905f3SJasvinder Singh 	}
171*202905f3SJasvinder Singh 
172*202905f3SJasvinder Singh 	if (softnic_parser_read_uint32(&p.size, tokens[3]) != 0) {
173*202905f3SJasvinder Singh 		snprintf(out, out_size, MSG_ARG_INVALID, "size");
174*202905f3SJasvinder Singh 		return;
175*202905f3SJasvinder Singh 	}
176*202905f3SJasvinder Singh 
177*202905f3SJasvinder Singh 	swq = softnic_swq_create(softnic, name, &p);
178*202905f3SJasvinder Singh 	if (swq == NULL) {
179*202905f3SJasvinder Singh 		snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
180*202905f3SJasvinder Singh 		return;
181*202905f3SJasvinder Singh 	}
182*202905f3SJasvinder Singh }
183*202905f3SJasvinder Singh 
184*202905f3SJasvinder Singh /**
185*202905f3SJasvinder Singh  * tap <tap_name>
186*202905f3SJasvinder Singh  */
187*202905f3SJasvinder Singh static void
188*202905f3SJasvinder Singh cmd_tap(struct pmd_internals *softnic,
189*202905f3SJasvinder Singh 	char **tokens,
190*202905f3SJasvinder Singh 	uint32_t n_tokens,
191*202905f3SJasvinder Singh 	char *out,
192*202905f3SJasvinder Singh 	size_t out_size)
193*202905f3SJasvinder Singh {
194*202905f3SJasvinder Singh 	char *name;
195*202905f3SJasvinder Singh 	struct softnic_tap *tap;
196*202905f3SJasvinder Singh 
197*202905f3SJasvinder Singh 	if (n_tokens != 2) {
198*202905f3SJasvinder Singh 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
199*202905f3SJasvinder Singh 		return;
200*202905f3SJasvinder Singh 	}
201*202905f3SJasvinder Singh 
202*202905f3SJasvinder Singh 	name = tokens[1];
203*202905f3SJasvinder Singh 
204*202905f3SJasvinder Singh 	tap = softnic_tap_create(softnic, name);
205*202905f3SJasvinder Singh 	if (tap == NULL) {
206*202905f3SJasvinder Singh 		snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
207*202905f3SJasvinder Singh 		return;
208*202905f3SJasvinder Singh 	}
209*202905f3SJasvinder Singh }
210*202905f3SJasvinder Singh 
211*202905f3SJasvinder Singh /**
212*202905f3SJasvinder Singh  * port in action profile <profile_name>
213*202905f3SJasvinder Singh  *  [filter match | mismatch offset <key_offset> mask <key_mask> key <key_value> port <port_id>]
214*202905f3SJasvinder Singh  *  [balance offset <key_offset> mask <key_mask> port <port_id0> ... <port_id15>]
215*202905f3SJasvinder Singh  */
216*202905f3SJasvinder Singh static void
217*202905f3SJasvinder Singh cmd_port_in_action_profile(struct pmd_internals *softnic,
218*202905f3SJasvinder Singh 	char **tokens,
219*202905f3SJasvinder Singh 	uint32_t n_tokens,
220*202905f3SJasvinder Singh 	char *out,
221*202905f3SJasvinder Singh 	size_t out_size)
222*202905f3SJasvinder Singh {
223*202905f3SJasvinder Singh 	struct softnic_port_in_action_profile_params p;
224*202905f3SJasvinder Singh 	struct softnic_port_in_action_profile *ap;
225*202905f3SJasvinder Singh 	char *name;
226*202905f3SJasvinder Singh 	uint32_t t0;
227*202905f3SJasvinder Singh 
228*202905f3SJasvinder Singh 	memset(&p, 0, sizeof(p));
229*202905f3SJasvinder Singh 
230*202905f3SJasvinder Singh 	if (n_tokens < 5) {
231*202905f3SJasvinder Singh 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
232*202905f3SJasvinder Singh 		return;
233*202905f3SJasvinder Singh 	}
234*202905f3SJasvinder Singh 
235*202905f3SJasvinder Singh 	if (strcmp(tokens[1], "in") != 0) {
236*202905f3SJasvinder Singh 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "in");
237*202905f3SJasvinder Singh 		return;
238*202905f3SJasvinder Singh 	}
239*202905f3SJasvinder Singh 
240*202905f3SJasvinder Singh 	if (strcmp(tokens[2], "action") != 0) {
241*202905f3SJasvinder Singh 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "action");
242*202905f3SJasvinder Singh 		return;
243*202905f3SJasvinder Singh 	}
244*202905f3SJasvinder Singh 
245*202905f3SJasvinder Singh 	if (strcmp(tokens[3], "profile") != 0) {
246*202905f3SJasvinder Singh 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "profile");
247*202905f3SJasvinder Singh 		return;
248*202905f3SJasvinder Singh 	}
249*202905f3SJasvinder Singh 
250*202905f3SJasvinder Singh 	name = tokens[4];
251*202905f3SJasvinder Singh 
252*202905f3SJasvinder Singh 	t0 = 5;
253*202905f3SJasvinder Singh 
254*202905f3SJasvinder Singh 	if (t0 < n_tokens &&
255*202905f3SJasvinder Singh 		(strcmp(tokens[t0], "filter") == 0)) {
256*202905f3SJasvinder Singh 		uint32_t size;
257*202905f3SJasvinder Singh 
258*202905f3SJasvinder Singh 		if (n_tokens < t0 + 10) {
259*202905f3SJasvinder Singh 			snprintf(out, out_size, MSG_ARG_MISMATCH, "port in action profile filter");
260*202905f3SJasvinder Singh 			return;
261*202905f3SJasvinder Singh 		}
262*202905f3SJasvinder Singh 
263*202905f3SJasvinder Singh 		if (strcmp(tokens[t0 + 1], "match") == 0) {
264*202905f3SJasvinder Singh 			p.fltr.filter_on_match = 1;
265*202905f3SJasvinder Singh 		} else if (strcmp(tokens[t0 + 1], "mismatch") == 0) {
266*202905f3SJasvinder Singh 			p.fltr.filter_on_match = 0;
267*202905f3SJasvinder Singh 		} else {
268*202905f3SJasvinder Singh 			snprintf(out, out_size, MSG_ARG_INVALID, "match or mismatch");
269*202905f3SJasvinder Singh 			return;
270*202905f3SJasvinder Singh 		}
271*202905f3SJasvinder Singh 
272*202905f3SJasvinder Singh 		if (strcmp(tokens[t0 + 2], "offset") != 0) {
273*202905f3SJasvinder Singh 			snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
274*202905f3SJasvinder Singh 			return;
275*202905f3SJasvinder Singh 		}
276*202905f3SJasvinder Singh 
277*202905f3SJasvinder Singh 		if (softnic_parser_read_uint32(&p.fltr.key_offset,
278*202905f3SJasvinder Singh 			tokens[t0 + 3]) != 0) {
279*202905f3SJasvinder Singh 			snprintf(out, out_size, MSG_ARG_INVALID, "key_offset");
280*202905f3SJasvinder Singh 			return;
281*202905f3SJasvinder Singh 		}
282*202905f3SJasvinder Singh 
283*202905f3SJasvinder Singh 		if (strcmp(tokens[t0 + 4], "mask") != 0) {
284*202905f3SJasvinder Singh 			snprintf(out, out_size, MSG_ARG_NOT_FOUND, "mask");
285*202905f3SJasvinder Singh 			return;
286*202905f3SJasvinder Singh 		}
287*202905f3SJasvinder Singh 
288*202905f3SJasvinder Singh 		size = RTE_PORT_IN_ACTION_FLTR_KEY_SIZE;
289*202905f3SJasvinder Singh 		if ((softnic_parse_hex_string(tokens[t0 + 5],
290*202905f3SJasvinder Singh 			p.fltr.key_mask, &size) != 0) ||
291*202905f3SJasvinder Singh 			size != RTE_PORT_IN_ACTION_FLTR_KEY_SIZE) {
292*202905f3SJasvinder Singh 			snprintf(out, out_size, MSG_ARG_INVALID, "key_mask");
293*202905f3SJasvinder Singh 			return;
294*202905f3SJasvinder Singh 		}
295*202905f3SJasvinder Singh 
296*202905f3SJasvinder Singh 		if (strcmp(tokens[t0 + 6], "key") != 0) {
297*202905f3SJasvinder Singh 			snprintf(out, out_size, MSG_ARG_NOT_FOUND, "key");
298*202905f3SJasvinder Singh 			return;
299*202905f3SJasvinder Singh 		}
300*202905f3SJasvinder Singh 
301*202905f3SJasvinder Singh 		size = RTE_PORT_IN_ACTION_FLTR_KEY_SIZE;
302*202905f3SJasvinder Singh 		if ((softnic_parse_hex_string(tokens[t0 + 7],
303*202905f3SJasvinder Singh 			p.fltr.key, &size) != 0) ||
304*202905f3SJasvinder Singh 			size != RTE_PORT_IN_ACTION_FLTR_KEY_SIZE) {
305*202905f3SJasvinder Singh 			snprintf(out, out_size, MSG_ARG_INVALID, "key_value");
306*202905f3SJasvinder Singh 			return;
307*202905f3SJasvinder Singh 		}
308*202905f3SJasvinder Singh 
309*202905f3SJasvinder Singh 		if (strcmp(tokens[t0 + 8], "port") != 0) {
310*202905f3SJasvinder Singh 			snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
311*202905f3SJasvinder Singh 			return;
312*202905f3SJasvinder Singh 		}
313*202905f3SJasvinder Singh 
314*202905f3SJasvinder Singh 		if (softnic_parser_read_uint32(&p.fltr.port_id,
315*202905f3SJasvinder Singh 			tokens[t0 + 9]) != 0) {
316*202905f3SJasvinder Singh 			snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
317*202905f3SJasvinder Singh 			return;
318*202905f3SJasvinder Singh 		}
319*202905f3SJasvinder Singh 
320*202905f3SJasvinder Singh 		p.action_mask |= 1LLU << RTE_PORT_IN_ACTION_FLTR;
321*202905f3SJasvinder Singh 		t0 += 10;
322*202905f3SJasvinder Singh 	} /* filter */
323*202905f3SJasvinder Singh 
324*202905f3SJasvinder Singh 	if (t0 < n_tokens &&
325*202905f3SJasvinder Singh 		(strcmp(tokens[t0], "balance") == 0)) {
326*202905f3SJasvinder Singh 		uint32_t i;
327*202905f3SJasvinder Singh 
328*202905f3SJasvinder Singh 		if (n_tokens < t0 + 22) {
329*202905f3SJasvinder Singh 			snprintf(out, out_size, MSG_ARG_MISMATCH,
330*202905f3SJasvinder Singh 				"port in action profile balance");
331*202905f3SJasvinder Singh 			return;
332*202905f3SJasvinder Singh 		}
333*202905f3SJasvinder Singh 
334*202905f3SJasvinder Singh 		if (strcmp(tokens[t0 + 1], "offset") != 0) {
335*202905f3SJasvinder Singh 			snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
336*202905f3SJasvinder Singh 			return;
337*202905f3SJasvinder Singh 		}
338*202905f3SJasvinder Singh 
339*202905f3SJasvinder Singh 		if (softnic_parser_read_uint32(&p.lb.key_offset,
340*202905f3SJasvinder Singh 			tokens[t0 + 2]) != 0) {
341*202905f3SJasvinder Singh 			snprintf(out, out_size, MSG_ARG_INVALID, "key_offset");
342*202905f3SJasvinder Singh 			return;
343*202905f3SJasvinder Singh 		}
344*202905f3SJasvinder Singh 
345*202905f3SJasvinder Singh 		if (strcmp(tokens[t0 + 3], "mask") != 0) {
346*202905f3SJasvinder Singh 			snprintf(out, out_size, MSG_ARG_NOT_FOUND, "mask");
347*202905f3SJasvinder Singh 			return;
348*202905f3SJasvinder Singh 		}
349*202905f3SJasvinder Singh 
350*202905f3SJasvinder Singh 		p.lb.key_size = RTE_PORT_IN_ACTION_LB_KEY_SIZE_MAX;
351*202905f3SJasvinder Singh 		if (softnic_parse_hex_string(tokens[t0 + 4],
352*202905f3SJasvinder Singh 			p.lb.key_mask, &p.lb.key_size) != 0) {
353*202905f3SJasvinder Singh 			snprintf(out, out_size, MSG_ARG_INVALID, "key_mask");
354*202905f3SJasvinder Singh 			return;
355*202905f3SJasvinder Singh 		}
356*202905f3SJasvinder Singh 
357*202905f3SJasvinder Singh 		if (strcmp(tokens[t0 + 5], "port") != 0) {
358*202905f3SJasvinder Singh 			snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
359*202905f3SJasvinder Singh 			return;
360*202905f3SJasvinder Singh 		}
361*202905f3SJasvinder Singh 
362*202905f3SJasvinder Singh 		for (i = 0; i < 16; i++)
363*202905f3SJasvinder Singh 			if (softnic_parser_read_uint32(&p.lb.port_id[i],
364*202905f3SJasvinder Singh 			tokens[t0 + 6 + i]) != 0) {
365*202905f3SJasvinder Singh 				snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
366*202905f3SJasvinder Singh 				return;
367*202905f3SJasvinder Singh 			}
368*202905f3SJasvinder Singh 
369*202905f3SJasvinder Singh 		p.action_mask |= 1LLU << RTE_PORT_IN_ACTION_LB;
370*202905f3SJasvinder Singh 		t0 += 22;
371*202905f3SJasvinder Singh 	} /* balance */
372*202905f3SJasvinder Singh 
373*202905f3SJasvinder Singh 	if (t0 < n_tokens) {
374*202905f3SJasvinder Singh 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
375*202905f3SJasvinder Singh 		return;
376*202905f3SJasvinder Singh 	}
377*202905f3SJasvinder Singh 
378*202905f3SJasvinder Singh 	ap = softnic_port_in_action_profile_create(softnic, name, &p);
379*202905f3SJasvinder Singh 	if (ap == NULL) {
380*202905f3SJasvinder Singh 		snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
381*202905f3SJasvinder Singh 		return;
382*202905f3SJasvinder Singh 	}
383*202905f3SJasvinder Singh }
384*202905f3SJasvinder Singh 
385*202905f3SJasvinder Singh /**
386*202905f3SJasvinder Singh  * table action profile <profile_name>
387*202905f3SJasvinder Singh  *  ipv4 | ipv6
388*202905f3SJasvinder Singh  *  offset <ip_offset>
389*202905f3SJasvinder Singh  *  fwd
390*202905f3SJasvinder Singh  *  [balance offset <key_offset> mask <key_mask> outoffset <out_offset>]
391*202905f3SJasvinder Singh  *  [meter srtcm | trtcm
392*202905f3SJasvinder Singh  *      tc <n_tc>
393*202905f3SJasvinder Singh  *      stats none | pkts | bytes | both]
394*202905f3SJasvinder Singh  *  [tm spp <n_subports_per_port> pps <n_pipes_per_subport>]
395*202905f3SJasvinder Singh  *  [encap ether | vlan | qinq | mpls | pppoe]
396*202905f3SJasvinder Singh  *  [nat src | dst
397*202905f3SJasvinder Singh  *      proto udp | tcp]
398*202905f3SJasvinder Singh  *  [ttl drop | fwd
399*202905f3SJasvinder Singh  *      stats none | pkts]
400*202905f3SJasvinder Singh  *  [stats pkts | bytes | both]
401*202905f3SJasvinder Singh  *  [time]
402*202905f3SJasvinder Singh  */
403*202905f3SJasvinder Singh static void
404*202905f3SJasvinder Singh cmd_table_action_profile(struct pmd_internals *softnic,
405*202905f3SJasvinder Singh 	char **tokens,
406*202905f3SJasvinder Singh 	uint32_t n_tokens,
407*202905f3SJasvinder Singh 	char *out,
408*202905f3SJasvinder Singh 	size_t out_size)
409*202905f3SJasvinder Singh {
410*202905f3SJasvinder Singh 	struct softnic_table_action_profile_params p;
411*202905f3SJasvinder Singh 	struct softnic_table_action_profile *ap;
412*202905f3SJasvinder Singh 	char *name;
413*202905f3SJasvinder Singh 	uint32_t t0;
414*202905f3SJasvinder Singh 
415*202905f3SJasvinder Singh 	memset(&p, 0, sizeof(p));
416*202905f3SJasvinder Singh 
417*202905f3SJasvinder Singh 	if (n_tokens < 8) {
418*202905f3SJasvinder Singh 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
419*202905f3SJasvinder Singh 		return;
420*202905f3SJasvinder Singh 	}
421*202905f3SJasvinder Singh 
422*202905f3SJasvinder Singh 	if (strcmp(tokens[1], "action") != 0) {
423*202905f3SJasvinder Singh 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "action");
424*202905f3SJasvinder Singh 		return;
425*202905f3SJasvinder Singh 	}
426*202905f3SJasvinder Singh 
427*202905f3SJasvinder Singh 	if (strcmp(tokens[2], "profile") != 0) {
428*202905f3SJasvinder Singh 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "profile");
429*202905f3SJasvinder Singh 		return;
430*202905f3SJasvinder Singh 	}
431*202905f3SJasvinder Singh 
432*202905f3SJasvinder Singh 	name = tokens[3];
433*202905f3SJasvinder Singh 
434*202905f3SJasvinder Singh 	if (strcmp(tokens[4], "ipv4") == 0) {
435*202905f3SJasvinder Singh 		p.common.ip_version = 1;
436*202905f3SJasvinder Singh 	} else if (strcmp(tokens[4], "ipv6") == 0) {
437*202905f3SJasvinder Singh 		p.common.ip_version = 0;
438*202905f3SJasvinder Singh 	} else {
439*202905f3SJasvinder Singh 		snprintf(out, out_size, MSG_ARG_INVALID, "ipv4 or ipv6");
440*202905f3SJasvinder Singh 		return;
441*202905f3SJasvinder Singh 	}
442*202905f3SJasvinder Singh 
443*202905f3SJasvinder Singh 	if (strcmp(tokens[5], "offset") != 0) {
444*202905f3SJasvinder Singh 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
445*202905f3SJasvinder Singh 		return;
446*202905f3SJasvinder Singh 	}
447*202905f3SJasvinder Singh 
448*202905f3SJasvinder Singh 	if (softnic_parser_read_uint32(&p.common.ip_offset,
449*202905f3SJasvinder Singh 		tokens[6]) != 0) {
450*202905f3SJasvinder Singh 		snprintf(out, out_size, MSG_ARG_INVALID, "ip_offset");
451*202905f3SJasvinder Singh 		return;
452*202905f3SJasvinder Singh 	}
453*202905f3SJasvinder Singh 
454*202905f3SJasvinder Singh 	if (strcmp(tokens[7], "fwd") != 0) {
455*202905f3SJasvinder Singh 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "fwd");
456*202905f3SJasvinder Singh 		return;
457*202905f3SJasvinder Singh 	}
458*202905f3SJasvinder Singh 
459*202905f3SJasvinder Singh 	p.action_mask |= 1LLU << RTE_TABLE_ACTION_FWD;
460*202905f3SJasvinder Singh 
461*202905f3SJasvinder Singh 	t0 = 8;
462*202905f3SJasvinder Singh 	if (t0 < n_tokens &&
463*202905f3SJasvinder Singh 		(strcmp(tokens[t0], "balance") == 0)) {
464*202905f3SJasvinder Singh 		if (n_tokens < t0 + 7) {
465*202905f3SJasvinder Singh 			snprintf(out, out_size, MSG_ARG_MISMATCH, "table action profile balance");
466*202905f3SJasvinder Singh 			return;
467*202905f3SJasvinder Singh 		}
468*202905f3SJasvinder Singh 
469*202905f3SJasvinder Singh 		if (strcmp(tokens[t0 + 1], "offset") != 0) {
470*202905f3SJasvinder Singh 			snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
471*202905f3SJasvinder Singh 			return;
472*202905f3SJasvinder Singh 		}
473*202905f3SJasvinder Singh 
474*202905f3SJasvinder Singh 		if (softnic_parser_read_uint32(&p.lb.key_offset,
475*202905f3SJasvinder Singh 			tokens[t0 + 2]) != 0) {
476*202905f3SJasvinder Singh 			snprintf(out, out_size, MSG_ARG_INVALID, "key_offset");
477*202905f3SJasvinder Singh 			return;
478*202905f3SJasvinder Singh 		}
479*202905f3SJasvinder Singh 
480*202905f3SJasvinder Singh 		if (strcmp(tokens[t0 + 3], "mask") != 0) {
481*202905f3SJasvinder Singh 			snprintf(out, out_size, MSG_ARG_NOT_FOUND, "mask");
482*202905f3SJasvinder Singh 			return;
483*202905f3SJasvinder Singh 		}
484*202905f3SJasvinder Singh 
485*202905f3SJasvinder Singh 		p.lb.key_size = RTE_PORT_IN_ACTION_LB_KEY_SIZE_MAX;
486*202905f3SJasvinder Singh 		if (softnic_parse_hex_string(tokens[t0 + 4],
487*202905f3SJasvinder Singh 			p.lb.key_mask, &p.lb.key_size) != 0) {
488*202905f3SJasvinder Singh 			snprintf(out, out_size, MSG_ARG_INVALID, "key_mask");
489*202905f3SJasvinder Singh 			return;
490*202905f3SJasvinder Singh 		}
491*202905f3SJasvinder Singh 
492*202905f3SJasvinder Singh 		if (strcmp(tokens[t0 + 5], "outoffset") != 0) {
493*202905f3SJasvinder Singh 			snprintf(out, out_size, MSG_ARG_NOT_FOUND, "outoffset");
494*202905f3SJasvinder Singh 			return;
495*202905f3SJasvinder Singh 		}
496*202905f3SJasvinder Singh 
497*202905f3SJasvinder Singh 		if (softnic_parser_read_uint32(&p.lb.out_offset,
498*202905f3SJasvinder Singh 			tokens[t0 + 6]) != 0) {
499*202905f3SJasvinder Singh 			snprintf(out, out_size, MSG_ARG_INVALID, "out_offset");
500*202905f3SJasvinder Singh 			return;
501*202905f3SJasvinder Singh 		}
502*202905f3SJasvinder Singh 
503*202905f3SJasvinder Singh 		p.action_mask |= 1LLU << RTE_TABLE_ACTION_LB;
504*202905f3SJasvinder Singh 		t0 += 7;
505*202905f3SJasvinder Singh 	} /* balance */
506*202905f3SJasvinder Singh 
507*202905f3SJasvinder Singh 	if (t0 < n_tokens &&
508*202905f3SJasvinder Singh 		(strcmp(tokens[t0], "meter") == 0)) {
509*202905f3SJasvinder Singh 		if (n_tokens < t0 + 6) {
510*202905f3SJasvinder Singh 			snprintf(out, out_size, MSG_ARG_MISMATCH,
511*202905f3SJasvinder Singh 				"table action profile meter");
512*202905f3SJasvinder Singh 			return;
513*202905f3SJasvinder Singh 		}
514*202905f3SJasvinder Singh 
515*202905f3SJasvinder Singh 		if (strcmp(tokens[t0 + 1], "srtcm") == 0) {
516*202905f3SJasvinder Singh 			p.mtr.alg = RTE_TABLE_ACTION_METER_SRTCM;
517*202905f3SJasvinder Singh 		} else if (strcmp(tokens[t0 + 1], "trtcm") == 0) {
518*202905f3SJasvinder Singh 			p.mtr.alg = RTE_TABLE_ACTION_METER_TRTCM;
519*202905f3SJasvinder Singh 		} else {
520*202905f3SJasvinder Singh 			snprintf(out, out_size, MSG_ARG_NOT_FOUND,
521*202905f3SJasvinder Singh 				"srtcm or trtcm");
522*202905f3SJasvinder Singh 			return;
523*202905f3SJasvinder Singh 		}
524*202905f3SJasvinder Singh 
525*202905f3SJasvinder Singh 		if (strcmp(tokens[t0 + 2], "tc") != 0) {
526*202905f3SJasvinder Singh 			snprintf(out, out_size, MSG_ARG_NOT_FOUND, "tc");
527*202905f3SJasvinder Singh 			return;
528*202905f3SJasvinder Singh 		}
529*202905f3SJasvinder Singh 
530*202905f3SJasvinder Singh 		if (softnic_parser_read_uint32(&p.mtr.n_tc,
531*202905f3SJasvinder Singh 			tokens[t0 + 3]) != 0) {
532*202905f3SJasvinder Singh 			snprintf(out, out_size, MSG_ARG_INVALID, "n_tc");
533*202905f3SJasvinder Singh 			return;
534*202905f3SJasvinder Singh 		}
535*202905f3SJasvinder Singh 
536*202905f3SJasvinder Singh 		if (strcmp(tokens[t0 + 4], "stats") != 0) {
537*202905f3SJasvinder Singh 			snprintf(out, out_size, MSG_ARG_NOT_FOUND, "stats");
538*202905f3SJasvinder Singh 			return;
539*202905f3SJasvinder Singh 		}
540*202905f3SJasvinder Singh 
541*202905f3SJasvinder Singh 		if (strcmp(tokens[t0 + 5], "none") == 0) {
542*202905f3SJasvinder Singh 			p.mtr.n_packets_enabled = 0;
543*202905f3SJasvinder Singh 			p.mtr.n_bytes_enabled = 0;
544*202905f3SJasvinder Singh 		} else if (strcmp(tokens[t0 + 5], "pkts") == 0) {
545*202905f3SJasvinder Singh 			p.mtr.n_packets_enabled = 1;
546*202905f3SJasvinder Singh 			p.mtr.n_bytes_enabled = 0;
547*202905f3SJasvinder Singh 		} else if (strcmp(tokens[t0 + 5], "bytes") == 0) {
548*202905f3SJasvinder Singh 			p.mtr.n_packets_enabled = 0;
549*202905f3SJasvinder Singh 			p.mtr.n_bytes_enabled = 1;
550*202905f3SJasvinder Singh 		} else if (strcmp(tokens[t0 + 5], "both") == 0) {
551*202905f3SJasvinder Singh 			p.mtr.n_packets_enabled = 1;
552*202905f3SJasvinder Singh 			p.mtr.n_bytes_enabled = 1;
553*202905f3SJasvinder Singh 		} else {
554*202905f3SJasvinder Singh 			snprintf(out, out_size, MSG_ARG_NOT_FOUND,
555*202905f3SJasvinder Singh 				"none or pkts or bytes or both");
556*202905f3SJasvinder Singh 			return;
557*202905f3SJasvinder Singh 		}
558*202905f3SJasvinder Singh 
559*202905f3SJasvinder Singh 		p.action_mask |= 1LLU << RTE_TABLE_ACTION_MTR;
560*202905f3SJasvinder Singh 		t0 += 6;
561*202905f3SJasvinder Singh 	} /* meter */
562*202905f3SJasvinder Singh 
563*202905f3SJasvinder Singh 	if (t0 < n_tokens &&
564*202905f3SJasvinder Singh 		(strcmp(tokens[t0], "tm") == 0)) {
565*202905f3SJasvinder Singh 		if (n_tokens < t0 + 5) {
566*202905f3SJasvinder Singh 			snprintf(out, out_size, MSG_ARG_MISMATCH,
567*202905f3SJasvinder Singh 				"table action profile tm");
568*202905f3SJasvinder Singh 			return;
569*202905f3SJasvinder Singh 		}
570*202905f3SJasvinder Singh 
571*202905f3SJasvinder Singh 		if (strcmp(tokens[t0 + 1], "spp") != 0) {
572*202905f3SJasvinder Singh 			snprintf(out, out_size, MSG_ARG_NOT_FOUND, "spp");
573*202905f3SJasvinder Singh 			return;
574*202905f3SJasvinder Singh 		}
575*202905f3SJasvinder Singh 
576*202905f3SJasvinder Singh 		if (softnic_parser_read_uint32(&p.tm.n_subports_per_port,
577*202905f3SJasvinder Singh 			tokens[t0 + 2]) != 0) {
578*202905f3SJasvinder Singh 			snprintf(out, out_size, MSG_ARG_INVALID,
579*202905f3SJasvinder Singh 				"n_subports_per_port");
580*202905f3SJasvinder Singh 			return;
581*202905f3SJasvinder Singh 		}
582*202905f3SJasvinder Singh 
583*202905f3SJasvinder Singh 		if (strcmp(tokens[t0 + 3], "pps") != 0) {
584*202905f3SJasvinder Singh 			snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pps");
585*202905f3SJasvinder Singh 			return;
586*202905f3SJasvinder Singh 		}
587*202905f3SJasvinder Singh 
588*202905f3SJasvinder Singh 		if (softnic_parser_read_uint32(&p.tm.n_pipes_per_subport,
589*202905f3SJasvinder Singh 			tokens[t0 + 4]) != 0) {
590*202905f3SJasvinder Singh 			snprintf(out, out_size, MSG_ARG_INVALID,
591*202905f3SJasvinder Singh 				"n_pipes_per_subport");
592*202905f3SJasvinder Singh 			return;
593*202905f3SJasvinder Singh 		}
594*202905f3SJasvinder Singh 
595*202905f3SJasvinder Singh 		p.action_mask |= 1LLU << RTE_TABLE_ACTION_TM;
596*202905f3SJasvinder Singh 		t0 += 5;
597*202905f3SJasvinder Singh 	} /* tm */
598*202905f3SJasvinder Singh 
599*202905f3SJasvinder Singh 	if (t0 < n_tokens &&
600*202905f3SJasvinder Singh 		(strcmp(tokens[t0], "encap") == 0)) {
601*202905f3SJasvinder Singh 		if (n_tokens < t0 + 2) {
602*202905f3SJasvinder Singh 			snprintf(out, out_size, MSG_ARG_MISMATCH,
603*202905f3SJasvinder Singh 				"action profile encap");
604*202905f3SJasvinder Singh 			return;
605*202905f3SJasvinder Singh 		}
606*202905f3SJasvinder Singh 
607*202905f3SJasvinder Singh 		if (strcmp(tokens[t0 + 1], "ether") == 0) {
608*202905f3SJasvinder Singh 			p.encap.encap_mask = 1LLU << RTE_TABLE_ACTION_ENCAP_ETHER;
609*202905f3SJasvinder Singh 		} else if (strcmp(tokens[t0 + 1], "vlan") == 0) {
610*202905f3SJasvinder Singh 			p.encap.encap_mask = 1LLU << RTE_TABLE_ACTION_ENCAP_VLAN;
611*202905f3SJasvinder Singh 		} else if (strcmp(tokens[t0 + 1], "qinq") == 0) {
612*202905f3SJasvinder Singh 			p.encap.encap_mask = 1LLU << RTE_TABLE_ACTION_ENCAP_QINQ;
613*202905f3SJasvinder Singh 		} else if (strcmp(tokens[t0 + 1], "mpls") == 0) {
614*202905f3SJasvinder Singh 			p.encap.encap_mask = 1LLU << RTE_TABLE_ACTION_ENCAP_MPLS;
615*202905f3SJasvinder Singh 		} else if (strcmp(tokens[t0 + 1], "pppoe") == 0) {
616*202905f3SJasvinder Singh 			p.encap.encap_mask = 1LLU << RTE_TABLE_ACTION_ENCAP_PPPOE;
617*202905f3SJasvinder Singh 		} else {
618*202905f3SJasvinder Singh 			snprintf(out, out_size, MSG_ARG_MISMATCH, "encap");
619*202905f3SJasvinder Singh 			return;
620*202905f3SJasvinder Singh 		}
621*202905f3SJasvinder Singh 
622*202905f3SJasvinder Singh 		p.action_mask |= 1LLU << RTE_TABLE_ACTION_ENCAP;
623*202905f3SJasvinder Singh 		t0 += 2;
624*202905f3SJasvinder Singh 	} /* encap */
625*202905f3SJasvinder Singh 
626*202905f3SJasvinder Singh 	if (t0 < n_tokens &&
627*202905f3SJasvinder Singh 		(strcmp(tokens[t0], "nat") == 0)) {
628*202905f3SJasvinder Singh 		if (n_tokens < t0 + 4) {
629*202905f3SJasvinder Singh 			snprintf(out, out_size, MSG_ARG_MISMATCH,
630*202905f3SJasvinder Singh 				"table action profile nat");
631*202905f3SJasvinder Singh 			return;
632*202905f3SJasvinder Singh 		}
633*202905f3SJasvinder Singh 
634*202905f3SJasvinder Singh 		if (strcmp(tokens[t0 + 1], "src") == 0) {
635*202905f3SJasvinder Singh 			p.nat.source_nat = 1;
636*202905f3SJasvinder Singh 		} else if (strcmp(tokens[t0 + 1], "dst") == 0) {
637*202905f3SJasvinder Singh 			p.nat.source_nat = 0;
638*202905f3SJasvinder Singh 		} else {
639*202905f3SJasvinder Singh 			snprintf(out, out_size, MSG_ARG_NOT_FOUND,
640*202905f3SJasvinder Singh 				"src or dst");
641*202905f3SJasvinder Singh 			return;
642*202905f3SJasvinder Singh 		}
643*202905f3SJasvinder Singh 
644*202905f3SJasvinder Singh 		if (strcmp(tokens[t0 + 2], "proto") != 0) {
645*202905f3SJasvinder Singh 			snprintf(out, out_size, MSG_ARG_NOT_FOUND, "proto");
646*202905f3SJasvinder Singh 			return;
647*202905f3SJasvinder Singh 		}
648*202905f3SJasvinder Singh 
649*202905f3SJasvinder Singh 		if (strcmp(tokens[t0 + 3], "tcp") == 0) {
650*202905f3SJasvinder Singh 			p.nat.proto = 0x06;
651*202905f3SJasvinder Singh 		} else if (strcmp(tokens[t0 + 3], "udp") == 0) {
652*202905f3SJasvinder Singh 			p.nat.proto = 0x11;
653*202905f3SJasvinder Singh 		} else {
654*202905f3SJasvinder Singh 			snprintf(out, out_size, MSG_ARG_NOT_FOUND,
655*202905f3SJasvinder Singh 				"tcp or udp");
656*202905f3SJasvinder Singh 			return;
657*202905f3SJasvinder Singh 		}
658*202905f3SJasvinder Singh 
659*202905f3SJasvinder Singh 		p.action_mask |= 1LLU << RTE_TABLE_ACTION_NAT;
660*202905f3SJasvinder Singh 		t0 += 4;
661*202905f3SJasvinder Singh 	} /* nat */
662*202905f3SJasvinder Singh 
663*202905f3SJasvinder Singh 	if (t0 < n_tokens &&
664*202905f3SJasvinder Singh 		(strcmp(tokens[t0], "ttl") == 0)) {
665*202905f3SJasvinder Singh 		if (n_tokens < t0 + 4) {
666*202905f3SJasvinder Singh 			snprintf(out, out_size, MSG_ARG_MISMATCH,
667*202905f3SJasvinder Singh 				"table action profile ttl");
668*202905f3SJasvinder Singh 			return;
669*202905f3SJasvinder Singh 		}
670*202905f3SJasvinder Singh 
671*202905f3SJasvinder Singh 		if (strcmp(tokens[t0 + 1], "drop") == 0) {
672*202905f3SJasvinder Singh 			p.ttl.drop = 1;
673*202905f3SJasvinder Singh 		} else if (strcmp(tokens[t0 + 1], "fwd") == 0) {
674*202905f3SJasvinder Singh 			p.ttl.drop = 0;
675*202905f3SJasvinder Singh 		} else {
676*202905f3SJasvinder Singh 			snprintf(out, out_size, MSG_ARG_NOT_FOUND,
677*202905f3SJasvinder Singh 				"drop or fwd");
678*202905f3SJasvinder Singh 			return;
679*202905f3SJasvinder Singh 		}
680*202905f3SJasvinder Singh 
681*202905f3SJasvinder Singh 		if (strcmp(tokens[t0 + 2], "stats") != 0) {
682*202905f3SJasvinder Singh 			snprintf(out, out_size, MSG_ARG_NOT_FOUND, "stats");
683*202905f3SJasvinder Singh 			return;
684*202905f3SJasvinder Singh 		}
685*202905f3SJasvinder Singh 
686*202905f3SJasvinder Singh 		if (strcmp(tokens[t0 + 3], "none") == 0) {
687*202905f3SJasvinder Singh 			p.ttl.n_packets_enabled = 0;
688*202905f3SJasvinder Singh 		} else if (strcmp(tokens[t0 + 3], "pkts") == 0) {
689*202905f3SJasvinder Singh 			p.ttl.n_packets_enabled = 1;
690*202905f3SJasvinder Singh 		} else {
691*202905f3SJasvinder Singh 			snprintf(out, out_size, MSG_ARG_NOT_FOUND,
692*202905f3SJasvinder Singh 				"none or pkts");
693*202905f3SJasvinder Singh 			return;
694*202905f3SJasvinder Singh 		}
695*202905f3SJasvinder Singh 
696*202905f3SJasvinder Singh 		p.action_mask |= 1LLU << RTE_TABLE_ACTION_TTL;
697*202905f3SJasvinder Singh 		t0 += 4;
698*202905f3SJasvinder Singh 	} /* ttl */
699*202905f3SJasvinder Singh 
700*202905f3SJasvinder Singh 	if (t0 < n_tokens &&
701*202905f3SJasvinder Singh 		(strcmp(tokens[t0], "stats") == 0)) {
702*202905f3SJasvinder Singh 		if (n_tokens < t0 + 2) {
703*202905f3SJasvinder Singh 			snprintf(out, out_size, MSG_ARG_MISMATCH,
704*202905f3SJasvinder Singh 				"table action profile stats");
705*202905f3SJasvinder Singh 			return;
706*202905f3SJasvinder Singh 		}
707*202905f3SJasvinder Singh 
708*202905f3SJasvinder Singh 		if (strcmp(tokens[t0 + 1], "pkts") == 0) {
709*202905f3SJasvinder Singh 			p.stats.n_packets_enabled = 1;
710*202905f3SJasvinder Singh 			p.stats.n_bytes_enabled = 0;
711*202905f3SJasvinder Singh 		} else if (strcmp(tokens[t0 + 1], "bytes") == 0) {
712*202905f3SJasvinder Singh 			p.stats.n_packets_enabled = 0;
713*202905f3SJasvinder Singh 			p.stats.n_bytes_enabled = 1;
714*202905f3SJasvinder Singh 		} else if (strcmp(tokens[t0 + 1], "both") == 0) {
715*202905f3SJasvinder Singh 			p.stats.n_packets_enabled = 1;
716*202905f3SJasvinder Singh 			p.stats.n_bytes_enabled = 1;
717*202905f3SJasvinder Singh 		} else {
718*202905f3SJasvinder Singh 			snprintf(out, out_size,	MSG_ARG_NOT_FOUND,
719*202905f3SJasvinder Singh 				"pkts or bytes or both");
720*202905f3SJasvinder Singh 			return;
721*202905f3SJasvinder Singh 		}
722*202905f3SJasvinder Singh 
723*202905f3SJasvinder Singh 		p.action_mask |= 1LLU << RTE_TABLE_ACTION_STATS;
724*202905f3SJasvinder Singh 		t0 += 2;
725*202905f3SJasvinder Singh 	} /* stats */
726*202905f3SJasvinder Singh 
727*202905f3SJasvinder Singh 	if (t0 < n_tokens &&
728*202905f3SJasvinder Singh 		(strcmp(tokens[t0], "time") == 0)) {
729*202905f3SJasvinder Singh 		p.action_mask |= 1LLU << RTE_TABLE_ACTION_TIME;
730*202905f3SJasvinder Singh 		t0 += 1;
731*202905f3SJasvinder Singh 	} /* time */
732*202905f3SJasvinder Singh 
733*202905f3SJasvinder Singh 	if (t0 < n_tokens) {
734*202905f3SJasvinder Singh 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
735*202905f3SJasvinder Singh 		return;
736*202905f3SJasvinder Singh 	}
737*202905f3SJasvinder Singh 
738*202905f3SJasvinder Singh 	ap = softnic_table_action_profile_create(softnic, name, &p);
739*202905f3SJasvinder Singh 	if (ap == NULL) {
740*202905f3SJasvinder Singh 		snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
741*202905f3SJasvinder Singh 		return;
742*202905f3SJasvinder Singh 	}
743*202905f3SJasvinder Singh }
744*202905f3SJasvinder Singh 
745*202905f3SJasvinder Singh /**
746*202905f3SJasvinder Singh  * pipeline <pipeline_name>
747*202905f3SJasvinder Singh  *  period <timer_period_ms>
748*202905f3SJasvinder Singh  *  offset_port_id <offset_port_id>
749*202905f3SJasvinder Singh  */
750*202905f3SJasvinder Singh static void
751*202905f3SJasvinder Singh cmd_pipeline(struct pmd_internals *softnic,
752*202905f3SJasvinder Singh 	char **tokens,
753*202905f3SJasvinder Singh 	uint32_t n_tokens,
754*202905f3SJasvinder Singh 	char *out,
755*202905f3SJasvinder Singh 	size_t out_size)
756*202905f3SJasvinder Singh {
757*202905f3SJasvinder Singh 	struct pipeline_params p;
758*202905f3SJasvinder Singh 	char *name;
759*202905f3SJasvinder Singh 	struct pipeline *pipeline;
760*202905f3SJasvinder Singh 
761*202905f3SJasvinder Singh 	if (n_tokens != 6) {
762*202905f3SJasvinder Singh 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
763*202905f3SJasvinder Singh 		return;
764*202905f3SJasvinder Singh 	}
765*202905f3SJasvinder Singh 
766*202905f3SJasvinder Singh 	name = tokens[1];
767*202905f3SJasvinder Singh 
768*202905f3SJasvinder Singh 	if (strcmp(tokens[2], "period") != 0) {
769*202905f3SJasvinder Singh 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "period");
770*202905f3SJasvinder Singh 		return;
771*202905f3SJasvinder Singh 	}
772*202905f3SJasvinder Singh 
773*202905f3SJasvinder Singh 	if (softnic_parser_read_uint32(&p.timer_period_ms,
774*202905f3SJasvinder Singh 		tokens[3]) != 0) {
775*202905f3SJasvinder Singh 		snprintf(out, out_size, MSG_ARG_INVALID, "timer_period_ms");
776*202905f3SJasvinder Singh 		return;
777*202905f3SJasvinder Singh 	}
778*202905f3SJasvinder Singh 
779*202905f3SJasvinder Singh 	if (strcmp(tokens[4], "offset_port_id") != 0) {
780*202905f3SJasvinder Singh 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset_port_id");
781*202905f3SJasvinder Singh 		return;
782*202905f3SJasvinder Singh 	}
783*202905f3SJasvinder Singh 
784*202905f3SJasvinder Singh 	if (softnic_parser_read_uint32(&p.offset_port_id,
785*202905f3SJasvinder Singh 		tokens[5]) != 0) {
786*202905f3SJasvinder Singh 		snprintf(out, out_size, MSG_ARG_INVALID, "offset_port_id");
787*202905f3SJasvinder Singh 		return;
788*202905f3SJasvinder Singh 	}
789*202905f3SJasvinder Singh 
790*202905f3SJasvinder Singh 	pipeline = softnic_pipeline_create(softnic, name, &p);
791*202905f3SJasvinder Singh 	if (pipeline == NULL) {
792*202905f3SJasvinder Singh 		snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
793*202905f3SJasvinder Singh 		return;
794*202905f3SJasvinder Singh 	}
795*202905f3SJasvinder Singh }
796*202905f3SJasvinder Singh 
797*202905f3SJasvinder Singh /**
798*202905f3SJasvinder Singh  * pipeline <pipeline_name> port in
799*202905f3SJasvinder Singh  *  bsz <burst_size>
800*202905f3SJasvinder Singh  *  link <link_name> rxq <queue_id>
801*202905f3SJasvinder Singh  *  | swq <swq_name>
802*202905f3SJasvinder Singh  *  | tmgr <tmgr_name>
803*202905f3SJasvinder Singh  *  | tap <tap_name> mempool <mempool_name> mtu <mtu>
804*202905f3SJasvinder Singh  *  | source mempool <mempool_name> file <file_name> bpp <n_bytes_per_pkt>
805*202905f3SJasvinder Singh  *  [action <port_in_action_profile_name>]
806*202905f3SJasvinder Singh  *  [disabled]
807*202905f3SJasvinder Singh  */
808*202905f3SJasvinder Singh static void
809*202905f3SJasvinder Singh cmd_pipeline_port_in(struct pmd_internals *softnic,
810*202905f3SJasvinder Singh 	char **tokens,
811*202905f3SJasvinder Singh 	uint32_t n_tokens,
812*202905f3SJasvinder Singh 	char *out,
813*202905f3SJasvinder Singh 	size_t out_size)
814*202905f3SJasvinder Singh {
815*202905f3SJasvinder Singh 	struct softnic_port_in_params p;
816*202905f3SJasvinder Singh 	char *pipeline_name;
817*202905f3SJasvinder Singh 	uint32_t t0;
818*202905f3SJasvinder Singh 	int enabled, status;
819*202905f3SJasvinder Singh 
820*202905f3SJasvinder Singh 	if (n_tokens < 7) {
821*202905f3SJasvinder Singh 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
822*202905f3SJasvinder Singh 		return;
823*202905f3SJasvinder Singh 	}
824*202905f3SJasvinder Singh 
825*202905f3SJasvinder Singh 	pipeline_name = tokens[1];
826*202905f3SJasvinder Singh 
827*202905f3SJasvinder Singh 	if (strcmp(tokens[2], "port") != 0) {
828*202905f3SJasvinder Singh 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
829*202905f3SJasvinder Singh 		return;
830*202905f3SJasvinder Singh 	}
831*202905f3SJasvinder Singh 
832*202905f3SJasvinder Singh 	if (strcmp(tokens[3], "in") != 0) {
833*202905f3SJasvinder Singh 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "in");
834*202905f3SJasvinder Singh 		return;
835*202905f3SJasvinder Singh 	}
836*202905f3SJasvinder Singh 
837*202905f3SJasvinder Singh 	if (strcmp(tokens[4], "bsz") != 0) {
838*202905f3SJasvinder Singh 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "bsz");
839*202905f3SJasvinder Singh 		return;
840*202905f3SJasvinder Singh 	}
841*202905f3SJasvinder Singh 
842*202905f3SJasvinder Singh 	if (softnic_parser_read_uint32(&p.burst_size, tokens[5]) != 0) {
843*202905f3SJasvinder Singh 		snprintf(out, out_size, MSG_ARG_INVALID, "burst_size");
844*202905f3SJasvinder Singh 		return;
845*202905f3SJasvinder Singh 	}
846*202905f3SJasvinder Singh 
847*202905f3SJasvinder Singh 	t0 = 6;
848*202905f3SJasvinder Singh 
849*202905f3SJasvinder Singh 	if (strcmp(tokens[t0], "link") == 0) {
850*202905f3SJasvinder Singh 		if (n_tokens < t0 + 4) {
851*202905f3SJasvinder Singh 			snprintf(out, out_size, MSG_ARG_MISMATCH,
852*202905f3SJasvinder Singh 				"pipeline port in link");
853*202905f3SJasvinder Singh 			return;
854*202905f3SJasvinder Singh 		}
855*202905f3SJasvinder Singh 
856*202905f3SJasvinder Singh 		p.type = PORT_IN_RXQ;
857*202905f3SJasvinder Singh 
858*202905f3SJasvinder Singh 		p.dev_name = tokens[t0 + 1];
859*202905f3SJasvinder Singh 
860*202905f3SJasvinder Singh 		if (strcmp(tokens[t0 + 2], "rxq") != 0) {
861*202905f3SJasvinder Singh 			snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rxq");
862*202905f3SJasvinder Singh 			return;
863*202905f3SJasvinder Singh 		}
864*202905f3SJasvinder Singh 
865*202905f3SJasvinder Singh 		if (softnic_parser_read_uint16(&p.rxq.queue_id,
866*202905f3SJasvinder Singh 			tokens[t0 + 3]) != 0) {
867*202905f3SJasvinder Singh 			snprintf(out, out_size, MSG_ARG_INVALID,
868*202905f3SJasvinder Singh 				"queue_id");
869*202905f3SJasvinder Singh 			return;
870*202905f3SJasvinder Singh 		}
871*202905f3SJasvinder Singh 		t0 += 4;
872*202905f3SJasvinder Singh 	} else if (strcmp(tokens[t0], "swq") == 0) {
873*202905f3SJasvinder Singh 		if (n_tokens < t0 + 2) {
874*202905f3SJasvinder Singh 			snprintf(out, out_size, MSG_ARG_MISMATCH,
875*202905f3SJasvinder Singh 				"pipeline port in swq");
876*202905f3SJasvinder Singh 			return;
877*202905f3SJasvinder Singh 		}
878*202905f3SJasvinder Singh 
879*202905f3SJasvinder Singh 		p.type = PORT_IN_SWQ;
880*202905f3SJasvinder Singh 
881*202905f3SJasvinder Singh 		p.dev_name = tokens[t0 + 1];
882*202905f3SJasvinder Singh 
883*202905f3SJasvinder Singh 		t0 += 2;
884*202905f3SJasvinder Singh 	} else if (strcmp(tokens[t0], "tmgr") == 0) {
885*202905f3SJasvinder Singh 		if (n_tokens < t0 + 2) {
886*202905f3SJasvinder Singh 			snprintf(out, out_size, MSG_ARG_MISMATCH,
887*202905f3SJasvinder Singh 				"pipeline port in tmgr");
888*202905f3SJasvinder Singh 			return;
889*202905f3SJasvinder Singh 		}
890*202905f3SJasvinder Singh 
891*202905f3SJasvinder Singh 		p.type = PORT_IN_TMGR;
892*202905f3SJasvinder Singh 
893*202905f3SJasvinder Singh 		p.dev_name = tokens[t0 + 1];
894*202905f3SJasvinder Singh 
895*202905f3SJasvinder Singh 		t0 += 2;
896*202905f3SJasvinder Singh 	} else if (strcmp(tokens[t0], "tap") == 0) {
897*202905f3SJasvinder Singh 		if (n_tokens < t0 + 6) {
898*202905f3SJasvinder Singh 			snprintf(out, out_size, MSG_ARG_MISMATCH,
899*202905f3SJasvinder Singh 				"pipeline port in tap");
900*202905f3SJasvinder Singh 			return;
901*202905f3SJasvinder Singh 		}
902*202905f3SJasvinder Singh 
903*202905f3SJasvinder Singh 		p.type = PORT_IN_TAP;
904*202905f3SJasvinder Singh 
905*202905f3SJasvinder Singh 		p.dev_name = tokens[t0 + 1];
906*202905f3SJasvinder Singh 
907*202905f3SJasvinder Singh 		if (strcmp(tokens[t0 + 2], "mempool") != 0) {
908*202905f3SJasvinder Singh 			snprintf(out, out_size, MSG_ARG_NOT_FOUND,
909*202905f3SJasvinder Singh 				"mempool");
910*202905f3SJasvinder Singh 			return;
911*202905f3SJasvinder Singh 		}
912*202905f3SJasvinder Singh 
913*202905f3SJasvinder Singh 		p.tap.mempool_name = tokens[t0 + 3];
914*202905f3SJasvinder Singh 
915*202905f3SJasvinder Singh 		if (strcmp(tokens[t0 + 4], "mtu") != 0) {
916*202905f3SJasvinder Singh 			snprintf(out, out_size, MSG_ARG_NOT_FOUND,
917*202905f3SJasvinder Singh 				"mtu");
918*202905f3SJasvinder Singh 			return;
919*202905f3SJasvinder Singh 		}
920*202905f3SJasvinder Singh 
921*202905f3SJasvinder Singh 		if (softnic_parser_read_uint32(&p.tap.mtu,
922*202905f3SJasvinder Singh 			tokens[t0 + 5]) != 0) {
923*202905f3SJasvinder Singh 			snprintf(out, out_size, MSG_ARG_INVALID, "mtu");
924*202905f3SJasvinder Singh 			return;
925*202905f3SJasvinder Singh 		}
926*202905f3SJasvinder Singh 
927*202905f3SJasvinder Singh 		t0 += 6;
928*202905f3SJasvinder Singh 	} else if (strcmp(tokens[t0], "source") == 0) {
929*202905f3SJasvinder Singh 		if (n_tokens < t0 + 6) {
930*202905f3SJasvinder Singh 			snprintf(out, out_size, MSG_ARG_MISMATCH,
931*202905f3SJasvinder Singh 				"pipeline port in source");
932*202905f3SJasvinder Singh 			return;
933*202905f3SJasvinder Singh 		}
934*202905f3SJasvinder Singh 
935*202905f3SJasvinder Singh 		p.type = PORT_IN_SOURCE;
936*202905f3SJasvinder Singh 
937*202905f3SJasvinder Singh 		p.dev_name = NULL;
938*202905f3SJasvinder Singh 
939*202905f3SJasvinder Singh 		if (strcmp(tokens[t0 + 1], "mempool") != 0) {
940*202905f3SJasvinder Singh 			snprintf(out, out_size, MSG_ARG_NOT_FOUND,
941*202905f3SJasvinder Singh 				"mempool");
942*202905f3SJasvinder Singh 			return;
943*202905f3SJasvinder Singh 		}
944*202905f3SJasvinder Singh 
945*202905f3SJasvinder Singh 		p.source.mempool_name = tokens[t0 + 2];
946*202905f3SJasvinder Singh 
947*202905f3SJasvinder Singh 		if (strcmp(tokens[t0 + 3], "file") != 0) {
948*202905f3SJasvinder Singh 			snprintf(out, out_size, MSG_ARG_NOT_FOUND,
949*202905f3SJasvinder Singh 				"file");
950*202905f3SJasvinder Singh 			return;
951*202905f3SJasvinder Singh 		}
952*202905f3SJasvinder Singh 
953*202905f3SJasvinder Singh 		p.source.file_name = tokens[t0 + 4];
954*202905f3SJasvinder Singh 
955*202905f3SJasvinder Singh 		if (strcmp(tokens[t0 + 5], "bpp") != 0) {
956*202905f3SJasvinder Singh 			snprintf(out, out_size, MSG_ARG_NOT_FOUND,
957*202905f3SJasvinder Singh 				"bpp");
958*202905f3SJasvinder Singh 			return;
959*202905f3SJasvinder Singh 		}
960*202905f3SJasvinder Singh 
961*202905f3SJasvinder Singh 		if (softnic_parser_read_uint32(&p.source.n_bytes_per_pkt,
962*202905f3SJasvinder Singh 			tokens[t0 + 6]) != 0) {
963*202905f3SJasvinder Singh 			snprintf(out, out_size, MSG_ARG_INVALID,
964*202905f3SJasvinder Singh 				"n_bytes_per_pkt");
965*202905f3SJasvinder Singh 			return;
966*202905f3SJasvinder Singh 		}
967*202905f3SJasvinder Singh 
968*202905f3SJasvinder Singh 		t0 += 7;
969*202905f3SJasvinder Singh 	} else {
970*202905f3SJasvinder Singh 		snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
971*202905f3SJasvinder Singh 		return;
972*202905f3SJasvinder Singh 	}
973*202905f3SJasvinder Singh 
974*202905f3SJasvinder Singh 	p.action_profile_name = NULL;
975*202905f3SJasvinder Singh 	if (n_tokens > t0 &&
976*202905f3SJasvinder Singh 		(strcmp(tokens[t0], "action") == 0)) {
977*202905f3SJasvinder Singh 		if (n_tokens < t0 + 2) {
978*202905f3SJasvinder Singh 			snprintf(out, out_size, MSG_ARG_MISMATCH, "action");
979*202905f3SJasvinder Singh 			return;
980*202905f3SJasvinder Singh 		}
981*202905f3SJasvinder Singh 
982*202905f3SJasvinder Singh 		p.action_profile_name = tokens[t0 + 1];
983*202905f3SJasvinder Singh 
984*202905f3SJasvinder Singh 		t0 += 2;
985*202905f3SJasvinder Singh 	}
986*202905f3SJasvinder Singh 
987*202905f3SJasvinder Singh 	enabled = 1;
988*202905f3SJasvinder Singh 	if (n_tokens > t0 &&
989*202905f3SJasvinder Singh 		(strcmp(tokens[t0], "disabled") == 0)) {
990*202905f3SJasvinder Singh 		enabled = 0;
991*202905f3SJasvinder Singh 
992*202905f3SJasvinder Singh 		t0 += 1;
993*202905f3SJasvinder Singh 	}
994*202905f3SJasvinder Singh 
995*202905f3SJasvinder Singh 	if (n_tokens != t0) {
996*202905f3SJasvinder Singh 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
997*202905f3SJasvinder Singh 		return;
998*202905f3SJasvinder Singh 	}
999*202905f3SJasvinder Singh 
1000*202905f3SJasvinder Singh 	status = softnic_pipeline_port_in_create(softnic,
1001*202905f3SJasvinder Singh 		pipeline_name,
1002*202905f3SJasvinder Singh 		&p,
1003*202905f3SJasvinder Singh 		enabled);
1004*202905f3SJasvinder Singh 	if (status) {
1005*202905f3SJasvinder Singh 		snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
1006*202905f3SJasvinder Singh 		return;
1007*202905f3SJasvinder Singh 	}
1008*202905f3SJasvinder Singh }
1009*202905f3SJasvinder Singh 
1010*202905f3SJasvinder Singh /**
1011*202905f3SJasvinder Singh  * pipeline <pipeline_name> port out
1012*202905f3SJasvinder Singh  *  bsz <burst_size>
1013*202905f3SJasvinder Singh  *  link <link_name> txq <txq_id>
1014*202905f3SJasvinder Singh  *  | swq <swq_name>
1015*202905f3SJasvinder Singh  *  | tmgr <tmgr_name>
1016*202905f3SJasvinder Singh  *  | tap <tap_name>
1017*202905f3SJasvinder Singh  *  | sink [file <file_name> pkts <max_n_pkts>]
1018*202905f3SJasvinder Singh  */
1019*202905f3SJasvinder Singh static void
1020*202905f3SJasvinder Singh cmd_pipeline_port_out(struct pmd_internals *softnic,
1021*202905f3SJasvinder Singh 	char **tokens,
1022*202905f3SJasvinder Singh 	uint32_t n_tokens,
1023*202905f3SJasvinder Singh 	char *out,
1024*202905f3SJasvinder Singh 	size_t out_size)
1025*202905f3SJasvinder Singh {
1026*202905f3SJasvinder Singh 	struct softnic_port_out_params p;
1027*202905f3SJasvinder Singh 	char *pipeline_name;
1028*202905f3SJasvinder Singh 	int status;
1029*202905f3SJasvinder Singh 
1030*202905f3SJasvinder Singh 	memset(&p, 0, sizeof(p));
1031*202905f3SJasvinder Singh 
1032*202905f3SJasvinder Singh 	if (n_tokens < 7) {
1033*202905f3SJasvinder Singh 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1034*202905f3SJasvinder Singh 		return;
1035*202905f3SJasvinder Singh 	}
1036*202905f3SJasvinder Singh 
1037*202905f3SJasvinder Singh 	pipeline_name = tokens[1];
1038*202905f3SJasvinder Singh 
1039*202905f3SJasvinder Singh 	if (strcmp(tokens[2], "port") != 0) {
1040*202905f3SJasvinder Singh 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
1041*202905f3SJasvinder Singh 		return;
1042*202905f3SJasvinder Singh 	}
1043*202905f3SJasvinder Singh 
1044*202905f3SJasvinder Singh 	if (strcmp(tokens[3], "out") != 0) {
1045*202905f3SJasvinder Singh 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "out");
1046*202905f3SJasvinder Singh 		return;
1047*202905f3SJasvinder Singh 	}
1048*202905f3SJasvinder Singh 
1049*202905f3SJasvinder Singh 	if (strcmp(tokens[4], "bsz") != 0) {
1050*202905f3SJasvinder Singh 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "bsz");
1051*202905f3SJasvinder Singh 		return;
1052*202905f3SJasvinder Singh 	}
1053*202905f3SJasvinder Singh 
1054*202905f3SJasvinder Singh 	if (softnic_parser_read_uint32(&p.burst_size, tokens[5]) != 0) {
1055*202905f3SJasvinder Singh 		snprintf(out, out_size, MSG_ARG_INVALID, "burst_size");
1056*202905f3SJasvinder Singh 		return;
1057*202905f3SJasvinder Singh 	}
1058*202905f3SJasvinder Singh 
1059*202905f3SJasvinder Singh 	if (strcmp(tokens[6], "link") == 0) {
1060*202905f3SJasvinder Singh 		if (n_tokens != 10) {
1061*202905f3SJasvinder Singh 			snprintf(out, out_size, MSG_ARG_MISMATCH,
1062*202905f3SJasvinder Singh 				"pipeline port out link");
1063*202905f3SJasvinder Singh 			return;
1064*202905f3SJasvinder Singh 		}
1065*202905f3SJasvinder Singh 
1066*202905f3SJasvinder Singh 		p.type = PORT_OUT_TXQ;
1067*202905f3SJasvinder Singh 
1068*202905f3SJasvinder Singh 		p.dev_name = tokens[7];
1069*202905f3SJasvinder Singh 
1070*202905f3SJasvinder Singh 		if (strcmp(tokens[8], "txq") != 0) {
1071*202905f3SJasvinder Singh 			snprintf(out, out_size, MSG_ARG_NOT_FOUND, "txq");
1072*202905f3SJasvinder Singh 			return;
1073*202905f3SJasvinder Singh 		}
1074*202905f3SJasvinder Singh 
1075*202905f3SJasvinder Singh 		if (softnic_parser_read_uint16(&p.txq.queue_id,
1076*202905f3SJasvinder Singh 			tokens[9]) != 0) {
1077*202905f3SJasvinder Singh 			snprintf(out, out_size, MSG_ARG_INVALID, "queue_id");
1078*202905f3SJasvinder Singh 			return;
1079*202905f3SJasvinder Singh 		}
1080*202905f3SJasvinder Singh 	} else if (strcmp(tokens[6], "swq") == 0) {
1081*202905f3SJasvinder Singh 		if (n_tokens != 8) {
1082*202905f3SJasvinder Singh 			snprintf(out, out_size, MSG_ARG_MISMATCH,
1083*202905f3SJasvinder Singh 				"pipeline port out swq");
1084*202905f3SJasvinder Singh 			return;
1085*202905f3SJasvinder Singh 		}
1086*202905f3SJasvinder Singh 
1087*202905f3SJasvinder Singh 		p.type = PORT_OUT_SWQ;
1088*202905f3SJasvinder Singh 
1089*202905f3SJasvinder Singh 		p.dev_name = tokens[7];
1090*202905f3SJasvinder Singh 	} else if (strcmp(tokens[6], "tmgr") == 0) {
1091*202905f3SJasvinder Singh 		if (n_tokens != 8) {
1092*202905f3SJasvinder Singh 			snprintf(out, out_size, MSG_ARG_MISMATCH,
1093*202905f3SJasvinder Singh 				"pipeline port out tmgr");
1094*202905f3SJasvinder Singh 			return;
1095*202905f3SJasvinder Singh 		}
1096*202905f3SJasvinder Singh 
1097*202905f3SJasvinder Singh 		p.type = PORT_OUT_TMGR;
1098*202905f3SJasvinder Singh 
1099*202905f3SJasvinder Singh 		p.dev_name = tokens[7];
1100*202905f3SJasvinder Singh 	} else if (strcmp(tokens[6], "tap") == 0) {
1101*202905f3SJasvinder Singh 		if (n_tokens != 8) {
1102*202905f3SJasvinder Singh 			snprintf(out, out_size, MSG_ARG_MISMATCH,
1103*202905f3SJasvinder Singh 				"pipeline port out tap");
1104*202905f3SJasvinder Singh 			return;
1105*202905f3SJasvinder Singh 		}
1106*202905f3SJasvinder Singh 
1107*202905f3SJasvinder Singh 		p.type = PORT_OUT_TAP;
1108*202905f3SJasvinder Singh 
1109*202905f3SJasvinder Singh 		p.dev_name = tokens[7];
1110*202905f3SJasvinder Singh 	} else if (strcmp(tokens[6], "sink") == 0) {
1111*202905f3SJasvinder Singh 		if ((n_tokens != 7) && (n_tokens != 11)) {
1112*202905f3SJasvinder Singh 			snprintf(out, out_size, MSG_ARG_MISMATCH,
1113*202905f3SJasvinder Singh 				"pipeline port out sink");
1114*202905f3SJasvinder Singh 			return;
1115*202905f3SJasvinder Singh 		}
1116*202905f3SJasvinder Singh 
1117*202905f3SJasvinder Singh 		p.type = PORT_OUT_SINK;
1118*202905f3SJasvinder Singh 
1119*202905f3SJasvinder Singh 		p.dev_name = NULL;
1120*202905f3SJasvinder Singh 
1121*202905f3SJasvinder Singh 		if (n_tokens == 7) {
1122*202905f3SJasvinder Singh 			p.sink.file_name = NULL;
1123*202905f3SJasvinder Singh 			p.sink.max_n_pkts = 0;
1124*202905f3SJasvinder Singh 		} else {
1125*202905f3SJasvinder Singh 			if (strcmp(tokens[7], "file") != 0) {
1126*202905f3SJasvinder Singh 				snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1127*202905f3SJasvinder Singh 					"file");
1128*202905f3SJasvinder Singh 				return;
1129*202905f3SJasvinder Singh 			}
1130*202905f3SJasvinder Singh 
1131*202905f3SJasvinder Singh 			p.sink.file_name = tokens[8];
1132*202905f3SJasvinder Singh 
1133*202905f3SJasvinder Singh 			if (strcmp(tokens[9], "pkts") != 0) {
1134*202905f3SJasvinder Singh 				snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pkts");
1135*202905f3SJasvinder Singh 				return;
1136*202905f3SJasvinder Singh 			}
1137*202905f3SJasvinder Singh 
1138*202905f3SJasvinder Singh 			if (softnic_parser_read_uint32(&p.sink.max_n_pkts,
1139*202905f3SJasvinder Singh 				tokens[10]) != 0) {
1140*202905f3SJasvinder Singh 				snprintf(out, out_size, MSG_ARG_INVALID, "max_n_pkts");
1141*202905f3SJasvinder Singh 				return;
1142*202905f3SJasvinder Singh 			}
1143*202905f3SJasvinder Singh 		}
1144*202905f3SJasvinder Singh 	} else {
1145*202905f3SJasvinder Singh 		snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
1146*202905f3SJasvinder Singh 		return;
1147*202905f3SJasvinder Singh 	}
1148*202905f3SJasvinder Singh 
1149*202905f3SJasvinder Singh 	status = softnic_pipeline_port_out_create(softnic, pipeline_name, &p);
1150*202905f3SJasvinder Singh 	if (status) {
1151*202905f3SJasvinder Singh 		snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
1152*202905f3SJasvinder Singh 		return;
1153*202905f3SJasvinder Singh 	}
1154*202905f3SJasvinder Singh }
1155*202905f3SJasvinder Singh 
1156*202905f3SJasvinder Singh /**
1157*202905f3SJasvinder Singh  * pipeline <pipeline_name> table
1158*202905f3SJasvinder Singh  *      match
1159*202905f3SJasvinder Singh  *      acl
1160*202905f3SJasvinder Singh  *          ipv4 | ipv6
1161*202905f3SJasvinder Singh  *          offset <ip_header_offset>
1162*202905f3SJasvinder Singh  *          size <n_rules>
1163*202905f3SJasvinder Singh  *      | array
1164*202905f3SJasvinder Singh  *          offset <key_offset>
1165*202905f3SJasvinder Singh  *          size <n_keys>
1166*202905f3SJasvinder Singh  *      | hash
1167*202905f3SJasvinder Singh  *          ext | lru
1168*202905f3SJasvinder Singh  *          key <key_size>
1169*202905f3SJasvinder Singh  *          mask <key_mask>
1170*202905f3SJasvinder Singh  *          offset <key_offset>
1171*202905f3SJasvinder Singh  *          buckets <n_buckets>
1172*202905f3SJasvinder Singh  *          size <n_keys>
1173*202905f3SJasvinder Singh  *      | lpm
1174*202905f3SJasvinder Singh  *          ipv4 | ipv6
1175*202905f3SJasvinder Singh  *          offset <ip_header_offset>
1176*202905f3SJasvinder Singh  *          size <n_rules>
1177*202905f3SJasvinder Singh  *      | stub
1178*202905f3SJasvinder Singh  *  [action <table_action_profile_name>]
1179*202905f3SJasvinder Singh  */
1180*202905f3SJasvinder Singh static void
1181*202905f3SJasvinder Singh cmd_pipeline_table(struct pmd_internals *softnic,
1182*202905f3SJasvinder Singh 	char **tokens,
1183*202905f3SJasvinder Singh 	uint32_t n_tokens,
1184*202905f3SJasvinder Singh 	char *out,
1185*202905f3SJasvinder Singh 	size_t out_size)
1186*202905f3SJasvinder Singh {
1187*202905f3SJasvinder Singh 	uint8_t key_mask[TABLE_RULE_MATCH_SIZE_MAX];
1188*202905f3SJasvinder Singh 	struct softnic_table_params p;
1189*202905f3SJasvinder Singh 	char *pipeline_name;
1190*202905f3SJasvinder Singh 	uint32_t t0;
1191*202905f3SJasvinder Singh 	int status;
1192*202905f3SJasvinder Singh 
1193*202905f3SJasvinder Singh 	if (n_tokens < 5) {
1194*202905f3SJasvinder Singh 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1195*202905f3SJasvinder Singh 		return;
1196*202905f3SJasvinder Singh 	}
1197*202905f3SJasvinder Singh 
1198*202905f3SJasvinder Singh 	pipeline_name = tokens[1];
1199*202905f3SJasvinder Singh 
1200*202905f3SJasvinder Singh 	if (strcmp(tokens[2], "table") != 0) {
1201*202905f3SJasvinder Singh 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
1202*202905f3SJasvinder Singh 		return;
1203*202905f3SJasvinder Singh 	}
1204*202905f3SJasvinder Singh 
1205*202905f3SJasvinder Singh 	if (strcmp(tokens[3], "match") != 0) {
1206*202905f3SJasvinder Singh 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "match");
1207*202905f3SJasvinder Singh 		return;
1208*202905f3SJasvinder Singh 	}
1209*202905f3SJasvinder Singh 
1210*202905f3SJasvinder Singh 	t0 = 4;
1211*202905f3SJasvinder Singh 	if (strcmp(tokens[t0], "acl") == 0) {
1212*202905f3SJasvinder Singh 		if (n_tokens < t0 + 6) {
1213*202905f3SJasvinder Singh 			snprintf(out, out_size, MSG_ARG_MISMATCH,
1214*202905f3SJasvinder Singh 				"pipeline table acl");
1215*202905f3SJasvinder Singh 			return;
1216*202905f3SJasvinder Singh 		}
1217*202905f3SJasvinder Singh 
1218*202905f3SJasvinder Singh 		p.match_type = TABLE_ACL;
1219*202905f3SJasvinder Singh 
1220*202905f3SJasvinder Singh 		if (strcmp(tokens[t0 + 1], "ipv4") == 0) {
1221*202905f3SJasvinder Singh 			p.match.acl.ip_version = 1;
1222*202905f3SJasvinder Singh 		} else if (strcmp(tokens[t0 + 1], "ipv6") == 0) {
1223*202905f3SJasvinder Singh 			p.match.acl.ip_version = 0;
1224*202905f3SJasvinder Singh 		} else {
1225*202905f3SJasvinder Singh 			snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1226*202905f3SJasvinder Singh 				"ipv4 or ipv6");
1227*202905f3SJasvinder Singh 			return;
1228*202905f3SJasvinder Singh 		}
1229*202905f3SJasvinder Singh 
1230*202905f3SJasvinder Singh 		if (strcmp(tokens[t0 + 2], "offset") != 0) {
1231*202905f3SJasvinder Singh 			snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
1232*202905f3SJasvinder Singh 			return;
1233*202905f3SJasvinder Singh 		}
1234*202905f3SJasvinder Singh 
1235*202905f3SJasvinder Singh 		if (softnic_parser_read_uint32(&p.match.acl.ip_header_offset,
1236*202905f3SJasvinder Singh 			tokens[t0 + 3]) != 0) {
1237*202905f3SJasvinder Singh 			snprintf(out, out_size, MSG_ARG_INVALID,
1238*202905f3SJasvinder Singh 				"ip_header_offset");
1239*202905f3SJasvinder Singh 			return;
1240*202905f3SJasvinder Singh 		}
1241*202905f3SJasvinder Singh 
1242*202905f3SJasvinder Singh 		if (strcmp(tokens[t0 + 4], "size") != 0) {
1243*202905f3SJasvinder Singh 			snprintf(out, out_size, MSG_ARG_NOT_FOUND, "size");
1244*202905f3SJasvinder Singh 			return;
1245*202905f3SJasvinder Singh 		}
1246*202905f3SJasvinder Singh 
1247*202905f3SJasvinder Singh 		if (softnic_parser_read_uint32(&p.match.acl.n_rules,
1248*202905f3SJasvinder Singh 			tokens[t0 + 5]) != 0) {
1249*202905f3SJasvinder Singh 			snprintf(out, out_size, MSG_ARG_INVALID, "n_rules");
1250*202905f3SJasvinder Singh 			return;
1251*202905f3SJasvinder Singh 		}
1252*202905f3SJasvinder Singh 
1253*202905f3SJasvinder Singh 		t0 += 6;
1254*202905f3SJasvinder Singh 	} else if (strcmp(tokens[t0], "array") == 0) {
1255*202905f3SJasvinder Singh 		if (n_tokens < t0 + 5) {
1256*202905f3SJasvinder Singh 			snprintf(out, out_size, MSG_ARG_MISMATCH,
1257*202905f3SJasvinder Singh 				"pipeline table array");
1258*202905f3SJasvinder Singh 			return;
1259*202905f3SJasvinder Singh 		}
1260*202905f3SJasvinder Singh 
1261*202905f3SJasvinder Singh 		p.match_type = TABLE_ARRAY;
1262*202905f3SJasvinder Singh 
1263*202905f3SJasvinder Singh 		if (strcmp(tokens[t0 + 1], "offset") != 0) {
1264*202905f3SJasvinder Singh 			snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
1265*202905f3SJasvinder Singh 			return;
1266*202905f3SJasvinder Singh 		}
1267*202905f3SJasvinder Singh 
1268*202905f3SJasvinder Singh 		if (softnic_parser_read_uint32(&p.match.array.key_offset,
1269*202905f3SJasvinder Singh 			tokens[t0 + 2]) != 0) {
1270*202905f3SJasvinder Singh 			snprintf(out, out_size, MSG_ARG_INVALID, "key_offset");
1271*202905f3SJasvinder Singh 			return;
1272*202905f3SJasvinder Singh 		}
1273*202905f3SJasvinder Singh 
1274*202905f3SJasvinder Singh 		if (strcmp(tokens[t0 + 3], "size") != 0) {
1275*202905f3SJasvinder Singh 			snprintf(out, out_size, MSG_ARG_NOT_FOUND, "size");
1276*202905f3SJasvinder Singh 			return;
1277*202905f3SJasvinder Singh 		}
1278*202905f3SJasvinder Singh 
1279*202905f3SJasvinder Singh 		if (softnic_parser_read_uint32(&p.match.array.n_keys,
1280*202905f3SJasvinder Singh 			tokens[t0 + 4]) != 0) {
1281*202905f3SJasvinder Singh 			snprintf(out, out_size, MSG_ARG_INVALID, "n_keys");
1282*202905f3SJasvinder Singh 			return;
1283*202905f3SJasvinder Singh 		}
1284*202905f3SJasvinder Singh 
1285*202905f3SJasvinder Singh 		t0 += 5;
1286*202905f3SJasvinder Singh 	} else if (strcmp(tokens[t0], "hash") == 0) {
1287*202905f3SJasvinder Singh 		uint32_t key_mask_size = TABLE_RULE_MATCH_SIZE_MAX;
1288*202905f3SJasvinder Singh 
1289*202905f3SJasvinder Singh 		if (n_tokens < t0 + 12) {
1290*202905f3SJasvinder Singh 			snprintf(out, out_size, MSG_ARG_MISMATCH,
1291*202905f3SJasvinder Singh 				"pipeline table hash");
1292*202905f3SJasvinder Singh 			return;
1293*202905f3SJasvinder Singh 		}
1294*202905f3SJasvinder Singh 
1295*202905f3SJasvinder Singh 		p.match_type = TABLE_HASH;
1296*202905f3SJasvinder Singh 
1297*202905f3SJasvinder Singh 		if (strcmp(tokens[t0 + 1], "ext") == 0) {
1298*202905f3SJasvinder Singh 			p.match.hash.extendable_bucket = 1;
1299*202905f3SJasvinder Singh 		} else if (strcmp(tokens[t0 + 1], "lru") == 0) {
1300*202905f3SJasvinder Singh 			p.match.hash.extendable_bucket = 0;
1301*202905f3SJasvinder Singh 		} else {
1302*202905f3SJasvinder Singh 			snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1303*202905f3SJasvinder Singh 				"ext or lru");
1304*202905f3SJasvinder Singh 			return;
1305*202905f3SJasvinder Singh 		}
1306*202905f3SJasvinder Singh 
1307*202905f3SJasvinder Singh 		if (strcmp(tokens[t0 + 2], "key") != 0) {
1308*202905f3SJasvinder Singh 			snprintf(out, out_size, MSG_ARG_NOT_FOUND, "key");
1309*202905f3SJasvinder Singh 			return;
1310*202905f3SJasvinder Singh 		}
1311*202905f3SJasvinder Singh 
1312*202905f3SJasvinder Singh 		if ((softnic_parser_read_uint32(&p.match.hash.key_size,
1313*202905f3SJasvinder Singh 			tokens[t0 + 3]) != 0) ||
1314*202905f3SJasvinder Singh 			p.match.hash.key_size == 0 ||
1315*202905f3SJasvinder Singh 			p.match.hash.key_size > TABLE_RULE_MATCH_SIZE_MAX) {
1316*202905f3SJasvinder Singh 			snprintf(out, out_size, MSG_ARG_INVALID, "key_size");
1317*202905f3SJasvinder Singh 			return;
1318*202905f3SJasvinder Singh 		}
1319*202905f3SJasvinder Singh 
1320*202905f3SJasvinder Singh 		if (strcmp(tokens[t0 + 4], "mask") != 0) {
1321*202905f3SJasvinder Singh 			snprintf(out, out_size, MSG_ARG_NOT_FOUND, "mask");
1322*202905f3SJasvinder Singh 			return;
1323*202905f3SJasvinder Singh 		}
1324*202905f3SJasvinder Singh 
1325*202905f3SJasvinder Singh 		if ((softnic_parse_hex_string(tokens[t0 + 5],
1326*202905f3SJasvinder Singh 			key_mask, &key_mask_size) != 0) ||
1327*202905f3SJasvinder Singh 			key_mask_size != p.match.hash.key_size) {
1328*202905f3SJasvinder Singh 			snprintf(out, out_size, MSG_ARG_INVALID, "key_mask");
1329*202905f3SJasvinder Singh 			return;
1330*202905f3SJasvinder Singh 		}
1331*202905f3SJasvinder Singh 		p.match.hash.key_mask = key_mask;
1332*202905f3SJasvinder Singh 
1333*202905f3SJasvinder Singh 		if (strcmp(tokens[t0 + 6], "offset") != 0) {
1334*202905f3SJasvinder Singh 			snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
1335*202905f3SJasvinder Singh 			return;
1336*202905f3SJasvinder Singh 		}
1337*202905f3SJasvinder Singh 
1338*202905f3SJasvinder Singh 		if (softnic_parser_read_uint32(&p.match.hash.key_offset,
1339*202905f3SJasvinder Singh 			tokens[t0 + 7]) != 0) {
1340*202905f3SJasvinder Singh 			snprintf(out, out_size, MSG_ARG_INVALID, "key_offset");
1341*202905f3SJasvinder Singh 			return;
1342*202905f3SJasvinder Singh 		}
1343*202905f3SJasvinder Singh 
1344*202905f3SJasvinder Singh 		if (strcmp(tokens[t0 + 8], "buckets") != 0) {
1345*202905f3SJasvinder Singh 			snprintf(out, out_size, MSG_ARG_NOT_FOUND, "buckets");
1346*202905f3SJasvinder Singh 			return;
1347*202905f3SJasvinder Singh 		}
1348*202905f3SJasvinder Singh 
1349*202905f3SJasvinder Singh 		if (softnic_parser_read_uint32(&p.match.hash.n_buckets,
1350*202905f3SJasvinder Singh 			tokens[t0 + 9]) != 0) {
1351*202905f3SJasvinder Singh 			snprintf(out, out_size, MSG_ARG_INVALID, "n_buckets");
1352*202905f3SJasvinder Singh 			return;
1353*202905f3SJasvinder Singh 		}
1354*202905f3SJasvinder Singh 
1355*202905f3SJasvinder Singh 		if (strcmp(tokens[t0 + 10], "size") != 0) {
1356*202905f3SJasvinder Singh 			snprintf(out, out_size, MSG_ARG_NOT_FOUND, "size");
1357*202905f3SJasvinder Singh 			return;
1358*202905f3SJasvinder Singh 		}
1359*202905f3SJasvinder Singh 
1360*202905f3SJasvinder Singh 		if (softnic_parser_read_uint32(&p.match.hash.n_keys,
1361*202905f3SJasvinder Singh 			tokens[t0 + 11]) != 0) {
1362*202905f3SJasvinder Singh 			snprintf(out, out_size, MSG_ARG_INVALID, "n_keys");
1363*202905f3SJasvinder Singh 			return;
1364*202905f3SJasvinder Singh 		}
1365*202905f3SJasvinder Singh 
1366*202905f3SJasvinder Singh 		t0 += 12;
1367*202905f3SJasvinder Singh 	} else if (strcmp(tokens[t0], "lpm") == 0) {
1368*202905f3SJasvinder Singh 		if (n_tokens < t0 + 6) {
1369*202905f3SJasvinder Singh 			snprintf(out, out_size, MSG_ARG_MISMATCH,
1370*202905f3SJasvinder Singh 				"pipeline table lpm");
1371*202905f3SJasvinder Singh 			return;
1372*202905f3SJasvinder Singh 		}
1373*202905f3SJasvinder Singh 
1374*202905f3SJasvinder Singh 		p.match_type = TABLE_LPM;
1375*202905f3SJasvinder Singh 
1376*202905f3SJasvinder Singh 		if (strcmp(tokens[t0 + 1], "ipv4") == 0) {
1377*202905f3SJasvinder Singh 			p.match.lpm.key_size = 4;
1378*202905f3SJasvinder Singh 		} else if (strcmp(tokens[t0 + 1], "ipv6") == 0) {
1379*202905f3SJasvinder Singh 			p.match.lpm.key_size = 16;
1380*202905f3SJasvinder Singh 		} else {
1381*202905f3SJasvinder Singh 			snprintf(out, out_size, MSG_ARG_NOT_FOUND,
1382*202905f3SJasvinder Singh 				"ipv4 or ipv6");
1383*202905f3SJasvinder Singh 			return;
1384*202905f3SJasvinder Singh 		}
1385*202905f3SJasvinder Singh 
1386*202905f3SJasvinder Singh 		if (strcmp(tokens[t0 + 2], "offset") != 0) {
1387*202905f3SJasvinder Singh 			snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
1388*202905f3SJasvinder Singh 			return;
1389*202905f3SJasvinder Singh 		}
1390*202905f3SJasvinder Singh 
1391*202905f3SJasvinder Singh 		if (softnic_parser_read_uint32(&p.match.lpm.key_offset,
1392*202905f3SJasvinder Singh 			tokens[t0 + 3]) != 0) {
1393*202905f3SJasvinder Singh 			snprintf(out, out_size, MSG_ARG_INVALID, "key_offset");
1394*202905f3SJasvinder Singh 			return;
1395*202905f3SJasvinder Singh 		}
1396*202905f3SJasvinder Singh 
1397*202905f3SJasvinder Singh 		if (strcmp(tokens[t0 + 4], "size") != 0) {
1398*202905f3SJasvinder Singh 			snprintf(out, out_size, MSG_ARG_NOT_FOUND, "size");
1399*202905f3SJasvinder Singh 			return;
1400*202905f3SJasvinder Singh 		}
1401*202905f3SJasvinder Singh 
1402*202905f3SJasvinder Singh 		if (softnic_parser_read_uint32(&p.match.lpm.n_rules,
1403*202905f3SJasvinder Singh 			tokens[t0 + 5]) != 0) {
1404*202905f3SJasvinder Singh 			snprintf(out, out_size, MSG_ARG_INVALID, "n_rules");
1405*202905f3SJasvinder Singh 			return;
1406*202905f3SJasvinder Singh 		}
1407*202905f3SJasvinder Singh 
1408*202905f3SJasvinder Singh 		t0 += 6;
1409*202905f3SJasvinder Singh 	} else if (strcmp(tokens[t0], "stub") == 0) {
1410*202905f3SJasvinder Singh 		p.match_type = TABLE_STUB;
1411*202905f3SJasvinder Singh 
1412*202905f3SJasvinder Singh 		t0 += 1;
1413*202905f3SJasvinder Singh 	} else {
1414*202905f3SJasvinder Singh 		snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
1415*202905f3SJasvinder Singh 		return;
1416*202905f3SJasvinder Singh 	}
1417*202905f3SJasvinder Singh 
1418*202905f3SJasvinder Singh 	p.action_profile_name = NULL;
1419*202905f3SJasvinder Singh 	if (n_tokens > t0 &&
1420*202905f3SJasvinder Singh 		(strcmp(tokens[t0], "action") == 0)) {
1421*202905f3SJasvinder Singh 		if (n_tokens < t0 + 2) {
1422*202905f3SJasvinder Singh 			snprintf(out, out_size, MSG_ARG_MISMATCH, "action");
1423*202905f3SJasvinder Singh 			return;
1424*202905f3SJasvinder Singh 		}
1425*202905f3SJasvinder Singh 
1426*202905f3SJasvinder Singh 		p.action_profile_name = tokens[t0 + 1];
1427*202905f3SJasvinder Singh 
1428*202905f3SJasvinder Singh 		t0 += 2;
1429*202905f3SJasvinder Singh 	}
1430*202905f3SJasvinder Singh 
1431*202905f3SJasvinder Singh 	if (n_tokens > t0) {
1432*202905f3SJasvinder Singh 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1433*202905f3SJasvinder Singh 		return;
1434*202905f3SJasvinder Singh 	}
1435*202905f3SJasvinder Singh 
1436*202905f3SJasvinder Singh 	status = softnic_pipeline_table_create(softnic, pipeline_name, &p);
1437*202905f3SJasvinder Singh 	if (status) {
1438*202905f3SJasvinder Singh 		snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
1439*202905f3SJasvinder Singh 		return;
1440*202905f3SJasvinder Singh 	}
1441*202905f3SJasvinder Singh }
1442*202905f3SJasvinder Singh 
1443*202905f3SJasvinder Singh /**
1444*202905f3SJasvinder Singh  * pipeline <pipeline_name> port in <port_id> table <table_id>
1445*202905f3SJasvinder Singh  */
1446*202905f3SJasvinder Singh static void
1447*202905f3SJasvinder Singh cmd_pipeline_port_in_table(struct pmd_internals *softnic,
1448*202905f3SJasvinder Singh 	char **tokens,
1449*202905f3SJasvinder Singh 	uint32_t n_tokens,
1450*202905f3SJasvinder Singh 	char *out,
1451*202905f3SJasvinder Singh 	size_t out_size)
1452*202905f3SJasvinder Singh {
1453*202905f3SJasvinder Singh 	char *pipeline_name;
1454*202905f3SJasvinder Singh 	uint32_t port_id, table_id;
1455*202905f3SJasvinder Singh 	int status;
1456*202905f3SJasvinder Singh 
1457*202905f3SJasvinder Singh 	if (n_tokens != 7) {
1458*202905f3SJasvinder Singh 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1459*202905f3SJasvinder Singh 		return;
1460*202905f3SJasvinder Singh 	}
1461*202905f3SJasvinder Singh 
1462*202905f3SJasvinder Singh 	pipeline_name = tokens[1];
1463*202905f3SJasvinder Singh 
1464*202905f3SJasvinder Singh 	if (strcmp(tokens[2], "port") != 0) {
1465*202905f3SJasvinder Singh 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
1466*202905f3SJasvinder Singh 		return;
1467*202905f3SJasvinder Singh 	}
1468*202905f3SJasvinder Singh 
1469*202905f3SJasvinder Singh 	if (strcmp(tokens[3], "in") != 0) {
1470*202905f3SJasvinder Singh 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "in");
1471*202905f3SJasvinder Singh 		return;
1472*202905f3SJasvinder Singh 	}
1473*202905f3SJasvinder Singh 
1474*202905f3SJasvinder Singh 	if (softnic_parser_read_uint32(&port_id, tokens[4]) != 0) {
1475*202905f3SJasvinder Singh 		snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
1476*202905f3SJasvinder Singh 		return;
1477*202905f3SJasvinder Singh 	}
1478*202905f3SJasvinder Singh 
1479*202905f3SJasvinder Singh 	if (strcmp(tokens[5], "table") != 0) {
1480*202905f3SJasvinder Singh 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
1481*202905f3SJasvinder Singh 		return;
1482*202905f3SJasvinder Singh 	}
1483*202905f3SJasvinder Singh 
1484*202905f3SJasvinder Singh 	if (softnic_parser_read_uint32(&table_id, tokens[6]) != 0) {
1485*202905f3SJasvinder Singh 		snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
1486*202905f3SJasvinder Singh 		return;
1487*202905f3SJasvinder Singh 	}
1488*202905f3SJasvinder Singh 
1489*202905f3SJasvinder Singh 	status = softnic_pipeline_port_in_connect_to_table(softnic,
1490*202905f3SJasvinder Singh 		pipeline_name,
1491*202905f3SJasvinder Singh 		port_id,
1492*202905f3SJasvinder Singh 		table_id);
1493*202905f3SJasvinder Singh 	if (status) {
1494*202905f3SJasvinder Singh 		snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
1495*202905f3SJasvinder Singh 		return;
1496*202905f3SJasvinder Singh 	}
1497*202905f3SJasvinder Singh }
1498*202905f3SJasvinder Singh 
1499*202905f3SJasvinder Singh /**
1500*202905f3SJasvinder Singh  * pipeline <pipeline_name> port in <port_id> enable
1501*202905f3SJasvinder Singh  */
1502*202905f3SJasvinder Singh static void
1503*202905f3SJasvinder Singh cmd_softnic_pipeline_port_in_enable(struct pmd_internals *softnic,
1504*202905f3SJasvinder Singh 	char **tokens,
1505*202905f3SJasvinder Singh 	uint32_t n_tokens,
1506*202905f3SJasvinder Singh 	char *out,
1507*202905f3SJasvinder Singh 	size_t out_size)
1508*202905f3SJasvinder Singh {
1509*202905f3SJasvinder Singh 	char *pipeline_name;
1510*202905f3SJasvinder Singh 	uint32_t port_id;
1511*202905f3SJasvinder Singh 	int status;
1512*202905f3SJasvinder Singh 
1513*202905f3SJasvinder Singh 	if (n_tokens != 6) {
1514*202905f3SJasvinder Singh 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1515*202905f3SJasvinder Singh 		return;
1516*202905f3SJasvinder Singh 	}
1517*202905f3SJasvinder Singh 
1518*202905f3SJasvinder Singh 	pipeline_name = tokens[1];
1519*202905f3SJasvinder Singh 
1520*202905f3SJasvinder Singh 	if (strcmp(tokens[2], "port") != 0) {
1521*202905f3SJasvinder Singh 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
1522*202905f3SJasvinder Singh 		return;
1523*202905f3SJasvinder Singh 	}
1524*202905f3SJasvinder Singh 
1525*202905f3SJasvinder Singh 	if (strcmp(tokens[3], "in") != 0) {
1526*202905f3SJasvinder Singh 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "in");
1527*202905f3SJasvinder Singh 		return;
1528*202905f3SJasvinder Singh 	}
1529*202905f3SJasvinder Singh 
1530*202905f3SJasvinder Singh 	if (softnic_parser_read_uint32(&port_id, tokens[4]) != 0) {
1531*202905f3SJasvinder Singh 		snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
1532*202905f3SJasvinder Singh 		return;
1533*202905f3SJasvinder Singh 	}
1534*202905f3SJasvinder Singh 
1535*202905f3SJasvinder Singh 	if (strcmp(tokens[5], "enable") != 0) {
1536*202905f3SJasvinder Singh 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "enable");
1537*202905f3SJasvinder Singh 		return;
1538*202905f3SJasvinder Singh 	}
1539*202905f3SJasvinder Singh 
1540*202905f3SJasvinder Singh 	status = softnic_pipeline_port_in_enable(softnic, pipeline_name, port_id);
1541*202905f3SJasvinder Singh 	if (status) {
1542*202905f3SJasvinder Singh 		snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
1543*202905f3SJasvinder Singh 		return;
1544*202905f3SJasvinder Singh 	}
1545*202905f3SJasvinder Singh }
1546*202905f3SJasvinder Singh 
1547*202905f3SJasvinder Singh /**
1548*202905f3SJasvinder Singh  * pipeline <pipeline_name> port in <port_id> disable
1549*202905f3SJasvinder Singh  */
1550*202905f3SJasvinder Singh static void
1551*202905f3SJasvinder Singh cmd_softnic_pipeline_port_in_disable(struct pmd_internals *softnic,
1552*202905f3SJasvinder Singh 	char **tokens,
1553*202905f3SJasvinder Singh 	uint32_t n_tokens,
1554*202905f3SJasvinder Singh 	char *out,
1555*202905f3SJasvinder Singh 	size_t out_size)
1556*202905f3SJasvinder Singh {
1557*202905f3SJasvinder Singh 	char *pipeline_name;
1558*202905f3SJasvinder Singh 	uint32_t port_id;
1559*202905f3SJasvinder Singh 	int status;
1560*202905f3SJasvinder Singh 
1561*202905f3SJasvinder Singh 	if (n_tokens != 6) {
1562*202905f3SJasvinder Singh 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
1563*202905f3SJasvinder Singh 		return;
1564*202905f3SJasvinder Singh 	}
1565*202905f3SJasvinder Singh 
1566*202905f3SJasvinder Singh 	pipeline_name = tokens[1];
1567*202905f3SJasvinder Singh 
1568*202905f3SJasvinder Singh 	if (strcmp(tokens[2], "port") != 0) {
1569*202905f3SJasvinder Singh 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
1570*202905f3SJasvinder Singh 		return;
1571*202905f3SJasvinder Singh 	}
1572*202905f3SJasvinder Singh 
1573*202905f3SJasvinder Singh 	if (strcmp(tokens[3], "in") != 0) {
1574*202905f3SJasvinder Singh 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "in");
1575*202905f3SJasvinder Singh 		return;
1576*202905f3SJasvinder Singh 	}
1577*202905f3SJasvinder Singh 
1578*202905f3SJasvinder Singh 	if (softnic_parser_read_uint32(&port_id, tokens[4]) != 0) {
1579*202905f3SJasvinder Singh 		snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
1580*202905f3SJasvinder Singh 		return;
1581*202905f3SJasvinder Singh 	}
1582*202905f3SJasvinder Singh 
1583*202905f3SJasvinder Singh 	if (strcmp(tokens[5], "disable") != 0) {
1584*202905f3SJasvinder Singh 		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "disable");
1585*202905f3SJasvinder Singh 		return;
1586*202905f3SJasvinder Singh 	}
1587*202905f3SJasvinder Singh 
1588*202905f3SJasvinder Singh 	status = softnic_pipeline_port_in_disable(softnic, pipeline_name, port_id);
1589*202905f3SJasvinder Singh 	if (status) {
1590*202905f3SJasvinder Singh 		snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
1591*202905f3SJasvinder Singh 		return;
1592*202905f3SJasvinder Singh 	}
1593*202905f3SJasvinder Singh }
1594*202905f3SJasvinder Singh 
159531ce8d88SJasvinder Singh void
1596*202905f3SJasvinder Singh softnic_cli_process(char *in, char *out, size_t out_size, void *arg)
159731ce8d88SJasvinder Singh {
159831ce8d88SJasvinder Singh 	char *tokens[CMD_MAX_TOKENS];
159931ce8d88SJasvinder Singh 	uint32_t n_tokens = RTE_DIM(tokens);
1600*202905f3SJasvinder Singh 	struct pmd_internals *softnic = arg;
160131ce8d88SJasvinder Singh 	int status;
160231ce8d88SJasvinder Singh 
160331ce8d88SJasvinder Singh 	if (is_comment(in))
160431ce8d88SJasvinder Singh 		return;
160531ce8d88SJasvinder Singh 
160631ce8d88SJasvinder Singh 	status = softnic_parse_tokenize_string(in, tokens, &n_tokens);
160731ce8d88SJasvinder Singh 	if (status) {
160831ce8d88SJasvinder Singh 		snprintf(out, out_size, MSG_ARG_TOO_MANY, "");
160931ce8d88SJasvinder Singh 		return;
161031ce8d88SJasvinder Singh 	}
161131ce8d88SJasvinder Singh 
161231ce8d88SJasvinder Singh 	if (n_tokens == 0)
161331ce8d88SJasvinder Singh 		return;
161431ce8d88SJasvinder Singh 
1615*202905f3SJasvinder Singh 	if (strcmp(tokens[0], "mempool") == 0) {
1616*202905f3SJasvinder Singh 		cmd_mempool(softnic, tokens, n_tokens, out, out_size);
1617*202905f3SJasvinder Singh 		return;
1618*202905f3SJasvinder Singh 	}
1619*202905f3SJasvinder Singh 
1620*202905f3SJasvinder Singh 	if (strcmp(tokens[0], "link") == 0) {
1621*202905f3SJasvinder Singh 		cmd_link(softnic, tokens, n_tokens, out, out_size);
1622*202905f3SJasvinder Singh 		return;
1623*202905f3SJasvinder Singh 	}
1624*202905f3SJasvinder Singh 
1625*202905f3SJasvinder Singh 	if (strcmp(tokens[0], "swq") == 0) {
1626*202905f3SJasvinder Singh 		cmd_swq(softnic, tokens, n_tokens, out, out_size);
1627*202905f3SJasvinder Singh 		return;
1628*202905f3SJasvinder Singh 	}
1629*202905f3SJasvinder Singh 
1630*202905f3SJasvinder Singh 	if (strcmp(tokens[0], "tap") == 0) {
1631*202905f3SJasvinder Singh 		cmd_tap(softnic, tokens, n_tokens, out, out_size);
1632*202905f3SJasvinder Singh 		return;
1633*202905f3SJasvinder Singh 	}
1634*202905f3SJasvinder Singh 
1635*202905f3SJasvinder Singh 	if (strcmp(tokens[0], "port") == 0) {
1636*202905f3SJasvinder Singh 		cmd_port_in_action_profile(softnic, tokens, n_tokens, out, out_size);
1637*202905f3SJasvinder Singh 		return;
1638*202905f3SJasvinder Singh 	}
1639*202905f3SJasvinder Singh 
1640*202905f3SJasvinder Singh 	if (strcmp(tokens[0], "table") == 0) {
1641*202905f3SJasvinder Singh 		cmd_table_action_profile(softnic, tokens, n_tokens, out, out_size);
1642*202905f3SJasvinder Singh 		return;
1643*202905f3SJasvinder Singh 	}
1644*202905f3SJasvinder Singh 
1645*202905f3SJasvinder Singh 	if (strcmp(tokens[0], "pipeline") == 0) {
1646*202905f3SJasvinder Singh 		if (n_tokens >= 3 &&
1647*202905f3SJasvinder Singh 			(strcmp(tokens[2], "period") == 0)) {
1648*202905f3SJasvinder Singh 			cmd_pipeline(softnic, tokens, n_tokens, out, out_size);
1649*202905f3SJasvinder Singh 			return;
1650*202905f3SJasvinder Singh 		}
1651*202905f3SJasvinder Singh 
1652*202905f3SJasvinder Singh 		if (n_tokens >= 5 &&
1653*202905f3SJasvinder Singh 			(strcmp(tokens[2], "port") == 0) &&
1654*202905f3SJasvinder Singh 			(strcmp(tokens[3], "in") == 0) &&
1655*202905f3SJasvinder Singh 			(strcmp(tokens[4], "bsz") == 0)) {
1656*202905f3SJasvinder Singh 			cmd_pipeline_port_in(softnic, tokens, n_tokens, out, out_size);
1657*202905f3SJasvinder Singh 			return;
1658*202905f3SJasvinder Singh 		}
1659*202905f3SJasvinder Singh 
1660*202905f3SJasvinder Singh 		if (n_tokens >= 5 &&
1661*202905f3SJasvinder Singh 			(strcmp(tokens[2], "port") == 0) &&
1662*202905f3SJasvinder Singh 			(strcmp(tokens[3], "out") == 0) &&
1663*202905f3SJasvinder Singh 			(strcmp(tokens[4], "bsz") == 0)) {
1664*202905f3SJasvinder Singh 			cmd_pipeline_port_out(softnic, tokens, n_tokens, out, out_size);
1665*202905f3SJasvinder Singh 			return;
1666*202905f3SJasvinder Singh 		}
1667*202905f3SJasvinder Singh 
1668*202905f3SJasvinder Singh 		if (n_tokens >= 4 &&
1669*202905f3SJasvinder Singh 			(strcmp(tokens[2], "table") == 0) &&
1670*202905f3SJasvinder Singh 			(strcmp(tokens[3], "match") == 0)) {
1671*202905f3SJasvinder Singh 			cmd_pipeline_table(softnic, tokens, n_tokens, out, out_size);
1672*202905f3SJasvinder Singh 			return;
1673*202905f3SJasvinder Singh 		}
1674*202905f3SJasvinder Singh 
1675*202905f3SJasvinder Singh 		if (n_tokens >= 6 &&
1676*202905f3SJasvinder Singh 			(strcmp(tokens[2], "port") == 0) &&
1677*202905f3SJasvinder Singh 			(strcmp(tokens[3], "in") == 0) &&
1678*202905f3SJasvinder Singh 			(strcmp(tokens[5], "table") == 0)) {
1679*202905f3SJasvinder Singh 			cmd_pipeline_port_in_table(softnic, tokens, n_tokens,
1680*202905f3SJasvinder Singh 				out, out_size);
1681*202905f3SJasvinder Singh 			return;
1682*202905f3SJasvinder Singh 		}
1683*202905f3SJasvinder Singh 
1684*202905f3SJasvinder Singh 		if (n_tokens >= 6 &&
1685*202905f3SJasvinder Singh 			(strcmp(tokens[2], "port") == 0) &&
1686*202905f3SJasvinder Singh 			(strcmp(tokens[3], "in") == 0) &&
1687*202905f3SJasvinder Singh 			(strcmp(tokens[5], "enable") == 0)) {
1688*202905f3SJasvinder Singh 			cmd_softnic_pipeline_port_in_enable(softnic, tokens, n_tokens,
1689*202905f3SJasvinder Singh 				out, out_size);
1690*202905f3SJasvinder Singh 			return;
1691*202905f3SJasvinder Singh 		}
1692*202905f3SJasvinder Singh 
1693*202905f3SJasvinder Singh 		if (n_tokens >= 6 &&
1694*202905f3SJasvinder Singh 			(strcmp(tokens[2], "port") == 0) &&
1695*202905f3SJasvinder Singh 			(strcmp(tokens[3], "in") == 0) &&
1696*202905f3SJasvinder Singh 			(strcmp(tokens[5], "disable") == 0)) {
1697*202905f3SJasvinder Singh 			cmd_softnic_pipeline_port_in_disable(softnic, tokens, n_tokens,
1698*202905f3SJasvinder Singh 				out, out_size);
1699*202905f3SJasvinder Singh 			return;
1700*202905f3SJasvinder Singh 		}
1701*202905f3SJasvinder Singh 	}
1702*202905f3SJasvinder Singh 
170331ce8d88SJasvinder Singh 	snprintf(out, out_size, MSG_CMD_UNKNOWN, tokens[0]);
170431ce8d88SJasvinder Singh }
170531ce8d88SJasvinder Singh 
170631ce8d88SJasvinder Singh int
170731ce8d88SJasvinder Singh softnic_cli_script_process(struct pmd_internals *softnic,
170831ce8d88SJasvinder Singh 	const char *file_name,
170931ce8d88SJasvinder Singh 	size_t msg_in_len_max,
171031ce8d88SJasvinder Singh 	size_t msg_out_len_max)
171131ce8d88SJasvinder Singh {
171231ce8d88SJasvinder Singh 	char *msg_in = NULL, *msg_out = NULL;
171331ce8d88SJasvinder Singh 	FILE *f = NULL;
171431ce8d88SJasvinder Singh 
171531ce8d88SJasvinder Singh 	/* Check input arguments */
171631ce8d88SJasvinder Singh 	if (file_name == NULL ||
171731ce8d88SJasvinder Singh 		strlen(file_name) == 0 ||
171831ce8d88SJasvinder Singh 		msg_in_len_max == 0 ||
171931ce8d88SJasvinder Singh 		msg_out_len_max == 0)
172031ce8d88SJasvinder Singh 		return -EINVAL;
172131ce8d88SJasvinder Singh 
172231ce8d88SJasvinder Singh 	msg_in = malloc(msg_in_len_max + 1);
172331ce8d88SJasvinder Singh 	msg_out = malloc(msg_out_len_max + 1);
172431ce8d88SJasvinder Singh 	if (msg_in == NULL ||
172531ce8d88SJasvinder Singh 		msg_out == NULL) {
172631ce8d88SJasvinder Singh 		free(msg_out);
172731ce8d88SJasvinder Singh 		free(msg_in);
172831ce8d88SJasvinder Singh 		return -ENOMEM;
172931ce8d88SJasvinder Singh 	}
173031ce8d88SJasvinder Singh 
173131ce8d88SJasvinder Singh 	/* Open input file */
173231ce8d88SJasvinder Singh 	f = fopen(file_name, "r");
173331ce8d88SJasvinder Singh 	if (f == NULL) {
173431ce8d88SJasvinder Singh 		free(msg_out);
173531ce8d88SJasvinder Singh 		free(msg_in);
173631ce8d88SJasvinder Singh 		return -EIO;
173731ce8d88SJasvinder Singh 	}
173831ce8d88SJasvinder Singh 
173931ce8d88SJasvinder Singh 	/* Read file */
174031ce8d88SJasvinder Singh 	for ( ; ; ) {
174131ce8d88SJasvinder Singh 		if (fgets(msg_in, msg_in_len_max + 1, f) == NULL)
174231ce8d88SJasvinder Singh 			break;
174331ce8d88SJasvinder Singh 
174431ce8d88SJasvinder Singh 		printf("%s", msg_in);
174531ce8d88SJasvinder Singh 		msg_out[0] = 0;
174631ce8d88SJasvinder Singh 
174731ce8d88SJasvinder Singh 		softnic_cli_process(msg_in,
174831ce8d88SJasvinder Singh 			msg_out,
174931ce8d88SJasvinder Singh 			msg_out_len_max,
175031ce8d88SJasvinder Singh 			softnic);
175131ce8d88SJasvinder Singh 
175231ce8d88SJasvinder Singh 		if (strlen(msg_out))
175331ce8d88SJasvinder Singh 			printf("%s", msg_out);
175431ce8d88SJasvinder Singh 	}
175531ce8d88SJasvinder Singh 
175631ce8d88SJasvinder Singh 	/* Close file */
175731ce8d88SJasvinder Singh 	fclose(f);
175831ce8d88SJasvinder Singh 	free(msg_out);
175931ce8d88SJasvinder Singh 	free(msg_in);
176031ce8d88SJasvinder Singh 	return 0;
176131ce8d88SJasvinder Singh }
1762