From c330152b7f7779f15dba3e0862bf5616e7cb3eab Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Sat, 4 Jul 2020 02:43:44 +0200 Subject: src: support for implicit chain bindings 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 --- src/parser_bison.y | 31 ++++++++++++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-) (limited to 'src/parser_bison.y') diff --git a/src/parser_bison.y b/src/parser_bison.y index face9950..756806d9 100644 --- a/src/parser_bison.y +++ b/src/parser_bison.y @@ -594,8 +594,8 @@ int nft_lex(void *, void *, void *); %type table_block_alloc table_block %destructor { close_scope(state); table_free($$); } table_block_alloc -%type chain_block_alloc chain_block -%destructor { close_scope(state); chain_free($$); } chain_block_alloc +%type chain_block_alloc chain_block subchain_block +%destructor { close_scope(state); chain_free($$); } chain_block_alloc subchain_block %type rule rule_alloc %destructor { rule_free($$); } rule @@ -642,7 +642,9 @@ int nft_lex(void *, void *, void *); %destructor { stmt_free($$); } tproxy_stmt %type synproxy_stmt synproxy_stmt_alloc %destructor { stmt_free($$); } synproxy_stmt synproxy_stmt_alloc - +%type chain_stmt +%destructor { stmt_free($$); } chain_stmt +%type chain_stmt_type %type queue_stmt queue_stmt_alloc %destructor { stmt_free($$); } queue_stmt queue_stmt_alloc @@ -1682,6 +1684,15 @@ chain_block : /* empty */ { $$ = $-1; } } ; +subchain_block : /* empty */ { $$ = $-1; } + | subchain_block stmt_separator + | subchain_block rule stmt_separator + { + list_add_tail(&$2->list, &$1->rules); + $$ = $1; + } + ; + typeof_expr : primary_expr { if (expr_ops($1)->build_udata == NULL) { @@ -2527,6 +2538,20 @@ stmt : verdict_stmt | set_stmt | map_stmt | synproxy_stmt + | chain_stmt + ; + +chain_stmt_type : JUMP { $$ = NFT_JUMP; } + | GOTO { $$ = NFT_GOTO; } + ; + +chain_stmt : chain_stmt_type chain_block_alloc '{' subchain_block '}' + { + $2->location = @2; + close_scope(state); + $4->location = @4; + $$ = chain_stmt_alloc(&@$, $4, $1); + } ; verdict_stmt : verdict_expr -- cgit v1.2.3