The rte action will be translated to 3 dr_actions which need 3 setters to program them.
For each setter, it may have different reparsing properties. Setter which requires no reparse can't share the same one with the one has reparse enabled even if there is spare space. Signed-off-by: Rongwei Liu <rongw...@nvidia.com> --- drivers/net/mlx5/hws/mlx5dr_action.c | 144 +++++++++++++++++++++++++++ 1 file changed, 144 insertions(+) diff --git a/drivers/net/mlx5/hws/mlx5dr_action.c b/drivers/net/mlx5/hws/mlx5dr_action.c index fa38654644..9f2386479a 100644 --- a/drivers/net/mlx5/hws/mlx5dr_action.c +++ b/drivers/net/mlx5/hws/mlx5dr_action.c @@ -2318,6 +2318,57 @@ mlx5dr_action_setter_modify_header(struct mlx5dr_actions_apply_data *apply, } } +static void +mlx5dr_action_setter_ipv6_routing_pop1(struct mlx5dr_actions_apply_data *apply, + struct mlx5dr_actions_wqe_setter *setter) +{ + struct mlx5dr_rule_action *rule_action; + struct mlx5dr_action *action; + + rule_action = &apply->rule_action[setter->idx_double]; + action = rule_action->action; + MLX5_ASSERT(action->type == MLX5DR_ACTION_TYP_IPV6_ROUTING_POP); + rule_action->action = action->recom.action1; + MLX5_ASSERT(rule_action->action->flags & MLX5DR_ACTION_FLAG_SHARED); + MLX5_ASSERT(rule_action->action->type == MLX5DR_ACTION_TYP_MODIFY_HDR); + mlx5dr_action_setter_modify_header(apply, setter); + rule_action->action = action; +} + +static void +mlx5dr_action_setter_ipv6_routing_pop2(struct mlx5dr_actions_apply_data *apply, + struct mlx5dr_actions_wqe_setter *setter) +{ + struct mlx5dr_rule_action *rule_action; + struct mlx5dr_action *action; + + rule_action = &apply->rule_action[setter->idx_double]; + action = rule_action->action; + MLX5_ASSERT(action->type == MLX5DR_ACTION_TYP_IPV6_ROUTING_POP); + rule_action->action = action->recom.action2; + MLX5_ASSERT(rule_action->action->flags & MLX5DR_ACTION_FLAG_SHARED); + MLX5_ASSERT(rule_action->action->type == MLX5DR_ACTION_TYP_MODIFY_HDR); + mlx5dr_action_setter_modify_header(apply, setter); + rule_action->action = action; +} + +static void +mlx5dr_action_setter_ipv6_routing_pop3(struct mlx5dr_actions_apply_data *apply, + struct mlx5dr_actions_wqe_setter *setter) +{ + struct mlx5dr_rule_action *rule_action; + struct mlx5dr_action *action; + + rule_action = &apply->rule_action[setter->idx_double]; + action = rule_action->action; + MLX5_ASSERT(action->type == MLX5DR_ACTION_TYP_IPV6_ROUTING_POP); + rule_action->action = action->recom.action3; + MLX5_ASSERT(rule_action->action->flags & MLX5DR_ACTION_FLAG_SHARED); + MLX5_ASSERT(rule_action->action->type == MLX5DR_ACTION_TYP_IPV6_ROUTING_POP); + mlx5dr_action_setter_modify_header(apply, setter); + rule_action->action = action; +} + static void mlx5dr_action_setter_insert_ptr(struct mlx5dr_actions_apply_data *apply, struct mlx5dr_actions_wqe_setter *setter) @@ -2346,6 +2397,60 @@ mlx5dr_action_setter_insert_ptr(struct mlx5dr_actions_apply_data *apply, } } +static void +mlx5dr_action_setter_ipv6_routing_push1(struct mlx5dr_actions_apply_data *apply, + struct mlx5dr_actions_wqe_setter *setter) +{ + struct mlx5dr_rule_action *rule_action; + struct mlx5dr_rule_action tmp; + + rule_action = &apply->rule_action[setter->idx_double]; + tmp = *rule_action; + MLX5_ASSERT(rule_action->action->type == MLX5DR_ACTION_TYP_IPV6_ROUTING_PUSH); + rule_action->action = tmp.action->recom.action1; + MLX5_ASSERT(rule_action->action->type == MLX5DR_ACTION_TYP_IPV6_ROUTING_PUSH); + rule_action->reformat.offset = tmp.recom.offset; + rule_action->reformat.data = tmp.recom.data; + mlx5dr_action_setter_insert_ptr(apply, setter); + *rule_action = tmp; +} + +static void +mlx5dr_action_setter_ipv6_routing_push2(struct mlx5dr_actions_apply_data *apply, + struct mlx5dr_actions_wqe_setter *setter) +{ + struct mlx5dr_rule_action *rule_action; + struct mlx5dr_action *action; + + rule_action = &apply->rule_action[setter->idx_double]; + action = rule_action->action; + MLX5_ASSERT(action->type == MLX5DR_ACTION_TYP_IPV6_ROUTING_PUSH); + rule_action->action = action->recom.action2; + MLX5_ASSERT(rule_action->action->flags & MLX5DR_ACTION_FLAG_SHARED); + MLX5_ASSERT(rule_action->action->type == MLX5DR_ACTION_TYP_MODIFY_HDR); + mlx5dr_action_setter_modify_header(apply, setter); + rule_action->action = action; +} + +static void +mlx5dr_action_setter_ipv6_routing_push3(struct mlx5dr_actions_apply_data *apply, + struct mlx5dr_actions_wqe_setter *setter) +{ + struct mlx5dr_rule_action *rule_action; + struct mlx5dr_rule_action tmp; + + rule_action = &apply->rule_action[setter->idx_double]; + tmp = *rule_action; + MLX5_ASSERT(rule_action->action->type == MLX5DR_ACTION_TYP_IPV6_ROUTING_PUSH); + rule_action->action = tmp.action->recom.action3; + MLX5_ASSERT(rule_action->action->type == MLX5DR_ACTION_TYP_MODIFY_HDR); + rule_action->modify_header.offset = tmp.recom.offset; + rule_action->modify_header.data = tmp.recom.mhdr; + MLX5_ASSERT(rule_action->action->modify_header.num_of_actions > 1); + mlx5dr_action_setter_modify_header(apply, setter); + *rule_action = tmp; +} + static void mlx5dr_action_setter_tnl_l3_to_l2(struct mlx5dr_actions_apply_data *apply, struct mlx5dr_actions_wqe_setter *setter) @@ -2553,6 +2658,45 @@ int mlx5dr_action_template_process(struct mlx5dr_action_template *at) setter->idx_double = i; break; + case MLX5DR_ACTION_TYP_IPV6_ROUTING_POP: + /* Double internal modify header list */ + setter = mlx5dr_action_setter_find_first(last_setter, + ASF_DOUBLE | ASF_REMOVE); + setter->flags |= ASF_DOUBLE | ASF_MODIFY | ASF_REPARSE; + setter->set_double = &mlx5dr_action_setter_ipv6_routing_pop1; + setter->idx_double = i; + setter++; + setter->flags |= ASF_DOUBLE | ASF_MODIFY | ASF_REPARSE; + setter->set_double = &mlx5dr_action_setter_ipv6_routing_pop2; + setter->idx_double = i; + setter++; + /* restore IPv6 protocol + pop via modify list. */ + setter->flags |= ASF_DOUBLE | ASF_MODIFY | ASF_REPARSE; + setter->set_double = &mlx5dr_action_setter_ipv6_routing_pop3; + setter->idx_double = i; + break; + + case MLX5DR_ACTION_TYP_IPV6_ROUTING_PUSH: + /* Double insert header with pointer */ + setter = mlx5dr_action_setter_find_first(last_setter, ASF_DOUBLE); + /* Can't squeeze with reparsing setter */ + if (setter->flags & ASF_REPARSE) + setter++; + setter->flags |= ASF_DOUBLE; + setter->set_double = &mlx5dr_action_setter_ipv6_routing_push1; + setter->idx_double = i; + setter++; + /* Set IPv6 protocol to 0x2b */ + setter->flags |= ASF_DOUBLE | ASF_MODIFY | ASF_REPARSE; + setter->set_double = &mlx5dr_action_setter_ipv6_routing_push2; + setter->idx_double = i; + setter++; + /* Load next hop IPv6 address and restore srv6.next_hdr */ + setter->flags |= ASF_DOUBLE | ASF_MODIFY | ASF_REPARSE; + setter->set_double = &mlx5dr_action_setter_ipv6_routing_push3; + setter->idx_double = i; + break; + case MLX5DR_ACTION_TYP_MODIFY_HDR: /* Double modify header list */ setter = mlx5dr_action_setter_find_first(last_setter, ASF_DOUBLE | ASF_REMOVE); -- 2.27.0