Currently in meter hierarchy, only meter action is supported for green
and yellow policy flow.
This patch adds support of jump action for green or yellow policy flow.

Fixes: 96ca87da4f46 ("net/mlx5: validate yellow meter action")
Cc: sta...@dpdk.org

Signed-off-by: Shun Hao <sh...@nvidia.com>
Acked-by: Suanming Mou <suanmi...@nvidia.com>
---
 drivers/net/mlx5/mlx5_flow_dv.c | 36 ++++++++++++++++++---------------
 1 file changed, 20 insertions(+), 16 deletions(-)

diff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c
index 6f72185916..85ea840dee 100644
--- a/drivers/net/mlx5/mlx5_flow_dv.c
+++ b/drivers/net/mlx5/mlx5_flow_dv.c
@@ -17949,7 +17949,7 @@ __flow_dv_create_policy_matcher(struct rte_eth_dev *dev,
 static int
 __flow_dv_create_domain_policy_rules(struct rte_eth_dev *dev,
                struct mlx5_flow_meter_sub_policy *sub_policy,
-               uint8_t egress, uint8_t transfer, bool match_src_port,
+               uint8_t egress, uint8_t transfer, bool *match_src_port,
                struct mlx5_meter_policy_acts acts[RTE_COLORS])
 {
        struct mlx5_priv *priv = dev->data->dev_private;
@@ -17964,6 +17964,7 @@ __flow_dv_create_domain_policy_rules(struct rte_eth_dev 
*dev,
                .reserved = 0,
        };
        int i;
+       uint16_t priority;
        int ret = mlx5_flow_get_reg_id(dev, MLX5_MTR_COLOR, 0, &flow_err);
        struct mlx5_sub_policy_color_rule *color_rule;
        struct mlx5_sub_policy_color_rule *tmp_rules[RTE_COLORS] = {NULL};
@@ -17998,12 +17999,12 @@ __flow_dv_create_domain_policy_rules(struct 
rte_eth_dev *dev,
                TAILQ_INSERT_TAIL(&sub_policy->color_rules[i],
                                  color_rule, next_port);
                color_rule->src_port = priv->representor_id;
-               /* No use. */
-               attr.priority = i;
+               priority = (match_src_port[i] == 
match_src_port[RTE_COLOR_GREEN]) ?
+                          MLX5_MTR_POLICY_MATCHER_PRIO : 
(MLX5_MTR_POLICY_MATCHER_PRIO + 1);
                /* Create matchers for colors. */
                if (__flow_dv_create_policy_matcher(dev, color_reg_c_idx,
-                               MLX5_MTR_POLICY_MATCHER_PRIO, sub_policy,
-                               &attr, match_src_port, NULL,
+                               priority, sub_policy,
+                               &attr, match_src_port[i], NULL,
                                &color_rule->matcher, &flow_err)) {
                        DRV_LOG(ERR, "Failed to create color%u matcher.", i);
                        goto err_exit;
@@ -18013,7 +18014,7 @@ __flow_dv_create_domain_policy_rules(struct rte_eth_dev 
*dev,
                                color_reg_c_idx, (enum rte_color)i,
                                color_rule->matcher,
                                acts[i].actions_n, acts[i].dv_actions,
-                               match_src_port, NULL, &color_rule->rule,
+                               match_src_port[i], NULL, &color_rule->rule,
                                &attr)) {
                        DRV_LOG(ERR, "Failed to create color%u rule.", i);
                        goto err_exit;
@@ -18061,7 +18062,7 @@ __flow_dv_create_policy_acts_rules(struct rte_eth_dev 
*dev,
        uint8_t egress = (domain == MLX5_MTR_DOMAIN_EGRESS) ? 1 : 0;
        uint8_t transfer = (domain == MLX5_MTR_DOMAIN_TRANSFER) ? 1 : 0;
        bool mtr_first = egress || (transfer && priv->representor_id != 
UINT16_MAX);
-       bool match_src_port = false;
+       bool match_src_port[RTE_COLORS] = {false};
        int i;
 
        /* If RSS or Queue, no previous actions / rules is created. */
@@ -18132,7 +18133,7 @@ __flow_dv_create_policy_acts_rules(struct rte_eth_dev 
*dev,
                                acts[i].dv_actions[acts[i].actions_n] =
                                        port_action->action;
                                acts[i].actions_n++;
-                               match_src_port = true;
+                               match_src_port[i] = true;
                                break;
                        case MLX5_FLOW_FATE_DROP:
                        case MLX5_FLOW_FATE_JUMP:
@@ -18184,7 +18185,7 @@ __flow_dv_create_policy_acts_rules(struct rte_eth_dev 
*dev,
                                acts[i].dv_actions[acts[i].actions_n++] =
                                                        tbl_data->jump.action;
                                if (mtr_policy->act_cnt[i].modify_hdr)
-                                       match_src_port = !!transfer;
+                                       match_src_port[i] = !!transfer;
                                break;
                        default:
                                /*Queue action do nothing*/
@@ -18198,9 +18199,9 @@ __flow_dv_create_policy_acts_rules(struct rte_eth_dev 
*dev,
                        "Failed to create policy rules per domain.");
                goto err_exit;
        }
-       if (match_src_port) {
-               mtr_policy->match_port = match_src_port;
-               mtr_policy->hierarchy_match_port = match_src_port;
+       if (match_src_port[RTE_COLOR_GREEN] || 
match_src_port[RTE_COLOR_YELLOW]) {
+               mtr_policy->match_port = 1;
+               mtr_policy->hierarchy_match_port = 1;
        }
        return 0;
 err_exit:
@@ -18262,6 +18263,7 @@ __flow_dv_create_domain_def_policy(struct rte_eth_dev 
*dev, uint32_t domain)
        uint8_t egress, transfer;
        struct rte_flow_error error;
        struct mlx5_meter_policy_acts acts[RTE_COLORS];
+       bool match_src_port[RTE_COLORS] = {false};
        int ret;
 
        egress = (domain == MLX5_MTR_DOMAIN_EGRESS) ? 1 : 0;
@@ -18337,7 +18339,7 @@ __flow_dv_create_domain_def_policy(struct rte_eth_dev 
*dev, uint32_t domain)
                /* Create default policy rules. */
                ret = __flow_dv_create_domain_policy_rules(dev,
                                        &def_policy->sub_policy,
-                                       egress, transfer, false, acts);
+                                       egress, transfer, match_src_port, acts);
                if (ret) {
                        DRV_LOG(ERR, "Failed to create default policy rules.");
                        goto def_policy_error;
@@ -19920,11 +19922,13 @@ flow_dv_validate_mtr_policy_acts(struct rte_eth_dev 
*dev,
                }
        }
        if (next_mtr && *policy_mode == MLX5_MTR_POLICY_MODE_ALL) {
-               if (!(action_flags[RTE_COLOR_GREEN] & 
action_flags[RTE_COLOR_YELLOW] &
-                     MLX5_FLOW_ACTION_METER_WITH_TERMINATED_POLICY))
+               uint64_t hierarchy_type_flag =
+                       MLX5_FLOW_ACTION_METER_WITH_TERMINATED_POLICY | 
MLX5_FLOW_ACTION_JUMP;
+               if (!(action_flags[RTE_COLOR_GREEN] & hierarchy_type_flag) ||
+                   !(action_flags[RTE_COLOR_YELLOW] & hierarchy_type_flag))
                        return -rte_mtr_error_set(error, EINVAL, 
RTE_MTR_ERROR_TYPE_METER_POLICY,
                                                  NULL,
-                                                 "Meter hierarchy supports 
meter action only.");
+                                                 "Unsupported action in meter 
hierarchy.");
        }
        /* If both colors have RSS, the attributes should be the same. */
        if (flow_dv_mtr_policy_rss_compare(rss_color[RTE_COLOR_GREEN],
-- 
2.20.0

Reply via email to