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