From: Hamdan Igbaria <hamd...@nvidia.com> Introduce jump to matcher action, this action will allow jumping to another matcher. For now this jump restricted to STE array matchers and matchers of size 1.
Signed-off-by: Hamdan Igbaria <hamd...@nvidia.com> --- drivers/net/mlx5/hws/mlx5dr.h | 29 ++++++++++ drivers/net/mlx5/hws/mlx5dr_action.c | 87 +++++++++++++++++++++++++++- drivers/net/mlx5/hws/mlx5dr_action.h | 3 + drivers/net/mlx5/hws/mlx5dr_debug.c | 1 + 4 files changed, 117 insertions(+), 3 deletions(-) diff --git a/drivers/net/mlx5/hws/mlx5dr.h b/drivers/net/mlx5/hws/mlx5dr.h index 8a1a389a3f..1b58eeb2c7 100644 --- a/drivers/net/mlx5/hws/mlx5dr.h +++ b/drivers/net/mlx5/hws/mlx5dr.h @@ -52,6 +52,7 @@ enum mlx5dr_action_type { MLX5DR_ACTION_TYP_POP_IPV6_ROUTE_EXT, MLX5DR_ACTION_TYP_PUSH_IPV6_ROUTE_EXT, MLX5DR_ACTION_TYP_NAT64, + MLX5DR_ACTION_TYP_JUMP_TO_MATCHER, MLX5DR_ACTION_TYP_MAX, }; @@ -287,6 +288,10 @@ struct mlx5dr_rule_action { uint32_t offset; enum mlx5dr_action_aso_ct_flags direction; } aso_ct; + + struct { + uint32_t offset; + } jump_to_matcher; }; }; @@ -304,6 +309,15 @@ struct mlx5dr_action_dest_attr { } reformat; }; +enum mlx5dr_action_jump_to_matcher_type { + MLX5DR_ACTION_JUMP_TO_MATCHER_BY_INDEX, +}; + +struct mlx5dr_action_jump_to_matcher_attr { + enum mlx5dr_action_jump_to_matcher_type type; + struct mlx5dr_matcher *matcher; +}; + union mlx5dr_crc_encap_entropy_hash_ip_field { uint8_t ipv6_addr[16]; struct { @@ -938,6 +952,21 @@ mlx5dr_action_create_nat64(struct mlx5dr_context *ctx, struct mlx5dr_action_nat64_attr *attr, uint32_t flags); +/* Create direct rule jump to matcher action. + * + * @param[in] ctx + * The context in which the new action will be created. + * @param[in] attr + * The relevant attribute of the action. + * @param[in] flags + * Action creation flags. (enum mlx5dr_action_flags) + * @return pointer to mlx5dr_action on success NULL otherwise. + */ +struct mlx5dr_action * +mlx5dr_action_create_jump_to_matcher(struct mlx5dr_context *ctx, + struct mlx5dr_action_jump_to_matcher_attr *attr, + uint32_t flags); + /* Destroy direct rule action. * * @param[in] action diff --git a/drivers/net/mlx5/hws/mlx5dr_action.c b/drivers/net/mlx5/hws/mlx5dr_action.c index 3fceb96de2..3412a96894 100644 --- a/drivers/net/mlx5/hws/mlx5dr_action.c +++ b/drivers/net/mlx5/hws/mlx5dr_action.c @@ -42,7 +42,8 @@ static const uint32_t action_order_arr[MLX5DR_TABLE_TYPE_MAX][MLX5DR_ACTION_TYP_ BIT(MLX5DR_ACTION_TYP_TIR) | BIT(MLX5DR_ACTION_TYP_DROP) | BIT(MLX5DR_ACTION_TYP_DEST_ROOT) | - BIT(MLX5DR_ACTION_TYP_DEST_ARRAY), + BIT(MLX5DR_ACTION_TYP_DEST_ARRAY) | + BIT(MLX5DR_ACTION_TYP_JUMP_TO_MATCHER), BIT(MLX5DR_ACTION_TYP_LAST), }, [MLX5DR_TABLE_TYPE_NIC_TX] = { @@ -62,7 +63,8 @@ static const uint32_t action_order_arr[MLX5DR_TABLE_TYPE_MAX][MLX5DR_ACTION_TYP_ BIT(MLX5DR_ACTION_TYP_TBL) | BIT(MLX5DR_ACTION_TYP_MISS) | BIT(MLX5DR_ACTION_TYP_DROP) | - BIT(MLX5DR_ACTION_TYP_DEST_ROOT), + BIT(MLX5DR_ACTION_TYP_DEST_ROOT) | + BIT(MLX5DR_ACTION_TYP_JUMP_TO_MATCHER), BIT(MLX5DR_ACTION_TYP_LAST), }, [MLX5DR_TABLE_TYPE_FDB] = { @@ -88,7 +90,8 @@ static const uint32_t action_order_arr[MLX5DR_TABLE_TYPE_MAX][MLX5DR_ACTION_TYP_ BIT(MLX5DR_ACTION_TYP_VPORT) | BIT(MLX5DR_ACTION_TYP_DROP) | BIT(MLX5DR_ACTION_TYP_DEST_ROOT) | - BIT(MLX5DR_ACTION_TYP_DEST_ARRAY), + BIT(MLX5DR_ACTION_TYP_DEST_ARRAY) | + BIT(MLX5DR_ACTION_TYP_JUMP_TO_MATCHER), BIT(MLX5DR_ACTION_TYP_LAST), }, }; @@ -1091,6 +1094,13 @@ static void mlx5dr_action_fill_stc_attr(struct mlx5dr_action *action, attr->action_offset = MLX5DR_ACTION_OFFSET_DW5; attr->reparse_mode = MLX5_IFC_STC_REPARSE_ALWAYS; break; + case MLX5DR_ACTION_TYP_JUMP_TO_MATCHER: + attr->action_type = MLX5_IFC_STC_ACTION_TYPE_JUMP_TO_STE_TABLE; + attr->action_offset = MLX5DR_ACTION_OFFSET_HIT; + attr->ste_table.ste = action->jump_to_matcher.matcher->match_ste.ste; + attr->ste_table.ste_pool = action->jump_to_matcher.matcher->match_ste.pool; + attr->ste_table.match_definer_id = action->ctx->caps->trivial_match_definer; + break; default: DR_LOG(ERR, "Invalid action type %d", action->type); assert(false); @@ -3078,6 +3088,57 @@ mlx5dr_action_create_nat64(struct mlx5dr_context *ctx, return NULL; } +struct mlx5dr_action * +mlx5dr_action_create_jump_to_matcher(struct mlx5dr_context *ctx, + struct mlx5dr_action_jump_to_matcher_attr *attr, + uint32_t flags) +{ + struct mlx5dr_matcher *matcher = attr->matcher; + struct mlx5dr_matcher_attr *m_attr; + struct mlx5dr_action *action; + + if (attr->type != MLX5DR_ACTION_JUMP_TO_MATCHER_BY_INDEX) { + DR_LOG(ERR, "Only jump to matcher by index is supported"); + goto enotsup; + } + + if (mlx5dr_action_is_root_flags(flags)) { + DR_LOG(ERR, "Action flags must be only non root (HWS)"); + goto enotsup; + } + + if (mlx5dr_table_is_root(matcher->tbl)) { + DR_LOG(ERR, "Root matcher cannot be set as destination"); + goto enotsup; + } + + m_attr = &matcher->attr; + + if (!(matcher->flags & MLX5DR_MATCHER_FLAGS_STE_ARRAY) && + (m_attr->resizable || m_attr->table.sz_col_log || m_attr->table.sz_row_log)) { + DR_LOG(ERR, "Only STE array or matcher of size 1 can be set as destination"); + goto enotsup; + } + + action = mlx5dr_action_create_generic(ctx, flags, MLX5DR_ACTION_TYP_JUMP_TO_MATCHER); + if (!action) + return NULL; + + action->jump_to_matcher.matcher = matcher; + + if (mlx5dr_action_create_stcs(action, NULL)) { + DR_LOG(ERR, "Failed to create action jump to matcher STC"); + simple_free(action); + return NULL; + } + + return action; + +enotsup: + rte_errno = ENOTSUP; + return NULL; +} + static void mlx5dr_action_destroy_hws(struct mlx5dr_action *action) { struct mlx5dr_devx_obj *obj = NULL; @@ -3100,6 +3161,7 @@ static void mlx5dr_action_destroy_hws(struct mlx5dr_action *action) case MLX5DR_ACTION_TYP_PUSH_VLAN: case MLX5DR_ACTION_TYP_REMOVE_HEADER: case MLX5DR_ACTION_TYP_VPORT: + case MLX5DR_ACTION_TYP_JUMP_TO_MATCHER: mlx5dr_action_destroy_stcs(action); break; case MLX5DR_ACTION_TYP_DEST_ROOT: @@ -3618,6 +3680,19 @@ mlx5dr_action_setter_default_hit(struct mlx5dr_actions_apply_data *apply, htobe32(apply->common_res->default_stc->default_hit.offset); } +static void +mlx5dr_action_setter_hit_matcher(struct mlx5dr_actions_apply_data *apply, + struct mlx5dr_actions_wqe_setter *setter) +{ + struct mlx5dr_rule_action *rule_action; + + rule_action = &apply->rule_action[setter->idx_hit]; + + apply->wqe_data[MLX5DR_ACTION_OFFSET_HIT_LSB] = + htobe32(rule_action->jump_to_matcher.offset << 6); + mlx5dr_action_apply_stc(apply, MLX5DR_ACTION_STC_IDX_HIT, setter->idx_hit); +} + static void mlx5dr_action_setter_hit_next_action(struct mlx5dr_actions_apply_data *apply, __rte_unused struct mlx5dr_actions_wqe_setter *setter) @@ -3965,6 +4040,12 @@ int mlx5dr_action_template_process(struct mlx5dr_action_template *at) } break; + case MLX5DR_ACTION_TYP_JUMP_TO_MATCHER: + last_setter->flags |= ASF_HIT; + last_setter->set_hit = &mlx5dr_action_setter_hit_matcher; + last_setter->idx_hit = i; + break; + default: DR_LOG(ERR, "Unsupported action type: %d", action_type[i]); rte_errno = ENOTSUP; diff --git a/drivers/net/mlx5/hws/mlx5dr_action.h b/drivers/net/mlx5/hws/mlx5dr_action.h index ba4ce55228..8ce4ecd5ba 100644 --- a/drivers/net/mlx5/hws/mlx5dr_action.h +++ b/drivers/net/mlx5/hws/mlx5dr_action.h @@ -223,6 +223,9 @@ struct mlx5dr_action { struct { struct mlx5dr_action *stages[MLX5DR_ACTION_NAT64_STAGES]; } nat64; + struct { + struct mlx5dr_matcher *matcher; + } jump_to_matcher; }; }; diff --git a/drivers/net/mlx5/hws/mlx5dr_debug.c b/drivers/net/mlx5/hws/mlx5dr_debug.c index f15ad96598..8684a8197a 100644 --- a/drivers/net/mlx5/hws/mlx5dr_debug.c +++ b/drivers/net/mlx5/hws/mlx5dr_debug.c @@ -29,6 +29,7 @@ const char *mlx5dr_debug_action_type_str[] = { [MLX5DR_ACTION_TYP_POP_IPV6_ROUTE_EXT] = "POP_IPV6_ROUTE_EXT", [MLX5DR_ACTION_TYP_PUSH_IPV6_ROUTE_EXT] = "PUSH_IPV6_ROUTE_EXT", [MLX5DR_ACTION_TYP_NAT64] = "NAT64", + [MLX5DR_ACTION_TYP_JUMP_TO_MATCHER] = "JUMP_TO_MATCHER", }; static_assert(ARRAY_SIZE(mlx5dr_debug_action_type_str) == MLX5DR_ACTION_TYP_MAX, -- 2.18.2