All of lore.kernel.org
 help / color / mirror / Atom feed
From: Stephen Hemminger <stephen@networkplumber.org>
To: dev@dpdk.org
Cc: Stephen Hemminger <stephen@networkplumber.org>,
	Thomas Monjalon <thomas@monjalon.net>
Subject: [RFC 2/3] doc: add programmer's guide for flow rule compiler
Date: Tue,  5 May 2026 20:29:56 -0700	[thread overview]
Message-ID: <20260506033338.480610-3-stephen@networkplumber.org> (raw)
In-Reply-To: <20260506033338.480610-1-stephen@networkplumber.org>

Add a chapter to the programmer's guide describing the new
rte_flow_compile library: API summary, BNF grammar, field
qualifier semantics (is/spec/last/mask/prefix), diagnostic
format, and the table-driven extension model for adding
items and actions.

Documents the limitations of the initial implementation
(item/action coverage, missing RSS and RAW handling) and
the textual MAC and IPv6 forms accepted.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 MAINTAINERS                                |   6 +
 doc/guides/prog_guide/flow_compile_lib.rst | 272 +++++++++++++++++++++
 doc/guides/prog_guide/index.rst            |   1 +
 doc/guides/rel_notes/release_26_07.rst     |   6 +
 4 files changed, 285 insertions(+)
 create mode 100644 doc/guides/prog_guide/flow_compile_lib.rst

diff --git a/MAINTAINERS b/MAINTAINERS
index 0f5539f851..4923e126df 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -448,6 +448,12 @@ F: app/test-pmd/cmdline_flow.c
 F: doc/guides/prog_guide/ethdev/flow_offload.rst
 F: lib/ethdev/rte_flow*
 
+Flow Compiler API
+M: Stephen Hemminger <stephen@networkplumber.org>
+T: git://dpdk.org/next/dpdk-next-net
+F: lib/flow_compile/
+F: doc/guides/prog_guide/flow_compile_lib.rst
+
 Traffic Management API
 M: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
 T: git://dpdk.org/next/dpdk-next-net
