* [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).