[PATCH v8] ethdev: support inline calculating masked item value

Stephen Hemminger stephen at networkplumber.org
Fri Oct 16 18:03:20 CEST 2026


On Fri, 16 Oct 2026 08:26:45 +0300
Bing Zhao <bingz at nvidia.com> wrote:

> Drivers implementing synchronous flow rules through the asynchronous
> template API need to apply item masks before creating a rule. The spec
> and last pointers are const, so this requires writable copies and
> per-item knowledge of their sizes.
> 
> Add RTE_FLOW_CONV_OP_PATTERN_MASKED to rte_flow_conv(). It copies the
> pattern like RTE_FLOW_CONV_OP_PATTERN and ANDs the inline fields of each
> copied spec and last with an explicit item mask. A NULL mask leaves the
> values unchanged; default masks are not substituted.
> 
> Preserve GENEVE_OPT.option_len and TAG.index because they describe the
> pointed-to data length and select the tag register, respectively.
> RAW pattern and GENEVE_OPT data are copied without applying their
> payload masks. Limit this operation to inline fields, leaving
> variable-length payload masking to the caller. FLEX, COMPARE and PMD
> private items are not masked.
> 
> Signed-off-by: Bing Zhao <bingz at nvidia.com>
> Reviewed-by: Dariusz Sosnowski <dsosnowski at nvidia.com>
> ---

Before merging:
  1. Need this warning fixed.
  2. Need a driver to support.
     It doesn't make sense to have things in ethdev until a driver uses it. (YAGNI)

Make a patch series for mlx5 with this as the first patch.


[PATCH v8] ethdev: support inline calculating masked item value

v7 comments on GENEVE_OPT option_len, TAG index and the commit
message are addressed. Applies to main (26.11-rc1), builds with
-Dwerror=true.

Warning

1. INTEGRITY level is a selector and is still masked.

rte_flow_item_integrity.level picks the encapsulation level, same
class as TAG index. rte_flow_item_integrity_mask has level = 0, so a
rule passing the default mask explicitly gets level zeroed, turning
an inner integrity match into an outer one. mlx5 SWS reads the
unmasked spec->level (flow_dv_translate_item_integrity(),
"if (spec->level > 1)").

level is the first member, so an offsetof() end limit does not work.
Return a range instead:

	static inline size_t
	rte_flow_conv_item_mask_range(const struct rte_flow_item *item,
				      size_t *start)
	{
		*start = 0;
		...
		case RTE_FLOW_ITEM_TYPE_INTEGRITY:
			*start = offsetof(struct rte_flow_item_integrity,
					  value);
			return sizeof(struct rte_flow_item_integrity);
		...
	}

and in rte_flow_conv_pattern():

	end = RTE_MIN(ret, item_mask_end);
	if (c_spec && mask && end > start)
		rte_flow_conv_apply_mask(c_spec + start, mask + start,
					 end - start);

Add INTEGRITY to the exception lists (rte_flow.h, helper comment,
release notes) and a test case.

2. Still no user of the new op.

Nothing in tree calls RTE_FLOW_CONV_OP_PATTERN_MASKED. Send it in a
series with the mlx5 change that uses it.

Info

3. NULL mask is not replaced by the default mask.

flow_offload.rst says spec without mask means the default mask. The
default masks are now in rte_flow_desc_item[].default_mask, so the
op could do it:

	mask = src->mask;
	if (mask == NULL && (int)src->type >= 0)
		mask = rte_flow_desc_item[src->type].default_mask;

As written, every caller has to handle the NULL case itself. If
leaving it out is intended, say why in the commit message.


More information about the dev mailing list