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_linearize.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'src/netlink_linearize.c') diff --git a/src/netlink_linearize.c b/src/netlink_linearize.c index f1b3ff69..21bc492e 100644 --- a/src/netlink_linearize.c +++ b/src/netlink_linearize.c @@ -490,7 +490,11 @@ static void netlink_gen_flagcmp(struct netlink_linearize_ctx *ctx, nle = alloc_nft_expr("cmp"); netlink_put_register(nle, NFTNL_EXPR_CMP_SREG, sreg); - nftnl_expr_set_u32(nle, NFTNL_EXPR_CMP_OP, NFT_CMP_NEQ); + if (expr->op == OP_NEG) + nftnl_expr_set_u32(nle, NFTNL_EXPR_CMP_OP, NFT_CMP_EQ); + else + nftnl_expr_set_u32(nle, NFTNL_EXPR_CMP_OP, NFT_CMP_NEQ); + nftnl_expr_set(nle, NFTNL_EXPR_CMP_DATA, nld.value, nld.len); nft_rule_add_expr(ctx, nle, &expr->location); @@ -518,6 +522,7 @@ static void netlink_gen_relational(struct netlink_linearize_ctx *ctx, case OP_GT: case OP_LTE: case OP_GTE: + case OP_NEG: break; default: BUG("invalid relational operation %u\n", expr->op); @@ -547,7 +552,7 @@ static void netlink_gen_relational(struct netlink_linearize_ctx *ctx, } break; default: - if (expr->op == OP_IMPLICIT && + if ((expr->op == OP_IMPLICIT || expr->op == OP_NEG) && expr->right->dtype->basetype != NULL && expr->right->dtype->basetype->type == TYPE_BITMASK) return netlink_gen_flagcmp(ctx, expr, dreg); -- cgit v1.2.3