The FDIR IPv4 node only checked fragment_offset when the item had a
range. Without one, any fragment_offset mask and spec were accepted and
then ignored, so the rule was installed as a non-fragmented IPv4 rule.
The old parser rejected these.
Check fragment_offset whether or not a range is given.
Fixes: 05432a6e4676 ("net/i40e: reimplement FDIR parser")
Signed-off-by: Anatoly Burakov <[email protected]>
---
drivers/net/intel/i40e/i40e_flow_fdir.c | 21 ++++++++++++++-------
1 file changed, 14 insertions(+), 7 deletions(-)
diff --git a/drivers/net/intel/i40e/i40e_flow_fdir.c
b/drivers/net/intel/i40e/i40e_flow_fdir.c
index ba8c18250c8..0c9dce6fd9d 100644
--- a/drivers/net/intel/i40e/i40e_flow_fdir.c
+++ b/drivers/net/intel/i40e/i40e_flow_fdir.c
@@ -257,11 +257,9 @@ i40e_fdir_node_ipv4_validate(const void *ctx __rte_unused,
const struct rte_flow
"Invalid IPv4 header mask");
}
- if (ipv4_last == NULL)
- return 0;
-
/* Only fragment_offset supports range */
- if (ipv4_last->hdr.version_ihl ||
+ if (ipv4_last != NULL &&
+ (ipv4_last->hdr.version_ihl ||
ipv4_last->hdr.type_of_service ||
ipv4_last->hdr.total_length ||
ipv4_last->hdr.packet_id ||
@@ -269,16 +267,25 @@ i40e_fdir_node_ipv4_validate(const void *ctx
__rte_unused, const struct rte_flow
ipv4_last->hdr.next_proto_id ||
ipv4_last->hdr.hdr_checksum ||
ipv4_last->hdr.src_addr ||
- ipv4_last->hdr.dst_addr) {
+ ipv4_last->hdr.dst_addr)) {
return rte_flow_error_set(error, EINVAL,
RTE_FLOW_ERROR_TYPE_ITEM, item,
"IPv4 range only supported for
fragment_offset");
}
- /* Validate fragment_offset range values */
+ /* Validate fragment_offset values */
uint16_t frag_mask = rte_be_to_cpu_16(ipv4_mask->hdr.fragment_offset);
uint16_t frag_spec = rte_be_to_cpu_16(ipv4_spec->hdr.fragment_offset);
- uint16_t frag_last = rte_be_to_cpu_16(ipv4_last->hdr.fragment_offset);
+ uint16_t frag_last = ipv4_last != NULL ?
+ rte_be_to_cpu_16(ipv4_last->hdr.fragment_offset) : 0;
+
+ if (frag_mask == 0) {
+ if (ipv4_last == NULL)
+ return 0; /* fragment_offset not matched */
+ return rte_flow_error_set(error, EINVAL,
+ RTE_FLOW_ERROR_TYPE_ITEM, item,
+ "IPv4 fragment_offset range requires a mask");
+ }
/* Mask must be 0x3fff (fragment offset + MF flag) */
if (frag_mask != (RTE_IPV4_HDR_OFFSET_MASK | RTE_IPV4_HDR_MF_FLAG)) {
--
2.52.0