From 9da1db6bbf7bfc6b8d62444920ff04991ac88917 Mon Sep 17 00:00:00 2001 From: Shahaf Shuler Date: Tue, 31 Jul 2018 10:57:20 +0300 Subject: [PATCH] net/mlx5: fix VLAN filtering The below commit has added a graph based expansion logic for RSS rule to satisfy Verbs requirements. With this logic, for example, the rule: flow create 0 ingress pattern eth / end actions rss queues 0 1 end types ipv4-tcp ipv6-tcp end / end will be expanded into the rules: flow create 0 ingress pattern eth / ipv4 / tcp / end actions rss queues 0 1 end types ipv4-tcp ipv6-tcp end / end flow create 0 ingress pattern eth / ipv6 / tcp / end actions rss queues 0 1 end types ipv4-tcp ipv6-tcp end / end flow create 0 ingress pattern eth / end actions queue index 0 / end The below commit defined two graphs: 1. graph for the tunnel case which starts from the ETH item 2. graph for the non-tunnel case which starts from the ETH item The graphs are ignoring the VLAN case. Hence rules with VLAN item will fail to traverse the graph and it will result in flow rule creation error. Adding the VLAN item to the existing graphs will not work as the flow engine will reject any VLAN item without a specific vid. To solve this case two new graphs were added (for the tunnel and non-tunnel case) which contain the VLAN item and are being used only when the VLAN item exists in the flow pattern. Two cases left un-covered for the inner RSS: 1. The case were VLAN exists in the pattern as part of the inner headers 2. The case were VLAN exists in the pattern both in the outer and the inner headers Solving those cases will require to add two more graphs. Holding a VLAN for the overlay network is not common, the subnets are usually defined by the tunnel protocol, for example the VXLAN vni. Hence adding those two graphs seems like an overkill at this point. Based on needs one can add those to provide the full support. Fixes: 592f05b29a25 ("net/mlx5: add RSS flow action") Signed-off-by: Shahaf Shuler --- drivers/net/mlx5/mlx5_flow.c | 60 ++++++++++++++++++++++++++++++++++-- 1 file changed, 57 insertions(+), 3 deletions(-) diff --git a/drivers/net/mlx5/mlx5_flow.c b/drivers/net/mlx5/mlx5_flow.c index 923fc28589..6c3021abac 100644 --- a/drivers/net/mlx5/mlx5_flow.c +++ b/drivers/net/mlx5/mlx5_flow.c @@ -103,7 +103,11 @@ extern const struct eth_dev_ops mlx5_dev_ops_isolate; enum mlx5_expansion { MLX5_EXPANSION_ROOT, MLX5_EXPANSION_ROOT_OUTER, + MLX5_EXPANSION_ROOT_ETH_VLAN, + MLX5_EXPANSION_ROOT_OUTER_ETH_VLAN, MLX5_EXPANSION_OUTER_ETH, + MLX5_EXPANSION_OUTER_ETH_VLAN, + MLX5_EXPANSION_OUTER_VLAN, MLX5_EXPANSION_OUTER_IPV4, MLX5_EXPANSION_OUTER_IPV4_UDP, MLX5_EXPANSION_OUTER_IPV4_TCP, @@ -115,6 +119,8 @@ enum mlx5_expansion { MLX5_EXPANSION_GRE, MLX5_EXPANSION_MPLS, MLX5_EXPANSION_ETH, + MLX5_EXPANSION_ETH_VLAN, + MLX5_EXPANSION_VLAN, MLX5_EXPANSION_IPV4, MLX5_EXPANSION_IPV4_UDP, MLX5_EXPANSION_IPV4_TCP, @@ -137,6 +143,14 @@ static const struct rte_flow_expand_node mlx5_support_expansion[] = { MLX5_EXPANSION_OUTER_IPV6), .type = RTE_FLOW_ITEM_TYPE_END, }, + [MLX5_EXPANSION_ROOT_ETH_VLAN] = { + .next = RTE_FLOW_EXPAND_RSS_NEXT(MLX5_EXPANSION_ETH_VLAN), + .type = RTE_FLOW_ITEM_TYPE_END, + }, + [MLX5_EXPANSION_ROOT_OUTER_ETH_VLAN] = { + .next = RTE_FLOW_EXPAND_RSS_NEXT(MLX5_EXPANSION_OUTER_ETH_VLAN), + .type = RTE_FLOW_ITEM_TYPE_END, + }, [MLX5_EXPANSION_OUTER_ETH] = { .next = RTE_FLOW_EXPAND_RSS_NEXT(MLX5_EXPANSION_OUTER_IPV4, MLX5_EXPANSION_OUTER_IPV6, @@ -144,6 +158,16 @@ static const struct rte_flow_expand_node mlx5_support_expansion[] = { .type = RTE_FLOW_ITEM_TYPE_ETH, .rss_types = 0, }, + [MLX5_EXPANSION_OUTER_ETH_VLAN] = { + .next = RTE_FLOW_EXPAND_RSS_NEXT(MLX5_EXPANSION_OUTER_VLAN), + .type = RTE_FLOW_ITEM_TYPE_ETH, + .rss_types = 0, + }, + [MLX5_EXPANSION_OUTER_VLAN] = { + .next = RTE_FLOW_EXPAND_RSS_NEXT(MLX5_EXPANSION_OUTER_IPV4, + MLX5_EXPANSION_OUTER_IPV6), + .type = RTE_FLOW_ITEM_TYPE_VLAN, + }, [MLX5_EXPANSION_OUTER_IPV4] = { .next = RTE_FLOW_EXPAND_RSS_NEXT (MLX5_EXPANSION_OUTER_IPV4_UDP, @@ -205,6 +229,15 @@ static const struct rte_flow_expand_node mlx5_support_expansion[] = { MLX5_EXPANSION_IPV6), .type = RTE_FLOW_ITEM_TYPE_ETH, }, + [MLX5_EXPANSION_ETH_VLAN] = { + .next = RTE_FLOW_EXPAND_RSS_NEXT(MLX5_EXPANSION_VLAN), + .type = RTE_FLOW_ITEM_TYPE_ETH, + }, + [MLX5_EXPANSION_VLAN] = { + .next = RTE_FLOW_EXPAND_RSS_NEXT(MLX5_EXPANSION_IPV4, + MLX5_EXPANSION_IPV6), + .type = RTE_FLOW_ITEM_TYPE_VLAN, + }, [MLX5_EXPANSION_IPV4] = { .next = RTE_FLOW_EXPAND_RSS_NEXT(MLX5_EXPANSION_IPV4_UDP, MLX5_EXPANSION_IPV4_TCP), @@ -2464,6 +2497,25 @@ mlx5_flow_merge_switch(struct rte_eth_dev *dev, return off + ret; } +static unsigned int +mlx5_find_graph_root(const struct rte_flow_item pattern[], uint32_t rss_level) +{ + const struct rte_flow_item *item; + unsigned int has_vlan = 0; + + for (item = pattern; item->type != RTE_FLOW_ITEM_TYPE_END; item++) { + if (item->type == RTE_FLOW_ITEM_TYPE_VLAN) { + has_vlan = 1; + break; + } + } + if (has_vlan) + return rss_level < 2 ? MLX5_EXPANSION_ROOT_ETH_VLAN : + MLX5_EXPANSION_ROOT_OUTER_ETH_VLAN; + return rss_level < 2 ? MLX5_EXPANSION_ROOT : + MLX5_EXPANSION_ROOT_OUTER; +} + /** * Convert the @p attributes, @p pattern, @p action, into an flow for the NIC * after ensuring the NIC will understand and process it correctly. @@ -2531,12 +2583,14 @@ mlx5_flow_merge(struct rte_eth_dev *dev, struct rte_flow *flow, if (ret < 0) return ret; if (local_flow.rss.types) { + unsigned int graph_root; + + graph_root = mlx5_find_graph_root(pattern, + local_flow.rss.level); ret = rte_flow_expand_rss(buf, sizeof(expand_buffer.buffer), pattern, local_flow.rss.types, mlx5_support_expansion, - local_flow.rss.level < 2 ? - MLX5_EXPANSION_ROOT : - MLX5_EXPANSION_ROOT_OUTER); + graph_root); assert(ret > 0 && (unsigned int)ret < sizeof(expand_buffer.buffer)); } else { -- 2.20.1