* @EXPR_FIB forward information base expression
* @EXPR_XFRM XFRM (ipsec) expression
* @EXPR_SET_ELEM_CATCHALL catchall element expression
- * @EXPR_FLAGCMP flagcmp expression
* @EXPR_RANGE_VALUE constant range expression
* @EXPR_RANGE_SYMBOL unparse symbol range expression
*/
EXPR_FIB,
EXPR_XFRM,
EXPR_SET_ELEM_CATCHALL,
- EXPR_FLAGCMP,
EXPR_RANGE_VALUE,
EXPR_RANGE_SYMBOL,
__EXPR_MAX
uint8_t ttl;
uint32_t flags;
} osf;
- struct {
- /* EXPR_FLAGCMP */
- struct expr *expr;
- struct expr *mask;
- struct expr *value;
- } flagcmp;
};
};
struct expr *set_elem_catchall_expr_alloc(const struct location *loc);
-struct expr *flagcmp_expr_alloc(const struct location *loc, enum ops op,
- struct expr *expr, struct expr *mask,
- struct expr *value);
-
extern void range_expr_value_low(mpz_t rop, const struct expr *expr);
extern void range_expr_value_high(mpz_t rop, const struct expr *expr);
void range_expr_swap_values(struct expr *range);
json_t *binop_expr_json(const struct expr *expr, struct output_ctx *octx);
json_t *relational_expr_json(const struct expr *expr, struct output_ctx *octx);
-json_t *flagcmp_expr_json(const struct expr *expr, struct output_ctx *octx);
json_t *range_expr_json(const struct expr *expr, struct output_ctx *octx);
json_t *meta_expr_json(const struct expr *expr, struct output_ctx *octx);
json_t *payload_expr_json(const struct expr *expr, struct output_ctx *octx);
JSON_PRINT_STUB(name##_stmt, const struct stmt *, struct output_ctx *)
EXPR_PRINT_STUB(binop_expr)
-EXPR_PRINT_STUB(flagcmp_expr)
EXPR_PRINT_STUB(relational_expr)
EXPR_PRINT_STUB(range_expr)
EXPR_PRINT_STUB(meta_expr)
return expr_evaluate_primary(ctx, exprp);
}
-static int expr_evaluate_flagcmp(struct eval_ctx *ctx, struct expr **exprp)
-{
- struct expr *expr = *exprp, *binop, *rel;
-
- if (expr->op != OP_EQ &&
- expr->op != OP_NEQ)
- return expr_error(ctx->msgs, expr, "either == or != is allowed");
-
- binop = binop_expr_alloc(&expr->location, OP_AND,
- expr_get(expr->flagcmp.expr),
- expr_get(expr->flagcmp.mask));
- rel = relational_expr_alloc(&expr->location, expr->op, binop,
- expr_get(expr->flagcmp.value));
- expr_free(expr);
- *exprp = rel;
-
- return expr_evaluate(ctx, exprp);
-}
-
static int verdict_validate_chainlen(struct eval_ctx *ctx,
struct expr *chain)
{
return expr_evaluate_xfrm(ctx, expr);
case EXPR_SET_ELEM_CATCHALL:
return expr_evaluate_set_elem_catchall(ctx, expr);
- case EXPR_FLAGCMP:
- return expr_evaluate_flagcmp(ctx, expr);
case EXPR_RANGE_SYMBOL:
return expr_evaluate_symbol_range(ctx, expr);
default:
return expr;
}
-static void flagcmp_expr_print(const struct expr *expr, struct output_ctx *octx)
-{
- expr_print(expr->flagcmp.expr, octx);
-
- if (expr->op == OP_NEQ)
- nft_print(octx, " != ");
- else
- nft_print(octx, " ");
-
- expr_print(expr->flagcmp.value, octx);
- nft_print(octx, " / ");
- expr_print(expr->flagcmp.mask, octx);
-}
-
-static void flagcmp_expr_clone(struct expr *new, const struct expr *expr)
-{
- new->flagcmp.expr = expr_clone(expr->flagcmp.expr);
- new->flagcmp.mask = expr_clone(expr->flagcmp.mask);
- new->flagcmp.value = expr_clone(expr->flagcmp.value);
-}
-
-static void flagcmp_expr_destroy(struct expr *expr)
-{
- expr_free(expr->flagcmp.expr);
- expr_free(expr->flagcmp.mask);
- expr_free(expr->flagcmp.value);
-}
-
-static const struct expr_ops flagcmp_expr_ops = {
- .type = EXPR_FLAGCMP,
- .name = "flags comparison",
- .print = flagcmp_expr_print,
- .json = flagcmp_expr_json,
- .clone = flagcmp_expr_clone,
- .destroy = flagcmp_expr_destroy,
-};
-
-struct expr *flagcmp_expr_alloc(const struct location *loc, enum ops op,
- struct expr *match, struct expr *mask,
- struct expr *value)
-{
- struct expr *expr;
-
- expr = expr_alloc(loc, EXPR_FLAGCMP, match->dtype, match->byteorder,
- match->len);
- expr->op = op;
- expr->flagcmp.expr = match;
- expr->flagcmp.mask = mask;
- /* json output needs this operation for compatibility */
- expr->flagcmp.mask->op = OP_OR;
- expr->flagcmp.value = value;
-
- return expr;
-}
-
void range_expr_value_low(mpz_t rop, const struct expr *expr)
{
switch (expr->etype) {
case EXPR_FIB: return &fib_expr_ops;
case EXPR_XFRM: return &xfrm_expr_ops;
case EXPR_SET_ELEM_CATCHALL: return &set_elem_catchall_expr_ops;
- case EXPR_FLAGCMP: return &flagcmp_expr_ops;
case EXPR_RANGE_VALUE: return &constant_range_expr_ops;
case EXPR_RANGE_SYMBOL: return &symbol_range_expr_ops;
case __EXPR_MAX: break;
return json_pack("{s:o}", "table", root);
}
-json_t *flagcmp_expr_json(const struct expr *expr, struct output_ctx *octx)
-{
- json_t *left;
-
- left = json_pack("{s:[o, o]}", expr_op_symbols[OP_AND],
- expr_print_json(expr->flagcmp.expr, octx),
- expr_print_json(expr->flagcmp.mask, octx));
-
- return json_pack("{s:{s:s, s:o, s:o}}", "match",
- "op", expr_op_symbols[expr->op] ? : "in",
- "left", left,
- "right", expr_print_json(expr->flagcmp.value, octx));
-}
-
static json_t *
__binop_expr_json(int op, const struct expr *expr, struct output_ctx *octx)
{