From patchwork Sun Dec 27 16:06:16 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Shiri Kuzin X-Patchwork-Id: 85743 X-Patchwork-Delegate: ferruh.yigit@amd.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id 3007CA09FF; Sun, 27 Dec 2020 17:06:54 +0100 (CET) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id CBF914F9C; Sun, 27 Dec 2020 17:06:43 +0100 (CET) Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by dpdk.org (Postfix) with ESMTP id 8F5034F96 for ; Sun, 27 Dec 2020 17:06:42 +0100 (CET) Received: from Internal Mail-Server by MTLPINE1 (envelope-from shirik@nvidia.com) with SMTP; 27 Dec 2020 18:06:37 +0200 Received: from nvidia.com (nps-server-11.mtl.labs.mlnx [10.7.12.71]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id 0BRG6VZS006105; Sun, 27 Dec 2020 18:06:36 +0200 From: Shiri Kuzin To: dev@dpdk.org Cc: viacheslavo@nvidia.com, adrien.mazarguil@6wind.com, orika@nvidia.com, ferruh.yigit@intel.com, thomas@monjalon.net, rasland@nvidia.com Date: Sun, 27 Dec 2020 18:06:16 +0200 Message-Id: <1609085183-25229-2-git-send-email-shirik@nvidia.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1609085183-25229-1-git-send-email-shirik@nvidia.com> References: <1609085183-25229-1-git-send-email-shirik@nvidia.com> Subject: [dpdk-dev] [PATCH 1/8] lib/librte_ethdev: introduce GENEVE header TLV option item X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" 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 --- 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. * From patchwork Sun Dec 27 16:06:17 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Shiri Kuzin X-Patchwork-Id: 85745 X-Patchwork-Delegate: ferruh.yigit@amd.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id 1EAF0A09FF; Sun, 27 Dec 2020 17:07:35 +0100 (CET) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 1A132C9AC; Sun, 27 Dec 2020 17:06:51 +0100 (CET) Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by dpdk.org (Postfix) with ESMTP id 9B9EAC8DC for ; Sun, 27 Dec 2020 17:06:47 +0100 (CET) Received: from Internal Mail-Server by MTLPINE1 (envelope-from shirik@nvidia.com) with SMTP; 27 Dec 2020 18:06:41 +0200 Received: from nvidia.com (nps-server-11.mtl.labs.mlnx [10.7.12.71]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id 0BRG6VZT006105; Sun, 27 Dec 2020 18:06:41 +0200 From: Shiri Kuzin To: dev@dpdk.org Cc: viacheslavo@nvidia.com, adrien.mazarguil@6wind.com, orika@nvidia.com, ferruh.yigit@intel.com, thomas@monjalon.net, rasland@nvidia.com Date: Sun, 27 Dec 2020 18:06:17 +0200 Message-Id: <1609085183-25229-3-git-send-email-shirik@nvidia.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1609085183-25229-1-git-send-email-shirik@nvidia.com> References: <1609085183-25229-1-git-send-email-shirik@nvidia.com> Subject: [dpdk-dev] [PATCH 2/8] app/testpmd: add GENEVE option item support X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" From: Viacheslav Ovsiienko 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 --- 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. From patchwork Sun Dec 27 16:06:18 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Shiri Kuzin X-Patchwork-Id: 85744 X-Patchwork-Delegate: ferruh.yigit@amd.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id 49A0FA09FF; Sun, 27 Dec 2020 17:07:16 +0100 (CET) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 6E89DC8DC; Sun, 27 Dec 2020 17:06:49 +0100 (CET) Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by dpdk.org (Postfix) with ESMTP id 8DDB4C8A6 for ; Sun, 27 Dec 2020 17:06:47 +0100 (CET) Received: from Internal Mail-Server by MTLPINE1 (envelope-from shirik@nvidia.com) with SMTP; 27 Dec 2020 18:06:45 +0200 Received: from nvidia.com (nps-server-11.mtl.labs.mlnx [10.7.12.71]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id 0BRG6VZU006105; Sun, 27 Dec 2020 18:06:45 +0200 From: Shiri Kuzin To: dev@dpdk.org Cc: viacheslavo@nvidia.com, adrien.mazarguil@6wind.com, orika@nvidia.com, ferruh.yigit@intel.com, thomas@monjalon.net, rasland@nvidia.com Date: Sun, 27 Dec 2020 18:06:18 +0200 Message-Id: <1609085183-25229-4-git-send-email-shirik@nvidia.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1609085183-25229-1-git-send-email-shirik@nvidia.com> References: <1609085183-25229-1-git-send-email-shirik@nvidia.com> Subject: [dpdk-dev] [PATCH 3/8] common/mlx5: check GENEVE TLV support in HCA attributes X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" 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 --- 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, From patchwork Sun Dec 27 16:06:19 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Shiri Kuzin X-Patchwork-Id: 85747 X-Patchwork-Delegate: ferruh.yigit@amd.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id 5AA3BA09FF; Sun, 27 Dec 2020 17:08:14 +0100 (CET) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 31DFECA0A; Sun, 27 Dec 2020 17:06:56 +0100 (CET) Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by dpdk.org (Postfix) with ESMTP id F3FB2C9B8 for ; Sun, 27 Dec 2020 17:06:52 +0100 (CET) Received: from Internal Mail-Server by MTLPINE1 (envelope-from shirik@nvidia.com) with SMTP; 27 Dec 2020 18:06:48 +0200 Received: from nvidia.com (nps-server-11.mtl.labs.mlnx [10.7.12.71]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id 0BRG6VZV006105; Sun, 27 Dec 2020 18:06:48 +0200 From: Shiri Kuzin To: dev@dpdk.org Cc: viacheslavo@nvidia.com, adrien.mazarguil@6wind.com, orika@nvidia.com, ferruh.yigit@intel.com, thomas@monjalon.net, rasland@nvidia.com Date: Sun, 27 Dec 2020 18:06:19 +0200 Message-Id: <1609085183-25229-5-git-send-email-shirik@nvidia.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1609085183-25229-1-git-send-email-shirik@nvidia.com> References: <1609085183-25229-1-git-send-email-shirik@nvidia.com> Subject: [dpdk-dev] [PATCH 4/8] common/mlx5: create GENEVE TLV option object with DevX X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" 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 --- 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; From patchwork Sun Dec 27 16:06:20 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Shiri Kuzin X-Patchwork-Id: 85746 X-Patchwork-Delegate: ferruh.yigit@amd.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id 68E09A09FF; Sun, 27 Dec 2020 17:07:55 +0100 (CET) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id A1DEBC9B8; Sun, 27 Dec 2020 17:06:54 +0100 (CET) Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by dpdk.org (Postfix) with ESMTP id EA677C9B6 for ; Sun, 27 Dec 2020 17:06:52 +0100 (CET) Received: from Internal Mail-Server by MTLPINE1 (envelope-from shirik@nvidia.com) with SMTP; 27 Dec 2020 18:06:50 +0200 Received: from nvidia.com (nps-server-11.mtl.labs.mlnx [10.7.12.71]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id 0BRG6VZW006105; Sun, 27 Dec 2020 18:06:50 +0200 From: Shiri Kuzin To: dev@dpdk.org Cc: viacheslavo@nvidia.com, adrien.mazarguil@6wind.com, orika@nvidia.com, ferruh.yigit@intel.com, thomas@monjalon.net, rasland@nvidia.com Date: Sun, 27 Dec 2020 18:06:20 +0200 Message-Id: <1609085183-25229-6-git-send-email-shirik@nvidia.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1609085183-25229-1-git-send-email-shirik@nvidia.com> References: <1609085183-25229-1-git-send-email-shirik@nvidia.com> Subject: [dpdk-dev] [PATCH 5/8] net/mlx5: create GENEVE TLV option management X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" 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 --- 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; From patchwork Sun Dec 27 16:06:21 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Shiri Kuzin X-Patchwork-Id: 85748 X-Patchwork-Delegate: ferruh.yigit@amd.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id 41F54A09FF; Sun, 27 Dec 2020 17:08:36 +0100 (CET) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 43C80CA4C; Sun, 27 Dec 2020 17:06:59 +0100 (CET) Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by dpdk.org (Postfix) with ESMTP id A9908CA2E for ; Sun, 27 Dec 2020 17:06:56 +0100 (CET) Received: from Internal Mail-Server by MTLPINE1 (envelope-from shirik@nvidia.com) with SMTP; 27 Dec 2020 18:06:55 +0200 Received: from nvidia.com (nps-server-11.mtl.labs.mlnx [10.7.12.71]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id 0BRG6VZX006105; Sun, 27 Dec 2020 18:06:55 +0200 From: Shiri Kuzin To: dev@dpdk.org Cc: viacheslavo@nvidia.com, adrien.mazarguil@6wind.com, orika@nvidia.com, ferruh.yigit@intel.com, thomas@monjalon.net, rasland@nvidia.com Date: Sun, 27 Dec 2020 18:06:21 +0200 Message-Id: <1609085183-25229-7-git-send-email-shirik@nvidia.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1609085183-25229-1-git-send-email-shirik@nvidia.com> References: <1609085183-25229-1-git-send-email-shirik@nvidia.com> Subject: [dpdk-dev] [PATCH 6/8] net/mlx5: add GENEVE TLV option flow validation X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" 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 --- 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); From patchwork Sun Dec 27 16:06:22 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Shiri Kuzin X-Patchwork-Id: 85749 X-Patchwork-Delegate: ferruh.yigit@amd.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id 57CF3A09FF; Sun, 27 Dec 2020 17:08:55 +0100 (CET) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id C3BD9CA5E; Sun, 27 Dec 2020 17:07:04 +0100 (CET) Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by dpdk.org (Postfix) with ESMTP id DFF74CA5C for ; Sun, 27 Dec 2020 17:07:02 +0100 (CET) Received: from Internal Mail-Server by MTLPINE1 (envelope-from shirik@nvidia.com) with SMTP; 27 Dec 2020 18:06:58 +0200 Received: from nvidia.com (nps-server-11.mtl.labs.mlnx [10.7.12.71]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id 0BRG6VZY006105; Sun, 27 Dec 2020 18:06:58 +0200 From: Shiri Kuzin To: dev@dpdk.org Cc: viacheslavo@nvidia.com, adrien.mazarguil@6wind.com, orika@nvidia.com, ferruh.yigit@intel.com, thomas@monjalon.net, rasland@nvidia.com Date: Sun, 27 Dec 2020 18:06:22 +0200 Message-Id: <1609085183-25229-8-git-send-email-shirik@nvidia.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1609085183-25229-1-git-send-email-shirik@nvidia.com> References: <1609085183-25229-1-git-send-email-shirik@nvidia.com> Subject: [dpdk-dev] [PATCH 7/8] net/mlx5: add GENEVE TLV option flow translation X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" 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 --- 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); From patchwork Sun Dec 27 16:06:23 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Shiri Kuzin X-Patchwork-Id: 85750 X-Patchwork-Delegate: ferruh.yigit@amd.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id 84C70A09FF; Sun, 27 Dec 2020 17:09:13 +0100 (CET) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 5975ECA45; Sun, 27 Dec 2020 17:07:09 +0100 (CET) Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by dpdk.org (Postfix) with ESMTP id ACDABCA64 for ; Sun, 27 Dec 2020 17:07:07 +0100 (CET) Received: from Internal Mail-Server by MTLPINE1 (envelope-from shirik@nvidia.com) with SMTP; 27 Dec 2020 18:07:01 +0200 Received: from nvidia.com (nps-server-11.mtl.labs.mlnx [10.7.12.71]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id 0BRG6VZZ006105; Sun, 27 Dec 2020 18:07:01 +0200 From: Shiri Kuzin To: dev@dpdk.org Cc: viacheslavo@nvidia.com, adrien.mazarguil@6wind.com, orika@nvidia.com, ferruh.yigit@intel.com, thomas@monjalon.net, rasland@nvidia.com Date: Sun, 27 Dec 2020 18:06:23 +0200 Message-Id: <1609085183-25229-9-git-send-email-shirik@nvidia.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1609085183-25229-1-git-send-email-shirik@nvidia.com> References: <1609085183-25229-1-git-send-email-shirik@nvidia.com> Subject: [dpdk-dev] [PATCH 8/8] doc: update GENEVE TLV option support X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" GENEVE TLV option support added to mlx5 PMD. The limitations and support were updated in documentation. Signed-off-by: Shiri Kuzin --- 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