All of lore.kernel.org
 help / color / mirror / Atom feed
* [libnftnl PATCH 1/4 v2] src: add command tag in json/xml export support
@ 2015-01-30 14:35 Alvaro Neira Ayuso
  2015-01-30 14:35 ` [libnftnl PATCH 2/4 v2] src: add support to import json/xml with the new syntax Alvaro Neira Ayuso
                   ` (3 more replies)
  0 siblings, 4 replies; 9+ messages in thread
From: Alvaro Neira Ayuso @ 2015-01-30 14:35 UTC (permalink / raw)
  To: netfilter-devel

Currently, we can't do incremental updates. For example:

If we have a ruleset like:

table ip filter {
	chain input {
		type filter hook input priority 0;
	}
}

The new syntax is:

{"nftables":[{"add":[{"table":{"name":"filter",...}}]}]}

Moreover, this patch adds support to export this new command tag. We support
all the actions that we can do with nft, they are:

- Add, delete and flush tables/chains.
- Add, delete, replace and insert rules.
- Add and delete sets.
- Add and delete set elements.
- Flush ruleset.

You only need to add the command tag:

	{"nftables":[{"delete":[{...}, {...},...}]}]}
		      ^^^^^^^^
		    command tag

The possible fields that we can use are "add", "delete", "flush", "insert",
"replace" and "flush". For example:

- Flush table or chain:

	{"nftables":[{"flush":[{"table":{"name":...}}]}]}

  To flush a chain. Replace the table with the chain in json format

