Since parsing of arphrd_type happens via sym_tbl, there is no dedicated parser function to perform the check in. So instead make use of maxval in expr_ctx to reject the value. While being at it, introduce a switch() to check for meta.key value in a single place. Signed-off-by: Phil Sutter <phil@xxxxxx> --- src/evaluate.c | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/src/evaluate.c b/src/evaluate.c index 55cd9d00d274c..ff52aefc669e0 100644 --- a/src/evaluate.c +++ b/src/evaluate.c @@ -23,6 +23,7 @@ #include <netinet/icmp6.h> #include <net/ethernet.h> #include <net/if.h> +#include <net/if_arp.h> #include <errno.h> #include <expression.h> @@ -1795,14 +1796,25 @@ static int expr_evaluate_fib(struct eval_ctx *ctx, struct expr **exprp) static int expr_evaluate_meta(struct eval_ctx *ctx, struct expr **exprp) { struct expr *meta = *exprp; + unsigned int maxval = 0; - if (ctx->pctx.family != NFPROTO_INET && - meta->flags & EXPR_F_PROTOCOL && - meta->meta.key == NFT_META_NFPROTO) + switch (meta->meta.key) { + case NFT_META_NFPROTO: + if (ctx->pctx.family == NFPROTO_INET || + !(meta->flags & EXPR_F_PROTOCOL)) + break; return expr_error(ctx->msgs, meta, - "meta nfproto is only useful in the inet family"); - - return expr_evaluate_primary(ctx, exprp); + "meta nfproto is only useful in the inet family"); + case NFT_META_IIFTYPE: + case NFT_META_OIFTYPE: + maxval = ARPHRD_VOID - 1; + break; + default: + break; + } + __expr_set_context(&ctx->ectx, (*exprp)->dtype, (*exprp)->byteorder, + (*exprp)->len, maxval); + return 0; } static int expr_evaluate_socket(struct eval_ctx *ctx, struct expr **expr) -- 2.22.0