summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am76
-rw-r--r--src/chain.c111
-rw-r--r--src/common.c34
-rw-r--r--src/expr.c2
-rw-r--r--src/expr/bitwise.c36
-rw-r--r--src/expr/byteorder.c38
-rw-r--r--src/expr/cmp.c33
-rw-r--r--src/expr/counter.c20
-rw-r--r--src/expr/ct.c167
-rw-r--r--src/expr/data_reg.c232
-rw-r--r--src/expr/data_reg.h6
-rw-r--r--src/expr/exthdr.c39
-rw-r--r--src/expr/immediate.c22
-rw-r--r--src/expr/limit.c21
-rw-r--r--src/expr/log.c31
-rw-r--r--src/expr/lookup.c78
-rw-r--r--src/expr/match.c14
-rw-r--r--src/expr/meta.c80
-rw-r--r--src/expr/nat.c44
-rw-r--r--src/expr/payload.c37
-rw-r--r--src/expr/queue.c4
-rw-r--r--src/expr/reject.c20
-rw-r--r--src/expr/target.c14
-rw-r--r--src/expr_ops.h6
-rw-r--r--src/internal.h104
-rw-r--r--src/jansson.c144
-rw-r--r--src/libnftnl.map (renamed from src/libnftables.map)12
-rw-r--r--src/mxml.c126
-rw-r--r--src/rule.c90
-rw-r--r--src/ruleset.c99
-rw-r--r--src/set.c119
-rw-r--r--src/set_elem.c70
-rw-r--r--src/table.c64
-rw-r--r--src/utils.c28
34 files changed, 1275 insertions, 746 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 441e96e..450279f 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1,40 +1,40 @@
include $(top_srcdir)/Make_global.am
-lib_LTLIBRARIES = libnftables.la
+lib_LTLIBRARIES = libnftnl.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 \
- chain.c \
- rule.c \
- set.c \
- set_elem.c \
- ruleset.c \
- mxml.c \
- jansson.c \
- expr.c \
- expr_ops.c \
- expr/bitwise.c \
- expr/byteorder.c \
- expr/cmp.c \
- expr/counter.c \
- expr/ct.c \
- expr/data_reg.c \
- expr/exthdr.c \
- expr/limit.c \
- expr/log.c \
- expr/lookup.c \
- expr/immediate.c \
- expr/match.c \
- expr/meta.c \
- expr/nat.c \
- expr/payload.c \
- expr/queue.c \
- expr/reject.c \
- expr/target.c \
- expr/data_reg.h \
- libnftables.map \
- expr_ops.h \
- internal.h
+libnftnl_la_LIBADD = ${LIBMNL_LIBS} ${LIBXML_LIBS} ${LIBJSON_LIBS}
+libnftnl_la_LDFLAGS = -Wl,--version-script=$(srcdir)/libnftnl.map \
+ -version-info $(LIBVERSION)
+
+libnftnl_la_SOURCES = utils.c \
+ common.c \
+ table.c \
+ chain.c \
+ rule.c \
+ set.c \
+ set_elem.c \
+ ruleset.c \
+ mxml.c \
+ jansson.c \
+ expr.c \
+ expr_ops.c \
+ expr/bitwise.c \
+ expr/byteorder.c \
+ expr/cmp.c \
+ expr/counter.c \
+ expr/ct.c \
+ expr/data_reg.c \
+ expr/exthdr.c \
+ expr/limit.c \
+ expr/log.c \
+ expr/lookup.c \
+ expr/immediate.c \
+ expr/match.c \
+ expr/meta.c \
+ expr/nat.c \
+ expr/payload.c \
+ expr/reject.c \
+ expr/target.c \
+ expr/data_reg.h \
+ libnftnl.map \
+ expr_ops.h \
+ internal.h
diff --git a/src/chain.c b/src/chain.c
index b1a692a..2cc7c61 100644
--- a/src/chain.c
+++ b/src/chain.c
@@ -26,7 +26,7 @@
#include <linux/netfilter.h>
#include <linux/netfilter_arp.h>
-#include <libnftables/chain.h>
+#include <libnftnl/chain.h>
struct nft_chain {
struct list_head head;
@@ -499,45 +499,49 @@ 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;
- uint32_t policy;
+ int policy;
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;
@@ -545,7 +549,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;
@@ -553,12 +557,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;
@@ -568,13 +572,16 @@ 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;
- policy = nft_str2verdict(valstr);
- if (policy == -1)
+ if (nft_str2verdict(valstr, &policy) != 0) {
+ errno = EINVAL;
+ err->node_name = "policy";
+ err->error = NFT_PARSE_EBADTYPE;
goto err;
+ }
nft_chain_attr_set_u32(c, NFT_CHAIN_ATTR_POLICY, policy);
}
@@ -588,17 +595,19 @@ 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 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_chain(c, tree);
+ return nft_jansson_parse_chain(c, tree, err);
#else
errno = EOPNOTSUPP;
return -1;
@@ -606,13 +615,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;
@@ -620,25 +630,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;
@@ -649,7 +659,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;
@@ -657,7 +667,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)
@@ -667,7 +677,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;
@@ -680,20 +690,23 @@ 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;
- policy = nft_str2verdict(policy_str);
- if (policy == -1)
+ if (nft_str2verdict(policy_str, &policy) != 0) {
+ errno = EINVAL;
+ err->node_name = "policy";
+ err->error = NFT_PARSE_EBADTYPE;
return -1;
+ }
c->policy = policy;
c->flags |= (1 << NFT_CHAIN_ATTR_POLICY);
@@ -703,15 +716,17 @@ 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 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, "chain");
+ mxml_node_t *tree = nft_mxml_build_tree(xml, "chain", err, input);
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,17 +735,19 @@ static int nft_chain_xml_parse(struct nft_chain *c, const char *xml)
#endif
}
-int nft_chain_parse(struct nft_chain *c, enum nft_parse_type type,
- const char *data)
+static int nft_chain_do_parse(struct nft_chain *c, 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_chain_xml_parse(c, data);
+ ret = nft_chain_xml_parse(c, data, &perr, input);
break;
case NFT_PARSE_JSON:
- ret = nft_chain_json_parse(c, data);
+ ret = nft_chain_json_parse(c, data, &perr, input);
break;
default:
ret = -1;
@@ -738,10 +755,26 @@ int nft_chain_parse(struct nft_chain *c, enum nft_parse_type type,
break;
}
+ if (err != NULL)
+ *err = perr;
+
return ret;
}
+
+int nft_chain_parse(struct nft_chain *c, enum nft_parse_type type,
+ const char *data, struct nft_parse_err *err)
+{
+ return nft_chain_do_parse(c, type, data, err, NFT_PARSE_BUFFER);
+}
EXPORT_SYMBOL(nft_chain_parse);
+int nft_chain_parse_file(struct nft_chain *c, enum nft_parse_type type,
+ FILE *fp, struct nft_parse_err *err)
+{
+ return nft_chain_do_parse(c, type, fp, err, NFT_PARSE_FILE);
+}
+EXPORT_SYMBOL(nft_chain_parse_file);
+
static int nft_chain_snprintf_json(char *buf, size_t size, struct nft_chain *c)
{
int ret, len = size, offset = 0;
diff --git a/src/common.c b/src/common.c
index f03e730..336d2b4 100644
--- a/src/common.c
+++ b/src/common.c
@@ -7,11 +7,13 @@
* (at your option) any later version.
*/
+#include <stdlib.h>
+#include <sys/socket.h>
#include <linux/netlink.h>
#include <linux/netfilter/nfnetlink.h>
#include <libmnl/libmnl.h>
-#include <libnftables/common.h>
+#include <libnftnl/common.h>
#include "internal.h"
@@ -34,3 +36,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);
diff --git a/src/expr.c b/src/expr.c
index aeb717e..55557da 100644
--- a/src/expr.c
+++ b/src/expr.c
@@ -22,7 +22,7 @@
#include <linux/netfilter/nfnetlink.h>
#include <linux/netfilter/nf_tables.h>
-#include <libnftables/expr.h>
+#include <libnftnl/expr.h>
#include "linux_list.h"
diff --git a/src/expr/bitwise.c b/src/expr/bitwise.c
index bcec516..c8fd0ec 100644
--- a/src/expr/bitwise.c
+++ b/src/expr/bitwise.c
@@ -18,8 +18,8 @@
#include <errno.h>
#include <libmnl/libmnl.h>
#include <linux/netfilter/nf_tables.h>
-#include <libnftables/expr.h>
-#include <libnftables/rule.h>
+#include <libnftnl/expr.h>
+#include <libnftnl/rule.h>
#include "data_reg.h"
#include "expr_ops.h"
@@ -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,21 +226,22 @@ 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;
+ uint32_t reg;
- reg = nft_mxml_reg_parse(tree, "sreg", MXML_DESCEND_FIRST);
- if (reg < 0)
+ if (nft_mxml_reg_parse(tree, "sreg", &reg, MXML_DESCEND_FIRST,
+ NFT_XML_MAND, err) != 0)
return -1;
bitwise->sreg = reg;
e->flags |= (1 << NFT_EXPR_BITWISE_SREG);
- reg = nft_mxml_reg_parse(tree, "dreg", MXML_DESCEND);
- if (reg < 0)
+ if (nft_mxml_reg_parse(tree, "dreg", &reg, MXML_DESCEND_FIRST,
+ NFT_XML_MAND, err) != 0)
return -1;
bitwise->dreg = reg;
@@ -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);
diff --git a/src/expr/byteorder.c b/src/expr/byteorder.c
index 7224c82..4889e80 100644
--- a/src/expr/byteorder.c
+++ b/src/expr/byteorder.c
@@ -18,8 +18,8 @@
#include <errno.h>
#include <libmnl/libmnl.h>
#include <linux/netfilter/nf_tables.h>
-#include <libnftables/expr.h>
-#include <libnftables/rule.h>
+#include <libnftnl/expr.h>
+#include <libnftnl/rule.h>
#include "data_reg.h"
#include "expr_ops.h"
@@ -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,31 @@ 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;
+ int32_t ntoh;
+ uint32_t reg;
- reg = nft_mxml_reg_parse(tree, "sreg", MXML_DESCEND_FIRST);
- if (reg < 0)
+ if (nft_mxml_reg_parse(tree, "sreg", &reg, MXML_DESCEND_FIRST,
+ NFT_XML_MAND, err) != 0)
return -1;
byteorder->sreg = reg;
e->flags |= (1 << NFT_EXPR_BYTEORDER_SREG);
- reg = nft_mxml_reg_parse(tree, "dreg", MXML_DESCEND);
- if (reg < 0)
+ if (nft_mxml_reg_parse(tree, "dreg", &reg, MXML_DESCEND, NFT_XML_MAND,
+ err) != 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 +277,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);
diff --git a/src/expr/cmp.c b/src/expr/cmp.c
index 1c5787e..63250f3 100644
--- a/src/expr/cmp.c
+++ b/src/expr/cmp.c
@@ -19,15 +19,15 @@
#include <libmnl/libmnl.h>
#include <linux/netfilter/nf_tables.h>
-#include <libnftables/expr.h>
-#include <libnftables/rule.h>
+#include <libnftnl/expr.h>
+#include <libnftnl/rule.h>
#include "expr_ops.h"
#include "data_reg.h"
struct nft_expr_cmp {
union nft_data_reg data;
- uint32_t sreg; /* enum nft_registers */
- uint32_t op; /* enum nft_cmp_ops */
+ enum nft_registers sreg;
+ enum nft_cmp_ops op;
};
static int
@@ -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,24 @@ 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;
+ int32_t op_value;
+ uint32_t reg;
- reg = nft_mxml_reg_parse(tree, "sreg", MXML_DESCEND_FIRST);
- if (reg < 0)
+ if (nft_mxml_reg_parse(tree, "sreg", &reg, MXML_DESCEND_FIRST,
+ NFT_XML_MAND, err) != 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 +240,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);
diff --git a/src/expr/counter.c b/src/expr/counter.c
index 4919a69..4bb7f1b 100644
--- a/src/expr/counter.c
+++ b/src/expr/counter.c
@@ -19,8 +19,8 @@
#include "internal.h"
#include <libmnl/libmnl.h>
-#include <libnftables/expr.h>
-#include <libnftables/rule.h>
+#include <libnftnl/expr.h>
+#include <libnftnl/rule.h>
#include "expr_ops.h"
struct nft_expr_counter {
@@ -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);
diff --git a/src/expr/ct.c b/src/expr/ct.c
index 49d8495..2df761c 100644
--- a/src/expr/ct.c
+++ b/src/expr/ct.c
@@ -18,8 +18,8 @@
#include "internal.h"
#include <libmnl/libmnl.h>
-#include <libnftables/expr.h>
-#include <libnftables/rule.h>
+#include <libnftnl/expr.h>
+#include <libnftnl/rule.h>
#include "expr_ops.h"
struct nft_expr_ct {
@@ -141,10 +141,6 @@ nft_rule_expr_ct_parse(struct nft_rule_expr *e, struct nlattr *attr)
ct->key = ntohl(mnl_attr_get_u32(tb[NFTA_CT_KEY]));
e->flags |= (1 << NFT_EXPR_CT_KEY);
}
- if (tb[NFTA_CT_DIRECTION]) {
- ct->dir = mnl_attr_get_u8(tb[NFTA_CT_DIRECTION]);
- e->flags |= (1 << NFT_EXPR_CT_DIR);
- }
if (tb[NFTA_CT_DREG]) {
ct->dreg = ntohl(mnl_attr_get_u32(tb[NFTA_CT_DREG]));
e->flags |= (1 << NFT_EXPR_CT_DREG);
@@ -153,6 +149,10 @@ nft_rule_expr_ct_parse(struct nft_rule_expr *e, struct nlattr *attr)
ct->sreg = ntohl(mnl_attr_get_u32(tb[NFTA_CT_SREG]));
e->flags |= (1 << NFT_EXPR_CT_SREG);
}
+ if (tb[NFTA_CT_DIRECTION]) {
+ ct->dir = mnl_attr_get_u8(tb[NFTA_CT_DIRECTION]);
+ e->flags |= (1 << NFT_EXPR_CT_DIR);
+ }
return 0;
}
@@ -165,6 +165,7 @@ const char *ctkey2str_array[NFT_CT_MAX] = {
[NFT_CT_SECMARK] = "secmark",
[NFT_CT_EXPIRATION] = "expiration",
[NFT_CT_HELPER] = "helper",
+ [NFT_CT_L3PROTOCOL] = "l3protocol",
[NFT_CT_PROTOCOL] = "protocol",
[NFT_CT_SRC] = "src",
[NFT_CT_DST] = "dst",
@@ -192,30 +193,58 @@ 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 const char *ctdir2str(uint8_t ctdir)
+{
+ switch (ctdir) {
+ case IP_CT_DIR_ORIGINAL:
+ return "original";
+ case IP_CT_DIR_REPLY:
+ return "reply";
+ default:
+ return "unknow";
+ }
+}
+
+static inline int str2ctdir(const char *str, uint8_t *ctdir)
+{
+ if (strcmp(str, "original") == 0) {
+ *ctdir = IP_CT_DIR_ORIGINAL;
+ return 0;
+ }
+
+ if (strcmp(str, "reply") == 0) {
+ *ctdir = IP_CT_DIR_REPLY;
+ return 0;
+ }
+
+ return -1;
+}
+
+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;
+ const char *key_str, *dir_str;
uint32_t reg;
uint8_t dir;
int key;
if (nft_jansson_node_exist(root, "dreg")) {
- 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, "sreg")) {
- 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_CT_SREG, 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;
@@ -228,11 +257,15 @@ 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)
+ dir_str = nft_jansson_parse_str(root, "dir", err);
+ if (dir_str == NULL)
return -1;
- if (dir != IP_CT_DIR_ORIGINAL && dir != IP_CT_DIR_REPLY)
+ if (str2ctdir(dir_str, &dir) != 0) {
+ err->node_name = "dir";
+ err->error = NFT_PARSE_EBADTYPE;
goto err;
+ }
nft_rule_expr_set_u8(e, NFT_EXPR_CT_DIR, dir);
}
@@ -248,29 +281,30 @@ 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);
- const char *key_str;
- int32_t reg;
+ const char *key_str, *dir_str;
int key;
uint8_t dir;
+ uint32_t reg;
- reg = nft_mxml_reg_parse(tree, "dreg", MXML_DESCEND_FIRST);
- if (reg >= 0) {
+ if (nft_mxml_reg_parse(tree, "dreg", &reg, MXML_DESCEND_FIRST,
+ NFT_XML_OPT, err) >= 0) {
ct->dreg = reg;
e->flags |= (1 << NFT_EXPR_CT_DREG);
}
- reg = nft_mxml_reg_parse(tree, "sreg", MXML_DESCEND_FIRST);
- if (reg >= 0) {
+ if (nft_mxml_reg_parse(tree, "sreg", &reg, MXML_DESCEND_FIRST,
+ NFT_XML_OPT, err) >= 0) {
ct->sreg = reg;
e->flags |= (1 << NFT_EXPR_CT_SREG);
}
key_str = nft_mxml_str_parse(tree, "key", MXML_DESCEND_FIRST,
- NFT_XML_MAND);
+ NFT_XML_MAND, err);
if (key_str == NULL)
return -1;
@@ -281,15 +315,17 @@ static int nft_rule_expr_ct_xml_parse(struct nft_rule_expr *e, mxml_node_t *tree
ct->key = key;
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)
- return -1;
-
- if (dir != IP_CT_DIR_ORIGINAL && dir != IP_CT_DIR_REPLY)
- goto err;
+ dir_str = nft_mxml_str_parse(tree, "dir", MXML_DESCEND_FIRST,
+ NFT_XML_OPT, err);
+ if (dir_str != NULL) {
+ if (str2ctdir(dir_str, &dir) != 0) {
+ err->node_name = "dir";
+ err->error = NFT_PARSE_EBADTYPE;
+ goto err;
+ }
- ct->dir = dir;
- e->flags |= (1 << NFT_EXPR_CT_DIR);
+ nft_rule_expr_set_u8(e, NFT_EXPR_CT_DIR, dir);
+ }
return 0;
err:
@@ -302,21 +338,41 @@ err:
}
static int
-nft_rule_expr_ct_snprintf_default(char *buf, size_t size,
- struct nft_rule_expr *e)
+nft_expr_ct_snprintf_json(char *buf, size_t size, struct nft_rule_expr *e)
{
+ int ret, len = size, offset = 0;
struct nft_expr_ct *ct = nft_expr_data(e);
- if (e->flags & (1 << NFT_EXPR_CT_SREG))
- return snprintf(buf, size, "set %s with reg %u ",
- ctkey2str(ct->key), ct->sreg);
+ if (e->flags & (1 << NFT_EXPR_CT_DREG)) {
+ ret = snprintf(buf+offset, len, "\"dreg\":%u,", ct->dreg);
+ SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
+ }
+
+ if (e->flags & (1 << NFT_EXPR_CT_SREG)) {
+ ret = snprintf(buf+offset, len, "\"sreg:\":%u,", ct->sreg);
+ SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
+ }
+
+ if (e->flags & (1 << NFT_EXPR_CT_KEY)) {
+ ret = snprintf(buf+offset, len, "\"key\":\"%s\",",
+ ctkey2str(ct->key));
+ SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
+ }
+
+ if (nft_rule_expr_is_set(e, NFT_EXPR_CT_DIR)) {
+ ret = snprintf(buf+offset, len, "\"dir\":\"%s\",",
+ ctdir2str(ct->dir));
+ SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
+ }
+
+ /* Remove the last separator characther */
+ buf[offset-1] = '\0';
- return snprintf(buf, size, "load %s => reg %u dir %u ",
- ctkey2str(ct->key), ct->dreg, ct->dir);
+ return offset-1;
}
static int
-nft_rule_expr_ct_snprintf_xml(char *buf, size_t size, struct nft_rule_expr *e)
+nft_expr_ct_snprintf_xml(char *buf, size_t size, struct nft_rule_expr *e)
{
int ret, len = size, offset = 0;
struct nft_expr_ct *ct = nft_expr_data(e);
@@ -337,8 +393,9 @@ nft_rule_expr_ct_snprintf_xml(char *buf, size_t size, struct nft_rule_expr *e)
SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
}
- if (e->flags & (1 << NFT_EXPR_CT_DIR)) {
- ret = snprintf(buf+offset, len, "<dir>%u</dir>", ct->dir);
+ if (nft_rule_expr_is_set(e, NFT_EXPR_CT_DIR)) {
+ ret = snprintf(buf+offset, len, "<dir>%s</dir>",
+ ctdir2str(ct->dir));
SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
}
@@ -346,36 +403,30 @@ nft_rule_expr_ct_snprintf_xml(char *buf, size_t size, struct nft_rule_expr *e)
}
static int
-nft_rule_expr_ct_snprintf_json(char *buf, size_t size, struct nft_rule_expr *e)
+nft_expr_ct_snprintf_default(char *buf, size_t size, struct nft_rule_expr *e)
{
int ret, len = size, offset = 0;
struct nft_expr_ct *ct = nft_expr_data(e);
- if (e->flags & (1 << NFT_EXPR_CT_DREG)) {
- ret = snprintf(buf+offset, len, "\"dreg\":%u,", ct->dreg);
- SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
- }
-
if (e->flags & (1 << NFT_EXPR_CT_SREG)) {
- ret = snprintf(buf+offset, len, "\"sreg:\":%u,", ct->sreg);
+ ret = snprintf(buf, size, "set %s with reg %u ",
+ ctkey2str(ct->key), ct->sreg);
SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
}
- if (e->flags & (1 << NFT_EXPR_CT_KEY)) {
- ret = snprintf(buf+offset, len, "\"key\":\"%s\",",
- ctkey2str(ct->key));
+ if (e->flags & (1 << NFT_EXPR_CT_DREG)) {
+ ret = snprintf(buf, len, "load %s => reg %u ",
+ ctkey2str(ct->key), ct->dreg);
SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
}
- if (e->flags & (1 << NFT_EXPR_CT_DIR)) {
- ret = snprintf(buf+offset, len, "\"dir\":%u,", ct->dir);
+ if (nft_rule_expr_is_set(e, NFT_EXPR_CT_DIR)) {
+ ret = snprintf(buf+offset, len, ", dir %s ",
+ ctdir2str(ct->dir));
SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
}
- /* Remove the last separator characther */
- buf[offset-1] = '\0';
-
- return offset-1;
+ return offset;
}
static int
@@ -384,11 +435,11 @@ nft_rule_expr_ct_snprintf(char *buf, size_t len, uint32_t type,
{
switch(type) {
case NFT_OUTPUT_DEFAULT:
- return nft_rule_expr_ct_snprintf_default(buf, len, e);
+ return nft_expr_ct_snprintf_default(buf, len, e);
case NFT_OUTPUT_XML:
- return nft_rule_expr_ct_snprintf_xml(buf, len, e);
+ return nft_expr_ct_snprintf_xml(buf, len, e);
case NFT_OUTPUT_JSON:
- return nft_rule_expr_ct_snprintf_json(buf, len, e);
+ return nft_expr_ct_snprintf_json(buf, len, e);
default:
break;
}
diff --git a/src/expr/data_reg.c b/src/expr/data_reg.c
index a198c67..0523cb7 100644
--- a/src/expr/data_reg.c
+++ b/src/expr/data_reg.c
@@ -18,82 +18,85 @@
#include <netinet/in.h>
#include <libmnl/libmnl.h>
-#include <libnftables/expr.h>
-#include <libnftables/rule.h>
-#include "internal.h"
-
#include <linux/netfilter.h>
#include <linux/netfilter/nf_tables.h>
+#include <libnftnl/expr.h>
+#include <libnftnl/rule.h>
+#include "expr_ops.h"
+#include "data_reg.h"
+#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;
+ const char *chain;
- verdict_str = nft_jansson_parse_str(data, "verdict");
+ verdict_str = nft_jansson_parse_str(data, "verdict", err);
if (verdict_str == NULL)
- return -1;
+ return DATA_NONE;
- verdict = nft_str2verdict(verdict_str);
- if (verdict < 0)
+ if (nft_str2verdict(verdict_str, &verdict) != 0) {
+ err->node_name = "verdict";
+ err->error = NFT_PARSE_EBADTYPE;
+ errno = EINVAL;
return -1;
+ }
reg->verdict = (uint32_t)verdict;
- return 0;
-}
+ if (nft_jansson_node_exist(data, "chain")) {
+ chain = nft_jansson_parse_str(data, "chain", err);
+ if (chain == NULL)
+ return DATA_NONE;
-static int nft_data_reg_chain_json_parse(union nft_data_reg *reg, json_t *data)
-{
- reg->chain = strdup(nft_jansson_parse_str(data, "chain"));
- if (reg->chain == NULL) {
- return -1;
+ reg->chain = strdup(chain);
}
- return 0;
+ return DATA_VERDICT;
}
-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)
- return -1;
+ if (nft_jansson_parse_val(data, "len", NFT_TYPE_U8, &reg->len, err) < 0)
+ return DATA_NONE;
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)
- return -1;
+ &reg->val[i], NFT_TYPE_U32, err) != 0)
+ return DATA_NONE;
}
- return 0;
+ return DATA_VALUE;
}
#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);
- } else if (strcmp(type, "verdict") == 0) {
- return nft_data_reg_verdict_json_parse(reg, data);
- } else if (strcmp(type, "chain") == 0) {
- return nft_data_reg_chain_json_parse(reg, data);
- }
+ if (strcmp(type, "value") == 0)
+ 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, err);
- return 0;
+ return DATA_NONE;
#else
errno = EOPNOTSUPP;
return -1;
@@ -102,44 +105,42 @@ 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;
+ const char *chain;
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;
- verdict = nft_str2verdict(verdict_str);
- if (verdict < 0)
+ if (nft_str2verdict(verdict_str, &verdict) != 0) {
+ err->node_name = "verdict";
+ err->error = NFT_PARSE_EBADTYPE;
+ errno = EINVAL;
return DATA_NONE;
+ }
reg->verdict = (uint32_t)verdict;
- return DATA_VERDICT;
-}
-
-static int nft_data_reg_chain_xml_parse(union nft_data_reg *reg,
- mxml_node_t *tree)
-{
- const char *chain;
-
chain = nft_mxml_str_parse(tree, "chain", MXML_DESCEND_FIRST,
- NFT_XML_MAND);
- if (chain == NULL)
- return DATA_NONE;
+ NFT_XML_OPT, err);
+ if (chain != NULL) {
+ if (reg->chain)
+ xfree(reg->chain);
- if (reg->chain)
- xfree(reg->chain);
+ reg->chain = strdup(chain);
+ }
- reg->chain = strdup(chain);
- return DATA_CHAIN;
+ return DATA_VERDICT;
}
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];
@@ -155,7 +156,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> */
@@ -164,7 +165,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;
}
@@ -172,7 +173,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;
@@ -180,26 +182,25 @@ int nft_data_reg_xml_parse(union nft_data_reg *reg, mxml_node_t *tree)
node = mxmlFindElement(tree, tree, "data_reg", "type", NULL,
MXML_DESCEND_FIRST);
- if (node == NULL) {
- errno = EINVAL;
- return DATA_NONE;
- }
+ if (node == NULL)
+ goto err;
type = mxmlElementGetAttr(node, "type");
- if (type == NULL) {
- errno = EINVAL;
- return DATA_NONE;
- }
+ if (type == NULL)
+ goto err;
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);
- else if (strcmp(type, "chain") == 0)
- return nft_data_reg_chain_xml_parse(reg, node);
+ return nft_data_reg_verdict_xml_parse(reg, node, err);
return DATA_NONE;
+err:
+ errno = EINVAL;
+ err->node_name = "data_reg";
+ err->error = NFT_PARSE_EMISSINGNODE;
+ return DATA_NONE;
#else
errno = EOPNOTSUPP;
return -1;
@@ -293,6 +294,67 @@ nft_data_reg_value_snprintf_default(char *buf, size_t size,
return offset;
}
+static int
+nft_data_reg_verdict_snprintf_def(char *buf, size_t size,
+ union nft_data_reg *reg, uint32_t flags)
+{
+ int len = size, offset = 0, ret = 0;
+
+ ret = snprintf(buf, size, "%s ", nft_verdict2str(reg->verdict));
+ SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
+
+ if (reg->chain != NULL) {
+ ret = snprintf(buf+offset, size, "-> %s ", reg->chain);
+ SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
+ }
+
+ return offset;
+}
+
+static int
+nft_data_reg_verdict_snprintf_xml(char *buf, size_t size,
+ union nft_data_reg *reg, uint32_t flags)
+{
+ int len = size, offset = 0, ret = 0;
+
+ ret = snprintf(buf, size, "<data_reg type=\"verdict\">"
+ "<verdict>%s</verdict>", nft_verdict2str(reg->verdict));
+ SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
+
+ if (reg->chain != NULL) {
+ ret = snprintf(buf+offset, size, "<chain>%s</chain>",
+ reg->chain);
+ SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
+ }
+
+ ret = snprintf(buf+offset, size, "</data_reg>");
+ SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
+
+ return offset;
+}
+
+static int
+nft_data_reg_verdict_snprintf_json(char *buf, size_t size,
+ union nft_data_reg *reg, uint32_t flags)
+{
+ int len = size, offset = 0, ret = 0;
+
+ ret = snprintf(buf, size, "\"data_reg\":{\"type\":\"verdict\","
+ "\"verdict\":\"%s\"", nft_verdict2str(reg->verdict));
+ SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
+
+ if (reg->chain != NULL) {
+ ret = snprintf(buf+offset, size, ",\"chain\":\"%s\"",
+ reg->chain);
+ SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
+ }
+
+ ret = snprintf(buf+offset, size, "}");
+ SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
+
+ return offset;
+}
+
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)
{
@@ -312,44 +374,24 @@ int nft_data_reg_snprintf(char *buf, size_t size, union nft_data_reg *reg,
break;
}
case DATA_VERDICT:
- switch(output_format) {
- case NFT_OUTPUT_DEFAULT:
- return snprintf(buf, size, "%d ", reg->verdict);
- case NFT_OUTPUT_XML:
- return snprintf(buf, size,
- "<data_reg type=\"verdict\">"
- "<verdict>%s</verdict>"
- "</data_reg>",
- nft_verdict2str(reg->verdict));
- case NFT_OUTPUT_JSON:
- return snprintf(buf, size,
- "\"data_reg\":{"
- "\"type\":\"verdict\","
- "\"verdict\":\"%s\""
- "}", nft_verdict2str(reg->verdict));
- default:
- break;
- }
case DATA_CHAIN:
switch(output_format) {
case NFT_OUTPUT_DEFAULT:
- return snprintf(buf, size, "%s ", reg->chain);
+ return nft_data_reg_verdict_snprintf_def(buf, size,
+ reg, flags);
case NFT_OUTPUT_XML:
- return snprintf(buf, size,
- "<data_reg type=\"chain\">"
- "<chain>%s</chain>"
- "</data_reg>", reg->chain);
+ return nft_data_reg_verdict_snprintf_xml(buf, size,
+ reg, flags);
case NFT_OUTPUT_JSON:
- return snprintf(buf, size,
- "\"data_reg\":{\"type\":\"chain\","
- "\"chain\":\"%s\""
- "}", reg->chain);
+ return nft_data_reg_verdict_snprintf_json(buf, size,
+ reg, flags);
default:
break;
}
default:
break;
}
+
return -1;
}
diff --git a/src/expr/data_reg.h b/src/expr/data_reg.h
index 8a6a235..5258051 100644
--- a/src/expr/data_reg.h
+++ b/src/expr/data_reg.h
@@ -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
diff --git a/src/expr/exthdr.c b/src/expr/exthdr.c
index 6841ac1..66a6cf5 100644
--- a/src/expr/exthdr.c
+++ b/src/expr/exthdr.c
@@ -21,8 +21,8 @@
#include <linux/netfilter/nf_tables.h>
-#include <libnftables/expr.h>
-#include <libnftables/rule.h>
+#include <libnftnl/expr.h>
+#include <libnftnl/rule.h>
#include "expr_ops.h"
@@ -32,9 +32,9 @@
struct nft_expr_exthdr {
enum nft_registers dreg;
+ uint32_t offset;
+ uint32_t len;
uint8_t type;
- unsigned int offset;
- unsigned int len;
};
static int
@@ -51,10 +51,10 @@ nft_rule_expr_exthdr_set(struct nft_rule_expr *e, uint16_t type,
exthdr->type = *((uint8_t *)data);
break;
case NFT_EXPR_EXTHDR_OFFSET:
- exthdr->offset = *((unsigned int *)data);
+ exthdr->offset = *((uint32_t *)data);
break;
case NFT_EXPR_EXTHDR_LEN:
- exthdr->len = *((unsigned int *)data);
+ exthdr->len = *((uint32_t *)data);
break;
default:
return -1;
@@ -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,23 +234,24 @@ 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);
const char *exthdr_type;
- int32_t reg;
int type;
+ uint32_t reg;
- reg = nft_mxml_reg_parse(tree, "dreg", MXML_DESCEND_FIRST);
- if (reg < 0)
+ if (nft_mxml_reg_parse(tree, "dreg", &reg, MXML_DESCEND_FIRST,
+ NFT_XML_MAND, err) != 0)
return -1;
exthdr->dreg = reg;
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);
diff --git a/src/expr/immediate.c b/src/expr/immediate.c
index a96d3de..b3c52b8 100644
--- a/src/expr/immediate.c
+++ b/src/expr/immediate.c
@@ -17,8 +17,8 @@
#include "internal.h"
#include <libmnl/libmnl.h>
#include <linux/netfilter/nf_tables.h>
-#include <libnftables/expr.h>
-#include <libnftables/rule.h>
+#include <libnftnl/expr.h>
+#include <libnftnl/rule.h>
#include "expr_ops.h"
#include "data_reg.h"
@@ -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,22 +218,23 @@ 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;
+ uint32_t reg;
- reg = nft_mxml_reg_parse(tree, "dreg", MXML_DESCEND_FIRST);
- if (reg < 0)
+ if (nft_mxml_reg_parse(tree, "dreg", &reg, MXML_DESCEND_FIRST,
+ NFT_XML_MAND, err) != 0)
return -1;
imm->dreg = reg;
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);
diff --git a/src/expr/limit.c b/src/expr/limit.c
index 4854a77..7d10340 100644
--- a/src/expr/limit.c
+++ b/src/expr/limit.c
@@ -19,8 +19,8 @@
#include "internal.h"
#include <libmnl/libmnl.h>
-#include <libnftables/expr.h>
-#include <libnftables/rule.h>
+#include <libnftnl/expr.h>
+#include <libnftnl/rule.h>
#include "expr_ops.h"
struct nft_expr_limit {
@@ -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);
diff --git a/src/expr/log.c b/src/expr/log.c
index 76657a9..5119c20 100644
--- a/src/expr/log.c
+++ b/src/expr/log.c
@@ -18,8 +18,8 @@
#include "internal.h"
#include <libmnl/libmnl.h>
-#include <libnftables/expr.h>
-#include <libnftables/rule.h>
+#include <libnftnl/expr.h>
+#include <libnftnl/rule.h>
#include "expr_ops.h"
struct nft_expr_log {
@@ -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);
diff --git a/src/expr/lookup.c b/src/expr/lookup.c
index 4e91cfb..5e0bf75 100644
--- a/src/expr/lookup.c
+++ b/src/expr/lookup.c
@@ -18,8 +18,8 @@
#include <errno.h>
#include <libmnl/libmnl.h>
#include <linux/netfilter/nf_tables.h>
-#include <libnftables/rule.h>
-#include <libnftables/expr.h>
+#include <libnftnl/rule.h>
+#include <libnftnl/expr.h>
#include "data_reg.h"
#include "expr_ops.h"
@@ -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,15 +174,16 @@ 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);
const char *set_name;
- int32_t reg;
+ uint32_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,19 +191,18 @@ 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);
- if (reg < 0)
+ if (nft_mxml_reg_parse(tree, "sreg", &reg, MXML_DESCEND,
+ NFT_XML_MAND, err) != 0)
return -1;
lookup->sreg = reg;
e->flags |= (1 << NFT_EXPR_LOOKUP_SREG);
- reg = nft_mxml_reg_parse(tree, "dreg", MXML_DESCEND);
- if (reg < 0)
- return -1;
-
- lookup->dreg = reg;
- e->flags |= (1 << NFT_EXPR_LOOKUP_DREG);
+ if (nft_mxml_reg_parse(tree, "dreg", &reg, MXML_DESCEND,
+ NFT_XML_OPT, err) == 0) {
+ lookup->dreg = reg;
+ e->flags |= (1 << NFT_EXPR_LOOKUP_DREG);
+ }
return 0;
#else
@@ -212,41 +213,59 @@ nft_rule_expr_lookup_xml_parse(struct nft_rule_expr *e, mxml_node_t *tree)
static int
nft_rule_expr_lookup_snprintf_json(char *buf, size_t size,
- struct nft_expr_lookup *l)
+ struct nft_rule_expr *e)
{
int len = size, offset = 0, ret;
+ struct nft_expr_lookup *l = nft_expr_data(e);
- ret = snprintf(buf, len, "\"set\":\"%s\",\"sreg\":%u,\"dreg\":%u",
- l->set_name, l->sreg, l->dreg);
+ ret = snprintf(buf, len, "\"set\":\"%s\",\"sreg\":%u",
+ l->set_name, l->sreg);
SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
+ if (e->flags & (1 << NFT_EXPR_LOOKUP_DREG)) {
+ ret = snprintf(buf+offset, len, ",\"dreg\":%u", l->dreg);
+ SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
+ }
+
return offset;
}
static int
nft_rule_expr_lookup_snprintf_xml(char *buf, size_t size,
- struct nft_expr_lookup *l)
+ struct nft_rule_expr *e)
{
int len = size, offset = 0, ret;
+ struct nft_expr_lookup *l = nft_expr_data(e);
- ret = snprintf(buf, len, "<set>%s</set><sreg>%u</sreg><dreg>%u</dreg>",
- l->set_name, l->sreg, l->dreg);
+ ret = snprintf(buf, len, "<set>%s</set><sreg>%u</sreg>",
+ l->set_name, l->sreg);
SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
+ if (e->flags & (1 << NFT_EXPR_LOOKUP_DREG)) {
+ ret = snprintf(buf+offset, len, "<dreg>%u</dreg>", l->dreg);
+ SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
+ }
+
return offset;
}
static int
nft_rule_expr_lookup_snprintf_default(char *buf, size_t size,
- struct nft_expr_lookup *l)
+ struct nft_rule_expr *e)
{
int len = size, offset = 0, ret;
+ struct nft_expr_lookup *l = nft_expr_data(e);
- ret = snprintf(buf, len, "reg %u set %s dreg %u ",
- l->sreg, l->set_name, l->dreg);
+ ret = snprintf(buf, len, "reg %u set %s ", l->sreg, l->set_name);
SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
+
+ if (e->flags & (1 << NFT_EXPR_LOOKUP_DREG)) {
+ ret = snprintf(buf+offset, len, "dreg %u ", l->dreg);
+ SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
+ }
+
return offset;
}
@@ -254,15 +273,14 @@ static int
nft_rule_expr_lookup_snprintf(char *buf, size_t size, uint32_t type,
uint32_t flags, struct nft_rule_expr *e)
{
- struct nft_expr_lookup *lookup = nft_expr_data(e);
switch(type) {
case NFT_OUTPUT_DEFAULT:
- return nft_rule_expr_lookup_snprintf_default(buf, size, lookup);
+ return nft_rule_expr_lookup_snprintf_default(buf, size, e);
case NFT_OUTPUT_XML:
- return nft_rule_expr_lookup_snprintf_xml(buf, size, lookup);
+ return nft_rule_expr_lookup_snprintf_xml(buf, size, e);
case NFT_OUTPUT_JSON:
- return nft_rule_expr_lookup_snprintf_json(buf, size, lookup);
+ return nft_rule_expr_lookup_snprintf_json(buf, size, e);
default:
break;
}
diff --git a/src/expr/match.c b/src/expr/match.c
index c7863b8..9f2fa03 100644
--- a/src/expr/match.c
+++ b/src/expr/match.c
@@ -22,8 +22,8 @@
#include <linux/netfilter/nf_tables_compat.h>
#include <linux/netfilter/x_tables.h>
-#include <libnftables/expr.h>
-#include <libnftables/rule.h>
+#include <libnftnl/expr.h>
+#include <libnftnl/rule.h>
#include "expr_ops.h"
@@ -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;
diff --git a/src/expr/meta.c b/src/expr/meta.c
index f96b081..bee2f4c 100644
--- a/src/expr/meta.c
+++ b/src/expr/meta.c
@@ -18,8 +18,8 @@
#include "internal.h"
#include <libmnl/libmnl.h>
-#include <libnftables/expr.h>
-#include <libnftables/rule.h>
+#include <libnftnl/expr.h>
+#include <libnftnl/rule.h>
#include "expr_ops.h"
#ifndef NFT_META_MAX
@@ -27,9 +27,9 @@
#endif
struct nft_expr_meta {
- uint32_t key; /* enum nft_meta_keys */
- uint32_t dreg; /* enum nft_registers */
- uint32_t sreg; /* enum nft_registers */
+ enum nft_meta_keys key;
+ enum nft_registers dreg;
+ enum nft_registers sreg;
};
static int
@@ -135,7 +135,7 @@ nft_rule_expr_meta_parse(struct nft_rule_expr *e, struct nlattr *attr)
return 0;
}
-const char *meta_key2str_array[NFT_META_MAX] = {
+static const char *meta_key2str_array[NFT_META_MAX] = {
[NFT_META_LEN] = "len",
[NFT_META_PROTOCOL] = "protocol",
[NFT_META_NFPROTO] = "nfproto",
@@ -176,14 +176,15 @@ 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, sreg;
+ uint32_t reg;
int key;
- key_str = nft_jansson_parse_str(root, "key");
+ key_str = nft_jansson_parse_str(root, "key", err);
if (key_str == NULL)
return -1;
@@ -194,18 +195,19 @@ static int nft_rule_expr_meta_json_parse(struct nft_rule_expr *e, json_t *root)
nft_rule_expr_set_u32(e, NFT_EXPR_META_KEY, key);
if (nft_jansson_node_exist(root, "dreg")) {
- 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);
}
if (nft_jansson_node_exist(root, "sreg")) {
- if (nft_jansson_parse_reg(root, "sreg",
- NFT_TYPE_U32, &sreg) < 0)
+ if (nft_jansson_parse_reg(root, "sreg", NFT_TYPE_U32, &reg,
+ err) < 0)
return -1;
- nft_rule_expr_set_u32(e, NFT_EXPR_META_SREG, sreg);
+ nft_rule_expr_set_u32(e, NFT_EXPR_META_SREG, reg);
}
return 0;
@@ -216,16 +218,17 @@ 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);
const char *key_str;
- int32_t reg;
int key;
+ uint32_t reg;
key_str = nft_mxml_str_parse(tree, "key", MXML_DESCEND_FIRST,
- NFT_XML_MAND);
+ NFT_XML_MAND, err);
if (key_str == NULL)
return -1;
@@ -236,14 +239,14 @@ static int nft_rule_expr_meta_xml_parse(struct nft_rule_expr *e, mxml_node_t *tr
meta->key = key;
e->flags |= (1 << NFT_EXPR_META_KEY);
- reg = nft_mxml_reg_parse(tree, "dreg", MXML_DESCEND_FIRST);
- if (reg >= 0) {
+ if (nft_mxml_reg_parse(tree, "dreg", &reg, MXML_DESCEND_FIRST,
+ NFT_XML_OPT, err) >= 0) {
meta->dreg = reg;
e->flags |= (1 << NFT_EXPR_META_DREG);
}
- reg = nft_mxml_reg_parse(tree, "sreg", MXML_DESCEND_FIRST);
- if (reg >= 0) {
+ if (nft_mxml_reg_parse(tree, "sreg", &reg, MXML_DESCEND_FIRST,
+ NFT_XML_OPT, err) >= 0) {
meta->sreg = reg;
e->flags |= (1 << NFT_EXPR_META_SREG);
}
@@ -261,12 +264,15 @@ nft_rule_expr_meta_snprintf_default(char *buf, size_t len,
{
struct nft_expr_meta *meta = nft_expr_data(e);
- if (e->flags & (1 << NFT_EXPR_META_SREG))
+ if (e->flags & (1 << NFT_EXPR_META_SREG)) {
return snprintf(buf, len, "set %s with reg %u ",
meta_key2str(meta->key), meta->sreg);
-
- return snprintf(buf, len, "load %s => reg %u ",
- meta_key2str(meta->key), meta->dreg);
+ }
+ if (e->flags & (1 << NFT_EXPR_META_DREG)) {
+ return snprintf(buf, len, "load %s => reg %u ",
+ meta_key2str(meta->key), meta->dreg);
+ }
+ return 0;
}
static int
@@ -276,6 +282,12 @@ nft_rule_expr_meta_snprintf_xml(char *buf, size_t size,
int ret, len = size, offset = 0;
struct nft_expr_meta *meta = nft_expr_data(e);
+ if (e->flags & (1 << NFT_EXPR_META_DREG)) {
+ ret = snprintf(buf+offset, len, "<dreg>%u</dreg>",
+ meta->dreg);
+ SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
+ }
+
if (e->flags & (1 << NFT_EXPR_META_KEY)) {
ret = snprintf(buf+offset, len, "<key>%s</key>",
meta_key2str(meta->key));
@@ -288,12 +300,6 @@ nft_rule_expr_meta_snprintf_xml(char *buf, size_t size,
SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
}
- if (e->flags & (1 << NFT_EXPR_META_DREG)) {
- ret = snprintf(buf+offset, len, "<dreg>%u</dreg>",
- meta->dreg);
- SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
- }
-
return offset;
}
@@ -304,6 +310,12 @@ nft_rule_expr_meta_snprintf_json(char *buf, size_t size,
int ret, len = size, offset = 0;
struct nft_expr_meta *meta = nft_expr_data(e);
+ if (e->flags & (1 << NFT_EXPR_META_DREG)) {
+ ret = snprintf(buf+offset, len, "\"dreg\":%u,",
+ meta->dreg);
+ SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
+ }
+
if (e->flags & (1 << NFT_EXPR_META_KEY)) {
ret = snprintf(buf+offset, len, "\"key\":\"%s\",",
meta_key2str(meta->key));
@@ -311,17 +323,11 @@ nft_rule_expr_meta_snprintf_json(char *buf, size_t size,
}
if (e->flags & (1 << NFT_EXPR_META_SREG)) {
- ret = snprintf(buf+offset, len, "\"sreg\":%u\",",
+ ret = snprintf(buf+offset, len, "\"sreg\":%u,",
meta->sreg);
SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
}
- if (e->flags & (1 << NFT_EXPR_META_DREG)) {
- ret = snprintf(buf+offset, len, "\"dreg\":%u\",",
- meta->dreg);
- SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
- }
-
/* Remove the last separator characther */
buf[offset-1] = '\0';
diff --git a/src/expr/nat.c b/src/expr/nat.c
index 30b02ec..42f2b49 100644
--- a/src/expr/nat.c
+++ b/src/expr/nat.c
@@ -20,8 +20,8 @@
#include <arpa/inet.h>
#include <libmnl/libmnl.h>
#include <linux/netfilter/nf_tables.h>
-#include <libnftables/expr.h>
-#include <libnftables/rule.h>
+#include <libnftnl/expr.h>
+#include <libnftnl/rule.h>
#include "expr_ops.h"
struct nft_expr_nat {
@@ -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,16 +255,17 @@ 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);
const char *nat_type;
- int32_t reg;
int family, nat_type_value;
+ uint32_t reg;
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,29 +286,29 @@ 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);
- if (reg < 0)
+ if (nft_mxml_reg_parse(tree, "sreg_addr_min", &reg,
+ MXML_DESCEND, NFT_XML_MAND, err) != 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);
- if (reg < 0)
+ if (nft_mxml_reg_parse(tree, "sreg_addr_max", &reg,
+ MXML_DESCEND, NFT_XML_MAND, err) != 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);
- if (reg < 0)
+ if (nft_mxml_reg_parse(tree, "sreg_proto_min", &reg,
+ MXML_DESCEND, NFT_XML_MAND, err) != 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);
- if (reg < 0)
+ if (nft_mxml_reg_parse(tree, "sreg_proto_max", &reg,
+ MXML_DESCEND, NFT_XML_MAND, err) != 0)
return -1;
nat->sreg_proto_max = reg;
diff --git a/src/expr/payload.c b/src/expr/payload.c
index fc32ff2..ad82015 100644
--- a/src/expr/payload.c
+++ b/src/expr/payload.c
@@ -21,16 +21,16 @@
#include <linux/netfilter/nf_tables.h>
-#include <libnftables/expr.h>
-#include <libnftables/rule.h>
+#include <libnftnl/expr.h>
+#include <libnftnl/rule.h>
#include "expr_ops.h"
struct nft_expr_payload {
enum nft_registers dreg;
enum nft_payload_bases base;
- unsigned int offset;
- unsigned int len;
+ uint32_t offset;
+ uint32_t len;
};
static int
@@ -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,22 +236,24 @@ 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;
+ int32_t base;
+ uint32_t reg;
- reg = nft_mxml_reg_parse(tree, "dreg", MXML_DESCEND_FIRST);
- if (reg < 0)
+ if (nft_mxml_reg_parse(tree, "dreg", &reg, MXML_DESCEND_FIRST,
+ NFT_XML_MAND, err) != 0)
return -1;
payload->dreg = reg;
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 +266,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);
diff --git a/src/expr/queue.c b/src/expr/queue.c
index 4c1c8a7..c3d0e19 100644
--- a/src/expr/queue.c
+++ b/src/expr/queue.c
@@ -17,8 +17,8 @@
#include "internal.h"
#include <libmnl/libmnl.h>
-#include <libnftables/expr.h>
-#include <libnftables/rule.h>
+#include <libnftnl/expr.h>
+#include <libnftnl/rule.h>
#include "expr_ops.h"
struct nft_expr_queue {
diff --git a/src/expr/reject.c b/src/expr/reject.c
index 848f004..62346e9 100644
--- a/src/expr/reject.c
+++ b/src/expr/reject.c
@@ -18,8 +18,8 @@
#include "internal.h"
#include <libmnl/libmnl.h>
-#include <libnftables/expr.h>
-#include <libnftables/rule.h>
+#include <libnftnl/expr.h>
+#include <libnftnl/rule.h>
#include "expr_ops.h"
struct nft_expr_reject {
@@ -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);
diff --git a/src/expr/target.c b/src/expr/target.c
index 23dff3a..36e37de 100644
--- a/src/expr/target.c
+++ b/src/expr/target.c
@@ -22,8 +22,8 @@
#include <linux/netfilter/nf_tables_compat.h>
#include <linux/netfilter/x_tables.h>
-#include <libnftables/expr.h>
-#include <libnftables/rule.h>
+#include <libnftnl/expr.h>
+#include <libnftnl/rule.h>
#include "expr_ops.h"
@@ -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;
diff --git a/src/expr_ops.h b/src/expr_ops.h
index 26e0b82..b06f575 100644
--- a/src/expr_ops.h
+++ b/src/expr_ops.h
@@ -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);
diff --git a/src/internal.h b/src/internal.h
index a10d874..a3fc46f 100644
--- a/src/internal.h
+++ b/src/internal.h
@@ -13,6 +13,7 @@
#include <stdint.h>
#include <stdbool.h>
+#include <libnftnl/common.h>
#define BASE_DEC 10
#define BASE_HEX 16
@@ -30,64 +31,107 @@ enum nft_type {
NFT_TYPE_S64,
};
+struct nft_parse_err {
+ int line;
+ int column;
+ int error;
+ const char *node_name;
+};
+
+enum nft_parse_input {
+ NFT_PARSE_BUFFER,
+ NFT_PARSE_FILE,
+};
+
#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 void *data, const char *treename,
+ struct nft_parse_err *err, enum nft_parse_input input);
+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 *reg,
+ uint32_t mxmlflags, 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 *tag, int type, void *out);
-const char *nft_jansson_parse_str(json_t *root, const char *tag);
-bool nft_jansson_node_exist(json_t *root, const char *tag);
-json_t *nft_jansson_create_root(const char *json, json_error_t *err);
-json_t *nft_jansson_get_node(json_t *root, const char *tag);
+
+int nft_jansson_parse_val(json_t *root, const char *node_name, int type,
+ 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 void *json, json_error_t *error,
+ struct nft_parse_err *err, enum nft_parse_input input);
+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 *tag, int base, void *out,
- enum nft_type type);
-int nft_jansson_parse_reg(json_t *root, const char *tag, int type, void *out);
-struct nft_rule_expr *nft_jansson_expr_parse(json_t *root);
+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_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 *tag,
- union nft_data_reg *data_reg);
+int nft_jansson_data_reg_parse(json_t *root, const char *node_name,
+ 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_jansson_set_elem_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);
int nft_str2family(const char *family);
int nft_strtoi(const char *string, int base, void *number, enum nft_type type);
const char *nft_verdict2str(uint32_t verdict);
-int nft_str2verdict(const char *verdict);
+int nft_str2verdict(const char *verdict, int *verdict_num);
int nft_get_value(enum nft_type type, void *val, void *out);
#include <stdio.h>
diff --git a/src/jansson.c b/src/jansson.c
index 04146e2..5107eb5 100644
--- a/src/jansson.c
+++ b/src/jansson.c
@@ -16,25 +16,29 @@
#include <errno.h>
#include <string.h>
#include "expr_ops.h"
-#include <libnftables/set.h>
+#include <libnftnl/set.h>
-#include <libnftables/expr.h>
+#include <libnftnl/expr.h>
#include <linux/netfilter/nf_tables.h>
#ifdef JSON_PARSING
-static int nft_jansson_load_int_node(json_t *root, const char *tag,
- json_int_t *val)
+static int nft_jansson_load_int_node(json_t *root, const char *node_name,
+ json_int_t *val, struct nft_parse_err *err)
{
json_t *node;
- node = json_object_get(root, tag);
+ 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,26 +47,35 @@ static int nft_jansson_load_int_node(json_t *root, const char *tag,
return 0;
}
-const char *nft_jansson_parse_str(json_t *root, const char *tag)
+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, tag);
+ 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 *tag, int type, void *out)
+int nft_jansson_parse_val(json_t *root, const char *node_name, int type,
+ void *out, struct nft_parse_err *err)
{
json_int_t val;
- if (nft_jansson_load_int_node(root, tag, &val) == -1)
+ if (nft_jansson_load_int_node(root, node_name, &val, err) == -1)
return -1;
if (nft_get_value(type, &val, out) == -1)
@@ -71,30 +84,50 @@ int nft_jansson_parse_val(json_t *root, const char *tag, int type, void *out)
return 0;
}
-bool nft_jansson_node_exist(json_t *root, const char *tag)
+bool nft_jansson_node_exist(json_t *root, const char *node_name)
{
- return json_object_get(root, tag) != NULL;
+ 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 void *json, json_error_t *error,
+ struct nft_parse_err *err, enum nft_parse_input input)
{
json_t *root;
- root = json_loadb(json, strlen(json), 0, err);
+ switch (input) {
+ case NFT_PARSE_BUFFER:
+ root = json_loadb(json, strlen(json), 0, error);
+ break;
+ case NFT_PARSE_FILE:
+ root = json_loadf((FILE *)json, 0, error);
+ break;
+ default:
+ goto err;
+ }
+
if (root == NULL) {
- errno = EINVAL;
- return NULL;
+ err->error = NFT_PARSE_EBADINPUT;
+ err->line = error->line;
+ err->column = error->column;
+ err->node_name = error->source;
+ goto err;
}
return root;
+err:
+ errno = EINVAL;
+ return NULL;
}
-json_t *nft_jansson_get_node(json_t *root, const char *tag)
+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, tag);
+ node = json_object_get(root, node_name);
if (node == NULL) {
+ err->error = NFT_PARSE_EMISSINGNODE;
+ err->node_name = node_name;
errno = EINVAL;
return NULL;
}
@@ -107,17 +140,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;
}
@@ -126,9 +160,10 @@ int nft_jansson_parse_family(json_t *root, void *out)
return 0;
}
-int nft_jansson_parse_reg(json_t *root, const char *tag, int type, void *out)
+int nft_jansson_parse_reg(json_t *root, const char *node_name, int type,
+ void *out, struct nft_parse_err *err)
{
- if (nft_jansson_parse_val(root, tag, type, out) < 0)
+ if (nft_jansson_parse_val(root, node_name, type, out, err) < 0)
return -1;
if (*((uint32_t *)out) > NFT_REG_MAX){
@@ -139,107 +174,102 @@ int nft_jansson_parse_reg(json_t *root, const char *tag, int type, void *out)
return 0;
}
-int nft_jansson_str2num(json_t *root, const char *tag, int base,
- void *out, enum nft_type type)
+int nft_jansson_str2num(json_t *root, const char *node_name, int base,
+ void *out, enum nft_type type, struct nft_parse_err *err)
{
const char *str;
- str = nft_jansson_parse_str(root, tag);
+ 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 *tag,
- union nft_data_reg *data_reg)
+int nft_jansson_data_reg_parse(json_t *root, const char *node_name,
+ union nft_data_reg *data_reg,
+ struct nft_parse_err *err)
{
json_t *data;
- const char *type;
int ret;
- data = json_object_get(root, tag);
+ 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);
-
- if (ret < 0) {
+ ret = nft_data_reg_json_parse(data_reg, data, err);
+ if (ret == DATA_NONE) {
errno = EINVAL;
return -1;
}
- type = nft_jansson_parse_str(data, "type");
- if (type == NULL)
- return -1;
-
- if (strcmp(type, "value") == 0)
- return DATA_VALUE;
- else if (strcmp(type, "verdict") == 0)
- return DATA_VERDICT;
- else if (strcmp(type, "chain") == 0)
- return DATA_CHAIN;
- else {
- errno = EINVAL;
- return -1;
- }
+ return ret;
}
-int nft_set_elem_json_parse(struct nft_set_elem *e, json_t *root)
+int nft_jansson_set_elem_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);
break;
case DATA_VERDICT:
e->flags |= (1 << NFT_SET_ELEM_ATTR_VERDICT);
+ if (e->data.chain != NULL)
+ e->flags |= (1 << NFT_SET_ELEM_ATTR_CHAIN);
+
break;
- case DATA_CHAIN:
- e->flags |= (1 << NFT_SET_ELEM_ATTR_CHAIN);
- break;
+ case DATA_NONE:
default:
return -1;
}
diff --git a/src/libnftables.map b/src/libnftnl.map
index 7dc9aee..43378ed 100644
--- a/src/libnftables.map
+++ b/src/libnftnl.map
@@ -1,4 +1,4 @@
-LIBNFTABLES_1.0 {
+LIBNFTNL_1.0 {
global:
nft_table_alloc;
nft_table_free;
@@ -13,6 +13,7 @@ global:
nft_table_attr_get_u32;
nft_table_attr_get_str;
nft_table_parse;
+ nft_table_parse_file;
nft_table_snprintf;
nft_table_fprintf;
nft_table_nlmsg_build_payload;
@@ -45,6 +46,7 @@ global:
nft_chain_attr_get_u64;
nft_chain_attr_get_str;
nft_chain_parse;
+ nft_chain_parse_file;
nft_chain_snprintf;
nft_chain_fprintf;
nft_chain_nlmsg_build_payload;
@@ -74,6 +76,7 @@ global:
nft_rule_attr_get_u64;
nft_rule_attr_get_str;
nft_rule_parse;
+ nft_rule_parse_file;
nft_rule_snprintf;
nft_rule_fprintf;
nft_rule_nlmsg_build_payload;
@@ -128,6 +131,7 @@ global:
nft_set_nlmsg_build_payload;
nft_set_nlmsg_parse;
nft_set_parse;
+ nft_set_parse_file;
nft_set_snprintf;
nft_set_fprintf;
@@ -159,6 +163,7 @@ global:
nft_set_elem_nlmsg_build_payload;
nft_set_elem_nlmsg_parse;
nft_set_elem_parse;
+ nft_set_elem_parse_file;
nft_set_elem_snprintf;
nft_set_elem_fprinf;
@@ -179,10 +184,15 @@ global:
nft_ruleset_attr_set;
nft_ruleset_attr_get;
nft_ruleset_parse;
+ nft_ruleset_parse_file;
nft_ruleset_snprintf;
nft_ruleset_fprintf;
nft_nlmsg_build_hdr;
+ nft_parse_err_alloc;
+ nft_parse_err_free;
+ nft_parse_perror;
+
local: *;
};
diff --git a/src/mxml.c b/src/mxml.c
index 82156b7..b2cb95e 100644
--- a/src/mxml.c
+++ b/src/mxml.c
@@ -15,31 +15,50 @@
#include <limits.h>
#include <linux/netfilter/nf_tables.h>
-#include <libnftables/table.h>
-#include <libnftables/chain.h>
-#include <libnftables/rule.h>
-#include <libnftables/expr.h>
-#include <libnftables/set.h>
+#include <libnftnl/table.h>
+#include <libnftnl/chain.h>
+#include <libnftnl/rule.h>
+#include <libnftnl/expr.h>
+#include <libnftnl/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 void *data, const char *treename,
+ struct nft_parse_err *err, enum nft_parse_input input)
{
mxml_node_t *tree;
- tree = mxmlLoadString(NULL, xml, MXML_OPAQUE_CALLBACK);
- if (tree == NULL)
+ switch (input) {
+ case NFT_PARSE_BUFFER:
+ tree = mxmlLoadString(NULL, data, MXML_OPAQUE_CALLBACK);
+ break;
+ case NFT_PARSE_FILE:
+ tree = mxmlLoadFile(NULL, (FILE *)data, MXML_OPAQUE_CALLBACK);
+ break;
+ default:
goto err;
+ }
+
+ if (tree == NULL) {
+ err->error = NFT_PARSE_EBADINPUT;
+ goto err;
+ }
if (strcmp(tree->value.opaque, treename) == 0)
return tree;
+ err->error = NFT_PARSE_EMISSINGNODE;
+ err->node_name = treename;
+
mxmlDelete(tree);
err:
+ err->line = 0;
+ err->column = 0;
errno = EINVAL;
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 +67,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 +87,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,94 +99,130 @@ 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 *reg,
+ uint32_t mxmlflags, uint32_t flags,
+ struct nft_parse_err *err)
{
mxml_node_t *node;
- uint64_t val;
- node = mxmlFindElement(tree, tree, reg_name, NULL, NULL, flags);
+ node = mxmlFindElement(tree, tree, reg_name, NULL, NULL, mxmlflags);
if (node == NULL) {
- errno = EINVAL;
- goto err;
+ if (!(flags & NFT_XML_OPT)) {
+ err->error = NFT_PARSE_EMISSINGNODE;
+ errno = EINVAL;
+ goto err;
+ }
+ return -1;
}
- if (nft_strtoi(node->child->value.opaque, BASE_DEC, &val,
- NFT_TYPE_U64) != 0)
+ if (nft_strtoi(node->child->value.opaque, BASE_DEC, reg,
+ NFT_TYPE_U32) != 0) {
+ err->error = NFT_PARSE_EBADTYPE;
goto err;
+ }
- if (val > NFT_REG_MAX) {
+ if (*reg > NFT_REG_MAX) {
errno = ERANGE;
goto err;
}
- return val;
+
+ return 0;
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;
}
diff --git a/src/rule.c b/src/rule.c
index 280350a..53d2ebf 100644
--- a/src/rule.c
+++ b/src/rule.c
@@ -24,8 +24,8 @@
#include <linux/netfilter/nfnetlink.h>
#include <linux/netfilter/nf_tables.h>
-#include <libnftables/rule.h>
-#include <libnftables/expr.h>
+#include <libnftnl/rule.h>
+#include <libnftnl/expr.h>
#include "linux_list.h"
#include "expr_ops.h"
@@ -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,19 @@ 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 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_rule(r, tree);
+ return nft_jansson_parse_rule(r, tree, err);
#else
errno = EOPNOTSUPP;
return -1;
@@ -539,7 +546,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 +555,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 +563,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 +574,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 +585,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 +608,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 +617,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 +628,17 @@ 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 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, "rule");
+ mxml_node_t *tree = nft_mxml_build_tree(xml, "rule", err, input);
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
@@ -637,28 +647,44 @@ static int nft_rule_xml_parse(struct nft_rule *r, const char *xml)
#endif
}
-int nft_rule_parse(struct nft_rule *r, enum nft_parse_type type,
- const char *data)
+static int nft_rule_do_parse(struct nft_rule *r, 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_rule_xml_parse(r, data);
+ ret = nft_rule_xml_parse(r, data, &perr, input);
break;
case NFT_PARSE_JSON:
- ret = nft_rule_json_parse(r, data);
+ ret = nft_rule_json_parse(r, data, &perr, input);
break;
default:
ret = -1;
errno = EOPNOTSUPP;
break;
}
+ if (err != NULL)
+ *err = perr;
return ret;
}
+int nft_rule_parse(struct nft_rule *r, enum nft_parse_type type,
+ const char *data, struct nft_parse_err *err)
+{
+ return nft_rule_do_parse(r, type, data, err, NFT_PARSE_BUFFER);
+}
EXPORT_SYMBOL(nft_rule_parse);
+int nft_rule_parse_file(struct nft_rule *r, enum nft_parse_type type,
+ FILE *fp, struct nft_parse_err *err)
+{
+ return nft_rule_do_parse(r, type, fp, err, NFT_PARSE_FILE);
+}
+EXPORT_SYMBOL(nft_rule_parse_file);
+
static int nft_rule_snprintf_json(char *buf, size_t size, struct nft_rule *r,
uint32_t type, uint32_t flags)
{
diff --git a/src/ruleset.c b/src/ruleset.c
index f591382..3cbec09 100644
--- a/src/ruleset.c
+++ b/src/ruleset.c
@@ -17,11 +17,11 @@
#include <stdlib.h>
#include <libmnl/libmnl.h>
-#include <libnftables/ruleset.h>
-#include <libnftables/table.h>
-#include <libnftables/chain.h>
-#include <libnftables/set.h>
-#include <libnftables/rule.h>
+#include <libnftnl/ruleset.h>
+#include <libnftnl/table.h>
+#include <libnftnl/chain.h>
+#include <libnftnl/set.h>
+#include <libnftnl/rule.h>
struct nft_ruleset {
struct nft_table_list *table_list;
@@ -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 void *json,
+ struct nft_parse_err *err, enum nft_parse_input input)
{
#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, input);
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 void *xml,
+ struct nft_parse_err *err, enum nft_parse_input input)
{
#ifdef XML_PARSING
mxml_node_t *tree;
- tree = nft_mxml_build_tree(xml, "nftables");
+ tree = nft_mxml_build_tree(xml, "nftables", err, input);
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);
@@ -557,17 +567,19 @@ err:
#endif
}
-int nft_ruleset_parse(struct nft_ruleset *r, enum nft_parse_type type,
- const char *data)
+static int
+nft_ruleset_do_parse(struct nft_ruleset *r, enum nft_parse_type type,
+ const void *data, struct nft_parse_err *err,
+ enum nft_parse_input input)
{
int ret;
switch (type) {
case NFT_PARSE_XML:
- ret = nft_ruleset_xml_parse(r, data);
+ ret = nft_ruleset_xml_parse(r, data, err, input);
break;
case NFT_PARSE_JSON:
- ret = nft_ruleset_json_parse(r, data);
+ ret = nft_ruleset_json_parse(r, data, err, input);
break;
default:
ret = -1;
@@ -577,8 +589,21 @@ int nft_ruleset_parse(struct nft_ruleset *r, enum nft_parse_type type,
return ret;
}
+
+int nft_ruleset_parse(struct nft_ruleset *r, enum nft_parse_type type,
+ const char *data, struct nft_parse_err *err)
+{
+ return nft_ruleset_do_parse(r, type, data, err, NFT_PARSE_BUFFER);
+}
EXPORT_SYMBOL(nft_ruleset_parse);
+int nft_ruleset_parse_file(struct nft_ruleset *rs, enum nft_parse_type type,
+ FILE *fp, struct nft_parse_err *err)
+{
+ return nft_ruleset_do_parse(rs, type, fp, err, NFT_PARSE_FILE);
+}
+EXPORT_SYMBOL(nft_ruleset_parse_file);
+
static const char *nft_ruleset_o_opentag(uint32_t type)
{
switch (type) {
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,
diff --git a/src/set_elem.c b/src/set_elem.c
index fce9c1d..79fc641 100644
--- a/src/set_elem.c
+++ b/src/set_elem.c
@@ -22,8 +22,8 @@
#include <linux/netfilter/nfnetlink.h>
#include <linux/netfilter/nf_tables.h>
-#include <libnftables/set.h>
-#include <libnftables/rule.h>
+#include <libnftnl/set.h>
+#include <libnftnl/rule.h>
#include "linux_list.h"
#include "expr/data_reg.h"
@@ -357,35 +357,36 @@ 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);
break;
case DATA_VERDICT:
e->flags |= (1 << NFT_SET_ELEM_ATTR_VERDICT);
- break;
- case DATA_CHAIN:
- e->flags |= (1 << NFT_SET_ELEM_ATTR_CHAIN);
+ if (e->data.chain != NULL)
+ e->flags |= (1 << NFT_SET_ELEM_ATTR_CHAIN);
+
break;
}
@@ -393,17 +394,19 @@ 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 void *xml,
+ struct nft_parse_err *err,
+ enum nft_parse_input input)
{
#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, input);
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
@@ -412,13 +415,38 @@ static int nft_set_elem_xml_parse(struct nft_set_elem *e, const char *xml)
#endif
}
-int nft_set_elem_parse(struct nft_set_elem *e,
- enum nft_parse_type type, const char *data) {
+static int nft_set_elem_json_parse(struct nft_set_elem *e, 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, err, input);
+ if (tree == NULL)
+ return -1;
+
+ return nft_jansson_set_elem_parse(e, tree, err);
+#else
+ errno = EOPNOTSUPP;
+ return -1;
+#endif
+}
+
+static int
+nft_set_elem_do_parse(struct nft_set_elem *e, enum nft_parse_type type,
+ const void *data, struct nft_parse_err *err,
+ enum nft_parse_input input)
+{
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, input);
+ break;
+ case NFT_PARSE_JSON:
+ ret = nft_set_elem_json_parse(e, data, err, input);
break;
default:
errno = EOPNOTSUPP;
@@ -428,8 +456,20 @@ int nft_set_elem_parse(struct nft_set_elem *e,
return ret;
}
+int nft_set_elem_parse(struct nft_set_elem *e, enum nft_parse_type type,
+ const char *data, struct nft_parse_err *err)
+{
+ return nft_set_elem_do_parse(e, type, data, err, NFT_PARSE_BUFFER);
+}
EXPORT_SYMBOL(nft_set_elem_parse);
+int nft_set_elem_parse_file(struct nft_set_elem *e, enum nft_parse_type type,
+ FILE *fp, struct nft_parse_err *err)
+{
+ return nft_set_elem_do_parse(e, type, fp, err, NFT_PARSE_FILE);
+}
+EXPORT_SYMBOL(nft_set_elem_parse_file);
+
static int nft_set_elem_snprintf_json(char *buf, size_t size,
struct nft_set_elem *e, uint32_t flags)
{
diff --git a/src/table.c b/src/table.c
index ba84264..c834a4e 100644
--- a/src/table.c
+++ b/src/table.c
@@ -23,7 +23,7 @@
#include <linux/netfilter/nfnetlink.h>
#include <linux/netfilter/nf_tables.h>
-#include <libnftables/table.h>
+#include <libnftnl/table.h>
struct nft_table {
struct list_head head;
@@ -230,13 +230,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;
@@ -247,7 +248,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;
@@ -256,7 +257,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);
@@ -265,15 +266,17 @@ 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 void *data,
+ struct nft_parse_err *err,
+ enum nft_parse_input input)
{
#ifdef XML_PARSING
int ret;
- mxml_node_t *tree = nft_mxml_build_tree(xml, "table");
+ mxml_node_t *tree = nft_mxml_build_tree(data, "table", err, input);
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
@@ -283,29 +286,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);
@@ -318,34 +322,38 @@ 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 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_table(t, tree);
+ return nft_jansson_parse_table(t, tree, err);
#else
errno = EOPNOTSUPP;
return -1;
#endif
}
-int nft_table_parse(struct nft_table *t, enum nft_parse_type type,
- const char *data)
+static int nft_table_do_parse(struct nft_table *t, 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_table_xml_parse(t, data);
+ ret = nft_table_xml_parse(t, data, &perr, input);
break;
case NFT_PARSE_JSON:
- ret = nft_table_json_parse(t, data);
+ ret = nft_table_json_parse(t, data, &perr, input);
break;
default:
ret = -1;
@@ -353,10 +361,26 @@ int nft_table_parse(struct nft_table *t, enum nft_parse_type type,
break;
}
+ if (err != NULL)
+ *err = perr;
+
return ret;
}
+
+int nft_table_parse(struct nft_table *t, enum nft_parse_type type,
+ const char *data, struct nft_parse_err *err)
+{
+ return nft_table_do_parse(t, type, data, err, NFT_PARSE_BUFFER);
+}
EXPORT_SYMBOL(nft_table_parse);
+int nft_table_parse_file(struct nft_table *t, enum nft_parse_type type,
+ FILE *fp, struct nft_parse_err *err)
+{
+ return nft_table_do_parse(t, type, fp, err, NFT_PARSE_FILE);
+}
+EXPORT_SYMBOL(nft_table_parse_file);
+
static int nft_table_snprintf_json(char *buf, size_t size, struct nft_table *t)
{
return snprintf(buf, size,
diff --git a/src/utils.c b/src/utils.c
index 6fd8e03..9691c4c 100644
--- a/src/utils.c
+++ b/src/utils.c
@@ -158,18 +158,24 @@ const char *nft_verdict2str(uint32_t verdict)
}
}
-int nft_str2verdict(const char *verdict)
+int nft_str2verdict(const char *verdict, int *verdict_num)
{
- if (strcmp(verdict, "accept") == 0)
- return NF_ACCEPT;
- else if (strcmp(verdict, "drop") == 0)
- return NF_DROP;
- else if (strcmp(verdict, "return") == 0)
- return NFT_RETURN;
- else if (strcmp(verdict, "jump") == 0)
- return NFT_JUMP;
- else if (strcmp(verdict, "goto") == 0)
- return NFT_GOTO;
+ if (strcmp(verdict, "accept") == 0) {
+ *verdict_num = NF_ACCEPT;
+ return 0;
+ } else if (strcmp(verdict, "drop") == 0) {
+ *verdict_num = NF_DROP;
+ return 0;
+ } else if (strcmp(verdict, "return") == 0) {
+ *verdict_num = NFT_RETURN;
+ return 0;
+ } else if (strcmp(verdict, "jump") == 0) {
+ *verdict_num = NFT_JUMP;
+ return 0;
+ } else if (strcmp(verdict, "goto") == 0) {
+ *verdict_num = NFT_GOTO;
+ return 0;
+ }
return -1;
}