remove extra parentheses in return statement
[dpdk.git] / app / test-pmd / cmdline.c
index b697423..52e9f5f 100644 (file)
@@ -1,7 +1,7 @@
 /*-
  *   BSD LICENSE
  *
- *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+ *   Copyright(c) 2010-2015 Intel Corporation. All rights reserved.
  *   Copyright(c) 2014 6WIND S.A.
  *   All rights reserved.
  *
@@ -59,8 +59,8 @@
 #include <rte_cycles.h>
 #include <rte_memory.h>
 #include <rte_memzone.h>
+#include <rte_malloc.h>
 #include <rte_launch.h>
-#include <rte_tailq.h>
 #include <rte_eal.h>
 #include <rte_per_lcore.h>
 #include <rte_lcore.h>
@@ -74,6 +74,7 @@
 #include <rte_ethdev.h>
 #include <rte_string_fns.h>
 #include <rte_devargs.h>
+#include <rte_eth_ctrl.h>
 
 #include <cmdline_rdline.h>
 #include <cmdline_parse.h>
 #include <cmdline_parse_etheraddr.h>
 #include <cmdline_socket.h>
 #include <cmdline.h>
-#include <rte_pci_dev_ids.h>
 #ifdef RTE_LIBRTE_PMD_BOND
 #include <rte_eth_bond.h>
 #endif
 
 #include "testpmd.h"
 
+static struct cmdline *testpmd_cl;
+
 static void cmd_reconfig_device_queue(portid_t id, uint8_t dev, uint8_t queue);
 
 #ifdef RTE_NIC_BYPASS
@@ -114,7 +116,6 @@ static void cmd_help_brief_parsed(__attribute__((unused)) void *parsed_result,
                "information.\n"
                "    help config     : Configuration information.\n"
                "    help ports      : Configuring ports.\n"
-               "    help flowdir    : Flow Director filter help.\n"
                "    help registers  : Reading and setting port registers.\n"
                "    help filters    : Filters configuration help.\n"
                "    help all        : All of the above sections.\n\n"
@@ -171,7 +172,7 @@ static void cmd_help_long_parsed(void *parsed_result,
                        " statistics.\n\n"
 
                        "quit\n"
-                       "    Quit to prompt in Linux and reboot on Baremetal.\n\n"
+                       "    Quit to prompt.\n\n"
                );
        }
 
@@ -183,17 +184,27 @@ static void cmd_help_long_parsed(void *parsed_result,
                        "Display:\n"
                        "--------\n\n"
 
-                       "show port (info|stats|xstats|fdir|stat_qmap) (port_id|all)\n"
+                       "show port (info|stats|xstats|fdir|stat_qmap|dcb_tc) (port_id|all)\n"
                        "    Display information for port_id, or all.\n\n"
 
-                       "show port rss-hash [key]\n"
+                       "show port X rss reta (size) (mask0,mask1,...)\n"
+                       "    Display the rss redirection table entry indicated"
+                       " by masks on port X. size is used to indicate the"
+                       " hardware supported reta size\n\n"
+
+                       "show port rss-hash ipv4|ipv4-frag|ipv4-tcp|ipv4-udp|"
+                       "ipv4-sctp|ipv4-other|ipv6|ipv6-frag|ipv6-tcp|ipv6-udp|ipv6-sctp|"
+                       "ipv6-other|l2-payload|ipv6-ex|ipv6-tcp-ex|ipv6-udp-ex [key]\n"
                        "    Display the RSS hash functions and RSS hash key"
                        " of port X\n\n"
 
                        "clear port (info|stats|xstats|fdir|stat_qmap) (port_id|all)\n"
                        "    Clear information for port_id, or all.\n\n"
 
-                       "show config (rxtx|cores|fwd)\n"
+                       "show (rxq|txq) info (port_id) (queue_id)\n"
+                       "    Display information for configured RX/TX queue.\n\n"
+
+                       "show config (rxtx|cores|fwd|txpkts)\n"
                        "    Display the given configuration.\n\n"
 
                        "read rxd (port_id) (queue_id) (rxd_id)\n"
@@ -240,7 +251,12 @@ static void cmd_help_long_parsed(void *parsed_result,
 
                        "set txpkts (x[,y]*)\n"
                        "    Set the length of each segment of TXONLY"
-                       " packets.\n\n"
+                       " and optionally CSUM packets.\n\n"
+
+                       "set txsplit (off|on|rand)\n"
+                       "    Set the split policy for the TX packets."
+                       " Right now only applicable for CSUM and TXONLY"
+                       " modes\n\n"
 
                        "set corelist (x[,y]*)\n"
                        "    Set the list of forwarding cores.\n\n"
@@ -286,11 +302,11 @@ static void cmd_help_long_parsed(void *parsed_result,
                        " a port\n\n"
 
                        "tunnel_filter add (port_id) (outer_mac) (inner_mac) (ip_addr) "
-                       "(inner_vlan) (tunnel_type) (filter_type) (tenant_id) (queue_id)\n"
+                       "(inner_vlan) (vxlan|nvgre) (filter_type) (tenant_id) (queue_id)\n"
                        "   add a tunnel filter of a port.\n\n"
 
                        "tunnel_filter rm (port_id) (outer_mac) (inner_mac) (ip_addr) "
-                       "(inner_vlan) (tunnel_type) (filter_type) (tenant_id) (queue_id)\n"
+                       "(inner_vlan) (vxlan|nvgre) (filter_type) (tenant_id) (queue_id)\n"
                        "   remove a tunnel filter of a port.\n\n"
 
                        "rx_vxlan_port add (udp_port) (port_id)\n"
@@ -299,9 +315,9 @@ static void cmd_help_long_parsed(void *parsed_result,
                        "rx_vxlan_port rm (udp_port) (port_id)\n"
                        "    Remove an UDP port for VXLAN packet filter on a port\n\n"
 
-                       "tx_vlan set vlan_id (port_id)\n"
-                       "    Set hardware insertion of VLAN ID in packets sent"
-                       " on a port.\n\n"
+                       "tx_vlan set (port_id) vlan_id[, vlan_id_outer]\n"
+                       "    Set hardware insertion of VLAN IDs (single or double VLAN "
+                       "depends on the number of VLAN IDs) in packets sent on a port.\n\n"
 
                        "tx_vlan set pvid port_id vlan_id (on|off)\n"
                        "    Set port based TX VLAN insertion.\n\n"
@@ -310,19 +326,33 @@ static void cmd_help_long_parsed(void *parsed_result,
                        "    Disable hardware insertion of a VLAN header in"
                        " packets sent on a port.\n\n"
 
-                       "tx_checksum set (mask) (port_id)\n"
-                       "    Enable hardware insertion of checksum offload with"
-                       " the 8-bit mask, 0~0xff, in packets sent on a port.\n"
-                       "        bit 0 - insert ip   checksum offload if set\n"
-                       "        bit 1 - insert udp  checksum offload if set\n"
-                       "        bit 2 - insert tcp  checksum offload if set\n"
-                       "        bit 3 - insert sctp checksum offload if set\n"
-                       "        bit 4 - insert inner ip  checksum offload if set\n"
-                       "        bit 5 - insert inner udp checksum offload if set\n"
-                       "        bit 6 - insert inner tcp checksum offload if set\n"
-                       "        bit 7 - insert inner sctp checksum offload if set\n"
+                       "csum set (ip|udp|tcp|sctp|outer-ip) (hw|sw) (port_id)\n"
+                       "    Select hardware or software calculation of the"
+                       " checksum when transmitting a packet using the"
+                       " csum forward engine.\n"
+                       "    ip|udp|tcp|sctp always concern the inner layer.\n"
+                       "    outer-ip concerns the outer IP layer in"
+                       " case the packet is recognized as a tunnel packet by"
+                       " the forward engine (vxlan, gre and ipip are supported)\n"
+                       "    Please check the NIC datasheet for HW limits.\n\n"
+
+                       "csum parse-tunnel (on|off) (tx_port_id)\n"
+                       "    If disabled, treat tunnel packets as non-tunneled"
+                       " packets (treat inner headers as payload). The port\n"
+                       "    argument is the port used for TX in csum forward"
+                       " engine.\n\n"
+
+                       "csum show (port_id)\n"
+                       "    Display tx checksum offload configuration\n\n"
+
+                       "tso set (segsize) (portid)\n"
+                       "    Enable TCP Segmentation Offload in csum forward"
+                       " engine.\n"
                        "    Please check the NIC datasheet for HW limits.\n\n"
 
+                       "tso show (portid)"
+                       "    Display the status of TCP Segmentation Offload.\n\n"
+
                        "set fwd (%s)\n"
                        "    Set packet forwarding mode.\n\n"
 
@@ -393,7 +423,7 @@ static void cmd_help_long_parsed(void *parsed_result,
                        "    Set rate limit for queues in VF of a port\n\n"
 
                        "set port (port_id) mirror-rule (rule_id)"
-                       "(pool-mirror|vlan-mirror)\n"
+                       " (pool-mirror-up|pool-mirror-down|vlan-mirror)"
                        " (poolmask|vlanid[,vlanid]*) dst-pool (pool_id) (on|off)\n"
                        "   Set pool or vlan type mirror rule on a port.\n"
                        "   e.g., 'set port 0 mirror-rule 0 vlan-mirror 0,1"
@@ -476,71 +506,6 @@ static void cmd_help_long_parsed(void *parsed_result,
                );
        }
 
-
-       if (show_all || !strcmp(res->section, "flowdir")) {
-
-               cmdline_printf(
-                       cl,
-                       "\n"
-                       "Flow director mode:\n"
-                       "-------------------\n\n"
-
-                       "add_signature_filter (port_id) (ip|udp|tcp|sctp)"
-                       " src (src_ip_address) (src_port)"
-                       " dst (dst_ip_address) (dst_port)"
-                       " flexbytes (flexbytes_values) vlan (vlan_id)"
-                       " queue (queue_id)\n"
-                       "    Add a signature filter.\n\n"
-
-                       "upd_signature_filter (port_id) (ip|udp|tcp|sctp)"
-                       " src (src_ip_address) (src_port)"
-                       " dst (dst_ip_address) (dst_port)"
-                       " flexbytes (flexbytes_values) vlan (vlan_id)"
-                       " queue (queue_id)\n"
-                       "    Update a signature filter.\n\n"
-
-                       "rm_signature_filter (port_id) (ip|udp|tcp|sctp)"
-                       " src (src_ip_address) (src_port)"
-                       " dst (dst_ip_address) (dst_port)"
-                       " flexbytes (flexbytes_values) vlan (vlan_id)\n"
-                       "    Remove a signature filter.\n\n"
-
-                       "add_perfect_filter (port_id) (ip|udp|tcp|sctp)"
-                       " src (src_ip_address) (src_port)"
-                       " dst (dst_ip_address) (dst_port)"
-                       " flexbytes (flexbytes_values) vlan (vlan_id)"
-                       " queue (queue_id) soft (soft_id)\n"
-                       "    Add a perfect filter.\n\n"
-
-                       "upd_perfect_filter (port_id) (ip|udp|tcp|sctp)"
-                       " src (src_ip_address) (src_port)"
-                       " dst (dst_ip_address) (dst_port)"
-                       " flexbytes (flexbytes_values) vlan (vlan_id)"
-                       " queue (queue_id)\n"
-                       "    Update a perfect filter.\n\n"
-
-                       "rm_perfect_filter (port_id) (ip|udp|tcp|sctp)"
-                       " src (src_ip_address) (src_port)"
-                       " dst (dst_ip_address) (dst_port)"
-                       " flexbytes (flexbytes_values) vlan (vlan_id)"
-                       " soft (soft_id)\n"
-                       "    Remove a perfect filter.\n\n"
-
-                       "set_masks_filter (port_id) only_ip_flow (0|1)"
-                       " src_mask (ip_src_mask) (src_port_mask)"
-                       " dst_mask (ip_dst_mask) (dst_port_mask)"
-                       " flexbytes (0|1) vlan_id (0|1) vlan_prio (0|1)\n"
-                       "    Set IPv4 filter masks.\n\n"
-
-                       "set_ipv6_masks_filter (port_id) only_ip_flow (0|1)"
-                       " src_mask (ip_src_mask) (src_port_mask)"
-                       " dst_mask (ip_dst_mask) (dst_port_mask)"
-                       " flexbytes (0|1) vlan_id (0|1) vlan_prio (0|1)"
-                       " compare_dst (0|1)\n"
-                       "    Set IPv6 filter masks.\n\n"
-               );
-       }
-
        if (show_all || !strcmp(res->section, "ports")) {
 
                cmdline_printf(
@@ -558,6 +523,12 @@ static void cmd_help_long_parsed(void *parsed_result,
                        "port close (port_id|all)\n"
                        "    Close all ports or port_id.\n\n"
 
+                       "port attach (ident)\n"
+                       "    Attach physical or virtual dev by pci address or virtual device name\n\n"
+
+                       "port detach (port_id)\n"
+                       "    Detach physical or virtual dev by port_id\n\n"
+
                        "port config (port_id|all)"
                        " speed (10|100|1000|10000|40000|auto)"
                        " duplex (half|full|auto)\n"
@@ -569,12 +540,13 @@ static void cmd_help_long_parsed(void *parsed_result,
                        "port config all max-pkt-len (value)\n"
                        "    Set the max packet length.\n\n"
 
-                       "port config all (crc-strip|rx-cksum|hw-vlan|drop-en)"
+                       "port config all (crc-strip|rx-cksum|hw-vlan|hw-vlan-filter|"
+                       "hw-vlan-strip|hw-vlan-extend|drop-en)"
                        " (on|off)\n"
                        "    Set crc-strip/rx-checksum/hardware-vlan/drop_en"
                        " for ports.\n\n"
 
-                       "port config all rss (ip|udp|none)\n"
+                       "port config all rss (all|ip|tcp|udp|sctp|ether|none)\n"
                        "    Set the RSS mode.\n\n"
 
                        "port config port-id rss reta (hash,queue)[,(hash,queue)]\n"
@@ -640,57 +612,143 @@ static void cmd_help_long_parsed(void *parsed_result,
                        "filters:\n"
                        "--------\n\n"
 
-                       "add_ethertype_filter (port_id) ethertype (eth_value)"
-                       " priority (enable|disable)(pri_value) queue (queue_id) index (idx)\n"
-                       "    add an ethertype filter.\n\n"
-
-                       "remove_ethertype_filter (port_id) index (idx)\n"
-                       "    remove an ethertype filter.\n\n"
-
-                       "get_ethertype_filter (port_id) index (idx)\n"
-                       "    get info of a ethertype filter.\n\n"
-
-                       "add_2tuple_filter (port_id) protocol (pro_value) (pro_mask)"
-                       " dst_port (port_value) (port_mask) flags (flg_value) priority (prio_value)"
-                       " queue (queue_id) index (idx)\n"
-                       "    add a 2tuple filter.\n\n"
-
-                       "remove_2tuple_filter (port_id) index (idx)\n"
-                       "    remove a 2tuple filter.\n\n"
-
-                       "get_2tuple_filter (port_id) index (idx)\n"
-                       "    get info of a 2tuple filter.\n\n"
-
-                       "add_5tuple_filter (port_id) dst_ip (dst_address) src_ip (src_address)"
-                       " dst_port (dst_port_value) src_port (src_port_value) protocol (protocol_value)"
-                       " mask (mask_value) flags (flags_value) priority (prio_value)"
-                       " queue (queue_id) index (idx)\n"
-                       "    add a 5tuple filter.\n\n"
-
-                       "remove_5tuple_filter (port_id) index (idx)\n"
-                       "    remove a 5tuple filter.\n\n"
-
-                       "get_5tuple_filter (port_id) index (idx)\n"
-                       "    get info of a 5tuple filter.\n\n"
-
-                       "add_syn_filter (port_id) priority (high|low) queue (queue_id)"
-                       "    add syn filter.\n\n"
-
-                       "remove_syn_filter (port_id)"
-                       "    remove syn filter.\n\n"
-
-                       "get_syn_filter (port_id) "
-                       "    get syn filter info.\n\n"
-
-                       "add_flex_filter (port_id) len (len_value) bytes (bytes_string) mask (mask_value)"
-                       " priority (prio_value) queue (queue_id) index (idx)\n"
-                       "    add a flex filter.\n\n"
-
-                       "remove_flex_filter (port_id) index (idx)\n"
-                       "    remove a flex filter.\n\n"
+                       "ethertype_filter (port_id) (add|del)"
+                       " (mac_addr|mac_ignr) (mac_address) ethertype"
+                       " (ether_type) (drop|fwd) queue (queue_id)\n"
+                       "    Add/Del an ethertype filter.\n\n"
+
+                       "2tuple_filter (port_id) (add|del)"
+                       " dst_port (dst_port_value) protocol (protocol_value)"
+                       " mask (mask_value) tcp_flags (tcp_flags_value)"
+                       " priority (prio_value) queue (queue_id)\n"
+                       "    Add/Del a 2tuple filter.\n\n"
+
+                       "5tuple_filter (port_id) (add|del)"
+                       " dst_ip (dst_address) src_ip (src_address)"
+                       " dst_port (dst_port_value) src_port (src_port_value)"
+                       " protocol (protocol_value)"
+                       " mask (mask_value) tcp_flags (tcp_flags_value)"
+                       " priority (prio_value) queue (queue_id)\n"
+                       "    Add/Del a 5tuple filter.\n\n"
+
+                       "syn_filter (port_id) (add|del) priority (high|low) queue (queue_id)"
+                       "    Add/Del syn filter.\n\n"
+
+                       "flex_filter (port_id) (add|del) len (len_value)"
+                       " bytes (bytes_value) mask (mask_value)"
+                       " priority (prio_value) queue (queue_id)\n"
+                       "    Add/Del a flex filter.\n\n"
+
+                       "flow_director_filter (port_id) mode IP (add|del|update)"
+                       " flow (ipv4-other|ipv4-frag|ipv6-other|ipv6-frag)"
+                       " src (src_ip_address) dst (dst_ip_address)"
+                       " vlan (vlan_value) flexbytes (flexbytes_value)"
+                       " (drop|fwd) pf|vf(vf_id) queue (queue_id)"
+                       " fd_id (fd_id_value)\n"
+                       "    Add/Del an IP type flow director filter.\n\n"
+
+                       "flow_director_filter (port_id) mode IP (add|del|update)"
+                       " flow (ipv4-tcp|ipv4-udp|ipv6-tcp|ipv6-udp)"
+                       " src (src_ip_address) (src_port)"
+                       " dst (dst_ip_address) (dst_port)"
+                       " vlan (vlan_value) flexbytes (flexbytes_value)"
+                       " (drop|fwd) pf|vf(vf_id) queue (queue_id)"
+                       " fd_id (fd_id_value)\n"
+                       "    Add/Del an UDP/TCP type flow director filter.\n\n"
 
-                       "get_flex_filter (port_id) index (idx)\n"
-                       "    get info of a flex filter.\n\n"
+                       "flow_director_filter (port_id) mode IP (add|del|update)"
+                       " flow (ipv4-sctp|ipv6-sctp)"
+                       " src (src_ip_address) (src_port)"
+                       " dst (dst_ip_address) (dst_port)"
+                       " tag (verification_tag) vlan (vlan_value)"
+                       " flexbytes (flexbytes_value) (drop|fwd)"
+                       " pf|vf(vf_id) queue (queue_id) fd_id (fd_id_value)\n"
+                       "    Add/Del a SCTP type flow director filter.\n\n"
+
+                       "flow_director_filter (port_id) mode IP (add|del|update)"
+                       " flow l2_payload ether (ethertype)"
+                       " flexbytes (flexbytes_value) (drop|fwd)"
+                       " pf|vf(vf_id) queue (queue_id) fd_id (fd_id_value)\n"
+                       "    Add/Del a l2 payload type flow director filter.\n\n"
+
+                       "flow_director_filter (port_id) mode MAC-VLAN (add|del|update)"
+                       " mac (mac_address) vlan (vlan_value)"
+                       " flexbytes (flexbytes_value) (drop|fwd)"
+                       " queue (queue_id) fd_id (fd_id_value)\n"
+                       "    Add/Del a MAC-VLAN flow director filter.\n\n"
+
+                       "flow_director_filter (port_id) mode Tunnel (add|del|update)"
+                       " mac (mac_address) vlan (vlan_value)"
+                       " tunnel (NVGRE|VxLAN) tunnel-id (tunnel_id_value)"
+                       " flexbytes (flexbytes_value) (drop|fwd)"
+                       " queue (queue_id) fd_id (fd_id_value)\n"
+                       "    Add/Del a Tunnel flow director filter.\n\n"
+
+                       "flush_flow_director (port_id)\n"
+                       "    Flush all flow director entries of a device.\n\n"
+
+                       "flow_director_mask (port_id) mode IP vlan (vlan_value)"
+                       " src_mask (ipv4_src) (ipv6_src) (src_port)"
+                       " dst_mask (ipv4_dst) (ipv6_dst) (dst_port)\n"
+                       "    Set flow director IP mask.\n\n"
+
+                       "flow_director_mask (port_id) mode MAC-VLAN"
+                       " vlan (vlan_value) mac (mac_value)\n"
+                       "    Set flow director MAC-VLAN mask.\n\n"
+
+                       "flow_director_mask (port_id) mode Tunnel"
+                       " vlan (vlan_value) mac (mac_value)"
+                       " tunnel-type (tunnel_type_value)"
+                       " tunnel-id (tunnel_id_value)\n"
+                       "    Set flow director Tunnel mask.\n\n"
+
+                       "flow_director_flex_mask (port_id)"
+                       " flow (none|ipv4-other|ipv4-frag|ipv4-tcp|ipv4-udp|ipv4-sctp|"
+                       "ipv6-other|ipv6-frag|ipv6-tcp|ipv6-udp|ipv6-sctp|l2_payload|all)"
+                       " (mask)\n"
+                       "    Configure mask of flex payload.\n\n"
+
+                       "flow_director_flex_payload (port_id)"
+                       " (raw|l2|l3|l4) (config)\n"
+                       "    Configure flex payload selection.\n\n"
+
+                       "get_sym_hash_ena_per_port (port_id)\n"
+                       "    get symmetric hash enable configuration per port.\n\n"
+
+                       "set_sym_hash_ena_per_port (port_id) (enable|disable)\n"
+                       "    set symmetric hash enable configuration per port"
+                       " to enable or disable.\n\n"
+
+                       "get_hash_global_config (port_id)\n"
+                       "    Get the global configurations of hash filters.\n\n"
+
+                       "set_hash_global_config (port_id) (toeplitz|simple_xor|default)"
+                       " (ipv4|ipv4-frag|ipv4-tcp|ipv4-udp|ipv4-sctp|ipv4-other|ipv6|"
+                       "ipv6-frag|ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other|l2_payload)"
+                       " (enable|disable)\n"
+                       "    Set the global configurations of hash filters.\n\n"
+
+                       "set_hash_input_set (port_id) (ipv4|ipv4-frag|"
+                       "ipv4-tcp|ipv4-udp|ipv4-sctp|ipv4-other|ipv6|"
+                       "ipv6-frag|ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other|"
+                       "l2_payload) (ovlan|ivlan|src-ipv4|dst-ipv4|src-ipv6|"
+                       "dst-ipv6|ipv4-tos|ipv4-proto|ipv6-tc|"
+                       "ipv6-next-header|udp-src-port|udp-dst-port|"
+                       "tcp-src-port|tcp-dst-port|sctp-src-port|"
+                       "sctp-dst-port|sctp-veri-tag|udp-key|gre-key|fld-1st|"
+                       "fld-2nd|fld-3rd|fld-4th|fld-5th|fld-6th|fld-7th|"
+                       "fld-8th|none) (select|add)\n"
+                       "    Set the input set for hash.\n\n"
+
+                       "set_fdir_input_set (port_id) (ipv4|ipv4-frag|"
+                       "ipv4-tcp|ipv4-udp|ipv4-sctp|ipv4-other|ipv6|"
+                       "ipv6-frag|ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other|"
+                       "l2_payload) (src-ipv4|dst-ipv4|src-ipv6|dst-ipv6|"
+                       "udp-src-port|udp-dst-port|tcp-src-port|tcp-dst-port|"
+                       "sctp-src-port|sctp-dst-port|sctp-veri-tag|fld-1st|"
+                       "fld-2nd|fld-3rd|fld-4th|fld-5th|fld-6th|fld-7th|"
+                       "fld-8th|none) (select|add)\n"
+                       "    Set the input set for FDir.\n\n"
                );
        }
 }
@@ -700,7 +758,7 @@ cmdline_parse_token_string_t cmd_help_long_help =
 
 cmdline_parse_token_string_t cmd_help_long_section =
        TOKEN_STRING_INITIALIZER(struct cmd_help_long_result, section,
-                       "all#control#display#config#flowdir#"
+                       "all#control#display#config#"
                        "ports#registers#filters");
 
 cmdline_parse_inst_t cmd_help_long = {
@@ -804,6 +862,89 @@ cmdline_parse_inst_t cmd_operate_specific_port = {
        },
 };
 
+/* *** attach a specified port *** */
+struct cmd_operate_attach_port_result {
+       cmdline_fixed_string_t port;
+       cmdline_fixed_string_t keyword;
+       cmdline_fixed_string_t identifier;
+};
+
+static void cmd_operate_attach_port_parsed(void *parsed_result,
+                               __attribute__((unused)) struct cmdline *cl,
+                               __attribute__((unused)) void *data)
+{
+       struct cmd_operate_attach_port_result *res = parsed_result;
+
+       if (!strcmp(res->keyword, "attach"))
+               attach_port(res->identifier);
+       else
+               printf("Unknown parameter\n");
+}
+
+cmdline_parse_token_string_t cmd_operate_attach_port_port =
+       TOKEN_STRING_INITIALIZER(struct cmd_operate_attach_port_result,
+                       port, "port");
+cmdline_parse_token_string_t cmd_operate_attach_port_keyword =
+       TOKEN_STRING_INITIALIZER(struct cmd_operate_attach_port_result,
+                       keyword, "attach");
+cmdline_parse_token_string_t cmd_operate_attach_port_identifier =
+       TOKEN_STRING_INITIALIZER(struct cmd_operate_attach_port_result,
+                       identifier, NULL);
+
+cmdline_parse_inst_t cmd_operate_attach_port = {
+       .f = cmd_operate_attach_port_parsed,
+       .data = NULL,
+       .help_str = "port attach identifier, "
+               "identifier: pci address or virtual dev name",
+       .tokens = {
+               (void *)&cmd_operate_attach_port_port,
+               (void *)&cmd_operate_attach_port_keyword,
+               (void *)&cmd_operate_attach_port_identifier,
+               NULL,
+       },
+};
+
+/* *** detach a specified port *** */
+struct cmd_operate_detach_port_result {
+       cmdline_fixed_string_t port;
+       cmdline_fixed_string_t keyword;
+       uint8_t port_id;
+};
+
+static void cmd_operate_detach_port_parsed(void *parsed_result,
+                               __attribute__((unused)) struct cmdline *cl,
+                               __attribute__((unused)) void *data)
+{
+       struct cmd_operate_detach_port_result *res = parsed_result;
+
+       if (!strcmp(res->keyword, "detach"))
+               detach_port(res->port_id);
+       else
+               printf("Unknown parameter\n");
+}
+
+cmdline_parse_token_string_t cmd_operate_detach_port_port =
+       TOKEN_STRING_INITIALIZER(struct cmd_operate_detach_port_result,
+                       port, "port");
+cmdline_parse_token_string_t cmd_operate_detach_port_keyword =
+       TOKEN_STRING_INITIALIZER(struct cmd_operate_detach_port_result,
+                       keyword, "detach");
+cmdline_parse_token_num_t cmd_operate_detach_port_port_id =
+       TOKEN_NUM_INITIALIZER(struct cmd_operate_detach_port_result,
+                       port_id, UINT8);
+
+cmdline_parse_inst_t cmd_operate_detach_port = {
+       .f = cmd_operate_detach_port_parsed,
+       .data = NULL,
+       .help_str = "port detach port_id",
+       .tokens = {
+               (void *)&cmd_operate_detach_port_port,
+               (void *)&cmd_operate_detach_port_keyword,
+               (void *)&cmd_operate_detach_port_port_id,
+               NULL,
+       },
+};
+
 /* *** configure speed for all ports *** */
 struct cmd_config_speed_all {
        cmdline_fixed_string_t port;
@@ -858,7 +999,7 @@ cmd_config_speed_all_parsed(void *parsed_result,
                return;
        }
 
-       for (pid = 0; pid < nb_ports; pid++) {
+       FOREACH_PORT(pid, ports) {
                ports[pid].dev_conf.link_speed = link_speed;
                ports[pid].dev_conf.link_duplex = link_duplex;
        }
@@ -926,10 +1067,8 @@ cmd_config_speed_specific_parsed(void *parsed_result,
                return;
        }
 
-       if (res->id >= nb_ports) {
-               printf("Port id %d must be less than %d\n", res->id, nb_ports);
+       if (port_id_is_invalid(res->id, ENABLED_WARN))
                return;
-       }
 
        if (!strcmp(res->value1, "10"))
                link_speed = ETH_LINK_SPEED_10;
@@ -1267,6 +1406,33 @@ cmd_config_rx_mode_flag_parsed(void *parsed_result,
                        printf("Unknown parameter\n");
                        return;
                }
+       } else if (!strcmp(res->name, "hw-vlan-filter")) {
+               if (!strcmp(res->value, "on"))
+                       rx_mode.hw_vlan_filter = 1;
+               else if (!strcmp(res->value, "off"))
+                       rx_mode.hw_vlan_filter = 0;
+               else {
+                       printf("Unknown parameter\n");
+                       return;
+               }
+       } else if (!strcmp(res->name, "hw-vlan-strip")) {
+               if (!strcmp(res->value, "on"))
+                       rx_mode.hw_vlan_strip  = 1;
+               else if (!strcmp(res->value, "off"))
+                       rx_mode.hw_vlan_strip  = 0;
+               else {
+                       printf("Unknown parameter\n");
+                       return;
+               }
+       } else if (!strcmp(res->name, "hw-vlan-extend")) {
+               if (!strcmp(res->value, "on"))
+                       rx_mode.hw_vlan_extend = 1;
+               else if (!strcmp(res->value, "off"))
+                       rx_mode.hw_vlan_extend = 0;
+               else {
+                       printf("Unknown parameter\n");
+                       return;
+               }
        } else if (!strcmp(res->name, "drop-en")) {
                if (!strcmp(res->value, "on"))
                        rx_drop_en = 1;
@@ -1295,7 +1461,8 @@ cmdline_parse_token_string_t cmd_config_rx_mode_flag_all =
        TOKEN_STRING_INITIALIZER(struct cmd_config_rx_mode_flag, all, "all");
 cmdline_parse_token_string_t cmd_config_rx_mode_flag_name =
        TOKEN_STRING_INITIALIZER(struct cmd_config_rx_mode_flag, name,
-                                       "crc-strip#rx-cksum#hw-vlan");
+                                       "crc-strip#rx-cksum#hw-vlan#"
+                                       "hw-vlan-filter#hw-vlan-strip#hw-vlan-extend");
 cmdline_parse_token_string_t cmd_config_rx_mode_flag_value =
        TOKEN_STRING_INITIALIZER(struct cmd_config_rx_mode_flag, value,
                                                        "on#off");
@@ -1303,7 +1470,8 @@ cmdline_parse_token_string_t cmd_config_rx_mode_flag_value =
 cmdline_parse_inst_t cmd_config_rx_mode_flag = {
        .f = cmd_config_rx_mode_flag_parsed,
        .data = NULL,
-       .help_str = "port config all crc-strip|rx-cksum|hw-vlan on|off",
+       .help_str = "port config all crc-strip|rx-cksum|hw-vlan|"
+               "hw-vlan-filter|hw-vlan-strip|hw-vlan-extend on|off",
        .tokens = {
                (void *)&cmd_config_rx_mode_flag_port,
                (void *)&cmd_config_rx_mode_flag_keyword,
@@ -1332,10 +1500,20 @@ cmd_config_rss_parsed(void *parsed_result,
        struct rte_eth_rss_conf rss_conf;
        uint8_t i;
 
-       if (!strcmp(res->value, "ip"))
+       if (!strcmp(res->value, "all"))
+               rss_conf.rss_hf = ETH_RSS_IP | ETH_RSS_TCP |
+                               ETH_RSS_UDP | ETH_RSS_SCTP |
+                                       ETH_RSS_L2_PAYLOAD;
+       else if (!strcmp(res->value, "ip"))
                rss_conf.rss_hf = ETH_RSS_IP;
        else if (!strcmp(res->value, "udp"))
                rss_conf.rss_hf = ETH_RSS_UDP;
+       else if (!strcmp(res->value, "tcp"))
+               rss_conf.rss_hf = ETH_RSS_TCP;
+       else if (!strcmp(res->value, "sctp"))
+               rss_conf.rss_hf = ETH_RSS_SCTP;
+       else if (!strcmp(res->value, "ether"))
+               rss_conf.rss_hf = ETH_RSS_L2_PAYLOAD;
        else if (!strcmp(res->value, "none"))
                rss_conf.rss_hf = 0;
        else {
@@ -1356,12 +1534,13 @@ cmdline_parse_token_string_t cmd_config_rss_all =
 cmdline_parse_token_string_t cmd_config_rss_name =
        TOKEN_STRING_INITIALIZER(struct cmd_config_rss, name, "rss");
 cmdline_parse_token_string_t cmd_config_rss_value =
-       TOKEN_STRING_INITIALIZER(struct cmd_config_rss, value, "ip#udp#none");
+       TOKEN_STRING_INITIALIZER(struct cmd_config_rss, value,
+               "all#ip#tcp#udp#sctp#ether#none");
 
 cmdline_parse_inst_t cmd_config_rss = {
        .f = cmd_config_rss_parsed,
        .data = NULL,
-       .help_str = "port config all rss ip|udp|none",
+       .help_str = "port config all rss all|ip|tcp|udp|sctp|ether|none",
        .tokens = {
                (void *)&cmd_config_rss_port,
                (void *)&cmd_config_rss_keyword,
@@ -1378,6 +1557,7 @@ struct cmd_config_rss_hash_key {
        cmdline_fixed_string_t config;
        uint8_t port_id;
        cmdline_fixed_string_t rss_hash_key;
+       cmdline_fixed_string_t rss_type;
        cmdline_fixed_string_t key;
 };
 
@@ -1435,7 +1615,8 @@ cmd_config_rss_hash_key_parsed(void *parsed_result,
                        return;
                hash_key[i] = (uint8_t) ((xdgt0 * 16) + xdgt1);
        }
-       port_rss_hash_key_update(res->port_id, hash_key);
+       port_rss_hash_key_update(res->port_id, res->rss_type, hash_key,
+                                RSS_HASH_KEY_LENGTH);
 }
 
 cmdline_parse_token_string_t cmd_config_rss_hash_key_port =
@@ -1448,18 +1629,29 @@ cmdline_parse_token_num_t cmd_config_rss_hash_key_port_id =
 cmdline_parse_token_string_t cmd_config_rss_hash_key_rss_hash_key =
        TOKEN_STRING_INITIALIZER(struct cmd_config_rss_hash_key,
                                 rss_hash_key, "rss-hash-key");
+cmdline_parse_token_string_t cmd_config_rss_hash_key_rss_type =
+       TOKEN_STRING_INITIALIZER(struct cmd_config_rss_hash_key, rss_type,
+                                "ipv4#ipv4-frag#ipv4-tcp#ipv4-udp#ipv4-sctp#"
+                                "ipv4-other#ipv6#ipv6-frag#ipv6-tcp#ipv6-udp#"
+                                "ipv6-sctp#ipv6-other#l2-payload#ipv6-ex#"
+                                "ipv6-tcp-ex#ipv6-udp-ex");
 cmdline_parse_token_string_t cmd_config_rss_hash_key_value =
        TOKEN_STRING_INITIALIZER(struct cmd_config_rss_hash_key, key, NULL);
 
 cmdline_parse_inst_t cmd_config_rss_hash_key = {
        .f = cmd_config_rss_hash_key_parsed,
        .data = NULL,
-       .help_str = "port config X rss-hash-key 80 hexa digits",
+       .help_str =
+               "port config X rss-hash-key ipv4|ipv4-frag|ipv4-tcp|ipv4-udp|"
+               "ipv4-sctp|ipv4-other|ipv6|ipv6-frag|ipv6-tcp|ipv6-udp|"
+               "ipv6-sctp|ipv6-other|l2-payload|"
+               "ipv6-ex|ipv6-tcp-ex|ipv6-udp-ex 80 hexa digits\n",
        .tokens = {
                (void *)&cmd_config_rss_hash_key_port,
                (void *)&cmd_config_rss_hash_key_config,
                (void *)&cmd_config_rss_hash_key_port_id,
                (void *)&cmd_config_rss_hash_key_rss_hash_key,
+               (void *)&cmd_config_rss_hash_key_rss_type,
                (void *)&cmd_config_rss_hash_key_value,
                NULL,
        },
@@ -1489,7 +1681,7 @@ cmd_config_rxtx_queue_parsed(void *parsed_result,
                return;
        }
 
-       if (port_id_is_invalid(res->portid))
+       if (port_id_is_invalid(res->portid, ENABLED_WARN))
                return;
 
        if (port_is_started(res->portid) != 1) {
@@ -1570,11 +1762,13 @@ struct cmd_config_rss_reta {
 };
 
 static int
-parse_reta_config(const char *str, struct rte_eth_rss_reta *reta_conf)
+parse_reta_config(const char *str,
+                 struct rte_eth_rss_reta_entry64 *reta_conf,
+                 uint16_t nb_entries)
 {
        int i;
        unsigned size;
-       uint8_t hash_index;
+       uint16_t hash_index, idx, shift;
        uint8_t nb_queue;
        char s[256];
        const char *p, *p0 = str;
@@ -1602,24 +1796,23 @@ parse_reta_config(const char *str, struct rte_eth_rss_reta *reta_conf)
                for (i = 0; i < _NUM_FLD; i++) {
                        errno = 0;
                        int_fld[i] = strtoul(str_fld[i], &end, 0);
-                       if (errno != 0 || end == str_fld[i] || int_fld[i] > 255)
+                       if (errno != 0 || end == str_fld[i] ||
+                                       int_fld[i] > 65535)
                                return -1;
                }
 
-               hash_index = (uint8_t)int_fld[FLD_HASH_INDEX];
+               hash_index = (uint16_t)int_fld[FLD_HASH_INDEX];
                nb_queue = (uint8_t)int_fld[FLD_QUEUE];
 
-               if (hash_index >= ETH_RSS_RETA_NUM_ENTRIES) {
-                       printf("Invalid RETA hash index=%d", hash_index);
+               if (hash_index >= nb_entries) {
+                       printf("Invalid RETA hash index=%d\n", hash_index);
                        return -1;
                }
 
-               if (hash_index < ETH_RSS_RETA_NUM_ENTRIES/2)
-                       reta_conf->mask_lo |= (1ULL << hash_index);
-               else
-                       reta_conf->mask_hi |= (1ULL << (hash_index - ETH_RSS_RETA_NUM_ENTRIES/2));
-
-               reta_conf->reta[hash_index] = nb_queue;
+               idx = hash_index / RTE_RETA_GROUP_SIZE;
+               shift = hash_index % RTE_RETA_GROUP_SIZE;
+               reta_conf[idx].mask |= (1ULL << shift);
+               reta_conf[idx].reta[shift] = nb_queue;
        }
 
        return 0;
@@ -1631,17 +1824,35 @@ cmd_set_rss_reta_parsed(void *parsed_result,
                        __attribute__((unused)) void *data)
 {
        int ret;
-       struct rte_eth_rss_reta reta_conf;
+       struct rte_eth_dev_info dev_info;
+       struct rte_eth_rss_reta_entry64 reta_conf[8];
        struct cmd_config_rss_reta *res = parsed_result;
 
-       memset(&reta_conf, 0, sizeof(struct rte_eth_rss_reta));
+       memset(&dev_info, 0, sizeof(dev_info));
+       rte_eth_dev_info_get(res->port_id, &dev_info);
+       if (dev_info.reta_size == 0) {
+               printf("Redirection table size is 0 which is "
+                                       "invalid for RSS\n");
+               return;
+       } else
+               printf("The reta size of port %d is %u\n",
+                       res->port_id, dev_info.reta_size);
+       if (dev_info.reta_size > ETH_RSS_RETA_SIZE_512) {
+               printf("Currently do not support more than %u entries of "
+                       "redirection table\n", ETH_RSS_RETA_SIZE_512);
+               return;
+       }
+
+       memset(reta_conf, 0, sizeof(reta_conf));
        if (!strcmp(res->list_name, "reta")) {
-               if (parse_reta_config(res->list_of_items, &reta_conf)) {
-                       printf("Invalid RSS Redirection Table config "
-                                                       "entered\n");
+               if (parse_reta_config(res->list_of_items, reta_conf,
+                                               dev_info.reta_size)) {
+                       printf("Invalid RSS Redirection Table "
+                                       "config entered\n");
                        return;
                }
-               ret = rte_eth_dev_rss_reta_update(res->port_id, &reta_conf);
+               ret = rte_eth_dev_rss_reta_update(res->port_id,
+                               reta_conf, dev_info.reta_size);
                if (ret != 0)
                        printf("Bad redirection table parameter, "
                                        "return code = %d \n", ret);
@@ -1683,26 +1894,73 @@ struct cmd_showport_reta {
        uint8_t port_id;
        cmdline_fixed_string_t rss;
        cmdline_fixed_string_t reta;
-       uint64_t mask_lo;
-       uint64_t mask_hi;
+       uint16_t size;
+       cmdline_fixed_string_t list_of_items;
 };
 
-static void cmd_showport_reta_parsed(void *parsed_result,
-                               __attribute__((unused)) struct cmdline *cl,
-                               __attribute__((unused)) void *data)
+static int
+showport_parse_reta_config(struct rte_eth_rss_reta_entry64 *conf,
+                          uint16_t nb_entries,
+                          char *str)
 {
-       struct cmd_showport_reta *res = parsed_result;
-       struct rte_eth_rss_reta reta_conf;
+       uint32_t size;
+       const char *p, *p0 = str;
+       char s[256];
+       char *end;
+       char *str_fld[8];
+       uint16_t i, num = nb_entries / RTE_RETA_GROUP_SIZE;
+       int ret;
 
-       if ((res->mask_lo == 0) && (res->mask_hi == 0)) {
-               printf("Invalid RSS Redirection Table config entered\n");
-               return;
+       p = strchr(p0, '(');
+       if (p == NULL)
+               return -1;
+       p++;
+       p0 = strchr(p, ')');
+       if (p0 == NULL)
+               return -1;
+       size = p0 - p;
+       if (size >= sizeof(s)) {
+               printf("The string size exceeds the internal buffer size\n");
+               return -1;
        }
+       snprintf(s, sizeof(s), "%.*s", size, p);
+       ret = rte_strsplit(s, sizeof(s), str_fld, num, ',');
+       if (ret <= 0 || ret != num) {
+               printf("The bits of masks do not match the number of "
+                                       "reta entries: %u\n", num);
+               return -1;
+       }
+       for (i = 0; i < ret; i++)
+               conf[i].mask = (uint64_t)strtoul(str_fld[i], &end, 0);
+
+       return 0;
+}
 
-       reta_conf.mask_lo = res->mask_lo;
-       reta_conf.mask_hi = res->mask_hi;
+static void
+cmd_showport_reta_parsed(void *parsed_result,
+                        __attribute__((unused)) struct cmdline *cl,
+                        __attribute__((unused)) void *data)
+{
+       struct cmd_showport_reta *res = parsed_result;
+       struct rte_eth_rss_reta_entry64 reta_conf[8];
+       struct rte_eth_dev_info dev_info;
+
+       memset(&dev_info, 0, sizeof(dev_info));
+       rte_eth_dev_info_get(res->port_id, &dev_info);
+       if (dev_info.reta_size == 0 || res->size != dev_info.reta_size ||
+                               res->size > ETH_RSS_RETA_SIZE_512) {
+               printf("Invalid redirection table size: %u\n", res->size);
+               return;
+       }
 
-       port_rss_reta_info(res->port_id,&reta_conf);
+       memset(reta_conf, 0, sizeof(reta_conf));
+       if (showport_parse_reta_config(reta_conf, res->size,
+                               res->list_of_items) < 0) {
+               printf("Invalid string: %s for reta masks\n",
+                                       res->list_of_items);
+               return;
+       }
+       port_rss_reta_info(res->port_id, reta_conf, res->size);
 }
 
 cmdline_parse_token_string_t cmd_showport_reta_show =
@@ -1715,24 +1973,24 @@ cmdline_parse_token_string_t cmd_showport_reta_rss =
        TOKEN_STRING_INITIALIZER(struct cmd_showport_reta, rss, "rss");
 cmdline_parse_token_string_t cmd_showport_reta_reta =
        TOKEN_STRING_INITIALIZER(struct cmd_showport_reta, reta, "reta");
-cmdline_parse_token_num_t cmd_showport_reta_mask_lo =
-       TOKEN_NUM_INITIALIZER(struct cmd_showport_reta, mask_lo, UINT64);
-cmdline_parse_token_num_t cmd_showport_reta_mask_hi =
-       TOKEN_NUM_INITIALIZER(struct cmd_showport_reta, mask_hi, UINT64);
+cmdline_parse_token_num_t cmd_showport_reta_size =
+       TOKEN_NUM_INITIALIZER(struct cmd_showport_reta, size, UINT16);
+cmdline_parse_token_string_t cmd_showport_reta_list_of_items =
+       TOKEN_STRING_INITIALIZER(struct cmd_showport_reta,
+                                       list_of_items, NULL);
 
 cmdline_parse_inst_t cmd_showport_reta = {
        .f = cmd_showport_reta_parsed,
        .data = NULL,
-       .help_str = "show port X rss reta mask_lo mask_hi (X = port number)\n\
-                       (mask_lo and mask_hi is UINT64)",
+       .help_str = "show port X rss reta (size) (mask0,mask1,...)",
        .tokens = {
                (void *)&cmd_showport_reta_show,
                (void *)&cmd_showport_reta_port,
                (void *)&cmd_showport_reta_port_id,
                (void *)&cmd_showport_reta_rss,
                (void *)&cmd_showport_reta_reta,
-               (void *)&cmd_showport_reta_mask_lo,
-               (void *)&cmd_showport_reta_mask_hi,
+               (void *)&cmd_showport_reta_size,
+               (void *)&cmd_showport_reta_list_of_items,
                NULL,
        },
 };
@@ -1743,6 +2001,7 @@ struct cmd_showport_rss_hash {
        cmdline_fixed_string_t port;
        uint8_t port_id;
        cmdline_fixed_string_t rss_hash;
+       cmdline_fixed_string_t rss_type;
        cmdline_fixed_string_t key; /* optional argument */
 };
 
@@ -1752,7 +2011,8 @@ static void cmd_showport_rss_hash_parsed(void *parsed_result,
 {
        struct cmd_showport_rss_hash *res = parsed_result;
 
-       port_rss_hash_conf_show(res->port_id, show_rss_key != NULL);
+       port_rss_hash_conf_show(res->port_id, res->rss_type,
+                               show_rss_key != NULL);
 }
 
 cmdline_parse_token_string_t cmd_showport_rss_hash_show =
@@ -1764,18 +2024,29 @@ cmdline_parse_token_num_t cmd_showport_rss_hash_port_id =
 cmdline_parse_token_string_t cmd_showport_rss_hash_rss_hash =
        TOKEN_STRING_INITIALIZER(struct cmd_showport_rss_hash, rss_hash,
                                 "rss-hash");
+cmdline_parse_token_string_t cmd_showport_rss_hash_rss_hash_info =
+       TOKEN_STRING_INITIALIZER(struct cmd_showport_rss_hash, rss_type,
+                                "ipv4#ipv4-frag#ipv4-tcp#ipv4-udp#ipv4-sctp#"
+                                "ipv4-other#ipv6#ipv6-frag#ipv6-tcp#ipv6-udp#"
+                                "ipv6-sctp#ipv6-other#l2-payload#ipv6-ex#"
+                                "ipv6-tcp-ex#ipv6-udp-ex");
 cmdline_parse_token_string_t cmd_showport_rss_hash_rss_key =
        TOKEN_STRING_INITIALIZER(struct cmd_showport_rss_hash, key, "key");
 
 cmdline_parse_inst_t cmd_showport_rss_hash = {
        .f = cmd_showport_rss_hash_parsed,
        .data = NULL,
-       .help_str = "show port X rss-hash (X = port number)\n",
+       .help_str =
+               "show port X rss-hash ipv4|ipv4-frag|ipv4-tcp|ipv4-udp|"
+               "ipv4-sctp|ipv4-other|ipv6|ipv6-frag|ipv6-tcp|ipv6-udp|"
+               "ipv6-sctp|ipv6-other|l2-payload|"
+               "ipv6-ex|ipv6-tcp-ex|ipv6-udp-ex (X = port number)\n",
        .tokens = {
                (void *)&cmd_showport_rss_hash_show,
                (void *)&cmd_showport_rss_hash_port,
                (void *)&cmd_showport_rss_hash_port_id,
                (void *)&cmd_showport_rss_hash_rss_hash,
+               (void *)&cmd_showport_rss_hash_rss_hash_info,
                NULL,
        },
 };
@@ -1783,12 +2054,17 @@ cmdline_parse_inst_t cmd_showport_rss_hash = {
 cmdline_parse_inst_t cmd_showport_rss_hash_key = {
        .f = cmd_showport_rss_hash_parsed,
        .data = (void *)1,
-       .help_str = "show port X rss-hash key (X = port number)\n",
+       .help_str =
+               "show port X rss-hash ipv4|ipv4-frag|ipv4-tcp|ipv4-udp|"
+               "ipv4-sctp|ipv4-other|ipv6|ipv6-frag|ipv6-tcp|ipv6-udp|"
+               "ipv6-sctp|ipv6-other|l2-payload|"
+               "ipv6-ex|ipv6-tcp-ex|ipv6-udp-ex key (X = port number)\n",
        .tokens = {
                (void *)&cmd_showport_rss_hash_show,
                (void *)&cmd_showport_rss_hash_port,
                (void *)&cmd_showport_rss_hash_port_id,
                (void *)&cmd_showport_rss_hash_rss_hash,
+               (void *)&cmd_showport_rss_hash_rss_hash_info,
                (void *)&cmd_showport_rss_hash_rss_key,
                NULL,
        },
@@ -1813,37 +2089,46 @@ cmd_config_dcb_parsed(void *parsed_result,
                         __attribute__((unused)) void *data)
 {
        struct cmd_config_dcb *res = parsed_result;
-       struct dcb_config dcb_conf;
        portid_t port_id = res->port_id;
        struct rte_port *port;
+       uint8_t pfc_en;
+       int ret;
 
        port = &ports[port_id];
        /** Check if the port is not started **/
        if (port->port_status != RTE_PORT_STOPPED) {
-               printf("Please stop port %d first\n",port_id);
+               printf("Please stop port %d first\n", port_id);
                return;
        }
 
-       dcb_conf.num_tcs = (enum rte_eth_nb_tcs) res->num_tcs;
-       if ((dcb_conf.num_tcs != ETH_4_TCS) && (dcb_conf.num_tcs != ETH_8_TCS)){
-               printf("The invalid number of traffic class,only 4 or 8 allowed\n");
+       if ((res->num_tcs != ETH_4_TCS) && (res->num_tcs != ETH_8_TCS)) {
+               printf("The invalid number of traffic class,"
+                       " only 4 or 8 allowed.\n");
                return;
        }
 
-       /* DCB in VT mode */
-       if (!strncmp(res->vt_en, "on",2))
-               dcb_conf.dcb_mode = DCB_VT_ENABLED;
+       if (nb_fwd_lcores < res->num_tcs) {
+               printf("nb_cores shouldn't be less than number of TCs.\n");
+               return;
+       }
+       if (!strncmp(res->pfc_en, "on", 2))
+               pfc_en = 1;
        else
-               dcb_conf.dcb_mode = DCB_ENABLED;
+               pfc_en = 0;
 
-       if (!strncmp(res->pfc_en, "on",2)) {
-               dcb_conf.pfc_en = 1;
-       }
+       /* DCB in VT mode */
+       if (!strncmp(res->vt_en, "on", 2))
+               ret = init_port_dcb_config(port_id, DCB_VT_ENABLED,
+                               (enum rte_eth_nb_tcs)res->num_tcs,
+                               pfc_en);
        else
-               dcb_conf.pfc_en = 0;
+               ret = init_port_dcb_config(port_id, DCB_ENABLED,
+                               (enum rte_eth_nb_tcs)res->num_tcs,
+                               pfc_en);
+
 
-       if (init_port_dcb_config(port_id,&dcb_conf) != 0) {
-               printf("Cannot initialize network ports\n");
+       if (ret != 0) {
+               printf("Cannot initialize network ports.\n");
                return;
        }
 
@@ -1971,17 +2256,17 @@ cmd_config_thresh_parsed(void *parsed_result,
        }
 
        if (!strcmp(res->name, "txpt"))
-               tx_thresh.pthresh = res->value;
+               tx_pthresh = res->value;
        else if(!strcmp(res->name, "txht"))
-               tx_thresh.hthresh = res->value;
+               tx_hthresh = res->value;
        else if(!strcmp(res->name, "txwt"))
-               tx_thresh.wthresh = res->value;
+               tx_wthresh = res->value;
        else if(!strcmp(res->name, "rxpt"))
-               rx_thresh.pthresh = res->value;
+               rx_pthresh = res->value;
        else if(!strcmp(res->name, "rxht"))
-               rx_thresh.hthresh = res->value;
+               rx_hthresh = res->value;
        else if(!strcmp(res->name, "rxwt"))
-               rx_thresh.wthresh = res->value;
+               rx_wthresh = res->value;
        else {
                printf("Unknown parameter\n");
                return;
@@ -2109,7 +2394,7 @@ cmdline_parse_inst_t cmd_stop = {
 
 /* *** SET CORELIST and PORTLIST CONFIGURATION *** */
 
-static unsigned int
+unsigned int
 parse_item_list(char* str, const char* item_name, unsigned int max_items,
                unsigned int *parsed_items, int check_unique_values)
 {
@@ -2135,11 +2420,11 @@ parse_item_list(char* str, const char* item_name, unsigned int max_items,
                }
                if (c != ',') {
                        printf("character %c is not a decimal digit\n", c);
-                       return (0);
+                       return 0;
                }
                if (! value_ok) {
                        printf("No valid value before comma\n");
-                       return (0);
+                       return 0;
                }
                if (nb_item < max_items) {
                        parsed_items[nb_item] = value;
@@ -2151,11 +2436,11 @@ parse_item_list(char* str, const char* item_name, unsigned int max_items,
        if (nb_item >= max_items) {
                printf("Number of %s = %u > %u (maximum items)\n",
                       item_name, nb_item + 1, max_items);
-               return (0);
+               return 0;
        }
        parsed_items[nb_item++] = value;
        if (! check_unique_values)
-               return (nb_item);
+               return nb_item;
 
        /*
         * Then, check that all values in the list are differents.
@@ -2166,11 +2451,11 @@ parse_item_list(char* str, const char* item_name, unsigned int max_items,
                        if (parsed_items[j] == parsed_items[i]) {
                                printf("duplicated %s %u at index %u and %u\n",
                                       item_name, parsed_items[i], i, j);
-                               return (0);
+                               return 0;
                        }
                }
        }
-       return (nb_item);
+       return nb_item;
 }
 
 struct cmd_set_list_result {
@@ -2190,6 +2475,11 @@ static void cmd_set_list_parsed(void *parsed_result,
        } parsed_items;
        unsigned int nb_item;
 
+       if (test_done == 0) {
+               printf("Please stop forwarding first\n");
+               return;
+       }
+
        res = parsed_result;
        if (!strcmp(res->list_name, "corelist")) {
                nb_item = parse_item_list(res->list_of_items, "core",
@@ -2244,6 +2534,10 @@ static void cmd_set_mask_parsed(void *parsed_result,
 {
        struct cmd_setmask_result *res = parsed_result;
 
+       if (test_done == 0) {
+               printf("Please stop forwarding first\n");
+               return;
+       }
        if (!strcmp(res->mask, "coremask"))
                set_fwd_lcores_mask(res->hexavalue);
        else if (!strcmp(res->mask, "portmask"))
@@ -2360,6 +2654,47 @@ cmdline_parse_inst_t cmd_set_txpkts = {
        },
 };
 
+/* *** SET COPY AND SPLIT POLICY ON TX PACKETS *** */
+
+struct cmd_set_txsplit_result {
+       cmdline_fixed_string_t cmd_keyword;
+       cmdline_fixed_string_t txsplit;
+       cmdline_fixed_string_t mode;
+};
+
+static void
+cmd_set_txsplit_parsed(void *parsed_result,
+                     __attribute__((unused)) struct cmdline *cl,
+                     __attribute__((unused)) void *data)
+{
+       struct cmd_set_txsplit_result *res;
+
+       res = parsed_result;
+       set_tx_pkt_split(res->mode);
+}
+
+cmdline_parse_token_string_t cmd_set_txsplit_keyword =
+       TOKEN_STRING_INITIALIZER(struct cmd_set_txsplit_result,
+                                cmd_keyword, "set");
+cmdline_parse_token_string_t cmd_set_txsplit_name =
+       TOKEN_STRING_INITIALIZER(struct cmd_set_txsplit_result,
+                                txsplit, "txsplit");
+cmdline_parse_token_string_t cmd_set_txsplit_mode =
+       TOKEN_STRING_INITIALIZER(struct cmd_set_txsplit_result,
+                                mode, NULL);
+
+cmdline_parse_inst_t cmd_set_txsplit = {
+       .f = cmd_set_txsplit_parsed,
+       .data = NULL,
+       .help_str = "set txsplit on|off|rand",
+       .tokens = {
+               (void *)&cmd_set_txsplit_keyword,
+               (void *)&cmd_set_txsplit_name,
+               (void *)&cmd_set_txsplit_mode,
+               NULL,
+       },
+};
+
 /* *** ADD/REMOVE ALL VLAN IDENTIFIERS TO/FROM A PORT VLAN RX FILTER *** */
 struct cmd_rx_vlan_filter_all_result {
        cmdline_fixed_string_t rx_vlan;
@@ -2609,8 +2944,8 @@ cmdline_parse_inst_t cmd_rx_vlan_filter = {
 struct cmd_tx_vlan_set_result {
        cmdline_fixed_string_t tx_vlan;
        cmdline_fixed_string_t set;
-       uint16_t vlan_id;
        uint8_t port_id;
+       uint16_t vlan_id;
 };
 
 static void
@@ -2619,6 +2954,13 @@ cmd_tx_vlan_set_parsed(void *parsed_result,
                       __attribute__((unused)) void *data)
 {
        struct cmd_tx_vlan_set_result *res = parsed_result;
+       int vlan_offload = rte_eth_dev_get_vlan_offload(res->port_id);
+
+       if (vlan_offload & ETH_VLAN_EXTEND_OFFLOAD) {
+               printf("Error, as QinQ has been enabled.\n");
+               return;
+       }
+
        tx_vlan_set(res->port_id, res->vlan_id);
 }
 
@@ -2638,13 +2980,69 @@ cmdline_parse_token_num_t cmd_tx_vlan_set_portid =
 cmdline_parse_inst_t cmd_tx_vlan_set = {
        .f = cmd_tx_vlan_set_parsed,
        .data = NULL,
-       .help_str = "enable hardware insertion of a VLAN header with a given "
-       "TAG Identifier in packets sent on a port",
+       .help_str = "enable hardware insertion of a single VLAN header "
+               "with a given TAG Identifier in packets sent on a port",
        .tokens = {
                (void *)&cmd_tx_vlan_set_tx_vlan,
                (void *)&cmd_tx_vlan_set_set,
-               (void *)&cmd_tx_vlan_set_vlanid,
                (void *)&cmd_tx_vlan_set_portid,
+               (void *)&cmd_tx_vlan_set_vlanid,
+               NULL,
+       },
+};
+
+/* *** ENABLE HARDWARE INSERTION OF Double VLAN HEADER IN TX PACKETS *** */
+struct cmd_tx_vlan_set_qinq_result {
+       cmdline_fixed_string_t tx_vlan;
+       cmdline_fixed_string_t set;
+       uint8_t port_id;
+       uint16_t vlan_id;
+       uint16_t vlan_id_outer;
+};
+
+static void
+cmd_tx_vlan_set_qinq_parsed(void *parsed_result,
+                           __attribute__((unused)) struct cmdline *cl,
+                           __attribute__((unused)) void *data)
+{
+       struct cmd_tx_vlan_set_qinq_result *res = parsed_result;
+       int vlan_offload = rte_eth_dev_get_vlan_offload(res->port_id);
+
+       if (!(vlan_offload & ETH_VLAN_EXTEND_OFFLOAD)) {
+               printf("Error, as QinQ hasn't been enabled.\n");
+               return;
+       }
+
+       tx_qinq_set(res->port_id, res->vlan_id, res->vlan_id_outer);
+}
+
+cmdline_parse_token_string_t cmd_tx_vlan_set_qinq_tx_vlan =
+       TOKEN_STRING_INITIALIZER(struct cmd_tx_vlan_set_qinq_result,
+               tx_vlan, "tx_vlan");
+cmdline_parse_token_string_t cmd_tx_vlan_set_qinq_set =
+       TOKEN_STRING_INITIALIZER(struct cmd_tx_vlan_set_qinq_result,
+               set, "set");
+cmdline_parse_token_num_t cmd_tx_vlan_set_qinq_portid =
+       TOKEN_NUM_INITIALIZER(struct cmd_tx_vlan_set_qinq_result,
+               port_id, UINT8);
+cmdline_parse_token_num_t cmd_tx_vlan_set_qinq_vlanid =
+       TOKEN_NUM_INITIALIZER(struct cmd_tx_vlan_set_qinq_result,
+               vlan_id, UINT16);
+cmdline_parse_token_num_t cmd_tx_vlan_set_qinq_vlanid_outer =
+       TOKEN_NUM_INITIALIZER(struct cmd_tx_vlan_set_qinq_result,
+               vlan_id_outer, UINT16);
+
+cmdline_parse_inst_t cmd_tx_vlan_set_qinq = {
+       .f = cmd_tx_vlan_set_qinq_parsed,
+       .data = NULL,
+       .help_str = "enable hardware insertion of double VLAN header "
+               "with given TAG Identifiers in packets sent on a port",
+       .tokens = {
+               (void *)&cmd_tx_vlan_set_qinq_tx_vlan,
+               (void *)&cmd_tx_vlan_set_qinq_set,
+               (void *)&cmd_tx_vlan_set_qinq_portid,
+               (void *)&cmd_tx_vlan_set_qinq_vlanid,
+               (void *)&cmd_tx_vlan_set_qinq_vlanid_outer,
                NULL,
        },
 };
@@ -2748,67 +3146,301 @@ cmdline_parse_inst_t cmd_tx_vlan_reset = {
 
 
 /* *** ENABLE HARDWARE INSERTION OF CHECKSUM IN TX PACKETS *** */
-struct cmd_tx_cksum_set_result {
-       cmdline_fixed_string_t tx_cksum;
-       cmdline_fixed_string_t set;
-       uint8_t cksum_mask;
+struct cmd_csum_result {
+       cmdline_fixed_string_t csum;
+       cmdline_fixed_string_t mode;
+       cmdline_fixed_string_t proto;
+       cmdline_fixed_string_t hwsw;
        uint8_t port_id;
 };
 
 static void
-cmd_tx_cksum_set_parsed(void *parsed_result,
+csum_show(int port_id)
+{
+       struct rte_eth_dev_info dev_info;
+       uint16_t ol_flags;
+
+       ol_flags = ports[port_id].tx_ol_flags;
+       printf("Parse tunnel is %s\n",
+               (ol_flags & TESTPMD_TX_OFFLOAD_PARSE_TUNNEL) ? "on" : "off");
+       printf("IP checksum offload is %s\n",
+               (ol_flags & TESTPMD_TX_OFFLOAD_IP_CKSUM) ? "hw" : "sw");
+       printf("UDP checksum offload is %s\n",
+               (ol_flags & TESTPMD_TX_OFFLOAD_UDP_CKSUM) ? "hw" : "sw");
+       printf("TCP checksum offload is %s\n",
+               (ol_flags & TESTPMD_TX_OFFLOAD_TCP_CKSUM) ? "hw" : "sw");
+       printf("SCTP checksum offload is %s\n",
+               (ol_flags & TESTPMD_TX_OFFLOAD_SCTP_CKSUM) ? "hw" : "sw");
+       printf("Outer-Ip checksum offload is %s\n",
+               (ol_flags & TESTPMD_TX_OFFLOAD_OUTER_IP_CKSUM) ? "hw" : "sw");
+
+       /* display warnings if configuration is not supported by the NIC */
+       rte_eth_dev_info_get(port_id, &dev_info);
+       if ((ol_flags & TESTPMD_TX_OFFLOAD_IP_CKSUM) &&
+               (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_IPV4_CKSUM) == 0) {
+               printf("Warning: hardware IP checksum enabled but not "
+                       "supported by port %d\n", port_id);
+       }
+       if ((ol_flags & TESTPMD_TX_OFFLOAD_UDP_CKSUM) &&
+               (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_UDP_CKSUM) == 0) {
+               printf("Warning: hardware UDP checksum enabled but not "
+                       "supported by port %d\n", port_id);
+       }
+       if ((ol_flags & TESTPMD_TX_OFFLOAD_TCP_CKSUM) &&
+               (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_TCP_CKSUM) == 0) {
+               printf("Warning: hardware TCP checksum enabled but not "
+                       "supported by port %d\n", port_id);
+       }
+       if ((ol_flags & TESTPMD_TX_OFFLOAD_SCTP_CKSUM) &&
+               (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_SCTP_CKSUM) == 0) {
+               printf("Warning: hardware SCTP checksum enabled but not "
+                       "supported by port %d\n", port_id);
+       }
+       if ((ol_flags & TESTPMD_TX_OFFLOAD_OUTER_IP_CKSUM) &&
+               (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_OUTER_IPV4_CKSUM) == 0) {
+               printf("Warning: hardware outer IP checksum enabled but not "
+                       "supported by port %d\n", port_id);
+       }
+}
+
+static void
+cmd_csum_parsed(void *parsed_result,
                       __attribute__((unused)) struct cmdline *cl,
                       __attribute__((unused)) void *data)
 {
-       struct cmd_tx_cksum_set_result *res = parsed_result;
+       struct cmd_csum_result *res = parsed_result;
+       int hw = 0;
+       uint16_t mask = 0;
+
+       if (port_id_is_invalid(res->port_id, ENABLED_WARN)) {
+               printf("invalid port %d\n", res->port_id);
+               return;
+       }
+
+       if (!strcmp(res->mode, "set")) {
+
+               if (!strcmp(res->hwsw, "hw"))
+                       hw = 1;
+
+               if (!strcmp(res->proto, "ip")) {
+                       mask = TESTPMD_TX_OFFLOAD_IP_CKSUM;
+               } else if (!strcmp(res->proto, "udp")) {
+                       mask = TESTPMD_TX_OFFLOAD_UDP_CKSUM;
+               } else if (!strcmp(res->proto, "tcp")) {
+                       mask = TESTPMD_TX_OFFLOAD_TCP_CKSUM;
+               } else if (!strcmp(res->proto, "sctp")) {
+                       mask = TESTPMD_TX_OFFLOAD_SCTP_CKSUM;
+               } else if (!strcmp(res->proto, "outer-ip")) {
+                       mask = TESTPMD_TX_OFFLOAD_OUTER_IP_CKSUM;
+               }
 
-       tx_cksum_set(res->port_id, res->cksum_mask);
+               if (hw)
+                       ports[res->port_id].tx_ol_flags |= mask;
+               else
+                       ports[res->port_id].tx_ol_flags &= (~mask);
+       }
+       csum_show(res->port_id);
 }
 
-cmdline_parse_token_string_t cmd_tx_cksum_set_tx_cksum =
-       TOKEN_STRING_INITIALIZER(struct cmd_tx_cksum_set_result,
-                               tx_cksum, "tx_checksum");
-cmdline_parse_token_string_t cmd_tx_cksum_set_set =
-       TOKEN_STRING_INITIALIZER(struct cmd_tx_cksum_set_result,
-                               set, "set");
-cmdline_parse_token_num_t cmd_tx_cksum_set_cksum_mask =
-       TOKEN_NUM_INITIALIZER(struct cmd_tx_cksum_set_result,
-                               cksum_mask, UINT8);
-cmdline_parse_token_num_t cmd_tx_cksum_set_portid =
-       TOKEN_NUM_INITIALIZER(struct cmd_tx_cksum_set_result,
+cmdline_parse_token_string_t cmd_csum_csum =
+       TOKEN_STRING_INITIALIZER(struct cmd_csum_result,
+                               csum, "csum");
+cmdline_parse_token_string_t cmd_csum_mode =
+       TOKEN_STRING_INITIALIZER(struct cmd_csum_result,
+                               mode, "set");
+cmdline_parse_token_string_t cmd_csum_proto =
+       TOKEN_STRING_INITIALIZER(struct cmd_csum_result,
+                               proto, "ip#tcp#udp#sctp#outer-ip");
+cmdline_parse_token_string_t cmd_csum_hwsw =
+       TOKEN_STRING_INITIALIZER(struct cmd_csum_result,
+                               hwsw, "hw#sw");
+cmdline_parse_token_num_t cmd_csum_portid =
+       TOKEN_NUM_INITIALIZER(struct cmd_csum_result,
                                port_id, UINT8);
 
-cmdline_parse_inst_t cmd_tx_cksum_set = {
-       .f = cmd_tx_cksum_set_parsed,
+cmdline_parse_inst_t cmd_csum_set = {
+       .f = cmd_csum_parsed,
        .data = NULL,
-       .help_str = "enable hardware insertion of L3/L4checksum with a given "
-       "mask in packets sent on a port, the bit mapping is given as, Bit 0 for ip, "
-       "Bit 1 for UDP, Bit 2 for TCP, Bit 3 for SCTP, Bit 4 for inner ip, "
-       "Bit 5 for inner UDP, Bit 6 for inner TCP, Bit 7 for inner SCTP",
+       .help_str = "enable/disable hardware calculation of L3/L4 checksum when "
+               "using csum forward engine: csum set ip|tcp|udp|sctp|outer-ip hw|sw <port>",
        .tokens = {
-               (void *)&cmd_tx_cksum_set_tx_cksum,
-               (void *)&cmd_tx_cksum_set_set,
-               (void *)&cmd_tx_cksum_set_cksum_mask,
-               (void *)&cmd_tx_cksum_set_portid,
+               (void *)&cmd_csum_csum,
+               (void *)&cmd_csum_mode,
+               (void *)&cmd_csum_proto,
+               (void *)&cmd_csum_hwsw,
+               (void *)&cmd_csum_portid,
                NULL,
        },
 };
 
-/* *** ENABLE/DISABLE FLUSH ON RX STREAMS *** */
-struct cmd_set_flush_rx {
-       cmdline_fixed_string_t set;
-       cmdline_fixed_string_t flush_rx;
-       cmdline_fixed_string_t mode;
+cmdline_parse_token_string_t cmd_csum_mode_show =
+       TOKEN_STRING_INITIALIZER(struct cmd_csum_result,
+                               mode, "show");
+
+cmdline_parse_inst_t cmd_csum_show = {
+       .f = cmd_csum_parsed,
+       .data = NULL,
+       .help_str = "show checksum offload configuration: csum show <port>",
+       .tokens = {
+               (void *)&cmd_csum_csum,
+               (void *)&cmd_csum_mode_show,
+               (void *)&cmd_csum_portid,
+               NULL,
+       },
+};
+
+/* Enable/disable tunnel parsing */
+struct cmd_csum_tunnel_result {
+       cmdline_fixed_string_t csum;
+       cmdline_fixed_string_t parse;
+       cmdline_fixed_string_t onoff;
+       uint8_t port_id;
 };
 
 static void
-cmd_set_flush_rx_parsed(void *parsed_result,
-               __attribute__((unused)) struct cmdline *cl,
-               __attribute__((unused)) void *data)
+cmd_csum_tunnel_parsed(void *parsed_result,
+                      __attribute__((unused)) struct cmdline *cl,
+                      __attribute__((unused)) void *data)
 {
-       struct cmd_set_flush_rx *res = parsed_result;
-       no_flush_rx = (uint8_t)((strcmp(res->mode, "on") == 0) ? 0 : 1);
-}
+       struct cmd_csum_tunnel_result *res = parsed_result;
+
+       if (port_id_is_invalid(res->port_id, ENABLED_WARN))
+               return;
+
+       if (!strcmp(res->onoff, "on"))
+               ports[res->port_id].tx_ol_flags |=
+                       TESTPMD_TX_OFFLOAD_PARSE_TUNNEL;
+       else
+               ports[res->port_id].tx_ol_flags &=
+                       (~TESTPMD_TX_OFFLOAD_PARSE_TUNNEL);
+
+       csum_show(res->port_id);
+}
+
+cmdline_parse_token_string_t cmd_csum_tunnel_csum =
+       TOKEN_STRING_INITIALIZER(struct cmd_csum_tunnel_result,
+                               csum, "csum");
+cmdline_parse_token_string_t cmd_csum_tunnel_parse =
+       TOKEN_STRING_INITIALIZER(struct cmd_csum_tunnel_result,
+                               parse, "parse_tunnel");
+cmdline_parse_token_string_t cmd_csum_tunnel_onoff =
+       TOKEN_STRING_INITIALIZER(struct cmd_csum_tunnel_result,
+                               onoff, "on#off");
+cmdline_parse_token_num_t cmd_csum_tunnel_portid =
+       TOKEN_NUM_INITIALIZER(struct cmd_csum_tunnel_result,
+                               port_id, UINT8);
+
+cmdline_parse_inst_t cmd_csum_tunnel = {
+       .f = cmd_csum_tunnel_parsed,
+       .data = NULL,
+       .help_str = "enable/disable parsing of tunnels for csum engine: "
+       "csum parse_tunnel on|off <tx-port>",
+       .tokens = {
+               (void *)&cmd_csum_tunnel_csum,
+               (void *)&cmd_csum_tunnel_parse,
+               (void *)&cmd_csum_tunnel_onoff,
+               (void *)&cmd_csum_tunnel_portid,
+               NULL,
+       },
+};
+
+/* *** ENABLE HARDWARE SEGMENTATION IN TX PACKETS *** */
+struct cmd_tso_set_result {
+       cmdline_fixed_string_t tso;
+       cmdline_fixed_string_t mode;
+       uint16_t tso_segsz;
+       uint8_t port_id;
+};
+
+static void
+cmd_tso_set_parsed(void *parsed_result,
+                      __attribute__((unused)) struct cmdline *cl,
+                      __attribute__((unused)) void *data)
+{
+       struct cmd_tso_set_result *res = parsed_result;
+       struct rte_eth_dev_info dev_info;
+
+       if (port_id_is_invalid(res->port_id, ENABLED_WARN))
+               return;
+
+       if (!strcmp(res->mode, "set"))
+               ports[res->port_id].tso_segsz = res->tso_segsz;
+
+       if (ports[res->port_id].tso_segsz == 0)
+               printf("TSO is disabled\n");
+       else
+               printf("TSO segment size is %d\n",
+                       ports[res->port_id].tso_segsz);
+
+       /* display warnings if configuration is not supported by the NIC */
+       rte_eth_dev_info_get(res->port_id, &dev_info);
+       if ((ports[res->port_id].tso_segsz != 0) &&
+               (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_TCP_TSO) == 0) {
+               printf("Warning: TSO enabled but not "
+                       "supported by port %d\n", res->port_id);
+       }
+}
+
+cmdline_parse_token_string_t cmd_tso_set_tso =
+       TOKEN_STRING_INITIALIZER(struct cmd_tso_set_result,
+                               tso, "tso");
+cmdline_parse_token_string_t cmd_tso_set_mode =
+       TOKEN_STRING_INITIALIZER(struct cmd_tso_set_result,
+                               mode, "set");
+cmdline_parse_token_num_t cmd_tso_set_tso_segsz =
+       TOKEN_NUM_INITIALIZER(struct cmd_tso_set_result,
+                               tso_segsz, UINT16);
+cmdline_parse_token_num_t cmd_tso_set_portid =
+       TOKEN_NUM_INITIALIZER(struct cmd_tso_set_result,
+                               port_id, UINT8);
+
+cmdline_parse_inst_t cmd_tso_set = {
+       .f = cmd_tso_set_parsed,
+       .data = NULL,
+       .help_str = "Set TSO segment size for csum engine (0 to disable): "
+       "tso set <tso_segsz> <port>",
+       .tokens = {
+               (void *)&cmd_tso_set_tso,
+               (void *)&cmd_tso_set_mode,
+               (void *)&cmd_tso_set_tso_segsz,
+               (void *)&cmd_tso_set_portid,
+               NULL,
+       },
+};
+
+cmdline_parse_token_string_t cmd_tso_show_mode =
+       TOKEN_STRING_INITIALIZER(struct cmd_tso_set_result,
+                               mode, "show");
+
+
+cmdline_parse_inst_t cmd_tso_show = {
+       .f = cmd_tso_set_parsed,
+       .data = NULL,
+       .help_str = "Show TSO segment size for csum engine: "
+       "tso show <port>",
+       .tokens = {
+               (void *)&cmd_tso_set_tso,
+               (void *)&cmd_tso_show_mode,
+               (void *)&cmd_tso_set_portid,
+               NULL,
+       },
+};
+
+/* *** ENABLE/DISABLE FLUSH ON RX STREAMS *** */
+struct cmd_set_flush_rx {
+       cmdline_fixed_string_t set;
+       cmdline_fixed_string_t flush_rx;
+       cmdline_fixed_string_t mode;
+};
+
+static void
+cmd_set_flush_rx_parsed(void *parsed_result,
+               __attribute__((unused)) struct cmdline *cl,
+               __attribute__((unused)) void *data)
+{
+       struct cmd_set_flush_rx *res = parsed_result;
+       no_flush_rx = (uint8_t)((strcmp(res->mode, "on") == 0) ? 0 : 1);
+}
 
 cmdline_parse_token_string_t cmd_setflushrx_set =
        TOKEN_STRING_INITIALIZER(struct cmd_set_flush_rx,
@@ -3526,6 +4158,7 @@ static void cmd_add_bonding_slave_parsed(void *parsed_result,
                return;
        }
        init_port_config();
+       set_port_slave_flag(slave_port_id);
 }
 
 cmdline_parse_token_string_t cmd_addbonding_slave_add =
@@ -3582,6 +4215,7 @@ static void cmd_remove_bonding_slave_parsed(void *parsed_result,
                return;
        }
        init_port_config();
+       clear_port_slave_flag(slave_port_id);
 }
 
 cmdline_parse_token_string_t cmd_removebonding_slave_remove =
@@ -3652,8 +4286,9 @@ static void cmd_create_bonded_device_parsed(void *parsed_result,
 
                /* Update number of ports */
                nb_ports = rte_eth_dev_count();
-               reconfig(port_id);
+               reconfig(port_id, res->socket);
                rte_eth_promiscuous_enable(port_id);
+               ports[port_id].enabled = 1;
        }
 
 }
@@ -3704,10 +4339,8 @@ static void cmd_set_bond_mac_addr_parsed(void *parsed_result,
        struct cmd_set_bond_mac_addr_result *res = parsed_result;
        int ret;
 
-       if (res->port_num >= nb_ports) {
-               printf("Port id %d must be less than %d\n", res->port_num, nb_ports);
+       if (port_id_is_invalid(res->port_num, ENABLED_WARN))
                return;
-       }
 
        ret = rte_eth_bond_mac_address_set(res->port_num, &res->address);
 
@@ -3944,7 +4577,7 @@ static void cmd_set_promisc_mode_parsed(void *parsed_result,
 
        /* all ports */
        if (allports) {
-               for (i = 0; i < nb_ports; i++) {
+               FOREACH_PORT(i, ports) {
                        if (enable)
                                rte_eth_promiscuous_enable(i);
                        else
@@ -4024,7 +4657,7 @@ static void cmd_set_allmulti_mode_parsed(void *parsed_result,
 
        /* all ports */
        if (allports) {
-               for (i = 0; i < nb_ports; i++) {
+               FOREACH_PORT(i, ports) {
                        if (enable)
                                rte_eth_allmulticast_enable(i);
                        else
@@ -4080,503 +4713,6 @@ cmdline_parse_inst_t cmd_set_allmulti_mode_one = {
        },
 };
 
-/* *** ADD/REMOVE A PKT FILTER *** */
-struct cmd_pkt_filter_result {
-       cmdline_fixed_string_t pkt_filter;
-       uint8_t  port_id;
-       cmdline_fixed_string_t protocol;
-       cmdline_fixed_string_t src;
-       cmdline_ipaddr_t ip_src;
-       uint16_t port_src;
-       cmdline_fixed_string_t dst;
-       cmdline_ipaddr_t ip_dst;
-       uint16_t port_dst;
-       cmdline_fixed_string_t flexbytes;
-       uint16_t flexbytes_value;
-       cmdline_fixed_string_t vlan;
-       uint16_t  vlan_id;
-       cmdline_fixed_string_t queue;
-       int8_t  queue_id;
-       cmdline_fixed_string_t soft;
-       uint8_t  soft_id;
-};
-
-static void
-cmd_pkt_filter_parsed(void *parsed_result,
-                         __attribute__((unused)) struct cmdline *cl,
-                         __attribute__((unused)) void *data)
-{
-       struct rte_fdir_filter fdir_filter;
-       struct cmd_pkt_filter_result *res = parsed_result;
-
-       memset(&fdir_filter, 0, sizeof(struct rte_fdir_filter));
-
-       if (res->ip_src.family == AF_INET)
-               fdir_filter.ip_src.ipv4_addr = res->ip_src.addr.ipv4.s_addr;
-       else
-               memcpy(&(fdir_filter.ip_src.ipv6_addr),
-                      &(res->ip_src.addr.ipv6),
-                      sizeof(struct in6_addr));
-
-       if (res->ip_dst.family == AF_INET)
-               fdir_filter.ip_dst.ipv4_addr = res->ip_dst.addr.ipv4.s_addr;
-       else
-               memcpy(&(fdir_filter.ip_dst.ipv6_addr),
-                      &(res->ip_dst.addr.ipv6),
-                      sizeof(struct in6_addr));
-
-       fdir_filter.port_dst = rte_cpu_to_be_16(res->port_dst);
-       fdir_filter.port_src = rte_cpu_to_be_16(res->port_src);
-
-       if (!strcmp(res->protocol, "udp"))
-               fdir_filter.l4type = RTE_FDIR_L4TYPE_UDP;
-       else if (!strcmp(res->protocol, "tcp"))
-               fdir_filter.l4type = RTE_FDIR_L4TYPE_TCP;
-       else if (!strcmp(res->protocol, "sctp"))
-               fdir_filter.l4type = RTE_FDIR_L4TYPE_SCTP;
-       else /* default only IP */
-               fdir_filter.l4type = RTE_FDIR_L4TYPE_NONE;
-
-       if (res->ip_dst.family == AF_INET6)
-               fdir_filter.iptype = RTE_FDIR_IPTYPE_IPV6;
-       else
-               fdir_filter.iptype = RTE_FDIR_IPTYPE_IPV4;
-
-       fdir_filter.vlan_id    = rte_cpu_to_be_16(res->vlan_id);
-       fdir_filter.flex_bytes = rte_cpu_to_be_16(res->flexbytes_value);
-
-       if (!strcmp(res->pkt_filter, "add_signature_filter"))
-               fdir_add_signature_filter(res->port_id, res->queue_id,
-                                         &fdir_filter);
-       else if (!strcmp(res->pkt_filter, "upd_signature_filter"))
-               fdir_update_signature_filter(res->port_id, res->queue_id,
-                                            &fdir_filter);
-       else if (!strcmp(res->pkt_filter, "rm_signature_filter"))
-               fdir_remove_signature_filter(res->port_id, &fdir_filter);
-       else if (!strcmp(res->pkt_filter, "add_perfect_filter"))
-               fdir_add_perfect_filter(res->port_id, res->soft_id,
-                                       res->queue_id,
-                                       (uint8_t) (res->queue_id < 0),
-                                       &fdir_filter);
-       else if (!strcmp(res->pkt_filter, "upd_perfect_filter"))
-               fdir_update_perfect_filter(res->port_id, res->soft_id,
-                                          res->queue_id,
-                                          (uint8_t) (res->queue_id < 0),
-                                          &fdir_filter);
-       else if (!strcmp(res->pkt_filter, "rm_perfect_filter"))
-               fdir_remove_perfect_filter(res->port_id, res->soft_id,
-                                          &fdir_filter);
-
-}
-
-
-cmdline_parse_token_num_t cmd_pkt_filter_port_id =
-       TOKEN_NUM_INITIALIZER(struct cmd_pkt_filter_result,
-                             port_id, UINT8);
-cmdline_parse_token_string_t cmd_pkt_filter_protocol =
-       TOKEN_STRING_INITIALIZER(struct cmd_pkt_filter_result,
-                                protocol, "ip#tcp#udp#sctp");
-cmdline_parse_token_string_t cmd_pkt_filter_src =
-       TOKEN_STRING_INITIALIZER(struct cmd_pkt_filter_result,
-                                src, "src");
-cmdline_parse_token_ipaddr_t cmd_pkt_filter_ip_src =
-       TOKEN_IPADDR_INITIALIZER(struct cmd_pkt_filter_result,
-                                ip_src);
-cmdline_parse_token_num_t cmd_pkt_filter_port_src =
-       TOKEN_NUM_INITIALIZER(struct cmd_pkt_filter_result,
-                             port_src, UINT16);
-cmdline_parse_token_string_t cmd_pkt_filter_dst =
-       TOKEN_STRING_INITIALIZER(struct cmd_pkt_filter_result,
-                                dst, "dst");
-cmdline_parse_token_ipaddr_t cmd_pkt_filter_ip_dst =
-       TOKEN_IPADDR_INITIALIZER(struct cmd_pkt_filter_result,
-                                ip_dst);
-cmdline_parse_token_num_t cmd_pkt_filter_port_dst =
-       TOKEN_NUM_INITIALIZER(struct cmd_pkt_filter_result,
-                             port_dst, UINT16);
-cmdline_parse_token_string_t cmd_pkt_filter_flexbytes =
-       TOKEN_STRING_INITIALIZER(struct cmd_pkt_filter_result,
-                                flexbytes, "flexbytes");
-cmdline_parse_token_num_t cmd_pkt_filter_flexbytes_value =
-       TOKEN_NUM_INITIALIZER(struct cmd_pkt_filter_result,
-                             flexbytes_value, UINT16);
-cmdline_parse_token_string_t cmd_pkt_filter_vlan =
-       TOKEN_STRING_INITIALIZER(struct cmd_pkt_filter_result,
-                                vlan, "vlan");
-cmdline_parse_token_num_t cmd_pkt_filter_vlan_id =
-       TOKEN_NUM_INITIALIZER(struct cmd_pkt_filter_result,
-                             vlan_id, UINT16);
-cmdline_parse_token_string_t cmd_pkt_filter_queue =
-       TOKEN_STRING_INITIALIZER(struct cmd_pkt_filter_result,
-                                queue, "queue");
-cmdline_parse_token_num_t cmd_pkt_filter_queue_id =
-       TOKEN_NUM_INITIALIZER(struct cmd_pkt_filter_result,
-                             queue_id, INT8);
-cmdline_parse_token_string_t cmd_pkt_filter_soft =
-       TOKEN_STRING_INITIALIZER(struct cmd_pkt_filter_result,
-                                soft, "soft");
-cmdline_parse_token_num_t cmd_pkt_filter_soft_id =
-       TOKEN_NUM_INITIALIZER(struct cmd_pkt_filter_result,
-                             soft_id, UINT16);
-
-
-cmdline_parse_token_string_t cmd_pkt_filter_add_signature_filter =
-       TOKEN_STRING_INITIALIZER(struct cmd_pkt_filter_result,
-                                pkt_filter, "add_signature_filter");
-cmdline_parse_inst_t cmd_add_signature_filter = {
-       .f = cmd_pkt_filter_parsed,
-       .data = NULL,
-       .help_str = "add a signature filter",
-       .tokens = {
-               (void *)&cmd_pkt_filter_add_signature_filter,
-               (void *)&cmd_pkt_filter_port_id,
-               (void *)&cmd_pkt_filter_protocol,
-               (void *)&cmd_pkt_filter_src,
-               (void *)&cmd_pkt_filter_ip_src,
-               (void *)&cmd_pkt_filter_port_src,
-               (void *)&cmd_pkt_filter_dst,
-               (void *)&cmd_pkt_filter_ip_dst,
-               (void *)&cmd_pkt_filter_port_dst,
-               (void *)&cmd_pkt_filter_flexbytes,
-               (void *)&cmd_pkt_filter_flexbytes_value,
-               (void *)&cmd_pkt_filter_vlan,
-               (void *)&cmd_pkt_filter_vlan_id,
-               (void *)&cmd_pkt_filter_queue,
-               (void *)&cmd_pkt_filter_queue_id,
-               NULL,
-       },
-};
-
-
-cmdline_parse_token_string_t cmd_pkt_filter_upd_signature_filter =
-       TOKEN_STRING_INITIALIZER(struct cmd_pkt_filter_result,
-                                pkt_filter, "upd_signature_filter");
-cmdline_parse_inst_t cmd_upd_signature_filter = {
-       .f = cmd_pkt_filter_parsed,
-       .data = NULL,
-       .help_str = "update a signature filter",
-       .tokens = {
-               (void *)&cmd_pkt_filter_upd_signature_filter,
-               (void *)&cmd_pkt_filter_port_id,
-               (void *)&cmd_pkt_filter_protocol,
-               (void *)&cmd_pkt_filter_src,
-               (void *)&cmd_pkt_filter_ip_src,
-               (void *)&cmd_pkt_filter_port_src,
-               (void *)&cmd_pkt_filter_dst,
-               (void *)&cmd_pkt_filter_ip_dst,
-               (void *)&cmd_pkt_filter_port_dst,
-               (void *)&cmd_pkt_filter_flexbytes,
-               (void *)&cmd_pkt_filter_flexbytes_value,
-               (void *)&cmd_pkt_filter_vlan,
-               (void *)&cmd_pkt_filter_vlan_id,
-               (void *)&cmd_pkt_filter_queue,
-               (void *)&cmd_pkt_filter_queue_id,
-               NULL,
-       },
-};
-
-
-cmdline_parse_token_string_t cmd_pkt_filter_rm_signature_filter =
-       TOKEN_STRING_INITIALIZER(struct cmd_pkt_filter_result,
-                                pkt_filter, "rm_signature_filter");
-cmdline_parse_inst_t cmd_rm_signature_filter = {
-       .f = cmd_pkt_filter_parsed,
-       .data = NULL,
-       .help_str = "remove a signature filter",
-       .tokens = {
-               (void *)&cmd_pkt_filter_rm_signature_filter,
-               (void *)&cmd_pkt_filter_port_id,
-               (void *)&cmd_pkt_filter_protocol,
-               (void *)&cmd_pkt_filter_src,
-               (void *)&cmd_pkt_filter_ip_src,
-               (void *)&cmd_pkt_filter_port_src,
-               (void *)&cmd_pkt_filter_dst,
-               (void *)&cmd_pkt_filter_ip_dst,
-               (void *)&cmd_pkt_filter_port_dst,
-               (void *)&cmd_pkt_filter_flexbytes,
-               (void *)&cmd_pkt_filter_flexbytes_value,
-               (void *)&cmd_pkt_filter_vlan,
-               (void *)&cmd_pkt_filter_vlan_id,
-               NULL
-               },
-};
-
-
-cmdline_parse_token_string_t cmd_pkt_filter_add_perfect_filter =
-       TOKEN_STRING_INITIALIZER(struct cmd_pkt_filter_result,
-                                pkt_filter, "add_perfect_filter");
-cmdline_parse_inst_t cmd_add_perfect_filter = {
-       .f = cmd_pkt_filter_parsed,
-       .data = NULL,
-       .help_str = "add a perfect filter",
-       .tokens = {
-               (void *)&cmd_pkt_filter_add_perfect_filter,
-               (void *)&cmd_pkt_filter_port_id,
-               (void *)&cmd_pkt_filter_protocol,
-               (void *)&cmd_pkt_filter_src,
-               (void *)&cmd_pkt_filter_ip_src,
-               (void *)&cmd_pkt_filter_port_src,
-               (void *)&cmd_pkt_filter_dst,
-               (void *)&cmd_pkt_filter_ip_dst,
-               (void *)&cmd_pkt_filter_port_dst,
-               (void *)&cmd_pkt_filter_flexbytes,
-               (void *)&cmd_pkt_filter_flexbytes_value,
-               (void *)&cmd_pkt_filter_vlan,
-               (void *)&cmd_pkt_filter_vlan_id,
-               (void *)&cmd_pkt_filter_queue,
-               (void *)&cmd_pkt_filter_queue_id,
-               (void *)&cmd_pkt_filter_soft,
-               (void *)&cmd_pkt_filter_soft_id,
-               NULL,
-       },
-};
-
-
-cmdline_parse_token_string_t cmd_pkt_filter_upd_perfect_filter =
-       TOKEN_STRING_INITIALIZER(struct cmd_pkt_filter_result,
-                                pkt_filter, "upd_perfect_filter");
-cmdline_parse_inst_t cmd_upd_perfect_filter = {
-       .f = cmd_pkt_filter_parsed,
-       .data = NULL,
-       .help_str = "update a perfect filter",
-       .tokens = {
-               (void *)&cmd_pkt_filter_upd_perfect_filter,
-               (void *)&cmd_pkt_filter_port_id,
-               (void *)&cmd_pkt_filter_protocol,
-               (void *)&cmd_pkt_filter_src,
-               (void *)&cmd_pkt_filter_ip_src,
-               (void *)&cmd_pkt_filter_port_src,
-               (void *)&cmd_pkt_filter_dst,
-               (void *)&cmd_pkt_filter_ip_dst,
-               (void *)&cmd_pkt_filter_port_dst,
-               (void *)&cmd_pkt_filter_flexbytes,
-               (void *)&cmd_pkt_filter_flexbytes_value,
-               (void *)&cmd_pkt_filter_vlan,
-               (void *)&cmd_pkt_filter_vlan_id,
-               (void *)&cmd_pkt_filter_queue,
-               (void *)&cmd_pkt_filter_queue_id,
-               (void *)&cmd_pkt_filter_soft,
-               (void *)&cmd_pkt_filter_soft_id,
-               NULL,
-       },
-};
-
-
-cmdline_parse_token_string_t cmd_pkt_filter_rm_perfect_filter =
-       TOKEN_STRING_INITIALIZER(struct cmd_pkt_filter_result,
-                                pkt_filter, "rm_perfect_filter");
-cmdline_parse_inst_t cmd_rm_perfect_filter = {
-       .f = cmd_pkt_filter_parsed,
-       .data = NULL,
-       .help_str = "remove a perfect filter",
-       .tokens = {
-               (void *)&cmd_pkt_filter_rm_perfect_filter,
-               (void *)&cmd_pkt_filter_port_id,
-               (void *)&cmd_pkt_filter_protocol,
-               (void *)&cmd_pkt_filter_src,
-               (void *)&cmd_pkt_filter_ip_src,
-               (void *)&cmd_pkt_filter_port_src,
-               (void *)&cmd_pkt_filter_dst,
-               (void *)&cmd_pkt_filter_ip_dst,
-               (void *)&cmd_pkt_filter_port_dst,
-               (void *)&cmd_pkt_filter_flexbytes,
-               (void *)&cmd_pkt_filter_flexbytes_value,
-               (void *)&cmd_pkt_filter_vlan,
-               (void *)&cmd_pkt_filter_vlan_id,
-               (void *)&cmd_pkt_filter_soft,
-               (void *)&cmd_pkt_filter_soft_id,
-               NULL,
-       },
-};
-
-/* *** SETUP MASKS FILTER *** */
-struct cmd_pkt_filter_masks_result {
-       cmdline_fixed_string_t filter_mask;
-       uint8_t  port_id;
-       cmdline_fixed_string_t src_mask;
-       uint32_t ip_src_mask;
-       uint16_t ipv6_src_mask;
-       uint16_t port_src_mask;
-       cmdline_fixed_string_t dst_mask;
-       uint32_t ip_dst_mask;
-       uint16_t ipv6_dst_mask;
-       uint16_t port_dst_mask;
-       cmdline_fixed_string_t flexbytes;
-       uint8_t flexbytes_value;
-       cmdline_fixed_string_t vlan_id;
-       uint8_t  vlan_id_value;
-       cmdline_fixed_string_t vlan_prio;
-       uint8_t  vlan_prio_value;
-       cmdline_fixed_string_t only_ip_flow;
-       uint8_t  only_ip_flow_value;
-       cmdline_fixed_string_t comp_ipv6_dst;
-       uint8_t  comp_ipv6_dst_value;
-};
-
-static void
-cmd_pkt_filter_masks_parsed(void *parsed_result,
-                         __attribute__((unused)) struct cmdline *cl,
-                         __attribute__((unused)) void *data)
-{
-       struct rte_fdir_masks fdir_masks;
-       struct cmd_pkt_filter_masks_result *res = parsed_result;
-
-       memset(&fdir_masks, 0, sizeof(struct rte_fdir_masks));
-
-       fdir_masks.only_ip_flow  = res->only_ip_flow_value;
-       fdir_masks.vlan_id       = res->vlan_id_value;
-       fdir_masks.vlan_prio     = res->vlan_prio_value;
-       fdir_masks.dst_ipv4_mask = res->ip_dst_mask;
-       fdir_masks.src_ipv4_mask = res->ip_src_mask;
-       fdir_masks.src_port_mask = res->port_src_mask;
-       fdir_masks.dst_port_mask = res->port_dst_mask;
-       fdir_masks.flexbytes     = res->flexbytes_value;
-
-       fdir_set_masks(res->port_id, &fdir_masks);
-}
-
-cmdline_parse_token_string_t cmd_pkt_filter_masks_filter_mask =
-       TOKEN_STRING_INITIALIZER(struct cmd_pkt_filter_masks_result,
-                                filter_mask, "set_masks_filter");
-cmdline_parse_token_num_t cmd_pkt_filter_masks_port_id =
-       TOKEN_NUM_INITIALIZER(struct cmd_pkt_filter_masks_result,
-                             port_id, UINT8);
-cmdline_parse_token_string_t cmd_pkt_filter_masks_only_ip_flow =
-       TOKEN_STRING_INITIALIZER(struct cmd_pkt_filter_masks_result,
-                                only_ip_flow, "only_ip_flow");
-cmdline_parse_token_num_t cmd_pkt_filter_masks_only_ip_flow_value =
-       TOKEN_NUM_INITIALIZER(struct cmd_pkt_filter_masks_result,
-                             only_ip_flow_value, UINT8);
-cmdline_parse_token_string_t cmd_pkt_filter_masks_src_mask =
-       TOKEN_STRING_INITIALIZER(struct cmd_pkt_filter_masks_result,
-                                src_mask, "src_mask");
-cmdline_parse_token_num_t cmd_pkt_filter_masks_ip_src_mask =
-       TOKEN_NUM_INITIALIZER(struct cmd_pkt_filter_masks_result,
-                             ip_src_mask, UINT32);
-cmdline_parse_token_num_t cmd_pkt_filter_masks_port_src_mask =
-       TOKEN_NUM_INITIALIZER(struct cmd_pkt_filter_masks_result,
-                             port_src_mask, UINT16);
-cmdline_parse_token_string_t cmd_pkt_filter_masks_dst_mask =
-       TOKEN_STRING_INITIALIZER(struct cmd_pkt_filter_masks_result,
-                                dst_mask, "dst_mask");
-cmdline_parse_token_num_t cmd_pkt_filter_masks_ip_dst_mask =
-       TOKEN_NUM_INITIALIZER(struct cmd_pkt_filter_masks_result,
-                             ip_dst_mask, UINT32);
-cmdline_parse_token_num_t cmd_pkt_filter_masks_port_dst_mask =
-       TOKEN_NUM_INITIALIZER(struct cmd_pkt_filter_masks_result,
-                             port_dst_mask, UINT16);
-cmdline_parse_token_string_t cmd_pkt_filter_masks_flexbytes =
-       TOKEN_STRING_INITIALIZER(struct cmd_pkt_filter_masks_result,
-                                flexbytes, "flexbytes");
-cmdline_parse_token_num_t cmd_pkt_filter_masks_flexbytes_value =
-       TOKEN_NUM_INITIALIZER(struct cmd_pkt_filter_masks_result,
-                             flexbytes_value, UINT8);
-cmdline_parse_token_string_t cmd_pkt_filter_masks_vlan_id =
-       TOKEN_STRING_INITIALIZER(struct cmd_pkt_filter_masks_result,
-                                vlan_id, "vlan_id");
-cmdline_parse_token_num_t cmd_pkt_filter_masks_vlan_id_value =
-       TOKEN_NUM_INITIALIZER(struct cmd_pkt_filter_masks_result,
-                             vlan_id_value, UINT8);
-cmdline_parse_token_string_t cmd_pkt_filter_masks_vlan_prio =
-       TOKEN_STRING_INITIALIZER(struct cmd_pkt_filter_masks_result,
-                                vlan_prio, "vlan_prio");
-cmdline_parse_token_num_t cmd_pkt_filter_masks_vlan_prio_value =
-       TOKEN_NUM_INITIALIZER(struct cmd_pkt_filter_masks_result,
-                             vlan_prio_value, UINT8);
-
-cmdline_parse_inst_t cmd_set_masks_filter = {
-       .f = cmd_pkt_filter_masks_parsed,
-       .data = NULL,
-       .help_str = "setup masks filter",
-       .tokens = {
-               (void *)&cmd_pkt_filter_masks_filter_mask,
-               (void *)&cmd_pkt_filter_masks_port_id,
-               (void *)&cmd_pkt_filter_masks_only_ip_flow,
-               (void *)&cmd_pkt_filter_masks_only_ip_flow_value,
-               (void *)&cmd_pkt_filter_masks_src_mask,
-               (void *)&cmd_pkt_filter_masks_ip_src_mask,
-               (void *)&cmd_pkt_filter_masks_port_src_mask,
-               (void *)&cmd_pkt_filter_masks_dst_mask,
-               (void *)&cmd_pkt_filter_masks_ip_dst_mask,
-               (void *)&cmd_pkt_filter_masks_port_dst_mask,
-               (void *)&cmd_pkt_filter_masks_flexbytes,
-               (void *)&cmd_pkt_filter_masks_flexbytes_value,
-               (void *)&cmd_pkt_filter_masks_vlan_id,
-               (void *)&cmd_pkt_filter_masks_vlan_id_value,
-               (void *)&cmd_pkt_filter_masks_vlan_prio,
-               (void *)&cmd_pkt_filter_masks_vlan_prio_value,
-               NULL,
-       },
-};
-
-static void
-cmd_pkt_filter_masks_ipv6_parsed(void *parsed_result,
-                         __attribute__((unused)) struct cmdline *cl,
-                         __attribute__((unused)) void *data)
-{
-       struct rte_fdir_masks fdir_masks;
-       struct cmd_pkt_filter_masks_result *res = parsed_result;
-
-       memset(&fdir_masks, 0, sizeof(struct rte_fdir_masks));
-
-       fdir_masks.set_ipv6_mask = 1;
-       fdir_masks.only_ip_flow  = res->only_ip_flow_value;
-       fdir_masks.vlan_id       = res->vlan_id_value;
-       fdir_masks.vlan_prio     = res->vlan_prio_value;
-       fdir_masks.dst_ipv6_mask = res->ipv6_dst_mask;
-       fdir_masks.src_ipv6_mask = res->ipv6_src_mask;
-       fdir_masks.src_port_mask = res->port_src_mask;
-       fdir_masks.dst_port_mask = res->port_dst_mask;
-       fdir_masks.flexbytes     = res->flexbytes_value;
-       fdir_masks.comp_ipv6_dst = res->comp_ipv6_dst_value;
-
-       fdir_set_masks(res->port_id, &fdir_masks);
-}
-
-cmdline_parse_token_string_t cmd_pkt_filter_masks_filter_mask_ipv6 =
-       TOKEN_STRING_INITIALIZER(struct cmd_pkt_filter_masks_result,
-                                filter_mask, "set_ipv6_masks_filter");
-cmdline_parse_token_num_t cmd_pkt_filter_masks_src_mask_ipv6_value =
-       TOKEN_NUM_INITIALIZER(struct cmd_pkt_filter_masks_result,
-                             ipv6_src_mask, UINT16);
-cmdline_parse_token_num_t cmd_pkt_filter_masks_dst_mask_ipv6_value =
-       TOKEN_NUM_INITIALIZER(struct cmd_pkt_filter_masks_result,
-                             ipv6_dst_mask, UINT16);
-
-cmdline_parse_token_string_t cmd_pkt_filter_masks_comp_ipv6_dst =
-       TOKEN_STRING_INITIALIZER(struct cmd_pkt_filter_masks_result,
-                                comp_ipv6_dst, "compare_dst");
-cmdline_parse_token_num_t cmd_pkt_filter_masks_comp_ipv6_dst_value =
-       TOKEN_NUM_INITIALIZER(struct cmd_pkt_filter_masks_result,
-                             comp_ipv6_dst_value, UINT8);
-
-cmdline_parse_inst_t cmd_set_ipv6_masks_filter = {
-       .f = cmd_pkt_filter_masks_ipv6_parsed,
-       .data = NULL,
-       .help_str = "setup ipv6 masks filter",
-       .tokens = {
-               (void *)&cmd_pkt_filter_masks_filter_mask_ipv6,
-               (void *)&cmd_pkt_filter_masks_port_id,
-               (void *)&cmd_pkt_filter_masks_only_ip_flow,
-               (void *)&cmd_pkt_filter_masks_only_ip_flow_value,
-               (void *)&cmd_pkt_filter_masks_src_mask,
-               (void *)&cmd_pkt_filter_masks_src_mask_ipv6_value,
-               (void *)&cmd_pkt_filter_masks_port_src_mask,
-               (void *)&cmd_pkt_filter_masks_dst_mask,
-               (void *)&cmd_pkt_filter_masks_dst_mask_ipv6_value,
-               (void *)&cmd_pkt_filter_masks_port_dst_mask,
-               (void *)&cmd_pkt_filter_masks_flexbytes,
-               (void *)&cmd_pkt_filter_masks_flexbytes_value,
-               (void *)&cmd_pkt_filter_masks_vlan_id,
-               (void *)&cmd_pkt_filter_masks_vlan_id_value,
-               (void *)&cmd_pkt_filter_masks_vlan_prio,
-               (void *)&cmd_pkt_filter_masks_vlan_prio_value,
-               (void *)&cmd_pkt_filter_masks_comp_ipv6_dst,
-               (void *)&cmd_pkt_filter_masks_comp_ipv6_dst_value,
-               NULL,
-       },
-};
-
 /* *** SETUP ETHERNET LINK FLOW CONTROL *** */
 struct cmd_link_flow_ctrl_set_result {
        cmdline_fixed_string_t set;
@@ -4817,7 +4953,8 @@ cmd_link_flow_ctrl_set_parsed(void *parsed_result,
        struct cmd_link_flow_ctrl_set_result *res = parsed_result;
        cmdline_parse_inst_t *cmd = data;
        struct rte_eth_fc_conf fc_conf;
-       int rx_fc_en, tx_fc_en;
+       int rx_fc_en = 0;
+       int tx_fc_en = 0;
        int ret;
 
        /*
@@ -5170,6 +5307,8 @@ static void cmd_showcfg_parsed(void *parsed_result,
                fwd_lcores_config_display();
        else if (!strcmp(res->what, "fwd"))
                fwd_config_display();
+       else if (!strcmp(res->what, "txpkts"))
+               show_tx_pkt_segments();
 }
 
 cmdline_parse_token_string_t cmd_showcfg_show =
@@ -5178,12 +5317,12 @@ cmdline_parse_token_string_t cmd_showcfg_port =
        TOKEN_STRING_INITIALIZER(struct cmd_showcfg_result, cfg, "config");
 cmdline_parse_token_string_t cmd_showcfg_what =
        TOKEN_STRING_INITIALIZER(struct cmd_showcfg_result, what,
-                                "rxtx#cores#fwd");
+                                "rxtx#cores#fwd#txpkts");
 
 cmdline_parse_inst_t cmd_showcfg = {
        .f = cmd_showcfg_parsed,
        .data = NULL,
-       .help_str = "show config rxtx|cores|fwd",
+       .help_str = "show config rxtx|cores|fwd|txpkts",
        .tokens = {
                (void *)&cmd_showcfg_show,
                (void *)&cmd_showcfg_port,
@@ -5209,26 +5348,29 @@ static void cmd_showportall_parsed(void *parsed_result,
        struct cmd_showportall_result *res = parsed_result;
        if (!strcmp(res->show, "clear")) {
                if (!strcmp(res->what, "stats"))
-                       for (i = 0; i < nb_ports; i++)
+                       FOREACH_PORT(i, ports)
                                nic_stats_clear(i);
                else if (!strcmp(res->what, "xstats"))
-                       for (i = 0; i < nb_ports; i++)
+                       FOREACH_PORT(i, ports)
                                nic_xstats_clear(i);
        } else if (!strcmp(res->what, "info"))
-               for (i = 0; i < nb_ports; i++)
+               FOREACH_PORT(i, ports)
                        port_infos_display(i);
        else if (!strcmp(res->what, "stats"))
-               for (i = 0; i < nb_ports; i++)
+               FOREACH_PORT(i, ports)
                        nic_stats_display(i);
        else if (!strcmp(res->what, "xstats"))
-               for (i = 0; i < nb_ports; i++)
+               FOREACH_PORT(i, ports)
                        nic_xstats_display(i);
        else if (!strcmp(res->what, "fdir"))
-               for (i = 0; i < nb_ports; i++)
+               FOREACH_PORT(i, ports)
                        fdir_get_infos(i);
        else if (!strcmp(res->what, "stat_qmap"))
-               for (i = 0; i < nb_ports; i++)
+               FOREACH_PORT(i, ports)
                        nic_stats_mapping_display(i);
+       else if (!strcmp(res->what, "dcb_tc"))
+               FOREACH_PORT(i, ports)
+                       port_dcb_info_display(i);
 }
 
 cmdline_parse_token_string_t cmd_showportall_show =
@@ -5238,13 +5380,13 @@ cmdline_parse_token_string_t cmd_showportall_port =
        TOKEN_STRING_INITIALIZER(struct cmd_showportall_result, port, "port");
 cmdline_parse_token_string_t cmd_showportall_what =
        TOKEN_STRING_INITIALIZER(struct cmd_showportall_result, what,
-                                "info#stats#xstats#fdir#stat_qmap");
+                                "info#stats#xstats#fdir#stat_qmap#dcb_tc");
 cmdline_parse_token_string_t cmd_showportall_all =
        TOKEN_STRING_INITIALIZER(struct cmd_showportall_result, all, "all");
 cmdline_parse_inst_t cmd_showportall = {
        .f = cmd_showportall_parsed,
        .data = NULL,
-       .help_str = "show|clear port info|stats|xstats|fdir|stat_qmap all",
+       .help_str = "show|clear port info|stats|xstats|fdir|stat_qmap|dcb_tc all",
        .tokens = {
                (void *)&cmd_showportall_show,
                (void *)&cmd_showportall_port,
@@ -5282,6 +5424,8 @@ static void cmd_showport_parsed(void *parsed_result,
                 fdir_get_infos(res->portnum);
        else if (!strcmp(res->what, "stat_qmap"))
                nic_stats_mapping_display(res->portnum);
+       else if (!strcmp(res->what, "dcb_tc"))
+               port_dcb_info_display(res->portnum);
 }
 
 cmdline_parse_token_string_t cmd_showport_show =
@@ -5291,14 +5435,14 @@ cmdline_parse_token_string_t cmd_showport_port =
        TOKEN_STRING_INITIALIZER(struct cmd_showport_result, port, "port");
 cmdline_parse_token_string_t cmd_showport_what =
        TOKEN_STRING_INITIALIZER(struct cmd_showport_result, what,
-                                "info#stats#xstats#fdir#stat_qmap");
+                                "info#stats#xstats#fdir#stat_qmap#dcb_tc");
 cmdline_parse_token_num_t cmd_showport_portnum =
-       TOKEN_NUM_INITIALIZER(struct cmd_showport_result, portnum, INT32);
+       TOKEN_NUM_INITIALIZER(struct cmd_showport_result, portnum, UINT8);
 
 cmdline_parse_inst_t cmd_showport = {
        .f = cmd_showport_parsed,
        .data = NULL,
-       .help_str = "show|clear port info|stats|xstats|fdir|stat_qmap X (X = port number)",
+       .help_str = "show|clear port info|stats|xstats|fdir|stat_qmap|dcb_tc X (X = port number)",
        .tokens = {
                (void *)&cmd_showport_show,
                (void *)&cmd_showport_port,
@@ -5308,6 +5452,53 @@ cmdline_parse_inst_t cmd_showport = {
        },
 };
 
+/* *** SHOW QUEUE INFO *** */
+struct cmd_showqueue_result {
+       cmdline_fixed_string_t show;
+       cmdline_fixed_string_t type;
+       cmdline_fixed_string_t what;
+       uint8_t portnum;
+       uint16_t queuenum;
+};
+
+static void
+cmd_showqueue_parsed(void *parsed_result,
+       __attribute__((unused)) struct cmdline *cl,
+       __attribute__((unused)) void *data)
+{
+       struct cmd_showqueue_result *res = parsed_result;
+
+       if (!strcmp(res->type, "rxq"))
+               rx_queue_infos_display(res->portnum, res->queuenum);
+       else if (!strcmp(res->type, "txq"))
+               tx_queue_infos_display(res->portnum, res->queuenum);
+}
+
+cmdline_parse_token_string_t cmd_showqueue_show =
+       TOKEN_STRING_INITIALIZER(struct cmd_showqueue_result, show, "show");
+cmdline_parse_token_string_t cmd_showqueue_type =
+       TOKEN_STRING_INITIALIZER(struct cmd_showqueue_result, type, "rxq#txq");
+cmdline_parse_token_string_t cmd_showqueue_what =
+       TOKEN_STRING_INITIALIZER(struct cmd_showqueue_result, what, "info");
+cmdline_parse_token_num_t cmd_showqueue_portnum =
+       TOKEN_NUM_INITIALIZER(struct cmd_showqueue_result, portnum, UINT8);
+cmdline_parse_token_num_t cmd_showqueue_queuenum =
+       TOKEN_NUM_INITIALIZER(struct cmd_showqueue_result, queuenum, UINT16);
+
+cmdline_parse_inst_t cmd_showqueue = {
+       .f = cmd_showqueue_parsed,
+       .data = NULL,
+       .help_str = "show rxq|txq info <port number> <queue_number>",
+       .tokens = {
+               (void *)&cmd_showqueue_show,
+               (void *)&cmd_showqueue_type,
+               (void *)&cmd_showqueue_what,
+               (void *)&cmd_showqueue_portnum,
+               (void *)&cmd_showqueue_queuenum,
+               NULL,
+       },
+};
+
 /* *** READ PORT REGISTER *** */
 struct cmd_read_reg_result {
        cmdline_fixed_string_t read;
@@ -6483,8 +6674,10 @@ cmd_tunnel_filter_parsed(void *parsed_result,
 
        if (!strcmp(res->tunnel_type, "vxlan"))
                tunnel_filter_conf.tunnel_type = RTE_TUNNEL_TYPE_VXLAN;
+       else if (!strcmp(res->tunnel_type, "nvgre"))
+               tunnel_filter_conf.tunnel_type = RTE_TUNNEL_TYPE_NVGRE;
        else {
-               printf("Only VXLAN is supported now.\n");
+               printf("The tunnel type %s not supported.\n", res->tunnel_type);
                return;
        }
 
@@ -6528,7 +6721,7 @@ cmdline_parse_token_ipaddr_t cmd_tunnel_filter_ip_value =
        ip_value);
 cmdline_parse_token_string_t cmd_tunnel_filter_tunnel_type =
        TOKEN_STRING_INITIALIZER(struct cmd_tunnel_filter_result,
-       tunnel_type, "vxlan");
+       tunnel_type, "vxlan#nvgre");
 
 cmdline_parse_token_string_t cmd_tunnel_filter_filter_type =
        TOKEN_STRING_INITIALIZER(struct cmd_tunnel_filter_result,
@@ -6546,7 +6739,7 @@ cmdline_parse_inst_t cmd_tunnel_filter = {
        .data = (void *)0,
        .help_str = "add/rm tunnel filter of a port: "
                        "tunnel_filter add port_id outer_mac inner_mac ip "
-                       "inner_vlan tunnel_type(vxlan) filter_type "
+                       "inner_vlan tunnel_type(vxlan|nvgre) filter_type "
                        "(imac-ivlan|imac-ivlan-tenid|imac-tenid|"
                        "imac|omac-imac-tenid) "
                        "tenant_id queue_num",
@@ -6624,6 +6817,57 @@ cmdline_parse_inst_t cmd_tunnel_udp_config = {
        },
 };
 
+/* *** GLOBAL CONFIG *** */
+struct cmd_global_config_result {
+       cmdline_fixed_string_t cmd;
+       uint8_t port_id;
+       cmdline_fixed_string_t cfg_type;
+       uint8_t len;
+};
+
+static void
+cmd_global_config_parsed(void *parsed_result,
+                        __attribute__((unused)) struct cmdline *cl,
+                        __attribute__((unused)) void *data)
+{
+       struct cmd_global_config_result *res = parsed_result;
+       struct rte_eth_global_cfg conf;
+       int ret;
+
+       memset(&conf, 0, sizeof(conf));
+       conf.cfg_type = RTE_ETH_GLOBAL_CFG_TYPE_GRE_KEY_LEN;
+       conf.cfg.gre_key_len = res->len;
+       ret = rte_eth_dev_filter_ctrl(res->port_id, RTE_ETH_FILTER_NONE,
+                                     RTE_ETH_FILTER_SET, &conf);
+       if (ret != 0)
+               printf("Global config error\n");
+}
+
+cmdline_parse_token_string_t cmd_global_config_cmd =
+       TOKEN_STRING_INITIALIZER(struct cmd_global_config_result, cmd,
+               "global_config");
+cmdline_parse_token_num_t cmd_global_config_port_id =
+       TOKEN_NUM_INITIALIZER(struct cmd_global_config_result, port_id, UINT8);
+cmdline_parse_token_string_t cmd_global_config_type =
+       TOKEN_STRING_INITIALIZER(struct cmd_global_config_result,
+               cfg_type, "gre-key-len");
+cmdline_parse_token_num_t cmd_global_config_gre_key_len =
+       TOKEN_NUM_INITIALIZER(struct cmd_global_config_result,
+               len, UINT8);
+
+cmdline_parse_inst_t cmd_global_config = {
+       .f = cmd_global_config_parsed,
+       .data = (void *)NULL,
+       .help_str = "global_config <port_id> gre-key-len <number>",
+       .tokens = {
+               (void *)&cmd_global_config_cmd,
+               (void *)&cmd_global_config_port_id,
+               (void *)&cmd_global_config_type,
+               (void *)&cmd_global_config_gre_key_len,
+               NULL,
+       },
+};
+
 /* *** CONFIGURE VM MIRROR VLAN/POOL RULE *** */
 struct cmd_set_mirror_mask_result {
        cmdline_fixed_string_t set;
@@ -6655,7 +6899,8 @@ cmdline_parse_token_num_t cmd_mirror_mask_ruleid =
                                rule_id, UINT8);
 cmdline_parse_token_string_t cmd_mirror_mask_what =
        TOKEN_STRING_INITIALIZER(struct cmd_set_mirror_mask_result,
-                               what, "pool-mirror#vlan-mirror");
+                               what, "pool-mirror-up#pool-mirror-down"
+                                     "#vlan-mirror");
 cmdline_parse_token_string_t cmd_mirror_mask_value =
        TOKEN_STRING_INITIALIZER(struct cmd_set_mirror_mask_result,
                                value, NULL);
@@ -6676,25 +6921,28 @@ cmd_set_mirror_mask_parsed(void *parsed_result,
 {
        int ret,nb_item,i;
        struct cmd_set_mirror_mask_result *res = parsed_result;
-       struct rte_eth_vmdq_mirror_conf mr_conf;
+       struct rte_eth_mirror_conf mr_conf;
 
-       memset(&mr_conf,0,sizeof(struct rte_eth_vmdq_mirror_conf));
+       memset(&mr_conf, 0, sizeof(struct rte_eth_mirror_conf));
 
-       unsigned int vlan_list[ETH_VMDQ_MAX_VLAN_FILTERS];
+       unsigned int vlan_list[ETH_MIRROR_MAX_VLANS];
 
        mr_conf.dst_pool = res->dstpool_id;
 
-       if (!strcmp(res->what, "pool-mirror")) {
-               mr_conf.pool_mask = strtoull(res->value,NULL,16);
-               mr_conf.rule_type_mask = ETH_VMDQ_POOL_MIRROR;
-       } else if(!strcmp(res->what, "vlan-mirror")) {
-               mr_conf.rule_type_mask = ETH_VMDQ_VLAN_MIRROR;
-               nb_item = parse_item_list(res->value, "core",
-                                       ETH_VMDQ_MAX_VLAN_FILTERS,vlan_list,1);
+       if (!strcmp(res->what, "pool-mirror-up")) {
+               mr_conf.pool_mask = strtoull(res->value, NULL, 16);
+               mr_conf.rule_type = ETH_MIRROR_VIRTUAL_POOL_UP;
+       } else if (!strcmp(res->what, "pool-mirror-down")) {
+               mr_conf.pool_mask = strtoull(res->value, NULL, 16);
+               mr_conf.rule_type = ETH_MIRROR_VIRTUAL_POOL_DOWN;
+       } else if (!strcmp(res->what, "vlan-mirror")) {
+               mr_conf.rule_type = ETH_MIRROR_VLAN;
+               nb_item = parse_item_list(res->value, "vlan",
+                               ETH_MIRROR_MAX_VLANS, vlan_list, 1);
                if (nb_item <= 0)
                        return;
 
-               for(i=0; i < nb_item; i++) {
+               for (i = 0; i < nb_item; i++) {
                        if (vlan_list[i] > ETHER_MAX_VLAN_ID) {
                                printf("Invalid vlan_id: must be < 4096\n");
                                return;
@@ -6705,21 +6953,21 @@ cmd_set_mirror_mask_parsed(void *parsed_result,
                }
        }
 
-       if(!strcmp(res->on, "on"))
-               ret = rte_eth_mirror_rule_set(res->port_id,&mr_conf,
+       if (!strcmp(res->on, "on"))
+               ret = rte_eth_mirror_rule_set(res->port_id, &mr_conf,
                                                res->rule_id, 1);
        else
-               ret = rte_eth_mirror_rule_set(res->port_id,&mr_conf,
+               ret = rte_eth_mirror_rule_set(res->port_id, &mr_conf,
                                                res->rule_id, 0);
-       if(ret < 0)
+       if (ret < 0)
                printf("mirror rule add error: (%s)\n", strerror(-ret));
 }
 
 cmdline_parse_inst_t cmd_set_mirror_mask = {
                .f = cmd_set_mirror_mask_parsed,
                .data = NULL,
-               .help_str = "set port X mirror-rule Y pool-mirror|vlan-mirror "
-                               "pool_mask|vlan_id[,vlan_id]* dst-pool Z on|off",
+               .help_str = "set port X mirror-rule Y pool-mirror-up|pool-mirror-down|vlan-mirror"
+                           pool_mask|vlan_id[,vlan_id]* dst-pool Z on|off",
                .tokens = {
                        (void *)&cmd_mirror_mask_set,
                        (void *)&cmd_mirror_mask_port,
@@ -6783,25 +7031,25 @@ cmd_set_mirror_link_parsed(void *parsed_result,
 {
        int ret;
        struct cmd_set_mirror_link_result *res = parsed_result;
-       struct rte_eth_vmdq_mirror_conf mr_conf;
+       struct rte_eth_mirror_conf mr_conf;
 
-       memset(&mr_conf,0,sizeof(struct rte_eth_vmdq_mirror_conf));
-       if(!strcmp(res->what, "uplink-mirror")) {
-               mr_conf.rule_type_mask = ETH_VMDQ_UPLINK_MIRROR;
-       }else if(!strcmp(res->what, "downlink-mirror"))
-               mr_conf.rule_type_mask = ETH_VMDQ_DOWNLIN_MIRROR;
+       memset(&mr_conf, 0, sizeof(struct rte_eth_mirror_conf));
+       if (!strcmp(res->what, "uplink-mirror"))
+               mr_conf.rule_type = ETH_MIRROR_UPLINK_PORT;
+       else
+               mr_conf.rule_type = ETH_MIRROR_DOWNLINK_PORT;
 
        mr_conf.dst_pool = res->dstpool_id;
 
-       if(!strcmp(res->on, "on"))
-               ret = rte_eth_mirror_rule_set(res->port_id,&mr_conf,
+       if (!strcmp(res->on, "on"))
+               ret = rte_eth_mirror_rule_set(res->port_id, &mr_conf,
                                                res->rule_id, 1);
        else
-               ret = rte_eth_mirror_rule_set(res->port_id,&mr_conf,
+               ret = rte_eth_mirror_rule_set(res->port_id, &mr_conf,
                                                res->rule_id, 0);
 
        /* check the return value and print it if is < 0 */
-       if(ret < 0)
+       if (ret < 0)
                printf("mirror rule add error: (%s)\n", strerror(-ret));
 
 }
@@ -6984,248 +7232,113 @@ cmdline_parse_inst_t cmd_dump_one = {
        },
 };
 
-/* *** ADD/REMOVE an ethertype FILTER *** */
-struct cmd_ethertype_filter_result {
+/* *** Add/Del syn filter *** */
+struct cmd_syn_filter_result {
        cmdline_fixed_string_t filter;
        uint8_t port_id;
-       cmdline_fixed_string_t ethertype;
-       uint16_t ethertype_value;
+       cmdline_fixed_string_t ops;
        cmdline_fixed_string_t priority;
-       cmdline_fixed_string_t priority_en;
-       uint8_t priority_value;
+       cmdline_fixed_string_t high;
        cmdline_fixed_string_t queue;
        uint16_t queue_id;
-       cmdline_fixed_string_t index;
-       uint16_t index_value;
 };
 
 static void
-cmd_ethertype_filter_parsed(void *parsed_result,
+cmd_syn_filter_parsed(void *parsed_result,
                        __attribute__((unused)) struct cmdline *cl,
                        __attribute__((unused)) void *data)
 {
+       struct cmd_syn_filter_result *res = parsed_result;
+       struct rte_eth_syn_filter syn_filter;
        int ret = 0;
-       struct cmd_ethertype_filter_result *res = parsed_result;
-       struct rte_ethertype_filter filter;
 
-       memset(&filter, 0, sizeof(struct rte_ethertype_filter));
-       filter.ethertype = rte_cpu_to_le_16(res->ethertype_value);
-       filter.priority = res->priority_value;
+       ret = rte_eth_dev_filter_supported(res->port_id,
+                                       RTE_ETH_FILTER_SYN);
+       if (ret < 0) {
+               printf("syn filter is not supported on port %u.\n",
+                               res->port_id);
+               return;
+       }
+
+       memset(&syn_filter, 0, sizeof(syn_filter));
+
+       if (!strcmp(res->ops, "add")) {
+               if (!strcmp(res->high, "high"))
+                       syn_filter.hig_pri = 1;
+               else
+                       syn_filter.hig_pri = 0;
 
-       if (!strcmp(res->priority_en, "enable"))
-               filter.priority_en = 1;
-       if (!strcmp(res->filter, "add_ethertype_filter"))
-               ret = rte_eth_dev_add_ethertype_filter(res->port_id,
-                               res->index_value,
-                               &filter, res->queue_id);
-       else if (!strcmp(res->filter, "remove_ethertype_filter"))
-               ret = rte_eth_dev_remove_ethertype_filter(res->port_id,
-                               res->index_value);
-       else if (!strcmp(res->filter, "get_ethertype_filter"))
-               get_ethertype_filter(res->port_id, res->index_value);
+               syn_filter.queue = res->queue_id;
+               ret = rte_eth_dev_filter_ctrl(res->port_id,
+                                               RTE_ETH_FILTER_SYN,
+                                               RTE_ETH_FILTER_ADD,
+                                               &syn_filter);
+       } else
+               ret = rte_eth_dev_filter_ctrl(res->port_id,
+                                               RTE_ETH_FILTER_SYN,
+                                               RTE_ETH_FILTER_DELETE,
+                                               &syn_filter);
 
        if (ret < 0)
-               printf("ethertype filter setting error: (%s)\n",
-                       strerror(-ret));
+               printf("syn filter programming error: (%s)\n",
+                               strerror(-ret));
 }
 
-cmdline_parse_token_num_t cmd_ethertype_filter_port_id =
-       TOKEN_NUM_INITIALIZER(struct cmd_ethertype_filter_result,
-                               port_id, UINT8);
-cmdline_parse_token_string_t cmd_ethertype_filter_ethertype =
-       TOKEN_STRING_INITIALIZER(struct cmd_ethertype_filter_result,
-                               ethertype, "ethertype");
-cmdline_parse_token_ipaddr_t cmd_ethertype_filter_ethertype_value =
-       TOKEN_NUM_INITIALIZER(struct cmd_ethertype_filter_result,
-                               ethertype_value, UINT16);
-cmdline_parse_token_string_t cmd_ethertype_filter_priority =
-       TOKEN_STRING_INITIALIZER(struct cmd_ethertype_filter_result,
+cmdline_parse_token_string_t cmd_syn_filter_filter =
+       TOKEN_STRING_INITIALIZER(struct cmd_syn_filter_result,
+       filter, "syn_filter");
+cmdline_parse_token_num_t cmd_syn_filter_port_id =
+       TOKEN_NUM_INITIALIZER(struct cmd_syn_filter_result,
+       port_id, UINT8);
+cmdline_parse_token_string_t cmd_syn_filter_ops =
+       TOKEN_STRING_INITIALIZER(struct cmd_syn_filter_result,
+       ops, "add#del");
+cmdline_parse_token_string_t cmd_syn_filter_priority =
+       TOKEN_STRING_INITIALIZER(struct cmd_syn_filter_result,
                                priority, "priority");
-cmdline_parse_token_string_t cmd_ethertype_filter_priority_en =
-       TOKEN_STRING_INITIALIZER(struct cmd_ethertype_filter_result,
-                               priority_en, "enable#disable");
-cmdline_parse_token_num_t cmd_ethertype_filter_priority_value =
-       TOKEN_NUM_INITIALIZER(struct cmd_ethertype_filter_result,
-                               priority_value, UINT8);
-cmdline_parse_token_string_t cmd_ethertype_filter_queue =
-       TOKEN_STRING_INITIALIZER(struct cmd_ethertype_filter_result,
+cmdline_parse_token_string_t cmd_syn_filter_high =
+       TOKEN_STRING_INITIALIZER(struct cmd_syn_filter_result,
+                               high, "high#low");
+cmdline_parse_token_string_t cmd_syn_filter_queue =
+       TOKEN_STRING_INITIALIZER(struct cmd_syn_filter_result,
                                queue, "queue");
-cmdline_parse_token_num_t cmd_ethertype_filter_queue_id =
-       TOKEN_NUM_INITIALIZER(struct cmd_ethertype_filter_result,
+cmdline_parse_token_num_t cmd_syn_filter_queue_id =
+       TOKEN_NUM_INITIALIZER(struct cmd_syn_filter_result,
                                queue_id, UINT16);
-cmdline_parse_token_string_t cmd_ethertype_filter_index =
-       TOKEN_STRING_INITIALIZER(struct cmd_ethertype_filter_result,
-                               index, "index");
-cmdline_parse_token_num_t cmd_ethertype_filter_index_value =
-       TOKEN_NUM_INITIALIZER(struct cmd_ethertype_filter_result,
-                               index_value, UINT16);
-cmdline_parse_token_string_t cmd_ethertype_filter_add_filter =
-       TOKEN_STRING_INITIALIZER(struct cmd_ethertype_filter_result,
-                               filter, "add_ethertype_filter");
-cmdline_parse_inst_t cmd_add_ethertype_filter = {
-       .f = cmd_ethertype_filter_parsed,
-       .data = NULL,
-       .help_str = "add an ethertype filter",
-       .tokens = {
-               (void *)&cmd_ethertype_filter_add_filter,
-               (void *)&cmd_ethertype_filter_port_id,
-               (void *)&cmd_ethertype_filter_ethertype,
-               (void *)&cmd_ethertype_filter_ethertype_value,
-               (void *)&cmd_ethertype_filter_priority,
-               (void *)&cmd_ethertype_filter_priority_en,
-               (void *)&cmd_ethertype_filter_priority_value,
-               (void *)&cmd_ethertype_filter_queue,
-               (void *)&cmd_ethertype_filter_queue_id,
-               (void *)&cmd_ethertype_filter_index,
-               (void *)&cmd_ethertype_filter_index_value,
-               NULL,
-       },
-};
 
-cmdline_parse_token_string_t cmd_ethertype_filter_remove_filter =
-       TOKEN_STRING_INITIALIZER(struct cmd_ethertype_filter_result,
-                                filter, "remove_ethertype_filter");
-cmdline_parse_inst_t cmd_remove_ethertype_filter = {
-       .f = cmd_ethertype_filter_parsed,
-       .data = NULL,
-       .help_str = "remove an ethertype filter",
-       .tokens = {
-               (void *)&cmd_ethertype_filter_remove_filter,
-               (void *)&cmd_ethertype_filter_port_id,
-               (void *)&cmd_ethertype_filter_index,
-               (void *)&cmd_ethertype_filter_index_value,
-               NULL,
-       },
-};
-cmdline_parse_token_string_t cmd_ethertype_filter_get_filter =
-       TOKEN_STRING_INITIALIZER(struct cmd_ethertype_filter_result,
-                                filter, "get_ethertype_filter");
-cmdline_parse_inst_t cmd_get_ethertype_filter = {
-       .f = cmd_ethertype_filter_parsed,
+cmdline_parse_inst_t cmd_syn_filter = {
+       .f = cmd_syn_filter_parsed,
        .data = NULL,
-       .help_str = "get an ethertype filter",
+       .help_str = "add/delete syn filter",
        .tokens = {
-               (void *)&cmd_ethertype_filter_get_filter,
-               (void *)&cmd_ethertype_filter_port_id,
-               (void *)&cmd_ethertype_filter_index,
-               (void *)&cmd_ethertype_filter_index_value,
+               (void *)&cmd_syn_filter_filter,
+               (void *)&cmd_syn_filter_port_id,
+               (void *)&cmd_syn_filter_ops,
+               (void *)&cmd_syn_filter_priority,
+               (void *)&cmd_syn_filter_high,
+               (void *)&cmd_syn_filter_queue,
+               (void *)&cmd_syn_filter_queue_id,
                NULL,
        },
 };
 
-/* *** set SYN filter *** */
-struct cmd_set_syn_filter_result {
-       cmdline_fixed_string_t filter;
-       uint8_t port_id;
-       cmdline_fixed_string_t priority;
-       cmdline_fixed_string_t high;
-       cmdline_fixed_string_t queue;
-       uint16_t  queue_id;
-};
-
-static void
-cmd_set_syn_filter_parsed(void *parsed_result,
-                       __attribute__((unused)) struct cmdline *cl,
-                       __attribute__((unused)) void *data)
-{
-       int ret = 0;
-       struct cmd_set_syn_filter_result *res = parsed_result;
-       struct rte_syn_filter filter;
-
-       if (!strcmp(res->filter, "add_syn_filter")) {
-               if (!strcmp(res->high, "high"))
-                       filter.hig_pri = 1;
-               else
-                       filter.hig_pri = 0;
-               ret = rte_eth_dev_add_syn_filter(res->port_id,
-                               &filter, res->queue_id);
-       } else if (!strcmp(res->filter, "remove_syn_filter"))
-               ret = rte_eth_dev_remove_syn_filter(res->port_id);
-       else if (!strcmp(res->filter, "get_syn_filter"))
-               get_syn_filter(res->port_id);
-       if (ret < 0)
-               printf("syn filter setting error: (%s)\n", strerror(-ret));
-
-}
-cmdline_parse_token_num_t cmd_syn_filter_portid =
-       TOKEN_NUM_INITIALIZER(struct cmd_set_syn_filter_result,
-                               port_id, UINT8);
-cmdline_parse_token_string_t cmd_syn_filter_priority =
-       TOKEN_STRING_INITIALIZER(struct cmd_set_syn_filter_result,
-                               priority, "priority");
-cmdline_parse_token_string_t cmd_syn_filter_high =
-       TOKEN_STRING_INITIALIZER(struct cmd_set_syn_filter_result,
-                               high, "high#low");
-cmdline_parse_token_string_t cmd_syn_filter_queue =
-       TOKEN_STRING_INITIALIZER(struct cmd_set_syn_filter_result,
-                               queue, "queue");
-cmdline_parse_token_num_t cmd_syn_filter_queue_id =
-       TOKEN_NUM_INITIALIZER(struct cmd_set_syn_filter_result,
-                               queue_id, UINT16);
-cmdline_parse_token_string_t cmd_syn_filter_add_filter =
-       TOKEN_STRING_INITIALIZER(struct cmd_set_syn_filter_result,
-                               filter, "add_syn_filter");
-cmdline_parse_token_string_t cmd_syn_filter_remove_filter =
-       TOKEN_STRING_INITIALIZER(struct cmd_set_syn_filter_result,
-                               filter, "remove_syn_filter");
-cmdline_parse_inst_t cmd_add_syn_filter = {
-               .f = cmd_set_syn_filter_parsed,
-               .data = NULL,
-               .help_str = "add syn filter",
-               .tokens = {
-                       (void *)&cmd_syn_filter_add_filter,
-                       (void *)&cmd_syn_filter_portid,
-                       (void *)&cmd_syn_filter_priority,
-                       (void *)&cmd_syn_filter_high,
-                       (void *)&cmd_syn_filter_queue,
-                       (void *)&cmd_syn_filter_queue_id,
-                       NULL,
-               },
-};
-cmdline_parse_inst_t cmd_remove_syn_filter = {
-               .f = cmd_set_syn_filter_parsed,
-               .data = NULL,
-               .help_str = "remove syn filter",
-               .tokens = {
-                       (void *)&cmd_syn_filter_remove_filter,
-                       (void *)&cmd_syn_filter_portid,
-                       NULL,
-               },
-};
-
-cmdline_parse_token_string_t cmd_syn_filter_get_filter =
-       TOKEN_STRING_INITIALIZER(struct cmd_set_syn_filter_result,
-                               filter, "get_syn_filter");
-
-cmdline_parse_inst_t cmd_get_syn_filter = {
-               .f = cmd_set_syn_filter_parsed,
-               .data = NULL,
-               .help_str = "get syn filter",
-               .tokens = {
-                       (void *)&cmd_syn_filter_get_filter,
-                       (void *)&cmd_syn_filter_portid,
-                       NULL,
-               },
-};
-
 /* *** ADD/REMOVE A 2tuple FILTER *** */
 struct cmd_2tuple_filter_result {
        cmdline_fixed_string_t filter;
-       uint8_t port_id;
-       cmdline_fixed_string_t protocol;
-       uint8_t protocol_value;
-       uint8_t protocol_mask;
+       uint8_t  port_id;
+       cmdline_fixed_string_t ops;
        cmdline_fixed_string_t dst_port;
        uint16_t dst_port_value;
-       uint16_t dst_port_mask;
-       cmdline_fixed_string_t flags;
-       uint8_t flags_value;
+       cmdline_fixed_string_t protocol;
+       uint8_t protocol_value;
+       cmdline_fixed_string_t mask;
+       uint8_t  mask_value;
+       cmdline_fixed_string_t tcp_flags;
+       uint8_t tcp_flags_value;
        cmdline_fixed_string_t priority;
-       uint8_t priority_value;
+       uint8_t  priority_value;
        cmdline_fixed_string_t queue;
-       uint16_t queue_id;
-       cmdline_fixed_string_t index;
-       uint16_t index_value;
+       uint16_t  queue_id;
 };
 
 static void
@@ -7233,59 +7346,92 @@ cmd_2tuple_filter_parsed(void *parsed_result,
                        __attribute__((unused)) struct cmdline *cl,
                        __attribute__((unused)) void *data)
 {
-       int ret = 0;
-       struct rte_2tuple_filter filter;
+       struct rte_eth_ntuple_filter filter;
        struct cmd_2tuple_filter_result *res = parsed_result;
+       int ret = 0;
+
+       ret = rte_eth_dev_filter_supported(res->port_id, RTE_ETH_FILTER_NTUPLE);
+       if (ret < 0) {
+               printf("ntuple filter is not supported on port %u.\n",
+                       res->port_id);
+               return;
+       }
 
-       memset(&filter, 0, sizeof(struct rte_2tuple_filter));
+       memset(&filter, 0, sizeof(struct rte_eth_ntuple_filter));
 
-       if (!strcmp(res->filter, "add_2tuple_filter")) {
-               /* need convert to big endian. */
-               filter.dst_port = rte_cpu_to_be_16(res->dst_port_value);
-               filter.protocol = res->protocol_value;
-               filter.dst_port_mask = (res->dst_port_mask) ? 0 : 1;
-               filter.protocol_mask = (res->protocol_mask) ? 0 : 1;
-               filter.priority = res->priority_value;
-               filter.tcp_flags = res->flags_value;
-               ret = rte_eth_dev_add_2tuple_filter(res->port_id,
-                       res->index_value, &filter, res->queue_id);
-       } else if (!strcmp(res->filter, "remove_2tuple_filter"))
-               ret = rte_eth_dev_remove_2tuple_filter(res->port_id,
-                       res->index_value);
-       else if (!strcmp(res->filter, "get_2tuple_filter"))
-               get_2tuple_filter(res->port_id, res->index_value);
+       filter.flags = RTE_2TUPLE_FLAGS;
+       filter.dst_port_mask = (res->mask_value & 0x02) ? UINT16_MAX : 0;
+       filter.proto_mask = (res->mask_value & 0x01) ? UINT8_MAX : 0;
+       filter.proto = res->protocol_value;
+       filter.priority = res->priority_value;
+       if (res->tcp_flags_value != 0 && filter.proto != IPPROTO_TCP) {
+               printf("nonzero tcp_flags is only meaningful"
+                       " when protocol is TCP.\n");
+               return;
+       }
+       if (res->tcp_flags_value > TCP_FLAG_ALL) {
+               printf("invalid TCP flags.\n");
+               return;
+       }
 
+       if (res->tcp_flags_value != 0) {
+               filter.flags |= RTE_NTUPLE_FLAGS_TCP_FLAG;
+               filter.tcp_flags = res->tcp_flags_value;
+       }
+
+       /* need convert to big endian. */
+       filter.dst_port = rte_cpu_to_be_16(res->dst_port_value);
+       filter.queue = res->queue_id;
+
+       if (!strcmp(res->ops, "add"))
+               ret = rte_eth_dev_filter_ctrl(res->port_id,
+                               RTE_ETH_FILTER_NTUPLE,
+                               RTE_ETH_FILTER_ADD,
+                               &filter);
+       else
+               ret = rte_eth_dev_filter_ctrl(res->port_id,
+                               RTE_ETH_FILTER_NTUPLE,
+                               RTE_ETH_FILTER_DELETE,
+                               &filter);
        if (ret < 0)
-               printf("2tuple filter setting error: (%s)\n", strerror(-ret));
+               printf("2tuple filter programming error: (%s)\n",
+                       strerror(-ret));
+
 }
 
+cmdline_parse_token_string_t cmd_2tuple_filter_filter =
+       TOKEN_STRING_INITIALIZER(struct cmd_2tuple_filter_result,
+                                filter, "2tuple_filter");
 cmdline_parse_token_num_t cmd_2tuple_filter_port_id =
        TOKEN_NUM_INITIALIZER(struct cmd_2tuple_filter_result,
                                port_id, UINT8);
-cmdline_parse_token_string_t cmd_2tuple_filter_protocol =
+cmdline_parse_token_string_t cmd_2tuple_filter_ops =
        TOKEN_STRING_INITIALIZER(struct cmd_2tuple_filter_result,
-                                protocol, "protocol");
-cmdline_parse_token_num_t cmd_2tuple_filter_protocol_value =
-       TOKEN_NUM_INITIALIZER(struct cmd_2tuple_filter_result,
-                                protocol_value, UINT8);
-cmdline_parse_token_num_t cmd_2tuple_filter_protocol_mask =
-       TOKEN_NUM_INITIALIZER(struct cmd_2tuple_filter_result,
-                               protocol_mask, UINT8);
+                                ops, "add#del");
 cmdline_parse_token_string_t cmd_2tuple_filter_dst_port =
        TOKEN_STRING_INITIALIZER(struct cmd_2tuple_filter_result,
                                dst_port, "dst_port");
 cmdline_parse_token_num_t cmd_2tuple_filter_dst_port_value =
        TOKEN_NUM_INITIALIZER(struct cmd_2tuple_filter_result,
                                dst_port_value, UINT16);
-cmdline_parse_token_num_t cmd_2tuple_filter_dst_port_mask =
+cmdline_parse_token_string_t cmd_2tuple_filter_protocol =
+       TOKEN_STRING_INITIALIZER(struct cmd_2tuple_filter_result,
+                               protocol, "protocol");
+cmdline_parse_token_num_t cmd_2tuple_filter_protocol_value =
+       TOKEN_NUM_INITIALIZER(struct cmd_2tuple_filter_result,
+                               protocol_value, UINT8);
+cmdline_parse_token_string_t cmd_2tuple_filter_mask =
+       TOKEN_STRING_INITIALIZER(struct cmd_2tuple_filter_result,
+                               mask, "mask");
+cmdline_parse_token_num_t cmd_2tuple_filter_mask_value =
        TOKEN_NUM_INITIALIZER(struct cmd_2tuple_filter_result,
-                               dst_port_mask, UINT16);
-cmdline_parse_token_string_t cmd_2tuple_filter_flags =
+                               mask_value, INT8);
+cmdline_parse_token_string_t cmd_2tuple_filter_tcp_flags =
        TOKEN_STRING_INITIALIZER(struct cmd_2tuple_filter_result,
-                               flags, "flags");
-cmdline_parse_token_num_t cmd_2tuple_filter_flags_value =
+                               tcp_flags, "tcp_flags");
+cmdline_parse_token_num_t cmd_2tuple_filter_tcp_flags_value =
        TOKEN_NUM_INITIALIZER(struct cmd_2tuple_filter_result,
-                               flags_value, UINT8);
+                               tcp_flags_value, UINT8);
 cmdline_parse_token_string_t cmd_2tuple_filter_priority =
        TOKEN_STRING_INITIALIZER(struct cmd_2tuple_filter_result,
                                priority, "priority");
@@ -7298,67 +7444,27 @@ cmdline_parse_token_string_t cmd_2tuple_filter_queue =
 cmdline_parse_token_num_t cmd_2tuple_filter_queue_id =
        TOKEN_NUM_INITIALIZER(struct cmd_2tuple_filter_result,
                                queue_id, UINT16);
-cmdline_parse_token_string_t cmd_2tuple_filter_index =
-       TOKEN_STRING_INITIALIZER(struct cmd_2tuple_filter_result,
-                               index, "index");
-cmdline_parse_token_num_t cmd_2tuple_filter_index_value =
-       TOKEN_NUM_INITIALIZER(struct cmd_2tuple_filter_result,
-                               index_value, UINT16);
-cmdline_parse_token_string_t cmd_2tuple_filter_add_filter =
-       TOKEN_STRING_INITIALIZER(struct cmd_2tuple_filter_result,
-                               filter, "add_2tuple_filter");
-cmdline_parse_inst_t cmd_add_2tuple_filter = {
+
+cmdline_parse_inst_t cmd_2tuple_filter = {
        .f = cmd_2tuple_filter_parsed,
        .data = NULL,
        .help_str = "add a 2tuple filter",
        .tokens = {
-               (void *)&cmd_2tuple_filter_add_filter,
+               (void *)&cmd_2tuple_filter_filter,
                (void *)&cmd_2tuple_filter_port_id,
-               (void *)&cmd_2tuple_filter_protocol,
-               (void *)&cmd_2tuple_filter_protocol_value,
-               (void *)&cmd_2tuple_filter_protocol_mask,
+               (void *)&cmd_2tuple_filter_ops,
                (void *)&cmd_2tuple_filter_dst_port,
                (void *)&cmd_2tuple_filter_dst_port_value,
-               (void *)&cmd_2tuple_filter_dst_port_mask,
-               (void *)&cmd_2tuple_filter_flags,
-               (void *)&cmd_2tuple_filter_flags_value,
+               (void *)&cmd_2tuple_filter_protocol,
+               (void *)&cmd_2tuple_filter_protocol_value,
+               (void *)&cmd_2tuple_filter_mask,
+               (void *)&cmd_2tuple_filter_mask_value,
+               (void *)&cmd_2tuple_filter_tcp_flags,
+               (void *)&cmd_2tuple_filter_tcp_flags_value,
                (void *)&cmd_2tuple_filter_priority,
                (void *)&cmd_2tuple_filter_priority_value,
                (void *)&cmd_2tuple_filter_queue,
                (void *)&cmd_2tuple_filter_queue_id,
-               (void *)&cmd_2tuple_filter_index,
-               (void *)&cmd_2tuple_filter_index_value,
-               NULL,
-       },
-};
-
-cmdline_parse_token_string_t cmd_2tuple_filter_remove_filter =
-       TOKEN_STRING_INITIALIZER(struct cmd_2tuple_filter_result,
-                               filter, "remove_2tuple_filter");
-cmdline_parse_inst_t cmd_remove_2tuple_filter = {
-       .f = cmd_2tuple_filter_parsed,
-       .data = NULL,
-       .help_str = "remove a 2tuple filter",
-       .tokens = {
-               (void *)&cmd_2tuple_filter_remove_filter,
-               (void *)&cmd_2tuple_filter_port_id,
-               (void *)&cmd_2tuple_filter_index,
-               (void *)&cmd_2tuple_filter_index_value,
-               NULL,
-       },
-};
-cmdline_parse_token_string_t cmd_2tuple_filter_get_filter =
-       TOKEN_STRING_INITIALIZER(struct cmd_2tuple_filter_result,
-                               filter, "get_2tuple_filter");
-cmdline_parse_inst_t cmd_get_2tuple_filter = {
-       .f = cmd_2tuple_filter_parsed,
-       .data = NULL,
-       .help_str = "get a 2tuple filter",
-       .tokens = {
-               (void *)&cmd_2tuple_filter_get_filter,
-               (void *)&cmd_2tuple_filter_port_id,
-               (void *)&cmd_2tuple_filter_index,
-               (void *)&cmd_2tuple_filter_index_value,
                NULL,
        },
 };
@@ -7367,6 +7473,7 @@ cmdline_parse_inst_t cmd_get_2tuple_filter = {
 struct cmd_5tuple_filter_result {
        cmdline_fixed_string_t filter;
        uint8_t  port_id;
+       cmdline_fixed_string_t ops;
        cmdline_fixed_string_t dst_ip;
        cmdline_ipaddr_t dst_ip_value;
        cmdline_fixed_string_t src_ip;
@@ -7379,14 +7486,12 @@ struct cmd_5tuple_filter_result {
        uint8_t protocol_value;
        cmdline_fixed_string_t mask;
        uint8_t  mask_value;
-       cmdline_fixed_string_t flags;
-       uint8_t flags_value;
+       cmdline_fixed_string_t tcp_flags;
+       uint8_t tcp_flags_value;
        cmdline_fixed_string_t priority;
        uint8_t  priority_value;
        cmdline_fixed_string_t queue;
        uint16_t  queue_id;
-       cmdline_fixed_string_t index;
-       uint16_t  index_value;
 };
 
 static void
@@ -7394,62 +7499,92 @@ cmd_5tuple_filter_parsed(void *parsed_result,
                        __attribute__((unused)) struct cmdline *cl,
                        __attribute__((unused)) void *data)
 {
-       int ret = 0;
-       struct rte_5tuple_filter filter;
+       struct rte_eth_ntuple_filter filter;
        struct cmd_5tuple_filter_result *res = parsed_result;
+       int ret = 0;
 
-       memset(&filter, 0, sizeof(struct rte_5tuple_filter));
-
-       if (!strcmp(res->filter, "add_5tuple_filter")) {
-               filter.dst_ip_mask = (res->mask_value & 0x10) ? 0 : 1;
-               filter.src_ip_mask = (res->mask_value & 0x08) ? 0 : 1;
-               filter.dst_port_mask = (res->mask_value & 0x04) ? 0 : 1;
-               filter.src_port_mask = (res->mask_value & 0x02) ? 0 : 1;
-               filter.protocol = res->protocol_value;
-               filter.protocol_mask = (res->mask_value & 0x01) ? 0 : 1;
-               filter.priority = res->priority_value;
-               filter.tcp_flags = res->flags_value;
-
-               if (res->dst_ip_value.family == AF_INET)
-                       /* no need to convert, already big endian. */
-                       filter.dst_ip = res->dst_ip_value.addr.ipv4.s_addr;
-               else {
-                       if (filter.dst_ip_mask == 0) {
-                               printf("can not support ipv6 involved compare.\n");
-                               return;
-                       }
-                       filter.dst_ip = 0;
+       ret = rte_eth_dev_filter_supported(res->port_id, RTE_ETH_FILTER_NTUPLE);
+       if (ret < 0) {
+               printf("ntuple filter is not supported on port %u.\n",
+                       res->port_id);
+               return;
+       }
+
+       memset(&filter, 0, sizeof(struct rte_eth_ntuple_filter));
+
+       filter.flags = RTE_5TUPLE_FLAGS;
+       filter.dst_ip_mask = (res->mask_value & 0x10) ? UINT32_MAX : 0;
+       filter.src_ip_mask = (res->mask_value & 0x08) ? UINT32_MAX : 0;
+       filter.dst_port_mask = (res->mask_value & 0x04) ? UINT16_MAX : 0;
+       filter.src_port_mask = (res->mask_value & 0x02) ? UINT16_MAX : 0;
+       filter.proto_mask = (res->mask_value & 0x01) ? UINT8_MAX : 0;
+       filter.proto = res->protocol_value;
+       filter.priority = res->priority_value;
+       if (res->tcp_flags_value != 0 && filter.proto != IPPROTO_TCP) {
+               printf("nonzero tcp_flags is only meaningful"
+                       " when protocol is TCP.\n");
+               return;
+       }
+       if (res->tcp_flags_value > TCP_FLAG_ALL) {
+               printf("invalid TCP flags.\n");
+               return;
+       }
+
+       if (res->tcp_flags_value != 0) {
+               filter.flags |= RTE_NTUPLE_FLAGS_TCP_FLAG;
+               filter.tcp_flags = res->tcp_flags_value;
+       }
+
+       if (res->dst_ip_value.family == AF_INET)
+               /* no need to convert, already big endian. */
+               filter.dst_ip = res->dst_ip_value.addr.ipv4.s_addr;
+       else {
+               if (filter.dst_ip_mask == 0) {
+                       printf("can not support ipv6 involved compare.\n");
+                       return;
                }
+               filter.dst_ip = 0;
+       }
 
-               if (res->src_ip_value.family == AF_INET)
-                       /* no need to convert, already big endian. */
-                       filter.src_ip = res->src_ip_value.addr.ipv4.s_addr;
-               else {
-                       if (filter.src_ip_mask == 0) {
-                               printf("can not support ipv6 involved compare.\n");
-                               return;
-                       }
-                       filter.src_ip = 0;
+       if (res->src_ip_value.family == AF_INET)
+               /* no need to convert, already big endian. */
+               filter.src_ip = res->src_ip_value.addr.ipv4.s_addr;
+       else {
+               if (filter.src_ip_mask == 0) {
+                       printf("can not support ipv6 involved compare.\n");
+                       return;
                }
-               /* need convert to big endian. */
-               filter.dst_port = rte_cpu_to_be_16(res->dst_port_value);
-               filter.src_port = rte_cpu_to_be_16(res->src_port_value);
-
-               ret = rte_eth_dev_add_5tuple_filter(res->port_id,
-                       res->index_value, &filter, res->queue_id);
-       } else if (!strcmp(res->filter, "remove_5tuple_filter"))
-               ret = rte_eth_dev_remove_5tuple_filter(res->port_id,
-                       res->index_value);
-       else if (!strcmp(res->filter, "get_5tuple_filter"))
-               get_5tuple_filter(res->port_id, res->index_value);
+               filter.src_ip = 0;
+       }
+       /* need convert to big endian. */
+       filter.dst_port = rte_cpu_to_be_16(res->dst_port_value);
+       filter.src_port = rte_cpu_to_be_16(res->src_port_value);
+       filter.queue = res->queue_id;
+
+       if (!strcmp(res->ops, "add"))
+               ret = rte_eth_dev_filter_ctrl(res->port_id,
+                               RTE_ETH_FILTER_NTUPLE,
+                               RTE_ETH_FILTER_ADD,
+                               &filter);
+       else
+               ret = rte_eth_dev_filter_ctrl(res->port_id,
+                               RTE_ETH_FILTER_NTUPLE,
+                               RTE_ETH_FILTER_DELETE,
+                               &filter);
        if (ret < 0)
-               printf("5tuple filter setting error: (%s)\n", strerror(-ret));
+               printf("5tuple filter programming error: (%s)\n",
+                       strerror(-ret));
 }
 
-
+cmdline_parse_token_string_t cmd_5tuple_filter_filter =
+       TOKEN_STRING_INITIALIZER(struct cmd_5tuple_filter_result,
+                                filter, "5tuple_filter");
 cmdline_parse_token_num_t cmd_5tuple_filter_port_id =
        TOKEN_NUM_INITIALIZER(struct cmd_5tuple_filter_result,
                                port_id, UINT8);
+cmdline_parse_token_string_t cmd_5tuple_filter_ops =
+       TOKEN_STRING_INITIALIZER(struct cmd_5tuple_filter_result,
+                                ops, "add#del");
 cmdline_parse_token_string_t cmd_5tuple_filter_dst_ip =
        TOKEN_STRING_INITIALIZER(struct cmd_5tuple_filter_result,
                                dst_ip, "dst_ip");
@@ -7486,12 +7621,12 @@ cmdline_parse_token_string_t cmd_5tuple_filter_mask =
 cmdline_parse_token_num_t cmd_5tuple_filter_mask_value =
        TOKEN_NUM_INITIALIZER(struct cmd_5tuple_filter_result,
                                mask_value, INT8);
-cmdline_parse_token_string_t cmd_5tuple_filter_flags =
+cmdline_parse_token_string_t cmd_5tuple_filter_tcp_flags =
        TOKEN_STRING_INITIALIZER(struct cmd_5tuple_filter_result,
-                               flags, "flags");
-cmdline_parse_token_num_t cmd_5tuple_filter_flags_value =
+                               tcp_flags, "tcp_flags");
+cmdline_parse_token_num_t cmd_5tuple_filter_tcp_flags_value =
        TOKEN_NUM_INITIALIZER(struct cmd_5tuple_filter_result,
-                               flags_value, UINT8);
+                               tcp_flags_value, UINT8);
 cmdline_parse_token_string_t cmd_5tuple_filter_priority =
        TOKEN_STRING_INITIALIZER(struct cmd_5tuple_filter_result,
                                priority, "priority");
@@ -7504,23 +7639,15 @@ cmdline_parse_token_string_t cmd_5tuple_filter_queue =
 cmdline_parse_token_num_t cmd_5tuple_filter_queue_id =
        TOKEN_NUM_INITIALIZER(struct cmd_5tuple_filter_result,
                                queue_id, UINT16);
-cmdline_parse_token_string_t cmd_5tuple_filter_index =
-       TOKEN_STRING_INITIALIZER(struct cmd_5tuple_filter_result,
-                               index, "index");
-cmdline_parse_token_num_t cmd_5tuple_filter_index_value =
-       TOKEN_NUM_INITIALIZER(struct cmd_5tuple_filter_result,
-                               index_value, UINT16);
 
-cmdline_parse_token_string_t cmd_5tuple_filter_add_filter =
-       TOKEN_STRING_INITIALIZER(struct cmd_5tuple_filter_result,
-                                filter, "add_5tuple_filter");
-cmdline_parse_inst_t cmd_add_5tuple_filter = {
+cmdline_parse_inst_t cmd_5tuple_filter = {
        .f = cmd_5tuple_filter_parsed,
        .data = NULL,
-       .help_str = "add a 5tuple filter",
+       .help_str = "add/del a 5tuple filter",
        .tokens = {
-               (void *)&cmd_5tuple_filter_add_filter,
+               (void *)&cmd_5tuple_filter_filter,
                (void *)&cmd_5tuple_filter_port_id,
+               (void *)&cmd_5tuple_filter_ops,
                (void *)&cmd_5tuple_filter_dst_ip,
                (void *)&cmd_5tuple_filter_dst_ip_value,
                (void *)&cmd_5tuple_filter_src_ip,
@@ -7533,46 +7660,12 @@ cmdline_parse_inst_t cmd_add_5tuple_filter = {
                (void *)&cmd_5tuple_filter_protocol_value,
                (void *)&cmd_5tuple_filter_mask,
                (void *)&cmd_5tuple_filter_mask_value,
-               (void *)&cmd_5tuple_filter_flags,
-               (void *)&cmd_5tuple_filter_flags_value,
+               (void *)&cmd_5tuple_filter_tcp_flags,
+               (void *)&cmd_5tuple_filter_tcp_flags_value,
                (void *)&cmd_5tuple_filter_priority,
                (void *)&cmd_5tuple_filter_priority_value,
                (void *)&cmd_5tuple_filter_queue,
                (void *)&cmd_5tuple_filter_queue_id,
-               (void *)&cmd_5tuple_filter_index,
-               (void *)&cmd_5tuple_filter_index_value,
-               NULL,
-       },
-};
-
-cmdline_parse_token_string_t cmd_5tuple_filter_remove_filter =
-       TOKEN_STRING_INITIALIZER(struct cmd_5tuple_filter_result,
-                               filter, "remove_5tuple_filter");
-cmdline_parse_inst_t cmd_remove_5tuple_filter = {
-       .f = cmd_5tuple_filter_parsed,
-       .data = NULL,
-       .help_str = "remove a 5tuple filter",
-       .tokens = {
-               (void *)&cmd_5tuple_filter_remove_filter,
-               (void *)&cmd_5tuple_filter_port_id,
-               (void *)&cmd_5tuple_filter_index,
-               (void *)&cmd_5tuple_filter_index_value,
-               NULL,
-       },
-};
-
-cmdline_parse_token_string_t cmd_5tuple_filter_get_filter =
-       TOKEN_STRING_INITIALIZER(struct cmd_5tuple_filter_result,
-                               filter, "get_5tuple_filter");
-cmdline_parse_inst_t cmd_get_5tuple_filter = {
-       .f = cmd_5tuple_filter_parsed,
-       .data = NULL,
-       .help_str = "get a 5tuple filter",
-       .tokens = {
-               (void *)&cmd_5tuple_filter_get_filter,
-               (void *)&cmd_5tuple_filter_port_id,
-               (void *)&cmd_5tuple_filter_index,
-               (void *)&cmd_5tuple_filter_index_value,
                NULL,
        },
 };
@@ -7580,6 +7673,7 @@ cmdline_parse_inst_t cmd_get_5tuple_filter = {
 /* *** ADD/REMOVE A flex FILTER *** */
 struct cmd_flex_filter_result {
        cmdline_fixed_string_t filter;
+       cmdline_fixed_string_t ops;
        uint8_t port_id;
        cmdline_fixed_string_t len;
        uint8_t len_value;
@@ -7591,8 +7685,6 @@ struct cmd_flex_filter_result {
        uint8_t priority_value;
        cmdline_fixed_string_t queue;
        uint16_t queue_id;
-       cmdline_fixed_string_t index;
-       uint16_t index_value;
 };
 
 static int xdigit2val(unsigned char c)
@@ -7613,113 +7705,106 @@ cmd_flex_filter_parsed(void *parsed_result,
                          __attribute__((unused)) void *data)
 {
        int ret = 0;
-       struct rte_flex_filter filter;
+       struct rte_eth_flex_filter filter;
        struct cmd_flex_filter_result *res = parsed_result;
        char *bytes_ptr, *mask_ptr;
-       uint16_t len, i, j;
+       uint16_t len, i, j = 0;
        char c;
-       int val, mod = 0;
-       uint32_t dword = 0;
+       int val;
        uint8_t byte = 0;
-       uint8_t hex = 0;
 
-       if (!strcmp(res->filter, "add_flex_filter")) {
-               if (res->len_value > 128) {
-                       printf("the len exceed the max length 128\n");
-                       return;
-               }
-               memset(&filter, 0, sizeof(struct rte_flex_filter));
-               filter.len = res->len_value;
-               filter.priority = res->priority_value;
-               bytes_ptr = res->bytes_value;
-               mask_ptr = res->mask_value;
-
-               j = 0;
-                /* translate bytes string to uint_32 array. */
-               if (bytes_ptr[0] == '0' && ((bytes_ptr[1] == 'x') ||
-                       (bytes_ptr[1] == 'X')))
-                       bytes_ptr += 2;
-               len = strnlen(bytes_ptr, res->len_value * 2);
-               if (len == 0 || (len % 8 != 0)) {
-                       printf("please check len and bytes input\n");
+       if (res->len_value > RTE_FLEX_FILTER_MAXLEN) {
+               printf("the len exceed the max length 128\n");
+               return;
+       }
+       memset(&filter, 0, sizeof(struct rte_eth_flex_filter));
+       filter.len = res->len_value;
+       filter.priority = res->priority_value;
+       filter.queue = res->queue_id;
+       bytes_ptr = res->bytes_value;
+       mask_ptr = res->mask_value;
+
+        /* translate bytes string to array. */
+       if (bytes_ptr[0] == '0' && ((bytes_ptr[1] == 'x') ||
+               (bytes_ptr[1] == 'X')))
+               bytes_ptr += 2;
+       len = strnlen(bytes_ptr, res->len_value * 2);
+       if (len == 0 || (len % 8 != 0)) {
+               printf("please check len and bytes input\n");
+               return;
+       }
+       for (i = 0; i < len; i++) {
+               c = bytes_ptr[i];
+               if (isxdigit(c) == 0) {
+                       /* invalid characters. */
+                       printf("invalid input\n");
                        return;
                }
-               for (i = 0; i < len; i++) {
-                       c = bytes_ptr[i];
-                       if (isxdigit(c) == 0) {
-                               /* invalid characters. */
-                               printf("invalid input\n");
-                               return;
-                       }
-                       val = xdigit2val(c);
-                       mod = i % 8;
-                       if (i % 2) {
-                               byte |= val;
-                               dword |= byte << (4 * mod - 4);
-                               byte = 0;
-                       } else
-                               byte |= val << 4;
-                       if (mod == 7) {
-                               filter.dwords[j] = dword;
-                               printf("dwords[%d]:%08x ", j, filter.dwords[j]);
-                               j++;
-                               dword = 0;
-                       }
-               }
-               printf("\n");
-                /* translate mask string to uint8_t array. */
-               j = 0;
-               if (mask_ptr[0] == '0' && ((mask_ptr[1] == 'x') ||
-                       (mask_ptr[1] == 'X')))
-                       mask_ptr += 2;
-               len = strnlen(mask_ptr, (res->len_value+3)/4);
-               if (len == 0) {
+               val = xdigit2val(c);
+               if (i % 2) {
+                       byte |= val;
+                       filter.bytes[j] = byte;
+                       printf("bytes[%d]:%02x ", j, filter.bytes[j]);
+                       j++;
+                       byte = 0;
+               } else
+                       byte |= val << 4;
+       }
+       printf("\n");
+        /* translate mask string to uint8_t array. */
+       if (mask_ptr[0] == '0' && ((mask_ptr[1] == 'x') ||
+               (mask_ptr[1] == 'X')))
+               mask_ptr += 2;
+       len = strnlen(mask_ptr, (res->len_value + 3) / 4);
+       if (len == 0) {
+               printf("invalid input\n");
+               return;
+       }
+       j = 0;
+       byte = 0;
+       for (i = 0; i < len; i++) {
+               c = mask_ptr[i];
+               if (isxdigit(c) == 0) {
+                       /* invalid characters. */
                        printf("invalid input\n");
                        return;
                }
-               for (i = 0; i < len; i++) {
-                       c = mask_ptr[i];
-                       if (isxdigit(c) == 0) {
-                               /* invalid characters. */
-                               printf("invalid input\n");
-                               return;
-                       }
-                       val = xdigit2val(c);
-                       hex |= (uint8_t)(val & 0x8) >> 3;
-                       hex |= (uint8_t)(val & 0x4) >> 1;
-                       hex |= (uint8_t)(val & 0x2) << 1;
-                       hex |= (uint8_t)(val & 0x1) << 3;
-                       if (i % 2) {
-                               byte |= hex << 4;
-                               filter.mask[j] = byte;
-                               printf("mask[%d]:%02x ", j, filter.mask[j]);
-                               j++;
-                               byte = 0;
-                       } else
-                               byte |= hex;
-                       hex = 0;
-               }
-               printf("\n");
-               printf("call function rte_eth_dev_add_flex_filter: "
-                       "index = %d, queue-id = %d, len = %d, priority = %d\n",
-                       res->index_value, res->queue_id,
-                       filter.len, filter.priority);
-               ret = rte_eth_dev_add_flex_filter(res->port_id, res->index_value,
-                               &filter, res->queue_id);
-
-       } else if (!strcmp(res->filter, "remove_flex_filter"))
-               ret = rte_eth_dev_remove_flex_filter(res->port_id,
-                       res->index_value);
-       else if (!strcmp(res->filter, "get_flex_filter"))
-               get_flex_filter(res->port_id, res->index_value);
+               val = xdigit2val(c);
+               if (i % 2) {
+                       byte |= val;
+                       filter.mask[j] = byte;
+                       printf("mask[%d]:%02x ", j, filter.mask[j]);
+                       j++;
+                       byte = 0;
+               } else
+                       byte |= val << 4;
+       }
+       printf("\n");
+
+       if (!strcmp(res->ops, "add"))
+               ret = rte_eth_dev_filter_ctrl(res->port_id,
+                               RTE_ETH_FILTER_FLEXIBLE,
+                               RTE_ETH_FILTER_ADD,
+                               &filter);
+       else
+               ret = rte_eth_dev_filter_ctrl(res->port_id,
+                               RTE_ETH_FILTER_FLEXIBLE,
+                               RTE_ETH_FILTER_DELETE,
+                               &filter);
 
        if (ret < 0)
                printf("flex filter setting error: (%s)\n", strerror(-ret));
 }
 
+cmdline_parse_token_string_t cmd_flex_filter_filter =
+       TOKEN_STRING_INITIALIZER(struct cmd_flex_filter_result,
+                               filter, "flex_filter");
 cmdline_parse_token_num_t cmd_flex_filter_port_id =
        TOKEN_NUM_INITIALIZER(struct cmd_flex_filter_result,
                                port_id, UINT8);
+cmdline_parse_token_string_t cmd_flex_filter_ops =
+       TOKEN_STRING_INITIALIZER(struct cmd_flex_filter_result,
+                               ops, "add#del");
 cmdline_parse_token_string_t cmd_flex_filter_len =
        TOKEN_STRING_INITIALIZER(struct cmd_flex_filter_result,
                                len, "len");
@@ -7750,22 +7835,14 @@ cmdline_parse_token_string_t cmd_flex_filter_queue =
 cmdline_parse_token_num_t cmd_flex_filter_queue_id =
        TOKEN_NUM_INITIALIZER(struct cmd_flex_filter_result,
                                queue_id, UINT16);
-cmdline_parse_token_string_t cmd_flex_filter_index =
-       TOKEN_STRING_INITIALIZER(struct cmd_flex_filter_result,
-                               index, "index");
-cmdline_parse_token_num_t cmd_flex_filter_index_value =
-       TOKEN_NUM_INITIALIZER(struct cmd_flex_filter_result,
-                               index_value, UINT16);
-cmdline_parse_token_string_t cmd_flex_filter_add_filter =
-       TOKEN_STRING_INITIALIZER(struct cmd_flex_filter_result,
-                               filter, "add_flex_filter");
-cmdline_parse_inst_t cmd_add_flex_filter = {
+cmdline_parse_inst_t cmd_flex_filter = {
        .f = cmd_flex_filter_parsed,
        .data = NULL,
-       .help_str = "add a flex filter",
+       .help_str = "add/del a flex filter",
        .tokens = {
-               (void *)&cmd_flex_filter_add_filter,
+               (void *)&cmd_flex_filter_filter,
                (void *)&cmd_flex_filter_port_id,
+               (void *)&cmd_flex_filter_ops,
                (void *)&cmd_flex_filter_len,
                (void *)&cmd_flex_filter_len_value,
                (void *)&cmd_flex_filter_bytes,
@@ -7776,54 +7853,1796 @@ cmdline_parse_inst_t cmd_add_flex_filter = {
                (void *)&cmd_flex_filter_priority_value,
                (void *)&cmd_flex_filter_queue,
                (void *)&cmd_flex_filter_queue_id,
-               (void *)&cmd_flex_filter_index,
-               (void *)&cmd_flex_filter_index_value,
                NULL,
        },
 };
 
-cmdline_parse_token_string_t cmd_flex_filter_remove_filter =
-       TOKEN_STRING_INITIALIZER(struct cmd_flex_filter_result,
-                               filter, "remove_flex_filter");
-cmdline_parse_inst_t cmd_remove_flex_filter = {
-       .f = cmd_flex_filter_parsed,
-       .data = NULL,
-       .help_str = "remove a flex filter",
-       .tokens = {
-               (void *)&cmd_flex_filter_remove_filter,
-               (void *)&cmd_flex_filter_port_id,
-               (void *)&cmd_flex_filter_index,
-               (void *)&cmd_flex_filter_index_value,
-               NULL,
-       },
-};
+/* *** Filters Control *** */
 
-cmdline_parse_token_string_t cmd_flex_filter_get_filter =
-       TOKEN_STRING_INITIALIZER(struct cmd_flex_filter_result,
-                               filter, "get_flex_filter");
-cmdline_parse_inst_t cmd_get_flex_filter = {
-       .f = cmd_flex_filter_parsed,
-       .data = NULL,
-       .help_str = "get a flex filter",
-       .tokens = {
-               (void *)&cmd_flex_filter_get_filter,
-               (void *)&cmd_flex_filter_port_id,
-               (void *)&cmd_flex_filter_index,
-               (void *)&cmd_flex_filter_index_value,
-               NULL,
-       },
+/* *** deal with ethertype filter *** */
+struct cmd_ethertype_filter_result {
+       cmdline_fixed_string_t filter;
+       uint8_t port_id;
+       cmdline_fixed_string_t ops;
+       cmdline_fixed_string_t mac;
+       struct ether_addr mac_addr;
+       cmdline_fixed_string_t ethertype;
+       uint16_t ethertype_value;
+       cmdline_fixed_string_t drop;
+       cmdline_fixed_string_t queue;
+       uint16_t  queue_id;
 };
 
-/* ******************************************************************************** */
-
-/* list of instructions */
-cmdline_parse_ctx_t main_ctx[] = {
-       (cmdline_parse_inst_t *)&cmd_help_brief,
-       (cmdline_parse_inst_t *)&cmd_help_long,
-       (cmdline_parse_inst_t *)&cmd_quit,
-       (cmdline_parse_inst_t *)&cmd_showport,
-       (cmdline_parse_inst_t *)&cmd_showportall,
-       (cmdline_parse_inst_t *)&cmd_showcfg,
+cmdline_parse_token_string_t cmd_ethertype_filter_filter =
+       TOKEN_STRING_INITIALIZER(struct cmd_ethertype_filter_result,
+                                filter, "ethertype_filter");
+cmdline_parse_token_num_t cmd_ethertype_filter_port_id =
+       TOKEN_NUM_INITIALIZER(struct cmd_ethertype_filter_result,
+                             port_id, UINT8);
+cmdline_parse_token_string_t cmd_ethertype_filter_ops =
+       TOKEN_STRING_INITIALIZER(struct cmd_ethertype_filter_result,
+                                ops, "add#del");
+cmdline_parse_token_string_t cmd_ethertype_filter_mac =
+       TOKEN_STRING_INITIALIZER(struct cmd_ethertype_filter_result,
+                                mac, "mac_addr#mac_ignr");
+cmdline_parse_token_etheraddr_t cmd_ethertype_filter_mac_addr =
+       TOKEN_ETHERADDR_INITIALIZER(struct cmd_ethertype_filter_result,
+                                    mac_addr);
+cmdline_parse_token_string_t cmd_ethertype_filter_ethertype =
+       TOKEN_STRING_INITIALIZER(struct cmd_ethertype_filter_result,
+                                ethertype, "ethertype");
+cmdline_parse_token_num_t cmd_ethertype_filter_ethertype_value =
+       TOKEN_NUM_INITIALIZER(struct cmd_ethertype_filter_result,
+                             ethertype_value, UINT16);
+cmdline_parse_token_string_t cmd_ethertype_filter_drop =
+       TOKEN_STRING_INITIALIZER(struct cmd_ethertype_filter_result,
+                                drop, "drop#fwd");
+cmdline_parse_token_string_t cmd_ethertype_filter_queue =
+       TOKEN_STRING_INITIALIZER(struct cmd_ethertype_filter_result,
+                                queue, "queue");
+cmdline_parse_token_num_t cmd_ethertype_filter_queue_id =
+       TOKEN_NUM_INITIALIZER(struct cmd_ethertype_filter_result,
+                             queue_id, UINT16);
+
+static void
+cmd_ethertype_filter_parsed(void *parsed_result,
+                         __attribute__((unused)) struct cmdline *cl,
+                         __attribute__((unused)) void *data)
+{
+       struct cmd_ethertype_filter_result *res = parsed_result;
+       struct rte_eth_ethertype_filter filter;
+       int ret = 0;
+
+       ret = rte_eth_dev_filter_supported(res->port_id,
+                       RTE_ETH_FILTER_ETHERTYPE);
+       if (ret < 0) {
+               printf("ethertype filter is not supported on port %u.\n",
+                       res->port_id);
+               return;
+       }
+
+       memset(&filter, 0, sizeof(filter));
+       if (!strcmp(res->mac, "mac_addr")) {
+               filter.flags |= RTE_ETHTYPE_FLAGS_MAC;
+               (void)rte_memcpy(&filter.mac_addr, &res->mac_addr,
+                       sizeof(struct ether_addr));
+       }
+       if (!strcmp(res->drop, "drop"))
+               filter.flags |= RTE_ETHTYPE_FLAGS_DROP;
+       filter.ether_type = res->ethertype_value;
+       filter.queue = res->queue_id;
+
+       if (!strcmp(res->ops, "add"))
+               ret = rte_eth_dev_filter_ctrl(res->port_id,
+                               RTE_ETH_FILTER_ETHERTYPE,
+                               RTE_ETH_FILTER_ADD,
+                               &filter);
+       else
+               ret = rte_eth_dev_filter_ctrl(res->port_id,
+                               RTE_ETH_FILTER_ETHERTYPE,
+                               RTE_ETH_FILTER_DELETE,
+                               &filter);
+       if (ret < 0)
+               printf("ethertype filter programming error: (%s)\n",
+                       strerror(-ret));
+}
+
+cmdline_parse_inst_t cmd_ethertype_filter = {
+       .f = cmd_ethertype_filter_parsed,
+       .data = NULL,
+       .help_str = "add or delete an ethertype filter entry",
+       .tokens = {
+               (void *)&cmd_ethertype_filter_filter,
+               (void *)&cmd_ethertype_filter_port_id,
+               (void *)&cmd_ethertype_filter_ops,
+               (void *)&cmd_ethertype_filter_mac,
+               (void *)&cmd_ethertype_filter_mac_addr,
+               (void *)&cmd_ethertype_filter_ethertype,
+               (void *)&cmd_ethertype_filter_ethertype_value,
+               (void *)&cmd_ethertype_filter_drop,
+               (void *)&cmd_ethertype_filter_queue,
+               (void *)&cmd_ethertype_filter_queue_id,
+               NULL,
+       },
+};
+
+/* *** deal with flow director filter *** */
+struct cmd_flow_director_result {
+       cmdline_fixed_string_t flow_director_filter;
+       uint8_t port_id;
+       cmdline_fixed_string_t mode;
+       cmdline_fixed_string_t mode_value;
+       cmdline_fixed_string_t ops;
+       cmdline_fixed_string_t flow;
+       cmdline_fixed_string_t flow_type;
+       cmdline_fixed_string_t ether;
+       uint16_t ether_type;
+       cmdline_fixed_string_t src;
+       cmdline_ipaddr_t ip_src;
+       uint16_t port_src;
+       cmdline_fixed_string_t dst;
+       cmdline_ipaddr_t ip_dst;
+       uint16_t port_dst;
+       cmdline_fixed_string_t verify_tag;
+       uint32_t verify_tag_value;
+       cmdline_fixed_string_t vlan;
+       uint16_t vlan_value;
+       cmdline_fixed_string_t flexbytes;
+       cmdline_fixed_string_t flexbytes_value;
+       cmdline_fixed_string_t pf_vf;
+       cmdline_fixed_string_t drop;
+       cmdline_fixed_string_t queue;
+       uint16_t  queue_id;
+       cmdline_fixed_string_t fd_id;
+       uint32_t  fd_id_value;
+       cmdline_fixed_string_t mac;
+       struct ether_addr mac_addr;
+       cmdline_fixed_string_t tunnel;
+       cmdline_fixed_string_t tunnel_type;
+       cmdline_fixed_string_t tunnel_id;
+       uint32_t tunnel_id_value;
+};
+
+static inline int
+parse_flexbytes(const char *q_arg, uint8_t *flexbytes, uint16_t max_num)
+{
+       char s[256];
+       const char *p, *p0 = q_arg;
+       char *end;
+       unsigned long int_fld;
+       char *str_fld[max_num];
+       int i;
+       unsigned size;
+       int ret = -1;
+
+       p = strchr(p0, '(');
+       if (p == NULL)
+               return -1;
+       ++p;
+       p0 = strchr(p, ')');
+       if (p0 == NULL)
+               return -1;
+
+       size = p0 - p;
+       if (size >= sizeof(s))
+               return -1;
+
+       snprintf(s, sizeof(s), "%.*s", size, p);
+       ret = rte_strsplit(s, sizeof(s), str_fld, max_num, ',');
+       if (ret < 0 || ret > max_num)
+               return -1;
+       for (i = 0; i < ret; i++) {
+               errno = 0;
+               int_fld = strtoul(str_fld[i], &end, 0);
+               if (errno != 0 || *end != '\0' || int_fld > UINT8_MAX)
+                       return -1;
+               flexbytes[i] = (uint8_t)int_fld;
+       }
+       return ret;
+}
+
+static uint16_t
+str2flowtype(char *string)
+{
+       uint8_t i = 0;
+       static const struct {
+               char str[32];
+               uint16_t type;
+       } flowtype_str[] = {
+               {"raw", RTE_ETH_FLOW_RAW},
+               {"ipv4", RTE_ETH_FLOW_IPV4},
+               {"ipv4-frag", RTE_ETH_FLOW_FRAG_IPV4},
+               {"ipv4-tcp", RTE_ETH_FLOW_NONFRAG_IPV4_TCP},
+               {"ipv4-udp", RTE_ETH_FLOW_NONFRAG_IPV4_UDP},
+               {"ipv4-sctp", RTE_ETH_FLOW_NONFRAG_IPV4_SCTP},
+               {"ipv4-other", RTE_ETH_FLOW_NONFRAG_IPV4_OTHER},
+               {"ipv6", RTE_ETH_FLOW_IPV6},
+               {"ipv6-frag", RTE_ETH_FLOW_FRAG_IPV6},
+               {"ipv6-tcp", RTE_ETH_FLOW_NONFRAG_IPV6_TCP},
+               {"ipv6-udp", RTE_ETH_FLOW_NONFRAG_IPV6_UDP},
+               {"ipv6-sctp", RTE_ETH_FLOW_NONFRAG_IPV6_SCTP},
+               {"ipv6-other", RTE_ETH_FLOW_NONFRAG_IPV6_OTHER},
+               {"l2_payload", RTE_ETH_FLOW_L2_PAYLOAD},
+       };
+
+       for (i = 0; i < RTE_DIM(flowtype_str); i++) {
+               if (!strcmp(flowtype_str[i].str, string))
+                       return flowtype_str[i].type;
+       }
+       return RTE_ETH_FLOW_UNKNOWN;
+}
+
+static enum rte_eth_fdir_tunnel_type
+str2fdir_tunneltype(char *string)
+{
+       uint8_t i = 0;
+
+       static const struct {
+               char str[32];
+               enum rte_eth_fdir_tunnel_type type;
+       } tunneltype_str[] = {
+               {"NVGRE", RTE_FDIR_TUNNEL_TYPE_NVGRE},
+               {"VxLAN", RTE_FDIR_TUNNEL_TYPE_VXLAN},
+       };
+
+       for (i = 0; i < RTE_DIM(tunneltype_str); i++) {
+               if (!strcmp(tunneltype_str[i].str, string))
+                       return tunneltype_str[i].type;
+       }
+       return RTE_FDIR_TUNNEL_TYPE_UNKNOWN;
+}
+
+#define IPV4_ADDR_TO_UINT(ip_addr, ip) \
+do { \
+       if ((ip_addr).family == AF_INET) \
+               (ip) = (ip_addr).addr.ipv4.s_addr; \
+       else { \
+               printf("invalid parameter.\n"); \
+               return; \
+       } \
+} while (0)
+
+#define IPV6_ADDR_TO_ARRAY(ip_addr, ip) \
+do { \
+       if ((ip_addr).family == AF_INET6) \
+               (void)rte_memcpy(&(ip), \
+                                &((ip_addr).addr.ipv6), \
+                                sizeof(struct in6_addr)); \
+       else { \
+               printf("invalid parameter.\n"); \
+               return; \
+       } \
+} while (0)
+
+static void
+cmd_flow_director_filter_parsed(void *parsed_result,
+                         __attribute__((unused)) struct cmdline *cl,
+                         __attribute__((unused)) void *data)
+{
+       struct cmd_flow_director_result *res = parsed_result;
+       struct rte_eth_fdir_filter entry;
+       uint8_t flexbytes[RTE_ETH_FDIR_MAX_FLEXLEN];
+       char *end;
+       unsigned long vf_id;
+       int ret = 0;
+
+       ret = rte_eth_dev_filter_supported(res->port_id, RTE_ETH_FILTER_FDIR);
+       if (ret < 0) {
+               printf("flow director is not supported on port %u.\n",
+                       res->port_id);
+               return;
+       }
+       memset(flexbytes, 0, sizeof(flexbytes));
+       memset(&entry, 0, sizeof(struct rte_eth_fdir_filter));
+
+       if (fdir_conf.mode ==  RTE_FDIR_MODE_PERFECT_MAC_VLAN) {
+               if (strcmp(res->mode_value, "MAC-VLAN")) {
+                       printf("Please set mode to MAC-VLAN.\n");
+                       return;
+               }
+       } else if (fdir_conf.mode ==  RTE_FDIR_MODE_PERFECT_TUNNEL) {
+               if (strcmp(res->mode_value, "Tunnel")) {
+                       printf("Please set mode to Tunnel.\n");
+                       return;
+               }
+       } else {
+               if (strcmp(res->mode_value, "IP")) {
+                       printf("Please set mode to IP.\n");
+                       return;
+               }
+               entry.input.flow_type = str2flowtype(res->flow_type);
+       }
+
+       ret = parse_flexbytes(res->flexbytes_value,
+                                       flexbytes,
+                                       RTE_ETH_FDIR_MAX_FLEXLEN);
+       if (ret < 0) {
+               printf("error: Cannot parse flexbytes input.\n");
+               return;
+       }
+
+       switch (entry.input.flow_type) {
+       case RTE_ETH_FLOW_FRAG_IPV4:
+       case RTE_ETH_FLOW_NONFRAG_IPV4_OTHER:
+       case RTE_ETH_FLOW_NONFRAG_IPV4_UDP:
+       case RTE_ETH_FLOW_NONFRAG_IPV4_TCP:
+               IPV4_ADDR_TO_UINT(res->ip_dst,
+                       entry.input.flow.ip4_flow.dst_ip);
+               IPV4_ADDR_TO_UINT(res->ip_src,
+                       entry.input.flow.ip4_flow.src_ip);
+               /* need convert to big endian. */
+               entry.input.flow.udp4_flow.dst_port =
+                               rte_cpu_to_be_16(res->port_dst);
+               entry.input.flow.udp4_flow.src_port =
+                               rte_cpu_to_be_16(res->port_src);
+               break;
+       case RTE_ETH_FLOW_NONFRAG_IPV4_SCTP:
+               IPV4_ADDR_TO_UINT(res->ip_dst,
+                       entry.input.flow.sctp4_flow.ip.dst_ip);
+               IPV4_ADDR_TO_UINT(res->ip_src,
+                       entry.input.flow.sctp4_flow.ip.src_ip);
+               /* need convert to big endian. */
+               entry.input.flow.sctp4_flow.dst_port =
+                               rte_cpu_to_be_16(res->port_dst);
+               entry.input.flow.sctp4_flow.src_port =
+                               rte_cpu_to_be_16(res->port_src);
+               entry.input.flow.sctp4_flow.verify_tag =
+                               rte_cpu_to_be_32(res->verify_tag_value);
+               break;
+       case RTE_ETH_FLOW_FRAG_IPV6:
+       case RTE_ETH_FLOW_NONFRAG_IPV6_OTHER:
+       case RTE_ETH_FLOW_NONFRAG_IPV6_UDP:
+       case RTE_ETH_FLOW_NONFRAG_IPV6_TCP:
+               IPV6_ADDR_TO_ARRAY(res->ip_dst,
+                       entry.input.flow.ipv6_flow.dst_ip);
+               IPV6_ADDR_TO_ARRAY(res->ip_src,
+                       entry.input.flow.ipv6_flow.src_ip);
+               /* need convert to big endian. */
+               entry.input.flow.udp6_flow.dst_port =
+                               rte_cpu_to_be_16(res->port_dst);
+               entry.input.flow.udp6_flow.src_port =
+                               rte_cpu_to_be_16(res->port_src);
+               break;
+       case RTE_ETH_FLOW_NONFRAG_IPV6_SCTP:
+               IPV6_ADDR_TO_ARRAY(res->ip_dst,
+                       entry.input.flow.sctp6_flow.ip.dst_ip);
+               IPV6_ADDR_TO_ARRAY(res->ip_src,
+                       entry.input.flow.sctp6_flow.ip.src_ip);
+               /* need convert to big endian. */
+               entry.input.flow.sctp6_flow.dst_port =
+                               rte_cpu_to_be_16(res->port_dst);
+               entry.input.flow.sctp6_flow.src_port =
+                               rte_cpu_to_be_16(res->port_src);
+               entry.input.flow.sctp6_flow.verify_tag =
+                               rte_cpu_to_be_32(res->verify_tag_value);
+               break;
+       case RTE_ETH_FLOW_L2_PAYLOAD:
+               entry.input.flow.l2_flow.ether_type =
+                       rte_cpu_to_be_16(res->ether_type);
+               break;
+       default:
+               break;
+       }
+
+       if (fdir_conf.mode ==  RTE_FDIR_MODE_PERFECT_MAC_VLAN)
+               (void)rte_memcpy(&entry.input.flow.mac_vlan_flow.mac_addr,
+                                &res->mac_addr,
+                                sizeof(struct ether_addr));
+
+       if (fdir_conf.mode ==  RTE_FDIR_MODE_PERFECT_TUNNEL) {
+               (void)rte_memcpy(&entry.input.flow.tunnel_flow.mac_addr,
+                                &res->mac_addr,
+                                sizeof(struct ether_addr));
+               entry.input.flow.tunnel_flow.tunnel_type =
+                       str2fdir_tunneltype(res->tunnel_type);
+               entry.input.flow.tunnel_flow.tunnel_id =
+                       rte_cpu_to_be_32(res->tunnel_id_value);
+       }
+
+       (void)rte_memcpy(entry.input.flow_ext.flexbytes,
+                  flexbytes,
+                  RTE_ETH_FDIR_MAX_FLEXLEN);
+
+       entry.input.flow_ext.vlan_tci = rte_cpu_to_be_16(res->vlan_value);
+
+       entry.action.flex_off = 0;  /*use 0 by default */
+       if (!strcmp(res->drop, "drop"))
+               entry.action.behavior = RTE_ETH_FDIR_REJECT;
+       else
+               entry.action.behavior = RTE_ETH_FDIR_ACCEPT;
+
+       if (!strcmp(res->pf_vf, "pf"))
+               entry.input.flow_ext.is_vf = 0;
+       else if (!strncmp(res->pf_vf, "vf", 2)) {
+               struct rte_eth_dev_info dev_info;
+
+               memset(&dev_info, 0, sizeof(dev_info));
+               rte_eth_dev_info_get(res->port_id, &dev_info);
+               errno = 0;
+               vf_id = strtoul(res->pf_vf + 2, &end, 10);
+               if (errno != 0 || *end != '\0' || vf_id >= dev_info.max_vfs) {
+                       printf("invalid parameter %s.\n", res->pf_vf);
+                       return;
+               }
+               entry.input.flow_ext.is_vf = 1;
+               entry.input.flow_ext.dst_id = (uint16_t)vf_id;
+       } else {
+               printf("invalid parameter %s.\n", res->pf_vf);
+               return;
+       }
+
+       /* set to report FD ID by default */
+       entry.action.report_status = RTE_ETH_FDIR_REPORT_ID;
+       entry.action.rx_queue = res->queue_id;
+       entry.soft_id = res->fd_id_value;
+       if (!strcmp(res->ops, "add"))
+               ret = rte_eth_dev_filter_ctrl(res->port_id, RTE_ETH_FILTER_FDIR,
+                                            RTE_ETH_FILTER_ADD, &entry);
+       else if (!strcmp(res->ops, "del"))
+               ret = rte_eth_dev_filter_ctrl(res->port_id, RTE_ETH_FILTER_FDIR,
+                                            RTE_ETH_FILTER_DELETE, &entry);
+       else
+               ret = rte_eth_dev_filter_ctrl(res->port_id, RTE_ETH_FILTER_FDIR,
+                                            RTE_ETH_FILTER_UPDATE, &entry);
+       if (ret < 0)
+               printf("flow director programming error: (%s)\n",
+                       strerror(-ret));
+}
+
+cmdline_parse_token_string_t cmd_flow_director_filter =
+       TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
+                                flow_director_filter, "flow_director_filter");
+cmdline_parse_token_num_t cmd_flow_director_port_id =
+       TOKEN_NUM_INITIALIZER(struct cmd_flow_director_result,
+                             port_id, UINT8);
+cmdline_parse_token_string_t cmd_flow_director_ops =
+       TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
+                                ops, "add#del#update");
+cmdline_parse_token_string_t cmd_flow_director_flow =
+       TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
+                                flow, "flow");
+cmdline_parse_token_string_t cmd_flow_director_flow_type =
+       TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
+               flow_type, "ipv4-other#ipv4-frag#ipv4-tcp#ipv4-udp#ipv4-sctp#"
+               "ipv6-other#ipv6-frag#ipv6-tcp#ipv6-udp#ipv6-sctp#l2_payload");
+cmdline_parse_token_string_t cmd_flow_director_ether =
+       TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
+                                ether, "ether");
+cmdline_parse_token_num_t cmd_flow_director_ether_type =
+       TOKEN_NUM_INITIALIZER(struct cmd_flow_director_result,
+                             ether_type, UINT16);
+cmdline_parse_token_string_t cmd_flow_director_src =
+       TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
+                                src, "src");
+cmdline_parse_token_ipaddr_t cmd_flow_director_ip_src =
+       TOKEN_IPADDR_INITIALIZER(struct cmd_flow_director_result,
+                                ip_src);
+cmdline_parse_token_num_t cmd_flow_director_port_src =
+       TOKEN_NUM_INITIALIZER(struct cmd_flow_director_result,
+                             port_src, UINT16);
+cmdline_parse_token_string_t cmd_flow_director_dst =
+       TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
+                                dst, "dst");
+cmdline_parse_token_ipaddr_t cmd_flow_director_ip_dst =
+       TOKEN_IPADDR_INITIALIZER(struct cmd_flow_director_result,
+                                ip_dst);
+cmdline_parse_token_num_t cmd_flow_director_port_dst =
+       TOKEN_NUM_INITIALIZER(struct cmd_flow_director_result,
+                             port_dst, UINT16);
+cmdline_parse_token_string_t cmd_flow_director_verify_tag =
+       TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
+                                 verify_tag, "verify_tag");
+cmdline_parse_token_num_t cmd_flow_director_verify_tag_value =
+       TOKEN_NUM_INITIALIZER(struct cmd_flow_director_result,
+                             verify_tag_value, UINT32);
+cmdline_parse_token_string_t cmd_flow_director_vlan =
+       TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
+                                vlan, "vlan");
+cmdline_parse_token_num_t cmd_flow_director_vlan_value =
+       TOKEN_NUM_INITIALIZER(struct cmd_flow_director_result,
+                             vlan_value, UINT16);
+cmdline_parse_token_string_t cmd_flow_director_flexbytes =
+       TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
+                                flexbytes, "flexbytes");
+cmdline_parse_token_string_t cmd_flow_director_flexbytes_value =
+       TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
+                             flexbytes_value, NULL);
+cmdline_parse_token_string_t cmd_flow_director_drop =
+       TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
+                                drop, "drop#fwd");
+cmdline_parse_token_string_t cmd_flow_director_pf_vf =
+       TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
+                             pf_vf, NULL);
+cmdline_parse_token_string_t cmd_flow_director_queue =
+       TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
+                                queue, "queue");
+cmdline_parse_token_num_t cmd_flow_director_queue_id =
+       TOKEN_NUM_INITIALIZER(struct cmd_flow_director_result,
+                             queue_id, UINT16);
+cmdline_parse_token_string_t cmd_flow_director_fd_id =
+       TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
+                                fd_id, "fd_id");
+cmdline_parse_token_num_t cmd_flow_director_fd_id_value =
+       TOKEN_NUM_INITIALIZER(struct cmd_flow_director_result,
+                             fd_id_value, UINT32);
+
+cmdline_parse_token_string_t cmd_flow_director_mode =
+       TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
+                                mode, "mode");
+cmdline_parse_token_string_t cmd_flow_director_mode_ip =
+       TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
+                                mode_value, "IP");
+cmdline_parse_token_string_t cmd_flow_director_mode_mac_vlan =
+       TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
+                                mode_value, "MAC-VLAN");
+cmdline_parse_token_string_t cmd_flow_director_mode_tunnel =
+       TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
+                                mode_value, "Tunnel");
+cmdline_parse_token_string_t cmd_flow_director_mac =
+       TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
+                                mac, "mac");
+cmdline_parse_token_etheraddr_t cmd_flow_director_mac_addr =
+       TOKEN_ETHERADDR_INITIALIZER(struct cmd_flow_director_result,
+                                   mac_addr);
+cmdline_parse_token_string_t cmd_flow_director_tunnel =
+       TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
+                                tunnel, "tunnel");
+cmdline_parse_token_string_t cmd_flow_director_tunnel_type =
+       TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
+                                tunnel_type, "NVGRE#VxLAN");
+cmdline_parse_token_string_t cmd_flow_director_tunnel_id =
+       TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
+                                tunnel_id, "tunnel-id");
+cmdline_parse_token_num_t cmd_flow_director_tunnel_id_value =
+       TOKEN_NUM_INITIALIZER(struct cmd_flow_director_result,
+                             tunnel_id_value, UINT32);
+
+cmdline_parse_inst_t cmd_add_del_ip_flow_director = {
+       .f = cmd_flow_director_filter_parsed,
+       .data = NULL,
+       .help_str = "add or delete an ip flow director entry on NIC",
+       .tokens = {
+               (void *)&cmd_flow_director_filter,
+               (void *)&cmd_flow_director_port_id,
+               (void *)&cmd_flow_director_mode,
+               (void *)&cmd_flow_director_mode_ip,
+               (void *)&cmd_flow_director_ops,
+               (void *)&cmd_flow_director_flow,
+               (void *)&cmd_flow_director_flow_type,
+               (void *)&cmd_flow_director_src,
+               (void *)&cmd_flow_director_ip_src,
+               (void *)&cmd_flow_director_dst,
+               (void *)&cmd_flow_director_ip_dst,
+               (void *)&cmd_flow_director_vlan,
+               (void *)&cmd_flow_director_vlan_value,
+               (void *)&cmd_flow_director_flexbytes,
+               (void *)&cmd_flow_director_flexbytes_value,
+               (void *)&cmd_flow_director_drop,
+               (void *)&cmd_flow_director_pf_vf,
+               (void *)&cmd_flow_director_queue,
+               (void *)&cmd_flow_director_queue_id,
+               (void *)&cmd_flow_director_fd_id,
+               (void *)&cmd_flow_director_fd_id_value,
+               NULL,
+       },
+};
+
+cmdline_parse_inst_t cmd_add_del_udp_flow_director = {
+       .f = cmd_flow_director_filter_parsed,
+       .data = NULL,
+       .help_str = "add or delete an udp/tcp flow director entry on NIC",
+       .tokens = {
+               (void *)&cmd_flow_director_filter,
+               (void *)&cmd_flow_director_port_id,
+               (void *)&cmd_flow_director_mode,
+               (void *)&cmd_flow_director_mode_ip,
+               (void *)&cmd_flow_director_ops,
+               (void *)&cmd_flow_director_flow,
+               (void *)&cmd_flow_director_flow_type,
+               (void *)&cmd_flow_director_src,
+               (void *)&cmd_flow_director_ip_src,
+               (void *)&cmd_flow_director_port_src,
+               (void *)&cmd_flow_director_dst,
+               (void *)&cmd_flow_director_ip_dst,
+               (void *)&cmd_flow_director_port_dst,
+               (void *)&cmd_flow_director_vlan,
+               (void *)&cmd_flow_director_vlan_value,
+               (void *)&cmd_flow_director_flexbytes,
+               (void *)&cmd_flow_director_flexbytes_value,
+               (void *)&cmd_flow_director_drop,
+               (void *)&cmd_flow_director_pf_vf,
+               (void *)&cmd_flow_director_queue,
+               (void *)&cmd_flow_director_queue_id,
+               (void *)&cmd_flow_director_fd_id,
+               (void *)&cmd_flow_director_fd_id_value,
+               NULL,
+       },
+};
+
+cmdline_parse_inst_t cmd_add_del_sctp_flow_director = {
+       .f = cmd_flow_director_filter_parsed,
+       .data = NULL,
+       .help_str = "add or delete a sctp flow director entry on NIC",
+       .tokens = {
+               (void *)&cmd_flow_director_filter,
+               (void *)&cmd_flow_director_port_id,
+               (void *)&cmd_flow_director_mode,
+               (void *)&cmd_flow_director_mode_ip,
+               (void *)&cmd_flow_director_ops,
+               (void *)&cmd_flow_director_flow,
+               (void *)&cmd_flow_director_flow_type,
+               (void *)&cmd_flow_director_src,
+               (void *)&cmd_flow_director_ip_src,
+               (void *)&cmd_flow_director_port_dst,
+               (void *)&cmd_flow_director_dst,
+               (void *)&cmd_flow_director_ip_dst,
+               (void *)&cmd_flow_director_port_dst,
+               (void *)&cmd_flow_director_verify_tag,
+               (void *)&cmd_flow_director_verify_tag_value,
+               (void *)&cmd_flow_director_vlan,
+               (void *)&cmd_flow_director_vlan_value,
+               (void *)&cmd_flow_director_flexbytes,
+               (void *)&cmd_flow_director_flexbytes_value,
+               (void *)&cmd_flow_director_drop,
+               (void *)&cmd_flow_director_pf_vf,
+               (void *)&cmd_flow_director_queue,
+               (void *)&cmd_flow_director_queue_id,
+               (void *)&cmd_flow_director_fd_id,
+               (void *)&cmd_flow_director_fd_id_value,
+               NULL,
+       },
+};
+
+cmdline_parse_inst_t cmd_add_del_l2_flow_director = {
+       .f = cmd_flow_director_filter_parsed,
+       .data = NULL,
+       .help_str = "add or delete a L2 flow director entry on NIC",
+       .tokens = {
+               (void *)&cmd_flow_director_filter,
+               (void *)&cmd_flow_director_port_id,
+               (void *)&cmd_flow_director_mode,
+               (void *)&cmd_flow_director_mode_ip,
+               (void *)&cmd_flow_director_ops,
+               (void *)&cmd_flow_director_flow,
+               (void *)&cmd_flow_director_flow_type,
+               (void *)&cmd_flow_director_ether,
+               (void *)&cmd_flow_director_ether_type,
+               (void *)&cmd_flow_director_flexbytes,
+               (void *)&cmd_flow_director_flexbytes_value,
+               (void *)&cmd_flow_director_drop,
+               (void *)&cmd_flow_director_pf_vf,
+               (void *)&cmd_flow_director_queue,
+               (void *)&cmd_flow_director_queue_id,
+               (void *)&cmd_flow_director_fd_id,
+               (void *)&cmd_flow_director_fd_id_value,
+               NULL,
+       },
+};
+
+cmdline_parse_inst_t cmd_add_del_mac_vlan_flow_director = {
+       .f = cmd_flow_director_filter_parsed,
+       .data = NULL,
+       .help_str = "add or delete a MAC VLAN flow director entry on NIC",
+       .tokens = {
+               (void *)&cmd_flow_director_filter,
+               (void *)&cmd_flow_director_port_id,
+               (void *)&cmd_flow_director_mode,
+               (void *)&cmd_flow_director_mode_mac_vlan,
+               (void *)&cmd_flow_director_ops,
+               (void *)&cmd_flow_director_mac,
+               (void *)&cmd_flow_director_mac_addr,
+               (void *)&cmd_flow_director_vlan,
+               (void *)&cmd_flow_director_vlan_value,
+               (void *)&cmd_flow_director_flexbytes,
+               (void *)&cmd_flow_director_flexbytes_value,
+               (void *)&cmd_flow_director_drop,
+               (void *)&cmd_flow_director_queue,
+               (void *)&cmd_flow_director_queue_id,
+               (void *)&cmd_flow_director_fd_id,
+               (void *)&cmd_flow_director_fd_id_value,
+               NULL,
+       },
+};
+
+cmdline_parse_inst_t cmd_add_del_tunnel_flow_director = {
+       .f = cmd_flow_director_filter_parsed,
+       .data = NULL,
+       .help_str = "add or delete a tunnel flow director entry on NIC",
+       .tokens = {
+               (void *)&cmd_flow_director_filter,
+               (void *)&cmd_flow_director_port_id,
+               (void *)&cmd_flow_director_mode,
+               (void *)&cmd_flow_director_mode_tunnel,
+               (void *)&cmd_flow_director_ops,
+               (void *)&cmd_flow_director_mac,
+               (void *)&cmd_flow_director_mac_addr,
+               (void *)&cmd_flow_director_vlan,
+               (void *)&cmd_flow_director_vlan_value,
+               (void *)&cmd_flow_director_tunnel,
+               (void *)&cmd_flow_director_tunnel_type,
+               (void *)&cmd_flow_director_tunnel_id,
+               (void *)&cmd_flow_director_tunnel_id_value,
+               (void *)&cmd_flow_director_flexbytes,
+               (void *)&cmd_flow_director_flexbytes_value,
+               (void *)&cmd_flow_director_drop,
+               (void *)&cmd_flow_director_queue,
+               (void *)&cmd_flow_director_queue_id,
+               (void *)&cmd_flow_director_fd_id,
+               (void *)&cmd_flow_director_fd_id_value,
+               NULL,
+       },
+};
+
+struct cmd_flush_flow_director_result {
+       cmdline_fixed_string_t flush_flow_director;
+       uint8_t port_id;
+};
+
+cmdline_parse_token_string_t cmd_flush_flow_director_flush =
+       TOKEN_STRING_INITIALIZER(struct cmd_flush_flow_director_result,
+                                flush_flow_director, "flush_flow_director");
+cmdline_parse_token_num_t cmd_flush_flow_director_port_id =
+       TOKEN_NUM_INITIALIZER(struct cmd_flush_flow_director_result,
+                             port_id, UINT8);
+
+static void
+cmd_flush_flow_director_parsed(void *parsed_result,
+                         __attribute__((unused)) struct cmdline *cl,
+                         __attribute__((unused)) void *data)
+{
+       struct cmd_flow_director_result *res = parsed_result;
+       int ret = 0;
+
+       ret = rte_eth_dev_filter_supported(res->port_id, RTE_ETH_FILTER_FDIR);
+       if (ret < 0) {
+               printf("flow director is not supported on port %u.\n",
+                       res->port_id);
+               return;
+       }
+
+       ret = rte_eth_dev_filter_ctrl(res->port_id, RTE_ETH_FILTER_FDIR,
+                       RTE_ETH_FILTER_FLUSH, NULL);
+       if (ret < 0)
+               printf("flow director table flushing error: (%s)\n",
+                       strerror(-ret));
+}
+
+cmdline_parse_inst_t cmd_flush_flow_director = {
+       .f = cmd_flush_flow_director_parsed,
+       .data = NULL,
+       .help_str = "flush all flow director entries of a device on NIC",
+       .tokens = {
+               (void *)&cmd_flush_flow_director_flush,
+               (void *)&cmd_flush_flow_director_port_id,
+               NULL,
+       },
+};
+
+/* *** deal with flow director mask *** */
+struct cmd_flow_director_mask_result {
+       cmdline_fixed_string_t flow_director_mask;
+       uint8_t port_id;
+       cmdline_fixed_string_t mode;
+       cmdline_fixed_string_t mode_value;
+       cmdline_fixed_string_t vlan;
+       uint16_t vlan_mask;
+       cmdline_fixed_string_t src_mask;
+       cmdline_ipaddr_t ipv4_src;
+       cmdline_ipaddr_t ipv6_src;
+       uint16_t port_src;
+       cmdline_fixed_string_t dst_mask;
+       cmdline_ipaddr_t ipv4_dst;
+       cmdline_ipaddr_t ipv6_dst;
+       uint16_t port_dst;
+       cmdline_fixed_string_t mac;
+       uint8_t mac_addr_byte_mask;
+       cmdline_fixed_string_t tunnel_id;
+       uint32_t tunnel_id_mask;
+       cmdline_fixed_string_t tunnel_type;
+       uint8_t tunnel_type_mask;
+};
+
+static void
+cmd_flow_director_mask_parsed(void *parsed_result,
+                         __attribute__((unused)) struct cmdline *cl,
+                         __attribute__((unused)) void *data)
+{
+       struct cmd_flow_director_mask_result *res = parsed_result;
+       struct rte_eth_fdir_masks *mask;
+       struct rte_port *port;
+
+       if (res->port_id > nb_ports) {
+               printf("Invalid port, range is [0, %d]\n", nb_ports - 1);
+               return;
+       }
+
+       port = &ports[res->port_id];
+       /** Check if the port is not started **/
+       if (port->port_status != RTE_PORT_STOPPED) {
+               printf("Please stop port %d first\n", res->port_id);
+               return;
+       }
+
+       mask = &port->dev_conf.fdir_conf.mask;
+
+       if (fdir_conf.mode ==  RTE_FDIR_MODE_PERFECT_MAC_VLAN) {
+               if (strcmp(res->mode_value, "MAC-VLAN")) {
+                       printf("Please set mode to MAC-VLAN.\n");
+                       return;
+               }
+
+               mask->vlan_tci_mask = res->vlan_mask;
+               mask->mac_addr_byte_mask = res->mac_addr_byte_mask;
+       } else if (fdir_conf.mode ==  RTE_FDIR_MODE_PERFECT_TUNNEL) {
+               if (strcmp(res->mode_value, "Tunnel")) {
+                       printf("Please set mode to Tunnel.\n");
+                       return;
+               }
+
+               mask->vlan_tci_mask = res->vlan_mask;
+               mask->mac_addr_byte_mask = res->mac_addr_byte_mask;
+               mask->tunnel_id_mask = res->tunnel_id_mask;
+               mask->tunnel_type_mask = res->tunnel_type_mask;
+       } else {
+               if (strcmp(res->mode_value, "IP")) {
+                       printf("Please set mode to IP.\n");
+                       return;
+               }
+
+               mask->vlan_tci_mask = res->vlan_mask;
+               IPV4_ADDR_TO_UINT(res->ipv4_src, mask->ipv4_mask.src_ip);
+               IPV4_ADDR_TO_UINT(res->ipv4_dst, mask->ipv4_mask.dst_ip);
+               IPV6_ADDR_TO_ARRAY(res->ipv6_src, mask->ipv6_mask.src_ip);
+               IPV6_ADDR_TO_ARRAY(res->ipv6_dst, mask->ipv6_mask.dst_ip);
+               mask->src_port_mask = res->port_src;
+               mask->dst_port_mask = res->port_dst;
+       }
+
+       cmd_reconfig_device_queue(res->port_id, 1, 1);
+}
+
+cmdline_parse_token_string_t cmd_flow_director_mask =
+       TOKEN_STRING_INITIALIZER(struct cmd_flow_director_mask_result,
+                                flow_director_mask, "flow_director_mask");
+cmdline_parse_token_num_t cmd_flow_director_mask_port_id =
+       TOKEN_NUM_INITIALIZER(struct cmd_flow_director_mask_result,
+                             port_id, UINT8);
+cmdline_parse_token_string_t cmd_flow_director_mask_vlan =
+       TOKEN_STRING_INITIALIZER(struct cmd_flow_director_mask_result,
+                                vlan, "vlan");
+cmdline_parse_token_num_t cmd_flow_director_mask_vlan_value =
+       TOKEN_NUM_INITIALIZER(struct cmd_flow_director_mask_result,
+                             vlan_mask, UINT16);
+cmdline_parse_token_string_t cmd_flow_director_mask_src =
+       TOKEN_STRING_INITIALIZER(struct cmd_flow_director_mask_result,
+                                src_mask, "src_mask");
+cmdline_parse_token_ipaddr_t cmd_flow_director_mask_ipv4_src =
+       TOKEN_IPADDR_INITIALIZER(struct cmd_flow_director_mask_result,
+                                ipv4_src);
+cmdline_parse_token_ipaddr_t cmd_flow_director_mask_ipv6_src =
+       TOKEN_IPADDR_INITIALIZER(struct cmd_flow_director_mask_result,
+                                ipv6_src);
+cmdline_parse_token_num_t cmd_flow_director_mask_port_src =
+       TOKEN_NUM_INITIALIZER(struct cmd_flow_director_mask_result,
+                             port_src, UINT16);
+cmdline_parse_token_string_t cmd_flow_director_mask_dst =
+       TOKEN_STRING_INITIALIZER(struct cmd_flow_director_mask_result,
+                                dst_mask, "dst_mask");
+cmdline_parse_token_ipaddr_t cmd_flow_director_mask_ipv4_dst =
+       TOKEN_IPADDR_INITIALIZER(struct cmd_flow_director_mask_result,
+                                ipv4_dst);
+cmdline_parse_token_ipaddr_t cmd_flow_director_mask_ipv6_dst =
+       TOKEN_IPADDR_INITIALIZER(struct cmd_flow_director_mask_result,
+                                ipv6_dst);
+cmdline_parse_token_num_t cmd_flow_director_mask_port_dst =
+       TOKEN_NUM_INITIALIZER(struct cmd_flow_director_mask_result,
+                             port_dst, UINT16);
+
+cmdline_parse_token_string_t cmd_flow_director_mask_mode =
+       TOKEN_STRING_INITIALIZER(struct cmd_flow_director_mask_result,
+                                mode, "mode");
+cmdline_parse_token_string_t cmd_flow_director_mask_mode_ip =
+       TOKEN_STRING_INITIALIZER(struct cmd_flow_director_mask_result,
+                                mode_value, "IP");
+cmdline_parse_token_string_t cmd_flow_director_mask_mode_mac_vlan =
+       TOKEN_STRING_INITIALIZER(struct cmd_flow_director_mask_result,
+                                mode_value, "MAC-VLAN");
+cmdline_parse_token_string_t cmd_flow_director_mask_mode_tunnel =
+       TOKEN_STRING_INITIALIZER(struct cmd_flow_director_mask_result,
+                                mode_value, "Tunnel");
+cmdline_parse_token_string_t cmd_flow_director_mask_mac =
+       TOKEN_STRING_INITIALIZER(struct cmd_flow_director_mask_result,
+                                mac, "mac");
+cmdline_parse_token_num_t cmd_flow_director_mask_mac_value =
+       TOKEN_NUM_INITIALIZER(struct cmd_flow_director_mask_result,
+                             mac_addr_byte_mask, UINT8);
+cmdline_parse_token_string_t cmd_flow_director_mask_tunnel_type =
+       TOKEN_STRING_INITIALIZER(struct cmd_flow_director_mask_result,
+                                tunnel_type, "tunnel-type");
+cmdline_parse_token_num_t cmd_flow_director_mask_tunnel_type_value =
+       TOKEN_NUM_INITIALIZER(struct cmd_flow_director_mask_result,
+                             tunnel_type_mask, UINT8);
+cmdline_parse_token_string_t cmd_flow_director_mask_tunnel_id =
+       TOKEN_STRING_INITIALIZER(struct cmd_flow_director_mask_result,
+                                tunnel_id, "tunnel-id");
+cmdline_parse_token_num_t cmd_flow_director_mask_tunnel_id_value =
+       TOKEN_NUM_INITIALIZER(struct cmd_flow_director_mask_result,
+                             tunnel_id_mask, UINT32);
+
+cmdline_parse_inst_t cmd_set_flow_director_ip_mask = {
+       .f = cmd_flow_director_mask_parsed,
+       .data = NULL,
+       .help_str = "set IP mode flow director's mask on NIC",
+       .tokens = {
+               (void *)&cmd_flow_director_mask,
+               (void *)&cmd_flow_director_mask_port_id,
+               (void *)&cmd_flow_director_mask_mode,
+               (void *)&cmd_flow_director_mask_mode_ip,
+               (void *)&cmd_flow_director_mask_vlan,
+               (void *)&cmd_flow_director_mask_vlan_value,
+               (void *)&cmd_flow_director_mask_src,
+               (void *)&cmd_flow_director_mask_ipv4_src,
+               (void *)&cmd_flow_director_mask_ipv6_src,
+               (void *)&cmd_flow_director_mask_port_src,
+               (void *)&cmd_flow_director_mask_dst,
+               (void *)&cmd_flow_director_mask_ipv4_dst,
+               (void *)&cmd_flow_director_mask_ipv6_dst,
+               (void *)&cmd_flow_director_mask_port_dst,
+               NULL,
+       },
+};
+
+cmdline_parse_inst_t cmd_set_flow_director_mac_vlan_mask = {
+       .f = cmd_flow_director_mask_parsed,
+       .data = NULL,
+       .help_str = "set MAC VLAN mode flow director's mask on NIC",
+       .tokens = {
+               (void *)&cmd_flow_director_mask,
+               (void *)&cmd_flow_director_mask_port_id,
+               (void *)&cmd_flow_director_mask_mode,
+               (void *)&cmd_flow_director_mask_mode_mac_vlan,
+               (void *)&cmd_flow_director_mask_vlan,
+               (void *)&cmd_flow_director_mask_vlan_value,
+               (void *)&cmd_flow_director_mask_mac,
+               (void *)&cmd_flow_director_mask_mac_value,
+               NULL,
+       },
+};
+
+cmdline_parse_inst_t cmd_set_flow_director_tunnel_mask = {
+       .f = cmd_flow_director_mask_parsed,
+       .data = NULL,
+       .help_str = "set tunnel mode flow director's mask on NIC",
+       .tokens = {
+               (void *)&cmd_flow_director_mask,
+               (void *)&cmd_flow_director_mask_port_id,
+               (void *)&cmd_flow_director_mask_mode,
+               (void *)&cmd_flow_director_mask_mode_tunnel,
+               (void *)&cmd_flow_director_mask_vlan,
+               (void *)&cmd_flow_director_mask_vlan_value,
+               (void *)&cmd_flow_director_mask_mac,
+               (void *)&cmd_flow_director_mask_mac_value,
+               (void *)&cmd_flow_director_mask_tunnel_type,
+               (void *)&cmd_flow_director_mask_tunnel_type_value,
+               (void *)&cmd_flow_director_mask_tunnel_id,
+               (void *)&cmd_flow_director_mask_tunnel_id_value,
+               NULL,
+       },
+};
+
+/* *** deal with flow director mask on flexible payload *** */
+struct cmd_flow_director_flex_mask_result {
+       cmdline_fixed_string_t flow_director_flexmask;
+       uint8_t port_id;
+       cmdline_fixed_string_t flow;
+       cmdline_fixed_string_t flow_type;
+       cmdline_fixed_string_t mask;
+};
+
+static void
+cmd_flow_director_flex_mask_parsed(void *parsed_result,
+                         __attribute__((unused)) struct cmdline *cl,
+                         __attribute__((unused)) void *data)
+{
+       struct cmd_flow_director_flex_mask_result *res = parsed_result;
+       struct rte_eth_fdir_info fdir_info;
+       struct rte_eth_fdir_flex_mask flex_mask;
+       struct rte_port *port;
+       uint32_t flow_type_mask;
+       uint16_t i;
+       int ret;
+
+       if (res->port_id > nb_ports) {
+               printf("Invalid port, range is [0, %d]\n", nb_ports - 1);
+               return;
+       }
+
+       port = &ports[res->port_id];
+       /** Check if the port is not started **/
+       if (port->port_status != RTE_PORT_STOPPED) {
+               printf("Please stop port %d first\n", res->port_id);
+               return;
+       }
+
+       memset(&flex_mask, 0, sizeof(struct rte_eth_fdir_flex_mask));
+       ret = parse_flexbytes(res->mask,
+                       flex_mask.mask,
+                       RTE_ETH_FDIR_MAX_FLEXLEN);
+       if (ret < 0) {
+               printf("error: Cannot parse mask input.\n");
+               return;
+       }
+
+       memset(&fdir_info, 0, sizeof(fdir_info));
+       ret = rte_eth_dev_filter_ctrl(res->port_id, RTE_ETH_FILTER_FDIR,
+                               RTE_ETH_FILTER_INFO, &fdir_info);
+       if (ret < 0) {
+               printf("Cannot get FDir filter info\n");
+               return;
+       }
+
+       if (!strcmp(res->flow_type, "none")) {
+               /* means don't specify the flow type */
+               flex_mask.flow_type = RTE_ETH_FLOW_UNKNOWN;
+               for (i = 0; i < RTE_ETH_FLOW_MAX; i++)
+                       memset(&port->dev_conf.fdir_conf.flex_conf.flex_mask[i],
+                              0, sizeof(struct rte_eth_fdir_flex_mask));
+               port->dev_conf.fdir_conf.flex_conf.nb_flexmasks = 1;
+               (void)rte_memcpy(&port->dev_conf.fdir_conf.flex_conf.flex_mask[0],
+                                &flex_mask,
+                                sizeof(struct rte_eth_fdir_flex_mask));
+               cmd_reconfig_device_queue(res->port_id, 1, 1);
+               return;
+       }
+       flow_type_mask = fdir_info.flow_types_mask[0];
+       if (!strcmp(res->flow_type, "all")) {
+               if (!flow_type_mask) {
+                       printf("No flow type supported\n");
+                       return;
+               }
+               for (i = RTE_ETH_FLOW_UNKNOWN; i < RTE_ETH_FLOW_MAX; i++) {
+                       if (flow_type_mask & (1 << i)) {
+                               flex_mask.flow_type = i;
+                               fdir_set_flex_mask(res->port_id, &flex_mask);
+                       }
+               }
+               cmd_reconfig_device_queue(res->port_id, 1, 1);
+               return;
+       }
+       flex_mask.flow_type = str2flowtype(res->flow_type);
+       if (!(flow_type_mask & (1 << flex_mask.flow_type))) {
+               printf("Flow type %s not supported on port %d\n",
+                               res->flow_type, res->port_id);
+               return;
+       }
+       fdir_set_flex_mask(res->port_id, &flex_mask);
+       cmd_reconfig_device_queue(res->port_id, 1, 1);
+}
+
+cmdline_parse_token_string_t cmd_flow_director_flexmask =
+       TOKEN_STRING_INITIALIZER(struct cmd_flow_director_flex_mask_result,
+                                flow_director_flexmask,
+                                "flow_director_flex_mask");
+cmdline_parse_token_num_t cmd_flow_director_flexmask_port_id =
+       TOKEN_NUM_INITIALIZER(struct cmd_flow_director_flex_mask_result,
+                             port_id, UINT8);
+cmdline_parse_token_string_t cmd_flow_director_flexmask_flow =
+       TOKEN_STRING_INITIALIZER(struct cmd_flow_director_flex_mask_result,
+                                flow, "flow");
+cmdline_parse_token_string_t cmd_flow_director_flexmask_flow_type =
+       TOKEN_STRING_INITIALIZER(struct cmd_flow_director_flex_mask_result,
+               flow_type, "none#ipv4-other#ipv4-frag#ipv4-tcp#ipv4-udp#ipv4-sctp#"
+               "ipv6-other#ipv6-frag#ipv6-tcp#ipv6-udp#ipv6-sctp#l2_payload#all");
+cmdline_parse_token_string_t cmd_flow_director_flexmask_mask =
+       TOKEN_STRING_INITIALIZER(struct cmd_flow_director_flex_mask_result,
+                                mask, NULL);
+
+cmdline_parse_inst_t cmd_set_flow_director_flex_mask = {
+       .f = cmd_flow_director_flex_mask_parsed,
+       .data = NULL,
+       .help_str = "set flow director's flex mask on NIC",
+       .tokens = {
+               (void *)&cmd_flow_director_flexmask,
+               (void *)&cmd_flow_director_flexmask_port_id,
+               (void *)&cmd_flow_director_flexmask_flow,
+               (void *)&cmd_flow_director_flexmask_flow_type,
+               (void *)&cmd_flow_director_flexmask_mask,
+               NULL,
+       },
+};
+
+/* *** deal with flow director flexible payload configuration *** */
+struct cmd_flow_director_flexpayload_result {
+       cmdline_fixed_string_t flow_director_flexpayload;
+       uint8_t port_id;
+       cmdline_fixed_string_t payload_layer;
+       cmdline_fixed_string_t payload_cfg;
+};
+
+static inline int
+parse_offsets(const char *q_arg, uint16_t *offsets, uint16_t max_num)
+{
+       char s[256];
+       const char *p, *p0 = q_arg;
+       char *end;
+       unsigned long int_fld;
+       char *str_fld[max_num];
+       int i;
+       unsigned size;
+       int ret = -1;
+
+       p = strchr(p0, '(');
+       if (p == NULL)
+               return -1;
+       ++p;
+       p0 = strchr(p, ')');
+       if (p0 == NULL)
+               return -1;
+
+       size = p0 - p;
+       if (size >= sizeof(s))
+               return -1;
+
+       snprintf(s, sizeof(s), "%.*s", size, p);
+       ret = rte_strsplit(s, sizeof(s), str_fld, max_num, ',');
+       if (ret < 0 || ret > max_num)
+               return -1;
+       for (i = 0; i < ret; i++) {
+               errno = 0;
+               int_fld = strtoul(str_fld[i], &end, 0);
+               if (errno != 0 || *end != '\0' || int_fld > UINT16_MAX)
+                       return -1;
+               offsets[i] = (uint16_t)int_fld;
+       }
+       return ret;
+}
+
+static void
+cmd_flow_director_flxpld_parsed(void *parsed_result,
+                         __attribute__((unused)) struct cmdline *cl,
+                         __attribute__((unused)) void *data)
+{
+       struct cmd_flow_director_flexpayload_result *res = parsed_result;
+       struct rte_eth_flex_payload_cfg flex_cfg;
+       struct rte_port *port;
+       int ret = 0;
+
+       if (res->port_id > nb_ports) {
+               printf("Invalid port, range is [0, %d]\n", nb_ports - 1);
+               return;
+       }
+
+       port = &ports[res->port_id];
+       /** Check if the port is not started **/
+       if (port->port_status != RTE_PORT_STOPPED) {
+               printf("Please stop port %d first\n", res->port_id);
+               return;
+       }
+
+       memset(&flex_cfg, 0, sizeof(struct rte_eth_flex_payload_cfg));
+
+       if (!strcmp(res->payload_layer, "raw"))
+               flex_cfg.type = RTE_ETH_RAW_PAYLOAD;
+       else if (!strcmp(res->payload_layer, "l2"))
+               flex_cfg.type = RTE_ETH_L2_PAYLOAD;
+       else if (!strcmp(res->payload_layer, "l3"))
+               flex_cfg.type = RTE_ETH_L3_PAYLOAD;
+       else if (!strcmp(res->payload_layer, "l4"))
+               flex_cfg.type = RTE_ETH_L4_PAYLOAD;
+
+       ret = parse_offsets(res->payload_cfg, flex_cfg.src_offset,
+                           RTE_ETH_FDIR_MAX_FLEXLEN);
+       if (ret < 0) {
+               printf("error: Cannot parse flex payload input.\n");
+               return;
+       }
+
+       fdir_set_flex_payload(res->port_id, &flex_cfg);
+       cmd_reconfig_device_queue(res->port_id, 1, 1);
+}
+
+cmdline_parse_token_string_t cmd_flow_director_flexpayload =
+       TOKEN_STRING_INITIALIZER(struct cmd_flow_director_flexpayload_result,
+                                flow_director_flexpayload,
+                                "flow_director_flex_payload");
+cmdline_parse_token_num_t cmd_flow_director_flexpayload_port_id =
+       TOKEN_NUM_INITIALIZER(struct cmd_flow_director_flexpayload_result,
+                             port_id, UINT8);
+cmdline_parse_token_string_t cmd_flow_director_flexpayload_payload_layer =
+       TOKEN_STRING_INITIALIZER(struct cmd_flow_director_flexpayload_result,
+                                payload_layer, "raw#l2#l3#l4");
+cmdline_parse_token_string_t cmd_flow_director_flexpayload_payload_cfg =
+       TOKEN_STRING_INITIALIZER(struct cmd_flow_director_flexpayload_result,
+                                payload_cfg, NULL);
+
+cmdline_parse_inst_t cmd_set_flow_director_flex_payload = {
+       .f = cmd_flow_director_flxpld_parsed,
+       .data = NULL,
+       .help_str = "set flow director's flex payload on NIC",
+       .tokens = {
+               (void *)&cmd_flow_director_flexpayload,
+               (void *)&cmd_flow_director_flexpayload_port_id,
+               (void *)&cmd_flow_director_flexpayload_payload_layer,
+               (void *)&cmd_flow_director_flexpayload_payload_cfg,
+               NULL,
+       },
+};
+
+/* *** Classification Filters Control *** */
+/* *** Get symmetric hash enable per port *** */
+struct cmd_get_sym_hash_ena_per_port_result {
+       cmdline_fixed_string_t get_sym_hash_ena_per_port;
+       uint8_t port_id;
+};
+
+static void
+cmd_get_sym_hash_per_port_parsed(void *parsed_result,
+                                __rte_unused struct cmdline *cl,
+                                __rte_unused void *data)
+{
+       struct cmd_get_sym_hash_ena_per_port_result *res = parsed_result;
+       struct rte_eth_hash_filter_info info;
+       int ret;
+
+       if (rte_eth_dev_filter_supported(res->port_id,
+                               RTE_ETH_FILTER_HASH) < 0) {
+               printf("RTE_ETH_FILTER_HASH not supported on port: %d\n",
+                                                       res->port_id);
+               return;
+       }
+
+       memset(&info, 0, sizeof(info));
+       info.info_type = RTE_ETH_HASH_FILTER_SYM_HASH_ENA_PER_PORT;
+       ret = rte_eth_dev_filter_ctrl(res->port_id, RTE_ETH_FILTER_HASH,
+                                               RTE_ETH_FILTER_GET, &info);
+
+       if (ret < 0) {
+               printf("Cannot get symmetric hash enable per port "
+                                       "on port %u\n", res->port_id);
+               return;
+       }
+
+       printf("Symmetric hash is %s on port %u\n", info.info.enable ?
+                               "enabled" : "disabled", res->port_id);
+}
+
+cmdline_parse_token_string_t cmd_get_sym_hash_ena_per_port_all =
+       TOKEN_STRING_INITIALIZER(struct cmd_get_sym_hash_ena_per_port_result,
+               get_sym_hash_ena_per_port, "get_sym_hash_ena_per_port");
+cmdline_parse_token_num_t cmd_get_sym_hash_ena_per_port_port_id =
+       TOKEN_NUM_INITIALIZER(struct cmd_get_sym_hash_ena_per_port_result,
+               port_id, UINT8);
+
+cmdline_parse_inst_t cmd_get_sym_hash_ena_per_port = {
+       .f = cmd_get_sym_hash_per_port_parsed,
+       .data = NULL,
+       .help_str = "get_sym_hash_ena_per_port port_id",
+       .tokens = {
+               (void *)&cmd_get_sym_hash_ena_per_port_all,
+               (void *)&cmd_get_sym_hash_ena_per_port_port_id,
+               NULL,
+       },
+};
+
+/* *** Set symmetric hash enable per port *** */
+struct cmd_set_sym_hash_ena_per_port_result {
+       cmdline_fixed_string_t set_sym_hash_ena_per_port;
+       cmdline_fixed_string_t enable;
+       uint8_t port_id;
+};
+
+static void
+cmd_set_sym_hash_per_port_parsed(void *parsed_result,
+                                __rte_unused struct cmdline *cl,
+                                __rte_unused void *data)
+{
+       struct cmd_set_sym_hash_ena_per_port_result *res = parsed_result;
+       struct rte_eth_hash_filter_info info;
+       int ret;
+
+       if (rte_eth_dev_filter_supported(res->port_id,
+                               RTE_ETH_FILTER_HASH) < 0) {
+               printf("RTE_ETH_FILTER_HASH not supported on port: %d\n",
+                                                       res->port_id);
+               return;
+       }
+
+       memset(&info, 0, sizeof(info));
+       info.info_type = RTE_ETH_HASH_FILTER_SYM_HASH_ENA_PER_PORT;
+       if (!strcmp(res->enable, "enable"))
+               info.info.enable = 1;
+       ret = rte_eth_dev_filter_ctrl(res->port_id, RTE_ETH_FILTER_HASH,
+                                       RTE_ETH_FILTER_SET, &info);
+       if (ret < 0) {
+               printf("Cannot set symmetric hash enable per port on "
+                                       "port %u\n", res->port_id);
+               return;
+       }
+       printf("Symmetric hash has been set to %s on port %u\n",
+                                       res->enable, res->port_id);
+}
+
+cmdline_parse_token_string_t cmd_set_sym_hash_ena_per_port_all =
+       TOKEN_STRING_INITIALIZER(struct cmd_set_sym_hash_ena_per_port_result,
+               set_sym_hash_ena_per_port, "set_sym_hash_ena_per_port");
+cmdline_parse_token_num_t cmd_set_sym_hash_ena_per_port_port_id =
+       TOKEN_NUM_INITIALIZER(struct cmd_set_sym_hash_ena_per_port_result,
+               port_id, UINT8);
+cmdline_parse_token_string_t cmd_set_sym_hash_ena_per_port_enable =
+       TOKEN_STRING_INITIALIZER(struct cmd_set_sym_hash_ena_per_port_result,
+               enable, "enable#disable");
+
+cmdline_parse_inst_t cmd_set_sym_hash_ena_per_port = {
+       .f = cmd_set_sym_hash_per_port_parsed,
+       .data = NULL,
+       .help_str = "set_sym_hash_ena_per_port port_id enable|disable",
+       .tokens = {
+               (void *)&cmd_set_sym_hash_ena_per_port_all,
+               (void *)&cmd_set_sym_hash_ena_per_port_port_id,
+               (void *)&cmd_set_sym_hash_ena_per_port_enable,
+               NULL,
+       },
+};
+
+/* Get global config of hash function */
+struct cmd_get_hash_global_config_result {
+       cmdline_fixed_string_t get_hash_global_config;
+       uint8_t port_id;
+};
+
+static char *
+flowtype_to_str(uint16_t ftype)
+{
+       uint16_t i;
+       static struct {
+               char str[16];
+               uint16_t ftype;
+       } ftype_table[] = {
+               {"ipv4", RTE_ETH_FLOW_IPV4},
+               {"ipv4-frag", RTE_ETH_FLOW_FRAG_IPV4},
+               {"ipv4-tcp", RTE_ETH_FLOW_NONFRAG_IPV4_TCP},
+               {"ipv4-udp", RTE_ETH_FLOW_NONFRAG_IPV4_UDP},
+               {"ipv4-sctp", RTE_ETH_FLOW_NONFRAG_IPV4_SCTP},
+               {"ipv4-other", RTE_ETH_FLOW_NONFRAG_IPV4_OTHER},
+               {"ipv6", RTE_ETH_FLOW_IPV6},
+               {"ipv6-frag", RTE_ETH_FLOW_FRAG_IPV6},
+               {"ipv6-tcp", RTE_ETH_FLOW_NONFRAG_IPV6_TCP},
+               {"ipv6-udp", RTE_ETH_FLOW_NONFRAG_IPV6_UDP},
+               {"ipv6-sctp", RTE_ETH_FLOW_NONFRAG_IPV6_SCTP},
+               {"ipv6-other", RTE_ETH_FLOW_NONFRAG_IPV6_OTHER},
+               {"l2_payload", RTE_ETH_FLOW_L2_PAYLOAD},
+       };
+
+       for (i = 0; i < RTE_DIM(ftype_table); i++) {
+               if (ftype_table[i].ftype == ftype)
+                       return ftype_table[i].str;
+       }
+
+       return NULL;
+}
+
+static void
+cmd_get_hash_global_config_parsed(void *parsed_result,
+                                 __rte_unused struct cmdline *cl,
+                                 __rte_unused void *data)
+{
+       struct cmd_get_hash_global_config_result *res = parsed_result;
+       struct rte_eth_hash_filter_info info;
+       uint32_t idx, offset;
+       uint16_t i;
+       char *str;
+       int ret;
+
+       if (rte_eth_dev_filter_supported(res->port_id,
+                       RTE_ETH_FILTER_HASH) < 0) {
+               printf("RTE_ETH_FILTER_HASH not supported on port %d\n",
+                                                       res->port_id);
+               return;
+       }
+
+       memset(&info, 0, sizeof(info));
+       info.info_type = RTE_ETH_HASH_FILTER_GLOBAL_CONFIG;
+       ret = rte_eth_dev_filter_ctrl(res->port_id, RTE_ETH_FILTER_HASH,
+                                       RTE_ETH_FILTER_GET, &info);
+       if (ret < 0) {
+               printf("Cannot get hash global configurations by port %d\n",
+                                                       res->port_id);
+               return;
+       }
+
+       switch (info.info.global_conf.hash_func) {
+       case RTE_ETH_HASH_FUNCTION_TOEPLITZ:
+               printf("Hash function is Toeplitz\n");
+               break;
+       case RTE_ETH_HASH_FUNCTION_SIMPLE_XOR:
+               printf("Hash function is Simple XOR\n");
+               break;
+       default:
+               printf("Unknown hash function\n");
+               break;
+       }
+
+       for (i = 0; i < RTE_ETH_FLOW_MAX; i++) {
+               idx = i / UINT32_BIT;
+               offset = i % UINT32_BIT;
+               if (!(info.info.global_conf.valid_bit_mask[idx] &
+                                               (1UL << offset)))
+                       continue;
+               str = flowtype_to_str(i);
+               if (!str)
+                       continue;
+               printf("Symmetric hash is %s globally for flow type %s "
+                                                       "by port %d\n",
+                       ((info.info.global_conf.sym_hash_enable_mask[idx] &
+                       (1UL << offset)) ? "enabled" : "disabled"), str,
+                                                       res->port_id);
+       }
+}
+
+cmdline_parse_token_string_t cmd_get_hash_global_config_all =
+       TOKEN_STRING_INITIALIZER(struct cmd_get_hash_global_config_result,
+               get_hash_global_config, "get_hash_global_config");
+cmdline_parse_token_num_t cmd_get_hash_global_config_port_id =
+       TOKEN_NUM_INITIALIZER(struct cmd_get_hash_global_config_result,
+               port_id, UINT8);
+
+cmdline_parse_inst_t cmd_get_hash_global_config = {
+       .f = cmd_get_hash_global_config_parsed,
+       .data = NULL,
+       .help_str = "get_hash_global_config port_id",
+       .tokens = {
+               (void *)&cmd_get_hash_global_config_all,
+               (void *)&cmd_get_hash_global_config_port_id,
+               NULL,
+       },
+};
+
+/* Set global config of hash function */
+struct cmd_set_hash_global_config_result {
+       cmdline_fixed_string_t set_hash_global_config;
+       uint8_t port_id;
+       cmdline_fixed_string_t hash_func;
+       cmdline_fixed_string_t flow_type;
+       cmdline_fixed_string_t enable;
+};
+
+static void
+cmd_set_hash_global_config_parsed(void *parsed_result,
+                                 __rte_unused struct cmdline *cl,
+                                 __rte_unused void *data)
+{
+       struct cmd_set_hash_global_config_result *res = parsed_result;
+       struct rte_eth_hash_filter_info info;
+       uint32_t ftype, idx, offset;
+       int ret;
+
+       if (rte_eth_dev_filter_supported(res->port_id,
+                               RTE_ETH_FILTER_HASH) < 0) {
+               printf("RTE_ETH_FILTER_HASH not supported on port %d\n",
+                                                       res->port_id);
+               return;
+       }
+       memset(&info, 0, sizeof(info));
+       info.info_type = RTE_ETH_HASH_FILTER_GLOBAL_CONFIG;
+       if (!strcmp(res->hash_func, "toeplitz"))
+               info.info.global_conf.hash_func =
+                       RTE_ETH_HASH_FUNCTION_TOEPLITZ;
+       else if (!strcmp(res->hash_func, "simple_xor"))
+               info.info.global_conf.hash_func =
+                       RTE_ETH_HASH_FUNCTION_SIMPLE_XOR;
+       else if (!strcmp(res->hash_func, "default"))
+               info.info.global_conf.hash_func =
+                       RTE_ETH_HASH_FUNCTION_DEFAULT;
+
+       ftype = str2flowtype(res->flow_type);
+       idx = ftype / (CHAR_BIT * sizeof(uint32_t));
+       offset = ftype % (CHAR_BIT * sizeof(uint32_t));
+       info.info.global_conf.valid_bit_mask[idx] |= (1UL << offset);
+       if (!strcmp(res->enable, "enable"))
+               info.info.global_conf.sym_hash_enable_mask[idx] |=
+                                               (1UL << offset);
+       ret = rte_eth_dev_filter_ctrl(res->port_id, RTE_ETH_FILTER_HASH,
+                                       RTE_ETH_FILTER_SET, &info);
+       if (ret < 0)
+               printf("Cannot set global hash configurations by port %d\n",
+                                                       res->port_id);
+       else
+               printf("Global hash configurations have been set "
+                       "succcessfully by port %d\n", res->port_id);
+}
+
+cmdline_parse_token_string_t cmd_set_hash_global_config_all =
+       TOKEN_STRING_INITIALIZER(struct cmd_set_hash_global_config_result,
+               set_hash_global_config, "set_hash_global_config");
+cmdline_parse_token_num_t cmd_set_hash_global_config_port_id =
+       TOKEN_NUM_INITIALIZER(struct cmd_set_hash_global_config_result,
+               port_id, UINT8);
+cmdline_parse_token_string_t cmd_set_hash_global_config_hash_func =
+       TOKEN_STRING_INITIALIZER(struct cmd_set_hash_global_config_result,
+               hash_func, "toeplitz#simple_xor#default");
+cmdline_parse_token_string_t cmd_set_hash_global_config_flow_type =
+       TOKEN_STRING_INITIALIZER(struct cmd_set_hash_global_config_result,
+               flow_type,
+               "ipv4#ipv4-frag#ipv4-tcp#ipv4-udp#ipv4-sctp#ipv4-other#ipv6#"
+               "ipv6-frag#ipv6-tcp#ipv6-udp#ipv6-sctp#ipv6-other#l2_payload");
+cmdline_parse_token_string_t cmd_set_hash_global_config_enable =
+       TOKEN_STRING_INITIALIZER(struct cmd_set_hash_global_config_result,
+               enable, "enable#disable");
+
+cmdline_parse_inst_t cmd_set_hash_global_config = {
+       .f = cmd_set_hash_global_config_parsed,
+       .data = NULL,
+       .help_str = "set_hash_global_config port_id "
+               "toeplitz|simple_xor|default "
+               "ipv4|ipv4-frag|ipv4-tcp|ipv4-udp|ipv4-sctp|ipv4-other|ipv6|"
+               "ipv6-frag|ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other|l2_payload "
+               "enable|disable",
+       .tokens = {
+               (void *)&cmd_set_hash_global_config_all,
+               (void *)&cmd_set_hash_global_config_port_id,
+               (void *)&cmd_set_hash_global_config_hash_func,
+               (void *)&cmd_set_hash_global_config_flow_type,
+               (void *)&cmd_set_hash_global_config_enable,
+               NULL,
+       },
+};
+
+/* Set hash input set */
+struct cmd_set_hash_input_set_result {
+       cmdline_fixed_string_t set_hash_input_set;
+       uint8_t port_id;
+       cmdline_fixed_string_t flow_type;
+       cmdline_fixed_string_t inset_field;
+       cmdline_fixed_string_t select;
+};
+
+static enum rte_eth_input_set_field
+str2inset(char *string)
+{
+       uint16_t i;
+
+       static const struct {
+               char str[32];
+               enum rte_eth_input_set_field inset;
+       } inset_table[] = {
+               {"ovlan", RTE_ETH_INPUT_SET_L2_OUTER_VLAN},
+               {"ivlan", RTE_ETH_INPUT_SET_L2_INNER_VLAN},
+               {"src-ipv4", RTE_ETH_INPUT_SET_L3_SRC_IP4},
+               {"dst-ipv4", RTE_ETH_INPUT_SET_L3_DST_IP4},
+               {"ipv4-tos", RTE_ETH_INPUT_SET_L3_IP4_TOS},
+               {"ipv4-proto", RTE_ETH_INPUT_SET_L3_IP4_PROTO},
+               {"src-ipv6", RTE_ETH_INPUT_SET_L3_SRC_IP6},
+               {"dst-ipv6", RTE_ETH_INPUT_SET_L3_DST_IP6},
+               {"ipv6-tc", RTE_ETH_INPUT_SET_L3_IP6_TC},
+               {"ipv6-next-header", RTE_ETH_INPUT_SET_L3_IP6_NEXT_HEADER},
+               {"udp-src-port", RTE_ETH_INPUT_SET_L4_UDP_SRC_PORT},
+               {"udp-dst-port", RTE_ETH_INPUT_SET_L4_UDP_DST_PORT},
+               {"tcp-src-port", RTE_ETH_INPUT_SET_L4_TCP_SRC_PORT},
+               {"tcp-dst-port", RTE_ETH_INPUT_SET_L4_TCP_DST_PORT},
+               {"sctp-src-port", RTE_ETH_INPUT_SET_L4_SCTP_SRC_PORT},
+               {"sctp-dst-port", RTE_ETH_INPUT_SET_L4_SCTP_DST_PORT},
+               {"sctp-veri-tag", RTE_ETH_INPUT_SET_L4_SCTP_VERIFICATION_TAG},
+               {"udp-key", RTE_ETH_INPUT_SET_TUNNEL_L4_UDP_KEY},
+               {"gre-key", RTE_ETH_INPUT_SET_TUNNEL_GRE_KEY},
+               {"fld-1st", RTE_ETH_INPUT_SET_FLEX_PAYLOAD_1ST_WORD},
+               {"fld-2nd", RTE_ETH_INPUT_SET_FLEX_PAYLOAD_2ND_WORD},
+               {"fld-3rd", RTE_ETH_INPUT_SET_FLEX_PAYLOAD_3RD_WORD},
+               {"fld-4th", RTE_ETH_INPUT_SET_FLEX_PAYLOAD_4TH_WORD},
+               {"fld-5th", RTE_ETH_INPUT_SET_FLEX_PAYLOAD_5TH_WORD},
+               {"fld-6th", RTE_ETH_INPUT_SET_FLEX_PAYLOAD_6TH_WORD},
+               {"fld-7th", RTE_ETH_INPUT_SET_FLEX_PAYLOAD_7TH_WORD},
+               {"fld-8th", RTE_ETH_INPUT_SET_FLEX_PAYLOAD_8TH_WORD},
+               {"none", RTE_ETH_INPUT_SET_NONE},
+       };
+
+       for (i = 0; i < RTE_DIM(inset_table); i++) {
+               if (!strcmp(string, inset_table[i].str))
+                       return inset_table[i].inset;
+       }
+
+       return RTE_ETH_INPUT_SET_UNKNOWN;
+}
+
+static void
+cmd_set_hash_input_set_parsed(void *parsed_result,
+                             __rte_unused struct cmdline *cl,
+                             __rte_unused void *data)
+{
+       struct cmd_set_hash_input_set_result *res = parsed_result;
+       struct rte_eth_hash_filter_info info;
+
+       memset(&info, 0, sizeof(info));
+       info.info_type = RTE_ETH_HASH_FILTER_INPUT_SET_SELECT;
+       info.info.input_set_conf.flow_type = str2flowtype(res->flow_type);
+       info.info.input_set_conf.field[0] = str2inset(res->inset_field);
+       info.info.input_set_conf.inset_size = 1;
+       if (!strcmp(res->select, "select"))
+               info.info.input_set_conf.op = RTE_ETH_INPUT_SET_SELECT;
+       else if (!strcmp(res->select, "add"))
+               info.info.input_set_conf.op = RTE_ETH_INPUT_SET_ADD;
+       rte_eth_dev_filter_ctrl(res->port_id, RTE_ETH_FILTER_HASH,
+                               RTE_ETH_FILTER_SET, &info);
+}
+
+cmdline_parse_token_string_t cmd_set_hash_input_set_cmd =
+       TOKEN_STRING_INITIALIZER(struct cmd_set_hash_input_set_result,
+               set_hash_input_set, "set_hash_input_set");
+cmdline_parse_token_num_t cmd_set_hash_input_set_port_id =
+       TOKEN_NUM_INITIALIZER(struct cmd_set_hash_input_set_result,
+               port_id, UINT8);
+cmdline_parse_token_string_t cmd_set_hash_input_set_flow_type =
+       TOKEN_STRING_INITIALIZER(struct cmd_set_hash_input_set_result,
+               flow_type,
+               "ipv4#ipv4-frag#ipv4-tcp#ipv4-udp#ipv4-sctp#ipv4-other#ipv6#"
+               "ipv6-frag#ipv6-tcp#ipv6-udp#ipv6-sctp#ipv6-other#l2_payload");
+cmdline_parse_token_string_t cmd_set_hash_input_set_field =
+       TOKEN_STRING_INITIALIZER(struct cmd_set_hash_input_set_result,
+               inset_field,
+               "ovlan#ivlan#src-ipv4#dst-ipv4#src-ipv6#dst-ipv6#"
+               "ipv4-tos#ipv4-proto#ipv6-tc#ipv6-next-header#udp-src-port#"
+               "udp-dst-port#tcp-src-port#tcp-dst-port#sctp-src-port#"
+               "sctp-dst-port#sctp-veri-tag#udp-key#gre-key#fld-1st#"
+               "fld-2nd#fld-3rd#fld-4th#fld-5th#fld-6th#fld-7th#"
+               "fld-8th#none");
+cmdline_parse_token_string_t cmd_set_hash_input_set_select =
+       TOKEN_STRING_INITIALIZER(struct cmd_set_hash_input_set_result,
+               select, "select#add");
+
+cmdline_parse_inst_t cmd_set_hash_input_set = {
+       .f = cmd_set_hash_input_set_parsed,
+       .data = NULL,
+       .help_str = "set_hash_input_set <port_id> "
+       "ipv4|ipv4-frag|ipv4-tcp|ipv4-udp|ipv4-sctp|ipv4-other|ipv6|ipv6-frag|"
+       "ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other|l2_payload "
+       "ovlan|ivlan|src-ipv4|dst-ipv4|src-ipv6|dst-ipv6|ipv4-tos|ipv4-proto|"
+       "ipv6-tc|ipv6-next-header|udp-src-port|udp-dst-port|tcp-src-port|"
+       "tcp-dst-port|sctp-src-port|sctp-dst-port|sctp-veri-tag|udp-key|"
+       "gre-key|fld-1st|fld-2nd|fld-3rd|fld-4th|fld-5th|fld-6th|"
+       "fld-7th|fld-8th|none select|add",
+       .tokens = {
+               (void *)&cmd_set_hash_input_set_cmd,
+               (void *)&cmd_set_hash_input_set_port_id,
+               (void *)&cmd_set_hash_input_set_flow_type,
+               (void *)&cmd_set_hash_input_set_field,
+               (void *)&cmd_set_hash_input_set_select,
+               NULL,
+       },
+};
+
+/* Set flow director input set */
+struct cmd_set_fdir_input_set_result {
+       cmdline_fixed_string_t set_fdir_input_set;
+       uint8_t port_id;
+       cmdline_fixed_string_t flow_type;
+       cmdline_fixed_string_t inset_field;
+       cmdline_fixed_string_t select;
+};
+
+static void
+cmd_set_fdir_input_set_parsed(void *parsed_result,
+       __rte_unused struct cmdline *cl,
+       __rte_unused void *data)
+{
+       struct cmd_set_fdir_input_set_result *res = parsed_result;
+       struct rte_eth_fdir_filter_info info;
+
+       memset(&info, 0, sizeof(info));
+       info.info_type = RTE_ETH_FDIR_FILTER_INPUT_SET_SELECT;
+       info.info.input_set_conf.flow_type = str2flowtype(res->flow_type);
+       info.info.input_set_conf.field[0] = str2inset(res->inset_field);
+       info.info.input_set_conf.inset_size = 1;
+       if (!strcmp(res->select, "select"))
+               info.info.input_set_conf.op = RTE_ETH_INPUT_SET_SELECT;
+       else if (!strcmp(res->select, "add"))
+               info.info.input_set_conf.op = RTE_ETH_INPUT_SET_ADD;
+       rte_eth_dev_filter_ctrl(res->port_id, RTE_ETH_FILTER_FDIR,
+               RTE_ETH_FILTER_SET, &info);
+}
+
+cmdline_parse_token_string_t cmd_set_fdir_input_set_cmd =
+       TOKEN_STRING_INITIALIZER(struct cmd_set_fdir_input_set_result,
+       set_fdir_input_set, "set_fdir_input_set");
+cmdline_parse_token_num_t cmd_set_fdir_input_set_port_id =
+       TOKEN_NUM_INITIALIZER(struct cmd_set_fdir_input_set_result,
+       port_id, UINT8);
+cmdline_parse_token_string_t cmd_set_fdir_input_set_flow_type =
+       TOKEN_STRING_INITIALIZER(struct cmd_set_fdir_input_set_result,
+       flow_type,
+       "ipv4#ipv4-frag#ipv4-tcp#ipv4-udp#ipv4-sctp#ipv4-other#ipv6#"
+       "ipv6-frag#ipv6-tcp#ipv6-udp#ipv6-sctp#ipv6-other#l2_payload");
+cmdline_parse_token_string_t cmd_set_fdir_input_set_field =
+       TOKEN_STRING_INITIALIZER(struct cmd_set_fdir_input_set_result,
+       inset_field,
+       "src-ipv4#dst-ipv4#src-ipv6#dst-ipv6#udp-src-port#udp-dst-port#"
+       "tcp-src-port#tcp-dst-port#sctp-src-port#sctp-dst-port#"
+       "sctp-veri-tag#fld-1st#fld-2nd#fld-3rd#fld-4th#fld-5th#fld-6th#"
+       "fld-7th#fld-8th#none");
+cmdline_parse_token_string_t cmd_set_fdir_input_set_select =
+       TOKEN_STRING_INITIALIZER(struct cmd_set_fdir_input_set_result,
+       select, "select#add");
+
+cmdline_parse_inst_t cmd_set_fdir_input_set = {
+       .f = cmd_set_fdir_input_set_parsed,
+       .data = NULL,
+       .help_str = "set_fdir_input_set <port_id> "
+       "ipv4|ipv4-frag|ipv4-tcp|ipv4-udp|ipv4-sctp|ipv4-other|ipv6|ipv6-frag|"
+       "ipv6-tcp|ipv6-udp|ipv6-sctp|ipv6-other|l2_payload "
+       "src-ipv4|dst-ipv4|src-ipv6|dst-ipv6|udp-src-port|udp-dst-port|"
+       "tcp-src-port|tcp-dst-port|sctp-src-port|sctp-dst-port|sctp-veri-tag|"
+       "fld-1st|fld-2nd|fld-3rd|fld-4th|fld-5th|fld-6th|"
+       "fld-7th|fld-8th|none select|add",
+       .tokens = {
+               (void *)&cmd_set_fdir_input_set_cmd,
+               (void *)&cmd_set_fdir_input_set_port_id,
+               (void *)&cmd_set_fdir_input_set_flow_type,
+               (void *)&cmd_set_fdir_input_set_field,
+               (void *)&cmd_set_fdir_input_set_select,
+               NULL,
+       },
+};
+
+/* *** ADD/REMOVE A MULTICAST MAC ADDRESS TO/FROM A PORT *** */
+struct cmd_mcast_addr_result {
+       cmdline_fixed_string_t mcast_addr_cmd;
+       cmdline_fixed_string_t what;
+       uint8_t port_num;
+       struct ether_addr mc_addr;
+};
+
+static void cmd_mcast_addr_parsed(void *parsed_result,
+               __attribute__((unused)) struct cmdline *cl,
+               __attribute__((unused)) void *data)
+{
+       struct cmd_mcast_addr_result *res = parsed_result;
+
+       if (!is_multicast_ether_addr(&res->mc_addr)) {
+               printf("Invalid multicast addr %02X:%02X:%02X:%02X:%02X:%02X\n",
+                      res->mc_addr.addr_bytes[0], res->mc_addr.addr_bytes[1],
+                      res->mc_addr.addr_bytes[2], res->mc_addr.addr_bytes[3],
+                      res->mc_addr.addr_bytes[4], res->mc_addr.addr_bytes[5]);
+               return;
+       }
+       if (strcmp(res->what, "add") == 0)
+               mcast_addr_add(res->port_num, &res->mc_addr);
+       else
+               mcast_addr_remove(res->port_num, &res->mc_addr);
+}
+
+cmdline_parse_token_string_t cmd_mcast_addr_cmd =
+       TOKEN_STRING_INITIALIZER(struct cmd_mcast_addr_result,
+                                mcast_addr_cmd, "mcast_addr");
+cmdline_parse_token_string_t cmd_mcast_addr_what =
+       TOKEN_STRING_INITIALIZER(struct cmd_mcast_addr_result, what,
+                                "add#remove");
+cmdline_parse_token_num_t cmd_mcast_addr_portnum =
+       TOKEN_NUM_INITIALIZER(struct cmd_mcast_addr_result, port_num, UINT8);
+cmdline_parse_token_etheraddr_t cmd_mcast_addr_addr =
+       TOKEN_ETHERADDR_INITIALIZER(struct cmd_mac_addr_result, address);
+
+cmdline_parse_inst_t cmd_mcast_addr = {
+       .f = cmd_mcast_addr_parsed,
+       .data = (void *)0,
+       .help_str = "mcast_addr add|remove X <mcast_addr>: add/remove multicast MAC address on port X",
+       .tokens = {
+               (void *)&cmd_mcast_addr_cmd,
+               (void *)&cmd_mcast_addr_what,
+               (void *)&cmd_mcast_addr_portnum,
+               (void *)&cmd_mcast_addr_addr,
+               NULL,
+       },
+};
+
+/* ******************************************************************************** */
+
+/* list of instructions */
+cmdline_parse_ctx_t main_ctx[] = {
+       (cmdline_parse_inst_t *)&cmd_help_brief,
+       (cmdline_parse_inst_t *)&cmd_help_long,
+       (cmdline_parse_inst_t *)&cmd_quit,
+       (cmdline_parse_inst_t *)&cmd_showport,
+       (cmdline_parse_inst_t *)&cmd_showqueue,
+       (cmdline_parse_inst_t *)&cmd_showportall,
+       (cmdline_parse_inst_t *)&cmd_showcfg,
        (cmdline_parse_inst_t *)&cmd_start,
        (cmdline_parse_inst_t *)&cmd_start_tx_first,
        (cmdline_parse_inst_t *)&cmd_set_link_up,
@@ -7831,6 +9650,7 @@ cmdline_parse_ctx_t main_ctx[] = {
        (cmdline_parse_inst_t *)&cmd_reset,
        (cmdline_parse_inst_t *)&cmd_set_numbers,
        (cmdline_parse_inst_t *)&cmd_set_txpkts,
+       (cmdline_parse_inst_t *)&cmd_set_txsplit,
        (cmdline_parse_inst_t *)&cmd_set_fwd_list,
        (cmdline_parse_inst_t *)&cmd_set_fwd_mask,
        (cmdline_parse_inst_t *)&cmd_set_fwd_mode,
@@ -7863,9 +9683,14 @@ cmdline_parse_ctx_t main_ctx[] = {
        (cmdline_parse_inst_t *)&cmd_rx_vlan_filter_all,
        (cmdline_parse_inst_t *)&cmd_rx_vlan_filter,
        (cmdline_parse_inst_t *)&cmd_tx_vlan_set,
+       (cmdline_parse_inst_t *)&cmd_tx_vlan_set_qinq,
        (cmdline_parse_inst_t *)&cmd_tx_vlan_reset,
        (cmdline_parse_inst_t *)&cmd_tx_vlan_set_pvid,
-       (cmdline_parse_inst_t *)&cmd_tx_cksum_set,
+       (cmdline_parse_inst_t *)&cmd_csum_set,
+       (cmdline_parse_inst_t *)&cmd_csum_show,
+       (cmdline_parse_inst_t *)&cmd_csum_tunnel,
+       (cmdline_parse_inst_t *)&cmd_tso_set,
+       (cmdline_parse_inst_t *)&cmd_tso_show,
        (cmdline_parse_inst_t *)&cmd_link_flow_control_set,
        (cmdline_parse_inst_t *)&cmd_link_flow_control_set_rx,
        (cmdline_parse_inst_t *)&cmd_link_flow_control_set_tx,
@@ -7884,19 +9709,13 @@ cmdline_parse_ctx_t main_ctx[] = {
        (cmdline_parse_inst_t *)&cmd_write_reg_bit_field,
        (cmdline_parse_inst_t *)&cmd_write_reg_bit,
        (cmdline_parse_inst_t *)&cmd_read_rxd_txd,
-       (cmdline_parse_inst_t *)&cmd_add_signature_filter,
-       (cmdline_parse_inst_t *)&cmd_upd_signature_filter,
-       (cmdline_parse_inst_t *)&cmd_rm_signature_filter,
-       (cmdline_parse_inst_t *)&cmd_add_perfect_filter,
-       (cmdline_parse_inst_t *)&cmd_upd_perfect_filter,
-       (cmdline_parse_inst_t *)&cmd_rm_perfect_filter,
-       (cmdline_parse_inst_t *)&cmd_set_masks_filter,
-       (cmdline_parse_inst_t *)&cmd_set_ipv6_masks_filter,
        (cmdline_parse_inst_t *)&cmd_stop,
        (cmdline_parse_inst_t *)&cmd_mac_addr,
        (cmdline_parse_inst_t *)&cmd_set_qmap,
        (cmdline_parse_inst_t *)&cmd_operate_port,
        (cmdline_parse_inst_t *)&cmd_operate_specific_port,
+       (cmdline_parse_inst_t *)&cmd_operate_attach_port,
+       (cmdline_parse_inst_t *)&cmd_operate_detach_port,
        (cmdline_parse_inst_t *)&cmd_config_speed_all,
        (cmdline_parse_inst_t *)&cmd_config_speed_specific,
        (cmdline_parse_inst_t *)&cmd_config_rx_tx,
@@ -7921,6 +9740,7 @@ cmdline_parse_ctx_t main_ctx[] = {
        (cmdline_parse_inst_t *)&cmd_vf_rate_limit,
        (cmdline_parse_inst_t *)&cmd_tunnel_filter,
        (cmdline_parse_inst_t *)&cmd_tunnel_udp_config,
+       (cmdline_parse_inst_t *)&cmd_global_config,
        (cmdline_parse_inst_t *)&cmd_set_mirror_mask,
        (cmdline_parse_inst_t *)&cmd_set_mirror_link,
        (cmdline_parse_inst_t *)&cmd_reset_mirror_rule,
@@ -7929,21 +9749,30 @@ cmdline_parse_ctx_t main_ctx[] = {
        (cmdline_parse_inst_t *)&cmd_config_rss_hash_key,
        (cmdline_parse_inst_t *)&cmd_dump,
        (cmdline_parse_inst_t *)&cmd_dump_one,
-       (cmdline_parse_inst_t *)&cmd_add_ethertype_filter,
-       (cmdline_parse_inst_t *)&cmd_remove_ethertype_filter,
-       (cmdline_parse_inst_t *)&cmd_get_ethertype_filter,
-       (cmdline_parse_inst_t *)&cmd_add_syn_filter,
-       (cmdline_parse_inst_t *)&cmd_remove_syn_filter,
-       (cmdline_parse_inst_t *)&cmd_get_syn_filter,
-       (cmdline_parse_inst_t *)&cmd_add_2tuple_filter,
-       (cmdline_parse_inst_t *)&cmd_remove_2tuple_filter,
-       (cmdline_parse_inst_t *)&cmd_get_2tuple_filter,
-       (cmdline_parse_inst_t *)&cmd_add_5tuple_filter,
-       (cmdline_parse_inst_t *)&cmd_remove_5tuple_filter,
-       (cmdline_parse_inst_t *)&cmd_get_5tuple_filter,
-       (cmdline_parse_inst_t *)&cmd_add_flex_filter,
-       (cmdline_parse_inst_t *)&cmd_remove_flex_filter,
-       (cmdline_parse_inst_t *)&cmd_get_flex_filter,
+       (cmdline_parse_inst_t *)&cmd_ethertype_filter,
+       (cmdline_parse_inst_t *)&cmd_syn_filter,
+       (cmdline_parse_inst_t *)&cmd_2tuple_filter,
+       (cmdline_parse_inst_t *)&cmd_5tuple_filter,
+       (cmdline_parse_inst_t *)&cmd_flex_filter,
+       (cmdline_parse_inst_t *)&cmd_add_del_ip_flow_director,
+       (cmdline_parse_inst_t *)&cmd_add_del_udp_flow_director,
+       (cmdline_parse_inst_t *)&cmd_add_del_sctp_flow_director,
+       (cmdline_parse_inst_t *)&cmd_add_del_l2_flow_director,
+       (cmdline_parse_inst_t *)&cmd_add_del_mac_vlan_flow_director,
+       (cmdline_parse_inst_t *)&cmd_add_del_tunnel_flow_director,
+       (cmdline_parse_inst_t *)&cmd_flush_flow_director,
+       (cmdline_parse_inst_t *)&cmd_set_flow_director_ip_mask,
+       (cmdline_parse_inst_t *)&cmd_set_flow_director_mac_vlan_mask,
+       (cmdline_parse_inst_t *)&cmd_set_flow_director_tunnel_mask,
+       (cmdline_parse_inst_t *)&cmd_set_flow_director_flex_mask,
+       (cmdline_parse_inst_t *)&cmd_set_flow_director_flex_payload,
+       (cmdline_parse_inst_t *)&cmd_get_sym_hash_ena_per_port,
+       (cmdline_parse_inst_t *)&cmd_set_sym_hash_ena_per_port,
+       (cmdline_parse_inst_t *)&cmd_get_hash_global_config,
+       (cmdline_parse_inst_t *)&cmd_set_hash_global_config,
+       (cmdline_parse_inst_t *)&cmd_set_hash_input_set,
+       (cmdline_parse_inst_t *)&cmd_set_fdir_input_set,
+       (cmdline_parse_inst_t *)&cmd_mcast_addr,
        NULL,
 };
 
@@ -7951,33 +9780,30 @@ cmdline_parse_ctx_t main_ctx[] = {
 void
 prompt(void)
 {
-       struct cmdline *cl;
-
        /* initialize non-constant commands */
        cmd_set_fwd_mode_init();
 
-       cl = cmdline_stdin_new(main_ctx, "testpmd> ");
-       if (cl == NULL) {
+       testpmd_cl = cmdline_stdin_new(main_ctx, "testpmd> ");
+       if (testpmd_cl == NULL)
                return;
-       }
-       cmdline_interact(cl);
-       cmdline_stdin_exit(cl);
+       cmdline_interact(testpmd_cl);
+       cmdline_stdin_exit(testpmd_cl);
+}
+
+void
+prompt_exit(void)
+{
+       if (testpmd_cl != NULL)
+               cmdline_quit(testpmd_cl);
 }
 
 static void
 cmd_reconfig_device_queue(portid_t id, uint8_t dev, uint8_t queue)
 {
-       if (id < nb_ports) {
-               /* check if need_reconfig has been set to 1 */
-               if (ports[id].need_reconfig == 0)
-                       ports[id].need_reconfig = dev;
-               /* check if need_reconfig_queues has been set to 1 */
-               if (ports[id].need_reconfig_queues == 0)
-                       ports[id].need_reconfig_queues = queue;
-       } else {
+       if (id == (portid_t)RTE_PORT_ALL) {
                portid_t pid;
 
-               for (pid = 0; pid < nb_ports; pid++) {
+               FOREACH_PORT(pid, ports) {
                        /* check if need_reconfig has been set to 1 */
                        if (ports[pid].need_reconfig == 0)
                                ports[pid].need_reconfig = dev;
@@ -7985,20 +9811,26 @@ cmd_reconfig_device_queue(portid_t id, uint8_t dev, uint8_t queue)
                        if (ports[pid].need_reconfig_queues == 0)
                                ports[pid].need_reconfig_queues = queue;
                }
+       } else if (!port_id_is_invalid(id, DISABLED_WARN)) {
+               /* check if need_reconfig has been set to 1 */
+               if (ports[id].need_reconfig == 0)
+                       ports[id].need_reconfig = dev;
+               /* check if need_reconfig_queues has been set to 1 */
+               if (ports[id].need_reconfig_queues == 0)
+                       ports[id].need_reconfig_queues = queue;
        }
 }
 
 #ifdef RTE_NIC_BYPASS
+#include <rte_pci_dev_ids.h>
 uint8_t
 bypass_is_supported(portid_t port_id)
 {
        struct rte_port   *port;
        struct rte_pci_id *pci_id;
 
-       if (port_id >= nb_ports) {
-               printf("\tPort id must be less than %d.\n", nb_ports);
+       if (port_id_is_invalid(port_id, ENABLED_WARN))
                return 0;
-       }
 
        /* Get the device id. */
        port    = &ports[port_id];