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