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 <fw@strlen.de>
Acked-by: Pablo Neira Ayuso <pablo@netfilter.org>
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 */
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);
+}
%token MH "mh"
%token META "meta"
-%token NFPROTO "nfproto"
-%token L4PROTO "l4proto"
%token MARK "mark"
%token IIF "iif"
%token IIFNAME "iifname"
{
$$ = 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; }
{
$$ = 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; }
"mh" { return MH; }
"meta" { return META; }
-"nfproto" { return NFPROTO; }
-"l4proto" { return L4PROTO; }
"mark" { return MARK; }
"iif" { return IIF; }
"iifname" { return IIFNAME; }