Add new command to set flow director's mask:
  - flow_director_mask
Update arguments of commands:
  - flow_director_filter
  - flow_director_flex_mask
  - flow_director_flex_payload

Signed-off-by: Jingjing Wu <jingjing.wu at intel.com>
---
 app/test-pmd/cmdline.c | 182 ++++++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 164 insertions(+), 18 deletions(-)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 4beb404..3671d25 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -701,25 +701,26 @@ static void cmd_help_long_parsed(void *parsed_result,
                        "get_flex_filter (port_id) index (idx)\n"
                        "    get info of a flex filter.\n\n"

-                       "flow_director_filter (port_id) (add|del)"
+                       "flow_director_filter (port_id) (add|del|update)"
                        " flow (ip4|ip4-frag|ip6|ip6-frag)"
                        " src (src_ip_address) dst (dst_ip_address)"
-                       " flexbytes (flexbytes_value)"
+                       " vlan (vlan_value) flexbytes (flexbytes_value)"
                        " (drop|fwd) queue (queue_id) fd_id (fd_id_value)\n"
                        "    Add/Del an IP type flow director filter.\n\n"

-                       "flow_director_filter (port_id) (add|del)"
+                       "flow_director_filter (port_id) (add|del|update)"
                        " flow (udp4|tcp4|udp6|tcp6)"
                        " src (src_ip_address) (src_port)"
                        " dst (dst_ip_address) (dst_port)"
-                       " flexbytes (flexbytes_value)"
+                       " vlan (vlan_value) flexbytes (flexbytes_value)"
                        " (drop|fwd) queue (queue_id) fd_id (fd_id_value)\n"
                        "    Add/Del an UDP/TCP type flow director filter.\n\n"

-                       "flow_director_filter (port_id) (add|del)"
+                       "flow_director_filter (port_id) (add|del|update)"
                        " flow (sctp4|sctp6)"
-                       " src (src_ip_address) dst (dst_ip_address)"
-                       " tag (verification_tag)"
+                       " src (src_ip_address) (src_port)"
+                       " dst (dst_ip_address) (dst_port)"
+                       " tag (verification_tag) vlan (vlan_value)"
                        " flexbytes (flexbytes_value) (drop|fwd)"
                        " queue (queue_id) fd_id (fd_id_value)\n"
                        "    Add/Del a SCTP type flow director filter.\n\n"
@@ -727,13 +728,18 @@ static void cmd_help_long_parsed(void *parsed_result,
                        "flush_flow_director (port_id)\n"
                        "    Flush all flow director entries of a device.\n\n"

+                       "flow_director_mask (port_id) vlan (vlan_value)"
+                       " src_mask (ipv4_src) (ipv6_src) (src_port)"
+                       " dst_mask (ipv4_dst) (ipv6_dst) (dst_port)\n"
+                       "    Set flow director mask.\n\n"
+
                        "flow_director_flex_mask (port_id)"
-                       " flow 
(ip4|ip4-frag|tcp4|udp4|sctp4|ip6|ip6-frag|tcp6|udp6|sctp6|all)"
+                       " flow 
(raw|ip4|ip4-frag|tcp4|udp4|sctp4|ip6|ip6-frag|tcp6|udp6|sctp6|all)"
                        " (mask)\n"
                        "    Configure mask of flex payload.\n\n"

                        "flow_director_flex_payload (port_id)"
-                       " (l2|l3|l4) (config)\n"
+                       " (raw|l2|l3|l4) (config)\n"
                        "    Configure flex payload selection.\n\n"
                );
        }
