Signed-off-by: Nelio Laranjeiro <nelio.laranje...@6wind.com> --- drivers/net/mlx5/mlx5_flow.c | 59 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 57 insertions(+), 2 deletions(-)
diff --git a/drivers/net/mlx5/mlx5_flow.c b/drivers/net/mlx5/mlx5_flow.c index a33c568..2478fb6 100644 --- a/drivers/net/mlx5/mlx5_flow.c +++ b/drivers/net/mlx5/mlx5_flow.c @@ -184,6 +184,9 @@ priv_flow_validate(struct priv *priv, .dst_port = -1, }, }; + const struct rte_flow_item_vlan vlan_mask = { + .tci = -1, + }; if (attr->group) { rte_flow_error_set(error, ENOTSUP, @@ -228,11 +231,32 @@ priv_flow_validate(struct priv *priv, sizeof(eth_mask)); if (err) goto exit_item_not_supported; - } else if (items->type == RTE_FLOW_ITEM_TYPE_IPV4) { + } else if (items->type == RTE_FLOW_ITEM_TYPE_VLAN) { if (!ilast) goto exit_item_not_supported; else if (ilast->type != RTE_FLOW_ITEM_TYPE_ETH) goto exit_item_not_supported; + if (((const struct rte_flow_item_vlan *)items)->tci > + ETHER_MAX_VLAN_ID) { + rte_flow_error_set(error, ENOTSUP, + RTE_FLOW_ERROR_TYPE_ITEM, + items, + "wrong VLAN tci value"); + goto exit; + } + ilast = items; + err = mlx5_flow_item_validate( + items, + (const uint8_t *)&vlan_mask, + sizeof(vlan_mask)); + if (err) + goto exit_item_not_supported; + } else if (items->type == RTE_FLOW_ITEM_TYPE_IPV4) { + if (!ilast) + goto exit_item_not_supported; + else if (ilast->type != RTE_FLOW_ITEM_TYPE_ETH && + ilast->type != RTE_FLOW_ITEM_TYPE_VLAN) + goto exit_item_not_supported; ilast = items; err = mlx5_flow_item_validate( items, @@ -243,7 +267,8 @@ priv_flow_validate(struct priv *priv, } else if (items->type == RTE_FLOW_ITEM_TYPE_IPV6) { if (!ilast) goto exit_item_not_supported; - else if (ilast->type != RTE_FLOW_ITEM_TYPE_ETH) + else if (ilast->type != RTE_FLOW_ITEM_TYPE_ETH && + ilast->type != RTE_FLOW_ITEM_TYPE_VLAN) goto exit_item_not_supported; ilast = items; err = mlx5_flow_item_validate( @@ -372,6 +397,28 @@ mlx5_flow_create_eth(const struct rte_flow_item *item, } /** + * Convert VLAN item to Verbs specification. + * + * @param item[in] + * Item specification. + * @param eth[in, out] + * Verbs Ethernet specification structure. + */ +static void +mlx5_flow_create_vlan(const struct rte_flow_item *item, + struct ibv_exp_flow_spec_eth *eth) +{ + const struct rte_flow_item_vlan *spec = item->spec; + const struct rte_flow_item_vlan *mask = item->mask; + + if (spec) + eth->val.vlan_tag = spec->tci; + if (mask) + eth->mask.vlan_tag = mask->tci; + eth->val.vlan_tag &= eth->mask.vlan_tag; +} + +/** * Convert IPv4 item to Verbs specification. * * @param item[in] @@ -700,6 +747,14 @@ priv_flow_create(struct priv *priv, flow_size += eth_size; ++ibv_attr->num_of_specs; ibv_attr->priority = 2; + } else if (items->type == RTE_FLOW_ITEM_TYPE_VLAN) { + struct ibv_exp_flow_spec_eth *eth; + unsigned int eth_size = + sizeof(struct ibv_exp_flow_spec_eth); + + eth = (void *)((uintptr_t)ibv_attr + flow_size - + eth_size); + mlx5_flow_create_vlan(items, eth); } else if (items->type == RTE_FLOW_ITEM_TYPE_IPV4) { struct ibv_exp_flow_spec_ipv4 *ipv4; unsigned int ipv4_size = -- 2.1.4