]> git.ipfire.org Git - thirdparty/libnftnl.git/commitdiff
src: new error reporting approach for XML/JSON parsers
authorÁlvaro Neira Ayuso <alvaroneay@gmail.com>
Sun, 5 Jan 2014 23:51:14 +0000 (00:51 +0100)
committerPablo Neira Ayuso <pablo@netfilter.org>
Mon, 6 Jan 2014 12:20:46 +0000 (13:20 +0100)
I have added a new structure for reporting some errors in parser
that we can't cover with errno.

In this patch, we have three errors that we can't cover with errno:

NFT_PARSE_EBADINPUT : Bad XML/JSON format in the input
NFT_PARSE_EMISSINGNODE : Missing node in our input
NFT_PARSE_EBADTYPE : Wrong type value in a node

Signed-off-by: Alvaro Neira Ayuso <alvaroneay@gmail.com>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
45 files changed:
examples/nft-chain-json-add.c
examples/nft-chain-xml-add.c
examples/nft-rule-json-add.c
examples/nft-rule-xml-add.c
examples/nft-set-json-add.c
examples/nft-table-json-add.c
examples/nft-table-xml-add.c
include/libnftables/chain.h
include/libnftables/common.h
include/libnftables/rule.h
include/libnftables/ruleset.h
include/libnftables/set.h
include/libnftables/table.h
src/Makefile.am
src/chain.c
src/common.c
src/expr/bitwise.c
src/expr/byteorder.c
src/expr/cmp.c
src/expr/counter.c
src/expr/ct.c
src/expr/data_reg.c
src/expr/data_reg.h
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/reject.c
src/expr/target.c
src/expr_ops.h
src/internal.h
src/jansson.c
src/libnftables.map
src/mxml.c
src/rule.c
src/ruleset.c
src/set.c
src/set_elem.c
src/table.c
tests/nft-parsing-test.c

index 50cb29f1ed0c30685810e291c95470188d42d632..1802fb095edbcb68352ba57b81aeffa02d7db87d 100644 (file)
@@ -39,6 +39,7 @@ int main(int argc, char *argv[])
        uint16_t family;
        char json[4096];
        char reprint[4096];
+       struct nft_parse_err *err;
 
        if (argc < 2) {
                printf("Usage: %s <json-file>\n", argv[0]);
@@ -63,10 +64,16 @@ int main(int argc, char *argv[])
                exit(EXIT_FAILURE);
        }
 
+       err = nft_parse_err_alloc();
+       if (err == NULL) {
+               perror("error");
+               exit(EXIT_FAILURE);
+       }
+
        close(fd);
 
