* 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
608 lines
17 KiB
Diff
608 lines
17 KiB
Diff
From cf8cedf79d49736dad61f01628a0cf738fefad26 Mon Sep 17 00:00:00 2001
|
||
From: Phil Sutter <psutter@redhat.com>
|
||
Date: Fri, 17 Jul 2026 11:09:42 +0200
|
||
Subject: [PATCH] src: add string preprocessor and use it for log prefix string
|
||
|
||
JIRA: https://issues.redhat.com/browse/RHEL-190549
|
||
Upstream Status: nftables commit 081bf5f0d7952a6e6ac0d23a365ccf1fd27010c0
|
||
Conflicts: Manually applied Makefile.am change due to missing commit
|
||
11e62138424ad ("build: no recursive make for "src/Makefile.am"")
|
||
|
||
commit 081bf5f0d7952a6e6ac0d23a365ccf1fd27010c0
|
||
Author: Pablo Neira Ayuso <pablo@netfilter.org>
|
||
Date: Tue Jun 18 14:26:31 2024 +0200
|
||
|
||
src: add string preprocessor and use it for log prefix string
|
||
|
||
Add a string preprocessor to identify and replace variables in a string.
|
||
Rework existing support to variables in log prefix strings to use it.
|
||
|
||
Fixes: e76bb3794018 ("src: allow for variables in the log prefix string")
|
||
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
||
|
||
Signed-off-by: Phil Sutter <psutter@redhat.com>
|
||
---
|
||
include/expression.h | 2 -
|
||
include/parser.h | 4 +
|
||
include/statement.h | 2 +-
|
||
src/Makefile.am | 1 +
|
||
src/evaluate.c | 45 +---------
|
||
src/expression.c | 9 --
|
||
src/json.c | 7 +-
|
||
src/netlink_delinearize.c | 6 +-
|
||
src/netlink_linearize.c | 7 +-
|
||
src/optimize.c | 6 +-
|
||
src/parser_bison.y | 126 ++--------------------------
|
||
src/parser_json.c | 4 +-
|
||
src/preprocess.c | 168 ++++++++++++++++++++++++++++++++++++++
|
||
src/statement.c | 10 +--
|
||
14 files changed, 198 insertions(+), 199 deletions(-)
|
||
create mode 100644 src/preprocess.c
|
||
|
||
diff --git a/include/expression.h b/include/expression.h
|
||
index 809089c..e143e71 100644
|
||
--- a/include/expression.h
|
||
+++ b/include/expression.h
|
||
@@ -414,8 +414,6 @@ extern const struct datatype *expr_basetype(const struct expr *expr);
|
||
extern void expr_set_type(struct expr *expr, const struct datatype *dtype,
|
||
enum byteorder byteorder);
|
||
|
||
-void expr_to_string(const struct expr *expr, char *string);
|
||
-
|
||
struct eval_ctx;
|
||
extern int expr_binary_error(struct list_head *msgs,
|
||
const struct expr *e1, const struct expr *e2,
|
||
diff --git a/include/parser.h b/include/parser.h
|
||
index f79a22f..576e5e4 100644
|
||
--- a/include/parser.h
|
||
+++ b/include/parser.h
|
||
@@ -112,4 +112,8 @@ extern void scanner_push_buffer(void *scanner,
|
||
|
||
extern void scanner_pop_start_cond(void *scanner, enum startcond_type sc);
|
||
|
||
+const char *str_preprocess(struct parser_state *state, struct location *loc,
|
||
+ struct scope *scope, const char *x,
|
||
+ struct error_record **rec);
|
||
+
|
||
#endif /* NFTABLES_PARSER_H */
|
||
diff --git a/include/statement.h b/include/statement.h
|
||
index 662f99d..9376911 100644
|
||
--- a/include/statement.h
|
||
+++ b/include/statement.h
|
||
@@ -90,7 +90,7 @@ enum {
|
||
};
|
||
|
||
struct log_stmt {
|
||
- struct expr *prefix;
|
||
+ const char *prefix;
|
||
unsigned int snaplen;
|
||
uint16_t group;
|
||
uint16_t qthreshold;
|
||
diff --git a/src/Makefile.am b/src/Makefile.am
|
||
index 63a4ef4..6d7bb89 100644
|
||
--- a/src/Makefile.am
|
||
+++ b/src/Makefile.am
|
||
@@ -75,6 +75,7 @@ libnftables_la_SOURCES = \
|
||
nfnl_osf.c \
|
||
tcpopt.c \
|
||
socket.c \
|
||
+ preprocess.c \
|
||
print.c \
|
||
sctp_chunk.c \
|
||
dccpopt.c \
|
||
diff --git a/src/evaluate.c b/src/evaluate.c
|
||
index 7f5b64b..c28f693 100644
|
||
--- a/src/evaluate.c
|
||
+++ b/src/evaluate.c
|
||
@@ -4292,49 +4292,12 @@ static int stmt_evaluate_queue(struct eval_ctx *ctx, struct stmt *stmt)
|
||
|
||
static int stmt_evaluate_log_prefix(struct eval_ctx *ctx, struct stmt *stmt)
|
||
{
|
||
- char tmp[NF_LOG_PREFIXLEN] = {};
|
||
- char prefix[NF_LOG_PREFIXLEN];
|
||
- size_t len = sizeof(prefix);
|
||
- size_t offset = 0;
|
||
- struct expr *expr;
|
||
-
|
||
- if (stmt->log.prefix->etype != EXPR_LIST) {
|
||
- if (stmt->log.prefix &&
|
||
- div_round_up(stmt->log.prefix->len, BITS_PER_BYTE) >= NF_LOG_PREFIXLEN)
|
||
- return expr_error(ctx->msgs, stmt->log.prefix, "log prefix is too long");
|
||
-
|
||
- return 0;
|
||
- }
|
||
-
|
||
- prefix[0] = '\0';
|
||
-
|
||
- list_for_each_entry(expr, &stmt->log.prefix->expressions, list) {
|
||
- int ret;
|
||
-
|
||
- switch (expr->etype) {
|
||
- case EXPR_VALUE:
|
||
- expr_to_string(expr, tmp);
|
||
- ret = snprintf(prefix + offset, len, "%s", tmp);
|
||
- break;
|
||
- case EXPR_VARIABLE:
|
||
- ret = snprintf(prefix + offset, len, "%s",
|
||
- expr->sym->expr->identifier);
|
||
- break;
|
||
- default:
|
||
- BUG("unknown expression type %s\n", expr_name(expr));
|
||
- break;
|
||
- }
|
||
- SNPRINTF_BUFFER_SIZE(ret, &len, &offset);
|
||
- }
|
||
+ unsigned int len = strlen(stmt->log.prefix);
|
||
|
||
- if (len == 0)
|
||
+ if (len >= NF_LOG_PREFIXLEN)
|
||
return stmt_error(ctx, stmt, "log prefix is too long");
|
||
-
|
||
- expr = constant_expr_alloc(&stmt->log.prefix->location, &string_type,
|
||
- BYTEORDER_HOST_ENDIAN,
|
||
- strlen(prefix) * BITS_PER_BYTE, prefix);
|
||
- expr_free(stmt->log.prefix);
|
||
- stmt->log.prefix = expr;
|
||
+ else if (len == 0)
|
||
+ return stmt_error(ctx, stmt, "log prefix must have a minimum length of 1 character");
|
||
|
||
return 0;
|
||
}
|
||
diff --git a/src/expression.c b/src/expression.c
|
||
index cb2573f..992f510 100644
|
||
--- a/src/expression.c
|
||
+++ b/src/expression.c
|
||
@@ -183,15 +183,6 @@ void expr_describe(const struct expr *expr, struct output_ctx *octx)
|
||
}
|
||
}
|
||
|
||
-void expr_to_string(const struct expr *expr, char *string)
|
||
-{
|
||
- int len = expr->len / BITS_PER_BYTE;
|
||
-
|
||
- assert(expr->dtype == &string_type);
|
||
-
|
||
- mpz_export_data(string, expr->value, BYTEORDER_HOST_ENDIAN, len);
|
||
-}
|
||
-
|
||
void expr_set_type(struct expr *expr, const struct datatype *dtype,
|
||
enum byteorder byteorder)
|
||
{
|
||
diff --git a/src/json.c b/src/json.c
|
||
index b3e1e4e..5faeb4d 100644
|
||
--- a/src/json.c
|
||
+++ b/src/json.c
|
||
@@ -1319,12 +1319,9 @@ json_t *log_stmt_json(const struct stmt *stmt, struct output_ctx *octx)
|
||
{
|
||
json_t *root = json_object(), *flags;
|
||
|
||
- if (stmt->log.flags & STMT_LOG_PREFIX) {
|
||
- char prefix[NF_LOG_PREFIXLEN] = {};
|
||
+ if (stmt->log.flags & STMT_LOG_PREFIX)
|
||
+ json_object_set_new(root, "prefix", json_string(stmt->log.prefix));
|
||
|
||
- expr_to_string(stmt->log.prefix, prefix);
|
||
- json_object_set_new(root, "prefix", json_string(prefix));
|
||
- }
|
||
if (stmt->log.flags & STMT_LOG_GROUP)
|
||
json_object_set_new(root, "group",
|
||
json_integer(stmt->log.group));
|
||
diff --git a/src/netlink_delinearize.c b/src/netlink_delinearize.c
|
||
index 1af0278..0ea10ee 100644
|
||
--- a/src/netlink_delinearize.c
|
||
+++ b/src/netlink_delinearize.c
|
||
@@ -1090,11 +1090,7 @@ static void netlink_parse_log(struct netlink_parse_ctx *ctx,
|
||
stmt = log_stmt_alloc(loc);
|
||
prefix = nftnl_expr_get_str(nle, NFTNL_EXPR_LOG_PREFIX);
|
||
if (nftnl_expr_is_set(nle, NFTNL_EXPR_LOG_PREFIX)) {
|
||
- stmt->log.prefix = constant_expr_alloc(&internal_location,
|
||
- &string_type,
|
||
- BYTEORDER_HOST_ENDIAN,
|
||
- (strlen(prefix) + 1) * BITS_PER_BYTE,
|
||
- prefix);
|
||
+ stmt->log.prefix = xstrdup(prefix);
|
||
stmt->log.flags |= STMT_LOG_PREFIX;
|
||
}
|
||
if (nftnl_expr_is_set(nle, NFTNL_EXPR_LOG_GROUP)) {
|
||
diff --git a/src/netlink_linearize.c b/src/netlink_linearize.c
|
||
index df395ba..a2a1cd5 100644
|
||
--- a/src/netlink_linearize.c
|
||
+++ b/src/netlink_linearize.c
|
||
@@ -1141,12 +1141,9 @@ static void netlink_gen_log_stmt(struct netlink_linearize_ctx *ctx,
|
||
struct nftnl_expr *nle;
|
||
|
||
nle = alloc_nft_expr("log");
|
||
- if (stmt->log.prefix != NULL) {
|
||
- char prefix[NF_LOG_PREFIXLEN] = {};
|
||
+ if (stmt->log.prefix != NULL)
|
||
+ nftnl_expr_set_str(nle, NFTNL_EXPR_LOG_PREFIX, stmt->log.prefix);
|
||
|
||
- expr_to_string(stmt->log.prefix, prefix);
|
||
- nftnl_expr_set_str(nle, NFTNL_EXPR_LOG_PREFIX, prefix);
|
||
- }
|
||
if (stmt->log.flags & STMT_LOG_GROUP) {
|
||
nftnl_expr_set_u16(nle, NFTNL_EXPR_LOG_GROUP, stmt->log.group);
|
||
if (stmt->log.flags & STMT_LOG_SNAPLEN)
|
||
diff --git a/src/optimize.c b/src/optimize.c
|
||
index b90dd99..1dd0858 100644
|
||
--- a/src/optimize.c
|
||
+++ b/src/optimize.c
|
||
@@ -215,9 +215,7 @@ static bool __stmt_type_eq(const struct stmt *stmt_a, const struct stmt *stmt_b,
|
||
if (!stmt_a->log.prefix)
|
||
return true;
|
||
|
||
- if (stmt_a->log.prefix->etype != EXPR_VALUE ||
|
||
- stmt_b->log.prefix->etype != EXPR_VALUE ||
|
||
- mpz_cmp(stmt_a->log.prefix->value, stmt_b->log.prefix->value))
|
||
+ if (strcmp(stmt_a->log.prefix, stmt_b->log.prefix))
|
||
return false;
|
||
break;
|
||
case STMT_REJECT:
|
||
@@ -406,7 +404,7 @@ static int rule_collect_stmts(struct optimize_ctx *ctx, struct rule *rule)
|
||
case STMT_LOG:
|
||
memcpy(&clone->log, &stmt->log, sizeof(clone->log));
|
||
if (stmt->log.prefix)
|
||
- clone->log.prefix = expr_get(stmt->log.prefix);
|
||
+ clone->log.prefix = xstrdup(stmt->log.prefix);
|
||
break;
|
||
case STMT_NAT:
|
||
if ((stmt->nat.addr &&
|
||
diff --git a/src/parser_bison.y b/src/parser_bison.y
|
||
index e3ac2fb..678dd50 100644
|
||
--- a/src/parser_bison.y
|
||
+++ b/src/parser_bison.y
|
||
@@ -3338,127 +3338,19 @@ log_args : log_arg
|
||
log_arg : PREFIX string
|
||
{
|
||
struct scope *scope = current_scope(state);
|
||
- bool done = false, another_var = false;
|
||
- char *start, *end, scratch = '\0';
|
||
- struct expr *expr, *item;
|
||
- struct symbol *sym;
|
||
- enum {
|
||
- PARSE_TEXT,
|
||
- PARSE_VAR,
|
||
- } prefix_state;
|
||
-
|
||
- /* No variables in log prefix, skip. */
|
||
- if (!strchr($2, '$')) {
|
||
- expr = constant_expr_alloc(&@$, &string_type,
|
||
- BYTEORDER_HOST_ENDIAN,
|
||
- (strlen($2) + 1) * BITS_PER_BYTE, $2);
|
||
- free_const($2);
|
||
- $<stmt>0->log.prefix = expr;
|
||
- $<stmt>0->log.flags |= STMT_LOG_PREFIX;
|
||
- break;
|
||
- }
|
||
-
|
||
- /* Parse variables in log prefix string using a
|
||
- * state machine parser with two states. This
|
||
- * parser creates list of expressions composed
|
||
- * of constant and variable expressions.
|
||
- */
|
||
- expr = compound_expr_alloc(&@$, EXPR_LIST);
|
||
-
|
||
- start = (char *)$2;
|
||
+ struct error_record *erec;
|
||
+ const char *prefix;
|
||
|
||
- if (*start != '$') {
|
||
- prefix_state = PARSE_TEXT;
|
||
- } else {
|
||
- prefix_state = PARSE_VAR;
|
||
- start++;
|
||
- }
|
||
- end = start;
|
||
-
|
||
- /* Not nice, but works. */
|
||
- while (!done) {
|
||
- switch (prefix_state) {
|
||
- case PARSE_TEXT:
|
||
- while (*end != '\0' && *end != '$')
|
||
- end++;
|
||
-
|
||
- if (*end == '\0')
|
||
- done = true;
|
||
-
|
||
- *end = '\0';
|
||
- item = constant_expr_alloc(&@$, &string_type,
|
||
- BYTEORDER_HOST_ENDIAN,
|
||
- (strlen(start) + 1) * BITS_PER_BYTE,
|
||
- start);
|
||
- compound_expr_add(expr, item);
|
||
-
|
||
- if (done)
|
||
- break;
|
||
-
|
||
- start = end + 1;
|
||
- end = start;
|
||
-
|
||
- /* fall through */
|
||
- case PARSE_VAR:
|
||
- while (isalnum(*end) || *end == '_')
|
||
- end++;
|
||
-
|
||
- if (*end == '\0')
|
||
- done = true;
|
||
- else if (*end == '$')
|
||
- another_var = true;
|
||
- else
|
||
- scratch = *end;
|
||
-
|
||
- *end = '\0';
|
||
-
|
||
- sym = symbol_get(scope, start);
|
||
- if (!sym) {
|
||
- sym = symbol_lookup_fuzzy(scope, start);
|
||
- if (sym) {
|
||
- erec_queue(error(&@2, "unknown identifier '%s'; "
|
||
- "did you mean identifier ‘%s’?",
|
||
- start, sym->identifier),
|
||
- state->msgs);
|
||
- } else {
|
||
- erec_queue(error(&@2, "unknown identifier '%s'",
|
||
- start),
|
||
- state->msgs);
|
||
- }
|
||
- expr_free(expr);
|
||
- free_const($2);
|
||
- YYERROR;
|
||
- }
|
||
- item = variable_expr_alloc(&@$, scope, sym);
|
||
- compound_expr_add(expr, item);
|
||
-
|
||
- if (done)
|
||
- break;
|
||
-
|
||
- /* Restore original byte after
|
||
- * symbol lookup.
|
||
- */
|
||
- if (scratch) {
|
||
- *end = scratch;
|
||
- scratch = '\0';
|
||
- }
|
||
-
|
||
- start = end;
|
||
- if (another_var) {
|
||
- another_var = false;
|
||
- start++;
|
||
- prefix_state = PARSE_VAR;
|
||
- } else {
|
||
- prefix_state = PARSE_TEXT;
|
||
- }
|
||
- end = start;
|
||
- break;
|
||
- }
|
||
+ prefix = str_preprocess(state, &@2, scope, $2, &erec);
|
||
+ if (!prefix) {
|
||
+ erec_queue(erec, state->msgs);
|
||
+ free_const($2);
|
||
+ YYERROR;
|
||
}
|
||
|
||
free_const($2);
|
||
- $<stmt>0->log.prefix = expr;
|
||
- $<stmt>0->log.flags |= STMT_LOG_PREFIX;
|
||
+ $<stmt>0->log.prefix = prefix;
|
||
+ $<stmt>0->log.flags |= STMT_LOG_PREFIX;
|
||
}
|
||
| GROUP NUM
|
||
{
|
||
diff --git a/src/parser_json.c b/src/parser_json.c
|
||
index 25483b1..ce36397 100644
|
||
--- a/src/parser_json.c
|
||
+++ b/src/parser_json.c
|
||
@@ -2540,9 +2540,7 @@ static struct stmt *json_parse_log_stmt(struct json_ctx *ctx,
|
||
stmt = log_stmt_alloc(int_loc);
|
||
|
||
if (!json_unpack(value, "{s:s}", "prefix", &tmpstr)) {
|
||
- stmt->log.prefix = constant_expr_alloc(int_loc, &string_type,
|
||
- BYTEORDER_HOST_ENDIAN,
|
||
- (strlen(tmpstr) + 1) * BITS_PER_BYTE, tmpstr);
|
||
+ stmt->log.prefix = xstrdup(tmpstr);
|
||
stmt->log.flags |= STMT_LOG_PREFIX;
|
||
}
|
||
if (!json_unpack(value, "{s:i}", "group", &tmp)) {
|
||
diff --git a/src/preprocess.c b/src/preprocess.c
|
||
new file mode 100644
|
||
index 0000000..619f67a
|
||
--- /dev/null
|
||
+++ b/src/preprocess.c
|
||
@@ -0,0 +1,168 @@
|
||
+/*
|
||
+ * Copyright (c) 2013-2024 Pablo Neira Ayuso <pablo@netfilter.org>
|
||
+ *
|
||
+ * This program is free software; you can redistribute it and/or modify
|
||
+ * it under the terms of the GNU General Public License version 2 (or any
|
||
+ * later) as published by the Free Software Foundation.
|
||
+ */
|
||
+
|
||
+#include <ctype.h>
|
||
+#include <stdio.h>
|
||
+#include <stdlib.h>
|
||
+#include <stdint.h>
|
||
+#include <stdbool.h>
|
||
+#include <string.h>
|
||
+#include <utils.h>
|
||
+
|
||
+#include "list.h"
|
||
+#include "parser.h"
|
||
+#include "erec.h"
|
||
+
|
||
+struct str_buf {
|
||
+ uint8_t *str;
|
||
+ uint32_t len;
|
||
+ uint32_t size;
|
||
+};
|
||
+
|
||
+#define STR_BUF_LEN 128
|
||
+
|
||
+static struct str_buf *str_buf_alloc(void)
|
||
+{
|
||
+ struct str_buf *buf;
|
||
+
|
||
+ buf = xzalloc(sizeof(*buf));
|
||
+ buf->str = xzalloc_array(1, STR_BUF_LEN);
|
||
+ buf->size = STR_BUF_LEN;
|
||
+
|
||
+ return buf;
|
||
+}
|
||
+
|
||
+static int str_buf_add(struct str_buf *buf, const char *str, uint32_t len)
|
||
+{
|
||
+ uint8_t *tmp;
|
||
+
|
||
+ if (len + buf->len > buf->size) {
|
||
+ buf->size = (len + buf->len) * 2;
|
||
+ tmp = xrealloc(buf->str, buf->size);
|
||
+ buf->str = tmp;
|
||
+ }
|
||
+
|
||
+ memcpy(&buf->str[buf->len], str, len);
|
||
+ buf->len += len;
|
||
+
|
||
+ return 0;
|
||
+}
|
||
+
|
||
+struct str_chunk {
|
||
+ struct list_head list;
|
||
+ char *str;
|
||
+ uint32_t len;
|
||
+ bool is_sym;
|
||
+};
|
||
+
|
||
+static void add_str_chunk(const char *x, int from, int to, struct list_head *list, bool is_sym)
|
||
+{
|
||
+ struct str_chunk *chunk;
|
||
+ int len = to - from;
|
||
+
|
||
+ chunk = xzalloc_array(1, sizeof(*chunk));
|
||
+ chunk->str = xzalloc_array(1, len + 1);
|
||
+ chunk->is_sym = is_sym;
|
||
+ chunk->len = len;
|
||
+ memcpy(chunk->str, &x[from], len);
|
||
+
|
||
+ list_add_tail(&chunk->list, list);
|
||
+}
|
||
+
|
||
+static void free_str_chunk(struct str_chunk *chunk)
|
||
+{
|
||
+ free(chunk->str);
|
||
+ free(chunk);
|
||
+}
|
||
+
|
||
+const char *str_preprocess(struct parser_state *state, struct location *loc,
|
||
+ struct scope *scope, const char *x,
|
||
+ struct error_record **erec)
|
||
+{
|
||
+ struct str_chunk *chunk, *next;
|
||
+ struct str_buf *buf;
|
||
+ const char *str;
|
||
+ int i, j, start;
|
||
+ LIST_HEAD(list);
|
||
+
|
||
+ start = 0;
|
||
+ i = 0;
|
||
+ while (1) {
|
||
+ if (x[i] == '\0') {
|
||
+ i++;
|
||
+ break;
|
||
+ }
|
||
+
|
||
+ if (x[i] != '$') {
|
||
+ i++;
|
||
+ continue;
|
||
+ }
|
||
+
|
||
+ if (isdigit(x[++i]))
|
||
+ continue;
|
||
+
|
||
+ j = i;
|
||
+ while (1) {
|
||
+ if (isalpha(x[i]) ||
|
||
+ isdigit(x[i]) ||
|
||
+ x[i] == '_') {
|
||
+ i++;
|
||
+ continue;
|
||
+ }
|
||
+ break;
|
||
+ }
|
||
+ add_str_chunk(x, start, j-1, &list, false);
|
||
+ add_str_chunk(x, j, i, &list, true);
|
||
+ start = i;
|
||
+ }
|
||
+ if (start != i)
|
||
+ add_str_chunk(x, start, i, &list, false);
|
||
+
|
||
+ buf = str_buf_alloc();
|
||
+
|
||
+ list_for_each_entry_safe(chunk, next, &list, list) {
|
||
+ if (chunk->is_sym) {
|
||
+ struct symbol *sym;
|
||
+
|
||
+ sym = symbol_lookup(scope, chunk->str);
|
||
+ if (!sym) {
|
||
+ sym = symbol_lookup_fuzzy(scope, chunk->str);
|
||
+ if (sym) {
|
||
+ *erec = error(loc, "unknown identifier '%s'; "
|
||
+ "did you mean identifier '%s'?",
|
||
+ chunk->str, sym->identifier);
|
||
+ } else {
|
||
+ *erec = error(loc, "unknown identifier '%s'",
|
||
+ chunk->str);
|
||
+ }
|
||
+ goto err;
|
||
+ }
|
||
+ str_buf_add(buf, sym->expr->identifier,
|
||
+ strlen(sym->expr->identifier));
|
||
+ } else {
|
||
+ str_buf_add(buf, chunk->str, chunk->len);
|
||
+ }
|
||
+ list_del(&chunk->list);
|
||
+ free_str_chunk(chunk);
|
||
+ }
|
||
+
|
||
+ str = (char *)buf->str;
|
||
+
|
||
+ free(buf);
|
||
+
|
||
+ return (char *)str;
|
||
+err:
|
||
+ list_for_each_entry_safe(chunk, next, &list, list) {
|
||
+ list_del(&chunk->list);
|
||
+ free_str_chunk(chunk);
|
||
+ }
|
||
+ free(buf->str);
|
||
+ free(buf);
|
||
+
|
||
+ return NULL;
|
||
+}
|
||
diff --git a/src/statement.c b/src/statement.c
|
||
index ab144d6..551cd13 100644
|
||
--- a/src/statement.c
|
||
+++ b/src/statement.c
|
||
@@ -377,12 +377,8 @@ int log_level_parse(const char *level)
|
||
static void log_stmt_print(const struct stmt *stmt, struct output_ctx *octx)
|
||
{
|
||
nft_print(octx, "log");
|
||
- if (stmt->log.flags & STMT_LOG_PREFIX) {
|
||
- char prefix[NF_LOG_PREFIXLEN] = {};
|
||
-
|
||
- expr_to_string(stmt->log.prefix, prefix);
|
||
- nft_print(octx, " prefix \"%s\"", prefix);
|
||
- }
|
||
+ if (stmt->log.flags & STMT_LOG_PREFIX)
|
||
+ nft_print(octx, " prefix \"%s\"", stmt->log.prefix);
|
||
if (stmt->log.flags & STMT_LOG_GROUP)
|
||
nft_print(octx, " group %u", stmt->log.group);
|
||
if (stmt->log.flags & STMT_LOG_SNAPLEN)
|
||
@@ -419,7 +415,7 @@ static void log_stmt_print(const struct stmt *stmt, struct output_ctx *octx)
|
||
|
||
static void log_stmt_destroy(struct stmt *stmt)
|
||
{
|
||
- expr_free(stmt->log.prefix);
|
||
+ free_const(stmt->log.prefix);
|
||
}
|
||
|
||
static const struct stmt_ops log_stmt_ops = {
|