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