[PATCH v1 5/9] net/i40e: validate IPv4 fragment offset without range

Anatoly Burakov anatoly.burakov at intel.com
Fri Oct 30 10:40:18 CET 2026


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 <anatoly.burakov at intel.com>
---
 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



More information about the dev mailing list