summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorArturo Borrero Gonzalez <arturo.borrero.glez@gmail.com>2013-09-16 20:24:51 +0200
committerPablo Neira Ayuso <pablo@netfilter.org>2013-09-16 22:42:43 +0200
commit210adc4063a7557b3bc0ffd69bd992c0bec4bacc (patch)
tree784228ac8183c4f4da0f696954040e214dfa760b /src
parent2f5a7c560ab5e20111f6196181a603e1bd3f8791 (diff)
src: xml: refactor XML parsing code
This patch refactors nft_*_xml_parse to provide a new intermediate function nft_mxml_parse_* which will allow us to navigate an entire XML tree containing a ruleset without xml2text2xml conversions. While at it, I added a helper to build the XML tree and validate the top node name. Signed-off-by: Arturo Borrero Gonzalez <arturo.borrero.glez@gmail.com>
Diffstat (limited to 'src')
-rw-r--r--src/chain.c50
-rw-r--r--src/internal.h9
-rw-r--r--src/mxml.c19
-rw-r--r--src/rule.c51
-rw-r--r--src/set.c50
-rw-r--r--src/set_elem.c14
-rw-r--r--src/table.c34
7 files changed, 122 insertions, 105 deletions
diff --git a/src/chain.c b/src/chain.c
index 09ab5e3..8c0d804 100644
--- a/src/chain.c
+++ b/src/chain.c
@@ -612,50 +612,42 @@ static int nft_chain_json_parse(struct nft_chain *c, const char *json)
#endif
}
-static int nft_chain_xml_parse(struct nft_chain *c, const char *xml)
-{
#ifdef XML_PARSING
- mxml_node_t *tree;
+int nft_mxml_chain_parse(mxml_node_t *tree, struct nft_chain *c)
+{
const char *table, *name, *hooknum_str, *policy_str, *type;
int family, hooknum, policy;
- tree = mxmlLoadString(NULL, xml, MXML_OPAQUE_CALLBACK);
- if (tree == NULL)
- return -1;
-
- if (strcmp(tree->value.opaque, "chain") != 0)
- goto err;
-
name = nft_mxml_str_parse(tree, "name", MXML_DESCEND_FIRST,
NFT_XML_MAND);
if (name == NULL)
- goto err;
+ return -1;
strncpy(c->name, name, NFT_CHAIN_MAXNAMELEN);
c->flags |= (1 << NFT_CHAIN_ATTR_NAME);
if (nft_mxml_num_parse(tree, "handle", MXML_DESCEND_FIRST, BASE_DEC,
&c->handle, NFT_TYPE_U64, NFT_XML_MAND) != 0)
- goto err;
+ return -1;
c->flags |= (1 << NFT_CHAIN_ATTR_HANDLE);
if (nft_mxml_num_parse(tree, "bytes", MXML_DESCEND_FIRST, BASE_DEC,
&c->bytes, NFT_TYPE_U64, NFT_XML_MAND) != 0)
- goto err;
+ return -1;
c->flags |= (1 << NFT_CHAIN_ATTR_BYTES);
if (nft_mxml_num_parse(tree, "packets", MXML_DESCEND_FIRST, BASE_DEC,
&c->packets, NFT_TYPE_U64, NFT_XML_MAND) != 0)
- goto err;
+ return -1;
c->flags |= (1 << NFT_CHAIN_ATTR_PACKETS);
table = nft_mxml_str_parse(tree, "table", MXML_DESCEND_FIRST,
NFT_XML_MAND);
if (table == NULL)
- goto err;
+ return -1;
if (c->table)
xfree(c->table);
@@ -666,7 +658,7 @@ static int nft_chain_xml_parse(struct nft_chain *c, const char *xml)
family = nft_mxml_family_parse(tree, "family", MXML_DESCEND_FIRST,
NFT_XML_MAND);
if (family < 0)
- goto err;
+ return -1;
c->family = family;
c->flags |= (1 << NFT_CHAIN_ATTR_FAMILY);
@@ -676,7 +668,7 @@ static int nft_chain_xml_parse(struct nft_chain *c, const char *xml)
if (hooknum_str != NULL) {
hooknum = nft_str2hooknum(c->family, hooknum_str);
if (hooknum < 0)
- goto err;
+ return -1;
c->hooknum = hooknum;
c->flags |= (1 << NFT_CHAIN_ATTR_HOOKNUM);
@@ -684,7 +676,7 @@ static int nft_chain_xml_parse(struct nft_chain *c, const char *xml)
type = nft_mxml_str_parse(tree, "type", MXML_DESCEND_FIRST,
NFT_XML_MAND);
if (type == NULL)
- goto err;
+ return -1;
if (c->type)
xfree(c->type);
@@ -696,7 +688,7 @@ static int nft_chain_xml_parse(struct nft_chain *c, const char *xml)
if (nft_mxml_num_parse(tree, "prio", MXML_DESCEND, BASE_DEC,
&c->prio, NFT_TYPE_S32,
NFT_XML_MAND) != 0)
- goto err;
+ return -1;
c->flags |= (1 << NFT_CHAIN_ATTR_PRIO);
@@ -704,21 +696,31 @@ static int nft_chain_xml_parse(struct nft_chain *c, const char *xml)
MXML_DESCEND_FIRST,
NFT_XML_MAND);
if (policy_str == NULL)
- goto err;
+ return -1;
policy = nft_str2verdict(policy_str);
if (policy == -1)
- goto err;
+ return -1;
c->policy = policy;
c->flags |= (1 << NFT_CHAIN_ATTR_POLICY);
}
- mxmlDelete(tree);
return 0;
-err:
+}
+#endif
+
+static int nft_chain_xml_parse(struct nft_chain *c, const char *xml)
+{
+#ifdef XML_PARSING
+ int ret;
+ mxml_node_t *tree = nft_mxml_build_tree(xml, "chain");
+ if (tree == NULL)
+ return -1;
+
+ ret = nft_mxml_chain_parse(tree, c);
mxmlDelete(tree);
- return -1;
+ return ret;
#else
errno = EOPNOTSUPP;
return -1;
diff --git a/src/internal.h b/src/internal.h
index 3d749b3..df64dd8 100644
--- a/src/internal.h
+++ b/src/internal.h
@@ -32,6 +32,7 @@ enum nft_type {
#include <mxml.h>
#define NFT_XML_MAND 0
#define NFT_XML_OPT (1 << 0)
+mxml_node_t *nft_mxml_build_tree(const char *xml, const char *treename);
struct nft_rule_expr *nft_mxml_expr_parse(mxml_node_t *node);
int nft_mxml_reg_parse(mxml_node_t *tree, const char *reg_name, uint32_t flags);
union nft_data_reg;
@@ -42,6 +43,14 @@ int nft_mxml_family_parse(mxml_node_t *tree, const char *node_name, uint32_t mxm
struct nft_set_elem;
int nft_mxml_set_elem_parse(mxml_node_t *node, struct nft_set_elem *e);
+struct nft_table;
+int nft_mxml_table_parse(mxml_node_t *tree, struct nft_table *t);
+struct nft_chain;
+int nft_mxml_chain_parse(mxml_node_t *tree, struct nft_chain *c);
+struct nft_rule;
+int nft_mxml_rule_parse(mxml_node_t *tree, struct nft_rule *r);
+struct nft_set;
+int nft_mxml_set_parse(mxml_node_t *tree, struct nft_set *s);
#endif
#ifdef JSON_PARSING
diff --git a/src/mxml.c b/src/mxml.c
index 6b7ca68..82156b7 100644
--- a/src/mxml.c
+++ b/src/mxml.c
@@ -15,11 +15,30 @@
#include <limits.h>
#include <linux/netfilter/nf_tables.h>
+#include <libnftables/table.h>
+#include <libnftables/chain.h>
#include <libnftables/rule.h>
#include <libnftables/expr.h>
#include <libnftables/set.h>
#ifdef XML_PARSING
+mxml_node_t *nft_mxml_build_tree(const char *xml, const char *treename)
+{
+ mxml_node_t *tree;
+
+ tree = mxmlLoadString(NULL, xml, MXML_OPAQUE_CALLBACK);
+ if (tree == NULL)
+ goto err;
+
+ if (strcmp(tree->value.opaque, treename) == 0)
+ return tree;
+
+ mxmlDelete(tree);
+err:
+ errno = EINVAL;
+ return NULL;
+}
+
struct nft_rule_expr *nft_mxml_expr_parse(mxml_node_t *node)
{
mxml_node_t *tree;
diff --git a/src/rule.c b/src/rule.c
index a381469..555e724 100644
--- a/src/rule.c
+++ b/src/rule.c
@@ -577,25 +577,18 @@ static int nft_rule_json_parse(struct nft_rule *r, const char *json)
#endif
}
-static int nft_rule_xml_parse(struct nft_rule *r, const char *xml)
-{
#ifdef XML_PARSING
- mxml_node_t *tree, *node, *save;
+int nft_mxml_rule_parse(mxml_node_t *tree, struct nft_rule *r)
+{
+ mxml_node_t *node;
struct nft_rule_expr *e;
const char *table, *chain;
int family;
- tree = mxmlLoadString(NULL, xml, MXML_OPAQUE_CALLBACK);
- if (tree == NULL)
- return -1;
-
- if (strcmp(tree->value.opaque, "rule") != 0)
- goto err;
-
family = nft_mxml_family_parse(tree, "family", MXML_DESCEND_FIRST,
NFT_XML_MAND);
if (family < 0)
- goto err;
+ return -1;
r->family = family;
r->flags |= (1 << NFT_RULE_ATTR_FAMILY);
@@ -603,7 +596,7 @@ static int nft_rule_xml_parse(struct nft_rule *r, const char *xml)
table = nft_mxml_str_parse(tree, "table", MXML_DESCEND_FIRST,
NFT_XML_MAND);
if (table == NULL)
- goto err;
+ return -1;
if (r->table)
xfree(r->table);
@@ -614,7 +607,7 @@ static int nft_rule_xml_parse(struct nft_rule *r, const char *xml)
chain = nft_mxml_str_parse(tree, "chain", MXML_DESCEND_FIRST,
NFT_XML_MAND);
if (chain == NULL)
- goto err;
+ return -1;
if (r->chain)
xfree(r->chain);
@@ -624,14 +617,14 @@ static int nft_rule_xml_parse(struct nft_rule *r, const char *xml)
if (nft_mxml_num_parse(tree, "handle", MXML_DESCEND_FIRST, BASE_DEC,
&r->handle, NFT_TYPE_U64, NFT_XML_MAND) != 0)
- goto err;
+ return -1;
r->flags |= (1 << NFT_RULE_ATTR_HANDLE);
if (nft_mxml_num_parse(tree, "flags", MXML_DESCEND_FIRST,
BASE_DEC, &r->rule_flags, NFT_TYPE_U32,
NFT_XML_MAND) != 0)
- goto err;
+ return -1;
r->flags |= (1 << NFT_RULE_ATTR_FLAGS);
@@ -648,7 +641,7 @@ static int nft_rule_xml_parse(struct nft_rule *r, const char *xml)
if (nft_rule_attr_is_set(r, NFT_RULE_ATTR_COMPAT_PROTO) !=
nft_rule_attr_is_set(r, NFT_RULE_ATTR_COMPAT_FLAGS)) {
errno = EINVAL;
- goto err;
+ return -1;
}
if (nft_mxml_num_parse(tree, "position", MXML_DESCEND_FIRST,
@@ -662,26 +655,28 @@ static int nft_rule_xml_parse(struct nft_rule *r, const char *xml)
node != NULL;
node = mxmlFindElement(node, tree, "expr", "type",
NULL, MXML_DESCEND)) {
-
- /* This is a hack for mxml to print just the current node */
- save = node->next;
- node->next = NULL;
-
e = nft_mxml_expr_parse(node);
if (e == NULL)
- goto err;
+ return -1;
nft_rule_add_expr(r, e);
-
- node->next = save;
- save = NULL;
}
- mxmlDelete(tree);
return 0;
-err:
+}
+#endif
+
+static int nft_rule_xml_parse(struct nft_rule *r, const char *xml)
+{
+#ifdef XML_PARSING
+ int ret;
+ mxml_node_t *tree = nft_mxml_build_tree(xml, "rule");
+ if (tree == NULL)
+ return -1;
+
+ ret = nft_mxml_rule_parse(tree, r);
mxmlDelete(tree);
- return -1;
+ return ret;
#else
errno = EOPNOTSUPP;
return -1;
diff --git a/src/set.c b/src/set.c
index 7f2ee57..98f357c 100644
--- a/src/set.c
+++ b/src/set.c
@@ -409,28 +409,18 @@ static int nft_set_json_parse(struct nft_set *s, const char *json)
#endif
}
-static int nft_set_xml_parse(struct nft_set *s, const char *xml)
-{
#ifdef XML_PARSING
- mxml_node_t *tree;
+int nft_mxml_set_parse(mxml_node_t *tree, struct nft_set *s)
+{
mxml_node_t *node = NULL;
struct nft_set_elem *elem;
const char *name, *table;
int family;
- tree = mxmlLoadString(NULL, xml, MXML_OPAQUE_CALLBACK);
- if (tree == NULL) {
- errno = EINVAL;
- return -1;
- }
-
- if (strcmp(tree->value.opaque, "set") != 0)
- goto err;
-
name = nft_mxml_str_parse(tree, "name", MXML_DESCEND_FIRST,
NFT_XML_MAND);
if (name == NULL)
- goto err;
+ return -1;
if (s->name)
xfree(s->name);
@@ -441,7 +431,7 @@ static int nft_set_xml_parse(struct nft_set *s, const char *xml)
table = nft_mxml_str_parse(tree, "table", MXML_DESCEND_FIRST,
NFT_XML_MAND);
if (table == NULL)
- goto err;
+ return -1;
if (s->table)
xfree(s->table);
@@ -452,7 +442,7 @@ static int nft_set_xml_parse(struct nft_set *s, const char *xml)
family = nft_mxml_family_parse(tree, "family", MXML_DESCEND_FIRST,
NFT_XML_MAND);
if (family < 0)
- goto err;
+ return -1;
s->family = family;
@@ -460,31 +450,31 @@ static int nft_set_xml_parse(struct nft_set *s, const char *xml)
if (nft_mxml_num_parse(tree, "flags", MXML_DESCEND_FIRST, BASE_DEC,
&s->set_flags, NFT_TYPE_U32, NFT_XML_MAND) != 0)
- goto err;
+ return -1;
s->flags |= (1 << NFT_SET_ATTR_FLAGS);
if (nft_mxml_num_parse(tree, "key_type", MXML_DESCEND_FIRST, BASE_DEC,
&s->key_type, NFT_TYPE_U32, NFT_XML_MAND) != 0)
- goto err;
+ return -1;
s->flags |= (1 << NFT_SET_ATTR_KEY_TYPE);
if (nft_mxml_num_parse(tree, "key_len", MXML_DESCEND_FIRST, BASE_DEC,
&s->key_len, NFT_TYPE_U32, NFT_XML_MAND) != 0)
- goto err;
+ return -1;
s->flags |= (1 << NFT_SET_ATTR_KEY_LEN);
if (nft_mxml_num_parse(tree, "data_type", MXML_DESCEND_FIRST, BASE_DEC,
&s->data_type, NFT_TYPE_U32, NFT_XML_MAND) != 0)
- goto err;
+ return -1;
s->flags |= (1 << NFT_SET_ATTR_DATA_TYPE);
if (nft_mxml_num_parse(tree, "data_len", MXML_DESCEND_FIRST, BASE_DEC,
&s->data_len, NFT_TYPE_U32, NFT_XML_MAND) != 0)
- goto err;
+ return -1;
s->flags |= (1 << NFT_SET_ATTR_DATA_LEN);
@@ -496,19 +486,29 @@ static int nft_set_xml_parse(struct nft_set *s, const char *xml)
elem = nft_set_elem_alloc();
if (elem == NULL)
- goto err;
+ return -1;
if (nft_mxml_set_elem_parse(node, elem) < 0)
- goto err;
+ return -1;
list_add_tail(&elem->head, &s->element_list);
}
- mxmlDelete(tree);
return 0;
-err:
+}
+#endif
+
+static int nft_set_xml_parse(struct nft_set *s, const char *xml)
+{
+#ifdef XML_PARSING
+ int ret;
+ mxml_node_t *tree = nft_mxml_build_tree(xml, "set");
+ if (tree == NULL)
+ return -1;
+
+ ret = nft_mxml_set_parse(tree, s);
mxmlDelete(tree);
- return -1;
+ return ret;
#else
errno = EOPNOTSUPP;
return -1;
diff --git a/src/set_elem.c b/src/set_elem.c
index 9ad482b..ec4a1a6 100644
--- a/src/set_elem.c
+++ b/src/set_elem.c
@@ -418,23 +418,13 @@ static int nft_set_elem_xml_parse(struct nft_set_elem *e, const char *xml)
mxml_node_t *tree;
int ret;
- tree = mxmlLoadString(NULL, xml, MXML_OPAQUE_CALLBACK);
- if (tree == NULL) {
- errno = EINVAL;
+ tree = nft_mxml_build_tree(xml, "set_elem");
+ if (tree == NULL)
return -1;
- }
-
- if (strcmp(tree->value.opaque, "set_elem") != 0) {
- errno = EINVAL;
- goto err;
- }
ret = nft_mxml_set_elem_parse(tree, e);
mxmlDelete(tree);
return ret;
-err:
- mxmlDelete(tree);
- return -1;
#else
errno = EOPNOTSUPP;
return -1;
diff --git a/src/table.c b/src/table.c
index 0b51d15..c8fff1e 100644
--- a/src/table.c
+++ b/src/table.c
@@ -218,24 +218,16 @@ int nft_table_nlmsg_parse(const struct nlmsghdr *nlh, struct nft_table *t)
}
EXPORT_SYMBOL(nft_table_nlmsg_parse);
-static int nft_table_xml_parse(struct nft_table *t, const char *xml)
-{
#ifdef XML_PARSING
- mxml_node_t *tree;
+int nft_mxml_table_parse(mxml_node_t *tree, struct nft_table *t)
+{
const char *name;
int family;
- tree = mxmlLoadString(NULL, xml, MXML_OPAQUE_CALLBACK);
- if (tree == NULL)
- return -1;
-
- if (strcmp(tree->value.opaque, "table") != 0)
- goto err;
-
name = nft_mxml_str_parse(tree, "name", MXML_DESCEND_FIRST,
NFT_XML_MAND);
if (name == NULL)
- goto err;
+ return -1;
if (t->name)
xfree(t->name);
@@ -246,7 +238,7 @@ static int nft_table_xml_parse(struct nft_table *t, const char *xml)
family = nft_mxml_family_parse(tree, "family", MXML_DESCEND_FIRST,
NFT_XML_MAND);
if (family < 0)
- goto err;
+ return -1;
t->family = family;
t->flags |= (1 << NFT_TABLE_ATTR_FAMILY);
@@ -254,15 +246,25 @@ static int nft_table_xml_parse(struct nft_table *t, const char *xml)
if (nft_mxml_num_parse(tree, "flags", MXML_DESCEND, BASE_DEC,
&t->table_flags, NFT_TYPE_U32,
NFT_XML_MAND) != 0)
- goto err;
+ return -1;
t->flags |= (1 << NFT_TABLE_ATTR_FLAGS);
- mxmlDelete(tree);
return 0;
-err:
+}
+#endif
+
+static int nft_table_xml_parse(struct nft_table *t, const char *xml)
+{
+#ifdef XML_PARSING
+ int ret;
+ mxml_node_t *tree = nft_mxml_build_tree(xml, "table");
+ if (tree == NULL)
+ return -1;
+
+ ret = nft_mxml_table_parse(tree, t);
mxmlDelete(tree);
- return -1;
+ return ret;
#else
errno = EOPNOTSUPP;
return -1;