-       if (nft_chain_parse(c, NFT_PARSE_JSON, json) < 0) {
-               printf("E: Unable to parse JSON file: %s\n", strerror(errno));
+       if (nft_chain_parse(c, NFT_PARSE_JSON, json, err) < 0) {
+               nft_parse_perror("Unable to parse JSON file", err);
                exit(EXIT_FAILURE);
        }
 
@@ -82,6 +89,7 @@ int main(int argc, char *argv[])
        nft_chain_nlmsg_build_payload(nlh, c);
 
        nft_chain_free(c);
+       nft_parse_err_free(err);
 
        nl = mnl_socket_open(NETLINK_NETFILTER);
        if (nl == NULL) {
index 03a295032f3ab392acfc5ceab429cd85c08cb5ee..79b15419206563de54a99513d52e8304a65b7d01 100644 (file)
@@ -37,6 +37,7 @@ int main(int argc, char *argv[])
        uint16_t family;
        char xml[4096];
        char reprint[4096];
+       struct nft_parse_err *err;
 
        if (argc < 2) {
                printf("Usage: %s <xml-file>\n", argv[0]);
@@ -49,6 +50,12 @@ int main(int argc, char *argv[])
                exit(EXIT_FAILURE);
        }
 
+       err = nft_parse_err_alloc();
+       if (err == NULL) {
+               perror("error");
+               exit(EXIT_FAILURE);
+       }
+
         fd = open(argv[1], O_RDONLY);
         if (fd < 0) {
                 perror("open");
@@ -63,8 +70,8 @@ int main(int argc, char *argv[])
 
        close(fd);
 
-       if (nft_chain_parse(c, NFT_PARSE_XML, xml) < 0) {
-               printf("E: Unable to parse XML file: %s\n", strerror(errno));
+       if (nft_chain_parse(c, NFT_PARSE_XML, xml, err) < 0) {
+               nft_parse_perror("Unable to parse XML file", err);
                exit(EXIT_FAILURE);
        }
 
@@ -80,6 +87,7 @@ int main(int argc, char *argv[])
        nft_chain_nlmsg_build_payload(nlh, c);
 
        nft_chain_free(c);
+       nft_parse_err_free(err);
 
        nl = mnl_socket_open(NETLINK_NETFILTER);
        if (nl == NULL) {
index 86590814d1222f3a3f2a5370ed04408e803a1c0b..de1fb5422bd15cd364c05db81086d88cd0608dbd 100644 (file)
@@ -38,6 +38,7 @@ int main(int argc, char *argv[])
        uint8_t family;
        char json[4096];
        char reprint[4096];
+       struct nft_parse_err *err;
 
        if (argc < 2) {
                printf("Usage: %s <json-file>\n", argv[0]);
@@ -63,8 +64,14 @@ int main(int argc, char *argv[])
                exit(EXIT_FAILURE);
        }
 
-       if (nft_rule_parse(r, NFT_PARSE_JSON, json) < 0) {
-               printf("E: Unable to parse JSON file: %s\n", strerror(errno));
+       err = nft_parse_err_alloc();
+       if (err == NULL) {
+               perror("error");
+               exit(EXIT_FAILURE);
+       }
+
+       if (nft_rule_parse(r, NFT_PARSE_JSON, json, err) < 0) {
+               nft_parse_perror("Unable to parse JSON file", err);
                exit(EXIT_FAILURE);
        }
 
@@ -80,6 +87,7 @@ int main(int argc, char *argv[])
                                       seq);
        nft_rule_nlmsg_build_payload(nlh, r);
        nft_rule_free(r);
+       nft_parse_err_free(err);
 
        nl = mnl_socket_open(NETLINK_NETFILTER);
        if (nl == NULL) {
index ce33fe7ca200ddf5300484690abd36836abb4dff..8a7685d7001da4ba6827933a806c653cb7b41e79 100644 (file)
@@ -38,6 +38,7 @@ int main(int argc, char *argv[])
        uint8_t family;
        char xml[4096];
        char reprint[4096];
+       struct nft_parse_err *err;
 
        if (argc < 2) {
                printf("Usage: %s <xml-file>\n", argv[0]);
@@ -63,8 +64,14 @@ int main(int argc, char *argv[])
                exit(EXIT_FAILURE);
        }
 
-       if (nft_rule_parse(r, NFT_PARSE_XML, xml) < 0) {
-               printf("E: Unable to parse XML file: %s\n", strerror(errno));
+       err = nft_parse_err_alloc();
+       if (err == NULL) {
+               perror("error");
+               exit(EXIT_FAILURE);
+       }
+
+       if (nft_rule_parse(r, NFT_PARSE_XML, xml, err) < 0) {
+               nft_parse_perror("Unable to parse XML file", err);
                exit(EXIT_FAILURE);
        }
 
@@ -80,6 +87,7 @@ int main(int argc, char *argv[])
                                       seq);
        nft_rule_nlmsg_build_payload(nlh, r);
        nft_rule_free(r);
+       nft_parse_err_free(err);
 
        nl = mnl_socket_open(NETLINK_NETFILTER);
        if (nl == NULL) {
index 9a4aa48e89098af010a63ffabfb21ca2288976a3..9553ebfd7b7ac7581c751aa8272c6291f8c38f75 100644 (file)
@@ -38,6 +38,7 @@ int main(int argc, char *argv[])
        uint16_t family;
        char json[4096];
        char reprint[4096];
+       struct nft_parse_err *err;
 
        if (argc < 2) {
                printf("Usage: %s <json-file>\n", argv[0]);
@@ -62,10 +63,16 @@ int main(int argc, char *argv[])
                exit(EXIT_FAILURE);
        }
 
+       err = nft_parse_err_alloc();
+       if (err == NULL) {
+               perror("error");
+               exit(EXIT_FAILURE);
+       }
+
        close(fd);
 
-       if (nft_set_parse(s, NFT_PARSE_JSON, json) < 0) {
-               printf("E: Unable to parse JSON file: %s\n", strerror(errno));
+       if (nft_set_parse(s, NFT_PARSE_JSON, json, err) < 0) {
+               nft_parse_perror("Unable to parse JSON file", err);
                exit(EXIT_FAILURE);
        }
 
@@ -80,6 +87,7 @@ int main(int argc, char *argv[])
                                        NLM_F_CREATE|NLM_F_ACK, seq);
        nft_set_nlmsg_build_payload(nlh, s);
        nft_set_free(s);
+       nft_parse_err_free(err);
 
        nl = mnl_socket_open(NETLINK_NETFILTER);
        if (nl == NULL) {
index 6b16c7f0b72aa444760d35b6b9b5021b868d5aba..f3a57c0bf1fe201693d93de7887d61389a27d5d3 100644 (file)
@@ -39,6 +39,7 @@ int main(int argc, char *argv[])
        uint16_t family;
        char json[4096];
        char reprint[4096];
+       struct nft_parse_err *err;
 
        if (argc < 2) {
                printf("Usage: %s <json-file>\n", argv[0]);
@@ -64,8 +65,14 @@ int main(int argc, char *argv[])
                exit(EXIT_FAILURE);
        }
 
-       if (nft_table_parse(t, NFT_PARSE_JSON, json) < 0) {
-               printf("E: Unable to parse JSON file: %s\n", strerror(errno));
+       err = nft_parse_err_alloc();
+       if (err == NULL) {
+               perror("error");
+               exit(EXIT_FAILURE);
+       }
+
+       if (nft_table_parse(t, NFT_PARSE_JSON, json, err) < 0) {
+               nft_parse_perror("Unable to parse JSON file", err);
                exit(EXIT_FAILURE);
        }
 
@@ -80,6 +87,7 @@ int main(int argc, char *argv[])
                                        NLM_F_CREATE|NLM_F_ACK, seq);
        nft_table_nlmsg_build_payload(nlh, t);
        nft_table_free(t);
+       nft_parse_err_free(err);
 
        nl = mnl_socket_open(NETLINK_NETFILTER);
        if (nl == NULL) {
index 6a9163b241ae14d3a145c0850f09c3518e5e9c34..edef1d433a77eaf5e8a5ecd0cd2b68e2054bf4fe 100644 (file)
@@ -23,6 +23,7 @@
 
 #include <libmnl/libmnl.h>
 #include <libnftables/table.h>
+#include <libnftables/common.h>
 
 int main(int argc, char *argv[])
 {
@@ -35,6 +36,7 @@ int main(int argc, char *argv[])
        uint16_t family;
        char xml[4096];
        char reprint[4096];
+       struct nft_parse_err *err;
 
        if (argc < 2) {
                printf("Usage: %s <xml-file>\n", argv[0]);
@@ -60,8 +62,14 @@ int main(int argc, char *argv[])
                exit(EXIT_FAILURE);
        }
 
-       if (nft_table_parse(t, NFT_PARSE_XML, xml) < 0) {
-               printf("E: Unable to parse XML file: %s\n", strerror(errno));
+       err = nft_parse_err_alloc();
+       if (err == NULL) {
+               perror("error");
+               exit(EXIT_FAILURE);
+       }
+
+       if (nft_table_parse(t, NFT_PARSE_XML, xml, err) < 0) {
+               nft_parse_perror("Unable to parse XML file", err);
                exit(EXIT_FAILURE);
        }
 
@@ -76,6 +84,7 @@ int main(int argc, char *argv[])
                                        NLM_F_CREATE|NLM_F_ACK, seq);
        nft_table_nlmsg_build_payload(nlh, t);
        nft_table_free(t);
+       nft_parse_err_free(err);
 
        nl = mnl_socket_open(NETLINK_NETFILTER);
        if (nl == NULL) {
index 8b4eab9c19b7dd412cc917a39a9012aa1b800ff5..dec1a77b367a3de6dadd5250322a0742421908ed 100644 (file)
@@ -51,7 +51,8 @@ struct nlmsghdr;
 
 void nft_chain_nlmsg_build_payload(struct nlmsghdr *nlh, const struct nft_chain *t);
 
-int nft_chain_parse(struct nft_chain *c, enum nft_parse_type type, const char *data);
+int nft_chain_parse(struct nft_chain *c, enum nft_parse_type type,
+                   const char *data, struct nft_parse_err *err);
 int nft_chain_snprintf(char *buf, size_t size, struct nft_chain *t, uint32_t type, uint32_t flags);
 int nft_chain_fprintf(FILE *fp, struct nft_chain *c, uint32_t type, uint32_t flags);
 
index 9cd92b287c15c42c23bc9fc37e6c2b6cc990003f..1ef88ba31f480229b83a8c6163ef018930a1893e 100644 (file)
@@ -1,6 +1,12 @@
 #ifndef _LIBNFTABLES_COMMON_H_
 #define _LIBNFTABLES_COMMON_H_
 
+enum {
+       NFT_PARSE_EBADINPUT     = 0,
+       NFT_PARSE_EMISSINGNODE,
+       NFT_PARSE_EBADTYPE,
+};
+
 enum nft_output_type {
        NFT_OUTPUT_DEFAULT      = 0,
        NFT_OUTPUT_XML,
@@ -14,7 +20,12 @@ enum nft_parse_type {
        NFT_PARSE_MAX,
 };
 
+struct nft_parse_err;
+
 struct nlmsghdr *nft_nlmsg_build_hdr(char *buf, uint16_t cmd, uint16_t family,
                                     uint16_t type, uint32_t seq);
 
+struct nft_parse_err *nft_parse_err_alloc(void);
+void nft_parse_err_free(struct nft_parse_err *);
+int nft_parse_perror(const char *str, struct nft_parse_err *err);
 #endif
index 86dbc17cb3ff45c121f9370c89792bec3fb80e04..15102037d1e55ec84fa2c17f2d2cf5b99a72f21b 100644 (file)
@@ -47,7 +47,8 @@ struct nlmsghdr;
 
 void nft_rule_nlmsg_build_payload(struct nlmsghdr *nlh, struct nft_rule *t);
 
-int nft_rule_parse(struct nft_rule *r, enum nft_parse_type type, const char *data);
+int nft_rule_parse(struct nft_rule *r, enum nft_parse_type type,
+                  const char *data, struct nft_parse_err *err);
 int nft_rule_snprintf(char *buf, size_t size, struct nft_rule *t, uint32_t type, uint32_t flags);
 int nft_rule_fprintf(FILE *fp, struct nft_rule *r, uint32_t type, uint32_t flags);
 
index 1ec3059f122d2dba18174603d554a376eb2358e3..b523346b8612130dde976b0f438870a10275b2af 100644 (file)
@@ -30,7 +30,8 @@ void nft_ruleset_attr_unset(struct nft_ruleset *r, uint16_t attr);
 void nft_ruleset_attr_set(struct nft_ruleset *r, uint16_t attr, void *data);
 const void *nft_ruleset_attr_get(const struct nft_ruleset *r, uint16_t attr);
 
-int nft_ruleset_parse(struct nft_ruleset *rs, enum nft_parse_type type, const char *data);
+int nft_ruleset_parse(struct nft_ruleset *rs, enum nft_parse_type type,
+                     const char *data, struct nft_parse_err *err);
 int nft_ruleset_snprintf(char *buf, size_t size, const struct nft_ruleset *rs, uint32_t type, uint32_t flags);
 int nft_ruleset_fprintf(FILE *fp, const struct nft_ruleset *rs, uint32_t type, uint32_t flags);
 
index 13ac8576e987ca3a079ff40ae1bc7156507b9e2e..97117295c0485ae2a94fa8a30751d12b39a106f3 100644 (file)
@@ -60,7 +60,8 @@ struct nft_set *nft_set_list_iter_cur(struct nft_set_list_iter *iter);
 struct nft_set *nft_set_list_iter_next(struct nft_set_list_iter *iter);
 void nft_set_list_iter_destroy(struct nft_set_list_iter *iter);
 
-int nft_set_parse(struct nft_set *s, enum nft_parse_type type, const char *data);
+int nft_set_parse(struct nft_set *s, enum nft_parse_type type,
+                 const char *data, struct nft_parse_err *err);
 
 /*
  * Set elements
@@ -98,7 +99,8 @@ void nft_set_elem_nlmsg_build_payload(struct nlmsghdr *nlh, struct nft_set_elem
 
 int nft_set_elem_nlmsg_parse(const struct nlmsghdr *nlh, struct nft_set_elem *s);
 
-int nft_set_elem_parse(struct nft_set_elem *e, enum nft_parse_type type, const char *data);
+int nft_set_elem_parse(struct nft_set_elem *e, enum nft_parse_type type,
+                      const char *data, struct nft_parse_err *err);
 int nft_set_elem_snprintf(char *buf, size_t size, struct nft_set_elem *s, uint32_t type, uint32_t flags);
 int nft_set_elem_fprintf(FILE *fp, struct nft_set_elem *se, uint32_t type, uint32_t flags);
 
index be60da91fbeacfccd2afb3743c47b753219ec59d..80f2349f43099a459a80bf1d558dc659852e98ff 100644 (file)
@@ -39,7 +39,8 @@ struct nlmsghdr;
 
 void nft_table_nlmsg_build_payload(struct nlmsghdr *nlh, const struct nft_table *t);
 
-int nft_table_parse(struct nft_table *t, enum nft_parse_type type, const char *data);
+int nft_table_parse(struct nft_table *t, enum nft_parse_type type,
+                   const char *data, struct nft_parse_err *err);
 int nft_table_snprintf(char *buf, size_t size, struct nft_table *t, uint32_t type, uint32_t flags);
 int nft_table_fprintf(FILE *fp, struct nft_table *t, uint32_t type, uint32_t flags);
 
index 83ab6584d0b824e604555c6b51c88ea0841405c2..fc13e460b7f7ac919995431c31b4433e39434b3d 100644 (file)
@@ -4,6 +4,7 @@ lib_LTLIBRARIES = libnftables.la
 libnftables_la_LIBADD = ${LIBMNL_LIBS} ${LIBXML_LIBS} ${LIBJSON_LIBS}
 libnftables_la_LDFLAGS = -Wl,--version-script=$(srcdir)/libnftables.map \
                         -version-info $(LIBVERSION)
+
 libnftables_la_SOURCES = utils.c               \
                         common.c               \
                         table.c                \
index a0004b5e5b368997aa947ed61a52357362529de8..a4ddb066eeb18ba1a6823bc016a41789c808326d 100644 (file)
@@ -498,7 +498,8 @@ static inline int nft_str2hooknum(int family, const char *hook)
 }
 
 #ifdef JSON_PARSING
-int nft_jansson_parse_chain(struct nft_chain *c, json_t *tree)
+int nft_jansson_parse_chain(struct nft_chain *c, json_t *tree,
+                           struct nft_parse_err *err)
 {
        json_t *root;
        uint64_t uval64;
@@ -506,37 +507,40 @@ int nft_jansson_parse_chain(struct nft_chain *c, json_t *tree)
        int32_t val32;
        const char *valstr;
 
-       root = nft_jansson_get_node(tree, "chain");
+       root = nft_jansson_get_node(tree, "chain", err);
        if (root == NULL)
                return -1;
 
-       valstr = nft_jansson_parse_str(root, "name");
+       valstr = nft_jansson_parse_str(root, "name", err);
        if (valstr == NULL)
                goto err;
 
        nft_chain_attr_set_str(c, NFT_CHAIN_ATTR_NAME, valstr);
 
-       if (nft_jansson_parse_val(root, "handle", NFT_TYPE_U64, &uval64) < 0)
+       if (nft_jansson_parse_val(root, "handle", NFT_TYPE_U64, &uval64,
+                                 err) < 0)
                goto err;
 
        nft_chain_attr_set_u64(c,NFT_CHAIN_ATTR_HANDLE, uval64);
 
-       if (nft_jansson_parse_val(root, "bytes", NFT_TYPE_U64, &uval64) < 0)
+       if (nft_jansson_parse_val(root, "bytes", NFT_TYPE_U64, &uval64,
+                                 err) < 0)
                goto err;
 
        nft_chain_attr_set_u64(c, NFT_CHAIN_ATTR_BYTES, uval64);
 
-       if (nft_jansson_parse_val(root, "packets", NFT_TYPE_U64, &uval64) < 0)
+       if (nft_jansson_parse_val(root, "packets", NFT_TYPE_U64, &uval64,
+                                 err) < 0)
                goto err;
 
        nft_chain_attr_set_u64(c, NFT_CHAIN_ATTR_PACKETS, uval64);
 
-       if (nft_jansson_parse_family(root, &val32) != 0)
+       if (nft_jansson_parse_family(root, &val32, err) != 0)
                goto err;
 
        nft_chain_attr_set_u32(c, NFT_CHAIN_ATTR_FAMILY, val32);
 
-       valstr = nft_jansson_parse_str(root, "table");
+       valstr = nft_jansson_parse_str(root, "table", err);
 
        if (valstr == NULL)
                goto err;
@@ -544,7 +548,7 @@ int nft_jansson_parse_chain(struct nft_chain *c, json_t *tree)
        nft_chain_attr_set_str(c, NFT_CHAIN_ATTR_TABLE, valstr);
 
        if (nft_jansson_node_exist(root, "hooknum")) {
-               valstr = nft_jansson_parse_str(root, "type");
+               valstr = nft_jansson_parse_str(root, "type", err);
 
                if (valstr == NULL)
                        goto err;
@@ -552,12 +556,12 @@ int nft_jansson_parse_chain(struct nft_chain *c, json_t *tree)
                nft_chain_attr_set_str(c, NFT_CHAIN_ATTR_TYPE, valstr);
 
                if (nft_jansson_parse_val(root, "prio", NFT_TYPE_S32,
-                                         &val32) < 0)
+                                         &val32, err) < 0)
                        goto err;
 
                nft_chain_attr_set_s32(c, NFT_CHAIN_ATTR_PRIO, val32);
 
-               valstr = nft_jansson_parse_str(root, "hooknum");
+               valstr = nft_jansson_parse_str(root, "hooknum", err);
                if (valstr == NULL)
                        goto err;
 
@@ -567,7 +571,7 @@ int nft_jansson_parse_chain(struct nft_chain *c, json_t *tree)
 
                nft_chain_attr_set_u32(c, NFT_CHAIN_ATTR_HOOKNUM, val32);
 
-               valstr = nft_jansson_parse_str(root, "policy");
+               valstr = nft_jansson_parse_str(root, "policy", err);
                if (valstr == NULL)
                        goto err;
 
@@ -587,17 +591,18 @@ err:
 }
 #endif
 
-static int nft_chain_json_parse(struct nft_chain *c, const char *json)
+static int nft_chain_json_parse(struct nft_chain *c, const char *json,
+                               struct nft_parse_err *err)
 {
 #ifdef JSON_PARSING
        json_t *tree;
        json_error_t error;
 
-       tree = nft_jansson_create_root(json, &error);
+       tree = nft_jansson_create_root(json, &error, err);
        if (tree == NULL)
                return -1;
 
-       return nft_jansson_parse_chain(c, tree);
+       return nft_jansson_parse_chain(c, tree, err);
 #else
        errno = EOPNOTSUPP;
        return -1;
@@ -605,13 +610,14 @@ static int nft_chain_json_parse(struct nft_chain *c, const char *json)
 }
 
 #ifdef XML_PARSING
-int nft_mxml_chain_parse(mxml_node_t *tree, struct nft_chain *c)
+int nft_mxml_chain_parse(mxml_node_t *tree, struct nft_chain *c,
+                        struct nft_parse_err *err)
 {
        const char *table, *name, *hooknum_str, *policy_str, *type;
        int family, hooknum, policy;
 
        name = nft_mxml_str_parse(tree, "name", MXML_DESCEND_FIRST,
-                                 NFT_XML_MAND);
+                                 NFT_XML_MAND, err);
        if (name == NULL)
                return -1;
 
@@ -619,25 +625,25 @@ int nft_mxml_chain_parse(mxml_node_t *tree, struct nft_chain *c)
        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)
+                              &c->handle, NFT_TYPE_U64, NFT_XML_MAND, err) != 0)
                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)
+                              &c->bytes, NFT_TYPE_U64, NFT_XML_MAND, err) != 0)
                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)
+                              &c->packets, NFT_TYPE_U64, NFT_XML_MAND, err) != 0)
                return -1;
 
        c->flags |= (1 << NFT_CHAIN_ATTR_PACKETS);
 
        table = nft_mxml_str_parse(tree, "table", MXML_DESCEND_FIRST,
-                                  NFT_XML_MAND);
+                                  NFT_XML_MAND, err);
        if (table == NULL)
                return -1;
 
@@ -648,7 +654,7 @@ int nft_mxml_chain_parse(mxml_node_t *tree, struct nft_chain *c)
        c->flags |= (1 << NFT_CHAIN_ATTR_TABLE);
 
        family = nft_mxml_family_parse(tree, "family", MXML_DESCEND_FIRST,
-                                      NFT_XML_MAND);
+                                      NFT_XML_MAND, err);
        if (family < 0)
                return -1;
 
@@ -656,7 +662,7 @@ int nft_mxml_chain_parse(mxml_node_t *tree, struct nft_chain *c)
        c->flags |= (1 << NFT_CHAIN_ATTR_FAMILY);
 
        hooknum_str = nft_mxml_str_parse(tree, "hooknum", MXML_DESCEND_FIRST,
-                                        NFT_XML_OPT);
+                                        NFT_XML_OPT, err);
        if (hooknum_str != NULL) {
                hooknum = nft_str2hooknum(c->family, hooknum_str);
                if (hooknum < 0)
@@ -666,7 +672,7 @@ int nft_mxml_chain_parse(mxml_node_t *tree, struct nft_chain *c)
                c->flags |= (1 << NFT_CHAIN_ATTR_HOOKNUM);
 
                type = nft_mxml_str_parse(tree, "type", MXML_DESCEND_FIRST,
-                                         NFT_XML_MAND);
+                                         NFT_XML_MAND, err);
                if (type == NULL)
                        return -1;
 
@@ -679,14 +685,14 @@ int nft_mxml_chain_parse(mxml_node_t *tree, struct nft_chain *c)
 
                if (nft_mxml_num_parse(tree, "prio", MXML_DESCEND, BASE_DEC,
                                       &c->prio, NFT_TYPE_S32,
-                                      NFT_XML_MAND) != 0)
+                                      NFT_XML_MAND, err) != 0)
                        return -1;
 
                c->flags |= (1 << NFT_CHAIN_ATTR_PRIO);
 
                policy_str = nft_mxml_str_parse(tree, "policy",
                                                MXML_DESCEND_FIRST,
-                                               NFT_XML_MAND);
+                                               NFT_XML_MAND, err);
                if (policy_str == NULL)
                        return -1;
 
@@ -702,15 +708,16 @@ int nft_mxml_chain_parse(mxml_node_t *tree, struct nft_chain *c)
 }
 #endif
 
-static int nft_chain_xml_parse(struct nft_chain *c, const char *xml)
+static int nft_chain_xml_parse(struct nft_chain *c, const char *xml,
+                              struct nft_parse_err *err)
 {
 #ifdef XML_PARSING
        int ret;
-       mxml_node_t *tree = nft_mxml_build_tree(xml, "chain");
+       mxml_node_t *tree = nft_mxml_build_tree(xml, "chain", err);
        if (tree == NULL)
                return -1;
 
-       ret = nft_mxml_chain_parse(tree, c);
+       ret = nft_mxml_chain_parse(tree, c, err);
        mxmlDelete(tree);
        return ret;
 #else
@@ -720,16 +727,17 @@ static int nft_chain_xml_parse(struct nft_chain *c, const char *xml)
 }
 
 int nft_chain_parse(struct nft_chain *c, enum nft_parse_type type,
-                   const char *data)
+                   const char *data, struct nft_parse_err *err)
 {
        int ret;
+       struct nft_parse_err perr;
 
        switch (type) {
        case NFT_PARSE_XML:
-               ret = nft_chain_xml_parse(c, data);
+               ret = nft_chain_xml_parse(c, data, &perr);
                break;
        case NFT_PARSE_JSON:
-               ret = nft_chain_json_parse(c, data);
+               ret = nft_chain_json_parse(c, data, &perr);
                break;
        default:
                ret = -1;
@@ -737,6 +745,9 @@ int nft_chain_parse(struct nft_chain *c, enum nft_parse_type type,
                break;
        }
 
+       if (err != NULL)
+               *err = perr;
+
        return ret;
 }
 EXPORT_SYMBOL(nft_chain_parse);
index f03e73059868681133d8bbc6be23b87097a3e4ad..5c6ddbfc0a496072b28ebb90cb5a4d8501dea34c 100644 (file)
@@ -14,6 +14,7 @@
 #include <libnftables/common.h>
 
 #include "internal.h"
+#include<stdlib.h>
 
 struct nlmsghdr *nft_nlmsg_build_hdr(char *buf, uint16_t cmd, uint16_t family,
                                     uint16_t type, uint32_t seq)
@@ -34,3 +35,33 @@ struct nlmsghdr *nft_nlmsg_build_hdr(char *buf, uint16_t cmd, uint16_t family,
        return nlh;
 }
 EXPORT_SYMBOL(nft_nlmsg_build_hdr);
+
+struct nft_parse_err *nft_parse_err_alloc(void)
+{
+       return calloc(1, sizeof(struct nft_parse_err));
+}
+EXPORT_SYMBOL(nft_parse_err_alloc);
+
+void nft_parse_err_free(struct nft_parse_err *err)
+{
+       xfree(err);
+}
+EXPORT_SYMBOL(nft_parse_err_free);
+
+int nft_parse_perror(const char *str, struct nft_parse_err *err)
+{
+       switch (err->error) {
+       case NFT_PARSE_EBADINPUT:
+               return fprintf(stderr, "%s : Bad input format in line %d column %d\n",
+                      str, err->line, err->column);
+       case NFT_PARSE_EMISSINGNODE:
+               return fprintf(stderr, "%s : Node \"%s\" not found\n",
+                               str, err->node_name);
+       case NFT_PARSE_EBADTYPE:
+               return fprintf(stderr, "%s: Invalid type in node \"%s\"\n",
+                               str, err->node_name);
+       default:
+               return fprintf(stderr, "Undefined error\n");
+       }
+}
+EXPORT_SYMBOL(nft_parse_perror);
index bcec516e1557ccec0190f8c547dfff4bd6aae29f..3c4f64458a55dabd949437d4532eb47e5cfd4ade 100644 (file)
@@ -181,35 +181,36 @@ nft_rule_expr_bitwise_parse(struct nft_rule_expr *e, struct nlattr *attr)
 }
 
 static int
-nft_rule_expr_bitwise_json_parse(struct nft_rule_expr *e, json_t *root)
+nft_rule_expr_bitwise_json_parse(struct nft_rule_expr *e, json_t *root,
+                                struct nft_parse_err *err)
 {
 #ifdef JSON_PARSING
        struct nft_expr_bitwise *bitwise = nft_expr_data(e);
        uint32_t reg, len;
 
-       if (nft_jansson_parse_reg(root, "sreg", NFT_TYPE_U32, &reg) < 0)
+       if (nft_jansson_parse_reg(root, "sreg", NFT_TYPE_U32, &reg, err) < 0)
                return -1;
 
        nft_rule_expr_set_u32(e, NFT_EXPR_BITWISE_SREG, reg);
 
-       if (nft_jansson_parse_reg(root, "dreg", NFT_TYPE_U32, &reg) < 0)
+       if (nft_jansson_parse_reg(root, "dreg", NFT_TYPE_U32, &reg, err) < 0)
                return -1;
 
        nft_rule_expr_set_u32(e, NFT_EXPR_BITWISE_DREG, reg);
 
-       if (nft_jansson_parse_val(root, "len", NFT_TYPE_U32, &len) < 0)
+       if (nft_jansson_parse_val(root, "len", NFT_TYPE_U32, &len, err) < 0)
                return -1;
 
        nft_rule_expr_set_u32(e, NFT_EXPR_BITWISE_LEN, len);
 
        if (nft_jansson_data_reg_parse(root, "mask",
-                                      &bitwise->mask) != DATA_VALUE)
+                                      &bitwise->mask, err) != DATA_VALUE)
                return -1;
 
        e->flags |= (1 << NFT_EXPR_BITWISE_MASK);
 
        if (nft_jansson_data_reg_parse(root, "xor",
-                                      &bitwise->xor) != DATA_VALUE)
+                                      &bitwise->xor, err) != DATA_VALUE)
                return -1;
 
        e->flags |= (1 << NFT_EXPR_BITWISE_XOR);
@@ -225,20 +226,21 @@ nft_rule_expr_bitwise_json_parse(struct nft_rule_expr *e, json_t *root)
 }
 
 static int
-nft_rule_expr_bitwise_xml_parse(struct nft_rule_expr *e, mxml_node_t *tree)
+nft_rule_expr_bitwise_xml_parse(struct nft_rule_expr *e, mxml_node_t *tree,
+                               struct nft_parse_err *err)
 {
 #ifdef XML_PARSING
        struct nft_expr_bitwise *bitwise = nft_expr_data(e);
        int32_t reg;
 
-       reg = nft_mxml_reg_parse(tree, "sreg", MXML_DESCEND_FIRST);
+       reg = nft_mxml_reg_parse(tree, "sreg", MXML_DESCEND_FIRST, err);
        if (reg < 0)
                return -1;
 
        bitwise->sreg = reg;
        e->flags |= (1 << NFT_EXPR_BITWISE_SREG);
 
-       reg = nft_mxml_reg_parse(tree, "dreg", MXML_DESCEND);
+       reg = nft_mxml_reg_parse(tree, "dreg", MXML_DESCEND, err);
        if (reg < 0)
                return -1;
 
@@ -247,19 +249,19 @@ nft_rule_expr_bitwise_xml_parse(struct nft_rule_expr *e, mxml_node_t *tree)
 
        if (nft_mxml_num_parse(tree, "len", MXML_DESCEND_FIRST,
                               BASE_DEC, &bitwise->len, NFT_TYPE_U8,
-                              NFT_XML_MAND) != 0)
+                              NFT_XML_MAND, err) != 0)
                return -1;
 
        e->flags |= (1 << NFT_EXPR_BITWISE_LEN);
 
        if (nft_mxml_data_reg_parse(tree, "mask", &bitwise->mask,
-                                   NFT_XML_MAND) != DATA_VALUE)
+                                   NFT_XML_MAND, err) != DATA_VALUE)
                return -1;
 
        e->flags |= (1 << NFT_EXPR_BITWISE_MASK);
 
        if (nft_mxml_data_reg_parse(tree, "xor", &bitwise->xor,
-                                   NFT_XML_MAND) != DATA_VALUE)
+                                   NFT_XML_MAND, err) != DATA_VALUE)
                return -1;
 
        e->flags |= (1 << NFT_EXPR_BITWISE_XOR);
index 7224c82eb5d82ec6581ba696e765b2fc1ec76d5b..d6beba3bd9c5a2d18794882b90d371cb747345cf 100644 (file)
@@ -194,24 +194,25 @@ static inline int nft_str2ntoh(const char *op)
 }
 
 static int
-nft_rule_expr_byteorder_json_parse(struct nft_rule_expr *e, json_t *root)
+nft_rule_expr_byteorder_json_parse(struct nft_rule_expr *e, json_t *root,
+                                  struct nft_parse_err *err)
 {
 #ifdef JSON_PARSING
        const char *op;
        uint32_t uval32;
        int ntoh;
 
-       if (nft_jansson_parse_reg(root, "sreg", NFT_TYPE_U32, &uval32) < 0)
+       if (nft_jansson_parse_reg(root, "sreg", NFT_TYPE_U32, &uval32, err) < 0)
                return -1;
 
        nft_rule_expr_set_u32(e, NFT_EXPR_BYTEORDER_SREG, uval32);
 
-       if (nft_jansson_parse_reg(root, "dreg", NFT_TYPE_U32, &uval32) < 0)
+       if (nft_jansson_parse_reg(root, "dreg", NFT_TYPE_U32, &uval32, err) < 0)
                return -1;
 
        nft_rule_expr_set_u32(e, NFT_EXPR_BYTEORDER_DREG, uval32);
 
-       op = nft_jansson_parse_str(root, "op");
+       op = nft_jansson_parse_str(root, "op", err);
        if (op == NULL)
                return -1;
 
@@ -221,12 +222,12 @@ nft_rule_expr_byteorder_json_parse(struct nft_rule_expr *e, json_t *root)
 
        nft_rule_expr_set_u32(e, NFT_EXPR_BYTEORDER_OP, ntoh);
 
-       if (nft_jansson_parse_val(root, "len", NFT_TYPE_U32, &uval32) < 0)
+       if (nft_jansson_parse_val(root, "len", NFT_TYPE_U32, &uval32, err) < 0)
                return -1;
 
        nft_rule_expr_set_u32(e, NFT_EXPR_BYTEORDER_LEN, uval32);
 
-       if (nft_jansson_parse_val(root, "size", NFT_TYPE_U32, &uval32) < 0)
+       if (nft_jansson_parse_val(root, "size", NFT_TYPE_U32, &uval32, err) < 0)
                return -1;
 
        nft_rule_expr_set_u32(e, NFT_EXPR_BYTEORDER_SIZE, uval32);
@@ -239,28 +240,30 @@ nft_rule_expr_byteorder_json_parse(struct nft_rule_expr *e, json_t *root)
 }
 
 static int
-nft_rule_expr_byteorder_xml_parse(struct nft_rule_expr *e, mxml_node_t *tree)
+nft_rule_expr_byteorder_xml_parse(struct nft_rule_expr *e, mxml_node_t *tree,
+                                 struct nft_parse_err *err)
 {
 #ifdef XML_PARSING
        struct nft_expr_byteorder *byteorder = nft_expr_data(e);
        const char *op;
        int32_t reg, ntoh;
 
-       reg = nft_mxml_reg_parse(tree, "sreg", MXML_DESCEND_FIRST);
+       reg = nft_mxml_reg_parse(tree, "sreg", MXML_DESCEND_FIRST, err);
        if (reg < 0)
                return -1;
 
        byteorder->sreg = reg;
        e->flags |= (1 << NFT_EXPR_BYTEORDER_SREG);
 
-       reg = nft_mxml_reg_parse(tree, "dreg", MXML_DESCEND);
+       reg = nft_mxml_reg_parse(tree, "dreg", MXML_DESCEND, err);
        if (reg < 0)
                return -1;
 
        byteorder->dreg = reg;
        e->flags |= (1 << NFT_EXPR_BYTEORDER_DREG);
 
-       op = nft_mxml_str_parse(tree, "op", MXML_DESCEND_FIRST, NFT_XML_MAND);
+       op = nft_mxml_str_parse(tree, "op", MXML_DESCEND_FIRST, NFT_XML_MAND,
+                               err);
        if (op == NULL)
                return -1;
 
@@ -273,14 +276,14 @@ nft_rule_expr_byteorder_xml_parse(struct nft_rule_expr *e, mxml_node_t *tree)
 
        if (nft_mxml_num_parse(tree, "len", MXML_DESCEND_FIRST, BASE_DEC,
                               &byteorder->len, NFT_TYPE_U8,
-                              NFT_XML_MAND) != 0)
+                              NFT_XML_MAND, err) != 0)
                return -1;
 
        e->flags |= (1 << NFT_EXPR_BYTEORDER_LEN);
 
        if (nft_mxml_num_parse(tree, "size", MXML_DESCEND_FIRST, BASE_DEC,
                               &byteorder->size, NFT_TYPE_U8,
-                              NFT_XML_MAND) != 0)
+                              NFT_XML_MAND, err) != 0)
                return -1;
 
        e->flags |= (1 << NFT_EXPR_BYTEORDER_SIZE);
index 246f22fac0d42f358ebd1e603d3b040f8b43948e..ca1503c72cba24048440678bcf6ee9a794bb465d 100644 (file)
@@ -174,7 +174,8 @@ static inline int nft_str2cmp(const char *op)
        }
 }
 
-static int nft_rule_expr_cmp_json_parse(struct nft_rule_expr *e, json_t *root)
+static int nft_rule_expr_cmp_json_parse(struct nft_rule_expr *e, json_t *root,
+                                       struct nft_parse_err *err)
 {
 #ifdef JSON_PARSING
        struct nft_expr_cmp *cmp = nft_expr_data(e);
@@ -182,12 +183,12 @@ static int nft_rule_expr_cmp_json_parse(struct nft_rule_expr *e, json_t *root)
        uint32_t uval32;
        int base;
 
-       if (nft_jansson_parse_val(root, "sreg", NFT_TYPE_U32, &uval32) < 0)
+       if (nft_jansson_parse_val(root, "sreg", NFT_TYPE_U32, &uval32, err) < 0)
                return -1;
 
        nft_rule_expr_set_u32(e, NFT_EXPR_CMP_SREG, uval32);
 
-       op = nft_jansson_parse_str(root, "op");
+       op = nft_jansson_parse_str(root, "op", err);
        if (op == NULL)
                return -1;
 
@@ -198,7 +199,7 @@ static int nft_rule_expr_cmp_json_parse(struct nft_rule_expr *e, json_t *root)
        nft_rule_expr_set_u32(e, NFT_EXPR_CMP_OP, base);
 
        if (nft_jansson_data_reg_parse(root, "cmpdata",
-                                      &cmp->data) != DATA_VALUE)
+                                      &cmp->data, err) != DATA_VALUE)
                return -1;
 
        e->flags |= (1 << NFT_EXPR_CMP_DATA);
@@ -210,21 +211,23 @@ static int nft_rule_expr_cmp_json_parse(struct nft_rule_expr *e, json_t *root)
 #endif
 }
 
-static int nft_rule_expr_cmp_xml_parse(struct nft_rule_expr *e, mxml_node_t *tree)
+static int nft_rule_expr_cmp_xml_parse(struct nft_rule_expr *e, mxml_node_t *tree,
+                                      struct nft_parse_err *err)
 {
 #ifdef XML_PARSING
        struct nft_expr_cmp *cmp = nft_expr_data(e);
        const char *op;
        int32_t reg, op_value;
 
-       reg = nft_mxml_reg_parse(tree, "sreg", MXML_DESCEND_FIRST);
+       reg = nft_mxml_reg_parse(tree, "sreg", MXML_DESCEND_FIRST, err);
        if (reg < 0)
                return -1;
 
        cmp->sreg = reg;
        e->flags |= (1 << NFT_EXPR_CMP_SREG);
 
-       op = nft_mxml_str_parse(tree, "op", MXML_DESCEND_FIRST, NFT_XML_MAND);
+       op = nft_mxml_str_parse(tree, "op", MXML_DESCEND_FIRST, NFT_XML_MAND,
+                               err);
        if (op == NULL)
                return -1;
 
@@ -236,7 +239,8 @@ static int nft_rule_expr_cmp_xml_parse(struct nft_rule_expr *e, mxml_node_t *tre
        e->flags |= (1 << NFT_EXPR_CMP_OP);
 
        if (nft_mxml_data_reg_parse(tree, "cmpdata",
-                                   &cmp->data, NFT_XML_MAND) != DATA_VALUE)
+                                   &cmp->data, NFT_XML_MAND,
+                                   err) != DATA_VALUE)
                return -1;
 
        e->flags |= (1 << NFT_EXPR_CMP_DATA);
index 4919a69f2eab2407acad43d744db845fc02417ed..11afb83720311cbe61a39e59e05c625273670c61 100644 (file)
@@ -119,17 +119,18 @@ nft_rule_expr_counter_parse(struct nft_rule_expr *e, struct nlattr *attr)
 }
 
 static int
-nft_rule_expr_counter_json_parse(struct nft_rule_expr *e, json_t *root)
+nft_rule_expr_counter_json_parse(struct nft_rule_expr *e, json_t *root,
+                                struct nft_parse_err *err)
 {
 #ifdef JSON_PARSING
        uint64_t uval64;
 
-       if (nft_jansson_parse_val(root, "pkts", NFT_TYPE_U64, &uval64) < 0)
+       if (nft_jansson_parse_val(root, "pkts", NFT_TYPE_U64, &uval64, err) < 0)
                return -1;
 
        nft_rule_expr_set_u64(e, NFT_EXPR_CTR_PACKETS, uval64);
 
-       if (nft_jansson_parse_val(root, "bytes", NFT_TYPE_U64, &uval64) < 0)
+       if (nft_jansson_parse_val(root, "bytes", NFT_TYPE_U64, &uval64, err) < 0)
                return -1;
 
        nft_rule_expr_set_u64(e, NFT_EXPR_CTR_BYTES, uval64);
@@ -142,19 +143,22 @@ nft_rule_expr_counter_json_parse(struct nft_rule_expr *e, json_t *root)
 }
 
 static int
-nft_rule_expr_counter_xml_parse(struct nft_rule_expr *e, mxml_node_t *tree)
+nft_rule_expr_counter_xml_parse(struct nft_rule_expr *e, mxml_node_t *tree,
+                               struct nft_parse_err *err)
 {
 #ifdef XML_PARSING
        struct nft_expr_counter *ctr = nft_expr_data(e);
 
        if (nft_mxml_num_parse(tree, "pkts", MXML_DESCEND_FIRST, BASE_DEC,
-                              &ctr->pkts, NFT_TYPE_U64, NFT_XML_MAND) != 0)
+                              &ctr->pkts, NFT_TYPE_U64, NFT_XML_MAND,
+                              err) != 0)
                return -1;
 
        e->flags |= (1 << NFT_EXPR_CTR_PACKETS);
 
        if (nft_mxml_num_parse(tree, "bytes", MXML_DESCEND_FIRST, BASE_DEC,
-                              &ctr->bytes, NFT_TYPE_U64, NFT_XML_MAND) != 0)
+                              &ctr->bytes, NFT_TYPE_U64, NFT_XML_MAND,
+                              err) != 0)
                return -1;
 
        e->flags |= (1 << NFT_EXPR_CTR_BYTES);
index 46e3cef6e7be65232a015f7e036788eee039d648..59d05a58d27aeee752aa2fb1a95eab8e6a345478 100644 (file)
@@ -178,7 +178,8 @@ static inline int str2ctkey(const char *ctkey)
        return -1;
 }
 
-static int nft_rule_expr_ct_json_parse(struct nft_rule_expr *e, json_t *root)
+static int nft_rule_expr_ct_json_parse(struct nft_rule_expr *e, json_t *root,
+                                      struct nft_parse_err *err)
 {
 #ifdef JSON_PARSING
        const char *key_str;
@@ -186,13 +187,13 @@ static int nft_rule_expr_ct_json_parse(struct nft_rule_expr *e, json_t *root)
        uint8_t dir;
        int key;
 
-       if (nft_jansson_parse_reg(root, "dreg", NFT_TYPE_U32, &reg) < 0)
+       if (nft_jansson_parse_reg(root, "dreg", NFT_TYPE_U32, &reg, err) < 0)
                return -1;
 
        nft_rule_expr_set_u32(e, NFT_EXPR_CT_DREG, reg);
 
        if (nft_jansson_node_exist(root, "key")) {
-               key_str = nft_jansson_parse_str(root, "key");
+               key_str = nft_jansson_parse_str(root, "key", err);
                if (key_str == NULL)
                        return -1;
 
@@ -205,7 +206,8 @@ static int nft_rule_expr_ct_json_parse(struct nft_rule_expr *e, json_t *root)
        }
 
        if (nft_jansson_node_exist(root, "dir")) {
-               if (nft_jansson_parse_val(root, "dir", NFT_TYPE_U8, &dir) < 0)
+               if (nft_jansson_parse_val(root, "dir", NFT_TYPE_U8, &dir,
+                                         err) < 0)
                        return -1;
 
                if (dir != IP_CT_DIR_ORIGINAL && dir != IP_CT_DIR_REPLY)
@@ -225,7 +227,8 @@ err:
 }
 
 
-static int nft_rule_expr_ct_xml_parse(struct nft_rule_expr *e, mxml_node_t *tree)
+static int nft_rule_expr_ct_xml_parse(struct nft_rule_expr *e, mxml_node_t *tree,
+                                     struct nft_parse_err *err)
 {
 #ifdef XML_PARSING
        struct nft_expr_ct *ct = nft_expr_data(e);
@@ -234,7 +237,7 @@ static int nft_rule_expr_ct_xml_parse(struct nft_rule_expr *e, mxml_node_t *tree
        int key;
        uint8_t dir;
 
-       reg = nft_mxml_reg_parse(tree, "dreg", MXML_DESCEND_FIRST);
+       reg = nft_mxml_reg_parse(tree, "dreg", MXML_DESCEND_FIRST, err);
        if (reg < 0)
                return -1;
 
@@ -242,7 +245,7 @@ static int nft_rule_expr_ct_xml_parse(struct nft_rule_expr *e, mxml_node_t *tree
        e->flags |= (1 << NFT_EXPR_CT_DREG);
 
        key_str = nft_mxml_str_parse(tree, "key", MXML_DESCEND_FIRST,
-                                    NFT_XML_MAND);
+                                    NFT_XML_MAND, err);
        if (key_str == NULL)
                return -1;
 
@@ -254,7 +257,7 @@ static int nft_rule_expr_ct_xml_parse(struct nft_rule_expr *e, mxml_node_t *tree
        e->flags |= (1 << NFT_EXPR_CT_KEY);
 
        if (nft_mxml_num_parse(tree, "dir", MXML_DESCEND_FIRST, BASE_DEC,
-                              &dir, NFT_TYPE_U8, NFT_XML_MAND) != 0)
+                              &dir, NFT_TYPE_U8, NFT_XML_MAND, err) != 0)
                return -1;
 
        if (dir != IP_CT_DIR_ORIGINAL && dir != IP_CT_DIR_REPLY)
index 76231af4829e2ed70b2d7f3ba207f155bffd55ec..e487bc70d8badda41de051ac698754c872772944 100644 (file)
 #include "internal.h"
 
 #ifdef JSON_PARSING
-static int nft_data_reg_verdict_json_parse(union nft_data_reg *reg, json_t *data)
+static int nft_data_reg_verdict_json_parse(union nft_data_reg *reg, json_t *data,
+                                          struct nft_parse_err *err)
 {
        int verdict;
        const char *verdict_str;
 
-       verdict_str = nft_jansson_parse_str(data, "verdict");
+       verdict_str = nft_jansson_parse_str(data, "verdict", err);
        if (verdict_str == NULL)
                return -1;
 
@@ -45,9 +46,10 @@ static int nft_data_reg_verdict_json_parse(union nft_data_reg *reg, json_t *data
        return 0;
 }
 
-static int nft_data_reg_chain_json_parse(union nft_data_reg *reg, json_t *data)
+static int nft_data_reg_chain_json_parse(union nft_data_reg *reg, json_t *data,
+                                        struct nft_parse_err *err)
 {
-       reg->chain = strdup(nft_jansson_parse_str(data, "chain"));
+       reg->chain = strdup(nft_jansson_parse_str(data, "chain", err));
        if (reg->chain == NULL) {
                return -1;
        }
@@ -55,19 +57,20 @@ static int nft_data_reg_chain_json_parse(union nft_data_reg *reg, json_t *data)
        return 0;
 }
 
-static int nft_data_reg_value_json_parse(union nft_data_reg *reg, json_t *data)
+static int nft_data_reg_value_json_parse(union nft_data_reg *reg, json_t *data,
+                                        struct nft_parse_err *err)
 {
        int i;
        char node_name[6];
 
-       if (nft_jansson_parse_val(data, "len", NFT_TYPE_U8, &reg->len) < 0)
+       if (nft_jansson_parse_val(data, "len", NFT_TYPE_U8, &reg->len, err) < 0)
                        return -1;
 
        for (i = 0; i < div_round_up(reg->len, sizeof(uint32_t)); i++) {
                sprintf(node_name, "data%d", i);
 
                if (nft_jansson_str2num(data, node_name, BASE_HEX,
-                                       &reg->val[i], NFT_TYPE_U32) != 0)
+                                       &reg->val[i], NFT_TYPE_U32, err) != 0)
                        return -1;
        }
 
@@ -75,23 +78,24 @@ static int nft_data_reg_value_json_parse(union nft_data_reg *reg, json_t *data)
 }
 #endif
 
-int nft_data_reg_json_parse(union nft_data_reg *reg, json_t *data)
+int nft_data_reg_json_parse(union nft_data_reg *reg, json_t *data,
+                           struct nft_parse_err *err)
 {
 #ifdef JSON_PARSING
 
        const char *type;
 
-       type = nft_jansson_parse_str(data, "type");
+       type = nft_jansson_parse_str(data, "type", err);
        if (type == NULL)
                return -1;
 
        /* Select what type of parsing is needed */
        if (strcmp(type, "value") == 0) {
-               return nft_data_reg_value_json_parse(reg, data);
+               return nft_data_reg_value_json_parse(reg, data, err);
        } else if (strcmp(type, "verdict") == 0) {
-               return nft_data_reg_verdict_json_parse(reg, data);
+               return nft_data_reg_verdict_json_parse(reg, data, err);
        } else if (strcmp(type, "chain") == 0) {
-               return nft_data_reg_chain_json_parse(reg, data);
+               return nft_data_reg_chain_json_parse(reg, data, err);
        }
 
        return 0;
@@ -103,13 +107,14 @@ int nft_data_reg_json_parse(union nft_data_reg *reg, json_t *data)
 
 #ifdef XML_PARSING
 static int nft_data_reg_verdict_xml_parse(union nft_data_reg *reg,
-                                         mxml_node_t *tree)
+                                         mxml_node_t *tree,
+                                         struct nft_parse_err *err)
 {
        int verdict;
        const char *verdict_str;
 
        verdict_str = nft_mxml_str_parse(tree, "verdict", MXML_DESCEND_FIRST,
-                                        NFT_XML_MAND);
+                                        NFT_XML_MAND, err);
        if (verdict_str == NULL)
                return DATA_NONE;
 
@@ -123,12 +128,13 @@ static int nft_data_reg_verdict_xml_parse(union nft_data_reg *reg,
 }
 
 static int nft_data_reg_chain_xml_parse(union nft_data_reg *reg,
-                                       mxml_node_t *tree)
+                                       mxml_node_t *tree,
+                                       struct nft_parse_err *err)
 {
        const char *chain;
 
        chain = nft_mxml_str_parse(tree, "chain", MXML_DESCEND_FIRST,
-                                  NFT_XML_MAND);
+                                  NFT_XML_MAND, err);
        if (chain == NULL)
                return DATA_NONE;
 
@@ -140,7 +146,8 @@ static int nft_data_reg_chain_xml_parse(union nft_data_reg *reg,
 }
 
 static int nft_data_reg_value_xml_parse(union nft_data_reg *reg,
-                                       mxml_node_t *tree)
+                                       mxml_node_t *tree,
+                                       struct nft_parse_err *err)
 {
        int i;
        char node_name[6];
@@ -156,7 +163,7 @@ static int nft_data_reg_value_xml_parse(union nft_data_reg *reg,
        */
 
        if (nft_mxml_num_parse(tree, "len", MXML_DESCEND_FIRST, BASE_DEC,
-                              &reg->len, NFT_TYPE_U8, NFT_XML_MAND) != 0)
+                              &reg->len, NFT_TYPE_U8, NFT_XML_MAND, err) != 0)
                return DATA_NONE;
 
        /* Get and set <dataN> */
@@ -165,7 +172,7 @@ static int nft_data_reg_value_xml_parse(union nft_data_reg *reg,
 
                if (nft_mxml_num_parse(tree, node_name, MXML_DESCEND_FIRST,
                                       BASE_HEX, &reg->val[i], NFT_TYPE_U32,
-                                      NFT_XML_MAND) != 0)
+                                      NFT_XML_MAND, err) != 0)
                        return DATA_NONE;
        }
 
@@ -173,7 +180,8 @@ static int nft_data_reg_value_xml_parse(union nft_data_reg *reg,
 }
 #endif
 
-int nft_data_reg_xml_parse(union nft_data_reg *reg, mxml_node_t *tree)
+int nft_data_reg_xml_parse(union nft_data_reg *reg, mxml_node_t *tree,
+                          struct nft_parse_err *err)
 {
 #ifdef XML_PARSING
        const char *type;
@@ -194,11 +202,11 @@ int nft_data_reg_xml_parse(union nft_data_reg *reg, mxml_node_t *tree)
        }
 
        if (strcmp(type, "value") == 0)
-               return nft_data_reg_value_xml_parse(reg, node);
+               return nft_data_reg_value_xml_parse(reg, node, err);
        else if (strcmp(type, "verdict") == 0)
-               return nft_data_reg_verdict_xml_parse(reg, node);
+               return nft_data_reg_verdict_xml_parse(reg, node, err);
        else if (strcmp(type, "chain") == 0)
-               return nft_data_reg_chain_xml_parse(reg, node);
+               return nft_data_reg_chain_xml_parse(reg, node, err);
 
        return DATA_NONE;
 #else
index 8a6a2350159038787e8a20554fe3df09b78d3346..5258051aef683638b9e4d61c72d7352e07ebc9fa 100644 (file)
@@ -29,8 +29,10 @@ union nft_data_reg {
 
 int nft_data_reg_snprintf(char *buf, size_t size, union nft_data_reg *reg,
                         uint32_t output_format, uint32_t flags, int reg_type);
-int nft_data_reg_xml_parse(union nft_data_reg *reg, mxml_node_t *tree);
+int nft_data_reg_xml_parse(union nft_data_reg *reg, mxml_node_t *tree,
+                          struct nft_parse_err *err);
 int nft_parse_data(union nft_data_reg *data, struct nlattr *attr, int *type);
-int nft_data_reg_json_parse(union nft_data_reg *reg, json_t *data);
+int nft_data_reg_json_parse(union nft_data_reg *reg, json_t *data,
+                           struct nft_parse_err *err);
 
 #endif
index 6841ac1d9ae8022065062184f5f6b29dcaafebcb..813830bd3691b55916be54bbbfc9c256ca64e015 100644 (file)
@@ -193,19 +193,20 @@ static inline int str2exthdr_type(const char *str)
 }
 
 static int
-nft_rule_expr_exthdr_json_parse(struct nft_rule_expr *e, json_t *root)
+nft_rule_expr_exthdr_json_parse(struct nft_rule_expr *e, json_t *root,
+                               struct nft_parse_err *err)
 {
 #ifdef JSON_PARSING
        const char *exthdr_type;
        uint32_t uval32;
        int type;
 
-       if (nft_jansson_parse_reg(root, "dreg", NFT_TYPE_U32, &uval32) < 0)
+       if (nft_jansson_parse_reg(root, "dreg", NFT_TYPE_U32, &uval32, err) < 0)
                return -1;
 
        nft_rule_expr_set_u32(e, NFT_EXPR_EXTHDR_DREG, uval32);
 
-       exthdr_type = nft_jansson_parse_str(root, "exthdr_type");
+       exthdr_type = nft_jansson_parse_str(root, "exthdr_type", err);
        if (exthdr_type == NULL)
                return -1;
 
@@ -215,12 +216,12 @@ nft_rule_expr_exthdr_json_parse(struct nft_rule_expr *e, json_t *root)
 
        nft_rule_expr_set_u32(e, NFT_EXPR_EXTHDR_TYPE, type);
 
-       if (nft_jansson_parse_val(root, "offset", NFT_TYPE_U32, &uval32) < 0)
+       if (nft_jansson_parse_val(root, "offset", NFT_TYPE_U32, &uval32, err) < 0)
                return -1;
 
        nft_rule_expr_set_u32(e, NFT_EXPR_EXTHDR_OFFSET, uval32);
 
-       if (nft_jansson_parse_val(root, "len", NFT_TYPE_U32, &uval32) < 0)
+       if (nft_jansson_parse_val(root, "len", NFT_TYPE_U32, &uval32, err) < 0)
                return -1;
 
         nft_rule_expr_set_u32(e, NFT_EXPR_EXTHDR_LEN, uval32);
@@ -233,7 +234,8 @@ nft_rule_expr_exthdr_json_parse(struct nft_rule_expr *e, json_t *root)
 }
 
 static int
-nft_rule_expr_exthdr_xml_parse(struct nft_rule_expr *e, mxml_node_t *tree)
+nft_rule_expr_exthdr_xml_parse(struct nft_rule_expr *e, mxml_node_t *tree,
+                              struct nft_parse_err *err)
 {
 #ifdef XML_PARSING
        struct nft_expr_exthdr *exthdr = nft_expr_data(e);
@@ -241,7 +243,7 @@ nft_rule_expr_exthdr_xml_parse(struct nft_rule_expr *e, mxml_node_t *tree)
        int32_t reg;
        int type;
 
-       reg = nft_mxml_reg_parse(tree, "dreg", MXML_DESCEND_FIRST);
+       reg = nft_mxml_reg_parse(tree, "dreg", MXML_DESCEND_FIRST, err);
        if (reg < 0)
                return -1;
 
@@ -249,7 +251,7 @@ nft_rule_expr_exthdr_xml_parse(struct nft_rule_expr *e, mxml_node_t *tree)
        e->flags |= (1 << NFT_EXPR_EXTHDR_DREG);
 
        exthdr_type = nft_mxml_str_parse(tree, "exthdr_type",
-                                        MXML_DESCEND_FIRST, NFT_XML_MAND);
+                                        MXML_DESCEND_FIRST, NFT_XML_MAND, err);
        if (exthdr_type == NULL)
                return -1;
 
@@ -263,14 +265,15 @@ nft_rule_expr_exthdr_xml_parse(struct nft_rule_expr *e, mxml_node_t *tree)
        /* Get and set <offset> */
        if (nft_mxml_num_parse(tree, "offset", MXML_DESCEND_FIRST, BASE_DEC,
                               &exthdr->offset, NFT_TYPE_U32,
-                              NFT_XML_MAND) != 0)
+                              NFT_XML_MAND, err) != 0)
                return -1;
 
        e->flags |= (1 << NFT_EXPR_EXTHDR_OFFSET);
 
        /* Get and set <len> */
        if (nft_mxml_num_parse(tree, "len", MXML_DESCEND_FIRST, BASE_DEC,
-                              &exthdr->len, NFT_TYPE_U32, NFT_XML_MAND) != 0)
+                              &exthdr->len, NFT_TYPE_U32, NFT_XML_MAND,
+                              err) != 0)
                return -1;
 
        e->flags |= (1 << NFT_EXPR_EXTHDR_LEN);
index a96d3dea6b4c54294a980c5d06f35aadc6f6a10d..3ae4082454b4957921ef502a9843279647c2e76b 100644 (file)
@@ -178,20 +178,21 @@ nft_rule_expr_immediate_parse(struct nft_rule_expr *e, struct nlattr *attr)
 }
 
 static int
-nft_rule_expr_immediate_json_parse(struct nft_rule_expr *e, json_t *root)
+nft_rule_expr_immediate_json_parse(struct nft_rule_expr *e, json_t *root,
+                                  struct nft_parse_err *err)
 {
 #ifdef JSON_PARSING
        struct nft_expr_immediate *imm = nft_expr_data(e);
        int datareg_type;
        uint32_t reg;
 
-       if (nft_jansson_parse_reg(root, "dreg", NFT_TYPE_U32, &reg) < 0)
+       if (nft_jansson_parse_reg(root, "dreg", NFT_TYPE_U32, &reg, err) < 0)
                return -1;
 
        nft_rule_expr_set_u32(e, NFT_EXPR_IMM_DREG, reg);
 
        datareg_type = nft_jansson_data_reg_parse(root, "immediatedata",
-                                                 &imm->data);
+                                                 &imm->data, err);
        if (datareg_type < 0)
                return -1;
 
@@ -217,14 +218,15 @@ nft_rule_expr_immediate_json_parse(struct nft_rule_expr *e, json_t *root)
 }
 
 static int
-nft_rule_expr_immediate_xml_parse(struct nft_rule_expr *e, mxml_node_t *tree)
+nft_rule_expr_immediate_xml_parse(struct nft_rule_expr *e, mxml_node_t *tree,
+                                 struct nft_parse_err *err)
 {
 #ifdef XML_PARSING
        struct nft_expr_immediate *imm = nft_expr_data(e);
        int datareg_type;
        int32_t reg;
 
-       reg = nft_mxml_reg_parse(tree, "dreg", MXML_DESCEND_FIRST);
+       reg = nft_mxml_reg_parse(tree, "dreg", MXML_DESCEND_FIRST, err);
        if (reg < 0)
                return -1;
 
@@ -232,7 +234,7 @@ nft_rule_expr_immediate_xml_parse(struct nft_rule_expr *e, mxml_node_t *tree)
        e->flags |= (1 << NFT_EXPR_IMM_DREG);
 
        datareg_type = nft_mxml_data_reg_parse(tree, "immediatedata",
-                                              &imm->data, NFT_XML_MAND);
+                                              &imm->data, NFT_XML_MAND, err);
        switch (datareg_type) {
        case DATA_VALUE:
                e->flags |= (1 << NFT_EXPR_IMM_DATA);
index 4854a7707661e44548e9e9f70fcd4b41554247dd..e6b0492c296b31c76c9da408a848065a5b9eb219 100644 (file)
@@ -118,17 +118,18 @@ nft_rule_expr_limit_parse(struct nft_rule_expr *e, struct nlattr *attr)
        return 0;
 }
 
-static int nft_rule_expr_limit_json_parse(struct nft_rule_expr *e, json_t *root)
+static int nft_rule_expr_limit_json_parse(struct nft_rule_expr *e, json_t *root,
+                                         struct nft_parse_err *err)
 {
 #ifdef JSON_PARSING
        uint64_t uval64;
 
-       if (nft_jansson_parse_val(root, "rate", NFT_TYPE_U64, &uval64) < 0)
+       if (nft_jansson_parse_val(root, "rate", NFT_TYPE_U64, &uval64, err) < 0)
                return -1;
 
        nft_rule_expr_set_u64(e, NFT_EXPR_LIMIT_RATE, uval64);
 
-       if (nft_jansson_parse_val(root, "unit", NFT_TYPE_U64, &uval64) < 0)
+       if (nft_jansson_parse_val(root, "unit", NFT_TYPE_U64, &uval64, err) < 0)
                return -1;
 
        nft_rule_expr_set_u64(e, NFT_EXPR_LIMIT_UNIT, uval64);
@@ -140,19 +141,23 @@ static int nft_rule_expr_limit_json_parse(struct nft_rule_expr *e, json_t *root)
 #endif
 }
 
-static int nft_rule_expr_limit_xml_parse(struct nft_rule_expr *e, mxml_node_t *tree)
+static int nft_rule_expr_limit_xml_parse(struct nft_rule_expr *e,
+                                        mxml_node_t *tree,
+                                        struct nft_parse_err *err)
 {
 #ifdef XML_PARSING
        struct nft_expr_limit *limit = nft_expr_data(e);
 
        if (nft_mxml_num_parse(tree, "rate", MXML_DESCEND_FIRST, BASE_DEC,
-                              &limit->rate, NFT_TYPE_U64, NFT_XML_MAND) != 0)
+                              &limit->rate, NFT_TYPE_U64, NFT_XML_MAND,
+                              err) != 0)
                return -1;
 
        e->flags |= (1 << NFT_EXPR_LIMIT_RATE);
 
        if (nft_mxml_num_parse(tree, "unit", MXML_DESCEND_FIRST, BASE_DEC,
-                              &limit->unit, NFT_TYPE_U64, NFT_XML_MAND) != 0)
+                              &limit->unit, NFT_TYPE_U64, NFT_XML_MAND,
+                              err) != 0)
                return -1;
 
        e->flags |= (1 << NFT_EXPR_LIMIT_UNIT);
