From: Shiri Kuzin Date: Sun, 17 Jan 2021 10:21:22 +0000 (+0200) Subject: net/mlx5: add GENEVE TLV option flow translation X-Git-Url: http://git.droids-corp.org/?a=commitdiff_plain;h=e440d6cf589e8774f6ac18819edb4b7bcb2c27a3;p=dpdk.git 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 Acked-by: Viacheslav Ovsiienko --- diff --git a/doc/guides/nics/mlx5.rst b/doc/guides/nics/mlx5.rst index db0c8b6c20..b8f80ac639 100644 --- a/doc/guides/nics/mlx5.rst +++ b/doc/guides/nics/mlx5.rst @@ -99,6 +99,7 @@ Features - Hairpin. - Multiple-thread flow insertion. - Matching on GTP extension header with raw encap/decap action. +- Matching on Geneve TLV option header with raw encap/decap action. Limitations ----------- @@ -186,7 +187,19 @@ 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()``). @@ -1019,6 +1032,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 @@ -1540,6 +1557,11 @@ Supported hardware offloads | | | rdma-core 35 | | rdma-core 35 | | | | ConnectX-6 Dx| | ConnectX-6 Dx | +-----------------------+-----------------+-----------------+ + | Encapsulation | | DPDK 21.02 | | DPDK 21.02 | + | GENEVE TLV option | | OFED 5.2 | | OFED 5.2 | + | | | rdma-core 34 | | rdma-core 34 | + | | | ConnectX-6 Dx | | ConnectX-6 Dx | + +-----------------------+-----------------+-----------------+ Notes for metadata ------------------ diff --git a/drivers/net/mlx5/mlx5_flow.h b/drivers/net/mlx5/mlx5_flow.h index 4c68c65f4f..a9e33b8ab8 100644 --- a/drivers/net/mlx5/mlx5_flow.h +++ b/drivers/net/mlx5/mlx5_flow.h @@ -330,7 +330,7 @@ enum mlx5_feature_name { #define MLX5_GENEVE_VER_VAL(a) \ (((a) >> (MLX5_GENEVE_VER_SHIFT)) & (MLX5_GENEVE_VER_MASK)) #define MLX5_GENEVE_OPTLEN_MASK 0x3F -#define MLX5_GENEVE_OPTLEN_SHIFT 7 +#define MLX5_GENEVE_OPTLEN_SHIFT 8 #define MLX5_GENEVE_OPTLEN_VAL(a) \ (((a) >> (MLX5_GENEVE_OPTLEN_SHIFT)) & (MLX5_GENEVE_OPTLEN_MASK)) #define MLX5_GENEVE_OAMF_MASK 0x1 diff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c index 86c9d2cbbd..936ddfa92f 100644 --- a/drivers/net/mlx5/mlx5_flow_dv.c +++ b/drivers/net/mlx5/mlx5_flow_dv.c @@ -7416,6 +7416,80 @@ exit: 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 *misc_m = MLX5_ADDR_OF(fte_match_param, matcher, misc_parameters); + void *misc_v = MLX5_ADDR_OF(fte_match_param, key, misc_parameters); + 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 option length in GENEVE header if not requested. + * The GENEVE TLV option length is expressed by the option length field + * in the GENEVE header. + * If the option length was not requested but the GENEVE TLV option item + * is present we set the option length field implicitly. + */ + if (!MLX5_GET16(fte_match_set_misc, misc_m, geneve_opt_len)) { + MLX5_SET(fte_match_set_misc, misc_m, geneve_opt_len, + MLX5_GENEVE_OPTLEN_MASK); + MLX5_SET(fte_match_set_misc, misc_v, geneve_opt_len, + geneve_opt_v->option_len + 1); + } + /* 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. * @@ -10739,6 +10813,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);