From: Dariusz Sosnowski <dsosnow...@nvidia.com> This patch adds validation step for action templates and validates if RTE_FLOW_ACTION_TYPE_MODIFY_FIELD actions' fields are properly masked.
Signed-off-by: Dariusz Sosnowski <dsosnow...@nvidia.com> --- drivers/net/mlx5/mlx5_flow_hw.c | 132 ++++++++++++++++++++++++++++++++ 1 file changed, 132 insertions(+) diff --git a/drivers/net/mlx5/mlx5_flow_hw.c b/drivers/net/mlx5/mlx5_flow_hw.c index b89d2cc44f..1f98e1248a 100644 --- a/drivers/net/mlx5/mlx5_flow_hw.c +++ b/drivers/net/mlx5/mlx5_flow_hw.c @@ -2047,6 +2047,136 @@ flow_hw_table_destroy(struct rte_eth_dev *dev, return 0; } +static int +flow_hw_validate_action_modify_field(const struct rte_flow_action *action, + const struct rte_flow_action *mask, + struct rte_flow_error *error) +{ + const struct rte_flow_action_modify_field *action_conf = + action->conf; + const struct rte_flow_action_modify_field *mask_conf = + mask->conf; + + if (action_conf->operation != mask_conf->operation) + return rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ACTION, action, + "modify_field operation mask and template are not equal"); + if (action_conf->dst.field != mask_conf->dst.field) + return rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ACTION, action, + "destination field mask and template are not equal"); + if (action_conf->dst.field == RTE_FLOW_FIELD_POINTER || + action_conf->dst.field == RTE_FLOW_FIELD_VALUE) + return rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ACTION, action, + "immediate value and pointer cannot be used as destination"); + if (mask_conf->dst.level != UINT32_MAX) + return rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ACTION, action, + "destination encapsulation level must be fully masked"); + if (mask_conf->dst.offset != UINT32_MAX) + return rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ACTION, action, + "destination offset level must be fully masked"); + if (action_conf->src.field != mask_conf->src.field) + return rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ACTION, action, + "destination field mask and template are not equal"); + if (action_conf->src.field != RTE_FLOW_FIELD_POINTER && + action_conf->src.field != RTE_FLOW_FIELD_VALUE) { + if (mask_conf->src.level != UINT32_MAX) + return rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ACTION, action, + "source encapsulation level must be fully masked"); + if (mask_conf->src.offset != UINT32_MAX) + return rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ACTION, action, + "source offset level must be fully masked"); + } + if (mask_conf->width != UINT32_MAX) + return rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ACTION, action, + "modify_field width field must be fully masked"); + return 0; +} + +static int +flow_hw_action_validate(const struct rte_flow_action actions[], + const struct rte_flow_action masks[], + struct rte_flow_error *error) +{ + int i; + bool actions_end = false; + int ret; + + for (i = 0; !actions_end; ++i) { + const struct rte_flow_action *action = &actions[i]; + const struct rte_flow_action *mask = &masks[i]; + + if (action->type != mask->type) + return rte_flow_error_set(error, ENOTSUP, + RTE_FLOW_ERROR_TYPE_ACTION, + action, + "mask type does not match action type"); + switch (action->type) { + case RTE_FLOW_ACTION_TYPE_VOID: + break; + case RTE_FLOW_ACTION_TYPE_INDIRECT: + /* TODO: Validation logic */ + break; + case RTE_FLOW_ACTION_TYPE_MARK: + /* TODO: Validation logic */ + break; + case RTE_FLOW_ACTION_TYPE_DROP: + /* TODO: Validation logic */ + break; + case RTE_FLOW_ACTION_TYPE_JUMP: + /* TODO: Validation logic */ + break; + case RTE_FLOW_ACTION_TYPE_QUEUE: + /* TODO: Validation logic */ + break; + case RTE_FLOW_ACTION_TYPE_RSS: + /* TODO: Validation logic */ + break; + case RTE_FLOW_ACTION_TYPE_VXLAN_ENCAP: + /* TODO: Validation logic */ + break; + case RTE_FLOW_ACTION_TYPE_NVGRE_ENCAP: + /* TODO: Validation logic */ + break; + case RTE_FLOW_ACTION_TYPE_VXLAN_DECAP: + /* TODO: Validation logic */ + break; + case RTE_FLOW_ACTION_TYPE_NVGRE_DECAP: + /* TODO: Validation logic */ + break; + case RTE_FLOW_ACTION_TYPE_RAW_ENCAP: + /* TODO: Validation logic */ + break; + case RTE_FLOW_ACTION_TYPE_RAW_DECAP: + /* TODO: Validation logic */ + break; + case RTE_FLOW_ACTION_TYPE_MODIFY_FIELD: + ret = flow_hw_validate_action_modify_field(action, + mask, + error); + if (ret < 0) + return ret; + break; + case RTE_FLOW_ACTION_TYPE_END: + actions_end = true; + break; + default: + return rte_flow_error_set(error, ENOTSUP, + RTE_FLOW_ERROR_TYPE_ACTION, + action, + "action not supported in template API"); + } + } + return 0; +} + /** * Create flow action template. * @@ -2075,6 +2205,8 @@ flow_hw_actions_template_create(struct rte_eth_dev *dev, int len, act_len, mask_len, i; struct rte_flow_actions_template *at; + if (flow_hw_action_validate(actions, masks, error)) + return NULL; act_len = rte_flow_conv(RTE_FLOW_CONV_OP_ACTIONS, NULL, 0, actions, error); if (act_len <= 0) -- 2.25.1