netfilter-devel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH nft 00/11] complete typeof support
@ 2019-12-17 17:16 Pablo Neira Ayuso
  2019-12-17 17:16 ` [PATCH nft 01/11] meta: add parse and build userdata interface Pablo Neira Ayuso
                   ` (10 more replies)
  0 siblings, 11 replies; 12+ messages in thread
From: Pablo Neira Ayuso @ 2019-12-17 17:16 UTC (permalink / raw)
  To: netfilter-devel; +Cc: fw

Hi Florian,

This completes your patchset adding typeof support for the remaining
primary expression.

Feel free to apply and push this out on top of your patchset.

P.S: testcases/maps/typeof_maps_0 fails:

/dev/stdin:14:28-30: Error: datatype mismatch, map expects string,
mapping expression has type IPv4 address
                ct mark set ip daddr map @m1
                            ~~~~~~~~     ^^^

There is a typo in the map definition:

/dev/stdin:14:28-30: Error: datatype mismatch, map expects string,
mapping expression has type IPv4 address
                ct mark set ip daddr map @m1
                            ~~~~~~~~     ^^^

This should be

                ct mark set osf name map @m1

dump file also needs an adjustment, you can fix this before pushing
this out.

Thanks!

P.S: I might follow up at some point to expose this userdata
attributes through libnftnl, later. Meanwhile, I have just pushed
out the libnftnl nesting dependencies.

Pablo Neira Ayuso (11):
  meta: add parse and build userdata interface
  exthdr: add exthdr_desc_id enum and use it
  exthdr: add parse and build userdata interface
  socket: add parse and build userdata interface
  osf: add parse and build userdata interface
  ct: add parse and build userdata interface
  numgen: add parse and build userdata interface
  hash: add parse and build userdata interface
  rt: add parse and build userdata interface
  fib: add parse and build userdata interface
  xfrm: add parse and build userdata interface

 include/exthdr.h |  15 ++++++++
 src/ct.c         |  56 ++++++++++++++++++++++++++++++
 src/expression.c |  13 +++++--
 src/exthdr.c     | 102 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/fib.c        |  60 ++++++++++++++++++++++++++++++--
 src/hash.c       |  72 +++++++++++++++++++++++++++++++++++++++
 src/meta.c       |  51 ++++++++++++++++++++++++++++
 src/numgen.c     |  62 +++++++++++++++++++++++++++++++++
 src/osf.c        |  13 +++++++
 src/rt.c         |  51 ++++++++++++++++++++++++++++
 src/socket.c     |  51 ++++++++++++++++++++++++++++
 src/xfrm.c       |  61 +++++++++++++++++++++++++++++++++
 12 files changed, 603 insertions(+), 4 deletions(-)

-- 
2.11.0


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

* [PATCH nft 01/11] meta: add parse and build userdata interface
  2019-12-17 17:16 [PATCH nft 00/11] complete typeof support Pablo Neira Ayuso
@ 2019-12-17 17:16 ` Pablo Neira Ayuso
  2019-12-17 17:16 ` [PATCH nft 02/11] exthdr: add exthdr_desc_id enum and use it Pablo Neira Ayuso
                   ` (9 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Pablo Neira Ayuso @ 2019-12-17 17:16 UTC (permalink / raw)
  To: netfilter-devel; +Cc: fw

Add support for meta userdata area.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
 src/expression.c |  4 ++--
 src/meta.c       | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 53 insertions(+), 2 deletions(-)

diff --git a/src/expression.c b/src/expression.c
index a7bbde7eec1a..a79c6f55a548 100644
--- a/src/expression.c
+++ b/src/expression.c
@@ -1226,8 +1226,8 @@ const struct expr_ops *expr_ops(const struct expr *e)
 const struct expr_ops *expr_ops_by_type(enum expr_types etype)
 {
 	switch (etype) {
-	case EXPR_PAYLOAD:
-		return &payload_expr_ops;
+	case EXPR_PAYLOAD: return &payload_expr_ops;
+	case EXPR_META: return &meta_expr_ops;
 	default:
 		break;
 	}
diff --git a/src/meta.c b/src/meta.c
index 796d8e941486..135f84b51c55 100644
--- a/src/meta.c
+++ b/src/meta.c
@@ -807,6 +807,55 @@ static void meta_expr_pctx_update(struct proto_ctx *ctx,
 	}
 }
 
+#define NFTNL_UDATA_META_KEY 0
+#define NFTNL_UDATA_META_MAX 1
+
+static int meta_expr_build_udata(struct nftnl_udata_buf *udbuf,
+				 const struct expr *expr)
+{
+	nftnl_udata_put_u32(udbuf, NFTNL_UDATA_META_KEY, expr->meta.key);
+
+	return 0;
+}
+
+static int meta_parse_udata(const struct nftnl_udata *attr, void *data)
+{
+	const struct nftnl_udata **ud = data;
+	uint8_t type = nftnl_udata_type(attr);
+	uint8_t len = nftnl_udata_len(attr);
+
+	switch (type) {
+	case NFTNL_UDATA_META_KEY:
+		if (len != sizeof(uint32_t))
+			return -1;
+		break;
+	default:
+		return 0;
+	}
+
+	ud[type] = attr;
+	return 0;
+}
+
+static struct expr *meta_expr_parse_udata(const struct nftnl_udata *attr)
+{
+	const struct nftnl_udata *ud[NFTNL_UDATA_META_MAX + 1] = {};
+	uint32_t key;
+	int err;
+
+	err = nftnl_udata_parse(nftnl_udata_get(attr), nftnl_udata_len(attr),
+				meta_parse_udata, ud);
+	if (err < 0)
+		return NULL;
+
+	if (!ud[NFTNL_UDATA_META_KEY])
+		return NULL;
+
+	key = nftnl_udata_get_u32(ud[NFTNL_UDATA_META_KEY]);
+
+	return meta_expr_alloc(&internal_location, key);
+}
+
 const struct expr_ops meta_expr_ops = {
 	.type		= EXPR_META,
 	.name		= "meta",
@@ -815,6 +864,8 @@ const struct expr_ops meta_expr_ops = {
 	.cmp		= meta_expr_cmp,
 	.clone		= meta_expr_clone,
 	.pctx_update	= meta_expr_pctx_update,
+	.build_udata	= meta_expr_build_udata,
+	.parse_udata	= meta_expr_parse_udata,
 };
 
 struct expr *meta_expr_alloc(const struct location *loc, enum nft_meta_keys key)
-- 
2.11.0


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

* [PATCH nft 02/11] exthdr: add exthdr_desc_id enum and use it
  2019-12-17 17:16 [PATCH nft 00/11] complete typeof support Pablo Neira Ayuso
  2019-12-17 17:16 ` [PATCH nft 01/11] meta: add parse and build userdata interface Pablo Neira Ayuso