index 76657a908a074b2842c729f147a3d859f77b3a7a..c62a8b453b201a9f59e6a5bee7319623753a3ea4 100644 (file)
@@ -160,31 +160,34 @@ nft_rule_expr_log_parse(struct nft_rule_expr *e, struct nlattr *attr)
        return 0;
 }
 
-static int nft_rule_expr_log_json_parse(struct nft_rule_expr *e, json_t *root)
+static int nft_rule_expr_log_json_parse(struct nft_rule_expr *e, json_t *root,
+                                       struct nft_parse_err *err)
 {
 #ifdef JSON_PARSING
        const char *prefix;
        uint32_t snaplen;
        uint16_t uval16;
 
-       prefix = nft_jansson_parse_str(root, "prefix");
+       prefix = nft_jansson_parse_str(root, "prefix", err);
        if (prefix == NULL)
                return -1;
 
        nft_rule_expr_set_str(e, NFT_EXPR_LOG_PREFIX, prefix);
 
-       if (nft_jansson_parse_val(root, "group", NFT_TYPE_U16, &uval16) < 0)
+       if (nft_jansson_parse_val(root, "group", NFT_TYPE_U16, &uval16,
+                                 err) < 0)
                return -1;
 
        nft_rule_expr_set_u16(e, NFT_EXPR_LOG_GROUP, uval16);
 
-       if (nft_jansson_parse_val(root, "snaplen", NFT_TYPE_U32, &snaplen) < 0)
+       if (nft_jansson_parse_val(root, "snaplen", NFT_TYPE_U32, &snaplen,
+                                 err) < 0)
                return -1;
 
        nft_rule_expr_set_u32(e, NFT_EXPR_LOG_SNAPLEN, snaplen);
 
        if (nft_jansson_parse_val(root, "qthreshold", NFT_TYPE_U16,
-                                 &uval16) < 0)
+                                 &uval16, err) < 0)
                return -1;
 
        nft_rule_expr_set_u16(e, NFT_EXPR_LOG_QTHRESHOLD, uval16);
