netfilter-devel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH nft 1/4] evaluate: set byteorder as lhs expression context in stmt_evaluate_arg()
@ 2017-02-28  0:00 Pablo Neira Ayuso
  2017-02-28  0:01 ` [PATCH nft 2/4] src: rename set_keytype_alloc() to set_datatype_alloc() Pablo Neira Ayuso
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Pablo Neira Ayuso @ 2017-02-28  0:00 UTC (permalink / raw)
  To: netfilter-devel

stmt_evaluate_arg() needs to take the lhs map expression byteorder in
order to evaluate the lhs of mappings accordingly.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
 src/evaluate.c | 24 +++++++++++++++---------
 1 file changed, 15 insertions(+), 9 deletions(-)

diff --git a/src/evaluate.c b/src/evaluate.c
index 87da2fd83597..21f1a475d5e9 100644
--- a/src/evaluate.c
+++ b/src/evaluate.c
@@ -1721,9 +1721,9 @@ static int stmt_evaluate_expr(struct eval_ctx *ctx, struct stmt *stmt)
 
 static int stmt_evaluate_arg(struct eval_ctx *ctx, struct stmt *stmt,
 			     const struct datatype *dtype, unsigned int len,
-			     struct expr **expr)
+			     enum byteorder byteorder, struct expr **expr)
 {
-	expr_set_context(&ctx->ectx, dtype, len);
+	__expr_set_context(&ctx->ectx, dtype, byteorder, len, 0);
 	if (expr_evaluate(ctx, expr) < 0)
 		return -1;
 
@@ -1737,7 +1737,7 @@ static int stmt_evaluate_arg(struct eval_ctx *ctx, struct stmt *stmt,
 
 static int stmt_evaluate_verdict(struct eval_ctx *ctx, struct stmt *stmt)
 {
-	if (stmt_evaluate_arg(ctx, stmt, &verdict_type, 0, &stmt->expr) < 0)
+	if (stmt_evaluate_arg(ctx, stmt, &verdict_type, 0, 0, &stmt->expr) < 0)
 		return -1;
 
 	switch (stmt->expr->ops->type) {
@@ -1777,7 +1777,7 @@ static int stmt_evaluate_payload(struct eval_ctx *ctx, struct stmt *stmt)
 
 	payload = stmt->payload.expr;
 	if (stmt_evaluate_arg(ctx, stmt, payload->dtype, payload->len,
-			      &stmt->payload.val) < 0)
+			      payload->byteorder, &stmt->payload.val) < 0)
 		return -1;
 
 	need_csum = stmt_evaluate_payload_need_csum(payload);
@@ -1908,6 +1908,7 @@ static int stmt_evaluate_meta(struct eval_ctx *ctx, struct stmt *stmt)
 	return stmt_evaluate_arg(ctx, stmt,
 				 stmt->meta.tmpl->dtype,
 				 stmt->meta.tmpl->len,
+				 stmt->meta.tmpl->byteorder,
 				 &stmt->meta.expr);
 }
 
@@ -1916,6 +1917,7 @@ static int stmt_evaluate_ct(struct eval_ctx *ctx, struct stmt *stmt)
 	return stmt_evaluate_arg(ctx, stmt,
 				 stmt->ct.tmpl->dtype,
 				 stmt->ct.tmpl->len,
+				 stmt->ct.tmpl->byteorder,
 				 &stmt->ct.expr);
 }
 
@@ -2306,7 +2308,8 @@ static int evaluate_addr(struct eval_ctx *ctx, struct stmt *stmt,
 		len   = 16 * BITS_PER_BYTE;
 	}
 
-	return stmt_evaluate_arg(ctx, stmt, dtype, len, expr);
+	return stmt_evaluate_arg(ctx, stmt, dtype, len, BYTEORDER_BIG_ENDIAN,
+				 expr);
 }
 
 static int nat_evaluate_transport(struct eval_ctx *ctx, struct stmt *stmt,
@@ -2321,7 +2324,7 @@ static int nat_evaluate_transport(struct eval_ctx *ctx, struct stmt *stmt,
 
 	return stmt_evaluate_arg(ctx, stmt,
 				 &inet_service_type, 2 * BITS_PER_BYTE,
-				 expr);
+				 BYTEORDER_BIG_ENDIAN, expr);
 }
 
 static int stmt_evaluate_nat(struct eval_ctx *ctx, struct stmt *stmt)
@@ -2400,6 +2403,7 @@ static int stmt_evaluate_dup(struct eval_ctx *ctx, struct stmt *stmt)
 		if (stmt->dup.dev != NULL) {
 			err = stmt_evaluate_arg(ctx, stmt, &ifindex_type,
 						sizeof(uint32_t) * BITS_PER_BYTE,
+						BYTEORDER_HOST_ENDIAN,
 						&stmt->dup.dev);
 			if (err < 0)
 				return err;
@@ -2414,7 +2418,7 @@ static int stmt_evaluate_dup(struct eval_ctx *ctx, struct stmt *stmt)
 
 		err = stmt_evaluate_arg(ctx, stmt, &ifindex_type,
 					sizeof(uint32_t) * BITS_PER_BYTE,
-					&stmt->dup.to);
+					BYTEORDER_HOST_ENDIAN, &stmt->dup.to);
 		if (err < 0)
 			return err;
 		break;
@@ -2436,7 +2440,7 @@ static int stmt_evaluate_fwd(struct eval_ctx *ctx, struct stmt *stmt)
 
 		err = stmt_evaluate_arg(ctx, stmt, &ifindex_type,
 					sizeof(uint32_t) * BITS_PER_BYTE,
-					&stmt->fwd.to);
+					BYTEORDER_HOST_ENDIAN, &stmt->fwd.to);
 		if (err < 0)
 			return err;
 		break;
@@ -2450,6 +2454,7 @@ static int stmt_evaluate_queue(struct eval_ctx *ctx, struct stmt *stmt)
 {
 	if (stmt->queue.queue != NULL) {
 		if (stmt_evaluate_arg(ctx, stmt, &integer_type, 16,
+				      BYTEORDER_HOST_ENDIAN,
 				      &stmt->queue.queue) < 0)
 			return -1;
 		if (!expr_is_constant(stmt->queue.queue))
@@ -2490,6 +2495,7 @@ static int stmt_evaluate_set(struct eval_ctx *ctx, struct stmt *stmt)
 	if (stmt_evaluate_arg(ctx, stmt,
 			      stmt->set.set->set->keytype,
 			      stmt->set.set->set->keylen,
+			      stmt->set.set->set->keytype->byteorder,
 			      &stmt->set.key) < 0)
 		return -1;
 	if (expr_is_constant(stmt->set.key))
@@ -2576,7 +2582,7 @@ static int stmt_evaluate_objref(struct eval_ctx *ctx, struct stmt *stmt)
 
 	if (stmt_evaluate_arg(ctx, stmt,
 			      &string_type, NFT_OBJ_MAXNAMELEN * BITS_PER_BYTE,
-			      &stmt->objref.expr) < 0)
+			      BYTEORDER_HOST_ENDIAN, &stmt->objref.expr) < 0)
 		return -1;
 
 	if (!expr_is_constant(stmt->objref.expr))
-- 
2.1.4


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

* [PATCH nft 2/4] src: rename set_keytype_alloc() to set_datatype_alloc()
  2017-02-28  0:00 [PATCH nft 1/4] evaluate: set byteorder as lhs expression context in stmt_evaluate_arg() Pablo Neira Ayuso
@ 2017-02-28  0:01 ` Pablo Neira Ayuso
  2017-02-28  0:01 ` [PATCH nft 3/4] netlink: rework NFTNL_SET_USERDATA to accomodate new attributes Pablo Neira Ayuso
  2017-02-28  0:01 ` [PATCH nft 4/4] src: store byteorder for set data Pablo Neira Ayuso
  2 siblings, 0 replies; 4+ messages in thread
