On Fri, 16 Oct 2026 08:26:45 +0300
Bing Zhao <[email protected]> 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 <[email protected]>
> Reviewed-by: Dariusz Sosnowski <[email protected]>
> ---

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.

Reply via email to