diff --git a/doc/guides/prog_guide/flow_compile_lib.rst b/doc/guides/prog_guide/flow_compile_lib.rst
new file mode 100644
index 0000000000..8af374b33b
--- /dev/null
+++ b/doc/guides/prog_guide/flow_compile_lib.rst
@@ -0,0 +1,272 @@
+..  SPDX-License-Identifier: BSD-3-Clause
+    Copyright (c) 2026 Stephen Hemminger <stephen@networkplumber.org>
+
+Flow Rule Compiler
+==================
+
+The flow rule compiler (``rte_flow_compile``) turns a textual
+description of an ``rte_flow`` rule into the
+``struct rte_flow_attr`` / ``struct rte_flow_item`` /
+``struct rte_flow_action`` arrays accepted by ``rte_flow_create()``.
+
+It is modelled on ``pcap_compile()`` from libpcap: a single string in,
+an opaque compiled object out, with human readable diagnostics
+written to a caller supplied buffer.
+
+The compiler depends only on the EAL and the existing
+``rte_ethdev`` (``rte_flow.h``) library.  In particular it does not
+pull in ``rte_cmdline``, so it is suitable for use from libraries,
+control planes and unit tests.
+
+
+Example
+-------
+
+.. code-block:: c
+
+   char errbuf[RTE_FLOW_COMPILE_ERRBUF_SIZE];
+   const char *src =
+       "ingress group 0 priority 1 "
+       "pattern eth / ipv4 src is 10.0.0.1 / udp dst is 4789 / end "
+       "actions queue index 3 / count / end";
+
+   struct rte_flow_compile *fc = rte_flow_compile(src, errbuf);
+   if (fc == NULL) {
+           fprintf(stderr, "%s\n", errbuf);
+           return -1;
+   }
+
+   struct rte_flow_error err;
+   struct rte_flow *f = rte_flow_compile_create(port_id, fc, &err);
+
+   /* fc may be reused on multiple ports or freed now. */
+   rte_flow_compile_free(fc);
+
+
+API summary
+-----------
+
+.. code-block:: c
+
+   struct rte_flow_compile *
+   rte_flow_compile(const char *str,
+                    char errbuf[RTE_FLOW_COMPILE_ERRBUF_SIZE]);
+
+   void
+   rte_flow_compile_free(struct rte_flow_compile *fc);
+
+   const struct rte_flow_attr   *rte_flow_compile_attr(...);
+   const struct rte_flow_item   *rte_flow_compile_pattern(..., unsigned int *n);
+   const struct rte_flow_action *rte_flow_compile_actions(..., unsigned int *n);
+
+   int             rte_flow_compile_validate(uint16_t port_id, ..., struct rte_flow_error *);
+   struct rte_flow *rte_flow_compile_create  (uint16_t port_id, ..., struct rte_flow_error *);
+
+The compiled object owns every buffer it returns: attributes,
+patterns, actions and all underlying spec/mask/last/conf payloads.
+Pointers are valid until ``rte_flow_compile_free()`` is called.
+A single compiled rule may be installed on many ports and validated
+or created concurrently from multiple threads; the parser itself
+holds no static mutable state.
+
+
+Grammar
+-------
+
+The grammar is pure ASCII; ``#`` starts an end-of-line comment.
+Whitespace is insignificant.
+
+.. code-block:: bnf
+
+   rule         ::= attribute* "pattern" item-list "actions" action-list
+   attribute    ::= "ingress" | "egress" | "transfer"
+                  | "group"    UINT
+                  | "priority" UINT
+   item-list    ::= ( item "/" )* "end"
+   item         ::= IDENT field-spec*
+   field-spec   ::= IDENT qualifier value
+   qualifier    ::= "is" | "spec" | "last" | "mask" | "prefix"
+   action-list  ::= ( action "/" )* "end"
+   action       ::= IDENT param*
+   param        ::= IDENT value
+   value        ::= UINT | IPV4 | IPV6 | MAC | HEXSTR | STRING
+
+Both lists may be empty; ``pattern end`` is a wildcard match and is
+useful as a catch-all rule.  An empty action list is accepted by the
+compiler but typically rejected by the underlying PMD.
+
+Lexical tokens:
+
+.. code-block:: bnf
+
+   IDENT        ::= [A-Za-z_][A-Za-z0-9_]*
+   UINT         ::= [0-9]+ | "0x" [0-9A-Fa-f]+         ; up to 16 hex digits
+   IPV4         ::= UINT "." UINT "." UINT "." UINT    ; each 0..255
+   IPV6         ::= RFC 4291 / 5952 textual form (no embedded IPv4)
+   MAC          ::= XX ":" XX ":" XX ":" XX ":" XX ":" XX
+   HEXSTR       ::= "0x" [0-9A-Fa-f]{2*N}              ; > 16 hex digits
+   STRING       ::= '"' character* '"'
+
+The grammar follows ``testpmd`` closely so that flow rules already
+familiar to users carry over; the lexer and parser are independent
+implementations and do not depend on testpmd, ``rte_cmdline`` or
+``cmdline_parse_*``.
+
+
+Field qualifier semantics
+-------------------------
+
+For each parsed ``field qualifier value`` triple the compiler writes
+into one or more of the spec/mask/last buffers.  Semantics match
+``testpmd``:
+
+.. list-table::
+   :header-rows: 1
+   :widths: 10 30 30 20
+
+   * - Qualifier
+     - spec
+     - mask
+     - last
+   * - ``is``
+     - value
+     - all-ones over the field
+     - --
+   * - ``spec``
+     - value
+     - --
+     - --
+   * - ``mask``
+     - --
+     - value
+     - --
+   * - ``last``
+     - --
+     - --
+     - value
+   * - ``prefix``
+     - --
+     - high N bits set (CIDR style); IPv4/IPv6 only
+     - --
+
+Last write wins.  ``ipv4 src spec 10.0.0.0 src prefix 16`` therefore
+matches the entire ``10.0.0.0/16`` range with mask ``255.255.0.0``;
+``src is 10.0.0.0`` would have set the mask to all-ones, which is
+exact match.
+
+
+Diagnostics
+-----------
+
+Errors are reported as ``LINE:COL: message`` in the caller-supplied
+``errbuf`` of at least ``RTE_FLOW_COMPILE_ERRBUF_SIZE`` (256) bytes.
+The first error wins; subsequent errors are suppressed so that the
+user sees the original cause rather than a cascade.
+
+On failure ``rte_errno`` is set to ``EINVAL`` for parse errors and
+``ENOMEM`` for allocation failures.
+
+
+Extending the compiler
+----------------------
+
+The parser is entirely table driven.  Adding a new flow item type
+requires no parser changes:
+
+#. In ``flow_compile_tables.c``, define a static
+   ``struct field_desc`` array describing the parsable fields of the
+   item's spec struct.
+#. Add an ``ITEM(...)`` entry to ``flow_items[]``.
+
+Each ``field_desc`` lists the field's offset, byte width and a
+``field_kind`` (``FK_U32``, ``FK_BE16``, ``FK_MAC``, ``FK_IPV4``,
+``FK_IPV6``, ``FK_BYTES``, ...).  Default setters honor every kind
+and produce the correct byte order automatically.
+
+For fields whose layout cannot be expressed as a plain byte range
+(C bitfields, indirect arrays, RSS keys, ...) populate the ``set``
+function pointer.  The custom setter receives the destination
+buffer, an optional mask buffer (non-NULL when the user wrote
+``is``) and the parsed value token.
+
+Adding a new action type follows the same pattern with
+``flow_actions[]`` and ``ACTION(...)``.
+
+
+Source layout
+-------------
+
+The library sits in ``lib/flow_compile`` and is split for clarity:
+
+================================  ==================================
+File                              Contents
+================================  ==================================
+``rte_flow_compile.h``            Public API.
+``flow_compile_priv.h``           Internal types: tokens, descriptors,
+                                  parser state.
+``flow_compile_lex.c``            Hand-rolled lexer with
+                                  source-position tracking for
+                                  diagnostics.
+``flow_compile_parse.c``          Recursive-descent parser plus the
+                                  default field setters used by the
+                                  table-driven body parser.
+``flow_compile_tables.c``         Per-item and per-action descriptor
+                                  tables.  All extension work
+                                  happens here.
+``rte_flow_compile_api.c``        Public entry points: compile,
+                                  free, accessors, validate, create.
+================================  ==================================
+
+
+Implementation notes
+--------------------
+
+Locale independence
+   Every character classification uses inline ASCII-only predicates
+   rather than ``<ctype.h>``; hex parsing uses an inline nibble
+   helper rather than ``strtoul()``.  The grammar is pure ASCII, so
+   the active locale cannot affect parsing.
+
+Endianness
+   All multibyte writes go through ``rte_cpu_to_be_{16,32,64}`` or
+   raw byte copies from already network-order tokens
+   (``TK_IPV4``, ``TK_MAC``, ``TK_IPV6``).
+
+Alignment
+   Spec and mask buffers may contain unaligned multibyte fields
+   inside packed-ish header structs.  All writes go through
+   ``memcpy`` to handle this portably.
+
+Memory
+   All allocations go through ``rte_zmalloc`` and ``rte_free``.  Each
+   spec, mask, last and conf payload is its own allocation; the
+   pattern and action arrays are separate ``rte_calloc`` allocations
+   that grow by doubling.  ``rte_flow_compile_free()`` walks the
+   pattern and action arrays and frees every non-NULL slot before
+   freeing the arrays themselves, so a partially compiled rule on
+   a parse-error path is cleaned up uniformly.
+
+Reentrancy
+   The parser holds no static mutable state.  Multiple threads may
+   compile rules in parallel and a single compiled rule may be
+   installed concurrently on multiple ports.
+
+
+Limitations
+-----------
+
+The initial implementation covers the most common items
+(``eth``, ``vlan``, ``ipv4``, ``ipv6``, ``tcp``, ``udp``, ``vxlan``,
+``port_id``, ``port_representor``, ``represented_port``) and actions
+(``drop``, ``passthru``, ``queue``, ``mark``, ``jump``, ``count``,
+``port_id``, ``port_representor``, ``represented_port``,
+``of_pop_vlan``, ``vxlan_decap``).  Adding more is purely a matter
+of extending the descriptor tables.
+
+Items and actions whose conf has a variable-length payload
+(``RSS``, ``RAW``, the various ``RAW_ENCAP``/``RAW_DECAP`` actions)
+are not yet wired up; they require custom setters via the
+``field_desc.set`` hook.
+
+The IPv6 tokeniser does not accept the embedded-IPv4 dotted-quad
+form (``::ffff:10.0.0.1``); use the all-hex form instead.
diff --git a/doc/guides/prog_guide/index.rst b/doc/guides/prog_guide/index.rst
index e6f24945b0..3476dfecfd 100644
--- a/doc/guides/prog_guide/index.rst
+++ b/doc/guides/prog_guide/index.rst
@@ -121,6 +121,7 @@ Utility Libraries
 
     argparse_lib
     cmdline