@@ -196,14 +199,16 @@ static int nft_rule_expr_log_json_parse(struct nft_rule_expr *e, json_t *root)
 #endif
 }
 
-static int nft_rule_expr_log_xml_parse(struct nft_rule_expr *e, mxml_node_t *tree)
+static int nft_rule_expr_log_xml_parse(struct nft_rule_expr *e,
+                                      mxml_node_t *tree,
+                                      struct nft_parse_err *err)
 {
 #ifdef XML_PARSING
        struct nft_expr_log *log = nft_expr_data(e);
        const char *prefix;
 
        prefix = nft_mxml_str_parse(tree, "prefix", MXML_DESCEND_FIRST,
-                                   NFT_XML_MAND);
+                                   NFT_XML_MAND, err);
        if (prefix == NULL)
                return -1;
 
@@ -211,20 +216,22 @@ static int nft_rule_expr_log_xml_parse(struct nft_rule_expr *e, mxml_node_t *tre
        e->flags |= (1 << NFT_EXPR_LOG_PREFIX);
 
        if (nft_mxml_num_parse(tree, "group", MXML_DESCEND_FIRST, BASE_DEC,
-                              &log->group, NFT_TYPE_U16, NFT_XML_MAND) != 0)
+                              &log->group, NFT_TYPE_U16, NFT_XML_MAND,
+                              err) != 0)
                return -1;
 
        e->flags |= (1 << NFT_EXPR_LOG_GROUP);
 
        if (nft_mxml_num_parse(tree, "snaplen", MXML_DESCEND_FIRST, BASE_DEC,
-                              &log->snaplen, NFT_TYPE_U32, NFT_XML_MAND) != 0)
+                              &log->snaplen, NFT_TYPE_U32, NFT_XML_MAND,
+                              err) != 0)
                return -1;
 
        e->flags |= (1 << NFT_EXPR_LOG_SNAPLEN);
 
        if (nft_mxml_num_parse(tree, "qthreshold", MXML_DESCEND_FIRST,
                               BASE_DEC, &log->qthreshold,
-                              NFT_TYPE_U16, NFT_XML_MAND) != 0)
+                              NFT_TYPE_U16, NFT_XML_MAND, err) != 0)
                return -1;
 
        e->flags |= (1 << NFT_EXPR_LOG_QTHRESHOLD);
index 4e91cfb79c608fb43bb2a1cddd594fe9bed82fec..b0aadf2c5d2871e835f9b21f095fb2674b150bdf 100644 (file)
@@ -143,24 +143,25 @@ nft_rule_expr_lookup_parse(struct nft_rule_expr *e, struct nlattr *attr)
 }
 
 static int
-nft_rule_expr_lookup_json_parse(struct nft_rule_expr *e, json_t *root)
+nft_rule_expr_lookup_json_parse(struct nft_rule_expr *e, json_t *root,
+                               struct nft_parse_err *err)
 {
 #ifdef JSON_PARSING
        const char *set_name;
        int32_t reg;
 
-       set_name = nft_jansson_parse_str(root, "set");
+       set_name = nft_jansson_parse_str(root, "set", err);
        if (set_name == NULL)
                return -1;
 
        nft_rule_expr_set_str(e, NFT_EXPR_LOOKUP_SET, set_name);
 
-       if (nft_jansson_parse_reg(root, "sreg", NFT_TYPE_U32, &reg) < 0)
+       if (nft_jansson_parse_reg(root, "sreg", NFT_TYPE_U32, &reg, err) < 0)
                return -1;
 
        nft_rule_expr_set_u32(e, NFT_EXPR_LOOKUP_SREG, reg);
 
-       if (nft_jansson_parse_reg(root, "dreg", NFT_TYPE_U32, &reg) < 0)
+       if (nft_jansson_parse_reg(root, "dreg", NFT_TYPE_U32, &reg, err) < 0)
                return -1;
 
        nft_rule_expr_set_u32(e, NFT_EXPR_LOOKUP_DREG, reg);
@@ -173,7 +174,8 @@ nft_rule_expr_lookup_json_parse(struct nft_rule_expr *e, json_t *root)
 }
 
 static int
-nft_rule_expr_lookup_xml_parse(struct nft_rule_expr *e, mxml_node_t *tree)
+nft_rule_expr_lookup_xml_parse(struct nft_rule_expr *e, mxml_node_t *tree,
+                              struct nft_parse_err *err)
 {
 #ifdef XML_PARSING
        struct nft_expr_lookup *lookup = nft_expr_data(e);
@@ -181,7 +183,7 @@ nft_rule_expr_lookup_xml_parse(struct nft_rule_expr *e, mxml_node_t *tree)
        int32_t reg;
 
        set_name = nft_mxml_str_parse(tree, "set", MXML_DESCEND_FIRST,
-                                     NFT_XML_MAND);
+                                     NFT_XML_MAND, err);
        if (set_name == NULL)
                return -1;
 
@@ -189,14 +191,14 @@ nft_rule_expr_lookup_xml_parse(struct nft_rule_expr *e, mxml_node_t *tree)
        lookup->set_name[IFNAMSIZ-1] = '\0';
        e->flags |= (1 << NFT_EXPR_LOOKUP_SET);
 
-       reg = nft_mxml_reg_parse(tree, "sreg", MXML_DESCEND);
+       reg = nft_mxml_reg_parse(tree, "sreg", MXML_DESCEND, err);
        if (reg < 0)
                return -1;
 
        lookup->sreg = reg;
        e->flags |= (1 << NFT_EXPR_LOOKUP_SREG);
 
-       reg = nft_mxml_reg_parse(tree, "dreg", MXML_DESCEND);
+       reg = nft_mxml_reg_parse(tree, "dreg", MXML_DESCEND, err);
        if (reg < 0)
                return -1;
 
index c7863b8785c9a97031c6373d53c624092aadee60..5487050ddc65977f4efbe91731d515ece492c47a 100644 (file)
@@ -170,12 +170,13 @@ static int nft_rule_expr_match_parse(struct nft_rule_expr *e, struct nlattr *att
        return 0;
 }
 
-static int nft_rule_expr_match_json_parse(struct nft_rule_expr *e, json_t *root)
+static int nft_rule_expr_match_json_parse(struct nft_rule_expr *e, json_t *root,
+                                         struct nft_parse_err *err)
 {
 #ifdef JSON_PARSING
        const char *name;
 
-       name = nft_jansson_parse_str(root, "name");
+       name = nft_jansson_parse_str(root, "name", err);
        if (name == NULL)
                return -1;
 
@@ -189,14 +190,15 @@ static int nft_rule_expr_match_json_parse(struct nft_rule_expr *e, json_t *root)
 }
 
 
-static int nft_rule_expr_match_xml_parse(struct nft_rule_expr *e, mxml_node_t *tree)
+static int nft_rule_expr_match_xml_parse(struct nft_rule_expr *e, mxml_node_t *tree,
+                                        struct nft_parse_err *err)
 {
 #ifdef XML_PARSING
        struct nft_expr_match *mt = nft_expr_data(e);
        const char *name;
 
        name = nft_mxml_str_parse(tree, "name", MXML_DESCEND_FIRST,
-                                 NFT_XML_MAND);
+                                 NFT_XML_MAND, err);
        if (name == NULL)
                return -1;
 
index 88d29087047b7b672c760c7d0f1fd5c7f1ab1b6e..3c5fd77575c334b2b397402ae7de840ac70e861f 100644 (file)
@@ -160,19 +160,20 @@ static inline int str2meta_key(const char *str)
        return -1;
 }
 
-static int nft_rule_expr_meta_json_parse(struct nft_rule_expr *e, json_t *root)
+static int nft_rule_expr_meta_json_parse(struct nft_rule_expr *e, json_t *root,
+                                        struct nft_parse_err *err)
 {
 #ifdef JSON_PARSING
        const char *key_str;
        uint32_t reg;
        int key;
 
-       if (nft_jansson_parse_reg(root, "dreg", NFT_TYPE_U32, &reg) < 0)
+       if (nft_jansson_parse_reg(root, "dreg", NFT_TYPE_U32, &reg, err) < 0)
                 return -1;
 
        nft_rule_expr_set_u32(e, NFT_EXPR_META_DREG, reg);
 
-       key_str = nft_jansson_parse_str(root, "key");
+       key_str = nft_jansson_parse_str(root, "key", err);
        if (key_str == NULL)
                return -1;
 
@@ -190,7 +191,8 @@ static int nft_rule_expr_meta_json_parse(struct nft_rule_expr *e, json_t *root)
 }
 
 
-static int nft_rule_expr_meta_xml_parse(struct nft_rule_expr *e, mxml_node_t *tree)
+static int nft_rule_expr_meta_xml_parse(struct nft_rule_expr *e, mxml_node_t *tree,
+                                       struct nft_parse_err *err)
 {
 #ifdef XML_PARSING
        struct nft_expr_meta *meta = nft_expr_data(e);
@@ -198,7 +200,7 @@ static int nft_rule_expr_meta_xml_parse(struct nft_rule_expr *e, mxml_node_t *tr
        int32_t reg;
        int key;
 
-       reg = nft_mxml_reg_parse(tree, "dreg", MXML_DESCEND_FIRST);
+       reg = nft_mxml_reg_parse(tree, "dreg", MXML_DESCEND_FIRST, err);
        if (reg < 0)
                 return -1;
 
@@ -206,7 +208,7 @@ static int nft_rule_expr_meta_xml_parse(struct nft_rule_expr *e, mxml_node_t *tr
        e->flags |= (1 << NFT_EXPR_META_DREG);
 
        key_str = nft_mxml_str_parse(tree, "key", MXML_DESCEND_FIRST,
-                                    NFT_XML_MAND);
+                                    NFT_XML_MAND, err);
        if (key_str == NULL)
                return -1;
 
index 30b02eca3bf74ec406190bb428be50c34d42981b..34a977a393ebaa0e9fbf1ca06dc7270bfd6f5a7b 100644 (file)
@@ -196,14 +196,15 @@ static inline int nft_str2nat(const char *nat)
        }
 }
 
