@@ -2379,6 +2379,13 @@ flow_hw_table_create(struct rte_eth_dev *dev,
for (i = 0; i < nb_item_templates; i++) {
uint32_t ret;
+ if ((flow_attr.ingress && !item_templates[i]->attr.ingress) ||
+ (flow_attr.egress && !item_templates[i]->attr.egress) ||
+ (flow_attr.transfer && !item_templates[i]->attr.transfer)) {
+ DRV_LOG(ERR, "pattern template and template table attribute mismatch");
+ rte_errno = EINVAL;
+ goto it_error;
+ }
ret = __atomic_add_fetch(&item_templates[i]->refcnt, 1,
__ATOMIC_RELAXED);
if (ret <= 1) {
@@ -2557,6 +2564,7 @@ flow_hw_template_table_create(struct rte_eth_dev *dev,
uint8_t nb_action_templates,
struct rte_flow_error *error)
{
+ struct mlx5_priv *priv = dev->data->dev_private;
struct mlx5_flow_template_table_cfg cfg = {
.attr = *attr,
.external = true,
@@ -2565,6 +2573,12 @@ flow_hw_template_table_create(struct rte_eth_dev *dev,
if (flow_hw_translate_group(dev, &cfg, group, &cfg.attr.flow_attr.group, error))
return NULL;
+ if (priv->sh->config.dv_esw_en && cfg.attr.flow_attr.egress) {
+ rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ATTR, NULL,
+ "egress flows are not supported with HW Steering"
+ " when E-Switch is enabled");
+ return NULL;
+ }
return flow_hw_table_create(dev, &cfg, item_templates, nb_item_templates,
action_templates, nb_action_templates, error);
}
@@ -3254,11 +3268,48 @@ flow_hw_pattern_validate(struct rte_eth_dev *dev,
const struct rte_flow_item items[],
struct rte_flow_error *error)
{
+ struct mlx5_priv *priv = dev->data->dev_private;
int i;
bool items_end = false;
- RTE_SET_USED(dev);
- RTE_SET_USED(attr);
+ if (!attr->ingress && !attr->egress && !attr->transfer)
+ return rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ATTR, NULL,
+ "at least one of the direction attributes"
+ " must be specified");
+ if (priv->sh->config.dv_esw_en) {
+ MLX5_ASSERT(priv->master || priv->representor);
+ if (priv->master) {
+ /*
+ * It is allowed to specify ingress, egress and transfer attributes
+ * at the same time, in order to construct flows catching all missed
+ * FDB traffic and forwarding it to the master port.
+ */
+ if (!(attr->ingress ^ attr->egress ^ attr->transfer))
+ return rte_flow_error_set(error, EINVAL,
+ RTE_FLOW_ERROR_TYPE_ATTR, NULL,
+ "only one or all direction attributes"
+ " at once can be used on transfer proxy"
+ " port");
+ } else {
+ if (attr->transfer)
+ return rte_flow_error_set(error, EINVAL,
+ RTE_FLOW_ERROR_TYPE_ATTR_TRANSFER, NULL,
+ "transfer attribute cannot be used with"
+ " port representors");
+ if (attr->ingress && attr->egress)
+ return rte_flow_error_set(error, EINVAL,
+ RTE_FLOW_ERROR_TYPE_ATTR, NULL,
+ "ingress and egress direction attributes"
+ " cannot be used at the same time on"
+ " port representors");
+ }
+ } else {
+ if (attr->transfer)
+ return rte_flow_error_set(error, EINVAL,
+ RTE_FLOW_ERROR_TYPE_ATTR_TRANSFER, NULL,
+ "transfer attribute cannot be used when"
+ " E-Switch is disabled");
+ }
for (i = 0; !items_end; i++) {
int type = items[i].type;
@@ -3289,7 +3340,15 @@ flow_hw_pattern_validate(struct rte_eth_dev *dev,
RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
NULL,
"Unsupported internal tag index");
+ break;
}
+ case RTE_FLOW_ITEM_TYPE_REPRESENTED_PORT:
+ if (attr->ingress || attr->egress)
+ return rte_flow_error_set(error, EINVAL,
+ RTE_FLOW_ERROR_TYPE_ITEM, NULL,
+ "represented port item cannot be used"
+ " when transfer attribute is set");
+ break;
case RTE_FLOW_ITEM_TYPE_VOID:
case RTE_FLOW_ITEM_TYPE_ETH:
case RTE_FLOW_ITEM_TYPE_VLAN:
@@ -3299,7 +3358,6 @@ flow_hw_pattern_validate(struct rte_eth_dev *dev,
case RTE_FLOW_ITEM_TYPE_TCP:
case RTE_FLOW_ITEM_TYPE_GTP:
case RTE_FLOW_ITEM_TYPE_GTP_PSC:
- case RTE_FLOW_ITEM_TYPE_REPRESENTED_PORT:
case RTE_FLOW_ITEM_TYPE_VXLAN:
case MLX5_RTE_FLOW_ITEM_TYPE_TX_QUEUE:
case RTE_FLOW_ITEM_TYPE_META:
@@ -3350,21 +3408,7 @@ flow_hw_pattern_template_create(struct rte_eth_dev *dev,
if (flow_hw_pattern_validate(dev, attr, items, error))
return NULL;
- if (priv->sh->config.dv_esw_en && attr->ingress) {
- /*
- * Disallow pattern template with ingress and egress/transfer
- * attributes in order to forbid implicit port matching
- * on egress and transfer traffic.
- */
- if (attr->egress || attr->transfer) {
- rte_flow_error_set(error, EINVAL,
- RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
- NULL,
- "item template for ingress traffic"
- " cannot be used for egress/transfer"
- " traffic when E-Switch is enabled");
- return NULL;
- }
+ if (priv->sh->config.dv_esw_en && attr->ingress && !attr->egress && !attr->transfer) {
copied_items = flow_hw_copy_prepend_port_item(items, error);
if (!copied_items)
return NULL;