Hi Florian, On Thu, Mar 07, 2024 at 01:26:32PM +0100, Florian Westphal wrote: > The existing parser cannot handle certain inputs. Example: > > "map": { > "family": "ip", > "name": "testmap", > "table": "test", > "type": "ipv4_addr", > "handle": 2, > "map": "verdict", > "elem": [ [ "*", { > "jump": { > "target": "testchain" > [..] > }, > { > "chain": { > "family": "ip", > "table": "test", > "name": "testchain", > ... > > Problem is that the json input parser does cmd_add at the earliest opportunity. > > For a simple input file defining a table, set, set element and chain, we get > following transaction: > * add table > * add set > * add setelem > * add chain > > This is rejected by the kernel, because the set element references a chain > that does (not yet) exist. > > Normal input parser only allocates a CMD_ADD request for the table. > > Rest of the transactional commands are created much later, via nft_cmd_expand(), > which walks "struct table" and then creates the needed CMD_ADD for the objects > owned by that table. JSON parser simply does not support nested syntax, like, for instance: | table test { | map testmap { | type ipv4_addr : verdict | elements = { | "*" : jump testchain | } | } | chain testchain { | } | } Your example above is equivalent to the following in standard syntax: | add table t | add map t m { type ipv4_addr : verdict; elements = { 10.0.0.1 : jump mychain }; } | add chain t mychain It is rejected by nft as well: | /tmp/input.nft:2:54-61: Error: Could not process rule: No such file or directory | add map t m { type ipv4_addr : verdict; elements = { 10.0.0.1 : jump mychain }; } | ^^^^^^^^ (Note the wrong marker position, an unrelated bug it seems.) If I swap the 'add map' and 'add chain' commands in input, it is accepted. Cheers, Phil