-static int nft_rule_expr_nat_json_parse(struct nft_rule_expr *e, json_t *root)
+static int nft_rule_expr_nat_json_parse(struct nft_rule_expr *e, json_t *root,
+                                       struct nft_parse_err *err)
 {
 #ifdef JSON_PARSING
        const char *nat_type, *family_str;
        uint32_t reg;
        int val32;
 
-       nat_type = nft_jansson_parse_str(root, "nat_type");
+       nat_type = nft_jansson_parse_str(root, "nat_type", err);
        if (nat_type == NULL)
                return -1;
 
@@ -213,7 +214,7 @@ static int nft_rule_expr_nat_json_parse(struct nft_rule_expr *e, json_t *root)
 
        nft_rule_expr_set_u32(e, NFT_EXPR_NAT_TYPE, val32);
 
-       family_str = nft_jansson_parse_str(root, "family");
+       family_str = nft_jansson_parse_str(root, "family", err);
        if (family_str == NULL)
                return -1;
 
@@ -224,25 +225,25 @@ static int nft_rule_expr_nat_json_parse(struct nft_rule_expr *e, json_t *root)
        nft_rule_expr_set_u32(e, NFT_EXPR_NAT_FAMILY, val32);
 
        if (nft_jansson_parse_reg(root, "sreg_addr_min", NFT_TYPE_U32,
-                                 &reg) < 0)
+                                 &reg, err) < 0)
                return -1;
 
        nft_rule_expr_set_u32(e, NFT_EXPR_NAT_REG_ADDR_MIN, reg);
 
        if (nft_jansson_parse_reg(root, "sreg_addr_max", NFT_TYPE_U32,
-                                 &reg) < 0)
+                                 &reg, err) < 0)
                return -1;
 
        nft_rule_expr_set_u32(e, NFT_EXPR_NAT_REG_ADDR_MAX, reg);
 
        if (nft_jansson_parse_reg(root, "sreg_proto_min", NFT_TYPE_U32,
-                                 &reg) < 0)
+                                 &reg, err) < 0)
                return -1;
 
        nft_rule_expr_set_u32(e, NFT_EXPR_NAT_REG_PROTO_MIN, reg);
 
        if (nft_jansson_parse_reg(root, "sreg_proto_max", NFT_TYPE_U32,
-                                 &reg) < 0)
+                                 &reg, err) < 0)
                return -1;
 
        nft_rule_expr_set_u32(e, NFT_EXPR_NAT_REG_PROTO_MAX, reg);
@@ -254,7 +255,8 @@ static int nft_rule_expr_nat_json_parse(struct nft_rule_expr *e, json_t *root)
 #endif
 }
 
-static int nft_rule_expr_nat_xml_parse(struct nft_rule_expr *e, mxml_node_t *tree)
+static int nft_rule_expr_nat_xml_parse(struct nft_rule_expr *e, mxml_node_t *tree,
+                                      struct nft_parse_err *err)
 {
 #ifdef XML_PARSING
        struct nft_expr_nat *nat = nft_expr_data(e);
@@ -263,7 +265,7 @@ static int nft_rule_expr_nat_xml_parse(struct nft_rule_expr *e, mxml_node_t *tre
        int family, nat_type_value;
 
        nat_type = nft_mxml_str_parse(tree, "type", MXML_DESCEND_FIRST,
-                                     NFT_XML_MAND);
+                                     NFT_XML_MAND, err);
        if (nat_type == NULL)
                return -1;
 
@@ -275,7 +277,7 @@ static int nft_rule_expr_nat_xml_parse(struct nft_rule_expr *e, mxml_node_t *tre
        e->flags |= (1 << NFT_EXPR_NAT_TYPE);
 
        family = nft_mxml_family_parse(tree, "family", MXML_DESCEND_FIRST,
-                                      NFT_XML_MAND);
+                                      NFT_XML_MAND, err);
        if (family < 0) {
                mxmlDelete(tree);
                return -1;
@@ -284,28 +286,28 @@ static int nft_rule_expr_nat_xml_parse(struct nft_rule_expr *e, mxml_node_t *tre
        nat->family = family;
        e->flags |= (1 << NFT_EXPR_NAT_FAMILY);
 
-       reg = nft_mxml_reg_parse(tree, "sreg_addr_min", MXML_DESCEND);
+       reg = nft_mxml_reg_parse(tree, "sreg_addr_min", MXML_DESCEND, err);
        if (reg < 0)
                return -1;
 
        nat->sreg_addr_min = reg;
        e->flags |= (1 << NFT_EXPR_NAT_REG_ADDR_MIN);
 
-       reg = nft_mxml_reg_parse(tree, "sreg_addr_max", MXML_DESCEND);
+       reg = nft_mxml_reg_parse(tree, "sreg_addr_max", MXML_DESCEND, err);
        if (reg < 0)
                return -1;
 
        nat->sreg_addr_max = reg;
        e->flags |= (1 << NFT_EXPR_NAT_REG_ADDR_MAX);
 
-       reg = nft_mxml_reg_parse(tree, "sreg_proto_min", MXML_DESCEND);
+       reg = nft_mxml_reg_parse(tree, "sreg_proto_min", MXML_DESCEND, err);
        if (reg < 0)
                return -1;
 
        nat->sreg_proto_min = reg;
        e->flags |= (1 << NFT_EXPR_NAT_REG_PROTO_MIN);
 
-       reg = nft_mxml_reg_parse(tree, "sreg_proto_max", MXML_DESCEND);
+       reg = nft_mxml_reg_parse(tree, "sreg_proto_max", MXML_DESCEND, err);
        if (reg < 0)
                return -1;
 
index fc32ff2dea9dfcd57813e4cab79775b8076d43a2..911bb01be97d0847891c6137712f63d349fda483 100644 (file)
@@ -194,19 +194,20 @@ static inline int nft_str2base(const char *base)
 }
 
 static int
-nft_rule_expr_payload_json_parse(struct nft_rule_expr *e, json_t *root)
+nft_rule_expr_payload_json_parse(struct nft_rule_expr *e, json_t *root,
+                                struct nft_parse_err *err)
 {
 #ifdef JSON_PARSING
        const char *base_str;
        uint32_t reg, uval32;
        int base;
 
-       if (nft_jansson_parse_reg(root, "dreg", NFT_TYPE_U32, &reg) < 0)
+       if (nft_jansson_parse_reg(root, "dreg", NFT_TYPE_U32, &reg, err) < 0)
                return -1;
 
        nft_rule_expr_set_u32(e, NFT_EXPR_PAYLOAD_DREG, reg);
 
-       base_str = nft_jansson_parse_str(root, "base");
+       base_str = nft_jansson_parse_str(root, "base", err);
        if (base_str == NULL)
                return -1;
 
@@ -216,12 +217,13 @@ nft_rule_expr_payload_json_parse(struct nft_rule_expr *e, json_t *root)
 
        nft_rule_expr_set_u32(e, NFT_EXPR_PAYLOAD_BASE, base);
 
-       if (nft_jansson_parse_val(root, "offset", NFT_TYPE_U32, &uval32) < 0)
+       if (nft_jansson_parse_val(root, "offset", NFT_TYPE_U32, &uval32,
+                                 err) < 0)
                return -1;
 
        nft_rule_expr_set_u32(e, NFT_EXPR_PAYLOAD_OFFSET, uval32);
 
-       if (nft_jansson_parse_val(root, "len", NFT_TYPE_U32, &uval32) < 0)
+       if (nft_jansson_parse_val(root, "len", NFT_TYPE_U32, &uval32, err) < 0)
                return -1;
 
        nft_rule_expr_set_u32(e, NFT_EXPR_PAYLOAD_LEN, uval32);
@@ -234,14 +236,15 @@ nft_rule_expr_payload_json_parse(struct nft_rule_expr *e, json_t *root)
 }
 
 static int
-nft_rule_expr_payload_xml_parse(struct nft_rule_expr *e, mxml_node_t *tree)
+nft_rule_expr_payload_xml_parse(struct nft_rule_expr *e, mxml_node_t *tree,
+                               struct nft_parse_err *err)
 {
 #ifdef XML_PARSING
        struct nft_expr_payload *payload = nft_expr_data(e);
        const char *base_str;
        int32_t reg, base;
 
-       reg = nft_mxml_reg_parse(tree, "dreg", MXML_DESCEND_FIRST);
+       reg = nft_mxml_reg_parse(tree, "dreg", MXML_DESCEND_FIRST, err);
        if (reg < 0)
                return -1;
 
@@ -249,7 +252,7 @@ nft_rule_expr_payload_xml_parse(struct nft_rule_expr *e, mxml_node_t *tree)
        e->flags |= (1 << NFT_EXPR_PAYLOAD_DREG);
 
        base_str = nft_mxml_str_parse(tree, "base", MXML_DESCEND_FIRST,
-                                     NFT_XML_MAND);
+                                     NFT_XML_MAND, err);
        if (base_str == NULL)
                return -1;
 
@@ -262,13 +265,14 @@ nft_rule_expr_payload_xml_parse(struct nft_rule_expr *e, mxml_node_t *tree)
 
        if (nft_mxml_num_parse(tree, "offset", MXML_DESCEND_FIRST, BASE_DEC,
                               &payload->offset, NFT_TYPE_U8,
-                              NFT_XML_MAND) != 0)
+                              NFT_XML_MAND, err) != 0)
                return -1;
 
        e->flags |= (1 << NFT_EXPR_PAYLOAD_OFFSET);
 
        if (nft_mxml_num_parse(tree, "len", MXML_DESCEND_FIRST, BASE_DEC,
-                              &payload->len, NFT_TYPE_U8, NFT_XML_MAND) != 0)
+                              &payload->len, NFT_TYPE_U8,
+                              NFT_XML_MAND, err) != 0)
                return -1;
 
        e->flags |= (1 << NFT_EXPR_PAYLOAD_LEN);
index 848f004b2997b21b68aaffb6c86fb79d1a0ace6b..c06b07063388c80b3e3cb82b9f890a25f530a049 100644 (file)
@@ -122,18 +122,19 @@ nft_rule_expr_reject_parse(struct nft_rule_expr *e, struct nlattr *attr)
 }
 
 static int
-nft_rule_expr_reject_json_parse(struct nft_rule_expr *e, json_t *root)
+nft_rule_expr_reject_json_parse(struct nft_rule_expr *e, json_t *root,
+                               struct nft_parse_err *err)
 {
 #ifdef JSON_PARSING
        uint32_t type;
        uint16_t code;
 
-       if (nft_jansson_parse_val(root, "type", NFT_TYPE_U32, &type) < 0)
+       if (nft_jansson_parse_val(root, "type", NFT_TYPE_U32, &type, err) < 0)
                return -1;
 
        nft_rule_expr_set_u32(e, NFT_EXPR_REJECT_TYPE, type);
 
-       if (nft_jansson_parse_val(root, "code", NFT_TYPE_U8, &code) < 0)
+       if (nft_jansson_parse_val(root, "code", NFT_TYPE_U8, &code, err) < 0)
                return -1;
 
        nft_rule_expr_set_u8(e, NFT_EXPR_REJECT_CODE, code);
@@ -146,19 +147,22 @@ nft_rule_expr_reject_json_parse(struct nft_rule_expr *e, json_t *root)
 }
 
 static int
-nft_rule_expr_reject_xml_parse(struct nft_rule_expr *e, mxml_node_t *tree)
+nft_rule_expr_reject_xml_parse(struct nft_rule_expr *e, mxml_node_t *tree,
+                              struct nft_parse_err *err)
 {
 #ifdef XML_PARSING
        struct nft_expr_reject *reject = nft_expr_data(e);
 
        if (nft_mxml_num_parse(tree, "type", MXML_DESCEND_FIRST, BASE_DEC,
-                              &reject->type, NFT_TYPE_U32, NFT_XML_MAND) != 0)
+                              &reject->type, NFT_TYPE_U32, NFT_XML_MAND,
+                              err) != 0)
                return -1;
 
        e->flags |= (1 << NFT_EXPR_REJECT_TYPE);
 
        if (nft_mxml_num_parse(tree, "code", MXML_DESCEND_FIRST, BASE_DEC,
-                              &reject->icmp_code, NFT_TYPE_U8, NFT_XML_MAND) != 0)
+                              &reject->icmp_code, NFT_TYPE_U8, NFT_XML_MAND,
+                              err) != 0)
                return -1;
 
        e->flags |= (1 << NFT_EXPR_REJECT_CODE);
index 23dff3af07d26493dbf0b4cfd3775d6129847929..071fb07042258db08f3f8028be3be7e40d274686 100644 (file)
@@ -171,12 +171,13 @@ static int nft_rule_expr_target_parse(struct nft_rule_expr *e, struct nlattr *at
 }
 
 static int
-nft_rule_expr_target_json_parse(struct nft_rule_expr *e, json_t *root)
+nft_rule_expr_target_json_parse(struct nft_rule_expr *e, json_t *root,
+                               struct nft_parse_err *err)
 {
 #ifdef JSON_PARSING
        const char *name;
 
-       name = nft_jansson_parse_str(root, "name");
+       name = nft_jansson_parse_str(root, "name", err);
        if (name == NULL)
                return -1;
 
@@ -190,14 +191,15 @@ nft_rule_expr_target_json_parse(struct nft_rule_expr *e, json_t *root)
 }
 
 static int
-nft_rule_expr_target_xml_parse(struct nft_rule_expr *e, mxml_node_t *tree)
+nft_rule_expr_target_xml_parse(struct nft_rule_expr *e, mxml_node_t *tree,
+                              struct nft_parse_err *err)
 {
 #ifdef XML_PARSING
        struct nft_expr_target *tg = nft_expr_data(e);
        const char *name;
 
        name = nft_mxml_str_parse(tree, "name", MXML_DESCEND_FIRST,
-                                 NFT_XML_MAND);
+                                 NFT_XML_MAND, err);
        if (name == NULL)
                return -1;
 
index 26e0b8249019c0b08f18593f02780cd657533046..b06f5754d2c986ae557302ea8473a92f54b1fa6c 100644 (file)
@@ -29,8 +29,10 @@ 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, mxml_node_t *tree);
-       int     (*json_parse)(struct nft_rule_expr *e, json_t *data);
+       int     (*xml_parse)(struct nft_rule_expr *e, mxml_node_t *tree,
+                            struct nft_parse_err *err);
+       int     (*json_parse)(struct nft_rule_expr *e, json_t *data,
+                             struct nft_parse_err *err);
 };
 
 void nft_expr_ops_register(struct expr_ops *ops);
index f975ad1fce5f32c2cd974f67b4e86425698bf485..9ef505f14d3d728ca471d112f98779a62551b323 100644 (file)
@@ -13,6 +13,7 @@
 
 #include <stdint.h>
 #include <stdbool.h>
+#include <libnftables/common.h>
 
 #define BASE_DEC 10
 #define BASE_HEX 16
@@ -30,59 +31,94 @@ enum nft_type {
        NFT_TYPE_S64,
 };
 
+struct nft_parse_err {
+       int line;
+       int column;
+       int error;
+       const char *node_name;
+};
+
 #ifdef XML_PARSING
 #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);
+mxml_node_t *nft_mxml_build_tree(const char *xml, const char *treename,
+                                struct nft_parse_err *err);
+struct nft_rule_expr *nft_mxml_expr_parse(mxml_node_t *node,
+                                         struct nft_parse_err *err);
+int nft_mxml_reg_parse(mxml_node_t *tree, const char *reg_name, uint32_t flags,
+                      struct nft_parse_err *err);
 union nft_data_reg;
-int nft_mxml_data_reg_parse(mxml_node_t *tree, const char *node_name, union nft_data_reg *data_reg, uint16_t flags);
-int nft_mxml_num_parse(mxml_node_t *tree, const char *node_name, uint32_t mxml_flags, int base, void *number, enum nft_type type, uint16_t flags);
-const char *nft_mxml_str_parse(mxml_node_t *tree, const char *node_name, uint32_t mxml_flags, uint16_t flags);
-int nft_mxml_family_parse(mxml_node_t *tree, const char *node_name, uint32_t mxml_flags, uint16_t flags);
+int nft_mxml_data_reg_parse(mxml_node_t *tree, const char *node_name,
+                           union nft_data_reg *data_reg, uint16_t flags,
+                           struct nft_parse_err *err);
+int nft_mxml_num_parse(mxml_node_t *tree, const char *node_name,
+                      uint32_t mxml_flags, int base, void *number,
+                      enum nft_type type, uint16_t flags,
+                      struct nft_parse_err *err);
+const char *nft_mxml_str_parse(mxml_node_t *tree, const char *node_name,
+                              uint32_t mxml_flags, uint16_t flags,
+                              struct nft_parse_err *err);
+int nft_mxml_family_parse(mxml_node_t *tree, const char *node_name,
+                         uint32_t mxml_flags, uint16_t flags,
+                         struct nft_parse_err *err);
 
 struct nft_set_elem;
-int nft_mxml_set_elem_parse(mxml_node_t *node, struct nft_set_elem *e);
+int nft_mxml_set_elem_parse(mxml_node_t *node, struct nft_set_elem *e,
+                           struct nft_parse_err *err);
 struct nft_table;
-int nft_mxml_table_parse(mxml_node_t *tree, struct nft_table *t);
+int nft_mxml_table_parse(mxml_node_t *tree, struct nft_table *t,
+                        struct nft_parse_err *err);
 struct nft_chain;
-int nft_mxml_chain_parse(mxml_node_t *tree, struct nft_chain *c);
+int nft_mxml_chain_parse(mxml_node_t *tree, struct nft_chain *c,
+                        struct nft_parse_err *err);
 struct nft_rule;
-int nft_mxml_rule_parse(mxml_node_t *tree, struct nft_rule *r);
+int nft_mxml_rule_parse(mxml_node_t *tree, struct nft_rule *r,
+                       struct nft_parse_err *err);
 struct nft_set;
-int nft_mxml_set_parse(mxml_node_t *tree, struct nft_set *s);
+int nft_mxml_set_parse(mxml_node_t *tree, struct nft_set *s,
+                      struct nft_parse_err *err);
 #endif
 
 #ifdef JSON_PARSING
 #include <jansson.h>
+
 int nft_jansson_parse_val(json_t *root, const char *node_name, int type,
-                         void *out);
-const char *nft_jansson_parse_str(json_t *root, const char *node_name);
+                         void *out, struct nft_parse_err *err);
+const char *nft_jansson_parse_str(json_t *root, const char *node_name,
+                                 struct nft_parse_err *err);
 bool nft_jansson_node_exist(json_t *root, const char *node_name);
-json_t *nft_jansson_create_root(const char *json, json_error_t *err);
-json_t *nft_jansson_get_node(json_t *root, const char *node_name);
+json_t *nft_jansson_create_root(const char *json, json_error_t *error,
+                               struct nft_parse_err *err);
+json_t *nft_jansson_get_node(json_t *root, const char *node_name,
+                            struct nft_parse_err *err);
 void nft_jansson_free_root(json_t *root);
-int nft_jansson_parse_family(json_t *root, void *out);
-int nft_jansson_str2num(json_t *root, const char *node_name, int base,
-                       void *out, enum nft_type type);
+int nft_jansson_parse_family(json_t *root, void *out, struct nft_parse_err *err);
+int nft_jansson_str2num(json_t *root, const char *node_name, int base, void *out,
+                       enum nft_type type, struct nft_parse_err *err);
 int nft_jansson_parse_reg(json_t *root, const char *node_name, int type,
-                         void *out);
-struct nft_rule_expr *nft_jansson_expr_parse(json_t *root);
+                         void *out, struct nft_parse_err *err);
+struct nft_rule_expr *nft_jansson_expr_parse(json_t *root,
+                                            struct nft_parse_err *err);
 union nft_data_reg;
 int nft_jansson_data_reg_parse(json_t *root, const char *node_name,
-                              union nft_data_reg *data_reg);
+                              union nft_data_reg *data_reg,
+                              struct nft_parse_err *err);
 struct nft_set_elem;
-int nft_set_elem_json_parse(struct nft_set_elem *e, json_t *root);
+int nft_set_elem_json_parse(struct nft_set_elem *e, json_t *root,
+                           struct nft_parse_err *err);
 struct nft_table;
-int nft_jansson_parse_table(struct nft_table *t, json_t *tree);
+int nft_jansson_parse_table(struct nft_table *t, json_t *tree,
+                           struct nft_parse_err *err);
 struct nft_chain;
-int nft_jansson_parse_chain(struct nft_chain *c, json_t *tree);
+int nft_jansson_parse_chain(struct nft_chain *c, json_t *tree,
+                           struct nft_parse_err *err);
 struct nft_rule;
-int nft_jansson_parse_rule(struct nft_rule *r, json_t *tree);
+int nft_jansson_parse_rule(struct nft_rule *r, json_t *tree,
+                          struct nft_parse_err *err);
 struct nft_set;
-int nft_jansson_parse_set(struct nft_set *s, json_t *tree);
+int nft_jansson_parse_set(struct nft_set *s, json_t *tree,
+                         struct nft_parse_err *err);
 #endif
 
 const char *nft_family2str(uint32_t family);