- Delete table, chain, set or rule:

	{"nftables":[{"delete":[{"chain":{"name":...}]}]}

  To delete a table, set or rule. Replace chain with the table, set or rule in
  json format.

- Replace a rule:

	{"nftables":[{"replace":[{"rule":{...}}]}]}

- Insert a rule:

	{"nftables":[{"insert":[{"rule":{...}}]}]}

We can export to the new syntax using the event flags and also you can use
the new functions nft_*_cmd_snprintf. In these functions, you can specify the
command that you want to set with your ruleset like a parameter.

Signed-off-by: Alvaro Neira Ayuso <alvaroneay@gmail.com>
---
[changes in v2]
 * Cosmetic changes
 * Extend the function nft_fprintf to use the new command syntax.

 include/buffer.h           |    7 ++++
 include/libnftnl/chain.h   |    2 +
 include/libnftnl/common.h  |    9 +++++
 include/libnftnl/gen.h     |    2 +
 include/libnftnl/rule.h    |    2 +
 include/libnftnl/ruleset.h |    5 +++
 include/libnftnl/set.h     |    4 ++
 include/libnftnl/table.h   |    2 +
 src/buffer.c               |   22 +++++++++++
 src/chain.c                |   24 +++++++++---
 src/common.c               |   93 +++++++++++++++++++++++---------------------
 src/gen.c                  |   24 +++++++++---
 src/internal.h             |   19 +++++----
 src/rule.c                 |   24 +++++++++---
 src/ruleset.c              |   53 +++++++++++++++++++------
 src/set.c                  |   24 +++++++++---
 src/set_elem.c             |   24 +++++++++---
 src/table.c                |   24 +++++++++---
 src/utils.c                |   24 ++++++++++--
 19 files changed, 285 insertions(+), 103 deletions(-)

diff --git a/include/buffer.h b/include/buffer.h
index 2b497f2..badffe6 100644
--- a/include/buffer.h
+++ b/include/buffer.h
@@ -24,7 +24,9 @@ int nft_buf_done(struct nft_buf *b);
 union nft_data_reg;
 
 int nft_buf_open(struct nft_buf *b, int type, const char *tag);
+int nft_buf_open_array(struct nft_buf *b, int type, const char *tag);
 int nft_buf_close(struct nft_buf *b, int type, const char *tag);
+int nft_buf_close_array(struct nft_buf *b, int type, const char *tag);
 
 int nft_buf_u32(struct nft_buf *b, int type, uint32_t value, const char *tag);
 int nft_buf_s32(struct nft_buf *b, int type, uint32_t value, const char *tag);
@@ -76,5 +78,10 @@ int nft_buf_reg(struct nft_buf *b, int type, union nft_data_reg *reg,
 #define UNIT			"unit"
 #define USE			"use"
 #define XOR			"xor"
+#define ADD			"add"
+#define INSERT			"insert"
+#define DELETE			"delete"
+#define REPLACE			"replace"
+#define FLUSH			"flush"
 
 #endif
diff --git a/include/libnftnl/chain.h b/include/libnftnl/chain.h
index c11cb5e..c820a94 100644
--- a/include/libnftnl/chain.h
+++ b/include/libnftnl/chain.h
@@ -61,6 +61,8 @@ int nft_chain_parse(struct nft_chain *c, enum nft_parse_type type,
 		    const char *data, struct nft_parse_err *err);
 int nft_chain_parse_file(struct nft_chain *c, enum nft_parse_type type,
 			 FILE *fp, struct nft_parse_err *err);
+int nft_chain_cmd_snprintf(char *buf, size_t size, struct nft_chain *t,
+			   uint32_t cmd, uint32_t type, uint32_t flags);
 int nft_chain_snprintf(char *buf, size_t size, struct nft_chain *t, uint32_t type, uint32_t flags);
 int nft_chain_fprintf(FILE *fp, struct nft_chain *c, uint32_t type, uint32_t flags);
 
diff --git a/include/libnftnl/common.h b/include/libnftnl/common.h
index fa3ab60..26f15c9 100644
--- a/include/libnftnl/common.h
+++ b/include/libnftnl/common.h
@@ -21,6 +21,15 @@ enum nft_output_flags {
 	NFT_OF_EVENT_ANY	= (NFT_OF_EVENT_NEW | NFT_OF_EVENT_DEL),
 };
 
+enum nft_cmd_type {
+	NFT_CMD_UNSPEC		= 0,
+	NFT_CMD_ADD,
+	NFT_CMD_INSERT,
+	NFT_CMD_DELETE,
+	NFT_CMD_REPLACE,
+	NFT_CMD_FLUSH,
+};
+
 enum nft_parse_type {
 	NFT_PARSE_NONE		= 0,
 	NFT_PARSE_XML,
diff --git a/include/libnftnl/gen.h b/include/libnftnl/gen.h
index 00753b0..ad79d92 100644
--- a/include/libnftnl/gen.h
+++ b/include/libnftnl/gen.h
@@ -39,6 +39,8 @@ struct nlmsghdr;
 int nft_gen_nlmsg_parse(const struct nlmsghdr *nlh, struct nft_gen *gen);
 
 int nft_gen_snprintf(char *buf, size_t size, struct nft_gen *gen, uint32_t type, uint32_t flags);
+int nft_gen_cmd_snprintf(char *buf, size_t size, struct nft_gen *gen,
+			 uint32_t cmd, uint32_t type, uint32_t flags);
 int nft_gen_fprintf(FILE *fp, struct nft_gen *gen, uint32_t type, uint32_t flags);
 
 #define nft_gen_nlmsg_build_hdr	nft_nlmsg_build_hdr
diff --git a/include/libnftnl/rule.h b/include/libnftnl/rule.h
index 62dba59..d0432e0 100644
--- a/include/libnftnl/rule.h
+++ b/include/libnftnl/rule.h
@@ -58,6 +58,8 @@ int nft_rule_parse(struct nft_rule *r, enum nft_parse_type type,
 		   const char *data, struct nft_parse_err *err);
 int nft_rule_parse_file(struct nft_rule *r, enum nft_parse_type type,
 			FILE *fp, struct nft_parse_err *err);
+int nft_rule_cmd_snprintf(char *buf, size_t size, struct nft_rule *t,
+			  uint32_t cmd, uint32_t type, uint32_t flags);
 int nft_rule_snprintf(char *buf, size_t size, struct nft_rule *t, uint32_t type, uint32_t flags);
 int nft_rule_fprintf(FILE *fp, struct nft_rule *r, uint32_t type, uint32_t flags);
 
diff --git a/include/libnftnl/ruleset.h b/include/libnftnl/ruleset.h
index 1a3e22f..cec6cd6 100644
--- a/include/libnftnl/ruleset.h
+++ b/include/libnftnl/ruleset.h
@@ -34,7 +34,12 @@ int nft_ruleset_parse(struct nft_ruleset *rs, enum nft_parse_type type,
 		      const char *data, struct nft_parse_err *err);
 int nft_ruleset_parse_file(struct nft_ruleset *rs, enum nft_parse_type type,
 			   FILE *fp, struct nft_parse_err *err);
+int nft_ruleset_cmd_snprintf(char *buf, size_t size,
+			     const struct nft_ruleset *rs, uint32_t cmd,
+			     uint32_t type, uint32_t flags);
 int nft_ruleset_snprintf(char *buf, size_t size, const struct nft_ruleset *rs, uint32_t type, uint32_t flags);
+int nft_ruleset_cmd_fprintf(FILE *fp, const struct nft_ruleset *rs,
+			    uint32_t cmd, uint32_t type, uint32_t flags);
 int nft_ruleset_fprintf(FILE *fp, const struct nft_ruleset *rs, uint32_t type, uint32_t flags);
 
 #ifdef __cplusplus
diff --git a/include/libnftnl/set.h b/include/libnftnl/set.h
index 7f3504f..6aedd80 100644
--- a/include/libnftnl/set.h
+++ b/include/libnftnl/set.h
@@ -50,6 +50,8 @@ void nft_set_nlmsg_build_payload(struct nlmsghdr *nlh, struct nft_set *s);
 int nft_set_nlmsg_parse(const struct nlmsghdr *nlh, struct nft_set *s);
 int nft_set_elems_nlmsg_parse(const struct nlmsghdr *nlh, struct nft_set *s);
 
+int nft_set_cmd_snprintf(char *buf, size_t size, struct nft_set *s,
+			 uint32_t cmd, uint32_t type, uint32_t flags);
 int nft_set_snprintf(char *buf, size_t size, struct nft_set *s, uint32_t type, uint32_t flags);
 int nft_set_fprintf(FILE *fp, struct nft_set *s, uint32_t type, uint32_t flags);
 
@@ -112,6 +114,8 @@ int nft_set_elem_parse(struct nft_set_elem *e, enum nft_parse_type type,
 		       const char *data, struct nft_parse_err *err);
 int nft_set_elem_parse_file(struct nft_set_elem *e, enum nft_parse_type type,
 			    FILE *fp, struct nft_parse_err *err);
+int nft_set_elem_cmd_snprintf(char *buf, size_t size, struct nft_set_elem *s,
+			      uint32_t cmd, uint32_t type, uint32_t flags);
 int nft_set_elem_snprintf(char *buf, size_t size, struct nft_set_elem *s, uint32_t type, uint32_t flags);
 int nft_set_elem_fprintf(FILE *fp, struct nft_set_elem *se, uint32_t type, uint32_t flags);
 
diff --git a/include/libnftnl/table.h b/include/libnftnl/table.h
index fac79e7..f20a684 100644
--- a/include/libnftnl/table.h
+++ b/include/libnftnl/table.h
@@ -51,6 +51,8 @@ int nft_table_parse(struct nft_table *t, enum nft_parse_type type,
 int nft_table_parse_file(struct nft_table *t, enum nft_parse_type type,
 			 FILE *fp, struct nft_parse_err *err);
 int nft_table_snprintf(char *buf, size_t size, struct nft_table *t, uint32_t type, uint32_t flags);
+int nft_table_cmd_snprintf(char *buf, size_t size, struct nft_table *t,
+			   uint32_t cmd, uint32_t type, uint32_t flags);
 int nft_table_fprintf(FILE *fp, struct nft_table *t, uint32_t type, uint32_t flags);
 
 #define nft_table_nlmsg_build_hdr	nft_nlmsg_build_hdr
diff --git a/src/buffer.c b/src/buffer.c
index d64f944..63cf2b8 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -71,6 +71,17 @@ int nft_buf_open(struct nft_buf *b, int type, const char *tag)
 	}
 }
 
+int nft_buf_open_array(struct nft_buf *b, int type, const char *tag)
+{
+	switch (type) {
+	case NFT_OUTPUT_JSON:
+		return nft_buf_put(b, "{\"%s\":[", tag);
+	case NFT_OUTPUT_XML:
+	default:
+		return 0;
+	}
+}
+
 int nft_buf_close(struct nft_buf *b, int type, const char *tag)
 {
 	switch (type) {
@@ -90,6 +101,17 @@ int nft_buf_close(struct nft_buf *b, int type, const char *tag)
 	}
 }
 
+int nft_buf_close_array(struct nft_buf *b, int type, const char *tag)
+{
+	switch (type) {
+	case NFT_OUTPUT_JSON:
+		return nft_buf_put(b, "]}");
+	case NFT_OUTPUT_XML:
+	default:
+		return 0;
+	}
+}
+
 int nft_buf_u32(struct nft_buf *b, int type, uint32_t value, const char *tag)
 {
 	switch (type) {
diff --git a/src/chain.c b/src/chain.c
index 26ad14d..7eb8923 100644
--- a/src/chain.c
+++ b/src/chain.c
@@ -847,12 +847,12 @@ static int nft_chain_snprintf_default(char *buf, size_t size,
 	return offset;
 }
 
-int nft_chain_snprintf(char *buf, size_t size, struct nft_chain *c,
-		       uint32_t type, uint32_t flags)
+int nft_chain_cmd_snprintf(char *buf, size_t size, struct nft_chain *c,
+			   uint32_t cmd, uint32_t type, uint32_t flags)
 {
 	int ret, len = size, offset = 0;
 
-	ret = nft_event_header_snprintf(buf+offset, len, type, flags);
+	ret = nft_cmd_header_snprintf(buf + offset, len, cmd, type, flags);
 	SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
 
 	switch (type) {
@@ -869,15 +869,26 @@ int nft_chain_snprintf(char *buf, size_t size, struct nft_chain *c,
 
 	SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
 
-	ret = nft_event_footer_snprintf(buf+offset, len, type, flags);
+	ret = nft_cmd_footer_snprintf(buf + offset, len, cmd, type, flags);
 	SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
 
 	return offset;
 }
 EXPORT_SYMBOL(nft_chain_snprintf);
 
+int nft_chain_snprintf(char *buf, size_t size, struct nft_chain *c,
+		       uint32_t type, uint32_t flags)
+{
+	uint32_t cmd;
+
+	nft_flag2cmd(flags, &cmd);
+	return nft_chain_cmd_snprintf(buf, size, c, cmd, type, flags);
+}
+EXPORT_SYMBOL(nft_chain_snprintf);
+
 static inline int nft_chain_do_snprintf(char *buf, size_t size, void *c,
-					uint32_t type, uint32_t flags)
+					uint32_t cmd, uint32_t type,
+					uint32_t flags)
 {
 	return nft_chain_snprintf(buf, size, c, type, flags);
 }
@@ -885,7 +896,8 @@ static inline int nft_chain_do_snprintf(char *buf, size_t size, void *c,
 int nft_chain_fprintf(FILE *fp, struct nft_chain *c, uint32_t type,
 		      uint32_t flags)
 {
-	return nft_fprintf(fp, c, type, flags, nft_chain_do_snprintf);
+	return nft_fprintf(fp, c, NFT_CMD_UNSPEC, type, flags,
+			   nft_chain_do_snprintf);
 }
 EXPORT_SYMBOL(nft_chain_fprintf);
 
diff --git a/src/common.c b/src/common.c
index a6f2508..98218aa 100644
--- a/src/common.c
+++ b/src/common.c
@@ -16,10 +16,19 @@
 #include <libmnl/libmnl.h>
 #include <libnftnl/common.h>
 #include <libnftnl/set.h>
+#include <buffer.h>
 
 #include <errno.h>
 #include "internal.h"
 
+const char *cmd2tag[] = {
+	[NFT_CMD_ADD]			= ADD,
+	[NFT_CMD_INSERT]		= INSERT,
+	[NFT_CMD_DELETE]		= DELETE,
+	[NFT_CMD_REPLACE]		= REPLACE,
+	[NFT_CMD_FLUSH]			= FLUSH,
+};
+
 struct nlmsghdr *nft_nlmsg_build_hdr(char *buf, uint16_t cmd, uint16_t family,
 				     uint16_t type, uint32_t seq)
 {
@@ -70,86 +79,82 @@ int nft_parse_perror(const char *msg, struct nft_parse_err *err)
 }
 EXPORT_SYMBOL(nft_parse_perror);
 
-int nft_event_header_snprintf(char *buf, size_t size, uint32_t type,
-			      uint32_t flags)
+int nft_cmd_header_snprintf(char *buf, size_t size, uint32_t cmd, uint32_t type,
+			    uint32_t flags)
 {
-	int ret = 0;
+	NFT_BUF_INIT(b, buf, size);
 
-	if (!(flags & NFT_OF_EVENT_ANY))
+	if (cmd == NFT_CMD_UNSPEC)
 		return 0;
 
 	switch (type) {
 	case NFT_OUTPUT_XML:
-		if (flags & NFT_OF_EVENT_NEW) {
-			ret = snprintf(buf, size, "<event><type>new</type>");
-		} else if (flags & NFT_OF_EVENT_DEL) {
-			ret = snprintf(buf, size,
-				       "<event><type>delete</type>");
-		} else {
-			ret = snprintf(buf, size,
-				       "<event><type>unknown</type>");
-		}
+		nft_buf_open(&b, type, cmd2tag[cmd]);
 		break;
 	case NFT_OUTPUT_JSON:
-		if (flags & NFT_OF_EVENT_NEW) {
-			ret = snprintf(buf, size, "{event:{type:\"new\",{\"");
-		} else if (flags & NFT_OF_EVENT_DEL) {
-			ret = snprintf(buf, size,
-				       "{event:{type:\"delete\",{\"");
-		} else {
-			ret = snprintf(buf, size,
-				       "{event:{type:\"unknown\",{\"");
-		}
+		nft_buf_open_array(&b, type, cmd2tag[cmd]);
 		break;
 	default:
-		if (flags & NFT_OF_EVENT_NEW) {
-			ret = snprintf(buf, size, "%9s", "[NEW] ");
-		} else if (flags & NFT_OF_EVENT_DEL) {
-			ret = snprintf(buf, size, "%9s", "[DELETE] ");
-		} else {
-			ret = snprintf(buf, size, "%9s", "[unknown] ");
+		switch (cmd) {
+		case NFT_CMD_ADD:
+			return snprintf(buf, size, "%9s", "[ADD] ");
+		case NFT_CMD_DELETE:
+			return snprintf(buf, size, "%9s", "[DELETE] ");
+		default:
+			return snprintf(buf, size, "%9s", "[unknown] ");
 		}
 		break;
 	}
-	return ret;
+	return nft_buf_done(&b);
 }
 
-static int nft_event_header_fprintf_cb(char *buf, size_t size, void *unused,
-				       uint32_t type, uint32_t flags)
+static int nft_cmd_header_fprintf_cb(char *buf, size_t size, void *obj,
+				     uint32_t cmd, uint32_t type,
+				     uint32_t flags)
 {
-	return nft_event_header_snprintf(buf, size, type, flags);
+	return nft_cmd_header_snprintf(buf, size, cmd, type, flags);
 }
 
-int nft_event_header_fprintf(FILE *fp, uint32_t type, uint32_t flags)
+int nft_cmd_header_fprintf(FILE *fp, uint32_t cmd, uint32_t type,
+			   uint32_t flags)
 {
-	return nft_fprintf(fp, NULL, type, flags, nft_event_header_fprintf_cb);
+	return nft_fprintf(fp, NULL, cmd, type, flags,
+			   nft_cmd_header_fprintf_cb);
 }
 
-int nft_event_footer_snprintf(char *buf, size_t size, uint32_t type,
-			      uint32_t flags)
+int nft_cmd_footer_snprintf(char *buf, size_t size, uint32_t cmd, uint32_t type,
+			    uint32_t flags)
 {
-	if (!(flags & NFT_OF_EVENT_ANY))
+	NFT_BUF_INIT(b, buf, size);
+
+	if (cmd == NFT_CMD_UNSPEC)
 		return 0;
 
 	switch (type) {
 	case NFT_OUTPUT_XML:
-		return snprintf(buf, size, "</event>");
+		nft_buf_close(&b, type, cmd2tag[cmd]);
+		break;
 	case NFT_OUTPUT_JSON:
-		return snprintf(buf, size, "}}}");
+		nft_buf_close_array(&b, type, 0);
+		break;
 	default:
 		return 0;
 	}
+	return nft_buf_done(&b);
 }
 
-static int nft_event_footer_fprintf_cb(char *buf, size_t size, void *unused,
-				       uint32_t type, uint32_t flags)
+static int nft_cmd_footer_fprintf_cb(char *buf, size_t size, void *obj,
+				     uint32_t cmd, uint32_t type,
+				     uint32_t flags)
 {
-	return nft_event_footer_snprintf(buf, size, type, flags);
+	return nft_cmd_footer_snprintf(buf, size, cmd, type, flags);
 }
 
-int nft_event_footer_fprintf(FILE *fp, uint32_t type, uint32_t flags)
+int nft_cmd_footer_fprintf(FILE *fp, uint32_t cmd, uint32_t type,
+			   uint32_t flags)
 {
-	return nft_fprintf(fp, NULL, type, flags, nft_event_footer_fprintf_cb);
+	return nft_fprintf(fp, NULL, cmd, type, flags,
+			   nft_cmd_footer_fprintf_cb);
 }
 
 static void nft_batch_build_hdr(char *buf, uint16_t type, uint32_t seq)
diff --git a/src/gen.c b/src/gen.c
index 21d3a49..c95af2c 100644
--- a/src/gen.c
+++ b/src/gen.c
@@ -161,12 +161,12 @@ static int nft_gen_snprintf_default(char *buf, size_t size, struct nft_gen *gen)
 	return snprintf(buf, size, "ruleset generation ID %u", gen->id);
 }
 
-int nft_gen_snprintf(char *buf, size_t size, struct nft_gen *gen,
-		       uint32_t type, uint32_t flags)
+int nft_gen_cmd_snprintf(char *buf, size_t size, struct nft_gen *gen,
+			 uint32_t cmd, uint32_t type, uint32_t flags)
 {
 	int ret, len = size, offset = 0;
 
-	ret = nft_event_header_snprintf(buf + offset, len, type, flags);
+	ret = nft_cmd_header_snprintf(buf + offset, len, cmd, type, flags);
 	SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
 
 	switch(type) {
@@ -178,15 +178,26 @@ int nft_gen_snprintf(char *buf, size_t size, struct nft_gen *gen,
 	}
 	SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
 
-	ret = nft_event_footer_snprintf(buf + offset, len, type, flags);
+	ret = nft_cmd_footer_snprintf(buf + offset, len, cmd, type, flags);
 	SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
 
 	return offset;
 }
+EXPORT_SYMBOL(nft_gen_cmd_snprintf);
+
+int nft_gen_snprintf(char *buf, size_t size, struct nft_gen *gen, uint32_t type,
+		     uint32_t flags)
+{
+	uint32_t cmd;
+
+	nft_flag2cmd(flags, &cmd);
+	return nft_gen_cmd_snprintf(buf, size, gen, cmd, type, flags);
+}
 EXPORT_SYMBOL(nft_gen_snprintf);
 
 static inline int nft_gen_do_snprintf(char *buf, size_t size, void *gen,
-				      uint32_t type, uint32_t flags)
+				      uint32_t cmd, uint32_t type,
+				      uint32_t flags)
 {
 	return nft_gen_snprintf(buf, size, gen, type, flags);
 }
@@ -194,6 +205,7 @@ static inline int nft_gen_do_snprintf(char *buf, size_t size, void *gen,
 int nft_gen_fprintf(FILE *fp, struct nft_gen *gen, uint32_t type,
 		    uint32_t flags)
 {
-	return nft_fprintf(fp, gen, type, flags, nft_gen_do_snprintf);
+	return nft_fprintf(fp, gen, NFT_CMD_UNSPEC, type, flags,
+			   nft_gen_do_snprintf);
 }
 EXPORT_SYMBOL(nft_gen_fprintf);
diff --git a/src/internal.h b/src/internal.h
index db9af11..a846d1e 100644
--- a/src/internal.h
+++ b/src/internal.h
@@ -146,16 +146,21 @@ int nft_str2family(const char *family);
 int nft_strtoi(const char *string, int base, void *number, enum nft_type type);
 const char *nft_verdict2str(uint32_t verdict);
 int nft_str2verdict(const char *verdict, int *verdict_num);
+int nft_flag2cmd(uint32_t flags, uint32_t *cmd);
 int nft_get_value(enum nft_type type, void *val, void *out);
 
 #include <stdio.h>
-int nft_fprintf(FILE *fp, void *obj, uint32_t type, uint32_t flags, int (*snprintf_cb)(char *buf, size_t bufsiz, void *obj, uint32_t type, uint32_t flags));
-int nft_event_header_snprintf(char *buf, size_t bufsize,
-			      uint32_t format, uint32_t flags);
-int nft_event_header_fprintf(FILE *fp, uint32_t format, uint32_t flags);
-int nft_event_footer_snprintf(char *buf, size_t bufsize,
-			      uint32_t format, uint32_t flags);
-int nft_event_footer_fprintf(FILE *fp, uint32_t format, uint32_t flags);
+int nft_fprintf(FILE *fp, void *obj, uint32_t cmd, uint32_t type,
+		uint32_t flags, int (*snprintf_cb)(char *buf, size_t bufsiz,
+		void *obj, uint32_t cmd, uint32_t type, uint32_t flags));
+int nft_cmd_header_snprintf(char *buf, size_t bufsize, uint32_t cmd,
+			    uint32_t format, uint32_t flags);
+int nft_cmd_header_fprintf(FILE *fp, uint32_t cmd, uint32_t format,
+			   uint32_t flags);
+int nft_cmd_footer_snprintf(char *buf, size_t bufsize, uint32_t cmd,
+			    uint32_t format, uint32_t flags);
+int nft_cmd_footer_fprintf(FILE *fp, uint32_t cmd, uint32_t format,
+			   uint32_t flags);
 
 struct expr_ops;
 
diff --git a/src/rule.c b/src/rule.c
index ac5136c..7ba5191 100644
--- a/src/rule.c
+++ b/src/rule.c
@@ -963,15 +963,15 @@ static int nft_rule_snprintf_default(char *buf, size_t size, struct nft_rule *r,
 	return offset;
 }
 
-int nft_rule_snprintf(char *buf, size_t size, struct nft_rule *r,
-		       uint32_t type, uint32_t flags)
+int nft_rule_cmd_snprintf(char *buf, size_t size, struct nft_rule *r,
+			  uint32_t cmd, uint32_t type, uint32_t flags)
 {
 	int ret, len = size, offset = 0;
 	uint32_t inner_flags = flags;
 
 	inner_flags &= ~NFT_OF_EVENT_ANY;
 
-	ret = nft_event_header_snprintf(buf+offset, len, type, flags);
+	ret = nft_cmd_header_snprintf(buf + offset, len, cmd, type, flags);
 	SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
 
 	switch(type) {
@@ -993,15 +993,26 @@ int nft_rule_snprintf(char *buf, size_t size, struct nft_rule *r,
 
 	SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
 
-	ret = nft_event_footer_snprintf(buf+offset, len, type, flags);
+	ret = nft_cmd_footer_snprintf(buf + offset, len, cmd, type, flags);
 	SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
 
 	return offset;
 }
+EXPORT_SYMBOL(nft_rule_cmd_snprintf);
+
+int nft_rule_snprintf(char *buf, size_t size, struct nft_rule *r,
+		      uint32_t type, uint32_t flags)
+{
+	uint32_t cmd;
+
+	nft_flag2cmd(flags, &cmd);
+	return nft_rule_cmd_snprintf(buf, size, r, cmd, type, flags);
+}
 EXPORT_SYMBOL(nft_rule_snprintf);
 
 static inline int nft_rule_do_snprintf(char *buf, size_t size, void *r,
-				       uint32_t type, uint32_t flags)
+				       uint32_t cmd, uint32_t type,
+				       uint32_t flags)
 {
 	return nft_rule_snprintf(buf, size, r, type, flags);
 }
@@ -1009,7 +1020,8 @@ static inline int nft_rule_do_snprintf(char *buf, size_t size, void *r,
 int nft_rule_fprintf(FILE *fp, struct nft_rule *r, uint32_t type,
 		     uint32_t flags)
 {
-	return nft_fprintf(fp, r, type, flags, nft_rule_do_snprintf);
+	return nft_fprintf(fp, r, NFT_CMD_UNSPEC, type, flags,
+			   nft_rule_do_snprintf);
 }
 EXPORT_SYMBOL(nft_rule_fprintf);
 
diff --git a/src/ruleset.c b/src/ruleset.c
index c29c307..3fb381d 100644
--- a/src/ruleset.c
+++ b/src/ruleset.c
@@ -784,7 +784,7 @@ nft_ruleset_snprintf_rule(char *buf, size_t size,
 
 static int
 nft_ruleset_do_snprintf(char *buf, size_t size, const struct nft_ruleset *rs,
-			uint32_t type, uint32_t flags)
+			uint32_t cmd, uint32_t type, uint32_t flags)
 {
 	int ret, len = size, offset = 0;
 	void *prev = NULL;
@@ -793,10 +793,10 @@ nft_ruleset_do_snprintf(char *buf, size_t size, const struct nft_ruleset *rs,
 	/* dont pass events flags to child calls of _snprintf() */
 	inner_flags &= ~NFT_OF_EVENT_ANY;
 
-	ret = nft_event_header_snprintf(buf+offset, len, type, flags);
+	ret = snprintf(buf+offset, len, "%s", nft_ruleset_o_opentag(type));
 	SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
 
-	ret = snprintf(buf+offset, len, "%s", nft_ruleset_o_opentag(type));
+	ret = nft_cmd_header_snprintf(buf + offset, len, cmd, type, flags);
 	SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
 
 	if (nft_ruleset_attr_is_set(rs, NFT_RULESET_ATTR_TABLELIST) &&
@@ -848,10 +848,10 @@ nft_ruleset_do_snprintf(char *buf, size_t size, const struct nft_ruleset *rs,
 		SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
 	}
 
-	ret = snprintf(buf+offset, len, "%s", nft_ruleset_o_closetag(type));
+	ret = nft_cmd_footer_snprintf(buf + offset, len, cmd, type, flags);
 	SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
 
-	ret = nft_event_footer_snprintf(buf+offset, len, type, flags);
+	ret = snprintf(buf+offset, len, "%s", nft_ruleset_o_closetag(type));
 	SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
 
 	return offset;
@@ -860,11 +860,14 @@ nft_ruleset_do_snprintf(char *buf, size_t size, const struct nft_ruleset *rs,
 int nft_ruleset_snprintf(char *buf, size_t size, const struct nft_ruleset *r,
 			 uint32_t type, uint32_t flags)
 {
+	uint32_t cmd;
+
+	nft_flag2cmd(flags, &cmd);
 	switch (type) {
 	case NFT_OUTPUT_DEFAULT:
 	case NFT_OUTPUT_XML:
 	case NFT_OUTPUT_JSON:
-		return nft_ruleset_do_snprintf(buf, size, r, type, flags);
+		return nft_ruleset_do_snprintf(buf, size, r, cmd, type, flags);
 	default:
 		errno = EOPNOTSUPP;
 		return -1;
@@ -872,6 +875,22 @@ int nft_ruleset_snprintf(char *buf, size_t size, const struct nft_ruleset *r,
 }
 EXPORT_SYMBOL(nft_ruleset_snprintf);
 
+int nft_ruleset_cmd_snprintf(char *buf, size_t size,
+			     const struct nft_ruleset *r, uint32_t cmd,
+			     uint32_t type, uint32_t flags)
+{
+	switch (type) {
+	case NFT_OUTPUT_DEFAULT:
+	case NFT_OUTPUT_XML:
+	case NFT_OUTPUT_JSON:
+		return nft_ruleset_do_snprintf(buf, size, r, cmd, type, flags);
+	default:
+		errno = EOPNOTSUPP;
+		return -1;
+	}
+}
+EXPORT_SYMBOL(nft_ruleset_cmd_snprintf);
+
 static int nft_ruleset_fprintf_tables(FILE *fp, const struct nft_ruleset *rs,
 				      uint32_t type, uint32_t flags)
 {
@@ -1017,8 +1036,8 @@ err:
 		return -1;			\
 	len += ret;
 
-int nft_ruleset_fprintf(FILE *fp, const struct nft_ruleset *rs, uint32_t type,
-			uint32_t flags)
+int nft_ruleset_cmd_fprintf(FILE *fp, const struct nft_ruleset *rs,
+			    uint32_t cmd, uint32_t type, uint32_t flags)
 {
 	int len = 0, ret = 0;
 	void *prev = NULL;
@@ -1027,10 +1046,10 @@ int nft_ruleset_fprintf(FILE *fp, const struct nft_ruleset *rs, uint32_t type,
 	/* dont pass events flags to child calls of _snprintf() */
 	inner_flags &= ~NFT_OF_EVENT_ANY;
 
-	ret = nft_event_header_fprintf(fp, type, flags);
+	ret = fprintf(fp, "%s", nft_ruleset_o_opentag(type));
 	NFT_FPRINTF_RETURN_OR_FIXLEN(ret, len);
 
-	ret = fprintf(fp, "%s", nft_ruleset_o_opentag(type));
+	ret = nft_cmd_header_fprintf(fp, cmd, type, flags);
 	NFT_FPRINTF_RETURN_OR_FIXLEN(ret, len);
 
 	if ((nft_ruleset_attr_is_set(rs, NFT_RULESET_ATTR_TABLELIST)) &&
@@ -1075,12 +1094,22 @@ int nft_ruleset_fprintf(FILE *fp, const struct nft_ruleset *rs, uint32_t type,
 		NFT_FPRINTF_RETURN_OR_FIXLEN(ret, len);
 	}
 
-	ret = fprintf(fp, "%s", nft_ruleset_o_closetag(type));
+	ret = nft_cmd_footer_fprintf(fp, cmd, type, flags);
 	NFT_FPRINTF_RETURN_OR_FIXLEN(ret, len);
 
-	ret = nft_event_footer_fprintf(fp, type, flags);
+	ret = fprintf(fp, "%s", nft_ruleset_o_closetag(type));
 	NFT_FPRINTF_RETURN_OR_FIXLEN(ret, len);
 
 	return len;
 }
+EXPORT_SYMBOL(nft_ruleset_cmd_fprintf);
+
+int nft_ruleset_fprintf(FILE *fp, const struct nft_ruleset *rs, uint32_t type,
+			uint32_t flags)
+{
+	uint32_t cmd;
+
+	nft_flag2cmd(flags, &cmd);
+	return nft_ruleset_cmd_fprintf(fp, rs, cmd, type, flags);
+}
 EXPORT_SYMBOL(nft_ruleset_fprintf);
diff --git a/src/set.c b/src/set.c
index 4fd786a..038b7fa 100644
--- a/src/set.c
+++ b/src/set.c
@@ -889,8 +889,8 @@ static int nft_set_snprintf_xml(char *buf, size_t size, struct nft_set *s,
 	return offset;
 }
 
-int nft_set_snprintf(char *buf, size_t size, struct nft_set *s,
-		     uint32_t type, uint32_t flags)
+int nft_set_cmd_snprintf(char *buf, size_t size, struct nft_set *s,
+			 uint32_t cmd, uint32_t type, uint32_t flags)
 {
 	int ret, len = size, offset = 0;
 	uint32_t inner_flags = flags;
@@ -898,7 +898,7 @@ int nft_set_snprintf(char *buf, size_t size, struct nft_set *s,
 	/* prevent set_elems to print as events */
 	inner_flags &= ~NFT_OF_EVENT_ANY;
 
-	ret = nft_event_header_snprintf(buf+offset, len, type, flags);
+	ret = nft_cmd_header_snprintf(buf + offset, len, cmd, type, flags);
 	SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
 
 	switch(type) {
@@ -919,15 +919,26 @@ int nft_set_snprintf(char *buf, size_t size, struct nft_set *s,
 
 	SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
 
-	ret = nft_event_footer_snprintf(buf+offset, len, type, flags);
+	ret = nft_cmd_footer_snprintf(buf + offset, len, cmd, type, flags);
 	SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
 
 	return offset;
 }
+EXPORT_SYMBOL(nft_set_cmd_snprintf);
+
+int nft_set_snprintf(char *buf, size_t size, struct nft_set *s,
+		     uint32_t type, uint32_t flags)
+{
+	uint32_t cmd;
+
+	nft_flag2cmd(flags, &cmd);
+	return nft_set_cmd_snprintf(buf, size, s, cmd, type, flags);
+}
 EXPORT_SYMBOL(nft_set_snprintf);
 
 static inline int nft_set_do_snprintf(char *buf, size_t size, void *s,
-				      uint32_t type, uint32_t flags)
+				      uint32_t cmd, uint32_t type,
+				      uint32_t flags)
 {
 	return nft_set_snprintf(buf, size, s, type, flags);
 }
@@ -935,7 +946,8 @@ static inline int nft_set_do_snprintf(char *buf, size_t size, void *s,
 int nft_set_fprintf(FILE *fp, struct nft_set *s, uint32_t type,
 		    uint32_t flags)
 {
-	return nft_fprintf(fp, s, type, flags, nft_set_do_snprintf);
+	return nft_fprintf(fp, s, NFT_CMD_UNSPEC, type, flags,
+			   nft_set_do_snprintf);
 }
 EXPORT_SYMBOL(nft_set_fprintf);
 
diff --git a/src/set_elem.c b/src/set_elem.c
index 4f52b1a..85254e9 100644
--- a/src/set_elem.c
+++ b/src/set_elem.c
@@ -614,12 +614,12 @@ static int nft_set_elem_snprintf_xml(char *buf, size_t size,
 	return offset;
 }
 
-int nft_set_elem_snprintf(char *buf, size_t size, struct nft_set_elem *e,
-			   uint32_t type, uint32_t flags)
+int nft_set_elem_cmd_snprintf(char *buf, size_t size, struct nft_set_elem *e,
+			      uint32_t cmd, uint32_t type, uint32_t flags)
 {
 	int ret, len = size, offset = 0;
 
-	ret = nft_event_header_snprintf(buf+offset, len, type, flags);
+	ret = nft_cmd_header_snprintf(buf + offset, len, cmd, type, flags);
 	SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
 
 	switch(type) {
@@ -638,15 +638,26 @@ int nft_set_elem_snprintf(char *buf, size_t size, struct nft_set_elem *e,
 
 	SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
 
-	ret = nft_event_footer_snprintf(buf+offset, len, type, flags);
+	ret = nft_cmd_footer_snprintf(buf + offset, len, cmd, type, flags);
 	SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
 
 	return offset;
 }
+EXPORT_SYMBOL(nft_set_elem_cmd_snprintf);
+
+int nft_set_elem_snprintf(char *buf, size_t size, struct nft_set_elem *e,
+			      uint32_t type, uint32_t flags)
+{
+	uint32_t cmd;
+
+	nft_flag2cmd(flags, &cmd);
+	return nft_set_elem_cmd_snprintf(buf, size, e, cmd, type, flags);
+}
 EXPORT_SYMBOL(nft_set_elem_snprintf);
 
 static inline int nft_set_elem_do_snprintf(char *buf, size_t size, void *e,
-					   uint32_t type, uint32_t flags)
+					   uint32_t cmd, uint32_t type,
+					   uint32_t flags)
 {
 	return nft_set_elem_snprintf(buf, size, e, type, flags);
 }
@@ -654,7 +665,8 @@ static inline int nft_set_elem_do_snprintf(char *buf, size_t size, void *e,
 int nft_set_elem_fprintf(FILE *fp, struct nft_set_elem *se, uint32_t type,
 			 uint32_t flags)
 {
-	return nft_fprintf(fp, se, type, flags, nft_set_elem_do_snprintf);
+	return nft_fprintf(fp, se, NFT_CMD_UNSPEC, type, flags,
+			   nft_set_elem_do_snprintf);
 }
 EXPORT_SYMBOL(nft_set_elem_fprintf);
 
diff --git a/src/table.c b/src/table.c
index e947394..6ed17c9 100644
--- a/src/table.c
+++ b/src/table.c
@@ -419,12 +419,12 @@ static int nft_table_snprintf_default(char *buf, size_t size, struct nft_table *
 			t->table_flags, t->use);
 }
 
-int nft_table_snprintf(char *buf, size_t size, struct nft_table *t,
-		       uint32_t type, uint32_t flags)
+int nft_table_cmd_snprintf(char *buf, size_t size, struct nft_table *t,
+			   uint32_t cmd, uint32_t type, uint32_t flags)
 {
 	int ret, len = size, offset = 0;
 
-	ret = nft_event_header_snprintf(buf+offset, len, type, flags);
+	ret = nft_cmd_header_snprintf(buf + offset, len, cmd, type, flags);
 	SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
 
 	switch (type) {
@@ -440,15 +440,26 @@ int nft_table_snprintf(char *buf, size_t size, struct nft_table *t,
 	}
 	SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
 
-	ret = nft_event_footer_snprintf(buf+offset, len, type, flags);
+	ret = nft_cmd_footer_snprintf(buf + offset, len, cmd, type, flags);
 	SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
 
 	return offset;
 }
+EXPORT_SYMBOL(nft_table_cmd_snprintf);
+
+int nft_table_snprintf(char *buf, size_t size, struct nft_table *t,
+		       uint32_t type, uint32_t flags)
+{
+	uint32_t cmd;
+
+	nft_flag2cmd(flags, &cmd);
+	return nft_table_cmd_snprintf(buf, size, t, cmd, type, flags);
+}
 EXPORT_SYMBOL(nft_table_snprintf);
 
 static inline int nft_table_do_snprintf(char *buf, size_t size, void *t,
-					uint32_t type, uint32_t flags)
+					uint32_t cmd, uint32_t type,
+					uint32_t flags)
 {
 	return nft_table_snprintf(buf, size, t, type, flags);
 }
@@ -456,7 +467,8 @@ static inline int nft_table_do_snprintf(char *buf, size_t size, void *t,
 int nft_table_fprintf(FILE *fp, struct nft_table *t, uint32_t type,
 		      uint32_t flags)
 {
-	return nft_fprintf(fp, t, type, flags, nft_table_do_snprintf);
+	return nft_fprintf(fp, t, NFT_CMD_UNSPEC, type, flags,
+			   nft_table_do_snprintf);
 }
 EXPORT_SYMBOL(nft_table_fprintf);
 
diff --git a/src/utils.c b/src/utils.c
index 9013b68..6ef0ef4 100644
--- a/src/utils.c
+++ b/src/utils.c
@@ -177,16 +177,32 @@ int nft_str2verdict(const char *verdict, int *verdict_num)
 	return -1;
 }
 
-int nft_fprintf(FILE *fp, void *obj, uint32_t type, uint32_t flags,
+int nft_flag2cmd(uint32_t flags, uint32_t *cmd)
+{
+	if (!(flags & NFT_OF_EVENT_ANY)) {
+		*cmd = NFT_CMD_UNSPEC;
+		return 0;
+	} else if (flags & NFT_OF_EVENT_NEW) {
+		*cmd = NFT_CMD_ADD;
+		return 0;
+	} else if (flags & NFT_OF_EVENT_DEL) {
+		*cmd = NFT_CMD_DELETE;
+		return 0;
+	}
+
+	return -1;
+}
+
+int nft_fprintf(FILE *fp, void *obj, uint32_t cmd, uint32_t type, uint32_t flags,
 		int (*snprintf_cb)(char *buf, size_t bufsiz, void *obj,
-				   uint32_t type, uint32_t flags))
+				   uint32_t cmd, uint32_t type, uint32_t flags))
 {
 	char _buf[NFT_SNPRINTF_BUFSIZ];
 	char *buf = _buf;
 	size_t bufsiz = sizeof(_buf);
 	int ret;
 
-	ret = snprintf_cb(buf, bufsiz, obj, type, flags);
+	ret = snprintf_cb(buf, bufsiz, obj, cmd, type, flags);
 	if (ret <= 0)
 		goto out;
 
@@ -197,7 +213,7 @@ int nft_fprintf(FILE *fp, void *obj, uint32_t type, uint32_t flags,
 		if (buf == NULL)
 			return -1;
 
-		ret = snprintf_cb(buf, bufsiz, obj, type, flags);
+		ret = snprintf_cb(buf, bufsiz, obj, cmd, type, flags);
 		if (ret <= 0)
 			goto out;
 	}
-- 
1.7.10.4


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

end of thread, other threads:[~2015-01-30 19:53 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-01-30 14:35 [libnftnl PATCH 1/4 v2] src: add command tag in json/xml export support Alvaro Neira Ayuso
2015-01-30 14:35 ` [libnftnl PATCH 2/4 v2] src: add support to import json/xml with the new syntax Alvaro Neira Ayuso
2015-01-30 18:38   ` Pablo Neira Ayuso
2015-01-30 19:56   ` Pablo Neira Ayuso
2015-01-30 14:35 ` [libnftnl PATCH 3/4 v4] example: Parse and create netlink message using the new parsing functions Alvaro Neira Ayuso
2015-01-30 19:43   ` Pablo Neira Ayuso
2015-01-30 14:35 ` [libnftnl PATCH 4/4 v2] test: update json/xml tests to the new syntax Alvaro Neira Ayuso
2015-01-30 18:38   ` Pablo Neira Ayuso
2015-01-30 18:36 ` [libnftnl PATCH 1/4 v2] src: add command tag in json/xml export support Pablo Neira Ayuso

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.