Skip to contentSkip to conversation

src: consolidate XML/JSON exportation

PATCH Superseded Pablo Neira Ayuso 1 participant 2 messages Nov 10, 2014 netfilter

v1 of 2 Superseded Latest is v2 →

lore
Share & tools
lore

Pablo Neira Ayuso

author maintainer
#0 lore raw

PATCH 1/1 src: consolidate XML/JSON exportation

Add new buffer class to consolidate the existing code to export objects in XML/JSON and use it. We save ~700 LOC with this change.

The rule and set objects are not yet consolidated. It seems this would require some specific glue code per representation type since lists are arranged differently.

---
@Arturo, @Alvaro: It seems to me that the XML and JSON are currently not round-trippable due to (at least) this difference:

<expr type="meta">...</expr>
"expr":[{"type":"meta",...

Two choices:

* XML uses <expr><type>meta</type>...</expr>.
* JSON uses "expr":[{"-type":"meta",...

in any case, I think we'll have to break the representation for one of them to fix this.

 include/Makefile.am  |    3 +-
 include/buffer.h     |   88 +++++++++++++++++++++++++
 src/Makefile.am      |    1 +
 src/buffer.c         |  153 ++++++++++++++++++++++++++++++++++++++++++++
 src/chain.c          |  173 ++++++++++----------------------------------------
 src/expr/bitwise.c   |  112 +++++---------------------------
 src/expr/byteorder.c |  101 ++++++++---------------------
 src/expr/cmp.c       |   65 ++++++-------------
 src/expr/counter.c   |   48 ++++----------
 src/expr/ct.c        |   73 ++++-----------------
 src/expr/exthdr.c    |   75 +++++-----------------
 src/expr/immediate.c |   71 +++++----------------
 src/expr/limit.c     |   50 +++------------
 src/expr/log.c       |   98 ++++++----------------------
 src/expr/lookup.c    |   56 ++++------------
 src/expr/masq.c      |   33 +++-------
 src/expr/match.c     |   35 +++-------
 src/expr/meta.c      |   64 ++++---------------
 src/expr/nat.c       |  102 +++++++----------------------
 src/expr/payload.c   |   69 +++++---------------
 src/expr/queue.c     |   65 ++++---------------
 src/expr/redir.c     |   64 ++++---------------
 src/expr/reject.c    |   51 ++++-----------
 src/expr/target.c    |   35 +++-------
 src/table.c          |   84 +++++-------------------
 25 files changed, 567 insertions(+), 1202 deletions(-)
 create mode 100644 include/buffer.h
 create mode 100644 src/buffer.c
include/Makefile.am +2 -1
index 5976bbd..102d5ab 100644
@@ -1,3 +1,4 @@
 SUBDIRS = libnftnl linux
 
-noinst_HEADERS = linux_list.h
+noinst_HEADERS = linux_list.h	\
+		 buffer.h
include/buffer.h new file +88 -0

88 lines not on this page · raw message

src/Makefile.am +1 -0
index 941e69e..c77c3cc 100644
@@ -6,6 +6,7 @@ libnftnl_la_LDFLAGS = -Wl,--version-script=$(srcdir)/libnftnl.map	\
 		      -version-info $(LIBVERSION)
 
 libnftnl_la_SOURCES = utils.c		\
+		      buffer.c		\
 		      common.c		\
 		      gen.c		\
 		      table.c		\
src/buffer.c new file +153 -0

153 lines not on this page · raw message

src/chain.c +32 -141

198 lines not on this page · raw message

src/expr/bitwise.c +17 -95

138 lines not on this page · raw message

src/expr/byteorder.c +28 -73

137 lines not on this page · raw message

src/expr/cmp.c +21 -44

97 lines not on this page · raw message

src/expr/counter.c +11 -37

75 lines not on this page · raw message

src/expr/ct.c +14 -59

99 lines not on this page · raw message

src/expr/exthdr.c +16 -59

107 lines not on this page · raw message

src/expr/immediate.c +15 -56

93 lines not on this page · raw message

src/expr/limit.c +10 -40

73 lines not on this page · raw message

src/expr/log.c +18 -80

123 lines not on this page · raw message

src/expr/lookup.c +12 -44

79 lines not on this page · raw message

src/expr/masq.c +8 -25
index b39a43a..41907d5 100644
@@ -20,6 +20,7 @@
 #include <libnftnl/expr.h>
 #include <libnftnl/rule.h>
 #include "expr_ops.h"
+#include <buffer.h>
 
 struct nft_expr_masq {
 	uint32_t	flags;
@@ -135,33 +136,16 @@ nft_rule_expr_masq_xml_parse(struct nft_rule_expr *e, mxml_node_t *tree,
 	return -1;
 #endif
 }
-static int nft_rule_expr_masq_snprintf_json(char *buf, size_t len,
-					    struct nft_rule_expr *e)
+static int nft_rule_expr_masq_export(char *buf, size_t size,
+				     struct nft_rule_expr *e, int type)
 {
-	int ret, size = len, offset = 0;
 	struct nft_expr_masq *masq = nft_expr_data(e);
+	NFT_BUF_INIT(b, buf);
 
-	if (e->flags & (1 << NFT_EXPR_MASQ_FLAGS)) {
-		ret = snprintf(buf + offset, len, "\"flags\":%u", masq->flags);
-		SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
-	}
-
-	return offset;
-}
-
-static int nft_rule_expr_masq_snprintf_xml(char *buf, size_t len,
-					   struct nft_rule_expr *e)
-{
-	int ret, size = len, offset = 0;
-	struct nft_expr_masq *masq = nft_expr_data(e);
-
-	if (e->flags & (1 << NFT_EXPR_MASQ_FLAGS)) {
-		ret = snprintf(buf + offset, len, "<flags>%u</flags>",
-			       masq->flags);
-		SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
-	}
+	if (e->flags & (1 << NFT_EXPR_MASQ_FLAGS))
+		nft_buf_u32(&b, type, masq->flags, FLAGS);
 
-	return offset;
+	return nft_buf_done(&b);
 }
 
 static int nft_rule_expr_masq_snprintf_default(char *buf, size_t len,
@@ -182,9 +166,8 @@ static int nft_rule_expr_masq_snprintf(char *buf, size_t len, uint32_t type,
 	case NFT_OUTPUT_DEFAULT:
 		return nft_rule_expr_masq_snprintf_default(buf, len, e);
 	case NFT_OUTPUT_XML:
-		return nft_rule_expr_masq_snprintf_xml(buf, len, e);
 	case NFT_OUTPUT_JSON:
-		return nft_rule_expr_masq_snprintf_json(buf, len, e);
+		return nft_rule_expr_masq_export(buf, len, e, type);
 	default:
 		break;
 	}
src/expr/match.c +9 -26
index dc66585..5ee3629 100644
@@ -25,6 +25,7 @@
 #include <libnftnl/rule.h>
 
 #include "expr_ops.h"
+#include <buffer.h>
 
 /* From include/linux/netfilter/x_tables.h */
 #define XT_EXTENSION_MAXNAMELEN 29
@@ -204,33 +205,16 @@ static int nft_rule_expr_match_xml_parse(struct nft_rule_expr *e, mxml_node_t *t
 #endif
 }
 
-static int nft_rule_expr_match_snprintf_json(char *buf, size_t len,
-					     struct nft_rule_expr *e)
+static int nft_rule_expr_match_export(char *buf, size_t len,
+				      struct nft_rule_expr *e, int type)
 {
 	struct nft_expr_match *mt = nft_expr_data(e);
-	int ret, size = len, offset = 0;
+	NFT_BUF_INIT(b, buf);
 
-	if (e->flags & (1 << NFT_EXPR_MT_NAME)) {
-		ret = snprintf(buf, len, "\"name\":\"%s\"", mt->name);
-		SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
-	}
-
-	return offset;
-}
-
-static int nft_rule_expr_match_snprintf_xml(char *buf, size_t len,
-					    struct nft_rule_expr *e)
-{
-	struct nft_expr_match *mt = nft_expr_data(e);
-	int ret, size=len;
-	int offset = 0;
-
-	if (e->flags & (1 << NFT_EXPR_MT_NAME)) {
-		ret = snprintf(buf, len, "<name>%s</name>", mt->name);
-		SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
-	}
+	if (e->flags & (1 << NFT_EXPR_MT_NAME))
+		nft_buf_str(&b, type, mt->name, NAME);
 
-	return offset;
+	return nft_buf_done(&b);
 }
 
 static int
@@ -239,14 +223,13 @@ nft_rule_expr_match_snprintf(char *buf, size_t len, uint32_t type,
 {
 	struct nft_expr_match *match = nft_expr_data(e);
 
-	switch(type) {
+	switch (type) {
 	case NFT_OUTPUT_DEFAULT:
 		return snprintf(buf, len, "name %s rev %u ",
 				match->name, match->rev);
 	case NFT_OUTPUT_XML:
-		return nft_rule_expr_match_snprintf_xml(buf, len, e);
 	case NFT_OUTPUT_JSON:
-		return nft_rule_expr_match_snprintf_json(buf, len, e);
+		return nft_rule_expr_match_export(buf, len, e, type);
 	default:
 		break;
 	}
src/expr/meta.c +13 -51

90 lines not on this page · raw message

src/expr/nat.c +23 -79

141 lines not on this page · raw message

src/expr/payload.c +15 -54

103 lines not on this page · raw message

src/expr/queue.c +13 -52

91 lines not on this page · raw message

src/expr/redir.c +12 -52

87 lines not on this page · raw message

src/expr/reject.c +11 -40

77 lines not on this page · raw message

src/expr/target.c +9 -26
index bfff513..f99abd6 100644
@@ -25,6 +25,7 @@
 #include <libnftnl/rule.h>
 
 #include "expr_ops.h"
+#include <buffer.h>
 
 /* From include/linux/netfilter/x_tables.h */
 #define XT_EXTENSION_MAXNAMELEN 29
@@ -205,33 +206,16 @@ nft_rule_expr_target_xml_parse(struct nft_rule_expr *e, mxml_node_t *tree,
 #endif
 }
 
-static int nft_rule_exp_target_snprintf_json(char *buf, size_t len,
-					     struct nft_rule_expr *e)
+static int nft_rule_exp_target_export(char *buf, size_t len,
+				      struct nft_rule_expr *e, int type)
 {
 	struct nft_expr_target *target = nft_expr_data(e);
-	int ret, size = len, offset = 0;
+	NFT_BUF_INIT(b, buf);
 
-	if (e->flags & (1 << NFT_EXPR_TG_NAME)) {
-		ret = snprintf(buf, len, "\"name\":\"%s\"", target->name);
-		SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
-	}
-
-	return offset;
-}
-
-static int nft_rule_exp_target_snprintf_xml(char *buf, size_t len,
-					    struct nft_rule_expr *e)
-{
-	struct nft_expr_target *target = nft_expr_data(e);
-	int ret, size=len;
-	int offset = 0;
-
-	if (e->flags & (1 << NFT_EXPR_TG_NAME)) {
-		ret = snprintf(buf, len, "<name>%s</name>", target->name);
-		SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
-	}
+	if (e->flags & (1 << NFT_EXPR_TG_NAME))
+		nft_buf_str(&b, type, target->name, NAME);
 
-	return offset;
+	return nft_buf_done(&b);
 }
 
 static int
@@ -240,14 +224,13 @@ nft_rule_expr_target_snprintf(char *buf, size_t len, uint32_t type,
 {
 	struct nft_expr_target *target = nft_expr_data(e);
 
-	switch(type) {
+	switch (type) {
 	case NFT_OUTPUT_DEFAULT:
 		return snprintf(buf, len, "name %s rev %u ",
 				target->name, target->rev);
 	case NFT_OUTPUT_XML:
-		return nft_rule_exp_target_snprintf_xml(buf, len, e);
 	case NFT_OUTPUT_JSON:
-		return nft_rule_exp_target_snprintf_json(buf, len, e);
+		return nft_rule_exp_target_export(buf, len, e, type);
 	default:
 		break;
 	}
src/table.c +16 -68

107 lines not on this page · raw message

Signature · 1 line
1.7.10.4
author maintainer
#1 lore raw
Quoted 15 lines · Pablo Neira Ayuso

Add new buffer class to consolidate the existing code to export objects in XML/JSON and use it. We save ~700 LOC with this change.

The rule and set objects are not yet consolidated. It seems this would require some specific glue code per representation type since lists are arranged differently.

---
@Arturo, @Alvaro: It seems to me that the XML and JSON are currently not round-trippable due to (at least) this difference:

<expr type="meta">...</expr>
"expr":[{"type":"meta",...

Quoted 7 lines

Two choices:

* XML uses <expr><type>meta</type>...</expr>.
* JSON uses "expr":[{"-type":"meta",...

in any case, I think we'll have to break the representation for one of them to fix this.

I accidentally sent an old version of this patch. This change has spotted and fixed many inconsistencies in the output of expressions. I'll resend the newer patch again.