netfilter-devel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH nft 1/5] src: add set_is_datamap(), set_is_objmap() and set_is_map() helpers
@ 2019-07-16 10:26 Pablo Neira Ayuso
  2019-07-16 10:26 ` [PATCH nft 2/5] evaluate: missing object maps handling in list and flush commands Pablo Neira Ayuso
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: Pablo Neira Ayuso @ 2019-07-16 10:26 UTC (permalink / raw)
  To: netfilter-devel

Two map types are currently possible:

* data maps, ie. set_is_datamap().
* object maps, ie. set_is_objmap().

This patch adds helper function to check for the map type.

set_is_map() allows you to check for either map type.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
 include/rule.h | 16 ++++++++++++++++
 src/evaluate.c | 12 ++++++------
 src/json.c     |  4 ++--
 src/mnl.c      |  6 +++---
 src/netlink.c  | 12 ++++++------
 src/rule.c     |  6 +++---
 6 files changed, 36 insertions(+), 20 deletions(-)

diff --git a/include/rule.h b/include/rule.h
index aefb24d95163..bee1d4474216 100644
--- a/include/rule.h
+++ b/include/rule.h
@@ -6,6 +6,7 @@
 #include <list.h>
 #include <netinet/in.h>
 #include <libnftnl/object.h>	/* For NFTNL_CTTIMEOUT_ARRAY_MAX. */
+#include <linux/netfilter/nf_tables.h>
 
 /**
  * struct handle_spec - handle ID
@@ -321,6 +322,21 @@ extern const char *set_policy2str(uint32_t policy);
 extern void set_print(const struct set *set, struct output_ctx *octx);
 extern void set_print_plain(const struct set *s, struct output_ctx *octx);
 
+static inline bool set_is_datamap(uint32_t set_flags)
+{
+	return set_flags & NFT_SET_MAP;
+}
+
+static inline bool set_is_objmap(uint32_t set_flags)
+{
+	return set_flags & NFT_SET_OBJECT;
+}
+
+static inline bool set_is_map(uint32_t set_flags)
+{
+	return set_is_datamap(set_flags) || set_is_objmap(set_flags);
+}
+
 #include <statement.h>
 
 struct counter {
diff --git a/src/evaluate.c b/src/evaluate.c
index 8086f750417a..e1a827e723ae 100644
--- a/src/evaluate.c
+++ b/src/evaluate.c
@@ -83,7 +83,7 @@ static struct expr *implicit_set_declaration(struct eval_ctx *ctx,
 	struct set *set;
 	struct handle h;
 
-	if (expr->set_flags & NFT_SET_MAP)
+	if (set_is_datamap(expr->set_flags))
 		key_fix_dtype_byteorder(key);
 
 	set = set_alloc(&expr->location);
@@ -1381,7 +1381,7 @@ static int expr_evaluate_map(struct eval_ctx *ctx, struct expr **expr)
 		if (expr_evaluate(ctx, &map->mappings) < 0)
 			return -1;
 		if (map->mappings->etype != EXPR_SET_REF ||
-		    !(map->mappings->set->flags & NFT_SET_MAP))
+		    !set_is_datamap(map->mappings->set->flags))
 			return expr_error(ctx->msgs, map->mappings,
 					  "Expression is not a map");
 		break;
@@ -1416,7 +1416,7 @@ static int expr_evaluate_mapping(struct eval_ctx *ctx, struct expr **expr)
 	if (set == NULL)
 		return expr_error(ctx->msgs, mapping,
 				  "mapping outside of map context");
-	if (!(set->flags & (NFT_SET_MAP | NFT_SET_OBJECT)))
+	if (!set_is_map(set->flags))
 		return set_error(ctx, set, "set is not a map");
 
 	expr_set_context(&ctx->ectx, set->key->dtype, set->key->len);
@@ -2991,7 +2991,7 @@ static int stmt_evaluate_objref_map(struct eval_ctx *ctx, struct stmt *stmt)
 		if (map->mappings->etype != EXPR_SET_REF)
 			return expr_error(ctx->msgs, map->mappings,
 					  "Expression is not a map");
-		if (!(map->mappings->set->flags & NFT_SET_OBJECT))
+		if (!set_is_objmap(map->mappings->set->flags))
 			return expr_error(ctx->msgs, map->mappings,
 					  "Expression is not a map with objects");
 		break;
@@ -3149,7 +3149,7 @@ static int set_evaluate(struct eval_ctx *ctx, struct set *set)
 	    set->key->etype == EXPR_CONCAT)
 		return set_error(ctx, set, "concatenated types not supported in interval sets");
 
-	if (set->flags & NFT_SET_MAP) {
+	if (set_is_datamap(set->flags)) {
 		if (set->datatype == NULL)
 			return set_error(ctx, set, "map definition does not "
 					 "specify mapping data type");
@@ -3158,7 +3158,7 @@ static int set_evaluate(struct eval_ctx *ctx, struct set *set)
 		if (set->datalen == 0 && set->datatype->type != TYPE_VERDICT)
 			return set_error(ctx, set, "unqualified mapping data "
 					 "type specified in map definition");
-	} else if (set->flags & NFT_SET_OBJECT) {
+	} else if (set_is_objmap(set->flags)) {
 		set->datatype = &string_type;
 		set->datalen  = NFT_OBJ_MAXNAMELEN * BITS_PER_BYTE;
 	}
diff --git a/src/json.c b/src/json.c
index 1006d7bb7f22..f40dc51883b7 100644
--- a/src/json.c
+++ b/src/json.c
@@ -79,10 +79,10 @@ static json_t *set_print_json(struct output_ctx *octx, const struct set *set)
 	json_t *root, *tmp;
 	const char *type, *datatype_ext = NULL;
 
-	if (set->flags & NFT_SET_MAP) {
+	if (set_is_datamap(set->flags)) {
 		type = "map";
 		datatype_ext = set->datatype->name;
-	} else if (set->flags & NFT_SET_OBJECT) {
+	} else if (set_is_objmap(set->flags)) {
 		type = "map";
 		datatype_ext = obj_type_name(set->objtype);
 	} else if (set->flags & NFT_SET_EVAL) {
diff --git a/src/mnl.c b/src/mnl.c
index c145cc5c9228..a954e9d8f5cd 100644
--- a/src/mnl.c
+++ b/src/mnl.c
@@ -799,13 +799,13 @@ int mnl_nft_set_add(struct netlink_ctx *ctx, const struct cmd *cmd,
 			  dtype_map_to_kernel(set->key->dtype));
 	nftnl_set_set_u32(nls, NFTNL_SET_KEY_LEN,
 			  div_round_up(set->key->len, BITS_PER_BYTE));
-	if (set->flags & NFT_SET_MAP) {
+	if (set_is_datamap(set->flags)) {
 		nftnl_set_set_u32(nls, NFTNL_SET_DATA_TYPE,
 				  dtype_map_to_kernel(set->datatype));
 		nftnl_set_set_u32(nls, NFTNL_SET_DATA_LEN,
 				  set->datalen / BITS_PER_BYTE);
 	}
-	if (set->flags & NFT_SET_OBJECT)
+	if (set_is_objmap(set->flags))
 		nftnl_set_set_u32(nls, NFTNL_SET_OBJ_TYPE, set->objtype);
 
 	if (set->timeout)
@@ -833,7 +833,7 @@ int mnl_nft_set_add(struct netlink_ctx *ctx, const struct cmd *cmd,
 				 set->key->byteorder))
 		memory_allocation_error();
 
-	if (set->flags & NFT_SET_MAP &&
+	if (set_is_datamap(set->flags) &&
 	    !nftnl_udata_put_u32(udbuf, NFTNL_UDATA_SET_DATABYTEORDER,
 				 set->datatype->byteorder))
 		memory_allocation_error();
diff --git a/src/netlink.c b/src/netlink.c
index 97eb082c6547..0374c39aca91 100644
--- a/src/netlink.c
+++ b/src/netlink.c
@@ -146,7 +146,7 @@ static struct nftnl_set_elem *alloc_nftnl_setelem(const struct expr *set,
 				   nftnl_udata_buf_len(udbuf));
 		nftnl_udata_buf_free(udbuf);
 	}
-	if (set->set_flags & NFT_SET_MAP && data != NULL) {
+	if (set_is_datamap(set->set_flags) && data != NULL) {
 		netlink_gen_data(data, &nld);
 		switch (data->etype) {
 		case EXPR_VERDICT:
@@ -165,7 +165,7 @@ static struct nftnl_set_elem *alloc_nftnl_setelem(const struct expr *set,
 			break;
 		}
 	}
-	if (set->set_flags & NFT_SET_OBJECT && data != NULL) {
+	if (set_is_objmap(set->set_flags) && data != NULL) {
 		netlink_gen_data(data, &nld);
 		nftnl_set_elem_set(nlse, NFTNL_SET_ELEM_OBJREF,
 				   nld.value, nld.len);
@@ -581,7 +581,7 @@ struct set *netlink_delinearize_set(struct netlink_ctx *ctx,
 	}
 
 	flags = nftnl_set_get_u32(nls, NFTNL_SET_FLAGS);
-	if (flags & NFT_SET_MAP) {
+	if (set_is_datamap(flags)) {
 		data = nftnl_set_get_u32(nls, NFTNL_SET_DATA_TYPE);
 		datatype = dtype_map_from_kernel(data);
 		if (datatype == NULL) {
@@ -593,7 +593,7 @@ struct set *netlink_delinearize_set(struct netlink_ctx *ctx,
 	} else
 		datatype = NULL;
 
-	if (flags & NFT_SET_OBJECT) {
+	if (set_is_objmap(flags)) {
 		objtype = nftnl_set_get_u32(nls, NFTNL_SET_OBJ_TYPE);
 		datatype = &string_type;
 	}
@@ -795,7 +795,7 @@ int netlink_delinearize_setelem(struct nftnl_set_elem *nlse,
 	if (flags & NFT_SET_ELEM_INTERVAL_END)
 		expr->flags |= EXPR_F_INTERVAL_END;
 
-	if (set->flags & NFT_SET_MAP) {
+	if (set_is_datamap(set->flags)) {
 		if (nftnl_set_elem_is_set(nlse, NFTNL_SET_ELEM_DATA)) {
 			nld.value = nftnl_set_elem_get(nlse, NFTNL_SET_ELEM_DATA,
 						       &nld.len);
@@ -817,7 +817,7 @@ int netlink_delinearize_setelem(struct nftnl_set_elem *nlse,
 
 		expr = mapping_expr_alloc(&netlink_location, expr, data);
 	}
-	if (set->flags & NFT_SET_OBJECT) {
+	if (set_is_objmap(set->flags)) {
 		if (nftnl_set_elem_is_set(nlse, NFTNL_SET_ELEM_OBJREF)) {
 			nld.value = nftnl_set_elem_get(nlse,
 						       NFTNL_SET_ELEM_OBJREF,
diff --git a/src/rule.c b/src/rule.c
index 0a91917f7568..e04fc09b0a5b 100644
--- a/src/rule.c
+++ b/src/rule.c
@@ -449,7 +449,7 @@ static void set_print_declaration(const struct set *set,
 	if ((set->flags & (NFT_SET_EVAL | NFT_SET_ANONYMOUS)) ==
 				(NFT_SET_EVAL | NFT_SET_ANONYMOUS))
 		type = "meter";
-	else if (set->flags & (NFT_SET_MAP | NFT_SET_OBJECT))
+	else if (set_is_map(set->flags))
 		type = "map";
 	else
 		type = "set";
@@ -469,9 +469,9 @@ static void set_print_declaration(const struct set *set,
 	nft_print(octx, "%s", opts->nl);
 	nft_print(octx, "%s%stype %s",
 		  opts->tab, opts->tab, set->key->dtype->name);
-	if (set->flags & NFT_SET_MAP)
+	if (set_is_datamap(set->flags))
 		nft_print(octx, " : %s", set->datatype->name);
-	else if (set->flags & NFT_SET_OBJECT)
+	else if (set_is_objmap(set->flags))
 		nft_print(octx, " : %s", obj_type_name(set->objtype));
 
 	nft_print(octx, "%s", opts->stmt_separator);
-- 
2.11.0


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

* [PATCH nft 2/5] evaluate: missing object maps handling in list and flush commands
  2019-07-16 10:26 [PATCH nft 1/5] src: add set_is_datamap(), set_is_objmap() and set_is_map() helpers Pablo Neira Ayuso
@ 2019-07-16 10:26 ` Pablo Neira Ayuso
  2019-07-16 10:26 ` [PATCH nft 3/5] src: use set_is_anonymous() Pablo Neira Ayuso
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: Pablo Neira Ayuso @ 2019-07-16 10:26 UTC (permalink / raw)
  To: netfilter-devel

NFT_SET_OBJECT tells there is an object map.

 # nft list ruleset
 table inet filter {
        map countermap {
                type ipv4_addr : counter
        }
 }

The following command fails:

 # nft flush set inet filter countermap

This patch checks for NFT_SET_OBJECT from new set_is_literal() and
map_is_literal() functions. This patch also adds tests for this.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
 include/rule.h                              | 15 +++++++++++++++
 src/evaluate.c                              | 13 +++++--------
 tests/shell/testcases/listing/0017objects_0 | 19 +++++++++++++++++++
 tests/shell/testcases/listing/0018data_0    | 19 +++++++++++++++++++
 tests/shell/testcases/listing/0019set_0     | 19 +++++++++++++++++++
 5 files changed, 77 insertions(+), 8 deletions(-)
 create mode 100755 tests/shell/testcases/listing/0017objects_0
 create mode 100755 tests/shell/testcases/listing/0018data_0
 create mode 100755 tests/shell/testcases/listing/0019set_0

diff --git a/include/rule.h b/include/rule.h
index bee1d4474216..42d29b7c910e 100644
--- a/include/rule.h
+++ b/include/rule.h
@@ -337,6 +337,21 @@ static inline bool set_is_map(uint32_t set_flags)
 	return set_is_datamap(set_flags) || set_is_objmap(set_flags);
 }
 
+static inline bool set_is_anonymous(uint32_t set_flags)
+{
+	return set_flags & NFT_SET_ANONYMOUS;
+}
+
+static inline bool set_is_literal(uint32_t set_flags)
+{
+	return !(set_is_anonymous(set_flags) || set_is_map(set_flags));
+}
+
+static inline bool map_is_literal(uint32_t set_flags)
+{
+	return !(set_is_anonymous(set_flags) || !set_is_map(set_flags));
+}
+
 #include <statement.h>
 
 struct counter {
diff --git a/src/evaluate.c b/src/evaluate.c
index e1a827e723ae..f915187165cc 100644
--- a/src/evaluate.c
+++ b/src/evaluate.c
@@ -3630,8 +3630,8 @@ static int cmd_evaluate_list(struct eval_ctx *ctx, struct cmd *cmd)
 		if (set == NULL)
 			return set_not_found(ctx, &ctx->cmd->handle.set.location,
 					     ctx->cmd->handle.set.name);
-		else if (set->flags & (NFT_SET_MAP | NFT_SET_ANONYMOUS))
-			return cmd_error(ctx,  &ctx->cmd->handle.set.location,
+		else if (!set_is_literal(set->flags))
+			return cmd_error(ctx, &ctx->cmd->handle.set.location,
 					 "%s", strerror(ENOENT));
 
 		return 0;
@@ -3659,8 +3659,7 @@ static int cmd_evaluate_list(struct eval_ctx *ctx, struct cmd *cmd)
 		if (set == NULL)
 			return set_not_found(ctx, &ctx->cmd->handle.set.location,
 					     ctx->cmd->handle.set.name);
-		else if (!(set->flags & NFT_SET_MAP) ||
-			 set->flags & NFT_SET_ANONYMOUS)
+		else if (!map_is_literal(set->flags))
 			return cmd_error(ctx, &ctx->cmd->handle.set.location,
 					 "%s", strerror(ENOENT));
 
@@ -3752,10 +3751,9 @@ static int cmd_evaluate_flush(struct eval_ctx *ctx, struct cmd *cmd)
 		if (set == NULL)
 			return set_not_found(ctx, &ctx->cmd->handle.set.location,
 					     ctx->cmd->handle.set.name);
-		else if (set->flags & (NFT_SET_MAP | NFT_SET_ANONYMOUS))
+		else if (!set_is_literal(set->flags))
 			return cmd_error(ctx, &ctx->cmd->handle.set.location,
 					 "%s", strerror(ENOENT));
-
 		return 0;
 	case CMD_OBJ_MAP:
 		table = table_lookup(&cmd->handle, &ctx->nft->cache);
@@ -3766,8 +3764,7 @@ static int cmd_evaluate_flush(struct eval_ctx *ctx, struct cmd *cmd)
 		if (set == NULL)
 			return set_not_found(ctx, &ctx->cmd->handle.set.location,
 					     ctx->cmd->handle.set.name);
-		else if (!(set->flags & NFT_SET_MAP) ||
-			 set->flags & NFT_SET_ANONYMOUS)
+		else if (!map_is_literal(set->flags))
 			return cmd_error(ctx, &ctx->cmd->handle.set.location,
 					 "%s", strerror(ENOENT));
 
diff --git a/tests/shell/testcases/listing/0017objects_0 b/tests/shell/testcases/listing/0017objects_0
new file mode 100755
index 000000000000..14d614382e1b
--- /dev/null
+++ b/tests/shell/testcases/listing/0017objects_0
@@ -0,0 +1,19 @@
+#!/bin/bash
+
+EXPECTED="table inet filter {
+	map countermap {
+		type ipv4_addr : counter
+	}
+}"
+
+set -e
+
+$NFT -f - <<< $EXPECTED
+$NFT flush map inet filter countermap
+
+GET="$($NFT list map inet filter countermap)"
+if [ "$EXPECTED" != "$GET" ] ; then
+	DIFF="$(which diff)"
+	[ -x $DIFF ] && $DIFF -u <(echo "$EXPECTED") <(echo "$GET")
+	exit 1
+fi
diff --git a/tests/shell/testcases/listing/0018data_0 b/tests/shell/testcases/listing/0018data_0
new file mode 100755
index 000000000000..767fe13ae65a
--- /dev/null
+++ b/tests/shell/testcases/listing/0018data_0
@@ -0,0 +1,19 @@
+#!/bin/bash
+
+EXPECTED="table inet filter {
+	map ipmap {
+		type ipv4_addr : ipv4_addr
+	}
+}"
+
+set -e
+
+$NFT -f - <<< $EXPECTED
+$NFT flush map inet filter ipmap
+
+GET="$($NFT list map inet filter ipmap)"
+if [ "$EXPECTED" != "$GET" ] ; then
+	DIFF="$(which diff)"
+	[ -x $DIFF ] && $DIFF -u <(echo "$EXPECTED") <(echo "$GET")
+	exit 1
+fi
diff --git a/tests/shell/testcases/listing/0019set_0 b/tests/shell/testcases/listing/0019set_0
new file mode 100755
index 000000000000..04eb0faf74af
--- /dev/null
+++ b/tests/shell/testcases/listing/0019set_0
@@ -0,0 +1,19 @@
+#!/bin/bash
+
+EXPECTED="table inet filter {
+	set ipset {
+		type ipv4_addr
+	}
+}"
+
+set -e
+
+$NFT -f - <<< $EXPECTED
+$NFT flush set inet filter ipset
+
+GET="$($NFT list set inet filter ipset)"
+if [ "$EXPECTED" != "$GET" ] ; then
+	DIFF="$(which diff)"
+	[ -x $DIFF ] && $DIFF -u <(echo "$EXPECTED") <(echo "$GET")
+	exit 1
+fi
-- 
2.11.0


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

* [PATCH nft 3/5] src: use set_is_anonymous()
  2019-07-16 10:26 [PATCH nft 1/5] src: add set_is_datamap(), set_is_objmap() and set_is_map() helpers Pablo Neira Ayuso
  2019-07-16 10:26 ` [PATCH nft 2/5] evaluate: missing object maps handling in list and flush commands Pablo Neira Ayuso
