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