[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