@ 2019-12-17 17:16 ` Pablo Neira Ayuso
  2019-12-17 17:16 ` [PATCH nft 03/11] exthdr: add parse and build userdata interface Pablo Neira Ayuso
                   ` (8 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Pablo Neira Ayuso @ 2019-12-17 17:16 UTC (permalink / raw)
  To: netfilter-devel; +Cc: fw

This allows to identify the exthdr protocol from the userdata area.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
 include/exthdr.h | 15 +++++++++++++++
 src/exthdr.c     | 28 ++++++++++++++++++++++++++++
 2 files changed, 43 insertions(+)

diff --git a/include/exthdr.h b/include/exthdr.h
index 3959a65c7713..c9a3c211b8c4 100644
--- a/include/exthdr.h
+++ b/include/exthdr.h
@@ -5,6 +5,20 @@
 #include <tcpopt.h>
 #include <ipopt.h>
 
+enum exthdr_desc_id {
+	EXTHDR_DESC_UNKNOWN	= 0,
+	EXTHDR_DESC_HBH,
+	EXTHDR_DESC_RT,
+	EXTHDR_DESC_RT0,
+	EXTHDR_DESC_RT2,
+	EXTHDR_DESC_SRH,
+	EXTHDR_DESC_FRAG,
+	EXTHDR_DESC_DST,
+	EXTHDR_DESC_MH,
+	__EXTHDR_DESC_MAX
+};
+#define EXTHDR_DESC_MAX	(__EXTHDR_DESC_MAX - 1)
+
 /**
  * struct exthdr_desc - extension header description
  *
@@ -14,6 +28,7 @@
  */
 struct exthdr_desc {
 	const char			*name;
+	enum exthdr_desc_id		id;
 	uint8_t				type;
 	int				proto_key;
 	struct proto_hdr_template	templates[10];
diff --git a/src/exthdr.c b/src/exthdr.c
index e1ec6f3dd52b..925b52329003 100644
--- a/src/exthdr.c
+++ b/src/exthdr.c
@@ -23,6 +23,26 @@
 #include <expression.h>
 #include <statement.h>
 
+static const struct exthdr_desc *exthdr_definitions[PROTO_DESC_MAX + 1] = {
+	[EXTHDR_DESC_HBH]	= &exthdr_hbh,
+	[EXTHDR_DESC_RT]	= &exthdr_rt,
+	[EXTHDR_DESC_RT0]	= &exthdr_rt0,
+	[EXTHDR_DESC_RT2]	= &exthdr_rt2,
+	[EXTHDR_DESC_SRH]	= &exthdr_rt4,
+	[EXTHDR_DESC_FRAG]	= &exthdr_frag,
+	[EXTHDR_DESC_DST]	= &exthdr_dst,
+	[EXTHDR_DESC_MH]	= &exthdr_mh,
+};
+
+static const struct exthdr_desc *exthdr_find_desc(enum exthdr_desc_id desc_id)
+{
+	if (desc_id >= EXTHDR_DESC_UNKNOWN &&
+	    desc_id <= EXTHDR_DESC_MAX)
+		return exthdr_definitions[desc_id];
+
+	return NULL;
+}
+
 static void exthdr_expr_print(const struct expr *expr, struct output_ctx *octx)
 {
 	if (expr->exthdr.op == NFT_EXTHDR_OP_TCPOPT) {
@@ -281,6 +301,7 @@ bool exthdr_find_template(struct expr *expr, const struct expr *mask, unsigned i
 
 const struct exthdr_desc exthdr_hbh = {
 	.name		= "hbh",
+	.id		= EXTHDR_DESC_HBH,
 	.type		= IPPROTO_HOPOPTS,
 	.templates	= {
 		[HBHHDR_NEXTHDR]	= HBH_FIELD("nexthdr", ip6h_nxt, &inet_protocol_type),
@@ -294,6 +315,7 @@ const struct exthdr_desc exthdr_hbh = {
 
 const struct exthdr_desc exthdr_rt2 = {
 	.name           = "rt2",
+	.id		= EXTHDR_DESC_RT2,
 	.type           = IPPROTO_ROUTING,
 	.proto_key	= 2,
 	.templates	= {
@@ -307,6 +329,7 @@ const struct exthdr_desc exthdr_rt2 = {
 
 const struct exthdr_desc exthdr_rt0 = {
 	.name           = "rt0",
+	.id		= EXTHDR_DESC_RT0,
 	.type           = IPPROTO_ROUTING,
 	.proto_key      = 0,
 	.templates	= {
@@ -322,6 +345,7 @@ const struct exthdr_desc exthdr_rt0 = {
 
 const struct exthdr_desc exthdr_rt4 = {
 	.name		= "srh",
+	.id		= EXTHDR_DESC_SRH,
 	.type		= IPPROTO_ROUTING,
 	.proto_key	= 4,
 	.templates      = {
@@ -340,6 +364,7 @@ const struct exthdr_desc exthdr_rt4 = {
 
 const struct exthdr_desc exthdr_rt = {
 	.name		= "rt",
+	.id		= EXTHDR_DESC_RT,
 	.type		= IPPROTO_ROUTING,
 	.proto_key      = -1,
 #if 0
@@ -366,6 +391,7 @@ const struct exthdr_desc exthdr_rt = {
 
 const struct exthdr_desc exthdr_frag = {
 	.name		= "frag",
+	.id		= EXTHDR_DESC_FRAG,
 	.type		= IPPROTO_FRAGMENT,
 	.templates	= {
 		[FRAGHDR_NEXTHDR]	= FRAG_FIELD("nexthdr", ip6f_nxt, &inet_protocol_type),
@@ -392,6 +418,7 @@ const struct exthdr_desc exthdr_frag = {
 
 const struct exthdr_desc exthdr_dst = {
 	.name		= "dst",
+	.id		= EXTHDR_DESC_DST,
 	.type		= IPPROTO_DSTOPTS,
 	.templates	= {
 		[DSTHDR_NEXTHDR]	= DST_FIELD("nexthdr", ip6d_nxt, &inet_protocol_type),
@@ -438,6 +465,7 @@ const struct datatype mh_type_type = {
 
 const struct exthdr_desc exthdr_mh = {
 	.name		= "mh",
+	.id		= EXTHDR_DESC_MH,
 	.type		= IPPROTO_MH,
 	.templates	= {
 		[MHHDR_NEXTHDR]		= MH_FIELD("nexthdr", ip6mh_proto, &inet_protocol_type),
-- 
2.11.0


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

* [PATCH nft 03/11] exthdr: add parse and build userdata interface
  2019-12-17 17:16 [PATCH nft 00/11] complete typeof support Pablo Neira Ayuso
  2019-12-17 17:16 ` [PATCH nft 01/11] meta: add parse and build userdata interface Pablo Neira Ayuso
  2019-12-17 17:16 ` [PATCH nft 02/11] exthdr: add exthdr_desc_id enum and use it Pablo Neira Ayuso
@ 2019-12-17 17:16 ` Pablo Neira Ayuso
  2019-12-17 17:16 ` [PATCH nft 04/11] socket: " Pablo Neira Ayuso
                   ` (7 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Pablo Neira Ayuso @ 2019-12-17 17:16 UTC (permalink / raw)
  To: netfilter-devel; +Cc: fw

Add support for meta userdata area.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
 src/expression.c |  1 +
 src/exthdr.c     | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 75 insertions(+)

diff --git a/src/expression.c b/src/expression.c
index a79c6f55a548..847c88ee82c5 100644
--- a/src/expression.c
+++ b/src/expression.c
@@ -1227,6 +1227,7 @@ const struct expr_ops *expr_ops_by_type(enum expr_types etype)
 {
 	switch (etype) {
 	case EXPR_PAYLOAD: return &payload_expr_ops;
+	case EXPR_EXTHDR: return &exthdr_expr_ops;
 	case EXPR_META: return &meta_expr_ops;
 	default:
 		break;
diff --git a/src/exthdr.c b/src/exthdr.c
index 925b52329003..0b23e0d38b91 100644
--- a/src/exthdr.c
+++ b/src/exthdr.c
@@ -91,6 +91,78 @@ static void exthdr_expr_clone(struct expr *new, const struct expr *expr)
 	new->exthdr.flags = expr->exthdr.flags;
 }
 
+#define NFTNL_UDATA_EXTHDR_DESC 0
+#define NFTNL_UDATA_EXTHDR_TYPE 1
+#define NFTNL_UDATA_EXTHDR_MAX 2
+
+static int exthdr_parse_udata(const struct nftnl_udata *attr, void *data)
+{
+	const struct nftnl_udata **ud = data;
+	uint8_t type = nftnl_udata_type(attr);
+	uint8_t len = nftnl_udata_len(attr);
+
+	switch (type) {
+	case NFTNL_UDATA_EXTHDR_DESC:
+	case NFTNL_UDATA_EXTHDR_TYPE:
+		if (len != sizeof(uint32_t))
+			return -1;
+		break;
+	default:
+		return 0;
+	}
+
+	ud[type] = attr;
+	return 0;
+}
+
+static struct expr *exthdr_expr_parse_udata(const struct nftnl_udata *attr)
+{
+	const struct nftnl_udata *ud[NFTNL_UDATA_EXTHDR_MAX + 1] = {};
+	const struct exthdr_desc *desc;
+	unsigned int type;
+	uint32_t desc_id;
+	int err;
+
+	err = nftnl_udata_parse(nftnl_udata_get(attr), nftnl_udata_len(attr),
+				exthdr_parse_udata, ud);
+	if (err < 0)
+		return NULL;
+
+	if (!ud[NFTNL_UDATA_EXTHDR_DESC] ||
+	    !ud[NFTNL_UDATA_EXTHDR_TYPE])
+		return NULL;
+
+	desc_id = nftnl_udata_get_u32(ud[NFTNL_UDATA_EXTHDR_DESC]);
+	desc = exthdr_find_desc(desc_id);
+	if (!desc)
+		return NULL;
+
+	type = nftnl_udata_get_u32(ud[NFTNL_UDATA_EXTHDR_TYPE]);
+
+	return exthdr_expr_alloc(&internal_location, desc, type);
+}
+
+static unsigned int expr_exthdr_type(const struct exthdr_desc *desc,
+				     const struct proto_hdr_template *tmpl)
+{
+	unsigned int offset = (unsigned int)(tmpl - &desc->templates[0]);
+
+	return offset / sizeof(*tmpl);
+}
+
+static int exthdr_expr_build_udata(struct nftnl_udata_buf *udbuf,
+				   const struct expr *expr)
+{
+	const struct proto_hdr_template *tmpl = expr->exthdr.tmpl;
+	const struct exthdr_desc *desc = expr->exthdr.desc;
+	unsigned int type = expr_exthdr_type(desc, tmpl);
+
+	nftnl_udata_put_u32(udbuf, NFTNL_UDATA_EXTHDR_DESC, desc->id);
+	nftnl_udata_put_u32(udbuf, NFTNL_UDATA_EXTHDR_TYPE, type);
+
+	return 0;
+}
+
 const struct expr_ops exthdr_expr_ops = {
 	.type		= EXPR_EXTHDR,
 	.name		= "exthdr",
@@ -98,6 +170,8 @@ const struct expr_ops exthdr_expr_ops = {
 	.json		= exthdr_expr_json,
 	.cmp		= exthdr_expr_cmp,
 	.clone		= exthdr_expr_clone,
+	.build_udata	= exthdr_expr_build_udata,
+	.parse_udata	= exthdr_expr_parse_udata,
 };
 
 static const struct proto_hdr_template exthdr_unknown_template =
-- 
2.11.0


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

* [PATCH nft 04/11] socket: add parse and build userdata interface
  2019-12-17 17:16 [PATCH nft 00/11] complete typeof support Pablo Neira Ayuso
                   ` (2 preceding siblings ...)
  2019-12-17 17:16 ` [PATCH nft 03/11] exthdr: add parse and build userdata interface Pablo Neira Ayuso
@ 2019-12-17 17:16 ` Pablo Neira Ayuso
  2019-12-17 17:16 ` [PATCH nft 05/11] osf: " Pablo Neira Ayuso
                   ` (6 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Pablo Neira Ayuso @ 2019-12-17 17:16 UTC (permalink / raw)
  To: netfilter-devel; +Cc: fw

Add support for meta userdata area.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
 src/expression.c |  1 +
 src/socket.c     | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 52 insertions(+)

diff --git a/src/expression.c b/src/expression.c
index 847c88ee82c5..191bc2be104b 100644
--- a/src/expression.c
+++ b/src/expression.c
@@ -1229,6 +1229,7 @@ const struct expr_ops *expr_ops_by_type(enum expr_types etype)
 	case EXPR_PAYLOAD: return &payload_expr_ops;
 	case EXPR_EXTHDR: return &exthdr_expr_ops;
 	case EXPR_META: return &meta_expr_ops;
+	case EXPR_SOCKET: return &socket_expr_ops;
 	default:
 		break;
 	}
diff --git a/src/socket.c b/src/socket.c
index e10b32267762..d78a163a21fa 100644
--- a/src/socket.c
+++ b/src/socket.c
@@ -43,6 +43,55 @@ static void socket_expr_clone(struct expr *new, const struct expr *expr)
 	new->socket.key = expr->socket.key;
 }
 
+#define NFTNL_UDATA_SOCKET_KEY 0
+#define NFTNL_UDATA_SOCKET_MAX 1
+
+static int socket_expr_build_udata(struct nftnl_udata_buf *udbuf,
+				 const struct expr *expr)
+{
+	nftnl_udata_put_u32(udbuf, NFTNL_UDATA_SOCKET_KEY, expr->socket.key);
+
+	return 0;
+}
+
+static int socket_parse_udata(const struct nftnl_udata *attr, void *data)
+{
+	const struct nftnl_udata **ud = data;
+	uint8_t type = nftnl_udata_type(attr);
+	uint8_t len = nftnl_udata_len(attr);
+
+	switch (type) {
+	case NFTNL_UDATA_SOCKET_KEY:
+		if (len != sizeof(uint32_t))
+			return -1;
+		break;
+	default:
+		return 0;
+	}
+
+	ud[type] = attr;
+	return 0;
+}
+
+static struct expr *socket_expr_parse_udata(const struct nftnl_udata *attr)
+{
+	const struct nftnl_udata *ud[NFTNL_UDATA_SOCKET_MAX + 1] = {};
+	uint32_t key;
+	int err;
+
+	err = nftnl_udata_parse(nftnl_udata_get(attr), nftnl_udata_len(attr),
+				socket_parse_udata, ud);
+	if (err < 0)
+		return NULL;
+
+	if (!ud[NFTNL_UDATA_SOCKET_KEY])
+		return NULL;
+
+	key = nftnl_udata_get_u32(ud[NFTNL_UDATA_SOCKET_KEY]);
+
+	return socket_expr_alloc(&internal_location, key);
+}
+
 const struct expr_ops socket_expr_ops = {
 	.type		= EXPR_SOCKET,
 	.name		= "socket",
@@ -50,6 +99,8 @@ const struct expr_ops socket_expr_ops = {
 	.json		= socket_expr_json,
 	.cmp		= socket_expr_cmp,
 	.clone		= socket_expr_clone,
+	.build_udata	= socket_expr_build_udata,
+	.parse_udata	= socket_expr_parse_udata,
 };
 
 struct expr *socket_expr_alloc(const struct location *loc, enum nft_socket_keys key)
-- 
2.11.0


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

* [PATCH nft 05/11] osf: add parse and build userdata interface
  2019-12-17 17:16 [PATCH nft 00/11] complete typeof support Pablo Neira Ayuso
                   ` (3 preceding siblings ...)
  2019-12-17 17:16 ` [PATCH nft 04/11] socket: " Pablo Neira Ayuso
@ 2019-12-17 17:16 ` Pablo Neira Ayuso
  2019-12-17 17:16 ` [PATCH nft 06/11] ct: " Pablo Neira Ayuso
                   ` (5 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Pablo Neira Ayuso @ 2019-12-17 17:16 UTC (permalink / raw)
  To: netfilter-devel; +Cc: fw

Add support for meta userdata area.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
 src/expression.c |  1 +
 src/osf.c        | 13 +++++++++++++
 2 files changed, 14 insertions(+)

diff --git a/src/expression.c b/src/expression.c
index 191bc2be104b..7d198222c90b 100644
--- a/src/expression.c
+++ b/src/expression.c
@@ -1230,6 +1230,7 @@ const struct expr_ops *expr_ops_by_type(enum expr_types etype)
 	case EXPR_EXTHDR: return &exthdr_expr_ops;
 	case EXPR_META: return &meta_expr_ops;
 	case EXPR_SOCKET: return &socket_expr_ops;
+	case EXPR_OSF: return &osf_expr_ops;
 	default:
 		break;
 	}
diff --git a/src/osf.c b/src/osf.c
index f0c22393cd85..cb58315d714d 100644
--- a/src/osf.c
+++ b/src/osf.c
@@ -37,6 +37,17 @@ static bool osf_expr_cmp(const struct expr *e1, const struct expr *e2)
 	       (e1->osf.flags == e2->osf.flags);
 }
 
+static int osf_expr_build_udata(struct nftnl_udata_buf *udbuf,
+				 const struct expr *expr)
+{
+	return 0;
+}
+
+static struct expr *osf_expr_parse_udata(const struct nftnl_udata *attr)
+{
+	return osf_expr_alloc(&internal_location, 0, 0);
+}
+
 const struct expr_ops osf_expr_ops = {
 	.type		= EXPR_OSF,
 	.name		= "osf",
@@ -44,6 +55,8 @@ const struct expr_ops osf_expr_ops = {
 	.clone		= osf_expr_clone,
 	.cmp		= osf_expr_cmp,
 	.json		= osf_expr_json,
+	.parse_udata	= osf_expr_parse_udata,
+	.build_udata	= osf_expr_build_udata,
 };
 
 struct expr *osf_expr_alloc(const struct location *loc, const uint8_t ttl,
-- 
2.11.0


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

* [PATCH nft 06/11] ct: add parse and build userdata interface
  2019-12-17 17:16 [PATCH nft 00/11] complete typeof support Pablo Neira Ayuso
                   ` (4 preceding siblings ...)
  2019-12-17 17:16 ` [PATCH nft 05/11] osf: " Pablo Neira Ayuso
@ 2019-12-17 17:16 ` Pablo Neira Ayuso
  2019-12-17 17:16 ` [PATCH nft 07/11] numgen: " Pablo Neira Ayuso
                   ` (4 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Pablo Neira Ayuso @ 2019-12-17 17:16 UTC (permalink / raw)
  To: netfilter-devel; +Cc: fw

Add support for meta userdata area.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
 src/ct.c         | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/expression.c |  1 +
 2 files changed, 57 insertions(+)

diff --git a/src/ct.c b/src/ct.c
index 9e6a8351ffb2..db1dabd319e9 100644
--- a/src/ct.c
+++ b/src/ct.c
@@ -367,6 +367,60 @@ static void ct_expr_pctx_update(struct proto_ctx *ctx, const struct expr *expr)
 	proto_ctx_update(ctx, left->ct.base + 1, &expr->location, desc);
 }
 
+#define NFTNL_UDATA_CT_KEY 0
+#define NFTNL_UDATA_CT_DIR 1
+#define NFTNL_UDATA_CT_MAX 2
+
+static int ct_expr_build_udata(struct nftnl_udata_buf *udbuf,
+			       const struct expr *expr)
+{
+	nftnl_udata_put_u32(udbuf, NFTNL_UDATA_CT_KEY, expr->ct.key);
+	nftnl_udata_put_u32(udbuf, NFTNL_UDATA_CT_DIR, expr->ct.direction);
+
+	return 0;
+}
+
+static int ct_parse_udata(const struct nftnl_udata *attr, void *data)
+{
+	const struct nftnl_udata **ud = data;
+	uint8_t type = nftnl_udata_type(attr);
+	uint8_t len = nftnl_udata_len(attr);
+
+	switch (type) {
+	case NFTNL_UDATA_CT_KEY:
+	case NFTNL_UDATA_CT_DIR:
+		if (len != sizeof(uint32_t))
+			return -1;
+		break;
+	default:
+		return 0;
+	}
+
+	ud[type] = attr;
+	return 0;
+}
+
+static struct expr *ct_expr_parse_udata(const struct nftnl_udata *attr)
+{
+	const struct nftnl_udata *ud[NFTNL_UDATA_CT_MAX + 1] = {};
+	uint32_t key, dir;
+	int err;
+
+	err = nftnl_udata_parse(nftnl_udata_get(attr), nftnl_udata_len(attr),
+				ct_parse_udata, ud);
+	if (err < 0)
+		return NULL;
+
+	if (!ud[NFTNL_UDATA_CT_KEY] ||
+	    !ud[NFTNL_UDATA_CT_DIR])
+		return NULL;
+
+	key = nftnl_udata_get_u32(ud[NFTNL_UDATA_CT_KEY]);
+	dir = nftnl_udata_get_u32(ud[NFTNL_UDATA_CT_DIR]);
+
+	return ct_expr_alloc(&internal_location, key, dir);
+}
+
 const struct expr_ops ct_expr_ops = {
 	.type		= EXPR_CT,
 	.name		= "ct",
@@ -375,6 +429,8 @@ const struct expr_ops ct_expr_ops = {
 	.cmp		= ct_expr_cmp,
 	.clone		= ct_expr_clone,
 	.pctx_update	= ct_expr_pctx_update,
+	.parse_udata	= ct_expr_parse_udata,
+	.build_udata	= ct_expr_build_udata,
 };
 
 struct expr *ct_expr_alloc(const struct location *loc, enum nft_ct_keys key,
diff --git a/src/expression.c b/src/expression.c
index 7d198222c90b..14bf329e25c3 100644
--- a/src/expression.c
+++ b/src/expression.c
@@ -1231,6 +1231,7 @@ const struct expr_ops *expr_ops_by_type(enum expr_types etype)
 	case EXPR_META: return &meta_expr_ops;
 	case EXPR_SOCKET: return &socket_expr_ops;
 	case EXPR_OSF: return &osf_expr_ops;
+	case EXPR_CT: return &ct_expr_ops;
 	default:
 		break;
 	}
-- 
2.11.0


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

* [PATCH nft 07/11] numgen: add parse and build userdata interface
  2019-12-17 17:16 [PATCH nft 00/11] complete typeof support Pablo Neira Ayuso
                   ` (5 preceding siblings ...)
  2019-12-17 17:16 ` [PATCH nft 06/11] ct: " Pablo Neira Ayuso
@ 2019-12-17 17:16 ` Pablo Neira Ayuso
  2019-12-17 17:16 ` [PATCH nft 08/11] hash: " Pablo Neira Ayuso
                   ` (3 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Pablo Neira Ayuso @ 2019-12-17 17:16 UTC (permalink / raw)
  To: netfilter-devel; +Cc: fw

Add support for meta userdata area.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
 src/expression.c |  1 +
 src/numgen.c     | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 63 insertions(+)

diff --git a/src/expression.c b/src/expression.c
index 14bf329e25c3..1791454ea466 100644
--- a/src/expression.c
+++ b/src/expression.c
@@ -1232,6 +1232,7 @@ const struct expr_ops *expr_ops_by_type(enum expr_types etype)
 	case EXPR_SOCKET: return &socket_expr_ops;
 	case EXPR_OSF: return &osf_expr_ops;
 	case EXPR_CT: return &ct_expr_ops;
+	case EXPR_NUMGEN: return &numgen_expr_ops;
 	default:
 		break;
 	}
diff --git a/src/numgen.c b/src/numgen.c
index 8318d0a2a796..ea2b262605f7 100644
--- a/src/numgen.c
+++ b/src/numgen.c
@@ -51,6 +51,66 @@ static void numgen_expr_clone(struct expr *new, const struct expr *expr)
 	new->numgen.offset = expr->numgen.offset;
 }
 
+#define NFTNL_UDATA_NUMGEN_TYPE 0
+#define NFTNL_UDATA_NUMGEN_MOD 1
+#define NFTNL_UDATA_NUMGEN_OFFSET 2
+#define NFTNL_UDATA_NUMGEN_MAX 3
+
+static int numgen_expr_build_udata(struct nftnl_udata_buf *udbuf,
+				   const struct expr *expr)
+{
+        nftnl_udata_put_u32(udbuf, NFTNL_UDATA_NUMGEN_TYPE, expr->numgen.type);
+        nftnl_udata_put_u32(udbuf, NFTNL_UDATA_NUMGEN_MOD, expr->numgen.mod);
+        nftnl_udata_put_u32(udbuf, NFTNL_UDATA_NUMGEN_OFFSET, expr->numgen.offset);
+
+        return 0;
+}
+
+static int numgen_parse_udata(const struct nftnl_udata *attr, void *data)
+{
+        const struct nftnl_udata **ud = data;
+        uint8_t type = nftnl_udata_type(attr);
+        uint8_t len = nftnl_udata_len(attr);
+
+        switch (type) {
+        case NFTNL_UDATA_NUMGEN_TYPE:
+        case NFTNL_UDATA_NUMGEN_MOD:
+        case NFTNL_UDATA_NUMGEN_OFFSET:
+                if (len != sizeof(uint32_t))
+                        return -1;
+                break;
+        default:
+                return 0;
+        }
+
+        ud[type] = attr;
+        return 0;
+}
+
+static struct expr *numgen_expr_parse_udata(const struct nftnl_udata *attr)
+{
+        const struct nftnl_udata *ud[NFTNL_UDATA_NUMGEN_MAX + 1] = {};
+	enum nft_ng_types type;
+	uint32_t mod, offset;
+        int err;
+
+        err = nftnl_udata_parse(nftnl_udata_get(attr), nftnl_udata_len(attr),
+                                numgen_parse_udata, ud);
+        if (err < 0)
+                return NULL;
+
+        if (!ud[NFTNL_UDATA_NUMGEN_TYPE] ||
+	    !ud[NFTNL_UDATA_NUMGEN_MOD] ||
+	    !ud[NFTNL_UDATA_NUMGEN_OFFSET])
+                return NULL;
+
+	type = nftnl_udata_get_u32(ud[NFTNL_UDATA_NUMGEN_TYPE]);
+	mod = nftnl_udata_get_u32(ud[NFTNL_UDATA_NUMGEN_MOD]);
+	offset = nftnl_udata_get_u32(ud[NFTNL_UDATA_NUMGEN_OFFSET]);
+
+	return numgen_expr_alloc(&internal_location, type, mod, offset);
+}
+
 const struct expr_ops numgen_expr_ops = {
 	.type		= EXPR_NUMGEN,
 	.name		= "numgen",
@@ -58,6 +118,8 @@ const struct expr_ops numgen_expr_ops = {
 	.json		= numgen_expr_json,
 	.cmp		= numgen_expr_cmp,
 	.clone		= numgen_expr_clone,
+	.parse_udata	= numgen_expr_parse_udata,
+	.build_udata	= numgen_expr_build_udata,
 };
 
 struct expr *numgen_expr_alloc(const struct location *loc,
-- 
2.11.0


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

* [PATCH nft 08/11] hash: add parse and build userdata interface
  2019-12-17 17:16 [PATCH nft 00/11] complete typeof support Pablo Neira Ayuso
                   ` (6 preceding siblings ...)
  2019-12-17 17:16 ` [PATCH nft 07/11] numgen: " Pablo Neira Ayuso
@ 2019-12-17 17:16 ` Pablo Neira Ayuso
  2019-12-17 17:17 ` [PATCH nft 09/11] rt: " Pablo Neira Ayuso
                   ` (2 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Pablo Neira Ayuso @ 2019-12-17 17:16 UTC (permalink / raw)
  To: netfilter-devel; +Cc: fw

Add support for meta userdata area.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
 src/expression.c |  1 +
 src/hash.c       | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 73 insertions(+)

diff --git a/src/expression.c b/src/expression.c
index 1791454ea466..7cca342b2f1a 100644
--- a/src/expression.c
+++ b/src/expression.c
@@ -1233,6 +1233,7 @@ const struct expr_ops *expr_ops_by_type(enum expr_types etype)
 	case EXPR_OSF: return &osf_expr_ops;
 	case EXPR_CT: return &ct_expr_ops;
 	case EXPR_NUMGEN: return &numgen_expr_ops;
+	case EXPR_HASH: return &hash_expr_ops;
 	default:
 		break;
 	}
diff --git a/src/hash.c b/src/hash.c
index 08e09099024e..42c504073ae8 100644
--- a/src/hash.c
+++ b/src/hash.c
@@ -61,6 +61,76 @@ static void hash_expr_destroy(struct expr *expr)
 	expr_free(expr->hash.expr);
 }
 
+#define NFTNL_UDATA_HASH_TYPE 0
+#define NFTNL_UDATA_HASH_OFFSET 1
+#define NFTNL_UDATA_HASH_MOD 2
+#define NFTNL_UDATA_HASH_SEED 3
+#define NFTNL_UDATA_HASH_SEED_SET 4
+#define NFTNL_UDATA_HASH_MAX 5
+
+static int hash_expr_build_udata(struct nftnl_udata_buf *udbuf,
+				 const struct expr *expr)
+{
+	nftnl_udata_put_u32(udbuf, NFTNL_UDATA_HASH_TYPE, expr->hash.type);
+	nftnl_udata_put_u32(udbuf, NFTNL_UDATA_HASH_OFFSET, expr->hash.offset);
+	nftnl_udata_put_u32(udbuf, NFTNL_UDATA_HASH_MOD, expr->hash.mod);
+	nftnl_udata_put_u32(udbuf, NFTNL_UDATA_HASH_SEED, expr->hash.seed);
+	nftnl_udata_put_u32(udbuf, NFTNL_UDATA_HASH_SEED_SET, expr->hash.seed_set);
+
+	return 0;
+}
+
+static int hash_parse_udata(const struct nftnl_udata *attr, void *data)
+{
+	const struct nftnl_udata **ud = data;
+	uint8_t type = nftnl_udata_type(attr);
+	uint8_t len = nftnl_udata_len(attr);
+
+	switch (type) {
+	case NFTNL_UDATA_HASH_TYPE:
+	case NFTNL_UDATA_HASH_OFFSET:
+	case NFTNL_UDATA_HASH_SEED:
+	case NFTNL_UDATA_HASH_SEED_SET:
+	case NFTNL_UDATA_HASH_MOD:
+		if (len != sizeof(uint32_t))
+			return -1;
+		break;
+	default:
+		return 0;
+	}
+
+	ud[type] = attr;
+	return 0;
+}
+
+static struct expr *hash_expr_parse_udata(const struct nftnl_udata *attr)
+{
+	const struct nftnl_udata *ud[NFTNL_UDATA_HASH_MAX + 1] = {};
+	uint32_t type, seed, seed_set, mod, offset;
+	int err;
+
+	err = nftnl_udata_parse(nftnl_udata_get(attr), nftnl_udata_len(attr),
+				hash_parse_udata, ud);
+	if (err < 0)
+		return NULL;
+
+	if (!ud[NFTNL_UDATA_HASH_TYPE] ||
+	    !ud[NFTNL_UDATA_HASH_OFFSET] ||
+	    !ud[NFTNL_UDATA_HASH_SEED] ||
+	    !ud[NFTNL_UDATA_HASH_MOD] ||
+	    !ud[NFTNL_UDATA_HASH_SEED_SET])
+		return NULL;
+
+	type = nftnl_udata_get_u32(ud[NFTNL_UDATA_HASH_TYPE]);
+	offset = nftnl_udata_get_u32(ud[NFTNL_UDATA_HASH_OFFSET]);
+	seed = nftnl_udata_get_u32(ud[NFTNL_UDATA_HASH_SEED]);
+	seed_set = nftnl_udata_get_u32(ud[NFTNL_UDATA_HASH_SEED_SET]);
+	mod = nftnl_udata_get_u32(ud[NFTNL_UDATA_HASH_MOD]);
+
+	return hash_expr_alloc(&internal_location, mod, seed_set, seed,
+			       offset, type);
+}
+
 const struct expr_ops hash_expr_ops = {
 	.type		= EXPR_HASH,
 	.name		= "hash",
@@ -69,6 +139,8 @@ const struct expr_ops hash_expr_ops = {
 	.cmp		= hash_expr_cmp,
 	.clone		= hash_expr_clone,
 	.destroy	= hash_expr_destroy,
+	.parse_udata	= hash_expr_parse_udata,
+	.build_udata	= hash_expr_build_udata,
 };
 
 struct expr *hash_expr_alloc(const struct location *loc,
-- 
2.11.0


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

* [PATCH nft 09/11] rt: add parse and build userdata interface
  2019-12-17 17:16 [PATCH nft 00/11] complete typeof support Pablo Neira Ayuso
                   ` (7 preceding siblings ...)
  2019-12-17 17:16 ` [PATCH nft 08/11] hash: " Pablo Neira Ayuso
@ 2019-12-17 17:17 ` Pablo Neira Ayuso
  2019-12-17 17:17 ` [PATCH nft 10/11] fib: " Pablo Neira Ayuso
  2019-12-17 17:17 ` [PATCH nft 11/11] xfrm: " Pablo Neira Ayuso
  10 siblings, 0 replies; 12+ messages in thread
From: Pablo Neira Ayuso @ 2019-12-17 17:17 UTC (permalink / raw)
  To: netfilter-devel; +Cc: fw

Add support for meta userdata area.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
 src/expression.c |  1 +
 src/rt.c         | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 52 insertions(+)

diff --git a/src/expression.c b/src/expression.c
index 7cca342b2f1a..386309b5ca27 100644
--- a/src/expression.c
+++ b/src/expression.c
@@ -1234,6 +1234,7 @@ const struct expr_ops *expr_ops_by_type(enum expr_types etype)
 	case EXPR_CT: return &ct_expr_ops;
 	case EXPR_NUMGEN: return &numgen_expr_ops;
 	case EXPR_HASH: return &hash_expr_ops;
+	case EXPR_RT: return &rt_expr_ops;
 	default:
 		break;
 	}
diff --git a/src/rt.c b/src/rt.c
index b19c44d6eefe..d7aa5edd93a3 100644
--- a/src/rt.c
+++ b/src/rt.c
@@ -114,6 +114,55 @@ static void rt_expr_clone(struct expr *new, const struct expr *expr)
 	new->rt.key = expr->rt.key;
 }
 
+#define NFTNL_UDATA_RT_KEY 0
+#define NFTNL_UDATA_RT_MAX 1
+
+static int rt_expr_build_udata(struct nftnl_udata_buf *udbuf,
+				 const struct expr *expr)
+{
+	nftnl_udata_put_u32(udbuf, NFTNL_UDATA_RT_KEY, expr->rt.key);
+
+	return 0;
+}
+
+static int rt_parse_udata(const struct nftnl_udata *attr, void *data)
+{
+	const struct nftnl_udata **ud = data;
+	uint8_t type = nftnl_udata_type(attr);
+	uint8_t len = nftnl_udata_len(attr);
+
+	switch (type) {
+	case NFTNL_UDATA_RT_KEY:
+		if (len != sizeof(uint32_t))
+			return -1;
+		break;
+	default:
+		return 0;
+	}
+
+	ud[type] = attr;
+	return 0;
+}
+
+static struct expr *rt_expr_parse_udata(const struct nftnl_udata *attr)
+{
+	const struct nftnl_udata *ud[NFTNL_UDATA_RT_MAX + 1] = {};
+	uint32_t key;
+	int err;
+
+	err = nftnl_udata_parse(nftnl_udata_get(attr), nftnl_udata_len(attr),
+				rt_parse_udata, ud);
+	if (err < 0)
+		return NULL;
+
+	if (!ud[NFTNL_UDATA_RT_KEY])
+		return NULL;
+
+	key = nftnl_udata_get_u32(ud[NFTNL_UDATA_RT_KEY]);
+
+	return rt_expr_alloc(&internal_location, key, false);
+}
+
 const struct expr_ops rt_expr_ops = {
 	.type		= EXPR_RT,
 	.name		= "rt",
@@ -121,6 +170,8 @@ const struct expr_ops rt_expr_ops = {
 	.json		= rt_expr_json,
 	.cmp		= rt_expr_cmp,
 	.clone		= rt_expr_clone,
+	.parse_udata	= rt_expr_parse_udata,
+	.build_udata	= rt_expr_build_udata,
 };
 
 struct expr *rt_expr_alloc(const struct location *loc, enum nft_rt_keys key,
-- 
2.11.0


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

* [PATCH nft 10/11] fib: add parse and build userdata interface
  2019-12-17 17:16 [PATCH nft 00/11] complete typeof support Pablo Neira Ayuso
                   ` (8 preceding siblings ...)
  2019-12-17 17:17 ` [PATCH nft 09/11] rt: " Pablo Neira Ayuso
@ 2019-12-17 17:17 ` Pablo Neira Ayuso
  2019-12-17 17:17 ` [PATCH nft 11/11] xfrm: " Pablo Neira Ayuso
  10 siblings, 0 replies; 12+ messages in thread
From: Pablo Neira Ayuso @ 2019-12-17 17:17 UTC (permalink / raw)
  To: netfilter-devel; +Cc: fw

Add support for meta userdata area.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
 src/expression.c |  1 +
 src/fib.c        | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++++++--
 2 files changed, 59 insertions(+), 2 deletions(-)

diff --git a/src/expression.c b/src/expression.c
index 386309b5ca27..43d2c9f94a84 100644
--- a/src/expression.c
+++ b/src/expression.c
@@ -1235,6 +1235,7 @@ const struct expr_ops *expr_ops_by_type(enum expr_types etype)
 	case EXPR_NUMGEN: return &numgen_expr_ops;
 	case EXPR_HASH: return &hash_expr_ops;
 	case EXPR_RT: return &rt_expr_ops;
+	case EXPR_FIB: return &fib_expr_ops;
 	default:
 		break;
 	}
diff --git a/src/fib.c b/src/fib.c
index f2bfef1deda1..c6ad0f9c5d15 100644
--- a/src/fib.c
+++ b/src/fib.c
@@ -1,7 +1,7 @@
 /*
  * FIB expression.
  *
- * Copyright (c) Red Hat GmbH.  Author: Florian Westphal <fw@strlen.de>
+ * Copyright (c) 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 version 2 as
@@ -91,7 +91,7 @@ static void fib_expr_print(const struct expr *expr, struct output_ctx *octx)
 
 static bool fib_expr_cmp(const struct expr *e1, const struct expr *e2)
 {
-	return  e1->fib.result == e2->fib.result &&
+	return	e1->fib.result == e2->fib.result &&
 		e1->fib.flags == e2->fib.flags;
 }
 
@@ -101,6 +101,60 @@ static void fib_expr_clone(struct expr *new, const struct expr *expr)
 	new->fib.flags= expr->fib.flags;
 }
 
+#define NFTNL_UDATA_FIB_RESULT 0
+#define NFTNL_UDATA_FIB_FLAGS 1
+#define NFTNL_UDATA_FIB_MAX 2
+
+static int fib_expr_build_udata(struct nftnl_udata_buf *udbuf,
+				 const struct expr *expr)
+{
+	nftnl_udata_put_u32(udbuf, NFTNL_UDATA_FIB_RESULT, expr->fib.result);
+	nftnl_udata_put_u32(udbuf, NFTNL_UDATA_FIB_FLAGS, expr->fib.flags);
+
+	return 0;
+}
+
+static int fib_parse_udata(const struct nftnl_udata *attr, void *data)
+{
+	const struct nftnl_udata **ud = data;
+	uint8_t type = nftnl_udata_type(attr);
+	uint8_t len = nftnl_udata_len(attr);
+
+	switch (type) {
+	case NFTNL_UDATA_FIB_RESULT:
+	case NFTNL_UDATA_FIB_FLAGS:
+		if (len != sizeof(uint32_t))
+			return -1;
+		break;
+	default:
+		return 0;
+	}
+
+	ud[type] = attr;
+	return 0;
+}
+
+static struct expr *fib_expr_parse_udata(const struct nftnl_udata *attr)
+{
+	const struct nftnl_udata *ud[NFTNL_UDATA_FIB_MAX + 1] = {};
+	uint32_t flags, result;
+	int err;
+
+	err = nftnl_udata_parse(nftnl_udata_get(attr), nftnl_udata_len(attr),
+				fib_parse_udata, ud);
+	if (err < 0)
+		return NULL;
+
+	if (!ud[NFTNL_UDATA_FIB_RESULT] ||
+	    !ud[NFTNL_UDATA_FIB_FLAGS])
+		return NULL;
+
+	result = nftnl_udata_get_u32(ud[NFTNL_UDATA_FIB_RESULT]);
+	flags = nftnl_udata_get_u32(ud[NFTNL_UDATA_FIB_FLAGS]);
+
+	return fib_expr_alloc(&internal_location, flags, result);
+}
+
 const struct expr_ops fib_expr_ops = {
 	.type		= EXPR_FIB,
 	.name		= "fib",
@@ -108,6 +162,8 @@ const struct expr_ops fib_expr_ops = {
 	.json		= fib_expr_json,
 	.cmp		= fib_expr_cmp,
 	.clone		= fib_expr_clone,
+	.parse_udata	= fib_expr_parse_udata,
+	.build_udata	= fib_expr_build_udata,
 };
 
 struct expr *fib_expr_alloc(const struct location *loc,
-- 
2.11.0


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

* [PATCH nft 11/11] xfrm: add parse and build userdata interface
  2019-12-17 17:16 [PATCH nft 00/11] complete typeof support Pablo Neira Ayuso
                   ` (9 preceding siblings ...)
  2019-12-17 17:17 ` [PATCH nft 10/11] fib: " Pablo Neira Ayuso
@ 2019-12-17 17:17 ` Pablo Neira Ayuso
  10 siblings, 0 replies; 12+ messages in thread
From: Pablo Neira Ayuso @ 2019-12-17 17:17 UTC (permalink / raw)
  To: netfilter-devel; +Cc: fw

Add support for meta userdata area.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
 src/expression.c |  1 +
 src/xfrm.c       | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 62 insertions(+)

diff --git a/src/expression.c b/src/expression.c
index 43d2c9f94a84..cb11cda43792 100644
--- a/src/expression.c
+++ b/src/expression.c
@@ -1236,6 +1236,7 @@ const struct expr_ops *expr_ops_by_type(enum expr_types etype)
 	case EXPR_HASH: return &hash_expr_ops;
 	case EXPR_RT: return &rt_expr_ops;
 	case EXPR_FIB: return &fib_expr_ops;
+	case EXPR_XFRM: return &xfrm_expr_ops;
 	default:
 		break;
 	}
diff --git a/src/xfrm.c b/src/xfrm.c
index 4dd53c3213f6..d0773ab789f1 100644
--- a/src/xfrm.c
+++ b/src/xfrm.c
@@ -91,6 +91,65 @@ static void xfrm_expr_clone(struct expr *new, const struct expr *expr)
 	memcpy(&new->xfrm, &expr->xfrm, sizeof(new->xfrm));
 }
 
+#define NFTNL_UDATA_XFRM_KEY 0
+#define NFTNL_UDATA_XFRM_SPNUM 1
+#define NFTNL_UDATA_XFRM_DIR 2
+#define NFTNL_UDATA_XFRM_MAX 3
+
+static int xfrm_expr_build_udata(struct nftnl_udata_buf *udbuf,
+				 const struct expr *expr)
+{
+	nftnl_udata_put_u32(udbuf, NFTNL_UDATA_XFRM_KEY, expr->xfrm.key);
+	nftnl_udata_put_u32(udbuf, NFTNL_UDATA_XFRM_SPNUM, expr->xfrm.spnum);
+	nftnl_udata_put_u32(udbuf, NFTNL_UDATA_XFRM_DIR, expr->xfrm.direction);
+
+	return 0;
+}
+
+static int xfrm_parse_udata(const struct nftnl_udata *attr, void *data)
+{
+	const struct nftnl_udata **ud = data;
+	uint8_t type = nftnl_udata_type(attr);
+	uint8_t len = nftnl_udata_len(attr);
+
+	switch (type) {
+	case NFTNL_UDATA_XFRM_KEY:
+	case NFTNL_UDATA_XFRM_SPNUM:
+	case NFTNL_UDATA_XFRM_DIR:
+		if (len != sizeof(uint32_t))
+			return -1;
+		break;
+	default:
+		return 0;
+	}
+
+	ud[type] = attr;
+	return 0;
+}
+
+static struct expr *xfrm_expr_parse_udata(const struct nftnl_udata *attr)
+{
+	const struct nftnl_udata *ud[NFTNL_UDATA_XFRM_MAX + 1] = {};
+	uint32_t key, dir, spnum;
+	int err;
+
+	err = nftnl_udata_parse(nftnl_udata_get(attr), nftnl_udata_len(attr),
+				xfrm_parse_udata, ud);
+	if (err < 0)
+		return NULL;
+
+	if (!ud[NFTNL_UDATA_XFRM_KEY] ||
+	    !ud[NFTNL_UDATA_XFRM_DIR] ||
+	    !ud[NFTNL_UDATA_XFRM_SPNUM])
+		return NULL;
+
+	key = nftnl_udata_get_u32(ud[NFTNL_UDATA_XFRM_KEY]);
+	dir = nftnl_udata_get_u32(ud[NFTNL_UDATA_XFRM_DIR]);
+	spnum = nftnl_udata_get_u32(ud[NFTNL_UDATA_XFRM_SPNUM]);
+
+	return xfrm_expr_alloc(&internal_location, dir, spnum, key);
+}
+
 const struct expr_ops xfrm_expr_ops = {
 	.type		= EXPR_XFRM,
 	.name		= "xfrm",
@@ -98,6 +157,8 @@ const struct expr_ops xfrm_expr_ops = {
 	.json		= xfrm_expr_json,
 	.cmp		= xfrm_expr_cmp,
 	.clone		= xfrm_expr_clone,
+	.parse_udata	= xfrm_expr_parse_udata,
+	.build_udata	= xfrm_expr_build_udata,
 };
 
 struct expr *xfrm_expr_alloc(const struct location *loc,
-- 
2.11.0


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

end of thread, other threads:[~2019-12-17 17:17 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-12-17 17:16 [PATCH nft 00/11] complete typeof support Pablo Neira Ayuso
2019-12-17 17:16 ` [PATCH nft 01/11] meta: add parse and build userdata interface Pablo Neira Ayuso
2019-12-17 17:16 ` [PATCH nft 02/11] exthdr: add exthdr_desc_id enum and use it Pablo Neira Ayuso
2019-12-17 17:16 ` [PATCH nft 03/11] exthdr: add parse and build userdata interface Pablo Neira Ayuso
2019-12-17 17:16 ` [PATCH nft 04/11] socket: " Pablo Neira Ayuso
2019-12-17 17:16 ` [PATCH nft 05/11] osf: " Pablo Neira Ayuso
2019-12-17 17:16 ` [PATCH nft 06/11] ct: " Pablo Neira Ayuso
2019-12-17 17:16 ` [PATCH nft 07/11] numgen: " Pablo Neira Ayuso
2019-12-17 17:16 ` [PATCH nft 08/11] hash: " Pablo Neira Ayuso
2019-12-17 17:17 ` [PATCH nft 09/11] rt: " Pablo Neira Ayuso
2019-12-17 17:17 ` [PATCH nft 10/11] fib: " Pablo Neira Ayuso
2019-12-17 17:17 ` [PATCH nft 11/11] xfrm: " 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).