netfilter-devel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [RFC 1/4] statement: make secmark statements idempotent
@ 2019-11-20 17:43 Christian Göttsche
  2019-11-20 17:43 ` [RFC 2/4] src: add ability to set/get secmarks to/from connection Christian Göttsche
                   ` (3 more replies)
  0 siblings, 4 replies; 9+ messages in thread
From: Christian Göttsche @ 2019-11-20 17:43 UTC (permalink / raw)
  To: netfilter-devel

Currently lines like

    ct state new meta secmark set tcp dport map @secmapping_in

become

    ct state new secmark name tcp dport map @secmapping_in

fixes: 3bc84e5c1fdd1ff011af9788fe174e0514c2c9ea

Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
---
 src/statement.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/src/statement.c b/src/statement.c
index af84e06c..be35bcef 100644
--- a/src/statement.c
+++ b/src/statement.c
@@ -233,6 +233,9 @@ static void objref_stmt_print(const struct stmt *stmt, struct output_ctx *octx)
 	case NFT_OBJECT_CT_EXPECT:
 		nft_print(octx, "ct expectation set ");
 		break;
+	case NFT_OBJECT_SECMARK:
+		nft_print(octx, "meta secmark set ");
+		break;
 	default:
 		nft_print(octx, "%s name ",
 			  objref_type_name(stmt->objref.type));
-- 
2.24.0


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [RFC 2/4] src: add ability to set/get secmarks to/from connection
  2019-11-20 17:43 [RFC 1/4] statement: make secmark statements idempotent Christian Göttsche
