Duplicated matching tag index is not allowed in sws
because they are using the same matching field in the
underlayer layout.
For example: "tag index is 0 data spec 0x12 mask 0xff /
tag index is 0 data spec 0x1234 mask 0xffff" is paradoxical
matching condition and "tag index is 0 data spec 0x12 mask 0xff /
tag index is 0 data spec 0x3400 mask 0xff00" should be "tag index
is 0 data spec 0x3412 mask 0xffff"
Add checking logic against it.
Fixes: e554b672aa05 ("net/mlx5: support flow tag")
Cc: viacheslavo@nvidia.com
Cc: stable@dpdk.org
Signed-off-by: Rongwei Liu <rongweil@nvidia.com>
Acked-by: Viacheslav Ovsiienko <viacheslavo@nvidia.com>
---
drivers/net/mlx5/mlx5_flow_dv.c | 21 +++++++++++++++++++--
1 file changed, 19 insertions(+), 2 deletions(-)
@@ -2294,6 +2294,8 @@ flow_dv_validate_item_meta(struct rte_eth_dev *dev __rte_unused,
* Pointer to the rte_eth_dev structure.
* @param[in] item
* Item specification.
+ * @param[in] tag_bitmap
+ * Tag index bitmap.
* @param[in] attr
* Attributes of flow that includes this item.
* @param[out] error
@@ -2305,6 +2307,7 @@ flow_dv_validate_item_meta(struct rte_eth_dev *dev __rte_unused,
static int
flow_dv_validate_item_tag(struct rte_eth_dev *dev,
const struct rte_flow_item *item,
+ uint32_t *tag_bitmap,
const struct rte_flow_attr *attr __rte_unused,
struct rte_flow_error *error)
{
@@ -2348,6 +2351,12 @@ flow_dv_validate_item_tag(struct rte_eth_dev *dev,
if (ret < 0)
return ret;
MLX5_ASSERT(ret != REG_NON);
+ if (*tag_bitmap & (1 << ret))
+ return rte_flow_error_set(error, EINVAL,
+ RTE_FLOW_ERROR_TYPE_ITEM_SPEC,
+ item->spec,
+ "Duplicated tag index");
+ *tag_bitmap |= 1 << ret;
return 0;
}
@@ -7290,9 +7299,10 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr,
bool def_policy = false;
bool shared_count = false;
uint16_t udp_dport = 0;
- uint32_t tag_id = 0;
+ uint32_t tag_id = 0, tag_bitmap = 0;
const struct rte_flow_action_age *non_shared_age = NULL;
const struct rte_flow_action_count *count = NULL;
+ const struct mlx5_rte_flow_item_tag *mlx5_tag;
struct mlx5_priv *act_priv = NULL;
int aso_after_sample = 0;
@@ -7621,7 +7631,7 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr,
last_item = MLX5_FLOW_LAYER_ICMP6;
break;
case RTE_FLOW_ITEM_TYPE_TAG:
- ret = flow_dv_validate_item_tag(dev, items,
+ ret = flow_dv_validate_item_tag(dev, items, &tag_bitmap,
attr, error);
if (ret < 0)
return ret;
@@ -7631,6 +7641,13 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr,
last_item = MLX5_FLOW_ITEM_SQ;
break;
case MLX5_RTE_FLOW_ITEM_TYPE_TAG:
+ mlx5_tag = (const struct mlx5_rte_flow_item_tag *)items->spec;
+ if (tag_bitmap & (1 << mlx5_tag->id))
+ return rte_flow_error_set(error, EINVAL,
+ RTE_FLOW_ERROR_TYPE_ITEM_SPEC,
+ items->spec,
+ "Duplicated tag index");
+ tag_bitmap |= 1 << mlx5_tag->id;
break;
case RTE_FLOW_ITEM_TYPE_GTP:
ret = flow_dv_validate_item_gtp(dev, items, item_flags,