* Wed Jul 22 2026 Phil Sutter <psutter@redhat.com> [1.0.9-8.el9]
- spec: Update expected test suite results (Phil Sutter) [RHEL-190549]
- tests: monitor: Fix for out-of-path call (Phil Sutter) [RHEL-190549]
- tests: monitor: Excercise all syntaxes and variants by default (Phil Sutter) [RHEL-190549]
- tests: monitor: Test JSON echo mode as well (Phil Sutter) [RHEL-190549]
- tests: monitor: Become $PWD agnostic (Phil Sutter) [RHEL-190549]
- tests: monitor: Run in own netns (Phil Sutter) [RHEL-190549]
- tests: monitor: Label diffs to help users (Phil Sutter) [RHEL-190549]
- tests: monitor: Extend testcases a bit (Phil Sutter) [RHEL-190549]
- tests: monitor: enclose device names in quotes (Phil Sutter) [RHEL-190549]
- json: Dump flowtable hook spec only if present (Phil Sutter) [RHEL-190549]
- tests: py: Fix some JSON equivalents (Phil Sutter) [RHEL-190549]
- rule: constify set_is_non_concat_range() (Phil Sutter) [RHEL-190549]
- datatype: don't return a const string from cgroupv2_get_path() (Phil Sutter) [RHEL-190549]
- tests: py: Fix --keep test runner option (Phil Sutter) [RHEL-190549]
- segtree: fix get element command with open intervals (Phil Sutter) [RHEL-190549]
- segtree: replace default case by specific types in get_set_intervals() (Phil Sutter) [RHEL-190549]
- src: remove EXPR_SET_ELEM in range_expr_value_{low,high}() (Phil Sutter) [RHEL-190549]
- segtree: rename set_elem_add() to set_elem_expr_add() (Phil Sutter) [RHEL-190549]
- parser_json: fix map/set type confusion crash in map statement parser (Phil Sutter) [RHEL-190549]
- cache: honor -c/--check for reset commands (Phil Sutter) [RHEL-190549]
- tests: py: osf is ip-only (Phil Sutter) [RHEL-190549]
- tests: py: print the file name as intended (Phil Sutter) [RHEL-190549]
- tests: py: don't use a fixed filename (Phil Sutter) [RHEL-190549]
- mnl: Fix ordering of hooks in 'list hooks' output (Phil Sutter) [RHEL-190549]
- segtree: Fix for variable-sized object may not be initialized (Phil Sutter) [RHEL-190549]
- cache: Filter for table when listing flowtables (Phil Sutter) [RHEL-190549]
- cache: Filter for table when listing sets or maps (Phil Sutter) [RHEL-190549]
- cache: Respect family in all list commands (Phil Sutter) [RHEL-190549]
- cache: Include chains, flowtables and objects in netlink debug output (Phil Sutter) [RHEL-190549]
- cache: Relax chain_cache_dump filter application (Phil Sutter) [RHEL-190549]
- parser_bison: add range check for synproxy wscale (Phil Sutter) [RHEL-190549]
- json: complete multi-statement set element support (Phil Sutter) [RHEL-190549]
- segtree: Fix range aggregation on Big Endian (Phil Sutter) [RHEL-190549]
- mergesort: Align concatenation sort order with Big Endian (Phil Sutter) [RHEL-190549]
- mergesort: Fix sorting of string values (Phil Sutter) [RHEL-190549]
- tests: py: any/tcpopt.t.json: Fix JSON equivalent (Phil Sutter) [RHEL-190549]
- expression: expr_build_udata_recurse should recurse (Phil Sutter) [RHEL-190549]
- expression: propagate key datatype for anonymous sets (Phil Sutter) [RHEL-190549]
- netlink_delinearize: also consider exthdr type when trimming binops (Phil Sutter) [RHEL-190549]
- tcpopt: add symbol table for mptcp suboptions (Phil Sutter) [RHEL-190549]
- monitor: fix memleak in setelem cb (Phil Sutter) [RHEL-190549]
- tests: json_echo: Drop rule handle before multi-add (Phil Sutter) [RHEL-190549]
- rule: skip CMD_OBJ_SETELEMS with no elements after set flush (Phil Sutter) [RHEL-190549]
- doc: libnftables-json: Describe RULESET object (Phil Sutter) [RHEL-190549]
- doc: don't suggest to disable GSO (Phil Sutter) [RHEL-190549]
- tests: py: Implement payload_record() (Phil Sutter) [RHEL-190549]
- tests: py: inet/osf.t: Fix element ordering in JSON equivalents (Phil Sutter) [RHEL-190549]
- tests: py: Do not rely upon '[end]' marker (Phil Sutter) [RHEL-190549]
- tests: py: Fix for using wrong payload path (Phil Sutter) [RHEL-190549]
- tests: py: any/ct.t.json.output: Drop leftover entry (Phil Sutter) [RHEL-190549]
- datatype: Fix boolean type on Big Endian (Phil Sutter) [RHEL-190549]
- optimize: Fix verdict expression comparison (Phil Sutter) [RHEL-190549]
- src: parser_json: fix format string bugs (Phil Sutter) [RHEL-190549]
- doc: fix tcpdump example (Phil Sutter) [RHEL-190549]
- tests: py: objects.t: must use input, not output (Phil Sutter) [RHEL-190549]
- fib: Fix for existence check on Big Endian (Phil Sutter) [RHEL-190549]
- tests: Prepare exit codes for automake (Phil Sutter) [RHEL-190549]
- monitor: Inform JSON printer when reporting an object delete event (Phil Sutter) [RHEL-190549]
- monitor: Recognize flowtable add/del events (Phil Sutter) [RHEL-190549]
- tests: monitor: Fix regex collecting expected echo output (Phil Sutter) [RHEL-190549]
- monitor: Quote device names in chain declarations, too (Phil Sutter) [RHEL-190549]
- mnl: continue on ENOBUFS errors when processing batch (Phil Sutter) [RHEL-190549]
- tests: monitor: Fix for flag arrays in JSON output (Phil Sutter) [RHEL-190549]
- mnl: silence compiler warning (Phil Sutter) [RHEL-190549]
- fib: restore JSON output for relational expressions (Phil Sutter) [RHEL-190549]
- src: ensure chain policy evaluation when specified (Phil Sutter) [RHEL-190549]
- segtree: incorrect type when aggregating concatenated set ranges (Phil Sutter) [RHEL-190549]
- json: Do not reduce single-item arrays on output (Phil Sutter) [RHEL-190549]
- tests: py: Fix tests added for 'icmpv6 taddr' support (Phil Sutter) [RHEL-190549]
- tests: py: Drop stale entry from ip/snat.t.payload (Phil Sutter) [RHEL-190549]
- tests: py: Drop stale entries from ip6/{ct,meta}.t.json (Phil Sutter) [RHEL-190549]
- tests: py: Drop stale entry from ip/snat.t.json (Phil Sutter) [RHEL-190549]
- tests: py: Drop duplicate test from inet/vxlan.t (Phil Sutter) [RHEL-190549]
- tests: py: Drop stale entry from inet/tcp.t.json (Phil Sutter) [RHEL-190549]
- tests: py: Drop duplicate test from inet/gretap.t (Phil Sutter) [RHEL-190549]
- tests: py: Drop duplicate test from inet/gre.t (Phil Sutter) [RHEL-190549]
- tests: py: Drop duplicate test from inet/geneve.t (Phil Sutter) [RHEL-190549]
- tests: py: Drop stale entries since redundant test case removal (Phil Sutter) [RHEL-190549]
- src: netlink: netlink_delinearize_table() may return NULL (Phil Sutter) [RHEL-190549]
- doc: nft.8: Minor NAT STATEMENTS section review (Phil Sutter) [RHEL-190549]
- mnl: Call mnl_attr_nest_end() just once (Phil Sutter) [RHEL-190549]
- evaluate: validate set expression type before accessing flags (Phil Sutter) [RHEL-190549]
- rule: print chain and flowtable devices in quotes (Phil Sutter) [RHEL-190549]
- tests: py: re-enables nft-test.py to load the local nftables.py (Phil Sutter) [RHEL-190549]
- fib: allow to use it in set statements (Phil Sutter) [RHEL-190549]
- fib: allow to check if route exists in maps (Phil Sutter) [RHEL-190549]
- tests: shell: Fix ifname_based_hooks feature check (Phil Sutter) [RHEL-190549]
- json: reject too long interface names (Phil Sutter) [RHEL-190549]
- tests/py: clean up set backend support fallout (Phil Sutter) [RHEL-190549]
- cache: assert name is non-nul when looking up (Phil Sutter) [RHEL-190549]
- parser_bison: only reset by name is supported by now (Phil Sutter) [RHEL-190549]
- rule: skip fuzzy lookup if object name is not available (Phil Sutter) [RHEL-190549]
- parser_bison: allow delete command with map via handle (Phil Sutter) [RHEL-190549]
- debug: include kernel set information on cache fill (Phil Sutter) [RHEL-190549]
- tests/py: prepare for set debug change (Phil Sutter) [RHEL-190549]
- src: BASECHAIN flag no longer implies presence of priority expression (Phil Sutter) [RHEL-190549]
- netlink: Avoid crash upon missing NFTNL_OBJ_CT_TIMEOUT_ARRAY attribute (Phil Sutter) [RHEL-190549]
- tests: py: Properly fix JSON equivalents for netdev/reject.t (Phil Sutter) [RHEL-190549]
- tests: shell: Adjust to ifname-based hooks (Phil Sutter) [RHEL-190549]
- tests: shell: combine dormant flag with netdevice removal (Phil Sutter) [RHEL-190549]
- tests: monitor: Fix for single flag array avoidance (Phil Sutter) [RHEL-190549]
- netlink: Do not allocate a bogus flowtable priority expr (Phil Sutter) [RHEL-190549]
- netlink: Fix for potential crash parsing a flowtable (Phil Sutter) [RHEL-190549]
- json: work around fuzzer-induced assert crashes (Phil Sutter) [RHEL-190549]
- json: prevent null deref if chain->policy is not set (Phil Sutter) [RHEL-190549]
- tests: py: fix json single-flag output for fib & synproxy (Phil Sutter) [RHEL-190549]
- tests: shell: check for features not available in 5.4 (Phil Sutter) [RHEL-190549]
- netlink: Avoid potential NULL-ptr deref parsing set elem expressions (Phil Sutter) [RHEL-190549]
- netlink: Catch unknown types when deserializing objects (Phil Sutter) [RHEL-190549]
- json: Introduce json_add_array_new() (Phil Sutter) [RHEL-190549]
- json: Fix for memleak in __binop_expr_json (Phil Sutter) [RHEL-190549]
- json: Accept more than two operands in binary expressions (Phil Sutter) [RHEL-190549]
- json: Print single fib flag as non-array (Phil Sutter) [RHEL-190549]
- tests: shell: Add test case for JSON 'flags' arrays (Phil Sutter) [RHEL-190549]
- json: Print single set flag as non-array (Phil Sutter) [RHEL-190549]
- json: Print single synproxy flags as non-array (Phil Sutter) [RHEL-190549]
- parser_json: Introduce parse_flags_array() (Phil Sutter) [RHEL-190549]
- doc: Fix typo in nat statement 'prefix' description (Phil Sutter) [RHEL-190549]
- netlink: bogus concatenated set ranges with netlink message overrun (Phil Sutter) [RHEL-190549]
- parser_bison: add selector_expr rule to restrict typeof_expr (Phil Sutter) [RHEL-190549]
- optimize: invalidate merge in case of duplicated key in set/map (Phil Sutter) [RHEL-190549]
- evaluate: bail out if ct saddr/daddr dependency cannot be inserted (Phil Sutter) [RHEL-190549]
- parser_json: bail out on malformed statement in set (Phil Sutter) [RHEL-190549]
- parser_json: reject empty jump/goto chain (Phil Sutter) [RHEL-190549]
- parser_json: allow statement stateful statement only in set elements (Phil Sutter) [RHEL-190549]
- cache: prevent possible crash rule filter is NULL (Phil Sutter) [RHEL-190549]
- optimize: expand expression list when merging into concatenation (Phil Sutter) [RHEL-190549]
- cache: don't crash when filter is NULL (Phil Sutter) [RHEL-190549]
- evaluate: only allow stateful statements in set and map definitions (Phil Sutter) [RHEL-190549]
- evaluate: compact STMT_F_STATEFUL checks (Phil Sutter) [RHEL-190549]
- json: don't BUG when asked to list synproxies (Phil Sutter) [RHEL-190549]
- optimize: incorrect comparison for reject statement (Phil Sutter) [RHEL-190549]
- optimize: compact bitmask matching in set/map (Phil Sutter) [RHEL-190549]
- tests: shell: missing ct count elements in new set_stmt test (Phil Sutter) [RHEL-190549]
- evaluate: don't update cache for anonymous chains (Phil Sutter) [RHEL-190549]
- json: make sure timeout list is initialised (Phil Sutter) [RHEL-190549]
- parser_bison: consolidate connlimit grammar rule for set elements (Phil Sutter) [RHEL-190549]
- parser_bison: consolidate last grammar rule for set elements (Phil Sutter) [RHEL-190549]
- parser_bison: consolidate quota grammar rule for set elements (Phil Sutter) [RHEL-190549]
- parser_bison: consolidate limit grammar rule for set elements (Phil Sutter) [RHEL-190549]
- parser_bison: consolidate counter grammar rule for set elements (Phil Sutter) [RHEL-190549]
- tests: shell: extend coverage for set element statements (Phil Sutter) [RHEL-190549]
- evaluate: fix assertion failure with malformed map definitions (Phil Sutter) [RHEL-190549]
- evaluate: don't allow nat map with specified protocol (Phil Sutter) [RHEL-190549]
- parser_bison: reject non-serializeable typeof expressions (Phil Sutter) [RHEL-190549]
- netlink: fix stack buffer overrun when emitting ranged expressions (Phil Sutter) [RHEL-190549]
- src: print set element with multi-word description in single one line (Phil Sutter) [RHEL-190549]
- tests: shell: detach synproxy test (Phil Sutter) [RHEL-190549]
- src: do not merge a set with a erroneous one (Phil Sutter) [RHEL-190549]
- segtree: incomplete output in get element command with maps (Phil Sutter) [RHEL-190549]
- evaluate: release existing datatype when evaluating unary expression (Phil Sutter) [RHEL-190549]
- segtree: fix string data initialisation (Phil Sutter) [RHEL-190549]
- payload: honor inner payload description in payload_expr_cmp() (Phil Sutter) [RHEL-190549]
- payload: return early if dependency is not a payload expression (Phil Sutter) [RHEL-190549]
- evaluate: optimize zero length range (Phil Sutter) [RHEL-190549]
- fib: Change data type of fib oifname to "ifname" (Phil Sutter) [RHEL-190549]
- evaluate: auto-merge is only available for singleton interval sets (Phil Sutter) [RHEL-190549]
- parser_bison: compact and simplify list and reset syntax (Phil Sutter) [RHEL-190549]
- parser_bison: turn redundant ip option type field match into boolean (Phil Sutter) [RHEL-190549]
- datatype: clamp boolean value to 0 and 1 (Phil Sutter) [RHEL-190549]
- tests: shell: delete netdev chain after test (Phil Sutter) [RHEL-190549]
- ipopt: use ipv4 address datatype for address field in ip options (Phil Sutter) [RHEL-190549]
- netlink_delinarize: fix bogus munging of mask value (Phil Sutter) [RHEL-190549]
- evaluate: remove variable shadowing (Phil Sutter) [RHEL-190549]
- intervals: do not merge intervals with different timeout (Phil Sutter) [RHEL-190549]
- src: add EXPR_RANGE_VALUE expression and use it (Phil Sutter) [RHEL-190549]
- intervals: add helper function to set previous element (Phil Sutter) [RHEL-190549]
- parser_bison: fix UaF when reporting table parse error (Phil Sutter) [RHEL-190549]
- intervals: set internal element location with the deletion trigger (Phil Sutter) [RHEL-190549]
- optimize: compare expression length (Phil Sutter) [RHEL-190549]
- tests: py: Fix for storing payload into missing file (Phil Sutter) [RHEL-190549]
- json: Support typeof in set and map types (Phil Sutter) [RHEL-190549]
- json: collapse set element commands from parser (Phil Sutter) [RHEL-190549]
- doc: extend description of fib expression (Phil Sutter) [RHEL-190549]
- tests: monitor: fix up test case breakage (Phil Sutter) [RHEL-190549]
- src: fix extended netlink error reporting with large set elements (Phil Sutter) [RHEL-190549]
- mnl: rename to mnl_seqnum_alloc() to mnl_seqnum_inc() (Phil Sutter) [RHEL-190549]
- mnl: update cmd_add_loc() to take struct nlmsghdr (Phil Sutter) [RHEL-190549]
- rule: netlink attribute offset is uint32_t for struct nlerr_loc (Phil Sutter) [RHEL-190549]
- src: collapse set element commands from parser (Phil Sutter) [RHEL-190549]
- libnftables-json: fix raw payload expression documentation (Phil Sutter) [RHEL-190549]
- cache: initialize filter when fetching implicit chains (Phil Sutter) [RHEL-190549]
- tests: py: fix up udp csum fixup output (Phil Sutter) [RHEL-190549]
- proto: use NFT_PAYLOAD_L4CSUM_PSEUDOHDR flag to mangle UDP checksum (Phil Sutter) [RHEL-190549]
- tests: shell: stabilize packetpath/payload (Phil Sutter) [RHEL-190549]
- libnftables: Zero ctx->vars after freeing it (Phil Sutter) [RHEL-190549]
- cache: position does not require full cache (Phil Sutter) [RHEL-190549]
- cache: relax requirement for replace rule command (Phil Sutter) [RHEL-190549]
- cache: remove full cache requirement when echo flag is set on (Phil Sutter) [RHEL-190549]
- cache: assert filter when calling nft_cache_evaluate() (Phil Sutter) [RHEL-190549]
- cache: consolidate reset command (Phil Sutter) [RHEL-190549]
- cache: add filtering support for objects (Phil Sutter) [RHEL-190549]
- cache: only dump rules for the given table (Phil Sutter) [RHEL-190549]
- cache: accumulate flags in batch (Phil Sutter) [RHEL-190549]
- cache: reset filter for each command (Phil Sutter) [RHEL-190549]
- parser_json: fix several expression memleaks from error path (Phil Sutter) [RHEL-190549]
- parser_json: release buffer returned by json_dumps (Phil Sutter) [RHEL-190549]
- json: Support maps with concatenated data (Phil Sutter) [RHEL-190549]
- parser_json: fix crash in json_parse_set_stmt_list (Phil Sutter) [RHEL-190549]
- parser_bison: allow 0 burst in limit rate byte mode (Phil Sutter) [RHEL-190549]
- datatype: improve error reporting when time unit is not correct (Phil Sutter) [RHEL-190549]
- cache: rule by index requires full cache (Phil Sutter) [RHEL-190549]
- datatype: reject rate in quota statement (Phil Sutter) [RHEL-190549]
- optimize: skip variables in nat statements (Phil Sutter) [RHEL-190549]
- parser_json: use stdin buffer if available (Phil Sutter) [RHEL-190549]
- libnftables: skip useable checks for /dev/stdin (Phil Sutter) [RHEL-190549]
- optimize: clone counter before insertion into set element (Phil Sutter) [RHEL-190549]
- segtree: set on EXPR_F_KERNEL flag for catchall elements in the cache (Phil Sutter) [RHEL-190549]
- evaluate: set on expr->len for catchall set elements (Phil Sutter) [RHEL-190549]
- parser_bison: recursive table declaration in deprecated meter statement (Phil Sutter) [RHEL-190549]
- intervals: fix element deletions with maps (Phil Sutter) [RHEL-190549]
- src: add string preprocessor and use it for log prefix string (Phil Sutter) [RHEL-190549]
- tests: shell: skip ip option tests if kernel does not support it (Phil Sutter) [RHEL-190549]
- cmd: skip variable set elements when collapsing commands (Phil Sutter) [RHEL-190549]
- cmd: provide better hint if chain is already declared with different type/hook/priority (Phil Sutter) [RHEL-190549]
- monitor: too large shift exponent displaying payload expression (Phil Sutter) [RHEL-190549]
- scanner: inet_pton() allows for broader IPv4-Mapped IPv6 addresses (Phil Sutter) [RHEL-190549]
- evaluate: Fix incorrect checking the `base` variable in case of IPV6 (Phil Sutter) [RHEL-190549]
- evaluate: bogus protocol conflicts in vlan with implicit dependencies (Phil Sutter) [RHEL-190549]
- cache: check for NFT_CACHE_REFRESH in current requested cache too (Phil Sutter) [RHEL-190549]
- doc: nft.8: Fix markup in ct expectation synopsis (Phil Sutter) [RHEL-190549]
- mergesort: Avoid accidental set element reordering (Phil Sutter) [RHEL-190549]
- doc: nft.8: Two minor synopsis fixups (Phil Sutter) [RHEL-190549]
- tests: shell: check for reset tcp options support (Phil Sutter) [RHEL-190549]
- tests: shell: payload matching requires egress support (Phil Sutter) [RHEL-190549]
- tests: py: complete icmp and icmpv6 update (Phil Sutter) [RHEL-190549]
- src: disentangle ICMP code types (Phil Sutter) [RHEL-190549]
- evaluate: display "Range negative size" error (Phil Sutter) [RHEL-190549]
- netlink_delinearize: restore binop syntax when listing ruleset for flags (Phil Sutter) [RHEL-190549]
- doc: libnftables-json: Drop invalid ops from match expression (Phil Sutter) [RHEL-190549]
- parser: json: Support for synproxy objects (Phil Sutter) [RHEL-190549]
- tests: py: add payload merging test cases (Phil Sutter) [RHEL-190549]
- nftables: do mot merge payloads on negation (Phil Sutter) [RHEL-190549]
- rule: fix ASAN errors in chain priority to textual names (Phil Sutter) [RHEL-190549]
- parser: compact type/typeof set rules (Phil Sutter) [RHEL-190549]
- parser: compact interval typeof rules (Phil Sutter) [RHEL-190549]
- src: improve error reporting for destroy command (Phil Sutter) [RHEL-190549]
- tests: shell: permit use of host-endian constant values in set lookup keys (Phil Sutter) [RHEL-190549]
- evaluate: permit use of host-endian constant values in set lookup keys (Phil Sutter) [RHEL-190549]
- expression: missing line in describe command with invalid expression (Phil Sutter) [RHEL-190549]
- netlink_delinearize: move concat and value postprocessing to helpers (Phil Sutter) [RHEL-190549]
- evaluate: skip byteorder conversion for selector smaller than 2 bytes (Phil Sutter) [RHEL-190549]
- cache: Optimize caching for 'list tables' command (Phil Sutter) [RHEL-190549]
- evaluate: fix check for unknown in cmd_op_to_name (Phil Sutter) [RHEL-190549]
- evaluate: don't assert on net/transport header conflict (Phil Sutter) [RHEL-190549]
- json: Support sets' auto-merge option (Phil Sutter) [RHEL-190549]
- rule: fix sym refcount assertion (Phil Sutter) [RHEL-190549]
- evaluate: error out when store needs more than one 128bit register of align fixup (Phil Sutter) [RHEL-190549]
- evaluate: do not fetch next expression on runaway number of concatenation components (Phil Sutter) [RHEL-190549]
- evaluate: skip anonymous set optimization for concatenations (Phil Sutter) [RHEL-190549]
- evaluate: add missing range checks for dup,fwd and payload statements (Phil Sutter) [RHEL-190549]
- doc: incorrect datatype description for icmpv6_type and icmpvx_code (Phil Sutter) [RHEL-190549]
- tests: shell: prefer project nft to system-wide nft (Phil Sutter) [RHEL-190549]
- parser_bison: ensure all timeout policy names are released (Phil Sutter) [RHEL-190549]
- netlink: fix stack overflow due to erroneous rounding (Phil Sutter) [RHEL-190549]
- parser_bison: error out on duplicated type/typeof/element keywords (Phil Sutter) [RHEL-190549]
- tests: shell: add test to cover payload transport match and mangle (Phil Sutter) [RHEL-190549]
- evaluate: fix stack overflow with huge priority string (Phil Sutter) [RHEL-190549]
- src: reject large raw payload and concat expressions (Phil Sutter) [RHEL-190549]
- evaluate: exthdr: statement arg must be not be a range (Phil Sutter) [RHEL-190549]
- meta: fix tc classid parsing out-of-bounds access (Phil Sutter) [RHEL-190549]
- parser_bison: close chain scope before chain release (Phil Sutter) [RHEL-190549]
- evaluate: fix bogus assertion failure with boolean datatype (Phil Sutter) [RHEL-190549]
- parser_bison: fix objref statement corruption (Phil Sutter) [RHEL-190549]
- tests: py: missing json output in meta.t with vlan mapping (Phil Sutter) [RHEL-190549]
- evaluate: reset statement length context before evaluating statement (Phil Sutter) [RHEL-190549]
- parser: tcpopt: fix tcp option parsing with NUM + length field (Phil Sutter) [RHEL-190549]
- evaluate: reject set definition with no key (Phil Sutter) [RHEL-190549]
- monitor: add support for concatenated set ranges (Phil Sutter) [RHEL-190549]
- evaluate: disable meta set with ranges (Phil Sutter) [RHEL-190549]
- evaluate: prevent assert when evaluating very large shift values (Phil Sutter) [RHEL-190549]
- evaluate: reject sets with no key (Phil Sutter) [RHEL-190549]
- evaluate: clone unary expression datatype to deal with dynamic datatype (Phil Sutter) [RHEL-190549]
- tests: shell: split nat inet tests (Phil Sutter) [RHEL-190549]
- evaluate: bogus error when adding devices to flowtable (Phil Sutter) [RHEL-190549]
- tests: shell: flush connlimit sets (Phil Sutter) [RHEL-190549]
- tests: shell: adjust add-after-delete flowtable for older kernels (Phil Sutter) [RHEL-190549]
- evaluate: fix rule replacement with anon sets (Phil Sutter) [RHEL-190549]
- tests: shell: skip if kernel does not support flowtable counter (Phil Sutter) [RHEL-190549]
- tests: shell: restore pipapo and chain binding coverage in standalone 30s-stress (Phil Sutter) [RHEL-190549]
- json: fix use after free in table_flags_json() (Phil Sutter) [RHEL-190549]
- src: expand create commands (Phil Sutter) [RHEL-190549]
- tests: shell: split set NAT interval test (Phil Sutter) [RHEL-190549]
- tests: shell: split merge nat optimization in two tests (Phil Sutter) [RHEL-190549]
- netlink: fix buffer size for user data in netlink_delinearize_chain() (Phil Sutter) [RHEL-190549]
- src: remove xfree() and use plain free() (Phil Sutter) [RHEL-190549]
- src: add free_const() and use it instead of xfree() (Phil Sutter) [RHEL-190549]
- evaluate: place byteorder conversion before rshift in payload expressions (Phil Sutter) [RHEL-190549]
- evaluate: reset statement length context only for set mappings (Phil Sutter) [RHEL-190549]
- meta: fix hour decoding when timezone offset is negative (Phil Sutter) [RHEL-190549]
- tproxy: Drop artificial port printing restriction (Phil Sutter) [RHEL-190549]
- tests/shell: fix mount command in "test-wrapper.sh" (Phil Sutter) [RHEL-190549]
- parser_bison: fix length check for ifname in ifname_expr_alloc() (Phil Sutter) [RHEL-190549]
- tests/shell: cover long interface name in "0042chain_variable_0" test (Phil Sutter) [RHEL-190549]
- tests/shell: add missing "elem_opts_compat_0.nodump" file (Phil Sutter) [RHEL-190549]
- parser_bison: Fix for broken compatibility with older dumps (Phil Sutter) [RHEL-190549]
Resolves: RHEL-190549
1046 lines
36 KiB
Diff
1046 lines
36 KiB
Diff
From 37ff6f9a918095db3ece832effcec42a66f5e77a Mon Sep 17 00:00:00 2001
|
||
From: Phil Sutter <psutter@redhat.com>
|
||
Date: Fri, 17 Jul 2026 11:14:04 +0200
|
||
Subject: [PATCH] json: work around fuzzer-induced assert crashes
|
||
|
||
JIRA: https://issues.redhat.com/browse/RHEL-190549
|
||
Upstream Status: nftables commit 18c24d89b9977ddc0900be64fe9e95e7ac1ce896
|
||
|
||
commit 18c24d89b9977ddc0900be64fe9e95e7ac1ce896
|
||
Author: Florian Westphal <fw@strlen.de>
|
||
Date: Mon Mar 31 16:47:11 2025 +0200
|
||
|
||
json: work around fuzzer-induced assert crashes
|
||
|
||
fuzzer can cause assert failures due to json_pack() returning a NULL
|
||
value and therefore triggering the assert(out) in __json_pack macro.
|
||
|
||
All instances I saw are due to invalid UTF-8 strings, i.e., table/chain
|
||
names with non-text characters in them.
|
||
|
||
Work around this for now, replace the assert with a plaintext error
|
||
message and return NULL instead of abort().
|
||
|
||
Signed-off-by: Florian Westphal <fw@strlen.de>
|
||
|
||
Signed-off-by: Phil Sutter <psutter@redhat.com>
|
||
---
|
||
src/json.c | 271 +++++++++---------
|
||
.../nft-j-f/Assertion__out_failed_assert | 6 +
|
||
2 files changed, 146 insertions(+), 131 deletions(-)
|
||
create mode 100644 tests/shell/testcases/bogons/nft-j-f/Assertion__out_failed_assert
|
||
|
||
diff --git a/src/json.c b/src/json.c
|
||
index bbea9aa..65fbbfa 100644
|
||
--- a/src/json.c
|
||
+++ b/src/json.c
|
||
@@ -33,14 +33,23 @@
|
||
#include <jansson.h>
|
||
#include <syslog.h>
|
||
|
||
-#ifdef DEBUG
|
||
-#define __json_pack json_pack
|
||
-#define json_pack(...) ({ \
|
||
- json_t *__out = __json_pack(__VA_ARGS__); \
|
||
- assert(__out); \
|
||
- __out; \
|
||
-})
|
||
-#endif
|
||
+static json_t *__nft_json_pack(unsigned int line, const char *fmt, ...)
|
||
+{
|
||
+ json_error_t error;
|
||
+ json_t *value;
|
||
+ va_list ap;
|
||
+
|
||
+ va_start(ap, fmt);
|
||
+ value = json_vpack_ex(&error, 0, fmt, ap);
|
||
+ va_end(ap);
|
||
+
|
||
+ if (value)
|
||
+ return value;
|
||
+
|
||
+ fprintf(stderr, "%s:%d: json_pack failure (%s)\n", __FILE__, line, error.text);
|
||
+ return NULL;
|
||
+}
|
||
+#define nft_json_pack(...) __nft_json_pack(__LINE__, __VA_ARGS__)
|
||
|
||
static int json_array_extend_new(json_t *array, json_t *other_array)
|
||
{
|
||
@@ -84,7 +93,7 @@ static json_t *expr_print_json(const struct expr *expr, struct output_ctx *octx)
|
||
fclose(octx->output_fp);
|
||
octx->output_fp = fp;
|
||
|
||
- return json_pack("s", buf);
|
||
+ return nft_json_pack("s", buf);
|
||
}
|
||
|
||
static json_t *set_dtype_json(const struct expr *key)
|
||
@@ -99,7 +108,7 @@ static json_t *set_dtype_json(const struct expr *key)
|
||
if (!root)
|
||
root = jtok;
|
||
else if (json_is_string(root))
|
||
- root = json_pack("[o, o]", root, jtok);
|
||
+ root = nft_json_pack("[o, o]", root, jtok);
|
||
else
|
||
json_array_append_new(root, jtok);
|
||
tok = strtok_r(NULL, " .", &tok_safe);
|
||
@@ -116,7 +125,7 @@ static json_t *set_key_dtype_json(const struct set *set,
|
||
if (!use_typeof)
|
||
return set_dtype_json(set->key);
|
||
|
||
- return json_pack("{s:o}", "typeof", expr_print_json(set->key, octx));
|
||
+ return nft_json_pack("{s:o}", "typeof", expr_print_json(set->key, octx));
|
||
}
|
||
|
||
static json_t *stmt_print_json(const struct stmt *stmt, struct output_ctx *octx)
|
||
@@ -138,7 +147,7 @@ static json_t *stmt_print_json(const struct stmt *stmt, struct output_ctx *octx)
|
||
fclose(octx->output_fp);
|
||
octx->output_fp = fp;
|
||
|
||
- return json_pack("s", buf);
|
||
+ return nft_json_pack("s", buf);
|
||
}
|
||
|
||
static json_t *set_stmt_list_json(const struct list_head *stmt_list,
|
||
@@ -177,7 +186,7 @@ static json_t *set_print_json(struct output_ctx *octx, const struct set *set)
|
||
type = "set";
|
||
}
|
||
|
||
- root = json_pack("{s:s, s:s, s:s, s:o, s:I}",
|
||
+ root = nft_json_pack("{s:s, s:s, s:s, s:o, s:I}",
|
||
"family", family2str(set->handle.family),
|
||
"name", set->handle.set.name,
|
||
"table", set->handle.table.name,
|
||
@@ -191,24 +200,24 @@ static json_t *set_print_json(struct output_ctx *octx, const struct set *set)
|
||
|
||
if (!(set->flags & (NFT_SET_CONSTANT))) {
|
||
if (set->policy != NFT_SET_POL_PERFORMANCE) {
|
||
- tmp = json_pack("s", set_policy2str(set->policy));
|
||
+ tmp = nft_json_pack("s", set_policy2str(set->policy));
|
||
json_object_set_new(root, "policy", tmp);
|
||
}
|
||
if (set->desc.size) {
|
||
- tmp = json_pack("i", set->desc.size);
|
||
+ tmp = nft_json_pack("i", set->desc.size);
|
||
json_object_set_new(root, "size", tmp);
|
||
}
|
||
}
|
||
|
||
tmp = json_array();
|
||
if (set->flags & NFT_SET_CONSTANT)
|
||
- json_array_append_new(tmp, json_pack("s", "constant"));
|
||
+ json_array_append_new(tmp, nft_json_pack("s", "constant"));
|
||
if (set->flags & NFT_SET_INTERVAL)
|
||
- json_array_append_new(tmp, json_pack("s", "interval"));
|
||
+ json_array_append_new(tmp, nft_json_pack("s", "interval"));
|
||
if (set->flags & NFT_SET_TIMEOUT)
|
||
- json_array_append_new(tmp, json_pack("s", "timeout"));
|
||
+ json_array_append_new(tmp, nft_json_pack("s", "timeout"));
|
||
if (set->flags & NFT_SET_EVAL)
|
||
- json_array_append_new(tmp, json_pack("s", "dynamic"));
|
||
+ json_array_append_new(tmp, nft_json_pack("s", "dynamic"));
|
||
json_add_array_new(root, "flags", tmp);
|
||
|
||
if (set->timeout) {
|
||
@@ -216,7 +225,7 @@ static json_t *set_print_json(struct output_ctx *octx, const struct set *set)
|
||
json_object_set_new(root, "timeout", tmp);
|
||
}
|
||
if (set->gc_int) {
|
||
- tmp = json_pack("i", set->gc_int / 1000);
|
||
+ tmp = nft_json_pack("i", set->gc_int / 1000);
|
||
json_object_set_new(root, "gc-interval", tmp);
|
||
}
|
||
if (set->automerge)
|
||
@@ -237,7 +246,7 @@ static json_t *set_print_json(struct output_ctx *octx, const struct set *set)
|
||
set_stmt_list_json(&set->stmt_list, octx));
|
||
}
|
||
|
||
- return json_pack("{s:o}", type, root);
|
||
+ return nft_json_pack("{s:o}", type, root);
|
||
}
|
||
|
||
/* XXX: Merge with set_print_json()? */
|
||
@@ -246,7 +255,7 @@ static json_t *element_print_json(struct output_ctx *octx,
|
||
{
|
||
json_t *root = expr_print_json(set->init, octx);
|
||
|
||
- return json_pack("{s: {s:s, s:s, s:s, s:o}}", "element",
|
||
+ return nft_json_pack("{s: {s:s, s:s, s:s, s:o}}", "element",
|
||
"family", family2str(set->handle.family),
|
||
"table", set->handle.table.name,
|
||
"name", set->handle.set.name,
|
||
@@ -259,7 +268,7 @@ static json_t *rule_print_json(struct output_ctx *octx,
|
||
const struct stmt *stmt;
|
||
json_t *root, *tmp;
|
||
|
||
- root = json_pack("{s:s, s:s, s:s, s:I}",
|
||
+ root = nft_json_pack("{s:s, s:s, s:s, s:I}",
|
||
"family", family2str(rule->handle.family),
|
||
"table", rule->handle.table.name,
|
||
"chain", rule->handle.chain.name,
|
||
@@ -279,7 +288,7 @@ static json_t *rule_print_json(struct output_ctx *octx,
|
||
json_decref(tmp);
|
||
}
|
||
|
||
- return json_pack("{s:o}", "rule", root);
|
||
+ return nft_json_pack("{s:o}", "rule", root);
|
||
}
|
||
|
||
static json_t *chain_print_json(const struct chain *chain)
|
||
@@ -287,7 +296,7 @@ static json_t *chain_print_json(const struct chain *chain)
|
||
json_t *root, *tmp, *devs = NULL;
|
||
int priority, policy, i;
|
||
|
||
- root = json_pack("{s:s, s:s, s:s, s:I}",
|
||
+ root = nft_json_pack("{s:s, s:s, s:s, s:I}",
|
||
"family", family2str(chain->handle.family),
|
||
"table", chain->handle.table.name,
|
||
"name", chain->handle.chain.name,
|
||
@@ -307,7 +316,7 @@ static json_t *chain_print_json(const struct chain *chain)
|
||
policy = NF_ACCEPT;
|
||
}
|
||
|
||
- tmp = json_pack("{s:s, s:s, s:i, s:s}",
|
||
+ tmp = nft_json_pack("{s:s, s:s, s:i, s:s}",
|
||
"type", chain->type.str,
|
||
"hook", hooknum2str(chain->handle.family,
|
||
chain->hook.num),
|
||
@@ -319,7 +328,7 @@ static json_t *chain_print_json(const struct chain *chain)
|
||
if (!devs)
|
||
devs = json_string(dev);
|
||
else if (json_is_string(devs))
|
||
- devs = json_pack("[o, s]", devs, dev);
|
||
+ devs = nft_json_pack("[o, s]", devs, dev);
|
||
else
|
||
json_array_append_new(devs, json_string(dev));
|
||
}
|
||
@@ -330,7 +339,7 @@ static json_t *chain_print_json(const struct chain *chain)
|
||
json_decref(tmp);
|
||
}
|
||
|
||
- return json_pack("{s:o}", "chain", root);
|
||
+ return nft_json_pack("{s:o}", "chain", root);
|
||
}
|
||
|
||
static json_t *proto_name_json(uint8_t proto)
|
||
@@ -366,28 +375,28 @@ static json_t *obj_print_json(const struct obj *obj)
|
||
json_t *root, *tmp, *flags;
|
||
uint64_t rate, burst;
|
||
|
||
- root = json_pack("{s:s, s:s, s:s, s:I}",
|
||
+ root = nft_json_pack("{s:s, s:s, s:s, s:I}",
|
||
"family", family2str(obj->handle.family),
|
||
"name", obj->handle.obj.name,
|
||
"table", obj->handle.table.name,
|
||
"handle", obj->handle.handle.id);
|
||
|
||
if (obj->comment) {
|
||
- tmp = json_pack("{s:s}", "comment", obj->comment);
|
||
+ tmp = nft_json_pack("{s:s}", "comment", obj->comment);
|
||
json_object_update(root, tmp);
|
||
json_decref(tmp);
|
||
}
|
||
|
||
switch (obj->type) {
|
||
case NFT_OBJECT_COUNTER:
|
||
- tmp = json_pack("{s:I, s:I}",
|
||
+ tmp = nft_json_pack("{s:I, s:I}",
|
||
"packets", obj->counter.packets,
|
||
"bytes", obj->counter.bytes);
|
||
json_object_update(root, tmp);
|
||
json_decref(tmp);
|
||
break;
|
||
case NFT_OBJECT_QUOTA:
|
||
- tmp = json_pack("{s:I, s:I, s:b}",
|
||
+ tmp = nft_json_pack("{s:I, s:I, s:b}",
|
||
"bytes", obj->quota.bytes,
|
||
"used", obj->quota.used,
|
||
"inv", obj->quota.flags & NFT_QUOTA_F_INV);
|
||
@@ -395,13 +404,13 @@ static json_t *obj_print_json(const struct obj *obj)
|
||
json_decref(tmp);
|
||
break;
|
||
case NFT_OBJECT_SECMARK:
|
||
- tmp = json_pack("{s:s}",
|
||
+ tmp = nft_json_pack("{s:s}",
|
||
"context", obj->secmark.ctx);
|
||
json_object_update(root, tmp);
|
||
json_decref(tmp);
|
||
break;
|
||
case NFT_OBJECT_CT_HELPER:
|
||
- tmp = json_pack("{s:s, s:o, s:s}",
|
||
+ tmp = nft_json_pack("{s:s, s:o, s:s}",
|
||
"type", obj->ct_helper.name, "protocol",
|
||
proto_name_json(obj->ct_helper.l4proto),
|
||
"l3proto", family2str(obj->ct_helper.l3proto));
|
||
@@ -411,7 +420,7 @@ static json_t *obj_print_json(const struct obj *obj)
|
||
case NFT_OBJECT_CT_TIMEOUT:
|
||
tmp = timeout_policy_json(obj->ct_timeout.l4proto,
|
||
obj->ct_timeout.timeout);
|
||
- tmp = json_pack("{s:o, s:s, s:o}",
|
||
+ tmp = nft_json_pack("{s:o, s:s, s:o}",
|
||
"protocol",
|
||
proto_name_json(obj->ct_timeout.l4proto),
|
||
"l3proto", family2str(obj->ct_timeout.l3proto),
|
||
@@ -420,7 +429,7 @@ static json_t *obj_print_json(const struct obj *obj)
|
||
json_decref(tmp);
|
||
break;
|
||
case NFT_OBJECT_CT_EXPECT:
|
||
- tmp = json_pack("{s:o, s:I, s:I, s:I, s:s}",
|
||
+ tmp = nft_json_pack("{s:o, s:I, s:I, s:I, s:s}",
|
||
"protocol",
|
||
proto_name_json(obj->ct_expect.l4proto),
|
||
"dport", obj->ct_expect.dport,
|
||
@@ -439,7 +448,7 @@ static json_t *obj_print_json(const struct obj *obj)
|
||
burst_unit = get_rate(obj->limit.burst, &burst);
|
||
}
|
||
|
||
- tmp = json_pack("{s:I, s:s}",
|
||
+ tmp = nft_json_pack("{s:I, s:s}",
|
||
"rate", rate,
|
||
"per", get_unit(obj->limit.unit));
|
||
|
||
@@ -459,9 +468,9 @@ static json_t *obj_print_json(const struct obj *obj)
|
||
json_decref(tmp);
|
||
break;
|
||
case NFT_OBJECT_SYNPROXY:
|
||
- tmp = json_pack("{s:i, s:i}",
|
||
- "mss", obj->synproxy.mss,
|
||
- "wscale", obj->synproxy.wscale);
|
||
+ tmp = nft_json_pack("{s:i, s:i}",
|
||
+ "mss", obj->synproxy.mss,
|
||
+ "wscale", obj->synproxy.wscale);
|
||
|
||
flags = json_array();
|
||
if (obj->synproxy.flags & NF_SYNPROXY_OPT_TIMESTAMP)
|
||
@@ -475,7 +484,7 @@ static json_t *obj_print_json(const struct obj *obj)
|
||
break;
|
||
}
|
||
|
||
- return json_pack("{s:o}", type, root);
|
||
+ return nft_json_pack("{s:o}", type, root);
|
||
}
|
||
|
||
static json_t *flowtable_print_json(const struct flowtable *ftable)
|
||
@@ -488,7 +497,7 @@ static json_t *flowtable_print_json(const struct flowtable *ftable)
|
||
BYTEORDER_HOST_ENDIAN, sizeof(int));
|
||
}
|
||
|
||
- root = json_pack("{s:s, s:s, s:s, s:I, s:s, s:i}",
|
||
+ root = nft_json_pack("{s:s, s:s, s:s, s:I, s:s, s:i}",
|
||
"family", family2str(ftable->handle.family),
|
||
"name", ftable->handle.flowtable.name,
|
||
"table", ftable->handle.table.name,
|
||
@@ -501,14 +510,14 @@ static json_t *flowtable_print_json(const struct flowtable *ftable)
|
||
if (!devs)
|
||
devs = json_string(dev);
|
||
else if (json_is_string(devs))
|
||
- devs = json_pack("[o, s]", devs, dev);
|
||
+ devs = nft_json_pack("[o, s]", devs, dev);
|
||
else
|
||
json_array_append_new(devs, json_string(dev));
|
||
}
|
||
if (devs)
|
||
json_object_set_new(root, "dev", devs);
|
||
|
||
- return json_pack("{s:o}", "flowtable", root);
|
||
+ return nft_json_pack("{s:o}", "flowtable", root);
|
||
}
|
||
|
||
static json_t *table_flags_json(const struct table *table)
|
||
@@ -532,7 +541,7 @@ static json_t *table_print_json(const struct table *table)
|
||
{
|
||
json_t *root;
|
||
|
||
- root = json_pack("{s:s, s:s, s:I}",
|
||
+ root = nft_json_pack("{s:s, s:s, s:I}",
|
||
"family", family2str(table->handle.family),
|
||
"name", table->handle.table.name,
|
||
"handle", table->handle.handle.id);
|
||
@@ -541,7 +550,7 @@ static json_t *table_print_json(const struct table *table)
|
||
if (table->comment)
|
||
json_object_set_new(root, "comment", json_string(table->comment));
|
||
|
||
- return json_pack("{s:o}", "table", root);
|
||
+ return nft_json_pack("{s:o}", "table", root);
|
||
}
|
||
|
||
json_t *flagcmp_expr_json(const struct expr *expr, struct output_ctx *octx)
|
||
@@ -576,13 +585,13 @@ __binop_expr_json(int op, const struct expr *expr, struct output_ctx *octx)
|
||
|
||
json_t *binop_expr_json(const struct expr *expr, struct output_ctx *octx)
|
||
{
|
||
- return json_pack("{s:o}", expr_op_symbols[expr->op],
|
||
+ return nft_json_pack("{s:o}", expr_op_symbols[expr->op],
|
||
__binop_expr_json(expr->op, expr, octx));
|
||
}
|
||
|
||
json_t *relational_expr_json(const struct expr *expr, struct output_ctx *octx)
|
||
{
|
||
- return json_pack("{s:{s:s, s:o, s:o}}", "match",
|
||
+ return nft_json_pack("{s:{s:s, s:o, s:o}}", "match",
|
||
"op", expr_op_symbols[expr->op] ? : "in",
|
||
"left", expr_print_json(expr->left, octx),
|
||
"right", expr_print_json(expr->right, octx));
|
||
@@ -595,7 +604,7 @@ json_t *range_expr_json(const struct expr *expr, struct output_ctx *octx)
|
||
|
||
octx->flags &= ~NFT_CTX_OUTPUT_SERVICE;
|
||
octx->flags |= NFT_CTX_OUTPUT_NUMERIC_PROTO;
|
||
- root = json_pack("{s:[o, o]}", "range",
|
||
+ root = nft_json_pack("{s:[o, o]}", "range",
|
||
expr_print_json(expr->left, octx),
|
||
expr_print_json(expr->right, octx));
|
||
octx->flags = flags;
|
||
@@ -605,7 +614,7 @@ json_t *range_expr_json(const struct expr *expr, struct output_ctx *octx)
|
||
|
||
json_t *meta_expr_json(const struct expr *expr, struct output_ctx *octx)
|
||
{
|
||
- return json_pack("{s:{s:s}}", "meta",
|
||
+ return nft_json_pack("{s:{s:s}}", "meta",
|
||
"key", meta_templates[expr->meta.key].token);
|
||
}
|
||
|
||
@@ -615,23 +624,23 @@ json_t *payload_expr_json(const struct expr *expr, struct output_ctx *octx)
|
||
|
||
if (payload_is_known(expr)) {
|
||
if (expr->payload.inner_desc) {
|
||
- root = json_pack("{s:s, s:s, s:s}",
|
||
+ root = nft_json_pack("{s:s, s:s, s:s}",
|
||
"tunnel", expr->payload.inner_desc->name,
|
||
"protocol", expr->payload.desc->name,
|
||
"field", expr->payload.tmpl->token);
|
||
} else {
|
||
- root = json_pack("{s:s, s:s}",
|
||
+ root = nft_json_pack("{s:s, s:s}",
|
||
"protocol", expr->payload.desc->name,
|
||
"field", expr->payload.tmpl->token);
|
||
}
|
||
} else {
|
||
- root = json_pack("{s:s, s:i, s:i}",
|
||
+ root = nft_json_pack("{s:s, s:i, s:i}",
|
||
"base", proto_base_tokens[expr->payload.base],
|
||
"offset", expr->payload.offset,
|
||
"len", expr->len);
|
||
}
|
||
|
||
- return json_pack("{s:o}", "payload", root);
|
||
+ return nft_json_pack("{s:o}", "payload", root);
|
||
}
|
||
|
||
json_t *ct_expr_json(const struct expr *expr, struct output_ctx *octx)
|
||
@@ -640,7 +649,7 @@ json_t *ct_expr_json(const struct expr *expr, struct output_ctx *octx)
|
||
enum nft_ct_keys key = expr->ct.key;
|
||
json_t *root;
|
||
|
||
- root = json_pack("{s:s}", "key", ct_templates[key].token);
|
||
+ root = nft_json_pack("{s:s}", "key", ct_templates[key].token);
|
||
|
||
if (expr->ct.direction < 0)
|
||
goto out;
|
||
@@ -648,7 +657,7 @@ json_t *ct_expr_json(const struct expr *expr, struct output_ctx *octx)
|
||
if (dirstr)
|
||
json_object_set_new(root, "dir", json_string(dirstr));
|
||
out:
|
||
- return json_pack("{s:o}", "ct", root);
|
||
+ return nft_json_pack("{s:o}", "ct", root);
|
||
}
|
||
|
||
json_t *concat_expr_json(const struct expr *expr, struct output_ctx *octx)
|
||
@@ -659,7 +668,7 @@ json_t *concat_expr_json(const struct expr *expr, struct output_ctx *octx)
|
||
list_for_each_entry(i, &expr->expressions, list)
|
||
json_array_append_new(array, expr_print_json(i, octx));
|
||
|
||
- return json_pack("{s:o}", "concat", array);
|
||
+ return nft_json_pack("{s:o}", "concat", array);
|
||
}
|
||
|
||
json_t *set_expr_json(const struct expr *expr, struct output_ctx *octx)
|
||
@@ -670,7 +679,7 @@ json_t *set_expr_json(const struct expr *expr, struct output_ctx *octx)
|
||
list_for_each_entry(i, &expr->expressions, list)
|
||
json_array_append_new(array, expr_print_json(i, octx));
|
||
|
||
- return json_pack("{s:o}", "set", array);
|
||
+ return nft_json_pack("{s:o}", "set", array);
|
||
}
|
||
|
||
json_t *set_ref_expr_json(const struct expr *expr, struct output_ctx *octx)
|
||
@@ -678,7 +687,7 @@ json_t *set_ref_expr_json(const struct expr *expr, struct output_ctx *octx)
|
||
if (set_is_anonymous(expr->set->flags)) {
|
||
return expr_print_json(expr->set->init, octx);
|
||
} else {
|
||
- return json_pack("s+", "@", expr->set->handle.set.name);
|
||
+ return nft_json_pack("s+", "@", expr->set->handle.set.name);
|
||
}
|
||
}
|
||
|
||
@@ -694,7 +703,7 @@ json_t *set_elem_expr_json(const struct expr *expr, struct output_ctx *octx)
|
||
/* these element attributes require formal set elem syntax */
|
||
if (expr->timeout || expr->expiration || expr->comment ||
|
||
!list_empty(&expr->stmt_list)) {
|
||
- root = json_pack("{s:o}", "val", root);
|
||
+ root = nft_json_pack("{s:o}", "val", root);
|
||
|
||
if (expr->timeout) {
|
||
tmp = json_integer(expr->timeout / 1000);
|
||
@@ -716,7 +725,7 @@ json_t *set_elem_expr_json(const struct expr *expr, struct output_ctx *octx)
|
||
/* TODO: only one statement per element. */
|
||
break;
|
||
}
|
||
- return json_pack("{s:o}", "elem", root);
|
||
+ return nft_json_pack("{s:o}", "elem", root);
|
||
}
|
||
|
||
return root;
|
||
@@ -726,7 +735,7 @@ json_t *prefix_expr_json(const struct expr *expr, struct output_ctx *octx)
|
||
{
|
||
json_t *root = expr_print_json(expr->prefix, octx);
|
||
|
||
- return json_pack("{s:{s:o, s:i}}", "prefix",
|
||
+ return nft_json_pack("{s:{s:o, s:i}}", "prefix",
|
||
"addr", root,
|
||
"len", expr->prefix_len);
|
||
}
|
||
@@ -739,7 +748,7 @@ json_t *list_expr_json(const struct expr *expr, struct output_ctx *octx)
|
||
list_for_each_entry(i, &expr->expressions, list)
|
||
json_array_append_new(array, expr_print_json(i, octx));
|
||
|
||
- //return json_pack("{s:s, s:o}", "type", "list", "val", array);
|
||
+ //return nft_json_pack("{s:s, s:o}", "type", "list", "val", array);
|
||
return array;
|
||
}
|
||
|
||
@@ -750,7 +759,7 @@ json_t *unary_expr_json(const struct expr *expr, struct output_ctx *octx)
|
||
|
||
json_t *mapping_expr_json(const struct expr *expr, struct output_ctx *octx)
|
||
{
|
||
- return json_pack("[o, o]",
|
||
+ return nft_json_pack("[o, o]",
|
||
expr_print_json(expr->left, octx),
|
||
expr_print_json(expr->right, octx));
|
||
}
|
||
@@ -763,7 +772,7 @@ json_t *map_expr_json(const struct expr *expr, struct output_ctx *octx)
|
||
expr->mappings->set->data->dtype->type == TYPE_VERDICT)
|
||
type = "vmap";
|
||
|
||
- return json_pack("{s:{s:o, s:o}}", type,
|
||
+ return nft_json_pack("{s:{s:o, s:o}}", type,
|
||
"key", expr_print_json(expr->map, octx),
|
||
"data", expr_print_json(expr->mappings, octx));
|
||
}
|
||
@@ -785,36 +794,36 @@ json_t *exthdr_expr_json(const struct expr *expr, struct output_ctx *octx)
|
||
if (offset < 4)
|
||
offstr = offstrs[offset];
|
||
|
||
- root = json_pack("{s:s+}", "name", desc, offstr);
|
||
+ root = nft_json_pack("{s:s+}", "name", desc, offstr);
|
||
|
||
if (!is_exists)
|
||
json_object_set_new(root, "field", json_string(field));
|
||
} else {
|
||
- root = json_pack("{s:i, s:i, s:i}",
|
||
+ root = nft_json_pack("{s:i, s:i, s:i}",
|
||
"base", expr->exthdr.raw_type,
|
||
"offset", expr->exthdr.offset,
|
||
"len", expr->len);
|
||
}
|
||
|
||
- return json_pack("{s:o}", "tcp option", root);
|
||
+ return nft_json_pack("{s:o}", "tcp option", root);
|
||
}
|
||
|
||
if (expr->exthdr.op == NFT_EXTHDR_OP_DCCP) {
|
||
- root = json_pack("{s:i}", "type", expr->exthdr.raw_type);
|
||
- return json_pack("{s:o}", "dccp option", root);
|
||
+ root = nft_json_pack("{s:i}", "type", expr->exthdr.raw_type);
|
||
+ return nft_json_pack("{s:o}", "dccp option", root);
|
||
}
|
||
|
||
- root = json_pack("{s:s}", "name", desc);
|
||
+ root = nft_json_pack("{s:s}", "name", desc);
|
||
if (!is_exists)
|
||
json_object_set_new(root, "field", json_string(field));
|
||
|
||
switch (expr->exthdr.op) {
|
||
case NFT_EXTHDR_OP_IPV4:
|
||
- return json_pack("{s:o}", "ip option", root);
|
||
+ return nft_json_pack("{s:o}", "ip option", root);
|
||
case NFT_EXTHDR_OP_SCTP:
|
||
- return json_pack("{s:o}", "sctp chunk", root);
|
||
+ return nft_json_pack("{s:o}", "sctp chunk", root);
|
||
default:
|
||
- return json_pack("{s:o}", "exthdr", root);
|
||
+ return nft_json_pack("{s:o}", "exthdr", root);
|
||
}
|
||
}
|
||
|
||
@@ -851,15 +860,15 @@ json_t *verdict_expr_json(const struct expr *expr, struct output_ctx *octx)
|
||
return NULL;
|
||
}
|
||
if (chain)
|
||
- return json_pack("{s:{s:o}}", name, "target", chain);
|
||
+ return nft_json_pack("{s:{s:o}}", name, "target", chain);
|
||
else
|
||
- return json_pack("{s:n}", name);
|
||
+ return nft_json_pack("{s:n}", name);
|
||
}
|
||
|
||
json_t *rt_expr_json(const struct expr *expr, struct output_ctx *octx)
|
||
{
|
||
const char *key = rt_templates[expr->rt.key].token;
|
||
- json_t *root = json_pack("{s:s}", "key", key);
|
||
+ json_t *root = nft_json_pack("{s:s}", "key", key);
|
||
const char *family = NULL;
|
||
|
||
switch (expr->rt.key) {
|
||
@@ -876,7 +885,7 @@ json_t *rt_expr_json(const struct expr *expr, struct output_ctx *octx)
|
||
if (family)
|
||
json_object_set_new(root, "family", json_string(family));
|
||
|
||
- return json_pack("{s:o}", "rt", root);
|
||
+ return nft_json_pack("{s:o}", "rt", root);
|
||
}
|
||
|
||
json_t *numgen_expr_json(const struct expr *expr, struct output_ctx *octx)
|
||
@@ -895,7 +904,7 @@ json_t *numgen_expr_json(const struct expr *expr, struct output_ctx *octx)
|
||
break;
|
||
}
|
||
|
||
- return json_pack("{s:{s:s, s:i, s:i}}", "numgen",
|
||
+ return nft_json_pack("{s:{s:s, s:i, s:i}}", "numgen",
|
||
"mode", mode,
|
||
"mod", expr->numgen.mod,
|
||
"offset", expr->numgen.offset);
|
||
@@ -917,7 +926,7 @@ json_t *hash_expr_json(const struct expr *expr, struct output_ctx *octx)
|
||
break;
|
||
}
|
||
|
||
- root = json_pack("{s:i}", "mod", expr->hash.mod);
|
||
+ root = nft_json_pack("{s:i}", "mod", expr->hash.mod);
|
||
if (expr->hash.seed_set)
|
||
json_object_set_new(root, "seed",
|
||
json_integer(expr->hash.seed));
|
||
@@ -927,7 +936,7 @@ json_t *hash_expr_json(const struct expr *expr, struct output_ctx *octx)
|
||
if (jexpr)
|
||
json_object_set_new(root, "expr", jexpr);
|
||
|
||
- return json_pack("{s:o}", type, root);
|
||
+ return nft_json_pack("{s:o}", type, root);
|
||
}
|
||
|
||
json_t *fib_expr_json(const struct expr *expr, struct output_ctx *octx)
|
||
@@ -936,7 +945,7 @@ json_t *fib_expr_json(const struct expr *expr, struct output_ctx *octx)
|
||
unsigned int flags = expr->fib.flags & ~NFTA_FIB_F_PRESENT;
|
||
json_t *root;
|
||
|
||
- root = json_pack("{s:s}", "result", fib_result_str(expr->fib.result));
|
||
+ root = nft_json_pack("{s:s}", "result", fib_result_str(expr->fib.result));
|
||
|
||
if (flags) {
|
||
json_t *tmp = json_array();
|
||
@@ -953,7 +962,7 @@ json_t *fib_expr_json(const struct expr *expr, struct output_ctx *octx)
|
||
|
||
json_add_array_new(root, "flags", tmp);
|
||
}
|
||
- return json_pack("{s:o}", "fib", root);
|
||
+ return nft_json_pack("{s:o}", "fib", root);
|
||
}
|
||
|
||
static json_t *symbolic_constant_json(const struct symbol_table *tbl,
|
||
@@ -1026,7 +1035,7 @@ json_t *constant_expr_json(const struct expr *expr, struct output_ctx *octx)
|
||
|
||
json_t *socket_expr_json(const struct expr *expr, struct output_ctx *octx)
|
||
{
|
||
- return json_pack("{s:{s:s}}", "socket", "key",
|
||
+ return nft_json_pack("{s:{s:s}}", "socket", "key",
|
||
socket_templates[expr->socket.key].token);
|
||
}
|
||
|
||
@@ -1035,9 +1044,9 @@ json_t *osf_expr_json(const struct expr *expr, struct output_ctx *octx)
|
||
json_t *root;
|
||
|
||
if (expr->osf.flags & NFT_OSF_F_VERSION)
|
||
- root = json_pack("{s:s}", "key", "version");
|
||
+ root = nft_json_pack("{s:s}", "key", "version");
|
||
else
|
||
- root = json_pack("{s:s}", "key", "name");
|
||
+ root = nft_json_pack("{s:s}", "key", "name");
|
||
|
||
switch (expr->osf.ttl) {
|
||
case 1:
|
||
@@ -1048,7 +1057,7 @@ json_t *osf_expr_json(const struct expr *expr, struct output_ctx *octx)
|
||
break;
|
||
}
|
||
|
||
- return json_pack("{s:o}", "osf", root);
|
||
+ return nft_json_pack("{s:o}", "osf", root);
|
||
}
|
||
|
||
json_t *xfrm_expr_json(const struct expr *expr, struct output_ctx *octx)
|
||
@@ -1085,7 +1094,7 @@ json_t *xfrm_expr_json(const struct expr *expr, struct output_ctx *octx)
|
||
break;
|
||
}
|
||
|
||
- root = json_pack("{s:s}", "key", name);
|
||
+ root = nft_json_pack("{s:s}", "key", name);
|
||
|
||
if (family)
|
||
json_object_set_new(root, "family", json_string(family));
|
||
@@ -1093,7 +1102,7 @@ json_t *xfrm_expr_json(const struct expr *expr, struct output_ctx *octx)
|
||
json_object_set_new(root, "dir", json_string(dirstr));
|
||
json_object_set_new(root, "spnum", json_integer(expr->xfrm.spnum));
|
||
|
||
- return json_pack("{s:o}", "ipsec", root);
|
||
+ return nft_json_pack("{s:o}", "ipsec", root);
|
||
}
|
||
|
||
json_t *integer_type_json(const struct expr *expr, struct output_ctx *octx)
|
||
@@ -1215,21 +1224,21 @@ json_t *expr_stmt_json(const struct stmt *stmt, struct output_ctx *octx)
|
||
|
||
json_t *flow_offload_stmt_json(const struct stmt *stmt, struct output_ctx *octx)
|
||
{
|
||
- return json_pack("{s:{s:s, s:s+}}", "flow",
|
||
+ return nft_json_pack("{s:{s:s, s:s+}}", "flow",
|
||
"op", "add", "flowtable",
|
||
"@", stmt->flow.table_name);
|
||
}
|
||
|
||
json_t *payload_stmt_json(const struct stmt *stmt, struct output_ctx *octx)
|
||
{
|
||
- return json_pack("{s: {s:o, s:o}}", "mangle",
|
||
+ return nft_json_pack("{s: {s:o, s:o}}", "mangle",
|
||
"key", expr_print_json(stmt->payload.expr, octx),
|
||
"value", expr_print_json(stmt->payload.val, octx));
|
||
}
|
||
|
||
json_t *exthdr_stmt_json(const struct stmt *stmt, struct output_ctx *octx)
|
||
{
|
||
- return json_pack("{s: {s:o, s:o}}", "mangle",
|
||
+ return nft_json_pack("{s: {s:o, s:o}}", "mangle",
|
||
"key", expr_print_json(stmt->exthdr.expr, octx),
|
||
"value", expr_print_json(stmt->exthdr.val, octx));
|
||
}
|
||
@@ -1241,7 +1250,7 @@ json_t *quota_stmt_json(const struct stmt *stmt, struct output_ctx *octx)
|
||
json_t *root;
|
||
|
||
data_unit = get_rate(stmt->quota.bytes, &bytes);
|
||
- root = json_pack("{s:I, s:s}",
|
||
+ root = nft_json_pack("{s:I, s:s}",
|
||
"val", bytes,
|
||
"val_unit", data_unit);
|
||
|
||
@@ -1253,7 +1262,7 @@ json_t *quota_stmt_json(const struct stmt *stmt, struct output_ctx *octx)
|
||
json_object_set_new(root, "used_unit", json_string(data_unit));
|
||
}
|
||
|
||
- return json_pack("{s:o}", "quota", root);
|
||
+ return nft_json_pack("{s:o}", "quota", root);
|
||
}
|
||
|
||
json_t *ct_stmt_json(const struct stmt *stmt, struct output_ctx *octx)
|
||
@@ -1266,7 +1275,7 @@ json_t *ct_stmt_json(const struct stmt *stmt, struct output_ctx *octx)
|
||
},
|
||
};
|
||
|
||
- return json_pack("{s:{s:o, s:o}}", "mangle",
|
||
+ return nft_json_pack("{s:{s:o, s:o}}", "mangle",
|
||
"key", ct_expr_json(&expr, octx),
|
||
"value", expr_print_json(stmt->ct.expr, octx));
|
||
}
|
||
@@ -1284,7 +1293,7 @@ json_t *limit_stmt_json(const struct stmt *stmt, struct output_ctx *octx)
|
||
burst_unit = get_rate(stmt->limit.burst, &burst);
|
||
}
|
||
|
||
- root = json_pack("{s:I, s:I, s:s}",
|
||
+ root = nft_json_pack("{s:I, s:I, s:s}",
|
||
"rate", rate,
|
||
"burst", burst,
|
||
"per", get_unit(stmt->limit.unit));
|
||
@@ -1296,14 +1305,14 @@ json_t *limit_stmt_json(const struct stmt *stmt, struct output_ctx *octx)
|
||
json_object_set_new(root, "burst_unit",
|
||
json_string(burst_unit));
|
||
|
||
- return json_pack("{s:o}", "limit", root);
|
||
+ return nft_json_pack("{s:o}", "limit", root);
|
||
}
|
||
|
||
json_t *fwd_stmt_json(const struct stmt *stmt, struct output_ctx *octx)
|
||
{
|
||
json_t *root, *tmp;
|
||
|
||
- root = json_pack("{s:o}", "dev", expr_print_json(stmt->fwd.dev, octx));
|
||
+ root = nft_json_pack("{s:o}", "dev", expr_print_json(stmt->fwd.dev, octx));
|
||
|
||
if (stmt->fwd.addr) {
|
||
tmp = json_string(family2str(stmt->fwd.family));
|
||
@@ -1313,12 +1322,12 @@ json_t *fwd_stmt_json(const struct stmt *stmt, struct output_ctx *octx)
|
||
json_object_set_new(root, "addr", tmp);
|
||
}
|
||
|
||
- return json_pack("{s:o}", "fwd", root);
|
||
+ return nft_json_pack("{s:o}", "fwd", root);
|
||
}
|
||
|
||
json_t *notrack_stmt_json(const struct stmt *stmt, struct output_ctx *octx)
|
||
{
|
||
- return json_pack("{s:n}", "notrack");
|
||
+ return nft_json_pack("{s:n}", "notrack");
|
||
}
|
||
|
||
json_t *dup_stmt_json(const struct stmt *stmt, struct output_ctx *octx)
|
||
@@ -1326,27 +1335,27 @@ json_t *dup_stmt_json(const struct stmt *stmt, struct output_ctx *octx)
|
||
json_t *root;
|
||
|
||
if (stmt->dup.to) {
|
||
- root = json_pack("{s:o}", "addr", expr_print_json(stmt->dup.to, octx));
|
||
+ root = nft_json_pack("{s:o}", "addr", expr_print_json(stmt->dup.to, octx));
|
||
if (stmt->dup.dev)
|
||
json_object_set_new(root, "dev",
|
||
expr_print_json(stmt->dup.dev, octx));
|
||
} else {
|
||
root = json_null();
|
||
}
|
||
- return json_pack("{s:o}", "dup", root);
|
||
+ return nft_json_pack("{s:o}", "dup", root);
|
||
}
|
||
|
||
json_t *meta_stmt_json(const struct stmt *stmt, struct output_ctx *octx)
|
||
{
|
||
json_t *root;
|
||
|
||
- root = json_pack("{s:{s:s}}", "meta",
|
||
+ root = nft_json_pack("{s:{s:s}}", "meta",
|
||
"key", meta_templates[stmt->meta.key].token);
|
||
- root = json_pack("{s:o, s:o}",
|
||
+ root = nft_json_pack("{s:o, s:o}",
|
||
"key", root,
|
||
"value", expr_print_json(stmt->meta.expr, octx));
|
||
|
||
- return json_pack("{s:o}", "mangle", root);
|
||
+ return nft_json_pack("{s:o}", "mangle", root);
|
||
}
|
||
|
||
json_t *log_stmt_json(const struct stmt *stmt, struct output_ctx *octx)
|
||
@@ -1395,7 +1404,7 @@ json_t *log_stmt_json(const struct stmt *stmt, struct output_ctx *octx)
|
||
root = json_null();
|
||
}
|
||
|
||
- return json_pack("{s:o}", "log", root);
|
||
+ return nft_json_pack("{s:o}", "log", root);
|
||
}
|
||
|
||
static json_t *nat_flags_json(uint32_t flags)
|
||
@@ -1457,7 +1466,7 @@ json_t *nat_stmt_json(const struct stmt *stmt, struct output_ctx *octx)
|
||
root = json_null();
|
||
}
|
||
|
||
- return json_pack("{s:o}", nat_etype2str(stmt->nat.type), root);
|
||
+ return nft_json_pack("{s:o}", nat_etype2str(stmt->nat.type), root);
|
||
}
|
||
|
||
json_t *reject_stmt_json(const struct stmt *stmt, struct output_ctx *octx)
|
||
@@ -1487,7 +1496,7 @@ json_t *reject_stmt_json(const struct stmt *stmt, struct output_ctx *octx)
|
||
}
|
||
|
||
if (!type && !jexpr)
|
||
- return json_pack("{s:n}", "reject");
|
||
+ return nft_json_pack("{s:n}", "reject");
|
||
|
||
root = json_object();
|
||
if (type)
|
||
@@ -1495,15 +1504,15 @@ json_t *reject_stmt_json(const struct stmt *stmt, struct output_ctx *octx)
|
||
if (jexpr)
|
||
json_object_set_new(root, "expr", jexpr);
|
||
|
||
- return json_pack("{s:o}", "reject", root);
|
||
+ return nft_json_pack("{s:o}", "reject", root);
|
||
}
|
||
|
||
json_t *counter_stmt_json(const struct stmt *stmt, struct output_ctx *octx)
|
||
{
|
||
if (nft_output_stateless(octx))
|
||
- return json_pack("{s:n}", "counter");
|
||
+ return nft_json_pack("{s:n}", "counter");
|
||
|
||
- return json_pack("{s:{s:I, s:I}}", "counter",
|
||
+ return nft_json_pack("{s:{s:I, s:I}}", "counter",
|
||
"packets", stmt->counter.packets,
|
||
"bytes", stmt->counter.bytes);
|
||
}
|
||
@@ -1511,16 +1520,16 @@ json_t *counter_stmt_json(const struct stmt *stmt, struct output_ctx *octx)
|
||
json_t *last_stmt_json(const struct stmt *stmt, struct output_ctx *octx)
|
||
{
|
||
if (nft_output_stateless(octx) || stmt->last.set == 0)
|
||
- return json_pack("{s:n}", "last");
|
||
+ return nft_json_pack("{s:n}", "last");
|
||
|
||
- return json_pack("{s:{s:I}}", "last", "used", stmt->last.used);
|
||
+ return nft_json_pack("{s:{s:I}}", "last", "used", stmt->last.used);
|
||
}
|
||
|
||
json_t *set_stmt_json(const struct stmt *stmt, struct output_ctx *octx)
|
||
{
|
||
json_t *root;
|
||
|
||
- root = json_pack("{s:s, s:o, s:s+}",
|
||
+ root = nft_json_pack("{s:s, s:o, s:s+}",
|
||
"op", set_stmt_op_names[stmt->set.op],
|
||
"elem", expr_print_json(stmt->set.key, octx),
|
||
"set", "@", stmt->set.set->set->handle.set.name);
|
||
@@ -1531,14 +1540,14 @@ json_t *set_stmt_json(const struct stmt *stmt, struct output_ctx *octx)
|
||
octx));
|
||
}
|
||
|
||
- return json_pack("{s:o}", "set", root);
|
||
+ return nft_json_pack("{s:o}", "set", root);
|
||
}
|
||
|
||
json_t *map_stmt_json(const struct stmt *stmt, struct output_ctx *octx)
|
||
{
|
||
json_t *root;
|
||
|
||
- root = json_pack("{s:s, s:o, s:o, s:s+}",
|
||
+ root = nft_json_pack("{s:s, s:o, s:o, s:s+}",
|
||
"op", set_stmt_op_names[stmt->map.op],
|
||
"elem", expr_print_json(stmt->map.key, octx),
|
||
"data", expr_print_json(stmt->map.data, octx),
|
||
@@ -1550,7 +1559,7 @@ json_t *map_stmt_json(const struct stmt *stmt, struct output_ctx *octx)
|
||
octx));
|
||
}
|
||
|
||
- return json_pack("{s:o}", "map", root);
|
||
+ return nft_json_pack("{s:o}", "map", root);
|
||
}
|
||
|
||
json_t *objref_stmt_json(const struct stmt *stmt, struct output_ctx *octx)
|
||
@@ -1562,7 +1571,7 @@ json_t *objref_stmt_json(const struct stmt *stmt, struct output_ctx *octx)
|
||
else
|
||
name = objref_type_name(stmt->objref.type);
|
||
|
||
- return json_pack("{s:o}", name, expr_print_json(stmt->objref.expr, octx));
|
||
+ return nft_json_pack("{s:o}", name, expr_print_json(stmt->objref.expr, octx));
|
||
}
|
||
|
||
json_t *meter_stmt_json(const struct stmt *stmt, struct output_ctx *octx)
|
||
@@ -1574,7 +1583,7 @@ json_t *meter_stmt_json(const struct stmt *stmt, struct output_ctx *octx)
|
||
tmp = stmt_print_json(stmt->meter.stmt, octx);
|
||
octx->flags = flags;
|
||
|
||
- root = json_pack("{s:o, s:o, s:i}",
|
||
+ root = nft_json_pack("{s:o, s:o, s:i}",
|
||
"key", expr_print_json(stmt->meter.key, octx),
|
||
"stmt", tmp,
|
||
"size", stmt->meter.size);
|
||
@@ -1583,7 +1592,7 @@ json_t *meter_stmt_json(const struct stmt *stmt, struct output_ctx *octx)
|
||
json_object_set_new(root, "name", tmp);
|
||
}
|
||
|
||
- return json_pack("{s:o}", "meter", root);
|
||
+ return nft_json_pack("{s:o}", "meter", root);
|
||
}
|
||
|
||
json_t *queue_stmt_json(const struct stmt *stmt, struct output_ctx *octx)
|
||
@@ -1608,7 +1617,7 @@ json_t *queue_stmt_json(const struct stmt *stmt, struct output_ctx *octx)
|
||
root = json_null();
|
||
}
|
||
|
||
- return json_pack("{s:o}", "queue", root);
|
||
+ return nft_json_pack("{s:o}", "queue", root);
|
||
}
|
||
|
||
json_t *verdict_stmt_json(const struct stmt *stmt, struct output_ctx *octx)
|
||
@@ -1618,12 +1627,12 @@ json_t *verdict_stmt_json(const struct stmt *stmt, struct output_ctx *octx)
|
||
|
||
json_t *connlimit_stmt_json(const struct stmt *stmt, struct output_ctx *octx)
|
||
{
|
||
- json_t *root = json_pack("{s:i}", "val", stmt->connlimit.count);
|
||
+ json_t *root = nft_json_pack("{s:i}", "val", stmt->connlimit.count);
|
||
|
||
if (stmt->connlimit.flags & NFT_CONNLIMIT_F_INV)
|
||
json_object_set_new(root, "inv", json_true());
|
||
|
||
- return json_pack("{s:o}", "ct count", root);
|
||
+ return nft_json_pack("{s:o}", "ct count", root);
|
||
}
|
||
|
||
json_t *tproxy_stmt_json(const struct stmt *stmt, struct output_ctx *octx)
|
||
@@ -1646,7 +1655,7 @@ json_t *tproxy_stmt_json(const struct stmt *stmt, struct output_ctx *octx)
|
||
json_object_set_new(root, "port", tmp);
|
||
}
|
||
|
||
- return json_pack("{s:o}", "tproxy", root);
|
||
+ return nft_json_pack("{s:o}", "tproxy", root);
|
||
}
|
||
|
||
json_t *synproxy_stmt_json(const struct stmt *stmt, struct output_ctx *octx)
|
||
@@ -1671,12 +1680,12 @@ json_t *synproxy_stmt_json(const struct stmt *stmt, struct output_ctx *octx)
|
||
root = json_null();
|
||
}
|
||
|
||
- return json_pack("{s:o}", "synproxy", root);
|
||
+ return nft_json_pack("{s:o}", "synproxy", root);
|
||
}
|
||
|
||
json_t *optstrip_stmt_json(const struct stmt *stmt, struct output_ctx *octx)
|
||
{
|
||
- return json_pack("{s:o}", "reset",
|
||
+ return nft_json_pack("{s:o}", "reset",
|
||
expr_print_json(stmt->optstrip.expr, octx));
|
||
}
|
||
|
||
@@ -1688,7 +1697,7 @@ json_t *xt_stmt_json(const struct stmt *stmt, struct output_ctx *octx)
|
||
[NFT_XT_WATCHER] = "watcher",
|
||
};
|
||
|
||
- return json_pack("{s:{s:s, s:s}}", "xt",
|
||
+ return nft_json_pack("{s:{s:s, s:s}}", "xt",
|
||
"type", xt_typename[stmt->xt.type],
|
||
"name", stmt->xt.name);
|
||
}
|
||
@@ -1831,7 +1840,7 @@ static json_t *do_list_set_json(struct netlink_ctx *ctx,
|
||
return json_null();
|
||
}
|
||
|
||
- return json_pack("[o]", set_print_json(&ctx->nft->output, set));
|
||
+ return nft_json_pack("[o]", set_print_json(&ctx->nft->output, set));
|
||
}
|
||
|
||
static json_t *do_list_sets_json(struct netlink_ctx *ctx, struct cmd *cmd)
|
||
@@ -1929,7 +1938,7 @@ static json_t *do_list_flowtables_json(struct netlink_ctx *ctx, struct cmd *cmd)
|
||
|
||
static json_t *generate_json_metainfo(void)
|
||
{
|
||
- return json_pack("{s: {s:s, s:s, s:i}}", "metainfo",
|
||
+ return nft_json_pack("{s: {s:s, s:s, s:i}}", "metainfo",
|
||
"version", PACKAGE_VERSION,
|
||
"release_name", RELEASE_NAME,
|
||
"json_schema_version", JSON_SCHEMA_VERSION);
|
||
@@ -2042,7 +2051,7 @@ int do_command_list_json(struct netlink_ctx *ctx, struct cmd *cmd)
|
||
|
||
json_array_insert_new(root, 0, generate_json_metainfo());
|
||
|
||
- root = json_pack("{s:o}", "nftables", root);
|
||
+ root = nft_json_pack("{s:o}", "nftables", root);
|
||
json_dumpf(root, ctx->nft->output.output_fp, 0);
|
||
json_decref(root);
|
||
fprintf(ctx->nft->output.output_fp, "\n");
|
||
@@ -2055,7 +2064,7 @@ static void monitor_print_json(struct netlink_mon_handler *monh,
|
||
{
|
||
struct nft_ctx *nft = monh->ctx->nft;
|
||
|
||
- obj = json_pack("{s:o}", cmd, obj);
|
||
+ obj = nft_json_pack("{s:o}", cmd, obj);
|
||
if (nft_output_echo(&nft->output) && !nft->json_root) {
|
||
json_array_append_new(nft->json_echo, obj);
|
||
} else {
|
||
diff --git a/tests/shell/testcases/bogons/nft-j-f/Assertion__out_failed_assert b/tests/shell/testcases/bogons/nft-j-f/Assertion__out_failed_assert
|
||
new file mode 100644
|
||
index 0000000..f8ce089
|
||
--- /dev/null
|
||
+++ b/tests/shell/testcases/bogons/nft-j-f/Assertion__out_failed_assert
|
||
@@ -0,0 +1,6 @@
|
||
+table ip test-ip {
|
||
+ quota htquota { comment "t<>st5" 5 kbytes
|
||
+ }
|
||
+}
|
||
+list ruleset
|
||
+add rule t c counter
|