xref: /dpdk/app/test-pmd/cmdline.c (revision 52e04a6323319ff1a7b4e1d7ed1df2b45d11a0a4)
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2010-2016 Intel Corporation.
3  * Copyright(c) 2014 6WIND S.A.
4  */
5 
6 #include <ctype.h>
7 #include <stdarg.h>
8 #include <errno.h>
9 #include <fcntl.h>
10 #include <stdio.h>
11 #include <stdint.h>
12 #include <stdlib.h>
13 #include <string.h>
14 #include <unistd.h>
15 #include <inttypes.h>
16 #include <sys/queue.h>
17 
18 #include <rte_common.h>
19 #include <rte_byteorder.h>
20 #include <rte_log.h>
21 #include <rte_debug.h>
22 #include <rte_cycles.h>
23 #include <rte_memory.h>
24 #include <rte_memzone.h>
25 #include <rte_malloc.h>
26 #include <rte_launch.h>
27 #include <rte_eal.h>
28 #include <rte_per_lcore.h>
29 #include <rte_lcore.h>
30 #include <rte_branch_prediction.h>
31 #include <rte_ring.h>
32 #include <rte_mempool.h>
33 #include <rte_interrupts.h>
34 #include <rte_ether.h>
35 #include <rte_ethdev.h>
36 #include <rte_string_fns.h>
37 #include <rte_devargs.h>
38 #include <rte_flow.h>
39 #ifdef RTE_LIB_GRO
40 #include <rte_gro.h>
41 #endif
42 #include <rte_mbuf_dyn.h>
43 #include <rte_trace.h>
44 
45 #include <cmdline_rdline.h>
46 #include <cmdline_parse.h>
47 #include <cmdline_parse_num.h>
48 #include <cmdline_parse_string.h>
49 #include <cmdline_parse_ipaddr.h>
50 #include <cmdline_parse_etheraddr.h>
51 #include <cmdline_socket.h>
52 #include <cmdline.h>
53 #if defined RTE_BUS_DPAA && defined RTE_NET_DPAA
54 #include <rte_pmd_dpaa.h>
55 #endif
56 #ifdef RTE_NET_IXGBE
57 #include <rte_pmd_ixgbe.h>
58 #endif
59 #ifdef RTE_NET_I40E
60 #include <rte_pmd_i40e.h>
61 #endif
62 #ifdef RTE_NET_BNXT
63 #include <rte_pmd_bnxt.h>
64 #endif
65 #include "testpmd.h"
66 #include "cmdline_cman.h"
67 #include "cmdline_mtr.h"
68 #include "cmdline_tm.h"
69 #include "bpf_cmd.h"
70 
71 static struct cmdline *testpmd_cl;
72 static cmdline_parse_ctx_t *main_ctx;
73 static TAILQ_HEAD(, testpmd_driver_commands) driver_commands_head =
74 	TAILQ_HEAD_INITIALIZER(driver_commands_head);
75 
76 /* *** Help command with introduction. *** */
77 struct cmd_help_brief_result {
78 	cmdline_fixed_string_t help;
79 };
80 
81 static void cmd_help_brief_parsed(__rte_unused void *parsed_result,
82                                   struct cmdline *cl,
83                                   __rte_unused void *data)
84 {
85 	cmdline_printf(
86 		cl,
87 		"\n"
88 		"Help is available for the following sections:\n\n"
89 		"    help control                    : Start and stop forwarding.\n"
90 		"    help display                    : Displaying port, stats and config "
91 		"information.\n"
92 		"    help config                     : Configuration information.\n"
93 		"    help ports                      : Configuring ports.\n"
94 		"    help filters                    : Filters configuration help.\n"
95 		"    help traffic_management         : Traffic Management commands.\n"
96 		"    help devices                    : Device related commands.\n"
97 		"    help drivers                    : Driver specific commands.\n"
98 		"    help all                        : All of the above sections.\n\n"
99 	);
100 
101 }
102 
103 static cmdline_parse_token_string_t cmd_help_brief_help =
104 	TOKEN_STRING_INITIALIZER(struct cmd_help_brief_result, help, "help");
105 
106 static cmdline_parse_inst_t cmd_help_brief = {
107 	.f = cmd_help_brief_parsed,
108 	.data = NULL,
109 	.help_str = "help: Show help",
110 	.tokens = {
111 		(void *)&cmd_help_brief_help,
112 		NULL,
113 	},
114 };
115 
116 /* *** Help command with help sections. *** */
117 struct cmd_help_long_result {
118 	cmdline_fixed_string_t help;
119 	cmdline_fixed_string_t section;
120 };
121 
122 static void cmd_help_long_parsed(void *parsed_result,
123                                  struct cmdline *cl,
124                                  __rte_unused void *data)
125 {
126 	int show_all = 0;
127 	struct cmd_help_long_result *res = parsed_result;
128 
129 	if (!strcmp(res->section, "all"))
130 		show_all = 1;
131 
132 	if (show_all || !strcmp(res->section, "control")) {
133 
134 		cmdline_printf(
135 			cl,
136 			"\n"
137 			"Control forwarding:\n"
138 			"-------------------\n\n"
139 
140 			"start\n"
141 			"    Start packet forwarding with current configuration.\n\n"
142 
143 			"start tx_first\n"
144 			"    Start packet forwarding with current config"
145 			" after sending one burst of packets.\n\n"
146 
147 			"stop\n"
148 			"    Stop packet forwarding, and display accumulated"
149 			" statistics.\n\n"
150 
151 			"quit\n"
152 			"    Quit to prompt.\n\n"
153 		);
154 	}
155 
156 	if (show_all || !strcmp(res->section, "display")) {
157 
158 		cmdline_printf(
159 			cl,
160 			"\n"
161 			"Display:\n"
162 			"--------\n\n"
163 
164 			"show port (info|stats|summary|xstats|fdir|dcb_tc) (port_id|all)\n"
165 			"    Display information for port_id, or all.\n\n"
166 
167 			"show port info (port_id) representor\n"
168 			"    Show supported representors for a specific port\n\n"
169 
170 			"show port port_id (module_eeprom|eeprom)\n"
171 			"    Display the module EEPROM or EEPROM information for port_id.\n\n"
172 
173 			"set port (port_id) eeprom (accept_risk) magic (magic_num)"
174 			" value (value) offset (offset)\n"
175 			"    Set the device eeprom for certain port.\nNote:\n"
176 			"    This is a high-risk command and its misuse may"
177 			" result in unexpected behaviour from the NIC.\n"
178 			"    By inserting \"accept_risk\" into the command, the"
179 			" user is acknowledging and taking responsibility for"
180 			" this risk.\n\n"
181 
182 			"show port X rss reta (size) (mask0,mask1,...)\n"
183 			"    Display the rss redirection table entry indicated"
184 			" by masks on port X. size is used to indicate the"
185 			" hardware supported reta size\n\n"
186 
187 			"show port (port_id) rss-hash [key | algorithm]\n"
188 			"    Display the RSS hash functions, RSS hash key and RSS hash algorithms of port\n\n"
189 
190 			"clear port (info|stats|xstats|fdir) (port_id|all)\n"
191 			"    Clear information for port_id, or all.\n\n"
192 
193 			"show (rxq|txq) info (port_id) (queue_id)\n"
194 			"    Display information for configured RX/TX queue.\n\n"
195 
196 			"show config (rxtx|cores|fwd|rxoffs|rxpkts|rxhdrs|txpkts)\n"
197 			"    Display the given configuration.\n\n"
198 
199 			"read rxd (port_id) (queue_id) (rxd_id)\n"
200 			"    Display an RX descriptor of a port RX queue.\n\n"
201 
202 			"read txd (port_id) (queue_id) (txd_id)\n"
203 			"    Display a TX descriptor of a port TX queue.\n\n"
204 
205 			"show vf stats (port_id) (vf_id)\n"
206 			"    Display a VF's statistics.\n\n"
207 
208 			"clear vf stats (port_id) (vf_id)\n"
209 			"    Reset a VF's statistics.\n\n"
210 
211 			"show port meter stats (port_id) (meter_id) (clear)\n"
212 			"    Get meter stats on a port\n\n"
213 
214 			"show fwd stats all\n"
215 			"    Display statistics for all fwd engines.\n\n"
216 
217 			"clear fwd stats all\n"
218 			"    Clear statistics for all fwd engines.\n\n"
219 
220 			"show port (port_id) rx_offload capabilities\n"
221 			"    List all per queue and per port Rx offloading"
222 			" capabilities of a port\n\n"
223 
224 			"show port (port_id) rx_offload configuration\n"
225 			"    List port level and all queue level"
226 			" Rx offloading configuration\n\n"
227 
228 			"show port (port_id) tx_offload capabilities\n"
229 			"    List all per queue and per port"
230 			" Tx offloading capabilities of a port\n\n"
231 
232 			"show port (port_id) tx_offload configuration\n"
233 			"    List port level and all queue level"
234 			" Tx offloading configuration\n\n"
235 
236 			"show port (port_id) tx_metadata\n"
237 			"    Show Tx metadata value set"
238 			" for a specific port\n\n"
239 
240 			"show port (port_id) ptypes\n"
241 			"    Show port supported ptypes"
242 			" for a specific port\n\n"
243 
244 			"show device info (<identifier>|all)"
245 			"       Show general information about devices probed.\n\n"
246 
247 			"show port (port_id) rxq|txq (queue_id) desc (desc_id) status"
248 			"       Show status of rx|tx descriptor.\n\n"
249 
250 			"show port (port_id) rxq|txq (queue_id) desc used count\n"
251 			"    Show current number of used descriptor count for rx|tx.\n\n"
252 
253 			"show port (port_id) macs|mcast_macs"
254 			"       Display list of mac addresses added to port.\n\n"
255 
256 			"show port (port_id) flow transfer proxy\n"
257 			"	Display proxy port to manage transfer flows\n\n"
258 
259 			"show port (port_id) fec capabilities"
260 			"	Show fec capabilities of a port.\n\n"
261 
262 			"show port (port_id) fec_mode"
263 			"	Show fec mode of a port.\n\n"
264 
265 			"show port (port_id) flow_ctrl"
266 			"	Show flow control info of a port.\n\n"
267 
268 			"dump_physmem\n"
269 			"    Dumps all physical memory segment layouts\n\n"
270 
271 			"dump_socket_mem\n"
272 			"    Dumps the memory usage of all sockets\n\n"
273 
274 			"dump_memzone\n"
275 			"    Dumps the layout of all memory zones\n\n"
276 
277 			"dump_struct_sizes\n"
278 			"    Dumps the size of all memory structures\n\n"
279 
280 			"dump_ring\n"
281 			"    Dumps the status of all or specific element in DPDK rings\n\n"
282 
283 			"dump_mempool\n"
284 			"    Dumps the statistics of all or specific memory pool\n\n"
285 
286 			"dump_devargs\n"
287 			"    Dumps the user device list\n\n"
288 
289 			"dump_lcores\n"
290 			"    Dumps the logical cores list\n\n"
291 
292 			"dump_trace\n"
293 			"    Dumps the tracing data to the folder according to the current EAL settings\n\n"
294 
295 			"dump_log_types\n"
296 			"    Dumps the log level for all the dpdk modules\n\n"
297 
298 			"show port (port_id) speed_lanes capabilities"
299 			"	Show speed lanes capabilities of a port.\n\n"
300 		);
301 	}
302 
303 	if (show_all || !strcmp(res->section, "config")) {
304 		cmdline_printf(
305 			cl,
306 			"\n"
307 			"Configuration:\n"
308 			"--------------\n"
309 			"Configuration changes only become active when"
310 			" forwarding is started/restarted.\n\n"
311 
312 			"set default\n"
313 			"    Reset forwarding to the default configuration.\n\n"
314 
315 			"set verbose (level)\n"
316 			"    Set the debug verbosity level X.\n\n"
317 
318 			"set log global|(type) (level)\n"
319 			"    Set the log level.\n\n"
320 
321 			"set nbport (num)\n"
322 			"    Set number of ports.\n\n"
323 
324 			"set nbcore (num)\n"
325 			"    Set number of cores.\n\n"
326 
327 			"set coremask (mask)\n"
328 			"    Set the forwarding cores hexadecimal mask.\n\n"
329 
330 			"set portmask (mask)\n"
331 			"    Set the forwarding ports hexadecimal mask.\n\n"
332 
333 			"set burst (num)\n"
334 			"    Set number of packets per burst.\n\n"
335 
336 			"set burst tx delay (microseconds) retry (num)\n"
337 			"    Set the transmit delay time and number of retries,"
338 			" effective when retry is enabled.\n\n"
339 
340 			"set rxoffs (x[,y]*)\n"
341 			"    Set the offset of each packet segment on"
342 			" receiving if split feature is engaged."
343 			" Affects only the queues configured with split"
344 			" offloads.\n\n"
345 
346 			"set rxpkts (x[,y]*)\n"
347 			"    Set the length of each segment to scatter"
348 			" packets on receiving if split feature is engaged."
349 			" Affects only the queues configured with split"
350 			" offloads.\n\n"
351 
352 			"set rxhdrs (eth[,ipv4])*\n"
353 			"    Set the protocol hdr of each segment to scatter"
354 			" packets on receiving if split feature is engaged."
355 			" Affects only the queues configured with split"
356 			" offloads.\n"
357 			"    Supported values: eth|ipv4|ipv6|ipv4-tcp|ipv6-tcp|"
358 			"ipv4-udp|ipv6-udp|ipv4-sctp|ipv6-sctp|"
359 			"grenat|inner-eth|inner-ipv4|inner-ipv6|inner-ipv4-tcp|"
360 			"inner-ipv6-tcp|inner-ipv4-udp|inner-ipv6-udp|"
361 			"inner-ipv4-sctp|inner-ipv6-sctp\n\n"
362 
363 			"set txpkts (x[,y]*)\n"
364 			"    Set the length of each segment of TXONLY"
365 			" and optionally CSUM packets.\n\n"
366 
367 			"set txsplit (off|on|rand)\n"
368 			"    Set the split policy for the TX packets."
369 			" Right now only applicable for CSUM and TXONLY"
370 			" modes\n\n"
371 
372 			"set txtimes (x, y)\n"
373 			"    Set the scheduling on timestamps"
374 			" timings for the TXONLY mode\n\n"
375 
376 			"set corelist (x[,y]*)\n"
377 			"    Set the list of forwarding cores.\n\n"
378 
379 			"set portlist (x[,y]*)\n"
380 			"    Set the list of forwarding ports.\n\n"
381 
382 			"set port setup on (iterator|event)\n"
383 			"    Select how attached port is retrieved for setup.\n\n"
384 
385 			"set tx loopback (port_id) (on|off)\n"
386 			"    Enable or disable tx loopback.\n\n"
387 
388 			"set all queues drop (port_id) (on|off)\n"
389 			"    Set drop enable bit for all queues.\n\n"
390 
391 			"set vf mac antispoof (port_id) (vf_id) (on|off).\n"
392 			"    Set MAC antispoof for a VF from the PF.\n\n"
393 
394 			"vlan set stripq (on|off) (port_id,queue_id)\n"
395 			"    Set the VLAN strip for a queue on a port.\n\n"
396 
397 			"set vf vlan stripq (port_id) (vf_id) (on|off)\n"
398 			"    Set the VLAN strip for all queues in a pool for a VF from the PF.\n\n"
399 
400 			"set vf vlan insert (port_id) (vf_id) (vlan_id)\n"
401 			"    Set VLAN insert for a VF from the PF.\n\n"
402 
403 			"set vf vlan antispoof (port_id) (vf_id) (on|off)\n"
404 			"    Set VLAN antispoof for a VF from the PF.\n\n"
405 
406 			"vlan set (strip|filter|qinq_strip|extend) (on|off) (port_id)\n"
407 			"    Set the VLAN strip or filter or qinq strip or extend\n\n"
408 
409 			"vlan set (inner|outer) tpid (value) (port_id)\n"
410 			"    Set the VLAN TPID for Packet Filtering on"
411 			" a port\n\n"
412 
413 			"rx_vlan add (vlan_id|all) (port_id)\n"
414 			"    Add a vlan_id, or all identifiers, to the set"
415 			" of VLAN identifiers filtered by port_id.\n\n"
416 
417 			"rx_vlan rm (vlan_id|all) (port_id)\n"
418 			"    Remove a vlan_id, or all identifiers, from the set"
419 			" of VLAN identifiers filtered by port_id.\n\n"
420 
421 			"rx_vlan add (vlan_id) port (port_id) vf (vf_mask)\n"
422 			"    Add a vlan_id, to the set of VLAN identifiers"
423 			"filtered for VF(s) from port_id.\n\n"
424 
425 			"rx_vlan rm (vlan_id) port (port_id) vf (vf_mask)\n"
426 			"    Remove a vlan_id, to the set of VLAN identifiers"
427 			"filtered for VF(s) from port_id.\n\n"
428 
429 			"rx_vxlan_port add (udp_port) (port_id)\n"
430 			"    Add an UDP port for VXLAN packet filter on a port\n\n"
431 
432 			"rx_vxlan_port rm (udp_port) (port_id)\n"
433 			"    Remove an UDP port for VXLAN packet filter on a port\n\n"
434 
435 			"tx_vlan set (port_id) vlan_id[, vlan_id_outer]\n"
436 			"    Set hardware insertion of VLAN IDs (single or double VLAN "
437 			"depends on the number of VLAN IDs) in packets sent on a port.\n\n"
438 
439 			"tx_vlan set pvid port_id vlan_id (on|off)\n"
440 			"    Set port based TX VLAN insertion.\n\n"
441 
442 			"tx_vlan reset (port_id)\n"
443 			"    Disable hardware insertion of a VLAN header in"
444 			" packets sent on a port.\n\n"
445 
446 			"csum set (ip|udp|tcp|sctp|outer-ip|outer-udp) (hw|sw) (port_id)\n"
447 			"    Select hardware or software calculation of the"
448 			" checksum when transmitting a packet using the"
449 			" csum forward engine.\n"
450 			"    ip|udp|tcp|sctp always concern the inner layer.\n"
451 			"    outer-ip concerns the outer IP layer in"
452 			"    outer-udp concerns the outer UDP layer in"
453 			" case the packet is recognized as a tunnel packet by"
454 			" the forward engine (vxlan, gre and ipip are supported)\n"
455 			"    Please check the NIC datasheet for HW limits.\n\n"
456 
457 			"csum parse-tunnel (on|off) (tx_port_id)\n"
458 			"    If disabled, treat tunnel packets as non-tunneled"
459 			" packets (treat inner headers as payload). The port\n"
460 			"    argument is the port used for TX in csum forward"
461 			" engine.\n\n"
462 
463 			"csum show (port_id)\n"
464 			"    Display tx checksum offload configuration\n\n"
465 
466 			"tso set (segsize) (portid)\n"
467 			"    Enable TCP Segmentation Offload in csum forward"
468 			" engine.\n"
469 			"    Please check the NIC datasheet for HW limits.\n\n"
470 
471 			"tso show (portid)"
472 			"    Display the status of TCP Segmentation Offload.\n\n"
473 
474 #ifdef RTE_LIB_GRO
475 			"set port (port_id) gro on|off\n"
476 			"    Enable or disable Generic Receive Offload in"
477 			" csum forwarding engine.\n\n"
478 
479 			"show port (port_id) gro\n"
480 			"    Display GRO configuration.\n\n"
481 
482 			"set gro flush (cycles)\n"
483 			"    Set the cycle to flush GROed packets from"
484 			" reassembly tables.\n\n"
485 #endif
486 
487 #ifdef RTE_LIB_GSO
488 			"set port (port_id) gso (on|off)"
489 			"    Enable or disable Generic Segmentation Offload in"
490 			" csum forwarding engine.\n\n"
491 
492 			"set gso segsz (length)\n"
493 			"    Set max packet length for output GSO segments,"
494 			" including packet header and payload.\n\n"
495 
496 			"show port (port_id) gso\n"
497 			"    Show GSO configuration.\n\n"
498 #endif
499 
500 			"set fwd (%s)\n"
501 			"    Set packet forwarding mode.\n\n"
502 
503 			"mac_addr add (port_id) (XX:XX:XX:XX:XX:XX)\n"
504 			"    Add a MAC address on port_id.\n\n"
505 
506 			"mac_addr remove (port_id) (XX:XX:XX:XX:XX:XX)\n"
507 			"    Remove a MAC address from port_id.\n\n"
508 
509 			"mac_addr set (port_id) (XX:XX:XX:XX:XX:XX)\n"
510 			"    Set the default MAC address for port_id.\n\n"
511 
512 			"mac_addr add port (port_id) vf (vf_id) (mac_address)\n"
513 			"    Add a MAC address for a VF on the port.\n\n"
514 
515 			"mcast_addr add (port_id) (mcast_addr)\n"
516 			"    Add a multicast MAC addresses on port_id.\n\n"
517 
518 			"mcast_addr remove (port_id) (mcast_addr)\n"
519 			"    Remove a multicast MAC address from port_id.\n\n"
520 
521 			"mcast_addr flush (port_id)\n"
522 			"    Flush all multicast MAC addresses on port_id.\n\n"
523 
524 			"set vf mac addr (port_id) (vf_id) (XX:XX:XX:XX:XX:XX)\n"
525 			"    Set the MAC address for a VF from the PF.\n\n"
526 
527 			"set eth-peer (port_id) (peer_addr)\n"
528 			"    set the peer address for certain port.\n\n"
529 
530 			"set port (port_id) uta (mac_address|all) (on|off)\n"
531 			"    Add/Remove a or all unicast hash filter(s)"
532 			"from port X.\n\n"
533 
534 			"set promisc (port_id|all) (on|off)\n"
535 			"    Set the promiscuous mode on port_id, or all.\n\n"
536 
537 			"set allmulti (port_id|all) (on|off)\n"
538 			"    Set the allmulti mode on port_id, or all.\n\n"
539 
540 			"set flow_ctrl rx (on|off) tx (on|off) (high_water)"
541 			" (low_water) (pause_time) (send_xon) mac_ctrl_frame_fwd"
542 			" (on|off) autoneg (on|off) (port_id)\n"
543 			"set flow_ctrl rx (on|off) (portid)\n"
544 			"set flow_ctrl tx (on|off) (portid)\n"
545 			"set flow_ctrl high_water (high_water) (portid)\n"
546 			"set flow_ctrl low_water (low_water) (portid)\n"
547 			"set flow_ctrl pause_time (pause_time) (portid)\n"
548 			"set flow_ctrl send_xon (send_xon) (portid)\n"
549 			"set flow_ctrl mac_ctrl_frame_fwd (on|off) (portid)\n"
550 			"set flow_ctrl autoneg (on|off) (port_id)\n"
551 			"    Set the link flow control parameter on a port.\n\n"
552 
553 			"set pfc_ctrl rx (on|off) tx (on|off) (high_water)"
554 			" (low_water) (pause_time) (priority) (port_id)\n"
555 			"    Set the priority flow control parameter on a"
556 			" port.\n\n"
557 
558 			"set pfc_queue_ctrl (port_id) rx (on|off) (tx_qid)"
559 			" (tx_tc) tx (on|off) (rx_qid) (rx_tc) (pause_time)\n"
560 			"    Set the queue priority flow control parameter on a"
561 			" given Rx and Tx queues of a port.\n\n"
562 
563 			"set port (port_id) rxq (queue_id) avail_thresh (0..99)>\n "
564 			"    set available descriptors threshold for Rx queue\n\n"
565 
566 			"set stat_qmap (tx|rx) (port_id) (queue_id) (qmapping)\n"
567 			"    Set statistics mapping (qmapping 0..15) for RX/TX"
568 			" queue on port.\n"
569 			"    e.g., 'set stat_qmap rx 0 2 5' sets rx queue 2"
570 			" on port 0 to mapping 5.\n\n"
571 
572 			"set xstats-hide-zero on|off\n"
573 			"    Set the option to hide the zero values"
574 			" for xstats display.\n"
575 
576 			"set record-core-cycles on|off\n"
577 			"    Set the option to enable measurement of CPU cycles.\n"
578 
579 			"set record-burst-stats on|off\n"
580 			"    Set the option to enable display of RX and TX bursts.\n"
581 
582 			"set port (port_id) vf (vf_id) rx|tx on|off\n"
583 			"    Enable/Disable a VF receive/transmit from a port\n\n"
584 
585 			"set port (port_id) vf (vf_id) rxmode (AUPE|ROPE|BAM"
586 			"|MPE) (on|off)\n"
587 			"    AUPE:accepts untagged VLAN;"
588 			"ROPE:accept unicast hash\n\n"
589 			"    BAM:accepts broadcast packets;"
590 			"MPE:accepts all multicast packets\n\n"
591 			"    Enable/Disable a VF receive mode of a port\n\n"
592 
593 			"set port (port_id) queue (queue_id) rate (rate_num)\n"
594 			"    Set rate limit for a queue of a port\n\n"
595 
596 			"set port (port_id) vf (vf_id) rate (rate_num) "
597 			"queue_mask (queue_mask_value)\n"
598 			"    Set rate limit for queues in VF of a port\n\n"
599 
600 			"set flush_rx (on|off)\n"
601 			"   Flush (default) or don't flush RX streams before"
602 			" forwarding. Mainly used with PCAP drivers.\n\n"
603 
604 			"set link-up port (port_id)\n"
605 			"	Set link up for a port.\n\n"
606 
607 			"set link-down port (port_id)\n"
608 			"	Set link down for a port.\n\n"
609 
610 			"set port (port_id) ptype_mask (ptype_mask)\n"
611 			"    set packet types classification for a specific port\n\n"
612 
613 			"show port meter cap (port_id)\n"
614 			"    Show port meter capability information\n\n"
615 
616 			"add port meter profile srtcm_rfc2697 (port_id) (profile_id) (cir) (cbs) (ebs) (packet_mode)\n"
617 			"    meter profile add - srtcm rfc 2697\n\n"
618 
619 			"add port meter profile trtcm_rfc2698 (port_id) (profile_id) (cir) (pir) (cbs) (pbs) (packet_mode)\n"
620 			"    meter profile add - trtcm rfc 2698\n\n"
621 
622 			"add port meter profile trtcm_rfc4115 (port_id) (profile_id) (cir) (eir) (cbs) (ebs) (packet_mode)\n"
623 			"    meter profile add - trtcm rfc 4115\n\n"
624 
625 			"del port meter profile (port_id) (profile_id)\n"
626 			"    meter profile delete\n\n"
627 
628 			"create port meter (port_id) (mtr_id) (profile_id) (policy_id) (meter_enable)\n"
629 			"(stats_mask) (shared) (use_pre_meter_color) [(dscp_tbl_entry0) (dscp_tbl_entry1)...\n"
630 			"(dscp_tbl_entry63)]\n"
631 			"    meter create\n\n"
632 
633 			"enable port meter (port_id) (mtr_id)\n"
634 			"    meter enable\n\n"
635 
636 			"disable port meter (port_id) (mtr_id)\n"
637 			"    meter disable\n\n"
638 
639 			"del port meter (port_id) (mtr_id)\n"
640 			"    meter delete\n\n"
641 
642 			"add port meter policy (port_id) (policy_id) g_actions (actions)\n"
643 			"y_actions (actions) r_actions (actions)\n"
644 			"    meter policy add\n\n"
645 
646 			"del port meter policy (port_id) (policy_id)\n"
647 			"    meter policy delete\n\n"
648 
649 			"set port meter profile (port_id) (mtr_id) (profile_id)\n"
650 			"    meter update meter profile\n\n"
651 
652 			"set port meter dscp table (port_id) (mtr_id) [(dscp_tbl_entry0)\n"
653 			"(dscp_tbl_entry1)...(dscp_tbl_entry63)]\n"
654 			"    update meter dscp table entries\n\n"
655 
656 			"set port meter policer action (port_id) (mtr_id) (action_mask)\n"
657 			"(action0) [(action1) (action2)]\n"
658 			"    meter update policer action\n\n"
659 
660 			"set port meter stats mask (port_id) (mtr_id) (stats_mask)\n"
661 			"    meter update stats\n\n"
662 
663 			"set port (port_id) fec_mode auto|off|rs|baser\n"
664 			"    set fec mode for a specific port\n\n"
665 
666 			"show port cman capa (port_id)\n"
667 			"    Show congestion management capabilities\n\n"
668 
669 			"show port cman config (port_id)\n"
670 			"    Show congestion management configuration\n\n"
671 
672 			"set port cman config (port_id) (queue_id) default | "
673 			"[obj (queue|queue_mempool) mode red (min_thresh) "
674 			"(max_thresh) (prob_inv)]\n"
675 			"    Set congestion management configuration\n\n"
676 
677 			"set port (port_id) led (on|off)\n"
678 			"    Set a controllable LED associated with a certain"
679 			" port on or off.\n\n"
680 
681 			, list_pkt_forwarding_modes()
682 		);
683 	}
684 
685 	if (show_all || !strcmp(res->section, "ports")) {
686 
687 		cmdline_printf(
688 			cl,
689 			"\n"
690 			"Port Operations:\n"
691 			"----------------\n\n"
692 
693 			"port start (port_id|all)\n"
694 			"    Start all ports or port_id.\n\n"
695 
696 			"port stop (port_id|all)\n"
697 			"    Stop all ports or port_id.\n\n"
698 
699 			"port close (port_id|all)\n"
700 			"    Close all ports or port_id.\n\n"
701 
702 			"port reset (port_id|all)\n"
703 			"    Reset all ports or port_id.\n\n"
704 
705 			"port attach (ident)\n"
706 			"    Attach physical or virtual dev by pci address or virtual device name\n\n"
707 
708 			"port detach (port_id)\n"
709 			"    Detach physical or virtual dev by port_id\n\n"
710 
711 			"port config (port_id|all)"
712 			" speed (10|100|1000|2500|5000|10000|25000|40000|50000|100000|200000|400000|auto)"
713 			" duplex (half|full|auto)\n"
714 			"    Set speed and duplex for all ports or port_id\n\n"
715 
716 			"port config (port_id|all) loopback (mode)\n"
717 			"    Set loopback mode for all ports or port_id\n\n"
718 
719 			"port config all (rxq|txq|rxd|txd) (value)\n"
720 			"    Set number for rxq/txq/rxd/txd.\n\n"
721 
722 			"port config all max-pkt-len (value)\n"
723 			"    Set the max packet length.\n\n"
724 
725 			"port config all max-lro-pkt-size (value)\n"
726 			"    Set the max LRO aggregated packet size.\n\n"
727 
728 			"port config all drop-en (on|off)\n"
729 			"    Enable or disable packet drop on all RX queues of all ports when no "
730 			"receive buffers available.\n\n"
731 
732 			"port config all rss (all|default|level-default|level-outer|level-inner|"
733 			"ip|tcp|udp|sctp|tunnel|vlan|none|"
734 			"ipv4|ipv4-frag|ipv4-tcp|ipv4-udp|ipv4-sctp|ipv4-other|"
735 			"ipv6|ipv6-frag|ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other|ipv6-ex|ipv6-tcp-ex|ipv6-udp-ex|ipv6-flow-label|"
736 			"l2-payload|port|vxlan|geneve|nvgre|gtpu|eth|s-vlan|c-vlan|"
737 			"esp|ah|l2tpv3|pfcp|pppoe|ecpri|mpls|ipv4-chksum|l4-chksum|"
738 			"l2tpv2|l3-pre96|l3-pre64|l3-pre56|l3-pre48|l3-pre40|l3-pre32|"
739 			"l2-dst-only|l2-src-only|l4-dst-only|l4-src-only|l3-dst-only|l3-src-only|<rsstype_id>)\n"
740 			"    Set the RSS mode.\n\n"
741 
742 			"port config port-id rss reta (hash,queue)[,(hash,queue)]\n"
743 			"    Set the RSS redirection table.\n\n"
744 
745 			"port config (port_id) rss-hash-algo (default|simple_xor|toeplitz|"
746 			"symmetric_toeplitz|symmetric_toeplitz_sort)\n"
747 			"    Set the RSS hash algorithm.\n\n"
748 
749 			"port config (port_id) dcb vt (on|off) (traffic_class)"
750 			" pfc (on|off)\n"
751 			"    Set the DCB mode.\n\n"
752 
753 			"port config all burst (value)\n"
754 			"    Set the number of packets per burst.\n\n"
755 
756 			"port config all (txpt|txht|txwt|rxpt|rxht|rxwt)"
757 			" (value)\n"
758 			"    Set the ring prefetch/host/writeback threshold"
759 			" for tx/rx queue.\n\n"
760 
761 			"port config all (txfreet|txrst|rxfreet) (value)\n"
762 			"    Set free threshold for rx/tx, or set"
763 			" tx rs bit threshold.\n\n"
764 			"port config mtu X value\n"
765 			"    Set the MTU of port X to a given value\n\n"
766 
767 			"port config (port_id) (rxq|txq) (queue_id) ring_size (value)\n"
768 			"    Set a rx/tx queue's ring size configuration, the new"
769 			" value will take effect after command that (re-)start the port"
770 			" or command that setup the specific queue\n\n"
771 
772 			"port (port_id) (rxq|txq) (queue_id) (start|stop)\n"
773 			"    Start/stop a rx/tx queue of port X. Only take effect"
774 			" when port X is started\n\n"
775 
776 			"port (port_id) (rxq|txq) (queue_id) deferred_start (on|off)\n"
777 			"    Switch on/off a deferred start of port X rx/tx queue. Only"
778 			" take effect when port X is stopped.\n\n"
779 
780 			"port (port_id) (rxq|txq) (queue_id) setup\n"
781 			"    Setup a rx/tx queue of port X.\n\n"
782 
783 			"port config (port_id) udp_tunnel_port add|rm vxlan|geneve|ecpri (udp_port)\n\n"
784 			"    Add/remove UDP tunnel port for tunneling offload\n\n"
785 
786 			"port config (port_id|all) rx_offload all|vlan_strip|"
787 			"ipv4_cksum|udp_cksum|tcp_cksum|tcp_lro|qinq_strip|"
788 			"outer_ipv4_cksum|macsec_strip|"
789 			"vlan_filter|vlan_extend|scatter|"
790 			"buffer_split|timestamp|security|keep_crc on|off\n"
791 			"     Enable or disable a per port Rx offloading"
792 			" on all Rx queues of a port\n\n"
793 
794 			"port (port_id) rxq (queue_id) rx_offload all|vlan_strip|"
795 			"ipv4_cksum|udp_cksum|tcp_cksum|tcp_lro|qinq_strip|"
796 			"outer_ipv4_cksum|macsec_strip|"
797 			"vlan_filter|vlan_extend|scatter|"
798 			"buffer_split|timestamp|security|keep_crc on|off\n"
799 			"    Enable or disable a per queue Rx offloading"
800 			" only on a specific Rx queue\n\n"
801 
802 			"port config (port_id|all) tx_offload all|vlan_insert|"
803 			"ipv4_cksum|udp_cksum|tcp_cksum|sctp_cksum|tcp_tso|"
804 			"udp_tso|outer_ipv4_cksum|qinq_insert|vxlan_tnl_tso|"
805 			"gre_tnl_tso|ipip_tnl_tso|geneve_tnl_tso|"
806 			"macsec_insert|mt_lockfree|multi_segs|mbuf_fast_free|"
807 			"security on|off\n"
808 			"    Enable or disable a per port Tx offloading"
809 			" on all Tx queues of a port\n\n"
810 
811 			"port (port_id) txq (queue_id) tx_offload all|vlan_insert|"
812 			"ipv4_cksum|udp_cksum|tcp_cksum|sctp_cksum|tcp_tso|"
813 			"udp_tso|outer_ipv4_cksum|qinq_insert|vxlan_tnl_tso|"
814 			"gre_tnl_tso|ipip_tnl_tso|geneve_tnl_tso|macsec_insert"
815 			"|mt_lockfree|multi_segs|mbuf_fast_free|security"
816 			" on|off\n"
817 			"    Enable or disable a per queue Tx offloading"
818 			" only on a specific Tx queue\n\n"
819 
820 			"bpf-load rx|tx (port) (queue) (J|M|B) (file_name)\n"
821 			"    Load an eBPF program as a callback"
822 			" for particular RX/TX queue\n\n"
823 
824 			"bpf-unload rx|tx (port) (queue)\n"
825 			"    Unload previously loaded eBPF program"
826 			" for particular RX/TX queue\n\n"
827 
828 			"port config (port_id) tx_metadata (value)\n"
829 			"    Set Tx metadata value per port. Testpmd will add this value"
830 			" to any Tx packet sent from this port\n\n"
831 
832 			"port config (port_id) dynf (name) set|clear\n"
833 			"    Register a dynf and Set/clear this flag on Tx. "
834 			"Testpmd will set this value to any Tx packet "
835 			"sent from this port\n\n"
836 
837 			"port cleanup (port_id) txq (queue_id) (free_cnt)\n"
838 			"    Cleanup txq mbufs for a specific Tx queue\n\n"
839 
840 			"port config (port_id) txq (queue_id) affinity (value)\n"
841 			"    Map a Tx queue with an aggregated port "
842 			"of the DPDK port\n\n"
843 
844 			"port config (port_id|all) speed_lanes (value)\n"
845 			"    Set number of lanes for all ports or port_id for a forced speed\n\n"
846 		);
847 	}
848 
849 	if (show_all || !strcmp(res->section, "filters")) {
850 
851 		cmdline_printf(
852 			cl,
853 			"\n"
854 			"filters:\n"
855 			"--------\n\n"
856 
857 			"flow validate {port_id}"
858 			" [group {group_id}] [priority {level}]"
859 			" [ingress] [egress]"
860 			" pattern {item} [/ {item} [...]] / end"
861 			" actions {action} [/ {action} [...]] / end\n"
862 			"    Check whether a flow rule can be created.\n\n"
863 
864 			"flow create {port_id}"
865 			" [group {group_id}] [priority {level}]"
866 			" [ingress] [egress]"
867 			" pattern {item} [/ {item} [...]] / end"
868 			" actions {action} [/ {action} [...]] / end\n"
869 			"    Create a flow rule.\n\n"
870 
871 			"flow destroy {port_id} rule {rule_id} [...]\n"
872 			"    Destroy specific flow rules.\n\n"
873 
874 			"flow update {port_id} {rule_id}"
875 			" actions {action} [/ {action} [...]] / end [user_id]\n"
876 			"    Update a flow rule with new actions.\n\n"
877 
878 			"flow flush {port_id}\n"
879 			"    Destroy all flow rules.\n\n"
880 
881 			"flow query {port_id} {rule_id} {action}\n"
882 			"    Query an existing flow rule.\n\n"
883 
884 			"flow list {port_id} [group {group_id}] [...]\n"
885 			"    List existing flow rules sorted by priority,"
886 			" filtered by group identifiers.\n\n"
887 
888 			"flow isolate {port_id} {boolean}\n"
889 			"    Restrict ingress traffic to the defined"
890 			" flow rules\n\n"
891 
892 			"flow aged {port_id} [destroy]\n"
893 			"    List and destroy aged flows"
894 			" flow rules\n\n"
895 
896 			"flow indirect_action {port_id} create"
897 			" [action_id {indirect_action_id}]"
898 			" [ingress] [egress]"
899 			" action {action} / end\n"
900 			"    Create indirect action.\n\n"
901 
902 			"flow indirect_action {port_id} update"
903 			" {indirect_action_id} action {action} / end\n"
904 			"    Update indirect action.\n\n"
905 
906 			"flow indirect_action {port_id} destroy"
907 			" action_id {indirect_action_id} [...]\n"
908 			"    Destroy specific indirect actions.\n\n"
909 
910 			"flow indirect_action {port_id} query"
911 			" {indirect_action_id}\n"
912 			"    Query an existing indirect action.\n\n"
913 
914 			"set vxlan ip-version (ipv4|ipv6) vni (vni) udp-src"
915 			" (udp-src) udp-dst (udp-dst) ip-src (ip-src) ip-dst"
916 			" (ip-dst) eth-src (eth-src) eth-dst (eth-dst)\n"
917 			"       Configure the VXLAN encapsulation for flows.\n\n"
918 
919 			"set vxlan-with-vlan ip-version (ipv4|ipv6) vni (vni)"
920 			" udp-src (udp-src) udp-dst (udp-dst) ip-src (ip-src)"
921 			" ip-dst (ip-dst) vlan-tci (vlan-tci) eth-src (eth-src)"
922 			" eth-dst (eth-dst)\n"
923 			"       Configure the VXLAN encapsulation for flows.\n\n"
924 
925 			"set vxlan-tos-ttl ip-version (ipv4|ipv6) vni (vni) udp-src"
926 			" (udp-src) udp-dst (udp-dst) ip-tos (ip-tos) ip-ttl (ip-ttl)"
927 			" ip-src (ip-src) ip-dst (ip-dst) eth-src (eth-src)"
928 			" eth-dst (eth-dst)\n"
929 			"       Configure the VXLAN encapsulation for flows.\n\n"
930 
931 			"set nvgre ip-version (ipv4|ipv6) tni (tni) ip-src"
932 			" (ip-src) ip-dst (ip-dst) eth-src (eth-src) eth-dst"
933 			" (eth-dst)\n"
934 			"       Configure the NVGRE encapsulation for flows.\n\n"
935 
936 			"set nvgre-with-vlan ip-version (ipv4|ipv6) tni (tni)"
937 			" ip-src (ip-src) ip-dst (ip-dst) vlan-tci (vlan-tci)"
938 			" eth-src (eth-src) eth-dst (eth-dst)\n"
939 			"       Configure the NVGRE encapsulation for flows.\n\n"
940 
941 			"set raw_encap {flow items}\n"
942 			"	Configure the encapsulation with raw data.\n\n"
943 
944 			"set raw_decap {flow items}\n"
945 			"	Configure the decapsulation with raw data.\n\n"
946 
947 		);
948 	}
949 
950 	if (show_all || !strcmp(res->section, "traffic_management")) {
951 		cmdline_printf(
952 			cl,
953 			"\n"
954 			"Traffic Management:\n"
955 			"--------------\n"
956 			"show port tm cap (port_id)\n"
957 			"       Display the port TM capability.\n\n"
958 
959 			"show port tm level cap (port_id) (level_id)\n"
960 			"       Display the port TM hierarchical level capability.\n\n"
961 
962 			"show port tm node cap (port_id) (node_id)\n"
963 			"       Display the port TM node capability.\n\n"
964 
965 			"show port tm node type (port_id) (node_id)\n"
966 			"       Display the port TM node type.\n\n"
967 
968 			"show port tm node stats (port_id) (node_id) (clear)\n"
969 			"       Display the port TM node stats.\n\n"
970 
971 			"add port tm node shaper profile (port_id) (shaper_profile_id)"
972 			" (cmit_tb_rate) (cmit_tb_size) (peak_tb_rate) (peak_tb_size)"
973 			" (packet_length_adjust) (packet_mode)\n"
974 			"       Add port tm node private shaper profile.\n\n"
975 
976 			"del port tm node shaper profile (port_id) (shaper_profile_id)\n"
977 			"       Delete port tm node private shaper profile.\n\n"
978 
979 			"add port tm node shared shaper (port_id) (shared_shaper_id)"
980 			" (shaper_profile_id)\n"
981 			"       Add/update port tm node shared shaper.\n\n"
982 
983 			"del port tm node shared shaper (port_id) (shared_shaper_id)\n"
984 			"       Delete port tm node shared shaper.\n\n"
985 
986 			"set port tm node shaper profile (port_id) (node_id)"
987 			" (shaper_profile_id)\n"
988 			"       Set port tm node shaper profile.\n\n"
989 
990 			"add port tm node wred profile (port_id) (wred_profile_id)"
991 			" (color_g) (min_th_g) (max_th_g) (maxp_inv_g) (wq_log2_g)"
992 			" (color_y) (min_th_y) (max_th_y) (maxp_inv_y) (wq_log2_y)"
993 			" (color_r) (min_th_r) (max_th_r) (maxp_inv_r) (wq_log2_r)\n"
994 			"       Add port tm node wred profile.\n\n"
995 
996 			"del port tm node wred profile (port_id) (wred_profile_id)\n"
997 			"       Delete port tm node wred profile.\n\n"
998 
999 			"add port tm nonleaf node (port_id) (node_id) (parent_node_id)"
1000 			" (priority) (weight) (level_id) (shaper_profile_id)"
1001 			" (n_sp_priorities) (stats_mask) (n_shared_shapers)"
1002 			" [(shared_shaper_id_0) (shared_shaper_id_1)...]\n"
1003 			"       Add port tm nonleaf node.\n\n"
1004 
1005 			"add port tm nonleaf node pktmode (port_id) (node_id) (parent_node_id)"
1006 			" (priority) (weight) (level_id) (shaper_profile_id)"
1007 			" (n_sp_priorities) (stats_mask) (n_shared_shapers)"
1008 			" [(shared_shaper_id_0) (shared_shaper_id_1)...]\n"
1009 			"       Add port tm nonleaf node with pkt mode enabled.\n\n"
1010 
1011 			"add port tm leaf node (port_id) (node_id) (parent_node_id)"
1012 			" (priority) (weight) (level_id) (shaper_profile_id)"
1013 			" (cman_mode) (wred_profile_id) (stats_mask) (n_shared_shapers)"
1014 			" [(shared_shaper_id_0) (shared_shaper_id_1)...]\n"
1015 			"       Add port tm leaf node.\n\n"
1016 
1017 			"del port tm node (port_id) (node_id)\n"
1018 			"       Delete port tm node.\n\n"
1019 
1020 			"set port tm node parent (port_id) (node_id) (parent_node_id)"
1021 			" (priority) (weight)\n"
1022 			"       Set port tm node parent.\n\n"
1023 
1024 			"suspend port tm node (port_id) (node_id)"
1025 			"       Suspend tm node.\n\n"
1026 
1027 			"resume port tm node (port_id) (node_id)"
1028 			"       Resume tm node.\n\n"
1029 
1030 			"port tm hierarchy commit (port_id) (clean_on_fail)\n"
1031 			"       Commit tm hierarchy.\n\n"
1032 
1033 			"set port tm mark ip_ecn (port) (green) (yellow)"
1034 			" (red)\n"
1035 			"    Enables/Disables the traffic management marking"
1036 			" for IP ECN (Explicit Congestion Notification)"
1037 			" packets on a given port\n\n"
1038 
1039 			"set port tm mark ip_dscp (port) (green) (yellow)"
1040 			" (red)\n"
1041 			"    Enables/Disables the traffic management marking"
1042 			" on the port for IP dscp packets\n\n"
1043 
1044 			"set port tm mark vlan_dei (port) (green) (yellow)"
1045 			" (red)\n"
1046 			"    Enables/Disables the traffic management marking"
1047 			" on the port for VLAN packets with DEI enabled\n\n"
1048 		);
1049 	}
1050 
1051 	if (show_all || !strcmp(res->section, "devices")) {
1052 		cmdline_printf(
1053 			cl,
1054 			"\n"
1055 			"Device Operations:\n"
1056 			"--------------\n"
1057 			"device detach (identifier)\n"
1058 			"       Detach device by identifier.\n\n"
1059 		);
1060 	}
1061 
1062 	if (show_all || !strcmp(res->section, "drivers")) {
1063 		struct testpmd_driver_commands *c;
1064 		unsigned int i;
1065 
1066 		cmdline_printf(
1067 			cl,
1068 			"\n"
1069 			"Driver specific:\n"
1070 			"----------------\n"
1071 		);
1072 		TAILQ_FOREACH(c, &driver_commands_head, next) {
1073 			for (i = 0; c->commands[i].ctx != NULL; i++)
1074 				cmdline_printf(cl, "%s\n", c->commands[i].help);
1075 		}
1076 	}
1077 }
1078 
1079 static cmdline_parse_token_string_t cmd_help_long_help =
1080 	TOKEN_STRING_INITIALIZER(struct cmd_help_long_result, help, "help");
1081 
1082 static cmdline_parse_token_string_t cmd_help_long_section =
1083 	TOKEN_STRING_INITIALIZER(struct cmd_help_long_result, section,
1084 		"all#control#display#config#ports#"
1085 		"filters#traffic_management#devices#drivers");
1086 
1087 static cmdline_parse_inst_t cmd_help_long = {
1088 	.f = cmd_help_long_parsed,
1089 	.data = NULL,
1090 	.help_str = "help all|control|display|config|ports|"
1091 		"filters|traffic_management|devices|drivers: "
1092 		"Show help",
1093 	.tokens = {
1094 		(void *)&cmd_help_long_help,
1095 		(void *)&cmd_help_long_section,
1096 		NULL,
1097 	},
1098 };
1099 
1100 
1101 /* *** start/stop/close all ports *** */
1102 struct cmd_operate_port_result {
1103 	cmdline_fixed_string_t keyword;
1104 	cmdline_fixed_string_t name;
1105 	cmdline_fixed_string_t value;
1106 };
1107 
1108 static void cmd_operate_port_parsed(void *parsed_result,
1109 				__rte_unused struct cmdline *cl,
1110 				__rte_unused void *data)
1111 {
1112 	struct cmd_operate_port_result *res = parsed_result;
1113 
1114 	if (!strcmp(res->name, "start"))
1115 		start_port(RTE_PORT_ALL);
1116 	else if (!strcmp(res->name, "stop"))
1117 		stop_port(RTE_PORT_ALL);
1118 	else if (!strcmp(res->name, "close"))
1119 		close_port(RTE_PORT_ALL);
1120 	else if (!strcmp(res->name, "reset"))
1121 		reset_port(RTE_PORT_ALL);
1122 	else
1123 		fprintf(stderr, "Unknown parameter\n");
1124 }
1125 
1126 static cmdline_parse_token_string_t cmd_operate_port_all_cmd =
1127 	TOKEN_STRING_INITIALIZER(struct cmd_operate_port_result, keyword,
1128 								"port");
1129 static cmdline_parse_token_string_t cmd_operate_port_all_port =
1130 	TOKEN_STRING_INITIALIZER(struct cmd_operate_port_result, name,
1131 						"start#stop#close#reset");
1132 static cmdline_parse_token_string_t cmd_operate_port_all_all =
1133 	TOKEN_STRING_INITIALIZER(struct cmd_operate_port_result, value, "all");
1134 
1135 static cmdline_parse_inst_t cmd_operate_port = {
1136 	.f = cmd_operate_port_parsed,
1137 	.data = NULL,
1138 	.help_str = "port start|stop|close|reset all: Start/Stop/Close/Reset all ports",
1139 	.tokens = {
1140 		(void *)&cmd_operate_port_all_cmd,
1141 		(void *)&cmd_operate_port_all_port,
1142 		(void *)&cmd_operate_port_all_all,
1143 		NULL,
1144 	},
1145 };
1146 
1147 /* *** start/stop/close specific port *** */
1148 struct cmd_operate_specific_port_result {
1149 	cmdline_fixed_string_t keyword;
1150 	cmdline_fixed_string_t name;
1151 	uint8_t value;
1152 };
1153 
1154 static void cmd_operate_specific_port_parsed(void *parsed_result,
1155 			__rte_unused struct cmdline *cl,
1156 				__rte_unused void *data)
1157 {
1158 	struct cmd_operate_specific_port_result *res = parsed_result;
1159 
1160 	if (!strcmp(res->name, "start"))
1161 		start_port(res->value);
1162 	else if (!strcmp(res->name, "stop"))
1163 		stop_port(res->value);
1164 	else if (!strcmp(res->name, "close"))
1165 		close_port(res->value);
1166 	else if (!strcmp(res->name, "reset"))
1167 		reset_port(res->value);
1168 	else
1169 		fprintf(stderr, "Unknown parameter\n");
1170 }
1171 
1172 static cmdline_parse_token_string_t cmd_operate_specific_port_cmd =
1173 	TOKEN_STRING_INITIALIZER(struct cmd_operate_specific_port_result,
1174 							keyword, "port");
1175 static cmdline_parse_token_string_t cmd_operate_specific_port_port =
1176 	TOKEN_STRING_INITIALIZER(struct cmd_operate_specific_port_result,
1177 						name, "start#stop#close#reset");
1178 static cmdline_parse_token_num_t cmd_operate_specific_port_id =
1179 	TOKEN_NUM_INITIALIZER(struct cmd_operate_specific_port_result,
1180 							value, RTE_UINT8);
1181 
1182 static cmdline_parse_inst_t cmd_operate_specific_port = {
1183 	.f = cmd_operate_specific_port_parsed,
1184 	.data = NULL,
1185 	.help_str = "port start|stop|close|reset <port_id>: Start/Stop/Close/Reset port_id",
1186 	.tokens = {
1187 		(void *)&cmd_operate_specific_port_cmd,
1188 		(void *)&cmd_operate_specific_port_port,
1189 		(void *)&cmd_operate_specific_port_id,
1190 		NULL,
1191 	},
1192 };
1193 
1194 /* *** enable port setup (after attach) via iterator or event *** */
1195 struct cmd_set_port_setup_on_result {
1196 	cmdline_fixed_string_t set;
1197 	cmdline_fixed_string_t port;
1198 	cmdline_fixed_string_t setup;
1199 	cmdline_fixed_string_t on;
1200 	cmdline_fixed_string_t mode;
1201 };
1202 
1203 static void cmd_set_port_setup_on_parsed(void *parsed_result,
1204 				__rte_unused struct cmdline *cl,
1205 				__rte_unused void *data)
1206 {
1207 	struct cmd_set_port_setup_on_result *res = parsed_result;
1208 
1209 	if (strcmp(res->mode, "event") == 0)
1210 		setup_on_probe_event = true;
1211 	else if (strcmp(res->mode, "iterator") == 0)
1212 		setup_on_probe_event = false;
1213 	else
1214 		fprintf(stderr, "Unknown mode\n");
1215 }
1216 
1217 static cmdline_parse_token_string_t cmd_set_port_setup_on_set =
1218 	TOKEN_STRING_INITIALIZER(struct cmd_set_port_setup_on_result,
1219 			set, "set");
1220 static cmdline_parse_token_string_t cmd_set_port_setup_on_port =
1221 	TOKEN_STRING_INITIALIZER(struct cmd_set_port_setup_on_result,
1222 			port, "port");
1223 static cmdline_parse_token_string_t cmd_set_port_setup_on_setup =
1224 	TOKEN_STRING_INITIALIZER(struct cmd_set_port_setup_on_result,
1225 			setup, "setup");
1226 static cmdline_parse_token_string_t cmd_set_port_setup_on_on =
1227 	TOKEN_STRING_INITIALIZER(struct cmd_set_port_setup_on_result,
1228 			on, "on");
1229 static cmdline_parse_token_string_t cmd_set_port_setup_on_mode =
1230 	TOKEN_STRING_INITIALIZER(struct cmd_set_port_setup_on_result,
1231 			mode, "iterator#event");
1232 
1233 static cmdline_parse_inst_t cmd_set_port_setup_on = {
1234 	.f = cmd_set_port_setup_on_parsed,
1235 	.data = NULL,
1236 	.help_str = "set port setup on iterator|event",
1237 	.tokens = {
1238 		(void *)&cmd_set_port_setup_on_set,
1239 		(void *)&cmd_set_port_setup_on_port,
1240 		(void *)&cmd_set_port_setup_on_setup,
1241 		(void *)&cmd_set_port_setup_on_on,
1242 		(void *)&cmd_set_port_setup_on_mode,
1243 		NULL,
1244 	},
1245 };
1246 
1247 /* *** attach a specified port *** */
1248 struct cmd_operate_attach_port_result {
1249 	cmdline_fixed_string_t port;
1250 	cmdline_fixed_string_t keyword;
1251 	cmdline_multi_string_t identifier;
1252 };
1253 
1254 static void cmd_operate_attach_port_parsed(void *parsed_result,
1255 				__rte_unused struct cmdline *cl,
1256 				__rte_unused void *data)
1257 {
1258 	struct cmd_operate_attach_port_result *res = parsed_result;
1259 
1260 	if (!strcmp(res->keyword, "attach"))
1261 		attach_port(res->identifier);
1262 	else
1263 		fprintf(stderr, "Unknown parameter\n");
1264 }
1265 
1266 static cmdline_parse_token_string_t cmd_operate_attach_port_port =
1267 	TOKEN_STRING_INITIALIZER(struct cmd_operate_attach_port_result,
1268 			port, "port");
1269 static cmdline_parse_token_string_t cmd_operate_attach_port_keyword =
1270 	TOKEN_STRING_INITIALIZER(struct cmd_operate_attach_port_result,
1271 			keyword, "attach");
1272 static cmdline_parse_token_string_t cmd_operate_attach_port_identifier =
1273 	TOKEN_STRING_INITIALIZER(struct cmd_operate_attach_port_result,
1274 			identifier, TOKEN_STRING_MULTI);
1275 
1276 static cmdline_parse_inst_t cmd_operate_attach_port = {
1277 	.f = cmd_operate_attach_port_parsed,
1278 	.data = NULL,
1279 	.help_str = "port attach <identifier>: "
1280 		"(identifier: pci address or virtual dev name)",
1281 	.tokens = {
1282 		(void *)&cmd_operate_attach_port_port,
1283 		(void *)&cmd_operate_attach_port_keyword,
1284 		(void *)&cmd_operate_attach_port_identifier,
1285 		NULL,
1286 	},
1287 };
1288 
1289 /* *** detach a specified port *** */
1290 struct cmd_operate_detach_port_result {
1291 	cmdline_fixed_string_t port;
1292 	cmdline_fixed_string_t keyword;
1293 	portid_t port_id;
1294 };
1295 
1296 static void cmd_operate_detach_port_parsed(void *parsed_result,
1297 				__rte_unused struct cmdline *cl,
1298 				__rte_unused void *data)
1299 {
1300 	struct cmd_operate_detach_port_result *res = parsed_result;
1301 
1302 	if (!strcmp(res->keyword, "detach")) {
1303 		RTE_ETH_VALID_PORTID_OR_RET(res->port_id);
1304 		detach_port_device(res->port_id);
1305 	} else {
1306 		fprintf(stderr, "Unknown parameter\n");
1307 	}
1308 }
1309 
1310 static cmdline_parse_token_string_t cmd_operate_detach_port_port =
1311 	TOKEN_STRING_INITIALIZER(struct cmd_operate_detach_port_result,
1312 			port, "port");
1313 static cmdline_parse_token_string_t cmd_operate_detach_port_keyword =
1314 	TOKEN_STRING_INITIALIZER(struct cmd_operate_detach_port_result,
1315 			keyword, "detach");
1316 static cmdline_parse_token_num_t cmd_operate_detach_port_port_id =
1317 	TOKEN_NUM_INITIALIZER(struct cmd_operate_detach_port_result,
1318 			port_id, RTE_UINT16);
1319 
1320 static cmdline_parse_inst_t cmd_operate_detach_port = {
1321 	.f = cmd_operate_detach_port_parsed,
1322 	.data = NULL,
1323 	.help_str = "port detach <port_id>",
1324 	.tokens = {
1325 		(void *)&cmd_operate_detach_port_port,
1326 		(void *)&cmd_operate_detach_port_keyword,
1327 		(void *)&cmd_operate_detach_port_port_id,
1328 		NULL,
1329 	},
1330 };
1331 
1332 /* *** detach device by identifier *** */
1333 struct cmd_operate_detach_device_result {
1334 	cmdline_fixed_string_t device;
1335 	cmdline_fixed_string_t keyword;
1336 	cmdline_fixed_string_t identifier;
1337 };
1338 
1339 static void cmd_operate_detach_device_parsed(void *parsed_result,
1340 				__rte_unused struct cmdline *cl,
1341 				__rte_unused void *data)
1342 {
1343 	struct cmd_operate_detach_device_result *res = parsed_result;
1344 
1345 	if (!strcmp(res->keyword, "detach"))
1346 		detach_devargs(res->identifier);
1347 	else
1348 		fprintf(stderr, "Unknown parameter\n");
1349 }
1350 
1351 static cmdline_parse_token_string_t cmd_operate_detach_device_device =
1352 	TOKEN_STRING_INITIALIZER(struct cmd_operate_detach_device_result,
1353 			device, "device");
1354 static cmdline_parse_token_string_t cmd_operate_detach_device_keyword =
1355 	TOKEN_STRING_INITIALIZER(struct cmd_operate_detach_device_result,
1356 			keyword, "detach");
1357 static cmdline_parse_token_string_t cmd_operate_detach_device_identifier =
1358 	TOKEN_STRING_INITIALIZER(struct cmd_operate_detach_device_result,
1359 			identifier, NULL);
1360 
1361 static cmdline_parse_inst_t cmd_operate_detach_device = {
1362 	.f = cmd_operate_detach_device_parsed,
1363 	.data = NULL,
1364 	.help_str = "device detach <identifier>:"
1365 		"(identifier: pci address or virtual dev name)",
1366 	.tokens = {
1367 		(void *)&cmd_operate_detach_device_device,
1368 		(void *)&cmd_operate_detach_device_keyword,
1369 		(void *)&cmd_operate_detach_device_identifier,
1370 		NULL,
1371 	},
1372 };
1373 /* *** configure speed for all ports *** */
1374 struct cmd_config_speed_all {
1375 	cmdline_fixed_string_t port;
1376 	cmdline_fixed_string_t keyword;
1377 	cmdline_fixed_string_t all;
1378 	cmdline_fixed_string_t item1;
1379 	cmdline_fixed_string_t item2;
1380 	cmdline_fixed_string_t value1;
1381 	cmdline_fixed_string_t value2;
1382 };
1383 
1384 static int
1385 parse_and_check_speed_duplex(char *speedstr, char *duplexstr, uint32_t *speed)
1386 {
1387 
1388 	int duplex;
1389 
1390 	if (!strcmp(duplexstr, "half")) {
1391 		duplex = RTE_ETH_LINK_HALF_DUPLEX;
1392 	} else if (!strcmp(duplexstr, "full")) {
1393 		duplex = RTE_ETH_LINK_FULL_DUPLEX;
1394 	} else if (!strcmp(duplexstr, "auto")) {
1395 		duplex = RTE_ETH_LINK_FULL_DUPLEX;
1396 	} else {
1397 		fprintf(stderr, "Unknown duplex parameter\n");
1398 		return -1;
1399 	}
1400 
1401 	if (!strcmp(speedstr, "10")) {
1402 		*speed = (duplex == RTE_ETH_LINK_HALF_DUPLEX) ?
1403 				RTE_ETH_LINK_SPEED_10M_HD : RTE_ETH_LINK_SPEED_10M;
1404 	} else if (!strcmp(speedstr, "100")) {
1405 		*speed = (duplex == RTE_ETH_LINK_HALF_DUPLEX) ?
1406 				RTE_ETH_LINK_SPEED_100M_HD : RTE_ETH_LINK_SPEED_100M;
1407 	} else {
1408 		if (duplex != RTE_ETH_LINK_FULL_DUPLEX) {
1409 			fprintf(stderr, "Invalid speed/duplex parameters\n");
1410 			return -1;
1411 		}
1412 		if (!strcmp(speedstr, "1000")) {
1413 			*speed = RTE_ETH_LINK_SPEED_1G;
1414 		} else if (!strcmp(speedstr, "2500")) {
1415 			*speed = RTE_ETH_LINK_SPEED_2_5G;
1416 		} else if (!strcmp(speedstr, "5000")) {
1417 			*speed = RTE_ETH_LINK_SPEED_5G;
1418 		} else if (!strcmp(speedstr, "10000")) {
1419 			*speed = RTE_ETH_LINK_SPEED_10G;
1420 		} else if (!strcmp(speedstr, "25000")) {
1421 			*speed = RTE_ETH_LINK_SPEED_25G;
1422 		} else if (!strcmp(speedstr, "40000")) {
1423 			*speed = RTE_ETH_LINK_SPEED_40G;
1424 		} else if (!strcmp(speedstr, "50000")) {
1425 			*speed = RTE_ETH_LINK_SPEED_50G;
1426 		} else if (!strcmp(speedstr, "100000")) {
1427 			*speed = RTE_ETH_LINK_SPEED_100G;
1428 		} else if (!strcmp(speedstr, "200000")) {
1429 			*speed = RTE_ETH_LINK_SPEED_200G;
1430 		} else if (!strcmp(speedstr, "400000")) {
1431 			*speed = RTE_ETH_LINK_SPEED_400G;
1432 		} else if (!strcmp(speedstr, "auto")) {
1433 			*speed = RTE_ETH_LINK_SPEED_AUTONEG;
1434 		} else {
1435 			fprintf(stderr, "Unknown speed parameter\n");
1436 			return -1;
1437 		}
1438 	}
1439 
1440 	if (*speed != RTE_ETH_LINK_SPEED_AUTONEG)
1441 		*speed |= RTE_ETH_LINK_SPEED_FIXED;
1442 
1443 	return 0;
1444 }
1445 
1446 static void
1447 cmd_config_speed_all_parsed(void *parsed_result,
1448 			__rte_unused struct cmdline *cl,
1449 			__rte_unused void *data)
1450 {
1451 	struct cmd_config_speed_all *res = parsed_result;
1452 	uint32_t link_speed;
1453 	portid_t pid;
1454 
1455 	if (!all_ports_stopped()) {
1456 		fprintf(stderr, "Please stop all ports first\n");
1457 		return;
1458 	}
1459 
1460 	if (parse_and_check_speed_duplex(res->value1, res->value2,
1461 			&link_speed) < 0)
1462 		return;
1463 
1464 	RTE_ETH_FOREACH_DEV(pid) {
1465 		ports[pid].dev_conf.link_speeds = link_speed;
1466 	}
1467 
1468 	cmd_reconfig_device_queue(RTE_PORT_ALL, 1, 1);
1469 }
1470 
1471 static cmdline_parse_token_string_t cmd_config_speed_all_port =
1472 	TOKEN_STRING_INITIALIZER(struct cmd_config_speed_all, port, "port");
1473 static cmdline_parse_token_string_t cmd_config_speed_all_keyword =
1474 	TOKEN_STRING_INITIALIZER(struct cmd_config_speed_all, keyword,
1475 							"config");
1476 static cmdline_parse_token_string_t cmd_config_speed_all_all =
1477 	TOKEN_STRING_INITIALIZER(struct cmd_config_speed_all, all, "all");
1478 static cmdline_parse_token_string_t cmd_config_speed_all_item1 =
1479 	TOKEN_STRING_INITIALIZER(struct cmd_config_speed_all, item1, "speed");
1480 static cmdline_parse_token_string_t cmd_config_speed_all_value1 =
1481 	TOKEN_STRING_INITIALIZER(struct cmd_config_speed_all, value1,
1482 				"10#100#1000#2500#5000#10000#25000#40000#50000#100000#200000#400000#auto");
1483 static cmdline_parse_token_string_t cmd_config_speed_all_item2 =
1484 	TOKEN_STRING_INITIALIZER(struct cmd_config_speed_all, item2, "duplex");
1485 static cmdline_parse_token_string_t cmd_config_speed_all_value2 =
1486 	TOKEN_STRING_INITIALIZER(struct cmd_config_speed_all, value2,
1487 						"half#full#auto");
1488 
1489 static cmdline_parse_inst_t cmd_config_speed_all = {
1490 	.f = cmd_config_speed_all_parsed,
1491 	.data = NULL,
1492 	.help_str = "port config all speed "
1493 		"10|100|1000|2500|5000|10000|25000|40000|50000|100000|200000|400000|auto duplex "
1494 							"half|full|auto",
1495 	.tokens = {
1496 		(void *)&cmd_config_speed_all_port,
1497 		(void *)&cmd_config_speed_all_keyword,
1498 		(void *)&cmd_config_speed_all_all,
1499 		(void *)&cmd_config_speed_all_item1,
1500 		(void *)&cmd_config_speed_all_value1,
1501 		(void *)&cmd_config_speed_all_item2,
1502 		(void *)&cmd_config_speed_all_value2,
1503 		NULL,
1504 	},
1505 };
1506 
1507 /* *** configure speed for specific port *** */
1508 struct cmd_config_speed_specific {
1509 	cmdline_fixed_string_t port;
1510 	cmdline_fixed_string_t keyword;
1511 	portid_t id;
1512 	cmdline_fixed_string_t item1;
1513 	cmdline_fixed_string_t item2;
1514 	cmdline_fixed_string_t value1;
1515 	cmdline_fixed_string_t value2;
1516 };
1517 
1518 static void
1519 cmd_config_speed_specific_parsed(void *parsed_result,
1520 				__rte_unused struct cmdline *cl,
1521 				__rte_unused void *data)
1522 {
1523 	struct cmd_config_speed_specific *res = parsed_result;
1524 	uint32_t link_speed;
1525 
1526 	if (port_id_is_invalid(res->id, ENABLED_WARN))
1527 		return;
1528 
1529 	if (!port_is_stopped(res->id)) {
1530 		fprintf(stderr, "Please stop port %d first\n", res->id);
1531 		return;
1532 	}
1533 
1534 	if (parse_and_check_speed_duplex(res->value1, res->value2,
1535 			&link_speed) < 0)
1536 		return;
1537 
1538 	ports[res->id].dev_conf.link_speeds = link_speed;
1539 
1540 	cmd_reconfig_device_queue(RTE_PORT_ALL, 1, 1);
1541 }
1542 
1543 
1544 static cmdline_parse_token_string_t cmd_config_speed_specific_port =
1545 	TOKEN_STRING_INITIALIZER(struct cmd_config_speed_specific, port,
1546 								"port");
1547 static cmdline_parse_token_string_t cmd_config_speed_specific_keyword =
1548 	TOKEN_STRING_INITIALIZER(struct cmd_config_speed_specific, keyword,
1549 								"config");
1550 static cmdline_parse_token_num_t cmd_config_speed_specific_id =
1551 	TOKEN_NUM_INITIALIZER(struct cmd_config_speed_specific, id, RTE_UINT16);
1552 static cmdline_parse_token_string_t cmd_config_speed_specific_item1 =
1553 	TOKEN_STRING_INITIALIZER(struct cmd_config_speed_specific, item1,
1554 								"speed");
1555 static cmdline_parse_token_string_t cmd_config_speed_specific_value1 =
1556 	TOKEN_STRING_INITIALIZER(struct cmd_config_speed_specific, value1,
1557 				"10#100#1000#2500#5000#10000#25000#40000#50000#100000#200000#400000#auto");
1558 static cmdline_parse_token_string_t cmd_config_speed_specific_item2 =
1559 	TOKEN_STRING_INITIALIZER(struct cmd_config_speed_specific, item2,
1560 								"duplex");
1561 static cmdline_parse_token_string_t cmd_config_speed_specific_value2 =
1562 	TOKEN_STRING_INITIALIZER(struct cmd_config_speed_specific, value2,
1563 							"half#full#auto");
1564 
1565 static cmdline_parse_inst_t cmd_config_speed_specific = {
1566 	.f = cmd_config_speed_specific_parsed,
1567 	.data = NULL,
1568 	.help_str = "port config <port_id> speed "
1569 		"10|100|1000|2500|5000|10000|25000|40000|50000|100000|200000|400000|auto duplex "
1570 							"half|full|auto",
1571 	.tokens = {
1572 		(void *)&cmd_config_speed_specific_port,
1573 		(void *)&cmd_config_speed_specific_keyword,
1574 		(void *)&cmd_config_speed_specific_id,
1575 		(void *)&cmd_config_speed_specific_item1,
1576 		(void *)&cmd_config_speed_specific_value1,
1577 		(void *)&cmd_config_speed_specific_item2,
1578 		(void *)&cmd_config_speed_specific_value2,
1579 		NULL,
1580 	},
1581 };
1582 
1583 static int
1584 parse_speed_lanes_cfg(portid_t pid, uint32_t lanes)
1585 {
1586 	int ret;
1587 
1588 	ret = rte_eth_speed_lanes_set(pid, lanes);
1589 	if (ret == -ENOTSUP) {
1590 		fprintf(stderr, "Function not implemented\n");
1591 		return -1;
1592 	} else if (ret < 0) {
1593 		fprintf(stderr, "Set speed lanes failed\n");
1594 		return -1;
1595 	}
1596 
1597 	return 0;
1598 }
1599 
1600 static void
1601 show_speed_lanes_capability(unsigned int num, struct rte_eth_speed_lanes_capa *speed_lanes_capa)
1602 {
1603 	unsigned int i;
1604 	uint32_t capa;
1605 
1606 	printf("\n%-15s %-10s", "Supported-speeds", "Valid-lanes");
1607 	printf("\n-----------------------------------\n");
1608 	for (i = 0; i < num; i++) {
1609 		printf("%-17s ",
1610 		       rte_eth_link_speed_to_str(speed_lanes_capa[i].speed));
1611 		capa = speed_lanes_capa[i].capa;
1612 		int s = 0;
1613 
1614 		while (capa) {
1615 			if (capa & 0x1)
1616 				printf("%-2d ", s);
1617 			s++;
1618 			capa = capa >> 1;
1619 		}
1620 		printf("\n");
1621 	}
1622 }
1623 
1624 /* *** display speed lanes per port capabilities *** */
1625 struct cmd_show_speed_lanes_result {
1626 	cmdline_fixed_string_t cmd_show;
1627 	cmdline_fixed_string_t cmd_port;
1628 	cmdline_fixed_string_t cmd_keyword;
1629 	portid_t cmd_pid;
1630 };
1631 
1632 static void
1633 cmd_show_speed_lanes_parsed(void *parsed_result,
1634 			    __rte_unused struct cmdline *cl,
1635 			    __rte_unused void *data)
1636 {
1637 	struct cmd_show_speed_lanes_result *res = parsed_result;
1638 	struct rte_eth_speed_lanes_capa *speed_lanes_capa;
1639 	unsigned int num;
1640 	int ret;
1641 
1642 	if (!rte_eth_dev_is_valid_port(res->cmd_pid)) {
1643 		fprintf(stderr, "Invalid port id %u\n", res->cmd_pid);
1644 		return;
1645 	}
1646 
1647 	ret = rte_eth_speed_lanes_get_capability(res->cmd_pid, NULL, 0);
1648 	if (ret == -ENOTSUP) {
1649 		fprintf(stderr, "Function not implemented\n");
1650 		return;
1651 	} else if (ret < 0) {
1652 		fprintf(stderr, "Get speed lanes capability failed: %d\n", ret);
1653 		return;
1654 	}
1655 
1656 	num = (unsigned int)ret;
1657 	speed_lanes_capa = calloc(num, sizeof(*speed_lanes_capa));
1658 	if (speed_lanes_capa == NULL) {
1659 		fprintf(stderr, "Failed to alloc speed lanes capability buffer\n");
1660 		return;
1661 	}
1662 
1663 	ret = rte_eth_speed_lanes_get_capability(res->cmd_pid, speed_lanes_capa, num);
1664 	if (ret < 0) {
1665 		fprintf(stderr, "Error getting speed lanes capability: %d\n", ret);
1666 		goto out;
1667 	}
1668 
1669 	show_speed_lanes_capability(num, speed_lanes_capa);
1670 out:
1671 	free(speed_lanes_capa);
1672 }
1673 
1674 static cmdline_parse_token_string_t cmd_show_speed_lanes_show =
1675 	TOKEN_STRING_INITIALIZER(struct cmd_show_speed_lanes_result,
1676 				 cmd_show, "show");
1677 static cmdline_parse_token_string_t cmd_show_speed_lanes_port =
1678 	TOKEN_STRING_INITIALIZER(struct cmd_show_speed_lanes_result,
1679 				 cmd_port, "port");
1680 static cmdline_parse_token_num_t cmd_show_speed_lanes_pid =
1681 	TOKEN_NUM_INITIALIZER(struct cmd_show_speed_lanes_result,
1682 			      cmd_pid, RTE_UINT16);
1683 static cmdline_parse_token_string_t cmd_show_speed_lanes_keyword =
1684 	TOKEN_STRING_INITIALIZER(struct cmd_show_speed_lanes_result,
1685 				 cmd_keyword, "speed_lanes");
1686 static cmdline_parse_token_string_t cmd_show_speed_lanes_cap_keyword =
1687 	TOKEN_STRING_INITIALIZER(struct cmd_show_speed_lanes_result,
1688 				 cmd_keyword, "capabilities");
1689 
1690 static cmdline_parse_inst_t cmd_show_speed_lanes = {
1691 	.f = cmd_show_speed_lanes_parsed,
1692 	.data = NULL,
1693 	.help_str = "show port <port_id> speed_lanes capabilities",
1694 	.tokens = {
1695 		(void *)&cmd_show_speed_lanes_show,
1696 		(void *)&cmd_show_speed_lanes_port,
1697 		(void *)&cmd_show_speed_lanes_pid,
1698 		(void *)&cmd_show_speed_lanes_keyword,
1699 		(void *)&cmd_show_speed_lanes_cap_keyword,
1700 		NULL,
1701 	},
1702 };
1703 
1704 /* *** configure speed_lanes for all ports *** */
1705 struct cmd_config_speed_lanes_all {
1706 	cmdline_fixed_string_t port;
1707 	cmdline_fixed_string_t keyword;
1708 	cmdline_fixed_string_t all;
1709 	cmdline_fixed_string_t item;
1710 	uint32_t lanes;
1711 };
1712 
1713 static void
1714 cmd_config_speed_lanes_all_parsed(void *parsed_result,
1715 				  __rte_unused struct cmdline *cl,
1716 				  __rte_unused void *data)
1717 {
1718 	struct cmd_config_speed_lanes_all *res = parsed_result;
1719 	portid_t pid;
1720 
1721 	if (!all_ports_stopped()) {
1722 		fprintf(stderr, "Please stop all ports first\n");
1723 		return;
1724 	}
1725 
1726 	RTE_ETH_FOREACH_DEV(pid) {
1727 		if (parse_speed_lanes_cfg(pid, res->lanes))
1728 			return;
1729 	}
1730 
1731 	cmd_reconfig_device_queue(RTE_PORT_ALL, 1, 1);
1732 }
1733 
1734 static cmdline_parse_token_string_t cmd_config_speed_lanes_all_port =
1735 	TOKEN_STRING_INITIALIZER(struct cmd_config_speed_lanes_all, port, "port");
1736 static cmdline_parse_token_string_t cmd_config_speed_lanes_all_keyword =
1737 	TOKEN_STRING_INITIALIZER(struct cmd_config_speed_lanes_all, keyword,
1738 				 "config");
1739 static cmdline_parse_token_string_t cmd_config_speed_lanes_all_all =
1740 	TOKEN_STRING_INITIALIZER(struct cmd_config_speed_lanes_all, all, "all");
1741 static cmdline_parse_token_string_t cmd_config_speed_lanes_all_item =
1742 	TOKEN_STRING_INITIALIZER(struct cmd_config_speed_lanes_all, item,
1743 				 "speed_lanes");
1744 static cmdline_parse_token_num_t cmd_config_speed_lanes_all_lanes =
1745 	TOKEN_NUM_INITIALIZER(struct cmd_config_speed_lanes_all, lanes, RTE_UINT32);
1746 
1747 static cmdline_parse_inst_t cmd_config_speed_lanes_all = {
1748 	.f = cmd_config_speed_lanes_all_parsed,
1749 	.data = NULL,
1750 	.help_str = "port config all speed_lanes <value>",
1751 	.tokens = {
1752 		(void *)&cmd_config_speed_lanes_all_port,
1753 		(void *)&cmd_config_speed_lanes_all_keyword,
1754 		(void *)&cmd_config_speed_lanes_all_all,
1755 		(void *)&cmd_config_speed_lanes_all_item,
1756 		(void *)&cmd_config_speed_lanes_all_lanes,
1757 		NULL,
1758 	},
1759 };
1760 
1761 /* *** configure speed_lanes for specific port *** */
1762 struct cmd_config_speed_lanes_specific {
1763 	cmdline_fixed_string_t port;
1764 	cmdline_fixed_string_t keyword;
1765 	uint16_t port_id;
1766 	cmdline_fixed_string_t item;
1767 	uint32_t lanes;
1768 };
1769 
1770 static void
1771 cmd_config_speed_lanes_specific_parsed(void *parsed_result,
1772 				       __rte_unused struct cmdline *cl,
1773 				       __rte_unused void *data)
1774 {
1775 	struct cmd_config_speed_lanes_specific *res = parsed_result;
1776 
1777 	if (port_id_is_invalid(res->port_id, ENABLED_WARN))
1778 		return;
1779 
1780 	if (!port_is_stopped(res->port_id)) {
1781 		fprintf(stderr, "Please stop port %u first\n", res->port_id);
1782 		return;
1783 	}
1784 
1785 	if (parse_speed_lanes_cfg(res->port_id, res->lanes))
1786 		return;
1787 
1788 	cmd_reconfig_device_queue(res->port_id, 1, 1);
1789 }
1790 
1791 static cmdline_parse_token_string_t cmd_config_speed_lanes_specific_port =
1792 	TOKEN_STRING_INITIALIZER(struct cmd_config_speed_lanes_specific, port,
1793 				 "port");
1794 static cmdline_parse_token_string_t cmd_config_speed_lanes_specific_keyword =
1795 	TOKEN_STRING_INITIALIZER(struct cmd_config_speed_lanes_specific, keyword,
1796 				 "config");
1797 static cmdline_parse_token_num_t cmd_config_speed_lanes_specific_id =
1798 	TOKEN_NUM_INITIALIZER(struct cmd_config_speed_lanes_specific, port_id,
1799 			      RTE_UINT16);
1800 static cmdline_parse_token_string_t cmd_config_speed_lanes_specific_item =
1801 	TOKEN_STRING_INITIALIZER(struct cmd_config_speed_lanes_specific, item,
1802 				 "speed_lanes");
1803 static cmdline_parse_token_num_t cmd_config_speed_lanes_specific_lanes =
1804 	TOKEN_NUM_INITIALIZER(struct cmd_config_speed_lanes_specific, lanes,
1805 			      RTE_UINT32);
1806 
1807 static cmdline_parse_inst_t cmd_config_speed_lanes_specific = {
1808 	.f = cmd_config_speed_lanes_specific_parsed,
1809 	.data = NULL,
1810 	.help_str = "port config <port_id> speed_lanes <value>",
1811 	.tokens = {
1812 		(void *)&cmd_config_speed_lanes_specific_port,
1813 		(void *)&cmd_config_speed_lanes_specific_keyword,
1814 		(void *)&cmd_config_speed_lanes_specific_id,
1815 		(void *)&cmd_config_speed_lanes_specific_item,
1816 		(void *)&cmd_config_speed_lanes_specific_lanes,
1817 		NULL,
1818 	},
1819 };
1820 
1821 /* *** configure loopback for all ports *** */
1822 struct cmd_config_loopback_all {
1823 	cmdline_fixed_string_t port;
1824 	cmdline_fixed_string_t keyword;
1825 	cmdline_fixed_string_t all;
1826 	cmdline_fixed_string_t item;
1827 	uint32_t mode;
1828 };
1829 
1830 static void
1831 cmd_config_loopback_all_parsed(void *parsed_result,
1832 			__rte_unused struct cmdline *cl,
1833 			__rte_unused void *data)
1834 {
1835 	struct cmd_config_loopback_all *res = parsed_result;
1836 	portid_t pid;
1837 
1838 	if (!all_ports_stopped()) {
1839 		fprintf(stderr, "Please stop all ports first\n");
1840 		return;
1841 	}
1842 
1843 	RTE_ETH_FOREACH_DEV(pid) {
1844 		ports[pid].dev_conf.lpbk_mode = res->mode;
1845 	}
1846 
1847 	cmd_reconfig_device_queue(RTE_PORT_ALL, 1, 1);
1848 }
1849 
1850 static cmdline_parse_token_string_t cmd_config_loopback_all_port =
1851 	TOKEN_STRING_INITIALIZER(struct cmd_config_loopback_all, port, "port");
1852 static cmdline_parse_token_string_t cmd_config_loopback_all_keyword =
1853 	TOKEN_STRING_INITIALIZER(struct cmd_config_loopback_all, keyword,
1854 							"config");
1855 static cmdline_parse_token_string_t cmd_config_loopback_all_all =
1856 	TOKEN_STRING_INITIALIZER(struct cmd_config_loopback_all, all, "all");
1857 static cmdline_parse_token_string_t cmd_config_loopback_all_item =
1858 	TOKEN_STRING_INITIALIZER(struct cmd_config_loopback_all, item,
1859 							"loopback");
1860 static cmdline_parse_token_num_t cmd_config_loopback_all_mode =
1861 	TOKEN_NUM_INITIALIZER(struct cmd_config_loopback_all, mode, RTE_UINT32);
1862 
1863 static cmdline_parse_inst_t cmd_config_loopback_all = {
1864 	.f = cmd_config_loopback_all_parsed,
1865 	.data = NULL,
1866 	.help_str = "port config all loopback <mode>",
1867 	.tokens = {
1868 		(void *)&cmd_config_loopback_all_port,
1869 		(void *)&cmd_config_loopback_all_keyword,
1870 		(void *)&cmd_config_loopback_all_all,
1871 		(void *)&cmd_config_loopback_all_item,
1872 		(void *)&cmd_config_loopback_all_mode,
1873 		NULL,
1874 	},
1875 };
1876 
1877 /* *** configure loopback for specific port *** */
1878 struct cmd_config_loopback_specific {
1879 	cmdline_fixed_string_t port;
1880 	cmdline_fixed_string_t keyword;
1881 	uint16_t port_id;
1882 	cmdline_fixed_string_t item;
1883 	uint32_t mode;
1884 };
1885 
1886 static void
1887 cmd_config_loopback_specific_parsed(void *parsed_result,
1888 				__rte_unused struct cmdline *cl,
1889 				__rte_unused void *data)
1890 {
1891 	struct cmd_config_loopback_specific *res = parsed_result;
1892 
1893 	if (port_id_is_invalid(res->port_id, ENABLED_WARN))
1894 		return;
1895 
1896 	if (!port_is_stopped(res->port_id)) {
1897 		fprintf(stderr, "Please stop port %u first\n", res->port_id);
1898 		return;
1899 	}
1900 
1901 	ports[res->port_id].dev_conf.lpbk_mode = res->mode;
1902 
1903 	cmd_reconfig_device_queue(res->port_id, 1, 1);
1904 }
1905 
1906 static cmdline_parse_token_string_t cmd_config_loopback_specific_port =
1907 	TOKEN_STRING_INITIALIZER(struct cmd_config_loopback_specific, port,
1908 								"port");
1909 static cmdline_parse_token_string_t cmd_config_loopback_specific_keyword =
1910 	TOKEN_STRING_INITIALIZER(struct cmd_config_loopback_specific, keyword,
1911 								"config");
1912 static cmdline_parse_token_num_t cmd_config_loopback_specific_id =
1913 	TOKEN_NUM_INITIALIZER(struct cmd_config_loopback_specific, port_id,
1914 								RTE_UINT16);
1915 static cmdline_parse_token_string_t cmd_config_loopback_specific_item =
1916 	TOKEN_STRING_INITIALIZER(struct cmd_config_loopback_specific, item,
1917 								"loopback");
1918 static cmdline_parse_token_num_t cmd_config_loopback_specific_mode =
1919 	TOKEN_NUM_INITIALIZER(struct cmd_config_loopback_specific, mode,
1920 			      RTE_UINT32);
1921 
1922 static cmdline_parse_inst_t cmd_config_loopback_specific = {
1923 	.f = cmd_config_loopback_specific_parsed,
1924 	.data = NULL,
1925 	.help_str = "port config <port_id> loopback <mode>",
1926 	.tokens = {
1927 		(void *)&cmd_config_loopback_specific_port,
1928 		(void *)&cmd_config_loopback_specific_keyword,
1929 		(void *)&cmd_config_loopback_specific_id,
1930 		(void *)&cmd_config_loopback_specific_item,
1931 		(void *)&cmd_config_loopback_specific_mode,
1932 		NULL,
1933 	},
1934 };
1935 
1936 /* *** configure txq/rxq, txd/rxd *** */
1937 struct cmd_config_rx_tx {
1938 	cmdline_fixed_string_t port;
1939 	cmdline_fixed_string_t keyword;
1940 	cmdline_fixed_string_t all;
1941 	cmdline_fixed_string_t name;
1942 	uint16_t value;
1943 };
1944 
1945 static void
1946 cmd_config_rx_tx_parsed(void *parsed_result,
1947 			__rte_unused struct cmdline *cl,
1948 			__rte_unused void *data)
1949 {
1950 	struct cmd_config_rx_tx *res = parsed_result;
1951 
1952 	if (!all_ports_stopped()) {
1953 		fprintf(stderr, "Please stop all ports first\n");
1954 		return;
1955 	}
1956 	if (!strcmp(res->name, "rxq")) {
1957 		if (!res->value && !nb_txq) {
1958 			fprintf(stderr, "Warning: Either rx or tx queues should be non zero\n");
1959 			return;
1960 		}
1961 		if (check_nb_rxq(res->value) != 0)
1962 			return;
1963 		nb_rxq = res->value;
1964 	}
1965 	else if (!strcmp(res->name, "txq")) {
1966 		if (!res->value && !nb_rxq) {
1967 			fprintf(stderr, "Warning: Either rx or tx queues should be non zero\n");
1968 			return;
1969 		}
1970 		if (check_nb_txq(res->value) != 0)
1971 			return;
1972 		nb_txq = res->value;
1973 	}
1974 	else if (!strcmp(res->name, "rxd")) {
1975 		if (check_nb_rxd(res->value) != 0)
1976 			return;
1977 		nb_rxd = res->value;
1978 	} else if (!strcmp(res->name, "txd")) {
1979 		if (check_nb_txd(res->value) != 0)
1980 			return;
1981 
1982 		nb_txd = res->value;
1983 	} else {
1984 		fprintf(stderr, "Unknown parameter\n");
1985 		return;
1986 	}
1987 
1988 	fwd_config_setup();
1989 
1990 	init_port_config();
1991 
1992 	cmd_reconfig_device_queue(RTE_PORT_ALL, 1, 1);
1993 }
1994 
1995 static cmdline_parse_token_string_t cmd_config_rx_tx_port =
1996 	TOKEN_STRING_INITIALIZER(struct cmd_config_rx_tx, port, "port");
1997 static cmdline_parse_token_string_t cmd_config_rx_tx_keyword =
1998 	TOKEN_STRING_INITIALIZER(struct cmd_config_rx_tx, keyword, "config");
1999 static cmdline_parse_token_string_t cmd_config_rx_tx_all =
2000 	TOKEN_STRING_INITIALIZER(struct cmd_config_rx_tx, all, "all");
2001 static cmdline_parse_token_string_t cmd_config_rx_tx_name =
2002 	TOKEN_STRING_INITIALIZER(struct cmd_config_rx_tx, name,
2003 						"rxq#txq#rxd#txd");
2004 static cmdline_parse_token_num_t cmd_config_rx_tx_value =
2005 	TOKEN_NUM_INITIALIZER(struct cmd_config_rx_tx, value, RTE_UINT16);
2006 
2007 static cmdline_parse_inst_t cmd_config_rx_tx = {
2008 	.f = cmd_config_rx_tx_parsed,
2009 	.data = NULL,
2010 	.help_str = "port config all rxq|txq|rxd|txd <value>",
2011 	.tokens = {
2012 		(void *)&cmd_config_rx_tx_port,
2013 		(void *)&cmd_config_rx_tx_keyword,
2014 		(void *)&cmd_config_rx_tx_all,
2015 		(void *)&cmd_config_rx_tx_name,
2016 		(void *)&cmd_config_rx_tx_value,
2017 		NULL,
2018 	},
2019 };
2020 
2021 /* *** config max packet length *** */
2022 struct cmd_config_max_pkt_len_result {
2023 	cmdline_fixed_string_t port;
2024 	cmdline_fixed_string_t keyword;
2025 	cmdline_fixed_string_t all;
2026 	cmdline_fixed_string_t name;
2027 	uint32_t value;
2028 };
2029 
2030 static void
2031 cmd_config_max_pkt_len_parsed(void *parsed_result,
2032 				__rte_unused struct cmdline *cl,
2033 				__rte_unused void *data)
2034 {
2035 	struct cmd_config_max_pkt_len_result *res = parsed_result;
2036 	portid_t port_id;
2037 	int ret;
2038 
2039 	if (strcmp(res->name, "max-pkt-len") != 0) {
2040 		printf("Unknown parameter\n");
2041 		return;
2042 	}
2043 
2044 	if (!all_ports_stopped()) {
2045 		fprintf(stderr, "Please stop all ports first\n");
2046 		return;
2047 	}
2048 
2049 	RTE_ETH_FOREACH_DEV(port_id) {
2050 		struct rte_port *port = &ports[port_id];
2051 
2052 		if (res->value < RTE_ETHER_MIN_LEN) {
2053 			fprintf(stderr,
2054 				"max-pkt-len can not be less than %d\n",
2055 				RTE_ETHER_MIN_LEN);
2056 			return;
2057 		}
2058 
2059 		ret = eth_dev_info_get_print_err(port_id, &port->dev_info);
2060 		if (ret != 0) {
2061 			fprintf(stderr,
2062 				"rte_eth_dev_info_get() failed for port %u\n",
2063 				port_id);
2064 			return;
2065 		}
2066 
2067 		update_mtu_from_frame_size(port_id, res->value);
2068 	}
2069 
2070 	init_port_config();
2071 
2072 	cmd_reconfig_device_queue(RTE_PORT_ALL, 1, 1);
2073 }
2074 
2075 static cmdline_parse_token_string_t cmd_config_max_pkt_len_port =
2076 	TOKEN_STRING_INITIALIZER(struct cmd_config_max_pkt_len_result, port,
2077 								"port");
2078 static cmdline_parse_token_string_t cmd_config_max_pkt_len_keyword =
2079 	TOKEN_STRING_INITIALIZER(struct cmd_config_max_pkt_len_result, keyword,
2080 								"config");
2081 static cmdline_parse_token_string_t cmd_config_max_pkt_len_all =
2082 	TOKEN_STRING_INITIALIZER(struct cmd_config_max_pkt_len_result, all,
2083 								"all");
2084 static cmdline_parse_token_string_t cmd_config_max_pkt_len_name =
2085 	TOKEN_STRING_INITIALIZER(struct cmd_config_max_pkt_len_result, name,
2086 								"max-pkt-len");
2087 static cmdline_parse_token_num_t cmd_config_max_pkt_len_value =
2088 	TOKEN_NUM_INITIALIZER(struct cmd_config_max_pkt_len_result, value,
2089 								RTE_UINT32);
2090 
2091 static cmdline_parse_inst_t cmd_config_max_pkt_len = {
2092 	.f = cmd_config_max_pkt_len_parsed,
2093 	.data = NULL,
2094 	.help_str = "port config all max-pkt-len <value>",
2095 	.tokens = {
2096 		(void *)&cmd_config_max_pkt_len_port,
2097 		(void *)&cmd_config_max_pkt_len_keyword,
2098 		(void *)&cmd_config_max_pkt_len_all,
2099 		(void *)&cmd_config_max_pkt_len_name,
2100 		(void *)&cmd_config_max_pkt_len_value,
2101 		NULL,
2102 	},
2103 };
2104 
2105 /* *** config max LRO aggregated packet size *** */
2106 struct cmd_config_max_lro_pkt_size_result {
2107 	cmdline_fixed_string_t port;
2108 	cmdline_fixed_string_t keyword;
2109 	cmdline_fixed_string_t all;
2110 	cmdline_fixed_string_t name;
2111 	uint32_t value;
2112 };
2113 
2114 static void
2115 cmd_config_max_lro_pkt_size_parsed(void *parsed_result,
2116 				__rte_unused struct cmdline *cl,
2117 				__rte_unused void *data)
2118 {
2119 	struct cmd_config_max_lro_pkt_size_result *res = parsed_result;
2120 	portid_t pid;
2121 
2122 	if (!all_ports_stopped()) {
2123 		fprintf(stderr, "Please stop all ports first\n");
2124 		return;
2125 	}
2126 
2127 	RTE_ETH_FOREACH_DEV(pid) {
2128 		struct rte_port *port = &ports[pid];
2129 
2130 		if (!strcmp(res->name, "max-lro-pkt-size")) {
2131 			if (res->value ==
2132 					port->dev_conf.rxmode.max_lro_pkt_size)
2133 				return;
2134 
2135 			port->dev_conf.rxmode.max_lro_pkt_size = res->value;
2136 		} else {
2137 			fprintf(stderr, "Unknown parameter\n");
2138 			return;
2139 		}
2140 	}
2141 
2142 	init_port_config();
2143 
2144 	cmd_reconfig_device_queue(RTE_PORT_ALL, 1, 1);
2145 }
2146 
2147 static cmdline_parse_token_string_t cmd_config_max_lro_pkt_size_port =
2148 	TOKEN_STRING_INITIALIZER(struct cmd_config_max_lro_pkt_size_result,
2149 				 port, "port");
2150 static cmdline_parse_token_string_t cmd_config_max_lro_pkt_size_keyword =
2151 	TOKEN_STRING_INITIALIZER(struct cmd_config_max_lro_pkt_size_result,
2152 				 keyword, "config");
2153 static cmdline_parse_token_string_t cmd_config_max_lro_pkt_size_all =
2154 	TOKEN_STRING_INITIALIZER(struct cmd_config_max_lro_pkt_size_result,
2155 				 all, "all");
2156 static cmdline_parse_token_string_t cmd_config_max_lro_pkt_size_name =
2157 	TOKEN_STRING_INITIALIZER(struct cmd_config_max_lro_pkt_size_result,
2158 				 name, "max-lro-pkt-size");
2159 static cmdline_parse_token_num_t cmd_config_max_lro_pkt_size_value =
2160 	TOKEN_NUM_INITIALIZER(struct cmd_config_max_lro_pkt_size_result,
2161 			      value, RTE_UINT32);
2162 
2163 static cmdline_parse_inst_t cmd_config_max_lro_pkt_size = {
2164 	.f = cmd_config_max_lro_pkt_size_parsed,
2165 	.data = NULL,
2166 	.help_str = "port config all max-lro-pkt-size <value>",
2167 	.tokens = {
2168 		(void *)&cmd_config_max_lro_pkt_size_port,
2169 		(void *)&cmd_config_max_lro_pkt_size_keyword,
2170 		(void *)&cmd_config_max_lro_pkt_size_all,
2171 		(void *)&cmd_config_max_lro_pkt_size_name,
2172 		(void *)&cmd_config_max_lro_pkt_size_value,
2173 		NULL,
2174 	},
2175 };
2176 
2177 /* *** configure port MTU *** */
2178 struct cmd_config_mtu_result {
2179 	cmdline_fixed_string_t port;
2180 	cmdline_fixed_string_t keyword;
2181 	cmdline_fixed_string_t mtu;
2182 	portid_t port_id;
2183 	uint16_t value;
2184 };
2185 
2186 static void
2187 cmd_config_mtu_parsed(void *parsed_result,
2188 		      __rte_unused struct cmdline *cl,
2189 		      __rte_unused void *data)
2190 {
2191 	struct cmd_config_mtu_result *res = parsed_result;
2192 
2193 	port_mtu_set(res->port_id, res->value);
2194 }
2195 
2196 static cmdline_parse_token_string_t cmd_config_mtu_port =
2197 	TOKEN_STRING_INITIALIZER(struct cmd_config_mtu_result, port,
2198 				 "port");
2199 static cmdline_parse_token_string_t cmd_config_mtu_keyword =
2200 	TOKEN_STRING_INITIALIZER(struct cmd_config_mtu_result, keyword,
2201 				 "config");
2202 static cmdline_parse_token_string_t cmd_config_mtu_mtu =
2203 	TOKEN_STRING_INITIALIZER(struct cmd_config_mtu_result, keyword,
2204 				 "mtu");
2205 static cmdline_parse_token_num_t cmd_config_mtu_port_id =
2206 	TOKEN_NUM_INITIALIZER(struct cmd_config_mtu_result, port_id,
2207 				 RTE_UINT16);
2208 static cmdline_parse_token_num_t cmd_config_mtu_value =
2209 	TOKEN_NUM_INITIALIZER(struct cmd_config_mtu_result, value,
2210 				 RTE_UINT16);
2211 
2212 static cmdline_parse_inst_t cmd_config_mtu = {
2213 	.f = cmd_config_mtu_parsed,
2214 	.data = NULL,
2215 	.help_str = "port config mtu <port_id> <value>",
2216 	.tokens = {
2217 		(void *)&cmd_config_mtu_port,
2218 		(void *)&cmd_config_mtu_keyword,
2219 		(void *)&cmd_config_mtu_mtu,
2220 		(void *)&cmd_config_mtu_port_id,
2221 		(void *)&cmd_config_mtu_value,
2222 		NULL,
2223 	},
2224 };
2225 
2226 /* *** configure rx mode *** */
2227 struct cmd_config_rx_mode_flag {
2228 	cmdline_fixed_string_t port;
2229 	cmdline_fixed_string_t keyword;
2230 	cmdline_fixed_string_t all;
2231 	cmdline_fixed_string_t name;
2232 	cmdline_fixed_string_t value;
2233 };
2234 
2235 static void
2236 cmd_config_rx_mode_flag_parsed(void *parsed_result,
2237 				__rte_unused struct cmdline *cl,
2238 				__rte_unused void *data)
2239 {
2240 	struct cmd_config_rx_mode_flag *res = parsed_result;
2241 
2242 	if (!all_ports_stopped()) {
2243 		fprintf(stderr, "Please stop all ports first\n");
2244 		return;
2245 	}
2246 
2247 	if (!strcmp(res->name, "drop-en")) {
2248 		if (!strcmp(res->value, "on"))
2249 			rx_drop_en = 1;
2250 		else if (!strcmp(res->value, "off"))
2251 			rx_drop_en = 0;
2252 		else {
2253 			fprintf(stderr, "Unknown parameter\n");
2254 			return;
2255 		}
2256 	} else {
2257 		fprintf(stderr, "Unknown parameter\n");
2258 		return;
2259 	}
2260 
2261 	init_port_config();
2262 
2263 	cmd_reconfig_device_queue(RTE_PORT_ALL, 1, 1);
2264 }
2265 
2266 static cmdline_parse_token_string_t cmd_config_rx_mode_flag_port =
2267 	TOKEN_STRING_INITIALIZER(struct cmd_config_rx_mode_flag, port, "port");
2268 static cmdline_parse_token_string_t cmd_config_rx_mode_flag_keyword =
2269 	TOKEN_STRING_INITIALIZER(struct cmd_config_rx_mode_flag, keyword,
2270 								"config");
2271 static cmdline_parse_token_string_t cmd_config_rx_mode_flag_all =
2272 	TOKEN_STRING_INITIALIZER(struct cmd_config_rx_mode_flag, all, "all");
2273 static cmdline_parse_token_string_t cmd_config_rx_mode_flag_name =
2274 	TOKEN_STRING_INITIALIZER(struct cmd_config_rx_mode_flag, name,
2275 					"drop-en");
2276 static cmdline_parse_token_string_t cmd_config_rx_mode_flag_value =
2277 	TOKEN_STRING_INITIALIZER(struct cmd_config_rx_mode_flag, value,
2278 							"on#off");
2279 
2280 static cmdline_parse_inst_t cmd_config_rx_mode_flag = {
2281 	.f = cmd_config_rx_mode_flag_parsed,
2282 	.data = NULL,
2283 	.help_str = "port config all drop-en on|off",
2284 	.tokens = {
2285 		(void *)&cmd_config_rx_mode_flag_port,
2286 		(void *)&cmd_config_rx_mode_flag_keyword,
2287 		(void *)&cmd_config_rx_mode_flag_all,
2288 		(void *)&cmd_config_rx_mode_flag_name,
2289 		(void *)&cmd_config_rx_mode_flag_value,
2290 		NULL,
2291 	},
2292 };
2293 
2294 /* *** configure rss *** */
2295 struct cmd_config_rss {
2296 	cmdline_fixed_string_t port;
2297 	cmdline_fixed_string_t keyword;
2298 	cmdline_fixed_string_t all;
2299 	cmdline_fixed_string_t name;
2300 	cmdline_fixed_string_t value;
2301 };
2302 
2303 static void
2304 cmd_config_rss_parsed(void *parsed_result,
2305 			__rte_unused struct cmdline *cl,
2306 			__rte_unused void *data)
2307 {
2308 	struct cmd_config_rss *res = parsed_result;
2309 	struct rte_eth_rss_conf rss_conf = { .rss_key_len = 0, };
2310 	struct rte_eth_dev_info dev_info = { .flow_type_rss_offloads = 0, };
2311 	int use_default = 0;
2312 	int all_updated = 1;
2313 	int diag;
2314 	uint16_t i;
2315 	int ret;
2316 
2317 	if (!strcmp(res->value, "level-default")) {
2318 		rss_hf &= (~RTE_ETH_RSS_LEVEL_MASK);
2319 		rss_conf.rss_hf = (rss_hf | RTE_ETH_RSS_LEVEL_PMD_DEFAULT);
2320 	} else if (!strcmp(res->value, "level-outer")) {
2321 		rss_hf &= (~RTE_ETH_RSS_LEVEL_MASK);
2322 		rss_conf.rss_hf = (rss_hf | RTE_ETH_RSS_LEVEL_OUTERMOST);
2323 	} else if (!strcmp(res->value, "level-inner")) {
2324 		rss_hf &= (~RTE_ETH_RSS_LEVEL_MASK);
2325 		rss_conf.rss_hf = (rss_hf | RTE_ETH_RSS_LEVEL_INNERMOST);
2326 	} else if (!strcmp(res->value, "default")) {
2327 		use_default = 1;
2328 	} else if (isdigit(res->value[0])) {
2329 		int value = atoi(res->value);
2330 		if (value > 0 && value < 64)
2331 			rss_conf.rss_hf = 1ULL << (uint8_t)value;
2332 		else {
2333 			fprintf(stderr, "flowtype_id should be greater than 0 and less than 64.\n");
2334 			return;
2335 		}
2336 	} else if (!strcmp(res->value, "none")) {
2337 		rss_conf.rss_hf = 0;
2338 	} else {
2339 		rss_conf.rss_hf = str_to_rsstypes(res->value);
2340 		if (rss_conf.rss_hf == 0) {
2341 			fprintf(stderr, "Unknown parameter\n");
2342 			return;
2343 		}
2344 	}
2345 	rss_conf.rss_key = NULL;
2346 	/* Update global configuration for RSS types. */
2347 	RTE_ETH_FOREACH_DEV(i) {
2348 		struct rte_eth_rss_conf local_rss_conf;
2349 
2350 		ret = eth_dev_info_get_print_err(i, &dev_info);
2351 		if (ret != 0)
2352 			return;
2353 
2354 		if (use_default)
2355 			rss_conf.rss_hf = dev_info.flow_type_rss_offloads;
2356 
2357 		local_rss_conf = rss_conf;
2358 		local_rss_conf.rss_hf = rss_conf.rss_hf &
2359 			dev_info.flow_type_rss_offloads;
2360 		if (local_rss_conf.rss_hf != rss_conf.rss_hf) {
2361 			printf("Port %u modified RSS hash function based on hardware support,"
2362 				"requested:%#"PRIx64" configured:%#"PRIx64"\n",
2363 				i, rss_conf.rss_hf, local_rss_conf.rss_hf);
2364 		}
2365 		diag = rte_eth_dev_rss_hash_update(i, &local_rss_conf);
2366 		if (diag < 0) {
2367 			all_updated = 0;
2368 			fprintf(stderr,
2369 				"Configuration of RSS hash at ethernet port %d failed with error (%d): %s.\n",
2370 				i, -diag, strerror(-diag));
2371 		}
2372 	}
2373 	if (all_updated && !use_default) {
2374 		rss_hf = rss_conf.rss_hf;
2375 		printf("rss_hf %#"PRIx64"\n", rss_hf);
2376 	}
2377 }
2378 
2379 static cmdline_parse_token_string_t cmd_config_rss_port =
2380 	TOKEN_STRING_INITIALIZER(struct cmd_config_rss, port, "port");
2381 static cmdline_parse_token_string_t cmd_config_rss_keyword =
2382 	TOKEN_STRING_INITIALIZER(struct cmd_config_rss, keyword, "config");
2383 static cmdline_parse_token_string_t cmd_config_rss_all =
2384 	TOKEN_STRING_INITIALIZER(struct cmd_config_rss, all, "all");
2385 static cmdline_parse_token_string_t cmd_config_rss_name =
2386 	TOKEN_STRING_INITIALIZER(struct cmd_config_rss, name, "rss");
2387 static cmdline_parse_token_string_t cmd_config_rss_value =
2388 	TOKEN_STRING_INITIALIZER(struct cmd_config_rss, value, NULL);
2389 
2390 static cmdline_parse_inst_t cmd_config_rss = {
2391 	.f = cmd_config_rss_parsed,
2392 	.data = NULL,
2393 	.help_str = "port config all rss "
2394 		"all|default|level-default|level-outer|level-inner|"
2395 		"ip|tcp|udp|sctp|tunnel|vlan|none|"
2396 		"ipv4|ipv4-frag|ipv4-tcp|ipv4-udp|ipv4-sctp|ipv4-other|"
2397 		"ipv6|ipv6-frag|ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other|ipv6-ex|ipv6-tcp-ex|ipv6-udp-ex|ipv6-flow-label|"
2398 		"l2-payload|port|vxlan|geneve|nvgre|gtpu|eth|s-vlan|c-vlan|"
2399 		"esp|ah|l2tpv3|pfcp|pppoe|ecpri|mpls|ipv4-chksum|l4-chksum|"
2400 		"l2tpv2|l3-pre96|l3-pre64|l3-pre56|l3-pre48|l3-pre40|l3-pre32|"
2401 		"l2-dst-only|l2-src-only|l4-dst-only|l4-src-only|l3-dst-only|l3-src-only|<rsstype_id>",
2402 	.tokens = {
2403 		(void *)&cmd_config_rss_port,
2404 		(void *)&cmd_config_rss_keyword,
2405 		(void *)&cmd_config_rss_all,
2406 		(void *)&cmd_config_rss_name,
2407 		(void *)&cmd_config_rss_value,
2408 		NULL,
2409 	},
2410 };
2411 
2412 /* *** configure rss hash key *** */
2413 struct cmd_config_rss_hash_key {
2414 	cmdline_fixed_string_t port;
2415 	cmdline_fixed_string_t config;
2416 	portid_t port_id;
2417 	cmdline_fixed_string_t rss_hash_key;
2418 	cmdline_fixed_string_t rss_type;
2419 	cmdline_fixed_string_t key;
2420 };
2421 
2422 static uint8_t
2423 hexa_digit_to_value(char hexa_digit)
2424 {
2425 	if ((hexa_digit >= '0') && (hexa_digit <= '9'))
2426 		return (uint8_t) (hexa_digit - '0');
2427 	if ((hexa_digit >= 'a') && (hexa_digit <= 'f'))
2428 		return (uint8_t) ((hexa_digit - 'a') + 10);
2429 	if ((hexa_digit >= 'A') && (hexa_digit <= 'F'))
2430 		return (uint8_t) ((hexa_digit - 'A') + 10);
2431 	/* Invalid hexa digit */
2432 	return 0xFF;
2433 }
2434 
2435 static uint8_t
2436 parse_and_check_key_hexa_digit(char *key, int idx)
2437 {
2438 	uint8_t hexa_v;
2439 
2440 	hexa_v = hexa_digit_to_value(key[idx]);
2441 	if (hexa_v == 0xFF)
2442 		fprintf(stderr,
2443 			"invalid key: character %c at position %d is not a valid hexa digit\n",
2444 			key[idx], idx);
2445 	return hexa_v;
2446 }
2447 
2448 static void
2449 cmd_config_rss_hash_key_parsed(void *parsed_result,
2450 			       __rte_unused struct cmdline *cl,
2451 			       __rte_unused void *data)
2452 {
2453 	struct cmd_config_rss_hash_key *res = parsed_result;
2454 	uint8_t hash_key[RSS_HASH_KEY_LENGTH];
2455 	uint8_t xdgt0;
2456 	uint8_t xdgt1;
2457 	int i;
2458 	struct rte_eth_dev_info dev_info;
2459 	uint8_t hash_key_size;
2460 	uint32_t key_len;
2461 	int ret;
2462 
2463 	ret = eth_dev_info_get_print_err(res->port_id, &dev_info);
2464 	if (ret != 0)
2465 		return;
2466 
2467 	if (dev_info.hash_key_size > 0 &&
2468 			dev_info.hash_key_size <= sizeof(hash_key))
2469 		hash_key_size = dev_info.hash_key_size;
2470 	else {
2471 		fprintf(stderr,
2472 			"dev_info did not provide a valid hash key size\n");
2473 		return;
2474 	}
2475 	/* Check the length of the RSS hash key */
2476 	key_len = strlen(res->key);
2477 	if (key_len != (hash_key_size * 2)) {
2478 		fprintf(stderr,
2479 			"key length: %d invalid - key must be a string of %d hexa-decimal numbers\n",
2480 			(int)key_len, hash_key_size * 2);
2481 		return;
2482 	}
2483 	/* Translate RSS hash key into binary representation */
2484 	for (i = 0; i < hash_key_size; i++) {
2485 		xdgt0 = parse_and_check_key_hexa_digit(res->key, (i * 2));
2486 		if (xdgt0 == 0xFF)
2487 			return;
2488 		xdgt1 = parse_and_check_key_hexa_digit(res->key, (i * 2) + 1);
2489 		if (xdgt1 == 0xFF)
2490 			return;
2491 		hash_key[i] = (uint8_t) ((xdgt0 * 16) + xdgt1);
2492 	}
2493 	port_rss_hash_key_update(res->port_id, res->rss_type, hash_key,
2494 			hash_key_size);
2495 }
2496 
2497 static cmdline_parse_token_string_t cmd_config_rss_hash_key_port =
2498 	TOKEN_STRING_INITIALIZER(struct cmd_config_rss_hash_key, port, "port");
2499 static cmdline_parse_token_string_t cmd_config_rss_hash_key_config =
2500 	TOKEN_STRING_INITIALIZER(struct cmd_config_rss_hash_key, config,
2501 				 "config");
2502 static cmdline_parse_token_num_t cmd_config_rss_hash_key_port_id =
2503 	TOKEN_NUM_INITIALIZER(struct cmd_config_rss_hash_key, port_id,
2504 				 RTE_UINT16);
2505 static cmdline_parse_token_string_t cmd_config_rss_hash_key_rss_hash_key =
2506 	TOKEN_STRING_INITIALIZER(struct cmd_config_rss_hash_key,
2507 				 rss_hash_key, "rss-hash-key");
2508 static cmdline_parse_token_string_t cmd_config_rss_hash_key_rss_type =
2509 	TOKEN_STRING_INITIALIZER(struct cmd_config_rss_hash_key, rss_type,
2510 				 "ipv4#ipv4-frag#ipv4-tcp#ipv4-udp#ipv4-sctp#"
2511 				 "ipv4-other#ipv6#ipv6-frag#ipv6-tcp#ipv6-udp#"
2512 				 "ipv6-sctp#ipv6-other#l2-payload#ipv6-ex#"
2513 				 "ipv6-tcp-ex#ipv6-udp-ex#ipv6-flow-label#"
2514 				 "l3-src-only#l3-dst-only#l4-src-only#l4-dst-only#"
2515 				 "l2-src-only#l2-dst-only#s-vlan#c-vlan#"
2516 				 "l2tpv3#esp#ah#pfcp#pppoe#gtpu#ecpri#mpls#l2tpv2");
2517 static cmdline_parse_token_string_t cmd_config_rss_hash_key_value =
2518 	TOKEN_STRING_INITIALIZER(struct cmd_config_rss_hash_key, key, NULL);
2519 
2520 static cmdline_parse_inst_t cmd_config_rss_hash_key = {
2521 	.f = cmd_config_rss_hash_key_parsed,
2522 	.data = NULL,
2523 	.help_str = "port config <port_id> rss-hash-key "
2524 		"ipv4|ipv4-frag|ipv4-tcp|ipv4-udp|ipv4-sctp|ipv4-other|"
2525 		"ipv6|ipv6-frag|ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other|"
2526 		"l2-payload|ipv6-ex|ipv6-tcp-ex|ipv6-udp-ex|ipv6-flow-label|"
2527 		"l3-src-only|l3-dst-only|l4-src-only|l4-dst-only|"
2528 		"l2-src-only|l2-dst-only|s-vlan|c-vlan|"
2529 		"l2tpv3|esp|ah|pfcp|pppoe|gtpu|ecpri|mpls|l2tpv2 "
2530 		"<string of hex digits (variable length, NIC dependent)>",
2531 	.tokens = {
2532 		(void *)&cmd_config_rss_hash_key_port,
2533 		(void *)&cmd_config_rss_hash_key_config,
2534 		(void *)&cmd_config_rss_hash_key_port_id,
2535 		(void *)&cmd_config_rss_hash_key_rss_hash_key,
2536 		(void *)&cmd_config_rss_hash_key_rss_type,
2537 		(void *)&cmd_config_rss_hash_key_value,
2538 		NULL,
2539 	},
2540 };
2541 
2542 /* *** configure rss hash algorithm *** */
2543 struct cmd_config_rss_hash_algo {
2544 	cmdline_fixed_string_t port;
2545 	cmdline_fixed_string_t config;
2546 	portid_t port_id;
2547 	cmdline_fixed_string_t rss_hash_algo;
2548 	cmdline_fixed_string_t algo;
2549 };
2550 
2551 static void
2552 cmd_config_rss_hash_algo_parsed(void *parsed_result,
2553 				__rte_unused struct cmdline *cl,
2554 				__rte_unused void *data)
2555 {
2556 	struct cmd_config_rss_hash_algo *res = parsed_result;
2557 	uint8_t rss_key[RSS_HASH_KEY_LENGTH];
2558 	struct rte_eth_rss_conf rss_conf;
2559 	uint32_t algorithm;
2560 	int ret;
2561 
2562 	rss_conf.rss_key_len = RSS_HASH_KEY_LENGTH;
2563 	rss_conf.rss_key = rss_key;
2564 	ret = rte_eth_dev_rss_hash_conf_get(res->port_id, &rss_conf);
2565 	if (ret != 0) {
2566 		fprintf(stderr, "failed to get port %u RSS configuration\n",
2567 			res->port_id);
2568 		return;
2569 	}
2570 
2571 	algorithm = (uint32_t)rss_conf.algorithm;
2572 	ret = rte_eth_find_rss_algo(res->algo, &algorithm);
2573 	if (ret != 0) {
2574 		fprintf(stderr, "port %u configured invalid RSS hash algorithm: %s\n",
2575 			res->port_id, res->algo);
2576 		return;
2577 	}
2578 
2579 	rss_conf.algorithm = algorithm;
2580 	ret = rte_eth_dev_rss_hash_update(res->port_id, &rss_conf);
2581 	if (ret != 0) {
2582 		fprintf(stderr, "failed to set port %u RSS hash algorithm\n",
2583 			res->port_id);
2584 		return;
2585 	}
2586 }
2587 
2588 static cmdline_parse_token_string_t cmd_config_rss_hash_algo_port =
2589 	TOKEN_STRING_INITIALIZER(struct cmd_config_rss_hash_algo, port, "port");
2590 static cmdline_parse_token_string_t cmd_config_rss_hash_algo_config =
2591 	TOKEN_STRING_INITIALIZER(struct cmd_config_rss_hash_algo, config,
2592 				 "config");
2593 static cmdline_parse_token_num_t cmd_config_rss_hash_algo_port_id =
2594 	TOKEN_NUM_INITIALIZER(struct cmd_config_rss_hash_algo, port_id,
2595 			      RTE_UINT16);
2596 static cmdline_parse_token_string_t cmd_config_rss_hash_algo_rss_hash_algo =
2597 	TOKEN_STRING_INITIALIZER(struct cmd_config_rss_hash_algo,
2598 				 rss_hash_algo, "rss-hash-algo");
2599 static cmdline_parse_token_string_t cmd_config_rss_hash_algo_algo =
2600 	TOKEN_STRING_INITIALIZER(struct cmd_config_rss_hash_algo, algo,
2601 				 "default#simple_xor#toeplitz#"
2602 				 "symmetric_toeplitz#symmetric_toeplitz_sort");
2603 
2604 static cmdline_parse_inst_t cmd_config_rss_hash_algo = {
2605 	.f = cmd_config_rss_hash_algo_parsed,
2606 	.data = NULL,
2607 	.help_str = "port config <port_id> rss-hash-algo "
2608 		"default|simple_xor|toeplitz|symmetric_toeplitz|symmetric_toeplitz_sort",
2609 	.tokens = {
2610 		(void *)&cmd_config_rss_hash_algo_port,
2611 		(void *)&cmd_config_rss_hash_algo_config,
2612 		(void *)&cmd_config_rss_hash_algo_port_id,
2613 		(void *)&cmd_config_rss_hash_algo_rss_hash_algo,
2614 		(void *)&cmd_config_rss_hash_algo_algo,
2615 		NULL,
2616 	},
2617 };
2618 
2619 /* *** cleanup txq mbufs *** */
2620 struct cmd_cleanup_txq_mbufs_result {
2621 	cmdline_fixed_string_t port;
2622 	cmdline_fixed_string_t keyword;
2623 	cmdline_fixed_string_t name;
2624 	uint16_t port_id;
2625 	uint16_t queue_id;
2626 	uint32_t free_cnt;
2627 };
2628 
2629 static void
2630 cmd_cleanup_txq_mbufs_parsed(void *parsed_result,
2631 			     __rte_unused struct cmdline *cl,
2632 			     __rte_unused void *data)
2633 {
2634 	struct cmd_cleanup_txq_mbufs_result *res = parsed_result;
2635 	uint16_t port_id = res->port_id;
2636 	uint16_t queue_id = res->queue_id;
2637 	uint32_t free_cnt = res->free_cnt;
2638 	struct rte_eth_txq_info qinfo;
2639 	int ret;
2640 
2641 	if (test_done == 0) {
2642 		fprintf(stderr, "Please stop forwarding first\n");
2643 		return;
2644 	}
2645 
2646 	if (rte_eth_tx_queue_info_get(port_id, queue_id, &qinfo)) {
2647 		fprintf(stderr, "Failed to get port %u Tx queue %u info\n",
2648 			port_id, queue_id);
2649 		return;
2650 	}
2651 
2652 	if (qinfo.queue_state != RTE_ETH_QUEUE_STATE_STARTED) {
2653 		fprintf(stderr, "Tx queue %u not started\n", queue_id);
2654 		return;
2655 	}
2656 
2657 	ret = rte_eth_tx_done_cleanup(port_id, queue_id, free_cnt);
2658 	if (ret < 0) {
2659 		fprintf(stderr,
2660 			"Failed to cleanup mbuf for port %u Tx queue %u error desc: %s(%d)\n",
2661 			port_id, queue_id, strerror(-ret), ret);
2662 		return;
2663 	}
2664 
2665 	printf("Cleanup port %u Tx queue %u mbuf nums: %u\n",
2666 	       port_id, queue_id, ret);
2667 }
2668 
2669 static cmdline_parse_token_string_t cmd_cleanup_txq_mbufs_port =
2670 	TOKEN_STRING_INITIALIZER(struct cmd_cleanup_txq_mbufs_result, port,
2671 				 "port");
2672 static cmdline_parse_token_string_t cmd_cleanup_txq_mbufs_cleanup =
2673 	TOKEN_STRING_INITIALIZER(struct cmd_cleanup_txq_mbufs_result, keyword,
2674 				 "cleanup");
2675 static cmdline_parse_token_num_t cmd_cleanup_txq_mbufs_port_id =
2676 	TOKEN_NUM_INITIALIZER(struct cmd_cleanup_txq_mbufs_result, port_id,
2677 			      RTE_UINT16);
2678 static cmdline_parse_token_string_t cmd_cleanup_txq_mbufs_txq =
2679 	TOKEN_STRING_INITIALIZER(struct cmd_cleanup_txq_mbufs_result, name,
2680 				 "txq");
2681 static cmdline_parse_token_num_t cmd_cleanup_txq_mbufs_queue_id =
2682 	TOKEN_NUM_INITIALIZER(struct cmd_cleanup_txq_mbufs_result, queue_id,
2683 			      RTE_UINT16);
2684 static cmdline_parse_token_num_t cmd_cleanup_txq_mbufs_free_cnt =
2685 	TOKEN_NUM_INITIALIZER(struct cmd_cleanup_txq_mbufs_result, free_cnt,
2686 			      RTE_UINT32);
2687 
2688 static cmdline_parse_inst_t cmd_cleanup_txq_mbufs = {
2689 	.f = cmd_cleanup_txq_mbufs_parsed,
2690 	.data = NULL,
2691 	.help_str = "port cleanup <port_id> txq <queue_id> <free_cnt>",
2692 	.tokens = {
2693 		(void *)&cmd_cleanup_txq_mbufs_port,
2694 		(void *)&cmd_cleanup_txq_mbufs_cleanup,
2695 		(void *)&cmd_cleanup_txq_mbufs_port_id,
2696 		(void *)&cmd_cleanup_txq_mbufs_txq,
2697 		(void *)&cmd_cleanup_txq_mbufs_queue_id,
2698 		(void *)&cmd_cleanup_txq_mbufs_free_cnt,
2699 		NULL,
2700 	},
2701 };
2702 
2703 /* *** configure port rxq/txq ring size *** */
2704 struct cmd_config_rxtx_ring_size {
2705 	cmdline_fixed_string_t port;
2706 	cmdline_fixed_string_t config;
2707 	portid_t portid;
2708 	cmdline_fixed_string_t rxtxq;
2709 	uint16_t qid;
2710 	cmdline_fixed_string_t rsize;
2711 	uint16_t size;
2712 };
2713 
2714 static void
2715 cmd_config_rxtx_ring_size_parsed(void *parsed_result,
2716 				 __rte_unused struct cmdline *cl,
2717 				 __rte_unused void *data)
2718 {
2719 	struct cmd_config_rxtx_ring_size *res = parsed_result;
2720 	struct rte_port *port;
2721 	uint8_t isrx;
2722 
2723 	if (port_id_is_invalid(res->portid, ENABLED_WARN))
2724 		return;
2725 
2726 	if (res->portid == (portid_t)RTE_PORT_ALL) {
2727 		fprintf(stderr, "Invalid port id\n");
2728 		return;
2729 	}
2730 
2731 	port = &ports[res->portid];
2732 
2733 	if (!strcmp(res->rxtxq, "rxq"))
2734 		isrx = 1;
2735 	else if (!strcmp(res->rxtxq, "txq"))
2736 		isrx = 0;
2737 	else {
2738 		fprintf(stderr, "Unknown parameter\n");
2739 		return;
2740 	}
2741 
2742 	if (isrx && rx_queue_id_is_invalid(res->qid))
2743 		return;
2744 	else if (!isrx && tx_queue_id_is_invalid(res->qid))
2745 		return;
2746 
2747 	if (isrx && res->size != 0 && res->size <= rx_free_thresh) {
2748 		fprintf(stderr,
2749 			"Invalid rx ring_size, must > rx_free_thresh: %d\n",
2750 			rx_free_thresh);
2751 		return;
2752 	}
2753 
2754 	if (isrx)
2755 		port->nb_rx_desc[res->qid] = res->size;
2756 	else
2757 		port->nb_tx_desc[res->qid] = res->size;
2758 
2759 	cmd_reconfig_device_queue(res->portid, 0, 1);
2760 }
2761 
2762 static cmdline_parse_token_string_t cmd_config_rxtx_ring_size_port =
2763 	TOKEN_STRING_INITIALIZER(struct cmd_config_rxtx_ring_size,
2764 				 port, "port");
2765 static cmdline_parse_token_string_t cmd_config_rxtx_ring_size_config =
2766 	TOKEN_STRING_INITIALIZER(struct cmd_config_rxtx_ring_size,
2767 				 config, "config");
2768 static cmdline_parse_token_num_t cmd_config_rxtx_ring_size_portid =
2769 	TOKEN_NUM_INITIALIZER(struct cmd_config_rxtx_ring_size,
2770 				 portid, RTE_UINT16);
2771 static cmdline_parse_token_string_t cmd_config_rxtx_ring_size_rxtxq =
2772 	TOKEN_STRING_INITIALIZER(struct cmd_config_rxtx_ring_size,
2773 				 rxtxq, "rxq#txq");
2774 static cmdline_parse_token_num_t cmd_config_rxtx_ring_size_qid =
2775 	TOKEN_NUM_INITIALIZER(struct cmd_config_rxtx_ring_size,
2776 			      qid, RTE_UINT16);
2777 static cmdline_parse_token_string_t cmd_config_rxtx_ring_size_rsize =
2778 	TOKEN_STRING_INITIALIZER(struct cmd_config_rxtx_ring_size,
2779 				 rsize, "ring_size");
2780 static cmdline_parse_token_num_t cmd_config_rxtx_ring_size_size =
2781 	TOKEN_NUM_INITIALIZER(struct cmd_config_rxtx_ring_size,
2782 			      size, RTE_UINT16);
2783 
2784 static cmdline_parse_inst_t cmd_config_rxtx_ring_size = {
2785 	.f = cmd_config_rxtx_ring_size_parsed,
2786 	.data = NULL,
2787 	.help_str = "port config <port_id> rxq|txq <queue_id> ring_size <value>",
2788 	.tokens = {
2789 		(void *)&cmd_config_rxtx_ring_size_port,
2790 		(void *)&cmd_config_rxtx_ring_size_config,
2791 		(void *)&cmd_config_rxtx_ring_size_portid,
2792 		(void *)&cmd_config_rxtx_ring_size_rxtxq,
2793 		(void *)&cmd_config_rxtx_ring_size_qid,
2794 		(void *)&cmd_config_rxtx_ring_size_rsize,
2795 		(void *)&cmd_config_rxtx_ring_size_size,
2796 		NULL,
2797 	},
2798 };
2799 
2800 /* *** configure port rxq/txq start/stop *** */
2801 struct cmd_config_rxtx_queue {
2802 	cmdline_fixed_string_t port;
2803 	portid_t portid;
2804 	cmdline_fixed_string_t rxtxq;
2805 	uint16_t qid;
2806 	cmdline_fixed_string_t opname;
2807 };
2808 
2809 static void
2810 cmd_config_rxtx_queue_parsed(void *parsed_result,
2811 			__rte_unused struct cmdline *cl,
2812 			__rte_unused void *data)
2813 {
2814 	struct cmd_config_rxtx_queue *res = parsed_result;
2815 	struct rte_port *port;
2816 	uint8_t isrx;
2817 	uint8_t isstart;
2818 	uint8_t *state;
2819 	int ret = 0;
2820 
2821 	if (test_done == 0) {
2822 		fprintf(stderr, "Please stop forwarding first\n");
2823 		return;
2824 	}
2825 
2826 	if (port_id_is_invalid(res->portid, ENABLED_WARN))
2827 		return;
2828 
2829 	if (port_is_started(res->portid) != 1) {
2830 		fprintf(stderr, "Please start port %u first\n", res->portid);
2831 		return;
2832 	}
2833 
2834 	if (!strcmp(res->rxtxq, "rxq"))
2835 		isrx = 1;
2836 	else if (!strcmp(res->rxtxq, "txq"))
2837 		isrx = 0;
2838 	else {
2839 		fprintf(stderr, "Unknown parameter\n");
2840 		return;
2841 	}
2842 
2843 	if (isrx && rx_queue_id_is_invalid(res->qid))
2844 		return;
2845 	else if (!isrx && tx_queue_id_is_invalid(res->qid))
2846 		return;
2847 
2848 	if (!strcmp(res->opname, "start"))
2849 		isstart = 1;
2850 	else if (!strcmp(res->opname, "stop"))
2851 		isstart = 0;
2852 	else {
2853 		fprintf(stderr, "Unknown parameter\n");
2854 		return;
2855 	}
2856 
2857 	if (isstart && isrx)
2858 		ret = rte_eth_dev_rx_queue_start(res->portid, res->qid);
2859 	else if (!isstart && isrx)
2860 		ret = rte_eth_dev_rx_queue_stop(res->portid, res->qid);
2861 	else if (isstart && !isrx)
2862 		ret = rte_eth_dev_tx_queue_start(res->portid, res->qid);
2863 	else
2864 		ret = rte_eth_dev_tx_queue_stop(res->portid, res->qid);
2865 
2866 	if (ret == -ENOTSUP) {
2867 		fprintf(stderr, "Function not supported in PMD\n");
2868 		return;
2869 	}
2870 
2871 	port = &ports[res->portid];
2872 	state = isrx ? &port->rxq[res->qid].state : &port->txq[res->qid].state;
2873 	*state = isstart ? RTE_ETH_QUEUE_STATE_STARTED :
2874 			   RTE_ETH_QUEUE_STATE_STOPPED;
2875 }
2876 
2877 static cmdline_parse_token_string_t cmd_config_rxtx_queue_port =
2878 	TOKEN_STRING_INITIALIZER(struct cmd_config_rxtx_queue, port, "port");
2879 static cmdline_parse_token_num_t cmd_config_rxtx_queue_portid =
2880 	TOKEN_NUM_INITIALIZER(struct cmd_config_rxtx_queue, portid, RTE_UINT16);
2881 static cmdline_parse_token_string_t cmd_config_rxtx_queue_rxtxq =
2882 	TOKEN_STRING_INITIALIZER(struct cmd_config_rxtx_queue, rxtxq, "rxq#txq");
2883 static cmdline_parse_token_num_t cmd_config_rxtx_queue_qid =
2884 	TOKEN_NUM_INITIALIZER(struct cmd_config_rxtx_queue, qid, RTE_UINT16);
2885 static cmdline_parse_token_string_t cmd_config_rxtx_queue_opname =
2886 	TOKEN_STRING_INITIALIZER(struct cmd_config_rxtx_queue, opname,
2887 						"start#stop");
2888 
2889 static cmdline_parse_inst_t cmd_config_rxtx_queue = {
2890 	.f = cmd_config_rxtx_queue_parsed,
2891 	.data = NULL,
2892 	.help_str = "port <port_id> rxq|txq <queue_id> start|stop",
2893 	.tokens = {
2894 		(void *)&cmd_config_rxtx_queue_port,
2895 		(void *)&cmd_config_rxtx_queue_portid,
2896 		(void *)&cmd_config_rxtx_queue_rxtxq,
2897 		(void *)&cmd_config_rxtx_queue_qid,
2898 		(void *)&cmd_config_rxtx_queue_opname,
2899 		NULL,
2900 	},
2901 };
2902 
2903 /* *** configure port rxq/txq deferred start on/off *** */
2904 struct cmd_config_deferred_start_rxtx_queue {
2905 	cmdline_fixed_string_t port;
2906 	portid_t port_id;
2907 	cmdline_fixed_string_t rxtxq;
2908 	uint16_t qid;
2909 	cmdline_fixed_string_t opname;
2910 	cmdline_fixed_string_t state;
2911 };
2912 
2913 static void
2914 cmd_config_deferred_start_rxtx_queue_parsed(void *parsed_result,
2915 			__rte_unused struct cmdline *cl,
2916 			__rte_unused void *data)
2917 {
2918 	struct cmd_config_deferred_start_rxtx_queue *res = parsed_result;
2919 	struct rte_port *port;
2920 	uint8_t isrx;
2921 	uint8_t ison;
2922 	uint8_t needreconfig = 0;
2923 
2924 	if (port_id_is_invalid(res->port_id, ENABLED_WARN))
2925 		return;
2926 
2927 	if (port_is_started(res->port_id) != 0) {
2928 		fprintf(stderr, "Please stop port %u first\n", res->port_id);
2929 		return;
2930 	}
2931 
2932 	port = &ports[res->port_id];
2933 
2934 	isrx = !strcmp(res->rxtxq, "rxq");
2935 
2936 	if (isrx && rx_queue_id_is_invalid(res->qid))
2937 		return;
2938 	else if (!isrx && tx_queue_id_is_invalid(res->qid))
2939 		return;
2940 
2941 	ison = !strcmp(res->state, "on");
2942 
2943 	if (isrx && port->rxq[res->qid].conf.rx_deferred_start != ison) {
2944 		port->rxq[res->qid].conf.rx_deferred_start = ison;
2945 		needreconfig = 1;
2946 	} else if (!isrx && port->txq[res->qid].conf.tx_deferred_start != ison) {
2947 		port->txq[res->qid].conf.tx_deferred_start = ison;
2948 		needreconfig = 1;
2949 	}
2950 
2951 	if (needreconfig)
2952 		cmd_reconfig_device_queue(res->port_id, 0, 1);
2953 }
2954 
2955 static cmdline_parse_token_string_t cmd_config_deferred_start_rxtx_queue_port =
2956 	TOKEN_STRING_INITIALIZER(struct cmd_config_deferred_start_rxtx_queue,
2957 						port, "port");
2958 static cmdline_parse_token_num_t cmd_config_deferred_start_rxtx_queue_port_id =
2959 	TOKEN_NUM_INITIALIZER(struct cmd_config_deferred_start_rxtx_queue,
2960 						port_id, RTE_UINT16);
2961 static cmdline_parse_token_string_t cmd_config_deferred_start_rxtx_queue_rxtxq =
2962 	TOKEN_STRING_INITIALIZER(struct cmd_config_deferred_start_rxtx_queue,
2963 						rxtxq, "rxq#txq");
2964 static cmdline_parse_token_num_t cmd_config_deferred_start_rxtx_queue_qid =
2965 	TOKEN_NUM_INITIALIZER(struct cmd_config_deferred_start_rxtx_queue,
2966 						qid, RTE_UINT16);
2967 static cmdline_parse_token_string_t cmd_config_deferred_start_rxtx_queue_opname =
2968 	TOKEN_STRING_INITIALIZER(struct cmd_config_deferred_start_rxtx_queue,
2969 						opname, "deferred_start");
2970 static cmdline_parse_token_string_t cmd_config_deferred_start_rxtx_queue_state =
2971 	TOKEN_STRING_INITIALIZER(struct cmd_config_deferred_start_rxtx_queue,
2972 						state, "on#off");
2973 
2974 static cmdline_parse_inst_t cmd_config_deferred_start_rxtx_queue = {
2975 	.f = cmd_config_deferred_start_rxtx_queue_parsed,
2976 	.data = NULL,
2977 	.help_str = "port <port_id> rxq|txq <queue_id> deferred_start on|off",
2978 	.tokens = {
2979 		(void *)&cmd_config_deferred_start_rxtx_queue_port,
2980 		(void *)&cmd_config_deferred_start_rxtx_queue_port_id,
2981 		(void *)&cmd_config_deferred_start_rxtx_queue_rxtxq,
2982 		(void *)&cmd_config_deferred_start_rxtx_queue_qid,
2983 		(void *)&cmd_config_deferred_start_rxtx_queue_opname,
2984 		(void *)&cmd_config_deferred_start_rxtx_queue_state,
2985 		NULL,
2986 	},
2987 };
2988 
2989 /* *** configure port rxq/txq setup *** */
2990 struct cmd_setup_rxtx_queue {
2991 	cmdline_fixed_string_t port;
2992 	portid_t portid;
2993 	cmdline_fixed_string_t rxtxq;
2994 	uint16_t qid;
2995 	cmdline_fixed_string_t setup;
2996 };
2997 
2998 /* Common CLI fields for queue setup */
2999 static cmdline_parse_token_string_t cmd_setup_rxtx_queue_port =
3000 	TOKEN_STRING_INITIALIZER(struct cmd_setup_rxtx_queue, port, "port");
3001 static cmdline_parse_token_num_t cmd_setup_rxtx_queue_portid =
3002 	TOKEN_NUM_INITIALIZER(struct cmd_setup_rxtx_queue, portid, RTE_UINT16);
3003 static cmdline_parse_token_string_t cmd_setup_rxtx_queue_rxtxq =
3004 	TOKEN_STRING_INITIALIZER(struct cmd_setup_rxtx_queue, rxtxq, "rxq#txq");
3005 static cmdline_parse_token_num_t cmd_setup_rxtx_queue_qid =
3006 	TOKEN_NUM_INITIALIZER(struct cmd_setup_rxtx_queue, qid, RTE_UINT16);
3007 static cmdline_parse_token_string_t cmd_setup_rxtx_queue_setup =
3008 	TOKEN_STRING_INITIALIZER(struct cmd_setup_rxtx_queue, setup, "setup");
3009 
3010 static void
3011 cmd_setup_rxtx_queue_parsed(
3012 	void *parsed_result,
3013 	__rte_unused struct cmdline *cl,
3014 	__rte_unused void *data)
3015 {
3016 	struct cmd_setup_rxtx_queue *res = parsed_result;
3017 	struct rte_port *port;
3018 	struct rte_mempool *mp;
3019 	unsigned int socket_id;
3020 	uint8_t isrx = 0;
3021 	int ret;
3022 
3023 	if (port_id_is_invalid(res->portid, ENABLED_WARN))
3024 		return;
3025 
3026 	if (res->portid == (portid_t)RTE_PORT_ALL) {
3027 		fprintf(stderr, "Invalid port id\n");
3028 		return;
3029 	}
3030 
3031 	if (!strcmp(res->rxtxq, "rxq"))
3032 		isrx = 1;
3033 	else if (!strcmp(res->rxtxq, "txq"))
3034 		isrx = 0;
3035 	else {
3036 		fprintf(stderr, "Unknown parameter\n");
3037 		return;
3038 	}
3039 
3040 	if (isrx && rx_queue_id_is_invalid(res->qid)) {
3041 		fprintf(stderr, "Invalid rx queue\n");
3042 		return;
3043 	} else if (!isrx && tx_queue_id_is_invalid(res->qid)) {
3044 		fprintf(stderr, "Invalid tx queue\n");
3045 		return;
3046 	}
3047 
3048 	port = &ports[res->portid];
3049 	if (isrx) {
3050 		socket_id = rxring_numa[res->portid];
3051 		if (!numa_support || socket_id == NUMA_NO_CONFIG)
3052 			socket_id = port->socket_id;
3053 
3054 		mp = mbuf_pool_find(socket_id, 0);
3055 		if (mp == NULL) {
3056 			fprintf(stderr,
3057 				"Failed to setup RX queue: No mempool allocation on the socket %d\n",
3058 				rxring_numa[res->portid]);
3059 			return;
3060 		}
3061 		ret = rx_queue_setup(res->portid,
3062 				     res->qid,
3063 				     port->nb_rx_desc[res->qid],
3064 				     socket_id,
3065 				     &port->rxq[res->qid].conf,
3066 				     mp);
3067 		if (ret)
3068 			fprintf(stderr, "Failed to setup RX queue\n");
3069 	} else {
3070 		socket_id = txring_numa[res->portid];
3071 		if (!numa_support || socket_id == NUMA_NO_CONFIG)
3072 			socket_id = port->socket_id;
3073 
3074 		if (port->nb_tx_desc[res->qid] < tx_pkt_nb_segs) {
3075 			fprintf(stderr,
3076 				"Failed to setup TX queue: not enough descriptors\n");
3077 			return;
3078 		}
3079 		ret = rte_eth_tx_queue_setup(res->portid,
3080 					     res->qid,
3081 					     port->nb_tx_desc[res->qid],
3082 					     socket_id,
3083 					     &port->txq[res->qid].conf);
3084 		if (ret)
3085 			fprintf(stderr, "Failed to setup TX queue\n");
3086 	}
3087 }
3088 
3089 static cmdline_parse_inst_t cmd_setup_rxtx_queue = {
3090 	.f = cmd_setup_rxtx_queue_parsed,
3091 	.data = NULL,
3092 	.help_str = "port <port_id> rxq|txq <queue_idx> setup",
3093 	.tokens = {
3094 		(void *)&cmd_setup_rxtx_queue_port,
3095 		(void *)&cmd_setup_rxtx_queue_portid,
3096 		(void *)&cmd_setup_rxtx_queue_rxtxq,
3097 		(void *)&cmd_setup_rxtx_queue_qid,
3098 		(void *)&cmd_setup_rxtx_queue_setup,
3099 		NULL,
3100 	},
3101 };
3102 
3103 
3104 /* *** Configure RSS RETA *** */
3105 struct cmd_config_rss_reta {
3106 	cmdline_fixed_string_t port;
3107 	cmdline_fixed_string_t keyword;
3108 	portid_t port_id;
3109 	cmdline_fixed_string_t name;
3110 	cmdline_fixed_string_t list_name;
3111 	cmdline_fixed_string_t list_of_items;
3112 };
3113 
3114 static int
3115 parse_reta_config(const char *str,
3116 		  struct rte_eth_rss_reta_entry64 *reta_conf,
3117 		  uint16_t nb_entries)
3118 {
3119 	int i;
3120 	unsigned size;
3121 	uint16_t hash_index, idx, shift;
3122 	uint16_t nb_queue;
3123 	char s[256];
3124 	const char *p, *p0 = str;
3125 	char *end;
3126 	enum fieldnames {
3127 		FLD_HASH_INDEX = 0,
3128 		FLD_QUEUE,
3129 		_NUM_FLD
3130 	};
3131 	unsigned long int_fld[_NUM_FLD];
3132 	char *str_fld[_NUM_FLD];
3133 
3134 	while ((p = strchr(p0,'(')) != NULL) {
3135 		++p;
3136 		if((p0 = strchr(p,')')) == NULL)
3137 			return -1;
3138 
3139 		size = p0 - p;
3140 		if(size >= sizeof(s))
3141 			return -1;
3142 
3143 		snprintf(s, sizeof(s), "%.*s", size, p);
3144 		if (rte_strsplit(s, sizeof(s), str_fld, _NUM_FLD, ',') != _NUM_FLD)
3145 			return -1;
3146 		for (i = 0; i < _NUM_FLD; i++) {
3147 			errno = 0;
3148 			int_fld[i] = strtoul(str_fld[i], &end, 0);
3149 			if (errno != 0 || end == str_fld[i] ||
3150 					int_fld[i] > 65535)
3151 				return -1;
3152 		}
3153 
3154 		hash_index = (uint16_t)int_fld[FLD_HASH_INDEX];
3155 		nb_queue = (uint16_t)int_fld[FLD_QUEUE];
3156 
3157 		if (hash_index >= nb_entries) {
3158 			fprintf(stderr, "Invalid RETA hash index=%d\n",
3159 				hash_index);
3160 			return -1;
3161 		}
3162 
3163 		idx = hash_index / RTE_ETH_RETA_GROUP_SIZE;
3164 		shift = hash_index % RTE_ETH_RETA_GROUP_SIZE;
3165 		reta_conf[idx].mask |= (1ULL << shift);
3166 		reta_conf[idx].reta[shift] = nb_queue;
3167 	}
3168 
3169 	return 0;
3170 }
3171 
3172 static void
3173 cmd_set_rss_reta_parsed(void *parsed_result,
3174 			__rte_unused struct cmdline *cl,
3175 			__rte_unused void *data)
3176 {
3177 	int ret;
3178 	struct rte_eth_dev_info dev_info;
3179 	struct rte_eth_rss_reta_entry64 reta_conf[8];
3180 	struct cmd_config_rss_reta *res = parsed_result;
3181 
3182 	ret = eth_dev_info_get_print_err(res->port_id, &dev_info);
3183 	if (ret != 0)
3184 		return;
3185 
3186 	if (dev_info.reta_size == 0) {
3187 		fprintf(stderr,
3188 			"Redirection table size is 0 which is invalid for RSS\n");
3189 		return;
3190 	} else
3191 		printf("The reta size of port %d is %u\n",
3192 			res->port_id, dev_info.reta_size);
3193 	if (dev_info.reta_size > RTE_ETH_RSS_RETA_SIZE_512) {
3194 		fprintf(stderr,
3195 			"Currently do not support more than %u entries of redirection table\n",
3196 			RTE_ETH_RSS_RETA_SIZE_512);
3197 		return;
3198 	}
3199 
3200 	memset(reta_conf, 0, sizeof(reta_conf));
3201 	if (!strcmp(res->list_name, "reta")) {
3202 		if (parse_reta_config(res->list_of_items, reta_conf,
3203 						dev_info.reta_size)) {
3204 			fprintf(stderr,
3205 				"Invalid RSS Redirection Table config entered\n");
3206 			return;
3207 		}
3208 		ret = rte_eth_dev_rss_reta_update(res->port_id,
3209 				reta_conf, dev_info.reta_size);
3210 		if (ret != 0)
3211 			fprintf(stderr,
3212 				"Bad redirection table parameter, return code = %d\n",
3213 				ret);
3214 	}
3215 }
3216 
3217 static cmdline_parse_token_string_t cmd_config_rss_reta_port =
3218 	TOKEN_STRING_INITIALIZER(struct cmd_config_rss_reta, port, "port");
3219 static cmdline_parse_token_string_t cmd_config_rss_reta_keyword =
3220 	TOKEN_STRING_INITIALIZER(struct cmd_config_rss_reta, keyword, "config");
3221 static cmdline_parse_token_num_t cmd_config_rss_reta_port_id =
3222 	TOKEN_NUM_INITIALIZER(struct cmd_config_rss_reta, port_id, RTE_UINT16);
3223 static cmdline_parse_token_string_t cmd_config_rss_reta_name =
3224 	TOKEN_STRING_INITIALIZER(struct cmd_config_rss_reta, name, "rss");
3225 static cmdline_parse_token_string_t cmd_config_rss_reta_list_name =
3226 	TOKEN_STRING_INITIALIZER(struct cmd_config_rss_reta, list_name, "reta");
3227 static cmdline_parse_token_string_t cmd_config_rss_reta_list_of_items =
3228         TOKEN_STRING_INITIALIZER(struct cmd_config_rss_reta, list_of_items,
3229                                  NULL);
3230 static cmdline_parse_inst_t cmd_config_rss_reta = {
3231 	.f = cmd_set_rss_reta_parsed,
3232 	.data = NULL,
3233 	.help_str = "port config <port_id> rss reta <hash,queue[,hash,queue]*>",
3234 	.tokens = {
3235 		(void *)&cmd_config_rss_reta_port,
3236 		(void *)&cmd_config_rss_reta_keyword,
3237 		(void *)&cmd_config_rss_reta_port_id,
3238 		(void *)&cmd_config_rss_reta_name,
3239 		(void *)&cmd_config_rss_reta_list_name,
3240 		(void *)&cmd_config_rss_reta_list_of_items,
3241 		NULL,
3242 	},
3243 };
3244 
3245 /* *** SHOW PORT RETA INFO *** */
3246 struct cmd_showport_reta {
3247 	cmdline_fixed_string_t show;
3248 	cmdline_fixed_string_t port;
3249 	portid_t port_id;
3250 	cmdline_fixed_string_t rss;
3251 	cmdline_fixed_string_t reta;
3252 	uint16_t size;
3253 	cmdline_fixed_string_t list_of_items;
3254 };
3255 
3256 static int
3257 showport_parse_reta_config(struct rte_eth_rss_reta_entry64 *conf,
3258 			   uint16_t nb_entries,
3259 			   char *str)
3260 {
3261 	uint32_t size;
3262 	const char *p, *p0 = str;
3263 	char s[256];
3264 	char *end;
3265 	char *str_fld[8];
3266 	uint16_t i;
3267 	uint16_t num = (nb_entries + RTE_ETH_RETA_GROUP_SIZE - 1) /
3268 			RTE_ETH_RETA_GROUP_SIZE;
3269 	int ret;
3270 
3271 	p = strchr(p0, '(');
3272 	if (p == NULL)
3273 		return -1;
3274 	p++;
3275 	p0 = strchr(p, ')');
3276 	if (p0 == NULL)
3277 		return -1;
3278 	size = p0 - p;
3279 	if (size >= sizeof(s)) {
3280 		fprintf(stderr,
3281 			"The string size exceeds the internal buffer size\n");
3282 		return -1;
3283 	}
3284 	snprintf(s, sizeof(s), "%.*s", size, p);
3285 	ret = rte_strsplit(s, sizeof(s), str_fld, num, ',');
3286 	if (ret <= 0 || ret != num) {
3287 		fprintf(stderr,
3288 			"The bits of masks do not match the number of reta entries: %u\n",
3289 			num);
3290 		return -1;
3291 	}
3292 	for (i = 0; i < ret; i++)
3293 		conf[i].mask = (uint64_t)strtoull(str_fld[i], &end, 0);
3294 
3295 	return 0;
3296 }
3297 
3298 static void
3299 cmd_showport_reta_parsed(void *parsed_result,
3300 			 __rte_unused struct cmdline *cl,
3301 			 __rte_unused void *data)
3302 {
3303 	struct cmd_showport_reta *res = parsed_result;
3304 	struct rte_eth_rss_reta_entry64 reta_conf[8];
3305 	struct rte_eth_dev_info dev_info;
3306 	uint16_t max_reta_size;
3307 	int ret;
3308 
3309 	ret = eth_dev_info_get_print_err(res->port_id, &dev_info);
3310 	if (ret != 0)
3311 		return;
3312 
3313 	max_reta_size = RTE_MIN(dev_info.reta_size, RTE_ETH_RSS_RETA_SIZE_512);
3314 	if (res->size == 0 || res->size > max_reta_size) {
3315 		fprintf(stderr, "Invalid redirection table size: %u (1-%u)\n",
3316 			res->size, max_reta_size);
3317 		return;
3318 	}
3319 
3320 	memset(reta_conf, 0, sizeof(reta_conf));
3321 	if (showport_parse_reta_config(reta_conf, res->size,
3322 				res->list_of_items) < 0) {
3323 		fprintf(stderr, "Invalid string: %s for reta masks\n",
3324 			res->list_of_items);
3325 		return;
3326 	}
3327 	port_rss_reta_info(res->port_id, reta_conf, res->size);
3328 }
3329 
3330 static cmdline_parse_token_string_t cmd_showport_reta_show =
3331 	TOKEN_STRING_INITIALIZER(struct  cmd_showport_reta, show, "show");
3332 static cmdline_parse_token_string_t cmd_showport_reta_port =
3333 	TOKEN_STRING_INITIALIZER(struct  cmd_showport_reta, port, "port");
3334 static cmdline_parse_token_num_t cmd_showport_reta_port_id =
3335 	TOKEN_NUM_INITIALIZER(struct cmd_showport_reta, port_id, RTE_UINT16);
3336 static cmdline_parse_token_string_t cmd_showport_reta_rss =
3337 	TOKEN_STRING_INITIALIZER(struct cmd_showport_reta, rss, "rss");
3338 static cmdline_parse_token_string_t cmd_showport_reta_reta =
3339 	TOKEN_STRING_INITIALIZER(struct cmd_showport_reta, reta, "reta");
3340 static cmdline_parse_token_num_t cmd_showport_reta_size =
3341 	TOKEN_NUM_INITIALIZER(struct cmd_showport_reta, size, RTE_UINT16);
3342 static cmdline_parse_token_string_t cmd_showport_reta_list_of_items =
3343 	TOKEN_STRING_INITIALIZER(struct cmd_showport_reta,
3344 					list_of_items, NULL);
3345 
3346 static cmdline_parse_inst_t cmd_showport_reta = {
3347 	.f = cmd_showport_reta_parsed,
3348 	.data = NULL,
3349 	.help_str = "show port <port_id> rss reta <size> <mask0[,mask1]*>",
3350 	.tokens = {
3351 		(void *)&cmd_showport_reta_show,
3352 		(void *)&cmd_showport_reta_port,
3353 		(void *)&cmd_showport_reta_port_id,
3354 		(void *)&cmd_showport_reta_rss,
3355 		(void *)&cmd_showport_reta_reta,
3356 		(void *)&cmd_showport_reta_size,
3357 		(void *)&cmd_showport_reta_list_of_items,
3358 		NULL,
3359 	},
3360 };
3361 
3362 /* *** Show RSS hash configuration *** */
3363 struct cmd_showport_rss_hash {
3364 	cmdline_fixed_string_t show;
3365 	cmdline_fixed_string_t port;
3366 	portid_t port_id;
3367 	cmdline_fixed_string_t rss_hash;
3368 	cmdline_fixed_string_t rss_type;
3369 	cmdline_fixed_string_t key; /* optional argument */
3370 	cmdline_fixed_string_t algorithm; /* optional argument */
3371 };
3372 
3373 static void cmd_showport_rss_hash_parsed(void *parsed_result,
3374 				__rte_unused struct cmdline *cl,
3375 				__rte_unused void *data)
3376 {
3377 	struct cmd_showport_rss_hash *res = parsed_result;
3378 
3379 	port_rss_hash_conf_show(res->port_id,
3380 		!strcmp(res->key, "key"), !strcmp(res->algorithm, "algorithm"));
3381 }
3382 
3383 static cmdline_parse_token_string_t cmd_showport_rss_hash_show =
3384 	TOKEN_STRING_INITIALIZER(struct cmd_showport_rss_hash, show, "show");
3385 static cmdline_parse_token_string_t cmd_showport_rss_hash_port =
3386 	TOKEN_STRING_INITIALIZER(struct cmd_showport_rss_hash, port, "port");
3387 static cmdline_parse_token_num_t cmd_showport_rss_hash_port_id =
3388 	TOKEN_NUM_INITIALIZER(struct cmd_showport_rss_hash, port_id,
3389 				 RTE_UINT16);
3390 static cmdline_parse_token_string_t cmd_showport_rss_hash_rss_hash =
3391 	TOKEN_STRING_INITIALIZER(struct cmd_showport_rss_hash, rss_hash,
3392 				 "rss-hash");
3393 static cmdline_parse_token_string_t cmd_showport_rss_hash_rss_key =
3394 	TOKEN_STRING_INITIALIZER(struct cmd_showport_rss_hash, key, "key");
3395 static cmdline_parse_token_string_t cmd_showport_rss_hash_rss_algo =
3396 	TOKEN_STRING_INITIALIZER(struct cmd_showport_rss_hash, algorithm, "algorithm");
3397 
3398 static cmdline_parse_inst_t cmd_showport_rss_hash = {
3399 	.f = cmd_showport_rss_hash_parsed,
3400 	.data = NULL,
3401 	.help_str = "show port <port_id> rss-hash",
3402 	.tokens = {
3403 		(void *)&cmd_showport_rss_hash_show,
3404 		(void *)&cmd_showport_rss_hash_port,
3405 		(void *)&cmd_showport_rss_hash_port_id,
3406 		(void *)&cmd_showport_rss_hash_rss_hash,
3407 		NULL,
3408 	},
3409 };
3410 
3411 static cmdline_parse_inst_t cmd_showport_rss_hash_key = {
3412 	.f = cmd_showport_rss_hash_parsed,
3413 	.data = NULL,
3414 	.help_str = "show port <port_id> rss-hash key",
3415 	.tokens = {
3416 		(void *)&cmd_showport_rss_hash_show,
3417 		(void *)&cmd_showport_rss_hash_port,
3418 		(void *)&cmd_showport_rss_hash_port_id,
3419 		(void *)&cmd_showport_rss_hash_rss_hash,
3420 		(void *)&cmd_showport_rss_hash_rss_key,
3421 		NULL,
3422 	},
3423 };
3424 
3425 static cmdline_parse_inst_t cmd_showport_rss_hash_algo = {
3426 	.f = cmd_showport_rss_hash_parsed,
3427 	.data = NULL,
3428 	.help_str = "show port <port_id> rss-hash algorithm",
3429 	.tokens = {
3430 		(void *)&cmd_showport_rss_hash_show,
3431 		(void *)&cmd_showport_rss_hash_port,
3432 		(void *)&cmd_showport_rss_hash_port_id,
3433 		(void *)&cmd_showport_rss_hash_rss_hash,
3434 		(void *)&cmd_showport_rss_hash_rss_algo,
3435 		NULL,
3436 	},
3437 };
3438 
3439 /* *** Configure DCB *** */
3440 struct cmd_config_dcb {
3441 	cmdline_fixed_string_t port;
3442 	cmdline_fixed_string_t config;
3443 	portid_t port_id;
3444 	cmdline_fixed_string_t dcb;
3445 	cmdline_fixed_string_t vt;
3446 	cmdline_fixed_string_t vt_en;
3447 	uint8_t num_tcs;
3448 	cmdline_fixed_string_t pfc;
3449 	cmdline_fixed_string_t pfc_en;
3450 };
3451 
3452 static void
3453 cmd_config_dcb_parsed(void *parsed_result,
3454                         __rte_unused struct cmdline *cl,
3455                         __rte_unused void *data)
3456 {
3457 	struct cmd_config_dcb *res = parsed_result;
3458 	struct rte_eth_dcb_info dcb_info;
3459 	portid_t port_id = res->port_id;
3460 	struct rte_port *port;
3461 	uint8_t pfc_en;
3462 	int ret;
3463 
3464 	port = &ports[port_id];
3465 	/** Check if the port is not started **/
3466 	if (port->port_status != RTE_PORT_STOPPED) {
3467 		fprintf(stderr, "Please stop port %d first\n", port_id);
3468 		return;
3469 	}
3470 
3471 	if ((res->num_tcs != RTE_ETH_4_TCS) && (res->num_tcs != RTE_ETH_8_TCS)) {
3472 		fprintf(stderr,
3473 			"The invalid number of traffic class, only 4 or 8 allowed.\n");
3474 		return;
3475 	}
3476 
3477 	if (nb_fwd_lcores < res->num_tcs) {
3478 		fprintf(stderr,
3479 			"nb_cores shouldn't be less than number of TCs.\n");
3480 		return;
3481 	}
3482 
3483 	/* Check whether the port supports the report of DCB info. */
3484 	ret = rte_eth_dev_get_dcb_info(port_id, &dcb_info);
3485 	if (ret == -ENOTSUP) {
3486 		fprintf(stderr, "rte_eth_dev_get_dcb_info not supported.\n");
3487 		return;
3488 	}
3489 
3490 	if (!strncmp(res->pfc_en, "on", 2))
3491 		pfc_en = 1;
3492 	else
3493 		pfc_en = 0;
3494 
3495 	/* DCB in VT mode */
3496 	if (!strncmp(res->vt_en, "on", 2))
3497 		ret = init_port_dcb_config(port_id, DCB_VT_ENABLED,
3498 				(enum rte_eth_nb_tcs)res->num_tcs,
3499 				pfc_en);
3500 	else
3501 		ret = init_port_dcb_config(port_id, DCB_ENABLED,
3502 				(enum rte_eth_nb_tcs)res->num_tcs,
3503 				pfc_en);
3504 	if (ret != 0) {
3505 		fprintf(stderr, "Cannot initialize network ports.\n");
3506 		return;
3507 	}
3508 
3509 	fwd_config_setup();
3510 
3511 	cmd_reconfig_device_queue(port_id, 1, 1);
3512 }
3513 
3514 static cmdline_parse_token_string_t cmd_config_dcb_port =
3515         TOKEN_STRING_INITIALIZER(struct cmd_config_dcb, port, "port");
3516 static cmdline_parse_token_string_t cmd_config_dcb_config =
3517         TOKEN_STRING_INITIALIZER(struct cmd_config_dcb, config, "config");
3518 static cmdline_parse_token_num_t cmd_config_dcb_port_id =
3519 	TOKEN_NUM_INITIALIZER(struct cmd_config_dcb, port_id, RTE_UINT16);
3520 static cmdline_parse_token_string_t cmd_config_dcb_dcb =
3521         TOKEN_STRING_INITIALIZER(struct cmd_config_dcb, dcb, "dcb");
3522 static cmdline_parse_token_string_t cmd_config_dcb_vt =
3523         TOKEN_STRING_INITIALIZER(struct cmd_config_dcb, vt, "vt");
3524 static cmdline_parse_token_string_t cmd_config_dcb_vt_en =
3525         TOKEN_STRING_INITIALIZER(struct cmd_config_dcb, vt_en, "on#off");
3526 static cmdline_parse_token_num_t cmd_config_dcb_num_tcs =
3527 	TOKEN_NUM_INITIALIZER(struct cmd_config_dcb, num_tcs, RTE_UINT8);
3528 static cmdline_parse_token_string_t cmd_config_dcb_pfc =
3529         TOKEN_STRING_INITIALIZER(struct cmd_config_dcb, pfc, "pfc");
3530 static cmdline_parse_token_string_t cmd_config_dcb_pfc_en =
3531         TOKEN_STRING_INITIALIZER(struct cmd_config_dcb, pfc_en, "on#off");
3532 
3533 static cmdline_parse_inst_t cmd_config_dcb = {
3534 	.f = cmd_config_dcb_parsed,
3535 	.data = NULL,
3536 	.help_str = "port config <port-id> dcb vt on|off <num_tcs> pfc on|off",
3537 	.tokens = {
3538 		(void *)&cmd_config_dcb_port,
3539 		(void *)&cmd_config_dcb_config,
3540 		(void *)&cmd_config_dcb_port_id,
3541 		(void *)&cmd_config_dcb_dcb,
3542 		(void *)&cmd_config_dcb_vt,
3543 		(void *)&cmd_config_dcb_vt_en,
3544 		(void *)&cmd_config_dcb_num_tcs,
3545 		(void *)&cmd_config_dcb_pfc,
3546 		(void *)&cmd_config_dcb_pfc_en,
3547                 NULL,
3548         },
3549 };
3550 
3551 /* *** configure number of packets per burst *** */
3552 struct cmd_config_burst {
3553 	cmdline_fixed_string_t port;
3554 	cmdline_fixed_string_t keyword;
3555 	cmdline_fixed_string_t all;
3556 	cmdline_fixed_string_t name;
3557 	uint16_t value;
3558 };
3559 
3560 static void
3561 cmd_config_burst_parsed(void *parsed_result,
3562 			__rte_unused struct cmdline *cl,
3563 			__rte_unused void *data)
3564 {
3565 	struct cmd_config_burst *res = parsed_result;
3566 	struct rte_eth_dev_info dev_info;
3567 	uint16_t rec_nb_pkts;
3568 	int ret;
3569 
3570 	if (!all_ports_stopped()) {
3571 		fprintf(stderr, "Please stop all ports first\n");
3572 		return;
3573 	}
3574 
3575 	if (!strcmp(res->name, "burst")) {
3576 		if (res->value == 0) {
3577 			/* If user gives a value of zero, query the PMD for
3578 			 * its recommended Rx burst size. Testpmd uses a single
3579 			 * size for all ports, so assume all ports are the same
3580 			 * NIC model and use the values from Port 0.
3581 			 */
3582 			ret = eth_dev_info_get_print_err(0, &dev_info);
3583 			if (ret != 0)
3584 				return;
3585 
3586 			rec_nb_pkts = dev_info.default_rxportconf.burst_size;
3587 
3588 			if (rec_nb_pkts == 0) {
3589 				printf("PMD does not recommend a burst size.\n"
3590 					"User provided value must be between"
3591 					" 1 and %d\n", MAX_PKT_BURST);
3592 				return;
3593 			} else if (rec_nb_pkts > MAX_PKT_BURST) {
3594 				printf("PMD recommended burst size of %d"
3595 					" exceeds maximum value of %d\n",
3596 					rec_nb_pkts, MAX_PKT_BURST);
3597 				return;
3598 			}
3599 			printf("Using PMD-provided burst value of %d\n",
3600 				rec_nb_pkts);
3601 			nb_pkt_per_burst = rec_nb_pkts;
3602 		} else if (res->value > MAX_PKT_BURST) {
3603 			fprintf(stderr, "burst must be >= 1 && <= %d\n",
3604 				MAX_PKT_BURST);
3605 			return;
3606 		} else
3607 			nb_pkt_per_burst = res->value;
3608 	} else {
3609 		fprintf(stderr, "Unknown parameter\n");
3610 		return;
3611 	}
3612 
3613 	init_port_config();
3614 
3615 	cmd_reconfig_device_queue(RTE_PORT_ALL, 1, 1);
3616 }
3617 
3618 static cmdline_parse_token_string_t cmd_config_burst_port =
3619 	TOKEN_STRING_INITIALIZER(struct cmd_config_burst, port, "port");
3620 static cmdline_parse_token_string_t cmd_config_burst_keyword =
3621 	TOKEN_STRING_INITIALIZER(struct cmd_config_burst, keyword, "config");
3622 static cmdline_parse_token_string_t cmd_config_burst_all =
3623 	TOKEN_STRING_INITIALIZER(struct cmd_config_burst, all, "all");
3624 static cmdline_parse_token_string_t cmd_config_burst_name =
3625 	TOKEN_STRING_INITIALIZER(struct cmd_config_burst, name, "burst");
3626 static cmdline_parse_token_num_t cmd_config_burst_value =
3627 	TOKEN_NUM_INITIALIZER(struct cmd_config_burst, value, RTE_UINT16);
3628 
3629 static cmdline_parse_inst_t cmd_config_burst = {
3630 	.f = cmd_config_burst_parsed,
3631 	.data = NULL,
3632 	.help_str = "port config all burst <value>",
3633 	.tokens = {
3634 		(void *)&cmd_config_burst_port,
3635 		(void *)&cmd_config_burst_keyword,
3636 		(void *)&cmd_config_burst_all,
3637 		(void *)&cmd_config_burst_name,
3638 		(void *)&cmd_config_burst_value,
3639 		NULL,
3640 	},
3641 };
3642 
3643 /* *** configure rx/tx queues *** */
3644 struct cmd_config_thresh {
3645 	cmdline_fixed_string_t port;
3646 	cmdline_fixed_string_t keyword;
3647 	cmdline_fixed_string_t all;
3648 	cmdline_fixed_string_t name;
3649 	uint8_t value;
3650 };
3651 
3652 static void
3653 cmd_config_thresh_parsed(void *parsed_result,
3654 			__rte_unused struct cmdline *cl,
3655 			__rte_unused void *data)
3656 {
3657 	struct cmd_config_thresh *res = parsed_result;
3658 
3659 	if (!all_ports_stopped()) {
3660 		fprintf(stderr, "Please stop all ports first\n");
3661 		return;
3662 	}
3663 
3664 	if (!strcmp(res->name, "txpt"))
3665 		tx_pthresh = res->value;
3666 	else if(!strcmp(res->name, "txht"))
3667 		tx_hthresh = res->value;
3668 	else if(!strcmp(res->name, "txwt"))
3669 		tx_wthresh = res->value;
3670 	else if(!strcmp(res->name, "rxpt"))
3671 		rx_pthresh = res->value;
3672 	else if(!strcmp(res->name, "rxht"))
3673 		rx_hthresh = res->value;
3674 	else if(!strcmp(res->name, "rxwt"))
3675 		rx_wthresh = res->value;
3676 	else {
3677 		fprintf(stderr, "Unknown parameter\n");
3678 		return;
3679 	}
3680 
3681 	init_port_config();
3682 
3683 	cmd_reconfig_device_queue(RTE_PORT_ALL, 1, 1);
3684 }
3685 
3686 static cmdline_parse_token_string_t cmd_config_thresh_port =
3687 	TOKEN_STRING_INITIALIZER(struct cmd_config_thresh, port, "port");
3688 static cmdline_parse_token_string_t cmd_config_thresh_keyword =
3689 	TOKEN_STRING_INITIALIZER(struct cmd_config_thresh, keyword, "config");
3690 static cmdline_parse_token_string_t cmd_config_thresh_all =
3691 	TOKEN_STRING_INITIALIZER(struct cmd_config_thresh, all, "all");
3692 static cmdline_parse_token_string_t cmd_config_thresh_name =
3693 	TOKEN_STRING_INITIALIZER(struct cmd_config_thresh, name,
3694 				"txpt#txht#txwt#rxpt#rxht#rxwt");
3695 static cmdline_parse_token_num_t cmd_config_thresh_value =
3696 	TOKEN_NUM_INITIALIZER(struct cmd_config_thresh, value, RTE_UINT8);
3697 
3698 static cmdline_parse_inst_t cmd_config_thresh = {
3699 	.f = cmd_config_thresh_parsed,
3700 	.data = NULL,
3701 	.help_str = "port config all txpt|txht|txwt|rxpt|rxht|rxwt <value>",
3702 	.tokens = {
3703 		(void *)&cmd_config_thresh_port,
3704 		(void *)&cmd_config_thresh_keyword,
3705 		(void *)&cmd_config_thresh_all,
3706 		(void *)&cmd_config_thresh_name,
3707 		(void *)&cmd_config_thresh_value,
3708 		NULL,
3709 	},
3710 };
3711 
3712 /* *** configure free/rs threshold *** */
3713 struct cmd_config_threshold {
3714 	cmdline_fixed_string_t port;
3715 	cmdline_fixed_string_t keyword;
3716 	cmdline_fixed_string_t all;
3717 	cmdline_fixed_string_t name;
3718 	uint16_t value;
3719 };
3720 
3721 static void
3722 cmd_config_threshold_parsed(void *parsed_result,
3723 			__rte_unused struct cmdline *cl,
3724 			__rte_unused void *data)
3725 {
3726 	struct cmd_config_threshold *res = parsed_result;
3727 
3728 	if (!all_ports_stopped()) {
3729 		fprintf(stderr, "Please stop all ports first\n");
3730 		return;
3731 	}
3732 
3733 	if (!strcmp(res->name, "txfreet"))
3734 		tx_free_thresh = res->value;
3735 	else if (!strcmp(res->name, "txrst"))
3736 		tx_rs_thresh = res->value;
3737 	else if (!strcmp(res->name, "rxfreet"))
3738 		rx_free_thresh = res->value;
3739 	else {
3740 		fprintf(stderr, "Unknown parameter\n");
3741 		return;
3742 	}
3743 
3744 	init_port_config();
3745 
3746 	cmd_reconfig_device_queue(RTE_PORT_ALL, 1, 1);
3747 }
3748 
3749 static cmdline_parse_token_string_t cmd_config_threshold_port =
3750 	TOKEN_STRING_INITIALIZER(struct cmd_config_threshold, port, "port");
3751 static cmdline_parse_token_string_t cmd_config_threshold_keyword =
3752 	TOKEN_STRING_INITIALIZER(struct cmd_config_threshold, keyword,
3753 								"config");
3754 static cmdline_parse_token_string_t cmd_config_threshold_all =
3755 	TOKEN_STRING_INITIALIZER(struct cmd_config_threshold, all, "all");
3756 static cmdline_parse_token_string_t cmd_config_threshold_name =
3757 	TOKEN_STRING_INITIALIZER(struct cmd_config_threshold, name,
3758 						"txfreet#txrst#rxfreet");
3759 static cmdline_parse_token_num_t cmd_config_threshold_value =
3760 	TOKEN_NUM_INITIALIZER(struct cmd_config_threshold, value, RTE_UINT16);
3761 
3762 static cmdline_parse_inst_t cmd_config_threshold = {
3763 	.f = cmd_config_threshold_parsed,
3764 	.data = NULL,
3765 	.help_str = "port config all txfreet|txrst|rxfreet <value>",
3766 	.tokens = {
3767 		(void *)&cmd_config_threshold_port,
3768 		(void *)&cmd_config_threshold_keyword,
3769 		(void *)&cmd_config_threshold_all,
3770 		(void *)&cmd_config_threshold_name,
3771 		(void *)&cmd_config_threshold_value,
3772 		NULL,
3773 	},
3774 };
3775 
3776 /* *** stop *** */
3777 struct cmd_stop_result {
3778 	cmdline_fixed_string_t stop;
3779 };
3780 
3781 static void cmd_stop_parsed(__rte_unused void *parsed_result,
3782 			    __rte_unused struct cmdline *cl,
3783 			    __rte_unused void *data)
3784 {
3785 	stop_packet_forwarding();
3786 }
3787 
3788 static cmdline_parse_token_string_t cmd_stop_stop =
3789 	TOKEN_STRING_INITIALIZER(struct cmd_stop_result, stop, "stop");
3790 
3791 static cmdline_parse_inst_t cmd_stop = {
3792 	.f = cmd_stop_parsed,
3793 	.data = NULL,
3794 	.help_str = "stop: Stop packet forwarding",
3795 	.tokens = {
3796 		(void *)&cmd_stop_stop,
3797 		NULL,
3798 	},
3799 };
3800 
3801 static unsigned int
3802 get_ptype(char *value)
3803 {
3804 	uint32_t protocol;
3805 
3806 	if (!strcmp(value, "eth"))
3807 		protocol = RTE_PTYPE_L2_ETHER;
3808 	else if (!strcmp(value, "ipv4"))
3809 		protocol = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN;
3810 	else if (!strcmp(value, "ipv6"))
3811 		protocol = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN;
3812 	else if (!strcmp(value, "ipv4-tcp"))
3813 		protocol = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN | RTE_PTYPE_L4_TCP;
3814 	else if (!strcmp(value, "ipv4-udp"))
3815 		protocol = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN | RTE_PTYPE_L4_UDP;
3816 	else if (!strcmp(value, "ipv4-sctp"))
3817 		protocol = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN | RTE_PTYPE_L4_SCTP;
3818 	else if (!strcmp(value, "ipv6-tcp"))
3819 		protocol = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN | RTE_PTYPE_L4_TCP;
3820 	else if (!strcmp(value, "ipv6-udp"))
3821 		protocol = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN | RTE_PTYPE_L4_UDP;
3822 	else if (!strcmp(value, "ipv6-sctp"))
3823 		protocol = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN | RTE_PTYPE_L4_SCTP;
3824 	else if (!strcmp(value, "grenat"))
3825 		protocol = RTE_PTYPE_TUNNEL_GRENAT;
3826 	else if (!strcmp(value, "inner-eth"))
3827 		protocol = RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER;
3828 	else if (!strcmp(value, "inner-ipv4"))
3829 		protocol = RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
3830 				RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN;
3831 	else if (!strcmp(value, "inner-ipv6"))
3832 		protocol = RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
3833 				RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN;
3834 	else if (!strcmp(value, "inner-ipv4-tcp"))
3835 		protocol = RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
3836 				RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN | RTE_PTYPE_INNER_L4_TCP;
3837 	else if (!strcmp(value, "inner-ipv4-udp"))
3838 		protocol = RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
3839 				RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN | RTE_PTYPE_INNER_L4_UDP;
3840 	else if (!strcmp(value, "inner-ipv4-sctp"))
3841 		protocol = RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
3842 				RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN | RTE_PTYPE_INNER_L4_SCTP;
3843 	else if (!strcmp(value, "inner-ipv6-tcp"))
3844 		protocol = RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
3845 				RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN | RTE_PTYPE_INNER_L4_TCP;
3846 	else if (!strcmp(value, "inner-ipv6-udp"))
3847 		protocol = RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
3848 				RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN | RTE_PTYPE_INNER_L4_UDP;
3849 	else if (!strcmp(value, "inner-ipv6-sctp"))
3850 		protocol = RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
3851 				RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN | RTE_PTYPE_INNER_L4_SCTP;
3852 	else {
3853 		fprintf(stderr, "Unsupported protocol: %s\n", value);
3854 		protocol = RTE_PTYPE_UNKNOWN;
3855 	}
3856 
3857 	return protocol;
3858 }
3859 
3860 /* *** SET RXHDRSLIST *** */
3861 
3862 unsigned int
3863 parse_hdrs_list(const char *str, const char *item_name, unsigned int max_items,
3864 				unsigned int *parsed_items)
3865 {
3866 	unsigned int nb_item;
3867 	char *cur;
3868 	char *tmp;
3869 
3870 	nb_item = 0;
3871 	char *str2 = strdup(str);
3872 	if (str2 == NULL)
3873 		return nb_item;
3874 	cur = strtok_r(str2, ",", &tmp);
3875 	while (cur != NULL) {
3876 		parsed_items[nb_item] = get_ptype(cur);
3877 		cur = strtok_r(NULL, ",", &tmp);
3878 		nb_item++;
3879 	}
3880 	if (nb_item > max_items)
3881 		fprintf(stderr, "Number of %s = %u > %u (maximum items)\n",
3882 			item_name, nb_item + 1, max_items);
3883 	free(str2);
3884 	return nb_item;
3885 }
3886 
3887 /* *** SET CORELIST and PORTLIST CONFIGURATION *** */
3888 
3889 unsigned int
3890 parse_item_list(const char *str, const char *item_name, unsigned int max_items,
3891 		unsigned int *parsed_items, int check_unique_values)
3892 {
3893 	unsigned int nb_item;
3894 	unsigned int value;
3895 	unsigned int i;
3896 	unsigned int j;
3897 	int value_ok;
3898 	char c;
3899 
3900 	/*
3901 	 * First parse all items in the list and store their value.
3902 	 */
3903 	value = 0;
3904 	nb_item = 0;
3905 	value_ok = 0;
3906 	for (i = 0; i < strnlen(str, STR_TOKEN_SIZE); i++) {
3907 		c = str[i];
3908 		if ((c >= '0') && (c <= '9')) {
3909 			value = (unsigned int) (value * 10 + (c - '0'));
3910 			value_ok = 1;
3911 			continue;
3912 		}
3913 		if (c != ',') {
3914 			fprintf(stderr, "character %c is not a decimal digit\n", c);
3915 			return 0;
3916 		}
3917 		if (! value_ok) {
3918 			fprintf(stderr, "No valid value before comma\n");
3919 			return 0;
3920 		}
3921 		if (nb_item < max_items) {
3922 			parsed_items[nb_item] = value;
3923 			value_ok = 0;
3924 			value = 0;
3925 		}
3926 		nb_item++;
3927 	}
3928 	if (nb_item >= max_items) {
3929 		fprintf(stderr, "Number of %s = %u > %u (maximum items)\n",
3930 			item_name, nb_item + 1, max_items);
3931 		return 0;
3932 	}
3933 	parsed_items[nb_item++] = value;
3934 	if (! check_unique_values)
3935 		return nb_item;
3936 
3937 	/*
3938 	 * Then, check that all values in the list are different.
3939 	 * No optimization here...
3940 	 */
3941 	for (i = 0; i < nb_item; i++) {
3942 		for (j = i + 1; j < nb_item; j++) {
3943 			if (parsed_items[j] == parsed_items[i]) {
3944 				fprintf(stderr,
3945 					"duplicated %s %u at index %u and %u\n",
3946 					item_name, parsed_items[i], i, j);
3947 				return 0;
3948 			}
3949 		}
3950 	}
3951 	return nb_item;
3952 }
3953 
3954 struct cmd_set_list_result {
3955 	cmdline_fixed_string_t cmd_keyword;
3956 	cmdline_fixed_string_t list_name;
3957 	cmdline_fixed_string_t list_of_items;
3958 };
3959 
3960 static void cmd_set_list_parsed(void *parsed_result,
3961 				__rte_unused struct cmdline *cl,
3962 				__rte_unused void *data)
3963 {
3964 	struct cmd_set_list_result *res;
3965 	union {
3966 		unsigned int lcorelist[RTE_MAX_LCORE];
3967 		unsigned int portlist[RTE_MAX_ETHPORTS];
3968 	} parsed_items;
3969 	unsigned int nb_item;
3970 
3971 	if (test_done == 0) {
3972 		fprintf(stderr, "Please stop forwarding first\n");
3973 		return;
3974 	}
3975 
3976 	res = parsed_result;
3977 	if (!strcmp(res->list_name, "corelist")) {
3978 		nb_item = parse_item_list(res->list_of_items, "core",
3979 					  RTE_MAX_LCORE,
3980 					  parsed_items.lcorelist, 1);
3981 		if (nb_item > 0) {
3982 			set_fwd_lcores_list(parsed_items.lcorelist, nb_item);
3983 			fwd_config_setup();
3984 		}
3985 		return;
3986 	}
3987 	if (!strcmp(res->list_name, "portlist")) {
3988 		nb_item = parse_item_list(res->list_of_items, "port",
3989 					  RTE_MAX_ETHPORTS,
3990 					  parsed_items.portlist, 1);
3991 		if (nb_item > 0) {
3992 			set_fwd_ports_list(parsed_items.portlist, nb_item);
3993 			fwd_config_setup();
3994 		}
3995 	}
3996 }
3997 
3998 static cmdline_parse_token_string_t cmd_set_list_keyword =
3999 	TOKEN_STRING_INITIALIZER(struct cmd_set_list_result, cmd_keyword,
4000 				 "set");
4001 static cmdline_parse_token_string_t cmd_set_list_name =
4002 	TOKEN_STRING_INITIALIZER(struct cmd_set_list_result, list_name,
4003 				 "corelist#portlist");
4004 static cmdline_parse_token_string_t cmd_set_list_of_items =
4005 	TOKEN_STRING_INITIALIZER(struct cmd_set_list_result, list_of_items,
4006 				 NULL);
4007 
4008 static cmdline_parse_inst_t cmd_set_fwd_list = {
4009 	.f = cmd_set_list_parsed,
4010 	.data = NULL,
4011 	.help_str = "set corelist|portlist <list0[,list1]*>",
4012 	.tokens = {
4013 		(void *)&cmd_set_list_keyword,
4014 		(void *)&cmd_set_list_name,
4015 		(void *)&cmd_set_list_of_items,
4016 		NULL,
4017 	},
4018 };
4019 
4020 /* *** SET COREMASK and PORTMASK CONFIGURATION *** */
4021 
4022 struct cmd_setmask_result {
4023 	cmdline_fixed_string_t set;
4024 	cmdline_fixed_string_t mask;
4025 	uint64_t hexavalue;
4026 };
4027 
4028 static void cmd_set_mask_parsed(void *parsed_result,
4029 				__rte_unused struct cmdline *cl,
4030 				__rte_unused void *data)
4031 {
4032 	struct cmd_setmask_result *res = parsed_result;
4033 
4034 	if (test_done == 0) {
4035 		fprintf(stderr, "Please stop forwarding first\n");
4036 		return;
4037 	}
4038 	if (!strcmp(res->mask, "coremask")) {
4039 		set_fwd_lcores_mask(res->hexavalue);
4040 		fwd_config_setup();
4041 	} else if (!strcmp(res->mask, "portmask")) {
4042 		set_fwd_ports_mask(res->hexavalue);
4043 		fwd_config_setup();
4044 	}
4045 }
4046 
4047 static cmdline_parse_token_string_t cmd_setmask_set =
4048 	TOKEN_STRING_INITIALIZER(struct cmd_setmask_result, set, "set");
4049 static cmdline_parse_token_string_t cmd_setmask_mask =
4050 	TOKEN_STRING_INITIALIZER(struct cmd_setmask_result, mask,
4051 				 "coremask#portmask");
4052 static cmdline_parse_token_num_t cmd_setmask_value =
4053 	TOKEN_NUM_INITIALIZER(struct cmd_setmask_result, hexavalue, RTE_UINT64);
4054 
4055 static cmdline_parse_inst_t cmd_set_fwd_mask = {
4056 	.f = cmd_set_mask_parsed,
4057 	.data = NULL,
4058 	.help_str = "set coremask|portmask <hexadecimal value>",
4059 	.tokens = {
4060 		(void *)&cmd_setmask_set,
4061 		(void *)&cmd_setmask_mask,
4062 		(void *)&cmd_setmask_value,
4063 		NULL,
4064 	},
4065 };
4066 
4067 /*
4068  * SET NBPORT, NBCORE, PACKET BURST, and VERBOSE LEVEL CONFIGURATION
4069  */
4070 struct cmd_set_result {
4071 	cmdline_fixed_string_t set;
4072 	cmdline_fixed_string_t what;
4073 	uint16_t value;
4074 };
4075 
4076 static void cmd_set_parsed(void *parsed_result,
4077 			   __rte_unused struct cmdline *cl,
4078 			   __rte_unused void *data)
4079 {
4080 	struct cmd_set_result *res = parsed_result;
4081 	if (!strcmp(res->what, "nbport")) {
4082 		set_fwd_ports_number(res->value);
4083 		fwd_config_setup();
4084 	} else if (!strcmp(res->what, "nbcore")) {
4085 		set_fwd_lcores_number(res->value);
4086 		fwd_config_setup();
4087 	} else if (!strcmp(res->what, "burst"))
4088 		set_nb_pkt_per_burst(res->value);
4089 	else if (!strcmp(res->what, "verbose"))
4090 		set_verbose_level(res->value);
4091 }
4092 
4093 static cmdline_parse_token_string_t cmd_set_set =
4094 	TOKEN_STRING_INITIALIZER(struct cmd_set_result, set, "set");
4095 static cmdline_parse_token_string_t cmd_set_what =
4096 	TOKEN_STRING_INITIALIZER(struct cmd_set_result, what,
4097 				 "nbport#nbcore#burst#verbose");
4098 static cmdline_parse_token_num_t cmd_set_value =
4099 	TOKEN_NUM_INITIALIZER(struct cmd_set_result, value, RTE_UINT16);
4100 
4101 static cmdline_parse_inst_t cmd_set_numbers = {
4102 	.f = cmd_set_parsed,
4103 	.data = NULL,
4104 	.help_str = "set nbport|nbcore|burst|verbose <value>",
4105 	.tokens = {
4106 		(void *)&cmd_set_set,
4107 		(void *)&cmd_set_what,
4108 		(void *)&cmd_set_value,
4109 		NULL,
4110 	},
4111 };
4112 
4113 /* *** SET LOG LEVEL CONFIGURATION *** */
4114 
4115 struct cmd_set_log_result {
4116 	cmdline_fixed_string_t set;
4117 	cmdline_fixed_string_t log;
4118 	cmdline_fixed_string_t type;
4119 	uint32_t level;
4120 };
4121 
4122 static void
4123 cmd_set_log_parsed(void *parsed_result,
4124 		   __rte_unused struct cmdline *cl,
4125 		   __rte_unused void *data)
4126 {
4127 	struct cmd_set_log_result *res;
4128 	int ret;
4129 
4130 	res = parsed_result;
4131 	if (!strcmp(res->type, "global"))
4132 		rte_log_set_global_level(res->level);
4133 	else {
4134 		ret = rte_log_set_level_regexp(res->type, res->level);
4135 		if (ret < 0)
4136 			fprintf(stderr, "Unable to set log level\n");
4137 	}
4138 }
4139 
4140 static cmdline_parse_token_string_t cmd_set_log_set =
4141 	TOKEN_STRING_INITIALIZER(struct cmd_set_log_result, set, "set");
4142 static cmdline_parse_token_string_t cmd_set_log_log =
4143 	TOKEN_STRING_INITIALIZER(struct cmd_set_log_result, log, "log");
4144 static cmdline_parse_token_string_t cmd_set_log_type =
4145 	TOKEN_STRING_INITIALIZER(struct cmd_set_log_result, type, NULL);
4146 static cmdline_parse_token_num_t cmd_set_log_level =
4147 	TOKEN_NUM_INITIALIZER(struct cmd_set_log_result, level, RTE_UINT32);
4148 
4149 static cmdline_parse_inst_t cmd_set_log = {
4150 	.f = cmd_set_log_parsed,
4151 	.data = NULL,
4152 	.help_str = "set log global|<type> <level>",
4153 	.tokens = {
4154 		(void *)&cmd_set_log_set,
4155 		(void *)&cmd_set_log_log,
4156 		(void *)&cmd_set_log_type,
4157 		(void *)&cmd_set_log_level,
4158 		NULL,
4159 	},
4160 };
4161 
4162 /* *** SET SEGMENT OFFSETS OF RX PACKETS SPLIT *** */
4163 
4164 struct cmd_set_rxoffs_result {
4165 	cmdline_fixed_string_t cmd_keyword;
4166 	cmdline_fixed_string_t rxoffs;
4167 	cmdline_fixed_string_t seg_offsets;
4168 };
4169 
4170 static void
4171 cmd_set_rxoffs_parsed(void *parsed_result,
4172 		      __rte_unused struct cmdline *cl,
4173 		      __rte_unused void *data)
4174 {
4175 	struct cmd_set_rxoffs_result *res;
4176 	unsigned int seg_offsets[MAX_SEGS_BUFFER_SPLIT];
4177 	unsigned int nb_segs;
4178 
4179 	res = parsed_result;
4180 	nb_segs = parse_item_list(res->seg_offsets, "segment offsets",
4181 				  MAX_SEGS_BUFFER_SPLIT, seg_offsets, 0);
4182 	if (nb_segs > 0)
4183 		set_rx_pkt_offsets(seg_offsets, nb_segs);
4184 	cmd_reconfig_device_queue(RTE_PORT_ALL, 0, 1);
4185 }
4186 
4187 static cmdline_parse_token_string_t cmd_set_rxoffs_keyword =
4188 	TOKEN_STRING_INITIALIZER(struct cmd_set_rxoffs_result,
4189 				 cmd_keyword, "set");
4190 static cmdline_parse_token_string_t cmd_set_rxoffs_name =
4191 	TOKEN_STRING_INITIALIZER(struct cmd_set_rxoffs_result,
4192 				 rxoffs, "rxoffs");
4193 static cmdline_parse_token_string_t cmd_set_rxoffs_offsets =
4194 	TOKEN_STRING_INITIALIZER(struct cmd_set_rxoffs_result,
4195 				 seg_offsets, NULL);
4196 
4197 static cmdline_parse_inst_t cmd_set_rxoffs = {
4198 	.f = cmd_set_rxoffs_parsed,
4199 	.data = NULL,
4200 	.help_str = "set rxoffs <len0[,len1]*>",
4201 	.tokens = {
4202 		(void *)&cmd_set_rxoffs_keyword,
4203 		(void *)&cmd_set_rxoffs_name,
4204 		(void *)&cmd_set_rxoffs_offsets,
4205 		NULL,
4206 	},
4207 };
4208 
4209 /* *** SET SEGMENT LENGTHS OF RX PACKETS SPLIT *** */
4210 
4211 struct cmd_set_rxpkts_result {
4212 	cmdline_fixed_string_t cmd_keyword;
4213 	cmdline_fixed_string_t rxpkts;
4214 	cmdline_fixed_string_t seg_lengths;
4215 };
4216 
4217 static void
4218 cmd_set_rxpkts_parsed(void *parsed_result,
4219 		      __rte_unused struct cmdline *cl,
4220 		      __rte_unused void *data)
4221 {
4222 	struct cmd_set_rxpkts_result *res;
4223 	unsigned int seg_lengths[MAX_SEGS_BUFFER_SPLIT];
4224 	unsigned int nb_segs;
4225 
4226 	res = parsed_result;
4227 	nb_segs = parse_item_list(res->seg_lengths, "segment lengths",
4228 				  MAX_SEGS_BUFFER_SPLIT, seg_lengths, 0);
4229 	if (nb_segs > 0)
4230 		set_rx_pkt_segments(seg_lengths, nb_segs);
4231 	cmd_reconfig_device_queue(RTE_PORT_ALL, 0, 1);
4232 }
4233 
4234 static cmdline_parse_token_string_t cmd_set_rxpkts_keyword =
4235 	TOKEN_STRING_INITIALIZER(struct cmd_set_rxpkts_result,
4236 				 cmd_keyword, "set");
4237 static cmdline_parse_token_string_t cmd_set_rxpkts_name =
4238 	TOKEN_STRING_INITIALIZER(struct cmd_set_rxpkts_result,
4239 				 rxpkts, "rxpkts");
4240 static cmdline_parse_token_string_t cmd_set_rxpkts_lengths =
4241 	TOKEN_STRING_INITIALIZER(struct cmd_set_rxpkts_result,
4242 				 seg_lengths, NULL);
4243 
4244 static cmdline_parse_inst_t cmd_set_rxpkts = {
4245 	.f = cmd_set_rxpkts_parsed,
4246 	.data = NULL,
4247 	.help_str = "set rxpkts <len0[,len1]*>",
4248 	.tokens = {
4249 		(void *)&cmd_set_rxpkts_keyword,
4250 		(void *)&cmd_set_rxpkts_name,
4251 		(void *)&cmd_set_rxpkts_lengths,
4252 		NULL,
4253 	},
4254 };
4255 
4256 /* *** SET SEGMENT HEADERS OF RX PACKETS SPLIT *** */
4257 struct cmd_set_rxhdrs_result {
4258 	cmdline_fixed_string_t set;
4259 	cmdline_fixed_string_t rxhdrs;
4260 	cmdline_fixed_string_t values;
4261 };
4262 
4263 static void
4264 cmd_set_rxhdrs_parsed(void *parsed_result,
4265 		      __rte_unused struct cmdline *cl,
4266 		      __rte_unused void *data)
4267 {
4268 	struct cmd_set_rxhdrs_result *res;
4269 	unsigned int seg_hdrs[MAX_SEGS_BUFFER_SPLIT];
4270 	unsigned int nb_segs;
4271 
4272 	res = parsed_result;
4273 	nb_segs = parse_hdrs_list(res->values, "segment hdrs",
4274 				  MAX_SEGS_BUFFER_SPLIT, seg_hdrs);
4275 	if (nb_segs > 0)
4276 		set_rx_pkt_hdrs(seg_hdrs, nb_segs);
4277 	cmd_reconfig_device_queue(RTE_PORT_ALL, 0, 1);
4278 }
4279 
4280 static cmdline_parse_token_string_t cmd_set_rxhdrs_set =
4281 	TOKEN_STRING_INITIALIZER(struct cmd_set_rxhdrs_result,
4282 				set, "set");
4283 static cmdline_parse_token_string_t cmd_set_rxhdrs_rxhdrs =
4284 	TOKEN_STRING_INITIALIZER(struct cmd_set_rxhdrs_result,
4285 				rxhdrs, "rxhdrs");
4286 static cmdline_parse_token_string_t cmd_set_rxhdrs_values =
4287 	TOKEN_STRING_INITIALIZER(struct cmd_set_rxhdrs_result,
4288 				values, NULL);
4289 
4290 static cmdline_parse_inst_t cmd_set_rxhdrs = {
4291 	.f = cmd_set_rxhdrs_parsed,
4292 	.data = NULL,
4293 	.help_str = "set rxhdrs <eth[,ipv4]*>",
4294 	.tokens = {
4295 		(void *)&cmd_set_rxhdrs_set,
4296 		(void *)&cmd_set_rxhdrs_rxhdrs,
4297 		(void *)&cmd_set_rxhdrs_values,
4298 		NULL,
4299 	},
4300 };
4301 
4302 /* *** SET SEGMENT LENGTHS OF TXONLY PACKETS *** */
4303 
4304 struct cmd_set_txpkts_result {
4305 	cmdline_fixed_string_t cmd_keyword;
4306 	cmdline_fixed_string_t txpkts;
4307 	cmdline_fixed_string_t seg_lengths;
4308 };
4309 
4310 static void
4311 cmd_set_txpkts_parsed(void *parsed_result,
4312 		      __rte_unused struct cmdline *cl,
4313 		      __rte_unused void *data)
4314 {
4315 	struct cmd_set_txpkts_result *res;
4316 	unsigned seg_lengths[RTE_MAX_SEGS_PER_PKT];
4317 	unsigned int nb_segs;
4318 
4319 	res = parsed_result;
4320 	nb_segs = parse_item_list(res->seg_lengths, "segment lengths",
4321 				  RTE_MAX_SEGS_PER_PKT, seg_lengths, 0);
4322 	if (nb_segs > 0)
4323 		set_tx_pkt_segments(seg_lengths, nb_segs);
4324 }
4325 
4326 static cmdline_parse_token_string_t cmd_set_txpkts_keyword =
4327 	TOKEN_STRING_INITIALIZER(struct cmd_set_txpkts_result,
4328 				 cmd_keyword, "set");
4329 static cmdline_parse_token_string_t cmd_set_txpkts_name =
4330 	TOKEN_STRING_INITIALIZER(struct cmd_set_txpkts_result,
4331 				 txpkts, "txpkts");
4332 static cmdline_parse_token_string_t cmd_set_txpkts_lengths =
4333 	TOKEN_STRING_INITIALIZER(struct cmd_set_txpkts_result,
4334 				 seg_lengths, NULL);
4335 
4336 static cmdline_parse_inst_t cmd_set_txpkts = {
4337 	.f = cmd_set_txpkts_parsed,
4338 	.data = NULL,
4339 	.help_str = "set txpkts <len0[,len1]*>",
4340 	.tokens = {
4341 		(void *)&cmd_set_txpkts_keyword,
4342 		(void *)&cmd_set_txpkts_name,
4343 		(void *)&cmd_set_txpkts_lengths,
4344 		NULL,
4345 	},
4346 };
4347 
4348 /* *** SET COPY AND SPLIT POLICY ON TX PACKETS *** */
4349 
4350 struct cmd_set_txsplit_result {
4351 	cmdline_fixed_string_t cmd_keyword;
4352 	cmdline_fixed_string_t txsplit;
4353 	cmdline_fixed_string_t mode;
4354 };
4355 
4356 static void
4357 cmd_set_txsplit_parsed(void *parsed_result,
4358 		      __rte_unused struct cmdline *cl,
4359 		      __rte_unused void *data)
4360 {
4361 	struct cmd_set_txsplit_result *res;
4362 
4363 	res = parsed_result;
4364 	set_tx_pkt_split(res->mode);
4365 }
4366 
4367 static cmdline_parse_token_string_t cmd_set_txsplit_keyword =
4368 	TOKEN_STRING_INITIALIZER(struct cmd_set_txsplit_result,
4369 				 cmd_keyword, "set");
4370 static cmdline_parse_token_string_t cmd_set_txsplit_name =
4371 	TOKEN_STRING_INITIALIZER(struct cmd_set_txsplit_result,
4372 				 txsplit, "txsplit");
4373 static cmdline_parse_token_string_t cmd_set_txsplit_mode =
4374 	TOKEN_STRING_INITIALIZER(struct cmd_set_txsplit_result,
4375 				 mode, NULL);
4376 
4377 static cmdline_parse_inst_t cmd_set_txsplit = {
4378 	.f = cmd_set_txsplit_parsed,
4379 	.data = NULL,
4380 	.help_str = "set txsplit on|off|rand",
4381 	.tokens = {
4382 		(void *)&cmd_set_txsplit_keyword,
4383 		(void *)&cmd_set_txsplit_name,
4384 		(void *)&cmd_set_txsplit_mode,
4385 		NULL,
4386 	},
4387 };
4388 
4389 /* *** SET TIMES FOR TXONLY PACKETS SCHEDULING ON TIMESTAMPS *** */
4390 
4391 struct cmd_set_txtimes_result {
4392 	cmdline_fixed_string_t cmd_keyword;
4393 	cmdline_fixed_string_t txtimes;
4394 	cmdline_fixed_string_t tx_times;
4395 };
4396 
4397 static void
4398 cmd_set_txtimes_parsed(void *parsed_result,
4399 		       __rte_unused struct cmdline *cl,
4400 		       __rte_unused void *data)
4401 {
4402 	struct cmd_set_txtimes_result *res;
4403 	unsigned int tx_times[2] = {0, 0};
4404 	unsigned int n_times;
4405 
4406 	res = parsed_result;
4407 	n_times = parse_item_list(res->tx_times, "tx times",
4408 				  2, tx_times, 0);
4409 	if (n_times == 2)
4410 		set_tx_pkt_times(tx_times);
4411 }
4412 
4413 static cmdline_parse_token_string_t cmd_set_txtimes_keyword =
4414 	TOKEN_STRING_INITIALIZER(struct cmd_set_txtimes_result,
4415 				 cmd_keyword, "set");
4416 static cmdline_parse_token_string_t cmd_set_txtimes_name =
4417 	TOKEN_STRING_INITIALIZER(struct cmd_set_txtimes_result,
4418 				 txtimes, "txtimes");
4419 static cmdline_parse_token_string_t cmd_set_txtimes_value =
4420 	TOKEN_STRING_INITIALIZER(struct cmd_set_txtimes_result,
4421 				 tx_times, NULL);
4422 
4423 static cmdline_parse_inst_t cmd_set_txtimes = {
4424 	.f = cmd_set_txtimes_parsed,
4425 	.data = NULL,
4426 	.help_str = "set txtimes <inter_burst>,<intra_burst>",
4427 	.tokens = {
4428 		(void *)&cmd_set_txtimes_keyword,
4429 		(void *)&cmd_set_txtimes_name,
4430 		(void *)&cmd_set_txtimes_value,
4431 		NULL,
4432 	},
4433 };
4434 
4435 /* *** ADD/REMOVE ALL VLAN IDENTIFIERS TO/FROM A PORT VLAN RX FILTER *** */
4436 struct cmd_rx_vlan_filter_all_result {
4437 	cmdline_fixed_string_t rx_vlan;
4438 	cmdline_fixed_string_t what;
4439 	cmdline_fixed_string_t all;
4440 	portid_t port_id;
4441 };
4442 
4443 static void
4444 cmd_rx_vlan_filter_all_parsed(void *parsed_result,
4445 			      __rte_unused struct cmdline *cl,
4446 			      __rte_unused void *data)
4447 {
4448 	struct cmd_rx_vlan_filter_all_result *res = parsed_result;
4449 
4450 	if (!strcmp(res->what, "add"))
4451 		rx_vlan_all_filter_set(res->port_id, 1);
4452 	else
4453 		rx_vlan_all_filter_set(res->port_id, 0);
4454 }
4455 
4456 static cmdline_parse_token_string_t cmd_rx_vlan_filter_all_rx_vlan =
4457 	TOKEN_STRING_INITIALIZER(struct cmd_rx_vlan_filter_all_result,
4458 				 rx_vlan, "rx_vlan");
4459 static cmdline_parse_token_string_t cmd_rx_vlan_filter_all_what =
4460 	TOKEN_STRING_INITIALIZER(struct cmd_rx_vlan_filter_all_result,
4461 				 what, "add#rm");
4462 static cmdline_parse_token_string_t cmd_rx_vlan_filter_all_all =
4463 	TOKEN_STRING_INITIALIZER(struct cmd_rx_vlan_filter_all_result,
4464 				 all, "all");
4465 static cmdline_parse_token_num_t cmd_rx_vlan_filter_all_portid =
4466 	TOKEN_NUM_INITIALIZER(struct cmd_rx_vlan_filter_all_result,
4467 			      port_id, RTE_UINT16);
4468 
4469 static cmdline_parse_inst_t cmd_rx_vlan_filter_all = {
4470 	.f = cmd_rx_vlan_filter_all_parsed,
4471 	.data = NULL,
4472 	.help_str = "rx_vlan add|rm all <port_id>: "
4473 		"Add/Remove all identifiers to/from the set of VLAN "
4474 		"identifiers filtered by a port",
4475 	.tokens = {
4476 		(void *)&cmd_rx_vlan_filter_all_rx_vlan,
4477 		(void *)&cmd_rx_vlan_filter_all_what,
4478 		(void *)&cmd_rx_vlan_filter_all_all,
4479 		(void *)&cmd_rx_vlan_filter_all_portid,
4480 		NULL,
4481 	},
4482 };
4483 
4484 /* *** VLAN OFFLOAD SET ON A PORT *** */
4485 struct cmd_vlan_offload_result {
4486 	cmdline_fixed_string_t vlan;
4487 	cmdline_fixed_string_t set;
4488 	cmdline_fixed_string_t vlan_type;
4489 	cmdline_fixed_string_t what;
4490 	cmdline_fixed_string_t on;
4491 	cmdline_fixed_string_t port_id;
4492 };
4493 
4494 static void
4495 cmd_vlan_offload_parsed(void *parsed_result,
4496 			  __rte_unused struct cmdline *cl,
4497 			  __rte_unused void *data)
4498 {
4499 	int on;
4500 	struct cmd_vlan_offload_result *res = parsed_result;
4501 	char *str;
4502 	int i, len = 0;
4503 	portid_t port_id = 0;
4504 	unsigned int tmp;
4505 
4506 	str = res->port_id;
4507 	len = strnlen(str, STR_TOKEN_SIZE);
4508 	i = 0;
4509 	/* Get port_id first */
4510 	while(i < len){
4511 		if(str[i] == ',')
4512 			break;
4513 
4514 		i++;
4515 	}
4516 	str[i]='\0';
4517 	tmp = strtoul(str, NULL, 0);
4518 	/* If port_id greater that what portid_t can represent, return */
4519 	if(tmp >= RTE_MAX_ETHPORTS)
4520 		return;
4521 	port_id = (portid_t)tmp;
4522 
4523 	if (!strcmp(res->on, "on"))
4524 		on = 1;
4525 	else
4526 		on = 0;
4527 
4528 	if (!strcmp(res->what, "strip"))
4529 		rx_vlan_strip_set(port_id,  on);
4530 	else if(!strcmp(res->what, "stripq")){
4531 		uint16_t queue_id = 0;
4532 
4533 		/* No queue_id, return */
4534 		if(i + 1 >= len) {
4535 			fprintf(stderr, "must specify (port,queue_id)\n");
4536 			return;
4537 		}
4538 		tmp = strtoul(str + i + 1, NULL, 0);
4539 		/* If queue_id greater that what 16-bits can represent, return */
4540 		if(tmp > 0xffff)
4541 			return;
4542 
4543 		queue_id = (uint16_t)tmp;
4544 		rx_vlan_strip_set_on_queue(port_id, queue_id, on);
4545 	}
4546 	else if (!strcmp(res->what, "filter"))
4547 		rx_vlan_filter_set(port_id, on);
4548 	else if (!strcmp(res->what, "qinq_strip"))
4549 		rx_vlan_qinq_strip_set(port_id, on);
4550 	else
4551 		vlan_extend_set(port_id, on);
4552 
4553 	return;
4554 }
4555 
4556 static cmdline_parse_token_string_t cmd_vlan_offload_vlan =
4557 	TOKEN_STRING_INITIALIZER(struct cmd_vlan_offload_result,
4558 				 vlan, "vlan");
4559 static cmdline_parse_token_string_t cmd_vlan_offload_set =
4560 	TOKEN_STRING_INITIALIZER(struct cmd_vlan_offload_result,
4561 				 set, "set");
4562 static cmdline_parse_token_string_t cmd_vlan_offload_what =
4563 	TOKEN_STRING_INITIALIZER(struct cmd_vlan_offload_result,
4564 				what, "strip#filter#qinq_strip#extend#stripq");
4565 static cmdline_parse_token_string_t cmd_vlan_offload_on =
4566 	TOKEN_STRING_INITIALIZER(struct cmd_vlan_offload_result,
4567 			      on, "on#off");
4568 static cmdline_parse_token_string_t cmd_vlan_offload_portid =
4569 	TOKEN_STRING_INITIALIZER(struct cmd_vlan_offload_result,
4570 			      port_id, NULL);
4571 
4572 static cmdline_parse_inst_t cmd_vlan_offload = {
4573 	.f = cmd_vlan_offload_parsed,
4574 	.data = NULL,
4575 	.help_str = "vlan set strip|filter|qinq_strip|extend|stripq on|off "
4576 		"<port_id[,queue_id]>: "
4577 		"Strip/Filter/QinQ for rx side Extend for both rx/tx sides",
4578 	.tokens = {
4579 		(void *)&cmd_vlan_offload_vlan,
4580 		(void *)&cmd_vlan_offload_set,
4581 		(void *)&cmd_vlan_offload_what,
4582 		(void *)&cmd_vlan_offload_on,
4583 		(void *)&cmd_vlan_offload_portid,
4584 		NULL,
4585 	},
4586 };
4587 
4588 /* *** VLAN TPID SET ON A PORT *** */
4589 struct cmd_vlan_tpid_result {
4590 	cmdline_fixed_string_t vlan;
4591 	cmdline_fixed_string_t set;
4592 	cmdline_fixed_string_t vlan_type;
4593 	cmdline_fixed_string_t what;
4594 	uint16_t tp_id;
4595 	portid_t port_id;
4596 };
4597 
4598 static void
4599 cmd_vlan_tpid_parsed(void *parsed_result,
4600 			  __rte_unused struct cmdline *cl,
4601 			  __rte_unused void *data)
4602 {
4603 	struct cmd_vlan_tpid_result *res = parsed_result;
4604 	enum rte_vlan_type vlan_type;
4605 
4606 	if (!strcmp(res->vlan_type, "inner"))
4607 		vlan_type = RTE_ETH_VLAN_TYPE_INNER;
4608 	else if (!strcmp(res->vlan_type, "outer"))
4609 		vlan_type = RTE_ETH_VLAN_TYPE_OUTER;
4610 	else {
4611 		fprintf(stderr, "Unknown vlan type\n");
4612 		return;
4613 	}
4614 	vlan_tpid_set(res->port_id, vlan_type, res->tp_id);
4615 }
4616 
4617 static cmdline_parse_token_string_t cmd_vlan_tpid_vlan =
4618 	TOKEN_STRING_INITIALIZER(struct cmd_vlan_tpid_result,
4619 				 vlan, "vlan");
4620 static cmdline_parse_token_string_t cmd_vlan_tpid_set =
4621 	TOKEN_STRING_INITIALIZER(struct cmd_vlan_tpid_result,
4622 				 set, "set");
4623 static cmdline_parse_token_string_t cmd_vlan_type =
4624 	TOKEN_STRING_INITIALIZER(struct cmd_vlan_tpid_result,
4625 				 vlan_type, "inner#outer");
4626 static cmdline_parse_token_string_t cmd_vlan_tpid_what =
4627 	TOKEN_STRING_INITIALIZER(struct cmd_vlan_tpid_result,
4628 				 what, "tpid");
4629 static cmdline_parse_token_num_t cmd_vlan_tpid_tpid =
4630 	TOKEN_NUM_INITIALIZER(struct cmd_vlan_tpid_result,
4631 			      tp_id, RTE_UINT16);
4632 static cmdline_parse_token_num_t cmd_vlan_tpid_portid =
4633 	TOKEN_NUM_INITIALIZER(struct cmd_vlan_tpid_result,
4634 			      port_id, RTE_UINT16);
4635 
4636 static cmdline_parse_inst_t cmd_vlan_tpid = {
4637 	.f = cmd_vlan_tpid_parsed,
4638 	.data = NULL,
4639 	.help_str = "vlan set inner|outer tpid <tp_id> <port_id>: "
4640 		"Set the VLAN Ether type",
4641 	.tokens = {
4642 		(void *)&cmd_vlan_tpid_vlan,
4643 		(void *)&cmd_vlan_tpid_set,
4644 		(void *)&cmd_vlan_type,
4645 		(void *)&cmd_vlan_tpid_what,
4646 		(void *)&cmd_vlan_tpid_tpid,
4647 		(void *)&cmd_vlan_tpid_portid,
4648 		NULL,
4649 	},
4650 };
4651 
4652 /* *** ADD/REMOVE A VLAN IDENTIFIER TO/FROM A PORT VLAN RX FILTER *** */
4653 struct cmd_rx_vlan_filter_result {
4654 	cmdline_fixed_string_t rx_vlan;
4655 	cmdline_fixed_string_t what;
4656 	uint16_t vlan_id;
4657 	portid_t port_id;
4658 };
4659 
4660 static void
4661 cmd_rx_vlan_filter_parsed(void *parsed_result,
4662 			  __rte_unused struct cmdline *cl,
4663 			  __rte_unused void *data)
4664 {
4665 	struct cmd_rx_vlan_filter_result *res = parsed_result;
4666 
4667 	if (!strcmp(res->what, "add"))
4668 		rx_vft_set(res->port_id, res->vlan_id, 1);
4669 	else
4670 		rx_vft_set(res->port_id, res->vlan_id, 0);
4671 }
4672 
4673 static cmdline_parse_token_string_t cmd_rx_vlan_filter_rx_vlan =
4674 	TOKEN_STRING_INITIALIZER(struct cmd_rx_vlan_filter_result,
4675 				 rx_vlan, "rx_vlan");
4676 static cmdline_parse_token_string_t cmd_rx_vlan_filter_what =
4677 	TOKEN_STRING_INITIALIZER(struct cmd_rx_vlan_filter_result,
4678 				 what, "add#rm");
4679 static cmdline_parse_token_num_t cmd_rx_vlan_filter_vlanid =
4680 	TOKEN_NUM_INITIALIZER(struct cmd_rx_vlan_filter_result,
4681 			      vlan_id, RTE_UINT16);
4682 static cmdline_parse_token_num_t cmd_rx_vlan_filter_portid =
4683 	TOKEN_NUM_INITIALIZER(struct cmd_rx_vlan_filter_result,
4684 			      port_id, RTE_UINT16);
4685 
4686 static cmdline_parse_inst_t cmd_rx_vlan_filter = {
4687 	.f = cmd_rx_vlan_filter_parsed,
4688 	.data = NULL,
4689 	.help_str = "rx_vlan add|rm <vlan_id> <port_id>: "
4690 		"Add/Remove a VLAN identifier to/from the set of VLAN "
4691 		"identifiers filtered by a port",
4692 	.tokens = {
4693 		(void *)&cmd_rx_vlan_filter_rx_vlan,
4694 		(void *)&cmd_rx_vlan_filter_what,
4695 		(void *)&cmd_rx_vlan_filter_vlanid,
4696 		(void *)&cmd_rx_vlan_filter_portid,
4697 		NULL,
4698 	},
4699 };
4700 
4701 /* *** ENABLE HARDWARE INSERTION OF VLAN HEADER IN TX PACKETS *** */
4702 struct cmd_tx_vlan_set_result {
4703 	cmdline_fixed_string_t tx_vlan;
4704 	cmdline_fixed_string_t set;
4705 	portid_t port_id;
4706 	uint16_t vlan_id;
4707 };
4708 
4709 static void
4710 cmd_tx_vlan_set_parsed(void *parsed_result,
4711 		       __rte_unused struct cmdline *cl,
4712 		       __rte_unused void *data)
4713 {
4714 	struct cmd_tx_vlan_set_result *res = parsed_result;
4715 
4716 	if (port_id_is_invalid(res->port_id, ENABLED_WARN))
4717 		return;
4718 
4719 	if (!port_is_stopped(res->port_id)) {
4720 		fprintf(stderr, "Please stop port %d first\n", res->port_id);
4721 		return;
4722 	}
4723 
4724 	tx_vlan_set(res->port_id, res->vlan_id);
4725 
4726 	cmd_reconfig_device_queue(res->port_id, 1, 1);
4727 }
4728 
4729 static cmdline_parse_token_string_t cmd_tx_vlan_set_tx_vlan =
4730 	TOKEN_STRING_INITIALIZER(struct cmd_tx_vlan_set_result,
4731 				 tx_vlan, "tx_vlan");
4732 static cmdline_parse_token_string_t cmd_tx_vlan_set_set =
4733 	TOKEN_STRING_INITIALIZER(struct cmd_tx_vlan_set_result,
4734 				 set, "set");
4735 static cmdline_parse_token_num_t cmd_tx_vlan_set_portid =
4736 	TOKEN_NUM_INITIALIZER(struct cmd_tx_vlan_set_result,
4737 			      port_id, RTE_UINT16);
4738 static cmdline_parse_token_num_t cmd_tx_vlan_set_vlanid =
4739 	TOKEN_NUM_INITIALIZER(struct cmd_tx_vlan_set_result,
4740 			      vlan_id, RTE_UINT16);
4741 
4742 static cmdline_parse_inst_t cmd_tx_vlan_set = {
4743 	.f = cmd_tx_vlan_set_parsed,
4744 	.data = NULL,
4745 	.help_str = "tx_vlan set <port_id> <vlan_id>: "
4746 		"Enable hardware insertion of a single VLAN header "
4747 		"with a given TAG Identifier in packets sent on a port",
4748 	.tokens = {
4749 		(void *)&cmd_tx_vlan_set_tx_vlan,
4750 		(void *)&cmd_tx_vlan_set_set,
4751 		(void *)&cmd_tx_vlan_set_portid,
4752 		(void *)&cmd_tx_vlan_set_vlanid,
4753 		NULL,
4754 	},
4755 };
4756 
4757 /* *** ENABLE HARDWARE INSERTION OF Double VLAN HEADER IN TX PACKETS *** */
4758 struct cmd_tx_vlan_set_qinq_result {
4759 	cmdline_fixed_string_t tx_vlan;
4760 	cmdline_fixed_string_t set;
4761 	portid_t port_id;
4762 	uint16_t vlan_id;
4763 	uint16_t vlan_id_outer;
4764 };
4765 
4766 static void
4767 cmd_tx_vlan_set_qinq_parsed(void *parsed_result,
4768 			    __rte_unused struct cmdline *cl,
4769 			    __rte_unused void *data)
4770 {
4771 	struct cmd_tx_vlan_set_qinq_result *res = parsed_result;
4772 
4773 	if (port_id_is_invalid(res->port_id, ENABLED_WARN))
4774 		return;
4775 
4776 	if (!port_is_stopped(res->port_id)) {
4777 		fprintf(stderr, "Please stop port %d first\n", res->port_id);
4778 		return;
4779 	}
4780 
4781 	tx_qinq_set(res->port_id, res->vlan_id, res->vlan_id_outer);
4782 
4783 	cmd_reconfig_device_queue(res->port_id, 1, 1);
4784 }
4785 
4786 static cmdline_parse_token_string_t cmd_tx_vlan_set_qinq_tx_vlan =
4787 	TOKEN_STRING_INITIALIZER(struct cmd_tx_vlan_set_qinq_result,
4788 		tx_vlan, "tx_vlan");
4789 static cmdline_parse_token_string_t cmd_tx_vlan_set_qinq_set =
4790 	TOKEN_STRING_INITIALIZER(struct cmd_tx_vlan_set_qinq_result,
4791 		set, "set");
4792 static cmdline_parse_token_num_t cmd_tx_vlan_set_qinq_portid =
4793 	TOKEN_NUM_INITIALIZER(struct cmd_tx_vlan_set_qinq_result,
4794 		port_id, RTE_UINT16);
4795 static cmdline_parse_token_num_t cmd_tx_vlan_set_qinq_vlanid =
4796 	TOKEN_NUM_INITIALIZER(struct cmd_tx_vlan_set_qinq_result,
4797 		vlan_id, RTE_UINT16);
4798 static cmdline_parse_token_num_t cmd_tx_vlan_set_qinq_vlanid_outer =
4799 	TOKEN_NUM_INITIALIZER(struct cmd_tx_vlan_set_qinq_result,
4800 		vlan_id_outer, RTE_UINT16);
4801 
4802 static cmdline_parse_inst_t cmd_tx_vlan_set_qinq = {
4803 	.f = cmd_tx_vlan_set_qinq_parsed,
4804 	.data = NULL,
4805 	.help_str = "tx_vlan set <port_id> <vlan_id> <outer_vlan_id>: "
4806 		"Enable hardware insertion of double VLAN header "
4807 		"with given TAG Identifiers in packets sent on a port",
4808 	.tokens = {
4809 		(void *)&cmd_tx_vlan_set_qinq_tx_vlan,
4810 		(void *)&cmd_tx_vlan_set_qinq_set,
4811 		(void *)&cmd_tx_vlan_set_qinq_portid,
4812 		(void *)&cmd_tx_vlan_set_qinq_vlanid,
4813 		(void *)&cmd_tx_vlan_set_qinq_vlanid_outer,
4814 		NULL,
4815 	},
4816 };
4817 
4818 /* *** ENABLE/DISABLE PORT BASED TX VLAN INSERTION *** */
4819 struct cmd_tx_vlan_set_pvid_result {
4820 	cmdline_fixed_string_t tx_vlan;
4821 	cmdline_fixed_string_t set;
4822 	cmdline_fixed_string_t pvid;
4823 	portid_t port_id;
4824 	uint16_t vlan_id;
4825 	cmdline_fixed_string_t mode;
4826 };
4827 
4828 static void
4829 cmd_tx_vlan_set_pvid_parsed(void *parsed_result,
4830 			    __rte_unused struct cmdline *cl,
4831 			    __rte_unused void *data)
4832 {
4833 	struct cmd_tx_vlan_set_pvid_result *res = parsed_result;
4834 
4835 	if (strcmp(res->mode, "on") == 0)
4836 		tx_vlan_pvid_set(res->port_id, res->vlan_id, 1);
4837 	else
4838 		tx_vlan_pvid_set(res->port_id, res->vlan_id, 0);
4839 }
4840 
4841 static cmdline_parse_token_string_t cmd_tx_vlan_set_pvid_tx_vlan =
4842 	TOKEN_STRING_INITIALIZER(struct cmd_tx_vlan_set_pvid_result,
4843 				 tx_vlan, "tx_vlan");
4844 static cmdline_parse_token_string_t cmd_tx_vlan_set_pvid_set =
4845 	TOKEN_STRING_INITIALIZER(struct cmd_tx_vlan_set_pvid_result,
4846 				 set, "set");
4847 static cmdline_parse_token_string_t cmd_tx_vlan_set_pvid_pvid =
4848 	TOKEN_STRING_INITIALIZER(struct cmd_tx_vlan_set_pvid_result,
4849 				 pvid, "pvid");
4850 static cmdline_parse_token_num_t cmd_tx_vlan_set_pvid_port_id =
4851 	TOKEN_NUM_INITIALIZER(struct cmd_tx_vlan_set_pvid_result,
4852 			     port_id, RTE_UINT16);
4853 static cmdline_parse_token_num_t cmd_tx_vlan_set_pvid_vlan_id =
4854 	TOKEN_NUM_INITIALIZER(struct cmd_tx_vlan_set_pvid_result,
4855 			      vlan_id, RTE_UINT16);
4856 static cmdline_parse_token_string_t cmd_tx_vlan_set_pvid_mode =
4857 	TOKEN_STRING_INITIALIZER(struct cmd_tx_vlan_set_pvid_result,
4858 				 mode, "on#off");
4859 
4860 static cmdline_parse_inst_t cmd_tx_vlan_set_pvid = {
4861 	.f = cmd_tx_vlan_set_pvid_parsed,
4862 	.data = NULL,
4863 	.help_str = "tx_vlan set pvid <port_id> <vlan_id> on|off",
4864 	.tokens = {
4865 		(void *)&cmd_tx_vlan_set_pvid_tx_vlan,
4866 		(void *)&cmd_tx_vlan_set_pvid_set,
4867 		(void *)&cmd_tx_vlan_set_pvid_pvid,
4868 		(void *)&cmd_tx_vlan_set_pvid_port_id,
4869 		(void *)&cmd_tx_vlan_set_pvid_vlan_id,
4870 		(void *)&cmd_tx_vlan_set_pvid_mode,
4871 		NULL,
4872 	},
4873 };
4874 
4875 /* *** DISABLE HARDWARE INSERTION OF VLAN HEADER IN TX PACKETS *** */
4876 struct cmd_tx_vlan_reset_result {
4877 	cmdline_fixed_string_t tx_vlan;
4878 	cmdline_fixed_string_t reset;
4879 	portid_t port_id;
4880 };
4881 
4882 static void
4883 cmd_tx_vlan_reset_parsed(void *parsed_result,
4884 			 __rte_unused struct cmdline *cl,
4885 			 __rte_unused void *data)
4886 {
4887 	struct cmd_tx_vlan_reset_result *res = parsed_result;
4888 
4889 	if (port_id_is_invalid(res->port_id, ENABLED_WARN))
4890 		return;
4891 
4892 	if (!port_is_stopped(res->port_id)) {
4893 		fprintf(stderr, "Please stop port %d first\n", res->port_id);
4894 		return;
4895 	}
4896 
4897 	tx_vlan_reset(res->port_id);
4898 
4899 	cmd_reconfig_device_queue(res->port_id, 1, 1);
4900 }
4901 
4902 static cmdline_parse_token_string_t cmd_tx_vlan_reset_tx_vlan =
4903 	TOKEN_STRING_INITIALIZER(struct cmd_tx_vlan_reset_result,
4904 				 tx_vlan, "tx_vlan");
4905 static cmdline_parse_token_string_t cmd_tx_vlan_reset_reset =
4906 	TOKEN_STRING_INITIALIZER(struct cmd_tx_vlan_reset_result,
4907 				 reset, "reset");
4908 static cmdline_parse_token_num_t cmd_tx_vlan_reset_portid =
4909 	TOKEN_NUM_INITIALIZER(struct cmd_tx_vlan_reset_result,
4910 			      port_id, RTE_UINT16);
4911 
4912 static cmdline_parse_inst_t cmd_tx_vlan_reset = {
4913 	.f = cmd_tx_vlan_reset_parsed,
4914 	.data = NULL,
4915 	.help_str = "tx_vlan reset <port_id>: Disable hardware insertion of a "
4916 		"VLAN header in packets sent on a port",
4917 	.tokens = {
4918 		(void *)&cmd_tx_vlan_reset_tx_vlan,
4919 		(void *)&cmd_tx_vlan_reset_reset,
4920 		(void *)&cmd_tx_vlan_reset_portid,
4921 		NULL,
4922 	},
4923 };
4924 
4925 
4926 /* *** ENABLE HARDWARE INSERTION OF CHECKSUM IN TX PACKETS *** */
4927 struct cmd_csum_result {
4928 	cmdline_fixed_string_t csum;
4929 	cmdline_fixed_string_t mode;
4930 	cmdline_fixed_string_t proto;
4931 	cmdline_fixed_string_t hwsw;
4932 	portid_t port_id;
4933 };
4934 
4935 static void
4936 csum_show(int port_id)
4937 {
4938 	struct rte_eth_dev_info dev_info;
4939 	uint64_t tx_offloads;
4940 	int ret;
4941 
4942 	tx_offloads = ports[port_id].dev_conf.txmode.offloads;
4943 	printf("Parse tunnel is %s\n",
4944 		(ports[port_id].parse_tunnel) ? "on" : "off");
4945 	printf("IP checksum offload is %s\n",
4946 		(tx_offloads & RTE_ETH_TX_OFFLOAD_IPV4_CKSUM) ? "hw" : "sw");
4947 	printf("UDP checksum offload is %s\n",
4948 		(tx_offloads & RTE_ETH_TX_OFFLOAD_UDP_CKSUM) ? "hw" : "sw");
4949 	printf("TCP checksum offload is %s\n",
4950 		(tx_offloads & RTE_ETH_TX_OFFLOAD_TCP_CKSUM) ? "hw" : "sw");
4951 	printf("SCTP checksum offload is %s\n",
4952 		(tx_offloads & RTE_ETH_TX_OFFLOAD_SCTP_CKSUM) ? "hw" : "sw");
4953 	printf("Outer-Ip checksum offload is %s\n",
4954 		(tx_offloads & RTE_ETH_TX_OFFLOAD_OUTER_IPV4_CKSUM) ? "hw" : "sw");
4955 	printf("Outer-Udp checksum offload is %s\n",
4956 		(tx_offloads & RTE_ETH_TX_OFFLOAD_OUTER_UDP_CKSUM) ? "hw" : "sw");
4957 
4958 	/* display warnings if configuration is not supported by the NIC */
4959 	ret = eth_dev_info_get_print_err(port_id, &dev_info);
4960 	if (ret != 0)
4961 		return;
4962 
4963 	if ((tx_offloads & RTE_ETH_TX_OFFLOAD_IPV4_CKSUM) &&
4964 		(dev_info.tx_offload_capa & RTE_ETH_TX_OFFLOAD_IPV4_CKSUM) == 0) {
4965 		fprintf(stderr,
4966 			"Warning: hardware IP checksum enabled but not supported by port %d\n",
4967 			port_id);
4968 	}
4969 	if ((tx_offloads & RTE_ETH_TX_OFFLOAD_UDP_CKSUM) &&
4970 		(dev_info.tx_offload_capa & RTE_ETH_TX_OFFLOAD_UDP_CKSUM) == 0) {
4971 		fprintf(stderr,
4972 			"Warning: hardware UDP checksum enabled but not supported by port %d\n",
4973 			port_id);
4974 	}
4975 	if ((tx_offloads & RTE_ETH_TX_OFFLOAD_TCP_CKSUM) &&
4976 		(dev_info.tx_offload_capa & RTE_ETH_TX_OFFLOAD_TCP_CKSUM) == 0) {
4977 		fprintf(stderr,
4978 			"Warning: hardware TCP checksum enabled but not supported by port %d\n",
4979 			port_id);
4980 	}
4981 	if ((tx_offloads & RTE_ETH_TX_OFFLOAD_SCTP_CKSUM) &&
4982 		(dev_info.tx_offload_capa & RTE_ETH_TX_OFFLOAD_SCTP_CKSUM) == 0) {
4983 		fprintf(stderr,
4984 			"Warning: hardware SCTP checksum enabled but not supported by port %d\n",
4985 			port_id);
4986 	}
4987 	if ((tx_offloads & RTE_ETH_TX_OFFLOAD_OUTER_IPV4_CKSUM) &&
4988 		(dev_info.tx_offload_capa & RTE_ETH_TX_OFFLOAD_OUTER_IPV4_CKSUM) == 0) {
4989 		fprintf(stderr,
4990 			"Warning: hardware outer IP checksum enabled but not supported by port %d\n",
4991 			port_id);
4992 	}
4993 	if ((tx_offloads & RTE_ETH_TX_OFFLOAD_OUTER_UDP_CKSUM) &&
4994 		(dev_info.tx_offload_capa & RTE_ETH_TX_OFFLOAD_OUTER_UDP_CKSUM)
4995 			== 0) {
4996 		fprintf(stderr,
4997 			"Warning: hardware outer UDP checksum enabled but not supported by port %d\n",
4998 			port_id);
4999 	}
5000 }
5001 
5002 static void
5003 cmd_config_queue_tx_offloads(struct rte_port *port)
5004 {
5005 	int k;
5006 
5007 	/* Apply queue tx offloads configuration */
5008 	for (k = 0; k < port->dev_info.max_tx_queues; k++)
5009 		port->txq[k].conf.offloads =
5010 			port->dev_conf.txmode.offloads;
5011 }
5012 
5013 static void
5014 cmd_csum_parsed(void *parsed_result,
5015 		       __rte_unused struct cmdline *cl,
5016 		       __rte_unused void *data)
5017 {
5018 	struct cmd_csum_result *res = parsed_result;
5019 	int hw = 0;
5020 	uint64_t csum_offloads = 0;
5021 	struct rte_eth_dev_info dev_info;
5022 	int ret;
5023 
5024 	if (port_id_is_invalid(res->port_id, ENABLED_WARN)) {
5025 		fprintf(stderr, "invalid port %d\n", res->port_id);
5026 		return;
5027 	}
5028 	if (!port_is_stopped(res->port_id)) {
5029 		fprintf(stderr, "Please stop port %d first\n", res->port_id);
5030 		return;
5031 	}
5032 
5033 	ret = eth_dev_info_get_print_err(res->port_id, &dev_info);
5034 	if (ret != 0)
5035 		return;
5036 
5037 	if (!strcmp(res->mode, "set")) {
5038 
5039 		if (!strcmp(res->hwsw, "hw"))
5040 			hw = 1;
5041 
5042 		if (!strcmp(res->proto, "ip")) {
5043 			if (hw == 0 || (dev_info.tx_offload_capa &
5044 						RTE_ETH_TX_OFFLOAD_IPV4_CKSUM)) {
5045 				csum_offloads |= RTE_ETH_TX_OFFLOAD_IPV4_CKSUM;
5046 			} else {
5047 				fprintf(stderr,
5048 					"IP checksum offload is not supported by port %u\n",
5049 					res->port_id);
5050 			}
5051 		} else if (!strcmp(res->proto, "udp")) {
5052 			if (hw == 0 || (dev_info.tx_offload_capa &
5053 						RTE_ETH_TX_OFFLOAD_UDP_CKSUM)) {
5054 				csum_offloads |= RTE_ETH_TX_OFFLOAD_UDP_CKSUM;
5055 			} else {
5056 				fprintf(stderr,
5057 					"UDP checksum offload is not supported by port %u\n",
5058 					res->port_id);
5059 			}
5060 		} else if (!strcmp(res->proto, "tcp")) {
5061 			if (hw == 0 || (dev_info.tx_offload_capa &
5062 						RTE_ETH_TX_OFFLOAD_TCP_CKSUM)) {
5063 				csum_offloads |= RTE_ETH_TX_OFFLOAD_TCP_CKSUM;
5064 			} else {
5065 				fprintf(stderr,
5066 					"TCP checksum offload is not supported by port %u\n",
5067 					res->port_id);
5068 			}
5069 		} else if (!strcmp(res->proto, "sctp")) {
5070 			if (hw == 0 || (dev_info.tx_offload_capa &
5071 						RTE_ETH_TX_OFFLOAD_SCTP_CKSUM)) {
5072 				csum_offloads |= RTE_ETH_TX_OFFLOAD_SCTP_CKSUM;
5073 			} else {
5074 				fprintf(stderr,
5075 					"SCTP checksum offload is not supported by port %u\n",
5076 					res->port_id);
5077 			}
5078 		} else if (!strcmp(res->proto, "outer-ip")) {
5079 			if (hw == 0 || (dev_info.tx_offload_capa &
5080 					RTE_ETH_TX_OFFLOAD_OUTER_IPV4_CKSUM)) {
5081 				csum_offloads |=
5082 						RTE_ETH_TX_OFFLOAD_OUTER_IPV4_CKSUM;
5083 			} else {
5084 				fprintf(stderr,
5085 					"Outer IP checksum offload is not supported by port %u\n",
5086 					res->port_id);
5087 			}
5088 		} else if (!strcmp(res->proto, "outer-udp")) {
5089 			if (hw == 0 || (dev_info.tx_offload_capa &
5090 					RTE_ETH_TX_OFFLOAD_OUTER_UDP_CKSUM)) {
5091 				csum_offloads |=
5092 						RTE_ETH_TX_OFFLOAD_OUTER_UDP_CKSUM;
5093 			} else {
5094 				fprintf(stderr,
5095 					"Outer UDP checksum offload is not supported by port %u\n",
5096 					res->port_id);
5097 			}
5098 		}
5099 
5100 		if (hw) {
5101 			ports[res->port_id].dev_conf.txmode.offloads |=
5102 							csum_offloads;
5103 		} else {
5104 			ports[res->port_id].dev_conf.txmode.offloads &=
5105 							(~csum_offloads);
5106 		}
5107 		cmd_config_queue_tx_offloads(&ports[res->port_id]);
5108 	}
5109 	csum_show(res->port_id);
5110 
5111 	cmd_reconfig_device_queue(res->port_id, 1, 1);
5112 }
5113 
5114 static cmdline_parse_token_string_t cmd_csum_csum =
5115 	TOKEN_STRING_INITIALIZER(struct cmd_csum_result,
5116 				csum, "csum");
5117 static cmdline_parse_token_string_t cmd_csum_mode =
5118 	TOKEN_STRING_INITIALIZER(struct cmd_csum_result,
5119 				mode, "set");
5120 static cmdline_parse_token_string_t cmd_csum_proto =
5121 	TOKEN_STRING_INITIALIZER(struct cmd_csum_result,
5122 				proto, "ip#tcp#udp#sctp#outer-ip#outer-udp");
5123 static cmdline_parse_token_string_t cmd_csum_hwsw =
5124 	TOKEN_STRING_INITIALIZER(struct cmd_csum_result,
5125 				hwsw, "hw#sw");
5126 static cmdline_parse_token_num_t cmd_csum_portid =
5127 	TOKEN_NUM_INITIALIZER(struct cmd_csum_result,
5128 				port_id, RTE_UINT16);
5129 
5130 static cmdline_parse_inst_t cmd_csum_set = {
5131 	.f = cmd_csum_parsed,
5132 	.data = NULL,
5133 	.help_str = "csum set ip|tcp|udp|sctp|outer-ip|outer-udp hw|sw <port_id>: "
5134 		"Enable/Disable hardware calculation of L3/L4 checksum when "
5135 		"using csum forward engine",
5136 	.tokens = {
5137 		(void *)&cmd_csum_csum,
5138 		(void *)&cmd_csum_mode,
5139 		(void *)&cmd_csum_proto,
5140 		(void *)&cmd_csum_hwsw,
5141 		(void *)&cmd_csum_portid,
5142 		NULL,
5143 	},
5144 };
5145 
5146 static cmdline_parse_token_string_t cmd_csum_mode_show =
5147 	TOKEN_STRING_INITIALIZER(struct cmd_csum_result,
5148 				mode, "show");
5149 
5150 static cmdline_parse_inst_t cmd_csum_show = {
5151 	.f = cmd_csum_parsed,
5152 	.data = NULL,
5153 	.help_str = "csum show <port_id>: Show checksum offload configuration",
5154 	.tokens = {
5155 		(void *)&cmd_csum_csum,
5156 		(void *)&cmd_csum_mode_show,
5157 		(void *)&cmd_csum_portid,
5158 		NULL,
5159 	},
5160 };
5161 
5162 /* Enable/disable tunnel parsing */
5163 struct cmd_csum_tunnel_result {
5164 	cmdline_fixed_string_t csum;
5165 	cmdline_fixed_string_t parse;
5166 	cmdline_fixed_string_t onoff;
5167 	portid_t port_id;
5168 };
5169 
5170 static void
5171 cmd_csum_tunnel_parsed(void *parsed_result,
5172 		       __rte_unused struct cmdline *cl,
5173 		       __rte_unused void *data)
5174 {
5175 	struct cmd_csum_tunnel_result *res = parsed_result;
5176 
5177 	if (port_id_is_invalid(res->port_id, ENABLED_WARN))
5178 		return;
5179 
5180 	if (!strcmp(res->onoff, "on"))
5181 		ports[res->port_id].parse_tunnel = 1;
5182 	else
5183 		ports[res->port_id].parse_tunnel = 0;
5184 
5185 	csum_show(res->port_id);
5186 }
5187 
5188 static cmdline_parse_token_string_t cmd_csum_tunnel_csum =
5189 	TOKEN_STRING_INITIALIZER(struct cmd_csum_tunnel_result,
5190 				csum, "csum");
5191 static cmdline_parse_token_string_t cmd_csum_tunnel_parse =
5192 	TOKEN_STRING_INITIALIZER(struct cmd_csum_tunnel_result,
5193 				parse, "parse-tunnel");
5194 static cmdline_parse_token_string_t cmd_csum_tunnel_onoff =
5195 	TOKEN_STRING_INITIALIZER(struct cmd_csum_tunnel_result,
5196 				onoff, "on#off");
5197 static cmdline_parse_token_num_t cmd_csum_tunnel_portid =
5198 	TOKEN_NUM_INITIALIZER(struct cmd_csum_tunnel_result,
5199 				port_id, RTE_UINT16);
5200 
5201 static cmdline_parse_inst_t cmd_csum_tunnel = {
5202 	.f = cmd_csum_tunnel_parsed,
5203 	.data = NULL,
5204 	.help_str = "csum parse-tunnel on|off <port_id>: "
5205 		"Enable/Disable parsing of tunnels for csum engine",
5206 	.tokens = {
5207 		(void *)&cmd_csum_tunnel_csum,
5208 		(void *)&cmd_csum_tunnel_parse,
5209 		(void *)&cmd_csum_tunnel_onoff,
5210 		(void *)&cmd_csum_tunnel_portid,
5211 		NULL,
5212 	},
5213 };
5214 
5215 struct cmd_csum_mac_swap_result {
5216 	cmdline_fixed_string_t csum;
5217 	cmdline_fixed_string_t parse;
5218 	cmdline_fixed_string_t onoff;
5219 	portid_t port_id;
5220 };
5221 
5222 static void
5223 cmd_csum_mac_swap_parsed(void *parsed_result,
5224 		       __rte_unused struct cmdline *cl,
5225 		       __rte_unused void *data)
5226 {
5227 	struct cmd_csum_mac_swap_result *res = parsed_result;
5228 
5229 	if (port_id_is_invalid(res->port_id, ENABLED_WARN))
5230 		return;
5231 	if (strcmp(res->onoff, "on") == 0)
5232 		ports[res->port_id].fwd_mac_swap = 1;
5233 	else
5234 		ports[res->port_id].fwd_mac_swap = 0;
5235 }
5236 
5237 static cmdline_parse_token_string_t cmd_csum_mac_swap_csum =
5238 	TOKEN_STRING_INITIALIZER(struct cmd_csum_mac_swap_result,
5239 				 csum, "csum");
5240 static cmdline_parse_token_string_t cmd_csum_mac_swap_parse =
5241 	TOKEN_STRING_INITIALIZER(struct cmd_csum_mac_swap_result,
5242 				 parse, "mac-swap");
5243 static cmdline_parse_token_string_t cmd_csum_mac_swap_onoff =
5244 	TOKEN_STRING_INITIALIZER(struct cmd_csum_mac_swap_result,
5245 				 onoff, "on#off");
5246 static cmdline_parse_token_num_t cmd_csum_mac_swap_portid =
5247 	TOKEN_NUM_INITIALIZER(struct cmd_csum_mac_swap_result,
5248 			      port_id, RTE_UINT16);
5249 
5250 static cmdline_parse_inst_t cmd_csum_mac_swap = {
5251 	.f = cmd_csum_mac_swap_parsed,
5252 	.data = NULL,
5253 	.help_str = "csum mac-swap on|off <port_id>: "
5254 		    "Enable/Disable forward mac address swap",
5255 	.tokens = {
5256 		(void *)&cmd_csum_mac_swap_csum,
5257 		(void *)&cmd_csum_mac_swap_parse,
5258 		(void *)&cmd_csum_mac_swap_onoff,
5259 		(void *)&cmd_csum_mac_swap_portid,
5260 		NULL,
5261 	},
5262 };
5263 
5264 /* *** ENABLE HARDWARE SEGMENTATION IN TX NON-TUNNELED PACKETS *** */
5265 struct cmd_tso_set_result {
5266 	cmdline_fixed_string_t tso;
5267 	cmdline_fixed_string_t mode;
5268 	uint16_t tso_segsz;
5269 	portid_t port_id;
5270 };
5271 
5272 static void
5273 cmd_tso_set_parsed(void *parsed_result,
5274 		       __rte_unused struct cmdline *cl,
5275 		       __rte_unused void *data)
5276 {
5277 	struct cmd_tso_set_result *res = parsed_result;
5278 	struct rte_eth_dev_info dev_info;
5279 	uint64_t offloads;
5280 	int ret;
5281 
5282 	if (port_id_is_invalid(res->port_id, ENABLED_WARN))
5283 		return;
5284 	if (!port_is_stopped(res->port_id)) {
5285 		fprintf(stderr, "Please stop port %d first\n", res->port_id);
5286 		return;
5287 	}
5288 
5289 	if (!strcmp(res->mode, "set"))
5290 		ports[res->port_id].tso_segsz = res->tso_segsz;
5291 
5292 	ret = eth_dev_info_get_print_err(res->port_id, &dev_info);
5293 	if (ret != 0)
5294 		return;
5295 
5296 	if (ports[res->port_id].tso_segsz != 0) {
5297 		if ((dev_info.tx_offload_capa & (RTE_ETH_TX_OFFLOAD_TCP_TSO |
5298 				RTE_ETH_TX_OFFLOAD_UDP_TSO)) == 0) {
5299 			fprintf(stderr, "Error: both TSO and UFO are not supported by port %d\n",
5300 				res->port_id);
5301 			return;
5302 		}
5303 		/* display warnings if configuration is not supported by the NIC */
5304 		if ((dev_info.tx_offload_capa & RTE_ETH_TX_OFFLOAD_TCP_TSO) == 0)
5305 			printf("Warning: port %d doesn't support TSO\n", res->port_id);
5306 		if ((dev_info.tx_offload_capa & RTE_ETH_TX_OFFLOAD_UDP_TSO) == 0)
5307 			printf("Warning: port %d doesn't support UFO\n", res->port_id);
5308 	}
5309 
5310 	if (ports[res->port_id].tso_segsz == 0) {
5311 		ports[res->port_id].dev_conf.txmode.offloads &=
5312 			~(RTE_ETH_TX_OFFLOAD_TCP_TSO | RTE_ETH_TX_OFFLOAD_UDP_TSO);
5313 		printf("TSO and UFO for non-tunneled packets is disabled\n");
5314 	} else {
5315 		offloads = (dev_info.tx_offload_capa & RTE_ETH_TX_OFFLOAD_TCP_TSO) ?
5316 					RTE_ETH_TX_OFFLOAD_TCP_TSO : 0;
5317 		offloads |= (dev_info.tx_offload_capa & RTE_ETH_TX_OFFLOAD_UDP_TSO) ?
5318 					RTE_ETH_TX_OFFLOAD_UDP_TSO : 0;
5319 		ports[res->port_id].dev_conf.txmode.offloads |= offloads;
5320 		printf("segment size for non-tunneled packets is %d\n",
5321 			ports[res->port_id].tso_segsz);
5322 	}
5323 	cmd_config_queue_tx_offloads(&ports[res->port_id]);
5324 	cmd_reconfig_device_queue(res->port_id, 1, 1);
5325 }
5326 
5327 static cmdline_parse_token_string_t cmd_tso_set_tso =
5328 	TOKEN_STRING_INITIALIZER(struct cmd_tso_set_result,
5329 				tso, "tso");
5330 static cmdline_parse_token_string_t cmd_tso_set_mode =
5331 	TOKEN_STRING_INITIALIZER(struct cmd_tso_set_result,
5332 				mode, "set");
5333 static cmdline_parse_token_num_t cmd_tso_set_tso_segsz =
5334 	TOKEN_NUM_INITIALIZER(struct cmd_tso_set_result,
5335 				tso_segsz, RTE_UINT16);
5336 static cmdline_parse_token_num_t cmd_tso_set_portid =
5337 	TOKEN_NUM_INITIALIZER(struct cmd_tso_set_result,
5338 				port_id, RTE_UINT16);
5339 
5340 static cmdline_parse_inst_t cmd_tso_set = {
5341 	.f = cmd_tso_set_parsed,
5342 	.data = NULL,
5343 	.help_str = "tso set <tso_segsz> <port_id>: "
5344 		"Set TSO segment size of non-tunneled packets for csum engine "
5345 		"(0 to disable)",
5346 	.tokens = {
5347 		(void *)&cmd_tso_set_tso,
5348 		(void *)&cmd_tso_set_mode,
5349 		(void *)&cmd_tso_set_tso_segsz,
5350 		(void *)&cmd_tso_set_portid,
5351 		NULL,
5352 	},
5353 };
5354 
5355 static cmdline_parse_token_string_t cmd_tso_show_mode =
5356 	TOKEN_STRING_INITIALIZER(struct cmd_tso_set_result,
5357 				mode, "show");
5358 
5359 
5360 static cmdline_parse_inst_t cmd_tso_show = {
5361 	.f = cmd_tso_set_parsed,
5362 	.data = NULL,
5363 	.help_str = "tso show <port_id>: "
5364 		"Show TSO segment size of non-tunneled packets for csum engine",
5365 	.tokens = {
5366 		(void *)&cmd_tso_set_tso,
5367 		(void *)&cmd_tso_show_mode,
5368 		(void *)&cmd_tso_set_portid,
5369 		NULL,
5370 	},
5371 };
5372 
5373 /* *** ENABLE HARDWARE SEGMENTATION IN TX TUNNELED PACKETS *** */
5374 struct cmd_tunnel_tso_set_result {
5375 	cmdline_fixed_string_t tso;
5376 	cmdline_fixed_string_t mode;
5377 	uint16_t tso_segsz;
5378 	portid_t port_id;
5379 };
5380 
5381 static void
5382 check_tunnel_tso_nic_support(portid_t port_id, uint64_t tx_offload_capa)
5383 {
5384 	if (!(tx_offload_capa & RTE_ETH_TX_OFFLOAD_VXLAN_TNL_TSO))
5385 		printf("Warning: VXLAN TUNNEL TSO not supported therefore not enabled for port %d\n",
5386 			port_id);
5387 	if (!(tx_offload_capa & RTE_ETH_TX_OFFLOAD_GRE_TNL_TSO))
5388 		printf("Warning: GRE TUNNEL TSO not supported therefore not enabled for port %d\n",
5389 			port_id);
5390 	if (!(tx_offload_capa & RTE_ETH_TX_OFFLOAD_IPIP_TNL_TSO))
5391 		printf("Warning: IPIP TUNNEL TSO not supported therefore not enabled for port %d\n",
5392 			port_id);
5393 	if (!(tx_offload_capa & RTE_ETH_TX_OFFLOAD_GENEVE_TNL_TSO))
5394 		printf("Warning: GENEVE TUNNEL TSO not supported therefore not enabled for port %d\n",
5395 			port_id);
5396 	if (!(tx_offload_capa & RTE_ETH_TX_OFFLOAD_IP_TNL_TSO))
5397 		printf("Warning: IP TUNNEL TSO not supported therefore not enabled for port %d\n",
5398 			port_id);
5399 	if (!(tx_offload_capa & RTE_ETH_TX_OFFLOAD_UDP_TNL_TSO))
5400 		printf("Warning: UDP TUNNEL TSO not supported therefore not enabled for port %d\n",
5401 			port_id);
5402 }
5403 
5404 static void
5405 cmd_tunnel_tso_set_parsed(void *parsed_result,
5406 			  __rte_unused struct cmdline *cl,
5407 			  __rte_unused void *data)
5408 {
5409 	struct cmd_tunnel_tso_set_result *res = parsed_result;
5410 	struct rte_eth_dev_info dev_info;
5411 	uint64_t all_tunnel_tso = RTE_ETH_TX_OFFLOAD_VXLAN_TNL_TSO |
5412 				RTE_ETH_TX_OFFLOAD_GRE_TNL_TSO |
5413 				RTE_ETH_TX_OFFLOAD_IPIP_TNL_TSO |
5414 				RTE_ETH_TX_OFFLOAD_GENEVE_TNL_TSO |
5415 				RTE_ETH_TX_OFFLOAD_IP_TNL_TSO |
5416 				RTE_ETH_TX_OFFLOAD_UDP_TNL_TSO;
5417 	int ret;
5418 
5419 	if (port_id_is_invalid(res->port_id, ENABLED_WARN))
5420 		return;
5421 	if (!port_is_stopped(res->port_id)) {
5422 		fprintf(stderr, "Please stop port %d first\n", res->port_id);
5423 		return;
5424 	}
5425 
5426 	if (!strcmp(res->mode, "set"))
5427 		ports[res->port_id].tunnel_tso_segsz = res->tso_segsz;
5428 
5429 	if (ports[res->port_id].tunnel_tso_segsz == 0) {
5430 		ports[res->port_id].dev_conf.txmode.offloads &= ~all_tunnel_tso;
5431 		printf("TSO for tunneled packets is disabled\n");
5432 	} else {
5433 		ret = eth_dev_info_get_print_err(res->port_id, &dev_info);
5434 		if (ret != 0)
5435 			return;
5436 
5437 		if ((all_tunnel_tso & dev_info.tx_offload_capa) == 0) {
5438 			fprintf(stderr, "Error: port=%u don't support tunnel TSO offloads.\n",
5439 				res->port_id);
5440 			return;
5441 		}
5442 
5443 		/* Below conditions are needed to make it work:
5444 		 * (1) tunnel TSO is supported by the NIC;
5445 		 * (2) "csum parse_tunnel" must be set so that tunneled pkts
5446 		 * are recognized;
5447 		 * (3) for tunneled pkts with outer L3 of IPv4,
5448 		 * "csum set outer-ip" must be set to hw, because after tso,
5449 		 * total_len of outer IP header is changed, and the checksum
5450 		 * of outer IP header calculated by sw should be wrong; that
5451 		 * is not necessary for IPv6 tunneled pkts because there's no
5452 		 * checksum in IP header anymore.
5453 		 */
5454 		if (!ports[res->port_id].parse_tunnel) {
5455 			fprintf(stderr,
5456 				"Error: csum parse_tunnel must be set so that tunneled packets are recognized\n");
5457 			return;
5458 		}
5459 		if (!(ports[res->port_id].dev_conf.txmode.offloads &
5460 		      RTE_ETH_TX_OFFLOAD_OUTER_IPV4_CKSUM)) {
5461 			fprintf(stderr,
5462 				"Error: csum set outer-ip must be set to hw if outer L3 is IPv4; not necessary for IPv6\n");
5463 			return;
5464 		}
5465 
5466 		check_tunnel_tso_nic_support(res->port_id, dev_info.tx_offload_capa);
5467 		ports[res->port_id].dev_conf.txmode.offloads |=
5468 				(all_tunnel_tso & dev_info.tx_offload_capa);
5469 		printf("TSO segment size for tunneled packets is %d\n",
5470 			ports[res->port_id].tunnel_tso_segsz);
5471 	}
5472 
5473 	cmd_config_queue_tx_offloads(&ports[res->port_id]);
5474 	cmd_reconfig_device_queue(res->port_id, 1, 1);
5475 }
5476 
5477 static cmdline_parse_token_string_t cmd_tunnel_tso_set_tso =
5478 	TOKEN_STRING_INITIALIZER(struct cmd_tunnel_tso_set_result,
5479 				tso, "tunnel_tso");
5480 static cmdline_parse_token_string_t cmd_tunnel_tso_set_mode =
5481 	TOKEN_STRING_INITIALIZER(struct cmd_tunnel_tso_set_result,
5482 				mode, "set");
5483 static cmdline_parse_token_num_t cmd_tunnel_tso_set_tso_segsz =
5484 	TOKEN_NUM_INITIALIZER(struct cmd_tunnel_tso_set_result,
5485 				tso_segsz, RTE_UINT16);
5486 static cmdline_parse_token_num_t cmd_tunnel_tso_set_portid =
5487 	TOKEN_NUM_INITIALIZER(struct cmd_tunnel_tso_set_result,
5488 				port_id, RTE_UINT16);
5489 
5490 static cmdline_parse_inst_t cmd_tunnel_tso_set = {
5491 	.f = cmd_tunnel_tso_set_parsed,
5492 	.data = NULL,
5493 	.help_str = "tunnel_tso set <tso_segsz> <port_id>: "
5494 		"Set TSO segment size of tunneled packets for csum engine "
5495 		"(0 to disable)",
5496 	.tokens = {
5497 		(void *)&cmd_tunnel_tso_set_tso,
5498 		(void *)&cmd_tunnel_tso_set_mode,
5499 		(void *)&cmd_tunnel_tso_set_tso_segsz,
5500 		(void *)&cmd_tunnel_tso_set_portid,
5501 		NULL,
5502 	},
5503 };
5504 
5505 static cmdline_parse_token_string_t cmd_tunnel_tso_show_mode =
5506 	TOKEN_STRING_INITIALIZER(struct cmd_tunnel_tso_set_result,
5507 				mode, "show");
5508 
5509 
5510 static cmdline_parse_inst_t cmd_tunnel_tso_show = {
5511 	.f = cmd_tunnel_tso_set_parsed,
5512 	.data = NULL,
5513 	.help_str = "tunnel_tso show <port_id> "
5514 		"Show TSO segment size of tunneled packets for csum engine",
5515 	.tokens = {
5516 		(void *)&cmd_tunnel_tso_set_tso,
5517 		(void *)&cmd_tunnel_tso_show_mode,
5518 		(void *)&cmd_tunnel_tso_set_portid,
5519 		NULL,
5520 	},
5521 };
5522 
5523 #ifdef RTE_LIB_GRO
5524 /* *** SET GRO FOR A PORT *** */
5525 struct cmd_gro_enable_result {
5526 	cmdline_fixed_string_t cmd_set;
5527 	cmdline_fixed_string_t cmd_port;
5528 	cmdline_fixed_string_t cmd_keyword;
5529 	cmdline_fixed_string_t cmd_onoff;
5530 	portid_t cmd_pid;
5531 };
5532 
5533 static void
5534 cmd_gro_enable_parsed(void *parsed_result,
5535 		__rte_unused struct cmdline *cl,
5536 		__rte_unused void *data)
5537 {
5538 	struct cmd_gro_enable_result *res;
5539 
5540 	res = parsed_result;
5541 	if (!strcmp(res->cmd_keyword, "gro"))
5542 		setup_gro(res->cmd_onoff, res->cmd_pid);
5543 }
5544 
5545 static cmdline_parse_token_string_t cmd_gro_enable_set =
5546 	TOKEN_STRING_INITIALIZER(struct cmd_gro_enable_result,
5547 			cmd_set, "set");
5548 static cmdline_parse_token_string_t cmd_gro_enable_port =
5549 	TOKEN_STRING_INITIALIZER(struct cmd_gro_enable_result,
5550 			cmd_keyword, "port");
5551 static cmdline_parse_token_num_t cmd_gro_enable_pid =
5552 	TOKEN_NUM_INITIALIZER(struct cmd_gro_enable_result,
5553 			cmd_pid, RTE_UINT16);
5554 static cmdline_parse_token_string_t cmd_gro_enable_keyword =
5555 	TOKEN_STRING_INITIALIZER(struct cmd_gro_enable_result,
5556 			cmd_keyword, "gro");
5557 static cmdline_parse_token_string_t cmd_gro_enable_onoff =
5558 	TOKEN_STRING_INITIALIZER(struct cmd_gro_enable_result,
5559 			cmd_onoff, "on#off");
5560 
5561 static cmdline_parse_inst_t cmd_gro_enable = {
5562 	.f = cmd_gro_enable_parsed,
5563 	.data = NULL,
5564 	.help_str = "set port <port_id> gro on|off",
5565 	.tokens = {
5566 		(void *)&cmd_gro_enable_set,
5567 		(void *)&cmd_gro_enable_port,
5568 		(void *)&cmd_gro_enable_pid,
5569 		(void *)&cmd_gro_enable_keyword,
5570 		(void *)&cmd_gro_enable_onoff,
5571 		NULL,
5572 	},
5573 };
5574 
5575 /* *** DISPLAY GRO CONFIGURATION *** */
5576 struct cmd_gro_show_result {
5577 	cmdline_fixed_string_t cmd_show;
5578 	cmdline_fixed_string_t cmd_port;
5579 	cmdline_fixed_string_t cmd_keyword;
5580 	portid_t cmd_pid;
5581 };
5582 
5583 static void
5584 cmd_gro_show_parsed(void *parsed_result,
5585 		__rte_unused struct cmdline *cl,
5586 		__rte_unused void *data)
5587 {
5588 	struct cmd_gro_show_result *res;
5589 
5590 	res = parsed_result;
5591 	if (!strcmp(res->cmd_keyword, "gro"))
5592 		show_gro(res->cmd_pid);
5593 }
5594 
5595 static cmdline_parse_token_string_t cmd_gro_show_show =
5596 	TOKEN_STRING_INITIALIZER(struct cmd_gro_show_result,
5597 			cmd_show, "show");
5598 static cmdline_parse_token_string_t cmd_gro_show_port =
5599 	TOKEN_STRING_INITIALIZER(struct cmd_gro_show_result,
5600 			cmd_port, "port");
5601 static cmdline_parse_token_num_t cmd_gro_show_pid =
5602 	TOKEN_NUM_INITIALIZER(struct cmd_gro_show_result,
5603 			cmd_pid, RTE_UINT16);
5604 static cmdline_parse_token_string_t cmd_gro_show_keyword =
5605 	TOKEN_STRING_INITIALIZER(struct cmd_gro_show_result,
5606 			cmd_keyword, "gro");
5607 
5608 static cmdline_parse_inst_t cmd_gro_show = {
5609 	.f = cmd_gro_show_parsed,
5610 	.data = NULL,
5611 	.help_str = "show port <port_id> gro",
5612 	.tokens = {
5613 		(void *)&cmd_gro_show_show,
5614 		(void *)&cmd_gro_show_port,
5615 		(void *)&cmd_gro_show_pid,
5616 		(void *)&cmd_gro_show_keyword,
5617 		NULL,
5618 	},
5619 };
5620 
5621 /* *** SET FLUSH CYCLES FOR GRO *** */
5622 struct cmd_gro_flush_result {
5623 	cmdline_fixed_string_t cmd_set;
5624 	cmdline_fixed_string_t cmd_keyword;
5625 	cmdline_fixed_string_t cmd_flush;
5626 	uint8_t cmd_cycles;
5627 };
5628 
5629 static void
5630 cmd_gro_flush_parsed(void *parsed_result,
5631 		__rte_unused struct cmdline *cl,
5632 		__rte_unused void *data)
5633 {
5634 	struct cmd_gro_flush_result *res;
5635 
5636 	res = parsed_result;
5637 	if ((!strcmp(res->cmd_keyword, "gro")) &&
5638 			(!strcmp(res->cmd_flush, "flush")))
5639 		setup_gro_flush_cycles(res->cmd_cycles);
5640 }
5641 
5642 static cmdline_parse_token_string_t cmd_gro_flush_set =
5643 	TOKEN_STRING_INITIALIZER(struct cmd_gro_flush_result,
5644 			cmd_set, "set");
5645 static cmdline_parse_token_string_t cmd_gro_flush_keyword =
5646 	TOKEN_STRING_INITIALIZER(struct cmd_gro_flush_result,
5647 			cmd_keyword, "gro");
5648 static cmdline_parse_token_string_t cmd_gro_flush_flush =
5649 	TOKEN_STRING_INITIALIZER(struct cmd_gro_flush_result,
5650 			cmd_flush, "flush");
5651 static cmdline_parse_token_num_t cmd_gro_flush_cycles =
5652 	TOKEN_NUM_INITIALIZER(struct cmd_gro_flush_result,
5653 			cmd_cycles, RTE_UINT8);
5654 
5655 static cmdline_parse_inst_t cmd_gro_flush = {
5656 	.f = cmd_gro_flush_parsed,
5657 	.data = NULL,
5658 	.help_str = "set gro flush <cycles>",
5659 	.tokens = {
5660 		(void *)&cmd_gro_flush_set,
5661 		(void *)&cmd_gro_flush_keyword,
5662 		(void *)&cmd_gro_flush_flush,
5663 		(void *)&cmd_gro_flush_cycles,
5664 		NULL,
5665 	},
5666 };
5667 #endif /* RTE_LIB_GRO */
5668 
5669 #ifdef RTE_LIB_GSO
5670 /* *** ENABLE/DISABLE GSO *** */
5671 struct cmd_gso_enable_result {
5672 	cmdline_fixed_string_t cmd_set;
5673 	cmdline_fixed_string_t cmd_port;
5674 	cmdline_fixed_string_t cmd_keyword;
5675 	cmdline_fixed_string_t cmd_mode;
5676 	portid_t cmd_pid;
5677 };
5678 
5679 static void
5680 cmd_gso_enable_parsed(void *parsed_result,
5681 		__rte_unused struct cmdline *cl,
5682 		__rte_unused void *data)
5683 {
5684 	struct cmd_gso_enable_result *res;
5685 
5686 	res = parsed_result;
5687 	if (!strcmp(res->cmd_keyword, "gso"))
5688 		setup_gso(res->cmd_mode, res->cmd_pid);
5689 }
5690 
5691 static cmdline_parse_token_string_t cmd_gso_enable_set =
5692 	TOKEN_STRING_INITIALIZER(struct cmd_gso_enable_result,
5693 			cmd_set, "set");
5694 static cmdline_parse_token_string_t cmd_gso_enable_port =
5695 	TOKEN_STRING_INITIALIZER(struct cmd_gso_enable_result,
5696 			cmd_port, "port");
5697 static cmdline_parse_token_string_t cmd_gso_enable_keyword =
5698 	TOKEN_STRING_INITIALIZER(struct cmd_gso_enable_result,
5699 			cmd_keyword, "gso");
5700 static cmdline_parse_token_string_t cmd_gso_enable_mode =
5701 	TOKEN_STRING_INITIALIZER(struct cmd_gso_enable_result,
5702 			cmd_mode, "on#off");
5703 static cmdline_parse_token_num_t cmd_gso_enable_pid =
5704 	TOKEN_NUM_INITIALIZER(struct cmd_gso_enable_result,
5705 			cmd_pid, RTE_UINT16);
5706 
5707 static cmdline_parse_inst_t cmd_gso_enable = {
5708 	.f = cmd_gso_enable_parsed,
5709 	.data = NULL,
5710 	.help_str = "set port <port_id> gso on|off",
5711 	.tokens = {
5712 		(void *)&cmd_gso_enable_set,
5713 		(void *)&cmd_gso_enable_port,
5714 		(void *)&cmd_gso_enable_pid,
5715 		(void *)&cmd_gso_enable_keyword,
5716 		(void *)&cmd_gso_enable_mode,
5717 		NULL,
5718 	},
5719 };
5720 
5721 /* *** SET MAX PACKET LENGTH FOR GSO SEGMENTS *** */
5722 struct cmd_gso_size_result {
5723 	cmdline_fixed_string_t cmd_set;
5724 	cmdline_fixed_string_t cmd_keyword;
5725 	cmdline_fixed_string_t cmd_segsz;
5726 	uint16_t cmd_size;
5727 };
5728 
5729 static void
5730 cmd_gso_size_parsed(void *parsed_result,
5731 		       __rte_unused struct cmdline *cl,
5732 		       __rte_unused void *data)
5733 {
5734 	struct cmd_gso_size_result *res = parsed_result;
5735 
5736 	if (test_done == 0) {
5737 		fprintf(stderr,
5738 			"Before setting GSO segsz, please first stop forwarding\n");
5739 		return;
5740 	}
5741 
5742 	if (!strcmp(res->cmd_keyword, "gso") &&
5743 			!strcmp(res->cmd_segsz, "segsz")) {
5744 		if (res->cmd_size < RTE_GSO_SEG_SIZE_MIN)
5745 			fprintf(stderr,
5746 				"gso_size should be larger than %zu. Please input a legal value\n",
5747 				RTE_GSO_SEG_SIZE_MIN);
5748 		else
5749 			gso_max_segment_size = res->cmd_size;
5750 	}
5751 }
5752 
5753 static cmdline_parse_token_string_t cmd_gso_size_set =
5754 	TOKEN_STRING_INITIALIZER(struct cmd_gso_size_result,
5755 				cmd_set, "set");
5756 static cmdline_parse_token_string_t cmd_gso_size_keyword =
5757 	TOKEN_STRING_INITIALIZER(struct cmd_gso_size_result,
5758 				cmd_keyword, "gso");
5759 static cmdline_parse_token_string_t cmd_gso_size_segsz =
5760 	TOKEN_STRING_INITIALIZER(struct cmd_gso_size_result,
5761 				cmd_segsz, "segsz");
5762 static cmdline_parse_token_num_t cmd_gso_size_size =
5763 	TOKEN_NUM_INITIALIZER(struct cmd_gso_size_result,
5764 				cmd_size, RTE_UINT16);
5765 
5766 static cmdline_parse_inst_t cmd_gso_size = {
5767 	.f = cmd_gso_size_parsed,
5768 	.data = NULL,
5769 	.help_str = "set gso segsz <length>",
5770 	.tokens = {
5771 		(void *)&cmd_gso_size_set,
5772 		(void *)&cmd_gso_size_keyword,
5773 		(void *)&cmd_gso_size_segsz,
5774 		(void *)&cmd_gso_size_size,
5775 		NULL,
5776 	},
5777 };
5778 
5779 /* *** SHOW GSO CONFIGURATION *** */
5780 struct cmd_gso_show_result {
5781 	cmdline_fixed_string_t cmd_show;
5782 	cmdline_fixed_string_t cmd_port;
5783 	cmdline_fixed_string_t cmd_keyword;
5784 	portid_t cmd_pid;
5785 };
5786 
5787 static void
5788 cmd_gso_show_parsed(void *parsed_result,
5789 		       __rte_unused struct cmdline *cl,
5790 		       __rte_unused void *data)
5791 {
5792 	struct cmd_gso_show_result *res = parsed_result;
5793 
5794 	if (!rte_eth_dev_is_valid_port(res->cmd_pid)) {
5795 		fprintf(stderr, "invalid port id %u\n", res->cmd_pid);
5796 		return;
5797 	}
5798 	if (!strcmp(res->cmd_keyword, "gso")) {
5799 		if (gso_ports[res->cmd_pid].enable) {
5800 			printf("Max GSO'd packet size: %uB\n"
5801 					"Supported GSO types: TCP/IPv4, "
5802 					"UDP/IPv4, VxLAN with inner "
5803 					"TCP/IPv4 packet, GRE with inner "
5804 					"TCP/IPv4 packet\n",
5805 					gso_max_segment_size);
5806 		} else
5807 			printf("GSO is not enabled on Port %u\n", res->cmd_pid);
5808 	}
5809 }
5810 
5811 static cmdline_parse_token_string_t cmd_gso_show_show =
5812 TOKEN_STRING_INITIALIZER(struct cmd_gso_show_result,
5813 		cmd_show, "show");
5814 static cmdline_parse_token_string_t cmd_gso_show_port =
5815 TOKEN_STRING_INITIALIZER(struct cmd_gso_show_result,
5816 		cmd_port, "port");
5817 static cmdline_parse_token_string_t cmd_gso_show_keyword =
5818 	TOKEN_STRING_INITIALIZER(struct cmd_gso_show_result,
5819 				cmd_keyword, "gso");
5820 static cmdline_parse_token_num_t cmd_gso_show_pid =
5821 	TOKEN_NUM_INITIALIZER(struct cmd_gso_show_result,
5822 				cmd_pid, RTE_UINT16);
5823 
5824 static cmdline_parse_inst_t cmd_gso_show = {
5825 	.f = cmd_gso_show_parsed,
5826 	.data = NULL,
5827 	.help_str = "show port <port_id> gso",
5828 	.tokens = {
5829 		(void *)&cmd_gso_show_show,
5830 		(void *)&cmd_gso_show_port,
5831 		(void *)&cmd_gso_show_pid,
5832 		(void *)&cmd_gso_show_keyword,
5833 		NULL,
5834 	},
5835 };
5836 #endif /* RTE_LIB_GSO */
5837 
5838 /* *** ENABLE/DISABLE FLUSH ON RX STREAMS *** */
5839 struct cmd_set_flush_rx {
5840 	cmdline_fixed_string_t set;
5841 	cmdline_fixed_string_t flush_rx;
5842 	cmdline_fixed_string_t mode;
5843 };
5844 
5845 static void
5846 cmd_set_flush_rx_parsed(void *parsed_result,
5847 		__rte_unused struct cmdline *cl,
5848 		__rte_unused void *data)
5849 {
5850 	struct cmd_set_flush_rx *res = parsed_result;
5851 
5852 	if (num_procs > 1 && (strcmp(res->mode, "on") == 0)) {
5853 		printf("multi-process doesn't support to flush Rx queues.\n");
5854 		return;
5855 	}
5856 
5857 	no_flush_rx = (uint8_t)((strcmp(res->mode, "on") == 0) ? 0 : 1);
5858 }
5859 
5860 static cmdline_parse_token_string_t cmd_setflushrx_set =
5861 	TOKEN_STRING_INITIALIZER(struct cmd_set_flush_rx,
5862 			set, "set");
5863 static cmdline_parse_token_string_t cmd_setflushrx_flush_rx =
5864 	TOKEN_STRING_INITIALIZER(struct cmd_set_flush_rx,
5865 			flush_rx, "flush_rx");
5866 static cmdline_parse_token_string_t cmd_setflushrx_mode =
5867 	TOKEN_STRING_INITIALIZER(struct cmd_set_flush_rx,
5868 			mode, "on#off");
5869 
5870 
5871 static cmdline_parse_inst_t cmd_set_flush_rx = {
5872 	.f = cmd_set_flush_rx_parsed,
5873 	.help_str = "set flush_rx on|off: Enable/Disable flush on rx streams",
5874 	.data = NULL,
5875 	.tokens = {
5876 		(void *)&cmd_setflushrx_set,
5877 		(void *)&cmd_setflushrx_flush_rx,
5878 		(void *)&cmd_setflushrx_mode,
5879 		NULL,
5880 	},
5881 };
5882 
5883 /* *** ENABLE/DISABLE LINK STATUS CHECK *** */
5884 struct cmd_set_link_check {
5885 	cmdline_fixed_string_t set;
5886 	cmdline_fixed_string_t link_check;
5887 	cmdline_fixed_string_t mode;
5888 };
5889 
5890 static void
5891 cmd_set_link_check_parsed(void *parsed_result,
5892 		__rte_unused struct cmdline *cl,
5893 		__rte_unused void *data)
5894 {
5895 	struct cmd_set_link_check *res = parsed_result;
5896 	no_link_check = (uint8_t)((strcmp(res->mode, "on") == 0) ? 0 : 1);
5897 }
5898 
5899 static cmdline_parse_token_string_t cmd_setlinkcheck_set =
5900 	TOKEN_STRING_INITIALIZER(struct cmd_set_link_check,
5901 			set, "set");
5902 static cmdline_parse_token_string_t cmd_setlinkcheck_link_check =
5903 	TOKEN_STRING_INITIALIZER(struct cmd_set_link_check,
5904 			link_check, "link_check");
5905 static cmdline_parse_token_string_t cmd_setlinkcheck_mode =
5906 	TOKEN_STRING_INITIALIZER(struct cmd_set_link_check,
5907 			mode, "on#off");
5908 
5909 
5910 static cmdline_parse_inst_t cmd_set_link_check = {
5911 	.f = cmd_set_link_check_parsed,
5912 	.help_str = "set link_check on|off: Enable/Disable link status check "
5913 	            "when starting/stopping a port",
5914 	.data = NULL,
5915 	.tokens = {
5916 		(void *)&cmd_setlinkcheck_set,
5917 		(void *)&cmd_setlinkcheck_link_check,
5918 		(void *)&cmd_setlinkcheck_mode,
5919 		NULL,
5920 	},
5921 };
5922 
5923 /* *** SET FORWARDING MODE *** */
5924 struct cmd_set_fwd_mode_result {
5925 	cmdline_fixed_string_t set;
5926 	cmdline_fixed_string_t fwd;
5927 	cmdline_fixed_string_t mode;
5928 };
5929 
5930 static void cmd_set_fwd_mode_parsed(void *parsed_result,
5931 				    __rte_unused struct cmdline *cl,
5932 				    __rte_unused void *data)
5933 {
5934 	struct cmd_set_fwd_mode_result *res = parsed_result;
5935 
5936 	retry_enabled = 0;
5937 	set_pkt_forwarding_mode(res->mode);
5938 }
5939 
5940 static cmdline_parse_token_string_t cmd_setfwd_set =
5941 	TOKEN_STRING_INITIALIZER(struct cmd_set_fwd_mode_result, set, "set");
5942 static cmdline_parse_token_string_t cmd_setfwd_fwd =
5943 	TOKEN_STRING_INITIALIZER(struct cmd_set_fwd_mode_result, fwd, "fwd");
5944 static cmdline_parse_token_string_t cmd_setfwd_mode =
5945 	TOKEN_STRING_INITIALIZER(struct cmd_set_fwd_mode_result, mode,
5946 		"" /* defined at init */);
5947 
5948 static cmdline_parse_inst_t cmd_set_fwd_mode = {
5949 	.f = cmd_set_fwd_mode_parsed,
5950 	.data = NULL,
5951 	.help_str = NULL, /* defined at init */
5952 	.tokens = {
5953 		(void *)&cmd_setfwd_set,
5954 		(void *)&cmd_setfwd_fwd,
5955 		(void *)&cmd_setfwd_mode,
5956 		NULL,
5957 	},
5958 };
5959 
5960 static void cmd_set_fwd_mode_init(void)
5961 {
5962 	char *modes, *c;
5963 	static char token[128];
5964 	static char help[256];
5965 	cmdline_parse_token_string_t *token_struct;
5966 
5967 	modes = list_pkt_forwarding_modes();
5968 	snprintf(help, sizeof(help), "set fwd %s: "
5969 		"Set packet forwarding mode", modes);
5970 	cmd_set_fwd_mode.help_str = help;
5971 
5972 	/* string token separator is # */
5973 	for (c = token; *modes != '\0'; modes++)
5974 		if (*modes == '|')
5975 			*c++ = '#';
5976 		else
5977 			*c++ = *modes;
5978 	token_struct = (cmdline_parse_token_string_t*)cmd_set_fwd_mode.tokens[2];
5979 	token_struct->string_data.str = token;
5980 }
5981 
5982 /* *** SET RETRY FORWARDING MODE *** */
5983 struct cmd_set_fwd_retry_mode_result {
5984 	cmdline_fixed_string_t set;
5985 	cmdline_fixed_string_t fwd;
5986 	cmdline_fixed_string_t mode;
5987 	cmdline_fixed_string_t retry;
5988 };
5989 
5990 static void cmd_set_fwd_retry_mode_parsed(void *parsed_result,
5991 			    __rte_unused struct cmdline *cl,
5992 			    __rte_unused void *data)
5993 {
5994 	struct cmd_set_fwd_retry_mode_result *res = parsed_result;
5995 
5996 	retry_enabled = 1;
5997 	set_pkt_forwarding_mode(res->mode);
5998 }
5999 
6000 static cmdline_parse_token_string_t cmd_setfwd_retry_set =
6001 	TOKEN_STRING_INITIALIZER(struct cmd_set_fwd_retry_mode_result,
6002 			set, "set");
6003 static cmdline_parse_token_string_t cmd_setfwd_retry_fwd =
6004 	TOKEN_STRING_INITIALIZER(struct cmd_set_fwd_retry_mode_result,
6005 			fwd, "fwd");
6006 static cmdline_parse_token_string_t cmd_setfwd_retry_mode =
6007 	TOKEN_STRING_INITIALIZER(struct cmd_set_fwd_retry_mode_result,
6008 			mode,
6009 		"" /* defined at init */);
6010 static cmdline_parse_token_string_t cmd_setfwd_retry_retry =
6011 	TOKEN_STRING_INITIALIZER(struct cmd_set_fwd_retry_mode_result,
6012 			retry, "retry");
6013 
6014 static cmdline_parse_inst_t cmd_set_fwd_retry_mode = {
6015 	.f = cmd_set_fwd_retry_mode_parsed,
6016 	.data = NULL,
6017 	.help_str = NULL, /* defined at init */
6018 	.tokens = {
6019 		(void *)&cmd_setfwd_retry_set,
6020 		(void *)&cmd_setfwd_retry_fwd,
6021 		(void *)&cmd_setfwd_retry_mode,
6022 		(void *)&cmd_setfwd_retry_retry,
6023 		NULL,
6024 	},
6025 };
6026 
6027 static void cmd_set_fwd_retry_mode_init(void)
6028 {
6029 	char *modes, *c;
6030 	static char token[128];
6031 	static char help[256];
6032 	cmdline_parse_token_string_t *token_struct;
6033 
6034 	modes = list_pkt_forwarding_retry_modes();
6035 	snprintf(help, sizeof(help), "set fwd %s retry: "
6036 		"Set packet forwarding mode with retry", modes);
6037 	cmd_set_fwd_retry_mode.help_str = help;
6038 
6039 	/* string token separator is # */
6040 	for (c = token; *modes != '\0'; modes++)
6041 		if (*modes == '|')
6042 			*c++ = '#';
6043 		else
6044 			*c++ = *modes;
6045 	token_struct = (cmdline_parse_token_string_t *)
6046 		cmd_set_fwd_retry_mode.tokens[2];
6047 	token_struct->string_data.str = token;
6048 }
6049 
6050 /* *** SET BURST TX DELAY TIME RETRY NUMBER *** */
6051 struct cmd_set_burst_tx_retry_result {
6052 	cmdline_fixed_string_t set;
6053 	cmdline_fixed_string_t burst;
6054 	cmdline_fixed_string_t tx;
6055 	cmdline_fixed_string_t delay;
6056 	uint32_t time;
6057 	cmdline_fixed_string_t retry;
6058 	uint32_t retry_num;
6059 };
6060 
6061 static void cmd_set_burst_tx_retry_parsed(void *parsed_result,
6062 					__rte_unused struct cmdline *cl,
6063 					__rte_unused void *data)
6064 {
6065 	struct cmd_set_burst_tx_retry_result *res = parsed_result;
6066 
6067 	if (!strcmp(res->set, "set") && !strcmp(res->burst, "burst")
6068 		&& !strcmp(res->tx, "tx")) {
6069 		if (!strcmp(res->delay, "delay"))
6070 			burst_tx_delay_time = res->time;
6071 		if (!strcmp(res->retry, "retry"))
6072 			burst_tx_retry_num = res->retry_num;
6073 	}
6074 
6075 }
6076 
6077 static cmdline_parse_token_string_t cmd_set_burst_tx_retry_set =
6078 	TOKEN_STRING_INITIALIZER(struct cmd_set_burst_tx_retry_result, set, "set");
6079 static cmdline_parse_token_string_t cmd_set_burst_tx_retry_burst =
6080 	TOKEN_STRING_INITIALIZER(struct cmd_set_burst_tx_retry_result, burst,
6081 				 "burst");
6082 static cmdline_parse_token_string_t cmd_set_burst_tx_retry_tx =
6083 	TOKEN_STRING_INITIALIZER(struct cmd_set_burst_tx_retry_result, tx, "tx");
6084 static cmdline_parse_token_string_t cmd_set_burst_tx_retry_delay =
6085 	TOKEN_STRING_INITIALIZER(struct cmd_set_burst_tx_retry_result, delay, "delay");
6086 static cmdline_parse_token_num_t cmd_set_burst_tx_retry_time =
6087 	TOKEN_NUM_INITIALIZER(struct cmd_set_burst_tx_retry_result, time,
6088 				 RTE_UINT32);
6089 static cmdline_parse_token_string_t cmd_set_burst_tx_retry_retry =
6090 	TOKEN_STRING_INITIALIZER(struct cmd_set_burst_tx_retry_result, retry, "retry");
6091 static cmdline_parse_token_num_t cmd_set_burst_tx_retry_retry_num =
6092 	TOKEN_NUM_INITIALIZER(struct cmd_set_burst_tx_retry_result, retry_num,
6093 				 RTE_UINT32);
6094 
6095 static cmdline_parse_inst_t cmd_set_burst_tx_retry = {
6096 	.f = cmd_set_burst_tx_retry_parsed,
6097 	.help_str = "set burst tx delay <delay_usec> retry <num_retry>",
6098 	.tokens = {
6099 		(void *)&cmd_set_burst_tx_retry_set,
6100 		(void *)&cmd_set_burst_tx_retry_burst,
6101 		(void *)&cmd_set_burst_tx_retry_tx,
6102 		(void *)&cmd_set_burst_tx_retry_delay,
6103 		(void *)&cmd_set_burst_tx_retry_time,
6104 		(void *)&cmd_set_burst_tx_retry_retry,
6105 		(void *)&cmd_set_burst_tx_retry_retry_num,
6106 		NULL,
6107 	},
6108 };
6109 
6110 /* *** SET PROMISC MODE *** */
6111 struct cmd_set_promisc_mode_result {
6112 	cmdline_fixed_string_t set;
6113 	cmdline_fixed_string_t promisc;
6114 	cmdline_fixed_string_t port_all; /* valid if "allports" argument == 1 */
6115 	uint16_t port_num;               /* valid if "allports" argument == 0 */
6116 	cmdline_fixed_string_t mode;
6117 };
6118 
6119 static void cmd_set_promisc_mode_parsed(void *parsed_result,
6120 					__rte_unused struct cmdline *cl,
6121 					void *allports)
6122 {
6123 	struct cmd_set_promisc_mode_result *res = parsed_result;
6124 	int enable;
6125 	portid_t i;
6126 
6127 	if (!strcmp(res->mode, "on"))
6128 		enable = 1;
6129 	else
6130 		enable = 0;
6131 
6132 	/* all ports */
6133 	if (allports) {
6134 		RTE_ETH_FOREACH_DEV(i)
6135 			eth_set_promisc_mode(i, enable);
6136 	} else {
6137 		eth_set_promisc_mode(res->port_num, enable);
6138 	}
6139 }
6140 
6141 static cmdline_parse_token_string_t cmd_setpromisc_set =
6142 	TOKEN_STRING_INITIALIZER(struct cmd_set_promisc_mode_result, set, "set");
6143 static cmdline_parse_token_string_t cmd_setpromisc_promisc =
6144 	TOKEN_STRING_INITIALIZER(struct cmd_set_promisc_mode_result, promisc,
6145 				 "promisc");
6146 static cmdline_parse_token_string_t cmd_setpromisc_portall =
6147 	TOKEN_STRING_INITIALIZER(struct cmd_set_promisc_mode_result, port_all,
6148 				 "all");
6149 static cmdline_parse_token_num_t cmd_setpromisc_portnum =
6150 	TOKEN_NUM_INITIALIZER(struct cmd_set_promisc_mode_result, port_num,
6151 			      RTE_UINT16);
6152 static cmdline_parse_token_string_t cmd_setpromisc_mode =
6153 	TOKEN_STRING_INITIALIZER(struct cmd_set_promisc_mode_result, mode,
6154 				 "on#off");
6155 
6156 static cmdline_parse_inst_t cmd_set_promisc_mode_all = {
6157 	.f = cmd_set_promisc_mode_parsed,
6158 	.data = (void *)1,
6159 	.help_str = "set promisc all on|off: Set promisc mode for all ports",
6160 	.tokens = {
6161 		(void *)&cmd_setpromisc_set,
6162 		(void *)&cmd_setpromisc_promisc,
6163 		(void *)&cmd_setpromisc_portall,
6164 		(void *)&cmd_setpromisc_mode,
6165 		NULL,
6166 	},
6167 };
6168 
6169 static cmdline_parse_inst_t cmd_set_promisc_mode_one = {
6170 	.f = cmd_set_promisc_mode_parsed,
6171 	.data = (void *)0,
6172 	.help_str = "set promisc <port_id> on|off: Set promisc mode on port_id",
6173 	.tokens = {
6174 		(void *)&cmd_setpromisc_set,
6175 		(void *)&cmd_setpromisc_promisc,
6176 		(void *)&cmd_setpromisc_portnum,
6177 		(void *)&cmd_setpromisc_mode,
6178 		NULL,
6179 	},
6180 };
6181 
6182 /* *** SET ALLMULTI MODE *** */
6183 struct cmd_set_allmulti_mode_result {
6184 	cmdline_fixed_string_t set;
6185 	cmdline_fixed_string_t allmulti;
6186 	cmdline_fixed_string_t port_all; /* valid if "allports" argument == 1 */
6187 	uint16_t port_num;               /* valid if "allports" argument == 0 */
6188 	cmdline_fixed_string_t mode;
6189 };
6190 
6191 static void cmd_set_allmulti_mode_parsed(void *parsed_result,
6192 					__rte_unused struct cmdline *cl,
6193 					void *allports)
6194 {
6195 	struct cmd_set_allmulti_mode_result *res = parsed_result;
6196 	int enable;
6197 	portid_t i;
6198 
6199 	if (!strcmp(res->mode, "on"))
6200 		enable = 1;
6201 	else
6202 		enable = 0;
6203 
6204 	/* all ports */
6205 	if (allports) {
6206 		RTE_ETH_FOREACH_DEV(i) {
6207 			eth_set_allmulticast_mode(i, enable);
6208 		}
6209 	}
6210 	else {
6211 		eth_set_allmulticast_mode(res->port_num, enable);
6212 	}
6213 }
6214 
6215 static cmdline_parse_token_string_t cmd_setallmulti_set =
6216 	TOKEN_STRING_INITIALIZER(struct cmd_set_allmulti_mode_result, set, "set");
6217 static cmdline_parse_token_string_t cmd_setallmulti_allmulti =
6218 	TOKEN_STRING_INITIALIZER(struct cmd_set_allmulti_mode_result, allmulti,
6219 				 "allmulti");
6220 static cmdline_parse_token_string_t cmd_setallmulti_portall =
6221 	TOKEN_STRING_INITIALIZER(struct cmd_set_allmulti_mode_result, port_all,
6222 				 "all");
6223 static cmdline_parse_token_num_t cmd_setallmulti_portnum =
6224 	TOKEN_NUM_INITIALIZER(struct cmd_set_allmulti_mode_result, port_num,
6225 			      RTE_UINT16);
6226 static cmdline_parse_token_string_t cmd_setallmulti_mode =
6227 	TOKEN_STRING_INITIALIZER(struct cmd_set_allmulti_mode_result, mode,
6228 				 "on#off");
6229 
6230 static cmdline_parse_inst_t cmd_set_allmulti_mode_all = {
6231 	.f = cmd_set_allmulti_mode_parsed,
6232 	.data = (void *)1,
6233 	.help_str = "set allmulti all on|off: Set allmulti mode for all ports",
6234 	.tokens = {
6235 		(void *)&cmd_setallmulti_set,
6236 		(void *)&cmd_setallmulti_allmulti,
6237 		(void *)&cmd_setallmulti_portall,
6238 		(void *)&cmd_setallmulti_mode,
6239 		NULL,
6240 	},
6241 };
6242 
6243 static cmdline_parse_inst_t cmd_set_allmulti_mode_one = {
6244 	.f = cmd_set_allmulti_mode_parsed,
6245 	.data = (void *)0,
6246 	.help_str = "set allmulti <port_id> on|off: "
6247 		"Set allmulti mode on port_id",
6248 	.tokens = {
6249 		(void *)&cmd_setallmulti_set,
6250 		(void *)&cmd_setallmulti_allmulti,
6251 		(void *)&cmd_setallmulti_portnum,
6252 		(void *)&cmd_setallmulti_mode,
6253 		NULL,
6254 	},
6255 };
6256 
6257 /* *** GET CURRENT ETHERNET LINK FLOW CONTROL *** */
6258 struct cmd_link_flow_ctrl_show {
6259 	cmdline_fixed_string_t show;
6260 	cmdline_fixed_string_t port;
6261 	portid_t port_id;
6262 	cmdline_fixed_string_t flow_ctrl;
6263 };
6264 
6265 static cmdline_parse_token_string_t cmd_lfc_show_show =
6266 	TOKEN_STRING_INITIALIZER(struct cmd_link_flow_ctrl_show,
6267 				show, "show");
6268 static cmdline_parse_token_string_t cmd_lfc_show_port =
6269 	TOKEN_STRING_INITIALIZER(struct cmd_link_flow_ctrl_show,
6270 				port, "port");
6271 static cmdline_parse_token_num_t cmd_lfc_show_portid =
6272 	TOKEN_NUM_INITIALIZER(struct cmd_link_flow_ctrl_show,
6273 				port_id, RTE_UINT16);
6274 static cmdline_parse_token_string_t cmd_lfc_show_flow_ctrl =
6275 	TOKEN_STRING_INITIALIZER(struct cmd_link_flow_ctrl_show,
6276 				flow_ctrl, "flow_ctrl");
6277 
6278 static void
6279 cmd_link_flow_ctrl_show_parsed(void *parsed_result,
6280 			      __rte_unused struct cmdline *cl,
6281 			      __rte_unused void *data)
6282 {
6283 	struct cmd_link_flow_ctrl_show *res = parsed_result;
6284 	static const char *info_border = "*********************";
6285 	struct rte_eth_fc_conf fc_conf;
6286 	bool rx_fc_en = false;
6287 	bool tx_fc_en = false;
6288 	int ret;
6289 
6290 	ret = rte_eth_dev_flow_ctrl_get(res->port_id, &fc_conf);
6291 	if (ret != 0) {
6292 		fprintf(stderr,
6293 			"Failed to get current flow ctrl information: err = %d\n",
6294 			ret);
6295 		return;
6296 	}
6297 
6298 	if (fc_conf.mode == RTE_ETH_FC_RX_PAUSE || fc_conf.mode == RTE_ETH_FC_FULL)
6299 		rx_fc_en = true;
6300 	if (fc_conf.mode == RTE_ETH_FC_TX_PAUSE || fc_conf.mode == RTE_ETH_FC_FULL)
6301 		tx_fc_en = true;
6302 
6303 	printf("\n%s Flow control infos for port %-2d %s\n",
6304 		info_border, res->port_id, info_border);
6305 	printf("FC mode:\n");
6306 	printf("   Rx pause: %s\n", rx_fc_en ? "on" : "off");
6307 	printf("   Tx pause: %s\n", tx_fc_en ? "on" : "off");
6308 	printf("Autoneg: %s\n", fc_conf.autoneg ? "on" : "off");
6309 	printf("Pause time: 0x%x\n", fc_conf.pause_time);
6310 	printf("High waterline: 0x%x\n", fc_conf.high_water);
6311 	printf("Low waterline: 0x%x\n", fc_conf.low_water);
6312 	printf("Send XON: %s\n", fc_conf.send_xon ? "on" : "off");
6313 	printf("Forward MAC control frames: %s\n",
6314 		fc_conf.mac_ctrl_frame_fwd ? "on" : "off");
6315 	printf("\n%s**************   End  ***********%s\n",
6316 		info_border, info_border);
6317 }
6318 
6319 static cmdline_parse_inst_t cmd_link_flow_control_show = {
6320 	.f = cmd_link_flow_ctrl_show_parsed,
6321 	.data = NULL,
6322 	.help_str = "show port <port_id> flow_ctrl",
6323 	.tokens = {
6324 		(void *)&cmd_lfc_show_show,
6325 		(void *)&cmd_lfc_show_port,
6326 		(void *)&cmd_lfc_show_portid,
6327 		(void *)&cmd_lfc_show_flow_ctrl,
6328 		NULL,
6329 	},
6330 };
6331 
6332 /* *** SETUP ETHERNET LINK FLOW CONTROL *** */
6333 struct cmd_link_flow_ctrl_set_result {
6334 	cmdline_fixed_string_t set;
6335 	cmdline_fixed_string_t flow_ctrl;
6336 	cmdline_fixed_string_t rx;
6337 	cmdline_fixed_string_t rx_lfc_mode;
6338 	cmdline_fixed_string_t tx;
6339 	cmdline_fixed_string_t tx_lfc_mode;
6340 	cmdline_fixed_string_t mac_ctrl_frame_fwd;
6341 	cmdline_fixed_string_t mac_ctrl_frame_fwd_mode;
6342 	cmdline_fixed_string_t autoneg_str;
6343 	cmdline_fixed_string_t autoneg;
6344 	cmdline_fixed_string_t hw_str;
6345 	uint32_t high_water;
6346 	cmdline_fixed_string_t lw_str;
6347 	uint32_t low_water;
6348 	cmdline_fixed_string_t pt_str;
6349 	uint16_t pause_time;
6350 	cmdline_fixed_string_t xon_str;
6351 	uint16_t send_xon;
6352 	portid_t port_id;
6353 };
6354 
6355 static cmdline_parse_token_string_t cmd_lfc_set_set =
6356 	TOKEN_STRING_INITIALIZER(struct cmd_link_flow_ctrl_set_result,
6357 				set, "set");
6358 static cmdline_parse_token_string_t cmd_lfc_set_flow_ctrl =
6359 	TOKEN_STRING_INITIALIZER(struct cmd_link_flow_ctrl_set_result,
6360 				flow_ctrl, "flow_ctrl");
6361 static cmdline_parse_token_string_t cmd_lfc_set_rx =
6362 	TOKEN_STRING_INITIALIZER(struct cmd_link_flow_ctrl_set_result,
6363 				rx, "rx");
6364 static cmdline_parse_token_string_t cmd_lfc_set_rx_mode =
6365 	TOKEN_STRING_INITIALIZER(struct cmd_link_flow_ctrl_set_result,
6366 				rx_lfc_mode, "on#off");
6367 static cmdline_parse_token_string_t cmd_lfc_set_tx =
6368 	TOKEN_STRING_INITIALIZER(struct cmd_link_flow_ctrl_set_result,
6369 				tx, "tx");
6370 static cmdline_parse_token_string_t cmd_lfc_set_tx_mode =
6371 	TOKEN_STRING_INITIALIZER(struct cmd_link_flow_ctrl_set_result,
6372 				tx_lfc_mode, "on#off");
6373 static cmdline_parse_token_string_t cmd_lfc_set_high_water_str =
6374 	TOKEN_STRING_INITIALIZER(struct cmd_link_flow_ctrl_set_result,
6375 				hw_str, "high_water");
6376 static cmdline_parse_token_num_t cmd_lfc_set_high_water =
6377 	TOKEN_NUM_INITIALIZER(struct cmd_link_flow_ctrl_set_result,
6378 				high_water, RTE_UINT32);
6379 static cmdline_parse_token_string_t cmd_lfc_set_low_water_str =
6380 	TOKEN_STRING_INITIALIZER(struct cmd_link_flow_ctrl_set_result,
6381 				lw_str, "low_water");
6382 static cmdline_parse_token_num_t cmd_lfc_set_low_water =
6383 	TOKEN_NUM_INITIALIZER(struct cmd_link_flow_ctrl_set_result,
6384 				low_water, RTE_UINT32);
6385 static cmdline_parse_token_string_t cmd_lfc_set_pause_time_str =
6386 	TOKEN_STRING_INITIALIZER(struct cmd_link_flow_ctrl_set_result,
6387 				pt_str, "pause_time");
6388 static cmdline_parse_token_num_t cmd_lfc_set_pause_time =
6389 	TOKEN_NUM_INITIALIZER(struct cmd_link_flow_ctrl_set_result,
6390 				pause_time, RTE_UINT16);
6391 static cmdline_parse_token_string_t cmd_lfc_set_send_xon_str =
6392 	TOKEN_STRING_INITIALIZER(struct cmd_link_flow_ctrl_set_result,
6393 				xon_str, "send_xon");
6394 static cmdline_parse_token_num_t cmd_lfc_set_send_xon =
6395 	TOKEN_NUM_INITIALIZER(struct cmd_link_flow_ctrl_set_result,
6396 				send_xon, RTE_UINT16);
6397 static cmdline_parse_token_string_t cmd_lfc_set_mac_ctrl_frame_fwd_mode =
6398 	TOKEN_STRING_INITIALIZER(struct cmd_link_flow_ctrl_set_result,
6399 				mac_ctrl_frame_fwd, "mac_ctrl_frame_fwd");
6400 static cmdline_parse_token_string_t cmd_lfc_set_mac_ctrl_frame_fwd =
6401 	TOKEN_STRING_INITIALIZER(struct cmd_link_flow_ctrl_set_result,
6402 				mac_ctrl_frame_fwd_mode, "on#off");
6403 static cmdline_parse_token_string_t cmd_lfc_set_autoneg_str =
6404 	TOKEN_STRING_INITIALIZER(struct cmd_link_flow_ctrl_set_result,
6405 				autoneg_str, "autoneg");
6406 static cmdline_parse_token_string_t cmd_lfc_set_autoneg =
6407 	TOKEN_STRING_INITIALIZER(struct cmd_link_flow_ctrl_set_result,
6408 				autoneg, "on#off");
6409 static cmdline_parse_token_num_t cmd_lfc_set_portid =
6410 	TOKEN_NUM_INITIALIZER(struct cmd_link_flow_ctrl_set_result,
6411 				port_id, RTE_UINT16);
6412 
6413 /* forward declaration */
6414 static void
6415 cmd_link_flow_ctrl_set_parsed(void *parsed_result, struct cmdline *cl,
6416 			      void *data);
6417 
6418 static cmdline_parse_inst_t cmd_link_flow_control_set = {
6419 	.f = cmd_link_flow_ctrl_set_parsed,
6420 	.data = NULL,
6421 	.help_str = "set flow_ctrl rx on|off tx on|off <high_water> "
6422 		"<low_water> <pause_time> <send_xon> mac_ctrl_frame_fwd on|off "
6423 		"autoneg on|off <port_id>: Configure the Ethernet flow control",
6424 	.tokens = {
6425 		(void *)&cmd_lfc_set_set,
6426 		(void *)&cmd_lfc_set_flow_ctrl,
6427 		(void *)&cmd_lfc_set_rx,
6428 		(void *)&cmd_lfc_set_rx_mode,
6429 		(void *)&cmd_lfc_set_tx,
6430 		(void *)&cmd_lfc_set_tx_mode,
6431 		(void *)&cmd_lfc_set_high_water,
6432 		(void *)&cmd_lfc_set_low_water,
6433 		(void *)&cmd_lfc_set_pause_time,
6434 		(void *)&cmd_lfc_set_send_xon,
6435 		(void *)&cmd_lfc_set_mac_ctrl_frame_fwd_mode,
6436 		(void *)&cmd_lfc_set_mac_ctrl_frame_fwd,
6437 		(void *)&cmd_lfc_set_autoneg_str,
6438 		(void *)&cmd_lfc_set_autoneg,
6439 		(void *)&cmd_lfc_set_portid,
6440 		NULL,
6441 	},
6442 };
6443 
6444 static cmdline_parse_inst_t cmd_link_flow_control_set_rx = {
6445 	.f = cmd_link_flow_ctrl_set_parsed,
6446 	.data = (void *)&cmd_link_flow_control_set_rx,
6447 	.help_str = "set flow_ctrl rx on|off <port_id>: "
6448 		"Change rx flow control parameter",
6449 	.tokens = {
6450 		(void *)&cmd_lfc_set_set,
6451 		(void *)&cmd_lfc_set_flow_ctrl,
6452 		(void *)&cmd_lfc_set_rx,
6453 		(void *)&cmd_lfc_set_rx_mode,
6454 		(void *)&cmd_lfc_set_portid,
6455 		NULL,
6456 	},
6457 };
6458 
6459 static cmdline_parse_inst_t cmd_link_flow_control_set_tx = {
6460 	.f = cmd_link_flow_ctrl_set_parsed,
6461 	.data = (void *)&cmd_link_flow_control_set_tx,
6462 	.help_str = "set flow_ctrl tx on|off <port_id>: "
6463 		"Change tx flow control parameter",
6464 	.tokens = {
6465 		(void *)&cmd_lfc_set_set,
6466 		(void *)&cmd_lfc_set_flow_ctrl,
6467 		(void *)&cmd_lfc_set_tx,
6468 		(void *)&cmd_lfc_set_tx_mode,
6469 		(void *)&cmd_lfc_set_portid,
6470 		NULL,
6471 	},
6472 };
6473 
6474 static cmdline_parse_inst_t cmd_link_flow_control_set_hw = {
6475 	.f = cmd_link_flow_ctrl_set_parsed,
6476 	.data = (void *)&cmd_link_flow_control_set_hw,
6477 	.help_str = "set flow_ctrl high_water <value> <port_id>: "
6478 		"Change high water flow control parameter",
6479 	.tokens = {
6480 		(void *)&cmd_lfc_set_set,
6481 		(void *)&cmd_lfc_set_flow_ctrl,
6482 		(void *)&cmd_lfc_set_high_water_str,
6483 		(void *)&cmd_lfc_set_high_water,
6484 		(void *)&cmd_lfc_set_portid,
6485 		NULL,
6486 	},
6487 };
6488 
6489 static cmdline_parse_inst_t cmd_link_flow_control_set_lw = {
6490 	.f = cmd_link_flow_ctrl_set_parsed,
6491 	.data = (void *)&cmd_link_flow_control_set_lw,
6492 	.help_str = "set flow_ctrl low_water <value> <port_id>: "
6493 		"Change low water flow control parameter",
6494 	.tokens = {
6495 		(void *)&cmd_lfc_set_set,
6496 		(void *)&cmd_lfc_set_flow_ctrl,
6497 		(void *)&cmd_lfc_set_low_water_str,
6498 		(void *)&cmd_lfc_set_low_water,
6499 		(void *)&cmd_lfc_set_portid,
6500 		NULL,
6501 	},
6502 };
6503 
6504 static cmdline_parse_inst_t cmd_link_flow_control_set_pt = {
6505 	.f = cmd_link_flow_ctrl_set_parsed,
6506 	.data = (void *)&cmd_link_flow_control_set_pt,
6507 	.help_str = "set flow_ctrl pause_time <value> <port_id>: "
6508 		"Change pause time flow control parameter",
6509 	.tokens = {
6510 		(void *)&cmd_lfc_set_set,
6511 		(void *)&cmd_lfc_set_flow_ctrl,
6512 		(void *)&cmd_lfc_set_pause_time_str,
6513 		(void *)&cmd_lfc_set_pause_time,
6514 		(void *)&cmd_lfc_set_portid,
6515 		NULL,
6516 	},
6517 };
6518 
6519 static cmdline_parse_inst_t cmd_link_flow_control_set_xon = {
6520 	.f = cmd_link_flow_ctrl_set_parsed,
6521 	.data = (void *)&cmd_link_flow_control_set_xon,
6522 	.help_str = "set flow_ctrl send_xon <value> <port_id>: "
6523 		"Change send_xon flow control parameter",
6524 	.tokens = {
6525 		(void *)&cmd_lfc_set_set,
6526 		(void *)&cmd_lfc_set_flow_ctrl,
6527 		(void *)&cmd_lfc_set_send_xon_str,
6528 		(void *)&cmd_lfc_set_send_xon,
6529 		(void *)&cmd_lfc_set_portid,
6530 		NULL,
6531 	},
6532 };
6533 
6534 static cmdline_parse_inst_t cmd_link_flow_control_set_macfwd = {
6535 	.f = cmd_link_flow_ctrl_set_parsed,
6536 	.data = (void *)&cmd_link_flow_control_set_macfwd,
6537 	.help_str = "set flow_ctrl mac_ctrl_frame_fwd on|off <port_id>: "
6538 		"Change mac ctrl fwd flow control parameter",
6539 	.tokens = {
6540 		(void *)&cmd_lfc_set_set,
6541 		(void *)&cmd_lfc_set_flow_ctrl,
6542 		(void *)&cmd_lfc_set_mac_ctrl_frame_fwd_mode,
6543 		(void *)&cmd_lfc_set_mac_ctrl_frame_fwd,
6544 		(void *)&cmd_lfc_set_portid,
6545 		NULL,
6546 	},
6547 };
6548 
6549 static cmdline_parse_inst_t cmd_link_flow_control_set_autoneg = {
6550 	.f = cmd_link_flow_ctrl_set_parsed,
6551 	.data = (void *)&cmd_link_flow_control_set_autoneg,
6552 	.help_str = "set flow_ctrl autoneg on|off <port_id>: "
6553 		"Change autoneg flow control parameter",
6554 	.tokens = {
6555 		(void *)&cmd_lfc_set_set,
6556 		(void *)&cmd_lfc_set_flow_ctrl,
6557 		(void *)&cmd_lfc_set_autoneg_str,
6558 		(void *)&cmd_lfc_set_autoneg,
6559 		(void *)&cmd_lfc_set_portid,
6560 		NULL,
6561 	},
6562 };
6563 
6564 static void
6565 cmd_link_flow_ctrl_set_parsed(void *parsed_result,
6566 			      __rte_unused struct cmdline *cl,
6567 			      void *data)
6568 {
6569 	struct cmd_link_flow_ctrl_set_result *res = parsed_result;
6570 	cmdline_parse_inst_t *cmd = data;
6571 	struct rte_eth_fc_conf fc_conf;
6572 	int rx_fc_en = 0;
6573 	int tx_fc_en = 0;
6574 	int ret;
6575 
6576 	/*
6577 	 * Rx on/off, flow control is enabled/disabled on RX side. This can indicate
6578 	 * the RTE_ETH_FC_TX_PAUSE, Transmit pause frame at the Rx side.
6579 	 * Tx on/off, flow control is enabled/disabled on TX side. This can indicate
6580 	 * the RTE_ETH_FC_RX_PAUSE, Respond to the pause frame at the Tx side.
6581 	 */
6582 	static enum rte_eth_fc_mode rx_tx_onoff_2_lfc_mode[2][2] = {
6583 			{RTE_ETH_FC_NONE, RTE_ETH_FC_TX_PAUSE}, {RTE_ETH_FC_RX_PAUSE, RTE_ETH_FC_FULL}
6584 	};
6585 
6586 	/* Partial command line, retrieve current configuration */
6587 	if (cmd) {
6588 		ret = rte_eth_dev_flow_ctrl_get(res->port_id, &fc_conf);
6589 		if (ret != 0) {
6590 			fprintf(stderr,
6591 				"cannot get current flow ctrl parameters, return code = %d\n",
6592 				ret);
6593 			return;
6594 		}
6595 
6596 		if ((fc_conf.mode == RTE_ETH_FC_RX_PAUSE) ||
6597 		    (fc_conf.mode == RTE_ETH_FC_FULL))
6598 			rx_fc_en = 1;
6599 		if ((fc_conf.mode == RTE_ETH_FC_TX_PAUSE) ||
6600 		    (fc_conf.mode == RTE_ETH_FC_FULL))
6601 			tx_fc_en = 1;
6602 	}
6603 
6604 	if (!cmd || cmd == &cmd_link_flow_control_set_rx)
6605 		rx_fc_en = (!strcmp(res->rx_lfc_mode, "on")) ? 1 : 0;
6606 
6607 	if (!cmd || cmd == &cmd_link_flow_control_set_tx)
6608 		tx_fc_en = (!strcmp(res->tx_lfc_mode, "on")) ? 1 : 0;
6609 
6610 	fc_conf.mode = rx_tx_onoff_2_lfc_mode[rx_fc_en][tx_fc_en];
6611 
6612 	if (!cmd || cmd == &cmd_link_flow_control_set_hw)
6613 		fc_conf.high_water = res->high_water;
6614 
6615 	if (!cmd || cmd == &cmd_link_flow_control_set_lw)
6616 		fc_conf.low_water = res->low_water;
6617 
6618 	if (!cmd || cmd == &cmd_link_flow_control_set_pt)
6619 		fc_conf.pause_time = res->pause_time;
6620 
6621 	if (!cmd || cmd == &cmd_link_flow_control_set_xon)
6622 		fc_conf.send_xon = res->send_xon;
6623 
6624 	if (!cmd || cmd == &cmd_link_flow_control_set_macfwd) {
6625 		if (!strcmp(res->mac_ctrl_frame_fwd_mode, "on"))
6626 			fc_conf.mac_ctrl_frame_fwd = 1;
6627 		else
6628 			fc_conf.mac_ctrl_frame_fwd = 0;
6629 	}
6630 
6631 	if (!cmd || cmd == &cmd_link_flow_control_set_autoneg)
6632 		fc_conf.autoneg = (!strcmp(res->autoneg, "on")) ? 1 : 0;
6633 
6634 	ret = rte_eth_dev_flow_ctrl_set(res->port_id, &fc_conf);
6635 	if (ret != 0)
6636 		fprintf(stderr,
6637 			"bad flow control parameter, return code = %d\n",
6638 			ret);
6639 }
6640 
6641 /* *** SETUP ETHERNET PRIORITY FLOW CONTROL *** */
6642 struct cmd_priority_flow_ctrl_set_result {
6643 	cmdline_fixed_string_t set;
6644 	cmdline_fixed_string_t pfc_ctrl;
6645 	cmdline_fixed_string_t rx;
6646 	cmdline_fixed_string_t rx_pfc_mode;
6647 	cmdline_fixed_string_t tx;
6648 	cmdline_fixed_string_t tx_pfc_mode;
6649 	uint32_t high_water;
6650 	uint32_t low_water;
6651 	uint16_t pause_time;
6652 	uint8_t  priority;
6653 	portid_t port_id;
6654 };
6655 
6656 static void
6657 cmd_priority_flow_ctrl_set_parsed(void *parsed_result,
6658 		       __rte_unused struct cmdline *cl,
6659 		       __rte_unused void *data)
6660 {
6661 	struct cmd_priority_flow_ctrl_set_result *res = parsed_result;
6662 	struct rte_eth_pfc_conf pfc_conf;
6663 	int rx_fc_enable, tx_fc_enable;
6664 	int ret;
6665 
6666 	/*
6667 	 * Rx on/off, flow control is enabled/disabled on RX side. This can indicate
6668 	 * the RTE_ETH_FC_TX_PAUSE, Transmit pause frame at the Rx side.
6669 	 * Tx on/off, flow control is enabled/disabled on TX side. This can indicate
6670 	 * the RTE_ETH_FC_RX_PAUSE, Respond to the pause frame at the Tx side.
6671 	 */
6672 	static enum rte_eth_fc_mode rx_tx_onoff_2_pfc_mode[2][2] = {
6673 		{RTE_ETH_FC_NONE, RTE_ETH_FC_TX_PAUSE}, {RTE_ETH_FC_RX_PAUSE, RTE_ETH_FC_FULL}
6674 	};
6675 
6676 	memset(&pfc_conf, 0, sizeof(struct rte_eth_pfc_conf));
6677 	rx_fc_enable = (!strncmp(res->rx_pfc_mode, "on",2)) ? 1 : 0;
6678 	tx_fc_enable = (!strncmp(res->tx_pfc_mode, "on",2)) ? 1 : 0;
6679 	pfc_conf.fc.mode       = rx_tx_onoff_2_pfc_mode[rx_fc_enable][tx_fc_enable];
6680 	pfc_conf.fc.high_water = res->high_water;
6681 	pfc_conf.fc.low_water  = res->low_water;
6682 	pfc_conf.fc.pause_time = res->pause_time;
6683 	pfc_conf.priority      = res->priority;
6684 
6685 	ret = rte_eth_dev_priority_flow_ctrl_set(res->port_id, &pfc_conf);
6686 	if (ret != 0)
6687 		fprintf(stderr,
6688 			"bad priority flow control parameter, return code = %d\n",
6689 			ret);
6690 }
6691 
6692 static cmdline_parse_token_string_t cmd_pfc_set_set =
6693 	TOKEN_STRING_INITIALIZER(struct cmd_priority_flow_ctrl_set_result,
6694 				set, "set");
6695 static cmdline_parse_token_string_t cmd_pfc_set_flow_ctrl =
6696 	TOKEN_STRING_INITIALIZER(struct cmd_priority_flow_ctrl_set_result,
6697 				pfc_ctrl, "pfc_ctrl");
6698 static cmdline_parse_token_string_t cmd_pfc_set_rx =
6699 	TOKEN_STRING_INITIALIZER(struct cmd_priority_flow_ctrl_set_result,
6700 				rx, "rx");
6701 static cmdline_parse_token_string_t cmd_pfc_set_rx_mode =
6702 	TOKEN_STRING_INITIALIZER(struct cmd_priority_flow_ctrl_set_result,
6703 				rx_pfc_mode, "on#off");
6704 static cmdline_parse_token_string_t cmd_pfc_set_tx =
6705 	TOKEN_STRING_INITIALIZER(struct cmd_priority_flow_ctrl_set_result,
6706 				tx, "tx");
6707 static cmdline_parse_token_string_t cmd_pfc_set_tx_mode =
6708 	TOKEN_STRING_INITIALIZER(struct cmd_priority_flow_ctrl_set_result,
6709 				tx_pfc_mode, "on#off");
6710 static cmdline_parse_token_num_t cmd_pfc_set_high_water =
6711 	TOKEN_NUM_INITIALIZER(struct cmd_priority_flow_ctrl_set_result,
6712 				high_water, RTE_UINT32);
6713 static cmdline_parse_token_num_t cmd_pfc_set_low_water =
6714 	TOKEN_NUM_INITIALIZER(struct cmd_priority_flow_ctrl_set_result,
6715 				low_water, RTE_UINT32);
6716 static cmdline_parse_token_num_t cmd_pfc_set_pause_time =
6717 	TOKEN_NUM_INITIALIZER(struct cmd_priority_flow_ctrl_set_result,
6718 				pause_time, RTE_UINT16);
6719 static cmdline_parse_token_num_t cmd_pfc_set_priority =
6720 	TOKEN_NUM_INITIALIZER(struct cmd_priority_flow_ctrl_set_result,
6721 				priority, RTE_UINT8);
6722 static cmdline_parse_token_num_t cmd_pfc_set_portid =
6723 	TOKEN_NUM_INITIALIZER(struct cmd_priority_flow_ctrl_set_result,
6724 				port_id, RTE_UINT16);
6725 
6726 static cmdline_parse_inst_t cmd_priority_flow_control_set = {
6727 	.f = cmd_priority_flow_ctrl_set_parsed,
6728 	.data = NULL,
6729 	.help_str = "set pfc_ctrl rx on|off tx on|off <high_water> <low_water> "
6730 		"<pause_time> <priority> <port_id>: "
6731 		"Configure the Ethernet priority flow control",
6732 	.tokens = {
6733 		(void *)&cmd_pfc_set_set,
6734 		(void *)&cmd_pfc_set_flow_ctrl,
6735 		(void *)&cmd_pfc_set_rx,
6736 		(void *)&cmd_pfc_set_rx_mode,
6737 		(void *)&cmd_pfc_set_tx,
6738 		(void *)&cmd_pfc_set_tx_mode,
6739 		(void *)&cmd_pfc_set_high_water,
6740 		(void *)&cmd_pfc_set_low_water,
6741 		(void *)&cmd_pfc_set_pause_time,
6742 		(void *)&cmd_pfc_set_priority,
6743 		(void *)&cmd_pfc_set_portid,
6744 		NULL,
6745 	},
6746 };
6747 
6748 struct cmd_queue_priority_flow_ctrl_set_result {
6749 	cmdline_fixed_string_t set;
6750 	cmdline_fixed_string_t pfc_queue_ctrl;
6751 	portid_t port_id;
6752 	cmdline_fixed_string_t rx;
6753 	cmdline_fixed_string_t rx_pfc_mode;
6754 	uint16_t tx_qid;
6755 	uint8_t  tx_tc;
6756 	cmdline_fixed_string_t tx;
6757 	cmdline_fixed_string_t tx_pfc_mode;
6758 	uint16_t rx_qid;
6759 	uint8_t  rx_tc;
6760 	uint16_t pause_time;
6761 };
6762 
6763 static void
6764 cmd_queue_priority_flow_ctrl_set_parsed(void *parsed_result,
6765 					__rte_unused struct cmdline *cl,
6766 					__rte_unused void *data)
6767 {
6768 	struct cmd_queue_priority_flow_ctrl_set_result *res = parsed_result;
6769 	struct rte_eth_pfc_queue_conf pfc_queue_conf;
6770 	int rx_fc_enable, tx_fc_enable;
6771 	int ret;
6772 
6773 	/*
6774 	 * Rx on/off, flow control is enabled/disabled on RX side. This can
6775 	 * indicate the RTE_ETH_FC_TX_PAUSE, Transmit pause frame at the Rx
6776 	 * side. Tx on/off, flow control is enabled/disabled on TX side. This
6777 	 * can indicate the RTE_ETH_FC_RX_PAUSE, Respond to the pause frame at
6778 	 * the Tx side.
6779 	 */
6780 	static enum rte_eth_fc_mode rx_tx_onoff_2_mode[2][2] = {
6781 		{RTE_ETH_FC_NONE, RTE_ETH_FC_TX_PAUSE},
6782 		{RTE_ETH_FC_RX_PAUSE, RTE_ETH_FC_FULL}
6783 	};
6784 
6785 	memset(&pfc_queue_conf, 0, sizeof(struct rte_eth_pfc_queue_conf));
6786 	rx_fc_enable = (!strncmp(res->rx_pfc_mode, "on", 2)) ? 1 : 0;
6787 	tx_fc_enable = (!strncmp(res->tx_pfc_mode, "on", 2)) ? 1 : 0;
6788 	pfc_queue_conf.mode = rx_tx_onoff_2_mode[rx_fc_enable][tx_fc_enable];
6789 	pfc_queue_conf.rx_pause.tc  = res->tx_tc;
6790 	pfc_queue_conf.rx_pause.tx_qid = res->tx_qid;
6791 	pfc_queue_conf.tx_pause.tc  = res->rx_tc;
6792 	pfc_queue_conf.tx_pause.rx_qid  = res->rx_qid;
6793 	pfc_queue_conf.tx_pause.pause_time = res->pause_time;
6794 
6795 	ret = rte_eth_dev_priority_flow_ctrl_queue_configure(res->port_id,
6796 							     &pfc_queue_conf);
6797 	if (ret != 0) {
6798 		fprintf(stderr,
6799 			"bad queue priority flow control parameter, rc = %d\n",
6800 			ret);
6801 	}
6802 }
6803 
6804 static cmdline_parse_token_string_t cmd_q_pfc_set_set =
6805 	TOKEN_STRING_INITIALIZER(struct cmd_queue_priority_flow_ctrl_set_result,
6806 				set, "set");
6807 static cmdline_parse_token_string_t cmd_q_pfc_set_flow_ctrl =
6808 	TOKEN_STRING_INITIALIZER(struct cmd_queue_priority_flow_ctrl_set_result,
6809 				pfc_queue_ctrl, "pfc_queue_ctrl");
6810 static cmdline_parse_token_num_t cmd_q_pfc_set_portid =
6811 	TOKEN_NUM_INITIALIZER(struct cmd_queue_priority_flow_ctrl_set_result,
6812 				port_id, RTE_UINT16);
6813 static cmdline_parse_token_string_t cmd_q_pfc_set_rx =
6814 	TOKEN_STRING_INITIALIZER(struct cmd_queue_priority_flow_ctrl_set_result,
6815 				rx, "rx");
6816 static cmdline_parse_token_string_t cmd_q_pfc_set_rx_mode =
6817 	TOKEN_STRING_INITIALIZER(struct cmd_queue_priority_flow_ctrl_set_result,
6818 				rx_pfc_mode, "on#off");
6819 static cmdline_parse_token_num_t cmd_q_pfc_set_tx_qid =
6820 	TOKEN_NUM_INITIALIZER(struct cmd_queue_priority_flow_ctrl_set_result,
6821 				tx_qid, RTE_UINT16);
6822 static cmdline_parse_token_num_t cmd_q_pfc_set_tx_tc =
6823 	TOKEN_NUM_INITIALIZER(struct cmd_queue_priority_flow_ctrl_set_result,
6824 				tx_tc, RTE_UINT8);
6825 static cmdline_parse_token_string_t cmd_q_pfc_set_tx =
6826 	TOKEN_STRING_INITIALIZER(struct cmd_queue_priority_flow_ctrl_set_result,
6827 				tx, "tx");
6828 static cmdline_parse_token_string_t cmd_q_pfc_set_tx_mode =
6829 	TOKEN_STRING_INITIALIZER(struct cmd_queue_priority_flow_ctrl_set_result,
6830 				tx_pfc_mode, "on#off");
6831 static cmdline_parse_token_num_t cmd_q_pfc_set_rx_qid =
6832 	TOKEN_NUM_INITIALIZER(struct cmd_queue_priority_flow_ctrl_set_result,
6833 				rx_qid, RTE_UINT16);
6834 static cmdline_parse_token_num_t cmd_q_pfc_set_rx_tc =
6835 	TOKEN_NUM_INITIALIZER(struct cmd_queue_priority_flow_ctrl_set_result,
6836 				rx_tc, RTE_UINT8);
6837 static cmdline_parse_token_num_t cmd_q_pfc_set_pause_time =
6838 	TOKEN_NUM_INITIALIZER(struct cmd_queue_priority_flow_ctrl_set_result,
6839 				pause_time, RTE_UINT16);
6840 
6841 static cmdline_parse_inst_t cmd_queue_priority_flow_control_set = {
6842 	.f = cmd_queue_priority_flow_ctrl_set_parsed,
6843 	.data = NULL,
6844 	.help_str = "set pfc_queue_ctrl <port_id> rx <on|off> <tx_qid> <tx_tc> "
6845 		"tx <on|off> <rx_qid> <rx_tc> <pause_time>: "
6846 		"Configure the Ethernet queue priority flow control",
6847 	.tokens = {
6848 		(void *)&cmd_q_pfc_set_set,
6849 		(void *)&cmd_q_pfc_set_flow_ctrl,
6850 		(void *)&cmd_q_pfc_set_portid,
6851 		(void *)&cmd_q_pfc_set_rx,
6852 		(void *)&cmd_q_pfc_set_rx_mode,
6853 		(void *)&cmd_q_pfc_set_tx_qid,
6854 		(void *)&cmd_q_pfc_set_tx_tc,
6855 		(void *)&cmd_q_pfc_set_tx,
6856 		(void *)&cmd_q_pfc_set_tx_mode,
6857 		(void *)&cmd_q_pfc_set_rx_qid,
6858 		(void *)&cmd_q_pfc_set_rx_tc,
6859 		(void *)&cmd_q_pfc_set_pause_time,
6860 		NULL,
6861 	},
6862 };
6863 
6864 /* *** RESET CONFIGURATION *** */
6865 struct cmd_reset_result {
6866 	cmdline_fixed_string_t reset;
6867 	cmdline_fixed_string_t def;
6868 };
6869 
6870 static void cmd_reset_parsed(__rte_unused void *parsed_result,
6871 			     struct cmdline *cl,
6872 			     __rte_unused void *data)
6873 {
6874 	cmdline_printf(cl, "Reset to default forwarding configuration...\n");
6875 	set_def_fwd_config();
6876 }
6877 
6878 static cmdline_parse_token_string_t cmd_reset_set =
6879 	TOKEN_STRING_INITIALIZER(struct cmd_reset_result, reset, "set");
6880 static cmdline_parse_token_string_t cmd_reset_def =
6881 	TOKEN_STRING_INITIALIZER(struct cmd_reset_result, def,
6882 				 "default");
6883 
6884 static cmdline_parse_inst_t cmd_reset = {
6885 	.f = cmd_reset_parsed,
6886 	.data = NULL,
6887 	.help_str = "set default: Reset default forwarding configuration",
6888 	.tokens = {
6889 		(void *)&cmd_reset_set,
6890 		(void *)&cmd_reset_def,
6891 		NULL,
6892 	},
6893 };
6894 
6895 /* *** START FORWARDING *** */
6896 struct cmd_start_result {
6897 	cmdline_fixed_string_t start;
6898 };
6899 
6900 static cmdline_parse_token_string_t cmd_start_start =
6901 	TOKEN_STRING_INITIALIZER(struct cmd_start_result, start, "start");
6902 
6903 static void cmd_start_parsed(__rte_unused void *parsed_result,
6904 			     __rte_unused struct cmdline *cl,
6905 			     __rte_unused void *data)
6906 {
6907 	start_packet_forwarding(0);
6908 }
6909 
6910 static cmdline_parse_inst_t cmd_start = {
6911 	.f = cmd_start_parsed,
6912 	.data = NULL,
6913 	.help_str = "start: Start packet forwarding",
6914 	.tokens = {
6915 		(void *)&cmd_start_start,
6916 		NULL,
6917 	},
6918 };
6919 
6920 /* *** START FORWARDING WITH ONE TX BURST FIRST *** */
6921 struct cmd_start_tx_first_result {
6922 	cmdline_fixed_string_t start;
6923 	cmdline_fixed_string_t tx_first;
6924 };
6925 
6926 static void
6927 cmd_start_tx_first_parsed(__rte_unused void *parsed_result,
6928 			  __rte_unused struct cmdline *cl,
6929 			  __rte_unused void *data)
6930 {
6931 	start_packet_forwarding(1);
6932 }
6933 
6934 static cmdline_parse_token_string_t cmd_start_tx_first_start =
6935 	TOKEN_STRING_INITIALIZER(struct cmd_start_tx_first_result, start,
6936 				 "start");
6937 static cmdline_parse_token_string_t cmd_start_tx_first_tx_first =
6938 	TOKEN_STRING_INITIALIZER(struct cmd_start_tx_first_result,
6939 				 tx_first, "tx_first");
6940 
6941 static cmdline_parse_inst_t cmd_start_tx_first = {
6942 	.f = cmd_start_tx_first_parsed,
6943 	.data = NULL,
6944 	.help_str = "start tx_first: Start packet forwarding, "
6945 		"after sending 1 burst of packets",
6946 	.tokens = {
6947 		(void *)&cmd_start_tx_first_start,
6948 		(void *)&cmd_start_tx_first_tx_first,
6949 		NULL,
6950 	},
6951 };
6952 
6953 /* *** START FORWARDING WITH N TX BURST FIRST *** */
6954 struct cmd_start_tx_first_n_result {
6955 	cmdline_fixed_string_t start;
6956 	cmdline_fixed_string_t tx_first;
6957 	uint32_t tx_num;
6958 };
6959 
6960 static void
6961 cmd_start_tx_first_n_parsed(void *parsed_result,
6962 			  __rte_unused struct cmdline *cl,
6963 			  __rte_unused void *data)
6964 {
6965 	struct cmd_start_tx_first_n_result *res = parsed_result;
6966 
6967 	start_packet_forwarding(res->tx_num);
6968 }
6969 
6970 static cmdline_parse_token_string_t cmd_start_tx_first_n_start =
6971 	TOKEN_STRING_INITIALIZER(struct cmd_start_tx_first_n_result,
6972 			start, "start");
6973 static cmdline_parse_token_string_t cmd_start_tx_first_n_tx_first =
6974 	TOKEN_STRING_INITIALIZER(struct cmd_start_tx_first_n_result,
6975 			tx_first, "tx_first");
6976 static cmdline_parse_token_num_t cmd_start_tx_first_n_tx_num =
6977 	TOKEN_NUM_INITIALIZER(struct cmd_start_tx_first_n_result,
6978 			tx_num, RTE_UINT32);
6979 
6980 static cmdline_parse_inst_t cmd_start_tx_first_n = {
6981 	.f = cmd_start_tx_first_n_parsed,
6982 	.data = NULL,
6983 	.help_str = "start tx_first <num>: "
6984 		"packet forwarding, after sending <num> bursts of packets",
6985 	.tokens = {
6986 		(void *)&cmd_start_tx_first_n_start,
6987 		(void *)&cmd_start_tx_first_n_tx_first,
6988 		(void *)&cmd_start_tx_first_n_tx_num,
6989 		NULL,
6990 	},
6991 };
6992 
6993 /* *** SET LINK UP *** */
6994 struct cmd_set_link_up_result {
6995 	cmdline_fixed_string_t set;
6996 	cmdline_fixed_string_t link_up;
6997 	cmdline_fixed_string_t port;
6998 	portid_t port_id;
6999 };
7000 
7001 static cmdline_parse_token_string_t cmd_set_link_up_set =
7002 	TOKEN_STRING_INITIALIZER(struct cmd_set_link_up_result, set, "set");
7003 static cmdline_parse_token_string_t cmd_set_link_up_link_up =
7004 	TOKEN_STRING_INITIALIZER(struct cmd_set_link_up_result, link_up,
7005 				"link-up");
7006 static cmdline_parse_token_string_t cmd_set_link_up_port =
7007 	TOKEN_STRING_INITIALIZER(struct cmd_set_link_up_result, port, "port");
7008 static cmdline_parse_token_num_t cmd_set_link_up_port_id =
7009 	TOKEN_NUM_INITIALIZER(struct cmd_set_link_up_result, port_id,
7010 				RTE_UINT16);
7011 
7012 static void cmd_set_link_up_parsed(__rte_unused void *parsed_result,
7013 			     __rte_unused struct cmdline *cl,
7014 			     __rte_unused void *data)
7015 {
7016 	struct cmd_set_link_up_result *res = parsed_result;
7017 	dev_set_link_up(res->port_id);
7018 }
7019 
7020 static cmdline_parse_inst_t cmd_set_link_up = {
7021 	.f = cmd_set_link_up_parsed,
7022 	.data = NULL,
7023 	.help_str = "set link-up port <port id>",
7024 	.tokens = {
7025 		(void *)&cmd_set_link_up_set,
7026 		(void *)&cmd_set_link_up_link_up,
7027 		(void *)&cmd_set_link_up_port,
7028 		(void *)&cmd_set_link_up_port_id,
7029 		NULL,
7030 	},
7031 };
7032 
7033 /* *** SET LINK DOWN *** */
7034 struct cmd_set_link_down_result {
7035 	cmdline_fixed_string_t set;
7036 	cmdline_fixed_string_t link_down;
7037 	cmdline_fixed_string_t port;
7038 	portid_t port_id;
7039 };
7040 
7041 static cmdline_parse_token_string_t cmd_set_link_down_set =
7042 	TOKEN_STRING_INITIALIZER(struct cmd_set_link_down_result, set, "set");
7043 static cmdline_parse_token_string_t cmd_set_link_down_link_down =
7044 	TOKEN_STRING_INITIALIZER(struct cmd_set_link_down_result, link_down,
7045 				"link-down");
7046 static cmdline_parse_token_string_t cmd_set_link_down_port =
7047 	TOKEN_STRING_INITIALIZER(struct cmd_set_link_down_result, port, "port");
7048 static cmdline_parse_token_num_t cmd_set_link_down_port_id =
7049 	TOKEN_NUM_INITIALIZER(struct cmd_set_link_down_result, port_id,
7050 				RTE_UINT16);
7051 
7052 static void cmd_set_link_down_parsed(
7053 				__rte_unused void *parsed_result,
7054 				__rte_unused struct cmdline *cl,
7055 				__rte_unused void *data)
7056 {
7057 	struct cmd_set_link_down_result *res = parsed_result;
7058 	dev_set_link_down(res->port_id);
7059 }
7060 
7061 static cmdline_parse_inst_t cmd_set_link_down = {
7062 	.f = cmd_set_link_down_parsed,
7063 	.data = NULL,
7064 	.help_str = "set link-down port <port id>",
7065 	.tokens = {
7066 		(void *)&cmd_set_link_down_set,
7067 		(void *)&cmd_set_link_down_link_down,
7068 		(void *)&cmd_set_link_down_port,
7069 		(void *)&cmd_set_link_down_port_id,
7070 		NULL,
7071 	},
7072 };
7073 
7074 /* *** SHOW CFG *** */
7075 struct cmd_showcfg_result {
7076 	cmdline_fixed_string_t show;
7077 	cmdline_fixed_string_t cfg;
7078 	cmdline_fixed_string_t what;
7079 };
7080 
7081 static void cmd_showcfg_parsed(void *parsed_result,
7082 			       __rte_unused struct cmdline *cl,
7083 			       __rte_unused void *data)
7084 {
7085 	struct cmd_showcfg_result *res = parsed_result;
7086 	if (!strcmp(res->what, "rxtx"))
7087 		rxtx_config_display();
7088 	else if (!strcmp(res->what, "cores"))
7089 		fwd_lcores_config_display();
7090 	else if (!strcmp(res->what, "fwd"))
7091 		pkt_fwd_config_display(&cur_fwd_config);
7092 	else if (!strcmp(res->what, "rxoffs"))
7093 		show_rx_pkt_offsets();
7094 	else if (!strcmp(res->what, "rxpkts"))
7095 		show_rx_pkt_segments();
7096 	else if (!strcmp(res->what, "rxhdrs"))
7097 		show_rx_pkt_hdrs();
7098 	else if (!strcmp(res->what, "txpkts"))
7099 		show_tx_pkt_segments();
7100 	else if (!strcmp(res->what, "txtimes"))
7101 		show_tx_pkt_times();
7102 }
7103 
7104 static cmdline_parse_token_string_t cmd_showcfg_show =
7105 	TOKEN_STRING_INITIALIZER(struct cmd_showcfg_result, show, "show");
7106 static cmdline_parse_token_string_t cmd_showcfg_port =
7107 	TOKEN_STRING_INITIALIZER(struct cmd_showcfg_result, cfg, "config");
7108 static cmdline_parse_token_string_t cmd_showcfg_what =
7109 	TOKEN_STRING_INITIALIZER(struct cmd_showcfg_result, what,
7110 				 "rxtx#cores#fwd#rxoffs#rxpkts#rxhdrs#txpkts#txtimes");
7111 
7112 static cmdline_parse_inst_t cmd_showcfg = {
7113 	.f = cmd_showcfg_parsed,
7114 	.data = NULL,
7115 	.help_str = "show config rxtx|cores|fwd|rxoffs|rxpkts|rxhdrs|txpkts|txtimes",
7116 	.tokens = {
7117 		(void *)&cmd_showcfg_show,
7118 		(void *)&cmd_showcfg_port,
7119 		(void *)&cmd_showcfg_what,
7120 		NULL,
7121 	},
7122 };
7123 
7124 /* *** SHOW ALL PORT INFO *** */
7125 struct cmd_showportall_result {
7126 	cmdline_fixed_string_t show;
7127 	cmdline_fixed_string_t port;
7128 	cmdline_fixed_string_t what;
7129 	cmdline_fixed_string_t all;
7130 };
7131 
7132 static void cmd_showportall_parsed(void *parsed_result,
7133 				__rte_unused struct cmdline *cl,
7134 				__rte_unused void *data)
7135 {
7136 	portid_t i;
7137 
7138 	struct cmd_showportall_result *res = parsed_result;
7139 	if (!strcmp(res->show, "clear")) {
7140 		if (!strcmp(res->what, "stats"))
7141 			RTE_ETH_FOREACH_DEV(i)
7142 				nic_stats_clear(i);
7143 		else if (!strcmp(res->what, "xstats"))
7144 			RTE_ETH_FOREACH_DEV(i)
7145 				nic_xstats_clear(i);
7146 	} else if (!strcmp(res->what, "info"))
7147 		RTE_ETH_FOREACH_DEV(i)
7148 			port_infos_display(i);
7149 	else if (!strcmp(res->what, "summary")) {
7150 		port_summary_header_display();
7151 		RTE_ETH_FOREACH_DEV(i)
7152 			port_summary_display(i);
7153 	}
7154 	else if (!strcmp(res->what, "stats"))
7155 		RTE_ETH_FOREACH_DEV(i)
7156 			nic_stats_display(i);
7157 	else if (!strcmp(res->what, "xstats"))
7158 		RTE_ETH_FOREACH_DEV(i)
7159 			nic_xstats_display(i);
7160 #if defined(RTE_NET_I40E) || defined(RTE_NET_IXGBE)
7161 	else if (!strcmp(res->what, "fdir"))
7162 		RTE_ETH_FOREACH_DEV(i)
7163 			fdir_get_infos(i);
7164 #endif
7165 	else if (!strcmp(res->what, "dcb_tc"))
7166 		RTE_ETH_FOREACH_DEV(i)
7167 			port_dcb_info_display(i);
7168 }
7169 
7170 static cmdline_parse_token_string_t cmd_showportall_show =
7171 	TOKEN_STRING_INITIALIZER(struct cmd_showportall_result, show,
7172 				 "show#clear");
7173 static cmdline_parse_token_string_t cmd_showportall_port =
7174 	TOKEN_STRING_INITIALIZER(struct cmd_showportall_result, port, "port");
7175 static cmdline_parse_token_string_t cmd_showportall_what =
7176 	TOKEN_STRING_INITIALIZER(struct cmd_showportall_result, what,
7177 				 "info#summary#stats#xstats#fdir#dcb_tc");
7178 static cmdline_parse_token_string_t cmd_showportall_all =
7179 	TOKEN_STRING_INITIALIZER(struct cmd_showportall_result, all, "all");
7180 static cmdline_parse_inst_t cmd_showportall = {
7181 	.f = cmd_showportall_parsed,
7182 	.data = NULL,
7183 	.help_str = "show|clear port "
7184 		"info|summary|stats|xstats|fdir|dcb_tc all",
7185 	.tokens = {
7186 		(void *)&cmd_showportall_show,
7187 		(void *)&cmd_showportall_port,
7188 		(void *)&cmd_showportall_what,
7189 		(void *)&cmd_showportall_all,
7190 		NULL,
7191 	},
7192 };
7193 
7194 /* *** SHOW PORT INFO *** */
7195 struct cmd_showport_result {
7196 	cmdline_fixed_string_t show;
7197 	cmdline_fixed_string_t port;
7198 	cmdline_fixed_string_t what;
7199 	uint16_t portnum;
7200 };
7201 
7202 static void cmd_showport_parsed(void *parsed_result,
7203 				__rte_unused struct cmdline *cl,
7204 				__rte_unused void *data)
7205 {
7206 	struct cmd_showport_result *res = parsed_result;
7207 	if (!strcmp(res->show, "clear")) {
7208 		if (!strcmp(res->what, "stats"))
7209 			nic_stats_clear(res->portnum);
7210 		else if (!strcmp(res->what, "xstats"))
7211 			nic_xstats_clear(res->portnum);
7212 	} else if (!strcmp(res->what, "info"))
7213 		port_infos_display(res->portnum);
7214 	else if (!strcmp(res->what, "summary")) {
7215 		port_summary_header_display();
7216 		port_summary_display(res->portnum);
7217 	}
7218 	else if (!strcmp(res->what, "stats"))
7219 		nic_stats_display(res->portnum);
7220 	else if (!strcmp(res->what, "xstats"))
7221 		nic_xstats_display(res->portnum);
7222 #if defined(RTE_NET_I40E) || defined(RTE_NET_IXGBE)
7223 	else if (!strcmp(res->what, "fdir"))
7224 		 fdir_get_infos(res->portnum);
7225 #endif
7226 	else if (!strcmp(res->what, "dcb_tc"))
7227 		port_dcb_info_display(res->portnum);
7228 }
7229 
7230 static cmdline_parse_token_string_t cmd_showport_show =
7231 	TOKEN_STRING_INITIALIZER(struct cmd_showport_result, show,
7232 				 "show#clear");
7233 static cmdline_parse_token_string_t cmd_showport_port =
7234 	TOKEN_STRING_INITIALIZER(struct cmd_showport_result, port, "port");
7235 static cmdline_parse_token_string_t cmd_showport_what =
7236 	TOKEN_STRING_INITIALIZER(struct cmd_showport_result, what,
7237 				 "info#summary#stats#xstats#fdir#dcb_tc");
7238 static cmdline_parse_token_num_t cmd_showport_portnum =
7239 	TOKEN_NUM_INITIALIZER(struct cmd_showport_result, portnum, RTE_UINT16);
7240 
7241 static cmdline_parse_inst_t cmd_showport = {
7242 	.f = cmd_showport_parsed,
7243 	.data = NULL,
7244 	.help_str = "show|clear port "
7245 		"info|summary|stats|xstats|fdir|dcb_tc "
7246 		"<port_id>",
7247 	.tokens = {
7248 		(void *)&cmd_showport_show,
7249 		(void *)&cmd_showport_port,
7250 		(void *)&cmd_showport_what,
7251 		(void *)&cmd_showport_portnum,
7252 		NULL,
7253 	},
7254 };
7255 
7256 /* *** show port representors information *** */
7257 struct cmd_representor_info_result {
7258 	cmdline_fixed_string_t cmd_show;
7259 	cmdline_fixed_string_t cmd_port;
7260 	cmdline_fixed_string_t cmd_info;
7261 	cmdline_fixed_string_t cmd_keyword;
7262 	portid_t cmd_pid;
7263 };
7264 
7265 static void
7266 cmd_representor_info_parsed(void *parsed_result,
7267 		__rte_unused struct cmdline *cl,
7268 		__rte_unused void *data)
7269 {
7270 	struct cmd_representor_info_result *res = parsed_result;
7271 	struct rte_eth_representor_info *info;
7272 	struct rte_eth_representor_range *range;
7273 	uint32_t range_diff;
7274 	uint32_t i;
7275 	int ret;
7276 	int num;
7277 
7278 	if (!rte_eth_dev_is_valid_port(res->cmd_pid)) {
7279 		fprintf(stderr, "Invalid port id %u\n", res->cmd_pid);
7280 		return;
7281 	}
7282 
7283 	ret = rte_eth_representor_info_get(res->cmd_pid, NULL);
7284 	if (ret < 0) {
7285 		fprintf(stderr,
7286 			"Failed to get the number of representor info ranges for port %hu: %s\n",
7287 			res->cmd_pid, rte_strerror(-ret));
7288 		return;
7289 	}
7290 	num = ret;
7291 
7292 	info = calloc(1, sizeof(*info) + num * sizeof(info->ranges[0]));
7293 	if (info == NULL) {
7294 		fprintf(stderr,
7295 			"Failed to allocate memory for representor info for port %hu\n",
7296 			res->cmd_pid);
7297 		return;
7298 	}
7299 	info->nb_ranges_alloc = num;
7300 
7301 	ret = rte_eth_representor_info_get(res->cmd_pid, info);
7302 	if (ret < 0) {
7303 		fprintf(stderr,
7304 			"Failed to get the representor info for port %hu: %s\n",
7305 			res->cmd_pid, rte_strerror(-ret));
7306 		free(info);
7307 		return;
7308 	}
7309 
7310 	printf("Port controller: %hu\n", info->controller);
7311 	printf("Port PF: %hu\n", info->pf);
7312 
7313 	printf("Ranges: %u\n", info->nb_ranges);
7314 	for (i = 0; i < info->nb_ranges; i++) {
7315 		range = &info->ranges[i];
7316 		range_diff = range->id_end - range->id_base;
7317 
7318 		printf("%u. ", i + 1);
7319 		printf("'%s' ", range->name);
7320 		if (range_diff > 0)
7321 			printf("[%u-%u]: ", range->id_base, range->id_end);
7322 		else
7323 			printf("[%u]: ", range->id_base);
7324 
7325 		printf("Controller %d, PF %d", range->controller, range->pf);
7326 
7327 		switch (range->type) {
7328 		case RTE_ETH_REPRESENTOR_NONE:
7329 			printf(", NONE\n");
7330 			break;
7331 		case RTE_ETH_REPRESENTOR_VF:
7332 			if (range_diff > 0)
7333 				printf(", VF %d..%d\n", range->vf,
7334 				       range->vf + range_diff);
7335 			else
7336 				printf(", VF %d\n", range->vf);
7337 			break;
7338 		case RTE_ETH_REPRESENTOR_SF:
7339 			printf(", SF %d\n", range->sf);
7340 			break;
7341 		case RTE_ETH_REPRESENTOR_PF:
7342 			if (range_diff > 0)
7343 				printf("..%d\n", range->pf + range_diff);
7344 			else
7345 				printf("\n");
7346 			break;
7347 		default:
7348 			printf(", UNKNOWN TYPE %d\n", range->type);
7349 			break;
7350 		}
7351 	}
7352 
7353 	free(info);
7354 }
7355 
7356 static cmdline_parse_token_string_t cmd_representor_info_show =
7357 	TOKEN_STRING_INITIALIZER(struct cmd_representor_info_result,
7358 			cmd_show, "show");
7359 static cmdline_parse_token_string_t cmd_representor_info_port =
7360 	TOKEN_STRING_INITIALIZER(struct cmd_representor_info_result,
7361 			cmd_port, "port");
7362 static cmdline_parse_token_string_t cmd_representor_info_info =
7363 	TOKEN_STRING_INITIALIZER(struct cmd_representor_info_result,
7364 			cmd_info, "info");
7365 static cmdline_parse_token_num_t cmd_representor_info_pid =
7366 	TOKEN_NUM_INITIALIZER(struct cmd_representor_info_result,
7367 			cmd_pid, RTE_UINT16);
7368 static cmdline_parse_token_string_t cmd_representor_info_keyword =
7369 	TOKEN_STRING_INITIALIZER(struct cmd_representor_info_result,
7370 			cmd_keyword, "representor");
7371 
7372 static cmdline_parse_inst_t cmd_representor_info = {
7373 	.f = cmd_representor_info_parsed,
7374 	.data = NULL,
7375 	.help_str = "show port info <port_id> representor",
7376 	.tokens = {
7377 		(void *)&cmd_representor_info_show,
7378 		(void *)&cmd_representor_info_port,
7379 		(void *)&cmd_representor_info_info,
7380 		(void *)&cmd_representor_info_pid,
7381 		(void *)&cmd_representor_info_keyword,
7382 		NULL,
7383 	},
7384 };
7385 
7386 
7387 /* *** SHOW DEVICE INFO *** */
7388 struct cmd_showdevice_result {
7389 	cmdline_fixed_string_t show;
7390 	cmdline_fixed_string_t device;
7391 	cmdline_fixed_string_t what;
7392 	cmdline_fixed_string_t identifier;
7393 };
7394 
7395 static void cmd_showdevice_parsed(void *parsed_result,
7396 				__rte_unused struct cmdline *cl,
7397 				__rte_unused void *data)
7398 {
7399 	struct cmd_showdevice_result *res = parsed_result;
7400 	if (!strcmp(res->what, "info")) {
7401 		if (!strcmp(res->identifier, "all"))
7402 			device_infos_display(NULL);
7403 		else
7404 			device_infos_display(res->identifier);
7405 	}
7406 }
7407 
7408 static cmdline_parse_token_string_t cmd_showdevice_show =
7409 	TOKEN_STRING_INITIALIZER(struct cmd_showdevice_result, show,
7410 				 "show");
7411 static cmdline_parse_token_string_t cmd_showdevice_device =
7412 	TOKEN_STRING_INITIALIZER(struct cmd_showdevice_result, device, "device");
7413 static cmdline_parse_token_string_t cmd_showdevice_what =
7414 	TOKEN_STRING_INITIALIZER(struct cmd_showdevice_result, what,
7415 				 "info");
7416 static cmdline_parse_token_string_t cmd_showdevice_identifier =
7417 	TOKEN_STRING_INITIALIZER(struct cmd_showdevice_result,
7418 			identifier, NULL);
7419 
7420 static cmdline_parse_inst_t cmd_showdevice = {
7421 	.f = cmd_showdevice_parsed,
7422 	.data = NULL,
7423 	.help_str = "show device info <identifier>|all",
7424 	.tokens = {
7425 		(void *)&cmd_showdevice_show,
7426 		(void *)&cmd_showdevice_device,
7427 		(void *)&cmd_showdevice_what,
7428 		(void *)&cmd_showdevice_identifier,
7429 		NULL,
7430 	},
7431 };
7432 
7433 /* *** SHOW MODULE EEPROM/EEPROM port INFO *** */
7434 struct cmd_showeeprom_result {
7435 	cmdline_fixed_string_t show;
7436 	cmdline_fixed_string_t port;
7437 	uint16_t portnum;
7438 	cmdline_fixed_string_t type;
7439 };
7440 
7441 static void cmd_showeeprom_parsed(void *parsed_result,
7442 		__rte_unused struct cmdline *cl,
7443 		__rte_unused void *data)
7444 {
7445 	struct cmd_showeeprom_result *res = parsed_result;
7446 
7447 	if (!strcmp(res->type, "eeprom"))
7448 		port_eeprom_display(res->portnum);
7449 	else if (!strcmp(res->type, "module_eeprom"))
7450 		port_module_eeprom_display(res->portnum);
7451 	else
7452 		fprintf(stderr, "Unknown argument\n");
7453 }
7454 
7455 static cmdline_parse_token_string_t cmd_showeeprom_show =
7456 	TOKEN_STRING_INITIALIZER(struct cmd_showeeprom_result, show, "show");
7457 static cmdline_parse_token_string_t cmd_showeeprom_port =
7458 	TOKEN_STRING_INITIALIZER(struct cmd_showeeprom_result, port, "port");
7459 static cmdline_parse_token_num_t cmd_showeeprom_portnum =
7460 	TOKEN_NUM_INITIALIZER(struct cmd_showeeprom_result, portnum,
7461 			RTE_UINT16);
7462 static cmdline_parse_token_string_t cmd_showeeprom_type =
7463 	TOKEN_STRING_INITIALIZER(struct cmd_showeeprom_result, type, "module_eeprom#eeprom");
7464 
7465 static cmdline_parse_inst_t cmd_showeeprom = {
7466 	.f = cmd_showeeprom_parsed,
7467 	.data = NULL,
7468 	.help_str = "show port <port_id> module_eeprom|eeprom",
7469 	.tokens = {
7470 		(void *)&cmd_showeeprom_show,
7471 		(void *)&cmd_showeeprom_port,
7472 		(void *)&cmd_showeeprom_portnum,
7473 		(void *)&cmd_showeeprom_type,
7474 		NULL,
7475 	},
7476 };
7477 
7478 /* *** SET PORT EEPROM *** */
7479 struct cmd_seteeprom_result {
7480 	cmdline_fixed_string_t set;
7481 	cmdline_fixed_string_t port;
7482 	uint16_t portnum;
7483 	cmdline_fixed_string_t eeprom;
7484 	cmdline_fixed_string_t confirm_str;
7485 	cmdline_fixed_string_t magic_str;
7486 	uint32_t magic;
7487 	cmdline_fixed_string_t value;
7488 	cmdline_multi_string_t token_str;
7489 };
7490 
7491 static void cmd_seteeprom_parsed(void *parsed_result,
7492 		__rte_unused struct cmdline *cl,
7493 		__rte_unused void *data)
7494 {
7495 	struct cmd_seteeprom_result *res = parsed_result;
7496 	uint32_t offset = 0;
7497 	uint32_t length;
7498 	uint8_t *value;
7499 	char *token_str;
7500 	char *token;
7501 
7502 	token_str = res->token_str;
7503 	token = strtok_r(token_str, " \f\n\r\t\v", &token_str);
7504 
7505 	/* Parse Hex string to Byte data */
7506 	if (strlen(token) % 2 != 0) {
7507 		fprintf(stderr, "Bad Argument: %s\nHex string must be in multiples of 2 Bytes\n",
7508 			token);
7509 		return;
7510 	}
7511 
7512 	length = strlen(token) / 2;
7513 	value = calloc(length, sizeof(uint8_t));
7514 	for (int count = 0; count < (int)(length); count++) {
7515 		if (sscanf(token, "%2hhx", &value[count]) != 1) {
7516 			fprintf(stderr, "Bad Argument: %s\nValue must be a hex string\n",
7517 				token - (count + 1));
7518 			goto out;
7519 		}
7520 		token += 2;
7521 	}
7522 
7523 	/* Second token: offset string */
7524 	token = strtok_r(token_str, " \f\n\r\t\v", &token_str);
7525 	if (token != NULL) {
7526 		if (strcmp(token, "offset") == 0) {
7527 			/* Third token: offset */
7528 			token = strtok_r(token_str, " \f\n\r\t\v", &token_str);
7529 			if (token == NULL) {
7530 				fprintf(stderr, "No offset specified\n");
7531 				goto out;
7532 			}
7533 
7534 			char *end;
7535 			offset = strtoul(token, &end, 10);
7536 			if (offset == 0 && strcmp(end, "") != 0) {
7537 				fprintf(stderr, "Bad Argument: %s\n", token);
7538 				goto out;
7539 			}
7540 		} else {
7541 			fprintf(stderr, "Bad Argument: %s\n", token);
7542 			goto out;
7543 		}
7544 	}
7545 
7546 	port_eeprom_set(res->portnum, res->magic, offset, length, value);
7547 
7548 out:
7549 	free(value);
7550 }
7551 
7552 static cmdline_parse_token_string_t cmd_seteeprom_set =
7553 	TOKEN_STRING_INITIALIZER(struct cmd_seteeprom_result, set, "set");
7554 static cmdline_parse_token_string_t cmd_seteeprom_port =
7555 	TOKEN_STRING_INITIALIZER(struct cmd_seteeprom_result, port, "port");
7556 static cmdline_parse_token_num_t cmd_seteeprom_portnum =
7557 	TOKEN_NUM_INITIALIZER(struct cmd_seteeprom_result, portnum, RTE_UINT16);
7558 static cmdline_parse_token_string_t cmd_seteeprom_eeprom =
7559 	TOKEN_STRING_INITIALIZER(struct cmd_seteeprom_result, eeprom, "eeprom");
7560 static cmdline_parse_token_string_t cmd_seteeprom_confirm_str =
7561 	TOKEN_STRING_INITIALIZER(struct cmd_seteeprom_result, confirm_str, "accept_risk");
7562 static cmdline_parse_token_string_t cmd_seteeprom_magic_str =
7563 	TOKEN_STRING_INITIALIZER(struct cmd_seteeprom_result, magic_str, "magic");
7564 static cmdline_parse_token_num_t cmd_seteeprom_magic =
7565 	TOKEN_NUM_INITIALIZER(struct cmd_seteeprom_result, magic, RTE_UINT32);
7566 static cmdline_parse_token_string_t cmd_seteeprom_value =
7567 	TOKEN_STRING_INITIALIZER(struct cmd_seteeprom_result, value, "value");
7568 static cmdline_parse_token_string_t cmd_seteeprom_token_str =
7569 	TOKEN_STRING_INITIALIZER(struct cmd_seteeprom_result, token_str, TOKEN_STRING_MULTI);
7570 
7571 static cmdline_parse_inst_t cmd_seteeprom = {
7572 	.f = cmd_seteeprom_parsed,
7573 	.data = NULL,
7574 	.help_str = "set port <port_id> eeprom <accept_risk> magic <magic_num> "
7575 		"value <value> offset <offset>: Set eeprom value for port_id.\n"
7576 		"Note:\n"
7577 		"This is a high-risk command and its misuse may result in "
7578 		"unexpected behaviour from the NIC.\n"
7579 		"By inserting \"accept_risk\" into the command, the user is "
7580 		"acknowledging and taking responsibility for this risk.",
7581 	.tokens = {
7582 		(void *)&cmd_seteeprom_set,
7583 		(void *)&cmd_seteeprom_port,
7584 		(void *)&cmd_seteeprom_portnum,
7585 		(void *)&cmd_seteeprom_eeprom,
7586 		(void *)&cmd_seteeprom_confirm_str,
7587 		(void *)&cmd_seteeprom_magic_str,
7588 		(void *)&cmd_seteeprom_magic,
7589 		(void *)&cmd_seteeprom_value,
7590 		(void *)&cmd_seteeprom_token_str,
7591 		NULL,
7592 	},
7593 };
7594 
7595 /* *** SHOW QUEUE INFO *** */
7596 struct cmd_showqueue_result {
7597 	cmdline_fixed_string_t show;
7598 	cmdline_fixed_string_t type;
7599 	cmdline_fixed_string_t what;
7600 	uint16_t portnum;
7601 	uint16_t queuenum;
7602 };
7603 
7604 static void
7605 cmd_showqueue_parsed(void *parsed_result,
7606 	__rte_unused struct cmdline *cl,
7607 	__rte_unused void *data)
7608 {
7609 	struct cmd_showqueue_result *res = parsed_result;
7610 
7611 	if (!strcmp(res->type, "rxq"))
7612 		rx_queue_infos_display(res->portnum, res->queuenum);
7613 	else if (!strcmp(res->type, "txq"))
7614 		tx_queue_infos_display(res->portnum, res->queuenum);
7615 }
7616 
7617 static cmdline_parse_token_string_t cmd_showqueue_show =
7618 	TOKEN_STRING_INITIALIZER(struct cmd_showqueue_result, show, "show");
7619 static cmdline_parse_token_string_t cmd_showqueue_type =
7620 	TOKEN_STRING_INITIALIZER(struct cmd_showqueue_result, type, "rxq#txq");
7621 static cmdline_parse_token_string_t cmd_showqueue_what =
7622 	TOKEN_STRING_INITIALIZER(struct cmd_showqueue_result, what, "info");
7623 static cmdline_parse_token_num_t cmd_showqueue_portnum =
7624 	TOKEN_NUM_INITIALIZER(struct cmd_showqueue_result, portnum,
7625 		RTE_UINT16);
7626 static cmdline_parse_token_num_t cmd_showqueue_queuenum =
7627 	TOKEN_NUM_INITIALIZER(struct cmd_showqueue_result, queuenum,
7628 		RTE_UINT16);
7629 
7630 static cmdline_parse_inst_t cmd_showqueue = {
7631 	.f = cmd_showqueue_parsed,
7632 	.data = NULL,
7633 	.help_str = "show rxq|txq info <port_id> <queue_id>",
7634 	.tokens = {
7635 		(void *)&cmd_showqueue_show,
7636 		(void *)&cmd_showqueue_type,
7637 		(void *)&cmd_showqueue_what,
7638 		(void *)&cmd_showqueue_portnum,
7639 		(void *)&cmd_showqueue_queuenum,
7640 		NULL,
7641 	},
7642 };
7643 
7644 /* show/clear fwd engine statistics */
7645 struct fwd_result {
7646 	cmdline_fixed_string_t action;
7647 	cmdline_fixed_string_t fwd;
7648 	cmdline_fixed_string_t stats;
7649 	cmdline_fixed_string_t all;
7650 };
7651 
7652 static cmdline_parse_token_string_t cmd_fwd_action =
7653 	TOKEN_STRING_INITIALIZER(struct fwd_result, action, "show#clear");
7654 static cmdline_parse_token_string_t cmd_fwd_fwd =
7655 	TOKEN_STRING_INITIALIZER(struct fwd_result, fwd, "fwd");
7656 static cmdline_parse_token_string_t cmd_fwd_stats =
7657 	TOKEN_STRING_INITIALIZER(struct fwd_result, stats, "stats");
7658 static cmdline_parse_token_string_t cmd_fwd_all =
7659 	TOKEN_STRING_INITIALIZER(struct fwd_result, all, "all");
7660 
7661 static void
7662 cmd_showfwdall_parsed(void *parsed_result,
7663 		      __rte_unused struct cmdline *cl,
7664 		      __rte_unused void *data)
7665 {
7666 	struct fwd_result *res = parsed_result;
7667 
7668 	if (!strcmp(res->action, "show"))
7669 		fwd_stats_display();
7670 	else
7671 		fwd_stats_reset();
7672 }
7673 
7674 static cmdline_parse_inst_t cmd_showfwdall = {
7675 	.f = cmd_showfwdall_parsed,
7676 	.data = NULL,
7677 	.help_str = "show|clear fwd stats all",
7678 	.tokens = {
7679 		(void *)&cmd_fwd_action,
7680 		(void *)&cmd_fwd_fwd,
7681 		(void *)&cmd_fwd_stats,
7682 		(void *)&cmd_fwd_all,
7683 		NULL,
7684 	},
7685 };
7686 
7687 /* *** READ A RING DESCRIPTOR OF A PORT RX/TX QUEUE *** */
7688 struct cmd_read_rxd_txd_result {
7689 	cmdline_fixed_string_t read;
7690 	cmdline_fixed_string_t rxd_txd;
7691 	portid_t port_id;
7692 	uint16_t queue_id;
7693 	uint16_t desc_id;
7694 };
7695 
7696 static void
7697 cmd_read_rxd_txd_parsed(void *parsed_result,
7698 			__rte_unused struct cmdline *cl,
7699 			__rte_unused void *data)
7700 {
7701 	struct cmd_read_rxd_txd_result *res = parsed_result;
7702 
7703 	if (!strcmp(res->rxd_txd, "rxd"))
7704 		rx_ring_desc_display(res->port_id, res->queue_id, res->desc_id);
7705 	else if (!strcmp(res->rxd_txd, "txd"))
7706 		tx_ring_desc_display(res->port_id, res->queue_id, res->desc_id);
7707 }
7708 
7709 static cmdline_parse_token_string_t cmd_read_rxd_txd_read =
7710 	TOKEN_STRING_INITIALIZER(struct cmd_read_rxd_txd_result, read, "read");
7711 static cmdline_parse_token_string_t cmd_read_rxd_txd_rxd_txd =
7712 	TOKEN_STRING_INITIALIZER(struct cmd_read_rxd_txd_result, rxd_txd,
7713 				 "rxd#txd");
7714 static cmdline_parse_token_num_t cmd_read_rxd_txd_port_id =
7715 	TOKEN_NUM_INITIALIZER(struct cmd_read_rxd_txd_result, port_id,
7716 				 RTE_UINT16);
7717 static cmdline_parse_token_num_t cmd_read_rxd_txd_queue_id =
7718 	TOKEN_NUM_INITIALIZER(struct cmd_read_rxd_txd_result, queue_id,
7719 				 RTE_UINT16);
7720 static cmdline_parse_token_num_t cmd_read_rxd_txd_desc_id =
7721 	TOKEN_NUM_INITIALIZER(struct cmd_read_rxd_txd_result, desc_id,
7722 				 RTE_UINT16);
7723 
7724 static cmdline_parse_inst_t cmd_read_rxd_txd = {
7725 	.f = cmd_read_rxd_txd_parsed,
7726 	.data = NULL,
7727 	.help_str = "read rxd|txd <port_id> <queue_id> <desc_id>",
7728 	.tokens = {
7729 		(void *)&cmd_read_rxd_txd_read,
7730 		(void *)&cmd_read_rxd_txd_rxd_txd,
7731 		(void *)&cmd_read_rxd_txd_port_id,
7732 		(void *)&cmd_read_rxd_txd_queue_id,
7733 		(void *)&cmd_read_rxd_txd_desc_id,
7734 		NULL,
7735 	},
7736 };
7737 
7738 /* *** QUIT *** */
7739 struct cmd_quit_result {
7740 	cmdline_fixed_string_t quit;
7741 };
7742 
7743 static void cmd_quit_parsed(__rte_unused void *parsed_result,
7744 			    struct cmdline *cl,
7745 			    __rte_unused void *data)
7746 {
7747 	cmdline_quit(cl);
7748 	cl_quit = 1;
7749 }
7750 
7751 static cmdline_parse_token_string_t cmd_quit_quit =
7752 	TOKEN_STRING_INITIALIZER(struct cmd_quit_result, quit, "quit");
7753 
7754 static cmdline_parse_inst_t cmd_quit = {
7755 	.f = cmd_quit_parsed,
7756 	.data = NULL,
7757 	.help_str = "quit: Exit application",
7758 	.tokens = {
7759 		(void *)&cmd_quit_quit,
7760 		NULL,
7761 	},
7762 };
7763 
7764 /* *** ADD/REMOVE MAC ADDRESS FROM A PORT *** */
7765 struct cmd_mac_addr_result {
7766 	cmdline_fixed_string_t mac_addr_cmd;
7767 	cmdline_fixed_string_t what;
7768 	uint16_t port_num;
7769 	struct rte_ether_addr address;
7770 };
7771 
7772 static void cmd_mac_addr_parsed(void *parsed_result,
7773 		__rte_unused struct cmdline *cl,
7774 		__rte_unused void *data)
7775 {
7776 	struct cmd_mac_addr_result *res = parsed_result;
7777 	int ret;
7778 
7779 	if (strcmp(res->what, "add") == 0)
7780 		ret = rte_eth_dev_mac_addr_add(res->port_num, &res->address, 0);
7781 	else if (strcmp(res->what, "set") == 0)
7782 		ret = rte_eth_dev_default_mac_addr_set(res->port_num,
7783 						       &res->address);
7784 	else
7785 		ret = rte_eth_dev_mac_addr_remove(res->port_num, &res->address);
7786 
7787 	/* check the return value and print it if is < 0 */
7788 	if(ret < 0)
7789 		fprintf(stderr, "mac_addr_cmd error: (%s)\n", strerror(-ret));
7790 
7791 }
7792 
7793 static cmdline_parse_token_string_t cmd_mac_addr_cmd =
7794 	TOKEN_STRING_INITIALIZER(struct cmd_mac_addr_result, mac_addr_cmd,
7795 				"mac_addr");
7796 static cmdline_parse_token_string_t cmd_mac_addr_what =
7797 	TOKEN_STRING_INITIALIZER(struct cmd_mac_addr_result, what,
7798 				"add#remove#set");
7799 static cmdline_parse_token_num_t cmd_mac_addr_portnum =
7800 		TOKEN_NUM_INITIALIZER(struct cmd_mac_addr_result, port_num,
7801 					RTE_UINT16);
7802 static cmdline_parse_token_etheraddr_t cmd_mac_addr_addr =
7803 		TOKEN_ETHERADDR_INITIALIZER(struct cmd_mac_addr_result, address);
7804 
7805 static cmdline_parse_inst_t cmd_mac_addr = {
7806 	.f = cmd_mac_addr_parsed,
7807 	.data = (void *)0,
7808 	.help_str = "mac_addr add|remove|set <port_id> <mac_addr>: "
7809 			"Add/Remove/Set MAC address on port_id",
7810 	.tokens = {
7811 		(void *)&cmd_mac_addr_cmd,
7812 		(void *)&cmd_mac_addr_what,
7813 		(void *)&cmd_mac_addr_portnum,
7814 		(void *)&cmd_mac_addr_addr,
7815 		NULL,
7816 	},
7817 };
7818 
7819 /* *** SET THE PEER ADDRESS FOR CERTAIN PORT *** */
7820 struct cmd_eth_peer_result {
7821 	cmdline_fixed_string_t set;
7822 	cmdline_fixed_string_t eth_peer;
7823 	portid_t port_id;
7824 	cmdline_fixed_string_t peer_addr;
7825 };
7826 
7827 static void cmd_set_eth_peer_parsed(void *parsed_result,
7828 			__rte_unused struct cmdline *cl,
7829 			__rte_unused void *data)
7830 {
7831 		struct cmd_eth_peer_result *res = parsed_result;
7832 
7833 		if (test_done == 0) {
7834 			fprintf(stderr, "Please stop forwarding first\n");
7835 			return;
7836 		}
7837 		if (!strcmp(res->eth_peer, "eth-peer")) {
7838 			set_fwd_eth_peer(res->port_id, res->peer_addr);
7839 			fwd_config_setup();
7840 		}
7841 }
7842 static cmdline_parse_token_string_t cmd_eth_peer_set =
7843 	TOKEN_STRING_INITIALIZER(struct cmd_eth_peer_result, set, "set");
7844 static cmdline_parse_token_string_t cmd_eth_peer =
7845 	TOKEN_STRING_INITIALIZER(struct cmd_eth_peer_result, eth_peer, "eth-peer");
7846 static cmdline_parse_token_num_t cmd_eth_peer_port_id =
7847 	TOKEN_NUM_INITIALIZER(struct cmd_eth_peer_result, port_id,
7848 		RTE_UINT16);
7849 static cmdline_parse_token_string_t cmd_eth_peer_addr =
7850 	TOKEN_STRING_INITIALIZER(struct cmd_eth_peer_result, peer_addr, NULL);
7851 
7852 static cmdline_parse_inst_t cmd_set_fwd_eth_peer = {
7853 	.f = cmd_set_eth_peer_parsed,
7854 	.data = NULL,
7855 	.help_str = "set eth-peer <port_id> <peer_mac>",
7856 	.tokens = {
7857 		(void *)&cmd_eth_peer_set,
7858 		(void *)&cmd_eth_peer,
7859 		(void *)&cmd_eth_peer_port_id,
7860 		(void *)&cmd_eth_peer_addr,
7861 		NULL,
7862 	},
7863 };
7864 
7865 /* *** CONFIGURE QUEUE STATS COUNTER MAPPINGS *** */
7866 struct cmd_set_qmap_result {
7867 	cmdline_fixed_string_t set;
7868 	cmdline_fixed_string_t qmap;
7869 	cmdline_fixed_string_t what;
7870 	portid_t port_id;
7871 	uint16_t queue_id;
7872 	uint8_t map_value;
7873 };
7874 
7875 static void
7876 cmd_set_qmap_parsed(void *parsed_result,
7877 		       __rte_unused struct cmdline *cl,
7878 		       __rte_unused void *data)
7879 {
7880 	struct cmd_set_qmap_result *res = parsed_result;
7881 	int is_rx = (strcmp(res->what, "tx") == 0) ? 0 : 1;
7882 
7883 	set_qmap(res->port_id, (uint8_t)is_rx, res->queue_id, res->map_value);
7884 }
7885 
7886 static cmdline_parse_token_string_t cmd_setqmap_set =
7887 	TOKEN_STRING_INITIALIZER(struct cmd_set_qmap_result,
7888 				 set, "set");
7889 static cmdline_parse_token_string_t cmd_setqmap_qmap =
7890 	TOKEN_STRING_INITIALIZER(struct cmd_set_qmap_result,
7891 				 qmap, "stat_qmap");
7892 static cmdline_parse_token_string_t cmd_setqmap_what =
7893 	TOKEN_STRING_INITIALIZER(struct cmd_set_qmap_result,
7894 				 what, "tx#rx");
7895 static cmdline_parse_token_num_t cmd_setqmap_portid =
7896 	TOKEN_NUM_INITIALIZER(struct cmd_set_qmap_result,
7897 			      port_id, RTE_UINT16);
7898 static cmdline_parse_token_num_t cmd_setqmap_queueid =
7899 	TOKEN_NUM_INITIALIZER(struct cmd_set_qmap_result,
7900 			      queue_id, RTE_UINT16);
7901 static cmdline_parse_token_num_t cmd_setqmap_mapvalue =
7902 	TOKEN_NUM_INITIALIZER(struct cmd_set_qmap_result,
7903 			      map_value, RTE_UINT8);
7904 
7905 static cmdline_parse_inst_t cmd_set_qmap = {
7906 	.f = cmd_set_qmap_parsed,
7907 	.data = NULL,
7908 	.help_str = "set stat_qmap rx|tx <port_id> <queue_id> <map_value>: "
7909 		"Set statistics mapping value on tx|rx queue_id of port_id",
7910 	.tokens = {
7911 		(void *)&cmd_setqmap_set,
7912 		(void *)&cmd_setqmap_qmap,
7913 		(void *)&cmd_setqmap_what,
7914 		(void *)&cmd_setqmap_portid,
7915 		(void *)&cmd_setqmap_queueid,
7916 		(void *)&cmd_setqmap_mapvalue,
7917 		NULL,
7918 	},
7919 };
7920 
7921 /* *** SET OPTION TO HIDE ZERO VALUES FOR XSTATS  DISPLAY *** */
7922 struct cmd_set_xstats_hide_zero_result {
7923 	cmdline_fixed_string_t keyword;
7924 	cmdline_fixed_string_t name;
7925 	cmdline_fixed_string_t on_off;
7926 };
7927 
7928 static void
7929 cmd_set_xstats_hide_zero_parsed(void *parsed_result,
7930 			__rte_unused struct cmdline *cl,
7931 			__rte_unused void *data)
7932 {
7933 	struct cmd_set_xstats_hide_zero_result *res;
7934 	uint16_t on_off = 0;
7935 
7936 	res = parsed_result;
7937 	on_off = !strcmp(res->on_off, "on") ? 1 : 0;
7938 	set_xstats_hide_zero(on_off);
7939 }
7940 
7941 static cmdline_parse_token_string_t cmd_set_xstats_hide_zero_keyword =
7942 	TOKEN_STRING_INITIALIZER(struct cmd_set_xstats_hide_zero_result,
7943 				 keyword, "set");
7944 static cmdline_parse_token_string_t cmd_set_xstats_hide_zero_name =
7945 	TOKEN_STRING_INITIALIZER(struct cmd_set_xstats_hide_zero_result,
7946 				 name, "xstats-hide-zero");
7947 static cmdline_parse_token_string_t cmd_set_xstats_hide_zero_on_off =
7948 	TOKEN_STRING_INITIALIZER(struct cmd_set_xstats_hide_zero_result,
7949 				 on_off, "on#off");
7950 
7951 static cmdline_parse_inst_t cmd_set_xstats_hide_zero = {
7952 	.f = cmd_set_xstats_hide_zero_parsed,
7953 	.data = NULL,
7954 	.help_str = "set xstats-hide-zero on|off",
7955 	.tokens = {
7956 		(void *)&cmd_set_xstats_hide_zero_keyword,
7957 		(void *)&cmd_set_xstats_hide_zero_name,
7958 		(void *)&cmd_set_xstats_hide_zero_on_off,
7959 		NULL,
7960 	},
7961 };
7962 
7963 /* *** SET OPTION TO ENABLE MEASUREMENT OF CPU CYCLES *** */
7964 struct cmd_set_record_core_cycles_result {
7965 	cmdline_fixed_string_t keyword;
7966 	cmdline_fixed_string_t name;
7967 	cmdline_fixed_string_t on_off;
7968 };
7969 
7970 static void
7971 cmd_set_record_core_cycles_parsed(void *parsed_result,
7972 			__rte_unused struct cmdline *cl,
7973 			__rte_unused void *data)
7974 {
7975 	struct cmd_set_record_core_cycles_result *res;
7976 	uint16_t on_off = 0;
7977 
7978 	res = parsed_result;
7979 	on_off = !strcmp(res->on_off, "on") ? 1 : 0;
7980 	set_record_core_cycles(on_off);
7981 }
7982 
7983 static cmdline_parse_token_string_t cmd_set_record_core_cycles_keyword =
7984 	TOKEN_STRING_INITIALIZER(struct cmd_set_record_core_cycles_result,
7985 				 keyword, "set");
7986 static cmdline_parse_token_string_t cmd_set_record_core_cycles_name =
7987 	TOKEN_STRING_INITIALIZER(struct cmd_set_record_core_cycles_result,
7988 				 name, "record-core-cycles");
7989 static cmdline_parse_token_string_t cmd_set_record_core_cycles_on_off =
7990 	TOKEN_STRING_INITIALIZER(struct cmd_set_record_core_cycles_result,
7991 				 on_off, "on#off");
7992 
7993 static cmdline_parse_inst_t cmd_set_record_core_cycles = {
7994 	.f = cmd_set_record_core_cycles_parsed,
7995 	.data = NULL,
7996 	.help_str = "set record-core-cycles on|off",
7997 	.tokens = {
7998 		(void *)&cmd_set_record_core_cycles_keyword,
7999 		(void *)&cmd_set_record_core_cycles_name,
8000 		(void *)&cmd_set_record_core_cycles_on_off,
8001 		NULL,
8002 	},
8003 };
8004 
8005 /* *** SET OPTION TO ENABLE DISPLAY OF RX AND TX BURSTS *** */
8006 struct cmd_set_record_burst_stats_result {
8007 	cmdline_fixed_string_t keyword;
8008 	cmdline_fixed_string_t name;
8009 	cmdline_fixed_string_t on_off;
8010 };
8011 
8012 static void
8013 cmd_set_record_burst_stats_parsed(void *parsed_result,
8014 			__rte_unused struct cmdline *cl,
8015 			__rte_unused void *data)
8016 {
8017 	struct cmd_set_record_burst_stats_result *res;
8018 	uint16_t on_off = 0;
8019 
8020 	res = parsed_result;
8021 	on_off = !strcmp(res->on_off, "on") ? 1 : 0;
8022 	set_record_burst_stats(on_off);
8023 }
8024 
8025 static cmdline_parse_token_string_t cmd_set_record_burst_stats_keyword =
8026 	TOKEN_STRING_INITIALIZER(struct cmd_set_record_burst_stats_result,
8027 				 keyword, "set");
8028 static cmdline_parse_token_string_t cmd_set_record_burst_stats_name =
8029 	TOKEN_STRING_INITIALIZER(struct cmd_set_record_burst_stats_result,
8030 				 name, "record-burst-stats");
8031 static cmdline_parse_token_string_t cmd_set_record_burst_stats_on_off =
8032 	TOKEN_STRING_INITIALIZER(struct cmd_set_record_burst_stats_result,
8033 				 on_off, "on#off");
8034 
8035 static cmdline_parse_inst_t cmd_set_record_burst_stats = {
8036 	.f = cmd_set_record_burst_stats_parsed,
8037 	.data = NULL,
8038 	.help_str = "set record-burst-stats on|off",
8039 	.tokens = {
8040 		(void *)&cmd_set_record_burst_stats_keyword,
8041 		(void *)&cmd_set_record_burst_stats_name,
8042 		(void *)&cmd_set_record_burst_stats_on_off,
8043 		NULL,
8044 	},
8045 };
8046 
8047 /* *** CONFIGURE UNICAST HASH TABLE *** */
8048 struct cmd_set_uc_hash_table {
8049 	cmdline_fixed_string_t set;
8050 	cmdline_fixed_string_t port;
8051 	portid_t port_id;
8052 	cmdline_fixed_string_t what;
8053 	struct rte_ether_addr address;
8054 	cmdline_fixed_string_t mode;
8055 };
8056 
8057 static void
8058 cmd_set_uc_hash_parsed(void *parsed_result,
8059 		       __rte_unused struct cmdline *cl,
8060 		       __rte_unused void *data)
8061 {
8062 	int ret=0;
8063 	struct cmd_set_uc_hash_table *res = parsed_result;
8064 
8065 	int is_on = (strcmp(res->mode, "on") == 0) ? 1 : 0;
8066 
8067 	if (strcmp(res->what, "uta") == 0)
8068 		ret = rte_eth_dev_uc_hash_table_set(res->port_id,
8069 						&res->address,(uint8_t)is_on);
8070 	if (ret < 0)
8071 		fprintf(stderr,
8072 			"bad unicast hash table parameter, return code = %d\n",
8073 			ret);
8074 
8075 }
8076 
8077 static cmdline_parse_token_string_t cmd_set_uc_hash_set =
8078 	TOKEN_STRING_INITIALIZER(struct cmd_set_uc_hash_table,
8079 				 set, "set");
8080 static cmdline_parse_token_string_t cmd_set_uc_hash_port =
8081 	TOKEN_STRING_INITIALIZER(struct cmd_set_uc_hash_table,
8082 				 port, "port");
8083 static cmdline_parse_token_num_t cmd_set_uc_hash_portid =
8084 	TOKEN_NUM_INITIALIZER(struct cmd_set_uc_hash_table,
8085 			      port_id, RTE_UINT16);
8086 static cmdline_parse_token_string_t cmd_set_uc_hash_what =
8087 	TOKEN_STRING_INITIALIZER(struct cmd_set_uc_hash_table,
8088 				 what, "uta");
8089 static cmdline_parse_token_etheraddr_t cmd_set_uc_hash_mac =
8090 	TOKEN_ETHERADDR_INITIALIZER(struct cmd_set_uc_hash_table,
8091 				address);
8092 static cmdline_parse_token_string_t cmd_set_uc_hash_mode =
8093 	TOKEN_STRING_INITIALIZER(struct cmd_set_uc_hash_table,
8094 				 mode, "on#off");
8095 
8096 static cmdline_parse_inst_t cmd_set_uc_hash_filter = {
8097 	.f = cmd_set_uc_hash_parsed,
8098 	.data = NULL,
8099 	.help_str = "set port <port_id> uta <mac_addr> on|off)",
8100 	.tokens = {
8101 		(void *)&cmd_set_uc_hash_set,
8102 		(void *)&cmd_set_uc_hash_port,
8103 		(void *)&cmd_set_uc_hash_portid,
8104 		(void *)&cmd_set_uc_hash_what,
8105 		(void *)&cmd_set_uc_hash_mac,
8106 		(void *)&cmd_set_uc_hash_mode,
8107 		NULL,
8108 	},
8109 };
8110 
8111 struct cmd_set_uc_all_hash_table {
8112 	cmdline_fixed_string_t set;
8113 	cmdline_fixed_string_t port;
8114 	portid_t port_id;
8115 	cmdline_fixed_string_t what;
8116 	cmdline_fixed_string_t value;
8117 	cmdline_fixed_string_t mode;
8118 };
8119 
8120 static void
8121 cmd_set_uc_all_hash_parsed(void *parsed_result,
8122 		       __rte_unused struct cmdline *cl,
8123 		       __rte_unused void *data)
8124 {
8125 	int ret=0;
8126 	struct cmd_set_uc_all_hash_table *res = parsed_result;
8127 
8128 	int is_on = (strcmp(res->mode, "on") == 0) ? 1 : 0;
8129 
8130 	if ((strcmp(res->what, "uta") == 0) &&
8131 		(strcmp(res->value, "all") == 0))
8132 		ret = rte_eth_dev_uc_all_hash_table_set(res->port_id,(uint8_t) is_on);
8133 	if (ret < 0)
8134 		fprintf(stderr,
8135 			"bad unicast hash table parameter, return code = %d\n",
8136 			ret);
8137 }
8138 
8139 static cmdline_parse_token_string_t cmd_set_uc_all_hash_set =
8140 	TOKEN_STRING_INITIALIZER(struct cmd_set_uc_all_hash_table,
8141 				 set, "set");
8142 static cmdline_parse_token_string_t cmd_set_uc_all_hash_port =
8143 	TOKEN_STRING_INITIALIZER(struct cmd_set_uc_all_hash_table,
8144 				 port, "port");
8145 static cmdline_parse_token_num_t cmd_set_uc_all_hash_portid =
8146 	TOKEN_NUM_INITIALIZER(struct cmd_set_uc_all_hash_table,
8147 			      port_id, RTE_UINT16);
8148 static cmdline_parse_token_string_t cmd_set_uc_all_hash_what =
8149 	TOKEN_STRING_INITIALIZER(struct cmd_set_uc_all_hash_table,
8150 				 what, "uta");
8151 static cmdline_parse_token_string_t cmd_set_uc_all_hash_value =
8152 	TOKEN_STRING_INITIALIZER(struct cmd_set_uc_all_hash_table,
8153 				value,"all");
8154 static cmdline_parse_token_string_t cmd_set_uc_all_hash_mode =
8155 	TOKEN_STRING_INITIALIZER(struct cmd_set_uc_all_hash_table,
8156 				 mode, "on#off");
8157 
8158 static cmdline_parse_inst_t cmd_set_uc_all_hash_filter = {
8159 	.f = cmd_set_uc_all_hash_parsed,
8160 	.data = NULL,
8161 	.help_str = "set port <port_id> uta all on|off",
8162 	.tokens = {
8163 		(void *)&cmd_set_uc_all_hash_set,
8164 		(void *)&cmd_set_uc_all_hash_port,
8165 		(void *)&cmd_set_uc_all_hash_portid,
8166 		(void *)&cmd_set_uc_all_hash_what,
8167 		(void *)&cmd_set_uc_all_hash_value,
8168 		(void *)&cmd_set_uc_all_hash_mode,
8169 		NULL,
8170 	},
8171 };
8172 
8173 /* *** CONFIGURE VF TRAFFIC CONTROL *** */
8174 struct cmd_set_vf_traffic {
8175 	cmdline_fixed_string_t set;
8176 	cmdline_fixed_string_t port;
8177 	portid_t port_id;
8178 	cmdline_fixed_string_t vf;
8179 	uint8_t vf_id;
8180 	cmdline_fixed_string_t what;
8181 	cmdline_fixed_string_t mode;
8182 };
8183 
8184 static void
8185 cmd_set_vf_traffic_parsed(void *parsed_result,
8186 		       __rte_unused struct cmdline *cl,
8187 		       __rte_unused void *data)
8188 {
8189 	struct cmd_set_vf_traffic *res = parsed_result;
8190 	int is_rx = (strcmp(res->what, "rx") == 0) ? 1 : 0;
8191 	int is_on = (strcmp(res->mode, "on") == 0) ? 1 : 0;
8192 
8193 	set_vf_traffic(res->port_id, (uint8_t)is_rx, res->vf_id,(uint8_t) is_on);
8194 }
8195 
8196 static cmdline_parse_token_string_t cmd_setvf_traffic_set =
8197 	TOKEN_STRING_INITIALIZER(struct cmd_set_vf_traffic,
8198 				 set, "set");
8199 static cmdline_parse_token_string_t cmd_setvf_traffic_port =
8200 	TOKEN_STRING_INITIALIZER(struct cmd_set_vf_traffic,
8201 				 port, "port");
8202 static cmdline_parse_token_num_t cmd_setvf_traffic_portid =
8203 	TOKEN_NUM_INITIALIZER(struct cmd_set_vf_traffic,
8204 			      port_id, RTE_UINT16);
8205 static cmdline_parse_token_string_t cmd_setvf_traffic_vf =
8206 	TOKEN_STRING_INITIALIZER(struct cmd_set_vf_traffic,
8207 				 vf, "vf");
8208 static cmdline_parse_token_num_t cmd_setvf_traffic_vfid =
8209 	TOKEN_NUM_INITIALIZER(struct cmd_set_vf_traffic,
8210 			      vf_id, RTE_UINT8);
8211 static cmdline_parse_token_string_t cmd_setvf_traffic_what =
8212 	TOKEN_STRING_INITIALIZER(struct cmd_set_vf_traffic,
8213 				 what, "tx#rx");
8214 static cmdline_parse_token_string_t cmd_setvf_traffic_mode =
8215 	TOKEN_STRING_INITIALIZER(struct cmd_set_vf_traffic,
8216 				 mode, "on#off");
8217 
8218 static cmdline_parse_inst_t cmd_set_vf_traffic = {
8219 	.f = cmd_set_vf_traffic_parsed,
8220 	.data = NULL,
8221 	.help_str = "set port <port_id> vf <vf_id> rx|tx on|off",
8222 	.tokens = {
8223 		(void *)&cmd_setvf_traffic_set,
8224 		(void *)&cmd_setvf_traffic_port,
8225 		(void *)&cmd_setvf_traffic_portid,
8226 		(void *)&cmd_setvf_traffic_vf,
8227 		(void *)&cmd_setvf_traffic_vfid,
8228 		(void *)&cmd_setvf_traffic_what,
8229 		(void *)&cmd_setvf_traffic_mode,
8230 		NULL,
8231 	},
8232 };
8233 
8234 /* *** CONFIGURE VF RECEIVE MODE *** */
8235 struct cmd_set_vf_rxmode {
8236 	cmdline_fixed_string_t set;
8237 	cmdline_fixed_string_t port;
8238 	portid_t port_id;
8239 	cmdline_fixed_string_t vf;
8240 	uint8_t vf_id;
8241 	cmdline_fixed_string_t what;
8242 	cmdline_fixed_string_t mode;
8243 	cmdline_fixed_string_t on;
8244 };
8245 
8246 static void
8247 cmd_set_vf_rxmode_parsed(void *parsed_result,
8248 		       __rte_unused struct cmdline *cl,
8249 		       __rte_unused void *data)
8250 {
8251 	int ret = -ENOTSUP;
8252 	uint16_t vf_rxmode = 0;
8253 	struct cmd_set_vf_rxmode *res = parsed_result;
8254 
8255 	int is_on = (strcmp(res->on, "on") == 0) ? 1 : 0;
8256 	if (!strcmp(res->what,"rxmode")) {
8257 		if (!strcmp(res->mode, "AUPE"))
8258 			vf_rxmode |= RTE_ETH_VMDQ_ACCEPT_UNTAG;
8259 		else if (!strcmp(res->mode, "ROPE"))
8260 			vf_rxmode |= RTE_ETH_VMDQ_ACCEPT_HASH_UC;
8261 		else if (!strcmp(res->mode, "BAM"))
8262 			vf_rxmode |= RTE_ETH_VMDQ_ACCEPT_BROADCAST;
8263 		else if (!strncmp(res->mode, "MPE",3))
8264 			vf_rxmode |= RTE_ETH_VMDQ_ACCEPT_MULTICAST;
8265 	}
8266 
8267 	RTE_SET_USED(is_on);
8268 	RTE_SET_USED(vf_rxmode);
8269 
8270 #ifdef RTE_NET_IXGBE
8271 	if (ret == -ENOTSUP)
8272 		ret = rte_pmd_ixgbe_set_vf_rxmode(res->port_id, res->vf_id,
8273 						  vf_rxmode, (uint8_t)is_on);
8274 #endif
8275 #ifdef RTE_NET_BNXT
8276 	if (ret == -ENOTSUP)
8277 		ret = rte_pmd_bnxt_set_vf_rxmode(res->port_id, res->vf_id,
8278 						 vf_rxmode, (uint8_t)is_on);
8279 #endif
8280 	if (ret < 0)
8281 		fprintf(stderr,
8282 			"bad VF receive mode parameter, return code = %d\n",
8283 			ret);
8284 }
8285 
8286 static cmdline_parse_token_string_t cmd_set_vf_rxmode_set =
8287 	TOKEN_STRING_INITIALIZER(struct cmd_set_vf_rxmode,
8288 				 set, "set");
8289 static cmdline_parse_token_string_t cmd_set_vf_rxmode_port =
8290 	TOKEN_STRING_INITIALIZER(struct cmd_set_vf_rxmode,
8291 				 port, "port");
8292 static cmdline_parse_token_num_t cmd_set_vf_rxmode_portid =
8293 	TOKEN_NUM_INITIALIZER(struct cmd_set_vf_rxmode,
8294 			      port_id, RTE_UINT16);
8295 static cmdline_parse_token_string_t cmd_set_vf_rxmode_vf =
8296 	TOKEN_STRING_INITIALIZER(struct cmd_set_vf_rxmode,
8297 				 vf, "vf");
8298 static cmdline_parse_token_num_t cmd_set_vf_rxmode_vfid =
8299 	TOKEN_NUM_INITIALIZER(struct cmd_set_vf_rxmode,
8300 			      vf_id, RTE_UINT8);
8301 static cmdline_parse_token_string_t cmd_set_vf_rxmode_what =
8302 	TOKEN_STRING_INITIALIZER(struct cmd_set_vf_rxmode,
8303 				 what, "rxmode");
8304 static cmdline_parse_token_string_t cmd_set_vf_rxmode_mode =
8305 	TOKEN_STRING_INITIALIZER(struct cmd_set_vf_rxmode,
8306 				 mode, "AUPE#ROPE#BAM#MPE");
8307 static cmdline_parse_token_string_t cmd_set_vf_rxmode_on =
8308 	TOKEN_STRING_INITIALIZER(struct cmd_set_vf_rxmode,
8309 				 on, "on#off");
8310 
8311 static cmdline_parse_inst_t cmd_set_vf_rxmode = {
8312 	.f = cmd_set_vf_rxmode_parsed,
8313 	.data = NULL,
8314 	.help_str = "set port <port_id> vf <vf_id> rxmode "
8315 		"AUPE|ROPE|BAM|MPE on|off",
8316 	.tokens = {
8317 		(void *)&cmd_set_vf_rxmode_set,
8318 		(void *)&cmd_set_vf_rxmode_port,
8319 		(void *)&cmd_set_vf_rxmode_portid,
8320 		(void *)&cmd_set_vf_rxmode_vf,
8321 		(void *)&cmd_set_vf_rxmode_vfid,
8322 		(void *)&cmd_set_vf_rxmode_what,
8323 		(void *)&cmd_set_vf_rxmode_mode,
8324 		(void *)&cmd_set_vf_rxmode_on,
8325 		NULL,
8326 	},
8327 };
8328 
8329 /* *** ADD MAC ADDRESS FILTER FOR A VF OF A PORT *** */
8330 struct cmd_vf_mac_addr_result {
8331 	cmdline_fixed_string_t mac_addr_cmd;
8332 	cmdline_fixed_string_t what;
8333 	cmdline_fixed_string_t port;
8334 	uint16_t port_num;
8335 	cmdline_fixed_string_t vf;
8336 	uint8_t vf_num;
8337 	struct rte_ether_addr address;
8338 };
8339 
8340 static void cmd_vf_mac_addr_parsed(void *parsed_result,
8341 		__rte_unused struct cmdline *cl,
8342 		__rte_unused void *data)
8343 {
8344 	struct cmd_vf_mac_addr_result *res = parsed_result;
8345 	int ret = -ENOTSUP;
8346 
8347 	if (strcmp(res->what, "add") != 0)
8348 		return;
8349 
8350 #ifdef RTE_NET_I40E
8351 	if (ret == -ENOTSUP)
8352 		ret = rte_pmd_i40e_add_vf_mac_addr(res->port_num, res->vf_num,
8353 						   &res->address);
8354 #endif
8355 #ifdef RTE_NET_BNXT
8356 	if (ret == -ENOTSUP)
8357 		ret = rte_pmd_bnxt_mac_addr_add(res->port_num, &res->address,
8358 						res->vf_num);
8359 #endif
8360 
8361 	if(ret < 0)
8362 		fprintf(stderr, "vf_mac_addr_cmd error: (%s)\n", strerror(-ret));
8363 
8364 }
8365 
8366 static cmdline_parse_token_string_t cmd_vf_mac_addr_cmd =
8367 	TOKEN_STRING_INITIALIZER(struct cmd_vf_mac_addr_result,
8368 				mac_addr_cmd,"mac_addr");
8369 static cmdline_parse_token_string_t cmd_vf_mac_addr_what =
8370 	TOKEN_STRING_INITIALIZER(struct cmd_vf_mac_addr_result,
8371 				what,"add");
8372 static cmdline_parse_token_string_t cmd_vf_mac_addr_port =
8373 	TOKEN_STRING_INITIALIZER(struct cmd_vf_mac_addr_result,
8374 				port,"port");
8375 static cmdline_parse_token_num_t cmd_vf_mac_addr_portnum =
8376 	TOKEN_NUM_INITIALIZER(struct cmd_vf_mac_addr_result,
8377 				port_num, RTE_UINT16);
8378 static cmdline_parse_token_string_t cmd_vf_mac_addr_vf =
8379 	TOKEN_STRING_INITIALIZER(struct cmd_vf_mac_addr_result,
8380 				vf,"vf");
8381 static cmdline_parse_token_num_t cmd_vf_mac_addr_vfnum =
8382 	TOKEN_NUM_INITIALIZER(struct cmd_vf_mac_addr_result,
8383 				vf_num, RTE_UINT8);
8384 static cmdline_parse_token_etheraddr_t cmd_vf_mac_addr_addr =
8385 	TOKEN_ETHERADDR_INITIALIZER(struct cmd_vf_mac_addr_result,
8386 				address);
8387 
8388 static cmdline_parse_inst_t cmd_vf_mac_addr_filter = {
8389 	.f = cmd_vf_mac_addr_parsed,
8390 	.data = (void *)0,
8391 	.help_str = "mac_addr add port <port_id> vf <vf_id> <mac_addr>: "
8392 		"Add MAC address filtering for a VF on port_id",
8393 	.tokens = {
8394 		(void *)&cmd_vf_mac_addr_cmd,
8395 		(void *)&cmd_vf_mac_addr_what,
8396 		(void *)&cmd_vf_mac_addr_port,
8397 		(void *)&cmd_vf_mac_addr_portnum,
8398 		(void *)&cmd_vf_mac_addr_vf,
8399 		(void *)&cmd_vf_mac_addr_vfnum,
8400 		(void *)&cmd_vf_mac_addr_addr,
8401 		NULL,
8402 	},
8403 };
8404 
8405 /* *** ADD/REMOVE A VLAN IDENTIFIER TO/FROM A PORT VLAN RX FILTER *** */
8406 struct cmd_vf_rx_vlan_filter {
8407 	cmdline_fixed_string_t rx_vlan;
8408 	cmdline_fixed_string_t what;
8409 	uint16_t vlan_id;
8410 	cmdline_fixed_string_t port;
8411 	portid_t port_id;
8412 	cmdline_fixed_string_t vf;
8413 	uint64_t vf_mask;
8414 };
8415 
8416 static void
8417 cmd_vf_rx_vlan_filter_parsed(void *parsed_result,
8418 			  __rte_unused struct cmdline *cl,
8419 			  __rte_unused void *data)
8420 {
8421 	struct cmd_vf_rx_vlan_filter *res = parsed_result;
8422 	int ret = -ENOTSUP;
8423 
8424 	__rte_unused int is_add = (strcmp(res->what, "add") == 0) ? 1 : 0;
8425 
8426 #ifdef RTE_NET_IXGBE
8427 	if (ret == -ENOTSUP)
8428 		ret = rte_pmd_ixgbe_set_vf_vlan_filter(res->port_id,
8429 				res->vlan_id, res->vf_mask, is_add);
8430 #endif
8431 #ifdef RTE_NET_I40E
8432 	if (ret == -ENOTSUP)
8433 		ret = rte_pmd_i40e_set_vf_vlan_filter(res->port_id,
8434 				res->vlan_id, res->vf_mask, is_add);
8435 #endif
8436 #ifdef RTE_NET_BNXT
8437 	if (ret == -ENOTSUP)
8438 		ret = rte_pmd_bnxt_set_vf_vlan_filter(res->port_id,
8439 				res->vlan_id, res->vf_mask, is_add);
8440 #endif
8441 
8442 	switch (ret) {
8443 	case 0:
8444 		break;
8445 	case -EINVAL:
8446 		fprintf(stderr, "invalid vlan_id %d or vf_mask %"PRIu64"\n",
8447 			res->vlan_id, res->vf_mask);
8448 		break;
8449 	case -ENODEV:
8450 		fprintf(stderr, "invalid port_id %d\n", res->port_id);
8451 		break;
8452 	case -ENOTSUP:
8453 		fprintf(stderr, "function not implemented or supported\n");
8454 		break;
8455 	default:
8456 		fprintf(stderr, "programming error: (%s)\n", strerror(-ret));
8457 	}
8458 }
8459 
8460 static cmdline_parse_token_string_t cmd_vf_rx_vlan_filter_rx_vlan =
8461 	TOKEN_STRING_INITIALIZER(struct cmd_vf_rx_vlan_filter,
8462 				 rx_vlan, "rx_vlan");
8463 static cmdline_parse_token_string_t cmd_vf_rx_vlan_filter_what =
8464 	TOKEN_STRING_INITIALIZER(struct cmd_vf_rx_vlan_filter,
8465 				 what, "add#rm");
8466 static cmdline_parse_token_num_t cmd_vf_rx_vlan_filter_vlanid =
8467 	TOKEN_NUM_INITIALIZER(struct cmd_vf_rx_vlan_filter,
8468 			      vlan_id, RTE_UINT16);
8469 static cmdline_parse_token_string_t cmd_vf_rx_vlan_filter_port =
8470 	TOKEN_STRING_INITIALIZER(struct cmd_vf_rx_vlan_filter,
8471 				 port, "port");
8472 static cmdline_parse_token_num_t cmd_vf_rx_vlan_filter_portid =
8473 	TOKEN_NUM_INITIALIZER(struct cmd_vf_rx_vlan_filter,
8474 			      port_id, RTE_UINT16);
8475 static cmdline_parse_token_string_t cmd_vf_rx_vlan_filter_vf =
8476 	TOKEN_STRING_INITIALIZER(struct cmd_vf_rx_vlan_filter,
8477 				 vf, "vf");
8478 static cmdline_parse_token_num_t cmd_vf_rx_vlan_filter_vf_mask =
8479 	TOKEN_NUM_INITIALIZER(struct cmd_vf_rx_vlan_filter,
8480 			      vf_mask, RTE_UINT64);
8481 
8482 static cmdline_parse_inst_t cmd_vf_rxvlan_filter = {
8483 	.f = cmd_vf_rx_vlan_filter_parsed,
8484 	.data = NULL,
8485 	.help_str = "rx_vlan add|rm <vlan_id> port <port_id> vf <vf_mask>: "
8486 		"(vf_mask = hexadecimal VF mask)",
8487 	.tokens = {
8488 		(void *)&cmd_vf_rx_vlan_filter_rx_vlan,
8489 		(void *)&cmd_vf_rx_vlan_filter_what,
8490 		(void *)&cmd_vf_rx_vlan_filter_vlanid,
8491 		(void *)&cmd_vf_rx_vlan_filter_port,
8492 		(void *)&cmd_vf_rx_vlan_filter_portid,
8493 		(void *)&cmd_vf_rx_vlan_filter_vf,
8494 		(void *)&cmd_vf_rx_vlan_filter_vf_mask,
8495 		NULL,
8496 	},
8497 };
8498 
8499 /* *** SET RATE LIMIT FOR A QUEUE OF A PORT *** */
8500 struct cmd_queue_rate_limit_result {
8501 	cmdline_fixed_string_t set;
8502 	cmdline_fixed_string_t port;
8503 	uint16_t port_num;
8504 	cmdline_fixed_string_t queue;
8505 	uint8_t queue_num;
8506 	cmdline_fixed_string_t rate;
8507 	uint32_t rate_num;
8508 };
8509 
8510 static void cmd_queue_rate_limit_parsed(void *parsed_result,
8511 		__rte_unused struct cmdline *cl,
8512 		__rte_unused void *data)
8513 {
8514 	struct cmd_queue_rate_limit_result *res = parsed_result;
8515 	int ret = 0;
8516 
8517 	if ((strcmp(res->set, "set") == 0) && (strcmp(res->port, "port") == 0)
8518 		&& (strcmp(res->queue, "queue") == 0)
8519 		&& (strcmp(res->rate, "rate") == 0))
8520 		ret = set_queue_rate_limit(res->port_num, res->queue_num,
8521 					res->rate_num);
8522 	if (ret < 0)
8523 		fprintf(stderr, "queue_rate_limit_cmd error: (%s)\n",
8524 			strerror(-ret));
8525 
8526 }
8527 
8528 static cmdline_parse_token_string_t cmd_queue_rate_limit_set =
8529 	TOKEN_STRING_INITIALIZER(struct cmd_queue_rate_limit_result,
8530 				set, "set");
8531 static cmdline_parse_token_string_t cmd_queue_rate_limit_port =
8532 	TOKEN_STRING_INITIALIZER(struct cmd_queue_rate_limit_result,
8533 				port, "port");
8534 static cmdline_parse_token_num_t cmd_queue_rate_limit_portnum =
8535 	TOKEN_NUM_INITIALIZER(struct cmd_queue_rate_limit_result,
8536 				port_num, RTE_UINT16);
8537 static cmdline_parse_token_string_t cmd_queue_rate_limit_queue =
8538 	TOKEN_STRING_INITIALIZER(struct cmd_queue_rate_limit_result,
8539 				queue, "queue");
8540 static cmdline_parse_token_num_t cmd_queue_rate_limit_queuenum =
8541 	TOKEN_NUM_INITIALIZER(struct cmd_queue_rate_limit_result,
8542 				queue_num, RTE_UINT8);
8543 static cmdline_parse_token_string_t cmd_queue_rate_limit_rate =
8544 	TOKEN_STRING_INITIALIZER(struct cmd_queue_rate_limit_result,
8545 				rate, "rate");
8546 static cmdline_parse_token_num_t cmd_queue_rate_limit_ratenum =
8547 	TOKEN_NUM_INITIALIZER(struct cmd_queue_rate_limit_result,
8548 				rate_num, RTE_UINT32);
8549 
8550 static cmdline_parse_inst_t cmd_queue_rate_limit = {
8551 	.f = cmd_queue_rate_limit_parsed,
8552 	.data = (void *)0,
8553 	.help_str = "set port <port_id> queue <queue_id> rate <rate_value>: "
8554 		"Set rate limit for a queue on port_id",
8555 	.tokens = {
8556 		(void *)&cmd_queue_rate_limit_set,
8557 		(void *)&cmd_queue_rate_limit_port,
8558 		(void *)&cmd_queue_rate_limit_portnum,
8559 		(void *)&cmd_queue_rate_limit_queue,
8560 		(void *)&cmd_queue_rate_limit_queuenum,
8561 		(void *)&cmd_queue_rate_limit_rate,
8562 		(void *)&cmd_queue_rate_limit_ratenum,
8563 		NULL,
8564 	},
8565 };
8566 
8567 /* *** SET RATE LIMIT FOR A VF OF A PORT *** */
8568 struct cmd_vf_rate_limit_result {
8569 	cmdline_fixed_string_t set;
8570 	cmdline_fixed_string_t port;
8571 	uint16_t port_num;
8572 	cmdline_fixed_string_t vf;
8573 	uint8_t vf_num;
8574 	cmdline_fixed_string_t rate;
8575 	uint32_t rate_num;
8576 	cmdline_fixed_string_t q_msk;
8577 	uint64_t q_msk_val;
8578 };
8579 
8580 static void cmd_vf_rate_limit_parsed(void *parsed_result,
8581 		__rte_unused struct cmdline *cl,
8582 		__rte_unused void *data)
8583 {
8584 	struct cmd_vf_rate_limit_result *res = parsed_result;
8585 	int ret = 0;
8586 
8587 	if ((strcmp(res->set, "set") == 0) && (strcmp(res->port, "port") == 0)
8588 		&& (strcmp(res->vf, "vf") == 0)
8589 		&& (strcmp(res->rate, "rate") == 0)
8590 		&& (strcmp(res->q_msk, "queue_mask") == 0))
8591 		ret = set_vf_rate_limit(res->port_num, res->vf_num,
8592 					res->rate_num, res->q_msk_val);
8593 	if (ret < 0)
8594 		fprintf(stderr, "vf_rate_limit_cmd error: (%s)\n",
8595 			strerror(-ret));
8596 
8597 }
8598 
8599 static cmdline_parse_token_string_t cmd_vf_rate_limit_set =
8600 	TOKEN_STRING_INITIALIZER(struct cmd_vf_rate_limit_result,
8601 				set, "set");
8602 static cmdline_parse_token_string_t cmd_vf_rate_limit_port =
8603 	TOKEN_STRING_INITIALIZER(struct cmd_vf_rate_limit_result,
8604 				port, "port");
8605 static cmdline_parse_token_num_t cmd_vf_rate_limit_portnum =
8606 	TOKEN_NUM_INITIALIZER(struct cmd_vf_rate_limit_result,
8607 				port_num, RTE_UINT16);
8608 static cmdline_parse_token_string_t cmd_vf_rate_limit_vf =
8609 	TOKEN_STRING_INITIALIZER(struct cmd_vf_rate_limit_result,
8610 				vf, "vf");
8611 static cmdline_parse_token_num_t cmd_vf_rate_limit_vfnum =
8612 	TOKEN_NUM_INITIALIZER(struct cmd_vf_rate_limit_result,
8613 				vf_num, RTE_UINT8);
8614 static cmdline_parse_token_string_t cmd_vf_rate_limit_rate =
8615 	TOKEN_STRING_INITIALIZER(struct cmd_vf_rate_limit_result,
8616 				rate, "rate");
8617 static cmdline_parse_token_num_t cmd_vf_rate_limit_ratenum =
8618 	TOKEN_NUM_INITIALIZER(struct cmd_vf_rate_limit_result,
8619 				rate_num, RTE_UINT32);
8620 static cmdline_parse_token_string_t cmd_vf_rate_limit_q_msk =
8621 	TOKEN_STRING_INITIALIZER(struct cmd_vf_rate_limit_result,
8622 				q_msk, "queue_mask");
8623 static cmdline_parse_token_num_t cmd_vf_rate_limit_q_msk_val =
8624 	TOKEN_NUM_INITIALIZER(struct cmd_vf_rate_limit_result,
8625 				q_msk_val, RTE_UINT64);
8626 
8627 static cmdline_parse_inst_t cmd_vf_rate_limit = {
8628 	.f = cmd_vf_rate_limit_parsed,
8629 	.data = (void *)0,
8630 	.help_str = "set port <port_id> vf <vf_id> rate <rate_value> "
8631 		"queue_mask <queue_mask_value>: "
8632 		"Set rate limit for queues of VF on port_id",
8633 	.tokens = {
8634 		(void *)&cmd_vf_rate_limit_set,
8635 		(void *)&cmd_vf_rate_limit_port,
8636 		(void *)&cmd_vf_rate_limit_portnum,
8637 		(void *)&cmd_vf_rate_limit_vf,
8638 		(void *)&cmd_vf_rate_limit_vfnum,
8639 		(void *)&cmd_vf_rate_limit_rate,
8640 		(void *)&cmd_vf_rate_limit_ratenum,
8641 		(void *)&cmd_vf_rate_limit_q_msk,
8642 		(void *)&cmd_vf_rate_limit_q_msk_val,
8643 		NULL,
8644 	},
8645 };
8646 
8647 /* *** CONFIGURE TUNNEL UDP PORT *** */
8648 struct cmd_tunnel_udp_config {
8649 	cmdline_fixed_string_t rx_vxlan_port;
8650 	cmdline_fixed_string_t what;
8651 	uint16_t udp_port;
8652 	portid_t port_id;
8653 };
8654 
8655 static void
8656 cmd_tunnel_udp_config_parsed(void *parsed_result,
8657 			  __rte_unused struct cmdline *cl,
8658 			  __rte_unused void *data)
8659 {
8660 	struct cmd_tunnel_udp_config *res = parsed_result;
8661 	struct rte_eth_udp_tunnel tunnel_udp;
8662 	int ret;
8663 
8664 	tunnel_udp.udp_port = res->udp_port;
8665 	tunnel_udp.prot_type = RTE_ETH_TUNNEL_TYPE_VXLAN;
8666 
8667 	if (!strcmp(res->what, "add"))
8668 		ret = rte_eth_dev_udp_tunnel_port_add(res->port_id,
8669 						      &tunnel_udp);
8670 	else
8671 		ret = rte_eth_dev_udp_tunnel_port_delete(res->port_id,
8672 							 &tunnel_udp);
8673 
8674 	if (ret < 0)
8675 		fprintf(stderr, "udp tunneling add error: (%s)\n",
8676 			strerror(-ret));
8677 }
8678 
8679 static cmdline_parse_token_string_t cmd_tunnel_udp_config_rx_vxlan_port =
8680 	TOKEN_STRING_INITIALIZER(struct cmd_tunnel_udp_config,
8681 				rx_vxlan_port, "rx_vxlan_port");
8682 static cmdline_parse_token_string_t cmd_tunnel_udp_config_what =
8683 	TOKEN_STRING_INITIALIZER(struct cmd_tunnel_udp_config,
8684 				what, "add#rm");
8685 static cmdline_parse_token_num_t cmd_tunnel_udp_config_udp_port =
8686 	TOKEN_NUM_INITIALIZER(struct cmd_tunnel_udp_config,
8687 				udp_port, RTE_UINT16);
8688 static cmdline_parse_token_num_t cmd_tunnel_udp_config_port_id =
8689 	TOKEN_NUM_INITIALIZER(struct cmd_tunnel_udp_config,
8690 				port_id, RTE_UINT16);
8691 
8692 static cmdline_parse_inst_t cmd_tunnel_udp_config = {
8693 	.f = cmd_tunnel_udp_config_parsed,
8694 	.data = (void *)0,
8695 	.help_str = "rx_vxlan_port add|rm <udp_port> <port_id>: "
8696 		"Add/Remove a tunneling UDP port filter",
8697 	.tokens = {
8698 		(void *)&cmd_tunnel_udp_config_rx_vxlan_port,
8699 		(void *)&cmd_tunnel_udp_config_what,
8700 		(void *)&cmd_tunnel_udp_config_udp_port,
8701 		(void *)&cmd_tunnel_udp_config_port_id,
8702 		NULL,
8703 	},
8704 };
8705 
8706 struct cmd_config_tunnel_udp_port {
8707 	cmdline_fixed_string_t port;
8708 	cmdline_fixed_string_t config;
8709 	portid_t port_id;
8710 	cmdline_fixed_string_t udp_tunnel_port;
8711 	cmdline_fixed_string_t action;
8712 	cmdline_fixed_string_t tunnel_type;
8713 	uint16_t udp_port;
8714 };
8715 
8716 static void
8717 cmd_cfg_tunnel_udp_port_parsed(void *parsed_result,
8718 			       __rte_unused struct cmdline *cl,
8719 			       __rte_unused void *data)
8720 {
8721 	struct cmd_config_tunnel_udp_port *res = parsed_result;
8722 	struct rte_eth_udp_tunnel tunnel_udp;
8723 	int ret = 0;
8724 
8725 	if (port_id_is_invalid(res->port_id, ENABLED_WARN))
8726 		return;
8727 
8728 	tunnel_udp.udp_port = res->udp_port;
8729 
8730 	if (!strcmp(res->tunnel_type, "vxlan")) {
8731 		tunnel_udp.prot_type = RTE_ETH_TUNNEL_TYPE_VXLAN;
8732 	} else if (!strcmp(res->tunnel_type, "geneve")) {
8733 		tunnel_udp.prot_type = RTE_ETH_TUNNEL_TYPE_GENEVE;
8734 	} else if (!strcmp(res->tunnel_type, "vxlan-gpe")) {
8735 		tunnel_udp.prot_type = RTE_ETH_TUNNEL_TYPE_VXLAN_GPE;
8736 	} else if (!strcmp(res->tunnel_type, "ecpri")) {
8737 		tunnel_udp.prot_type = RTE_ETH_TUNNEL_TYPE_ECPRI;
8738 	} else {
8739 		fprintf(stderr, "Invalid tunnel type\n");
8740 		return;
8741 	}
8742 
8743 	if (!strcmp(res->action, "add"))
8744 		ret = rte_eth_dev_udp_tunnel_port_add(res->port_id,
8745 						      &tunnel_udp);
8746 	else
8747 		ret = rte_eth_dev_udp_tunnel_port_delete(res->port_id,
8748 							 &tunnel_udp);
8749 
8750 	if (ret < 0)
8751 		fprintf(stderr, "udp tunneling port add error: (%s)\n",
8752 			strerror(-ret));
8753 }
8754 
8755 static cmdline_parse_token_string_t cmd_config_tunnel_udp_port_port =
8756 	TOKEN_STRING_INITIALIZER(struct cmd_config_tunnel_udp_port, port,
8757 				 "port");
8758 static cmdline_parse_token_string_t cmd_config_tunnel_udp_port_config =
8759 	TOKEN_STRING_INITIALIZER(struct cmd_config_tunnel_udp_port, config,
8760 				 "config");
8761 static cmdline_parse_token_num_t cmd_config_tunnel_udp_port_port_id =
8762 	TOKEN_NUM_INITIALIZER(struct cmd_config_tunnel_udp_port, port_id,
8763 			      RTE_UINT16);
8764 static cmdline_parse_token_string_t cmd_config_tunnel_udp_port_tunnel_port =
8765 	TOKEN_STRING_INITIALIZER(struct cmd_config_tunnel_udp_port,
8766 				 udp_tunnel_port,
8767 				 "udp_tunnel_port");
8768 static cmdline_parse_token_string_t cmd_config_tunnel_udp_port_action =
8769 	TOKEN_STRING_INITIALIZER(struct cmd_config_tunnel_udp_port, action,
8770 				 "add#rm");
8771 static cmdline_parse_token_string_t cmd_config_tunnel_udp_port_tunnel_type =
8772 	TOKEN_STRING_INITIALIZER(struct cmd_config_tunnel_udp_port, tunnel_type,
8773 				 "vxlan#geneve#vxlan-gpe#ecpri");
8774 static cmdline_parse_token_num_t cmd_config_tunnel_udp_port_value =
8775 	TOKEN_NUM_INITIALIZER(struct cmd_config_tunnel_udp_port, udp_port,
8776 			      RTE_UINT16);
8777 
8778 static cmdline_parse_inst_t cmd_cfg_tunnel_udp_port = {
8779 	.f = cmd_cfg_tunnel_udp_port_parsed,
8780 	.data = NULL,
8781 	.help_str = "port config <port_id> udp_tunnel_port add|rm vxlan|"
8782 		"geneve|vxlan-gpe|ecpri <udp_port>",
8783 	.tokens = {
8784 		(void *)&cmd_config_tunnel_udp_port_port,
8785 		(void *)&cmd_config_tunnel_udp_port_config,
8786 		(void *)&cmd_config_tunnel_udp_port_port_id,
8787 		(void *)&cmd_config_tunnel_udp_port_tunnel_port,
8788 		(void *)&cmd_config_tunnel_udp_port_action,
8789 		(void *)&cmd_config_tunnel_udp_port_tunnel_type,
8790 		(void *)&cmd_config_tunnel_udp_port_value,
8791 		NULL,
8792 	},
8793 };
8794 
8795 /* ******************************************************************************** */
8796 
8797 struct cmd_dump_result {
8798 	cmdline_fixed_string_t dump;
8799 };
8800 
8801 static void
8802 dump_struct_sizes(void)
8803 {
8804 #define DUMP_SIZE(t) printf("sizeof(" #t ") = %u\n", (unsigned)sizeof(t));
8805 	DUMP_SIZE(struct rte_mbuf);
8806 	DUMP_SIZE(struct rte_mempool);
8807 	DUMP_SIZE(struct rte_ring);
8808 #undef DUMP_SIZE
8809 }
8810 
8811 
8812 /* Dump the socket memory statistics on console */
8813 static void
8814 dump_socket_mem(FILE *f)
8815 {
8816 	struct rte_malloc_socket_stats socket_stats;
8817 	unsigned int i;
8818 	size_t total = 0;
8819 	size_t alloc = 0;
8820 	size_t free = 0;
8821 	unsigned int n_alloc = 0;
8822 	unsigned int n_free = 0;
8823 	static size_t last_allocs;
8824 	static size_t last_total;
8825 
8826 
8827 	for (i = 0; i < RTE_MAX_NUMA_NODES; i++) {
8828 		if (rte_malloc_get_socket_stats(i, &socket_stats) ||
8829 		    !socket_stats.heap_totalsz_bytes)
8830 			continue;
8831 		total += socket_stats.heap_totalsz_bytes;
8832 		alloc += socket_stats.heap_allocsz_bytes;
8833 		free += socket_stats.heap_freesz_bytes;
8834 		n_alloc += socket_stats.alloc_count;
8835 		n_free += socket_stats.free_count;
8836 		fprintf(f,
8837 			"Socket %u: size(M) total: %.6lf alloc: %.6lf(%.3lf%%) free: %.6lf \tcount alloc: %-4u free: %u\n",
8838 			i,
8839 			(double)socket_stats.heap_totalsz_bytes / (1024 * 1024),
8840 			(double)socket_stats.heap_allocsz_bytes / (1024 * 1024),
8841 			(double)socket_stats.heap_allocsz_bytes * 100 /
8842 			(double)socket_stats.heap_totalsz_bytes,
8843 			(double)socket_stats.heap_freesz_bytes / (1024 * 1024),
8844 			socket_stats.alloc_count,
8845 			socket_stats.free_count);
8846 	}
8847 	fprintf(f,
8848 		"Total   : size(M) total: %.6lf alloc: %.6lf(%.3lf%%) free: %.6lf \tcount alloc: %-4u free: %u\n",
8849 		(double)total / (1024 * 1024), (double)alloc / (1024 * 1024),
8850 		total ? ((double)alloc * 100 / (double)total) : 0,
8851 		(double)free / (1024 * 1024),
8852 		n_alloc, n_free);
8853 	if (last_allocs)
8854 		fprintf(stdout, "Memory total change: %.6lf(M), allocation change: %.6lf(M)\n",
8855 			((double)total - (double)last_total) / (1024 * 1024),
8856 			(double)(alloc - (double)last_allocs) / 1024 / 1024);
8857 	last_allocs = alloc;
8858 	last_total = total;
8859 }
8860 
8861 static void cmd_dump_parsed(void *parsed_result,
8862 			    __rte_unused struct cmdline *cl,
8863 			    __rte_unused void *data)
8864 {
8865 	struct cmd_dump_result *res = parsed_result;
8866 
8867 	if (!strcmp(res->dump, "dump_physmem"))
8868 		rte_dump_physmem_layout(stdout);
8869 	else if (!strcmp(res->dump, "dump_socket_mem"))
8870 		dump_socket_mem(stdout);
8871 	else if (!strcmp(res->dump, "dump_memzone"))
8872 		rte_memzone_dump(stdout);
8873 	else if (!strcmp(res->dump, "dump_struct_sizes"))
8874 		dump_struct_sizes();
8875 	else if (!strcmp(res->dump, "dump_ring"))
8876 		rte_ring_list_dump(stdout);
8877 	else if (!strcmp(res->dump, "dump_mempool"))
8878 		rte_mempool_list_dump(stdout);
8879 	else if (!strcmp(res->dump, "dump_devargs"))
8880 		rte_devargs_dump(stdout);
8881 	else if (!strcmp(res->dump, "dump_lcores"))
8882 		rte_lcore_dump(stdout);
8883 #ifndef RTE_EXEC_ENV_WINDOWS
8884 	else if (!strcmp(res->dump, "dump_trace"))
8885 		rte_trace_save();
8886 #endif
8887 	else if (!strcmp(res->dump, "dump_log_types"))
8888 		rte_log_dump(stdout);
8889 }
8890 
8891 static cmdline_parse_token_string_t cmd_dump_dump =
8892 	TOKEN_STRING_INITIALIZER(struct cmd_dump_result, dump,
8893 		"dump_physmem#"
8894 		"dump_memzone#"
8895 		"dump_socket_mem#"
8896 		"dump_struct_sizes#"
8897 		"dump_ring#"
8898 		"dump_mempool#"
8899 		"dump_devargs#"
8900 		"dump_lcores#"
8901 #ifndef RTE_EXEC_ENV_WINDOWS
8902 		"dump_trace#"
8903 #endif
8904 		"dump_log_types");
8905 
8906 static cmdline_parse_inst_t cmd_dump = {
8907 	.f = cmd_dump_parsed,  /* function to call */
8908 	.data = NULL,      /* 2nd arg of func */
8909 	.help_str = "Dump status",
8910 	.tokens = {        /* token list, NULL terminated */
8911 		(void *)&cmd_dump_dump,
8912 		NULL,
8913 	},
8914 };
8915 
8916 /* ******************************************************************************** */
8917 
8918 struct cmd_dump_one_result {
8919 	cmdline_fixed_string_t dump;
8920 	cmdline_fixed_string_t name;
8921 };
8922 
8923 static void cmd_dump_one_parsed(void *parsed_result, struct cmdline *cl,
8924 				__rte_unused void *data)
8925 {
8926 	struct cmd_dump_one_result *res = parsed_result;
8927 
8928 	if (!strcmp(res->dump, "dump_ring")) {
8929 		struct rte_ring *r;
8930 		r = rte_ring_lookup(res->name);
8931 		if (r == NULL) {
8932 			cmdline_printf(cl, "Cannot find ring\n");
8933 			return;
8934 		}
8935 		rte_ring_dump(stdout, r);
8936 	} else if (!strcmp(res->dump, "dump_mempool")) {
8937 		struct rte_mempool *mp;
8938 		mp = rte_mempool_lookup(res->name);
8939 		if (mp == NULL) {
8940 			cmdline_printf(cl, "Cannot find mempool\n");
8941 			return;
8942 		}
8943 		rte_mempool_dump(stdout, mp);
8944 	}
8945 }
8946 
8947 static cmdline_parse_token_string_t cmd_dump_one_dump =
8948 	TOKEN_STRING_INITIALIZER(struct cmd_dump_one_result, dump,
8949 				 "dump_ring#dump_mempool");
8950 
8951 static cmdline_parse_token_string_t cmd_dump_one_name =
8952 	TOKEN_STRING_INITIALIZER(struct cmd_dump_one_result, name, NULL);
8953 
8954 static cmdline_parse_inst_t cmd_dump_one = {
8955 	.f = cmd_dump_one_parsed,  /* function to call */
8956 	.data = NULL,      /* 2nd arg of func */
8957 	.help_str = "dump_ring|dump_mempool <name>: Dump one ring/mempool",
8958 	.tokens = {        /* token list, NULL terminated */
8959 		(void *)&cmd_dump_one_dump,
8960 		(void *)&cmd_dump_one_name,
8961 		NULL,
8962 	},
8963 };
8964 
8965 /* *** Filters Control *** */
8966 
8967 #define IPV4_ADDR_TO_UINT(ip_addr, ip) \
8968 do { \
8969 	if ((ip_addr).family == AF_INET) \
8970 		(ip) = (ip_addr).addr.ipv4.s_addr; \
8971 	else { \
8972 		fprintf(stderr, "invalid parameter.\n"); \
8973 		return; \
8974 	} \
8975 } while (0)
8976 
8977 #define IPV6_ADDR_TO_ARRAY(ip_addr, ip) \
8978 do { \
8979 	if ((ip_addr).family == AF_INET6) \
8980 		ip = ip_addr.addr.ipv6; \
8981 	else { \
8982 		fprintf(stderr, "invalid parameter.\n"); \
8983 		return; \
8984 	} \
8985 } while (0)
8986 
8987 /* Generic flow interface command. */
8988 extern cmdline_parse_inst_t cmd_flow;
8989 
8990 /* *** ADD/REMOVE A MULTICAST MAC ADDRESS TO/FROM A PORT *** */
8991 struct cmd_mcast_addr_result {
8992 	cmdline_fixed_string_t mcast_addr_cmd;
8993 	cmdline_fixed_string_t what;
8994 	uint16_t port_num;
8995 	struct rte_ether_addr mc_addr;
8996 };
8997 
8998 static void cmd_mcast_addr_parsed(void *parsed_result,
8999 		__rte_unused struct cmdline *cl,
9000 		__rte_unused void *data)
9001 {
9002 	struct cmd_mcast_addr_result *res = parsed_result;
9003 
9004 	if (!rte_is_multicast_ether_addr(&res->mc_addr)) {
9005 		fprintf(stderr,
9006 			"Invalid multicast addr " RTE_ETHER_ADDR_PRT_FMT "\n",
9007 			RTE_ETHER_ADDR_BYTES(&res->mc_addr));
9008 		return;
9009 	}
9010 	if (strcmp(res->what, "add") == 0)
9011 		mcast_addr_add(res->port_num, &res->mc_addr);
9012 	else
9013 		mcast_addr_remove(res->port_num, &res->mc_addr);
9014 }
9015 
9016 static cmdline_parse_token_string_t cmd_mcast_addr_cmd =
9017 	TOKEN_STRING_INITIALIZER(struct cmd_mcast_addr_result,
9018 				 mcast_addr_cmd, "mcast_addr");
9019 static cmdline_parse_token_string_t cmd_mcast_addr_what =
9020 	TOKEN_STRING_INITIALIZER(struct cmd_mcast_addr_result, what,
9021 				 "add#remove");
9022 static cmdline_parse_token_num_t cmd_mcast_addr_portnum =
9023 	TOKEN_NUM_INITIALIZER(struct cmd_mcast_addr_result, port_num,
9024 				 RTE_UINT16);
9025 static cmdline_parse_token_etheraddr_t cmd_mcast_addr_addr =
9026 	TOKEN_ETHERADDR_INITIALIZER(struct cmd_mac_addr_result, address);
9027 
9028 static cmdline_parse_inst_t cmd_mcast_addr = {
9029 	.f = cmd_mcast_addr_parsed,
9030 	.data = (void *)0,
9031 	.help_str = "mcast_addr add|remove <port_id> <mcast_addr>: "
9032 		"Add/Remove multicast MAC address on port_id",
9033 	.tokens = {
9034 		(void *)&cmd_mcast_addr_cmd,
9035 		(void *)&cmd_mcast_addr_what,
9036 		(void *)&cmd_mcast_addr_portnum,
9037 		(void *)&cmd_mcast_addr_addr,
9038 		NULL,
9039 	},
9040 };
9041 
9042 /* *** FLUSH MULTICAST MAC ADDRESS ON PORT *** */
9043 struct cmd_mcast_addr_flush_result {
9044 	cmdline_fixed_string_t mcast_addr_cmd;
9045 	cmdline_fixed_string_t what;
9046 	uint16_t port_num;
9047 };
9048 
9049 static void cmd_mcast_addr_flush_parsed(void *parsed_result,
9050 		__rte_unused struct cmdline *cl,
9051 		__rte_unused void *data)
9052 {
9053 	struct cmd_mcast_addr_flush_result *res = parsed_result;
9054 
9055 	mcast_addr_flush(res->port_num);
9056 }
9057 
9058 static cmdline_parse_token_string_t cmd_mcast_addr_flush_cmd =
9059 	TOKEN_STRING_INITIALIZER(struct cmd_mcast_addr_result,
9060 				 mcast_addr_cmd, "mcast_addr");
9061 static cmdline_parse_token_string_t cmd_mcast_addr_flush_what =
9062 	TOKEN_STRING_INITIALIZER(struct cmd_mcast_addr_result, what,
9063 				 "flush");
9064 static cmdline_parse_token_num_t cmd_mcast_addr_flush_portnum =
9065 	TOKEN_NUM_INITIALIZER(struct cmd_mcast_addr_result, port_num,
9066 				 RTE_UINT16);
9067 
9068 static cmdline_parse_inst_t cmd_mcast_addr_flush = {
9069 	.f = cmd_mcast_addr_flush_parsed,
9070 	.data = (void *)0,
9071 	.help_str = "mcast_addr flush <port_id> : "
9072 		"flush all multicast MAC addresses on port_id",
9073 	.tokens = {
9074 		(void *)&cmd_mcast_addr_flush_cmd,
9075 		(void *)&cmd_mcast_addr_flush_what,
9076 		(void *)&cmd_mcast_addr_flush_portnum,
9077 		NULL,
9078 	},
9079 };
9080 
9081 /* vf vlan anti spoof configuration */
9082 
9083 /* Common result structure for vf vlan anti spoof */
9084 struct cmd_vf_vlan_anti_spoof_result {
9085 	cmdline_fixed_string_t set;
9086 	cmdline_fixed_string_t vf;
9087 	cmdline_fixed_string_t vlan;
9088 	cmdline_fixed_string_t antispoof;
9089 	portid_t port_id;
9090 	uint32_t vf_id;
9091 	cmdline_fixed_string_t on_off;
9092 };
9093 
9094 /* Common CLI fields for vf vlan anti spoof enable disable */
9095 static cmdline_parse_token_string_t cmd_vf_vlan_anti_spoof_set =
9096 	TOKEN_STRING_INITIALIZER
9097 		(struct cmd_vf_vlan_anti_spoof_result,
9098 		 set, "set");
9099 static cmdline_parse_token_string_t cmd_vf_vlan_anti_spoof_vf =
9100 	TOKEN_STRING_INITIALIZER
9101 		(struct cmd_vf_vlan_anti_spoof_result,
9102 		 vf, "vf");
9103 static cmdline_parse_token_string_t cmd_vf_vlan_anti_spoof_vlan =
9104 	TOKEN_STRING_INITIALIZER
9105 		(struct cmd_vf_vlan_anti_spoof_result,
9106 		 vlan, "vlan");
9107 static cmdline_parse_token_string_t cmd_vf_vlan_anti_spoof_antispoof =
9108 	TOKEN_STRING_INITIALIZER
9109 		(struct cmd_vf_vlan_anti_spoof_result,
9110 		 antispoof, "antispoof");
9111 static cmdline_parse_token_num_t cmd_vf_vlan_anti_spoof_port_id =
9112 	TOKEN_NUM_INITIALIZER
9113 		(struct cmd_vf_vlan_anti_spoof_result,
9114 		 port_id, RTE_UINT16);
9115 static cmdline_parse_token_num_t cmd_vf_vlan_anti_spoof_vf_id =
9116 	TOKEN_NUM_INITIALIZER
9117 		(struct cmd_vf_vlan_anti_spoof_result,
9118 		 vf_id, RTE_UINT32);
9119 static cmdline_parse_token_string_t cmd_vf_vlan_anti_spoof_on_off =
9120 	TOKEN_STRING_INITIALIZER
9121 		(struct cmd_vf_vlan_anti_spoof_result,
9122 		 on_off, "on#off");
9123 
9124 static void
9125 cmd_set_vf_vlan_anti_spoof_parsed(
9126 	void *parsed_result,
9127 	__rte_unused struct cmdline *cl,
9128 	__rte_unused void *data)
9129 {
9130 	struct cmd_vf_vlan_anti_spoof_result *res = parsed_result;
9131 	int ret = -ENOTSUP;
9132 
9133 	__rte_unused int is_on = (strcmp(res->on_off, "on") == 0) ? 1 : 0;
9134 
9135 	if (port_id_is_invalid(res->port_id, ENABLED_WARN))
9136 		return;
9137 
9138 #ifdef RTE_NET_IXGBE
9139 	if (ret == -ENOTSUP)
9140 		ret = rte_pmd_ixgbe_set_vf_vlan_anti_spoof(res->port_id,
9141 				res->vf_id, is_on);
9142 #endif
9143 #ifdef RTE_NET_I40E
9144 	if (ret == -ENOTSUP)
9145 		ret = rte_pmd_i40e_set_vf_vlan_anti_spoof(res->port_id,
9146 				res->vf_id, is_on);
9147 #endif
9148 #ifdef RTE_NET_BNXT
9149 	if (ret == -ENOTSUP)
9150 		ret = rte_pmd_bnxt_set_vf_vlan_anti_spoof(res->port_id,
9151 				res->vf_id, is_on);
9152 #endif
9153 
9154 	switch (ret) {
9155 	case 0:
9156 		break;
9157 	case -EINVAL:
9158 		fprintf(stderr, "invalid vf_id %d\n", res->vf_id);
9159 		break;
9160 	case -ENODEV:
9161 		fprintf(stderr, "invalid port_id %d\n", res->port_id);
9162 		break;
9163 	case -ENOTSUP:
9164 		fprintf(stderr, "function not implemented\n");
9165 		break;
9166 	default:
9167 		fprintf(stderr, "programming error: (%s)\n", strerror(-ret));
9168 	}
9169 }
9170 
9171 static cmdline_parse_inst_t cmd_set_vf_vlan_anti_spoof = {
9172 	.f = cmd_set_vf_vlan_anti_spoof_parsed,
9173 	.data = NULL,
9174 	.help_str = "set vf vlan antispoof <port_id> <vf_id> on|off",
9175 	.tokens = {
9176 		(void *)&cmd_vf_vlan_anti_spoof_set,
9177 		(void *)&cmd_vf_vlan_anti_spoof_vf,
9178 		(void *)&cmd_vf_vlan_anti_spoof_vlan,
9179 		(void *)&cmd_vf_vlan_anti_spoof_antispoof,
9180 		(void *)&cmd_vf_vlan_anti_spoof_port_id,
9181 		(void *)&cmd_vf_vlan_anti_spoof_vf_id,
9182 		(void *)&cmd_vf_vlan_anti_spoof_on_off,
9183 		NULL,
9184 	},
9185 };
9186 
9187 /* vf mac anti spoof configuration */
9188 
9189 /* Common result structure for vf mac anti spoof */
9190 struct cmd_vf_mac_anti_spoof_result {
9191 	cmdline_fixed_string_t set;
9192 	cmdline_fixed_string_t vf;
9193 	cmdline_fixed_string_t mac;
9194 	cmdline_fixed_string_t antispoof;
9195 	portid_t port_id;
9196 	uint32_t vf_id;
9197 	cmdline_fixed_string_t on_off;
9198 };
9199 
9200 /* Common CLI fields for vf mac anti spoof enable disable */
9201 static cmdline_parse_token_string_t cmd_vf_mac_anti_spoof_set =
9202 	TOKEN_STRING_INITIALIZER
9203 		(struct cmd_vf_mac_anti_spoof_result,
9204 		 set, "set");
9205 static cmdline_parse_token_string_t cmd_vf_mac_anti_spoof_vf =
9206 	TOKEN_STRING_INITIALIZER
9207 		(struct cmd_vf_mac_anti_spoof_result,
9208 		 vf, "vf");
9209 static cmdline_parse_token_string_t cmd_vf_mac_anti_spoof_mac =
9210 	TOKEN_STRING_INITIALIZER
9211 		(struct cmd_vf_mac_anti_spoof_result,
9212 		 mac, "mac");
9213 static cmdline_parse_token_string_t cmd_vf_mac_anti_spoof_antispoof =
9214 	TOKEN_STRING_INITIALIZER
9215 		(struct cmd_vf_mac_anti_spoof_result,
9216 		 antispoof, "antispoof");
9217 static cmdline_parse_token_num_t cmd_vf_mac_anti_spoof_port_id =
9218 	TOKEN_NUM_INITIALIZER
9219 		(struct cmd_vf_mac_anti_spoof_result,
9220 		 port_id, RTE_UINT16);
9221 static cmdline_parse_token_num_t cmd_vf_mac_anti_spoof_vf_id =
9222 	TOKEN_NUM_INITIALIZER
9223 		(struct cmd_vf_mac_anti_spoof_result,
9224 		 vf_id, RTE_UINT32);
9225 static cmdline_parse_token_string_t cmd_vf_mac_anti_spoof_on_off =
9226 	TOKEN_STRING_INITIALIZER
9227 		(struct cmd_vf_mac_anti_spoof_result,
9228 		 on_off, "on#off");
9229 
9230 static void
9231 cmd_set_vf_mac_anti_spoof_parsed(
9232 	void *parsed_result,
9233 	__rte_unused struct cmdline *cl,
9234 	__rte_unused void *data)
9235 {
9236 	struct cmd_vf_mac_anti_spoof_result *res = parsed_result;
9237 	int ret = -ENOTSUP;
9238 
9239 	__rte_unused int is_on = (strcmp(res->on_off, "on") == 0) ? 1 : 0;
9240 
9241 	if (port_id_is_invalid(res->port_id, ENABLED_WARN))
9242 		return;
9243 
9244 #ifdef RTE_NET_IXGBE
9245 	if (ret == -ENOTSUP)
9246 		ret = rte_pmd_ixgbe_set_vf_mac_anti_spoof(res->port_id,
9247 			res->vf_id, is_on);
9248 #endif
9249 #ifdef RTE_NET_I40E
9250 	if (ret == -ENOTSUP)
9251 		ret = rte_pmd_i40e_set_vf_mac_anti_spoof(res->port_id,
9252 			res->vf_id, is_on);
9253 #endif
9254 #ifdef RTE_NET_BNXT
9255 	if (ret == -ENOTSUP)
9256 		ret = rte_pmd_bnxt_set_vf_mac_anti_spoof(res->port_id,
9257 			res->vf_id, is_on);
9258 #endif
9259 
9260 	switch (ret) {
9261 	case 0:
9262 		break;
9263 	case -EINVAL:
9264 		fprintf(stderr, "invalid vf_id %d or is_on %d\n",
9265 			res->vf_id, is_on);
9266 		break;
9267 	case -ENODEV:
9268 		fprintf(stderr, "invalid port_id %d\n", res->port_id);
9269 		break;
9270 	case -ENOTSUP:
9271 		fprintf(stderr, "function not implemented\n");
9272 		break;
9273 	default:
9274 		fprintf(stderr, "programming error: (%s)\n", strerror(-ret));
9275 	}
9276 }
9277 
9278 static cmdline_parse_inst_t cmd_set_vf_mac_anti_spoof = {
9279 	.f = cmd_set_vf_mac_anti_spoof_parsed,
9280 	.data = NULL,
9281 	.help_str = "set vf mac antispoof <port_id> <vf_id> on|off",
9282 	.tokens = {
9283 		(void *)&cmd_vf_mac_anti_spoof_set,
9284 		(void *)&cmd_vf_mac_anti_spoof_vf,
9285 		(void *)&cmd_vf_mac_anti_spoof_mac,
9286 		(void *)&cmd_vf_mac_anti_spoof_antispoof,
9287 		(void *)&cmd_vf_mac_anti_spoof_port_id,
9288 		(void *)&cmd_vf_mac_anti_spoof_vf_id,
9289 		(void *)&cmd_vf_mac_anti_spoof_on_off,
9290 		NULL,
9291 	},
9292 };
9293 
9294 /* vf vlan strip queue configuration */
9295 
9296 /* Common result structure for vf mac anti spoof */
9297 struct cmd_vf_vlan_stripq_result {
9298 	cmdline_fixed_string_t set;
9299 	cmdline_fixed_string_t vf;
9300 	cmdline_fixed_string_t vlan;
9301 	cmdline_fixed_string_t stripq;
9302 	portid_t port_id;
9303 	uint16_t vf_id;
9304 	cmdline_fixed_string_t on_off;
9305 };
9306 
9307 /* Common CLI fields for vf vlan strip enable disable */
9308 static cmdline_parse_token_string_t cmd_vf_vlan_stripq_set =
9309 	TOKEN_STRING_INITIALIZER
9310 		(struct cmd_vf_vlan_stripq_result,
9311 		 set, "set");
9312 static cmdline_parse_token_string_t cmd_vf_vlan_stripq_vf =
9313 	TOKEN_STRING_INITIALIZER
9314 		(struct cmd_vf_vlan_stripq_result,
9315 		 vf, "vf");
9316 static cmdline_parse_token_string_t cmd_vf_vlan_stripq_vlan =
9317 	TOKEN_STRING_INITIALIZER
9318 		(struct cmd_vf_vlan_stripq_result,
9319 		 vlan, "vlan");
9320 static cmdline_parse_token_string_t cmd_vf_vlan_stripq_stripq =
9321 	TOKEN_STRING_INITIALIZER
9322 		(struct cmd_vf_vlan_stripq_result,
9323 		 stripq, "stripq");
9324 static cmdline_parse_token_num_t cmd_vf_vlan_stripq_port_id =
9325 	TOKEN_NUM_INITIALIZER
9326 		(struct cmd_vf_vlan_stripq_result,
9327 		 port_id, RTE_UINT16);
9328 static cmdline_parse_token_num_t cmd_vf_vlan_stripq_vf_id =
9329 	TOKEN_NUM_INITIALIZER
9330 		(struct cmd_vf_vlan_stripq_result,
9331 		 vf_id, RTE_UINT16);
9332 static cmdline_parse_token_string_t cmd_vf_vlan_stripq_on_off =
9333 	TOKEN_STRING_INITIALIZER
9334 		(struct cmd_vf_vlan_stripq_result,
9335 		 on_off, "on#off");
9336 
9337 static void
9338 cmd_set_vf_vlan_stripq_parsed(
9339 	void *parsed_result,
9340 	__rte_unused struct cmdline *cl,
9341 	__rte_unused void *data)
9342 {
9343 	struct cmd_vf_vlan_stripq_result *res = parsed_result;
9344 	int ret = -ENOTSUP;
9345 
9346 	__rte_unused int is_on = (strcmp(res->on_off, "on") == 0) ? 1 : 0;
9347 
9348 	if (port_id_is_invalid(res->port_id, ENABLED_WARN))
9349 		return;
9350 
9351 #ifdef RTE_NET_IXGBE
9352 	if (ret == -ENOTSUP)
9353 		ret = rte_pmd_ixgbe_set_vf_vlan_stripq(res->port_id,
9354 			res->vf_id, is_on);
9355 #endif
9356 #ifdef RTE_NET_I40E
9357 	if (ret == -ENOTSUP)
9358 		ret = rte_pmd_i40e_set_vf_vlan_stripq(res->port_id,
9359 			res->vf_id, is_on);
9360 #endif
9361 #ifdef RTE_NET_BNXT
9362 	if (ret == -ENOTSUP)
9363 		ret = rte_pmd_bnxt_set_vf_vlan_stripq(res->port_id,
9364 			res->vf_id, is_on);
9365 #endif
9366 
9367 	switch (ret) {
9368 	case 0:
9369 		break;
9370 	case -EINVAL:
9371 		fprintf(stderr, "invalid vf_id %d or is_on %d\n",
9372 			res->vf_id, is_on);
9373 		break;
9374 	case -ENODEV:
9375 		fprintf(stderr, "invalid port_id %d\n", res->port_id);
9376 		break;
9377 	case -ENOTSUP:
9378 		fprintf(stderr, "function not implemented\n");
9379 		break;
9380 	default:
9381 		fprintf(stderr, "programming error: (%s)\n", strerror(-ret));
9382 	}
9383 }
9384 
9385 static cmdline_parse_inst_t cmd_set_vf_vlan_stripq = {
9386 	.f = cmd_set_vf_vlan_stripq_parsed,
9387 	.data = NULL,
9388 	.help_str = "set vf vlan stripq <port_id> <vf_id> on|off",
9389 	.tokens = {
9390 		(void *)&cmd_vf_vlan_stripq_set,
9391 		(void *)&cmd_vf_vlan_stripq_vf,
9392 		(void *)&cmd_vf_vlan_stripq_vlan,
9393 		(void *)&cmd_vf_vlan_stripq_stripq,
9394 		(void *)&cmd_vf_vlan_stripq_port_id,
9395 		(void *)&cmd_vf_vlan_stripq_vf_id,
9396 		(void *)&cmd_vf_vlan_stripq_on_off,
9397 		NULL,
9398 	},
9399 };
9400 
9401 /* vf vlan insert configuration */
9402 
9403 /* Common result structure for vf vlan insert */
9404 struct cmd_vf_vlan_insert_result {
9405 	cmdline_fixed_string_t set;
9406 	cmdline_fixed_string_t vf;
9407 	cmdline_fixed_string_t vlan;
9408 	cmdline_fixed_string_t insert;
9409 	portid_t port_id;
9410 	uint16_t vf_id;
9411 	uint16_t vlan_id;
9412 };
9413 
9414 /* Common CLI fields for vf vlan insert enable disable */
9415 static cmdline_parse_token_string_t cmd_vf_vlan_insert_set =
9416 	TOKEN_STRING_INITIALIZER
9417 		(struct cmd_vf_vlan_insert_result,
9418 		 set, "set");
9419 static cmdline_parse_token_string_t cmd_vf_vlan_insert_vf =
9420 	TOKEN_STRING_INITIALIZER
9421 		(struct cmd_vf_vlan_insert_result,
9422 		 vf, "vf");
9423 static cmdline_parse_token_string_t cmd_vf_vlan_insert_vlan =
9424 	TOKEN_STRING_INITIALIZER
9425 		(struct cmd_vf_vlan_insert_result,
9426 		 vlan, "vlan");
9427 static cmdline_parse_token_string_t cmd_vf_vlan_insert_insert =
9428 	TOKEN_STRING_INITIALIZER
9429 		(struct cmd_vf_vlan_insert_result,
9430 		 insert, "insert");
9431 static cmdline_parse_token_num_t cmd_vf_vlan_insert_port_id =
9432 	TOKEN_NUM_INITIALIZER
9433 		(struct cmd_vf_vlan_insert_result,
9434 		 port_id, RTE_UINT16);
9435 static cmdline_parse_token_num_t cmd_vf_vlan_insert_vf_id =
9436 	TOKEN_NUM_INITIALIZER
9437 		(struct cmd_vf_vlan_insert_result,
9438 		 vf_id, RTE_UINT16);
9439 static cmdline_parse_token_num_t cmd_vf_vlan_insert_vlan_id =
9440 	TOKEN_NUM_INITIALIZER
9441 		(struct cmd_vf_vlan_insert_result,
9442 		 vlan_id, RTE_UINT16);
9443 
9444 static void
9445 cmd_set_vf_vlan_insert_parsed(
9446 	void *parsed_result,
9447 	__rte_unused struct cmdline *cl,
9448 	__rte_unused void *data)
9449 {
9450 	struct cmd_vf_vlan_insert_result *res = parsed_result;
9451 	int ret = -ENOTSUP;
9452 
9453 	if (port_id_is_invalid(res->port_id, ENABLED_WARN))
9454 		return;
9455 
9456 #ifdef RTE_NET_IXGBE
9457 	if (ret == -ENOTSUP)
9458 		ret = rte_pmd_ixgbe_set_vf_vlan_insert(res->port_id, res->vf_id,
9459 			res->vlan_id);
9460 #endif
9461 #ifdef RTE_NET_I40E
9462 	if (ret == -ENOTSUP)
9463 		ret = rte_pmd_i40e_set_vf_vlan_insert(res->port_id, res->vf_id,
9464 			res->vlan_id);
9465 #endif
9466 #ifdef RTE_NET_BNXT
9467 	if (ret == -ENOTSUP)
9468 		ret = rte_pmd_bnxt_set_vf_vlan_insert(res->port_id, res->vf_id,
9469 			res->vlan_id);
9470 #endif
9471 
9472 	switch (ret) {
9473 	case 0:
9474 		break;
9475 	case -EINVAL:
9476 		fprintf(stderr, "invalid vf_id %d or vlan_id %d\n",
9477 			res->vf_id, res->vlan_id);
9478 		break;
9479 	case -ENODEV:
9480 		fprintf(stderr, "invalid port_id %d\n", res->port_id);
9481 		break;
9482 	case -ENOTSUP:
9483 		fprintf(stderr, "function not implemented\n");
9484 		break;
9485 	default:
9486 		fprintf(stderr, "programming error: (%s)\n", strerror(-ret));
9487 	}
9488 }
9489 
9490 static cmdline_parse_inst_t cmd_set_vf_vlan_insert = {
9491 	.f = cmd_set_vf_vlan_insert_parsed,
9492 	.data = NULL,
9493 	.help_str = "set vf vlan insert <port_id> <vf_id> <vlan_id>",
9494 	.tokens = {
9495 		(void *)&cmd_vf_vlan_insert_set,
9496 		(void *)&cmd_vf_vlan_insert_vf,
9497 		(void *)&cmd_vf_vlan_insert_vlan,
9498 		(void *)&cmd_vf_vlan_insert_insert,
9499 		(void *)&cmd_vf_vlan_insert_port_id,
9500 		(void *)&cmd_vf_vlan_insert_vf_id,
9501 		(void *)&cmd_vf_vlan_insert_vlan_id,
9502 		NULL,
9503 	},
9504 };
9505 
9506 /* tx loopback configuration */
9507 
9508 /* Common result structure for tx loopback */
9509 struct cmd_tx_loopback_result {
9510 	cmdline_fixed_string_t set;
9511 	cmdline_fixed_string_t tx;
9512 	cmdline_fixed_string_t loopback;
9513 	portid_t port_id;
9514 	cmdline_fixed_string_t on_off;
9515 };
9516 
9517 /* Common CLI fields for tx loopback enable disable */
9518 static cmdline_parse_token_string_t cmd_tx_loopback_set =
9519 	TOKEN_STRING_INITIALIZER
9520 		(struct cmd_tx_loopback_result,
9521 		 set, "set");
9522 static cmdline_parse_token_string_t cmd_tx_loopback_tx =
9523 	TOKEN_STRING_INITIALIZER
9524 		(struct cmd_tx_loopback_result,
9525 		 tx, "tx");
9526 static cmdline_parse_token_string_t cmd_tx_loopback_loopback =
9527 	TOKEN_STRING_INITIALIZER
9528 		(struct cmd_tx_loopback_result,
9529 		 loopback, "loopback");
9530 static cmdline_parse_token_num_t cmd_tx_loopback_port_id =
9531 	TOKEN_NUM_INITIALIZER
9532 		(struct cmd_tx_loopback_result,
9533 		 port_id, RTE_UINT16);
9534 static cmdline_parse_token_string_t cmd_tx_loopback_on_off =
9535 	TOKEN_STRING_INITIALIZER
9536 		(struct cmd_tx_loopback_result,
9537 		 on_off, "on#off");
9538 
9539 static void
9540 cmd_set_tx_loopback_parsed(
9541 	void *parsed_result,
9542 	__rte_unused struct cmdline *cl,
9543 	__rte_unused void *data)
9544 {
9545 	struct cmd_tx_loopback_result *res = parsed_result;
9546 	int ret = -ENOTSUP;
9547 
9548 	__rte_unused int is_on = (strcmp(res->on_off, "on") == 0) ? 1 : 0;
9549 
9550 	if (port_id_is_invalid(res->port_id, ENABLED_WARN))
9551 		return;
9552 
9553 #ifdef RTE_NET_IXGBE
9554 	if (ret == -ENOTSUP)
9555 		ret = rte_pmd_ixgbe_set_tx_loopback(res->port_id, is_on);
9556 #endif
9557 #ifdef RTE_NET_I40E
9558 	if (ret == -ENOTSUP)
9559 		ret = rte_pmd_i40e_set_tx_loopback(res->port_id, is_on);
9560 #endif
9561 #ifdef RTE_NET_BNXT
9562 	if (ret == -ENOTSUP)
9563 		ret = rte_pmd_bnxt_set_tx_loopback(res->port_id, is_on);
9564 #endif
9565 #if defined RTE_BUS_DPAA && defined RTE_NET_DPAA
9566 	if (ret == -ENOTSUP)
9567 		ret = rte_pmd_dpaa_set_tx_loopback(res->port_id, is_on);
9568 #endif
9569 
9570 	switch (ret) {
9571 	case 0:
9572 		break;
9573 	case -EINVAL:
9574 		fprintf(stderr, "invalid is_on %d\n", is_on);
9575 		break;
9576 	case -ENODEV:
9577 		fprintf(stderr, "invalid port_id %d\n", res->port_id);
9578 		break;
9579 	case -ENOTSUP:
9580 		fprintf(stderr, "function not implemented\n");
9581 		break;
9582 	default:
9583 		fprintf(stderr, "programming error: (%s)\n", strerror(-ret));
9584 	}
9585 }
9586 
9587 static cmdline_parse_inst_t cmd_set_tx_loopback = {
9588 	.f = cmd_set_tx_loopback_parsed,
9589 	.data = NULL,
9590 	.help_str = "set tx loopback <port_id> on|off",
9591 	.tokens = {
9592 		(void *)&cmd_tx_loopback_set,
9593 		(void *)&cmd_tx_loopback_tx,
9594 		(void *)&cmd_tx_loopback_loopback,
9595 		(void *)&cmd_tx_loopback_port_id,
9596 		(void *)&cmd_tx_loopback_on_off,
9597 		NULL,
9598 	},
9599 };
9600 
9601 /* all queues drop enable configuration */
9602 
9603 /* Common result structure for all queues drop enable */
9604 struct cmd_all_queues_drop_en_result {
9605 	cmdline_fixed_string_t set;
9606 	cmdline_fixed_string_t all;
9607 	cmdline_fixed_string_t queues;
9608 	cmdline_fixed_string_t drop;
9609 	portid_t port_id;
9610 	cmdline_fixed_string_t on_off;
9611 };
9612 
9613 /* Common CLI fields for tx loopback enable disable */
9614 static cmdline_parse_token_string_t cmd_all_queues_drop_en_set =
9615 	TOKEN_STRING_INITIALIZER
9616 		(struct cmd_all_queues_drop_en_result,
9617 		 set, "set");
9618 static cmdline_parse_token_string_t cmd_all_queues_drop_en_all =
9619 	TOKEN_STRING_INITIALIZER
9620 		(struct cmd_all_queues_drop_en_result,
9621 		 all, "all");
9622 static cmdline_parse_token_string_t cmd_all_queues_drop_en_queues =
9623 	TOKEN_STRING_INITIALIZER
9624 		(struct cmd_all_queues_drop_en_result,
9625 		 queues, "queues");
9626 static cmdline_parse_token_string_t cmd_all_queues_drop_en_drop =
9627 	TOKEN_STRING_INITIALIZER
9628 		(struct cmd_all_queues_drop_en_result,
9629 		 drop, "drop");
9630 static cmdline_parse_token_num_t cmd_all_queues_drop_en_port_id =
9631 	TOKEN_NUM_INITIALIZER
9632 		(struct cmd_all_queues_drop_en_result,
9633 		 port_id, RTE_UINT16);
9634 static cmdline_parse_token_string_t cmd_all_queues_drop_en_on_off =
9635 	TOKEN_STRING_INITIALIZER
9636 		(struct cmd_all_queues_drop_en_result,
9637 		 on_off, "on#off");
9638 
9639 static void
9640 cmd_set_all_queues_drop_en_parsed(
9641 	void *parsed_result,
9642 	__rte_unused struct cmdline *cl,
9643 	__rte_unused void *data)
9644 {
9645 	struct cmd_all_queues_drop_en_result *res = parsed_result;
9646 	int ret = -ENOTSUP;
9647 	int is_on = (strcmp(res->on_off, "on") == 0) ? 1 : 0;
9648 
9649 	if (port_id_is_invalid(res->port_id, ENABLED_WARN))
9650 		return;
9651 
9652 #ifdef RTE_NET_IXGBE
9653 	if (ret == -ENOTSUP)
9654 		ret = rte_pmd_ixgbe_set_all_queues_drop_en(res->port_id, is_on);
9655 #endif
9656 #ifdef RTE_NET_BNXT
9657 	if (ret == -ENOTSUP)
9658 		ret = rte_pmd_bnxt_set_all_queues_drop_en(res->port_id, is_on);
9659 #endif
9660 	switch (ret) {
9661 	case 0:
9662 		break;
9663 	case -EINVAL:
9664 		fprintf(stderr, "invalid is_on %d\n", is_on);
9665 		break;
9666 	case -ENODEV:
9667 		fprintf(stderr, "invalid port_id %d\n", res->port_id);
9668 		break;
9669 	case -ENOTSUP:
9670 		fprintf(stderr, "function not implemented\n");
9671 		break;
9672 	default:
9673 		fprintf(stderr, "programming error: (%s)\n", strerror(-ret));
9674 	}
9675 }
9676 
9677 static cmdline_parse_inst_t cmd_set_all_queues_drop_en = {
9678 	.f = cmd_set_all_queues_drop_en_parsed,
9679 	.data = NULL,
9680 	.help_str = "set all queues drop <port_id> on|off",
9681 	.tokens = {
9682 		(void *)&cmd_all_queues_drop_en_set,
9683 		(void *)&cmd_all_queues_drop_en_all,
9684 		(void *)&cmd_all_queues_drop_en_queues,
9685 		(void *)&cmd_all_queues_drop_en_drop,
9686 		(void *)&cmd_all_queues_drop_en_port_id,
9687 		(void *)&cmd_all_queues_drop_en_on_off,
9688 		NULL,
9689 	},
9690 };
9691 
9692 /* vf mac address configuration */
9693 
9694 /* Common result structure for vf mac address */
9695 struct cmd_set_vf_mac_addr_result {
9696 	cmdline_fixed_string_t set;
9697 	cmdline_fixed_string_t vf;
9698 	cmdline_fixed_string_t mac;
9699 	cmdline_fixed_string_t addr;
9700 	portid_t port_id;
9701 	uint16_t vf_id;
9702 	struct rte_ether_addr mac_addr;
9703 
9704 };
9705 
9706 /* Common CLI fields for vf split drop enable disable */
9707 static cmdline_parse_token_string_t cmd_set_vf_mac_addr_set =
9708 	TOKEN_STRING_INITIALIZER
9709 		(struct cmd_set_vf_mac_addr_result,
9710 		 set, "set");
9711 static cmdline_parse_token_string_t cmd_set_vf_mac_addr_vf =
9712 	TOKEN_STRING_INITIALIZER
9713 		(struct cmd_set_vf_mac_addr_result,
9714 		 vf, "vf");
9715 static cmdline_parse_token_string_t cmd_set_vf_mac_addr_mac =
9716 	TOKEN_STRING_INITIALIZER
9717 		(struct cmd_set_vf_mac_addr_result,
9718 		 mac, "mac");
9719 static cmdline_parse_token_string_t cmd_set_vf_mac_addr_addr =
9720 	TOKEN_STRING_INITIALIZER
9721 		(struct cmd_set_vf_mac_addr_result,
9722 		 addr, "addr");
9723 static cmdline_parse_token_num_t cmd_set_vf_mac_addr_port_id =
9724 	TOKEN_NUM_INITIALIZER
9725 		(struct cmd_set_vf_mac_addr_result,
9726 		 port_id, RTE_UINT16);
9727 static cmdline_parse_token_num_t cmd_set_vf_mac_addr_vf_id =
9728 	TOKEN_NUM_INITIALIZER
9729 		(struct cmd_set_vf_mac_addr_result,
9730 		 vf_id, RTE_UINT16);
9731 static cmdline_parse_token_etheraddr_t cmd_set_vf_mac_addr_mac_addr =
9732 	TOKEN_ETHERADDR_INITIALIZER(struct cmd_set_vf_mac_addr_result,
9733 		 mac_addr);
9734 
9735 static void
9736 cmd_set_vf_mac_addr_parsed(
9737 	void *parsed_result,
9738 	__rte_unused struct cmdline *cl,
9739 	__rte_unused void *data)
9740 {
9741 	struct cmd_set_vf_mac_addr_result *res = parsed_result;
9742 	int ret = -ENOTSUP;
9743 
9744 	if (port_id_is_invalid(res->port_id, ENABLED_WARN))
9745 		return;
9746 
9747 #ifdef RTE_NET_IXGBE
9748 	if (ret == -ENOTSUP)
9749 		ret = rte_pmd_ixgbe_set_vf_mac_addr(res->port_id, res->vf_id,
9750 				&res->mac_addr);
9751 #endif
9752 #ifdef RTE_NET_I40E
9753 	if (ret == -ENOTSUP)
9754 		ret = rte_pmd_i40e_set_vf_mac_addr(res->port_id, res->vf_id,
9755 				&res->mac_addr);
9756 #endif
9757 #ifdef RTE_NET_BNXT
9758 	if (ret == -ENOTSUP)
9759 		ret = rte_pmd_bnxt_set_vf_mac_addr(res->port_id, res->vf_id,
9760 				&res->mac_addr);
9761 #endif
9762 
9763 	switch (ret) {
9764 	case 0:
9765 		break;
9766 	case -EINVAL:
9767 		fprintf(stderr, "invalid vf_id %d or mac_addr\n", res->vf_id);
9768 		break;
9769 	case -ENODEV:
9770 		fprintf(stderr, "invalid port_id %d\n", res->port_id);
9771 		break;
9772 	case -ENOTSUP:
9773 		fprintf(stderr, "function not implemented\n");
9774 		break;
9775 	default:
9776 		fprintf(stderr, "programming error: (%s)\n", strerror(-ret));
9777 	}
9778 }
9779 
9780 static cmdline_parse_inst_t cmd_set_vf_mac_addr = {
9781 	.f = cmd_set_vf_mac_addr_parsed,
9782 	.data = NULL,
9783 	.help_str = "set vf mac addr <port_id> <vf_id> <mac_addr>",
9784 	.tokens = {
9785 		(void *)&cmd_set_vf_mac_addr_set,
9786 		(void *)&cmd_set_vf_mac_addr_vf,
9787 		(void *)&cmd_set_vf_mac_addr_mac,
9788 		(void *)&cmd_set_vf_mac_addr_addr,
9789 		(void *)&cmd_set_vf_mac_addr_port_id,
9790 		(void *)&cmd_set_vf_mac_addr_vf_id,
9791 		(void *)&cmd_set_vf_mac_addr_mac_addr,
9792 		NULL,
9793 	},
9794 };
9795 
9796 /** Set VXLAN encapsulation details */
9797 struct cmd_set_vxlan_result {
9798 	cmdline_fixed_string_t set;
9799 	cmdline_fixed_string_t vxlan;
9800 	cmdline_fixed_string_t pos_token;
9801 	cmdline_fixed_string_t ip_version;
9802 	uint32_t vlan_present:1;
9803 	uint32_t vni;
9804 	uint16_t udp_src;
9805 	uint16_t udp_dst;
9806 	cmdline_ipaddr_t ip_src;
9807 	cmdline_ipaddr_t ip_dst;
9808 	uint16_t tci;
9809 	uint8_t tos;
9810 	uint8_t ttl;
9811 	struct rte_ether_addr eth_src;
9812 	struct rte_ether_addr eth_dst;
9813 };
9814 
9815 static cmdline_parse_token_string_t cmd_set_vxlan_set =
9816 	TOKEN_STRING_INITIALIZER(struct cmd_set_vxlan_result, set, "set");
9817 static cmdline_parse_token_string_t cmd_set_vxlan_vxlan =
9818 	TOKEN_STRING_INITIALIZER(struct cmd_set_vxlan_result, vxlan, "vxlan");
9819 static cmdline_parse_token_string_t cmd_set_vxlan_vxlan_tos_ttl =
9820 	TOKEN_STRING_INITIALIZER(struct cmd_set_vxlan_result, vxlan,
9821 				 "vxlan-tos-ttl");
9822 static cmdline_parse_token_string_t cmd_set_vxlan_vxlan_with_vlan =
9823 	TOKEN_STRING_INITIALIZER(struct cmd_set_vxlan_result, vxlan,
9824 				 "vxlan-with-vlan");
9825 static cmdline_parse_token_string_t cmd_set_vxlan_ip_version =
9826 	TOKEN_STRING_INITIALIZER(struct cmd_set_vxlan_result, pos_token,
9827 				 "ip-version");
9828 static cmdline_parse_token_string_t cmd_set_vxlan_ip_version_value =
9829 	TOKEN_STRING_INITIALIZER(struct cmd_set_vxlan_result, ip_version,
9830 				 "ipv4#ipv6");
9831 static cmdline_parse_token_string_t cmd_set_vxlan_vni =
9832 	TOKEN_STRING_INITIALIZER(struct cmd_set_vxlan_result, pos_token,
9833 				 "vni");
9834 static cmdline_parse_token_num_t cmd_set_vxlan_vni_value =
9835 	TOKEN_NUM_INITIALIZER(struct cmd_set_vxlan_result, vni, RTE_UINT32);
9836 static cmdline_parse_token_string_t cmd_set_vxlan_udp_src =
9837 	TOKEN_STRING_INITIALIZER(struct cmd_set_vxlan_result, pos_token,
9838 				 "udp-src");
9839 static cmdline_parse_token_num_t cmd_set_vxlan_udp_src_value =
9840 	TOKEN_NUM_INITIALIZER(struct cmd_set_vxlan_result, udp_src, RTE_UINT16);
9841 static cmdline_parse_token_string_t cmd_set_vxlan_udp_dst =
9842 	TOKEN_STRING_INITIALIZER(struct cmd_set_vxlan_result, pos_token,
9843 				 "udp-dst");
9844 static cmdline_parse_token_num_t cmd_set_vxlan_udp_dst_value =
9845 	TOKEN_NUM_INITIALIZER(struct cmd_set_vxlan_result, udp_dst, RTE_UINT16);
9846 static cmdline_parse_token_string_t cmd_set_vxlan_ip_tos =
9847 	TOKEN_STRING_INITIALIZER(struct cmd_set_vxlan_result, pos_token,
9848 				 "ip-tos");
9849 static cmdline_parse_token_num_t cmd_set_vxlan_ip_tos_value =
9850 	TOKEN_NUM_INITIALIZER(struct cmd_set_vxlan_result, tos, RTE_UINT8);
9851 static cmdline_parse_token_string_t cmd_set_vxlan_ip_ttl =
9852 	TOKEN_STRING_INITIALIZER(struct cmd_set_vxlan_result, pos_token,
9853 				 "ip-ttl");
9854 static cmdline_parse_token_num_t cmd_set_vxlan_ip_ttl_value =
9855 	TOKEN_NUM_INITIALIZER(struct cmd_set_vxlan_result, ttl, RTE_UINT8);
9856 static cmdline_parse_token_string_t cmd_set_vxlan_ip_src =
9857 	TOKEN_STRING_INITIALIZER(struct cmd_set_vxlan_result, pos_token,
9858 				 "ip-src");
9859 static cmdline_parse_token_ipaddr_t cmd_set_vxlan_ip_src_value =
9860 	TOKEN_IPADDR_INITIALIZER(struct cmd_set_vxlan_result, ip_src);
9861 static cmdline_parse_token_string_t cmd_set_vxlan_ip_dst =
9862 	TOKEN_STRING_INITIALIZER(struct cmd_set_vxlan_result, pos_token,
9863 				 "ip-dst");
9864 static cmdline_parse_token_ipaddr_t cmd_set_vxlan_ip_dst_value =
9865 	TOKEN_IPADDR_INITIALIZER(struct cmd_set_vxlan_result, ip_dst);
9866 static cmdline_parse_token_string_t cmd_set_vxlan_vlan =
9867 	TOKEN_STRING_INITIALIZER(struct cmd_set_vxlan_result, pos_token,
9868 				 "vlan-tci");
9869 static cmdline_parse_token_num_t cmd_set_vxlan_vlan_value =
9870 	TOKEN_NUM_INITIALIZER(struct cmd_set_vxlan_result, tci, RTE_UINT16);
9871 static cmdline_parse_token_string_t cmd_set_vxlan_eth_src =
9872 	TOKEN_STRING_INITIALIZER(struct cmd_set_vxlan_result, pos_token,
9873 				 "eth-src");
9874 static cmdline_parse_token_etheraddr_t cmd_set_vxlan_eth_src_value =
9875 	TOKEN_ETHERADDR_INITIALIZER(struct cmd_set_vxlan_result, eth_src);
9876 static cmdline_parse_token_string_t cmd_set_vxlan_eth_dst =
9877 	TOKEN_STRING_INITIALIZER(struct cmd_set_vxlan_result, pos_token,
9878 				 "eth-dst");
9879 static cmdline_parse_token_etheraddr_t cmd_set_vxlan_eth_dst_value =
9880 	TOKEN_ETHERADDR_INITIALIZER(struct cmd_set_vxlan_result, eth_dst);
9881 
9882 static void cmd_set_vxlan_parsed(void *parsed_result,
9883 	__rte_unused struct cmdline *cl,
9884 	__rte_unused void *data)
9885 {
9886 	struct cmd_set_vxlan_result *res = parsed_result;
9887 	union {
9888 		uint32_t vxlan_id;
9889 		uint8_t vni[4];
9890 	} id = {
9891 		.vxlan_id = rte_cpu_to_be_32(res->vni) & RTE_BE32(0x00ffffff),
9892 	};
9893 
9894 	vxlan_encap_conf.select_tos_ttl = 0;
9895 	if (strcmp(res->vxlan, "vxlan") == 0)
9896 		vxlan_encap_conf.select_vlan = 0;
9897 	else if (strcmp(res->vxlan, "vxlan-with-vlan") == 0)
9898 		vxlan_encap_conf.select_vlan = 1;
9899 	else if (strcmp(res->vxlan, "vxlan-tos-ttl") == 0) {
9900 		vxlan_encap_conf.select_vlan = 0;
9901 		vxlan_encap_conf.select_tos_ttl = 1;
9902 	}
9903 	if (strcmp(res->ip_version, "ipv4") == 0)
9904 		vxlan_encap_conf.select_ipv4 = 1;
9905 	else if (strcmp(res->ip_version, "ipv6") == 0)
9906 		vxlan_encap_conf.select_ipv4 = 0;
9907 	else
9908 		return;
9909 	rte_memcpy(vxlan_encap_conf.vni, &id.vni[1], 3);
9910 	vxlan_encap_conf.udp_src = rte_cpu_to_be_16(res->udp_src);
9911 	vxlan_encap_conf.udp_dst = rte_cpu_to_be_16(res->udp_dst);
9912 	vxlan_encap_conf.ip_tos = res->tos;
9913 	vxlan_encap_conf.ip_ttl = res->ttl;
9914 	if (vxlan_encap_conf.select_ipv4) {
9915 		IPV4_ADDR_TO_UINT(res->ip_src, vxlan_encap_conf.ipv4_src);
9916 		IPV4_ADDR_TO_UINT(res->ip_dst, vxlan_encap_conf.ipv4_dst);
9917 	} else {
9918 		IPV6_ADDR_TO_ARRAY(res->ip_src, vxlan_encap_conf.ipv6_src);
9919 		IPV6_ADDR_TO_ARRAY(res->ip_dst, vxlan_encap_conf.ipv6_dst);
9920 	}
9921 	if (vxlan_encap_conf.select_vlan)
9922 		vxlan_encap_conf.vlan_tci = rte_cpu_to_be_16(res->tci);
9923 	rte_memcpy(vxlan_encap_conf.eth_src, res->eth_src.addr_bytes,
9924 		   RTE_ETHER_ADDR_LEN);
9925 	rte_memcpy(vxlan_encap_conf.eth_dst, res->eth_dst.addr_bytes,
9926 		   RTE_ETHER_ADDR_LEN);
9927 }
9928 
9929 static cmdline_parse_inst_t cmd_set_vxlan = {
9930 	.f = cmd_set_vxlan_parsed,
9931 	.data = NULL,
9932 	.help_str = "set vxlan ip-version ipv4|ipv6 vni <vni> udp-src"
9933 		" <udp-src> udp-dst <udp-dst> ip-src <ip-src> ip-dst <ip-dst>"
9934 		" eth-src <eth-src> eth-dst <eth-dst>",
9935 	.tokens = {
9936 		(void *)&cmd_set_vxlan_set,
9937 		(void *)&cmd_set_vxlan_vxlan,
9938 		(void *)&cmd_set_vxlan_ip_version,
9939 		(void *)&cmd_set_vxlan_ip_version_value,
9940 		(void *)&cmd_set_vxlan_vni,
9941 		(void *)&cmd_set_vxlan_vni_value,
9942 		(void *)&cmd_set_vxlan_udp_src,
9943 		(void *)&cmd_set_vxlan_udp_src_value,
9944 		(void *)&cmd_set_vxlan_udp_dst,
9945 		(void *)&cmd_set_vxlan_udp_dst_value,
9946 		(void *)&cmd_set_vxlan_ip_src,
9947 		(void *)&cmd_set_vxlan_ip_src_value,
9948 		(void *)&cmd_set_vxlan_ip_dst,
9949 		(void *)&cmd_set_vxlan_ip_dst_value,
9950 		(void *)&cmd_set_vxlan_eth_src,
9951 		(void *)&cmd_set_vxlan_eth_src_value,
9952 		(void *)&cmd_set_vxlan_eth_dst,
9953 		(void *)&cmd_set_vxlan_eth_dst_value,
9954 		NULL,
9955 	},
9956 };
9957 
9958 static cmdline_parse_inst_t cmd_set_vxlan_tos_ttl = {
9959 	.f = cmd_set_vxlan_parsed,
9960 	.data = NULL,
9961 	.help_str = "set vxlan-tos-ttl ip-version ipv4|ipv6 vni <vni> udp-src"
9962 		" <udp-src> udp-dst <udp-dst> ip-tos <ip-tos> ip-ttl <ip-ttl>"
9963 		" ip-src <ip-src> ip-dst <ip-dst> eth-src <eth-src>"
9964 		" eth-dst <eth-dst>",
9965 	.tokens = {
9966 		(void *)&cmd_set_vxlan_set,
9967 		(void *)&cmd_set_vxlan_vxlan_tos_ttl,
9968 		(void *)&cmd_set_vxlan_ip_version,
9969 		(void *)&cmd_set_vxlan_ip_version_value,
9970 		(void *)&cmd_set_vxlan_vni,
9971 		(void *)&cmd_set_vxlan_vni_value,
9972 		(void *)&cmd_set_vxlan_udp_src,
9973 		(void *)&cmd_set_vxlan_udp_src_value,
9974 		(void *)&cmd_set_vxlan_udp_dst,
9975 		(void *)&cmd_set_vxlan_udp_dst_value,
9976 		(void *)&cmd_set_vxlan_ip_tos,
9977 		(void *)&cmd_set_vxlan_ip_tos_value,
9978 		(void *)&cmd_set_vxlan_ip_ttl,
9979 		(void *)&cmd_set_vxlan_ip_ttl_value,
9980 		(void *)&cmd_set_vxlan_ip_src,
9981 		(void *)&cmd_set_vxlan_ip_src_value,
9982 		(void *)&cmd_set_vxlan_ip_dst,
9983 		(void *)&cmd_set_vxlan_ip_dst_value,
9984 		(void *)&cmd_set_vxlan_eth_src,
9985 		(void *)&cmd_set_vxlan_eth_src_value,
9986 		(void *)&cmd_set_vxlan_eth_dst,
9987 		(void *)&cmd_set_vxlan_eth_dst_value,
9988 		NULL,
9989 	},
9990 };
9991 
9992 static cmdline_parse_inst_t cmd_set_vxlan_with_vlan = {
9993 	.f = cmd_set_vxlan_parsed,
9994 	.data = NULL,
9995 	.help_str = "set vxlan-with-vlan ip-version ipv4|ipv6 vni <vni>"
9996 		" udp-src <udp-src> udp-dst <udp-dst> ip-src <ip-src> ip-dst"
9997 		" <ip-dst> vlan-tci <vlan-tci> eth-src <eth-src> eth-dst"
9998 		" <eth-dst>",
9999 	.tokens = {
10000 		(void *)&cmd_set_vxlan_set,
10001 		(void *)&cmd_set_vxlan_vxlan_with_vlan,
10002 		(void *)&cmd_set_vxlan_ip_version,
10003 		(void *)&cmd_set_vxlan_ip_version_value,
10004 		(void *)&cmd_set_vxlan_vni,
10005 		(void *)&cmd_set_vxlan_vni_value,
10006 		(void *)&cmd_set_vxlan_udp_src,
10007 		(void *)&cmd_set_vxlan_udp_src_value,
10008 		(void *)&cmd_set_vxlan_udp_dst,
10009 		(void *)&cmd_set_vxlan_udp_dst_value,
10010 		(void *)&cmd_set_vxlan_ip_src,
10011 		(void *)&cmd_set_vxlan_ip_src_value,
10012 		(void *)&cmd_set_vxlan_ip_dst,
10013 		(void *)&cmd_set_vxlan_ip_dst_value,
10014 		(void *)&cmd_set_vxlan_vlan,
10015 		(void *)&cmd_set_vxlan_vlan_value,
10016 		(void *)&cmd_set_vxlan_eth_src,
10017 		(void *)&cmd_set_vxlan_eth_src_value,
10018 		(void *)&cmd_set_vxlan_eth_dst,
10019 		(void *)&cmd_set_vxlan_eth_dst_value,
10020 		NULL,
10021 	},
10022 };
10023 
10024 /** Set NVGRE encapsulation details */
10025 struct cmd_set_nvgre_result {
10026 	cmdline_fixed_string_t set;
10027 	cmdline_fixed_string_t nvgre;
10028 	cmdline_fixed_string_t pos_token;
10029 	cmdline_fixed_string_t ip_version;
10030 	uint32_t tni;
10031 	cmdline_ipaddr_t ip_src;
10032 	cmdline_ipaddr_t ip_dst;
10033 	uint16_t tci;
10034 	struct rte_ether_addr eth_src;
10035 	struct rte_ether_addr eth_dst;
10036 };
10037 
10038 static cmdline_parse_token_string_t cmd_set_nvgre_set =
10039 	TOKEN_STRING_INITIALIZER(struct cmd_set_nvgre_result, set, "set");
10040 static cmdline_parse_token_string_t cmd_set_nvgre_nvgre =
10041 	TOKEN_STRING_INITIALIZER(struct cmd_set_nvgre_result, nvgre, "nvgre");
10042 static cmdline_parse_token_string_t cmd_set_nvgre_nvgre_with_vlan =
10043 	TOKEN_STRING_INITIALIZER(struct cmd_set_nvgre_result, nvgre,
10044 				 "nvgre-with-vlan");
10045 static cmdline_parse_token_string_t cmd_set_nvgre_ip_version =
10046 	TOKEN_STRING_INITIALIZER(struct cmd_set_nvgre_result, pos_token,
10047 				 "ip-version");
10048 static cmdline_parse_token_string_t cmd_set_nvgre_ip_version_value =
10049 	TOKEN_STRING_INITIALIZER(struct cmd_set_nvgre_result, ip_version,
10050 				 "ipv4#ipv6");
10051 static cmdline_parse_token_string_t cmd_set_nvgre_tni =
10052 	TOKEN_STRING_INITIALIZER(struct cmd_set_nvgre_result, pos_token,
10053 				 "tni");
10054 static cmdline_parse_token_num_t cmd_set_nvgre_tni_value =
10055 	TOKEN_NUM_INITIALIZER(struct cmd_set_nvgre_result, tni, RTE_UINT32);
10056 static cmdline_parse_token_string_t cmd_set_nvgre_ip_src =
10057 	TOKEN_STRING_INITIALIZER(struct cmd_set_nvgre_result, pos_token,
10058 				 "ip-src");
10059 static cmdline_parse_token_num_t cmd_set_nvgre_ip_src_value =
10060 	TOKEN_IPADDR_INITIALIZER(struct cmd_set_nvgre_result, ip_src);
10061 static cmdline_parse_token_string_t cmd_set_nvgre_ip_dst =
10062 	TOKEN_STRING_INITIALIZER(struct cmd_set_nvgre_result, pos_token,
10063 				 "ip-dst");
10064 static cmdline_parse_token_ipaddr_t cmd_set_nvgre_ip_dst_value =
10065 	TOKEN_IPADDR_INITIALIZER(struct cmd_set_nvgre_result, ip_dst);
10066 static cmdline_parse_token_string_t cmd_set_nvgre_vlan =
10067 	TOKEN_STRING_INITIALIZER(struct cmd_set_nvgre_result, pos_token,
10068 				 "vlan-tci");
10069 static cmdline_parse_token_num_t cmd_set_nvgre_vlan_value =
10070 	TOKEN_NUM_INITIALIZER(struct cmd_set_nvgre_result, tci, RTE_UINT16);
10071 static cmdline_parse_token_string_t cmd_set_nvgre_eth_src =
10072 	TOKEN_STRING_INITIALIZER(struct cmd_set_nvgre_result, pos_token,
10073 				 "eth-src");
10074 static cmdline_parse_token_etheraddr_t cmd_set_nvgre_eth_src_value =
10075 	TOKEN_ETHERADDR_INITIALIZER(struct cmd_set_nvgre_result, eth_src);
10076 static cmdline_parse_token_string_t cmd_set_nvgre_eth_dst =
10077 	TOKEN_STRING_INITIALIZER(struct cmd_set_nvgre_result, pos_token,
10078 				 "eth-dst");
10079 static cmdline_parse_token_etheraddr_t cmd_set_nvgre_eth_dst_value =
10080 	TOKEN_ETHERADDR_INITIALIZER(struct cmd_set_nvgre_result, eth_dst);
10081 
10082 static void cmd_set_nvgre_parsed(void *parsed_result,
10083 	__rte_unused struct cmdline *cl,
10084 	__rte_unused void *data)
10085 {
10086 	struct cmd_set_nvgre_result *res = parsed_result;
10087 	union {
10088 		uint32_t nvgre_tni;
10089 		uint8_t tni[4];
10090 	} id = {
10091 		.nvgre_tni = rte_cpu_to_be_32(res->tni) & RTE_BE32(0x00ffffff),
10092 	};
10093 
10094 	if (strcmp(res->nvgre, "nvgre") == 0)
10095 		nvgre_encap_conf.select_vlan = 0;
10096 	else if (strcmp(res->nvgre, "nvgre-with-vlan") == 0)
10097 		nvgre_encap_conf.select_vlan = 1;
10098 	if (strcmp(res->ip_version, "ipv4") == 0)
10099 		nvgre_encap_conf.select_ipv4 = 1;
10100 	else if (strcmp(res->ip_version, "ipv6") == 0)
10101 		nvgre_encap_conf.select_ipv4 = 0;
10102 	else
10103 		return;
10104 	rte_memcpy(nvgre_encap_conf.tni, &id.tni[1], 3);
10105 	if (nvgre_encap_conf.select_ipv4) {
10106 		IPV4_ADDR_TO_UINT(res->ip_src, nvgre_encap_conf.ipv4_src);
10107 		IPV4_ADDR_TO_UINT(res->ip_dst, nvgre_encap_conf.ipv4_dst);
10108 	} else {
10109 		IPV6_ADDR_TO_ARRAY(res->ip_src, nvgre_encap_conf.ipv6_src);
10110 		IPV6_ADDR_TO_ARRAY(res->ip_dst, nvgre_encap_conf.ipv6_dst);
10111 	}
10112 	if (nvgre_encap_conf.select_vlan)
10113 		nvgre_encap_conf.vlan_tci = rte_cpu_to_be_16(res->tci);
10114 	rte_memcpy(nvgre_encap_conf.eth_src, res->eth_src.addr_bytes,
10115 		   RTE_ETHER_ADDR_LEN);
10116 	rte_memcpy(nvgre_encap_conf.eth_dst, res->eth_dst.addr_bytes,
10117 		   RTE_ETHER_ADDR_LEN);
10118 }
10119 
10120 static cmdline_parse_inst_t cmd_set_nvgre = {
10121 	.f = cmd_set_nvgre_parsed,
10122 	.data = NULL,
10123 	.help_str = "set nvgre ip-version <ipv4|ipv6> tni <tni> ip-src"
10124 		" <ip-src> ip-dst <ip-dst> eth-src <eth-src>"
10125 		" eth-dst <eth-dst>",
10126 	.tokens = {
10127 		(void *)&cmd_set_nvgre_set,
10128 		(void *)&cmd_set_nvgre_nvgre,
10129 		(void *)&cmd_set_nvgre_ip_version,
10130 		(void *)&cmd_set_nvgre_ip_version_value,
10131 		(void *)&cmd_set_nvgre_tni,
10132 		(void *)&cmd_set_nvgre_tni_value,
10133 		(void *)&cmd_set_nvgre_ip_src,
10134 		(void *)&cmd_set_nvgre_ip_src_value,
10135 		(void *)&cmd_set_nvgre_ip_dst,
10136 		(void *)&cmd_set_nvgre_ip_dst_value,
10137 		(void *)&cmd_set_nvgre_eth_src,
10138 		(void *)&cmd_set_nvgre_eth_src_value,
10139 		(void *)&cmd_set_nvgre_eth_dst,
10140 		(void *)&cmd_set_nvgre_eth_dst_value,
10141 		NULL,
10142 	},
10143 };
10144 
10145 static cmdline_parse_inst_t cmd_set_nvgre_with_vlan = {
10146 	.f = cmd_set_nvgre_parsed,
10147 	.data = NULL,
10148 	.help_str = "set nvgre-with-vlan ip-version <ipv4|ipv6> tni <tni>"
10149 		" ip-src <ip-src> ip-dst <ip-dst> vlan-tci <vlan-tci>"
10150 		" eth-src <eth-src> eth-dst <eth-dst>",
10151 	.tokens = {
10152 		(void *)&cmd_set_nvgre_set,
10153 		(void *)&cmd_set_nvgre_nvgre_with_vlan,
10154 		(void *)&cmd_set_nvgre_ip_version,
10155 		(void *)&cmd_set_nvgre_ip_version_value,
10156 		(void *)&cmd_set_nvgre_tni,
10157 		(void *)&cmd_set_nvgre_tni_value,
10158 		(void *)&cmd_set_nvgre_ip_src,
10159 		(void *)&cmd_set_nvgre_ip_src_value,
10160 		(void *)&cmd_set_nvgre_ip_dst,
10161 		(void *)&cmd_set_nvgre_ip_dst_value,
10162 		(void *)&cmd_set_nvgre_vlan,
10163 		(void *)&cmd_set_nvgre_vlan_value,
10164 		(void *)&cmd_set_nvgre_eth_src,
10165 		(void *)&cmd_set_nvgre_eth_src_value,
10166 		(void *)&cmd_set_nvgre_eth_dst,
10167 		(void *)&cmd_set_nvgre_eth_dst_value,
10168 		NULL,
10169 	},
10170 };
10171 
10172 /** Set L2 encapsulation details */
10173 struct cmd_set_l2_encap_result {
10174 	cmdline_fixed_string_t set;
10175 	cmdline_fixed_string_t l2_encap;
10176 	cmdline_fixed_string_t pos_token;
10177 	cmdline_fixed_string_t ip_version;
10178 	uint32_t vlan_present:1;
10179 	uint16_t tci;
10180 	struct rte_ether_addr eth_src;
10181 	struct rte_ether_addr eth_dst;
10182 };
10183 
10184 static cmdline_parse_token_string_t cmd_set_l2_encap_set =
10185 	TOKEN_STRING_INITIALIZER(struct cmd_set_l2_encap_result, set, "set");
10186 static cmdline_parse_token_string_t cmd_set_l2_encap_l2_encap =
10187 	TOKEN_STRING_INITIALIZER(struct cmd_set_l2_encap_result, l2_encap, "l2_encap");
10188 static cmdline_parse_token_string_t cmd_set_l2_encap_l2_encap_with_vlan =
10189 	TOKEN_STRING_INITIALIZER(struct cmd_set_l2_encap_result, l2_encap,
10190 				 "l2_encap-with-vlan");
10191 static cmdline_parse_token_string_t cmd_set_l2_encap_ip_version =
10192 	TOKEN_STRING_INITIALIZER(struct cmd_set_l2_encap_result, pos_token,
10193 				 "ip-version");
10194 static cmdline_parse_token_string_t cmd_set_l2_encap_ip_version_value =
10195 	TOKEN_STRING_INITIALIZER(struct cmd_set_l2_encap_result, ip_version,
10196 				 "ipv4#ipv6");
10197 static cmdline_parse_token_string_t cmd_set_l2_encap_vlan =
10198 	TOKEN_STRING_INITIALIZER(struct cmd_set_l2_encap_result, pos_token,
10199 				 "vlan-tci");
10200 static cmdline_parse_token_num_t cmd_set_l2_encap_vlan_value =
10201 	TOKEN_NUM_INITIALIZER(struct cmd_set_l2_encap_result, tci, RTE_UINT16);
10202 static cmdline_parse_token_string_t cmd_set_l2_encap_eth_src =
10203 	TOKEN_STRING_INITIALIZER(struct cmd_set_l2_encap_result, pos_token,
10204 				 "eth-src");
10205 static cmdline_parse_token_etheraddr_t cmd_set_l2_encap_eth_src_value =
10206 	TOKEN_ETHERADDR_INITIALIZER(struct cmd_set_l2_encap_result, eth_src);
10207 static cmdline_parse_token_string_t cmd_set_l2_encap_eth_dst =
10208 	TOKEN_STRING_INITIALIZER(struct cmd_set_l2_encap_result, pos_token,
10209 				 "eth-dst");
10210 static cmdline_parse_token_etheraddr_t cmd_set_l2_encap_eth_dst_value =
10211 	TOKEN_ETHERADDR_INITIALIZER(struct cmd_set_l2_encap_result, eth_dst);
10212 
10213 static void cmd_set_l2_encap_parsed(void *parsed_result,
10214 	__rte_unused struct cmdline *cl,
10215 	__rte_unused void *data)
10216 {
10217 	struct cmd_set_l2_encap_result *res = parsed_result;
10218 
10219 	if (strcmp(res->l2_encap, "l2_encap") == 0)
10220 		l2_encap_conf.select_vlan = 0;
10221 	else if (strcmp(res->l2_encap, "l2_encap-with-vlan") == 0)
10222 		l2_encap_conf.select_vlan = 1;
10223 	if (strcmp(res->ip_version, "ipv4") == 0)
10224 		l2_encap_conf.select_ipv4 = 1;
10225 	else if (strcmp(res->ip_version, "ipv6") == 0)
10226 		l2_encap_conf.select_ipv4 = 0;
10227 	else
10228 		return;
10229 	if (l2_encap_conf.select_vlan)
10230 		l2_encap_conf.vlan_tci = rte_cpu_to_be_16(res->tci);
10231 	rte_memcpy(l2_encap_conf.eth_src, res->eth_src.addr_bytes,
10232 		   RTE_ETHER_ADDR_LEN);
10233 	rte_memcpy(l2_encap_conf.eth_dst, res->eth_dst.addr_bytes,
10234 		   RTE_ETHER_ADDR_LEN);
10235 }
10236 
10237 static cmdline_parse_inst_t cmd_set_l2_encap = {
10238 	.f = cmd_set_l2_encap_parsed,
10239 	.data = NULL,
10240 	.help_str = "set l2_encap ip-version ipv4|ipv6"
10241 		" eth-src <eth-src> eth-dst <eth-dst>",
10242 	.tokens = {
10243 		(void *)&cmd_set_l2_encap_set,
10244 		(void *)&cmd_set_l2_encap_l2_encap,
10245 		(void *)&cmd_set_l2_encap_ip_version,
10246 		(void *)&cmd_set_l2_encap_ip_version_value,
10247 		(void *)&cmd_set_l2_encap_eth_src,
10248 		(void *)&cmd_set_l2_encap_eth_src_value,
10249 		(void *)&cmd_set_l2_encap_eth_dst,
10250 		(void *)&cmd_set_l2_encap_eth_dst_value,
10251 		NULL,
10252 	},
10253 };
10254 
10255 static cmdline_parse_inst_t cmd_set_l2_encap_with_vlan = {
10256 	.f = cmd_set_l2_encap_parsed,
10257 	.data = NULL,
10258 	.help_str = "set l2_encap-with-vlan ip-version ipv4|ipv6"
10259 		" vlan-tci <vlan-tci> eth-src <eth-src> eth-dst <eth-dst>",
10260 	.tokens = {
10261 		(void *)&cmd_set_l2_encap_set,
10262 		(void *)&cmd_set_l2_encap_l2_encap_with_vlan,
10263 		(void *)&cmd_set_l2_encap_ip_version,
10264 		(void *)&cmd_set_l2_encap_ip_version_value,
10265 		(void *)&cmd_set_l2_encap_vlan,
10266 		(void *)&cmd_set_l2_encap_vlan_value,
10267 		(void *)&cmd_set_l2_encap_eth_src,
10268 		(void *)&cmd_set_l2_encap_eth_src_value,
10269 		(void *)&cmd_set_l2_encap_eth_dst,
10270 		(void *)&cmd_set_l2_encap_eth_dst_value,
10271 		NULL,
10272 	},
10273 };
10274 
10275 /** Set L2 decapsulation details */
10276 struct cmd_set_l2_decap_result {
10277 	cmdline_fixed_string_t set;
10278 	cmdline_fixed_string_t l2_decap;
10279 	cmdline_fixed_string_t pos_token;
10280 	uint32_t vlan_present:1;
10281 };
10282 
10283 static cmdline_parse_token_string_t cmd_set_l2_decap_set =
10284 	TOKEN_STRING_INITIALIZER(struct cmd_set_l2_decap_result, set, "set");
10285 static cmdline_parse_token_string_t cmd_set_l2_decap_l2_decap =
10286 	TOKEN_STRING_INITIALIZER(struct cmd_set_l2_decap_result, l2_decap,
10287 				 "l2_decap");
10288 static cmdline_parse_token_string_t cmd_set_l2_decap_l2_decap_with_vlan =
10289 	TOKEN_STRING_INITIALIZER(struct cmd_set_l2_decap_result, l2_decap,
10290 				 "l2_decap-with-vlan");
10291 
10292 static void cmd_set_l2_decap_parsed(void *parsed_result,
10293 	__rte_unused struct cmdline *cl,
10294 	__rte_unused void *data)
10295 {
10296 	struct cmd_set_l2_decap_result *res = parsed_result;
10297 
10298 	if (strcmp(res->l2_decap, "l2_decap") == 0)
10299 		l2_decap_conf.select_vlan = 0;
10300 	else if (strcmp(res->l2_decap, "l2_decap-with-vlan") == 0)
10301 		l2_decap_conf.select_vlan = 1;
10302 }
10303 
10304 static cmdline_parse_inst_t cmd_set_l2_decap = {
10305 	.f = cmd_set_l2_decap_parsed,
10306 	.data = NULL,
10307 	.help_str = "set l2_decap",
10308 	.tokens = {
10309 		(void *)&cmd_set_l2_decap_set,
10310 		(void *)&cmd_set_l2_decap_l2_decap,
10311 		NULL,
10312 	},
10313 };
10314 
10315 static cmdline_parse_inst_t cmd_set_l2_decap_with_vlan = {
10316 	.f = cmd_set_l2_decap_parsed,
10317 	.data = NULL,
10318 	.help_str = "set l2_decap-with-vlan",
10319 	.tokens = {
10320 		(void *)&cmd_set_l2_decap_set,
10321 		(void *)&cmd_set_l2_decap_l2_decap_with_vlan,
10322 		NULL,
10323 	},
10324 };
10325 
10326 /** Set MPLSoGRE encapsulation details */
10327 struct cmd_set_mplsogre_encap_result {
10328 	cmdline_fixed_string_t set;
10329 	cmdline_fixed_string_t mplsogre;
10330 	cmdline_fixed_string_t pos_token;
10331 	cmdline_fixed_string_t ip_version;
10332 	uint32_t vlan_present:1;
10333 	uint32_t label;
10334 	cmdline_ipaddr_t ip_src;
10335 	cmdline_ipaddr_t ip_dst;
10336 	uint16_t tci;
10337 	struct rte_ether_addr eth_src;
10338 	struct rte_ether_addr eth_dst;
10339 };
10340 
10341 static cmdline_parse_token_string_t cmd_set_mplsogre_encap_set =
10342 	TOKEN_STRING_INITIALIZER(struct cmd_set_mplsogre_encap_result, set,
10343 				 "set");
10344 static cmdline_parse_token_string_t cmd_set_mplsogre_encap_mplsogre_encap =
10345 	TOKEN_STRING_INITIALIZER(struct cmd_set_mplsogre_encap_result, mplsogre,
10346 				 "mplsogre_encap");
10347 static cmdline_parse_token_string_t cmd_set_mplsogre_encap_mplsogre_encap_with_vlan =
10348 	TOKEN_STRING_INITIALIZER(struct cmd_set_mplsogre_encap_result,
10349 				 mplsogre, "mplsogre_encap-with-vlan");
10350 static cmdline_parse_token_string_t cmd_set_mplsogre_encap_ip_version =
10351 	TOKEN_STRING_INITIALIZER(struct cmd_set_mplsogre_encap_result,
10352 				 pos_token, "ip-version");
10353 static cmdline_parse_token_string_t cmd_set_mplsogre_encap_ip_version_value =
10354 	TOKEN_STRING_INITIALIZER(struct cmd_set_mplsogre_encap_result,
10355 				 ip_version, "ipv4#ipv6");
10356 static cmdline_parse_token_string_t cmd_set_mplsogre_encap_label =
10357 	TOKEN_STRING_INITIALIZER(struct cmd_set_mplsogre_encap_result,
10358 				 pos_token, "label");
10359 static cmdline_parse_token_num_t cmd_set_mplsogre_encap_label_value =
10360 	TOKEN_NUM_INITIALIZER(struct cmd_set_mplsogre_encap_result, label,
10361 			      RTE_UINT32);
10362 static cmdline_parse_token_string_t cmd_set_mplsogre_encap_ip_src =
10363 	TOKEN_STRING_INITIALIZER(struct cmd_set_mplsogre_encap_result,
10364 				 pos_token, "ip-src");
10365 static cmdline_parse_token_ipaddr_t cmd_set_mplsogre_encap_ip_src_value =
10366 	TOKEN_IPADDR_INITIALIZER(struct cmd_set_mplsogre_encap_result, ip_src);
10367 static cmdline_parse_token_string_t cmd_set_mplsogre_encap_ip_dst =
10368 	TOKEN_STRING_INITIALIZER(struct cmd_set_mplsogre_encap_result,
10369 				 pos_token, "ip-dst");
10370 static cmdline_parse_token_ipaddr_t cmd_set_mplsogre_encap_ip_dst_value =
10371 	TOKEN_IPADDR_INITIALIZER(struct cmd_set_mplsogre_encap_result, ip_dst);
10372 static cmdline_parse_token_string_t cmd_set_mplsogre_encap_vlan =
10373 	TOKEN_STRING_INITIALIZER(struct cmd_set_mplsogre_encap_result,
10374 				 pos_token, "vlan-tci");
10375 static cmdline_parse_token_num_t cmd_set_mplsogre_encap_vlan_value =
10376 	TOKEN_NUM_INITIALIZER(struct cmd_set_mplsogre_encap_result, tci,
10377 			      RTE_UINT16);
10378 static cmdline_parse_token_string_t cmd_set_mplsogre_encap_eth_src =
10379 	TOKEN_STRING_INITIALIZER(struct cmd_set_mplsogre_encap_result,
10380 				 pos_token, "eth-src");
10381 static cmdline_parse_token_etheraddr_t cmd_set_mplsogre_encap_eth_src_value =
10382 	TOKEN_ETHERADDR_INITIALIZER(struct cmd_set_mplsogre_encap_result,
10383 				    eth_src);
10384 static cmdline_parse_token_string_t cmd_set_mplsogre_encap_eth_dst =
10385 	TOKEN_STRING_INITIALIZER(struct cmd_set_mplsogre_encap_result,
10386 				 pos_token, "eth-dst");
10387 static cmdline_parse_token_etheraddr_t cmd_set_mplsogre_encap_eth_dst_value =
10388 	TOKEN_ETHERADDR_INITIALIZER(struct cmd_set_mplsogre_encap_result,
10389 				    eth_dst);
10390 
10391 static void cmd_set_mplsogre_encap_parsed(void *parsed_result,
10392 	__rte_unused struct cmdline *cl,
10393 	__rte_unused void *data)
10394 {
10395 	struct cmd_set_mplsogre_encap_result *res = parsed_result;
10396 	union {
10397 		uint32_t mplsogre_label;
10398 		uint8_t label[4];
10399 	} id = {
10400 		.mplsogre_label = rte_cpu_to_be_32(res->label<<12),
10401 	};
10402 
10403 	if (strcmp(res->mplsogre, "mplsogre_encap") == 0)
10404 		mplsogre_encap_conf.select_vlan = 0;
10405 	else if (strcmp(res->mplsogre, "mplsogre_encap-with-vlan") == 0)
10406 		mplsogre_encap_conf.select_vlan = 1;
10407 	if (strcmp(res->ip_version, "ipv4") == 0)
10408 		mplsogre_encap_conf.select_ipv4 = 1;
10409 	else if (strcmp(res->ip_version, "ipv6") == 0)
10410 		mplsogre_encap_conf.select_ipv4 = 0;
10411 	else
10412 		return;
10413 	rte_memcpy(mplsogre_encap_conf.label, &id.label, 3);
10414 	if (mplsogre_encap_conf.select_ipv4) {
10415 		IPV4_ADDR_TO_UINT(res->ip_src, mplsogre_encap_conf.ipv4_src);
10416 		IPV4_ADDR_TO_UINT(res->ip_dst, mplsogre_encap_conf.ipv4_dst);
10417 	} else {
10418 		IPV6_ADDR_TO_ARRAY(res->ip_src, mplsogre_encap_conf.ipv6_src);
10419 		IPV6_ADDR_TO_ARRAY(res->ip_dst, mplsogre_encap_conf.ipv6_dst);
10420 	}
10421 	if (mplsogre_encap_conf.select_vlan)
10422 		mplsogre_encap_conf.vlan_tci = rte_cpu_to_be_16(res->tci);
10423 	rte_memcpy(mplsogre_encap_conf.eth_src, res->eth_src.addr_bytes,
10424 		   RTE_ETHER_ADDR_LEN);
10425 	rte_memcpy(mplsogre_encap_conf.eth_dst, res->eth_dst.addr_bytes,
10426 		   RTE_ETHER_ADDR_LEN);
10427 }
10428 
10429 static cmdline_parse_inst_t cmd_set_mplsogre_encap = {
10430 	.f = cmd_set_mplsogre_encap_parsed,
10431 	.data = NULL,
10432 	.help_str = "set mplsogre_encap ip-version ipv4|ipv6 label <label>"
10433 		" ip-src <ip-src> ip-dst <ip-dst> eth-src <eth-src>"
10434 		" eth-dst <eth-dst>",
10435 	.tokens = {
10436 		(void *)&cmd_set_mplsogre_encap_set,
10437 		(void *)&cmd_set_mplsogre_encap_mplsogre_encap,
10438 		(void *)&cmd_set_mplsogre_encap_ip_version,
10439 		(void *)&cmd_set_mplsogre_encap_ip_version_value,
10440 		(void *)&cmd_set_mplsogre_encap_label,
10441 		(void *)&cmd_set_mplsogre_encap_label_value,
10442 		(void *)&cmd_set_mplsogre_encap_ip_src,
10443 		(void *)&cmd_set_mplsogre_encap_ip_src_value,
10444 		(void *)&cmd_set_mplsogre_encap_ip_dst,
10445 		(void *)&cmd_set_mplsogre_encap_ip_dst_value,
10446 		(void *)&cmd_set_mplsogre_encap_eth_src,
10447 		(void *)&cmd_set_mplsogre_encap_eth_src_value,
10448 		(void *)&cmd_set_mplsogre_encap_eth_dst,
10449 		(void *)&cmd_set_mplsogre_encap_eth_dst_value,
10450 		NULL,
10451 	},
10452 };
10453 
10454 static cmdline_parse_inst_t cmd_set_mplsogre_encap_with_vlan = {
10455 	.f = cmd_set_mplsogre_encap_parsed,
10456 	.data = NULL,
10457 	.help_str = "set mplsogre_encap-with-vlan ip-version ipv4|ipv6"
10458 		" label <label> ip-src <ip-src> ip-dst <ip-dst>"
10459 		" vlan-tci <vlan-tci> eth-src <eth-src> eth-dst <eth-dst>",
10460 	.tokens = {
10461 		(void *)&cmd_set_mplsogre_encap_set,
10462 		(void *)&cmd_set_mplsogre_encap_mplsogre_encap_with_vlan,
10463 		(void *)&cmd_set_mplsogre_encap_ip_version,
10464 		(void *)&cmd_set_mplsogre_encap_ip_version_value,
10465 		(void *)&cmd_set_mplsogre_encap_label,
10466 		(void *)&cmd_set_mplsogre_encap_label_value,
10467 		(void *)&cmd_set_mplsogre_encap_ip_src,
10468 		(void *)&cmd_set_mplsogre_encap_ip_src_value,
10469 		(void *)&cmd_set_mplsogre_encap_ip_dst,
10470 		(void *)&cmd_set_mplsogre_encap_ip_dst_value,
10471 		(void *)&cmd_set_mplsogre_encap_vlan,
10472 		(void *)&cmd_set_mplsogre_encap_vlan_value,
10473 		(void *)&cmd_set_mplsogre_encap_eth_src,
10474 		(void *)&cmd_set_mplsogre_encap_eth_src_value,
10475 		(void *)&cmd_set_mplsogre_encap_eth_dst,
10476 		(void *)&cmd_set_mplsogre_encap_eth_dst_value,
10477 		NULL,
10478 	},
10479 };
10480 
10481 /** Set MPLSoGRE decapsulation details */
10482 struct cmd_set_mplsogre_decap_result {
10483 	cmdline_fixed_string_t set;
10484 	cmdline_fixed_string_t mplsogre;
10485 	cmdline_fixed_string_t pos_token;
10486 	cmdline_fixed_string_t ip_version;
10487 	uint32_t vlan_present:1;
10488 };
10489 
10490 static cmdline_parse_token_string_t cmd_set_mplsogre_decap_set =
10491 	TOKEN_STRING_INITIALIZER(struct cmd_set_mplsogre_decap_result, set,
10492 				 "set");
10493 static cmdline_parse_token_string_t cmd_set_mplsogre_decap_mplsogre_decap =
10494 	TOKEN_STRING_INITIALIZER(struct cmd_set_mplsogre_decap_result, mplsogre,
10495 				 "mplsogre_decap");
10496 static cmdline_parse_token_string_t cmd_set_mplsogre_decap_mplsogre_decap_with_vlan =
10497 	TOKEN_STRING_INITIALIZER(struct cmd_set_mplsogre_decap_result,
10498 				 mplsogre, "mplsogre_decap-with-vlan");
10499 static cmdline_parse_token_string_t cmd_set_mplsogre_decap_ip_version =
10500 	TOKEN_STRING_INITIALIZER(struct cmd_set_mplsogre_decap_result,
10501 				 pos_token, "ip-version");
10502 static cmdline_parse_token_string_t cmd_set_mplsogre_decap_ip_version_value =
10503 	TOKEN_STRING_INITIALIZER(struct cmd_set_mplsogre_decap_result,
10504 				 ip_version, "ipv4#ipv6");
10505 
10506 static void cmd_set_mplsogre_decap_parsed(void *parsed_result,
10507 	__rte_unused struct cmdline *cl,
10508 	__rte_unused void *data)
10509 {
10510 	struct cmd_set_mplsogre_decap_result *res = parsed_result;
10511 
10512 	if (strcmp(res->mplsogre, "mplsogre_decap") == 0)
10513 		mplsogre_decap_conf.select_vlan = 0;
10514 	else if (strcmp(res->mplsogre, "mplsogre_decap-with-vlan") == 0)
10515 		mplsogre_decap_conf.select_vlan = 1;
10516 	if (strcmp(res->ip_version, "ipv4") == 0)
10517 		mplsogre_decap_conf.select_ipv4 = 1;
10518 	else if (strcmp(res->ip_version, "ipv6") == 0)
10519 		mplsogre_decap_conf.select_ipv4 = 0;
10520 }
10521 
10522 static cmdline_parse_inst_t cmd_set_mplsogre_decap = {
10523 	.f = cmd_set_mplsogre_decap_parsed,
10524 	.data = NULL,
10525 	.help_str = "set mplsogre_decap ip-version ipv4|ipv6",
10526 	.tokens = {
10527 		(void *)&cmd_set_mplsogre_decap_set,
10528 		(void *)&cmd_set_mplsogre_decap_mplsogre_decap,
10529 		(void *)&cmd_set_mplsogre_decap_ip_version,
10530 		(void *)&cmd_set_mplsogre_decap_ip_version_value,
10531 		NULL,
10532 	},
10533 };
10534 
10535 static cmdline_parse_inst_t cmd_set_mplsogre_decap_with_vlan = {
10536 	.f = cmd_set_mplsogre_decap_parsed,
10537 	.data = NULL,
10538 	.help_str = "set mplsogre_decap-with-vlan ip-version ipv4|ipv6",
10539 	.tokens = {
10540 		(void *)&cmd_set_mplsogre_decap_set,
10541 		(void *)&cmd_set_mplsogre_decap_mplsogre_decap_with_vlan,
10542 		(void *)&cmd_set_mplsogre_decap_ip_version,
10543 		(void *)&cmd_set_mplsogre_decap_ip_version_value,
10544 		NULL,
10545 	},
10546 };
10547 
10548 /** Set MPLSoUDP encapsulation details */
10549 struct cmd_set_mplsoudp_encap_result {
10550 	cmdline_fixed_string_t set;
10551 	cmdline_fixed_string_t mplsoudp;
10552 	cmdline_fixed_string_t pos_token;
10553 	cmdline_fixed_string_t ip_version;
10554 	uint32_t vlan_present:1;
10555 	uint32_t label;
10556 	uint16_t udp_src;
10557 	uint16_t udp_dst;
10558 	cmdline_ipaddr_t ip_src;
10559 	cmdline_ipaddr_t ip_dst;
10560 	uint16_t tci;
10561 	struct rte_ether_addr eth_src;
10562 	struct rte_ether_addr eth_dst;
10563 };
10564 
10565 static cmdline_parse_token_string_t cmd_set_mplsoudp_encap_set =
10566 	TOKEN_STRING_INITIALIZER(struct cmd_set_mplsoudp_encap_result, set,
10567 				 "set");
10568 static cmdline_parse_token_string_t cmd_set_mplsoudp_encap_mplsoudp_encap =
10569 	TOKEN_STRING_INITIALIZER(struct cmd_set_mplsoudp_encap_result, mplsoudp,
10570 				 "mplsoudp_encap");
10571 static cmdline_parse_token_string_t cmd_set_mplsoudp_encap_mplsoudp_encap_with_vlan =
10572 	TOKEN_STRING_INITIALIZER(struct cmd_set_mplsoudp_encap_result,
10573 				 mplsoudp, "mplsoudp_encap-with-vlan");
10574 static cmdline_parse_token_string_t cmd_set_mplsoudp_encap_ip_version =
10575 	TOKEN_STRING_INITIALIZER(struct cmd_set_mplsoudp_encap_result,
10576 				 pos_token, "ip-version");
10577 static cmdline_parse_token_string_t cmd_set_mplsoudp_encap_ip_version_value =
10578 	TOKEN_STRING_INITIALIZER(struct cmd_set_mplsoudp_encap_result,
10579 				 ip_version, "ipv4#ipv6");
10580 static cmdline_parse_token_string_t cmd_set_mplsoudp_encap_label =
10581 	TOKEN_STRING_INITIALIZER(struct cmd_set_mplsoudp_encap_result,
10582 				 pos_token, "label");
10583 static cmdline_parse_token_num_t cmd_set_mplsoudp_encap_label_value =
10584 	TOKEN_NUM_INITIALIZER(struct cmd_set_mplsoudp_encap_result, label,
10585 			      RTE_UINT32);
10586 static cmdline_parse_token_string_t cmd_set_mplsoudp_encap_udp_src =
10587 	TOKEN_STRING_INITIALIZER(struct cmd_set_mplsoudp_encap_result,
10588 				 pos_token, "udp-src");
10589 static cmdline_parse_token_num_t cmd_set_mplsoudp_encap_udp_src_value =
10590 	TOKEN_NUM_INITIALIZER(struct cmd_set_mplsoudp_encap_result, udp_src,
10591 			      RTE_UINT16);
10592 static cmdline_parse_token_string_t cmd_set_mplsoudp_encap_udp_dst =
10593 	TOKEN_STRING_INITIALIZER(struct cmd_set_mplsoudp_encap_result,
10594 				 pos_token, "udp-dst");
10595 static cmdline_parse_token_num_t cmd_set_mplsoudp_encap_udp_dst_value =
10596 	TOKEN_NUM_INITIALIZER(struct cmd_set_mplsoudp_encap_result, udp_dst,
10597 			      RTE_UINT16);
10598 static cmdline_parse_token_string_t cmd_set_mplsoudp_encap_ip_src =
10599 	TOKEN_STRING_INITIALIZER(struct cmd_set_mplsoudp_encap_result,
10600 				 pos_token, "ip-src");
10601 static cmdline_parse_token_ipaddr_t cmd_set_mplsoudp_encap_ip_src_value =
10602 	TOKEN_IPADDR_INITIALIZER(struct cmd_set_mplsoudp_encap_result, ip_src);
10603 static cmdline_parse_token_string_t cmd_set_mplsoudp_encap_ip_dst =
10604 	TOKEN_STRING_INITIALIZER(struct cmd_set_mplsoudp_encap_result,
10605 				 pos_token, "ip-dst");
10606 static cmdline_parse_token_ipaddr_t cmd_set_mplsoudp_encap_ip_dst_value =
10607 	TOKEN_IPADDR_INITIALIZER(struct cmd_set_mplsoudp_encap_result, ip_dst);
10608 static cmdline_parse_token_string_t cmd_set_mplsoudp_encap_vlan =
10609 	TOKEN_STRING_INITIALIZER(struct cmd_set_mplsoudp_encap_result,
10610 				 pos_token, "vlan-tci");
10611 static cmdline_parse_token_num_t cmd_set_mplsoudp_encap_vlan_value =
10612 	TOKEN_NUM_INITIALIZER(struct cmd_set_mplsoudp_encap_result, tci,
10613 			      RTE_UINT16);
10614 static cmdline_parse_token_string_t cmd_set_mplsoudp_encap_eth_src =
10615 	TOKEN_STRING_INITIALIZER(struct cmd_set_mplsoudp_encap_result,
10616 				 pos_token, "eth-src");
10617 static cmdline_parse_token_etheraddr_t cmd_set_mplsoudp_encap_eth_src_value =
10618 	TOKEN_ETHERADDR_INITIALIZER(struct cmd_set_mplsoudp_encap_result,
10619 				    eth_src);
10620 static cmdline_parse_token_string_t cmd_set_mplsoudp_encap_eth_dst =
10621 	TOKEN_STRING_INITIALIZER(struct cmd_set_mplsoudp_encap_result,
10622 				 pos_token, "eth-dst");
10623 static cmdline_parse_token_etheraddr_t cmd_set_mplsoudp_encap_eth_dst_value =
10624 	TOKEN_ETHERADDR_INITIALIZER(struct cmd_set_mplsoudp_encap_result,
10625 				    eth_dst);
10626 
10627 static void cmd_set_mplsoudp_encap_parsed(void *parsed_result,
10628 	__rte_unused struct cmdline *cl,
10629 	__rte_unused void *data)
10630 {
10631 	struct cmd_set_mplsoudp_encap_result *res = parsed_result;
10632 	union {
10633 		uint32_t mplsoudp_label;
10634 		uint8_t label[4];
10635 	} id = {
10636 		.mplsoudp_label = rte_cpu_to_be_32(res->label<<12),
10637 	};
10638 
10639 	if (strcmp(res->mplsoudp, "mplsoudp_encap") == 0)
10640 		mplsoudp_encap_conf.select_vlan = 0;
10641 	else if (strcmp(res->mplsoudp, "mplsoudp_encap-with-vlan") == 0)
10642 		mplsoudp_encap_conf.select_vlan = 1;
10643 	if (strcmp(res->ip_version, "ipv4") == 0)
10644 		mplsoudp_encap_conf.select_ipv4 = 1;
10645 	else if (strcmp(res->ip_version, "ipv6") == 0)
10646 		mplsoudp_encap_conf.select_ipv4 = 0;
10647 	else
10648 		return;
10649 	rte_memcpy(mplsoudp_encap_conf.label, &id.label, 3);
10650 	mplsoudp_encap_conf.udp_src = rte_cpu_to_be_16(res->udp_src);
10651 	mplsoudp_encap_conf.udp_dst = rte_cpu_to_be_16(res->udp_dst);
10652 	if (mplsoudp_encap_conf.select_ipv4) {
10653 		IPV4_ADDR_TO_UINT(res->ip_src, mplsoudp_encap_conf.ipv4_src);
10654 		IPV4_ADDR_TO_UINT(res->ip_dst, mplsoudp_encap_conf.ipv4_dst);
10655 	} else {
10656 		IPV6_ADDR_TO_ARRAY(res->ip_src, mplsoudp_encap_conf.ipv6_src);
10657 		IPV6_ADDR_TO_ARRAY(res->ip_dst, mplsoudp_encap_conf.ipv6_dst);
10658 	}
10659 	if (mplsoudp_encap_conf.select_vlan)
10660 		mplsoudp_encap_conf.vlan_tci = rte_cpu_to_be_16(res->tci);
10661 	rte_memcpy(mplsoudp_encap_conf.eth_src, res->eth_src.addr_bytes,
10662 		   RTE_ETHER_ADDR_LEN);
10663 	rte_memcpy(mplsoudp_encap_conf.eth_dst, res->eth_dst.addr_bytes,
10664 		   RTE_ETHER_ADDR_LEN);
10665 }
10666 
10667 static cmdline_parse_inst_t cmd_set_mplsoudp_encap = {
10668 	.f = cmd_set_mplsoudp_encap_parsed,
10669 	.data = NULL,
10670 	.help_str = "set mplsoudp_encap ip-version ipv4|ipv6 label <label>"
10671 		" udp-src <udp-src> udp-dst <udp-dst> ip-src <ip-src>"
10672 		" ip-dst <ip-dst> eth-src <eth-src> eth-dst <eth-dst>",
10673 	.tokens = {
10674 		(void *)&cmd_set_mplsoudp_encap_set,
10675 		(void *)&cmd_set_mplsoudp_encap_mplsoudp_encap,
10676 		(void *)&cmd_set_mplsoudp_encap_ip_version,
10677 		(void *)&cmd_set_mplsoudp_encap_ip_version_value,
10678 		(void *)&cmd_set_mplsoudp_encap_label,
10679 		(void *)&cmd_set_mplsoudp_encap_label_value,
10680 		(void *)&cmd_set_mplsoudp_encap_udp_src,
10681 		(void *)&cmd_set_mplsoudp_encap_udp_src_value,
10682 		(void *)&cmd_set_mplsoudp_encap_udp_dst,
10683 		(void *)&cmd_set_mplsoudp_encap_udp_dst_value,
10684 		(void *)&cmd_set_mplsoudp_encap_ip_src,
10685 		(void *)&cmd_set_mplsoudp_encap_ip_src_value,
10686 		(void *)&cmd_set_mplsoudp_encap_ip_dst,
10687 		(void *)&cmd_set_mplsoudp_encap_ip_dst_value,
10688 		(void *)&cmd_set_mplsoudp_encap_eth_src,
10689 		(void *)&cmd_set_mplsoudp_encap_eth_src_value,
10690 		(void *)&cmd_set_mplsoudp_encap_eth_dst,
10691 		(void *)&cmd_set_mplsoudp_encap_eth_dst_value,
10692 		NULL,
10693 	},
10694 };
10695 
10696 static cmdline_parse_inst_t cmd_set_mplsoudp_encap_with_vlan = {
10697 	.f = cmd_set_mplsoudp_encap_parsed,
10698 	.data = NULL,
10699 	.help_str = "set mplsoudp_encap-with-vlan ip-version ipv4|ipv6"
10700 		" label <label> udp-src <udp-src> udp-dst <udp-dst>"
10701 		" ip-src <ip-src> ip-dst <ip-dst> vlan-tci <vlan-tci>"
10702 		" eth-src <eth-src> eth-dst <eth-dst>",
10703 	.tokens = {
10704 		(void *)&cmd_set_mplsoudp_encap_set,
10705 		(void *)&cmd_set_mplsoudp_encap_mplsoudp_encap_with_vlan,
10706 		(void *)&cmd_set_mplsoudp_encap_ip_version,
10707 		(void *)&cmd_set_mplsoudp_encap_ip_version_value,
10708 		(void *)&cmd_set_mplsoudp_encap_label,
10709 		(void *)&cmd_set_mplsoudp_encap_label_value,
10710 		(void *)&cmd_set_mplsoudp_encap_udp_src,
10711 		(void *)&cmd_set_mplsoudp_encap_udp_src_value,
10712 		(void *)&cmd_set_mplsoudp_encap_udp_dst,
10713 		(void *)&cmd_set_mplsoudp_encap_udp_dst_value,
10714 		(void *)&cmd_set_mplsoudp_encap_ip_src,
10715 		(void *)&cmd_set_mplsoudp_encap_ip_src_value,
10716 		(void *)&cmd_set_mplsoudp_encap_ip_dst,
10717 		(void *)&cmd_set_mplsoudp_encap_ip_dst_value,
10718 		(void *)&cmd_set_mplsoudp_encap_vlan,
10719 		(void *)&cmd_set_mplsoudp_encap_vlan_value,
10720 		(void *)&cmd_set_mplsoudp_encap_eth_src,
10721 		(void *)&cmd_set_mplsoudp_encap_eth_src_value,
10722 		(void *)&cmd_set_mplsoudp_encap_eth_dst,
10723 		(void *)&cmd_set_mplsoudp_encap_eth_dst_value,
10724 		NULL,
10725 	},
10726 };
10727 
10728 /** Set MPLSoUDP decapsulation details */
10729 struct cmd_set_mplsoudp_decap_result {
10730 	cmdline_fixed_string_t set;
10731 	cmdline_fixed_string_t mplsoudp;
10732 	cmdline_fixed_string_t pos_token;
10733 	cmdline_fixed_string_t ip_version;
10734 	uint32_t vlan_present:1;
10735 };
10736 
10737 static cmdline_parse_token_string_t cmd_set_mplsoudp_decap_set =
10738 	TOKEN_STRING_INITIALIZER(struct cmd_set_mplsoudp_decap_result, set,
10739 				 "set");
10740 static cmdline_parse_token_string_t cmd_set_mplsoudp_decap_mplsoudp_decap =
10741 	TOKEN_STRING_INITIALIZER(struct cmd_set_mplsoudp_decap_result, mplsoudp,
10742 				 "mplsoudp_decap");
10743 static cmdline_parse_token_string_t cmd_set_mplsoudp_decap_mplsoudp_decap_with_vlan =
10744 	TOKEN_STRING_INITIALIZER(struct cmd_set_mplsoudp_decap_result,
10745 				 mplsoudp, "mplsoudp_decap-with-vlan");
10746 static cmdline_parse_token_string_t cmd_set_mplsoudp_decap_ip_version =
10747 	TOKEN_STRING_INITIALIZER(struct cmd_set_mplsoudp_decap_result,
10748 				 pos_token, "ip-version");
10749 static cmdline_parse_token_string_t cmd_set_mplsoudp_decap_ip_version_value =
10750 	TOKEN_STRING_INITIALIZER(struct cmd_set_mplsoudp_decap_result,
10751 				 ip_version, "ipv4#ipv6");
10752 
10753 static void cmd_set_mplsoudp_decap_parsed(void *parsed_result,
10754 	__rte_unused struct cmdline *cl,
10755 	__rte_unused void *data)
10756 {
10757 	struct cmd_set_mplsoudp_decap_result *res = parsed_result;
10758 
10759 	if (strcmp(res->mplsoudp, "mplsoudp_decap") == 0)
10760 		mplsoudp_decap_conf.select_vlan = 0;
10761 	else if (strcmp(res->mplsoudp, "mplsoudp_decap-with-vlan") == 0)
10762 		mplsoudp_decap_conf.select_vlan = 1;
10763 	if (strcmp(res->ip_version, "ipv4") == 0)
10764 		mplsoudp_decap_conf.select_ipv4 = 1;
10765 	else if (strcmp(res->ip_version, "ipv6") == 0)
10766 		mplsoudp_decap_conf.select_ipv4 = 0;
10767 }
10768 
10769 static cmdline_parse_inst_t cmd_set_mplsoudp_decap = {
10770 	.f = cmd_set_mplsoudp_decap_parsed,
10771 	.data = NULL,
10772 	.help_str = "set mplsoudp_decap ip-version ipv4|ipv6",
10773 	.tokens = {
10774 		(void *)&cmd_set_mplsoudp_decap_set,
10775 		(void *)&cmd_set_mplsoudp_decap_mplsoudp_decap,
10776 		(void *)&cmd_set_mplsoudp_decap_ip_version,
10777 		(void *)&cmd_set_mplsoudp_decap_ip_version_value,
10778 		NULL,
10779 	},
10780 };
10781 
10782 static cmdline_parse_inst_t cmd_set_mplsoudp_decap_with_vlan = {
10783 	.f = cmd_set_mplsoudp_decap_parsed,
10784 	.data = NULL,
10785 	.help_str = "set mplsoudp_decap-with-vlan ip-version ipv4|ipv6",
10786 	.tokens = {
10787 		(void *)&cmd_set_mplsoudp_decap_set,
10788 		(void *)&cmd_set_mplsoudp_decap_mplsoudp_decap_with_vlan,
10789 		(void *)&cmd_set_mplsoudp_decap_ip_version,
10790 		(void *)&cmd_set_mplsoudp_decap_ip_version_value,
10791 		NULL,
10792 	},
10793 };
10794 
10795 /** Set connection tracking object common details */
10796 struct cmd_set_conntrack_common_result {
10797 	cmdline_fixed_string_t set;
10798 	cmdline_fixed_string_t conntrack;
10799 	cmdline_fixed_string_t common;
10800 	cmdline_fixed_string_t peer;
10801 	cmdline_fixed_string_t is_orig;
10802 	cmdline_fixed_string_t enable;
10803 	cmdline_fixed_string_t live;
10804 	cmdline_fixed_string_t sack;
10805 	cmdline_fixed_string_t cack;
10806 	cmdline_fixed_string_t last_dir;
10807 	cmdline_fixed_string_t liberal;
10808 	cmdline_fixed_string_t state;
10809 	cmdline_fixed_string_t max_ack_win;
10810 	cmdline_fixed_string_t retrans;
10811 	cmdline_fixed_string_t last_win;
10812 	cmdline_fixed_string_t last_seq;
10813 	cmdline_fixed_string_t last_ack;
10814 	cmdline_fixed_string_t last_end;
10815 	cmdline_fixed_string_t last_index;
10816 	uint8_t stat;
10817 	uint8_t factor;
10818 	uint16_t peer_port;
10819 	uint32_t is_original;
10820 	uint32_t en;
10821 	uint32_t is_live;
10822 	uint32_t s_ack;
10823 	uint32_t c_ack;
10824 	uint32_t ld;
10825 	uint32_t lb;
10826 	uint8_t re_num;
10827 	uint8_t li;
10828 	uint16_t lw;
10829 	uint32_t ls;
10830 	uint32_t la;
10831 	uint32_t le;
10832 };
10833 
10834 static cmdline_parse_token_string_t cmd_set_conntrack_set =
10835 	TOKEN_STRING_INITIALIZER(struct cmd_set_conntrack_common_result,
10836 				 set, "set");
10837 static cmdline_parse_token_string_t cmd_set_conntrack_conntrack =
10838 	TOKEN_STRING_INITIALIZER(struct cmd_set_conntrack_common_result,
10839 				 conntrack, "conntrack");
10840 static cmdline_parse_token_string_t cmd_set_conntrack_common_com =
10841 	TOKEN_STRING_INITIALIZER(struct cmd_set_conntrack_common_result,
10842 				 common, "com");
10843 static cmdline_parse_token_string_t cmd_set_conntrack_common_peer =
10844 	TOKEN_STRING_INITIALIZER(struct cmd_set_conntrack_common_result,
10845 				 peer, "peer");
10846 static cmdline_parse_token_num_t cmd_set_conntrack_common_peer_value =
10847 	TOKEN_NUM_INITIALIZER(struct cmd_set_conntrack_common_result,
10848 			      peer_port, RTE_UINT16);
10849 static cmdline_parse_token_string_t cmd_set_conntrack_common_is_orig =
10850 	TOKEN_STRING_INITIALIZER(struct cmd_set_conntrack_common_result,
10851 				 is_orig, "is_orig");
10852 static cmdline_parse_token_num_t cmd_set_conntrack_common_is_orig_value =
10853 	TOKEN_NUM_INITIALIZER(struct cmd_set_conntrack_common_result,
10854 			      is_original, RTE_UINT32);
10855 static cmdline_parse_token_string_t cmd_set_conntrack_common_enable =
10856 	TOKEN_STRING_INITIALIZER(struct cmd_set_conntrack_common_result,
10857 				 enable, "enable");
10858 static cmdline_parse_token_num_t cmd_set_conntrack_common_enable_value =
10859 	TOKEN_NUM_INITIALIZER(struct cmd_set_conntrack_common_result,
10860 			      en, RTE_UINT32);
10861 static cmdline_parse_token_string_t cmd_set_conntrack_common_live =
10862 	TOKEN_STRING_INITIALIZER(struct cmd_set_conntrack_common_result,
10863 				 live, "live");
10864 static cmdline_parse_token_num_t cmd_set_conntrack_common_live_value =
10865 	TOKEN_NUM_INITIALIZER(struct cmd_set_conntrack_common_result,
10866 			      is_live, RTE_UINT32);
10867 static cmdline_parse_token_string_t cmd_set_conntrack_common_sack =
10868 	TOKEN_STRING_INITIALIZER(struct cmd_set_conntrack_common_result,
10869 				 sack, "sack");
10870 static cmdline_parse_token_num_t cmd_set_conntrack_common_sack_value =
10871 	TOKEN_NUM_INITIALIZER(struct cmd_set_conntrack_common_result,
10872 			      s_ack, RTE_UINT32);
10873 static cmdline_parse_token_string_t cmd_set_conntrack_common_cack =
10874 	TOKEN_STRING_INITIALIZER(struct cmd_set_conntrack_common_result,
10875 				 cack, "cack");
10876 static cmdline_parse_token_num_t cmd_set_conntrack_common_cack_value =
10877 	TOKEN_NUM_INITIALIZER(struct cmd_set_conntrack_common_result,
10878 			      c_ack, RTE_UINT32);
10879 static cmdline_parse_token_string_t cmd_set_conntrack_common_last_dir =
10880 	TOKEN_STRING_INITIALIZER(struct cmd_set_conntrack_common_result,
10881 				 last_dir, "last_dir");
10882 static cmdline_parse_token_num_t cmd_set_conntrack_common_last_dir_value =
10883 	TOKEN_NUM_INITIALIZER(struct cmd_set_conntrack_common_result,
10884 			      ld, RTE_UINT32);
10885 static cmdline_parse_token_string_t cmd_set_conntrack_common_liberal =
10886 	TOKEN_STRING_INITIALIZER(struct cmd_set_conntrack_common_result,
10887 				 liberal, "liberal");
10888 static cmdline_parse_token_num_t cmd_set_conntrack_common_liberal_value =
10889 	TOKEN_NUM_INITIALIZER(struct cmd_set_conntrack_common_result,
10890 			      lb, RTE_UINT32);
10891 static cmdline_parse_token_string_t cmd_set_conntrack_common_state =
10892 	TOKEN_STRING_INITIALIZER(struct cmd_set_conntrack_common_result,
10893 				 state, "state");
10894 static cmdline_parse_token_num_t cmd_set_conntrack_common_state_value =
10895 	TOKEN_NUM_INITIALIZER(struct cmd_set_conntrack_common_result,
10896 			      stat, RTE_UINT8);
10897 static cmdline_parse_token_string_t cmd_set_conntrack_common_max_ackwin =
10898 	TOKEN_STRING_INITIALIZER(struct cmd_set_conntrack_common_result,
10899 				 max_ack_win, "max_ack_win");
10900 static cmdline_parse_token_num_t cmd_set_conntrack_common_max_ackwin_value =
10901 	TOKEN_NUM_INITIALIZER(struct cmd_set_conntrack_common_result,
10902 			      factor, RTE_UINT8);
10903 static cmdline_parse_token_string_t cmd_set_conntrack_common_retrans =
10904 	TOKEN_STRING_INITIALIZER(struct cmd_set_conntrack_common_result,
10905 				 retrans, "r_lim");
10906 static cmdline_parse_token_num_t cmd_set_conntrack_common_retrans_value =
10907 	TOKEN_NUM_INITIALIZER(struct cmd_set_conntrack_common_result,
10908 			      re_num, RTE_UINT8);
10909 static cmdline_parse_token_string_t cmd_set_conntrack_common_last_win =
10910 	TOKEN_STRING_INITIALIZER(struct cmd_set_conntrack_common_result,
10911 				 last_win, "last_win");
10912 static cmdline_parse_token_num_t cmd_set_conntrack_common_last_win_value =
10913 	TOKEN_NUM_INITIALIZER(struct cmd_set_conntrack_common_result,
10914 			      lw, RTE_UINT16);
10915 static cmdline_parse_token_string_t cmd_set_conntrack_common_last_seq =
10916 	TOKEN_STRING_INITIALIZER(struct cmd_set_conntrack_common_result,
10917 				 last_seq, "last_seq");
10918 static cmdline_parse_token_num_t cmd_set_conntrack_common_last_seq_value =
10919 	TOKEN_NUM_INITIALIZER(struct cmd_set_conntrack_common_result,
10920 			      ls, RTE_UINT32);
10921 static cmdline_parse_token_string_t cmd_set_conntrack_common_last_ack =
10922 	TOKEN_STRING_INITIALIZER(struct cmd_set_conntrack_common_result,
10923 				 last_ack, "last_ack");
10924 static cmdline_parse_token_num_t cmd_set_conntrack_common_last_ack_value =
10925 	TOKEN_NUM_INITIALIZER(struct cmd_set_conntrack_common_result,
10926 			      la, RTE_UINT32);
10927 static cmdline_parse_token_string_t cmd_set_conntrack_common_last_end =
10928 	TOKEN_STRING_INITIALIZER(struct cmd_set_conntrack_common_result,
10929 				 last_end, "last_end");
10930 static cmdline_parse_token_num_t cmd_set_conntrack_common_last_end_value =
10931 	TOKEN_NUM_INITIALIZER(struct cmd_set_conntrack_common_result,
10932 			      le, RTE_UINT32);
10933 static cmdline_parse_token_string_t cmd_set_conntrack_common_last_index =
10934 	TOKEN_STRING_INITIALIZER(struct cmd_set_conntrack_common_result,
10935 				 last_index, "last_index");
10936 static cmdline_parse_token_num_t cmd_set_conntrack_common_last_index_value =
10937 	TOKEN_NUM_INITIALIZER(struct cmd_set_conntrack_common_result,
10938 			      li, RTE_UINT8);
10939 
10940 static void cmd_set_conntrack_common_parsed(void *parsed_result,
10941 	__rte_unused struct cmdline *cl,
10942 	__rte_unused void *data)
10943 {
10944 	struct cmd_set_conntrack_common_result *res = parsed_result;
10945 
10946 	/* No need to swap to big endian. */
10947 	conntrack_context.peer_port = res->peer_port;
10948 	conntrack_context.is_original_dir = res->is_original;
10949 	conntrack_context.enable = res->en;
10950 	conntrack_context.live_connection = res->is_live;
10951 	conntrack_context.selective_ack = res->s_ack;
10952 	conntrack_context.challenge_ack_passed = res->c_ack;
10953 	conntrack_context.last_direction = res->ld;
10954 	conntrack_context.liberal_mode = res->lb;
10955 	conntrack_context.state = (enum rte_flow_conntrack_state)res->stat;
10956 	conntrack_context.max_ack_window = res->factor;
10957 	conntrack_context.retransmission_limit = res->re_num;
10958 	conntrack_context.last_window = res->lw;
10959 	conntrack_context.last_index =
10960 		(enum rte_flow_conntrack_tcp_last_index)res->li;
10961 	conntrack_context.last_seq = res->ls;
10962 	conntrack_context.last_ack = res->la;
10963 	conntrack_context.last_end = res->le;
10964 }
10965 
10966 static cmdline_parse_inst_t cmd_set_conntrack_common = {
10967 	.f = cmd_set_conntrack_common_parsed,
10968 	.data = NULL,
10969 	.help_str = "set conntrack com peer <port_id> is_orig <dir> enable <en>"
10970 		" live <ack_seen> sack <en> cack <passed> last_dir <dir>"
10971 		" liberal <en> state <s> max_ack_win <factor> r_lim <num>"
10972 		" last_win <win> last_seq <seq> last_ack <ack> last_end <end>"
10973 		" last_index <flag>",
10974 	.tokens = {
10975 		(void *)&cmd_set_conntrack_set,
10976 		(void *)&cmd_set_conntrack_conntrack,
10977 		(void *)&cmd_set_conntrack_common_com,
10978 		(void *)&cmd_set_conntrack_common_peer,
10979 		(void *)&cmd_set_conntrack_common_peer_value,
10980 		(void *)&cmd_set_conntrack_common_is_orig,
10981 		(void *)&cmd_set_conntrack_common_is_orig_value,
10982 		(void *)&cmd_set_conntrack_common_enable,
10983 		(void *)&cmd_set_conntrack_common_enable_value,
10984 		(void *)&cmd_set_conntrack_common_live,
10985 		(void *)&cmd_set_conntrack_common_live_value,
10986 		(void *)&cmd_set_conntrack_common_sack,
10987 		(void *)&cmd_set_conntrack_common_sack_value,
10988 		(void *)&cmd_set_conntrack_common_cack,
10989 		(void *)&cmd_set_conntrack_common_cack_value,
10990 		(void *)&cmd_set_conntrack_common_last_dir,
10991 		(void *)&cmd_set_conntrack_common_last_dir_value,
10992 		(void *)&cmd_set_conntrack_common_liberal,
10993 		(void *)&cmd_set_conntrack_common_liberal_value,
10994 		(void *)&cmd_set_conntrack_common_state,
10995 		(void *)&cmd_set_conntrack_common_state_value,
10996 		(void *)&cmd_set_conntrack_common_max_ackwin,
10997 		(void *)&cmd_set_conntrack_common_max_ackwin_value,
10998 		(void *)&cmd_set_conntrack_common_retrans,
10999 		(void *)&cmd_set_conntrack_common_retrans_value,
11000 		(void *)&cmd_set_conntrack_common_last_win,
11001 		(void *)&cmd_set_conntrack_common_last_win_value,
11002 		(void *)&cmd_set_conntrack_common_last_seq,
11003 		(void *)&cmd_set_conntrack_common_last_seq_value,
11004 		(void *)&cmd_set_conntrack_common_last_ack,
11005 		(void *)&cmd_set_conntrack_common_last_ack_value,
11006 		(void *)&cmd_set_conntrack_common_last_end,
11007 		(void *)&cmd_set_conntrack_common_last_end_value,
11008 		(void *)&cmd_set_conntrack_common_last_index,
11009 		(void *)&cmd_set_conntrack_common_last_index_value,
11010 		NULL,
11011 	},
11012 };
11013 
11014 /** Set connection tracking object both directions' details */
11015 struct cmd_set_conntrack_dir_result {
11016 	cmdline_fixed_string_t set;
11017 	cmdline_fixed_string_t conntrack;
11018 	cmdline_fixed_string_t dir;
11019 	cmdline_fixed_string_t scale;
11020 	cmdline_fixed_string_t fin;
11021 	cmdline_fixed_string_t ack_seen;
11022 	cmdline_fixed_string_t unack;
11023 	cmdline_fixed_string_t sent_end;
11024 	cmdline_fixed_string_t reply_end;
11025 	cmdline_fixed_string_t max_win;
11026 	cmdline_fixed_string_t max_ack;
11027 	uint32_t factor;
11028 	uint32_t f;
11029 	uint32_t as;
11030 	uint32_t un;
11031 	uint32_t se;
11032 	uint32_t re;
11033 	uint32_t mw;
11034 	uint32_t ma;
11035 };
11036 
11037 static cmdline_parse_token_string_t cmd_set_conntrack_dir_dir =
11038 	TOKEN_STRING_INITIALIZER(struct cmd_set_conntrack_dir_result,
11039 				 dir, "orig#rply");
11040 static cmdline_parse_token_string_t cmd_set_conntrack_dir_scale =
11041 	TOKEN_STRING_INITIALIZER(struct cmd_set_conntrack_dir_result,
11042 				 scale, "scale");
11043 static cmdline_parse_token_num_t cmd_set_conntrack_dir_scale_value =
11044 	TOKEN_NUM_INITIALIZER(struct cmd_set_conntrack_dir_result,
11045 			      factor, RTE_UINT32);
11046 static cmdline_parse_token_string_t cmd_set_conntrack_dir_fin =
11047 	TOKEN_STRING_INITIALIZER(struct cmd_set_conntrack_dir_result,
11048 				 fin, "fin");
11049 static cmdline_parse_token_num_t cmd_set_conntrack_dir_fin_value =
11050 	TOKEN_NUM_INITIALIZER(struct cmd_set_conntrack_dir_result,
11051 			      f, RTE_UINT32);
11052 static cmdline_parse_token_string_t cmd_set_conntrack_dir_ack =
11053 	TOKEN_STRING_INITIALIZER(struct cmd_set_conntrack_dir_result,
11054 				 ack_seen, "acked");
11055 static cmdline_parse_token_num_t cmd_set_conntrack_dir_ack_value =
11056 	TOKEN_NUM_INITIALIZER(struct cmd_set_conntrack_dir_result,
11057 			      as, RTE_UINT32);
11058 static cmdline_parse_token_string_t cmd_set_conntrack_dir_unack_data =
11059 	TOKEN_STRING_INITIALIZER(struct cmd_set_conntrack_dir_result,
11060 				 unack, "unack_data");
11061 static cmdline_parse_token_num_t cmd_set_conntrack_dir_unack_data_value =
11062 	TOKEN_NUM_INITIALIZER(struct cmd_set_conntrack_dir_result,
11063 			      un, RTE_UINT32);
11064 static cmdline_parse_token_string_t cmd_set_conntrack_dir_sent_end =
11065 	TOKEN_STRING_INITIALIZER(struct cmd_set_conntrack_dir_result,
11066 				 sent_end, "sent_end");
11067 static cmdline_parse_token_num_t cmd_set_conntrack_dir_sent_end_value =
11068 	TOKEN_NUM_INITIALIZER(struct cmd_set_conntrack_dir_result,
11069 			      se, RTE_UINT32);
11070 static cmdline_parse_token_string_t cmd_set_conntrack_dir_reply_end =
11071 	TOKEN_STRING_INITIALIZER(struct cmd_set_conntrack_dir_result,
11072 				 reply_end, "reply_end");
11073 static cmdline_parse_token_num_t cmd_set_conntrack_dir_reply_end_value =
11074 	TOKEN_NUM_INITIALIZER(struct cmd_set_conntrack_dir_result,
11075 			      re, RTE_UINT32);
11076 static cmdline_parse_token_string_t cmd_set_conntrack_dir_max_win =
11077 	TOKEN_STRING_INITIALIZER(struct cmd_set_conntrack_dir_result,
11078 				 max_win, "max_win");
11079 static cmdline_parse_token_num_t cmd_set_conntrack_dir_max_win_value =
11080 	TOKEN_NUM_INITIALIZER(struct cmd_set_conntrack_dir_result,
11081 			      mw, RTE_UINT32);
11082 static cmdline_parse_token_string_t cmd_set_conntrack_dir_max_ack =
11083 	TOKEN_STRING_INITIALIZER(struct cmd_set_conntrack_dir_result,
11084 				 max_ack, "max_ack");
11085 static cmdline_parse_token_num_t cmd_set_conntrack_dir_max_ack_value =
11086 	TOKEN_NUM_INITIALIZER(struct cmd_set_conntrack_dir_result,
11087 			      ma, RTE_UINT32);
11088 
11089 static void cmd_set_conntrack_dir_parsed(void *parsed_result,
11090 	__rte_unused struct cmdline *cl,
11091 	__rte_unused void *data)
11092 {
11093 	struct cmd_set_conntrack_dir_result *res = parsed_result;
11094 	struct rte_flow_tcp_dir_param *dir = NULL;
11095 
11096 	if (strcmp(res->dir, "orig") == 0)
11097 		dir = &conntrack_context.original_dir;
11098 	else if (strcmp(res->dir, "rply") == 0)
11099 		dir = &conntrack_context.reply_dir;
11100 	else
11101 		return;
11102 	dir->scale = res->factor;
11103 	dir->close_initiated = res->f;
11104 	dir->last_ack_seen = res->as;
11105 	dir->data_unacked = res->un;
11106 	dir->sent_end = res->se;
11107 	dir->reply_end = res->re;
11108 	dir->max_ack = res->ma;
11109 	dir->max_win = res->mw;
11110 }
11111 
11112 static cmdline_parse_inst_t cmd_set_conntrack_dir = {
11113 	.f = cmd_set_conntrack_dir_parsed,
11114 	.data = NULL,
11115 	.help_str = "set conntrack orig|rply scale <factor> fin <sent>"
11116 		    " acked <seen> unack_data <unack> sent_end <sent>"
11117 		    " reply_end <reply> max_win <win> max_ack <ack>",
11118 	.tokens = {
11119 		(void *)&cmd_set_conntrack_set,
11120 		(void *)&cmd_set_conntrack_conntrack,
11121 		(void *)&cmd_set_conntrack_dir_dir,
11122 		(void *)&cmd_set_conntrack_dir_scale,
11123 		(void *)&cmd_set_conntrack_dir_scale_value,
11124 		(void *)&cmd_set_conntrack_dir_fin,
11125 		(void *)&cmd_set_conntrack_dir_fin_value,
11126 		(void *)&cmd_set_conntrack_dir_ack,
11127 		(void *)&cmd_set_conntrack_dir_ack_value,
11128 		(void *)&cmd_set_conntrack_dir_unack_data,
11129 		(void *)&cmd_set_conntrack_dir_unack_data_value,
11130 		(void *)&cmd_set_conntrack_dir_sent_end,
11131 		(void *)&cmd_set_conntrack_dir_sent_end_value,
11132 		(void *)&cmd_set_conntrack_dir_reply_end,
11133 		(void *)&cmd_set_conntrack_dir_reply_end_value,
11134 		(void *)&cmd_set_conntrack_dir_max_win,
11135 		(void *)&cmd_set_conntrack_dir_max_win_value,
11136 		(void *)&cmd_set_conntrack_dir_max_ack,
11137 		(void *)&cmd_set_conntrack_dir_max_ack_value,
11138 		NULL,
11139 	},
11140 };
11141 
11142 /* show vf stats */
11143 
11144 /* Common result structure for show vf stats */
11145 struct cmd_show_vf_stats_result {
11146 	cmdline_fixed_string_t show;
11147 	cmdline_fixed_string_t vf;
11148 	cmdline_fixed_string_t stats;
11149 	portid_t port_id;
11150 	uint16_t vf_id;
11151 };
11152 
11153 /* Common CLI fields show vf stats*/
11154 static cmdline_parse_token_string_t cmd_show_vf_stats_show =
11155 	TOKEN_STRING_INITIALIZER
11156 		(struct cmd_show_vf_stats_result,
11157 		 show, "show");
11158 static cmdline_parse_token_string_t cmd_show_vf_stats_vf =
11159 	TOKEN_STRING_INITIALIZER
11160 		(struct cmd_show_vf_stats_result,
11161 		 vf, "vf");
11162 static cmdline_parse_token_string_t cmd_show_vf_stats_stats =
11163 	TOKEN_STRING_INITIALIZER
11164 		(struct cmd_show_vf_stats_result,
11165 		 stats, "stats");
11166 static cmdline_parse_token_num_t cmd_show_vf_stats_port_id =
11167 	TOKEN_NUM_INITIALIZER
11168 		(struct cmd_show_vf_stats_result,
11169 		 port_id, RTE_UINT16);
11170 static cmdline_parse_token_num_t cmd_show_vf_stats_vf_id =
11171 	TOKEN_NUM_INITIALIZER
11172 		(struct cmd_show_vf_stats_result,
11173 		 vf_id, RTE_UINT16);
11174 
11175 static void
11176 cmd_show_vf_stats_parsed(
11177 	void *parsed_result,
11178 	__rte_unused struct cmdline *cl,
11179 	__rte_unused void *data)
11180 {
11181 	struct cmd_show_vf_stats_result *res = parsed_result;
11182 	struct rte_eth_stats stats;
11183 	int ret = -ENOTSUP;
11184 	static const char *nic_stats_border = "########################";
11185 
11186 	if (port_id_is_invalid(res->port_id, ENABLED_WARN))
11187 		return;
11188 
11189 	memset(&stats, 0, sizeof(stats));
11190 
11191 #ifdef RTE_NET_I40E
11192 	if (ret == -ENOTSUP)
11193 		ret = rte_pmd_i40e_get_vf_stats(res->port_id,
11194 						res->vf_id,
11195 						&stats);
11196 #endif
11197 #ifdef RTE_NET_BNXT
11198 	if (ret == -ENOTSUP)
11199 		ret = rte_pmd_bnxt_get_vf_stats(res->port_id,
11200 						res->vf_id,
11201 						&stats);
11202 #endif
11203 
11204 	switch (ret) {
11205 	case 0:
11206 		break;
11207 	case -EINVAL:
11208 		fprintf(stderr, "invalid vf_id %d\n", res->vf_id);
11209 		break;
11210 	case -ENODEV:
11211 		fprintf(stderr, "invalid port_id %d\n", res->port_id);
11212 		break;
11213 	case -ENOTSUP:
11214 		fprintf(stderr, "function not implemented\n");
11215 		break;
11216 	default:
11217 		fprintf(stderr, "programming error: (%s)\n", strerror(-ret));
11218 	}
11219 
11220 	printf("\n  %s NIC statistics for port %-2d vf %-2d %s\n",
11221 		nic_stats_border, res->port_id, res->vf_id, nic_stats_border);
11222 
11223 	printf("  RX-packets: %-10"PRIu64" RX-missed: %-10"PRIu64" RX-bytes:  "
11224 	       "%-"PRIu64"\n",
11225 	       stats.ipackets, stats.imissed, stats.ibytes);
11226 	printf("  RX-errors: %-"PRIu64"\n", stats.ierrors);
11227 	printf("  RX-nombuf:  %-10"PRIu64"\n",
11228 	       stats.rx_nombuf);
11229 	printf("  TX-packets: %-10"PRIu64" TX-errors: %-10"PRIu64" TX-bytes:  "
11230 	       "%-"PRIu64"\n",
11231 	       stats.opackets, stats.oerrors, stats.obytes);
11232 
11233 	printf("  %s############################%s\n",
11234 			       nic_stats_border, nic_stats_border);
11235 }
11236 
11237 static cmdline_parse_inst_t cmd_show_vf_stats = {
11238 	.f = cmd_show_vf_stats_parsed,
11239 	.data = NULL,
11240 	.help_str = "show vf stats <port_id> <vf_id>",
11241 	.tokens = {
11242 		(void *)&cmd_show_vf_stats_show,
11243 		(void *)&cmd_show_vf_stats_vf,
11244 		(void *)&cmd_show_vf_stats_stats,
11245 		(void *)&cmd_show_vf_stats_port_id,
11246 		(void *)&cmd_show_vf_stats_vf_id,
11247 		NULL,
11248 	},
11249 };
11250 
11251 /* clear vf stats */
11252 
11253 /* Common result structure for clear vf stats */
11254 struct cmd_clear_vf_stats_result {
11255 	cmdline_fixed_string_t clear;
11256 	cmdline_fixed_string_t vf;
11257 	cmdline_fixed_string_t stats;
11258 	portid_t port_id;
11259 	uint16_t vf_id;
11260 };
11261 
11262 /* Common CLI fields clear vf stats*/
11263 static cmdline_parse_token_string_t cmd_clear_vf_stats_clear =
11264 	TOKEN_STRING_INITIALIZER
11265 		(struct cmd_clear_vf_stats_result,
11266 		 clear, "clear");
11267 static cmdline_parse_token_string_t cmd_clear_vf_stats_vf =
11268 	TOKEN_STRING_INITIALIZER
11269 		(struct cmd_clear_vf_stats_result,
11270 		 vf, "vf");
11271 static cmdline_parse_token_string_t cmd_clear_vf_stats_stats =
11272 	TOKEN_STRING_INITIALIZER
11273 		(struct cmd_clear_vf_stats_result,
11274 		 stats, "stats");
11275 static cmdline_parse_token_num_t cmd_clear_vf_stats_port_id =
11276 	TOKEN_NUM_INITIALIZER
11277 		(struct cmd_clear_vf_stats_result,
11278 		 port_id, RTE_UINT16);
11279 static cmdline_parse_token_num_t cmd_clear_vf_stats_vf_id =
11280 	TOKEN_NUM_INITIALIZER
11281 		(struct cmd_clear_vf_stats_result,
11282 		 vf_id, RTE_UINT16);
11283 
11284 static void
11285 cmd_clear_vf_stats_parsed(
11286 	void *parsed_result,
11287 	__rte_unused struct cmdline *cl,
11288 	__rte_unused void *data)
11289 {
11290 	struct cmd_clear_vf_stats_result *res = parsed_result;
11291 	int ret = -ENOTSUP;
11292 
11293 	if (port_id_is_invalid(res->port_id, ENABLED_WARN))
11294 		return;
11295 
11296 #ifdef RTE_NET_I40E
11297 	if (ret == -ENOTSUP)
11298 		ret = rte_pmd_i40e_reset_vf_stats(res->port_id,
11299 						  res->vf_id);
11300 #endif
11301 #ifdef RTE_NET_BNXT
11302 	if (ret == -ENOTSUP)
11303 		ret = rte_pmd_bnxt_reset_vf_stats(res->port_id,
11304 						  res->vf_id);
11305 #endif
11306 
11307 	switch (ret) {
11308 	case 0:
11309 		break;
11310 	case -EINVAL:
11311 		fprintf(stderr, "invalid vf_id %d\n", res->vf_id);
11312 		break;
11313 	case -ENODEV:
11314 		fprintf(stderr, "invalid port_id %d\n", res->port_id);
11315 		break;
11316 	case -ENOTSUP:
11317 		fprintf(stderr, "function not implemented\n");
11318 		break;
11319 	default:
11320 		fprintf(stderr, "programming error: (%s)\n", strerror(-ret));
11321 	}
11322 }
11323 
11324 static cmdline_parse_inst_t cmd_clear_vf_stats = {
11325 	.f = cmd_clear_vf_stats_parsed,
11326 	.data = NULL,
11327 	.help_str = "clear vf stats <port_id> <vf_id>",
11328 	.tokens = {
11329 		(void *)&cmd_clear_vf_stats_clear,
11330 		(void *)&cmd_clear_vf_stats_vf,
11331 		(void *)&cmd_clear_vf_stats_stats,
11332 		(void *)&cmd_clear_vf_stats_port_id,
11333 		(void *)&cmd_clear_vf_stats_vf_id,
11334 		NULL,
11335 	},
11336 };
11337 
11338 /* Common result structure for file commands */
11339 struct cmd_cmdfile_result {
11340 	cmdline_fixed_string_t load;
11341 	cmdline_fixed_string_t filename;
11342 };
11343 
11344 /* Common CLI fields for file commands */
11345 static cmdline_parse_token_string_t cmd_load_cmdfile =
11346 	TOKEN_STRING_INITIALIZER(struct cmd_cmdfile_result, load, "load");
11347 static cmdline_parse_token_string_t cmd_load_cmdfile_filename =
11348 	TOKEN_STRING_INITIALIZER(struct cmd_cmdfile_result, filename, NULL);
11349 
11350 static void
11351 cmd_load_from_file_parsed(
11352 	void *parsed_result,
11353 	__rte_unused struct cmdline *cl,
11354 	__rte_unused void *data)
11355 {
11356 	struct cmd_cmdfile_result *res = parsed_result;
11357 
11358 	cmdline_read_from_file(res->filename);
11359 }
11360 
11361 static cmdline_parse_inst_t cmd_load_from_file = {
11362 	.f = cmd_load_from_file_parsed,
11363 	.data = NULL,
11364 	.help_str = "load <filename>",
11365 	.tokens = {
11366 		(void *)&cmd_load_cmdfile,
11367 		(void *)&cmd_load_cmdfile_filename,
11368 		NULL,
11369 	},
11370 };
11371 
11372 /* Get Rx offloads capabilities */
11373 struct cmd_rx_offload_get_capa_result {
11374 	cmdline_fixed_string_t show;
11375 	cmdline_fixed_string_t port;
11376 	portid_t port_id;
11377 	cmdline_fixed_string_t rx_offload;
11378 	cmdline_fixed_string_t capabilities;
11379 };
11380 
11381 static cmdline_parse_token_string_t cmd_rx_offload_get_capa_show =
11382 	TOKEN_STRING_INITIALIZER
11383 		(struct cmd_rx_offload_get_capa_result,
11384 		 show, "show");
11385 static cmdline_parse_token_string_t cmd_rx_offload_get_capa_port =
11386 	TOKEN_STRING_INITIALIZER
11387 		(struct cmd_rx_offload_get_capa_result,
11388 		 port, "port");
11389 static cmdline_parse_token_num_t cmd_rx_offload_get_capa_port_id =
11390 	TOKEN_NUM_INITIALIZER
11391 		(struct cmd_rx_offload_get_capa_result,
11392 		 port_id, RTE_UINT16);
11393 static cmdline_parse_token_string_t cmd_rx_offload_get_capa_rx_offload =
11394 	TOKEN_STRING_INITIALIZER
11395 		(struct cmd_rx_offload_get_capa_result,
11396 		 rx_offload, "rx_offload");
11397 static cmdline_parse_token_string_t cmd_rx_offload_get_capa_capabilities =
11398 	TOKEN_STRING_INITIALIZER
11399 		(struct cmd_rx_offload_get_capa_result,
11400 		 capabilities, "capabilities");
11401 
11402 static void
11403 print_rx_offloads(uint64_t offloads)
11404 {
11405 	uint64_t single_offload;
11406 	int begin;
11407 	int end;
11408 	int bit;
11409 
11410 	if (offloads == 0)
11411 		return;
11412 
11413 	begin = rte_ctz64(offloads);
11414 	end = sizeof(offloads) * CHAR_BIT - rte_clz64(offloads);
11415 
11416 	single_offload = 1ULL << begin;
11417 	for (bit = begin; bit < end; bit++) {
11418 		if (offloads & single_offload)
11419 			printf(" %s",
11420 			       rte_eth_dev_rx_offload_name(single_offload));
11421 		single_offload <<= 1;
11422 	}
11423 }
11424 
11425 static void
11426 cmd_rx_offload_get_capa_parsed(
11427 	void *parsed_result,
11428 	__rte_unused struct cmdline *cl,
11429 	__rte_unused void *data)
11430 {
11431 	struct cmd_rx_offload_get_capa_result *res = parsed_result;
11432 	struct rte_eth_dev_info dev_info;
11433 	portid_t port_id = res->port_id;
11434 	uint64_t queue_offloads;
11435 	uint64_t port_offloads;
11436 	int ret;
11437 
11438 	ret = eth_dev_info_get_print_err(port_id, &dev_info);
11439 	if (ret != 0)
11440 		return;
11441 
11442 	queue_offloads = dev_info.rx_queue_offload_capa;
11443 	port_offloads = dev_info.rx_offload_capa ^ queue_offloads;
11444 
11445 	printf("Rx Offloading Capabilities of port %d :\n", port_id);
11446 	printf("  Per Queue :");
11447 	print_rx_offloads(queue_offloads);
11448 
11449 	printf("\n");
11450 	printf("  Per Port  :");
11451 	print_rx_offloads(port_offloads);
11452 	printf("\n\n");
11453 }
11454 
11455 static cmdline_parse_inst_t cmd_rx_offload_get_capa = {
11456 	.f = cmd_rx_offload_get_capa_parsed,
11457 	.data = NULL,
11458 	.help_str = "show port <port_id> rx_offload capabilities",
11459 	.tokens = {
11460 		(void *)&cmd_rx_offload_get_capa_show,
11461 		(void *)&cmd_rx_offload_get_capa_port,
11462 		(void *)&cmd_rx_offload_get_capa_port_id,
11463 		(void *)&cmd_rx_offload_get_capa_rx_offload,
11464 		(void *)&cmd_rx_offload_get_capa_capabilities,
11465 		NULL,
11466 	}
11467 };
11468 
11469 /* Get Rx offloads configuration */
11470 struct cmd_rx_offload_get_configuration_result {
11471 	cmdline_fixed_string_t show;
11472 	cmdline_fixed_string_t port;
11473 	portid_t port_id;
11474 	cmdline_fixed_string_t rx_offload;
11475 	cmdline_fixed_string_t configuration;
11476 };
11477 
11478 static cmdline_parse_token_string_t cmd_rx_offload_get_configuration_show =
11479 	TOKEN_STRING_INITIALIZER
11480 		(struct cmd_rx_offload_get_configuration_result,
11481 		 show, "show");
11482 static cmdline_parse_token_string_t cmd_rx_offload_get_configuration_port =
11483 	TOKEN_STRING_INITIALIZER
11484 		(struct cmd_rx_offload_get_configuration_result,
11485 		 port, "port");
11486 static cmdline_parse_token_num_t cmd_rx_offload_get_configuration_port_id =
11487 	TOKEN_NUM_INITIALIZER
11488 		(struct cmd_rx_offload_get_configuration_result,
11489 		 port_id, RTE_UINT16);
11490 static cmdline_parse_token_string_t cmd_rx_offload_get_configuration_rx_offload =
11491 	TOKEN_STRING_INITIALIZER
11492 		(struct cmd_rx_offload_get_configuration_result,
11493 		 rx_offload, "rx_offload");
11494 static cmdline_parse_token_string_t cmd_rx_offload_get_configuration_configuration =
11495 	TOKEN_STRING_INITIALIZER
11496 		(struct cmd_rx_offload_get_configuration_result,
11497 		 configuration, "configuration");
11498 
11499 static void
11500 cmd_rx_offload_get_configuration_parsed(
11501 	void *parsed_result,
11502 	__rte_unused struct cmdline *cl,
11503 	__rte_unused void *data)
11504 {
11505 	struct cmd_rx_offload_get_configuration_result *res = parsed_result;
11506 	struct rte_eth_dev_info dev_info;
11507 	portid_t port_id = res->port_id;
11508 	struct rte_port *port = &ports[port_id];
11509 	struct rte_eth_conf dev_conf;
11510 	uint64_t port_offloads;
11511 	uint64_t queue_offloads;
11512 	uint16_t nb_rx_queues;
11513 	int q;
11514 	int ret;
11515 
11516 	printf("Rx Offloading Configuration of port %d :\n", port_id);
11517 
11518 	ret = eth_dev_conf_get_print_err(port_id, &dev_conf);
11519 	if (ret != 0)
11520 		return;
11521 
11522 	port_offloads = dev_conf.rxmode.offloads;
11523 	printf("  Port :");
11524 	print_rx_offloads(port_offloads);
11525 	printf("\n");
11526 
11527 	ret = eth_dev_info_get_print_err(port_id, &dev_info);
11528 	if (ret != 0)
11529 		return;
11530 
11531 	nb_rx_queues = dev_info.nb_rx_queues;
11532 	for (q = 0; q < nb_rx_queues; q++) {
11533 		queue_offloads = port->rxq[q].conf.offloads;
11534 		printf("  Queue[%2d] :", q);
11535 		print_rx_offloads(queue_offloads);
11536 		printf("\n");
11537 	}
11538 	printf("\n");
11539 }
11540 
11541 static cmdline_parse_inst_t cmd_rx_offload_get_configuration = {
11542 	.f = cmd_rx_offload_get_configuration_parsed,
11543 	.data = NULL,
11544 	.help_str = "show port <port_id> rx_offload configuration",
11545 	.tokens = {
11546 		(void *)&cmd_rx_offload_get_configuration_show,
11547 		(void *)&cmd_rx_offload_get_configuration_port,
11548 		(void *)&cmd_rx_offload_get_configuration_port_id,
11549 		(void *)&cmd_rx_offload_get_configuration_rx_offload,
11550 		(void *)&cmd_rx_offload_get_configuration_configuration,
11551 		NULL,
11552 	}
11553 };
11554 
11555 /* Enable/Disable a per port offloading */
11556 struct cmd_config_per_port_rx_offload_result {
11557 	cmdline_fixed_string_t port;
11558 	cmdline_fixed_string_t config;
11559 	portid_t port_id;
11560 	cmdline_fixed_string_t rx_offload;
11561 	cmdline_fixed_string_t offload;
11562 	cmdline_fixed_string_t on_off;
11563 };
11564 
11565 static cmdline_parse_token_string_t cmd_config_per_port_rx_offload_result_port =
11566 	TOKEN_STRING_INITIALIZER
11567 		(struct cmd_config_per_port_rx_offload_result,
11568 		 port, "port");
11569 static cmdline_parse_token_string_t cmd_config_per_port_rx_offload_result_config =
11570 	TOKEN_STRING_INITIALIZER
11571 		(struct cmd_config_per_port_rx_offload_result,
11572 		 config, "config");
11573 static cmdline_parse_token_num_t cmd_config_per_port_rx_offload_result_port_id =
11574 	TOKEN_NUM_INITIALIZER
11575 		(struct cmd_config_per_port_rx_offload_result,
11576 		 port_id, RTE_UINT16);
11577 static cmdline_parse_token_string_t cmd_config_per_port_rx_offload_result_rx_offload =
11578 	TOKEN_STRING_INITIALIZER
11579 		(struct cmd_config_per_port_rx_offload_result,
11580 		 rx_offload, "rx_offload");
11581 static cmdline_parse_token_string_t cmd_config_per_port_rx_offload_result_offload =
11582 	TOKEN_STRING_INITIALIZER
11583 		(struct cmd_config_per_port_rx_offload_result,
11584 		 offload, "all#vlan_strip#ipv4_cksum#udp_cksum#tcp_cksum#tcp_lro#"
11585 			   "qinq_strip#outer_ipv4_cksum#macsec_strip#"
11586 			   "vlan_filter#vlan_extend#"
11587 			   "scatter#buffer_split#timestamp#security#"
11588 			   "keep_crc#rss_hash");
11589 static cmdline_parse_token_string_t cmd_config_per_port_rx_offload_result_on_off =
11590 	TOKEN_STRING_INITIALIZER
11591 		(struct cmd_config_per_port_rx_offload_result,
11592 		 on_off, "on#off");
11593 
11594 static uint64_t
11595 search_rx_offload(const char *name)
11596 {
11597 	uint64_t single_offload;
11598 	const char *single_name;
11599 	int found = 0;
11600 	unsigned int bit;
11601 
11602 	single_offload = 1;
11603 	for (bit = 0; bit < sizeof(single_offload) * CHAR_BIT; bit++) {
11604 		single_name = rte_eth_dev_rx_offload_name(single_offload);
11605 		if (!strcasecmp(single_name, name)) {
11606 			found = 1;
11607 			break;
11608 		}
11609 		single_offload <<= 1;
11610 	}
11611 
11612 	if (found)
11613 		return single_offload;
11614 
11615 	return 0;
11616 }
11617 
11618 static void
11619 config_port_rx_offload(portid_t port_id, char *name, bool on)
11620 {
11621 	struct rte_eth_dev_info dev_info;
11622 	struct rte_port *port = &ports[port_id];
11623 	uint16_t nb_rx_queues;
11624 	uint64_t offload;
11625 	int q;
11626 	int ret;
11627 
11628 	if (port->port_status != RTE_PORT_STOPPED) {
11629 		fprintf(stderr,
11630 			"Error: Can't config offload when Port %d is not stopped\n",
11631 			port_id);
11632 		return;
11633 	}
11634 
11635 	ret = eth_dev_info_get_print_err(port_id, &dev_info);
11636 	if (ret != 0)
11637 		return;
11638 
11639 	if (!strcmp(name, "all")) {
11640 		offload = dev_info.rx_offload_capa;
11641 	} else {
11642 		offload = search_rx_offload(name);
11643 		if (offload == 0) {
11644 			fprintf(stderr, "Unknown offload name: %s\n", name);
11645 			return;
11646 		}
11647 		if ((offload & dev_info.rx_offload_capa) == 0) {
11648 			fprintf(stderr, "Error: port %u doesn't support offload: %s.\n",
11649 				port_id, name);
11650 			return;
11651 		}
11652 	}
11653 
11654 	nb_rx_queues = dev_info.nb_rx_queues;
11655 	if (on) {
11656 		port->dev_conf.rxmode.offloads |= offload;
11657 		for (q = 0; q < nb_rx_queues; q++)
11658 			port->rxq[q].conf.offloads |= offload;
11659 	} else {
11660 		port->dev_conf.rxmode.offloads &= ~offload;
11661 		for (q = 0; q < nb_rx_queues; q++)
11662 			port->rxq[q].conf.offloads &= ~offload;
11663 	}
11664 
11665 	cmd_reconfig_device_queue(port_id, 1, 1);
11666 }
11667 
11668 static void
11669 cmd_config_per_port_rx_offload_parsed(void *parsed_result,
11670 				__rte_unused struct cmdline *cl,
11671 				__rte_unused void *data)
11672 {
11673 	struct cmd_config_per_port_rx_offload_result *res = parsed_result;
11674 	bool on;
11675 
11676 	on = strcmp(res->on_off, "on") == 0;
11677 	config_port_rx_offload(res->port_id, res->offload, on);
11678 }
11679 
11680 static cmdline_parse_inst_t cmd_config_per_port_rx_offload = {
11681 	.f = cmd_config_per_port_rx_offload_parsed,
11682 	.data = NULL,
11683 	.help_str = "port config <port_id> rx_offload all|vlan_strip|ipv4_cksum|"
11684 		    "udp_cksum|tcp_cksum|tcp_lro|qinq_strip|outer_ipv4_cksum|"
11685 		    "macsec_strip|vlan_filter|vlan_extend|"
11686 		    "scatter|buffer_split|timestamp|security|"
11687 		    "keep_crc|rss_hash on|off",
11688 	.tokens = {
11689 		(void *)&cmd_config_per_port_rx_offload_result_port,
11690 		(void *)&cmd_config_per_port_rx_offload_result_config,
11691 		(void *)&cmd_config_per_port_rx_offload_result_port_id,
11692 		(void *)&cmd_config_per_port_rx_offload_result_rx_offload,
11693 		(void *)&cmd_config_per_port_rx_offload_result_offload,
11694 		(void *)&cmd_config_per_port_rx_offload_result_on_off,
11695 		NULL,
11696 	}
11697 };
11698 
11699 /* Enable/Disable all port Rx offloading */
11700 struct cmd_config_all_port_rx_offload_result {
11701 	cmdline_fixed_string_t port;
11702 	cmdline_fixed_string_t config;
11703 	cmdline_fixed_string_t port_all;
11704 	cmdline_fixed_string_t rx_offload;
11705 	cmdline_fixed_string_t offload;
11706 	cmdline_fixed_string_t on_off;
11707 };
11708 
11709 static cmdline_parse_token_string_t cmd_config_all_port_rx_offload_result_port =
11710 	TOKEN_STRING_INITIALIZER
11711 		(struct cmd_config_all_port_rx_offload_result,
11712 		 port, "port");
11713 static cmdline_parse_token_string_t cmd_config_all_port_rx_offload_result_config =
11714 	TOKEN_STRING_INITIALIZER
11715 		(struct cmd_config_all_port_rx_offload_result,
11716 		 config, "config");
11717 
11718 static cmdline_parse_token_string_t cmd_config_all_port_rx_offload_result_port_all =
11719 	TOKEN_STRING_INITIALIZER(struct cmd_config_all_port_rx_offload_result,
11720 				 port_all, "all");
11721 static cmdline_parse_token_string_t cmd_config_all_port_rx_offload_result_rx_offload =
11722 	TOKEN_STRING_INITIALIZER
11723 		(struct cmd_config_all_port_rx_offload_result,
11724 		 rx_offload, "rx_offload");
11725 static cmdline_parse_token_string_t cmd_config_all_port_rx_offload_result_offload =
11726 	TOKEN_STRING_INITIALIZER
11727 		(struct cmd_config_all_port_rx_offload_result,
11728 		 offload, "all#vlan_strip#ipv4_cksum#udp_cksum#tcp_cksum#tcp_lro#"
11729 			   "qinq_strip#outer_ipv4_cksum#macsec_strip#"
11730 			   "vlan_filter#vlan_extend#"
11731 			   "scatter#buffer_split#timestamp#security#"
11732 			   "keep_crc#rss_hash");
11733 static cmdline_parse_token_string_t cmd_config_all_port_rx_offload_result_on_off =
11734 	TOKEN_STRING_INITIALIZER
11735 		(struct cmd_config_all_port_rx_offload_result,
11736 		 on_off, "on#off");
11737 
11738 static void
11739 cmd_config_all_port_rx_offload_parsed(void *parsed_result,
11740 				__rte_unused struct cmdline *cl,
11741 				__rte_unused void *data)
11742 {
11743 	struct cmd_config_all_port_rx_offload_result *res = parsed_result;
11744 	bool on_off;
11745 	portid_t i;
11746 
11747 	on_off = strcmp(res->on_off, "on") == 0;
11748 	RTE_ETH_FOREACH_DEV(i)
11749 		config_port_rx_offload(i, res->offload, on_off);
11750 
11751 }
11752 
11753 static cmdline_parse_inst_t cmd_config_all_port_rx_offload = {
11754 	.f = cmd_config_all_port_rx_offload_parsed,
11755 	.data = NULL,
11756 	.help_str = "port config all rx_offload all|vlan_strip|ipv4_cksum|"
11757 		    "udp_cksum|tcp_cksum|tcp_lro|qinq_strip|outer_ipv4_cksum|"
11758 		    "macsec_strip|vlan_filter|vlan_extend|"
11759 		    "scatter|buffer_split|timestamp|security|"
11760 		    "keep_crc|rss_hash on|off",
11761 	.tokens = {
11762 		(void *)&cmd_config_all_port_rx_offload_result_port,
11763 		(void *)&cmd_config_all_port_rx_offload_result_config,
11764 		(void *)&cmd_config_all_port_rx_offload_result_port_all,
11765 		(void *)&cmd_config_all_port_rx_offload_result_rx_offload,
11766 		(void *)&cmd_config_all_port_rx_offload_result_offload,
11767 		(void *)&cmd_config_all_port_rx_offload_result_on_off,
11768 		NULL,
11769 	}
11770 };
11771 
11772 /* Enable/Disable a per queue offloading */
11773 struct cmd_config_per_queue_rx_offload_result {
11774 	cmdline_fixed_string_t port;
11775 	portid_t port_id;
11776 	cmdline_fixed_string_t rxq;
11777 	uint16_t queue_id;
11778 	cmdline_fixed_string_t rx_offload;
11779 	cmdline_fixed_string_t offload;
11780 	cmdline_fixed_string_t on_off;
11781 };
11782 
11783 static cmdline_parse_token_string_t cmd_config_per_queue_rx_offload_result_port =
11784 	TOKEN_STRING_INITIALIZER
11785 		(struct cmd_config_per_queue_rx_offload_result,
11786 		 port, "port");
11787 static cmdline_parse_token_num_t cmd_config_per_queue_rx_offload_result_port_id =
11788 	TOKEN_NUM_INITIALIZER
11789 		(struct cmd_config_per_queue_rx_offload_result,
11790 		 port_id, RTE_UINT16);
11791 static cmdline_parse_token_string_t cmd_config_per_queue_rx_offload_result_rxq =
11792 	TOKEN_STRING_INITIALIZER
11793 		(struct cmd_config_per_queue_rx_offload_result,
11794 		 rxq, "rxq");
11795 static cmdline_parse_token_num_t cmd_config_per_queue_rx_offload_result_queue_id =
11796 	TOKEN_NUM_INITIALIZER
11797 		(struct cmd_config_per_queue_rx_offload_result,
11798 		 queue_id, RTE_UINT16);
11799 static cmdline_parse_token_string_t cmd_config_per_queue_rx_offload_result_rxoffload =
11800 	TOKEN_STRING_INITIALIZER
11801 		(struct cmd_config_per_queue_rx_offload_result,
11802 		 rx_offload, "rx_offload");
11803 static cmdline_parse_token_string_t cmd_config_per_queue_rx_offload_result_offload =
11804 	TOKEN_STRING_INITIALIZER
11805 		(struct cmd_config_per_queue_rx_offload_result,
11806 		 offload, "all#vlan_strip#ipv4_cksum#udp_cksum#tcp_cksum#tcp_lro#"
11807 			   "qinq_strip#outer_ipv4_cksum#macsec_strip#"
11808 			   "vlan_filter#vlan_extend#"
11809 			   "scatter#buffer_split#timestamp#security#keep_crc");
11810 static cmdline_parse_token_string_t cmd_config_per_queue_rx_offload_result_on_off =
11811 	TOKEN_STRING_INITIALIZER
11812 		(struct cmd_config_per_queue_rx_offload_result,
11813 		 on_off, "on#off");
11814 
11815 static void
11816 cmd_config_per_queue_rx_offload_parsed(void *parsed_result,
11817 				__rte_unused struct cmdline *cl,
11818 				__rte_unused void *data)
11819 {
11820 	struct cmd_config_per_queue_rx_offload_result *res = parsed_result;
11821 	struct rte_eth_dev_info dev_info;
11822 	portid_t port_id = res->port_id;
11823 	uint16_t queue_id = res->queue_id;
11824 	struct rte_port *port = &ports[port_id];
11825 	uint64_t offload;
11826 	int ret;
11827 
11828 	if (port->port_status != RTE_PORT_STOPPED) {
11829 		fprintf(stderr,
11830 			"Error: Can't config offload when Port %d is not stopped\n",
11831 			port_id);
11832 		return;
11833 	}
11834 
11835 	ret = eth_dev_info_get_print_err(port_id, &dev_info);
11836 	if (ret != 0)
11837 		return;
11838 
11839 	if (queue_id >= dev_info.nb_rx_queues) {
11840 		fprintf(stderr,
11841 			"Error: input queue_id should be 0 ... %d\n",
11842 			dev_info.nb_rx_queues - 1);
11843 		return;
11844 	}
11845 
11846 	if (!strcmp(res->offload, "all")) {
11847 		offload = dev_info.rx_queue_offload_capa;
11848 	} else {
11849 		offload = search_rx_offload(res->offload);
11850 		if (offload == 0) {
11851 			fprintf(stderr, "Unknown offload name: %s\n", res->offload);
11852 			return;
11853 		}
11854 		if ((offload & dev_info.rx_queue_offload_capa) == 0) {
11855 			fprintf(stderr, "Error: port %u doesn't support per queue offload: %s.\n",
11856 				port_id, res->offload);
11857 			return;
11858 		}
11859 	}
11860 
11861 	if (!strcmp(res->on_off, "on"))
11862 		port->rxq[queue_id].conf.offloads |= offload;
11863 	else
11864 		port->rxq[queue_id].conf.offloads &= ~offload;
11865 
11866 	cmd_reconfig_device_queue(port_id, 1, 1);
11867 }
11868 
11869 static cmdline_parse_inst_t cmd_config_per_queue_rx_offload = {
11870 	.f = cmd_config_per_queue_rx_offload_parsed,
11871 	.data = NULL,
11872 	.help_str = "port <port_id> rxq <queue_id> rx_offload "
11873 		    "all|vlan_strip|ipv4_cksum|"
11874 		    "udp_cksum|tcp_cksum|tcp_lro|qinq_strip|outer_ipv4_cksum|"
11875 		    "macsec_strip|vlan_filter|vlan_extend|"
11876 		    "scatter|buffer_split|timestamp|security|"
11877 		    "keep_crc on|off",
11878 	.tokens = {
11879 		(void *)&cmd_config_per_queue_rx_offload_result_port,
11880 		(void *)&cmd_config_per_queue_rx_offload_result_port_id,
11881 		(void *)&cmd_config_per_queue_rx_offload_result_rxq,
11882 		(void *)&cmd_config_per_queue_rx_offload_result_queue_id,
11883 		(void *)&cmd_config_per_queue_rx_offload_result_rxoffload,
11884 		(void *)&cmd_config_per_queue_rx_offload_result_offload,
11885 		(void *)&cmd_config_per_queue_rx_offload_result_on_off,
11886 		NULL,
11887 	}
11888 };
11889 
11890 /* Get Tx offloads capabilities */
11891 struct cmd_tx_offload_get_capa_result {
11892 	cmdline_fixed_string_t show;
11893 	cmdline_fixed_string_t port;
11894 	portid_t port_id;
11895 	cmdline_fixed_string_t tx_offload;
11896 	cmdline_fixed_string_t capabilities;
11897 };
11898 
11899 static cmdline_parse_token_string_t cmd_tx_offload_get_capa_show =
11900 	TOKEN_STRING_INITIALIZER
11901 		(struct cmd_tx_offload_get_capa_result,
11902 		 show, "show");
11903 static cmdline_parse_token_string_t cmd_tx_offload_get_capa_port =
11904 	TOKEN_STRING_INITIALIZER
11905 		(struct cmd_tx_offload_get_capa_result,
11906 		 port, "port");
11907 static cmdline_parse_token_num_t cmd_tx_offload_get_capa_port_id =
11908 	TOKEN_NUM_INITIALIZER
11909 		(struct cmd_tx_offload_get_capa_result,
11910 		 port_id, RTE_UINT16);
11911 static cmdline_parse_token_string_t cmd_tx_offload_get_capa_tx_offload =
11912 	TOKEN_STRING_INITIALIZER
11913 		(struct cmd_tx_offload_get_capa_result,
11914 		 tx_offload, "tx_offload");
11915 static cmdline_parse_token_string_t cmd_tx_offload_get_capa_capabilities =
11916 	TOKEN_STRING_INITIALIZER
11917 		(struct cmd_tx_offload_get_capa_result,
11918 		 capabilities, "capabilities");
11919 
11920 static void
11921 print_tx_offloads(uint64_t offloads)
11922 {
11923 	uint64_t single_offload;
11924 	int begin;
11925 	int end;
11926 	int bit;
11927 
11928 	if (offloads == 0)
11929 		return;
11930 
11931 	begin = rte_ctz64(offloads);
11932 	end = sizeof(offloads) * CHAR_BIT - rte_clz64(offloads);
11933 
11934 	single_offload = 1ULL << begin;
11935 	for (bit = begin; bit < end; bit++) {
11936 		if (offloads & single_offload)
11937 			printf(" %s",
11938 			       rte_eth_dev_tx_offload_name(single_offload));
11939 		single_offload <<= 1;
11940 	}
11941 }
11942 
11943 static void
11944 cmd_tx_offload_get_capa_parsed(
11945 	void *parsed_result,
11946 	__rte_unused struct cmdline *cl,
11947 	__rte_unused void *data)
11948 {
11949 	struct cmd_tx_offload_get_capa_result *res = parsed_result;
11950 	struct rte_eth_dev_info dev_info;
11951 	portid_t port_id = res->port_id;
11952 	uint64_t queue_offloads;
11953 	uint64_t port_offloads;
11954 	int ret;
11955 
11956 	ret = eth_dev_info_get_print_err(port_id, &dev_info);
11957 	if (ret != 0)
11958 		return;
11959 
11960 	queue_offloads = dev_info.tx_queue_offload_capa;
11961 	port_offloads = dev_info.tx_offload_capa ^ queue_offloads;
11962 
11963 	printf("Tx Offloading Capabilities of port %d :\n", port_id);
11964 	printf("  Per Queue :");
11965 	print_tx_offloads(queue_offloads);
11966 
11967 	printf("\n");
11968 	printf("  Per Port  :");
11969 	print_tx_offloads(port_offloads);
11970 	printf("\n\n");
11971 }
11972 
11973 static cmdline_parse_inst_t cmd_tx_offload_get_capa = {
11974 	.f = cmd_tx_offload_get_capa_parsed,
11975 	.data = NULL,
11976 	.help_str = "show port <port_id> tx_offload capabilities",
11977 	.tokens = {
11978 		(void *)&cmd_tx_offload_get_capa_show,
11979 		(void *)&cmd_tx_offload_get_capa_port,
11980 		(void *)&cmd_tx_offload_get_capa_port_id,
11981 		(void *)&cmd_tx_offload_get_capa_tx_offload,
11982 		(void *)&cmd_tx_offload_get_capa_capabilities,
11983 		NULL,
11984 	}
11985 };
11986 
11987 /* Get Tx offloads configuration */
11988 struct cmd_tx_offload_get_configuration_result {
11989 	cmdline_fixed_string_t show;
11990 	cmdline_fixed_string_t port;
11991 	portid_t port_id;
11992 	cmdline_fixed_string_t tx_offload;
11993 	cmdline_fixed_string_t configuration;
11994 };
11995 
11996 static cmdline_parse_token_string_t cmd_tx_offload_get_configuration_show =
11997 	TOKEN_STRING_INITIALIZER
11998 		(struct cmd_tx_offload_get_configuration_result,
11999 		 show, "show");
12000 static cmdline_parse_token_string_t cmd_tx_offload_get_configuration_port =
12001 	TOKEN_STRING_INITIALIZER
12002 		(struct cmd_tx_offload_get_configuration_result,
12003 		 port, "port");
12004 static cmdline_parse_token_num_t cmd_tx_offload_get_configuration_port_id =
12005 	TOKEN_NUM_INITIALIZER
12006 		(struct cmd_tx_offload_get_configuration_result,
12007 		 port_id, RTE_UINT16);
12008 static cmdline_parse_token_string_t cmd_tx_offload_get_configuration_tx_offload =
12009 	TOKEN_STRING_INITIALIZER
12010 		(struct cmd_tx_offload_get_configuration_result,
12011 		 tx_offload, "tx_offload");
12012 static cmdline_parse_token_string_t cmd_tx_offload_get_configuration_configuration =
12013 	TOKEN_STRING_INITIALIZER
12014 		(struct cmd_tx_offload_get_configuration_result,
12015 		 configuration, "configuration");
12016 
12017 static void
12018 cmd_tx_offload_get_configuration_parsed(
12019 	void *parsed_result,
12020 	__rte_unused struct cmdline *cl,
12021 	__rte_unused void *data)
12022 {
12023 	struct cmd_tx_offload_get_configuration_result *res = parsed_result;
12024 	struct rte_eth_dev_info dev_info;
12025 	portid_t port_id = res->port_id;
12026 	struct rte_port *port = &ports[port_id];
12027 	struct rte_eth_conf dev_conf;
12028 	uint64_t port_offloads;
12029 	uint64_t queue_offloads;
12030 	uint16_t nb_tx_queues;
12031 	int q;
12032 	int ret;
12033 
12034 	printf("Tx Offloading Configuration of port %d :\n", port_id);
12035 
12036 	ret = eth_dev_conf_get_print_err(port_id, &dev_conf);
12037 	if (ret != 0)
12038 		return;
12039 
12040 	port_offloads = dev_conf.txmode.offloads;
12041 	printf("  Port :");
12042 	print_tx_offloads(port_offloads);
12043 	printf("\n");
12044 
12045 	ret = eth_dev_info_get_print_err(port_id, &dev_info);
12046 	if (ret != 0)
12047 		return;
12048 
12049 	nb_tx_queues = dev_info.nb_tx_queues;
12050 	for (q = 0; q < nb_tx_queues; q++) {
12051 		queue_offloads = port->txq[q].conf.offloads;
12052 		printf("  Queue[%2d] :", q);
12053 		print_tx_offloads(queue_offloads);
12054 		printf("\n");
12055 	}
12056 	printf("\n");
12057 }
12058 
12059 static cmdline_parse_inst_t cmd_tx_offload_get_configuration = {
12060 	.f = cmd_tx_offload_get_configuration_parsed,
12061 	.data = NULL,
12062 	.help_str = "show port <port_id> tx_offload configuration",
12063 	.tokens = {
12064 		(void *)&cmd_tx_offload_get_configuration_show,
12065 		(void *)&cmd_tx_offload_get_configuration_port,
12066 		(void *)&cmd_tx_offload_get_configuration_port_id,
12067 		(void *)&cmd_tx_offload_get_configuration_tx_offload,
12068 		(void *)&cmd_tx_offload_get_configuration_configuration,
12069 		NULL,
12070 	}
12071 };
12072 
12073 /* Enable/Disable a per port offloading */
12074 struct cmd_config_per_port_tx_offload_result {
12075 	cmdline_fixed_string_t port;
12076 	cmdline_fixed_string_t config;
12077 	portid_t port_id;
12078 	cmdline_fixed_string_t tx_offload;
12079 	cmdline_fixed_string_t offload;
12080 	cmdline_fixed_string_t on_off;
12081 };
12082 
12083 static cmdline_parse_token_string_t cmd_config_per_port_tx_offload_result_port =
12084 	TOKEN_STRING_INITIALIZER
12085 		(struct cmd_config_per_port_tx_offload_result,
12086 		 port, "port");
12087 static cmdline_parse_token_string_t cmd_config_per_port_tx_offload_result_config =
12088 	TOKEN_STRING_INITIALIZER
12089 		(struct cmd_config_per_port_tx_offload_result,
12090 		 config, "config");
12091 static cmdline_parse_token_num_t cmd_config_per_port_tx_offload_result_port_id =
12092 	TOKEN_NUM_INITIALIZER
12093 		(struct cmd_config_per_port_tx_offload_result,
12094 		 port_id, RTE_UINT16);
12095 static cmdline_parse_token_string_t cmd_config_per_port_tx_offload_result_tx_offload =
12096 	TOKEN_STRING_INITIALIZER
12097 		(struct cmd_config_per_port_tx_offload_result,
12098 		 tx_offload, "tx_offload");
12099 static cmdline_parse_token_string_t cmd_config_per_port_tx_offload_result_offload =
12100 	TOKEN_STRING_INITIALIZER
12101 		(struct cmd_config_per_port_tx_offload_result,
12102 		 offload, "all#vlan_insert#ipv4_cksum#udp_cksum#tcp_cksum#"
12103 			  "sctp_cksum#tcp_tso#udp_tso#outer_ipv4_cksum#"
12104 			  "qinq_insert#vxlan_tnl_tso#gre_tnl_tso#"
12105 			  "ipip_tnl_tso#geneve_tnl_tso#macsec_insert#"
12106 			  "mt_lockfree#multi_segs#mbuf_fast_free#security#"
12107 			  "send_on_timestamp");
12108 static cmdline_parse_token_string_t cmd_config_per_port_tx_offload_result_on_off =
12109 	TOKEN_STRING_INITIALIZER
12110 		(struct cmd_config_per_port_tx_offload_result,
12111 		 on_off, "on#off");
12112 
12113 static uint64_t
12114 search_tx_offload(const char *name)
12115 {
12116 	uint64_t single_offload;
12117 	const char *single_name;
12118 	int found = 0;
12119 	unsigned int bit;
12120 
12121 	single_offload = 1;
12122 	for (bit = 0; bit < sizeof(single_offload) * CHAR_BIT; bit++) {
12123 		single_name = rte_eth_dev_tx_offload_name(single_offload);
12124 		if (single_name == NULL)
12125 			break;
12126 		if (!strcasecmp(single_name, name)) {
12127 			found = 1;
12128 			break;
12129 		} else if (!strcasecmp(single_name, "UNKNOWN"))
12130 			break;
12131 		single_offload <<= 1;
12132 	}
12133 
12134 	if (found)
12135 		return single_offload;
12136 
12137 	return 0;
12138 }
12139 
12140 static void
12141 config_port_tx_offload(portid_t port_id, char *name, bool on)
12142 {
12143 	struct rte_eth_dev_info dev_info;
12144 	struct rte_port *port = &ports[port_id];
12145 	uint16_t nb_tx_queues;
12146 	uint64_t offload;
12147 	int q;
12148 	int ret;
12149 
12150 	if (port->port_status != RTE_PORT_STOPPED) {
12151 		fprintf(stderr,
12152 			"Error: Can't config offload when Port %d is not stopped\n",
12153 			port_id);
12154 		return;
12155 	}
12156 
12157 	ret = eth_dev_info_get_print_err(port_id, &dev_info);
12158 	if (ret != 0)
12159 		return;
12160 
12161 	if (!strcmp(name, "all")) {
12162 		offload = dev_info.tx_offload_capa;
12163 	} else {
12164 		offload = search_tx_offload(name);
12165 		if (offload == 0) {
12166 			fprintf(stderr, "Unknown offload name: %s\n", name);
12167 			return;
12168 		}
12169 		if ((offload & dev_info.tx_offload_capa) == 0) {
12170 			fprintf(stderr, "Error: port %u doesn't support offload: %s.\n",
12171 				port_id, name);
12172 			return;
12173 		}
12174 	}
12175 
12176 	nb_tx_queues = dev_info.nb_tx_queues;
12177 	if (on) {
12178 		port->dev_conf.txmode.offloads |= offload;
12179 		for (q = 0; q < nb_tx_queues; q++)
12180 			port->txq[q].conf.offloads |= offload;
12181 	} else {
12182 		port->dev_conf.txmode.offloads &= ~offload;
12183 		for (q = 0; q < nb_tx_queues; q++)
12184 			port->txq[q].conf.offloads &= ~offload;
12185 	}
12186 
12187 	cmd_reconfig_device_queue(port_id, 1, 1);
12188 }
12189 
12190 static void
12191 cmd_config_per_port_tx_offload_parsed(void *parsed_result,
12192 				__rte_unused struct cmdline *cl,
12193 				__rte_unused void *data)
12194 {
12195 	struct cmd_config_per_port_tx_offload_result *res = parsed_result;
12196 	bool on;
12197 
12198 	on = strcmp(res->on_off, "on") == 0;
12199 	config_port_tx_offload(res->port_id, res->offload, on);
12200 }
12201 
12202 static cmdline_parse_inst_t cmd_config_per_port_tx_offload = {
12203 	.f = cmd_config_per_port_tx_offload_parsed,
12204 	.data = NULL,
12205 	.help_str = "port config <port_id> tx_offload "
12206 		    "all|vlan_insert|ipv4_cksum|udp_cksum|tcp_cksum|"
12207 		    "sctp_cksum|tcp_tso|udp_tso|outer_ipv4_cksum|"
12208 		    "qinq_insert|vxlan_tnl_tso|gre_tnl_tso|"
12209 		    "ipip_tnl_tso|geneve_tnl_tso|macsec_insert|"
12210 		    "mt_lockfree|multi_segs|mbuf_fast_free|security|"
12211 		    "send_on_timestamp on|off",
12212 	.tokens = {
12213 		(void *)&cmd_config_per_port_tx_offload_result_port,
12214 		(void *)&cmd_config_per_port_tx_offload_result_config,
12215 		(void *)&cmd_config_per_port_tx_offload_result_port_id,
12216 		(void *)&cmd_config_per_port_tx_offload_result_tx_offload,
12217 		(void *)&cmd_config_per_port_tx_offload_result_offload,
12218 		(void *)&cmd_config_per_port_tx_offload_result_on_off,
12219 		NULL,
12220 	}
12221 };
12222 
12223 /* Enable/Disable all port Tx offloading */
12224 struct cmd_config_all_port_tx_offload_result {
12225 	cmdline_fixed_string_t port;
12226 	cmdline_fixed_string_t config;
12227 	cmdline_fixed_string_t port_all;
12228 	cmdline_fixed_string_t tx_offload;
12229 	cmdline_fixed_string_t offload;
12230 	cmdline_fixed_string_t on_off;
12231 };
12232 
12233 static cmdline_parse_token_string_t cmd_config_all_port_tx_offload_result_port =
12234 	TOKEN_STRING_INITIALIZER
12235 		(struct cmd_config_all_port_tx_offload_result,
12236 		 port, "port");
12237 static cmdline_parse_token_string_t cmd_config_all_port_tx_offload_result_config =
12238 	TOKEN_STRING_INITIALIZER
12239 		(struct cmd_config_all_port_tx_offload_result,
12240 		 config, "config");
12241 static cmdline_parse_token_string_t cmd_config_all_port_tx_offload_result_port_all =
12242 	TOKEN_STRING_INITIALIZER(struct cmd_config_all_port_tx_offload_result,
12243 				 port_all, "all");
12244 static cmdline_parse_token_string_t cmd_config_all_port_tx_offload_result_tx_offload =
12245 	TOKEN_STRING_INITIALIZER
12246 		(struct cmd_config_all_port_tx_offload_result,
12247 		 tx_offload, "tx_offload");
12248 static cmdline_parse_token_string_t cmd_config_all_port_tx_offload_result_offload =
12249 	TOKEN_STRING_INITIALIZER
12250 		(struct cmd_config_all_port_tx_offload_result,
12251 		 offload, "all#vlan_insert#ipv4_cksum#udp_cksum#tcp_cksum#"
12252 			  "sctp_cksum#tcp_tso#udp_tso#outer_ipv4_cksum#"
12253 			  "qinq_insert#vxlan_tnl_tso#gre_tnl_tso#"
12254 			  "ipip_tnl_tso#geneve_tnl_tso#macsec_insert#"
12255 			  "mt_lockfree#multi_segs#mbuf_fast_free#security#"
12256 			  "send_on_timestamp");
12257 static cmdline_parse_token_string_t cmd_config_all_port_tx_offload_result_on_off =
12258 	TOKEN_STRING_INITIALIZER
12259 		(struct cmd_config_all_port_tx_offload_result,
12260 		 on_off, "on#off");
12261 
12262 static void
12263 cmd_config_all_port_tx_offload_parsed(void *parsed_result,
12264 				__rte_unused struct cmdline *cl,
12265 				__rte_unused void *data)
12266 {
12267 	struct cmd_config_all_port_tx_offload_result *res = parsed_result;
12268 	portid_t i;
12269 	bool on_off;
12270 
12271 	on_off = strcmp(res->on_off, "on") == 0;
12272 	RTE_ETH_FOREACH_DEV(i)
12273 		config_port_tx_offload(i, res->offload, on_off);
12274 }
12275 
12276 static cmdline_parse_inst_t cmd_config_all_port_tx_offload = {
12277 	.f = cmd_config_all_port_tx_offload_parsed,
12278 	.data = NULL,
12279 	.help_str = "port config all tx_offload "
12280 		    "all|vlan_insert|ipv4_cksum|udp_cksum|tcp_cksum|"
12281 		    "sctp_cksum|tcp_tso|udp_tso|outer_ipv4_cksum|"
12282 		    "qinq_insert|vxlan_tnl_tso|gre_tnl_tso|"
12283 		    "ipip_tnl_tso|geneve_tnl_tso|macsec_insert|"
12284 		    "mt_lockfree|multi_segs|mbuf_fast_free|security|"
12285 		    "send_on_timestamp on|off",
12286 	.tokens = {
12287 		(void *)&cmd_config_all_port_tx_offload_result_port,
12288 		(void *)&cmd_config_all_port_tx_offload_result_config,
12289 		(void *)&cmd_config_all_port_tx_offload_result_port_all,
12290 		(void *)&cmd_config_all_port_tx_offload_result_tx_offload,
12291 		(void *)&cmd_config_all_port_tx_offload_result_offload,
12292 		(void *)&cmd_config_all_port_tx_offload_result_on_off,
12293 		NULL,
12294 	}
12295 };
12296 
12297 /* Enable/Disable a per queue offloading */
12298 struct cmd_config_per_queue_tx_offload_result {
12299 	cmdline_fixed_string_t port;
12300 	portid_t port_id;
12301 	cmdline_fixed_string_t txq;
12302 	uint16_t queue_id;
12303 	cmdline_fixed_string_t tx_offload;
12304 	cmdline_fixed_string_t offload;
12305 	cmdline_fixed_string_t on_off;
12306 };
12307 
12308 static cmdline_parse_token_string_t cmd_config_per_queue_tx_offload_result_port =
12309 	TOKEN_STRING_INITIALIZER
12310 		(struct cmd_config_per_queue_tx_offload_result,
12311 		 port, "port");
12312 static cmdline_parse_token_num_t cmd_config_per_queue_tx_offload_result_port_id =
12313 	TOKEN_NUM_INITIALIZER
12314 		(struct cmd_config_per_queue_tx_offload_result,
12315 		 port_id, RTE_UINT16);
12316 static cmdline_parse_token_string_t cmd_config_per_queue_tx_offload_result_txq =
12317 	TOKEN_STRING_INITIALIZER
12318 		(struct cmd_config_per_queue_tx_offload_result,
12319 		 txq, "txq");
12320 static cmdline_parse_token_num_t cmd_config_per_queue_tx_offload_result_queue_id =
12321 	TOKEN_NUM_INITIALIZER
12322 		(struct cmd_config_per_queue_tx_offload_result,
12323 		 queue_id, RTE_UINT16);
12324 static cmdline_parse_token_string_t cmd_config_per_queue_tx_offload_result_txoffload =
12325 	TOKEN_STRING_INITIALIZER
12326 		(struct cmd_config_per_queue_tx_offload_result,
12327 		 tx_offload, "tx_offload");
12328 static cmdline_parse_token_string_t cmd_config_per_queue_tx_offload_result_offload =
12329 	TOKEN_STRING_INITIALIZER
12330 		(struct cmd_config_per_queue_tx_offload_result,
12331 		 offload, "all#vlan_insert#ipv4_cksum#udp_cksum#tcp_cksum#"
12332 			  "sctp_cksum#tcp_tso#udp_tso#outer_ipv4_cksum#"
12333 			  "qinq_insert#vxlan_tnl_tso#gre_tnl_tso#"
12334 			  "ipip_tnl_tso#geneve_tnl_tso#macsec_insert#"
12335 			  "mt_lockfree#multi_segs#mbuf_fast_free#security");
12336 static cmdline_parse_token_string_t cmd_config_per_queue_tx_offload_result_on_off =
12337 	TOKEN_STRING_INITIALIZER
12338 		(struct cmd_config_per_queue_tx_offload_result,
12339 		 on_off, "on#off");
12340 
12341 static void
12342 cmd_config_per_queue_tx_offload_parsed(void *parsed_result,
12343 				__rte_unused struct cmdline *cl,
12344 				__rte_unused void *data)
12345 {
12346 	struct cmd_config_per_queue_tx_offload_result *res = parsed_result;
12347 	struct rte_eth_dev_info dev_info;
12348 	portid_t port_id = res->port_id;
12349 	uint16_t queue_id = res->queue_id;
12350 	struct rte_port *port = &ports[port_id];
12351 	uint64_t offload;
12352 	int ret;
12353 
12354 	if (port->port_status != RTE_PORT_STOPPED) {
12355 		fprintf(stderr,
12356 			"Error: Can't config offload when Port %d is not stopped\n",
12357 			port_id);
12358 		return;
12359 	}
12360 
12361 	ret = eth_dev_info_get_print_err(port_id, &dev_info);
12362 	if (ret != 0)
12363 		return;
12364 
12365 	if (queue_id >= dev_info.nb_tx_queues) {
12366 		fprintf(stderr,
12367 			"Error: input queue_id should be 0 ... %d\n",
12368 			dev_info.nb_tx_queues - 1);
12369 		return;
12370 	}
12371 
12372 	if (!strcmp(res->offload, "all")) {
12373 		offload = dev_info.tx_queue_offload_capa;
12374 	} else {
12375 		offload = search_tx_offload(res->offload);
12376 		if (offload == 0) {
12377 			fprintf(stderr, "Unknown offload name: %s\n", res->offload);
12378 			return;
12379 		}
12380 		if ((offload & dev_info.tx_queue_offload_capa) == 0) {
12381 			fprintf(stderr, "Error: port %u doesn't support per queue offload: %s.\n",
12382 				port_id, res->offload);
12383 			return;
12384 		}
12385 	}
12386 
12387 	if (!strcmp(res->on_off, "on"))
12388 		port->txq[queue_id].conf.offloads |= offload;
12389 	else
12390 		port->txq[queue_id].conf.offloads &= ~offload;
12391 
12392 	cmd_reconfig_device_queue(port_id, 1, 1);
12393 }
12394 
12395 static cmdline_parse_inst_t cmd_config_per_queue_tx_offload = {
12396 	.f = cmd_config_per_queue_tx_offload_parsed,
12397 	.data = NULL,
12398 	.help_str = "port <port_id> txq <queue_id> tx_offload "
12399 		    "all|vlan_insert|ipv4_cksum|udp_cksum|tcp_cksum|"
12400 		    "sctp_cksum|tcp_tso|udp_tso|outer_ipv4_cksum|"
12401 		    "qinq_insert|vxlan_tnl_tso|gre_tnl_tso|"
12402 		    "ipip_tnl_tso|geneve_tnl_tso|macsec_insert|"
12403 		    "mt_lockfree|multi_segs|mbuf_fast_free|security "
12404 		    "on|off",
12405 	.tokens = {
12406 		(void *)&cmd_config_per_queue_tx_offload_result_port,
12407 		(void *)&cmd_config_per_queue_tx_offload_result_port_id,
12408 		(void *)&cmd_config_per_queue_tx_offload_result_txq,
12409 		(void *)&cmd_config_per_queue_tx_offload_result_queue_id,
12410 		(void *)&cmd_config_per_queue_tx_offload_result_txoffload,
12411 		(void *)&cmd_config_per_queue_tx_offload_result_offload,
12412 		(void *)&cmd_config_per_queue_tx_offload_result_on_off,
12413 		NULL,
12414 	}
12415 };
12416 
12417 /* *** configure tx_metadata for specific port *** */
12418 struct cmd_config_tx_metadata_specific_result {
12419 	cmdline_fixed_string_t port;
12420 	cmdline_fixed_string_t keyword;
12421 	uint16_t port_id;
12422 	cmdline_fixed_string_t item;
12423 	uint32_t value;
12424 };
12425 
12426 static void
12427 cmd_config_tx_metadata_specific_parsed(void *parsed_result,
12428 				__rte_unused struct cmdline *cl,
12429 				__rte_unused void *data)
12430 {
12431 	struct cmd_config_tx_metadata_specific_result *res = parsed_result;
12432 
12433 	if (port_id_is_invalid(res->port_id, ENABLED_WARN))
12434 		return;
12435 	ports[res->port_id].tx_metadata = res->value;
12436 	/* Add/remove callback to insert valid metadata in every Tx packet. */
12437 	if (ports[res->port_id].tx_metadata)
12438 		add_tx_md_callback(res->port_id);
12439 	else
12440 		remove_tx_md_callback(res->port_id);
12441 	rte_flow_dynf_metadata_register();
12442 }
12443 
12444 static cmdline_parse_token_string_t cmd_config_tx_metadata_specific_port =
12445 	TOKEN_STRING_INITIALIZER(struct cmd_config_tx_metadata_specific_result,
12446 			port, "port");
12447 static cmdline_parse_token_string_t cmd_config_tx_metadata_specific_keyword =
12448 	TOKEN_STRING_INITIALIZER(struct cmd_config_tx_metadata_specific_result,
12449 			keyword, "config");
12450 static cmdline_parse_token_num_t cmd_config_tx_metadata_specific_id =
12451 	TOKEN_NUM_INITIALIZER(struct cmd_config_tx_metadata_specific_result,
12452 			port_id, RTE_UINT16);
12453 static cmdline_parse_token_string_t cmd_config_tx_metadata_specific_item =
12454 	TOKEN_STRING_INITIALIZER(struct cmd_config_tx_metadata_specific_result,
12455 			item, "tx_metadata");
12456 static cmdline_parse_token_num_t cmd_config_tx_metadata_specific_value =
12457 	TOKEN_NUM_INITIALIZER(struct cmd_config_tx_metadata_specific_result,
12458 			value, RTE_UINT32);
12459 
12460 static cmdline_parse_inst_t cmd_config_tx_metadata_specific = {
12461 	.f = cmd_config_tx_metadata_specific_parsed,
12462 	.data = NULL,
12463 	.help_str = "port config <port_id> tx_metadata <value>",
12464 	.tokens = {
12465 		(void *)&cmd_config_tx_metadata_specific_port,
12466 		(void *)&cmd_config_tx_metadata_specific_keyword,
12467 		(void *)&cmd_config_tx_metadata_specific_id,
12468 		(void *)&cmd_config_tx_metadata_specific_item,
12469 		(void *)&cmd_config_tx_metadata_specific_value,
12470 		NULL,
12471 	},
12472 };
12473 
12474 /* *** set dynf *** */
12475 struct cmd_config_tx_dynf_specific_result {
12476 	cmdline_fixed_string_t port;
12477 	cmdline_fixed_string_t keyword;
12478 	uint16_t port_id;
12479 	cmdline_fixed_string_t item;
12480 	cmdline_fixed_string_t name;
12481 	cmdline_fixed_string_t value;
12482 };
12483 
12484 static void
12485 cmd_config_dynf_specific_parsed(void *parsed_result,
12486 				__rte_unused struct cmdline *cl,
12487 				__rte_unused void *data)
12488 {
12489 	struct cmd_config_tx_dynf_specific_result *res = parsed_result;
12490 	struct rte_mbuf_dynflag desc_flag;
12491 	int flag;
12492 	uint64_t old_port_flags;
12493 
12494 	if (port_id_is_invalid(res->port_id, ENABLED_WARN))
12495 		return;
12496 	flag = rte_mbuf_dynflag_lookup(res->name, NULL);
12497 	if (flag <= 0) {
12498 		if (strlcpy(desc_flag.name, res->name,
12499 			    RTE_MBUF_DYN_NAMESIZE) >= RTE_MBUF_DYN_NAMESIZE) {
12500 			fprintf(stderr, "Flag name too long\n");
12501 			return;
12502 		}
12503 		desc_flag.flags = 0;
12504 		flag = rte_mbuf_dynflag_register(&desc_flag);
12505 		if (flag < 0) {
12506 			fprintf(stderr, "Can't register flag\n");
12507 			return;
12508 		}
12509 		strcpy(dynf_names[flag], desc_flag.name);
12510 	}
12511 	old_port_flags = ports[res->port_id].mbuf_dynf;
12512 	if (!strcmp(res->value, "set")) {
12513 		ports[res->port_id].mbuf_dynf |= 1UL << flag;
12514 		if (old_port_flags == 0)
12515 			add_tx_dynf_callback(res->port_id);
12516 	} else {
12517 		ports[res->port_id].mbuf_dynf &= ~(1UL << flag);
12518 		if (ports[res->port_id].mbuf_dynf == 0)
12519 			remove_tx_dynf_callback(res->port_id);
12520 	}
12521 }
12522 
12523 static cmdline_parse_token_string_t cmd_config_tx_dynf_specific_port =
12524 	TOKEN_STRING_INITIALIZER(struct cmd_config_tx_dynf_specific_result,
12525 			keyword, "port");
12526 static cmdline_parse_token_string_t cmd_config_tx_dynf_specific_keyword =
12527 	TOKEN_STRING_INITIALIZER(struct cmd_config_tx_dynf_specific_result,
12528 			keyword, "config");
12529 static cmdline_parse_token_num_t cmd_config_tx_dynf_specific_port_id =
12530 	TOKEN_NUM_INITIALIZER(struct cmd_config_tx_dynf_specific_result,
12531 			port_id, RTE_UINT16);
12532 static cmdline_parse_token_string_t cmd_config_tx_dynf_specific_item =
12533 	TOKEN_STRING_INITIALIZER(struct cmd_config_tx_dynf_specific_result,
12534 			item, "dynf");
12535 static cmdline_parse_token_string_t cmd_config_tx_dynf_specific_name =
12536 	TOKEN_STRING_INITIALIZER(struct cmd_config_tx_dynf_specific_result,
12537 			name, NULL);
12538 static cmdline_parse_token_string_t cmd_config_tx_dynf_specific_value =
12539 	TOKEN_STRING_INITIALIZER(struct cmd_config_tx_dynf_specific_result,
12540 			value, "set#clear");
12541 
12542 static cmdline_parse_inst_t cmd_config_tx_dynf_specific = {
12543 	.f = cmd_config_dynf_specific_parsed,
12544 	.data = NULL,
12545 	.help_str = "port config <port id> dynf <name> set|clear",
12546 	.tokens = {
12547 		(void *)&cmd_config_tx_dynf_specific_port,
12548 		(void *)&cmd_config_tx_dynf_specific_keyword,
12549 		(void *)&cmd_config_tx_dynf_specific_port_id,
12550 		(void *)&cmd_config_tx_dynf_specific_item,
12551 		(void *)&cmd_config_tx_dynf_specific_name,
12552 		(void *)&cmd_config_tx_dynf_specific_value,
12553 		NULL,
12554 	},
12555 };
12556 
12557 /* *** display tx_metadata per port configuration *** */
12558 struct cmd_show_tx_metadata_result {
12559 	cmdline_fixed_string_t cmd_show;
12560 	cmdline_fixed_string_t cmd_port;
12561 	cmdline_fixed_string_t cmd_keyword;
12562 	portid_t cmd_pid;
12563 };
12564 
12565 static void
12566 cmd_show_tx_metadata_parsed(void *parsed_result,
12567 		__rte_unused struct cmdline *cl,
12568 		__rte_unused void *data)
12569 {
12570 	struct cmd_show_tx_metadata_result *res = parsed_result;
12571 
12572 	if (!rte_eth_dev_is_valid_port(res->cmd_pid)) {
12573 		fprintf(stderr, "invalid port id %u\n", res->cmd_pid);
12574 		return;
12575 	}
12576 	if (!strcmp(res->cmd_keyword, "tx_metadata")) {
12577 		printf("Port %u tx_metadata: %u\n", res->cmd_pid,
12578 		       ports[res->cmd_pid].tx_metadata);
12579 	}
12580 }
12581 
12582 static cmdline_parse_token_string_t cmd_show_tx_metadata_show =
12583 	TOKEN_STRING_INITIALIZER(struct cmd_show_tx_metadata_result,
12584 			cmd_show, "show");
12585 static cmdline_parse_token_string_t cmd_show_tx_metadata_port =
12586 	TOKEN_STRING_INITIALIZER(struct cmd_show_tx_metadata_result,
12587 			cmd_port, "port");
12588 static cmdline_parse_token_num_t cmd_show_tx_metadata_pid =
12589 	TOKEN_NUM_INITIALIZER(struct cmd_show_tx_metadata_result,
12590 			cmd_pid, RTE_UINT16);
12591 static cmdline_parse_token_string_t cmd_show_tx_metadata_keyword =
12592 	TOKEN_STRING_INITIALIZER(struct cmd_show_tx_metadata_result,
12593 			cmd_keyword, "tx_metadata");
12594 
12595 static cmdline_parse_inst_t cmd_show_tx_metadata = {
12596 	.f = cmd_show_tx_metadata_parsed,
12597 	.data = NULL,
12598 	.help_str = "show port <port_id> tx_metadata",
12599 	.tokens = {
12600 		(void *)&cmd_show_tx_metadata_show,
12601 		(void *)&cmd_show_tx_metadata_port,
12602 		(void *)&cmd_show_tx_metadata_pid,
12603 		(void *)&cmd_show_tx_metadata_keyword,
12604 		NULL,
12605 	},
12606 };
12607 
12608 /* *** show fec capability per port configuration *** */
12609 struct cmd_show_fec_capability_result {
12610 	cmdline_fixed_string_t cmd_show;
12611 	cmdline_fixed_string_t cmd_port;
12612 	cmdline_fixed_string_t cmd_fec;
12613 	cmdline_fixed_string_t cmd_keyword;
12614 	portid_t cmd_pid;
12615 };
12616 
12617 static void
12618 cmd_show_fec_capability_parsed(void *parsed_result,
12619 		__rte_unused struct cmdline *cl,
12620 		__rte_unused void *data)
12621 {
12622 	struct cmd_show_fec_capability_result *res = parsed_result;
12623 	struct rte_eth_fec_capa *speed_fec_capa;
12624 	unsigned int num;
12625 	int ret;
12626 
12627 	if (!rte_eth_dev_is_valid_port(res->cmd_pid)) {
12628 		fprintf(stderr, "Invalid port id %u\n", res->cmd_pid);
12629 		return;
12630 	}
12631 
12632 	ret = rte_eth_fec_get_capability(res->cmd_pid, NULL, 0);
12633 	if (ret == -ENOTSUP) {
12634 		fprintf(stderr, "Function not implemented\n");
12635 		return;
12636 	} else if (ret < 0) {
12637 		fprintf(stderr, "Get FEC capability failed: %d\n", ret);
12638 		return;
12639 	}
12640 
12641 	num = (unsigned int)ret;
12642 	speed_fec_capa = calloc(num, sizeof(*speed_fec_capa));
12643 	if (speed_fec_capa == NULL) {
12644 		fprintf(stderr, "Failed to alloc FEC capability buffer\n");
12645 		return;
12646 	}
12647 
12648 	ret = rte_eth_fec_get_capability(res->cmd_pid, speed_fec_capa, num);
12649 	if (ret < 0) {
12650 		fprintf(stderr, "Error getting FEC capability: %d\n", ret);
12651 		goto out;
12652 	}
12653 
12654 	show_fec_capability(num, speed_fec_capa);
12655 out:
12656 	free(speed_fec_capa);
12657 }
12658 
12659 static cmdline_parse_token_string_t cmd_show_fec_capability_show =
12660 	TOKEN_STRING_INITIALIZER(struct cmd_show_fec_capability_result,
12661 			cmd_show, "show");
12662 static cmdline_parse_token_string_t cmd_show_fec_capability_port =
12663 	TOKEN_STRING_INITIALIZER(struct cmd_show_fec_capability_result,
12664 			cmd_port, "port");
12665 static cmdline_parse_token_num_t cmd_show_fec_capability_pid =
12666 	TOKEN_NUM_INITIALIZER(struct cmd_show_fec_capability_result,
12667 			cmd_pid, RTE_UINT16);
12668 static cmdline_parse_token_string_t cmd_show_fec_capability_fec =
12669 	TOKEN_STRING_INITIALIZER(struct cmd_show_fec_capability_result,
12670 			cmd_fec, "fec");
12671 static cmdline_parse_token_string_t cmd_show_fec_capability_keyword =
12672 	TOKEN_STRING_INITIALIZER(struct cmd_show_fec_capability_result,
12673 			cmd_keyword, "capabilities");
12674 
12675 static cmdline_parse_inst_t cmd_show_capability = {
12676 	.f = cmd_show_fec_capability_parsed,
12677 	.data = NULL,
12678 	.help_str = "show port <port_id> fec capabilities",
12679 	.tokens = {
12680 		(void *)&cmd_show_fec_capability_show,
12681 		(void *)&cmd_show_fec_capability_port,
12682 		(void *)&cmd_show_fec_capability_pid,
12683 		(void *)&cmd_show_fec_capability_fec,
12684 		(void *)&cmd_show_fec_capability_keyword,
12685 		NULL,
12686 	},
12687 };
12688 
12689 /* *** show fec mode per port configuration *** */
12690 struct cmd_show_fec_metadata_result {
12691 	cmdline_fixed_string_t cmd_show;
12692 	cmdline_fixed_string_t cmd_port;
12693 	cmdline_fixed_string_t cmd_keyword;
12694 	portid_t cmd_pid;
12695 };
12696 
12697 static void
12698 cmd_show_fec_mode_parsed(void *parsed_result,
12699 		__rte_unused struct cmdline *cl,
12700 		__rte_unused void *data)
12701 {
12702 #define FEC_NAME_SIZE 16
12703 	struct cmd_show_fec_metadata_result *res = parsed_result;
12704 	uint32_t mode;
12705 	char buf[FEC_NAME_SIZE];
12706 	int ret;
12707 
12708 	if (!rte_eth_dev_is_valid_port(res->cmd_pid)) {
12709 		fprintf(stderr, "Invalid port id %u\n", res->cmd_pid);
12710 		return;
12711 	}
12712 	ret = rte_eth_fec_get(res->cmd_pid, &mode);
12713 	if (ret == -ENOTSUP) {
12714 		fprintf(stderr, "Function not implemented\n");
12715 		return;
12716 	} else if (ret < 0) {
12717 		fprintf(stderr, "Get FEC mode failed\n");
12718 		return;
12719 	}
12720 
12721 	switch (mode) {
12722 	case RTE_ETH_FEC_MODE_CAPA_MASK(NOFEC):
12723 		strlcpy(buf, "off", sizeof(buf));
12724 		break;
12725 	case RTE_ETH_FEC_MODE_CAPA_MASK(AUTO):
12726 		strlcpy(buf, "auto", sizeof(buf));
12727 		break;
12728 	case RTE_ETH_FEC_MODE_CAPA_MASK(BASER):
12729 		strlcpy(buf, "baser", sizeof(buf));
12730 		break;
12731 	case RTE_ETH_FEC_MODE_CAPA_MASK(RS):
12732 		strlcpy(buf, "rs", sizeof(buf));
12733 		break;
12734 	case RTE_ETH_FEC_MODE_CAPA_MASK(LLRS):
12735 		strlcpy(buf, "llrs", sizeof(buf));
12736 		break;
12737 	default:
12738 		return;
12739 	}
12740 
12741 	printf("%s\n", buf);
12742 }
12743 
12744 static cmdline_parse_token_string_t cmd_show_fec_mode_show =
12745 	TOKEN_STRING_INITIALIZER(struct cmd_show_fec_metadata_result,
12746 			cmd_show, "show");
12747 static cmdline_parse_token_string_t cmd_show_fec_mode_port =
12748 	TOKEN_STRING_INITIALIZER(struct cmd_show_fec_metadata_result,
12749 			cmd_port, "port");
12750 static cmdline_parse_token_num_t cmd_show_fec_mode_pid =
12751 	TOKEN_NUM_INITIALIZER(struct cmd_show_fec_metadata_result,
12752 			cmd_pid, RTE_UINT16);
12753 static cmdline_parse_token_string_t cmd_show_fec_mode_keyword =
12754 	TOKEN_STRING_INITIALIZER(struct cmd_show_fec_metadata_result,
12755 			cmd_keyword, "fec_mode");
12756 
12757 static cmdline_parse_inst_t cmd_show_fec_mode = {
12758 	.f = cmd_show_fec_mode_parsed,
12759 	.data = NULL,
12760 	.help_str = "show port <port_id> fec_mode",
12761 	.tokens = {
12762 		(void *)&cmd_show_fec_mode_show,
12763 		(void *)&cmd_show_fec_mode_port,
12764 		(void *)&cmd_show_fec_mode_pid,
12765 		(void *)&cmd_show_fec_mode_keyword,
12766 		NULL,
12767 	},
12768 };
12769 
12770 /* *** set fec mode per port configuration *** */
12771 struct cmd_set_port_fec_mode {
12772 	cmdline_fixed_string_t set;
12773 	cmdline_fixed_string_t port;
12774 	portid_t port_id;
12775 	cmdline_fixed_string_t fec_mode;
12776 	cmdline_fixed_string_t fec_value;
12777 };
12778 
12779 /* Common CLI fields for set fec mode */
12780 static cmdline_parse_token_string_t cmd_set_port_fec_mode_set =
12781 	TOKEN_STRING_INITIALIZER
12782 		(struct cmd_set_port_fec_mode,
12783 		 set, "set");
12784 static cmdline_parse_token_string_t cmd_set_port_fec_mode_port =
12785 	TOKEN_STRING_INITIALIZER
12786 		(struct cmd_set_port_fec_mode,
12787 		 port, "port");
12788 static cmdline_parse_token_num_t cmd_set_port_fec_mode_port_id =
12789 	TOKEN_NUM_INITIALIZER
12790 		(struct cmd_set_port_fec_mode,
12791 		 port_id, RTE_UINT16);
12792 static cmdline_parse_token_string_t cmd_set_port_fec_mode_str =
12793 	TOKEN_STRING_INITIALIZER
12794 		(struct cmd_set_port_fec_mode,
12795 		 fec_mode, "fec_mode");
12796 static cmdline_parse_token_string_t cmd_set_port_fec_mode_value =
12797 	TOKEN_STRING_INITIALIZER
12798 		(struct cmd_set_port_fec_mode,
12799 		 fec_value, NULL);
12800 
12801 static void
12802 cmd_set_port_fec_mode_parsed(
12803 	void *parsed_result,
12804 	__rte_unused struct cmdline *cl,
12805 	__rte_unused void *data)
12806 {
12807 	struct cmd_set_port_fec_mode *res = parsed_result;
12808 	uint16_t port_id = res->port_id;
12809 	uint32_t fec_capa;
12810 	int ret;
12811 
12812 	ret = parse_fec_mode(res->fec_value, &fec_capa);
12813 	if (ret < 0) {
12814 		fprintf(stderr, "Unknown fec mode: %s for port %d\n",
12815 				res->fec_value,	port_id);
12816 		return;
12817 	}
12818 
12819 	ret = rte_eth_fec_set(port_id, fec_capa);
12820 	if (ret == -ENOTSUP) {
12821 		fprintf(stderr, "Function not implemented\n");
12822 		return;
12823 	} else if (ret < 0) {
12824 		fprintf(stderr, "Set FEC mode failed\n");
12825 		return;
12826 	}
12827 }
12828 
12829 static cmdline_parse_inst_t cmd_set_fec_mode = {
12830 	.f = cmd_set_port_fec_mode_parsed,
12831 	.data = NULL,
12832 	.help_str = "set port <port_id> fec_mode auto|off|rs|baser|llrs",
12833 	.tokens = {
12834 		(void *)&cmd_set_port_fec_mode_set,
12835 		(void *)&cmd_set_port_fec_mode_port,
12836 		(void *)&cmd_set_port_fec_mode_port_id,
12837 		(void *)&cmd_set_port_fec_mode_str,
12838 		(void *)&cmd_set_port_fec_mode_value,
12839 		NULL,
12840 	},
12841 };
12842 
12843 /* *** set available descriptors threshold for an RxQ of a port *** */
12844 struct cmd_set_rxq_avail_thresh_result {
12845 	cmdline_fixed_string_t set;
12846 	cmdline_fixed_string_t port;
12847 	uint16_t port_num;
12848 	cmdline_fixed_string_t rxq;
12849 	uint16_t rxq_num;
12850 	cmdline_fixed_string_t avail_thresh;
12851 	uint8_t avail_thresh_num;
12852 };
12853 
12854 static void cmd_set_rxq_avail_thresh_parsed(void *parsed_result,
12855 		__rte_unused struct cmdline *cl,
12856 		__rte_unused void *data)
12857 {
12858 	struct cmd_set_rxq_avail_thresh_result *res = parsed_result;
12859 	int ret = 0;
12860 
12861 	if ((strcmp(res->set, "set") == 0) && (strcmp(res->port, "port") == 0)
12862 	    && (strcmp(res->rxq, "rxq") == 0)
12863 	    && (strcmp(res->avail_thresh, "avail_thresh") == 0))
12864 		ret = set_rxq_avail_thresh(res->port_num, res->rxq_num,
12865 				  res->avail_thresh_num);
12866 	if (ret < 0)
12867 		printf("rxq_avail_thresh_cmd error: (%s)\n", strerror(-ret));
12868 
12869 }
12870 
12871 static cmdline_parse_token_string_t cmd_set_rxq_avail_thresh_set =
12872 	TOKEN_STRING_INITIALIZER(struct cmd_set_rxq_avail_thresh_result,
12873 				set, "set");
12874 static cmdline_parse_token_string_t cmd_set_rxq_avail_thresh_port =
12875 	TOKEN_STRING_INITIALIZER(struct cmd_set_rxq_avail_thresh_result,
12876 				port, "port");
12877 static cmdline_parse_token_num_t cmd_set_rxq_avail_thresh_portnum =
12878 	TOKEN_NUM_INITIALIZER(struct cmd_set_rxq_avail_thresh_result,
12879 				port_num, RTE_UINT16);
12880 static cmdline_parse_token_string_t cmd_set_rxq_avail_thresh_rxq =
12881 	TOKEN_STRING_INITIALIZER(struct cmd_set_rxq_avail_thresh_result,
12882 				rxq, "rxq");
12883 static cmdline_parse_token_num_t cmd_set_rxq_avail_thresh_rxqnum =
12884 	TOKEN_NUM_INITIALIZER(struct cmd_set_rxq_avail_thresh_result,
12885 				rxq_num, RTE_UINT16);
12886 static cmdline_parse_token_string_t cmd_set_rxq_avail_thresh_avail_thresh =
12887 	TOKEN_STRING_INITIALIZER(struct cmd_set_rxq_avail_thresh_result,
12888 				avail_thresh, "avail_thresh");
12889 static cmdline_parse_token_num_t cmd_set_rxq_avail_thresh_avail_threshnum =
12890 	TOKEN_NUM_INITIALIZER(struct cmd_set_rxq_avail_thresh_result,
12891 				avail_thresh_num, RTE_UINT8);
12892 
12893 static cmdline_parse_inst_t cmd_set_rxq_avail_thresh = {
12894 	.f = cmd_set_rxq_avail_thresh_parsed,
12895 	.data = (void *)0,
12896 	.help_str =
12897 		"set port <port_id> rxq <queue_id> avail_thresh <0..99>: "
12898 		"Set available descriptors threshold for Rx queue",
12899 	.tokens = {
12900 		(void *)&cmd_set_rxq_avail_thresh_set,
12901 		(void *)&cmd_set_rxq_avail_thresh_port,
12902 		(void *)&cmd_set_rxq_avail_thresh_portnum,
12903 		(void *)&cmd_set_rxq_avail_thresh_rxq,
12904 		(void *)&cmd_set_rxq_avail_thresh_rxqnum,
12905 		(void *)&cmd_set_rxq_avail_thresh_avail_thresh,
12906 		(void *)&cmd_set_rxq_avail_thresh_avail_threshnum,
12907 		NULL,
12908 	},
12909 };
12910 
12911 /* show port supported ptypes */
12912 
12913 /* Common result structure for show port ptypes */
12914 struct cmd_show_port_supported_ptypes_result {
12915 	cmdline_fixed_string_t show;
12916 	cmdline_fixed_string_t port;
12917 	portid_t port_id;
12918 	cmdline_fixed_string_t ptypes;
12919 };
12920 
12921 /* Common CLI fields for show port ptypes */
12922 static cmdline_parse_token_string_t cmd_show_port_supported_ptypes_show =
12923 	TOKEN_STRING_INITIALIZER
12924 		(struct cmd_show_port_supported_ptypes_result,
12925 		 show, "show");
12926 static cmdline_parse_token_string_t cmd_show_port_supported_ptypes_port =
12927 	TOKEN_STRING_INITIALIZER
12928 		(struct cmd_show_port_supported_ptypes_result,
12929 		 port, "port");
12930 static cmdline_parse_token_num_t cmd_show_port_supported_ptypes_port_id =
12931 	TOKEN_NUM_INITIALIZER
12932 		(struct cmd_show_port_supported_ptypes_result,
12933 		 port_id, RTE_UINT16);
12934 static cmdline_parse_token_string_t cmd_show_port_supported_ptypes_ptypes =
12935 	TOKEN_STRING_INITIALIZER
12936 		(struct cmd_show_port_supported_ptypes_result,
12937 		 ptypes, "ptypes");
12938 
12939 static void
12940 cmd_show_port_supported_ptypes_parsed(
12941 	void *parsed_result,
12942 	__rte_unused struct cmdline *cl,
12943 	__rte_unused void *data)
12944 {
12945 #define RSVD_PTYPE_MASK       0xf0000000
12946 #define MAX_PTYPES_PER_LAYER  16
12947 #define LTYPE_NAMESIZE        32
12948 #define PTYPE_NAMESIZE        256
12949 	struct cmd_show_port_supported_ptypes_result *res = parsed_result;
12950 	char buf[PTYPE_NAMESIZE], ltype[LTYPE_NAMESIZE];
12951 	uint32_t ptype_mask = RTE_PTYPE_L2_MASK;
12952 	uint32_t ptypes[MAX_PTYPES_PER_LAYER];
12953 	uint16_t port_id = res->port_id;
12954 	int ret, i;
12955 
12956 	ret = rte_eth_dev_get_supported_ptypes(port_id, ptype_mask, NULL, 0);
12957 	if (ret < 0)
12958 		return;
12959 
12960 	while (ptype_mask != RSVD_PTYPE_MASK) {
12961 
12962 		switch (ptype_mask) {
12963 		case RTE_PTYPE_L2_MASK:
12964 			strlcpy(ltype, "L2", sizeof(ltype));
12965 			break;
12966 		case RTE_PTYPE_L3_MASK:
12967 			strlcpy(ltype, "L3", sizeof(ltype));
12968 			break;
12969 		case RTE_PTYPE_L4_MASK:
12970 			strlcpy(ltype, "L4", sizeof(ltype));
12971 			break;
12972 		case RTE_PTYPE_TUNNEL_MASK:
12973 			strlcpy(ltype, "Tunnel", sizeof(ltype));
12974 			break;
12975 		case RTE_PTYPE_INNER_L2_MASK:
12976 			strlcpy(ltype, "Inner L2", sizeof(ltype));
12977 			break;
12978 		case RTE_PTYPE_INNER_L3_MASK:
12979 			strlcpy(ltype, "Inner L3", sizeof(ltype));
12980 			break;
12981 		case RTE_PTYPE_INNER_L4_MASK:
12982 			strlcpy(ltype, "Inner L4", sizeof(ltype));
12983 			break;
12984 		default:
12985 			return;
12986 		}
12987 
12988 		ret = rte_eth_dev_get_supported_ptypes(res->port_id,
12989 						       ptype_mask, ptypes,
12990 						       MAX_PTYPES_PER_LAYER);
12991 
12992 		if (ret > 0)
12993 			printf("Supported %s ptypes:\n", ltype);
12994 		else
12995 			printf("%s ptypes unsupported\n", ltype);
12996 
12997 		for (i = 0; i < ret; ++i) {
12998 			rte_get_ptype_name(ptypes[i], buf, sizeof(buf));
12999 			printf("%s\n", buf);
13000 		}
13001 
13002 		ptype_mask <<= 4;
13003 	}
13004 }
13005 
13006 static cmdline_parse_inst_t cmd_show_port_supported_ptypes = {
13007 	.f = cmd_show_port_supported_ptypes_parsed,
13008 	.data = NULL,
13009 	.help_str = "show port <port_id> ptypes",
13010 	.tokens = {
13011 		(void *)&cmd_show_port_supported_ptypes_show,
13012 		(void *)&cmd_show_port_supported_ptypes_port,
13013 		(void *)&cmd_show_port_supported_ptypes_port_id,
13014 		(void *)&cmd_show_port_supported_ptypes_ptypes,
13015 		NULL,
13016 	},
13017 };
13018 
13019 /* *** display rx/tx descriptor status *** */
13020 struct cmd_show_rx_tx_desc_status_result {
13021 	cmdline_fixed_string_t cmd_show;
13022 	cmdline_fixed_string_t cmd_port;
13023 	cmdline_fixed_string_t cmd_keyword;
13024 	cmdline_fixed_string_t cmd_desc;
13025 	cmdline_fixed_string_t cmd_status;
13026 	portid_t cmd_pid;
13027 	portid_t cmd_qid;
13028 	portid_t cmd_did;
13029 };
13030 
13031 static void
13032 cmd_show_rx_tx_desc_status_parsed(void *parsed_result,
13033 		__rte_unused struct cmdline *cl,
13034 		__rte_unused void *data)
13035 {
13036 	struct cmd_show_rx_tx_desc_status_result *res = parsed_result;
13037 	int rc;
13038 
13039 	if (!strcmp(res->cmd_keyword, "rxq")) {
13040 		if (rte_eth_rx_queue_is_valid(res->cmd_pid, res->cmd_qid) != 0) {
13041 			fprintf(stderr,
13042 				"Invalid input: port id = %d, queue id = %d\n",
13043 				res->cmd_pid, res->cmd_qid);
13044 			return;
13045 		}
13046 		rc = rte_eth_rx_descriptor_status(res->cmd_pid, res->cmd_qid,
13047 					     res->cmd_did);
13048 		if (rc < 0) {
13049 			fprintf(stderr,
13050 				"Invalid input: queue id = %d, desc id = %d\n",
13051 				res->cmd_qid, res->cmd_did);
13052 			return;
13053 		}
13054 		if (rc == RTE_ETH_RX_DESC_AVAIL)
13055 			printf("Desc status = AVAILABLE\n");
13056 		else if (rc == RTE_ETH_RX_DESC_DONE)
13057 			printf("Desc status = DONE\n");
13058 		else
13059 			printf("Desc status = UNAVAILABLE\n");
13060 	} else if (!strcmp(res->cmd_keyword, "txq")) {
13061 		if (rte_eth_tx_queue_is_valid(res->cmd_pid, res->cmd_qid) != 0) {
13062 			fprintf(stderr,
13063 				"Invalid input: port id = %d, queue id = %d\n",
13064 				res->cmd_pid, res->cmd_qid);
13065 			return;
13066 		}
13067 		rc = rte_eth_tx_descriptor_status(res->cmd_pid, res->cmd_qid,
13068 					     res->cmd_did);
13069 		if (rc < 0) {
13070 			fprintf(stderr,
13071 				"Invalid input: queue id = %d, desc id = %d\n",
13072 				res->cmd_qid, res->cmd_did);
13073 			return;
13074 		}
13075 		if (rc == RTE_ETH_TX_DESC_FULL)
13076 			printf("Desc status = FULL\n");
13077 		else if (rc == RTE_ETH_TX_DESC_DONE)
13078 			printf("Desc status = DONE\n");
13079 		else
13080 			printf("Desc status = UNAVAILABLE\n");
13081 	}
13082 }
13083 
13084 static cmdline_parse_token_string_t cmd_show_rx_tx_desc_status_show =
13085 	TOKEN_STRING_INITIALIZER(struct cmd_show_rx_tx_desc_status_result,
13086 			cmd_show, "show");
13087 static cmdline_parse_token_string_t cmd_show_rx_tx_desc_status_port =
13088 	TOKEN_STRING_INITIALIZER(struct cmd_show_rx_tx_desc_status_result,
13089 			cmd_port, "port");
13090 static cmdline_parse_token_num_t cmd_show_rx_tx_desc_status_pid =
13091 	TOKEN_NUM_INITIALIZER(struct cmd_show_rx_tx_desc_status_result,
13092 			cmd_pid, RTE_UINT16);
13093 static cmdline_parse_token_string_t cmd_show_rx_tx_desc_status_keyword =
13094 	TOKEN_STRING_INITIALIZER(struct cmd_show_rx_tx_desc_status_result,
13095 			cmd_keyword, "rxq#txq");
13096 static cmdline_parse_token_num_t cmd_show_rx_tx_desc_status_qid =
13097 	TOKEN_NUM_INITIALIZER(struct cmd_show_rx_tx_desc_status_result,
13098 			cmd_qid, RTE_UINT16);
13099 static cmdline_parse_token_string_t cmd_show_rx_tx_desc_status_desc =
13100 	TOKEN_STRING_INITIALIZER(struct cmd_show_rx_tx_desc_status_result,
13101 			cmd_desc, "desc");
13102 static cmdline_parse_token_num_t cmd_show_rx_tx_desc_status_did =
13103 	TOKEN_NUM_INITIALIZER(struct cmd_show_rx_tx_desc_status_result,
13104 			cmd_did, RTE_UINT16);
13105 static cmdline_parse_token_string_t cmd_show_rx_tx_desc_status_status =
13106 	TOKEN_STRING_INITIALIZER(struct cmd_show_rx_tx_desc_status_result,
13107 			cmd_status, "status");
13108 static cmdline_parse_inst_t cmd_show_rx_tx_desc_status = {
13109 	.f = cmd_show_rx_tx_desc_status_parsed,
13110 	.data = NULL,
13111 	.help_str = "show port <port_id> rxq|txq <queue_id> desc <desc_id> "
13112 		"status",
13113 	.tokens = {
13114 		(void *)&cmd_show_rx_tx_desc_status_show,
13115 		(void *)&cmd_show_rx_tx_desc_status_port,
13116 		(void *)&cmd_show_rx_tx_desc_status_pid,
13117 		(void *)&cmd_show_rx_tx_desc_status_keyword,
13118 		(void *)&cmd_show_rx_tx_desc_status_qid,
13119 		(void *)&cmd_show_rx_tx_desc_status_desc,
13120 		(void *)&cmd_show_rx_tx_desc_status_did,
13121 		(void *)&cmd_show_rx_tx_desc_status_status,
13122 		NULL,
13123 	},
13124 };
13125 
13126 /* *** display rx/tx queue descriptor used count *** */
13127 struct cmd_show_rx_tx_queue_desc_used_count_result {
13128 	cmdline_fixed_string_t cmd_show;
13129 	cmdline_fixed_string_t cmd_port;
13130 	cmdline_fixed_string_t cmd_dir;
13131 	cmdline_fixed_string_t cmd_desc;
13132 	cmdline_fixed_string_t cmd_used;
13133 	cmdline_fixed_string_t cmd_count;
13134 	portid_t cmd_pid;
13135 	portid_t cmd_qid;
13136 };
13137 
13138 static void
13139 cmd_show_rx_tx_queue_desc_used_count_parsed(void *parsed_result, __rte_unused struct cmdline *cl,
13140 					    __rte_unused void *data)
13141 {
13142 	struct cmd_show_rx_tx_queue_desc_used_count_result *res = parsed_result;
13143 	int rc;
13144 
13145 	if (!strcmp(res->cmd_dir, "rxq")) {
13146 		if (rte_eth_rx_queue_is_valid(res->cmd_pid, res->cmd_qid) != 0) {
13147 			fprintf(stderr, "Invalid input: port id = %d, queue id = %d\n",
13148 				res->cmd_pid, res->cmd_qid);
13149 			return;
13150 		}
13151 
13152 		rc = rte_eth_rx_queue_count(res->cmd_pid, res->cmd_qid);
13153 		if (rc < 0) {
13154 			fprintf(stderr, "Rx queue count get failed rc=%d queue_id=%d\n", rc,
13155 				res->cmd_qid);
13156 			return;
13157 		}
13158 		printf("RxQ %d used desc count = %d\n", res->cmd_qid, rc);
13159 	} else if (!strcmp(res->cmd_dir, "txq")) {
13160 		if (rte_eth_tx_queue_is_valid(res->cmd_pid, res->cmd_qid) != 0) {
13161 			fprintf(stderr, "Invalid input: port id = %d, queue id = %d\n",
13162 				res->cmd_pid, res->cmd_qid);
13163 			return;
13164 		}
13165 
13166 		rc = rte_eth_tx_queue_count(res->cmd_pid, res->cmd_qid);
13167 		if (rc < 0) {
13168 			fprintf(stderr, "Tx queue count get failed rc=%d queue_id=%d\n", rc,
13169 				res->cmd_qid);
13170 			return;
13171 		}
13172 		printf("TxQ %d used desc count = %d\n", res->cmd_qid, rc);
13173 	}
13174 }
13175 
13176 static cmdline_parse_token_string_t cmd_show_rx_tx_queue_desc_used_count_show =
13177 	TOKEN_STRING_INITIALIZER
13178 		(struct cmd_show_rx_tx_queue_desc_used_count_result,
13179 		 cmd_show, "show");
13180 static cmdline_parse_token_string_t cmd_show_rx_tx_queue_desc_used_count_port =
13181 	TOKEN_STRING_INITIALIZER
13182 		(struct cmd_show_rx_tx_queue_desc_used_count_result,
13183 		 cmd_port, "port");
13184 static cmdline_parse_token_num_t cmd_show_rx_tx_queue_desc_used_count_pid =
13185 	TOKEN_NUM_INITIALIZER
13186 		(struct cmd_show_rx_tx_queue_desc_used_count_result,
13187 		 cmd_pid, RTE_UINT16);
13188 static cmdline_parse_token_string_t cmd_show_rx_tx_queue_desc_used_count_dir =
13189 	TOKEN_STRING_INITIALIZER
13190 		(struct cmd_show_rx_tx_queue_desc_used_count_result,
13191 		 cmd_dir, "rxq#txq");
13192 static cmdline_parse_token_num_t cmd_show_rx_tx_queue_desc_used_count_qid =
13193 	TOKEN_NUM_INITIALIZER
13194 		(struct cmd_show_rx_tx_queue_desc_used_count_result,
13195 		 cmd_qid, RTE_UINT16);
13196 static cmdline_parse_token_string_t cmd_show_rx_tx_queue_desc_used_count_desc =
13197 	TOKEN_STRING_INITIALIZER
13198 		(struct cmd_show_rx_tx_queue_desc_used_count_result,
13199 		 cmd_desc, "desc");
13200 static cmdline_parse_token_string_t cmd_show_rx_tx_queue_desc_used_count_used =
13201 	TOKEN_STRING_INITIALIZER
13202 		(struct cmd_show_rx_tx_queue_desc_used_count_result,
13203 		 cmd_count, "used");
13204 static cmdline_parse_token_string_t cmd_show_rx_tx_queue_desc_used_count_count =
13205 	TOKEN_STRING_INITIALIZER
13206 		(struct cmd_show_rx_tx_queue_desc_used_count_result,
13207 		 cmd_count, "count");
13208 static cmdline_parse_inst_t cmd_show_rx_tx_queue_desc_used_count = {
13209 	.f = cmd_show_rx_tx_queue_desc_used_count_parsed,
13210 	.data = NULL,
13211 	.help_str = "show port <port_id> rxq|txq <queue_id> desc used count",
13212 	.tokens = {
13213 		(void *)&cmd_show_rx_tx_queue_desc_used_count_show,
13214 		(void *)&cmd_show_rx_tx_queue_desc_used_count_port,
13215 		(void *)&cmd_show_rx_tx_queue_desc_used_count_pid,
13216 		(void *)&cmd_show_rx_tx_queue_desc_used_count_dir,
13217 		(void *)&cmd_show_rx_tx_queue_desc_used_count_qid,
13218 		(void *)&cmd_show_rx_tx_queue_desc_used_count_desc,
13219 		(void *)&cmd_show_rx_tx_queue_desc_used_count_used,
13220 		(void *)&cmd_show_rx_tx_queue_desc_used_count_count,
13221 		NULL,
13222 	},
13223 };
13224 
13225 /* Common result structure for set port ptypes */
13226 struct cmd_set_port_ptypes_result {
13227 	cmdline_fixed_string_t set;
13228 	cmdline_fixed_string_t port;
13229 	portid_t port_id;
13230 	cmdline_fixed_string_t ptype_mask;
13231 	uint32_t mask;
13232 };
13233 
13234 /* Common CLI fields for set port ptypes */
13235 static cmdline_parse_token_string_t cmd_set_port_ptypes_set =
13236 	TOKEN_STRING_INITIALIZER
13237 		(struct cmd_set_port_ptypes_result,
13238 		 set, "set");
13239 static cmdline_parse_token_string_t cmd_set_port_ptypes_port =
13240 	TOKEN_STRING_INITIALIZER
13241 		(struct cmd_set_port_ptypes_result,
13242 		 port, "port");
13243 static cmdline_parse_token_num_t cmd_set_port_ptypes_port_id =
13244 	TOKEN_NUM_INITIALIZER
13245 		(struct cmd_set_port_ptypes_result,
13246 		 port_id, RTE_UINT16);
13247 static cmdline_parse_token_string_t cmd_set_port_ptypes_mask_str =
13248 	TOKEN_STRING_INITIALIZER
13249 		(struct cmd_set_port_ptypes_result,
13250 		 ptype_mask, "ptype_mask");
13251 static cmdline_parse_token_num_t cmd_set_port_ptypes_mask_u32 =
13252 	TOKEN_NUM_INITIALIZER
13253 		(struct cmd_set_port_ptypes_result,
13254 		 mask, RTE_UINT32);
13255 
13256 static void
13257 cmd_set_port_ptypes_parsed(
13258 	void *parsed_result,
13259 	__rte_unused struct cmdline *cl,
13260 	__rte_unused void *data)
13261 {
13262 	struct cmd_set_port_ptypes_result *res = parsed_result;
13263 #define PTYPE_NAMESIZE        256
13264 	char ptype_name[PTYPE_NAMESIZE];
13265 	uint16_t port_id = res->port_id;
13266 	uint32_t ptype_mask = res->mask;
13267 	int ret, i;
13268 
13269 	ret = rte_eth_dev_get_supported_ptypes(port_id, RTE_PTYPE_ALL_MASK,
13270 					       NULL, 0);
13271 	if (ret <= 0) {
13272 		fprintf(stderr, "Port %d doesn't support any ptypes.\n",
13273 			port_id);
13274 		return;
13275 	}
13276 
13277 	uint32_t ptypes[ret];
13278 
13279 	ret = rte_eth_dev_set_ptypes(port_id, ptype_mask, ptypes, ret);
13280 	if (ret < 0) {
13281 		fprintf(stderr, "Unable to set requested ptypes for Port %d\n",
13282 			port_id);
13283 		return;
13284 	}
13285 
13286 	printf("Successfully set following ptypes for Port %d\n", port_id);
13287 	for (i = 0; i < ret && ptypes[i] != RTE_PTYPE_UNKNOWN; i++) {
13288 		rte_get_ptype_name(ptypes[i], ptype_name, sizeof(ptype_name));
13289 		printf("%s\n", ptype_name);
13290 	}
13291 
13292 	clear_ptypes = false;
13293 }
13294 
13295 static cmdline_parse_inst_t cmd_set_port_ptypes = {
13296 	.f = cmd_set_port_ptypes_parsed,
13297 	.data = NULL,
13298 	.help_str = "set port <port_id> ptype_mask <mask>",
13299 	.tokens = {
13300 		(void *)&cmd_set_port_ptypes_set,
13301 		(void *)&cmd_set_port_ptypes_port,
13302 		(void *)&cmd_set_port_ptypes_port_id,
13303 		(void *)&cmd_set_port_ptypes_mask_str,
13304 		(void *)&cmd_set_port_ptypes_mask_u32,
13305 		NULL,
13306 	},
13307 };
13308 
13309 /* *** display mac addresses added to a port *** */
13310 struct cmd_showport_macs_result {
13311 	cmdline_fixed_string_t cmd_show;
13312 	cmdline_fixed_string_t cmd_port;
13313 	cmdline_fixed_string_t cmd_keyword;
13314 	portid_t cmd_pid;
13315 };
13316 
13317 static void
13318 cmd_showport_macs_parsed(void *parsed_result,
13319 		__rte_unused struct cmdline *cl,
13320 		__rte_unused void *data)
13321 {
13322 	struct cmd_showport_macs_result *res = parsed_result;
13323 
13324 	if (port_id_is_invalid(res->cmd_pid, ENABLED_WARN))
13325 		return;
13326 
13327 	if (!strcmp(res->cmd_keyword, "macs"))
13328 		show_macs(res->cmd_pid);
13329 	else if (!strcmp(res->cmd_keyword, "mcast_macs"))
13330 		show_mcast_macs(res->cmd_pid);
13331 }
13332 
13333 static cmdline_parse_token_string_t cmd_showport_macs_show =
13334 	TOKEN_STRING_INITIALIZER(struct cmd_showport_macs_result,
13335 			cmd_show, "show");
13336 static cmdline_parse_token_string_t cmd_showport_macs_port =
13337 	TOKEN_STRING_INITIALIZER(struct cmd_showport_macs_result,
13338 			cmd_port, "port");
13339 static cmdline_parse_token_num_t cmd_showport_macs_pid =
13340 	TOKEN_NUM_INITIALIZER(struct cmd_showport_macs_result,
13341 			cmd_pid, RTE_UINT16);
13342 static cmdline_parse_token_string_t cmd_showport_macs_keyword =
13343 	TOKEN_STRING_INITIALIZER(struct cmd_showport_macs_result,
13344 			cmd_keyword, "macs#mcast_macs");
13345 
13346 static cmdline_parse_inst_t cmd_showport_macs = {
13347 	.f = cmd_showport_macs_parsed,
13348 	.data = NULL,
13349 	.help_str = "show port <port_id> macs|mcast_macs",
13350 	.tokens = {
13351 		(void *)&cmd_showport_macs_show,
13352 		(void *)&cmd_showport_macs_port,
13353 		(void *)&cmd_showport_macs_pid,
13354 		(void *)&cmd_showport_macs_keyword,
13355 		NULL,
13356 	},
13357 };
13358 
13359 /* *** show flow transfer proxy port ID for the given port *** */
13360 struct cmd_show_port_flow_transfer_proxy_result {
13361 	cmdline_fixed_string_t show;
13362 	cmdline_fixed_string_t port;
13363 	portid_t port_id;
13364 	cmdline_fixed_string_t flow;
13365 	cmdline_fixed_string_t transfer;
13366 	cmdline_fixed_string_t proxy;
13367 };
13368 
13369 static cmdline_parse_token_string_t cmd_show_port_flow_transfer_proxy_show =
13370 	TOKEN_STRING_INITIALIZER
13371 		(struct cmd_show_port_flow_transfer_proxy_result,
13372 		 show, "show");
13373 static cmdline_parse_token_string_t cmd_show_port_flow_transfer_proxy_port =
13374 	TOKEN_STRING_INITIALIZER
13375 		(struct cmd_show_port_flow_transfer_proxy_result,
13376 		 port, "port");
13377 static cmdline_parse_token_num_t cmd_show_port_flow_transfer_proxy_port_id =
13378 	TOKEN_NUM_INITIALIZER
13379 		(struct cmd_show_port_flow_transfer_proxy_result,
13380 		 port_id, RTE_UINT16);
13381 static cmdline_parse_token_string_t cmd_show_port_flow_transfer_proxy_flow =
13382 	TOKEN_STRING_INITIALIZER
13383 		(struct cmd_show_port_flow_transfer_proxy_result,
13384 		 flow, "flow");
13385 static cmdline_parse_token_string_t cmd_show_port_flow_transfer_proxy_transfer =
13386 	TOKEN_STRING_INITIALIZER
13387 		(struct cmd_show_port_flow_transfer_proxy_result,
13388 		 transfer, "transfer");
13389 static cmdline_parse_token_string_t cmd_show_port_flow_transfer_proxy_proxy =
13390 	TOKEN_STRING_INITIALIZER
13391 		(struct cmd_show_port_flow_transfer_proxy_result,
13392 		 proxy, "proxy");
13393 
13394 static void
13395 cmd_show_port_flow_transfer_proxy_parsed(void *parsed_result,
13396 					 __rte_unused struct cmdline *cl,
13397 					 __rte_unused void *data)
13398 {
13399 	struct cmd_show_port_flow_transfer_proxy_result *res = parsed_result;
13400 	portid_t proxy_port_id;
13401 	int ret;
13402 
13403 	printf("\n");
13404 
13405 	ret = rte_flow_pick_transfer_proxy(res->port_id, &proxy_port_id, NULL);
13406 	if (ret != 0) {
13407 		fprintf(stderr, "Failed to pick transfer proxy: %s\n",
13408 			rte_strerror(-ret));
13409 		return;
13410 	}
13411 
13412 	printf("Transfer proxy port ID: %u\n\n", proxy_port_id);
13413 }
13414 
13415 static cmdline_parse_inst_t cmd_show_port_flow_transfer_proxy = {
13416 	.f = cmd_show_port_flow_transfer_proxy_parsed,
13417 	.data = NULL,
13418 	.help_str = "show port <port_id> flow transfer proxy",
13419 	.tokens = {
13420 		(void *)&cmd_show_port_flow_transfer_proxy_show,
13421 		(void *)&cmd_show_port_flow_transfer_proxy_port,
13422 		(void *)&cmd_show_port_flow_transfer_proxy_port_id,
13423 		(void *)&cmd_show_port_flow_transfer_proxy_flow,
13424 		(void *)&cmd_show_port_flow_transfer_proxy_transfer,
13425 		(void *)&cmd_show_port_flow_transfer_proxy_proxy,
13426 		NULL,
13427 	}
13428 };
13429 
13430 /* *** configure port txq affinity value *** */
13431 struct cmd_config_tx_affinity_map {
13432 	cmdline_fixed_string_t port;
13433 	cmdline_fixed_string_t config;
13434 	portid_t portid;
13435 	cmdline_fixed_string_t txq;
13436 	uint16_t qid;
13437 	cmdline_fixed_string_t affinity;
13438 	uint8_t value;
13439 };
13440 
13441 static void
13442 cmd_config_tx_affinity_map_parsed(void *parsed_result,
13443 				  __rte_unused struct cmdline *cl,
13444 				  __rte_unused void *data)
13445 {
13446 	struct cmd_config_tx_affinity_map *res = parsed_result;
13447 	int ret;
13448 
13449 	if (port_id_is_invalid(res->portid, ENABLED_WARN))
13450 		return;
13451 
13452 	if (res->portid == (portid_t)RTE_PORT_ALL) {
13453 		printf("Invalid port id\n");
13454 		return;
13455 	}
13456 
13457 	if (strcmp(res->txq, "txq")) {
13458 		printf("Unknown parameter\n");
13459 		return;
13460 	}
13461 	if (tx_queue_id_is_invalid(res->qid))
13462 		return;
13463 
13464 	ret = rte_eth_dev_count_aggr_ports(res->portid);
13465 	if (ret < 0) {
13466 		printf("Failed to count the aggregated ports: (%s)\n",
13467 			strerror(-ret));
13468 		return;
13469 	}
13470 
13471 	ret = rte_eth_dev_map_aggr_tx_affinity(res->portid, res->qid, res->value);
13472 	if (ret != 0) {
13473 		printf("Failed to map tx queue with an aggregated port: %s\n",
13474 			rte_strerror(-ret));
13475 		return;
13476 	}
13477 }
13478 
13479 cmdline_parse_token_string_t cmd_config_tx_affinity_map_port =
13480 	TOKEN_STRING_INITIALIZER(struct cmd_config_tx_affinity_map,
13481 				 port, "port");
13482 cmdline_parse_token_string_t cmd_config_tx_affinity_map_config =
13483 	TOKEN_STRING_INITIALIZER(struct cmd_config_tx_affinity_map,
13484 				 config, "config");
13485 cmdline_parse_token_num_t cmd_config_tx_affinity_map_portid =
13486 	TOKEN_NUM_INITIALIZER(struct cmd_config_tx_affinity_map,
13487 				 portid, RTE_UINT16);
13488 cmdline_parse_token_string_t cmd_config_tx_affinity_map_txq =
13489 	TOKEN_STRING_INITIALIZER(struct cmd_config_tx_affinity_map,
13490 				 txq, "txq");
13491 cmdline_parse_token_num_t cmd_config_tx_affinity_map_qid =
13492 	TOKEN_NUM_INITIALIZER(struct cmd_config_tx_affinity_map,
13493 			      qid, RTE_UINT16);
13494 cmdline_parse_token_string_t cmd_config_tx_affinity_map_affinity =
13495 	TOKEN_STRING_INITIALIZER(struct cmd_config_tx_affinity_map,
13496 				 affinity, "affinity");
13497 cmdline_parse_token_num_t cmd_config_tx_affinity_map_value =
13498 	TOKEN_NUM_INITIALIZER(struct cmd_config_tx_affinity_map,
13499 			      value, RTE_UINT8);
13500 
13501 static cmdline_parse_inst_t cmd_config_tx_affinity_map = {
13502 	.f = cmd_config_tx_affinity_map_parsed,
13503 	.data = (void *)0,
13504 	.help_str = "port config <port_id> txq <queue_id> affinity <value>",
13505 	.tokens = {
13506 		(void *)&cmd_config_tx_affinity_map_port,
13507 		(void *)&cmd_config_tx_affinity_map_config,
13508 		(void *)&cmd_config_tx_affinity_map_portid,
13509 		(void *)&cmd_config_tx_affinity_map_txq,
13510 		(void *)&cmd_config_tx_affinity_map_qid,
13511 		(void *)&cmd_config_tx_affinity_map_affinity,
13512 		(void *)&cmd_config_tx_affinity_map_value,
13513 		NULL,
13514 	},
13515 };
13516 
13517 /* *** SET THE LED FOR CERTAIN PORT TO ON/OFF *** */
13518 struct cmd_dev_led_result {
13519 	cmdline_fixed_string_t set;
13520 	cmdline_fixed_string_t port;
13521 	portid_t port_id;
13522 	cmdline_fixed_string_t led;
13523 	cmdline_fixed_string_t state;
13524 };
13525 
13526 static void
13527 cmd_set_dev_led_parsed(void *parsed_result,
13528 		__rte_unused struct cmdline *cl,
13529 		__rte_unused void *data)
13530 {
13531 	struct cmd_dev_led_result *res = parsed_result;
13532 
13533 	if (strcmp(res->state, "on") == 0)
13534 		set_dev_led(res->port_id, true);
13535 	else
13536 		set_dev_led(res->port_id, false);
13537 }
13538 
13539 static cmdline_parse_token_string_t cmd_dev_led_set =
13540 	TOKEN_STRING_INITIALIZER(struct cmd_dev_led_result, set, "set");
13541 static cmdline_parse_token_string_t cmd_dev_led_port =
13542 	TOKEN_STRING_INITIALIZER(struct cmd_dev_led_result, port, "port");
13543 static cmdline_parse_token_num_t cmd_dev_led_port_id =
13544 	TOKEN_NUM_INITIALIZER(struct cmd_dev_led_result, port_id, RTE_UINT16);
13545 static cmdline_parse_token_string_t cmd_dev_led =
13546 	TOKEN_STRING_INITIALIZER(struct cmd_dev_led_result, led, "led");
13547 static cmdline_parse_token_string_t cmd_dev_state =
13548 	TOKEN_STRING_INITIALIZER(struct cmd_dev_led_result, state, "on#off");
13549 
13550 static cmdline_parse_inst_t cmd_set_dev_led = {
13551 	.f = cmd_set_dev_led_parsed,
13552 	.data = NULL,
13553 	.help_str = "set port <port_id> led <on/off>",
13554 	.tokens = {
13555 		(void *)&cmd_dev_led_set,
13556 		(void *)&cmd_dev_led_port,
13557 		(void *)&cmd_dev_led_port_id,
13558 		(void *)&cmd_dev_led,
13559 		(void *)&cmd_dev_state,
13560 		NULL,
13561 	},
13562 };
13563 
13564 /* ******************************************************************************** */
13565 
13566 /* list of instructions */
13567 static cmdline_parse_ctx_t builtin_ctx[] = {
13568 	&cmd_help_brief,
13569 	&cmd_help_long,
13570 	&cmd_quit,
13571 	&cmd_load_from_file,
13572 	&cmd_showport,
13573 	&cmd_showqueue,
13574 	&cmd_showeeprom,
13575 	&cmd_seteeprom,
13576 	&cmd_showportall,
13577 	&cmd_representor_info,
13578 	&cmd_showdevice,
13579 	&cmd_showcfg,
13580 	&cmd_showfwdall,
13581 	&cmd_start,
13582 	&cmd_start_tx_first,
13583 	&cmd_start_tx_first_n,
13584 	&cmd_set_link_up,
13585 	&cmd_set_link_down,
13586 	&cmd_reset,
13587 	&cmd_set_numbers,
13588 	&cmd_set_log,
13589 	&cmd_set_rxoffs,
13590 	&cmd_set_rxpkts,
13591 	&cmd_set_rxhdrs,
13592 	&cmd_set_txpkts,
13593 	&cmd_set_txsplit,
13594 	&cmd_set_txtimes,
13595 	&cmd_set_fwd_list,
13596 	&cmd_set_fwd_mask,
13597 	&cmd_set_fwd_mode,
13598 	&cmd_set_fwd_retry_mode,
13599 	&cmd_set_burst_tx_retry,
13600 	&cmd_set_promisc_mode_one,
13601 	&cmd_set_promisc_mode_all,
13602 	&cmd_set_allmulti_mode_one,
13603 	&cmd_set_allmulti_mode_all,
13604 	&cmd_set_flush_rx,
13605 	&cmd_set_link_check,
13606 	&cmd_vlan_offload,
13607 	&cmd_vlan_tpid,
13608 	&cmd_rx_vlan_filter_all,
13609 	&cmd_rx_vlan_filter,
13610 	&cmd_tx_vlan_set,
13611 	&cmd_tx_vlan_set_qinq,
13612 	&cmd_tx_vlan_reset,
13613 	&cmd_tx_vlan_set_pvid,
13614 	&cmd_csum_set,
13615 	&cmd_csum_show,
13616 	&cmd_csum_tunnel,
13617 	&cmd_csum_mac_swap,
13618 	&cmd_tso_set,
13619 	&cmd_tso_show,
13620 	&cmd_tunnel_tso_set,
13621 	&cmd_tunnel_tso_show,
13622 #ifdef RTE_LIB_GRO
13623 	&cmd_gro_enable,
13624 	&cmd_gro_flush,
13625 	&cmd_gro_show,
13626 #endif
13627 #ifdef RTE_LIB_GSO
13628 	&cmd_gso_enable,
13629 	&cmd_gso_size,
13630 	&cmd_gso_show,
13631 #endif
13632 	&cmd_link_flow_control_set,
13633 	&cmd_link_flow_control_set_rx,
13634 	&cmd_link_flow_control_set_tx,
13635 	&cmd_link_flow_control_set_hw,
13636 	&cmd_link_flow_control_set_lw,
13637 	&cmd_link_flow_control_set_pt,
13638 	&cmd_link_flow_control_set_xon,
13639 	&cmd_link_flow_control_set_macfwd,
13640 	&cmd_link_flow_control_set_autoneg,
13641 	&cmd_link_flow_control_show,
13642 	&cmd_priority_flow_control_set,
13643 	&cmd_queue_priority_flow_control_set,
13644 	&cmd_config_dcb,
13645 	&cmd_read_rxd_txd,
13646 	&cmd_stop,
13647 	&cmd_mac_addr,
13648 	&cmd_set_fwd_eth_peer,
13649 	&cmd_set_qmap,
13650 	&cmd_set_xstats_hide_zero,
13651 	&cmd_set_record_core_cycles,
13652 	&cmd_set_record_burst_stats,
13653 	&cmd_operate_port,
13654 	&cmd_operate_specific_port,
13655 	&cmd_operate_attach_port,
13656 	&cmd_operate_detach_port,
13657 	&cmd_operate_detach_device,
13658 	&cmd_set_port_setup_on,
13659 	&cmd_config_speed_all,
13660 	&cmd_config_speed_specific,
13661 	&cmd_config_speed_lanes_all,
13662 	&cmd_config_speed_lanes_specific,
13663 	&cmd_show_speed_lanes,
13664 	&cmd_config_loopback_all,
13665 	&cmd_config_loopback_specific,
13666 	&cmd_config_rx_tx,
13667 	&cmd_config_mtu,
13668 	&cmd_config_max_pkt_len,
13669 	&cmd_config_max_lro_pkt_size,
13670 	&cmd_config_rx_mode_flag,
13671 	&cmd_config_rss,
13672 	&cmd_config_rxtx_ring_size,
13673 	&cmd_config_rxtx_queue,
13674 	&cmd_config_deferred_start_rxtx_queue,
13675 	&cmd_setup_rxtx_queue,
13676 	&cmd_config_rss_reta,
13677 	&cmd_showport_reta,
13678 	&cmd_showport_macs,
13679 	&cmd_show_port_flow_transfer_proxy,
13680 	&cmd_config_burst,
13681 	&cmd_config_thresh,
13682 	&cmd_config_threshold,
13683 	&cmd_set_uc_hash_filter,
13684 	&cmd_set_uc_all_hash_filter,
13685 	&cmd_vf_mac_addr_filter,
13686 	&cmd_queue_rate_limit,
13687 	&cmd_tunnel_udp_config,
13688 	&cmd_showport_rss_hash,
13689 	&cmd_showport_rss_hash_key,
13690 	&cmd_showport_rss_hash_algo,
13691 	&cmd_config_rss_hash_key,
13692 	&cmd_config_rss_hash_algo,
13693 	&cmd_cleanup_txq_mbufs,
13694 	&cmd_dump,
13695 	&cmd_dump_one,
13696 	&cmd_flow,
13697 	&cmd_show_port_meter_cap,
13698 	&cmd_add_port_meter_profile_srtcm,
13699 	&cmd_add_port_meter_profile_trtcm,
13700 	&cmd_add_port_meter_profile_trtcm_rfc4115,
13701 	&cmd_del_port_meter_profile,
13702 	&cmd_create_port_meter,
13703 	&cmd_enable_port_meter,
13704 	&cmd_disable_port_meter,
13705 	&cmd_del_port_meter,
13706 	&cmd_del_port_meter_policy,
13707 	&cmd_set_port_meter_profile,
13708 	&cmd_set_port_meter_dscp_table,
13709 	&cmd_set_port_meter_vlan_table,
13710 	&cmd_set_port_meter_in_proto,
13711 	&cmd_get_port_meter_in_proto,
13712 	&cmd_get_port_meter_in_proto_prio,
13713 	&cmd_set_port_meter_stats_mask,
13714 	&cmd_show_port_meter_stats,
13715 	&cmd_mcast_addr,
13716 	&cmd_mcast_addr_flush,
13717 	&cmd_set_vf_vlan_anti_spoof,
13718 	&cmd_set_vf_mac_anti_spoof,
13719 	&cmd_set_vf_vlan_stripq,
13720 	&cmd_set_vf_vlan_insert,
13721 	&cmd_set_tx_loopback,
13722 	&cmd_set_all_queues_drop_en,
13723 	&cmd_set_vf_traffic,
13724 	&cmd_set_vf_rxmode,
13725 	&cmd_vf_rate_limit,
13726 	&cmd_vf_rxvlan_filter,
13727 	&cmd_set_vf_mac_addr,
13728 	&cmd_set_vxlan,
13729 	&cmd_set_vxlan_tos_ttl,
13730 	&cmd_set_vxlan_with_vlan,
13731 	&cmd_set_nvgre,
13732 	&cmd_set_nvgre_with_vlan,
13733 	&cmd_set_l2_encap,
13734 	&cmd_set_l2_encap_with_vlan,
13735 	&cmd_set_l2_decap,
13736 	&cmd_set_l2_decap_with_vlan,
13737 	&cmd_set_mplsogre_encap,
13738 	&cmd_set_mplsogre_encap_with_vlan,
13739 	&cmd_set_mplsogre_decap,
13740 	&cmd_set_mplsogre_decap_with_vlan,
13741 	&cmd_set_mplsoudp_encap,
13742 	&cmd_set_mplsoudp_encap_with_vlan,
13743 	&cmd_set_mplsoudp_decap,
13744 	&cmd_set_mplsoudp_decap_with_vlan,
13745 	&cmd_set_conntrack_common,
13746 	&cmd_set_conntrack_dir,
13747 	&cmd_show_vf_stats,
13748 	&cmd_clear_vf_stats,
13749 	&cmd_show_port_supported_ptypes,
13750 	&cmd_set_port_ptypes,
13751 	&cmd_show_port_tm_cap,
13752 	&cmd_show_port_tm_level_cap,
13753 	&cmd_show_port_tm_node,
13754 	&cmd_show_port_tm_node_cap,
13755 	&cmd_show_port_tm_node_type,
13756 	&cmd_show_port_tm_node_stats,
13757 	&cmd_add_port_tm_node_shaper_profile,
13758 	&cmd_del_port_tm_node_shaper_profile,
13759 	&cmd_add_port_tm_node_shared_shaper,
13760 	&cmd_del_port_tm_node_shared_shaper,
13761 	&cmd_add_port_tm_node_wred_profile,
13762 	&cmd_del_port_tm_node_wred_profile,
13763 	&cmd_set_port_tm_node_shaper_profile,
13764 	&cmd_add_port_tm_nonleaf_node,
13765 	&cmd_add_port_tm_nonleaf_node_pmode,
13766 	&cmd_add_port_tm_leaf_node,
13767 	&cmd_del_port_tm_node,
13768 	&cmd_set_port_tm_node_parent,
13769 	&cmd_suspend_port_tm_node,
13770 	&cmd_resume_port_tm_node,
13771 	&cmd_port_tm_hierarchy_commit,
13772 	&cmd_port_tm_mark_ip_ecn,
13773 	&cmd_port_tm_mark_ip_dscp,
13774 	&cmd_port_tm_mark_vlan_dei,
13775 	&cmd_cfg_tunnel_udp_port,
13776 	&cmd_rx_offload_get_capa,
13777 	&cmd_rx_offload_get_configuration,
13778 	&cmd_config_per_port_rx_offload,
13779 	&cmd_config_all_port_rx_offload,
13780 	&cmd_config_per_queue_rx_offload,
13781 	&cmd_tx_offload_get_capa,
13782 	&cmd_tx_offload_get_configuration,
13783 	&cmd_config_per_port_tx_offload,
13784 	&cmd_config_all_port_tx_offload,
13785 	&cmd_config_per_queue_tx_offload,
13786 #ifdef RTE_LIB_BPF
13787 	&cmd_operate_bpf_ld_parse,
13788 	&cmd_operate_bpf_unld_parse,
13789 #endif
13790 	&cmd_config_tx_metadata_specific,
13791 	&cmd_show_tx_metadata,
13792 	&cmd_show_rx_tx_desc_status,
13793 	&cmd_show_rx_tx_queue_desc_used_count,
13794 	&cmd_set_raw,
13795 	&cmd_show_set_raw,
13796 	&cmd_show_set_raw_all,
13797 	&cmd_config_tx_dynf_specific,
13798 	&cmd_show_fec_mode,
13799 	&cmd_set_fec_mode,
13800 	&cmd_set_rxq_avail_thresh,
13801 	&cmd_show_capability,
13802 	&cmd_set_flex_is_pattern,
13803 	&cmd_set_flex_spec_pattern,
13804 	&cmd_show_port_cman_capa,
13805 	&cmd_show_port_cman_config,
13806 	&cmd_set_port_cman_config,
13807 	&cmd_config_tx_affinity_map,
13808 	&cmd_set_dev_led,
13809 	NULL,
13810 };
13811 
13812 void
13813 testpmd_add_driver_commands(struct testpmd_driver_commands *c)
13814 {
13815 	TAILQ_INSERT_TAIL(&driver_commands_head, c, next);
13816 }
13817 
13818 int
13819 init_cmdline(void)
13820 {
13821 	struct testpmd_driver_commands *c;
13822 	unsigned int count;
13823 	unsigned int i;
13824 
13825 	/* initialize non-constant commands */
13826 	cmd_set_fwd_mode_init();
13827 	cmd_set_fwd_retry_mode_init();
13828 
13829 	count = 0;
13830 	for (i = 0; builtin_ctx[i] != NULL; i++)
13831 		count++;
13832 	TAILQ_FOREACH(c, &driver_commands_head, next) {
13833 		for (i = 0; c->commands[i].ctx != NULL; i++)
13834 			count++;
13835 	}
13836 
13837 	/* cmdline expects a NULL terminated array */
13838 	main_ctx = calloc(count + 1, sizeof(main_ctx[0]));
13839 	if (main_ctx == NULL)
13840 		return -1;
13841 
13842 	count = 0;
13843 	for (i = 0; builtin_ctx[i] != NULL; i++, count++)
13844 		main_ctx[count] = builtin_ctx[i];
13845 	TAILQ_FOREACH(c, &driver_commands_head, next) {
13846 		for (i = 0; c->commands[i].ctx != NULL; i++, count++)
13847 			main_ctx[count] = c->commands[i].ctx;
13848 	}
13849 
13850 	return 0;
13851 }
13852 
13853 /* read cmdline commands from file */
13854 void
13855 cmdline_read_from_file(const char *filename)
13856 {
13857 	struct cmdline *cl;
13858 
13859 	/* cmdline_file_new does not produce any output which is not ideal here.
13860 	 * Much better to show output of the commands, so we open filename directly
13861 	 * and then pass that to cmdline_new with stdout as the output path.
13862 	 */
13863 	int fd = open(filename, O_RDONLY);
13864 	if (fd < 0) {
13865 		fprintf(stderr, "Failed to open file %s: %s\n",
13866 			filename, strerror(errno));
13867 		return;
13868 	}
13869 
13870 	cl = cmdline_new(main_ctx, "testpmd> ", fd, STDOUT_FILENO);
13871 	if (cl == NULL) {
13872 		fprintf(stderr,
13873 			"Failed to create file based cmdline context: %s\n",
13874 			filename);
13875 		return;
13876 	}
13877 
13878 	cmdline_interact(cl);
13879 	cmdline_quit(cl);
13880 
13881 	cmdline_free(cl);
13882 
13883 	printf("Read CLI commands from %s\n", filename);
13884 }
13885 
13886 void
13887 prompt_exit(void)
13888 {
13889 	cmdline_quit(testpmd_cl);
13890 }
13891 
13892 /* prompt function, called from main on MAIN lcore */
13893 void
13894 prompt(void)
13895 {
13896 	testpmd_cl = cmdline_stdin_new(main_ctx, "testpmd> ");
13897 	if (testpmd_cl == NULL) {
13898 		fprintf(stderr,
13899 			"Failed to create stdin based cmdline context\n");
13900 		return;
13901 	}
13902 
13903 	cmdline_interact(testpmd_cl);
13904 	cmdline_stdin_exit(testpmd_cl);
13905 }
13906 
13907 void
13908 cmd_reconfig_device_queue(portid_t id, uint8_t dev, uint8_t queue)
13909 {
13910 	if (id == (portid_t)RTE_PORT_ALL) {
13911 		portid_t pid;
13912 
13913 		RTE_ETH_FOREACH_DEV(pid) {
13914 			/* check if need_reconfig has been set to 1 */
13915 			if (ports[pid].need_reconfig == 0)
13916 				ports[pid].need_reconfig = dev;
13917 			/* check if need_reconfig_queues has been set to 1 */
13918 			if (ports[pid].need_reconfig_queues == 0)
13919 				ports[pid].need_reconfig_queues = queue;
13920 		}
13921 	} else if (!port_id_is_invalid(id, DISABLED_WARN)) {
13922 		/* check if need_reconfig has been set to 1 */
13923 		if (ports[id].need_reconfig == 0)
13924 			ports[id].need_reconfig = dev;
13925 		/* check if need_reconfig_queues has been set to 1 */
13926 		if (ports[id].need_reconfig_queues == 0)
13927 			ports[id].need_reconfig_queues = queue;
13928 	}
13929 }
13930