From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id 29A3FA04FD; Tue, 14 Jan 2020 04:45:47 +0100 (CET) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id EAE801C2E8; Tue, 14 Jan 2020 04:45:46 +0100 (CET) Received: from git-send-mailer.rdmz.labs.mlnx (unknown [37.142.13.130]) by dpdk.org (Postfix) with ESMTP id 0B07C1C1ED for ; Tue, 14 Jan 2020 04:45:45 +0100 (CET) From: Xiaoyu Min To: viacheslavo@mellanox.com, matan@mellanox.com, rasland@mellanox.com, Wenzhuo Lu , Jingjing Wu , Bernard Iremonger , Adrien Mazarguil , Ori Kam Cc: dev@dpdk.org, Xueming Li Date: Tue, 14 Jan 2020 05:45:13 +0200 Message-Id: <620a2408b0dd370b8483c452d2b5957b3144fac7.1578969179.git.jackmin@mellanox.com> X-Mailer: git-send-email 2.21.0 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Subject: [dpdk-dev] [RFC 2/4] app/testpmd: new flow dump CLI X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" From: Xueming Li New flow dump CLI to dump MLX5 PMD specific flows into screen. Signed-off-by: Xueming Li Signed-off-by: Xiaoyu Min --- app/test-pmd/Makefile | 4 ++ app/test-pmd/cmdline_flow.c | 91 +++++++++++++++++++++++++++++++++++++ app/test-pmd/config.c | 33 ++++++++++++++ app/test-pmd/meson.build | 3 ++ app/test-pmd/testpmd.h | 1 + 5 files changed, 132 insertions(+) diff --git a/app/test-pmd/Makefile b/app/test-pmd/Makefile index d5258eae4a..e60c8ecf63 100644 --- a/app/test-pmd/Makefile +++ b/app/test-pmd/Makefile @@ -70,6 +70,10 @@ ifeq ($(CONFIG_RTE_LIBRTE_PMD_SOFTNIC),y) LDLIBS += -lrte_pmd_softnic endif +ifeq ($(CONFIG_RTE_LIBRTE_MLX5_PMD),y) +LDLIBS += -lrte_pmd_mlx5 +endif + endif include $(RTE_SDK)/mk/rte.app.mk diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c index 99dade7d8c..19336e5d42 100644 --- a/app/test-pmd/cmdline_flow.c +++ b/app/test-pmd/cmdline_flow.c @@ -41,6 +41,7 @@ enum index { BOOLEAN, STRING, HEX, + FILE_PATH, MAC_ADDR, IPV4_ADDR, IPV6_ADDR, @@ -63,6 +64,7 @@ enum index { CREATE, DESTROY, FLUSH, + DUMP, QUERY, LIST, ISOLATE, @@ -631,6 +633,9 @@ struct buffer { uint32_t *rule; uint32_t rule_n; } destroy; /**< Destroy arguments. */ + struct { + char file[128]; + } dump; /**< Dump arguments. */ struct { uint32_t rule; struct rte_flow_action action; @@ -685,6 +690,12 @@ static const enum index next_destroy_attr[] = { ZERO, }; +static const enum index next_dump_attr[] = { + FILE_PATH, + END, + ZERO, +}; + static const enum index next_list_attr[] = { LIST_GROUP, END, @@ -1374,6 +1385,9 @@ static int parse_destroy(struct context *, const struct token *, static int parse_flush(struct context *, const struct token *, const char *, unsigned int, void *, unsigned int); +static int parse_dump(struct context *, const struct token *, + const char *, unsigned int, + void *, unsigned int); static int parse_query(struct context *, const struct token *, const char *, unsigned int, void *, unsigned int); @@ -1401,6 +1415,9 @@ static int parse_string(struct context *, const struct token *, static int parse_hex(struct context *ctx, const struct token *token, const char *str, unsigned int len, void *buf, unsigned int size); +static int parse_string0(struct context *, const struct token *, + const char *, unsigned int, + void *, unsigned int); static int parse_mac_addr(struct context *, const struct token *, const char *, unsigned int, void *, unsigned int); @@ -1494,6 +1511,12 @@ static const struct token token_list[] = { .type = "HEX", .help = "fixed string", .call = parse_hex, + }, + [FILE_PATH] = { + .name = "{file path}", + .type = "STRING", + .help = "file path", + .call = parse_string0, .comp = comp_none, }, [MAC_ADDR] = { @@ -1555,6 +1578,7 @@ static const struct token token_list[] = { CREATE, DESTROY, FLUSH, + DUMP, LIST, QUERY, ISOLATE)), @@ -1589,6 +1613,14 @@ static const struct token token_list[] = { .args = ARGS(ARGS_ENTRY(struct buffer, port)), .call = parse_flush, }, + [DUMP] = { + .name = "dump", + .help = "dump all flow rules to file", + .next = NEXT(next_dump_attr, NEXT_ENTRY(PORT_ID)), + .args = ARGS(ARGS_ENTRY(struct buffer, args.dump.file), + ARGS_ENTRY(struct buffer, port)), + .call = parse_dump, + }, [QUERY] = { .name = "query", .help = "query an existing flow rule", @@ -5012,6 +5044,33 @@ parse_flush(struct context *ctx, const struct token *token, return len; } +/** Parse tokens for dump command. */ +static int +parse_dump(struct context *ctx, const struct token *token, + const char *str, unsigned int len, + void *buf, unsigned int size) +{ + struct buffer *out = buf; + + /* Token name must match. */ + if (parse_default(ctx, token, str, len, NULL, 0) < 0) + return -1; + /* Nothing else to do if there is no buffer. */ + if (!out) + return len; + if (!out->command) { + if (ctx->curr != DUMP) + return -1; + if (sizeof(*out) > size) + return -1; + out->command = ctx->curr; + ctx->objdata = 0; + ctx->object = out; + ctx->objmask = NULL; + } + return len; +} + /** Parse tokens for query command. */ static int parse_query(struct context *ctx, const struct token *token, @@ -5409,6 +5468,35 @@ parse_hex(struct context *ctx, const struct token *token, } +/** + * Parse a zero-ended string. + */ +static int +parse_string0(struct context *ctx, const struct token *token __rte_unused, + const char *str, unsigned int len, + void *buf, unsigned int size) +{ + const struct arg *arg_data = pop_args(ctx); + + /* Arguments are expected. */ + if (!arg_data) + return -1; + size = arg_data->size; + /* Bit-mask fill is not supported. */ + if (arg_data->mask || size < len + 1) + goto error; + if (!ctx->object) + return len; + buf = (uint8_t *)ctx->object + arg_data->offset; + strncpy(buf, str, len); + if (ctx->objmask) + memset((uint8_t *)ctx->objmask + arg_data->offset, 0xff, len); + return len; +error: + push_args(ctx, arg_data); + return -1; +} + /** * Parse a MAC address. * @@ -6068,6 +6156,9 @@ cmd_flow_parsed(const struct buffer *in) case FLUSH: port_flow_flush(in->port); break; + case DUMP: + port_flow_dump(in->port, in->args.dump.file); + break; case QUERY: port_flow_query(in->port, in->args.query.rule, &in->args.query.action); diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c index 9da1ffb034..b5a9915df9 100644 --- a/app/test-pmd/config.c +++ b/app/test-pmd/config.c @@ -48,6 +48,9 @@ #ifdef RTE_LIBRTE_BNXT_PMD #include #endif +#ifdef RTE_LIBRTE_MLX5_PMD +#include +#endif #include #include @@ -1441,6 +1444,36 @@ port_flow_flush(portid_t port_id) return ret; } +/** Dump all flow rules. */ +int +port_flow_dump(portid_t port_id __rte_unused, + const char *file_name __rte_unused) +{ + int ret = 0; +#ifdef RTE_LIBRTE_MLX5_PMD + FILE * file = stdout; + + if (file_name && strlen(file_name)) { + file = fopen(file_name, "w"); + if (!file) { + printf("Failed to create file %s: %s\n", file_name, + strerror(errno)); + return -errno; + } + } + ret = rte_pmd_mlx5_flow_dump(port_id, file); + if (ret) + printf("Failed to dump flow: %s\n", strerror(-ret)); + else + printf("Flow dump finished\n"); + if (file_name && strlen(file_name)) + fclose(file); +#else + printf("MLX5 PMD driver disabled\n"); +#endif + return ret; +} + /** Query a flow rule. */ int port_flow_query(portid_t port_id, uint32_t rule, diff --git a/app/test-pmd/meson.build b/app/test-pmd/meson.build index 6006c60f99..a71e0a0cd1 100644 --- a/app/test-pmd/meson.build +++ b/app/test-pmd/meson.build @@ -48,3 +48,6 @@ if dpdk_conf.has('RTE_LIBRTE_BPF') sources += files('bpf_cmd.c') deps += 'bpf' endif +if dpdk_conf.has('RTE_LIBRTE_MLX5_PMD') + deps += 'pmd_mlx5' +endif diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h index 857a11f8de..e1b9aba360 100644 --- a/app/test-pmd/testpmd.h +++ b/app/test-pmd/testpmd.h @@ -734,6 +734,7 @@ int port_flow_create(portid_t port_id, const struct rte_flow_action *actions); int port_flow_destroy(portid_t port_id, uint32_t n, const uint32_t *rule); int port_flow_flush(portid_t port_id); +int port_flow_dump(portid_t port_id, const char *file_name); int port_flow_query(portid_t port_id, uint32_t rule, const struct rte_flow_action *action); void port_flow_list(portid_t port_id, uint32_t n, const uint32_t *group); -- 2.24.1