Add commands to test control packet filter
 - add/delete control packet filter

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

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 0b972f9..78a73ac 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -660,6 +660,11 @@ 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"
+
+                       "ctrl_pkt_filter (port_id) (add|del)"
+                       " mac_addr (mac_address) ethertype (ether_type)"
+                       " (none|options) queue (queue_id)\n"
+                       "    Add/Del a control packet filter.\n\n"
                );
        }
 }
@@ -7414,6 +7419,149 @@ cmdline_parse_inst_t cmd_get_flex_filter = {
                NULL,
        },
 };
+/* *** Filters Control *** */
+
+/* *** deal with control packet filter *** */
+struct cmd_ctrl_pkt_filter_result {
+       cmdline_fixed_string_t filter;
+       uint8_t port_id;
+       cmdline_fixed_string_t ops;
+       cmdline_fixed_string_t mac_addr;
+       struct ether_addr mac_addr_value;
+       cmdline_fixed_string_t ethertype;
+       uint16_t ethertype_value;
+       cmdline_fixed_string_t options;
+       cmdline_fixed_string_t queue;
+       uint16_t  queue_id;
+};
+
+cmdline_parse_token_string_t cmd_ctrl_pkt_filter_filter =
+       TOKEN_STRING_INITIALIZER(struct cmd_ctrl_pkt_filter_result,
+                                filter, "ctrl_pkt_filter");
+cmdline_parse_token_num_t cmd_ctrl_pkt_filter_port_id =
+       TOKEN_NUM_INITIALIZER(struct cmd_ctrl_pkt_filter_result,
+                             port_id, UINT8);
+cmdline_parse_token_string_t cmd_ctrl_pkt_filter_ops =
+       TOKEN_STRING_INITIALIZER(struct cmd_ctrl_pkt_filter_result,
+                                ops, "add#del");
+cmdline_parse_token_string_t cmd_ctrl_pkt_filter_mac_addr =
+       TOKEN_STRING_INITIALIZER(struct cmd_ctrl_pkt_filter_result,
+                                mac_addr, "mac_addr");
+cmdline_parse_token_etheraddr_t cmd_ctrl_pkt_filter_mac_addr_value =
+       TOKEN_ETHERADDR_INITIALIZER(struct cmd_ctrl_pkt_filter_result,
+                                    mac_addr_value);
+cmdline_parse_token_string_t cmd_ctrl_pkt_filter_ethertype =
+       TOKEN_STRING_INITIALIZER(struct cmd_ctrl_pkt_filter_result,
+                                ethertype, "ethertype");
+cmdline_parse_token_num_t cmd_ctrl_pkt_filter_ethertype_value =
+       TOKEN_NUM_INITIALIZER(struct cmd_ctrl_pkt_filter_result,
+                             ethertype_value, UINT16);
+cmdline_parse_token_string_t cmd_ctrl_pkt_filter_options =
+       TOKEN_STRING_INITIALIZER(struct cmd_ctrl_pkt_filter_result,
+                                options, NULL);
+cmdline_parse_token_string_t cmd_ctrl_pkt_filter_queue =
+       TOKEN_STRING_INITIALIZER(struct cmd_ctrl_pkt_filter_result,
+                                queue, "queue");
+cmdline_parse_token_num_t cmd_ctrl_pkt_filter_queue_id =
+       TOKEN_NUM_INITIALIZER(struct cmd_ctrl_pkt_filter_result,
+                             queue_id, UINT16);
+
+static inline int
+parse_ctrl_pkt_filter_options(const char *q_arg,
+                            uint16_t *flags)
+{
+#define MAX_NUM_OPTIONS 3
+       char s[256];
+       char *str_fld[MAX_NUM_OPTIONS];
+       int i;
+       int num_options = -1;
+       unsigned size;
+
+       *flags = 0;
+       if (!strcmp(q_arg, "none"))
+               return 0;
+
+       size = strnlen(q_arg, sizeof(s));
+       snprintf(s, sizeof(s), "%.*s", size, q_arg);
+       num_options = rte_strsplit(s, sizeof(s), str_fld, MAX_NUM_OPTIONS, '-');
+       /* multi-options are combined by - */
+       if (num_options < 0 || num_options > MAX_NUM_OPTIONS)
+               return -1;
+       for (i = 0; i < num_options; i++) {
+               if (!strcmp(str_fld[i], "tx"))
+                       *flags |= RTE_CONTROL_PACKET_FLAGS_TX;
+               if (!strcmp(str_fld[i], "mac_ignr"))
+                       *flags |= RTE_CONTROL_PACKET_FLAGS_IGNORE_MAC;
+               if (!strcmp(str_fld[i], "drop"))
+                       *flags |= RTE_CONTROL_PACKET_FLAGS_DROP;
+       }
+       return num_options;
+}
+
+static void
+cmd_ctrl_pkt_filter_parsed(void *parsed_result,
+                         __attribute__((unused)) struct cmdline *cl,
+                         __attribute__((unused)) void *data)
+{
+       struct cmd_ctrl_pkt_filter_result *res = parsed_result;
+       struct rte_ctrl_pkt_filter filter;
+       int ret = 0;
+
+       ret = rte_eth_dev_filter_supported(res->port_id, 
RTE_ETH_FILTER_CTRL_PKT);
+       if (ret < 0) {
+               printf("control packet filter is not supported on port %u.\n",
+                       res->port_id);
+               return;
+       }
+
+       memset(&filter, 0, sizeof(filter));
+
+       (void)rte_memcpy(&filter.mac_addr, &res->mac_addr_value,
+               sizeof(struct ether_addr));
+       filter.ether_type = res->ethertype_value;
+
+       ret = parse_ctrl_pkt_filter_options(res->options, &filter.flags);
+       if (ret < 0) {
+               printf("options input is invalid.\n");
+               return;
+       }
+       if (!(filter.flags & RTE_CONTROL_PACKET_FLAGS_DROP)) {
+               filter.flags |= RTE_CONTROL_PACKET_FLAGS_TO_QUEUE;
+               filter.queue = res->queue_id;
+       }
+       if (!strcmp(res->ops, "add"))
+               ret = rte_eth_dev_filter_ctrl(res->port_id,
+                               RTE_ETH_FILTER_CTRL_PKT,
+                               RTE_ETH_FILTER_ADD,
+                               &filter);
+       else
+               ret = rte_eth_dev_filter_ctrl(res->port_id,
+                               RTE_ETH_FILTER_CTRL_PKT,
+                               RTE_ETH_FILTER_DELETE,
+                               &filter);
+       if (ret < 0)
+               printf("control packet filter programming error: (%s)\n",
+                       strerror(-ret));
+}
+
+cmdline_parse_inst_t cmd_ctrl_pkt_filter = {
+       .f = cmd_ctrl_pkt_filter_parsed,
+       .data = NULL,
+       .help_str = "add or delete a control packet filter entry",
+       .tokens = {
+               (void *)&cmd_ctrl_pkt_filter_filter,
+               (void *)&cmd_ctrl_pkt_filter_port_id,
+               (void *)&cmd_ctrl_pkt_filter_ops,
+               (void *)&cmd_ctrl_pkt_filter_mac_addr,
+               (void *)&cmd_ctrl_pkt_filter_mac_addr_value,
+               (void *)&cmd_ctrl_pkt_filter_ethertype,
+               (void *)&cmd_ctrl_pkt_filter_ethertype_value,
+               (void *)&cmd_ctrl_pkt_filter_options,
+               (void *)&cmd_ctrl_pkt_filter_queue,
+               (void *)&cmd_ctrl_pkt_filter_queue_id,
+               NULL,
+       },
+};

 /* 
********************************************************************************
 */

@@ -7541,6 +7689,7 @@ cmdline_parse_ctx_t main_ctx[] = {
        (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_ctrl_pkt_filter,
        NULL,
 };

-- 
1.8.1.4

Reply via email to