]> git.ipfire.org Git - thirdparty/libnftnl.git/commitdiff
src: consolidate XML parsing of expressions via nft_mxml_expr_parse
authorPablo Neira Ayuso <pablo@netfilter.org>
Thu, 4 Jul 2013 12:50:22 +0000 (14:50 +0200)
committerPablo Neira Ayuso <pablo@netfilter.org>
Thu, 4 Jul 2013 14:47:38 +0000 (16:47 +0200)
Move common code for XML parsing of expressions to the new
nft_mxml_expr_parse function.

This patch reduces the XML parsing code in 300 LOC.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
21 files changed:
include/libnftables/expr.h
src/Makefile.am
src/expr/bitwise.c
src/expr/byteorder.c
src/expr/cmp.c
src/expr/counter.c
src/expr/ct.c
src/expr/exthdr.c
src/expr/immediate.c
src/expr/limit.c
src/expr/log.c
src/expr/lookup.c
src/expr/match.c
src/expr/meta.c
src/expr/nat.c
src/expr/payload.c
src/expr/target.c
src/expr_ops.h
src/internal.h
src/mxml.c [new file with mode: 0644]
src/rule.c

index b7d408bb96431e63f340cb48bed8bdedf2dfd25e..02f38d04ffcf90b924faa2cc0507228256f99b51 100644 (file)
@@ -31,6 +31,8 @@ uint32_t nft_rule_expr_get_u32(const struct nft_rule_expr *expr, uint16_t type);
 uint64_t nft_rule_expr_get_u64(const struct nft_rule_expr *expr, uint16_t type);
 const char *nft_rule_expr_get_str(const struct nft_rule_expr *expr, uint16_t type);
 
+struct nlmsghdr;
+
 void nft_rule_expr_build_payload(struct nlmsghdr *nlh, struct nft_rule_expr *expr);
 
 int nft_rule_expr_snprintf(char *buf, size_t buflen, struct nft_rule_expr *expr, uint32_t type, uint32_t flags);
index 46496469934f20a163f647aeb0fb5d01ac15ffba..64965117136e29d322699567690f4b574db9dff9 100644 (file)
@@ -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         \
index 6843086eabdaa086abcd918fe00d2f5c69d93a2a..4b483928849c6a96156de20aac4e20c5fb34c123 100644 (file)
@@ -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;
index bb47f10f44a78f86f16cda1c21a74ee7d026bda5..e1a98e94a85cd0b366aea705d8a10d65c368b111 100644 (file)
@@ -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
index f92b3b6827ed13c1c6649d04e358bfa78b971c8e..ca8dd82e2384b3671c96fa6f675a202998caeb1b 100644 (file)
@@ -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;
index 62bd143a536475b8dd94718e569af2be83b5412d..665fa148916b703c7f9589ae211a72ca8dfba55a 100644 (file)
@@ -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;
index 8014314cf0588e3d98b75a8c084a3a64f050db95..13da0368754f61f369a9eb73ffd0abf6535e70bf 100644 (file)
@@ -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
index b4b9c1303a15a7f53560e96d5489a6306046aac7..e7f4fab2b1353b3d3f5ce01021faff1f9aefe670 100644 (file)
@@ -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;
index 1937d82508d1f972947b2c6ad7073497210909ad..b196ed28af9b2094f924349b74aca8481d0bef6e 100644 (file)
@@ -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;
index 1e843ce56076275da3316594e4448bc6e3d9aaa1..fdd76e306a27f0827dcc52601d58ef71367f1dc6 100644 (file)
@@ -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;
index 8dc5201e766716bddd13510e717b3a7e6eb7856e..b2b3ca1d623f4285d7fdc0e048d779cc200baa83 100644 (file)
@@ -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;
index 8591d4e56e650ea85018f74eb45b2778ed97b5ce..ca10cabaabe94f53e7f063099643a58f60ec690e 100644 (file)
@@ -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;
index 7d0f07805e54ded347359c6080efe98c814800d6..3302bb499dda043066a2feff0dc18eaa6ded2347 100644 (file)
@@ -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;
index 1a609cf95df75fc265a1ba176f713e373b3b0053..46a863a4a8119343c0ba88ac3009a22e0e2d3c9c 100644 (file)
@@ -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;
index b753069aac8b7b4bee9e7ffa6f68d574f3120ef7..05d2e74a56aa3aa4974968200246851f1a374fba 100644 (file)
@@ -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;
index 2111c47c6633a213555c4625a658ea25e0db6dc4..88667555d489e3da244ebc91140e48b0d978a1c4 100644 (file)
@@ -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;
index 0ad39d59d671a224bca2b14208f415aff604194a..ba7ee1a879f35c24f1bee4291f2e53d7e9ad7c5e 100644 (file)
@@ -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;
index 282225da26c119d9ad97955e9155733a458f4549..8dc4a09940f4788e9f1e4b048fad855bec329bc1 100644 (file)
@@ -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);
index 55505be2ce7375df8958e29c8dc9c6d233e2be05..ee09661217512c53109415cab20bff77acdb760d 100644 (file)
@@ -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 (file)
index 0000000..76fb05f
--- /dev/null
@@ -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;
+}
index 5e9b16d525419f50e05ed35e76e99fe4144d03e4..64c34bd8bd27d9e5db9f54a9ed592396698e2581 100644 (file)
@@ -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;
                }