]> git.ipfire.org Git - thirdparty/nftables.git/commitdiff
doc: clarify JSON rule positioning with handle field
authorAlexandre Knecht <knecht.alexandre@gmail.com>
Thu, 6 Nov 2025 09:16:09 +0000 (10:16 +0100)
committerPhil Sutter <phil@nwl.cc>
Tue, 20 Jan 2026 23:03:03 +0000 (00:03 +0100)
The existing documentation briefly mentioned that the handle field can be
used for positioning, but the behavior was ambiguous. This commit clarifies:

- ADD with handle: inserts rule AFTER the specified handle
- INSERT with handle: inserts rule BEFORE the specified handle
- Multiple rules added at the same handle are positioned relative to the
  original rule, not to previously inserted rules
- Explicit commands (with command wrapper) use handle for positioning
- Implicit commands (without command wrapper, used in export/import)
  ignore handle for portability

This clarification helps users understand the correct behavior and avoid
confusion when using the JSON API for rule management.

Signed-off-by: Alexandre Knecht <knecht.alexandre@gmail.com>
Signed-off-by: Phil Sutter <phil@nwl.cc>
doc/libnftables-json.adoc

index c3af007e19177f06c40b19efa190656b50c15e58..23a928df772d47784577b02a4ca7af1961ff06aa 100644 (file)
@@ -122,7 +122,9 @@ ____
                'CT_TIMEOUT' | 'CT_EXPECTATION'
 ____
 
-Add a new ruleset element to the kernel.
+Add a new ruleset element to the kernel. For rules, this appends the rule to the
+end of the chain by default. If the rule contains a *handle* or *index* property,
+it is inserted *after* the rule identified by those properties.
 
 === REPLACE
 [verse]
@@ -143,9 +145,14 @@ Identical to *add* command, but returns an error if the object already exists.
 
 This command is identical to *add* for rules, but instead of appending the rule
 to the chain by default, it inserts at first position. If a *handle* or *index*
-property is given, the rule is inserted before the rule identified by those
+property is given, the rule is inserted *before* the rule identified by those
 properties.
 
+NOTE: In explicit commands (*add*, *insert*, *create* with command wrapper), the
+*handle* field is used for positioning. In implicit commands (bare *rule* objects
+without command wrapper, as used in export/import), the *handle* field is ignored
+to ensure portability across systems.
+
 === DELETE
 [verse]
 *{ "delete":* 'ADD_OBJECT' *}*
@@ -311,8 +318,13 @@ Each rule consists of at least one.
        *add*/*insert*/*replace* commands only.
 *handle*::
        The rule's handle. In *delete*/*replace* commands, it serves as an identifier
-       of the rule to delete/replace. In *add*/*insert* commands, it serves as
-       an identifier of an existing rule to append/prepend the rule to.
+       of the rule to delete/replace. In *add*/*insert*/*create* commands, when
+       present, it specifies positioning relative to an existing rule: *add* inserts
+       the new rule *after* the specified handle, *insert* inserts *before* it. When
+       multiple rules are added at the same handle position, they are positioned
+       relative to the original rule, not to previously inserted rules. In implicit
+       rule objects (without command wrapper, as used in *nft -j list* output), the
+       handle field is present but ignored on input to ensure export/import portability.
 *index*::
        The rule's position for *add*/*insert* commands. It is used as an alternative to
        *handle* then.