summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPhil Sutter <phil@nwl.cc>2017-03-11 14:31:39 +0100
committerPablo Neira Ayuso <pablo@netfilter.org>2017-03-13 12:13:43 +0100
commitf686a17eafa0bb5e9b0665c646fac09c9f95c0a5 (patch)
treea120b7e5ecc815f9daef482f1e9159021f8d00fb /src
parentc6cd7c22548a545ea9a831a1ea725d1716295b4a (diff)
fib: Support existence check
This allows to check whether a FIB entry exists for a given packet by comparing the expression with a boolean keyword like so: | fib daddr oif exists The implementation requires introduction of a generic expression flag EXPR_F_BOOLEAN which allows relational expression to signal it's LHS that a boolean comparison is being done (indicated by boolean type on RHS). In contrast to exthdr existence checks, fib expression can't know this in beforehand because the LHS syntax is absolutely identical to a non-boolean comparison. Signed-off-by: Phil Sutter <phil@nwl.cc> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'src')
-rw-r--r--src/evaluate.c14
-rw-r--r--src/expression.c4
-rw-r--r--src/fib.c5
3 files changed, 21 insertions, 2 deletions
diff --git a/src/evaluate.c b/src/evaluate.c
index 7c039cba..7ddbb658 100644
--- a/src/evaluate.c
+++ b/src/evaluate.c
@@ -1658,6 +1658,17 @@ range:
return 0;
}
+static int expr_evaluate_fib(struct eval_ctx *ctx, struct expr **exprp)
+{
+ struct expr *expr = *exprp;
+
+ if (expr->flags & EXPR_F_BOOLEAN) {
+ expr->fib.flags |= NFTA_FIB_F_PRESENT;
+ expr->dtype = &boolean_type;
+ }
+ return expr_evaluate_primary(ctx, exprp);
+}
+
static int expr_evaluate(struct eval_ctx *ctx, struct expr **expr)
{
#ifdef DEBUG
@@ -1680,8 +1691,9 @@ static int expr_evaluate(struct eval_ctx *ctx, struct expr **expr)
return expr_evaluate_exthdr(ctx, expr);
case EXPR_VERDICT:
case EXPR_META:
- case EXPR_FIB:
return expr_evaluate_primary(ctx, expr);
+ case EXPR_FIB:
+ return expr_evaluate_fib(ctx, expr);
case EXPR_PAYLOAD:
return expr_evaluate_payload(ctx, expr);
case EXPR_RT:
diff --git a/src/expression.c b/src/expression.c
index da94b79f..a6065524 100644
--- a/src/expression.c
+++ b/src/expression.c
@@ -592,6 +592,10 @@ struct expr *relational_expr_alloc(const struct location *loc, enum ops op,
expr->left = left;
expr->op = op;
expr->right = right;
+
+ if (right->dtype == &boolean_type)
+ left->flags |= EXPR_F_BOOLEAN;
+
return expr;
}
diff --git a/src/fib.c b/src/fib.c
index c65677c8..28ef4b50 100644
--- a/src/fib.c
+++ b/src/fib.c
@@ -73,7 +73,7 @@ static void __fib_expr_print_f(unsigned int *flags, unsigned int f, const char *
static void fib_expr_print(const struct expr *expr)
{
- unsigned int flags = expr->fib.flags;
+ unsigned int flags = expr->fib.flags & ~NFTA_FIB_F_PRESENT;
printf("fib ");
__fib_expr_print_f(&flags, NFTA_FIB_F_SADDR, "saddr");
@@ -130,6 +130,9 @@ struct expr *fib_expr_alloc(const struct location *loc,
BUG("Unknown result %d\n", result);
}
+ if (flags & NFTA_FIB_F_PRESENT)
+ type = &boolean_type;
+
expr = expr_alloc(loc, &fib_expr_ops, type,
BYTEORDER_HOST_ENDIAN, len);