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 <shi...@nvidia.com> Acked-by: Viacheslav Ovsiienko <viachesl...@nvidia.com> --- drivers/net/mlx5/mlx5_flow.h | 2 +- drivers/net/mlx5/mlx5_flow_dv.c | 80 +++++++++++++++++++++++++++++++++ 2 files changed, 81 insertions(+), 1 deletion(-) diff --git a/drivers/net/mlx5/mlx5_flow.h b/drivers/net/mlx5/mlx5_flow.h index 28db5faee1..d6a6839476 100644 --- a/drivers/net/mlx5/mlx5_flow.h +++ b/drivers/net/mlx5/mlx5_flow.h @@ -329,7 +329,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 c24123fbf3..dc30682896 100644 --- a/drivers/net/mlx5/mlx5_flow_dv.c +++ b/drivers/net/mlx5/mlx5_flow_dv.c @@ -7336,6 +7336,75 @@ 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 *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; + rte_be16_t opt_len = 0x200; + 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. */ + if (!MLX5_GET16(fte_match_set_misc, misc_v, geneve_opt_len)) { + MLX5_SET(fte_match_set_misc, misc_m, geneve_opt_len, + MLX5_GENEVE_OPTLEN_VAL(opt_len)); + MLX5_SET(fte_match_set_misc, misc_v, geneve_opt_len, + MLX5_GENEVE_OPTLEN_VAL(opt_len)); + } + /* 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. * @@ -10583,6 +10652,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