net/mlx5: fix E-Switch egress mirror flow validation
The stored metadata in all registers C were lost in E-Switch egress
mirroring flows due to HW limitation. The register C0 keeps the
source vport index that also was used as one of the flow matcher.
While sample action and jump action (jump to table X) was in the
E-Switch egress flow, the flow in the next table X wasn't hit since
source vport value lost.
The modify actions after sample action should be applied to the packet
on normal path, not to the sampled packet. In order to support this
mlx5 PMD splits the flow into sub flows and jump action is engaged
implicitly, causing malfunction due to registers corruption.
This patch adds the validation the for E-Switch mirroring jump egress
flow, and checks for this hidden jump as well and reject the flows with
modify actions after sampling.
Fixes: 6a951567c1
("net/mlx5: support E-Switch mirroring and jump in one flow")
Cc: stable@dpdk.org
Signed-off-by: Jiawei Wang <jiaweiw@nvidia.com>
Acked-by: Viacheslav Ovsiienko <viacheslavo@nvidia.com>
This commit is contained in:
parent
493f0bb51c
commit
255b8f86eb
@ -5093,6 +5093,8 @@ flow_dv_modify_create_cb(struct mlx5_hlist *list, uint64_t key __rte_unused,
|
|||||||
* Pointer to the RSS action in sample action list.
|
* Pointer to the RSS action in sample action list.
|
||||||
* @param[out] count
|
* @param[out] count
|
||||||
* Pointer to the COUNT action in sample action list.
|
* Pointer to the COUNT action in sample action list.
|
||||||
|
* @param[out] fdb_mirror_limit
|
||||||
|
* Pointer to the FDB mirror limitation flag.
|
||||||
* @param[out] error
|
* @param[out] error
|
||||||
* Pointer to error structure.
|
* Pointer to error structure.
|
||||||
*
|
*
|
||||||
@ -5108,6 +5110,7 @@ flow_dv_validate_action_sample(uint64_t *action_flags,
|
|||||||
const struct rte_flow_action_rss *rss,
|
const struct rte_flow_action_rss *rss,
|
||||||
const struct rte_flow_action_rss **sample_rss,
|
const struct rte_flow_action_rss **sample_rss,
|
||||||
const struct rte_flow_action_count **count,
|
const struct rte_flow_action_count **count,
|
||||||
|
int *fdb_mirror_limit,
|
||||||
struct rte_flow_error *error)
|
struct rte_flow_error *error)
|
||||||
{
|
{
|
||||||
struct mlx5_priv *priv = dev->data->dev_private;
|
struct mlx5_priv *priv = dev->data->dev_private;
|
||||||
@ -5279,6 +5282,9 @@ flow_dv_validate_action_sample(uint64_t *action_flags,
|
|||||||
NULL,
|
NULL,
|
||||||
"E-Switch must has a dest "
|
"E-Switch must has a dest "
|
||||||
"port for mirroring");
|
"port for mirroring");
|
||||||
|
if (!priv->config.hca_attr.reg_c_preserve &&
|
||||||
|
priv->representor_id != -1)
|
||||||
|
*fdb_mirror_limit = 1;
|
||||||
}
|
}
|
||||||
/* Continue validation for Xcap actions.*/
|
/* Continue validation for Xcap actions.*/
|
||||||
if ((sub_action_flags & MLX5_FLOW_XCAP_ACTIONS) &&
|
if ((sub_action_flags & MLX5_FLOW_XCAP_ACTIONS) &&
|
||||||
@ -6020,6 +6026,8 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr,
|
|||||||
uint16_t ether_type = 0;
|
uint16_t ether_type = 0;
|
||||||
int actions_n = 0;
|
int actions_n = 0;
|
||||||
uint8_t item_ipv6_proto = 0;
|
uint8_t item_ipv6_proto = 0;
|
||||||
|
int fdb_mirror_limit = 0;
|
||||||
|
int modify_after_mirror = 0;
|
||||||
const struct rte_flow_item *geneve_item = NULL;
|
const struct rte_flow_item *geneve_item = NULL;
|
||||||
const struct rte_flow_item *gre_item = NULL;
|
const struct rte_flow_item *gre_item = NULL;
|
||||||
const struct rte_flow_item *gtp_item = NULL;
|
const struct rte_flow_item *gtp_item = NULL;
|
||||||
@ -6441,6 +6449,9 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr,
|
|||||||
++actions_n;
|
++actions_n;
|
||||||
action_flags |= MLX5_FLOW_ACTION_FLAG |
|
action_flags |= MLX5_FLOW_ACTION_FLAG |
|
||||||
MLX5_FLOW_ACTION_MARK_EXT;
|
MLX5_FLOW_ACTION_MARK_EXT;
|
||||||
|
if (action_flags & MLX5_FLOW_ACTION_SAMPLE)
|
||||||
|
modify_after_mirror = 1;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
action_flags |= MLX5_FLOW_ACTION_FLAG;
|
action_flags |= MLX5_FLOW_ACTION_FLAG;
|
||||||
++actions_n;
|
++actions_n;
|
||||||
@ -6460,6 +6471,8 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr,
|
|||||||
++actions_n;
|
++actions_n;
|
||||||
action_flags |= MLX5_FLOW_ACTION_MARK |
|
action_flags |= MLX5_FLOW_ACTION_MARK |
|
||||||
MLX5_FLOW_ACTION_MARK_EXT;
|
MLX5_FLOW_ACTION_MARK_EXT;
|
||||||
|
if (action_flags & MLX5_FLOW_ACTION_SAMPLE)
|
||||||
|
modify_after_mirror = 1;
|
||||||
} else {
|
} else {
|
||||||
action_flags |= MLX5_FLOW_ACTION_MARK;
|
action_flags |= MLX5_FLOW_ACTION_MARK;
|
||||||
++actions_n;
|
++actions_n;
|
||||||
@ -6475,6 +6488,8 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr,
|
|||||||
/* Count all modify-header actions as one action. */
|
/* Count all modify-header actions as one action. */
|
||||||
if (!(action_flags & MLX5_FLOW_MODIFY_HDR_ACTIONS))
|
if (!(action_flags & MLX5_FLOW_MODIFY_HDR_ACTIONS))
|
||||||
++actions_n;
|
++actions_n;
|
||||||
|
if (action_flags & MLX5_FLOW_ACTION_SAMPLE)
|
||||||
|
modify_after_mirror = 1;
|
||||||
action_flags |= MLX5_FLOW_ACTION_SET_META;
|
action_flags |= MLX5_FLOW_ACTION_SET_META;
|
||||||
rw_act_num += MLX5_ACT_NUM_SET_META;
|
rw_act_num += MLX5_ACT_NUM_SET_META;
|
||||||
break;
|
break;
|
||||||
@ -6487,6 +6502,8 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr,
|
|||||||
/* Count all modify-header actions as one action. */
|
/* Count all modify-header actions as one action. */
|
||||||
if (!(action_flags & MLX5_FLOW_MODIFY_HDR_ACTIONS))
|
if (!(action_flags & MLX5_FLOW_MODIFY_HDR_ACTIONS))
|
||||||
++actions_n;
|
++actions_n;
|
||||||
|
if (action_flags & MLX5_FLOW_ACTION_SAMPLE)
|
||||||
|
modify_after_mirror = 1;
|
||||||
action_flags |= MLX5_FLOW_ACTION_SET_TAG;
|
action_flags |= MLX5_FLOW_ACTION_SET_TAG;
|
||||||
rw_act_num += MLX5_ACT_NUM_SET_TAG;
|
rw_act_num += MLX5_ACT_NUM_SET_TAG;
|
||||||
break;
|
break;
|
||||||
@ -6649,6 +6666,8 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr,
|
|||||||
RTE_FLOW_ACTION_TYPE_SET_MAC_SRC ?
|
RTE_FLOW_ACTION_TYPE_SET_MAC_SRC ?
|
||||||
MLX5_FLOW_ACTION_SET_MAC_SRC :
|
MLX5_FLOW_ACTION_SET_MAC_SRC :
|
||||||
MLX5_FLOW_ACTION_SET_MAC_DST;
|
MLX5_FLOW_ACTION_SET_MAC_DST;
|
||||||
|
if (action_flags & MLX5_FLOW_ACTION_SAMPLE)
|
||||||
|
modify_after_mirror = 1;
|
||||||
/*
|
/*
|
||||||
* Even if the source and destination MAC addresses have
|
* Even if the source and destination MAC addresses have
|
||||||
* overlap in the header with 4B alignment, the convert
|
* overlap in the header with 4B alignment, the convert
|
||||||
@ -6669,6 +6688,8 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr,
|
|||||||
/* Count all modify-header actions as one action. */
|
/* Count all modify-header actions as one action. */
|
||||||
if (!(action_flags & MLX5_FLOW_MODIFY_HDR_ACTIONS))
|
if (!(action_flags & MLX5_FLOW_MODIFY_HDR_ACTIONS))
|
||||||
++actions_n;
|
++actions_n;
|
||||||
|
if (action_flags & MLX5_FLOW_ACTION_SAMPLE)
|
||||||
|
modify_after_mirror = 1;
|
||||||
action_flags |= actions->type ==
|
action_flags |= actions->type ==
|
||||||
RTE_FLOW_ACTION_TYPE_SET_IPV4_SRC ?
|
RTE_FLOW_ACTION_TYPE_SET_IPV4_SRC ?
|
||||||
MLX5_FLOW_ACTION_SET_IPV4_SRC :
|
MLX5_FLOW_ACTION_SET_IPV4_SRC :
|
||||||
@ -6692,6 +6713,8 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr,
|
|||||||
/* Count all modify-header actions as one action. */
|
/* Count all modify-header actions as one action. */
|
||||||
if (!(action_flags & MLX5_FLOW_MODIFY_HDR_ACTIONS))
|
if (!(action_flags & MLX5_FLOW_MODIFY_HDR_ACTIONS))
|
||||||
++actions_n;
|
++actions_n;
|
||||||
|
if (action_flags & MLX5_FLOW_ACTION_SAMPLE)
|
||||||
|
modify_after_mirror = 1;
|
||||||
action_flags |= actions->type ==
|
action_flags |= actions->type ==
|
||||||
RTE_FLOW_ACTION_TYPE_SET_IPV6_SRC ?
|
RTE_FLOW_ACTION_TYPE_SET_IPV6_SRC ?
|
||||||
MLX5_FLOW_ACTION_SET_IPV6_SRC :
|
MLX5_FLOW_ACTION_SET_IPV6_SRC :
|
||||||
@ -6709,6 +6732,8 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr,
|
|||||||
/* Count all modify-header actions as one action. */
|
/* Count all modify-header actions as one action. */
|
||||||
if (!(action_flags & MLX5_FLOW_MODIFY_HDR_ACTIONS))
|
if (!(action_flags & MLX5_FLOW_MODIFY_HDR_ACTIONS))
|
||||||
++actions_n;
|
++actions_n;
|
||||||
|
if (action_flags & MLX5_FLOW_ACTION_SAMPLE)
|
||||||
|
modify_after_mirror = 1;
|
||||||
action_flags |= actions->type ==
|
action_flags |= actions->type ==
|
||||||
RTE_FLOW_ACTION_TYPE_SET_TP_SRC ?
|
RTE_FLOW_ACTION_TYPE_SET_TP_SRC ?
|
||||||
MLX5_FLOW_ACTION_SET_TP_SRC :
|
MLX5_FLOW_ACTION_SET_TP_SRC :
|
||||||
@ -6726,6 +6751,8 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr,
|
|||||||
/* Count all modify-header actions as one action. */
|
/* Count all modify-header actions as one action. */
|
||||||
if (!(action_flags & MLX5_FLOW_MODIFY_HDR_ACTIONS))
|
if (!(action_flags & MLX5_FLOW_MODIFY_HDR_ACTIONS))
|
||||||
++actions_n;
|
++actions_n;
|
||||||
|
if (action_flags & MLX5_FLOW_ACTION_SAMPLE)
|
||||||
|
modify_after_mirror = 1;
|
||||||
action_flags |= actions->type ==
|
action_flags |= actions->type ==
|
||||||
RTE_FLOW_ACTION_TYPE_SET_TTL ?
|
RTE_FLOW_ACTION_TYPE_SET_TTL ?
|
||||||
MLX5_FLOW_ACTION_SET_TTL :
|
MLX5_FLOW_ACTION_SET_TTL :
|
||||||
@ -6739,6 +6766,12 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr,
|
|||||||
error);
|
error);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
if ((action_flags & MLX5_FLOW_ACTION_SAMPLE) &&
|
||||||
|
fdb_mirror_limit)
|
||||||
|
return rte_flow_error_set(error, EINVAL,
|
||||||
|
RTE_FLOW_ERROR_TYPE_ACTION,
|
||||||
|
NULL,
|
||||||
|
"sample and jump action combination is not supported");
|
||||||
++actions_n;
|
++actions_n;
|
||||||
action_flags |= MLX5_FLOW_ACTION_JUMP;
|
action_flags |= MLX5_FLOW_ACTION_JUMP;
|
||||||
break;
|
break;
|
||||||
@ -6754,6 +6787,8 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr,
|
|||||||
/* Count all modify-header actions as one action. */
|
/* Count all modify-header actions as one action. */
|
||||||
if (!(action_flags & MLX5_FLOW_MODIFY_HDR_ACTIONS))
|
if (!(action_flags & MLX5_FLOW_MODIFY_HDR_ACTIONS))
|
||||||
++actions_n;
|
++actions_n;
|
||||||
|
if (action_flags & MLX5_FLOW_ACTION_SAMPLE)
|
||||||
|
modify_after_mirror = 1;
|
||||||
action_flags |= actions->type ==
|
action_flags |= actions->type ==
|
||||||
RTE_FLOW_ACTION_TYPE_INC_TCP_SEQ ?
|
RTE_FLOW_ACTION_TYPE_INC_TCP_SEQ ?
|
||||||
MLX5_FLOW_ACTION_INC_TCP_SEQ :
|
MLX5_FLOW_ACTION_INC_TCP_SEQ :
|
||||||
@ -6772,6 +6807,8 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr,
|
|||||||
/* Count all modify-header actions as one action. */
|
/* Count all modify-header actions as one action. */
|
||||||
if (!(action_flags & MLX5_FLOW_MODIFY_HDR_ACTIONS))
|
if (!(action_flags & MLX5_FLOW_MODIFY_HDR_ACTIONS))
|
||||||
++actions_n;
|
++actions_n;
|
||||||
|
if (action_flags & MLX5_FLOW_ACTION_SAMPLE)
|
||||||
|
modify_after_mirror = 1;
|
||||||
action_flags |= actions->type ==
|
action_flags |= actions->type ==
|
||||||
RTE_FLOW_ACTION_TYPE_INC_TCP_ACK ?
|
RTE_FLOW_ACTION_TYPE_INC_TCP_ACK ?
|
||||||
MLX5_FLOW_ACTION_INC_TCP_ACK :
|
MLX5_FLOW_ACTION_INC_TCP_ACK :
|
||||||
@ -6843,6 +6880,8 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr,
|
|||||||
/* Count all modify-header actions as one action. */
|
/* Count all modify-header actions as one action. */
|
||||||
if (!(action_flags & MLX5_FLOW_MODIFY_HDR_ACTIONS))
|
if (!(action_flags & MLX5_FLOW_MODIFY_HDR_ACTIONS))
|
||||||
++actions_n;
|
++actions_n;
|
||||||
|
if (action_flags & MLX5_FLOW_ACTION_SAMPLE)
|
||||||
|
modify_after_mirror = 1;
|
||||||
action_flags |= MLX5_FLOW_ACTION_SET_IPV4_DSCP;
|
action_flags |= MLX5_FLOW_ACTION_SET_IPV4_DSCP;
|
||||||
rw_act_num += MLX5_ACT_NUM_SET_DSCP;
|
rw_act_num += MLX5_ACT_NUM_SET_DSCP;
|
||||||
break;
|
break;
|
||||||
@ -6857,6 +6896,8 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr,
|
|||||||
/* Count all modify-header actions as one action. */
|
/* Count all modify-header actions as one action. */
|
||||||
if (!(action_flags & MLX5_FLOW_MODIFY_HDR_ACTIONS))
|
if (!(action_flags & MLX5_FLOW_MODIFY_HDR_ACTIONS))
|
||||||
++actions_n;
|
++actions_n;
|
||||||
|
if (action_flags & MLX5_FLOW_ACTION_SAMPLE)
|
||||||
|
modify_after_mirror = 1;
|
||||||
action_flags |= MLX5_FLOW_ACTION_SET_IPV6_DSCP;
|
action_flags |= MLX5_FLOW_ACTION_SET_IPV6_DSCP;
|
||||||
rw_act_num += MLX5_ACT_NUM_SET_DSCP;
|
rw_act_num += MLX5_ACT_NUM_SET_DSCP;
|
||||||
break;
|
break;
|
||||||
@ -6866,6 +6907,7 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr,
|
|||||||
attr, item_flags,
|
attr, item_flags,
|
||||||
rss, &sample_rss,
|
rss, &sample_rss,
|
||||||
&sample_count,
|
&sample_count,
|
||||||
|
&fdb_mirror_limit,
|
||||||
error);
|
error);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
@ -7064,6 +7106,11 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr,
|
|||||||
NULL, "too many header modify"
|
NULL, "too many header modify"
|
||||||
" actions to support");
|
" actions to support");
|
||||||
}
|
}
|
||||||
|
/* Eswitch egress mirror and modify flow has limitation on CX5 */
|
||||||
|
if (fdb_mirror_limit && modify_after_mirror)
|
||||||
|
return rte_flow_error_set(error, EINVAL,
|
||||||
|
RTE_FLOW_ERROR_TYPE_ACTION, NULL,
|
||||||
|
"sample before modify action is not supported");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user