All of lore.kernel.org
 help / color / mirror / Atom feed
From: Florian Westphal <fw@strlen.de>
To: <netfilter-devel@vger.kernel.org>
Cc: Florian Westphal <fw@strlen.de>
Subject: [PATCH nft 1/6] scanner: add support for scope nesting
Date: Wed, 17 Mar 2021 00:40:34 +0100	[thread overview]
Message-ID: <20210316234039.15677-2-fw@strlen.de> (raw)
In-Reply-To: <20210316234039.15677-1-fw@strlen.de>

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>
---
 include/parser.h |  2 ++
 src/scanner.l    | 17 +++++++++++++++++
 2 files changed, 19 insertions(+)

diff --git a/include/parser.h b/include/parser.h
index 9fdebcd11dd2..0c229963d3be 100644
--- a/include/parser.h
+++ b/include/parser.h
@@ -23,6 +23,8 @@ struct parser_state {
 	struct scope			*scopes[SCOPE_NEST_MAX];
 	unsigned int			scope;
 
+	unsigned int			flex_state_pop;
+	unsigned int			startcond_type;
 	struct list_head		*cmds;
 };
 
diff --git a/src/scanner.l b/src/scanner.l
index a73ce1b819d8..01e1dca52fdd 100644
--- a/src/scanner.l
+++ b/src/scanner.l
@@ -1017,11 +1017,28 @@ void scanner_destroy(struct nft_ctx *nft)
 
 static void scanner_push_start_cond(void *scanner, enum startcond_type type)
 {
+	struct parser_state *state = yyget_extra(scanner);
+
+	state->startcond_type = type;
 	yy_push_state((int)type, scanner);
 }
 
 void scanner_pop_start_cond(void *scanner, enum startcond_type t)
 {
+	struct parser_state *state = yyget_extra(scanner);
+
+	if (state->startcond_type != t) {
+		state->flex_state_pop++;
+		return; /* Can't pop just yet! */
+	}
+
+	while (state->flex_state_pop) {
+		state->flex_state_pop--;
+		state->startcond_type = yy_top_state(scanner);
+		yy_pop_state(scanner);
+	}
+
+	state->startcond_type = yy_top_state(scanner);
 	yy_pop_state(scanner);
 	(void)yy_top_state(scanner); /* suppress gcc warning wrt. unused function */
 }
-- 
2.26.2


  reply	other threads:[~2021-03-16 23:41 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-03-16 23:40 [PATCH nft 0/6] arbirary table/chain names Florian Westphal
2021-03-16 23:40 ` Florian Westphal [this message]
2021-03-16 23:40 ` [PATCH nft 2/6] scanner: counter: move to own scope Florian Westphal
2021-03-16 23:40 ` [PATCH nft 3/6] scanner: log: " Florian Westphal
2021-03-16 23:40 ` [PATCH nft 4/6] scanner: support arbitary table names Florian Westphal
2021-03-16 23:40 ` [PATCH nft 5/6] scanner: support arbitrary chain names Florian Westphal
2021-03-16 23:40 ` [PATCH nft 6/6] src: allow arbitary chain name in implicit rule add case Florian Westphal
2021-03-18 12:00   ` Phil Sutter
2021-03-18 12:37     ` Florian Westphal
2021-03-18 13:51       ` Phil Sutter
2021-03-18 13:20   ` Florian Westphal
2021-03-24 10:58     ` Florian Westphal

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210316234039.15677-2-fw@strlen.de \
    --to=fw@strlen.de \
    --cc=netfilter-devel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.