On Thu, 21 May 2026 15:43:54 +0530
Megha Ajmera <[email protected]> wrote:

> Add parser support for a generic PROG flow action in testpmd.
> 
> The update adds CLI tokens and parsing logic for program name and
> argument tuples (name, size, value), enabling programmable action
> configuration through the flow command interface.
> 
> Example flow rule:
>   flow create 0 ingress pattern eth / end actions prog name my_prog
>   argument name arg0 size 4 value 10 / end
> 
> Signed-off-by: Megha Ajmera <[email protected]>
> Signed-off-by: Praveen Shetty <[email protected]>
> ---

Ran AI review on this manually since that gets better context.
The feedback was:

On Thu, 21 May 2026 15:43:54 +0530
Megha Ajmera <[email protected]> wrote:

> Add parser support for a generic PROG flow action in testpmd.
>
> The update adds CLI tokens and parsing logic for program name and
> argument tuples (name, size, value), enabling programmable action
> configuration through the flow command interface.

Errors

1. CREATE proceeds with partially-converted action data on conversion
   failure.

   In cmd_flow_parsed() the CREATE case prints a warning if
   convert_action_prog_to_rte_flow() returns negative, then
   unconditionally calls port_flow_create(). Inside
   convert_action_prog_to_rte_flow(), each per-PROG failure does
   "continue" rather than aborting, so the function returns negative
   while some actions[i].conf pointers have been replaced with
   rte_flow_action_prog and others still point to the parser-internal
   action_prog_data (a completely different layout). The PMD then
   dereferences a mix of two unrelated structure types. Either abort
   the create on negative ret, or make convert_action_prog_to_rte_flow()
   fail-fast: free everything converted so far, restore conf pointers
   (or never overwrite them until the whole pass succeeds), and return
   without touching port_flow_create().

2. Argument value is sent in host byte order, but the API requires
   network byte order.

   The doc for struct rte_flow_action_prog_argument in
   lib/ethdev/rte_flow.h says the value array must be in network byte
   order. The conversion code does:

       memcpy(value, &prog_data->args[j].value, args[j].size);

   prog_data->args[j].value is a host-order uint64_t populated by
   parse_int. For "size 4 value 10" on little-endian this produces
   {0x0a,0x00,0x00,0x00}; on big-endian it produces {0x00,0x00,0x00,0x00}
   -- the leading zero bytes of the 8-byte value, so the user always
   sees zero. Either convert with rte_cpu_to_be_32/64 before memcpy,
   or have the parser accept and store the value as a network-order
   byte array of the declared size.

3. Only the CREATE path is converted; VALIDATE and the async/template
   paths still pass action_prog_data to the PMD.

   cmd_flow_parsed() routes the same in->args.vc.actions array to
   VALIDATE (port_flow_validate), and to multiple async/template paths
   (port_queue_flow_create, port_flow_template_table_create,
   port_action_handle_create, etc.). None of these are converted by
   this patch, so any PROG action used with "flow validate",
   "flow queue ... create", indirect-action create, or pattern/action
   templates passes the parser-internal action_prog_data to the PMD
   with the wrong layout. Conversion needs to be factored into a
   helper invoked from every code path that hands actions to the
   ethdev API, not bolted onto CREATE only.

4. Unbounded scan for END in convert_action_prog_to_rte_flow().

       while (actions[i].type != RTE_FLOW_ACTION_TYPE_END)
               i++;

   If a caller ever passes an actions array without a terminating END,
   this walks off the end. The caller already knows
   in->args.vc.actions_n; pass that as the bound and remove the
   dual-mode behavior (count-or-not). The function is only ever called
   with prog_action_count == 0, so the other branch is dead code
   anyway.

5. size == 0 argument is silently accepted but violates the API.

   The rte_flow_action_prog_argument doc states "its size must be
   non-zero and its value must point to a valid array of size bytes".
   The convert code does:

       args[j].size = prog_data->args[j].size;
       if (args[j].size == 0)
               continue;

   This leaves args[j].value == NULL while args[j].size == 0 and hands
   that to the PMD. Either reject size == 0 at parse time, or treat it
   as an error during conversion. Letting it through means
   valid-looking input produces an API-contract violation that the PMD
   has no obligation to handle.

Warnings

6. Identifiers with a leading double underscore are reserved.

   __prog_argument_name_args_push, __prog_argument_size_args_push, and
   __prog_argument_value_args_push use a "__" prefix. The C standard
   reserves names starting with two underscores for the implementation.
   Rename to e.g. prog_argument_name_args_push.

7. RTE_SET_USED on parameters that are used.

   parse_vc_action_prog_argument() marks token and str as unused, then
   passes both to parse_default(). parse_vc_action_prog_argument_value()
   marks size as unused, then passes it to parse_vc_conf(). The v2
   changelog says "Fixed compilation warning"; these spurious
   RTE_SET_USED calls look like that fix. Remove them -- they mislead
   future readers and can hide a real unused parameter if one is added
   later.

8. Doxygen parameter name mismatch.

   The comment block above convert_action_prog_to_rte_flow() documents
   "@param action_count" but the actual parameter is named
   prog_action_count. The same comment describes a dual-mode interface
   ("If 0, will count until END action") that is never exercised --
   fix the name or simplify the interface.

9. No testpmd user-guide update.

   This adds new CLI syntax

       actions prog name <name> argument name <n> size <s> value <v>

   but doc/guides/testpmd_app_ug/testpmd_funcs.rst is not updated.
   Users have no documented way to learn the syntax.

10. No release notes update.

    A new user-visible testpmd feature should have a one-line entry in
    the current release notes.

Info

11. The static "struct arg arg[ACTION_PROG_MAX_ARGS]" arrays inside the
    three __prog_argument_*_args_push helpers can simply be a single
    non-static "struct arg" (or three) on the stack. push_args()
    consumes the entries during the current parse_vc_conf() call;
    persistent storage across CLI invocations is not needed and
    obscures the lifetime.

12. action_prog_data.length is written by the COMMON_STRING parser for
    the prog name field but never read afterwards (convert uses strdup,
    relying on NUL termination). It is required as a destination for
    the COMMON_STRING args triple, but a brief comment would prevent
    the next reader from thinking it is meaningful state.

Reply via email to