index 539f9ab0399207261f3c999ad7deeb671cdd8c78..54a56b9930eece76d08a81f620415afefa0c9562 100644 (file)
 #ifdef JSON_PARSING
 
 static int nft_jansson_load_int_node(json_t *root, const char *node_name,
-                                     json_int_t *val)
+                                     json_int_t *val, struct nft_parse_err *err)
 {
        json_t *node;
 
        node = json_object_get(root, node_name);
        if (node == NULL) {
+               err->error = NFT_PARSE_EMISSINGNODE;
+               err->node_name = node_name;
                errno = EINVAL;
                return -1;
        }
 
        if (!json_is_integer(node)) {
+               err->error = NFT_PARSE_EBADTYPE;
+               err->node_name = node_name;
                errno = ERANGE;
                return -1;
        }
@@ -43,27 +47,35 @@ static int nft_jansson_load_int_node(json_t *root, const char *node_name,
        return 0;
 }
 
-const char *nft_jansson_parse_str(json_t *root, const char *node_name)
+const char *nft_jansson_parse_str(json_t *root, const char *node_name,
+                                 struct nft_parse_err *err)
 {
        json_t *node;
        const char *val;
 
        node = json_object_get(root, node_name);
        if (node == NULL) {
+               err->error = NFT_PARSE_EMISSINGNODE;
+               err->node_name = node_name;
                errno = EINVAL;
                return NULL;
        }
+
        val = json_string_value(node);
+       if (val == NULL) {
+               err->error = NFT_PARSE_EBADTYPE;
+               err->node_name = node_name;
+       }
 
        return val;
 }
 
 int nft_jansson_parse_val(json_t *root, const char *node_name, int type,
-                         void *out)
+                         void *out, struct nft_parse_err *err)
 {
        json_int_t val;
 
-       if (nft_jansson_load_int_node(root, node_name, &val) == -1)
+       if (nft_jansson_load_int_node(root, node_name, &val, err) == -1)
                return -1;
 
        if (nft_get_value(type, &val, out) == -1)
@@ -77,12 +89,17 @@ bool nft_jansson_node_exist(json_t *root, const char *node_name)
        return json_object_get(root, node_name) != NULL;
 }
 
-json_t *nft_jansson_create_root(const char *json, json_error_t *err)
+json_t *nft_jansson_create_root(const char *json, json_error_t *error,
+                               struct nft_parse_err *err)
 {
        json_t *root;
 
-       root = json_loadb(json, strlen(json), 0, err);
+       root = json_loadb(json, strlen(json), 0, error);
        if (root == NULL) {
+               err->error = NFT_PARSE_EBADINPUT;
+               err->line = error->line;
+               err->column = error->column;
+               err->node_name = error->source;
                errno = EINVAL;
                return NULL;
        }
@@ -90,12 +107,15 @@ json_t *nft_jansson_create_root(const char *json, json_error_t *err)
        return root;
 }
 
-json_t *nft_jansson_get_node(json_t *root, const char *node_name)
+json_t *nft_jansson_get_node(json_t *root, const char *node_name,
+                            struct nft_parse_err *err)
 {
        json_t *node;
 
        node = json_object_get(root, node_name);
        if (node == NULL) {
+               err->error = NFT_PARSE_EMISSINGNODE;
+               err->node_name = node_name;
                errno = EINVAL;
                return NULL;
        }
@@ -108,17 +128,18 @@ void nft_jansson_free_root(json_t *root)
        json_decref(root);
 }
 
-int nft_jansson_parse_family(json_t *root, void *out)
+int nft_jansson_parse_family(json_t *root, void *out, struct nft_parse_err *err)
 {
        const char *str;
        int family;
 
-       str = nft_jansson_parse_str(root, "family");
+       str = nft_jansson_parse_str(root, "family", err);
        if (str == NULL)
                return -1;
 
        family = nft_str2family(str);
        if (family < 0) {
+               err->node_name = "family";
                errno = EINVAL;
                return -1;
        }
@@ -128,9 +149,9 @@ int nft_jansson_parse_family(json_t *root, void *out)
 }
 
 int nft_jansson_parse_reg(json_t *root, const char *node_name, int type,
-                         void *out)
+                         void *out, struct nft_parse_err *err)
 {
-       if (nft_jansson_parse_val(root, node_name, type, out) < 0)
+       if (nft_jansson_parse_val(root, node_name, type, out, err) < 0)
                return -1;
 
        if (*((uint32_t *)out) > NFT_REG_MAX){
@@ -142,38 +163,42 @@ int nft_jansson_parse_reg(json_t *root, const char *node_name, int type,
 }
 
 int nft_jansson_str2num(json_t *root, const char *node_name, int base,
-                       void *out, enum nft_type type)
+                       void *out, enum nft_type type, struct nft_parse_err *err)
 {
        const char *str;
 
-       str = nft_jansson_parse_str(root, node_name);
+       str = nft_jansson_parse_str(root, node_name, err);
        if (str == NULL)
                return -1;
 
        return nft_strtoi(str, base, out, type);
 }
 
-struct nft_rule_expr *nft_jansson_expr_parse(json_t *root)
+struct nft_rule_expr *nft_jansson_expr_parse(json_t *root,
+                                            struct nft_parse_err *err)
 {
        struct nft_rule_expr *e;
        const char *type;
        int ret;
 
-       type = nft_jansson_parse_str(root, "type");
+       type = nft_jansson_parse_str(root, "type", err);
        if (type == NULL)
                return NULL;
 
        e = nft_rule_expr_alloc(type);
-       if (e == NULL)
-               return NULL;;
+       if (e == NULL) {
+               err->node_name = "type";
+               return NULL;
+       }
 
-       ret = e->ops->json_parse(e, root);
+       ret = e->ops->json_parse(e, root, err);
 
        return ret < 0 ? NULL : e;
 }
 
 int nft_jansson_data_reg_parse(json_t *root, const char *node_name,
-                              union nft_data_reg *data_reg)
+                              union nft_data_reg *data_reg,
+                              struct nft_parse_err *err)
 {
        json_t *data;
        const char *type;
@@ -181,24 +206,27 @@ int nft_jansson_data_reg_parse(json_t *root, const char *node_name,
 
        data = json_object_get(root, node_name);
        if (data == NULL) {
+               err->error = NFT_PARSE_EMISSINGNODE;
+               err->node_name = node_name;
                errno = EINVAL;
                return -1;
        }
 
        data = json_object_get(data, "data_reg");
        if (data == NULL) {
+               err->error = NFT_PARSE_EMISSINGNODE;
+               err->node_name = "data_reg";
                errno = EINVAL;
                return -1;
        }
 
-       ret = nft_data_reg_json_parse(data_reg, data);
-
+       ret = nft_data_reg_json_parse(data_reg, data, err);
        if (ret < 0) {
                errno = EINVAL;
                return -1;
        }
 
-       type = nft_jansson_parse_str(data, "type");
+       type = nft_jansson_parse_str(data, "type", err);
        if (type == NULL)
                return -1;
 
@@ -209,29 +237,32 @@ int nft_jansson_data_reg_parse(json_t *root, const char *node_name,
        else if (strcmp(type, "chain") == 0)
                return DATA_CHAIN;
        else {
+               err->error = NFT_PARSE_EBADTYPE;
+               err->node_name = "type";
                errno = EINVAL;
                return -1;
        }
 }
 
-int nft_set_elem_json_parse(struct nft_set_elem *e, json_t *root)
+int nft_set_elem_json_parse(struct nft_set_elem *e, json_t *root,
+                           struct nft_parse_err *err)
 {
        uint32_t uval32;
        int set_elem_data;
 
-       if (nft_jansson_parse_val(root, "flags", NFT_TYPE_U32, &uval32) < 0)
+       if (nft_jansson_parse_val(root, "flags", NFT_TYPE_U32, &uval32, err) < 0)
                return -1;
 
        nft_set_elem_attr_set_u32(e, NFT_SET_ELEM_ATTR_FLAGS, uval32);
 
-       if (nft_jansson_data_reg_parse(root, "key", &e->key) != DATA_VALUE)
+       if (nft_jansson_data_reg_parse(root, "key", &e->key, err) != DATA_VALUE)
                return -1;
 
        e->flags |= (1 << NFT_SET_ELEM_ATTR_KEY);
 
        if (nft_jansson_node_exist(root, "data")) {
                set_elem_data = nft_jansson_data_reg_parse(root, "data",
-                                                          &e->data);
+                                                          &e->data, err);
                switch (set_elem_data) {
                case DATA_VALUE:
                        e->flags |= (1 << NFT_SET_ELEM_ATTR_DATA);
index 7dc9aee15f11ae5109edd05e174e1cfe9014e2b0..be5c783ec3493865d7a838710253bf26ffa43d89 100644 (file)
@@ -184,5 +184,9 @@ global:
 
   nft_nlmsg_build_hdr;
 
+  nft_parse_err_alloc;
+  nft_parse_err_free;
+  nft_parse_perror;
+
 local: *;
 };
index 82156b7d1e83f8ac14367455171f279c6a6f15cc..bd09bb3df179747d9b068d6eabfd4e7506fcbc22 100644 (file)
 #include <libnftables/set.h>
 
 #ifdef XML_PARSING
-mxml_node_t *nft_mxml_build_tree(const char *xml, const char *treename)
+mxml_node_t *nft_mxml_build_tree(const char *xml, const char *treename,
+                                struct nft_parse_err *err)
 {
        mxml_node_t *tree;
 
        tree = mxmlLoadString(NULL, xml, MXML_OPAQUE_CALLBACK);
-       if (tree == NULL)
+       if (tree == NULL) {
+               err->error = NFT_PARSE_EBADINPUT;
+               err->line = 0;
+               err->column = 0;
                goto err;
+       }
 
        if (strcmp(tree->value.opaque, treename) == 0)
                return tree;
@@ -39,7 +44,8 @@ err:
        return NULL;
 }
 
-struct nft_rule_expr *nft_mxml_expr_parse(mxml_node_t *node)
+struct nft_rule_expr *nft_mxml_expr_parse(mxml_node_t *node,
+                                         struct nft_parse_err *err)
 {
        mxml_node_t *tree;
        struct nft_rule_expr *e;
@@ -48,8 +54,11 @@ struct nft_rule_expr *nft_mxml_expr_parse(mxml_node_t *node)
        int ret;
 
        expr_name = mxmlElementGetAttr(node, "type");
-       if (expr_name == NULL)
+       if (expr_name == NULL) {
+               err->node_name = "type";
+               err->error = NFT_PARSE_EMISSINGNODE;
                goto err;
+       }
 
        e = nft_rule_expr_alloc(expr_name);
        if (e == NULL)
@@ -65,7 +74,7 @@ struct nft_rule_expr *nft_mxml_expr_parse(mxml_node_t *node)
        if (tree == NULL)
                goto err_expr;
 
-       ret = e->ops->xml_parse(e, tree);
+       ret = e->ops->xml_parse(e, tree, err);
        mxmlDelete(tree);
 
        return ret < 0 ? NULL : e;
@@ -77,20 +86,24 @@ err:
        return NULL;
 }
 
-int nft_mxml_reg_parse(mxml_node_t *tree, const char *reg_name, uint32_t flags)
+int nft_mxml_reg_parse(mxml_node_t *tree, const char *reg_name, uint32_t flags,
+                      struct nft_parse_err *err)
 {
        mxml_node_t *node;
        uint64_t val;
 
        node = mxmlFindElement(tree, tree, reg_name, NULL, NULL, flags);
        if (node == NULL) {
+               err->error = NFT_PARSE_EMISSINGNODE;
                errno = EINVAL;
                goto err;
        }
 
        if (nft_strtoi(node->child->value.opaque, BASE_DEC, &val,
-                      NFT_TYPE_U64) != 0)
+                      NFT_TYPE_U64) != 0) {
+               err->error = NFT_PARSE_EBADTYPE;
                goto err;
+       }
 
        if (val > NFT_REG_MAX) {
                errno = ERANGE;
@@ -98,73 +111,101 @@ int nft_mxml_reg_parse(mxml_node_t *tree, const char *reg_name, uint32_t flags)
        }
        return val;
 err:
+       err->node_name = reg_name;
        return -1;
 }
 
 int nft_mxml_data_reg_parse(mxml_node_t *tree, const char *node_name,
-                           union nft_data_reg *data_reg, uint16_t flags)
+                           union nft_data_reg *data_reg, uint16_t flags,
+                           struct nft_parse_err *err)
 {
        mxml_node_t *node;
 
        node = mxmlFindElement(tree, tree, node_name, NULL, NULL,
                               MXML_DESCEND_FIRST);
        if (node == NULL || node->child == NULL) {
-               if (!(flags & NFT_XML_OPT))
+               if (!(flags & NFT_XML_OPT)) {
+                       err->error = NFT_PARSE_EMISSINGNODE;
+                       err->node_name = node_name;
                        errno = EINVAL;
+               }
 
                return DATA_NONE;
        }
 
-       return nft_data_reg_xml_parse(data_reg, node);
+       return nft_data_reg_xml_parse(data_reg, node, err);
 }
 
 int
 nft_mxml_num_parse(mxml_node_t *tree, const char *node_name,
                   uint32_t mxml_flags, int base, void *number,
-                  enum nft_type type, uint16_t flags)
+                  enum nft_type type, uint16_t flags,
+                  struct nft_parse_err *err)
 {
        mxml_node_t *node = NULL;
+       int ret;
 
        node = mxmlFindElement(tree, tree, node_name, NULL, NULL, mxml_flags);
        if (node == NULL || node->child == NULL) {
-               if (!(flags & NFT_XML_OPT))
+               if (!(flags & NFT_XML_OPT)) {
                        errno = EINVAL;
-
+                       err->node_name = node_name;
+                       err->error = NFT_PARSE_EMISSINGNODE;
+               }
                return -1;
        }
-       return nft_strtoi(node->child->value.opaque, base, number, type);
+
+       ret = nft_strtoi(node->child->value.opaque, base, number, type);
+
+       if (ret != 0) {
+               err->error = NFT_PARSE_EBADTYPE;
+               err->node_name = node_name;
+       }
+       return ret;
 }
 
 const char *nft_mxml_str_parse(mxml_node_t *tree, const char *node_name,
-                              uint32_t mxml_flags, uint16_t flags)
+                              uint32_t mxml_flags, uint16_t flags,
+                              struct nft_parse_err *err)
 {
        mxml_node_t *node;
+       const char *ret;
 
        node = mxmlFindElement(tree, tree, node_name, NULL, NULL, mxml_flags);
        if (node == NULL || node->child == NULL) {
-               if (!(flags & NFT_XML_OPT))
+               if (!(flags & NFT_XML_OPT)) {
                        errno = EINVAL;
-
+                       err->node_name = node_name;
+                       err->error = NFT_PARSE_EMISSINGNODE;
+               }
                return NULL;
        }
 
-       return node->child->value.opaque;
+       ret = node->child->value.opaque;
+       if (ret == NULL) {
+               err->node_name = node_name;
+               err->error = NFT_PARSE_EBADTYPE;
+       }
+       return ret;
 }
 
 int nft_mxml_family_parse(mxml_node_t *tree, const char *node_name,
-                         uint32_t mxml_flags, uint16_t flags)
+                         uint32_t mxml_flags, uint16_t flags,
+                         struct nft_parse_err *err)
 {
        const char *family_str;
        int family;
 
        family_str = nft_mxml_str_parse(tree, node_name, mxml_flags,
-                                       flags);
+                                       flags, err);
        if (family_str == NULL)
                return -1;
 
        family = nft_str2family(family_str);
-       if (family < 0)
+       if (family < 0) {
+               err->node_name = node_name;
                errno = EAFNOSUPPORT;
+       }
 
        return family;
 }
index 280350a31fffba45bb7e9b3eadf89cce93879e03..2e35aba437ad31172359ec3963a650e105754e25 100644 (file)
@@ -442,7 +442,8 @@ int nft_rule_nlmsg_parse(const struct nlmsghdr *nlh, struct nft_rule *r)
 EXPORT_SYMBOL(nft_rule_nlmsg_parse);
 
 #ifdef JSON_PARSING
-int nft_jansson_parse_rule(struct nft_rule *r, json_t *tree)
+int nft_jansson_parse_rule(struct nft_rule *r, json_t *tree,
+                          struct nft_parse_err *err)
 {
        json_t *root, *array;
        struct nft_rule_expr *e;
@@ -451,28 +452,29 @@ int nft_jansson_parse_rule(struct nft_rule *r, json_t *tree)
        uint32_t uval32;
        int i, family;
 
-       root = nft_jansson_get_node(tree, "rule");
+       root = nft_jansson_get_node(tree, "rule", err);
        if (root == NULL)
                return -1;
 
-       if (nft_jansson_parse_family(root, &family) != 0)
+       if (nft_jansson_parse_family(root, &family, err) != 0)
                goto err;
 
        nft_rule_attr_set_u32(r, NFT_RULE_ATTR_FAMILY, family);
 
-       str = nft_jansson_parse_str(root, "table");
+       str = nft_jansson_parse_str(root, "table", err);
        if (str == NULL)
                goto err;
 
        nft_rule_attr_set_str(r, NFT_RULE_ATTR_TABLE, str);
 
-       str = nft_jansson_parse_str(root, "chain");
+       str = nft_jansson_parse_str(root, "chain", err);
        if (str == NULL)
                goto err;
 
        nft_rule_attr_set_str(r, NFT_RULE_ATTR_CHAIN, str);
 
-       if (nft_jansson_parse_val(root, "handle", NFT_TYPE_U64, &uval64) < 0)
+       if (nft_jansson_parse_val(root, "handle", NFT_TYPE_U64, &uval64,
+                                 err) < 0)
                goto err;
 
        nft_rule_attr_set_u64(r, NFT_RULE_ATTR_HANDLE, uval64);
@@ -480,13 +482,13 @@ int nft_jansson_parse_rule(struct nft_rule *r, json_t *tree)
        if (nft_jansson_node_exist(root, "compat_proto") ||
            nft_jansson_node_exist(root, "compat_flags")) {
                if (nft_jansson_parse_val(root, "compat_proto", NFT_TYPE_U32,
-                                         &uval32) < 0)
+                                         &uval32, err) < 0)
                        goto err;
 
                nft_rule_attr_set_u32(r, NFT_RULE_ATTR_COMPAT_PROTO, uval32);
 
                if (nft_jansson_parse_val(root, "compat_flags", NFT_TYPE_U32,
-                                         &uval32) < 0)
+                                         &uval32, err) < 0)
                        goto err;
 
                nft_rule_attr_set_u32(r, NFT_RULE_ATTR_COMPAT_FLAGS, uval32);
@@ -494,19 +496,22 @@ int nft_jansson_parse_rule(struct nft_rule *r, json_t *tree)
 
        if (nft_jansson_node_exist(root, "position")) {
                if (nft_jansson_parse_val(root, "position", NFT_TYPE_U64,
-                                         &uval64) < 0)
+                                         &uval64, err) < 0)
                        goto err;
 
                nft_rule_attr_set_u64(r, NFT_RULE_ATTR_POSITION, uval64);
        }
 
        array = json_object_get(root, "expr");
-       if (array == NULL)
+       if (array == NULL) {
+               err->error = NFT_PARSE_EMISSINGNODE;
+               err->node_name = "expr";
                goto err;
+       }
 
        for (i = 0; i < json_array_size(array); ++i) {
 
-               e = nft_jansson_expr_parse(json_array_get(array, i));
+               e = nft_jansson_expr_parse(json_array_get(array, i), err);
                if (e == NULL)
                        goto err;
 
@@ -521,17 +526,18 @@ err:
 }
 #endif
 
-static int nft_rule_json_parse(struct nft_rule *r, const char *json)
+static int nft_rule_json_parse(struct nft_rule *r, const char *json,
+                              struct nft_parse_err *err)
 {
 #ifdef JSON_PARSING
        json_t *tree;
        json_error_t error;
 
-       tree = nft_jansson_create_root(json, &error);
+       tree = nft_jansson_create_root(json, &error, err);
        if (tree == NULL)
                return -1;
 
-       return nft_jansson_parse_rule(r, tree);
+       return nft_jansson_parse_rule(r, tree, err);
 #else
        errno = EOPNOTSUPP;
        return -1;
@@ -539,7 +545,8 @@ static int nft_rule_json_parse(struct nft_rule *r, const char *json)
 }
 
 #ifdef XML_PARSING