@ 2019-11-20 17:43 ` Christian Göttsche
  2019-11-21 13:06   ` Pablo Neira Ayuso
  2019-11-20 17:43 ` [RFC 3/4] files: add example secmark config Christian Göttsche
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 9+ messages in thread
From: Christian Göttsche @ 2019-11-20 17:43 UTC (permalink / raw)
  To: netfilter-devel

Labeling established and related packets requires the secmark to be stored in the connection.
Add the ability to store and retrieve secmarks like:

    ...
    chain input {
        ...

        # label new incoming packets
        ct state new meta secmark set tcp dport map @secmapping_in

        # add label to connection
        ct state new ct secmark set meta secmark

        # set label for est/rel packets from connection
        ct state established,related meta secmark set ct secmark

        ...
    }
    ...
    chain output {
        ...

        # label new outgoing packets
        ct state new meta secmark set tcp dport map @secmapping_out

        # add label to connection
        ct state new ct secmark set meta secmark

        # set label for est/rel packets from connection
        ct state established,related meta secmark set ct secmark

        ...
        }
    ...

improves: 3bc84e5c1fdd1ff011af9788fe174e0514c2c9ea

Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
---
 src/ct.c           |  2 ++
 src/evaluate.c     | 10 ++++++++++
 src/meta.c         |  2 ++
 src/parser_bison.y | 14 +++++++++++---
 4 files changed, 25 insertions(+), 3 deletions(-)

diff --git a/src/ct.c b/src/ct.c
index ed458e6b..9e6a8351 100644
--- a/src/ct.c
+++ b/src/ct.c
@@ -299,6 +299,8 @@ const struct ct_template ct_templates[__NFT_CT_MAX] = {
 					      BYTEORDER_BIG_ENDIAN, 128),
 	[NFT_CT_DST_IP6]	= CT_TEMPLATE("ip6 daddr", &ip6addr_type,
 					      BYTEORDER_BIG_ENDIAN, 128),
+	[NFT_CT_SECMARK]	= CT_TEMPLATE("secmark", &integer_type,
+					      BYTEORDER_HOST_ENDIAN, 32),
 };
 
 static void ct_print(enum nft_ct_keys key, int8_t dir, uint8_t nfproto,
diff --git a/src/evaluate.c b/src/evaluate.c
index e54eaf1a..740d3c30 100644
--- a/src/evaluate.c
+++ b/src/evaluate.c
@@ -1794,6 +1794,16 @@ static int expr_evaluate_relational(struct eval_ctx *ctx, struct expr **expr)
 		if (expr_is_singleton(right))
 			relational_expr_pctx_update(&ctx->pctx, rel);
 
+		/*
+		 * Statements like 'ct secmark 12 counter' are parsed as
+		 * relational expression with implicit operator.
+		 * Make them invalid.
+		 */
+		if ((left->etype == EXPR_META && left->meta.key == NFT_META_SECMARK)
+			|| (left->etype == EXPR_CT && left->ct.key == NFT_CT_SECMARK))
+			return expr_error(ctx->msgs, *expr,
+                                          "secmark is invalid with hardcoded ids");
+
 		/* fall through */
 	case OP_NEQ:
 		switch (right->etype) {
diff --git a/src/meta.c b/src/meta.c
index 69a897a9..796d8e94 100644
--- a/src/meta.c
+++ b/src/meta.c
@@ -698,6 +698,8 @@ const struct meta_template meta_templates[] = {
 	[NFT_META_TIME_HOUR]	= META_TEMPLATE("hour", &hour_type,
 						4 * BITS_PER_BYTE,
 						BYTEORDER_HOST_ENDIAN),
+	[NFT_META_SECMARK]	= META_TEMPLATE("secmark", &integer_type,
+						32, BYTEORDER_HOST_ENDIAN),
 };
 
 static bool meta_key_is_unqualified(enum nft_meta_keys key)
diff --git a/src/parser_bison.y b/src/parser_bison.y
index 631b7d68..707f4671 100644
--- a/src/parser_bison.y
+++ b/src/parser_bison.y
@@ -4190,9 +4190,16 @@ meta_stmt		:	META	meta_key	SET	stmt_expr
 			{
 				switch ($2) {
 				case NFT_META_SECMARK:
-					$$ = objref_stmt_alloc(&@$);
-					$$->objref.type = NFT_OBJECT_SECMARK;
-					$$->objref.expr = $4;
+					switch ($4->etype) {
+					case EXPR_CT:
+						$$ = meta_stmt_alloc(&@$, $2, $4);
+						break;
+					default:
+						$$ = objref_stmt_alloc(&@$);
+						$$->objref.type = NFT_OBJECT_SECMARK;
+						$$->objref.expr = $4;
+						break;
+					}
 					break;
 				default:
 					$$ = meta_stmt_alloc(&@$, $2, $4);
@@ -4388,6 +4395,7 @@ ct_key			:	L3PROTOCOL	{ $$ = NFT_CT_L3PROTOCOL; }
 			|	PROTO_DST	{ $$ = NFT_CT_PROTO_DST; }
 			|	LABEL		{ $$ = NFT_CT_LABELS; }
 			|	EVENT		{ $$ = NFT_CT_EVENTMASK; }
+			|	SECMARK		{ $$ = NFT_CT_SECMARK; }
 			|	ct_key_dir_optional
 			;
 
-- 
2.24.0


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [RFC 3/4] files: add example secmark config
  2019-11-20 17:43 [RFC 1/4] statement: make secmark statements idempotent Christian Göttsche
  2019-11-20 17:43 ` [RFC 2/4] src: add ability to set/get secmarks to/from connection Christian Göttsche
@ 2019-11-20 17:43 ` Christian Göttsche
  2019-11-21 13:06   ` Pablo Neira Ayuso
  2019-11-20 17:43 ` [RFC 4/4] src: add ability to reset secmarks Christian Göttsche
  2019-11-21 13:05 ` [RFC 1/4] statement: make secmark statements idempotent Pablo Neira Ayuso
  3 siblings, 1 reply; 9+ messages in thread
From: Christian Göttsche @ 2019-11-20 17:43 UTC (permalink / raw)
  To: netfilter-devel

Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
---
 files/examples/Makefile.am |  1 +
 files/examples/secmark.nft | 85 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 86 insertions(+)
 create mode 100755 files/examples/secmark.nft

