acl: remove redundant macro
[dpdk.git] / app / test-pmd / cmdline.c
index f4ae931..8142910 100644 (file)
@@ -61,7 +61,6 @@
 #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>
@@ -292,11 +291,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"
@@ -318,7 +317,7 @@ static void cmd_help_long_parsed(void *parsed_result,
 
                        "csum set (ip|udp|tcp|sctp|outer-ip) (hw|sw) (port_id)\n"
                        "    Select hardware or software calculation of the"
-                       " checksum with when transmitting a packet using 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"
@@ -513,6 +512,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"
@@ -524,12 +529,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"
@@ -655,8 +661,7 @@ static void cmd_help_long_parsed(void *parsed_result,
                        "    Set flow director mask.\n\n"
 
                        "flow_director_flex_mask (port_id)"
-                       " flow (raw|ip4|ip4-frag|tcp4|udp4|sctp4|ip6|ip6-frag|tcp6|udp6|sctp6|all)"
-                       " flow (raw|ipv4-other|ipv4-frag|ipv4-tcp|ipv4-udp|ipv4-sctp|"
+                       " flow (none|ipv4-other|ipv4-frag|ipv4-tcp|ipv4-udp|ipv4-sctp|"
                        "ipv6-other|ipv6-frag|ipv6-tcp|ipv6-udp|ipv6-sctp|all)"
                        " (mask)\n"
                        "    Configure mask of flex payload.\n\n"
@@ -793,6 +798,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;
@@ -847,7 +935,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;
        }
@@ -915,10 +1003,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;
@@ -1256,6 +1342,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;
@@ -1284,7 +1397,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");
@@ -1292,7 +1406,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,
@@ -1321,10 +1436,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 {
@@ -1345,12 +1470,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,
@@ -1478,7 +1604,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) {
@@ -2878,7 +3004,7 @@ cmd_csum_parsed(void *parsed_result,
        int hw = 0;
        uint16_t mask = 0;
 
-       if (port_id_is_invalid(res->port_id)) {
+       if (port_id_is_invalid(res->port_id, ENABLED_WARN)) {
                printf("invalid port %d\n", res->port_id);
                return;
        }
@@ -2970,10 +3096,8 @@ cmd_csum_tunnel_parsed(void *parsed_result,
 {
        struct cmd_csum_tunnel_result *res = parsed_result;
 
-       if (port_id_is_invalid(res->port_id)) {
-               printf("invalid port %d\n", res->port_id);
+       if (port_id_is_invalid(res->port_id, ENABLED_WARN))
                return;
-       }
 
        if (!strcmp(res->onoff, "on"))
                ports[res->port_id].tx_ol_flags |=
@@ -3028,7 +3152,7 @@ cmd_tso_set_parsed(void *parsed_result,
        struct cmd_tso_set_result *res = parsed_result;
        struct rte_eth_dev_info dev_info;
 
-       if (port_id_is_invalid(res->port_id))
+       if (port_id_is_invalid(res->port_id, ENABLED_WARN))
                return;
 
        if (!strcmp(res->mode, "set"))
@@ -3954,6 +4078,7 @@ static void cmd_create_bonded_device_parsed(void *parsed_result,
                nb_ports = rte_eth_dev_count();
                reconfig(port_id, res->socket);
                rte_eth_promiscuous_enable(port_id);
+               ports[port_id].enabled = 1;
        }
 
 }
@@ -4004,10 +4129,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);
 
@@ -4244,7 +4367,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
@@ -4324,7 +4447,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
@@ -4620,7 +4743,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 = 0;
+       int rx_fc_en = 0;
+       int tx_fc_en = 0;
        int ret;
 
        /*
@@ -5012,25 +5136,25 @@ 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);
 }
 
@@ -6286,8 +6410,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;
        }
 
@@ -6331,7 +6457,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,
@@ -6349,7 +6475,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",
@@ -8102,6 +8228,19 @@ cmd_flow_director_flex_mask_parsed(void *parsed_result,
                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) {
@@ -8139,7 +8278,7 @@ cmdline_parse_token_string_t cmd_flow_director_flexmask_flow =
                                 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, "raw#ipv4-other#ipv4-frag#ipv4-tcp#ipv4-udp#ipv4-sctp#"
+               flow_type, "none#ipv4-other#ipv4-frag#ipv4-tcp#ipv4-udp#ipv4-sctp#"
                "ipv6-other#ipv6-frag#ipv6-tcp#ipv6-udp#ipv6-sctp#all");
 cmdline_parse_token_string_t cmd_flow_director_flexmask_mask =
        TOKEN_STRING_INITIALIZER(struct cmd_flow_director_flex_mask_result,
@@ -8595,6 +8734,57 @@ cmdline_parse_inst_t cmd_set_hash_global_config = {
        },
 };
 
+/* *** 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 */
@@ -8674,6 +8864,8 @@ cmdline_parse_ctx_t main_ctx[] = {
        (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,
@@ -8722,6 +8914,7 @@ cmdline_parse_ctx_t main_ctx[] = {
        (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_mcast_addr,
        NULL,
 };
 
@@ -8745,17 +8938,10 @@ prompt(void)
 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;
@@ -8763,6 +8949,13 @@ 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;
        }
 }
 
@@ -8773,10 +8966,8 @@ 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];