-int nft_mxml_rule_parse(mxml_node_t *tree, struct nft_rule *r)
+int nft_mxml_rule_parse(mxml_node_t *tree, struct nft_rule *r,
+                       struct nft_parse_err *err)
 {
        mxml_node_t *node;
        struct nft_rule_expr *e;
@@ -547,7 +554,7 @@ int nft_mxml_rule_parse(mxml_node_t *tree, struct nft_rule *r)
        int family;
 
        family = nft_mxml_family_parse(tree, "family", MXML_DESCEND_FIRST,
-                                      NFT_XML_MAND);
+                                      NFT_XML_MAND, err);
        if (family < 0)
                return -1;
 
@@ -555,7 +562,7 @@ int nft_mxml_rule_parse(mxml_node_t *tree, struct nft_rule *r)
        r->flags |= (1 << NFT_RULE_ATTR_FAMILY);
 
        table = nft_mxml_str_parse(tree, "table", MXML_DESCEND_FIRST,
-                                  NFT_XML_MAND);
+                                  NFT_XML_MAND, err);
        if (table == NULL)
                return -1;
 
@@ -566,7 +573,7 @@ int nft_mxml_rule_parse(mxml_node_t *tree, struct nft_rule *r)
        r->flags |= (1 << NFT_RULE_ATTR_TABLE);
 
        chain = nft_mxml_str_parse(tree, "chain", MXML_DESCEND_FIRST,
-                                  NFT_XML_MAND);
+                                  NFT_XML_MAND, err);
        if (chain == NULL)
                return -1;
 
@@ -577,19 +584,19 @@ int nft_mxml_rule_parse(mxml_node_t *tree, struct nft_rule *r)
        r->flags |= (1 << NFT_RULE_ATTR_CHAIN);
 
        if (nft_mxml_num_parse(tree, "handle", MXML_DESCEND_FIRST, BASE_DEC,
-                              &r->handle, NFT_TYPE_U64, NFT_XML_MAND) != 0)
+                              &r->handle, NFT_TYPE_U64, NFT_XML_MAND, err) != 0)
                return -1;
 
        r->flags |= (1 << NFT_RULE_ATTR_HANDLE);
 
        if (nft_mxml_num_parse(tree, "compat_proto", MXML_DESCEND_FIRST,
                               BASE_DEC, &r->compat.proto, NFT_TYPE_U32,
-                              NFT_XML_OPT) >= 0)
+                              NFT_XML_OPT, err) >= 0)
                r->flags |= (1 << NFT_RULE_ATTR_COMPAT_PROTO);
 
        if (nft_mxml_num_parse(tree, "compat_flags", MXML_DESCEND_FIRST,
                               BASE_DEC, &r->compat.flags, NFT_TYPE_U32,
-                              NFT_XML_OPT) >= 0)
+                              NFT_XML_OPT, err) >= 0)
                r->flags |= (1 << NFT_RULE_ATTR_COMPAT_FLAGS);
 
        if (nft_rule_attr_is_set(r, NFT_RULE_ATTR_COMPAT_PROTO) !=
@@ -600,7 +607,7 @@ int nft_mxml_rule_parse(mxml_node_t *tree, struct nft_rule *r)
 
        if (nft_mxml_num_parse(tree, "position", MXML_DESCEND_FIRST,
                               BASE_DEC, &r->position, NFT_TYPE_U64,
-                              NFT_XML_OPT) >= 0)
+                              NFT_XML_OPT, err) >= 0)
                r->flags |= (1 << NFT_RULE_ATTR_POSITION);
 
        /* Iterating over <expr> */
@@ -609,7 +616,7 @@ int nft_mxml_rule_parse(mxml_node_t *tree, struct nft_rule *r)
                node != NULL;
                node = mxmlFindElement(node, tree, "expr", "type",
                                       NULL, MXML_DESCEND)) {
-               e = nft_mxml_expr_parse(node);
+               e = nft_mxml_expr_parse(node, err);
                if (e == NULL)
                        return -1;
 
@@ -620,15 +627,16 @@ int nft_mxml_rule_parse(mxml_node_t *tree, struct nft_rule *r)
 }
 #endif
 
-static int nft_rule_xml_parse(struct nft_rule *r, const char *xml)
+static int nft_rule_xml_parse(struct nft_rule *r, const char *xml,
+                             struct nft_parse_err *err)
 {
 #ifdef XML_PARSING
        int ret;
-       mxml_node_t *tree = nft_mxml_build_tree(xml, "rule");
+       mxml_node_t *tree = nft_mxml_build_tree(xml, "rule", err);
        if (tree == NULL)
                return -1;
 
-       ret = nft_mxml_rule_parse(tree, r);
+       ret = nft_mxml_rule_parse(tree, r, err);
        mxmlDelete(tree);
        return ret;
 #else
@@ -638,22 +646,25 @@ static int nft_rule_xml_parse(struct nft_rule *r, const char *xml)
 }
 
 int nft_rule_parse(struct nft_rule *r, enum nft_parse_type type,
-                  const char *data)
+                  const char *data, struct nft_parse_err *err)
 {
        int ret;
+       struct nft_parse_err perr;
 
        switch (type) {
        case NFT_PARSE_XML:
-               ret = nft_rule_xml_parse(r, data);
+               ret = nft_rule_xml_parse(r, data, &perr);
                break;
        case NFT_PARSE_JSON:
-               ret = nft_rule_json_parse(r, data);
+               ret = nft_rule_json_parse(r, data, &perr);
                break;
        default:
                ret = -1;
                errno = EOPNOTSUPP;
                break;
        }
+       if (err != NULL)
+               *err = perr;
 
        return ret;
 }
index f591382da73a869cdfea78dc6dfe3383e6b04d24..a12efa96fb9ef453a7f217929979144cc195564c 100644 (file)
@@ -132,7 +132,8 @@ const void *nft_ruleset_attr_get(const struct nft_ruleset *r, uint16_t attr)
 EXPORT_SYMBOL(nft_ruleset_attr_get);
 
 #ifdef JSON_PARSING
-static int nft_ruleset_json_parse_tables(struct nft_ruleset *rs, json_t *array)
+static int nft_ruleset_json_parse_tables(struct nft_ruleset *rs, json_t *array,
+                                        struct nft_parse_err *err)
 {
        int i, len;
        json_t *node;
@@ -161,7 +162,7 @@ static int nft_ruleset_json_parse_tables(struct nft_ruleset *rs, json_t *array)
                        goto err;
                }
 
-               if (nft_jansson_parse_table(o, node) < 0) {
+               if (nft_jansson_parse_table(o, node, err) < 0) {
                        nft_table_free(o);
                        goto err;
                }
@@ -180,7 +181,8 @@ err:
        return -1;
 }
 
-static int nft_ruleset_json_parse_chains(struct nft_ruleset *rs, json_t *array)
+static int nft_ruleset_json_parse_chains(struct nft_ruleset *rs, json_t *array,
+                                        struct nft_parse_err *err)
 {
        int i, len;
        json_t *node;
@@ -209,7 +211,7 @@ static int nft_ruleset_json_parse_chains(struct nft_ruleset *rs, json_t *array)
                        goto err;
                }
 
-               if (nft_jansson_parse_chain(o, node) < 0) {
+               if (nft_jansson_parse_chain(o, node, err) < 0) {
                        nft_chain_free(o);
                        goto err;
                }
@@ -228,7 +230,8 @@ err:
        return -1;
 }
 
-static int nft_ruleset_json_parse_sets(struct nft_ruleset *rs, json_t *array)
+static int nft_ruleset_json_parse_sets(struct nft_ruleset *rs, json_t *array,
+                                      struct nft_parse_err *err)
 {
        int i, len;
        json_t *node;
@@ -257,7 +260,7 @@ static int nft_ruleset_json_parse_sets(struct nft_ruleset *rs, json_t *array)
                        goto err;
                }
 
-               if (nft_jansson_parse_set(s, node) < 0) {
+               if (nft_jansson_parse_set(s, node, err) < 0) {
                        nft_set_free(s);
                        goto err;
                }
@@ -276,7 +279,8 @@ err:
        return -1;
 }
 
-static int nft_ruleset_json_parse_rules(struct nft_ruleset *rs, json_t *array)
+static int nft_ruleset_json_parse_rules(struct nft_ruleset *rs, json_t *array,
+                                       struct nft_parse_err *err)
 {
        int i, len;
        json_t *node;
@@ -305,7 +309,7 @@ static int nft_ruleset_json_parse_rules(struct nft_ruleset *rs, json_t *array)
                        goto err;
                }
 
-               if (nft_jansson_parse_rule(o, node) < 0) {
+               if (nft_jansson_parse_rule(o, node, err) < 0) {
                        nft_rule_free(o);
                        goto err;
                }
@@ -326,13 +330,14 @@ err:
 
 #endif
 
-static int nft_ruleset_json_parse(struct nft_ruleset *rs, const char *json)
+static int nft_ruleset_json_parse(struct nft_ruleset *rs, const char *json,
+                                 struct nft_parse_err *err)
 {
 #ifdef JSON_PARSING
        json_t *root, *array;
        json_error_t error;
 
-       root = nft_jansson_create_root(json, &error);
+       root = nft_jansson_create_root(json, &error, err);
        if (root == NULL)
                return -1;
 
@@ -342,16 +347,16 @@ static int nft_ruleset_json_parse(struct nft_ruleset *rs, const char *json)
                goto err;
        }
 
-       if (nft_ruleset_json_parse_tables(rs, array) != 0)
+       if (nft_ruleset_json_parse_tables(rs, array, err) != 0)
                goto err;
 
-       if (nft_ruleset_json_parse_chains(rs, array) != 0)
+       if (nft_ruleset_json_parse_chains(rs, array, err) != 0)
                goto err;
 
-       if (nft_ruleset_json_parse_sets(rs, array) != 0)
+       if (nft_ruleset_json_parse_sets(rs, array, err) != 0)
                goto err;
 
-       if (nft_ruleset_json_parse_rules(rs, array) != 0)
+       if (nft_ruleset_json_parse_rules(rs, array, err) != 0)
                goto err;
 
        nft_jansson_free_root(root);
@@ -367,7 +372,8 @@ err:
 
 #ifdef XML_PARSING
 static int
-nft_ruleset_xml_parse_tables(struct nft_ruleset *rs, mxml_node_t *tree)
+nft_ruleset_xml_parse_tables(struct nft_ruleset *rs, mxml_node_t *tree,
+                            struct nft_parse_err *err)
 {
        mxml_node_t *node;
        struct nft_table *t;
@@ -386,7 +392,7 @@ nft_ruleset_xml_parse_tables(struct nft_ruleset *rs, mxml_node_t *tree)
                if (t == NULL)
                        goto err_free;
 
-               if (nft_mxml_table_parse(node, t) != 0) {
+               if (nft_mxml_table_parse(node, t, err) != 0) {
                        nft_table_free(t);
                        goto err_free;
                }
@@ -407,7 +413,8 @@ err_free:
 }
 
 static int
-nft_ruleset_xml_parse_chains(struct nft_ruleset *rs, mxml_node_t *tree)
+nft_ruleset_xml_parse_chains(struct nft_ruleset *rs, mxml_node_t *tree,
+                            struct nft_parse_err *err)
 {
        mxml_node_t *node;
        struct nft_chain *c;
@@ -426,7 +433,7 @@ nft_ruleset_xml_parse_chains(struct nft_ruleset *rs, mxml_node_t *tree)
                if (c == NULL)
                        goto err_free;
 
-               if (nft_mxml_chain_parse(node, c) != 0) {
+               if (nft_mxml_chain_parse(node, c, err) != 0) {
                        nft_chain_free(c);
                        goto err_free;
                }
@@ -447,7 +454,8 @@ err_free:
 }
 
 static int
-nft_ruleset_xml_parse_sets(struct nft_ruleset *rs, mxml_node_t *tree)
+nft_ruleset_xml_parse_sets(struct nft_ruleset *rs, mxml_node_t *tree,
+                          struct nft_parse_err *err)
 {
        mxml_node_t *node;
        struct nft_set *s;
@@ -466,7 +474,7 @@ nft_ruleset_xml_parse_sets(struct nft_ruleset *rs, mxml_node_t *tree)
                if (s == NULL)
                        goto err_free;
 
-               if (nft_mxml_set_parse(node, s) != 0) {
+               if (nft_mxml_set_parse(node, s, err) != 0) {
                        nft_set_free(s);
                        goto err_free;
                }
@@ -486,7 +494,8 @@ err_free:
 }
 
 static int
-nft_ruleset_xml_parse_rules(struct nft_ruleset *rs, mxml_node_t *tree)
+nft_ruleset_xml_parse_rules(struct nft_ruleset *rs, mxml_node_t *tree,
+                           struct nft_parse_err *err)
 {
        mxml_node_t *node;
        struct nft_rule *r;
@@ -505,7 +514,7 @@ nft_ruleset_xml_parse_rules(struct nft_ruleset *rs, mxml_node_t *tree)
                if (r == NULL)
                        goto err_free;
 
-               if (nft_mxml_rule_parse(node, r) != 0) {
+               if (nft_mxml_rule_parse(node, r, err) != 0) {
                        nft_rule_free(r);
                        goto err_free;
                }
@@ -525,25 +534,26 @@ err_free:
 }
 #endif
 
-static int nft_ruleset_xml_parse(struct nft_ruleset *rs, const char *xml)
+static int nft_ruleset_xml_parse(struct nft_ruleset *rs, const char *xml,
+                                struct nft_parse_err *err)
 {
 #ifdef XML_PARSING
        mxml_node_t *tree;
 
-       tree = nft_mxml_build_tree(xml, "nftables");
+       tree = nft_mxml_build_tree(xml, "nftables", err);
        if (tree == NULL)
                return -1;
 
-       if (nft_ruleset_xml_parse_tables(rs, tree) != 0)
+       if (nft_ruleset_xml_parse_tables(rs, tree, err) != 0)
                goto err;
 
-       if (nft_ruleset_xml_parse_chains(rs, tree) != 0)
+       if (nft_ruleset_xml_parse_chains(rs, tree, err) != 0)
                goto err;
 
-       if (nft_ruleset_xml_parse_sets(rs, tree) != 0)
+       if (nft_ruleset_xml_parse_sets(rs, tree, err) != 0)
                goto err;
 
-       if (nft_ruleset_xml_parse_rules(rs, tree) != 0)
+       if (nft_ruleset_xml_parse_rules(rs, tree, err) != 0)
                goto err;
 
        mxmlDelete(tree);
@@ -558,16 +568,16 @@ err:
 }
 
 int nft_ruleset_parse(struct nft_ruleset *r, enum nft_parse_type type,
-                     const char *data)
+                     const char *data, struct nft_parse_err *err)
 {
        int ret;
 
        switch (type) {
        case NFT_PARSE_XML:
-               ret = nft_ruleset_xml_parse(r, data);
+               ret = nft_ruleset_xml_parse(r, data, err);
                break;
        case NFT_PARSE_JSON:
-               ret = nft_ruleset_json_parse(r, data);
+               ret = nft_ruleset_json_parse(r, data, err);
                break;
        default:
                ret = -1;
index c5204cc6be972b97015c4a9b9600b752cacf9f9b..32c7fffdd2fe6bd33644aa1c5aac82932dd1cb07 100644 (file)
--- a/src/set.c
+++ b/src/set.c
@@ -283,7 +283,8 @@ int nft_set_nlmsg_parse(const struct nlmsghdr *nlh, struct nft_set *s)
 EXPORT_SYMBOL(nft_set_nlmsg_parse);
 
 #ifdef JSON_PARSING
-int nft_jansson_parse_set(struct nft_set *s, json_t *tree)
+int nft_jansson_parse_set(struct nft_set *s, json_t *tree,
+                         struct nft_parse_err *err)
 {
        json_t *root, *array, *json_elem;
        uint32_t uval32;
@@ -291,45 +292,47 @@ int nft_jansson_parse_set(struct nft_set *s, json_t *tree)
        const char *valstr;
        struct nft_set_elem *elem;
 
-       root = nft_jansson_get_node(tree, "set");
+       root = nft_jansson_get_node(tree, "set", err);
        if (root == NULL)
                return -1;
 
-       valstr = nft_jansson_parse_str(root, "name");
+       valstr = nft_jansson_parse_str(root, "name", err);
        if (valstr == NULL)
                return -1;
 
        nft_set_attr_set_str(s, NFT_SET_ATTR_NAME, valstr);
 
-       valstr = nft_jansson_parse_str(root, "table");
+       valstr = nft_jansson_parse_str(root, "table", err);
        if (valstr == NULL)
                return -1;
 
        nft_set_attr_set_str(s, NFT_SET_ATTR_TABLE, valstr);
 
-       if (nft_jansson_parse_val(root, "flags", NFT_TYPE_U32, &uval32) < 0)
+       if (nft_jansson_parse_val(root, "flags", NFT_TYPE_U32, &uval32, err) < 0)
                return -1;
 
        nft_set_attr_set_u32(s, NFT_SET_ATTR_FLAGS, uval32);
 
-       if (nft_jansson_parse_family(root, &family) < 0)
+       if (nft_jansson_parse_family(root, &family, err) < 0)
                return -1;
 
        nft_set_attr_set_u32(s, NFT_SET_ATTR_FAMILY, family);
 
-       if (nft_jansson_parse_val(root, "key_type", NFT_TYPE_U32, &uval32) < 0)
+       if (nft_jansson_parse_val(root, "key_type", NFT_TYPE_U32, &uval32,
+                                 err) < 0)
                return -1;
 
        nft_set_attr_set_u32(s, NFT_SET_ATTR_KEY_TYPE, uval32);
 
-       if (nft_jansson_parse_val(root, "key_len", NFT_TYPE_U32, &uval32) < 0)
+       if (nft_jansson_parse_val(root, "key_len", NFT_TYPE_U32, &uval32,
+                                 err) < 0)
                return -1;
 
        nft_set_attr_set_u32(s, NFT_SET_ATTR_KEY_LEN, uval32);
 
        if (nft_jansson_node_exist(root, "data_type")) {
                if (nft_jansson_parse_val(root, "data_type", NFT_TYPE_U32,
-                                         &uval32) < 0)
+                                         &uval32, err) < 0)
                        goto err;
 
                nft_set_attr_set_u32(s, NFT_SET_ATTR_DATA_TYPE, uval32);
@@ -337,7 +340,7 @@ int nft_jansson_parse_set(struct nft_set *s, json_t *tree)
 
        if (nft_jansson_node_exist(root, "data_len")) {
                if (nft_jansson_parse_val(root, "data_len", NFT_TYPE_U32,
-                                         &uval32) < 0)
+                                         &uval32, err) < 0)
                        goto err;
 
                nft_set_attr_set_u32(s, NFT_SET_ATTR_DATA_LEN, uval32);
@@ -354,7 +357,7 @@ int nft_jansson_parse_set(struct nft_set *s, json_t *tree)
                        if (json_elem == NULL)
                                goto err;
 
-                       if (nft_set_elem_json_parse(elem, json_elem) < 0)
+                       if (nft_set_elem_json_parse(elem, json_elem, err) < 0)
                                goto err;
 
                        list_add_tail(&elem->head, &s->element_list);
@@ -371,17 +374,18 @@ err:
 }
 #endif
 
-static int nft_set_json_parse(struct nft_set *s, const char *json)
+static int nft_set_json_parse(struct nft_set *s, const char *json,
+                             struct nft_parse_err *err)
 {
 #ifdef JSON_PARSING
        json_t *tree;
        json_error_t error;
 
-       tree = nft_jansson_create_root(json, &error);
+       tree = nft_jansson_create_root(json, &error, err);
        if (tree == NULL)
                return -1;
 
-       return nft_jansson_parse_set(s, tree);
+       return nft_jansson_parse_set(s, tree, err);
 #else
        errno = EOPNOTSUPP;
        return -1;
@@ -389,7 +393,8 @@ static int nft_set_json_parse(struct nft_set *s, const char *json)
 }
 
 #ifdef XML_PARSING
-int nft_mxml_set_parse(mxml_node_t *tree, struct nft_set *s)
+int nft_mxml_set_parse(mxml_node_t *tree, struct nft_set *s,
+                      struct nft_parse_err *err)
 {
        mxml_node_t *node = NULL;
        struct nft_set_elem *elem;
@@ -397,7 +402,7 @@ int nft_mxml_set_parse(mxml_node_t *tree, struct nft_set *s)
        int family;
 
        name = nft_mxml_str_parse(tree, "name", MXML_DESCEND_FIRST,
-                                 NFT_XML_MAND);
+                                 NFT_XML_MAND, err);
        if (name == NULL)
                return -1;
 
@@ -408,7 +413,7 @@ int nft_mxml_set_parse(mxml_node_t *tree, struct nft_set *s)
        s->flags |= (1 << NFT_SET_ATTR_NAME);
 
        table = nft_mxml_str_parse(tree, "table", MXML_DESCEND_FIRST,
-                                  NFT_XML_MAND);
+                                  NFT_XML_MAND, err);
        if (table == NULL)
                return -1;
 
@@ -419,7 +424,7 @@ int nft_mxml_set_parse(mxml_node_t *tree, struct nft_set *s)
        s->flags |= (1 << NFT_SET_ATTR_TABLE);
 
        family = nft_mxml_family_parse(tree, "family", MXML_DESCEND_FIRST,
-                                      NFT_XML_MAND);
+                                      NFT_XML_MAND, err);
        if (family < 0)
                return -1;
 
@@ -428,31 +433,31 @@ int nft_mxml_set_parse(mxml_node_t *tree, struct nft_set *s)
        s->flags |= (1 << NFT_SET_ATTR_FAMILY);
 
        if (nft_mxml_num_parse(tree, "flags", MXML_DESCEND_FIRST, BASE_DEC,
-                              &s->set_flags, NFT_TYPE_U32, NFT_XML_MAND) != 0)
+                              &s->set_flags, NFT_TYPE_U32, NFT_XML_MAND, err) != 0)
                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)
