* [dpdk-dev] [PATCH 0/8] ethdev: introduce GENEVE header TLV option item @ 2020-12-27 16:06 Shiri Kuzin 2020-12-27 16:06 ` [dpdk-dev] [PATCH 1/8] lib/librte_ethdev: " Shiri Kuzin ` (8 more replies) 0 siblings, 9 replies; 27+ messages in thread From: Shiri Kuzin @ 2020-12-27 16:06 UTC (permalink / raw) To: dev; +Cc: viacheslavo, adrien.mazarguil, orika, ferruh.yigit, thomas, rasland The Geneve tunneling protocol is designed to allow the user to specify some data context on the packet. The GENEVE TLV (Type-Length-Variable) Option is the mean intended to present the user data. In order to support GENEVE TLV Option the new rte_flow item "rte_flow_item_geneve_opt" is introduced. The new item contains the values and masks for the following fields: -option class -option type -length -data The usage example: "flow create 0 ingress pattern eth / ipv4 / udp / geneve vni is 100 / geneve-opt class is 5 length is 1 type is 0 data is 0x66998800 / end actions count / drop / end" New item will be added to testpmd to support raw encap/decap action. Shiri Kuzin (7): lib/librte_ethdev: introduce GENEVE header TLV option item common/mlx5: check GENEVE TLV support in HCA attributes common/mlx5: create GENEVE TLV option object with DevX net/mlx5: create GENEVE TLV option management net/mlx5: add GENEVE TLV option flow validation net/mlx5: add GENEVE TLV option flow translation doc: update GENEVE TLV option support Viacheslav Ovsiienko (1): app/testpmd: add GENEVE option item support app/test-pmd/cmdline_flow.c | 102 ++++++++++++++- doc/guides/nics/mlx5.rst | 18 ++- doc/guides/testpmd_app_ug/testpmd_funcs.rst | 8 ++ drivers/common/mlx5/mlx5_devx_cmds.c | 61 +++++++++ drivers/common/mlx5/mlx5_devx_cmds.h | 9 ++ drivers/common/mlx5/mlx5_prm.h | 28 ++++- drivers/common/mlx5/version.map | 1 + drivers/net/mlx5/mlx5.c | 2 + drivers/net/mlx5/mlx5.h | 13 ++ drivers/net/mlx5/mlx5_flow.c | 120 ++++++++++++++++++ drivers/net/mlx5/mlx5_flow.h | 11 ++ drivers/net/mlx5/mlx5_flow_dv.c | 188 +++++++++++++++++++++++++++- lib/librte_ethdev/rte_flow.c | 1 + lib/librte_ethdev/rte_flow.h | 33 +++++ 14 files changed, 584 insertions(+), 11 deletions(-) -- 1.8.3.1 ^ permalink raw reply [flat|nested] 27+ messages in thread
* [dpdk-dev] [PATCH 1/8] lib/librte_ethdev: introduce GENEVE header TLV option item 2020-12-27 16:06 [dpdk-dev] [PATCH 0/8] ethdev: introduce GENEVE header TLV option item Shiri Kuzin @ 2020-12-27 16:06 ` Shiri Kuzin 2020-12-27 17:25 ` Stephen Hemminger 2020-12-27 16:06 ` [dpdk-dev] [PATCH 2/8] app/testpmd: add GENEVE option item support Shiri Kuzin ` (7 subsequent siblings) 8 siblings, 1 reply; 27+ messages in thread From: Shiri Kuzin @ 2020-12-27 16:06 UTC (permalink / raw) To: dev; +Cc: viacheslavo, adrien.mazarguil, orika, ferruh.yigit, thomas, rasland The Geneve tunneling protocol is designed to allow the user to specify some data context on the packet. The GENEVE TLV (Type-Length-Variable) Option is the mean intended to present the user data. In order to support GENEVE TLV Option the new rte_flow item "rte_flow_item_geneve_opt" is added. The new item contains the values and masks for the following fields: -option class -option type -length -data New item will be added to testpmd to support match and raw encap/decap actions. Signed-off-by: Shiri Kuzin <shirik@nvidia.com> --- lib/librte_ethdev/rte_flow.c | 1 + lib/librte_ethdev/rte_flow.h | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/lib/librte_ethdev/rte_flow.c b/lib/librte_ethdev/rte_flow.c index a06f64c..2af7d96 100644 --- a/lib/librte_ethdev/rte_flow.c +++ b/lib/librte_ethdev/rte_flow.c @@ -97,6 +97,7 @@ struct rte_flow_desc_data { MK_FLOW_ITEM(L2TPV3OIP, sizeof(struct rte_flow_item_l2tpv3oip)), MK_FLOW_ITEM(PFCP, sizeof(struct rte_flow_item_pfcp)), MK_FLOW_ITEM(ECPRI, sizeof(struct rte_flow_item_ecpri)), + MK_FLOW_ITEM(GENEVE_OPT, sizeof(struct rte_flow_item_geneve_opt)), }; /** Generate flow_action[] entry. */ diff --git a/lib/librte_ethdev/rte_flow.h b/lib/librte_ethdev/rte_flow.h index 0977a78..e17a630 100644 --- a/lib/librte_ethdev/rte_flow.h +++ b/lib/librte_ethdev/rte_flow.h @@ -543,6 +543,14 @@ enum rte_flow_item_type { * See struct rte_flow_item_ipv6_frag_ext. */ RTE_FLOW_ITEM_TYPE_IPV6_FRAG_EXT, + + /** + * Matches Geneve Variable Length Option + * + * See struct rte_flow_item_geneve_opt + */ + RTE_FLOW_ITEM_TYPE_GENEVE_OPT, + }; /** @@ -1626,7 +1634,32 @@ struct rte_flow_item_ecpri { }, }; #endif +#ifdef PEDANTIC +#pragma GCC diagnostic ignored "-Wpedantic" +#endif +/** + * RTE_FLOW_ITEM_TYPE_GENEVE_OPT + * + * Matches a GENEVE Variable Length Option + */ +RTE_STD_C11 +struct rte_flow_item_geneve_opt { + rte_be16_t option_class; + uint8_t option_type; + uint8_t option_len; + uint32_t *data; +}; +#ifdef PEDANTIC +#pragma GCC diagnostic ignored "-Wpedantic" +#endif +/** Default mask for RTE_FLOW_ITEM_TYPE_GENEVE_OPT. */ +#ifndef __cplusplus +static const struct rte_flow_item_geneve_opt +rte_flow_item_geneve_opt_mask = { + .option_type = 0xff, +}; +#endif /** * Matching pattern item definition. * -- 1.8.3.1 ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [dpdk-dev] [PATCH 1/8] lib/librte_ethdev: introduce GENEVE header TLV option item 2020-12-27 16:06 ` [dpdk-dev] [PATCH 1/8] lib/librte_ethdev: " Shiri Kuzin @ 2020-12-27 17:25 ` Stephen Hemminger 2020-12-29 10:12 ` Ori Kam 0 siblings, 1 reply; 27+ messages in thread From: Stephen Hemminger @ 2020-12-27 17:25 UTC (permalink / raw) To: Shiri Kuzin Cc: dev, viacheslavo, adrien.mazarguil, orika, ferruh.yigit, thomas, rasland On Sun, 27 Dec 2020 18:06:16 +0200 Shiri Kuzin <shirik@nvidia.com> wrote: > +#ifdef PEDANTIC > +#pragma GCC diagnostic ignored "-Wpedantic" > +#endif Please do not introduce pragma's for pedantic in standard headers. It just clutters the code unnecessarily. The rest of DPDK is not guaranteed to be free of pedantic warnings, so starting now is not worth the mess. ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [dpdk-dev] [PATCH 1/8] lib/librte_ethdev: introduce GENEVE header TLV option item 2020-12-27 17:25 ` Stephen Hemminger @ 2020-12-29 10:12 ` Ori Kam 2020-12-30 8:22 ` Shiri Kuzin 0 siblings, 1 reply; 27+ messages in thread From: Ori Kam @ 2020-12-29 10:12 UTC (permalink / raw) To: Stephen Hemminger, Shiri Kuzin Cc: dev, Slava Ovsiienko, NBU-Contact-Adrien Mazarguil, ferruh.yigit, NBU-Contact-Thomas Monjalon, Raslan Darawsheh > -----Original Message----- > From: Stephen Hemminger <stephen@networkplumber.org> > > On Sun, 27 Dec 2020 18:06:16 +0200 > Shiri Kuzin <shirik@nvidia.com> wrote: > > > +#ifdef PEDANTIC > > +#pragma GCC diagnostic ignored "-Wpedantic" > > +#endif > > Please do not introduce pragma's for pedantic in standard headers. > It just clutters the code unnecessarily. The rest of DPDK is not guaranteed > to be free of pedantic warnings, so starting now is not worth the mess. +1 Thanks, Ori ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [dpdk-dev] [PATCH 1/8] lib/librte_ethdev: introduce GENEVE header TLV option item 2020-12-29 10:12 ` Ori Kam @ 2020-12-30 8:22 ` Shiri Kuzin 0 siblings, 0 replies; 27+ messages in thread From: Shiri Kuzin @ 2020-12-30 8:22 UTC (permalink / raw) To: Ori Kam, Stephen Hemminger Cc: dev, Slava Ovsiienko, NBU-Contact-Adrien Mazarguil, ferruh.yigit, NBU-Contact-Thomas Monjalon, Raslan Darawsheh > -----Original Message----- > From: Ori Kam <orika@nvidia.com> > Sent: Tuesday, December 29, 2020 12:13 PM > To: Stephen Hemminger <stephen@networkplumber.org>; Shiri Kuzin > <shirik@nvidia.com> > Cc: dev@dpdk.org; Slava Ovsiienko <viacheslavo@nvidia.com>; NBU- > Contact-Adrien Mazarguil <adrien.mazarguil@6wind.com>; > ferruh.yigit@intel.com; NBU-Contact-Thomas Monjalon > <thomas@monjalon.net>; Raslan Darawsheh <rasland@nvidia.com> > Subject: RE: [dpdk-dev] [PATCH 1/8] lib/librte_ethdev: introduce GENEVE > header TLV option item > > > > > -----Original Message----- > > From: Stephen Hemminger <stephen@networkplumber.org> > > > > On Sun, 27 Dec 2020 18:06:16 +0200 > > Shiri Kuzin <shirik@nvidia.com> wrote: > > > > > +#ifdef PEDANTIC > > > +#pragma GCC diagnostic ignored "-Wpedantic" > > > +#endif > > > > Please do not introduce pragma's for pedantic in standard headers. > > It just clutters the code unnecessarily. The rest of DPDK is not > > guaranteed to be free of pedantic warnings, so starting now is not worth > the mess. > > +1 > > Thanks, > Ori Thank you for the comment. I will update it in the revised patch set. Thanks, Shiri. ^ permalink raw reply [flat|nested] 27+ messages in thread
* [dpdk-dev] [PATCH 2/8] app/testpmd: add GENEVE option item support 2020-12-27 16:06 [dpdk-dev] [PATCH 0/8] ethdev: introduce GENEVE header TLV option item Shiri Kuzin 2020-12-27 16:06 ` [dpdk-dev] [PATCH 1/8] lib/librte_ethdev: " Shiri Kuzin @ 2020-12-27 16:06 ` Shiri Kuzin 2020-12-27 16:06 ` [dpdk-dev] [PATCH 3/8] common/mlx5: check GENEVE TLV support in HCA attributes Shiri Kuzin ` (6 subsequent siblings) 8 siblings, 0 replies; 27+ messages in thread From: Shiri Kuzin @ 2020-12-27 16:06 UTC (permalink / raw) To: dev; +Cc: viacheslavo, adrien.mazarguil, orika, ferruh.yigit, thomas, rasland From: Viacheslav Ovsiienko <viacheslavo@nvidia.com> The patch adds the GENEVE option rte flow item support to command line interpreter. The flow command with GENEVE option items looks like: flow create 0 ingress pattern eth / ipv4 / udp / geneve vni is 100 / geneve-opt class is 99 length is 1 type is 0 data is 0x669988 / end actions drop / end The option length should be specified in 32-bit words, this value specifies the length of the data pattern/mask arrays (should be multiplied by sizeof(uint32_t) to be expressed in bytes. If match on the length itself is not needed the mask should be set to zero, in this case length is used to specify the pattern/mask array lengths only. Signed-off-by: Viacheslav Ovsiienko <viacheslavo@nvidia.com> --- app/test-pmd/cmdline_flow.c | 102 ++++++++++++++++++++++++++-- doc/guides/testpmd_app_ug/testpmd_funcs.rst | 8 +++ 2 files changed, 104 insertions(+), 6 deletions(-) diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c index 585cab9..8bb2cb1 100644 --- a/app/test-pmd/cmdline_flow.c +++ b/app/test-pmd/cmdline_flow.c @@ -283,6 +283,11 @@ enum index { ITEM_ECPRI_MSG_IQ_DATA_PCID, ITEM_ECPRI_MSG_RTC_CTRL_RTCID, ITEM_ECPRI_MSG_DLY_MSR_MSRID, + ITEM_GENEVE_OPT, + ITEM_GENEVE_OPT_CLASS, + ITEM_GENEVE_OPT_TYPE, + ITEM_GENEVE_OPT_LENGTH, + ITEM_GENEVE_OPT_DATA, /* Validate/create actions. */ ACTIONS, @@ -413,6 +418,9 @@ enum index { /** Maximum size for pattern in struct rte_flow_item_raw. */ #define ITEM_RAW_PATTERN_SIZE 40 +/** Maximum size for GENEVE option data pattern in bytes. */ +#define ITEM_GENEVE_OPT_DATA_SIZE 124 + /** Storage size for struct rte_flow_item_raw including pattern. */ #define ITEM_RAW_SIZE \ (sizeof(struct rte_flow_item_raw) + ITEM_RAW_PATTERN_SIZE) @@ -428,7 +436,7 @@ struct action_rss_data { }; /** Maximum data size in struct rte_flow_action_raw_encap. */ -#define ACTION_RAW_ENCAP_MAX_DATA 128 +#define ACTION_RAW_ENCAP_MAX_DATA 512 #define RAW_ENCAP_CONFS_MAX_NUM 8 /** Storage for struct rte_flow_action_raw_encap. */ @@ -658,6 +666,16 @@ struct token { .mask = (const void *)&(const s){ .f = (1 << (b)) - 1 }, \ }) +/** Static initializer for ARGS() to target a field with limits. */ +#define ARGS_ENTRY_BOUNDED(s, f, i, a) \ + (&(const struct arg){ \ + .bounded = 1, \ + .min = (i), \ + .max = (a), \ + .offset = offsetof(s, f), \ + .size = sizeof(((s *)0)->f), \ + }) + /** Static initializer for ARGS() to target an arbitrary bit-mask. */ #define ARGS_ENTRY_MASK(s, f, m) \ (&(const struct arg){ \ @@ -903,6 +921,7 @@ struct parse_action_priv { ITEM_AH, ITEM_PFCP, ITEM_ECPRI, + ITEM_GENEVE_OPT, END_SET, ZERO, }; @@ -1244,6 +1263,15 @@ struct parse_action_priv { ZERO, }; +static const enum index item_geneve_opt[] = { + ITEM_GENEVE_OPT_CLASS, + ITEM_GENEVE_OPT_TYPE, + ITEM_GENEVE_OPT_LENGTH, + ITEM_GENEVE_OPT_DATA, + ITEM_NEXT, + ZERO, +}; + static const enum index next_action[] = { ACTION_END, ACTION_VOID, @@ -3230,6 +3258,47 @@ static int comp_set_sample_index(struct context *, const struct token *, .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ecpri, hdr.type5.msr_id)), }, + [ITEM_GENEVE_OPT] = { + .name = "geneve-opt", + .help = "GENEVE header option", + .priv = PRIV_ITEM(GENEVE_OPT, + sizeof(struct rte_flow_item_geneve_opt) + + ITEM_GENEVE_OPT_DATA_SIZE), + .next = NEXT(item_geneve_opt), + .call = parse_vc, + }, + [ITEM_GENEVE_OPT_CLASS] = { + .name = "class", + .help = "GENEVE option class", + .next = NEXT(item_geneve_opt, NEXT_ENTRY(UNSIGNED), item_param), + .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_geneve_opt, + option_class)), + }, + [ITEM_GENEVE_OPT_TYPE] = { + .name = "type", + .help = "GENEVE option type", + .next = NEXT(item_geneve_opt, NEXT_ENTRY(UNSIGNED), item_param), + .args = ARGS(ARGS_ENTRY(struct rte_flow_item_geneve_opt, + option_type)), + }, + [ITEM_GENEVE_OPT_LENGTH] = { + .name = "length", + .help = "GENEVE option data length (in 32b words)", + .next = NEXT(item_geneve_opt, NEXT_ENTRY(UNSIGNED), item_param), + .args = ARGS(ARGS_ENTRY_BOUNDED( + struct rte_flow_item_geneve_opt, option_len, + 0, 31)), + }, + [ITEM_GENEVE_OPT_DATA] = { + .name = "data", + .help = "GENEVE option data pattern", + .next = NEXT(item_geneve_opt, NEXT_ENTRY(HEX), item_param), + .args = ARGS(ARGS_ENTRY(struct rte_flow_item_geneve_opt, data), + ARGS_ENTRY_ARB(0, 0), + ARGS_ENTRY_ARB + (sizeof(struct rte_flow_item_geneve_opt), + ITEM_GENEVE_OPT_DATA_SIZE)), + }, /* Validate/create actions. */ [ACTIONS] = { .name = "actions", @@ -6482,11 +6551,14 @@ static int comp_set_sample_index(struct context *, const struct token *, ret = snprintf(tmp, sizeof(tmp), "%u", hexlen); if (ret < 0) goto error; - push_args(ctx, arg_len); - ret = parse_int(ctx, token, tmp, ret, NULL, 0); - if (ret < 0) { - pop_args(ctx); - goto error; + /* Save length if requested. */ + if (arg_len->size) { + push_args(ctx, arg_len); + ret = parse_int(ctx, token, tmp, ret, NULL, 0); + if (ret < 0) { + pop_args(ctx); + goto error; + } } buf = (uint8_t *)ctx->object + arg_data->offset; /* Output buffer is not necessarily NUL-terminated. */ @@ -7486,6 +7558,9 @@ static int comp_set_sample_index(struct context *, const struct token *, case RTE_FLOW_ITEM_TYPE_GENEVE: mask = &rte_flow_item_geneve_mask; break; + case RTE_FLOW_ITEM_TYPE_GENEVE_OPT: + mask = &rte_flow_item_geneve_opt_mask; + break; case RTE_FLOW_ITEM_TYPE_PPPOE_PROTO_ID: mask = &rte_flow_item_pppoe_proto_id_mask; break; @@ -7598,6 +7673,8 @@ static int comp_set_sample_index(struct context *, const struct token *, /* process hdr from upper layer to low layer (L3/L4 -> L2). */ data_tail = data + ACTION_RAW_ENCAP_MAX_DATA; for (i = n - 1 ; i >= 0; --i) { + const struct rte_flow_item_geneve_opt *opt; + item = in->args.vc.pattern + i; if (item->spec == NULL) item->spec = flow_item_default_mask(item); @@ -7650,6 +7727,19 @@ static int comp_set_sample_index(struct context *, const struct token *, case RTE_FLOW_ITEM_TYPE_GENEVE: size = sizeof(struct rte_geneve_hdr); break; + case RTE_FLOW_ITEM_TYPE_GENEVE_OPT: + opt = (const struct rte_flow_item_geneve_opt *) + item->spec; + size = sizeof(struct rte_flow_item_geneve_opt) - + sizeof(opt->data); + if (opt->option_len && opt->data) { + *total_size += opt->option_len * + sizeof(uint32_t); + rte_memcpy(data_tail - (*total_size), + opt->data, + opt->option_len * sizeof(uint32_t)); + } + break; case RTE_FLOW_ITEM_TYPE_L2TPV3OIP: size = sizeof(rte_be32_t); proto = 0x73; diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst index 9be4500..37278d3 100644 --- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst +++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst @@ -3680,6 +3680,14 @@ This section lists supported pattern items and their attributes, if any. - ``vni {unsigned}``: virtual network identifier. - ``protocol {unsigned}``: protocol type. +- ``geneve-opt``: match GENEVE header option. + + - ``class {unsigned}``: GENEVE option class. + - ``type {unsigned}``: GENEVE option type. + - ``length {unsigned}``: GENEVE option length in 32-bit words. + - ``data {hex string}``: GENEVE option data, the legnt is defined by + ``length`` field + - ``vxlan-gpe``: match VXLAN-GPE header. - ``vni {unsigned}``: VXLAN-GPE identifier. -- 1.8.3.1 ^ permalink raw reply [flat|nested] 27+ messages in thread
* [dpdk-dev] [PATCH 3/8] common/mlx5: check GENEVE TLV support in HCA attributes 2020-12-27 16:06 [dpdk-dev] [PATCH 0/8] ethdev: introduce GENEVE header TLV option item Shiri Kuzin 2020-12-27 16:06 ` [dpdk-dev] [PATCH 1/8] lib/librte_ethdev: " Shiri Kuzin 2020-12-27 16:06 ` [dpdk-dev] [PATCH 2/8] app/testpmd: add GENEVE option item support Shiri Kuzin @ 2020-12-27 16:06 ` Shiri Kuzin 2020-12-27 16:06 ` [dpdk-dev] [PATCH 4/8] common/mlx5: create GENEVE TLV option object with DevX Shiri Kuzin ` (5 subsequent siblings) 8 siblings, 0 replies; 27+ messages in thread From: Shiri Kuzin @ 2020-12-27 16:06 UTC (permalink / raw) To: dev; +Cc: viacheslavo, adrien.mazarguil, orika, ferruh.yigit, thomas, rasland This is preparation step to support match on GENEVE TLV option. In this Patch we add the HCA attributes that will allow supporting GENEVE TLV option matching. Signed-off-by: Shiri Kuzin <shirik@nvidia.com> --- drivers/common/mlx5/mlx5_devx_cmds.c | 7 +++++++ drivers/common/mlx5/mlx5_devx_cmds.h | 4 ++++ drivers/common/mlx5/mlx5_prm.h | 28 +++++++++++++++++++++++++--- 3 files changed, 36 insertions(+), 3 deletions(-) diff --git a/drivers/common/mlx5/mlx5_devx_cmds.c b/drivers/common/mlx5/mlx5_devx_cmds.c index 9c1d188..a6d052d 100644 --- a/drivers/common/mlx5/mlx5_devx_cmds.c +++ b/drivers/common/mlx5/mlx5_devx_cmds.c @@ -693,6 +693,10 @@ struct mlx5_devx_obj * attr->eth_virt = MLX5_GET(cmd_hca_cap, hcattr, eth_virt); attr->flex_parser_protocols = MLX5_GET(cmd_hca_cap, hcattr, flex_parser_protocols); + attr->max_geneve_tlv_options = MLX5_GET(cmd_hca_cap, hcattr, + max_geneve_tlv_options); + attr->max_geneve_tlv_option_data_len = MLX5_GET(cmd_hca_cap, hcattr, + max_geneve_tlv_option_data_len); attr->qos.sup = MLX5_GET(cmd_hca_cap, hcattr, qos); attr->vdpa.valid = !!(MLX5_GET64(cmd_hca_cap, hcattr, general_obj_types) & @@ -720,6 +724,9 @@ struct mlx5_devx_obj * attr->flow_hit_aso = !!(MLX5_GET64(cmd_hca_cap, hcattr, general_obj_types) & MLX5_GENERAL_OBJ_TYPES_CAP_FLOW_HIT_ASO); + attr->geneve_tlv_opt = !!(MLX5_GET64(cmd_hca_cap, hcattr, + general_obj_types) & + MLX5_GENERAL_OBJ_TYPES_CAP_GENEVE_TLV_OPT); if (attr->qos.sup) { MLX5_SET(query_hca_cap_in, in, op_mod, MLX5_GET_HCA_CAP_OP_MOD_QOS_CAP | diff --git a/drivers/common/mlx5/mlx5_devx_cmds.h b/drivers/common/mlx5/mlx5_devx_cmds.h index 726e9f5..58e619f 100644 --- a/drivers/common/mlx5/mlx5_devx_cmds.h +++ b/drivers/common/mlx5/mlx5_devx_cmds.h @@ -96,6 +96,8 @@ struct mlx5_hca_attr { uint32_t lro_timer_supported_periods[MLX5_LRO_NUM_SUPP_PERIODS]; uint16_t lro_min_mss_size; uint32_t flex_parser_protocols; + uint32_t max_geneve_tlv_options; + uint32_t max_geneve_tlv_option_data_len; uint32_t hairpin:1; uint32_t log_max_hairpin_queues:5; uint32_t log_max_hairpin_wq_data_sz:5; @@ -115,6 +117,7 @@ struct mlx5_hca_attr { uint32_t regex:1; uint32_t regexp_num_of_engines; uint32_t log_max_ft_sampler_num:8; + uint32_t geneve_tlv_opt; struct mlx5_hca_qos_attr qos; struct mlx5_hca_vdpa_attr vdpa; }; @@ -469,6 +472,7 @@ struct mlx5_devx_obj *mlx5_devx_cmd_create_flex_parser(void *ctx, __rte_internal int mlx5_devx_cmd_register_read(void *ctx, uint16_t reg_id, uint32_t arg, uint32_t *data, uint32_t dw_cnt); + /** * Create virtio queue counters object DevX API. * diff --git a/drivers/common/mlx5/mlx5_prm.h b/drivers/common/mlx5/mlx5_prm.h index 58d1804..c4fa395 100644 --- a/drivers/common/mlx5/mlx5_prm.h +++ b/drivers/common/mlx5/mlx5_prm.h @@ -787,7 +787,7 @@ struct mlx5_ifc_fte_match_set_misc3_bits { u8 icmp_code[0x8]; u8 icmpv6_type[0x8]; u8 icmpv6_code[0x8]; - u8 reserved_at_120[0x20]; + u8 geneve_tlv_option_0_data[0x20]; u8 gtpu_teid[0x20]; u8 gtpu_msg_type[0x08]; u8 gtpu_msg_flags[0x08]; @@ -1065,6 +1065,8 @@ enum { (1ULL << MLX5_GENERAL_OBJ_TYPE_FLEX_PARSE_GRAPH) #define MLX5_GENERAL_OBJ_TYPES_CAP_FLOW_HIT_ASO \ (1ULL << MLX5_GENERAL_OBJ_TYPE_FLOW_HIT_ASO) +#define MLX5_GENERAL_OBJ_TYPES_CAP_GENEVE_TLV_OPT \ + (1ULL << MLX5_OBJ_TYPE_GENEVE_TLV_OPT) enum { MLX5_HCA_CAP_OPMOD_GET_MAX = 0, @@ -1363,8 +1365,10 @@ struct mlx5_ifc_cmd_hca_cap_bits { u8 reserved_at_500[0x20]; u8 num_of_uars_per_page[0x20]; u8 flex_parser_protocols[0x20]; - u8 reserved_at_560[0x20]; - u8 reserved_at_580[0x3c]; + u8 max_geneve_tlv_options[0x8]; + u8 reserved_at_568[0x3]; + u8 max_geneve_tlv_option_data_len[0x5]; + u8 reserved_at_570[0x4c]; u8 mini_cqe_resp_stride_index[0x1]; u8 cqe_128_always[0x1]; u8 cqe_compression_128[0x1]; @@ -2232,6 +2236,7 @@ struct mlx5_ifc_create_cq_in_bits { }; enum { + MLX5_OBJ_TYPE_GENEVE_TLV_OPT = 0x000b, MLX5_GENERAL_OBJ_TYPE_VIRTQ = 0x000d, MLX5_GENERAL_OBJ_TYPE_VIRTIO_Q_COUNTERS = 0x001c, MLX5_GENERAL_OBJ_TYPE_FLEX_PARSE_GRAPH = 0x0022, @@ -2266,6 +2271,17 @@ struct mlx5_ifc_virtio_q_counters_bits { u8 reserved_at_180[0x50]; }; +struct mlx5_ifc_geneve_tlv_option_bits { + u8 modify_field_select[0x40]; + u8 reserved_at_40[0x18]; + u8 geneve_option_fte_index[0x8]; + u8 option_class[0x10]; + u8 option_type[0x8]; + u8 reserved_at_78[0x3]; + u8 option_data_length[0x5]; + u8 reserved_at_80[0x180]; +}; + struct mlx5_ifc_create_virtio_q_counters_in_bits { struct mlx5_ifc_general_obj_in_cmd_hdr_bits hdr; struct mlx5_ifc_virtio_q_counters_bits virtio_q_counters; @@ -2275,6 +2291,12 @@ struct mlx5_ifc_query_virtio_q_counters_out_bits { struct mlx5_ifc_general_obj_in_cmd_hdr_bits hdr; struct mlx5_ifc_virtio_q_counters_bits virtio_q_counters; }; + +struct mlx5_ifc_create_geneve_tlv_option_in_bits { + struct mlx5_ifc_general_obj_in_cmd_hdr_bits hdr; + struct mlx5_ifc_geneve_tlv_option_bits geneve_tlv_opt; +}; + enum { MLX5_VIRTQ_STATE_INIT = 0, MLX5_VIRTQ_STATE_RDY = 1, -- 1.8.3.1 ^ permalink raw reply [flat|nested] 27+ messages in thread
* [dpdk-dev] [PATCH 4/8] common/mlx5: create GENEVE TLV option object with DevX 2020-12-27 16:06 [dpdk-dev] [PATCH 0/8] ethdev: introduce GENEVE header TLV option item Shiri Kuzin ` (2 preceding siblings ...) 2020-12-27 16:06 ` [dpdk-dev] [PATCH 3/8] common/mlx5: check GENEVE TLV support in HCA attributes Shiri Kuzin @ 2020-12-27 16:06 ` Shiri Kuzin 2020-12-27 16:06 ` [dpdk-dev] [PATCH 5/8] net/mlx5: create GENEVE TLV option management Shiri Kuzin ` (4 subsequent siblings) 8 siblings, 0 replies; 27+ messages in thread From: Shiri Kuzin @ 2020-12-27 16:06 UTC (permalink / raw) To: dev; +Cc: viacheslavo, adrien.mazarguil, orika, ferruh.yigit, thomas, rasland TLV object is a special firmware maintained entity used to support match on GENEVE header extension option. The TLV object is created with DevX API and accepts the option class, type and lehgth fields. The class type and length fields are set using MLX5_SET and the Devx object is created using mlx5 glue function. Signed-off-by: Shiri Kuzin <shirik@nvidia.com> --- drivers/common/mlx5/mlx5_devx_cmds.c | 54 ++++++++++++++++++++++++++++++++++++ drivers/common/mlx5/mlx5_devx_cmds.h | 5 ++++ drivers/common/mlx5/version.map | 1 + 3 files changed, 60 insertions(+) diff --git a/drivers/common/mlx5/mlx5_devx_cmds.c b/drivers/common/mlx5/mlx5_devx_cmds.c index a6d052d..b5808a9 100644 --- a/drivers/common/mlx5/mlx5_devx_cmds.c +++ b/drivers/common/mlx5/mlx5_devx_cmds.c @@ -2051,3 +2051,57 @@ struct mlx5_devx_obj * flow_hit_aso_obj->id = MLX5_GET(general_obj_out_cmd_hdr, out, obj_id); return flow_hit_aso_obj; } + +/** + * Create general object of type GENEVE TLV option using DevX API. + * + * @param[in] ctx + * Context returned from mlx5 open_device() glue function. + * @param [in] class + * TLV option variable value of class + * @param [in] type + * TLV option variable value of type + * @param [in] len + * TLV option variable value of len + * + * @return + * The DevX object created, NULL otherwise and rte_errno is set. + */ +struct mlx5_devx_obj * +mlx5_devx_cmd_create_geneve_tlv_option(void *ctx, + uint16_t class, uint8_t type, uint8_t len) +{ + uint32_t in[MLX5_ST_SZ_DW(create_geneve_tlv_option_in)] = {0}; + uint32_t out[MLX5_ST_SZ_DW(general_obj_out_cmd_hdr)] = {0}; + struct mlx5_devx_obj *geneve_tlv_opt_obj = mlx5_malloc(MLX5_MEM_ZERO, + sizeof(*geneve_tlv_opt_obj), + 0, SOCKET_ID_ANY); + + if (!geneve_tlv_opt_obj) { + DRV_LOG(ERR, "Failed to allocate geneve tlv option object."); + rte_errno = ENOMEM; + return NULL; + } + void *hdr = MLX5_ADDR_OF(create_geneve_tlv_option_in, in, hdr); + void *opt = MLX5_ADDR_OF(create_geneve_tlv_option_in, in, + geneve_tlv_opt); + MLX5_SET(general_obj_in_cmd_hdr, hdr, opcode, + MLX5_CMD_OP_CREATE_GENERAL_OBJECT); + MLX5_SET(general_obj_in_cmd_hdr, hdr, obj_type, + MLX5_OBJ_TYPE_GENEVE_TLV_OPT); + MLX5_SET(geneve_tlv_option, opt, option_class, + rte_be_to_cpu_16(class)); + MLX5_SET(geneve_tlv_option, opt, option_type, type); + MLX5_SET(geneve_tlv_option, opt, option_data_length, len); + geneve_tlv_opt_obj->obj = mlx5_glue->devx_obj_create(ctx, in, + sizeof(in), out, sizeof(out)); + if (!geneve_tlv_opt_obj->obj) { + rte_errno = errno; + DRV_LOG(ERR, "Failed to create Geneve tlv option " + "Obj using DevX."); + mlx5_free(geneve_tlv_opt_obj); + return NULL; + } + geneve_tlv_opt_obj->id = MLX5_GET(general_obj_out_cmd_hdr, out, obj_id); + return geneve_tlv_opt_obj; +} diff --git a/drivers/common/mlx5/mlx5_devx_cmds.h b/drivers/common/mlx5/mlx5_devx_cmds.h index 58e619f..73c1dfd 100644 --- a/drivers/common/mlx5/mlx5_devx_cmds.h +++ b/drivers/common/mlx5/mlx5_devx_cmds.h @@ -473,6 +473,11 @@ struct mlx5_devx_obj *mlx5_devx_cmd_create_flex_parser(void *ctx, int mlx5_devx_cmd_register_read(void *ctx, uint16_t reg_id, uint32_t arg, uint32_t *data, uint32_t dw_cnt); +__rte_internal +struct mlx5_devx_obj * +mlx5_devx_cmd_create_geneve_tlv_option(void *ctx, + uint16_t class, uint8_t type, uint8_t len); + /** * Create virtio queue counters object DevX API. * diff --git a/drivers/common/mlx5/version.map b/drivers/common/mlx5/version.map index 17dd11f..3c403d2 100644 --- a/drivers/common/mlx5/version.map +++ b/drivers/common/mlx5/version.map @@ -22,6 +22,7 @@ INTERNAL { mlx5_devx_cmd_create_virtio_q_counters; mlx5_devx_cmd_create_virtq; mlx5_devx_cmd_create_flow_hit_aso_obj; + mlx5_devx_cmd_create_geneve_tlv_option; mlx5_devx_cmd_destroy; mlx5_devx_cmd_flow_counter_alloc; mlx5_devx_cmd_flow_counter_query; -- 1.8.3.1 ^ permalink raw reply [flat|nested] 27+ messages in thread
* [dpdk-dev] [PATCH 5/8] net/mlx5: create GENEVE TLV option management 2020-12-27 16:06 [dpdk-dev] [PATCH 0/8] ethdev: introduce GENEVE header TLV option item Shiri Kuzin ` (3 preceding siblings ...) 2020-12-27 16:06 ` [dpdk-dev] [PATCH 4/8] common/mlx5: create GENEVE TLV option object with DevX Shiri Kuzin @ 2020-12-27 16:06 ` Shiri Kuzin 2020-12-27 16:06 ` [dpdk-dev] [PATCH 6/8] net/mlx5: add GENEVE TLV option flow validation Shiri Kuzin ` (3 subsequent siblings) 8 siblings, 0 replies; 27+ messages in thread From: Shiri Kuzin @ 2020-12-27 16:06 UTC (permalink / raw) To: dev; +Cc: viacheslavo, adrien.mazarguil, orika, ferruh.yigit, thomas, rasland Currently firmware supports the only TLV object per device to match on the GENEVE header option. This patch adds the simple TLV object management to the mlx5 PMD. Signed-off-by: Shiri Kuzin <shirik@nvidia.com> --- drivers/net/mlx5/mlx5.c | 2 + drivers/net/mlx5/mlx5.h | 13 +++++ drivers/net/mlx5/mlx5_flow.h | 4 ++ drivers/net/mlx5/mlx5_flow_dv.c | 108 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 127 insertions(+) diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c index 52a8a25..4ed3730 100644 --- a/drivers/net/mlx5/mlx5.c +++ b/drivers/net/mlx5/mlx5.c @@ -1013,6 +1013,7 @@ struct mlx5_dev_ctx_shared * rte_rwlock_write_unlock(&mlx5_shared_data->mem_event_rwlock); /* Add context to the global device list. */ LIST_INSERT_HEAD(&mlx5_dev_ctx_list, sh, next); + rte_spinlock_init(&sh->geneve_tlv_opt_sl); exit: pthread_mutex_unlock(&mlx5_dev_ctx_list_mutex); return sh; @@ -1108,6 +1109,7 @@ struct mlx5_dev_ctx_shared * mlx5_glue->devx_free_uar(sh->devx_rx_uar); if (sh->ctx) claim_zero(mlx5_glue->close_device(sh->ctx)); + MLX5_ASSERT(sh->geneve_tlv_option_resource == NULL); pthread_mutex_destroy(&sh->txpp.mutex); mlx5_free(sh); return; diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h index 121d726..923f7cb 100644 --- a/drivers/net/mlx5/mlx5.h +++ b/drivers/net/mlx5/mlx5.h @@ -535,6 +535,16 @@ struct mlx5_aso_age_mng { struct mlx5_aso_sq aso_sq; /* ASO queue objects. */ }; +/* Management structure for geneve tlv option */ +struct mlx5_geneve_tlv_option_resource { + struct mlx5_devx_obj *obj; /* Pointer to the geneve tlv opt object. */ + rte_be16_t option_class; /* geneve tlv opt class.*/ + uint8_t option_type; /* geneve tlv opt type.*/ + uint8_t length; /* geneve tlv opt length. */ + uint32_t refcnt; /* geneve tlv object reference counter */ +}; + + #define MLX5_AGE_EVENT_NEW 1 #define MLX5_AGE_TRIGGER 2 #define MLX5_AGE_SET(age_info, BIT) \ @@ -747,6 +757,9 @@ struct mlx5_dev_ctx_shared { void *devx_rx_uar; /* DevX UAR for Rx. */ struct mlx5_aso_age_mng *aso_age_mng; /* Management data for aging mechanism using ASO Flow Hit. */ + struct mlx5_geneve_tlv_option_resource *geneve_tlv_option_resource; + /* Management structure for geneve tlv option */ + rte_spinlock_t geneve_tlv_opt_sl; /* Lock for geneve tlv resource */ struct mlx5_dev_shared_port port[]; /* per device port data array. */ }; diff --git a/drivers/net/mlx5/mlx5_flow.h b/drivers/net/mlx5/mlx5_flow.h index d85dd19..d8a6688 100644 --- a/drivers/net/mlx5/mlx5_flow.h +++ b/drivers/net/mlx5/mlx5_flow.h @@ -1048,6 +1048,7 @@ struct rte_flow { uint32_t counter; /**< Holds flow counter. */ uint32_t tunnel_id; /**< Tunnel id */ uint32_t age; /**< Holds ASO age bit index. */ + uint32_t geneve_tlv_option; /**< Holds Geneve TLV option id. > */ } __rte_packed; /* @@ -1505,4 +1506,7 @@ void flow_dv_dest_array_remove_cb(struct mlx5_cache_list *list, struct mlx5_cache_entry *entry); struct mlx5_aso_age_action *flow_aso_age_get_by_idx(struct rte_eth_dev *dev, uint32_t age_idx); +int flow_dev_geneve_tlv_option_resource_register(struct rte_eth_dev *dev, + const struct rte_flow_item *item, + struct rte_flow_error *error); #endif /* RTE_PMD_MLX5_FLOW_H_ */ diff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c index 4f638e2..3dcb87a 100644 --- a/drivers/net/mlx5/mlx5_flow_dv.c +++ b/drivers/net/mlx5/mlx5_flow_dv.c @@ -7224,6 +7224,90 @@ struct mlx5_hlist_entry * } /** + * Create Geneve TLV option resource. + * + * @param dev[in, out] + * Pointer to rte_eth_dev structure. + * @param[in, out] tag_be24 + * Tag value in big endian then R-shift 8. + * @parm[in, out] dev_flow + * Pointer to the dev_flow. + * @param[out] error + * pointer to error structure. + * + * @return + * 0 on success otherwise -errno and errno is set. + */ + +int +flow_dev_geneve_tlv_option_resource_register(struct rte_eth_dev *dev, + const struct rte_flow_item *item, + struct rte_flow_error *error) +{ + struct mlx5_priv *priv = dev->data->dev_private; + struct mlx5_dev_ctx_shared *sh = priv->sh; + struct mlx5_geneve_tlv_option_resource *geneve_opt_resource = + sh->geneve_tlv_option_resource; + struct mlx5_devx_obj *obj; + const struct rte_flow_item_geneve_opt *geneve_opt_v = item->spec; + int ret = 0; + + if (!geneve_opt_v) + return -1; + rte_spinlock_lock(&sh->geneve_tlv_opt_sl); + if (geneve_opt_resource != NULL) { + if (geneve_opt_resource->option_class == + geneve_opt_v->option_class && + geneve_opt_resource->option_type == + geneve_opt_v->option_type && + geneve_opt_resource->length == + geneve_opt_v->option_len) { + /* We already have GENVE TLV option obj allocated. */ + __atomic_fetch_add(&geneve_opt_resource->refcnt, 1, + __ATOMIC_RELAXED); + } else { + ret = rte_flow_error_set(error, ENOMEM, + RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL, + "Only one GENEVE TLV option supported"); + goto exit; + } + } else { + /* Create a GENEVE TLV object and resource. */ + obj = mlx5_devx_cmd_create_geneve_tlv_option(sh->ctx, + geneve_opt_v->option_class, + geneve_opt_v->option_type, + geneve_opt_v->option_len); + if (!obj) { + ret = rte_flow_error_set(error, ENODATA, + RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL, + "Failed to create GENEVE TLV Devx object"); + goto exit; + } + sh->geneve_tlv_option_resource = + mlx5_malloc(MLX5_MEM_ZERO, + sizeof(*geneve_opt_resource), + 0, SOCKET_ID_ANY); + if (!sh->geneve_tlv_option_resource) { + claim_zero(mlx5_devx_cmd_destroy(obj)); + ret = rte_flow_error_set(error, ENOMEM, + RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL, + "GENEVE TLV object memory allocation failed"); + goto exit; + } + geneve_opt_resource = sh->geneve_tlv_option_resource; + geneve_opt_resource->obj = obj; + geneve_opt_resource->option_class = geneve_opt_v->option_class; + geneve_opt_resource->option_type = geneve_opt_v->option_type; + geneve_opt_resource->length = geneve_opt_v->option_len; + __atomic_store_n(&geneve_opt_resource->refcnt, 1, + __ATOMIC_RELAXED); + } +exit: + rte_spinlock_unlock(&sh->geneve_tlv_opt_sl); + return ret; +} + +/** * Add MPLS item to matcher and to the value. * * @param[in, out] matcher @@ -11212,6 +11296,26 @@ struct mlx5_cache_entry * &cache->entry); } +static void +flow_dv_geneve_tlv_option_resource_release(struct rte_eth_dev *dev) +{ + struct mlx5_priv *priv = dev->data->dev_private; + struct mlx5_dev_ctx_shared *sh = priv->sh; + struct mlx5_geneve_tlv_option_resource *geneve_opt_resource = + sh->geneve_tlv_option_resource; + rte_spinlock_lock(&sh->geneve_tlv_opt_sl); + if (geneve_opt_resource) { + if (!(__atomic_sub_fetch(&geneve_opt_resource->refcnt, 1, + __ATOMIC_RELAXED))) { + claim_zero(mlx5_devx_cmd_destroy + (geneve_opt_resource->obj)); + mlx5_free(sh->geneve_tlv_option_resource); + sh->geneve_tlv_option_resource = NULL; + } + } + rte_spinlock_unlock(&sh->geneve_tlv_opt_sl); +} + /** * Remove the flow from the NIC but keeps it in memory. * Lock free, (mutex should be acquired by caller). @@ -11281,6 +11385,10 @@ struct mlx5_cache_entry * } if (flow->age) flow_dv_aso_age_release(dev, flow->age); + if (flow->geneve_tlv_option) { + flow_dv_geneve_tlv_option_resource_release(dev); + flow->geneve_tlv_option = 0; + } while (flow->dev_handles) { uint32_t tmp_idx = flow->dev_handles; -- 1.8.3.1 ^ permalink raw reply [flat|nested] 27+ messages in thread
* [dpdk-dev] [PATCH 6/8] net/mlx5: add GENEVE TLV option flow validation 2020-12-27 16:06 [dpdk-dev] [PATCH 0/8] ethdev: introduce GENEVE header TLV option item Shiri Kuzin ` (4 preceding siblings ...) 2020-12-27 16:06 ` [dpdk-dev] [PATCH 5/8] net/mlx5: create GENEVE TLV option management Shiri Kuzin @ 2020-12-27 16:06 ` Shiri Kuzin 2020-12-27 16:06 ` [dpdk-dev] [PATCH 7/8] net/mlx5: add GENEVE TLV option flow translation Shiri Kuzin ` (2 subsequent siblings) 8 siblings, 0 replies; 27+ messages in thread From: Shiri Kuzin @ 2020-12-27 16:06 UTC (permalink / raw) To: dev; +Cc: viacheslavo, adrien.mazarguil, orika, ferruh.yigit, thomas, rasland This patch adds validation routine for the GENEVE header TLV option. The GENEVE TLV option match must include all fields with full masks due to NIC does not support masking on option class, type and length. The option data length must be non zero and provided data pattern should be zero neither due to hardware limitations. Signed-off-by: Shiri Kuzin <shirik@nvidia.com> --- drivers/net/mlx5/mlx5_flow.c | 120 ++++++++++++++++++++++++++++++++++++++++ drivers/net/mlx5/mlx5_flow.h | 7 +++ drivers/net/mlx5/mlx5_flow_dv.c | 10 +++- 3 files changed, 136 insertions(+), 1 deletion(-) diff --git a/drivers/net/mlx5/mlx5_flow.c b/drivers/net/mlx5/mlx5_flow.c index 82e24d7..eaf777b 100644 --- a/drivers/net/mlx5/mlx5_flow.c +++ b/drivers/net/mlx5/mlx5_flow.c @@ -2603,6 +2603,126 @@ struct mlx5_flow_tunnel_info { } /** + * Validate Geneve TLV option item. + * + * @param[in] item + * Item specification. + * @param[in] last_item + * Previous validated item in the pattern items. + * @param[in] dev + * Pointer to the rte_eth_dev structure. + * @param[out] error + * Pointer to error structure. + * + * @return + * 0 on success, a negative errno value otherwise and rte_errno is set. + */ +int +mlx5_flow_validate_item_geneve_opt(const struct rte_flow_item *item, + uint64_t last_item, + struct rte_eth_dev *dev, + struct rte_flow_error *error) +{ + struct mlx5_priv *priv = dev->data->dev_private; + struct mlx5_dev_ctx_shared *sh = priv->sh; + struct mlx5_geneve_tlv_option_resource *geneve_opt_resource; + struct mlx5_hca_attr *hca_attr = &priv->config.hca_attr; + uint8_t data_max_supported = + hca_attr->max_geneve_tlv_option_data_len * 4; + struct mlx5_dev_config *config = &priv->config; + const struct rte_flow_item_geneve_opt *spec = item->spec; + const struct rte_flow_item_geneve_opt *mask = item->mask; + unsigned int i; + unsigned int data_len; + const struct rte_flow_item_geneve_opt full_mask = { + .option_class = RTE_BE16(0xffff), + .option_type = 0xff, + .option_len = 0x1f, + }; + + if (!mask) + mask = &rte_flow_item_geneve_opt_mask; + if (!spec) + return rte_flow_error_set + (error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ITEM, item, + "Geneve TLV opt class/type/length must be specified"); + if ((uint32_t)(spec->option_len) > MLX5_GENEVE_OPTLEN_MASK) + return rte_flow_error_set + (error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ITEM, item, + "Geneve TLV opt length exceeeds the limit (31)"); + /* Check if class type and length masks are full. */ + if (full_mask.option_class != mask->option_class || + full_mask.option_type != mask->option_type || + full_mask.option_len != (mask->option_len & full_mask.option_len)) + return rte_flow_error_set + (error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ITEM, item, + "Geneve TLV opt class/type/length masks must be full"); + /* Check if length is supported */ + if ((uint32_t)(spec->option_len) > + config->hca_attr.max_geneve_tlv_option_data_len) + return rte_flow_error_set + (error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ITEM, item, + "Geneve TLV opt length not supported"); + if (config->hca_attr.max_geneve_tlv_options > 1) + DRV_LOG(DEBUG, + "max_geneve_tlv_options supports more than 1 option"); + /* Check GENEVE item preceding. */ + if (!(last_item & MLX5_FLOW_LAYER_GENEVE)) + return rte_flow_error_set + (error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ITEM, item, + "Geneve opt item must be preceded with Geneve item"); + /* Check if length is 0 or data is 0. */ + if (spec->data == NULL || spec->option_len == 0) + return rte_flow_error_set + (error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ITEM, item, + "Geneve TLV opt with zero data/length not supported"); + /* Check not all data & mask are 0. */ + data_len = spec->option_len * 4; + if (mask->data == NULL) { + for (i = 0; i < data_len; i++) + if (spec->data[i]) + break; + if (i == data_len) + return rte_flow_error_set(error, ENOTSUP, + RTE_FLOW_ERROR_TYPE_ITEM, item, + "Can't match on Geneve option data 0"); + } else { + for (i = 0; i < data_len; i++) + if (spec->data[i] & mask->data[i]) + break; + if (i == data_len) + return rte_flow_error_set(error, ENOTSUP, + RTE_FLOW_ERROR_TYPE_ITEM, item, + "Can't match on Geneve option data and mask 0"); + /* Check data mask supported. */ + for (i = data_max_supported; i < data_len ; i++) + if (mask->data[i]) + return rte_flow_error_set(error, ENOTSUP, + RTE_FLOW_ERROR_TYPE_ITEM, item, + "Data mask is of unsupported size"); + } + /* Check GENEVE option is supported in NIC. */ + if (!config->hca_attr.geneve_tlv_opt) + return rte_flow_error_set + (error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ITEM, item, + "Geneve TLV opt not supported"); + /* Check if we already have geneve option with different type/class. */ + rte_spinlock_lock(&sh->geneve_tlv_opt_sl); + geneve_opt_resource = sh->geneve_tlv_option_resource; + if (geneve_opt_resource != NULL) + if (geneve_opt_resource->option_class != spec->option_class || + geneve_opt_resource->option_type != spec->option_type || + geneve_opt_resource->length != spec->option_len) { + rte_spinlock_unlock(&sh->geneve_tlv_opt_sl); + return rte_flow_error_set(error, ENOTSUP, + RTE_FLOW_ERROR_TYPE_ITEM, item, + "Only one Geneve TLV option supported"); + } + rte_spinlock_unlock(&sh->geneve_tlv_opt_sl); + return 0; +} + +/** * Validate MPLS item. * * @param[in] dev diff --git a/drivers/net/mlx5/mlx5_flow.h b/drivers/net/mlx5/mlx5_flow.h index d8a6688..f9b81f5 100644 --- a/drivers/net/mlx5/mlx5_flow.h +++ b/drivers/net/mlx5/mlx5_flow.h @@ -138,6 +138,9 @@ enum mlx5_feature_name { #define MLX5_FLOW_LAYER_OUTER_L3_IPV6_FRAG_EXT (1u << 30) #define MLX5_FLOW_LAYER_INNER_L3_IPV6_FRAG_EXT (1u << 31) +/* Pattern tunnel Layer bits (continued). */ +#define MLX5_FLOW_LAYER_GENEVE_OPT (UINT64_C(1) << 32) + /* Outer Masks. */ #define MLX5_FLOW_LAYER_OUTER_L3 \ (MLX5_FLOW_LAYER_OUTER_L3_IPV4 | MLX5_FLOW_LAYER_OUTER_L3_IPV6) @@ -1398,6 +1401,10 @@ int mlx5_flow_validate_item_geneve(const struct rte_flow_item *item, uint64_t item_flags, struct rte_eth_dev *dev, struct rte_flow_error *error); +int mlx5_flow_validate_item_geneve_opt(const struct rte_flow_item *item, + uint64_t last_item, + struct rte_eth_dev *dev, + struct rte_flow_error *error); int mlx5_flow_validate_item_ecpri(const struct rte_flow_item *item, uint64_t item_flags, uint64_t last_item, diff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c index 3dcb87a..6db2789 100644 --- a/drivers/net/mlx5/mlx5_flow_dv.c +++ b/drivers/net/mlx5/mlx5_flow_dv.c @@ -5501,6 +5501,15 @@ struct mlx5_hlist_entry * return ret; last_item = MLX5_FLOW_LAYER_GENEVE; break; + case RTE_FLOW_ITEM_TYPE_GENEVE_OPT: + ret = mlx5_flow_validate_item_geneve_opt(items, + last_item, + dev, + error); + if (ret < 0) + return ret; + last_item = MLX5_FLOW_LAYER_GENEVE_OPT; + break; case RTE_FLOW_ITEM_TYPE_MPLS: ret = mlx5_flow_validate_item_mpls(dev, items, item_flags, @@ -5509,7 +5518,6 @@ struct mlx5_hlist_entry * return ret; last_item = MLX5_FLOW_LAYER_MPLS; break; - case RTE_FLOW_ITEM_TYPE_MARK: ret = flow_dv_validate_item_mark(dev, items, attr, error); -- 1.8.3.1 ^ permalink raw reply [flat|nested] 27+ messages in thread
* [dpdk-dev] [PATCH 7/8] net/mlx5: add GENEVE TLV option flow translation 2020-12-27 16:06 [dpdk-dev] [PATCH 0/8] ethdev: introduce GENEVE header TLV option item Shiri Kuzin ` (5 preceding siblings ...) 2020-12-27 16:06 ` [dpdk-dev] [PATCH 6/8] net/mlx5: add GENEVE TLV option flow validation Shiri Kuzin @ 2020-12-27 16:06 ` Shiri Kuzin 2020-12-27 16:06 ` [dpdk-dev] [PATCH 8/8] doc: update GENEVE TLV option support Shiri Kuzin 2021-01-05 17:53 ` [dpdk-dev] [PATCH v2 0/8] ethdev: introduce GENEVE header TLV option item Shiri Kuzin 8 siblings, 0 replies; 27+ messages in thread From: Shiri Kuzin @ 2020-12-27 16:06 UTC (permalink / raw) To: dev; +Cc: viacheslavo, adrien.mazarguil, orika, ferruh.yigit, thomas, rasland The GENEVE TLV option matching flows must be created using a translation function. This function checks whether we already created a Devx object for the matching and either creates the objects or updates the reference counter. Signed-off-by: Shiri Kuzin <shirik@nvidia.com> --- drivers/net/mlx5/mlx5_flow_dv.c | 70 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) diff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c index 6db2789..f78622d 100644 --- a/drivers/net/mlx5/mlx5_flow_dv.c +++ b/drivers/net/mlx5/mlx5_flow_dv.c @@ -7316,6 +7316,65 @@ struct mlx5_hlist_entry * } /** + * Add Geneve TLV option item to matcher. + * + * @param[in, out] dev + * Pointer to rte_eth_dev structure. + * @param[in, out] matcher + * Flow matcher. + * @param[in, out] key + * Flow matcher value. + * @param[in] item + * Flow pattern to translate. + * @param[out] error + * Pointer to error structure. + */ +static int +flow_dv_translate_item_geneve_opt(struct rte_eth_dev *dev, void *matcher, + void *key, const struct rte_flow_item *item, + struct rte_flow_error *error) +{ + const struct rte_flow_item_geneve_opt *geneve_opt_m = item->mask; + const struct rte_flow_item_geneve_opt *geneve_opt_v = item->spec; + void *misc3_m = MLX5_ADDR_OF(fte_match_param, matcher, + misc_parameters_3); + void *misc3_v = MLX5_ADDR_OF(fte_match_param, key, misc_parameters_3); + rte_be32_t opt_data_key = 0, opt_data_mask = 0; + int ret = 0; + + if (!geneve_opt_v) + return -1; + if (!geneve_opt_m) + geneve_opt_m = &rte_flow_item_geneve_opt_mask; + ret = flow_dev_geneve_tlv_option_resource_register(dev, item, + error); + if (ret) { + DRV_LOG(ERR, "Failed to create geneve_tlv_obj"); + return ret; + } + /* Set the data. */ + if (geneve_opt_v->data) { + memcpy(&opt_data_key, geneve_opt_v->data, + RTE_MIN((uint32_t)(geneve_opt_v->option_len * 4), + sizeof(opt_data_key))); + MLX5_ASSERT((uint32_t)(geneve_opt_v->option_len * 4) <= + sizeof(opt_data_key)); + memcpy(&opt_data_mask, geneve_opt_m->data, + RTE_MIN((uint32_t)(geneve_opt_v->option_len * 4), + sizeof(opt_data_mask))); + MLX5_ASSERT((uint32_t)(geneve_opt_v->option_len * 4) <= + sizeof(opt_data_mask)); + MLX5_SET(fte_match_set_misc3, misc3_m, + geneve_tlv_option_0_data, + rte_be_to_cpu_32(opt_data_mask)); + MLX5_SET(fte_match_set_misc3, misc3_v, + geneve_tlv_option_0_data, + rte_be_to_cpu_32(opt_data_key & opt_data_mask)); + } + return ret; +} + +/** * Add MPLS item to matcher and to the value. * * @param[in, out] matcher @@ -10559,6 +10618,17 @@ struct mlx5_cache_entry * matcher.priority = MLX5_TUNNEL_PRIO_GET(rss_desc); last_item = MLX5_FLOW_LAYER_GENEVE; break; + case RTE_FLOW_ITEM_TYPE_GENEVE_OPT: + ret = flow_dv_translate_item_geneve_opt(dev, match_mask, + match_value, + items, error); + if (ret) + return rte_flow_error_set(error, -ret, + RTE_FLOW_ERROR_TYPE_ITEM, NULL, + "cannot create GENEVE TLV option"); + flow->geneve_tlv_option = 1; + last_item = MLX5_FLOW_LAYER_GENEVE_OPT; + break; case RTE_FLOW_ITEM_TYPE_MPLS: flow_dv_translate_item_mpls(match_mask, match_value, items, last_item, tunnel); -- 1.8.3.1 ^ permalink raw reply [flat|nested] 27+ messages in thread
* [dpdk-dev] [PATCH 8/8] doc: update GENEVE TLV option support 2020-12-27 16:06 [dpdk-dev] [PATCH 0/8] ethdev: introduce GENEVE header TLV option item Shiri Kuzin ` (6 preceding siblings ...) 2020-12-27 16:06 ` [dpdk-dev] [PATCH 7/8] net/mlx5: add GENEVE TLV option flow translation Shiri Kuzin @ 2020-12-27 16:06 ` Shiri Kuzin 2021-01-05 17:53 ` [dpdk-dev] [PATCH v2 0/8] ethdev: introduce GENEVE header TLV option item Shiri Kuzin 8 siblings, 0 replies; 27+ messages in thread From: Shiri Kuzin @ 2020-12-27 16:06 UTC (permalink / raw) To: dev; +Cc: viacheslavo, adrien.mazarguil, orika, ferruh.yigit, thomas, rasland GENEVE TLV option support added to mlx5 PMD. The limitations and support were updated in documentation. Signed-off-by: Shiri Kuzin <shirik@nvidia.com> --- doc/guides/nics/mlx5.rst | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/doc/guides/nics/mlx5.rst b/doc/guides/nics/mlx5.rst index 3bda0f8..9700fe5 100644 --- a/doc/guides/nics/mlx5.rst +++ b/doc/guides/nics/mlx5.rst @@ -98,6 +98,7 @@ Features - Hardware LRO. - Hairpin. - Multiple-thread flow insertion. +- Matching on Geneve TLV option header with raw encap/decap action. Limitations ----------- @@ -175,7 +176,18 @@ Limitations - OAM - protocol type - options length - Currently, the only supported options length value is 0. + +- Match on Geneve TLv option is supported on the following fields: + - Class + - Type + - Length + - Data + + Only one Class/Type/Length Geneve TLV option is supported per shared device. + Class/Type/Length fields must be specified as well as masks. + Class/Type/Length specified masks must be full. + Matching Geneve TLV option without specifying data is not supported. + Matching Geneve TLV option with data & mask == 0 is not supported. - VF: flow rules created on VF devices can only match traffic targeted at the configured MAC addresses (see ``rte_eth_dev_mac_addr_add()``). @@ -1022,6 +1034,10 @@ Below are some firmware configurations listed. or FLEX_PARSER_PROFILE_ENABLE=1 +- enable Geneve TLV option flow matching:: + + FLEX_PARSER_PROFILE_ENABLE=0 + - enable GTP flow matching:: FLEX_PARSER_PROFILE_ENABLE=3 -- 1.8.3.1 ^ permalink raw reply [flat|nested] 27+ messages in thread
* [dpdk-dev] [PATCH v2 0/8] ethdev: introduce GENEVE header TLV option item 2020-12-27 16:06 [dpdk-dev] [PATCH 0/8] ethdev: introduce GENEVE header TLV option item Shiri Kuzin ` (7 preceding siblings ...) 2020-12-27 16:06 ` [dpdk-dev] [PATCH 8/8] doc: update GENEVE TLV option support Shiri Kuzin @ 2021-01-05 17:53 ` Shiri Kuzin 2021-01-05 17:53 ` [dpdk-dev] [PATCH v2 1/8] lib/librte_ethdev: " Shiri Kuzin ` (7 more replies) 8 siblings, 8 replies; 27+ messages in thread From: Shiri Kuzin @ 2021-01-05 17:53 UTC (permalink / raw) To: dev; +Cc: viacheslavo, adrien.mazarguil, orika, ferruh.yigit, thomas, rasland The Geneve tunneling protocol is designed to allow the user to specify some data context on the packet. The GENEVE TLV (Type-Length-Variable) Option is the mean intended to present the user data. In order to support GENEVE TLV Option the new rte_flow item "rte_flow_item_geneve_opt" is introduced. The new item contains the values and masks for the following fields: -option class -option type -length -data The usage example: "flow create 0 ingress pattern eth / ipv4 / udp / geneve vni is 100 / geneve-opt class is 5 length is 1 type is 0 data is 0x66998800 / end actions count / drop / end" New item will be added to testpmd to support raw encap/decap action. Shiri Kuzin (7): lib/librte_ethdev: introduce GENEVE header TLV option item common/mlx5: check GENEVE TLV support in HCA attributes common/mlx5: create GENEVE TLV option object with DevX net/mlx5: create GENEVE TLV option management net/mlx5: add GENEVE TLV option flow validation net/mlx5: add GENEVE TLV option flow translation doc: update GENEVE TLV option support Viacheslav Ovsiienko (1): app/testpmd: add GENEVE option item support app/test-pmd/cmdline_flow.c | 102 ++++++++++- doc/guides/nics/mlx5.rst | 18 +- doc/guides/rel_notes/release_21_02.rst | 8 + doc/guides/testpmd_app_ug/testpmd_funcs.rst | 8 + drivers/common/mlx5/mlx5_devx_cmds.c | 63 ++++++- drivers/common/mlx5/mlx5_devx_cmds.h | 9 + drivers/common/mlx5/mlx5_prm.h | 28 ++- drivers/common/mlx5/version.map | 1 + drivers/net/mlx5/mlx5.c | 2 + drivers/net/mlx5/mlx5.h | 13 ++ drivers/net/mlx5/mlx5_flow.c | 120 +++++++++++++ drivers/net/mlx5/mlx5_flow.h | 11 ++ drivers/net/mlx5/mlx5_flow_dv.c | 188 +++++++++++++++++++- lib/librte_ethdev/rte_flow.c | 1 + lib/librte_ethdev/rte_flow.h | 27 +++ 15 files changed, 587 insertions(+), 12 deletions(-) -- 2.21.0 ^ permalink raw reply [flat|nested] 27+ messages in thread
* [dpdk-dev] [PATCH v2 1/8] lib/librte_ethdev: introduce GENEVE header TLV option item 2021-01-05 17:53 ` [dpdk-dev] [PATCH v2 0/8] ethdev: introduce GENEVE header TLV option item Shiri Kuzin @ 2021-01-05 17:53 ` Shiri Kuzin 2021-01-05 17:53 ` [dpdk-dev] [PATCH v2 2/8] app/testpmd: add GENEVE option item support Shiri Kuzin ` (6 subsequent siblings) 7 siblings, 0 replies; 27+ messages in thread From: Shiri Kuzin @ 2021-01-05 17:53 UTC (permalink / raw) To: dev; +Cc: viacheslavo, adrien.mazarguil, orika, ferruh.yigit, thomas, rasland The Geneve tunneling protocol is designed to allow the user to specify some data context on the packet. The GENEVE TLV (Type-Length-Variable) Option is the mean intended to present the user data. In order to support GENEVE TLV Option the new rte_flow item "rte_flow_item_geneve_opt" is added. The new item contains the values and masks for the following fields: -option class -option type -length -data New item will be added to testpmd to support match and raw encap/decap actions. Signed-off-by: Shiri Kuzin <shirik@nvidia.com> --- lib/librte_ethdev/rte_flow.c | 1 + lib/librte_ethdev/rte_flow.h | 27 +++++++++++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/lib/librte_ethdev/rte_flow.c b/lib/librte_ethdev/rte_flow.c index a06f64c271..2af7d965e1 100644 --- a/lib/librte_ethdev/rte_flow.c +++ b/lib/librte_ethdev/rte_flow.c @@ -97,6 +97,7 @@ static const struct rte_flow_desc_data rte_flow_desc_item[] = { MK_FLOW_ITEM(L2TPV3OIP, sizeof(struct rte_flow_item_l2tpv3oip)), MK_FLOW_ITEM(PFCP, sizeof(struct rte_flow_item_pfcp)), MK_FLOW_ITEM(ECPRI, sizeof(struct rte_flow_item_ecpri)), + MK_FLOW_ITEM(GENEVE_OPT, sizeof(struct rte_flow_item_geneve_opt)), }; /** Generate flow_action[] entry. */ diff --git a/lib/librte_ethdev/rte_flow.h b/lib/librte_ethdev/rte_flow.h index 0977a78270..11a6494b8e 100644 --- a/lib/librte_ethdev/rte_flow.h +++ b/lib/librte_ethdev/rte_flow.h @@ -543,6 +543,14 @@ enum rte_flow_item_type { * See struct rte_flow_item_ipv6_frag_ext. */ RTE_FLOW_ITEM_TYPE_IPV6_FRAG_EXT, + + /** + * Matches Geneve Variable Length Option + * + * See struct rte_flow_item_geneve_opt + */ + RTE_FLOW_ITEM_TYPE_GENEVE_OPT, + }; /** @@ -1627,6 +1635,25 @@ static const struct rte_flow_item_ecpri rte_flow_item_ecpri_mask = { }; #endif +/** + * RTE_FLOW_ITEM_TYPE_GENEVE_OPT + * + * Matches a GENEVE Variable Length Option + */ +struct rte_flow_item_geneve_opt { + rte_be16_t option_class; + uint8_t option_type; + uint8_t option_len; + uint32_t *data; +}; + +/** Default mask for RTE_FLOW_ITEM_TYPE_GENEVE_OPT. */ +#ifndef __cplusplus +static const struct rte_flow_item_geneve_opt +rte_flow_item_geneve_opt_mask = { + .option_type = 0xff, +}; +#endif /** * Matching pattern item definition. * -- 2.21.0 ^ permalink raw reply [flat|nested] 27+ messages in thread
* [dpdk-dev] [PATCH v2 2/8] app/testpmd: add GENEVE option item support 2021-01-05 17:53 ` [dpdk-dev] [PATCH v2 0/8] ethdev: introduce GENEVE header TLV option item Shiri Kuzin 2021-01-05 17:53 ` [dpdk-dev] [PATCH v2 1/8] lib/librte_ethdev: " Shiri Kuzin @ 2021-01-05 17:53 ` Shiri Kuzin 2021-01-05 17:53 ` [dpdk-dev] [PATCH v2 3/8] common/mlx5: check GENEVE TLV support in HCA attributes Shiri Kuzin ` (5 subsequent siblings) 7 siblings, 0 replies; 27+ messages in thread From: Shiri Kuzin @ 2021-01-05 17:53 UTC (permalink / raw) To: dev; +Cc: viacheslavo, adrien.mazarguil, orika, ferruh.yigit, thomas, rasland From: Viacheslav Ovsiienko <viacheslavo@nvidia.com> The patch adds the GENEVE option rte flow item support to command line interpreter. The flow command with GENEVE option items looks like: flow create 0 ingress pattern eth / ipv4 / udp / geneve vni is 100 / geneve-opt class is 99 length is 1 type is 0 data is 0x669988 / end actions drop / end The option length should be specified in 32-bit words, this value specifies the length of the data pattern/mask arrays (should be multiplied by sizeof(uint32_t) to be expressed in bytes. If match on the length itself is not needed the mask should be set to zero, in this case length is used to specify the pattern/mask array lengths only. Signed-off-by: Viacheslav Ovsiienko <viacheslavo@nvidia.com> --- app/test-pmd/cmdline_flow.c | 102 ++++++++++++++++++-- doc/guides/testpmd_app_ug/testpmd_funcs.rst | 8 ++ 2 files changed, 104 insertions(+), 6 deletions(-) diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c index 585cab98b4..8bb2cb1b2d 100644 --- a/app/test-pmd/cmdline_flow.c +++ b/app/test-pmd/cmdline_flow.c @@ -283,6 +283,11 @@ enum index { ITEM_ECPRI_MSG_IQ_DATA_PCID, ITEM_ECPRI_MSG_RTC_CTRL_RTCID, ITEM_ECPRI_MSG_DLY_MSR_MSRID, + ITEM_GENEVE_OPT, + ITEM_GENEVE_OPT_CLASS, + ITEM_GENEVE_OPT_TYPE, + ITEM_GENEVE_OPT_LENGTH, + ITEM_GENEVE_OPT_DATA, /* Validate/create actions. */ ACTIONS, @@ -413,6 +418,9 @@ enum index { /** Maximum size for pattern in struct rte_flow_item_raw. */ #define ITEM_RAW_PATTERN_SIZE 40 +/** Maximum size for GENEVE option data pattern in bytes. */ +#define ITEM_GENEVE_OPT_DATA_SIZE 124 + /** Storage size for struct rte_flow_item_raw including pattern. */ #define ITEM_RAW_SIZE \ (sizeof(struct rte_flow_item_raw) + ITEM_RAW_PATTERN_SIZE) @@ -428,7 +436,7 @@ struct action_rss_data { }; /** Maximum data size in struct rte_flow_action_raw_encap. */ -#define ACTION_RAW_ENCAP_MAX_DATA 128 +#define ACTION_RAW_ENCAP_MAX_DATA 512 #define RAW_ENCAP_CONFS_MAX_NUM 8 /** Storage for struct rte_flow_action_raw_encap. */ @@ -658,6 +666,16 @@ struct token { .mask = (const void *)&(const s){ .f = (1 << (b)) - 1 }, \ }) +/** Static initializer for ARGS() to target a field with limits. */ +#define ARGS_ENTRY_BOUNDED(s, f, i, a) \ + (&(const struct arg){ \ + .bounded = 1, \ + .min = (i), \ + .max = (a), \ + .offset = offsetof(s, f), \ + .size = sizeof(((s *)0)->f), \ + }) + /** Static initializer for ARGS() to target an arbitrary bit-mask. */ #define ARGS_ENTRY_MASK(s, f, m) \ (&(const struct arg){ \ @@ -903,6 +921,7 @@ static const enum index next_item[] = { ITEM_AH, ITEM_PFCP, ITEM_ECPRI, + ITEM_GENEVE_OPT, END_SET, ZERO, }; @@ -1244,6 +1263,15 @@ static const enum index item_ecpri_common_type[] = { ZERO, }; +static const enum index item_geneve_opt[] = { + ITEM_GENEVE_OPT_CLASS, + ITEM_GENEVE_OPT_TYPE, + ITEM_GENEVE_OPT_LENGTH, + ITEM_GENEVE_OPT_DATA, + ITEM_NEXT, + ZERO, +}; + static const enum index next_action[] = { ACTION_END, ACTION_VOID, @@ -3230,6 +3258,47 @@ static const struct token token_list[] = { .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ecpri, hdr.type5.msr_id)), }, + [ITEM_GENEVE_OPT] = { + .name = "geneve-opt", + .help = "GENEVE header option", + .priv = PRIV_ITEM(GENEVE_OPT, + sizeof(struct rte_flow_item_geneve_opt) + + ITEM_GENEVE_OPT_DATA_SIZE), + .next = NEXT(item_geneve_opt), + .call = parse_vc, + }, + [ITEM_GENEVE_OPT_CLASS] = { + .name = "class", + .help = "GENEVE option class", + .next = NEXT(item_geneve_opt, NEXT_ENTRY(UNSIGNED), item_param), + .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_geneve_opt, + option_class)), + }, + [ITEM_GENEVE_OPT_TYPE] = { + .name = "type", + .help = "GENEVE option type", + .next = NEXT(item_geneve_opt, NEXT_ENTRY(UNSIGNED), item_param), + .args = ARGS(ARGS_ENTRY(struct rte_flow_item_geneve_opt, + option_type)), + }, + [ITEM_GENEVE_OPT_LENGTH] = { + .name = "length", + .help = "GENEVE option data length (in 32b words)", + .next = NEXT(item_geneve_opt, NEXT_ENTRY(UNSIGNED), item_param), + .args = ARGS(ARGS_ENTRY_BOUNDED( + struct rte_flow_item_geneve_opt, option_len, + 0, 31)), + }, + [ITEM_GENEVE_OPT_DATA] = { + .name = "data", + .help = "GENEVE option data pattern", + .next = NEXT(item_geneve_opt, NEXT_ENTRY(HEX), item_param), + .args = ARGS(ARGS_ENTRY(struct rte_flow_item_geneve_opt, data), + ARGS_ENTRY_ARB(0, 0), + ARGS_ENTRY_ARB + (sizeof(struct rte_flow_item_geneve_opt), + ITEM_GENEVE_OPT_DATA_SIZE)), + }, /* Validate/create actions. */ [ACTIONS] = { .name = "actions", @@ -6482,11 +6551,14 @@ parse_hex(struct context *ctx, const struct token *token, ret = snprintf(tmp, sizeof(tmp), "%u", hexlen); if (ret < 0) goto error; - push_args(ctx, arg_len); - ret = parse_int(ctx, token, tmp, ret, NULL, 0); - if (ret < 0) { - pop_args(ctx); - goto error; + /* Save length if requested. */ + if (arg_len->size) { + push_args(ctx, arg_len); + ret = parse_int(ctx, token, tmp, ret, NULL, 0); + if (ret < 0) { + pop_args(ctx); + goto error; + } } buf = (uint8_t *)ctx->object + arg_data->offset; /* Output buffer is not necessarily NUL-terminated. */ @@ -7486,6 +7558,9 @@ flow_item_default_mask(const struct rte_flow_item *item) case RTE_FLOW_ITEM_TYPE_GENEVE: mask = &rte_flow_item_geneve_mask; break; + case RTE_FLOW_ITEM_TYPE_GENEVE_OPT: + mask = &rte_flow_item_geneve_opt_mask; + break; case RTE_FLOW_ITEM_TYPE_PPPOE_PROTO_ID: mask = &rte_flow_item_pppoe_proto_id_mask; break; @@ -7598,6 +7673,8 @@ cmd_set_raw_parsed(const struct buffer *in) /* process hdr from upper layer to low layer (L3/L4 -> L2). */ data_tail = data + ACTION_RAW_ENCAP_MAX_DATA; for (i = n - 1 ; i >= 0; --i) { + const struct rte_flow_item_geneve_opt *opt; + item = in->args.vc.pattern + i; if (item->spec == NULL) item->spec = flow_item_default_mask(item); @@ -7650,6 +7727,19 @@ cmd_set_raw_parsed(const struct buffer *in) case RTE_FLOW_ITEM_TYPE_GENEVE: size = sizeof(struct rte_geneve_hdr); break; + case RTE_FLOW_ITEM_TYPE_GENEVE_OPT: + opt = (const struct rte_flow_item_geneve_opt *) + item->spec; + size = sizeof(struct rte_flow_item_geneve_opt) - + sizeof(opt->data); + if (opt->option_len && opt->data) { + *total_size += opt->option_len * + sizeof(uint32_t); + rte_memcpy(data_tail - (*total_size), + opt->data, + opt->option_len * sizeof(uint32_t)); + } + break; case RTE_FLOW_ITEM_TYPE_L2TPV3OIP: size = sizeof(rte_be32_t); proto = 0x73; diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst index 9be450066e..37278d31d6 100644 --- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst +++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst @@ -3680,6 +3680,14 @@ This section lists supported pattern items and their attributes, if any. - ``vni {unsigned}``: virtual network identifier. - ``protocol {unsigned}``: protocol type. +- ``geneve-opt``: match GENEVE header option. + + - ``class {unsigned}``: GENEVE option class. + - ``type {unsigned}``: GENEVE option type. + - ``length {unsigned}``: GENEVE option length in 32-bit words. + - ``data {hex string}``: GENEVE option data, the legnt is defined by + ``length`` field + - ``vxlan-gpe``: match VXLAN-GPE header. - ``vni {unsigned}``: VXLAN-GPE identifier. -- 2.21.0 ^ permalink raw reply [flat|nested] 27+ messages in thread
* [dpdk-dev] [PATCH v2 3/8] common/mlx5: check GENEVE TLV support in HCA attributes 2021-01-05 17:53 ` [dpdk-dev] [PATCH v2 0/8] ethdev: introduce GENEVE header TLV option item Shiri Kuzin 2021-01-05 17:53 ` [dpdk-dev] [PATCH v2 1/8] lib/librte_ethdev: " Shiri Kuzin 2021-01-05 17:53 ` [dpdk-dev] [PATCH v2 2/8] app/testpmd: add GENEVE option item support Shiri Kuzin @ 2021-01-05 17:53 ` Shiri Kuzin 2021-01-06 9:23 ` Slava Ovsiienko 2021-01-05 17:53 ` [dpdk-dev] [PATCH v2 4/8] common/mlx5: create GENEVE TLV option object with DevX Shiri Kuzin ` (4 subsequent siblings) 7 siblings, 1 reply; 27+ messages in thread From: Shiri Kuzin @ 2021-01-05 17:53 UTC (permalink / raw) To: dev; +Cc: viacheslavo, adrien.mazarguil, orika, ferruh.yigit, thomas, rasland This is preparation step to support match on GENEVE TLV option. In this Patch we add the HCA attributes that will allow supporting GENEVE TLV option matching. Signed-off-by: Shiri Kuzin <shirik@nvidia.com> --- drivers/common/mlx5/mlx5_devx_cmds.c | 7 +++++++ drivers/common/mlx5/mlx5_devx_cmds.h | 4 ++++ drivers/common/mlx5/mlx5_prm.h | 28 +++++++++++++++++++++++++--- 3 files changed, 36 insertions(+), 3 deletions(-) diff --git a/drivers/common/mlx5/mlx5_devx_cmds.c b/drivers/common/mlx5/mlx5_devx_cmds.c index 12f51a940c..fc406af062 100644 --- a/drivers/common/mlx5/mlx5_devx_cmds.c +++ b/drivers/common/mlx5/mlx5_devx_cmds.c @@ -693,6 +693,10 @@ mlx5_devx_cmd_query_hca_attr(void *ctx, attr->eth_virt = MLX5_GET(cmd_hca_cap, hcattr, eth_virt); attr->flex_parser_protocols = MLX5_GET(cmd_hca_cap, hcattr, flex_parser_protocols); + attr->max_geneve_tlv_options = MLX5_GET(cmd_hca_cap, hcattr, + max_geneve_tlv_options); + attr->max_geneve_tlv_option_data_len = MLX5_GET(cmd_hca_cap, hcattr, + max_geneve_tlv_option_data_len); attr->qos.sup = MLX5_GET(cmd_hca_cap, hcattr, qos); attr->vdpa.valid = !!(MLX5_GET64(cmd_hca_cap, hcattr, general_obj_types) & @@ -720,6 +724,9 @@ mlx5_devx_cmd_query_hca_attr(void *ctx, attr->flow_hit_aso = !!(MLX5_GET64(cmd_hca_cap, hcattr, general_obj_types) & MLX5_GENERAL_OBJ_TYPES_CAP_FLOW_HIT_ASO); + attr->geneve_tlv_opt = !!(MLX5_GET64(cmd_hca_cap, hcattr, + general_obj_types) & + MLX5_GENERAL_OBJ_TYPES_CAP_GENEVE_TLV_OPT); attr->log_max_cq = MLX5_GET(cmd_hca_cap, hcattr, log_max_cq); attr->log_max_qp = MLX5_GET(cmd_hca_cap, hcattr, log_max_qp); attr->log_max_cq_sz = MLX5_GET(cmd_hca_cap, hcattr, log_max_cq_sz); diff --git a/drivers/common/mlx5/mlx5_devx_cmds.h b/drivers/common/mlx5/mlx5_devx_cmds.h index b335b7c82c..6b2f77837b 100644 --- a/drivers/common/mlx5/mlx5_devx_cmds.h +++ b/drivers/common/mlx5/mlx5_devx_cmds.h @@ -97,6 +97,8 @@ struct mlx5_hca_attr { uint32_t lro_timer_supported_periods[MLX5_LRO_NUM_SUPP_PERIODS]; uint16_t lro_min_mss_size; uint32_t flex_parser_protocols; + uint32_t max_geneve_tlv_options; + uint32_t max_geneve_tlv_option_data_len; uint32_t hairpin:1; uint32_t log_max_hairpin_queues:5; uint32_t log_max_hairpin_wq_data_sz:5; @@ -116,6 +118,7 @@ struct mlx5_hca_attr { uint32_t regex:1; uint32_t regexp_num_of_engines; uint32_t log_max_ft_sampler_num:8; + uint32_t geneve_tlv_opt; struct mlx5_hca_qos_attr qos; struct mlx5_hca_vdpa_attr vdpa; int log_max_qp_sz; @@ -479,6 +482,7 @@ struct mlx5_devx_obj *mlx5_devx_cmd_create_flex_parser(void *ctx, __rte_internal int mlx5_devx_cmd_register_read(void *ctx, uint16_t reg_id, uint32_t arg, uint32_t *data, uint32_t dw_cnt); + /** * Create virtio queue counters object DevX API. * diff --git a/drivers/common/mlx5/mlx5_prm.h b/drivers/common/mlx5/mlx5_prm.h index 8c9b53ce10..458550279e 100644 --- a/drivers/common/mlx5/mlx5_prm.h +++ b/drivers/common/mlx5/mlx5_prm.h @@ -789,7 +789,7 @@ struct mlx5_ifc_fte_match_set_misc3_bits { u8 icmp_code[0x8]; u8 icmpv6_type[0x8]; u8 icmpv6_code[0x8]; - u8 reserved_at_120[0x20]; + u8 geneve_tlv_option_0_data[0x20]; u8 gtpu_teid[0x20]; u8 gtpu_msg_type[0x08]; u8 gtpu_msg_flags[0x08]; @@ -1082,6 +1082,8 @@ enum { (1ULL << MLX5_GENERAL_OBJ_TYPE_FLEX_PARSE_GRAPH) #define MLX5_GENERAL_OBJ_TYPES_CAP_FLOW_HIT_ASO \ (1ULL << MLX5_GENERAL_OBJ_TYPE_FLOW_HIT_ASO) +#define MLX5_GENERAL_OBJ_TYPES_CAP_GENEVE_TLV_OPT \ + (1ULL << MLX5_OBJ_TYPE_GENEVE_TLV_OPT) enum { MLX5_HCA_CAP_OPMOD_GET_MAX = 0, @@ -1380,8 +1382,10 @@ struct mlx5_ifc_cmd_hca_cap_bits { u8 reserved_at_500[0x20]; u8 num_of_uars_per_page[0x20]; u8 flex_parser_protocols[0x20]; - u8 reserved_at_560[0x20]; - u8 reserved_at_580[0x3c]; + u8 max_geneve_tlv_options[0x8]; + u8 reserved_at_568[0x3]; + u8 max_geneve_tlv_option_data_len[0x5]; + u8 reserved_at_570[0x4c]; u8 mini_cqe_resp_stride_index[0x1]; u8 cqe_128_always[0x1]; u8 cqe_compression_128[0x1]; @@ -2292,6 +2296,7 @@ struct mlx5_ifc_create_cq_in_bits { }; enum { + MLX5_OBJ_TYPE_GENEVE_TLV_OPT = 0x000b, MLX5_GENERAL_OBJ_TYPE_VIRTQ = 0x000d, MLX5_GENERAL_OBJ_TYPE_VIRTIO_Q_COUNTERS = 0x001c, MLX5_GENERAL_OBJ_TYPE_FLEX_PARSE_GRAPH = 0x0022, @@ -2326,6 +2331,17 @@ struct mlx5_ifc_virtio_q_counters_bits { u8 reserved_at_180[0x50]; }; +struct mlx5_ifc_geneve_tlv_option_bits { + u8 modify_field_select[0x40]; + u8 reserved_at_40[0x18]; + u8 geneve_option_fte_index[0x8]; + u8 option_class[0x10]; + u8 option_type[0x8]; + u8 reserved_at_78[0x3]; + u8 option_data_length[0x5]; + u8 reserved_at_80[0x180]; +}; + struct mlx5_ifc_create_virtio_q_counters_in_bits { struct mlx5_ifc_general_obj_in_cmd_hdr_bits hdr; struct mlx5_ifc_virtio_q_counters_bits virtio_q_counters; @@ -2335,6 +2351,12 @@ struct mlx5_ifc_query_virtio_q_counters_out_bits { struct mlx5_ifc_general_obj_in_cmd_hdr_bits hdr; struct mlx5_ifc_virtio_q_counters_bits virtio_q_counters; }; + +struct mlx5_ifc_create_geneve_tlv_option_in_bits { + struct mlx5_ifc_general_obj_in_cmd_hdr_bits hdr; + struct mlx5_ifc_geneve_tlv_option_bits geneve_tlv_opt; +}; + enum { MLX5_VIRTQ_STATE_INIT = 0, MLX5_VIRTQ_STATE_RDY = 1, -- 2.21.0 ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [dpdk-dev] [PATCH v2 3/8] common/mlx5: check GENEVE TLV support in HCA attributes 2021-01-05 17:53 ` [dpdk-dev] [PATCH v2 3/8] common/mlx5: check GENEVE TLV support in HCA attributes Shiri Kuzin @ 2021-01-06 9:23 ` Slava Ovsiienko 0 siblings, 0 replies; 27+ messages in thread From: Slava Ovsiienko @ 2021-01-06 9:23 UTC (permalink / raw) To: Shiri Kuzin, dev Cc: NBU-Contact-Adrien Mazarguil, Ori Kam, ferruh.yigit, NBU-Contact-Thomas Monjalon, Raslan Darawsheh > -----Original Message----- > From: Shiri Kuzin <shirik@nvidia.com> > Sent: Tuesday, January 5, 2021 19:54 > To: dev@dpdk.org > Cc: Slava Ovsiienko <viacheslavo@nvidia.com>; NBU-Contact-Adrien Mazarguil > <adrien.mazarguil@6wind.com>; Ori Kam <orika@nvidia.com>; > ferruh.yigit@intel.com; NBU-Contact-Thomas Monjalon > <thomas@monjalon.net>; Raslan Darawsheh <rasland@nvidia.com> > Subject: [PATCH v2 3/8] common/mlx5: check GENEVE TLV support in HCA > attributes > > This is preparation step to support match on GENEVE TLV option. > > In this Patch we add the HCA attributes that will allow supporting GENEVE TLV > option matching. > > Signed-off-by: Shiri Kuzin <shirik@nvidia.com> Acked-by: Viacheslav Ovsiienko <viacheslavo@nvidia.com> ^ permalink raw reply [flat|nested] 27+ messages in thread
* [dpdk-dev] [PATCH v2 4/8] common/mlx5: create GENEVE TLV option object with DevX 2021-01-05 17:53 ` [dpdk-dev] [PATCH v2 0/8] ethdev: introduce GENEVE header TLV option item Shiri Kuzin ` (2 preceding siblings ...) 2021-01-05 17:53 ` [dpdk-dev] [PATCH v2 3/8] common/mlx5: check GENEVE TLV support in HCA attributes Shiri Kuzin @ 2021-01-05 17:53 ` Shiri Kuzin 2021-01-06 9:24 ` Slava Ovsiienko 2021-01-05 17:53 ` [dpdk-dev] [PATCH v2 5/8] net/mlx5: create GENEVE TLV option management Shiri Kuzin ` (3 subsequent siblings) 7 siblings, 1 reply; 27+ messages in thread From: Shiri Kuzin @ 2021-01-05 17:53 UTC (permalink / raw) To: dev; +Cc: viacheslavo, adrien.mazarguil, orika, ferruh.yigit, thomas, rasland TLV object is a special firmware maintained entity used to support match on GENEVE header extension option. The TLV object is created with DevX API and accepts the option class, type and lehgth fields. The class type and length fields are set using MLX5_SET and the Devx object is created using mlx5 glue function. Signed-off-by: Shiri Kuzin <shirik@nvidia.com> --- drivers/common/mlx5/mlx5_devx_cmds.c | 56 +++++++++++++++++++++++++++- drivers/common/mlx5/mlx5_devx_cmds.h | 5 +++ drivers/common/mlx5/version.map | 1 + 3 files changed, 61 insertions(+), 1 deletion(-) diff --git a/drivers/common/mlx5/mlx5_devx_cmds.c b/drivers/common/mlx5/mlx5_devx_cmds.c index fc406af062..08bd357ad1 100644 --- a/drivers/common/mlx5/mlx5_devx_cmds.c +++ b/drivers/common/mlx5/mlx5_devx_cmds.c @@ -2068,7 +2068,6 @@ mlx5_devx_cmd_create_flow_hit_aso_obj(void *ctx, uint32_t pd) * * @param[in] ctx * Context returned from mlx5 open_device() glue function. - * * @return * The DevX object created, NULL otherwise and rte_errno is set. */ @@ -2097,3 +2096,58 @@ mlx5_devx_cmd_alloc_pd(void *ctx) ppd->id = MLX5_GET(alloc_pd_out, out, pd); return ppd; } + +/** + * Create general object of type GENEVE TLV option using DevX API. + * + * @param[in] ctx + * Context returned from mlx5 open_device() glue function. + * @param [in] class + * TLV option variable value of class + * @param [in] type + * TLV option variable value of type + * @param [in] len + * TLV option variable value of len + * * + * @return + * The DevX object created, NULL otherwise and rte_errno is set. + */ +struct mlx5_devx_obj * +mlx5_devx_cmd_create_geneve_tlv_option(void *ctx, + uint16_t class, uint8_t type, uint8_t len) +{ + uint32_t in[MLX5_ST_SZ_DW(create_geneve_tlv_option_in)] = {0}; + uint32_t out[MLX5_ST_SZ_DW(general_obj_out_cmd_hdr)] = {0}; + struct mlx5_devx_obj *geneve_tlv_opt_obj = mlx5_malloc(MLX5_MEM_ZERO, + sizeof(*geneve_tlv_opt_obj), + 0, SOCKET_ID_ANY); + + if (!geneve_tlv_opt_obj) { + DRV_LOG(ERR, "Failed to allocate geneve tlv option object."); + rte_errno = ENOMEM; + return NULL; + } + void *hdr = MLX5_ADDR_OF(create_geneve_tlv_option_in, in, hdr); + void *opt = MLX5_ADDR_OF(create_geneve_tlv_option_in, in, + geneve_tlv_opt); + MLX5_SET(general_obj_in_cmd_hdr, hdr, opcode, + MLX5_CMD_OP_CREATE_GENERAL_OBJECT); + MLX5_SET(general_obj_in_cmd_hdr, hdr, obj_type, + MLX5_OBJ_TYPE_GENEVE_TLV_OPT); + MLX5_SET(geneve_tlv_option, opt, option_class, + rte_be_to_cpu_16(class)); + MLX5_SET(geneve_tlv_option, opt, option_type, type); + MLX5_SET(geneve_tlv_option, opt, option_data_length, len); + geneve_tlv_opt_obj->obj = mlx5_glue->devx_obj_create(ctx, in, + sizeof(in), out, sizeof(out)); + if (!geneve_tlv_opt_obj->obj) { + rte_errno = errno; + DRV_LOG(ERR, "Failed to create Geneve tlv option " + "Obj using DevX."); + mlx5_free(geneve_tlv_opt_obj); + return NULL; + } + geneve_tlv_opt_obj->id = MLX5_GET(general_obj_out_cmd_hdr, out, obj_id); + return geneve_tlv_opt_obj; +} + diff --git a/drivers/common/mlx5/mlx5_devx_cmds.h b/drivers/common/mlx5/mlx5_devx_cmds.h index 6b2f77837b..6774b49d2d 100644 --- a/drivers/common/mlx5/mlx5_devx_cmds.h +++ b/drivers/common/mlx5/mlx5_devx_cmds.h @@ -483,6 +483,11 @@ __rte_internal int mlx5_devx_cmd_register_read(void *ctx, uint16_t reg_id, uint32_t arg, uint32_t *data, uint32_t dw_cnt); +__rte_internal +struct mlx5_devx_obj * +mlx5_devx_cmd_create_geneve_tlv_option(void *ctx, + uint16_t class, uint8_t type, uint8_t len); + /** * Create virtio queue counters object DevX API. * diff --git a/drivers/common/mlx5/version.map b/drivers/common/mlx5/version.map index fb3952bbc6..7de8006b89 100644 --- a/drivers/common/mlx5/version.map +++ b/drivers/common/mlx5/version.map @@ -23,6 +23,7 @@ INTERNAL { mlx5_devx_cmd_create_virtio_q_counters; mlx5_devx_cmd_create_virtq; mlx5_devx_cmd_create_flow_hit_aso_obj; + mlx5_devx_cmd_create_geneve_tlv_option; mlx5_devx_cmd_destroy; mlx5_devx_cmd_flow_counter_alloc; mlx5_devx_cmd_flow_counter_query; -- 2.21.0 ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [dpdk-dev] [PATCH v2 4/8] common/mlx5: create GENEVE TLV option object with DevX 2021-01-05 17:53 ` [dpdk-dev] [PATCH v2 4/8] common/mlx5: create GENEVE TLV option object with DevX Shiri Kuzin @ 2021-01-06 9:24 ` Slava Ovsiienko 0 siblings, 0 replies; 27+ messages in thread From: Slava Ovsiienko @ 2021-01-06 9:24 UTC (permalink / raw) To: Shiri Kuzin, dev Cc: NBU-Contact-Adrien Mazarguil, Ori Kam, ferruh.yigit, NBU-Contact-Thomas Monjalon, Raslan Darawsheh > -----Original Message----- > From: Shiri Kuzin <shirik@nvidia.com> > Sent: Tuesday, January 5, 2021 19:54 > To: dev@dpdk.org > Cc: Slava Ovsiienko <viacheslavo@nvidia.com>; NBU-Contact-Adrien Mazarguil > <adrien.mazarguil@6wind.com>; Ori Kam <orika@nvidia.com>; > ferruh.yigit@intel.com; NBU-Contact-Thomas Monjalon > <thomas@monjalon.net>; Raslan Darawsheh <rasland@nvidia.com> > Subject: [PATCH v2 4/8] common/mlx5: create GENEVE TLV option object with > DevX > > TLV object is a special firmware maintained entity used to support match on > GENEVE header extension option. > > The TLV object is created with DevX API and accepts the option class, type and > lehgth fields. > > The class type and length fields are set using MLX5_SET and the Devx object is > created using mlx5 glue function. > > Signed-off-by: Shiri Kuzin <shirik@nvidia.com> Acked-by: Viacheslav Ovsiienko <viacheslavo@nvidia.com> ^ permalink raw reply [flat|nested] 27+ messages in thread
* [dpdk-dev] [PATCH v2 5/8] net/mlx5: create GENEVE TLV option management 2021-01-05 17:53 ` [dpdk-dev] [PATCH v2 0/8] ethdev: introduce GENEVE header TLV option item Shiri Kuzin ` (3 preceding siblings ...) 2021-01-05 17:53 ` [dpdk-dev] [PATCH v2 4/8] common/mlx5: create GENEVE TLV option object with DevX Shiri Kuzin @ 2021-01-05 17:53 ` Shiri Kuzin 2021-01-06 9:24 ` Slava Ovsiienko 2021-01-05 17:53 ` [dpdk-dev] [PATCH v2 6/8] net/mlx5: add GENEVE TLV option flow validation Shiri Kuzin ` (2 subsequent siblings) 7 siblings, 1 reply; 27+ messages in thread From: Shiri Kuzin @ 2021-01-05 17:53 UTC (permalink / raw) To: dev; +Cc: viacheslavo, adrien.mazarguil, orika, ferruh.yigit, thomas, rasland Currently firmware supports the only TLV object per device to match on the GENEVE header option. This patch adds the simple TLV object management to the mlx5 PMD. Signed-off-by: Shiri Kuzin <shirik@nvidia.com> --- drivers/net/mlx5/mlx5.c | 2 + drivers/net/mlx5/mlx5.h | 13 ++++ drivers/net/mlx5/mlx5_flow.h | 4 ++ drivers/net/mlx5/mlx5_flow_dv.c | 108 ++++++++++++++++++++++++++++++++ 4 files changed, 127 insertions(+) diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c index 023ef50a77..68d6352d48 100644 --- a/drivers/net/mlx5/mlx5.c +++ b/drivers/net/mlx5/mlx5.c @@ -1014,6 +1014,7 @@ mlx5_alloc_shared_dev_ctx(const struct mlx5_dev_spawn_data *spawn, rte_rwlock_write_unlock(&mlx5_shared_data->mem_event_rwlock); /* Add context to the global device list. */ LIST_INSERT_HEAD(&mlx5_dev_ctx_list, sh, next); + rte_spinlock_init(&sh->geneve_tlv_opt_sl); exit: pthread_mutex_unlock(&mlx5_dev_ctx_list_mutex); return sh; @@ -1109,6 +1110,7 @@ mlx5_free_shared_dev_ctx(struct mlx5_dev_ctx_shared *sh) mlx5_glue->devx_free_uar(sh->devx_rx_uar); if (sh->ctx) claim_zero(mlx5_glue->close_device(sh->ctx)); + MLX5_ASSERT(sh->geneve_tlv_option_resource == NULL); pthread_mutex_destroy(&sh->txpp.mutex); mlx5_free(sh); return; diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h index 41034f5d19..23272950a4 100644 --- a/drivers/net/mlx5/mlx5.h +++ b/drivers/net/mlx5/mlx5.h @@ -540,6 +540,16 @@ struct mlx5_aso_age_mng { struct mlx5_aso_sq aso_sq; /* ASO queue objects. */ }; +/* Management structure for geneve tlv option */ +struct mlx5_geneve_tlv_option_resource { + struct mlx5_devx_obj *obj; /* Pointer to the geneve tlv opt object. */ + rte_be16_t option_class; /* geneve tlv opt class.*/ + uint8_t option_type; /* geneve tlv opt type.*/ + uint8_t length; /* geneve tlv opt length. */ + uint32_t refcnt; /* geneve tlv object reference counter */ +}; + + #define MLX5_AGE_EVENT_NEW 1 #define MLX5_AGE_TRIGGER 2 #define MLX5_AGE_SET(age_info, BIT) \ @@ -752,6 +762,9 @@ struct mlx5_dev_ctx_shared { void *devx_rx_uar; /* DevX UAR for Rx. */ struct mlx5_aso_age_mng *aso_age_mng; /* Management data for aging mechanism using ASO Flow Hit. */ + struct mlx5_geneve_tlv_option_resource *geneve_tlv_option_resource; + /* Management structure for geneve tlv option */ + rte_spinlock_t geneve_tlv_opt_sl; /* Lock for geneve tlv resource */ struct mlx5_dev_shared_port port[]; /* per device port data array. */ }; diff --git a/drivers/net/mlx5/mlx5_flow.h b/drivers/net/mlx5/mlx5_flow.h index ee85c9d8a5..0c8861964c 100644 --- a/drivers/net/mlx5/mlx5_flow.h +++ b/drivers/net/mlx5/mlx5_flow.h @@ -1046,6 +1046,7 @@ struct rte_flow { uint32_t counter; /**< Holds flow counter. */ uint32_t tunnel_id; /**< Tunnel id */ uint32_t age; /**< Holds ASO age bit index. */ + uint32_t geneve_tlv_option; /**< Holds Geneve TLV option id. > */ } __rte_packed; /* @@ -1503,4 +1504,7 @@ void flow_dv_dest_array_remove_cb(struct mlx5_cache_list *list, struct mlx5_cache_entry *entry); struct mlx5_aso_age_action *flow_aso_age_get_by_idx(struct rte_eth_dev *dev, uint32_t age_idx); +int flow_dev_geneve_tlv_option_resource_register(struct rte_eth_dev *dev, + const struct rte_flow_item *item, + struct rte_flow_error *error); #endif /* RTE_PMD_MLX5_FLOW_H_ */ diff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c index ce229dbe85..d33c92aa57 100644 --- a/drivers/net/mlx5/mlx5_flow_dv.c +++ b/drivers/net/mlx5/mlx5_flow_dv.c @@ -7223,6 +7223,90 @@ flow_dv_translate_item_geneve(void *matcher, void *key, MLX5_GENEVE_OPTLEN_VAL(gbhdr_m)); } +/** + * Create Geneve TLV option resource. + * + * @param dev[in, out] + * Pointer to rte_eth_dev structure. + * @param[in, out] tag_be24 + * Tag value in big endian then R-shift 8. + * @parm[in, out] dev_flow + * Pointer to the dev_flow. + * @param[out] error + * pointer to error structure. + * + * @return + * 0 on success otherwise -errno and errno is set. + */ + +int +flow_dev_geneve_tlv_option_resource_register(struct rte_eth_dev *dev, + const struct rte_flow_item *item, + struct rte_flow_error *error) +{ + struct mlx5_priv *priv = dev->data->dev_private; + struct mlx5_dev_ctx_shared *sh = priv->sh; + struct mlx5_geneve_tlv_option_resource *geneve_opt_resource = + sh->geneve_tlv_option_resource; + struct mlx5_devx_obj *obj; + const struct rte_flow_item_geneve_opt *geneve_opt_v = item->spec; + int ret = 0; + + if (!geneve_opt_v) + return -1; + rte_spinlock_lock(&sh->geneve_tlv_opt_sl); + if (geneve_opt_resource != NULL) { + if (geneve_opt_resource->option_class == + geneve_opt_v->option_class && + geneve_opt_resource->option_type == + geneve_opt_v->option_type && + geneve_opt_resource->length == + geneve_opt_v->option_len) { + /* We already have GENVE TLV option obj allocated. */ + __atomic_fetch_add(&geneve_opt_resource->refcnt, 1, + __ATOMIC_RELAXED); + } else { + ret = rte_flow_error_set(error, ENOMEM, + RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL, + "Only one GENEVE TLV option supported"); + goto exit; + } + } else { + /* Create a GENEVE TLV object and resource. */ + obj = mlx5_devx_cmd_create_geneve_tlv_option(sh->ctx, + geneve_opt_v->option_class, + geneve_opt_v->option_type, + geneve_opt_v->option_len); + if (!obj) { + ret = rte_flow_error_set(error, ENODATA, + RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL, + "Failed to create GENEVE TLV Devx object"); + goto exit; + } + sh->geneve_tlv_option_resource = + mlx5_malloc(MLX5_MEM_ZERO, + sizeof(*geneve_opt_resource), + 0, SOCKET_ID_ANY); + if (!sh->geneve_tlv_option_resource) { + claim_zero(mlx5_devx_cmd_destroy(obj)); + ret = rte_flow_error_set(error, ENOMEM, + RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL, + "GENEVE TLV object memory allocation failed"); + goto exit; + } + geneve_opt_resource = sh->geneve_tlv_option_resource; + geneve_opt_resource->obj = obj; + geneve_opt_resource->option_class = geneve_opt_v->option_class; + geneve_opt_resource->option_type = geneve_opt_v->option_type; + geneve_opt_resource->length = geneve_opt_v->option_len; + __atomic_store_n(&geneve_opt_resource->refcnt, 1, + __ATOMIC_RELAXED); + } +exit: + rte_spinlock_unlock(&sh->geneve_tlv_opt_sl); + return ret; +} + /** * Add MPLS item to matcher and to the value. * @@ -11215,6 +11299,26 @@ flow_dv_dest_array_resource_release(struct rte_eth_dev *dev, &cache->entry); } +static void +flow_dv_geneve_tlv_option_resource_release(struct rte_eth_dev *dev) +{ + struct mlx5_priv *priv = dev->data->dev_private; + struct mlx5_dev_ctx_shared *sh = priv->sh; + struct mlx5_geneve_tlv_option_resource *geneve_opt_resource = + sh->geneve_tlv_option_resource; + rte_spinlock_lock(&sh->geneve_tlv_opt_sl); + if (geneve_opt_resource) { + if (!(__atomic_sub_fetch(&geneve_opt_resource->refcnt, 1, + __ATOMIC_RELAXED))) { + claim_zero(mlx5_devx_cmd_destroy + (geneve_opt_resource->obj)); + mlx5_free(sh->geneve_tlv_option_resource); + sh->geneve_tlv_option_resource = NULL; + } + } + rte_spinlock_unlock(&sh->geneve_tlv_opt_sl); +} + /** * Remove the flow from the NIC but keeps it in memory. * Lock free, (mutex should be acquired by caller). @@ -11284,6 +11388,10 @@ flow_dv_destroy(struct rte_eth_dev *dev, struct rte_flow *flow) } if (flow->age) flow_dv_aso_age_release(dev, flow->age); + if (flow->geneve_tlv_option) { + flow_dv_geneve_tlv_option_resource_release(dev); + flow->geneve_tlv_option = 0; + } while (flow->dev_handles) { uint32_t tmp_idx = flow->dev_handles; -- 2.21.0 ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [dpdk-dev] [PATCH v2 5/8] net/mlx5: create GENEVE TLV option management 2021-01-05 17:53 ` [dpdk-dev] [PATCH v2 5/8] net/mlx5: create GENEVE TLV option management Shiri Kuzin @ 2021-01-06 9:24 ` Slava Ovsiienko 0 siblings, 0 replies; 27+ messages in thread From: Slava Ovsiienko @ 2021-01-06 9:24 UTC (permalink / raw) To: Shiri Kuzin, dev Cc: NBU-Contact-Adrien Mazarguil, Ori Kam, ferruh.yigit, NBU-Contact-Thomas Monjalon, Raslan Darawsheh > -----Original Message----- > From: Shiri Kuzin <shirik@nvidia.com> > Sent: Tuesday, January 5, 2021 19:54 > To: dev@dpdk.org > Cc: Slava Ovsiienko <viacheslavo@nvidia.com>; NBU-Contact-Adrien Mazarguil > <adrien.mazarguil@6wind.com>; Ori Kam <orika@nvidia.com>; > ferruh.yigit@intel.com; NBU-Contact-Thomas Monjalon > <thomas@monjalon.net>; Raslan Darawsheh <rasland@nvidia.com> > Subject: [PATCH v2 5/8] net/mlx5: create GENEVE TLV option management > > Currently firmware supports the only TLV object per device to match on the > GENEVE header option. > > This patch adds the simple TLV object management to the mlx5 PMD. > > Signed-off-by: Shiri Kuzin <shirik@nvidia.com> Acked-by: Viacheslav Ovsiienko <viacheslavo@nvidia.com> ^ permalink raw reply [flat|nested] 27+ messages in thread
* [dpdk-dev] [PATCH v2 6/8] net/mlx5: add GENEVE TLV option flow validation 2021-01-05 17:53 ` [dpdk-dev] [PATCH v2 0/8] ethdev: introduce GENEVE header TLV option item Shiri Kuzin ` (4 preceding siblings ...) 2021-01-05 17:53 ` [dpdk-dev] [PATCH v2 5/8] net/mlx5: create GENEVE TLV option management Shiri Kuzin @ 2021-01-05 17:53 ` Shiri Kuzin 2021-01-06 9:24 ` Slava Ovsiienko 2021-01-05 17:53 ` [dpdk-dev] [PATCH v2 7/8] net/mlx5: add GENEVE TLV option flow translation Shiri Kuzin 2021-01-05 17:53 ` [dpdk-dev] [PATCH v2 8/8] doc: update GENEVE TLV option support Shiri Kuzin 7 siblings, 1 reply; 27+ messages in thread From: Shiri Kuzin @ 2021-01-05 17:53 UTC (permalink / raw) To: dev; +Cc: viacheslavo, adrien.mazarguil, orika, ferruh.yigit, thomas, rasland This patch adds validation routine for the GENEVE header TLV option. The GENEVE TLV option match must include all fields with full masks due to NIC does not support masking on option class, type and length. The option data length must be non zero and provided data pattern should be zero neither due to hardware limitations. Signed-off-by: Shiri Kuzin <shirik@nvidia.com> --- drivers/net/mlx5/mlx5_flow.c | 120 ++++++++++++++++++++++++++++++++ drivers/net/mlx5/mlx5_flow.h | 7 ++ drivers/net/mlx5/mlx5_flow_dv.c | 10 ++- 3 files changed, 136 insertions(+), 1 deletion(-) diff --git a/drivers/net/mlx5/mlx5_flow.c b/drivers/net/mlx5/mlx5_flow.c index f110c6b714..d56935fa03 100644 --- a/drivers/net/mlx5/mlx5_flow.c +++ b/drivers/net/mlx5/mlx5_flow.c @@ -2603,6 +2603,126 @@ mlx5_flow_validate_item_geneve(const struct rte_flow_item *item, return 0; } +/** + * Validate Geneve TLV option item. + * + * @param[in] item + * Item specification. + * @param[in] last_item + * Previous validated item in the pattern items. + * @param[in] dev + * Pointer to the rte_eth_dev structure. + * @param[out] error + * Pointer to error structure. + * + * @return + * 0 on success, a negative errno value otherwise and rte_errno is set. + */ +int +mlx5_flow_validate_item_geneve_opt(const struct rte_flow_item *item, + uint64_t last_item, + struct rte_eth_dev *dev, + struct rte_flow_error *error) +{ + struct mlx5_priv *priv = dev->data->dev_private; + struct mlx5_dev_ctx_shared *sh = priv->sh; + struct mlx5_geneve_tlv_option_resource *geneve_opt_resource; + struct mlx5_hca_attr *hca_attr = &priv->config.hca_attr; + uint8_t data_max_supported = + hca_attr->max_geneve_tlv_option_data_len * 4; + struct mlx5_dev_config *config = &priv->config; + const struct rte_flow_item_geneve_opt *spec = item->spec; + const struct rte_flow_item_geneve_opt *mask = item->mask; + unsigned int i; + unsigned int data_len; + const struct rte_flow_item_geneve_opt full_mask = { + .option_class = RTE_BE16(0xffff), + .option_type = 0xff, + .option_len = 0x1f, + }; + + if (!mask) + mask = &rte_flow_item_geneve_opt_mask; + if (!spec) + return rte_flow_error_set + (error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ITEM, item, + "Geneve TLV opt class/type/length must be specified"); + if ((uint32_t)(spec->option_len) > MLX5_GENEVE_OPTLEN_MASK) + return rte_flow_error_set + (error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ITEM, item, + "Geneve TLV opt length exceeeds the limit (31)"); + /* Check if class type and length masks are full. */ + if (full_mask.option_class != mask->option_class || + full_mask.option_type != mask->option_type || + full_mask.option_len != (mask->option_len & full_mask.option_len)) + return rte_flow_error_set + (error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ITEM, item, + "Geneve TLV opt class/type/length masks must be full"); + /* Check if length is supported */ + if ((uint32_t)(spec->option_len) > + config->hca_attr.max_geneve_tlv_option_data_len) + return rte_flow_error_set + (error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ITEM, item, + "Geneve TLV opt length not supported"); + if (config->hca_attr.max_geneve_tlv_options > 1) + DRV_LOG(DEBUG, + "max_geneve_tlv_options supports more than 1 option"); + /* Check GENEVE item preceding. */ + if (!(last_item & MLX5_FLOW_LAYER_GENEVE)) + return rte_flow_error_set + (error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ITEM, item, + "Geneve opt item must be preceded with Geneve item"); + /* Check if length is 0 or data is 0. */ + if (spec->data == NULL || spec->option_len == 0) + return rte_flow_error_set + (error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ITEM, item, + "Geneve TLV opt with zero data/length not supported"); + /* Check not all data & mask are 0. */ + data_len = spec->option_len * 4; + if (mask->data == NULL) { + for (i = 0; i < data_len; i++) + if (spec->data[i]) + break; + if (i == data_len) + return rte_flow_error_set(error, ENOTSUP, + RTE_FLOW_ERROR_TYPE_ITEM, item, + "Can't match on Geneve option data 0"); + } else { + for (i = 0; i < data_len; i++) + if (spec->data[i] & mask->data[i]) + break; + if (i == data_len) + return rte_flow_error_set(error, ENOTSUP, + RTE_FLOW_ERROR_TYPE_ITEM, item, + "Can't match on Geneve option data and mask 0"); + /* Check data mask supported. */ + for (i = data_max_supported; i < data_len ; i++) + if (mask->data[i]) + return rte_flow_error_set(error, ENOTSUP, + RTE_FLOW_ERROR_TYPE_ITEM, item, + "Data mask is of unsupported size"); + } + /* Check GENEVE option is supported in NIC. */ + if (!config->hca_attr.geneve_tlv_opt) + return rte_flow_error_set + (error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ITEM, item, + "Geneve TLV opt not supported"); + /* Check if we already have geneve option with different type/class. */ + rte_spinlock_lock(&sh->geneve_tlv_opt_sl); + geneve_opt_resource = sh->geneve_tlv_option_resource; + if (geneve_opt_resource != NULL) + if (geneve_opt_resource->option_class != spec->option_class || + geneve_opt_resource->option_type != spec->option_type || + geneve_opt_resource->length != spec->option_len) { + rte_spinlock_unlock(&sh->geneve_tlv_opt_sl); + return rte_flow_error_set(error, ENOTSUP, + RTE_FLOW_ERROR_TYPE_ITEM, item, + "Only one Geneve TLV option supported"); + } + rte_spinlock_unlock(&sh->geneve_tlv_opt_sl); + return 0; +} + /** * Validate MPLS item. * diff --git a/drivers/net/mlx5/mlx5_flow.h b/drivers/net/mlx5/mlx5_flow.h index 0c8861964c..28db5faee1 100644 --- a/drivers/net/mlx5/mlx5_flow.h +++ b/drivers/net/mlx5/mlx5_flow.h @@ -138,6 +138,9 @@ enum mlx5_feature_name { #define MLX5_FLOW_LAYER_OUTER_L3_IPV6_FRAG_EXT (1u << 30) #define MLX5_FLOW_LAYER_INNER_L3_IPV6_FRAG_EXT (1u << 31) +/* Pattern tunnel Layer bits (continued). */ +#define MLX5_FLOW_LAYER_GENEVE_OPT (UINT64_C(1) << 32) + /* Outer Masks. */ #define MLX5_FLOW_LAYER_OUTER_L3 \ (MLX5_FLOW_LAYER_OUTER_L3_IPV4 | MLX5_FLOW_LAYER_OUTER_L3_IPV6) @@ -1396,6 +1399,10 @@ int mlx5_flow_validate_item_geneve(const struct rte_flow_item *item, uint64_t item_flags, struct rte_eth_dev *dev, struct rte_flow_error *error); +int mlx5_flow_validate_item_geneve_opt(const struct rte_flow_item *item, + uint64_t last_item, + struct rte_eth_dev *dev, + struct rte_flow_error *error); int mlx5_flow_validate_item_ecpri(const struct rte_flow_item *item, uint64_t item_flags, uint64_t last_item, diff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c index d33c92aa57..14e000e32d 100644 --- a/drivers/net/mlx5/mlx5_flow_dv.c +++ b/drivers/net/mlx5/mlx5_flow_dv.c @@ -5501,6 +5501,15 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr, return ret; last_item = MLX5_FLOW_LAYER_GENEVE; break; + case RTE_FLOW_ITEM_TYPE_GENEVE_OPT: + ret = mlx5_flow_validate_item_geneve_opt(items, + last_item, + dev, + error); + if (ret < 0) + return ret; + last_item = MLX5_FLOW_LAYER_GENEVE_OPT; + break; case RTE_FLOW_ITEM_TYPE_MPLS: ret = mlx5_flow_validate_item_mpls(dev, items, item_flags, @@ -5509,7 +5518,6 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr, return ret; last_item = MLX5_FLOW_LAYER_MPLS; break; - case RTE_FLOW_ITEM_TYPE_MARK: ret = flow_dv_validate_item_mark(dev, items, attr, error); -- 2.21.0 ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [dpdk-dev] [PATCH v2 6/8] net/mlx5: add GENEVE TLV option flow validation 2021-01-05 17:53 ` [dpdk-dev] [PATCH v2 6/8] net/mlx5: add GENEVE TLV option flow validation Shiri Kuzin @ 2021-01-06 9:24 ` Slava Ovsiienko 0 siblings, 0 replies; 27+ messages in thread From: Slava Ovsiienko @ 2021-01-06 9:24 UTC (permalink / raw) To: Shiri Kuzin, dev Cc: NBU-Contact-Adrien Mazarguil, Ori Kam, ferruh.yigit, NBU-Contact-Thomas Monjalon, Raslan Darawsheh > -----Original Message----- > From: Shiri Kuzin <shirik@nvidia.com> > Sent: Tuesday, January 5, 2021 19:54 > To: dev@dpdk.org > Cc: Slava Ovsiienko <viacheslavo@nvidia.com>; NBU-Contact-Adrien Mazarguil > <adrien.mazarguil@6wind.com>; Ori Kam <orika@nvidia.com>; > ferruh.yigit@intel.com; NBU-Contact-Thomas Monjalon > <thomas@monjalon.net>; Raslan Darawsheh <rasland@nvidia.com> > Subject: [PATCH v2 6/8] net/mlx5: add GENEVE TLV option flow validation > > This patch adds validation routine for the GENEVE header TLV option. > > The GENEVE TLV option match must include all fields with full masks due to > NIC does not support masking on option class, type and length. > > The option data length must be non zero and provided data pattern should be > zero neither due to hardware limitations. > > Signed-off-by: Shiri Kuzin <shirik@nvidia.com> Acked-by: Viacheslav Ovsiienko <viacheslavo@nvidia.com> ^ permalink raw reply [flat|nested] 27+ messages in thread
* [dpdk-dev] [PATCH v2 7/8] net/mlx5: add GENEVE TLV option flow translation 2021-01-05 17:53 ` [dpdk-dev] [PATCH v2 0/8] ethdev: introduce GENEVE header TLV option item Shiri Kuzin ` (5 preceding siblings ...) 2021-01-05 17:53 ` [dpdk-dev] [PATCH v2 6/8] net/mlx5: add GENEVE TLV option flow validation Shiri Kuzin @ 2021-01-05 17:53 ` Shiri Kuzin 2021-01-06 9:25 ` Slava Ovsiienko 2021-01-05 17:53 ` [dpdk-dev] [PATCH v2 8/8] doc: update GENEVE TLV option support Shiri Kuzin 7 siblings, 1 reply; 27+ messages in thread From: Shiri Kuzin @ 2021-01-05 17:53 UTC (permalink / raw) To: dev; +Cc: viacheslavo, adrien.mazarguil, orika, ferruh.yigit, thomas, rasland The GENEVE TLV option matching flows must be created using a translation function. This function checks whether we already created a Devx object for the matching and either creates the objects or updates the reference counter. Signed-off-by: Shiri Kuzin <shirik@nvidia.com> --- drivers/net/mlx5/mlx5_flow_dv.c | 70 +++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) diff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c index 14e000e32d..8fd0681424 100644 --- a/drivers/net/mlx5/mlx5_flow_dv.c +++ b/drivers/net/mlx5/mlx5_flow_dv.c @@ -7315,6 +7315,65 @@ flow_dev_geneve_tlv_option_resource_register(struct rte_eth_dev *dev, return ret; } +/** + * Add Geneve TLV option item to matcher. + * + * @param[in, out] dev + * Pointer to rte_eth_dev structure. + * @param[in, out] matcher + * Flow matcher. + * @param[in, out] key + * Flow matcher value. + * @param[in] item + * Flow pattern to translate. + * @param[out] error + * Pointer to error structure. + */ +static int +flow_dv_translate_item_geneve_opt(struct rte_eth_dev *dev, void *matcher, + void *key, const struct rte_flow_item *item, + struct rte_flow_error *error) +{ + const struct rte_flow_item_geneve_opt *geneve_opt_m = item->mask; + const struct rte_flow_item_geneve_opt *geneve_opt_v = item->spec; + void *misc3_m = MLX5_ADDR_OF(fte_match_param, matcher, + misc_parameters_3); + void *misc3_v = MLX5_ADDR_OF(fte_match_param, key, misc_parameters_3); + rte_be32_t opt_data_key = 0, opt_data_mask = 0; + int ret = 0; + + if (!geneve_opt_v) + return -1; + if (!geneve_opt_m) + geneve_opt_m = &rte_flow_item_geneve_opt_mask; + ret = flow_dev_geneve_tlv_option_resource_register(dev, item, + error); + if (ret) { + DRV_LOG(ERR, "Failed to create geneve_tlv_obj"); + return ret; + } + /* Set the data. */ + if (geneve_opt_v->data) { + memcpy(&opt_data_key, geneve_opt_v->data, + RTE_MIN((uint32_t)(geneve_opt_v->option_len * 4), + sizeof(opt_data_key))); + MLX5_ASSERT((uint32_t)(geneve_opt_v->option_len * 4) <= + sizeof(opt_data_key)); + memcpy(&opt_data_mask, geneve_opt_m->data, + RTE_MIN((uint32_t)(geneve_opt_v->option_len * 4), + sizeof(opt_data_mask))); + MLX5_ASSERT((uint32_t)(geneve_opt_v->option_len * 4) <= + sizeof(opt_data_mask)); + MLX5_SET(fte_match_set_misc3, misc3_m, + geneve_tlv_option_0_data, + rte_be_to_cpu_32(opt_data_mask)); + MLX5_SET(fte_match_set_misc3, misc3_v, + geneve_tlv_option_0_data, + rte_be_to_cpu_32(opt_data_key & opt_data_mask)); + } + return ret; +} + /** * Add MPLS item to matcher and to the value. * @@ -10561,6 +10620,17 @@ flow_dv_translate(struct rte_eth_dev *dev, matcher.priority = MLX5_TUNNEL_PRIO_GET(rss_desc); last_item = MLX5_FLOW_LAYER_GENEVE; break; + case RTE_FLOW_ITEM_TYPE_GENEVE_OPT: + ret = flow_dv_translate_item_geneve_opt(dev, match_mask, + match_value, + items, error); + if (ret) + return rte_flow_error_set(error, -ret, + RTE_FLOW_ERROR_TYPE_ITEM, NULL, + "cannot create GENEVE TLV option"); + flow->geneve_tlv_option = 1; + last_item = MLX5_FLOW_LAYER_GENEVE_OPT; + break; case RTE_FLOW_ITEM_TYPE_MPLS: flow_dv_translate_item_mpls(match_mask, match_value, items, last_item, tunnel); -- 2.21.0 ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [dpdk-dev] [PATCH v2 7/8] net/mlx5: add GENEVE TLV option flow translation 2021-01-05 17:53 ` [dpdk-dev] [PATCH v2 7/8] net/mlx5: add GENEVE TLV option flow translation Shiri Kuzin @ 2021-01-06 9:25 ` Slava Ovsiienko 0 siblings, 0 replies; 27+ messages in thread From: Slava Ovsiienko @ 2021-01-06 9:25 UTC (permalink / raw) To: Shiri Kuzin, dev Cc: NBU-Contact-Adrien Mazarguil, Ori Kam, ferruh.yigit, NBU-Contact-Thomas Monjalon, Raslan Darawsheh > -----Original Message----- > From: Shiri Kuzin <shirik@nvidia.com> > Sent: Tuesday, January 5, 2021 19:54 > To: dev@dpdk.org > Cc: Slava Ovsiienko <viacheslavo@nvidia.com>; NBU-Contact-Adrien Mazarguil > <adrien.mazarguil@6wind.com>; Ori Kam <orika@nvidia.com>; > ferruh.yigit@intel.com; NBU-Contact-Thomas Monjalon > <thomas@monjalon.net>; Raslan Darawsheh <rasland@nvidia.com> > Subject: [PATCH v2 7/8] net/mlx5: add GENEVE TLV option flow translation > > The GENEVE TLV option matching flows must be created using a translation > function. > > This function checks whether we already created a Devx object for the > matching and either creates the objects or updates the reference counter. > > Signed-off-by: Shiri Kuzin <shirik@nvidia.com> Acked-by: Viacheslav Ovsiienko <viacheslavo@nvidia.com> ^ permalink raw reply [flat|nested] 27+ messages in thread
* [dpdk-dev] [PATCH v2 8/8] doc: update GENEVE TLV option support 2021-01-05 17:53 ` [dpdk-dev] [PATCH v2 0/8] ethdev: introduce GENEVE header TLV option item Shiri Kuzin ` (6 preceding siblings ...) 2021-01-05 17:53 ` [dpdk-dev] [PATCH v2 7/8] net/mlx5: add GENEVE TLV option flow translation Shiri Kuzin @ 2021-01-05 17:53 ` Shiri Kuzin 2021-01-06 9:26 ` Slava Ovsiienko 7 siblings, 1 reply; 27+ messages in thread From: Shiri Kuzin @ 2021-01-05 17:53 UTC (permalink / raw) To: dev; +Cc: viacheslavo, adrien.mazarguil, orika, ferruh.yigit, thomas, rasland GENEVE TLV option support added to mlx5 PMD. The limitations and support were updated in documentation. Signed-off-by: Shiri Kuzin <shirik@nvidia.com> --- doc/guides/nics/mlx5.rst | 18 +++++++++++++++++- doc/guides/rel_notes/release_21_02.rst | 8 ++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/doc/guides/nics/mlx5.rst b/doc/guides/nics/mlx5.rst index 3bda0f8417..9700fe5057 100644 --- a/doc/guides/nics/mlx5.rst +++ b/doc/guides/nics/mlx5.rst @@ -98,6 +98,7 @@ Features - Hardware LRO. - Hairpin. - Multiple-thread flow insertion. +- Matching on Geneve TLV option header with raw encap/decap action. Limitations ----------- @@ -175,7 +176,18 @@ Limitations - OAM - protocol type - options length - Currently, the only supported options length value is 0. + +- Match on Geneve TLv option is supported on the following fields: + - Class + - Type + - Length + - Data + + Only one Class/Type/Length Geneve TLV option is supported per shared device. + Class/Type/Length fields must be specified as well as masks. + Class/Type/Length specified masks must be full. + Matching Geneve TLV option without specifying data is not supported. + Matching Geneve TLV option with data & mask == 0 is not supported. - VF: flow rules created on VF devices can only match traffic targeted at the configured MAC addresses (see ``rte_eth_dev_mac_addr_add()``). @@ -1022,6 +1034,10 @@ Below are some firmware configurations listed. or FLEX_PARSER_PROFILE_ENABLE=1 +- enable Geneve TLV option flow matching:: + + FLEX_PARSER_PROFILE_ENABLE=0 + - enable GTP flow matching:: FLEX_PARSER_PROFILE_ENABLE=3 diff --git a/doc/guides/rel_notes/release_21_02.rst b/doc/guides/rel_notes/release_21_02.rst index 638f98168b..2fb5bf9c38 100644 --- a/doc/guides/rel_notes/release_21_02.rst +++ b/doc/guides/rel_notes/release_21_02.rst @@ -55,6 +55,14 @@ New Features Also, make sure to start the actual text at the margin. ======================================================= +* **Updated Mellanox mlx5 driver.** + + Updated the Mellanox mlx5 driver with new features and improvements, including: + + * **Added GENEVE TLV option in rte_flow.** + + Added support for matching GENEVE TLV option and raw encap/decap of GENEVE + TLV option. Removed Items ------------- -- 2.21.0 ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [dpdk-dev] [PATCH v2 8/8] doc: update GENEVE TLV option support 2021-01-05 17:53 ` [dpdk-dev] [PATCH v2 8/8] doc: update GENEVE TLV option support Shiri Kuzin @ 2021-01-06 9:26 ` Slava Ovsiienko 0 siblings, 0 replies; 27+ messages in thread From: Slava Ovsiienko @ 2021-01-06 9:26 UTC (permalink / raw) To: Shiri Kuzin, dev Cc: NBU-Contact-Adrien Mazarguil, Ori Kam, ferruh.yigit, NBU-Contact-Thomas Monjalon, Raslan Darawsheh > -----Original Message----- > From: Shiri Kuzin <shirik@nvidia.com> > Sent: Tuesday, January 5, 2021 19:54 > To: dev@dpdk.org > Cc: Slava Ovsiienko <viacheslavo@nvidia.com>; NBU-Contact-Adrien Mazarguil > <adrien.mazarguil@6wind.com>; Ori Kam <orika@nvidia.com>; > ferruh.yigit@intel.com; NBU-Contact-Thomas Monjalon > <thomas@monjalon.net>; Raslan Darawsheh <rasland@nvidia.com> > Subject: [PATCH v2 8/8] doc: update GENEVE TLV option support > > GENEVE TLV option support added to mlx5 PMD. > > The limitations and support were updated in documentation. > > Signed-off-by: Shiri Kuzin <shirik@nvidia.com> Acked-by: Viacheslav Ovsiienko <viacheslavo@nvidia.com> ^ permalink raw reply [flat|nested] 27+ messages in thread
end of thread, other threads:[~2021-01-06 9:26 UTC | newest] Thread overview: 27+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2020-12-27 16:06 [dpdk-dev] [PATCH 0/8] ethdev: introduce GENEVE header TLV option item Shiri Kuzin 2020-12-27 16:06 ` [dpdk-dev] [PATCH 1/8] lib/librte_ethdev: " Shiri Kuzin 2020-12-27 17:25 ` Stephen Hemminger 2020-12-29 10:12 ` Ori Kam 2020-12-30 8:22 ` Shiri Kuzin 2020-12-27 16:06 ` [dpdk-dev] [PATCH 2/8] app/testpmd: add GENEVE option item support Shiri Kuzin 2020-12-27 16:06 ` [dpdk-dev] [PATCH 3/8] common/mlx5: check GENEVE TLV support in HCA attributes Shiri Kuzin 2020-12-27 16:06 ` [dpdk-dev] [PATCH 4/8] common/mlx5: create GENEVE TLV option object with DevX Shiri Kuzin 2020-12-27 16:06 ` [dpdk-dev] [PATCH 5/8] net/mlx5: create GENEVE TLV option management Shiri Kuzin 2020-12-27 16:06 ` [dpdk-dev] [PATCH 6/8] net/mlx5: add GENEVE TLV option flow validation Shiri Kuzin 2020-12-27 16:06 ` [dpdk-dev] [PATCH 7/8] net/mlx5: add GENEVE TLV option flow translation Shiri Kuzin 2020-12-27 16:06 ` [dpdk-dev] [PATCH 8/8] doc: update GENEVE TLV option support Shiri Kuzin 2021-01-05 17:53 ` [dpdk-dev] [PATCH v2 0/8] ethdev: introduce GENEVE header TLV option item Shiri Kuzin 2021-01-05 17:53 ` [dpdk-dev] [PATCH v2 1/8] lib/librte_ethdev: " Shiri Kuzin 2021-01-05 17:53 ` [dpdk-dev] [PATCH v2 2/8] app/testpmd: add GENEVE option item support Shiri Kuzin 2021-01-05 17:53 ` [dpdk-dev] [PATCH v2 3/8] common/mlx5: check GENEVE TLV support in HCA attributes Shiri Kuzin 2021-01-06 9:23 ` Slava Ovsiienko 2021-01-05 17:53 ` [dpdk-dev] [PATCH v2 4/8] common/mlx5: create GENEVE TLV option object with DevX Shiri Kuzin 2021-01-06 9:24 ` Slava Ovsiienko 2021-01-05 17:53 ` [dpdk-dev] [PATCH v2 5/8] net/mlx5: create GENEVE TLV option management Shiri Kuzin 2021-01-06 9:24 ` Slava Ovsiienko 2021-01-05 17:53 ` [dpdk-dev] [PATCH v2 6/8] net/mlx5: add GENEVE TLV option flow validation Shiri Kuzin 2021-01-06 9:24 ` Slava Ovsiienko 2021-01-05 17:53 ` [dpdk-dev] [PATCH v2 7/8] net/mlx5: add GENEVE TLV option flow translation Shiri Kuzin 2021-01-06 9:25 ` Slava Ovsiienko 2021-01-05 17:53 ` [dpdk-dev] [PATCH v2 8/8] doc: update GENEVE TLV option support Shiri Kuzin 2021-01-06 9:26 ` Slava Ovsiienko
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).