summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPablo Neira Ayuso <pablo@netfilter.org>2014-02-03 14:04:42 +0100
committerPablo Neira Ayuso <pablo@netfilter.org>2014-02-03 18:43:13 +0100
commit29fd6a1df9f6c80d155a7a73b8514a68dc9cd22d (patch)
tree9dc15a3e19a6ff36ae9ee3d38c7b8190b73f0a72
parent16871a3615edcf358d688a8d079b1e7b20053fb1 (diff)
parent076fd1e66e7f1bc3b2bd91f3efb84080da26fb9c (diff)
Merge branch 'master' into next-3.14
This patch includes changes to adapt this branch to the library rename that happened in the master branch. Conflicts: src/Makefile.am src/expr/cmp.c src/expr/ct.c src/expr/data_reg.c src/expr/meta.c tests/jsonfiles/01-table.json tests/jsonfiles/02-table.json tests/jsonfiles/64-ruleset.json tests/xmlfiles/01-table.xml tests/xmlfiles/02-table.xml
-rw-r--r--.gitignore2
-rw-r--r--COPYING10
-rw-r--r--Makefile.am2
-rw-r--r--configure.ac28
-rw-r--r--doxygen.cfg.in2
-rw-r--r--examples/Makefile.am54
-rw-r--r--examples/nft-chain-add.c2
-rw-r--r--examples/nft-chain-del.c2
-rw-r--r--examples/nft-chain-get.c2
-rw-r--r--examples/nft-chain-json-add.c16
-rw-r--r--examples/nft-chain-xml-add.c16
-rw-r--r--examples/nft-events.c6
-rw-r--r--examples/nft-rule-add.c261
-rw-r--r--examples/nft-rule-del.c2
-rw-r--r--examples/nft-rule-get.c2
-rw-r--r--examples/nft-rule-insert.c4
-rw-r--r--examples/nft-rule-json-add.c14
-rw-r--r--examples/nft-rule-xml-add.c14
-rw-r--r--examples/nft-ruleset-get.c12
-rw-r--r--examples/nft-set-add.c4
-rw-r--r--examples/nft-set-del.c2
-rw-r--r--examples/nft-set-elem-add.c2
-rw-r--r--examples/nft-set-elem-del.c2
-rw-r--r--examples/nft-set-elem-get.c2
-rw-r--r--examples/nft-set-get.c2
-rw-r--r--examples/nft-set-json-add.c14
-rw-r--r--examples/nft-table-add.c2
-rw-r--r--examples/nft-table-del.c2
-rw-r--r--examples/nft-table-get.c2
-rw-r--r--examples/nft-table-json-add.c14
-rw-r--r--examples/nft-table-upd.c2
-rw-r--r--examples/nft-table-xml-add.c15
-rw-r--r--include/Makefile.am2
-rw-r--r--include/libnftables/common.h20
-rw-r--r--include/libnftnl/Makefile.am (renamed from include/libnftables/Makefile.am)0
-rw-r--r--include/libnftnl/chain.h (renamed from include/libnftables/chain.h)13
-rw-r--r--include/libnftnl/common.h33
-rw-r--r--include/libnftnl/expr.h (renamed from include/libnftables/expr.h)6
-rw-r--r--include/libnftnl/rule.h (renamed from include/libnftables/rule.h)13
-rw-r--r--include/libnftnl/ruleset.h (renamed from include/libnftables/ruleset.h)13
-rw-r--r--include/libnftnl/set.h (renamed from include/libnftables/set.h)18
-rw-r--r--include/libnftnl/table.h (renamed from include/libnftables/table.h)13
-rw-r--r--include/linux/kernel.h29
-rw-r--r--include/linux/netfilter/nf_tables.h89
-rw-r--r--include/linux/netfilter/nfnetlink.h5
-rw-r--r--include/linux/netfilter/x_tables.h185
-rw-r--r--libnftnl.pc.in (renamed from libnftables.pc.in)8
-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
-rw-r--r--tests/Makefile.am44
-rw-r--r--tests/jsonfiles/01-table.json2
-rw-r--r--tests/jsonfiles/02-table.json2
-rw-r--r--tests/jsonfiles/11-chain.json2
-rw-r--r--tests/jsonfiles/12-chain.json2
-rw-r--r--tests/jsonfiles/13-chain.json2
-rw-r--r--tests/jsonfiles/14-chain.json2
-rw-r--r--tests/jsonfiles/20-rule-bitwise.json2
-rw-r--r--tests/jsonfiles/21-rule-byteorder.json2
-rw-r--r--tests/jsonfiles/22-rule-cmp.json2
-rw-r--r--tests/jsonfiles/23-rule-counter.json2
-rw-r--r--tests/jsonfiles/24-rule-ct.json2
-rw-r--r--tests/jsonfiles/25-rule-exthdr.json2
-rw-r--r--tests/jsonfiles/26-rule-immediate.json2
-rw-r--r--tests/jsonfiles/27-rule-limit.json2
-rw-r--r--tests/jsonfiles/28-rule-log.json2
-rw-r--r--tests/jsonfiles/29-rule-match.json2
-rw-r--r--tests/jsonfiles/30-rule-lookup.json2
-rw-r--r--tests/jsonfiles/31-rule-meta.json2
-rw-r--r--tests/jsonfiles/32-rule-nat4.json2
-rw-r--r--tests/jsonfiles/33-rule-nat6.json2
-rw-r--r--tests/jsonfiles/34-rule-payload.json2
-rw-r--r--tests/jsonfiles/35-rule-target.json2
-rw-r--r--tests/jsonfiles/36-rule-real.json2
-rw-r--r--tests/jsonfiles/37-rule-real.json2
-rw-r--r--tests/jsonfiles/38-rule-real.json2
-rw-r--r--tests/jsonfiles/39-rule-real.json2
-rw-r--r--tests/jsonfiles/40-rule-real.json2
-rw-r--r--tests/jsonfiles/41-rule-real.json2
-rw-r--r--tests/jsonfiles/42-rule-real.json2
-rw-r--r--tests/jsonfiles/43-rule-real.json2
-rw-r--r--tests/jsonfiles/44-rule-real.json2
-rw-r--r--tests/jsonfiles/45-rule-real.json2
-rw-r--r--tests/jsonfiles/46-rule-real.json2
-rw-r--r--tests/jsonfiles/47-rule-real.json2
-rw-r--r--tests/jsonfiles/48-rule-real.json2
-rw-r--r--tests/jsonfiles/49-rule-real.json2
-rw-r--r--tests/jsonfiles/50-rule-real.json2
-rw-r--r--tests/jsonfiles/51-rule-real.json2
-rw-r--r--tests/jsonfiles/52-rule-real.json2
-rw-r--r--tests/jsonfiles/53-rule-real.json2
-rw-r--r--tests/jsonfiles/54-rule-real.json2
-rw-r--r--tests/jsonfiles/55-rule-real.json2
-rw-r--r--tests/jsonfiles/56-rule-real.json2
-rw-r--r--tests/jsonfiles/57-rule-real.json2
-rw-r--r--tests/jsonfiles/58-rule-real.json2
-rw-r--r--tests/jsonfiles/59-rule-real.json2
-rw-r--r--tests/jsonfiles/60-rule-real.json2
-rw-r--r--tests/jsonfiles/61-rule-real.json2
-rw-r--r--tests/jsonfiles/62-set.json2
-rw-r--r--tests/jsonfiles/63-set.json2
-rw-r--r--tests/jsonfiles/64-ruleset.json3
-rw-r--r--tests/jsonfiles/65-rule-meta-target.json2
-rw-r--r--tests/nft-chain-test.c2
-rw-r--r--tests/nft-expr_bitwise-test.c4
-rw-r--r--tests/nft-expr_byteorder-test.c4
-rw-r--r--tests/nft-expr_cmp-test.c4
-rw-r--r--tests/nft-expr_counter-test.c4
-rw-r--r--tests/nft-expr_ct-test.c4
-rw-r--r--tests/nft-expr_exthdr-test.c4
-rw-r--r--tests/nft-expr_immediate-test.c4
-rw-r--r--tests/nft-expr_limit-test.c4
-rw-r--r--tests/nft-expr_log-test.c4
-rw-r--r--tests/nft-expr_lookup-test.c4
-rw-r--r--tests/nft-expr_match-test.c4
-rw-r--r--tests/nft-expr_meta-test.c4
-rw-r--r--tests/nft-expr_nat-test.c4
-rw-r--r--tests/nft-expr_payload-test.c4
-rw-r--r--tests/nft-expr_queue-test.c4
-rw-r--r--tests/nft-expr_reject-test.c4
-rw-r--r--tests/nft-expr_target-test.c4
-rw-r--r--tests/nft-parsing-test.c288
-rw-r--r--tests/nft-rule-test.c2
-rw-r--r--tests/nft-set-test.c2
-rw-r--r--tests/nft-table-test.c2
-rw-r--r--tests/xmlfiles/01-table.xml2
-rw-r--r--tests/xmlfiles/02-table.xml2
-rw-r--r--tests/xmlfiles/10-chain.xml2
-rw-r--r--tests/xmlfiles/11-chain.xml2
-rw-r--r--tests/xmlfiles/12-chain.xml2
-rw-r--r--tests/xmlfiles/20-rule-bitwise.xml3
-rw-r--r--tests/xmlfiles/21-rule-byteorder.xml2
-rw-r--r--tests/xmlfiles/22-rule-cmp.xml3
-rw-r--r--tests/xmlfiles/23-rule-counter.xml3
-rw-r--r--tests/xmlfiles/24-rule-ct.xml3
-rw-r--r--tests/xmlfiles/25-rule-exthdr.xml2
-rw-r--r--tests/xmlfiles/26-rule-immediate.xml3
-rw-r--r--tests/xmlfiles/27-rule-limit.xml2
-rw-r--r--tests/xmlfiles/28-rule-log.xml3
-rw-r--r--tests/xmlfiles/29-rule-lookup.xml3
-rw-r--r--tests/xmlfiles/30-rule-match.xml2
-rw-r--r--tests/xmlfiles/31-rule-meta.xml3
-rw-r--r--tests/xmlfiles/32-rule-nat6.xml2
-rw-r--r--tests/xmlfiles/33-rule-nat4.xml2
-rw-r--r--tests/xmlfiles/34-rule-payload.xml3
-rw-r--r--tests/xmlfiles/35-rule-target.xml2
-rw-r--r--tests/xmlfiles/36-rule-real.xml3
-rw-r--r--tests/xmlfiles/37-rule-real.xml3
-rw-r--r--tests/xmlfiles/38-rule-real.xml3
-rw-r--r--tests/xmlfiles/39-rule-real.xml3
-rw-r--r--tests/xmlfiles/40-rule-real.xml3
-rw-r--r--tests/xmlfiles/41-rule-real.xml3
-rw-r--r--tests/xmlfiles/42-rule-real.xml3
-rw-r--r--tests/xmlfiles/43-rule-real.xml3
-rw-r--r--tests/xmlfiles/44-rule-real.xml3
-rw-r--r--tests/xmlfiles/45-rule-real.xml3
-rw-r--r--tests/xmlfiles/46-rule-real.xml3
-rw-r--r--tests/xmlfiles/47-rule-real.xml3
-rw-r--r--tests/xmlfiles/48-rule-real.xml3
-rw-r--r--tests/xmlfiles/49-rule-real.xml3
-rw-r--r--tests/xmlfiles/50-rule-real.xml3
-rw-r--r--tests/xmlfiles/51-rule-real.xml3
-rw-r--r--tests/xmlfiles/52-rule-real.xml3
-rw-r--r--tests/xmlfiles/53-rule-real.xml3
-rw-r--r--tests/xmlfiles/54-rule-real.xml3
-rw-r--r--tests/xmlfiles/55-rule-real.xml3
-rw-r--r--tests/xmlfiles/56-rule-real.xml3
-rw-r--r--tests/xmlfiles/57-rule-real.xml3
-rw-r--r--tests/xmlfiles/58-rule-real.xml3
-rw-r--r--tests/xmlfiles/59-rule-real.xml3
-rw-r--r--tests/xmlfiles/60-rule-real.xml3
-rw-r--r--tests/xmlfiles/61-rule-real.xml3
-rw-r--r--tests/xmlfiles/62-rule-real.xml3
-rw-r--r--tests/xmlfiles/63-rule-real.xml3
-rw-r--r--tests/xmlfiles/64-rule-real.xml3
-rw-r--r--tests/xmlfiles/65-rule-real.xml3
-rw-r--r--tests/xmlfiles/66-rule-real.xml3
-rw-r--r--tests/xmlfiles/67-rule-real.xml3
-rw-r--r--tests/xmlfiles/68-rule-real.xml3
-rw-r--r--tests/xmlfiles/69-rule-real.xml3
-rw-r--r--tests/xmlfiles/70-rule-real.xml3
-rw-r--r--tests/xmlfiles/71-rule-real.xml3
-rw-r--r--tests/xmlfiles/72-rule-real.xml3
-rw-r--r--tests/xmlfiles/73-set.xml3
-rw-r--r--tests/xmlfiles/74-set.xml3
-rw-r--r--tests/xmlfiles/76-rule-meta_target.xml2
217 files changed, 2193 insertions, 1474 deletions
diff --git a/.gitignore b/.gitignore
index d8a55bf..5fada45 100644
--- a/.gitignore
+++ b/.gitignore
@@ -15,7 +15,7 @@ configure
autom4te.cache
stamp-h1
aclocal.m4
-libnftables.pc
+libnftnl.pc
libtool
build-aux
doxygen.cfg
diff --git a/COPYING b/COPYING
index a43ea21..21b9363 100644
--- a/COPYING
+++ b/COPYING
@@ -2,7 +2,7 @@
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
- 675 Mass Ave, Cambridge, MA 02139, USA
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
@@ -278,8 +278,9 @@ PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
-
- Appendix: How to Apply These Terms to Your New Programs
+
+
+ How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
@@ -305,7 +306,8 @@ the "copyright" line and a pointer to where the full notice is found.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
Also add information on how to contact you by electronic and paper mail.
diff --git a/Makefile.am b/Makefile.am
index 83f176d..4163829 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -6,4 +6,4 @@ SUBDIRS = src include examples tests
DIST_SUBDIRS = src include examples tests
pkgconfigdir = $(libdir)/pkgconfig
-pkgconfig_DATA = libnftables.pc
+pkgconfig_DATA = libnftnl.pc
diff --git a/configure.ac b/configure.ac
index b023755..f95b268 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,6 +1,6 @@
dnl Process this file with autoconf to create configure.
-AC_INIT([libnftables], [1.0.0])
+AC_INIT([libnftnl], [1.0.0])
AC_CONFIG_AUX_DIR([build-aux])
AC_CANONICAL_HOST
AC_CONFIG_MACRO_DIR([m4])
@@ -16,18 +16,18 @@ m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
dnl Dependencies
PKG_CHECK_MODULES([LIBMNL], [libmnl >= 1.0.0])
AC_ARG_WITH([xml-parsing],
- AS_HELP_STRING([--with-xml-parsing], [XML parsing support]),
- [with_xml_parsing="yes"], [with_xml_parsing="no"])
+ AS_HELP_STRING([--with-xml-parsing], [XML parsing support]))
AC_ARG_WITH([json-parsing],
- AS_HELP_STRING([--with-json-parsing], [JSON parsing support]),
- [with_json_parsing="yes"], [with_json_parsing="no"])
-
-AS_IF([test "x$with_xml_parsing" = "xyes"], [
- PKG_CHECK_MODULES([LIBXML], [mxml >= 2.6])
-])
-AS_IF([test "x$with_json_parsing" = "xyes"], [
- PKG_CHECK_MODULES([LIBJSON], [jansson >= 2.3])
-])
+ AS_HELP_STRING([--with-json-parsing], [JSON parsing support]))
+
+AS_IF([test "x$with_xml_parsing" = "xyes"],
+ [PKG_CHECK_MODULES([LIBXML], [mxml >= 2.6])],
+ [with_xml_parsing="no"]
+)
+AS_IF([test "x$with_json_parsing" = "xyes"],
+ [PKG_CHECK_MODULES([LIBJSON], [jansson >= 2.3])],
+ [with_json_parsing="no"]
+)
AC_PROG_CC
AM_PROG_CC_C_O
AC_EXEEXT
@@ -52,10 +52,10 @@ regular_CFLAGS="-Wall -Waggregate-return -Wmissing-declarations \
-Wformat=2 -pipe"
AC_SUBST([regular_CPPFLAGS])
AC_SUBST([regular_CFLAGS])
-AC_CONFIG_FILES([Makefile src/Makefile include/Makefile include/libnftables/Makefile include/linux/Makefile include/linux/netfilter/Makefile examples/Makefile tests/Makefile libnftables.pc doxygen.cfg])
+AC_CONFIG_FILES([Makefile src/Makefile include/Makefile include/libnftnl/Makefile include/linux/Makefile include/linux/netfilter/Makefile examples/Makefile tests/Makefile libnftnl.pc doxygen.cfg])
AC_OUTPUT
echo "
-libnftables configuration:
+libnftnl configuration:
XML support: ${with_xml_parsing}
JSON support: ${with_json_parsing}"
diff --git a/doxygen.cfg.in b/doxygen.cfg.in
index 9582600..85e8d36 100644
--- a/doxygen.cfg.in
+++ b/doxygen.cfg.in
@@ -67,7 +67,7 @@ WARN_FORMAT = "$file:$line: $text"
WARN_LOGFILE =
INPUT = .
INPUT_ENCODING = UTF-8
-FILE_PATTERNS = *.c libnftables.h
+FILE_PATTERNS = *.c libnftnl.h
RECURSIVE = YES
EXCLUDE =
EXCLUDE_SYMLINKS = NO
diff --git a/examples/Makefile.am b/examples/Makefile.am
index b909684..b433b2d 100644
--- a/examples/Makefile.am
+++ b/examples/Makefile.am
@@ -29,82 +29,82 @@ check_PROGRAMS = nft-table-add \
nft-compat-get
nft_table_add_SOURCES = nft-table-add.c
-nft_table_add_LDADD = ../src/libnftables.la ${LIBMNL_LIBS}
+nft_table_add_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
nft_table_xml_add_SOURCES = nft-table-xml-add.c
-nft_table_xml_add_LDADD = ../src/libnftables.la ${LIBMNL_LIBS}
+nft_table_xml_add_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
nft_table_json_add_SOURCES = nft-table-json-add.c
-nft_table_json_add_LDADD = ../src/libnftables.la ${LIBMNL_LIBS}
+nft_table_json_add_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
nft_table_upd_SOURCES = nft-table-upd.c
-nft_table_upd_LDADD = ../src/libnftables.la ${LIBMNL_LIBS}
+nft_table_upd_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
nft_table_del_SOURCES = nft-table-del.c
-nft_table_del_LDADD = ../src/libnftables.la ${LIBMNL_LIBS}
+nft_table_del_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
nft_table_get_SOURCES = nft-table-get.c
-nft_table_get_LDADD = ../src/libnftables.la ${LIBMNL_LIBS}
+nft_table_get_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
nft_chain_add_SOURCES = nft-chain-add.c
-nft_chain_add_LDADD = ../src/libnftables.la ${LIBMNL_LIBS}
+nft_chain_add_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
nft_chain_xml_add_SOURCES = nft-chain-xml-add.c
-nft_chain_xml_add_LDADD = ../src/libnftables.la ${LIBMNL_LIBS}
+nft_chain_xml_add_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
nft_chain_json_add_SOURCES = nft-chain-json-add.c
-nft_chain_json_add_LDADD = ../src/libnftables.la ${LIBMNL_LIBS} ${LIBXML_LIBS} ${LIBJSON_LIBS}
+nft_chain_json_add_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS} ${LIBXML_LIBS} ${LIBJSON_LIBS}
nft_chain_del_SOURCES = nft-chain-del.c
-nft_chain_del_LDADD = ../src/libnftables.la ${LIBMNL_LIBS}
+nft_chain_del_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
nft_chain_get_SOURCES = nft-chain-get.c
-nft_chain_get_LDADD = ../src/libnftables.la ${LIBMNL_LIBS}
+nft_chain_get_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
nft_rule_add_SOURCES = nft-rule-add.c
-nft_rule_add_LDADD = ../src/libnftables.la ${LIBMNL_LIBS}
+nft_rule_add_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
nft_rule_insert_SOURCES = nft-rule-insert.c
-nft_rule_insert_LDADD = ../src/libnftables.la ${LIBMNL_LIBS} ${LIBXML_LIBS}
+nft_rule_insert_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS} ${LIBXML_LIBS}
nft_rule_xml_add_SOURCES = nft-rule-xml-add.c
-nft_rule_xml_add_LDADD = ../src/libnftables.la ${LIBMNL_LIBS}
+nft_rule_xml_add_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
nft_rule_json_add_SOURCES = nft-rule-json-add.c
-nft_rule_json_add_LDADD = ../src/libnftables.la ${LIBMNL_LIBS}
+nft_rule_json_add_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
nft_rule_del_SOURCES = nft-rule-del.c
-nft_rule_del_LDADD = ../src/libnftables.la ${LIBMNL_LIBS}
+nft_rule_del_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
nft_rule_get_SOURCES = nft-rule-get.c
-nft_rule_get_LDADD = ../src/libnftables.la ${LIBMNL_LIBS}
+nft_rule_get_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
nft_events_SOURCES = nft-events.c
-nft_events_LDADD = ../src/libnftables.la ${LIBMNL_LIBS}
+nft_events_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
nft_set_add_SOURCES = nft-set-add.c
-nft_set_add_LDADD = ../src/libnftables.la ${LIBMNL_LIBS}
+nft_set_add_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
nft_set_json_add_SOURCES = nft-set-json-add.c
-nft_set_json_add_LDADD = ../src/libnftables.la ${LIBMNL_LIBS}
+nft_set_json_add_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
nft_set_del_SOURCES = nft-set-del.c
-nft_set_del_LDADD = ../src/libnftables.la ${LIBMNL_LIBS}
+nft_set_del_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
nft_set_get_SOURCES = nft-set-get.c
-nft_set_get_LDADD = ../src/libnftables.la ${LIBMNL_LIBS}
+nft_set_get_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
nft_set_elem_add_SOURCES = nft-set-elem-add.c
-nft_set_elem_add_LDADD = ../src/libnftables.la ${LIBMNL_LIBS}
+nft_set_elem_add_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
nft_set_elem_del_SOURCES = nft-set-elem-del.c
-nft_set_elem_del_LDADD = ../src/libnftables.la ${LIBMNL_LIBS}
+nft_set_elem_del_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
nft_set_elem_get_SOURCES = nft-set-elem-get.c
-nft_set_elem_get_LDADD = ../src/libnftables.la ${LIBMNL_LIBS}
+nft_set_elem_get_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
nft_ruleset_get_SOURCES = nft-ruleset-get.c
-nft_ruleset_get_LDADD = ../src/libnftables.la ${LIBMNL_LIBS}
+nft_ruleset_get_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
nft_compat_get_SOURCES = nft-compat-get.c
-nft_compat_get_LDADD = ../src/libnftables.la ${LIBMNL_LIBS}
+nft_compat_get_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
diff --git a/examples/nft-chain-add.c b/examples/nft-chain-add.c
index 22f9f3b..3edff86 100644
--- a/examples/nft-chain-add.c
+++ b/examples/nft-chain-add.c
@@ -18,7 +18,7 @@
#include <linux/netfilter/nf_tables.h>
#include <libmnl/libmnl.h>
-#include <libnftables/chain.h>
+#include <libnftnl/chain.h>
int main(int argc, char *argv[])
{
diff --git a/examples/nft-chain-del.c b/examples/nft-chain-del.c
index 95a1a7f..c87ab92 100644
--- a/examples/nft-chain-del.c
+++ b/examples/nft-chain-del.c
@@ -18,7 +18,7 @@
#include <linux/netfilter/nf_tables.h>
#include <libmnl/libmnl.h>
-#include <libnftables/chain.h>
+#include <libnftnl/chain.h>
int main(int argc, char *argv[])
{
diff --git a/examples/nft-chain-get.c b/examples/nft-chain-get.c
index 7e162f6..76fa5d9 100644
--- a/examples/nft-chain-get.c
+++ b/examples/nft-chain-get.c
@@ -18,7 +18,7 @@
#include <linux/netfilter/nf_tables.h>
#include <libmnl/libmnl.h>
-#include <libnftables/chain.h>
+#include <libnftnl/chain.h>
static int table_cb(const struct nlmsghdr *nlh, void *data)
{
diff --git a/examples/nft-chain-json-add.c b/examples/nft-chain-json-add.c
index 50cb29f..4fd0551 100644
--- a/examples/nft-chain-json-add.c
+++ b/examples/nft-chain-json-add.c
@@ -25,8 +25,8 @@
#include <linux/netfilter/nf_tables.h>
#include <libmnl/libmnl.h>
-#include <libnftables/chain.h>
-#include <libnftables/rule.h>
+#include <libnftnl/chain.h>
+#include <libnftnl/rule.h>
int main(int argc, char *argv[])
{
@@ -39,6 +39,7 @@ int main(int argc, char *argv[])
uint16_t family;
char json[4096];
char reprint[4096];
+ struct nft_parse_err *err;
if (argc < 2) {
printf("Usage: %s <json-file>\n", argv[0]);
@@ -63,10 +64,16 @@ int main(int argc, char *argv[])
exit(EXIT_FAILURE);
}
+ err = nft_parse_err_alloc();
+ if (err == NULL) {
+ perror("error");
+ exit(EXIT_FAILURE);
+ }
+
close(fd);
- if (nft_chain_parse(c, NFT_PARSE_JSON, json) < 0) {
- printf("E: Unable to parse JSON file: %s\n", strerror(errno));
+ if (nft_chain_parse(c, NFT_PARSE_JSON, json, err) < 0) {
+ nft_parse_perror("Unable to parse JSON file", err);
exit(EXIT_FAILURE);
}
@@ -82,6 +89,7 @@ int main(int argc, char *argv[])
nft_chain_nlmsg_build_payload(nlh, c);
nft_chain_free(c);
+ nft_parse_err_free(err);
nl = mnl_socket_open(NETLINK_NETFILTER);
if (nl == NULL) {
diff --git a/examples/nft-chain-xml-add.c b/examples/nft-chain-xml-add.c
index 03a2950..5d26af6 100644
--- a/examples/nft-chain-xml-add.c
+++ b/examples/nft-chain-xml-add.c
@@ -23,8 +23,8 @@
#include <linux/netfilter/nf_tables.h>
#include <libmnl/libmnl.h>
-#include <libnftables/chain.h>
-#include <libnftables/rule.h>
+#include <libnftnl/chain.h>
+#include <libnftnl/rule.h>
int main(int argc, char *argv[])
{
@@ -37,6 +37,7 @@ int main(int argc, char *argv[])
uint16_t family;
char xml[4096];
char reprint[4096];
+ struct nft_parse_err *err;
if (argc < 2) {
printf("Usage: %s <xml-file>\n", argv[0]);
@@ -49,6 +50,12 @@ int main(int argc, char *argv[])
exit(EXIT_FAILURE);
}
+ err = nft_parse_err_alloc();
+ if (err == NULL) {
+ perror("error");
+ exit(EXIT_FAILURE);
+ }
+
fd = open(argv[1], O_RDONLY);
if (fd < 0) {
perror("open");
@@ -63,8 +70,8 @@ int main(int argc, char *argv[])
close(fd);
- if (nft_chain_parse(c, NFT_PARSE_XML, xml) < 0) {
- printf("E: Unable to parse XML file: %s\n", strerror(errno));
+ if (nft_chain_parse(c, NFT_PARSE_XML, xml, err) < 0) {
+ nft_parse_perror("Unable to parse XML file", err);
exit(EXIT_FAILURE);
}
@@ -80,6 +87,7 @@ int main(int argc, char *argv[])
nft_chain_nlmsg_build_payload(nlh, c);
nft_chain_free(c);
+ nft_parse_err_free(err);
nl = mnl_socket_open(NETLINK_NETFILTER);
if (nl == NULL) {
diff --git a/examples/nft-events.c b/examples/nft-events.c
index 29cb659..150346a 100644
--- a/examples/nft-events.c
+++ b/examples/nft-events.c
@@ -18,9 +18,9 @@
#include <linux/netfilter/nf_tables.h>
#include <libmnl/libmnl.h>
-#include <libnftables/table.h>
-#include <libnftables/chain.h>
-#include <libnftables/rule.h>
+#include <libnftnl/table.h>
+#include <libnftnl/chain.h>
+#include <libnftnl/rule.h>
static int table_cb(const struct nlmsghdr *nlh, int type)
{
diff --git a/examples/nft-rule-add.c b/examples/nft-rule-add.c
index f896bc0..dbe93f5 100644
--- a/examples/nft-rule-add.c
+++ b/examples/nft-rule-add.c
@@ -14,126 +14,178 @@
#include <string.h>
#include <stddef.h> /* for offsetof */
#include <netinet/in.h>
+#include <netinet/ip.h>
+#include <netinet/tcp.h>
#include <arpa/inet.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <errno.h>
#include <linux/netfilter.h>
+#include <linux/netfilter/nfnetlink.h>
#include <linux/netfilter/nf_tables.h>
#include <libmnl/libmnl.h>
-#include <libnftables/rule.h>
-#include <libnftables/expr.h>
-
-#include <linux/netfilter_ipv4/ipt_LOG.h>
-#include <linux/netfilter/xt_iprange.h>
-
-#include <netinet/ip.h>
+#include <libnftnl/rule.h>
+#include <libnftnl/expr.h>
-static void add_target_log(struct nft_rule_expr *e)
+static void add_payload(struct nft_rule *r, uint32_t base, uint32_t dreg,
+ uint32_t offset, uint32_t len)
{
- struct ipt_log_info *info;
+ struct nft_rule_expr *e;
- nft_rule_expr_set(e, NFT_EXPR_TG_NAME, "LOG", strlen("LOG"));
- nft_rule_expr_set_u32(e, NFT_EXPR_TG_REV, 0);
-
- info = calloc(1, sizeof(struct ipt_log_info));
- if (info == NULL)
- return;
+ e = nft_rule_expr_alloc("payload");
+ if (e == NULL) {
+ perror("expr payload oom");
+ exit(EXIT_FAILURE);
+ }
- sprintf(info->prefix, "test: ");
- info->prefix[sizeof(info->prefix)-1] = '\0';
- info->logflags = 0x0f;
- info->level = 5;
+ nft_rule_expr_set_u32(e, NFT_EXPR_PAYLOAD_BASE, base);
+ nft_rule_expr_set_u32(e, NFT_EXPR_PAYLOAD_DREG, dreg);
+ nft_rule_expr_set_u32(e, NFT_EXPR_PAYLOAD_OFFSET, offset);
+ nft_rule_expr_set_u32(e, NFT_EXPR_PAYLOAD_LEN, len);
- nft_rule_expr_set(e, NFT_EXPR_TG_INFO, info, sizeof(*info));
+ nft_rule_add_expr(r, e);
}
-static void add_expr_target(struct nft_rule *r)
+static void add_cmp(struct nft_rule *r, uint32_t sreg, uint32_t op,
+ const void *data, uint32_t data_len)
{
- struct nft_rule_expr *expr;
+ struct nft_rule_expr *e;
- expr = nft_rule_expr_alloc("target");
- if (expr == NULL)
- return;
+ e = nft_rule_expr_alloc("cmp");
+ if (e == NULL) {
+ perror("expr cmp oom");
+ exit(EXIT_FAILURE);
+ }
- add_target_log(expr);
+ nft_rule_expr_set_u32(e, NFT_EXPR_CMP_SREG, sreg);
+ nft_rule_expr_set_u32(e, NFT_EXPR_CMP_OP, op);
+ nft_rule_expr_set(e, NFT_EXPR_CMP_DATA, data, data_len);
- nft_rule_add_expr(r, expr);
+ nft_rule_add_expr(r, e);
}
-static void add_match_iprange(struct nft_rule_expr *e)
+static void add_counter(struct nft_rule *r)
{
- struct xt_iprange_mtinfo *info;
-
- nft_rule_expr_set(e, NFT_EXPR_MT_NAME, "iprange", strlen("iprange"));
- nft_rule_expr_set_u32(e, NFT_EXPR_MT_REV, 1);
+ struct nft_rule_expr *e;
- info = calloc(1, sizeof(struct xt_iprange_mtinfo));
- if (info == NULL)
- return;
-
- info->src_min.ip = info->dst_min.ip = inet_addr("127.0.0.1");
- info->src_max.ip = info->dst_max.ip = inet_addr("127.0.0.1");
- info->flags = IPRANGE_SRC;
+ e = nft_rule_expr_alloc("counter");
+ if (e == NULL) {
+ perror("expr counter oom");
+ exit(EXIT_FAILURE);
+ }
- nft_rule_expr_set(e, NFT_EXPR_MT_INFO, info, sizeof(*info));
+ nft_rule_add_expr(r, e);
}
-static void add_expr_match(struct nft_rule *r)
+static struct nft_rule *setup_rule(uint8_t family, const char *table,
+ const char *chain)
{
- struct nft_rule_expr *expr;
+ struct nft_rule *r = NULL;
+ uint8_t proto;
+ uint16_t dport;
- expr = nft_rule_expr_alloc("match");
- if (expr == NULL)
- return;
+ r = nft_rule_alloc();
+ if (r == NULL) {
+ perror("OOM");
+ exit(EXIT_FAILURE);
+ }
- add_match_iprange(expr);
+ nft_rule_attr_set(r, NFT_RULE_ATTR_TABLE, table);
+ nft_rule_attr_set(r, NFT_RULE_ATTR_CHAIN, chain);
+ nft_rule_attr_set_u32(r, NFT_RULE_ATTR_FAMILY, family);
- nft_rule_add_expr(r, expr);
-}
+ proto = IPPROTO_TCP;
+ add_payload(r, NFT_PAYLOAD_NETWORK_HEADER, NFT_REG_1,
+ offsetof(struct iphdr, protocol), sizeof(uint8_t));
+ add_cmp(r, NFT_REG_1, NFT_CMP_EQ, &proto, sizeof(uint8_t));
-#define field_sizeof(t, f) (sizeof(((t *)NULL)->f))
+ dport = htons(22);
+ add_payload(r, NFT_PAYLOAD_TRANSPORT_HEADER, NFT_REG_1,
+ offsetof(struct tcphdr, dest), sizeof(uint16_t));
+ add_cmp(r, NFT_REG_1, NFT_CMP_EQ, &dport, sizeof(uint16_t));
-static void add_payload2(struct nft_rule_expr *e)
-{
- nft_rule_expr_set_u32(e, NFT_EXPR_PAYLOAD_BASE,
- NFT_PAYLOAD_NETWORK_HEADER);
- nft_rule_expr_set_u32(e, NFT_EXPR_PAYLOAD_DREG, NFT_REG_1);
- nft_rule_expr_set_u32(e, NFT_EXPR_PAYLOAD_OFFSET,
- offsetof(struct iphdr, protocol));
- nft_rule_expr_set_u32(e, NFT_EXPR_PAYLOAD_LEN, 1);
+ add_counter(r);
+
+ return r;
}
-static void add_payload(struct nft_rule *r)
+static int seq;
+
+static void nft_mnl_batch_put(struct mnl_nlmsg_batch *batch, int type)
{
- struct nft_rule_expr *expr;
+ struct nlmsghdr *nlh;
+ struct nfgenmsg *nfg;
- expr = nft_rule_expr_alloc("payload");
- if (expr == NULL)
- return;
+ nlh = mnl_nlmsg_put_header(mnl_nlmsg_batch_current(batch));
+ nlh->nlmsg_type = type;
+ nlh->nlmsg_flags = NLM_F_REQUEST;
+ nlh->nlmsg_seq = seq++;
- add_payload2(expr);
+ nfg = mnl_nlmsg_put_extra_header(nlh, sizeof(*nfg));
+ nfg->nfgen_family = AF_INET;
+ nfg->version = NFNETLINK_V0;
+ nfg->res_id = NFNL_SUBSYS_NFTABLES;
- nft_rule_add_expr(r, expr);
+ mnl_nlmsg_batch_next(batch);
+}
+
+static int nft_mnl_batch_talk(struct mnl_socket *nl, struct mnl_nlmsg_batch *b)
+{
+ int ret, fd = mnl_socket_get_fd(nl);
+ char rcv_buf[MNL_SOCKET_BUFFER_SIZE];
+ fd_set readfds;
+ struct timeval tv = {
+ .tv_sec = 0,
+ .tv_usec = 0
+ };
+
+ ret = mnl_socket_sendto(nl, mnl_nlmsg_batch_head(b),
+ mnl_nlmsg_batch_size(b));
+ if (ret == -1)
+ goto err;
+
+ FD_ZERO(&readfds);
+ FD_SET(fd, &readfds);
+
+ /* receive and digest all the acknowledgments from the kernel. */
+ ret = select(fd+1, &readfds, NULL, NULL, &tv);
+ if (ret == -1)
+ goto err;
+
+ while (ret > 0 && FD_ISSET(fd, &readfds)) {
+ ret = mnl_socket_recvfrom(nl, rcv_buf, sizeof(rcv_buf));
+ if (ret == -1)
+ goto err;
+
+ ret = mnl_cb_run(rcv_buf, ret, 0, mnl_socket_get_portid(nl),
+ NULL, NULL);
+ if (ret < 0)
+ goto err;
+
+ ret = select(fd+1, &readfds, NULL, NULL, &tv);
+ if (ret == -1)
+ goto err;
+
+ FD_ZERO(&readfds);
+ FD_SET(fd, &readfds);
+ }
+err:
+ return ret;
}
int main(int argc, char *argv[])
{
struct mnl_socket *nl;
- char buf[MNL_SOCKET_BUFFER_SIZE];
+ struct nft_rule *r;
struct nlmsghdr *nlh;
- uint32_t portid, seq;
- struct nft_rule *r = NULL;
- int ret, family;
+ struct mnl_nlmsg_batch *batch;
+ uint8_t family;
+ char buf[4096];
if (argc != 4) {
- fprintf(stderr, "Usage: %s <family> <table> <chain>\n",
- argv[0]);
- exit(EXIT_FAILURE);
- }
-
- r = nft_rule_alloc();
- if (r == NULL) {
- perror("OOM");
+ fprintf(stderr, "Usage: %s <family> <table> <chain>\n", argv[0]);
exit(EXIT_FAILURE);
}
@@ -141,32 +193,12 @@ int main(int argc, char *argv[])
family = NFPROTO_IPV4;
else if (strcmp(argv[1], "ip6") == 0)
family = NFPROTO_IPV6;
- else if (strcmp(argv[1], "bridge") == 0)
- family = NFPROTO_BRIDGE;
- else if (strcmp(argv[1], "arp") == 0)
- family = NFPROTO_ARP;
else {
- fprintf(stderr, "Unknown family: ip, ip6, bridge, arp\n");
+ fprintf(stderr, "Unknown family: ip, ip6\n");
exit(EXIT_FAILURE);
}
- nft_rule_attr_set(r, NFT_RULE_ATTR_TABLE, argv[2]);
- nft_rule_attr_set(r, NFT_RULE_ATTR_CHAIN, argv[3]);
-
- add_expr_match(r);
- add_payload(r);
- add_expr_target(r);
-
- char tmp[1024];
- nft_rule_snprintf(tmp, sizeof(tmp), r, 0, 0);
- printf("%s\n", tmp);
-
- seq = time(NULL);
- nlh = nft_rule_nlmsg_build_hdr(buf, NFT_MSG_NEWRULE, family,
- NLM_F_APPEND|NLM_F_ACK|NLM_F_CREATE,
- seq);
- nft_rule_nlmsg_build_payload(nlh, r);
- nft_rule_free(r);
+ r = setup_rule(family, argv[2], argv[3]);
nl = mnl_socket_open(NETLINK_NETFILTER);
if (nl == NULL) {
@@ -178,24 +210,29 @@ int main(int argc, char *argv[])
perror("mnl_socket_bind");
exit(EXIT_FAILURE);
}
- portid = mnl_socket_get_portid(nl);
- if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) {
- perror("mnl_socket_send");
- exit(EXIT_FAILURE);
- }
+ batch = mnl_nlmsg_batch_start(buf, sizeof(buf));
- ret = mnl_socket_recvfrom(nl, buf, sizeof(buf));
- while (ret > 0) {
- ret = mnl_cb_run(buf, ret, seq, portid, NULL, NULL);
- if (ret <= 0)
- break;
- ret = mnl_socket_recvfrom(nl, buf, sizeof(buf));
- }
- if (ret == -1) {
- perror("error");
+ nft_mnl_batch_put(batch, NFNL_MSG_BATCH_BEGIN);
+
+ nlh = nft_rule_nlmsg_build_hdr(mnl_nlmsg_batch_current(batch),
+ NFT_MSG_NEWRULE,
+ nft_rule_attr_get_u32(r, NFT_RULE_ATTR_FAMILY),
+ NLM_F_APPEND|NLM_F_CREATE, seq);
+
+ nft_rule_nlmsg_build_payload(nlh, r);
+ nft_rule_free(r);
+ mnl_nlmsg_batch_next(batch);
+
+ nft_mnl_batch_put(batch, NFNL_MSG_BATCH_END);
+
+ if (nft_mnl_batch_talk(nl, batch) < 0) {
+ perror("Netlink problem");
exit(EXIT_FAILURE);
}
+
+ mnl_nlmsg_batch_stop(batch);
+
mnl_socket_close(nl);
return EXIT_SUCCESS;
diff --git a/examples/nft-rule-del.c b/examples/nft-rule-del.c
index c2b1a70..6f665b0 100644
--- a/examples/nft-rule-del.c
+++ b/examples/nft-rule-del.c
@@ -19,7 +19,7 @@
#include <linux/netfilter/nf_tables.h>
#include <libmnl/libmnl.h>
-#include <libnftables/rule.h>
+#include <libnftnl/rule.h>
int main(int argc, char *argv[])
{
diff --git a/examples/nft-rule-get.c b/examples/nft-rule-get.c
index f17630b..5803143 100644
--- a/examples/nft-rule-get.c
+++ b/examples/nft-rule-get.c
@@ -18,7 +18,7 @@
#include <linux/netfilter/nf_tables.h>
#include <libmnl/libmnl.h>
-#include <libnftables/rule.h>
+#include <libnftnl/rule.h>
static int table_cb(const struct nlmsghdr *nlh, void *data)
{
diff --git a/examples/nft-rule-insert.c b/examples/nft-rule-insert.c
index 1418127..1b377de 100644
--- a/examples/nft-rule-insert.c
+++ b/examples/nft-rule-insert.c
@@ -20,8 +20,8 @@
#include <linux/netfilter/nf_tables.h>
#include <libmnl/libmnl.h>
-#include <libnftables/rule.h>
-#include <libnftables/expr.h>
+#include <libnftnl/rule.h>
+#include <libnftnl/expr.h>
#include <linux/netfilter_ipv4/ipt_LOG.h>
#include <linux/netfilter/xt_iprange.h>
diff --git a/examples/nft-rule-json-add.c b/examples/nft-rule-json-add.c
index 8659081..b33025b 100644
--- a/examples/nft-rule-json-add.c
+++ b/examples/nft-rule-json-add.c
@@ -25,7 +25,7 @@
#include <linux/netfilter/nf_tables.h>
#include <libmnl/libmnl.h>
-#include <libnftables/rule.h>
+#include <libnftnl/rule.h>
int main(int argc, char *argv[])
{
@@ -38,6 +38,7 @@ int main(int argc, char *argv[])
uint8_t family;
char json[4096];
char reprint[4096];
+ struct nft_parse_err *err;
if (argc < 2) {
printf("Usage: %s <json-file>\n", argv[0]);
@@ -63,8 +64,14 @@ int main(int argc, char *argv[])
exit(EXIT_FAILURE);
}
- if (nft_rule_parse(r, NFT_PARSE_JSON, json) < 0) {
- printf("E: Unable to parse JSON file: %s\n", strerror(errno));
+ err = nft_parse_err_alloc();
+ if (err == NULL) {
+ perror("error");
+ exit(EXIT_FAILURE);
+ }
+
+ if (nft_rule_parse(r, NFT_PARSE_JSON, json, err) < 0) {
+ nft_parse_perror("Unable to parse JSON file", err);
exit(EXIT_FAILURE);
}
@@ -80,6 +87,7 @@ int main(int argc, char *argv[])
seq);
nft_rule_nlmsg_build_payload(nlh, r);
nft_rule_free(r);
+ nft_parse_err_free(err);
nl = mnl_socket_open(NETLINK_NETFILTER);
if (nl == NULL) {
diff --git a/examples/nft-rule-xml-add.c b/examples/nft-rule-xml-add.c
index ce33fe7..dd16922 100644
--- a/examples/nft-rule-xml-add.c
+++ b/examples/nft-rule-xml-add.c
@@ -25,7 +25,7 @@
#include <linux/netfilter/nf_tables.h>
#include <libmnl/libmnl.h>
-#include <libnftables/rule.h>
+#include <libnftnl/rule.h>
int main(int argc, char *argv[])
{
@@ -38,6 +38,7 @@ int main(int argc, char *argv[])
uint8_t family;
char xml[4096];
char reprint[4096];
+ struct nft_parse_err *err;
if (argc < 2) {
printf("Usage: %s <xml-file>\n", argv[0]);
@@ -63,8 +64,14 @@ int main(int argc, char *argv[])
exit(EXIT_FAILURE);
}
- if (nft_rule_parse(r, NFT_PARSE_XML, xml) < 0) {
- printf("E: Unable to parse XML file: %s\n", strerror(errno));
+ err = nft_parse_err_alloc();
+ if (err == NULL) {
+ perror("error");
+ exit(EXIT_FAILURE);
+ }
+
+ if (nft_rule_parse(r, NFT_PARSE_XML, xml, err) < 0) {
+ nft_parse_perror("Unable to parse XML file", err);
exit(EXIT_FAILURE);
}
@@ -80,6 +87,7 @@ int main(int argc, char *argv[])
seq);
nft_rule_nlmsg_build_payload(nlh, r);
nft_rule_free(r);
+ nft_parse_err_free(err);
nl = mnl_socket_open(NETLINK_NETFILTER);
if (nl == NULL) {
diff --git a/examples/nft-ruleset-get.c b/examples/nft-ruleset-get.c
index 25c6d7c..18de2a9 100644
--- a/examples/nft-ruleset-get.c
+++ b/examples/nft-ruleset-get.c
@@ -21,12 +21,12 @@
#include <linux/netfilter/nf_tables.h>
#include <libmnl/libmnl.h>
-#include <libnftables/common.h>
-#include <libnftables/ruleset.h>
-#include <libnftables/table.h>
-#include <libnftables/chain.h>
-#include <libnftables/set.h>
-#include <libnftables/rule.h>
+#include <libnftnl/common.h>
+#include <libnftnl/ruleset.h>
+#include <libnftnl/table.h>
+#include <libnftnl/chain.h>
+#include <libnftnl/set.h>
+#include <libnftnl/rule.h>
static int seq;
diff --git a/examples/nft-set-add.c b/examples/nft-set-add.c
index 0d17c38..4e54c39 100644
--- a/examples/nft-set-add.c
+++ b/examples/nft-set-add.c
@@ -18,8 +18,8 @@
#include <linux/netfilter/nf_tables.h>
#include <libmnl/libmnl.h>
-#include <libnftables/table.h>
-#include <libnftables/set.h>
+#include <libnftnl/table.h>
+#include <libnftnl/set.h>
int main(int argc, char *argv[])
{
diff --git a/examples/nft-set-del.c b/examples/nft-set-del.c
index 7828ae0..5abd3b1 100644
--- a/examples/nft-set-del.c
+++ b/examples/nft-set-del.c
@@ -18,7 +18,7 @@
#include <linux/netfilter/nf_tables.h>
#include <libmnl/libmnl.h>
-#include <libnftables/set.h>
+#include <libnftnl/set.h>
int main(int argc, char *argv[])
{
diff --git a/examples/nft-set-elem-add.c b/examples/nft-set-elem-add.c
index e2e278d..ffc025c 100644
--- a/examples/nft-set-elem-add.c
+++ b/examples/nft-set-elem-add.c
@@ -18,7 +18,7 @@
#include <linux/netfilter/nf_tables.h>
#include <libmnl/libmnl.h>
-#include <libnftables/set.h>
+#include <libnftnl/set.h>
int main(int argc, char *argv[])
{
diff --git a/examples/nft-set-elem-del.c b/examples/nft-set-elem-del.c
index 36f1016..af70cde 100644
--- a/examples/nft-set-elem-del.c
+++ b/examples/nft-set-elem-del.c
@@ -18,7 +18,7 @@
#include <linux/netfilter/nf_tables.h>
#include <libmnl/libmnl.h>
-#include <libnftables/set.h>
+#include <libnftnl/set.h>
int main(int argc, char *argv[])
{
diff --git a/examples/nft-set-elem-get.c b/examples/nft-set-elem-get.c
index 0b46f36..6908c2a 100644
--- a/examples/nft-set-elem-get.c
+++ b/examples/nft-set-elem-get.c
@@ -18,7 +18,7 @@
#include <linux/netfilter/nf_tables.h>
#include <libmnl/libmnl.h>
-#include <libnftables/set.h>
+#include <libnftnl/set.h>
static int set_cb(const struct nlmsghdr *nlh, void *data)
{
diff --git a/examples/nft-set-get.c b/examples/nft-set-get.c
index b774199..2822025 100644
--- a/examples/nft-set-get.c
+++ b/examples/nft-set-get.c
@@ -18,7 +18,7 @@
#include <linux/netfilter/nf_tables.h>
#include <libmnl/libmnl.h>
-#include <libnftables/set.h>
+#include <libnftnl/set.h>
static int set_cb(const struct nlmsghdr *nlh, void *data)
{
diff --git a/examples/nft-set-json-add.c b/examples/nft-set-json-add.c
index 9a4aa48..a4535da 100644
--- a/examples/nft-set-json-add.c
+++ b/examples/nft-set-json-add.c
@@ -25,7 +25,7 @@
#include <linux/netfilter/nf_tables.h>
#include <libmnl/libmnl.h>
-#include <libnftables/set.h>
+#include <libnftnl/set.h>
int main(int argc, char *argv[])
{
@@ -38,6 +38,7 @@ int main(int argc, char *argv[])
uint16_t family;
char json[4096];
char reprint[4096];
+ struct nft_parse_err *err;
if (argc < 2) {
printf("Usage: %s <json-file>\n", argv[0]);
@@ -62,10 +63,16 @@ int main(int argc, char *argv[])
exit(EXIT_FAILURE);
}
+ err = nft_parse_err_alloc();
+ if (err == NULL) {
+ perror("error");
+ exit(EXIT_FAILURE);
+ }
+
close(fd);
- if (nft_set_parse(s, NFT_PARSE_JSON, json) < 0) {
- printf("E: Unable to parse JSON file: %s\n", strerror(errno));
+ if (nft_set_parse(s, NFT_PARSE_JSON, json, err) < 0) {
+ nft_parse_perror("Unable to parse JSON file", err);
exit(EXIT_FAILURE);
}
@@ -80,6 +87,7 @@ int main(int argc, char *argv[])
NLM_F_CREATE|NLM_F_ACK, seq);
nft_set_nlmsg_build_payload(nlh, s);
nft_set_free(s);
+ nft_parse_err_free(err);
nl = mnl_socket_open(NETLINK_NETFILTER);
if (nl == NULL) {
diff --git a/examples/nft-table-add.c b/examples/nft-table-add.c
index e4d7db9..3b7572f 100644
--- a/examples/nft-table-add.c
+++ b/examples/nft-table-add.c
@@ -18,7 +18,7 @@
#include <linux/netfilter/nf_tables.h>
#include <libmnl/libmnl.h>
-#include <libnftables/table.h>
+#include <libnftnl/table.h>
int main(int argc, char *argv[])
{
diff --git a/examples/nft-table-del.c b/examples/nft-table-del.c
index 11762fe..ed1140d 100644
--- a/examples/nft-table-del.c
+++ b/examples/nft-table-del.c
@@ -18,7 +18,7 @@
#include <linux/netfilter/nf_tables.h>
#include <libmnl/libmnl.h>
-#include <libnftables/table.h>
+#include <libnftnl/table.h>
int main(int argc, char *argv[])
{
diff --git a/examples/nft-table-get.c b/examples/nft-table-get.c
index c5bc89d..6ac56d6 100644
--- a/examples/nft-table-get.c
+++ b/examples/nft-table-get.c
@@ -18,7 +18,7 @@
#include <linux/netfilter/nf_tables.h>
#include <libmnl/libmnl.h>
-#include <libnftables/table.h>
+#include <libnftnl/table.h>
static int table_cb(const struct nlmsghdr *nlh, void *data)
{
diff --git a/examples/nft-table-json-add.c b/examples/nft-table-json-add.c
index 6b16c7f..a9bd217 100644
--- a/examples/nft-table-json-add.c
+++ b/examples/nft-table-json-add.c
@@ -26,7 +26,7 @@
#include <linux/netfilter/nf_tables.h>
#include <libmnl/libmnl.h>
-#include <libnftables/table.h>
+#include <libnftnl/table.h>
int main(int argc, char *argv[])
{
@@ -39,6 +39,7 @@ int main(int argc, char *argv[])
uint16_t family;
char json[4096];
char reprint[4096];
+ struct nft_parse_err *err;
if (argc < 2) {
printf("Usage: %s <json-file>\n", argv[0]);
@@ -64,8 +65,14 @@ int main(int argc, char *argv[])
exit(EXIT_FAILURE);
}
- if (nft_table_parse(t, NFT_PARSE_JSON, json) < 0) {
- printf("E: Unable to parse JSON file: %s\n", strerror(errno));
+ err = nft_parse_err_alloc();
+ if (err == NULL) {
+ perror("error");
+ exit(EXIT_FAILURE);
+ }
+
+ if (nft_table_parse(t, NFT_PARSE_JSON, json, err) < 0) {
+ nft_parse_perror("Unable to parse JSON file", err);
exit(EXIT_FAILURE);
}
@@ -80,6 +87,7 @@ int main(int argc, char *argv[])
NLM_F_CREATE|NLM_F_ACK, seq);
nft_table_nlmsg_build_payload(nlh, t);
nft_table_free(t);
+ nft_parse_err_free(err);
nl = mnl_socket_open(NETLINK_NETFILTER);
if (nl == NULL) {
diff --git a/examples/nft-table-upd.c b/examples/nft-table-upd.c
index 1cf41a4..9f0e809 100644
--- a/examples/nft-table-upd.c
+++ b/examples/nft-table-upd.c
@@ -18,7 +18,7 @@
#include <linux/netfilter/nf_tables.h>
#include <libmnl/libmnl.h>
-#include <libnftables/table.h>
+#include <libnftnl/table.h>
int main(int argc, char *argv[])
{
diff --git a/examples/nft-table-xml-add.c b/examples/nft-table-xml-add.c
index 6a9163b..f36f0ab 100644
--- a/examples/nft-table-xml-add.c
+++ b/examples/nft-table-xml-add.c
@@ -22,7 +22,8 @@
#include <linux/netfilter/nf_tables.h>
#include <libmnl/libmnl.h>
-#include <libnftables/table.h>
+#include <libnftnl/table.h>
+#include <libnftnl/common.h>
int main(int argc, char *argv[])
{
@@ -35,6 +36,7 @@ int main(int argc, char *argv[])
uint16_t family;
char xml[4096];
char reprint[4096];
+ struct nft_parse_err *err;
if (argc < 2) {
printf("Usage: %s <xml-file>\n", argv[0]);
@@ -60,8 +62,14 @@ int main(int argc, char *argv[])
exit(EXIT_FAILURE);
}
- if (nft_table_parse(t, NFT_PARSE_XML, xml) < 0) {
- printf("E: Unable to parse XML file: %s\n", strerror(errno));
+ err = nft_parse_err_alloc();
+ if (err == NULL) {
+ perror("error");
+ exit(EXIT_FAILURE);
+ }
+
+ if (nft_table_parse(t, NFT_PARSE_XML, xml, err) < 0) {
+ nft_parse_perror("Unable to parse XML file", err);
exit(EXIT_FAILURE);
}
@@ -76,6 +84,7 @@ int main(int argc, char *argv[])
NLM_F_CREATE|NLM_F_ACK, seq);
nft_table_nlmsg_build_payload(nlh, t);
nft_table_free(t);
+ nft_parse_err_free(err);
nl = mnl_socket_open(NETLINK_NETFILTER);
if (nl == NULL) {
diff --git a/include/Makefile.am b/include/Makefile.am
index 10332b7..5976bbd 100644
--- a/include/Makefile.am
+++ b/include/Makefile.am
@@ -1,3 +1,3 @@
-SUBDIRS = libnftables linux
+SUBDIRS = libnftnl linux
noinst_HEADERS = linux_list.h
diff --git a/include/libnftables/common.h b/include/libnftables/common.h
deleted file mode 100644
index 9cd92b2..0000000
--- a/include/libnftables/common.h
+++ /dev/null
@@ -1,20 +0,0 @@
-#ifndef _LIBNFTABLES_COMMON_H_
-#define _LIBNFTABLES_COMMON_H_
-
-enum nft_output_type {
- NFT_OUTPUT_DEFAULT = 0,
- NFT_OUTPUT_XML,
- NFT_OUTPUT_JSON,
-};
-
-enum nft_parse_type {
- NFT_PARSE_NONE = 0,
- NFT_PARSE_XML,
- NFT_PARSE_JSON,
- NFT_PARSE_MAX,
-};
-
-struct nlmsghdr *nft_nlmsg_build_hdr(char *buf, uint16_t cmd, uint16_t family,
- uint16_t type, uint32_t seq);
-
-#endif
diff --git a/include/libnftables/Makefile.am b/include/libnftnl/Makefile.am
index a0841d2..a0841d2 100644
--- a/include/libnftables/Makefile.am
+++ b/include/libnftnl/Makefile.am
diff --git a/include/libnftables/chain.h b/include/libnftnl/chain.h
index 8b4eab9..66626d8 100644
--- a/include/libnftables/chain.h
+++ b/include/libnftnl/chain.h
@@ -1,12 +1,12 @@
-#ifndef _LIBNFTABLES_CHAIN_H_
-#define _LIBNFTABLES_CHAIN_H_
+#ifndef _LIBNFTNL_CHAIN_H_
+#define _LIBNFTNL_CHAIN_H_
#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
#include <sys/types.h>
-#include <libnftables/common.h>
+#include <libnftnl/common.h>
#ifdef __cplusplus
extern "C" {
@@ -51,7 +51,10 @@ struct nlmsghdr;
void nft_chain_nlmsg_build_payload(struct nlmsghdr *nlh, const struct nft_chain *t);
-int nft_chain_parse(struct nft_chain *c, enum nft_parse_type type, const char *data);
+int nft_chain_parse(struct nft_chain *c, enum nft_parse_type type,
+ const char *data, struct nft_parse_err *err);
+int nft_chain_parse_file(struct nft_chain *c, enum nft_parse_type type,
+ FILE *fp, struct nft_parse_err *err);
int nft_chain_snprintf(char *buf, size_t size, struct nft_chain *t, uint32_t type, uint32_t flags);
int nft_chain_fprintf(FILE *fp, struct nft_chain *c, uint32_t type, uint32_t flags);
@@ -79,4 +82,4 @@ void nft_chain_list_iter_destroy(struct nft_chain_list_iter *iter);
} /* extern "C" */
#endif
-#endif /* _LIBNFTABLES_CHAIN_H_ */
+#endif /* _LIBNFTNL_CHAIN_H_ */
diff --git a/include/libnftnl/common.h b/include/libnftnl/common.h
new file mode 100644
index 0000000..f0c20f0
--- /dev/null
+++ b/include/libnftnl/common.h
@@ -0,0 +1,33 @@
+#ifndef _LIBNFTNL_COMMON_H_
+#define _LIBNFTNL_COMMON_H_
+
+#include <stdint.h>
+
+enum {
+ NFT_PARSE_EBADINPUT = 0,
+ NFT_PARSE_EMISSINGNODE,
+ NFT_PARSE_EBADTYPE,
+};
+
+enum nft_output_type {
+ NFT_OUTPUT_DEFAULT = 0,
+ NFT_OUTPUT_XML,
+ NFT_OUTPUT_JSON,
+};
+
+enum nft_parse_type {
+ NFT_PARSE_NONE = 0,
+ NFT_PARSE_XML,
+ NFT_PARSE_JSON,
+ NFT_PARSE_MAX,
+};
+
+struct nft_parse_err;
+
+struct nlmsghdr *nft_nlmsg_build_hdr(char *buf, uint16_t cmd, uint16_t family,
+ uint16_t type, uint32_t seq);
+
+struct nft_parse_err *nft_parse_err_alloc(void);
+void nft_parse_err_free(struct nft_parse_err *);
+int nft_parse_perror(const char *str, struct nft_parse_err *err);
+#endif
diff --git a/include/libnftables/expr.h b/include/libnftnl/expr.h
index 653bbb0..6ec05a6 100644
--- a/include/libnftables/expr.h
+++ b/include/libnftnl/expr.h
@@ -1,5 +1,5 @@
-#ifndef _LIBNFTABLES_RULE_EXPR_H_
-#define _LIBNFTABLES_RULE_EXPR_H_
+#ifndef _LIBNFTNL_RULE_EXPR_H_
+#define _LIBNFTNL_RULE_EXPR_H_
#include <stdint.h>
#include <stdbool.h>
@@ -154,4 +154,4 @@ enum {
} /* extern "C" */
#endif
-#endif /* _LIBNFTABLES_RULE_EXPR_H_ */
+#endif /* _LIBNFTNL_RULE_EXPR_H_ */
diff --git a/include/libnftables/rule.h b/include/libnftnl/rule.h
index 86dbc17..4033d3c 100644
--- a/include/libnftables/rule.h
+++ b/include/libnftnl/rule.h
@@ -1,12 +1,12 @@
-#ifndef _LIBNFTABLES_RULE_H_
-#define _LIBNFTABLES_RULE_H_
+#ifndef _LIBNFTNL_RULE_H_
+#define _LIBNFTNL_RULE_H_
#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
#include <sys/types.h>
-#include <libnftables/common.h>
+#include <libnftnl/common.h>
#ifdef __cplusplus
extern "C" {
@@ -47,7 +47,10 @@ struct nlmsghdr;
void nft_rule_nlmsg_build_payload(struct nlmsghdr *nlh, struct nft_rule *t);
-int nft_rule_parse(struct nft_rule *r, enum nft_parse_type type, const char *data);
+int nft_rule_parse(struct nft_rule *r, enum nft_parse_type type,
+ const char *data, struct nft_parse_err *err);
+int nft_rule_parse_file(struct nft_rule *r, enum nft_parse_type type,
+ FILE *fp, struct nft_parse_err *err);
int nft_rule_snprintf(char *buf, size_t size, struct nft_rule *t, uint32_t type, uint32_t flags);
int nft_rule_fprintf(FILE *fp, struct nft_rule *r, uint32_t type, uint32_t flags);
@@ -85,4 +88,4 @@ void nft_rule_list_iter_destroy(struct nft_rule_list_iter *iter);
} /* extern "C" */
#endif
-#endif /* _LIBNFTABLES_RULE_H_ */
+#endif /* _LIBNFTNL_RULE_H_ */
diff --git a/include/libnftables/ruleset.h b/include/libnftnl/ruleset.h
index 1ec3059..6f89110 100644
--- a/include/libnftables/ruleset.h
+++ b/include/libnftnl/ruleset.h
@@ -1,5 +1,5 @@
-#ifndef _LIBNFTABLES_RULESET_H_
-#define _LIBNFTABLES_RULESET_H_
+#ifndef _LIBNFTNL_RULESET_H_
+#define _LIBNFTNL_RULESET_H_
#include <stdio.h>
@@ -7,7 +7,7 @@
#include <stdint.h>
#include <sys/types.h>
-#include <libnftables/common.h>
+#include <libnftnl/common.h>
#ifdef __cplusplus
extern "C" {
@@ -30,7 +30,10 @@ void nft_ruleset_attr_unset(struct nft_ruleset *r, uint16_t attr);
void nft_ruleset_attr_set(struct nft_ruleset *r, uint16_t attr, void *data);
const void *nft_ruleset_attr_get(const struct nft_ruleset *r, uint16_t attr);
-int nft_ruleset_parse(struct nft_ruleset *rs, enum nft_parse_type type, const char *data);
+int nft_ruleset_parse(struct nft_ruleset *rs, enum nft_parse_type type,
+ const char *data, struct nft_parse_err *err);
+int nft_ruleset_parse_file(struct nft_ruleset *rs, enum nft_parse_type type,
+ FILE *fp, struct nft_parse_err *err);
int nft_ruleset_snprintf(char *buf, size_t size, const struct nft_ruleset *rs, uint32_t type, uint32_t flags);
int nft_ruleset_fprintf(FILE *fp, const struct nft_ruleset *rs, uint32_t type, uint32_t flags);
@@ -38,4 +41,4 @@ int nft_ruleset_fprintf(FILE *fp, const struct nft_ruleset *rs, uint32_t type, u
} /* extern "C" */
#endif
-#endif /* _LIBNFTABLES_RULESET_H_ */
+#endif /* _LIBNFTNL_RULESET_H_ */
diff --git a/include/libnftables/set.h b/include/libnftnl/set.h
index 13ac857..7fa9fb2 100644
--- a/include/libnftables/set.h
+++ b/include/libnftnl/set.h
@@ -1,12 +1,12 @@
-#ifndef _LIBNFTABLES_SET_H_
-#define _LIBNFTABLES_SET_H_
+#ifndef _LIBNFTNL_SET_H_
+#define _LIBNFTNL_SET_H_
#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
#include <sys/types.h>
-#include <libnftables/common.h>
+#include <libnftnl/common.h>
enum {
NFT_SET_ATTR_TABLE,
@@ -60,7 +60,10 @@ struct nft_set *nft_set_list_iter_cur(struct nft_set_list_iter *iter);
struct nft_set *nft_set_list_iter_next(struct nft_set_list_iter *iter);
void nft_set_list_iter_destroy(struct nft_set_list_iter *iter);
-int nft_set_parse(struct nft_set *s, enum nft_parse_type type, const char *data);
+int nft_set_parse(struct nft_set *s, enum nft_parse_type type,
+ const char *data, struct nft_parse_err *err);
+int nft_set_parse_file(struct nft_set *s, enum nft_parse_type type,
+ FILE *fp, struct nft_parse_err *err);
/*
* Set elements
@@ -98,7 +101,10 @@ void nft_set_elem_nlmsg_build_payload(struct nlmsghdr *nlh, struct nft_set_elem
int nft_set_elem_nlmsg_parse(const struct nlmsghdr *nlh, struct nft_set_elem *s);
-int nft_set_elem_parse(struct nft_set_elem *e, enum nft_parse_type type, const char *data);
+int nft_set_elem_parse(struct nft_set_elem *e, enum nft_parse_type type,
+ const char *data, struct nft_parse_err *err);
+int nft_set_elem_parse_file(struct nft_set_elem *e, enum nft_parse_type type,
+ FILE *fp, struct nft_parse_err *err);
int nft_set_elem_snprintf(char *buf, size_t size, struct nft_set_elem *s, uint32_t type, uint32_t flags);
int nft_set_elem_fprintf(FILE *fp, struct nft_set_elem *se, uint32_t type, uint32_t flags);
@@ -110,4 +116,4 @@ struct nft_set_elem *nft_set_elems_iter_cur(struct nft_set_elems_iter *iter);
struct nft_set_elem *nft_set_elems_iter_next(struct nft_set_elems_iter *iter);
void nft_set_elems_iter_destroy(struct nft_set_elems_iter *iter);
-#endif /* _LIBNFTABLES_SET_H_ */
+#endif /* _LIBNFTNL_SET_H_ */
diff --git a/include/libnftables/table.h b/include/libnftnl/table.h
index 1d2be07..56e7e35 100644
--- a/include/libnftables/table.h
+++ b/include/libnftnl/table.h
@@ -1,12 +1,12 @@
-#ifndef _LIBNFTABLES_TABLE_H_
-#define _LIBNFTABLES_TABLE_H_
+#ifndef _LIBNFTNL_TABLE_H_
+#define _LIBNFTNL_TABLE_H_
#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
#include <sys/types.h>
-#include <libnftables/common.h>
+#include <libnftnl/common.h>
#ifdef __cplusplus
extern "C" {
@@ -40,7 +40,10 @@ struct nlmsghdr;
void nft_table_nlmsg_build_payload(struct nlmsghdr *nlh, const struct nft_table *t);
-int nft_table_parse(struct nft_table *t, enum nft_parse_type type, const char *data);
+int nft_table_parse(struct nft_table *t, enum nft_parse_type type,
+ const char *data, struct nft_parse_err *err);
+int nft_table_parse_file(struct nft_table *t, enum nft_parse_type type,
+ FILE *fp, struct nft_parse_err *err);
int nft_table_snprintf(char *buf, size_t size, struct nft_table *t, uint32_t type, uint32_t flags);
int nft_table_fprintf(FILE *fp, struct nft_table *t, uint32_t type, uint32_t flags);
@@ -68,4 +71,4 @@ void nft_table_list_iter_destroy(struct nft_table_list_iter *iter);
} /* extern "C" */
#endif
-#endif /* _LIBNFTABLES_TABLE_H_ */
+#endif /* _LIBNFTNL_TABLE_H_ */
diff --git a/include/linux/kernel.h b/include/linux/kernel.h
new file mode 100644
index 0000000..d4c59f6
--- /dev/null
+++ b/include/linux/kernel.h
@@ -0,0 +1,29 @@
+#ifndef _LINUX_KERNEL_H
+#define _LINUX_KERNEL_H
+
+/*
+ * 'kernel.h' contains some often-used function prototypes etc
+ */
+#define __ALIGN_KERNEL(x, a) __ALIGN_KERNEL_MASK(x, (typeof(x))(a) - 1)
+#define __ALIGN_KERNEL_MASK(x, mask) (((x) + (mask)) & ~(mask))
+
+
+#define SI_LOAD_SHIFT 16
+struct sysinfo {
+ long uptime; /* Seconds since boot */
+ unsigned long loads[3]; /* 1, 5, and 15 minute load averages */
+ unsigned long totalram; /* Total usable main memory size */
+ unsigned long freeram; /* Available memory size */
+ unsigned long sharedram; /* Amount of shared memory */
+ unsigned long bufferram; /* Memory used by buffers */
+ unsigned long totalswap; /* Total swap space size */
+ unsigned long freeswap; /* swap space still available */
+ unsigned short procs; /* Number of current processes */
+ unsigned short pad; /* explicit padding for m68k */
+ unsigned long totalhigh; /* Total high memory size */
+ unsigned long freehigh; /* Available high memory size */
+ unsigned int mem_unit; /* Memory unit size in bytes */
+ char _f[20-2*sizeof(long)-sizeof(int)]; /* Padding: libc5 uses this.. */
+};
+
+#endif
diff --git a/include/linux/netfilter/nf_tables.h b/include/linux/netfilter/nf_tables.h
index 6a22a37..31ddd06 100644
--- a/include/linux/netfilter/nf_tables.h
+++ b/include/linux/netfilter/nf_tables.h
@@ -32,6 +32,25 @@ enum nft_verdicts {
NFT_RETURN = -5,
};
+/**
+ * enum nf_tables_msg_types - nf_tables netlink message types
+ *
+ * @NFT_MSG_NEWTABLE: create a new table (enum nft_table_attributes)
+ * @NFT_MSG_GETTABLE: get a table (enum nft_table_attributes)
+ * @NFT_MSG_DELTABLE: delete a table (enum nft_table_attributes)
+ * @NFT_MSG_NEWCHAIN: create a new chain (enum nft_chain_attributes)
+ * @NFT_MSG_GETCHAIN: get a chain (enum nft_chain_attributes)
+ * @NFT_MSG_DELCHAIN: delete a chain (enum nft_chain_attributes)
+ * @NFT_MSG_NEWRULE: create a new rule (enum nft_rule_attributes)
+ * @NFT_MSG_GETRULE: get a rule (enum nft_rule_attributes)
+ * @NFT_MSG_DELRULE: delete a rule (enum nft_rule_attributes)
+ * @NFT_MSG_NEWSET: create a new set (enum nft_set_attributes)
+ * @NFT_MSG_GETSET: get a set (enum nft_set_attributes)
+ * @NFT_MSG_DELSET: delete a set (enum nft_set_attributes)
+ * @NFT_MSG_NEWSETELEM: create a new set element (enum nft_set_elem_attributes)
+ * @NFT_MSG_GETSETELEM: get a set element (enum nft_set_elem_attributes)
+ * @NFT_MSG_DELSETELEM: delete a set element (enum nft_set_elem_attributes)
+ */
enum nf_tables_msg_types {
NFT_MSG_NEWTABLE,
NFT_MSG_GETTABLE,
@@ -90,6 +109,7 @@ enum nft_table_flags {
* enum nft_table_attributes - nf_tables table netlink attributes
*
* @NFTA_TABLE_NAME: name of the table (NLA_STRING)
+ * @NFTA_TABLE_FLAGS: bitmask of enum nft_table_flags (NLA_U32)
*/
enum nft_table_attributes {
NFTA_TABLE_UNSPEC,
@@ -104,8 +124,13 @@ enum nft_table_attributes {
* enum nft_chain_attributes - nf_tables chain netlink attributes
*
* @NFTA_CHAIN_TABLE: name of the table containing the chain (NLA_STRING)
+ * @NFTA_CHAIN_HANDLE: numeric handle of the chain (NLA_U64)
* @NFTA_CHAIN_NAME: name of the chain (NLA_STRING)
* @NFTA_CHAIN_HOOK: hook specification for basechains (NLA_NESTED: nft_hook_attributes)
+ * @NFTA_CHAIN_POLICY: numeric policy of the chain (NLA_U32)
+ * @NFTA_CHAIN_USE: number of references to this chain (NLA_U32)
+ * @NFTA_CHAIN_TYPE: type name of the string (NLA_NUL_STRING)
+ * @NFTA_CHAIN_COUNTERS: counter specification of the chain (NLA_NESTED: nft_counter_attributes)
*/
enum nft_chain_attributes {
NFTA_CHAIN_UNSPEC,
@@ -126,8 +151,10 @@ enum nft_chain_attributes {
*
* @NFTA_RULE_TABLE: name of the table containing the rule (NLA_STRING)
* @NFTA_RULE_CHAIN: name of the chain containing the rule (NLA_STRING)
- * @NFTA_RULE_HANDLE: numeric handle of the rule (NLA_U16)
+ * @NFTA_RULE_HANDLE: numeric handle of the rule (NLA_U64)
* @NFTA_RULE_EXPRESSIONS: list of expressions (NLA_NESTED: nft_expr_attributes)
+ * @NFTA_RULE_COMPAT: compatibility specifications of the rule (NLA_NESTED: nft_rule_compat_attributes)
+ * @NFTA_RULE_POSITION: numeric handle of the previous rule (NLA_U64)
*/
enum nft_rule_attributes {
NFTA_RULE_UNSPEC,
@@ -141,11 +168,22 @@ enum nft_rule_attributes {
};
#define NFTA_RULE_MAX (__NFTA_RULE_MAX - 1)
+/**
+ * enum nft_rule_compat_flags - nf_tables rule compat flags
+ *
+ * @NFT_RULE_COMPAT_F_INV: invert the check result
+ */
enum nft_rule_compat_flags {
NFT_RULE_COMPAT_F_INV = (1 << 1),
NFT_RULE_COMPAT_F_MASK = NFT_RULE_COMPAT_F_INV,
};
+/**
+ * enum nft_rule_compat_attributes - nf_tables rule compat attributes
+ *
+ * @NFTA_RULE_COMPAT_PROTO: numerice value of handled protocol (NLA_U32)
+ * @NFTA_RULE_COMPAT_FLAGS: bitmask of enum nft_rule_compat_flags (NLA_U32)
+ */
enum nft_rule_compat_attributes {
NFTA_RULE_COMPAT_UNSPEC,
NFTA_RULE_COMPAT_PROTO,
@@ -343,11 +381,26 @@ enum nft_bitwise_attributes {
};
#define NFTA_BITWISE_MAX (__NFTA_BITWISE_MAX - 1)
+/**
+ * enum nft_byteorder_ops - nf_tables byteorder operators
+ *
+ * @NFT_BYTEORDER_NTOH: network to host operator
+ * @NFT_BYTEORDER_HTON: host to network opertaor
+ */
enum nft_byteorder_ops {
NFT_BYTEORDER_NTOH,
NFT_BYTEORDER_HTON,
};
+/**
+ * enum nft_byteorder_attributes - nf_tables byteorder expression netlink attributes
+ *
+ * @NFTA_BYTEORDER_SREG: source register (NLA_U32: nft_registers)
+ * @NFTA_BYTEORDER_DREG: destination register (NLA_U32: nft_registers)
+ * @NFTA_BYTEORDER_OP: operator (NLA_U32: enum nft_byteorder_ops)
+ * @NFTA_BYTEORDER_LEN: length of the data (NLA_U32)
+ * @NFTA_BYTEORDER_SIZE: data size in bytes (NLA_U32: 2 or 4)
+ */
enum nft_byteorder_attributes {
NFTA_BYTEORDER_UNSPEC,
NFTA_BYTEORDER_SREG,
@@ -359,6 +412,16 @@ enum nft_byteorder_attributes {
};
#define NFTA_BYTEORDER_MAX (__NFTA_BYTEORDER_MAX - 1)
+/**
+ * enum nft_cmp_ops - nf_tables relational operator
+ *
+ * @NFT_CMP_EQ: equal
+ * @NFT_CMP_NEQ: not equal
+ * @NFT_CMP_LT: less than
+ * @NFT_CMP_LTE: less than or equal to
+ * @NFT_CMP_GT: greater than
+ * @NFT_CMP_GTE: greater than or equal to
+ */
enum nft_cmp_ops {
NFT_CMP_EQ,
NFT_CMP_NEQ,
@@ -384,6 +447,13 @@ enum nft_cmp_attributes {
};
#define NFTA_CMP_MAX (__NFTA_CMP_MAX - 1)
+/**
+ * enum nft_lookup_attributes - nf_tables set lookup expression netlink attributes
+ *
+ * @NFTA_LOOKUP_SET: name of the set where to look for (NLA_STRING)
+ * @NFTA_LOOKUP_SREG: source register of the data to look for (NLA_U32: nft_registers)
+ * @NFTA_LOOKUP_DREG: destination register (NLA_U32: nft_registers)
+ */
enum nft_lookup_attributes {
NFTA_LOOKUP_UNSPEC,
NFTA_LOOKUP_SET,
@@ -424,6 +494,14 @@ enum nft_payload_attributes {
};
#define NFTA_PAYLOAD_MAX (__NFTA_PAYLOAD_MAX - 1)
+/**
+ * enum nft_exthdr_attributes - nf_tables IPv6 extension header expression netlink attributes
+ *
+ * @NFTA_EXTHDR_DREG: destination register (NLA_U32: nft_registers)
+ * @NFTA_EXTHDR_TYPE: extension header type (NLA_U8)
+ * @NFTA_EXTHDR_OFFSET: extension header offset (NLA_U32)
+ * @NFTA_EXTHDR_LEN: extension header length (NLA_U32)
+ */
enum nft_exthdr_attributes {
NFTA_EXTHDR_UNSPEC,
NFTA_EXTHDR_DREG,
@@ -648,10 +726,11 @@ enum nft_nat_types {
* enum nft_nat_attributes - nf_tables nat expression netlink attributes
*
* @NFTA_NAT_TYPE: NAT type (NLA_U32: nft_nat_types)
- * @NFTA_NAT_ADDR_MIN: source register of address range start (NLA_U32: nft_registers)
- * @NFTA_NAT_ADDR_MAX: source register of address range end (NLA_U32: nft_registers)
- * @NFTA_NAT_PROTO_MIN: source register of proto range start (NLA_U32: nft_registers)
- * @NFTA_NAT_PROTO_MAX: source register of proto range end (NLA_U32: nft_registers)
+ * @NFTA_NAT_FAMILY: NAT family (NLA_U32)
+ * @NFTA_NAT_REG_ADDR_MIN: source register of address range start (NLA_U32: nft_registers)
+ * @NFTA_NAT_REG_ADDR_MAX: source register of address range end (NLA_U32: nft_registers)
+ * @NFTA_NAT_REG_PROTO_MIN: source register of proto range start (NLA_U32: nft_registers)
+ * @NFTA_NAT_REG_PROTO_MAX: source register of proto range end (NLA_U32: nft_registers)
*/
enum nft_nat_attributes {
NFTA_NAT_UNSPEC,
diff --git a/include/linux/netfilter/nfnetlink.h b/include/linux/netfilter/nfnetlink.h
index 91eebab..336c10c 100644
--- a/include/linux/netfilter/nfnetlink.h
+++ b/include/linux/netfilter/nfnetlink.h
@@ -97,4 +97,9 @@ extern void nfnl_unlock(void);
MODULE_ALIAS("nfnetlink-subsys-" __stringify(subsys))
#endif /* __KERNEL__ */
+
+/* Reserved control nfnetlink messages */
+#define NFNL_MSG_BATCH_BEGIN NLMSG_MIN_TYPE
+#define NFNL_MSG_BATCH_END NLMSG_MIN_TYPE+1
+
#endif /* _NFNETLINK_H */
diff --git a/include/linux/netfilter/x_tables.h b/include/linux/netfilter/x_tables.h
new file mode 100644
index 0000000..4120970
--- /dev/null
+++ b/include/linux/netfilter/x_tables.h
@@ -0,0 +1,185 @@
+#ifndef _X_TABLES_H
+#define _X_TABLES_H
+#include <linux/kernel.h>
+#include <linux/types.h>
+
+#define XT_FUNCTION_MAXNAMELEN 30
+#define XT_EXTENSION_MAXNAMELEN 29
+#define XT_TABLE_MAXNAMELEN 32
+
+struct xt_entry_match {
+ union {
+ struct {
+ __u16 match_size;
+
+ /* Used by userspace */
+ char name[XT_EXTENSION_MAXNAMELEN];
+ __u8 revision;
+ } user;
+ struct {
+ __u16 match_size;
+
+ /* Used inside the kernel */
+ struct xt_match *match;
+ } kernel;
+
+ /* Total length */
+ __u16 match_size;
+ } u;
+
+ unsigned char data[0];
+};
+
+struct xt_entry_target {
+ union {
+ struct {
+ __u16 target_size;
+
+ /* Used by userspace */
+ char name[XT_EXTENSION_MAXNAMELEN];
+ __u8 revision;
+ } user;
+ struct {
+ __u16 target_size;
+
+ /* Used inside the kernel */
+ struct xt_target *target;
+ } kernel;
+
+ /* Total length */
+ __u16 target_size;
+ } u;
+
+ unsigned char data[0];
+};
+
+#define XT_TARGET_INIT(__name, __size) \
+{ \
+ .target.u.user = { \
+ .target_size = XT_ALIGN(__size), \
+ .name = __name, \
+ }, \
+}
+
+struct xt_standard_target {
+ struct xt_entry_target target;
+ int verdict;
+};
+
+struct xt_error_target {
+ struct xt_entry_target target;
+ char errorname[XT_FUNCTION_MAXNAMELEN];
+};
+
+/* The argument to IPT_SO_GET_REVISION_*. Returns highest revision
+ * kernel supports, if >= revision. */
+struct xt_get_revision {
+ char name[XT_EXTENSION_MAXNAMELEN];
+ __u8 revision;
+};
+
+/* CONTINUE verdict for targets */
+#define XT_CONTINUE 0xFFFFFFFF
+
+/* For standard target */
+#define XT_RETURN (-NF_REPEAT - 1)
+
+/* this is a dummy structure to find out the alignment requirement for a struct
+ * containing all the fundamental data types that are used in ipt_entry,
+ * ip6t_entry and arpt_entry. This sucks, and it is a hack. It will be my
+ * personal pleasure to remove it -HW
+ */
+struct _xt_align {
+ __u8 u8;
+ __u16 u16;
+ __u32 u32;
+ __u64 u64;
+};
+
+#define XT_ALIGN(s) __ALIGN_KERNEL((s), __alignof__(struct _xt_align))
+
+/* Standard return verdict, or do jump. */
+#define XT_STANDARD_TARGET ""
+/* Error verdict. */
+#define XT_ERROR_TARGET "ERROR"
+
+#define SET_COUNTER(c,b,p) do { (c).bcnt = (b); (c).pcnt = (p); } while(0)
+#define ADD_COUNTER(c,b,p) do { (c).bcnt += (b); (c).pcnt += (p); } while(0)
+
+struct xt_counters {
+ __u64 pcnt, bcnt; /* Packet and byte counters */
+};
+
+/* The argument to IPT_SO_ADD_COUNTERS. */
+struct xt_counters_info {
+ /* Which table. */
+ char name[XT_TABLE_MAXNAMELEN];
+
+ unsigned int num_counters;
+
+ /* The counters (actually `number' of these). */
+ struct xt_counters counters[0];
+};
+
+#define XT_INV_PROTO 0x40 /* Invert the sense of PROTO. */
+
+/* fn returns 0 to continue iteration */
+#define XT_MATCH_ITERATE(type, e, fn, args...) \
+({ \
+ unsigned int __i; \
+ int __ret = 0; \
+ struct xt_entry_match *__m; \
+ \
+ for (__i = sizeof(type); \
+ __i < (e)->target_offset; \
+ __i += __m->u.match_size) { \
+ __m = (void *)e + __i; \
+ \
+ __ret = fn(__m , ## args); \
+ if (__ret != 0) \
+ break; \
+ } \
+ __ret; \
+})
+
+/* fn returns 0 to continue iteration */
+#define XT_ENTRY_ITERATE_CONTINUE(type, entries, size, n, fn, args...) \
+({ \
+ unsigned int __i, __n; \
+ int __ret = 0; \
+ type *__entry; \
+ \
+ for (__i = 0, __n = 0; __i < (size); \
+ __i += __entry->next_offset, __n++) { \
+ __entry = (void *)(entries) + __i; \
+ if (__n < n) \
+ continue; \
+ \
+ __ret = fn(__entry , ## args); \
+ if (__ret != 0) \
+ break; \
+ } \
+ __ret; \
+})
+
+/* fn returns 0 to continue iteration */
+#define XT_ENTRY_ITERATE(type, entries, size, fn, args...) \
+ XT_ENTRY_ITERATE_CONTINUE(type, entries, size, 0, fn, args)
+
+
+/* pos is normally a struct ipt_entry/ip6t_entry/etc. */
+#define xt_entry_foreach(pos, ehead, esize) \
+ for ((pos) = (typeof(pos))(ehead); \
+ (pos) < (typeof(pos))((char *)(ehead) + (esize)); \
+ (pos) = (typeof(pos))((char *)(pos) + (pos)->next_offset))
+
+/* can only be xt_entry_match, so no use of typeof here */
+#define xt_ematch_foreach(pos, entry) \
+ for ((pos) = (struct xt_entry_match *)entry->elems; \
+ (pos) < (struct xt_entry_match *)((char *)(entry) + \
+ (entry)->target_offset); \
+ (pos) = (struct xt_entry_match *)((char *)(pos) + \
+ (pos)->u.match_size))
+
+
+#endif /* _X_TABLES_H */
diff --git a/libnftables.pc.in b/libnftnl.pc.in
index 0c6d57e..fd5cc6a 100644
--- a/libnftables.pc.in
+++ b/libnftnl.pc.in
@@ -1,15 +1,15 @@
-# libnftables pkg-config file
+# libnftnl pkg-config file
prefix=@prefix@
exec_prefix=@exec_prefix@
libdir=@libdir@
includedir=@includedir@
-Name: libnftables
+Name: libnftnl
Description: Netfilter nf_tables infrastructure library
-URL: http://netfilter.org/projects/libnftables/
+URL: http://netfilter.org/projects/libnftnl/
Version: @VERSION@
Requires:
Conflicts:
-Libs: -L${libdir} -lnftables
+Libs: -L${libdir} -lnftnl
Cflags: -I${includedir}
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;
}
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 576bf73..d5df071 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -24,67 +24,67 @@ check_PROGRAMS = nft-parsing-test \
nft-expr_target-test
nft_parsing_test_SOURCES = nft-parsing-test.c
-nft_parsing_test_LDADD = ../src/libnftables.la ${LIBMNL_LIBS} ${LIBXML_LIBS} ${LIBJSON_LIBS}
+nft_parsing_test_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS} ${LIBXML_LIBS} ${LIBJSON_LIBS}
nft_table_test_SOURCES = nft-table-test.c
-nft_table_test_LDADD = ../src/libnftables.la ${LIBMNL_LIBS}
+nft_table_test_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
nft_chain_test_SOURCES = nft-chain-test.c
-nft_chain_test_LDADD = ../src/libnftables.la ${LIBMNL_LIBS}
+nft_chain_test_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
nft_rule_test_SOURCES = nft-rule-test.c
-nft_rule_test_LDADD = ../src/libnftables.la ${LIBMNL_LIBS}
+nft_rule_test_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
nft_set_test_SOURCES = nft-set-test.c
-nft_set_test_LDADD = ../src/libnftables.la ${LIBMNL_LIBS}
+nft_set_test_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
nft_expr_bitwise_test_SOURCES = nft-expr_bitwise-test.c
-nft_expr_bitwise_test_LDADD = ../src/libnftables.la ${LIBMNL_LIBS}
+nft_expr_bitwise_test_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
nft_expr_byteorder_test_SOURCES = nft-expr_byteorder-test.c
-nft_expr_byteorder_test_LDADD = ../src/libnftables.la ${LIBMNL_LIBS}
+nft_expr_byteorder_test_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
nft_expr_cmp_test_SOURCES = nft-expr_cmp-test.c
-nft_expr_cmp_test_LDADD = ../src/libnftables.la ${LIBMNL_LIBS}
+nft_expr_cmp_test_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
nft_expr_counter_test_SOURCES = nft-expr_counter-test.c
-nft_expr_counter_test_LDADD = ../src/libnftables.la ${LIBMNL_LIBS}
+nft_expr_counter_test_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
nft_expr_exthdr_test_SOURCES = nft-expr_exthdr-test.c
-nft_expr_exthdr_test_LDADD = ../src/libnftables.la ${LIBMNL_LIBS}
+nft_expr_exthdr_test_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
nft_expr_ct_test_SOURCES = nft-expr_ct-test.c
-nft_expr_ct_test_LDADD = ../src/libnftables.la ${LIBMNL_LIBS}
+nft_expr_ct_test_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
nft_expr_immediate_test_SOURCES = nft-expr_counter-test.c
-nft_expr_immediate_test_LDADD = ../src/libnftables.la ${LIBMNL_LIBS}
+nft_expr_immediate_test_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
nft_expr_limit_test_SOURCES = nft-expr_limit-test.c
-nft_expr_limit_test_LDADD = ../src/libnftables.la ${LIBMNL_LIBS}
+nft_expr_limit_test_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
nft_expr_lookup_test_SOURCES = nft-expr_limit-test.c
-nft_expr_lookup_test_LDADD = ../src/libnftables.la ${LIBMNL_LIBS}
+nft_expr_lookup_test_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
nft_expr_log_test_SOURCES = nft-expr_log-test.c
-nft_expr_log_test_LDADD = ../src/libnftables.la ${LIBMNL_LIBS}
+nft_expr_log_test_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
nft_expr_match_test_SOURCES = nft-expr_match-test.c
-nft_expr_match_test_LDADD = ../src/libnftables.la ${LIBMNL_LIBS}
+nft_expr_match_test_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
nft_expr_meta_test_SOURCES = nft-expr_meta-test.c
-nft_expr_meta_test_LDADD = ../src/libnftables.la ${LIBMNL_LIBS}
+nft_expr_meta_test_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
nft_expr_nat_test_SOURCES = nft-expr_nat-test.c
-nft_expr_nat_test_LDADD = ../src/libnftables.la ${LIBMNL_LIBS}
+nft_expr_nat_test_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
nft_expr_payload_test_SOURCES = nft-expr_payload-test.c
-nft_expr_payload_test_LDADD = ../src/libnftables.la ${LIBMNL_LIBS}
+nft_expr_payload_test_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
nft_expr_queue_test_SOURCES = nft-expr_queue-test.c
-nft_expr_queue_test_LDADD = ../src/libnftables.la ${LIBMNL_LIBS}
+nft_expr_queue_test_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
nft_expr_reject_test_SOURCES = nft-expr_reject-test.c
-nft_expr_reject_test_LDADD = ../src/libnftables.la ${LIBMNL_LIBS}
+nft_expr_reject_test_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
nft_expr_target_test_SOURCES = nft-expr_target-test.c
-nft_expr_target_test_LDADD = ../src/libnftables.la ${LIBMNL_LIBS}
+nft_expr_target_test_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
diff --git a/tests/jsonfiles/01-table.json b/tests/jsonfiles/01-table.json
index f217189..9be7b40 100644
--- a/tests/jsonfiles/01-table.json
+++ b/tests/jsonfiles/01-table.json
@@ -1 +1 @@
-{"table":{"name":"filter","family":"ip","flags":0,"use":0}}
+{"nftables":[{"table":{"name":"filter","family":"ip","flags":0,"use":0}}]}
diff --git a/tests/jsonfiles/02-table.json b/tests/jsonfiles/02-table.json
index c23e7b0..4ff5674 100644
--- a/tests/jsonfiles/02-table.json
+++ b/tests/jsonfiles/02-table.json
@@ -1 +1 @@
-{"table":{"name":"filter2","family":"ip6","flags":0,"use":0}}
+{"nftables":[{"table":{"name":"filter2","family":"ip6","flags":0,"use":0}}]}
diff --git a/tests/jsonfiles/11-chain.json b/tests/jsonfiles/11-chain.json
index e1ed07f..2610b79 100644
--- a/tests/jsonfiles/11-chain.json
+++ b/tests/jsonfiles/11-chain.json
@@ -1 +1 @@
-{"chain":{"name":"input","handle":1,"bytes":1375696,"packets":4136,"family":"ip","table":"filter","use":0,"type":"filter","hooknum":"input","prio":0,"policy":"accept"}}
+{"nftables":[{"chain":{"name":"input","handle":1,"bytes":1375696,"packets":4136,"family":"ip","table":"filter","use":0,"type":"filter","hooknum":"input","prio":0,"policy":"accept"}}]}
diff --git a/tests/jsonfiles/12-chain.json b/tests/jsonfiles/12-chain.json
index b3fa541..3d15982 100644
--- a/tests/jsonfiles/12-chain.json
+++ b/tests/jsonfiles/12-chain.json
@@ -1 +1 @@
-{"chain":{"name":"forward","handle":2,"bytes":0,"packets":0,"family":"ip","table":"filter","use":0,"type":"filter","hooknum":"forward","prio":0,"policy":"accept"}}
+{"nftables":[{"chain":{"name":"forward","handle":2,"bytes":0,"packets":0,"family":"ip","table":"filter","use":0,"type":"filter","hooknum":"forward","prio":0,"policy":"accept"}}]}
diff --git a/tests/jsonfiles/13-chain.json b/tests/jsonfiles/13-chain.json
index 6d8230d..e3a17f0 100644
--- a/tests/jsonfiles/13-chain.json
+++ b/tests/jsonfiles/13-chain.json
@@ -1 +1 @@
-{"chain":{"name":"output","handle":3,"bytes":454786,"packets":2681,"family":"ip","table":"filter","use":0,"type":"filter","hooknum":"output","prio":0,"policy":"accept"}}
+{"nftables":[{"chain":{"name":"output","handle":3,"bytes":454786,"packets":2681,"family":"ip","table":"filter","use":0,"type":"filter","hooknum":"output","prio":0,"policy":"accept"}}]}
diff --git a/tests/jsonfiles/14-chain.json b/tests/jsonfiles/14-chain.json
index 44bc106..d98dc94 100644
--- a/tests/jsonfiles/14-chain.json
+++ b/tests/jsonfiles/14-chain.json
@@ -1 +1 @@
-{"chain":{"name":"chain1","handle":4,"bytes":0,"packets":0,"family":"ip","table":"filter","use":0}}
+{"nftables":[{"chain":{"name":"chain1","handle":4,"bytes":0,"packets":0,"family":"ip","table":"filter","use":0}}]}
diff --git a/tests/jsonfiles/20-rule-bitwise.json b/tests/jsonfiles/20-rule-bitwise.json
index 511ad88..de3d9ec 100644
--- a/tests/jsonfiles/20-rule-bitwise.json
+++ b/tests/jsonfiles/20-rule-bitwise.json
@@ -1 +1 @@
-{"rule":{"family":"ip","table":"filter","chain":"input","handle":20,"expr":[{"type":"bitwise","sreg":1,"dreg":1,"len":4,"mask":{"data_reg":{"type":"value","len":4,"data0":"0x0000000a"}},"xor":{"data_reg":{"type":"value","len":4,"data0":"0x00000000"}}}]}}
+{"nftables":[{"rule":{"family":"ip","table":"filter","chain":"input","handle":20,"expr":[{"type":"bitwise","sreg":1,"dreg":1,"len":4,"mask":{"data_reg":{"type":"value","len":4,"data0":"0x0000000a"}},"xor":{"data_reg":{"type":"value","len":4,"data0":"0x00000000"}}}]}}]}
diff --git a/tests/jsonfiles/21-rule-byteorder.json b/tests/jsonfiles/21-rule-byteorder.json
index 9c5498e..ae6fb32 100644
--- a/tests/jsonfiles/21-rule-byteorder.json
+++ b/tests/jsonfiles/21-rule-byteorder.json
@@ -1 +1 @@
-{"rule":{"family":"ip","table":"filter","chain":"input","handle":21,"expr":[{"type":"byteorder","sreg":3,"dreg":4,"op":"hton","len":4,"size":4}]}}
+{"nftables":[{"rule":{"family":"ip","table":"filter","chain":"input","handle":21,"expr":[{"type":"byteorder","sreg":3,"dreg":4,"op":"hton","len":4,"size":4}]}}]}
diff --git a/tests/jsonfiles/22-rule-cmp.json b/tests/jsonfiles/22-rule-cmp.json
index ad1c71a..c32d7ad 100644
--- a/tests/jsonfiles/22-rule-cmp.json
+++ b/tests/jsonfiles/22-rule-cmp.json
@@ -1 +1 @@
-{"rule":{"family":"ip","table":"filter","chain":"forward","handle":22,"expr":[{"type":"cmp","sreg":1,"op":"eq","cmpdata":{"data_reg":{"type":"value","len":16,"data0":"0x00000000","data1":"0x6e6f6200","data2":"0x2e303164","data3":"0x00393331"}}}]}}
+{"nftables":[{"rule":{"family":"ip","table":"filter","chain":"forward","handle":22,"expr":[{"type":"cmp","sreg":1,"op":"eq","cmpdata":{"data_reg":{"type":"value","len":16,"data0":"0x00000000","data1":"0x6e6f6200","data2":"0x2e303164","data3":"0x00393331"}}}]}}]}
diff --git a/tests/jsonfiles/23-rule-counter.json b/tests/jsonfiles/23-rule-counter.json
index 331ab2c..95d5072 100644
--- a/tests/jsonfiles/23-rule-counter.json
+++ b/tests/jsonfiles/23-rule-counter.json
@@ -1 +1 @@
-{"rule":{"family":"ip","table":"filter","chain":"output","handle":23,"expr":[{"type":"counter","pkts":135,"bytes":21655}]}}
+{"nftables":[{"rule":{"family":"ip","table":"filter","chain":"output","handle":23,"expr":[{"type":"counter","pkts":135,"bytes":21655}]}}]}
diff --git a/tests/jsonfiles/24-rule-ct.json b/tests/jsonfiles/24-rule-ct.json
index 3b161f3..1aa3dd2 100644
--- a/tests/jsonfiles/24-rule-ct.json
+++ b/tests/jsonfiles/24-rule-ct.json
@@ -1 +1 @@
-{"rule":{"family":"ip","table":"filter","chain":"input","handle":24,"expr":[{"type":"ct","dreg":1,"key":"state"},{"type":"cmp","sreg":1,"op":"eq","cmpdata":{"data_reg":{"type":"value","len":4,"data0":"0x00000008"}}}]}}
+{"nftables":[{"rule":{"family":"ip","table":"filter","chain":"input","handle":24,"expr":[{"type":"ct","dreg":1,"key":"state"},{"type":"cmp","sreg":1,"op":"eq","cmpdata":{"data_reg":{"type":"value","len":4,"data0":"0x00000008"}}}]}}]}
diff --git a/tests/jsonfiles/25-rule-exthdr.json b/tests/jsonfiles/25-rule-exthdr.json
index 32667a3..c40a074 100644
--- a/tests/jsonfiles/25-rule-exthdr.json
+++ b/tests/jsonfiles/25-rule-exthdr.json
@@ -1 +1 @@
-{"rule":{"family":"ip","table":"filter","chain":"input","handle":25,"expr":[{"type":"exthdr","dreg":1,"exthdr_type":"mh","offset":2,"len":16}]}}
+{"nftables":[{"rule":{"family":"ip","table":"filter","chain":"input","handle":25,"expr":[{"type":"exthdr","dreg":1,"exthdr_type":"mh","offset":2,"len":16}]}}]}
diff --git a/tests/jsonfiles/26-rule-immediate.json b/tests/jsonfiles/26-rule-immediate.json
index fbe7f8b..3582a39 100644
--- a/tests/jsonfiles/26-rule-immediate.json
+++ b/tests/jsonfiles/26-rule-immediate.json
@@ -1 +1 @@
-{"rule":{"family":"ip","table":"filter","chain":"input","handle":26,"expr":[{"type":"immediate","dreg":0,"immediatedata":{"data_reg":{"type":"verdict","verdict":"accept"}}}]}}
+{"nftables":[{"rule":{"family":"ip","table":"filter","chain":"input","handle":26,"expr":[{"type":"immediate","dreg":0,"immediatedata":{"data_reg":{"type":"verdict","verdict":"accept"}}}]}}]}
diff --git a/tests/jsonfiles/27-rule-limit.json b/tests/jsonfiles/27-rule-limit.json
index 3ac5118..c268357 100644
--- a/tests/jsonfiles/27-rule-limit.json
+++ b/tests/jsonfiles/27-rule-limit.json
@@ -1 +1 @@
-{"rule":{"family":"ip","table":"filter","chain":"input","handle":27,"expr":[{"type":"limit","rate":321321,"unit":0}]}}
+{"nftables":[{"rule":{"family":"ip","table":"filter","chain":"input","handle":27,"expr":[{"type":"limit","rate":321321,"unit":0}]}}]}
diff --git a/tests/jsonfiles/28-rule-log.json b/tests/jsonfiles/28-rule-log.json
index ad0ca8f..1e739f1 100644
--- a/tests/jsonfiles/28-rule-log.json
+++ b/tests/jsonfiles/28-rule-log.json
@@ -1 +1 @@
-{"rule":{"family":"ip","table":"filter","chain":"input","handle":28,"expr":[{"type":"log","prefix":"test_chain","group":1,"snaplen":0,"qthreshold":0}]}}
+{"nftables":[{"rule":{"family":"ip","table":"filter","chain":"input","handle":28,"expr":[{"type":"log","prefix":"test_chain","group":1,"snaplen":0,"qthreshold":0}]}}]}
diff --git a/tests/jsonfiles/29-rule-match.json b/tests/jsonfiles/29-rule-match.json
index 78f087d..b533e77 100644
--- a/tests/jsonfiles/29-rule-match.json
+++ b/tests/jsonfiles/29-rule-match.json
@@ -1 +1 @@
-{"rule":{"family":"ip","table":"filter","chain":"input","handle":9,"expr":[{"type":"match","name":"state"},{"type":"counter","pkts":0,"bytes":0}]}}
+{"nftables":[{"rule":{"family":"ip","table":"filter","chain":"input","handle":9,"expr":[{"type":"match","name":"state"},{"type":"counter","pkts":0,"bytes":0}]}}]}
diff --git a/tests/jsonfiles/30-rule-lookup.json b/tests/jsonfiles/30-rule-lookup.json
index 5dbf823..05576b0 100644
--- a/tests/jsonfiles/30-rule-lookup.json
+++ b/tests/jsonfiles/30-rule-lookup.json
@@ -1 +1 @@
-{"rule":{"family":"ip","table":"filter","chain":"input","handle":8,"expr":[{"type":"payload","dreg":1,"offset":12,"len":4,"base":"network"},{"type":"lookup","set":"set0","sreg":1,"dreg":0}]}}
+{"nftables":[{"rule":{"family":"ip","table":"filter","chain":"input","handle":8,"expr":[{"type":"payload","dreg":1,"offset":12,"len":4,"base":"network"},{"type":"lookup","set":"set0","sreg":1,"dreg":0}]}}]}
diff --git a/tests/jsonfiles/31-rule-meta.json b/tests/jsonfiles/31-rule-meta.json
index b52d29e..96e02e5 100644
--- a/tests/jsonfiles/31-rule-meta.json
+++ b/tests/jsonfiles/31-rule-meta.json
@@ -1 +1 @@
-{"rule":{"family":"ip","table":"filter","chain":"output","handle":8,"expr":[{"type":"meta","dreg":1,"key":"protocol"},{"type":"cmp","sreg":1,"op":"eq","cmpdata":{"data_reg":{"type":"value","len":4,"data0":"0x000003e8"}}},{"type":"counter","pkts":0,"bytes":0}]}}
+{"nftables":[{"rule":{"family":"ip","table":"filter","chain":"output","handle":8,"expr":[{"type":"meta","dreg":1,"key":"protocol"},{"type":"cmp","sreg":1,"op":"eq","cmpdata":{"data_reg":{"type":"value","len":4,"data0":"0x000003e8"}}},{"type":"counter","pkts":0,"bytes":0}]}}]}
diff --git a/tests/jsonfiles/32-rule-nat4.json b/tests/jsonfiles/32-rule-nat4.json
index eb3ae5b..aa2b50d 100644
--- a/tests/jsonfiles/32-rule-nat4.json
+++ b/tests/jsonfiles/32-rule-nat4.json
@@ -1 +1 @@
-{"rule":{"family":"ip","table":"filter","chain":"input","handle":10,"expr":[{"type":"nat","nat_type":"dnat","family":"ip","sreg_addr_min":1,"sreg_addr_max":2,"sreg_proto_min":3,"sreg_proto_max":4}]}}
+{"nftables":[{"rule":{"family":"ip","table":"filter","chain":"input","handle":10,"expr":[{"type":"nat","nat_type":"dnat","family":"ip","sreg_addr_min":1,"sreg_addr_max":2,"sreg_proto_min":3,"sreg_proto_max":4}]}}]}
diff --git a/tests/jsonfiles/33-rule-nat6.json b/tests/jsonfiles/33-rule-nat6.json
index fae48d0..e5d8c8f 100644
--- a/tests/jsonfiles/33-rule-nat6.json
+++ b/tests/jsonfiles/33-rule-nat6.json
@@ -1 +1 @@
-{"rule":{"family":"ip6","table":"nat","chain":"output","handle":33,"expr":[{"type":"nat","nat_type":"snat","family":"ip6","sreg_addr_min":1,"sreg_addr_max":2,"sreg_proto_min":3,"sreg_proto_max":4}]}}
+{"nftables":[{"rule":{"family":"ip6","table":"nat","chain":"output","handle":33,"expr":[{"type":"nat","nat_type":"snat","family":"ip6","sreg_addr_min":1,"sreg_addr_max":2,"sreg_proto_min":3,"sreg_proto_max":4}]}}]}
diff --git a/tests/jsonfiles/34-rule-payload.json b/tests/jsonfiles/34-rule-payload.json
index 3559ca6..7eaff41 100644
--- a/tests/jsonfiles/34-rule-payload.json
+++ b/tests/jsonfiles/34-rule-payload.json
@@ -1 +1 @@
-{"rule":{"family":"ip","table":"filter","chain":"input","handle":26,"expr":[{"type":"payload","dreg":1,"offset":9,"len":1,"base":"network"},{"type":"cmp","sreg":1,"op":"eq","cmpdata":{"data_reg":{"type":"value","len":1,"data0":"0x00000006"}}},{"type":"payload","dreg":1,"offset":2,"len":2,"base":"transport"},{"type":"cmp","sreg":1,"op":"eq","cmpdata":{"data_reg":{"type":"value","len":2,"data0":"0x00001600"}}},{"type":"immediate","dreg":0,"immediatedata":{"data_reg":{"type":"verdict","verdict":"accept"}}}]}}
+{"nftables":[{"rule":{"family":"ip","table":"filter","chain":"input","handle":26,"expr":[{"type":"payload","dreg":1,"offset":9,"len":1,"base":"network"},{"type":"cmp","sreg":1,"op":"eq","cmpdata":{"data_reg":{"type":"value","len":1,"data0":"0x00000006"}}},{"type":"payload","dreg":1,"offset":2,"len":2,"base":"transport"},{"type":"cmp","sreg":1,"op":"eq","cmpdata":{"data_reg":{"type":"value","len":2,"data0":"0x00001600"}}},{"type":"immediate","dreg":0,"immediatedata":{"data_reg":{"type":"verdict","verdict":"accept"}}}]}}]}
diff --git a/tests/jsonfiles/35-rule-target.json b/tests/jsonfiles/35-rule-target.json
index c8ff656..da02921 100644
--- a/tests/jsonfiles/35-rule-target.json
+++ b/tests/jsonfiles/35-rule-target.json
@@ -1 +1 @@
-{"rule":{"family":"ip","table":"filter","chain":"INPUT","handle":20,"expr":[{"type":"counter","pkts":17,"bytes":4436},{"type":"target","name":"LOG"}]}}
+{"nftables":[{"rule":{"family":"ip","table":"filter","chain":"INPUT","handle":20,"expr":[{"type":"counter","pkts":17,"bytes":4436},{"type":"target","name":"LOG"}]}}]}
diff --git a/tests/jsonfiles/36-rule-real.json b/tests/jsonfiles/36-rule-real.json
index c8bfc26..4c5e331 100644
--- a/tests/jsonfiles/36-rule-real.json
+++ b/tests/jsonfiles/36-rule-real.json
@@ -1 +1 @@
-{"rule":{"family":"ip","table":"filter","chain":"output","handle":36,"expr":[{"type":"payload","dreg":1,"offset":12,"len":8,"base":"link"},{"type":"cmp","sreg":1,"op":"eq","cmpdata":{"data_reg":{"type":"value","len":8,"data0":"0x0100a8c0","data1":"0x6400a8c0"}}},{"type":"counter","pkts":0,"bytes":0}]}}
+{"nftables":[{"rule":{"family":"ip","table":"filter","chain":"output","handle":36,"expr":[{"type":"payload","dreg":1,"offset":12,"len":8,"base":"link"},{"type":"cmp","sreg":1,"op":"eq","cmpdata":{"data_reg":{"type":"value","len":8,"data0":"0x0100a8c0","data1":"0x6400a8c0"}}},{"type":"counter","pkts":0,"bytes":0}]}}]}
diff --git a/tests/jsonfiles/37-rule-real.json b/tests/jsonfiles/37-rule-real.json
index d9b4580..2645328 100644
--- a/tests/jsonfiles/37-rule-real.json
+++ b/tests/jsonfiles/37-rule-real.json
@@ -1 +1 @@
-{"rule":{"family":"ip","table":"filter","chain":"output","handle":37,"expr":[{"type":"payload","dreg":1,"offset":16,"len":4,"base":"link"},{"type":"cmp","sreg":1,"op":"eq","cmpdata":{"data_reg":{"type":"value","len":4,"data0":"0x0100a8c0"}}}]}}
+{"nftables":[{"rule":{"family":"ip","table":"filter","chain":"output","handle":37,"expr":[{"type":"payload","dreg":1,"offset":16,"len":4,"base":"link"},{"type":"cmp","sreg":1,"op":"eq","cmpdata":{"data_reg":{"type":"value","len":4,"data0":"0x0100a8c0"}}}]}}]}
diff --git a/tests/jsonfiles/38-rule-real.json b/tests/jsonfiles/38-rule-real.json
index ce37407..2a7640b 100644
--- a/tests/jsonfiles/38-rule-real.json
+++ b/tests/jsonfiles/38-rule-real.json
@@ -1 +1 @@
-{"rule":{"family":"ip","table":"filter","chain":"output","handle":38,"expr":[{"type":"payload","dreg":1,"offset":16,"len":4,"base":"link"},{"type":"cmp","sreg":1,"op":"eq","cmpdata":{"data_reg":{"type":"value","len":4,"data0":"0x0100a8c0"}}}]}}
+{"nftables":[{"rule":{"family":"ip","table":"filter","chain":"output","handle":38,"expr":[{"type":"payload","dreg":1,"offset":16,"len":4,"base":"link"},{"type":"cmp","sreg":1,"op":"eq","cmpdata":{"data_reg":{"type":"value","len":4,"data0":"0x0100a8c0"}}}]}}]}
diff --git a/tests/jsonfiles/39-rule-real.json b/tests/jsonfiles/39-rule-real.json
index 8529d06..5ab4fae 100644
--- a/tests/jsonfiles/39-rule-real.json
+++ b/tests/jsonfiles/39-rule-real.json
@@ -1 +1 @@
-{"rule":{"family":"ip","table":"filter","chain":"output","handle":39,"expr":[{"type":"payload","dreg":1,"offset":16,"len":4,"base":"link"},{"type":"cmp","sreg":1,"op":"gte","cmpdata":{"data_reg":{"type":"value","len":4,"data0":"0x0100a8c0"}}},{"type":"cmp","sreg":1,"op":"lte","cmpdata":{"data_reg":{"type":"value","len":4,"data0":"0xfa00a8c0"}}}]}}
+{"nftables":[{"rule":{"family":"ip","table":"filter","chain":"output","handle":39,"expr":[{"type":"payload","dreg":1,"offset":16,"len":4,"base":"link"},{"type":"cmp","sreg":1,"op":"gte","cmpdata":{"data_reg":{"type":"value","len":4,"data0":"0x0100a8c0"}}},{"type":"cmp","sreg":1,"op":"lte","cmpdata":{"data_reg":{"type":"value","len":4,"data0":"0xfa00a8c0"}}}]}}]}
diff --git a/tests/jsonfiles/40-rule-real.json b/tests/jsonfiles/40-rule-real.json
index f13c99e..483a1a5 100644
--- a/tests/jsonfiles/40-rule-real.json
+++ b/tests/jsonfiles/40-rule-real.json
@@ -1 +1 @@
-{"rule":{"family":"ip","table":"filter","chain":"output","handle":40,"expr":[{"type":"payload","dreg":1,"offset":16,"len":4,"base":"link"},{"type":"cmp","sreg":1,"op":"eq","cmpdata":{"data_reg":{"type":"value","len":4,"data0":"0x0100a8c0"}}},{"type":"counter","pkts":0,"bytes":0}]}}
+{"nftables":[{"rule":{"family":"ip","table":"filter","chain":"output","handle":40,"expr":[{"type":"payload","dreg":1,"offset":16,"len":4,"base":"link"},{"type":"cmp","sreg":1,"op":"eq","cmpdata":{"data_reg":{"type":"value","len":4,"data0":"0x0100a8c0"}}},{"type":"counter","pkts":0,"bytes":0}]}}]}
diff --git a/tests/jsonfiles/41-rule-real.json b/tests/jsonfiles/41-rule-real.json
index ed23fc2..d8ed85c 100644
--- a/tests/jsonfiles/41-rule-real.json
+++ b/tests/jsonfiles/41-rule-real.json
@@ -1 +1 @@
-{"rule":{"family":"ip","table":"filter","chain":"output","handle":41,"expr":[{"type":"payload","dreg":1,"offset":16,"len":4,"base":"link"},{"type":"cmp","sreg":1,"op":"eq","cmpdata":{"data_reg":{"type":"value","len":4,"data0":"0x0100a8c0"}}},{"type":"counter","pkts":0,"bytes":0},{"type":"immediate","dreg":0,"immediatedata":{"data_reg":{"type":"verdict","verdict":"drop"}}}]}}
+{"nftables":[{"rule":{"family":"ip","table":"filter","chain":"output","handle":41,"expr":[{"type":"payload","dreg":1,"offset":16,"len":4,"base":"link"},{"type":"cmp","sreg":1,"op":"eq","cmpdata":{"data_reg":{"type":"value","len":4,"data0":"0x0100a8c0"}}},{"type":"counter","pkts":0,"bytes":0},{"type":"immediate","dreg":0,"immediatedata":{"data_reg":{"type":"verdict","verdict":"drop"}}}]}}]}
diff --git a/tests/jsonfiles/42-rule-real.json b/tests/jsonfiles/42-rule-real.json
index 6c305e1..49f9b56 100644
--- a/tests/jsonfiles/42-rule-real.json
+++ b/tests/jsonfiles/42-rule-real.json
@@ -1 +1 @@
-{"rule":{"family":"ip","table":"filter","chain":"output","handle":42,"expr":[{"type":"payload","dreg":1,"offset":16,"len":4,"base":"link"},{"type":"cmp","sreg":1,"op":"eq","cmpdata":{"data_reg":{"type":"value","len":4,"data0":"0x0100a8c0"}}},{"type":"counter","pkts":0,"bytes":0},{"type":"log","prefix":"(null)","group":0,"snaplen":0,"qthreshold":0}]}}
+{"nftables":[{"rule":{"family":"ip","table":"filter","chain":"output","handle":42,"expr":[{"type":"payload","dreg":1,"offset":16,"len":4,"base":"link"},{"type":"cmp","sreg":1,"op":"eq","cmpdata":{"data_reg":{"type":"value","len":4,"data0":"0x0100a8c0"}}},{"type":"counter","pkts":0,"bytes":0},{"type":"log","prefix":"(null)","group":0,"snaplen":0,"qthreshold":0}]}}]}
diff --git a/tests/jsonfiles/43-rule-real.json b/tests/jsonfiles/43-rule-real.json
index 95d0333..be2c6fb 100644
--- a/tests/jsonfiles/43-rule-real.json
+++ b/tests/jsonfiles/43-rule-real.json
@@ -1 +1 @@
-{"rule":{"family":"ip","table":"filter","chain":"output","handle":43,"expr":[{"type":"payload","dreg":1,"offset":9,"len":1,"base":"link"},{"type":"cmp","sreg":1,"op":"eq","cmpdata":{"data_reg":{"type":"value","len":1,"data0":"0x00000006"}}},{"type":"payload","dreg":1,"offset":2,"len":2,"base":"link"},{"type":"cmp","sreg":1,"op":"eq","cmpdata":{"data_reg":{"type":"value","len":2,"data0":"0x00001600"}}},{"type":"counter","pkts":0,"bytes":0}]}}
+{"nftables":[{"rule":{"family":"ip","table":"filter","chain":"output","handle":43,"expr":[{"type":"payload","dreg":1,"offset":9,"len":1,"base":"link"},{"type":"cmp","sreg":1,"op":"eq","cmpdata":{"data_reg":{"type":"value","len":1,"data0":"0x00000006"}}},{"type":"payload","dreg":1,"offset":2,"len":2,"base":"link"},{"type":"cmp","sreg":1,"op":"eq","cmpdata":{"data_reg":{"type":"value","len":2,"data0":"0x00001600"}}},{"type":"counter","pkts":0,"bytes":0}]}}]}
diff --git a/tests/jsonfiles/44-rule-real.json b/tests/jsonfiles/44-rule-real.json
index a838dbb..890e529 100644
--- a/tests/jsonfiles/44-rule-real.json
+++ b/tests/jsonfiles/44-rule-real.json
@@ -1 +1 @@
-{"rule":{"family":"ip","table":"filter","chain":"output","handle":44,"expr":[{"type":"payload","dreg":1,"offset":9,"len":1,"base":"link"},{"type":"cmp","sreg":1,"op":"eq","cmpdata":{"data_reg":{"type":"value","len":1,"data0":"0x00000006"}}},{"type":"payload","dreg":1,"offset":0,"len":4,"base":"link"},{"type":"cmp","sreg":1,"op":"eq","cmpdata":{"data_reg":{"type":"value","len":4,"data0":"0x16000004"}}},{"type":"counter","pkts":0,"bytes":0}]}}
+{"nftables":[{"rule":{"family":"ip","table":"filter","chain":"output","handle":44,"expr":[{"type":"payload","dreg":1,"offset":9,"len":1,"base":"link"},{"type":"cmp","sreg":1,"op":"eq","cmpdata":{"data_reg":{"type":"value","len":1,"data0":"0x00000006"}}},{"type":"payload","dreg":1,"offset":0,"len":4,"base":"link"},{"type":"cmp","sreg":1,"op":"eq","cmpdata":{"data_reg":{"type":"value","len":4,"data0":"0x16000004"}}},{"type":"counter","pkts":0,"bytes":0}]}}]}
diff --git a/tests/jsonfiles/45-rule-real.json b/tests/jsonfiles/45-rule-real.json
index 8b143d6..ed61093 100644
--- a/tests/jsonfiles/45-rule-real.json
+++ b/tests/jsonfiles/45-rule-real.json
@@ -1 +1 @@
-{"rule":{"family":"ip","table":"filter","chain":"output","handle":45,"expr":[{"type":"payload","dreg":1,"offset":12,"len":8,"base":"link"},{"type":"cmp","sreg":1,"op":"eq","cmpdata":{"data_reg":{"type":"value","len":8,"data0":"0x0100a8c0","data1":"0x6400a8c0"}}},{"type":"counter","pkts":0,"bytes":0}]}}
+{"nftables":[{"rule":{"family":"ip","table":"filter","chain":"output","handle":45,"expr":[{"type":"payload","dreg":1,"offset":12,"len":8,"base":"link"},{"type":"cmp","sreg":1,"op":"eq","cmpdata":{"data_reg":{"type":"value","len":8,"data0":"0x0100a8c0","data1":"0x6400a8c0"}}},{"type":"counter","pkts":0,"bytes":0}]}}]}
diff --git a/tests/jsonfiles/46-rule-real.json b/tests/jsonfiles/46-rule-real.json
index 28643c8..ed2431e 100644
--- a/tests/jsonfiles/46-rule-real.json
+++ b/tests/jsonfiles/46-rule-real.json
@@ -1 +1 @@
-{"rule":{"family":"ip","table":"filter","chain":"output","handle":46,"expr":[{"type":"payload","dreg":1,"offset":9,"len":1,"base":"link"},{"type":"cmp","sreg":1,"op":"eq","cmpdata":{"data_reg":{"type":"value","len":1,"data0":"0x00000006"}}},{"type":"payload","dreg":1,"offset":0,"len":8,"base":"link"},{"type":"cmp","sreg":1,"op":"eq","cmpdata":{"data_reg":{"type":"value","len":8,"data0":"0x16000004","data1":"0x00000000"}}}]}}
+{"nftables":[{"rule":{"family":"ip","table":"filter","chain":"output","handle":46,"expr":[{"type":"payload","dreg":1,"offset":9,"len":1,"base":"link"},{"type":"cmp","sreg":1,"op":"eq","cmpdata":{"data_reg":{"type":"value","len":1,"data0":"0x00000006"}}},{"type":"payload","dreg":1,"offset":0,"len":8,"base":"link"},{"type":"cmp","sreg":1,"op":"eq","cmpdata":{"data_reg":{"type":"value","len":8,"data0":"0x16000004","data1":"0x00000000"}}}]}}]}
diff --git a/tests/jsonfiles/47-rule-real.json b/tests/jsonfiles/47-rule-real.json
index 8f68634..828e3ef 100644
--- a/tests/jsonfiles/47-rule-real.json
+++ b/tests/jsonfiles/47-rule-real.json
@@ -1 +1 @@
-{"rule":{"family":"ip","table":"filter","chain":"output","handle":47,"expr":[{"type":"payload","dreg":1,"offset":9,"len":1,"base":"link"},{"type":"cmp","sreg":1,"op":"eq","cmpdata":{"data_reg":{"type":"value","len":1,"data0":"0x00000006"}}},{"type":"payload","dreg":1,"offset":0,"len":8,"base":"link"},{"type":"cmp","sreg":1,"op":"eq","cmpdata":{"data_reg":{"type":"value","len":8,"data0":"0x16000004","data1":"0x00000000"}}}]}}
+{"nftables":[{"rule":{"family":"ip","table":"filter","chain":"output","handle":47,"expr":[{"type":"payload","dreg":1,"offset":9,"len":1,"base":"link"},{"type":"cmp","sreg":1,"op":"eq","cmpdata":{"data_reg":{"type":"value","len":1,"data0":"0x00000006"}}},{"type":"payload","dreg":1,"offset":0,"len":8,"base":"link"},{"type":"cmp","sreg":1,"op":"eq","cmpdata":{"data_reg":{"type":"value","len":8,"data0":"0x16000004","data1":"0x00000000"}}}]}}]}
diff --git a/tests/jsonfiles/48-rule-real.json b/tests/jsonfiles/48-rule-real.json
index 0cd835e..7f08637 100644
--- a/tests/jsonfiles/48-rule-real.json
+++ b/tests/jsonfiles/48-rule-real.json
@@ -1 +1 @@
-{"rule":{"family":"ip","table":"filter","chain":"output","handle":48,"expr":[{"type":"meta","dreg":1,"key":"len"},{"type":"cmp","sreg":1,"op":"eq","cmpdata":{"data_reg":{"type":"value","len":4,"data0":"0x000003e8"}}},{"type":"counter","pkts":0,"bytes":0}]}}
+{"nftables":[{"rule":{"family":"ip","table":"filter","chain":"output","handle":48,"expr":[{"type":"meta","dreg":1,"key":"len"},{"type":"cmp","sreg":1,"op":"eq","cmpdata":{"data_reg":{"type":"value","len":4,"data0":"0x000003e8"}}},{"type":"counter","pkts":0,"bytes":0}]}}]}
diff --git a/tests/jsonfiles/49-rule-real.json b/tests/jsonfiles/49-rule-real.json
index 445f46a..26f2672 100644
--- a/tests/jsonfiles/49-rule-real.json
+++ b/tests/jsonfiles/49-rule-real.json
@@ -1 +1 @@
-{"rule":{"family":"ip","table":"filter","chain":"output","handle":49,"expr":[{"type":"meta","dreg":1,"key":"mark"},{"type":"cmp","sreg":1,"op":"eq","cmpdata":{"data_reg":{"type":"value","len":4,"data0":"0x00000000"}}},{"type":"counter","pkts":55,"bytes":11407}]}}
+{"nftables":[{"rule":{"family":"ip","table":"filter","chain":"output","handle":49,"expr":[{"type":"meta","dreg":1,"key":"mark"},{"type":"cmp","sreg":1,"op":"eq","cmpdata":{"data_reg":{"type":"value","len":4,"data0":"0x00000000"}}},{"type":"counter","pkts":55,"bytes":11407}]}}]}
diff --git a/tests/jsonfiles/50-rule-real.json b/tests/jsonfiles/50-rule-real.json
index 2722236..b63d722 100644
--- a/tests/jsonfiles/50-rule-real.json
+++ b/tests/jsonfiles/50-rule-real.json
@@ -1 +1 @@
-{"rule":{"family":"ip","table":"filter","chain":"output","handle":50,"expr":[{"type":"meta","dreg":1,"key":"iif"},{"type":"cmp","sreg":1,"op":"eq","cmpdata":{"data_reg":{"type":"value","len":4,"data0":"0x00000001"}}},{"type":"counter","pkts":0,"bytes":0}]}}
+{"nftables":[{"rule":{"family":"ip","table":"filter","chain":"output","handle":50,"expr":[{"type":"meta","dreg":1,"key":"iif"},{"type":"cmp","sreg":1,"op":"eq","cmpdata":{"data_reg":{"type":"value","len":4,"data0":"0x00000001"}}},{"type":"counter","pkts":0,"bytes":0}]}}]}
diff --git a/tests/jsonfiles/51-rule-real.json b/tests/jsonfiles/51-rule-real.json
index 3161fa4..441716e 100644
--- a/tests/jsonfiles/51-rule-real.json
+++ b/tests/jsonfiles/51-rule-real.json
@@ -1 +1 @@
-{"rule":{"family":"ip","table":"filter","chain":"output","handle":51,"expr":[{"type":"meta","dreg":1,"key":"iifname"},{"type":"cmp","sreg":1,"op":"eq","cmpdata":{"data_reg":{"type":"value","len":16,"data0":"0x00000000","data1":"0x00000000","data2":"0x65000000","data3":"0x00306874"}}},{"type":"counter","pkts":0,"bytes":0}]}}
+{"nftables":[{"rule":{"family":"ip","table":"filter","chain":"output","handle":51,"expr":[{"type":"meta","dreg":1,"key":"iifname"},{"type":"cmp","sreg":1,"op":"eq","cmpdata":{"data_reg":{"type":"value","len":16,"data0":"0x00000000","data1":"0x00000000","data2":"0x65000000","data3":"0x00306874"}}},{"type":"counter","pkts":0,"bytes":0}]}}]}
diff --git a/tests/jsonfiles/52-rule-real.json b/tests/jsonfiles/52-rule-real.json
index d4092c6..baec217 100644
--- a/tests/jsonfiles/52-rule-real.json
+++ b/tests/jsonfiles/52-rule-real.json
@@ -1 +1 @@
-{"rule":{"family":"ip","table":"filter","chain":"output","handle":52,"expr":[{"type":"meta","dreg":1,"key":"oif"},{"type":"cmp","sreg":1,"op":"eq","cmpdata":{"data_reg":{"type":"value","len":4,"data0":"0x00000001"}}},{"type":"counter","pkts":0,"bytes":0}]}}
+{"nftables":[{"rule":{"family":"ip","table":"filter","chain":"output","handle":52,"expr":[{"type":"meta","dreg":1,"key":"oif"},{"type":"cmp","sreg":1,"op":"eq","cmpdata":{"data_reg":{"type":"value","len":4,"data0":"0x00000001"}}},{"type":"counter","pkts":0,"bytes":0}]}}]}
diff --git a/tests/jsonfiles/53-rule-real.json b/tests/jsonfiles/53-rule-real.json
index 526c9d3..bb28dea 100644
--- a/tests/jsonfiles/53-rule-real.json
+++ b/tests/jsonfiles/53-rule-real.json
@@ -1 +1 @@
-{"rule":{"family":"ip","table":"filter","chain":"output","handle":53,"expr":[{"type":"meta","dreg":1,"key":"oifname"},{"type":"cmp","sreg":1,"op":"eq","cmpdata":{"data_reg":{"type":"value","len":16,"data0":"0x00000000","data1":"0x00000000","data2":"0x65000000","data3":"0x00306874"}}},{"type":"counter","pkts":0,"bytes":0}]}}
+{"nftables":[{"rule":{"family":"ip","table":"filter","chain":"output","handle":53,"expr":[{"type":"meta","dreg":1,"key":"oifname"},{"type":"cmp","sreg":1,"op":"eq","cmpdata":{"data_reg":{"type":"value","len":16,"data0":"0x00000000","data1":"0x00000000","data2":"0x65000000","data3":"0x00306874"}}},{"type":"counter","pkts":0,"bytes":0}]}}]}
diff --git a/tests/jsonfiles/54-rule-real.json b/tests/jsonfiles/54-rule-real.json
index edb8c18..ae3b6e8 100644
--- a/tests/jsonfiles/54-rule-real.json
+++ b/tests/jsonfiles/54-rule-real.json
@@ -1 +1 @@
-{"rule":{"family":"ip","table":"filter","chain":"output","handle":54,"expr":[{"type":"meta","dreg":1,"key":"skuid"},{"type":"cmp","sreg":1,"op":"eq","cmpdata":{"data_reg":{"type":"value","len":4,"data0":"0x000003e8"}}},{"type":"counter","pkts":0,"bytes":0}]}}
+{"nftables":[{"rule":{"family":"ip","table":"filter","chain":"output","handle":54,"expr":[{"type":"meta","dreg":1,"key":"skuid"},{"type":"cmp","sreg":1,"op":"eq","cmpdata":{"data_reg":{"type":"value","len":4,"data0":"0x000003e8"}}},{"type":"counter","pkts":0,"bytes":0}]}}]}
diff --git a/tests/jsonfiles/55-rule-real.json b/tests/jsonfiles/55-rule-real.json
index a10fc0f..69febc0 100644
--- a/tests/jsonfiles/55-rule-real.json
+++ b/tests/jsonfiles/55-rule-real.json
@@ -1 +1 @@
-{"rule":{"family":"ip","table":"filter","chain":"output","handle":55,"expr":[{"type":"meta","dreg":1,"key":"skgid"},{"type":"cmp","sreg":1,"op":"eq","cmpdata":{"data_reg":{"type":"value","len":4,"data0":"0x000003e8"}}},{"type":"counter","pkts":0,"bytes":0}]}}
+{"nftables":[{"rule":{"family":"ip","table":"filter","chain":"output","handle":55,"expr":[{"type":"meta","dreg":1,"key":"skgid"},{"type":"cmp","sreg":1,"op":"eq","cmpdata":{"data_reg":{"type":"value","len":4,"data0":"0x000003e8"}}},{"type":"counter","pkts":0,"bytes":0}]}}]}
diff --git a/tests/jsonfiles/56-rule-real.json b/tests/jsonfiles/56-rule-real.json
index 137e146..6f5f4c5 100644
--- a/tests/jsonfiles/56-rule-real.json
+++ b/tests/jsonfiles/56-rule-real.json
@@ -1 +1 @@
-{"rule":{"family":"ip","table":"filter","chain":"output","handle":56,"expr":[{"type":"meta","dreg":1,"key":"secmark"},{"type":"cmp","sreg":1,"op":"eq","cmpdata":{"data_reg":{"type":"value","len":4,"data0":"0x00000000"}}},{"type":"counter","pkts":55,"bytes":11407}]}}
+{"nftables":[{"rule":{"family":"ip","table":"filter","chain":"output","handle":56,"expr":[{"type":"meta","dreg":1,"key":"secmark"},{"type":"cmp","sreg":1,"op":"eq","cmpdata":{"data_reg":{"type":"value","len":4,"data0":"0x00000000"}}},{"type":"counter","pkts":55,"bytes":11407}]}}]}
diff --git a/tests/jsonfiles/57-rule-real.json b/tests/jsonfiles/57-rule-real.json
index 8694ea1..da17f64 100644
--- a/tests/jsonfiles/57-rule-real.json
+++ b/tests/jsonfiles/57-rule-real.json
@@ -1 +1 @@
-{"rule":{"family":"ip","table":"filter","chain":"output","handle":57,"expr":[{"type":"meta","dreg":1,"key":"len"},{"type":"cmp","sreg":1,"op":"eq","cmpdata":{"data_reg":{"type":"value","len":4,"data0":"0x000003e8"}}},{"type":"counter","pkts":0,"bytes":0}]}}
+{"nftables":[{"rule":{"family":"ip","table":"filter","chain":"output","handle":57,"expr":[{"type":"meta","dreg":1,"key":"len"},{"type":"cmp","sreg":1,"op":"eq","cmpdata":{"data_reg":{"type":"value","len":4,"data0":"0x000003e8"}}},{"type":"counter","pkts":0,"bytes":0}]}}]}
diff --git a/tests/jsonfiles/58-rule-real.json b/tests/jsonfiles/58-rule-real.json
index 59237b6..52532f1 100644
--- a/tests/jsonfiles/58-rule-real.json
+++ b/tests/jsonfiles/58-rule-real.json
@@ -1 +1 @@
-{"rule":{"family":"ip","table":"filter","chain":"output","handle":58,"expr":[{"type":"meta","dreg":1,"key":"protocol"},{"type":"cmp","sreg":1,"op":"eq","cmpdata":{"data_reg":{"type":"value","len":2,"data0":"0x00000008"}}},{"type":"counter","pkts":55,"bytes":11407}]}}
+{"nftables":[{"rule":{"family":"ip","table":"filter","chain":"output","handle":58,"expr":[{"type":"meta","dreg":1,"key":"protocol"},{"type":"cmp","sreg":1,"op":"eq","cmpdata":{"data_reg":{"type":"value","len":2,"data0":"0x00000008"}}},{"type":"counter","pkts":55,"bytes":11407}]}}]}
diff --git a/tests/jsonfiles/59-rule-real.json b/tests/jsonfiles/59-rule-real.json
index d6245b2..aa632d3 100644
--- a/tests/jsonfiles/59-rule-real.json
+++ b/tests/jsonfiles/59-rule-real.json
@@ -1 +1 @@
-{"rule":{"family":"ip","table":"filter","chain":"output","handle":59,"expr":[{"type":"meta","dreg":1,"key":"mark"},{"type":"cmp","sreg":1,"op":"eq","cmpdata":{"data_reg":{"type":"value","len":4,"data0":"0x00000000"}}},{"type":"counter","pkts":55,"bytes":11407}]}}
+{"nftables":[{"rule":{"family":"ip","table":"filter","chain":"output","handle":59,"expr":[{"type":"meta","dreg":1,"key":"mark"},{"type":"cmp","sreg":1,"op":"eq","cmpdata":{"data_reg":{"type":"value","len":4,"data0":"0x00000000"}}},{"type":"counter","pkts":55,"bytes":11407}]}}]}
diff --git a/tests/jsonfiles/60-rule-real.json b/tests/jsonfiles/60-rule-real.json
index 54d5288..4b58efd 100644
--- a/tests/jsonfiles/60-rule-real.json
+++ b/tests/jsonfiles/60-rule-real.json
@@ -1 +1 @@
-{"rule":{"family":"ip","table":"filter","chain":"output","handle":60,"expr":[{"type":"meta","dreg":1,"key":"iif"},{"type":"cmp","sreg":1,"op":"eq","cmpdata":{"data_reg":{"type":"value","len":4,"data0":"0x00000001"}}},{"type":"counter","pkts":0,"bytes":0}]}}
+{"nftables":[{"rule":{"family":"ip","table":"filter","chain":"output","handle":60,"expr":[{"type":"meta","dreg":1,"key":"iif"},{"type":"cmp","sreg":1,"op":"eq","cmpdata":{"data_reg":{"type":"value","len":4,"data0":"0x00000001"}}},{"type":"counter","pkts":0,"bytes":0}]}}]}
diff --git a/tests/jsonfiles/61-rule-real.json b/tests/jsonfiles/61-rule-real.json
index 3942c3f..c6acf03 100644
--- a/tests/jsonfiles/61-rule-real.json
+++ b/tests/jsonfiles/61-rule-real.json
@@ -1 +1 @@
-{"rule":{"family":"ip","table":"filter","chain":"output","handle":61,"expr":[{"type":"meta","dreg":1,"key":"iifname"},{"type":"cmp","sreg":1,"op":"eq","cmpdata":{"data_reg":{"type":"value","len":16,"data0":"0x00000000","data1":"0x00000000","data2":"0x65000000","data3":"0x00306874"}}},{"type":"counter","pkts":0,"bytes":0}]}}
+{"nftables":[{"rule":{"family":"ip","table":"filter","chain":"output","handle":61,"expr":[{"type":"meta","dreg":1,"key":"iifname"},{"type":"cmp","sreg":1,"op":"eq","cmpdata":{"data_reg":{"type":"value","len":16,"data0":"0x00000000","data1":"0x00000000","data2":"0x65000000","data3":"0x00306874"}}},{"type":"counter","pkts":0,"bytes":0}]}}]}
diff --git a/tests/jsonfiles/62-set.json b/tests/jsonfiles/62-set.json
index 0e52f70..8a8d99c 100644
--- a/tests/jsonfiles/62-set.json
+++ b/tests/jsonfiles/62-set.json
@@ -1 +1 @@
-{"set":{"name":"set0","table":"filter","flags":3,"family":"ip","key_type":12,"key_len":2,"set_elem":[{"flags":0,"key":{"data_reg":{"type":"value","len":2,"data0":"0x00001700"}}},{"flags":0,"key":{"data_reg":{"type":"value","len":2,"data0":"0x00001600"}}}]}}
+{"nftables":[{"set":{"name":"set0","table":"filter","flags":3,"family":"ip","key_type":12,"key_len":2,"set_elem":[{"flags":0,"key":{"data_reg":{"type":"value","len":2,"data0":"0x00001700"}}},{"flags":0,"key":{"data_reg":{"type":"value","len":2,"data0":"0x00001600"}}}]}}]}
diff --git a/tests/jsonfiles/63-set.json b/tests/jsonfiles/63-set.json
index 90afec3..62ccd2f 100644
--- a/tests/jsonfiles/63-set.json
+++ b/tests/jsonfiles/63-set.json
@@ -1 +1 @@
-{"set":{"name":"map0","table":"filter","flags":11,"family":"ip","key_type":12,"key_len":2,"data_type":4294967040,"data_len":16,"set_elem":[{"flags":0,"key":{"data_reg":{"type":"value","len":2,"data0":"0x00001700"}},"data":{"data_reg":{"type":"chain","chain":"forward"}}},{"flags":0,"key":{"data_reg":{"type":"value","len":2,"data0":"0x00001600"}},"data":{"data_reg":{"type":"chain","chain":"chain1"}}}]}}
+{"nftables":[{"set":{"name":"map0","table":"f","flags":11,"family":"ip","key_type":12,"key_len":2,"data_type":4294967040,"data_len":16,"set_elem":[{"flags":0,"key":{"data_reg":{"type":"value","len":2,"data0":"0x00001700"}},"data":{"data_reg":{"type":"verdict","verdict":"goto","chain":"o"}}},{"flags":0,"key":{"data_reg":{"type":"value","len":2,"data0":"0x00001600"}},"data":{"data_reg":{"type":"verdict","verdict":"accept"}}}]}}]}
diff --git a/tests/jsonfiles/64-ruleset.json b/tests/jsonfiles/64-ruleset.json
index d1c22b8..3495d83 100644
--- a/tests/jsonfiles/64-ruleset.json
+++ b/tests/jsonfiles/64-ruleset.json
@@ -1,2 +1 @@
-{"nftables":[{"table":{"name":"filter","family":"ip","flags":0,"use":0}},{"table":{"name":"filter2","family":"ip6","flags":0,"use":0}},{"chain":{"name":"input","handle":1,"bytes":10681449,"packets":16216,"family":"ip","table":"filter","use":0,"type":"filter","hooknum":"input","prio":0,"policy":"accept"}},{"chain":{"name":"forward","handle":2,"bytes":0,"packets":0,"family":"ip","table":"filter","use":0,"type":"filter","hooknum":"forward","prio":0,"policy":"accept"}},{"chain":{"name":"output","handle":3,"bytes":2375830,"packets":15184,"family":"ip","table":"filter","use":0,"type":"filter","hooknum":"output","prio":0,"policy":"accept"}},{"chain":{"name":"chain1","handle":4,"bytes":0,"packets":0,"family":"ip","table":"filter","use":0}},{"set":{"name":"set0","table":"filter","flags":3,"family":"ip","key_type":12,"key_len":2}},{"rule":{"family":"ip","table":"filter","chain":"output","handle":6,"expr":[{"type":"payload","dreg":1,"offset":16,"len":4,"base":"link"},{"type":"cmp","sreg":1,"op":"eq","cmpdata":{"data_reg":{"type":"value","len":4,"data0":"0x0100a8c0"}}},{"type":"counter","pkts":0,"bytes":0},{"type":"immediate","dreg":0,"immediatedata":{"data_reg":{"type":"verdict","verdict":"drop"}}}]}},{"rule":{"family":"ip","table":"filter","chain":"output","handle":9,"expr":[{"type":"payload","dreg":1,"offset":9,"len":1,"base":"link"},{"type":"cmp","sreg":1,"op":"eq","cmpdata":{"data_reg":{"type":"value","len":1,"data0":"0x00000006"}}},{"type":"payload","dreg":1,"offset":2,"len":2,"base":"link"},{"type":"cmp","sreg":1,"op":"eq","cmpdata":{"data_reg":{"type":"value","len":2,"data0":"0x00001600"}}},{"type":"counter","pkts":0,"bytes":0}]}},{"rule":{"family":"ip","table":"filter","chain":"output","handle":10,"expr":[{"type":"payload","dreg":1,"offset":16,"len":4,"base":"link"},{"type":"cmp","sreg":1,"op":"eq","cmpdata":{"data_reg":{"type":"value","len":4,"data0":"0x0100a8c0"}}},{"type":"counter","pkts":0,"bytes":0}]}},{"rule":{"family":"ip","table":"filter", "chain":"output","handle":11,"expr":[{"type":"payload","dreg":1,"offset":16,"len":4,"base":"link"},{"type":"cmp","sreg":1,"op":"eq","cmpdata":{"data_reg":{"type":"value","len":4,"data0":"0x0100a8c0"}}},{"type":"counter","pkts":0,"bytes":0},{"type":"immediate","dreg":0,"immediatedata":{"data_reg":{"type":"verdict","verdict":"drop"}}}]}}]}
-
+{"nftables":[{"table":{"name":"filter","family":"ip","flags":0,"use":0}},{"table":{"name":"filter2","family":"ip6","flags":0,"use":0}},{"chain":{"name":"input","handle":1,"bytes":10681449,"packets":16216,"family":"ip","table":"filter","use":0,"type":"filter","hooknum":"input","prio":0,"policy":"accept"}},{"chain":{"name":"forward","handle":2,"bytes":0,"packets":0,"family":"ip","table":"filter","use":0,"type":"filter","hooknum":"forward","prio":0,"policy":"accept"}},{"chain":{"name":"output","handle":3,"bytes":2375830,"packets":15184,"family":"ip","table":"filter","use":0,"type":"filter","hooknum":"output","prio":0,"policy":"accept"}},{"chain":{"name":"chain1","handle":4,"bytes":0,"packets":0,"family":"ip","table":"filter","use":0}},{"set":{"name":"set0","table":"filter","flags":3,"family":"ip","key_type":12,"key_len":2}},{"rule":{"family":"ip","table":"filter","chain":"output","handle":6,"expr":[{"type":"payload","dreg":1,"offset":16,"len":4,"base":"link"},{"type":"cmp","sreg":1,"op":"eq","cmpdata":{"data_reg":{"type":"value","len":4,"data0":"0x0100a8c0"}}},{"type":"counter","pkts":0,"bytes":0},{"type":"immediate","dreg":0,"immediatedata":{"data_reg":{"type":"verdict","verdict":"drop"}}}]}},{"rule":{"family":"ip","table":"filter","chain":"output","handle":9,"expr":[{"type":"payload","dreg":1,"offset":9,"len":1,"base":"link"},{"type":"cmp","sreg":1,"op":"eq","cmpdata":{"data_reg":{"type":"value","len":1,"data0":"0x00000006"}}},{"type":"payload","dreg":1,"offset":2,"len":2,"base":"link"},{"type":"cmp","sreg":1,"op":"eq","cmpdata":{"data_reg":{"type":"value","len":2,"data0":"0x00001600"}}},{"type":"counter","pkts":0,"bytes":0}]}},{"rule":{"family":"ip","table":"filter","chain":"output","handle":10,"expr":[{"type":"payload","dreg":1,"offset":16,"len":4,"base":"link"},{"type":"cmp","sreg":1,"op":"eq","cmpdata":{"data_reg":{"type":"value","len":4,"data0":"0x0100a8c0"}}},{"type":"counter","pkts":0,"bytes":0}]}},{"rule":{"family":"ip","table":"filter","chain":"output","handle":11,"expr":[{"type":"payload","dreg":1,"offset":16,"len":4,"base":"link"},{"type":"cmp","sreg":1,"op":"eq","cmpdata":{"data_reg":{"type":"value","len":4,"data0":"0x0100a8c0"}}},{"type":"counter","pkts":0,"bytes":0},{"type":"immediate","dreg":0,"immediatedata":{"data_reg":{"type":"verdict","verdict":"drop"}}}]}}]}
diff --git a/tests/jsonfiles/65-rule-meta-target.json b/tests/jsonfiles/65-rule-meta-target.json
index d058a1f..cf036bc 100644
--- a/tests/jsonfiles/65-rule-meta-target.json
+++ b/tests/jsonfiles/65-rule-meta-target.json
@@ -1 +1 @@
-{"rule":{"family":"ip","table":"filter","chain":"output","handle":1,"expr":[{"type":"meta","key":"mark","sreg":1},{"type":"cmp","sreg":1,"op":"eq","cmpdata":{"data_reg":{"type":"value","len":4,"data0":"0x000003e8"}}},{"type":"counter","pkts":0,"bytes":0}]}}
+{"nftables":[{"rule":{"family":"ip","table":"filter","chain":"output","handle":1,"expr":[{"type":"meta","key":"mark","sreg":1},{"type":"cmp","sreg":1,"op":"eq","cmpdata":{"data_reg":{"type":"value","len":4,"data0":"0x000003e8"}}},{"type":"counter","pkts":0,"bytes":0}]}}]}
diff --git a/tests/nft-chain-test.c b/tests/nft-chain-test.c
index 80c1981..125562a 100644
--- a/tests/nft-chain-test.c
+++ b/tests/nft-chain-test.c
@@ -13,7 +13,7 @@
#include <string.h>
#include <netinet/in.h>
#include <linux/netfilter/nf_tables.h>
-#include <libnftables/chain.h>
+#include <libnftnl/chain.h>
static int test_ok = 1;
diff --git a/tests/nft-expr_bitwise-test.c b/tests/nft-expr_bitwise-test.c
index d755c75..0fe5329 100644
--- a/tests/nft-expr_bitwise-test.c
+++ b/tests/nft-expr_bitwise-test.c
@@ -16,8 +16,8 @@
#include <netinet/ip.h>
#include <linux/netfilter/nf_tables.h>
#include <libmnl/libmnl.h>
-#include <libnftables/rule.h>
-#include <libnftables/expr.h>
+#include <libnftnl/rule.h>
+#include <libnftnl/expr.h>
static int test_ok = 1;
diff --git a/tests/nft-expr_byteorder-test.c b/tests/nft-expr_byteorder-test.c
index 5e50da1..456d508 100644
--- a/tests/nft-expr_byteorder-test.c
+++ b/tests/nft-expr_byteorder-test.c
@@ -16,8 +16,8 @@
#include <netinet/ip.h>
#include <linux/netfilter/nf_tables.h>
#include <libmnl/libmnl.h>
-#include <libnftables/rule.h>
-#include <libnftables/expr.h>
+#include <libnftnl/rule.h>
+#include <libnftnl/expr.h>
static int test_ok = 1;
diff --git a/tests/nft-expr_cmp-test.c b/tests/nft-expr_cmp-test.c
index f435bbe..f411770 100644
--- a/tests/nft-expr_cmp-test.c
+++ b/tests/nft-expr_cmp-test.c
@@ -16,8 +16,8 @@
#include <netinet/ip.h>
#include <linux/netfilter/nf_tables.h>
#include <libmnl/libmnl.h>
-#include <libnftables/rule.h>
-#include <libnftables/expr.h>
+#include <libnftnl/rule.h>
+#include <libnftnl/expr.h>
static int test_ok = 1;
diff --git a/tests/nft-expr_counter-test.c b/tests/nft-expr_counter-test.c
index 70cac2b..e27d20a 100644
--- a/tests/nft-expr_counter-test.c
+++ b/tests/nft-expr_counter-test.c
@@ -16,8 +16,8 @@
#include <netinet/ip.h>
#include <linux/netfilter/nf_tables.h>
#include <libmnl/libmnl.h>
-#include <libnftables/rule.h>
-#include <libnftables/expr.h>
+#include <libnftnl/rule.h>
+#include <libnftnl/expr.h>
static int test_ok = 1;
diff --git a/tests/nft-expr_ct-test.c b/tests/nft-expr_ct-test.c
index f8bd13d..341d9e6 100644
--- a/tests/nft-expr_ct-test.c
+++ b/tests/nft-expr_ct-test.c
@@ -16,8 +16,8 @@
#include <linux/netfilter/nf_tables.h>
#include <libmnl/libmnl.h>
-#include <libnftables/rule.h>
-#include <libnftables/expr.h>
+#include <libnftnl/rule.h>
+#include <libnftnl/expr.h>
static int test_ok = 1;
static void print_err(const char *msg)
diff --git a/tests/nft-expr_exthdr-test.c b/tests/nft-expr_exthdr-test.c
index 64c364c..a712903 100644
--- a/tests/nft-expr_exthdr-test.c
+++ b/tests/nft-expr_exthdr-test.c
@@ -16,8 +16,8 @@
#include <netinet/ip.h>
#include <linux/netfilter/nf_tables.h>
#include <libmnl/libmnl.h>
-#include <libnftables/rule.h>
-#include <libnftables/expr.h>
+#include <libnftnl/rule.h>
+#include <libnftnl/expr.h>
static int test_ok = 1;
diff --git a/tests/nft-expr_immediate-test.c b/tests/nft-expr_immediate-test.c
index 91e8a3d..c45cefa 100644
--- a/tests/nft-expr_immediate-test.c
+++ b/tests/nft-expr_immediate-test.c
@@ -16,8 +16,8 @@
#include <linux/netfilter/nf_tables.h>
#include <libmnl/libmnl.h>
-#include <libnftables/rule.h>
-#include <libnftables/expr.h>
+#include <libnftnl/rule.h>
+#include <libnftnl/expr.h>
static int test_ok = 1;
diff --git a/tests/nft-expr_limit-test.c b/tests/nft-expr_limit-test.c
index c5730cc..38c3e5b 100644
--- a/tests/nft-expr_limit-test.c
+++ b/tests/nft-expr_limit-test.c
@@ -17,8 +17,8 @@
#include <linux/netfilter/nf_tables.h>
#include <libmnl/libmnl.h>
-#include <libnftables/rule.h>
-#include <libnftables/expr.h>
+#include <libnftnl/rule.h>
+#include <libnftnl/expr.h>
static int test_ok = 1;
diff --git a/tests/nft-expr_log-test.c b/tests/nft-expr_log-test.c
index 7590548..7e257ab 100644
--- a/tests/nft-expr_log-test.c
+++ b/tests/nft-expr_log-test.c
@@ -16,8 +16,8 @@
#include <linux/netfilter/nf_tables.h>
#include <libmnl/libmnl.h>
-#include <libnftables/rule.h>
-#include <libnftables/expr.h>
+#include <libnftnl/rule.h>
+#include <libnftnl/expr.h>
static int test_ok = 1;
diff --git a/tests/nft-expr_lookup-test.c b/tests/nft-expr_lookup-test.c
index 760e69c..38a2a46 100644
--- a/tests/nft-expr_lookup-test.c
+++ b/tests/nft-expr_lookup-test.c
@@ -16,8 +16,8 @@
#include <netinet/ip.h>
#include <linux/netfilter/nf_tables.h>
#include <libmnl/libmnl.h>
-#include <libnftables/rule.h>
-#include <libnftables/expr.h>
+#include <libnftnl/rule.h>
+#include <libnftnl/expr.h>
static int test_ok = 1;
diff --git a/tests/nft-expr_match-test.c b/tests/nft-expr_match-test.c
index dcb9f74..96b063a 100644
--- a/tests/nft-expr_match-test.c
+++ b/tests/nft-expr_match-test.c
@@ -18,8 +18,8 @@
#include <linux/netfilter/nf_tables.h>
#include <linux/netfilter/xt_iprange.h>
#include <libmnl/libmnl.h>
-#include <libnftables/rule.h>
-#include <libnftables/expr.h>
+#include <libnftnl/rule.h>
+#include <libnftnl/expr.h>
static int test_ok = 1;
diff --git a/tests/nft-expr_meta-test.c b/tests/nft-expr_meta-test.c
index 879f2e7..9196f9c 100644
--- a/tests/nft-expr_meta-test.c
+++ b/tests/nft-expr_meta-test.c
@@ -16,8 +16,8 @@
#include <linux/netfilter/nf_tables.h>
#include <libmnl/libmnl.h>
-#include <libnftables/rule.h>
-#include <libnftables/expr.h>
+#include <libnftnl/rule.h>
+#include <libnftnl/expr.h>
static int test_ok = 1;
diff --git a/tests/nft-expr_nat-test.c b/tests/nft-expr_nat-test.c
index 35b6479..64966b2 100644
--- a/tests/nft-expr_nat-test.c
+++ b/tests/nft-expr_nat-test.c
@@ -17,8 +17,8 @@
#include <linux/netfilter/nf_tables.h>
#include <linux/netfilter/xt_iprange.h>
#include <libmnl/libmnl.h>
-#include <libnftables/rule.h>
-#include <libnftables/expr.h>
+#include <libnftnl/rule.h>
+#include <libnftnl/expr.h>
static int test_ok = 1;
diff --git a/tests/nft-expr_payload-test.c b/tests/nft-expr_payload-test.c
index d6f4e05..3ce59f9 100644
--- a/tests/nft-expr_payload-test.c
+++ b/tests/nft-expr_payload-test.c
@@ -17,8 +17,8 @@
#include <linux/netfilter/nf_tables.h>
#include <linux/netfilter/xt_iprange.h>
#include <libmnl/libmnl.h>
-#include <libnftables/rule.h>
-#include <libnftables/expr.h>
+#include <libnftnl/rule.h>
+#include <libnftnl/expr.h>
static int test_ok = 1;
diff --git a/tests/nft-expr_queue-test.c b/tests/nft-expr_queue-test.c
index eb741f4..cfe01b6 100644
--- a/tests/nft-expr_queue-test.c
+++ b/tests/nft-expr_queue-test.c
@@ -19,8 +19,8 @@
#include <linux/netfilter/nf_tables.h>
#include <linux/netfilter/xt_iprange.h>
#include <libmnl/libmnl.h>
-#include <libnftables/rule.h>
-#include <libnftables/expr.h>
+#include <libnftnl/rule.h>
+#include <libnftnl/expr.h>
static int test_ok = 1;
diff --git a/tests/nft-expr_reject-test.c b/tests/nft-expr_reject-test.c
index 23784e9..0678081 100644
--- a/tests/nft-expr_reject-test.c
+++ b/tests/nft-expr_reject-test.c
@@ -17,8 +17,8 @@
#include <linux/netfilter/nf_tables.h>
#include <linux/netfilter/xt_iprange.h>
#include <libmnl/libmnl.h>
-#include <libnftables/rule.h>
-#include <libnftables/expr.h>
+#include <libnftnl/rule.h>
+#include <libnftnl/expr.h>
static int test_ok = 1;
diff --git a/tests/nft-expr_target-test.c b/tests/nft-expr_target-test.c
index 7bde348..9387779 100644
--- a/tests/nft-expr_target-test.c
+++ b/tests/nft-expr_target-test.c
@@ -18,8 +18,8 @@
#include <linux/netfilter/xt_iprange.h>
#include <linux/netfilter/xt_LOG.h>
#include <libmnl/libmnl.h>
-#include <libnftables/rule.h>
-#include <libnftables/expr.h>
+#include <libnftnl/rule.h>
+#include <libnftnl/expr.h>
static int test_ok = 1;
diff --git a/tests/nft-parsing-test.c b/tests/nft-parsing-test.c
index 6a5ab4d..1786cb6 100644
--- a/tests/nft-parsing-test.c
+++ b/tests/nft-parsing-test.c
@@ -6,34 +6,17 @@
#include <errno.h>
#include <libmnl/libmnl.h> /*nlmsghdr*/
-#include <libnftables/ruleset.h>
-#include <libnftables/table.h>
-#include <libnftables/chain.h>
-#include <libnftables/rule.h>
-#include <libnftables/set.h>
-
-#ifdef XML_PARSING
-#include <mxml.h>
-#endif
-
-#ifdef JSON_PARSING
-#include <jansson.h>
-#endif
+#include <libnftnl/ruleset.h>
+#include <libnftnl/table.h>
+#include <libnftnl/chain.h>
+#include <libnftnl/rule.h>
+#include <libnftnl/set.h>
enum {
- TEST_XML_TABLE = 0,
- TEST_XML_CHAIN,
- TEST_XML_RULE,
- TEST_XML_SET,
TEST_XML_RULESET,
- TEST_JSON_TABLE,
- TEST_JSON_CHAIN,
- TEST_JSON_RULE,
- TEST_JSON_SET,
TEST_JSON_RULESET,
};
-#if defined(XML_PARSING) || defined(JSON_PARSING)
static void print_detail_error(char *a, char *b)
{
int i;
@@ -73,68 +56,13 @@ static void print_detail_error(char *a, char *b)
}
}
-static int compare_test(uint32_t type, void *input, const char *filename)
+static int compare_test(uint32_t type, struct nft_ruleset *rs,
+ const char *filename, FILE *fp)
{
- struct nft_table *t = NULL;
- struct nft_chain *c = NULL;
- struct nft_rule *r = NULL;
- struct nft_set *s = NULL;
- struct nft_ruleset *rs = NULL;
char orig[4096];
char out[4096];
- FILE *fp;
switch (type) {
- case TEST_XML_TABLE:
- case TEST_JSON_TABLE:
- t = (struct nft_table *)input;
- break;
- case TEST_XML_CHAIN:
- case TEST_JSON_CHAIN:
- c = (struct nft_chain *)input;
- break;
- case TEST_XML_RULE:
- case TEST_JSON_RULE:
- r = (struct nft_rule *)input;
- break;
- case TEST_XML_SET:
- case TEST_JSON_SET:
- s = (struct nft_set *)input;
- break;
- case TEST_XML_RULESET:
- case TEST_JSON_RULESET:
- rs = (struct nft_ruleset *)input;
- break;
- default:
- errno = EINVAL;
- return -1;
- }
-
- switch (type) {
- case TEST_XML_TABLE:
- nft_table_snprintf(out, sizeof(out), t, NFT_OUTPUT_XML, 0);
- break;
- case TEST_JSON_TABLE:
- nft_table_snprintf(out, sizeof(out), t, NFT_OUTPUT_JSON, 0);
- break;
- case TEST_XML_CHAIN:
- nft_chain_snprintf(out, sizeof(out), c, NFT_OUTPUT_XML, 0);
- break;
- case TEST_JSON_CHAIN:
- nft_chain_snprintf(out, sizeof(out), c, NFT_OUTPUT_JSON, 0);
- break;
- case TEST_XML_RULE:
- nft_rule_snprintf(out, sizeof(out), r, NFT_OUTPUT_XML, 0);
- break;
- case TEST_JSON_RULE:
- nft_rule_snprintf(out, sizeof(out), r, NFT_OUTPUT_JSON, 0);
- break;
- case TEST_XML_SET:
- nft_set_snprintf(out, sizeof(out), s, NFT_OUTPUT_XML, 0);
- break;
- case TEST_JSON_SET:
- nft_set_snprintf(out, sizeof(out), s, NFT_OUTPUT_JSON, 0);
- break;
case TEST_XML_RULESET:
nft_ruleset_snprintf(out, sizeof(out), rs,
NFT_OUTPUT_XML, 0);
@@ -148,14 +76,8 @@ static int compare_test(uint32_t type, void *input, const char *filename)
return -1;
}
- fp = fopen(filename, "r");
- if (fp == NULL) {
- perror("open");
- exit(EXIT_FAILURE);
- }
-
+ rewind(fp);
fgets(orig, sizeof(orig), fp);
- fclose(fp);
if (strncmp(orig, out, strlen(out)) == 0)
return 0;
@@ -165,194 +87,78 @@ static int compare_test(uint32_t type, void *input, const char *filename)
print_detail_error(orig, out);
return -1;
}
-#endif
-static int test_json(const char *filename)
+static int test_json(const char *filename, struct nft_parse_err *err)
{
-#ifdef JSON_PARSING
int ret = -1;
- struct nft_table *t;
- struct nft_chain *c;
- struct nft_rule *r;
- struct nft_set *s;
struct nft_ruleset *rs;
- json_t *root;
- json_error_t error;
- char *json;
+ FILE *fp;
- root = json_load_file(filename, 0, &error);
- if (!root) {
- printf("Error on the line %d : %s", error.line, error.text);
+ fp = fopen(filename, "r");
+ if (fp == NULL) {
+ printf("unable to open file %s: %s\n", filename,
+ strerror(errno));
return -1;
}
- json = json_dumps(root, JSON_INDENT(0));
-
- if (json_object_get(root, "table") != NULL) {
- t = nft_table_alloc();
- if (t != NULL) {
- if (nft_table_parse(t, NFT_PARSE_JSON, json) == 0)
- ret = compare_test(TEST_JSON_TABLE, t, filename);
- else
- goto failparsing;
-
- nft_table_free(t);
- }
- } else if (json_object_get(root, "chain") != NULL) {
- c = nft_chain_alloc();
- if (c != NULL) {
- if (nft_chain_parse(c, NFT_PARSE_JSON, json) == 0)
- ret = compare_test(TEST_JSON_CHAIN, c, filename);
- else
- goto failparsing;
-
- nft_chain_free(c);
- }
- } else if (json_object_get(root, "rule") != NULL) {
- r = nft_rule_alloc();
- if (r != NULL) {
- if (nft_rule_parse(r, NFT_PARSE_JSON, json) == 0)
- ret = compare_test(TEST_JSON_RULE, r, filename);
- else
- goto failparsing;
-
- nft_rule_free(r);
- }
- } else if (json_object_get(root, "set") != NULL) {
- s = nft_set_alloc();
- if (s != NULL) {
- if (nft_set_parse(s, NFT_PARSE_JSON, json) == 0)
- ret = compare_test(TEST_JSON_SET, s, filename);
- else
- goto failparsing;
+ rs = nft_ruleset_alloc();
+ if (rs == NULL) {
+ perror("nft_ruleset_alloc");
+ return -1;
+ }
- nft_set_free(s);
- }
- } else if (json_object_get(root, "nftables") != NULL) {
- rs = nft_ruleset_alloc();
- if (rs != NULL) {
- if (nft_ruleset_parse(rs, NFT_PARSE_JSON, json) == 0)
- ret = compare_test(TEST_JSON_RULESET, rs, filename);
- else
- goto failparsing;
+ if (nft_ruleset_parse_file(rs, NFT_PARSE_JSON, fp, err) == 0)
+ ret = compare_test(TEST_JSON_RULESET, rs, filename, fp);
+ else
+ goto failparsing;
- nft_ruleset_free(rs);
- }
- }
+ nft_ruleset_free(rs);
+ fclose(fp);
- free(json);
- json_decref(root);
return ret;
failparsing:
+ fclose(fp);
printf("parsing %s: ", filename);
printf("\033[31mFAILED\e[0m (%s)\n", strerror(errno));
- free(json);
- json_decref(root);
+ nft_parse_perror("fail", err);
return -1;
-#else
- printf("Compiled without support for JSON.\n");
- return -1;
-#endif
}
-static int test_xml(const char *filename)
+static int test_xml(const char *filename, struct nft_parse_err *err)
{
-#ifdef XML_PARSING
int ret = -1;
- struct nft_table *t;
- struct nft_chain *c;
- struct nft_rule *r;
- struct nft_set *s;
struct nft_ruleset *rs;
FILE *fp;
- mxml_node_t *tree;
- char *xml;
fp = fopen(filename, "r");
- tree = mxmlLoadFile(NULL, fp, MXML_NO_CALLBACK);
- fclose(fp);
-
- if (tree == NULL) {
- printf("unable to build XML tree from file "
- "%s \033[31mFAILED\e[0m\n", filename);
+ if (fp == NULL) {
+ printf("unable to open file %s: %s\n", filename,
+ strerror(errno));
return -1;
}
- xml = mxmlSaveAllocString(tree, MXML_NO_CALLBACK);
- if (xml == NULL) {
- printf("unable to alloc string from XML tree from %s "
- "\033[31mFAILED\e[0m\n", filename);
+ rs = nft_ruleset_alloc();
+ if (rs == NULL) {
+ perror("nft_ruleset_alloc");
return -1;
}
- /* Check what parsing should be done */
- if (strcmp(tree->value.opaque, "table") == 0) {
- t = nft_table_alloc();
- if (t != NULL) {
- if (nft_table_parse(t, NFT_PARSE_XML, xml) == 0)
- ret = compare_test(TEST_XML_TABLE, t, filename);
- else
- goto failparsing;
-
- nft_table_free(t);
- }
- } else if (strcmp(tree->value.opaque, "chain") == 0) {
- c = nft_chain_alloc();
- if (c != NULL) {
- if (nft_chain_parse(c, NFT_PARSE_XML, xml) == 0)
- ret = compare_test(TEST_XML_CHAIN, c, filename);
- else
- goto failparsing;
-
- nft_chain_free(c);
- }
- } else if (strcmp(tree->value.opaque, "rule") == 0) {
- r = nft_rule_alloc();
- if (r != NULL) {
- if (nft_rule_parse(r, NFT_PARSE_XML, xml) == 0)
- ret = compare_test(TEST_XML_RULE, r, filename);
- else
- goto failparsing;
+ if (nft_ruleset_parse_file(rs, NFT_PARSE_XML, fp, err) == 0)
+ ret = compare_test(TEST_XML_RULESET, rs, filename, fp);
+ else
+ goto failparsing;
- nft_rule_free(r);
- }
- } else if (strcmp(tree->value.opaque, "set") == 0) {
- s = nft_set_alloc();
- if (s != NULL) {
- if (nft_set_parse(s, NFT_PARSE_XML, xml) == 0)
- ret = compare_test(TEST_XML_SET, s, filename);
- else
- goto failparsing;
-
- nft_set_free(s);
- }
- } else if (strcmp(tree->value.opaque, "nftables") == 0) {
- rs = nft_ruleset_alloc();
- if (rs != NULL) {
- if (nft_ruleset_parse(rs, NFT_PARSE_XML,
- xml) == 0)
- ret = compare_test(TEST_XML_RULESET, rs,
- filename);
- else
- goto failparsing;
-
- nft_ruleset_free(rs);
- }
- }
+ nft_ruleset_free(rs);
+ fclose(fp);
- mxmlDelete(tree);
return ret;
failparsing:
- mxmlDelete(tree);
+ fclose(fp);
printf("parsing %s: ", filename);
printf("\033[31mFAILED\e[0m (%s)\n", strerror(errno));
return -1;
-#else
- printf("Compiled without support for XML.\n");
- return -1;
-#endif
}
int main(int argc, char *argv[])
@@ -361,6 +167,7 @@ int main(int argc, char *argv[])
struct dirent *dent;
char path[PATH_MAX];
int ret = 0, exit_code = 0;
+ struct nft_parse_err *err;
if (argc != 2) {
fprintf(stderr, "Usage: %s <directory>\n", argv[0]);
@@ -373,6 +180,12 @@ int main(int argc, char *argv[])
exit(EXIT_FAILURE);
}
+ err = nft_parse_err_alloc();
+ if (err == NULL) {
+ perror("error");
+ exit(EXIT_FAILURE);
+ }
+
while ((dent = readdir(d)) != NULL) {
int len = strlen(dent->d_name);
@@ -383,14 +196,14 @@ int main(int argc, char *argv[])
snprintf(path, sizeof(path), "%s/%s", argv[1], dent->d_name);
if (strcmp(&dent->d_name[len-4], ".xml") == 0) {
- if ((ret = test_xml(path)) == 0) {
+ if ((ret = test_xml(path, err)) == 0) {
printf("parsing and validating %s: ", path);
printf("\033[32mOK\e[0m\n");
}
exit_code += ret;
}
if (strcmp(&dent->d_name[len-5], ".json") == 0) {
- if ((ret = test_json(path)) == 0) {
+ if ((ret = test_json(path, err)) == 0) {
printf("parsing and validating %s: ", path);
printf("\033[32mOK\e[0m\n");
}
@@ -399,6 +212,7 @@ int main(int argc, char *argv[])
}
closedir(d);
+ nft_parse_err_free(err);
if (exit_code != 0)
exit(EXIT_FAILURE);
diff --git a/tests/nft-rule-test.c b/tests/nft-rule-test.c
index 5b99003..80338d0 100644
--- a/tests/nft-rule-test.c
+++ b/tests/nft-rule-test.c
@@ -14,7 +14,7 @@
#include <netinet/in.h>
#include <linux/netfilter/nf_tables.h>
-#include <libnftables/rule.h>
+#include <libnftnl/rule.h>
static int test_ok = 1;
diff --git a/tests/nft-set-test.c b/tests/nft-set-test.c
index 5930af3..141dfd3 100644
--- a/tests/nft-set-test.c
+++ b/tests/nft-set-test.c
@@ -14,7 +14,7 @@
#include <netinet/in.h>
#include <linux/netfilter/nf_tables.h>
-#include <libnftables/set.h>
+#include <libnftnl/set.h>
static int test_ok = 1;
diff --git a/tests/nft-table-test.c b/tests/nft-table-test.c
index fd85f42..051163b 100644
--- a/tests/nft-table-test.c
+++ b/tests/nft-table-test.c
@@ -14,7 +14,7 @@
#include <netinet/in.h>
#include <linux/netfilter/nf_tables.h>
-#include <libnftables/table.h>
+#include <libnftnl/table.h>
static int test_ok = 1;
diff --git a/tests/xmlfiles/01-table.xml b/tests/xmlfiles/01-table.xml
index 1a11aa3..655b544 100644
--- a/tests/xmlfiles/01-table.xml
+++ b/tests/xmlfiles/01-table.xml
@@ -1 +1 @@
-<table><name>filter</name><family>ip</family><flags>0</flags><use>0</use></table>
+<nftables><table><name>filter</name><family>ip</family><flags>0</flags><use>0</use></table></nftables>
diff --git a/tests/xmlfiles/02-table.xml b/tests/xmlfiles/02-table.xml
index ece0455..5de924f 100644
--- a/tests/xmlfiles/02-table.xml
+++ b/tests/xmlfiles/02-table.xml
@@ -1 +1 @@
-<table><name>nat</name><family>ip6</family><flags>0</flags><use>0</use></table>
+<nftables><table><name>nat</name><family>ip6</family><flags>0</flags><use>0</use></table></nftables>
diff --git a/tests/xmlfiles/10-chain.xml b/tests/xmlfiles/10-chain.xml
index c6aa156..9c00eda 100644
--- a/tests/xmlfiles/10-chain.xml
+++ b/tests/xmlfiles/10-chain.xml
@@ -1 +1 @@
-<chain><name>test</name><handle>0</handle><bytes>0</bytes><packets>0</packets><table>filter</table><type>filter</type><hooknum>input</hooknum><prio>0</prio><policy>accept</policy><family>ip</family></chain>
+<nftables><chain><name>test</name><handle>0</handle><bytes>0</bytes><packets>0</packets><table>filter</table><type>filter</type><hooknum>input</hooknum><prio>0</prio><policy>accept</policy><family>ip</family></chain></nftables>
diff --git a/tests/xmlfiles/11-chain.xml b/tests/xmlfiles/11-chain.xml
index 3423078..3d9978e 100644
--- a/tests/xmlfiles/11-chain.xml
+++ b/tests/xmlfiles/11-chain.xml
@@ -1 +1 @@
-<chain><name>test</name><handle>0</handle><bytes>59</bytes><packets>1</packets><table>filter</table><type>filter</type><hooknum>forward</hooknum><prio>0</prio><policy>drop</policy><family>ip6</family></chain>
+<nftables><chain><name>test</name><handle>0</handle><bytes>59</bytes><packets>1</packets><table>filter</table><type>filter</type><hooknum>forward</hooknum><prio>0</prio><policy>drop</policy><family>ip6</family></chain></nftables>
diff --git a/tests/xmlfiles/12-chain.xml b/tests/xmlfiles/12-chain.xml
index 6afcd00..db0f56c 100644
--- a/tests/xmlfiles/12-chain.xml
+++ b/tests/xmlfiles/12-chain.xml
@@ -1 +1 @@
-<chain><name>foo</name><handle>100</handle><bytes>59264154979</bytes><packets>2548796325</packets><table>nat</table><type>nat</type><hooknum>postrouting</hooknum><prio>0</prio><policy>accept</policy><family>ip</family></chain>
+<nftables><chain><name>foo</name><handle>100</handle><bytes>59264154979</bytes><packets>2548796325</packets><table>nat</table><type>nat</type><hooknum>postrouting</hooknum><prio>0</prio><policy>accept</policy><family>ip</family></chain></nftables>
diff --git a/tests/xmlfiles/20-rule-bitwise.xml b/tests/xmlfiles/20-rule-bitwise.xml
index 9517db9..756b22c 100644
--- a/tests/xmlfiles/20-rule-bitwise.xml
+++ b/tests/xmlfiles/20-rule-bitwise.xml
@@ -1,2 +1 @@
-<rule><family>ip</family><table>filter</table><chain>INPUT</chain><handle>100</handle><expr type="bitwise"><sreg>1</sreg><dreg>1</dreg><len>4</len><mask><data_reg type="value"><len>4</len><data0>0x0000000a</data0></data_reg></mask><xor><data_reg type="value"><len>4</len><data0>0x00000000</data0></data_reg></xor></expr></rule>
-<!-- nft add rule filter input ct state new,established accept -->
+<nftables><rule><family>ip</family><table>filter</table><chain>INPUT</chain><handle>100</handle><expr type="bitwise"><sreg>1</sreg><dreg>1</dreg><len>4</len><mask><data_reg type="value"><len>4</len><data0>0x0000000a</data0></data_reg></mask><xor><data_reg type="value"><len>4</len><data0>0x00000000</data0></data_reg></xor></expr></rule></nftables>
diff --git a/tests/xmlfiles/21-rule-byteorder.xml b/tests/xmlfiles/21-rule-byteorder.xml
index f8f13b6..fce4ed1 100644
--- a/tests/xmlfiles/21-rule-byteorder.xml
+++ b/tests/xmlfiles/21-rule-byteorder.xml
@@ -1 +1 @@
-<rule><family>ip</family><table>test</table><chain>test</chain><handle>1000</handle><expr type="byteorder"><sreg>3</sreg><dreg>4</dreg><op>hton</op><len>4</len><size>4</size></expr></rule>
+<nftables><rule><family>ip</family><table>test</table><chain>test</chain><handle>1000</handle><expr type="byteorder"><sreg>3</sreg><dreg>4</dreg><op>hton</op><len>4</len><size>4</size></expr></rule></nftables>
diff --git a/tests/xmlfiles/22-rule-cmp.xml b/tests/xmlfiles/22-rule-cmp.xml
index 837d0de..308fb9f 100644
--- a/tests/xmlfiles/22-rule-cmp.xml
+++ b/tests/xmlfiles/22-rule-cmp.xml
@@ -1,2 +1 @@
-<rule><family>ip6</family><table>filter</table><chain>test</chain><handle>36</handle><expr type="cmp"><sreg>1</sreg><op>eq</op><cmpdata><data_reg type="value"><len>16</len><data0>0x00000000</data0><data1>0x6e6f6200</data1><data2>0x2e303164</data2><data3>0x00393331</data3></data_reg></cmpdata></expr></rule>
-<!-- nft add rule ip6 filter test meta iifname bond10.139 accept -->
+<nftables><rule><family>ip6</family><table>filter</table><chain>test</chain><handle>36</handle><expr type="cmp"><sreg>1</sreg><op>eq</op><cmpdata><data_reg type="value"><len>16</len><data0>0x00000000</data0><data1>0x6e6f6200</data1><data2>0x2e303164</data2><data3>0x00393331</data3></data_reg></cmpdata></expr></rule></nftables>
diff --git a/tests/xmlfiles/23-rule-counter.xml b/tests/xmlfiles/23-rule-counter.xml
index 77aba7a..6299e84 100644
--- a/tests/xmlfiles/23-rule-counter.xml
+++ b/tests/xmlfiles/23-rule-counter.xml
@@ -1,2 +1 @@
-<rule><family>ip6</family><table>filter</table><chain>test</chain><handle>39</handle><expr type="counter"><pkts>3</pkts><bytes>177</bytes></expr></rule>
-<!-- nft add rule ip6 filter test udp dport 53 counter accept -->
+<nftables><rule><family>ip6</family><table>filter</table><chain>test</chain><handle>39</handle><expr type="counter"><pkts>3</pkts><bytes>177</bytes></expr></rule></nftables>
diff --git a/tests/xmlfiles/24-rule-ct.xml b/tests/xmlfiles/24-rule-ct.xml
index 814ab52..1939e43 100644
--- a/tests/xmlfiles/24-rule-ct.xml
+++ b/tests/xmlfiles/24-rule-ct.xml
@@ -1,2 +1 @@
-<rule><family>ip</family><table>filter</table><chain>INPUT</chain><handle>100</handle><expr type="ct"><dreg>1</dreg><key>state</key><dir>0</dir></expr></rule>
-<!-- nft add rule filter input ct state new,established accept -->
+<nftables><rule><family>ip</family><table>filter</table><chain>INPUT</chain><handle>100</handle><expr type="ct"><dreg>1</dreg><key>state</key><dir>original</dir></expr></rule></nftables>
diff --git a/tests/xmlfiles/25-rule-exthdr.xml b/tests/xmlfiles/25-rule-exthdr.xml
index 6bf139c..9e10a88 100644
--- a/tests/xmlfiles/25-rule-exthdr.xml
+++ b/tests/xmlfiles/25-rule-exthdr.xml
@@ -1 +1 @@
-<rule><family>ip6</family><table>filter</table><chain>INPUT</chain><handle>100</handle><expr type="exthdr"><dreg>1</dreg><exthdr_type>mh</exthdr_type><offset>2</offset><len>16</len></expr></rule>
+<nftables><rule><family>ip6</family><table>filter</table><chain>INPUT</chain><handle>100</handle><expr type="exthdr"><dreg>1</dreg><exthdr_type>mh</exthdr_type><offset>2</offset><len>16</len></expr></rule></nftables>
diff --git a/tests/xmlfiles/26-rule-immediate.xml b/tests/xmlfiles/26-rule-immediate.xml
index 2928142..1258c8b 100644
--- a/tests/xmlfiles/26-rule-immediate.xml
+++ b/tests/xmlfiles/26-rule-immediate.xml
@@ -1,2 +1 @@
-<rule><family>ip</family><table>filter</table><chain>input</chain><handle>32</handle><expr type="immediate"><dreg>0</dreg><immediatedata><data_reg type="verdict"><verdict>accept</verdict></data_reg></immediatedata></expr></rule>
-<!-- nft add rule filter input ct state new,established accept -->
+<nftables><rule><family>ip</family><table>filter</table><chain>input</chain><handle>32</handle><expr type="immediate"><dreg>0</dreg><immediatedata><data_reg type="verdict"><verdict>accept</verdict></data_reg></immediatedata></expr></rule></nftables>
diff --git a/tests/xmlfiles/27-rule-limit.xml b/tests/xmlfiles/27-rule-limit.xml
index 6761c9e..a4398e8 100644
--- a/tests/xmlfiles/27-rule-limit.xml
+++ b/tests/xmlfiles/27-rule-limit.xml
@@ -1 +1 @@
-<rule><family>ip</family><table>filter</table><chain>INPUT</chain><handle>100</handle><expr type="limit"><rate>123123</rate><unit>321321</unit></expr></rule>
+<nftables><rule><family>ip</family><table>filter</table><chain>INPUT</chain><handle>100</handle><expr type="limit"><rate>123123</rate><unit>321321</unit></expr></rule></nftables>
diff --git a/tests/xmlfiles/28-rule-log.xml b/tests/xmlfiles/28-rule-log.xml
index d30e5fb..5865bd4 100644
--- a/tests/xmlfiles/28-rule-log.xml
+++ b/tests/xmlfiles/28-rule-log.xml
@@ -1,2 +1 @@
-<rule><family>ip6</family><table>filter</table><chain>test</chain><handle>96</handle><expr type="log"><prefix>test_chain</prefix><group>1</group><snaplen>0</snaplen><qthreshold>0</qthreshold></expr></rule>
-<!-- nft add rule ip6 filter test log prefix test_chain group 1 -->
+<nftables><rule><family>ip6</family><table>filter</table><chain>test</chain><handle>96</handle><expr type="log"><prefix>test_chain</prefix><group>1</group><snaplen>0</snaplen><qthreshold>0</qthreshold></expr></rule></nftables>
diff --git a/tests/xmlfiles/29-rule-lookup.xml b/tests/xmlfiles/29-rule-lookup.xml
index b08ccd3..052b008 100644
--- a/tests/xmlfiles/29-rule-lookup.xml
+++ b/tests/xmlfiles/29-rule-lookup.xml
@@ -1,2 +1 @@
-<rule><family>ip6</family><table>filter</table><chain>test</chain><handle>37</handle><expr type="lookup"><set>set0</set><sreg>1</sreg><dreg>0</dreg></expr></rule>
-<!-- nft add rule ip6 filter test ip6 saddr { ::2 , ::3 } drop -->
+<nftables><rule><family>ip6</family><table>filter</table><chain>test</chain><handle>37</handle><expr type="lookup"><set>set0</set><sreg>1</sreg><dreg>0</dreg></expr></rule></nftables>
diff --git a/tests/xmlfiles/30-rule-match.xml b/tests/xmlfiles/30-rule-match.xml
index b4cf72b..4cfe33b 100644
--- a/tests/xmlfiles/30-rule-match.xml
+++ b/tests/xmlfiles/30-rule-match.xml
@@ -1 +1 @@
-<rule><family>ip</family><table>filter</table><chain>INPUT</chain><handle>100</handle><expr type="match"><name>state</name></expr></rule>
+<nftables><rule><family>ip</family><table>filter</table><chain>INPUT</chain><handle>100</handle><expr type="match"><name>state</name></expr></rule></nftables>
diff --git a/tests/xmlfiles/31-rule-meta.xml b/tests/xmlfiles/31-rule-meta.xml
index b38e430..a1c9e8c 100644
--- a/tests/xmlfiles/31-rule-meta.xml
+++ b/tests/xmlfiles/31-rule-meta.xml
@@ -1,2 +1 @@
-<rule><family>ip6</family><table>filter</table><chain>test</chain><handle>36</handle><expr type="meta"><dreg>1</dreg><key>iifname</key></expr></rule>
-<!-- nft add rule ip6 filter test meta iifname bond10.139 accept -->
+<nftables><rule><family>ip6</family><table>filter</table><chain>test</chain><handle>36</handle><expr type="meta"><dreg>1</dreg><key>iifname</key></expr></rule></nftables>
diff --git a/tests/xmlfiles/32-rule-nat6.xml b/tests/xmlfiles/32-rule-nat6.xml
index 81566ce..f96b7d8 100644
--- a/tests/xmlfiles/32-rule-nat6.xml
+++ b/tests/xmlfiles/32-rule-nat6.xml
@@ -1 +1 @@
-<rule><family>ip6</family><table>nat</table><chain>OUTPUT</chain><handle>100</handle><expr type="nat"><type>snat</type><family>ip6</family><sreg_addr_min>1</sreg_addr_min><sreg_addr_max>2</sreg_addr_max><sreg_proto_min>3</sreg_proto_min><sreg_proto_max>4</sreg_proto_max></expr></rule>
+<nftables><rule><family>ip6</family><table>nat</table><chain>OUTPUT</chain><handle>100</handle><expr type="nat"><type>snat</type><family>ip6</family><sreg_addr_min>1</sreg_addr_min><sreg_addr_max>2</sreg_addr_max><sreg_proto_min>3</sreg_proto_min><sreg_proto_max>4</sreg_proto_max></expr></rule></nftables>
diff --git a/tests/xmlfiles/33-rule-nat4.xml b/tests/xmlfiles/33-rule-nat4.xml
index 0e495a8..73c5b56 100644
--- a/tests/xmlfiles/33-rule-nat4.xml
+++ b/tests/xmlfiles/33-rule-nat4.xml
@@ -1 +1 @@
-<rule><family>ip</family><table>filter</table><chain>INPUT</chain><handle>100</handle><expr type="nat"><type>dnat</type><family>ip</family><sreg_addr_min>1</sreg_addr_min><sreg_addr_max>2</sreg_addr_max><sreg_proto_min>3</sreg_proto_min><sreg_proto_max>4</sreg_proto_max></expr></rule>
+<nftables><rule><family>ip</family><table>filter</table><chain>INPUT</chain><handle>100</handle><expr type="nat"><type>dnat</type><family>ip</family><sreg_addr_min>1</sreg_addr_min><sreg_addr_max>2</sreg_addr_max><sreg_proto_min>3</sreg_proto_min><sreg_proto_max>4</sreg_proto_max></expr></rule></nftables>
diff --git a/tests/xmlfiles/34-rule-payload.xml b/tests/xmlfiles/34-rule-payload.xml
index 6c2da6a..a6faca9 100644
--- a/tests/xmlfiles/34-rule-payload.xml
+++ b/tests/xmlfiles/34-rule-payload.xml
@@ -1,2 +1 @@
-<rule><family>ip6</family><table>filter</table><chain>test</chain><handle>34</handle><expr type="payload"><dreg>1</dreg><offset>2</offset><len>2</len><base>transport</base></expr></rule>
-<!-- nft add rule ip6 filter test tcp dport 22 accept -->
+<nftables><rule><family>ip6</family><table>filter</table><chain>test</chain><handle>34</handle><expr type="payload"><dreg>1</dreg><offset>2</offset><len>2</len><base>transport</base></expr></rule></nftables>
diff --git a/tests/xmlfiles/35-rule-target.xml b/tests/xmlfiles/35-rule-target.xml
index 6925d96..5b46350 100644
--- a/tests/xmlfiles/35-rule-target.xml
+++ b/tests/xmlfiles/35-rule-target.xml
@@ -1 +1 @@
-<rule><family>ip</family><table>filter</table><chain>INPUT</chain><handle>100</handle><expr type="target"><name>LOG</name></expr></rule>
+<nftables><rule><family>ip</family><table>filter</table><chain>INPUT</chain><handle>100</handle><expr type="target"><name>LOG</name></expr></rule></nftables>
diff --git a/tests/xmlfiles/36-rule-real.xml b/tests/xmlfiles/36-rule-real.xml
index 1c953e7..5c8e075 100644
--- a/tests/xmlfiles/36-rule-real.xml
+++ b/tests/xmlfiles/36-rule-real.xml
@@ -1,2 +1 @@
-<rule><family>ip</family><table>filter</table><chain>output</chain><handle>22</handle><expr type="payload"><dreg>1</dreg><offset>12</offset><len>8</len><base>network</base></expr><expr type="cmp"><sreg>1</sreg><op>eq</op><cmpdata><data_reg type="value"><len>8</len><data0>0x0100a8c0</data0><data1>0x6400a8c0</data1></data_reg></cmpdata></expr><expr type="counter"><pkts>0</pkts><bytes>0</bytes></expr></rule>
-<!-- nft add rule filter INPUT ip saddr 192.168.0.1 ip daddr 192.168.0.100 counter -->
+<nftables><rule><family>ip</family><table>filter</table><chain>output</chain><handle>22</handle><expr type="payload"><dreg>1</dreg><offset>12</offset><len>8</len><base>network</base></expr><expr type="cmp"><sreg>1</sreg><op>eq</op><cmpdata><data_reg type="value"><len>8</len><data0>0x0100a8c0</data0><data1>0x6400a8c0</data1></data_reg></cmpdata></expr><expr type="counter"><pkts>0</pkts><bytes>0</bytes></expr></rule></nftables>
diff --git a/tests/xmlfiles/37-rule-real.xml b/tests/xmlfiles/37-rule-real.xml
index 3c8ba13..d9293f6 100644
--- a/tests/xmlfiles/37-rule-real.xml
+++ b/tests/xmlfiles/37-rule-real.xml
@@ -1,2 +1 @@
-<rule><family>ip</family><table>filter</table><chain>INPUT</chain><handle>25</handle><expr type="meta"><dreg>1</dreg><key>iifname</key></expr><expr type="cmp"><sreg>1</sreg><op>eq</op><cmpdata><data_reg type="value"><len>16</len><data0>0x00000000</data0><data1>0x00000000</data1><data2>0x65000000</data2><data3>0x00306874</data3></data_reg></cmpdata></expr><expr type="payload"><dreg>1</dreg><offset>9</offset><len>1</len><base>network</base></expr><expr type="cmp"><sreg>1</sreg><op>eq</op><cmpdata><data_reg type="value"><len>1</len><data0>0x00000006</data0></data_reg></cmpdata></expr><expr type="payload"><dreg>1</dreg><offset>2</offset><len>2</len><base>transport</base></expr><expr type="cmp"><sreg>1</sreg><op>eq</op><cmpdata><data_reg type="value"><len>2</len><data0>0x00001600</data0></data_reg></cmpdata></expr><expr type="ct"><dreg>1</dreg><key>state</key><dir>0</dir></expr><expr type="bitwise"><sreg>1</sreg><dreg>1</dreg><len>4</len><mask><data_reg type="value"><len>4</len><data0>0x0000000a</data0></data_reg></mask><xor><data_reg type="value"><len>4</len><data0>0x00000000</data0></data_reg></xor></expr><expr type="cmp"><sreg>1</sreg><op>neq</op><cmpdata><data_reg type="value"><len>4</len><data0>0x00000000</data0></data_reg></cmpdata></expr><expr type="counter"><pkts>0</pkts><bytes>0</bytes></expr><expr type="log"><prefix>testprefix</prefix><group>1</group><snaplen>0</snaplen><qthreshold>0</qthreshold></expr></rule>
-<!-- nft add rule filter INPUT meta iifname "eth0" tcp dport 22 ct state new,established counter log prefix testprefix group 1 -->
+<nftables><rule><family>ip</family><table>filter</table><chain>INPUT</chain><handle>25</handle><expr type="meta"><dreg>1</dreg><key>iifname</key></expr><expr type="cmp"><sreg>1</sreg><op>eq</op><cmpdata><data_reg type="value"><len>16</len><data0>0x00000000</data0><data1>0x00000000</data1><data2>0x65000000</data2><data3>0x00306874</data3></data_reg></cmpdata></expr><expr type="payload"><dreg>1</dreg><offset>9</offset><len>1</len><base>network</base></expr><expr type="cmp"><sreg>1</sreg><op>eq</op><cmpdata><data_reg type="value"><len>1</len><data0>0x00000006</data0></data_reg></cmpdata></expr><expr type="payload"><dreg>1</dreg><offset>2</offset><len>2</len><base>transport</base></expr><expr type="cmp"><sreg>1</sreg><op>eq</op><cmpdata><data_reg type="value"><len>2</len><data0>0x00001600</data0></data_reg></cmpdata></expr><expr type="ct"><dreg>1</dreg><key>state</key><dir>original</dir></expr><expr type="bitwise"><sreg>1</sreg><dreg>1</dreg><len>4</len><mask><data_reg type="value"><len>4</len><data0>0x0000000a</data0></data_reg></mask><xor><data_reg type="value"><len>4</len><data0>0x00000000</data0></data_reg></xor></expr><expr type="cmp"><sreg>1</sreg><op>neq</op><cmpdata><data_reg type="value"><len>4</len><data0>0x00000000</data0></data_reg></cmpdata></expr><expr type="counter"><pkts>0</pkts><bytes>0</bytes></expr><expr type="log"><prefix>testprefix</prefix><group>1</group><snaplen>0</snaplen><qthreshold>0</qthreshold></expr></rule></nftables>
diff --git a/tests/xmlfiles/38-rule-real.xml b/tests/xmlfiles/38-rule-real.xml
index 6161425..b8830b0 100644
--- a/tests/xmlfiles/38-rule-real.xml
+++ b/tests/xmlfiles/38-rule-real.xml
@@ -1,2 +1 @@
-<rule><family>ip</family><table>filter</table><chain>INPUT</chain><handle>30</handle><expr type="payload"><dreg>1</dreg><offset>16</offset><len>4</len><base>network</base></expr><expr type="lookup"><set>set3</set><sreg>1</sreg><dreg>0</dreg></expr><expr type="payload"><dreg>1</dreg><offset>9</offset><len>1</len><base>network</base></expr><expr type="cmp"><sreg>1</sreg><op>eq</op><cmpdata><data_reg type="value"><len>1</len><data0>0x00000006</data0></data_reg></cmpdata></expr><expr type="payload"><dreg>1</dreg><offset>2</offset><len>2</len><base>transport</base></expr><expr type="cmp"><sreg>1</sreg><op>eq</op><cmpdata><data_reg type="value"><len>2</len><data0>0x0000bb01</data0></data_reg></cmpdata></expr><expr type="counter"><pkts>0</pkts><bytes>0</bytes></expr><expr type="immediate"><dreg>0</dreg><immediatedata><data_reg type="verdict"><verdict>accept</verdict></data_reg></immediatedata></expr></rule>
-<!-- nft add rule ip filter INPUT ip daddr { 192.168.0.1, 192.168.0.2, 192.168.0.3 } tcp dport 443 counter accept -->
+<nftables><rule><family>ip</family><table>filter</table><chain>INPUT</chain><handle>30</handle><expr type="payload"><dreg>1</dreg><offset>16</offset><len>4</len><base>network</base></expr><expr type="lookup"><set>set3</set><sreg>1</sreg><dreg>0</dreg></expr><expr type="payload"><dreg>1</dreg><offset>9</offset><len>1</len><base>network</base></expr><expr type="cmp"><sreg>1</sreg><op>eq</op><cmpdata><data_reg type="value"><len>1</len><data0>0x00000006</data0></data_reg></cmpdata></expr><expr type="payload"><dreg>1</dreg><offset>2</offset><len>2</len><base>transport</base></expr><expr type="cmp"><sreg>1</sreg><op>eq</op><cmpdata><data_reg type="value"><len>2</len><data0>0x0000bb01</data0></data_reg></cmpdata></expr><expr type="counter"><pkts>0</pkts><bytes>0</bytes></expr><expr type="immediate"><dreg>0</dreg><immediatedata><data_reg type="verdict"><verdict>accept</verdict></data_reg></immediatedata></expr></rule></nftables>
diff --git a/tests/xmlfiles/39-rule-real.xml b/tests/xmlfiles/39-rule-real.xml
index fbf3d61..9a69a61 100644
--- a/tests/xmlfiles/39-rule-real.xml
+++ b/tests/xmlfiles/39-rule-real.xml
@@ -1,2 +1 @@
-<rule><family>ip6</family><table>filter</table><chain>test</chain><handle>31</handle><expr type="meta"><dreg>1</dreg><key>iifname</key></expr><expr type="cmp"><sreg>1</sreg><op>eq</op><cmpdata><data_reg type="value"><len>16</len><data0>0x00000000</data0><data1>0x00000000</data1><data2>0x6f620000</data2><data3>0x0030646e</data3></data_reg></cmpdata></expr><expr type="meta"><dreg>1</dreg><key>oifname</key></expr><expr type="cmp"><sreg>1</sreg><op>eq</op><cmpdata><data_reg type="value"><len>16</len><data0>0x00000000</data0><data1>0x62000000</data1><data2>0x31646e6f</data2><data3>0x0037322e</data3></data_reg></cmpdata></expr><expr type="payload"><dreg>1</dreg><offset>8</offset><len>16</len><base>network</base></expr><expr type="cmp"><sreg>1</sreg><op>eq</op><cmpdata><data_reg type="value"><len>16</len><data0>0xc09a002a</data0><data1>0x2700cac1</data1><data2>0x00000000</data2><data3>0x50010000</data3></data_reg></cmpdata></expr><expr type="payload"><dreg>1</dreg><offset>6</offset><len>1</len><base>network</base></expr><expr type="cmp"><sreg>1</sreg><op>eq</op><cmpdata><data_reg type="value"><len>1</len><data0>0x00000011</data0></data_reg></cmpdata></expr><expr type="payload"><dreg>1</dreg><offset>2</offset><len>2</len><base>transport</base></expr><expr type="cmp"><sreg>1</sreg><op>eq</op><cmpdata><data_reg type="value"><len>2</len><data0>0x00003500</data0></data_reg></cmpdata></expr><expr type="ct"><dreg>1</dreg><key>status</key><dir>0</dir></expr><expr type="cmp"><sreg>1</sreg><op>eq</op><cmpdata><data_reg type="value"><len>4</len><data0>0x00000001</data0></data_reg></cmpdata></expr><expr type="counter"><pkts>0</pkts><bytes>0</bytes></expr><expr type="log"><prefix>dns_drop</prefix><group>2</group><snaplen>0</snaplen><qthreshold>0</qthreshold></expr><expr type="immediate"><dreg>0</dreg><immediatedata><data_reg type="verdict"><verdict>drop</verdict></data_reg></immediatedata></expr></rule>
-<!-- nft add rule ip6 filter test meta iifname "bond0" meta oifname "bond1.27" ip6 saddr 2a00:9ac0:c1ca:27::150 udp dport 53 ct status expected counter log prefix dns_drop group 2 drop -->
+<nftables><rule><family>ip6</family><table>filter</table><chain>test</chain><handle>31</handle><expr type="meta"><dreg>1</dreg><key>iifname</key></expr><expr type="cmp"><sreg>1</sreg><op>eq</op><cmpdata><data_reg type="value"><len>16</len><data0>0x00000000</data0><data1>0x00000000</data1><data2>0x6f620000</data2><data3>0x0030646e</data3></data_reg></cmpdata></expr><expr type="meta"><dreg>1</dreg><key>oifname</key></expr><expr type="cmp"><sreg>1</sreg><op>eq</op><cmpdata><data_reg type="value"><len>16</len><data0>0x00000000</data0><data1>0x62000000</data1><data2>0x31646e6f</data2><data3>0x0037322e</data3></data_reg></cmpdata></expr><expr type="payload"><dreg>1</dreg><offset>8</offset><len>16</len><base>network</base></expr><expr type="cmp"><sreg>1</sreg><op>eq</op><cmpdata><data_reg type="value"><len>16</len><data0>0xc09a002a</data0><data1>0x2700cac1</data1><data2>0x00000000</data2><data3>0x50010000</data3></data_reg></cmpdata></expr><expr type="payload"><dreg>1</dreg><offset>6</offset><len>1</len><base>network</base></expr><expr type="cmp"><sreg>1</sreg><op>eq</op><cmpdata><data_reg type="value"><len>1</len><data0>0x00000011</data0></data_reg></cmpdata></expr><expr type="payload"><dreg>1</dreg><offset>2</offset><len>2</len><base>transport</base></expr><expr type="cmp"><sreg>1</sreg><op>eq</op><cmpdata><data_reg type="value"><len>2</len><data0>0x00003500</data0></data_reg></cmpdata></expr><expr type="ct"><dreg>1</dreg><key>status</key><dir>original</dir></expr><expr type="cmp"><sreg>1</sreg><op>eq</op><cmpdata><data_reg type="value"><len>4</len><data0>0x00000001</data0></data_reg></cmpdata></expr><expr type="counter"><pkts>0</pkts><bytes>0</bytes></expr><expr type="log"><prefix>dns_drop</prefix><group>2</group><snaplen>0</snaplen><qthreshold>0</qthreshold></expr><expr type="immediate"><dreg>0</dreg><immediatedata><data_reg type="verdict"><verdict>drop</verdict></data_reg></immediatedata></expr></rule></nftables>
diff --git a/tests/xmlfiles/40-rule-real.xml b/tests/xmlfiles/40-rule-real.xml
index 8e1d565..0041ebf 100644
--- a/tests/xmlfiles/40-rule-real.xml
+++ b/tests/xmlfiles/40-rule-real.xml
@@ -1,2 +1 @@
-<rule><family>ip</family><table>filter</table><chain>output</chain><handle>2</handle><expr type="payload"><dreg>1</dreg><offset>16</offset><len>4</len><base>network</base></expr><expr type="cmp"><sreg>1</sreg><op>eq</op><cmpdata><data_reg type="value"><len>4</len><data0>0x0100a8c0</data0></data_reg></cmpdata></expr></rule>
-<!-- nft add rule filter output ip daddr 192.168.0.1 -->
+<nftables><rule><family>ip</family><table>filter</table><chain>output</chain><handle>2</handle><expr type="payload"><dreg>1</dreg><offset>16</offset><len>4</len><base>network</base></expr><expr type="cmp"><sreg>1</sreg><op>eq</op><cmpdata><data_reg type="value"><len>4</len><data0>0x0100a8c0</data0></data_reg></cmpdata></expr></rule></nftables>
diff --git a/tests/xmlfiles/41-rule-real.xml b/tests/xmlfiles/41-rule-real.xml
index 810267d..bd213b0 100644
--- a/tests/xmlfiles/41-rule-real.xml
+++ b/tests/xmlfiles/41-rule-real.xml
@@ -1,2 +1 @@
-<rule><family>ip</family><table>filter</table><chain>output</chain><handle>3</handle><expr type="payload"><dreg>1</dreg><offset>16</offset><len>4</len><base>network</base></expr><expr type="cmp"><sreg>1</sreg><op>gte</op><cmpdata><data_reg type="value"><len>4</len><data0>0x0100a8c0</data0></data_reg></cmpdata></expr><expr type="cmp"><sreg>1</sreg><op>lte</op><cmpdata><data_reg type="value"><len>4</len><data0>0xfa00a8c0</data0></data_reg></cmpdata></expr></rule>
-<!-- nft add rule filter output ip daddr 192.168.0.1-192.168.0.250 -->
+<nftables><rule><family>ip</family><table>filter</table><chain>output</chain><handle>3</handle><expr type="payload"><dreg>1</dreg><offset>16</offset><len>4</len><base>network</base></expr><expr type="cmp"><sreg>1</sreg><op>gte</op><cmpdata><data_reg type="value"><len>4</len><data0>0x0100a8c0</data0></data_reg></cmpdata></expr><expr type="cmp"><sreg>1</sreg><op>lte</op><cmpdata><data_reg type="value"><len>4</len><data0>0xfa00a8c0</data0></data_reg></cmpdata></expr></rule></nftables>
diff --git a/tests/xmlfiles/42-rule-real.xml b/tests/xmlfiles/42-rule-real.xml
index 6aba9eb..b5cc1bd 100644
--- a/tests/xmlfiles/42-rule-real.xml
+++ b/tests/xmlfiles/42-rule-real.xml
@@ -1,2 +1 @@
-<rule><family>ip</family><table>filter</table><chain>output</chain><handle>4</handle><expr type="payload"><dreg>1</dreg><offset>16</offset><len>4</len><base>network</base></expr><expr type="cmp"><sreg>1</sreg><op>eq</op><cmpdata><data_reg type="value"><len>4</len><data0>0x0100a8c0</data0></data_reg></cmpdata></expr><expr type="counter"><pkts>0</pkts><bytes>0</bytes></expr></rule>
-<!-- nft add rule filter output ip daddr 192.168.0.1 counter -->
+<nftables><rule><family>ip</family><table>filter</table><chain>output</chain><handle>4</handle><expr type="payload"><dreg>1</dreg><offset>16</offset><len>4</len><base>network</base></expr><expr type="cmp"><sreg>1</sreg><op>eq</op><cmpdata><data_reg type="value"><len>4</len><data0>0x0100a8c0</data0></data_reg></cmpdata></expr><expr type="counter"><pkts>0</pkts><bytes>0</bytes></expr></rule></nftables>
diff --git a/tests/xmlfiles/43-rule-real.xml b/tests/xmlfiles/43-rule-real.xml
index 7a2fe6b..a84f513 100644
--- a/tests/xmlfiles/43-rule-real.xml
+++ b/tests/xmlfiles/43-rule-real.xml
@@ -1,2 +1 @@
-<rule><family>ip</family><table>filter</table><chain>output</chain><handle>5</handle><expr type="payload"><dreg>1</dreg><offset>16</offset><len>4</len><base>network</base></expr><expr type="cmp"><sreg>1</sreg><op>eq</op><cmpdata><data_reg type="value"><len>4</len><data0>0x0100a8c0</data0></data_reg></cmpdata></expr><expr type="counter"><pkts>0</pkts><bytes>0</bytes></expr><expr type="immediate"><dreg>0</dreg><immediatedata><data_reg type="verdict"><verdict>drop</verdict></data_reg></immediatedata></expr></rule>
-<!-- nft add rule filter output ip daddr 192.168.0.1 counter drop -->
+<nftables><rule><family>ip</family><table>filter</table><chain>output</chain><handle>5</handle><expr type="payload"><dreg>1</dreg><offset>16</offset><len>4</len><base>network</base></expr><expr type="cmp"><sreg>1</sreg><op>eq</op><cmpdata><data_reg type="value"><len>4</len><data0>0x0100a8c0</data0></data_reg></cmpdata></expr><expr type="counter"><pkts>0</pkts><bytes>0</bytes></expr><expr type="immediate"><dreg>0</dreg><immediatedata><data_reg type="verdict"><verdict>drop</verdict></data_reg></immediatedata></expr></rule></nftables>
diff --git a/tests/xmlfiles/44-rule-real.xml b/tests/xmlfiles/44-rule-real.xml
index 69bdca8..5a99e6f 100644
--- a/tests/xmlfiles/44-rule-real.xml
+++ b/tests/xmlfiles/44-rule-real.xml
@@ -1,2 +1 @@
-<rule><family>ip</family><table>filter</table><chain>output</chain><handle>6</handle><expr type="payload"><dreg>1</dreg><offset>16</offset><len>4</len><base>network</base></expr><expr type="cmp"><sreg>1</sreg><op>eq</op><cmpdata><data_reg type="value"><len>4</len><data0>0x0100a8c0</data0></data_reg></cmpdata></expr><expr type="counter"><pkts>0</pkts><bytes>0</bytes></expr><expr type="log"><prefix>(null)</prefix><group>0</group><snaplen>0</snaplen><qthreshold>0</qthreshold></expr></rule>
-<!-- nft add rule filter output ip daddr 192.168.0.1 counter log -->
+<nftables><rule><family>ip</family><table>filter</table><chain>output</chain><handle>6</handle><expr type="payload"><dreg>1</dreg><offset>16</offset><len>4</len><base>network</base></expr><expr type="cmp"><sreg>1</sreg><op>eq</op><cmpdata><data_reg type="value"><len>4</len><data0>0x0100a8c0</data0></data_reg></cmpdata></expr><expr type="counter"><pkts>0</pkts><bytes>0</bytes></expr><expr type="log"><prefix>(null)</prefix><group>0</group><snaplen>0</snaplen><qthreshold>0</qthreshold></expr></rule></nftables>
diff --git a/tests/xmlfiles/45-rule-real.xml b/tests/xmlfiles/45-rule-real.xml
index 36837de..53fa009 100644
--- a/tests/xmlfiles/45-rule-real.xml
+++ b/tests/xmlfiles/45-rule-real.xml
@@ -1,2 +1 @@
-<rule><family>ip</family><table>filter</table><chain>output</chain><handle>7</handle><expr type="payload"><dreg>1</dreg><offset>9</offset><len>1</len><base>network</base></expr><expr type="cmp"><sreg>1</sreg><op>eq</op><cmpdata><data_reg type="value"><len>1</len><data0>0x00000006</data0></data_reg></cmpdata></expr><expr type="payload"><dreg>1</dreg><offset>2</offset><len>2</len><base>transport</base></expr><expr type="cmp"><sreg>1</sreg><op>eq</op><cmpdata><data_reg type="value"><len>2</len><data0>0x00001600</data0></data_reg></cmpdata></expr><expr type="counter"><pkts>0</pkts><bytes>0</bytes></expr></rule>
-<!-- nft add rule filter output tcp dport 22 counter -->
+<nftables><rule><family>ip</family><table>filter</table><chain>output</chain><handle>7</handle><expr type="payload"><dreg>1</dreg><offset>9</offset><len>1</len><base>network</base></expr><expr type="cmp"><sreg>1</sreg><op>eq</op><cmpdata><data_reg type="value"><len>1</len><data0>0x00000006</data0></data_reg></cmpdata></expr><expr type="payload"><dreg>1</dreg><offset>2</offset><len>2</len><base>transport</base></expr><expr type="cmp"><sreg>1</sreg><op>eq</op><cmpdata><data_reg type="value"><len>2</len><data0>0x00001600</data0></data_reg></cmpdata></expr><expr type="counter"><pkts>0</pkts><bytes>0</bytes></expr></rule></nftables>
diff --git a/tests/xmlfiles/46-rule-real.xml b/tests/xmlfiles/46-rule-real.xml
index 8465d0f..0ddf6c8 100644
--- a/tests/xmlfiles/46-rule-real.xml
+++ b/tests/xmlfiles/46-rule-real.xml
@@ -1,2 +1 @@
-<rule><family>ip</family><table>filter</table><chain>output</chain><handle>8</handle><expr type="payload"><dreg>1</dreg><offset>9</offset><len>1</len><base>network</base></expr><expr type="cmp"><sreg>1</sreg><op>eq</op><cmpdata><data_reg type="value"><len>1</len><data0>0x00000006</data0></data_reg></cmpdata></expr><expr type="payload"><dreg>1</dreg><offset>0</offset><len>4</len><base>transport</base></expr><expr type="cmp"><sreg>1</sreg><op>eq</op><cmpdata><data_reg type="value"><len>4</len><data0>0x16000004</data0></data_reg></cmpdata></expr><expr type="counter"><pkts>0</pkts><bytes>0</bytes></expr></rule>
-<!-- nft add rule filter output tcp sport 1024 tcp dport 22 counter -->
+<nftables><rule><family>ip</family><table>filter</table><chain>output</chain><handle>8</handle><expr type="payload"><dreg>1</dreg><offset>9</offset><len>1</len><base>network</base></expr><expr type="cmp"><sreg>1</sreg><op>eq</op><cmpdata><data_reg type="value"><len>1</len><data0>0x00000006</data0></data_reg></cmpdata></expr><expr type="payload"><dreg>1</dreg><offset>0</offset><len>4</len><base>transport</base></expr><expr type="cmp"><sreg>1</sreg><op>eq</op><cmpdata><data_reg type="value"><len>4</len><data0>0x16000004</data0></data_reg></cmpdata></expr><expr type="counter"><pkts>0</pkts><bytes>0</bytes></expr></rule></nftables>
diff --git a/tests/xmlfiles/47-rule-real.xml b/tests/xmlfiles/47-rule-real.xml
index 39a09a5..fde6d26 100644
--- a/tests/xmlfiles/47-rule-real.xml
+++ b/tests/xmlfiles/47-rule-real.xml
@@ -1,2 +1 @@
-<rule><family>ip</family><table>filter</table><chain>output</chain><handle>9</handle><expr type="payload"><dreg>1</dreg><offset>12</offset><len>8</len><base>network</base></expr><expr type="cmp"><sreg>1</sreg><op>eq</op><cmpdata><data_reg type="value"><len>8</len><data0>0x0100a8c0</data0><data1>0x6400a8c0</data1></data_reg></cmpdata></expr><expr type="counter"><pkts>0</pkts><bytes>0</bytes></expr></rule>
-<!-- nft add rule filter output ip saddr 192.168.0.1 ip daddr 192.168.0.100 counter -->
+<nftables><rule><family>ip</family><table>filter</table><chain>output</chain><handle>9</handle><expr type="payload"><dreg>1</dreg><offset>12</offset><len>8</len><base>network</base></expr><expr type="cmp"><sreg>1</sreg><op>eq</op><cmpdata><data_reg type="value"><len>8</len><data0>0x0100a8c0</data0><data1>0x6400a8c0</data1></data_reg></cmpdata></expr><expr type="counter"><pkts>0</pkts><bytes>0</bytes></expr></rule></nftables>
diff --git a/tests/xmlfiles/48-rule-real.xml b/tests/xmlfiles/48-rule-real.xml
index 89c5088..547a0f6 100644
--- a/tests/xmlfiles/48-rule-real.xml
+++ b/tests/xmlfiles/48-rule-real.xml
@@ -1,2 +1 @@
-<rule><family>ip</family><table>filter</table><chain>output</chain><handle>10</handle><expr type="payload"><dreg>1</dreg><offset>9</offset><len>1</len><base>network</base></expr><expr type="cmp"><sreg>1</sreg><op>eq</op><cmpdata><data_reg type="value"><len>1</len><data0>0x00000006</data0></data_reg></cmpdata></expr><expr type="payload"><dreg>1</dreg><offset>0</offset><len>8</len><base>transport</base></expr><expr type="cmp"><sreg>1</sreg><op>eq</op><cmpdata><data_reg type="value"><len>8</len><data0>0x16000004</data0><data1>0x00000000</data1></data_reg></cmpdata></expr></rule>
-<!-- nft add rule filter output tcp sequence 0 tcp sport 1024 tcp dport 22 -->
+<nftables><rule><family>ip</family><table>filter</table><chain>output</chain><handle>10</handle><expr type="payload"><dreg>1</dreg><offset>9</offset><len>1</len><base>network</base></expr><expr type="cmp"><sreg>1</sreg><op>eq</op><cmpdata><data_reg type="value"><len>1</len><data0>0x00000006</data0></data_reg></cmpdata></expr><expr type="payload"><dreg>1</dreg><offset>0</offset><len>8</len><base>transport</base></expr><expr type="cmp"><sreg>1</sreg><op>eq</op><cmpdata><data_reg type="value"><len>8</len><data0>0x16000004</data0><data1>0x00000000</data1></data_reg></cmpdata></expr></rule></nftables>
diff --git a/tests/xmlfiles/49-rule-real.xml b/tests/xmlfiles/49-rule-real.xml
index 0896823..dc662a3 100644
--- a/tests/xmlfiles/49-rule-real.xml
+++ b/tests/xmlfiles/49-rule-real.xml
@@ -1,2 +1 @@
-<rule><family>ip</family><table>filter</table><chain>output</chain><handle>11</handle><expr type="payload"><dreg>1</dreg><offset>9</offset><len>1</len><base>network</base></expr><expr type="cmp"><sreg>1</sreg><op>eq</op><cmpdata><data_reg type="value"><len>1</len><data0>0x00000006</data0></data_reg></cmpdata></expr><expr type="payload"><dreg>1</dreg><offset>0</offset><len>8</len><base>transport</base></expr><expr type="cmp"><sreg>1</sreg><op>eq</op><cmpdata><data_reg type="value"><len>8</len><data0>0x16000004</data0><data1>0x00000000</data1></data_reg></cmpdata></expr></rule>
-<!-- nft add rule filter output tcp sport 1024 tcp dport 22 tcp sequence 0 -->
+<nftables><rule><family>ip</family><table>filter</table><chain>output</chain><handle>11</handle><expr type="payload"><dreg>1</dreg><offset>9</offset><len>1</len><base>network</base></expr><expr type="cmp"><sreg>1</sreg><op>eq</op><cmpdata><data_reg type="value"><len>1</len><data0>0x00000006</data0></data_reg></cmpdata></expr><expr type="payload"><dreg>1</dreg><offset>0</offset><len>8</len><base>transport</base></expr><expr type="cmp"><sreg>1</sreg><op>eq</op><cmpdata><data_reg type="value"><len>8</len><data0>0x16000004</data0><data1>0x00000000</data1></data_reg></cmpdata></expr></rule></nftables>
diff --git a/tests/xmlfiles/50-rule-real.xml b/tests/xmlfiles/50-rule-real.xml
index 1195131..c52e00e 100644
--- a/tests/xmlfiles/50-rule-real.xml
+++ b/tests/xmlfiles/50-rule-real.xml
@@ -1,2 +1 @@
-<rule><family>ip</family><table>filter</table><chain>output</chain><handle>12</handle><expr type="ct"><dreg>1</dreg><key>state</key><dir>0</dir></expr><expr type="bitwise"><sreg>1</sreg><dreg>1</dreg><len>4</len><mask><data_reg type="value"><len>4</len><data0>0x0000000a</data0></data_reg></mask><xor><data_reg type="value"><len>4</len><data0>0x00000000</data0></data_reg></xor></expr><expr type="cmp"><sreg>1</sreg><op>neq</op><cmpdata><data_reg type="value"><len>4</len><data0>0x00000000</data0></data_reg></cmpdata></expr><expr type="counter"><pkts>55</pkts><bytes>11407</bytes></expr></rule>
-<!-- nft add rule filter output ct state new,established counter -->
+<nftables><rule><family>ip</family><table>filter</table><chain>output</chain><handle>12</handle><expr type="ct"><dreg>1</dreg><key>state</key><dir>original</dir></expr><expr type="bitwise"><sreg>1</sreg><dreg>1</dreg><len>4</len><mask><data_reg type="value"><len>4</len><data0>0x0000000a</data0></data_reg></mask><xor><data_reg type="value"><len>4</len><data0>0x00000000</data0></data_reg></xor></expr><expr type="cmp"><sreg>1</sreg><op>neq</op><cmpdata><data_reg type="value"><len>4</len><data0>0x00000000</data0></data_reg></cmpdata></expr><expr type="counter"><pkts>55</pkts><bytes>11407</bytes></expr></rule></nftables>
diff --git a/tests/xmlfiles/51-rule-real.xml b/tests/xmlfiles/51-rule-real.xml
index 4064ffb..93d6632 100644
--- a/tests/xmlfiles/51-rule-real.xml
+++ b/tests/xmlfiles/51-rule-real.xml
@@ -1,2 +1 @@
-<rule><family>ip</family><table>filter</table><chain>output</chain><handle>13</handle><expr type="ct"><dreg>1</dreg><key>direction</key><dir>0</dir></expr><expr type="cmp"><sreg>1</sreg><op>eq</op><cmpdata><data_reg type="value"><len>1</len><data0>0x00000000</data0></data_reg></cmpdata></expr><expr type="counter"><pkts>5</pkts><bytes>160</bytes></expr></rule>
-<!-- nft add rule filter output ct direction original counter -->
+<nftables><rule><family>ip</family><table>filter</table><chain>output</chain><handle>13</handle><expr type="ct"><dreg>1</dreg><key>direction</key><dir>original</dir></expr><expr type="cmp"><sreg>1</sreg><op>eq</op><cmpdata><data_reg type="value"><len>1</len><data0>0x00000000</data0></data_reg></cmpdata></expr><expr type="counter"><pkts>5</pkts><bytes>160</bytes></expr></rule></nftables>
diff --git a/tests/xmlfiles/52-rule-real.xml b/tests/xmlfiles/52-rule-real.xml
index 6ee7459..c6ca9ec 100644
--- a/tests/xmlfiles/52-rule-real.xml
+++ b/tests/xmlfiles/52-rule-real.xml
@@ -1,2 +1 @@
-<rule><family>ip</family><table>filter</table><chain>output</chain><handle>14</handle><expr type="ct"><dreg>1</dreg><key>direction</key><dir>0</dir></expr><expr type="cmp"><sreg>1</sreg><op>eq</op><cmpdata><data_reg type="value"><len>1</len><data0>0x00000001</data0></data_reg></cmpdata></expr><expr type="counter"><pkts>50</pkts><bytes>11247</bytes></expr></rule>
-<!-- nft add rule filter output ct direction reply counter -->
+<nftables><rule><family>ip</family><table>filter</table><chain>output</chain><handle>14</handle><expr type="ct"><dreg>1</dreg><key>direction</key><dir>original</dir></expr><expr type="cmp"><sreg>1</sreg><op>eq</op><cmpdata><data_reg type="value"><len>1</len><data0>0x00000001</data0></data_reg></cmpdata></expr><expr type="counter"><pkts>50</pkts><bytes>11247</bytes></expr></rule></nftables>
diff --git a/tests/xmlfiles/53-rule-real.xml b/tests/xmlfiles/53-rule-real.xml
index ec4ea21..8cb0783 100644
--- a/tests/xmlfiles/53-rule-real.xml
+++ b/tests/xmlfiles/53-rule-real.xml
@@ -1,2 +1 @@
-<rule><family>ip</family><table>filter</table><chain>output</chain><handle>15</handle><expr type="ct"><dreg>1</dreg><key>status</key><dir>0</dir></expr><expr type="cmp"><sreg>1</sreg><op>eq</op><cmpdata><data_reg type="value"><len>4</len><data0>0x00000001</data0></data_reg></cmpdata></expr><expr type="counter"><pkts>0</pkts><bytes>0</bytes></expr></rule>
-<!-- nft add rule filter output ct status expected counter -->
+<nftables><rule><family>ip</family><table>filter</table><chain>output</chain><handle>15</handle><expr type="ct"><dreg>1</dreg><key>status</key><dir>original</dir></expr><expr type="cmp"><sreg>1</sreg><op>eq</op><cmpdata><data_reg type="value"><len>4</len><data0>0x00000001</data0></data_reg></cmpdata></expr><expr type="counter"><pkts>0</pkts><bytes>0</bytes></expr></rule></nftables>
diff --git a/tests/xmlfiles/54-rule-real.xml b/tests/xmlfiles/54-rule-real.xml
index c80d43a..0c0dc9a 100644
--- a/tests/xmlfiles/54-rule-real.xml
+++ b/tests/xmlfiles/54-rule-real.xml
@@ -1,2 +1 @@
-<rule><family>ip</family><table>filter</table><chain>output</chain><handle>16</handle><expr type="ct"><dreg>1</dreg><key>mark</key><dir>0</dir></expr><expr type="cmp"><sreg>1</sreg><op>eq</op><cmpdata><data_reg type="value"><len>4</len><data0>0x00000064</data0></data_reg></cmpdata></expr><expr type="counter"><pkts>0</pkts><bytes>0</bytes></expr></rule>
-<!-- nft rule add filter output ct mark 100 counter -->
+<nftables><rule><family>ip</family><table>filter</table><chain>output</chain><handle>16</handle><expr type="ct"><dreg>1</dreg><key>mark</key><dir>original</dir></expr><expr type="cmp"><sreg>1</sreg><op>eq</op><cmpdata><data_reg type="value"><len>4</len><data0>0x00000064</data0></data_reg></cmpdata></expr><expr type="counter"><pkts>0</pkts><bytes>0</bytes></expr></rule></nftables>
diff --git a/tests/xmlfiles/55-rule-real.xml b/tests/xmlfiles/55-rule-real.xml
index 47f2e01..fca8c99 100644
--- a/tests/xmlfiles/55-rule-real.xml
+++ b/tests/xmlfiles/55-rule-real.xml
@@ -1,2 +1 @@
-<rule><family>ip</family><table>filter</table><chain>output</chain><handle>17</handle><expr type="ct"><dreg>1</dreg><key>secmark</key><dir>0</dir></expr><expr type="cmp"><sreg>1</sreg><op>eq</op><cmpdata><data_reg type="value"><len>4</len><data0>0x00000000</data0></data_reg></cmpdata></expr><expr type="counter"><pkts>55</pkts><bytes>11407</bytes></expr></rule>
-<!-- nft add rule filter output ct secmark 0 counter -->
+<nftables><rule><family>ip</family><table>filter</table><chain>output</chain><handle>17</handle><expr type="ct"><dreg>1</dreg><key>secmark</key><dir>original</dir></expr><expr type="cmp"><sreg>1</sreg><op>eq</op><cmpdata><data_reg type="value"><len>4</len><data0>0x00000000</data0></data_reg></cmpdata></expr><expr type="counter"><pkts>55</pkts><bytes>11407</bytes></expr></rule></nftables>
diff --git a/tests/xmlfiles/56-rule-real.xml b/tests/xmlfiles/56-rule-real.xml
index e4965e1..1ea7f0c 100644
--- a/tests/xmlfiles/56-rule-real.xml
+++ b/tests/xmlfiles/56-rule-real.xml
@@ -1,2 +1 @@
-<rule><family>ip</family><table>filter</table><chain>output</chain><handle>18</handle><expr type="ct"><dreg>1</dreg><key>expiration</key><dir>0</dir></expr><expr type="cmp"><sreg>1</sreg><op>eq</op><cmpdata><data_reg type="value"><len>4</len><data0>0x0000001e</data0></data_reg></cmpdata></expr><expr type="counter"><pkts>0</pkts><bytes>0</bytes></expr></rule>
-<!-- nft add rule filter output ct expiration 30 counter -->
+<nftables><rule><family>ip</family><table>filter</table><chain>output</chain><handle>18</handle><expr type="ct"><dreg>1</dreg><key>expiration</key><dir>original</dir></expr><expr type="cmp"><sreg>1</sreg><op>eq</op><cmpdata><data_reg type="value"><len>4</len><data0>0x0000001e</data0></data_reg></cmpdata></expr><expr type="counter"><pkts>0</pkts><bytes>0</bytes></expr></rule></nftables>
diff --git a/tests/xmlfiles/57-rule-real.xml b/tests/xmlfiles/57-rule-real.xml
index 985b274..6036973 100644
--- a/tests/xmlfiles/57-rule-real.xml
+++ b/tests/xmlfiles/57-rule-real.xml
@@ -1,2 +1 @@
-<rule><family>ip</family><table>filter</table><chain>output</chain><handle>19</handle><expr type="ct"><dreg>1</dreg><key>helper</key><dir>0</dir></expr><expr type="cmp"><sreg>1</sreg><op>eq</op><cmpdata><data_reg type="value"><len>4</len><data0>0x00707466</data0></data_reg></cmpdata></expr><expr type="counter"><pkts>0</pkts><bytes>0</bytes></expr></rule>
-<!-- nft add rule filter output ct helper "ftp" counter -->
+<nftables><rule><family>ip</family><table>filter</table><chain>output</chain><handle>19</handle><expr type="ct"><dreg>1</dreg><key>helper</key><dir>original</dir></expr><expr type="cmp"><sreg>1</sreg><op>eq</op><cmpdata><data_reg type="value"><len>4</len><data0>0x00707466</data0></data_reg></cmpdata></expr><expr type="counter"><pkts>0</pkts><bytes>0</bytes></expr></rule></nftables>
diff --git a/tests/xmlfiles/58-rule-real.xml b/tests/xmlfiles/58-rule-real.xml
index 4b456c1..d9bfe3a 100644
--- a/tests/xmlfiles/58-rule-real.xml
+++ b/tests/xmlfiles/58-rule-real.xml
@@ -1,2 +1 @@
-<rule><family>ip</family><table>filter</table><chain>output</chain><handle>20</handle><expr type="meta"><dreg>1</dreg><key>len</key></expr><expr type="cmp"><sreg>1</sreg><op>eq</op><cmpdata><data_reg type="value"><len>4</len><data0>0x000003e8</data0></data_reg></cmpdata></expr><expr type="counter"><pkts>0</pkts><bytes>0</bytes></expr></rule>
-<!-- nft add rule ip filter output meta length 1000 counter -->
+<nftables><rule><family>ip</family><table>filter</table><chain>output</chain><handle>20</handle><expr type="meta"><dreg>1</dreg><key>len</key></expr><expr type="cmp"><sreg>1</sreg><op>eq</op><cmpdata><data_reg type="value"><len>4</len><data0>0x000003e8</data0></data_reg></cmpdata></expr><expr type="counter"><pkts>0</pkts><bytes>0</bytes></expr></rule></nftables>
diff --git a/tests/xmlfiles/59-rule-real.xml b/tests/xmlfiles/59-rule-real.xml
index 603fe19..6af8aa6 100644
--- a/tests/xmlfiles/59-rule-real.xml
+++ b/tests/xmlfiles/59-rule-real.xml
@@ -1,2 +1 @@
-<rule><family>ip</family><table>filter</table><chain>output</chain><handle>21</handle><expr type="meta"><dreg>1</dreg><key>protocol</key></expr><expr type="cmp"><sreg>1</sreg><op>eq</op><cmpdata><data_reg type="value"><len>2</len><data0>0x00000008</data0></data_reg></cmpdata></expr><expr type="counter"><pkts>55</pkts><bytes>11407</bytes></expr></rule>
-<!-- nft add rule ip filter output meta protocol 0x0800 counter -->
+<nftables><rule><family>ip</family><table>filter</table><chain>output</chain><handle>21</handle><expr type="meta"><dreg>1</dreg><key>protocol</key></expr><expr type="cmp"><sreg>1</sreg><op>eq</op><cmpdata><data_reg type="value"><len>2</len><data0>0x00000008</data0></data_reg></cmpdata></expr><expr type="counter"><pkts>55</pkts><bytes>11407</bytes></expr></rule></nftables>
diff --git a/tests/xmlfiles/60-rule-real.xml b/tests/xmlfiles/60-rule-real.xml
index 66a96fe..24cf057 100644
--- a/tests/xmlfiles/60-rule-real.xml
+++ b/tests/xmlfiles/60-rule-real.xml
@@ -1,2 +1 @@
-<rule><family>ip</family><table>filter</table><chain>output</chain><handle>22</handle><expr type="meta"><dreg>1</dreg><key>mark</key></expr><expr type="cmp"><sreg>1</sreg><op>eq</op><cmpdata><data_reg type="value"><len>4</len><data0>0x00000000</data0></data_reg></cmpdata></expr><expr type="counter"><pkts>55</pkts><bytes>11407</bytes></expr></rule>
-<!-- nft add rule ip filter output meta mark 0 counter -->
+<nftables><rule><family>ip</family><table>filter</table><chain>output</chain><handle>22</handle><expr type="meta"><dreg>1</dreg><key>mark</key></expr><expr type="cmp"><sreg>1</sreg><op>eq</op><cmpdata><data_reg type="value"><len>4</len><data0>0x00000000</data0></data_reg></cmpdata></expr><expr type="counter"><pkts>55</pkts><bytes>11407</bytes></expr></rule></nftables>
diff --git a/tests/xmlfiles/61-rule-real.xml b/tests/xmlfiles/61-rule-real.xml
index 5c1340c..3aaad57 100644
--- a/tests/xmlfiles/61-rule-real.xml
+++ b/tests/xmlfiles/61-rule-real.xml
@@ -1,2 +1 @@
-<rule><family>ip</family><table>filter</table><chain>output</chain><handle>23</handle><expr type="meta"><dreg>1</dreg><key>iif</key></expr><expr type="cmp"><sreg>1</sreg><op>eq</op><cmpdata><data_reg type="value"><len>4</len><data0>0x00000001</data0></data_reg></cmpdata></expr><expr type="counter"><pkts>0</pkts><bytes>0</bytes></expr></rule>
-<!-- nft add rule ip filter output meta iif lo counter -->
+<nftables><rule><family>ip</family><table>filter</table><chain>output</chain><handle>23</handle><expr type="meta"><dreg>1</dreg><key>iif</key></expr><expr type="cmp"><sreg>1</sreg><op>eq</op><cmpdata><data_reg type="value"><len>4</len><data0>0x00000001</data0></data_reg></cmpdata></expr><expr type="counter"><pkts>0</pkts><bytes>0</bytes></expr></rule></nftables>
diff --git a/tests/xmlfiles/62-rule-real.xml b/tests/xmlfiles/62-rule-real.xml
index 6a6d381..d7935d1 100644
--- a/tests/xmlfiles/62-rule-real.xml
+++ b/tests/xmlfiles/62-rule-real.xml
@@ -1,2 +1 @@
-<rule><family>ip</family><table>filter</table><chain>output</chain><handle>24</handle><expr type="meta"><dreg>1</dreg><key>iifname</key></expr><expr type="cmp"><sreg>1</sreg><op>eq</op><cmpdata><data_reg type="value"><len>16</len><data0>0x00000000</data0><data1>0x00000000</data1><data2>0x65000000</data2><data3>0x00306874</data3></data_reg></cmpdata></expr><expr type="counter"><pkts>0</pkts><bytes>0</bytes></expr></rule>
-<!-- nft add rule ip filter output meta iifname "eth0" counter -->
+<nftables><rule><family>ip</family><table>filter</table><chain>output</chain><handle>24</handle><expr type="meta"><dreg>1</dreg><key>iifname</key></expr><expr type="cmp"><sreg>1</sreg><op>eq</op><cmpdata><data_reg type="value"><len>16</len><data0>0x00000000</data0><data1>0x00000000</data1><data2>0x65000000</data2><data3>0x00306874</data3></data_reg></cmpdata></expr><expr type="counter"><pkts>0</pkts><bytes>0</bytes></expr></rule></nftables>
diff --git a/tests/xmlfiles/63-rule-real.xml b/tests/xmlfiles/63-rule-real.xml
index baa13a7..f2a36f4 100644
--- a/tests/xmlfiles/63-rule-real.xml
+++ b/tests/xmlfiles/63-rule-real.xml
@@ -1,2 +1 @@
-<rule><family>ip</family><table>filter</table><chain>output</chain><handle>25</handle><expr type="meta"><dreg>1</dreg><key>oif</key></expr><expr type="cmp"><sreg>1</sreg><op>eq</op><cmpdata><data_reg type="value"><len>4</len><data0>0x00000001</data0></data_reg></cmpdata></expr><expr type="counter"><pkts>0</pkts><bytes>0</bytes></expr></rule>
-<!-- nft add rule ip filter output meta oif lo counter -->
+<nftables><rule><family>ip</family><table>filter</table><chain>output</chain><handle>25</handle><expr type="meta"><dreg>1</dreg><key>oif</key></expr><expr type="cmp"><sreg>1</sreg><op>eq</op><cmpdata><data_reg type="value"><len>4</len><data0>0x00000001</data0></data_reg></cmpdata></expr><expr type="counter"><pkts>0</pkts><bytes>0</bytes></expr></rule></nftables>
diff --git a/tests/xmlfiles/64-rule-real.xml b/tests/xmlfiles/64-rule-real.xml
index 157773f..01a8708 100644
--- a/tests/xmlfiles/64-rule-real.xml
+++ b/tests/xmlfiles/64-rule-real.xml
@@ -1,2 +1 @@
-<rule><family>ip</family><table>filter</table><chain>output</chain><handle>26</handle><expr type="meta"><dreg>1</dreg><key>oifname</key></expr><expr type="cmp"><sreg>1</sreg><op>eq</op><cmpdata><data_reg type="value"><len>16</len><data0>0x00000000</data0><data1>0x00000000</data1><data2>0x65000000</data2><data3>0x00306874</data3></data_reg></cmpdata></expr><expr type="counter"><pkts>0</pkts><bytes>0</bytes></expr></rule>
-<!-- nft add rule ip filter output meta oifname "eth0" counter -->
+<nftables><rule><family>ip</family><table>filter</table><chain>output</chain><handle>26</handle><expr type="meta"><dreg>1</dreg><key>oifname</key></expr><expr type="cmp"><sreg>1</sreg><op>eq</op><cmpdata><data_reg type="value"><len>16</len><data0>0x00000000</data0><data1>0x00000000</data1><data2>0x65000000</data2><data3>0x00306874</data3></data_reg></cmpdata></expr><expr type="counter"><pkts>0</pkts><bytes>0</bytes></expr></rule></nftables>
diff --git a/tests/xmlfiles/65-rule-real.xml b/tests/xmlfiles/65-rule-real.xml
index 06c560b..2d59190 100644
--- a/tests/xmlfiles/65-rule-real.xml
+++ b/tests/xmlfiles/65-rule-real.xml
@@ -1,2 +1 @@
-<rule><family>ip</family><table>filter</table><chain>output</chain><handle>27</handle><expr type="meta"><dreg>1</dreg><key>skuid</key></expr><expr type="cmp"><sreg>1</sreg><op>eq</op><cmpdata><data_reg type="value"><len>4</len><data0>0x000003e8</data0></data_reg></cmpdata></expr><expr type="counter"><pkts>0</pkts><bytes>0</bytes></expr></rule>
-<!-- nft add rule ip filter output meta skuid 1000 counter -->
+<nftables><rule><family>ip</family><table>filter</table><chain>output</chain><handle>27</handle><expr type="meta"><dreg>1</dreg><key>skuid</key></expr><expr type="cmp"><sreg>1</sreg><op>eq</op><cmpdata><data_reg type="value"><len>4</len><data0>0x000003e8</data0></data_reg></cmpdata></expr><expr type="counter"><pkts>0</pkts><bytes>0</bytes></expr></rule></nftables>
diff --git a/tests/xmlfiles/66-rule-real.xml b/tests/xmlfiles/66-rule-real.xml
index 9a5b721..f9d9c5e 100644
--- a/tests/xmlfiles/66-rule-real.xml
+++ b/tests/xmlfiles/66-rule-real.xml
@@ -1,2 +1 @@
-<rule><family>ip</family><table>filter</table><chain>output</chain><handle>28</handle><expr type="meta"><dreg>1</dreg><key>skgid</key></expr><expr type="cmp"><sreg>1</sreg><op>eq</op><cmpdata><data_reg type="value"><len>4</len><data0>0x000003e8</data0></data_reg></cmpdata></expr><expr type="counter"><pkts>0</pkts><bytes>0</bytes></expr></rule>
-<!-- nft add rule ip filter output meta skgid 1000 counter -->
+<nftables><rule><family>ip</family><table>filter</table><chain>output</chain><handle>28</handle><expr type="meta"><dreg>1</dreg><key>skgid</key></expr><expr type="cmp"><sreg>1</sreg><op>eq</op><cmpdata><data_reg type="value"><len>4</len><data0>0x000003e8</data0></data_reg></cmpdata></expr><expr type="counter"><pkts>0</pkts><bytes>0</bytes></expr></rule></nftables>
diff --git a/tests/xmlfiles/67-rule-real.xml b/tests/xmlfiles/67-rule-real.xml
index a3cbc2d..555139c 100644
--- a/tests/xmlfiles/67-rule-real.xml
+++ b/tests/xmlfiles/67-rule-real.xml
@@ -1,2 +1 @@
-<rule><family>ip</family><table>filter</table><chain>output</chain><handle>29</handle><expr type="meta"><dreg>1</dreg><key>secmark</key></expr><expr type="cmp"><sreg>1</sreg><op>eq</op><cmpdata><data_reg type="value"><len>4</len><data0>0x00000000</data0></data_reg></cmpdata></expr><expr type="counter"><pkts>55</pkts><bytes>11407</bytes></expr></rule>
-<!-- nft add rule ip filter output meta secmark 0 counter -->
+<nftables><rule><family>ip</family><table>filter</table><chain>output</chain><handle>29</handle><expr type="meta"><dreg>1</dreg><key>secmark</key></expr><expr type="cmp"><sreg>1</sreg><op>eq</op><cmpdata><data_reg type="value"><len>4</len><data0>0x00000000</data0></data_reg></cmpdata></expr><expr type="counter"><pkts>55</pkts><bytes>11407</bytes></expr></rule></nftables>
diff --git a/tests/xmlfiles/68-rule-real.xml b/tests/xmlfiles/68-rule-real.xml
index 7023e59..a0ff9ce 100644
--- a/tests/xmlfiles/68-rule-real.xml
+++ b/tests/xmlfiles/68-rule-real.xml
@@ -1,2 +1 @@
-<rule><family>ip</family><table>filter</table><chain>output</chain><handle>32</handle><expr type="payload"><dreg>1</dreg><offset>9</offset><len>1</len><base>network</base></expr><expr type="cmp"><sreg>1</sreg><op>eq</op><cmpdata><data_reg type="value"><len>1</len><data0>0x00000006</data0></data_reg></cmpdata></expr><expr type="payload"><dreg>1</dreg><offset>2</offset><len>2</len><base>transport</base></expr><expr type="lookup"><set>set0</set><sreg>1</sreg><dreg>0</dreg></expr><expr type="counter"><pkts>0</pkts><bytes>0</bytes></expr></rule>
-<!-- nft add rule filter output tcp dport { 22, 23 } counter -->
+<nftables><rule><family>ip</family><table>filter</table><chain>output</chain><handle>32</handle><expr type="payload"><dreg>1</dreg><offset>9</offset><len>1</len><base>network</base></expr><expr type="cmp"><sreg>1</sreg><op>eq</op><cmpdata><data_reg type="value"><len>1</len><data0>0x00000006</data0></data_reg></cmpdata></expr><expr type="payload"><dreg>1</dreg><offset>2</offset><len>2</len><base>transport</base></expr><expr type="lookup"><set>set0</set><sreg>1</sreg><dreg>0</dreg></expr><expr type="counter"><pkts>0</pkts><bytes>0</bytes></expr></rule></nftables>
diff --git a/tests/xmlfiles/69-rule-real.xml b/tests/xmlfiles/69-rule-real.xml
index dc2728e..e39e2cb 100644
--- a/tests/xmlfiles/69-rule-real.xml
+++ b/tests/xmlfiles/69-rule-real.xml
@@ -1,2 +1 @@
-<rule><family>ip</family><table>filter</table><chain>output</chain><handle>33</handle><expr type="payload"><dreg>1</dreg><offset>16</offset><len>4</len><base>network</base></expr><expr type="lookup"><set>set1</set><sreg>1</sreg><dreg>0</dreg></expr></rule>
-<!-- nft add rule ip filter output ip daddr { 192.168.0.1, 192.168.0.2, 192.168.0.3 } -->
+<nftables><rule><family>ip</family><table>filter</table><chain>output</chain><handle>33</handle><expr type="payload"><dreg>1</dreg><offset>16</offset><len>4</len><base>network</base></expr><expr type="lookup"><set>set1</set><sreg>1</sreg><dreg>0</dreg></expr></rule></nftables>
diff --git a/tests/xmlfiles/70-rule-real.xml b/tests/xmlfiles/70-rule-real.xml
index 64834d4..6edd166 100644
--- a/tests/xmlfiles/70-rule-real.xml
+++ b/tests/xmlfiles/70-rule-real.xml
@@ -1,2 +1 @@
-<rule><family>ip</family><table>filter</table><chain>output</chain><handle>34</handle><expr type="payload"><dreg>1</dreg><offset>9</offset><len>1</len><base>network</base></expr><expr type="cmp"><sreg>1</sreg><op>eq</op><cmpdata><data_reg type="value"><len>1</len><data0>0x00000006</data0></data_reg></cmpdata></expr><expr type="payload"><dreg>1</dreg><offset>2</offset><len>2</len><base>transport</base></expr><expr type="lookup"><set>map0</set><sreg>1</sreg><dreg>0</dreg></expr></rule>
-<!-- nft add rule ip filter output tcp dport vmap { 22 => jump chain1, 23 => jump chain2, } -->
+<nftables><rule><family>ip</family><table>filter</table><chain>output</chain><handle>34</handle><expr type="payload"><dreg>1</dreg><offset>9</offset><len>1</len><base>network</base></expr><expr type="cmp"><sreg>1</sreg><op>eq</op><cmpdata><data_reg type="value"><len>1</len><data0>0x00000006</data0></data_reg></cmpdata></expr><expr type="payload"><dreg>1</dreg><offset>2</offset><len>2</len><base>transport</base></expr><expr type="lookup"><set>map0</set><sreg>1</sreg><dreg>0</dreg></expr></rule></nftables>
diff --git a/tests/xmlfiles/71-rule-real.xml b/tests/xmlfiles/71-rule-real.xml
index e10437a..fba3af9 100644
--- a/tests/xmlfiles/71-rule-real.xml
+++ b/tests/xmlfiles/71-rule-real.xml
@@ -1,2 +1 @@
-<rule><family>ip</family><table>filter</table><chain>output</chain><handle>35</handle><expr type="payload"><dreg>1</dreg><offset>9</offset><len>1</len><base>network</base></expr><expr type="cmp"><sreg>1</sreg><op>eq</op><cmpdata><data_reg type="value"><len>1</len><data0>0x00000006</data0></data_reg></cmpdata></expr><expr type="payload"><dreg>1</dreg><offset>2</offset><len>2</len><base>transport</base></expr><expr type="lookup"><set>map1</set><sreg>1</sreg><dreg>0</dreg></expr></rule>
-<!-- nft add rule ip filter output tcp dport vmap { 22 => accept, 23 => drop, } -->
+<nftables><rule><family>ip</family><table>filter</table><chain>output</chain><handle>35</handle><expr type="payload"><dreg>1</dreg><offset>9</offset><len>1</len><base>network</base></expr><expr type="cmp"><sreg>1</sreg><op>eq</op><cmpdata><data_reg type="value"><len>1</len><data0>0x00000006</data0></data_reg></cmpdata></expr><expr type="payload"><dreg>1</dreg><offset>2</offset><len>2</len><base>transport</base></expr><expr type="lookup"><set>map1</set><sreg>1</sreg><dreg>0</dreg></expr></rule></nftables>
diff --git a/tests/xmlfiles/72-rule-real.xml b/tests/xmlfiles/72-rule-real.xml
index ccda1fe..aac8b85 100644
--- a/tests/xmlfiles/72-rule-real.xml
+++ b/tests/xmlfiles/72-rule-real.xml
@@ -1,2 +1 @@
-<rule><family>ip</family><table>filter</table><chain>output</chain><handle>36</handle><expr type="payload"><dreg>1</dreg><offset>16</offset><len>4</len><base>network</base></expr><expr type="lookup"><set>map2</set><sreg>1</sreg><dreg>0</dreg></expr></rule>
-<!-- nft add rule ip filter output ip daddr vmap { 192.168.1.1 => accept, 192.168.1.2 => drop, } -->
+<nftables><rule><family>ip</family><table>filter</table><chain>output</chain><handle>36</handle><expr type="payload"><dreg>1</dreg><offset>16</offset><len>4</len><base>network</base></expr><expr type="lookup"><set>map2</set><sreg>1</sreg><dreg>0</dreg></expr></rule></nftables>
diff --git a/tests/xmlfiles/73-set.xml b/tests/xmlfiles/73-set.xml
index 88bf402..6a9323a 100644
--- a/tests/xmlfiles/73-set.xml
+++ b/tests/xmlfiles/73-set.xml
@@ -1,2 +1 @@
-<set><family>ip</family><table>filter</table><name>set0</name><flags>0</flags><key_type>0</key_type><key_len>0</key_len><data_type>0</data_type><data_len>0</data_len><set_elem><flags>0</flags><key><data_reg type="value"><len>4</len><data0>0x0300a8c0</data0></data_reg></key></set_elem><set_elem><flags>0</flags><key><data_reg type="value"><len>4</len><data0>0x0200a8c0</data0></data_reg></key></set_elem><set_elem><flags>0</flags><key><data_reg type="value"><len>4</len><data0>0x0100a8c0</data0></data_reg></key></set_elem></set>
-<!-- nft add rule ip filter test ip daddr { 192.168.0.1, 192.168.0.2, 192.168.0.3 } tcp dport 443 counter accept -->
+<nftables><set><family>ip</family><table>filter</table><name>set0</name><flags>0</flags><key_type>0</key_type><key_len>0</key_len><data_type>0</data_type><data_len>0</data_len><set_elem><flags>0</flags><key><data_reg type="value"><len>4</len><data0>0x0300a8c0</data0></data_reg></key></set_elem><set_elem><flags>0</flags><key><data_reg type="value"><len>4</len><data0>0x0200a8c0</data0></data_reg></key></set_elem><set_elem><flags>0</flags><key><data_reg type="value"><len>4</len><data0>0x0100a8c0</data0></data_reg></key></set_elem></set></nftables>
diff --git a/tests/xmlfiles/74-set.xml b/tests/xmlfiles/74-set.xml
index 5b6e8f1..5f0e7ae 100644
--- a/tests/xmlfiles/74-set.xml
+++ b/tests/xmlfiles/74-set.xml
@@ -1,2 +1 @@
-<set><family>ip6</family><table>filter</table><name>set0</name><flags>0</flags><key_type>0</key_type><key_len>0</key_len><data_type>0</data_type><data_len>0</data_len><set_elem><flags>0</flags><key><data_reg type="value"><len>16</len><data0>0xc09a002a</data0><data1>0x2700cac1</data1><data2>0x00000000</data2><data3>0x70010000</data3></data_reg></key></set_elem><set_elem><flags>0</flags><key><data_reg type="value"><len>16</len><data0>0xc09a002a</data0><data1>0x2700cac1</data1><data2>0x00000000</data2><data3>0x50010000</data3></data_reg></key></set_elem></set>
-<!-- nft add rule ip6 filter test ip6 daddr { 2a00:9ac0:c1ca:27::150, 2a00:9ac0:c1ca:27::170, } counter accept -->
+<nftables><set><family>ip6</family><table>filter</table><name>set0</name><flags>0</flags><key_type>0</key_type><key_len>0</key_len><data_type>0</data_type><data_len>0</data_len><set_elem><flags>0</flags><key><data_reg type="value"><len>16</len><data0>0xc09a002a</data0><data1>0x2700cac1</data1><data2>0x00000000</data2><data3>0x70010000</data3></data_reg></key></set_elem><set_elem><flags>0</flags><key><data_reg type="value"><len>16</len><data0>0xc09a002a</data0><data1>0x2700cac1</data1><data2>0x00000000</data2><data3>0x50010000</data3></data_reg></key></set_elem></set></nftables>
diff --git a/tests/xmlfiles/76-rule-meta_target.xml b/tests/xmlfiles/76-rule-meta_target.xml
index 0c48ca5..970de61 100644
--- a/tests/xmlfiles/76-rule-meta_target.xml
+++ b/tests/xmlfiles/76-rule-meta_target.xml
@@ -1 +1 @@
-<rule><family>ip6</family><table>filter</table><chain>test</chain><handle>129</handle><expr type="meta"><key>mark</key><sreg>1</sreg></expr></rule>
+<nftables><rule><family>ip6</family><table>filter</table><chain>test</chain><handle>129</handle><expr type="meta"><key>mark</key><sreg>1</sreg></expr></rule></nftables>