+                              &s->key_type, NFT_TYPE_U32, NFT_XML_MAND, err) != 0)
                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)
+                              &s->key_len, NFT_TYPE_U32, NFT_XML_MAND, err) != 0)
                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)
+                              &s->data_type, NFT_TYPE_U32, NFT_XML_MAND, err) != 0)
                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)
+                              &s->data_len, NFT_TYPE_U32, NFT_XML_MAND, err) != 0)
                return -1;
 
        s->flags |= (1 << NFT_SET_ATTR_DATA_LEN);
@@ -467,7 +472,7 @@ int nft_mxml_set_parse(mxml_node_t *tree, struct nft_set *s)
                if (elem == NULL)
                        return -1;
 
-               if (nft_mxml_set_elem_parse(node, elem) < 0)
+               if (nft_mxml_set_elem_parse(node, elem, err) < 0)
                        return -1;
 
                list_add_tail(&elem->head, &s->element_list);
@@ -477,15 +482,16 @@ int nft_mxml_set_parse(mxml_node_t *tree, struct nft_set *s)
 }
 #endif
 
-static int nft_set_xml_parse(struct nft_set *s, const char *xml)
+static int nft_set_xml_parse(struct nft_set *s, const char *xml,
+                            struct nft_parse_err *err)
 {
 #ifdef XML_PARSING
        int ret;
-       mxml_node_t *tree = nft_mxml_build_tree(xml, "set");
+       mxml_node_t *tree = nft_mxml_build_tree(xml, "set", err);
        if (tree == NULL)
                return -1;
 
-       ret = nft_mxml_set_parse(tree, s);
+       ret = nft_mxml_set_parse(tree, s, err);
        mxmlDelete(tree);
        return ret;
 #else
@@ -495,16 +501,17 @@ static int nft_set_xml_parse(struct nft_set *s, const char *xml)
 }
 
 int nft_set_parse(struct nft_set *s, enum nft_parse_type type,
-                 const char *data)
+                 const char *data, struct nft_parse_err *err)
 {
        int ret;
+       struct nft_parse_err perr;
 
        switch (type) {
        case NFT_PARSE_XML:
-               ret = nft_set_xml_parse(s, data);
+               ret = nft_set_xml_parse(s, data, &perr);
                break;
        case NFT_PARSE_JSON:
-               ret = nft_set_json_parse(s, data);
+               ret = nft_set_json_parse(s, data, &perr);
                break;
        default:
                ret = -1;
@@ -512,6 +519,9 @@ int nft_set_parse(struct nft_set *s, enum nft_parse_type type,
                break;
        }
 
+       if (err != NULL)
+               *err = perr;
+
        return ret;
 }
 EXPORT_SYMBOL(nft_set_parse);
index fce9c1d9ccd5a5c7ac400a20456bca4a5c754c0f..7365affc1b744871deaa81a1b65e3f9cac04d79c 100644 (file)
@@ -357,26 +357,27 @@ int nft_set_elems_nlmsg_parse(const struct nlmsghdr *nlh, struct nft_set *s)
 EXPORT_SYMBOL(nft_set_elems_nlmsg_parse);
 
 #ifdef XML_PARSING
-int nft_mxml_set_elem_parse(mxml_node_t *tree, struct nft_set_elem *e)
+int nft_mxml_set_elem_parse(mxml_node_t *tree, struct nft_set_elem *e,
+                           struct nft_parse_err *err)
 {
        int set_elem_data;
 
        if (nft_mxml_num_parse(tree, "flags", MXML_DESCEND_FIRST,
                               BASE_DEC, &e->set_elem_flags,
-                              NFT_TYPE_U32, NFT_XML_MAND) != 0)
+                              NFT_TYPE_U32, NFT_XML_MAND, err) != 0)
                return -1;
 
        e->flags |= (1 << NFT_SET_ELEM_ATTR_FLAGS);
 
        if (nft_mxml_data_reg_parse(tree, "key", &e->key,
-                                   NFT_XML_MAND) != DATA_VALUE)
+                                   NFT_XML_MAND, err) != DATA_VALUE)
                return -1;
 
        e->flags |= (1 << NFT_SET_ELEM_ATTR_KEY);
 
        /* <set_elem_data> is not mandatory */
        set_elem_data = nft_mxml_data_reg_parse(tree, "data",
-                                               &e->data, NFT_XML_OPT);
+                                               &e->data, NFT_XML_OPT, err);
        switch (set_elem_data) {
        case DATA_VALUE:
                e->flags |= (1 << NFT_SET_ELEM_ATTR_DATA);
@@ -393,17 +394,18 @@ int nft_mxml_set_elem_parse(mxml_node_t *tree, struct nft_set_elem *e)
 }
 #endif
 
-static int nft_set_elem_xml_parse(struct nft_set_elem *e, const char *xml)
+static int nft_set_elem_xml_parse(struct nft_set_elem *e, const char *xml,
+                                 struct nft_parse_err *err)
 {
 #ifdef XML_PARSING
        mxml_node_t *tree;
        int ret;
 
-       tree = nft_mxml_build_tree(xml, "set_elem");
+       tree = nft_mxml_build_tree(xml, "set_elem", err);
        if (tree == NULL)
                return -1;
 
-       ret = nft_mxml_set_elem_parse(tree, e);
+       ret = nft_mxml_set_elem_parse(tree, e, err);
        mxmlDelete(tree);
        return ret;
 #else
@@ -413,12 +415,13 @@ static int nft_set_elem_xml_parse(struct nft_set_elem *e, const char *xml)
 }
 
 int nft_set_elem_parse(struct nft_set_elem *e,
-                      enum nft_parse_type type, const char *data) {
+                      enum nft_parse_type type, const char *data,
+                      struct nft_parse_err *err) {
        int ret;
 
        switch (type) {
        case NFT_PARSE_XML:
-               ret = nft_set_elem_xml_parse(e, data);
+               ret = nft_set_elem_xml_parse(e, data, err);
                break;
        default:
                errno = EOPNOTSUPP;
index 9e20768325eb40d8961167da7d2f4bde2ee69763..9b5f5c9c84e22dcab8edcb709ceaff11e1a770db 100644 (file)
@@ -211,13 +211,14 @@ int nft_table_nlmsg_parse(const struct nlmsghdr *nlh, struct nft_table *t)
 EXPORT_SYMBOL(nft_table_nlmsg_parse);
 
 #ifdef XML_PARSING
-int nft_mxml_table_parse(mxml_node_t *tree, struct nft_table *t)
+int nft_mxml_table_parse(mxml_node_t *tree, struct nft_table *t,
+                        struct nft_parse_err *err)
 {
        const char *name;
        int family;
 
        name = nft_mxml_str_parse(tree, "name", MXML_DESCEND_FIRST,
-                                 NFT_XML_MAND);
+                                 NFT_XML_MAND, err);
        if (name == NULL)
                return -1;
 
@@ -228,7 +229,7 @@ int nft_mxml_table_parse(mxml_node_t *tree, struct nft_table *t)
        t->flags |= (1 << NFT_TABLE_ATTR_NAME);
 
        family = nft_mxml_family_parse(tree, "family", MXML_DESCEND_FIRST,
-                                      NFT_XML_MAND);
+                                      NFT_XML_MAND, err);
        if (family < 0)
                return -1;
 
@@ -237,7 +238,7 @@ int nft_mxml_table_parse(mxml_node_t *tree, struct nft_table *t)
 
        if (nft_mxml_num_parse(tree, "flags", MXML_DESCEND, BASE_DEC,
                               &t->table_flags, NFT_TYPE_U32,
-                              NFT_XML_MAND) != 0)
+                              NFT_XML_MAND, err) != 0)
                return -1;
 
        t->flags |= (1 << NFT_TABLE_ATTR_FLAGS);
@@ -246,15 +247,16 @@ int nft_mxml_table_parse(mxml_node_t *tree, struct nft_table *t)
 }
 #endif
 
-static int nft_table_xml_parse(struct nft_table *t, const char *xml)
+static int nft_table_xml_parse(struct nft_table *t, const char *xml,
+                              struct nft_parse_err *err)
 {
 #ifdef XML_PARSING
        int ret;
-       mxml_node_t *tree = nft_mxml_build_tree(xml, "table");
+       mxml_node_t *tree = nft_mxml_build_tree(xml, "table", err);
        if (tree == NULL)
                return -1;
 
-       ret = nft_mxml_table_parse(tree, t);
+       ret = nft_mxml_table_parse(tree, t, err);
        mxmlDelete(tree);
        return ret;
 #else
@@ -264,29 +266,30 @@ static int nft_table_xml_parse(struct nft_table *t, const char *xml)
 }
 
 #ifdef JSON_PARSING
-int nft_jansson_parse_table(struct nft_table *t, json_t *tree)
+int nft_jansson_parse_table(struct nft_table *t, json_t *tree,
+                           struct nft_parse_err *err)
 {
        json_t *root;
        uint32_t flags;
        const char *str;
        int family;
 
-       root = nft_jansson_get_node(tree, "table");
+       root = nft_jansson_get_node(tree, "table", err);
        if (root == NULL)
                return -1;
 
-       str = nft_jansson_parse_str(root, "name");
+       str = nft_jansson_parse_str(root, "name", err);
        if (str == NULL)
                goto err;
 
        nft_table_attr_set_str(t, NFT_TABLE_ATTR_NAME, str);
 
-       if (nft_jansson_parse_family(root, &family) != 0)
+       if (nft_jansson_parse_family(root, &family, err) != 0)
                goto err;
 
        nft_table_attr_set_u32(t, NFT_TABLE_ATTR_FAMILY, family);
 
-       if (nft_jansson_parse_val(root, "flags", NFT_TYPE_U32, &flags) < 0)
+       if (nft_jansson_parse_val(root, "flags", NFT_TYPE_U32, &flags, err) < 0)
                goto err;
 
        nft_table_attr_set_u32(t, NFT_TABLE_ATTR_FLAGS, flags);
@@ -299,17 +302,18 @@ err:
 }
 #endif
 
-static int nft_table_json_parse(struct nft_table *t, const char *json)
+static int nft_table_json_parse(struct nft_table *t, const char *json,
+                               struct nft_parse_err *err)
 {
 #ifdef JSON_PARSING
        json_t *tree;
        json_error_t error;
 
-       tree = nft_jansson_create_root(json, &error);
+       tree = nft_jansson_create_root(json, &error, err);
        if (tree == NULL)
                return -1;
 
-       return nft_jansson_parse_table(t, tree);
+       return nft_jansson_parse_table(t, tree, err);
 #else
        errno = EOPNOTSUPP;
        return -1;
@@ -317,16 +321,17 @@ static int nft_table_json_parse(struct nft_table *t, const char *json)
 }
 
 int nft_table_parse(struct nft_table *t, enum nft_parse_type type,
-                   const char *data)
+                   const char *data, struct nft_parse_err *err)
 {
        int ret;
+       struct nft_parse_err perr;
 
        switch (type) {
        case NFT_PARSE_XML:
-               ret = nft_table_xml_parse(t, data);
+               ret = nft_table_xml_parse(t, data, &perr);
                break;
        case NFT_PARSE_JSON:
-               ret = nft_table_json_parse(t, data);
+               ret = nft_table_json_parse(t, data, &perr);
                break;
        default:
                ret = -1;
@@ -334,6 +339,9 @@ int nft_table_parse(struct nft_table *t, enum nft_parse_type type,
                break;
        }
 
+       if (err != NULL)
+               *err = perr;
+
        return ret;
 }
 EXPORT_SYMBOL(nft_table_parse);
index 6a5ab4db8f35c09d4c25868ff17363956457ac72..558c849c350052201b8c5d692c6cd4fba81fd037 100644 (file)
@@ -167,7 +167,7 @@ static int compare_test(uint32_t type, void *input, const char *filename)
 }
 #endif
 
-static int test_json(const char *filename)
+static int test_json(const char *filename, struct nft_parse_err *err)
 {
 #ifdef JSON_PARSING
        int ret = -1;
@@ -181,17 +181,15 @@ static int test_json(const char *filename)
        char *json;
 
        root = json_load_file(filename, 0, &error);
-       if (!root) {
-               printf("Error on the line %d : %s", error.line, error.text);
+       if (!root)
                return -1;
-       }
 
        json = json_dumps(root, JSON_INDENT(0));
 
        if (json_object_get(root, "table") != NULL) {
                t = nft_table_alloc();
                if (t != NULL) {
-                       if (nft_table_parse(t, NFT_PARSE_JSON, json) == 0)
+                       if (nft_table_parse(t, NFT_PARSE_JSON, json, err) == 0)
                                ret = compare_test(TEST_JSON_TABLE, t, filename);
                        else
                                goto failparsing;
@@ -201,7 +199,7 @@ static int test_json(const char *filename)
        } else if (json_object_get(root, "chain") != NULL) {
                c = nft_chain_alloc();
                if (c != NULL) {
-                       if (nft_chain_parse(c, NFT_PARSE_JSON, json) == 0)
+                       if (nft_chain_parse(c, NFT_PARSE_JSON, json, err) == 0)
                                ret = compare_test(TEST_JSON_CHAIN, c, filename);
                        else
                                goto failparsing;
@@ -211,7 +209,7 @@ static int test_json(const char *filename)
        } else if (json_object_get(root, "rule") != NULL) {
                r = nft_rule_alloc();
                if (r != NULL) {
-                       if (nft_rule_parse(r, NFT_PARSE_JSON, json) == 0)
+                       if (nft_rule_parse(r, NFT_PARSE_JSON, json, err) == 0)
                                ret = compare_test(TEST_JSON_RULE, r, filename);
                        else
                                goto failparsing;
@@ -221,7 +219,7 @@ static int test_json(const char *filename)
        } else if (json_object_get(root, "set") != NULL) {
                s = nft_set_alloc();
                if (s != NULL) {
-                       if (nft_set_parse(s, NFT_PARSE_JSON, json) == 0)
+                       if (nft_set_parse(s, NFT_PARSE_JSON, json, err) == 0)
                                ret = compare_test(TEST_JSON_SET, s, filename);
                        else
                                goto failparsing;
@@ -231,7 +229,7 @@ static int test_json(const char *filename)
        } else if (json_object_get(root, "nftables") != NULL) {
                rs = nft_ruleset_alloc();
                if (rs != NULL) {
-                       if (nft_ruleset_parse(rs, NFT_PARSE_JSON, json) == 0)
+                       if (nft_ruleset_parse(rs, NFT_PARSE_JSON, json, err) == 0)
                                ret = compare_test(TEST_JSON_RULESET, rs, filename);
                        else
                                goto failparsing;
@@ -256,7 +254,7 @@ failparsing:
 #endif
 }
 
-static int test_xml(const char *filename)
+static int test_xml(const char *filename, struct nft_parse_err *err)
 {
 #ifdef XML_PARSING
        int ret = -1;
@@ -290,7 +288,7 @@ static int test_xml(const char *filename)
        if (strcmp(tree->value.opaque, "table") == 0) {
                t = nft_table_alloc();
                if (t != NULL) {
-                       if (nft_table_parse(t, NFT_PARSE_XML, xml) == 0)
+                       if (nft_table_parse(t, NFT_PARSE_XML, xml, err) == 0)
                                ret = compare_test(TEST_XML_TABLE, t, filename);
                        else
                                goto failparsing;
@@ -300,7 +298,7 @@ static int test_xml(const char *filename)
        } else if (strcmp(tree->value.opaque, "chain") == 0) {
                c = nft_chain_alloc();
                if (c != NULL) {
-                       if (nft_chain_parse(c, NFT_PARSE_XML, xml) == 0)
+                       if (nft_chain_parse(c, NFT_PARSE_XML, xml, err) == 0)
                                ret = compare_test(TEST_XML_CHAIN, c, filename);
                        else
                                goto failparsing;
@@ -310,7 +308,7 @@ static int test_xml(const char *filename)
        } else if (strcmp(tree->value.opaque, "rule") == 0) {
                r = nft_rule_alloc();
                if (r != NULL) {
-                       if (nft_rule_parse(r, NFT_PARSE_XML, xml) == 0)
+                       if (nft_rule_parse(r, NFT_PARSE_XML, xml, err) == 0)
                                ret = compare_test(TEST_XML_RULE, r, filename);
                        else
                                goto failparsing;
@@ -320,7 +318,7 @@ static int test_xml(const char *filename)
        } else if (strcmp(tree->value.opaque, "set") == 0) {
                s = nft_set_alloc();
                if (s != NULL) {
-                       if (nft_set_parse(s, NFT_PARSE_XML, xml) == 0)
+                       if (nft_set_parse(s, NFT_PARSE_XML, xml, err) == 0)
                                ret = compare_test(TEST_XML_SET, s, filename);
                        else
                                goto failparsing;
@@ -331,7 +329,7 @@ static int test_xml(const char *filename)
                rs = nft_ruleset_alloc();
                if (rs != NULL) {
                        if (nft_ruleset_parse(rs, NFT_PARSE_XML,
-                                             xml) == 0)
+                                             xml, err) == 0)
                                ret = compare_test(TEST_XML_RULESET, rs,
                                                   filename);
                        else
@@ -361,6 +359,7 @@ int main(int argc, char *argv[])
        struct dirent *dent;
        char path[PATH_MAX];
        int ret = 0, exit_code = 0;
+       struct nft_parse_err *err;
 
        if (argc != 2) {
                fprintf(stderr, "Usage: %s <directory>\n", argv[0]);
@@ -373,6 +372,12 @@ int main(int argc, char *argv[])
                exit(EXIT_FAILURE);
        }
 
+       err = nft_parse_err_alloc();
+       if (err == NULL) {
+               perror("error");
+               exit(EXIT_FAILURE);
+       }
+
        while ((dent = readdir(d)) != NULL) {
                int len = strlen(dent->d_name);
 
@@ -383,14 +388,14 @@ int main(int argc, char *argv[])
                snprintf(path, sizeof(path), "%s/%s", argv[1], dent->d_name);
 
                if (strcmp(&dent->d_name[len-4], ".xml") == 0) {
-                       if ((ret = test_xml(path)) == 0) {
+                       if ((ret = test_xml(path, err)) == 0) {
                                printf("parsing and validating %s: ", path);
                                printf("\033[32mOK\e[0m\n");
                        }
                        exit_code += ret;
                }
                if (strcmp(&dent->d_name[len-5], ".json") == 0) {
-                       if ((ret = test_json(path)) == 0) {
+                       if ((ret = test_json(path, err)) == 0) {
                                printf("parsing and validating %s: ", path);
                                printf("\033[32mOK\e[0m\n");
                        }
@@ -399,6 +404,7 @@ int main(int argc, char *argv[])
        }
 
        closedir(d);
+       nft_parse_err_free(err);
 
        if (exit_code != 0)
                exit(EXIT_FAILURE);