From 93d44351bbe2b4cf6b567e3b356ff797866cdc04 Mon Sep 17 00:00:00 2001 From: Florian Westphal Date: Wed, 27 Jul 2016 09:42:38 +0200 Subject: meta: allow resolving meta keys at run time use the meta template to translate the textual token to the enum value. This allows to remove two keywords from the scanner and also means we do not need to introduce new keywords when more meta keys get added. Signed-off-by: Florian Westphal Acked-by: Pablo Neira Ayuso --- include/meta.h | 4 ++++ src/meta.c | 36 ++++++++++++++++++++++++++++++++++++ src/parser_bison.y | 31 ++++++++++++++++++++++++++----- src/scanner.l | 2 -- 4 files changed, 66 insertions(+), 7 deletions(-) diff --git a/include/meta.h b/include/meta.h index f25b147a..55784609 100644 --- a/include/meta.h +++ b/include/meta.h @@ -30,4 +30,8 @@ struct stmt *meta_stmt_meta_iiftype(const struct location *loc, uint16_t type); const struct datatype ifindex_type; +struct error_record *meta_key_parse(const struct location *loc, + const char *name, + unsigned int *value); + #endif /* NFTABLES_META_H */ diff --git a/src/meta.c b/src/meta.c index bd1e4f28..574fc500 100644 --- a/src/meta.c +++ b/src/meta.c @@ -640,3 +640,39 @@ struct stmt *meta_stmt_meta_iiftype(const struct location *loc, uint16_t type) dep = relational_expr_alloc(loc, OP_EQ, left, right); return expr_stmt_alloc(&dep->location, dep); } + +struct error_record *meta_key_parse(const struct location *loc, + const char *str, + unsigned int *value) +{ + int ret, len, offset = 0; + const char *sep = ""; + unsigned int i; + char buf[1024]; + size_t size; + + for (i = 0; i < array_size(meta_templates); i++) { + if (!meta_templates[i].token || strcmp(meta_templates[i].token, str)) + continue; + + *value = i; + return NULL; + } + + len = (int)sizeof(buf); + size = sizeof(buf); + + for (i = 0; i < array_size(meta_templates); i++) { + if (!meta_templates[i].token) + continue; + + if (offset) + sep = ", "; + + ret = snprintf(buf+offset, len, "%s%s", sep, meta_templates[i].token); + SNPRINTF_BUFFER_SIZE(ret, size, len, offset); + assert(offset < (int)sizeof(buf)); + } + + return error(loc, "syntax error, unexpected %s, known keys are %s", str, buf); +} diff --git a/src/parser_bison.y b/src/parser_bison.y index 1730b8d3..ec9052af 100644 --- a/src/parser_bison.y +++ b/src/parser_bison.y @@ -319,8 +319,6 @@ static void location_update(struct location *loc, struct location *rhs, int n) %token MH "mh" %token META "meta" -%token NFPROTO "nfproto" -%token L4PROTO "l4proto" %token MARK "mark" %token IIF "iif" %token IIFNAME "iifname" @@ -2443,15 +2441,25 @@ meta_expr : META meta_key { $$ = meta_expr_alloc(&@$, $1); } - ; + | META STRING + { + struct error_record *erec; + unsigned int key; + + erec = meta_key_parse(&@$, $2, &key); + if (erec != NULL) { + erec_queue(erec, state->msgs); + YYERROR; + } + + $$ = meta_expr_alloc(&@$, key); + } meta_key : meta_key_qualified | meta_key_unqualified ; meta_key_qualified : LENGTH { $$ = NFT_META_LEN; } - | NFPROTO { $$ = NFT_META_NFPROTO; } - | L4PROTO { $$ = NFT_META_L4PROTO; } | PROTOCOL { $$ = NFT_META_PROTOCOL; } | PRIORITY { $$ = NFT_META_PRIORITY; } | RANDOM { $$ = NFT_META_PRANDOM; } @@ -2485,6 +2493,19 @@ meta_stmt : META meta_key SET expr { $$ = meta_stmt_alloc(&@$, $1, $3); } + | META STRING SET expr + { + struct error_record *erec; + unsigned int key; + + erec = meta_key_parse(&@$, $2, &key); + if (erec != NULL) { + erec_queue(erec, state->msgs); + YYERROR; + } + + $$ = meta_stmt_alloc(&@$, key, $4); + } ; offset_opt : /* empty */ { $$ = 0; } diff --git a/src/scanner.l b/src/scanner.l index 2ddcad94..8afddf15 100644 --- a/src/scanner.l +++ b/src/scanner.l @@ -427,8 +427,6 @@ addrstring ({macaddr}|{ip4addr}|{ip6addr}) "mh" { return MH; } "meta" { return META; } -"nfproto" { return NFPROTO; } -"l4proto" { return L4PROTO; } "mark" { return MARK; } "iif" { return IIF; } "iifname" { return IIFNAME; } -- cgit v1.2.3