xref: /dpdk/app/test-pmd/cmdline.c (revision 938a184a1870bcc139b49a284ae599457e8fb8ce)
1 /*-
2  *   BSD LICENSE
3  *
4  *   Copyright(c) 2010-2016 Intel Corporation. All rights reserved.
5  *   Copyright(c) 2014 6WIND S.A.
6  *   All rights reserved.
7  *
8  *   Redistribution and use in source and binary forms, with or without
9  *   modification, are permitted provided that the following conditions
10  *   are met:
11  *
12  *     * Redistributions of source code must retain the above copyright
13  *       notice, this list of conditions and the following disclaimer.
14  *     * Redistributions in binary form must reproduce the above copyright
15  *       notice, this list of conditions and the following disclaimer in
16  *       the documentation and/or other materials provided with the
17  *       distribution.
18  *     * Neither the name of Intel Corporation nor the names of its
19  *       contributors may be used to endorse or promote products derived
20  *       from this software without specific prior written permission.
21  *
22  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
25  *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
26  *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
27  *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
28  *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29  *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30  *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31  *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
32  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33  */
34 
35 #include <stdarg.h>
36 #include <errno.h>
37 #include <stdio.h>
38 #include <stdint.h>
39 #include <stdarg.h>
40 #include <string.h>
41 #include <termios.h>
42 #include <unistd.h>
43 #include <inttypes.h>
44 #ifndef __linux__
45 #ifndef __FreeBSD__
46 #include <net/socket.h>
47 #else
48 #include <sys/socket.h>
49 #endif
50 #endif
51 #include <netinet/in.h>
52 
53 #include <sys/queue.h>
54 
55 #include <rte_common.h>
56 #include <rte_byteorder.h>
57 #include <rte_log.h>
58 #include <rte_debug.h>
59 #include <rte_cycles.h>
60 #include <rte_memory.h>
61 #include <rte_memzone.h>
62 #include <rte_malloc.h>
63 #include <rte_launch.h>
64 #include <rte_eal.h>
65 #include <rte_per_lcore.h>
66 #include <rte_lcore.h>
67 #include <rte_atomic.h>
68 #include <rte_branch_prediction.h>
69 #include <rte_ring.h>
70 #include <rte_mempool.h>
71 #include <rte_interrupts.h>
72 #include <rte_pci.h>
73 #include <rte_ether.h>
74 #include <rte_ethdev.h>
75 #include <rte_string_fns.h>
76 #include <rte_devargs.h>
77 #include <rte_eth_ctrl.h>
78 #include <rte_flow.h>
79 
80 #include <cmdline_rdline.h>
81 #include <cmdline_parse.h>
82 #include <cmdline_parse_num.h>
83 #include <cmdline_parse_string.h>
84 #include <cmdline_parse_ipaddr.h>
85 #include <cmdline_parse_etheraddr.h>
86 #include <cmdline_socket.h>
87 #include <cmdline.h>
88 #ifdef RTE_LIBRTE_PMD_BOND
89 #include <rte_eth_bond.h>
90 #endif
91 #ifdef RTE_LIBRTE_IXGBE_PMD
92 #include <rte_pmd_ixgbe.h>
93 #endif
94 #include "testpmd.h"
95 
96 static struct cmdline *testpmd_cl;
97 
98 static void cmd_reconfig_device_queue(portid_t id, uint8_t dev, uint8_t queue);
99 
100 /* *** Help command with introduction. *** */
101 struct cmd_help_brief_result {
102 	cmdline_fixed_string_t help;
103 };
104 
105 static void cmd_help_brief_parsed(__attribute__((unused)) void *parsed_result,
106                                   struct cmdline *cl,
107                                   __attribute__((unused)) void *data)
108 {
109 	cmdline_printf(
110 		cl,
111 		"\n"
112 		"Help is available for the following sections:\n\n"
113 		"    help control    : Start and stop forwarding.\n"
114 		"    help display    : Displaying port, stats and config "
115 		"information.\n"
116 		"    help config     : Configuration information.\n"
117 		"    help ports      : Configuring ports.\n"
118 		"    help registers  : Reading and setting port registers.\n"
119 		"    help filters    : Filters configuration help.\n"
120 		"    help all        : All of the above sections.\n\n"
121 	);
122 
123 }
124 
125 cmdline_parse_token_string_t cmd_help_brief_help =
126 	TOKEN_STRING_INITIALIZER(struct cmd_help_brief_result, help, "help");
127 
128 cmdline_parse_inst_t cmd_help_brief = {
129 	.f = cmd_help_brief_parsed,
130 	.data = NULL,
131 	.help_str = "help: Show help",
132 	.tokens = {
133 		(void *)&cmd_help_brief_help,
134 		NULL,
135 	},
136 };
137 
138 /* *** Help command with help sections. *** */
139 struct cmd_help_long_result {
140 	cmdline_fixed_string_t help;
141 	cmdline_fixed_string_t section;
142 };
143 
144 static void cmd_help_long_parsed(void *parsed_result,
145                                  struct cmdline *cl,
146                                  __attribute__((unused)) void *data)
147 {
148 	int show_all = 0;
149 	struct cmd_help_long_result *res = parsed_result;
150 
151 	if (!strcmp(res->section, "all"))
152 		show_all = 1;
153 
154 	if (show_all || !strcmp(res->section, "control")) {
155 
156 		cmdline_printf(
157 			cl,
158 			"\n"
159 			"Control forwarding:\n"
160 			"-------------------\n\n"
161 
162 			"start\n"
163 			"    Start packet forwarding with current configuration.\n\n"
164 
165 			"start tx_first\n"
166 			"    Start packet forwarding with current config"
167 			" after sending one burst of packets.\n\n"
168 
169 			"stop\n"
170 			"    Stop packet forwarding, and display accumulated"
171 			" statistics.\n\n"
172 
173 			"quit\n"
174 			"    Quit to prompt.\n\n"
175 		);
176 	}
177 
178 	if (show_all || !strcmp(res->section, "display")) {
179 
180 		cmdline_printf(
181 			cl,
182 			"\n"
183 			"Display:\n"
184 			"--------\n\n"
185 
186 			"show port (info|stats|xstats|fdir|stat_qmap|dcb_tc) (port_id|all)\n"
187 			"    Display information for port_id, or all.\n\n"
188 
189 			"show port X rss reta (size) (mask0,mask1,...)\n"
190 			"    Display the rss redirection table entry indicated"
191 			" by masks on port X. size is used to indicate the"
192 			" hardware supported reta size\n\n"
193 
194 			"show port rss-hash ipv4|ipv4-frag|ipv4-tcp|ipv4-udp|"
195 			"ipv4-sctp|ipv4-other|ipv6|ipv6-frag|ipv6-tcp|ipv6-udp|ipv6-sctp|"
196 			"ipv6-other|l2-payload|ipv6-ex|ipv6-tcp-ex|ipv6-udp-ex [key]\n"
197 			"    Display the RSS hash functions and RSS hash key"
198 			" of port X\n\n"
199 
200 			"clear port (info|stats|xstats|fdir|stat_qmap) (port_id|all)\n"
201 			"    Clear information for port_id, or all.\n\n"
202 
203 			"show (rxq|txq) info (port_id) (queue_id)\n"
204 			"    Display information for configured RX/TX queue.\n\n"
205 
206 			"show config (rxtx|cores|fwd|txpkts)\n"
207 			"    Display the given configuration.\n\n"
208 
209 			"read rxd (port_id) (queue_id) (rxd_id)\n"
210 			"    Display an RX descriptor of a port RX queue.\n\n"
211 
212 			"read txd (port_id) (queue_id) (txd_id)\n"
213 			"    Display a TX descriptor of a port TX queue.\n\n"
214 		);
215 	}
216 
217 	if (show_all || !strcmp(res->section, "config")) {
218 		cmdline_printf(
219 			cl,
220 			"\n"
221 			"Configuration:\n"
222 			"--------------\n"
223 			"Configuration changes only become active when"
224 			" forwarding is started/restarted.\n\n"
225 
226 			"set default\n"
227 			"    Reset forwarding to the default configuration.\n\n"
228 
229 			"set verbose (level)\n"
230 			"    Set the debug verbosity level X.\n\n"
231 
232 			"set nbport (num)\n"
233 			"    Set number of ports.\n\n"
234 
235 			"set nbcore (num)\n"
236 			"    Set number of cores.\n\n"
237 
238 			"set coremask (mask)\n"
239 			"    Set the forwarding cores hexadecimal mask.\n\n"
240 
241 			"set portmask (mask)\n"
242 			"    Set the forwarding ports hexadecimal mask.\n\n"
243 
244 			"set burst (num)\n"
245 			"    Set number of packets per burst.\n\n"
246 
247 			"set burst tx delay (microseconds) retry (num)\n"
248 			"    Set the transmit delay time and number of retries,"
249 			" effective when retry is enabled.\n\n"
250 
251 			"set txpkts (x[,y]*)\n"
252 			"    Set the length of each segment of TXONLY"
253 			" and optionally CSUM packets.\n\n"
254 
255 			"set txsplit (off|on|rand)\n"
256 			"    Set the split policy for the TX packets."
257 			" Right now only applicable for CSUM and TXONLY"
258 			" modes\n\n"
259 
260 			"set corelist (x[,y]*)\n"
261 			"    Set the list of forwarding cores.\n\n"
262 
263 			"set portlist (x[,y]*)\n"
264 			"    Set the list of forwarding ports.\n\n"
265 
266 #ifdef RTE_LIBRTE_IXGBE_PMD
267 			"set tx loopback (port_id) (on|off)\n"
268 			"    Enable or disable tx loopback.\n\n"
269 
270 			"set all queues drop (port_id) (on|off)\n"
271 			"    Set drop enable bit for all queues.\n\n"
272 
273 			"set vf split drop (port_id) (vf_id) (on|off)\n"
274 			"    Set split drop enable bit for a VF from the PF.\n\n"
275 
276 			"set vf mac antispoof (port_id) (vf_id) (on|off).\n"
277 			"    Set MAC antispoof for a VF from the PF.\n\n"
278 #endif
279 
280 			"vlan set strip (on|off) (port_id)\n"
281 			"    Set the VLAN strip on a port.\n\n"
282 
283 			"vlan set stripq (on|off) (port_id,queue_id)\n"
284 			"    Set the VLAN strip for a queue on a port.\n\n"
285 
286 #ifdef RTE_LIBRTE_IXGBE_PMD
287 			"set vf vlan stripq (port_id) (vf_id) (on|off)\n"
288 			"    Set the VLAN strip for all queues in a pool for a VF from the PF.\n\n"
289 
290 			"set vf vlan insert (port_id) (vf_id) (vlan_id)\n"
291 			"    Set VLAN insert for a VF from the PF.\n\n"
292 
293 			"set vf vlan antispoof (port_id) (vf_id) (on|off)\n"
294 			"    Set VLAN antispoof for a VF from the PF.\n\n"
295 #endif
296 
297 			"vlan set filter (on|off) (port_id)\n"
298 			"    Set the VLAN filter on a port.\n\n"
299 
300 			"vlan set qinq (on|off) (port_id)\n"
301 			"    Set the VLAN QinQ (extended queue in queue)"
302 			" on a port.\n\n"
303 
304 			"vlan set (inner|outer) tpid (value) (port_id)\n"
305 			"    Set the VLAN TPID for Packet Filtering on"
306 			" a port\n\n"
307 
308 			"rx_vlan add (vlan_id|all) (port_id)\n"
309 			"    Add a vlan_id, or all identifiers, to the set"
310 			" of VLAN identifiers filtered by port_id.\n\n"
311 
312 			"rx_vlan rm (vlan_id|all) (port_id)\n"
313 			"    Remove a vlan_id, or all identifiers, from the set"
314 			" of VLAN identifiers filtered by port_id.\n\n"
315 
316 			"rx_vlan add (vlan_id) port (port_id) vf (vf_mask)\n"
317 			"    Add a vlan_id, to the set of VLAN identifiers"
318 			"filtered for VF(s) from port_id.\n\n"
319 
320 			"rx_vlan rm (vlan_id) port (port_id) vf (vf_mask)\n"
321 			"    Remove a vlan_id, to the set of VLAN identifiers"
322 			"filtered for VF(s) from port_id.\n\n"
323 
324 			"tunnel_filter add (port_id) (outer_mac) (inner_mac) (ip_addr) "
325 			"(inner_vlan) (vxlan|nvgre|ipingre) (imac-ivlan|imac-ivlan-tenid|"
326 			"imac-tenid|imac|omac-imac-tenid|oip|iip) (tenant_id) (queue_id)\n"
327 			"   add a tunnel filter of a port.\n\n"
328 
329 			"tunnel_filter rm (port_id) (outer_mac) (inner_mac) (ip_addr) "
330 			"(inner_vlan) (vxlan|nvgre|ipingre) (imac-ivlan|imac-ivlan-tenid|"
331 			"imac-tenid|imac|omac-imac-tenid|oip|iip) (tenant_id) (queue_id)\n"
332 			"   remove a tunnel filter of a port.\n\n"
333 
334 			"rx_vxlan_port add (udp_port) (port_id)\n"
335 			"    Add an UDP port for VXLAN packet filter on a port\n\n"
336 
337 			"rx_vxlan_port rm (udp_port) (port_id)\n"
338 			"    Remove an UDP port for VXLAN packet filter on a port\n\n"
339 
340 			"tx_vlan set (port_id) vlan_id[, vlan_id_outer]\n"
341 			"    Set hardware insertion of VLAN IDs (single or double VLAN "
342 			"depends on the number of VLAN IDs) in packets sent on a port.\n\n"
343 
344 			"tx_vlan set pvid port_id vlan_id (on|off)\n"
345 			"    Set port based TX VLAN insertion.\n\n"
346 
347 			"tx_vlan reset (port_id)\n"
348 			"    Disable hardware insertion of a VLAN header in"
349 			" packets sent on a port.\n\n"
350 
351 			"csum set (ip|udp|tcp|sctp|outer-ip) (hw|sw) (port_id)\n"
352 			"    Select hardware or software calculation of the"
353 			" checksum when transmitting a packet using the"
354 			" csum forward engine.\n"
355 			"    ip|udp|tcp|sctp always concern the inner layer.\n"
356 			"    outer-ip concerns the outer IP layer in"
357 			" case the packet is recognized as a tunnel packet by"
358 			" the forward engine (vxlan, gre and ipip are supported)\n"
359 			"    Please check the NIC datasheet for HW limits.\n\n"
360 
361 			"csum parse-tunnel (on|off) (tx_port_id)\n"
362 			"    If disabled, treat tunnel packets as non-tunneled"
363 			" packets (treat inner headers as payload). The port\n"
364 			"    argument is the port used for TX in csum forward"
365 			" engine.\n\n"
366 
367 			"csum show (port_id)\n"
368 			"    Display tx checksum offload configuration\n\n"
369 
370 			"tso set (segsize) (portid)\n"
371 			"    Enable TCP Segmentation Offload in csum forward"
372 			" engine.\n"
373 			"    Please check the NIC datasheet for HW limits.\n\n"
374 
375 			"tso show (portid)"
376 			"    Display the status of TCP Segmentation Offload.\n\n"
377 
378 			"set fwd (%s)\n"
379 			"    Set packet forwarding mode.\n\n"
380 
381 			"mac_addr add (port_id) (XX:XX:XX:XX:XX:XX)\n"
382 			"    Add a MAC address on port_id.\n\n"
383 
384 			"mac_addr remove (port_id) (XX:XX:XX:XX:XX:XX)\n"
385 			"    Remove a MAC address from port_id.\n\n"
386 
387 			"mac_addr add port (port_id) vf (vf_id) (mac_address)\n"
388 			"    Add a MAC address for a VF on the port.\n\n"
389 
390 #ifdef RTE_LIBRTE_IXGBE_PMD
391 			"set vf mac addr (port_id) (vf_id) (XX:XX:XX:XX:XX:XX)\n"
392 			"    Set the MAC address for a VF from the PF.\n\n"
393 #endif
394 
395 			"set port (port_id) uta (mac_address|all) (on|off)\n"
396 			"    Add/Remove a or all unicast hash filter(s)"
397 			"from port X.\n\n"
398 
399 			"set promisc (port_id|all) (on|off)\n"
400 			"    Set the promiscuous mode on port_id, or all.\n\n"
401 
402 			"set allmulti (port_id|all) (on|off)\n"
403 			"    Set the allmulti mode on port_id, or all.\n\n"
404 
405 			"set flow_ctrl rx (on|off) tx (on|off) (high_water)"
406 			" (low_water) (pause_time) (send_xon) mac_ctrl_frame_fwd"
407 			" (on|off) autoneg (on|off) (port_id)\n"
408 			"set flow_ctrl rx (on|off) (portid)\n"
409 			"set flow_ctrl tx (on|off) (portid)\n"
410 			"set flow_ctrl high_water (high_water) (portid)\n"
411 			"set flow_ctrl low_water (low_water) (portid)\n"
412 			"set flow_ctrl pause_time (pause_time) (portid)\n"
413 			"set flow_ctrl send_xon (send_xon) (portid)\n"
414 			"set flow_ctrl mac_ctrl_frame_fwd (on|off) (portid)\n"
415 			"set flow_ctrl autoneg (on|off) (port_id)\n"
416 			"    Set the link flow control parameter on a port.\n\n"
417 
418 			"set pfc_ctrl rx (on|off) tx (on|off) (high_water)"
419 			" (low_water) (pause_time) (priority) (port_id)\n"
420 			"    Set the priority flow control parameter on a"
421 			" port.\n\n"
422 
423 			"set stat_qmap (tx|rx) (port_id) (queue_id) (qmapping)\n"
424 			"    Set statistics mapping (qmapping 0..15) for RX/TX"
425 			" queue on port.\n"
426 			"    e.g., 'set stat_qmap rx 0 2 5' sets rx queue 2"
427 			" on port 0 to mapping 5.\n\n"
428 
429 			"set port (port_id) vf (vf_id) rx|tx on|off\n"
430 			"    Enable/Disable a VF receive/tranmit from a port\n\n"
431 
432 			"set port (port_id) vf (vf_id) (mac_addr)"
433 			" (exact-mac#exact-mac-vlan#hashmac|hashmac-vlan) on|off\n"
434 			"   Add/Remove unicast or multicast MAC addr filter"
435 			" for a VF.\n\n"
436 
437 			"set port (port_id) vf (vf_id) rxmode (AUPE|ROPE|BAM"
438 			"|MPE) (on|off)\n"
439 			"    AUPE:accepts untagged VLAN;"
440 			"ROPE:accept unicast hash\n\n"
441 			"    BAM:accepts broadcast packets;"
442 			"MPE:accepts all multicast packets\n\n"
443 			"    Enable/Disable a VF receive mode of a port\n\n"
444 
445 			"set port (port_id) queue (queue_id) rate (rate_num)\n"
446 			"    Set rate limit for a queue of a port\n\n"
447 
448 			"set port (port_id) vf (vf_id) rate (rate_num) "
449 			"queue_mask (queue_mask_value)\n"
450 			"    Set rate limit for queues in VF of a port\n\n"
451 
452 			"set port (port_id) mirror-rule (rule_id)"
453 			" (pool-mirror-up|pool-mirror-down|vlan-mirror)"
454 			" (poolmask|vlanid[,vlanid]*) dst-pool (pool_id) (on|off)\n"
455 			"   Set pool or vlan type mirror rule on a port.\n"
456 			"   e.g., 'set port 0 mirror-rule 0 vlan-mirror 0,1"
457 			" dst-pool 0 on' enable mirror traffic with vlan 0,1"
458 			" to pool 0.\n\n"
459 
460 			"set port (port_id) mirror-rule (rule_id)"
461 			" (uplink-mirror|downlink-mirror) dst-pool"
462 			" (pool_id) (on|off)\n"
463 			"   Set uplink or downlink type mirror rule on a port.\n"
464 			"   e.g., 'set port 0 mirror-rule 0 uplink-mirror dst-pool"
465 			" 0 on' enable mirror income traffic to pool 0.\n\n"
466 
467 			"reset port (port_id) mirror-rule (rule_id)\n"
468 			"   Reset a mirror rule.\n\n"
469 
470 			"set flush_rx (on|off)\n"
471 			"   Flush (default) or don't flush RX streams before"
472 			" forwarding. Mainly used with PCAP drivers.\n\n"
473 
474 			#ifdef RTE_NIC_BYPASS
475 			"set bypass mode (normal|bypass|isolate) (port_id)\n"
476 			"   Set the bypass mode for the lowest port on bypass enabled"
477 			" NIC.\n\n"
478 
479 			"set bypass event (timeout|os_on|os_off|power_on|power_off) "
480 			"mode (normal|bypass|isolate) (port_id)\n"
481 			"   Set the event required to initiate specified bypass mode for"
482 			" the lowest port on a bypass enabled NIC where:\n"
483 			"       timeout   = enable bypass after watchdog timeout.\n"
484 			"       os_on     = enable bypass when OS/board is powered on.\n"
485 			"       os_off    = enable bypass when OS/board is powered off.\n"
486 			"       power_on  = enable bypass when power supply is turned on.\n"
487 			"       power_off = enable bypass when power supply is turned off."
488 			"\n\n"
489 
490 			"set bypass timeout (0|1.5|2|3|4|8|16|32)\n"
491 			"   Set the bypass watchdog timeout to 'n' seconds"
492 			" where 0 = instant.\n\n"
493 
494 			"show bypass config (port_id)\n"
495 			"   Show the bypass configuration for a bypass enabled NIC"
496 			" using the lowest port on the NIC.\n\n"
497 #endif
498 #ifdef RTE_LIBRTE_PMD_BOND
499 			"create bonded device (mode) (socket)\n"
500 			"	Create a new bonded device with specific bonding mode and socket.\n\n"
501 
502 			"add bonding slave (slave_id) (port_id)\n"
503 			"	Add a slave device to a bonded device.\n\n"
504 
505 			"remove bonding slave (slave_id) (port_id)\n"
506 			"	Remove a slave device from a bonded device.\n\n"
507 
508 			"set bonding mode (value) (port_id)\n"
509 			"	Set the bonding mode on a bonded device.\n\n"
510 
511 			"set bonding primary (slave_id) (port_id)\n"
512 			"	Set the primary slave for a bonded device.\n\n"
513 
514 			"show bonding config (port_id)\n"
515 			"	Show the bonding config for port_id.\n\n"
516 
517 			"set bonding mac_addr (port_id) (address)\n"
518 			"	Set the MAC address of a bonded device.\n\n"
519 
520 			"set bonding xmit_balance_policy (port_id) (l2|l23|l34)\n"
521 			"	Set the transmit balance policy for bonded device running in balance mode.\n\n"
522 
523 			"set bonding mon_period (port_id) (value)\n"
524 			"	Set the bonding link status monitoring polling period in ms.\n\n"
525 #endif
526 			"set link-up port (port_id)\n"
527 			"	Set link up for a port.\n\n"
528 
529 			"set link-down port (port_id)\n"
530 			"	Set link down for a port.\n\n"
531 
532 			"E-tag set insertion on port-tag-id (value)"
533 			" port (port_id) vf (vf_id)\n"
534 			"    Enable E-tag insertion for a VF on a port\n\n"
535 
536 			"E-tag set insertion off port (port_id) vf (vf_id)\n"
537 			"    Disable E-tag insertion for a VF on a port\n\n"
538 
539 			"E-tag set stripping (on|off) port (port_id)\n"
540 			"    Enable/disable E-tag stripping on a port\n\n"
541 
542 			"E-tag set forwarding (on|off) port (port_id)\n"
543 			"    Enable/disable E-tag based forwarding"
544 			" on a port\n\n"
545 
546 			"E-tag set filter add e-tag-id (value) dst-pool"
547 			" (pool_id) port (port_id)\n"
548 			"    Add an E-tag forwarding filter on a port\n\n"
549 
550 			"E-tag set filter del e-tag-id (value) port (port_id)\n"
551 			"    Delete an E-tag forwarding filter on a port\n\n"
552 
553 			, list_pkt_forwarding_modes()
554 		);
555 	}
556 
557 	if (show_all || !strcmp(res->section, "ports")) {
558 
559 		cmdline_printf(
560 			cl,
561 			"\n"
562 			"Port Operations:\n"
563 			"----------------\n\n"
564 
565 			"port start (port_id|all)\n"
566 			"    Start all ports or port_id.\n\n"
567 
568 			"port stop (port_id|all)\n"
569 			"    Stop all ports or port_id.\n\n"
570 
571 			"port close (port_id|all)\n"
572 			"    Close all ports or port_id.\n\n"
573 
574 			"port attach (ident)\n"
575 			"    Attach physical or virtual dev by pci address or virtual device name\n\n"
576 
577 			"port detach (port_id)\n"
578 			"    Detach physical or virtual dev by port_id\n\n"
579 
580 			"port config (port_id|all)"
581 			" speed (10|100|1000|10000|25000|40000|50000|100000|auto)"
582 			" duplex (half|full|auto)\n"
583 			"    Set speed and duplex for all ports or port_id\n\n"
584 
585 			"port config all (rxq|txq|rxd|txd) (value)\n"
586 			"    Set number for rxq/txq/rxd/txd.\n\n"
587 
588 			"port config all max-pkt-len (value)\n"
589 			"    Set the max packet length.\n\n"
590 
591 			"port config all (crc-strip|scatter|rx-cksum|hw-vlan|hw-vlan-filter|"
592 			"hw-vlan-strip|hw-vlan-extend|drop-en)"
593 			" (on|off)\n"
594 			"    Set crc-strip/scatter/rx-checksum/hardware-vlan/drop_en"
595 			" for ports.\n\n"
596 
597 			"port config all rss (all|ip|tcp|udp|sctp|ether|port|vxlan|geneve|nvgre|none)\n"
598 			"    Set the RSS mode.\n\n"
599 
600 			"port config port-id rss reta (hash,queue)[,(hash,queue)]\n"
601 			"    Set the RSS redirection table.\n\n"
602 
603 			"port config (port_id) dcb vt (on|off) (traffic_class)"
604 			" pfc (on|off)\n"
605 			"    Set the DCB mode.\n\n"
606 
607 			"port config all burst (value)\n"
608 			"    Set the number of packets per burst.\n\n"
609 
610 			"port config all (txpt|txht|txwt|rxpt|rxht|rxwt)"
611 			" (value)\n"
612 			"    Set the ring prefetch/host/writeback threshold"
613 			" for tx/rx queue.\n\n"
614 
615 			"port config all (txfreet|txrst|rxfreet) (value)\n"
616 			"    Set free threshold for rx/tx, or set"
617 			" tx rs bit threshold.\n\n"
618 			"port config mtu X value\n"
619 			"    Set the MTU of port X to a given value\n\n"
620 
621 			"port (port_id) (rxq|txq) (queue_id) (start|stop)\n"
622 			"    Start/stop a rx/tx queue of port X. Only take effect"
623 			" when port X is started\n\n"
624 
625 			"port config (port_id|all) l2-tunnel E-tag ether-type"
626 			" (value)\n"
627 			"    Set the value of E-tag ether-type.\n\n"
628 
629 			"port config (port_id|all) l2-tunnel E-tag"
630 			" (enable|disable)\n"
631 			"    Enable/disable the E-tag support.\n\n"
632 		);
633 	}
634 
635 	if (show_all || !strcmp(res->section, "registers")) {
636 
637 		cmdline_printf(
638 			cl,
639 			"\n"
640 			"Registers:\n"
641 			"----------\n\n"
642 
643 			"read reg (port_id) (address)\n"
644 			"    Display value of a port register.\n\n"
645 
646 			"read regfield (port_id) (address) (bit_x) (bit_y)\n"
647 			"    Display a port register bit field.\n\n"
648 
649 			"read regbit (port_id) (address) (bit_x)\n"
650 			"    Display a single port register bit.\n\n"
651 
652 			"write reg (port_id) (address) (value)\n"
653 			"    Set value of a port register.\n\n"
654 
655 			"write regfield (port_id) (address) (bit_x) (bit_y)"
656 			" (value)\n"
657 			"    Set bit field of a port register.\n\n"
658 
659 			"write regbit (port_id) (address) (bit_x) (value)\n"
660 			"    Set single bit value of a port register.\n\n"
661 		);
662 	}
663 	if (show_all || !strcmp(res->section, "filters")) {
664 
665 		cmdline_printf(
666 			cl,
667 			"\n"
668 			"filters:\n"
669 			"--------\n\n"
670 
671 			"ethertype_filter (port_id) (add|del)"
672 			" (mac_addr|mac_ignr) (mac_address) ethertype"
673 			" (ether_type) (drop|fwd) queue (queue_id)\n"
674 			"    Add/Del an ethertype filter.\n\n"
675 
676 			"2tuple_filter (port_id) (add|del)"
677 			" dst_port (dst_port_value) protocol (protocol_value)"
678 			" mask (mask_value) tcp_flags (tcp_flags_value)"
679 			" priority (prio_value) queue (queue_id)\n"
680 			"    Add/Del a 2tuple filter.\n\n"
681 
682 			"5tuple_filter (port_id) (add|del)"
683 			" dst_ip (dst_address) src_ip (src_address)"
684 			" dst_port (dst_port_value) src_port (src_port_value)"
685 			" protocol (protocol_value)"
686 			" mask (mask_value) tcp_flags (tcp_flags_value)"
687 			" priority (prio_value) queue (queue_id)\n"
688 			"    Add/Del a 5tuple filter.\n\n"
689 
690 			"syn_filter (port_id) (add|del) priority (high|low) queue (queue_id)"
691 			"    Add/Del syn filter.\n\n"
692 
693 			"flex_filter (port_id) (add|del) len (len_value)"
694 			" bytes (bytes_value) mask (mask_value)"
695 			" priority (prio_value) queue (queue_id)\n"
696 			"    Add/Del a flex filter.\n\n"
697 
698 			"flow_director_filter (port_id) mode IP (add|del|update)"
699 			" flow (ipv4-other|ipv4-frag|ipv6-other|ipv6-frag)"
700 			" src (src_ip_address) dst (dst_ip_address)"
701 			" tos (tos_value) proto (proto_value) ttl (ttl_value)"
702 			" vlan (vlan_value) flexbytes (flexbytes_value)"
703 			" (drop|fwd) pf|vf(vf_id) queue (queue_id)"
704 			" fd_id (fd_id_value)\n"
705 			"    Add/Del an IP type flow director filter.\n\n"
706 
707 			"flow_director_filter (port_id) mode IP (add|del|update)"
708 			" flow (ipv4-tcp|ipv4-udp|ipv6-tcp|ipv6-udp)"
709 			" src (src_ip_address) (src_port)"
710 			" dst (dst_ip_address) (dst_port)"
711 			" tos (tos_value) ttl (ttl_value)"
712 			" vlan (vlan_value) flexbytes (flexbytes_value)"
713 			" (drop|fwd) pf|vf(vf_id) queue (queue_id)"
714 			" fd_id (fd_id_value)\n"
715 			"    Add/Del an UDP/TCP type flow director filter.\n\n"
716 
717 			"flow_director_filter (port_id) mode IP (add|del|update)"
718 			" flow (ipv4-sctp|ipv6-sctp)"
719 			" src (src_ip_address) (src_port)"
720 			" dst (dst_ip_address) (dst_port)"
721 			" tag (verification_tag) "
722 			" tos (tos_value) ttl (ttl_value)"
723 			" vlan (vlan_value)"
724 			" flexbytes (flexbytes_value) (drop|fwd)"
725 			" pf|vf(vf_id) queue (queue_id) fd_id (fd_id_value)\n"
726 			"    Add/Del a SCTP type flow director filter.\n\n"
727 
728 			"flow_director_filter (port_id) mode IP (add|del|update)"
729 			" flow l2_payload ether (ethertype)"
730 			" flexbytes (flexbytes_value) (drop|fwd)"
731 			" pf|vf(vf_id) queue (queue_id) fd_id (fd_id_value)\n"
732 			"    Add/Del a l2 payload type flow director filter.\n\n"
733 
734 			"flow_director_filter (port_id) mode MAC-VLAN (add|del|update)"
735 			" mac (mac_address) vlan (vlan_value)"
736 			" flexbytes (flexbytes_value) (drop|fwd)"
737 			" queue (queue_id) fd_id (fd_id_value)\n"
738 			"    Add/Del a MAC-VLAN flow director filter.\n\n"
739 
740 			"flow_director_filter (port_id) mode Tunnel (add|del|update)"
741 			" mac (mac_address) vlan (vlan_value)"
742 			" tunnel (NVGRE|VxLAN) tunnel-id (tunnel_id_value)"
743 			" flexbytes (flexbytes_value) (drop|fwd)"
744 			" queue (queue_id) fd_id (fd_id_value)\n"
745 			"    Add/Del a Tunnel flow director filter.\n\n"
746 
747 			"flush_flow_director (port_id)\n"
748 			"    Flush all flow director entries of a device.\n\n"
749 
750 			"flow_director_mask (port_id) mode IP vlan (vlan_value)"
751 			" src_mask (ipv4_src) (ipv6_src) (src_port)"
752 			" dst_mask (ipv4_dst) (ipv6_dst) (dst_port)\n"
753 			"    Set flow director IP mask.\n\n"
754 
755 			"flow_director_mask (port_id) mode MAC-VLAN"
756 			" vlan (vlan_value)\n"
757 			"    Set flow director MAC-VLAN mask.\n\n"
758 
759 			"flow_director_mask (port_id) mode Tunnel"
760 			" vlan (vlan_value) mac (mac_value)"
761 			" tunnel-type (tunnel_type_value)"
762 			" tunnel-id (tunnel_id_value)\n"
763 			"    Set flow director Tunnel mask.\n\n"
764 
765 			"flow_director_flex_mask (port_id)"
766 			" flow (none|ipv4-other|ipv4-frag|ipv4-tcp|ipv4-udp|ipv4-sctp|"
767 			"ipv6-other|ipv6-frag|ipv6-tcp|ipv6-udp|ipv6-sctp|l2_payload|all)"
768 			" (mask)\n"
769 			"    Configure mask of flex payload.\n\n"
770 
771 			"flow_director_flex_payload (port_id)"
772 			" (raw|l2|l3|l4) (config)\n"
773 			"    Configure flex payload selection.\n\n"
774 
775 			"get_sym_hash_ena_per_port (port_id)\n"
776 			"    get symmetric hash enable configuration per port.\n\n"
777 
778 			"set_sym_hash_ena_per_port (port_id) (enable|disable)\n"
779 			"    set symmetric hash enable configuration per port"
780 			" to enable or disable.\n\n"
781 
782 			"get_hash_global_config (port_id)\n"
783 			"    Get the global configurations of hash filters.\n\n"
784 
785 			"set_hash_global_config (port_id) (toeplitz|simple_xor|default)"
786 			" (ipv4|ipv4-frag|ipv4-tcp|ipv4-udp|ipv4-sctp|ipv4-other|ipv6|"
787 			"ipv6-frag|ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other|l2_payload)"
788 			" (enable|disable)\n"
789 			"    Set the global configurations of hash filters.\n\n"
790 
791 			"set_hash_input_set (port_id) (ipv4|ipv4-frag|"
792 			"ipv4-tcp|ipv4-udp|ipv4-sctp|ipv4-other|ipv6|"
793 			"ipv6-frag|ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other|"
794 			"l2_payload) (ovlan|ivlan|src-ipv4|dst-ipv4|src-ipv6|"
795 			"dst-ipv6|ipv4-tos|ipv4-proto|ipv6-tc|"
796 			"ipv6-next-header|udp-src-port|udp-dst-port|"
797 			"tcp-src-port|tcp-dst-port|sctp-src-port|"
798 			"sctp-dst-port|sctp-veri-tag|udp-key|gre-key|fld-1st|"
799 			"fld-2nd|fld-3rd|fld-4th|fld-5th|fld-6th|fld-7th|"
800 			"fld-8th|none) (select|add)\n"
801 			"    Set the input set for hash.\n\n"
802 
803 			"set_fdir_input_set (port_id) "
804 			"(ipv4-frag|ipv4-tcp|ipv4-udp|ipv4-sctp|ipv4-other|"
805 			"ipv6-frag|ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other|"
806 			"l2_payload) (ivlan|ethertype|src-ipv4|dst-ipv4|src-ipv6|"
807 			"dst-ipv6|ipv4-tos|ipv4-proto|ipv4-ttl|ipv6-tc|"
808 			"ipv6-next-header|ipv6-hop-limits|udp-src-port|"
809 			"udp-dst-port|tcp-src-port|tcp-dst-port|"
810 			"sctp-src-port|sctp-dst-port|sctp-veri-tag|none)"
811 			" (select|add)\n"
812 			"    Set the input set for FDir.\n\n"
813 		);
814 	}
815 }
816 
817 cmdline_parse_token_string_t cmd_help_long_help =
818 	TOKEN_STRING_INITIALIZER(struct cmd_help_long_result, help, "help");
819 
820 cmdline_parse_token_string_t cmd_help_long_section =
821 	TOKEN_STRING_INITIALIZER(struct cmd_help_long_result, section,
822 			"all#control#display#config#"
823 			"ports#registers#filters");
824 
825 cmdline_parse_inst_t cmd_help_long = {
826 	.f = cmd_help_long_parsed,
827 	.data = NULL,
828 	.help_str = "help all|control|display|config|ports|register|filters: "
829 		"Show help",
830 	.tokens = {
831 		(void *)&cmd_help_long_help,
832 		(void *)&cmd_help_long_section,
833 		NULL,
834 	},
835 };
836 
837 
838 /* *** start/stop/close all ports *** */
839 struct cmd_operate_port_result {
840 	cmdline_fixed_string_t keyword;
841 	cmdline_fixed_string_t name;
842 	cmdline_fixed_string_t value;
843 };
844 
845 static void cmd_operate_port_parsed(void *parsed_result,
846 				__attribute__((unused)) struct cmdline *cl,
847 				__attribute__((unused)) void *data)
848 {
849 	struct cmd_operate_port_result *res = parsed_result;
850 
851 	if (!strcmp(res->name, "start"))
852 		start_port(RTE_PORT_ALL);
853 	else if (!strcmp(res->name, "stop"))
854 		stop_port(RTE_PORT_ALL);
855 	else if (!strcmp(res->name, "close"))
856 		close_port(RTE_PORT_ALL);
857 	else
858 		printf("Unknown parameter\n");
859 }
860 
861 cmdline_parse_token_string_t cmd_operate_port_all_cmd =
862 	TOKEN_STRING_INITIALIZER(struct cmd_operate_port_result, keyword,
863 								"port");
864 cmdline_parse_token_string_t cmd_operate_port_all_port =
865 	TOKEN_STRING_INITIALIZER(struct cmd_operate_port_result, name,
866 						"start#stop#close");
867 cmdline_parse_token_string_t cmd_operate_port_all_all =
868 	TOKEN_STRING_INITIALIZER(struct cmd_operate_port_result, value, "all");
869 
870 cmdline_parse_inst_t cmd_operate_port = {
871 	.f = cmd_operate_port_parsed,
872 	.data = NULL,
873 	.help_str = "port start|stop|close all: Start/Stop/Close all ports",
874 	.tokens = {
875 		(void *)&cmd_operate_port_all_cmd,
876 		(void *)&cmd_operate_port_all_port,
877 		(void *)&cmd_operate_port_all_all,
878 		NULL,
879 	},
880 };
881 
882 /* *** start/stop/close specific port *** */
883 struct cmd_operate_specific_port_result {
884 	cmdline_fixed_string_t keyword;
885 	cmdline_fixed_string_t name;
886 	uint8_t value;
887 };
888 
889 static void cmd_operate_specific_port_parsed(void *parsed_result,
890 			__attribute__((unused)) struct cmdline *cl,
891 				__attribute__((unused)) void *data)
892 {
893 	struct cmd_operate_specific_port_result *res = parsed_result;
894 
895 	if (!strcmp(res->name, "start"))
896 		start_port(res->value);
897 	else if (!strcmp(res->name, "stop"))
898 		stop_port(res->value);
899 	else if (!strcmp(res->name, "close"))
900 		close_port(res->value);
901 	else
902 		printf("Unknown parameter\n");
903 }
904 
905 cmdline_parse_token_string_t cmd_operate_specific_port_cmd =
906 	TOKEN_STRING_INITIALIZER(struct cmd_operate_specific_port_result,
907 							keyword, "port");
908 cmdline_parse_token_string_t cmd_operate_specific_port_port =
909 	TOKEN_STRING_INITIALIZER(struct cmd_operate_specific_port_result,
910 						name, "start#stop#close");
911 cmdline_parse_token_num_t cmd_operate_specific_port_id =
912 	TOKEN_NUM_INITIALIZER(struct cmd_operate_specific_port_result,
913 							value, UINT8);
914 
915 cmdline_parse_inst_t cmd_operate_specific_port = {
916 	.f = cmd_operate_specific_port_parsed,
917 	.data = NULL,
918 	.help_str = "port start|stop|close <port_id>: Start/Stop/Close port_id",
919 	.tokens = {
920 		(void *)&cmd_operate_specific_port_cmd,
921 		(void *)&cmd_operate_specific_port_port,
922 		(void *)&cmd_operate_specific_port_id,
923 		NULL,
924 	},
925 };
926 
927 /* *** attach a specified port *** */
928 struct cmd_operate_attach_port_result {
929 	cmdline_fixed_string_t port;
930 	cmdline_fixed_string_t keyword;
931 	cmdline_fixed_string_t identifier;
932 };
933 
934 static void cmd_operate_attach_port_parsed(void *parsed_result,
935 				__attribute__((unused)) struct cmdline *cl,
936 				__attribute__((unused)) void *data)
937 {
938 	struct cmd_operate_attach_port_result *res = parsed_result;
939 
940 	if (!strcmp(res->keyword, "attach"))
941 		attach_port(res->identifier);
942 	else
943 		printf("Unknown parameter\n");
944 }
945 
946 cmdline_parse_token_string_t cmd_operate_attach_port_port =
947 	TOKEN_STRING_INITIALIZER(struct cmd_operate_attach_port_result,
948 			port, "port");
949 cmdline_parse_token_string_t cmd_operate_attach_port_keyword =
950 	TOKEN_STRING_INITIALIZER(struct cmd_operate_attach_port_result,
951 			keyword, "attach");
952 cmdline_parse_token_string_t cmd_operate_attach_port_identifier =
953 	TOKEN_STRING_INITIALIZER(struct cmd_operate_attach_port_result,
954 			identifier, NULL);
955 
956 cmdline_parse_inst_t cmd_operate_attach_port = {
957 	.f = cmd_operate_attach_port_parsed,
958 	.data = NULL,
959 	.help_str = "port attach <identifier>: "
960 		"(identifier: pci address or virtual dev name)",
961 	.tokens = {
962 		(void *)&cmd_operate_attach_port_port,
963 		(void *)&cmd_operate_attach_port_keyword,
964 		(void *)&cmd_operate_attach_port_identifier,
965 		NULL,
966 	},
967 };
968 
969 /* *** detach a specified port *** */
970 struct cmd_operate_detach_port_result {
971 	cmdline_fixed_string_t port;
972 	cmdline_fixed_string_t keyword;
973 	uint8_t port_id;
974 };
975 
976 static void cmd_operate_detach_port_parsed(void *parsed_result,
977 				__attribute__((unused)) struct cmdline *cl,
978 				__attribute__((unused)) void *data)
979 {
980 	struct cmd_operate_detach_port_result *res = parsed_result;
981 
982 	if (!strcmp(res->keyword, "detach"))
983 		detach_port(res->port_id);
984 	else
985 		printf("Unknown parameter\n");
986 }
987 
988 cmdline_parse_token_string_t cmd_operate_detach_port_port =
989 	TOKEN_STRING_INITIALIZER(struct cmd_operate_detach_port_result,
990 			port, "port");
991 cmdline_parse_token_string_t cmd_operate_detach_port_keyword =
992 	TOKEN_STRING_INITIALIZER(struct cmd_operate_detach_port_result,
993 			keyword, "detach");
994 cmdline_parse_token_num_t cmd_operate_detach_port_port_id =
995 	TOKEN_NUM_INITIALIZER(struct cmd_operate_detach_port_result,
996 			port_id, UINT8);
997 
998 cmdline_parse_inst_t cmd_operate_detach_port = {
999 	.f = cmd_operate_detach_port_parsed,
1000 	.data = NULL,
1001 	.help_str = "port detach <port_id>",
1002 	.tokens = {
1003 		(void *)&cmd_operate_detach_port_port,
1004 		(void *)&cmd_operate_detach_port_keyword,
1005 		(void *)&cmd_operate_detach_port_port_id,
1006 		NULL,
1007 	},
1008 };
1009 
1010 /* *** configure speed for all ports *** */
1011 struct cmd_config_speed_all {
1012 	cmdline_fixed_string_t port;
1013 	cmdline_fixed_string_t keyword;
1014 	cmdline_fixed_string_t all;
1015 	cmdline_fixed_string_t item1;
1016 	cmdline_fixed_string_t item2;
1017 	cmdline_fixed_string_t value1;
1018 	cmdline_fixed_string_t value2;
1019 };
1020 
1021 static int
1022 parse_and_check_speed_duplex(char *speedstr, char *duplexstr, uint32_t *speed)
1023 {
1024 
1025 	int duplex;
1026 
1027 	if (!strcmp(duplexstr, "half")) {
1028 		duplex = ETH_LINK_HALF_DUPLEX;
1029 	} else if (!strcmp(duplexstr, "full")) {
1030 		duplex = ETH_LINK_FULL_DUPLEX;
1031 	} else if (!strcmp(duplexstr, "auto")) {
1032 		duplex = ETH_LINK_FULL_DUPLEX;
1033 	} else {
1034 		printf("Unknown duplex parameter\n");
1035 		return -1;
1036 	}
1037 
1038 	if (!strcmp(speedstr, "10")) {
1039 		*speed = (duplex == ETH_LINK_HALF_DUPLEX) ?
1040 				ETH_LINK_SPEED_10M_HD : ETH_LINK_SPEED_10M;
1041 	} else if (!strcmp(speedstr, "100")) {
1042 		*speed = (duplex == ETH_LINK_HALF_DUPLEX) ?
1043 				ETH_LINK_SPEED_100M_HD : ETH_LINK_SPEED_100M;
1044 	} else {
1045 		if (duplex != ETH_LINK_FULL_DUPLEX) {
1046 			printf("Invalid speed/duplex parameters\n");
1047 			return -1;
1048 		}
1049 		if (!strcmp(speedstr, "1000")) {
1050 			*speed = ETH_LINK_SPEED_1G;
1051 		} else if (!strcmp(speedstr, "10000")) {
1052 			*speed = ETH_LINK_SPEED_10G;
1053 		} else if (!strcmp(speedstr, "25000")) {
1054 			*speed = ETH_LINK_SPEED_25G;
1055 		} else if (!strcmp(speedstr, "40000")) {
1056 			*speed = ETH_LINK_SPEED_40G;
1057 		} else if (!strcmp(speedstr, "50000")) {
1058 			*speed = ETH_LINK_SPEED_50G;
1059 		} else if (!strcmp(speedstr, "100000")) {
1060 			*speed = ETH_LINK_SPEED_100G;
1061 		} else if (!strcmp(speedstr, "auto")) {
1062 			*speed = ETH_LINK_SPEED_AUTONEG;
1063 		} else {
1064 			printf("Unknown speed parameter\n");
1065 			return -1;
1066 		}
1067 	}
1068 
1069 	return 0;
1070 }
1071 
1072 static void
1073 cmd_config_speed_all_parsed(void *parsed_result,
1074 			__attribute__((unused)) struct cmdline *cl,
1075 			__attribute__((unused)) void *data)
1076 {
1077 	struct cmd_config_speed_all *res = parsed_result;
1078 	uint32_t link_speed;
1079 	portid_t pid;
1080 
1081 	if (!all_ports_stopped()) {
1082 		printf("Please stop all ports first\n");
1083 		return;
1084 	}
1085 
1086 	if (parse_and_check_speed_duplex(res->value1, res->value2,
1087 			&link_speed) < 0)
1088 		return;
1089 
1090 	FOREACH_PORT(pid, ports) {
1091 		ports[pid].dev_conf.link_speeds = link_speed;
1092 	}
1093 
1094 	cmd_reconfig_device_queue(RTE_PORT_ALL, 1, 1);
1095 }
1096 
1097 cmdline_parse_token_string_t cmd_config_speed_all_port =
1098 	TOKEN_STRING_INITIALIZER(struct cmd_config_speed_all, port, "port");
1099 cmdline_parse_token_string_t cmd_config_speed_all_keyword =
1100 	TOKEN_STRING_INITIALIZER(struct cmd_config_speed_all, keyword,
1101 							"config");
1102 cmdline_parse_token_string_t cmd_config_speed_all_all =
1103 	TOKEN_STRING_INITIALIZER(struct cmd_config_speed_all, all, "all");
1104 cmdline_parse_token_string_t cmd_config_speed_all_item1 =
1105 	TOKEN_STRING_INITIALIZER(struct cmd_config_speed_all, item1, "speed");
1106 cmdline_parse_token_string_t cmd_config_speed_all_value1 =
1107 	TOKEN_STRING_INITIALIZER(struct cmd_config_speed_all, value1,
1108 				"10#100#1000#10000#25000#40000#50000#100000#auto");
1109 cmdline_parse_token_string_t cmd_config_speed_all_item2 =
1110 	TOKEN_STRING_INITIALIZER(struct cmd_config_speed_all, item2, "duplex");
1111 cmdline_parse_token_string_t cmd_config_speed_all_value2 =
1112 	TOKEN_STRING_INITIALIZER(struct cmd_config_speed_all, value2,
1113 						"half#full#auto");
1114 
1115 cmdline_parse_inst_t cmd_config_speed_all = {
1116 	.f = cmd_config_speed_all_parsed,
1117 	.data = NULL,
1118 	.help_str = "port config all speed "
1119 		"10|100|1000|10000|25000|40000|50000|100000|auto duplex "
1120 							"half|full|auto",
1121 	.tokens = {
1122 		(void *)&cmd_config_speed_all_port,
1123 		(void *)&cmd_config_speed_all_keyword,
1124 		(void *)&cmd_config_speed_all_all,
1125 		(void *)&cmd_config_speed_all_item1,
1126 		(void *)&cmd_config_speed_all_value1,
1127 		(void *)&cmd_config_speed_all_item2,
1128 		(void *)&cmd_config_speed_all_value2,
1129 		NULL,
1130 	},
1131 };
1132 
1133 /* *** configure speed for specific port *** */
1134 struct cmd_config_speed_specific {
1135 	cmdline_fixed_string_t port;
1136 	cmdline_fixed_string_t keyword;
1137 	uint8_t id;
1138 	cmdline_fixed_string_t item1;
1139 	cmdline_fixed_string_t item2;
1140 	cmdline_fixed_string_t value1;
1141 	cmdline_fixed_string_t value2;
1142 };
1143 
1144 static void
1145 cmd_config_speed_specific_parsed(void *parsed_result,
1146 				__attribute__((unused)) struct cmdline *cl,
1147 				__attribute__((unused)) void *data)
1148 {
1149 	struct cmd_config_speed_specific *res = parsed_result;
1150 	uint32_t link_speed;
1151 
1152 	if (!all_ports_stopped()) {
1153 		printf("Please stop all ports first\n");
1154 		return;
1155 	}
1156 
1157 	if (port_id_is_invalid(res->id, ENABLED_WARN))
1158 		return;
1159 
1160 	if (parse_and_check_speed_duplex(res->value1, res->value2,
1161 			&link_speed) < 0)
1162 		return;
1163 
1164 	ports[res->id].dev_conf.link_speeds = link_speed;
1165 
1166 	cmd_reconfig_device_queue(RTE_PORT_ALL, 1, 1);
1167 }
1168 
1169 
1170 cmdline_parse_token_string_t cmd_config_speed_specific_port =
1171 	TOKEN_STRING_INITIALIZER(struct cmd_config_speed_specific, port,
1172 								"port");
1173 cmdline_parse_token_string_t cmd_config_speed_specific_keyword =
1174 	TOKEN_STRING_INITIALIZER(struct cmd_config_speed_specific, keyword,
1175 								"config");
1176 cmdline_parse_token_num_t cmd_config_speed_specific_id =
1177 	TOKEN_NUM_INITIALIZER(struct cmd_config_speed_specific, id, UINT8);
1178 cmdline_parse_token_string_t cmd_config_speed_specific_item1 =
1179 	TOKEN_STRING_INITIALIZER(struct cmd_config_speed_specific, item1,
1180 								"speed");
1181 cmdline_parse_token_string_t cmd_config_speed_specific_value1 =
1182 	TOKEN_STRING_INITIALIZER(struct cmd_config_speed_specific, value1,
1183 				"10#100#1000#10000#25000#40000#50000#100000#auto");
1184 cmdline_parse_token_string_t cmd_config_speed_specific_item2 =
1185 	TOKEN_STRING_INITIALIZER(struct cmd_config_speed_specific, item2,
1186 								"duplex");
1187 cmdline_parse_token_string_t cmd_config_speed_specific_value2 =
1188 	TOKEN_STRING_INITIALIZER(struct cmd_config_speed_specific, value2,
1189 							"half#full#auto");
1190 
1191 cmdline_parse_inst_t cmd_config_speed_specific = {
1192 	.f = cmd_config_speed_specific_parsed,
1193 	.data = NULL,
1194 	.help_str = "port config <port_id> speed "
1195 		"10|100|1000|10000|25000|40000|50000|100000|auto duplex "
1196 							"half|full|auto",
1197 	.tokens = {
1198 		(void *)&cmd_config_speed_specific_port,
1199 		(void *)&cmd_config_speed_specific_keyword,
1200 		(void *)&cmd_config_speed_specific_id,
1201 		(void *)&cmd_config_speed_specific_item1,
1202 		(void *)&cmd_config_speed_specific_value1,
1203 		(void *)&cmd_config_speed_specific_item2,
1204 		(void *)&cmd_config_speed_specific_value2,
1205 		NULL,
1206 	},
1207 };
1208 
1209 /* *** configure txq/rxq, txd/rxd *** */
1210 struct cmd_config_rx_tx {
1211 	cmdline_fixed_string_t port;
1212 	cmdline_fixed_string_t keyword;
1213 	cmdline_fixed_string_t all;
1214 	cmdline_fixed_string_t name;
1215 	uint16_t value;
1216 };
1217 
1218 static void
1219 cmd_config_rx_tx_parsed(void *parsed_result,
1220 			__attribute__((unused)) struct cmdline *cl,
1221 			__attribute__((unused)) void *data)
1222 {
1223 	struct cmd_config_rx_tx *res = parsed_result;
1224 
1225 	if (!all_ports_stopped()) {
1226 		printf("Please stop all ports first\n");
1227 		return;
1228 	}
1229 	if (!strcmp(res->name, "rxq")) {
1230 		if (!res->value && !nb_txq) {
1231 			printf("Warning: Either rx or tx queues should be non zero\n");
1232 			return;
1233 		}
1234 		nb_rxq = res->value;
1235 	}
1236 	else if (!strcmp(res->name, "txq")) {
1237 		if (!res->value && !nb_rxq) {
1238 			printf("Warning: Either rx or tx queues should be non zero\n");
1239 			return;
1240 		}
1241 		nb_txq = res->value;
1242 	}
1243 	else if (!strcmp(res->name, "rxd")) {
1244 		if (res->value <= 0 || res->value > RTE_TEST_RX_DESC_MAX) {
1245 			printf("rxd %d invalid - must be > 0 && <= %d\n",
1246 					res->value, RTE_TEST_RX_DESC_MAX);
1247 			return;
1248 		}
1249 		nb_rxd = res->value;
1250 	} else if (!strcmp(res->name, "txd")) {
1251 		if (res->value <= 0 || res->value > RTE_TEST_TX_DESC_MAX) {
1252 			printf("txd %d invalid - must be > 0 && <= %d\n",
1253 					res->value, RTE_TEST_TX_DESC_MAX);
1254 			return;
1255 		}
1256 		nb_txd = res->value;
1257 	} else {
1258 		printf("Unknown parameter\n");
1259 		return;
1260 	}
1261 
1262 	fwd_config_setup();
1263 
1264 	init_port_config();
1265 
1266 	cmd_reconfig_device_queue(RTE_PORT_ALL, 1, 1);
1267 }
1268 
1269 cmdline_parse_token_string_t cmd_config_rx_tx_port =
1270 	TOKEN_STRING_INITIALIZER(struct cmd_config_rx_tx, port, "port");
1271 cmdline_parse_token_string_t cmd_config_rx_tx_keyword =
1272 	TOKEN_STRING_INITIALIZER(struct cmd_config_rx_tx, keyword, "config");
1273 cmdline_parse_token_string_t cmd_config_rx_tx_all =
1274 	TOKEN_STRING_INITIALIZER(struct cmd_config_rx_tx, all, "all");
1275 cmdline_parse_token_string_t cmd_config_rx_tx_name =
1276 	TOKEN_STRING_INITIALIZER(struct cmd_config_rx_tx, name,
1277 						"rxq#txq#rxd#txd");
1278 cmdline_parse_token_num_t cmd_config_rx_tx_value =
1279 	TOKEN_NUM_INITIALIZER(struct cmd_config_rx_tx, value, UINT16);
1280 
1281 cmdline_parse_inst_t cmd_config_rx_tx = {
1282 	.f = cmd_config_rx_tx_parsed,
1283 	.data = NULL,
1284 	.help_str = "port config all rxq|txq|rxd|txd <value>",
1285 	.tokens = {
1286 		(void *)&cmd_config_rx_tx_port,
1287 		(void *)&cmd_config_rx_tx_keyword,
1288 		(void *)&cmd_config_rx_tx_all,
1289 		(void *)&cmd_config_rx_tx_name,
1290 		(void *)&cmd_config_rx_tx_value,
1291 		NULL,
1292 	},
1293 };
1294 
1295 /* *** config max packet length *** */
1296 struct cmd_config_max_pkt_len_result {
1297 	cmdline_fixed_string_t port;
1298 	cmdline_fixed_string_t keyword;
1299 	cmdline_fixed_string_t all;
1300 	cmdline_fixed_string_t name;
1301 	uint32_t value;
1302 };
1303 
1304 static void
1305 cmd_config_max_pkt_len_parsed(void *parsed_result,
1306 				__attribute__((unused)) struct cmdline *cl,
1307 				__attribute__((unused)) void *data)
1308 {
1309 	struct cmd_config_max_pkt_len_result *res = parsed_result;
1310 
1311 	if (!all_ports_stopped()) {
1312 		printf("Please stop all ports first\n");
1313 		return;
1314 	}
1315 
1316 	if (!strcmp(res->name, "max-pkt-len")) {
1317 		if (res->value < ETHER_MIN_LEN) {
1318 			printf("max-pkt-len can not be less than %d\n",
1319 							ETHER_MIN_LEN);
1320 			return;
1321 		}
1322 		if (res->value == rx_mode.max_rx_pkt_len)
1323 			return;
1324 
1325 		rx_mode.max_rx_pkt_len = res->value;
1326 		if (res->value > ETHER_MAX_LEN)
1327 			rx_mode.jumbo_frame = 1;
1328 		else
1329 			rx_mode.jumbo_frame = 0;
1330 	} else {
1331 		printf("Unknown parameter\n");
1332 		return;
1333 	}
1334 
1335 	init_port_config();
1336 
1337 	cmd_reconfig_device_queue(RTE_PORT_ALL, 1, 1);
1338 }
1339 
1340 cmdline_parse_token_string_t cmd_config_max_pkt_len_port =
1341 	TOKEN_STRING_INITIALIZER(struct cmd_config_max_pkt_len_result, port,
1342 								"port");
1343 cmdline_parse_token_string_t cmd_config_max_pkt_len_keyword =
1344 	TOKEN_STRING_INITIALIZER(struct cmd_config_max_pkt_len_result, keyword,
1345 								"config");
1346 cmdline_parse_token_string_t cmd_config_max_pkt_len_all =
1347 	TOKEN_STRING_INITIALIZER(struct cmd_config_max_pkt_len_result, all,
1348 								"all");
1349 cmdline_parse_token_string_t cmd_config_max_pkt_len_name =
1350 	TOKEN_STRING_INITIALIZER(struct cmd_config_max_pkt_len_result, name,
1351 								"max-pkt-len");
1352 cmdline_parse_token_num_t cmd_config_max_pkt_len_value =
1353 	TOKEN_NUM_INITIALIZER(struct cmd_config_max_pkt_len_result, value,
1354 								UINT32);
1355 
1356 cmdline_parse_inst_t cmd_config_max_pkt_len = {
1357 	.f = cmd_config_max_pkt_len_parsed,
1358 	.data = NULL,
1359 	.help_str = "port config all max-pkt-len <value>",
1360 	.tokens = {
1361 		(void *)&cmd_config_max_pkt_len_port,
1362 		(void *)&cmd_config_max_pkt_len_keyword,
1363 		(void *)&cmd_config_max_pkt_len_all,
1364 		(void *)&cmd_config_max_pkt_len_name,
1365 		(void *)&cmd_config_max_pkt_len_value,
1366 		NULL,
1367 	},
1368 };
1369 
1370 /* *** configure port MTU *** */
1371 struct cmd_config_mtu_result {
1372 	cmdline_fixed_string_t port;
1373 	cmdline_fixed_string_t keyword;
1374 	cmdline_fixed_string_t mtu;
1375 	uint8_t port_id;
1376 	uint16_t value;
1377 };
1378 
1379 static void
1380 cmd_config_mtu_parsed(void *parsed_result,
1381 		      __attribute__((unused)) struct cmdline *cl,
1382 		      __attribute__((unused)) void *data)
1383 {
1384 	struct cmd_config_mtu_result *res = parsed_result;
1385 
1386 	if (res->value < ETHER_MIN_LEN) {
1387 		printf("mtu cannot be less than %d\n", ETHER_MIN_LEN);
1388 		return;
1389 	}
1390 	port_mtu_set(res->port_id, res->value);
1391 }
1392 
1393 cmdline_parse_token_string_t cmd_config_mtu_port =
1394 	TOKEN_STRING_INITIALIZER(struct cmd_config_mtu_result, port,
1395 				 "port");
1396 cmdline_parse_token_string_t cmd_config_mtu_keyword =
1397 	TOKEN_STRING_INITIALIZER(struct cmd_config_mtu_result, keyword,
1398 				 "config");
1399 cmdline_parse_token_string_t cmd_config_mtu_mtu =
1400 	TOKEN_STRING_INITIALIZER(struct cmd_config_mtu_result, keyword,
1401 				 "mtu");
1402 cmdline_parse_token_num_t cmd_config_mtu_port_id =
1403 	TOKEN_NUM_INITIALIZER(struct cmd_config_mtu_result, port_id, UINT8);
1404 cmdline_parse_token_num_t cmd_config_mtu_value =
1405 	TOKEN_NUM_INITIALIZER(struct cmd_config_mtu_result, value, UINT16);
1406 
1407 cmdline_parse_inst_t cmd_config_mtu = {
1408 	.f = cmd_config_mtu_parsed,
1409 	.data = NULL,
1410 	.help_str = "port config mtu <port_id> <value>",
1411 	.tokens = {
1412 		(void *)&cmd_config_mtu_port,
1413 		(void *)&cmd_config_mtu_keyword,
1414 		(void *)&cmd_config_mtu_mtu,
1415 		(void *)&cmd_config_mtu_port_id,
1416 		(void *)&cmd_config_mtu_value,
1417 		NULL,
1418 	},
1419 };
1420 
1421 /* *** configure rx mode *** */
1422 struct cmd_config_rx_mode_flag {
1423 	cmdline_fixed_string_t port;
1424 	cmdline_fixed_string_t keyword;
1425 	cmdline_fixed_string_t all;
1426 	cmdline_fixed_string_t name;
1427 	cmdline_fixed_string_t value;
1428 };
1429 
1430 static void
1431 cmd_config_rx_mode_flag_parsed(void *parsed_result,
1432 				__attribute__((unused)) struct cmdline *cl,
1433 				__attribute__((unused)) void *data)
1434 {
1435 	struct cmd_config_rx_mode_flag *res = parsed_result;
1436 
1437 	if (!all_ports_stopped()) {
1438 		printf("Please stop all ports first\n");
1439 		return;
1440 	}
1441 
1442 	if (!strcmp(res->name, "crc-strip")) {
1443 		if (!strcmp(res->value, "on"))
1444 			rx_mode.hw_strip_crc = 1;
1445 		else if (!strcmp(res->value, "off"))
1446 			rx_mode.hw_strip_crc = 0;
1447 		else {
1448 			printf("Unknown parameter\n");
1449 			return;
1450 		}
1451 	} else if (!strcmp(res->name, "scatter")) {
1452 		if (!strcmp(res->value, "on"))
1453 			rx_mode.enable_scatter = 1;
1454 		else if (!strcmp(res->value, "off"))
1455 			rx_mode.enable_scatter = 0;
1456 		else {
1457 			printf("Unknown parameter\n");
1458 			return;
1459 		}
1460 	} else if (!strcmp(res->name, "rx-cksum")) {
1461 		if (!strcmp(res->value, "on"))
1462 			rx_mode.hw_ip_checksum = 1;
1463 		else if (!strcmp(res->value, "off"))
1464 			rx_mode.hw_ip_checksum = 0;
1465 		else {
1466 			printf("Unknown parameter\n");
1467 			return;
1468 		}
1469 	} else if (!strcmp(res->name, "hw-vlan")) {
1470 		if (!strcmp(res->value, "on")) {
1471 			rx_mode.hw_vlan_filter = 1;
1472 			rx_mode.hw_vlan_strip  = 1;
1473 		}
1474 		else if (!strcmp(res->value, "off")) {
1475 			rx_mode.hw_vlan_filter = 0;
1476 			rx_mode.hw_vlan_strip  = 0;
1477 		}
1478 		else {
1479 			printf("Unknown parameter\n");
1480 			return;
1481 		}
1482 	} else if (!strcmp(res->name, "hw-vlan-filter")) {
1483 		if (!strcmp(res->value, "on"))
1484 			rx_mode.hw_vlan_filter = 1;
1485 		else if (!strcmp(res->value, "off"))
1486 			rx_mode.hw_vlan_filter = 0;
1487 		else {
1488 			printf("Unknown parameter\n");
1489 			return;
1490 		}
1491 	} else if (!strcmp(res->name, "hw-vlan-strip")) {
1492 		if (!strcmp(res->value, "on"))
1493 			rx_mode.hw_vlan_strip  = 1;
1494 		else if (!strcmp(res->value, "off"))
1495 			rx_mode.hw_vlan_strip  = 0;
1496 		else {
1497 			printf("Unknown parameter\n");
1498 			return;
1499 		}
1500 	} else if (!strcmp(res->name, "hw-vlan-extend")) {
1501 		if (!strcmp(res->value, "on"))
1502 			rx_mode.hw_vlan_extend = 1;
1503 		else if (!strcmp(res->value, "off"))
1504 			rx_mode.hw_vlan_extend = 0;
1505 		else {
1506 			printf("Unknown parameter\n");
1507 			return;
1508 		}
1509 	} else if (!strcmp(res->name, "drop-en")) {
1510 		if (!strcmp(res->value, "on"))
1511 			rx_drop_en = 1;
1512 		else if (!strcmp(res->value, "off"))
1513 			rx_drop_en = 0;
1514 		else {
1515 			printf("Unknown parameter\n");
1516 			return;
1517 		}
1518 	} else {
1519 		printf("Unknown parameter\n");
1520 		return;
1521 	}
1522 
1523 	init_port_config();
1524 
1525 	cmd_reconfig_device_queue(RTE_PORT_ALL, 1, 1);
1526 }
1527 
1528 cmdline_parse_token_string_t cmd_config_rx_mode_flag_port =
1529 	TOKEN_STRING_INITIALIZER(struct cmd_config_rx_mode_flag, port, "port");
1530 cmdline_parse_token_string_t cmd_config_rx_mode_flag_keyword =
1531 	TOKEN_STRING_INITIALIZER(struct cmd_config_rx_mode_flag, keyword,
1532 								"config");
1533 cmdline_parse_token_string_t cmd_config_rx_mode_flag_all =
1534 	TOKEN_STRING_INITIALIZER(struct cmd_config_rx_mode_flag, all, "all");
1535 cmdline_parse_token_string_t cmd_config_rx_mode_flag_name =
1536 	TOKEN_STRING_INITIALIZER(struct cmd_config_rx_mode_flag, name,
1537 					"crc-strip#scatter#rx-cksum#hw-vlan#"
1538 					"hw-vlan-filter#hw-vlan-strip#hw-vlan-extend");
1539 cmdline_parse_token_string_t cmd_config_rx_mode_flag_value =
1540 	TOKEN_STRING_INITIALIZER(struct cmd_config_rx_mode_flag, value,
1541 							"on#off");
1542 
1543 cmdline_parse_inst_t cmd_config_rx_mode_flag = {
1544 	.f = cmd_config_rx_mode_flag_parsed,
1545 	.data = NULL,
1546 	.help_str = "port config all crc-strip|scatter|rx-cksum|hw-vlan|"
1547 		"hw-vlan-filter|hw-vlan-strip|hw-vlan-extend on|off",
1548 	.tokens = {
1549 		(void *)&cmd_config_rx_mode_flag_port,
1550 		(void *)&cmd_config_rx_mode_flag_keyword,
1551 		(void *)&cmd_config_rx_mode_flag_all,
1552 		(void *)&cmd_config_rx_mode_flag_name,
1553 		(void *)&cmd_config_rx_mode_flag_value,
1554 		NULL,
1555 	},
1556 };
1557 
1558 /* *** configure rss *** */
1559 struct cmd_config_rss {
1560 	cmdline_fixed_string_t port;
1561 	cmdline_fixed_string_t keyword;
1562 	cmdline_fixed_string_t all;
1563 	cmdline_fixed_string_t name;
1564 	cmdline_fixed_string_t value;
1565 };
1566 
1567 static void
1568 cmd_config_rss_parsed(void *parsed_result,
1569 			__attribute__((unused)) struct cmdline *cl,
1570 			__attribute__((unused)) void *data)
1571 {
1572 	struct cmd_config_rss *res = parsed_result;
1573 	struct rte_eth_rss_conf rss_conf;
1574 	int diag;
1575 	uint8_t i;
1576 
1577 	if (!strcmp(res->value, "all"))
1578 		rss_conf.rss_hf = ETH_RSS_IP | ETH_RSS_TCP |
1579 				ETH_RSS_UDP | ETH_RSS_SCTP |
1580 					ETH_RSS_L2_PAYLOAD;
1581 	else if (!strcmp(res->value, "ip"))
1582 		rss_conf.rss_hf = ETH_RSS_IP;
1583 	else if (!strcmp(res->value, "udp"))
1584 		rss_conf.rss_hf = ETH_RSS_UDP;
1585 	else if (!strcmp(res->value, "tcp"))
1586 		rss_conf.rss_hf = ETH_RSS_TCP;
1587 	else if (!strcmp(res->value, "sctp"))
1588 		rss_conf.rss_hf = ETH_RSS_SCTP;
1589 	else if (!strcmp(res->value, "ether"))
1590 		rss_conf.rss_hf = ETH_RSS_L2_PAYLOAD;
1591 	else if (!strcmp(res->value, "port"))
1592 		rss_conf.rss_hf = ETH_RSS_PORT;
1593 	else if (!strcmp(res->value, "vxlan"))
1594 		rss_conf.rss_hf = ETH_RSS_VXLAN;
1595 	else if (!strcmp(res->value, "geneve"))
1596 		rss_conf.rss_hf = ETH_RSS_GENEVE;
1597 	else if (!strcmp(res->value, "nvgre"))
1598 		rss_conf.rss_hf = ETH_RSS_NVGRE;
1599 	else if (!strcmp(res->value, "none"))
1600 		rss_conf.rss_hf = 0;
1601 	else {
1602 		printf("Unknown parameter\n");
1603 		return;
1604 	}
1605 	rss_conf.rss_key = NULL;
1606 	for (i = 0; i < rte_eth_dev_count(); i++) {
1607 		diag = rte_eth_dev_rss_hash_update(i, &rss_conf);
1608 		if (diag < 0)
1609 			printf("Configuration of RSS hash at ethernet port %d "
1610 				"failed with error (%d): %s.\n",
1611 				i, -diag, strerror(-diag));
1612 	}
1613 }
1614 
1615 cmdline_parse_token_string_t cmd_config_rss_port =
1616 	TOKEN_STRING_INITIALIZER(struct cmd_config_rss, port, "port");
1617 cmdline_parse_token_string_t cmd_config_rss_keyword =
1618 	TOKEN_STRING_INITIALIZER(struct cmd_config_rss, keyword, "config");
1619 cmdline_parse_token_string_t cmd_config_rss_all =
1620 	TOKEN_STRING_INITIALIZER(struct cmd_config_rss, all, "all");
1621 cmdline_parse_token_string_t cmd_config_rss_name =
1622 	TOKEN_STRING_INITIALIZER(struct cmd_config_rss, name, "rss");
1623 cmdline_parse_token_string_t cmd_config_rss_value =
1624 	TOKEN_STRING_INITIALIZER(struct cmd_config_rss, value,
1625 		"all#ip#tcp#udp#sctp#ether#port#vxlan#geneve#nvgre#none");
1626 
1627 cmdline_parse_inst_t cmd_config_rss = {
1628 	.f = cmd_config_rss_parsed,
1629 	.data = NULL,
1630 	.help_str = "port config all rss "
1631 		"all|ip|tcp|udp|sctp|ether|port|vxlan|geneve|nvgre|none",
1632 	.tokens = {
1633 		(void *)&cmd_config_rss_port,
1634 		(void *)&cmd_config_rss_keyword,
1635 		(void *)&cmd_config_rss_all,
1636 		(void *)&cmd_config_rss_name,
1637 		(void *)&cmd_config_rss_value,
1638 		NULL,
1639 	},
1640 };
1641 
1642 /* *** configure rss hash key *** */
1643 struct cmd_config_rss_hash_key {
1644 	cmdline_fixed_string_t port;
1645 	cmdline_fixed_string_t config;
1646 	uint8_t port_id;
1647 	cmdline_fixed_string_t rss_hash_key;
1648 	cmdline_fixed_string_t rss_type;
1649 	cmdline_fixed_string_t key;
1650 };
1651 
1652 static uint8_t
1653 hexa_digit_to_value(char hexa_digit)
1654 {
1655 	if ((hexa_digit >= '0') && (hexa_digit <= '9'))
1656 		return (uint8_t) (hexa_digit - '0');
1657 	if ((hexa_digit >= 'a') && (hexa_digit <= 'f'))
1658 		return (uint8_t) ((hexa_digit - 'a') + 10);
1659 	if ((hexa_digit >= 'A') && (hexa_digit <= 'F'))
1660 		return (uint8_t) ((hexa_digit - 'A') + 10);
1661 	/* Invalid hexa digit */
1662 	return 0xFF;
1663 }
1664 
1665 static uint8_t
1666 parse_and_check_key_hexa_digit(char *key, int idx)
1667 {
1668 	uint8_t hexa_v;
1669 
1670 	hexa_v = hexa_digit_to_value(key[idx]);
1671 	if (hexa_v == 0xFF)
1672 		printf("invalid key: character %c at position %d is not a "
1673 		       "valid hexa digit\n", key[idx], idx);
1674 	return hexa_v;
1675 }
1676 
1677 static void
1678 cmd_config_rss_hash_key_parsed(void *parsed_result,
1679 			       __attribute__((unused)) struct cmdline *cl,
1680 			       __attribute__((unused)) void *data)
1681 {
1682 	struct cmd_config_rss_hash_key *res = parsed_result;
1683 	uint8_t hash_key[RSS_HASH_KEY_LENGTH];
1684 	uint8_t xdgt0;
1685 	uint8_t xdgt1;
1686 	int i;
1687 	struct rte_eth_dev_info dev_info;
1688 	uint8_t hash_key_size;
1689 	uint32_t key_len;
1690 
1691 	memset(&dev_info, 0, sizeof(dev_info));
1692 	rte_eth_dev_info_get(res->port_id, &dev_info);
1693 	if (dev_info.hash_key_size > 0 &&
1694 			dev_info.hash_key_size <= sizeof(hash_key))
1695 		hash_key_size = dev_info.hash_key_size;
1696 	else {
1697 		printf("dev_info did not provide a valid hash key size\n");
1698 		return;
1699 	}
1700 	/* Check the length of the RSS hash key */
1701 	key_len = strlen(res->key);
1702 	if (key_len != (hash_key_size * 2)) {
1703 		printf("key length: %d invalid - key must be a string of %d"
1704 			   " hexa-decimal numbers\n",
1705 			   (int) key_len, hash_key_size * 2);
1706 		return;
1707 	}
1708 	/* Translate RSS hash key into binary representation */
1709 	for (i = 0; i < hash_key_size; i++) {
1710 		xdgt0 = parse_and_check_key_hexa_digit(res->key, (i * 2));
1711 		if (xdgt0 == 0xFF)
1712 			return;
1713 		xdgt1 = parse_and_check_key_hexa_digit(res->key, (i * 2) + 1);
1714 		if (xdgt1 == 0xFF)
1715 			return;
1716 		hash_key[i] = (uint8_t) ((xdgt0 * 16) + xdgt1);
1717 	}
1718 	port_rss_hash_key_update(res->port_id, res->rss_type, hash_key,
1719 			hash_key_size);
1720 }
1721 
1722 cmdline_parse_token_string_t cmd_config_rss_hash_key_port =
1723 	TOKEN_STRING_INITIALIZER(struct cmd_config_rss_hash_key, port, "port");
1724 cmdline_parse_token_string_t cmd_config_rss_hash_key_config =
1725 	TOKEN_STRING_INITIALIZER(struct cmd_config_rss_hash_key, config,
1726 				 "config");
1727 cmdline_parse_token_num_t cmd_config_rss_hash_key_port_id =
1728 	TOKEN_NUM_INITIALIZER(struct cmd_config_rss_hash_key, port_id, UINT8);
1729 cmdline_parse_token_string_t cmd_config_rss_hash_key_rss_hash_key =
1730 	TOKEN_STRING_INITIALIZER(struct cmd_config_rss_hash_key,
1731 				 rss_hash_key, "rss-hash-key");
1732 cmdline_parse_token_string_t cmd_config_rss_hash_key_rss_type =
1733 	TOKEN_STRING_INITIALIZER(struct cmd_config_rss_hash_key, rss_type,
1734 				 "ipv4#ipv4-frag#ipv4-tcp#ipv4-udp#ipv4-sctp#"
1735 				 "ipv4-other#ipv6#ipv6-frag#ipv6-tcp#ipv6-udp#"
1736 				 "ipv6-sctp#ipv6-other#l2-payload#ipv6-ex#"
1737 				 "ipv6-tcp-ex#ipv6-udp-ex");
1738 cmdline_parse_token_string_t cmd_config_rss_hash_key_value =
1739 	TOKEN_STRING_INITIALIZER(struct cmd_config_rss_hash_key, key, NULL);
1740 
1741 cmdline_parse_inst_t cmd_config_rss_hash_key = {
1742 	.f = cmd_config_rss_hash_key_parsed,
1743 	.data = NULL,
1744 	.help_str = "port config <port_id> rss-hash-key "
1745 		"ipv4|ipv4-frag|ipv4-tcp|ipv4-udp|ipv4-sctp|ipv4-other|"
1746 		"ipv6|ipv6-frag|ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other|"
1747 		"l2-payload|ipv6-ex|ipv6-tcp-ex|ipv6-udp-ex "
1748 		"<string of hex digits (variable length, NIC dependent)>",
1749 	.tokens = {
1750 		(void *)&cmd_config_rss_hash_key_port,
1751 		(void *)&cmd_config_rss_hash_key_config,
1752 		(void *)&cmd_config_rss_hash_key_port_id,
1753 		(void *)&cmd_config_rss_hash_key_rss_hash_key,
1754 		(void *)&cmd_config_rss_hash_key_rss_type,
1755 		(void *)&cmd_config_rss_hash_key_value,
1756 		NULL,
1757 	},
1758 };
1759 
1760 /* *** configure port rxq/txq start/stop *** */
1761 struct cmd_config_rxtx_queue {
1762 	cmdline_fixed_string_t port;
1763 	uint8_t portid;
1764 	cmdline_fixed_string_t rxtxq;
1765 	uint16_t qid;
1766 	cmdline_fixed_string_t opname;
1767 };
1768 
1769 static void
1770 cmd_config_rxtx_queue_parsed(void *parsed_result,
1771 			__attribute__((unused)) struct cmdline *cl,
1772 			__attribute__((unused)) void *data)
1773 {
1774 	struct cmd_config_rxtx_queue *res = parsed_result;
1775 	uint8_t isrx;
1776 	uint8_t isstart;
1777 	int ret = 0;
1778 
1779 	if (test_done == 0) {
1780 		printf("Please stop forwarding first\n");
1781 		return;
1782 	}
1783 
1784 	if (port_id_is_invalid(res->portid, ENABLED_WARN))
1785 		return;
1786 
1787 	if (port_is_started(res->portid) != 1) {
1788 		printf("Please start port %u first\n", res->portid);
1789 		return;
1790 	}
1791 
1792 	if (!strcmp(res->rxtxq, "rxq"))
1793 		isrx = 1;
1794 	else if (!strcmp(res->rxtxq, "txq"))
1795 		isrx = 0;
1796 	else {
1797 		printf("Unknown parameter\n");
1798 		return;
1799 	}
1800 
1801 	if (isrx && rx_queue_id_is_invalid(res->qid))
1802 		return;
1803 	else if (!isrx && tx_queue_id_is_invalid(res->qid))
1804 		return;
1805 
1806 	if (!strcmp(res->opname, "start"))
1807 		isstart = 1;
1808 	else if (!strcmp(res->opname, "stop"))
1809 		isstart = 0;
1810 	else {
1811 		printf("Unknown parameter\n");
1812 		return;
1813 	}
1814 
1815 	if (isstart && isrx)
1816 		ret = rte_eth_dev_rx_queue_start(res->portid, res->qid);
1817 	else if (!isstart && isrx)
1818 		ret = rte_eth_dev_rx_queue_stop(res->portid, res->qid);
1819 	else if (isstart && !isrx)
1820 		ret = rte_eth_dev_tx_queue_start(res->portid, res->qid);
1821 	else
1822 		ret = rte_eth_dev_tx_queue_stop(res->portid, res->qid);
1823 
1824 	if (ret == -ENOTSUP)
1825 		printf("Function not supported in PMD driver\n");
1826 }
1827 
1828 cmdline_parse_token_string_t cmd_config_rxtx_queue_port =
1829 	TOKEN_STRING_INITIALIZER(struct cmd_config_rxtx_queue, port, "port");
1830 cmdline_parse_token_num_t cmd_config_rxtx_queue_portid =
1831 	TOKEN_NUM_INITIALIZER(struct cmd_config_rxtx_queue, portid, UINT8);
1832 cmdline_parse_token_string_t cmd_config_rxtx_queue_rxtxq =
1833 	TOKEN_STRING_INITIALIZER(struct cmd_config_rxtx_queue, rxtxq, "rxq#txq");
1834 cmdline_parse_token_num_t cmd_config_rxtx_queue_qid =
1835 	TOKEN_NUM_INITIALIZER(struct cmd_config_rxtx_queue, qid, UINT16);
1836 cmdline_parse_token_string_t cmd_config_rxtx_queue_opname =
1837 	TOKEN_STRING_INITIALIZER(struct cmd_config_rxtx_queue, opname,
1838 						"start#stop");
1839 
1840 cmdline_parse_inst_t cmd_config_rxtx_queue = {
1841 	.f = cmd_config_rxtx_queue_parsed,
1842 	.data = NULL,
1843 	.help_str = "port <port_id> rxq|txq <queue_id> start|stop",
1844 	.tokens = {
1845 		(void *)&cmd_config_speed_all_port,
1846 		(void *)&cmd_config_rxtx_queue_portid,
1847 		(void *)&cmd_config_rxtx_queue_rxtxq,
1848 		(void *)&cmd_config_rxtx_queue_qid,
1849 		(void *)&cmd_config_rxtx_queue_opname,
1850 		NULL,
1851 	},
1852 };
1853 
1854 /* *** Configure RSS RETA *** */
1855 struct cmd_config_rss_reta {
1856 	cmdline_fixed_string_t port;
1857 	cmdline_fixed_string_t keyword;
1858 	uint8_t port_id;
1859 	cmdline_fixed_string_t name;
1860 	cmdline_fixed_string_t list_name;
1861 	cmdline_fixed_string_t list_of_items;
1862 };
1863 
1864 static int
1865 parse_reta_config(const char *str,
1866 		  struct rte_eth_rss_reta_entry64 *reta_conf,
1867 		  uint16_t nb_entries)
1868 {
1869 	int i;
1870 	unsigned size;
1871 	uint16_t hash_index, idx, shift;
1872 	uint16_t nb_queue;
1873 	char s[256];
1874 	const char *p, *p0 = str;
1875 	char *end;
1876 	enum fieldnames {
1877 		FLD_HASH_INDEX = 0,
1878 		FLD_QUEUE,
1879 		_NUM_FLD
1880 	};
1881 	unsigned long int_fld[_NUM_FLD];
1882 	char *str_fld[_NUM_FLD];
1883 
1884 	while ((p = strchr(p0,'(')) != NULL) {
1885 		++p;
1886 		if((p0 = strchr(p,')')) == NULL)
1887 			return -1;
1888 
1889 		size = p0 - p;
1890 		if(size >= sizeof(s))
1891 			return -1;
1892 
1893 		snprintf(s, sizeof(s), "%.*s", size, p);
1894 		if (rte_strsplit(s, sizeof(s), str_fld, _NUM_FLD, ',') != _NUM_FLD)
1895 			return -1;
1896 		for (i = 0; i < _NUM_FLD; i++) {
1897 			errno = 0;
1898 			int_fld[i] = strtoul(str_fld[i], &end, 0);
1899 			if (errno != 0 || end == str_fld[i] ||
1900 					int_fld[i] > 65535)
1901 				return -1;
1902 		}
1903 
1904 		hash_index = (uint16_t)int_fld[FLD_HASH_INDEX];
1905 		nb_queue = (uint16_t)int_fld[FLD_QUEUE];
1906 
1907 		if (hash_index >= nb_entries) {
1908 			printf("Invalid RETA hash index=%d\n", hash_index);
1909 			return -1;
1910 		}
1911 
1912 		idx = hash_index / RTE_RETA_GROUP_SIZE;
1913 		shift = hash_index % RTE_RETA_GROUP_SIZE;
1914 		reta_conf[idx].mask |= (1ULL << shift);
1915 		reta_conf[idx].reta[shift] = nb_queue;
1916 	}
1917 
1918 	return 0;
1919 }
1920 
1921 static void
1922 cmd_set_rss_reta_parsed(void *parsed_result,
1923 			__attribute__((unused)) struct cmdline *cl,
1924 			__attribute__((unused)) void *data)
1925 {
1926 	int ret;
1927 	struct rte_eth_dev_info dev_info;
1928 	struct rte_eth_rss_reta_entry64 reta_conf[8];
1929 	struct cmd_config_rss_reta *res = parsed_result;
1930 
1931 	memset(&dev_info, 0, sizeof(dev_info));
1932 	rte_eth_dev_info_get(res->port_id, &dev_info);
1933 	if (dev_info.reta_size == 0) {
1934 		printf("Redirection table size is 0 which is "
1935 					"invalid for RSS\n");
1936 		return;
1937 	} else
1938 		printf("The reta size of port %d is %u\n",
1939 			res->port_id, dev_info.reta_size);
1940 	if (dev_info.reta_size > ETH_RSS_RETA_SIZE_512) {
1941 		printf("Currently do not support more than %u entries of "
1942 			"redirection table\n", ETH_RSS_RETA_SIZE_512);
1943 		return;
1944 	}
1945 
1946 	memset(reta_conf, 0, sizeof(reta_conf));
1947 	if (!strcmp(res->list_name, "reta")) {
1948 		if (parse_reta_config(res->list_of_items, reta_conf,
1949 						dev_info.reta_size)) {
1950 			printf("Invalid RSS Redirection Table "
1951 					"config entered\n");
1952 			return;
1953 		}
1954 		ret = rte_eth_dev_rss_reta_update(res->port_id,
1955 				reta_conf, dev_info.reta_size);
1956 		if (ret != 0)
1957 			printf("Bad redirection table parameter, "
1958 					"return code = %d \n", ret);
1959 	}
1960 }
1961 
1962 cmdline_parse_token_string_t cmd_config_rss_reta_port =
1963 	TOKEN_STRING_INITIALIZER(struct cmd_config_rss_reta, port, "port");
1964 cmdline_parse_token_string_t cmd_config_rss_reta_keyword =
1965 	TOKEN_STRING_INITIALIZER(struct cmd_config_rss_reta, keyword, "config");
1966 cmdline_parse_token_num_t cmd_config_rss_reta_port_id =
1967 	TOKEN_NUM_INITIALIZER(struct cmd_config_rss_reta, port_id, UINT8);
1968 cmdline_parse_token_string_t cmd_config_rss_reta_name =
1969 	TOKEN_STRING_INITIALIZER(struct cmd_config_rss_reta, name, "rss");
1970 cmdline_parse_token_string_t cmd_config_rss_reta_list_name =
1971 	TOKEN_STRING_INITIALIZER(struct cmd_config_rss_reta, list_name, "reta");
1972 cmdline_parse_token_string_t cmd_config_rss_reta_list_of_items =
1973         TOKEN_STRING_INITIALIZER(struct cmd_config_rss_reta, list_of_items,
1974                                  NULL);
1975 cmdline_parse_inst_t cmd_config_rss_reta = {
1976 	.f = cmd_set_rss_reta_parsed,
1977 	.data = NULL,
1978 	.help_str = "port config <port_id> rss reta <hash,queue[,hash,queue]*>",
1979 	.tokens = {
1980 		(void *)&cmd_config_rss_reta_port,
1981 		(void *)&cmd_config_rss_reta_keyword,
1982 		(void *)&cmd_config_rss_reta_port_id,
1983 		(void *)&cmd_config_rss_reta_name,
1984 		(void *)&cmd_config_rss_reta_list_name,
1985 		(void *)&cmd_config_rss_reta_list_of_items,
1986 		NULL,
1987 	},
1988 };
1989 
1990 /* *** SHOW PORT RETA INFO *** */
1991 struct cmd_showport_reta {
1992 	cmdline_fixed_string_t show;
1993 	cmdline_fixed_string_t port;
1994 	uint8_t port_id;
1995 	cmdline_fixed_string_t rss;
1996 	cmdline_fixed_string_t reta;
1997 	uint16_t size;
1998 	cmdline_fixed_string_t list_of_items;
1999 };
2000 
2001 static int
2002 showport_parse_reta_config(struct rte_eth_rss_reta_entry64 *conf,
2003 			   uint16_t nb_entries,
2004 			   char *str)
2005 {
2006 	uint32_t size;
2007 	const char *p, *p0 = str;
2008 	char s[256];
2009 	char *end;
2010 	char *str_fld[8];
2011 	uint16_t i, num = nb_entries / RTE_RETA_GROUP_SIZE;
2012 	int ret;
2013 
2014 	p = strchr(p0, '(');
2015 	if (p == NULL)
2016 		return -1;
2017 	p++;
2018 	p0 = strchr(p, ')');
2019 	if (p0 == NULL)
2020 		return -1;
2021 	size = p0 - p;
2022 	if (size >= sizeof(s)) {
2023 		printf("The string size exceeds the internal buffer size\n");
2024 		return -1;
2025 	}
2026 	snprintf(s, sizeof(s), "%.*s", size, p);
2027 	ret = rte_strsplit(s, sizeof(s), str_fld, num, ',');
2028 	if (ret <= 0 || ret != num) {
2029 		printf("The bits of masks do not match the number of "
2030 					"reta entries: %u\n", num);
2031 		return -1;
2032 	}
2033 	for (i = 0; i < ret; i++)
2034 		conf[i].mask = (uint64_t)strtoul(str_fld[i], &end, 0);
2035 
2036 	return 0;
2037 }
2038 
2039 static void
2040 cmd_showport_reta_parsed(void *parsed_result,
2041 			 __attribute__((unused)) struct cmdline *cl,
2042 			 __attribute__((unused)) void *data)
2043 {
2044 	struct cmd_showport_reta *res = parsed_result;
2045 	struct rte_eth_rss_reta_entry64 reta_conf[8];
2046 	struct rte_eth_dev_info dev_info;
2047 
2048 	memset(&dev_info, 0, sizeof(dev_info));
2049 	rte_eth_dev_info_get(res->port_id, &dev_info);
2050 	if (dev_info.reta_size == 0 || res->size != dev_info.reta_size ||
2051 				res->size > ETH_RSS_RETA_SIZE_512) {
2052 		printf("Invalid redirection table size: %u\n", res->size);
2053 		return;
2054 	}
2055 
2056 	memset(reta_conf, 0, sizeof(reta_conf));
2057 	if (showport_parse_reta_config(reta_conf, res->size,
2058 				res->list_of_items) < 0) {
2059 		printf("Invalid string: %s for reta masks\n",
2060 					res->list_of_items);
2061 		return;
2062 	}
2063 	port_rss_reta_info(res->port_id, reta_conf, res->size);
2064 }
2065 
2066 cmdline_parse_token_string_t cmd_showport_reta_show =
2067 	TOKEN_STRING_INITIALIZER(struct  cmd_showport_reta, show, "show");
2068 cmdline_parse_token_string_t cmd_showport_reta_port =
2069 	TOKEN_STRING_INITIALIZER(struct  cmd_showport_reta, port, "port");
2070 cmdline_parse_token_num_t cmd_showport_reta_port_id =
2071 	TOKEN_NUM_INITIALIZER(struct cmd_showport_reta, port_id, UINT8);
2072 cmdline_parse_token_string_t cmd_showport_reta_rss =
2073 	TOKEN_STRING_INITIALIZER(struct cmd_showport_reta, rss, "rss");
2074 cmdline_parse_token_string_t cmd_showport_reta_reta =
2075 	TOKEN_STRING_INITIALIZER(struct cmd_showport_reta, reta, "reta");
2076 cmdline_parse_token_num_t cmd_showport_reta_size =
2077 	TOKEN_NUM_INITIALIZER(struct cmd_showport_reta, size, UINT16);
2078 cmdline_parse_token_string_t cmd_showport_reta_list_of_items =
2079 	TOKEN_STRING_INITIALIZER(struct cmd_showport_reta,
2080 					list_of_items, NULL);
2081 
2082 cmdline_parse_inst_t cmd_showport_reta = {
2083 	.f = cmd_showport_reta_parsed,
2084 	.data = NULL,
2085 	.help_str = "show port <port_id> rss reta <size> <mask0[,mask1]*>",
2086 	.tokens = {
2087 		(void *)&cmd_showport_reta_show,
2088 		(void *)&cmd_showport_reta_port,
2089 		(void *)&cmd_showport_reta_port_id,
2090 		(void *)&cmd_showport_reta_rss,
2091 		(void *)&cmd_showport_reta_reta,
2092 		(void *)&cmd_showport_reta_size,
2093 		(void *)&cmd_showport_reta_list_of_items,
2094 		NULL,
2095 	},
2096 };
2097 
2098 /* *** Show RSS hash configuration *** */
2099 struct cmd_showport_rss_hash {
2100 	cmdline_fixed_string_t show;
2101 	cmdline_fixed_string_t port;
2102 	uint8_t port_id;
2103 	cmdline_fixed_string_t rss_hash;
2104 	cmdline_fixed_string_t rss_type;
2105 	cmdline_fixed_string_t key; /* optional argument */
2106 };
2107 
2108 static void cmd_showport_rss_hash_parsed(void *parsed_result,
2109 				__attribute__((unused)) struct cmdline *cl,
2110 				void *show_rss_key)
2111 {
2112 	struct cmd_showport_rss_hash *res = parsed_result;
2113 
2114 	port_rss_hash_conf_show(res->port_id, res->rss_type,
2115 				show_rss_key != NULL);
2116 }
2117 
2118 cmdline_parse_token_string_t cmd_showport_rss_hash_show =
2119 	TOKEN_STRING_INITIALIZER(struct cmd_showport_rss_hash, show, "show");
2120 cmdline_parse_token_string_t cmd_showport_rss_hash_port =
2121 	TOKEN_STRING_INITIALIZER(struct cmd_showport_rss_hash, port, "port");
2122 cmdline_parse_token_num_t cmd_showport_rss_hash_port_id =
2123 	TOKEN_NUM_INITIALIZER(struct cmd_showport_rss_hash, port_id, UINT8);
2124 cmdline_parse_token_string_t cmd_showport_rss_hash_rss_hash =
2125 	TOKEN_STRING_INITIALIZER(struct cmd_showport_rss_hash, rss_hash,
2126 				 "rss-hash");
2127 cmdline_parse_token_string_t cmd_showport_rss_hash_rss_hash_info =
2128 	TOKEN_STRING_INITIALIZER(struct cmd_showport_rss_hash, rss_type,
2129 				 "ipv4#ipv4-frag#ipv4-tcp#ipv4-udp#ipv4-sctp#"
2130 				 "ipv4-other#ipv6#ipv6-frag#ipv6-tcp#ipv6-udp#"
2131 				 "ipv6-sctp#ipv6-other#l2-payload#ipv6-ex#"
2132 				 "ipv6-tcp-ex#ipv6-udp-ex");
2133 cmdline_parse_token_string_t cmd_showport_rss_hash_rss_key =
2134 	TOKEN_STRING_INITIALIZER(struct cmd_showport_rss_hash, key, "key");
2135 
2136 cmdline_parse_inst_t cmd_showport_rss_hash = {
2137 	.f = cmd_showport_rss_hash_parsed,
2138 	.data = NULL,
2139 	.help_str = "show port <port_id> rss-hash "
2140 		"ipv4|ipv4-frag|ipv4-tcp|ipv4-udp|ipv4-sctp|ipv4-other|"
2141 		"ipv6|ipv6-frag|ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other|"
2142 		"l2-payload|ipv6-ex|ipv6-tcp-ex|ipv6-udp-ex",
2143 	.tokens = {
2144 		(void *)&cmd_showport_rss_hash_show,
2145 		(void *)&cmd_showport_rss_hash_port,
2146 		(void *)&cmd_showport_rss_hash_port_id,
2147 		(void *)&cmd_showport_rss_hash_rss_hash,
2148 		(void *)&cmd_showport_rss_hash_rss_hash_info,
2149 		NULL,
2150 	},
2151 };
2152 
2153 cmdline_parse_inst_t cmd_showport_rss_hash_key = {
2154 	.f = cmd_showport_rss_hash_parsed,
2155 	.data = (void *)1,
2156 	.help_str = "show port <port_id> rss-hash "
2157 		"ipv4|ipv4-frag|ipv4-tcp|ipv4-udp|ipv4-sctp|ipv4-other|"
2158 		"ipv6|ipv6-frag|ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other|"
2159 		"l2-payload|ipv6-ex|ipv6-tcp-ex|ipv6-udp-ex key",
2160 	.tokens = {
2161 		(void *)&cmd_showport_rss_hash_show,
2162 		(void *)&cmd_showport_rss_hash_port,
2163 		(void *)&cmd_showport_rss_hash_port_id,
2164 		(void *)&cmd_showport_rss_hash_rss_hash,
2165 		(void *)&cmd_showport_rss_hash_rss_hash_info,
2166 		(void *)&cmd_showport_rss_hash_rss_key,
2167 		NULL,
2168 	},
2169 };
2170 
2171 /* *** Configure DCB *** */
2172 struct cmd_config_dcb {
2173 	cmdline_fixed_string_t port;
2174 	cmdline_fixed_string_t config;
2175 	uint8_t port_id;
2176 	cmdline_fixed_string_t dcb;
2177 	cmdline_fixed_string_t vt;
2178 	cmdline_fixed_string_t vt_en;
2179 	uint8_t num_tcs;
2180 	cmdline_fixed_string_t pfc;
2181 	cmdline_fixed_string_t pfc_en;
2182 };
2183 
2184 static void
2185 cmd_config_dcb_parsed(void *parsed_result,
2186                         __attribute__((unused)) struct cmdline *cl,
2187                         __attribute__((unused)) void *data)
2188 {
2189 	struct cmd_config_dcb *res = parsed_result;
2190 	portid_t port_id = res->port_id;
2191 	struct rte_port *port;
2192 	uint8_t pfc_en;
2193 	int ret;
2194 
2195 	port = &ports[port_id];
2196 	/** Check if the port is not started **/
2197 	if (port->port_status != RTE_PORT_STOPPED) {
2198 		printf("Please stop port %d first\n", port_id);
2199 		return;
2200 	}
2201 
2202 	if ((res->num_tcs != ETH_4_TCS) && (res->num_tcs != ETH_8_TCS)) {
2203 		printf("The invalid number of traffic class,"
2204 			" only 4 or 8 allowed.\n");
2205 		return;
2206 	}
2207 
2208 	if (nb_fwd_lcores < res->num_tcs) {
2209 		printf("nb_cores shouldn't be less than number of TCs.\n");
2210 		return;
2211 	}
2212 	if (!strncmp(res->pfc_en, "on", 2))
2213 		pfc_en = 1;
2214 	else
2215 		pfc_en = 0;
2216 
2217 	/* DCB in VT mode */
2218 	if (!strncmp(res->vt_en, "on", 2))
2219 		ret = init_port_dcb_config(port_id, DCB_VT_ENABLED,
2220 				(enum rte_eth_nb_tcs)res->num_tcs,
2221 				pfc_en);
2222 	else
2223 		ret = init_port_dcb_config(port_id, DCB_ENABLED,
2224 				(enum rte_eth_nb_tcs)res->num_tcs,
2225 				pfc_en);
2226 
2227 
2228 	if (ret != 0) {
2229 		printf("Cannot initialize network ports.\n");
2230 		return;
2231 	}
2232 
2233 	cmd_reconfig_device_queue(port_id, 1, 1);
2234 }
2235 
2236 cmdline_parse_token_string_t cmd_config_dcb_port =
2237         TOKEN_STRING_INITIALIZER(struct cmd_config_dcb, port, "port");
2238 cmdline_parse_token_string_t cmd_config_dcb_config =
2239         TOKEN_STRING_INITIALIZER(struct cmd_config_dcb, config, "config");
2240 cmdline_parse_token_num_t cmd_config_dcb_port_id =
2241         TOKEN_NUM_INITIALIZER(struct cmd_config_dcb, port_id, UINT8);
2242 cmdline_parse_token_string_t cmd_config_dcb_dcb =
2243         TOKEN_STRING_INITIALIZER(struct cmd_config_dcb, dcb, "dcb");
2244 cmdline_parse_token_string_t cmd_config_dcb_vt =
2245         TOKEN_STRING_INITIALIZER(struct cmd_config_dcb, vt, "vt");
2246 cmdline_parse_token_string_t cmd_config_dcb_vt_en =
2247         TOKEN_STRING_INITIALIZER(struct cmd_config_dcb, vt_en, "on#off");
2248 cmdline_parse_token_num_t cmd_config_dcb_num_tcs =
2249         TOKEN_NUM_INITIALIZER(struct cmd_config_dcb, num_tcs, UINT8);
2250 cmdline_parse_token_string_t cmd_config_dcb_pfc=
2251         TOKEN_STRING_INITIALIZER(struct cmd_config_dcb, pfc, "pfc");
2252 cmdline_parse_token_string_t cmd_config_dcb_pfc_en =
2253         TOKEN_STRING_INITIALIZER(struct cmd_config_dcb, pfc_en, "on#off");
2254 
2255 cmdline_parse_inst_t cmd_config_dcb = {
2256 	.f = cmd_config_dcb_parsed,
2257 	.data = NULL,
2258 	.help_str = "port config <port-id> dcb vt on|off <num_tcs> pfc on|off",
2259 	.tokens = {
2260 		(void *)&cmd_config_dcb_port,
2261 		(void *)&cmd_config_dcb_config,
2262 		(void *)&cmd_config_dcb_port_id,
2263 		(void *)&cmd_config_dcb_dcb,
2264 		(void *)&cmd_config_dcb_vt,
2265 		(void *)&cmd_config_dcb_vt_en,
2266 		(void *)&cmd_config_dcb_num_tcs,
2267 		(void *)&cmd_config_dcb_pfc,
2268 		(void *)&cmd_config_dcb_pfc_en,
2269                 NULL,
2270         },
2271 };
2272 
2273 /* *** configure number of packets per burst *** */
2274 struct cmd_config_burst {
2275 	cmdline_fixed_string_t port;
2276 	cmdline_fixed_string_t keyword;
2277 	cmdline_fixed_string_t all;
2278 	cmdline_fixed_string_t name;
2279 	uint16_t value;
2280 };
2281 
2282 static void
2283 cmd_config_burst_parsed(void *parsed_result,
2284 			__attribute__((unused)) struct cmdline *cl,
2285 			__attribute__((unused)) void *data)
2286 {
2287 	struct cmd_config_burst *res = parsed_result;
2288 
2289 	if (!all_ports_stopped()) {
2290 		printf("Please stop all ports first\n");
2291 		return;
2292 	}
2293 
2294 	if (!strcmp(res->name, "burst")) {
2295 		if (res->value < 1 || res->value > MAX_PKT_BURST) {
2296 			printf("burst must be >= 1 && <= %d\n", MAX_PKT_BURST);
2297 			return;
2298 		}
2299 		nb_pkt_per_burst = res->value;
2300 	} else {
2301 		printf("Unknown parameter\n");
2302 		return;
2303 	}
2304 
2305 	init_port_config();
2306 
2307 	cmd_reconfig_device_queue(RTE_PORT_ALL, 1, 1);
2308 }
2309 
2310 cmdline_parse_token_string_t cmd_config_burst_port =
2311 	TOKEN_STRING_INITIALIZER(struct cmd_config_burst, port, "port");
2312 cmdline_parse_token_string_t cmd_config_burst_keyword =
2313 	TOKEN_STRING_INITIALIZER(struct cmd_config_burst, keyword, "config");
2314 cmdline_parse_token_string_t cmd_config_burst_all =
2315 	TOKEN_STRING_INITIALIZER(struct cmd_config_burst, all, "all");
2316 cmdline_parse_token_string_t cmd_config_burst_name =
2317 	TOKEN_STRING_INITIALIZER(struct cmd_config_burst, name, "burst");
2318 cmdline_parse_token_num_t cmd_config_burst_value =
2319 	TOKEN_NUM_INITIALIZER(struct cmd_config_burst, value, UINT16);
2320 
2321 cmdline_parse_inst_t cmd_config_burst = {
2322 	.f = cmd_config_burst_parsed,
2323 	.data = NULL,
2324 	.help_str = "port config all burst <value>",
2325 	.tokens = {
2326 		(void *)&cmd_config_burst_port,
2327 		(void *)&cmd_config_burst_keyword,
2328 		(void *)&cmd_config_burst_all,
2329 		(void *)&cmd_config_burst_name,
2330 		(void *)&cmd_config_burst_value,
2331 		NULL,
2332 	},
2333 };
2334 
2335 /* *** configure rx/tx queues *** */
2336 struct cmd_config_thresh {
2337 	cmdline_fixed_string_t port;
2338 	cmdline_fixed_string_t keyword;
2339 	cmdline_fixed_string_t all;
2340 	cmdline_fixed_string_t name;
2341 	uint8_t value;
2342 };
2343 
2344 static void
2345 cmd_config_thresh_parsed(void *parsed_result,
2346 			__attribute__((unused)) struct cmdline *cl,
2347 			__attribute__((unused)) void *data)
2348 {
2349 	struct cmd_config_thresh *res = parsed_result;
2350 
2351 	if (!all_ports_stopped()) {
2352 		printf("Please stop all ports first\n");
2353 		return;
2354 	}
2355 
2356 	if (!strcmp(res->name, "txpt"))
2357 		tx_pthresh = res->value;
2358 	else if(!strcmp(res->name, "txht"))
2359 		tx_hthresh = res->value;
2360 	else if(!strcmp(res->name, "txwt"))
2361 		tx_wthresh = res->value;
2362 	else if(!strcmp(res->name, "rxpt"))
2363 		rx_pthresh = res->value;
2364 	else if(!strcmp(res->name, "rxht"))
2365 		rx_hthresh = res->value;
2366 	else if(!strcmp(res->name, "rxwt"))
2367 		rx_wthresh = res->value;
2368 	else {
2369 		printf("Unknown parameter\n");
2370 		return;
2371 	}
2372 
2373 	init_port_config();
2374 
2375 	cmd_reconfig_device_queue(RTE_PORT_ALL, 1, 1);
2376 }
2377 
2378 cmdline_parse_token_string_t cmd_config_thresh_port =
2379 	TOKEN_STRING_INITIALIZER(struct cmd_config_thresh, port, "port");
2380 cmdline_parse_token_string_t cmd_config_thresh_keyword =
2381 	TOKEN_STRING_INITIALIZER(struct cmd_config_thresh, keyword, "config");
2382 cmdline_parse_token_string_t cmd_config_thresh_all =
2383 	TOKEN_STRING_INITIALIZER(struct cmd_config_thresh, all, "all");
2384 cmdline_parse_token_string_t cmd_config_thresh_name =
2385 	TOKEN_STRING_INITIALIZER(struct cmd_config_thresh, name,
2386 				"txpt#txht#txwt#rxpt#rxht#rxwt");
2387 cmdline_parse_token_num_t cmd_config_thresh_value =
2388 	TOKEN_NUM_INITIALIZER(struct cmd_config_thresh, value, UINT8);
2389 
2390 cmdline_parse_inst_t cmd_config_thresh = {
2391 	.f = cmd_config_thresh_parsed,
2392 	.data = NULL,
2393 	.help_str = "port config all txpt|txht|txwt|rxpt|rxht|rxwt <value>",
2394 	.tokens = {
2395 		(void *)&cmd_config_thresh_port,
2396 		(void *)&cmd_config_thresh_keyword,
2397 		(void *)&cmd_config_thresh_all,
2398 		(void *)&cmd_config_thresh_name,
2399 		(void *)&cmd_config_thresh_value,
2400 		NULL,
2401 	},
2402 };
2403 
2404 /* *** configure free/rs threshold *** */
2405 struct cmd_config_threshold {
2406 	cmdline_fixed_string_t port;
2407 	cmdline_fixed_string_t keyword;
2408 	cmdline_fixed_string_t all;
2409 	cmdline_fixed_string_t name;
2410 	uint16_t value;
2411 };
2412 
2413 static void
2414 cmd_config_threshold_parsed(void *parsed_result,
2415 			__attribute__((unused)) struct cmdline *cl,
2416 			__attribute__((unused)) void *data)
2417 {
2418 	struct cmd_config_threshold *res = parsed_result;
2419 
2420 	if (!all_ports_stopped()) {
2421 		printf("Please stop all ports first\n");
2422 		return;
2423 	}
2424 
2425 	if (!strcmp(res->name, "txfreet"))
2426 		tx_free_thresh = res->value;
2427 	else if (!strcmp(res->name, "txrst"))
2428 		tx_rs_thresh = res->value;
2429 	else if (!strcmp(res->name, "rxfreet"))
2430 		rx_free_thresh = res->value;
2431 	else {
2432 		printf("Unknown parameter\n");
2433 		return;
2434 	}
2435 
2436 	init_port_config();
2437 
2438 	cmd_reconfig_device_queue(RTE_PORT_ALL, 1, 1);
2439 }
2440 
2441 cmdline_parse_token_string_t cmd_config_threshold_port =
2442 	TOKEN_STRING_INITIALIZER(struct cmd_config_threshold, port, "port");
2443 cmdline_parse_token_string_t cmd_config_threshold_keyword =
2444 	TOKEN_STRING_INITIALIZER(struct cmd_config_threshold, keyword,
2445 								"config");
2446 cmdline_parse_token_string_t cmd_config_threshold_all =
2447 	TOKEN_STRING_INITIALIZER(struct cmd_config_threshold, all, "all");
2448 cmdline_parse_token_string_t cmd_config_threshold_name =
2449 	TOKEN_STRING_INITIALIZER(struct cmd_config_threshold, name,
2450 						"txfreet#txrst#rxfreet");
2451 cmdline_parse_token_num_t cmd_config_threshold_value =
2452 	TOKEN_NUM_INITIALIZER(struct cmd_config_threshold, value, UINT16);
2453 
2454 cmdline_parse_inst_t cmd_config_threshold = {
2455 	.f = cmd_config_threshold_parsed,
2456 	.data = NULL,
2457 	.help_str = "port config all txfreet|txrst|rxfreet <value>",
2458 	.tokens = {
2459 		(void *)&cmd_config_threshold_port,
2460 		(void *)&cmd_config_threshold_keyword,
2461 		(void *)&cmd_config_threshold_all,
2462 		(void *)&cmd_config_threshold_name,
2463 		(void *)&cmd_config_threshold_value,
2464 		NULL,
2465 	},
2466 };
2467 
2468 /* *** stop *** */
2469 struct cmd_stop_result {
2470 	cmdline_fixed_string_t stop;
2471 };
2472 
2473 static void cmd_stop_parsed(__attribute__((unused)) void *parsed_result,
2474 			    __attribute__((unused)) struct cmdline *cl,
2475 			    __attribute__((unused)) void *data)
2476 {
2477 	stop_packet_forwarding();
2478 }
2479 
2480 cmdline_parse_token_string_t cmd_stop_stop =
2481 	TOKEN_STRING_INITIALIZER(struct cmd_stop_result, stop, "stop");
2482 
2483 cmdline_parse_inst_t cmd_stop = {
2484 	.f = cmd_stop_parsed,
2485 	.data = NULL,
2486 	.help_str = "stop: Stop packet forwarding",
2487 	.tokens = {
2488 		(void *)&cmd_stop_stop,
2489 		NULL,
2490 	},
2491 };
2492 
2493 /* *** SET CORELIST and PORTLIST CONFIGURATION *** */
2494 
2495 unsigned int
2496 parse_item_list(char* str, const char* item_name, unsigned int max_items,
2497 		unsigned int *parsed_items, int check_unique_values)
2498 {
2499 	unsigned int nb_item;
2500 	unsigned int value;
2501 	unsigned int i;
2502 	unsigned int j;
2503 	int value_ok;
2504 	char c;
2505 
2506 	/*
2507 	 * First parse all items in the list and store their value.
2508 	 */
2509 	value = 0;
2510 	nb_item = 0;
2511 	value_ok = 0;
2512 	for (i = 0; i < strnlen(str, STR_TOKEN_SIZE); i++) {
2513 		c = str[i];
2514 		if ((c >= '0') && (c <= '9')) {
2515 			value = (unsigned int) (value * 10 + (c - '0'));
2516 			value_ok = 1;
2517 			continue;
2518 		}
2519 		if (c != ',') {
2520 			printf("character %c is not a decimal digit\n", c);
2521 			return 0;
2522 		}
2523 		if (! value_ok) {
2524 			printf("No valid value before comma\n");
2525 			return 0;
2526 		}
2527 		if (nb_item < max_items) {
2528 			parsed_items[nb_item] = value;
2529 			value_ok = 0;
2530 			value = 0;
2531 		}
2532 		nb_item++;
2533 	}
2534 	if (nb_item >= max_items) {
2535 		printf("Number of %s = %u > %u (maximum items)\n",
2536 		       item_name, nb_item + 1, max_items);
2537 		return 0;
2538 	}
2539 	parsed_items[nb_item++] = value;
2540 	if (! check_unique_values)
2541 		return nb_item;
2542 
2543 	/*
2544 	 * Then, check that all values in the list are differents.
2545 	 * No optimization here...
2546 	 */
2547 	for (i = 0; i < nb_item; i++) {
2548 		for (j = i + 1; j < nb_item; j++) {
2549 			if (parsed_items[j] == parsed_items[i]) {
2550 				printf("duplicated %s %u at index %u and %u\n",
2551 				       item_name, parsed_items[i], i, j);
2552 				return 0;
2553 			}
2554 		}
2555 	}
2556 	return nb_item;
2557 }
2558 
2559 struct cmd_set_list_result {
2560 	cmdline_fixed_string_t cmd_keyword;
2561 	cmdline_fixed_string_t list_name;
2562 	cmdline_fixed_string_t list_of_items;
2563 };
2564 
2565 static void cmd_set_list_parsed(void *parsed_result,
2566 				__attribute__((unused)) struct cmdline *cl,
2567 				__attribute__((unused)) void *data)
2568 {
2569 	struct cmd_set_list_result *res;
2570 	union {
2571 		unsigned int lcorelist[RTE_MAX_LCORE];
2572 		unsigned int portlist[RTE_MAX_ETHPORTS];
2573 	} parsed_items;
2574 	unsigned int nb_item;
2575 
2576 	if (test_done == 0) {
2577 		printf("Please stop forwarding first\n");
2578 		return;
2579 	}
2580 
2581 	res = parsed_result;
2582 	if (!strcmp(res->list_name, "corelist")) {
2583 		nb_item = parse_item_list(res->list_of_items, "core",
2584 					  RTE_MAX_LCORE,
2585 					  parsed_items.lcorelist, 1);
2586 		if (nb_item > 0) {
2587 			set_fwd_lcores_list(parsed_items.lcorelist, nb_item);
2588 			fwd_config_setup();
2589 		}
2590 		return;
2591 	}
2592 	if (!strcmp(res->list_name, "portlist")) {
2593 		nb_item = parse_item_list(res->list_of_items, "port",
2594 					  RTE_MAX_ETHPORTS,
2595 					  parsed_items.portlist, 1);
2596 		if (nb_item > 0) {
2597 			set_fwd_ports_list(parsed_items.portlist, nb_item);
2598 			fwd_config_setup();
2599 		}
2600 	}
2601 }
2602 
2603 cmdline_parse_token_string_t cmd_set_list_keyword =
2604 	TOKEN_STRING_INITIALIZER(struct cmd_set_list_result, cmd_keyword,
2605 				 "set");
2606 cmdline_parse_token_string_t cmd_set_list_name =
2607 	TOKEN_STRING_INITIALIZER(struct cmd_set_list_result, list_name,
2608 				 "corelist#portlist");
2609 cmdline_parse_token_string_t cmd_set_list_of_items =
2610 	TOKEN_STRING_INITIALIZER(struct cmd_set_list_result, list_of_items,
2611 				 NULL);
2612 
2613 cmdline_parse_inst_t cmd_set_fwd_list = {
2614 	.f = cmd_set_list_parsed,
2615 	.data = NULL,
2616 	.help_str = "set corelist|portlist <list0[,list1]*>",
2617 	.tokens = {
2618 		(void *)&cmd_set_list_keyword,
2619 		(void *)&cmd_set_list_name,
2620 		(void *)&cmd_set_list_of_items,
2621 		NULL,
2622 	},
2623 };
2624 
2625 /* *** SET COREMASK and PORTMASK CONFIGURATION *** */
2626 
2627 struct cmd_setmask_result {
2628 	cmdline_fixed_string_t set;
2629 	cmdline_fixed_string_t mask;
2630 	uint64_t hexavalue;
2631 };
2632 
2633 static void cmd_set_mask_parsed(void *parsed_result,
2634 				__attribute__((unused)) struct cmdline *cl,
2635 				__attribute__((unused)) void *data)
2636 {
2637 	struct cmd_setmask_result *res = parsed_result;
2638 
2639 	if (test_done == 0) {
2640 		printf("Please stop forwarding first\n");
2641 		return;
2642 	}
2643 	if (!strcmp(res->mask, "coremask")) {
2644 		set_fwd_lcores_mask(res->hexavalue);
2645 		fwd_config_setup();
2646 	} else if (!strcmp(res->mask, "portmask")) {
2647 		set_fwd_ports_mask(res->hexavalue);
2648 		fwd_config_setup();
2649 	}
2650 }
2651 
2652 cmdline_parse_token_string_t cmd_setmask_set =
2653 	TOKEN_STRING_INITIALIZER(struct cmd_setmask_result, set, "set");
2654 cmdline_parse_token_string_t cmd_setmask_mask =
2655 	TOKEN_STRING_INITIALIZER(struct cmd_setmask_result, mask,
2656 				 "coremask#portmask");
2657 cmdline_parse_token_num_t cmd_setmask_value =
2658 	TOKEN_NUM_INITIALIZER(struct cmd_setmask_result, hexavalue, UINT64);
2659 
2660 cmdline_parse_inst_t cmd_set_fwd_mask = {
2661 	.f = cmd_set_mask_parsed,
2662 	.data = NULL,
2663 	.help_str = "set coremask|portmask <hexadecimal value>",
2664 	.tokens = {
2665 		(void *)&cmd_setmask_set,
2666 		(void *)&cmd_setmask_mask,
2667 		(void *)&cmd_setmask_value,
2668 		NULL,
2669 	},
2670 };
2671 
2672 /*
2673  * SET NBPORT, NBCORE, PACKET BURST, and VERBOSE LEVEL CONFIGURATION
2674  */
2675 struct cmd_set_result {
2676 	cmdline_fixed_string_t set;
2677 	cmdline_fixed_string_t what;
2678 	uint16_t value;
2679 };
2680 
2681 static void cmd_set_parsed(void *parsed_result,
2682 			   __attribute__((unused)) struct cmdline *cl,
2683 			   __attribute__((unused)) void *data)
2684 {
2685 	struct cmd_set_result *res = parsed_result;
2686 	if (!strcmp(res->what, "nbport")) {
2687 		set_fwd_ports_number(res->value);
2688 		fwd_config_setup();
2689 	} else if (!strcmp(res->what, "nbcore")) {
2690 		set_fwd_lcores_number(res->value);
2691 		fwd_config_setup();
2692 	} else if (!strcmp(res->what, "burst"))
2693 		set_nb_pkt_per_burst(res->value);
2694 	else if (!strcmp(res->what, "verbose"))
2695 		set_verbose_level(res->value);
2696 }
2697 
2698 cmdline_parse_token_string_t cmd_set_set =
2699 	TOKEN_STRING_INITIALIZER(struct cmd_set_result, set, "set");
2700 cmdline_parse_token_string_t cmd_set_what =
2701 	TOKEN_STRING_INITIALIZER(struct cmd_set_result, what,
2702 				 "nbport#nbcore#burst#verbose");
2703 cmdline_parse_token_num_t cmd_set_value =
2704 	TOKEN_NUM_INITIALIZER(struct cmd_set_result, value, UINT16);
2705 
2706 cmdline_parse_inst_t cmd_set_numbers = {
2707 	.f = cmd_set_parsed,
2708 	.data = NULL,
2709 	.help_str = "set nbport|nbcore|burst|verbose <value>",
2710 	.tokens = {
2711 		(void *)&cmd_set_set,
2712 		(void *)&cmd_set_what,
2713 		(void *)&cmd_set_value,
2714 		NULL,
2715 	},
2716 };
2717 
2718 /* *** SET SEGMENT LENGTHS OF TXONLY PACKETS *** */
2719 
2720 struct cmd_set_txpkts_result {
2721 	cmdline_fixed_string_t cmd_keyword;
2722 	cmdline_fixed_string_t txpkts;
2723 	cmdline_fixed_string_t seg_lengths;
2724 };
2725 
2726 static void
2727 cmd_set_txpkts_parsed(void *parsed_result,
2728 		      __attribute__((unused)) struct cmdline *cl,
2729 		      __attribute__((unused)) void *data)
2730 {
2731 	struct cmd_set_txpkts_result *res;
2732 	unsigned seg_lengths[RTE_MAX_SEGS_PER_PKT];
2733 	unsigned int nb_segs;
2734 
2735 	res = parsed_result;
2736 	nb_segs = parse_item_list(res->seg_lengths, "segment lengths",
2737 				  RTE_MAX_SEGS_PER_PKT, seg_lengths, 0);
2738 	if (nb_segs > 0)
2739 		set_tx_pkt_segments(seg_lengths, nb_segs);
2740 }
2741 
2742 cmdline_parse_token_string_t cmd_set_txpkts_keyword =
2743 	TOKEN_STRING_INITIALIZER(struct cmd_set_txpkts_result,
2744 				 cmd_keyword, "set");
2745 cmdline_parse_token_string_t cmd_set_txpkts_name =
2746 	TOKEN_STRING_INITIALIZER(struct cmd_set_txpkts_result,
2747 				 txpkts, "txpkts");
2748 cmdline_parse_token_string_t cmd_set_txpkts_lengths =
2749 	TOKEN_STRING_INITIALIZER(struct cmd_set_txpkts_result,
2750 				 seg_lengths, NULL);
2751 
2752 cmdline_parse_inst_t cmd_set_txpkts = {
2753 	.f = cmd_set_txpkts_parsed,
2754 	.data = NULL,
2755 	.help_str = "set txpkts <len0[,len1]*>",
2756 	.tokens = {
2757 		(void *)&cmd_set_txpkts_keyword,
2758 		(void *)&cmd_set_txpkts_name,
2759 		(void *)&cmd_set_txpkts_lengths,
2760 		NULL,
2761 	},
2762 };
2763 
2764 /* *** SET COPY AND SPLIT POLICY ON TX PACKETS *** */
2765 
2766 struct cmd_set_txsplit_result {
2767 	cmdline_fixed_string_t cmd_keyword;
2768 	cmdline_fixed_string_t txsplit;
2769 	cmdline_fixed_string_t mode;
2770 };
2771 
2772 static void
2773 cmd_set_txsplit_parsed(void *parsed_result,
2774 		      __attribute__((unused)) struct cmdline *cl,
2775 		      __attribute__((unused)) void *data)
2776 {
2777 	struct cmd_set_txsplit_result *res;
2778 
2779 	res = parsed_result;
2780 	set_tx_pkt_split(res->mode);
2781 }
2782 
2783 cmdline_parse_token_string_t cmd_set_txsplit_keyword =
2784 	TOKEN_STRING_INITIALIZER(struct cmd_set_txsplit_result,
2785 				 cmd_keyword, "set");
2786 cmdline_parse_token_string_t cmd_set_txsplit_name =
2787 	TOKEN_STRING_INITIALIZER(struct cmd_set_txsplit_result,
2788 				 txsplit, "txsplit");
2789 cmdline_parse_token_string_t cmd_set_txsplit_mode =
2790 	TOKEN_STRING_INITIALIZER(struct cmd_set_txsplit_result,
2791 				 mode, NULL);
2792 
2793 cmdline_parse_inst_t cmd_set_txsplit = {
2794 	.f = cmd_set_txsplit_parsed,
2795 	.data = NULL,
2796 	.help_str = "set txsplit on|off|rand",
2797 	.tokens = {
2798 		(void *)&cmd_set_txsplit_keyword,
2799 		(void *)&cmd_set_txsplit_name,
2800 		(void *)&cmd_set_txsplit_mode,
2801 		NULL,
2802 	},
2803 };
2804 
2805 /* *** CONFIG TX QUEUE FLAGS *** */
2806 
2807 struct cmd_config_txqflags_result {
2808 	cmdline_fixed_string_t port;
2809 	cmdline_fixed_string_t config;
2810 	cmdline_fixed_string_t all;
2811 	cmdline_fixed_string_t what;
2812 	int32_t hexvalue;
2813 };
2814 
2815 static void cmd_config_txqflags_parsed(void *parsed_result,
2816 				__attribute__((unused)) struct cmdline *cl,
2817 				__attribute__((unused)) void *data)
2818 {
2819 	struct cmd_config_txqflags_result *res = parsed_result;
2820 
2821 	if (!all_ports_stopped()) {
2822 		printf("Please stop all ports first\n");
2823 		return;
2824 	}
2825 
2826 	if (strcmp(res->what, "txqflags")) {
2827 		printf("Unknown parameter\n");
2828 		return;
2829 	}
2830 
2831 	if (res->hexvalue >= 0) {
2832 		txq_flags = res->hexvalue;
2833 	} else {
2834 		printf("txqflags must be >= 0\n");
2835 		return;
2836 	}
2837 
2838 	init_port_config();
2839 
2840 	cmd_reconfig_device_queue(RTE_PORT_ALL, 1, 1);
2841 }
2842 
2843 cmdline_parse_token_string_t cmd_config_txqflags_port =
2844 	TOKEN_STRING_INITIALIZER(struct cmd_config_txqflags_result, port,
2845 				 "port");
2846 cmdline_parse_token_string_t cmd_config_txqflags_config =
2847 	TOKEN_STRING_INITIALIZER(struct cmd_config_txqflags_result, config,
2848 				 "config");
2849 cmdline_parse_token_string_t cmd_config_txqflags_all =
2850 	TOKEN_STRING_INITIALIZER(struct cmd_config_txqflags_result, all,
2851 				 "all");
2852 cmdline_parse_token_string_t cmd_config_txqflags_what =
2853 	TOKEN_STRING_INITIALIZER(struct cmd_config_txqflags_result, what,
2854 				 "txqflags");
2855 cmdline_parse_token_num_t cmd_config_txqflags_value =
2856 	TOKEN_NUM_INITIALIZER(struct cmd_config_txqflags_result,
2857 				hexvalue, INT32);
2858 
2859 cmdline_parse_inst_t cmd_config_txqflags = {
2860 	.f = cmd_config_txqflags_parsed,
2861 	.data = NULL,
2862 	.help_str = "port config all txqflags <value>",
2863 	.tokens = {
2864 		(void *)&cmd_config_txqflags_port,
2865 		(void *)&cmd_config_txqflags_config,
2866 		(void *)&cmd_config_txqflags_all,
2867 		(void *)&cmd_config_txqflags_what,
2868 		(void *)&cmd_config_txqflags_value,
2869 		NULL,
2870 	},
2871 };
2872 
2873 /* *** ADD/REMOVE ALL VLAN IDENTIFIERS TO/FROM A PORT VLAN RX FILTER *** */
2874 struct cmd_rx_vlan_filter_all_result {
2875 	cmdline_fixed_string_t rx_vlan;
2876 	cmdline_fixed_string_t what;
2877 	cmdline_fixed_string_t all;
2878 	uint8_t port_id;
2879 };
2880 
2881 static void
2882 cmd_rx_vlan_filter_all_parsed(void *parsed_result,
2883 			      __attribute__((unused)) struct cmdline *cl,
2884 			      __attribute__((unused)) void *data)
2885 {
2886 	struct cmd_rx_vlan_filter_all_result *res = parsed_result;
2887 
2888 	if (!strcmp(res->what, "add"))
2889 		rx_vlan_all_filter_set(res->port_id, 1);
2890 	else
2891 		rx_vlan_all_filter_set(res->port_id, 0);
2892 }
2893 
2894 cmdline_parse_token_string_t cmd_rx_vlan_filter_all_rx_vlan =
2895 	TOKEN_STRING_INITIALIZER(struct cmd_rx_vlan_filter_all_result,
2896 				 rx_vlan, "rx_vlan");
2897 cmdline_parse_token_string_t cmd_rx_vlan_filter_all_what =
2898 	TOKEN_STRING_INITIALIZER(struct cmd_rx_vlan_filter_all_result,
2899 				 what, "add#rm");
2900 cmdline_parse_token_string_t cmd_rx_vlan_filter_all_all =
2901 	TOKEN_STRING_INITIALIZER(struct cmd_rx_vlan_filter_all_result,
2902 				 all, "all");
2903 cmdline_parse_token_num_t cmd_rx_vlan_filter_all_portid =
2904 	TOKEN_NUM_INITIALIZER(struct cmd_rx_vlan_filter_all_result,
2905 			      port_id, UINT8);
2906 
2907 cmdline_parse_inst_t cmd_rx_vlan_filter_all = {
2908 	.f = cmd_rx_vlan_filter_all_parsed,
2909 	.data = NULL,
2910 	.help_str = "rx_vlan add|rm all <port_id>: "
2911 		"Add/Remove all identifiers to/from the set of VLAN "
2912 		"identifiers filtered by a port",
2913 	.tokens = {
2914 		(void *)&cmd_rx_vlan_filter_all_rx_vlan,
2915 		(void *)&cmd_rx_vlan_filter_all_what,
2916 		(void *)&cmd_rx_vlan_filter_all_all,
2917 		(void *)&cmd_rx_vlan_filter_all_portid,
2918 		NULL,
2919 	},
2920 };
2921 
2922 /* *** VLAN OFFLOAD SET ON A PORT *** */
2923 struct cmd_vlan_offload_result {
2924 	cmdline_fixed_string_t vlan;
2925 	cmdline_fixed_string_t set;
2926 	cmdline_fixed_string_t vlan_type;
2927 	cmdline_fixed_string_t what;
2928 	cmdline_fixed_string_t on;
2929 	cmdline_fixed_string_t port_id;
2930 };
2931 
2932 static void
2933 cmd_vlan_offload_parsed(void *parsed_result,
2934 			  __attribute__((unused)) struct cmdline *cl,
2935 			  __attribute__((unused)) void *data)
2936 {
2937 	int on;
2938 	struct cmd_vlan_offload_result *res = parsed_result;
2939 	char *str;
2940 	int i, len = 0;
2941 	portid_t port_id = 0;
2942 	unsigned int tmp;
2943 
2944 	str = res->port_id;
2945 	len = strnlen(str, STR_TOKEN_SIZE);
2946 	i = 0;
2947 	/* Get port_id first */
2948 	while(i < len){
2949 		if(str[i] == ',')
2950 			break;
2951 
2952 		i++;
2953 	}
2954 	str[i]='\0';
2955 	tmp = strtoul(str, NULL, 0);
2956 	/* If port_id greater that what portid_t can represent, return */
2957 	if(tmp >= RTE_MAX_ETHPORTS)
2958 		return;
2959 	port_id = (portid_t)tmp;
2960 
2961 	if (!strcmp(res->on, "on"))
2962 		on = 1;
2963 	else
2964 		on = 0;
2965 
2966 	if (!strcmp(res->what, "strip"))
2967 		rx_vlan_strip_set(port_id,  on);
2968 	else if(!strcmp(res->what, "stripq")){
2969 		uint16_t queue_id = 0;
2970 
2971 		/* No queue_id, return */
2972 		if(i + 1 >= len) {
2973 			printf("must specify (port,queue_id)\n");
2974 			return;
2975 		}
2976 		tmp = strtoul(str + i + 1, NULL, 0);
2977 		/* If queue_id greater that what 16-bits can represent, return */
2978 		if(tmp > 0xffff)
2979 			return;
2980 
2981 		queue_id = (uint16_t)tmp;
2982 		rx_vlan_strip_set_on_queue(port_id, queue_id, on);
2983 	}
2984 	else if (!strcmp(res->what, "filter"))
2985 		rx_vlan_filter_set(port_id, on);
2986 	else
2987 		vlan_extend_set(port_id, on);
2988 
2989 	return;
2990 }
2991 
2992 cmdline_parse_token_string_t cmd_vlan_offload_vlan =
2993 	TOKEN_STRING_INITIALIZER(struct cmd_vlan_offload_result,
2994 				 vlan, "vlan");
2995 cmdline_parse_token_string_t cmd_vlan_offload_set =
2996 	TOKEN_STRING_INITIALIZER(struct cmd_vlan_offload_result,
2997 				 set, "set");
2998 cmdline_parse_token_string_t cmd_vlan_offload_what =
2999 	TOKEN_STRING_INITIALIZER(struct cmd_vlan_offload_result,
3000 				 what, "strip#filter#qinq#stripq");
3001 cmdline_parse_token_string_t cmd_vlan_offload_on =
3002 	TOKEN_STRING_INITIALIZER(struct cmd_vlan_offload_result,
3003 			      on, "on#off");
3004 cmdline_parse_token_string_t cmd_vlan_offload_portid =
3005 	TOKEN_STRING_INITIALIZER(struct cmd_vlan_offload_result,
3006 			      port_id, NULL);
3007 
3008 cmdline_parse_inst_t cmd_vlan_offload = {
3009 	.f = cmd_vlan_offload_parsed,
3010 	.data = NULL,
3011 	.help_str = "vlan set strip|filter|qinq|stripq on|off "
3012 		"<port_id[,queue_id]>: "
3013 		"Filter/Strip for rx side qinq(extended) for both rx/tx sides",
3014 	.tokens = {
3015 		(void *)&cmd_vlan_offload_vlan,
3016 		(void *)&cmd_vlan_offload_set,
3017 		(void *)&cmd_vlan_offload_what,
3018 		(void *)&cmd_vlan_offload_on,
3019 		(void *)&cmd_vlan_offload_portid,
3020 		NULL,
3021 	},
3022 };
3023 
3024 /* *** VLAN TPID SET ON A PORT *** */
3025 struct cmd_vlan_tpid_result {
3026 	cmdline_fixed_string_t vlan;
3027 	cmdline_fixed_string_t set;
3028 	cmdline_fixed_string_t vlan_type;
3029 	cmdline_fixed_string_t what;
3030 	uint16_t tp_id;
3031 	uint8_t port_id;
3032 };
3033 
3034 static void
3035 cmd_vlan_tpid_parsed(void *parsed_result,
3036 			  __attribute__((unused)) struct cmdline *cl,
3037 			  __attribute__((unused)) void *data)
3038 {
3039 	struct cmd_vlan_tpid_result *res = parsed_result;
3040 	enum rte_vlan_type vlan_type;
3041 
3042 	if (!strcmp(res->vlan_type, "inner"))
3043 		vlan_type = ETH_VLAN_TYPE_INNER;
3044 	else if (!strcmp(res->vlan_type, "outer"))
3045 		vlan_type = ETH_VLAN_TYPE_OUTER;
3046 	else {
3047 		printf("Unknown vlan type\n");
3048 		return;
3049 	}
3050 	vlan_tpid_set(res->port_id, vlan_type, res->tp_id);
3051 }
3052 
3053 cmdline_parse_token_string_t cmd_vlan_tpid_vlan =
3054 	TOKEN_STRING_INITIALIZER(struct cmd_vlan_tpid_result,
3055 				 vlan, "vlan");
3056 cmdline_parse_token_string_t cmd_vlan_tpid_set =
3057 	TOKEN_STRING_INITIALIZER(struct cmd_vlan_tpid_result,
3058 				 set, "set");
3059 cmdline_parse_token_string_t cmd_vlan_type =
3060 	TOKEN_STRING_INITIALIZER(struct cmd_vlan_tpid_result,
3061 				 vlan_type, "inner#outer");
3062 cmdline_parse_token_string_t cmd_vlan_tpid_what =
3063 	TOKEN_STRING_INITIALIZER(struct cmd_vlan_tpid_result,
3064 				 what, "tpid");
3065 cmdline_parse_token_num_t cmd_vlan_tpid_tpid =
3066 	TOKEN_NUM_INITIALIZER(struct cmd_vlan_tpid_result,
3067 			      tp_id, UINT16);
3068 cmdline_parse_token_num_t cmd_vlan_tpid_portid =
3069 	TOKEN_NUM_INITIALIZER(struct cmd_vlan_tpid_result,
3070 			      port_id, UINT8);
3071 
3072 cmdline_parse_inst_t cmd_vlan_tpid = {
3073 	.f = cmd_vlan_tpid_parsed,
3074 	.data = NULL,
3075 	.help_str = "vlan set inner|outer tpid <tp_id> <port_id>: "
3076 		"Set the VLAN Ether type",
3077 	.tokens = {
3078 		(void *)&cmd_vlan_tpid_vlan,
3079 		(void *)&cmd_vlan_tpid_set,
3080 		(void *)&cmd_vlan_type,
3081 		(void *)&cmd_vlan_tpid_what,
3082 		(void *)&cmd_vlan_tpid_tpid,
3083 		(void *)&cmd_vlan_tpid_portid,
3084 		NULL,
3085 	},
3086 };
3087 
3088 /* *** ADD/REMOVE A VLAN IDENTIFIER TO/FROM A PORT VLAN RX FILTER *** */
3089 struct cmd_rx_vlan_filter_result {
3090 	cmdline_fixed_string_t rx_vlan;
3091 	cmdline_fixed_string_t what;
3092 	uint16_t vlan_id;
3093 	uint8_t port_id;
3094 };
3095 
3096 static void
3097 cmd_rx_vlan_filter_parsed(void *parsed_result,
3098 			  __attribute__((unused)) struct cmdline *cl,
3099 			  __attribute__((unused)) void *data)
3100 {
3101 	struct cmd_rx_vlan_filter_result *res = parsed_result;
3102 
3103 	if (!strcmp(res->what, "add"))
3104 		rx_vft_set(res->port_id, res->vlan_id, 1);
3105 	else
3106 		rx_vft_set(res->port_id, res->vlan_id, 0);
3107 }
3108 
3109 cmdline_parse_token_string_t cmd_rx_vlan_filter_rx_vlan =
3110 	TOKEN_STRING_INITIALIZER(struct cmd_rx_vlan_filter_result,
3111 				 rx_vlan, "rx_vlan");
3112 cmdline_parse_token_string_t cmd_rx_vlan_filter_what =
3113 	TOKEN_STRING_INITIALIZER(struct cmd_rx_vlan_filter_result,
3114 				 what, "add#rm");
3115 cmdline_parse_token_num_t cmd_rx_vlan_filter_vlanid =
3116 	TOKEN_NUM_INITIALIZER(struct cmd_rx_vlan_filter_result,
3117 			      vlan_id, UINT16);
3118 cmdline_parse_token_num_t cmd_rx_vlan_filter_portid =
3119 	TOKEN_NUM_INITIALIZER(struct cmd_rx_vlan_filter_result,
3120 			      port_id, UINT8);
3121 
3122 cmdline_parse_inst_t cmd_rx_vlan_filter = {
3123 	.f = cmd_rx_vlan_filter_parsed,
3124 	.data = NULL,
3125 	.help_str = "rx_vlan add|rm <vlan_id> <port_id>: "
3126 		"Add/Remove a VLAN identifier to/from the set of VLAN "
3127 		"identifiers filtered by a port",
3128 	.tokens = {
3129 		(void *)&cmd_rx_vlan_filter_rx_vlan,
3130 		(void *)&cmd_rx_vlan_filter_what,
3131 		(void *)&cmd_rx_vlan_filter_vlanid,
3132 		(void *)&cmd_rx_vlan_filter_portid,
3133 		NULL,
3134 	},
3135 };
3136 
3137 /* *** ENABLE HARDWARE INSERTION OF VLAN HEADER IN TX PACKETS *** */
3138 struct cmd_tx_vlan_set_result {
3139 	cmdline_fixed_string_t tx_vlan;
3140 	cmdline_fixed_string_t set;
3141 	uint8_t port_id;
3142 	uint16_t vlan_id;
3143 };
3144 
3145 static void
3146 cmd_tx_vlan_set_parsed(void *parsed_result,
3147 		       __attribute__((unused)) struct cmdline *cl,
3148 		       __attribute__((unused)) void *data)
3149 {
3150 	struct cmd_tx_vlan_set_result *res = parsed_result;
3151 
3152 	tx_vlan_set(res->port_id, res->vlan_id);
3153 }
3154 
3155 cmdline_parse_token_string_t cmd_tx_vlan_set_tx_vlan =
3156 	TOKEN_STRING_INITIALIZER(struct cmd_tx_vlan_set_result,
3157 				 tx_vlan, "tx_vlan");
3158 cmdline_parse_token_string_t cmd_tx_vlan_set_set =
3159 	TOKEN_STRING_INITIALIZER(struct cmd_tx_vlan_set_result,
3160 				 set, "set");
3161 cmdline_parse_token_num_t cmd_tx_vlan_set_portid =
3162 	TOKEN_NUM_INITIALIZER(struct cmd_tx_vlan_set_result,
3163 			      port_id, UINT8);
3164 cmdline_parse_token_num_t cmd_tx_vlan_set_vlanid =
3165 	TOKEN_NUM_INITIALIZER(struct cmd_tx_vlan_set_result,
3166 			      vlan_id, UINT16);
3167 
3168 cmdline_parse_inst_t cmd_tx_vlan_set = {
3169 	.f = cmd_tx_vlan_set_parsed,
3170 	.data = NULL,
3171 	.help_str = "tx_vlan set <port_id> <vlan_id>: "
3172 		"Enable hardware insertion of a single VLAN header "
3173 		"with a given TAG Identifier in packets sent on a port",
3174 	.tokens = {
3175 		(void *)&cmd_tx_vlan_set_tx_vlan,
3176 		(void *)&cmd_tx_vlan_set_set,
3177 		(void *)&cmd_tx_vlan_set_portid,
3178 		(void *)&cmd_tx_vlan_set_vlanid,
3179 		NULL,
3180 	},
3181 };
3182 
3183 /* *** ENABLE HARDWARE INSERTION OF Double VLAN HEADER IN TX PACKETS *** */
3184 struct cmd_tx_vlan_set_qinq_result {
3185 	cmdline_fixed_string_t tx_vlan;
3186 	cmdline_fixed_string_t set;
3187 	uint8_t port_id;
3188 	uint16_t vlan_id;
3189 	uint16_t vlan_id_outer;
3190 };
3191 
3192 static void
3193 cmd_tx_vlan_set_qinq_parsed(void *parsed_result,
3194 			    __attribute__((unused)) struct cmdline *cl,
3195 			    __attribute__((unused)) void *data)
3196 {
3197 	struct cmd_tx_vlan_set_qinq_result *res = parsed_result;
3198 
3199 	tx_qinq_set(res->port_id, res->vlan_id, res->vlan_id_outer);
3200 }
3201 
3202 cmdline_parse_token_string_t cmd_tx_vlan_set_qinq_tx_vlan =
3203 	TOKEN_STRING_INITIALIZER(struct cmd_tx_vlan_set_qinq_result,
3204 		tx_vlan, "tx_vlan");
3205 cmdline_parse_token_string_t cmd_tx_vlan_set_qinq_set =
3206 	TOKEN_STRING_INITIALIZER(struct cmd_tx_vlan_set_qinq_result,
3207 		set, "set");
3208 cmdline_parse_token_num_t cmd_tx_vlan_set_qinq_portid =
3209 	TOKEN_NUM_INITIALIZER(struct cmd_tx_vlan_set_qinq_result,
3210 		port_id, UINT8);
3211 cmdline_parse_token_num_t cmd_tx_vlan_set_qinq_vlanid =
3212 	TOKEN_NUM_INITIALIZER(struct cmd_tx_vlan_set_qinq_result,
3213 		vlan_id, UINT16);
3214 cmdline_parse_token_num_t cmd_tx_vlan_set_qinq_vlanid_outer =
3215 	TOKEN_NUM_INITIALIZER(struct cmd_tx_vlan_set_qinq_result,
3216 		vlan_id_outer, UINT16);
3217 
3218 cmdline_parse_inst_t cmd_tx_vlan_set_qinq = {
3219 	.f = cmd_tx_vlan_set_qinq_parsed,
3220 	.data = NULL,
3221 	.help_str = "tx_vlan set <port_id> <vlan_id> <outer_vlan_id>: "
3222 		"Enable hardware insertion of double VLAN header "
3223 		"with given TAG Identifiers in packets sent on a port",
3224 	.tokens = {
3225 		(void *)&cmd_tx_vlan_set_qinq_tx_vlan,
3226 		(void *)&cmd_tx_vlan_set_qinq_set,
3227 		(void *)&cmd_tx_vlan_set_qinq_portid,
3228 		(void *)&cmd_tx_vlan_set_qinq_vlanid,
3229 		(void *)&cmd_tx_vlan_set_qinq_vlanid_outer,
3230 		NULL,
3231 	},
3232 };
3233 
3234 /* *** ENABLE/DISABLE PORT BASED TX VLAN INSERTION *** */
3235 struct cmd_tx_vlan_set_pvid_result {
3236 	cmdline_fixed_string_t tx_vlan;
3237 	cmdline_fixed_string_t set;
3238 	cmdline_fixed_string_t pvid;
3239 	uint8_t port_id;
3240 	uint16_t vlan_id;
3241 	cmdline_fixed_string_t mode;
3242 };
3243 
3244 static void
3245 cmd_tx_vlan_set_pvid_parsed(void *parsed_result,
3246 			    __attribute__((unused)) struct cmdline *cl,
3247 			    __attribute__((unused)) void *data)
3248 {
3249 	struct cmd_tx_vlan_set_pvid_result *res = parsed_result;
3250 
3251 	if (strcmp(res->mode, "on") == 0)
3252 		tx_vlan_pvid_set(res->port_id, res->vlan_id, 1);
3253 	else
3254 		tx_vlan_pvid_set(res->port_id, res->vlan_id, 0);
3255 }
3256 
3257 cmdline_parse_token_string_t cmd_tx_vlan_set_pvid_tx_vlan =
3258 	TOKEN_STRING_INITIALIZER(struct cmd_tx_vlan_set_pvid_result,
3259 				 tx_vlan, "tx_vlan");
3260 cmdline_parse_token_string_t cmd_tx_vlan_set_pvid_set =
3261 	TOKEN_STRING_INITIALIZER(struct cmd_tx_vlan_set_pvid_result,
3262 				 set, "set");
3263 cmdline_parse_token_string_t cmd_tx_vlan_set_pvid_pvid =
3264 	TOKEN_STRING_INITIALIZER(struct cmd_tx_vlan_set_pvid_result,
3265 				 pvid, "pvid");
3266 cmdline_parse_token_num_t cmd_tx_vlan_set_pvid_port_id =
3267 	TOKEN_NUM_INITIALIZER(struct cmd_tx_vlan_set_pvid_result,
3268 			     port_id, UINT8);
3269 cmdline_parse_token_num_t cmd_tx_vlan_set_pvid_vlan_id =
3270 	TOKEN_NUM_INITIALIZER(struct cmd_tx_vlan_set_pvid_result,
3271 			      vlan_id, UINT16);
3272 cmdline_parse_token_string_t cmd_tx_vlan_set_pvid_mode =
3273 	TOKEN_STRING_INITIALIZER(struct cmd_tx_vlan_set_pvid_result,
3274 				 mode, "on#off");
3275 
3276 cmdline_parse_inst_t cmd_tx_vlan_set_pvid = {
3277 	.f = cmd_tx_vlan_set_pvid_parsed,
3278 	.data = NULL,
3279 	.help_str = "tx_vlan set pvid <port_id> <vlan_id> on|off",
3280 	.tokens = {
3281 		(void *)&cmd_tx_vlan_set_pvid_tx_vlan,
3282 		(void *)&cmd_tx_vlan_set_pvid_set,
3283 		(void *)&cmd_tx_vlan_set_pvid_pvid,
3284 		(void *)&cmd_tx_vlan_set_pvid_port_id,
3285 		(void *)&cmd_tx_vlan_set_pvid_vlan_id,
3286 		(void *)&cmd_tx_vlan_set_pvid_mode,
3287 		NULL,
3288 	},
3289 };
3290 
3291 /* *** DISABLE HARDWARE INSERTION OF VLAN HEADER IN TX PACKETS *** */
3292 struct cmd_tx_vlan_reset_result {
3293 	cmdline_fixed_string_t tx_vlan;
3294 	cmdline_fixed_string_t reset;
3295 	uint8_t port_id;
3296 };
3297 
3298 static void
3299 cmd_tx_vlan_reset_parsed(void *parsed_result,
3300 			 __attribute__((unused)) struct cmdline *cl,
3301 			 __attribute__((unused)) void *data)
3302 {
3303 	struct cmd_tx_vlan_reset_result *res = parsed_result;
3304 
3305 	tx_vlan_reset(res->port_id);
3306 }
3307 
3308 cmdline_parse_token_string_t cmd_tx_vlan_reset_tx_vlan =
3309 	TOKEN_STRING_INITIALIZER(struct cmd_tx_vlan_reset_result,
3310 				 tx_vlan, "tx_vlan");
3311 cmdline_parse_token_string_t cmd_tx_vlan_reset_reset =
3312 	TOKEN_STRING_INITIALIZER(struct cmd_tx_vlan_reset_result,
3313 				 reset, "reset");
3314 cmdline_parse_token_num_t cmd_tx_vlan_reset_portid =
3315 	TOKEN_NUM_INITIALIZER(struct cmd_tx_vlan_reset_result,
3316 			      port_id, UINT8);
3317 
3318 cmdline_parse_inst_t cmd_tx_vlan_reset = {
3319 	.f = cmd_tx_vlan_reset_parsed,
3320 	.data = NULL,
3321 	.help_str = "tx_vlan reset <port_id>: Disable hardware insertion of a "
3322 		"VLAN header in packets sent on a port",
3323 	.tokens = {
3324 		(void *)&cmd_tx_vlan_reset_tx_vlan,
3325 		(void *)&cmd_tx_vlan_reset_reset,
3326 		(void *)&cmd_tx_vlan_reset_portid,
3327 		NULL,
3328 	},
3329 };
3330 
3331 
3332 /* *** ENABLE HARDWARE INSERTION OF CHECKSUM IN TX PACKETS *** */
3333 struct cmd_csum_result {
3334 	cmdline_fixed_string_t csum;
3335 	cmdline_fixed_string_t mode;
3336 	cmdline_fixed_string_t proto;
3337 	cmdline_fixed_string_t hwsw;
3338 	uint8_t port_id;
3339 };
3340 
3341 static void
3342 csum_show(int port_id)
3343 {
3344 	struct rte_eth_dev_info dev_info;
3345 	uint16_t ol_flags;
3346 
3347 	ol_flags = ports[port_id].tx_ol_flags;
3348 	printf("Parse tunnel is %s\n",
3349 		(ol_flags & TESTPMD_TX_OFFLOAD_PARSE_TUNNEL) ? "on" : "off");
3350 	printf("IP checksum offload is %s\n",
3351 		(ol_flags & TESTPMD_TX_OFFLOAD_IP_CKSUM) ? "hw" : "sw");
3352 	printf("UDP checksum offload is %s\n",
3353 		(ol_flags & TESTPMD_TX_OFFLOAD_UDP_CKSUM) ? "hw" : "sw");
3354 	printf("TCP checksum offload is %s\n",
3355 		(ol_flags & TESTPMD_TX_OFFLOAD_TCP_CKSUM) ? "hw" : "sw");
3356 	printf("SCTP checksum offload is %s\n",
3357 		(ol_flags & TESTPMD_TX_OFFLOAD_SCTP_CKSUM) ? "hw" : "sw");
3358 	printf("Outer-Ip checksum offload is %s\n",
3359 		(ol_flags & TESTPMD_TX_OFFLOAD_OUTER_IP_CKSUM) ? "hw" : "sw");
3360 
3361 	/* display warnings if configuration is not supported by the NIC */
3362 	rte_eth_dev_info_get(port_id, &dev_info);
3363 	if ((ol_flags & TESTPMD_TX_OFFLOAD_IP_CKSUM) &&
3364 		(dev_info.tx_offload_capa & DEV_TX_OFFLOAD_IPV4_CKSUM) == 0) {
3365 		printf("Warning: hardware IP checksum enabled but not "
3366 			"supported by port %d\n", port_id);
3367 	}
3368 	if ((ol_flags & TESTPMD_TX_OFFLOAD_UDP_CKSUM) &&
3369 		(dev_info.tx_offload_capa & DEV_TX_OFFLOAD_UDP_CKSUM) == 0) {
3370 		printf("Warning: hardware UDP checksum enabled but not "
3371 			"supported by port %d\n", port_id);
3372 	}
3373 	if ((ol_flags & TESTPMD_TX_OFFLOAD_TCP_CKSUM) &&
3374 		(dev_info.tx_offload_capa & DEV_TX_OFFLOAD_TCP_CKSUM) == 0) {
3375 		printf("Warning: hardware TCP checksum enabled but not "
3376 			"supported by port %d\n", port_id);
3377 	}
3378 	if ((ol_flags & TESTPMD_TX_OFFLOAD_SCTP_CKSUM) &&
3379 		(dev_info.tx_offload_capa & DEV_TX_OFFLOAD_SCTP_CKSUM) == 0) {
3380 		printf("Warning: hardware SCTP checksum enabled but not "
3381 			"supported by port %d\n", port_id);
3382 	}
3383 	if ((ol_flags & TESTPMD_TX_OFFLOAD_OUTER_IP_CKSUM) &&
3384 		(dev_info.tx_offload_capa & DEV_TX_OFFLOAD_OUTER_IPV4_CKSUM) == 0) {
3385 		printf("Warning: hardware outer IP checksum enabled but not "
3386 			"supported by port %d\n", port_id);
3387 	}
3388 }
3389 
3390 static void
3391 cmd_csum_parsed(void *parsed_result,
3392 		       __attribute__((unused)) struct cmdline *cl,
3393 		       __attribute__((unused)) void *data)
3394 {
3395 	struct cmd_csum_result *res = parsed_result;
3396 	int hw = 0;
3397 	uint16_t mask = 0;
3398 
3399 	if (port_id_is_invalid(res->port_id, ENABLED_WARN)) {
3400 		printf("invalid port %d\n", res->port_id);
3401 		return;
3402 	}
3403 
3404 	if (!strcmp(res->mode, "set")) {
3405 
3406 		if (!strcmp(res->hwsw, "hw"))
3407 			hw = 1;
3408 
3409 		if (!strcmp(res->proto, "ip")) {
3410 			mask = TESTPMD_TX_OFFLOAD_IP_CKSUM;
3411 		} else if (!strcmp(res->proto, "udp")) {
3412 			mask = TESTPMD_TX_OFFLOAD_UDP_CKSUM;
3413 		} else if (!strcmp(res->proto, "tcp")) {
3414 			mask = TESTPMD_TX_OFFLOAD_TCP_CKSUM;
3415 		} else if (!strcmp(res->proto, "sctp")) {
3416 			mask = TESTPMD_TX_OFFLOAD_SCTP_CKSUM;
3417 		} else if (!strcmp(res->proto, "outer-ip")) {
3418 			mask = TESTPMD_TX_OFFLOAD_OUTER_IP_CKSUM;
3419 		}
3420 
3421 		if (hw)
3422 			ports[res->port_id].tx_ol_flags |= mask;
3423 		else
3424 			ports[res->port_id].tx_ol_flags &= (~mask);
3425 	}
3426 	csum_show(res->port_id);
3427 }
3428 
3429 cmdline_parse_token_string_t cmd_csum_csum =
3430 	TOKEN_STRING_INITIALIZER(struct cmd_csum_result,
3431 				csum, "csum");
3432 cmdline_parse_token_string_t cmd_csum_mode =
3433 	TOKEN_STRING_INITIALIZER(struct cmd_csum_result,
3434 				mode, "set");
3435 cmdline_parse_token_string_t cmd_csum_proto =
3436 	TOKEN_STRING_INITIALIZER(struct cmd_csum_result,
3437 				proto, "ip#tcp#udp#sctp#outer-ip");
3438 cmdline_parse_token_string_t cmd_csum_hwsw =
3439 	TOKEN_STRING_INITIALIZER(struct cmd_csum_result,
3440 				hwsw, "hw#sw");
3441 cmdline_parse_token_num_t cmd_csum_portid =
3442 	TOKEN_NUM_INITIALIZER(struct cmd_csum_result,
3443 				port_id, UINT8);
3444 
3445 cmdline_parse_inst_t cmd_csum_set = {
3446 	.f = cmd_csum_parsed,
3447 	.data = NULL,
3448 	.help_str = "csum set ip|tcp|udp|sctp|outer-ip hw|sw <port_id>: "
3449 		"Enable/Disable hardware calculation of L3/L4 checksum when "
3450 		"using csum forward engine",
3451 	.tokens = {
3452 		(void *)&cmd_csum_csum,
3453 		(void *)&cmd_csum_mode,
3454 		(void *)&cmd_csum_proto,
3455 		(void *)&cmd_csum_hwsw,
3456 		(void *)&cmd_csum_portid,
3457 		NULL,
3458 	},
3459 };
3460 
3461 cmdline_parse_token_string_t cmd_csum_mode_show =
3462 	TOKEN_STRING_INITIALIZER(struct cmd_csum_result,
3463 				mode, "show");
3464 
3465 cmdline_parse_inst_t cmd_csum_show = {
3466 	.f = cmd_csum_parsed,
3467 	.data = NULL,
3468 	.help_str = "csum show <port_id>: Show checksum offload configuration",
3469 	.tokens = {
3470 		(void *)&cmd_csum_csum,
3471 		(void *)&cmd_csum_mode_show,
3472 		(void *)&cmd_csum_portid,
3473 		NULL,
3474 	},
3475 };
3476 
3477 /* Enable/disable tunnel parsing */
3478 struct cmd_csum_tunnel_result {
3479 	cmdline_fixed_string_t csum;
3480 	cmdline_fixed_string_t parse;
3481 	cmdline_fixed_string_t onoff;
3482 	uint8_t port_id;
3483 };
3484 
3485 static void
3486 cmd_csum_tunnel_parsed(void *parsed_result,
3487 		       __attribute__((unused)) struct cmdline *cl,
3488 		       __attribute__((unused)) void *data)
3489 {
3490 	struct cmd_csum_tunnel_result *res = parsed_result;
3491 
3492 	if (port_id_is_invalid(res->port_id, ENABLED_WARN))
3493 		return;
3494 
3495 	if (!strcmp(res->onoff, "on"))
3496 		ports[res->port_id].tx_ol_flags |=
3497 			TESTPMD_TX_OFFLOAD_PARSE_TUNNEL;
3498 	else
3499 		ports[res->port_id].tx_ol_flags &=
3500 			(~TESTPMD_TX_OFFLOAD_PARSE_TUNNEL);
3501 
3502 	csum_show(res->port_id);
3503 }
3504 
3505 cmdline_parse_token_string_t cmd_csum_tunnel_csum =
3506 	TOKEN_STRING_INITIALIZER(struct cmd_csum_tunnel_result,
3507 				csum, "csum");
3508 cmdline_parse_token_string_t cmd_csum_tunnel_parse =
3509 	TOKEN_STRING_INITIALIZER(struct cmd_csum_tunnel_result,
3510 				parse, "parse_tunnel");
3511 cmdline_parse_token_string_t cmd_csum_tunnel_onoff =
3512 	TOKEN_STRING_INITIALIZER(struct cmd_csum_tunnel_result,
3513 				onoff, "on#off");
3514 cmdline_parse_token_num_t cmd_csum_tunnel_portid =
3515 	TOKEN_NUM_INITIALIZER(struct cmd_csum_tunnel_result,
3516 				port_id, UINT8);
3517 
3518 cmdline_parse_inst_t cmd_csum_tunnel = {
3519 	.f = cmd_csum_tunnel_parsed,
3520 	.data = NULL,
3521 	.help_str = "csum parse_tunnel on|off <port_id>: "
3522 		"Enable/Disable parsing of tunnels for csum engine",
3523 	.tokens = {
3524 		(void *)&cmd_csum_tunnel_csum,
3525 		(void *)&cmd_csum_tunnel_parse,
3526 		(void *)&cmd_csum_tunnel_onoff,
3527 		(void *)&cmd_csum_tunnel_portid,
3528 		NULL,
3529 	},
3530 };
3531 
3532 /* *** ENABLE HARDWARE SEGMENTATION IN TX NON-TUNNELED PACKETS *** */
3533 struct cmd_tso_set_result {
3534 	cmdline_fixed_string_t tso;
3535 	cmdline_fixed_string_t mode;
3536 	uint16_t tso_segsz;
3537 	uint8_t port_id;
3538 };
3539 
3540 static void
3541 cmd_tso_set_parsed(void *parsed_result,
3542 		       __attribute__((unused)) struct cmdline *cl,
3543 		       __attribute__((unused)) void *data)
3544 {
3545 	struct cmd_tso_set_result *res = parsed_result;
3546 	struct rte_eth_dev_info dev_info;
3547 
3548 	if (port_id_is_invalid(res->port_id, ENABLED_WARN))
3549 		return;
3550 
3551 	if (!strcmp(res->mode, "set"))
3552 		ports[res->port_id].tso_segsz = res->tso_segsz;
3553 
3554 	if (ports[res->port_id].tso_segsz == 0)
3555 		printf("TSO for non-tunneled packets is disabled\n");
3556 	else
3557 		printf("TSO segment size for non-tunneled packets is %d\n",
3558 			ports[res->port_id].tso_segsz);
3559 
3560 	/* display warnings if configuration is not supported by the NIC */
3561 	rte_eth_dev_info_get(res->port_id, &dev_info);
3562 	if ((ports[res->port_id].tso_segsz != 0) &&
3563 		(dev_info.tx_offload_capa & DEV_TX_OFFLOAD_TCP_TSO) == 0) {
3564 		printf("Warning: TSO enabled but not "
3565 			"supported by port %d\n", res->port_id);
3566 	}
3567 }
3568 
3569 cmdline_parse_token_string_t cmd_tso_set_tso =
3570 	TOKEN_STRING_INITIALIZER(struct cmd_tso_set_result,
3571 				tso, "tso");
3572 cmdline_parse_token_string_t cmd_tso_set_mode =
3573 	TOKEN_STRING_INITIALIZER(struct cmd_tso_set_result,
3574 				mode, "set");
3575 cmdline_parse_token_num_t cmd_tso_set_tso_segsz =
3576 	TOKEN_NUM_INITIALIZER(struct cmd_tso_set_result,
3577 				tso_segsz, UINT16);
3578 cmdline_parse_token_num_t cmd_tso_set_portid =
3579 	TOKEN_NUM_INITIALIZER(struct cmd_tso_set_result,
3580 				port_id, UINT8);
3581 
3582 cmdline_parse_inst_t cmd_tso_set = {
3583 	.f = cmd_tso_set_parsed,
3584 	.data = NULL,
3585 	.help_str = "tso set <tso_segsz> <port_id>: "
3586 		"Set TSO segment size of non-tunneled packets for csum engine "
3587 		"(0 to disable)",
3588 	.tokens = {
3589 		(void *)&cmd_tso_set_tso,
3590 		(void *)&cmd_tso_set_mode,
3591 		(void *)&cmd_tso_set_tso_segsz,
3592 		(void *)&cmd_tso_set_portid,
3593 		NULL,
3594 	},
3595 };
3596 
3597 cmdline_parse_token_string_t cmd_tso_show_mode =
3598 	TOKEN_STRING_INITIALIZER(struct cmd_tso_set_result,
3599 				mode, "show");
3600 
3601 
3602 cmdline_parse_inst_t cmd_tso_show = {
3603 	.f = cmd_tso_set_parsed,
3604 	.data = NULL,
3605 	.help_str = "tso show <port_id>: "
3606 		"Show TSO segment size of non-tunneled packets for csum engine",
3607 	.tokens = {
3608 		(void *)&cmd_tso_set_tso,
3609 		(void *)&cmd_tso_show_mode,
3610 		(void *)&cmd_tso_set_portid,
3611 		NULL,
3612 	},
3613 };
3614 
3615 /* *** ENABLE HARDWARE SEGMENTATION IN TX TUNNELED PACKETS *** */
3616 struct cmd_tunnel_tso_set_result {
3617 	cmdline_fixed_string_t tso;
3618 	cmdline_fixed_string_t mode;
3619 	uint16_t tso_segsz;
3620 	uint8_t port_id;
3621 };
3622 
3623 static void
3624 check_tunnel_tso_nic_support(uint8_t port_id)
3625 {
3626 	struct rte_eth_dev_info dev_info;
3627 
3628 	rte_eth_dev_info_get(port_id, &dev_info);
3629 	if (!(dev_info.tx_offload_capa & DEV_TX_OFFLOAD_VXLAN_TNL_TSO))
3630 		printf("Warning: TSO enabled but VXLAN TUNNEL TSO not "
3631 		       "supported by port %d\n", port_id);
3632 	if (!(dev_info.tx_offload_capa & DEV_TX_OFFLOAD_GRE_TNL_TSO))
3633 		printf("Warning: TSO enabled but GRE TUNNEL TSO not "
3634 			"supported by port %d\n", port_id);
3635 	if (!(dev_info.tx_offload_capa & DEV_TX_OFFLOAD_IPIP_TNL_TSO))
3636 		printf("Warning: TSO enabled but IPIP TUNNEL TSO not "
3637 		       "supported by port %d\n", port_id);
3638 	if (!(dev_info.tx_offload_capa & DEV_TX_OFFLOAD_GENEVE_TNL_TSO))
3639 		printf("Warning: TSO enabled but GENEVE TUNNEL TSO not "
3640 		       "supported by port %d\n", port_id);
3641 }
3642 
3643 static void
3644 cmd_tunnel_tso_set_parsed(void *parsed_result,
3645 			  __attribute__((unused)) struct cmdline *cl,
3646 			  __attribute__((unused)) void *data)
3647 {
3648 	struct cmd_tunnel_tso_set_result *res = parsed_result;
3649 
3650 	if (port_id_is_invalid(res->port_id, ENABLED_WARN))
3651 		return;
3652 
3653 	if (!strcmp(res->mode, "set"))
3654 		ports[res->port_id].tunnel_tso_segsz = res->tso_segsz;
3655 
3656 	if (ports[res->port_id].tunnel_tso_segsz == 0)
3657 		printf("TSO for tunneled packets is disabled\n");
3658 	else {
3659 		printf("TSO segment size for tunneled packets is %d\n",
3660 			ports[res->port_id].tunnel_tso_segsz);
3661 
3662 		/* Below conditions are needed to make it work:
3663 		 * (1) tunnel TSO is supported by the NIC;
3664 		 * (2) "csum parse_tunnel" must be set so that tunneled pkts
3665 		 * are recognized;
3666 		 * (3) for tunneled pkts with outer L3 of IPv4,
3667 		 * "csum set outer-ip" must be set to hw, because after tso,
3668 		 * total_len of outer IP header is changed, and the checksum
3669 		 * of outer IP header calculated by sw should be wrong; that
3670 		 * is not necessary for IPv6 tunneled pkts because there's no
3671 		 * checksum in IP header anymore.
3672 		 */
3673 		check_tunnel_tso_nic_support(res->port_id);
3674 
3675 		if (!(ports[res->port_id].tx_ol_flags &
3676 		      TESTPMD_TX_OFFLOAD_PARSE_TUNNEL))
3677 			printf("Warning: csum parse_tunnel must be set "
3678 				"so that tunneled packets are recognized\n");
3679 		if (!(ports[res->port_id].tx_ol_flags &
3680 		      TESTPMD_TX_OFFLOAD_OUTER_IP_CKSUM))
3681 			printf("Warning: csum set outer-ip must be set to hw "
3682 				"if outer L3 is IPv4; not necessary for IPv6\n");
3683 	}
3684 }
3685 
3686 cmdline_parse_token_string_t cmd_tunnel_tso_set_tso =
3687 	TOKEN_STRING_INITIALIZER(struct cmd_tunnel_tso_set_result,
3688 				tso, "tunnel_tso");
3689 cmdline_parse_token_string_t cmd_tunnel_tso_set_mode =
3690 	TOKEN_STRING_INITIALIZER(struct cmd_tunnel_tso_set_result,
3691 				mode, "set");
3692 cmdline_parse_token_num_t cmd_tunnel_tso_set_tso_segsz =
3693 	TOKEN_NUM_INITIALIZER(struct cmd_tunnel_tso_set_result,
3694 				tso_segsz, UINT16);
3695 cmdline_parse_token_num_t cmd_tunnel_tso_set_portid =
3696 	TOKEN_NUM_INITIALIZER(struct cmd_tunnel_tso_set_result,
3697 				port_id, UINT8);
3698 
3699 cmdline_parse_inst_t cmd_tunnel_tso_set = {
3700 	.f = cmd_tunnel_tso_set_parsed,
3701 	.data = NULL,
3702 	.help_str = "tunnel_tso set <tso_segsz> <port_id>: "
3703 		"Set TSO segment size of tunneled packets for csum engine "
3704 		"(0 to disable)",
3705 	.tokens = {
3706 		(void *)&cmd_tunnel_tso_set_tso,
3707 		(void *)&cmd_tunnel_tso_set_mode,
3708 		(void *)&cmd_tunnel_tso_set_tso_segsz,
3709 		(void *)&cmd_tunnel_tso_set_portid,
3710 		NULL,
3711 	},
3712 };
3713 
3714 cmdline_parse_token_string_t cmd_tunnel_tso_show_mode =
3715 	TOKEN_STRING_INITIALIZER(struct cmd_tunnel_tso_set_result,
3716 				mode, "show");
3717 
3718 
3719 cmdline_parse_inst_t cmd_tunnel_tso_show = {
3720 	.f = cmd_tunnel_tso_set_parsed,
3721 	.data = NULL,
3722 	.help_str = "tunnel_tso show <port_id> "
3723 		"Show TSO segment size of tunneled packets for csum engine",
3724 	.tokens = {
3725 		(void *)&cmd_tunnel_tso_set_tso,
3726 		(void *)&cmd_tunnel_tso_show_mode,
3727 		(void *)&cmd_tunnel_tso_set_portid,
3728 		NULL,
3729 	},
3730 };
3731 
3732 /* *** ENABLE/DISABLE FLUSH ON RX STREAMS *** */
3733 struct cmd_set_flush_rx {
3734 	cmdline_fixed_string_t set;
3735 	cmdline_fixed_string_t flush_rx;
3736 	cmdline_fixed_string_t mode;
3737 };
3738 
3739 static void
3740 cmd_set_flush_rx_parsed(void *parsed_result,
3741 		__attribute__((unused)) struct cmdline *cl,
3742 		__attribute__((unused)) void *data)
3743 {
3744 	struct cmd_set_flush_rx *res = parsed_result;
3745 	no_flush_rx = (uint8_t)((strcmp(res->mode, "on") == 0) ? 0 : 1);
3746 }
3747 
3748 cmdline_parse_token_string_t cmd_setflushrx_set =
3749 	TOKEN_STRING_INITIALIZER(struct cmd_set_flush_rx,
3750 			set, "set");
3751 cmdline_parse_token_string_t cmd_setflushrx_flush_rx =
3752 	TOKEN_STRING_INITIALIZER(struct cmd_set_flush_rx,
3753 			flush_rx, "flush_rx");
3754 cmdline_parse_token_string_t cmd_setflushrx_mode =
3755 	TOKEN_STRING_INITIALIZER(struct cmd_set_flush_rx,
3756 			mode, "on#off");
3757 
3758 
3759 cmdline_parse_inst_t cmd_set_flush_rx = {
3760 	.f = cmd_set_flush_rx_parsed,
3761 	.help_str = "set flush_rx on|off: Enable/Disable flush on rx streams",
3762 	.data = NULL,
3763 	.tokens = {
3764 		(void *)&cmd_setflushrx_set,
3765 		(void *)&cmd_setflushrx_flush_rx,
3766 		(void *)&cmd_setflushrx_mode,
3767 		NULL,
3768 	},
3769 };
3770 
3771 /* *** ENABLE/DISABLE LINK STATUS CHECK *** */
3772 struct cmd_set_link_check {
3773 	cmdline_fixed_string_t set;
3774 	cmdline_fixed_string_t link_check;
3775 	cmdline_fixed_string_t mode;
3776 };
3777 
3778 static void
3779 cmd_set_link_check_parsed(void *parsed_result,
3780 		__attribute__((unused)) struct cmdline *cl,
3781 		__attribute__((unused)) void *data)
3782 {
3783 	struct cmd_set_link_check *res = parsed_result;
3784 	no_link_check = (uint8_t)((strcmp(res->mode, "on") == 0) ? 0 : 1);
3785 }
3786 
3787 cmdline_parse_token_string_t cmd_setlinkcheck_set =
3788 	TOKEN_STRING_INITIALIZER(struct cmd_set_link_check,
3789 			set, "set");
3790 cmdline_parse_token_string_t cmd_setlinkcheck_link_check =
3791 	TOKEN_STRING_INITIALIZER(struct cmd_set_link_check,
3792 			link_check, "link_check");
3793 cmdline_parse_token_string_t cmd_setlinkcheck_mode =
3794 	TOKEN_STRING_INITIALIZER(struct cmd_set_link_check,
3795 			mode, "on#off");
3796 
3797 
3798 cmdline_parse_inst_t cmd_set_link_check = {
3799 	.f = cmd_set_link_check_parsed,
3800 	.help_str = "set link_check on|off: Enable/Disable link status check "
3801 	            "when starting/stopping a port",
3802 	.data = NULL,
3803 	.tokens = {
3804 		(void *)&cmd_setlinkcheck_set,
3805 		(void *)&cmd_setlinkcheck_link_check,
3806 		(void *)&cmd_setlinkcheck_mode,
3807 		NULL,
3808 	},
3809 };
3810 
3811 #ifdef RTE_NIC_BYPASS
3812 /* *** SET NIC BYPASS MODE *** */
3813 struct cmd_set_bypass_mode_result {
3814 	cmdline_fixed_string_t set;
3815 	cmdline_fixed_string_t bypass;
3816 	cmdline_fixed_string_t mode;
3817 	cmdline_fixed_string_t value;
3818 	uint8_t port_id;
3819 };
3820 
3821 static void
3822 cmd_set_bypass_mode_parsed(void *parsed_result,
3823 		__attribute__((unused)) struct cmdline *cl,
3824 		__attribute__((unused)) void *data)
3825 {
3826 	struct cmd_set_bypass_mode_result *res = parsed_result;
3827 	portid_t port_id = res->port_id;
3828 	uint32_t bypass_mode = RTE_BYPASS_MODE_NORMAL;
3829 
3830 	if (!strcmp(res->value, "bypass"))
3831 		bypass_mode = RTE_BYPASS_MODE_BYPASS;
3832 	else if (!strcmp(res->value, "isolate"))
3833 		bypass_mode = RTE_BYPASS_MODE_ISOLATE;
3834 	else
3835 		bypass_mode = RTE_BYPASS_MODE_NORMAL;
3836 
3837 	/* Set the bypass mode for the relevant port. */
3838 	if (0 != rte_eth_dev_bypass_state_set(port_id, &bypass_mode)) {
3839 		printf("\t Failed to set bypass mode for port = %d.\n", port_id);
3840 	}
3841 }
3842 
3843 cmdline_parse_token_string_t cmd_setbypass_mode_set =
3844 	TOKEN_STRING_INITIALIZER(struct cmd_set_bypass_mode_result,
3845 			set, "set");
3846 cmdline_parse_token_string_t cmd_setbypass_mode_bypass =
3847 	TOKEN_STRING_INITIALIZER(struct cmd_set_bypass_mode_result,
3848 			bypass, "bypass");
3849 cmdline_parse_token_string_t cmd_setbypass_mode_mode =
3850 	TOKEN_STRING_INITIALIZER(struct cmd_set_bypass_mode_result,
3851 			mode, "mode");
3852 cmdline_parse_token_string_t cmd_setbypass_mode_value =
3853 	TOKEN_STRING_INITIALIZER(struct cmd_set_bypass_mode_result,
3854 			value, "normal#bypass#isolate");
3855 cmdline_parse_token_num_t cmd_setbypass_mode_port =
3856 	TOKEN_NUM_INITIALIZER(struct cmd_set_bypass_mode_result,
3857 				port_id, UINT8);
3858 
3859 cmdline_parse_inst_t cmd_set_bypass_mode = {
3860 	.f = cmd_set_bypass_mode_parsed,
3861 	.help_str = "set bypass mode normal|bypass|isolate <port_id>: "
3862 	            "Set the NIC bypass mode for port_id",
3863 	.data = NULL,
3864 	.tokens = {
3865 		(void *)&cmd_setbypass_mode_set,
3866 		(void *)&cmd_setbypass_mode_bypass,
3867 		(void *)&cmd_setbypass_mode_mode,
3868 		(void *)&cmd_setbypass_mode_value,
3869 		(void *)&cmd_setbypass_mode_port,
3870 		NULL,
3871 	},
3872 };
3873 
3874 /* *** SET NIC BYPASS EVENT *** */
3875 struct cmd_set_bypass_event_result {
3876 	cmdline_fixed_string_t set;
3877 	cmdline_fixed_string_t bypass;
3878 	cmdline_fixed_string_t event;
3879 	cmdline_fixed_string_t event_value;
3880 	cmdline_fixed_string_t mode;
3881 	cmdline_fixed_string_t mode_value;
3882 	uint8_t port_id;
3883 };
3884 
3885 static void
3886 cmd_set_bypass_event_parsed(void *parsed_result,
3887 		__attribute__((unused)) struct cmdline *cl,
3888 		__attribute__((unused)) void *data)
3889 {
3890 	int32_t rc;
3891 	struct cmd_set_bypass_event_result *res = parsed_result;
3892 	portid_t port_id = res->port_id;
3893 	uint32_t bypass_event = RTE_BYPASS_EVENT_NONE;
3894 	uint32_t bypass_mode = RTE_BYPASS_MODE_NORMAL;
3895 
3896 	if (!strcmp(res->event_value, "timeout"))
3897 		bypass_event = RTE_BYPASS_EVENT_TIMEOUT;
3898 	else if (!strcmp(res->event_value, "os_on"))
3899 		bypass_event = RTE_BYPASS_EVENT_OS_ON;
3900 	else if (!strcmp(res->event_value, "os_off"))
3901 		bypass_event = RTE_BYPASS_EVENT_OS_OFF;
3902 	else if (!strcmp(res->event_value, "power_on"))
3903 		bypass_event = RTE_BYPASS_EVENT_POWER_ON;
3904 	else if (!strcmp(res->event_value, "power_off"))
3905 		bypass_event = RTE_BYPASS_EVENT_POWER_OFF;
3906 	else
3907 		bypass_event = RTE_BYPASS_EVENT_NONE;
3908 
3909 	if (!strcmp(res->mode_value, "bypass"))
3910 		bypass_mode = RTE_BYPASS_MODE_BYPASS;
3911 	else if (!strcmp(res->mode_value, "isolate"))
3912 		bypass_mode = RTE_BYPASS_MODE_ISOLATE;
3913 	else
3914 		bypass_mode = RTE_BYPASS_MODE_NORMAL;
3915 
3916 	/* Set the watchdog timeout. */
3917 	if (bypass_event == RTE_BYPASS_EVENT_TIMEOUT) {
3918 
3919 		rc = -EINVAL;
3920 		if (!RTE_BYPASS_TMT_VALID(bypass_timeout) ||
3921 				(rc = rte_eth_dev_wd_timeout_store(port_id,
3922 				bypass_timeout)) != 0) {
3923 			printf("Failed to set timeout value %u "
3924 				"for port %d, errto code: %d.\n",
3925 				bypass_timeout, port_id, rc);
3926 		}
3927 	}
3928 
3929 	/* Set the bypass event to transition to bypass mode. */
3930 	if (0 != rte_eth_dev_bypass_event_store(port_id,
3931 			bypass_event, bypass_mode)) {
3932 		printf("\t Failed to set bypass event for port = %d.\n", port_id);
3933 	}
3934 
3935 }
3936 
3937 cmdline_parse_token_string_t cmd_setbypass_event_set =
3938 	TOKEN_STRING_INITIALIZER(struct cmd_set_bypass_event_result,
3939 			set, "set");
3940 cmdline_parse_token_string_t cmd_setbypass_event_bypass =
3941 	TOKEN_STRING_INITIALIZER(struct cmd_set_bypass_event_result,
3942 			bypass, "bypass");
3943 cmdline_parse_token_string_t cmd_setbypass_event_event =
3944 	TOKEN_STRING_INITIALIZER(struct cmd_set_bypass_event_result,
3945 			event, "event");
3946 cmdline_parse_token_string_t cmd_setbypass_event_event_value =
3947 	TOKEN_STRING_INITIALIZER(struct cmd_set_bypass_event_result,
3948 			event_value, "none#timeout#os_off#os_on#power_on#power_off");
3949 cmdline_parse_token_string_t cmd_setbypass_event_mode =
3950 	TOKEN_STRING_INITIALIZER(struct cmd_set_bypass_event_result,
3951 			mode, "mode");
3952 cmdline_parse_token_string_t cmd_setbypass_event_mode_value =
3953 	TOKEN_STRING_INITIALIZER(struct cmd_set_bypass_event_result,
3954 			mode_value, "normal#bypass#isolate");
3955 cmdline_parse_token_num_t cmd_setbypass_event_port =
3956 	TOKEN_NUM_INITIALIZER(struct cmd_set_bypass_event_result,
3957 				port_id, UINT8);
3958 
3959 cmdline_parse_inst_t cmd_set_bypass_event = {
3960 	.f = cmd_set_bypass_event_parsed,
3961 	.help_str = "set bypass event none|timeout|os_on|os_off|power_on|"
3962 		"power_off mode normal|bypass|isolate <port_id>: "
3963 		"Set the NIC bypass event mode for port_id",
3964 	.data = NULL,
3965 	.tokens = {
3966 		(void *)&cmd_setbypass_event_set,
3967 		(void *)&cmd_setbypass_event_bypass,
3968 		(void *)&cmd_setbypass_event_event,
3969 		(void *)&cmd_setbypass_event_event_value,
3970 		(void *)&cmd_setbypass_event_mode,
3971 		(void *)&cmd_setbypass_event_mode_value,
3972 		(void *)&cmd_setbypass_event_port,
3973 		NULL,
3974 	},
3975 };
3976 
3977 
3978 /* *** SET NIC BYPASS TIMEOUT *** */
3979 struct cmd_set_bypass_timeout_result {
3980 	cmdline_fixed_string_t set;
3981 	cmdline_fixed_string_t bypass;
3982 	cmdline_fixed_string_t timeout;
3983 	cmdline_fixed_string_t value;
3984 };
3985 
3986 static void
3987 cmd_set_bypass_timeout_parsed(void *parsed_result,
3988 		__attribute__((unused)) struct cmdline *cl,
3989 		__attribute__((unused)) void *data)
3990 {
3991 	struct cmd_set_bypass_timeout_result *res = parsed_result;
3992 
3993 	if (!strcmp(res->value, "1.5"))
3994 		bypass_timeout = RTE_BYPASS_TMT_1_5_SEC;
3995 	else if (!strcmp(res->value, "2"))
3996 		bypass_timeout = RTE_BYPASS_TMT_2_SEC;
3997 	else if (!strcmp(res->value, "3"))
3998 		bypass_timeout = RTE_BYPASS_TMT_3_SEC;
3999 	else if (!strcmp(res->value, "4"))
4000 		bypass_timeout = RTE_BYPASS_TMT_4_SEC;
4001 	else if (!strcmp(res->value, "8"))
4002 		bypass_timeout = RTE_BYPASS_TMT_8_SEC;
4003 	else if (!strcmp(res->value, "16"))
4004 		bypass_timeout = RTE_BYPASS_TMT_16_SEC;
4005 	else if (!strcmp(res->value, "32"))
4006 		bypass_timeout = RTE_BYPASS_TMT_32_SEC;
4007 	else
4008 		bypass_timeout = RTE_BYPASS_TMT_OFF;
4009 }
4010 
4011 cmdline_parse_token_string_t cmd_setbypass_timeout_set =
4012 	TOKEN_STRING_INITIALIZER(struct cmd_set_bypass_timeout_result,
4013 			set, "set");
4014 cmdline_parse_token_string_t cmd_setbypass_timeout_bypass =
4015 	TOKEN_STRING_INITIALIZER(struct cmd_set_bypass_timeout_result,
4016 			bypass, "bypass");
4017 cmdline_parse_token_string_t cmd_setbypass_timeout_timeout =
4018 	TOKEN_STRING_INITIALIZER(struct cmd_set_bypass_timeout_result,
4019 			timeout, "timeout");
4020 cmdline_parse_token_string_t cmd_setbypass_timeout_value =
4021 	TOKEN_STRING_INITIALIZER(struct cmd_set_bypass_timeout_result,
4022 			value, "0#1.5#2#3#4#8#16#32");
4023 
4024 cmdline_parse_inst_t cmd_set_bypass_timeout = {
4025 	.f = cmd_set_bypass_timeout_parsed,
4026 	.help_str = "set bypass timeout 0|1.5|2|3|4|8|16|32: "
4027 		"Set the NIC bypass watchdog timeout in seconds",
4028 	.data = NULL,
4029 	.tokens = {
4030 		(void *)&cmd_setbypass_timeout_set,
4031 		(void *)&cmd_setbypass_timeout_bypass,
4032 		(void *)&cmd_setbypass_timeout_timeout,
4033 		(void *)&cmd_setbypass_timeout_value,
4034 		NULL,
4035 	},
4036 };
4037 
4038 /* *** SHOW NIC BYPASS MODE *** */
4039 struct cmd_show_bypass_config_result {
4040 	cmdline_fixed_string_t show;
4041 	cmdline_fixed_string_t bypass;
4042 	cmdline_fixed_string_t config;
4043 	uint8_t port_id;
4044 };
4045 
4046 static void
4047 cmd_show_bypass_config_parsed(void *parsed_result,
4048 		__attribute__((unused)) struct cmdline *cl,
4049 		__attribute__((unused)) void *data)
4050 {
4051 	struct cmd_show_bypass_config_result *res = parsed_result;
4052 	uint32_t event_mode;
4053 	uint32_t bypass_mode;
4054 	portid_t port_id = res->port_id;
4055 	uint32_t timeout = bypass_timeout;
4056 	int i;
4057 
4058 	static const char * const timeouts[RTE_BYPASS_TMT_NUM] =
4059 		{"off", "1.5", "2", "3", "4", "8", "16", "32"};
4060 	static const char * const modes[RTE_BYPASS_MODE_NUM] =
4061 		{"UNKNOWN", "normal", "bypass", "isolate"};
4062 	static const char * const events[RTE_BYPASS_EVENT_NUM] = {
4063 		"NONE",
4064 		"OS/board on",
4065 		"power supply on",
4066 		"OS/board off",
4067 		"power supply off",
4068 		"timeout"};
4069 	int num_events = (sizeof events) / (sizeof events[0]);
4070 
4071 	/* Display the bypass mode.*/
4072 	if (0 != rte_eth_dev_bypass_state_show(port_id, &bypass_mode)) {
4073 		printf("\tFailed to get bypass mode for port = %d\n", port_id);
4074 		return;
4075 	}
4076 	else {
4077 		if (!RTE_BYPASS_MODE_VALID(bypass_mode))
4078 			bypass_mode = RTE_BYPASS_MODE_NONE;
4079 
4080 		printf("\tbypass mode    = %s\n",  modes[bypass_mode]);
4081 	}
4082 
4083 	/* Display the bypass timeout.*/
4084 	if (!RTE_BYPASS_TMT_VALID(timeout))
4085 		timeout = RTE_BYPASS_TMT_OFF;
4086 
4087 	printf("\tbypass timeout = %s\n", timeouts[timeout]);
4088 
4089 	/* Display the bypass events and associated modes. */
4090 	for (i = RTE_BYPASS_EVENT_START; i < num_events; i++) {
4091 
4092 		if (0 != rte_eth_dev_bypass_event_show(port_id, i, &event_mode)) {
4093 			printf("\tFailed to get bypass mode for event = %s\n",
4094 				events[i]);
4095 		} else {
4096 			if (!RTE_BYPASS_MODE_VALID(event_mode))
4097 				event_mode = RTE_BYPASS_MODE_NONE;
4098 
4099 			printf("\tbypass event: %-16s = %s\n", events[i],
4100 				modes[event_mode]);
4101 		}
4102 	}
4103 }
4104 
4105 cmdline_parse_token_string_t cmd_showbypass_config_show =
4106 	TOKEN_STRING_INITIALIZER(struct cmd_show_bypass_config_result,
4107 			show, "show");
4108 cmdline_parse_token_string_t cmd_showbypass_config_bypass =
4109 	TOKEN_STRING_INITIALIZER(struct cmd_show_bypass_config_result,
4110 			bypass, "bypass");
4111 cmdline_parse_token_string_t cmd_showbypass_config_config =
4112 	TOKEN_STRING_INITIALIZER(struct cmd_show_bypass_config_result,
4113 			config, "config");
4114 cmdline_parse_token_num_t cmd_showbypass_config_port =
4115 	TOKEN_NUM_INITIALIZER(struct cmd_show_bypass_config_result,
4116 				port_id, UINT8);
4117 
4118 cmdline_parse_inst_t cmd_show_bypass_config = {
4119 	.f = cmd_show_bypass_config_parsed,
4120 	.help_str = "show bypass config <port_id>: "
4121 	            "Show the NIC bypass config for port_id",
4122 	.data = NULL,
4123 	.tokens = {
4124 		(void *)&cmd_showbypass_config_show,
4125 		(void *)&cmd_showbypass_config_bypass,
4126 		(void *)&cmd_showbypass_config_config,
4127 		(void *)&cmd_showbypass_config_port,
4128 		NULL,
4129 	},
4130 };
4131 #endif
4132 
4133 #ifdef RTE_LIBRTE_PMD_BOND
4134 /* *** SET BONDING MODE *** */
4135 struct cmd_set_bonding_mode_result {
4136 	cmdline_fixed_string_t set;
4137 	cmdline_fixed_string_t bonding;
4138 	cmdline_fixed_string_t mode;
4139 	uint8_t value;
4140 	uint8_t port_id;
4141 };
4142 
4143 static void cmd_set_bonding_mode_parsed(void *parsed_result,
4144 		__attribute__((unused))  struct cmdline *cl,
4145 		__attribute__((unused)) void *data)
4146 {
4147 	struct cmd_set_bonding_mode_result *res = parsed_result;
4148 	portid_t port_id = res->port_id;
4149 
4150 	/* Set the bonding mode for the relevant port. */
4151 	if (0 != rte_eth_bond_mode_set(port_id, res->value))
4152 		printf("\t Failed to set bonding mode for port = %d.\n", port_id);
4153 }
4154 
4155 cmdline_parse_token_string_t cmd_setbonding_mode_set =
4156 TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_mode_result,
4157 		set, "set");
4158 cmdline_parse_token_string_t cmd_setbonding_mode_bonding =
4159 TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_mode_result,
4160 		bonding, "bonding");
4161 cmdline_parse_token_string_t cmd_setbonding_mode_mode =
4162 TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_mode_result,
4163 		mode, "mode");
4164 cmdline_parse_token_num_t cmd_setbonding_mode_value =
4165 TOKEN_NUM_INITIALIZER(struct cmd_set_bonding_mode_result,
4166 		value, UINT8);
4167 cmdline_parse_token_num_t cmd_setbonding_mode_port =
4168 TOKEN_NUM_INITIALIZER(struct cmd_set_bonding_mode_result,
4169 		port_id, UINT8);
4170 
4171 cmdline_parse_inst_t cmd_set_bonding_mode = {
4172 		.f = cmd_set_bonding_mode_parsed,
4173 		.help_str = "set bonding mode <mode_value> <port_id>: "
4174 			"Set the bonding mode for port_id",
4175 		.data = NULL,
4176 		.tokens = {
4177 				(void *) &cmd_setbonding_mode_set,
4178 				(void *) &cmd_setbonding_mode_bonding,
4179 				(void *) &cmd_setbonding_mode_mode,
4180 				(void *) &cmd_setbonding_mode_value,
4181 				(void *) &cmd_setbonding_mode_port,
4182 				NULL
4183 		}
4184 };
4185 
4186 /* *** SET BALANCE XMIT POLICY *** */
4187 struct cmd_set_bonding_balance_xmit_policy_result {
4188 	cmdline_fixed_string_t set;
4189 	cmdline_fixed_string_t bonding;
4190 	cmdline_fixed_string_t balance_xmit_policy;
4191 	uint8_t port_id;
4192 	cmdline_fixed_string_t policy;
4193 };
4194 
4195 static void cmd_set_bonding_balance_xmit_policy_parsed(void *parsed_result,
4196 		__attribute__((unused))  struct cmdline *cl,
4197 		__attribute__((unused)) void *data)
4198 {
4199 	struct cmd_set_bonding_balance_xmit_policy_result *res = parsed_result;
4200 	portid_t port_id = res->port_id;
4201 	uint8_t policy;
4202 
4203 	if (!strcmp(res->policy, "l2")) {
4204 		policy = BALANCE_XMIT_POLICY_LAYER2;
4205 	} else if (!strcmp(res->policy, "l23")) {
4206 		policy = BALANCE_XMIT_POLICY_LAYER23;
4207 	} else if (!strcmp(res->policy, "l34")) {
4208 		policy = BALANCE_XMIT_POLICY_LAYER34;
4209 	} else {
4210 		printf("\t Invalid xmit policy selection");
4211 		return;
4212 	}
4213 
4214 	/* Set the bonding mode for the relevant port. */
4215 	if (0 != rte_eth_bond_xmit_policy_set(port_id, policy)) {
4216 		printf("\t Failed to set bonding balance xmit policy for port = %d.\n",
4217 				port_id);
4218 	}
4219 }
4220 
4221 cmdline_parse_token_string_t cmd_setbonding_balance_xmit_policy_set =
4222 TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_balance_xmit_policy_result,
4223 		set, "set");
4224 cmdline_parse_token_string_t cmd_setbonding_balance_xmit_policy_bonding =
4225 TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_balance_xmit_policy_result,
4226 		bonding, "bonding");
4227 cmdline_parse_token_string_t cmd_setbonding_balance_xmit_policy_balance_xmit_policy =
4228 TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_balance_xmit_policy_result,
4229 		balance_xmit_policy, "balance_xmit_policy");
4230 cmdline_parse_token_num_t cmd_setbonding_balance_xmit_policy_port =
4231 TOKEN_NUM_INITIALIZER(struct cmd_set_bonding_balance_xmit_policy_result,
4232 		port_id, UINT8);
4233 cmdline_parse_token_string_t cmd_setbonding_balance_xmit_policy_policy =
4234 TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_balance_xmit_policy_result,
4235 		policy, "l2#l23#l34");
4236 
4237 cmdline_parse_inst_t cmd_set_balance_xmit_policy = {
4238 		.f = cmd_set_bonding_balance_xmit_policy_parsed,
4239 		.help_str = "set bonding balance_xmit_policy <port_id> "
4240 			"l2|l23|l34: "
4241 			"Set the bonding balance_xmit_policy for port_id",
4242 		.data = NULL,
4243 		.tokens = {
4244 				(void *)&cmd_setbonding_balance_xmit_policy_set,
4245 				(void *)&cmd_setbonding_balance_xmit_policy_bonding,
4246 				(void *)&cmd_setbonding_balance_xmit_policy_balance_xmit_policy,
4247 				(void *)&cmd_setbonding_balance_xmit_policy_port,
4248 				(void *)&cmd_setbonding_balance_xmit_policy_policy,
4249 				NULL
4250 		}
4251 };
4252 
4253 /* *** SHOW NIC BONDING CONFIGURATION *** */
4254 struct cmd_show_bonding_config_result {
4255 	cmdline_fixed_string_t show;
4256 	cmdline_fixed_string_t bonding;
4257 	cmdline_fixed_string_t config;
4258 	uint8_t port_id;
4259 };
4260 
4261 static void cmd_show_bonding_config_parsed(void *parsed_result,
4262 		__attribute__((unused))  struct cmdline *cl,
4263 		__attribute__((unused)) void *data)
4264 {
4265 	struct cmd_show_bonding_config_result *res = parsed_result;
4266 	int bonding_mode;
4267 	uint8_t slaves[RTE_MAX_ETHPORTS];
4268 	int num_slaves, num_active_slaves;
4269 	int primary_id;
4270 	int i;
4271 	portid_t port_id = res->port_id;
4272 
4273 	/* Display the bonding mode.*/
4274 	bonding_mode = rte_eth_bond_mode_get(port_id);
4275 	if (bonding_mode < 0) {
4276 		printf("\tFailed to get bonding mode for port = %d\n", port_id);
4277 		return;
4278 	} else
4279 		printf("\tBonding mode: %d\n", bonding_mode);
4280 
4281 	if (bonding_mode == BONDING_MODE_BALANCE) {
4282 		int balance_xmit_policy;
4283 
4284 		balance_xmit_policy = rte_eth_bond_xmit_policy_get(port_id);
4285 		if (balance_xmit_policy < 0) {
4286 			printf("\tFailed to get balance xmit policy for port = %d\n",
4287 					port_id);
4288 			return;
4289 		} else {
4290 			printf("\tBalance Xmit Policy: ");
4291 
4292 			switch (balance_xmit_policy) {
4293 			case BALANCE_XMIT_POLICY_LAYER2:
4294 				printf("BALANCE_XMIT_POLICY_LAYER2");
4295 				break;
4296 			case BALANCE_XMIT_POLICY_LAYER23:
4297 				printf("BALANCE_XMIT_POLICY_LAYER23");
4298 				break;
4299 			case BALANCE_XMIT_POLICY_LAYER34:
4300 				printf("BALANCE_XMIT_POLICY_LAYER34");
4301 				break;
4302 			}
4303 			printf("\n");
4304 		}
4305 	}
4306 
4307 	num_slaves = rte_eth_bond_slaves_get(port_id, slaves, RTE_MAX_ETHPORTS);
4308 
4309 	if (num_slaves < 0) {
4310 		printf("\tFailed to get slave list for port = %d\n", port_id);
4311 		return;
4312 	}
4313 	if (num_slaves > 0) {
4314 		printf("\tSlaves (%d): [", num_slaves);
4315 		for (i = 0; i < num_slaves - 1; i++)
4316 			printf("%d ", slaves[i]);
4317 
4318 		printf("%d]\n", slaves[num_slaves - 1]);
4319 	} else {
4320 		printf("\tSlaves: []\n");
4321 
4322 	}
4323 
4324 	num_active_slaves = rte_eth_bond_active_slaves_get(port_id, slaves,
4325 			RTE_MAX_ETHPORTS);
4326 
4327 	if (num_active_slaves < 0) {
4328 		printf("\tFailed to get active slave list for port = %d\n", port_id);
4329 		return;
4330 	}
4331 	if (num_active_slaves > 0) {
4332 		printf("\tActive Slaves (%d): [", num_active_slaves);
4333 		for (i = 0; i < num_active_slaves - 1; i++)
4334 			printf("%d ", slaves[i]);
4335 
4336 		printf("%d]\n", slaves[num_active_slaves - 1]);
4337 
4338 	} else {
4339 		printf("\tActive Slaves: []\n");
4340 
4341 	}
4342 
4343 	primary_id = rte_eth_bond_primary_get(port_id);
4344 	if (primary_id < 0) {
4345 		printf("\tFailed to get primary slave for port = %d\n", port_id);
4346 		return;
4347 	} else
4348 		printf("\tPrimary: [%d]\n", primary_id);
4349 
4350 }
4351 
4352 cmdline_parse_token_string_t cmd_showbonding_config_show =
4353 TOKEN_STRING_INITIALIZER(struct cmd_show_bonding_config_result,
4354 		show, "show");
4355 cmdline_parse_token_string_t cmd_showbonding_config_bonding =
4356 TOKEN_STRING_INITIALIZER(struct cmd_show_bonding_config_result,
4357 		bonding, "bonding");
4358 cmdline_parse_token_string_t cmd_showbonding_config_config =
4359 TOKEN_STRING_INITIALIZER(struct cmd_show_bonding_config_result,
4360 		config, "config");
4361 cmdline_parse_token_num_t cmd_showbonding_config_port =
4362 TOKEN_NUM_INITIALIZER(struct cmd_show_bonding_config_result,
4363 		port_id, UINT8);
4364 
4365 cmdline_parse_inst_t cmd_show_bonding_config = {
4366 		.f = cmd_show_bonding_config_parsed,
4367 		.help_str = "show bonding config <port_id>: "
4368 			"Show the bonding config for port_id",
4369 		.data = NULL,
4370 		.tokens = {
4371 				(void *)&cmd_showbonding_config_show,
4372 				(void *)&cmd_showbonding_config_bonding,
4373 				(void *)&cmd_showbonding_config_config,
4374 				(void *)&cmd_showbonding_config_port,
4375 				NULL
4376 		}
4377 };
4378 
4379 /* *** SET BONDING PRIMARY *** */
4380 struct cmd_set_bonding_primary_result {
4381 	cmdline_fixed_string_t set;
4382 	cmdline_fixed_string_t bonding;
4383 	cmdline_fixed_string_t primary;
4384 	uint8_t slave_id;
4385 	uint8_t port_id;
4386 };
4387 
4388 static void cmd_set_bonding_primary_parsed(void *parsed_result,
4389 		__attribute__((unused))  struct cmdline *cl,
4390 		__attribute__((unused)) void *data)
4391 {
4392 	struct cmd_set_bonding_primary_result *res = parsed_result;
4393 	portid_t master_port_id = res->port_id;
4394 	portid_t slave_port_id = res->slave_id;
4395 
4396 	/* Set the primary slave for a bonded device. */
4397 	if (0 != rte_eth_bond_primary_set(master_port_id, slave_port_id)) {
4398 		printf("\t Failed to set primary slave for port = %d.\n",
4399 				master_port_id);
4400 		return;
4401 	}
4402 	init_port_config();
4403 }
4404 
4405 cmdline_parse_token_string_t cmd_setbonding_primary_set =
4406 TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_primary_result,
4407 		set, "set");
4408 cmdline_parse_token_string_t cmd_setbonding_primary_bonding =
4409 TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_primary_result,
4410 		bonding, "bonding");
4411 cmdline_parse_token_string_t cmd_setbonding_primary_primary =
4412 TOKEN_STRING_INITIALIZER(struct cmd_set_bonding_primary_result,
4413 		primary, "primary");
4414 cmdline_parse_token_num_t cmd_setbonding_primary_slave =
4415 TOKEN_NUM_INITIALIZER(struct cmd_set_bonding_primary_result,
4416 		slave_id, UINT8);
4417 cmdline_parse_token_num_t cmd_setbonding_primary_port =
4418 TOKEN_NUM_INITIALIZER(struct cmd_set_bonding_primary_result,
4419 		port_id, UINT8);
4420 
4421 cmdline_parse_inst_t cmd_set_bonding_primary = {
4422 		.f = cmd_set_bonding_primary_parsed,
4423 		.help_str = "set bonding primary <slave_id> <port_id>: "
4424 			"Set the primary slave for port_id",
4425 		.data = NULL,
4426 		.tokens = {
4427 				(void *)&cmd_setbonding_primary_set,
4428 				(void *)&cmd_setbonding_primary_bonding,
4429 				(void *)&cmd_setbonding_primary_primary,
4430 				(void *)&cmd_setbonding_primary_slave,
4431 				(void *)&cmd_setbonding_primary_port,
4432 				NULL
4433 		}
4434 };
4435 
4436 /* *** ADD SLAVE *** */
4437 struct cmd_add_bonding_slave_result {
4438 	cmdline_fixed_string_t add;
4439 	cmdline_fixed_string_t bonding;
4440 	cmdline_fixed_string_t slave;
4441 	uint8_t slave_id;
4442 	uint8_t port_id;
4443 };
4444 
4445 static void cmd_add_bonding_slave_parsed(void *parsed_result,
4446 		__attribute__((unused))  struct cmdline *cl,
4447 		__attribute__((unused)) void *data)
4448 {
4449 	struct cmd_add_bonding_slave_result *res = parsed_result;
4450 	portid_t master_port_id = res->port_id;
4451 	portid_t slave_port_id = res->slave_id;
4452 
4453 	/* Set the primary slave for a bonded device. */
4454 	if (0 != rte_eth_bond_slave_add(master_port_id, slave_port_id)) {
4455 		printf("\t Failed to add slave %d to master port = %d.\n",
4456 				slave_port_id, master_port_id);
4457 		return;
4458 	}
4459 	init_port_config();
4460 	set_port_slave_flag(slave_port_id);
4461 }
4462 
4463 cmdline_parse_token_string_t cmd_addbonding_slave_add =
4464 TOKEN_STRING_INITIALIZER(struct cmd_add_bonding_slave_result,
4465 		add, "add");
4466 cmdline_parse_token_string_t cmd_addbonding_slave_bonding =
4467 TOKEN_STRING_INITIALIZER(struct cmd_add_bonding_slave_result,
4468 		bonding, "bonding");
4469 cmdline_parse_token_string_t cmd_addbonding_slave_slave =
4470 TOKEN_STRING_INITIALIZER(struct cmd_add_bonding_slave_result,
4471 		slave, "slave");
4472 cmdline_parse_token_num_t cmd_addbonding_slave_slaveid =
4473 TOKEN_NUM_INITIALIZER(struct cmd_add_bonding_slave_result,
4474 		slave_id, UINT8);
4475 cmdline_parse_token_num_t cmd_addbonding_slave_port =
4476 TOKEN_NUM_INITIALIZER(struct cmd_add_bonding_slave_result,
4477 		port_id, UINT8);
4478 
4479 cmdline_parse_inst_t cmd_add_bonding_slave = {
4480 		.f = cmd_add_bonding_slave_parsed,
4481 		.help_str = "add bonding slave <slave_id> <port_id>: "
4482 			"Add a slave device to a bonded device",
4483 		.data = NULL,
4484 		.tokens = {
4485 				(void *)&cmd_addbonding_slave_add,
4486 				(void *)&cmd_addbonding_slave_bonding,
4487 				(void *)&cmd_addbonding_slave_slave,
4488 				(void *)&cmd_addbonding_slave_slaveid,
4489 				(void *)&cmd_addbonding_slave_port,
4490 				NULL
4491 		}
4492 };
4493 
4494 /* *** REMOVE SLAVE *** */
4495 struct cmd_remove_bonding_slave_result {
4496 	cmdline_fixed_string_t remove;
4497 	cmdline_fixed_string_t bonding;
4498 	cmdline_fixed_string_t slave;
4499 	uint8_t slave_id;
4500 	uint8_t port_id;
4501 };
4502 
4503 static void cmd_remove_bonding_slave_parsed(void *parsed_result,
4504 		__attribute__((unused))  struct cmdline *cl,
4505 		__attribute__((unused)) void *data)
4506 {
4507 	struct cmd_remove_bonding_slave_result *res = parsed_result;
4508 	portid_t master_port_id = res->port_id;
4509 	portid_t slave_port_id = res->slave_id;
4510 
4511 	/* Set the primary slave for a bonded device. */
4512 	if (0 != rte_eth_bond_slave_remove(master_port_id, slave_port_id)) {
4513 		printf("\t Failed to remove slave %d from master port = %d.\n",
4514 				slave_port_id, master_port_id);
4515 		return;
4516 	}
4517 	init_port_config();
4518 	clear_port_slave_flag(slave_port_id);
4519 }
4520 
4521 cmdline_parse_token_string_t cmd_removebonding_slave_remove =
4522 		TOKEN_STRING_INITIALIZER(struct cmd_remove_bonding_slave_result,
4523 				remove, "remove");
4524 cmdline_parse_token_string_t cmd_removebonding_slave_bonding =
4525 		TOKEN_STRING_INITIALIZER(struct cmd_remove_bonding_slave_result,
4526 				bonding, "bonding");
4527 cmdline_parse_token_string_t cmd_removebonding_slave_slave =
4528 		TOKEN_STRING_INITIALIZER(struct cmd_remove_bonding_slave_result,
4529 				slave, "slave");
4530 cmdline_parse_token_num_t cmd_removebonding_slave_slaveid =
4531 		TOKEN_NUM_INITIALIZER(struct cmd_remove_bonding_slave_result,
4532 				slave_id, UINT8);
4533 cmdline_parse_token_num_t cmd_removebonding_slave_port =
4534 		TOKEN_NUM_INITIALIZER(struct cmd_remove_bonding_slave_result,
4535 				port_id, UINT8);
4536 
4537 cmdline_parse_inst_t cmd_remove_bonding_slave = {
4538 		.f = cmd_remove_bonding_slave_parsed,
4539 		.help_str = "remove bonding slave <slave_id> <port_id>: "
4540 			"Remove a slave device from a bonded device",
4541 		.data = NULL,
4542 		.tokens = {
4543 				(void *)&cmd_removebonding_slave_remove,
4544 				(void *)&cmd_removebonding_slave_bonding,
4545 				(void *)&cmd_removebonding_slave_slave,
4546 				(void *)&cmd_removebonding_slave_slaveid,
4547 				(void *)&cmd_removebonding_slave_port,
4548 				NULL
4549 		}
4550 };
4551 
4552 /* *** CREATE BONDED DEVICE *** */
4553 struct cmd_create_bonded_device_result {
4554 	cmdline_fixed_string_t create;
4555 	cmdline_fixed_string_t bonded;
4556 	cmdline_fixed_string_t device;
4557 	uint8_t mode;
4558 	uint8_t socket;
4559 };
4560 
4561 static int bond_dev_num = 0;
4562 
4563 static void cmd_create_bonded_device_parsed(void *parsed_result,
4564 		__attribute__((unused))  struct cmdline *cl,
4565 		__attribute__((unused)) void *data)
4566 {
4567 	struct cmd_create_bonded_device_result *res = parsed_result;
4568 	char ethdev_name[RTE_ETH_NAME_MAX_LEN];
4569 	int port_id;
4570 
4571 	if (test_done == 0) {
4572 		printf("Please stop forwarding first\n");
4573 		return;
4574 	}
4575 
4576 	snprintf(ethdev_name, RTE_ETH_NAME_MAX_LEN, "net_bond_testpmd_%d",
4577 			bond_dev_num++);
4578 
4579 	/* Create a new bonded device. */
4580 	port_id = rte_eth_bond_create(ethdev_name, res->mode, res->socket);
4581 	if (port_id < 0) {
4582 		printf("\t Failed to create bonded device.\n");
4583 		return;
4584 	} else {
4585 		printf("Created new bonded device %s on (port %d).\n", ethdev_name,
4586 				port_id);
4587 
4588 		/* Update number of ports */
4589 		nb_ports = rte_eth_dev_count();
4590 		reconfig(port_id, res->socket);
4591 		rte_eth_promiscuous_enable(port_id);
4592 		ports[port_id].enabled = 1;
4593 	}
4594 
4595 }
4596 
4597 cmdline_parse_token_string_t cmd_createbonded_device_create =
4598 		TOKEN_STRING_INITIALIZER(struct cmd_create_bonded_device_result,
4599 				create, "create");
4600 cmdline_parse_token_string_t cmd_createbonded_device_bonded =
4601 		TOKEN_STRING_INITIALIZER(struct cmd_create_bonded_device_result,
4602 				bonded, "bonded");
4603 cmdline_parse_token_string_t cmd_createbonded_device_device =
4604 		TOKEN_STRING_INITIALIZER(struct cmd_create_bonded_device_result,
4605 				device, "device");
4606 cmdline_parse_token_num_t cmd_createbonded_device_mode =
4607 		TOKEN_NUM_INITIALIZER(struct cmd_create_bonded_device_result,
4608 				mode, UINT8);
4609 cmdline_parse_token_num_t cmd_createbonded_device_socket =
4610 		TOKEN_NUM_INITIALIZER(struct cmd_create_bonded_device_result,
4611 				socket, UINT8);
4612 
4613 cmdline_parse_inst_t cmd_create_bonded_device = {
4614 		.f = cmd_create_bonded_device_parsed,
4615 		.help_str = "create bonded device <mode> <socket>: "
4616 			"Create a new bonded device with specific bonding mode and socket",
4617 		.data = NULL,
4618 		.tokens = {
4619 				(void *)&cmd_createbonded_device_create,
4620 				(void *)&cmd_createbonded_device_bonded,
4621 				(void *)&cmd_createbonded_device_device,
4622 				(void *)&cmd_createbonded_device_mode,
4623 				(void *)&cmd_createbonded_device_socket,
4624 				NULL
4625 		}
4626 };
4627 
4628 /* *** SET MAC ADDRESS IN BONDED DEVICE *** */
4629 struct cmd_set_bond_mac_addr_result {
4630 	cmdline_fixed_string_t set;
4631 	cmdline_fixed_string_t bonding;
4632 	cmdline_fixed_string_t mac_addr;
4633 	uint8_t port_num;
4634 	struct ether_addr address;
4635 };
4636 
4637 static void cmd_set_bond_mac_addr_parsed(void *parsed_result,
4638 		__attribute__((unused))  struct cmdline *cl,
4639 		__attribute__((unused)) void *data)
4640 {
4641 	struct cmd_set_bond_mac_addr_result *res = parsed_result;
4642 	int ret;
4643 
4644 	if (port_id_is_invalid(res->port_num, ENABLED_WARN))
4645 		return;
4646 
4647 	ret = rte_eth_bond_mac_address_set(res->port_num, &res->address);
4648 
4649 	/* check the return value and print it if is < 0 */
4650 	if (ret < 0)
4651 		printf("set_bond_mac_addr error: (%s)\n", strerror(-ret));
4652 }
4653 
4654 cmdline_parse_token_string_t cmd_set_bond_mac_addr_set =
4655 		TOKEN_STRING_INITIALIZER(struct cmd_set_bond_mac_addr_result, set, "set");
4656 cmdline_parse_token_string_t cmd_set_bond_mac_addr_bonding =
4657 		TOKEN_STRING_INITIALIZER(struct cmd_set_bond_mac_addr_result, bonding,
4658 				"bonding");
4659 cmdline_parse_token_string_t cmd_set_bond_mac_addr_mac =
4660 		TOKEN_STRING_INITIALIZER(struct cmd_set_bond_mac_addr_result, mac_addr,
4661 				"mac_addr");
4662 cmdline_parse_token_num_t cmd_set_bond_mac_addr_portnum =
4663 		TOKEN_NUM_INITIALIZER(struct cmd_set_bond_mac_addr_result, port_num, UINT8);
4664 cmdline_parse_token_etheraddr_t cmd_set_bond_mac_addr_addr =
4665 		TOKEN_ETHERADDR_INITIALIZER(struct cmd_set_bond_mac_addr_result, address);
4666 
4667 cmdline_parse_inst_t cmd_set_bond_mac_addr = {
4668 		.f = cmd_set_bond_mac_addr_parsed,
4669 		.data = (void *) 0,
4670 		.help_str = "set bonding mac_addr <port_id> <mac_addr>",
4671 		.tokens = {
4672 				(void *)&cmd_set_bond_mac_addr_set,
4673 				(void *)&cmd_set_bond_mac_addr_bonding,
4674 				(void *)&cmd_set_bond_mac_addr_mac,
4675 				(void *)&cmd_set_bond_mac_addr_portnum,
4676 				(void *)&cmd_set_bond_mac_addr_addr,
4677 				NULL
4678 		}
4679 };
4680 
4681 
4682 /* *** SET LINK STATUS MONITORING POLLING PERIOD ON BONDED DEVICE *** */
4683 struct cmd_set_bond_mon_period_result {
4684 	cmdline_fixed_string_t set;
4685 	cmdline_fixed_string_t bonding;
4686 	cmdline_fixed_string_t mon_period;
4687 	uint8_t port_num;
4688 	uint32_t period_ms;
4689 };
4690 
4691 static void cmd_set_bond_mon_period_parsed(void *parsed_result,
4692 		__attribute__((unused))  struct cmdline *cl,
4693 		__attribute__((unused)) void *data)
4694 {
4695 	struct cmd_set_bond_mon_period_result *res = parsed_result;
4696 	int ret;
4697 
4698 	if (res->port_num >= nb_ports) {
4699 		printf("Port id %d must be less than %d\n", res->port_num, nb_ports);
4700 		return;
4701 	}
4702 
4703 	ret = rte_eth_bond_link_monitoring_set(res->port_num, res->period_ms);
4704 
4705 	/* check the return value and print it if is < 0 */
4706 	if (ret < 0)
4707 		printf("set_bond_mac_addr error: (%s)\n", strerror(-ret));
4708 }
4709 
4710 cmdline_parse_token_string_t cmd_set_bond_mon_period_set =
4711 		TOKEN_STRING_INITIALIZER(struct cmd_set_bond_mon_period_result,
4712 				set, "set");
4713 cmdline_parse_token_string_t cmd_set_bond_mon_period_bonding =
4714 		TOKEN_STRING_INITIALIZER(struct cmd_set_bond_mon_period_result,
4715 				bonding, "bonding");
4716 cmdline_parse_token_string_t cmd_set_bond_mon_period_mon_period =
4717 		TOKEN_STRING_INITIALIZER(struct cmd_set_bond_mon_period_result,
4718 				mon_period,	"mon_period");
4719 cmdline_parse_token_num_t cmd_set_bond_mon_period_portnum =
4720 		TOKEN_NUM_INITIALIZER(struct cmd_set_bond_mon_period_result,
4721 				port_num, UINT8);
4722 cmdline_parse_token_num_t cmd_set_bond_mon_period_period_ms =
4723 		TOKEN_NUM_INITIALIZER(struct cmd_set_bond_mon_period_result,
4724 				period_ms, UINT32);
4725 
4726 cmdline_parse_inst_t cmd_set_bond_mon_period = {
4727 		.f = cmd_set_bond_mon_period_parsed,
4728 		.data = (void *) 0,
4729 		.help_str = "set bonding mon_period <port_id> <period_ms>",
4730 		.tokens = {
4731 				(void *)&cmd_set_bond_mon_period_set,
4732 				(void *)&cmd_set_bond_mon_period_bonding,
4733 				(void *)&cmd_set_bond_mon_period_mon_period,
4734 				(void *)&cmd_set_bond_mon_period_portnum,
4735 				(void *)&cmd_set_bond_mon_period_period_ms,
4736 				NULL
4737 		}
4738 };
4739 
4740 #endif /* RTE_LIBRTE_PMD_BOND */
4741 
4742 /* *** SET FORWARDING MODE *** */
4743 struct cmd_set_fwd_mode_result {
4744 	cmdline_fixed_string_t set;
4745 	cmdline_fixed_string_t fwd;
4746 	cmdline_fixed_string_t mode;
4747 };
4748 
4749 static void cmd_set_fwd_mode_parsed(void *parsed_result,
4750 				    __attribute__((unused)) struct cmdline *cl,
4751 				    __attribute__((unused)) void *data)
4752 {
4753 	struct cmd_set_fwd_mode_result *res = parsed_result;
4754 
4755 	retry_enabled = 0;
4756 	set_pkt_forwarding_mode(res->mode);
4757 }
4758 
4759 cmdline_parse_token_string_t cmd_setfwd_set =
4760 	TOKEN_STRING_INITIALIZER(struct cmd_set_fwd_mode_result, set, "set");
4761 cmdline_parse_token_string_t cmd_setfwd_fwd =
4762 	TOKEN_STRING_INITIALIZER(struct cmd_set_fwd_mode_result, fwd, "fwd");
4763 cmdline_parse_token_string_t cmd_setfwd_mode =
4764 	TOKEN_STRING_INITIALIZER(struct cmd_set_fwd_mode_result, mode,
4765 		"" /* defined at init */);
4766 
4767 cmdline_parse_inst_t cmd_set_fwd_mode = {
4768 	.f = cmd_set_fwd_mode_parsed,
4769 	.data = NULL,
4770 	.help_str = NULL, /* defined at init */
4771 	.tokens = {
4772 		(void *)&cmd_setfwd_set,
4773 		(void *)&cmd_setfwd_fwd,
4774 		(void *)&cmd_setfwd_mode,
4775 		NULL,
4776 	},
4777 };
4778 
4779 static void cmd_set_fwd_mode_init(void)
4780 {
4781 	char *modes, *c;
4782 	static char token[128];
4783 	static char help[256];
4784 	cmdline_parse_token_string_t *token_struct;
4785 
4786 	modes = list_pkt_forwarding_modes();
4787 	snprintf(help, sizeof(help), "set fwd %s: "
4788 		"Set packet forwarding mode", modes);
4789 	cmd_set_fwd_mode.help_str = help;
4790 
4791 	/* string token separator is # */
4792 	for (c = token; *modes != '\0'; modes++)
4793 		if (*modes == '|')
4794 			*c++ = '#';
4795 		else
4796 			*c++ = *modes;
4797 	token_struct = (cmdline_parse_token_string_t*)cmd_set_fwd_mode.tokens[2];
4798 	token_struct->string_data.str = token;
4799 }
4800 
4801 /* *** SET RETRY FORWARDING MODE *** */
4802 struct cmd_set_fwd_retry_mode_result {
4803 	cmdline_fixed_string_t set;
4804 	cmdline_fixed_string_t fwd;
4805 	cmdline_fixed_string_t mode;
4806 	cmdline_fixed_string_t retry;
4807 };
4808 
4809 static void cmd_set_fwd_retry_mode_parsed(void *parsed_result,
4810 			    __attribute__((unused)) struct cmdline *cl,
4811 			    __attribute__((unused)) void *data)
4812 {
4813 	struct cmd_set_fwd_retry_mode_result *res = parsed_result;
4814 
4815 	retry_enabled = 1;
4816 	set_pkt_forwarding_mode(res->mode);
4817 }
4818 
4819 cmdline_parse_token_string_t cmd_setfwd_retry_set =
4820 	TOKEN_STRING_INITIALIZER(struct cmd_set_fwd_retry_mode_result,
4821 			set, "set");
4822 cmdline_parse_token_string_t cmd_setfwd_retry_fwd =
4823 	TOKEN_STRING_INITIALIZER(struct cmd_set_fwd_retry_mode_result,
4824 			fwd, "fwd");
4825 cmdline_parse_token_string_t cmd_setfwd_retry_mode =
4826 	TOKEN_STRING_INITIALIZER(struct cmd_set_fwd_retry_mode_result,
4827 			mode,
4828 		"" /* defined at init */);
4829 cmdline_parse_token_string_t cmd_setfwd_retry_retry =
4830 	TOKEN_STRING_INITIALIZER(struct cmd_set_fwd_retry_mode_result,
4831 			retry, "retry");
4832 
4833 cmdline_parse_inst_t cmd_set_fwd_retry_mode = {
4834 	.f = cmd_set_fwd_retry_mode_parsed,
4835 	.data = NULL,
4836 	.help_str = NULL, /* defined at init */
4837 	.tokens = {
4838 		(void *)&cmd_setfwd_retry_set,
4839 		(void *)&cmd_setfwd_retry_fwd,
4840 		(void *)&cmd_setfwd_retry_mode,
4841 		(void *)&cmd_setfwd_retry_retry,
4842 		NULL,
4843 	},
4844 };
4845 
4846 static void cmd_set_fwd_retry_mode_init(void)
4847 {
4848 	char *modes, *c;
4849 	static char token[128];
4850 	static char help[256];
4851 	cmdline_parse_token_string_t *token_struct;
4852 
4853 	modes = list_pkt_forwarding_retry_modes();
4854 	snprintf(help, sizeof(help), "set fwd %s retry: "
4855 		"Set packet forwarding mode with retry", modes);
4856 	cmd_set_fwd_retry_mode.help_str = help;
4857 
4858 	/* string token separator is # */
4859 	for (c = token; *modes != '\0'; modes++)
4860 		if (*modes == '|')
4861 			*c++ = '#';
4862 		else
4863 			*c++ = *modes;
4864 	token_struct = (cmdline_parse_token_string_t *)
4865 		cmd_set_fwd_retry_mode.tokens[2];
4866 	token_struct->string_data.str = token;
4867 }
4868 
4869 /* *** SET BURST TX DELAY TIME RETRY NUMBER *** */
4870 struct cmd_set_burst_tx_retry_result {
4871 	cmdline_fixed_string_t set;
4872 	cmdline_fixed_string_t burst;
4873 	cmdline_fixed_string_t tx;
4874 	cmdline_fixed_string_t delay;
4875 	uint32_t time;
4876 	cmdline_fixed_string_t retry;
4877 	uint32_t retry_num;
4878 };
4879 
4880 static void cmd_set_burst_tx_retry_parsed(void *parsed_result,
4881 					__attribute__((unused)) struct cmdline *cl,
4882 					__attribute__((unused)) void *data)
4883 {
4884 	struct cmd_set_burst_tx_retry_result *res = parsed_result;
4885 
4886 	if (!strcmp(res->set, "set") && !strcmp(res->burst, "burst")
4887 		&& !strcmp(res->tx, "tx")) {
4888 		if (!strcmp(res->delay, "delay"))
4889 			burst_tx_delay_time = res->time;
4890 		if (!strcmp(res->retry, "retry"))
4891 			burst_tx_retry_num = res->retry_num;
4892 	}
4893 
4894 }
4895 
4896 cmdline_parse_token_string_t cmd_set_burst_tx_retry_set =
4897 	TOKEN_STRING_INITIALIZER(struct cmd_set_burst_tx_retry_result, set, "set");
4898 cmdline_parse_token_string_t cmd_set_burst_tx_retry_burst =
4899 	TOKEN_STRING_INITIALIZER(struct cmd_set_burst_tx_retry_result, burst,
4900 				 "burst");
4901 cmdline_parse_token_string_t cmd_set_burst_tx_retry_tx =
4902 	TOKEN_STRING_INITIALIZER(struct cmd_set_burst_tx_retry_result, tx, "tx");
4903 cmdline_parse_token_string_t cmd_set_burst_tx_retry_delay =
4904 	TOKEN_STRING_INITIALIZER(struct cmd_set_burst_tx_retry_result, delay, "delay");
4905 cmdline_parse_token_num_t cmd_set_burst_tx_retry_time =
4906 	TOKEN_NUM_INITIALIZER(struct cmd_set_burst_tx_retry_result, time, UINT32);
4907 cmdline_parse_token_string_t cmd_set_burst_tx_retry_retry =
4908 	TOKEN_STRING_INITIALIZER(struct cmd_set_burst_tx_retry_result, retry, "retry");
4909 cmdline_parse_token_num_t cmd_set_burst_tx_retry_retry_num =
4910 	TOKEN_NUM_INITIALIZER(struct cmd_set_burst_tx_retry_result, retry_num, UINT32);
4911 
4912 cmdline_parse_inst_t cmd_set_burst_tx_retry = {
4913 	.f = cmd_set_burst_tx_retry_parsed,
4914 	.help_str = "set burst tx delay <delay_usec> retry <num_retry>",
4915 	.tokens = {
4916 		(void *)&cmd_set_burst_tx_retry_set,
4917 		(void *)&cmd_set_burst_tx_retry_burst,
4918 		(void *)&cmd_set_burst_tx_retry_tx,
4919 		(void *)&cmd_set_burst_tx_retry_delay,
4920 		(void *)&cmd_set_burst_tx_retry_time,
4921 		(void *)&cmd_set_burst_tx_retry_retry,
4922 		(void *)&cmd_set_burst_tx_retry_retry_num,
4923 		NULL,
4924 	},
4925 };
4926 
4927 /* *** SET PROMISC MODE *** */
4928 struct cmd_set_promisc_mode_result {
4929 	cmdline_fixed_string_t set;
4930 	cmdline_fixed_string_t promisc;
4931 	cmdline_fixed_string_t port_all; /* valid if "allports" argument == 1 */
4932 	uint8_t port_num;                /* valid if "allports" argument == 0 */
4933 	cmdline_fixed_string_t mode;
4934 };
4935 
4936 static void cmd_set_promisc_mode_parsed(void *parsed_result,
4937 					__attribute__((unused)) struct cmdline *cl,
4938 					void *allports)
4939 {
4940 	struct cmd_set_promisc_mode_result *res = parsed_result;
4941 	int enable;
4942 	portid_t i;
4943 
4944 	if (!strcmp(res->mode, "on"))
4945 		enable = 1;
4946 	else
4947 		enable = 0;
4948 
4949 	/* all ports */
4950 	if (allports) {
4951 		FOREACH_PORT(i, ports) {
4952 			if (enable)
4953 				rte_eth_promiscuous_enable(i);
4954 			else
4955 				rte_eth_promiscuous_disable(i);
4956 		}
4957 	}
4958 	else {
4959 		if (enable)
4960 			rte_eth_promiscuous_enable(res->port_num);
4961 		else
4962 			rte_eth_promiscuous_disable(res->port_num);
4963 	}
4964 }
4965 
4966 cmdline_parse_token_string_t cmd_setpromisc_set =
4967 	TOKEN_STRING_INITIALIZER(struct cmd_set_promisc_mode_result, set, "set");
4968 cmdline_parse_token_string_t cmd_setpromisc_promisc =
4969 	TOKEN_STRING_INITIALIZER(struct cmd_set_promisc_mode_result, promisc,
4970 				 "promisc");
4971 cmdline_parse_token_string_t cmd_setpromisc_portall =
4972 	TOKEN_STRING_INITIALIZER(struct cmd_set_promisc_mode_result, port_all,
4973 				 "all");
4974 cmdline_parse_token_num_t cmd_setpromisc_portnum =
4975 	TOKEN_NUM_INITIALIZER(struct cmd_set_promisc_mode_result, port_num,
4976 			      UINT8);
4977 cmdline_parse_token_string_t cmd_setpromisc_mode =
4978 	TOKEN_STRING_INITIALIZER(struct cmd_set_promisc_mode_result, mode,
4979 				 "on#off");
4980 
4981 cmdline_parse_inst_t cmd_set_promisc_mode_all = {
4982 	.f = cmd_set_promisc_mode_parsed,
4983 	.data = (void *)1,
4984 	.help_str = "set promisc all on|off: Set promisc mode for all ports",
4985 	.tokens = {
4986 		(void *)&cmd_setpromisc_set,
4987 		(void *)&cmd_setpromisc_promisc,
4988 		(void *)&cmd_setpromisc_portall,
4989 		(void *)&cmd_setpromisc_mode,
4990 		NULL,
4991 	},
4992 };
4993 
4994 cmdline_parse_inst_t cmd_set_promisc_mode_one = {
4995 	.f = cmd_set_promisc_mode_parsed,
4996 	.data = (void *)0,
4997 	.help_str = "set promisc <port_id> on|off: Set promisc mode on port_id",
4998 	.tokens = {
4999 		(void *)&cmd_setpromisc_set,
5000 		(void *)&cmd_setpromisc_promisc,
5001 		(void *)&cmd_setpromisc_portnum,
5002 		(void *)&cmd_setpromisc_mode,
5003 		NULL,
5004 	},
5005 };
5006 
5007 /* *** SET ALLMULTI MODE *** */
5008 struct cmd_set_allmulti_mode_result {
5009 	cmdline_fixed_string_t set;
5010 	cmdline_fixed_string_t allmulti;
5011 	cmdline_fixed_string_t port_all; /* valid if "allports" argument == 1 */
5012 	uint8_t port_num;                /* valid if "allports" argument == 0 */
5013 	cmdline_fixed_string_t mode;
5014 };
5015 
5016 static void cmd_set_allmulti_mode_parsed(void *parsed_result,
5017 					__attribute__((unused)) struct cmdline *cl,
5018 					void *allports)
5019 {
5020 	struct cmd_set_allmulti_mode_result *res = parsed_result;
5021 	int enable;
5022 	portid_t i;
5023 
5024 	if (!strcmp(res->mode, "on"))
5025 		enable = 1;
5026 	else
5027 		enable = 0;
5028 
5029 	/* all ports */
5030 	if (allports) {
5031 		FOREACH_PORT(i, ports) {
5032 			if (enable)
5033 				rte_eth_allmulticast_enable(i);
5034 			else
5035 				rte_eth_allmulticast_disable(i);
5036 		}
5037 	}
5038 	else {
5039 		if (enable)
5040 			rte_eth_allmulticast_enable(res->port_num);
5041 		else
5042 			rte_eth_allmulticast_disable(res->port_num);
5043 	}
5044 }
5045 
5046 cmdline_parse_token_string_t cmd_setallmulti_set =
5047 	TOKEN_STRING_INITIALIZER(struct cmd_set_allmulti_mode_result, set, "set");
5048 cmdline_parse_token_string_t cmd_setallmulti_allmulti =
5049 	TOKEN_STRING_INITIALIZER(struct cmd_set_allmulti_mode_result, allmulti,
5050 				 "allmulti");
5051 cmdline_parse_token_string_t cmd_setallmulti_portall =
5052 	TOKEN_STRING_INITIALIZER(struct cmd_set_allmulti_mode_result, port_all,
5053 				 "all");
5054 cmdline_parse_token_num_t cmd_setallmulti_portnum =
5055 	TOKEN_NUM_INITIALIZER(struct cmd_set_allmulti_mode_result, port_num,
5056 			      UINT8);
5057 cmdline_parse_token_string_t cmd_setallmulti_mode =
5058 	TOKEN_STRING_INITIALIZER(struct cmd_set_allmulti_mode_result, mode,
5059 				 "on#off");
5060 
5061 cmdline_parse_inst_t cmd_set_allmulti_mode_all = {
5062 	.f = cmd_set_allmulti_mode_parsed,
5063 	.data = (void *)1,
5064 	.help_str = "set allmulti all on|off: Set allmulti mode for all ports",
5065 	.tokens = {
5066 		(void *)&cmd_setallmulti_set,
5067 		(void *)&cmd_setallmulti_allmulti,
5068 		(void *)&cmd_setallmulti_portall,
5069 		(void *)&cmd_setallmulti_mode,
5070 		NULL,
5071 	},
5072 };
5073 
5074 cmdline_parse_inst_t cmd_set_allmulti_mode_one = {
5075 	.f = cmd_set_allmulti_mode_parsed,
5076 	.data = (void *)0,
5077 	.help_str = "set allmulti <port_id> on|off: "
5078 		"Set allmulti mode on port_id",
5079 	.tokens = {
5080 		(void *)&cmd_setallmulti_set,
5081 		(void *)&cmd_setallmulti_allmulti,
5082 		(void *)&cmd_setallmulti_portnum,
5083 		(void *)&cmd_setallmulti_mode,
5084 		NULL,
5085 	},
5086 };
5087 
5088 /* *** SETUP ETHERNET LINK FLOW CONTROL *** */
5089 struct cmd_link_flow_ctrl_set_result {
5090 	cmdline_fixed_string_t set;
5091 	cmdline_fixed_string_t flow_ctrl;
5092 	cmdline_fixed_string_t rx;
5093 	cmdline_fixed_string_t rx_lfc_mode;
5094 	cmdline_fixed_string_t tx;
5095 	cmdline_fixed_string_t tx_lfc_mode;
5096 	cmdline_fixed_string_t mac_ctrl_frame_fwd;
5097 	cmdline_fixed_string_t mac_ctrl_frame_fwd_mode;
5098 	cmdline_fixed_string_t autoneg_str;
5099 	cmdline_fixed_string_t autoneg;
5100 	cmdline_fixed_string_t hw_str;
5101 	uint32_t high_water;
5102 	cmdline_fixed_string_t lw_str;
5103 	uint32_t low_water;
5104 	cmdline_fixed_string_t pt_str;
5105 	uint16_t pause_time;
5106 	cmdline_fixed_string_t xon_str;
5107 	uint16_t send_xon;
5108 	uint8_t  port_id;
5109 };
5110 
5111 cmdline_parse_token_string_t cmd_lfc_set_set =
5112 	TOKEN_STRING_INITIALIZER(struct cmd_link_flow_ctrl_set_result,
5113 				set, "set");
5114 cmdline_parse_token_string_t cmd_lfc_set_flow_ctrl =
5115 	TOKEN_STRING_INITIALIZER(struct cmd_link_flow_ctrl_set_result,
5116 				flow_ctrl, "flow_ctrl");
5117 cmdline_parse_token_string_t cmd_lfc_set_rx =
5118 	TOKEN_STRING_INITIALIZER(struct cmd_link_flow_ctrl_set_result,
5119 				rx, "rx");
5120 cmdline_parse_token_string_t cmd_lfc_set_rx_mode =
5121 	TOKEN_STRING_INITIALIZER(struct cmd_link_flow_ctrl_set_result,
5122 				rx_lfc_mode, "on#off");
5123 cmdline_parse_token_string_t cmd_lfc_set_tx =
5124 	TOKEN_STRING_INITIALIZER(struct cmd_link_flow_ctrl_set_result,
5125 				tx, "tx");
5126 cmdline_parse_token_string_t cmd_lfc_set_tx_mode =
5127 	TOKEN_STRING_INITIALIZER(struct cmd_link_flow_ctrl_set_result,
5128 				tx_lfc_mode, "on#off");
5129 cmdline_parse_token_string_t cmd_lfc_set_high_water_str =
5130 	TOKEN_STRING_INITIALIZER(struct cmd_link_flow_ctrl_set_result,
5131 				hw_str, "high_water");
5132 cmdline_parse_token_num_t cmd_lfc_set_high_water =
5133 	TOKEN_NUM_INITIALIZER(struct cmd_link_flow_ctrl_set_result,
5134 				high_water, UINT32);
5135 cmdline_parse_token_string_t cmd_lfc_set_low_water_str =
5136 	TOKEN_STRING_INITIALIZER(struct cmd_link_flow_ctrl_set_result,
5137 				lw_str, "low_water");
5138 cmdline_parse_token_num_t cmd_lfc_set_low_water =
5139 	TOKEN_NUM_INITIALIZER(struct cmd_link_flow_ctrl_set_result,
5140 				low_water, UINT32);
5141 cmdline_parse_token_string_t cmd_lfc_set_pause_time_str =
5142 	TOKEN_STRING_INITIALIZER(struct cmd_link_flow_ctrl_set_result,
5143 				pt_str, "pause_time");
5144 cmdline_parse_token_num_t cmd_lfc_set_pause_time =
5145 	TOKEN_NUM_INITIALIZER(struct cmd_link_flow_ctrl_set_result,
5146 				pause_time, UINT16);
5147 cmdline_parse_token_string_t cmd_lfc_set_send_xon_str =
5148 	TOKEN_STRING_INITIALIZER(struct cmd_link_flow_ctrl_set_result,
5149 				xon_str, "send_xon");
5150 cmdline_parse_token_num_t cmd_lfc_set_send_xon =
5151 	TOKEN_NUM_INITIALIZER(struct cmd_link_flow_ctrl_set_result,
5152 				send_xon, UINT16);
5153 cmdline_parse_token_string_t cmd_lfc_set_mac_ctrl_frame_fwd_mode =
5154 	TOKEN_STRING_INITIALIZER(struct cmd_link_flow_ctrl_set_result,
5155 				mac_ctrl_frame_fwd, "mac_ctrl_frame_fwd");
5156 cmdline_parse_token_string_t cmd_lfc_set_mac_ctrl_frame_fwd =
5157 	TOKEN_STRING_INITIALIZER(struct cmd_link_flow_ctrl_set_result,
5158 				mac_ctrl_frame_fwd_mode, "on#off");
5159 cmdline_parse_token_string_t cmd_lfc_set_autoneg_str =
5160 	TOKEN_STRING_INITIALIZER(struct cmd_link_flow_ctrl_set_result,
5161 				autoneg_str, "autoneg");
5162 cmdline_parse_token_string_t cmd_lfc_set_autoneg =
5163 	TOKEN_STRING_INITIALIZER(struct cmd_link_flow_ctrl_set_result,
5164 				autoneg, "on#off");
5165 cmdline_parse_token_num_t cmd_lfc_set_portid =
5166 	TOKEN_NUM_INITIALIZER(struct cmd_link_flow_ctrl_set_result,
5167 				port_id, UINT8);
5168 
5169 /* forward declaration */
5170 static void
5171 cmd_link_flow_ctrl_set_parsed(void *parsed_result, struct cmdline *cl,
5172 			      void *data);
5173 
5174 cmdline_parse_inst_t cmd_link_flow_control_set = {
5175 	.f = cmd_link_flow_ctrl_set_parsed,
5176 	.data = NULL,
5177 	.help_str = "set flow_ctrl rx on|off tx on|off <high_water> "
5178 		"<low_water> <pause_time> <send_xon> mac_ctrl_frame_fwd on|off "
5179 		"autoneg on|off <port_id>: Configure the Ethernet flow control",
5180 	.tokens = {
5181 		(void *)&cmd_lfc_set_set,
5182 		(void *)&cmd_lfc_set_flow_ctrl,
5183 		(void *)&cmd_lfc_set_rx,
5184 		(void *)&cmd_lfc_set_rx_mode,
5185 		(void *)&cmd_lfc_set_tx,
5186 		(void *)&cmd_lfc_set_tx_mode,
5187 		(void *)&cmd_lfc_set_high_water,
5188 		(void *)&cmd_lfc_set_low_water,
5189 		(void *)&cmd_lfc_set_pause_time,
5190 		(void *)&cmd_lfc_set_send_xon,
5191 		(void *)&cmd_lfc_set_mac_ctrl_frame_fwd_mode,
5192 		(void *)&cmd_lfc_set_mac_ctrl_frame_fwd,
5193 		(void *)&cmd_lfc_set_autoneg_str,
5194 		(void *)&cmd_lfc_set_autoneg,
5195 		(void *)&cmd_lfc_set_portid,
5196 		NULL,
5197 	},
5198 };
5199 
5200 cmdline_parse_inst_t cmd_link_flow_control_set_rx = {
5201 	.f = cmd_link_flow_ctrl_set_parsed,
5202 	.data = (void *)&cmd_link_flow_control_set_rx,
5203 	.help_str = "set flow_ctrl rx on|off <port_id>: "
5204 		"Change rx flow control parameter",
5205 	.tokens = {
5206 		(void *)&cmd_lfc_set_set,
5207 		(void *)&cmd_lfc_set_flow_ctrl,
5208 		(void *)&cmd_lfc_set_rx,
5209 		(void *)&cmd_lfc_set_rx_mode,
5210 		(void *)&cmd_lfc_set_portid,
5211 		NULL,
5212 	},
5213 };
5214 
5215 cmdline_parse_inst_t cmd_link_flow_control_set_tx = {
5216 	.f = cmd_link_flow_ctrl_set_parsed,
5217 	.data = (void *)&cmd_link_flow_control_set_tx,
5218 	.help_str = "set flow_ctrl tx on|off <port_id>: "
5219 		"Change tx flow control parameter",
5220 	.tokens = {
5221 		(void *)&cmd_lfc_set_set,
5222 		(void *)&cmd_lfc_set_flow_ctrl,
5223 		(void *)&cmd_lfc_set_tx,
5224 		(void *)&cmd_lfc_set_tx_mode,
5225 		(void *)&cmd_lfc_set_portid,
5226 		NULL,
5227 	},
5228 };
5229 
5230 cmdline_parse_inst_t cmd_link_flow_control_set_hw = {
5231 	.f = cmd_link_flow_ctrl_set_parsed,
5232 	.data = (void *)&cmd_link_flow_control_set_hw,
5233 	.help_str = "set flow_ctrl high_water <value> <port_id>: "
5234 		"Change high water flow control parameter",
5235 	.tokens = {
5236 		(void *)&cmd_lfc_set_set,
5237 		(void *)&cmd_lfc_set_flow_ctrl,
5238 		(void *)&cmd_lfc_set_high_water_str,
5239 		(void *)&cmd_lfc_set_high_water,
5240 		(void *)&cmd_lfc_set_portid,
5241 		NULL,
5242 	},
5243 };
5244 
5245 cmdline_parse_inst_t cmd_link_flow_control_set_lw = {
5246 	.f = cmd_link_flow_ctrl_set_parsed,
5247 	.data = (void *)&cmd_link_flow_control_set_lw,
5248 	.help_str = "set flow_ctrl low_water <value> <port_id>: "
5249 		"Change low water flow control parameter",
5250 	.tokens = {
5251 		(void *)&cmd_lfc_set_set,
5252 		(void *)&cmd_lfc_set_flow_ctrl,
5253 		(void *)&cmd_lfc_set_low_water_str,
5254 		(void *)&cmd_lfc_set_low_water,
5255 		(void *)&cmd_lfc_set_portid,
5256 		NULL,
5257 	},
5258 };
5259 
5260 cmdline_parse_inst_t cmd_link_flow_control_set_pt = {
5261 	.f = cmd_link_flow_ctrl_set_parsed,
5262 	.data = (void *)&cmd_link_flow_control_set_pt,
5263 	.help_str = "set flow_ctrl pause_time <value> <port_id>: "
5264 		"Change pause time flow control parameter",
5265 	.tokens = {
5266 		(void *)&cmd_lfc_set_set,
5267 		(void *)&cmd_lfc_set_flow_ctrl,
5268 		(void *)&cmd_lfc_set_pause_time_str,
5269 		(void *)&cmd_lfc_set_pause_time,
5270 		(void *)&cmd_lfc_set_portid,
5271 		NULL,
5272 	},
5273 };
5274 
5275 cmdline_parse_inst_t cmd_link_flow_control_set_xon = {
5276 	.f = cmd_link_flow_ctrl_set_parsed,
5277 	.data = (void *)&cmd_link_flow_control_set_xon,
5278 	.help_str = "set flow_ctrl send_xon <value> <port_id>: "
5279 		"Change send_xon flow control parameter",
5280 	.tokens = {
5281 		(void *)&cmd_lfc_set_set,
5282 		(void *)&cmd_lfc_set_flow_ctrl,
5283 		(void *)&cmd_lfc_set_send_xon_str,
5284 		(void *)&cmd_lfc_set_send_xon,
5285 		(void *)&cmd_lfc_set_portid,
5286 		NULL,
5287 	},
5288 };
5289 
5290 cmdline_parse_inst_t cmd_link_flow_control_set_macfwd = {
5291 	.f = cmd_link_flow_ctrl_set_parsed,
5292 	.data = (void *)&cmd_link_flow_control_set_macfwd,
5293 	.help_str = "set flow_ctrl mac_ctrl_frame_fwd on|off <port_id>: "
5294 		"Change mac ctrl fwd flow control parameter",
5295 	.tokens = {
5296 		(void *)&cmd_lfc_set_set,
5297 		(void *)&cmd_lfc_set_flow_ctrl,
5298 		(void *)&cmd_lfc_set_mac_ctrl_frame_fwd_mode,
5299 		(void *)&cmd_lfc_set_mac_ctrl_frame_fwd,
5300 		(void *)&cmd_lfc_set_portid,
5301 		NULL,
5302 	},
5303 };
5304 
5305 cmdline_parse_inst_t cmd_link_flow_control_set_autoneg = {
5306 	.f = cmd_link_flow_ctrl_set_parsed,
5307 	.data = (void *)&cmd_link_flow_control_set_autoneg,
5308 	.help_str = "set flow_ctrl autoneg on|off <port_id>: "
5309 		"Change autoneg flow control parameter",
5310 	.tokens = {
5311 		(void *)&cmd_lfc_set_set,
5312 		(void *)&cmd_lfc_set_flow_ctrl,
5313 		(void *)&cmd_lfc_set_autoneg_str,
5314 		(void *)&cmd_lfc_set_autoneg,
5315 		(void *)&cmd_lfc_set_portid,
5316 		NULL,
5317 	},
5318 };
5319 
5320 static void
5321 cmd_link_flow_ctrl_set_parsed(void *parsed_result,
5322 			      __attribute__((unused)) struct cmdline *cl,
5323 			      void *data)
5324 {
5325 	struct cmd_link_flow_ctrl_set_result *res = parsed_result;
5326 	cmdline_parse_inst_t *cmd = data;
5327 	struct rte_eth_fc_conf fc_conf;
5328 	int rx_fc_en = 0;
5329 	int tx_fc_en = 0;
5330 	int ret;
5331 
5332 	/*
5333 	 * Rx on/off, flow control is enabled/disabled on RX side. This can indicate
5334 	 * the RTE_FC_TX_PAUSE, Transmit pause frame at the Rx side.
5335 	 * Tx on/off, flow control is enabled/disabled on TX side. This can indicate
5336 	 * the RTE_FC_RX_PAUSE, Respond to the pause frame at the Tx side.
5337 	 */
5338 	static enum rte_eth_fc_mode rx_tx_onoff_2_lfc_mode[2][2] = {
5339 			{RTE_FC_NONE, RTE_FC_TX_PAUSE}, {RTE_FC_RX_PAUSE, RTE_FC_FULL}
5340 	};
5341 
5342 	/* Partial command line, retrieve current configuration */
5343 	if (cmd) {
5344 		ret = rte_eth_dev_flow_ctrl_get(res->port_id, &fc_conf);
5345 		if (ret != 0) {
5346 			printf("cannot get current flow ctrl parameters, return"
5347 			       "code = %d\n", ret);
5348 			return;
5349 		}
5350 
5351 		if ((fc_conf.mode == RTE_FC_RX_PAUSE) ||
5352 		    (fc_conf.mode == RTE_FC_FULL))
5353 			rx_fc_en = 1;
5354 		if ((fc_conf.mode == RTE_FC_TX_PAUSE) ||
5355 		    (fc_conf.mode == RTE_FC_FULL))
5356 			tx_fc_en = 1;
5357 	}
5358 
5359 	if (!cmd || cmd == &cmd_link_flow_control_set_rx)
5360 		rx_fc_en = (!strcmp(res->rx_lfc_mode, "on")) ? 1 : 0;
5361 
5362 	if (!cmd || cmd == &cmd_link_flow_control_set_tx)
5363 		tx_fc_en = (!strcmp(res->tx_lfc_mode, "on")) ? 1 : 0;
5364 
5365 	fc_conf.mode = rx_tx_onoff_2_lfc_mode[rx_fc_en][tx_fc_en];
5366 
5367 	if (!cmd || cmd == &cmd_link_flow_control_set_hw)
5368 		fc_conf.high_water = res->high_water;
5369 
5370 	if (!cmd || cmd == &cmd_link_flow_control_set_lw)
5371 		fc_conf.low_water = res->low_water;
5372 
5373 	if (!cmd || cmd == &cmd_link_flow_control_set_pt)
5374 		fc_conf.pause_time = res->pause_time;
5375 
5376 	if (!cmd || cmd == &cmd_link_flow_control_set_xon)
5377 		fc_conf.send_xon = res->send_xon;
5378 
5379 	if (!cmd || cmd == &cmd_link_flow_control_set_macfwd) {
5380 		if (!strcmp(res->mac_ctrl_frame_fwd_mode, "on"))
5381 			fc_conf.mac_ctrl_frame_fwd = 1;
5382 		else
5383 			fc_conf.mac_ctrl_frame_fwd = 0;
5384 	}
5385 
5386 	if (!cmd || cmd == &cmd_link_flow_control_set_autoneg)
5387 		fc_conf.autoneg = (!strcmp(res->autoneg, "on")) ? 1 : 0;
5388 
5389 	ret = rte_eth_dev_flow_ctrl_set(res->port_id, &fc_conf);
5390 	if (ret != 0)
5391 		printf("bad flow contrl parameter, return code = %d \n", ret);
5392 }
5393 
5394 /* *** SETUP ETHERNET PIRORITY FLOW CONTROL *** */
5395 struct cmd_priority_flow_ctrl_set_result {
5396 	cmdline_fixed_string_t set;
5397 	cmdline_fixed_string_t pfc_ctrl;
5398 	cmdline_fixed_string_t rx;
5399 	cmdline_fixed_string_t rx_pfc_mode;
5400 	cmdline_fixed_string_t tx;
5401 	cmdline_fixed_string_t tx_pfc_mode;
5402 	uint32_t high_water;
5403 	uint32_t low_water;
5404 	uint16_t pause_time;
5405 	uint8_t  priority;
5406 	uint8_t  port_id;
5407 };
5408 
5409 static void
5410 cmd_priority_flow_ctrl_set_parsed(void *parsed_result,
5411 		       __attribute__((unused)) struct cmdline *cl,
5412 		       __attribute__((unused)) void *data)
5413 {
5414 	struct cmd_priority_flow_ctrl_set_result *res = parsed_result;
5415 	struct rte_eth_pfc_conf pfc_conf;
5416 	int rx_fc_enable, tx_fc_enable;
5417 	int ret;
5418 
5419 	/*
5420 	 * Rx on/off, flow control is enabled/disabled on RX side. This can indicate
5421 	 * the RTE_FC_TX_PAUSE, Transmit pause frame at the Rx side.
5422 	 * Tx on/off, flow control is enabled/disabled on TX side. This can indicate
5423 	 * the RTE_FC_RX_PAUSE, Respond to the pause frame at the Tx side.
5424 	 */
5425 	static enum rte_eth_fc_mode rx_tx_onoff_2_pfc_mode[2][2] = {
5426 			{RTE_FC_NONE, RTE_FC_RX_PAUSE}, {RTE_FC_TX_PAUSE, RTE_FC_FULL}
5427 	};
5428 
5429 	rx_fc_enable = (!strncmp(res->rx_pfc_mode, "on",2)) ? 1 : 0;
5430 	tx_fc_enable = (!strncmp(res->tx_pfc_mode, "on",2)) ? 1 : 0;
5431 	pfc_conf.fc.mode       = rx_tx_onoff_2_pfc_mode[rx_fc_enable][tx_fc_enable];
5432 	pfc_conf.fc.high_water = res->high_water;
5433 	pfc_conf.fc.low_water  = res->low_water;
5434 	pfc_conf.fc.pause_time = res->pause_time;
5435 	pfc_conf.priority      = res->priority;
5436 
5437 	ret = rte_eth_dev_priority_flow_ctrl_set(res->port_id, &pfc_conf);
5438 	if (ret != 0)
5439 		printf("bad priority flow contrl parameter, return code = %d \n", ret);
5440 }
5441 
5442 cmdline_parse_token_string_t cmd_pfc_set_set =
5443 	TOKEN_STRING_INITIALIZER(struct cmd_priority_flow_ctrl_set_result,
5444 				set, "set");
5445 cmdline_parse_token_string_t cmd_pfc_set_flow_ctrl =
5446 	TOKEN_STRING_INITIALIZER(struct cmd_priority_flow_ctrl_set_result,
5447 				pfc_ctrl, "pfc_ctrl");
5448 cmdline_parse_token_string_t cmd_pfc_set_rx =
5449 	TOKEN_STRING_INITIALIZER(struct cmd_priority_flow_ctrl_set_result,
5450 				rx, "rx");
5451 cmdline_parse_token_string_t cmd_pfc_set_rx_mode =
5452 	TOKEN_STRING_INITIALIZER(struct cmd_priority_flow_ctrl_set_result,
5453 				rx_pfc_mode, "on#off");
5454 cmdline_parse_token_string_t cmd_pfc_set_tx =
5455 	TOKEN_STRING_INITIALIZER(struct cmd_priority_flow_ctrl_set_result,
5456 				tx, "tx");
5457 cmdline_parse_token_string_t cmd_pfc_set_tx_mode =
5458 	TOKEN_STRING_INITIALIZER(struct cmd_priority_flow_ctrl_set_result,
5459 				tx_pfc_mode, "on#off");
5460 cmdline_parse_token_num_t cmd_pfc_set_high_water =
5461 	TOKEN_NUM_INITIALIZER(struct cmd_priority_flow_ctrl_set_result,
5462 				high_water, UINT32);
5463 cmdline_parse_token_num_t cmd_pfc_set_low_water =
5464 	TOKEN_NUM_INITIALIZER(struct cmd_priority_flow_ctrl_set_result,
5465 				low_water, UINT32);
5466 cmdline_parse_token_num_t cmd_pfc_set_pause_time =
5467 	TOKEN_NUM_INITIALIZER(struct cmd_priority_flow_ctrl_set_result,
5468 				pause_time, UINT16);
5469 cmdline_parse_token_num_t cmd_pfc_set_priority =
5470 	TOKEN_NUM_INITIALIZER(struct cmd_priority_flow_ctrl_set_result,
5471 				priority, UINT8);
5472 cmdline_parse_token_num_t cmd_pfc_set_portid =
5473 	TOKEN_NUM_INITIALIZER(struct cmd_priority_flow_ctrl_set_result,
5474 				port_id, UINT8);
5475 
5476 cmdline_parse_inst_t cmd_priority_flow_control_set = {
5477 	.f = cmd_priority_flow_ctrl_set_parsed,
5478 	.data = NULL,
5479 	.help_str = "set pfc_ctrl rx on|off tx on|off <high_water> <low_water> "
5480 		"<pause_time> <priority> <port_id>: "
5481 		"Configure the Ethernet priority flow control",
5482 	.tokens = {
5483 		(void *)&cmd_pfc_set_set,
5484 		(void *)&cmd_pfc_set_flow_ctrl,
5485 		(void *)&cmd_pfc_set_rx,
5486 		(void *)&cmd_pfc_set_rx_mode,
5487 		(void *)&cmd_pfc_set_tx,
5488 		(void *)&cmd_pfc_set_tx_mode,
5489 		(void *)&cmd_pfc_set_high_water,
5490 		(void *)&cmd_pfc_set_low_water,
5491 		(void *)&cmd_pfc_set_pause_time,
5492 		(void *)&cmd_pfc_set_priority,
5493 		(void *)&cmd_pfc_set_portid,
5494 		NULL,
5495 	},
5496 };
5497 
5498 /* *** RESET CONFIGURATION *** */
5499 struct cmd_reset_result {
5500 	cmdline_fixed_string_t reset;
5501 	cmdline_fixed_string_t def;
5502 };
5503 
5504 static void cmd_reset_parsed(__attribute__((unused)) void *parsed_result,
5505 			     struct cmdline *cl,
5506 			     __attribute__((unused)) void *data)
5507 {
5508 	cmdline_printf(cl, "Reset to default forwarding configuration...\n");
5509 	set_def_fwd_config();
5510 }
5511 
5512 cmdline_parse_token_string_t cmd_reset_set =
5513 	TOKEN_STRING_INITIALIZER(struct cmd_reset_result, reset, "set");
5514 cmdline_parse_token_string_t cmd_reset_def =
5515 	TOKEN_STRING_INITIALIZER(struct cmd_reset_result, def,
5516 				 "default");
5517 
5518 cmdline_parse_inst_t cmd_reset = {
5519 	.f = cmd_reset_parsed,
5520 	.data = NULL,
5521 	.help_str = "set default: Reset default forwarding configuration",
5522 	.tokens = {
5523 		(void *)&cmd_reset_set,
5524 		(void *)&cmd_reset_def,
5525 		NULL,
5526 	},
5527 };
5528 
5529 /* *** START FORWARDING *** */
5530 struct cmd_start_result {
5531 	cmdline_fixed_string_t start;
5532 };
5533 
5534 cmdline_parse_token_string_t cmd_start_start =
5535 	TOKEN_STRING_INITIALIZER(struct cmd_start_result, start, "start");
5536 
5537 static void cmd_start_parsed(__attribute__((unused)) void *parsed_result,
5538 			     __attribute__((unused)) struct cmdline *cl,
5539 			     __attribute__((unused)) void *data)
5540 {
5541 	start_packet_forwarding(0);
5542 }
5543 
5544 cmdline_parse_inst_t cmd_start = {
5545 	.f = cmd_start_parsed,
5546 	.data = NULL,
5547 	.help_str = "start: Start packet forwarding",
5548 	.tokens = {
5549 		(void *)&cmd_start_start,
5550 		NULL,
5551 	},
5552 };
5553 
5554 /* *** START FORWARDING WITH ONE TX BURST FIRST *** */
5555 struct cmd_start_tx_first_result {
5556 	cmdline_fixed_string_t start;
5557 	cmdline_fixed_string_t tx_first;
5558 };
5559 
5560 static void
5561 cmd_start_tx_first_parsed(__attribute__((unused)) void *parsed_result,
5562 			  __attribute__((unused)) struct cmdline *cl,
5563 			  __attribute__((unused)) void *data)
5564 {
5565 	start_packet_forwarding(1);
5566 }
5567 
5568 cmdline_parse_token_string_t cmd_start_tx_first_start =
5569 	TOKEN_STRING_INITIALIZER(struct cmd_start_tx_first_result, start,
5570 				 "start");
5571 cmdline_parse_token_string_t cmd_start_tx_first_tx_first =
5572 	TOKEN_STRING_INITIALIZER(struct cmd_start_tx_first_result,
5573 				 tx_first, "tx_first");
5574 
5575 cmdline_parse_inst_t cmd_start_tx_first = {
5576 	.f = cmd_start_tx_first_parsed,
5577 	.data = NULL,
5578 	.help_str = "start tx_first: Start packet forwarding, "
5579 		"after sending 1 burst of packets",
5580 	.tokens = {
5581 		(void *)&cmd_start_tx_first_start,
5582 		(void *)&cmd_start_tx_first_tx_first,
5583 		NULL,
5584 	},
5585 };
5586 
5587 /* *** START FORWARDING WITH N TX BURST FIRST *** */
5588 struct cmd_start_tx_first_n_result {
5589 	cmdline_fixed_string_t start;
5590 	cmdline_fixed_string_t tx_first;
5591 	uint32_t tx_num;
5592 };
5593 
5594 static void
5595 cmd_start_tx_first_n_parsed(void *parsed_result,
5596 			  __attribute__((unused)) struct cmdline *cl,
5597 			  __attribute__((unused)) void *data)
5598 {
5599 	struct cmd_start_tx_first_n_result *res = parsed_result;
5600 
5601 	start_packet_forwarding(res->tx_num);
5602 }
5603 
5604 cmdline_parse_token_string_t cmd_start_tx_first_n_start =
5605 	TOKEN_STRING_INITIALIZER(struct cmd_start_tx_first_n_result,
5606 			start, "start");
5607 cmdline_parse_token_string_t cmd_start_tx_first_n_tx_first =
5608 	TOKEN_STRING_INITIALIZER(struct cmd_start_tx_first_n_result,
5609 			tx_first, "tx_first");
5610 cmdline_parse_token_num_t cmd_start_tx_first_n_tx_num =
5611 	TOKEN_NUM_INITIALIZER(struct cmd_start_tx_first_n_result,
5612 			tx_num, UINT32);
5613 
5614 cmdline_parse_inst_t cmd_start_tx_first_n = {
5615 	.f = cmd_start_tx_first_n_parsed,
5616 	.data = NULL,
5617 	.help_str = "start tx_first <num>: "
5618 		"packet forwarding, after sending <num> bursts of packets",
5619 	.tokens = {
5620 		(void *)&cmd_start_tx_first_n_start,
5621 		(void *)&cmd_start_tx_first_n_tx_first,
5622 		(void *)&cmd_start_tx_first_n_tx_num,
5623 		NULL,
5624 	},
5625 };
5626 
5627 /* *** SET LINK UP *** */
5628 struct cmd_set_link_up_result {
5629 	cmdline_fixed_string_t set;
5630 	cmdline_fixed_string_t link_up;
5631 	cmdline_fixed_string_t port;
5632 	uint8_t port_id;
5633 };
5634 
5635 cmdline_parse_token_string_t cmd_set_link_up_set =
5636 	TOKEN_STRING_INITIALIZER(struct cmd_set_link_up_result, set, "set");
5637 cmdline_parse_token_string_t cmd_set_link_up_link_up =
5638 	TOKEN_STRING_INITIALIZER(struct cmd_set_link_up_result, link_up,
5639 				"link-up");
5640 cmdline_parse_token_string_t cmd_set_link_up_port =
5641 	TOKEN_STRING_INITIALIZER(struct cmd_set_link_up_result, port, "port");
5642 cmdline_parse_token_num_t cmd_set_link_up_port_id =
5643 	TOKEN_NUM_INITIALIZER(struct cmd_set_link_up_result, port_id, UINT8);
5644 
5645 static void cmd_set_link_up_parsed(__attribute__((unused)) void *parsed_result,
5646 			     __attribute__((unused)) struct cmdline *cl,
5647 			     __attribute__((unused)) void *data)
5648 {
5649 	struct cmd_set_link_up_result *res = parsed_result;
5650 	dev_set_link_up(res->port_id);
5651 }
5652 
5653 cmdline_parse_inst_t cmd_set_link_up = {
5654 	.f = cmd_set_link_up_parsed,
5655 	.data = NULL,
5656 	.help_str = "set link-up port <port id>",
5657 	.tokens = {
5658 		(void *)&cmd_set_link_up_set,
5659 		(void *)&cmd_set_link_up_link_up,
5660 		(void *)&cmd_set_link_up_port,
5661 		(void *)&cmd_set_link_up_port_id,
5662 		NULL,
5663 	},
5664 };
5665 
5666 /* *** SET LINK DOWN *** */
5667 struct cmd_set_link_down_result {
5668 	cmdline_fixed_string_t set;
5669 	cmdline_fixed_string_t link_down;
5670 	cmdline_fixed_string_t port;
5671 	uint8_t port_id;
5672 };
5673 
5674 cmdline_parse_token_string_t cmd_set_link_down_set =
5675 	TOKEN_STRING_INITIALIZER(struct cmd_set_link_down_result, set, "set");
5676 cmdline_parse_token_string_t cmd_set_link_down_link_down =
5677 	TOKEN_STRING_INITIALIZER(struct cmd_set_link_down_result, link_down,
5678 				"link-down");
5679 cmdline_parse_token_string_t cmd_set_link_down_port =
5680 	TOKEN_STRING_INITIALIZER(struct cmd_set_link_down_result, port, "port");
5681 cmdline_parse_token_num_t cmd_set_link_down_port_id =
5682 	TOKEN_NUM_INITIALIZER(struct cmd_set_link_down_result, port_id, UINT8);
5683 
5684 static void cmd_set_link_down_parsed(
5685 				__attribute__((unused)) void *parsed_result,
5686 				__attribute__((unused)) struct cmdline *cl,
5687 				__attribute__((unused)) void *data)
5688 {
5689 	struct cmd_set_link_down_result *res = parsed_result;
5690 	dev_set_link_down(res->port_id);
5691 }
5692 
5693 cmdline_parse_inst_t cmd_set_link_down = {
5694 	.f = cmd_set_link_down_parsed,
5695 	.data = NULL,
5696 	.help_str = "set link-down port <port id>",
5697 	.tokens = {
5698 		(void *)&cmd_set_link_down_set,
5699 		(void *)&cmd_set_link_down_link_down,
5700 		(void *)&cmd_set_link_down_port,
5701 		(void *)&cmd_set_link_down_port_id,
5702 		NULL,
5703 	},
5704 };
5705 
5706 /* *** SHOW CFG *** */
5707 struct cmd_showcfg_result {
5708 	cmdline_fixed_string_t show;
5709 	cmdline_fixed_string_t cfg;
5710 	cmdline_fixed_string_t what;
5711 };
5712 
5713 static void cmd_showcfg_parsed(void *parsed_result,
5714 			       __attribute__((unused)) struct cmdline *cl,
5715 			       __attribute__((unused)) void *data)
5716 {
5717 	struct cmd_showcfg_result *res = parsed_result;
5718 	if (!strcmp(res->what, "rxtx"))
5719 		rxtx_config_display();
5720 	else if (!strcmp(res->what, "cores"))
5721 		fwd_lcores_config_display();
5722 	else if (!strcmp(res->what, "fwd"))
5723 		pkt_fwd_config_display(&cur_fwd_config);
5724 	else if (!strcmp(res->what, "txpkts"))
5725 		show_tx_pkt_segments();
5726 }
5727 
5728 cmdline_parse_token_string_t cmd_showcfg_show =
5729 	TOKEN_STRING_INITIALIZER(struct cmd_showcfg_result, show, "show");
5730 cmdline_parse_token_string_t cmd_showcfg_port =
5731 	TOKEN_STRING_INITIALIZER(struct cmd_showcfg_result, cfg, "config");
5732 cmdline_parse_token_string_t cmd_showcfg_what =
5733 	TOKEN_STRING_INITIALIZER(struct cmd_showcfg_result, what,
5734 				 "rxtx#cores#fwd#txpkts");
5735 
5736 cmdline_parse_inst_t cmd_showcfg = {
5737 	.f = cmd_showcfg_parsed,
5738 	.data = NULL,
5739 	.help_str = "show config rxtx|cores|fwd|txpkts",
5740 	.tokens = {
5741 		(void *)&cmd_showcfg_show,
5742 		(void *)&cmd_showcfg_port,
5743 		(void *)&cmd_showcfg_what,
5744 		NULL,
5745 	},
5746 };
5747 
5748 /* *** SHOW ALL PORT INFO *** */
5749 struct cmd_showportall_result {
5750 	cmdline_fixed_string_t show;
5751 	cmdline_fixed_string_t port;
5752 	cmdline_fixed_string_t what;
5753 	cmdline_fixed_string_t all;
5754 };
5755 
5756 static void cmd_showportall_parsed(void *parsed_result,
5757 				__attribute__((unused)) struct cmdline *cl,
5758 				__attribute__((unused)) void *data)
5759 {
5760 	portid_t i;
5761 
5762 	struct cmd_showportall_result *res = parsed_result;
5763 	if (!strcmp(res->show, "clear")) {
5764 		if (!strcmp(res->what, "stats"))
5765 			FOREACH_PORT(i, ports)
5766 				nic_stats_clear(i);
5767 		else if (!strcmp(res->what, "xstats"))
5768 			FOREACH_PORT(i, ports)
5769 				nic_xstats_clear(i);
5770 	} else if (!strcmp(res->what, "info"))
5771 		FOREACH_PORT(i, ports)
5772 			port_infos_display(i);
5773 	else if (!strcmp(res->what, "stats"))
5774 		FOREACH_PORT(i, ports)
5775 			nic_stats_display(i);
5776 	else if (!strcmp(res->what, "xstats"))
5777 		FOREACH_PORT(i, ports)
5778 			nic_xstats_display(i);
5779 	else if (!strcmp(res->what, "fdir"))
5780 		FOREACH_PORT(i, ports)
5781 			fdir_get_infos(i);
5782 	else if (!strcmp(res->what, "stat_qmap"))
5783 		FOREACH_PORT(i, ports)
5784 			nic_stats_mapping_display(i);
5785 	else if (!strcmp(res->what, "dcb_tc"))
5786 		FOREACH_PORT(i, ports)
5787 			port_dcb_info_display(i);
5788 }
5789 
5790 cmdline_parse_token_string_t cmd_showportall_show =
5791 	TOKEN_STRING_INITIALIZER(struct cmd_showportall_result, show,
5792 				 "show#clear");
5793 cmdline_parse_token_string_t cmd_showportall_port =
5794 	TOKEN_STRING_INITIALIZER(struct cmd_showportall_result, port, "port");
5795 cmdline_parse_token_string_t cmd_showportall_what =
5796 	TOKEN_STRING_INITIALIZER(struct cmd_showportall_result, what,
5797 				 "info#stats#xstats#fdir#stat_qmap#dcb_tc");
5798 cmdline_parse_token_string_t cmd_showportall_all =
5799 	TOKEN_STRING_INITIALIZER(struct cmd_showportall_result, all, "all");
5800 cmdline_parse_inst_t cmd_showportall = {
5801 	.f = cmd_showportall_parsed,
5802 	.data = NULL,
5803 	.help_str = "show|clear port info|stats|xstats|fdir|stat_qmap|dcb_tc all",
5804 	.tokens = {
5805 		(void *)&cmd_showportall_show,
5806 		(void *)&cmd_showportall_port,
5807 		(void *)&cmd_showportall_what,
5808 		(void *)&cmd_showportall_all,
5809 		NULL,
5810 	},
5811 };
5812 
5813 /* *** SHOW PORT INFO *** */
5814 struct cmd_showport_result {
5815 	cmdline_fixed_string_t show;
5816 	cmdline_fixed_string_t port;
5817 	cmdline_fixed_string_t what;
5818 	uint8_t portnum;
5819 };
5820 
5821 static void cmd_showport_parsed(void *parsed_result,
5822 				__attribute__((unused)) struct cmdline *cl,
5823 				__attribute__((unused)) void *data)
5824 {
5825 	struct cmd_showport_result *res = parsed_result;
5826 	if (!strcmp(res->show, "clear")) {
5827 		if (!strcmp(res->what, "stats"))
5828 			nic_stats_clear(res->portnum);
5829 		else if (!strcmp(res->what, "xstats"))
5830 			nic_xstats_clear(res->portnum);
5831 	} else if (!strcmp(res->what, "info"))
5832 		port_infos_display(res->portnum);
5833 	else if (!strcmp(res->what, "stats"))
5834 		nic_stats_display(res->portnum);
5835 	else if (!strcmp(res->what, "xstats"))
5836 		nic_xstats_display(res->portnum);
5837 	else if (!strcmp(res->what, "fdir"))
5838 		 fdir_get_infos(res->portnum);
5839 	else if (!strcmp(res->what, "stat_qmap"))
5840 		nic_stats_mapping_display(res->portnum);
5841 	else if (!strcmp(res->what, "dcb_tc"))
5842 		port_dcb_info_display(res->portnum);
5843 }
5844 
5845 cmdline_parse_token_string_t cmd_showport_show =
5846 	TOKEN_STRING_INITIALIZER(struct cmd_showport_result, show,
5847 				 "show#clear");
5848 cmdline_parse_token_string_t cmd_showport_port =
5849 	TOKEN_STRING_INITIALIZER(struct cmd_showport_result, port, "port");
5850 cmdline_parse_token_string_t cmd_showport_what =
5851 	TOKEN_STRING_INITIALIZER(struct cmd_showport_result, what,
5852 				 "info#stats#xstats#fdir#stat_qmap#dcb_tc");
5853 cmdline_parse_token_num_t cmd_showport_portnum =
5854 	TOKEN_NUM_INITIALIZER(struct cmd_showport_result, portnum, UINT8);
5855 
5856 cmdline_parse_inst_t cmd_showport = {
5857 	.f = cmd_showport_parsed,
5858 	.data = NULL,
5859 	.help_str = "show|clear port info|stats|xstats|fdir|stat_qmap|dcb_tc "
5860 		"<port_id>",
5861 	.tokens = {
5862 		(void *)&cmd_showport_show,
5863 		(void *)&cmd_showport_port,
5864 		(void *)&cmd_showport_what,
5865 		(void *)&cmd_showport_portnum,
5866 		NULL,
5867 	},
5868 };
5869 
5870 /* *** SHOW QUEUE INFO *** */
5871 struct cmd_showqueue_result {
5872 	cmdline_fixed_string_t show;
5873 	cmdline_fixed_string_t type;
5874 	cmdline_fixed_string_t what;
5875 	uint8_t portnum;
5876 	uint16_t queuenum;
5877 };
5878 
5879 static void
5880 cmd_showqueue_parsed(void *parsed_result,
5881 	__attribute__((unused)) struct cmdline *cl,
5882 	__attribute__((unused)) void *data)
5883 {
5884 	struct cmd_showqueue_result *res = parsed_result;
5885 
5886 	if (!strcmp(res->type, "rxq"))
5887 		rx_queue_infos_display(res->portnum, res->queuenum);
5888 	else if (!strcmp(res->type, "txq"))
5889 		tx_queue_infos_display(res->portnum, res->queuenum);
5890 }
5891 
5892 cmdline_parse_token_string_t cmd_showqueue_show =
5893 	TOKEN_STRING_INITIALIZER(struct cmd_showqueue_result, show, "show");
5894 cmdline_parse_token_string_t cmd_showqueue_type =
5895 	TOKEN_STRING_INITIALIZER(struct cmd_showqueue_result, type, "rxq#txq");
5896 cmdline_parse_token_string_t cmd_showqueue_what =
5897 	TOKEN_STRING_INITIALIZER(struct cmd_showqueue_result, what, "info");
5898 cmdline_parse_token_num_t cmd_showqueue_portnum =
5899 	TOKEN_NUM_INITIALIZER(struct cmd_showqueue_result, portnum, UINT8);
5900 cmdline_parse_token_num_t cmd_showqueue_queuenum =
5901 	TOKEN_NUM_INITIALIZER(struct cmd_showqueue_result, queuenum, UINT16);
5902 
5903 cmdline_parse_inst_t cmd_showqueue = {
5904 	.f = cmd_showqueue_parsed,
5905 	.data = NULL,
5906 	.help_str = "show rxq|txq info <port_id> <queue_id>",
5907 	.tokens = {
5908 		(void *)&cmd_showqueue_show,
5909 		(void *)&cmd_showqueue_type,
5910 		(void *)&cmd_showqueue_what,
5911 		(void *)&cmd_showqueue_portnum,
5912 		(void *)&cmd_showqueue_queuenum,
5913 		NULL,
5914 	},
5915 };
5916 
5917 /* *** READ PORT REGISTER *** */
5918 struct cmd_read_reg_result {
5919 	cmdline_fixed_string_t read;
5920 	cmdline_fixed_string_t reg;
5921 	uint8_t port_id;
5922 	uint32_t reg_off;
5923 };
5924 
5925 static void
5926 cmd_read_reg_parsed(void *parsed_result,
5927 		    __attribute__((unused)) struct cmdline *cl,
5928 		    __attribute__((unused)) void *data)
5929 {
5930 	struct cmd_read_reg_result *res = parsed_result;
5931 	port_reg_display(res->port_id, res->reg_off);
5932 }
5933 
5934 cmdline_parse_token_string_t cmd_read_reg_read =
5935 	TOKEN_STRING_INITIALIZER(struct cmd_read_reg_result, read, "read");
5936 cmdline_parse_token_string_t cmd_read_reg_reg =
5937 	TOKEN_STRING_INITIALIZER(struct cmd_read_reg_result, reg, "reg");
5938 cmdline_parse_token_num_t cmd_read_reg_port_id =
5939 	TOKEN_NUM_INITIALIZER(struct cmd_read_reg_result, port_id, UINT8);
5940 cmdline_parse_token_num_t cmd_read_reg_reg_off =
5941 	TOKEN_NUM_INITIALIZER(struct cmd_read_reg_result, reg_off, UINT32);
5942 
5943 cmdline_parse_inst_t cmd_read_reg = {
5944 	.f = cmd_read_reg_parsed,
5945 	.data = NULL,
5946 	.help_str = "read reg <port_id> <reg_off>",
5947 	.tokens = {
5948 		(void *)&cmd_read_reg_read,
5949 		(void *)&cmd_read_reg_reg,
5950 		(void *)&cmd_read_reg_port_id,
5951 		(void *)&cmd_read_reg_reg_off,
5952 		NULL,
5953 	},
5954 };
5955 
5956 /* *** READ PORT REGISTER BIT FIELD *** */
5957 struct cmd_read_reg_bit_field_result {
5958 	cmdline_fixed_string_t read;
5959 	cmdline_fixed_string_t regfield;
5960 	uint8_t port_id;
5961 	uint32_t reg_off;
5962 	uint8_t bit1_pos;
5963 	uint8_t bit2_pos;
5964 };
5965 
5966 static void
5967 cmd_read_reg_bit_field_parsed(void *parsed_result,
5968 			      __attribute__((unused)) struct cmdline *cl,
5969 			      __attribute__((unused)) void *data)
5970 {
5971 	struct cmd_read_reg_bit_field_result *res = parsed_result;
5972 	port_reg_bit_field_display(res->port_id, res->reg_off,
5973 				   res->bit1_pos, res->bit2_pos);
5974 }
5975 
5976 cmdline_parse_token_string_t cmd_read_reg_bit_field_read =
5977 	TOKEN_STRING_INITIALIZER(struct cmd_read_reg_bit_field_result, read,
5978 				 "read");
5979 cmdline_parse_token_string_t cmd_read_reg_bit_field_regfield =
5980 	TOKEN_STRING_INITIALIZER(struct cmd_read_reg_bit_field_result,
5981 				 regfield, "regfield");
5982 cmdline_parse_token_num_t cmd_read_reg_bit_field_port_id =
5983 	TOKEN_NUM_INITIALIZER(struct cmd_read_reg_bit_field_result, port_id,
5984 			      UINT8);
5985 cmdline_parse_token_num_t cmd_read_reg_bit_field_reg_off =
5986 	TOKEN_NUM_INITIALIZER(struct cmd_read_reg_bit_field_result, reg_off,
5987 			      UINT32);
5988 cmdline_parse_token_num_t cmd_read_reg_bit_field_bit1_pos =
5989 	TOKEN_NUM_INITIALIZER(struct cmd_read_reg_bit_field_result, bit1_pos,
5990 			      UINT8);
5991 cmdline_parse_token_num_t cmd_read_reg_bit_field_bit2_pos =
5992 	TOKEN_NUM_INITIALIZER(struct cmd_read_reg_bit_field_result, bit2_pos,
5993 			      UINT8);
5994 
5995 cmdline_parse_inst_t cmd_read_reg_bit_field = {
5996 	.f = cmd_read_reg_bit_field_parsed,
5997 	.data = NULL,
5998 	.help_str = "read regfield <port_id> <reg_off> <bit_x> <bit_y>: "
5999 	"Read register bit field between bit_x and bit_y included",
6000 	.tokens = {
6001 		(void *)&cmd_read_reg_bit_field_read,
6002 		(void *)&cmd_read_reg_bit_field_regfield,
6003 		(void *)&cmd_read_reg_bit_field_port_id,
6004 		(void *)&cmd_read_reg_bit_field_reg_off,
6005 		(void *)&cmd_read_reg_bit_field_bit1_pos,
6006 		(void *)&cmd_read_reg_bit_field_bit2_pos,
6007 		NULL,
6008 	},
6009 };
6010 
6011 /* *** READ PORT REGISTER BIT *** */
6012 struct cmd_read_reg_bit_result {
6013 	cmdline_fixed_string_t read;
6014 	cmdline_fixed_string_t regbit;
6015 	uint8_t port_id;
6016 	uint32_t reg_off;
6017 	uint8_t bit_pos;
6018 };
6019 
6020 static void
6021 cmd_read_reg_bit_parsed(void *parsed_result,
6022 			__attribute__((unused)) struct cmdline *cl,
6023 			__attribute__((unused)) void *data)
6024 {
6025 	struct cmd_read_reg_bit_result *res = parsed_result;
6026 	port_reg_bit_display(res->port_id, res->reg_off, res->bit_pos);
6027 }
6028 
6029 cmdline_parse_token_string_t cmd_read_reg_bit_read =
6030 	TOKEN_STRING_INITIALIZER(struct cmd_read_reg_bit_result, read, "read");
6031 cmdline_parse_token_string_t cmd_read_reg_bit_regbit =
6032 	TOKEN_STRING_INITIALIZER(struct cmd_read_reg_bit_result,
6033 				 regbit, "regbit");
6034 cmdline_parse_token_num_t cmd_read_reg_bit_port_id =
6035 	TOKEN_NUM_INITIALIZER(struct cmd_read_reg_bit_result, port_id, UINT8);
6036 cmdline_parse_token_num_t cmd_read_reg_bit_reg_off =
6037 	TOKEN_NUM_INITIALIZER(struct cmd_read_reg_bit_result, reg_off, UINT32);
6038 cmdline_parse_token_num_t cmd_read_reg_bit_bit_pos =
6039 	TOKEN_NUM_INITIALIZER(struct cmd_read_reg_bit_result, bit_pos, UINT8);
6040 
6041 cmdline_parse_inst_t cmd_read_reg_bit = {
6042 	.f = cmd_read_reg_bit_parsed,
6043 	.data = NULL,
6044 	.help_str = "read regbit <port_id> <reg_off> <bit_x>: 0 <= bit_x <= 31",
6045 	.tokens = {
6046 		(void *)&cmd_read_reg_bit_read,
6047 		(void *)&cmd_read_reg_bit_regbit,
6048 		(void *)&cmd_read_reg_bit_port_id,
6049 		(void *)&cmd_read_reg_bit_reg_off,
6050 		(void *)&cmd_read_reg_bit_bit_pos,
6051 		NULL,
6052 	},
6053 };
6054 
6055 /* *** WRITE PORT REGISTER *** */
6056 struct cmd_write_reg_result {
6057 	cmdline_fixed_string_t write;
6058 	cmdline_fixed_string_t reg;
6059 	uint8_t port_id;
6060 	uint32_t reg_off;
6061 	uint32_t value;
6062 };
6063 
6064 static void
6065 cmd_write_reg_parsed(void *parsed_result,
6066 		     __attribute__((unused)) struct cmdline *cl,
6067 		     __attribute__((unused)) void *data)
6068 {
6069 	struct cmd_write_reg_result *res = parsed_result;
6070 	port_reg_set(res->port_id, res->reg_off, res->value);
6071 }
6072 
6073 cmdline_parse_token_string_t cmd_write_reg_write =
6074 	TOKEN_STRING_INITIALIZER(struct cmd_write_reg_result, write, "write");
6075 cmdline_parse_token_string_t cmd_write_reg_reg =
6076 	TOKEN_STRING_INITIALIZER(struct cmd_write_reg_result, reg, "reg");
6077 cmdline_parse_token_num_t cmd_write_reg_port_id =
6078 	TOKEN_NUM_INITIALIZER(struct cmd_write_reg_result, port_id, UINT8);
6079 cmdline_parse_token_num_t cmd_write_reg_reg_off =
6080 	TOKEN_NUM_INITIALIZER(struct cmd_write_reg_result, reg_off, UINT32);
6081 cmdline_parse_token_num_t cmd_write_reg_value =
6082 	TOKEN_NUM_INITIALIZER(struct cmd_write_reg_result, value, UINT32);
6083 
6084 cmdline_parse_inst_t cmd_write_reg = {
6085 	.f = cmd_write_reg_parsed,
6086 	.data = NULL,
6087 	.help_str = "write reg <port_id> <reg_off> <reg_value>",
6088 	.tokens = {
6089 		(void *)&cmd_write_reg_write,
6090 		(void *)&cmd_write_reg_reg,
6091 		(void *)&cmd_write_reg_port_id,
6092 		(void *)&cmd_write_reg_reg_off,
6093 		(void *)&cmd_write_reg_value,
6094 		NULL,
6095 	},
6096 };
6097 
6098 /* *** WRITE PORT REGISTER BIT FIELD *** */
6099 struct cmd_write_reg_bit_field_result {
6100 	cmdline_fixed_string_t write;
6101 	cmdline_fixed_string_t regfield;
6102 	uint8_t port_id;
6103 	uint32_t reg_off;
6104 	uint8_t bit1_pos;
6105 	uint8_t bit2_pos;
6106 	uint32_t value;
6107 };
6108 
6109 static void
6110 cmd_write_reg_bit_field_parsed(void *parsed_result,
6111 			       __attribute__((unused)) struct cmdline *cl,
6112 			       __attribute__((unused)) void *data)
6113 {
6114 	struct cmd_write_reg_bit_field_result *res = parsed_result;
6115 	port_reg_bit_field_set(res->port_id, res->reg_off,
6116 			  res->bit1_pos, res->bit2_pos, res->value);
6117 }
6118 
6119 cmdline_parse_token_string_t cmd_write_reg_bit_field_write =
6120 	TOKEN_STRING_INITIALIZER(struct cmd_write_reg_bit_field_result, write,
6121 				 "write");
6122 cmdline_parse_token_string_t cmd_write_reg_bit_field_regfield =
6123 	TOKEN_STRING_INITIALIZER(struct cmd_write_reg_bit_field_result,
6124 				 regfield, "regfield");
6125 cmdline_parse_token_num_t cmd_write_reg_bit_field_port_id =
6126 	TOKEN_NUM_INITIALIZER(struct cmd_write_reg_bit_field_result, port_id,
6127 			      UINT8);
6128 cmdline_parse_token_num_t cmd_write_reg_bit_field_reg_off =
6129 	TOKEN_NUM_INITIALIZER(struct cmd_write_reg_bit_field_result, reg_off,
6130 			      UINT32);
6131 cmdline_parse_token_num_t cmd_write_reg_bit_field_bit1_pos =
6132 	TOKEN_NUM_INITIALIZER(struct cmd_write_reg_bit_field_result, bit1_pos,
6133 			      UINT8);
6134 cmdline_parse_token_num_t cmd_write_reg_bit_field_bit2_pos =
6135 	TOKEN_NUM_INITIALIZER(struct cmd_write_reg_bit_field_result, bit2_pos,
6136 			      UINT8);
6137 cmdline_parse_token_num_t cmd_write_reg_bit_field_value =
6138 	TOKEN_NUM_INITIALIZER(struct cmd_write_reg_bit_field_result, value,
6139 			      UINT32);
6140 
6141 cmdline_parse_inst_t cmd_write_reg_bit_field = {
6142 	.f = cmd_write_reg_bit_field_parsed,
6143 	.data = NULL,
6144 	.help_str = "write regfield <port_id> <reg_off> <bit_x> <bit_y> "
6145 		"<reg_value>: "
6146 		"Set register bit field between bit_x and bit_y included",
6147 	.tokens = {
6148 		(void *)&cmd_write_reg_bit_field_write,
6149 		(void *)&cmd_write_reg_bit_field_regfield,
6150 		(void *)&cmd_write_reg_bit_field_port_id,
6151 		(void *)&cmd_write_reg_bit_field_reg_off,
6152 		(void *)&cmd_write_reg_bit_field_bit1_pos,
6153 		(void *)&cmd_write_reg_bit_field_bit2_pos,
6154 		(void *)&cmd_write_reg_bit_field_value,
6155 		NULL,
6156 	},
6157 };
6158 
6159 /* *** WRITE PORT REGISTER BIT *** */
6160 struct cmd_write_reg_bit_result {
6161 	cmdline_fixed_string_t write;
6162 	cmdline_fixed_string_t regbit;
6163 	uint8_t port_id;
6164 	uint32_t reg_off;
6165 	uint8_t bit_pos;
6166 	uint8_t value;
6167 };
6168 
6169 static void
6170 cmd_write_reg_bit_parsed(void *parsed_result,
6171 			 __attribute__((unused)) struct cmdline *cl,
6172 			 __attribute__((unused)) void *data)
6173 {
6174 	struct cmd_write_reg_bit_result *res = parsed_result;
6175 	port_reg_bit_set(res->port_id, res->reg_off, res->bit_pos, res->value);
6176 }
6177 
6178 cmdline_parse_token_string_t cmd_write_reg_bit_write =
6179 	TOKEN_STRING_INITIALIZER(struct cmd_write_reg_bit_result, write,
6180 				 "write");
6181 cmdline_parse_token_string_t cmd_write_reg_bit_regbit =
6182 	TOKEN_STRING_INITIALIZER(struct cmd_write_reg_bit_result,
6183 				 regbit, "regbit");
6184 cmdline_parse_token_num_t cmd_write_reg_bit_port_id =
6185 	TOKEN_NUM_INITIALIZER(struct cmd_write_reg_bit_result, port_id, UINT8);
6186 cmdline_parse_token_num_t cmd_write_reg_bit_reg_off =
6187 	TOKEN_NUM_INITIALIZER(struct cmd_write_reg_bit_result, reg_off, UINT32);
6188 cmdline_parse_token_num_t cmd_write_reg_bit_bit_pos =
6189 	TOKEN_NUM_INITIALIZER(struct cmd_write_reg_bit_result, bit_pos, UINT8);
6190 cmdline_parse_token_num_t cmd_write_reg_bit_value =
6191 	TOKEN_NUM_INITIALIZER(struct cmd_write_reg_bit_result, value, UINT8);
6192 
6193 cmdline_parse_inst_t cmd_write_reg_bit = {
6194 	.f = cmd_write_reg_bit_parsed,
6195 	.data = NULL,
6196 	.help_str = "write regbit <port_id> <reg_off> <bit_x> 0|1: "
6197 		"0 <= bit_x <= 31",
6198 	.tokens = {
6199 		(void *)&cmd_write_reg_bit_write,
6200 		(void *)&cmd_write_reg_bit_regbit,
6201 		(void *)&cmd_write_reg_bit_port_id,
6202 		(void *)&cmd_write_reg_bit_reg_off,
6203 		(void *)&cmd_write_reg_bit_bit_pos,
6204 		(void *)&cmd_write_reg_bit_value,
6205 		NULL,
6206 	},
6207 };
6208 
6209 /* *** READ A RING DESCRIPTOR OF A PORT RX/TX QUEUE *** */
6210 struct cmd_read_rxd_txd_result {
6211 	cmdline_fixed_string_t read;
6212 	cmdline_fixed_string_t rxd_txd;
6213 	uint8_t port_id;
6214 	uint16_t queue_id;
6215 	uint16_t desc_id;
6216 };
6217 
6218 static void
6219 cmd_read_rxd_txd_parsed(void *parsed_result,
6220 			__attribute__((unused)) struct cmdline *cl,
6221 			__attribute__((unused)) void *data)
6222 {
6223 	struct cmd_read_rxd_txd_result *res = parsed_result;
6224 
6225 	if (!strcmp(res->rxd_txd, "rxd"))
6226 		rx_ring_desc_display(res->port_id, res->queue_id, res->desc_id);
6227 	else if (!strcmp(res->rxd_txd, "txd"))
6228 		tx_ring_desc_display(res->port_id, res->queue_id, res->desc_id);
6229 }
6230 
6231 cmdline_parse_token_string_t cmd_read_rxd_txd_read =
6232 	TOKEN_STRING_INITIALIZER(struct cmd_read_rxd_txd_result, read, "read");
6233 cmdline_parse_token_string_t cmd_read_rxd_txd_rxd_txd =
6234 	TOKEN_STRING_INITIALIZER(struct cmd_read_rxd_txd_result, rxd_txd,
6235 				 "rxd#txd");
6236 cmdline_parse_token_num_t cmd_read_rxd_txd_port_id =
6237 	TOKEN_NUM_INITIALIZER(struct cmd_read_rxd_txd_result, port_id, UINT8);
6238 cmdline_parse_token_num_t cmd_read_rxd_txd_queue_id =
6239 	TOKEN_NUM_INITIALIZER(struct cmd_read_rxd_txd_result, queue_id, UINT16);
6240 cmdline_parse_token_num_t cmd_read_rxd_txd_desc_id =
6241 	TOKEN_NUM_INITIALIZER(struct cmd_read_rxd_txd_result, desc_id, UINT16);
6242 
6243 cmdline_parse_inst_t cmd_read_rxd_txd = {
6244 	.f = cmd_read_rxd_txd_parsed,
6245 	.data = NULL,
6246 	.help_str = "read rxd|txd <port_id> <queue_id> <desc_id>",
6247 	.tokens = {
6248 		(void *)&cmd_read_rxd_txd_read,
6249 		(void *)&cmd_read_rxd_txd_rxd_txd,
6250 		(void *)&cmd_read_rxd_txd_port_id,
6251 		(void *)&cmd_read_rxd_txd_queue_id,
6252 		(void *)&cmd_read_rxd_txd_desc_id,
6253 		NULL,
6254 	},
6255 };
6256 
6257 /* *** QUIT *** */
6258 struct cmd_quit_result {
6259 	cmdline_fixed_string_t quit;
6260 };
6261 
6262 static void cmd_quit_parsed(__attribute__((unused)) void *parsed_result,
6263 			    struct cmdline *cl,
6264 			    __attribute__((unused)) void *data)
6265 {
6266 	pmd_test_exit();
6267 	cmdline_quit(cl);
6268 }
6269 
6270 cmdline_parse_token_string_t cmd_quit_quit =
6271 	TOKEN_STRING_INITIALIZER(struct cmd_quit_result, quit, "quit");
6272 
6273 cmdline_parse_inst_t cmd_quit = {
6274 	.f = cmd_quit_parsed,
6275 	.data = NULL,
6276 	.help_str = "quit: Exit application",
6277 	.tokens = {
6278 		(void *)&cmd_quit_quit,
6279 		NULL,
6280 	},
6281 };
6282 
6283 /* *** ADD/REMOVE MAC ADDRESS FROM A PORT *** */
6284 struct cmd_mac_addr_result {
6285 	cmdline_fixed_string_t mac_addr_cmd;
6286 	cmdline_fixed_string_t what;
6287 	uint8_t port_num;
6288 	struct ether_addr address;
6289 };
6290 
6291 static void cmd_mac_addr_parsed(void *parsed_result,
6292 		__attribute__((unused)) struct cmdline *cl,
6293 		__attribute__((unused)) void *data)
6294 {
6295 	struct cmd_mac_addr_result *res = parsed_result;
6296 	int ret;
6297 
6298 	if (strcmp(res->what, "add") == 0)
6299 		ret = rte_eth_dev_mac_addr_add(res->port_num, &res->address, 0);
6300 	else
6301 		ret = rte_eth_dev_mac_addr_remove(res->port_num, &res->address);
6302 
6303 	/* check the return value and print it if is < 0 */
6304 	if(ret < 0)
6305 		printf("mac_addr_cmd error: (%s)\n", strerror(-ret));
6306 
6307 }
6308 
6309 cmdline_parse_token_string_t cmd_mac_addr_cmd =
6310 	TOKEN_STRING_INITIALIZER(struct cmd_mac_addr_result, mac_addr_cmd,
6311 				"mac_addr");
6312 cmdline_parse_token_string_t cmd_mac_addr_what =
6313 	TOKEN_STRING_INITIALIZER(struct cmd_mac_addr_result, what,
6314 				"add#remove");
6315 cmdline_parse_token_num_t cmd_mac_addr_portnum =
6316 		TOKEN_NUM_INITIALIZER(struct cmd_mac_addr_result, port_num, UINT8);
6317 cmdline_parse_token_etheraddr_t cmd_mac_addr_addr =
6318 		TOKEN_ETHERADDR_INITIALIZER(struct cmd_mac_addr_result, address);
6319 
6320 cmdline_parse_inst_t cmd_mac_addr = {
6321 	.f = cmd_mac_addr_parsed,
6322 	.data = (void *)0,
6323 	.help_str = "mac_addr add|remove <port_id> <mac_addr>: "
6324 			"Add/Remove MAC address on port_id",
6325 	.tokens = {
6326 		(void *)&cmd_mac_addr_cmd,
6327 		(void *)&cmd_mac_addr_what,
6328 		(void *)&cmd_mac_addr_portnum,
6329 		(void *)&cmd_mac_addr_addr,
6330 		NULL,
6331 	},
6332 };
6333 
6334 
6335 /* *** CONFIGURE QUEUE STATS COUNTER MAPPINGS *** */
6336 struct cmd_set_qmap_result {
6337 	cmdline_fixed_string_t set;
6338 	cmdline_fixed_string_t qmap;
6339 	cmdline_fixed_string_t what;
6340 	uint8_t port_id;
6341 	uint16_t queue_id;
6342 	uint8_t map_value;
6343 };
6344 
6345 static void
6346 cmd_set_qmap_parsed(void *parsed_result,
6347 		       __attribute__((unused)) struct cmdline *cl,
6348 		       __attribute__((unused)) void *data)
6349 {
6350 	struct cmd_set_qmap_result *res = parsed_result;
6351 	int is_rx = (strcmp(res->what, "tx") == 0) ? 0 : 1;
6352 
6353 	set_qmap(res->port_id, (uint8_t)is_rx, res->queue_id, res->map_value);
6354 }
6355 
6356 cmdline_parse_token_string_t cmd_setqmap_set =
6357 	TOKEN_STRING_INITIALIZER(struct cmd_set_qmap_result,
6358 				 set, "set");
6359 cmdline_parse_token_string_t cmd_setqmap_qmap =
6360 	TOKEN_STRING_INITIALIZER(struct cmd_set_qmap_result,
6361 				 qmap, "stat_qmap");
6362 cmdline_parse_token_string_t cmd_setqmap_what =
6363 	TOKEN_STRING_INITIALIZER(struct cmd_set_qmap_result,
6364 				 what, "tx#rx");
6365 cmdline_parse_token_num_t cmd_setqmap_portid =
6366 	TOKEN_NUM_INITIALIZER(struct cmd_set_qmap_result,
6367 			      port_id, UINT8);
6368 cmdline_parse_token_num_t cmd_setqmap_queueid =
6369 	TOKEN_NUM_INITIALIZER(struct cmd_set_qmap_result,
6370 			      queue_id, UINT16);
6371 cmdline_parse_token_num_t cmd_setqmap_mapvalue =
6372 	TOKEN_NUM_INITIALIZER(struct cmd_set_qmap_result,
6373 			      map_value, UINT8);
6374 
6375 cmdline_parse_inst_t cmd_set_qmap = {
6376 	.f = cmd_set_qmap_parsed,
6377 	.data = NULL,
6378 	.help_str = "set stat_qmap rx|tx <port_id> <queue_id> <map_value>: "
6379 		"Set statistics mapping value on tx|rx queue_id of port_id",
6380 	.tokens = {
6381 		(void *)&cmd_setqmap_set,
6382 		(void *)&cmd_setqmap_qmap,
6383 		(void *)&cmd_setqmap_what,
6384 		(void *)&cmd_setqmap_portid,
6385 		(void *)&cmd_setqmap_queueid,
6386 		(void *)&cmd_setqmap_mapvalue,
6387 		NULL,
6388 	},
6389 };
6390 
6391 /* *** CONFIGURE UNICAST HASH TABLE *** */
6392 struct cmd_set_uc_hash_table {
6393 	cmdline_fixed_string_t set;
6394 	cmdline_fixed_string_t port;
6395 	uint8_t port_id;
6396 	cmdline_fixed_string_t what;
6397 	struct ether_addr address;
6398 	cmdline_fixed_string_t mode;
6399 };
6400 
6401 static void
6402 cmd_set_uc_hash_parsed(void *parsed_result,
6403 		       __attribute__((unused)) struct cmdline *cl,
6404 		       __attribute__((unused)) void *data)
6405 {
6406 	int ret=0;
6407 	struct cmd_set_uc_hash_table *res = parsed_result;
6408 
6409 	int is_on = (strcmp(res->mode, "on") == 0) ? 1 : 0;
6410 
6411 	if (strcmp(res->what, "uta") == 0)
6412 		ret = rte_eth_dev_uc_hash_table_set(res->port_id,
6413 						&res->address,(uint8_t)is_on);
6414 	if (ret < 0)
6415 		printf("bad unicast hash table parameter, return code = %d \n", ret);
6416 
6417 }
6418 
6419 cmdline_parse_token_string_t cmd_set_uc_hash_set =
6420 	TOKEN_STRING_INITIALIZER(struct cmd_set_uc_hash_table,
6421 				 set, "set");
6422 cmdline_parse_token_string_t cmd_set_uc_hash_port =
6423 	TOKEN_STRING_INITIALIZER(struct cmd_set_uc_hash_table,
6424 				 port, "port");
6425 cmdline_parse_token_num_t cmd_set_uc_hash_portid =
6426 	TOKEN_NUM_INITIALIZER(struct cmd_set_uc_hash_table,
6427 			      port_id, UINT8);
6428 cmdline_parse_token_string_t cmd_set_uc_hash_what =
6429 	TOKEN_STRING_INITIALIZER(struct cmd_set_uc_hash_table,
6430 				 what, "uta");
6431 cmdline_parse_token_etheraddr_t cmd_set_uc_hash_mac =
6432 	TOKEN_ETHERADDR_INITIALIZER(struct cmd_set_uc_hash_table,
6433 				address);
6434 cmdline_parse_token_string_t cmd_set_uc_hash_mode =
6435 	TOKEN_STRING_INITIALIZER(struct cmd_set_uc_hash_table,
6436 				 mode, "on#off");
6437 
6438 cmdline_parse_inst_t cmd_set_uc_hash_filter = {
6439 	.f = cmd_set_uc_hash_parsed,
6440 	.data = NULL,
6441 	.help_str = "set port <port_id> uta <mac_addr> on|off)",
6442 	.tokens = {
6443 		(void *)&cmd_set_uc_hash_set,
6444 		(void *)&cmd_set_uc_hash_port,
6445 		(void *)&cmd_set_uc_hash_portid,
6446 		(void *)&cmd_set_uc_hash_what,
6447 		(void *)&cmd_set_uc_hash_mac,
6448 		(void *)&cmd_set_uc_hash_mode,
6449 		NULL,
6450 	},
6451 };
6452 
6453 struct cmd_set_uc_all_hash_table {
6454 	cmdline_fixed_string_t set;
6455 	cmdline_fixed_string_t port;
6456 	uint8_t port_id;
6457 	cmdline_fixed_string_t what;
6458 	cmdline_fixed_string_t value;
6459 	cmdline_fixed_string_t mode;
6460 };
6461 
6462 static void
6463 cmd_set_uc_all_hash_parsed(void *parsed_result,
6464 		       __attribute__((unused)) struct cmdline *cl,
6465 		       __attribute__((unused)) void *data)
6466 {
6467 	int ret=0;
6468 	struct cmd_set_uc_all_hash_table *res = parsed_result;
6469 
6470 	int is_on = (strcmp(res->mode, "on") == 0) ? 1 : 0;
6471 
6472 	if ((strcmp(res->what, "uta") == 0) &&
6473 		(strcmp(res->value, "all") == 0))
6474 		ret = rte_eth_dev_uc_all_hash_table_set(res->port_id,(uint8_t) is_on);
6475 	if (ret < 0)
6476 		printf("bad unicast hash table parameter,"
6477 			"return code = %d \n", ret);
6478 }
6479 
6480 cmdline_parse_token_string_t cmd_set_uc_all_hash_set =
6481 	TOKEN_STRING_INITIALIZER(struct cmd_set_uc_all_hash_table,
6482 				 set, "set");
6483 cmdline_parse_token_string_t cmd_set_uc_all_hash_port =
6484 	TOKEN_STRING_INITIALIZER(struct cmd_set_uc_all_hash_table,
6485 				 port, "port");
6486 cmdline_parse_token_num_t cmd_set_uc_all_hash_portid =
6487 	TOKEN_NUM_INITIALIZER(struct cmd_set_uc_all_hash_table,
6488 			      port_id, UINT8);
6489 cmdline_parse_token_string_t cmd_set_uc_all_hash_what =
6490 	TOKEN_STRING_INITIALIZER(struct cmd_set_uc_all_hash_table,
6491 				 what, "uta");
6492 cmdline_parse_token_string_t cmd_set_uc_all_hash_value =
6493 	TOKEN_STRING_INITIALIZER(struct cmd_set_uc_all_hash_table,
6494 				value,"all");
6495 cmdline_parse_token_string_t cmd_set_uc_all_hash_mode =
6496 	TOKEN_STRING_INITIALIZER(struct cmd_set_uc_all_hash_table,
6497 				 mode, "on#off");
6498 
6499 cmdline_parse_inst_t cmd_set_uc_all_hash_filter = {
6500 	.f = cmd_set_uc_all_hash_parsed,
6501 	.data = NULL,
6502 	.help_str = "set port <port_id> uta all on|off",
6503 	.tokens = {
6504 		(void *)&cmd_set_uc_all_hash_set,
6505 		(void *)&cmd_set_uc_all_hash_port,
6506 		(void *)&cmd_set_uc_all_hash_portid,
6507 		(void *)&cmd_set_uc_all_hash_what,
6508 		(void *)&cmd_set_uc_all_hash_value,
6509 		(void *)&cmd_set_uc_all_hash_mode,
6510 		NULL,
6511 	},
6512 };
6513 
6514 /* *** CONFIGURE MACVLAN FILTER FOR VF(s) *** */
6515 struct cmd_set_vf_macvlan_filter {
6516 	cmdline_fixed_string_t set;
6517 	cmdline_fixed_string_t port;
6518 	uint8_t port_id;
6519 	cmdline_fixed_string_t vf;
6520 	uint8_t vf_id;
6521 	struct ether_addr address;
6522 	cmdline_fixed_string_t filter_type;
6523 	cmdline_fixed_string_t mode;
6524 };
6525 
6526 static void
6527 cmd_set_vf_macvlan_parsed(void *parsed_result,
6528 		       __attribute__((unused)) struct cmdline *cl,
6529 		       __attribute__((unused)) void *data)
6530 {
6531 	int is_on, ret = 0;
6532 	struct cmd_set_vf_macvlan_filter *res = parsed_result;
6533 	struct rte_eth_mac_filter filter;
6534 
6535 	memset(&filter, 0, sizeof(struct rte_eth_mac_filter));
6536 
6537 	(void)rte_memcpy(&filter.mac_addr, &res->address, ETHER_ADDR_LEN);
6538 
6539 	/* set VF MAC filter */
6540 	filter.is_vf = 1;
6541 
6542 	/* set VF ID */
6543 	filter.dst_id = res->vf_id;
6544 
6545 	if (!strcmp(res->filter_type, "exact-mac"))
6546 		filter.filter_type = RTE_MAC_PERFECT_MATCH;
6547 	else if (!strcmp(res->filter_type, "exact-mac-vlan"))
6548 		filter.filter_type = RTE_MACVLAN_PERFECT_MATCH;
6549 	else if (!strcmp(res->filter_type, "hashmac"))
6550 		filter.filter_type = RTE_MAC_HASH_MATCH;
6551 	else if (!strcmp(res->filter_type, "hashmac-vlan"))
6552 		filter.filter_type = RTE_MACVLAN_HASH_MATCH;
6553 
6554 	is_on = (strcmp(res->mode, "on") == 0) ? 1 : 0;
6555 
6556 	if (is_on)
6557 		ret = rte_eth_dev_filter_ctrl(res->port_id,
6558 					RTE_ETH_FILTER_MACVLAN,
6559 					RTE_ETH_FILTER_ADD,
6560 					 &filter);
6561 	else
6562 		ret = rte_eth_dev_filter_ctrl(res->port_id,
6563 					RTE_ETH_FILTER_MACVLAN,
6564 					RTE_ETH_FILTER_DELETE,
6565 					&filter);
6566 
6567 	if (ret < 0)
6568 		printf("bad set MAC hash parameter, return code = %d\n", ret);
6569 
6570 }
6571 
6572 cmdline_parse_token_string_t cmd_set_vf_macvlan_set =
6573 	TOKEN_STRING_INITIALIZER(struct cmd_set_vf_macvlan_filter,
6574 				 set, "set");
6575 cmdline_parse_token_string_t cmd_set_vf_macvlan_port =
6576 	TOKEN_STRING_INITIALIZER(struct cmd_set_vf_macvlan_filter,
6577 				 port, "port");
6578 cmdline_parse_token_num_t cmd_set_vf_macvlan_portid =
6579 	TOKEN_NUM_INITIALIZER(struct cmd_set_vf_macvlan_filter,
6580 			      port_id, UINT8);
6581 cmdline_parse_token_string_t cmd_set_vf_macvlan_vf =
6582 	TOKEN_STRING_INITIALIZER(struct cmd_set_vf_macvlan_filter,
6583 				 vf, "vf");
6584 cmdline_parse_token_num_t cmd_set_vf_macvlan_vf_id =
6585 	TOKEN_NUM_INITIALIZER(struct cmd_set_vf_macvlan_filter,
6586 				vf_id, UINT8);
6587 cmdline_parse_token_etheraddr_t cmd_set_vf_macvlan_mac =
6588 	TOKEN_ETHERADDR_INITIALIZER(struct cmd_set_vf_macvlan_filter,
6589 				address);
6590 cmdline_parse_token_string_t cmd_set_vf_macvlan_filter_type =
6591 	TOKEN_STRING_INITIALIZER(struct cmd_set_vf_macvlan_filter,
6592 				filter_type, "exact-mac#exact-mac-vlan"
6593 				"#hashmac#hashmac-vlan");
6594 cmdline_parse_token_string_t cmd_set_vf_macvlan_mode =
6595 	TOKEN_STRING_INITIALIZER(struct cmd_set_vf_macvlan_filter,
6596 				 mode, "on#off");
6597 
6598 cmdline_parse_inst_t cmd_set_vf_macvlan_filter = {
6599 	.f = cmd_set_vf_macvlan_parsed,
6600 	.data = NULL,
6601 	.help_str = "set port <port_id> vf <vf_id> <mac_addr> "
6602 		"exact-mac|exact-mac-vlan|hashmac|hashmac-vlan on|off: "
6603 		"Exact match rule: exact match of MAC or MAC and VLAN; "
6604 		"hash match rule: hash match of MAC and exact match of VLAN",
6605 	.tokens = {
6606 		(void *)&cmd_set_vf_macvlan_set,
6607 		(void *)&cmd_set_vf_macvlan_port,
6608 		(void *)&cmd_set_vf_macvlan_portid,
6609 		(void *)&cmd_set_vf_macvlan_vf,
6610 		(void *)&cmd_set_vf_macvlan_vf_id,
6611 		(void *)&cmd_set_vf_macvlan_mac,
6612 		(void *)&cmd_set_vf_macvlan_filter_type,
6613 		(void *)&cmd_set_vf_macvlan_mode,
6614 		NULL,
6615 	},
6616 };
6617 
6618 /* *** CONFIGURE VF TRAFFIC CONTROL *** */
6619 struct cmd_set_vf_traffic {
6620 	cmdline_fixed_string_t set;
6621 	cmdline_fixed_string_t port;
6622 	uint8_t port_id;
6623 	cmdline_fixed_string_t vf;
6624 	uint8_t vf_id;
6625 	cmdline_fixed_string_t what;
6626 	cmdline_fixed_string_t mode;
6627 };
6628 
6629 static void
6630 cmd_set_vf_traffic_parsed(void *parsed_result,
6631 		       __attribute__((unused)) struct cmdline *cl,
6632 		       __attribute__((unused)) void *data)
6633 {
6634 	struct cmd_set_vf_traffic *res = parsed_result;
6635 	int is_rx = (strcmp(res->what, "rx") == 0) ? 1 : 0;
6636 	int is_on = (strcmp(res->mode, "on") == 0) ? 1 : 0;
6637 
6638 	set_vf_traffic(res->port_id, (uint8_t)is_rx, res->vf_id,(uint8_t) is_on);
6639 }
6640 
6641 cmdline_parse_token_string_t cmd_setvf_traffic_set =
6642 	TOKEN_STRING_INITIALIZER(struct cmd_set_vf_traffic,
6643 				 set, "set");
6644 cmdline_parse_token_string_t cmd_setvf_traffic_port =
6645 	TOKEN_STRING_INITIALIZER(struct cmd_set_vf_traffic,
6646 				 port, "port");
6647 cmdline_parse_token_num_t cmd_setvf_traffic_portid =
6648 	TOKEN_NUM_INITIALIZER(struct cmd_set_vf_traffic,
6649 			      port_id, UINT8);
6650 cmdline_parse_token_string_t cmd_setvf_traffic_vf =
6651 	TOKEN_STRING_INITIALIZER(struct cmd_set_vf_traffic,
6652 				 vf, "vf");
6653 cmdline_parse_token_num_t cmd_setvf_traffic_vfid =
6654 	TOKEN_NUM_INITIALIZER(struct cmd_set_vf_traffic,
6655 			      vf_id, UINT8);
6656 cmdline_parse_token_string_t cmd_setvf_traffic_what =
6657 	TOKEN_STRING_INITIALIZER(struct cmd_set_vf_traffic,
6658 				 what, "tx#rx");
6659 cmdline_parse_token_string_t cmd_setvf_traffic_mode =
6660 	TOKEN_STRING_INITIALIZER(struct cmd_set_vf_traffic,
6661 				 mode, "on#off");
6662 
6663 cmdline_parse_inst_t cmd_set_vf_traffic = {
6664 	.f = cmd_set_vf_traffic_parsed,
6665 	.data = NULL,
6666 	.help_str = "set port <port_id> vf <vf_id> rx|tx on|off",
6667 	.tokens = {
6668 		(void *)&cmd_setvf_traffic_set,
6669 		(void *)&cmd_setvf_traffic_port,
6670 		(void *)&cmd_setvf_traffic_portid,
6671 		(void *)&cmd_setvf_traffic_vf,
6672 		(void *)&cmd_setvf_traffic_vfid,
6673 		(void *)&cmd_setvf_traffic_what,
6674 		(void *)&cmd_setvf_traffic_mode,
6675 		NULL,
6676 	},
6677 };
6678 
6679 /* *** CONFIGURE VF RECEIVE MODE *** */
6680 struct cmd_set_vf_rxmode {
6681 	cmdline_fixed_string_t set;
6682 	cmdline_fixed_string_t port;
6683 	uint8_t port_id;
6684 	cmdline_fixed_string_t vf;
6685 	uint8_t vf_id;
6686 	cmdline_fixed_string_t what;
6687 	cmdline_fixed_string_t mode;
6688 	cmdline_fixed_string_t on;
6689 };
6690 
6691 static void
6692 cmd_set_vf_rxmode_parsed(void *parsed_result,
6693 		       __attribute__((unused)) struct cmdline *cl,
6694 		       __attribute__((unused)) void *data)
6695 {
6696 	int ret;
6697 	uint16_t rx_mode = 0;
6698 	struct cmd_set_vf_rxmode *res = parsed_result;
6699 
6700 	int is_on = (strcmp(res->on, "on") == 0) ? 1 : 0;
6701 	if (!strcmp(res->what,"rxmode")) {
6702 		if (!strcmp(res->mode, "AUPE"))
6703 			rx_mode |= ETH_VMDQ_ACCEPT_UNTAG;
6704 		else if (!strcmp(res->mode, "ROPE"))
6705 			rx_mode |= ETH_VMDQ_ACCEPT_HASH_UC;
6706 		else if (!strcmp(res->mode, "BAM"))
6707 			rx_mode |= ETH_VMDQ_ACCEPT_BROADCAST;
6708 		else if (!strncmp(res->mode, "MPE",3))
6709 			rx_mode |= ETH_VMDQ_ACCEPT_MULTICAST;
6710 	}
6711 
6712 	ret = rte_eth_dev_set_vf_rxmode(res->port_id,res->vf_id,rx_mode,(uint8_t)is_on);
6713 	if (ret < 0)
6714 		printf("bad VF receive mode parameter, return code = %d \n",
6715 		ret);
6716 }
6717 
6718 cmdline_parse_token_string_t cmd_set_vf_rxmode_set =
6719 	TOKEN_STRING_INITIALIZER(struct cmd_set_vf_rxmode,
6720 				 set, "set");
6721 cmdline_parse_token_string_t cmd_set_vf_rxmode_port =
6722 	TOKEN_STRING_INITIALIZER(struct cmd_set_vf_rxmode,
6723 				 port, "port");
6724 cmdline_parse_token_num_t cmd_set_vf_rxmode_portid =
6725 	TOKEN_NUM_INITIALIZER(struct cmd_set_vf_rxmode,
6726 			      port_id, UINT8);
6727 cmdline_parse_token_string_t cmd_set_vf_rxmode_vf =
6728 	TOKEN_STRING_INITIALIZER(struct cmd_set_vf_rxmode,
6729 				 vf, "vf");
6730 cmdline_parse_token_num_t cmd_set_vf_rxmode_vfid =
6731 	TOKEN_NUM_INITIALIZER(struct cmd_set_vf_rxmode,
6732 			      vf_id, UINT8);
6733 cmdline_parse_token_string_t cmd_set_vf_rxmode_what =
6734 	TOKEN_STRING_INITIALIZER(struct cmd_set_vf_rxmode,
6735 				 what, "rxmode");
6736 cmdline_parse_token_string_t cmd_set_vf_rxmode_mode =
6737 	TOKEN_STRING_INITIALIZER(struct cmd_set_vf_rxmode,
6738 				 mode, "AUPE#ROPE#BAM#MPE");
6739 cmdline_parse_token_string_t cmd_set_vf_rxmode_on =
6740 	TOKEN_STRING_INITIALIZER(struct cmd_set_vf_rxmode,
6741 				 on, "on#off");
6742 
6743 cmdline_parse_inst_t cmd_set_vf_rxmode = {
6744 	.f = cmd_set_vf_rxmode_parsed,
6745 	.data = NULL,
6746 	.help_str = "set port <port_id> vf <vf_id> rxmode "
6747 		"AUPE|ROPE|BAM|MPE on|off",
6748 	.tokens = {
6749 		(void *)&cmd_set_vf_rxmode_set,
6750 		(void *)&cmd_set_vf_rxmode_port,
6751 		(void *)&cmd_set_vf_rxmode_portid,
6752 		(void *)&cmd_set_vf_rxmode_vf,
6753 		(void *)&cmd_set_vf_rxmode_vfid,
6754 		(void *)&cmd_set_vf_rxmode_what,
6755 		(void *)&cmd_set_vf_rxmode_mode,
6756 		(void *)&cmd_set_vf_rxmode_on,
6757 		NULL,
6758 	},
6759 };
6760 
6761 /* *** ADD MAC ADDRESS FILTER FOR A VF OF A PORT *** */
6762 struct cmd_vf_mac_addr_result {
6763 	cmdline_fixed_string_t mac_addr_cmd;
6764 	cmdline_fixed_string_t what;
6765 	cmdline_fixed_string_t port;
6766 	uint8_t port_num;
6767 	cmdline_fixed_string_t vf;
6768 	uint8_t vf_num;
6769 	struct ether_addr address;
6770 };
6771 
6772 static void cmd_vf_mac_addr_parsed(void *parsed_result,
6773 		__attribute__((unused)) struct cmdline *cl,
6774 		__attribute__((unused)) void *data)
6775 {
6776 	struct cmd_vf_mac_addr_result *res = parsed_result;
6777 	int ret = 0;
6778 
6779 	if (strcmp(res->what, "add") == 0)
6780 		ret = rte_eth_dev_mac_addr_add(res->port_num,
6781 					&res->address, res->vf_num);
6782 	if(ret < 0)
6783 		printf("vf_mac_addr_cmd error: (%s)\n", strerror(-ret));
6784 
6785 }
6786 
6787 cmdline_parse_token_string_t cmd_vf_mac_addr_cmd =
6788 	TOKEN_STRING_INITIALIZER(struct cmd_vf_mac_addr_result,
6789 				mac_addr_cmd,"mac_addr");
6790 cmdline_parse_token_string_t cmd_vf_mac_addr_what =
6791 	TOKEN_STRING_INITIALIZER(struct cmd_vf_mac_addr_result,
6792 				what,"add");
6793 cmdline_parse_token_string_t cmd_vf_mac_addr_port =
6794 	TOKEN_STRING_INITIALIZER(struct cmd_vf_mac_addr_result,
6795 				port,"port");
6796 cmdline_parse_token_num_t cmd_vf_mac_addr_portnum =
6797 	TOKEN_NUM_INITIALIZER(struct cmd_vf_mac_addr_result,
6798 				port_num, UINT8);
6799 cmdline_parse_token_string_t cmd_vf_mac_addr_vf =
6800 	TOKEN_STRING_INITIALIZER(struct cmd_vf_mac_addr_result,
6801 				vf,"vf");
6802 cmdline_parse_token_num_t cmd_vf_mac_addr_vfnum =
6803 	TOKEN_NUM_INITIALIZER(struct cmd_vf_mac_addr_result,
6804 				vf_num, UINT8);
6805 cmdline_parse_token_etheraddr_t cmd_vf_mac_addr_addr =
6806 	TOKEN_ETHERADDR_INITIALIZER(struct cmd_vf_mac_addr_result,
6807 				address);
6808 
6809 cmdline_parse_inst_t cmd_vf_mac_addr_filter = {
6810 	.f = cmd_vf_mac_addr_parsed,
6811 	.data = (void *)0,
6812 	.help_str = "mac_addr add port <port_id> vf <vf_id> <mac_addr>: "
6813 		"Add MAC address filtering for a VF on port_id",
6814 	.tokens = {
6815 		(void *)&cmd_vf_mac_addr_cmd,
6816 		(void *)&cmd_vf_mac_addr_what,
6817 		(void *)&cmd_vf_mac_addr_port,
6818 		(void *)&cmd_vf_mac_addr_portnum,
6819 		(void *)&cmd_vf_mac_addr_vf,
6820 		(void *)&cmd_vf_mac_addr_vfnum,
6821 		(void *)&cmd_vf_mac_addr_addr,
6822 		NULL,
6823 	},
6824 };
6825 
6826 /* *** ADD/REMOVE A VLAN IDENTIFIER TO/FROM A PORT VLAN RX FILTER *** */
6827 struct cmd_vf_rx_vlan_filter {
6828 	cmdline_fixed_string_t rx_vlan;
6829 	cmdline_fixed_string_t what;
6830 	uint16_t vlan_id;
6831 	cmdline_fixed_string_t port;
6832 	uint8_t port_id;
6833 	cmdline_fixed_string_t vf;
6834 	uint64_t vf_mask;
6835 };
6836 
6837 static void
6838 cmd_vf_rx_vlan_filter_parsed(void *parsed_result,
6839 			  __attribute__((unused)) struct cmdline *cl,
6840 			  __attribute__((unused)) void *data)
6841 {
6842 	struct cmd_vf_rx_vlan_filter *res = parsed_result;
6843 
6844 	if (!strcmp(res->what, "add"))
6845 		set_vf_rx_vlan(res->port_id, res->vlan_id,res->vf_mask, 1);
6846 	else
6847 		set_vf_rx_vlan(res->port_id, res->vlan_id,res->vf_mask, 0);
6848 }
6849 
6850 cmdline_parse_token_string_t cmd_vf_rx_vlan_filter_rx_vlan =
6851 	TOKEN_STRING_INITIALIZER(struct cmd_vf_rx_vlan_filter,
6852 				 rx_vlan, "rx_vlan");
6853 cmdline_parse_token_string_t cmd_vf_rx_vlan_filter_what =
6854 	TOKEN_STRING_INITIALIZER(struct cmd_vf_rx_vlan_filter,
6855 				 what, "add#rm");
6856 cmdline_parse_token_num_t cmd_vf_rx_vlan_filter_vlanid =
6857 	TOKEN_NUM_INITIALIZER(struct cmd_vf_rx_vlan_filter,
6858 			      vlan_id, UINT16);
6859 cmdline_parse_token_string_t cmd_vf_rx_vlan_filter_port =
6860 	TOKEN_STRING_INITIALIZER(struct cmd_vf_rx_vlan_filter,
6861 				 port, "port");
6862 cmdline_parse_token_num_t cmd_vf_rx_vlan_filter_portid =
6863 	TOKEN_NUM_INITIALIZER(struct cmd_vf_rx_vlan_filter,
6864 			      port_id, UINT8);
6865 cmdline_parse_token_string_t cmd_vf_rx_vlan_filter_vf =
6866 	TOKEN_STRING_INITIALIZER(struct cmd_vf_rx_vlan_filter,
6867 				 vf, "vf");
6868 cmdline_parse_token_num_t cmd_vf_rx_vlan_filter_vf_mask =
6869 	TOKEN_NUM_INITIALIZER(struct cmd_vf_rx_vlan_filter,
6870 			      vf_mask, UINT64);
6871 
6872 cmdline_parse_inst_t cmd_vf_rxvlan_filter = {
6873 	.f = cmd_vf_rx_vlan_filter_parsed,
6874 	.data = NULL,
6875 	.help_str = "rx_vlan add|rm <vlan_id> port <port_id> vf <vf_mask>: "
6876 		"(vf_mask = hexadecimal VF mask)",
6877 	.tokens = {
6878 		(void *)&cmd_vf_rx_vlan_filter_rx_vlan,
6879 		(void *)&cmd_vf_rx_vlan_filter_what,
6880 		(void *)&cmd_vf_rx_vlan_filter_vlanid,
6881 		(void *)&cmd_vf_rx_vlan_filter_port,
6882 		(void *)&cmd_vf_rx_vlan_filter_portid,
6883 		(void *)&cmd_vf_rx_vlan_filter_vf,
6884 		(void *)&cmd_vf_rx_vlan_filter_vf_mask,
6885 		NULL,
6886 	},
6887 };
6888 
6889 /* *** SET RATE LIMIT FOR A QUEUE OF A PORT *** */
6890 struct cmd_queue_rate_limit_result {
6891 	cmdline_fixed_string_t set;
6892 	cmdline_fixed_string_t port;
6893 	uint8_t port_num;
6894 	cmdline_fixed_string_t queue;
6895 	uint8_t queue_num;
6896 	cmdline_fixed_string_t rate;
6897 	uint16_t rate_num;
6898 };
6899 
6900 static void cmd_queue_rate_limit_parsed(void *parsed_result,
6901 		__attribute__((unused)) struct cmdline *cl,
6902 		__attribute__((unused)) void *data)
6903 {
6904 	struct cmd_queue_rate_limit_result *res = parsed_result;
6905 	int ret = 0;
6906 
6907 	if ((strcmp(res->set, "set") == 0) && (strcmp(res->port, "port") == 0)
6908 		&& (strcmp(res->queue, "queue") == 0)
6909 		&& (strcmp(res->rate, "rate") == 0))
6910 		ret = set_queue_rate_limit(res->port_num, res->queue_num,
6911 					res->rate_num);
6912 	if (ret < 0)
6913 		printf("queue_rate_limit_cmd error: (%s)\n", strerror(-ret));
6914 
6915 }
6916 
6917 cmdline_parse_token_string_t cmd_queue_rate_limit_set =
6918 	TOKEN_STRING_INITIALIZER(struct cmd_queue_rate_limit_result,
6919 				set, "set");
6920 cmdline_parse_token_string_t cmd_queue_rate_limit_port =
6921 	TOKEN_STRING_INITIALIZER(struct cmd_queue_rate_limit_result,
6922 				port, "port");
6923 cmdline_parse_token_num_t cmd_queue_rate_limit_portnum =
6924 	TOKEN_NUM_INITIALIZER(struct cmd_queue_rate_limit_result,
6925 				port_num, UINT8);
6926 cmdline_parse_token_string_t cmd_queue_rate_limit_queue =
6927 	TOKEN_STRING_INITIALIZER(struct cmd_queue_rate_limit_result,
6928 				queue, "queue");
6929 cmdline_parse_token_num_t cmd_queue_rate_limit_queuenum =
6930 	TOKEN_NUM_INITIALIZER(struct cmd_queue_rate_limit_result,
6931 				queue_num, UINT8);
6932 cmdline_parse_token_string_t cmd_queue_rate_limit_rate =
6933 	TOKEN_STRING_INITIALIZER(struct cmd_queue_rate_limit_result,
6934 				rate, "rate");
6935 cmdline_parse_token_num_t cmd_queue_rate_limit_ratenum =
6936 	TOKEN_NUM_INITIALIZER(struct cmd_queue_rate_limit_result,
6937 				rate_num, UINT16);
6938 
6939 cmdline_parse_inst_t cmd_queue_rate_limit = {
6940 	.f = cmd_queue_rate_limit_parsed,
6941 	.data = (void *)0,
6942 	.help_str = "set port <port_id> queue <queue_id> rate <rate_value>: "
6943 		"Set rate limit for a queue on port_id",
6944 	.tokens = {
6945 		(void *)&cmd_queue_rate_limit_set,
6946 		(void *)&cmd_queue_rate_limit_port,
6947 		(void *)&cmd_queue_rate_limit_portnum,
6948 		(void *)&cmd_queue_rate_limit_queue,
6949 		(void *)&cmd_queue_rate_limit_queuenum,
6950 		(void *)&cmd_queue_rate_limit_rate,
6951 		(void *)&cmd_queue_rate_limit_ratenum,
6952 		NULL,
6953 	},
6954 };
6955 
6956 /* *** SET RATE LIMIT FOR A VF OF A PORT *** */
6957 struct cmd_vf_rate_limit_result {
6958 	cmdline_fixed_string_t set;
6959 	cmdline_fixed_string_t port;
6960 	uint8_t port_num;
6961 	cmdline_fixed_string_t vf;
6962 	uint8_t vf_num;
6963 	cmdline_fixed_string_t rate;
6964 	uint16_t rate_num;
6965 	cmdline_fixed_string_t q_msk;
6966 	uint64_t q_msk_val;
6967 };
6968 
6969 static void cmd_vf_rate_limit_parsed(void *parsed_result,
6970 		__attribute__((unused)) struct cmdline *cl,
6971 		__attribute__((unused)) void *data)
6972 {
6973 	struct cmd_vf_rate_limit_result *res = parsed_result;
6974 	int ret = 0;
6975 
6976 	if ((strcmp(res->set, "set") == 0) && (strcmp(res->port, "port") == 0)
6977 		&& (strcmp(res->vf, "vf") == 0)
6978 		&& (strcmp(res->rate, "rate") == 0)
6979 		&& (strcmp(res->q_msk, "queue_mask") == 0))
6980 		ret = set_vf_rate_limit(res->port_num, res->vf_num,
6981 					res->rate_num, res->q_msk_val);
6982 	if (ret < 0)
6983 		printf("vf_rate_limit_cmd error: (%s)\n", strerror(-ret));
6984 
6985 }
6986 
6987 cmdline_parse_token_string_t cmd_vf_rate_limit_set =
6988 	TOKEN_STRING_INITIALIZER(struct cmd_vf_rate_limit_result,
6989 				set, "set");
6990 cmdline_parse_token_string_t cmd_vf_rate_limit_port =
6991 	TOKEN_STRING_INITIALIZER(struct cmd_vf_rate_limit_result,
6992 				port, "port");
6993 cmdline_parse_token_num_t cmd_vf_rate_limit_portnum =
6994 	TOKEN_NUM_INITIALIZER(struct cmd_vf_rate_limit_result,
6995 				port_num, UINT8);
6996 cmdline_parse_token_string_t cmd_vf_rate_limit_vf =
6997 	TOKEN_STRING_INITIALIZER(struct cmd_vf_rate_limit_result,
6998 				vf, "vf");
6999 cmdline_parse_token_num_t cmd_vf_rate_limit_vfnum =
7000 	TOKEN_NUM_INITIALIZER(struct cmd_vf_rate_limit_result,
7001 				vf_num, UINT8);
7002 cmdline_parse_token_string_t cmd_vf_rate_limit_rate =
7003 	TOKEN_STRING_INITIALIZER(struct cmd_vf_rate_limit_result,
7004 				rate, "rate");
7005 cmdline_parse_token_num_t cmd_vf_rate_limit_ratenum =
7006 	TOKEN_NUM_INITIALIZER(struct cmd_vf_rate_limit_result,
7007 				rate_num, UINT16);
7008 cmdline_parse_token_string_t cmd_vf_rate_limit_q_msk =
7009 	TOKEN_STRING_INITIALIZER(struct cmd_vf_rate_limit_result,
7010 				q_msk, "queue_mask");
7011 cmdline_parse_token_num_t cmd_vf_rate_limit_q_msk_val =
7012 	TOKEN_NUM_INITIALIZER(struct cmd_vf_rate_limit_result,
7013 				q_msk_val, UINT64);
7014 
7015 cmdline_parse_inst_t cmd_vf_rate_limit = {
7016 	.f = cmd_vf_rate_limit_parsed,
7017 	.data = (void *)0,
7018 	.help_str = "set port <port_id> vf <vf_id> rate <rate_value> "
7019 		"queue_mask <queue_mask_value>: "
7020 		"Set rate limit for queues of VF on port_id",
7021 	.tokens = {
7022 		(void *)&cmd_vf_rate_limit_set,
7023 		(void *)&cmd_vf_rate_limit_port,
7024 		(void *)&cmd_vf_rate_limit_portnum,
7025 		(void *)&cmd_vf_rate_limit_vf,
7026 		(void *)&cmd_vf_rate_limit_vfnum,
7027 		(void *)&cmd_vf_rate_limit_rate,
7028 		(void *)&cmd_vf_rate_limit_ratenum,
7029 		(void *)&cmd_vf_rate_limit_q_msk,
7030 		(void *)&cmd_vf_rate_limit_q_msk_val,
7031 		NULL,
7032 	},
7033 };
7034 
7035 /* *** ADD TUNNEL FILTER OF A PORT *** */
7036 struct cmd_tunnel_filter_result {
7037 	cmdline_fixed_string_t cmd;
7038 	cmdline_fixed_string_t what;
7039 	uint8_t port_id;
7040 	struct ether_addr outer_mac;
7041 	struct ether_addr inner_mac;
7042 	cmdline_ipaddr_t ip_value;
7043 	uint16_t inner_vlan;
7044 	cmdline_fixed_string_t tunnel_type;
7045 	cmdline_fixed_string_t filter_type;
7046 	uint32_t tenant_id;
7047 	uint16_t queue_num;
7048 };
7049 
7050 static void
7051 cmd_tunnel_filter_parsed(void *parsed_result,
7052 			  __attribute__((unused)) struct cmdline *cl,
7053 			  __attribute__((unused)) void *data)
7054 {
7055 	struct cmd_tunnel_filter_result *res = parsed_result;
7056 	struct rte_eth_tunnel_filter_conf tunnel_filter_conf;
7057 	int ret = 0;
7058 
7059 	memset(&tunnel_filter_conf, 0, sizeof(tunnel_filter_conf));
7060 
7061 	ether_addr_copy(&res->outer_mac, &tunnel_filter_conf.outer_mac);
7062 	ether_addr_copy(&res->inner_mac, &tunnel_filter_conf.inner_mac);
7063 	tunnel_filter_conf.inner_vlan = res->inner_vlan;
7064 
7065 	if (res->ip_value.family == AF_INET) {
7066 		tunnel_filter_conf.ip_addr.ipv4_addr =
7067 			res->ip_value.addr.ipv4.s_addr;
7068 		tunnel_filter_conf.ip_type = RTE_TUNNEL_IPTYPE_IPV4;
7069 	} else {
7070 		memcpy(&(tunnel_filter_conf.ip_addr.ipv6_addr),
7071 			&(res->ip_value.addr.ipv6),
7072 			sizeof(struct in6_addr));
7073 		tunnel_filter_conf.ip_type = RTE_TUNNEL_IPTYPE_IPV6;
7074 	}
7075 
7076 	if (!strcmp(res->filter_type, "imac-ivlan"))
7077 		tunnel_filter_conf.filter_type = RTE_TUNNEL_FILTER_IMAC_IVLAN;
7078 	else if (!strcmp(res->filter_type, "imac-ivlan-tenid"))
7079 		tunnel_filter_conf.filter_type =
7080 			RTE_TUNNEL_FILTER_IMAC_IVLAN_TENID;
7081 	else if (!strcmp(res->filter_type, "imac-tenid"))
7082 		tunnel_filter_conf.filter_type = RTE_TUNNEL_FILTER_IMAC_TENID;
7083 	else if (!strcmp(res->filter_type, "imac"))
7084 		tunnel_filter_conf.filter_type = ETH_TUNNEL_FILTER_IMAC;
7085 	else if (!strcmp(res->filter_type, "omac-imac-tenid"))
7086 		tunnel_filter_conf.filter_type =
7087 			RTE_TUNNEL_FILTER_OMAC_TENID_IMAC;
7088 	else if (!strcmp(res->filter_type, "oip"))
7089 		tunnel_filter_conf.filter_type = ETH_TUNNEL_FILTER_OIP;
7090 	else if (!strcmp(res->filter_type, "iip"))
7091 		tunnel_filter_conf.filter_type = ETH_TUNNEL_FILTER_IIP;
7092 	else {
7093 		printf("The filter type is not supported");
7094 		return;
7095 	}
7096 
7097 	if (!strcmp(res->tunnel_type, "vxlan"))
7098 		tunnel_filter_conf.tunnel_type = RTE_TUNNEL_TYPE_VXLAN;
7099 	else if (!strcmp(res->tunnel_type, "nvgre"))
7100 		tunnel_filter_conf.tunnel_type = RTE_TUNNEL_TYPE_NVGRE;
7101 	else if (!strcmp(res->tunnel_type, "ipingre"))
7102 		tunnel_filter_conf.tunnel_type = RTE_TUNNEL_TYPE_IP_IN_GRE;
7103 	else {
7104 		printf("The tunnel type %s not supported.\n", res->tunnel_type);
7105 		return;
7106 	}
7107 
7108 	tunnel_filter_conf.tenant_id = res->tenant_id;
7109 	tunnel_filter_conf.queue_id = res->queue_num;
7110 	if (!strcmp(res->what, "add"))
7111 		ret = rte_eth_dev_filter_ctrl(res->port_id,
7112 					RTE_ETH_FILTER_TUNNEL,
7113 					RTE_ETH_FILTER_ADD,
7114 					&tunnel_filter_conf);
7115 	else
7116 		ret = rte_eth_dev_filter_ctrl(res->port_id,
7117 					RTE_ETH_FILTER_TUNNEL,
7118 					RTE_ETH_FILTER_DELETE,
7119 					&tunnel_filter_conf);
7120 	if (ret < 0)
7121 		printf("cmd_tunnel_filter_parsed error: (%s)\n",
7122 				strerror(-ret));
7123 
7124 }
7125 cmdline_parse_token_string_t cmd_tunnel_filter_cmd =
7126 	TOKEN_STRING_INITIALIZER(struct cmd_tunnel_filter_result,
7127 	cmd, "tunnel_filter");
7128 cmdline_parse_token_string_t cmd_tunnel_filter_what =
7129 	TOKEN_STRING_INITIALIZER(struct cmd_tunnel_filter_result,
7130 	what, "add#rm");
7131 cmdline_parse_token_num_t cmd_tunnel_filter_port_id =
7132 	TOKEN_NUM_INITIALIZER(struct cmd_tunnel_filter_result,
7133 	port_id, UINT8);
7134 cmdline_parse_token_etheraddr_t cmd_tunnel_filter_outer_mac =
7135 	TOKEN_ETHERADDR_INITIALIZER(struct cmd_tunnel_filter_result,
7136 	outer_mac);
7137 cmdline_parse_token_etheraddr_t cmd_tunnel_filter_inner_mac =
7138 	TOKEN_ETHERADDR_INITIALIZER(struct cmd_tunnel_filter_result,
7139 	inner_mac);
7140 cmdline_parse_token_num_t cmd_tunnel_filter_innner_vlan =
7141 	TOKEN_NUM_INITIALIZER(struct cmd_tunnel_filter_result,
7142 	inner_vlan, UINT16);
7143 cmdline_parse_token_ipaddr_t cmd_tunnel_filter_ip_value =
7144 	TOKEN_IPADDR_INITIALIZER(struct cmd_tunnel_filter_result,
7145 	ip_value);
7146 cmdline_parse_token_string_t cmd_tunnel_filter_tunnel_type =
7147 	TOKEN_STRING_INITIALIZER(struct cmd_tunnel_filter_result,
7148 	tunnel_type, "vxlan#nvgre#ipingre");
7149 
7150 cmdline_parse_token_string_t cmd_tunnel_filter_filter_type =
7151 	TOKEN_STRING_INITIALIZER(struct cmd_tunnel_filter_result,
7152 	filter_type, "oip#iip#imac-ivlan#imac-ivlan-tenid#imac-tenid#"
7153 		"imac#omac-imac-tenid");
7154 cmdline_parse_token_num_t cmd_tunnel_filter_tenant_id =
7155 	TOKEN_NUM_INITIALIZER(struct cmd_tunnel_filter_result,
7156 	tenant_id, UINT32);
7157 cmdline_parse_token_num_t cmd_tunnel_filter_queue_num =
7158 	TOKEN_NUM_INITIALIZER(struct cmd_tunnel_filter_result,
7159 	queue_num, UINT16);
7160 
7161 cmdline_parse_inst_t cmd_tunnel_filter = {
7162 	.f = cmd_tunnel_filter_parsed,
7163 	.data = (void *)0,
7164 	.help_str = "tunnel_filter add|rm <port_id> <outer_mac> <inner_mac> "
7165 		"<ip> <inner_vlan> vxlan|nvgre|ipingre oip|iip|imac-ivlan|"
7166 		"imac-ivlan-tenid|imac-tenid|imac|omac-imac-tenid <tenant_id> "
7167 		"<queue_id>: Add/Rm tunnel filter of a port",
7168 	.tokens = {
7169 		(void *)&cmd_tunnel_filter_cmd,
7170 		(void *)&cmd_tunnel_filter_what,
7171 		(void *)&cmd_tunnel_filter_port_id,
7172 		(void *)&cmd_tunnel_filter_outer_mac,
7173 		(void *)&cmd_tunnel_filter_inner_mac,
7174 		(void *)&cmd_tunnel_filter_ip_value,
7175 		(void *)&cmd_tunnel_filter_innner_vlan,
7176 		(void *)&cmd_tunnel_filter_tunnel_type,
7177 		(void *)&cmd_tunnel_filter_filter_type,
7178 		(void *)&cmd_tunnel_filter_tenant_id,
7179 		(void *)&cmd_tunnel_filter_queue_num,
7180 		NULL,
7181 	},
7182 };
7183 
7184 /* *** CONFIGURE TUNNEL UDP PORT *** */
7185 struct cmd_tunnel_udp_config {
7186 	cmdline_fixed_string_t cmd;
7187 	cmdline_fixed_string_t what;
7188 	uint16_t udp_port;
7189 	uint8_t port_id;
7190 };
7191 
7192 static void
7193 cmd_tunnel_udp_config_parsed(void *parsed_result,
7194 			  __attribute__((unused)) struct cmdline *cl,
7195 			  __attribute__((unused)) void *data)
7196 {
7197 	struct cmd_tunnel_udp_config *res = parsed_result;
7198 	struct rte_eth_udp_tunnel tunnel_udp;
7199 	int ret;
7200 
7201 	tunnel_udp.udp_port = res->udp_port;
7202 
7203 	if (!strcmp(res->cmd, "rx_vxlan_port"))
7204 		tunnel_udp.prot_type = RTE_TUNNEL_TYPE_VXLAN;
7205 
7206 	if (!strcmp(res->what, "add"))
7207 		ret = rte_eth_dev_udp_tunnel_port_add(res->port_id,
7208 						      &tunnel_udp);
7209 	else
7210 		ret = rte_eth_dev_udp_tunnel_port_delete(res->port_id,
7211 							 &tunnel_udp);
7212 
7213 	if (ret < 0)
7214 		printf("udp tunneling add error: (%s)\n", strerror(-ret));
7215 }
7216 
7217 cmdline_parse_token_string_t cmd_tunnel_udp_config_cmd =
7218 	TOKEN_STRING_INITIALIZER(struct cmd_tunnel_udp_config,
7219 				cmd, "rx_vxlan_port");
7220 cmdline_parse_token_string_t cmd_tunnel_udp_config_what =
7221 	TOKEN_STRING_INITIALIZER(struct cmd_tunnel_udp_config,
7222 				what, "add#rm");
7223 cmdline_parse_token_num_t cmd_tunnel_udp_config_udp_port =
7224 	TOKEN_NUM_INITIALIZER(struct cmd_tunnel_udp_config,
7225 				udp_port, UINT16);
7226 cmdline_parse_token_num_t cmd_tunnel_udp_config_port_id =
7227 	TOKEN_NUM_INITIALIZER(struct cmd_tunnel_udp_config,
7228 				port_id, UINT8);
7229 
7230 cmdline_parse_inst_t cmd_tunnel_udp_config = {
7231 	.f = cmd_tunnel_udp_config_parsed,
7232 	.data = (void *)0,
7233 	.help_str = "rx_vxlan_port add|rm <udp_port> <port_id>: "
7234 		"Add/Remove a tunneling UDP port filter",
7235 	.tokens = {
7236 		(void *)&cmd_tunnel_udp_config_cmd,
7237 		(void *)&cmd_tunnel_udp_config_what,
7238 		(void *)&cmd_tunnel_udp_config_udp_port,
7239 		(void *)&cmd_tunnel_udp_config_port_id,
7240 		NULL,
7241 	},
7242 };
7243 
7244 /* *** GLOBAL CONFIG *** */
7245 struct cmd_global_config_result {
7246 	cmdline_fixed_string_t cmd;
7247 	uint8_t port_id;
7248 	cmdline_fixed_string_t cfg_type;
7249 	uint8_t len;
7250 };
7251 
7252 static void
7253 cmd_global_config_parsed(void *parsed_result,
7254 			 __attribute__((unused)) struct cmdline *cl,
7255 			 __attribute__((unused)) void *data)
7256 {
7257 	struct cmd_global_config_result *res = parsed_result;
7258 	struct rte_eth_global_cfg conf;
7259 	int ret;
7260 
7261 	memset(&conf, 0, sizeof(conf));
7262 	conf.cfg_type = RTE_ETH_GLOBAL_CFG_TYPE_GRE_KEY_LEN;
7263 	conf.cfg.gre_key_len = res->len;
7264 	ret = rte_eth_dev_filter_ctrl(res->port_id, RTE_ETH_FILTER_NONE,
7265 				      RTE_ETH_FILTER_SET, &conf);
7266 	if (ret != 0)
7267 		printf("Global config error\n");
7268 }
7269 
7270 cmdline_parse_token_string_t cmd_global_config_cmd =
7271 	TOKEN_STRING_INITIALIZER(struct cmd_global_config_result, cmd,
7272 		"global_config");
7273 cmdline_parse_token_num_t cmd_global_config_port_id =
7274 	TOKEN_NUM_INITIALIZER(struct cmd_global_config_result, port_id, UINT8);
7275 cmdline_parse_token_string_t cmd_global_config_type =
7276 	TOKEN_STRING_INITIALIZER(struct cmd_global_config_result,
7277 		cfg_type, "gre-key-len");
7278 cmdline_parse_token_num_t cmd_global_config_gre_key_len =
7279 	TOKEN_NUM_INITIALIZER(struct cmd_global_config_result,
7280 		len, UINT8);
7281 
7282 cmdline_parse_inst_t cmd_global_config = {
7283 	.f = cmd_global_config_parsed,
7284 	.data = (void *)NULL,
7285 	.help_str = "global_config <port_id> gre-key-len <key_len>",
7286 	.tokens = {
7287 		(void *)&cmd_global_config_cmd,
7288 		(void *)&cmd_global_config_port_id,
7289 		(void *)&cmd_global_config_type,
7290 		(void *)&cmd_global_config_gre_key_len,
7291 		NULL,
7292 	},
7293 };
7294 
7295 /* *** CONFIGURE VM MIRROR VLAN/POOL RULE *** */
7296 struct cmd_set_mirror_mask_result {
7297 	cmdline_fixed_string_t set;
7298 	cmdline_fixed_string_t port;
7299 	uint8_t port_id;
7300 	cmdline_fixed_string_t mirror;
7301 	uint8_t rule_id;
7302 	cmdline_fixed_string_t what;
7303 	cmdline_fixed_string_t value;
7304 	cmdline_fixed_string_t dstpool;
7305 	uint8_t dstpool_id;
7306 	cmdline_fixed_string_t on;
7307 };
7308 
7309 cmdline_parse_token_string_t cmd_mirror_mask_set =
7310 	TOKEN_STRING_INITIALIZER(struct cmd_set_mirror_mask_result,
7311 				set, "set");
7312 cmdline_parse_token_string_t cmd_mirror_mask_port =
7313 	TOKEN_STRING_INITIALIZER(struct cmd_set_mirror_mask_result,
7314 				port, "port");
7315 cmdline_parse_token_num_t cmd_mirror_mask_portid =
7316 	TOKEN_NUM_INITIALIZER(struct cmd_set_mirror_mask_result,
7317 				port_id, UINT8);
7318 cmdline_parse_token_string_t cmd_mirror_mask_mirror =
7319 	TOKEN_STRING_INITIALIZER(struct cmd_set_mirror_mask_result,
7320 				mirror, "mirror-rule");
7321 cmdline_parse_token_num_t cmd_mirror_mask_ruleid =
7322 	TOKEN_NUM_INITIALIZER(struct cmd_set_mirror_mask_result,
7323 				rule_id, UINT8);
7324 cmdline_parse_token_string_t cmd_mirror_mask_what =
7325 	TOKEN_STRING_INITIALIZER(struct cmd_set_mirror_mask_result,
7326 				what, "pool-mirror-up#pool-mirror-down"
7327 				      "#vlan-mirror");
7328 cmdline_parse_token_string_t cmd_mirror_mask_value =
7329 	TOKEN_STRING_INITIALIZER(struct cmd_set_mirror_mask_result,
7330 				value, NULL);
7331 cmdline_parse_token_string_t cmd_mirror_mask_dstpool =
7332 	TOKEN_STRING_INITIALIZER(struct cmd_set_mirror_mask_result,
7333 				dstpool, "dst-pool");
7334 cmdline_parse_token_num_t cmd_mirror_mask_poolid =
7335 	TOKEN_NUM_INITIALIZER(struct cmd_set_mirror_mask_result,
7336 				dstpool_id, UINT8);
7337 cmdline_parse_token_string_t cmd_mirror_mask_on =
7338 	TOKEN_STRING_INITIALIZER(struct cmd_set_mirror_mask_result,
7339 				on, "on#off");
7340 
7341 static void
7342 cmd_set_mirror_mask_parsed(void *parsed_result,
7343 		       __attribute__((unused)) struct cmdline *cl,
7344 		       __attribute__((unused)) void *data)
7345 {
7346 	int ret,nb_item,i;
7347 	struct cmd_set_mirror_mask_result *res = parsed_result;
7348 	struct rte_eth_mirror_conf mr_conf;
7349 
7350 	memset(&mr_conf, 0, sizeof(struct rte_eth_mirror_conf));
7351 
7352 	unsigned int vlan_list[ETH_MIRROR_MAX_VLANS];
7353 
7354 	mr_conf.dst_pool = res->dstpool_id;
7355 
7356 	if (!strcmp(res->what, "pool-mirror-up")) {
7357 		mr_conf.pool_mask = strtoull(res->value, NULL, 16);
7358 		mr_conf.rule_type = ETH_MIRROR_VIRTUAL_POOL_UP;
7359 	} else if (!strcmp(res->what, "pool-mirror-down")) {
7360 		mr_conf.pool_mask = strtoull(res->value, NULL, 16);
7361 		mr_conf.rule_type = ETH_MIRROR_VIRTUAL_POOL_DOWN;
7362 	} else if (!strcmp(res->what, "vlan-mirror")) {
7363 		mr_conf.rule_type = ETH_MIRROR_VLAN;
7364 		nb_item = parse_item_list(res->value, "vlan",
7365 				ETH_MIRROR_MAX_VLANS, vlan_list, 1);
7366 		if (nb_item <= 0)
7367 			return;
7368 
7369 		for (i = 0; i < nb_item; i++) {
7370 			if (vlan_list[i] > ETHER_MAX_VLAN_ID) {
7371 				printf("Invalid vlan_id: must be < 4096\n");
7372 				return;
7373 			}
7374 
7375 			mr_conf.vlan.vlan_id[i] = (uint16_t)vlan_list[i];
7376 			mr_conf.vlan.vlan_mask |= 1ULL << i;
7377 		}
7378 	}
7379 
7380 	if (!strcmp(res->on, "on"))
7381 		ret = rte_eth_mirror_rule_set(res->port_id, &mr_conf,
7382 						res->rule_id, 1);
7383 	else
7384 		ret = rte_eth_mirror_rule_set(res->port_id, &mr_conf,
7385 						res->rule_id, 0);
7386 	if (ret < 0)
7387 		printf("mirror rule add error: (%s)\n", strerror(-ret));
7388 }
7389 
7390 cmdline_parse_inst_t cmd_set_mirror_mask = {
7391 		.f = cmd_set_mirror_mask_parsed,
7392 		.data = NULL,
7393 		.help_str = "set port <port_id> mirror-rule <rule_id> "
7394 			"pool-mirror-up|pool-mirror-down|vlan-mirror "
7395 			"<pool_mask|vlan_id[,vlan_id]*> dst-pool <pool_id> on|off",
7396 		.tokens = {
7397 			(void *)&cmd_mirror_mask_set,
7398 			(void *)&cmd_mirror_mask_port,
7399 			(void *)&cmd_mirror_mask_portid,
7400 			(void *)&cmd_mirror_mask_mirror,
7401 			(void *)&cmd_mirror_mask_ruleid,
7402 			(void *)&cmd_mirror_mask_what,
7403 			(void *)&cmd_mirror_mask_value,
7404 			(void *)&cmd_mirror_mask_dstpool,
7405 			(void *)&cmd_mirror_mask_poolid,
7406 			(void *)&cmd_mirror_mask_on,
7407 			NULL,
7408 		},
7409 };
7410 
7411 /* *** CONFIGURE VM MIRROR UDLINK/DOWNLINK RULE *** */
7412 struct cmd_set_mirror_link_result {
7413 	cmdline_fixed_string_t set;
7414 	cmdline_fixed_string_t port;
7415 	uint8_t port_id;
7416 	cmdline_fixed_string_t mirror;
7417 	uint8_t rule_id;
7418 	cmdline_fixed_string_t what;
7419 	cmdline_fixed_string_t dstpool;
7420 	uint8_t dstpool_id;
7421 	cmdline_fixed_string_t on;
7422 };
7423 
7424 cmdline_parse_token_string_t cmd_mirror_link_set =
7425 	TOKEN_STRING_INITIALIZER(struct cmd_set_mirror_link_result,
7426 				 set, "set");
7427 cmdline_parse_token_string_t cmd_mirror_link_port =
7428 	TOKEN_STRING_INITIALIZER(struct cmd_set_mirror_link_result,
7429 				port, "port");
7430 cmdline_parse_token_num_t cmd_mirror_link_portid =
7431 	TOKEN_NUM_INITIALIZER(struct cmd_set_mirror_link_result,
7432 				port_id, UINT8);
7433 cmdline_parse_token_string_t cmd_mirror_link_mirror =
7434 	TOKEN_STRING_INITIALIZER(struct cmd_set_mirror_link_result,
7435 				mirror, "mirror-rule");
7436 cmdline_parse_token_num_t cmd_mirror_link_ruleid =
7437 	TOKEN_NUM_INITIALIZER(struct cmd_set_mirror_link_result,
7438 			    rule_id, UINT8);
7439 cmdline_parse_token_string_t cmd_mirror_link_what =
7440 	TOKEN_STRING_INITIALIZER(struct cmd_set_mirror_link_result,
7441 				what, "uplink-mirror#downlink-mirror");
7442 cmdline_parse_token_string_t cmd_mirror_link_dstpool =
7443 	TOKEN_STRING_INITIALIZER(struct cmd_set_mirror_link_result,
7444 				dstpool, "dst-pool");
7445 cmdline_parse_token_num_t cmd_mirror_link_poolid =
7446 	TOKEN_NUM_INITIALIZER(struct cmd_set_mirror_link_result,
7447 				dstpool_id, UINT8);
7448 cmdline_parse_token_string_t cmd_mirror_link_on =
7449 	TOKEN_STRING_INITIALIZER(struct cmd_set_mirror_link_result,
7450 				on, "on#off");
7451 
7452 static void
7453 cmd_set_mirror_link_parsed(void *parsed_result,
7454 		       __attribute__((unused)) struct cmdline *cl,
7455 		       __attribute__((unused)) void *data)
7456 {
7457 	int ret;
7458 	struct cmd_set_mirror_link_result *res = parsed_result;
7459 	struct rte_eth_mirror_conf mr_conf;
7460 
7461 	memset(&mr_conf, 0, sizeof(struct rte_eth_mirror_conf));
7462 	if (!strcmp(res->what, "uplink-mirror"))
7463 		mr_conf.rule_type = ETH_MIRROR_UPLINK_PORT;
7464 	else
7465 		mr_conf.rule_type = ETH_MIRROR_DOWNLINK_PORT;
7466 
7467 	mr_conf.dst_pool = res->dstpool_id;
7468 
7469 	if (!strcmp(res->on, "on"))
7470 		ret = rte_eth_mirror_rule_set(res->port_id, &mr_conf,
7471 						res->rule_id, 1);
7472 	else
7473 		ret = rte_eth_mirror_rule_set(res->port_id, &mr_conf,
7474 						res->rule_id, 0);
7475 
7476 	/* check the return value and print it if is < 0 */
7477 	if (ret < 0)
7478 		printf("mirror rule add error: (%s)\n", strerror(-ret));
7479 
7480 }
7481 
7482 cmdline_parse_inst_t cmd_set_mirror_link = {
7483 		.f = cmd_set_mirror_link_parsed,
7484 		.data = NULL,
7485 		.help_str = "set port <port_id> mirror-rule <rule_id> "
7486 			"uplink-mirror|downlink-mirror dst-pool <pool_id> on|off",
7487 		.tokens = {
7488 			(void *)&cmd_mirror_link_set,
7489 			(void *)&cmd_mirror_link_port,
7490 			(void *)&cmd_mirror_link_portid,
7491 			(void *)&cmd_mirror_link_mirror,
7492 			(void *)&cmd_mirror_link_ruleid,
7493 			(void *)&cmd_mirror_link_what,
7494 			(void *)&cmd_mirror_link_dstpool,
7495 			(void *)&cmd_mirror_link_poolid,
7496 			(void *)&cmd_mirror_link_on,
7497 			NULL,
7498 		},
7499 };
7500 
7501 /* *** RESET VM MIRROR RULE *** */
7502 struct cmd_rm_mirror_rule_result {
7503 	cmdline_fixed_string_t reset;
7504 	cmdline_fixed_string_t port;
7505 	uint8_t port_id;
7506 	cmdline_fixed_string_t mirror;
7507 	uint8_t rule_id;
7508 };
7509 
7510 cmdline_parse_token_string_t cmd_rm_mirror_rule_reset =
7511 	TOKEN_STRING_INITIALIZER(struct cmd_rm_mirror_rule_result,
7512 				 reset, "reset");
7513 cmdline_parse_token_string_t cmd_rm_mirror_rule_port =
7514 	TOKEN_STRING_INITIALIZER(struct cmd_rm_mirror_rule_result,
7515 				port, "port");
7516 cmdline_parse_token_num_t cmd_rm_mirror_rule_portid =
7517 	TOKEN_NUM_INITIALIZER(struct cmd_rm_mirror_rule_result,
7518 				port_id, UINT8);
7519 cmdline_parse_token_string_t cmd_rm_mirror_rule_mirror =
7520 	TOKEN_STRING_INITIALIZER(struct cmd_rm_mirror_rule_result,
7521 				mirror, "mirror-rule");
7522 cmdline_parse_token_num_t cmd_rm_mirror_rule_ruleid =
7523 	TOKEN_NUM_INITIALIZER(struct cmd_rm_mirror_rule_result,
7524 				rule_id, UINT8);
7525 
7526 static void
7527 cmd_reset_mirror_rule_parsed(void *parsed_result,
7528 		       __attribute__((unused)) struct cmdline *cl,
7529 		       __attribute__((unused)) void *data)
7530 {
7531 	int ret;
7532 	struct cmd_set_mirror_link_result *res = parsed_result;
7533         /* check rule_id */
7534 	ret = rte_eth_mirror_rule_reset(res->port_id,res->rule_id);
7535 	if(ret < 0)
7536 		printf("mirror rule remove error: (%s)\n", strerror(-ret));
7537 }
7538 
7539 cmdline_parse_inst_t cmd_reset_mirror_rule = {
7540 		.f = cmd_reset_mirror_rule_parsed,
7541 		.data = NULL,
7542 		.help_str = "reset port <port_id> mirror-rule <rule_id>",
7543 		.tokens = {
7544 			(void *)&cmd_rm_mirror_rule_reset,
7545 			(void *)&cmd_rm_mirror_rule_port,
7546 			(void *)&cmd_rm_mirror_rule_portid,
7547 			(void *)&cmd_rm_mirror_rule_mirror,
7548 			(void *)&cmd_rm_mirror_rule_ruleid,
7549 			NULL,
7550 		},
7551 };
7552 
7553 /* ******************************************************************************** */
7554 
7555 struct cmd_dump_result {
7556 	cmdline_fixed_string_t dump;
7557 };
7558 
7559 static void
7560 dump_struct_sizes(void)
7561 {
7562 #define DUMP_SIZE(t) printf("sizeof(" #t ") = %u\n", (unsigned)sizeof(t));
7563 	DUMP_SIZE(struct rte_mbuf);
7564 	DUMP_SIZE(struct rte_mempool);
7565 	DUMP_SIZE(struct rte_ring);
7566 #undef DUMP_SIZE
7567 }
7568 
7569 static void cmd_dump_parsed(void *parsed_result,
7570 			    __attribute__((unused)) struct cmdline *cl,
7571 			    __attribute__((unused)) void *data)
7572 {
7573 	struct cmd_dump_result *res = parsed_result;
7574 
7575 	if (!strcmp(res->dump, "dump_physmem"))
7576 		rte_dump_physmem_layout(stdout);
7577 	else if (!strcmp(res->dump, "dump_memzone"))
7578 		rte_memzone_dump(stdout);
7579 	else if (!strcmp(res->dump, "dump_struct_sizes"))
7580 		dump_struct_sizes();
7581 	else if (!strcmp(res->dump, "dump_ring"))
7582 		rte_ring_list_dump(stdout);
7583 	else if (!strcmp(res->dump, "dump_mempool"))
7584 		rte_mempool_list_dump(stdout);
7585 	else if (!strcmp(res->dump, "dump_devargs"))
7586 		rte_eal_devargs_dump(stdout);
7587 }
7588 
7589 cmdline_parse_token_string_t cmd_dump_dump =
7590 	TOKEN_STRING_INITIALIZER(struct cmd_dump_result, dump,
7591 		"dump_physmem#"
7592 		"dump_memzone#"
7593 		"dump_struct_sizes#"
7594 		"dump_ring#"
7595 		"dump_mempool#"
7596 		"dump_devargs");
7597 
7598 cmdline_parse_inst_t cmd_dump = {
7599 	.f = cmd_dump_parsed,  /* function to call */
7600 	.data = NULL,      /* 2nd arg of func */
7601 	.help_str = "Dump status",
7602 	.tokens = {        /* token list, NULL terminated */
7603 		(void *)&cmd_dump_dump,
7604 		NULL,
7605 	},
7606 };
7607 
7608 /* ******************************************************************************** */
7609 
7610 struct cmd_dump_one_result {
7611 	cmdline_fixed_string_t dump;
7612 	cmdline_fixed_string_t name;
7613 };
7614 
7615 static void cmd_dump_one_parsed(void *parsed_result, struct cmdline *cl,
7616 				__attribute__((unused)) void *data)
7617 {
7618 	struct cmd_dump_one_result *res = parsed_result;
7619 
7620 	if (!strcmp(res->dump, "dump_ring")) {
7621 		struct rte_ring *r;
7622 		r = rte_ring_lookup(res->name);
7623 		if (r == NULL) {
7624 			cmdline_printf(cl, "Cannot find ring\n");
7625 			return;
7626 		}
7627 		rte_ring_dump(stdout, r);
7628 	} else if (!strcmp(res->dump, "dump_mempool")) {
7629 		struct rte_mempool *mp;
7630 		mp = rte_mempool_lookup(res->name);
7631 		if (mp == NULL) {
7632 			cmdline_printf(cl, "Cannot find mempool\n");
7633 			return;
7634 		}
7635 		rte_mempool_dump(stdout, mp);
7636 	}
7637 }
7638 
7639 cmdline_parse_token_string_t cmd_dump_one_dump =
7640 	TOKEN_STRING_INITIALIZER(struct cmd_dump_one_result, dump,
7641 				 "dump_ring#dump_mempool");
7642 
7643 cmdline_parse_token_string_t cmd_dump_one_name =
7644 	TOKEN_STRING_INITIALIZER(struct cmd_dump_one_result, name, NULL);
7645 
7646 cmdline_parse_inst_t cmd_dump_one = {
7647 	.f = cmd_dump_one_parsed,  /* function to call */
7648 	.data = NULL,      /* 2nd arg of func */
7649 	.help_str = "dump_ring|dump_mempool <name>: Dump one ring/mempool",
7650 	.tokens = {        /* token list, NULL terminated */
7651 		(void *)&cmd_dump_one_dump,
7652 		(void *)&cmd_dump_one_name,
7653 		NULL,
7654 	},
7655 };
7656 
7657 /* *** Add/Del syn filter *** */
7658 struct cmd_syn_filter_result {
7659 	cmdline_fixed_string_t filter;
7660 	uint8_t port_id;
7661 	cmdline_fixed_string_t ops;
7662 	cmdline_fixed_string_t priority;
7663 	cmdline_fixed_string_t high;
7664 	cmdline_fixed_string_t queue;
7665 	uint16_t queue_id;
7666 };
7667 
7668 static void
7669 cmd_syn_filter_parsed(void *parsed_result,
7670 			__attribute__((unused)) struct cmdline *cl,
7671 			__attribute__((unused)) void *data)
7672 {
7673 	struct cmd_syn_filter_result *res = parsed_result;
7674 	struct rte_eth_syn_filter syn_filter;
7675 	int ret = 0;
7676 
7677 	ret = rte_eth_dev_filter_supported(res->port_id,
7678 					RTE_ETH_FILTER_SYN);
7679 	if (ret < 0) {
7680 		printf("syn filter is not supported on port %u.\n",
7681 				res->port_id);
7682 		return;
7683 	}
7684 
7685 	memset(&syn_filter, 0, sizeof(syn_filter));
7686 
7687 	if (!strcmp(res->ops, "add")) {
7688 		if (!strcmp(res->high, "high"))
7689 			syn_filter.hig_pri = 1;
7690 		else
7691 			syn_filter.hig_pri = 0;
7692 
7693 		syn_filter.queue = res->queue_id;
7694 		ret = rte_eth_dev_filter_ctrl(res->port_id,
7695 						RTE_ETH_FILTER_SYN,
7696 						RTE_ETH_FILTER_ADD,
7697 						&syn_filter);
7698 	} else
7699 		ret = rte_eth_dev_filter_ctrl(res->port_id,
7700 						RTE_ETH_FILTER_SYN,
7701 						RTE_ETH_FILTER_DELETE,
7702 						&syn_filter);
7703 
7704 	if (ret < 0)
7705 		printf("syn filter programming error: (%s)\n",
7706 				strerror(-ret));
7707 }
7708 
7709 cmdline_parse_token_string_t cmd_syn_filter_filter =
7710 	TOKEN_STRING_INITIALIZER(struct cmd_syn_filter_result,
7711 	filter, "syn_filter");
7712 cmdline_parse_token_num_t cmd_syn_filter_port_id =
7713 	TOKEN_NUM_INITIALIZER(struct cmd_syn_filter_result,
7714 	port_id, UINT8);
7715 cmdline_parse_token_string_t cmd_syn_filter_ops =
7716 	TOKEN_STRING_INITIALIZER(struct cmd_syn_filter_result,
7717 	ops, "add#del");
7718 cmdline_parse_token_string_t cmd_syn_filter_priority =
7719 	TOKEN_STRING_INITIALIZER(struct cmd_syn_filter_result,
7720 				priority, "priority");
7721 cmdline_parse_token_string_t cmd_syn_filter_high =
7722 	TOKEN_STRING_INITIALIZER(struct cmd_syn_filter_result,
7723 				high, "high#low");
7724 cmdline_parse_token_string_t cmd_syn_filter_queue =
7725 	TOKEN_STRING_INITIALIZER(struct cmd_syn_filter_result,
7726 				queue, "queue");
7727 cmdline_parse_token_num_t cmd_syn_filter_queue_id =
7728 	TOKEN_NUM_INITIALIZER(struct cmd_syn_filter_result,
7729 				queue_id, UINT16);
7730 
7731 cmdline_parse_inst_t cmd_syn_filter = {
7732 	.f = cmd_syn_filter_parsed,
7733 	.data = NULL,
7734 	.help_str = "syn_filter <port_id> add|del priority high|low queue "
7735 		"<queue_id>: Add/Delete syn filter",
7736 	.tokens = {
7737 		(void *)&cmd_syn_filter_filter,
7738 		(void *)&cmd_syn_filter_port_id,
7739 		(void *)&cmd_syn_filter_ops,
7740 		(void *)&cmd_syn_filter_priority,
7741 		(void *)&cmd_syn_filter_high,
7742 		(void *)&cmd_syn_filter_queue,
7743 		(void *)&cmd_syn_filter_queue_id,
7744 		NULL,
7745 	},
7746 };
7747 
7748 /* *** ADD/REMOVE A 2tuple FILTER *** */
7749 struct cmd_2tuple_filter_result {
7750 	cmdline_fixed_string_t filter;
7751 	uint8_t  port_id;
7752 	cmdline_fixed_string_t ops;
7753 	cmdline_fixed_string_t dst_port;
7754 	uint16_t dst_port_value;
7755 	cmdline_fixed_string_t protocol;
7756 	uint8_t protocol_value;
7757 	cmdline_fixed_string_t mask;
7758 	uint8_t  mask_value;
7759 	cmdline_fixed_string_t tcp_flags;
7760 	uint8_t tcp_flags_value;
7761 	cmdline_fixed_string_t priority;
7762 	uint8_t  priority_value;
7763 	cmdline_fixed_string_t queue;
7764 	uint16_t  queue_id;
7765 };
7766 
7767 static void
7768 cmd_2tuple_filter_parsed(void *parsed_result,
7769 			__attribute__((unused)) struct cmdline *cl,
7770 			__attribute__((unused)) void *data)
7771 {
7772 	struct rte_eth_ntuple_filter filter;
7773 	struct cmd_2tuple_filter_result *res = parsed_result;
7774 	int ret = 0;
7775 
7776 	ret = rte_eth_dev_filter_supported(res->port_id, RTE_ETH_FILTER_NTUPLE);
7777 	if (ret < 0) {
7778 		printf("ntuple filter is not supported on port %u.\n",
7779 			res->port_id);
7780 		return;
7781 	}
7782 
7783 	memset(&filter, 0, sizeof(struct rte_eth_ntuple_filter));
7784 
7785 	filter.flags = RTE_2TUPLE_FLAGS;
7786 	filter.dst_port_mask = (res->mask_value & 0x02) ? UINT16_MAX : 0;
7787 	filter.proto_mask = (res->mask_value & 0x01) ? UINT8_MAX : 0;
7788 	filter.proto = res->protocol_value;
7789 	filter.priority = res->priority_value;
7790 	if (res->tcp_flags_value != 0 && filter.proto != IPPROTO_TCP) {
7791 		printf("nonzero tcp_flags is only meaningful"
7792 			" when protocol is TCP.\n");
7793 		return;
7794 	}
7795 	if (res->tcp_flags_value > TCP_FLAG_ALL) {
7796 		printf("invalid TCP flags.\n");
7797 		return;
7798 	}
7799 
7800 	if (res->tcp_flags_value != 0) {
7801 		filter.flags |= RTE_NTUPLE_FLAGS_TCP_FLAG;
7802 		filter.tcp_flags = res->tcp_flags_value;
7803 	}
7804 
7805 	/* need convert to big endian. */
7806 	filter.dst_port = rte_cpu_to_be_16(res->dst_port_value);
7807 	filter.queue = res->queue_id;
7808 
7809 	if (!strcmp(res->ops, "add"))
7810 		ret = rte_eth_dev_filter_ctrl(res->port_id,
7811 				RTE_ETH_FILTER_NTUPLE,
7812 				RTE_ETH_FILTER_ADD,
7813 				&filter);
7814 	else
7815 		ret = rte_eth_dev_filter_ctrl(res->port_id,
7816 				RTE_ETH_FILTER_NTUPLE,
7817 				RTE_ETH_FILTER_DELETE,
7818 				&filter);
7819 	if (ret < 0)
7820 		printf("2tuple filter programming error: (%s)\n",
7821 			strerror(-ret));
7822 
7823 }
7824 
7825 cmdline_parse_token_string_t cmd_2tuple_filter_filter =
7826 	TOKEN_STRING_INITIALIZER(struct cmd_2tuple_filter_result,
7827 				 filter, "2tuple_filter");
7828 cmdline_parse_token_num_t cmd_2tuple_filter_port_id =
7829 	TOKEN_NUM_INITIALIZER(struct cmd_2tuple_filter_result,
7830 				port_id, UINT8);
7831 cmdline_parse_token_string_t cmd_2tuple_filter_ops =
7832 	TOKEN_STRING_INITIALIZER(struct cmd_2tuple_filter_result,
7833 				 ops, "add#del");
7834 cmdline_parse_token_string_t cmd_2tuple_filter_dst_port =
7835 	TOKEN_STRING_INITIALIZER(struct cmd_2tuple_filter_result,
7836 				dst_port, "dst_port");
7837 cmdline_parse_token_num_t cmd_2tuple_filter_dst_port_value =
7838 	TOKEN_NUM_INITIALIZER(struct cmd_2tuple_filter_result,
7839 				dst_port_value, UINT16);
7840 cmdline_parse_token_string_t cmd_2tuple_filter_protocol =
7841 	TOKEN_STRING_INITIALIZER(struct cmd_2tuple_filter_result,
7842 				protocol, "protocol");
7843 cmdline_parse_token_num_t cmd_2tuple_filter_protocol_value =
7844 	TOKEN_NUM_INITIALIZER(struct cmd_2tuple_filter_result,
7845 				protocol_value, UINT8);
7846 cmdline_parse_token_string_t cmd_2tuple_filter_mask =
7847 	TOKEN_STRING_INITIALIZER(struct cmd_2tuple_filter_result,
7848 				mask, "mask");
7849 cmdline_parse_token_num_t cmd_2tuple_filter_mask_value =
7850 	TOKEN_NUM_INITIALIZER(struct cmd_2tuple_filter_result,
7851 				mask_value, INT8);
7852 cmdline_parse_token_string_t cmd_2tuple_filter_tcp_flags =
7853 	TOKEN_STRING_INITIALIZER(struct cmd_2tuple_filter_result,
7854 				tcp_flags, "tcp_flags");
7855 cmdline_parse_token_num_t cmd_2tuple_filter_tcp_flags_value =
7856 	TOKEN_NUM_INITIALIZER(struct cmd_2tuple_filter_result,
7857 				tcp_flags_value, UINT8);
7858 cmdline_parse_token_string_t cmd_2tuple_filter_priority =
7859 	TOKEN_STRING_INITIALIZER(struct cmd_2tuple_filter_result,
7860 				priority, "priority");
7861 cmdline_parse_token_num_t cmd_2tuple_filter_priority_value =
7862 	TOKEN_NUM_INITIALIZER(struct cmd_2tuple_filter_result,
7863 				priority_value, UINT8);
7864 cmdline_parse_token_string_t cmd_2tuple_filter_queue =
7865 	TOKEN_STRING_INITIALIZER(struct cmd_2tuple_filter_result,
7866 				queue, "queue");
7867 cmdline_parse_token_num_t cmd_2tuple_filter_queue_id =
7868 	TOKEN_NUM_INITIALIZER(struct cmd_2tuple_filter_result,
7869 				queue_id, UINT16);
7870 
7871 cmdline_parse_inst_t cmd_2tuple_filter = {
7872 	.f = cmd_2tuple_filter_parsed,
7873 	.data = NULL,
7874 	.help_str = "2tuple_filter <port_id> add|del dst_port <value> protocol "
7875 		"<value> mask <value> tcp_flags <value> priority <value> queue "
7876 		"<queue_id>: Add a 2tuple filter",
7877 	.tokens = {
7878 		(void *)&cmd_2tuple_filter_filter,
7879 		(void *)&cmd_2tuple_filter_port_id,
7880 		(void *)&cmd_2tuple_filter_ops,
7881 		(void *)&cmd_2tuple_filter_dst_port,
7882 		(void *)&cmd_2tuple_filter_dst_port_value,
7883 		(void *)&cmd_2tuple_filter_protocol,
7884 		(void *)&cmd_2tuple_filter_protocol_value,
7885 		(void *)&cmd_2tuple_filter_mask,
7886 		(void *)&cmd_2tuple_filter_mask_value,
7887 		(void *)&cmd_2tuple_filter_tcp_flags,
7888 		(void *)&cmd_2tuple_filter_tcp_flags_value,
7889 		(void *)&cmd_2tuple_filter_priority,
7890 		(void *)&cmd_2tuple_filter_priority_value,
7891 		(void *)&cmd_2tuple_filter_queue,
7892 		(void *)&cmd_2tuple_filter_queue_id,
7893 		NULL,
7894 	},
7895 };
7896 
7897 /* *** ADD/REMOVE A 5tuple FILTER *** */
7898 struct cmd_5tuple_filter_result {
7899 	cmdline_fixed_string_t filter;
7900 	uint8_t  port_id;
7901 	cmdline_fixed_string_t ops;
7902 	cmdline_fixed_string_t dst_ip;
7903 	cmdline_ipaddr_t dst_ip_value;
7904 	cmdline_fixed_string_t src_ip;
7905 	cmdline_ipaddr_t src_ip_value;
7906 	cmdline_fixed_string_t dst_port;
7907 	uint16_t dst_port_value;
7908 	cmdline_fixed_string_t src_port;
7909 	uint16_t src_port_value;
7910 	cmdline_fixed_string_t protocol;
7911 	uint8_t protocol_value;
7912 	cmdline_fixed_string_t mask;
7913 	uint8_t  mask_value;
7914 	cmdline_fixed_string_t tcp_flags;
7915 	uint8_t tcp_flags_value;
7916 	cmdline_fixed_string_t priority;
7917 	uint8_t  priority_value;
7918 	cmdline_fixed_string_t queue;
7919 	uint16_t  queue_id;
7920 };
7921 
7922 static void
7923 cmd_5tuple_filter_parsed(void *parsed_result,
7924 			__attribute__((unused)) struct cmdline *cl,
7925 			__attribute__((unused)) void *data)
7926 {
7927 	struct rte_eth_ntuple_filter filter;
7928 	struct cmd_5tuple_filter_result *res = parsed_result;
7929 	int ret = 0;
7930 
7931 	ret = rte_eth_dev_filter_supported(res->port_id, RTE_ETH_FILTER_NTUPLE);
7932 	if (ret < 0) {
7933 		printf("ntuple filter is not supported on port %u.\n",
7934 			res->port_id);
7935 		return;
7936 	}
7937 
7938 	memset(&filter, 0, sizeof(struct rte_eth_ntuple_filter));
7939 
7940 	filter.flags = RTE_5TUPLE_FLAGS;
7941 	filter.dst_ip_mask = (res->mask_value & 0x10) ? UINT32_MAX : 0;
7942 	filter.src_ip_mask = (res->mask_value & 0x08) ? UINT32_MAX : 0;
7943 	filter.dst_port_mask = (res->mask_value & 0x04) ? UINT16_MAX : 0;
7944 	filter.src_port_mask = (res->mask_value & 0x02) ? UINT16_MAX : 0;
7945 	filter.proto_mask = (res->mask_value & 0x01) ? UINT8_MAX : 0;
7946 	filter.proto = res->protocol_value;
7947 	filter.priority = res->priority_value;
7948 	if (res->tcp_flags_value != 0 && filter.proto != IPPROTO_TCP) {
7949 		printf("nonzero tcp_flags is only meaningful"
7950 			" when protocol is TCP.\n");
7951 		return;
7952 	}
7953 	if (res->tcp_flags_value > TCP_FLAG_ALL) {
7954 		printf("invalid TCP flags.\n");
7955 		return;
7956 	}
7957 
7958 	if (res->tcp_flags_value != 0) {
7959 		filter.flags |= RTE_NTUPLE_FLAGS_TCP_FLAG;
7960 		filter.tcp_flags = res->tcp_flags_value;
7961 	}
7962 
7963 	if (res->dst_ip_value.family == AF_INET)
7964 		/* no need to convert, already big endian. */
7965 		filter.dst_ip = res->dst_ip_value.addr.ipv4.s_addr;
7966 	else {
7967 		if (filter.dst_ip_mask == 0) {
7968 			printf("can not support ipv6 involved compare.\n");
7969 			return;
7970 		}
7971 		filter.dst_ip = 0;
7972 	}
7973 
7974 	if (res->src_ip_value.family == AF_INET)
7975 		/* no need to convert, already big endian. */
7976 		filter.src_ip = res->src_ip_value.addr.ipv4.s_addr;
7977 	else {
7978 		if (filter.src_ip_mask == 0) {
7979 			printf("can not support ipv6 involved compare.\n");
7980 			return;
7981 		}
7982 		filter.src_ip = 0;
7983 	}
7984 	/* need convert to big endian. */
7985 	filter.dst_port = rte_cpu_to_be_16(res->dst_port_value);
7986 	filter.src_port = rte_cpu_to_be_16(res->src_port_value);
7987 	filter.queue = res->queue_id;
7988 
7989 	if (!strcmp(res->ops, "add"))
7990 		ret = rte_eth_dev_filter_ctrl(res->port_id,
7991 				RTE_ETH_FILTER_NTUPLE,
7992 				RTE_ETH_FILTER_ADD,
7993 				&filter);
7994 	else
7995 		ret = rte_eth_dev_filter_ctrl(res->port_id,
7996 				RTE_ETH_FILTER_NTUPLE,
7997 				RTE_ETH_FILTER_DELETE,
7998 				&filter);
7999 	if (ret < 0)
8000 		printf("5tuple filter programming error: (%s)\n",
8001 			strerror(-ret));
8002 }
8003 
8004 cmdline_parse_token_string_t cmd_5tuple_filter_filter =
8005 	TOKEN_STRING_INITIALIZER(struct cmd_5tuple_filter_result,
8006 				 filter, "5tuple_filter");
8007 cmdline_parse_token_num_t cmd_5tuple_filter_port_id =
8008 	TOKEN_NUM_INITIALIZER(struct cmd_5tuple_filter_result,
8009 				port_id, UINT8);
8010 cmdline_parse_token_string_t cmd_5tuple_filter_ops =
8011 	TOKEN_STRING_INITIALIZER(struct cmd_5tuple_filter_result,
8012 				 ops, "add#del");
8013 cmdline_parse_token_string_t cmd_5tuple_filter_dst_ip =
8014 	TOKEN_STRING_INITIALIZER(struct cmd_5tuple_filter_result,
8015 				dst_ip, "dst_ip");
8016 cmdline_parse_token_ipaddr_t cmd_5tuple_filter_dst_ip_value =
8017 	TOKEN_IPADDR_INITIALIZER(struct cmd_5tuple_filter_result,
8018 				dst_ip_value);
8019 cmdline_parse_token_string_t cmd_5tuple_filter_src_ip =
8020 	TOKEN_STRING_INITIALIZER(struct cmd_5tuple_filter_result,
8021 				src_ip, "src_ip");
8022 cmdline_parse_token_ipaddr_t cmd_5tuple_filter_src_ip_value =
8023 	TOKEN_IPADDR_INITIALIZER(struct cmd_5tuple_filter_result,
8024 				src_ip_value);
8025 cmdline_parse_token_string_t cmd_5tuple_filter_dst_port =
8026 	TOKEN_STRING_INITIALIZER(struct cmd_5tuple_filter_result,
8027 				dst_port, "dst_port");
8028 cmdline_parse_token_num_t cmd_5tuple_filter_dst_port_value =
8029 	TOKEN_NUM_INITIALIZER(struct cmd_5tuple_filter_result,
8030 				dst_port_value, UINT16);
8031 cmdline_parse_token_string_t cmd_5tuple_filter_src_port =
8032 	TOKEN_STRING_INITIALIZER(struct cmd_5tuple_filter_result,
8033 				src_port, "src_port");
8034 cmdline_parse_token_num_t cmd_5tuple_filter_src_port_value =
8035 	TOKEN_NUM_INITIALIZER(struct cmd_5tuple_filter_result,
8036 				src_port_value, UINT16);
8037 cmdline_parse_token_string_t cmd_5tuple_filter_protocol =
8038 	TOKEN_STRING_INITIALIZER(struct cmd_5tuple_filter_result,
8039 				protocol, "protocol");
8040 cmdline_parse_token_num_t cmd_5tuple_filter_protocol_value =
8041 	TOKEN_NUM_INITIALIZER(struct cmd_5tuple_filter_result,
8042 				protocol_value, UINT8);
8043 cmdline_parse_token_string_t cmd_5tuple_filter_mask =
8044 	TOKEN_STRING_INITIALIZER(struct cmd_5tuple_filter_result,
8045 				mask, "mask");
8046 cmdline_parse_token_num_t cmd_5tuple_filter_mask_value =
8047 	TOKEN_NUM_INITIALIZER(struct cmd_5tuple_filter_result,
8048 				mask_value, INT8);
8049 cmdline_parse_token_string_t cmd_5tuple_filter_tcp_flags =
8050 	TOKEN_STRING_INITIALIZER(struct cmd_5tuple_filter_result,
8051 				tcp_flags, "tcp_flags");
8052 cmdline_parse_token_num_t cmd_5tuple_filter_tcp_flags_value =
8053 	TOKEN_NUM_INITIALIZER(struct cmd_5tuple_filter_result,
8054 				tcp_flags_value, UINT8);
8055 cmdline_parse_token_string_t cmd_5tuple_filter_priority =
8056 	TOKEN_STRING_INITIALIZER(struct cmd_5tuple_filter_result,
8057 				priority, "priority");
8058 cmdline_parse_token_num_t cmd_5tuple_filter_priority_value =
8059 	TOKEN_NUM_INITIALIZER(struct cmd_5tuple_filter_result,
8060 				priority_value, UINT8);
8061 cmdline_parse_token_string_t cmd_5tuple_filter_queue =
8062 	TOKEN_STRING_INITIALIZER(struct cmd_5tuple_filter_result,
8063 				queue, "queue");
8064 cmdline_parse_token_num_t cmd_5tuple_filter_queue_id =
8065 	TOKEN_NUM_INITIALIZER(struct cmd_5tuple_filter_result,
8066 				queue_id, UINT16);
8067 
8068 cmdline_parse_inst_t cmd_5tuple_filter = {
8069 	.f = cmd_5tuple_filter_parsed,
8070 	.data = NULL,
8071 	.help_str = "5tuple_filter <port_id> add|del dst_ip <value> "
8072 		"src_ip <value> dst_port <value> src_port <value> "
8073 		"protocol <value>  mask <value> tcp_flags <value> "
8074 		"priority <value> queue <queue_id>: Add/Del a 5tuple filter",
8075 	.tokens = {
8076 		(void *)&cmd_5tuple_filter_filter,
8077 		(void *)&cmd_5tuple_filter_port_id,
8078 		(void *)&cmd_5tuple_filter_ops,
8079 		(void *)&cmd_5tuple_filter_dst_ip,
8080 		(void *)&cmd_5tuple_filter_dst_ip_value,
8081 		(void *)&cmd_5tuple_filter_src_ip,
8082 		(void *)&cmd_5tuple_filter_src_ip_value,
8083 		(void *)&cmd_5tuple_filter_dst_port,
8084 		(void *)&cmd_5tuple_filter_dst_port_value,
8085 		(void *)&cmd_5tuple_filter_src_port,
8086 		(void *)&cmd_5tuple_filter_src_port_value,
8087 		(void *)&cmd_5tuple_filter_protocol,
8088 		(void *)&cmd_5tuple_filter_protocol_value,
8089 		(void *)&cmd_5tuple_filter_mask,
8090 		(void *)&cmd_5tuple_filter_mask_value,
8091 		(void *)&cmd_5tuple_filter_tcp_flags,
8092 		(void *)&cmd_5tuple_filter_tcp_flags_value,
8093 		(void *)&cmd_5tuple_filter_priority,
8094 		(void *)&cmd_5tuple_filter_priority_value,
8095 		(void *)&cmd_5tuple_filter_queue,
8096 		(void *)&cmd_5tuple_filter_queue_id,
8097 		NULL,
8098 	},
8099 };
8100 
8101 /* *** ADD/REMOVE A flex FILTER *** */
8102 struct cmd_flex_filter_result {
8103 	cmdline_fixed_string_t filter;
8104 	cmdline_fixed_string_t ops;
8105 	uint8_t port_id;
8106 	cmdline_fixed_string_t len;
8107 	uint8_t len_value;
8108 	cmdline_fixed_string_t bytes;
8109 	cmdline_fixed_string_t bytes_value;
8110 	cmdline_fixed_string_t mask;
8111 	cmdline_fixed_string_t mask_value;
8112 	cmdline_fixed_string_t priority;
8113 	uint8_t priority_value;
8114 	cmdline_fixed_string_t queue;
8115 	uint16_t queue_id;
8116 };
8117 
8118 static int xdigit2val(unsigned char c)
8119 {
8120 	int val;
8121 	if (isdigit(c))
8122 		val = c - '0';
8123 	else if (isupper(c))
8124 		val = c - 'A' + 10;
8125 	else
8126 		val = c - 'a' + 10;
8127 	return val;
8128 }
8129 
8130 static void
8131 cmd_flex_filter_parsed(void *parsed_result,
8132 			  __attribute__((unused)) struct cmdline *cl,
8133 			  __attribute__((unused)) void *data)
8134 {
8135 	int ret = 0;
8136 	struct rte_eth_flex_filter filter;
8137 	struct cmd_flex_filter_result *res = parsed_result;
8138 	char *bytes_ptr, *mask_ptr;
8139 	uint16_t len, i, j = 0;
8140 	char c;
8141 	int val;
8142 	uint8_t byte = 0;
8143 
8144 	if (res->len_value > RTE_FLEX_FILTER_MAXLEN) {
8145 		printf("the len exceed the max length 128\n");
8146 		return;
8147 	}
8148 	memset(&filter, 0, sizeof(struct rte_eth_flex_filter));
8149 	filter.len = res->len_value;
8150 	filter.priority = res->priority_value;
8151 	filter.queue = res->queue_id;
8152 	bytes_ptr = res->bytes_value;
8153 	mask_ptr = res->mask_value;
8154 
8155 	 /* translate bytes string to array. */
8156 	if (bytes_ptr[0] == '0' && ((bytes_ptr[1] == 'x') ||
8157 		(bytes_ptr[1] == 'X')))
8158 		bytes_ptr += 2;
8159 	len = strnlen(bytes_ptr, res->len_value * 2);
8160 	if (len == 0 || (len % 8 != 0)) {
8161 		printf("please check len and bytes input\n");
8162 		return;
8163 	}
8164 	for (i = 0; i < len; i++) {
8165 		c = bytes_ptr[i];
8166 		if (isxdigit(c) == 0) {
8167 			/* invalid characters. */
8168 			printf("invalid input\n");
8169 			return;
8170 		}
8171 		val = xdigit2val(c);
8172 		if (i % 2) {
8173 			byte |= val;
8174 			filter.bytes[j] = byte;
8175 			printf("bytes[%d]:%02x ", j, filter.bytes[j]);
8176 			j++;
8177 			byte = 0;
8178 		} else
8179 			byte |= val << 4;
8180 	}
8181 	printf("\n");
8182 	 /* translate mask string to uint8_t array. */
8183 	if (mask_ptr[0] == '0' && ((mask_ptr[1] == 'x') ||
8184 		(mask_ptr[1] == 'X')))
8185 		mask_ptr += 2;
8186 	len = strnlen(mask_ptr, (res->len_value + 3) / 4);
8187 	if (len == 0) {
8188 		printf("invalid input\n");
8189 		return;
8190 	}
8191 	j = 0;
8192 	byte = 0;
8193 	for (i = 0; i < len; i++) {
8194 		c = mask_ptr[i];
8195 		if (isxdigit(c) == 0) {
8196 			/* invalid characters. */
8197 			printf("invalid input\n");
8198 			return;
8199 		}
8200 		val = xdigit2val(c);
8201 		if (i % 2) {
8202 			byte |= val;
8203 			filter.mask[j] = byte;
8204 			printf("mask[%d]:%02x ", j, filter.mask[j]);
8205 			j++;
8206 			byte = 0;
8207 		} else
8208 			byte |= val << 4;
8209 	}
8210 	printf("\n");
8211 
8212 	if (!strcmp(res->ops, "add"))
8213 		ret = rte_eth_dev_filter_ctrl(res->port_id,
8214 				RTE_ETH_FILTER_FLEXIBLE,
8215 				RTE_ETH_FILTER_ADD,
8216 				&filter);
8217 	else
8218 		ret = rte_eth_dev_filter_ctrl(res->port_id,
8219 				RTE_ETH_FILTER_FLEXIBLE,
8220 				RTE_ETH_FILTER_DELETE,
8221 				&filter);
8222 
8223 	if (ret < 0)
8224 		printf("flex filter setting error: (%s)\n", strerror(-ret));
8225 }
8226 
8227 cmdline_parse_token_string_t cmd_flex_filter_filter =
8228 	TOKEN_STRING_INITIALIZER(struct cmd_flex_filter_result,
8229 				filter, "flex_filter");
8230 cmdline_parse_token_num_t cmd_flex_filter_port_id =
8231 	TOKEN_NUM_INITIALIZER(struct cmd_flex_filter_result,
8232 				port_id, UINT8);
8233 cmdline_parse_token_string_t cmd_flex_filter_ops =
8234 	TOKEN_STRING_INITIALIZER(struct cmd_flex_filter_result,
8235 				ops, "add#del");
8236 cmdline_parse_token_string_t cmd_flex_filter_len =
8237 	TOKEN_STRING_INITIALIZER(struct cmd_flex_filter_result,
8238 				len, "len");
8239 cmdline_parse_token_num_t cmd_flex_filter_len_value =
8240 	TOKEN_NUM_INITIALIZER(struct cmd_flex_filter_result,
8241 				len_value, UINT8);
8242 cmdline_parse_token_string_t cmd_flex_filter_bytes =
8243 	TOKEN_STRING_INITIALIZER(struct cmd_flex_filter_result,
8244 				bytes, "bytes");
8245 cmdline_parse_token_string_t cmd_flex_filter_bytes_value =
8246 	TOKEN_STRING_INITIALIZER(struct cmd_flex_filter_result,
8247 				bytes_value, NULL);
8248 cmdline_parse_token_string_t cmd_flex_filter_mask =
8249 	TOKEN_STRING_INITIALIZER(struct cmd_flex_filter_result,
8250 				mask, "mask");
8251 cmdline_parse_token_string_t cmd_flex_filter_mask_value =
8252 	TOKEN_STRING_INITIALIZER(struct cmd_flex_filter_result,
8253 				mask_value, NULL);
8254 cmdline_parse_token_string_t cmd_flex_filter_priority =
8255 	TOKEN_STRING_INITIALIZER(struct cmd_flex_filter_result,
8256 				priority, "priority");
8257 cmdline_parse_token_num_t cmd_flex_filter_priority_value =
8258 	TOKEN_NUM_INITIALIZER(struct cmd_flex_filter_result,
8259 				priority_value, UINT8);
8260 cmdline_parse_token_string_t cmd_flex_filter_queue =
8261 	TOKEN_STRING_INITIALIZER(struct cmd_flex_filter_result,
8262 				queue, "queue");
8263 cmdline_parse_token_num_t cmd_flex_filter_queue_id =
8264 	TOKEN_NUM_INITIALIZER(struct cmd_flex_filter_result,
8265 				queue_id, UINT16);
8266 cmdline_parse_inst_t cmd_flex_filter = {
8267 	.f = cmd_flex_filter_parsed,
8268 	.data = NULL,
8269 	.help_str = "flex_filter <port_id> add|del len <value> bytes "
8270 		"<value> mask <value> priority <value> queue <queue_id>: "
8271 		"Add/Del a flex filter",
8272 	.tokens = {
8273 		(void *)&cmd_flex_filter_filter,
8274 		(void *)&cmd_flex_filter_port_id,
8275 		(void *)&cmd_flex_filter_ops,
8276 		(void *)&cmd_flex_filter_len,
8277 		(void *)&cmd_flex_filter_len_value,
8278 		(void *)&cmd_flex_filter_bytes,
8279 		(void *)&cmd_flex_filter_bytes_value,
8280 		(void *)&cmd_flex_filter_mask,
8281 		(void *)&cmd_flex_filter_mask_value,
8282 		(void *)&cmd_flex_filter_priority,
8283 		(void *)&cmd_flex_filter_priority_value,
8284 		(void *)&cmd_flex_filter_queue,
8285 		(void *)&cmd_flex_filter_queue_id,
8286 		NULL,
8287 	},
8288 };
8289 
8290 /* *** Filters Control *** */
8291 
8292 /* *** deal with ethertype filter *** */
8293 struct cmd_ethertype_filter_result {
8294 	cmdline_fixed_string_t filter;
8295 	uint8_t port_id;
8296 	cmdline_fixed_string_t ops;
8297 	cmdline_fixed_string_t mac;
8298 	struct ether_addr mac_addr;
8299 	cmdline_fixed_string_t ethertype;
8300 	uint16_t ethertype_value;
8301 	cmdline_fixed_string_t drop;
8302 	cmdline_fixed_string_t queue;
8303 	uint16_t  queue_id;
8304 };
8305 
8306 cmdline_parse_token_string_t cmd_ethertype_filter_filter =
8307 	TOKEN_STRING_INITIALIZER(struct cmd_ethertype_filter_result,
8308 				 filter, "ethertype_filter");
8309 cmdline_parse_token_num_t cmd_ethertype_filter_port_id =
8310 	TOKEN_NUM_INITIALIZER(struct cmd_ethertype_filter_result,
8311 			      port_id, UINT8);
8312 cmdline_parse_token_string_t cmd_ethertype_filter_ops =
8313 	TOKEN_STRING_INITIALIZER(struct cmd_ethertype_filter_result,
8314 				 ops, "add#del");
8315 cmdline_parse_token_string_t cmd_ethertype_filter_mac =
8316 	TOKEN_STRING_INITIALIZER(struct cmd_ethertype_filter_result,
8317 				 mac, "mac_addr#mac_ignr");
8318 cmdline_parse_token_etheraddr_t cmd_ethertype_filter_mac_addr =
8319 	TOKEN_ETHERADDR_INITIALIZER(struct cmd_ethertype_filter_result,
8320 				     mac_addr);
8321 cmdline_parse_token_string_t cmd_ethertype_filter_ethertype =
8322 	TOKEN_STRING_INITIALIZER(struct cmd_ethertype_filter_result,
8323 				 ethertype, "ethertype");
8324 cmdline_parse_token_num_t cmd_ethertype_filter_ethertype_value =
8325 	TOKEN_NUM_INITIALIZER(struct cmd_ethertype_filter_result,
8326 			      ethertype_value, UINT16);
8327 cmdline_parse_token_string_t cmd_ethertype_filter_drop =
8328 	TOKEN_STRING_INITIALIZER(struct cmd_ethertype_filter_result,
8329 				 drop, "drop#fwd");
8330 cmdline_parse_token_string_t cmd_ethertype_filter_queue =
8331 	TOKEN_STRING_INITIALIZER(struct cmd_ethertype_filter_result,
8332 				 queue, "queue");
8333 cmdline_parse_token_num_t cmd_ethertype_filter_queue_id =
8334 	TOKEN_NUM_INITIALIZER(struct cmd_ethertype_filter_result,
8335 			      queue_id, UINT16);
8336 
8337 static void
8338 cmd_ethertype_filter_parsed(void *parsed_result,
8339 			  __attribute__((unused)) struct cmdline *cl,
8340 			  __attribute__((unused)) void *data)
8341 {
8342 	struct cmd_ethertype_filter_result *res = parsed_result;
8343 	struct rte_eth_ethertype_filter filter;
8344 	int ret = 0;
8345 
8346 	ret = rte_eth_dev_filter_supported(res->port_id,
8347 			RTE_ETH_FILTER_ETHERTYPE);
8348 	if (ret < 0) {
8349 		printf("ethertype filter is not supported on port %u.\n",
8350 			res->port_id);
8351 		return;
8352 	}
8353 
8354 	memset(&filter, 0, sizeof(filter));
8355 	if (!strcmp(res->mac, "mac_addr")) {
8356 		filter.flags |= RTE_ETHTYPE_FLAGS_MAC;
8357 		(void)rte_memcpy(&filter.mac_addr, &res->mac_addr,
8358 			sizeof(struct ether_addr));
8359 	}
8360 	if (!strcmp(res->drop, "drop"))
8361 		filter.flags |= RTE_ETHTYPE_FLAGS_DROP;
8362 	filter.ether_type = res->ethertype_value;
8363 	filter.queue = res->queue_id;
8364 
8365 	if (!strcmp(res->ops, "add"))
8366 		ret = rte_eth_dev_filter_ctrl(res->port_id,
8367 				RTE_ETH_FILTER_ETHERTYPE,
8368 				RTE_ETH_FILTER_ADD,
8369 				&filter);
8370 	else
8371 		ret = rte_eth_dev_filter_ctrl(res->port_id,
8372 				RTE_ETH_FILTER_ETHERTYPE,
8373 				RTE_ETH_FILTER_DELETE,
8374 				&filter);
8375 	if (ret < 0)
8376 		printf("ethertype filter programming error: (%s)\n",
8377 			strerror(-ret));
8378 }
8379 
8380 cmdline_parse_inst_t cmd_ethertype_filter = {
8381 	.f = cmd_ethertype_filter_parsed,
8382 	.data = NULL,
8383 	.help_str = "ethertype_filter <port_id> add|del mac_addr|mac_ignr "
8384 		"<mac_addr> ethertype <value> drop|fw queue <queue_id>: "
8385 		"Add or delete an ethertype filter entry",
8386 	.tokens = {
8387 		(void *)&cmd_ethertype_filter_filter,
8388 		(void *)&cmd_ethertype_filter_port_id,
8389 		(void *)&cmd_ethertype_filter_ops,
8390 		(void *)&cmd_ethertype_filter_mac,
8391 		(void *)&cmd_ethertype_filter_mac_addr,
8392 		(void *)&cmd_ethertype_filter_ethertype,
8393 		(void *)&cmd_ethertype_filter_ethertype_value,
8394 		(void *)&cmd_ethertype_filter_drop,
8395 		(void *)&cmd_ethertype_filter_queue,
8396 		(void *)&cmd_ethertype_filter_queue_id,
8397 		NULL,
8398 	},
8399 };
8400 
8401 /* *** deal with flow director filter *** */
8402 struct cmd_flow_director_result {
8403 	cmdline_fixed_string_t flow_director_filter;
8404 	uint8_t port_id;
8405 	cmdline_fixed_string_t mode;
8406 	cmdline_fixed_string_t mode_value;
8407 	cmdline_fixed_string_t ops;
8408 	cmdline_fixed_string_t flow;
8409 	cmdline_fixed_string_t flow_type;
8410 	cmdline_fixed_string_t ether;
8411 	uint16_t ether_type;
8412 	cmdline_fixed_string_t src;
8413 	cmdline_ipaddr_t ip_src;
8414 	uint16_t port_src;
8415 	cmdline_fixed_string_t dst;
8416 	cmdline_ipaddr_t ip_dst;
8417 	uint16_t port_dst;
8418 	cmdline_fixed_string_t verify_tag;
8419 	uint32_t verify_tag_value;
8420 	cmdline_ipaddr_t tos;
8421 	uint8_t tos_value;
8422 	cmdline_ipaddr_t proto;
8423 	uint8_t proto_value;
8424 	cmdline_ipaddr_t ttl;
8425 	uint8_t ttl_value;
8426 	cmdline_fixed_string_t vlan;
8427 	uint16_t vlan_value;
8428 	cmdline_fixed_string_t flexbytes;
8429 	cmdline_fixed_string_t flexbytes_value;
8430 	cmdline_fixed_string_t pf_vf;
8431 	cmdline_fixed_string_t drop;
8432 	cmdline_fixed_string_t queue;
8433 	uint16_t  queue_id;
8434 	cmdline_fixed_string_t fd_id;
8435 	uint32_t  fd_id_value;
8436 	cmdline_fixed_string_t mac;
8437 	struct ether_addr mac_addr;
8438 	cmdline_fixed_string_t tunnel;
8439 	cmdline_fixed_string_t tunnel_type;
8440 	cmdline_fixed_string_t tunnel_id;
8441 	uint32_t tunnel_id_value;
8442 };
8443 
8444 static inline int
8445 parse_flexbytes(const char *q_arg, uint8_t *flexbytes, uint16_t max_num)
8446 {
8447 	char s[256];
8448 	const char *p, *p0 = q_arg;
8449 	char *end;
8450 	unsigned long int_fld;
8451 	char *str_fld[max_num];
8452 	int i;
8453 	unsigned size;
8454 	int ret = -1;
8455 
8456 	p = strchr(p0, '(');
8457 	if (p == NULL)
8458 		return -1;
8459 	++p;
8460 	p0 = strchr(p, ')');
8461 	if (p0 == NULL)
8462 		return -1;
8463 
8464 	size = p0 - p;
8465 	if (size >= sizeof(s))
8466 		return -1;
8467 
8468 	snprintf(s, sizeof(s), "%.*s", size, p);
8469 	ret = rte_strsplit(s, sizeof(s), str_fld, max_num, ',');
8470 	if (ret < 0 || ret > max_num)
8471 		return -1;
8472 	for (i = 0; i < ret; i++) {
8473 		errno = 0;
8474 		int_fld = strtoul(str_fld[i], &end, 0);
8475 		if (errno != 0 || *end != '\0' || int_fld > UINT8_MAX)
8476 			return -1;
8477 		flexbytes[i] = (uint8_t)int_fld;
8478 	}
8479 	return ret;
8480 }
8481 
8482 static uint16_t
8483 str2flowtype(char *string)
8484 {
8485 	uint8_t i = 0;
8486 	static const struct {
8487 		char str[32];
8488 		uint16_t type;
8489 	} flowtype_str[] = {
8490 		{"raw", RTE_ETH_FLOW_RAW},
8491 		{"ipv4", RTE_ETH_FLOW_IPV4},
8492 		{"ipv4-frag", RTE_ETH_FLOW_FRAG_IPV4},
8493 		{"ipv4-tcp", RTE_ETH_FLOW_NONFRAG_IPV4_TCP},
8494 		{"ipv4-udp", RTE_ETH_FLOW_NONFRAG_IPV4_UDP},
8495 		{"ipv4-sctp", RTE_ETH_FLOW_NONFRAG_IPV4_SCTP},
8496 		{"ipv4-other", RTE_ETH_FLOW_NONFRAG_IPV4_OTHER},
8497 		{"ipv6", RTE_ETH_FLOW_IPV6},
8498 		{"ipv6-frag", RTE_ETH_FLOW_FRAG_IPV6},
8499 		{"ipv6-tcp", RTE_ETH_FLOW_NONFRAG_IPV6_TCP},
8500 		{"ipv6-udp", RTE_ETH_FLOW_NONFRAG_IPV6_UDP},
8501 		{"ipv6-sctp", RTE_ETH_FLOW_NONFRAG_IPV6_SCTP},
8502 		{"ipv6-other", RTE_ETH_FLOW_NONFRAG_IPV6_OTHER},
8503 		{"l2_payload", RTE_ETH_FLOW_L2_PAYLOAD},
8504 	};
8505 
8506 	for (i = 0; i < RTE_DIM(flowtype_str); i++) {
8507 		if (!strcmp(flowtype_str[i].str, string))
8508 			return flowtype_str[i].type;
8509 	}
8510 	return RTE_ETH_FLOW_UNKNOWN;
8511 }
8512 
8513 static enum rte_eth_fdir_tunnel_type
8514 str2fdir_tunneltype(char *string)
8515 {
8516 	uint8_t i = 0;
8517 
8518 	static const struct {
8519 		char str[32];
8520 		enum rte_eth_fdir_tunnel_type type;
8521 	} tunneltype_str[] = {
8522 		{"NVGRE", RTE_FDIR_TUNNEL_TYPE_NVGRE},
8523 		{"VxLAN", RTE_FDIR_TUNNEL_TYPE_VXLAN},
8524 	};
8525 
8526 	for (i = 0; i < RTE_DIM(tunneltype_str); i++) {
8527 		if (!strcmp(tunneltype_str[i].str, string))
8528 			return tunneltype_str[i].type;
8529 	}
8530 	return RTE_FDIR_TUNNEL_TYPE_UNKNOWN;
8531 }
8532 
8533 #define IPV4_ADDR_TO_UINT(ip_addr, ip) \
8534 do { \
8535 	if ((ip_addr).family == AF_INET) \
8536 		(ip) = (ip_addr).addr.ipv4.s_addr; \
8537 	else { \
8538 		printf("invalid parameter.\n"); \
8539 		return; \
8540 	} \
8541 } while (0)
8542 
8543 #define IPV6_ADDR_TO_ARRAY(ip_addr, ip) \
8544 do { \
8545 	if ((ip_addr).family == AF_INET6) \
8546 		(void)rte_memcpy(&(ip), \
8547 				 &((ip_addr).addr.ipv6), \
8548 				 sizeof(struct in6_addr)); \
8549 	else { \
8550 		printf("invalid parameter.\n"); \
8551 		return; \
8552 	} \
8553 } while (0)
8554 
8555 static void
8556 cmd_flow_director_filter_parsed(void *parsed_result,
8557 			  __attribute__((unused)) struct cmdline *cl,
8558 			  __attribute__((unused)) void *data)
8559 {
8560 	struct cmd_flow_director_result *res = parsed_result;
8561 	struct rte_eth_fdir_filter entry;
8562 	uint8_t flexbytes[RTE_ETH_FDIR_MAX_FLEXLEN];
8563 	char *end;
8564 	unsigned long vf_id;
8565 	int ret = 0;
8566 
8567 	ret = rte_eth_dev_filter_supported(res->port_id, RTE_ETH_FILTER_FDIR);
8568 	if (ret < 0) {
8569 		printf("flow director is not supported on port %u.\n",
8570 			res->port_id);
8571 		return;
8572 	}
8573 	memset(flexbytes, 0, sizeof(flexbytes));
8574 	memset(&entry, 0, sizeof(struct rte_eth_fdir_filter));
8575 
8576 	if (fdir_conf.mode ==  RTE_FDIR_MODE_PERFECT_MAC_VLAN) {
8577 		if (strcmp(res->mode_value, "MAC-VLAN")) {
8578 			printf("Please set mode to MAC-VLAN.\n");
8579 			return;
8580 		}
8581 	} else if (fdir_conf.mode ==  RTE_FDIR_MODE_PERFECT_TUNNEL) {
8582 		if (strcmp(res->mode_value, "Tunnel")) {
8583 			printf("Please set mode to Tunnel.\n");
8584 			return;
8585 		}
8586 	} else {
8587 		if (strcmp(res->mode_value, "IP")) {
8588 			printf("Please set mode to IP.\n");
8589 			return;
8590 		}
8591 		entry.input.flow_type = str2flowtype(res->flow_type);
8592 	}
8593 
8594 	ret = parse_flexbytes(res->flexbytes_value,
8595 					flexbytes,
8596 					RTE_ETH_FDIR_MAX_FLEXLEN);
8597 	if (ret < 0) {
8598 		printf("error: Cannot parse flexbytes input.\n");
8599 		return;
8600 	}
8601 
8602 	switch (entry.input.flow_type) {
8603 	case RTE_ETH_FLOW_FRAG_IPV4:
8604 	case RTE_ETH_FLOW_NONFRAG_IPV4_OTHER:
8605 		entry.input.flow.ip4_flow.proto = res->proto_value;
8606 	case RTE_ETH_FLOW_NONFRAG_IPV4_UDP:
8607 	case RTE_ETH_FLOW_NONFRAG_IPV4_TCP:
8608 		IPV4_ADDR_TO_UINT(res->ip_dst,
8609 			entry.input.flow.ip4_flow.dst_ip);
8610 		IPV4_ADDR_TO_UINT(res->ip_src,
8611 			entry.input.flow.ip4_flow.src_ip);
8612 		entry.input.flow.ip4_flow.tos = res->tos_value;
8613 		entry.input.flow.ip4_flow.ttl = res->ttl_value;
8614 		/* need convert to big endian. */
8615 		entry.input.flow.udp4_flow.dst_port =
8616 				rte_cpu_to_be_16(res->port_dst);
8617 		entry.input.flow.udp4_flow.src_port =
8618 				rte_cpu_to_be_16(res->port_src);
8619 		break;
8620 	case RTE_ETH_FLOW_NONFRAG_IPV4_SCTP:
8621 		IPV4_ADDR_TO_UINT(res->ip_dst,
8622 			entry.input.flow.sctp4_flow.ip.dst_ip);
8623 		IPV4_ADDR_TO_UINT(res->ip_src,
8624 			entry.input.flow.sctp4_flow.ip.src_ip);
8625 		entry.input.flow.ip4_flow.tos = res->tos_value;
8626 		entry.input.flow.ip4_flow.ttl = res->ttl_value;
8627 		/* need convert to big endian. */
8628 		entry.input.flow.sctp4_flow.dst_port =
8629 				rte_cpu_to_be_16(res->port_dst);
8630 		entry.input.flow.sctp4_flow.src_port =
8631 				rte_cpu_to_be_16(res->port_src);
8632 		entry.input.flow.sctp4_flow.verify_tag =
8633 				rte_cpu_to_be_32(res->verify_tag_value);
8634 		break;
8635 	case RTE_ETH_FLOW_FRAG_IPV6:
8636 	case RTE_ETH_FLOW_NONFRAG_IPV6_OTHER:
8637 		entry.input.flow.ipv6_flow.proto = res->proto_value;
8638 	case RTE_ETH_FLOW_NONFRAG_IPV6_UDP:
8639 	case RTE_ETH_FLOW_NONFRAG_IPV6_TCP:
8640 		IPV6_ADDR_TO_ARRAY(res->ip_dst,
8641 			entry.input.flow.ipv6_flow.dst_ip);
8642 		IPV6_ADDR_TO_ARRAY(res->ip_src,
8643 			entry.input.flow.ipv6_flow.src_ip);
8644 		entry.input.flow.ipv6_flow.tc = res->tos_value;
8645 		entry.input.flow.ipv6_flow.hop_limits = res->ttl_value;
8646 		/* need convert to big endian. */
8647 		entry.input.flow.udp6_flow.dst_port =
8648 				rte_cpu_to_be_16(res->port_dst);
8649 		entry.input.flow.udp6_flow.src_port =
8650 				rte_cpu_to_be_16(res->port_src);
8651 		break;
8652 	case RTE_ETH_FLOW_NONFRAG_IPV6_SCTP:
8653 		IPV6_ADDR_TO_ARRAY(res->ip_dst,
8654 			entry.input.flow.sctp6_flow.ip.dst_ip);
8655 		IPV6_ADDR_TO_ARRAY(res->ip_src,
8656 			entry.input.flow.sctp6_flow.ip.src_ip);
8657 		entry.input.flow.ipv6_flow.tc = res->tos_value;
8658 		entry.input.flow.ipv6_flow.hop_limits = res->ttl_value;
8659 		/* need convert to big endian. */
8660 		entry.input.flow.sctp6_flow.dst_port =
8661 				rte_cpu_to_be_16(res->port_dst);
8662 		entry.input.flow.sctp6_flow.src_port =
8663 				rte_cpu_to_be_16(res->port_src);
8664 		entry.input.flow.sctp6_flow.verify_tag =
8665 				rte_cpu_to_be_32(res->verify_tag_value);
8666 		break;
8667 	case RTE_ETH_FLOW_L2_PAYLOAD:
8668 		entry.input.flow.l2_flow.ether_type =
8669 			rte_cpu_to_be_16(res->ether_type);
8670 		break;
8671 	default:
8672 		break;
8673 	}
8674 
8675 	if (fdir_conf.mode ==  RTE_FDIR_MODE_PERFECT_MAC_VLAN)
8676 		(void)rte_memcpy(&entry.input.flow.mac_vlan_flow.mac_addr,
8677 				 &res->mac_addr,
8678 				 sizeof(struct ether_addr));
8679 
8680 	if (fdir_conf.mode ==  RTE_FDIR_MODE_PERFECT_TUNNEL) {
8681 		(void)rte_memcpy(&entry.input.flow.tunnel_flow.mac_addr,
8682 				 &res->mac_addr,
8683 				 sizeof(struct ether_addr));
8684 		entry.input.flow.tunnel_flow.tunnel_type =
8685 			str2fdir_tunneltype(res->tunnel_type);
8686 		entry.input.flow.tunnel_flow.tunnel_id =
8687 			rte_cpu_to_be_32(res->tunnel_id_value);
8688 	}
8689 
8690 	(void)rte_memcpy(entry.input.flow_ext.flexbytes,
8691 		   flexbytes,
8692 		   RTE_ETH_FDIR_MAX_FLEXLEN);
8693 
8694 	entry.input.flow_ext.vlan_tci = rte_cpu_to_be_16(res->vlan_value);
8695 
8696 	entry.action.flex_off = 0;  /*use 0 by default */
8697 	if (!strcmp(res->drop, "drop"))
8698 		entry.action.behavior = RTE_ETH_FDIR_REJECT;
8699 	else
8700 		entry.action.behavior = RTE_ETH_FDIR_ACCEPT;
8701 
8702 	if (fdir_conf.mode !=  RTE_FDIR_MODE_PERFECT_MAC_VLAN &&
8703 	    fdir_conf.mode !=  RTE_FDIR_MODE_PERFECT_TUNNEL) {
8704 		if (!strcmp(res->pf_vf, "pf"))
8705 			entry.input.flow_ext.is_vf = 0;
8706 		else if (!strncmp(res->pf_vf, "vf", 2)) {
8707 			struct rte_eth_dev_info dev_info;
8708 
8709 			memset(&dev_info, 0, sizeof(dev_info));
8710 			rte_eth_dev_info_get(res->port_id, &dev_info);
8711 			errno = 0;
8712 			vf_id = strtoul(res->pf_vf + 2, &end, 10);
8713 			if (errno != 0 || *end != '\0' ||
8714 			    vf_id >= dev_info.max_vfs) {
8715 				printf("invalid parameter %s.\n", res->pf_vf);
8716 				return;
8717 			}
8718 			entry.input.flow_ext.is_vf = 1;
8719 			entry.input.flow_ext.dst_id = (uint16_t)vf_id;
8720 		} else {
8721 			printf("invalid parameter %s.\n", res->pf_vf);
8722 			return;
8723 		}
8724 	}
8725 
8726 	/* set to report FD ID by default */
8727 	entry.action.report_status = RTE_ETH_FDIR_REPORT_ID;
8728 	entry.action.rx_queue = res->queue_id;
8729 	entry.soft_id = res->fd_id_value;
8730 	if (!strcmp(res->ops, "add"))
8731 		ret = rte_eth_dev_filter_ctrl(res->port_id, RTE_ETH_FILTER_FDIR,
8732 					     RTE_ETH_FILTER_ADD, &entry);
8733 	else if (!strcmp(res->ops, "del"))
8734 		ret = rte_eth_dev_filter_ctrl(res->port_id, RTE_ETH_FILTER_FDIR,
8735 					     RTE_ETH_FILTER_DELETE, &entry);
8736 	else
8737 		ret = rte_eth_dev_filter_ctrl(res->port_id, RTE_ETH_FILTER_FDIR,
8738 					     RTE_ETH_FILTER_UPDATE, &entry);
8739 	if (ret < 0)
8740 		printf("flow director programming error: (%s)\n",
8741 			strerror(-ret));
8742 }
8743 
8744 cmdline_parse_token_string_t cmd_flow_director_filter =
8745 	TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
8746 				 flow_director_filter, "flow_director_filter");
8747 cmdline_parse_token_num_t cmd_flow_director_port_id =
8748 	TOKEN_NUM_INITIALIZER(struct cmd_flow_director_result,
8749 			      port_id, UINT8);
8750 cmdline_parse_token_string_t cmd_flow_director_ops =
8751 	TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
8752 				 ops, "add#del#update");
8753 cmdline_parse_token_string_t cmd_flow_director_flow =
8754 	TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
8755 				 flow, "flow");
8756 cmdline_parse_token_string_t cmd_flow_director_flow_type =
8757 	TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
8758 		flow_type, "ipv4-other#ipv4-frag#ipv4-tcp#ipv4-udp#ipv4-sctp#"
8759 		"ipv6-other#ipv6-frag#ipv6-tcp#ipv6-udp#ipv6-sctp#l2_payload");
8760 cmdline_parse_token_string_t cmd_flow_director_ether =
8761 	TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
8762 				 ether, "ether");
8763 cmdline_parse_token_num_t cmd_flow_director_ether_type =
8764 	TOKEN_NUM_INITIALIZER(struct cmd_flow_director_result,
8765 			      ether_type, UINT16);
8766 cmdline_parse_token_string_t cmd_flow_director_src =
8767 	TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
8768 				 src, "src");
8769 cmdline_parse_token_ipaddr_t cmd_flow_director_ip_src =
8770 	TOKEN_IPADDR_INITIALIZER(struct cmd_flow_director_result,
8771 				 ip_src);
8772 cmdline_parse_token_num_t cmd_flow_director_port_src =
8773 	TOKEN_NUM_INITIALIZER(struct cmd_flow_director_result,
8774 			      port_src, UINT16);
8775 cmdline_parse_token_string_t cmd_flow_director_dst =
8776 	TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
8777 				 dst, "dst");
8778 cmdline_parse_token_ipaddr_t cmd_flow_director_ip_dst =
8779 	TOKEN_IPADDR_INITIALIZER(struct cmd_flow_director_result,
8780 				 ip_dst);
8781 cmdline_parse_token_num_t cmd_flow_director_port_dst =
8782 	TOKEN_NUM_INITIALIZER(struct cmd_flow_director_result,
8783 			      port_dst, UINT16);
8784 cmdline_parse_token_string_t cmd_flow_director_verify_tag =
8785 	TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
8786 				  verify_tag, "verify_tag");
8787 cmdline_parse_token_num_t cmd_flow_director_verify_tag_value =
8788 	TOKEN_NUM_INITIALIZER(struct cmd_flow_director_result,
8789 			      verify_tag_value, UINT32);
8790 cmdline_parse_token_string_t cmd_flow_director_tos =
8791 	TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
8792 				 tos, "tos");
8793 cmdline_parse_token_num_t cmd_flow_director_tos_value =
8794 	TOKEN_NUM_INITIALIZER(struct cmd_flow_director_result,
8795 			      tos_value, UINT8);
8796 cmdline_parse_token_string_t cmd_flow_director_proto =
8797 	TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
8798 				 proto, "proto");
8799 cmdline_parse_token_num_t cmd_flow_director_proto_value =
8800 	TOKEN_NUM_INITIALIZER(struct cmd_flow_director_result,
8801 			      proto_value, UINT8);
8802 cmdline_parse_token_string_t cmd_flow_director_ttl =
8803 	TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
8804 				 ttl, "ttl");
8805 cmdline_parse_token_num_t cmd_flow_director_ttl_value =
8806 	TOKEN_NUM_INITIALIZER(struct cmd_flow_director_result,
8807 			      ttl_value, UINT8);
8808 cmdline_parse_token_string_t cmd_flow_director_vlan =
8809 	TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
8810 				 vlan, "vlan");
8811 cmdline_parse_token_num_t cmd_flow_director_vlan_value =
8812 	TOKEN_NUM_INITIALIZER(struct cmd_flow_director_result,
8813 			      vlan_value, UINT16);
8814 cmdline_parse_token_string_t cmd_flow_director_flexbytes =
8815 	TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
8816 				 flexbytes, "flexbytes");
8817 cmdline_parse_token_string_t cmd_flow_director_flexbytes_value =
8818 	TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
8819 			      flexbytes_value, NULL);
8820 cmdline_parse_token_string_t cmd_flow_director_drop =
8821 	TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
8822 				 drop, "drop#fwd");
8823 cmdline_parse_token_string_t cmd_flow_director_pf_vf =
8824 	TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
8825 			      pf_vf, NULL);
8826 cmdline_parse_token_string_t cmd_flow_director_queue =
8827 	TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
8828 				 queue, "queue");
8829 cmdline_parse_token_num_t cmd_flow_director_queue_id =
8830 	TOKEN_NUM_INITIALIZER(struct cmd_flow_director_result,
8831 			      queue_id, UINT16);
8832 cmdline_parse_token_string_t cmd_flow_director_fd_id =
8833 	TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
8834 				 fd_id, "fd_id");
8835 cmdline_parse_token_num_t cmd_flow_director_fd_id_value =
8836 	TOKEN_NUM_INITIALIZER(struct cmd_flow_director_result,
8837 			      fd_id_value, UINT32);
8838 
8839 cmdline_parse_token_string_t cmd_flow_director_mode =
8840 	TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
8841 				 mode, "mode");
8842 cmdline_parse_token_string_t cmd_flow_director_mode_ip =
8843 	TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
8844 				 mode_value, "IP");
8845 cmdline_parse_token_string_t cmd_flow_director_mode_mac_vlan =
8846 	TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
8847 				 mode_value, "MAC-VLAN");
8848 cmdline_parse_token_string_t cmd_flow_director_mode_tunnel =
8849 	TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
8850 				 mode_value, "Tunnel");
8851 cmdline_parse_token_string_t cmd_flow_director_mac =
8852 	TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
8853 				 mac, "mac");
8854 cmdline_parse_token_etheraddr_t cmd_flow_director_mac_addr =
8855 	TOKEN_ETHERADDR_INITIALIZER(struct cmd_flow_director_result,
8856 				    mac_addr);
8857 cmdline_parse_token_string_t cmd_flow_director_tunnel =
8858 	TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
8859 				 tunnel, "tunnel");
8860 cmdline_parse_token_string_t cmd_flow_director_tunnel_type =
8861 	TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
8862 				 tunnel_type, "NVGRE#VxLAN");
8863 cmdline_parse_token_string_t cmd_flow_director_tunnel_id =
8864 	TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
8865 				 tunnel_id, "tunnel-id");
8866 cmdline_parse_token_num_t cmd_flow_director_tunnel_id_value =
8867 	TOKEN_NUM_INITIALIZER(struct cmd_flow_director_result,
8868 			      tunnel_id_value, UINT32);
8869 
8870 cmdline_parse_inst_t cmd_add_del_ip_flow_director = {
8871 	.f = cmd_flow_director_filter_parsed,
8872 	.data = NULL,
8873 	.help_str = "flow_director_filter <port_id> mode IP add|del|update flow"
8874 		" ipv4-other|ipv4-frag|ipv4-tcp|ipv4-udp|ipv4-sctp|"
8875 		"ipv6-other|ipv6-frag|ipv6-tcp|ipv6-udp|ipv6-sctp|"
8876 		"l2_payload src <src_ip> dst <dst_ip> tos <tos_value> "
8877 		"proto <proto_value> ttl <ttl_value> vlan <vlan_value> "
8878 		"flexbytes <flexbyte_vaues> drop|fw <pf_vf> queue <queue_id> "
8879 		"fd_id <fd_id_value>: "
8880 		"Add or delete an ip flow director entry on NIC",
8881 	.tokens = {
8882 		(void *)&cmd_flow_director_filter,
8883 		(void *)&cmd_flow_director_port_id,
8884 		(void *)&cmd_flow_director_mode,
8885 		(void *)&cmd_flow_director_mode_ip,
8886 		(void *)&cmd_flow_director_ops,
8887 		(void *)&cmd_flow_director_flow,
8888 		(void *)&cmd_flow_director_flow_type,
8889 		(void *)&cmd_flow_director_src,
8890 		(void *)&cmd_flow_director_ip_src,
8891 		(void *)&cmd_flow_director_dst,
8892 		(void *)&cmd_flow_director_ip_dst,
8893 		(void *)&cmd_flow_director_tos,
8894 		(void *)&cmd_flow_director_tos_value,
8895 		(void *)&cmd_flow_director_proto,
8896 		(void *)&cmd_flow_director_proto_value,
8897 		(void *)&cmd_flow_director_ttl,
8898 		(void *)&cmd_flow_director_ttl_value,
8899 		(void *)&cmd_flow_director_vlan,
8900 		(void *)&cmd_flow_director_vlan_value,
8901 		(void *)&cmd_flow_director_flexbytes,
8902 		(void *)&cmd_flow_director_flexbytes_value,
8903 		(void *)&cmd_flow_director_drop,
8904 		(void *)&cmd_flow_director_pf_vf,
8905 		(void *)&cmd_flow_director_queue,
8906 		(void *)&cmd_flow_director_queue_id,
8907 		(void *)&cmd_flow_director_fd_id,
8908 		(void *)&cmd_flow_director_fd_id_value,
8909 		NULL,
8910 	},
8911 };
8912 
8913 cmdline_parse_inst_t cmd_add_del_udp_flow_director = {
8914 	.f = cmd_flow_director_filter_parsed,
8915 	.data = NULL,
8916 	.help_str = "flow_director_filter ... : Add or delete an udp/tcp flow "
8917 		"director entry on NIC",
8918 	.tokens = {
8919 		(void *)&cmd_flow_director_filter,
8920 		(void *)&cmd_flow_director_port_id,
8921 		(void *)&cmd_flow_director_mode,
8922 		(void *)&cmd_flow_director_mode_ip,
8923 		(void *)&cmd_flow_director_ops,
8924 		(void *)&cmd_flow_director_flow,
8925 		(void *)&cmd_flow_director_flow_type,
8926 		(void *)&cmd_flow_director_src,
8927 		(void *)&cmd_flow_director_ip_src,
8928 		(void *)&cmd_flow_director_port_src,
8929 		(void *)&cmd_flow_director_dst,
8930 		(void *)&cmd_flow_director_ip_dst,
8931 		(void *)&cmd_flow_director_port_dst,
8932 		(void *)&cmd_flow_director_tos,
8933 		(void *)&cmd_flow_director_tos_value,
8934 		(void *)&cmd_flow_director_ttl,
8935 		(void *)&cmd_flow_director_ttl_value,
8936 		(void *)&cmd_flow_director_vlan,
8937 		(void *)&cmd_flow_director_vlan_value,
8938 		(void *)&cmd_flow_director_flexbytes,
8939 		(void *)&cmd_flow_director_flexbytes_value,
8940 		(void *)&cmd_flow_director_drop,
8941 		(void *)&cmd_flow_director_pf_vf,
8942 		(void *)&cmd_flow_director_queue,
8943 		(void *)&cmd_flow_director_queue_id,
8944 		(void *)&cmd_flow_director_fd_id,
8945 		(void *)&cmd_flow_director_fd_id_value,
8946 		NULL,
8947 	},
8948 };
8949 
8950 cmdline_parse_inst_t cmd_add_del_sctp_flow_director = {
8951 	.f = cmd_flow_director_filter_parsed,
8952 	.data = NULL,
8953 	.help_str = "flow_director_filter ... : Add or delete a sctp flow "
8954 		"director entry on NIC",
8955 	.tokens = {
8956 		(void *)&cmd_flow_director_filter,
8957 		(void *)&cmd_flow_director_port_id,
8958 		(void *)&cmd_flow_director_mode,
8959 		(void *)&cmd_flow_director_mode_ip,
8960 		(void *)&cmd_flow_director_ops,
8961 		(void *)&cmd_flow_director_flow,
8962 		(void *)&cmd_flow_director_flow_type,
8963 		(void *)&cmd_flow_director_src,
8964 		(void *)&cmd_flow_director_ip_src,
8965 		(void *)&cmd_flow_director_port_dst,
8966 		(void *)&cmd_flow_director_dst,
8967 		(void *)&cmd_flow_director_ip_dst,
8968 		(void *)&cmd_flow_director_port_dst,
8969 		(void *)&cmd_flow_director_verify_tag,
8970 		(void *)&cmd_flow_director_verify_tag_value,
8971 		(void *)&cmd_flow_director_tos,
8972 		(void *)&cmd_flow_director_tos_value,
8973 		(void *)&cmd_flow_director_ttl,
8974 		(void *)&cmd_flow_director_ttl_value,
8975 		(void *)&cmd_flow_director_vlan,
8976 		(void *)&cmd_flow_director_vlan_value,
8977 		(void *)&cmd_flow_director_flexbytes,
8978 		(void *)&cmd_flow_director_flexbytes_value,
8979 		(void *)&cmd_flow_director_drop,
8980 		(void *)&cmd_flow_director_pf_vf,
8981 		(void *)&cmd_flow_director_queue,
8982 		(void *)&cmd_flow_director_queue_id,
8983 		(void *)&cmd_flow_director_fd_id,
8984 		(void *)&cmd_flow_director_fd_id_value,
8985 		NULL,
8986 	},
8987 };
8988 
8989 cmdline_parse_inst_t cmd_add_del_l2_flow_director = {
8990 	.f = cmd_flow_director_filter_parsed,
8991 	.data = NULL,
8992 	.help_str = "flow_director_filter ... : Add or delete a L2 flow "
8993 		"director entry on NIC",
8994 	.tokens = {
8995 		(void *)&cmd_flow_director_filter,
8996 		(void *)&cmd_flow_director_port_id,
8997 		(void *)&cmd_flow_director_mode,
8998 		(void *)&cmd_flow_director_mode_ip,
8999 		(void *)&cmd_flow_director_ops,
9000 		(void *)&cmd_flow_director_flow,
9001 		(void *)&cmd_flow_director_flow_type,
9002 		(void *)&cmd_flow_director_ether,
9003 		(void *)&cmd_flow_director_ether_type,
9004 		(void *)&cmd_flow_director_flexbytes,
9005 		(void *)&cmd_flow_director_flexbytes_value,
9006 		(void *)&cmd_flow_director_drop,
9007 		(void *)&cmd_flow_director_pf_vf,
9008 		(void *)&cmd_flow_director_queue,
9009 		(void *)&cmd_flow_director_queue_id,
9010 		(void *)&cmd_flow_director_fd_id,
9011 		(void *)&cmd_flow_director_fd_id_value,
9012 		NULL,
9013 	},
9014 };
9015 
9016 cmdline_parse_inst_t cmd_add_del_mac_vlan_flow_director = {
9017 	.f = cmd_flow_director_filter_parsed,
9018 	.data = NULL,
9019 	.help_str = "flow_director_filter ... : Add or delete a MAC VLAN flow "
9020 		"director entry on NIC",
9021 	.tokens = {
9022 		(void *)&cmd_flow_director_filter,
9023 		(void *)&cmd_flow_director_port_id,
9024 		(void *)&cmd_flow_director_mode,
9025 		(void *)&cmd_flow_director_mode_mac_vlan,
9026 		(void *)&cmd_flow_director_ops,
9027 		(void *)&cmd_flow_director_mac,
9028 		(void *)&cmd_flow_director_mac_addr,
9029 		(void *)&cmd_flow_director_vlan,
9030 		(void *)&cmd_flow_director_vlan_value,
9031 		(void *)&cmd_flow_director_flexbytes,
9032 		(void *)&cmd_flow_director_flexbytes_value,
9033 		(void *)&cmd_flow_director_drop,
9034 		(void *)&cmd_flow_director_queue,
9035 		(void *)&cmd_flow_director_queue_id,
9036 		(void *)&cmd_flow_director_fd_id,
9037 		(void *)&cmd_flow_director_fd_id_value,
9038 		NULL,
9039 	},
9040 };
9041 
9042 cmdline_parse_inst_t cmd_add_del_tunnel_flow_director = {
9043 	.f = cmd_flow_director_filter_parsed,
9044 	.data = NULL,
9045 	.help_str = "flow_director_filter ... : Add or delete a tunnel flow "
9046 		"director entry on NIC",
9047 	.tokens = {
9048 		(void *)&cmd_flow_director_filter,
9049 		(void *)&cmd_flow_director_port_id,
9050 		(void *)&cmd_flow_director_mode,
9051 		(void *)&cmd_flow_director_mode_tunnel,
9052 		(void *)&cmd_flow_director_ops,
9053 		(void *)&cmd_flow_director_mac,
9054 		(void *)&cmd_flow_director_mac_addr,
9055 		(void *)&cmd_flow_director_vlan,
9056 		(void *)&cmd_flow_director_vlan_value,
9057 		(void *)&cmd_flow_director_tunnel,
9058 		(void *)&cmd_flow_director_tunnel_type,
9059 		(void *)&cmd_flow_director_tunnel_id,
9060 		(void *)&cmd_flow_director_tunnel_id_value,
9061 		(void *)&cmd_flow_director_flexbytes,
9062 		(void *)&cmd_flow_director_flexbytes_value,
9063 		(void *)&cmd_flow_director_drop,
9064 		(void *)&cmd_flow_director_queue,
9065 		(void *)&cmd_flow_director_queue_id,
9066 		(void *)&cmd_flow_director_fd_id,
9067 		(void *)&cmd_flow_director_fd_id_value,
9068 		NULL,
9069 	},
9070 };
9071 
9072 struct cmd_flush_flow_director_result {
9073 	cmdline_fixed_string_t flush_flow_director;
9074 	uint8_t port_id;
9075 };
9076 
9077 cmdline_parse_token_string_t cmd_flush_flow_director_flush =
9078 	TOKEN_STRING_INITIALIZER(struct cmd_flush_flow_director_result,
9079 				 flush_flow_director, "flush_flow_director");
9080 cmdline_parse_token_num_t cmd_flush_flow_director_port_id =
9081 	TOKEN_NUM_INITIALIZER(struct cmd_flush_flow_director_result,
9082 			      port_id, UINT8);
9083 
9084 static void
9085 cmd_flush_flow_director_parsed(void *parsed_result,
9086 			  __attribute__((unused)) struct cmdline *cl,
9087 			  __attribute__((unused)) void *data)
9088 {
9089 	struct cmd_flow_director_result *res = parsed_result;
9090 	int ret = 0;
9091 
9092 	ret = rte_eth_dev_filter_supported(res->port_id, RTE_ETH_FILTER_FDIR);
9093 	if (ret < 0) {
9094 		printf("flow director is not supported on port %u.\n",
9095 			res->port_id);
9096 		return;
9097 	}
9098 
9099 	ret = rte_eth_dev_filter_ctrl(res->port_id, RTE_ETH_FILTER_FDIR,
9100 			RTE_ETH_FILTER_FLUSH, NULL);
9101 	if (ret < 0)
9102 		printf("flow director table flushing error: (%s)\n",
9103 			strerror(-ret));
9104 }
9105 
9106 cmdline_parse_inst_t cmd_flush_flow_director = {
9107 	.f = cmd_flush_flow_director_parsed,
9108 	.data = NULL,
9109 	.help_str = "flush_flow_director <port_id>: "
9110 		"Flush all flow director entries of a device on NIC",
9111 	.tokens = {
9112 		(void *)&cmd_flush_flow_director_flush,
9113 		(void *)&cmd_flush_flow_director_port_id,
9114 		NULL,
9115 	},
9116 };
9117 
9118 /* *** deal with flow director mask *** */
9119 struct cmd_flow_director_mask_result {
9120 	cmdline_fixed_string_t flow_director_mask;
9121 	uint8_t port_id;
9122 	cmdline_fixed_string_t mode;
9123 	cmdline_fixed_string_t mode_value;
9124 	cmdline_fixed_string_t vlan;
9125 	uint16_t vlan_mask;
9126 	cmdline_fixed_string_t src_mask;
9127 	cmdline_ipaddr_t ipv4_src;
9128 	cmdline_ipaddr_t ipv6_src;
9129 	uint16_t port_src;
9130 	cmdline_fixed_string_t dst_mask;
9131 	cmdline_ipaddr_t ipv4_dst;
9132 	cmdline_ipaddr_t ipv6_dst;
9133 	uint16_t port_dst;
9134 	cmdline_fixed_string_t mac;
9135 	uint8_t mac_addr_byte_mask;
9136 	cmdline_fixed_string_t tunnel_id;
9137 	uint32_t tunnel_id_mask;
9138 	cmdline_fixed_string_t tunnel_type;
9139 	uint8_t tunnel_type_mask;
9140 };
9141 
9142 static void
9143 cmd_flow_director_mask_parsed(void *parsed_result,
9144 			  __attribute__((unused)) struct cmdline *cl,
9145 			  __attribute__((unused)) void *data)
9146 {
9147 	struct cmd_flow_director_mask_result *res = parsed_result;
9148 	struct rte_eth_fdir_masks *mask;
9149 	struct rte_port *port;
9150 
9151 	if (res->port_id > nb_ports) {
9152 		printf("Invalid port, range is [0, %d]\n", nb_ports - 1);
9153 		return;
9154 	}
9155 
9156 	port = &ports[res->port_id];
9157 	/** Check if the port is not started **/
9158 	if (port->port_status != RTE_PORT_STOPPED) {
9159 		printf("Please stop port %d first\n", res->port_id);
9160 		return;
9161 	}
9162 
9163 	mask = &port->dev_conf.fdir_conf.mask;
9164 
9165 	if (fdir_conf.mode ==  RTE_FDIR_MODE_PERFECT_MAC_VLAN) {
9166 		if (strcmp(res->mode_value, "MAC-VLAN")) {
9167 			printf("Please set mode to MAC-VLAN.\n");
9168 			return;
9169 		}
9170 
9171 		mask->vlan_tci_mask = rte_cpu_to_be_16(res->vlan_mask);
9172 	} else if (fdir_conf.mode ==  RTE_FDIR_MODE_PERFECT_TUNNEL) {
9173 		if (strcmp(res->mode_value, "Tunnel")) {
9174 			printf("Please set mode to Tunnel.\n");
9175 			return;
9176 		}
9177 
9178 		mask->vlan_tci_mask = rte_cpu_to_be_16(res->vlan_mask);
9179 		mask->mac_addr_byte_mask = res->mac_addr_byte_mask;
9180 		mask->tunnel_id_mask = rte_cpu_to_be_32(res->tunnel_id_mask);
9181 		mask->tunnel_type_mask = res->tunnel_type_mask;
9182 	} else {
9183 		if (strcmp(res->mode_value, "IP")) {
9184 			printf("Please set mode to IP.\n");
9185 			return;
9186 		}
9187 
9188 		mask->vlan_tci_mask = rte_cpu_to_be_16(res->vlan_mask);
9189 		IPV4_ADDR_TO_UINT(res->ipv4_src, mask->ipv4_mask.src_ip);
9190 		IPV4_ADDR_TO_UINT(res->ipv4_dst, mask->ipv4_mask.dst_ip);
9191 		IPV6_ADDR_TO_ARRAY(res->ipv6_src, mask->ipv6_mask.src_ip);
9192 		IPV6_ADDR_TO_ARRAY(res->ipv6_dst, mask->ipv6_mask.dst_ip);
9193 		mask->src_port_mask = rte_cpu_to_be_16(res->port_src);
9194 		mask->dst_port_mask = rte_cpu_to_be_16(res->port_dst);
9195 	}
9196 
9197 	cmd_reconfig_device_queue(res->port_id, 1, 1);
9198 }
9199 
9200 cmdline_parse_token_string_t cmd_flow_director_mask =
9201 	TOKEN_STRING_INITIALIZER(struct cmd_flow_director_mask_result,
9202 				 flow_director_mask, "flow_director_mask");
9203 cmdline_parse_token_num_t cmd_flow_director_mask_port_id =
9204 	TOKEN_NUM_INITIALIZER(struct cmd_flow_director_mask_result,
9205 			      port_id, UINT8);
9206 cmdline_parse_token_string_t cmd_flow_director_mask_vlan =
9207 	TOKEN_STRING_INITIALIZER(struct cmd_flow_director_mask_result,
9208 				 vlan, "vlan");
9209 cmdline_parse_token_num_t cmd_flow_director_mask_vlan_value =
9210 	TOKEN_NUM_INITIALIZER(struct cmd_flow_director_mask_result,
9211 			      vlan_mask, UINT16);
9212 cmdline_parse_token_string_t cmd_flow_director_mask_src =
9213 	TOKEN_STRING_INITIALIZER(struct cmd_flow_director_mask_result,
9214 				 src_mask, "src_mask");
9215 cmdline_parse_token_ipaddr_t cmd_flow_director_mask_ipv4_src =
9216 	TOKEN_IPADDR_INITIALIZER(struct cmd_flow_director_mask_result,
9217 				 ipv4_src);
9218 cmdline_parse_token_ipaddr_t cmd_flow_director_mask_ipv6_src =
9219 	TOKEN_IPADDR_INITIALIZER(struct cmd_flow_director_mask_result,
9220 				 ipv6_src);
9221 cmdline_parse_token_num_t cmd_flow_director_mask_port_src =
9222 	TOKEN_NUM_INITIALIZER(struct cmd_flow_director_mask_result,
9223 			      port_src, UINT16);
9224 cmdline_parse_token_string_t cmd_flow_director_mask_dst =
9225 	TOKEN_STRING_INITIALIZER(struct cmd_flow_director_mask_result,
9226 				 dst_mask, "dst_mask");
9227 cmdline_parse_token_ipaddr_t cmd_flow_director_mask_ipv4_dst =
9228 	TOKEN_IPADDR_INITIALIZER(struct cmd_flow_director_mask_result,
9229 				 ipv4_dst);
9230 cmdline_parse_token_ipaddr_t cmd_flow_director_mask_ipv6_dst =
9231 	TOKEN_IPADDR_INITIALIZER(struct cmd_flow_director_mask_result,
9232 				 ipv6_dst);
9233 cmdline_parse_token_num_t cmd_flow_director_mask_port_dst =
9234 	TOKEN_NUM_INITIALIZER(struct cmd_flow_director_mask_result,
9235 			      port_dst, UINT16);
9236 
9237 cmdline_parse_token_string_t cmd_flow_director_mask_mode =
9238 	TOKEN_STRING_INITIALIZER(struct cmd_flow_director_mask_result,
9239 				 mode, "mode");
9240 cmdline_parse_token_string_t cmd_flow_director_mask_mode_ip =
9241 	TOKEN_STRING_INITIALIZER(struct cmd_flow_director_mask_result,
9242 				 mode_value, "IP");
9243 cmdline_parse_token_string_t cmd_flow_director_mask_mode_mac_vlan =
9244 	TOKEN_STRING_INITIALIZER(struct cmd_flow_director_mask_result,
9245 				 mode_value, "MAC-VLAN");
9246 cmdline_parse_token_string_t cmd_flow_director_mask_mode_tunnel =
9247 	TOKEN_STRING_INITIALIZER(struct cmd_flow_director_mask_result,
9248 				 mode_value, "Tunnel");
9249 cmdline_parse_token_string_t cmd_flow_director_mask_mac =
9250 	TOKEN_STRING_INITIALIZER(struct cmd_flow_director_mask_result,
9251 				 mac, "mac");
9252 cmdline_parse_token_num_t cmd_flow_director_mask_mac_value =
9253 	TOKEN_NUM_INITIALIZER(struct cmd_flow_director_mask_result,
9254 			      mac_addr_byte_mask, UINT8);
9255 cmdline_parse_token_string_t cmd_flow_director_mask_tunnel_type =
9256 	TOKEN_STRING_INITIALIZER(struct cmd_flow_director_mask_result,
9257 				 tunnel_type, "tunnel-type");
9258 cmdline_parse_token_num_t cmd_flow_director_mask_tunnel_type_value =
9259 	TOKEN_NUM_INITIALIZER(struct cmd_flow_director_mask_result,
9260 			      tunnel_type_mask, UINT8);
9261 cmdline_parse_token_string_t cmd_flow_director_mask_tunnel_id =
9262 	TOKEN_STRING_INITIALIZER(struct cmd_flow_director_mask_result,
9263 				 tunnel_id, "tunnel-id");
9264 cmdline_parse_token_num_t cmd_flow_director_mask_tunnel_id_value =
9265 	TOKEN_NUM_INITIALIZER(struct cmd_flow_director_mask_result,
9266 			      tunnel_id_mask, UINT32);
9267 
9268 cmdline_parse_inst_t cmd_set_flow_director_ip_mask = {
9269 	.f = cmd_flow_director_mask_parsed,
9270 	.data = NULL,
9271 	.help_str = "flow_director_mask ... : "
9272 		"Set IP mode flow director's mask on NIC",
9273 	.tokens = {
9274 		(void *)&cmd_flow_director_mask,
9275 		(void *)&cmd_flow_director_mask_port_id,
9276 		(void *)&cmd_flow_director_mask_mode,
9277 		(void *)&cmd_flow_director_mask_mode_ip,
9278 		(void *)&cmd_flow_director_mask_vlan,
9279 		(void *)&cmd_flow_director_mask_vlan_value,
9280 		(void *)&cmd_flow_director_mask_src,
9281 		(void *)&cmd_flow_director_mask_ipv4_src,
9282 		(void *)&cmd_flow_director_mask_ipv6_src,
9283 		(void *)&cmd_flow_director_mask_port_src,
9284 		(void *)&cmd_flow_director_mask_dst,
9285 		(void *)&cmd_flow_director_mask_ipv4_dst,
9286 		(void *)&cmd_flow_director_mask_ipv6_dst,
9287 		(void *)&cmd_flow_director_mask_port_dst,
9288 		NULL,
9289 	},
9290 };
9291 
9292 cmdline_parse_inst_t cmd_set_flow_director_mac_vlan_mask = {
9293 	.f = cmd_flow_director_mask_parsed,
9294 	.data = NULL,
9295 	.help_str = "flow_director_mask ... : Set MAC VLAN mode "
9296 		"flow director's mask on NIC",
9297 	.tokens = {
9298 		(void *)&cmd_flow_director_mask,
9299 		(void *)&cmd_flow_director_mask_port_id,
9300 		(void *)&cmd_flow_director_mask_mode,
9301 		(void *)&cmd_flow_director_mask_mode_mac_vlan,
9302 		(void *)&cmd_flow_director_mask_vlan,
9303 		(void *)&cmd_flow_director_mask_vlan_value,
9304 		NULL,
9305 	},
9306 };
9307 
9308 cmdline_parse_inst_t cmd_set_flow_director_tunnel_mask = {
9309 	.f = cmd_flow_director_mask_parsed,
9310 	.data = NULL,
9311 	.help_str = "flow_director_mask ... : Set tunnel mode "
9312 		"flow director's mask on NIC",
9313 	.tokens = {
9314 		(void *)&cmd_flow_director_mask,
9315 		(void *)&cmd_flow_director_mask_port_id,
9316 		(void *)&cmd_flow_director_mask_mode,
9317 		(void *)&cmd_flow_director_mask_mode_tunnel,
9318 		(void *)&cmd_flow_director_mask_vlan,
9319 		(void *)&cmd_flow_director_mask_vlan_value,
9320 		(void *)&cmd_flow_director_mask_mac,
9321 		(void *)&cmd_flow_director_mask_mac_value,
9322 		(void *)&cmd_flow_director_mask_tunnel_type,
9323 		(void *)&cmd_flow_director_mask_tunnel_type_value,
9324 		(void *)&cmd_flow_director_mask_tunnel_id,
9325 		(void *)&cmd_flow_director_mask_tunnel_id_value,
9326 		NULL,
9327 	},
9328 };
9329 
9330 /* *** deal with flow director mask on flexible payload *** */
9331 struct cmd_flow_director_flex_mask_result {
9332 	cmdline_fixed_string_t flow_director_flexmask;
9333 	uint8_t port_id;
9334 	cmdline_fixed_string_t flow;
9335 	cmdline_fixed_string_t flow_type;
9336 	cmdline_fixed_string_t mask;
9337 };
9338 
9339 static void
9340 cmd_flow_director_flex_mask_parsed(void *parsed_result,
9341 			  __attribute__((unused)) struct cmdline *cl,
9342 			  __attribute__((unused)) void *data)
9343 {
9344 	struct cmd_flow_director_flex_mask_result *res = parsed_result;
9345 	struct rte_eth_fdir_info fdir_info;
9346 	struct rte_eth_fdir_flex_mask flex_mask;
9347 	struct rte_port *port;
9348 	uint32_t flow_type_mask;
9349 	uint16_t i;
9350 	int ret;
9351 
9352 	if (res->port_id > nb_ports) {
9353 		printf("Invalid port, range is [0, %d]\n", nb_ports - 1);
9354 		return;
9355 	}
9356 
9357 	port = &ports[res->port_id];
9358 	/** Check if the port is not started **/
9359 	if (port->port_status != RTE_PORT_STOPPED) {
9360 		printf("Please stop port %d first\n", res->port_id);
9361 		return;
9362 	}
9363 
9364 	memset(&flex_mask, 0, sizeof(struct rte_eth_fdir_flex_mask));
9365 	ret = parse_flexbytes(res->mask,
9366 			flex_mask.mask,
9367 			RTE_ETH_FDIR_MAX_FLEXLEN);
9368 	if (ret < 0) {
9369 		printf("error: Cannot parse mask input.\n");
9370 		return;
9371 	}
9372 
9373 	memset(&fdir_info, 0, sizeof(fdir_info));
9374 	ret = rte_eth_dev_filter_ctrl(res->port_id, RTE_ETH_FILTER_FDIR,
9375 				RTE_ETH_FILTER_INFO, &fdir_info);
9376 	if (ret < 0) {
9377 		printf("Cannot get FDir filter info\n");
9378 		return;
9379 	}
9380 
9381 	if (!strcmp(res->flow_type, "none")) {
9382 		/* means don't specify the flow type */
9383 		flex_mask.flow_type = RTE_ETH_FLOW_UNKNOWN;
9384 		for (i = 0; i < RTE_ETH_FLOW_MAX; i++)
9385 			memset(&port->dev_conf.fdir_conf.flex_conf.flex_mask[i],
9386 			       0, sizeof(struct rte_eth_fdir_flex_mask));
9387 		port->dev_conf.fdir_conf.flex_conf.nb_flexmasks = 1;
9388 		(void)rte_memcpy(&port->dev_conf.fdir_conf.flex_conf.flex_mask[0],
9389 				 &flex_mask,
9390 				 sizeof(struct rte_eth_fdir_flex_mask));
9391 		cmd_reconfig_device_queue(res->port_id, 1, 1);
9392 		return;
9393 	}
9394 	flow_type_mask = fdir_info.flow_types_mask[0];
9395 	if (!strcmp(res->flow_type, "all")) {
9396 		if (!flow_type_mask) {
9397 			printf("No flow type supported\n");
9398 			return;
9399 		}
9400 		for (i = RTE_ETH_FLOW_UNKNOWN; i < RTE_ETH_FLOW_MAX; i++) {
9401 			if (flow_type_mask & (1 << i)) {
9402 				flex_mask.flow_type = i;
9403 				fdir_set_flex_mask(res->port_id, &flex_mask);
9404 			}
9405 		}
9406 		cmd_reconfig_device_queue(res->port_id, 1, 1);
9407 		return;
9408 	}
9409 	flex_mask.flow_type = str2flowtype(res->flow_type);
9410 	if (!(flow_type_mask & (1 << flex_mask.flow_type))) {
9411 		printf("Flow type %s not supported on port %d\n",
9412 				res->flow_type, res->port_id);
9413 		return;
9414 	}
9415 	fdir_set_flex_mask(res->port_id, &flex_mask);
9416 	cmd_reconfig_device_queue(res->port_id, 1, 1);
9417 }
9418 
9419 cmdline_parse_token_string_t cmd_flow_director_flexmask =
9420 	TOKEN_STRING_INITIALIZER(struct cmd_flow_director_flex_mask_result,
9421 				 flow_director_flexmask,
9422 				 "flow_director_flex_mask");
9423 cmdline_parse_token_num_t cmd_flow_director_flexmask_port_id =
9424 	TOKEN_NUM_INITIALIZER(struct cmd_flow_director_flex_mask_result,
9425 			      port_id, UINT8);
9426 cmdline_parse_token_string_t cmd_flow_director_flexmask_flow =
9427 	TOKEN_STRING_INITIALIZER(struct cmd_flow_director_flex_mask_result,
9428 				 flow, "flow");
9429 cmdline_parse_token_string_t cmd_flow_director_flexmask_flow_type =
9430 	TOKEN_STRING_INITIALIZER(struct cmd_flow_director_flex_mask_result,
9431 		flow_type, "none#ipv4-other#ipv4-frag#ipv4-tcp#ipv4-udp#ipv4-sctp#"
9432 		"ipv6-other#ipv6-frag#ipv6-tcp#ipv6-udp#ipv6-sctp#l2_payload#all");
9433 cmdline_parse_token_string_t cmd_flow_director_flexmask_mask =
9434 	TOKEN_STRING_INITIALIZER(struct cmd_flow_director_flex_mask_result,
9435 				 mask, NULL);
9436 
9437 cmdline_parse_inst_t cmd_set_flow_director_flex_mask = {
9438 	.f = cmd_flow_director_flex_mask_parsed,
9439 	.data = NULL,
9440 	.help_str = "flow_director_flex_mask ... : "
9441 		"Set flow director's flex mask on NIC",
9442 	.tokens = {
9443 		(void *)&cmd_flow_director_flexmask,
9444 		(void *)&cmd_flow_director_flexmask_port_id,
9445 		(void *)&cmd_flow_director_flexmask_flow,
9446 		(void *)&cmd_flow_director_flexmask_flow_type,
9447 		(void *)&cmd_flow_director_flexmask_mask,
9448 		NULL,
9449 	},
9450 };
9451 
9452 /* *** deal with flow director flexible payload configuration *** */
9453 struct cmd_flow_director_flexpayload_result {
9454 	cmdline_fixed_string_t flow_director_flexpayload;
9455 	uint8_t port_id;
9456 	cmdline_fixed_string_t payload_layer;
9457 	cmdline_fixed_string_t payload_cfg;
9458 };
9459 
9460 static inline int
9461 parse_offsets(const char *q_arg, uint16_t *offsets, uint16_t max_num)
9462 {
9463 	char s[256];
9464 	const char *p, *p0 = q_arg;
9465 	char *end;
9466 	unsigned long int_fld;
9467 	char *str_fld[max_num];
9468 	int i;
9469 	unsigned size;
9470 	int ret = -1;
9471 
9472 	p = strchr(p0, '(');
9473 	if (p == NULL)
9474 		return -1;
9475 	++p;
9476 	p0 = strchr(p, ')');
9477 	if (p0 == NULL)
9478 		return -1;
9479 
9480 	size = p0 - p;
9481 	if (size >= sizeof(s))
9482 		return -1;
9483 
9484 	snprintf(s, sizeof(s), "%.*s", size, p);
9485 	ret = rte_strsplit(s, sizeof(s), str_fld, max_num, ',');
9486 	if (ret < 0 || ret > max_num)
9487 		return -1;
9488 	for (i = 0; i < ret; i++) {
9489 		errno = 0;
9490 		int_fld = strtoul(str_fld[i], &end, 0);
9491 		if (errno != 0 || *end != '\0' || int_fld > UINT16_MAX)
9492 			return -1;
9493 		offsets[i] = (uint16_t)int_fld;
9494 	}
9495 	return ret;
9496 }
9497 
9498 static void
9499 cmd_flow_director_flxpld_parsed(void *parsed_result,
9500 			  __attribute__((unused)) struct cmdline *cl,
9501 			  __attribute__((unused)) void *data)
9502 {
9503 	struct cmd_flow_director_flexpayload_result *res = parsed_result;
9504 	struct rte_eth_flex_payload_cfg flex_cfg;
9505 	struct rte_port *port;
9506 	int ret = 0;
9507 
9508 	if (res->port_id > nb_ports) {
9509 		printf("Invalid port, range is [0, %d]\n", nb_ports - 1);
9510 		return;
9511 	}
9512 
9513 	port = &ports[res->port_id];
9514 	/** Check if the port is not started **/
9515 	if (port->port_status != RTE_PORT_STOPPED) {
9516 		printf("Please stop port %d first\n", res->port_id);
9517 		return;
9518 	}
9519 
9520 	memset(&flex_cfg, 0, sizeof(struct rte_eth_flex_payload_cfg));
9521 
9522 	if (!strcmp(res->payload_layer, "raw"))
9523 		flex_cfg.type = RTE_ETH_RAW_PAYLOAD;
9524 	else if (!strcmp(res->payload_layer, "l2"))
9525 		flex_cfg.type = RTE_ETH_L2_PAYLOAD;
9526 	else if (!strcmp(res->payload_layer, "l3"))
9527 		flex_cfg.type = RTE_ETH_L3_PAYLOAD;
9528 	else if (!strcmp(res->payload_layer, "l4"))
9529 		flex_cfg.type = RTE_ETH_L4_PAYLOAD;
9530 
9531 	ret = parse_offsets(res->payload_cfg, flex_cfg.src_offset,
9532 			    RTE_ETH_FDIR_MAX_FLEXLEN);
9533 	if (ret < 0) {
9534 		printf("error: Cannot parse flex payload input.\n");
9535 		return;
9536 	}
9537 
9538 	fdir_set_flex_payload(res->port_id, &flex_cfg);
9539 	cmd_reconfig_device_queue(res->port_id, 1, 1);
9540 }
9541 
9542 cmdline_parse_token_string_t cmd_flow_director_flexpayload =
9543 	TOKEN_STRING_INITIALIZER(struct cmd_flow_director_flexpayload_result,
9544 				 flow_director_flexpayload,
9545 				 "flow_director_flex_payload");
9546 cmdline_parse_token_num_t cmd_flow_director_flexpayload_port_id =
9547 	TOKEN_NUM_INITIALIZER(struct cmd_flow_director_flexpayload_result,
9548 			      port_id, UINT8);
9549 cmdline_parse_token_string_t cmd_flow_director_flexpayload_payload_layer =
9550 	TOKEN_STRING_INITIALIZER(struct cmd_flow_director_flexpayload_result,
9551 				 payload_layer, "raw#l2#l3#l4");
9552 cmdline_parse_token_string_t cmd_flow_director_flexpayload_payload_cfg =
9553 	TOKEN_STRING_INITIALIZER(struct cmd_flow_director_flexpayload_result,
9554 				 payload_cfg, NULL);
9555 
9556 cmdline_parse_inst_t cmd_set_flow_director_flex_payload = {
9557 	.f = cmd_flow_director_flxpld_parsed,
9558 	.data = NULL,
9559 	.help_str = "flow_director_flexpayload ... : "
9560 		"Set flow director's flex payload on NIC",
9561 	.tokens = {
9562 		(void *)&cmd_flow_director_flexpayload,
9563 		(void *)&cmd_flow_director_flexpayload_port_id,
9564 		(void *)&cmd_flow_director_flexpayload_payload_layer,
9565 		(void *)&cmd_flow_director_flexpayload_payload_cfg,
9566 		NULL,
9567 	},
9568 };
9569 
9570 /* *** Classification Filters Control *** */
9571 /* *** Get symmetric hash enable per port *** */
9572 struct cmd_get_sym_hash_ena_per_port_result {
9573 	cmdline_fixed_string_t get_sym_hash_ena_per_port;
9574 	uint8_t port_id;
9575 };
9576 
9577 static void
9578 cmd_get_sym_hash_per_port_parsed(void *parsed_result,
9579 				 __rte_unused struct cmdline *cl,
9580 				 __rte_unused void *data)
9581 {
9582 	struct cmd_get_sym_hash_ena_per_port_result *res = parsed_result;
9583 	struct rte_eth_hash_filter_info info;
9584 	int ret;
9585 
9586 	if (rte_eth_dev_filter_supported(res->port_id,
9587 				RTE_ETH_FILTER_HASH) < 0) {
9588 		printf("RTE_ETH_FILTER_HASH not supported on port: %d\n",
9589 							res->port_id);
9590 		return;
9591 	}
9592 
9593 	memset(&info, 0, sizeof(info));
9594 	info.info_type = RTE_ETH_HASH_FILTER_SYM_HASH_ENA_PER_PORT;
9595 	ret = rte_eth_dev_filter_ctrl(res->port_id, RTE_ETH_FILTER_HASH,
9596 						RTE_ETH_FILTER_GET, &info);
9597 
9598 	if (ret < 0) {
9599 		printf("Cannot get symmetric hash enable per port "
9600 					"on port %u\n", res->port_id);
9601 		return;
9602 	}
9603 
9604 	printf("Symmetric hash is %s on port %u\n", info.info.enable ?
9605 				"enabled" : "disabled", res->port_id);
9606 }
9607 
9608 cmdline_parse_token_string_t cmd_get_sym_hash_ena_per_port_all =
9609 	TOKEN_STRING_INITIALIZER(struct cmd_get_sym_hash_ena_per_port_result,
9610 		get_sym_hash_ena_per_port, "get_sym_hash_ena_per_port");
9611 cmdline_parse_token_num_t cmd_get_sym_hash_ena_per_port_port_id =
9612 	TOKEN_NUM_INITIALIZER(struct cmd_get_sym_hash_ena_per_port_result,
9613 		port_id, UINT8);
9614 
9615 cmdline_parse_inst_t cmd_get_sym_hash_ena_per_port = {
9616 	.f = cmd_get_sym_hash_per_port_parsed,
9617 	.data = NULL,
9618 	.help_str = "get_sym_hash_ena_per_port <port_id>",
9619 	.tokens = {
9620 		(void *)&cmd_get_sym_hash_ena_per_port_all,
9621 		(void *)&cmd_get_sym_hash_ena_per_port_port_id,
9622 		NULL,
9623 	},
9624 };
9625 
9626 /* *** Set symmetric hash enable per port *** */
9627 struct cmd_set_sym_hash_ena_per_port_result {
9628 	cmdline_fixed_string_t set_sym_hash_ena_per_port;
9629 	cmdline_fixed_string_t enable;
9630 	uint8_t port_id;
9631 };
9632 
9633 static void
9634 cmd_set_sym_hash_per_port_parsed(void *parsed_result,
9635 				 __rte_unused struct cmdline *cl,
9636 				 __rte_unused void *data)
9637 {
9638 	struct cmd_set_sym_hash_ena_per_port_result *res = parsed_result;
9639 	struct rte_eth_hash_filter_info info;
9640 	int ret;
9641 
9642 	if (rte_eth_dev_filter_supported(res->port_id,
9643 				RTE_ETH_FILTER_HASH) < 0) {
9644 		printf("RTE_ETH_FILTER_HASH not supported on port: %d\n",
9645 							res->port_id);
9646 		return;
9647 	}
9648 
9649 	memset(&info, 0, sizeof(info));
9650 	info.info_type = RTE_ETH_HASH_FILTER_SYM_HASH_ENA_PER_PORT;
9651 	if (!strcmp(res->enable, "enable"))
9652 		info.info.enable = 1;
9653 	ret = rte_eth_dev_filter_ctrl(res->port_id, RTE_ETH_FILTER_HASH,
9654 					RTE_ETH_FILTER_SET, &info);
9655 	if (ret < 0) {
9656 		printf("Cannot set symmetric hash enable per port on "
9657 					"port %u\n", res->port_id);
9658 		return;
9659 	}
9660 	printf("Symmetric hash has been set to %s on port %u\n",
9661 					res->enable, res->port_id);
9662 }
9663 
9664 cmdline_parse_token_string_t cmd_set_sym_hash_ena_per_port_all =
9665 	TOKEN_STRING_INITIALIZER(struct cmd_set_sym_hash_ena_per_port_result,
9666 		set_sym_hash_ena_per_port, "set_sym_hash_ena_per_port");
9667 cmdline_parse_token_num_t cmd_set_sym_hash_ena_per_port_port_id =
9668 	TOKEN_NUM_INITIALIZER(struct cmd_set_sym_hash_ena_per_port_result,
9669 		port_id, UINT8);
9670 cmdline_parse_token_string_t cmd_set_sym_hash_ena_per_port_enable =
9671 	TOKEN_STRING_INITIALIZER(struct cmd_set_sym_hash_ena_per_port_result,
9672 		enable, "enable#disable");
9673 
9674 cmdline_parse_inst_t cmd_set_sym_hash_ena_per_port = {
9675 	.f = cmd_set_sym_hash_per_port_parsed,
9676 	.data = NULL,
9677 	.help_str = "set_sym_hash_ena_per_port <port_id> enable|disable",
9678 	.tokens = {
9679 		(void *)&cmd_set_sym_hash_ena_per_port_all,
9680 		(void *)&cmd_set_sym_hash_ena_per_port_port_id,
9681 		(void *)&cmd_set_sym_hash_ena_per_port_enable,
9682 		NULL,
9683 	},
9684 };
9685 
9686 /* Get global config of hash function */
9687 struct cmd_get_hash_global_config_result {
9688 	cmdline_fixed_string_t get_hash_global_config;
9689 	uint8_t port_id;
9690 };
9691 
9692 static char *
9693 flowtype_to_str(uint16_t ftype)
9694 {
9695 	uint16_t i;
9696 	static struct {
9697 		char str[16];
9698 		uint16_t ftype;
9699 	} ftype_table[] = {
9700 		{"ipv4", RTE_ETH_FLOW_IPV4},
9701 		{"ipv4-frag", RTE_ETH_FLOW_FRAG_IPV4},
9702 		{"ipv4-tcp", RTE_ETH_FLOW_NONFRAG_IPV4_TCP},
9703 		{"ipv4-udp", RTE_ETH_FLOW_NONFRAG_IPV4_UDP},
9704 		{"ipv4-sctp", RTE_ETH_FLOW_NONFRAG_IPV4_SCTP},
9705 		{"ipv4-other", RTE_ETH_FLOW_NONFRAG_IPV4_OTHER},
9706 		{"ipv6", RTE_ETH_FLOW_IPV6},
9707 		{"ipv6-frag", RTE_ETH_FLOW_FRAG_IPV6},
9708 		{"ipv6-tcp", RTE_ETH_FLOW_NONFRAG_IPV6_TCP},
9709 		{"ipv6-udp", RTE_ETH_FLOW_NONFRAG_IPV6_UDP},
9710 		{"ipv6-sctp", RTE_ETH_FLOW_NONFRAG_IPV6_SCTP},
9711 		{"ipv6-other", RTE_ETH_FLOW_NONFRAG_IPV6_OTHER},
9712 		{"l2_payload", RTE_ETH_FLOW_L2_PAYLOAD},
9713 		{"port", RTE_ETH_FLOW_PORT},
9714 		{"vxlan", RTE_ETH_FLOW_VXLAN},
9715 		{"geneve", RTE_ETH_FLOW_GENEVE},
9716 		{"nvgre", RTE_ETH_FLOW_NVGRE},
9717 	};
9718 
9719 	for (i = 0; i < RTE_DIM(ftype_table); i++) {
9720 		if (ftype_table[i].ftype == ftype)
9721 			return ftype_table[i].str;
9722 	}
9723 
9724 	return NULL;
9725 }
9726 
9727 static void
9728 cmd_get_hash_global_config_parsed(void *parsed_result,
9729 				  __rte_unused struct cmdline *cl,
9730 				  __rte_unused void *data)
9731 {
9732 	struct cmd_get_hash_global_config_result *res = parsed_result;
9733 	struct rte_eth_hash_filter_info info;
9734 	uint32_t idx, offset;
9735 	uint16_t i;
9736 	char *str;
9737 	int ret;
9738 
9739 	if (rte_eth_dev_filter_supported(res->port_id,
9740 			RTE_ETH_FILTER_HASH) < 0) {
9741 		printf("RTE_ETH_FILTER_HASH not supported on port %d\n",
9742 							res->port_id);
9743 		return;
9744 	}
9745 
9746 	memset(&info, 0, sizeof(info));
9747 	info.info_type = RTE_ETH_HASH_FILTER_GLOBAL_CONFIG;
9748 	ret = rte_eth_dev_filter_ctrl(res->port_id, RTE_ETH_FILTER_HASH,
9749 					RTE_ETH_FILTER_GET, &info);
9750 	if (ret < 0) {
9751 		printf("Cannot get hash global configurations by port %d\n",
9752 							res->port_id);
9753 		return;
9754 	}
9755 
9756 	switch (info.info.global_conf.hash_func) {
9757 	case RTE_ETH_HASH_FUNCTION_TOEPLITZ:
9758 		printf("Hash function is Toeplitz\n");
9759 		break;
9760 	case RTE_ETH_HASH_FUNCTION_SIMPLE_XOR:
9761 		printf("Hash function is Simple XOR\n");
9762 		break;
9763 	default:
9764 		printf("Unknown hash function\n");
9765 		break;
9766 	}
9767 
9768 	for (i = 0; i < RTE_ETH_FLOW_MAX; i++) {
9769 		idx = i / UINT32_BIT;
9770 		offset = i % UINT32_BIT;
9771 		if (!(info.info.global_conf.valid_bit_mask[idx] &
9772 						(1UL << offset)))
9773 			continue;
9774 		str = flowtype_to_str(i);
9775 		if (!str)
9776 			continue;
9777 		printf("Symmetric hash is %s globally for flow type %s "
9778 							"by port %d\n",
9779 			((info.info.global_conf.sym_hash_enable_mask[idx] &
9780 			(1UL << offset)) ? "enabled" : "disabled"), str,
9781 							res->port_id);
9782 	}
9783 }
9784 
9785 cmdline_parse_token_string_t cmd_get_hash_global_config_all =
9786 	TOKEN_STRING_INITIALIZER(struct cmd_get_hash_global_config_result,
9787 		get_hash_global_config, "get_hash_global_config");
9788 cmdline_parse_token_num_t cmd_get_hash_global_config_port_id =
9789 	TOKEN_NUM_INITIALIZER(struct cmd_get_hash_global_config_result,
9790 		port_id, UINT8);
9791 
9792 cmdline_parse_inst_t cmd_get_hash_global_config = {
9793 	.f = cmd_get_hash_global_config_parsed,
9794 	.data = NULL,
9795 	.help_str = "get_hash_global_config <port_id>",
9796 	.tokens = {
9797 		(void *)&cmd_get_hash_global_config_all,
9798 		(void *)&cmd_get_hash_global_config_port_id,
9799 		NULL,
9800 	},
9801 };
9802 
9803 /* Set global config of hash function */
9804 struct cmd_set_hash_global_config_result {
9805 	cmdline_fixed_string_t set_hash_global_config;
9806 	uint8_t port_id;
9807 	cmdline_fixed_string_t hash_func;
9808 	cmdline_fixed_string_t flow_type;
9809 	cmdline_fixed_string_t enable;
9810 };
9811 
9812 static void
9813 cmd_set_hash_global_config_parsed(void *parsed_result,
9814 				  __rte_unused struct cmdline *cl,
9815 				  __rte_unused void *data)
9816 {
9817 	struct cmd_set_hash_global_config_result *res = parsed_result;
9818 	struct rte_eth_hash_filter_info info;
9819 	uint32_t ftype, idx, offset;
9820 	int ret;
9821 
9822 	if (rte_eth_dev_filter_supported(res->port_id,
9823 				RTE_ETH_FILTER_HASH) < 0) {
9824 		printf("RTE_ETH_FILTER_HASH not supported on port %d\n",
9825 							res->port_id);
9826 		return;
9827 	}
9828 	memset(&info, 0, sizeof(info));
9829 	info.info_type = RTE_ETH_HASH_FILTER_GLOBAL_CONFIG;
9830 	if (!strcmp(res->hash_func, "toeplitz"))
9831 		info.info.global_conf.hash_func =
9832 			RTE_ETH_HASH_FUNCTION_TOEPLITZ;
9833 	else if (!strcmp(res->hash_func, "simple_xor"))
9834 		info.info.global_conf.hash_func =
9835 			RTE_ETH_HASH_FUNCTION_SIMPLE_XOR;
9836 	else if (!strcmp(res->hash_func, "default"))
9837 		info.info.global_conf.hash_func =
9838 			RTE_ETH_HASH_FUNCTION_DEFAULT;
9839 
9840 	ftype = str2flowtype(res->flow_type);
9841 	idx = ftype / (CHAR_BIT * sizeof(uint32_t));
9842 	offset = ftype % (CHAR_BIT * sizeof(uint32_t));
9843 	info.info.global_conf.valid_bit_mask[idx] |= (1UL << offset);
9844 	if (!strcmp(res->enable, "enable"))
9845 		info.info.global_conf.sym_hash_enable_mask[idx] |=
9846 						(1UL << offset);
9847 	ret = rte_eth_dev_filter_ctrl(res->port_id, RTE_ETH_FILTER_HASH,
9848 					RTE_ETH_FILTER_SET, &info);
9849 	if (ret < 0)
9850 		printf("Cannot set global hash configurations by port %d\n",
9851 							res->port_id);
9852 	else
9853 		printf("Global hash configurations have been set "
9854 			"succcessfully by port %d\n", res->port_id);
9855 }
9856 
9857 cmdline_parse_token_string_t cmd_set_hash_global_config_all =
9858 	TOKEN_STRING_INITIALIZER(struct cmd_set_hash_global_config_result,
9859 		set_hash_global_config, "set_hash_global_config");
9860 cmdline_parse_token_num_t cmd_set_hash_global_config_port_id =
9861 	TOKEN_NUM_INITIALIZER(struct cmd_set_hash_global_config_result,
9862 		port_id, UINT8);
9863 cmdline_parse_token_string_t cmd_set_hash_global_config_hash_func =
9864 	TOKEN_STRING_INITIALIZER(struct cmd_set_hash_global_config_result,
9865 		hash_func, "toeplitz#simple_xor#default");
9866 cmdline_parse_token_string_t cmd_set_hash_global_config_flow_type =
9867 	TOKEN_STRING_INITIALIZER(struct cmd_set_hash_global_config_result,
9868 		flow_type,
9869 		"ipv4#ipv4-frag#ipv4-tcp#ipv4-udp#ipv4-sctp#ipv4-other#ipv6#"
9870 		"ipv6-frag#ipv6-tcp#ipv6-udp#ipv6-sctp#ipv6-other#l2_payload");
9871 cmdline_parse_token_string_t cmd_set_hash_global_config_enable =
9872 	TOKEN_STRING_INITIALIZER(struct cmd_set_hash_global_config_result,
9873 		enable, "enable#disable");
9874 
9875 cmdline_parse_inst_t cmd_set_hash_global_config = {
9876 	.f = cmd_set_hash_global_config_parsed,
9877 	.data = NULL,
9878 	.help_str = "set_hash_global_config <port_id> "
9879 		"toeplitz|simple_xor|default "
9880 		"ipv4|ipv4-frag|ipv4-tcp|ipv4-udp|ipv4-sctp|ipv4-other|"
9881 		"ipv6|ipv6-frag|ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other|"
9882 		"l2_payload enable|disable",
9883 	.tokens = {
9884 		(void *)&cmd_set_hash_global_config_all,
9885 		(void *)&cmd_set_hash_global_config_port_id,
9886 		(void *)&cmd_set_hash_global_config_hash_func,
9887 		(void *)&cmd_set_hash_global_config_flow_type,
9888 		(void *)&cmd_set_hash_global_config_enable,
9889 		NULL,
9890 	},
9891 };
9892 
9893 /* Set hash input set */
9894 struct cmd_set_hash_input_set_result {
9895 	cmdline_fixed_string_t set_hash_input_set;
9896 	uint8_t port_id;
9897 	cmdline_fixed_string_t flow_type;
9898 	cmdline_fixed_string_t inset_field;
9899 	cmdline_fixed_string_t select;
9900 };
9901 
9902 static enum rte_eth_input_set_field
9903 str2inset(char *string)
9904 {
9905 	uint16_t i;
9906 
9907 	static const struct {
9908 		char str[32];
9909 		enum rte_eth_input_set_field inset;
9910 	} inset_table[] = {
9911 		{"ethertype", RTE_ETH_INPUT_SET_L2_ETHERTYPE},
9912 		{"ovlan", RTE_ETH_INPUT_SET_L2_OUTER_VLAN},
9913 		{"ivlan", RTE_ETH_INPUT_SET_L2_INNER_VLAN},
9914 		{"src-ipv4", RTE_ETH_INPUT_SET_L3_SRC_IP4},
9915 		{"dst-ipv4", RTE_ETH_INPUT_SET_L3_DST_IP4},
9916 		{"ipv4-tos", RTE_ETH_INPUT_SET_L3_IP4_TOS},
9917 		{"ipv4-proto", RTE_ETH_INPUT_SET_L3_IP4_PROTO},
9918 		{"ipv4-ttl", RTE_ETH_INPUT_SET_L3_IP4_TTL},
9919 		{"src-ipv6", RTE_ETH_INPUT_SET_L3_SRC_IP6},
9920 		{"dst-ipv6", RTE_ETH_INPUT_SET_L3_DST_IP6},
9921 		{"ipv6-tc", RTE_ETH_INPUT_SET_L3_IP6_TC},
9922 		{"ipv6-next-header", RTE_ETH_INPUT_SET_L3_IP6_NEXT_HEADER},
9923 		{"ipv6-hop-limits", RTE_ETH_INPUT_SET_L3_IP6_HOP_LIMITS},
9924 		{"udp-src-port", RTE_ETH_INPUT_SET_L4_UDP_SRC_PORT},
9925 		{"udp-dst-port", RTE_ETH_INPUT_SET_L4_UDP_DST_PORT},
9926 		{"tcp-src-port", RTE_ETH_INPUT_SET_L4_TCP_SRC_PORT},
9927 		{"tcp-dst-port", RTE_ETH_INPUT_SET_L4_TCP_DST_PORT},
9928 		{"sctp-src-port", RTE_ETH_INPUT_SET_L4_SCTP_SRC_PORT},
9929 		{"sctp-dst-port", RTE_ETH_INPUT_SET_L4_SCTP_DST_PORT},
9930 		{"sctp-veri-tag", RTE_ETH_INPUT_SET_L4_SCTP_VERIFICATION_TAG},
9931 		{"udp-key", RTE_ETH_INPUT_SET_TUNNEL_L4_UDP_KEY},
9932 		{"gre-key", RTE_ETH_INPUT_SET_TUNNEL_GRE_KEY},
9933 		{"fld-1st", RTE_ETH_INPUT_SET_FLEX_PAYLOAD_1ST_WORD},
9934 		{"fld-2nd", RTE_ETH_INPUT_SET_FLEX_PAYLOAD_2ND_WORD},
9935 		{"fld-3rd", RTE_ETH_INPUT_SET_FLEX_PAYLOAD_3RD_WORD},
9936 		{"fld-4th", RTE_ETH_INPUT_SET_FLEX_PAYLOAD_4TH_WORD},
9937 		{"fld-5th", RTE_ETH_INPUT_SET_FLEX_PAYLOAD_5TH_WORD},
9938 		{"fld-6th", RTE_ETH_INPUT_SET_FLEX_PAYLOAD_6TH_WORD},
9939 		{"fld-7th", RTE_ETH_INPUT_SET_FLEX_PAYLOAD_7TH_WORD},
9940 		{"fld-8th", RTE_ETH_INPUT_SET_FLEX_PAYLOAD_8TH_WORD},
9941 		{"none", RTE_ETH_INPUT_SET_NONE},
9942 	};
9943 
9944 	for (i = 0; i < RTE_DIM(inset_table); i++) {
9945 		if (!strcmp(string, inset_table[i].str))
9946 			return inset_table[i].inset;
9947 	}
9948 
9949 	return RTE_ETH_INPUT_SET_UNKNOWN;
9950 }
9951 
9952 static void
9953 cmd_set_hash_input_set_parsed(void *parsed_result,
9954 			      __rte_unused struct cmdline *cl,
9955 			      __rte_unused void *data)
9956 {
9957 	struct cmd_set_hash_input_set_result *res = parsed_result;
9958 	struct rte_eth_hash_filter_info info;
9959 
9960 	memset(&info, 0, sizeof(info));
9961 	info.info_type = RTE_ETH_HASH_FILTER_INPUT_SET_SELECT;
9962 	info.info.input_set_conf.flow_type = str2flowtype(res->flow_type);
9963 	info.info.input_set_conf.field[0] = str2inset(res->inset_field);
9964 	info.info.input_set_conf.inset_size = 1;
9965 	if (!strcmp(res->select, "select"))
9966 		info.info.input_set_conf.op = RTE_ETH_INPUT_SET_SELECT;
9967 	else if (!strcmp(res->select, "add"))
9968 		info.info.input_set_conf.op = RTE_ETH_INPUT_SET_ADD;
9969 	rte_eth_dev_filter_ctrl(res->port_id, RTE_ETH_FILTER_HASH,
9970 				RTE_ETH_FILTER_SET, &info);
9971 }
9972 
9973 cmdline_parse_token_string_t cmd_set_hash_input_set_cmd =
9974 	TOKEN_STRING_INITIALIZER(struct cmd_set_hash_input_set_result,
9975 		set_hash_input_set, "set_hash_input_set");
9976 cmdline_parse_token_num_t cmd_set_hash_input_set_port_id =
9977 	TOKEN_NUM_INITIALIZER(struct cmd_set_hash_input_set_result,
9978 		port_id, UINT8);
9979 cmdline_parse_token_string_t cmd_set_hash_input_set_flow_type =
9980 	TOKEN_STRING_INITIALIZER(struct cmd_set_hash_input_set_result,
9981 		flow_type,
9982 		"ipv4-frag#ipv4-tcp#ipv4-udp#ipv4-sctp#ipv4-other#"
9983 		"ipv6-frag#ipv6-tcp#ipv6-udp#ipv6-sctp#ipv6-other#l2_payload");
9984 cmdline_parse_token_string_t cmd_set_hash_input_set_field =
9985 	TOKEN_STRING_INITIALIZER(struct cmd_set_hash_input_set_result,
9986 		inset_field,
9987 		"ovlan#ivlan#src-ipv4#dst-ipv4#src-ipv6#dst-ipv6#"
9988 		"ipv4-tos#ipv4-proto#ipv6-tc#ipv6-next-header#udp-src-port#"
9989 		"udp-dst-port#tcp-src-port#tcp-dst-port#sctp-src-port#"
9990 		"sctp-dst-port#sctp-veri-tag#udp-key#gre-key#fld-1st#"
9991 		"fld-2nd#fld-3rd#fld-4th#fld-5th#fld-6th#fld-7th#"
9992 		"fld-8th#none");
9993 cmdline_parse_token_string_t cmd_set_hash_input_set_select =
9994 	TOKEN_STRING_INITIALIZER(struct cmd_set_hash_input_set_result,
9995 		select, "select#add");
9996 
9997 cmdline_parse_inst_t cmd_set_hash_input_set = {
9998 	.f = cmd_set_hash_input_set_parsed,
9999 	.data = NULL,
10000 	.help_str = "set_hash_input_set <port_id> "
10001 	"ipv4-frag|ipv4-tcp|ipv4-udp|ipv4-sctp|ipv4-other|"
10002 	"ipv6-frag|ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other|l2_payload "
10003 	"ovlan|ivlan|src-ipv4|dst-ipv4|src-ipv6|dst-ipv6|ipv4-tos|ipv4-proto|"
10004 	"ipv6-tc|ipv6-next-header|udp-src-port|udp-dst-port|tcp-src-port|"
10005 	"tcp-dst-port|sctp-src-port|sctp-dst-port|sctp-veri-tag|udp-key|"
10006 	"gre-key|fld-1st|fld-2nd|fld-3rd|fld-4th|fld-5th|fld-6th|"
10007 	"fld-7th|fld-8th|none select|add",
10008 	.tokens = {
10009 		(void *)&cmd_set_hash_input_set_cmd,
10010 		(void *)&cmd_set_hash_input_set_port_id,
10011 		(void *)&cmd_set_hash_input_set_flow_type,
10012 		(void *)&cmd_set_hash_input_set_field,
10013 		(void *)&cmd_set_hash_input_set_select,
10014 		NULL,
10015 	},
10016 };
10017 
10018 /* Set flow director input set */
10019 struct cmd_set_fdir_input_set_result {
10020 	cmdline_fixed_string_t set_fdir_input_set;
10021 	uint8_t port_id;
10022 	cmdline_fixed_string_t flow_type;
10023 	cmdline_fixed_string_t inset_field;
10024 	cmdline_fixed_string_t select;
10025 };
10026 
10027 static void
10028 cmd_set_fdir_input_set_parsed(void *parsed_result,
10029 	__rte_unused struct cmdline *cl,
10030 	__rte_unused void *data)
10031 {
10032 	struct cmd_set_fdir_input_set_result *res = parsed_result;
10033 	struct rte_eth_fdir_filter_info info;
10034 
10035 	memset(&info, 0, sizeof(info));
10036 	info.info_type = RTE_ETH_FDIR_FILTER_INPUT_SET_SELECT;
10037 	info.info.input_set_conf.flow_type = str2flowtype(res->flow_type);
10038 	info.info.input_set_conf.field[0] = str2inset(res->inset_field);
10039 	info.info.input_set_conf.inset_size = 1;
10040 	if (!strcmp(res->select, "select"))
10041 		info.info.input_set_conf.op = RTE_ETH_INPUT_SET_SELECT;
10042 	else if (!strcmp(res->select, "add"))
10043 		info.info.input_set_conf.op = RTE_ETH_INPUT_SET_ADD;
10044 	rte_eth_dev_filter_ctrl(res->port_id, RTE_ETH_FILTER_FDIR,
10045 		RTE_ETH_FILTER_SET, &info);
10046 }
10047 
10048 cmdline_parse_token_string_t cmd_set_fdir_input_set_cmd =
10049 	TOKEN_STRING_INITIALIZER(struct cmd_set_fdir_input_set_result,
10050 	set_fdir_input_set, "set_fdir_input_set");
10051 cmdline_parse_token_num_t cmd_set_fdir_input_set_port_id =
10052 	TOKEN_NUM_INITIALIZER(struct cmd_set_fdir_input_set_result,
10053 	port_id, UINT8);
10054 cmdline_parse_token_string_t cmd_set_fdir_input_set_flow_type =
10055 	TOKEN_STRING_INITIALIZER(struct cmd_set_fdir_input_set_result,
10056 	flow_type,
10057 	"ipv4-frag#ipv4-tcp#ipv4-udp#ipv4-sctp#ipv4-other#"
10058 	"ipv6-frag#ipv6-tcp#ipv6-udp#ipv6-sctp#ipv6-other#l2_payload");
10059 cmdline_parse_token_string_t cmd_set_fdir_input_set_field =
10060 	TOKEN_STRING_INITIALIZER(struct cmd_set_fdir_input_set_result,
10061 	inset_field,
10062 	"ivlan#ethertype#src-ipv4#dst-ipv4#src-ipv6#dst-ipv6#"
10063 	"ipv4-tos#ipv4-proto#ipv4-ttl#ipv6-tc#ipv6-next-header#"
10064 	"ipv6-hop-limits#udp-src-port#udp-dst-port#"
10065 	"tcp-src-port#tcp-dst-port#sctp-src-port#sctp-dst-port#"
10066 	"sctp-veri-tag#none");
10067 cmdline_parse_token_string_t cmd_set_fdir_input_set_select =
10068 	TOKEN_STRING_INITIALIZER(struct cmd_set_fdir_input_set_result,
10069 	select, "select#add");
10070 
10071 cmdline_parse_inst_t cmd_set_fdir_input_set = {
10072 	.f = cmd_set_fdir_input_set_parsed,
10073 	.data = NULL,
10074 	.help_str = "set_fdir_input_set <port_id> "
10075 	"ipv4-frag|ipv4-tcp|ipv4-udp|ipv4-sctp|ipv4-other|"
10076 	"ipv6-frag|ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other|l2_payload "
10077 	"ivlan|ethertype|src-ipv4|dst-ipv4|src-ipv6|dst-ipv6|"
10078 	"ipv4-tos|ipv4-proto|ipv4-ttl|ipv6-tc|ipv6-next-header|"
10079 	"ipv6-hop-limits|udp-src-port|udp-dst-port|"
10080 	"tcp-src-port|tcp-dst-port|sctp-src-port|sctp-dst-port|"
10081 	"sctp-veri-tag|none select|add",
10082 	.tokens = {
10083 		(void *)&cmd_set_fdir_input_set_cmd,
10084 		(void *)&cmd_set_fdir_input_set_port_id,
10085 		(void *)&cmd_set_fdir_input_set_flow_type,
10086 		(void *)&cmd_set_fdir_input_set_field,
10087 		(void *)&cmd_set_fdir_input_set_select,
10088 		NULL,
10089 	},
10090 };
10091 
10092 /* *** ADD/REMOVE A MULTICAST MAC ADDRESS TO/FROM A PORT *** */
10093 struct cmd_mcast_addr_result {
10094 	cmdline_fixed_string_t mcast_addr_cmd;
10095 	cmdline_fixed_string_t what;
10096 	uint8_t port_num;
10097 	struct ether_addr mc_addr;
10098 };
10099 
10100 static void cmd_mcast_addr_parsed(void *parsed_result,
10101 		__attribute__((unused)) struct cmdline *cl,
10102 		__attribute__((unused)) void *data)
10103 {
10104 	struct cmd_mcast_addr_result *res = parsed_result;
10105 
10106 	if (!is_multicast_ether_addr(&res->mc_addr)) {
10107 		printf("Invalid multicast addr %02X:%02X:%02X:%02X:%02X:%02X\n",
10108 		       res->mc_addr.addr_bytes[0], res->mc_addr.addr_bytes[1],
10109 		       res->mc_addr.addr_bytes[2], res->mc_addr.addr_bytes[3],
10110 		       res->mc_addr.addr_bytes[4], res->mc_addr.addr_bytes[5]);
10111 		return;
10112 	}
10113 	if (strcmp(res->what, "add") == 0)
10114 		mcast_addr_add(res->port_num, &res->mc_addr);
10115 	else
10116 		mcast_addr_remove(res->port_num, &res->mc_addr);
10117 }
10118 
10119 cmdline_parse_token_string_t cmd_mcast_addr_cmd =
10120 	TOKEN_STRING_INITIALIZER(struct cmd_mcast_addr_result,
10121 				 mcast_addr_cmd, "mcast_addr");
10122 cmdline_parse_token_string_t cmd_mcast_addr_what =
10123 	TOKEN_STRING_INITIALIZER(struct cmd_mcast_addr_result, what,
10124 				 "add#remove");
10125 cmdline_parse_token_num_t cmd_mcast_addr_portnum =
10126 	TOKEN_NUM_INITIALIZER(struct cmd_mcast_addr_result, port_num, UINT8);
10127 cmdline_parse_token_etheraddr_t cmd_mcast_addr_addr =
10128 	TOKEN_ETHERADDR_INITIALIZER(struct cmd_mac_addr_result, address);
10129 
10130 cmdline_parse_inst_t cmd_mcast_addr = {
10131 	.f = cmd_mcast_addr_parsed,
10132 	.data = (void *)0,
10133 	.help_str = "mcast_addr add|remove <port_id> <mcast_addr>: "
10134 		"Add/Remove multicast MAC address on port_id",
10135 	.tokens = {
10136 		(void *)&cmd_mcast_addr_cmd,
10137 		(void *)&cmd_mcast_addr_what,
10138 		(void *)&cmd_mcast_addr_portnum,
10139 		(void *)&cmd_mcast_addr_addr,
10140 		NULL,
10141 	},
10142 };
10143 
10144 /* l2 tunnel config
10145  * only support E-tag now.
10146  */
10147 
10148 /* Ether type config */
10149 struct cmd_config_l2_tunnel_eth_type_result {
10150 	cmdline_fixed_string_t port;
10151 	cmdline_fixed_string_t config;
10152 	cmdline_fixed_string_t all;
10153 	uint8_t id;
10154 	cmdline_fixed_string_t l2_tunnel;
10155 	cmdline_fixed_string_t l2_tunnel_type;
10156 	cmdline_fixed_string_t eth_type;
10157 	uint16_t eth_type_val;
10158 };
10159 
10160 cmdline_parse_token_string_t cmd_config_l2_tunnel_eth_type_port =
10161 	TOKEN_STRING_INITIALIZER
10162 		(struct cmd_config_l2_tunnel_eth_type_result,
10163 		 port, "port");
10164 cmdline_parse_token_string_t cmd_config_l2_tunnel_eth_type_config =
10165 	TOKEN_STRING_INITIALIZER
10166 		(struct cmd_config_l2_tunnel_eth_type_result,
10167 		 config, "config");
10168 cmdline_parse_token_string_t cmd_config_l2_tunnel_eth_type_all_str =
10169 	TOKEN_STRING_INITIALIZER
10170 		(struct cmd_config_l2_tunnel_eth_type_result,
10171 		 all, "all");
10172 cmdline_parse_token_num_t cmd_config_l2_tunnel_eth_type_id =
10173 	TOKEN_NUM_INITIALIZER
10174 		(struct cmd_config_l2_tunnel_eth_type_result,
10175 		 id, UINT8);
10176 cmdline_parse_token_string_t cmd_config_l2_tunnel_eth_type_l2_tunnel =
10177 	TOKEN_STRING_INITIALIZER
10178 		(struct cmd_config_l2_tunnel_eth_type_result,
10179 		 l2_tunnel, "l2-tunnel");
10180 cmdline_parse_token_string_t cmd_config_l2_tunnel_eth_type_l2_tunnel_type =
10181 	TOKEN_STRING_INITIALIZER
10182 		(struct cmd_config_l2_tunnel_eth_type_result,
10183 		 l2_tunnel_type, "E-tag");
10184 cmdline_parse_token_string_t cmd_config_l2_tunnel_eth_type_eth_type =
10185 	TOKEN_STRING_INITIALIZER
10186 		(struct cmd_config_l2_tunnel_eth_type_result,
10187 		 eth_type, "ether-type");
10188 cmdline_parse_token_num_t cmd_config_l2_tunnel_eth_type_eth_type_val =
10189 	TOKEN_NUM_INITIALIZER
10190 		(struct cmd_config_l2_tunnel_eth_type_result,
10191 		 eth_type_val, UINT16);
10192 
10193 static enum rte_eth_tunnel_type
10194 str2fdir_l2_tunnel_type(char *string)
10195 {
10196 	uint32_t i = 0;
10197 
10198 	static const struct {
10199 		char str[32];
10200 		enum rte_eth_tunnel_type type;
10201 	} l2_tunnel_type_str[] = {
10202 		{"E-tag", RTE_L2_TUNNEL_TYPE_E_TAG},
10203 	};
10204 
10205 	for (i = 0; i < RTE_DIM(l2_tunnel_type_str); i++) {
10206 		if (!strcmp(l2_tunnel_type_str[i].str, string))
10207 			return l2_tunnel_type_str[i].type;
10208 	}
10209 	return RTE_TUNNEL_TYPE_NONE;
10210 }
10211 
10212 /* ether type config for all ports */
10213 static void
10214 cmd_config_l2_tunnel_eth_type_all_parsed
10215 	(void *parsed_result,
10216 	 __attribute__((unused)) struct cmdline *cl,
10217 	 __attribute__((unused)) void *data)
10218 {
10219 	struct cmd_config_l2_tunnel_eth_type_result *res = parsed_result;
10220 	struct rte_eth_l2_tunnel_conf entry;
10221 	portid_t pid;
10222 
10223 	entry.l2_tunnel_type = str2fdir_l2_tunnel_type(res->l2_tunnel_type);
10224 	entry.ether_type = res->eth_type_val;
10225 
10226 	FOREACH_PORT(pid, ports) {
10227 		rte_eth_dev_l2_tunnel_eth_type_conf(pid, &entry);
10228 	}
10229 }
10230 
10231 cmdline_parse_inst_t cmd_config_l2_tunnel_eth_type_all = {
10232 	.f = cmd_config_l2_tunnel_eth_type_all_parsed,
10233 	.data = NULL,
10234 	.help_str = "port config all l2-tunnel E-tag ether-type <value>",
10235 	.tokens = {
10236 		(void *)&cmd_config_l2_tunnel_eth_type_port,
10237 		(void *)&cmd_config_l2_tunnel_eth_type_config,
10238 		(void *)&cmd_config_l2_tunnel_eth_type_all_str,
10239 		(void *)&cmd_config_l2_tunnel_eth_type_l2_tunnel,
10240 		(void *)&cmd_config_l2_tunnel_eth_type_l2_tunnel_type,
10241 		(void *)&cmd_config_l2_tunnel_eth_type_eth_type,
10242 		(void *)&cmd_config_l2_tunnel_eth_type_eth_type_val,
10243 		NULL,
10244 	},
10245 };
10246 
10247 /* ether type config for a specific port */
10248 static void
10249 cmd_config_l2_tunnel_eth_type_specific_parsed(
10250 	void *parsed_result,
10251 	__attribute__((unused)) struct cmdline *cl,
10252 	__attribute__((unused)) void *data)
10253 {
10254 	struct cmd_config_l2_tunnel_eth_type_result *res =
10255 		 parsed_result;
10256 	struct rte_eth_l2_tunnel_conf entry;
10257 
10258 	if (port_id_is_invalid(res->id, ENABLED_WARN))
10259 		return;
10260 
10261 	entry.l2_tunnel_type = str2fdir_l2_tunnel_type(res->l2_tunnel_type);
10262 	entry.ether_type = res->eth_type_val;
10263 
10264 	rte_eth_dev_l2_tunnel_eth_type_conf(res->id, &entry);
10265 }
10266 
10267 cmdline_parse_inst_t cmd_config_l2_tunnel_eth_type_specific = {
10268 	.f = cmd_config_l2_tunnel_eth_type_specific_parsed,
10269 	.data = NULL,
10270 	.help_str = "port config <port_id> l2-tunnel E-tag ether-type <value>",
10271 	.tokens = {
10272 		(void *)&cmd_config_l2_tunnel_eth_type_port,
10273 		(void *)&cmd_config_l2_tunnel_eth_type_config,
10274 		(void *)&cmd_config_l2_tunnel_eth_type_id,
10275 		(void *)&cmd_config_l2_tunnel_eth_type_l2_tunnel,
10276 		(void *)&cmd_config_l2_tunnel_eth_type_l2_tunnel_type,
10277 		(void *)&cmd_config_l2_tunnel_eth_type_eth_type,
10278 		(void *)&cmd_config_l2_tunnel_eth_type_eth_type_val,
10279 		NULL,
10280 	},
10281 };
10282 
10283 /* Enable/disable l2 tunnel */
10284 struct cmd_config_l2_tunnel_en_dis_result {
10285 	cmdline_fixed_string_t port;
10286 	cmdline_fixed_string_t config;
10287 	cmdline_fixed_string_t all;
10288 	uint8_t id;
10289 	cmdline_fixed_string_t l2_tunnel;
10290 	cmdline_fixed_string_t l2_tunnel_type;
10291 	cmdline_fixed_string_t en_dis;
10292 };
10293 
10294 cmdline_parse_token_string_t cmd_config_l2_tunnel_en_dis_port =
10295 	TOKEN_STRING_INITIALIZER
10296 		(struct cmd_config_l2_tunnel_en_dis_result,
10297 		 port, "port");
10298 cmdline_parse_token_string_t cmd_config_l2_tunnel_en_dis_config =
10299 	TOKEN_STRING_INITIALIZER
10300 		(struct cmd_config_l2_tunnel_en_dis_result,
10301 		 config, "config");
10302 cmdline_parse_token_string_t cmd_config_l2_tunnel_en_dis_all_str =
10303 	TOKEN_STRING_INITIALIZER
10304 		(struct cmd_config_l2_tunnel_en_dis_result,
10305 		 all, "all");
10306 cmdline_parse_token_num_t cmd_config_l2_tunnel_en_dis_id =
10307 	TOKEN_NUM_INITIALIZER
10308 		(struct cmd_config_l2_tunnel_en_dis_result,
10309 		 id, UINT8);
10310 cmdline_parse_token_string_t cmd_config_l2_tunnel_en_dis_l2_tunnel =
10311 	TOKEN_STRING_INITIALIZER
10312 		(struct cmd_config_l2_tunnel_en_dis_result,
10313 		 l2_tunnel, "l2-tunnel");
10314 cmdline_parse_token_string_t cmd_config_l2_tunnel_en_dis_l2_tunnel_type =
10315 	TOKEN_STRING_INITIALIZER
10316 		(struct cmd_config_l2_tunnel_en_dis_result,
10317 		 l2_tunnel_type, "E-tag");
10318 cmdline_parse_token_string_t cmd_config_l2_tunnel_en_dis_en_dis =
10319 	TOKEN_STRING_INITIALIZER
10320 		(struct cmd_config_l2_tunnel_en_dis_result,
10321 		 en_dis, "enable#disable");
10322 
10323 /* enable/disable l2 tunnel for all ports */
10324 static void
10325 cmd_config_l2_tunnel_en_dis_all_parsed(
10326 	void *parsed_result,
10327 	__attribute__((unused)) struct cmdline *cl,
10328 	__attribute__((unused)) void *data)
10329 {
10330 	struct cmd_config_l2_tunnel_en_dis_result *res = parsed_result;
10331 	struct rte_eth_l2_tunnel_conf entry;
10332 	portid_t pid;
10333 	uint8_t en;
10334 
10335 	entry.l2_tunnel_type = str2fdir_l2_tunnel_type(res->l2_tunnel_type);
10336 
10337 	if (!strcmp("enable", res->en_dis))
10338 		en = 1;
10339 	else
10340 		en = 0;
10341 
10342 	FOREACH_PORT(pid, ports) {
10343 		rte_eth_dev_l2_tunnel_offload_set(pid,
10344 						  &entry,
10345 						  ETH_L2_TUNNEL_ENABLE_MASK,
10346 						  en);
10347 	}
10348 }
10349 
10350 cmdline_parse_inst_t cmd_config_l2_tunnel_en_dis_all = {
10351 	.f = cmd_config_l2_tunnel_en_dis_all_parsed,
10352 	.data = NULL,
10353 	.help_str = "port config all l2-tunnel E-tag enable|disable",
10354 	.tokens = {
10355 		(void *)&cmd_config_l2_tunnel_en_dis_port,
10356 		(void *)&cmd_config_l2_tunnel_en_dis_config,
10357 		(void *)&cmd_config_l2_tunnel_en_dis_all_str,
10358 		(void *)&cmd_config_l2_tunnel_en_dis_l2_tunnel,
10359 		(void *)&cmd_config_l2_tunnel_en_dis_l2_tunnel_type,
10360 		(void *)&cmd_config_l2_tunnel_en_dis_en_dis,
10361 		NULL,
10362 	},
10363 };
10364 
10365 /* enable/disable l2 tunnel for a port */
10366 static void
10367 cmd_config_l2_tunnel_en_dis_specific_parsed(
10368 	void *parsed_result,
10369 	__attribute__((unused)) struct cmdline *cl,
10370 	__attribute__((unused)) void *data)
10371 {
10372 	struct cmd_config_l2_tunnel_en_dis_result *res =
10373 		parsed_result;
10374 	struct rte_eth_l2_tunnel_conf entry;
10375 
10376 	if (port_id_is_invalid(res->id, ENABLED_WARN))
10377 		return;
10378 
10379 	entry.l2_tunnel_type = str2fdir_l2_tunnel_type(res->l2_tunnel_type);
10380 
10381 	if (!strcmp("enable", res->en_dis))
10382 		rte_eth_dev_l2_tunnel_offload_set(res->id,
10383 						  &entry,
10384 						  ETH_L2_TUNNEL_ENABLE_MASK,
10385 						  1);
10386 	else
10387 		rte_eth_dev_l2_tunnel_offload_set(res->id,
10388 						  &entry,
10389 						  ETH_L2_TUNNEL_ENABLE_MASK,
10390 						  0);
10391 }
10392 
10393 cmdline_parse_inst_t cmd_config_l2_tunnel_en_dis_specific = {
10394 	.f = cmd_config_l2_tunnel_en_dis_specific_parsed,
10395 	.data = NULL,
10396 	.help_str = "port config <port_id> l2-tunnel E-tag enable|disable",
10397 	.tokens = {
10398 		(void *)&cmd_config_l2_tunnel_en_dis_port,
10399 		(void *)&cmd_config_l2_tunnel_en_dis_config,
10400 		(void *)&cmd_config_l2_tunnel_en_dis_id,
10401 		(void *)&cmd_config_l2_tunnel_en_dis_l2_tunnel,
10402 		(void *)&cmd_config_l2_tunnel_en_dis_l2_tunnel_type,
10403 		(void *)&cmd_config_l2_tunnel_en_dis_en_dis,
10404 		NULL,
10405 	},
10406 };
10407 
10408 /* E-tag configuration */
10409 
10410 /* Common result structure for all E-tag configuration */
10411 struct cmd_config_e_tag_result {
10412 	cmdline_fixed_string_t e_tag;
10413 	cmdline_fixed_string_t set;
10414 	cmdline_fixed_string_t insertion;
10415 	cmdline_fixed_string_t stripping;
10416 	cmdline_fixed_string_t forwarding;
10417 	cmdline_fixed_string_t filter;
10418 	cmdline_fixed_string_t add;
10419 	cmdline_fixed_string_t del;
10420 	cmdline_fixed_string_t on;
10421 	cmdline_fixed_string_t off;
10422 	cmdline_fixed_string_t on_off;
10423 	cmdline_fixed_string_t port_tag_id;
10424 	uint32_t port_tag_id_val;
10425 	cmdline_fixed_string_t e_tag_id;
10426 	uint16_t e_tag_id_val;
10427 	cmdline_fixed_string_t dst_pool;
10428 	uint8_t dst_pool_val;
10429 	cmdline_fixed_string_t port;
10430 	uint8_t port_id;
10431 	cmdline_fixed_string_t vf;
10432 	uint8_t vf_id;
10433 };
10434 
10435 /* Common CLI fields for all E-tag configuration */
10436 cmdline_parse_token_string_t cmd_config_e_tag_e_tag =
10437 	TOKEN_STRING_INITIALIZER
10438 		(struct cmd_config_e_tag_result,
10439 		 e_tag, "E-tag");
10440 cmdline_parse_token_string_t cmd_config_e_tag_set =
10441 	TOKEN_STRING_INITIALIZER
10442 		(struct cmd_config_e_tag_result,
10443 		 set, "set");
10444 cmdline_parse_token_string_t cmd_config_e_tag_insertion =
10445 	TOKEN_STRING_INITIALIZER
10446 		(struct cmd_config_e_tag_result,
10447 		 insertion, "insertion");
10448 cmdline_parse_token_string_t cmd_config_e_tag_stripping =
10449 	TOKEN_STRING_INITIALIZER
10450 		(struct cmd_config_e_tag_result,
10451 		 stripping, "stripping");
10452 cmdline_parse_token_string_t cmd_config_e_tag_forwarding =
10453 	TOKEN_STRING_INITIALIZER
10454 		(struct cmd_config_e_tag_result,
10455 		 forwarding, "forwarding");
10456 cmdline_parse_token_string_t cmd_config_e_tag_filter =
10457 	TOKEN_STRING_INITIALIZER
10458 		(struct cmd_config_e_tag_result,
10459 		 filter, "filter");
10460 cmdline_parse_token_string_t cmd_config_e_tag_add =
10461 	TOKEN_STRING_INITIALIZER
10462 		(struct cmd_config_e_tag_result,
10463 		 add, "add");
10464 cmdline_parse_token_string_t cmd_config_e_tag_del =
10465 	TOKEN_STRING_INITIALIZER
10466 		(struct cmd_config_e_tag_result,
10467 		 del, "del");
10468 cmdline_parse_token_string_t cmd_config_e_tag_on =
10469 	TOKEN_STRING_INITIALIZER
10470 		(struct cmd_config_e_tag_result,
10471 		 on, "on");
10472 cmdline_parse_token_string_t cmd_config_e_tag_off =
10473 	TOKEN_STRING_INITIALIZER
10474 		(struct cmd_config_e_tag_result,
10475 		 off, "off");
10476 cmdline_parse_token_string_t cmd_config_e_tag_on_off =
10477 	TOKEN_STRING_INITIALIZER
10478 		(struct cmd_config_e_tag_result,
10479 		 on_off, "on#off");
10480 cmdline_parse_token_string_t cmd_config_e_tag_port_tag_id =
10481 	TOKEN_STRING_INITIALIZER
10482 		(struct cmd_config_e_tag_result,
10483 		 port_tag_id, "port-tag-id");
10484 cmdline_parse_token_num_t cmd_config_e_tag_port_tag_id_val =
10485 	TOKEN_NUM_INITIALIZER
10486 		(struct cmd_config_e_tag_result,
10487 		 port_tag_id_val, UINT32);
10488 cmdline_parse_token_string_t cmd_config_e_tag_e_tag_id =
10489 	TOKEN_STRING_INITIALIZER
10490 		(struct cmd_config_e_tag_result,
10491 		 e_tag_id, "e-tag-id");
10492 cmdline_parse_token_num_t cmd_config_e_tag_e_tag_id_val =
10493 	TOKEN_NUM_INITIALIZER
10494 		(struct cmd_config_e_tag_result,
10495 		 e_tag_id_val, UINT16);
10496 cmdline_parse_token_string_t cmd_config_e_tag_dst_pool =
10497 	TOKEN_STRING_INITIALIZER
10498 		(struct cmd_config_e_tag_result,
10499 		 dst_pool, "dst-pool");
10500 cmdline_parse_token_num_t cmd_config_e_tag_dst_pool_val =
10501 	TOKEN_NUM_INITIALIZER
10502 		(struct cmd_config_e_tag_result,
10503 		 dst_pool_val, UINT8);
10504 cmdline_parse_token_string_t cmd_config_e_tag_port =
10505 	TOKEN_STRING_INITIALIZER
10506 		(struct cmd_config_e_tag_result,
10507 		 port, "port");
10508 cmdline_parse_token_num_t cmd_config_e_tag_port_id =
10509 	TOKEN_NUM_INITIALIZER
10510 		(struct cmd_config_e_tag_result,
10511 		 port_id, UINT8);
10512 cmdline_parse_token_string_t cmd_config_e_tag_vf =
10513 	TOKEN_STRING_INITIALIZER
10514 		(struct cmd_config_e_tag_result,
10515 		 vf, "vf");
10516 cmdline_parse_token_num_t cmd_config_e_tag_vf_id =
10517 	TOKEN_NUM_INITIALIZER
10518 		(struct cmd_config_e_tag_result,
10519 		 vf_id, UINT8);
10520 
10521 /* E-tag insertion configuration */
10522 static void
10523 cmd_config_e_tag_insertion_en_parsed(
10524 	void *parsed_result,
10525 	__attribute__((unused)) struct cmdline *cl,
10526 	__attribute__((unused)) void *data)
10527 {
10528 	struct cmd_config_e_tag_result *res =
10529 		parsed_result;
10530 	struct rte_eth_l2_tunnel_conf entry;
10531 
10532 	if (port_id_is_invalid(res->port_id, ENABLED_WARN))
10533 		return;
10534 
10535 	entry.l2_tunnel_type = RTE_L2_TUNNEL_TYPE_E_TAG;
10536 	entry.tunnel_id = res->port_tag_id_val;
10537 	entry.vf_id = res->vf_id;
10538 	rte_eth_dev_l2_tunnel_offload_set(res->port_id,
10539 					  &entry,
10540 					  ETH_L2_TUNNEL_INSERTION_MASK,
10541 					  1);
10542 }
10543 
10544 static void
10545 cmd_config_e_tag_insertion_dis_parsed(
10546 	void *parsed_result,
10547 	__attribute__((unused)) struct cmdline *cl,
10548 	__attribute__((unused)) void *data)
10549 {
10550 	struct cmd_config_e_tag_result *res =
10551 		parsed_result;
10552 	struct rte_eth_l2_tunnel_conf entry;
10553 
10554 	if (port_id_is_invalid(res->port_id, ENABLED_WARN))
10555 		return;
10556 
10557 	entry.l2_tunnel_type = RTE_L2_TUNNEL_TYPE_E_TAG;
10558 	entry.vf_id = res->vf_id;
10559 
10560 	rte_eth_dev_l2_tunnel_offload_set(res->port_id,
10561 					  &entry,
10562 					  ETH_L2_TUNNEL_INSERTION_MASK,
10563 					  0);
10564 }
10565 
10566 cmdline_parse_inst_t cmd_config_e_tag_insertion_en = {
10567 	.f = cmd_config_e_tag_insertion_en_parsed,
10568 	.data = NULL,
10569 	.help_str = "E-tag ... : E-tag insertion enable",
10570 	.tokens = {
10571 		(void *)&cmd_config_e_tag_e_tag,
10572 		(void *)&cmd_config_e_tag_set,
10573 		(void *)&cmd_config_e_tag_insertion,
10574 		(void *)&cmd_config_e_tag_on,
10575 		(void *)&cmd_config_e_tag_port_tag_id,
10576 		(void *)&cmd_config_e_tag_port_tag_id_val,
10577 		(void *)&cmd_config_e_tag_port,
10578 		(void *)&cmd_config_e_tag_port_id,
10579 		(void *)&cmd_config_e_tag_vf,
10580 		(void *)&cmd_config_e_tag_vf_id,
10581 		NULL,
10582 	},
10583 };
10584 
10585 cmdline_parse_inst_t cmd_config_e_tag_insertion_dis = {
10586 	.f = cmd_config_e_tag_insertion_dis_parsed,
10587 	.data = NULL,
10588 	.help_str = "E-tag ... : E-tag insertion disable",
10589 	.tokens = {
10590 		(void *)&cmd_config_e_tag_e_tag,
10591 		(void *)&cmd_config_e_tag_set,
10592 		(void *)&cmd_config_e_tag_insertion,
10593 		(void *)&cmd_config_e_tag_off,
10594 		(void *)&cmd_config_e_tag_port,
10595 		(void *)&cmd_config_e_tag_port_id,
10596 		(void *)&cmd_config_e_tag_vf,
10597 		(void *)&cmd_config_e_tag_vf_id,
10598 		NULL,
10599 	},
10600 };
10601 
10602 /* E-tag stripping configuration */
10603 static void
10604 cmd_config_e_tag_stripping_parsed(
10605 	void *parsed_result,
10606 	__attribute__((unused)) struct cmdline *cl,
10607 	__attribute__((unused)) void *data)
10608 {
10609 	struct cmd_config_e_tag_result *res =
10610 		parsed_result;
10611 	struct rte_eth_l2_tunnel_conf entry;
10612 
10613 	if (port_id_is_invalid(res->port_id, ENABLED_WARN))
10614 		return;
10615 
10616 	entry.l2_tunnel_type = RTE_L2_TUNNEL_TYPE_E_TAG;
10617 
10618 	if (!strcmp(res->on_off, "on"))
10619 		rte_eth_dev_l2_tunnel_offload_set
10620 			(res->port_id,
10621 			 &entry,
10622 			 ETH_L2_TUNNEL_STRIPPING_MASK,
10623 			 1);
10624 	else
10625 		rte_eth_dev_l2_tunnel_offload_set
10626 			(res->port_id,
10627 			 &entry,
10628 			 ETH_L2_TUNNEL_STRIPPING_MASK,
10629 			 0);
10630 }
10631 
10632 cmdline_parse_inst_t cmd_config_e_tag_stripping_en_dis = {
10633 	.f = cmd_config_e_tag_stripping_parsed,
10634 	.data = NULL,
10635 	.help_str = "E-tag ... : E-tag stripping enable/disable",
10636 	.tokens = {
10637 		(void *)&cmd_config_e_tag_e_tag,
10638 		(void *)&cmd_config_e_tag_set,
10639 		(void *)&cmd_config_e_tag_stripping,
10640 		(void *)&cmd_config_e_tag_on_off,
10641 		(void *)&cmd_config_e_tag_port,
10642 		(void *)&cmd_config_e_tag_port_id,
10643 		NULL,
10644 	},
10645 };
10646 
10647 /* E-tag forwarding configuration */
10648 static void
10649 cmd_config_e_tag_forwarding_parsed(
10650 	void *parsed_result,
10651 	__attribute__((unused)) struct cmdline *cl,
10652 	__attribute__((unused)) void *data)
10653 {
10654 	struct cmd_config_e_tag_result *res = parsed_result;
10655 	struct rte_eth_l2_tunnel_conf entry;
10656 
10657 	if (port_id_is_invalid(res->port_id, ENABLED_WARN))
10658 		return;
10659 
10660 	entry.l2_tunnel_type = RTE_L2_TUNNEL_TYPE_E_TAG;
10661 
10662 	if (!strcmp(res->on_off, "on"))
10663 		rte_eth_dev_l2_tunnel_offload_set
10664 			(res->port_id,
10665 			 &entry,
10666 			 ETH_L2_TUNNEL_FORWARDING_MASK,
10667 			 1);
10668 	else
10669 		rte_eth_dev_l2_tunnel_offload_set
10670 			(res->port_id,
10671 			 &entry,
10672 			 ETH_L2_TUNNEL_FORWARDING_MASK,
10673 			 0);
10674 }
10675 
10676 cmdline_parse_inst_t cmd_config_e_tag_forwarding_en_dis = {
10677 	.f = cmd_config_e_tag_forwarding_parsed,
10678 	.data = NULL,
10679 	.help_str = "E-tag ... : E-tag forwarding enable/disable",
10680 	.tokens = {
10681 		(void *)&cmd_config_e_tag_e_tag,
10682 		(void *)&cmd_config_e_tag_set,
10683 		(void *)&cmd_config_e_tag_forwarding,
10684 		(void *)&cmd_config_e_tag_on_off,
10685 		(void *)&cmd_config_e_tag_port,
10686 		(void *)&cmd_config_e_tag_port_id,
10687 		NULL,
10688 	},
10689 };
10690 
10691 /* E-tag filter configuration */
10692 static void
10693 cmd_config_e_tag_filter_add_parsed(
10694 	void *parsed_result,
10695 	__attribute__((unused)) struct cmdline *cl,
10696 	__attribute__((unused)) void *data)
10697 {
10698 	struct cmd_config_e_tag_result *res = parsed_result;
10699 	struct rte_eth_l2_tunnel_conf entry;
10700 	int ret = 0;
10701 
10702 	if (port_id_is_invalid(res->port_id, ENABLED_WARN))
10703 		return;
10704 
10705 	if (res->e_tag_id_val > 0x3fff) {
10706 		printf("e-tag-id must be equal or less than 0x3fff.\n");
10707 		return;
10708 	}
10709 
10710 	ret = rte_eth_dev_filter_supported(res->port_id,
10711 					   RTE_ETH_FILTER_L2_TUNNEL);
10712 	if (ret < 0) {
10713 		printf("E-tag filter is not supported on port %u.\n",
10714 		       res->port_id);
10715 		return;
10716 	}
10717 
10718 	entry.l2_tunnel_type = RTE_L2_TUNNEL_TYPE_E_TAG;
10719 	entry.tunnel_id = res->e_tag_id_val;
10720 	entry.pool = res->dst_pool_val;
10721 
10722 	ret = rte_eth_dev_filter_ctrl(res->port_id,
10723 				      RTE_ETH_FILTER_L2_TUNNEL,
10724 				      RTE_ETH_FILTER_ADD,
10725 				      &entry);
10726 	if (ret < 0)
10727 		printf("E-tag filter programming error: (%s)\n",
10728 		       strerror(-ret));
10729 }
10730 
10731 cmdline_parse_inst_t cmd_config_e_tag_filter_add = {
10732 	.f = cmd_config_e_tag_filter_add_parsed,
10733 	.data = NULL,
10734 	.help_str = "E-tag ... : E-tag filter add",
10735 	.tokens = {
10736 		(void *)&cmd_config_e_tag_e_tag,
10737 		(void *)&cmd_config_e_tag_set,
10738 		(void *)&cmd_config_e_tag_filter,
10739 		(void *)&cmd_config_e_tag_add,
10740 		(void *)&cmd_config_e_tag_e_tag_id,
10741 		(void *)&cmd_config_e_tag_e_tag_id_val,
10742 		(void *)&cmd_config_e_tag_dst_pool,
10743 		(void *)&cmd_config_e_tag_dst_pool_val,
10744 		(void *)&cmd_config_e_tag_port,
10745 		(void *)&cmd_config_e_tag_port_id,
10746 		NULL,
10747 	},
10748 };
10749 
10750 static void
10751 cmd_config_e_tag_filter_del_parsed(
10752 	void *parsed_result,
10753 	__attribute__((unused)) struct cmdline *cl,
10754 	__attribute__((unused)) void *data)
10755 {
10756 	struct cmd_config_e_tag_result *res = parsed_result;
10757 	struct rte_eth_l2_tunnel_conf entry;
10758 	int ret = 0;
10759 
10760 	if (port_id_is_invalid(res->port_id, ENABLED_WARN))
10761 		return;
10762 
10763 	if (res->e_tag_id_val > 0x3fff) {
10764 		printf("e-tag-id must be less than 0x3fff.\n");
10765 		return;
10766 	}
10767 
10768 	ret = rte_eth_dev_filter_supported(res->port_id,
10769 					   RTE_ETH_FILTER_L2_TUNNEL);
10770 	if (ret < 0) {
10771 		printf("E-tag filter is not supported on port %u.\n",
10772 		       res->port_id);
10773 		return;
10774 	}
10775 
10776 	entry.l2_tunnel_type = RTE_L2_TUNNEL_TYPE_E_TAG;
10777 	entry.tunnel_id = res->e_tag_id_val;
10778 
10779 	ret = rte_eth_dev_filter_ctrl(res->port_id,
10780 				      RTE_ETH_FILTER_L2_TUNNEL,
10781 				      RTE_ETH_FILTER_DELETE,
10782 				      &entry);
10783 	if (ret < 0)
10784 		printf("E-tag filter programming error: (%s)\n",
10785 		       strerror(-ret));
10786 }
10787 
10788 cmdline_parse_inst_t cmd_config_e_tag_filter_del = {
10789 	.f = cmd_config_e_tag_filter_del_parsed,
10790 	.data = NULL,
10791 	.help_str = "E-tag ... : E-tag filter delete",
10792 	.tokens = {
10793 		(void *)&cmd_config_e_tag_e_tag,
10794 		(void *)&cmd_config_e_tag_set,
10795 		(void *)&cmd_config_e_tag_filter,
10796 		(void *)&cmd_config_e_tag_del,
10797 		(void *)&cmd_config_e_tag_e_tag_id,
10798 		(void *)&cmd_config_e_tag_e_tag_id_val,
10799 		(void *)&cmd_config_e_tag_port,
10800 		(void *)&cmd_config_e_tag_port_id,
10801 		NULL,
10802 	},
10803 };
10804 #ifdef RTE_LIBRTE_IXGBE_PMD
10805 
10806 /* vf vlan anti spoof configuration */
10807 
10808 /* Common result structure for vf vlan anti spoof */
10809 struct cmd_vf_vlan_anti_spoof_result {
10810 	cmdline_fixed_string_t set;
10811 	cmdline_fixed_string_t vf;
10812 	cmdline_fixed_string_t vlan;
10813 	cmdline_fixed_string_t antispoof;
10814 	uint8_t port_id;
10815 	uint32_t vf_id;
10816 	cmdline_fixed_string_t on_off;
10817 };
10818 
10819 /* Common CLI fields for vf vlan anti spoof enable disable */
10820 cmdline_parse_token_string_t cmd_vf_vlan_anti_spoof_set =
10821 	TOKEN_STRING_INITIALIZER
10822 		(struct cmd_vf_vlan_anti_spoof_result,
10823 		 set, "set");
10824 cmdline_parse_token_string_t cmd_vf_vlan_anti_spoof_vf =
10825 	TOKEN_STRING_INITIALIZER
10826 		(struct cmd_vf_vlan_anti_spoof_result,
10827 		 vf, "vf");
10828 cmdline_parse_token_string_t cmd_vf_vlan_anti_spoof_vlan =
10829 	TOKEN_STRING_INITIALIZER
10830 		(struct cmd_vf_vlan_anti_spoof_result,
10831 		 vlan, "vlan");
10832 cmdline_parse_token_string_t cmd_vf_vlan_anti_spoof_antispoof =
10833 	TOKEN_STRING_INITIALIZER
10834 		(struct cmd_vf_vlan_anti_spoof_result,
10835 		 antispoof, "antispoof");
10836 cmdline_parse_token_num_t cmd_vf_vlan_anti_spoof_port_id =
10837 	TOKEN_NUM_INITIALIZER
10838 		(struct cmd_vf_vlan_anti_spoof_result,
10839 		 port_id, UINT8);
10840 cmdline_parse_token_num_t cmd_vf_vlan_anti_spoof_vf_id =
10841 	TOKEN_NUM_INITIALIZER
10842 		(struct cmd_vf_vlan_anti_spoof_result,
10843 		 vf_id, UINT32);
10844 cmdline_parse_token_string_t cmd_vf_vlan_anti_spoof_on_off =
10845 	TOKEN_STRING_INITIALIZER
10846 		(struct cmd_vf_vlan_anti_spoof_result,
10847 		 on_off, "on#off");
10848 
10849 static void
10850 cmd_set_vf_vlan_anti_spoof_parsed(
10851 	void *parsed_result,
10852 	__attribute__((unused)) struct cmdline *cl,
10853 	__attribute__((unused)) void *data)
10854 {
10855 	struct cmd_vf_vlan_anti_spoof_result *res = parsed_result;
10856 	int ret = 0;
10857 	int is_on = (strcmp(res->on_off, "on") == 0) ? 1 : 0;
10858 
10859 	ret = rte_pmd_ixgbe_set_vf_vlan_anti_spoof(res->port_id, res->vf_id,
10860 			is_on);
10861 	switch (ret) {
10862 	case 0:
10863 		break;
10864 	case -EINVAL:
10865 		printf("invalid vf_id %d\n", res->vf_id);
10866 		break;
10867 	case -ENODEV:
10868 		printf("invalid port_id %d\n", res->port_id);
10869 		break;
10870 	default:
10871 		printf("programming error: (%s)\n", strerror(-ret));
10872 	}
10873 }
10874 
10875 cmdline_parse_inst_t cmd_set_vf_vlan_anti_spoof = {
10876 	.f = cmd_set_vf_vlan_anti_spoof_parsed,
10877 	.data = NULL,
10878 	.help_str = "set vf vlan antispoof <port_id> <vf_id> on|off",
10879 	.tokens = {
10880 		(void *)&cmd_vf_vlan_anti_spoof_set,
10881 		(void *)&cmd_vf_vlan_anti_spoof_vf,
10882 		(void *)&cmd_vf_vlan_anti_spoof_vlan,
10883 		(void *)&cmd_vf_vlan_anti_spoof_antispoof,
10884 		(void *)&cmd_vf_vlan_anti_spoof_port_id,
10885 		(void *)&cmd_vf_vlan_anti_spoof_vf_id,
10886 		(void *)&cmd_vf_vlan_anti_spoof_on_off,
10887 		NULL,
10888 	},
10889 };
10890 
10891 /* vf mac anti spoof configuration */
10892 
10893 /* Common result structure for vf mac anti spoof */
10894 struct cmd_vf_mac_anti_spoof_result {
10895 	cmdline_fixed_string_t set;
10896 	cmdline_fixed_string_t vf;
10897 	cmdline_fixed_string_t mac;
10898 	cmdline_fixed_string_t antispoof;
10899 	uint8_t port_id;
10900 	uint32_t vf_id;
10901 	cmdline_fixed_string_t on_off;
10902 };
10903 
10904 /* Common CLI fields for vf mac anti spoof enable disable */
10905 cmdline_parse_token_string_t cmd_vf_mac_anti_spoof_set =
10906 	TOKEN_STRING_INITIALIZER
10907 		(struct cmd_vf_mac_anti_spoof_result,
10908 		 set, "set");
10909 cmdline_parse_token_string_t cmd_vf_mac_anti_spoof_vf =
10910 	TOKEN_STRING_INITIALIZER
10911 		(struct cmd_vf_mac_anti_spoof_result,
10912 		 vf, "vf");
10913 cmdline_parse_token_string_t cmd_vf_mac_anti_spoof_mac =
10914 	TOKEN_STRING_INITIALIZER
10915 		(struct cmd_vf_mac_anti_spoof_result,
10916 		 mac, "mac");
10917 cmdline_parse_token_string_t cmd_vf_mac_anti_spoof_antispoof =
10918 	TOKEN_STRING_INITIALIZER
10919 		(struct cmd_vf_mac_anti_spoof_result,
10920 		 antispoof, "antispoof");
10921 cmdline_parse_token_num_t cmd_vf_mac_anti_spoof_port_id =
10922 	TOKEN_NUM_INITIALIZER
10923 		(struct cmd_vf_mac_anti_spoof_result,
10924 		 port_id, UINT8);
10925 cmdline_parse_token_num_t cmd_vf_mac_anti_spoof_vf_id =
10926 	TOKEN_NUM_INITIALIZER
10927 		(struct cmd_vf_mac_anti_spoof_result,
10928 		 vf_id, UINT32);
10929 cmdline_parse_token_string_t cmd_vf_mac_anti_spoof_on_off =
10930 	TOKEN_STRING_INITIALIZER
10931 		(struct cmd_vf_mac_anti_spoof_result,
10932 		 on_off, "on#off");
10933 
10934 static void
10935 cmd_set_vf_mac_anti_spoof_parsed(
10936 	void *parsed_result,
10937 	__attribute__((unused)) struct cmdline *cl,
10938 	__attribute__((unused)) void *data)
10939 {
10940 	struct cmd_vf_mac_anti_spoof_result *res = parsed_result;
10941 	int ret;
10942 	int is_on = (strcmp(res->on_off, "on") == 0) ? 1 : 0;
10943 
10944 	ret = rte_pmd_ixgbe_set_vf_mac_anti_spoof(res->port_id, res->vf_id,
10945 			is_on);
10946 	switch (ret) {
10947 	case 0:
10948 		break;
10949 	case -EINVAL:
10950 		printf("invalid vf_id %d or is_on %d\n", res->vf_id, is_on);
10951 		break;
10952 	case -ENODEV:
10953 		printf("invalid port_id %d\n", res->port_id);
10954 		break;
10955 	default:
10956 		printf("programming error: (%s)\n", strerror(-ret));
10957 	}
10958 }
10959 
10960 cmdline_parse_inst_t cmd_set_vf_mac_anti_spoof = {
10961 	.f = cmd_set_vf_mac_anti_spoof_parsed,
10962 	.data = NULL,
10963 	.help_str = "set vf mac antispoof <port_id> <vf_id> on|off",
10964 	.tokens = {
10965 		(void *)&cmd_vf_mac_anti_spoof_set,
10966 		(void *)&cmd_vf_mac_anti_spoof_vf,
10967 		(void *)&cmd_vf_mac_anti_spoof_mac,
10968 		(void *)&cmd_vf_mac_anti_spoof_antispoof,
10969 		(void *)&cmd_vf_mac_anti_spoof_port_id,
10970 		(void *)&cmd_vf_mac_anti_spoof_vf_id,
10971 		(void *)&cmd_vf_mac_anti_spoof_on_off,
10972 		NULL,
10973 	},
10974 };
10975 
10976 /* vf vlan strip queue configuration */
10977 
10978 /* Common result structure for vf mac anti spoof */
10979 struct cmd_vf_vlan_stripq_result {
10980 	cmdline_fixed_string_t set;
10981 	cmdline_fixed_string_t vf;
10982 	cmdline_fixed_string_t vlan;
10983 	cmdline_fixed_string_t stripq;
10984 	uint8_t port_id;
10985 	uint16_t vf_id;
10986 	cmdline_fixed_string_t on_off;
10987 };
10988 
10989 /* Common CLI fields for vf vlan strip enable disable */
10990 cmdline_parse_token_string_t cmd_vf_vlan_stripq_set =
10991 	TOKEN_STRING_INITIALIZER
10992 		(struct cmd_vf_vlan_stripq_result,
10993 		 set, "set");
10994 cmdline_parse_token_string_t cmd_vf_vlan_stripq_vf =
10995 	TOKEN_STRING_INITIALIZER
10996 		(struct cmd_vf_vlan_stripq_result,
10997 		 vf, "vf");
10998 cmdline_parse_token_string_t cmd_vf_vlan_stripq_vlan =
10999 	TOKEN_STRING_INITIALIZER
11000 		(struct cmd_vf_vlan_stripq_result,
11001 		 vlan, "vlan");
11002 cmdline_parse_token_string_t cmd_vf_vlan_stripq_stripq =
11003 	TOKEN_STRING_INITIALIZER
11004 		(struct cmd_vf_vlan_stripq_result,
11005 		 stripq, "stripq");
11006 cmdline_parse_token_num_t cmd_vf_vlan_stripq_port_id =
11007 	TOKEN_NUM_INITIALIZER
11008 		(struct cmd_vf_vlan_stripq_result,
11009 		 port_id, UINT8);
11010 cmdline_parse_token_num_t cmd_vf_vlan_stripq_vf_id =
11011 	TOKEN_NUM_INITIALIZER
11012 		(struct cmd_vf_vlan_stripq_result,
11013 		 vf_id, UINT16);
11014 cmdline_parse_token_string_t cmd_vf_vlan_stripq_on_off =
11015 	TOKEN_STRING_INITIALIZER
11016 		(struct cmd_vf_vlan_stripq_result,
11017 		 on_off, "on#off");
11018 
11019 static void
11020 cmd_set_vf_vlan_stripq_parsed(
11021 	void *parsed_result,
11022 	__attribute__((unused)) struct cmdline *cl,
11023 	__attribute__((unused)) void *data)
11024 {
11025 	struct cmd_vf_vlan_stripq_result *res = parsed_result;
11026 	int ret = 0;
11027 	int is_on = (strcmp(res->on_off, "on") == 0) ? 1 : 0;
11028 
11029 	ret = rte_pmd_ixgbe_set_vf_vlan_stripq(res->port_id, res->vf_id, is_on);
11030 	switch (ret) {
11031 	case 0:
11032 		break;
11033 	case -EINVAL:
11034 		printf("invalid vf_id %d or is_on %d\n", res->vf_id, is_on);
11035 		break;
11036 	case -ENODEV:
11037 		printf("invalid port_id %d\n", res->port_id);
11038 		break;
11039 	default:
11040 		printf("programming error: (%s)\n", strerror(-ret));
11041 	}
11042 }
11043 
11044 cmdline_parse_inst_t cmd_set_vf_vlan_stripq = {
11045 	.f = cmd_set_vf_vlan_stripq_parsed,
11046 	.data = NULL,
11047 	.help_str = "set vf vlan stripq <port_id> <vf_id> on|off",
11048 	.tokens = {
11049 		(void *)&cmd_vf_vlan_stripq_set,
11050 		(void *)&cmd_vf_vlan_stripq_vf,
11051 		(void *)&cmd_vf_vlan_stripq_vlan,
11052 		(void *)&cmd_vf_vlan_stripq_stripq,
11053 		(void *)&cmd_vf_vlan_stripq_port_id,
11054 		(void *)&cmd_vf_vlan_stripq_vf_id,
11055 		(void *)&cmd_vf_vlan_stripq_on_off,
11056 		NULL,
11057 	},
11058 };
11059 
11060 /* vf vlan insert configuration */
11061 
11062 /* Common result structure for vf vlan insert */
11063 struct cmd_vf_vlan_insert_result {
11064 	cmdline_fixed_string_t set;
11065 	cmdline_fixed_string_t vf;
11066 	cmdline_fixed_string_t vlan;
11067 	cmdline_fixed_string_t insert;
11068 	uint8_t port_id;
11069 	uint16_t vf_id;
11070 	uint16_t vlan_id;
11071 };
11072 
11073 /* Common CLI fields for vf vlan insert enable disable */
11074 cmdline_parse_token_string_t cmd_vf_vlan_insert_set =
11075 	TOKEN_STRING_INITIALIZER
11076 		(struct cmd_vf_vlan_insert_result,
11077 		 set, "set");
11078 cmdline_parse_token_string_t cmd_vf_vlan_insert_vf =
11079 	TOKEN_STRING_INITIALIZER
11080 		(struct cmd_vf_vlan_insert_result,
11081 		 vf, "vf");
11082 cmdline_parse_token_string_t cmd_vf_vlan_insert_vlan =
11083 	TOKEN_STRING_INITIALIZER
11084 		(struct cmd_vf_vlan_insert_result,
11085 		 vlan, "vlan");
11086 cmdline_parse_token_string_t cmd_vf_vlan_insert_insert =
11087 	TOKEN_STRING_INITIALIZER
11088 		(struct cmd_vf_vlan_insert_result,
11089 		 insert, "insert");
11090 cmdline_parse_token_num_t cmd_vf_vlan_insert_port_id =
11091 	TOKEN_NUM_INITIALIZER
11092 		(struct cmd_vf_vlan_insert_result,
11093 		 port_id, UINT8);
11094 cmdline_parse_token_num_t cmd_vf_vlan_insert_vf_id =
11095 	TOKEN_NUM_INITIALIZER
11096 		(struct cmd_vf_vlan_insert_result,
11097 		 vf_id, UINT16);
11098 cmdline_parse_token_num_t cmd_vf_vlan_insert_vlan_id =
11099 	TOKEN_NUM_INITIALIZER
11100 		(struct cmd_vf_vlan_insert_result,
11101 		 vlan_id, UINT16);
11102 
11103 static void
11104 cmd_set_vf_vlan_insert_parsed(
11105 	void *parsed_result,
11106 	__attribute__((unused)) struct cmdline *cl,
11107 	__attribute__((unused)) void *data)
11108 {
11109 	struct cmd_vf_vlan_insert_result *res = parsed_result;
11110 	int ret;
11111 
11112 	ret = rte_pmd_ixgbe_set_vf_vlan_insert(res->port_id, res->vf_id, res->vlan_id);
11113 	switch (ret) {
11114 	case 0:
11115 		break;
11116 	case -EINVAL:
11117 		printf("invalid vf_id %d or vlan_id %d\n", res->vf_id, res->vlan_id);
11118 		break;
11119 	case -ENODEV:
11120 		printf("invalid port_id %d\n", res->port_id);
11121 		break;
11122 	default:
11123 		printf("programming error: (%s)\n", strerror(-ret));
11124 	}
11125 }
11126 
11127 cmdline_parse_inst_t cmd_set_vf_vlan_insert = {
11128 	.f = cmd_set_vf_vlan_insert_parsed,
11129 	.data = NULL,
11130 	.help_str = "set vf vlan insert <port_id> <vf_id> <vlan_id>",
11131 	.tokens = {
11132 		(void *)&cmd_vf_vlan_insert_set,
11133 		(void *)&cmd_vf_vlan_insert_vf,
11134 		(void *)&cmd_vf_vlan_insert_vlan,
11135 		(void *)&cmd_vf_vlan_insert_insert,
11136 		(void *)&cmd_vf_vlan_insert_port_id,
11137 		(void *)&cmd_vf_vlan_insert_vf_id,
11138 		(void *)&cmd_vf_vlan_insert_vlan_id,
11139 		NULL,
11140 	},
11141 };
11142 
11143 /* tx loopback configuration */
11144 
11145 /* Common result structure for tx loopback */
11146 struct cmd_tx_loopback_result {
11147 	cmdline_fixed_string_t set;
11148 	cmdline_fixed_string_t tx;
11149 	cmdline_fixed_string_t loopback;
11150 	uint8_t port_id;
11151 	cmdline_fixed_string_t on_off;
11152 };
11153 
11154 /* Common CLI fields for tx loopback enable disable */
11155 cmdline_parse_token_string_t cmd_tx_loopback_set =
11156 	TOKEN_STRING_INITIALIZER
11157 		(struct cmd_tx_loopback_result,
11158 		 set, "set");
11159 cmdline_parse_token_string_t cmd_tx_loopback_tx =
11160 	TOKEN_STRING_INITIALIZER
11161 		(struct cmd_tx_loopback_result,
11162 		 tx, "tx");
11163 cmdline_parse_token_string_t cmd_tx_loopback_loopback =
11164 	TOKEN_STRING_INITIALIZER
11165 		(struct cmd_tx_loopback_result,
11166 		 loopback, "loopback");
11167 cmdline_parse_token_num_t cmd_tx_loopback_port_id =
11168 	TOKEN_NUM_INITIALIZER
11169 		(struct cmd_tx_loopback_result,
11170 		 port_id, UINT8);
11171 cmdline_parse_token_string_t cmd_tx_loopback_on_off =
11172 	TOKEN_STRING_INITIALIZER
11173 		(struct cmd_tx_loopback_result,
11174 		 on_off, "on#off");
11175 
11176 static void
11177 cmd_set_tx_loopback_parsed(
11178 	void *parsed_result,
11179 	__attribute__((unused)) struct cmdline *cl,
11180 	__attribute__((unused)) void *data)
11181 {
11182 	struct cmd_tx_loopback_result *res = parsed_result;
11183 	int ret;
11184 	int is_on = (strcmp(res->on_off, "on") == 0) ? 1 : 0;
11185 
11186 	ret = rte_pmd_ixgbe_set_tx_loopback(res->port_id, is_on);
11187 	switch (ret) {
11188 	case 0:
11189 		break;
11190 	case -EINVAL:
11191 		printf("invalid is_on %d\n", is_on);
11192 		break;
11193 	case -ENODEV:
11194 		printf("invalid port_id %d\n", res->port_id);
11195 		break;
11196 	default:
11197 		printf("programming error: (%s)\n", strerror(-ret));
11198 	}
11199 }
11200 
11201 cmdline_parse_inst_t cmd_set_tx_loopback = {
11202 	.f = cmd_set_tx_loopback_parsed,
11203 	.data = NULL,
11204 	.help_str = "set tx loopback <port_id> on|off",
11205 	.tokens = {
11206 		(void *)&cmd_tx_loopback_set,
11207 		(void *)&cmd_tx_loopback_tx,
11208 		(void *)&cmd_tx_loopback_loopback,
11209 		(void *)&cmd_tx_loopback_port_id,
11210 		(void *)&cmd_tx_loopback_on_off,
11211 		NULL,
11212 	},
11213 };
11214 
11215 /* all queues drop enable configuration */
11216 
11217 /* Common result structure for all queues drop enable */
11218 struct cmd_all_queues_drop_en_result {
11219 	cmdline_fixed_string_t set;
11220 	cmdline_fixed_string_t all;
11221 	cmdline_fixed_string_t queues;
11222 	cmdline_fixed_string_t drop;
11223 	uint8_t port_id;
11224 	cmdline_fixed_string_t on_off;
11225 };
11226 
11227 /* Common CLI fields for tx loopback enable disable */
11228 cmdline_parse_token_string_t cmd_all_queues_drop_en_set =
11229 	TOKEN_STRING_INITIALIZER
11230 		(struct cmd_all_queues_drop_en_result,
11231 		 set, "set");
11232 cmdline_parse_token_string_t cmd_all_queues_drop_en_all =
11233 	TOKEN_STRING_INITIALIZER
11234 		(struct cmd_all_queues_drop_en_result,
11235 		 all, "all");
11236 cmdline_parse_token_string_t cmd_all_queues_drop_en_queues =
11237 	TOKEN_STRING_INITIALIZER
11238 		(struct cmd_all_queues_drop_en_result,
11239 		 queues, "queues");
11240 cmdline_parse_token_string_t cmd_all_queues_drop_en_drop =
11241 	TOKEN_STRING_INITIALIZER
11242 		(struct cmd_all_queues_drop_en_result,
11243 		 drop, "drop");
11244 cmdline_parse_token_num_t cmd_all_queues_drop_en_port_id =
11245 	TOKEN_NUM_INITIALIZER
11246 		(struct cmd_all_queues_drop_en_result,
11247 		 port_id, UINT8);
11248 cmdline_parse_token_string_t cmd_all_queues_drop_en_on_off =
11249 	TOKEN_STRING_INITIALIZER
11250 		(struct cmd_all_queues_drop_en_result,
11251 		 on_off, "on#off");
11252 
11253 static void
11254 cmd_set_all_queues_drop_en_parsed(
11255 	void *parsed_result,
11256 	__attribute__((unused)) struct cmdline *cl,
11257 	__attribute__((unused)) void *data)
11258 {
11259 	struct cmd_all_queues_drop_en_result *res = parsed_result;
11260 	int ret = 0;
11261 	int is_on = (strcmp(res->on_off, "on") == 0) ? 1 : 0;
11262 
11263 	ret = rte_pmd_ixgbe_set_all_queues_drop_en(res->port_id, is_on);
11264 	switch (ret) {
11265 	case 0:
11266 		break;
11267 	case -EINVAL:
11268 		printf("invalid is_on %d\n", is_on);
11269 		break;
11270 	case -ENODEV:
11271 		printf("invalid port_id %d\n", res->port_id);
11272 		break;
11273 	default:
11274 		printf("programming error: (%s)\n", strerror(-ret));
11275 	}
11276 }
11277 
11278 cmdline_parse_inst_t cmd_set_all_queues_drop_en = {
11279 	.f = cmd_set_all_queues_drop_en_parsed,
11280 	.data = NULL,
11281 	.help_str = "set all queues drop <port_id> on|off",
11282 	.tokens = {
11283 		(void *)&cmd_all_queues_drop_en_set,
11284 		(void *)&cmd_all_queues_drop_en_all,
11285 		(void *)&cmd_all_queues_drop_en_queues,
11286 		(void *)&cmd_all_queues_drop_en_drop,
11287 		(void *)&cmd_all_queues_drop_en_port_id,
11288 		(void *)&cmd_all_queues_drop_en_on_off,
11289 		NULL,
11290 	},
11291 };
11292 
11293 /* vf split drop enable configuration */
11294 
11295 /* Common result structure for vf split drop enable */
11296 struct cmd_vf_split_drop_en_result {
11297 	cmdline_fixed_string_t set;
11298 	cmdline_fixed_string_t vf;
11299 	cmdline_fixed_string_t split;
11300 	cmdline_fixed_string_t drop;
11301 	uint8_t port_id;
11302 	uint16_t vf_id;
11303 	cmdline_fixed_string_t on_off;
11304 };
11305 
11306 /* Common CLI fields for vf split drop enable disable */
11307 cmdline_parse_token_string_t cmd_vf_split_drop_en_set =
11308 	TOKEN_STRING_INITIALIZER
11309 		(struct cmd_vf_split_drop_en_result,
11310 		 set, "set");
11311 cmdline_parse_token_string_t cmd_vf_split_drop_en_vf =
11312 	TOKEN_STRING_INITIALIZER
11313 		(struct cmd_vf_split_drop_en_result,
11314 		 vf, "vf");
11315 cmdline_parse_token_string_t cmd_vf_split_drop_en_split =
11316 	TOKEN_STRING_INITIALIZER
11317 		(struct cmd_vf_split_drop_en_result,
11318 		 split, "split");
11319 cmdline_parse_token_string_t cmd_vf_split_drop_en_drop =
11320 	TOKEN_STRING_INITIALIZER
11321 		(struct cmd_vf_split_drop_en_result,
11322 		 drop, "drop");
11323 cmdline_parse_token_num_t cmd_vf_split_drop_en_port_id =
11324 	TOKEN_NUM_INITIALIZER
11325 		(struct cmd_vf_split_drop_en_result,
11326 		 port_id, UINT8);
11327 cmdline_parse_token_num_t cmd_vf_split_drop_en_vf_id =
11328 	TOKEN_NUM_INITIALIZER
11329 		(struct cmd_vf_split_drop_en_result,
11330 		 vf_id, UINT16);
11331 cmdline_parse_token_string_t cmd_vf_split_drop_en_on_off =
11332 	TOKEN_STRING_INITIALIZER
11333 		(struct cmd_vf_split_drop_en_result,
11334 		 on_off, "on#off");
11335 
11336 static void
11337 cmd_set_vf_split_drop_en_parsed(
11338 	void *parsed_result,
11339 	__attribute__((unused)) struct cmdline *cl,
11340 	__attribute__((unused)) void *data)
11341 {
11342 	struct cmd_vf_split_drop_en_result *res = parsed_result;
11343 	int ret;
11344 	int is_on = (strcmp(res->on_off, "on") == 0) ? 1 : 0;
11345 
11346 	ret = rte_pmd_ixgbe_set_vf_split_drop_en(res->port_id, res->vf_id,
11347 			is_on);
11348 	switch (ret) {
11349 	case 0:
11350 		break;
11351 	case -EINVAL:
11352 		printf("invalid vf_id %d or is_on %d\n", res->vf_id, is_on);
11353 		break;
11354 	case -ENODEV:
11355 		printf("invalid port_id %d\n", res->port_id);
11356 		break;
11357 	default:
11358 		printf("programming error: (%s)\n", strerror(-ret));
11359 	}
11360 }
11361 
11362 cmdline_parse_inst_t cmd_set_vf_split_drop_en = {
11363 	.f = cmd_set_vf_split_drop_en_parsed,
11364 	.data = NULL,
11365 	.help_str = "set vf split drop <port_id> <vf_id> on|off",
11366 	.tokens = {
11367 		(void *)&cmd_vf_split_drop_en_set,
11368 		(void *)&cmd_vf_split_drop_en_vf,
11369 		(void *)&cmd_vf_split_drop_en_split,
11370 		(void *)&cmd_vf_split_drop_en_drop,
11371 		(void *)&cmd_vf_split_drop_en_port_id,
11372 		(void *)&cmd_vf_split_drop_en_vf_id,
11373 		(void *)&cmd_vf_split_drop_en_on_off,
11374 		NULL,
11375 	},
11376 };
11377 
11378 /* vf mac address configuration */
11379 
11380 /* Common result structure for vf mac address */
11381 struct cmd_set_vf_mac_addr_result {
11382 	cmdline_fixed_string_t set;
11383 	cmdline_fixed_string_t vf;
11384 	cmdline_fixed_string_t mac;
11385 	cmdline_fixed_string_t addr;
11386 	uint8_t port_id;
11387 	uint16_t vf_id;
11388 	struct ether_addr mac_addr;
11389 
11390 };
11391 
11392 /* Common CLI fields for vf split drop enable disable */
11393 cmdline_parse_token_string_t cmd_set_vf_mac_addr_set =
11394 	TOKEN_STRING_INITIALIZER
11395 		(struct cmd_set_vf_mac_addr_result,
11396 		 set, "set");
11397 cmdline_parse_token_string_t cmd_set_vf_mac_addr_vf =
11398 	TOKEN_STRING_INITIALIZER
11399 		(struct cmd_set_vf_mac_addr_result,
11400 		 vf, "vf");
11401 cmdline_parse_token_string_t cmd_set_vf_mac_addr_mac =
11402 	TOKEN_STRING_INITIALIZER
11403 		(struct cmd_set_vf_mac_addr_result,
11404 		 mac, "mac");
11405 cmdline_parse_token_string_t cmd_set_vf_mac_addr_addr =
11406 	TOKEN_STRING_INITIALIZER
11407 		(struct cmd_set_vf_mac_addr_result,
11408 		 addr, "addr");
11409 cmdline_parse_token_num_t cmd_set_vf_mac_addr_port_id =
11410 	TOKEN_NUM_INITIALIZER
11411 		(struct cmd_set_vf_mac_addr_result,
11412 		 port_id, UINT8);
11413 cmdline_parse_token_num_t cmd_set_vf_mac_addr_vf_id =
11414 	TOKEN_NUM_INITIALIZER
11415 		(struct cmd_set_vf_mac_addr_result,
11416 		 vf_id, UINT16);
11417 cmdline_parse_token_etheraddr_t cmd_set_vf_mac_addr_mac_addr =
11418 	TOKEN_ETHERADDR_INITIALIZER(struct cmd_set_vf_mac_addr_result,
11419 		 mac_addr);
11420 
11421 static void
11422 cmd_set_vf_mac_addr_parsed(
11423 	void *parsed_result,
11424 	__attribute__((unused)) struct cmdline *cl,
11425 	__attribute__((unused)) void *data)
11426 {
11427 	struct cmd_set_vf_mac_addr_result *res = parsed_result;
11428 	int ret;
11429 
11430 	ret = rte_pmd_ixgbe_set_vf_mac_addr(res->port_id, res->vf_id,
11431 			&res->mac_addr);
11432 	switch (ret) {
11433 	case 0:
11434 		break;
11435 	case -EINVAL:
11436 		printf("invalid vf_id %d or mac_addr\n", res->vf_id);
11437 		break;
11438 	case -ENODEV:
11439 		printf("invalid port_id %d\n", res->port_id);
11440 		break;
11441 	default:
11442 		printf("programming error: (%s)\n", strerror(-ret));
11443 	}
11444 }
11445 
11446 cmdline_parse_inst_t cmd_set_vf_mac_addr = {
11447 	.f = cmd_set_vf_mac_addr_parsed,
11448 	.data = NULL,
11449 	.help_str = "set vf mac addr <port_id> <vf_id> <mac_addr>",
11450 	.tokens = {
11451 		(void *)&cmd_set_vf_mac_addr_set,
11452 		(void *)&cmd_set_vf_mac_addr_vf,
11453 		(void *)&cmd_set_vf_mac_addr_mac,
11454 		(void *)&cmd_set_vf_mac_addr_addr,
11455 		(void *)&cmd_set_vf_mac_addr_port_id,
11456 		(void *)&cmd_set_vf_mac_addr_vf_id,
11457 		(void *)&cmd_set_vf_mac_addr_mac_addr,
11458 		NULL,
11459 	},
11460 };
11461 #endif
11462 
11463 /* ******************************************************************************** */
11464 
11465 /* list of instructions */
11466 cmdline_parse_ctx_t main_ctx[] = {
11467 	(cmdline_parse_inst_t *)&cmd_help_brief,
11468 	(cmdline_parse_inst_t *)&cmd_help_long,
11469 	(cmdline_parse_inst_t *)&cmd_quit,
11470 	(cmdline_parse_inst_t *)&cmd_showport,
11471 	(cmdline_parse_inst_t *)&cmd_showqueue,
11472 	(cmdline_parse_inst_t *)&cmd_showportall,
11473 	(cmdline_parse_inst_t *)&cmd_showcfg,
11474 	(cmdline_parse_inst_t *)&cmd_start,
11475 	(cmdline_parse_inst_t *)&cmd_start_tx_first,
11476 	(cmdline_parse_inst_t *)&cmd_start_tx_first_n,
11477 	(cmdline_parse_inst_t *)&cmd_set_link_up,
11478 	(cmdline_parse_inst_t *)&cmd_set_link_down,
11479 	(cmdline_parse_inst_t *)&cmd_reset,
11480 	(cmdline_parse_inst_t *)&cmd_set_numbers,
11481 	(cmdline_parse_inst_t *)&cmd_set_txpkts,
11482 	(cmdline_parse_inst_t *)&cmd_set_txsplit,
11483 	(cmdline_parse_inst_t *)&cmd_set_fwd_list,
11484 	(cmdline_parse_inst_t *)&cmd_set_fwd_mask,
11485 	(cmdline_parse_inst_t *)&cmd_set_fwd_mode,
11486 	(cmdline_parse_inst_t *)&cmd_set_fwd_retry_mode,
11487 	(cmdline_parse_inst_t *)&cmd_set_burst_tx_retry,
11488 	(cmdline_parse_inst_t *)&cmd_set_promisc_mode_one,
11489 	(cmdline_parse_inst_t *)&cmd_set_promisc_mode_all,
11490 	(cmdline_parse_inst_t *)&cmd_set_allmulti_mode_one,
11491 	(cmdline_parse_inst_t *)&cmd_set_allmulti_mode_all,
11492 	(cmdline_parse_inst_t *)&cmd_set_flush_rx,
11493 	(cmdline_parse_inst_t *)&cmd_set_link_check,
11494 #ifdef RTE_NIC_BYPASS
11495 	(cmdline_parse_inst_t *)&cmd_set_bypass_mode,
11496 	(cmdline_parse_inst_t *)&cmd_set_bypass_event,
11497 	(cmdline_parse_inst_t *)&cmd_set_bypass_timeout,
11498 	(cmdline_parse_inst_t *)&cmd_show_bypass_config,
11499 #endif
11500 #ifdef RTE_LIBRTE_PMD_BOND
11501 	(cmdline_parse_inst_t *) &cmd_set_bonding_mode,
11502 	(cmdline_parse_inst_t *) &cmd_show_bonding_config,
11503 	(cmdline_parse_inst_t *) &cmd_set_bonding_primary,
11504 	(cmdline_parse_inst_t *) &cmd_add_bonding_slave,
11505 	(cmdline_parse_inst_t *) &cmd_remove_bonding_slave,
11506 	(cmdline_parse_inst_t *) &cmd_create_bonded_device,
11507 	(cmdline_parse_inst_t *) &cmd_set_bond_mac_addr,
11508 	(cmdline_parse_inst_t *) &cmd_set_balance_xmit_policy,
11509 	(cmdline_parse_inst_t *) &cmd_set_bond_mon_period,
11510 #endif
11511 	(cmdline_parse_inst_t *)&cmd_vlan_offload,
11512 	(cmdline_parse_inst_t *)&cmd_vlan_tpid,
11513 	(cmdline_parse_inst_t *)&cmd_rx_vlan_filter_all,
11514 	(cmdline_parse_inst_t *)&cmd_rx_vlan_filter,
11515 	(cmdline_parse_inst_t *)&cmd_tx_vlan_set,
11516 	(cmdline_parse_inst_t *)&cmd_tx_vlan_set_qinq,
11517 	(cmdline_parse_inst_t *)&cmd_tx_vlan_reset,
11518 	(cmdline_parse_inst_t *)&cmd_tx_vlan_set_pvid,
11519 	(cmdline_parse_inst_t *)&cmd_csum_set,
11520 	(cmdline_parse_inst_t *)&cmd_csum_show,
11521 	(cmdline_parse_inst_t *)&cmd_csum_tunnel,
11522 	(cmdline_parse_inst_t *)&cmd_tso_set,
11523 	(cmdline_parse_inst_t *)&cmd_tso_show,
11524 	(cmdline_parse_inst_t *)&cmd_tunnel_tso_set,
11525 	(cmdline_parse_inst_t *)&cmd_tunnel_tso_show,
11526 	(cmdline_parse_inst_t *)&cmd_link_flow_control_set,
11527 	(cmdline_parse_inst_t *)&cmd_link_flow_control_set_rx,
11528 	(cmdline_parse_inst_t *)&cmd_link_flow_control_set_tx,
11529 	(cmdline_parse_inst_t *)&cmd_link_flow_control_set_hw,
11530 	(cmdline_parse_inst_t *)&cmd_link_flow_control_set_lw,
11531 	(cmdline_parse_inst_t *)&cmd_link_flow_control_set_pt,
11532 	(cmdline_parse_inst_t *)&cmd_link_flow_control_set_xon,
11533 	(cmdline_parse_inst_t *)&cmd_link_flow_control_set_macfwd,
11534 	(cmdline_parse_inst_t *)&cmd_link_flow_control_set_autoneg,
11535 	(cmdline_parse_inst_t *)&cmd_priority_flow_control_set,
11536 	(cmdline_parse_inst_t *)&cmd_config_dcb,
11537 	(cmdline_parse_inst_t *)&cmd_read_reg,
11538 	(cmdline_parse_inst_t *)&cmd_read_reg_bit_field,
11539 	(cmdline_parse_inst_t *)&cmd_read_reg_bit,
11540 	(cmdline_parse_inst_t *)&cmd_write_reg,
11541 	(cmdline_parse_inst_t *)&cmd_write_reg_bit_field,
11542 	(cmdline_parse_inst_t *)&cmd_write_reg_bit,
11543 	(cmdline_parse_inst_t *)&cmd_read_rxd_txd,
11544 	(cmdline_parse_inst_t *)&cmd_stop,
11545 	(cmdline_parse_inst_t *)&cmd_mac_addr,
11546 	(cmdline_parse_inst_t *)&cmd_set_qmap,
11547 	(cmdline_parse_inst_t *)&cmd_operate_port,
11548 	(cmdline_parse_inst_t *)&cmd_operate_specific_port,
11549 	(cmdline_parse_inst_t *)&cmd_operate_attach_port,
11550 	(cmdline_parse_inst_t *)&cmd_operate_detach_port,
11551 	(cmdline_parse_inst_t *)&cmd_config_speed_all,
11552 	(cmdline_parse_inst_t *)&cmd_config_speed_specific,
11553 	(cmdline_parse_inst_t *)&cmd_config_rx_tx,
11554 	(cmdline_parse_inst_t *)&cmd_config_mtu,
11555 	(cmdline_parse_inst_t *)&cmd_config_max_pkt_len,
11556 	(cmdline_parse_inst_t *)&cmd_config_rx_mode_flag,
11557 	(cmdline_parse_inst_t *)&cmd_config_rss,
11558 	(cmdline_parse_inst_t *)&cmd_config_rxtx_queue,
11559 	(cmdline_parse_inst_t *)&cmd_config_txqflags,
11560 	(cmdline_parse_inst_t *)&cmd_config_rss_reta,
11561 	(cmdline_parse_inst_t *)&cmd_showport_reta,
11562 	(cmdline_parse_inst_t *)&cmd_config_burst,
11563 	(cmdline_parse_inst_t *)&cmd_config_thresh,
11564 	(cmdline_parse_inst_t *)&cmd_config_threshold,
11565 	(cmdline_parse_inst_t *)&cmd_set_vf_rxmode,
11566 	(cmdline_parse_inst_t *)&cmd_set_uc_hash_filter,
11567 	(cmdline_parse_inst_t *)&cmd_set_uc_all_hash_filter,
11568 	(cmdline_parse_inst_t *)&cmd_vf_mac_addr_filter,
11569 	(cmdline_parse_inst_t *)&cmd_set_vf_macvlan_filter,
11570 	(cmdline_parse_inst_t *)&cmd_set_vf_traffic,
11571 	(cmdline_parse_inst_t *)&cmd_vf_rxvlan_filter,
11572 	(cmdline_parse_inst_t *)&cmd_queue_rate_limit,
11573 	(cmdline_parse_inst_t *)&cmd_vf_rate_limit,
11574 	(cmdline_parse_inst_t *)&cmd_tunnel_filter,
11575 	(cmdline_parse_inst_t *)&cmd_tunnel_udp_config,
11576 	(cmdline_parse_inst_t *)&cmd_global_config,
11577 	(cmdline_parse_inst_t *)&cmd_set_mirror_mask,
11578 	(cmdline_parse_inst_t *)&cmd_set_mirror_link,
11579 	(cmdline_parse_inst_t *)&cmd_reset_mirror_rule,
11580 	(cmdline_parse_inst_t *)&cmd_showport_rss_hash,
11581 	(cmdline_parse_inst_t *)&cmd_showport_rss_hash_key,
11582 	(cmdline_parse_inst_t *)&cmd_config_rss_hash_key,
11583 	(cmdline_parse_inst_t *)&cmd_dump,
11584 	(cmdline_parse_inst_t *)&cmd_dump_one,
11585 	(cmdline_parse_inst_t *)&cmd_ethertype_filter,
11586 	(cmdline_parse_inst_t *)&cmd_syn_filter,
11587 	(cmdline_parse_inst_t *)&cmd_2tuple_filter,
11588 	(cmdline_parse_inst_t *)&cmd_5tuple_filter,
11589 	(cmdline_parse_inst_t *)&cmd_flex_filter,
11590 	(cmdline_parse_inst_t *)&cmd_add_del_ip_flow_director,
11591 	(cmdline_parse_inst_t *)&cmd_add_del_udp_flow_director,
11592 	(cmdline_parse_inst_t *)&cmd_add_del_sctp_flow_director,
11593 	(cmdline_parse_inst_t *)&cmd_add_del_l2_flow_director,
11594 	(cmdline_parse_inst_t *)&cmd_add_del_mac_vlan_flow_director,
11595 	(cmdline_parse_inst_t *)&cmd_add_del_tunnel_flow_director,
11596 	(cmdline_parse_inst_t *)&cmd_flush_flow_director,
11597 	(cmdline_parse_inst_t *)&cmd_set_flow_director_ip_mask,
11598 	(cmdline_parse_inst_t *)&cmd_set_flow_director_mac_vlan_mask,
11599 	(cmdline_parse_inst_t *)&cmd_set_flow_director_tunnel_mask,
11600 	(cmdline_parse_inst_t *)&cmd_set_flow_director_flex_mask,
11601 	(cmdline_parse_inst_t *)&cmd_set_flow_director_flex_payload,
11602 	(cmdline_parse_inst_t *)&cmd_get_sym_hash_ena_per_port,
11603 	(cmdline_parse_inst_t *)&cmd_set_sym_hash_ena_per_port,
11604 	(cmdline_parse_inst_t *)&cmd_get_hash_global_config,
11605 	(cmdline_parse_inst_t *)&cmd_set_hash_global_config,
11606 	(cmdline_parse_inst_t *)&cmd_set_hash_input_set,
11607 	(cmdline_parse_inst_t *)&cmd_set_fdir_input_set,
11608 	(cmdline_parse_inst_t *)&cmd_mcast_addr,
11609 	(cmdline_parse_inst_t *)&cmd_config_l2_tunnel_eth_type_all,
11610 	(cmdline_parse_inst_t *)&cmd_config_l2_tunnel_eth_type_specific,
11611 	(cmdline_parse_inst_t *)&cmd_config_l2_tunnel_en_dis_all,
11612 	(cmdline_parse_inst_t *)&cmd_config_l2_tunnel_en_dis_specific,
11613 	(cmdline_parse_inst_t *)&cmd_config_e_tag_insertion_en,
11614 	(cmdline_parse_inst_t *)&cmd_config_e_tag_insertion_dis,
11615 	(cmdline_parse_inst_t *)&cmd_config_e_tag_stripping_en_dis,
11616 	(cmdline_parse_inst_t *)&cmd_config_e_tag_forwarding_en_dis,
11617 	(cmdline_parse_inst_t *)&cmd_config_e_tag_filter_add,
11618 	(cmdline_parse_inst_t *)&cmd_config_e_tag_filter_del,
11619 #ifdef RTE_LIBRTE_IXGBE_PMD
11620 	(cmdline_parse_inst_t *)&cmd_set_vf_vlan_anti_spoof,
11621 	(cmdline_parse_inst_t *)&cmd_set_vf_mac_anti_spoof,
11622 	(cmdline_parse_inst_t *)&cmd_set_vf_vlan_stripq,
11623 	(cmdline_parse_inst_t *)&cmd_set_vf_vlan_insert,
11624 	(cmdline_parse_inst_t *)&cmd_set_tx_loopback,
11625 	(cmdline_parse_inst_t *)&cmd_set_all_queues_drop_en,
11626 	(cmdline_parse_inst_t *)&cmd_set_vf_split_drop_en,
11627 	(cmdline_parse_inst_t *)&cmd_set_vf_mac_addr,
11628 #endif
11629 	NULL,
11630 };
11631 
11632 /* prompt function, called from main on MASTER lcore */
11633 void
11634 prompt(void)
11635 {
11636 	/* initialize non-constant commands */
11637 	cmd_set_fwd_mode_init();
11638 	cmd_set_fwd_retry_mode_init();
11639 
11640 	testpmd_cl = cmdline_stdin_new(main_ctx, "testpmd> ");
11641 	if (testpmd_cl == NULL)
11642 		return;
11643 	cmdline_interact(testpmd_cl);
11644 	cmdline_stdin_exit(testpmd_cl);
11645 }
11646 
11647 void
11648 prompt_exit(void)
11649 {
11650 	if (testpmd_cl != NULL)
11651 		cmdline_quit(testpmd_cl);
11652 }
11653 
11654 static void
11655 cmd_reconfig_device_queue(portid_t id, uint8_t dev, uint8_t queue)
11656 {
11657 	if (id == (portid_t)RTE_PORT_ALL) {
11658 		portid_t pid;
11659 
11660 		FOREACH_PORT(pid, ports) {
11661 			/* check if need_reconfig has been set to 1 */
11662 			if (ports[pid].need_reconfig == 0)
11663 				ports[pid].need_reconfig = dev;
11664 			/* check if need_reconfig_queues has been set to 1 */
11665 			if (ports[pid].need_reconfig_queues == 0)
11666 				ports[pid].need_reconfig_queues = queue;
11667 		}
11668 	} else if (!port_id_is_invalid(id, DISABLED_WARN)) {
11669 		/* check if need_reconfig has been set to 1 */
11670 		if (ports[id].need_reconfig == 0)
11671 			ports[id].need_reconfig = dev;
11672 		/* check if need_reconfig_queues has been set to 1 */
11673 		if (ports[id].need_reconfig_queues == 0)
11674 			ports[id].need_reconfig_queues = queue;
11675 	}
11676 }
11677