summaryrefslogtreecommitdiffstats
path: root/include/parser.h
Commit message (Collapse)AuthorAgeFilesLines
* scanner: don't pop active flex scanner scopeFlorian Westphal2022-06-271-0/+3
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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-1/+0
| | | | | | | | | | | | | | | | | | | | | | | 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: dup, fwd, tproxy: Move to own scopesPhil Sutter2022-03-011-0/+3
| | | | | | 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-0/+1
| | | | | | | 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-0/+1
| | | | | | | 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-0/+1
| | | | | | | | | | 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-0/+1
| | | | | | Isolate 'performance' and 'memory' keywords. Signed-off-by: Phil Sutter <phil@nwl.cc>
* scanner: flags: move to own scopePhil Sutter2022-03-011-0/+1
| | | | | | 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-0/+1
| | | | | | Two more keywords isolated. Signed-off-by: Phil Sutter <phil@nwl.cc>
* scanner: import, export: Move to own scopesPhil Sutter2022-03-011-0/+2
| | | | | | | 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-0/+1
| | | | | | 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-0/+1
| | | | | | Some keywords are shared with list command. Signed-off-by: Phil Sutter <phil@nwl.cc>
* scanner: type: Move to own scopePhil Sutter2022-03-011-0/+1
| | | | | | 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-0/+4
| | | | | | | 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-0/+2
| | | | | | 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-0/+1
| | | | | | 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-0/+2
| | | | | | | 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-0/+2
| | | | | | | 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-0/+1
| | | | | | Isolates only 'cpi' keyword for now. Signed-off-by: Phil Sutter <phil@nwl.cc>
* scanner: synproxy: Move to own scopePhil Sutter2022-03-011-0/+1
| | | | | | Quite a few keywords are shared with PARSER_SC_TCP. Signed-off-by: Phil Sutter <phil@nwl.cc>
* scanner: igmp: Move to own scopePhil Sutter2022-03-011-0/+1
| | | | | | | 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-0/+1
| | | | | | Unify the two, header fields are almost identical. Signed-off-by: Phil Sutter <phil@nwl.cc>
* scanner: add tcp flex scopeFlorian Westphal2021-12-011-0/+1
| | | | | | | | 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>
* scanner: add list cmd parser scopeFlorian Westphal2021-06-091-0/+1
| | | | | | | | | | 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/+1
| | | | | | | | 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-0/+1
| | | | | | | This isolates only "vtag" token for now. Signed-off-by: Phil Sutter <phil@nwl.cc> Reviewed-by: Florian Westphal <fw@strlen.de>
* scanner: log: move to own scopeFlorian Westphal2021-03-241-0/+2
| | | | | | | GROUP and PREFIX are used by igmp and nat, so they can't be moved out of INITIAL scope yet. Signed-off-by: Florian Westphal <fw@strlen.de>
* scanner: counter: move to own scopeFlorian Westphal2021-03-241-0/+1
| | | | | | move bytes/packets away from initial state. Signed-off-by: Florian Westphal <fw@strlen.de>
* scanner: add support for scope nestingFlorian Westphal2021-03-241-0/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Adding a COUNTER scope introduces parsing errors. Example: add rule ... counter ip saddr 1.2.3.4 This is supposed to be COUNTER IP SADDR SYMBOL but it will be parsed as COUNTER IP STRING SYMBOL ... and rule fails with unknown saddr. This is because IP state change gets popped right after it was pushed. bison parser invokes scanner_pop_start_cond() helper via 'close_scope_counter' rule after it has processed the entire 'counter' rule. But that happens *after* flex has executed the 'IP' rule. IOW, the sequence of events is not the exepcted "COUNTER close_scope_counter IP SADDR SYMBOL close_scope_ip", it is "COUNTER IP close_scope_counter". close_scope_counter pops the just-pushed SCANSTATE_IP and returns the scanner to SCANSTATE_COUNTER, so next input token (saddr) gets parsed as a string, which gets then rejected from bison. To resolve this, defer the pop operation until the current state is done. scanner_pop_start_cond() already gets the scope that it has been completed as an argument, so we can compare it to the active state. If those are not the same, just defer the pop operation until the bison reports its done with the active flex scope. This leads to following sequence of events: 1. flex switches to SCANSTATE_COUNTER 2. flex switches to SCANSTATE_IP 3. bison calls scanner_pop_start_cond(SCANSTATE_COUNTER) 4. flex remains in SCANSTATE_IP, bison continues 5. bison calls scanner_pop_start_cond(SCANSTATE_IP) once the entire ip rule has completed: this pops both IP and COUNTER. Signed-off-by: Florian Westphal <fw@strlen.de>
* scanner: secmark: move to own scopeFlorian Westphal2021-03-161-0/+1
| | | | Signed-off-by: Florian Westphal <fw@strlen.de>
* scanner: quota: move to own scopeFlorian Westphal2021-03-161-0/+1
| | | | | | ... and move "used" keyword to it. Signed-off-by: Florian Westphal <fw@strlen.de>
* scanner: limit: move to own scopeFlorian Westphal2021-03-161-0/+1
| | | | | | Moves rate and burst out of INITIAL. Signed-off-by: Florian Westphal <fw@strlen.de>
* scanner: vlan: move to own scopeFlorian Westphal2021-03-161-0/+1
| | | | | | ID needs to remain exposed as its used by ct, icmp, icmp6 and so on. Signed-off-by: Florian Westphal <fw@strlen.de>
* scanner: arp: move to own scopeFlorian Westphal2021-03-161-0/+1
| | | | | | allows to move the arp specific tokens out of the INITIAL scope. Signed-off-by: Florian Westphal <fw@strlen.de>
* scanner: add ether scopeFlorian Westphal2021-03-161-0/+1
| | | | | | | just like previous change: useless as-is, but prepares for removal of saddr/daddr from INITIAL scope. Signed-off-by: Florian Westphal <fw@strlen.de>
* scanner: add fib scopeFlorian Westphal2021-03-161-0/+1
| | | | | | | | | makes no sense as-is because all keywords need to stay in the INITIAL scope. This can be changed after all saddr/daddr users have been scoped. Signed-off-by: Florian Westphal <fw@strlen.de>
* scanner: ip6: move to own scopeFlorian Westphal2021-03-161-0/+1
| | | | | | move flowlabel and hoplimit. Signed-off-by: Florian Westphal <fw@strlen.de>
* scanner: ip: move to own scopeFlorian Westphal2021-03-161-0/+1
| | | | | | Move the ip option names (rr, lsrr, ...) out of INITIAL scope. Signed-off-by: Florian Westphal <fw@strlen.de>
* scanner: ct: move to own scopeFlorian Westphal2021-03-161-0/+1
| | | | | | | | | | | | This allows moving multiple ct specific keywords out of INITIAL scope. Next few patches follow same pattern: 1. add a scope_close_XXX rule 2. add a SCANSTATE_XXX & make flex switch to it when encountering XXX keyword 3. make bison leave SCANSTATE_XXXX when it has seen the complete expression. Signed-off-by: Florian Westphal <fw@strlen.de>
* scanner: socket: move to own scopeFlorian Westphal2021-03-111-0/+1
| | | | Signed-off-by: Florian Westphal <fw@strlen.de>
* scanner: rt: move to own scopeFlorian Westphal2021-03-111-0/+1
| | | | | | | | classid and nexthop can be moved out of INIT scope. Rest are still needed because tehy are used by other expressions as well. Signed-off-by: Florian Westphal <fw@strlen.de>
* scanner: ipsec: move to own scopeFlorian Westphal2021-03-111-0/+1
| | | | | | ... and hide the ipsec specific tokens from the INITITAL scope. Signed-off-by: Florian Westphal <fw@strlen.de>
* scanner: queue: move to own scopeFlorian Westphal2021-03-111-0/+1
| | | | | | allows to remove 3 queue specific keywords from INITIAL scope. Signed-off-by: Florian Westphal <fw@strlen.de>
* scanner: introduce start condition stackFlorian Westphal2021-03-111-0/+8
| | | | | | | | | | | | | | | | | | | | Add a small initial chunk of flex start conditionals. This starts with two low-hanging fruits, numgen and j/symhash. NUMGEN and HASH start conditions are entered from flex when the corresponding expression token is encountered. Flex returns to the INIT condition when the bison parser has seen a complete numgen/hash statement. This intentionally uses a stack rather than BEGIN() to eventually support nested states. The scanner_pop_start_cond() function argument is not used yet, but will need to be used later to deal with nesting. Signed-off-by: Florian Westphal <fw@strlen.de>
* src: support for implicit chain bindingsPablo Neira Ayuso2020-07-151-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | This patch allows you to group rules in a subchain, e.g. table inet x { chain y { type filter hook input priority 0; tcp dport 22 jump { ip saddr { 127.0.0.0/8, 172.23.0.0/16, 192.168.13.0/24 } accept ip6 saddr ::1/128 accept; } } } This also supports for the `goto' chain verdict. This patch adds a new chain binding list to avoid a chain list lookup from the delinearize path for the usual chains. This can be simplified later on with a single hashtable per table for all chains. From the shell, you have to use the explicit separator ';', in bash you have to escape this: # nft add rule inet x y tcp dport 80 jump { ip saddr 127.0.0.1 accept\; ip6 saddr ::1 accept \; } Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* scanner: remove parser_state->indesc_idxLaurent Fasnacht2020-02-131-1/+0
| | | | | | | | Now that we have a proper stack implementation, we don't need an additional counter for the number of buffer state pushed. Signed-off-by: Laurent Fasnacht <fasnacht@protonmail.ch> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* scanner: remove parser_state->indescs static arrayLaurent Fasnacht2020-02-131-1/+0
| | | | | | | | This static array is redundant with the indesc_list structure, but is less flexible. Signed-off-by: Laurent Fasnacht <fasnacht@protonmail.ch> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* libnftables: Store top_scope in struct nft_ctxPhil Sutter2019-11-071-2/+2
| | | | | | | | | | | | | | | | Allow for interactive sessions to make use of defines. Since parser is initialized for each line, top scope defines didn't persist although they are actually useful for stuff like: | # nft -i | define goodports = { 22, 23, 80, 443 } | add rule inet t c tcp dport $goodports accept | add rule inet t c tcp sport $goodports accept While being at it, introduce scope_alloc() and scope_free(). Signed-off-by: Phil Sutter <phil@nwl.cc> Acked-by: Pablo Neira Ayuso <pablo@netfilter.org>
* src: perform evaluation after parsingPablo Neira Ayuso2019-06-051-1/+0
| | | | | | | | | | | | | | | | | Since 61236968b7a1 ("parser: evaluate commands immediately after parsing"), evaluation is invoked from the parsing phase in order to improve error reporting. However, this approach is problematic from the cache perspective since we don't know if a full or partial netlink dump from the kernel is needed. If the number of objects in the kernel is significant, the netlink dump operation to build the cache may significantly slow down commands. This patch moves the evaluation phase after the parsing phase as a preparation update to allow for a better strategy to build the cache. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* src: dynamic input_descriptor allocationPablo Neira Ayuso2019-06-051-1/+2
| | | | | | | | | | | | | This patch introduces the input descriptor list, that stores the existing input descriptor objects. These objects are now dynamically allocated and release from scanner_destroy() path. Follow up patches that decouple the parsing and the evaluation phases require this for error reporting as described by b14572f72aac ("erec: Fix input descriptors for included files"), this patch partially reverts such partial. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>