net/mlx5: update flow mirroring validation
Mirroring flow using sample action with ratio is 1, and it doesn't support jump action with the same one flow. Sample action must have destination actions like port or queue for mirroring, and don't need split function as sampling flow. Signed-off-by: Jiawei Wang <jiaweiw@nvidia.com> Acked-by: Viacheslav Ovsiienko <viacheslavo@nvidia.com>
This commit is contained in:
parent
4d23dd35f2
commit
50390aab11
@ -4251,6 +4251,8 @@ flow_mreg_tx_copy_prep(struct rte_eth_dev *dev,
|
||||
*
|
||||
* @param[in] actions
|
||||
* Pointer to the list of actions.
|
||||
* @param[in] attr
|
||||
* Flow rule attributes.
|
||||
* @param[in] action
|
||||
* The action to be check if exist.
|
||||
* @param[out] match_action_pos
|
||||
@ -4264,10 +4266,15 @@ flow_mreg_tx_copy_prep(struct rte_eth_dev *dev,
|
||||
*/
|
||||
static int
|
||||
flow_check_match_action(const struct rte_flow_action actions[],
|
||||
const struct rte_flow_attr *attr,
|
||||
enum rte_flow_action_type action,
|
||||
int *match_action_pos, int *qrss_action_pos)
|
||||
{
|
||||
const struct rte_flow_action_sample *sample;
|
||||
int actions_n = 0;
|
||||
int jump_flag = 0;
|
||||
uint32_t ratio = 0;
|
||||
int sub_type = 0;
|
||||
int flag = 0;
|
||||
|
||||
*match_action_pos = -1;
|
||||
@ -4280,8 +4287,25 @@ flow_check_match_action(const struct rte_flow_action actions[],
|
||||
if (actions->type == RTE_FLOW_ACTION_TYPE_QUEUE ||
|
||||
actions->type == RTE_FLOW_ACTION_TYPE_RSS)
|
||||
*qrss_action_pos = actions_n;
|
||||
if (actions->type == RTE_FLOW_ACTION_TYPE_JUMP)
|
||||
jump_flag = 1;
|
||||
if (actions->type == RTE_FLOW_ACTION_TYPE_SAMPLE) {
|
||||
sample = actions->conf;
|
||||
ratio = sample->ratio;
|
||||
sub_type = ((const struct rte_flow_action *)
|
||||
(sample->actions))->type;
|
||||
}
|
||||
actions_n++;
|
||||
}
|
||||
if (flag && action == RTE_FLOW_ACTION_TYPE_SAMPLE && attr->transfer) {
|
||||
if (ratio == 1) {
|
||||
/* JUMP Action not support for Mirroring;
|
||||
* Mirroring support multi-destination;
|
||||
*/
|
||||
if (!jump_flag && sub_type != RTE_FLOW_ACTION_TYPE_END)
|
||||
flag = 0;
|
||||
}
|
||||
}
|
||||
/* Count RTE_FLOW_ACTION_TYPE_END. */
|
||||
return flag ? actions_n + 1 : 0;
|
||||
}
|
||||
@ -4833,7 +4857,7 @@ flow_create_split_sample(struct rte_eth_dev *dev,
|
||||
int ret = 0;
|
||||
|
||||
if (priv->sampler_en)
|
||||
actions_n = flow_check_match_action(actions,
|
||||
actions_n = flow_check_match_action(actions, attr,
|
||||
RTE_FLOW_ACTION_TYPE_SAMPLE,
|
||||
&sample_action_pos, &qrss_action_pos);
|
||||
if (actions_n) {
|
||||
|
@ -3374,6 +3374,8 @@ flow_dv_create_action_push_vlan(struct rte_eth_dev *dev,
|
||||
(dev, &res, dev_flow, error);
|
||||
}
|
||||
|
||||
static int fdb_mirror;
|
||||
|
||||
/**
|
||||
* Validate the modify-header actions.
|
||||
*
|
||||
@ -3401,6 +3403,12 @@ flow_dv_validate_action_modify_hdr(const uint64_t action_flags,
|
||||
RTE_FLOW_ERROR_TYPE_ACTION, NULL,
|
||||
"can't have encap action before"
|
||||
" modify action");
|
||||
if ((action_flags & MLX5_FLOW_ACTION_SAMPLE) && fdb_mirror)
|
||||
return rte_flow_error_set(error, EINVAL,
|
||||
RTE_FLOW_ERROR_TYPE_ACTION, NULL,
|
||||
"can't support sample action before"
|
||||
" modify action for E-Switch"
|
||||
" mirroring");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -3724,6 +3732,12 @@ flow_dv_validate_action_jump(const struct rte_flow_action *action,
|
||||
return rte_flow_error_set(error, ENOTSUP,
|
||||
RTE_FLOW_ERROR_TYPE_ACTION, NULL,
|
||||
"jump with meter not support");
|
||||
if ((action_flags & MLX5_FLOW_ACTION_SAMPLE) && fdb_mirror)
|
||||
return rte_flow_error_set(error, EINVAL,
|
||||
RTE_FLOW_ERROR_TYPE_ACTION, NULL,
|
||||
"E-Switch mirroring can't support"
|
||||
" Sample action and jump action in"
|
||||
" same flow now");
|
||||
if (!action->conf)
|
||||
return rte_flow_error_set(error, EINVAL,
|
||||
RTE_FLOW_ERROR_TYPE_ACTION_CONF,
|
||||
@ -4074,8 +4088,10 @@ flow_dv_validate_action_sample(uint64_t action_flags,
|
||||
const struct rte_flow_action_sample *sample = action->conf;
|
||||
const struct rte_flow_action *act;
|
||||
uint64_t sub_action_flags = 0;
|
||||
uint16_t queue_index = 0xFFFF;
|
||||
int actions_n = 0;
|
||||
int ret;
|
||||
fdb_mirror = 0;
|
||||
|
||||
if (!sample)
|
||||
return rte_flow_error_set(error, EINVAL,
|
||||
@ -4119,6 +4135,8 @@ flow_dv_validate_action_sample(uint64_t action_flags,
|
||||
attr, error);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
queue_index = ((const struct rte_flow_action_queue *)
|
||||
(act->conf))->index;
|
||||
sub_action_flags |= MLX5_FLOW_ACTION_QUEUE;
|
||||
++actions_n;
|
||||
break;
|
||||
@ -4142,6 +4160,25 @@ flow_dv_validate_action_sample(uint64_t action_flags,
|
||||
sub_action_flags |= MLX5_FLOW_ACTION_COUNT;
|
||||
++actions_n;
|
||||
break;
|
||||
case RTE_FLOW_ACTION_TYPE_PORT_ID:
|
||||
ret = flow_dv_validate_action_port_id(dev,
|
||||
sub_action_flags,
|
||||
act,
|
||||
attr,
|
||||
error);
|
||||
if (ret)
|
||||
return ret;
|
||||
sub_action_flags |= MLX5_FLOW_ACTION_PORT_ID;
|
||||
++actions_n;
|
||||
break;
|
||||
case RTE_FLOW_ACTION_TYPE_RAW_ENCAP:
|
||||
ret = flow_dv_validate_action_raw_encap_decap
|
||||
(dev, NULL, act->conf, attr, &sub_action_flags,
|
||||
&actions_n, error);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
++actions_n;
|
||||
break;
|
||||
default:
|
||||
return rte_flow_error_set(error, ENOTSUP,
|
||||
RTE_FLOW_ERROR_TYPE_ACTION,
|
||||
@ -4165,10 +4202,43 @@ flow_dv_validate_action_sample(uint64_t action_flags,
|
||||
"or E-Switch");
|
||||
} else if (sample->actions->type != RTE_FLOW_ACTION_TYPE_END) {
|
||||
MLX5_ASSERT(attr->transfer);
|
||||
return rte_flow_error_set(error, ENOTSUP,
|
||||
RTE_FLOW_ERROR_TYPE_ACTION, NULL,
|
||||
"E-Switch doesn't support any "
|
||||
"optional action for sampling");
|
||||
if (sample->ratio > 1)
|
||||
return rte_flow_error_set(error, ENOTSUP,
|
||||
RTE_FLOW_ERROR_TYPE_ACTION,
|
||||
NULL,
|
||||
"E-Switch doesn't support "
|
||||
"any optional action "
|
||||
"for sampling");
|
||||
fdb_mirror = 1;
|
||||
if (sub_action_flags & MLX5_FLOW_ACTION_QUEUE)
|
||||
return rte_flow_error_set(error, ENOTSUP,
|
||||
RTE_FLOW_ERROR_TYPE_ACTION,
|
||||
NULL,
|
||||
"unsupported action QUEUE");
|
||||
if (!(sub_action_flags & MLX5_FLOW_ACTION_PORT_ID))
|
||||
return rte_flow_error_set(error, EINVAL,
|
||||
RTE_FLOW_ERROR_TYPE_ACTION,
|
||||
NULL,
|
||||
"E-Switch must has a dest "
|
||||
"port for mirroring");
|
||||
}
|
||||
/* Continue validation for Xcap actions.*/
|
||||
if ((sub_action_flags & MLX5_FLOW_XCAP_ACTIONS) &&
|
||||
(queue_index == 0xFFFF ||
|
||||
mlx5_rxq_get_type(dev, queue_index) != MLX5_RXQ_TYPE_HAIRPIN)) {
|
||||
if ((sub_action_flags & MLX5_FLOW_XCAP_ACTIONS) ==
|
||||
MLX5_FLOW_XCAP_ACTIONS)
|
||||
return rte_flow_error_set(error, ENOTSUP,
|
||||
RTE_FLOW_ERROR_TYPE_ACTION,
|
||||
NULL, "encap and decap "
|
||||
"combination aren't "
|
||||
"supported");
|
||||
if (!attr->transfer && attr->ingress && (sub_action_flags &
|
||||
MLX5_FLOW_ACTION_ENCAP))
|
||||
return rte_flow_error_set(error, ENOTSUP,
|
||||
RTE_FLOW_ERROR_TYPE_ACTION,
|
||||
NULL, "encap is not supported"
|
||||
" for ingress traffic");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user