diff --git a/files/examples/Makefile.am b/files/examples/Makefile.am
index c40e041e..b29e9f61 100644
--- a/files/examples/Makefile.am
+++ b/files/examples/Makefile.am
@@ -1,4 +1,5 @@
 pkgdocdir = ${docdir}/examples
 dist_pkgdoc_SCRIPTS = ct_helpers.nft \
 		load_balancing.nft \
+		secmark.nft \
 		sets_and_maps.nft
diff --git a/files/examples/secmark.nft b/files/examples/secmark.nft
new file mode 100755
index 00000000..0e010056
--- /dev/null
+++ b/files/examples/secmark.nft
@@ -0,0 +1,85 @@
+#!/usr/sbin/nft -f
+
+# This example file shows how to use secmark labels with the nftables framework.
+# This script is meant to be loaded with `nft -f <file>`
+# You require linux kernel >= 4.20 and nft >= 0.9.3
+# For up-to-date information please visit https://wiki.nftables.org
+
+
+flush ruleset
+
+table inet filter {
+	secmark ssh_server {
+		"system_u:object_r:ssh_server_packet_t:s0"
+	}
+
+	secmark dns_client {
+		"system_u:object_r:dns_client_packet_t:s0"
+	}
+
+	secmark http_client {
+		"system_u:object_r:http_client_packet_t:s0"
+	}
+
+	secmark https_client {
+		"system_u:object_r:http_client_packet_t:s0"
+	}
+
+	secmark ntp_client {
+		"system_u:object_r:ntp_client_packet_t:s0"
+	}
+
+	secmark icmp_client {
+		"system_u:object_r:icmp_client_packet_t:s0"
+	}
+
+	secmark icmp_server {
+		"system_u:object_r:icmp_server_packet_t:s0"
+	}
+
+	secmark ssh_client {
+		"system_u:object_r:ssh_client_packet_t:s0"
+	}
+
+	secmark git_client {
+		"system_u:object_r:git_client_packet_t:s0"
+	}
+
+	map secmapping_in {
+		type inet_service : secmark
+		elements = { 22 : "ssh_server" }
+	}
+
+	map secmapping_out {
+		type inet_service : secmark
+		elements = { 22 : "ssh_client", 53 : "dns_client", 80 : "http_client", 123 : "ntp_client", 443 : "http_client", 9418 : "git_client" }
+	}
+
+	chain input {
+		type filter hook input priority 0;
+
+		# label new incoming packets and add to connection
+		ct state new meta secmark set tcp dport map @secmapping_in
+		ct state new meta secmark set udp dport map @secmapping_in
+		ct state new ip protocol icmp meta secmark set "icmp_server"
+		ct state new ip6 nexthdr icmpv6 meta secmark set "icmp_server"
+		ct state new ct secmark set meta secmark
+
+		# set label for est/rel packets from connection
+		ct state established,related meta secmark set ct secmark
+	}
+
+	chain output {
+		type filter hook output priority 0;
+
+		# label new outgoing packets and add to connection
+		ct state new meta secmark set tcp dport map @secmapping_out
+		ct state new meta secmark set udp dport map @secmapping_out
+		ct state new ip protocol icmp meta secmark set "icmp_client"
+		ct state new ip6 nexthdr icmpv6 meta secmark set "icmp_client"
+		ct state new ct secmark set meta secmark
+
+		# set label for est/rel packets from connection
+		ct state established,related meta secmark set ct secmark
+	}
+}
-- 
2.24.0


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [RFC 4/4] src: add ability to reset secmarks
  2019-11-20 17:43 [RFC 1/4] statement: make secmark statements idempotent Christian Göttsche
  2019-11-20 17:43 ` [RFC 2/4] src: add ability to set/get secmarks to/from connection Christian Göttsche
  2019-11-20 17:43 ` [RFC 3/4] files: add example secmark config Christian Göttsche
