summaryrefslogtreecommitdiffstats
path: root/src/statement.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/statement.c')
-rw-r--r--src/statement.c45
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;