diff options
Diffstat (limited to 'src/statement.c')
-rw-r--r-- | src/statement.c | 45 |
1 files changed, 45 insertions, 0 deletions
diff --git a/src/statement.c b/src/statement.c index afedbba2..6fe8e9d9 100644 --- a/src/statement.c +++ b/src/statement.c @@ -15,6 +15,7 @@ #include <inttypes.h> #include <string.h> #include <syslog.h> +#include <rule.h> #include <arpa/inet.h> #include <linux/netfilter.h> @@ -112,6 +113,50 @@ struct stmt *verdict_stmt_alloc(const struct location *loc, struct expr *expr) return stmt; } +static const char *chain_verdict(const struct expr *expr) +{ + switch (expr->verdict) { + case NFT_JUMP: + return "jump"; + case NFT_GOTO: + return "goto"; + default: + BUG("unknown chain verdict"); + } +} + +static void chain_stmt_print(const struct stmt *stmt, struct output_ctx *octx) +{ + nft_print(octx, "%s {\n", chain_verdict(stmt->chain.expr)); + chain_rules_print(stmt->chain.chain, octx, "\t"); + nft_print(octx, "\t\t}"); +} + +static void chain_stmt_destroy(struct stmt *stmt) +{ + expr_free(stmt->chain.expr); +} + +static const struct stmt_ops chain_stmt_ops = { + .type = STMT_CHAIN, + .name = "chain", + .print = chain_stmt_print, + .destroy = chain_stmt_destroy, +}; + +struct stmt *chain_stmt_alloc(const struct location *loc, struct chain *chain, + enum nft_verdicts verdict) +{ + struct stmt *stmt; + + stmt = stmt_alloc(loc, &chain_stmt_ops); + stmt->chain.chain = chain; + stmt->chain.expr = verdict_expr_alloc(loc, verdict, NULL); + stmt->chain.expr->chain_id = chain->handle.chain_id; + + return stmt; +} + static void meter_stmt_print(const struct stmt *stmt, struct output_ctx *octx) { unsigned int flags = octx->flags; |