netfilter-devel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 nftables 0/7] ct helper set support
@ 2017-03-15 15:01 Florian Westphal
  2017-03-15 15:01 ` [PATCH v2 nftables 1/7] src: add initial ct helper support Florian Westphal
                   ` (7 more replies)
  0 siblings, 8 replies; 9+ messages in thread
From: Florian Westphal @ 2017-03-15 15:01 UTC (permalink / raw)
  To: netfilter-devel

v2, with updated syntax to force type and protocol keywords
into same statement, i.e.

ct helper ftp-standard {
  type "ftp" protocol tcp
}

I also cleaned up the changes to bison (reuse family_spec_explicit)
and added a test for an invalid helper (l3proto ip6 in ip table).

 doc/nft.xml                         |   76 +++++++++++++++++
 include/ct.h                        |    1 
 include/linux/netfilter/nf_tables.h |   12 ++
 include/rule.h                      |   12 ++
 src/ct.c                            |   10 ++
 src/evaluate.c                      |   37 +++++---
 src/netlink.c                       |   16 +++
 src/parser_bison.y                  |  156 +++++++++++++++++++++++++++++++++++-
 src/rule.c                          |   45 ++++++++++
 src/statement.c                     |   10 ++
 tests/py/ip/objects.t               |    5 +
 tests/py/ip/objects.t.payload       |   14 +++
 tests/py/nft-test.py                |   28 +++++-
 13 files changed, 399 insertions(+), 23 deletions(-)

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

* [PATCH v2 nftables 1/7] src: add initial ct helper support
  2017-03-15 15:01 [PATCH v2 nftables 0/7] ct helper set support Florian Westphal
@ 2017-03-15 15:01 ` Florian Westphal
  2017-03-15 15:01 ` [PATCH v2 nftables 2/7] evaluate: refactor CMD_OBJ_QUOTA/COUNTER handling Florian Westphal
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Florian Westphal @ 2017-03-15 15:01 UTC (permalink / raw)
  To: netfilter-devel; +Cc: Florian Westphal

This adds initial support for defining conntrack helper objects
which can then be assigned to connections using the objref infrastructure:

table ip filter {
  ct helper ftp-standard {
    type "ftp" protocol tcp
  }
  chain y {
	 tcp dport 21 ct helper set "ftp-standard"
  }
}

Signed-off-by: Florian Westphal <fw@strlen.de>
---
 Changes since v1:
   - tweak user syntax
   - minor cleanup
   - fix parsing of l3proto: v1 used to set l4proto instead of l3.

 include/ct.h                        |  1 +
 include/linux/netfilter/nf_tables.h | 12 +++++-
 include/rule.h                      |  7 ++++
 src/ct.c                            | 10 +++++
 src/netlink.c                       | 16 ++++++++
 src/parser_bison.y                  | 74 ++++++++++++++++++++++++++++++++++++-
 src/rule.c                          | 21 ++++++++++-
 src/statement.c                     | 10 ++++-
 8 files changed, 146 insertions(+), 5 deletions(-)

diff --git a/include/ct.h b/include/ct.h
index 03e76e619e23..ae900ee4fb61 100644
--- a/include/ct.h
+++ b/include/ct.h
@@ -31,6 +31,7 @@ extern struct error_record *ct_dir_parse(const struct location *loc,
 					 const char *str, int8_t *dir);
 extern struct error_record *ct_key_parse(const struct location *loc, const char *str,
 					 unsigned int *key);
+extern struct error_record *ct_objtype_parse(const struct location *loc, const char *str, int *type);
 
 extern struct stmt *notrack_stmt_alloc(const struct location *loc);
 
diff --git a/include/linux/netfilter/nf_tables.h b/include/linux/netfilter/nf_tables.h
index a9280a6541ac..8f3842690d17 100644
--- a/include/linux/netfilter/nf_tables.h
+++ b/include/linux/netfilter/nf_tables.h
@@ -1260,10 +1260,20 @@ enum nft_fib_flags {
 	NFTA_FIB_F_PRESENT	= 1 << 5,	/* check existence only */
 };
 
+enum nft_ct_helper_attributes {
+	NFTA_CT_HELPER_UNSPEC,
+	NFTA_CT_HELPER_NAME,
+	NFTA_CT_HELPER_L3PROTO,
+	NFTA_CT_HELPER_L4PROTO,
+	__NFTA_CT_HELPER_MAX,
+};
+#define NFTA_CT_HELPER_MAX	(__NFTA_CT_HELPER_MAX - 1)
+
 #define NFT_OBJECT_UNSPEC	0
 #define NFT_OBJECT_COUNTER	1
 #define NFT_OBJECT_QUOTA	2