@ 2019-07-16 10:26 ` Pablo Neira Ayuso
  2019-07-16 10:26 ` [PATCH nft 4/5] evaluate: honor NFT_SET_OBJECT flag Pablo Neira Ayuso
  2019-07-16 10:26 ` [PATCH nft 5/5] cache: incorrect cache flags for create commands Pablo Neira Ayuso
  3 siblings, 0 replies; 5+ messages in thread
From: Pablo Neira Ayuso @ 2019-07-16 10:26 UTC (permalink / raw)
  To: netfilter-devel

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
 src/evaluate.c    | 2 +-
 src/expression.c  | 4 ++--
 src/json.c        | 4 ++--
 src/monitor.c     | 4 ++--
 src/parser_json.c | 2 +-
 src/rule.c        | 4 ++--
 src/segtree.c     | 2 +-
 7 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/src/evaluate.c b/src/evaluate.c
index f915187165cc..e35291d28b6a 100644
--- a/src/evaluate.c
+++ b/src/evaluate.c
@@ -1642,7 +1642,7 @@ static int __binop_transfer(struct eval_ctx *ctx,
 		}
 		break;
 	case EXPR_SET_REF:
-		if (!((*right)->set->flags & NFT_SET_ANONYMOUS))
+		if (!set_is_anonymous((*right)->set->flags))
 			return 0;
 
 		return __binop_transfer(ctx, left, &(*right)->set->init);
diff --git a/src/expression.c b/src/expression.c
index 5d0b4f82cae4..cb49e0b73f5a 100644
--- a/src/expression.c
+++ b/src/expression.c
@@ -851,7 +851,7 @@ static const char *calculate_delim(const struct expr *expr, int *count)
 	const char *newline = ",\n\t\t\t     ";
 	const char *singleline = ", ";
 
-	if (expr->set_flags & NFT_SET_ANONYMOUS)
+	if (set_is_anonymous(expr->set_flags))
 		return singleline;
 
 	if (!expr->dtype)
@@ -1035,7 +1035,7 @@ struct expr *map_expr_alloc(const struct location *loc, struct expr *arg,
 
 static void set_ref_expr_print(const struct expr *expr, struct output_ctx *octx)
 {
-	if (expr->set->flags & NFT_SET_ANONYMOUS) {
+	if (set_is_anonymous(expr->set->flags)) {
 		if (expr->set->flags & NFT_SET_EVAL)
 			nft_print(octx, "%s", expr->set->handle.set.name);
 		else
diff --git a/src/json.c b/src/json.c
index f40dc51883b7..b21677efea91 100644
--- a/src/json.c
+++ b/src/json.c
@@ -522,7 +522,7 @@ json_t *set_expr_json(const struct expr *expr, struct output_ctx *octx)
 
 json_t *set_ref_expr_json(const struct expr *expr, struct output_ctx *octx)
 {
-	if (expr->set->flags & NFT_SET_ANONYMOUS) {
+	if (set_is_anonymous(expr->set->flags)) {
 		return expr_print_json(expr->set->init, octx);
 	} else {
 		return json_pack("s+", "@", expr->set->handle.set.name);
@@ -1473,7 +1473,7 @@ static json_t *table_print_json_full(struct netlink_ctx *ctx,
 		json_array_append_new(root, tmp);
 	}
 	list_for_each_entry(set, &table->sets, list) {
-		if (set->flags & NFT_SET_ANONYMOUS)
+		if (set_is_anonymous(set->flags))
 			continue;
 		tmp = set_print_json(&ctx->nft->output, set);
 		json_array_append_new(root, tmp);
diff --git a/src/monitor.c b/src/monitor.c
index 5b25c9d4854e..40c381149cda 100644
--- a/src/monitor.c
+++ b/src/monitor.c
@@ -275,7 +275,7 @@ static int netlink_events_set_cb(const struct nlmsghdr *nlh, int type,
 
 	nls = netlink_set_alloc(nlh);
 	flags = nftnl_set_get_u32(nls, NFTNL_SET_FLAGS);
-	if (flags & NFT_SET_ANONYMOUS)
+	if (set_is_anonymous(flags))
 		goto out;
 
 	set = netlink_delinearize_set(monh->ctx, nls);
@@ -392,7 +392,7 @@ static int netlink_events_setelem_cb(const struct nlmsghdr *nlh, int type,
 		goto out;
 	}
 
-	if (set->flags & NFT_SET_ANONYMOUS)
+	if (set_is_anonymous(set->flags))
 		goto out;
 
 	/* we want to 'delinearize' the set_elem, but don't
diff --git a/src/parser_json.c b/src/parser_json.c
index f701ebdf1858..9add6f88d09e 100644
--- a/src/parser_json.c
+++ b/src/parser_json.c
@@ -3598,7 +3598,7 @@ static uint64_t handle_from_nlmsg(const struct nlmsghdr *nlh)
 	case NFT_MSG_NEWSET:
 		nls = netlink_set_alloc(nlh);
 		flags = nftnl_set_get_u32(nls, NFTNL_SET_FLAGS);
-		if (!(flags & NFT_SET_ANONYMOUS))
+		if (!set_is_anonymous(flags))
 			handle = nftnl_set_get_u64(nls, NFTNL_SET_HANDLE);
 		nftnl_set_free(nls);
 		break;
diff --git a/src/rule.c b/src/rule.c
index e04fc09b0a5b..52d8181f0d92 100644
--- a/src/rule.c
+++ b/src/rule.c
@@ -388,7 +388,7 @@ struct set *set_lookup_fuzzy(const char *set_name,
 
 	list_for_each_entry(table, &cache->list, list) {
 		list_for_each_entry(set, &table->sets, list) {
-			if (set->flags & NFT_SET_ANONYMOUS)
+			if (set_is_anonymous(set->flags))
 				continue;
 			if (!strcmp(set->handle.set.name, set_name)) {
 				*t = table;
@@ -1272,7 +1272,7 @@ static void table_print(const struct table *table, struct output_ctx *octx)
 		delim = "\n";
 	}
 	list_for_each_entry(set, &table->sets, list) {
-		if (set->flags & NFT_SET_ANONYMOUS)
+		if (set_is_anonymous(set->flags))
 			continue;
 		nft_print(octx, "%s", delim);
 		set_print(set, octx);
diff --git a/src/segtree.c b/src/segtree.c
index a21270a08c46..eff0653a8dfb 100644
--- a/src/segtree.c
+++ b/src/segtree.c
@@ -440,7 +440,7 @@ static bool segtree_needs_first_segment(const struct set *set,
 		 * 3) New empty set and, separately, new elements are added.
 		 * 4) This set is created with a number of initial elements.
 		 */
-		if ((set->flags & NFT_SET_ANONYMOUS) ||
+		if ((set_is_anonymous(set->flags)) ||
 		    (set->init && set->init->size == 0) ||
 		    (set->init == NULL && init) ||
 		    (set->init == init)) {
-- 
2.11.0


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

* [PATCH nft 4/5] evaluate: honor NFT_SET_OBJECT flag
  2019-07-16 10:26 [PATCH nft 1/5] src: add set_is_datamap(), set_is_objmap() and set_is_map() helpers Pablo Neira Ayuso
  2019-07-16 10:26 ` [PATCH nft 2/5] evaluate: missing object maps handling in list and flush commands Pablo Neira Ayuso
  2019-07-16 10:26 ` [PATCH nft 3/5] src: use set_is_anonymous() Pablo Neira Ayuso
@ 2019-07-16 10:26 ` Pablo Neira Ayuso
  2019-07-16 10:26 ` [PATCH nft 5/5] cache: incorrect cache flags for create commands Pablo Neira Ayuso
  3 siblings, 0 replies; 5+ messages in thread
From: Pablo Neira Ayuso @ 2019-07-16 10:26 UTC (permalink / raw)
  To: netfilter-devel

This is noticeable when displaying mispelling errors, however, there are
also few spots not checking for the object map flag.

Before:

 # nft flush set inet filter countermxx
 Error: No such file or directory; did you mean set ‘countermap’ in table inet ‘filter’?
 flush set inet filter countermxx
                       ^^^^^^^^^^
After:

 # nft flush set inet filter countermxx
 Error: No such file or directory; did you mean map ‘countermap’ in table inet ‘filter’?
 flush set inet filter countermxx
                       ^^^^^^^^^^

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
 src/evaluate.c | 6 +++---
 src/json.c     | 5 ++---
 src/rule.c     | 5 ++---
 3 files changed, 7 insertions(+), 9 deletions(-)

diff --git a/src/evaluate.c b/src/evaluate.c
index e35291d28b6a..f95f42e1067a 100644
--- a/src/evaluate.c
+++ b/src/evaluate.c
@@ -211,7 +211,7 @@ static int set_not_found(struct eval_ctx *ctx, const struct location *loc,
 	return cmd_error(ctx, loc,
 			 "%s; did you mean %s ‘%s’ in table %s ‘%s’?",
 			 strerror(ENOENT),
-			 set->flags & NFT_SET_MAP ? "map" : "set",
+			 set_is_map(set->flags) ? "map" : "set",
 			 set->handle.set.name,
 			 family2str(set->handle.family),
 			 table->handle.table.name);
@@ -3129,7 +3129,7 @@ static int set_evaluate(struct eval_ctx *ctx, struct set *set)
 	if (!(set->flags & NFT_SET_INTERVAL) && set->automerge)
 		return set_error(ctx, set, "auto-merge only works with interval sets");
 
-	type = set->flags & NFT_SET_MAP ? "map" : "set";
+	type = set_is_map(set->flags) ? "map" : "set";
 
 	if (set->key == NULL)
 		return set_error(ctx, set, "%s definition does not specify key",
@@ -3560,7 +3560,7 @@ static int cmd_evaluate_get(struct eval_ctx *ctx, struct cmd *cmd)
 			return table_not_found(ctx);
 
 		set = set_lookup(table, cmd->handle.set.name);
-		if (set == NULL || set->flags & NFT_SET_MAP)
+		if (set == NULL || set_is_map(set->flags))
 			return set_not_found(ctx, &ctx->cmd->handle.set.location,
 					     ctx->cmd->handle.set.name);
 
diff --git a/src/json.c b/src/json.c
index b21677efea91..215de65a114a 100644
--- a/src/json.c
+++ b/src/json.c
@@ -1605,14 +1605,13 @@ static json_t *do_list_sets_json(struct netlink_ctx *ctx, struct cmd *cmd)
 
 		list_for_each_entry(set, &table->sets, list) {
 			if (cmd->obj == CMD_OBJ_SETS &&
-			    (set->flags & NFT_SET_ANONYMOUS ||
-			    set->flags & NFT_SET_MAP))
+			    !set_is_literal(set->flags))
 				continue;
 			if (cmd->obj == CMD_OBJ_METERS &&
 			    !(set->flags & NFT_SET_EVAL))
 				continue;
 			if (cmd->obj == CMD_OBJ_MAPS &&
-			    !(set->flags & NFT_SET_MAP))
+			    !map_is_literal(set->flags))
 				continue;
 			json_array_append_new(root, set_print_json(octx, set));
 		}
diff --git a/src/rule.c b/src/rule.c
index 52d8181f0d92..4e07871a1f65 100644
--- a/src/rule.c
+++ b/src/rule.c
@@ -1652,14 +1652,13 @@ static int do_list_sets(struct netlink_ctx *ctx, struct cmd *cmd)
 
 		list_for_each_entry(set, &table->sets, list) {
 			if (cmd->obj == CMD_OBJ_SETS &&
-			    (set->flags & NFT_SET_ANONYMOUS ||
-			    set->flags & NFT_SET_MAP))
+			    !set_is_literal(set->flags))
 				continue;
 			if (cmd->obj == CMD_OBJ_METERS &&
 			    !(set->flags & NFT_SET_EVAL))
 				continue;
 			if (cmd->obj == CMD_OBJ_MAPS &&
-			    !(set->flags & NFT_SET_MAP))
+			    !map_is_literal(set->flags))
 				continue;
 			set_print_declaration(set, &opts, &ctx->nft->output);
 			nft_print(&ctx->nft->output, "%s}%s", opts.tab, opts.nl);
-- 
2.11.0


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

* [PATCH nft 5/5] cache: incorrect cache flags for create commands
  2019-07-16 10:26 [PATCH nft 1/5] src: add set_is_datamap(), set_is_objmap() and set_is_map() helpers Pablo Neira Ayuso
                   ` (2 preceding siblings ...)
  2019-07-16 10:26 ` [PATCH nft 4/5] evaluate: honor NFT_SET_OBJECT flag Pablo Neira Ayuso
@ 2019-07-16 10:26 ` Pablo Neira Ayuso
  3 siblings, 0 replies; 5+ messages in thread
