From e6c32b2fa0b820bc81cbb99e8ed601eabbbfac69 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Mon, 1 Feb 2021 22:21:41 +0100 Subject: src: add negation match on singleton bitmask value This patch provides a shortcut for: ct status and dnat == 0 which allows to check for the packet whose dnat bit is unset: # nft add rule x y ct status ! dnat counter This operation is only available for expression with a bitmask basetype, eg. # nft describe ct status ct expression, datatype ct_status (conntrack status) (basetype bitmask, integer), 32 bits Signed-off-by: Pablo Neira Ayuso --- src/netlink_delinearize.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'src/netlink_delinearize.c') diff --git a/src/netlink_delinearize.c b/src/netlink_delinearize.c index 04560b97..7cd7d403 100644 --- a/src/netlink_delinearize.c +++ b/src/netlink_delinearize.c @@ -2167,7 +2167,7 @@ static void relational_binop_postprocess(struct rule_pp_ctx *ctx, struct expr *e { struct expr *binop = expr->left, *value = expr->right; - if (binop->op == OP_AND && expr->op == OP_NEQ && + if (binop->op == OP_AND && (expr->op == OP_NEQ || expr->op == OP_EQ) && value->dtype->basetype && value->dtype->basetype->type == TYPE_BITMASK && !mpz_cmp_ui(value->value, 0)) { @@ -2180,8 +2180,16 @@ static void relational_binop_postprocess(struct rule_pp_ctx *ctx, struct expr *e expr->left = expr_get(binop->left); expr->right = binop_tree_to_list(NULL, binop->right); - expr->op = OP_IMPLICIT; - + switch (expr->op) { + case OP_NEQ: + expr->op = OP_IMPLICIT; + break; + case OP_EQ: + expr->op = OP_NEG; + break; + default: + BUG("unknown operation type %d\n", expr->op); + } expr_free(binop); } else if (binop->left->dtype->flags & DTYPE_F_PREFIX && binop->op == OP_AND && expr->right->etype == EXPR_VALUE && -- cgit v1.2.3