From 6431068d0f0ac60d3c31d816f655fd4ff0cf5a6d Mon Sep 17 00:00:00 2001 From: Sean Zhang Date: Tue, 7 Jun 2022 14:19:00 +0300 Subject: [PATCH] net/mlx5: support field modification in meter rules This patch introduces MODIFY_FIELD action support in meter. User can create meter policy with MODIFY_FIELD action in green/yellow action. For example: testpmd> add port meter policy 0 21 g_actions modify_field op set dst_type ipv4_ecn src_type value src_value 3 width 2 / ... Signed-off-by: Sean Zhang Acked-by: Viacheslav Ovsiienko --- doc/guides/nics/mlx5.rst | 4 +-- drivers/net/mlx5/mlx5_flow.c | 5 ++- drivers/net/mlx5/mlx5_flow.h | 2 ++ drivers/net/mlx5/mlx5_flow_dv.c | 49 +++++++++++++++++++++++++++--- drivers/net/mlx5/mlx5_flow_meter.c | 2 +- 5 files changed, 54 insertions(+), 8 deletions(-) diff --git a/doc/guides/nics/mlx5.rst b/doc/guides/nics/mlx5.rst index 7693c13400..73ed28ffaf 100644 --- a/doc/guides/nics/mlx5.rst +++ b/doc/guides/nics/mlx5.rst @@ -446,8 +446,8 @@ Limitations - yellow: NULL or END. - RED: DROP / END. - The only supported meter policy actions: - - green: QUEUE, RSS, PORT_ID, REPRESENTED_PORT, JUMP, DROP, MARK, METER and SET_TAG. - - yellow: QUEUE, RSS, PORT_ID, REPRESENTED_PORT, JUMP, DROP, MARK, METER and SET_TAG. + - green: QUEUE, RSS, PORT_ID, REPRESENTED_PORT, JUMP, DROP, MODIFY_FIELD, MARK, METER and SET_TAG. + - yellow: QUEUE, RSS, PORT_ID, REPRESENTED_PORT, JUMP, DROP, MODIFY_FIELD, MARK, METER and SET_TAG. - RED: must be DROP. - Policy actions of RSS for green and yellow should have the same configuration except queues. - Policy with RSS/queue action is not supported when ``dv_xmeta_en`` enabled. diff --git a/drivers/net/mlx5/mlx5_flow.c b/drivers/net/mlx5/mlx5_flow.c index 5d6c321d95..090de0366b 100644 --- a/drivers/net/mlx5/mlx5_flow.c +++ b/drivers/net/mlx5/mlx5_flow.c @@ -7910,6 +7910,8 @@ mlx5_flow_destroy_mtr_acts(struct rte_eth_dev *dev, * Meter policy struct. * @param[in] action * Action specification used to create meter actions. + * @param[in] attr + * Flow rule attributes. * @param[out] error * Perform verbose error reporting if not NULL. Initialized in case of * error only. @@ -7921,12 +7923,13 @@ int mlx5_flow_create_mtr_acts(struct rte_eth_dev *dev, struct mlx5_flow_meter_policy *mtr_policy, const struct rte_flow_action *actions[RTE_COLORS], + struct rte_flow_attr *attr, struct rte_mtr_error *error) { const struct mlx5_flow_driver_ops *fops; fops = flow_get_drv_ops(MLX5_FLOW_TYPE_DV); - return fops->create_mtr_acts(dev, mtr_policy, actions, error); + return fops->create_mtr_acts(dev, mtr_policy, actions, attr, error); } /** diff --git a/drivers/net/mlx5/mlx5_flow.h b/drivers/net/mlx5/mlx5_flow.h index 85e55eb5d0..f00c033fc5 100644 --- a/drivers/net/mlx5/mlx5_flow.h +++ b/drivers/net/mlx5/mlx5_flow.h @@ -1379,6 +1379,7 @@ typedef int (*mlx5_flow_create_mtr_acts_t) (struct rte_eth_dev *dev, struct mlx5_flow_meter_policy *mtr_policy, const struct rte_flow_action *actions[RTE_COLORS], + struct rte_flow_attr *attr, struct rte_mtr_error *error); typedef void (*mlx5_flow_destroy_mtr_acts_t) (struct rte_eth_dev *dev, @@ -2037,6 +2038,7 @@ void mlx5_flow_destroy_mtr_acts(struct rte_eth_dev *dev, int mlx5_flow_create_mtr_acts(struct rte_eth_dev *dev, struct mlx5_flow_meter_policy *mtr_policy, const struct rte_flow_action *actions[RTE_COLORS], + struct rte_flow_attr *attr, struct rte_mtr_error *error); int mlx5_flow_create_policy_rules(struct rte_eth_dev *dev, struct mlx5_flow_meter_policy *mtr_policy); diff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c index 2b94f7156e..65b02b20ce 100644 --- a/drivers/net/mlx5/mlx5_flow_dv.c +++ b/drivers/net/mlx5/mlx5_flow_dv.c @@ -15871,6 +15871,8 @@ __flow_dv_create_mtr_yellow_action(struct rte_eth_dev *dev, * Meter policy struct. * @param[in] action * Action specification used to create meter actions. + * @param[in] attr + * Pointer to the flow attributes. * @param[out] error * Perform verbose error reporting if not NULL. Initialized in case of * error only. @@ -15882,6 +15884,7 @@ static int __flow_dv_create_domain_policy_acts(struct rte_eth_dev *dev, struct mlx5_flow_meter_policy *mtr_policy, const struct rte_flow_action *actions[RTE_COLORS], + struct rte_flow_attr *attr, enum mlx5_meter_domain domain, struct rte_mtr_error *error) { @@ -16178,6 +16181,28 @@ __flow_dv_create_domain_policy_acts(struct rte_eth_dev *dev, action_flags |= MLX5_FLOW_ACTION_JUMP; break; } + case RTE_FLOW_ACTION_TYPE_MODIFY_FIELD: + { + if (i >= MLX5_MTR_RTE_COLORS) + return -rte_mtr_error_set(error, + ENOTSUP, + RTE_MTR_ERROR_TYPE_METER_POLICY, + NULL, + "cannot create policy modify field for this color"); + if (flow_dv_convert_action_modify_field + (dev, mhdr_res, act, attr, &flow_err)) + return -rte_mtr_error_set(error, + ENOTSUP, + RTE_MTR_ERROR_TYPE_METER_POLICY, + NULL, "cannot setup policy modify field action"); + if (!mhdr_res->actions_num) + return -rte_mtr_error_set(error, + ENOTSUP, + RTE_MTR_ERROR_TYPE_METER_POLICY, + NULL, "cannot find policy modify field action"); + action_flags |= MLX5_FLOW_ACTION_MODIFY_FIELD; + break; + } /* * No need to check meter hierarchy for R colors * here since it is done in the validation stage. @@ -16250,7 +16275,8 @@ __flow_dv_create_domain_policy_acts(struct rte_eth_dev *dev, RTE_MTR_ERROR_TYPE_METER_POLICY, NULL, "action type not supported"); } - if (action_flags & MLX5_FLOW_ACTION_SET_TAG) { + if ((action_flags & MLX5_FLOW_ACTION_SET_TAG) || + (action_flags & MLX5_FLOW_ACTION_MODIFY_FIELD)) { /* create modify action if needed. */ dev_flow.dv.group = 1; if (flow_dv_modify_hdr_resource_register @@ -16258,8 +16284,7 @@ __flow_dv_create_domain_policy_acts(struct rte_eth_dev *dev, return -rte_mtr_error_set(error, ENOTSUP, RTE_MTR_ERROR_TYPE_METER_POLICY, - NULL, "cannot register policy " - "set tag action"); + NULL, "cannot register policy set tag/modify field action"); act_cnt->modify_hdr = dev_flow.handle->dvh.modify_hdr; } @@ -16279,6 +16304,8 @@ __flow_dv_create_domain_policy_acts(struct rte_eth_dev *dev, * Meter policy struct. * @param[in] action * Action specification used to create meter actions. + * @param[in] attr + * Pointer to the flow attributes. * @param[out] error * Perform verbose error reporting if not NULL. Initialized in case of * error only. @@ -16290,6 +16317,7 @@ static int flow_dv_create_mtr_policy_acts(struct rte_eth_dev *dev, struct mlx5_flow_meter_policy *mtr_policy, const struct rte_flow_action *actions[RTE_COLORS], + struct rte_flow_attr *attr, struct rte_mtr_error *error) { int ret, i; @@ -16301,7 +16329,7 @@ flow_dv_create_mtr_policy_acts(struct rte_eth_dev *dev, MLX5_MTR_SUB_POLICY_NUM_MASK; if (sub_policy_num) { ret = __flow_dv_create_domain_policy_acts(dev, - mtr_policy, actions, + mtr_policy, actions, attr, (enum mlx5_meter_domain)i, error); /* Cleaning resource is done in the caller level. */ if (ret) @@ -18553,6 +18581,19 @@ flow_dv_validate_mtr_policy_acts(struct rte_eth_dev *dev, MLX5_FLOW_ACTION_METER_WITH_TERMINATED_POLICY; next_mtr = mtr; break; + case RTE_FLOW_ACTION_TYPE_MODIFY_FIELD: + ret = flow_dv_validate_action_modify_field(dev, + action_flags[i], act, attr, &flow_err); + if (ret < 0) + return -rte_mtr_error_set(error, + ENOTSUP, + RTE_MTR_ERROR_TYPE_METER_POLICY, + NULL, flow_err.message ? + flow_err.message : + "Modify field action validate check fail"); + ++actions_n; + action_flags[i] |= MLX5_FLOW_ACTION_MODIFY_FIELD; + break; default: return -rte_mtr_error_set(error, ENOTSUP, RTE_MTR_ERROR_TYPE_METER_POLICY, diff --git a/drivers/net/mlx5/mlx5_flow_meter.c b/drivers/net/mlx5/mlx5_flow_meter.c index 22f6ca7faf..7c0d84907a 100644 --- a/drivers/net/mlx5/mlx5_flow_meter.c +++ b/drivers/net/mlx5/mlx5_flow_meter.c @@ -916,7 +916,7 @@ mlx5_flow_meter_policy_add(struct rte_eth_dev *dev, } rte_spinlock_init(&mtr_policy->sl); ret = mlx5_flow_create_mtr_acts(dev, mtr_policy, - policy->actions, error); + policy->actions, &attr, error); if (ret) goto policy_add_err; if (mtr_policy->is_hierarchy) { -- 2.39.5