-#define __NFT_OBJECT_MAX	3
+#define NFT_OBJECT_CT_HELPER	3
+#define __NFT_OBJECT_MAX	4
 #define NFT_OBJECT_MAX		(__NFT_OBJECT_MAX - 1)
 
 /**
diff --git a/include/rule.h b/include/rule.h
index ed12774d0ba7..d89a963dfd05 100644
--- a/include/rule.h
+++ b/include/rule.h
@@ -260,6 +260,12 @@ struct quota {
 	uint32_t	flags;
 };
 
+struct ct {
+	char helper_name[16];
+	uint16_t l3proto;
+	uint8_t l4proto;
+};
+
 /**
  * struct obj - nftables stateful object statement
  *
@@ -277,6 +283,7 @@ struct obj {
 	union {
 		struct counter		counter;
 		struct quota		quota;
+		struct ct		ct;
 	};
 };
 
diff --git a/src/ct.c b/src/ct.c
index 83fceff67139..fd8ca87a21fb 100644
--- a/src/ct.c
+++ b/src/ct.c
@@ -353,6 +353,16 @@ struct error_record *ct_key_parse(const struct location *loc, const char *str,
 	return error(loc, "syntax error, unexpected %s, known keys are %s", str, buf);
 }
 
+struct error_record *ct_objtype_parse(const struct location *loc, const char *str, int *type)
+{
+	if (strcmp(str, "helper") == 0) {
+		*type = NFT_OBJECT_CT_HELPER;
+		return NULL;
+	}
+
+	return error(loc, "unknown ct class '%s', want 'helper'", str);
+}
+
 struct expr *ct_expr_alloc(const struct location *loc, enum nft_ct_keys key,
 			   int8_t direction)
 {
diff --git a/src/netlink.c b/src/netlink.c
index fb6d2876a6f1..6fbb67da7f76 100644
--- a/src/netlink.c
+++ b/src/netlink.c
@@ -317,6 +317,15 @@ alloc_nftnl_obj(const struct handle *h, struct obj *obj)
 		nftnl_obj_set_u32(nlo, NFTNL_OBJ_QUOTA_FLAGS,
 				  obj->quota.flags);
 		break;
+	case NFT_OBJECT_CT_HELPER:
+		nftnl_obj_set_str(nlo, NFTNL_OBJ_CT_HELPER_NAME,
+				  obj->ct.helper_name);
+		nftnl_obj_set_u8(nlo, NFTNL_OBJ_CT_HELPER_L4PROTO,
+				  obj->ct.l4proto);
+		if (obj->ct.l3proto)
+			nftnl_obj_set_u16(nlo, NFTNL_OBJ_CT_HELPER_L3PROTO,
+					  obj->ct.l3proto);
+		break;
 	default:
 		BUG("Unknown type %d\n", obj->type);
 		break;
@@ -1814,6 +1823,13 @@ static struct obj *netlink_delinearize_obj(struct netlink_ctx *ctx,
 			nftnl_obj_get_u64(nlo, NFTNL_OBJ_QUOTA_CONSUMED);
 		obj->quota.flags =
 			nftnl_obj_get_u32(nlo, NFTNL_OBJ_QUOTA_FLAGS);
+		break;
+	case NFT_OBJECT_CT_HELPER:
+		snprintf(obj->ct.helper_name, sizeof(obj->ct.helper_name), "%s",
+			 nftnl_obj_get_str(nlo, NFTNL_OBJ_CT_HELPER_NAME));
+		obj->ct.l3proto = nftnl_obj_get_u16(nlo, NFTNL_OBJ_CT_HELPER_L3PROTO);
+		obj->ct.l4proto = nftnl_obj_get_u8(nlo, NFTNL_OBJ_CT_HELPER_L4PROTO);
+		break;
 	}
 	obj->type = type;
 
diff --git a/src/parser_bison.y b/src/parser_bison.y
index 12a6e64645fa..2cf732ce818f 100644
--- a/src/parser_bison.y
+++ b/src/parser_bison.y
@@ -136,6 +136,7 @@ static void location_update(struct location *loc, struct location *rhs, int n)
 	struct obj		*obj;
 	struct counter		*counter;
 	struct quota		*quota;
+	struct ct		*ct;
 	const struct datatype	*datatype;
 	struct handle_spec	handle_spec;
 	struct position_spec	position_spec;
@@ -494,7 +495,7 @@ static void location_update(struct location *loc, struct location *rhs, int n)
 %type <set>			map_block_alloc map_block
 %destructor { set_free($$); }	map_block_alloc
 
-%type <obj>			obj_block_alloc counter_block quota_block
+%type <obj>			obj_block_alloc counter_block quota_block ct_block
 %destructor { obj_free($$); }	obj_block_alloc
 
 %type <list>			stmt_list
@@ -665,6 +666,10 @@ static void location_update(struct location *loc, struct location *rhs, int n)
 %destructor { expr_free($$); }	exthdr_exists_expr
 %type <val>			exthdr_key
 
+%type <val>			ct_l4protoname
+%type <string>			ct_obj_kind
+%destructor { xfree($$); }     	ct_obj_kind
+
 %%
 
 input			:	/* empty */
@@ -1191,6 +1196,24 @@ table_block		:	/* empty */	{ $$ = $<table>-1; }
 				list_add_tail(&$4->list, &$1->objs);
 				$$ = $1;
 			}
+			|	table_block	CT	ct_obj_kind	obj_identifier  obj_block_alloc '{'     ct_block     '}' stmt_seperator
+			{
+				struct error_record *erec;
+				int type;
+
+				erec = ct_objtype_parse(&@$, $3, &type);
+				if (erec != NULL) {
+					erec_queue(erec, state->msgs);
+					YYERROR;
+				}
+
+				$5->location = @4;
+				$5->type = type;
+				handle_merge(&$5->handle, &$4);
+				handle_free(&$4);
+				list_add_tail(&$5->list, &$1->objs);
+				$$ = $1;
+			}
 			;
 
 chain_block_alloc	:	/* empty */
@@ -1385,6 +1408,16 @@ quota_block		:	/* empty */	{ $$ = $<obj>-1; }
 			}
 			;
 
+ct_block		:	/* empty */	{ $$ = $<obj>-1; }
+			|       ct_block     common_block
+			|       ct_block     stmt_seperator
+			|       ct_block     ct_config
+			{
+				$$ = $1;
+			}
+			;
+
+
 type_identifier		:	STRING	{ $$ = $1; }
 			|	MARK	{ $$ = xstrdup("mark"); }
 			|	DSCP	{ $$ = xstrdup("dscp"); }
@@ -2578,6 +2611,34 @@ quota_obj		:	quota_config
 			}
 			;
 
+ct_obj_kind		:	STRING		{ $$ = $1; }
+			;
+
+ct_l4protoname		:	TCP	{ $$ = IPPROTO_TCP; }
+			|	UDP	{ $$ = IPPROTO_UDP; }
+			;
+
+ct_config		:	TYPE	QUOTED_STRING	PROTOCOL	ct_l4protoname	stmt_seperator
+			{
+				struct ct *ct;
+				int ret;
+
+				ct = &$<obj>0->ct;
+
+				ret = snprintf(ct->helper_name, sizeof(ct->helper_name), "%s", $2);
+				if (ret <= 0 || ret >= (int)sizeof(ct->helper_name)) {
+					erec_queue(error(&@2, "invalid name '%s', max length is %u\n", $2, (int)sizeof(ct->helper_name)), state->msgs);
+					YYERROR;
+				}
+
+				ct->l4proto = $4;
+			}
+			|	L3PROTOCOL	family_spec_explicit	stmt_seperator
+			{
+				$<obj>0->ct.l3proto = $2;
+			}
+			;
+
 relational_expr		:	expr	/* implicit */	rhs_expr
 			{
 				$$ = relational_expr_alloc(&@$, OP_IMPLICIT, $1, $2);
@@ -3037,7 +3098,16 @@ ct_stmt			:	CT	ct_key		SET	expr
 					YYERROR;
 				}
 