From: Pablo Neira Ayuso @ 2017-02-28  0:01 UTC (permalink / raw)
  To: netfilter-devel

This function can be used either side of the map, so rename it to
something generic.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
 include/datatype.h | 4 ++--
 src/datatype.c     | 6 +++---
 src/evaluate.c     | 2 +-
 src/netlink.c      | 2 +-
 src/rule.c         | 2 +-
 5 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/include/datatype.h b/include/datatype.h
index 3ce3a888f063..b78d76f78f76 100644
--- a/include/datatype.h
+++ b/include/datatype.h
@@ -254,8 +254,8 @@ concat_subtype_lookup(uint32_t type, unsigned int n)
 }
 
 extern const struct datatype *
-set_keytype_alloc(const struct datatype *orig_dtype, unsigned int byteorder);
-extern void set_keytype_destroy(const struct datatype *dtype);
+set_datatype_alloc(const struct datatype *orig_dtype, unsigned int byteorder);
+extern void set_datatype_destroy(const struct datatype *dtype);
 
 extern void time_print(uint64_t seconds);
 extern struct error_record *time_parse(const struct location *loc,
diff --git a/src/datatype.c b/src/datatype.c
index 64b8b8845b10..6b1dd4a09abb 100644
--- a/src/datatype.c
+++ b/src/datatype.c
@@ -1029,8 +1029,8 @@ void concat_type_destroy(const struct datatype *dtype)
 	dtype_free(dtype);
 }
 
