summaryrefslogtreecommitdiffstats
path: root/src/set.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/set.c')
-rw-r--r--src/set.c119
1 files changed, 76 insertions, 43 deletions
diff --git a/src/set.c b/src/set.c
index c5204cc..c3a7fae 100644
--- a/src/set.c
+++ b/src/set.c
@@ -23,7 +23,7 @@
#include <linux/netfilter/nfnetlink.h>
#include <linux/netfilter/nf_tables.h>
-#include <libnftables/set.h>
+#include <libnftnl/set.h>
#include "linux_list.h"
#include "expr/data_reg.h"
@@ -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,8 @@ 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_jansson_set_elem_parse(elem,
+ json_elem, err) < 0)
goto err;
list_add_tail(&elem->head, &s->element_list);
@@ -371,17 +375,19 @@ 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 void *json,
+ struct nft_parse_err *err,
+ enum nft_parse_input input)
{
#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, input);
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 +395,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 +404,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 +415,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 +426,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,34 +435,35 @@ 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)
- return -1;
-
- s->flags |= (1 << NFT_SET_ATTR_DATA_TYPE);
+ &s->data_type, NFT_TYPE_U32,
+ NFT_XML_OPT, err) == 0) {
+ 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)
- return -1;
+ if (nft_mxml_num_parse(tree, "data_len", MXML_DESCEND_FIRST,
+ BASE_DEC, &s->data_len, NFT_TYPE_U32,
+ NFT_XML_MAND, err) != 0)
+ return -1;
- s->flags |= (1 << NFT_SET_ATTR_DATA_LEN);
+ s->flags |= (1 << NFT_SET_ATTR_DATA_LEN);
+ }
for (node = mxmlFindElement(tree, tree, "set_elem", NULL,
NULL, MXML_DESCEND);
@@ -467,7 +475,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 +485,17 @@ 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 void *xml,
+ struct nft_parse_err *err,
+ enum nft_parse_input input)
{
#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, input);
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
@@ -494,17 +504,19 @@ static int nft_set_xml_parse(struct nft_set *s, const char *xml)
#endif
}
-int nft_set_parse(struct nft_set *s, enum nft_parse_type type,
- const char *data)
+static int nft_set_do_parse(struct nft_set *s, enum nft_parse_type type,
+ const void *data, struct nft_parse_err *err,
+ enum nft_parse_input input)
{
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, input);
break;
case NFT_PARSE_JSON:
- ret = nft_set_json_parse(s, data);
+ ret = nft_set_json_parse(s, data, &perr, input);
break;
default:
ret = -1;
@@ -512,10 +524,25 @@ int nft_set_parse(struct nft_set *s, enum nft_parse_type type,
break;
}
+ if (err != NULL)
+ *err = perr;
+
return ret;
}
+int nft_set_parse(struct nft_set *s, enum nft_parse_type type,
+ const char *data, struct nft_parse_err *err)
+{
+ return nft_set_do_parse(s, type, data, err, NFT_PARSE_BUFFER);
+}
EXPORT_SYMBOL(nft_set_parse);
+int nft_set_parse_file(struct nft_set *s, enum nft_parse_type type,
+ FILE *fp, struct nft_parse_err *err)
+{
+ return nft_set_do_parse(s, type, fp, err, NFT_PARSE_FILE);
+}
+EXPORT_SYMBOL(nft_set_parse_file);
+
static int nft_set_snprintf_json(char *buf, size_t size, struct nft_set *s,
uint32_t type, uint32_t flags)
{
@@ -608,14 +635,20 @@ static int nft_set_snprintf_xml(char *buf, size_t size, struct nft_set *s,
"<name>%s</name>"
"<flags>%u</flags>"
"<key_type>%u</key_type>"
- "<key_len>%u</key_len>"
- "<data_type>%u</data_type>"
- "<data_len>%u</data_len>",
+ "<key_len>%u</key_len>",
nft_family2str(s->family), s->table, s->name,
- s->set_flags, s->key_type,
- s->key_len, s->data_type, s->data_len);
+ s->set_flags, s->key_type, s->key_len);
SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
+ if (s->flags & (1 << NFT_SET_ATTR_DATA_TYPE) &&
+ s->flags & (1 << NFT_SET_ATTR_DATA_LEN)) {
+ ret = snprintf(buf+offset, len, "<data_type>%u</data_type>"
+ "<data_len>%u</data_len>",
+ s->data_type, s->data_len);
+
+ SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
+ }
+
if (!list_empty(&s->element_list)) {
list_for_each_entry(elem, &s->element_list, head) {
ret = nft_set_elem_snprintf(buf+offset, len, elem,