Skip to content

Commit

Permalink
ethdev: fix RSS flow expansion in case of mismatch
Browse files Browse the repository at this point in the history
Function rte_flow_expand_rss() is used to expand a flow rule with
partial pattern into several rules, to ensure all relevant packets
are matched.
It uses utility function rte_flow_expand_rss_item_complete(), to check
if the last valid item in the flow rule pattern needs to be completed.
For example the pattern "eth / ipv4 proto is 17 / end" will be completed
with a "udp" item.
This function returns "void" item in two cases:
1) The last item has empty spec, for example "eth / ipv4 / end".
2) The last itme has spec that can't be expanded for RSS.
   For example the pattern "eth / ipv4 proto is 47 / end" ends with IPv4
   item that has next protocol GRE.

In both cases the flow rule may be expanded, but in the second case such
expansion may create rules with invalid pattern.
For example "eth / ipv4 proto is 47 / udp / end".
In such a case the flow rule should not be expanded.

This patch updates function rte_flow_expand_rss_item_complete().
Return value RTE_FLOW_ITEM_TYPE_END is used to indicate the flow rule
should not be expanded.
In such a case, rte_flow_expand_rss() will return with the original flow
rule only, without any expansion.

Fixes: fc2dd8d ("ethdev: fix expand RSS flows")
Cc: stable@dpdk.org

Signed-off-by: Dekel Peled <dekelp@nvidia.com>
Acked-by: Xiaoyu Min <jackmin@nvidia.com>
Acked-by: Viacheslav Ovsiienko <viacheslavo@nvidia.com>
Acked-by: Ori Kam <orika@nvidia.com>
  • Loading branch information
Dekel Peled authored and Ferruh Yigit committed Oct 8, 2020
1 parent 7ae5c75 commit 7f6a316
Showing 1 changed file with 14 additions and 2 deletions.
16 changes: 14 additions & 2 deletions lib/librte_ethdev/rte_flow.c
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,8 @@ rte_flow_expand_rss_item_complete(const struct rte_flow_item *item)
ret = RTE_FLOW_ITEM_TYPE_IPV6;
else if (rte_be_to_cpu_16(ether_type) == RTE_ETHER_TYPE_VLAN)
ret = RTE_FLOW_ITEM_TYPE_VLAN;
else
ret = RTE_FLOW_ITEM_TYPE_END;
break;
case RTE_FLOW_ITEM_TYPE_VLAN:
if (item->mask)
Expand All @@ -264,6 +266,8 @@ rte_flow_expand_rss_item_complete(const struct rte_flow_item *item)
ret = RTE_FLOW_ITEM_TYPE_IPV6;
else if (rte_be_to_cpu_16(ether_type) == RTE_ETHER_TYPE_VLAN)
ret = RTE_FLOW_ITEM_TYPE_VLAN;
else
ret = RTE_FLOW_ITEM_TYPE_END;
break;
case RTE_FLOW_ITEM_TYPE_IPV4:
if (item->mask)
Expand All @@ -284,6 +288,8 @@ rte_flow_expand_rss_item_complete(const struct rte_flow_item *item)
ret = RTE_FLOW_ITEM_TYPE_IPV4;
else if (ip_next_proto == IPPROTO_IPV6)
ret = RTE_FLOW_ITEM_TYPE_IPV6;
else
ret = RTE_FLOW_ITEM_TYPE_END;
break;
case RTE_FLOW_ITEM_TYPE_IPV6:
if (item->mask)
Expand All @@ -304,6 +310,8 @@ rte_flow_expand_rss_item_complete(const struct rte_flow_item *item)
ret = RTE_FLOW_ITEM_TYPE_IPV4;
else if (ip_next_proto == IPPROTO_IPV6)
ret = RTE_FLOW_ITEM_TYPE_IPV6;
else
ret = RTE_FLOW_ITEM_TYPE_END;
break;
default:
ret = RTE_FLOW_ITEM_TYPE_VOID;
Expand Down Expand Up @@ -1110,10 +1118,14 @@ rte_flow_expand_rss(struct rte_flow_expand_rss *buf, size_t size,
memset(flow_items, 0, sizeof(flow_items));
user_pattern_size -= sizeof(*item);
/*
* Check if the last valid item has spec set
* and need complete pattern.
* Check if the last valid item has spec set, need complete pattern,
* and the pattern can be used for expansion.
*/
missed_item.type = rte_flow_expand_rss_item_complete(last_item);
if (missed_item.type == RTE_FLOW_ITEM_TYPE_END) {
/* Item type END indicates expansion is not required. */
return lsize;
}
if (missed_item.type != RTE_FLOW_ITEM_TYPE_VOID) {
next = NULL;
missed = 1;
Expand Down

0 comments on commit 7f6a316

Please sign in to comment.