-const struct datatype *set_keytype_alloc(const struct datatype *orig_dtype,
-					 unsigned int byteorder)
+const struct datatype *set_datatype_alloc(const struct datatype *orig_dtype,
+					  unsigned int byteorder)
 {
 	struct datatype *dtype;
 
@@ -1044,7 +1044,7 @@ const struct datatype *set_keytype_alloc(const struct datatype *orig_dtype,
 	return dtype;
 }
 
-void set_keytype_destroy(const struct datatype *dtype)
+void set_datatype_destroy(const struct datatype *dtype)
 {
 	if (dtype->flags & DTYPE_F_CLONE)
 		dtype_free(dtype);
diff --git a/src/evaluate.c b/src/evaluate.c
index 21f1a475d5e9..07a611804a90 100644
--- a/src/evaluate.c
+++ b/src/evaluate.c
@@ -73,7 +73,7 @@ static struct expr *implicit_set_declaration(struct eval_ctx *ctx,
 	set = set_alloc(&expr->location);
 	set->flags	= NFT_SET_ANONYMOUS | expr->set_flags;
 	set->handle.set = xstrdup(name),
-	set->keytype 	= set_keytype_alloc(keytype, keybyteorder);
+	set->keytype 	= set_datatype_alloc(keytype, keybyteorder);
 	set->keylen	= keylen;
 	set->init	= expr;
 
diff --git a/src/netlink.c b/src/netlink.c
index 1f3398225892..60d86d61c504 100644
--- a/src/netlink.c
+++ b/src/netlink.c
@@ -1189,7 +1189,7 @@ static struct set *netlink_delinearize_set(struct netlink_ctx *ctx,
 	set->handle.table  = xstrdup(nftnl_set_get_str(nls, NFTNL_SET_TABLE));
 	set->handle.set    = xstrdup(nftnl_set_get_str(nls, NFTNL_SET_NAME));
 
-	set->keytype = set_keytype_alloc(keytype, byteorder);
+	set->keytype = set_datatype_alloc(keytype, byteorder);
 	set->keylen  = nftnl_set_get_u32(nls, NFTNL_SET_KEY_LEN) * BITS_PER_BYTE;
 	set->flags   = nftnl_set_get_u32(nls, NFTNL_SET_FLAGS);
 
diff --git a/src/rule.c b/src/rule.c
index b47076f000ee..6045747710db 100644
--- a/src/rule.c
+++ b/src/rule.c
@@ -210,7 +210,7 @@ void set_free(struct set *set)
 	if (set->init != NULL)
 		expr_free(set->init);
 	handle_free(&set->handle);
-	set_keytype_destroy(set->keytype);
+	set_datatype_destroy(set->keytype);
 	xfree(set);
 }
 
-- 
2.1.4


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

* [PATCH nft 3/4] netlink: rework NFTNL_SET_USERDATA to accomodate new attributes
  2017-02-28  0:00 [PATCH nft 1/4] evaluate: set byteorder as lhs expression context in stmt_evaluate_arg() Pablo Neira Ayuso
  2017-02-28  0:01 ` [PATCH nft 2/4] src: rename set_keytype_alloc() to set_datatype_alloc() Pablo Neira Ayuso
@ 2017-02-28  0:01 ` Pablo Neira Ayuso
  2017-02-28  0:01 ` [PATCH nft 4/4] src: store byteorder for set data Pablo Neira Ayuso
  2 siblings, 0 replies; 4+ messages in thread
From: Pablo Neira Ayuso @ 2017-02-28  0:01 UTC (permalink / raw)
  To: netfilter-devel

Rework the NFTNL_SET_USERDATA in netlink_delinearize_set() to accomodate
rhs datatype byteorder in mappings.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
 src/netlink.c | 50 ++++++++++++++++++--------------------------------
 1 file changed, 18 insertions(+), 32 deletions(-)

diff --git a/src/netlink.c b/src/netlink.c
index 60d86d61c504..d643034f77ca 100644
--- a/src/netlink.c
+++ b/src/netlink.c
@@ -1122,40 +1122,27 @@ static int set_parse_udata_cb(const struct nftnl_udata *attr, void *data)
 	return 0;
 }
 
-static uint32_t set_udata_get_key_byteorder(const void *data, uint32_t data_len)
-{
-	const struct nftnl_udata *tb[UDATA_TYPE_MAX + 1] = {};
-
-	if (nftnl_udata_parse(data, data_len, set_parse_udata_cb, tb) < 0)
-		return BYTEORDER_INVALID;
-
-	if (!tb[UDATA_SET_KEYBYTEORDER])
-		return BYTEORDER_INVALID;
-
-	return *((uint32_t *)nftnl_udata_get(tb[UDATA_SET_KEYBYTEORDER]));
-}
-
-static enum byteorder set_key_byteorder(const struct nftnl_set *nls)
-{
-	enum byteorder byteorder = BYTEORDER_INVALID;
-	const void *data;
-	uint32_t len;
-
-	if (nftnl_set_is_set(nls, NFTNL_SET_USERDATA)) {
-		data = nftnl_set_get_data(nls, NFTNL_SET_USERDATA, &len);
-		byteorder = set_udata_get_key_byteorder(data, len);
-	}
-
-	return byteorder;
-}
-
 static struct set *netlink_delinearize_set(struct netlink_ctx *ctx,
 					   const struct nftnl_set *nls)
 {
-	struct set *set;
-	const struct datatype *keytype, *datatype;
+	const struct nftnl_udata *ud[UDATA_SET_MAX + 1] = {};
 	uint32_t flags, key, data, data_len, objtype = 0;
-	enum byteorder byteorder;
+	enum byteorder keybyteorder = BYTEORDER_INVALID;
+	const struct datatype *keytype, *datatype;
+	const char *udata;
+	struct set *set;
+	uint32_t ulen;
+
+	if (nftnl_set_is_set(nls, NFTNL_SET_USERDATA)) {
+		udata = nftnl_set_get_data(nls, NFTNL_SET_USERDATA, &ulen);
+		if (nftnl_udata_parse(udata, ulen, set_parse_udata_cb, ud) < 0) {
+			netlink_io_error(ctx, NULL, "Cannot parse userdata");
+			return NULL;
+		}
+
+		if (ud[UDATA_SET_KEYBYTEORDER])
+			keybyteorder = *((uint32_t *)nftnl_udata_get(ud[UDATA_SET_KEYBYTEORDER]));
+	}
 
 	key = nftnl_set_get_u32(nls, NFTNL_SET_KEY_TYPE);
 	keytype = dtype_map_from_kernel(key);
@@ -1164,7 +1151,6 @@ static struct set *netlink_delinearize_set(struct netlink_ctx *ctx,
 				 key);
 		return NULL;
 	}
-	byteorder = set_key_byteorder(nls);
 
 	flags = nftnl_set_get_u32(nls, NFTNL_SET_FLAGS);
 	if (flags & NFT_SET_MAP) {
@@ -1189,7 +1175,7 @@ static struct set *netlink_delinearize_set(struct netlink_ctx *ctx,
 	set->handle.table  = xstrdup(nftnl_set_get_str(nls, NFTNL_SET_TABLE));
 	set->handle.set    = xstrdup(nftnl_set_get_str(nls, NFTNL_SET_NAME));
 
-	set->keytype = set_datatype_alloc(keytype, byteorder);
+	set->keytype = set_datatype_alloc(keytype, keybyteorder);
 	set->keylen  = nftnl_set_get_u32(nls, NFTNL_SET_KEY_LEN) * BITS_PER_BYTE;
 	set->flags   = nftnl_set_get_u32(nls, NFTNL_SET_FLAGS);
 
-- 
2.1.4


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

* [PATCH nft 4/4] src: store byteorder for set data
  2017-02-28  0:00 [PATCH nft 1/4] evaluate: set byteorder as lhs expression context in stmt_evaluate_arg() Pablo Neira Ayuso
  2017-02-28  0:01 ` [PATCH nft 2/4] src: rename set_keytype_alloc() to set_datatype_alloc() Pablo Neira Ayuso
  2017-02-28  0:01 ` [PATCH nft 3/4] netlink: rework NFTNL_SET_USERDATA to accomodate new attributes Pablo Neira Ayuso
@ 2017-02-28  0:01 ` Pablo Neira Ayuso
  2 siblings, 0 replies; 4+ messages in thread
From: Pablo Neira Ayuso @ 2017-02-28  0:01 UTC (permalink / raw)
  To: netfilter-devel

Add new UDATA_SET_DATABYTEORDER attribute for NFTA_SET_UDATA to store
the datatype byteorder. This is required if integer_type is used on the
rhs of the mapping given that this datatype comes with no specific
byteorder.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
 include/rule.h |  1 +
 src/evaluate.c |  4 +++-
 src/netlink.c  | 16 +++++++++++++++-
 src/rule.c     |  2 ++
 4 files changed, 21 insertions(+), 2 deletions(-)

diff --git a/include/rule.h b/include/rule.h
index f5160daf4d8e..ed12774d0ba7 100644
--- a/include/rule.h
+++ b/include/rule.h
@@ -479,6 +479,7 @@ enum udata_type {
 
 enum udata_set_type {
 	UDATA_SET_KEYBYTEORDER,
+	UDATA_SET_DATABYTEORDER,
 	__UDATA_SET_MAX,
 };
 #define UDATA_SET_MAX (__UDATA_SET_MAX - 1)
diff --git a/src/evaluate.c b/src/evaluate.c
index 07a611804a90..5498516686ad 100644
--- a/src/evaluate.c
+++ b/src/evaluate.c
@@ -1174,7 +1174,9 @@ static int expr_evaluate_map(struct eval_ctx *ctx, struct expr **expr)
 						    ctx->ectx.len,
 						    ctx->ectx.byteorder,
 						    mappings);
-		mappings->set->datatype = ectx.dtype;
+
+		mappings->set->datatype = set_datatype_alloc(ectx.dtype,
+							     ectx.byteorder);
 		mappings->set->datalen  = ectx.len;
 
 		map->mappings = mappings;
diff --git a/src/netlink.c b/src/netlink.c
index d643034f77ca..8b0fc9403361 100644
--- a/src/netlink.c
+++ b/src/netlink.c
@@ -1112,6 +1112,7 @@ static int set_parse_udata_cb(const struct nftnl_udata *attr, void *data)
 
 	switch (type) {
 	case UDATA_SET_KEYBYTEORDER:
+	case UDATA_SET_DATABYTEORDER:
 		if (len != sizeof(uint32_t))
 			return -1;
 		break;
@@ -1128,6 +1129,7 @@ static struct set *netlink_delinearize_set(struct netlink_ctx *ctx,
 	const struct nftnl_udata *ud[UDATA_SET_MAX + 1] = {};
 	uint32_t flags, key, data, data_len, objtype = 0;
 	enum byteorder keybyteorder = BYTEORDER_INVALID;
+	enum byteorder databyteorder = BYTEORDER_INVALID;
 	const struct datatype *keytype, *datatype;
 	const char *udata;
 	struct set *set;
@@ -1142,6 +1144,8 @@ static struct set *netlink_delinearize_set(struct netlink_ctx *ctx,
 
 		if (ud[UDATA_SET_KEYBYTEORDER])
 			keybyteorder = *((uint32_t *)nftnl_udata_get(ud[UDATA_SET_KEYBYTEORDER]));
+		if (ud[UDATA_SET_DATABYTEORDER])
+			databyteorder = *((uint32_t *)nftnl_udata_get(ud[UDATA_SET_DATABYTEORDER]));
 	}
 
 	key = nftnl_set_get_u32(nls, NFTNL_SET_KEY_TYPE);
@@ -1181,7 +1185,11 @@ static struct set *netlink_delinearize_set(struct netlink_ctx *ctx,
 
 	set->objtype = objtype;
 
-	set->datatype = datatype;
+	if (datatype)
+		set->datatype = set_datatype_alloc(datatype, databyteorder);
+	else
+		set->datatype = NULL;
+
 	if (nftnl_set_is_set(nls, NFTNL_SET_DATA_LEN)) {
 		data_len = nftnl_set_get_u32(nls, NFTNL_SET_DATA_LEN);
 		set->datalen = data_len * BITS_PER_BYTE;
@@ -1279,6 +1287,12 @@ static int netlink_add_set_batch(struct netlink_ctx *ctx,
 	if (!nftnl_udata_put(udbuf, UDATA_SET_KEYBYTEORDER, sizeof(uint32_t),
 			     &set->keytype->byteorder))
 		memory_allocation_error();
+
+	if (set->flags & NFT_SET_MAP &&
+	    !nftnl_udata_put(udbuf, UDATA_SET_DATABYTEORDER, sizeof(uint32_t),
+			     &set->datatype->byteorder))
+		memory_allocation_error();
+
 	nftnl_set_set_data(nls, NFTNL_SET_USERDATA, nftnl_udata_buf_data(udbuf),
 			   nftnl_udata_buf_len(udbuf));
 	nftnl_udata_buf_free(udbuf);
diff --git a/src/rule.c b/src/rule.c
index 6045747710db..f5ff1103c9f1 100644
--- a/src/rule.c
+++ b/src/rule.c
@@ -211,6 +211,8 @@ void set_free(struct set *set)
 		expr_free(set->init);
 	handle_free(&set->handle);
 	set_datatype_destroy(set->keytype);
+	if (set->datatype)
+		set_datatype_destroy(set->datatype);
 	xfree(set);
 }
 
-- 
2.1.4


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

end of thread, other threads:[~2017-02-28  0:02 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-02-28  0:00 [PATCH nft 1/4] evaluate: set byteorder as lhs expression context in stmt_evaluate_arg() Pablo Neira Ayuso
2017-02-28  0:01 ` [PATCH nft 2/4] src: rename set_keytype_alloc() to set_datatype_alloc() Pablo Neira Ayuso
2017-02-28  0:01 ` [PATCH nft 3/4] netlink: rework NFTNL_SET_USERDATA to accomodate new attributes Pablo Neira Ayuso
2017-02-28  0:01 ` [PATCH nft 4/4] src: store byteorder for set data 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).