]> git.ipfire.org Git - thirdparty/libnftnl.git/commitdiff
set: Add json parser support
authorÁlvaro Neira Ayuso <alvaroneay@gmail.com>
Tue, 27 Aug 2013 18:10:47 +0000 (20:10 +0200)
committerPablo Neira Ayuso <pablo@netfilter.org>
Tue, 27 Aug 2013 22:21:24 +0000 (00:21 +0200)
Add function for parsing set in format JSON.

Signed-off-by: Alvaro Neira Ayuso <alvaroneay@gmail.com>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
include/libnftables/set.h
src/internal.h
src/jansson.c
src/set.c

index c55718c86ddb3b7855de0c2ccbcd8fd77013f54a..9526ae11c4d51a0dcf62a3460ada2ba459288b35 100644 (file)
@@ -55,6 +55,7 @@ void nft_set_list_iter_destroy(struct nft_set_list_iter *iter);
 enum nft_set_parse_type {
        NFT_SET_PARSE_NONE      = 0,
        NFT_SET_PARSE_XML,
+       NFT_SET_PARSE_JSON,
        NFT_SET_PARSE_MAX,
 };
 
index 66989621fda53c7bdffe55cde8a3dae85493b237..2a36543f63c650058300faa564198a3d6b03a496 100644 (file)
@@ -58,6 +58,7 @@ struct nft_rule_expr *nft_jansson_expr_parse(json_t *root);
 union nft_data_reg;
 int nft_jansson_data_reg_parse(json_t *root, const char *tag,
                               union nft_data_reg *data_reg);
+int nft_set_elem_json_parse(struct nft_set_elem *e, json_t *root);
 #endif
 
 const char *nft_family2str(uint32_t family);
index 682b74b80bff8a2134736b4660d75f7116462141..04146e20e6ce68c46a9d294321b2b07affedb9e0 100644 (file)
@@ -16,6 +16,7 @@
 #include <errno.h>
 #include <string.h>
 #include "expr_ops.h"
+#include <libnftables/set.h>
 
 #include <libnftables/expr.h>
 #include <linux/netfilter/nf_tables.h>
@@ -210,4 +211,40 @@ int nft_jansson_data_reg_parse(json_t *root, const char *tag,
                return -1;
        }
 }
+
+int nft_set_elem_json_parse(struct nft_set_elem *e, json_t *root)
+{
+       uint32_t uval32;
+       int set_elem_data;
+
+       if (nft_jansson_parse_val(root, "flags", NFT_TYPE_U32, &uval32) < 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)
+               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);
+               switch (set_elem_data) {
+               case DATA_VALUE:
+                       e->flags |= (1 << NFT_SET_ELEM_ATTR_DATA);
+                       break;
+               case DATA_VERDICT:
+                       e->flags |= (1 << NFT_SET_ELEM_ATTR_VERDICT);
+                       break;
+               case DATA_CHAIN:
+                       e->flags |= (1 << NFT_SET_ELEM_ATTR_CHAIN);
+                       break;
+               default:
+                       return -1;
+               }
+       }
+
+       return 0;
+}
 #endif
index 3617265de617b83b7474fa072fca8343bdf44ecb..1168b54d17d10200d6000bed8ac8805c7885a9fd 100644 (file)
--- a/src/set.c
+++ b/src/set.c
@@ -303,6 +303,102 @@ int nft_set_nlmsg_parse(const struct nlmsghdr *nlh, struct nft_set *s)
 }
 EXPORT_SYMBOL(nft_set_nlmsg_parse);
 
+static int nft_set_json_parse(struct nft_set *s, const char *json)
+{
+#ifdef JSON_PARSING
+       json_t *root, *node, *array, *json_elem;
+       json_error_t error;
+       uint32_t uval32;
+       int family, i;
+       const char *valstr;
+       struct nft_set_elem *elem;
+
+       node = nft_jansson_create_root(json, &error);
+       if (node == NULL)
+               return -1;
+
+       root = nft_jansson_get_node(node, "set");
+       if (root == NULL)
+               return -1;
+
+       valstr = nft_jansson_parse_str(root, "name");
+       if (valstr == NULL)
+               return -1;
+
+       nft_set_attr_set_str(s, NFT_SET_ATTR_NAME, valstr);
+
+       valstr = nft_jansson_parse_str(root, "table");
+       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)
+               return -1;
+
+       nft_set_attr_set_u32(s, NFT_SET_ATTR_FLAGS, uval32);
+
+       if (nft_jansson_parse_family(root, &family) < 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)
+               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)
+               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)
+                       goto err;
+
+               nft_set_attr_set_u32(s, NFT_SET_ATTR_DATA_TYPE, uval32);
+       }
+
+       if (nft_jansson_node_exist(root, "data_len")) {
+               if (nft_jansson_parse_val(root, "data_len", NFT_TYPE_U32,
+                                         &uval32) < 0)
+                       goto err;
+
+               nft_set_attr_set_u32(s, NFT_SET_ATTR_DATA_LEN, uval32);
+       }
+
+       if (nft_jansson_node_exist(root, "set_elem")) {
+               array = json_object_get(root, "set_elem");
+               for (i = 0; i < json_array_size(array); i++) {
+                       elem = nft_set_elem_alloc();
+                       if (elem == NULL)
+                               goto err;
+
+                       json_elem = json_array_get(array, i);
+                       if (json_elem == NULL)
+                               goto err;
+
+                       if (nft_set_elem_json_parse(elem, json_elem) < 0)
+                               goto err;
+
+                       list_add_tail(&elem->head, &s->element_list);
+               }
+
+       }
+
+       nft_jansson_free_root(node);
+       return 0;
+err:
+       nft_jansson_free_root(node);
+       return -1;
+#else
+       errno = EOPNOTSUPP;
+       return -1;
+#endif
+}
+
 static int nft_set_xml_parse(struct nft_set *s, const char *xml)
 {
 #ifdef XML_PARSING
@@ -415,6 +511,9 @@ int nft_set_parse(struct nft_set *s, enum nft_set_parse_type type,
        case NFT_SET_PARSE_XML:
                ret = nft_set_xml_parse(s, data);
                break;
+       case NFT_SET_PARSE_JSON:
+               ret = nft_set_json_parse(s, data);
+               break;
        default:
                ret = -1;
                errno = EOPNOTSUPP;