@ 2019-11-20 17:43 ` Christian Göttsche
  2019-11-21 13:08   ` Pablo Neira Ayuso
  2019-11-21 13:05 ` [RFC 1/4] statement: make secmark statements idempotent Pablo Neira Ayuso
  3 siblings, 1 reply; 9+ messages in thread
From: Christian Göttsche @ 2019-11-20 17:43 UTC (permalink / raw)
  To: netfilter-devel

Add the ability to reset secmark associations between the user-end string representation and the kernel intern secid.
This allows a lightweight reset, without reloading the whole configuration and resetting all counters etc. .

*TODO*:
Pablo suggested to drop this change.
Are the actual objects in the kernel not destroyed and recreated?
Or is this functionality useless?

Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
---
 src/evaluate.c     |  2 ++
 src/parser_bison.y | 12 ++++++++++++
 src/rule.c         |  6 ++++++
 3 files changed, 20 insertions(+)

diff --git a/src/evaluate.c b/src/evaluate.c
index 740d3c30..cebc33d3 100644
--- a/src/evaluate.c
+++ b/src/evaluate.c
@@ -3982,8 +3982,10 @@ static int cmd_evaluate_reset(struct eval_ctx *ctx, struct cmd *cmd)
 	switch (cmd->obj) {
 	case CMD_OBJ_COUNTER:
 	case CMD_OBJ_QUOTA:
+	case CMD_OBJ_SECMARK:
 	case CMD_OBJ_COUNTERS:
 	case CMD_OBJ_QUOTAS:
+	case CMD_OBJ_SECMARKS:
 		if (cmd->handle.table.name == NULL)
 			return 0;
 		if (table_lookup(&cmd->handle, &ctx->nft->cache) == NULL)
diff --git a/src/parser_bison.y b/src/parser_bison.y
index 707f4671..eb767547 100644
--- a/src/parser_bison.y
+++ b/src/parser_bison.y
@@ -1375,6 +1375,18 @@ reset_cmd		:	COUNTERS	ruleset_spec
 			{
 				$$ = cmd_alloc(CMD_RESET, CMD_OBJ_QUOTA, &$2, &@$, NULL);
 			}
+			|	SECMARKS	ruleset_spec
+			{
+				$$ = cmd_alloc(CMD_RESET, CMD_OBJ_SECMARKS, &$2, &@$, NULL);
+			}
+			|	SECMARKS	TABLE	table_spec
+			{
+				$$ = cmd_alloc(CMD_RESET, CMD_OBJ_SECMARKS, &$3, &@$, NULL);
+			}
+			|	SECMARK		obj_spec
+			{
+				$$ = cmd_alloc(CMD_RESET, CMD_OBJ_SECMARK, &$2, &@$, NULL);
+			}
 			;
 
 flush_cmd		:	TABLE		table_spec
diff --git a/src/rule.c b/src/rule.c
index 4abc13c9..08b04827 100644
--- a/src/rule.c
+++ b/src/rule.c
@@ -2539,6 +2539,12 @@ static int do_command_reset(struct netlink_ctx *ctx, struct cmd *cmd)
 	case CMD_OBJ_QUOTA:
 		type = NFT_OBJECT_QUOTA;
 		break;
+	case CMD_OBJ_SECMARKS:
+		dump = true;
+		/* fall through */
+	case CMD_OBJ_SECMARK:
+		type = NFT_OBJECT_SECMARK;
+		break;
 	default:
 		BUG("invalid command object type %u\n", cmd->obj);
 	}
-- 
2.24.0


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [RFC 1/4] statement: make secmark statements idempotent
  2019-11-20 17:43 [RFC 1/4] statement: make secmark statements idempotent Christian Göttsche
                   ` (2 preceding siblings ...)
  2019-11-20 17:43 ` [RFC 4/4] src: add ability to reset secmarks Christian Göttsche
@ 2019-11-21 13:05 ` Pablo Neira Ayuso
  3 siblings, 0 replies; 9+ messages in thread
From: Pablo Neira Ayuso @ 2019-11-21 13:05 UTC (permalink / raw)
  To: Christian Göttsche; +Cc: netfilter-devel

On Wed, Nov 20, 2019 at 06:43:54PM +0100, Christian Göttsche wrote:
> Currently lines like
> 
>     ct state new meta secmark set tcp dport map @secmapping_in
> 
> become
> 
>     ct state new secmark name tcp dport map @secmapping_in

