All of lore.kernel.org
 help / color / mirror / Atom feed
From: Patrick McHardy <kaber@trash.net>
To: pablo@netfilter.org
Cc: netfilter-devel@vger.kernel.org
Subject: [PATCH nft 6/7] stmt: support generating stateful statements outside of rule context
Date: Wed, 27 Apr 2016 12:29:49 +0100	[thread overview]
Message-ID: <1461756590-22880-7-git-send-email-kaber@trash.net> (raw)
In-Reply-To: <1461756590-22880-1-git-send-email-kaber@trash.net>

The flow statement contains a stateful per flow statement, which is not
directly part of the rule. Allow generating these statements without adding
them to the rule and mark the supported statements using a new flag
STMT_F_STATEFUL.

Signed-off-by: Patrick McHardy <kaber@trash.net>
---
 include/statement.h     |  1 +
 src/netlink_linearize.c | 80 ++++++++++++++++++++++++++++++-------------------
 src/statement.c         | 12 ++++++--
 3 files changed, 61 insertions(+), 32 deletions(-)

diff --git a/include/statement.h b/include/statement.h
index e7872b0..a6a86f9 100644
--- a/include/statement.h
+++ b/include/statement.h
@@ -197,6 +197,7 @@ struct stmt_ops {
 
 enum stmt_flags {
 	STMT_F_TERMINAL		= 0x1,
+	STMT_F_STATEFUL		= 0x2,
 };
 
 /**
diff --git a/src/netlink_linearize.c b/src/netlink_linearize.c
index 3263043..28feecf 100644
--- a/src/netlink_linearize.c
+++ b/src/netlink_linearize.c
@@ -718,14 +718,9 @@ static void netlink_gen_expr(struct netlink_linearize_ctx *ctx,
 	}
 }
 
-static void netlink_gen_verdict_stmt(struct netlink_linearize_ctx *ctx,
-				     const struct stmt *stmt)
-{
-	return netlink_gen_expr(ctx, stmt->expr, NFT_REG_VERDICT);
-}
-
-static void netlink_gen_counter_stmt(struct netlink_linearize_ctx *ctx,
-				     const struct stmt *stmt)
+static struct nftnl_expr *
+netlink_gen_counter_stmt(struct netlink_linearize_ctx *ctx,
+			 const struct stmt *stmt)
 {
 	struct nftnl_expr *nle;
 
@@ -738,7 +733,46 @@ static void netlink_gen_counter_stmt(struct netlink_linearize_ctx *ctx,
 		nftnl_expr_set_u64(nle, NFTNL_EXPR_CTR_BYTES,
 				   stmt->counter.bytes);
 	}
-	nftnl_rule_add_expr(ctx->nlr, nle);
+
+	return nle;
+}
+
+static struct nftnl_expr *
+netlink_gen_limit_stmt(struct netlink_linearize_ctx *ctx,
+		       const struct stmt *stmt)
+{
+	struct nftnl_expr *nle;
+
+	nle = alloc_nft_expr("limit");
+	nftnl_expr_set_u64(nle, NFTNL_EXPR_LIMIT_RATE, stmt->limit.rate);
+	nftnl_expr_set_u64(nle, NFTNL_EXPR_LIMIT_UNIT, stmt->limit.unit);
+	nftnl_expr_set_u32(nle, NFTNL_EXPR_LIMIT_TYPE, stmt->limit.type);
+	if (stmt->limit.burst > 0)
+		nftnl_expr_set_u32(nle, NFTNL_EXPR_LIMIT_BURST,
+				   stmt->limit.burst);
+	nftnl_expr_set_u32(nle, NFTNL_EXPR_LIMIT_FLAGS, stmt->limit.flags);
+
+	return nle;
+}
+
+static struct nftnl_expr *
+netlink_gen_stmt_stateful(struct netlink_linearize_ctx *ctx,
+			  const struct stmt *stmt)
+{
+	switch (stmt->ops->type) {
+	case STMT_COUNTER:
+		return netlink_gen_counter_stmt(ctx, stmt);
+	case STMT_LIMIT:
+		return netlink_gen_limit_stmt(ctx, stmt);
+	default:
+		BUG("unknown stateful statement type %s\n", stmt->ops->name);
+	}
+}
+
+static void netlink_gen_verdict_stmt(struct netlink_linearize_ctx *ctx,
+				     const struct stmt *stmt)
+{
+	return netlink_gen_expr(ctx, stmt->expr, NFT_REG_VERDICT);
 }
 
 static void netlink_gen_payload_stmt(struct netlink_linearize_ctx *ctx,
@@ -821,23 +855,6 @@ static void netlink_gen_log_stmt(struct netlink_linearize_ctx *ctx,
 	nftnl_rule_add_expr(ctx->nlr, nle);
 }
 
-static void netlink_gen_limit_stmt(struct netlink_linearize_ctx *ctx,
-				   const struct stmt *stmt)
-{
-	struct nftnl_expr *nle;
-
-	nle = alloc_nft_expr("limit");
-	nftnl_expr_set_u64(nle, NFTNL_EXPR_LIMIT_RATE, stmt->limit.rate);
-	nftnl_expr_set_u64(nle, NFTNL_EXPR_LIMIT_UNIT, stmt->limit.unit);
-	nftnl_expr_set_u32(nle, NFTNL_EXPR_LIMIT_TYPE, stmt->limit.type);
-	if (stmt->limit.burst > 0)
-		nftnl_expr_set_u32(nle, NFTNL_EXPR_LIMIT_BURST,
-				   stmt->limit.burst);
-	nftnl_expr_set_u32(nle, NFTNL_EXPR_LIMIT_FLAGS, stmt->limit.flags);
-
-	nftnl_rule_add_expr(ctx->nlr, nle);
-}
-
 static void netlink_gen_reject_stmt(struct netlink_linearize_ctx *ctx,
 				    const struct stmt *stmt)
 {
@@ -1121,21 +1138,19 @@ static void netlink_gen_set_stmt(struct netlink_linearize_ctx *ctx,
 static void netlink_gen_stmt(struct netlink_linearize_ctx *ctx,
 			     const struct stmt *stmt)
 {
+	struct nftnl_expr *nle;
+
 	switch (stmt->ops->type) {
 	case STMT_EXPRESSION:
 		return netlink_gen_expr(ctx, stmt->expr, NFT_REG_VERDICT);
 	case STMT_VERDICT:
 		return netlink_gen_verdict_stmt(ctx, stmt);
-	case STMT_COUNTER:
-		return netlink_gen_counter_stmt(ctx, stmt);
 	case STMT_PAYLOAD:
 		return netlink_gen_payload_stmt(ctx, stmt);
 	case STMT_META:
 		return netlink_gen_meta_stmt(ctx, stmt);
 	case STMT_LOG:
 		return netlink_gen_log_stmt(ctx, stmt);
-	case STMT_LIMIT:
-		return netlink_gen_limit_stmt(ctx, stmt);
 	case STMT_REJECT:
 		return netlink_gen_reject_stmt(ctx, stmt);
 	case STMT_NAT:
@@ -1154,6 +1169,11 @@ static void netlink_gen_stmt(struct netlink_linearize_ctx *ctx,
 		return netlink_gen_set_stmt(ctx, stmt);
 	case STMT_FWD:
 		return netlink_gen_fwd_stmt(ctx, stmt);
+	case STMT_COUNTER:
+	case STMT_LIMIT:
+		nle = netlink_gen_stmt_stateful(ctx, stmt);
+		nftnl_rule_add_expr(ctx->nlr, nle);
+		break;
 	default:
 		BUG("unknown statement type %s\n", stmt->ops->name);
 	}
diff --git a/src/statement.c b/src/statement.c
index 2a6f19f..4149841 100644
--- a/src/statement.c
+++ b/src/statement.c
@@ -117,7 +117,11 @@ static const struct stmt_ops counter_stmt_ops = {
 
 struct stmt *counter_stmt_alloc(const struct location *loc)
 {
-	return stmt_alloc(loc, &counter_stmt_ops);
+	struct stmt *stmt;
+
+	stmt = stmt_alloc(loc, &counter_stmt_ops);
+	stmt->flags |= STMT_F_STATEFUL;
+	return stmt;
 }
 
 static const char *syslog_level[LOG_DEBUG + 1] = {
@@ -249,7 +253,11 @@ static const struct stmt_ops limit_stmt_ops = {
 
 struct stmt *limit_stmt_alloc(const struct location *loc)
 {
-	return stmt_alloc(loc, &limit_stmt_ops);
+	struct stmt *stmt;
+
+	stmt = stmt_alloc(loc, &limit_stmt_ops);
+	stmt->flags |= STMT_F_STATEFUL;
+	return stmt;
 }
 
 static void queue_stmt_print(const struct stmt *stmt)
-- 
2.5.5


  parent reply	other threads:[~2016-04-27 11:30 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-04-27 11:29 [PATCH nft 0/7] flow statement Patrick McHardy
2016-04-27 11:29 ` [PATCH nft 1/7] netlink: make dump functions object argument constant Patrick McHardy
2016-04-27 11:29 ` [PATCH nft 2/7] set: allow non-constant implicit set declarations Patrick McHardy
2016-04-27 11:29 ` [PATCH nft 3/7] set: explicitly supply name to " Patrick McHardy
2016-04-27 11:29 ` [PATCH nft 4/7] tests: update for changed set name Patrick McHardy
2016-04-27 11:29 ` [PATCH nft 5/7] netlink_delinearize: support parsing statements not contained within a rule Patrick McHardy
2016-04-27 11:29 ` Patrick McHardy [this message]
2016-04-27 11:29 ` [PATCH nft 7/7] nft: add flow statement Patrick McHardy
2016-04-27 16:37   ` Pablo Neira Ayuso
2016-05-13 18:12 ` [PATCH nft 0/7] " Pablo Neira Ayuso

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1461756590-22880-7-git-send-email-kaber@trash.net \
    --to=kaber@trash.net \
    --cc=netfilter-devel@vger.kernel.org \
    --cc=pablo@netfilter.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.