+    flow_compile_lib
     ptr_compress_lib
     timer_lib
     rcu_lib
diff --git a/doc/guides/rel_notes/release_26_07.rst b/doc/guides/rel_notes/release_26_07.rst
index f012d47a4b..addb9ff94b 100644
--- a/doc/guides/rel_notes/release_26_07.rst
+++ b/doc/guides/rel_notes/release_26_07.rst
@@ -64,6 +64,12 @@ New Features
   * ``--auto-probing`` enables the initial bus probing, which is the current default behavior.
 
 
+* **Added library to compile flow definitions.**
+
+  New library that works like libpcap ``pcap_compile`` function to compile
+  a text string into flow rules.
+
+
 Removed Items
 -------------
 
-- 
2.53.0


  parent reply	other threads:[~2026-05-06  3:33 UTC|newest]

Thread overview: 31+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-05-05 18:39 [PATCH v12 0/6] flow_parser: add shared parser library Lukas Sismis
2026-05-05 18:39 ` [PATCH v12 1/6] cmdline: include stddef.h for MSVC compatibility Lukas Sismis
2026-05-05 18:39 ` [PATCH v12 2/6] ethdev: add RSS type helper APIs Lukas Sismis
2026-05-05 18:39 ` [PATCH v12 3/6] ethdev: add flow parser library Lukas Sismis
2026-05-05 18:39 ` [PATCH v12 4/6] app/testpmd: use flow parser from ethdev Lukas Sismis
2026-05-05 18:39 ` [PATCH v12 5/6] examples/flow_parsing: add flow parser demo Lukas Sismis
2026-05-05 18:39 ` [PATCH v12 6/6] test: add flow parser functional tests Lukas Sismis
2026-05-05 18:46 ` [PATCH v12 0/6] flow_parser: add shared parser library Lukáš Šišmiš
2026-05-05 21:59 ` Stephen Hemminger
2026-05-07 12:29   ` Lukáš Šišmiš
2026-05-06  3:29 ` [RFC PATCH 0/3] flow_compile: textual flow rule compiler Stephen Hemminger
2026-05-06  3:29   ` [RFC 1/3] flow_compile: introduce " Stephen Hemminger
2026-05-06  8:06     ` Bruce Richardson
2026-05-06 10:10       ` Konstantin Ananyev
2026-05-06 15:46       ` Stephen Hemminger
2026-05-06 15:56         ` Bruce Richardson
2026-05-06 17:11           ` Stephen Hemminger
2026-05-06  3:29   ` Stephen Hemminger [this message]
2026-05-06  3:29   ` [RFC 3/3] test/flow_compile: add unit tests for " Stephen Hemminger
2026-05-22 15:27   ` [RFC PATCH 0/3] flow_compile: textual " Lukáš Šišmiš
2026-05-22 18:16     ` Stephen Hemminger
2026-05-07  0:06 ` [RFC v2 0/4] " Stephen Hemminger
2026-05-07  0:06   ` [RFC v2 1/4] config: add support for using flex and bison Stephen Hemminger
2026-05-07  0:06   ` [RFC v2 2/4] flow_compile: introduce textual flow rule compiler Stephen Hemminger
2026-05-07  0:06   ` [RFC v2 3/4] doc: add programmer's guide for " Stephen Hemminger
2026-05-07  0:06   ` [RFC v2 4/4] test/flow_compile: add unit tests " Stephen Hemminger
2026-05-07  2:54   ` [RFC v2 0/4] flow_compile: textual " Stephen Hemminger
2026-05-07  8:10   ` Bruce Richardson
2026-05-07 16:09     ` Stephen Hemminger
2026-05-07 16:26       ` Bruce Richardson
2026-05-07 16:57         ` Stephen Hemminger

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260506033338.480610-3-stephen@networkplumber.org \
    --to=stephen@networkplumber.org \
    --cc=dev@dpdk.org \
    --cc=thomas@monjalon.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.