Applied, thanks.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [RFC 2/4] src: add ability to set/get secmarks to/from connection
  2019-11-20 17:43 ` [RFC 2/4] src: add ability to set/get secmarks to/from connection Christian Göttsche
@ 2019-11-21 13:06   ` Pablo Neira Ayuso
  2019-11-21 13:27     ` Pablo Neira Ayuso
  0 siblings, 1 reply; 9+ messages in thread
From: Pablo Neira Ayuso @ 2019-11-21 13:06 UTC (permalink / raw)
  To: Christian Göttsche; +Cc: netfilter-devel

On Wed, Nov 20, 2019 at 06:43:55PM +0100, Christian Göttsche wrote:
> Labeling established and related packets requires the secmark to be stored in the connection.
> Add the ability to store and retrieve secmarks like:
> 
>     ...
>     chain input {
>         ...
> 
>         # label new incoming packets
>         ct state new meta secmark set tcp dport map @secmapping_in
> 
>         # add label to connection
>         ct state new ct secmark set meta secmark
> 
>         # set label for est/rel packets from connection
>         ct state established,related meta secmark set ct secmark
> 
>         ...
>     }
>     ...
>     chain output {
>         ...
> 
>         # label new outgoing packets
>         ct state new meta secmark set tcp dport map @secmapping_out
> 
>         # add label to connection
>         ct state new ct secmark set meta secmark
> 
>         # set label for est/rel packets from connection
>         ct state established,related meta secmark set ct secmark
> 
>         ...
>         }
>     ...

I have applied this with minor changes on the evaluation side. Just
follow up with another patch in case you find any issue.

Thanks.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [RFC 3/4] files: add example secmark config
  2019-11-20 17:43 ` [RFC 3/4] files: add example secmark config Christian Göttsche