@@ -8084,6 +8090,8 @@ struct cmd_flow_director_result {
        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 drop;
@@ -8139,6 +8147,7 @@ str2flowtype(char *string)
                char str[32];
                enum rte_eth_flow_type type;
        } flowtype_str[] = {
+               {"raw", RTE_ETH_FLOW_TYPE_RAW},
                {"ip4", RTE_ETH_FLOW_TYPE_IPV4_OTHER},
                {"ip4-frag", RTE_ETH_FLOW_TYPE_FRAG_IPV4},
                {"udp4", RTE_ETH_FLOW_TYPE_UDPV4},
@@ -8209,6 +8218,7 @@ cmd_flow_director_filter_parsed(void *parsed_result,
        entry.input.flow_type = str2flowtype(res->flow_type);
        switch (entry.input.flow_type) {
        case RTE_ETH_FLOW_TYPE_IPV4_OTHER:
+       case RTE_ETH_FLOW_TYPE_FRAG_IPV4:
        case RTE_ETH_FLOW_TYPE_UDPV4:
        case RTE_ETH_FLOW_TYPE_TCPV4:
                IPV4_ADDR_TO_UINT(res->ip_dst,
@@ -8231,6 +8241,7 @@ cmd_flow_director_filter_parsed(void *parsed_result,
                                rte_cpu_to_be_32(res->verify_tag_value);
                break;
        case RTE_ETH_FLOW_TYPE_IPV6_OTHER:
+       case RTE_ETH_FLOW_TYPE_FRAG_IPV6:
        case RTE_ETH_FLOW_TYPE_UDPV6:
        case RTE_ETH_FLOW_TYPE_TCPV6:
                IPV6_ADDR_TO_ARRAY(res->ip_dst,
@@ -8260,6 +8271,8 @@ cmd_flow_director_filter_parsed(void *parsed_result,
                   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;
@@ -8272,9 +8285,12 @@ cmd_flow_director_filter_parsed(void *parsed_result,
        if (!strcmp(res->ops, "add"))
                ret = rte_eth_dev_filter_ctrl(res->port_id, RTE_ETH_FILTER_FDIR,
                                             RTE_ETH_FILTER_ADD, &entry);
-       else
+       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));
@@ -8288,7 +8304,7 @@ cmdline_parse_token_num_t cmd_flow_director_port_id =
                              port_id, UINT8);
 cmdline_parse_token_string_t cmd_flow_director_ops =
        TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
-                                ops, "add#del");
+                                ops, "add#del#update");
 cmdline_parse_token_string_t cmd_flow_director_flow =
        TOKEN_STRING_INITIALIZER(struct cmd_flow_director_result,
                                 flow, "flow");
@@ -8321,6 +8337,12 @@ cmdline_parse_token_string_t 
cmd_flow_director_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");
@@ -8357,6 +8379,8 @@ cmdline_parse_inst_t cmd_add_del_ip_flow_director = {
                (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,
@@ -8384,6 +8408,8 @@ cmdline_parse_inst_t cmd_add_del_udp_flow_director = {
                (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,
@@ -8407,10 +8433,14 @@ cmdline_parse_inst_t cmd_add_del_sctp_flow_director = {
                (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,
@@ -8467,6 +8497,112 @@ cmdline_parse_inst_t cmd_flush_flow_director = {
        },
 };

+/* *** 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 vlan;
+       uint16_t vlan_value;
+       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;
+};
+
+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;
+
+       mask->vlan_tci_mask = res->vlan_value;
+       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_value, 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_inst_t cmd_set_flow_director_mask = {
+       .f = cmd_flow_director_mask_parsed,
+       .data = NULL,
+       .help_str = "set flow director's mask on NIC",
+       .tokens = {
+               (void *)&cmd_flow_director_mask,
+               (void *)&cmd_flow_director_mask_port_id,
+               (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,
+       },
+};
+
 /* *** deal with flow director mask on flexible payload *** */
 struct cmd_flow_director_flex_mask_result {
        cmdline_fixed_string_t flow_director_flexmask;
@@ -8482,6 +8618,7 @@ cmd_flow_director_flex_mask_parsed(void *parsed_result,
                          __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;
        enum rte_eth_flow_type i;
@@ -8507,14 +8644,20 @@ cmd_flow_director_flex_mask_parsed(void *parsed_result,
                printf("error: Cannot parse mask input.\n");
                return;
        }
+
        if (!strcmp(res->flow_type, "all")) {
-               for (i = RTE_ETH_FLOW_TYPE_UDPV4;
+               memset(&fdir_info, 0, sizeof(fdir_info));
+               rte_eth_dev_filter_ctrl(res->port_id, RTE_ETH_FILTER_FDIR,
+                                      RTE_ETH_FILTER_INFO, &fdir_info);
+               for (i = RTE_ETH_FLOW_TYPE_RAW;
                     i <= RTE_ETH_FLOW_TYPE_FRAG_IPV6;
                     i++) {
-                       flex_mask.flow_type = i;
-                       fdir_set_flex_mask(res->port_id, &flex_mask);
+                       if (fdir_info.flow_types_mask[0] & (1 << i)) {
+                               flex_mask.flow_type = i;
+                               fdir_set_flex_mask(res->port_id, &flex_mask);
+                       }
                }
-               cmd_reconfig_device_queue(res->port_id, 1, 0);
+               cmd_reconfig_device_queue(res->port_id, 1, 1);
                return;
        }
        flex_mask.flow_type = str2flowtype(res->flow_type);
@@ -8535,7 +8678,7 @@ cmdline_parse_token_string_t 
cmd_flow_director_flexmask_flow =
 cmdline_parse_token_string_t cmd_flow_director_flexmask_flow_type =
        TOKEN_STRING_INITIALIZER(struct cmd_flow_director_flex_mask_result,
                                 flow_type,
-                               "ip4#ip4-frag#tcp4#udp4#sctp4#"
+                               "raw#ip4#ip4-frag#tcp4#udp4#sctp4#"
                                "ip6#ip6-frag#tcp6#udp6#sctp6#all");
 cmdline_parse_token_string_t cmd_flow_director_flexmask_mask =
        TOKEN_STRING_INITIALIZER(struct cmd_flow_director_flex_mask_result,
@@ -8625,7 +8768,9 @@ cmd_flow_director_flxpld_parsed(void *parsed_result,

        memset(&flex_cfg, 0, sizeof(struct rte_eth_flex_payload_cfg));

-       if (!strcmp(res->payload_layer, "l2"))
+       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;
@@ -8652,7 +8797,7 @@ cmdline_parse_token_num_t 
cmd_flow_director_flexpayload_port_id =
                              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, "l2#l3#l4");
+                                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);
@@ -8805,6 +8950,7 @@ cmdline_parse_ctx_t main_ctx[] = {
        (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_flush_flow_director,
+       (cmdline_parse_inst_t *)&cmd_set_flow_director_mask,
        (cmdline_parse_inst_t *)&cmd_set_flow_director_flex_mask,
        (cmdline_parse_inst_t *)&cmd_set_flow_director_flex_payload,
        NULL,
-- 
1.9.3

Reply via email to