summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am1
-rw-r--r--src/expr/bitwise.c62
-rw-r--r--src/expr/byteorder.c15
-rw-r--r--src/expr/cmp.c28
-rw-r--r--src/expr/counter.c26
-rw-r--r--src/expr/ct.c15
-rw-r--r--src/expr/exthdr.c54
-rw-r--r--src/expr/immediate.c47
-rw-r--r--src/expr/limit.c15
-rw-r--r--src/expr/log.c15
-rw-r--r--src/expr/lookup.c42
-rw-r--r--src/expr/match.c19
-rw-r--r--src/expr/meta.c38
-rw-r--r--src/expr/nat.c47
-rw-r--r--src/expr/payload.c35
-rw-r--r--src/expr/target.c19
-rw-r--r--src/expr_ops.h3
-rw-r--r--src/internal.h2
-rw-r--r--src/mxml.c55
-rw-r--r--src/rule.c23
20 files changed, 130 insertions, 431 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 4649646..6496511 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -10,6 +10,7 @@ libnftables_la_SOURCES = utils.c \
rule.c \
set.c \
set_elem.c \
+ mxml.c \
expr.c \
expr_ops.c \
expr/bitwise.c \
diff --git a/src/expr/bitwise.c b/src/expr/bitwise.c
index 6843086..4b48392 100644
--- a/src/expr/bitwise.c
+++ b/src/expr/bitwise.c
@@ -198,69 +198,42 @@ nft_rule_expr_bitwise_parse(struct nft_rule_expr *e, struct nlattr *attr)
}
static int
-nft_rule_expr_bitwise_xml_parse(struct nft_rule_expr *e, char *xml)
+nft_rule_expr_bitwise_xml_parse(struct nft_rule_expr *e, mxml_node_t *tree)
{
#ifdef XML_PARSING
struct nft_expr_bitwise *bitwise = (struct nft_expr_bitwise *)e->data;
- mxml_node_t *tree = NULL;
mxml_node_t *node = NULL;
mxml_node_t *save = NULL;
uint64_t tmp;
union nft_data_reg data_regtmp;
char *endptr = NULL;
- tree = mxmlLoadString(NULL, xml, MXML_OPAQUE_CALLBACK);
- if (tree == NULL)
- return -1;
-
- if (mxmlElementGetAttr(tree, "type") == NULL) {
- mxmlDelete(tree);
- return -1;
- }
-
- if (strcmp("bitwise", mxmlElementGetAttr(tree, "type")) != 0) {
- mxmlDelete(tree);
- return -1;
- }
-
/* get and set <sreg> */
node = mxmlFindElement(tree, tree, "sreg", NULL, NULL,
MXML_DESCEND_FIRST);
- if (node == NULL) {
- mxmlDelete(tree);
+ if (node == NULL)
return -1;
- }
tmp = strtoull(node->child->value.opaque, &endptr, 10);
- if (tmp > UINT32_MAX || tmp < 0 || *endptr) {
- mxmlDelete(tree);
+ if (tmp > UINT32_MAX || tmp < 0 || *endptr)
return -1;
- }
- if (tmp > NFT_REG_MAX) {
- mxmlDelete(tree);
+ if (tmp > NFT_REG_MAX)
return -1;
- }
bitwise->sreg = (uint32_t)tmp;
e->flags |= (1 << NFT_EXPR_BITWISE_SREG);
/* get and set <dreg> */
node = mxmlFindElement(tree, tree, "dreg", NULL, NULL, MXML_DESCEND);
- if (node == NULL) {
- mxmlDelete(tree);
+ if (node == NULL)
return -1;
- }
tmp = strtoull(node->child->value.opaque, &endptr, 10);
- if (tmp > UINT32_MAX || tmp < 0 || *endptr) {
- mxmlDelete(tree);
+ if (tmp > UINT32_MAX || tmp < 0 || *endptr)
return -1;
- }
- if (tmp > NFT_REG_MAX) {
- mxmlDelete(tree);
+ if (tmp > NFT_REG_MAX)
return -1;
- }
bitwise->dreg = (uint32_t)tmp;
e->flags |= (1 << NFT_EXPR_BITWISE_DREG);
@@ -268,19 +241,15 @@ nft_rule_expr_bitwise_xml_parse(struct nft_rule_expr *e, char *xml)
/* Get and set <mask> */
node = mxmlFindElement(tree, tree, "mask", NULL, NULL,
MXML_DESCEND);
- if (node == NULL) {
- mxmlDelete(tree);
+ if (node == NULL)
return -1;
- }
/* hack for mxmSaveAllocString to print just the current node */
save = node->next;
node->next = NULL;
if (nft_data_reg_xml_parse(&data_regtmp,
- mxmlSaveAllocString(node, MXML_NO_CALLBACK)) < 0) {
- mxmlDelete(tree);
+ mxmlSaveAllocString(node, MXML_NO_CALLBACK)) < 0)
return -1;
- }
node->next = save;
memcpy(&bitwise->mask.val, data_regtmp.val, data_regtmp.len);
@@ -290,19 +259,15 @@ nft_rule_expr_bitwise_xml_parse(struct nft_rule_expr *e, char *xml)
/* Get and set <xor> */
node = mxmlFindElement(tree, tree, "xor", NULL, NULL,
MXML_DESCEND);
- if (node == NULL) {
- mxmlDelete(tree);
+ if (node == NULL)
return -1;
- }
/* hack for mxmSaveAllocString to print just the current node */
save = node->next;
node->next = NULL;
if (nft_data_reg_xml_parse(&data_regtmp,
- mxmlSaveAllocString(node, MXML_NO_CALLBACK)) < 0) {
- mxmlDelete(tree);
+ mxmlSaveAllocString(node, MXML_NO_CALLBACK)) < 0)
return -1;
- }
memcpy(&bitwise->xor.val, data_regtmp.val, data_regtmp.len);
bitwise->xor.len = data_regtmp.len;
@@ -311,12 +276,9 @@ nft_rule_expr_bitwise_xml_parse(struct nft_rule_expr *e, char *xml)
/* Additional validation: mask and xor must use the same number of
* data registers.
*/
- if (bitwise->mask.len != bitwise->xor.len) {
- mxmlDelete(tree);
+ if (bitwise->mask.len != bitwise->xor.len)
return -1;
- }
- mxmlDelete(tree);
return 0;
#else
errno = EOPNOTSUPP;
diff --git a/src/expr/byteorder.c b/src/expr/byteorder.c
index bb47f10..e1a98e9 100644
--- a/src/expr/byteorder.c
+++ b/src/expr/byteorder.c
@@ -202,25 +202,14 @@ static char *expr_byteorder_str[] = {
};
static int
-nft_rule_expr_byteorder_xml_parse(struct nft_rule_expr *e, char *xml)
+nft_rule_expr_byteorder_xml_parse(struct nft_rule_expr *e, mxml_node_t *tree)
{
#ifdef XML_PARSING
struct nft_expr_byteorder *byteorder = (struct nft_expr_byteorder *)e;
- mxml_node_t *tree = NULL;
mxml_node_t *node = NULL;
uint64_t tmp;
char *endptr = NULL;
- tree = mxmlLoadString(NULL, xml, MXML_OPAQUE_CALLBACK);
- if (tree == NULL)
- return -1;
-
- if (mxmlElementGetAttr(tree, "type") == NULL)
- goto err;
-
- if (strcmp("byteorder", mxmlElementGetAttr(tree, "type")) != 0)
- goto err;
-
node = mxmlFindElement(tree, tree, "sreg", NULL, NULL,
MXML_DESCEND_FIRST);
if (node == NULL)
@@ -285,10 +274,8 @@ nft_rule_expr_byteorder_xml_parse(struct nft_rule_expr *e, char *xml)
byteorder->size = tmp;
e->flags |= (1 << NFT_EXPR_BYTEORDER_SIZE);
- mxmlDelete(tree);
return 0;
err:
- mxmlDelete(tree);
errno = EINVAL;
return -1;
#else
diff --git a/src/expr/cmp.c b/src/expr/cmp.c
index f92b3b6..ca8dd82 100644
--- a/src/expr/cmp.c
+++ b/src/expr/cmp.c
@@ -168,45 +168,26 @@ static char *expr_cmp_str[] = {
[NFT_CMP_GTE] = "gte",
};
-static int nft_rule_expr_cmp_xml_parse(struct nft_rule_expr *e, char *xml)
+static int nft_rule_expr_cmp_xml_parse(struct nft_rule_expr *e, mxml_node_t *tree)
{
#ifdef XML_PARSING
struct nft_expr_cmp *cmp = (struct nft_expr_cmp *)e->data;
- mxml_node_t *tree = NULL;
mxml_node_t *node = NULL;
mxml_node_t *save = NULL;
union nft_data_reg data_regtmp;
uint64_t tmp;
char *endptr;
- tree = mxmlLoadString(NULL, xml, MXML_OPAQUE_CALLBACK);
- if (tree == NULL)
- return -1;
-
- if (mxmlElementGetAttr(tree, "type") == NULL) {
- mxmlDelete(tree);
- return -1;
- }
-
- if (strcmp("cmp", mxmlElementGetAttr(tree, "type")) != 0) {
- mxmlDelete(tree);
- return -1;
- }
-
/* Get and set <sreg>. Is not mandatory */
node = mxmlFindElement(tree, tree, "sreg", NULL, NULL,
MXML_DESCEND_FIRST);
if (node != NULL) {
tmp = strtoull(node->child->value.opaque, &endptr, 10);
- if (tmp > UINT8_MAX || tmp < 0 || *endptr) {
- mxmlDelete(tree);
+ if (tmp > UINT8_MAX || tmp < 0 || *endptr)
return -1;
- }
- if (tmp > NFT_REG_MAX) {
- mxmlDelete(tree);
+ if (tmp > NFT_REG_MAX)
return -1;
- }
cmp->sreg = (uint8_t)tmp;
e->flags |= (1 << NFT_EXPR_CMP_SREG);
@@ -229,7 +210,6 @@ static int nft_rule_expr_cmp_xml_parse(struct nft_rule_expr *e, char *xml)
cmp->op = NFT_CMP_GTE;
} else {
/* If <op> is present, a valid value is mandatory */
- mxmlDelete(tree);
return -1;
}
e->flags |= (1 << NFT_EXPR_CMP_OP);
@@ -245,7 +225,6 @@ static int nft_rule_expr_cmp_xml_parse(struct nft_rule_expr *e, char *xml)
if (nft_data_reg_xml_parse(&data_regtmp,
mxmlSaveAllocString(node, MXML_NO_CALLBACK)) < 0) {
- mxmlDelete(tree);
return -1;
}
@@ -256,7 +235,6 @@ static int nft_rule_expr_cmp_xml_parse(struct nft_rule_expr *e, char *xml)
e->flags |= (1 << NFT_EXPR_CMP_DATA);
}
- mxmlDelete(tree);
return 0;
#else
errno = EOPNOTSUPP;
diff --git a/src/expr/counter.c b/src/expr/counter.c
index 62bd143..665fa14 100644
--- a/src/expr/counter.c
+++ b/src/expr/counter.c
@@ -128,38 +128,21 @@ nft_rule_expr_counter_parse(struct nft_rule_expr *e, struct nlattr *attr)
}
static int
-nft_rule_expr_counter_xml_parse(struct nft_rule_expr *e, char *xml)
+nft_rule_expr_counter_xml_parse(struct nft_rule_expr *e, mxml_node_t *tree)
{
#ifdef XML_PARSING
struct nft_expr_counter *ctr = (struct nft_expr_counter *)e->data;
- mxml_node_t *tree = NULL;
mxml_node_t *node = NULL;
char *endptr;
uint64_t tmp;
- tree = mxmlLoadString(NULL, xml, MXML_OPAQUE_CALLBACK);
- if (tree == NULL)
- return -1;
-
- if (mxmlElementGetAttr(tree, "type") == NULL) {
- mxmlDelete(tree);
- return -1;
- }
-
- if (strcmp("counter", mxmlElementGetAttr(tree, "type")) != 0) {
- mxmlDelete(tree);
- return -1;
- }
-
/* get and set <pkts>. Is not mandatory*/
node = mxmlFindElement(tree, tree, "pkts", NULL, NULL,
MXML_DESCEND_FIRST);
if (node != NULL) {
tmp = strtoull(node->child->value.opaque, &endptr, 10);
- if (tmp == UINT64_MAX || tmp < 0 || *endptr ) {
- mxmlDelete(tree);
+ if (tmp == UINT64_MAX || tmp < 0 || *endptr )
return -1;
- }
ctr->pkts = tmp;
e->flags |= (1 << NFT_EXPR_CTR_PACKETS);
@@ -170,16 +153,13 @@ nft_rule_expr_counter_xml_parse(struct nft_rule_expr *e, char *xml)
MXML_DESCEND);
if (node != NULL) {
tmp = strtoull(node->child->value.opaque, &endptr, 10);
- if (tmp == UINT64_MAX || tmp < 0 || *endptr) {
- mxmlDelete(tree);
+ if (tmp == UINT64_MAX || tmp < 0 || *endptr)
return -1;
- }
ctr->bytes = tmp;
e->flags |= (1 << NFT_EXPR_CTR_BYTES);
}
- mxmlDelete(tree);
return 0;
#else
errno = EOPNOTSUPP;
diff --git a/src/expr/ct.c b/src/expr/ct.c
index 8014314..13da036 100644
--- a/src/expr/ct.c
+++ b/src/expr/ct.c
@@ -192,26 +192,15 @@ static inline int str2ctkey(const char *ctkey)
return -1;
}
-static int nft_rule_expr_ct_xml_parse(struct nft_rule_expr *e, char *xml)
+static int nft_rule_expr_ct_xml_parse(struct nft_rule_expr *e, mxml_node_t *tree)
{
#ifdef XML_PARSING
struct nft_expr_ct *ct = (struct nft_expr_ct *)e->data;
- mxml_node_t *tree = NULL;
mxml_node_t *node = NULL;
uint64_t tmp;
char *endptr;
int key;
- tree = mxmlLoadString(NULL, xml, MXML_OPAQUE_CALLBACK);
- if (tree == NULL)
- return -1;
-
- if (mxmlElementGetAttr(tree, "type") == NULL)
- goto err;
-
- if (strcmp("ct", mxmlElementGetAttr(tree, "type")) != 0)
- goto err;
-
node = mxmlFindElement(tree, tree, "dreg", NULL, NULL,
MXML_DESCEND_FIRST);
if (node == NULL)
@@ -252,10 +241,8 @@ static int nft_rule_expr_ct_xml_parse(struct nft_rule_expr *e, char *xml)
ct->dir = tmp;
e->flags |= (1 << NFT_EXPR_CT_DIR);
- mxmlDelete(tree);
return 0;
err:
- mxmlDelete(tree);
errno = EINVAL;
return -1;
#else
diff --git a/src/expr/exthdr.c b/src/expr/exthdr.c
index b4b9c13..e7f4fab 100644
--- a/src/expr/exthdr.c
+++ b/src/expr/exthdr.c
@@ -212,50 +212,29 @@ static inline int str2exthdr_type(char *str)
static int
-nft_rule_expr_exthdr_xml_parse(struct nft_rule_expr *e, char *xml)
+nft_rule_expr_exthdr_xml_parse(struct nft_rule_expr *e, mxml_node_t *tree)
{
#ifdef XML_PARSING
struct nft_expr_exthdr *exthdr = (struct nft_expr_exthdr *)e->data;
- mxml_node_t *tree = NULL;
mxml_node_t *node = NULL;
uint64_t tmp;
char *endptr;
int type;
- tree = mxmlLoadString(NULL, xml, MXML_OPAQUE_CALLBACK);
- if (tree == NULL)
- return -1;
-
- if (mxmlElementGetAttr(tree, "type") == NULL) {
- mxmlDelete(tree);
- return -1;
- }
-
- if (strcmp("exthdr", mxmlElementGetAttr(tree, "type")) != 0) {
- mxmlDelete(tree);
- return -1;
- }
-
/* All nodes are mandatory */
/* Get and set <dreg> */
node = mxmlFindElement(tree, tree, "dreg", NULL, NULL,
MXML_DESCEND_FIRST);
- if (node == NULL) {
- mxmlDelete(tree);
+ if (node == NULL)
return -1;
- }
tmp = strtoull(node->child->value.opaque, &endptr, 10);
- if (tmp > UINT32_MAX || tmp < 0 || *endptr) {
- mxmlDelete(tree);
+ if (tmp > UINT32_MAX || tmp < 0 || *endptr)
return -1;
- }
- if (tmp > NFT_REG_MAX) {
- mxmlDelete(tree);
+ if (tmp > NFT_REG_MAX)
return -1;
- }
exthdr->dreg = tmp;
e->flags |= (1 << NFT_EXPR_EXTHDR_DREG);
@@ -263,16 +242,12 @@ nft_rule_expr_exthdr_xml_parse(struct nft_rule_expr *e, char *xml)
/* Get and set <exthdr_type> */
node = mxmlFindElement(tree, tree, "exthdr_type", NULL, NULL,
MXML_DESCEND);
- if (node == NULL) {
- mxmlDelete(tree);
+ if (node == NULL)
return -1;
- }
type = str2exthdr_type(node->child->value.opaque);
- if (type < 0) {
- mxmlDelete(tree);
+ if (type < 0)
return -1;
- }
exthdr->type = type;
e->flags |= (1 << NFT_EXPR_EXTHDR_TYPE);
@@ -280,37 +255,28 @@ nft_rule_expr_exthdr_xml_parse(struct nft_rule_expr *e, char *xml)
/* Get and set <offset> */
node = mxmlFindElement(tree, tree, "offset", NULL, NULL,
MXML_DESCEND);
- if (node == NULL) {
- mxmlDelete(tree);
+ if (node == NULL)
return -1;
- }
tmp = strtoull(node->child->value.opaque, &endptr, 10);
- if (tmp > UINT_MAX || tmp < 0 || *endptr) {
- mxmlDelete(tree);
+ if (tmp > UINT_MAX || tmp < 0 || *endptr)
return -1;
- }
exthdr->offset = tmp;
e->flags |= (1 << NFT_EXPR_EXTHDR_OFFSET);
/* Get and set <len> */
node = mxmlFindElement(tree, tree, "len", NULL, NULL, MXML_DESCEND);
- if (node == NULL) {
- mxmlDelete(tree);
+ if (node == NULL)
return -1;
- }
tmp = strtoull(node->child->value.opaque, &endptr, 10);
- if (tmp > UINT_MAX || tmp < 0 || *endptr) {
- mxmlDelete(tree);
+ if (tmp > UINT_MAX || tmp < 0 || *endptr)
return -1;
- }
exthdr->len = tmp;
e->flags |= (1 << NFT_EXPR_EXTHDR_LEN);
- mxmlDelete(tree);
return 0;
#else
errno = EOPNOTSUPP;
diff --git a/src/expr/immediate.c b/src/expr/immediate.c
index 1937d82..b196ed2 100644
--- a/src/expr/immediate.c
+++ b/src/expr/immediate.c
@@ -196,50 +196,28 @@ nft_rule_expr_immediate_parse(struct nft_rule_expr *e, struct nlattr *attr)
}
static int
-nft_rule_expr_immediate_xml_parse(struct nft_rule_expr *e, char *xml)
+nft_rule_expr_immediate_xml_parse(struct nft_rule_expr *e, mxml_node_t *tree)
{
#ifdef XML_PARSING
struct nft_expr_immediate *imm = (struct nft_expr_immediate *)e->data;
- mxml_node_t *tree = NULL;
mxml_node_t *node = NULL;
mxml_node_t *save = NULL;
union nft_data_reg data_regtmp;
uint64_t tmp;
char *endptr;
- /* load the tree */
- tree = mxmlLoadString(NULL, xml, MXML_OPAQUE_CALLBACK);
- if (tree == NULL)
- return -1;
-
- if (mxmlElementGetAttr(tree, "type") == NULL) {
- mxmlDelete(tree);
- return -1;
- }
-
- if (strcmp("immediate", mxmlElementGetAttr(tree, "type")) != 0) {
- mxmlDelete(tree);
- return -1;
- }
-
/* Get and set <dreg>. Is mandatory */
node = mxmlFindElement(tree, tree, "dreg", NULL, NULL,
MXML_DESCEND_FIRST);
- if (node == NULL) {
- mxmlDelete(tree);
+ if (node == NULL)
return -1;
- }
tmp = strtoull(node->child->value.opaque, &endptr, 10);
- if (tmp > UINT32_MAX || tmp < 0 || *endptr) {
- mxmlDelete(tree);
+ if (tmp > UINT32_MAX || tmp < 0 || *endptr)
return -1;
- }
- if (tmp > NFT_REG_MAX) {
- mxmlDelete(tree);
+ if (tmp > NFT_REG_MAX)
return -1;
- }
imm->dreg = (uint32_t)tmp;
e->flags |= (1 << NFT_EXPR_IMM_DREG);
@@ -247,34 +225,26 @@ nft_rule_expr_immediate_xml_parse(struct nft_rule_expr *e, char *xml)
/* Get and set <immdata>. Is mandatory */
node = mxmlFindElement(tree, tree, "immdata", NULL, NULL,
MXML_DESCEND);
- if (node == NULL) {
- mxmlDelete(tree);
+ if (node == NULL)
return -1;
- }
/* hack for mxmSaveAllocString to print just the current node */
save = node->next;
node->next = NULL;
if (nft_data_reg_xml_parse(&data_regtmp,
- mxmlSaveAllocString(node, MXML_NO_CALLBACK)) < 0) {
- mxmlDelete(tree);
+ mxmlSaveAllocString(node, MXML_NO_CALLBACK)) < 0)
return -1;
- }
node->next = save;
/* data_reg type switch */
node = mxmlFindElement(tree, tree, "data_reg", NULL, NULL,
MXML_DESCEND);
- if (node == NULL) {
- mxmlDelete(tree);
+ if (node == NULL)
return -1;
- }
- if (mxmlElementGetAttr(node, "type") == NULL) {
- mxmlDelete(tree);
+ if (mxmlElementGetAttr(node, "type") == NULL)
return -1;
- }
if (strcmp(mxmlElementGetAttr(node, "type"), "value") == 0) {
memcpy(&imm->data.val, data_regtmp.val, data_regtmp.len);
@@ -291,7 +261,6 @@ nft_rule_expr_immediate_xml_parse(struct nft_rule_expr *e, char *xml)
e->flags |= (1 << NFT_EXPR_IMM_CHAIN);
}
- mxmlDelete(tree);
return 0;
#else
errno = EOPNOTSUPP;
diff --git a/src/expr/limit.c b/src/expr/limit.c
index 1e843ce..fdd76e3 100644
--- a/src/expr/limit.c
+++ b/src/expr/limit.c
@@ -126,25 +126,14 @@ nft_rule_expr_limit_parse(struct nft_rule_expr *e, struct nlattr *attr)
return 0;
}
-static int nft_rule_expr_limit_xml_parse(struct nft_rule_expr *e, char *xml)
+static int nft_rule_expr_limit_xml_parse(struct nft_rule_expr *e, mxml_node_t *tree)
{
#ifdef XML_PARSING
struct nft_expr_limit *limit = (struct nft_expr_limit *)e->data;
- mxml_node_t *tree = NULL;
mxml_node_t *node = NULL;
uint64_t tmp;
char *endptr;
- tree = mxmlLoadString(NULL, xml, MXML_OPAQUE_CALLBACK);
- if (tree == NULL)
- return -1;
-
- if (mxmlElementGetAttr(tree, "type") == NULL)
- goto err;
-
- if (strcmp("limit", mxmlElementGetAttr(tree, "type")) != 0)
- goto err;
-
node = mxmlFindElement(tree, tree, "rate", NULL, NULL,
MXML_DESCEND_FIRST);
if (node == NULL)
@@ -169,11 +158,9 @@ static int nft_rule_expr_limit_xml_parse(struct nft_rule_expr *e, char *xml)
limit->depth = tmp;
e->flags |= (1 << NFT_EXPR_LIMIT_DEPTH);
- mxmlDelete(tree);
return 0;
err:
errno = EINVAL;
- mxmlDelete(tree);
return -1;
#else
errno = EOPNOTSUPP;
diff --git a/src/expr/log.c b/src/expr/log.c
index 8dc5201..b2b3ca1 100644
--- a/src/expr/log.c
+++ b/src/expr/log.c
@@ -170,25 +170,14 @@ nft_rule_expr_log_parse(struct nft_rule_expr *e, struct nlattr *attr)
return 0;
}
-static int nft_rule_expr_log_xml_parse(struct nft_rule_expr *e, char *xml)
+static int nft_rule_expr_log_xml_parse(struct nft_rule_expr *e, mxml_node_t *tree)
{
#ifdef XML_PARSING
struct nft_expr_log *log = (struct nft_expr_log *)e->data;
- mxml_node_t *tree = NULL;
mxml_node_t *node = NULL;
uint64_t tmp;
char *endptr;
- tree = mxmlLoadString(NULL, xml, MXML_OPAQUE_CALLBACK);
- if (tree == NULL)
- return -1;
-
- if (mxmlElementGetAttr(tree, "type") == NULL)
- goto err;
-
- if (strcmp("log", mxmlElementGetAttr(tree, "type")) != 0)
- goto err;
-
node = mxmlFindElement(tree, tree, "prefix", NULL, NULL,
MXML_DESCEND_FIRST);
if (node == NULL)
@@ -232,11 +221,9 @@ static int nft_rule_expr_log_xml_parse(struct nft_rule_expr *e, char *xml)
log->qthreshold = tmp;
e->flags |= (1 << NFT_EXPR_LOG_QTHRESHOLD);
- mxmlDelete(tree);
return 0;
err:
errno = EINVAL;
- mxmlDelete(tree);
return -1;
#else
errno = EOPNOTSUPP;
diff --git a/src/expr/lookup.c b/src/expr/lookup.c
index 8591d4e..ca10cab 100644
--- a/src/expr/lookup.c
+++ b/src/expr/lookup.c
@@ -153,36 +153,19 @@ nft_rule_expr_lookup_parse(struct nft_rule_expr *e, struct nlattr *attr)
}
static int
-nft_rule_expr_lookup_xml_parse(struct nft_rule_expr *e, char *xml)
+nft_rule_expr_lookup_xml_parse(struct nft_rule_expr *e, mxml_node_t *tree)
{
#ifdef XML_PARSING
struct nft_expr_lookup *lookup = (struct nft_expr_lookup *)e->data;
- mxml_node_t *tree = NULL;
mxml_node_t *node = NULL;
uint64_t tmp;
char *endptr;
- tree = mxmlLoadString(NULL, xml, MXML_OPAQUE_CALLBACK);
- if (tree == NULL)
- return -1;
-
- if (mxmlElementGetAttr(tree, "type") == NULL) {
- mxmlDelete(tree);
- return -1;
- }
-
- if (strcmp("lookup", mxmlElementGetAttr(tree, "type")) != 0) {
- mxmlDelete(tree);
- return -1;
- }
-
/* get and set <set>. Is mandatory */
node = mxmlFindElement(tree, tree, "set", NULL, NULL,
MXML_DESCEND_FIRST);
- if (node == NULL) {
- mxmlDelete(tree);
+ if (node == NULL)
return -1;
- }
memcpy(lookup->set_name, node->child->value.opaque, IFNAMSIZ);
lookup->set_name[IFNAMSIZ-1] = '\0';
@@ -191,23 +174,17 @@ nft_rule_expr_lookup_xml_parse(struct nft_rule_expr *e, char *xml)
/* get and set <sreg>. Is mandatory */
node = mxmlFindElement(tree, tree, "sreg", NULL, NULL,
MXML_DESCEND);
- if (node == NULL) {
- mxmlDelete(tree);
+ if (node == NULL)
return -1;
- }
errno = 0;
tmp = strtoull(node->child->value.opaque, &endptr, 10);
- if (tmp > UINT32_MAX || tmp < 0 || *endptr) {
- mxmlDelete(tree);
+ if (tmp > UINT32_MAX || tmp < 0 || *endptr)
return -1;
- }
- if (tmp > NFT_REG_MAX) {
- mxmlDelete(tree);
+ if (tmp > NFT_REG_MAX)
return -1;
- }
lookup->sreg = (uint32_t)tmp;
e->flags |= (1 << NFT_EXPR_LOOKUP_SREG);
@@ -217,20 +194,15 @@ nft_rule_expr_lookup_xml_parse(struct nft_rule_expr *e, char *xml)
MXML_DESCEND);
if (node != NULL) {
tmp = strtoull(node->child->value.opaque, &endptr, 10);
- if (tmp > UINT32_MAX || tmp < 0 || *endptr) {
- mxmlDelete(tree);
+ if (tmp > UINT32_MAX || tmp < 0 || *endptr)
return -1;
- }
- if (tmp > NFT_REG_MAX) {
- mxmlDelete(tree);
+ if (tmp > NFT_REG_MAX)
return -1;
- }
lookup->dreg = (uint32_t)tmp;
e->flags |= (1 << NFT_EXPR_LOOKUP_DREG);
}
- mxmlDelete(tree);
return 0;
#else
errno = EOPNOTSUPP;
diff --git a/src/expr/match.c b/src/expr/match.c
index 7d0f078..3302bb4 100644
--- a/src/expr/match.c
+++ b/src/expr/match.c
@@ -184,28 +184,12 @@ static int nft_rule_expr_match_parse(struct nft_rule_expr *e, struct nlattr *att
return 0;
}
-static int nft_rule_expr_match_xml_parse(struct nft_rule_expr *e, char *xml)
+static int nft_rule_expr_match_xml_parse(struct nft_rule_expr *e, mxml_node_t *tree)
{
#ifdef XML_PARSING
struct nft_expr_match *mt = (struct nft_expr_match *)e->data;
- mxml_node_t *tree = NULL;
mxml_node_t *node = NULL;
- /* load the tree */
- tree = mxmlLoadString(NULL, xml, MXML_OPAQUE_CALLBACK);
- if (tree == NULL)
- return -1;
-
- if (mxmlElementGetAttr(tree, "type") == NULL) {
- mxmlDelete(tree);
- return -1;
- }
-
- if (strcmp("match", mxmlElementGetAttr(tree, "type")) != 0) {
- mxmlDelete(tree);
- return -1;
- }
-
/* get and set <name>. Not mandatory */
node = mxmlFindElement(tree, tree, "name", NULL, NULL,
MXML_DESCEND_FIRST);
@@ -218,7 +202,6 @@ static int nft_rule_expr_match_xml_parse(struct nft_rule_expr *e, char *xml)
/* mt->info is ignored until other solution is reached */
- mxmlDelete(tree);
return 0;
#else
errno = EOPNOTSUPP;
diff --git a/src/expr/meta.c b/src/expr/meta.c
index 1a609cf..46a863a 100644
--- a/src/expr/meta.c
+++ b/src/expr/meta.c
@@ -169,69 +169,43 @@ static inline int str2meta_key(const char *str)
return -1;
}
-static int nft_rule_expr_meta_xml_parse(struct nft_rule_expr *e, char *xml)
+static int nft_rule_expr_meta_xml_parse(struct nft_rule_expr *e, mxml_node_t *tree)
{
#ifdef XML_PARSING
struct nft_expr_meta *meta = (struct nft_expr_meta *)e->data;
- mxml_node_t *tree = NULL;
mxml_node_t *node = NULL;
uint64_t tmp;
char *endptr;
int key;
- tree = mxmlLoadString(NULL, xml, MXML_OPAQUE_CALLBACK);
- if (tree == NULL)
- return -1;
-
- if (mxmlElementGetAttr(tree, "type") == NULL) {
- mxmlDelete(tree);
- return -1;
- }
-
- if (strcmp("meta", mxmlElementGetAttr(tree, "type")) != 0) {
- mxmlDelete(tree);
- return -1;
- }
-
/* Get and set <dreg>. Is mandatory */
node = mxmlFindElement(tree, tree, "dreg", NULL, NULL,
MXML_DESCEND_FIRST);
- if (node == NULL) {
- mxmlDelete(tree);
+ if (node == NULL)
return -1;
- }
tmp = strtoull(node->child->value.opaque, &endptr, 10);
- if (tmp > UINT8_MAX || tmp < 0 || *endptr) {
- mxmlDelete(tree);
+ if (tmp > UINT8_MAX || tmp < 0 || *endptr)
return -1;
- }
- if (tmp > NFT_REG_MAX) {
- mxmlDelete(tree);
+ if (tmp > NFT_REG_MAX)
return -1;
- }
meta->dreg = (uint8_t)tmp;
e->flags |= (1 << NFT_EXPR_META_DREG);
/* Get and set <key>. Is mandatory */
node = mxmlFindElement(tree, tree, "key", NULL, NULL, MXML_DESCEND);
- if (node == NULL) {
- mxmlDelete(tree);
+ if (node == NULL)
return -1;
- }
key = str2meta_key(node->child->value.opaque);
- if (key < 0) {
- mxmlDelete(tree);
+ if (key < 0)
return -1;
- }
meta->key = key;
e->flags |= (1 << NFT_EXPR_META_KEY);
- mxmlDelete(tree);
return 0;
#else
errno = EOPNOTSUPP;
diff --git a/src/expr/nat.c b/src/expr/nat.c
index b753069..05d2e74 100644
--- a/src/expr/nat.c
+++ b/src/expr/nat.c
@@ -205,44 +205,26 @@ nft_rule_expr_nat_build(struct nlmsghdr *nlh, struct nft_rule_expr *e)
}
-static int nft_rule_expr_nat_xml_parse(struct nft_rule_expr *e, char *xml)
+static int nft_rule_expr_nat_xml_parse(struct nft_rule_expr *e, mxml_node_t *tree)
{
#ifdef XML_PARSING
struct nft_expr_nat *nat = (struct nft_expr_nat *)e->data;
- mxml_node_t *tree = NULL;
mxml_node_t *node = NULL;
uint64_t tmp;
char *endptr;
int family;
- tree = mxmlLoadString(NULL, xml, MXML_OPAQUE_CALLBACK);
- if (tree == NULL)
- return -1;
-
- if (mxmlElementGetAttr(tree, "type") == NULL) {
- mxmlDelete(tree);
- return -1;
- }
-
- if (strcmp("nat", mxmlElementGetAttr(tree, "type")) != 0) {
- mxmlDelete(tree);
- return -1;
- }
-
/* Get and set <nat_type>. Mandatory */
node = mxmlFindElement(tree, tree, "nat_type", NULL, NULL,
MXML_DESCEND_FIRST);
- if (node == NULL) {
- mxmlDelete(tree);
+ if (node == NULL)
return -1;
- }
if (strcmp(node->child->value.opaque, "snat") == 0) {
nat->type = NFT_NAT_SNAT;
} else if (strcmp(node->child->value.opaque, "dnat") == 0) {
nat->type = NFT_NAT_DNAT;
} else {
- mxmlDelete(tree);
return -1;
}
e->flags |= (1 << NFT_EXPR_NAT_TYPE);
@@ -250,16 +232,12 @@ static int nft_rule_expr_nat_xml_parse(struct nft_rule_expr *e, char *xml)
/* Get and set <family>. Mandatory */
node = mxmlFindElement(tree, tree, "family", NULL, NULL,
MXML_DESCEND);
- if (node == NULL) {
- mxmlDelete(tree);
+ if (node == NULL)
return -1;
- }
family = nft_str2family(node->child->value.opaque);
- if (family < 0) {
- mxmlDelete(tree);
+ if (family < 0)
return -1;
- }
nat->family = family;
e->flags |= (1 << NFT_EXPR_NAT_FAMILY);
@@ -269,10 +247,8 @@ static int nft_rule_expr_nat_xml_parse(struct nft_rule_expr *e, char *xml)
MXML_DESCEND);
if (node != NULL) {
tmp = strtoull(node->child->value.opaque, &endptr, 10);
- if (tmp > UINT32_MAX || tmp < 0 || *endptr) {
- mxmlDelete(tree);
+ if (tmp > UINT32_MAX || tmp < 0 || *endptr)
return -1;
- }
nat->sreg_addr_min = (uint32_t)tmp;
e->flags |= (1 << NFT_EXPR_NAT_REG_ADDR_MIN);
@@ -283,10 +259,8 @@ static int nft_rule_expr_nat_xml_parse(struct nft_rule_expr *e, char *xml)
MXML_DESCEND);
if (node != NULL) {
tmp = strtoull(node->child->value.opaque, &endptr, 10);
- if (tmp > UINT32_MAX || tmp < 0 || *endptr) {
- mxmlDelete(tree);
+ if (tmp > UINT32_MAX || tmp < 0 || *endptr)
return -1;
- }
nat->sreg_addr_max = (uint32_t)tmp;
e->flags |= (1 << NFT_EXPR_NAT_REG_ADDR_MAX);
@@ -297,10 +271,8 @@ static int nft_rule_expr_nat_xml_parse(struct nft_rule_expr *e, char *xml)
MXML_DESCEND);
if (node != NULL) {
tmp = strtoull(node->child->value.opaque, &endptr, 10);
- if (tmp > UINT32_MAX || tmp < 0 || *endptr) {
- mxmlDelete(tree);
+ if (tmp > UINT32_MAX || tmp < 0 || *endptr)
return -1;
- }
nat->sreg_proto_min = (uint32_t)tmp;
e->flags |= (1 << NFT_EXPR_NAT_REG_PROTO_MIN);
@@ -311,15 +283,12 @@ static int nft_rule_expr_nat_xml_parse(struct nft_rule_expr *e, char *xml)
MXML_DESCEND);
if (node != NULL) {
tmp = strtoull(node->child->value.opaque, &endptr, 10);
- if (tmp > UINT32_MAX || tmp < 0 || *endptr) {
- mxmlDelete(tree);
+ if (tmp > UINT32_MAX || tmp < 0 || *endptr)
return -1;
- }
nat->sreg_proto_max = (uint32_t)tmp;
e->flags |= (1 << NFT_EXPR_NAT_REG_PROTO_MAX);
}
- mxmlDelete(tree);
return 0;
#else
errno = EOPNOTSUPP;
diff --git a/src/expr/payload.c b/src/expr/payload.c
index 2111c47..8866755 100644
--- a/src/expr/payload.c
+++ b/src/expr/payload.c
@@ -197,43 +197,24 @@ nft_rule_expr_payload_snprintf_json(char *buf, size_t len, uint32_t flags,
}
static int
-nft_rule_expr_payload_xml_parse(struct nft_rule_expr *e, char *xml)
+nft_rule_expr_payload_xml_parse(struct nft_rule_expr *e, mxml_node_t *tree)
{
#ifdef XML_PARSING
struct nft_expr_payload *payload = (struct nft_expr_payload *)e->data;
- mxml_node_t *tree = NULL;
mxml_node_t *node = NULL;
uint64_t tmp;
char *endptr;
- tree = mxmlLoadString(NULL, xml, MXML_OPAQUE_CALLBACK);
- if (tree == NULL)
- return -1;
-
- if (mxmlElementGetAttr(tree, "type") == NULL) {
- mxmlDelete(tree);
- return -1;
- }
-
- if (strcmp("payload", mxmlElementGetAttr(tree, "type")) != 0) {
- mxmlDelete(tree);
- return -1;
- }
-
/* Get and set <dreg>. Not mandatory */
node = mxmlFindElement(tree, tree, "dreg", NULL, NULL,
MXML_DESCEND_FIRST);
if (node != NULL) {
tmp = strtoull(node->child->value.opaque, &endptr, 10);
- if (tmp > UINT32_MAX || tmp < 0 || *endptr) {
- mxmlDelete(tree);
+ if (tmp > UINT32_MAX || tmp < 0 || *endptr)
return -1;
- }
- if (tmp > NFT_REG_MAX) {
- mxmlDelete(tree);
+ if (tmp > NFT_REG_MAX)
return -1;
- }
payload->dreg = (uint32_t)tmp;
e->flags |= (1 << NFT_EXPR_PAYLOAD_DREG);
@@ -251,7 +232,6 @@ nft_rule_expr_payload_xml_parse(struct nft_rule_expr *e, char *xml)
"transport") == 0) {
payload->base = NFT_PAYLOAD_TRANSPORT_HEADER;
} else {
- mxmlDelete(tree);
return -1;
}
@@ -263,10 +243,8 @@ nft_rule_expr_payload_xml_parse(struct nft_rule_expr *e, char *xml)
MXML_DESCEND);
if (node != NULL) {
tmp = strtoull(node->child->value.opaque, &endptr, 10);
- if (tmp > UINT_MAX || tmp < 0 || *endptr) {
- mxmlDelete(tree);
+ if (tmp > UINT_MAX || tmp < 0 || *endptr)
return -1;
- }
payload->offset = (unsigned int)tmp;
e->flags |= (1 << NFT_EXPR_PAYLOAD_OFFSET);
@@ -276,15 +254,12 @@ nft_rule_expr_payload_xml_parse(struct nft_rule_expr *e, char *xml)
node = mxmlFindElement(tree, tree, "len", NULL, NULL, MXML_DESCEND);
if (node != NULL) {
tmp = strtoull(node->child->value.opaque, &endptr, 10);
- if (tmp > UINT_MAX || tmp < 0 || *endptr) {
- mxmlDelete(tree);
+ if (tmp > UINT_MAX || tmp < 0 || *endptr)
return -1;
- }
payload->len = (unsigned int)tmp;
e->flags |= (1 << NFT_EXPR_PAYLOAD_LEN);
}
- mxmlDelete(tree);
return 0;
#else
errno = EOPNOTSUPP;
diff --git a/src/expr/target.c b/src/expr/target.c
index 0ad39d5..ba7ee1a 100644
--- a/src/expr/target.c
+++ b/src/expr/target.c
@@ -185,28 +185,12 @@ static int nft_rule_expr_target_parse(struct nft_rule_expr *e, struct nlattr *at
}
static int
-nft_rule_expr_target_xml_parse(struct nft_rule_expr *e, char *xml)
+nft_rule_expr_target_xml_parse(struct nft_rule_expr *e, mxml_node_t *tree)
{
#ifdef XML_PARSING
struct nft_expr_target *tg = (struct nft_expr_target *)e->data;
- mxml_node_t *tree = NULL;
mxml_node_t *node = NULL;
- /* load the tree */
- tree = mxmlLoadString(NULL, xml, MXML_OPAQUE_CALLBACK);
- if (tree == NULL)
- return -1;
-
- if (mxmlElementGetAttr(tree, "type") == NULL) {
- mxmlDelete(tree);
- return -1;
- }
-
- if (strcmp("target", mxmlElementGetAttr(tree, "type")) != 0) {
- mxmlDelete(tree);
- return -1;
- }
-
/* Get and set <name>. Optional */
node = mxmlFindElement(tree, tree, "name", NULL, NULL,
MXML_DESCEND_FIRST);
@@ -219,7 +203,6 @@ nft_rule_expr_target_xml_parse(struct nft_rule_expr *e, char *xml)
/* tg->info is ignored until other solution is reached */
- mxmlDelete(tree);
return 0;
#else
errno = EOPNOTSUPP;
diff --git a/src/expr_ops.h b/src/expr_ops.h
index 282225d..8dc4a09 100644
--- a/src/expr_ops.h
+++ b/src/expr_ops.h
@@ -1,6 +1,7 @@
#ifndef _EXPR_OPS_H_
#define _EXPR_OPS_H_
+#include "internal.h"
#include <stdlib.h>
#include <stdint.h>
@@ -17,7 +18,7 @@ struct expr_ops {
int (*parse)(struct nft_rule_expr *e, struct nlattr *attr);
void (*build)(struct nlmsghdr *nlh, struct nft_rule_expr *e);
int (*snprintf)(char *buf, size_t len, uint32_t type, uint32_t flags, struct nft_rule_expr *e);
- int (*xml_parse)(struct nft_rule_expr *e, char *xml);
+ int (*xml_parse)(struct nft_rule_expr *e, mxml_node_t *tree);
};
struct expr_ops *nft_expr_ops_lookup(const char *name);
diff --git a/src/internal.h b/src/internal.h
index 55505be..ee09661 100644
--- a/src/internal.h
+++ b/src/internal.h
@@ -15,6 +15,8 @@
#ifdef XML_PARSING
#include <mxml.h>
+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);
#endif
#define NFT_TABLE_XML_VERSION 0
diff --git a/src/mxml.c b/src/mxml.c
new file mode 100644
index 0000000..76fb05f
--- /dev/null
+++ b/src/mxml.c
@@ -0,0 +1,55 @@
+/*
+ * (C) 2012-2013 by Pablo Neira Ayuso <pablo@netfilter.org>
+ * (C) 2013 by Arturo Borrero Gonzalez <arturo.borrero.glez@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This code has been sponsored by Sophos Astaro <http://www.sophos.com>
+ */
+#include "internal.h"
+#include "expr_ops.h"
+
+#include <linux/netfilter/nf_tables.h>
+#include <libnftables/rule.h>
+#include <libnftables/expr.h>
+
+struct nft_rule_expr *nft_mxml_expr_parse(mxml_node_t *node)
+{
+ mxml_node_t *tree;
+ struct nft_rule_expr *e;
+ const char *expr_name;
+ char *xml_text;
+ int ret;
+
+ expr_name = mxmlElementGetAttr(node, "type");
+ if (expr_name == NULL)
+ goto err;
+
+ e = nft_rule_expr_alloc(expr_name);
+ if (e == NULL)
+ goto err;
+
+ xml_text = mxmlSaveAllocString(node, MXML_NO_CALLBACK);
+ if (xml_text == NULL)
+ goto err_expr;
+
+ tree = mxmlLoadString(NULL, xml_text, MXML_OPAQUE_CALLBACK);
+ free(xml_text);
+
+ if (tree == NULL)
+ goto err_expr;
+
+ ret = e->ops->xml_parse(e, tree);
+ mxmlDelete(tree);
+
+ return ret < 0 ? NULL : e;
+err_expr:
+ nft_rule_expr_free(e);
+err:
+ mxmlDelete(tree);
+ errno = EINVAL;
+ return NULL;
+}
diff --git a/src/rule.c b/src/rule.c
index 5e9b16d..64c34bd 100644
--- a/src/rule.c
+++ b/src/rule.c
@@ -483,7 +483,6 @@ static int nft_rule_xml_parse(struct nft_rule *r, char *xml)
mxml_node_t *node = NULL;
mxml_node_t *save = NULL;
struct nft_rule_expr *e;
- struct expr_ops *ops;
char *endptr = NULL;
uint64_t tmp;
int family;
@@ -608,30 +607,12 @@ static int nft_rule_xml_parse(struct nft_rule *r, char *xml)
node = mxmlFindElement(node, tree, "expr", "type",
NULL, MXML_DESCEND)) {
- if (mxmlElementGetAttr(node, "type") == NULL) {
- mxmlDelete(tree);
- return -1;
- }
-
- ops = nft_expr_ops_lookup(mxmlElementGetAttr(node, "type"));
- if (ops == NULL) {
- mxmlDelete(tree);
- return -1;
- }
-
- e = nft_rule_expr_alloc(mxmlElementGetAttr(node, "type"));
- if (e == NULL) {
- mxmlDelete(tree);
- return -1;
- }
-
/* This is a hack for mxml to print just the current node */
save = node->next;
node->next = NULL;
- if (ops->xml_parse(e,
- mxmlSaveAllocString(node,
- MXML_NO_CALLBACK)) != 0) {
+ e = nft_mxml_expr_parse(node);
+ if (e == NULL) {
mxmlDelete(tree);
return -1;
}