@ 2019-11-21 13:06   ` Pablo Neira Ayuso
  0 siblings, 0 replies; 9+ messages in thread
From: Pablo Neira Ayuso @ 2019-11-21 13:06 UTC (permalink / raw)
  To: Christian Göttsche; +Cc: netfilter-devel

This patch does not apply here to current git HEAD for some reason.

On Wed, Nov 20, 2019 at 06:43:56PM +0100, Christian Göttsche wrote:
> Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
> ---
>  files/examples/Makefile.am |  1 +
>  files/examples/secmark.nft | 85 ++++++++++++++++++++++++++++++++++++++
>  2 files changed, 86 insertions(+)
>  create mode 100755 files/examples/secmark.nft
> 
> diff --git a/files/examples/Makefile.am b/files/examples/Makefile.am
> index c40e041e..b29e9f61 100644
> --- a/files/examples/Makefile.am
> +++ b/files/examples/Makefile.am
> @@ -1,4 +1,5 @@
>  pkgdocdir = ${docdir}/examples
>  dist_pkgdoc_SCRIPTS = ct_helpers.nft \
>  		load_balancing.nft \
> +		secmark.nft \
>  		sets_and_maps.nft
> diff --git a/files/examples/secmark.nft b/files/examples/secmark.nft
> new file mode 100755
> index 00000000..0e010056
> --- /dev/null
> +++ b/files/examples/secmark.nft
> @@ -0,0 +1,85 @@
> +#!/usr/sbin/nft -f
> +
> +# This example file shows how to use secmark labels with the nftables framework.
> +# This script is meant to be loaded with `nft -f <file>`
> +# You require linux kernel >= 4.20 and nft >= 0.9.3
> +# For up-to-date information please visit https://wiki.nftables.org
> +
> +
> +flush ruleset
> +
> +table inet filter {
> +	secmark ssh_server {
> +		"system_u:object_r:ssh_server_packet_t:s0"
> +	}
> +
> +	secmark dns_client {
> +		"system_u:object_r:dns_client_packet_t:s0"
> +	}
> +
> +	secmark http_client {
> +		"system_u:object_r:http_client_packet_t:s0"
> +	}
> +
> +	secmark https_client {
> +		"system_u:object_r:http_client_packet_t:s0"
> +	}
> +
> +	secmark ntp_client {
> +		"system_u:object_r:ntp_client_packet_t:s0"
> +	}
> +
> +	secmark icmp_client {
> +		"system_u:object_r:icmp_client_packet_t:s0"
> +	}
> +
> +	secmark icmp_server {
> +		"system_u:object_r:icmp_server_packet_t:s0"
> +	}
> +
> +	secmark ssh_client {
> +		"system_u:object_r:ssh_client_packet_t:s0"
> +	}
> +
> +	secmark git_client {
> +		"system_u:object_r:git_client_packet_t:s0"
> +	}
> +
> +	map secmapping_in {
> +		type inet_service : secmark
> +		elements = { 22 : "ssh_server" }
> +	}
> +
> +	map secmapping_out {
> +		type inet_service : secmark
> +		elements = { 22 : "ssh_client", 53 : "dns_client", 80 : "http_client", 123 : "ntp_client", 443 : "http_client", 9418 : "git_client" }
> +	}
> +
> +	chain input {
> +		type filter hook input priority 0;
> +
> +		# label new incoming packets and add to connection
> +		ct state new meta secmark set tcp dport map @secmapping_in
> +		ct state new meta secmark set udp dport map @secmapping_in
> +		ct state new ip protocol icmp meta secmark set "icmp_server"
> +		ct state new ip6 nexthdr icmpv6 meta secmark set "icmp_server"
> +		ct state new ct secmark set meta secmark
> +
> +		# set label for est/rel packets from connection
> +		ct state established,related meta secmark set ct secmark
> +	}
> +
> +	chain output {
> +		type filter hook output priority 0;
> +
> +		# label new outgoing packets and add to connection
> +		ct state new meta secmark set tcp dport map @secmapping_out
> +		ct state new meta secmark set udp dport map @secmapping_out
> +		ct state new ip protocol icmp meta secmark set "icmp_client"
> +		ct state new ip6 nexthdr icmpv6 meta secmark set "icmp_client"
> +		ct state new ct secmark set meta secmark
> +
> +		# set label for est/rel packets from connection
> +		ct state established,related meta secmark set ct secmark
> +	}
> +}
> -- 
> 2.24.0
> 

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [RFC 4/4] src: add ability to reset secmarks
  2019-11-20 17:43 ` [RFC 4/4] src: add ability to reset secmarks Christian Göttsche
@ 2019-11-21 13:08   ` Pablo Neira Ayuso
  0 siblings, 0 replies; 9+ messages in thread
From: Pablo Neira Ayuso @ 2019-11-21 13:08 UTC (permalink / raw)
  To: Christian Göttsche; +Cc: netfilter-devel

On Wed, Nov 20, 2019 at 06:43:57PM +0100, Christian Göttsche wrote:
> Add the ability to reset secmark associations between the user-end string representation and the kernel intern secid.
> This allows a lightweight reset, without reloading the whole configuration and resetting all counters etc. .
> 
> *TODO*:
> Pablo suggested to drop this change.
> Are the actual objects in the kernel not destroyed and recreated?
> Or is this functionality useless?

The reset command is useful for stateful objects that collect some
internal state.

Basically, reset allows you to list the existing object state and
reset it, eg. counters.

In this case, secmark is not a stateful object, unless I'm missing
anything, I think we can skip this.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [RFC 2/4] src: add ability to set/get secmarks to/from connection
  2019-11-21 13:06   ` Pablo Neira Ayuso