From: Pablo Neira Ayuso @ 2019-07-16 10:26 UTC (permalink / raw)
  To: netfilter-devel

 # nft create table testD
 # nft create chain testD test6
 Error: No such file or directory
 create chain testD test6
              ^^^^^

Handle 'create' command just like 'add' and 'insert'. Check for object
types to dump the tables for more fine grain listing, instead of dumping
the whole ruleset.

Fixes: 7df42800cf89 ("src: single cache_update() call to build cache before evaluation")
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
 src/cache.c                                        | 30 +++++++++++++++-------
 tests/shell/testcases/chains/0030create_0          |  6 +++++
 .../shell/testcases/chains/dumps/0030create_0.nft  |  4 +++
 3 files changed, 31 insertions(+), 9 deletions(-)
 create mode 100644 tests/shell/testcases/chains/0030create_0
 create mode 100644 tests/shell/testcases/chains/dumps/0030create_0.nft

diff --git a/src/cache.c b/src/cache.c
index d371c5488d1b..e04ead85c830 100644
--- a/src/cache.c
+++ b/src/cache.c
@@ -16,10 +16,29 @@
 static unsigned int evaluate_cache_add(struct cmd *cmd, unsigned int flags)
 {
 	switch (cmd->obj) {
+	case CMD_OBJ_CHAIN:
+	case CMD_OBJ_SET:
+	case CMD_OBJ_COUNTER:
+	case CMD_OBJ_QUOTA:
+	case CMD_OBJ_LIMIT:
+	case CMD_OBJ_SECMARK:
+	case CMD_OBJ_FLOWTABLE:
+		flags |= NFT_CACHE_TABLE;
+		break;
 	case CMD_OBJ_SETELEM:
-		flags |= NFT_CACHE_SETELEM;
+		flags |= NFT_CACHE_TABLE |
+			 NFT_CACHE_CHAIN |
+			 NFT_CACHE_SET |
+			 NFT_CACHE_OBJECT |
+			 NFT_CACHE_SETELEM;
 		break;
 	case CMD_OBJ_RULE:
+		flags |= NFT_CACHE_TABLE |
+			 NFT_CACHE_CHAIN |
+			 NFT_CACHE_SET |
+			 NFT_CACHE_OBJECT |
+			 NFT_CACHE_FLOWTABLE;
+
 		if (cmd->handle.index.id ||
 		    cmd->handle.position.id)
 			flags |= NFT_CACHE_RULE;
@@ -83,18 +102,11 @@ unsigned int cache_evaluate(struct nft_ctx *nft, struct list_head *cmds)
 		switch (cmd->op) {
 		case CMD_ADD:
 		case CMD_INSERT:
+		case CMD_CREATE:
 			if (nft_output_echo(&nft->output)) {
 				flags = NFT_CACHE_FULL;
 				break;
 			}
-
-			flags |= NFT_CACHE_TABLE |
-				 NFT_CACHE_CHAIN |
-				 NFT_CACHE_SET |
-				 NFT_CACHE_FLOWTABLE |
-				 NFT_CACHE_OBJECT;
-			/* Fall through */
-		case CMD_CREATE:
 			flags = evaluate_cache_add(cmd, flags);
 			break;
 		case CMD_REPLACE:
diff --git a/tests/shell/testcases/chains/0030create_0 b/tests/shell/testcases/chains/0030create_0
new file mode 100644
index 000000000000..0b457f91f11f
--- /dev/null
+++ b/tests/shell/testcases/chains/0030create_0
@@ -0,0 +1,6 @@
+#!/bin/bash
+
+set -e
+
+$NFT add table ip x
+$NFT create chain ip x y
diff --git a/tests/shell/testcases/chains/dumps/0030create_0.nft b/tests/shell/testcases/chains/dumps/0030create_0.nft
new file mode 100644
index 000000000000..8e818d2d05e6
--- /dev/null
+++ b/tests/shell/testcases/chains/dumps/0030create_0.nft
@@ -0,0 +1,4 @@
+table ip x {
+	chain y {
+	}
+}
-- 
2.11.0


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

end of thread, other threads:[~2019-07-16 10:26 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-07-16 10:26 [PATCH nft 1/5] src: add set_is_datamap(), set_is_objmap() and set_is_map() helpers Pablo Neira Ayuso
2019-07-16 10:26 ` [PATCH nft 2/5] evaluate: missing object maps handling in list and flush commands Pablo Neira Ayuso
2019-07-16 10:26 ` [PATCH nft 3/5] src: use set_is_anonymous() Pablo Neira Ayuso
2019-07-16 10:26 ` [PATCH nft 4/5] evaluate: honor NFT_SET_OBJECT flag Pablo Neira Ayuso
2019-07-16 10:26 ` [PATCH nft 5/5] cache: incorrect cache flags for create commands 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).