On Tue, 27 Jan 2026 22:05:25 +0100 Lukas Sismis <[email protected]> wrote:
> This series extracts the testpmd flow CLI parser into a reusable library, > enabling external applications to parse rte_flow rules using testpmd syntax. > > Motivation > ---------- > External applications like Suricata IDS [1] need to express hardware filtering > rules in a consistent, human-readable format. Rather than inventing custom > syntax, reusing testpmd's well-tested flow grammar provides immediate > compatibility with existing documentation and user knowledge. > > Note: This library provides only one way to create rte_flow structures. > Applications can also construct rte_flow_attr, rte_flow_item[], and > rte_flow_action[] directly in C code. > > Design > ------ > The library (librte_flow_parser) exposes the following APIs: > - rte_flow_parser_parse_attr_str(): Parse attributes only > - rte_flow_parser_parse_pattern_str(): Parse patterns only > - rte_flow_parser_parse_actions_str(): Parse actions only > > Testpmd is updated to use the library, ensuring a single > maintained parser implementation. > > Testing and Demo > ------- > - Functional tests in dpdk-test > - Example application: examples/flow_parsing > > Changes > ------- > > v6: > - Inconsistent Experimental API Version adjusted > - Fixes Tag added to MSVC build commit > - Non-Standard Header Guards updated > - Implicit Pointer Comparison and Return Type issues addressed in many places > - commit message in patch 6 updated > > v5: > - removed/replaced (f)printf code from the library > - reverted back to exporting the internal/private API as it is needed by > testpmd and cannot be easily split further. > - adjusted length of certain lines > - marking port/queue id typedef as experimental > - updated release rel_notes > - copyeright adjustments > > > v4: > - ethdev changes in separate commit > - library's public API only exposes attribute, pattern and action parsing, > while the full command parsing is kept internal for testpmd usage only. > - Addressed Stephen's comments from V3 > - dpdk-test now have tests focused on public and internal library functions > > v3: > - Add more functional tests > - More concise MAINTAINERS updates > - Updated license headers > - A thing to note: When playing with flow commands, I figured, some may use > non-flow commands, such as raw decap/encap, policy meter and others. > Flow parser library itself now supports `set` command to set e.g. the decap/ > encap parameters, as the flow syntax only supports defining the index of the > encap/decap configs. The library, however, does not support e.g. `create` > command to create policy meters, as that is just an ID and it can be created > separately using rte_meter APIs. > > [1] https://github.com/OISF/suricata/pull/13950 > > Lukas Sismis (6): > cmdline: include stddef.h for MSVC compatibility > ethdev: add RSS type helper APIs > flow_parser: add shared parser library > app/testpmd: use shared flow parser library > examples/flow_parsing: add flow parser demo > test: add flow parser library functional tests > > MAINTAINERS | 6 +- > app/test-pmd/cmd_flex_item.c | 41 +- > app/test-pmd/cmdline.c | 267 +- > app/test-pmd/config.c | 112 +- > app/test-pmd/flow_parser.c | 409 + > app/test-pmd/flow_parser_cli.c | 153 + > app/test-pmd/meson.build | 5 +- > app/test-pmd/testpmd.c | 4 + > app/test-pmd/testpmd.h | 126 +- > app/test/meson.build | 1 + > app/test/test_ethdev_api.c | 51 + > app/test/test_flow_parser.c | 923 ++ > doc/api/doxy-api-index.md | 1 + > doc/api/doxy-api.conf.in | 1 + > doc/guides/prog_guide/flow_parser_lib.rst | 111 + > doc/guides/prog_guide/index.rst | 1 + > doc/guides/rel_notes/release_26_03.rst | 21 + > examples/flow_parsing/main.c | 291 + > examples/flow_parsing/meson.build | 11 + > examples/meson.build | 1 + > lib/cmdline/cmdline_parse.h | 2 + > lib/ethdev/rte_ethdev.c | 107 + > lib/ethdev/rte_ethdev.h | 77 + > lib/flow_parser/meson.build | 7 + > .../flow_parser/rte_flow_parser.c | 11430 ++++++++-------- > lib/flow_parser/rte_flow_parser.h | 124 + > lib/flow_parser/rte_flow_parser_private.h | 1247 ++ > lib/meson.build | 2 + > 28 files changed, 9698 insertions(+), 5834 deletions(-) > create mode 100644 app/test-pmd/flow_parser.c > create mode 100644 app/test-pmd/flow_parser_cli.c > create mode 100644 app/test/test_flow_parser.c > create mode 100644 doc/guides/prog_guide/flow_parser_lib.rst > create mode 100644 examples/flow_parsing/main.c > create mode 100644 examples/flow_parsing/meson.build > create mode 100644 lib/flow_parser/meson.build > rename app/test-pmd/cmdline_flow.c => lib/flow_parser/rte_flow_parser.c (55%) > create mode 100644 lib/flow_parser/rte_flow_parser.h > create mode 100644 lib/flow_parser/rte_flow_parser_private.h > There are only a couple of minor nits left to keep me from putting this in next-net. There is a check comparing pointer against 0 and the example is using headers not found on Windows. ### Patch 3/6: flow_parser: add shared parser library **Error** (must fix): 1. **Incorrect NULL checks in parse helper functions** (lines ~15667 and ~15692): ```c if (src == NULL || pattern == NULL || pattern_n == 0) // BUG: should be pattern_n == NULL ``` ```c if (src == NULL || actions == NULL || actions_n == 0) // BUG: should be actions_n == NULL ``` These check if the *count* is zero rather than if the *pointer* is NULL. This will cause incorrect behavior when passing valid pointers. **Warning** (should fix): 2. **Thread safety documentation** — The documentation states "The parser is not thread-safe" but the public header doesn't include this warning in the API docstrings. Add `@warning Not thread-safe` to each public function's Doxygen comment. 3. **Missing error return in `rte_flow_parser_init()`** — The function signature shows `int` return but I don't see error handling for double-initialization or invalid state. --- ### Patch 5/6: examples/flow_parsing: add example **Warning**: - Uses `<arpa/inet.h>` which is not portable to Windows. Consider using DPDK's byte order macros or conditional compilation. --- ### Required Fix ```c // In rte_flow_parser_parse_pattern_str(): - if (src == NULL || pattern == NULL || pattern_n == 0) + if (src == NULL || pattern == NULL || pattern_n == NULL) // In rte_flow_parser_parse_actions_str(): - if (src == NULL || actions == NULL || actions_n == 0) + if (src == NULL || actions == NULL || actions_n == NULL) ```

