first public release
[dpdk.git] / app / test-pmd / cmdline.c
1 /*-
2  *   BSD LICENSE
3  * 
4  *   Copyright(c) 2010-2012 Intel Corporation. All rights reserved.
5  *   All rights reserved.
6  * 
7  *   Redistribution and use in source and binary forms, with or without 
8  *   modification, are permitted provided that the following conditions 
9  *   are met:
10  * 
11  *     * Redistributions of source code must retain the above copyright 
12  *       notice, this list of conditions and the following disclaimer.
13  *     * Redistributions in binary form must reproduce the above copyright 
14  *       notice, this list of conditions and the following disclaimer in 
15  *       the documentation and/or other materials provided with the 
16  *       distribution.
17  *     * Neither the name of Intel Corporation nor the names of its 
18  *       contributors may be used to endorse or promote products derived 
19  *       from this software without specific prior written permission.
20  * 
21  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
22  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
23  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
24  *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
25  *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
26  *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
27  *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 
28  *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
29  *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
30  *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
31  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  * 
33  *  version: DPDK.L.1.2.3-3
34  */
35
36 #include <stdarg.h>
37 #include <errno.h>
38 #include <stdio.h>
39 #include <stdint.h>
40 #include <stdarg.h>
41 #include <string.h>
42 #include <termios.h>
43 #include <unistd.h>
44 #include <inttypes.h>
45 #ifndef __linux__
46 #include <net/socket.h>
47 #endif
48 #include <netinet/in.h>
49
50 #include <sys/queue.h>
51
52 #include <rte_common.h>
53 #include <rte_byteorder.h>
54 #include <rte_log.h>
55 #include <rte_debug.h>
56 #include <rte_cycles.h>
57 #include <rte_memory.h>
58 #include <rte_memzone.h>
59 #include <rte_launch.h>
60 #include <rte_tailq.h>
61 #include <rte_eal.h>
62 #include <rte_per_lcore.h>
63 #include <rte_lcore.h>
64 #include <rte_atomic.h>
65 #include <rte_branch_prediction.h>
66 #include <rte_ring.h>
67 #include <rte_mempool.h>
68 #include <rte_interrupts.h>
69 #include <rte_pci.h>
70 #include <rte_ether.h>
71 #include <rte_ethdev.h>
72 #include <rte_string_fns.h>
73
74 #include <cmdline_rdline.h>
75 #include <cmdline_parse.h>
76 #include <cmdline_parse_num.h>
77 #include <cmdline_parse_string.h>
78 #include <cmdline_parse_ipaddr.h>
79 #include <cmdline_parse_etheraddr.h>
80 #include <cmdline_socket.h>
81 #include <cmdline.h>
82
83 #include "testpmd.h"
84
85 /* *** HELP *** */
86 struct cmd_help_result {
87         cmdline_fixed_string_t help;
88 };
89
90 static void cmd_help_parsed(__attribute__((unused)) void *parsed_result,
91                             struct cmdline *cl,
92                             __attribute__((unused)) void *data)
93 {
94         cmdline_printf(cl,
95                        "\n"
96                        "TEST PMD\n"
97                        "--------\n"
98                        "\n"
99                        "This commandline can be used to configure forwarding\n"
100                        "\n");
101         cmdline_printf(cl,
102                        "Display informations:\n"
103                        "---------------------\n"
104                        "- show port info|stats|fdir X|all\n"
105                        "    Diplays information or stats on port X, or all\n"
106                        "- clear port stats X|all\n"
107                        "    Clear stats for port X, or all\n"
108                        "- show config rxtx|cores|fwd\n"
109                        "    Displays the given configuration\n"
110                        "- read reg port_id reg_off\n"
111                        "    Displays value of a port register\n"
112                        "- read regfield port_id reg_off bit_x bit_y\n"
113                        "    Displays value of a port register bit field\n"
114                        "- read regbit port_id reg_off bit_x\n"
115                        "    Displays value of a port register bit\n"
116                        "- read rxd port_id queue_id rxd_id\n"
117                        "    Displays a RX descriptor of a port RX queue\n"
118                        "- read txd port_id queue_id txd_id\n"
119                        "    Displays a TX descriptor of a port TX queue\n"
120                        "\n");
121         cmdline_printf(cl,
122                        "Configure:\n"
123                        "----------\n"
124                        "Modifications are taken into account once "
125                        "forwarding is restarted.\n"
126                        "- set default\n"
127                        "    Set forwarding to default configuration\n"
128                        "- set nbport|nbcore|burst|verbose X\n"
129                        "    Set number of ports, number of cores, number "
130                        "of packets per burst,\n    or verbose level to X\n"
131                        "- set txpkts x[,y]*\n"
132                        "    Set the length of each segment of TXONLY packets\n"
133                        "- set coremask|portmask X\n"
134                        "    Set the hexadecimal mask of forwarding cores / "
135                        "forwarding ports\n"
136                        "- set corelist|portlist x[,y]*\n"
137                        "    Set the list of forwarding cores / forwarding "
138                        "ports\n"
139                        "- rx_vlan add/rm vlan_id|all port_id\n"
140                        "    Add/remove vlan_id, or all identifiers, to/from "
141                        "the set of VLAN Identifiers\n    filtered by port_id\n"
142                        "- tx_vlan set vlan_id port_id\n"
143                        "    Enable hardware insertion of a VLAN header with "
144                        "the Tag Identifier vlan_id\n    in packets sent on"
145                        "port_id\n"
146                        "- tx_vlan reset port_id\n"
147                        "    Disable hardware insertion of a VLAN header in "
148                        "packets sent on port_id\n"
149                        "- tx_checksum set mask port_id\n"
150                        "    Enable hardware insertion of checksum offload with "
151                        "the 4-bit mask (0~0xf)\n    in packets sent on port_id\n"
152                        "    Please check the NIC datasheet for HW limits\n"
153                        "      bit 0 - insert ip checksum offload if set \n"
154                        "      bit 1 - insert udp checksum offload if set \n"
155                        "      bit 2 - insert tcp checksum offload if set\n"
156                        "      bit 3 - insert sctp checksum offload if set\n"
157 #ifdef RTE_LIBRTE_IEEE1588
158                        "- set fwd io|mac|rxonly|txonly|csum|ieee1588\n"
159                        "    Set IO, MAC, RXONLY, TXONLY, CSUM or IEEE1588 "
160                        "packet forwarding mode\n"
161 #else
162                        "- set fwd io|mac|rxonly|txonly|csum\n"
163                        "    Set IO, MAC, RXONLY, CSUM or TXONLY packet "
164                        "forwarding mode\n"
165 #endif
166                        "- mac_addr add|remove X <xx:xx:xx:xx:xx:xx>\n"
167                        "    Add/Remove the MAC address <xx:xx:xx:xx:xx:xx> on port X\n"
168                        "- set promisc|allmulti [all|X] on|off\n"
169                        "    Set/unset promisc|allmulti mode on port X, or all\n"
170                        "- set flow_ctrl rx on|off tx on|off high_water low_water "
171                                                 "pause_time send_xon port_id \n"
172                        "    Set the link flow control parameter on the port \n"
173                        "- write reg port_id reg_off value\n"
174                        "    Set value of a port register\n"
175                        "- write regfield port_id reg_off bit_x bit_y value\n"
176                        "    Set bit field value of a port register\n"
177                        "- write regbit port_id reg_off bit_x value\n"
178                        "    Set bit value of a port register\n"
179                        "\n");
180         cmdline_printf(cl,
181                        "Control forwarding:\n"
182                        "-------------------\n"
183                        "- start\n"
184                        "    Start packet forwarding with current config\n"
185                        "- start tx_first\n"
186                        "    Start packet forwarding with current config"
187                        " after sending one burst\n    of packets\n"
188                        "- stop\n"
189                        "    Stop packet forwarding, and displays accumulated"
190                        " stats\n"
191                        "\n");
192         cmdline_printf(cl,
193                        "Flow director mode:\n"
194                        "-------------------\n"
195                        "- add_signature_filter port_id ip|udp|tcp|sctp src\n"
196                        "    ip_src_address port_src dst ip_dst_address port_dst\n"
197                        "    flexbytes flexbytes_values vlan vlan_id queue queue_id\n"
198                        "- upd_signature_filter port_id ip|udp|tcp|sctp src \n"
199                        "    ip_src_address port_src dst ip_dst_address port_dst\n"
200                        "    flexbytes flexbytes_values vlan vlan_id queue queue_id\n"
201                        "- rm_signature_filter port_id ip|udp|tcp|sctp src\n"
202                        "    ip_src_address port_src dst ip_dst_address port_dst\n"
203                        "    flexbytes flexbytes_values vlan vlan_id\n"
204                        "- add_perfect_filter port_id ip|udp|tcp|sctp src\n"
205                        "    ip_src_address port_src dst ip_dst_address port_dst\n"
206                        "    flexbytes flexbytes_values vlan vlan_id queue \n"
207                        "    queue_id soft soft_id\n"
208                        "- upd_perfect_filter port_id ip|udp|tcp|sctp src\n"
209                        "    ip_src_address port_src dst ip_dst_address port_dst\n"
210                        "    flexbytes flexbytes_values vlan vlan_id queue queue_id\n"
211                        "- rm_perfect_filter port_id ip|udp|tcp|sctp src\n"
212                        "    ip_src_address port_src dst ip_dst_address port_dst\n"
213                        "    flexbytes flexbytes_values vlan vlan_id soft soft_id\n"
214                        "- set_masks_filter port_id only_ip_flow 0|1 src_mask\n"
215                        "    ip_src_mask  port_src_mask dst_mask ip_dst_mask\n"
216                        "    port_dst_mask flexbytes 0|1 vlan_id 0|1 vlan_prio 0|1\n"
217                        "\n");
218         cmdline_printf(cl,
219                        "Misc:\n"
220                        "-----\n"
221                        "- quit\n"
222                        "    Quit to prompt in linux, and reboot on baremetal\n"
223                        "\n");
224 }
225
226 cmdline_parse_token_string_t cmd_help_help =
227         TOKEN_STRING_INITIALIZER(struct cmd_help_result, help, "help");
228
229 cmdline_parse_inst_t cmd_help = {
230         .f = cmd_help_parsed,
231         .data = NULL,
232         .help_str = "show help",
233         .tokens = {
234                 (void *)&cmd_help_help,
235                 NULL,
236         },
237 };
238
239 /* *** stop *** */
240 struct cmd_stop_result {
241         cmdline_fixed_string_t stop;
242 };
243
244 static void cmd_stop_parsed(__attribute__((unused)) void *parsed_result,
245                             __attribute__((unused)) struct cmdline *cl,
246                             __attribute__((unused)) void *data)
247 {
248         stop_packet_forwarding();
249 }
250
251 cmdline_parse_token_string_t cmd_stop_stop =
252         TOKEN_STRING_INITIALIZER(struct cmd_stop_result, stop, "stop");
253
254 cmdline_parse_inst_t cmd_stop = {
255         .f = cmd_stop_parsed,
256         .data = NULL,
257         .help_str = "stop - stop packet forwarding",
258         .tokens = {
259                 (void *)&cmd_stop_stop,
260                 NULL,
261         },
262 };
263
264 /* *** SET CORELIST and PORTLIST CONFIGURATION *** */
265
266 static unsigned int
267 parse_item_list(char* str, const char* item_name, unsigned int max_items,
268                 unsigned int *parsed_items, int check_unique_values)
269 {
270         unsigned int nb_item;
271         unsigned int value;
272         unsigned int i;
273         unsigned int j;
274         int value_ok;
275         char c;
276
277         /*
278          * First parse all items in the list and store their value.
279          */
280         value = 0;
281         nb_item = 0;
282         value_ok = 0;
283         for (i = 0; i < strnlen(str, STR_TOKEN_SIZE); i++) {
284                 c = str[i];
285                 if ((c >= '0') && (c <= '9')) {
286                         value = (unsigned int) (value * 10 + (c - '0'));
287                         value_ok = 1;
288                         continue;
289                 }
290                 if (c != ',') {
291                         printf("character %c is not a decimal digit\n", c);
292                         return (0);
293                 }
294                 if (! value_ok) {
295                         printf("No valid value before comma\n");
296                         return (0);
297                 }
298                 if (nb_item < max_items) {
299                         parsed_items[nb_item] = value;
300                         value_ok = 0;
301                         value = 0;
302                 }
303                 nb_item++;
304         }
305         if (nb_item >= max_items) {
306                 printf("Number of %s = %u > %u (maximum items)\n",
307                        item_name, nb_item + 1, max_items);
308                 return (0);
309         }
310         parsed_items[nb_item++] = value;
311         if (! check_unique_values)
312                 return (nb_item);
313
314         /*
315          * Then, check that all values in the list are differents.
316          * No optimization here...
317          */
318         for (i = 0; i < nb_item; i++) {
319                 for (j = i + 1; j < nb_item; j++) {
320                         if (parsed_items[j] == parsed_items[i]) {
321                                 printf("duplicated %s %u at index %u and %u\n",
322                                        item_name, parsed_items[i], i, j);
323                                 return (0);
324                         }
325                 }
326         }
327         return (nb_item);
328 }
329
330 struct cmd_set_list_result {
331         cmdline_fixed_string_t cmd_keyword;
332         cmdline_fixed_string_t list_name;
333         cmdline_fixed_string_t list_of_items;
334 };
335
336 static void cmd_set_list_parsed(void *parsed_result,
337                                 __attribute__((unused)) struct cmdline *cl,
338                                 __attribute__((unused)) void *data)
339 {
340         struct cmd_set_list_result *res;
341         union {
342                 unsigned int lcorelist[RTE_MAX_LCORE];
343                 unsigned int portlist[RTE_MAX_ETHPORTS];
344         } parsed_items;
345         unsigned int nb_item;
346
347         res = parsed_result;
348         if (!strcmp(res->list_name, "corelist")) {
349                 nb_item = parse_item_list(res->list_of_items, "core",
350                                           RTE_MAX_LCORE,
351                                           parsed_items.lcorelist, 1);
352                 if (nb_item > 0)
353                         set_fwd_lcores_list(parsed_items.lcorelist, nb_item);
354                 return;
355         }
356         if (!strcmp(res->list_name, "portlist")) {
357                 nb_item = parse_item_list(res->list_of_items, "port",
358                                           RTE_MAX_ETHPORTS,
359                                           parsed_items.portlist, 1);
360                 if (nb_item > 0)
361                         set_fwd_ports_list(parsed_items.portlist, nb_item);
362         }
363 }
364
365 cmdline_parse_token_string_t cmd_set_list_keyword =
366         TOKEN_STRING_INITIALIZER(struct cmd_set_list_result, cmd_keyword,
367                                  "set");
368 cmdline_parse_token_string_t cmd_set_list_name =
369         TOKEN_STRING_INITIALIZER(struct cmd_set_list_result, list_name,
370                                  "corelist#portlist");
371 cmdline_parse_token_string_t cmd_set_list_of_items =
372         TOKEN_STRING_INITIALIZER(struct cmd_set_list_result, list_of_items,
373                                  NULL);
374
375 cmdline_parse_inst_t cmd_set_fwd_list = {
376         .f = cmd_set_list_parsed,
377         .data = NULL,
378         .help_str = "set corelist|portlist x[,y]*",
379         .tokens = {
380                 (void *)&cmd_set_list_keyword,
381                 (void *)&cmd_set_list_name,
382                 (void *)&cmd_set_list_of_items,
383                 NULL,
384         },
385 };
386
387 /* *** SET COREMASK and PORTMASK CONFIGURATION *** */
388
389 struct cmd_setmask_result {
390         cmdline_fixed_string_t set;
391         cmdline_fixed_string_t mask;
392         uint64_t hexavalue;
393 };
394
395 static void cmd_set_mask_parsed(void *parsed_result,
396                                 __attribute__((unused)) struct cmdline *cl,
397                                 __attribute__((unused)) void *data)
398 {
399         struct cmd_setmask_result *res = parsed_result;
400
401         if (!strcmp(res->mask, "coremask"))
402                 set_fwd_lcores_mask(res->hexavalue);
403         else if (!strcmp(res->mask, "portmask"))
404                 set_fwd_ports_mask(res->hexavalue);
405 }
406
407 cmdline_parse_token_string_t cmd_setmask_set =
408         TOKEN_STRING_INITIALIZER(struct cmd_setmask_result, set, "set");
409 cmdline_parse_token_string_t cmd_setmask_mask =
410         TOKEN_STRING_INITIALIZER(struct cmd_setmask_result, mask,
411                                  "coremask#portmask");
412 cmdline_parse_token_num_t cmd_setmask_value =
413         TOKEN_NUM_INITIALIZER(struct cmd_setmask_result, hexavalue, UINT64);
414
415 cmdline_parse_inst_t cmd_set_fwd_mask = {
416         .f = cmd_set_mask_parsed,
417         .data = NULL,
418         .help_str = "set coremask|portmask hexadecimal value",
419         .tokens = {
420                 (void *)&cmd_setmask_set,
421                 (void *)&cmd_setmask_mask,
422                 (void *)&cmd_setmask_value,
423                 NULL,
424         },
425 };
426
427 /*
428  * SET NBPORT, NBCORE, PACKET BURST, and VERBOSE LEVEL CONFIGURATION
429  */
430 struct cmd_set_result {
431         cmdline_fixed_string_t set;
432         cmdline_fixed_string_t what;
433         uint16_t value;
434 };
435
436 static void cmd_set_parsed(void *parsed_result,
437                            __attribute__((unused)) struct cmdline *cl,
438                            __attribute__((unused)) void *data)
439 {
440         struct cmd_set_result *res = parsed_result;
441         if (!strcmp(res->what, "nbport"))
442                 set_fwd_ports_number(res->value);
443         else if (!strcmp(res->what, "nbcore"))
444                 set_fwd_lcores_number(res->value);
445         else if (!strcmp(res->what, "burst"))
446                 set_nb_pkt_per_burst(res->value);
447         else if (!strcmp(res->what, "verbose"))
448                 set_verbose_level(res->value);
449 }
450
451 cmdline_parse_token_string_t cmd_set_set =
452         TOKEN_STRING_INITIALIZER(struct cmd_set_result, set, "set");
453 cmdline_parse_token_string_t cmd_set_what =
454         TOKEN_STRING_INITIALIZER(struct cmd_set_result, what,
455                                  "nbport#nbcore#burst#verbose");
456 cmdline_parse_token_num_t cmd_set_value =
457         TOKEN_NUM_INITIALIZER(struct cmd_set_result, value, UINT16);
458
459 cmdline_parse_inst_t cmd_set_numbers = {
460         .f = cmd_set_parsed,
461         .data = NULL,
462         .help_str = "set nbport|nbcore|burst|verbose value",
463         .tokens = {
464                 (void *)&cmd_set_set,
465                 (void *)&cmd_set_what,
466                 (void *)&cmd_set_value,
467                 NULL,
468         },
469 };
470
471 /* *** SET SEGMENT LENGTHS OF TXONLY PACKETS *** */
472
473 struct cmd_set_txpkts_result {
474         cmdline_fixed_string_t cmd_keyword;
475         cmdline_fixed_string_t txpkts;
476         cmdline_fixed_string_t seg_lengths;
477 };
478
479 static void
480 cmd_set_txpkts_parsed(void *parsed_result,
481                       __attribute__((unused)) struct cmdline *cl,
482                       __attribute__((unused)) void *data)
483 {
484         struct cmd_set_txpkts_result *res;
485         unsigned seg_lengths[RTE_MAX_SEGS_PER_PKT];
486         unsigned int nb_segs;
487
488         res = parsed_result;
489         nb_segs = parse_item_list(res->seg_lengths, "segment lengths",
490                                   RTE_MAX_SEGS_PER_PKT, seg_lengths, 0);
491         if (nb_segs > 0)
492                 set_tx_pkt_segments(seg_lengths, nb_segs);
493 }
494
495 cmdline_parse_token_string_t cmd_set_txpkts_keyword =
496         TOKEN_STRING_INITIALIZER(struct cmd_set_txpkts_result,
497                                  cmd_keyword, "set");
498 cmdline_parse_token_string_t cmd_set_txpkts_name =
499         TOKEN_STRING_INITIALIZER(struct cmd_set_txpkts_result,
500                                  txpkts, "txpkts");
501 cmdline_parse_token_string_t cmd_set_txpkts_lengths =
502         TOKEN_STRING_INITIALIZER(struct cmd_set_txpkts_result,
503                                  seg_lengths, NULL);
504
505 cmdline_parse_inst_t cmd_set_txpkts = {
506         .f = cmd_set_txpkts_parsed,
507         .data = NULL,
508         .help_str = "set txpkts x[,y]*",
509         .tokens = {
510                 (void *)&cmd_set_txpkts_keyword,
511                 (void *)&cmd_set_txpkts_name,
512                 (void *)&cmd_set_txpkts_lengths,
513                 NULL,
514         },
515 };
516
517 /* *** ADD/REMOVE ALL VLAN IDENTIFIERS TO/FROM A PORT VLAN RX FILTER *** */
518 struct cmd_rx_vlan_filter_all_result {
519         cmdline_fixed_string_t rx_vlan;
520         cmdline_fixed_string_t what;
521         cmdline_fixed_string_t all;
522         uint8_t port_id;
523 };
524
525 static void
526 cmd_rx_vlan_filter_all_parsed(void *parsed_result,
527                               __attribute__((unused)) struct cmdline *cl,
528                               __attribute__((unused)) void *data)
529 {
530         struct cmd_rx_vlan_filter_all_result *res = parsed_result;
531
532         if (!strcmp(res->what, "add"))
533                 rx_vlan_all_filter_set(res->port_id, 1);
534         else
535                 rx_vlan_all_filter_set(res->port_id, 0);
536 }
537
538 cmdline_parse_token_string_t cmd_rx_vlan_filter_all_rx_vlan =
539         TOKEN_STRING_INITIALIZER(struct cmd_rx_vlan_filter_all_result,
540                                  rx_vlan, "rx_vlan");
541 cmdline_parse_token_string_t cmd_rx_vlan_filter_all_what =
542         TOKEN_STRING_INITIALIZER(struct cmd_rx_vlan_filter_all_result,
543                                  what, "add#rm");
544 cmdline_parse_token_string_t cmd_rx_vlan_filter_all_all =
545         TOKEN_STRING_INITIALIZER(struct cmd_rx_vlan_filter_all_result,
546                                  all, "all");
547 cmdline_parse_token_num_t cmd_rx_vlan_filter_all_portid =
548         TOKEN_NUM_INITIALIZER(struct cmd_rx_vlan_filter_all_result,
549                               port_id, UINT8);
550
551 cmdline_parse_inst_t cmd_rx_vlan_filter_all = {
552         .f = cmd_rx_vlan_filter_all_parsed,
553         .data = NULL,
554         .help_str = "add/remove all identifiers to/from the set of VLAN "
555         "Identifiers filtered by a port",
556         .tokens = {
557                 (void *)&cmd_rx_vlan_filter_all_rx_vlan,
558                 (void *)&cmd_rx_vlan_filter_all_what,
559                 (void *)&cmd_rx_vlan_filter_all_all,
560                 (void *)&cmd_rx_vlan_filter_all_portid,
561                 NULL,
562         },
563 };
564
565 /* *** ADD/REMOVE A VLAN IDENTIFIER TO/FROM A PORT VLAN RX FILTER *** */
566 struct cmd_rx_vlan_filter_result {
567         cmdline_fixed_string_t rx_vlan;
568         cmdline_fixed_string_t what;
569         uint16_t vlan_id;
570         uint8_t port_id;
571 };
572
573 static void
574 cmd_rx_vlan_filter_parsed(void *parsed_result,
575                           __attribute__((unused)) struct cmdline *cl,
576                           __attribute__((unused)) void *data)
577 {
578         struct cmd_rx_vlan_filter_result *res = parsed_result;
579
580         if (!strcmp(res->what, "add"))
581                 rx_vlan_filter_set(res->port_id, res->vlan_id, 1);
582         else
583                 rx_vlan_filter_set(res->port_id, res->vlan_id, 0);
584 }
585
586 cmdline_parse_token_string_t cmd_rx_vlan_filter_rx_vlan =
587         TOKEN_STRING_INITIALIZER(struct cmd_rx_vlan_filter_result,
588                                  rx_vlan, "rx_vlan");
589 cmdline_parse_token_string_t cmd_rx_vlan_filter_what =
590         TOKEN_STRING_INITIALIZER(struct cmd_rx_vlan_filter_result,
591                                  what, "add#rm");
592 cmdline_parse_token_num_t cmd_rx_vlan_filter_vlanid =
593         TOKEN_NUM_INITIALIZER(struct cmd_rx_vlan_filter_result,
594                               vlan_id, UINT16);
595 cmdline_parse_token_num_t cmd_rx_vlan_filter_portid =
596         TOKEN_NUM_INITIALIZER(struct cmd_rx_vlan_filter_result,
597                               port_id, UINT8);
598
599 cmdline_parse_inst_t cmd_rx_vlan_filter = {
600         .f = cmd_rx_vlan_filter_parsed,
601         .data = NULL,
602         .help_str = "add/remove a VLAN identifier to/from the set of VLAN "
603         "Identifiers filtered by a port",
604         .tokens = {
605                 (void *)&cmd_rx_vlan_filter_rx_vlan,
606                 (void *)&cmd_rx_vlan_filter_what,
607                 (void *)&cmd_rx_vlan_filter_vlanid,
608                 (void *)&cmd_rx_vlan_filter_portid,
609                 NULL,
610         },
611 };
612
613 /* *** ENABLE HARDWARE INSERTION OF VLAN HEADER IN TX PACKETS *** */
614 struct cmd_tx_vlan_set_result {
615         cmdline_fixed_string_t tx_vlan;
616         cmdline_fixed_string_t set;
617         uint16_t vlan_id;
618         uint8_t port_id;
619 };
620
621 static void
622 cmd_tx_vlan_set_parsed(void *parsed_result,
623                        __attribute__((unused)) struct cmdline *cl,
624                        __attribute__((unused)) void *data)
625 {
626         struct cmd_tx_vlan_set_result *res = parsed_result;
627
628         tx_vlan_set(res->port_id, res->vlan_id);
629 }
630
631 cmdline_parse_token_string_t cmd_tx_vlan_set_tx_vlan =
632         TOKEN_STRING_INITIALIZER(struct cmd_tx_vlan_set_result,
633                                  tx_vlan, "tx_vlan");
634 cmdline_parse_token_string_t cmd_tx_vlan_set_set =
635         TOKEN_STRING_INITIALIZER(struct cmd_tx_vlan_set_result,
636                                  set, "set");
637 cmdline_parse_token_num_t cmd_tx_vlan_set_vlanid =
638         TOKEN_NUM_INITIALIZER(struct cmd_tx_vlan_set_result,
639                               vlan_id, UINT16);
640 cmdline_parse_token_num_t cmd_tx_vlan_set_portid =
641         TOKEN_NUM_INITIALIZER(struct cmd_tx_vlan_set_result,
642                               port_id, UINT8);
643
644 cmdline_parse_inst_t cmd_tx_vlan_set = {
645         .f = cmd_tx_vlan_set_parsed,
646         .data = NULL,
647         .help_str = "enable hardware insertion of a VLAN header with a given "
648         "TAG Identifier in packets sent on a port",
649         .tokens = {
650                 (void *)&cmd_tx_vlan_set_tx_vlan,
651                 (void *)&cmd_tx_vlan_set_set,
652                 (void *)&cmd_tx_vlan_set_vlanid,
653                 (void *)&cmd_tx_vlan_set_portid,
654                 NULL,
655         },
656 };
657
658 /* *** DISABLE HARDWARE INSERTION OF VLAN HEADER IN TX PACKETS *** */
659 struct cmd_tx_vlan_reset_result {
660         cmdline_fixed_string_t tx_vlan;
661         cmdline_fixed_string_t reset;
662         uint8_t port_id;
663 };
664
665 static void
666 cmd_tx_vlan_reset_parsed(void *parsed_result,
667                          __attribute__((unused)) struct cmdline *cl,
668                          __attribute__((unused)) void *data)
669 {
670         struct cmd_tx_vlan_reset_result *res = parsed_result;
671
672         tx_vlan_reset(res->port_id);
673 }
674
675 cmdline_parse_token_string_t cmd_tx_vlan_reset_tx_vlan =
676         TOKEN_STRING_INITIALIZER(struct cmd_tx_vlan_reset_result,
677                                  tx_vlan, "tx_vlan");
678 cmdline_parse_token_string_t cmd_tx_vlan_reset_reset =
679         TOKEN_STRING_INITIALIZER(struct cmd_tx_vlan_reset_result,
680                                  reset, "reset");
681 cmdline_parse_token_num_t cmd_tx_vlan_reset_portid =
682         TOKEN_NUM_INITIALIZER(struct cmd_tx_vlan_reset_result,
683                               port_id, UINT8);
684
685 cmdline_parse_inst_t cmd_tx_vlan_reset = {
686         .f = cmd_tx_vlan_reset_parsed,
687         .data = NULL,
688         .help_str = "disable hardware insertion of a VLAN header in packets "
689         "sent on a port",
690         .tokens = {
691                 (void *)&cmd_tx_vlan_reset_tx_vlan,
692                 (void *)&cmd_tx_vlan_reset_reset,
693                 (void *)&cmd_tx_vlan_reset_portid,
694                 NULL,
695         },
696 };
697
698
699 /* *** ENABLE HARDWARE INSERTION OF CHECKSUM IN TX PACKETS *** */
700 struct cmd_tx_cksum_set_result {
701         cmdline_fixed_string_t tx_cksum;
702         cmdline_fixed_string_t set;
703         uint8_t cksum_mask;
704         uint8_t port_id;
705 };
706
707 static void
708 cmd_tx_cksum_set_parsed(void *parsed_result,
709                        __attribute__((unused)) struct cmdline *cl,
710                        __attribute__((unused)) void *data)
711 {
712         struct cmd_tx_cksum_set_result *res = parsed_result;
713
714         tx_cksum_set(res->port_id, res->cksum_mask);
715 }
716
717 cmdline_parse_token_string_t cmd_tx_cksum_set_tx_cksum =
718         TOKEN_STRING_INITIALIZER(struct cmd_tx_cksum_set_result,
719                                 tx_cksum, "tx_checksum");
720 cmdline_parse_token_string_t cmd_tx_cksum_set_set =
721         TOKEN_STRING_INITIALIZER(struct cmd_tx_cksum_set_result,
722                                 set, "set");
723 cmdline_parse_token_num_t cmd_tx_cksum_set_cksum_mask =
724         TOKEN_NUM_INITIALIZER(struct cmd_tx_cksum_set_result,
725                                 cksum_mask, UINT8);
726 cmdline_parse_token_num_t cmd_tx_cksum_set_portid =
727         TOKEN_NUM_INITIALIZER(struct cmd_tx_cksum_set_result,
728                                 port_id, UINT8);
729
730 cmdline_parse_inst_t cmd_tx_cksum_set = {
731         .f = cmd_tx_cksum_set_parsed,
732         .data = NULL,
733         .help_str = "enable hardware insertion of L3/L4checksum with a given "
734         "mask in packets sent on a port, the bit mapping is given as, Bit 0 for ip"
735         "Bit 1 for UDP, Bit 2 for TCP, Bit 3 for SCTP",
736         .tokens = {
737                 (void *)&cmd_tx_cksum_set_tx_cksum,
738                 (void *)&cmd_tx_cksum_set_set,
739                 (void *)&cmd_tx_cksum_set_cksum_mask,
740                 (void *)&cmd_tx_cksum_set_portid,
741                 NULL,
742         },
743 };
744
745 /* *** SET FORWARDING MODE *** */
746 struct cmd_set_fwd_mode_result {
747         cmdline_fixed_string_t set;
748         cmdline_fixed_string_t fwd;
749         cmdline_fixed_string_t mode;
750 };
751
752 static void cmd_set_fwd_mode_parsed(void *parsed_result,
753                                     __attribute__((unused)) struct cmdline *cl,
754                                     __attribute__((unused)) void *data)
755 {
756         struct cmd_set_fwd_mode_result *res = parsed_result;
757
758         set_pkt_forwarding_mode(res->mode);
759 }
760
761 cmdline_parse_token_string_t cmd_setfwd_set =
762         TOKEN_STRING_INITIALIZER(struct cmd_set_fwd_mode_result, set, "set");
763 cmdline_parse_token_string_t cmd_setfwd_fwd =
764         TOKEN_STRING_INITIALIZER(struct cmd_set_fwd_mode_result, fwd, "fwd");
765 cmdline_parse_token_string_t cmd_setfwd_mode =
766         TOKEN_STRING_INITIALIZER(struct cmd_set_fwd_mode_result, mode,
767 #ifdef RTE_LIBRTE_IEEE1588
768                                  "io#mac#rxonly#txonly#csum#ieee1588");
769 #else
770                                  "io#mac#rxonly#txonly#csum");
771 #endif
772
773 cmdline_parse_inst_t cmd_set_fwd_mode = {
774         .f = cmd_set_fwd_mode_parsed,
775         .data = NULL,
776 #ifdef RTE_LIBRTE_IEEE1588
777         .help_str = "set fwd io|mac|rxonly|txonly|csum|ieee1588 - set IO, MAC,"
778         " RXONLY, TXONLY, CSUM or IEEE1588 packet forwarding mode",
779 #else
780         .help_str = "set fwd io|mac|rxonly|txonly|csum - set IO, MAC,"
781         " RXONLY, CSUM or TXONLY packet forwarding mode",
782 #endif
783         .tokens = {
784                 (void *)&cmd_setfwd_set,
785                 (void *)&cmd_setfwd_fwd,
786                 (void *)&cmd_setfwd_mode,
787                 NULL,
788         },
789 };
790
791 /* *** SET PROMISC MODE *** */
792 struct cmd_set_promisc_mode_result {
793         cmdline_fixed_string_t set;
794         cmdline_fixed_string_t promisc;
795         cmdline_fixed_string_t port_all; /* valid if "allports" argument == 1 */
796         uint8_t port_num;                /* valid if "allports" argument == 0 */
797         cmdline_fixed_string_t mode;
798 };
799
800 static void cmd_set_promisc_mode_parsed(void *parsed_result,
801                                         __attribute__((unused)) struct cmdline *cl,
802                                         void *allports)
803 {
804         struct cmd_set_promisc_mode_result *res = parsed_result;
805         int enable;
806         portid_t i;
807
808         if (!strcmp(res->mode, "on"))
809                 enable = 1;
810         else
811                 enable = 0;
812
813         /* all ports */
814         if (allports) {
815                 for (i = 0; i < nb_ports; i++) {
816                         if (enable)
817                                 rte_eth_promiscuous_enable(i);
818                         else
819                                 rte_eth_promiscuous_disable(i);
820                 }
821         }
822         else {
823                 if (enable)
824                         rte_eth_promiscuous_enable(res->port_num);
825                 else
826                         rte_eth_promiscuous_disable(res->port_num);
827         }
828 }
829
830 cmdline_parse_token_string_t cmd_setpromisc_set =
831         TOKEN_STRING_INITIALIZER(struct cmd_set_promisc_mode_result, set, "set");
832 cmdline_parse_token_string_t cmd_setpromisc_promisc =
833         TOKEN_STRING_INITIALIZER(struct cmd_set_promisc_mode_result, promisc,
834                                  "promisc");
835 cmdline_parse_token_string_t cmd_setpromisc_portall =
836         TOKEN_STRING_INITIALIZER(struct cmd_set_promisc_mode_result, port_all,
837                                  "all");
838 cmdline_parse_token_num_t cmd_setpromisc_portnum =
839         TOKEN_NUM_INITIALIZER(struct cmd_set_promisc_mode_result, port_num,
840                               UINT8);
841 cmdline_parse_token_string_t cmd_setpromisc_mode =
842         TOKEN_STRING_INITIALIZER(struct cmd_set_promisc_mode_result, mode,
843                                  "on#off");
844
845 cmdline_parse_inst_t cmd_set_promisc_mode_all = {
846         .f = cmd_set_promisc_mode_parsed,
847         .data = (void *)1,
848         .help_str = "set promisc all on|off: set promisc mode for all ports",
849         .tokens = {
850                 (void *)&cmd_setpromisc_set,
851                 (void *)&cmd_setpromisc_promisc,
852                 (void *)&cmd_setpromisc_portall,
853                 (void *)&cmd_setpromisc_mode,
854                 NULL,
855         },
856 };
857
858 cmdline_parse_inst_t cmd_set_promisc_mode_one = {
859         .f = cmd_set_promisc_mode_parsed,
860         .data = (void *)0,
861         .help_str = "set promisc X on|off: set promisc mode on port X",
862         .tokens = {
863                 (void *)&cmd_setpromisc_set,
864                 (void *)&cmd_setpromisc_promisc,
865                 (void *)&cmd_setpromisc_portnum,
866                 (void *)&cmd_setpromisc_mode,
867                 NULL,
868         },
869 };
870
871 /* *** SET ALLMULTI MODE *** */
872 struct cmd_set_allmulti_mode_result {
873         cmdline_fixed_string_t set;
874         cmdline_fixed_string_t allmulti;
875         cmdline_fixed_string_t port_all; /* valid if "allports" argument == 1 */
876         uint8_t port_num;                /* valid if "allports" argument == 0 */
877         cmdline_fixed_string_t mode;
878 };
879
880 static void cmd_set_allmulti_mode_parsed(void *parsed_result,
881                                         __attribute__((unused)) struct cmdline *cl,
882                                         void *allports)
883 {
884         struct cmd_set_allmulti_mode_result *res = parsed_result;
885         int enable;
886         portid_t i;
887
888         if (!strcmp(res->mode, "on"))
889                 enable = 1;
890         else
891                 enable = 0;
892
893         /* all ports */
894         if (allports) {
895                 for (i = 0; i < nb_ports; i++) {
896                         if (enable)
897                                 rte_eth_allmulticast_enable(i);
898                         else
899                                 rte_eth_allmulticast_disable(i);
900                 }
901         }
902         else {
903                 if (enable)
904                         rte_eth_allmulticast_enable(res->port_num);
905                 else
906                         rte_eth_allmulticast_disable(res->port_num);
907         }
908 }
909
910 cmdline_parse_token_string_t cmd_setallmulti_set =
911         TOKEN_STRING_INITIALIZER(struct cmd_set_allmulti_mode_result, set, "set");
912 cmdline_parse_token_string_t cmd_setallmulti_allmulti =
913         TOKEN_STRING_INITIALIZER(struct cmd_set_allmulti_mode_result, allmulti,
914                                  "allmulti");
915 cmdline_parse_token_string_t cmd_setallmulti_portall =
916         TOKEN_STRING_INITIALIZER(struct cmd_set_allmulti_mode_result, port_all,
917                                  "all");
918 cmdline_parse_token_num_t cmd_setallmulti_portnum =
919         TOKEN_NUM_INITIALIZER(struct cmd_set_allmulti_mode_result, port_num,
920                               UINT8);
921 cmdline_parse_token_string_t cmd_setallmulti_mode =
922         TOKEN_STRING_INITIALIZER(struct cmd_set_allmulti_mode_result, mode,
923                                  "on#off");
924
925 cmdline_parse_inst_t cmd_set_allmulti_mode_all = {
926         .f = cmd_set_allmulti_mode_parsed,
927         .data = (void *)1,
928         .help_str = "set allmulti all on|off: set allmulti mode for all ports",
929         .tokens = {
930                 (void *)&cmd_setallmulti_set,
931                 (void *)&cmd_setallmulti_allmulti,
932                 (void *)&cmd_setallmulti_portall,
933                 (void *)&cmd_setallmulti_mode,
934                 NULL,
935         },
936 };
937
938 cmdline_parse_inst_t cmd_set_allmulti_mode_one = {
939         .f = cmd_set_allmulti_mode_parsed,
940         .data = (void *)0,
941         .help_str = "set allmulti X on|off: set allmulti mode on port X",
942         .tokens = {
943                 (void *)&cmd_setallmulti_set,
944                 (void *)&cmd_setallmulti_allmulti,
945                 (void *)&cmd_setallmulti_portnum,
946                 (void *)&cmd_setallmulti_mode,
947                 NULL,
948         },
949 };
950
951 /* *** ADD/REMOVE A PKT FILTER *** */
952 struct cmd_pkt_filter_result {
953         cmdline_fixed_string_t pkt_filter;
954         uint8_t  port_id;
955         cmdline_fixed_string_t protocol;
956         cmdline_fixed_string_t src;
957         cmdline_ipaddr_t ip_src;
958         uint16_t port_src;
959         cmdline_fixed_string_t dst;
960         cmdline_ipaddr_t ip_dst;
961         uint16_t port_dst;
962         cmdline_fixed_string_t flexbytes;
963         uint16_t flexbytes_value;
964         cmdline_fixed_string_t vlan;
965         uint16_t  vlan_id;
966         cmdline_fixed_string_t queue;
967         int8_t  queue_id;
968         cmdline_fixed_string_t soft;
969         uint8_t  soft_id;
970 };
971
972 static void
973 cmd_pkt_filter_parsed(void *parsed_result,
974                           __attribute__((unused)) struct cmdline *cl,
975                           __attribute__((unused)) void *data)
976 {
977         struct rte_fdir_filter fdir_filter;
978         struct cmd_pkt_filter_result *res = parsed_result;
979
980         memset(&fdir_filter, 0, sizeof(struct rte_fdir_filter));
981
982         if (res->ip_src.family == AF_INET)
983                 fdir_filter.ip_src.ipv4_addr = res->ip_src.addr.ipv4.s_addr;
984         else
985                 memcpy(&(fdir_filter.ip_src.ipv6_addr),
986                        &(res->ip_src.addr.ipv6),
987                        sizeof(struct in6_addr));
988
989         if (res->ip_dst.family == AF_INET)
990                 fdir_filter.ip_dst.ipv4_addr = res->ip_dst.addr.ipv4.s_addr;
991         else
992                 memcpy(&(fdir_filter.ip_dst.ipv6_addr),
993                        &(res->ip_dst.addr.ipv6),
994                        sizeof(struct in6_addr));
995
996         fdir_filter.port_dst = rte_cpu_to_be_16(res->port_dst);
997         fdir_filter.port_src = rte_cpu_to_be_16(res->port_src);
998
999         if (!strcmp(res->protocol, "udp"))
1000                 fdir_filter.l4type = RTE_FDIR_L4TYPE_UDP;
1001         else if (!strcmp(res->protocol, "tcp"))
1002                 fdir_filter.l4type = RTE_FDIR_L4TYPE_TCP;
1003         else if (!strcmp(res->protocol, "sctp"))
1004                 fdir_filter.l4type = RTE_FDIR_L4TYPE_SCTP;
1005         else /* default only IP */
1006                 fdir_filter.l4type = RTE_FDIR_L4TYPE_NONE;
1007
1008         if (res->ip_dst.family == AF_INET6)
1009                 fdir_filter.iptype = RTE_FDIR_IPTYPE_IPV6;
1010         else
1011                 fdir_filter.iptype = RTE_FDIR_IPTYPE_IPV4;
1012
1013         fdir_filter.vlan_id    = rte_cpu_to_be_16(res->vlan_id);
1014         fdir_filter.flex_bytes = rte_cpu_to_be_16(res->flexbytes_value);
1015
1016         if (!strcmp(res->pkt_filter, "add_signature_filter"))
1017                 fdir_add_signature_filter(res->port_id, res->queue_id,
1018                                           &fdir_filter);
1019         else if (!strcmp(res->pkt_filter, "upd_signature_filter"))
1020                 fdir_update_signature_filter(res->port_id, res->queue_id,
1021                                              &fdir_filter);
1022         else if (!strcmp(res->pkt_filter, "rm_signature_filter"))
1023                 fdir_remove_signature_filter(res->port_id, &fdir_filter);
1024         else if (!strcmp(res->pkt_filter, "add_perfect_filter"))
1025                 fdir_add_perfect_filter(res->port_id, res->soft_id,
1026                                         res->queue_id,
1027                                         (uint8_t) (res->queue_id < 0),
1028                                         &fdir_filter);
1029         else if (!strcmp(res->pkt_filter, "upd_perfect_filter"))
1030                 fdir_update_perfect_filter(res->port_id, res->soft_id,
1031                                            res->queue_id,
1032                                            (uint8_t) (res->queue_id < 0),
1033                                            &fdir_filter);
1034         else if (!strcmp(res->pkt_filter, "rm_perfect_filter"))
1035                 fdir_remove_perfect_filter(res->port_id, res->soft_id,
1036                                            &fdir_filter);
1037
1038 }
1039
1040
1041 cmdline_parse_token_num_t cmd_pkt_filter_port_id =
1042         TOKEN_NUM_INITIALIZER(struct cmd_pkt_filter_result,
1043                               port_id, UINT8);
1044 cmdline_parse_token_string_t cmd_pkt_filter_protocol =
1045         TOKEN_STRING_INITIALIZER(struct cmd_pkt_filter_result,
1046                                  protocol, "ip#tcp#udp#sctp");
1047 cmdline_parse_token_string_t cmd_pkt_filter_src =
1048         TOKEN_STRING_INITIALIZER(struct cmd_pkt_filter_result,
1049                                  src, "src");
1050 cmdline_parse_token_ipaddr_t cmd_pkt_filter_ip_src =
1051         TOKEN_IPADDR_INITIALIZER(struct cmd_pkt_filter_result,
1052                                  ip_src);
1053 cmdline_parse_token_num_t cmd_pkt_filter_port_src =
1054         TOKEN_NUM_INITIALIZER(struct cmd_pkt_filter_result,
1055                               port_src, UINT16);
1056 cmdline_parse_token_string_t cmd_pkt_filter_dst =
1057         TOKEN_STRING_INITIALIZER(struct cmd_pkt_filter_result,
1058                                  dst, "dst");
1059 cmdline_parse_token_ipaddr_t cmd_pkt_filter_ip_dst =
1060         TOKEN_IPADDR_INITIALIZER(struct cmd_pkt_filter_result,
1061                                  ip_dst);
1062 cmdline_parse_token_num_t cmd_pkt_filter_port_dst =
1063         TOKEN_NUM_INITIALIZER(struct cmd_pkt_filter_result,
1064                               port_dst, UINT16);
1065 cmdline_parse_token_string_t cmd_pkt_filter_flexbytes =
1066         TOKEN_STRING_INITIALIZER(struct cmd_pkt_filter_result,
1067                                  flexbytes, "flexbytes");
1068 cmdline_parse_token_num_t cmd_pkt_filter_flexbytes_value =
1069         TOKEN_NUM_INITIALIZER(struct cmd_pkt_filter_result,
1070                               flexbytes_value, UINT16);
1071 cmdline_parse_token_string_t cmd_pkt_filter_vlan =
1072         TOKEN_STRING_INITIALIZER(struct cmd_pkt_filter_result,
1073                                  vlan, "vlan");
1074 cmdline_parse_token_num_t cmd_pkt_filter_vlan_id =
1075         TOKEN_NUM_INITIALIZER(struct cmd_pkt_filter_result,
1076                               vlan_id, UINT16);
1077 cmdline_parse_token_string_t cmd_pkt_filter_queue =
1078         TOKEN_STRING_INITIALIZER(struct cmd_pkt_filter_result,
1079                                  queue, "queue");
1080 cmdline_parse_token_num_t cmd_pkt_filter_queue_id =
1081         TOKEN_NUM_INITIALIZER(struct cmd_pkt_filter_result,
1082                               queue_id, INT8);
1083 cmdline_parse_token_string_t cmd_pkt_filter_soft =
1084         TOKEN_STRING_INITIALIZER(struct cmd_pkt_filter_result,
1085                                  soft, "soft");
1086 cmdline_parse_token_num_t cmd_pkt_filter_soft_id =
1087         TOKEN_NUM_INITIALIZER(struct cmd_pkt_filter_result,
1088                               soft_id, UINT16);
1089
1090
1091 cmdline_parse_token_string_t cmd_pkt_filter_add_signature_filter =
1092         TOKEN_STRING_INITIALIZER(struct cmd_pkt_filter_result,
1093                                  pkt_filter, "add_signature_filter");
1094 cmdline_parse_inst_t cmd_add_signature_filter = {
1095         .f = cmd_pkt_filter_parsed,
1096         .data = NULL,
1097         .help_str = "add a signature filter",
1098         .tokens = {
1099                 (void *)&cmd_pkt_filter_add_signature_filter,
1100                 (void *)&cmd_pkt_filter_port_id,
1101                 (void *)&cmd_pkt_filter_protocol,
1102                 (void *)&cmd_pkt_filter_src,
1103                 (void *)&cmd_pkt_filter_ip_src,
1104                 (void *)&cmd_pkt_filter_port_src,
1105                 (void *)&cmd_pkt_filter_dst,
1106                 (void *)&cmd_pkt_filter_ip_dst,
1107                 (void *)&cmd_pkt_filter_port_dst,
1108                 (void *)&cmd_pkt_filter_flexbytes,
1109                 (void *)&cmd_pkt_filter_flexbytes_value,
1110                 (void *)&cmd_pkt_filter_vlan,
1111                 (void *)&cmd_pkt_filter_vlan_id,
1112                 (void *)&cmd_pkt_filter_queue,
1113                 (void *)&cmd_pkt_filter_queue_id,
1114                 NULL,
1115         },
1116 };
1117
1118
1119 cmdline_parse_token_string_t cmd_pkt_filter_upd_signature_filter =
1120         TOKEN_STRING_INITIALIZER(struct cmd_pkt_filter_result,
1121                                  pkt_filter, "upd_signature_filter");
1122 cmdline_parse_inst_t cmd_upd_signature_filter = {
1123         .f = cmd_pkt_filter_parsed,
1124         .data = NULL,
1125         .help_str = "update a signature filter",
1126         .tokens = {
1127                 (void *)&cmd_pkt_filter_upd_signature_filter,
1128                 (void *)&cmd_pkt_filter_port_id,
1129                 (void *)&cmd_pkt_filter_protocol,
1130                 (void *)&cmd_pkt_filter_src,
1131                 (void *)&cmd_pkt_filter_ip_src,
1132                 (void *)&cmd_pkt_filter_port_src,
1133                 (void *)&cmd_pkt_filter_dst,
1134                 (void *)&cmd_pkt_filter_ip_dst,
1135                 (void *)&cmd_pkt_filter_port_dst,
1136                 (void *)&cmd_pkt_filter_flexbytes,
1137                 (void *)&cmd_pkt_filter_flexbytes_value,
1138                 (void *)&cmd_pkt_filter_vlan,
1139                 (void *)&cmd_pkt_filter_vlan_id,
1140                 (void *)&cmd_pkt_filter_queue,
1141                 (void *)&cmd_pkt_filter_queue_id,
1142                 NULL,
1143         },
1144 };
1145
1146
1147 cmdline_parse_token_string_t cmd_pkt_filter_rm_signature_filter =
1148         TOKEN_STRING_INITIALIZER(struct cmd_pkt_filter_result,
1149                                  pkt_filter, "rm_signature_filter");
1150 cmdline_parse_inst_t cmd_rm_signature_filter = {
1151         .f = cmd_pkt_filter_parsed,
1152         .data = NULL,
1153         .help_str = "remove a signature filter",
1154         .tokens = {
1155                 (void *)&cmd_pkt_filter_rm_signature_filter,
1156                 (void *)&cmd_pkt_filter_port_id,
1157                 (void *)&cmd_pkt_filter_protocol,
1158                 (void *)&cmd_pkt_filter_src,
1159                 (void *)&cmd_pkt_filter_ip_src,
1160                 (void *)&cmd_pkt_filter_port_src,
1161                 (void *)&cmd_pkt_filter_dst,
1162                 (void *)&cmd_pkt_filter_ip_dst,
1163                 (void *)&cmd_pkt_filter_port_dst,
1164                 (void *)&cmd_pkt_filter_flexbytes,
1165                 (void *)&cmd_pkt_filter_flexbytes_value,
1166                 (void *)&cmd_pkt_filter_vlan,
1167                 (void *)&cmd_pkt_filter_vlan_id,
1168                 NULL
1169                 },
1170 };
1171
1172
1173 cmdline_parse_token_string_t cmd_pkt_filter_add_perfect_filter =
1174         TOKEN_STRING_INITIALIZER(struct cmd_pkt_filter_result,
1175                                  pkt_filter, "add_perfect_filter");
1176 cmdline_parse_inst_t cmd_add_perfect_filter = {
1177         .f = cmd_pkt_filter_parsed,
1178         .data = NULL,
1179         .help_str = "add a perfect filter",
1180         .tokens = {
1181                 (void *)&cmd_pkt_filter_add_perfect_filter,
1182                 (void *)&cmd_pkt_filter_port_id,
1183                 (void *)&cmd_pkt_filter_protocol,
1184                 (void *)&cmd_pkt_filter_src,
1185                 (void *)&cmd_pkt_filter_ip_src,
1186                 (void *)&cmd_pkt_filter_port_src,
1187                 (void *)&cmd_pkt_filter_dst,
1188                 (void *)&cmd_pkt_filter_ip_dst,
1189                 (void *)&cmd_pkt_filter_port_dst,
1190                 (void *)&cmd_pkt_filter_flexbytes,
1191                 (void *)&cmd_pkt_filter_flexbytes_value,
1192                 (void *)&cmd_pkt_filter_vlan,
1193                 (void *)&cmd_pkt_filter_vlan_id,
1194                 (void *)&cmd_pkt_filter_queue,
1195                 (void *)&cmd_pkt_filter_queue_id,
1196                 (void *)&cmd_pkt_filter_soft,
1197                 (void *)&cmd_pkt_filter_soft_id,
1198                 NULL,
1199         },
1200 };
1201
1202
1203 cmdline_parse_token_string_t cmd_pkt_filter_upd_perfect_filter =
1204         TOKEN_STRING_INITIALIZER(struct cmd_pkt_filter_result,
1205                                  pkt_filter, "upd_perfect_filter");
1206 cmdline_parse_inst_t cmd_upd_perfect_filter = {
1207         .f = cmd_pkt_filter_parsed,
1208         .data = NULL,
1209         .help_str = "update a perfect filter",
1210         .tokens = {
1211                 (void *)&cmd_pkt_filter_upd_perfect_filter,
1212                 (void *)&cmd_pkt_filter_port_id,
1213                 (void *)&cmd_pkt_filter_protocol,
1214                 (void *)&cmd_pkt_filter_src,
1215                 (void *)&cmd_pkt_filter_ip_src,
1216                 (void *)&cmd_pkt_filter_port_src,
1217                 (void *)&cmd_pkt_filter_dst,
1218                 (void *)&cmd_pkt_filter_ip_dst,
1219                 (void *)&cmd_pkt_filter_port_dst,
1220                 (void *)&cmd_pkt_filter_flexbytes,
1221                 (void *)&cmd_pkt_filter_flexbytes_value,
1222                 (void *)&cmd_pkt_filter_vlan,
1223                 (void *)&cmd_pkt_filter_vlan_id,
1224                 (void *)&cmd_pkt_filter_queue,
1225                 (void *)&cmd_pkt_filter_queue_id,
1226                 (void *)&cmd_pkt_filter_soft,
1227                 (void *)&cmd_pkt_filter_soft_id,
1228                 NULL,
1229         },
1230 };
1231
1232
1233 cmdline_parse_token_string_t cmd_pkt_filter_rm_perfect_filter =
1234         TOKEN_STRING_INITIALIZER(struct cmd_pkt_filter_result,
1235                                  pkt_filter, "rm_perfect_filter");
1236 cmdline_parse_inst_t cmd_rm_perfect_filter = {
1237         .f = cmd_pkt_filter_parsed,
1238         .data = NULL,
1239         .help_str = "remove a perfect filter",
1240         .tokens = {
1241                 (void *)&cmd_pkt_filter_rm_perfect_filter,
1242                 (void *)&cmd_pkt_filter_port_id,
1243                 (void *)&cmd_pkt_filter_protocol,
1244                 (void *)&cmd_pkt_filter_src,
1245                 (void *)&cmd_pkt_filter_ip_src,
1246                 (void *)&cmd_pkt_filter_port_src,
1247                 (void *)&cmd_pkt_filter_dst,
1248                 (void *)&cmd_pkt_filter_ip_dst,
1249                 (void *)&cmd_pkt_filter_port_dst,
1250                 (void *)&cmd_pkt_filter_flexbytes,
1251                 (void *)&cmd_pkt_filter_flexbytes_value,
1252                 (void *)&cmd_pkt_filter_vlan,
1253                 (void *)&cmd_pkt_filter_vlan_id,
1254                 (void *)&cmd_pkt_filter_soft,
1255                 (void *)&cmd_pkt_filter_soft_id,
1256                 NULL,
1257         },
1258 };
1259
1260 /* *** SETUP MASKS FILTER *** */
1261 struct cmd_pkt_filter_masks_result {
1262         cmdline_fixed_string_t filter_mask;
1263         uint8_t  port_id;
1264         cmdline_fixed_string_t src_mask;
1265         uint32_t ip_src_mask;
1266         uint16_t port_src_mask;
1267         cmdline_fixed_string_t dst_mask;
1268         uint32_t ip_dst_mask;
1269         uint16_t port_dst_mask;
1270         cmdline_fixed_string_t flexbytes;
1271         uint8_t flexbytes_value;
1272         cmdline_fixed_string_t vlan_id;
1273         uint8_t  vlan_id_value;
1274         cmdline_fixed_string_t vlan_prio;
1275         uint8_t  vlan_prio_value;
1276         cmdline_fixed_string_t only_ip_flow;
1277         uint8_t  only_ip_flow_value;
1278 };
1279
1280 static void
1281 cmd_pkt_filter_masks_parsed(void *parsed_result,
1282                           __attribute__((unused)) struct cmdline *cl,
1283                           __attribute__((unused)) void *data)
1284 {
1285         struct rte_fdir_masks fdir_masks;
1286         struct cmd_pkt_filter_masks_result *res = parsed_result;
1287
1288         memset(&fdir_masks, 0, sizeof(struct rte_fdir_masks));
1289
1290         fdir_masks.only_ip_flow  = res->only_ip_flow_value;
1291         fdir_masks.vlan_id       = res->vlan_id_value;
1292         fdir_masks.vlan_prio     = res->vlan_prio_value;
1293         fdir_masks.dst_ipv4_mask = res->ip_dst_mask;
1294         fdir_masks.src_ipv4_mask = res->ip_src_mask;
1295         fdir_masks.src_port_mask = res->port_src_mask;
1296         fdir_masks.dst_port_mask = res->port_dst_mask;
1297         fdir_masks.flexbytes     = res->flexbytes_value;
1298
1299         fdir_set_masks(res->port_id, &fdir_masks);
1300 }
1301
1302 cmdline_parse_token_string_t cmd_pkt_filter_masks_filter_mask =
1303         TOKEN_STRING_INITIALIZER(struct cmd_pkt_filter_masks_result,
1304                                  filter_mask, "set_masks_filter");
1305 cmdline_parse_token_num_t cmd_pkt_filter_masks_port_id =
1306         TOKEN_NUM_INITIALIZER(struct cmd_pkt_filter_masks_result,
1307                               port_id, UINT8);
1308 cmdline_parse_token_string_t cmd_pkt_filter_masks_only_ip_flow =
1309         TOKEN_STRING_INITIALIZER(struct cmd_pkt_filter_masks_result,
1310                                  only_ip_flow, "only_ip_flow");
1311 cmdline_parse_token_num_t cmd_pkt_filter_masks_only_ip_flow_value =
1312         TOKEN_NUM_INITIALIZER(struct cmd_pkt_filter_masks_result,
1313                               only_ip_flow_value, UINT8);
1314 cmdline_parse_token_string_t cmd_pkt_filter_masks_src_mask =
1315         TOKEN_STRING_INITIALIZER(struct cmd_pkt_filter_masks_result,
1316                                  src_mask, "src_mask");
1317 cmdline_parse_token_num_t cmd_pkt_filter_masks_ip_src_mask =
1318         TOKEN_NUM_INITIALIZER(struct cmd_pkt_filter_masks_result,
1319                               ip_src_mask, UINT32);
1320 cmdline_parse_token_num_t cmd_pkt_filter_masks_port_src_mask =
1321         TOKEN_NUM_INITIALIZER(struct cmd_pkt_filter_masks_result,
1322                               port_src_mask, UINT16);
1323 cmdline_parse_token_string_t cmd_pkt_filter_masks_dst_mask =
1324         TOKEN_STRING_INITIALIZER(struct cmd_pkt_filter_masks_result,
1325                                  src_mask, "dst_mask");
1326 cmdline_parse_token_num_t cmd_pkt_filter_masks_ip_dst_mask =
1327         TOKEN_NUM_INITIALIZER(struct cmd_pkt_filter_masks_result,
1328                               ip_dst_mask, UINT32);
1329 cmdline_parse_token_num_t cmd_pkt_filter_masks_port_dst_mask =
1330         TOKEN_NUM_INITIALIZER(struct cmd_pkt_filter_masks_result,
1331                               port_dst_mask, UINT16);
1332 cmdline_parse_token_string_t cmd_pkt_filter_masks_flexbytes =
1333         TOKEN_STRING_INITIALIZER(struct cmd_pkt_filter_masks_result,
1334                                  flexbytes, "flexbytes");
1335 cmdline_parse_token_num_t cmd_pkt_filter_masks_flexbytes_value =
1336         TOKEN_NUM_INITIALIZER(struct cmd_pkt_filter_masks_result,
1337                               flexbytes_value, UINT8);
1338 cmdline_parse_token_string_t cmd_pkt_filter_masks_vlan_id =
1339         TOKEN_STRING_INITIALIZER(struct cmd_pkt_filter_masks_result,
1340                                  vlan_id, "vlan_id");
1341 cmdline_parse_token_num_t cmd_pkt_filter_masks_vlan_id_value =
1342         TOKEN_NUM_INITIALIZER(struct cmd_pkt_filter_masks_result,
1343                               vlan_id_value, UINT8);
1344 cmdline_parse_token_string_t cmd_pkt_filter_masks_vlan_prio =
1345         TOKEN_STRING_INITIALIZER(struct cmd_pkt_filter_masks_result,
1346                                  vlan_prio, "vlan_prio");
1347 cmdline_parse_token_num_t cmd_pkt_filter_masks_vlan_prio_value =
1348         TOKEN_NUM_INITIALIZER(struct cmd_pkt_filter_masks_result,
1349                               vlan_prio_value, UINT8);
1350
1351 cmdline_parse_inst_t cmd_set_masks_filter = {
1352         .f = cmd_pkt_filter_masks_parsed,
1353         .data = NULL,
1354         .help_str = "setup masks filter",
1355         .tokens = {
1356                 (void *)&cmd_pkt_filter_masks_filter_mask,
1357                 (void *)&cmd_pkt_filter_masks_port_id,
1358                 (void *)&cmd_pkt_filter_masks_only_ip_flow,
1359                 (void *)&cmd_pkt_filter_masks_only_ip_flow_value,
1360                 (void *)&cmd_pkt_filter_masks_src_mask,
1361                 (void *)&cmd_pkt_filter_masks_ip_src_mask,
1362                 (void *)&cmd_pkt_filter_masks_port_src_mask,
1363                 (void *)&cmd_pkt_filter_masks_dst_mask,
1364                 (void *)&cmd_pkt_filter_masks_ip_dst_mask,
1365                 (void *)&cmd_pkt_filter_masks_port_dst_mask,
1366                 (void *)&cmd_pkt_filter_masks_flexbytes,
1367                 (void *)&cmd_pkt_filter_masks_flexbytes_value,
1368                 (void *)&cmd_pkt_filter_masks_vlan_id,
1369                 (void *)&cmd_pkt_filter_masks_vlan_id_value,
1370                 (void *)&cmd_pkt_filter_masks_vlan_prio,
1371                 (void *)&cmd_pkt_filter_masks_vlan_prio_value,
1372                 NULL,
1373         },
1374 };
1375
1376 /* *** SETUP ETHERNET LINK FLOW CONTROL *** */
1377 struct cmd_link_flow_ctrl_set_result {
1378         cmdline_fixed_string_t set;
1379         cmdline_fixed_string_t flow_ctrl;
1380         cmdline_fixed_string_t rx;
1381         cmdline_fixed_string_t rx_lfc_mode;
1382         cmdline_fixed_string_t tx;
1383         cmdline_fixed_string_t tx_lfc_mode;
1384         uint32_t high_water;
1385         uint32_t low_water;
1386         uint16_t pause_time;
1387         uint16_t send_xon;
1388         uint8_t  port_id;
1389 };
1390
1391 static void
1392 cmd_link_flow_ctrl_set_parsed(void *parsed_result,
1393                        __attribute__((unused)) struct cmdline *cl,
1394                        __attribute__((unused)) void *data)
1395 {
1396         struct cmd_link_flow_ctrl_set_result *res = parsed_result;
1397         struct rte_eth_fc_conf fc_conf;
1398         int rx_fc_enable, tx_fc_enable;
1399         int ret;
1400
1401         /*
1402          * Rx on/off, flow control is enabled/disabled on RX side. This can indicate
1403          * the RTE_FC_TX_PAUSE, Transmit pause frame at the Rx side.
1404          * Tx on/off, flow control is enabled/disabled on TX side. This can indicate
1405          * the RTE_FC_RX_PAUSE, Respond to the pause frame at the Tx side.
1406          */
1407         static enum rte_eth_fc_mode rx_tx_onoff_2_lfc_mode[2][2] = {
1408                         {RTE_FC_NONE, RTE_FC_RX_PAUSE}, {RTE_FC_TX_PAUSE, RTE_FC_FULL}
1409         };
1410
1411         rx_fc_enable = (!strcmp(res->rx_lfc_mode, "on")) ? 1 : 0;
1412         tx_fc_enable = (!strcmp(res->tx_lfc_mode, "on")) ? 1 : 0;
1413
1414         fc_conf.mode       = rx_tx_onoff_2_lfc_mode[rx_fc_enable][tx_fc_enable];
1415         fc_conf.high_water = res->high_water;
1416         fc_conf.low_water  = res->low_water;
1417         fc_conf.pause_time = res->pause_time;
1418         fc_conf.send_xon   = res->send_xon;
1419
1420         ret = rte_eth_dev_flow_ctrl_set(res->port_id, &fc_conf);
1421         if (ret != 0)
1422                 printf("bad flow contrl parameter, return code = %d \n", ret);
1423 }
1424
1425 cmdline_parse_token_string_t cmd_lfc_set_set =
1426         TOKEN_STRING_INITIALIZER(struct cmd_link_flow_ctrl_set_result,
1427                                 set, "set");
1428 cmdline_parse_token_string_t cmd_lfc_set_flow_ctrl =
1429         TOKEN_STRING_INITIALIZER(struct cmd_link_flow_ctrl_set_result,
1430                                 flow_ctrl, "flow_ctrl");
1431 cmdline_parse_token_string_t cmd_lfc_set_rx =
1432         TOKEN_STRING_INITIALIZER(struct cmd_link_flow_ctrl_set_result,
1433                                 rx, "rx");
1434 cmdline_parse_token_string_t cmd_lfc_set_rx_mode =
1435         TOKEN_STRING_INITIALIZER(struct cmd_link_flow_ctrl_set_result,
1436                                 rx_lfc_mode, "on#off");
1437 cmdline_parse_token_string_t cmd_lfc_set_tx =
1438         TOKEN_STRING_INITIALIZER(struct cmd_link_flow_ctrl_set_result,
1439                                 tx, "tx");
1440 cmdline_parse_token_string_t cmd_lfc_set_tx_mode =
1441         TOKEN_STRING_INITIALIZER(struct cmd_link_flow_ctrl_set_result,
1442                                 tx_lfc_mode, "on#off");
1443 cmdline_parse_token_num_t cmd_lfc_set_high_water =
1444         TOKEN_NUM_INITIALIZER(struct cmd_link_flow_ctrl_set_result,
1445                                 high_water, UINT32);
1446 cmdline_parse_token_num_t cmd_lfc_set_low_water =
1447         TOKEN_NUM_INITIALIZER(struct cmd_link_flow_ctrl_set_result,
1448                                 low_water, UINT32);
1449 cmdline_parse_token_num_t cmd_lfc_set_pause_time =
1450         TOKEN_NUM_INITIALIZER(struct cmd_link_flow_ctrl_set_result,
1451                                 pause_time, UINT16);
1452 cmdline_parse_token_num_t cmd_lfc_set_send_xon =
1453         TOKEN_NUM_INITIALIZER(struct cmd_link_flow_ctrl_set_result,
1454                                 send_xon, UINT16);
1455 cmdline_parse_token_num_t cmd_lfc_set_portid =
1456         TOKEN_NUM_INITIALIZER(struct cmd_link_flow_ctrl_set_result,
1457                                 port_id, UINT8);
1458
1459 cmdline_parse_inst_t cmd_link_flow_control_set = {
1460         .f = cmd_link_flow_ctrl_set_parsed,
1461         .data = NULL,
1462         .help_str = "Configure the Ethernet link flow control...",
1463         .tokens = {
1464                 (void *)&cmd_lfc_set_set,
1465                 (void *)&cmd_lfc_set_flow_ctrl,
1466                 (void *)&cmd_lfc_set_rx,
1467                 (void *)&cmd_lfc_set_rx_mode,
1468                 (void *)&cmd_lfc_set_tx,
1469                 (void *)&cmd_lfc_set_tx_mode,
1470                 (void *)&cmd_lfc_set_high_water,
1471                 (void *)&cmd_lfc_set_low_water,
1472                 (void *)&cmd_lfc_set_pause_time,
1473                 (void *)&cmd_lfc_set_send_xon,
1474                 (void *)&cmd_lfc_set_portid,
1475                 NULL,
1476         },
1477 };
1478
1479 /* *** RESET CONFIGURATION *** */
1480 struct cmd_reset_result {
1481         cmdline_fixed_string_t reset;
1482         cmdline_fixed_string_t def;
1483 };
1484
1485 static void cmd_reset_parsed(__attribute__((unused)) void *parsed_result,
1486                              struct cmdline *cl,
1487                              __attribute__((unused)) void *data)
1488 {
1489         cmdline_printf(cl, "Reset to default forwarding configuration...\n");
1490         set_def_fwd_config();
1491 }
1492
1493 cmdline_parse_token_string_t cmd_reset_set =
1494         TOKEN_STRING_INITIALIZER(struct cmd_reset_result, reset, "set");
1495 cmdline_parse_token_string_t cmd_reset_def =
1496         TOKEN_STRING_INITIALIZER(struct cmd_reset_result, def,
1497                                  "default");
1498
1499 cmdline_parse_inst_t cmd_reset = {
1500         .f = cmd_reset_parsed,
1501         .data = NULL,
1502         .help_str = "set default: reset default forwarding configuration",
1503         .tokens = {
1504                 (void *)&cmd_reset_set,
1505                 (void *)&cmd_reset_def,
1506                 NULL,
1507         },
1508 };
1509
1510 /* *** START FORWARDING *** */
1511 struct cmd_start_result {
1512         cmdline_fixed_string_t start;
1513 };
1514
1515 cmdline_parse_token_string_t cmd_start_start =
1516         TOKEN_STRING_INITIALIZER(struct cmd_start_result, start, "start");
1517
1518 static void cmd_start_parsed(__attribute__((unused)) void *parsed_result,
1519                              __attribute__((unused)) struct cmdline *cl,
1520                              __attribute__((unused)) void *data)
1521 {
1522         start_packet_forwarding(0);
1523 }
1524
1525 cmdline_parse_inst_t cmd_start = {
1526         .f = cmd_start_parsed,
1527         .data = NULL,
1528         .help_str = "start packet forwarding",
1529         .tokens = {
1530                 (void *)&cmd_start_start,
1531                 NULL,
1532         },
1533 };
1534
1535 /* *** START FORWARDING WITH ONE TX BURST FIRST *** */
1536 struct cmd_start_tx_first_result {
1537         cmdline_fixed_string_t start;
1538         cmdline_fixed_string_t tx_first;
1539 };
1540
1541 static void
1542 cmd_start_tx_first_parsed(__attribute__((unused)) void *parsed_result,
1543                           __attribute__((unused)) struct cmdline *cl,
1544                           __attribute__((unused)) void *data)
1545 {
1546         start_packet_forwarding(1);
1547 }
1548
1549 cmdline_parse_token_string_t cmd_start_tx_first_start =
1550         TOKEN_STRING_INITIALIZER(struct cmd_start_tx_first_result, start,
1551                                  "start");
1552 cmdline_parse_token_string_t cmd_start_tx_first_tx_first =
1553         TOKEN_STRING_INITIALIZER(struct cmd_start_tx_first_result,
1554                                  tx_first, "tx_first");
1555
1556 cmdline_parse_inst_t cmd_start_tx_first = {
1557         .f = cmd_start_tx_first_parsed,
1558         .data = NULL,
1559         .help_str = "start packet forwarding, after sending 1 burst of packets",
1560         .tokens = {
1561                 (void *)&cmd_start_tx_first_start,
1562                 (void *)&cmd_start_tx_first_tx_first,
1563                 NULL,
1564         },
1565 };
1566
1567 /* *** SHOW CFG *** */
1568 struct cmd_showcfg_result {
1569         cmdline_fixed_string_t show;
1570         cmdline_fixed_string_t cfg;
1571         cmdline_fixed_string_t what;
1572 };
1573
1574 static void cmd_showcfg_parsed(void *parsed_result,
1575                                __attribute__((unused)) struct cmdline *cl,
1576                                __attribute__((unused)) void *data)
1577 {
1578         struct cmd_showcfg_result *res = parsed_result;
1579         if (!strcmp(res->what, "rxtx"))
1580                 rxtx_config_display();
1581         else if (!strcmp(res->what, "cores"))
1582                 fwd_lcores_config_display();
1583         else if (!strcmp(res->what, "fwd"))
1584                 fwd_config_display();
1585 }
1586
1587 cmdline_parse_token_string_t cmd_showcfg_show =
1588         TOKEN_STRING_INITIALIZER(struct cmd_showcfg_result, show, "show");
1589 cmdline_parse_token_string_t cmd_showcfg_port =
1590         TOKEN_STRING_INITIALIZER(struct cmd_showcfg_result, cfg, "config");
1591 cmdline_parse_token_string_t cmd_showcfg_what =
1592         TOKEN_STRING_INITIALIZER(struct cmd_showcfg_result, what,
1593                                  "rxtx#cores#fwd");
1594
1595 cmdline_parse_inst_t cmd_showcfg = {
1596         .f = cmd_showcfg_parsed,
1597         .data = NULL,
1598         .help_str = "show config rxtx|cores|fwd",
1599         .tokens = {
1600                 (void *)&cmd_showcfg_show,
1601                 (void *)&cmd_showcfg_port,
1602                 (void *)&cmd_showcfg_what,
1603                 NULL,
1604         },
1605 };
1606
1607 /* *** SHOW ALL PORT INFO *** */
1608 struct cmd_showportall_result {
1609         cmdline_fixed_string_t show;
1610         cmdline_fixed_string_t port;
1611         cmdline_fixed_string_t what;
1612         cmdline_fixed_string_t all;
1613 };
1614
1615 static void cmd_showportall_parsed(void *parsed_result,
1616                                 __attribute__((unused)) struct cmdline *cl,
1617                                 __attribute__((unused)) void *data)
1618 {
1619         portid_t i;
1620
1621         struct cmd_showportall_result *res = parsed_result;
1622         if (!strcmp(res->show, "clear")) {
1623                 if (!strcmp(res->what, "stats"))
1624                         for (i = 0; i < nb_ports; i++)
1625                                 nic_stats_clear(i);
1626         } else if (!strcmp(res->what, "info"))
1627                 for (i = 0; i < nb_ports; i++)
1628                         port_infos_display(i);
1629         else if (!strcmp(res->what, "stats"))
1630                 for (i = 0; i < nb_ports; i++)
1631                         nic_stats_display(i);
1632         else if (!strcmp(res->what, "fdir"))
1633                 for (i = 0; i < nb_ports; i++)
1634                         fdir_get_infos(i);
1635 }
1636
1637 cmdline_parse_token_string_t cmd_showportall_show =
1638         TOKEN_STRING_INITIALIZER(struct cmd_showportall_result, show,
1639                                  "show#clear");
1640 cmdline_parse_token_string_t cmd_showportall_port =
1641         TOKEN_STRING_INITIALIZER(struct cmd_showportall_result, port, "port");
1642 cmdline_parse_token_string_t cmd_showportall_what =
1643         TOKEN_STRING_INITIALIZER(struct cmd_showportall_result, what,
1644                                  "info#stats#fdir");
1645 cmdline_parse_token_string_t cmd_showportall_all =
1646         TOKEN_STRING_INITIALIZER(struct cmd_showportall_result, all, "all");
1647 cmdline_parse_inst_t cmd_showportall = {
1648         .f = cmd_showportall_parsed,
1649         .data = NULL,
1650         .help_str = "show|clear port info|stats|fdir all",
1651         .tokens = {
1652                 (void *)&cmd_showportall_show,
1653                 (void *)&cmd_showportall_port,
1654                 (void *)&cmd_showportall_what,
1655                 (void *)&cmd_showportall_all,
1656                 NULL,
1657         },
1658 };
1659
1660 /* *** SHOW PORT INFO *** */
1661 struct cmd_showport_result {
1662         cmdline_fixed_string_t show;
1663         cmdline_fixed_string_t port;
1664         cmdline_fixed_string_t what;
1665         uint8_t portnum;
1666 };
1667
1668 static void cmd_showport_parsed(void *parsed_result,
1669                                 __attribute__((unused)) struct cmdline *cl,
1670                                 __attribute__((unused)) void *data)
1671 {
1672         struct cmd_showport_result *res = parsed_result;
1673         if (!strcmp(res->show, "clear")) {
1674                 if (!strcmp(res->what, "stats"))
1675                         nic_stats_clear(res->portnum);
1676         } else if (!strcmp(res->what, "info"))
1677                 port_infos_display(res->portnum);
1678         else if (!strcmp(res->what, "stats"))
1679                 nic_stats_display(res->portnum);
1680         else if (!strcmp(res->what, "fdir"))
1681                  fdir_get_infos(res->portnum);
1682 }
1683
1684 cmdline_parse_token_string_t cmd_showport_show =
1685         TOKEN_STRING_INITIALIZER(struct cmd_showport_result, show,
1686                                  "show#clear");
1687 cmdline_parse_token_string_t cmd_showport_port =
1688         TOKEN_STRING_INITIALIZER(struct cmd_showport_result, port, "port");
1689 cmdline_parse_token_string_t cmd_showport_what =
1690         TOKEN_STRING_INITIALIZER(struct cmd_showport_result, what,
1691                                  "info#stats#fdir");
1692 cmdline_parse_token_num_t cmd_showport_portnum =
1693         TOKEN_NUM_INITIALIZER(struct cmd_showport_result, portnum, INT32);
1694
1695 cmdline_parse_inst_t cmd_showport = {
1696         .f = cmd_showport_parsed,
1697         .data = NULL,
1698         .help_str = "show|clear port info|stats|fdir X (X = port number)",
1699         .tokens = {
1700                 (void *)&cmd_showport_show,
1701                 (void *)&cmd_showport_port,
1702                 (void *)&cmd_showport_what,
1703                 (void *)&cmd_showport_portnum,
1704                 NULL,
1705         },
1706 };
1707
1708 /* *** READ PORT REGISTER *** */
1709 struct cmd_read_reg_result {
1710         cmdline_fixed_string_t read;
1711         cmdline_fixed_string_t reg;
1712         uint8_t port_id;
1713         uint32_t reg_off;
1714 };
1715
1716 static void
1717 cmd_read_reg_parsed(void *parsed_result,
1718                     __attribute__((unused)) struct cmdline *cl,
1719                     __attribute__((unused)) void *data)
1720 {
1721         struct cmd_read_reg_result *res = parsed_result;
1722         port_reg_display(res->port_id, res->reg_off);
1723 }
1724
1725 cmdline_parse_token_string_t cmd_read_reg_read =
1726         TOKEN_STRING_INITIALIZER(struct cmd_read_reg_result, read, "read");
1727 cmdline_parse_token_string_t cmd_read_reg_reg =
1728         TOKEN_STRING_INITIALIZER(struct cmd_read_reg_result, reg, "reg");
1729 cmdline_parse_token_num_t cmd_read_reg_port_id =
1730         TOKEN_NUM_INITIALIZER(struct cmd_read_reg_result, port_id, UINT8);
1731 cmdline_parse_token_num_t cmd_read_reg_reg_off =
1732         TOKEN_NUM_INITIALIZER(struct cmd_read_reg_result, reg_off, UINT32);
1733
1734 cmdline_parse_inst_t cmd_read_reg = {
1735         .f = cmd_read_reg_parsed,
1736         .data = NULL,
1737         .help_str = "read reg port_id reg_off",
1738         .tokens = {
1739                 (void *)&cmd_read_reg_read,
1740                 (void *)&cmd_read_reg_reg,
1741                 (void *)&cmd_read_reg_port_id,
1742                 (void *)&cmd_read_reg_reg_off,
1743                 NULL,
1744         },
1745 };
1746
1747 /* *** READ PORT REGISTER BIT FIELD *** */
1748 struct cmd_read_reg_bit_field_result {
1749         cmdline_fixed_string_t read;
1750         cmdline_fixed_string_t regfield;
1751         uint8_t port_id;
1752         uint32_t reg_off;
1753         uint8_t bit1_pos;
1754         uint8_t bit2_pos;
1755 };
1756
1757 static void
1758 cmd_read_reg_bit_field_parsed(void *parsed_result,
1759                               __attribute__((unused)) struct cmdline *cl,
1760                               __attribute__((unused)) void *data)
1761 {
1762         struct cmd_read_reg_bit_field_result *res = parsed_result;
1763         port_reg_bit_field_display(res->port_id, res->reg_off,
1764                                    res->bit1_pos, res->bit2_pos);
1765 }
1766
1767 cmdline_parse_token_string_t cmd_read_reg_bit_field_read =
1768         TOKEN_STRING_INITIALIZER(struct cmd_read_reg_bit_field_result, read,
1769                                  "read");
1770 cmdline_parse_token_string_t cmd_read_reg_bit_field_regfield =
1771         TOKEN_STRING_INITIALIZER(struct cmd_read_reg_bit_field_result,
1772                                  regfield, "regfield");
1773 cmdline_parse_token_num_t cmd_read_reg_bit_field_port_id =
1774         TOKEN_NUM_INITIALIZER(struct cmd_read_reg_bit_field_result, port_id,
1775                               UINT8);
1776 cmdline_parse_token_num_t cmd_read_reg_bit_field_reg_off =
1777         TOKEN_NUM_INITIALIZER(struct cmd_read_reg_bit_field_result, reg_off,
1778                               UINT32);
1779 cmdline_parse_token_num_t cmd_read_reg_bit_field_bit1_pos =
1780         TOKEN_NUM_INITIALIZER(struct cmd_read_reg_bit_field_result, bit1_pos,
1781                               UINT8);
1782 cmdline_parse_token_num_t cmd_read_reg_bit_field_bit2_pos =
1783         TOKEN_NUM_INITIALIZER(struct cmd_read_reg_bit_field_result, bit2_pos,
1784                               UINT8);
1785
1786 cmdline_parse_inst_t cmd_read_reg_bit_field = {
1787         .f = cmd_read_reg_bit_field_parsed,
1788         .data = NULL,
1789         .help_str = "read regfield port_id reg_off bit_x bit_y "
1790         "(read register bit field between bit_x and bit_y included)",
1791         .tokens = {
1792                 (void *)&cmd_read_reg_bit_field_read,
1793                 (void *)&cmd_read_reg_bit_field_regfield,
1794                 (void *)&cmd_read_reg_bit_field_port_id,
1795                 (void *)&cmd_read_reg_bit_field_reg_off,
1796                 (void *)&cmd_read_reg_bit_field_bit1_pos,
1797                 (void *)&cmd_read_reg_bit_field_bit2_pos,
1798                 NULL,
1799         },
1800 };
1801
1802 /* *** READ PORT REGISTER BIT *** */
1803 struct cmd_read_reg_bit_result {
1804         cmdline_fixed_string_t read;
1805         cmdline_fixed_string_t regbit;
1806         uint8_t port_id;
1807         uint32_t reg_off;
1808         uint8_t bit_pos;
1809 };
1810
1811 static void
1812 cmd_read_reg_bit_parsed(void *parsed_result,
1813                         __attribute__((unused)) struct cmdline *cl,
1814                         __attribute__((unused)) void *data)
1815 {
1816         struct cmd_read_reg_bit_result *res = parsed_result;
1817         port_reg_bit_display(res->port_id, res->reg_off, res->bit_pos);
1818 }
1819
1820 cmdline_parse_token_string_t cmd_read_reg_bit_read =
1821         TOKEN_STRING_INITIALIZER(struct cmd_read_reg_bit_result, read, "read");
1822 cmdline_parse_token_string_t cmd_read_reg_bit_regbit =
1823         TOKEN_STRING_INITIALIZER(struct cmd_read_reg_bit_result,
1824                                  regbit, "regbit");
1825 cmdline_parse_token_num_t cmd_read_reg_bit_port_id =
1826         TOKEN_NUM_INITIALIZER(struct cmd_read_reg_bit_result, port_id, UINT8);
1827 cmdline_parse_token_num_t cmd_read_reg_bit_reg_off =
1828         TOKEN_NUM_INITIALIZER(struct cmd_read_reg_bit_result, reg_off, UINT32);
1829 cmdline_parse_token_num_t cmd_read_reg_bit_bit_pos =
1830         TOKEN_NUM_INITIALIZER(struct cmd_read_reg_bit_result, bit_pos, UINT8);
1831
1832 cmdline_parse_inst_t cmd_read_reg_bit = {
1833         .f = cmd_read_reg_bit_parsed,
1834         .data = NULL,
1835         .help_str = "read regbit port_id reg_off bit_x (0 <= bit_x <= 31)",
1836         .tokens = {
1837                 (void *)&cmd_read_reg_bit_read,
1838                 (void *)&cmd_read_reg_bit_regbit,
1839                 (void *)&cmd_read_reg_bit_port_id,
1840                 (void *)&cmd_read_reg_bit_reg_off,
1841                 (void *)&cmd_read_reg_bit_bit_pos,
1842                 NULL,
1843         },
1844 };
1845
1846 /* *** WRITE PORT REGISTER *** */
1847 struct cmd_write_reg_result {
1848         cmdline_fixed_string_t write;
1849         cmdline_fixed_string_t reg;
1850         uint8_t port_id;
1851         uint32_t reg_off;
1852         uint32_t value;
1853 };
1854
1855 static void
1856 cmd_write_reg_parsed(void *parsed_result,
1857                      __attribute__((unused)) struct cmdline *cl,
1858                      __attribute__((unused)) void *data)
1859 {
1860         struct cmd_write_reg_result *res = parsed_result;
1861         port_reg_set(res->port_id, res->reg_off, res->value);
1862 }
1863
1864 cmdline_parse_token_string_t cmd_write_reg_write =
1865         TOKEN_STRING_INITIALIZER(struct cmd_write_reg_result, write, "write");
1866 cmdline_parse_token_string_t cmd_write_reg_reg =
1867         TOKEN_STRING_INITIALIZER(struct cmd_write_reg_result, reg, "reg");
1868 cmdline_parse_token_num_t cmd_write_reg_port_id =
1869         TOKEN_NUM_INITIALIZER(struct cmd_write_reg_result, port_id, UINT8);
1870 cmdline_parse_token_num_t cmd_write_reg_reg_off =
1871         TOKEN_NUM_INITIALIZER(struct cmd_write_reg_result, reg_off, UINT32);
1872 cmdline_parse_token_num_t cmd_write_reg_value =
1873         TOKEN_NUM_INITIALIZER(struct cmd_write_reg_result, value, UINT32);
1874
1875 cmdline_parse_inst_t cmd_write_reg = {
1876         .f = cmd_write_reg_parsed,
1877         .data = NULL,
1878         .help_str = "write reg port_id reg_off reg_value",
1879         .tokens = {
1880                 (void *)&cmd_write_reg_write,
1881                 (void *)&cmd_write_reg_reg,
1882                 (void *)&cmd_write_reg_port_id,
1883                 (void *)&cmd_write_reg_reg_off,
1884                 (void *)&cmd_write_reg_value,
1885                 NULL,
1886         },
1887 };
1888
1889 /* *** WRITE PORT REGISTER BIT FIELD *** */
1890 struct cmd_write_reg_bit_field_result {
1891         cmdline_fixed_string_t write;
1892         cmdline_fixed_string_t regfield;
1893         uint8_t port_id;
1894         uint32_t reg_off;
1895         uint8_t bit1_pos;
1896         uint8_t bit2_pos;
1897         uint32_t value;
1898 };
1899
1900 static void
1901 cmd_write_reg_bit_field_parsed(void *parsed_result,
1902                                __attribute__((unused)) struct cmdline *cl,
1903                                __attribute__((unused)) void *data)
1904 {
1905         struct cmd_write_reg_bit_field_result *res = parsed_result;
1906         port_reg_bit_field_set(res->port_id, res->reg_off,
1907                           res->bit1_pos, res->bit2_pos, res->value);
1908 }
1909
1910 cmdline_parse_token_string_t cmd_write_reg_bit_field_write =
1911         TOKEN_STRING_INITIALIZER(struct cmd_write_reg_bit_field_result, write,
1912                                  "write");
1913 cmdline_parse_token_string_t cmd_write_reg_bit_field_regfield =
1914         TOKEN_STRING_INITIALIZER(struct cmd_write_reg_bit_field_result,
1915                                  regfield, "regfield");
1916 cmdline_parse_token_num_t cmd_write_reg_bit_field_port_id =
1917         TOKEN_NUM_INITIALIZER(struct cmd_write_reg_bit_field_result, port_id,
1918                               UINT8);
1919 cmdline_parse_token_num_t cmd_write_reg_bit_field_reg_off =
1920         TOKEN_NUM_INITIALIZER(struct cmd_write_reg_bit_field_result, reg_off,
1921                               UINT32);
1922 cmdline_parse_token_num_t cmd_write_reg_bit_field_bit1_pos =
1923         TOKEN_NUM_INITIALIZER(struct cmd_write_reg_bit_field_result, bit1_pos,
1924                               UINT8);
1925 cmdline_parse_token_num_t cmd_write_reg_bit_field_bit2_pos =
1926         TOKEN_NUM_INITIALIZER(struct cmd_write_reg_bit_field_result, bit2_pos,
1927                               UINT8);
1928 cmdline_parse_token_num_t cmd_write_reg_bit_field_value =
1929         TOKEN_NUM_INITIALIZER(struct cmd_write_reg_bit_field_result, value,
1930                               UINT32);
1931
1932 cmdline_parse_inst_t cmd_write_reg_bit_field = {
1933         .f = cmd_write_reg_bit_field_parsed,
1934         .data = NULL,
1935         .help_str = "write regfield port_id reg_off bit_x bit_y reg_value"
1936         "(set register bit field between bit_x and bit_y included)",
1937         .tokens = {
1938                 (void *)&cmd_write_reg_bit_field_write,
1939                 (void *)&cmd_write_reg_bit_field_regfield,
1940                 (void *)&cmd_write_reg_bit_field_port_id,
1941                 (void *)&cmd_write_reg_bit_field_reg_off,
1942                 (void *)&cmd_write_reg_bit_field_bit1_pos,
1943                 (void *)&cmd_write_reg_bit_field_bit2_pos,
1944                 (void *)&cmd_write_reg_bit_field_value,
1945                 NULL,
1946         },
1947 };
1948
1949 /* *** WRITE PORT REGISTER BIT *** */
1950 struct cmd_write_reg_bit_result {
1951         cmdline_fixed_string_t write;
1952         cmdline_fixed_string_t regbit;
1953         uint8_t port_id;
1954         uint32_t reg_off;
1955         uint8_t bit_pos;
1956         uint8_t value;
1957 };
1958
1959 static void
1960 cmd_write_reg_bit_parsed(void *parsed_result,
1961                          __attribute__((unused)) struct cmdline *cl,
1962                          __attribute__((unused)) void *data)
1963 {
1964         struct cmd_write_reg_bit_result *res = parsed_result;
1965         port_reg_bit_set(res->port_id, res->reg_off, res->bit_pos, res->value);
1966 }
1967
1968 cmdline_parse_token_string_t cmd_write_reg_bit_write =
1969         TOKEN_STRING_INITIALIZER(struct cmd_write_reg_bit_result, write,
1970                                  "write");
1971 cmdline_parse_token_string_t cmd_write_reg_bit_regbit =
1972         TOKEN_STRING_INITIALIZER(struct cmd_write_reg_bit_result,
1973                                  regbit, "regbit");
1974 cmdline_parse_token_num_t cmd_write_reg_bit_port_id =
1975         TOKEN_NUM_INITIALIZER(struct cmd_write_reg_bit_result, port_id, UINT8);
1976 cmdline_parse_token_num_t cmd_write_reg_bit_reg_off =
1977         TOKEN_NUM_INITIALIZER(struct cmd_write_reg_bit_result, reg_off, UINT32);
1978 cmdline_parse_token_num_t cmd_write_reg_bit_bit_pos =
1979         TOKEN_NUM_INITIALIZER(struct cmd_write_reg_bit_result, bit_pos, UINT8);
1980 cmdline_parse_token_num_t cmd_write_reg_bit_value =
1981         TOKEN_NUM_INITIALIZER(struct cmd_write_reg_bit_result, value, UINT8);
1982
1983 cmdline_parse_inst_t cmd_write_reg_bit = {
1984         .f = cmd_write_reg_bit_parsed,
1985         .data = NULL,
1986         .help_str = "write regbit port_id reg_off bit_x 0/1 (0 <= bit_x <= 31)",
1987         .tokens = {
1988                 (void *)&cmd_write_reg_bit_write,
1989                 (void *)&cmd_write_reg_bit_regbit,
1990                 (void *)&cmd_write_reg_bit_port_id,
1991                 (void *)&cmd_write_reg_bit_reg_off,
1992                 (void *)&cmd_write_reg_bit_bit_pos,
1993                 (void *)&cmd_write_reg_bit_value,
1994                 NULL,
1995         },
1996 };
1997
1998 /* *** READ A RING DESCRIPTOR OF A PORT RX/TX QUEUE *** */
1999 struct cmd_read_rxd_txd_result {
2000         cmdline_fixed_string_t read;
2001         cmdline_fixed_string_t rxd_txd;
2002         uint8_t port_id;
2003         uint16_t queue_id;
2004         uint16_t desc_id;
2005 };
2006
2007 static void
2008 cmd_read_rxd_txd_parsed(void *parsed_result,
2009                         __attribute__((unused)) struct cmdline *cl,
2010                         __attribute__((unused)) void *data)
2011 {
2012         struct cmd_read_rxd_txd_result *res = parsed_result;
2013
2014         if (!strcmp(res->rxd_txd, "rxd"))
2015                 rx_ring_desc_display(res->port_id, res->queue_id, res->desc_id);
2016         else if (!strcmp(res->rxd_txd, "txd"))
2017                 tx_ring_desc_display(res->port_id, res->queue_id, res->desc_id);
2018 }
2019
2020 cmdline_parse_token_string_t cmd_read_rxd_txd_read =
2021         TOKEN_STRING_INITIALIZER(struct cmd_read_rxd_txd_result, read, "read");
2022 cmdline_parse_token_string_t cmd_read_rxd_txd_rxd_txd =
2023         TOKEN_STRING_INITIALIZER(struct cmd_read_rxd_txd_result, rxd_txd,
2024                                  "rxd#txd");
2025 cmdline_parse_token_num_t cmd_read_rxd_txd_port_id =
2026         TOKEN_NUM_INITIALIZER(struct cmd_read_rxd_txd_result, port_id, UINT8);
2027 cmdline_parse_token_num_t cmd_read_rxd_txd_queue_id =
2028         TOKEN_NUM_INITIALIZER(struct cmd_read_rxd_txd_result, queue_id, UINT16);
2029 cmdline_parse_token_num_t cmd_read_rxd_txd_desc_id =
2030         TOKEN_NUM_INITIALIZER(struct cmd_read_rxd_txd_result, desc_id, UINT16);
2031
2032 cmdline_parse_inst_t cmd_read_rxd_txd = {
2033         .f = cmd_read_rxd_txd_parsed,
2034         .data = NULL,
2035         .help_str = "read rxd|txd port_id queue_id rxd_id",
2036         .tokens = {
2037                 (void *)&cmd_read_rxd_txd_read,
2038                 (void *)&cmd_read_rxd_txd_rxd_txd,
2039                 (void *)&cmd_read_rxd_txd_port_id,
2040                 (void *)&cmd_read_rxd_txd_queue_id,
2041                 (void *)&cmd_read_rxd_txd_desc_id,
2042                 NULL,
2043         },
2044 };
2045
2046 /* *** QUIT *** */
2047 struct cmd_quit_result {
2048         cmdline_fixed_string_t quit;
2049 };
2050
2051 static void cmd_quit_parsed(__attribute__((unused)) void *parsed_result,
2052                             struct cmdline *cl,
2053                             __attribute__((unused)) void *data)
2054 {
2055         pmd_test_exit();
2056         cmdline_quit(cl);
2057 }
2058
2059 cmdline_parse_token_string_t cmd_quit_quit =
2060         TOKEN_STRING_INITIALIZER(struct cmd_quit_result, quit, "quit");
2061
2062 cmdline_parse_inst_t cmd_quit = {
2063         .f = cmd_quit_parsed,
2064         .data = NULL,
2065         .help_str = "exit application",
2066         .tokens = {
2067                 (void *)&cmd_quit_quit,
2068                 NULL,
2069         },
2070 };
2071
2072 /* *** ADD/REMOVE MAC ADDRESS FROM A PORT *** */
2073 struct cmd_mac_addr_result {
2074         cmdline_fixed_string_t mac_addr_cmd;
2075         cmdline_fixed_string_t what;
2076         uint8_t port_num;
2077         struct ether_addr address;
2078 };
2079
2080 static void cmd_mac_addr_parsed(void *parsed_result,
2081                 __attribute__((unused)) struct cmdline *cl,
2082                 __attribute__((unused)) void *data)
2083 {
2084         struct cmd_mac_addr_result *res = parsed_result;
2085         int ret;
2086
2087         if (strcmp(res->what, "add") == 0)
2088                 ret = rte_eth_dev_mac_addr_add(res->port_num, &res->address, 0);
2089         else
2090                 ret = rte_eth_dev_mac_addr_remove(res->port_num, &res->address);
2091
2092         /* check the return value and print it if is < 0 */
2093         if(ret < 0)
2094                 printf("mac_addr_cmd error: (%s)\n", strerror(-ret));
2095
2096 }
2097
2098 cmdline_parse_token_string_t cmd_mac_addr_cmd =
2099         TOKEN_STRING_INITIALIZER(struct cmd_mac_addr_result, mac_addr_cmd,
2100                                 "mac_addr");
2101 cmdline_parse_token_string_t cmd_mac_addr_what =
2102         TOKEN_STRING_INITIALIZER(struct cmd_mac_addr_result, what,
2103                                 "add#remove");
2104 cmdline_parse_token_num_t cmd_mac_addr_portnum =
2105                 TOKEN_NUM_INITIALIZER(struct cmd_mac_addr_result, port_num, UINT8);
2106 cmdline_parse_token_string_t cmd_mac_addr_addr =
2107                 TOKEN_ETHERADDR_INITIALIZER(struct cmd_mac_addr_result, address);
2108
2109 cmdline_parse_inst_t cmd_mac_addr = {
2110         .f = cmd_mac_addr_parsed,
2111         .data = (void *)0,
2112         .help_str = "mac_addr add|remove X <address>: "
2113                         "add/remove MAC address on port X",
2114         .tokens = {
2115                 (void *)&cmd_mac_addr_cmd,
2116                 (void *)&cmd_mac_addr_what,
2117                 (void *)&cmd_mac_addr_portnum,
2118                 (void *)&cmd_mac_addr_addr,
2119                 NULL,
2120         },
2121 };
2122
2123
2124 /* list of instructions */
2125 cmdline_parse_ctx_t main_ctx[] = {
2126         (cmdline_parse_inst_t *)&cmd_help,
2127         (cmdline_parse_inst_t *)&cmd_quit,
2128         (cmdline_parse_inst_t *)&cmd_showport,
2129         (cmdline_parse_inst_t *)&cmd_showportall,
2130         (cmdline_parse_inst_t *)&cmd_showcfg,
2131         (cmdline_parse_inst_t *)&cmd_start,
2132         (cmdline_parse_inst_t *)&cmd_start_tx_first,
2133         (cmdline_parse_inst_t *)&cmd_reset,
2134         (cmdline_parse_inst_t *)&cmd_set_numbers,
2135         (cmdline_parse_inst_t *)&cmd_set_txpkts,
2136         (cmdline_parse_inst_t *)&cmd_set_fwd_list,
2137         (cmdline_parse_inst_t *)&cmd_set_fwd_mask,
2138         (cmdline_parse_inst_t *)&cmd_set_fwd_mode,
2139         (cmdline_parse_inst_t *)&cmd_set_promisc_mode_one,
2140         (cmdline_parse_inst_t *)&cmd_set_promisc_mode_all,
2141         (cmdline_parse_inst_t *)&cmd_set_allmulti_mode_one,
2142         (cmdline_parse_inst_t *)&cmd_set_allmulti_mode_all,
2143         (cmdline_parse_inst_t *)&cmd_rx_vlan_filter_all,
2144         (cmdline_parse_inst_t *)&cmd_rx_vlan_filter,
2145         (cmdline_parse_inst_t *)&cmd_tx_vlan_set,
2146         (cmdline_parse_inst_t *)&cmd_tx_vlan_reset,
2147         (cmdline_parse_inst_t *)&cmd_tx_cksum_set,
2148         (cmdline_parse_inst_t *)&cmd_link_flow_control_set,
2149         (cmdline_parse_inst_t *)&cmd_read_reg,
2150         (cmdline_parse_inst_t *)&cmd_read_reg_bit_field,
2151         (cmdline_parse_inst_t *)&cmd_read_reg_bit,
2152         (cmdline_parse_inst_t *)&cmd_write_reg,
2153         (cmdline_parse_inst_t *)&cmd_write_reg_bit_field,
2154         (cmdline_parse_inst_t *)&cmd_write_reg_bit,
2155         (cmdline_parse_inst_t *)&cmd_read_rxd_txd,
2156         (cmdline_parse_inst_t *)&cmd_add_signature_filter,
2157         (cmdline_parse_inst_t *)&cmd_upd_signature_filter,
2158         (cmdline_parse_inst_t *)&cmd_rm_signature_filter,
2159         (cmdline_parse_inst_t *)&cmd_add_perfect_filter,
2160         (cmdline_parse_inst_t *)&cmd_upd_perfect_filter,
2161         (cmdline_parse_inst_t *)&cmd_rm_perfect_filter,
2162         (cmdline_parse_inst_t *)&cmd_set_masks_filter,
2163         (cmdline_parse_inst_t *)&cmd_stop,
2164         (cmdline_parse_inst_t *)&cmd_mac_addr,
2165         NULL,
2166 };
2167
2168 /* prompt function, called from main on MASTER lcore */
2169 void
2170 prompt(void)
2171 {
2172         struct cmdline *cl;
2173
2174         cl = cmdline_stdin_new(main_ctx, "testpmd> ");
2175         if (cl == NULL) {
2176                 return;
2177         }
2178         cmdline_interact(cl);
2179         cmdline_stdin_exit(cl);
2180 }