summaryrefslogtreecommitdiffstats
path: root/src/scanner.l
Commit message (Collapse)AuthorAgeFilesLines
* Implement 'reset rule' and 'reset rules' commandsPhil Sutter2023-01-181-0/+1
| | | | | | | | Reset rule counters and quotas in kernel, i.e. without having to reload them. Requires respective kernel patch to support NFT_MSG_GETRULE_RESET message type. Signed-off-by: Phil Sutter <phil@nwl.cc>
* src: add gretap supportPablo Neira Ayuso2023-01-021-0/+1
| | | | Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* src: add geneve matching supportPablo Neira Ayuso2023-01-021-0/+2
| | | | | | Add support for GENEVE vni and (ether) type header field. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* src: add gre supportPablo Neira Ayuso2023-01-021-2/+5
| | | | | | | | | | | | | GRE has a number of fields that are conditional based on flags, which requires custom dependency code similar to icmp and icmpv6. Matching on optional fields is not supported at this stage. Since this is a layer 3 tunnel protocol, an implicit dependency on NFT_META_L4PROTO for IPPROTO_GRE is generated. To achieve this, this patch adds new infrastructure to remove an outer dependency based on the inner protocol from delinearize path. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* src: add vxlan matching supportPablo Neira Ayuso2023-01-021-0/+3
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This patch adds the initial infrastructure to support for inner header tunnel matching and its first user: vxlan. A new struct proto_desc field for payload and meta expression to specify that the expression refers to inner header matching is used. The existing codebase to generate bytecode is fully reused, allowing for reusing existing supported layer 2, 3 and 4 protocols. Syntax requires to specify vxlan before the inner protocol field: ... vxlan ip protocol udp ... vxlan ip saddr 1.2.3.0/24 This also works with concatenations and anonymous sets, eg. ... vxlan ip saddr . vxlan ip daddr { 1.2.3.4 . 4.3.2.1 } You have to restrict vxlan matching to udp traffic, otherwise it complains on missing transport protocol dependency, e.g. ... udp dport 4789 vxlan ip daddr 1.2.3.4 The bytecode that is generated uses the new inner expression: # nft --debug=netlink add rule netdev x y udp dport 4789 vxlan ip saddr 1.2.3.4 netdev x y [ meta load l4proto => reg 1 ] [ cmp eq reg 1 0x00000011 ] [ payload load 2b @ transport header + 2 => reg 1 ] [ cmp eq reg 1 0x0000b512 ] [ inner type 1 hdrsize 8 flags f [ meta load protocol => reg 1 ] ] [ cmp eq reg 1 0x00000008 ] [ inner type 1 hdrsize 8 flags f [ payload load 4b @ network header + 12 => reg 1 ] ] [ cmp eq reg 1 0x04030201 ] JSON support is not included in this patch. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* scanner: treat invalid octal strings as stringsJeremy Sowden2022-12-221-3/+15
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The action associated with the `{numberstring}` pattern, passes `yytext` to `strtoull` with base 0: errno = 0; yylval->val = strtoull(yytext, NULL, 0); if (errno != 0) { yylval->string = xstrdup(yytext); return STRING; } return NUM; If `yytext` begins with '0', it will be parsed as octal. However, this has unexpected consequences if the token contains non-octal characters. `09` will be parsed as 0; `0308` will be parsed as 24, because `strtoull` and its siblings stop parsing as soon as they reach a character in the input which is not valid for the base. Replace the `{numberstring}` match with separate `{hexstring}` and `{decstring}` matches. For `{decstring}` set the base to 8 if the leading character is '0', and handle an incompletely parsed token in the same way as one that causes `strtoull` to set `errno`. Thus, instead of: $ sudo nft -f - <<<' table x { chain y { ip saddr 0308 continue comment "parsed as 0.0.0.24/32" } } ' $ sudo nft list chain x y table ip x { chain y { ip saddr 0.0.0.24 continue comment "parsed as 0.0.0.24/32" } } We get: $ sudo ./src/nft -f - <<<' > table x { > chain y { > ip saddr 0308 continue comment "error" > } > } > ' /dev/stdin:4:14-17: Error: Could not resolve hostname: Name or service not known ip saddr 0308 continue comment "error" ^^^^ Add a test-case. Link: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=932880 Link: https://bugzilla.netfilter.org/show_bug.cgi?id=1363 Signed-off-by: Jeremy Sowden <jeremy@azazel.net> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* xt: Rewrite unsupported compat expression dumpingPhil Sutter2022-12-131-0/+3
| | | | | | | | | Choose a format which provides more information and is easily parseable. Then teach parsers about it and make it explicitly reject the ruleset giving a meaningful explanation. Also update the man pages with some more details. Signed-off-by: Phil Sutter <phil@nwl.cc>
* scanner: match full comment line in case of tiePablo Neira Ayuso2022-12-121-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | add element ip filter public_services { # comment 1 tcp . 80 : jump log_accept, # comment 2 tcp . 443 : jump log_accept, } still fails with the error message: # nft -f filter_sets.ip In file included from filter_sets.ip:63:1-42: filter_sets.ip:4:12-12: Error: syntax error, unexpected newline, expecting comma or '}' # comment 2 ^ flex honors the first rule found in case of tie, place comment_line before comment rule. Fixes: 931737a17198 ("scanner: munch full comment lines") Reported-by: Jozsef Kadlecsik <kadlec@netfilter.org> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* scanner: munch full comment linesPablo Neira Ayuso2022-12-071-0/+4
| | | | | | | | | | | Munch lines full comment lines, regular expression matches lines that start by space or tab, then # follows, finally anything including one single line break. Call reset_pos() to ensure error reporting location is not puzzled. Closes: https://bugzilla.netfilter.org/show_bug.cgi?id=1196 Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* scanner: allow prefix in ip6 scopeFlorian Westphal2022-07-071-1/+1
| | | | | | | | | | | 'ip6 prefix' is valid syntax, so make sure scanner recognizes it also in ip6 context. Also add test case. Fixes: a67fce7ffe7e ("scanner: nat: Move to own scope") Closes: https://bugzilla.netfilter.org/show_bug.cgi?id=1619 Signed-off-by: Florian Westphal <fw@strlen.de>
* scanner: don't pop active flex scanner scopeFlorian Westphal2022-06-271-0/+11
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Currently we can pop a flex scope that is still active, i.e. the scanner_pop_start_cond() for the scope has not been done. Example: counter ipsec out ip daddr 192.168.1.2 counter name "ipsec_out" Here, parser fails because 'daddr' is parsed as STRING, not as DADDR token. Bug is as follows: COUNTER changes scope to COUNTER. (COUNTER). Next, IPSEC scope gets pushed, stack is: COUNTER, IPSEC. Then, the 'COUNTER' scope close happens. Because active scope has changed, we cannot pop (we would pop the 'ipsec' scope in flex). The pop operation gets delayed accordingly. Next, IP gets pushed, stack is: COUNTER, IPSEC, IP, plus the information that one scope closure/pop was delayed. Then, the IP scope is closed. Because a pop operation was delayed, we pop again, which brings us back to COUNTER state. This is bogus: The pop operation CANNOT be done yet, because the ipsec scope is still open, but the existing code lacks the information to detect this. After popping the IP scope, we must remain in IPSEC scope until bison parser calls scanner_pop_start_cond(, IPSEC). This adds a counter per flex scope so that we can detect this case. In above case, after the IP scope gets closed, the "new" (previous) scope (IPSEC) will be treated as active and its close is attempted again on the next call to scanner_pop_start_cond(). After this patch, transition in above rule is: push counter (COUNTER) push IPSEC (COUNTER, IPSEC) pop COUNTER (delayed: COUNTER, IPSEC, pending-pop for COUNTER), push IP (COUNTER, IPSEC, IP, pending-pop for COUNTER) pop IP (COUNTER, IPSEC, pending-pop for COUNTER) parse DADDR (we're in IPSEC scope, its valid token) pop IPSEC (pops all remaining scopes). We could also resurrect the commit: "scanner: flags: move to own scope", the test case passes with the new scope closure logic. Fixes: bff106c5b277 ("scanner: add support for scope nesting") Signed-off-by: Florian Westphal <fw@strlen.de>
* Revert "scanner: flags: move to own scope"Florian Westphal2022-06-101-11/+7
| | | | | | | | | | | | | | | | | | | | | | | Excess nesting of scanner scopes is very fragile and error prone: rule `iif != lo ip daddr 127.0.0.1/8 counter limit rate 1/second log flags all prefix "nft_lo4 " drop` fails with `Error: No symbol type information` hinting at `prefix` Problem is that we nest via: counter limit log flags By the time 'prefix' is scanned, state is still stuck in 'counter' due to this nesting. Working around "prefix" isn't enough, any other keyword, e.g. "level" in 'flags all level debug' will be parsed as 'string' too. So, revert this. Fixes: a16697097e2b ("scanner: flags: move to own scope") Reported-by: Christian Göttsche <cgzones@googlemail.com> Signed-off-by: Florian Westphal <fw@strlen.de>
* scanner: Fix for ipportmap nat statementsPhil Sutter2022-03-021-1/+1
| | | | | | | | Due to lookahead, "addr" keyword is still found in IP/IP6 scope, not STMT_NAT one. Fixes: a67fce7ffe7e4 ("scanner: nat: Move to own scope") Signed-off-by: Phil Sutter <phil@nwl.cc>
* scanner: dup, fwd, tproxy: Move to own scopesPhil Sutter2022-03-011-4/+7
| | | | | | With these three scopes in place, keyword 'to' may be isolated. Signed-off-by: Phil Sutter <phil@nwl.cc>
* scanner: meta: Move to own scopePhil Sutter2022-03-011-3/+4
| | | | | | | This allows to isolate 'length' and 'protocol' keywords shared by other scopes as well. Signed-off-by: Phil Sutter <phil@nwl.cc>
* scanner: at: Move to own scopePhil Sutter2022-03-011-3/+6
| | | | | | | Modification of raw TCP option rule is a bit more complicated to avoid pushing tcp_hdr_option_type into the introduced scope by accident. Signed-off-by: Phil Sutter <phil@nwl.cc>
* scanner: nat: Move to own scopePhil Sutter2022-03-011-9/+12
| | | | | | | | | | Unify nat, masquerade and redirect statements, they widely share their syntax. Note the workaround of adding "prefix" to SCANSTATE_IP. This is required to fix for 'snat ip prefix ...' style expressions. Signed-off-by: Phil Sutter <phil@nwl.cc>
* scanner: policy: move to own scopePhil Sutter2022-03-011-3/+6
| | | | | | Isolate 'performance' and 'memory' keywords. Signed-off-by: Phil Sutter <phil@nwl.cc>
* scanner: flags: move to own scopePhil Sutter2022-03-011-6/+10
| | | | | | This isolates at least 'constant', 'dynamic' and 'all' keywords. Signed-off-by: Phil Sutter <phil@nwl.cc>
* scanner: reject: Move to own scopePhil Sutter2022-03-011-3/+6
| | | | | | Two more keywords isolated. Signed-off-by: Phil Sutter <phil@nwl.cc>
* scanner: import, export: Move to own scopesPhil Sutter2022-03-011-5/+9
| | | | | | | In theory, one could use a common scope for both import and export commands, their parameters are identical. Signed-off-by: Phil Sutter <phil@nwl.cc>
* scanner: reset: move to own ScopePhil Sutter2022-03-011-3/+6
| | | | | | Isolate two more keywords shared with list command. Signed-off-by: Phil Sutter <phil@nwl.cc>
* scanner: monitor: Move to own ScopePhil Sutter2022-03-011-6/+11
| | | | | | Some keywords are shared with list command. Signed-off-by: Phil Sutter <phil@nwl.cc>
* scanner: rt: Extend scope over rt0, rt2 and srhPhil Sutter2022-03-011-6/+6
| | | | | | | These are technically all just routing headers with different types, so unify them under the same scope. Signed-off-by: Phil Sutter <phil@nwl.cc>
* scanner: type: Move to own scopePhil Sutter2022-03-011-4/+11
| | | | | | As a side-effect, this fixes for use of 'classid' as set data type. Signed-off-by: Phil Sutter <phil@nwl.cc>
* scanner: dst, frag, hbh, mh: Move to own scopesPhil Sutter2022-03-011-11/+25
| | | | | | | These are the remaining IPv6 extension header expressions, only rt expression was scoped already. Signed-off-by: Phil Sutter <phil@nwl.cc>
* scanner: ah, esp: Move to own scopesPhil Sutter2022-03-011-4/+8
| | | | | | They share 'sequence' keyword with icmp and tcp expressions. Signed-off-by: Phil Sutter <phil@nwl.cc>
* scanner: osf: Move to own scopePhil Sutter2022-03-011-4/+9
| | | | | | It shares two keywords with PARSER_SC_IP. Signed-off-by: Phil Sutter <phil@nwl.cc>
* scanner: dccp, th: Move to own scopesPhil Sutter2022-03-011-4/+10
| | | | | | | With them in place, heavily shared keywords 'sport' and 'dport' may be isolated. Signed-off-by: Phil Sutter <phil@nwl.cc>
* scanner: udp{,lite}: Move to own scopePhil Sutter2022-03-011-2/+7
| | | | | | | All used keywords are shared with others, so no separation for now apart from 'csumcov' which was actually missing from scanner.l. Signed-off-by: Phil Sutter <phil@nwl.cc>
* scanner: comp: Move to own scope.Phil Sutter2022-03-011-2/+5
| | | | | | Isolates only 'cpi' keyword for now. Signed-off-by: Phil Sutter <phil@nwl.cc>
* scanner: synproxy: Move to own scopePhil Sutter2022-03-011-7/+13
| | | | | | Quite a few keywords are shared with PARSER_SC_TCP. Signed-off-by: Phil Sutter <phil@nwl.cc>
* scanner: tcp: Move to own scopePhil Sutter2022-03-011-25/+35
| | | | | | | Apart from header fields, this isolates TCP option types and fields, too. Signed-off-by: Phil Sutter <phil@nwl.cc>
* scanner: igmp: Move to own scopePhil Sutter2022-03-011-3/+7
| | | | | | | At least isolates 'mrt' and 'group' keywords, the latter is shared with log statement. Signed-off-by: Phil Sutter <phil@nwl.cc>
* scanner: icmp{,v6}: Move to own scopePhil Sutter2022-03-011-8/+11
| | | | | | Unify the two, header fields are almost identical. Signed-off-by: Phil Sutter <phil@nwl.cc>
* scanner: rt: Move seg-left keyword into scopePhil Sutter2022-02-201-1/+1
| | | | | | | It's not used outside of rt_hdr_expr, so move it out of INIT scope. Fixes: 8861db1b771a6 ("scanner: rt: move to own scope") Signed-off-by: Phil Sutter <phil@nwl.cc>
* scanner: Some time units are only used in limit scopePhil Sutter2022-02-201-3/+5
| | | | | | | | 'hour' and 'day' are allowed as unqualified meta expressions, so leave them alone. Fixes: eae2525685252 ("scanner: limit: move to own scope") Signed-off-by: Phil Sutter <phil@nwl.cc>
* scanner: Move 'maps' keyword into list cmd scopePhil Sutter2022-02-201-1/+1
| | | | | | | | This was missed when introducing SCANSTATE_CMD_LIST, no other command operates on "maps". Fixes: 6a24ffb04642e ("scanner: add list cmd parser scope") Signed-off-by: Phil Sutter <phil@nwl.cc>
* src: error reporting with -f and read from stdinPablo Neira Ayuso2022-01-151-1/+1
| | | | | | | | | | | | | | | | | | | | | Reading from stdin requires to store the ruleset in a buffer so error reporting works accordingly, eg. # cat ruleset.nft | nft -f - /dev/stdin:3:13-13: Error: unknown identifier 'x' ip saddr $x ^ The error reporting infrastructure performs a fseek() on the file descriptor which does not work in this case since the data from the descriptor has been already consumed. This patch adds a new stdin input descriptor to perform this special handling which consists on re-routing this request through the buffer functions. Fixes: 935f82e7dd49 ("Support 'nft -f -' to read from stdin") Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* mptcp: add subtype matchingFlorian Westphal2021-12-011-0/+1
| | | | | | | | | | | | | | | | | | | | | | MPTCP multiplexes the various mptcp signalling data using the first 4 bits of the mptcp option. This allows to match on the mptcp subtype via: tcp option mptcp subtype 1 This misses delinearization support. mptcp subtype is the first tcp option field that has a length of less than one byte. Serialization processing will add a binop for this, but netlink delinearization can't remove them, yet. Also misses a new datatype/symbol table to allow to use mnemonics like 'mp_join' instead of raw numbers. For this reason, no tests are added yet. Signed-off-by: Florian Westphal <fw@strlen.de>
* tcpopt: add md5sig, fastopen and mptcp optionsFlorian Westphal2021-12-011-0/+3
| | | | | | | | | Allow to use "fastopen", "md5sig" and "mptcp" mnemonics rather than the raw option numbers. These new keywords are only recognized while scanner is in tcp state. Signed-off-by: Florian Westphal <fw@strlen.de>
* scanner: add tcp flex scopeFlorian Westphal2021-12-011-6/+11
| | | | | | | | This moves tcp options not used anywhere else (e.g. in synproxy) to a distinct scope. This will also allow to avoid exposing new option keywords in the ruleset context. Signed-off-by: Florian Westphal <fw@strlen.de>
* tcpopt: remove KIND keywordFlorian Westphal2021-12-011-1/+0
| | | | | | | | | | | | | | | | tcp option <foo> kind ... never makes any sense, as "tcp option <foo>" already tells the kernel to look for the foo <kind>. "tcp option sack kind 5" matches if the sack option is present; its a more complicated form of the simpler "tcp option sack exists". "tcp option sack kind 1" (or any other value than 5) will never match. So remove this. Test cases are converted to "exists". Signed-off-by: Florian Westphal <fw@strlen.de>
* parser: allow for string raw payload basePablo Neira Ayuso2021-11-161-1/+0
| | | | | | | Remove new 'ih' token, allow to represent the raw payload base with a string instead. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* src: raw payload match and mangle on inner header / payload dataPablo Neira Ayuso2021-11-081-0/+1
| | | | | | | | | | | | | | | This patch adds support to match on inner header / payload data: # nft add rule x y @ih,32,32 0x14000000 counter you can also mangle payload data: # nft add rule x y @ih,32,32 set 0x14000000 counter This update triggers a checksum update at the layer 4 header via csum_flags, mangling odd bytes is also aligned to 16-bits. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* src: add vlan deiPablo Neira Ayuso2021-06-111-0/+1
| | | | | | | | | | the CFI bit has been repurposed as DEI "Drop Eligible Indicator" since 802.1Q-2011. The vlan cfi field is still retained for compatibility. Closes: https://bugzilla.netfilter.org/show_bug.cgi?id=1516 Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* src: add support for base hook dumpingFlorian Westphal2021-06-091-0/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Example output: $ nft list hook ip input family ip hook input { +0000000000 nft_do_chain_inet [nf_tables] # nft table ip filter chain input +0000000010 nft_do_chain_inet [nf_tables] # nft table ip firewalld chain filter_INPUT +0000000100 nf_nat_ipv4_local_in [nf_nat] +2147483647 ipv4_confirm [nf_conntrack] } $ nft list hooks netdev type ingress device lo family netdev hook ingress device lo { +0000000000 nft_do_chain_netdev [nf_tables] } $ nft list hooks inet family ip hook prerouting { -0000000400 ipv4_conntrack_defrag [nf_defrag_ipv4] -0000000300 iptable_raw_hook [iptable_raw] -0000000290 nft_do_chain_inet [nf_tables] # nft table ip firewalld chain raw_PREROUTING -0000000200 ipv4_conntrack_in [nf_conntrack] -0000000140 nft_do_chain_inet [nf_tables] # nft table ip firewalld chain mangle_PREROUTING -0000000100 nf_nat_ipv4_pre_routing [nf_nat] } ... 'nft list hooks' will display everyting except the netdev family via successive dump request for all family:hook combinations. Signed-off-by: Florian Westphal <fw@strlen.de>
* scanner: add list cmd parser scopeFlorian Westphal2021-06-091-6/+9
| | | | | | | | | | Followup patch will add new 'hooks' keyword for nft list hooks Add a scope for list to avoid exposure of the new keyword in nft rulesets. Signed-off-by: Florian Westphal <fw@strlen.de>
* exthdr: Implement SCTP Chunk matchingPhil Sutter2021-05-191-0/+38
| | | | | | | | Extend exthdr expression to support scanning through SCTP packet chunks and matching on fixed fields' values. Signed-off-by: Phil Sutter <phil@nwl.cc> Acked-by: Florian Westphal <fw@strlen.de>
* scanner: sctp: Move to own scopePhil Sutter2021-05-191-2/+6
| | | | | | | This isolates only "vtag" token for now. Signed-off-by: Phil Sutter <phil@nwl.cc> Reviewed-by: Florian Westphal <fw@strlen.de>