* [PATCH libnftnl 1/7] object: extend set/get api for u8/u16 types
2017-02-27 15:02 [PATCH 0/7] nftables: add ct helper set support Florian Westphal
@ 2017-02-27 15:02 ` Florian Westphal
2017-02-27 15:02 ` [PATCH libnftnl 2/7] src: ct helper support Florian Westphal
` (6 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: Florian Westphal @ 2017-02-27 15:02 UTC (permalink / raw)
To: netfilter-devel; +Cc: Florian Westphal
Signed-off-by: Florian Westphal <fw@strlen.de>
---
include/libnftnl/object.h | 4 ++++
src/libnftnl.map | 8 ++++++++
src/object.c | 26 ++++++++++++++++++++++++++
3 files changed, 38 insertions(+)
diff --git a/include/libnftnl/object.h b/include/libnftnl/object.h
index 074a37789734..ca3abeae66cc 100644
--- a/include/libnftnl/object.h
+++ b/include/libnftnl/object.h
@@ -44,12 +44,16 @@ void nftnl_obj_unset(struct nftnl_obj *ne, uint16_t attr);
void nftnl_obj_set_data(struct nftnl_obj *ne, uint16_t attr, const void *data,
uint32_t data_len);
void nftnl_obj_set(struct nftnl_obj *ne, uint16_t attr, const void *data);
+void nftnl_obj_set_u8(struct nftnl_obj *ne, uint16_t attr, uint8_t val);
+void nftnl_obj_set_u16(struct nftnl_obj *ne, uint16_t attr, uint16_t val);
void nftnl_obj_set_u32(struct nftnl_obj *ne, uint16_t attr, uint32_t val);
void nftnl_obj_set_u64(struct nftnl_obj *obj, uint16_t attr, uint64_t val);
void nftnl_obj_set_str(struct nftnl_obj *ne, uint16_t attr, const char *str);
const void *nftnl_obj_get_data(struct nftnl_obj *ne, uint16_t attr,
uint32_t *data_len);
const void *nftnl_obj_get(struct nftnl_obj *ne, uint16_t attr);
+uint8_t nftnl_obj_get_u8(struct nftnl_obj *ne, uint16_t attr);
+uint16_t nftnl_obj_get_u16(struct nftnl_obj *obj, uint16_t attr);
uint32_t nftnl_obj_get_u32(struct nftnl_obj *ne, uint16_t attr);
uint64_t nftnl_obj_get_u64(struct nftnl_obj *obj, uint16_t attr);
const char *nftnl_obj_get_str(struct nftnl_obj *ne, uint16_t attr);
diff --git a/src/libnftnl.map b/src/libnftnl.map
index 4282367db5b8..efe63bce98ee 100644
--- a/src/libnftnl.map
+++ b/src/libnftnl.map
@@ -301,3 +301,11 @@ global:
local: *;
};
+
+LIBNFTNL_5.1 {
+ nftnl_obj_get_u8;
+ nftnl_obj_get_u16;
+
+ nftnl_obj_set_u8;
+ nftnl_obj_set_u16;
+} LIBNFTNL_5;
diff --git a/src/object.c b/src/object.c
index 773eff6a5a18..e635f6a8ff0e 100644
--- a/src/object.c
+++ b/src/object.c
@@ -107,6 +107,18 @@ void nftnl_obj_set(struct nftnl_obj *obj, uint16_t attr, const void *data)
}
EXPORT_SYMBOL(nftnl_obj_set);
+void nftnl_obj_set_u8(struct nftnl_obj *obj, uint16_t attr, uint8_t val)
+{
+ nftnl_obj_set_data(obj, attr, &val, sizeof(uint8_t));
+}
+EXPORT_SYMBOL(nftnl_obj_set_u8);
+
+void nftnl_obj_set_u16(struct nftnl_obj *obj, uint16_t attr, uint16_t val)
+{
+ nftnl_obj_set_data(obj, attr, &val, sizeof(uint16_t));
+}
+EXPORT_SYMBOL(nftnl_obj_set_u16);
+
void nftnl_obj_set_u32(struct nftnl_obj *obj, uint16_t attr, uint32_t val)
{
nftnl_obj_set_data(obj, attr, &val, sizeof(uint32_t));
@@ -164,6 +176,20 @@ const void *nftnl_obj_get(struct nftnl_obj *obj, uint16_t attr)
}
EXPORT_SYMBOL(nftnl_obj_get);
+uint8_t nftnl_obj_get_u8(struct nftnl_obj *obj, uint16_t attr)
+{
+ const void *ret = nftnl_obj_get(obj, attr);
+ return ret == NULL ? 0 : *((uint8_t *)ret);
+}
+EXPORT_SYMBOL(nftnl_obj_get_u8);
+
+uint16_t nftnl_obj_get_u16(struct nftnl_obj *obj, uint16_t attr)
+{
+ const void *ret = nftnl_obj_get(obj, attr);
+ return ret == NULL ? 0 : *((uint16_t *)ret);
+}
+EXPORT_SYMBOL(nftnl_obj_get_u16);
+
uint32_t nftnl_obj_get_u32(struct nftnl_obj *obj, uint16_t attr)
{
const void *ret = nftnl_obj_get(obj, attr);
--
2.10.2
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH libnftnl 2/7] src: ct helper support
2017-02-27 15:02 [PATCH 0/7] nftables: add ct helper set support Florian Westphal
2017-02-27 15:02 ` [PATCH libnftnl 1/7] object: extend set/get api for u8/u16 types Florian Westphal
@ 2017-02-27 15:02 ` Florian Westphal
2017-02-27 15:02 ` [PATCH nft 3/7] netlink: BUG when object type is unknown Florian Westphal
` (5 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: Florian Westphal @ 2017-02-27 15:02 UTC (permalink / raw)
To: netfilter-devel; +Cc: Florian Westphal
add support for ct helper objects, these are used to assign helpers to
connections, similar to iptables -j CT --set-helper target.
Signed-off-by: Florian Westphal <fw@strlen.de>
---
include/libnftnl/object.h | 6 ++
include/linux/netfilter/nf_tables.h | 12 ++-
include/obj.h | 6 ++
src/Makefile.am | 1 +
src/obj/ct_helper.c | 210 ++++++++++++++++++++++++++++++++++++
src/object.c | 3 +-
6 files changed, 236 insertions(+), 2 deletions(-)
create mode 100644 src/obj/ct_helper.c
diff --git a/include/libnftnl/object.h b/include/libnftnl/object.h
index ca3abeae66cc..ccd9d19b9364 100644
--- a/include/libnftnl/object.h
+++ b/include/libnftnl/object.h
@@ -34,6 +34,12 @@ enum {
NFTNL_OBJ_QUOTA_FLAGS,
};
+enum {
+ NFTNL_OBJ_CT_HELPER_NAME = NFTNL_OBJ_BASE,
+ NFTNL_OBJ_CT_HELPER_L3PROTO,
+ NFTNL_OBJ_CT_HELPER_L4PROTO,
+};
+
struct nftnl_obj;
struct nftnl_obj *nftnl_obj_alloc(void);
diff --git a/include/linux/netfilter/nf_tables.h b/include/linux/netfilter/nf_tables.h
index 05215d30fe5c..121e79cacc49 100644
--- a/include/linux/netfilter/nf_tables.h
+++ b/include/linux/netfilter/nf_tables.h
@@ -1246,10 +1246,20 @@ enum nft_fib_flags {
NFTA_FIB_F_OIF = 1 << 4, /* restrict to oif */
};
+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/obj.h b/include/obj.h
index edbf023f5cdd..d90919f2d86b 100644
--- a/include/obj.h
+++ b/include/obj.h
@@ -30,6 +30,11 @@ struct nftnl_obj {
uint64_t consumed;
uint32_t flags;
} quota;
+ struct nftnl_obj_ct_helper {
+ uint16_t l3proto;
+ uint8_t l4proto;
+ char name[16];
+ } ct_helper;
} data;
};
@@ -49,6 +54,7 @@ struct obj_ops {
extern struct obj_ops obj_ops_counter;
extern struct obj_ops obj_ops_quota;
+extern struct obj_ops obj_ops_ct_helper;
#define nftnl_obj_data(obj) (void *)&obj->data
diff --git a/src/Makefile.am b/src/Makefile.am
index 485a8c4acbef..77b67b267672 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -53,5 +53,6 @@ libnftnl_la_SOURCES = utils.c \
expr/redir.c \
expr/hash.c \
obj/counter.c \
+ obj/ct_helper.c \
obj/quota.c \
libnftnl.map
diff --git a/src/obj/ct_helper.c b/src/obj/ct_helper.c
new file mode 100644
index 000000000000..d6d3111ecce8
--- /dev/null
+++ b/src/obj/ct_helper.c
@@ -0,0 +1,210 @@
+/*
+ * (C) 2017 Red Hat GmbH
+ * Author: Florian Westphal <fw@strlen.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <stdio.h>
+#include <stdint.h>
+#include <arpa/inet.h>
+#include <errno.h>
+#include <inttypes.h>
+
+#include <linux/netfilter/nf_tables.h>
+
+#include "internal.h"
+#include <libmnl/libmnl.h>
+#include <libnftnl/object.h>
+
+#include "obj.h"
+
+static int nftnl_obj_ct_helper_set(struct nftnl_obj *e, uint16_t type,
+ const void *data, uint32_t data_len)
+{
+ struct nftnl_obj_ct_helper *helper = nftnl_obj_data(e);
+
+ switch (type) {
+ case NFTNL_OBJ_CT_HELPER_NAME:
+ snprintf(helper->name, sizeof(helper->name), "%s", (const char *)data);
+ break;
+ case NFTNL_OBJ_CT_HELPER_L3PROTO:
+ helper->l3proto = *((uint16_t *)data);
+ break;
+ case NFTNL_OBJ_CT_HELPER_L4PROTO:
+ helper->l4proto = *((uint8_t *)data);
+ break;
+ default:
+ return -1;
+ }
+ return 0;
+}
+
+static const void *nftnl_obj_ct_helper_get(const struct nftnl_obj *e,
+ uint16_t type, uint32_t *data_len)
+{
+ struct nftnl_obj_ct_helper *helper = nftnl_obj_data(e);
+
+ switch (type) {
+ case NFTNL_OBJ_CT_HELPER_NAME:
+ *data_len = strlen(helper->name);
+ return helper->name;
+ case NFTNL_OBJ_CT_HELPER_L3PROTO:
+ *data_len = sizeof(helper->l3proto);
+ return &helper->l3proto;
+ case NFTNL_OBJ_CT_HELPER_L4PROTO:
+ *data_len = sizeof(helper->l4proto);
+ return &helper->l4proto;
+ }
+ return NULL;
+}
+
+static int nftnl_obj_ct_helper_cb(const struct nlattr *attr, void *data)
+{
+ const struct nftnl_obj_ct_helper *helper = NULL;
+ int type = mnl_attr_get_type(attr);
+ const struct nlattr **tb = data;
+
+ if (mnl_attr_type_valid(attr, NFTA_CT_HELPER_MAX) < 0)
+ return MNL_CB_OK;
+
+ switch (type) {
+ case NFTA_CT_HELPER_NAME:
+ if (mnl_attr_validate(attr, MNL_TYPE_STRING) < 0)
+ abi_breakage();
+ if (mnl_attr_get_payload_len(attr) >= sizeof(helper->name))
+ abi_breakage();
+ break;
+ case NFTA_CT_HELPER_L3PROTO:
+ if (mnl_attr_validate(attr, MNL_TYPE_U16) < 0)
+ abi_breakage();
+ break;
+ case NFTA_CT_HELPER_L4PROTO:
+ if (mnl_attr_validate(attr, MNL_TYPE_U8) < 0)
+ abi_breakage();
+ break;
+ }
+
+ tb[type] = attr;
+ return MNL_CB_OK;
+}
+
+static void
+nftnl_obj_ct_helper_build(struct nlmsghdr *nlh, const struct nftnl_obj *e)
+{
+ struct nftnl_obj_ct_helper *helper = nftnl_obj_data(e);
+
+ if (e->flags & (1 << NFTNL_OBJ_CT_HELPER_NAME))
+ mnl_attr_put_str(nlh, NFTA_CT_HELPER_NAME, helper->name);
+ if (e->flags & (1 << NFTNL_OBJ_CT_HELPER_L3PROTO))
+ mnl_attr_put_u16(nlh, NFTA_CT_HELPER_L3PROTO, htons(helper->l3proto));
+ if (e->flags & (1 << NFTNL_OBJ_CT_HELPER_L4PROTO))
+ mnl_attr_put_u8(nlh, NFTA_CT_HELPER_L4PROTO, helper->l4proto);
+}
+
+static int
+nftnl_obj_ct_helper_parse(struct nftnl_obj *e, struct nlattr *attr)
+{
+ struct nftnl_obj_ct_helper *helper = nftnl_obj_data(e);
+ struct nlattr *tb[NFTA_CT_HELPER_MAX + 1] = {};
+
+ if (mnl_attr_parse_nested(attr, nftnl_obj_ct_helper_cb, tb) < 0)
+ return -1;
+
+ if (tb[NFTA_CT_HELPER_NAME]) {
+ snprintf(helper->name, sizeof(helper->name), "%s",
+ mnl_attr_get_str(tb[NFTA_CT_HELPER_NAME]));
+ e->flags |= (1 << NFTNL_OBJ_CT_HELPER_NAME);
+ }
+ if (tb[NFTA_CT_HELPER_L3PROTO]) {
+ helper->l3proto = ntohs(mnl_attr_get_u16(tb[NFTA_CT_HELPER_L3PROTO]));
+ e->flags |= (1 << NFTNL_OBJ_CT_HELPER_L3PROTO);
+ }
+ if (tb[NFTA_CT_HELPER_L4PROTO]) {
+ helper->l4proto = mnl_attr_get_u8(tb[NFTA_CT_HELPER_L4PROTO]);
+ e->flags |= (1 << NFTNL_OBJ_CT_HELPER_L4PROTO);
+ }
+
+ return 0;
+}
+
+static int
+nftnl_obj_quota_json_parse(struct nftnl_obj *e, json_t *root,
+ struct nftnl_parse_err *err)
+{
+#ifdef JSON_PARSING
+ uint64_t bytes;
+ uint32_t flags;
+
+ if (nftnl_jansson_parse_val(root, "bytes", NFTNL_TYPE_U64, &bytes,
+ err) == 0)
+ nftnl_obj_set_u64(e, NFTNL_OBJ_QUOTA_BYTES, bytes);
+ if (nftnl_jansson_parse_val(root, "consumed", NFTNL_TYPE_U64, &bytes,
+ err) == 0)
+ nftnl_obj_set_u64(e, NFTNL_OBJ_QUOTA_CONSUMED, bytes);
+ if (nftnl_jansson_parse_val(root, "flags", NFTNL_TYPE_U32, &flags,
+ err) == 0)
+ nftnl_obj_set_u32(e, NFTNL_OBJ_QUOTA_FLAGS, flags);
+
+ return 0;
+#else
+ errno = EOPNOTSUPP;
+ return -1;
+#endif
+}
+
+static int nftnl_obj_ct_helper_export(char *buf, size_t size,
+ const struct nftnl_obj *e, int type)
+{
+ struct nftnl_obj_ct_helper *helper = nftnl_obj_data(e);
+ NFTNL_BUF_INIT(b, buf, size);
+
+ if (e->flags & (1 << NFTNL_OBJ_CT_HELPER_NAME))
+ nftnl_buf_str(&b, type, helper->name, NAME);
+ if (e->flags & (1 << NFTNL_OBJ_CT_HELPER_L3PROTO))
+ nftnl_buf_u32(&b, type, helper->l3proto, FAMILY);
+ if (e->flags & (1 << NFTNL_OBJ_CT_HELPER_L4PROTO))
+ nftnl_buf_u32(&b, type, helper->l4proto, "service");
+
+ return nftnl_buf_done(&b);
+}
+
+static int nftnl_obj_ct_helper_snprintf_default(char *buf, size_t len,
+ const struct nftnl_obj *e)
+{
+ struct nftnl_obj_ct_helper *helper = nftnl_obj_data(e);
+
+ return snprintf(buf, len, "name %s family %d protocol %d ",
+ helper->name, helper->l3proto, helper->l4proto);
+}
+
+static int nftnl_obj_ct_helper_snprintf(char *buf, size_t len, uint32_t type,
+ uint32_t flags,
+ const struct nftnl_obj *e)
+{
+ switch (type) {
+ case NFTNL_OUTPUT_DEFAULT:
+ return nftnl_obj_ct_helper_snprintf_default(buf, len, e);
+ case NFTNL_OUTPUT_JSON:
+ return nftnl_obj_ct_helper_export(buf, len, e, type);
+ default:
+ break;
+ }
+ return -1;
+}
+
+struct obj_ops obj_ops_ct_helper = {
+ .name = "ct_helper",
+ .type = NFT_OBJECT_CT_HELPER,
+ .alloc_len = sizeof(struct nftnl_obj_ct_helper),
+ .max_attr = NFTA_CT_HELPER_MAX,
+ .set = nftnl_obj_ct_helper_set,
+ .get = nftnl_obj_ct_helper_get,
+ .parse = nftnl_obj_ct_helper_parse,
+ .build = nftnl_obj_ct_helper_build,
+ .snprintf = nftnl_obj_ct_helper_snprintf,
+ .json_parse = nftnl_obj_quota_json_parse,
+};
diff --git a/src/object.c b/src/object.c
index e635f6a8ff0e..e1a5ac4757b6 100644
--- a/src/object.c
+++ b/src/object.c
@@ -28,11 +28,12 @@
static struct obj_ops *obj_ops[] = {
[NFT_OBJECT_COUNTER] = &obj_ops_counter,
[NFT_OBJECT_QUOTA] = &obj_ops_quota,
+ [NFT_OBJECT_CT_HELPER] = &obj_ops_ct_helper,
};
static struct obj_ops *nftnl_obj_ops_lookup(uint32_t type)
{
- if (type > NFT_OBJECT_QUOTA)
+ if (type > NFT_OBJECT_CT_HELPER)
return NULL;
return obj_ops[type];
--
2.10.2
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH nft 3/7] netlink: BUG when object type is unknown
2017-02-27 15:02 [PATCH 0/7] nftables: add ct helper set support Florian Westphal
2017-02-27 15:02 ` [PATCH libnftnl 1/7] object: extend set/get api for u8/u16 types Florian Westphal
2017-02-27 15:02 ` [PATCH libnftnl 2/7] src: ct helper support Florian Westphal
@ 2017-02-27 15:02 ` Florian Westphal
2017-02-27 15:02 ` [PATCH nft 4/7] src: add initial ct helper support Florian Westphal
` (4 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: Florian Westphal @ 2017-02-27 15:02 UTC (permalink / raw)
To: netfilter-devel; +Cc: Florian Westphal
This will only trigger during development when adding new object types to
the parser.
The BUG() gives a clear hint where the serialization code needs to go.
Signed-off-by: Florian Westphal <fw@strlen.de>
---
src/netlink.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/src/netlink.c b/src/netlink.c
index 1f3398225892..d2ede2a47c5d 100644
--- a/src/netlink.c
+++ b/src/netlink.c
@@ -317,6 +317,9 @@ alloc_nftnl_obj(const struct handle *h, struct obj *obj)
nftnl_obj_set_u32(nlo, NFTNL_OBJ_QUOTA_FLAGS,
obj->quota.flags);
break;
+ default:
+ BUG("Unknown type %d\n", obj->type);
+ break;
}
return nlo;
}
--
2.10.2
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH nft 4/7] src: add initial ct helper support
2017-02-27 15:02 [PATCH 0/7] nftables: add ct helper set support Florian Westphal
` (2 preceding siblings ...)
2017-02-27 15:02 ` [PATCH nft 3/7] netlink: BUG when object type is unknown Florian Westphal
@ 2017-02-27 15:02 ` Florian Westphal
2017-02-27 15:02 ` [PATCH nft 5/7] evaluate: refactor CMD_OBJ_QUOTA/COUNTER handling Florian Westphal
` (3 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: Florian Westphal @ 2017-02-27 15:02 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>
---
include/ct.h | 1 +
include/linux/netfilter/nf_tables.h | 3 +-
include/rule.h | 7 ++++
src/ct.c | 10 +++++
src/netlink.c | 16 ++++++++
src/parser_bison.y | 80 ++++++++++++++++++++++++++++++++++++-
src/rule.c | 35 +++++++++++++++-
src/statement.c | 10 ++++-
8 files changed, 157 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 05215d30fe5c..9fa2aa49a36c 100644
--- a/include/linux/netfilter/nf_tables.h
+++ b/include/linux/netfilter/nf_tables.h
@@ -1249,7 +1249,8 @@ enum nft_fib_flags {
#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 f5160daf4d8e..6a495a9a36be 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 31c7a4b1beda..bd9b25bed1f9 100644
--- a/src/ct.c
+++ b/src/ct.c
@@ -346,6 +346,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 d2ede2a47c5d..5f2ba107bfd3 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;
@@ -1812,6 +1821,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 b295bfde2ed3..3ff11ff18cfe 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;
@@ -469,7 +470,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
@@ -634,6 +635,10 @@ static void location_update(struct location *loc, struct location *rhs, int n)
%destructor { expr_free($$); } tcp_hdr_expr
%type <val> tcp_hdr_field
+%type <val> ct_l4protoname ct_l3protoname
+%type <string> ct_obj_kind
+%destructor { xfree($$); } ct_obj_kind
+
%%
input : /* empty */
@@ -1160,6 +1165,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 */
@@ -1354,6 +1377,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"); }
@@ -2546,6 +2579,40 @@ quota_obj : quota_config
}
;
+ct_obj_kind : STRING { $$ = $1; }
+ ;
+
+ct_l3protoname : IP { $$ = NFPROTO_IPV4; }
+ | IP6 { $$ = NFPROTO_IPV6; }
+ ;
+
+ct_l4protoname : TCP { $$ = IPPROTO_TCP; }
+ | UDP { $$ = IPPROTO_UDP; }
+ ;
+
+ct_config : TYPE QUOTED_STRING 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;
+ }
+ }
+ | PROTOCOL ct_l4protoname stmt_seperator
+ {
+ $<obj>0->ct.l4proto = $2;
+ }
+ | L3PROTOCOL ct_l3protoname stmt_seperator
+ {
+ $<obj>0->ct.l4proto = $2;
+ }
+ ;
+
relational_expr : expr /* implicit */ rhs_expr
{
$$ = relational_expr_alloc(&@$, OP_IMPLICIT, $1, $2);
@@ -2988,7 +3055,16 @@ ct_stmt : CT ct_key SET expr
YYERROR;
}
- $$ = ct_stmt_alloc(&@$, key, $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, $4);
+ break;
+ }
}
;
diff --git a/src/rule.c b/src/rule.c
index b47076f000ee..eb31f0e9ec5e 100644
--- a/src/rule.c
+++ b/src/rule.c
@@ -1171,6 +1171,29 @@ struct obj *obj_lookup(const struct table *table, const char *name,
return NULL;
}
+static const char *proto_name_proto(uint8_t l4, char *b, size_t l)
+{
+ switch (l4) {
+ case IPPROTO_UDP: return "udp";
+ case IPPROTO_TCP: return "tcp";
+ }
+
+ snprintf(b, l, "%d\n", l4);
+ return b;
+}
+
+static const char *proto_name_family(uint16_t family, char *b, size_t l)
+{
+ switch (family) {
+ case NFPROTO_IPV4: return "ip";
+ case NFPROTO_IPV6: return "ip6";
+ case NFPROTO_INET: return "inet";
+ }
+
+ snprintf(b, l, "%d\n", family);
+ return b;
+}
+
static void obj_print_data(const struct obj *obj,
struct print_fmt_options *opts)
{
@@ -1201,6 +1224,15 @@ static void obj_print_data(const struct obj *obj,
}
}
break;
+ case NFT_OBJECT_CT_HELPER: {
+ char buf[16];
+
+ printf("ct helper %s {\n", obj->handle.obj);
+ printf("\t\ttype \"%s\"\n", obj->ct.helper_name);
+ printf("\t\tl3proto %s\n", proto_name_family(obj->ct.l3proto, buf, sizeof(buf)));
+ printf("\t\tprotocol %s", proto_name_proto(obj->ct.l4proto, buf, sizeof(buf)));
+ break;
+ }
default:
printf("unknown {%s", opts->nl);
break;
@@ -1210,11 +1242,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 nft 5/7] evaluate: refactor CMD_OBJ_QUOTA/COUNTER handling
2017-02-27 15:02 [PATCH 0/7] nftables: add ct helper set support Florian Westphal
` (3 preceding siblings ...)
2017-02-27 15:02 ` [PATCH nft 4/7] src: add initial ct helper support Florian Westphal
@ 2017-02-27 15:02 ` Florian Westphal
2017-02-27 15:02 ` [PATCH nft 6/7] src: allow listing all ct helpers Florian Westphal
` (2 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: Florian Westphal @ 2017-02-27 15:02 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>
---
src/evaluate.c | 32 ++++++++++++++++++++------------
1 file changed, 20 insertions(+), 12 deletions(-)
diff --git a/src/evaluate.c b/src/evaluate.c
index 87da2fd83597..4ac55e177d54 100644
--- a/src/evaluate.c
+++ b/src/evaluate.c
@@ -2916,12 +2916,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)
@@ -2977,18 +2994,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 nft 6/7] src: allow listing all ct helpers
2017-02-27 15:02 [PATCH 0/7] nftables: add ct helper set support Florian Westphal
` (4 preceding siblings ...)
2017-02-27 15:02 ` [PATCH nft 5/7] evaluate: refactor CMD_OBJ_QUOTA/COUNTER handling Florian Westphal
@ 2017-02-27 15:02 ` Florian Westphal
2017-02-27 15:02 ` [PATCH nft 7/7] src: implement add/create/delete for ct helper objects Florian Westphal
2017-02-28 11:30 ` [PATCH 0/7] nftables: add ct helper set support Pablo Neira Ayuso
7 siblings, 0 replies; 9+ messages in thread
From: Florian Westphal @ 2017-02-27 15:02 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>
---
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 6a495a9a36be..882fc3350c6c 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 4ac55e177d54..4c8c1e8a4229 100644
--- a/src/evaluate.c
+++ b/src/evaluate.c
@@ -2999,6 +2999,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 3ff11ff18cfe..076e59ae603d 100644
--- a/src/parser_bison.y
+++ b/src/parser_bison.y
@@ -985,6 +985,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 eb31f0e9ec5e..889aa719afaa 100644
--- a/src/rule.c
+++ b/src/rule.c
@@ -1468,6 +1468,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 nft 7/7] src: implement add/create/delete for ct helper objects
2017-02-27 15:02 [PATCH 0/7] nftables: add ct helper set support Florian Westphal
` (5 preceding siblings ...)
2017-02-27 15:02 ` [PATCH nft 6/7] src: allow listing all ct helpers Florian Westphal
@ 2017-02-27 15:02 ` Florian Westphal
2017-02-28 11:30 ` [PATCH 0/7] nftables: add ct helper set support Pablo Neira Ayuso
7 siblings, 0 replies; 9+ messages in thread
From: Florian Westphal @ 2017-02-27 15:02 UTC (permalink / raw)
To: netfilter-devel; +Cc: Florian Westphal
Signed-off-by: Florian Westphal <fw@strlen.de>
---
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 882fc3350c6c..3edf7b9f36bb 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 4c8c1e8a4229..2f943c238e6f 100644
--- a/src/evaluate.c
+++ b/src/evaluate.c
@@ -2887,6 +2887,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);
@@ -2910,6 +2911,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);
@@ -2997,6 +2999,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 076e59ae603d..22d922784f19 100644
--- a/src/parser_bison.y
+++ b/src/parser_bison.y
@@ -558,8 +558,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
@@ -809,6 +809,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
@@ -875,6 +888,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
@@ -915,6 +941,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
@@ -985,6 +1024,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;
@@ -2632,6 +2684,13 @@ ct_config : TYPE QUOTED_STRING 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 889aa719afaa..e412eac362fb 100644
--- a/src/rule.c
+++ b/src/rule.c
@@ -883,6 +883,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:
@@ -999,6 +1000,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);
@@ -1069,6 +1071,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);
}
@@ -1468,6 +1473,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:
@@ -1616,6 +1622,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
* Re: [PATCH 0/7] nftables: add ct helper set support
2017-02-27 15:02 [PATCH 0/7] nftables: add ct helper set support Florian Westphal
` (6 preceding siblings ...)
2017-02-27 15:02 ` [PATCH nft 7/7] src: implement add/create/delete for ct helper objects Florian Westphal
@ 2017-02-28 11:30 ` Pablo Neira Ayuso
7 siblings, 0 replies; 9+ messages in thread
From: Pablo Neira Ayuso @ 2017-02-28 11:30 UTC (permalink / raw)
To: Florian Westphal; +Cc: netfilter-devel
On Mon, Feb 27, 2017 at 04:02:48PM +0100, Florian Westphal wrote:
> This series adds initial support to set conntrack helpers via
> the nft objref infrastructure.
>
> As -next is closed I will not push this yet since kernel support
> is still missing.
>
> Currently only supported attributes are:
>
> type (e.g. "ftp", "sip)
> protocol (udp or tcp)
> l3proto (ip, ip6).
>
> l3proto is optional, the kernel will infer it from
> the family, i.e. in "inet" case kernel will check for both ipv4 and ipv6.
>
> Let me know in case you spot any isses, patches #3 and #5 could already
> be pushed to nft master since they are just preparation patches.
Series looks good, thanks Florian.
Acked-by: Pablo Neira Ayuso <pablo@netfilter.org>
^ permalink raw reply [flat|nested] 9+ messages in thread