-				$$ = ct_stmt_alloc(&@$, key, -1, $4);
+				switch (key) {
+				case NFT_CT_HELPER:
+					$$ = objref_stmt_alloc(&@$);
+					$$->objref.type = NFT_OBJECT_CT_HELPER;
+					$$->objref.expr = $4;
+					break;
+				default:
+					$$ = ct_stmt_alloc(&@$, key, -1, $4);
+					break;
+				}
 			}
 			|	CT	STRING	ct_key_dir_optional SET	expr
 			{
diff --git a/src/rule.c b/src/rule.c
index 056d5ce8394e..17c20f35398a 100644
--- a/src/rule.c
+++ b/src/rule.c
@@ -19,6 +19,7 @@
 #include <statement.h>
 #include <rule.h>
 #include <utils.h>
+#include <netdb.h>
 #include <netlink.h>
 
 #include <libnftnl/common.h>
@@ -1172,6 +1173,16 @@ struct obj *obj_lookup(const struct table *table, const char *name,
 	return NULL;
 }
 
+static void print_proto_name_proto(uint8_t l4)
+{
+	const struct protoent *p = getprotobynumber(l4);
+
+	if (p)
+		printf("%s\n", p->p_name);
+	else
+		printf("%d\n", l4);
+}
+
 static void obj_print_data(const struct obj *obj,
 			   struct print_fmt_options *opts)
 {
@@ -1202,6 +1213,13 @@ static void obj_print_data(const struct obj *obj,
 		}
 		}
 		break;
+	case NFT_OBJECT_CT_HELPER: {
+		printf("ct helper %s {\n", obj->handle.obj);
+		printf("\t\ttype \"%s\" protocol ", obj->ct.helper_name);
+		print_proto_name_proto(obj->ct.l4proto);
+		printf("\t\tl3proto %s", family2str(obj->ct.l3proto));
+		break;
+		}
 	default:
 		printf("unknown {%s", opts->nl);
 		break;
@@ -1211,11 +1229,12 @@ static void obj_print_data(const struct obj *obj,
 static const char *obj_type_name_array[] = {
 	[NFT_OBJECT_COUNTER]	= "counter",
 	[NFT_OBJECT_QUOTA]	= "quota",
+	[NFT_OBJECT_CT_HELPER]	= "",
 };
 
 const char *obj_type_name(enum stmt_types type)
 {
-	assert(type <= NFT_OBJECT_QUOTA && obj_type_name_array[type]);
+	assert(type <= NFT_OBJECT_CT_HELPER && obj_type_name_array[type]);
 
 	return obj_type_name_array[type];
 }
diff --git a/src/statement.c b/src/statement.c
index 7ffd25f98ea6..d824dc0bd91a 100644
--- a/src/statement.c
+++ b/src/statement.c
@@ -174,6 +174,7 @@ struct stmt *counter_stmt_alloc(const struct location *loc)
 static const char *objref_type[NFT_OBJECT_MAX + 1] = {
 	[NFT_OBJECT_COUNTER]	= "counter",
 	[NFT_OBJECT_QUOTA]	= "quota",
+	[NFT_OBJECT_CT_HELPER]	= "cthelper",
 };
 
 static const char *objref_type_name(uint32_t type)
@@ -186,7 +187,14 @@ static const char *objref_type_name(uint32_t type)
 
 static void objref_stmt_print(const struct stmt *stmt)
 {
-	printf("%s name ", objref_type_name(stmt->objref.type));
+	switch (stmt->objref.type) {
+	case NFT_OBJECT_CT_HELPER:
+		printf("ct helper set ");
+		break;
+	default:
+		printf("%s name ", objref_type_name(stmt->objref.type));
+		break;
+	}
 	expr_print(stmt->objref.expr);
 }
 
-- 
2.10.2


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

* [PATCH v2 nftables 2/7] evaluate: refactor CMD_OBJ_QUOTA/COUNTER handling
  2017-03-15 15:01 [PATCH v2 nftables 0/7] ct helper set support Florian Westphal
  2017-03-15 15:01 ` [PATCH v2 nftables 1/7] src: add initial ct helper support Florian Westphal
@ 2017-03-15 15:01 ` Florian Westphal
  2017-03-15 15:01 ` [PATCH v2 nftables 3/7] src: allow listing all ct helpers Florian Westphal
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Florian Westphal @ 2017-03-15 15:01 UTC (permalink / raw)
  To: netfilter-devel; +Cc: Florian Westphal

... to make adding CMD_OBJ_CT_HELPER support easier.

Signed-off-by: Florian Westphal <fw@strlen.de>
---
 no changes since v1.
 src/evaluate.c | 32 ++++++++++++++++++++------------
 1 file changed, 20 insertions(+), 12 deletions(-)

diff --git a/src/evaluate.c b/src/evaluate.c
index 7ddbb658f96f..ae30bc9bb3b9 100644
--- a/src/evaluate.c
+++ b/src/evaluate.c
@@ -2940,12 +2940,29 @@ static int cmd_evaluate_delete(struct eval_ctx *ctx, struct cmd *cmd)
 	}
 }
 
+static int cmd_evaluate_list_obj(struct eval_ctx *ctx, const struct cmd *cmd,
+				 uint32_t obj_type)
+{
+	const struct table *table;
+
+	if (obj_type == NFT_OBJECT_UNSPEC)
+		obj_type = NFT_OBJECT_COUNTER;
+
+	table = table_lookup(&cmd->handle);
+	if (table == NULL)
+		return cmd_error(ctx, "Could not process rule: Table '%s' does not exist",
+				 cmd->handle.table);
+	if (obj_lookup(table, cmd->handle.obj, obj_type) == NULL)
+		return cmd_error(ctx, "Could not process rule: Object '%s' does not exist",
+					 cmd->handle.obj);
+	return 0;
+}
+
 static int cmd_evaluate_list(struct eval_ctx *ctx, struct cmd *cmd)
 {
 	struct table *table;
 	struct set *set;
 	int ret;
-	uint32_t obj_type = NFT_OBJECT_UNSPEC;
 
 	ret = cache_update(cmd->op, ctx->msgs);
 	if (ret < 0)
@@ -3001,18 +3018,9 @@ static int cmd_evaluate_list(struct eval_ctx *ctx, struct cmd *cmd)
 					 cmd->handle.chain);
 		return 0;
 	case CMD_OBJ_QUOTA:
-		obj_type = NFT_OBJECT_QUOTA;
+		return cmd_evaluate_list_obj(ctx, cmd, NFT_OBJECT_QUOTA);
 	case CMD_OBJ_COUNTER:
-		if (obj_type == NFT_OBJECT_UNSPEC)
-			obj_type = NFT_OBJECT_COUNTER;
-		table = table_lookup(&cmd->handle);
-		if (table == NULL)
-			return cmd_error(ctx, "Could not process rule: Table '%s' does not exist",
-					 cmd->handle.table);
-		if (obj_lookup(table, cmd->handle.obj, obj_type) == NULL)
-			return cmd_error(ctx, "Could not process rule: Object '%s' does not exist",
-					 cmd->handle.obj);
-		return 0;
+		return cmd_evaluate_list_obj(ctx, cmd, NFT_OBJECT_COUNTER);
 	case CMD_OBJ_COUNTERS:
 	case CMD_OBJ_QUOTAS:
 		if (cmd->handle.table == NULL)
-- 
2.10.2


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

* [PATCH v2 nftables 3/7] src: allow listing all ct helpers
  2017-03-15 15:01 [PATCH v2 nftables 0/7] ct helper set support Florian Westphal
  2017-03-15 15:01 ` [PATCH v2 nftables 1/7] src: add initial ct helper support Florian Westphal
  2017-03-15 15:01 ` [PATCH v2 nftables 2/7] evaluate: refactor CMD_OBJ_QUOTA/COUNTER handling Florian Westphal
@ 2017-03-15 15:01 ` Florian Westphal
  2017-03-15 15:01 ` [PATCH v2 nftables 4/7] src: implement add/create/delete for ct helper objects Florian Westphal
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Florian Westphal @ 2017-03-15 15:01 UTC (permalink / raw)
  To: netfilter-devel; +Cc: Florian Westphal

this implements
nft list ct helpers table filter
table ip filter {
    ct helper ftp-standard {
..

Signed-off-by: Florian Westphal <fw@strlen.de>
---
 no changes since v1.
 include/rule.h     |  1 +
 src/evaluate.c     |  1 +
 src/parser_bison.y | 19 +++++++++++++++++++
 src/rule.c         |  2 ++
 4 files changed, 23 insertions(+)

diff --git a/include/rule.h b/include/rule.h
index d89a963dfd05..b791cc0a497c 100644
--- a/include/rule.h
+++ b/include/rule.h
@@ -370,6 +370,7 @@ enum cmd_obj {
 	CMD_OBJ_COUNTERS,
 	CMD_OBJ_QUOTA,
 	CMD_OBJ_QUOTAS,
+	CMD_OBJ_CT_HELPERS,
 };
 
 struct export {
diff --git a/src/evaluate.c b/src/evaluate.c
index ae30bc9bb3b9..20f67ee784dd 100644
--- a/src/evaluate.c
+++ b/src/evaluate.c
@@ -3023,6 +3023,7 @@ static int cmd_evaluate_list(struct eval_ctx *ctx, struct cmd *cmd)
 		return cmd_evaluate_list_obj(ctx, cmd, NFT_OBJECT_COUNTER);
 	case CMD_OBJ_COUNTERS:
 	case CMD_OBJ_QUOTAS:
+	case CMD_OBJ_CT_HELPERS:
 		if (cmd->handle.table == NULL)
 			return 0;
 		if (table_lookup(&cmd->handle) == NULL)
diff --git a/src/parser_bison.y b/src/parser_bison.y
index 2cf732ce818f..1bcbff598ad7 100644
--- a/src/parser_bison.y
+++ b/src/parser_bison.y
@@ -1016,6 +1016,25 @@ list_cmd		:	TABLE		table_spec
 			{
 				$$ = cmd_alloc(CMD_LIST, CMD_OBJ_MAP, &$2, &@$, NULL);
 			}
+			|       CT              STRING  TABLE   table_spec
+			{
+				int cmd;
+
+				if (strcmp($2, "helpers") == 0) {
+					cmd = CMD_OBJ_CT_HELPERS;
+				} else {
+					struct error_record *erec;
+
+					erec = error(&@$, "unknown ct class '%s', want 'helpers'", $2);
+
+					if (erec != NULL) {
+						erec_queue(erec, state->msgs);
+						YYERROR;
+					}
+				}
+
+				$$ = cmd_alloc(CMD_LIST, cmd, &$4, &@$, NULL);
+			}
 			;
 
 reset_cmd		:	COUNTERS	ruleset_spec
diff --git a/src/rule.c b/src/rule.c
index 17c20f35398a..453aa2f2cc9c 100644
--- a/src/rule.c
+++ b/src/rule.c
@@ -1455,6 +1455,8 @@ static int do_command_list(struct netlink_ctx *ctx, struct cmd *cmd)
 	case CMD_OBJ_QUOTA:
 	case CMD_OBJ_QUOTAS:
 		return do_list_obj(ctx, cmd, NFT_OBJECT_QUOTA);
+	case CMD_OBJ_CT_HELPERS:
+		return do_list_obj(ctx, cmd, NFT_OBJECT_CT_HELPER);
 	default:
 		BUG("invalid command object type %u\n", cmd->obj);
 	}
-- 
2.10.2


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

* [PATCH v2 nftables 4/7] src: implement add/create/delete for ct helper objects
  2017-03-15 15:01 [PATCH v2 nftables 0/7] ct helper set support Florian Westphal
                   ` (2 preceding siblings ...)
  2017-03-15 15:01 ` [PATCH v2 nftables 3/7] src: allow listing all ct helpers Florian Westphal
@ 2017-03-15 15:01 ` Florian Westphal
  2017-03-15 15:01 ` [PATCH v2 nftables 5/7] tests: py: add ct helper tests Florian Westphal
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Florian Westphal @ 2017-03-15 15:01 UTC (permalink / raw)
  To: netfilter-devel; +Cc: Florian Westphal

Signed-off-by: Florian Westphal <fw@strlen.de>
---
 no changes since v1.
 include/rule.h     |  4 ++++
 src/evaluate.c     |  4 ++++
 src/parser_bison.y | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++++--
 src/rule.c         | 22 +++++++++++++++++++
 4 files changed, 91 insertions(+), 2 deletions(-)

diff --git a/include/rule.h b/include/rule.h
index b791cc0a497c..fb4606406a94 100644
--- a/include/rule.h
+++ b/include/rule.h
@@ -370,6 +370,7 @@ enum cmd_obj {
 	CMD_OBJ_COUNTERS,
 	CMD_OBJ_QUOTA,
 	CMD_OBJ_QUOTAS,
+	CMD_OBJ_CT_HELPER,
 	CMD_OBJ_CT_HELPERS,
 };
 
@@ -438,6 +439,9 @@ struct cmd {
 extern struct cmd *cmd_alloc(enum cmd_ops op, enum cmd_obj obj,
 			     const struct handle *h, const struct location *loc,
 			     void *data);
+extern struct cmd *cmd_alloc_obj_ct(enum cmd_ops op, int type,
+				    const struct handle *h,
+				    const struct location *loc, void *data);
 extern void cmd_free(struct cmd *cmd);
 
 #include <payload.h>
diff --git a/src/evaluate.c b/src/evaluate.c
index 20f67ee784dd..8fb716c06244 100644
--- a/src/evaluate.c
+++ b/src/evaluate.c
@@ -2911,6 +2911,7 @@ static int cmd_evaluate_add(struct eval_ctx *ctx, struct cmd *cmd)
 		return table_evaluate(ctx, cmd->table);
 	case CMD_OBJ_COUNTER:
 	case CMD_OBJ_QUOTA:
+	case CMD_OBJ_CT_HELPER:
 		return 0;
 	default:
 		BUG("invalid command object type %u\n", cmd->obj);
@@ -2934,6 +2935,7 @@ static int cmd_evaluate_delete(struct eval_ctx *ctx, struct cmd *cmd)
 	case CMD_OBJ_TABLE:
 	case CMD_OBJ_COUNTER:
 	case CMD_OBJ_QUOTA:
+	case CMD_OBJ_CT_HELPER:
 		return 0;
 	default:
 		BUG("invalid command object type %u\n", cmd->obj);
@@ -3021,6 +3023,8 @@ static int cmd_evaluate_list(struct eval_ctx *ctx, struct cmd *cmd)
 		return cmd_evaluate_list_obj(ctx, cmd, NFT_OBJECT_QUOTA);
 	case CMD_OBJ_COUNTER:
 		return cmd_evaluate_list_obj(ctx, cmd, NFT_OBJECT_COUNTER);
+	case CMD_OBJ_CT_HELPER:
+		return cmd_evaluate_list_obj(ctx, cmd, NFT_OBJECT_CT_HELPER);
 	case CMD_OBJ_COUNTERS:
 	case CMD_OBJ_QUOTAS:
 	case CMD_OBJ_CT_HELPERS:
diff --git a/src/parser_bison.y b/src/parser_bison.y
index 1bcbff598ad7..5d3d10694823 100644
--- a/src/parser_bison.y
+++ b/src/parser_bison.y
@@ -583,8 +583,8 @@ static void location_update(struct location *loc, struct location *rhs, int n)
 %type <expr>			and_rhs_expr exclusive_or_rhs_expr inclusive_or_rhs_expr
 %destructor { expr_free($$); }	and_rhs_expr exclusive_or_rhs_expr inclusive_or_rhs_expr
 
-%type <obj>			counter_obj quota_obj
-%destructor { obj_free($$); }	counter_obj quota_obj
+%type <obj>			counter_obj quota_obj ct_obj_alloc
+%destructor { obj_free($$); }	counter_obj quota_obj ct_obj_alloc
 
 %type <expr>			relational_expr
 %destructor { expr_free($$); }	relational_expr
@@ -840,6 +840,19 @@ add_cmd			:	TABLE		table_spec
 			{
 				$$ = cmd_alloc(CMD_ADD, CMD_OBJ_QUOTA, &$2, &@$, $3);
 			}
+			|	CT	STRING	obj_spec	ct_obj_alloc	'{' ct_block '}'	stmt_seperator
+			{
+				struct error_record *erec;
+				int type;
+
+				erec = ct_objtype_parse(&@$, $2, &type);
+				if (erec != NULL) {
+					erec_queue(erec, state->msgs);
+					YYERROR;
+				}
+
+				$$ = cmd_alloc_obj_ct(CMD_ADD, type, &$3, &@$, $4);
+			}
 			;
 
 replace_cmd		:	RULE		ruleid_spec	rule
@@ -906,6 +919,19 @@ create_cmd		:	TABLE		table_spec
 			{
 				$$ = cmd_alloc(CMD_CREATE, CMD_OBJ_QUOTA, &$2, &@$, $3);
 			}
+			|	CT	STRING	obj_spec	ct_obj_alloc	'{' ct_block '}'	stmt_seperator
+			{
+				struct error_record *erec;
+				int type;
+
+				erec = ct_objtype_parse(&@$, $2, &type);
+				if (erec != NULL) {
+					erec_queue(erec, state->msgs);
+					YYERROR;
+				}
+
+				$$ = cmd_alloc_obj_ct(CMD_CREATE, type, &$3, &@$, $4);
+			}
 			;
 
 insert_cmd		:	RULE		rule_position	rule
@@ -946,6 +972,19 @@ delete_cmd		:	TABLE		table_spec
 			{
 				$$ = cmd_alloc(CMD_DELETE, CMD_OBJ_QUOTA, &$2, &@$, NULL);
 			}
+			|	CT	STRING	obj_spec	ct_obj_alloc
+			{
+				struct error_record *erec;
+				int type;
+
+				erec = ct_objtype_parse(&@$, $2, &type);
+				if (erec != NULL) {
+					erec_queue(erec, state->msgs);
+					YYERROR;
+				}
+
+				$$ = cmd_alloc_obj_ct(CMD_DELETE, type, &$3, &@$, $4);
+			}
 			;
 
 list_cmd		:	TABLE		table_spec
@@ -1016,6 +1055,19 @@ list_cmd		:	TABLE		table_spec
 			{
 				$$ = cmd_alloc(CMD_LIST, CMD_OBJ_MAP, &$2, &@$, NULL);
 			}
+			|	CT		STRING	obj_spec
+			{
+				struct error_record *erec;
+				int type;
+
+				erec = ct_objtype_parse(&@$, $2, &type);
+				if (erec != NULL) {
+					erec_queue(erec, state->msgs);
+					YYERROR;
+				}
+
+				$$ = cmd_alloc_obj_ct(CMD_LIST, type, &$3, &@$, NULL);
+			}
 			|       CT              STRING  TABLE   table_spec
 			{
 				int cmd;
@@ -2658,6 +2710,13 @@ ct_config		:	TYPE	QUOTED_STRING	PROTOCOL	ct_l4protoname	stmt_seperator
 			}
 			;
 
+ct_obj_alloc		:
+			{
+				$$ = obj_alloc(&@$);
+				$$->type = NFT_OBJECT_CT_HELPER;
+			}
+			;
+
 relational_expr		:	expr	/* implicit */	rhs_expr
 			{
 				$$ = relational_expr_alloc(&@$, OP_IMPLICIT, $1, $2);
diff --git a/src/rule.c b/src/rule.c
index 453aa2f2cc9c..997a6243eb49 100644
--- a/src/rule.c
+++ b/src/rule.c
@@ -885,6 +885,7 @@ void cmd_free(struct cmd *cmd)
 			break;
 		case CMD_OBJ_COUNTER:
 		case CMD_OBJ_QUOTA:
+		case CMD_OBJ_CT_HELPER:
 			obj_free(cmd->object);
 			break;
 		default:
@@ -1001,6 +1002,7 @@ static int do_command_add(struct netlink_ctx *ctx, struct cmd *cmd, bool excl)
 		return do_add_setelems(ctx, &cmd->handle, cmd->expr, excl);
 	case CMD_OBJ_COUNTER:
 	case CMD_OBJ_QUOTA:
+	case CMD_OBJ_CT_HELPER:
 		return netlink_add_obj(ctx, &cmd->handle, cmd->object, excl);
 	default:
 		BUG("invalid command object type %u\n", cmd->obj);
@@ -1071,6 +1073,9 @@ static int do_command_delete(struct netlink_ctx *ctx, struct cmd *cmd)
 	case CMD_OBJ_QUOTA:
 		return netlink_delete_obj(ctx, &cmd->handle, &cmd->location,
 					  NFT_OBJECT_QUOTA);
+	case CMD_OBJ_CT_HELPER:
+		return netlink_delete_obj(ctx, &cmd->handle, &cmd->location,
+					  NFT_OBJECT_CT_HELPER);
 	default:
 		BUG("invalid command object type %u\n", cmd->obj);
 	}
@@ -1455,6 +1460,7 @@ static int do_command_list(struct netlink_ctx *ctx, struct cmd *cmd)
 	case CMD_OBJ_QUOTA:
 	case CMD_OBJ_QUOTAS:
 		return do_list_obj(ctx, cmd, NFT_OBJECT_QUOTA);
+	case CMD_OBJ_CT_HELPER:
 	case CMD_OBJ_CT_HELPERS:
 		return do_list_obj(ctx, cmd, NFT_OBJECT_CT_HELPER);
 	default:
@@ -1603,6 +1609,22 @@ static int do_command_describe(struct netlink_ctx *ctx, struct cmd *cmd)
 	return 0;
 }
 
+struct cmd *cmd_alloc_obj_ct(enum cmd_ops op, int type, const struct handle *h,
+			     const struct location *loc, void *data)
+{
+	enum cmd_obj cmd_obj;
+
+	switch (type) {
+	case NFT_OBJECT_CT_HELPER:
+		cmd_obj = CMD_OBJ_CT_HELPER;
+		break;
+	default:
+		BUG("missing type mapping");
+	}
+
+	return cmd_alloc(op, cmd_obj, h, loc, data);
+}
+
 int do_command(struct netlink_ctx *ctx, struct cmd *cmd)
 {
 	switch (cmd->op) {
-- 
2.10.2


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

* [PATCH v2 nftables 5/7] tests: py: add ct helper tests
  2017-03-15 15:01 [PATCH v2 nftables 0/7] ct helper set support Florian Westphal
                   ` (3 preceding siblings ...)
  2017-03-15 15:01 ` [PATCH v2 nftables 4/7] src: implement add/create/delete for ct helper objects Florian Westphal
@ 2017-03-15 15:01 ` Florian Westphal
  2017-03-15 15:01 ` [PATCH v2 nftables 6/7] tests: add insert-failure test Florian Westphal
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Florian Westphal @ 2017-03-15 15:01 UTC (permalink / raw)
  To: netfilter-devel; +Cc: Florian Westphal

needs minor tweak to nft-test.py so we don't zap the ';' withhin the {}.

Signed-off-by: Florian Westphal <fw@strlen.de>
---
 no changes since v1.
 tests/py/ip/objects.t         |  4 ++++
 tests/py/ip/objects.t.payload | 14 ++++++++++++++
 tests/py/nft-test.py          | 11 ++++++++++-
 3 files changed, 28 insertions(+), 1 deletion(-)

diff --git a/tests/py/ip/objects.t b/tests/py/ip/objects.t
index 8109402da8ba..ec8e8fd916d4 100644
--- a/tests/py/ip/objects.t
+++ b/tests/py/ip/objects.t
@@ -13,3 +13,7 @@ counter name tcp dport map {443 : "cnt1", 80 : "cnt2", 22 : "cnt1"};ok
 ip saddr 192.168.1.3 quota name "qt1";ok
 ip saddr 192.168.1.3 quota name "qt3";fail
 quota name tcp dport map {443 : "qt1", 80 : "qt2", 22 : "qt1"};ok
+
+%cthelp1 type ct helper { type \"ftp\" protocol tcp\; };ok
+ct helper set "cthelp1";ok
+ct helper set tcp dport map {21 : "cthelp1", 2121 : "cthelp1" };ok
diff --git a/tests/py/ip/objects.t.payload b/tests/py/ip/objects.t.payload
index b5cad4d1e3fc..6499d36348fe 100644
--- a/tests/py/ip/objects.t.payload
+++ b/tests/py/ip/objects.t.payload
@@ -29,3 +29,17 @@ ip test-ip4 output
   [ cmp eq reg 1 0x00000006 ]
   [ payload load 2b @ transport header + 2 => reg 1 ]
   [ objref sreg 1 set __objmap%d id 1 ]
+
+# ct helper set "cthelp1"
+ip test-ip4 output
+  [ objref type 3 name cthelp1 ]
+
+# ct helper set tcp dport map {21 : "cthelp1", 2121 : "cthelp1" }
+__objmap%d test-ip4 43
+__objmap%d test-ip4 0
+        element 00001500  : 0 [end]     element 00004908  : 0 [end]
+ip test-ip4 output
+  [ payload load 1b @ network header + 9 => reg 1 ]
+  [ cmp eq reg 1 0x00000006 ]
+  [ payload load 2b @ transport header + 2 => reg 1 ]
+  [ objref sreg 1 set __objmap%d id 1 ]
diff --git a/tests/py/nft-test.py b/tests/py/nft-test.py
index 25009217e51d..b22404076edd 100755
--- a/tests/py/nft-test.py
+++ b/tests/py/nft-test.py
@@ -885,6 +885,10 @@ def obj_process(obj_line, filename, lineno):
     obj_type = tokens[2]
     obj_spcf = ""
 
+    if obj_type == "ct" and tokens[3] == "helper":
+       obj_type = "ct helper"
+       tokens[3] = ""
+
     if len(tokens) > 3:
         obj_spcf = " ".join(tokens[3:])
 
@@ -985,7 +989,12 @@ def run_test_file(filename, force_all_family_option, specific_file):
             continue
 
         if line[0] == "%":  # Adds this object
-            obj_line = line.rstrip()[1:].split(";")
+            brace = line.rfind("}")
+            if brace < 0:
+                obj_line = line.rstrip()[1:].split(";")
+            else:
+                obj_line = (line[1:brace+1], line[brace+2:].rstrip())
+
             ret = obj_process(obj_line, filename, lineno)
             tests += 1
             if ret == -1:
-- 
2.10.2


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

* [PATCH v2 nftables 6/7] tests: add insert-failure test
  2017-03-15 15:01 [PATCH v2 nftables 0/7] ct helper set support Florian Westphal
                   ` (4 preceding siblings ...)
  2017-03-15 15:01 ` [PATCH v2 nftables 5/7] tests: py: add ct helper tests Florian Westphal
@ 2017-03-15 15:01 ` Florian Westphal
  2017-03-15 15:01 ` [PATCH v2 nftables 7/7] doc: ct helper objects and helper set support Florian Westphal
  2017-03-15 16:22 ` [PATCH v2 nftables 0/7] ct " Pablo Neira Ayuso
  7 siblings, 0 replies; 9+ messages in thread
From: Florian Westphal @ 2017-03-15 15:01 UTC (permalink / raw)
  To: netfilter-devel; +Cc: Florian Westphal

It should not be possible to add a ip6 restricted helper to ip family.

Signed-off-by: Florian Westphal <fw@strlen.de>
---
 not part of v1 series.

 tests/py/ip/objects.t |  1 +
 tests/py/nft-test.py  | 17 ++++++++++++++---
 2 files changed, 15 insertions(+), 3 deletions(-)

diff --git a/tests/py/ip/objects.t b/tests/py/ip/objects.t
index ec8e8fd916d4..742ec6af2572 100644
--- a/tests/py/ip/objects.t
+++ b/tests/py/ip/objects.t
@@ -6,6 +6,7 @@
 %cnt2 type counter;ok
 %qt1 type quota 25 mbytes;ok
 %qt2 type quota over 1 kbytes;ok
+%cthelp2 type ct helper { type \"ftp\" protocol tcp\; l3proto ip6\; };fail
 
 ip saddr 192.168.1.3 counter name "cnt2";ok
 ip saddr 192.168.1.3 counter name "cnt3";fail
diff --git a/tests/py/nft-test.py b/tests/py/nft-test.py
index b22404076edd..8d1df3bc517a 100755
--- a/tests/py/nft-test.py
+++ b/tests/py/nft-test.py
@@ -517,12 +517,23 @@ def obj_add(o, test_result, filename, lineno):
             print_error(reason, filename, lineno)
             return -1
 
-        if not _obj_exist(o, filename, lineno):
-            reason = "I have just added the " + obj_handle + \
-                     " to the table " + table.name + " but it does not exist"
+        exist = _obj_exist(o, filename, lineno)
+
+        if exist:
+            if test_result == "ok":
+                 return 0
+            reason = "I added the " + obj_handle + \
+                     " to the table " + table.name + " but it should have failed"
             print_error(reason, filename, lineno)
             return -1
 
+        if test_result == "fail":
+            return 0
+
+        reason = "I have just added the " + obj_handle + \
+                 " to the table " + table.name + " but it does not exist"
+        print_error(reason, filename, lineno)
+        return -1
 
 def obj_delete(table, filename=None, lineno=None):
     '''
-- 
2.10.2


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

* [PATCH v2 nftables 7/7] doc: ct helper objects and helper set support
  2017-03-15 15:01 [PATCH v2 nftables 0/7] ct helper set support Florian Westphal
                   ` (5 preceding siblings ...)
  2017-03-15 15:01 ` [PATCH v2 nftables 6/7] tests: add insert-failure test Florian Westphal
@ 2017-03-15 15:01 ` Florian Westphal
  2017-03-15 16:22 ` [PATCH v2 nftables 0/7] ct " Pablo Neira Ayuso
  7 siblings, 0 replies; 9+ messages in thread
From: Florian Westphal @ 2017-03-15 15:01 UTC (permalink / raw)
  To: netfilter-devel; +Cc: Florian Westphal

Signed-off-by: Florian Westphal <fw@strlen.de>
---
 changes since v1:
 use <replaceable> in cmdsynopsis, update example

 doc/nft.xml | 76 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 76 insertions(+)

diff --git a/doc/nft.xml b/doc/nft.xml
index 8ea280417742..80f201e89d37 100644
--- a/doc/nft.xml
+++ b/doc/nft.xml
@@ -950,6 +950,77 @@ filter input iif $int_ifs accept
 		</variablelist>
 
 		<refsect2>
+			<title>Ct</title>
+			<para>
+				<cmdsynopsis>
+					<command>ct</command>
+					<arg choice="req">helper</arg>
+					<arg choice="req">type</arg>
+					<arg choice="req"><replaceable>type</replaceable></arg>
+					<arg choice="req">protocol</arg>
+					<arg choice="req"><replaceable>protocol</replaceable></arg>
+					<arg choice="opt">l3proto</arg>
+					<arg choice="opt"><replaceable>family</replaceable></arg>
+				</cmdsynopsis>
+			</para>
+			<para>
+				Ct helper is used to define connection tracking helpers that can then be used in combination with the <literal>"ct helper set"</literal> statement.
+				type and protocol are mandatory, l3proto is derived from the table family by default, i.e. in the inet table the kernel will
+				try to load both the ipv4 and ipv6 helper backends, if they are supported by the kernel.
+			</para>
+			<table frame="all">
+				<title>conntrack helper specifications</title>
+				<tgroup cols='3' align='left' colsep='1' rowsep='1'>
+					<colspec colname='c1'/>
+					<colspec colname='c2'/>
+					<colspec colname='c3'/>
+					<thead>
+						<row>
+							<entry>Keyword</entry>
+							<entry>Description</entry>
+							<entry>Type</entry>
+						</row>
+					</thead>
+					<tbody>
+						<row>
+							<entry>type</entry>
+							<entry>name of helper type</entry>
+							<entry>quoted string (e.g. "ftp")</entry>
+						</row>
+						<row>
+							<entry>protocol</entry>
+							<entry>layer 4 protocol of the helper</entry>
+							<entry>string (e.g. tcp)</entry>
+						</row>
+						<row>
+							<entry>l3proto</entry>
+							<entry>layer 3 protocol of the helper</entry>
+							<entry>address family (e.g. ip)</entry>
+						</row>
+					</tbody>
+				</tgroup>
+			</table>
+			<example>
+				<title>defining and assigning ftp helper</title>
+				<para>
+				Unlike iptables, helper assignment needs to be performed after the conntrack lookup has completed, for example
+				with the default 0 hook priority.
+				</para>
+				<programlisting>
+table inet myhelpers {
+  ct helper ftp-standard {
+     type "ftp" protocol tcp
+  }
+  chain prerouting {
+      type filter hook prerouting priority 0;
+      tcp dport 21 ct helper set "ftp-standard"
+  }
+}
+				</programlisting>
+			</example>
+		</refsect2>
+
+		<refsect2>
 			<title>Counter</title>
 			<para>
 				<cmdsynopsis>
@@ -3376,6 +3447,11 @@ ip6 filter output log flags all
 						</thead>
 						<tbody>
 							<row>
+								<entry>helper</entry>
+								<entry>name of ct helper object to assign to the connection</entry>
+								<entry>quoted string</entry>
+							</row>
+							<row>
 								<entry>mark</entry>
 								<entry>Connection tracking mark</entry>
 								<entry>mark</entry>
-- 
2.10.2


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

* Re: [PATCH v2 nftables 0/7] ct helper set support
  2017-03-15 15:01 [PATCH v2 nftables 0/7] ct helper set support Florian Westphal
                   ` (6 preceding siblings ...)
  2017-03-15 15:01 ` [PATCH v2 nftables 7/7] doc: ct helper objects and helper set support Florian Westphal
@ 2017-03-15 16:22 ` Pablo Neira Ayuso
  7 siblings, 0 replies; 9+ messages in thread
From: Pablo Neira Ayuso @ 2017-03-15 16:22 UTC (permalink / raw)
  To: Florian Westphal; +Cc: netfilter-devel

On Wed, Mar 15, 2017 at 04:01:04PM +0100, Florian Westphal wrote:
> v2, with updated syntax to force type and protocol keywords
> into same statement, i.e.
> 
> ct helper ftp-standard {
>   type "ftp" protocol tcp
> }
> 
> I also cleaned up the changes to bison (reuse family_spec_explicit)
> and added a test for an invalid helper (l3proto ip6 in ip table).

Acked-by: Pablo Neira Ayuso <pablo@netfilter.org>

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

end of thread, other threads:[~2017-03-15 16:23 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-03-15 15:01 [PATCH v2 nftables 0/7] ct helper set support Florian Westphal
2017-03-15 15:01 ` [PATCH v2 nftables 1/7] src: add initial ct helper support Florian Westphal
2017-03-15 15:01 ` [PATCH v2 nftables 2/7] evaluate: refactor CMD_OBJ_QUOTA/COUNTER handling Florian Westphal
2017-03-15 15:01 ` [PATCH v2 nftables 3/7] src: allow listing all ct helpers Florian Westphal
2017-03-15 15:01 ` [PATCH v2 nftables 4/7] src: implement add/create/delete for ct helper objects Florian Westphal
2017-03-15 15:01 ` [PATCH v2 nftables 5/7] tests: py: add ct helper tests Florian Westphal
2017-03-15 15:01 ` [PATCH v2 nftables 6/7] tests: add insert-failure test Florian Westphal
2017-03-15 15:01 ` [PATCH v2 nftables 7/7] doc: ct helper objects and helper set support Florian Westphal
2017-03-15 16:22 ` [PATCH v2 nftables 0/7] ct " 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).