summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/meta.h4
-rw-r--r--src/meta.c36
-rw-r--r--src/parser_bison.y31
-rw-r--r--src/scanner.l2
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; }