@ 2019-11-21 13:27     ` Pablo Neira Ayuso
  0 siblings, 0 replies; 9+ messages in thread
From: Pablo Neira Ayuso @ 2019-11-21 13:27 UTC (permalink / raw)
  To: Christian Göttsche; +Cc: netfilter-devel

[-- Attachment #1: Type: text/plain, Size: 1748 bytes --]

On Thu, Nov 21, 2019 at 02:06:34PM +0100, Pablo Neira Ayuso wrote:
> On Wed, Nov 20, 2019 at 06:43:55PM +0100, Christian Göttsche wrote:
> > Labeling established and related packets requires the secmark to be stored in the connection.
> > Add the ability to store and retrieve secmarks like:
> > 
> >     ...
> >     chain input {
> >         ...
> > 
> >         # label new incoming packets
> >         ct state new meta secmark set tcp dport map @secmapping_in
> > 
> >         # add label to connection
> >         ct state new ct secmark set meta secmark
> > 
> >         # set label for est/rel packets from connection
> >         ct state established,related meta secmark set ct secmark
> > 
> >         ...
> >     }
> >     ...
> >     chain output {
> >         ...
> > 
> >         # label new outgoing packets
> >         ct state new meta secmark set tcp dport map @secmapping_out
> > 
> >         # add label to connection
> >         ct state new ct secmark set meta secmark
> > 
> >         # set label for est/rel packets from connection
> >         ct state established,related meta secmark set ct secmark
> > 
> >         ...
> >         }
> >     ...
> 
> I have applied this with minor changes on the evaluation side. Just
> follow up with another patch in case you find any issue.

Actually, I'm keeping back 2/4. I'm attaching the update I made.

I think it's good to disallow this:

        ct secmark 12
        meta secmark 12

but you also have to check from the evaluation phase that ct and meta
statements do not allow setting a constant value, ie.

        ct secmark set 12
        meta secmark set 12

From the objref statement evaluation step, you can check if this
expression is a constant through flags.

Thanks.

[-- Attachment #2: x.patch --]
[-- Type: text/x-diff, Size: 4590 bytes --]

commit 785049e16782f7afb658927e5fee3b1da761f97d
Author: Christian Göttsche <cgzones@googlemail.com>
Date:   Wed Nov 20 18:43:55 2019 +0100

    src: add ability to set/get secmarks to/from connection
    
    Labeling established and related packets requires the secmark to be stored in the connection.
    Add the ability to store and retrieve secmarks like:
    
        ...
        chain input {
            ...
    
            # label new incoming packets
            ct state new meta secmark set tcp dport map @secmapping_in
    
            # add label to connection
            ct state new ct secmark set meta secmark
    
            # set label for est/rel packets from connection
            ct state established,related meta secmark set ct secmark
    
            ...
        }
        ...
        chain output {
            ...
    
            # label new outgoing packets
            ct state new meta secmark set tcp dport map @secmapping_out
    
            # add label to connection
            ct state new ct secmark set meta secmark
    
            # set label for est/rel packets from connection
            ct state established,related meta secmark set ct secmark
    
            ...
            }
        ...
    
    This patch also disallow constant value on the right hand side.
    
     # nft add rule x y meta secmark 12
     Error: Cannot be used with right hand side constant value
     add rule x y meta secmark 12
                  ~~~~~~~~~~~~ ^^
     # nft add rule x y ct secmark 12
     Error: Cannot be used with right hand side constant value
     add rule x y ct secmark 12
                  ~~~~~~~~~~ ^^
    
    This patch improves 3bc84e5c1fdd ("src: add support for setting secmark").
    
    Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
    Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>

diff --git a/src/ct.c b/src/ct.c
index ed458e6b679b..9e6a8351ffb2 100644
--- a/src/ct.c
+++ b/src/ct.c
@@ -299,6 +299,8 @@ const struct ct_template ct_templates[__NFT_CT_MAX] = {
 					      BYTEORDER_BIG_ENDIAN, 128),
 	[NFT_CT_DST_IP6]	= CT_TEMPLATE("ip6 daddr", &ip6addr_type,
 					      BYTEORDER_BIG_ENDIAN, 128),
+	[NFT_CT_SECMARK]	= CT_TEMPLATE("secmark", &integer_type,
+					      BYTEORDER_HOST_ENDIAN, 32),
 };
 
 static void ct_print(enum nft_ct_keys key, int8_t dir, uint8_t nfproto,
diff --git a/src/evaluate.c b/src/evaluate.c
index e54eaf1a7110..00f6c6a4cc3e 100644
--- a/src/evaluate.c
+++ b/src/evaluate.c
@@ -1784,6 +1784,18 @@ static int expr_evaluate_relational(struct eval_ctx *ctx, struct expr **expr)
 					 left->dtype->desc,
 					 right->dtype->desc);
 
+	/*
+	 * Statements like 'ct secmark 12' are parsed as relational,
+	 * disallow constant value on the right hand side.
+	 */
+	if (((left->etype == EXPR_META &&
+	      left->meta.key == NFT_META_SECMARK) ||
+	     (left->etype == EXPR_CT &&
+	      left->ct.key == NFT_CT_SECMARK)) &&
+	    right->flags & EXPR_F_CONSTANT)
+		return expr_binary_error(ctx->msgs, right, left,
+                                         "Cannot be used with right hand side constant value");
+
 	switch (rel->op) {
 	case OP_EQ:
 	case OP_IMPLICIT:
diff --git a/src/meta.c b/src/meta.c
index 69a897a92686..796d8e941486 100644
--- a/src/meta.c
+++ b/src/meta.c
@@ -698,6 +698,8 @@ const struct meta_template meta_templates[] = {
 	[NFT_META_TIME_HOUR]	= META_TEMPLATE("hour", &hour_type,
 						4 * BITS_PER_BYTE,
 						BYTEORDER_HOST_ENDIAN),
+	[NFT_META_SECMARK]	= META_TEMPLATE("secmark", &integer_type,
+						32, BYTEORDER_HOST_ENDIAN),
 };
 
 static bool meta_key_is_unqualified(enum nft_meta_keys key)
diff --git a/src/parser_bison.y b/src/parser_bison.y
index 631b7d684555..707f46716ed3 100644
--- a/src/parser_bison.y
+++ b/src/parser_bison.y
@@ -4190,9 +4190,16 @@ meta_stmt		:	META	meta_key	SET	stmt_expr
 			{
 				switch ($2) {
 				case NFT_META_SECMARK:
-					$$ = objref_stmt_alloc(&@$);
-					$$->objref.type = NFT_OBJECT_SECMARK;
-					$$->objref.expr = $4;
+					switch ($4->etype) {
+					case EXPR_CT:
+						$$ = meta_stmt_alloc(&@$, $2, $4);
+						break;
+					default:
+						$$ = objref_stmt_alloc(&@$);
+						$$->objref.type = NFT_OBJECT_SECMARK;
+						$$->objref.expr = $4;
+						break;
+					}
 					break;
 				default:
 					$$ = meta_stmt_alloc(&@$, $2, $4);
@@ -4388,6 +4395,7 @@ ct_key			:	L3PROTOCOL	{ $$ = NFT_CT_L3PROTOCOL; }
 			|	PROTO_DST	{ $$ = NFT_CT_PROTO_DST; }
 			|	LABEL		{ $$ = NFT_CT_LABELS; }
 			|	EVENT		{ $$ = NFT_CT_EVENTMASK; }
+			|	SECMARK		{ $$ = NFT_CT_SECMARK; }
 			|	ct_key_dir_optional
 			;
 

^ permalink raw reply related	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2019-11-21 13:27 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-11-20 17:43 [RFC 1/4] statement: make secmark statements idempotent Christian Göttsche
2019-11-20 17:43 ` [RFC 2/4] src: add ability to set/get secmarks to/from connection Christian Göttsche
2019-11-21 13:06   ` Pablo Neira Ayuso
2019-11-21 13:27     ` Pablo Neira Ayuso
2019-11-20 17:43 ` [RFC 3/4] files: add example secmark config Christian Göttsche
2019-11-21 13:06   ` Pablo Neira Ayuso
2019-11-20 17:43 ` [RFC 4/4] src: add ability to reset secmarks Christian Göttsche
2019-11-21 13:08   ` Pablo Neira Ayuso
2019-11-21 13:05 ` [RFC 1/4] statement: make secmark statements idempotent Pablo Neira Ayuso

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).