All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/7] patches for an autotooled version of 'nftables'. (vers. 2)
@ 2014-07-07 14:19 Giorgio Dal Molin
  2014-07-07 14:19 ` [PATCH 1/7] autotool conversion: autotools support for the subdir. 'files/nftables' Giorgio Dal Molin
                   ` (7 more replies)
  0 siblings, 8 replies; 22+ messages in thread
From: Giorgio Dal Molin @ 2014-07-07 14:19 UTC (permalink / raw)
  To: netfilter-devel; +Cc: Giorgio Dal Molin

Hi,

I'm sending a couple of patches to add autotools support to the 'nftables' project.

I would like to have some feedback on it and eventually see the patches
merged on the main 'nftables' repo.

The patches are based on the version 0.3 of nftable:

commit id: ae73759150652213029718ecfa3017fa28e879c1

upstream.

The whole changes are divided in different commits for the sake of clarity
and documentation but it's not really possible to build any of the tree states
in between, only the last 'autotool conversion: ...' state is usable.

Target of these patches is a sw package that is easier to configure, cross-compile,
build in parallel also from a different build directory, and that supports
creating release tar archives.

One of my tests was to create a release distribution from there:

# cd /tmp
# mkdir nft_build
# cd nft_build
# /tmp/nftable-0.3_autotooled/autogen.sh
# /tmp/nftable-0.3_autotooled/configure
# make distcheck

The 'distcheck' target tries to configure/build/locally-install the package and if it's all
right it produces a tar archive with all that's needed for a release.

giorgio


Giorgio Dal Molin (7):
  autotool conversion: converted the subdir. 'src/'
  autotool conversion: updated the files .gitignore
  autotool conversion: use pkg-config to find 'libmnl', libnftnl' and
    'ncurses'.
  autotool conversion: Converted the support for the 'doc/' subdir.
  autotools conversion: commit the rest of the configure.ac changes.
  autotool conversion: autotools support for the subdir.
    'files/nftables'.
  autotools conversion: include the header 'config.h' in every C source
    file.

 .gitignore                   |   19 +-
 autogen.sh                   |   10 +-
 configure.ac                 |  133 ++-
 doc/Makefile.am              |   10 +
 doc/Makefile.in              |   20 -
 files/nftables/Makefile.am   |   13 +
 files/nftables/bridge-filter |    2 +-
 files/nftables/inet-filter   |    2 +-
 files/nftables/ipv4-filter   |    2 +-
 files/nftables/ipv4-mangle   |    2 +-
 files/nftables/ipv4-nat      |    2 +-
 files/nftables/ipv6-filter   |    2 +-
 files/nftables/ipv6-mangle   |    2 +-
 files/nftables/ipv6-nat      |    2 +-
 m4/ax_lib_readlibe.m4        |  107 ++
 src/.gitignore               |    4 +-
 src/Makefile.am              |   44 +
 src/Makefile.in              |   31 -
 src/cli.c                    |    3 +
 src/ct.c                     |    3 +
 src/datatype.c               |    3 +
 src/erec.c                   |    3 +
 src/evaluate.c               |    3 +
 src/expression.c             |    3 +
 src/exthdr.c                 |    3 +
 src/gmputil.c                |    3 +
 src/main.c                   |    3 +
 src/meta.c                   |    3 +
 src/mnl.c                    |    3 +
 src/netlink.c                |    3 +
 src/netlink_delinearize.c    |    3 +
 src/netlink_linearize.c      |    3 +
 src/parser.y                 | 2251 ------------------------------------------
 src/payload.c                |    3 +
 src/proto.c                  |    3 +
 src/rbtree.c                 |    3 +
 src/rule.c                   |    3 +
 src/scanner.l                |    3 +-
 src/segtree.c                |    3 +
 src/statement.c              |    3 +
 src/utils.c                  |    3 +
 src/yacc_parser.y            | 2251 ++++++++++++++++++++++++++++++++++++++++++
 42 files changed, 2605 insertions(+), 2370 deletions(-)
 create mode 100644 doc/Makefile.am
 delete mode 100644 doc/Makefile.in
 create mode 100644 files/nftables/Makefile.am
 create mode 100644 m4/ax_lib_readlibe.m4
 create mode 100644 src/Makefile.am
 delete mode 100644 src/Makefile.in
 delete mode 100644 src/parser.y
 create mode 100644 src/yacc_parser.y

-- 
2.0.1


^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH 1/7] autotool conversion: autotools support for the subdir. 'files/nftables'.
  2014-07-07 14:19 [PATCH 0/7] patches for an autotooled version of 'nftables'. (vers. 2) Giorgio Dal Molin
@ 2014-07-07 14:19 ` Giorgio Dal Molin
  2014-07-07 14:19 ` [PATCH 2/7] autotool conversion: use pkg-config to find 'libmnl', libnftnl' and 'ncurses' Giorgio Dal Molin
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 22+ messages in thread
From: Giorgio Dal Molin @ 2014-07-07 14:19 UTC (permalink / raw)
  To: netfilter-devel; +Cc: Giorgio Dal Molin

We added the marker @sbindir@ to the first line of the scripts so it
can be replaced once the scripts are installed.
---
 files/nftables/Makefile.am   | 13 +++++++++++++
 files/nftables/bridge-filter |  2 +-
 files/nftables/inet-filter   |  2 +-
 files/nftables/ipv4-filter   |  2 +-
 files/nftables/ipv4-mangle   |  2 +-
 files/nftables/ipv4-nat      |  2 +-
 files/nftables/ipv6-filter   |  2 +-
 files/nftables/ipv6-mangle   |  2 +-
 files/nftables/ipv6-nat      |  2 +-
 9 files changed, 21 insertions(+), 8 deletions(-)
 create mode 100644 files/nftables/Makefile.am

diff --git a/files/nftables/Makefile.am b/files/nftables/Makefile.am
new file mode 100644
index 0000000..32dced3
--- /dev/null
+++ b/files/nftables/Makefile.am
@@ -0,0 +1,13 @@
+
+pkgsysconfdir = ${sysconfdir}/nftables
+dist_pkgsysconf_DATA =	bridge-filter	\
+			inet-filter	\
+			ipv4-filter	\
+			ipv4-mangle	\
+			ipv4-nat	\
+			ipv6-filter	\
+			ipv6-mangle	\
+			ipv6-nat
+
+install-data-hook:
+	${SED} -i 's|@sbindir[@]|${sbindir}|g' ${DESTDIR}${pkgsysconfdir}/*
diff --git a/files/nftables/bridge-filter b/files/nftables/bridge-filter
index 54779c4..2add455 100644
--- a/files/nftables/bridge-filter
+++ b/files/nftables/bridge-filter
@@ -1,4 +1,4 @@
-#! nft -f
+#! @sbindir@nft -f
 
 table bridge filter {
 	chain input		{ type filter hook input priority -200; }
diff --git a/files/nftables/inet-filter b/files/nftables/inet-filter
index 9f3108f..f572db5 100644
--- a/files/nftables/inet-filter
+++ b/files/nftables/inet-filter
@@ -1,4 +1,4 @@
-#! nft -f
+#! @sbindir@nft -f
 
 table inet filter {
 	chain input		{ type filter hook input priority 0; }
diff --git a/files/nftables/ipv4-filter b/files/nftables/ipv4-filter
index 3174e7a..a4ca7f2 100644
--- a/files/nftables/ipv4-filter
+++ b/files/nftables/ipv4-filter
@@ -1,4 +1,4 @@
-#! nft -f
+#! @sbindir@nft -f
 
 table filter {
 	chain input		{ type filter hook input priority 0; }
diff --git a/files/nftables/ipv4-mangle b/files/nftables/ipv4-mangle
index 27327d3..be564a5 100644
--- a/files/nftables/ipv4-mangle
+++ b/files/nftables/ipv4-mangle
@@ -1,4 +1,4 @@
-#! nft -f
+#! @sbindir@nft -f
 
 table mangle {
 	chain output		{ type route hook output priority -150; }
diff --git a/files/nftables/ipv4-nat b/files/nftables/ipv4-nat
index 99d6951..01c6c3d 100644
--- a/files/nftables/ipv4-nat
+++ b/files/nftables/ipv4-nat
@@ -1,4 +1,4 @@
-#! nft -f
+#! @sbindir@nft -f
 
 table nat {
 	chain prerouting	{ type nat hook prerouting priority -150; }
diff --git a/files/nftables/ipv6-filter b/files/nftables/ipv6-filter
index 98fce02..ce4d7de 100644
--- a/files/nftables/ipv6-filter
+++ b/files/nftables/ipv6-filter
@@ -1,4 +1,4 @@
-#! nft -f
+#! @sbindir@nft -f
 
 table ip6 filter {
 	chain input		{ type filter hook input priority 0; }
diff --git a/files/nftables/ipv6-mangle b/files/nftables/ipv6-mangle
index 7274353..fa32402 100644
--- a/files/nftables/ipv6-mangle
+++ b/files/nftables/ipv6-mangle
@@ -1,4 +1,4 @@
-#! nft -f
+#! @sbindir@nft -f
 
 table ip6 mangle {
 	chain output		{ type route hook output priority -150; }
diff --git a/files/nftables/ipv6-nat b/files/nftables/ipv6-nat
index 33ecf9b..3f57c56 100644
--- a/files/nftables/ipv6-nat
+++ b/files/nftables/ipv6-nat
@@ -1,4 +1,4 @@
-#! nft -f
+#! @sbindir@nft -f
 
 table ip6 nat {
 	chain prerouting	{ type nat hook prerouting priority -150; }
-- 
2.0.1


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH 2/7] autotool conversion: use pkg-config to find 'libmnl', libnftnl' and 'ncurses'.
  2014-07-07 14:19 [PATCH 0/7] patches for an autotooled version of 'nftables'. (vers. 2) Giorgio Dal Molin
  2014-07-07 14:19 ` [PATCH 1/7] autotool conversion: autotools support for the subdir. 'files/nftables' Giorgio Dal Molin
@ 2014-07-07 14:19 ` Giorgio Dal Molin
  2014-07-07 14:19 ` [PATCH 3/7] autotool conversion: converted the subdir. 'src/' Giorgio Dal Molin
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 22+ messages in thread
From: Giorgio Dal Molin @ 2014-07-07 14:19 UTC (permalink / raw)
  To: netfilter-devel; +Cc: Giorgio Dal Molin

Use pkg-config to find the compile and link flags for 'libnftnl' and
'libmnl'.

Use the special macro AX_LIB_READLINE to check for libreadline and its
dependencies.

The macro is part of the 'autoconf-archive' project:

https://www.gnu.org/software/autoconf-archive/ax_lib_readline.html
---
 configure.ac          |  15 ++++---
 m4/ax_lib_readlibe.m4 | 107 ++++++++++++++++++++++++++++++++++++++++++++++++++
 src/Makefile.am       |  44 +++++++++++++++++++++
 3 files changed, 158 insertions(+), 8 deletions(-)
 create mode 100644 m4/ax_lib_readlibe.m4
 create mode 100644 src/Makefile.am

diff --git a/configure.ac b/configure.ac
index 3a7647f..605d39d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -62,17 +62,16 @@ then
 fi
 
 # Checks for libraries.
-AC_CHECK_LIB([mnl], [mnl_socket_open], ,
-	     AC_MSG_ERROR([No suitable version of libmnl found]))
 
-AC_CHECK_LIB([nftnl], [nft_rule_alloc], ,
-	     AC_MSG_ERROR([No suitable version of libnftnl found]))
+dnl Check for package libnftnl
+PKG_CHECK_MODULES(LIBMNL, [libmnl], , AC_MSG_ERROR([No suitable version of libmnl found]))
 
-AC_CHECK_LIB([gmp], [__gmpz_init], ,
-	     AC_MSG_ERROR([No suitable version of libgmp found]))
+dnl Check for package libnftnl
+PKG_CHECK_MODULES(LIBNFTNL, [libnftnl], , AC_MSG_ERROR([No suitable version of libnftnl found]))
 
-AC_CHECK_LIB([readline], [readline], ,
-	     AC_MSG_ERROR([No suitable version of libreadline found]))
+AC_CHECK_LIB([gmp], [__gmpz_init], , AC_MSG_ERROR([No suitable version of libgmp found]))
+
+AX_LIB_READLINE
 
 # Checks for header files.
 AC_HEADER_STDC
diff --git a/m4/ax_lib_readlibe.m4 b/m4/ax_lib_readlibe.m4
new file mode 100644
index 0000000..056f25c
--- /dev/null
+++ b/m4/ax_lib_readlibe.m4
@@ -0,0 +1,107 @@
+# ===========================================================================
+#      http://www.gnu.org/software/autoconf-archive/ax_lib_readline.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+#   AX_LIB_READLINE
+#
+# DESCRIPTION
+#
+#   Searches for a readline compatible library. If found, defines
+#   `HAVE_LIBREADLINE'. If the found library has the `add_history' function,
+#   sets also `HAVE_READLINE_HISTORY'. Also checks for the locations of the
+#   necessary include files and sets `HAVE_READLINE_H' or
+#   `HAVE_READLINE_READLINE_H' and `HAVE_READLINE_HISTORY_H' or
+#   'HAVE_HISTORY_H' if the corresponding include files exists.
+#
+#   The libraries that may be readline compatible are `libedit',
+#   `libeditline' and `libreadline'. Sometimes we need to link a termcap
+#   library for readline to work, this macro tests these cases too by trying
+#   to link with `libtermcap', `libcurses' or `libncurses' before giving up.
+#
+#   Here is an example of how to use the information provided by this macro
+#   to perform the necessary includes or declarations in a C file:
+#
+#     #ifdef HAVE_LIBREADLINE
+#     #  if defined(HAVE_READLINE_READLINE_H)
+#     #    include <readline/readline.h>
+#     #  elif defined(HAVE_READLINE_H)
+#     #    include <readline.h>
+#     #  else /* !defined(HAVE_READLINE_H) */
+#     extern char *readline ();
+#     #  endif /* !defined(HAVE_READLINE_H) */
+#     char *cmdline = NULL;
+#     #else /* !defined(HAVE_READLINE_READLINE_H) */
+#       /* no readline */
+#     #endif /* HAVE_LIBREADLINE */
+#
+#     #ifdef HAVE_READLINE_HISTORY
+#     #  if defined(HAVE_READLINE_HISTORY_H)
+#     #    include <readline/history.h>
+#     #  elif defined(HAVE_HISTORY_H)
+#     #    include <history.h>
+#     #  else /* !defined(HAVE_HISTORY_H) */
+#     extern void add_history ();
+#     extern int write_history ();
+#     extern int read_history ();
+#     #  endif /* defined(HAVE_READLINE_HISTORY_H) */
+#       /* no history */
+#     #endif /* HAVE_READLINE_HISTORY */
+#
+# LICENSE
+#
+#   Copyright (c) 2008 Ville Laurikari <vl@iki.fi>
+#
+#   Copying and distribution of this file, with or without modification, are
+#   permitted in any medium without royalty provided the copyright notice
+#   and this notice are preserved. This file is offered as-is, without any
+#   warranty.
+
+#serial 6
+
+AU_ALIAS([VL_LIB_READLINE], [AX_LIB_READLINE])
+AC_DEFUN([AX_LIB_READLINE], [
+  AC_CACHE_CHECK([for a readline compatible library],
+                 ax_cv_lib_readline, [
+    ORIG_LIBS="$LIBS"
+    for readline_lib in readline edit editline; do
+      for termcap_lib in "" termcap curses ncurses; do
+        if test -z "$termcap_lib"; then
+          TRY_LIB="-l$readline_lib"
+        else
+          TRY_LIB="-l$readline_lib -l$termcap_lib"
+        fi
+        LIBS="$ORIG_LIBS $TRY_LIB"
+        AC_TRY_LINK_FUNC(readline, ax_cv_lib_readline="$TRY_LIB")
+        if test -n "$ax_cv_lib_readline"; then
+          break
+        fi
+      done
+      if test -n "$ax_cv_lib_readline"; then
+        break
+      fi
+    done
+    if test -z "$ax_cv_lib_readline"; then
+      ax_cv_lib_readline="no"
+    fi
+    LIBS="$ORIG_LIBS"
+  ])
+
+  if test "$ax_cv_lib_readline" != "no"; then
+    LIBS="$LIBS $ax_cv_lib_readline"
+    AC_DEFINE(HAVE_LIBREADLINE, 1,
+              [Define if you have a readline compatible library])
+    AC_CHECK_HEADERS(readline.h readline/readline.h)
+    AC_CACHE_CHECK([whether readline supports history],
+                   ax_cv_lib_readline_history, [
+      ax_cv_lib_readline_history="no"
+      AC_TRY_LINK_FUNC(add_history, ax_cv_lib_readline_history="yes")
+    ])
+    if test "$ax_cv_lib_readline_history" = "yes"; then
+      AC_DEFINE(HAVE_READLINE_HISTORY, 1,
+                [Define if your readline library has \`add_history'])
+      AC_CHECK_HEADERS(history.h readline/history.h)
+    fi
+  fi
+])dnl
diff --git a/src/Makefile.am b/src/Makefile.am
new file mode 100644
index 0000000..5f19732
--- /dev/null
+++ b/src/Makefile.am
@@ -0,0 +1,44 @@
+sbin_PROGRAMS = nft
+
+nft_CFLAGS =	-fno-strict-aliasing							\
+		-Wall									\
+		-Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations		\
+		-Wdeclaration-after-statement -Wsign-compare -Winit-self		\
+		-Wformat-nonliteral -Wformat-security -Wmissing-format-attribute	\
+		-Wcast-align -Wundef -Wbad-function-cast				\
+		-Waggregate-return -Wunused -Wwrite-strings
+
+nft_CPPFLAGS = -I${srcdir}/../include ${LIBMNL_CFLAGS} ${LIBNFTNL_CFLAGS}
+
+nft_LDADD = ${LIBMNL_LIBS} ${LIBNFTNL_LIBS}
+
+AM_YFLAGS = -d
+BUILT_SOURCES =	scanner.c scanner.h yacc_parser.c yacc_parser.h
+
+scanner.h: scanner.c
+
+nft_SOURCES = 	main.c				\
+		cli.c				\
+		rule.c				\
+		statement.c			\
+		datatype.c			\
+		expression.c			\
+		evaluate.c			\
+		proto.c				\
+		payload.c			\
+		exthdr.c			\
+		meta.c				\
+		ct.c				\
+		netlink.c			\
+		netlink_linearize.c		\
+		netlink_delinearize.c		\
+		segtree.c			\
+		rbtree.c			\
+		gmputil.c			\
+		utils.c				\
+		erec.c				\
+		mnl.c				\
+		scanner.l			\
+		yacc_parser.y
+
+CLEANFILES = *~ scanner.c scanner.h yacc_parser.c yacc_parser.h
-- 
2.0.1


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH 3/7] autotool conversion: converted the subdir. 'src/'
  2014-07-07 14:19 [PATCH 0/7] patches for an autotooled version of 'nftables'. (vers. 2) Giorgio Dal Molin
  2014-07-07 14:19 ` [PATCH 1/7] autotool conversion: autotools support for the subdir. 'files/nftables' Giorgio Dal Molin
  2014-07-07 14:19 ` [PATCH 2/7] autotool conversion: use pkg-config to find 'libmnl', libnftnl' and 'ncurses' Giorgio Dal Molin
@ 2014-07-07 14:19 ` Giorgio Dal Molin
  2014-07-10 10:08   ` Pablo Neira Ayuso
  2014-07-07 14:19 ` [PATCH 4/7] autotools conversion: include the header 'config.h' in every C source file Giorgio Dal Molin
                   ` (4 subsequent siblings)
  7 siblings, 1 reply; 22+ messages in thread
From: Giorgio Dal Molin @ 2014-07-07 14:19 UTC (permalink / raw)
  To: netfilter-devel; +Cc: Giorgio Dal Molin

Use specialized test macros to find 'yacc' and 'lex' in the configure.ac.

Renamed the file 'src/parser.y' to 'src/yacc_parser.y' to avoid having
two header files with the same name, 'parser.h': one under 'src/',
generated by 'yacc' from 'parser.y' and the other under 'include/'.

Added an %option line to 'src/scanner.l': this new %option directive
lets us save a custom recipe in the 'src/Makefile.am'; it replaces the
'lex' command line option '--outfile=scanner.c'.
We don't have any explicit make recipe to call 'lex' on 'scanner.l' to
generate 'scanner.c' and 'scanner.h' as in the old 'Makefile.rules';
listing the file 'scanner.l' in the variable 'nft_SOURCES' of
'src/Makefile.am' is now enough.
---
 configure.ac      |   13 +-
 src/Makefile.in   |   31 -
 src/parser.y      | 2251 -----------------------------------------------------
 src/scanner.l     |    3 +-
 src/yacc_parser.y | 2251 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 2255 insertions(+), 2294 deletions(-)
 delete mode 100644 src/Makefile.in
 delete mode 100644 src/parser.y
 create mode 100644 src/yacc_parser.y

diff --git a/configure.ac b/configure.ac
index 605d39d..900b26a 100644
--- a/configure.ac
+++ b/configure.ac
@@ -24,6 +24,8 @@ AC_PROG_CC
 AC_PROG_MKDIR_P
 AC_PROG_INSTALL
 AC_PROG_SED
+AC_PROG_YACC
+AM_PROG_LEX
 
 AC_CHECK_PROG(CONFIG_MAN1, [docbook2x-man], [y], [n])
 if test "$CONFIG_MAN1" == "y"
@@ -49,17 +51,6 @@ then
 	AC_MSG_WARN([dblatex not found, no PDF manpages will be built])
 fi
 
-AC_PATH_PROG(LEX, [flex])
-if test -z "$LEX"
-then
-	AC_MSG_ERROR([No suitable version of flex found])
-fi
-
-AC_PATH_PROG(YACC, [bison])
-if test -z "$YACC"
-then
-	AC_MSG_ERROR([No suitable version of bison found])
-fi
 
 # Checks for libraries.
 
diff --git a/src/Makefile.in b/src/Makefile.in
deleted file mode 100644
index 8ac2b46..0000000
--- a/src/Makefile.in
+++ /dev/null
@@ -1,31 +0,0 @@
-PROGRAMS		+= nft
-
-nft-destdir		:= @sbindir@
-
-nft-obj			+= main.o
-nft-obj			+= cli.o
-nft-obj			+= rule.o
-nft-obj			+= statement.o
-nft-obj			+= datatype.o
-nft-obj			+= expression.o
-nft-obj			+= evaluate.o
-nft-obj			+= proto.o
-nft-obj			+= payload.o
-nft-obj			+= exthdr.o
-nft-obj			+= meta.o
-nft-obj			+= ct.o
-nft-obj			+= netlink.o
-nft-obj			+= netlink_linearize.o
-nft-obj			+= netlink_delinearize.o
-nft-obj			+= segtree.o
-nft-obj			+= rbtree.o
-nft-obj			+= gmputil.o
-nft-obj			+= utils.o
-nft-obj			+= erec.o
-nft-obj			+= mnl.o
-
-nft-obj			+= parser.o
-nft-extra-clean-files	+= parser.c parser.h
-
-nft-obj			+= scanner.o
-nft-extra-clean-files	+= scanner.c scanner.h
diff --git a/src/parser.y b/src/parser.y
deleted file mode 100644
index 3e08e21..0000000
--- a/src/parser.y
+++ /dev/null
@@ -1,2251 +0,0 @@
-/*
- * Copyright (c) 2007-2012 Patrick McHardy <kaber@trash.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * Development of this code funded by Astaro AG (http://www.astaro.com/)
- */
-
-%{
-
-#include <stddef.h>
-#include <stdio.h>
-#include <inttypes.h>
-#include <netinet/ip.h>
-#include <netinet/if_ether.h>
-#include <linux/netfilter.h>
-#include <linux/netfilter/nf_tables.h>
-#include <linux/netfilter/nf_conntrack_tuple_common.h>
-#include <libnftnl/common.h>
-
-#include <rule.h>
-#include <statement.h>
-#include <expression.h>
-#include <utils.h>
-#include <parser.h>
-#include <erec.h>
-
-#include "parser.h"
-#include "scanner.h"
-
-void parser_init(struct parser_state *state, struct list_head *msgs)
-{
-	memset(state, 0, sizeof(*state));
-	init_list_head(&state->cmds);
-	init_list_head(&state->top_scope.symbols);
-	state->msgs = msgs;
-	state->scopes[0] = scope_init(&state->top_scope, NULL);
-	state->ectx.msgs = msgs;
-}
-
-static void yyerror(struct location *loc, void *scanner,
-		    struct parser_state *state, const char *s)
-{
-	erec_queue(error(loc, "%s", s), state->msgs);
-}
-
-static struct scope *current_scope(const struct parser_state *state)
-{
-	return state->scopes[state->scope];
-}
-
-static void open_scope(struct parser_state *state, struct scope *scope)
-{
-	assert(state->scope < array_size(state->scopes) - 1);
-	scope_init(scope, current_scope(state));
-	state->scopes[++state->scope] = scope;
-}
-
-static void close_scope(struct parser_state *state)
-{
-	assert(state->scope > 0);
-	state->scope--;
-}
-
-static void location_init(void *scanner, struct parser_state *state,
-			  struct location *loc)
-{
-	memset(loc, 0, sizeof(*loc));
-	loc->indesc = state->indesc;
-}
-
-static void location_update(struct location *loc, struct location *rhs, int n)
-{
-	if (n) {
-		loc->indesc       = rhs[n].indesc;
-		loc->token_offset = rhs[1].token_offset;
-		loc->line_offset  = rhs[1].line_offset;
-		loc->first_line   = rhs[1].first_line;
-		loc->first_column = rhs[1].first_column;
-		loc->last_line    = rhs[n].last_line;
-		loc->last_column  = rhs[n].last_column;
-	} else {
-		loc->indesc       = rhs[0].indesc;
-		loc->token_offset = rhs[0].token_offset;
-		loc->line_offset  = rhs[0].line_offset;
-		loc->first_line   = loc->last_line   = rhs[0].last_line;
-		loc->first_column = loc->last_column = rhs[0].last_column;
-	}
-}
-
-#define YYLLOC_DEFAULT(Current, Rhs, N)	location_update(&Current, Rhs, N)
-
-enum {
-	NFT_EVENT_NEW	= 0,
-	NFT_EVENT_DEL,
-};
-
-static int monitor_lookup_event(const char *event)
-{
-	if (strcmp(event, "new") == 0)
-		return NFT_EVENT_NEW;
-	else if (strcmp(event, "destroy") == 0)
-		return NFT_EVENT_DEL;
-
-	return -1;
-}
-
-%}
-
-/* Declaration section */
-
-%name-prefix "nft_"
-%debug
-%pure-parser
-%parse-param		{ void *scanner }
-%parse-param		{ struct parser_state *state }
-%lex-param		{ scanner }
-%error-verbose
-%locations
-
-%initial-action {
-	location_init(scanner, state, &yylloc);
-#ifdef DEBUG
-	if (debug_level & DEBUG_SCANNER)
-		nft_set_debug(1, scanner);
-	if (debug_level & DEBUG_PARSER)
-		yydebug = 1;
-#endif
-}
-
-%union {
-	uint64_t		val;
-	const char *		string;
-
-	struct list_head	*list;
-	struct cmd		*cmd;
-	struct handle		handle;
-	struct table		*table;
-	struct chain		*chain;
-	struct rule		*rule;
-	struct stmt		*stmt;
-	struct expr		*expr;
-	struct set		*set;
-}
-
-%token TOKEN_EOF 0		"end of file"
-%token JUNK			"junk"
-
-%token NEWLINE			"newline"
-%token COLON			"colon"
-%token SEMICOLON		"semicolon"
-%token COMMA			"comma"
-%token DOT			"."
-
-%token EQ			"=="
-%token NEQ			"!="
-%token LT			"<"
-%token GT			">"
-%token GTE			">="
-%token LTE			"<="
-%token LSHIFT			"<<"
-%token RSHIFT			">>"
-%token AMPERSAND		"&"
-%token CARET			"^"
-%token NOT			"!"
-%token SLASH			"/"
-%token ASTERISK			"*"
-%token DASH			"-"
-%token AT			"@"
-%token VMAP			"vmap"
-
-%token INCLUDE			"include"
-%token DEFINE			"define"
-
-%token HOOK			"hook"
-%token TABLE			"table"
-%token TABLES			"tables"
-%token CHAIN			"chain"
-%token CHAINS			"chains"
-%token RULE			"rule"
-%token RULES			"rules"
-%token SETS			"sets"
-%token SET			"set"
-%token ELEMENT			"element"
-%token MAP			"map"
-%token HANDLE			"handle"
-
-%token INET			"inet"
-
-%token ADD			"add"
-%token CREATE			"create"
-%token INSERT			"insert"
-%token DELETE			"delete"
-%token LIST			"list"
-%token FLUSH			"flush"
-%token RENAME			"rename"
-%token DESCRIBE			"describe"
-%token EXPORT			"export"
-%token MONITOR			"monitor"
-
-%token ACCEPT			"accept"
-%token DROP			"drop"
-%token CONTINUE			"continue"
-%token JUMP			"jump"
-%token GOTO			"goto"
-%token RETURN			"return"
-
-%token CONSTANT			"constant"
-%token INTERVAL			"interval"
-%token ELEMENTS			"elements"
-
-%token <val> NUM		"number"
-%token <string> STRING		"string"
-%token <string> QUOTED_STRING
-%destructor { xfree($$); }	STRING QUOTED_STRING
-
-%token LL_HDR			"ll"
-%token NETWORK_HDR		"nh"
-%token TRANSPORT_HDR		"th"
-
-%token BRIDGE			"bridge"
-
-%token ETHER			"ether"
-%token SADDR			"saddr"
-%token DADDR			"daddr"
-%token TYPE			"type"
-
-%token VLAN			"vlan"
-%token ID			"id"
-%token CFI			"cfi"
-%token PCP			"pcp"
-
-%token ARP			"arp"
-%token HTYPE			"htype"
-%token PTYPE			"ptype"
-%token HLEN			"hlen"
-%token PLEN			"plen"
-%token OPERATION		"operation"
-
-%token IP			"ip"
-%token VERSION			"version"
-%token HDRLENGTH		"hdrlength"
-%token TOS			"tos"
-%token LENGTH			"length"
-%token FRAG_OFF			"frag-off"
-%token TTL			"ttl"
-%token PROTOCOL			"protocol"
-%token CHECKSUM			"checksum"
-
-%token ICMP			"icmp"
-%token CODE			"code"
-%token SEQUENCE			"seq"
-%token GATEWAY			"gateway"
-%token MTU			"mtu"
-
-%token IP6			"ip6"
-%token PRIORITY			"priority"
-%token FLOWLABEL		"flowlabel"
-%token NEXTHDR			"nexthdr"
-%token HOPLIMIT			"hoplimit"
-
-%token ICMP6			"icmpv6"
-%token PPTR			"param-problem"
-%token MAXDELAY			"max-delay"
-
-%token AH			"ah"
-%token RESERVED			"reserved"
-%token SPI			"spi"
-
-%token ESP			"esp"
-
-%token COMP			"comp"
-%token FLAGS			"flags"
-%token CPI			"cpi"
-
-%token UDP			"udp"
-%token SPORT			"sport"
-%token DPORT			"dport"
-%token UDPLITE			"udplite"
-%token CSUMCOV			"csumcov"
-
-%token TCP			"tcp"
-%token ACKSEQ			"ackseq"
-%token DOFF			"doff"
-%token WINDOW			"window"
-%token URGPTR			"urgptr"
-
-%token DCCP			"dccp"
-
-%token SCTP			"sctp"
-%token VTAG			"vtag"
-
-%token RT			"rt"
-%token RT0			"rt0"
-%token RT2			"rt2"
-%token SEG_LEFT			"seg-left"
-%token ADDR			"addr"
-
-%token HBH			"hbh"
-
-%token FRAG			"frag"
-%token RESERVED2		"reserved2"
-%token MORE_FRAGMENTS		"more-fragments"
-
-%token DST			"dst"
-
-%token MH			"mh"
-
-%token META			"meta"
-%token NFPROTO			"nfproto"
-%token L4PROTO			"l4proto"
-%token MARK			"mark"
-%token IIF			"iif"
-%token IIFNAME			"iifname"
-%token IIFTYPE			"iiftype"
-%token OIF			"oif"
-%token OIFNAME			"oifname"
-%token OIFTYPE			"oiftype"
-%token SKUID			"skuid"
-%token SKGID			"skgid"
-%token NFTRACE			"nftrace"
-%token RTCLASSID		"rtclassid"
-%token IBRIPORT			"ibriport"
-%token OBRIPORT			"obriport"
-
-%token CT			"ct"
-%token DIRECTION		"direction"
-%token STATE			"state"
-%token STATUS			"status"
-%token EXPIRATION		"expiration"
-%token HELPER			"helper"
-%token L3PROTOCOL		"l3proto"
-%token PROTO_SRC		"proto-src"
-%token PROTO_DST		"proto-dst"
-%token LABEL			"label"
-
-%token COUNTER			"counter"
-%token PACKETS			"packets"
-%token BYTES			"bytes"
-
-%token LOG			"log"
-%token PREFIX			"prefix"
-%token GROUP			"group"
-%token SNAPLEN			"snaplen"
-%token QUEUE_THRESHOLD		"queue-threshold"
-
-%token LIMIT			"limit"
-%token RATE			"rate"
-
-%token NANOSECOND		"nanosecond"
-%token MICROSECOND		"microsecond"
-%token MILLISECOND		"millisecond"
-%token SECOND			"second"
-%token MINUTE			"minute"
-%token HOUR			"hour"
-%token DAY			"day"
-%token WEEK			"week"
-
-%token _REJECT			"reject"
-
-%token SNAT			"snat"
-%token DNAT			"dnat"
-
-%token QUEUE			"queue"
-%token QUEUENUM			"num"
-%token QUEUEBYPASS		"bypass"
-%token QUEUECPUFANOUT		"fanout"
-
-%token POSITION			"position"
-%token COMMENT			"comment"
-
-%token XML			"xml"
-%token JSON			"json"
-
-%type <string>			identifier string comment_spec
-%destructor { xfree($$); }	identifier string comment_spec
-
-%type <cmd>			line
-%destructor { cmd_free($$); }	line
-
-%type <cmd>			base_cmd add_cmd create_cmd insert_cmd delete_cmd list_cmd flush_cmd rename_cmd export_cmd monitor_cmd
-%destructor { cmd_free($$); }	base_cmd add_cmd create_cmd insert_cmd delete_cmd list_cmd flush_cmd rename_cmd export_cmd monitor_cmd
-
-%type <handle>			table_spec tables_spec chain_spec chain_identifier ruleid_spec
-%destructor { handle_free(&$$); } table_spec tables_spec chain_spec chain_identifier ruleid_spec
-%type <handle>			set_spec set_identifier
-%destructor { handle_free(&$$); } set_spec set_identifier
-%type <val>			handle_spec family_spec position_spec
-
-%type <table>			table_block_alloc table_block
-%destructor { close_scope(state); table_free($$); }	table_block_alloc
-%type <chain>			chain_block_alloc chain_block
-%destructor { close_scope(state); chain_free($$); }	chain_block_alloc
-%type <rule>			rule
-%destructor { rule_free($$); }	rule
-
-%type <val>			set_flag_list	set_flag
-
-%type <set>			set_block_alloc set_block
-%destructor { set_free($$); }	set_block_alloc
-
-%type <set>			map_block_alloc map_block
-%destructor { set_free($$); }	map_block_alloc
-
-%type <list>			stmt_list
-%destructor { stmt_list_free($$); xfree($$); } stmt_list
-%type <stmt>			stmt match_stmt verdict_stmt
-%destructor { stmt_free($$); }	stmt match_stmt verdict_stmt
-%type <stmt>			counter_stmt counter_stmt_alloc
-%destructor { stmt_free($$); }	counter_stmt counter_stmt_alloc
-%type <stmt>			ct_stmt
-%destructor { stmt_free($$); }	ct_stmt
-%type <stmt>			meta_stmt
-%destructor { stmt_free($$); }	meta_stmt
-%type <stmt>			log_stmt log_stmt_alloc
-%destructor { stmt_free($$); }	log_stmt log_stmt_alloc
-%type <stmt>			limit_stmt
-%destructor { stmt_free($$); }	limit_stmt
-%type <val>			time_unit
-%type <stmt>			reject_stmt
-%destructor { stmt_free($$); }	reject_stmt
-%type <stmt>			nat_stmt nat_stmt_alloc
-%destructor { stmt_free($$); }	nat_stmt nat_stmt_alloc
-%type <stmt>			queue_stmt queue_stmt_alloc queue_range
-%destructor { stmt_free($$); }	queue_stmt queue_stmt_alloc
-%type <val>			queue_flags queue_flag
-
-%type <expr>			symbol_expr verdict_expr integer_expr
-%destructor { expr_free($$); }	symbol_expr verdict_expr integer_expr
-%type <expr>			primary_expr shift_expr and_expr
-%destructor { expr_free($$); }	primary_expr shift_expr and_expr
-%type <expr>			exclusive_or_expr inclusive_or_expr
-%destructor { expr_free($$); }	exclusive_or_expr inclusive_or_expr
-%type <expr>			basic_expr
-%destructor { expr_free($$); }	basic_expr
-
-%type <expr>			multiton_expr
-%destructor { expr_free($$); }	multiton_expr
-%type <expr>			prefix_expr range_expr wildcard_expr
-%destructor { expr_free($$); }	prefix_expr range_expr wildcard_expr
-%type <expr>			list_expr
-%destructor { expr_free($$); }	list_expr
-%type <expr>			concat_expr map_lhs_expr
-%destructor { expr_free($$); }	concat_expr map_lhs_expr
-
-%type <expr>			map_expr
-%destructor { expr_free($$); }	map_expr
-
-%type <expr>			verdict_map_stmt
-%destructor { expr_free($$); }	verdict_map_stmt
-
-%type <expr>			verdict_map_expr verdict_map_list_expr verdict_map_list_member_expr
-%destructor { expr_free($$); }	verdict_map_expr verdict_map_list_expr verdict_map_list_member_expr
-
-%type <expr>			set_expr set_list_expr set_list_member_expr
-%destructor { expr_free($$); }	set_expr set_list_expr set_list_member_expr
-
-%type <expr>			expr initializer_expr
-%destructor { expr_free($$); }	expr initializer_expr
-
-%type <expr>			relational_expr
-%destructor { expr_free($$); }	relational_expr
-%type <val>			relational_op
-
-%type <expr>			payload_expr payload_raw_expr
-%destructor { expr_free($$); }	payload_expr payload_raw_expr
-%type <val>			payload_base_spec
-%type <expr>			eth_hdr_expr	vlan_hdr_expr
-%destructor { expr_free($$); }	eth_hdr_expr	vlan_hdr_expr
-%type <val>			eth_hdr_field	vlan_hdr_field
-%type <expr>			arp_hdr_expr
-%destructor { expr_free($$); }	arp_hdr_expr
-%type <val>			arp_hdr_field
-%type <expr>			ip_hdr_expr	icmp_hdr_expr
-%destructor { expr_free($$); }	ip_hdr_expr	icmp_hdr_expr
-%type <val>			ip_hdr_field	icmp_hdr_field
-%type <expr>			ip6_hdr_expr    icmp6_hdr_expr
-%destructor { expr_free($$); }	ip6_hdr_expr	icmp6_hdr_expr
-%type <val>			ip6_hdr_field   icmp6_hdr_field
-%type <expr>			auth_hdr_expr	esp_hdr_expr		comp_hdr_expr
-%destructor { expr_free($$); }	auth_hdr_expr	esp_hdr_expr		comp_hdr_expr
-%type <val>			auth_hdr_field	esp_hdr_field		comp_hdr_field
-%type <expr>			udp_hdr_expr	udplite_hdr_expr	tcp_hdr_expr
-%destructor { expr_free($$); }	udp_hdr_expr	udplite_hdr_expr	tcp_hdr_expr
-%type <val>			udp_hdr_field	udplite_hdr_field	tcp_hdr_field
-%type <expr>			dccp_hdr_expr	sctp_hdr_expr
-%destructor { expr_free($$); }	dccp_hdr_expr	sctp_hdr_expr
-%type <val>			dccp_hdr_field	sctp_hdr_field
-
-%type <expr>			exthdr_expr
-%destructor { expr_free($$); }	exthdr_expr
-%type <expr>			hbh_hdr_expr	frag_hdr_expr		dst_hdr_expr
-%destructor { expr_free($$); }	hbh_hdr_expr	frag_hdr_expr		dst_hdr_expr
-%type <val>			hbh_hdr_field	frag_hdr_field		dst_hdr_field
-%type <expr>			rt_hdr_expr	rt0_hdr_expr		rt2_hdr_expr
-%destructor { expr_free($$); }	rt_hdr_expr	rt0_hdr_expr		rt2_hdr_expr
-%type <val>			rt_hdr_field	rt0_hdr_field		rt2_hdr_field
-%type <expr>			mh_hdr_expr
-%destructor { expr_free($$); }	mh_hdr_expr
-%type <val>			mh_hdr_field
-
-%type <expr>			meta_expr
-%destructor { expr_free($$); }	meta_expr
-%type <val>			meta_key	meta_key_qualified	meta_key_unqualified
-
-%type <expr>			ct_expr
-%destructor { expr_free($$); }	ct_expr
-%type <val>			ct_key
-
-%type <val>			export_format	output_format	monitor_flags
-
-%%
-
-input			:	/* empty */
-			|	input		line
-			{
-				if ($2 != NULL) {
-					LIST_HEAD(list);
-
-					$2->location = @2;
-
-					list_add_tail(&$2->list, &list);
-					if (cmd_evaluate(&state->ectx, $2) < 0) {
-						if (++state->nerrs == max_errors)
-							YYABORT;
-					} else
-						list_splice_tail(&list, &state->cmds);
-				}
-			}
-			;
-
-stmt_seperator		:	NEWLINE
-			|	SEMICOLON
-			;
-
-opt_newline		:	NEWLINE
-		 	|	/* empty */
-			;
-
-common_block		:	INCLUDE		QUOTED_STRING	stmt_seperator
-			{
-				if (scanner_include_file(scanner, $2, &@$) < 0) {
-					xfree($2);
-					YYERROR;
-				}
-				xfree($2);
-			}
-			|	DEFINE		identifier	'='	initializer_expr	stmt_seperator
-			{
-				struct scope *scope = current_scope(state);
-
-				if (symbol_lookup(scope, $2) != NULL) {
-					erec_queue(error(&@2, "redfinition of symbol '%s'", $2),
-						   state->msgs);
-					YYERROR;
-				}
-
-				symbol_bind(scope, $2, $4);
-				xfree($2);
-			}
-			|	error		stmt_seperator
-			{
-				if (++state->nerrs == max_errors)
-					YYABORT;
-				yyerrok;
-			}
-			;
-
-line			:	common_block			{ $$ = NULL; }
-			|	stmt_seperator			{ $$ = NULL; }
-			|	base_cmd	stmt_seperator	{ $$ = $1; }
-			|	base_cmd	TOKEN_EOF
-			{
-				/*
-				 * Very hackish workaround for bison >= 2.4: previous versions
-				 * terminated parsing after EOF, 2.4+ tries to get further input
-				 * in 'input' and calls the scanner again, causing a crash when
-				 * the final input buffer has been popped. Terminate manually to
-				 * avoid this. The correct fix should be to adjust the grammar
-				 * to accept EOF in input, but for unknown reasons it does not
-				 * work.
-				 */
-				if ($1 != NULL) {
-					LIST_HEAD(list);
-
-					$1->location = @1;
-
-					list_add_tail(&$1->list, &list);
-					if (cmd_evaluate(&state->ectx, $1) < 0) {
-						if (++state->nerrs == max_errors)
-							YYABORT;
-					} else
-						list_splice_tail(&list, &state->cmds);
-				}
-				$$ = NULL;
-
-				YYACCEPT;
-			}
-			;
-
-base_cmd		:	/* empty */	add_cmd		{ $$ = $1; }
-	  		|	ADD		add_cmd		{ $$ = $2; }
-			|	CREATE		create_cmd	{ $$ = $2; }
-			|	INSERT		insert_cmd	{ $$ = $2; }
-			|	DELETE		delete_cmd	{ $$ = $2; }
-			|	LIST		list_cmd	{ $$ = $2; }
-			|	FLUSH		flush_cmd	{ $$ = $2; }
-			|	RENAME		rename_cmd	{ $$ = $2; }
-			|	EXPORT		export_cmd	{ $$ = $2; }
-			|	MONITOR		monitor_cmd	{ $$ = $2; }
-			|	DESCRIBE	primary_expr
-			{
-				expr_describe($2);
-				expr_free($2);
-				$$ = NULL;
-			}
-			;
-
-add_cmd			:	TABLE		table_spec
-			{
-				$$ = cmd_alloc(CMD_ADD, CMD_OBJ_TABLE, &$2, &@$, NULL);
-			}
-			|	TABLE		table_spec	table_block_alloc
-						'{'	table_block	'}'
-			{
-				handle_merge(&$3->handle, &$2);
-				close_scope(state);
-				$$ = cmd_alloc(CMD_ADD, CMD_OBJ_TABLE, &$2, &@$, $5);
-			}
-			|	CHAIN		chain_spec
-			{
-				$$ = cmd_alloc(CMD_ADD, CMD_OBJ_CHAIN, &$2, &@$, NULL);
-			}
-			|	CHAIN		chain_spec	chain_block_alloc
-						'{'	chain_block	'}'
-			{
-				$5->location = @5;
-				handle_merge(&$3->handle, &$2);
-				close_scope(state);
-				$$ = cmd_alloc(CMD_ADD, CMD_OBJ_CHAIN, &$2, &@$, $5);
-			}
-			|	RULE		ruleid_spec	rule
-			{
-				$$ = cmd_alloc(CMD_ADD, CMD_OBJ_RULE, &$2, &@$, $3);
-			}
-			|	/* empty */	ruleid_spec	rule
-			{
-				$$ = cmd_alloc(CMD_ADD, CMD_OBJ_RULE, &$1, &@$, $2);
-			}
-			|	SET		set_spec	set_block_alloc
-						'{'	set_block	'}'
-			{
-				$5->location = @5;
-				handle_merge(&$3->handle, &$2);
-				$$ = cmd_alloc(CMD_ADD, CMD_OBJ_SET, &$2, &@$, $5);
-			}
-			|	MAP		set_spec	map_block_alloc
-						'{'	map_block	'}'
-			{
-				$5->location = @5;
-				handle_merge(&$3->handle, &$2);
-				$$ = cmd_alloc(CMD_ADD, CMD_OBJ_SET, &$2, &@$, $5);
-			}
-			|	ELEMENT		set_spec	set_expr
-			{
-				$$ = cmd_alloc(CMD_ADD, CMD_OBJ_SETELEM, &$2, &@$, $3);
-			}
-			;
-
-create_cmd		:	TABLE		table_spec
-			{
-				$$ = cmd_alloc(CMD_CREATE, CMD_OBJ_TABLE, &$2, &@$, NULL);
-			}
-			|	TABLE		table_spec	table_block_alloc
-						'{'	table_block	'}'
-			{
-				handle_merge(&$3->handle, &$2);
-				close_scope(state);
-				$$ = cmd_alloc(CMD_CREATE, CMD_OBJ_TABLE, &$2, &@$, $5);
-			}
-			|	CHAIN		chain_spec
-			{
-				$$ = cmd_alloc(CMD_CREATE, CMD_OBJ_CHAIN, &$2, &@$, NULL);
-			}
-			|	CHAIN		chain_spec	chain_block_alloc
-						'{'	chain_block	'}'
-			{
-				$5->location = @5;
-				handle_merge(&$3->handle, &$2);
-				close_scope(state);
-				$$ = cmd_alloc(CMD_CREATE, CMD_OBJ_CHAIN, &$2, &@$, $5);
-			}
-			;
-
-insert_cmd		:	RULE		ruleid_spec	rule
-			{
-				$$ = cmd_alloc(CMD_INSERT, CMD_OBJ_RULE, &$2, &@$, $3);
-			}
-			;
-
-delete_cmd		:	TABLE		table_spec
-			{
-				$$ = cmd_alloc(CMD_DELETE, CMD_OBJ_TABLE, &$2, &@$, NULL);
-			}
-			|	CHAIN		chain_spec
-			{
-				$$ = cmd_alloc(CMD_DELETE, CMD_OBJ_CHAIN, &$2, &@$, NULL);
-			}
-			|	RULE		ruleid_spec
-			{
-				$$ = cmd_alloc(CMD_DELETE, CMD_OBJ_RULE, &$2, &@$, NULL);
-			}
-			|	SET		set_spec
-			{
-				$$ = cmd_alloc(CMD_DELETE, CMD_OBJ_SET, &$2, &@$, NULL);
-			}
-			|	MAP		set_spec
-			{
-				$$ = cmd_alloc(CMD_DELETE, CMD_OBJ_SET, &$2, &@$, NULL);
-			}
-			|	ELEMENT		set_spec	set_expr
-			{
-				$$ = cmd_alloc(CMD_DELETE, CMD_OBJ_SETELEM, &$2, &@$, $3);
-			}
-			;
-
-list_cmd		:	TABLE		table_spec
-			{
-				$$ = cmd_alloc(CMD_LIST, CMD_OBJ_TABLE, &$2, &@$, NULL);
-			}
-			|	TABLES		tables_spec
-			{
-				$$ = cmd_alloc(CMD_LIST, CMD_OBJ_TABLE, &$2, &@$, NULL);
-			}
-			|	CHAIN		chain_spec
-			{
-				$$ = cmd_alloc(CMD_LIST, CMD_OBJ_CHAIN, &$2, &@$, NULL);
-			}
-			|	SETS		tables_spec
-			{
-				$$ = cmd_alloc(CMD_LIST, CMD_OBJ_SETS, &$2, &@$, NULL);
-			}
-			|	SET		set_spec
-			{
-				$$ = cmd_alloc(CMD_LIST, CMD_OBJ_SET, &$2, &@$, NULL);
-			}
-			;
-
-flush_cmd		:	TABLE		table_spec
-			{
-				$$ = cmd_alloc(CMD_FLUSH, CMD_OBJ_TABLE, &$2, &@$, NULL);
-			}
-			|	CHAIN		chain_spec
-			{
-				$$ = cmd_alloc(CMD_FLUSH, CMD_OBJ_CHAIN, &$2, &@$, NULL);
-			}
-			|	SET		set_spec
-			{
-				$$ = cmd_alloc(CMD_FLUSH, CMD_OBJ_SET, &$2, &@$, NULL);
-			}
-			;
-
-rename_cmd		:	CHAIN		chain_spec	identifier
-			{
-				$$ = cmd_alloc(CMD_RENAME, CMD_OBJ_CHAIN, &$2, &@$, NULL);
-				$$->arg = $3;
-			}
-			;
-
-export_cmd		:	export_format
-			{
-				struct handle h = { .family = NFPROTO_UNSPEC };
-				$$ = cmd_alloc(CMD_EXPORT, CMD_OBJ_RULESET, &h, &@$, NULL);
-				$$->format = $1;
-			}
-			;
-
-monitor_cmd		:	monitor_flags	output_format
-			{
-				struct handle h = { .family = NFPROTO_UNSPEC };
-				$$ = cmd_alloc(CMD_MONITOR, CMD_OBJ_RULESET, &h, &@$, NULL);
-				$$->monitor_flags = $1;
-				$$->format = $2;
-			}
-			;
-
-monitor_flags		:	/* empty */
-			{
-				$$ = (1 << NFT_MSG_NEWRULE)	|
-				     (1 << NFT_MSG_DELRULE)	|
-				     (1 << NFT_MSG_NEWSET)	|
-				     (1 << NFT_MSG_DELSET)	|
-				     (1 << NFT_MSG_NEWSETELEM)	|
-				     (1 << NFT_MSG_DELSETELEM)	|
-				     (1 << NFT_MSG_NEWCHAIN)	|
-				     (1 << NFT_MSG_DELCHAIN)	|
-				     (1 << NFT_MSG_NEWTABLE)	|
-				     (1 << NFT_MSG_DELTABLE);
-			}
-			|	STRING
-			{
-				int event;
-
-				event = monitor_lookup_event($1);
-				if (event < 0) {
-					erec_queue(error(&@1, "unknown event type %s", $1),
-						   state->msgs);
-					YYERROR;
-				}
-
-				switch (event) {
-				case NFT_EVENT_NEW:
-					$$ = (1 << NFT_MSG_NEWTABLE)	|
-					     (1 << NFT_MSG_NEWCHAIN)	|
-					     (1 << NFT_MSG_NEWRULE)	|
-					     (1 << NFT_MSG_NEWSET)	|
-					     (1 << NFT_MSG_NEWSETELEM);
-					break;
-				case NFT_EVENT_DEL:
-					$$ = (1 << NFT_MSG_DELTABLE)	|
-					     (1 << NFT_MSG_DELCHAIN)	|
-					     (1 << NFT_MSG_DELRULE)	|
-					     (1 << NFT_MSG_DELSET)	|
-					     (1 << NFT_MSG_DELSETELEM);
-					break;
-				}
-			}
-			|	TABLES
-			{
-				$$ = (1 << NFT_MSG_NEWTABLE) |
-				     (1 << NFT_MSG_DELTABLE);
-			}
-			|	STRING 	TABLES
-			{
-				int event;
-
-				event = monitor_lookup_event($1);
-				if (event < 0) {
-					erec_queue(error(&@1, "unknown event type %s", $1),
-						   state->msgs);
-					YYERROR;
-				}
-
-				switch (event) {
-				case NFT_EVENT_NEW:
-					$$ = (1 << NFT_MSG_NEWTABLE);
-					break;
-				case NFT_EVENT_DEL:
-					$$ = (1 << NFT_MSG_DELTABLE);
-					break;
-				}
-			}
-			|	CHAINS
-			{
-				$$ = (1 << NFT_MSG_NEWCHAIN) |
-				     (1 << NFT_MSG_DELCHAIN);
-			}
-			|	STRING	CHAINS
-			{
-				int event;
-
-				event = monitor_lookup_event($1);
-				if (event < 0) {
-					erec_queue(error(&@1, "unknown event type %s", $1),
-						   state->msgs);
-					YYERROR;
-				}
-
-				switch (event) {
-				case NFT_EVENT_NEW:
-					$$ = (1 << NFT_MSG_NEWCHAIN);
-					break;
-				case NFT_EVENT_DEL:
-					$$ = (1 << NFT_MSG_DELCHAIN);
-					break;
-				}
-			}
-			|	SETS
-			{
-				$$ = (1 << NFT_MSG_NEWSET) |
-				     (1 << NFT_MSG_DELSET);
-			}
-			|	STRING	SETS
-			{
-				int event;
-
-				event = monitor_lookup_event($1);
-				if (event < 0) {
-					erec_queue(error(&@1, "unknown event type %s", $1),
-						   state->msgs);
-					YYERROR;
-				}
-
-				switch (event) {
-				case NFT_EVENT_NEW:
-					$$ = (1 << NFT_MSG_NEWSET);
-					break;
-				case NFT_EVENT_DEL:
-					$$ = (1 << NFT_MSG_DELSET);
-					break;
-				}
-			}
-			|	RULES
-			{
-				$$ = (1 << NFT_MSG_NEWRULE) |
-				     (1 << NFT_MSG_DELRULE);
-			}
-			|	STRING 	RULES
-			{
-				int event;
-
-				event = monitor_lookup_event($1);
-				if (event < 0) {
-					erec_queue(error(&@1, "unknown event type %s", $1),
-						   state->msgs);
-					YYERROR;
-				}
-
-				switch (event) {
-				case NFT_EVENT_NEW:
-					$$ = (1 << NFT_MSG_NEWRULE);
-					break;
-				case NFT_EVENT_DEL:
-					$$ = (1 << NFT_MSG_DELRULE);
-					break;
-				}
-			}
-			|	ELEMENTS
-			{
-				$$ = (1 << NFT_MSG_NEWSETELEM) |
-				     (1 << NFT_MSG_DELSETELEM);
-			}
-			|	STRING	ELEMENTS
-			{
-				int event;
-
-				event = monitor_lookup_event($1);
-				if (event < 0) {
-					erec_queue(error(&@1, "unknown event type %s", $1),
-						   state->msgs);
-					YYERROR;
-				}
-
-				switch (event) {
-				case NFT_EVENT_NEW:
-					$$ = (1 << NFT_MSG_NEWSETELEM);
-					break;
-				case NFT_EVENT_DEL:
-					$$ = (1 << NFT_MSG_DELSETELEM);
-					break;
-				}
-			}
-			;
-
-output_format		:	/* empty */
-			{
-				$$ = NFT_OUTPUT_DEFAULT;
-			}
-			|	export_format
-			;
-
-table_block_alloc	:	/* empty */
-			{
-				$$ = table_alloc();
-				open_scope(state, &$$->scope);
-			}
-			;
-
-table_block		:	/* empty */	{ $$ = $<table>-1; }
-			|	table_block	common_block
-			|	table_block	stmt_seperator
-			|	table_block	CHAIN		chain_identifier
-					chain_block_alloc	'{' 	chain_block	'}'
-					stmt_seperator
-			{
-				$4->location = @3;
-				handle_merge(&$4->handle, &$3);
-				handle_free(&$3);
-				close_scope(state);
-				list_add_tail(&$4->list, &$1->chains);
-				$$ = $1;
-			}
-			|	table_block	SET		set_identifier
-					set_block_alloc		'{'	set_block	'}'
-					stmt_seperator
-			{
-				$4->location = @3;
-				handle_merge(&$4->handle, &$3);
-				handle_free(&$3);
-				list_add_tail(&$4->list, &$1->sets);
-				$$ = $1;
-			}
-			|	table_block	MAP		set_identifier
-					map_block_alloc		'{'	map_block	'}'
-					stmt_seperator
-			{
-				$4->location = @3;
-				handle_merge(&$4->handle, &$3);
-				handle_free(&$3);
-				list_add_tail(&$4->list, &$1->sets);
-				$$ = $1;
-			}
-			;
-
-chain_block_alloc	:	/* empty */
-			{
-				$$ = chain_alloc(NULL);
-				open_scope(state, &$$->scope);
-			}
-			;
-
-chain_block		:	/* empty */	{ $$ = $<chain>-1; }
-			|	chain_block	common_block
-	     		|	chain_block	stmt_seperator
-			|	chain_block	hook_spec	stmt_seperator
-			|	chain_block	rule		stmt_seperator
-			{
-				list_add_tail(&$2->list, &$1->rules);
-				$$ = $1;
-			}
-			;
-
-set_block_alloc		:	/* empty */
-			{
-				$$ = set_alloc(NULL);
-			}
-			;
-
-set_block		:	/* empty */	{ $$ = $<set>-1; }
-			|	set_block	common_block
-			|	set_block	stmt_seperator
-			|	set_block	TYPE		identifier	stmt_seperator
-			{
-				$1->keytype = datatype_lookup_byname($3);
-				if ($1->keytype == NULL) {
-					erec_queue(error(&@3, "unknown datatype %s", $3),
-						   state->msgs);
-					YYERROR;
-				}
-				$$ = $1;
-			}
-			|	set_block	FLAGS		set_flag_list	stmt_seperator
-			{
-				$1->flags = $3;
-				$$ = $1;
-			}
-			|	set_block	ELEMENTS	'='		set_expr
-			{
-				$1->init = $4;
-				$$ = $1;
-			}
-			;
-
-set_flag_list		:	set_flag_list	COMMA		set_flag
-			{
-				$$ = $1 | $3;
-			}
-			|	set_flag
-			;
-
-set_flag		:	CONSTANT	{ $$ = SET_F_CONSTANT; }
-			|	INTERVAL	{ $$ = SET_F_INTERVAL; }
-			;
-
-map_block_alloc		:	/* empty */
-			{
-				$$ = set_alloc(NULL);
-				$$->flags |= NFT_SET_MAP;
-			}
-			;
-
-map_block		:	/* empty */	{ $$ = $<set>-1; }
-			|	map_block	common_block
-			|	map_block	stmt_seperator
-			|	map_block	TYPE
-						identifier	COLON	identifier
-						stmt_seperator
-			{
-				$1->keytype = datatype_lookup_byname($3);
-				if ($1->keytype == NULL) {
-					erec_queue(error(&@3, "unknown datatype %s", $3),
-						   state->msgs);
-					YYERROR;
-				}
-
-				$1->datatype = datatype_lookup_byname($5);
-				if ($1->datatype == NULL) {
-					erec_queue(error(&@5, "unknown datatype %s", $5),
-						   state->msgs);
-					YYERROR;
-				}
-
-				$$ = $1;
-			}
-			|	map_block	FLAGS		set_flag_list	stmt_seperator
-			{
-				$1->flags = $3;
-				$$ = $1;
-			}
-			|	map_block	ELEMENTS	'='		set_expr
-			{
-				$1->init = $4;
-				$$ = $1;
-			}
-			;
-
-hook_spec		:	TYPE		STRING		HOOK		STRING		PRIORITY	NUM
-			{
-				$<chain>0->type		= chain_type_name_lookup($2);
-				if ($<chain>0->type == NULL) {
-					erec_queue(error(&@2, "unknown chain type %s", $2),
-						   state->msgs);
-					YYERROR;
-				}
-				$<chain>0->hookstr	= chain_hookname_lookup($4);
-				if ($<chain>0->hookstr == NULL) {
-					erec_queue(error(&@4, "unknown chain type %s", $4),
-						   state->msgs);
-					YYERROR;
-				}
-				$<chain>0->priority	= $6;
-				$<chain>0->flags	|= CHAIN_F_BASECHAIN;
-			}
-			|	TYPE		STRING		HOOK		STRING		PRIORITY	DASH	NUM
-			{
-				$<chain>0->type		= chain_type_name_lookup($2);
-				if ($<chain>0->type == NULL) {
-					erec_queue(error(&@2, "unknown type name %s", $2),
-						   state->msgs);
-					YYERROR;
-				}
-				$<chain>0->hookstr	= chain_hookname_lookup($4);
-				if ($<chain>0->hookstr == NULL) {
-					erec_queue(error(&@4, "unknown hook name %s", $4),
-						   state->msgs);
-					YYERROR;
-				}
-				$<chain>0->priority	= -$7;
-				$<chain>0->flags	|= CHAIN_F_BASECHAIN;
-			}
-			;
-
-identifier		:	STRING
-			;
-
-string			:	STRING
-			|	QUOTED_STRING
-			;
-
-family_spec		:	/* empty */	{ $$ = NFPROTO_IPV4; }
-			|	IP		{ $$ = NFPROTO_IPV4; }
-			|	IP6		{ $$ = NFPROTO_IPV6; }
-			|	INET		{ $$ = NFPROTO_INET; }
-			|	ARP		{ $$ = NFPROTO_ARP; }
-			|	BRIDGE		{ $$ = NFPROTO_BRIDGE; }
-			;
-
-table_spec		:	family_spec	identifier
-			{
-				memset(&$$, 0, sizeof($$));
-				$$.family	= $1;
-				$$.table	= $2;
-			}
-			;
-
-tables_spec		:	family_spec
-			{
-				memset(&$$, 0, sizeof($$));
-				$$.family	= $1;
-				$$.table	= NULL;
-			}
-			;
-
-chain_spec		:	table_spec	identifier
-			{
-				$$		= $1;
-				$$.chain	= $2;
-			}
-			;
-
-chain_identifier	:	identifier
-			{
-				memset(&$$, 0, sizeof($$));
-				$$.chain	= $1;
-			}
-			;
-
-set_spec		:	table_spec	identifier
-			{
-				$$		= $1;
-				$$.set		= $2;
-			}
-			;
-
-set_identifier		:	identifier
-			{
-				memset(&$$, 0, sizeof($$));
-				$$.set		= $1;
-			}
-			;
-
-handle_spec		:	/* empty */
-			{
-				$$ = 0;
-			}
-			|	HANDLE		NUM
-			{
-				$$ = $2;
-			}
-			;
-
-position_spec		:	/* empty */
-			{
-				$$ = 0;
-			}
-			|	POSITION	NUM
-			{
-				$$ = $2;
-			}
-			;
-
-ruleid_spec		:	chain_spec	handle_spec	position_spec
-			{
-				$$		= $1;
-				$$.handle	= $2;
-				$$.position	= $3;
-			}
-			;
-
-comment_spec		:	/* empty */
-			{
-				$$ = NULL;
-			}
-			|	COMMENT		string
-			{
-				$$ = $2;
-			}
-			;
-
-rule			:	stmt_list	comment_spec
-			{
-				struct stmt *i;
-
-				$$ = rule_alloc(&@$, NULL);
-				$$->handle.comment = $2;
-				list_for_each_entry(i, $1, list)
-					$$->num_stmts++;
-				list_splice_tail($1, &$$->stmts);
-				xfree($1);
-			}
-			;
-
-stmt_list		:	stmt
-			{
-				$$ = xmalloc(sizeof(*$$));
-				init_list_head($$);
-				list_add_tail(&$1->list, $$);
-			}
-			|	stmt_list		stmt
-			{
-				$$ = $1;
-				list_add_tail(&$2->list, $1);
-			}
-			;
-
-stmt			:	verdict_stmt
-			|	match_stmt
-			|	counter_stmt
-			|	meta_stmt
-			|	log_stmt
-			|	limit_stmt
-			|	reject_stmt
-			|	nat_stmt
-			|	queue_stmt
-			|	ct_stmt
-			;
-
-verdict_stmt		:	verdict_expr
-			{
-				$$ = verdict_stmt_alloc(&@$, $1);
-			}
-			|	verdict_map_stmt
-			{
-				$$ = verdict_stmt_alloc(&@$, $1);
-			}
-			;
-
-verdict_map_stmt	:	concat_expr	VMAP	verdict_map_expr
-			{
-				$$ = map_expr_alloc(&@$, $1, $3);
-			}
-			;
-
-verdict_map_expr	:	'{'	verdict_map_list_expr	'}'
-			{
-				$2->location = @$;
-				$$ = $2;
-			}
-			;
-
-verdict_map_list_expr	:	verdict_map_list_member_expr
-			{
-				$$ = set_expr_alloc(&@$);
-				compound_expr_add($$, $1);
-			}
-			|	verdict_map_list_expr	COMMA	verdict_map_list_member_expr
-			{
-				compound_expr_add($1, $3);
-				$$ = $1;
-			}
-			|	verdict_map_list_expr	COMMA	opt_newline
-			;
-
-verdict_map_list_member_expr:	opt_newline	map_lhs_expr	COLON	verdict_expr	opt_newline
-			{
-				$$ = mapping_expr_alloc(&@$, $2, $4);
-			}
-			;
-
-
-counter_stmt		:	counter_stmt_alloc
-			|	counter_stmt_alloc	counter_args
-
-counter_stmt_alloc	:	COUNTER
-			{
-				$$ = counter_stmt_alloc(&@$);
-			}
-			;
-
-counter_args		:	counter_arg
-			{
-				$<stmt>$	= $<stmt>0;
-			}
-			|	counter_args	counter_arg
-			;
-
-counter_arg		:	PACKETS			NUM
-			{
-				$<stmt>0->counter.packets = $2;
-			}
-			|	BYTES			NUM
-			{
-				$<stmt>0->counter.bytes	 = $2;
-			}
-			;
-
-log_stmt		:	log_stmt_alloc
-			|	log_stmt_alloc		log_args
-			;
-
-log_stmt_alloc		:	LOG
-			{
-				$$ = log_stmt_alloc(&@$);
-			}
-			;
-
-log_args		:	log_arg
-			{
-				$<stmt>$	= $<stmt>0;
-			}
-			|	log_args	log_arg
-			;
-
-log_arg			:	PREFIX			string
-			{
-				$<stmt>0->log.prefix	 = $2;
-			}
-			|	GROUP			NUM
-			{
-				$<stmt>0->log.group	 = $2;
-			}
-			|	SNAPLEN			NUM
-			{
-				$<stmt>0->log.snaplen	 = $2;
-			}
-			|	QUEUE_THRESHOLD		NUM
-			{
-				$<stmt>0->log.qthreshold = $2;
-			}
-			;
-
-limit_stmt		:	LIMIT	RATE	NUM	SLASH	time_unit
-	    		{
-				$$ = limit_stmt_alloc(&@$);
-				$$->limit.rate	= $3;
-				$$->limit.unit	= $5;
-			}
-			;
-
-time_unit		:	SECOND		{ $$ = 1ULL; }
-			|	MINUTE		{ $$ = 1ULL * 60; }
-			|	HOUR		{ $$ = 1ULL * 60 * 60; }
-			|	DAY		{ $$ = 1ULL * 60 * 60 * 24; }
-			|	WEEK		{ $$ = 1ULL * 60 * 60 * 24 * 7; }
-			;
-
-reject_stmt		:	_REJECT
-			{
-				$$ = reject_stmt_alloc(&@$);
-			}
-			;
-
-nat_stmt		:	nat_stmt_alloc	nat_stmt_args
-			;
-
-nat_stmt_alloc		:	SNAT
-			{
-				$$ = nat_stmt_alloc(&@$);
-				$$->nat.type = NFT_NAT_SNAT;
-			}
-			|	DNAT
-			{
-				$$ = nat_stmt_alloc(&@$);
-				$$->nat.type = NFT_NAT_DNAT;
-			}
-			;
-
-nat_stmt_args		:	expr
-			{
-				$<stmt>0->nat.addr = $1;
-			}
-			|	expr	COLON	expr
-			{
-				$<stmt>0->nat.addr = $1;
-				$<stmt>0->nat.proto = $3;
-			}
-			|	COLON	expr
-			{
-				$<stmt>0->nat.proto = $2;
-			}
-			;
-
-queue_stmt		:	queue_stmt_alloc
-			|	queue_stmt_alloc		queue_args
-			;
-
-queue_stmt_alloc	:	QUEUE
-			{
-				$$ = queue_stmt_alloc(&@$);
-			}
-			;
-
-queue_args		:	QUEUENUM	queue_range	queue_flags
-			{
-				$<stmt>0->queue.from = $2->queue.from;
-				$<stmt>0->queue.to = $2->queue.to;
-				$<stmt>0->queue.flags = $3;
-			}
-			|	QUEUENUM	queue_range
-			{
-				$<stmt>0->queue.from = $2->queue.from;
-				$<stmt>0->queue.to = $2->queue.to;
-			}
-			|	queue_flags
-			{
-				$<stmt>0->queue.flags = $1;
-			}
-			;
-
-queue_range		:	NUM
-			{
-				$<stmt>0->queue.from = $1;
-				$<stmt>0->queue.to = $1;
-				$$ = $<stmt>0;
-			}
-			|	NUM	DASH	NUM
-			{
-				if ($3 < $1) {
-					erec_queue(error(&@1,
-							 "invalid range %d-%d",
-							 $1, $3), state->msgs);
-					YYERROR;
-				}
-				$<stmt>0->queue.from = $1;
-				$<stmt>0->queue.to = $3;
-				$$ = $<stmt>0;
-			}
-			;
-
-queue_flags		:	queue_flag
-			{
-				$$ = $1;
-			}
-			|	queue_flags	queue_flag
-			{
-				$$ |= $1 | $2;
-			}
-			;
-
-queue_flag		:	QUEUEBYPASS
-			{
-				$$ = NFT_QUEUE_FLAG_BYPASS;
-			}
-			|	QUEUECPUFANOUT
-			{
-				$$ = NFT_QUEUE_FLAG_CPU_FANOUT;
-			}
-			;
-
-match_stmt		:	relational_expr
-			{
-				$$ = expr_stmt_alloc(&@$, $1);
-			}
-			;
-
-symbol_expr		:	string
-			{
-				$$ = symbol_expr_alloc(&@$, SYMBOL_VALUE,
-						       current_scope(state),
-						       $1);
-				xfree($1);
-			}
-			|	'$'	identifier
-			{
-				struct scope *scope = current_scope(state);
-
-				if (symbol_lookup(scope, $2) == NULL) {
-					erec_queue(error(&@2, "unknown identifier '%s'", $2),
-						   state->msgs);
-					YYERROR;
-				}
-
-				$$ = symbol_expr_alloc(&@$, SYMBOL_DEFINE,
-						       scope, $2);
-				xfree($2);
-			}
-			|	AT	identifier
-			{
-				$$ = symbol_expr_alloc(&@$, SYMBOL_SET,
-						       current_scope(state),
-						       $2);
-				xfree($2);
-			}
-			;
-
-integer_expr		:	NUM
-			{
-				char str[64];
-
-				snprintf(str, sizeof(str), "%" PRIu64, $1);
-				$$ = symbol_expr_alloc(&@$, SYMBOL_VALUE,
-						       current_scope(state),
-						       str);
-			}
-			;
-
-primary_expr		:	symbol_expr			{ $$ = $1; }
-			|	integer_expr			{ $$ = $1; }
-			|	payload_expr			{ $$ = $1; }
-			|	exthdr_expr			{ $$ = $1; }
-			|	meta_expr			{ $$ = $1; }
-			|	ct_expr				{ $$ = $1; }
-			|	'('	basic_expr	')'	{ $$ = $2; }
-			;
-
-shift_expr		:	primary_expr
-			|	shift_expr		LSHIFT		primary_expr
-			{
-				$$ = binop_expr_alloc(&@$, OP_LSHIFT, $1, $3);
-			}
-			|	shift_expr		RSHIFT		primary_expr
-			{
-				$$ = binop_expr_alloc(&@$, OP_RSHIFT, $1, $3);
-			}
-			;
-
-and_expr		:	shift_expr
-			|	and_expr		AMPERSAND	shift_expr
-			{
-				$$ = binop_expr_alloc(&@$, OP_AND, $1, $3);
-			}
-			;
-
-exclusive_or_expr	:	and_expr
-			|	exclusive_or_expr	CARET		and_expr
-			{
-				$$ = binop_expr_alloc(&@$, OP_XOR, $1, $3);
-			}
-			;
-
-inclusive_or_expr	:	exclusive_or_expr
-			|	inclusive_or_expr	'|'		exclusive_or_expr
-			{
-				$$ = binop_expr_alloc(&@$, OP_OR, $1, $3);
-			}
-			;
-
-basic_expr		:	inclusive_or_expr
-			;
-
-concat_expr		:	basic_expr
-			|	concat_expr		DOT		basic_expr
-			{
-				if ($$->ops->type != EXPR_CONCAT) {
-					$$ = concat_expr_alloc(&@$);
-					compound_expr_add($$, $1);
-				} else {
-					struct location rhs[] = {
-						[1]	= @2,
-						[2]	= @3,
-					};
-					location_update(&$3->location, rhs, 2);
-
-					$$ = $1;
-					$$->location = @$;
-				}
-				compound_expr_add($$, $3);
-			}
-			;
-
-list_expr		:	basic_expr		COMMA		basic_expr
-			{
-				$$ = list_expr_alloc(&@$);
-				compound_expr_add($$, $1);
-				compound_expr_add($$, $3);
-			}
-			|	list_expr		COMMA		basic_expr
-			{
-				$1->location = @$;
-				compound_expr_add($1, $3);
-				$$ = $1;
-			}
-			;
-
-prefix_expr		:	basic_expr		SLASH	NUM
-			{
-				$$ = prefix_expr_alloc(&@$, $1, $3);
-			}
-			;
-
-range_expr		:	basic_expr		DASH	basic_expr
-			{
-				$$ = range_expr_alloc(&@$, $1, $3);
-			}
-			;
-
-wildcard_expr		:	ASTERISK
-	       		{
-				struct expr *expr;
-
-				expr = constant_expr_alloc(&@$, &integer_type,
-							   BYTEORDER_HOST_ENDIAN,
-							   0, NULL);
-				$$ = prefix_expr_alloc(&@$, expr, 0);
-			}
-			;
-
-multiton_expr		:	prefix_expr
-			|	range_expr
-			|	wildcard_expr
-			;
-
-map_lhs_expr		:	multiton_expr
-			|	concat_expr
-			;
-
-map_expr		:	concat_expr	MAP	expr
-			{
-				$$ = map_expr_alloc(&@$, $1, $3);
-			}
-			;
-
-expr			:	concat_expr
-			|	set_expr
-			|       map_expr
-			|	multiton_expr
-			;
-
-set_expr		:	'{'	set_list_expr		'}'
-			{
-				$2->location = @$;
-				$$ = $2;
-			}
-			;
-
-set_list_expr		:	set_list_member_expr
-			{
-				$$ = set_expr_alloc(&@$);
-				compound_expr_add($$, $1);
-			}
-			|	set_list_expr		COMMA	set_list_member_expr
-			{
-				compound_expr_add($1, $3);
-				$$ = $1;
-			}
-			|	set_list_expr		COMMA	opt_newline
-			;
-
-set_list_member_expr	:	opt_newline	expr	opt_newline
-			{
-				$$ = $2;
-			}
-			|	opt_newline	map_lhs_expr	COLON	concat_expr	opt_newline
-			{
-				$$ = mapping_expr_alloc(&@$, $2, $4);
-			}
-			;
-
-initializer_expr	:	expr
-			|	list_expr
-			;
-
-relational_expr		:	expr	/* implicit */	expr
-			{
-				$$ = relational_expr_alloc(&@$, OP_IMPLICIT, $1, $2);
-			}
-			|	expr	/* implicit */	list_expr
-			{
-				$$ = relational_expr_alloc(&@$, OP_FLAGCMP, $1, $2);
-			}
-			|	expr	relational_op	expr
-			{
-				$$ = relational_expr_alloc(&@2, $2, $1, $3);
-			}
-			;
-
-relational_op		:	EQ		{ $$ = OP_EQ; }
-			|	NEQ		{ $$ = OP_NEQ; }
-			|	LT		{ $$ = OP_LT; }
-			|	GT		{ $$ = OP_GT; }
-			|	GTE		{ $$ = OP_GTE; }
-			|	LTE		{ $$ = OP_LTE; }
-			;
-
-verdict_expr		:	ACCEPT
-			{
-				$$ = verdict_expr_alloc(&@$, NF_ACCEPT, NULL);
-			}
-			|	DROP
-			{
-				$$ = verdict_expr_alloc(&@$, NF_DROP, NULL);
-			}
-			|	CONTINUE
-			{
-				$$ = verdict_expr_alloc(&@$, NFT_CONTINUE, NULL);
-			}
-			|	JUMP			identifier
-			{
-				$$ = verdict_expr_alloc(&@$, NFT_JUMP, $2);
-			}
-			|	GOTO			identifier
-			{
-				$$ = verdict_expr_alloc(&@$, NFT_GOTO, $2);
-			}
-			|	RETURN
-			{
-				$$ = verdict_expr_alloc(&@$, NFT_RETURN, NULL);
-			}
-			;
-
-meta_expr		:	META	meta_key
-			{
-				$$ = meta_expr_alloc(&@$, $2);
-			}
-			|	meta_key_unqualified
-			{
-				$$ = meta_expr_alloc(&@$, $1);
-			}
-			;
-
-meta_key		:	meta_key_qualified
-			|	meta_key_unqualified
-			;
-
-meta_key_qualified	:	LENGTH		{ $$ = NFT_META_LEN; }
-			|	NFPROTO		{ $$ = NFT_META_NFPROTO; }
-			|	L4PROTO		{ $$ = NFT_META_L4PROTO; }
-			|	PROTOCOL	{ $$ = NFT_META_PROTOCOL; }
-			|	PRIORITY	{ $$ = NFT_META_PRIORITY; }
-			;
-
-meta_key_unqualified	:	MARK		{ $$ = NFT_META_MARK; }
-			|	IIF		{ $$ = NFT_META_IIF; }
-			|	IIFNAME		{ $$ = NFT_META_IIFNAME; }
-			|	IIFTYPE		{ $$ = NFT_META_IIFTYPE; }
-			|	OIF		{ $$ = NFT_META_OIF; }
-			|	OIFNAME		{ $$ = NFT_META_OIFNAME; }
-			|	OIFTYPE		{ $$ = NFT_META_OIFTYPE; }
-			|	SKUID		{ $$ = NFT_META_SKUID; }
-			|	SKGID		{ $$ = NFT_META_SKGID; }
-			|	NFTRACE		{ $$ = NFT_META_NFTRACE; }
-			|	RTCLASSID	{ $$ = NFT_META_RTCLASSID; }
-			|	IBRIPORT	{ $$ = NFT_META_BRI_IIFNAME; }
-			|       OBRIPORT	{ $$ = NFT_META_BRI_OIFNAME; }
-			;
-
-meta_stmt		:	META	meta_key	SET	expr
-			{
-				$$ = meta_stmt_alloc(&@$, $2, $4);
-			}
-			|	meta_key_unqualified	SET	expr
-			{
-				$$ = meta_stmt_alloc(&@$, $1, $3);
-			}
-			;
-
-ct_expr			:	CT	ct_key
-			{
-				$$ = ct_expr_alloc(&@$, $2);
-			}
-			;
-
-ct_key			:	STATE		{ $$ = NFT_CT_STATE; }
-			|	DIRECTION	{ $$ = NFT_CT_DIRECTION; }
-			|	STATUS		{ $$ = NFT_CT_STATUS; }
-			|	MARK		{ $$ = NFT_CT_MARK; }
-			|	EXPIRATION	{ $$ = NFT_CT_EXPIRATION; }
-			|	HELPER		{ $$ = NFT_CT_HELPER; }
-			|	L3PROTOCOL	{ $$ = NFT_CT_L3PROTOCOL; }
-			|	SADDR		{ $$ = NFT_CT_SRC; }
-			|	DADDR		{ $$ = NFT_CT_DST; }
-			|	PROTOCOL	{ $$ = NFT_CT_PROTOCOL; }
-			|	PROTO_SRC	{ $$ = NFT_CT_PROTO_SRC; }
-			|	PROTO_DST	{ $$ = NFT_CT_PROTO_DST; }
-			|	LABEL		{ $$ = NFT_CT_LABEL; }
-			;
-
-ct_stmt			:	CT	ct_key		SET	expr
-			{
-				$$ = ct_stmt_alloc(&@$, $2, $4);
-			}
-			;
-
-payload_expr		:	payload_raw_expr
-			|	eth_hdr_expr
-			|	vlan_hdr_expr
-			|	arp_hdr_expr
-			|	ip_hdr_expr
-			|	icmp_hdr_expr
-			|	ip6_hdr_expr
-			|	icmp6_hdr_expr
-			|	auth_hdr_expr
-			|	esp_hdr_expr
-			|	comp_hdr_expr
-			|	udp_hdr_expr
-			|	udplite_hdr_expr
-			|	tcp_hdr_expr
-			|	dccp_hdr_expr
-			|	sctp_hdr_expr
-			;
-
-payload_raw_expr	:	AT	payload_base_spec	COMMA	NUM	COMMA	NUM
-			{
-				$$ = payload_expr_alloc(&@$, NULL, 0);
-				$$->payload.base	= $2;
-				$$->payload.offset	= $4;
-				$$->len			= $6;
-				$$->dtype		= &integer_type;
-			}
-			;
-
-payload_base_spec	:	LL_HDR		{ $$ = PROTO_BASE_LL_HDR; }
-			|	NETWORK_HDR	{ $$ = PROTO_BASE_NETWORK_HDR; }
-			|	TRANSPORT_HDR	{ $$ = PROTO_BASE_TRANSPORT_HDR; }
-			;
-
-eth_hdr_expr		:	ETHER	eth_hdr_field
-			{
-				$$ = payload_expr_alloc(&@$, &proto_eth, $2);
-			}
-			|	ETHER
-			{
-				$$ = symbol_expr_alloc(&@$, SYMBOL_VALUE,
-						       current_scope(state),
-						       "ether");
-			}
-			;
-
-eth_hdr_field		:	SADDR		{ $$ = ETHHDR_SADDR; }
-			|	DADDR		{ $$ = ETHHDR_DADDR; }
-			|	TYPE		{ $$ = ETHHDR_TYPE; }
-			;
-
-vlan_hdr_expr		:	VLAN	vlan_hdr_field
-			{
-				$$ = payload_expr_alloc(&@$, &proto_vlan, $2);
-			}
-			|	VLAN
-			{
-				$$ = symbol_expr_alloc(&@$, SYMBOL_VALUE,
-						       current_scope(state),
-						       "vlan");
-			}
-			;
-
-vlan_hdr_field		:	ID		{ $$ = VLANHDR_VID; }
-			|	CFI		{ $$ = VLANHDR_CFI; }
-			|	PCP		{ $$ = VLANHDR_PCP; }
-			|	TYPE		{ $$ = VLANHDR_TYPE; }
-			;
-
-arp_hdr_expr		:	ARP	arp_hdr_field
-			{
-				$$ = payload_expr_alloc(&@$, &proto_arp, $2);
-			}
-			|	ARP
-			{
-				$$ = symbol_expr_alloc(&@$, SYMBOL_VALUE,
-						       current_scope(state),
-						       "arp");
-			}
-			;
-
-arp_hdr_field		:	HTYPE		{ $$ = ARPHDR_HRD; }
-			|	PTYPE		{ $$ = ARPHDR_PRO; }
-			|	HLEN		{ $$ = ARPHDR_HLN; }
-			|	PLEN		{ $$ = ARPHDR_PLN; }
-			|	OPERATION	{ $$ = ARPHDR_OP; }
-			;
-
-ip_hdr_expr		:	IP	ip_hdr_field
-			{
-				$$ = payload_expr_alloc(&@$, &proto_ip, $2);
-			}
-			|	IP
-			{
-				$$ = symbol_expr_alloc(&@$, SYMBOL_VALUE,
-						       current_scope(state),
-						       "ip");
-			}
-			;
-
-ip_hdr_field		:	VERSION		{ $$ = IPHDR_VERSION; }
-			|	HDRLENGTH	{ $$ = IPHDR_HDRLENGTH; }
-			|	TOS		{ $$ = IPHDR_TOS; }
-			|	LENGTH		{ $$ = IPHDR_LENGTH; }
-			|	ID		{ $$ = IPHDR_ID; }
-			|	FRAG_OFF	{ $$ = IPHDR_FRAG_OFF; }
-			|	TTL		{ $$ = IPHDR_TTL; }
-			|	PROTOCOL	{ $$ = IPHDR_PROTOCOL; }
-			|	CHECKSUM	{ $$ = IPHDR_CHECKSUM; }
-			|	SADDR		{ $$ = IPHDR_SADDR; }
-			|	DADDR		{ $$ = IPHDR_DADDR; }
-			;
-
-icmp_hdr_expr		:	ICMP	icmp_hdr_field
-			{
-				$$ = payload_expr_alloc(&@$, &proto_icmp, $2);
-			}
-			|	ICMP
-			{
-				uint8_t data = IPPROTO_ICMP;
-				$$ = constant_expr_alloc(&@$, &inet_protocol_type,
-							 BYTEORDER_HOST_ENDIAN,
-							 sizeof(data) * BITS_PER_BYTE, &data);
-			}
-			;
-
-icmp_hdr_field		:	TYPE		{ $$ = ICMPHDR_TYPE; }
-			|	CODE		{ $$ = ICMPHDR_CODE; }
-			|	CHECKSUM	{ $$ = ICMPHDR_CHECKSUM; }
-			|	ID		{ $$ = ICMPHDR_ID; }
-			|	SEQUENCE	{ $$ = ICMPHDR_SEQ; }
-			|	GATEWAY		{ $$ = ICMPHDR_GATEWAY; }
-			|	MTU		{ $$ = ICMPHDR_MTU; }
-			;
-
-ip6_hdr_expr		:	IP6	ip6_hdr_field
-			{
-				$$ = payload_expr_alloc(&@$, &proto_ip6, $2);
-			}
-			|	IP6
-			{
-				$$ = symbol_expr_alloc(&@$, SYMBOL_VALUE,
-						       current_scope(state),
-						       "ip6");
-			}
-			;
-
-ip6_hdr_field		:	VERSION		{ $$ = IP6HDR_VERSION; }
-			|	PRIORITY	{ $$ = IP6HDR_PRIORITY; }
-			|	FLOWLABEL	{ $$ = IP6HDR_FLOWLABEL; }
-			|	LENGTH		{ $$ = IP6HDR_LENGTH; }
-			|	NEXTHDR		{ $$ = IP6HDR_NEXTHDR; }
-			|	HOPLIMIT	{ $$ = IP6HDR_HOPLIMIT; }
-			|	SADDR		{ $$ = IP6HDR_SADDR; }
-			|	DADDR		{ $$ = IP6HDR_DADDR; }
-			;
-icmp6_hdr_expr		:	ICMP6	icmp6_hdr_field
-			{
-				$$ = payload_expr_alloc(&@$, &proto_icmp6, $2);
-			}
-			|	ICMP6
-			{
-				uint8_t data = IPPROTO_ICMPV6;
-				$$ = constant_expr_alloc(&@$, &inet_protocol_type,
-							 BYTEORDER_HOST_ENDIAN,
-							 sizeof(data) * BITS_PER_BYTE, &data);
-			}
-			;
-
-icmp6_hdr_field		:	TYPE		{ $$ = ICMP6HDR_TYPE; }
-			|	CODE		{ $$ = ICMP6HDR_CODE; }
-			|	CHECKSUM	{ $$ = ICMP6HDR_CHECKSUM; }
-			|	PPTR		{ $$ = ICMP6HDR_PPTR; }
-			|	MTU		{ $$ = ICMP6HDR_MTU; }
-			|	ID		{ $$ = ICMP6HDR_ID; }
-			|	SEQUENCE	{ $$ = ICMP6HDR_SEQ; }
-			|	MAXDELAY	{ $$ = ICMP6HDR_MAXDELAY; }
-			;
-
-auth_hdr_expr		:	AH	auth_hdr_field
-			{
-				$$ = payload_expr_alloc(&@$, &proto_ah, $2);
-			}
-			|	AH
-			{
-				uint8_t data = IPPROTO_AH;
-				$$ = constant_expr_alloc(&@$, &inet_protocol_type,
-							 BYTEORDER_HOST_ENDIAN,
-							 sizeof(data) * BITS_PER_BYTE, &data);
-			}
-			;
-
-auth_hdr_field		:	NEXTHDR		{ $$ = AHHDR_NEXTHDR; }
-			|	HDRLENGTH	{ $$ = AHHDR_HDRLENGTH; }
-			|	RESERVED	{ $$ = AHHDR_RESERVED; }
-			|	SPI		{ $$ = AHHDR_SPI; }
-			|	SEQUENCE	{ $$ = AHHDR_SEQUENCE; }
-			;
-
-esp_hdr_expr		:	ESP	esp_hdr_field
-			{
-				$$ = payload_expr_alloc(&@$, &proto_esp, $2);
-			}
-			|	ESP
-			{
-				uint8_t data = IPPROTO_ESP;
-				$$ = constant_expr_alloc(&@$, &inet_protocol_type,
-							 BYTEORDER_HOST_ENDIAN,
-							 sizeof(data) * BITS_PER_BYTE, &data);
-			}
-			;
-
-esp_hdr_field		:	SPI		{ $$ = ESPHDR_SPI; }
-			|	SEQUENCE	{ $$ = ESPHDR_SEQUENCE; }
-			;
-
-comp_hdr_expr		:	COMP	comp_hdr_field
-			{
-				$$ = payload_expr_alloc(&@$, &proto_comp, $2);
-			}
-			|	COMP
-			{
-				uint8_t data = IPPROTO_COMP;
-				$$ = constant_expr_alloc(&@$, &inet_protocol_type,
-							 BYTEORDER_HOST_ENDIAN,
-							 sizeof(data) * BITS_PER_BYTE, &data);
-			}
-			;
-
-comp_hdr_field		:	NEXTHDR		{ $$ = COMPHDR_NEXTHDR; }
-			|	FLAGS		{ $$ = COMPHDR_FLAGS; }
-			|	CPI		{ $$ = COMPHDR_CPI; }
-			;
-
-udp_hdr_expr		:	UDP	udp_hdr_field
-			{
-				$$ = payload_expr_alloc(&@$, &proto_udp, $2);
-			}
-			|	UDP
-			{
-				uint8_t data = IPPROTO_UDP;
-				$$ = constant_expr_alloc(&@$, &inet_protocol_type,
-							 BYTEORDER_HOST_ENDIAN,
-							 sizeof(data) * BITS_PER_BYTE, &data);
-			}
-			;
-
-udp_hdr_field		:	SPORT		{ $$ = UDPHDR_SPORT; }
-			|	DPORT		{ $$ = UDPHDR_DPORT; }
-			|	LENGTH		{ $$ = UDPHDR_LENGTH; }
-			|	CHECKSUM	{ $$ = UDPHDR_CHECKSUM; }
-			;
-
-udplite_hdr_expr	:	UDPLITE	udplite_hdr_field
-			{
-				$$ = payload_expr_alloc(&@$, &proto_udplite, $2);
-			}
-			|	UDPLITE
-			{
-				uint8_t data = IPPROTO_UDPLITE;
-				$$ = constant_expr_alloc(&@$, &inet_protocol_type,
-							 BYTEORDER_HOST_ENDIAN,
-							 sizeof(data) * BITS_PER_BYTE, &data);
-			}
-			;
-
-udplite_hdr_field	:	SPORT		{ $$ = UDPHDR_SPORT; }
-			|	DPORT		{ $$ = UDPHDR_DPORT; }
-			|	CSUMCOV		{ $$ = UDPHDR_LENGTH; }
-			|	CHECKSUM	{ $$ = UDPHDR_CHECKSUM; }
-			;
-
-tcp_hdr_expr		:	TCP	tcp_hdr_field
-			{
-				$$ = payload_expr_alloc(&@$, &proto_tcp, $2);
-			}
-			|	TCP
-			{
-				uint8_t data = IPPROTO_TCP;
-				$$ = constant_expr_alloc(&@$, &inet_protocol_type,
-							 BYTEORDER_HOST_ENDIAN,
-							 sizeof(data) * BITS_PER_BYTE, &data);
-			}
-			;
-
-tcp_hdr_field		:	SPORT		{ $$ = TCPHDR_SPORT; }
-			|	DPORT		{ $$ = TCPHDR_DPORT; }
-			|	SEQUENCE	{ $$ = TCPHDR_SEQ; }
-			|	ACKSEQ		{ $$ = TCPHDR_ACKSEQ; }
-			|	DOFF		{ $$ = TCPHDR_DOFF; }
-			|	RESERVED	{ $$ = TCPHDR_RESERVED; }
-			|	FLAGS		{ $$ = TCPHDR_FLAGS; }
-			|	WINDOW		{ $$ = TCPHDR_WINDOW; }
-			|	CHECKSUM	{ $$ = TCPHDR_CHECKSUM; }
-			|	URGPTR		{ $$ = TCPHDR_URGPTR; }
-			;
-
-dccp_hdr_expr		:	DCCP	dccp_hdr_field
-			{
-				$$ = payload_expr_alloc(&@$, &proto_dccp, $2);
-			}
-			|	DCCP
-			{
-				uint8_t data = IPPROTO_DCCP;
-				$$ = constant_expr_alloc(&@$, &inet_protocol_type,
-							 BYTEORDER_HOST_ENDIAN,
-							 sizeof(data) * BITS_PER_BYTE, &data);
-			}
-			;
-
-dccp_hdr_field		:	SPORT		{ $$ = DCCPHDR_SPORT; }
-			|	DPORT		{ $$ = DCCPHDR_DPORT; }
-			|	TYPE		{ $$ = DCCPHDR_TYPE; }
-			;
-
-sctp_hdr_expr		:	SCTP	sctp_hdr_field
-			{
-				$$ = payload_expr_alloc(&@$, &proto_sctp, $2);
-			}
-			|	SCTP
-			{
-				uint8_t data = IPPROTO_SCTP;
-				$$ = constant_expr_alloc(&@$, &inet_protocol_type,
-							 BYTEORDER_HOST_ENDIAN,
-							 sizeof(data) * BITS_PER_BYTE, &data);
-			}
-			;
-
-sctp_hdr_field		:	SPORT		{ $$ = SCTPHDR_SPORT; }
-			|	DPORT		{ $$ = SCTPHDR_DPORT; }
-			|	VTAG		{ $$ = SCTPHDR_VTAG; }
-			|	CHECKSUM	{ $$ = SCTPHDR_CHECKSUM; }
-			;
-
-exthdr_expr		:	hbh_hdr_expr
-			|	rt_hdr_expr
-			|	rt0_hdr_expr
-			|	rt2_hdr_expr
-			|	frag_hdr_expr
-			|	dst_hdr_expr
-			|	mh_hdr_expr
-			;
-
-hbh_hdr_expr		:	HBH	hbh_hdr_field
-			{
-				$$ = exthdr_expr_alloc(&@$, &exthdr_hbh, $2);
-			}
-			;
-
-hbh_hdr_field		:	NEXTHDR		{ $$ = HBHHDR_NEXTHDR; }
-			|	HDRLENGTH	{ $$ = HBHHDR_HDRLENGTH; }
-			;
-
-rt_hdr_expr		:	RT	rt_hdr_field
-			{
-				$$ = exthdr_expr_alloc(&@$, &exthdr_rt, $2);
-			}
-			;
-
-rt_hdr_field		:	NEXTHDR		{ $$ = RTHDR_NEXTHDR; }
-			|	HDRLENGTH	{ $$ = RTHDR_HDRLENGTH; }
-			|	TYPE		{ $$ = RTHDR_TYPE; }
-			|	SEG_LEFT	{ $$ = RTHDR_SEG_LEFT; }
-			;
-
-rt0_hdr_expr		:	RT0	rt0_hdr_field
-			{
-				$$ = exthdr_expr_alloc(&@$, &exthdr_rt0, $2);
-			}
-			;
-
-rt0_hdr_field		:	ADDR	'['	NUM	']'
-			{
-				$$ = RT0HDR_ADDR_1 + $3 - 1;
-			}
-			;
-
-rt2_hdr_expr		:	RT2	rt2_hdr_field
-			{
-				$$ = exthdr_expr_alloc(&@$, &exthdr_rt2, $2);
-			}
-			;
-
-rt2_hdr_field		:	ADDR		{ $$ = RT2HDR_ADDR; }
-			;
-
-frag_hdr_expr		:	FRAG	frag_hdr_field
-			{
-				$$ = exthdr_expr_alloc(&@$, &exthdr_frag, $2);
-			}
-			;
-
-frag_hdr_field		:	NEXTHDR		{ $$ = FRAGHDR_NEXTHDR; }
-			|	RESERVED	{ $$ = FRAGHDR_RESERVED; }
-			|	FRAG_OFF	{ $$ = FRAGHDR_FRAG_OFF; }
-			|	RESERVED2	{ $$ = FRAGHDR_RESERVED2; }
-			|	MORE_FRAGMENTS	{ $$ = FRAGHDR_MFRAGS; }
-			|	ID		{ $$ = FRAGHDR_ID; }
-			;
-
-dst_hdr_expr		:	DST	dst_hdr_field
-			{
-				$$ = exthdr_expr_alloc(&@$, &exthdr_dst, $2);
-			}
-			;
-
-dst_hdr_field		:	NEXTHDR		{ $$ = DSTHDR_NEXTHDR; }
-			|	HDRLENGTH	{ $$ = DSTHDR_HDRLENGTH; }
-			;
-
-mh_hdr_expr		:	MH	mh_hdr_field
-			{
-				$$ = exthdr_expr_alloc(&@$, &exthdr_mh, $2);
-			}
-			;
-
-mh_hdr_field		:	NEXTHDR		{ $$ = MHHDR_NEXTHDR; }
-			|	HDRLENGTH	{ $$ = MHHDR_HDRLENGTH; }
-			|	TYPE		{ $$ = MHHDR_TYPE; }
-			|	RESERVED	{ $$ = MHHDR_RESERVED; }
-			|	CHECKSUM	{ $$ = MHHDR_CHECKSUM; }
-			;
-
-export_format		: 	XML 		{ $$ = NFT_OUTPUT_XML; }
-			|	JSON		{ $$ = NFT_OUTPUT_JSON; }
-			;
-%%
diff --git a/src/scanner.l b/src/scanner.l
index 73a1a3f..e6b8127 100644
--- a/src/scanner.l
+++ b/src/scanner.l
@@ -20,7 +20,7 @@
 #include <erec.h>
 #include <rule.h>
 #include <parser.h>
-#include "parser.h"
+#include "yacc_parser.h"
 
 #define YY_NO_INPUT
 
@@ -178,6 +178,7 @@ addrstring	({macaddr}|{ip4addr}|{ip6addr})
 %option yylineno
 %option nodefault
 %option warn
+%option outfile="scanner.c"
 
 %%
 
diff --git a/src/yacc_parser.y b/src/yacc_parser.y
new file mode 100644
index 0000000..7cb790d
--- /dev/null
+++ b/src/yacc_parser.y
@@ -0,0 +1,2251 @@
+/*
+ * Copyright (c) 2007-2012 Patrick McHardy <kaber@trash.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Development of this code funded by Astaro AG (http://www.astaro.com/)
+ */
+
+%{
+
+#include <stddef.h>
+#include <stdio.h>
+#include <string.h>
+#include <inttypes.h>
+#include <netinet/ip.h>
+#include <netinet/if_ether.h>
+#include <linux/netfilter.h>
+#include <linux/netfilter/nf_tables.h>
+#include <linux/netfilter/nf_conntrack_tuple_common.h>
+#include <libnftnl/common.h>
+
+#include <rule.h>
+#include <statement.h>
+#include <expression.h>
+#include <utils.h>
+#include <parser.h>
+#include <erec.h>
+
+#include "yacc_parser.h"
+
+void parser_init(struct parser_state *state, struct list_head *msgs)
+{
+	memset(state, 0, sizeof(*state));
+	init_list_head(&state->cmds);
+	init_list_head(&state->top_scope.symbols);
+	state->msgs = msgs;
+	state->scopes[0] = scope_init(&state->top_scope, NULL);
+	state->ectx.msgs = msgs;
+}
+
+static void yyerror(struct location *loc, void *scanner,
+		    struct parser_state *state, const char *s)
+{
+	erec_queue(error(loc, "%s", s), state->msgs);
+}
+
+static struct scope *current_scope(const struct parser_state *state)
+{
+	return state->scopes[state->scope];
+}
+
+static void open_scope(struct parser_state *state, struct scope *scope)
+{
+	assert(state->scope < array_size(state->scopes) - 1);
+	scope_init(scope, current_scope(state));
+	state->scopes[++state->scope] = scope;
+}
+
+static void close_scope(struct parser_state *state)
+{
+	assert(state->scope > 0);
+	state->scope--;
+}
+
+static void location_init(void *scanner, struct parser_state *state,
+			  struct location *loc)
+{
+	memset(loc, 0, sizeof(*loc));
+	loc->indesc = state->indesc;
+}
+
+static void location_update(struct location *loc, struct location *rhs, int n)
+{
+	if (n) {
+		loc->indesc       = rhs[n].indesc;
+		loc->token_offset = rhs[1].token_offset;
+		loc->line_offset  = rhs[1].line_offset;
+		loc->first_line   = rhs[1].first_line;
+		loc->first_column = rhs[1].first_column;
+		loc->last_line    = rhs[n].last_line;
+		loc->last_column  = rhs[n].last_column;
+	} else {
+		loc->indesc       = rhs[0].indesc;
+		loc->token_offset = rhs[0].token_offset;
+		loc->line_offset  = rhs[0].line_offset;
+		loc->first_line   = loc->last_line   = rhs[0].last_line;
+		loc->first_column = loc->last_column = rhs[0].last_column;
+	}
+}
+
+#define YYLLOC_DEFAULT(Current, Rhs, N)	location_update(&Current, Rhs, N)
+
+enum {
+	NFT_EVENT_NEW	= 0,
+	NFT_EVENT_DEL,
+};
+
+static int monitor_lookup_event(const char *event)
+{
+	if (strcmp(event, "new") == 0)
+		return NFT_EVENT_NEW;
+	else if (strcmp(event, "destroy") == 0)
+		return NFT_EVENT_DEL;
+
+	return -1;
+}
+
+%}
+
+/* Declaration section */
+
+%name-prefix "nft_"
+%debug
+%pure-parser
+%parse-param		{ void *scanner }
+%parse-param		{ struct parser_state *state }
+%lex-param		{ scanner }
+%error-verbose
+%locations
+
+%initial-action {
+	location_init(scanner, state, &yylloc);
+#ifdef DEBUG
+	if (debug_level & DEBUG_SCANNER)
+		nft_set_debug(1, scanner);
+	if (debug_level & DEBUG_PARSER)
+		yydebug = 1;
+#endif
+}
+
+%union {
+	uint64_t		val;
+	const char *		string;
+
+	struct list_head	*list;
+	struct cmd		*cmd;
+	struct handle		handle;
+	struct table		*table;
+	struct chain		*chain;
+	struct rule		*rule;
+	struct stmt		*stmt;
+	struct expr		*expr;
+	struct set		*set;
+}
+
+%token TOKEN_EOF 0		"end of file"
+%token JUNK			"junk"
+
+%token NEWLINE			"newline"
+%token COLON			"colon"
+%token SEMICOLON		"semicolon"
+%token COMMA			"comma"
+%token DOT			"."
+
+%token EQ			"=="
+%token NEQ			"!="
+%token LT			"<"
+%token GT			">"
+%token GTE			">="
+%token LTE			"<="
+%token LSHIFT			"<<"
+%token RSHIFT			">>"
+%token AMPERSAND		"&"
+%token CARET			"^"
+%token NOT			"!"
+%token SLASH			"/"
+%token ASTERISK			"*"
+%token DASH			"-"
+%token AT			"@"
+%token VMAP			"vmap"
+
+%token INCLUDE			"include"
+%token DEFINE			"define"
+
+%token HOOK			"hook"
+%token TABLE			"table"
+%token TABLES			"tables"
+%token CHAIN			"chain"
+%token CHAINS			"chains"
+%token RULE			"rule"
+%token RULES			"rules"
+%token SETS			"sets"
+%token SET			"set"
+%token ELEMENT			"element"
+%token MAP			"map"
+%token HANDLE			"handle"
+
+%token INET			"inet"
+
+%token ADD			"add"
+%token CREATE			"create"
+%token INSERT			"insert"
+%token DELETE			"delete"
+%token LIST			"list"
+%token FLUSH			"flush"
+%token RENAME			"rename"
+%token DESCRIBE			"describe"
+%token EXPORT			"export"
+%token MONITOR			"monitor"
+
+%token ACCEPT			"accept"
+%token DROP			"drop"
+%token CONTINUE			"continue"
+%token JUMP			"jump"
+%token GOTO			"goto"
+%token RETURN			"return"
+
+%token CONSTANT			"constant"
+%token INTERVAL			"interval"
+%token ELEMENTS			"elements"
+
+%token <val> NUM		"number"
+%token <string> STRING		"string"
+%token <string> QUOTED_STRING
+%destructor { xfree($$); }	STRING QUOTED_STRING
+
+%token LL_HDR			"ll"
+%token NETWORK_HDR		"nh"
+%token TRANSPORT_HDR		"th"
+
+%token BRIDGE			"bridge"
+
+%token ETHER			"ether"
+%token SADDR			"saddr"
+%token DADDR			"daddr"
+%token TYPE			"type"
+
+%token VLAN			"vlan"
+%token ID			"id"
+%token CFI			"cfi"
+%token PCP			"pcp"
+
+%token ARP			"arp"
+%token HTYPE			"htype"
+%token PTYPE			"ptype"
+%token HLEN			"hlen"
+%token PLEN			"plen"
+%token OPERATION		"operation"
+
+%token IP			"ip"
+%token VERSION			"version"
+%token HDRLENGTH		"hdrlength"
+%token TOS			"tos"
+%token LENGTH			"length"
+%token FRAG_OFF			"frag-off"
+%token TTL			"ttl"
+%token PROTOCOL			"protocol"
+%token CHECKSUM			"checksum"
+
+%token ICMP			"icmp"
+%token CODE			"code"
+%token SEQUENCE			"seq"
+%token GATEWAY			"gateway"
+%token MTU			"mtu"
+
+%token IP6			"ip6"
+%token PRIORITY			"priority"
+%token FLOWLABEL		"flowlabel"
+%token NEXTHDR			"nexthdr"
+%token HOPLIMIT			"hoplimit"
+
+%token ICMP6			"icmpv6"
+%token PPTR			"param-problem"
+%token MAXDELAY			"max-delay"
+
+%token AH			"ah"
+%token RESERVED			"reserved"
+%token SPI			"spi"
+
+%token ESP			"esp"
+
+%token COMP			"comp"
+%token FLAGS			"flags"
+%token CPI			"cpi"
+
+%token UDP			"udp"
+%token SPORT			"sport"
+%token DPORT			"dport"
+%token UDPLITE			"udplite"
+%token CSUMCOV			"csumcov"
+
+%token TCP			"tcp"
+%token ACKSEQ			"ackseq"
+%token DOFF			"doff"
+%token WINDOW			"window"
+%token URGPTR			"urgptr"
+
+%token DCCP			"dccp"
+
+%token SCTP			"sctp"
+%token VTAG			"vtag"
+
+%token RT			"rt"
+%token RT0			"rt0"
+%token RT2			"rt2"
+%token SEG_LEFT			"seg-left"
+%token ADDR			"addr"
+
+%token HBH			"hbh"
+
+%token FRAG			"frag"
+%token RESERVED2		"reserved2"
+%token MORE_FRAGMENTS		"more-fragments"
+
+%token DST			"dst"
+
+%token MH			"mh"
+
+%token META			"meta"
+%token NFPROTO			"nfproto"
+%token L4PROTO			"l4proto"
+%token MARK			"mark"
+%token IIF			"iif"
+%token IIFNAME			"iifname"
+%token IIFTYPE			"iiftype"
+%token OIF			"oif"
+%token OIFNAME			"oifname"
+%token OIFTYPE			"oiftype"
+%token SKUID			"skuid"
+%token SKGID			"skgid"
+%token NFTRACE			"nftrace"
+%token RTCLASSID		"rtclassid"
+%token IBRIPORT			"ibriport"
+%token OBRIPORT			"obriport"
+
+%token CT			"ct"
+%token DIRECTION		"direction"
+%token STATE			"state"
+%token STATUS			"status"
+%token EXPIRATION		"expiration"
+%token HELPER			"helper"
+%token L3PROTOCOL		"l3proto"
+%token PROTO_SRC		"proto-src"
+%token PROTO_DST		"proto-dst"
+%token LABEL			"label"
+
+%token COUNTER			"counter"
+%token PACKETS			"packets"
+%token BYTES			"bytes"
+
+%token LOG			"log"
+%token PREFIX			"prefix"
+%token GROUP			"group"
+%token SNAPLEN			"snaplen"
+%token QUEUE_THRESHOLD		"queue-threshold"
+
+%token LIMIT			"limit"
+%token RATE			"rate"
+
+%token NANOSECOND		"nanosecond"
+%token MICROSECOND		"microsecond"
+%token MILLISECOND		"millisecond"
+%token SECOND			"second"
+%token MINUTE			"minute"
+%token HOUR			"hour"
+%token DAY			"day"
+%token WEEK			"week"
+
+%token _REJECT			"reject"
+
+%token SNAT			"snat"
+%token DNAT			"dnat"
+
+%token QUEUE			"queue"
+%token QUEUENUM			"num"
+%token QUEUEBYPASS		"bypass"
+%token QUEUECPUFANOUT		"fanout"
+
+%token POSITION			"position"
+%token COMMENT			"comment"
+
+%token XML			"xml"
+%token JSON			"json"
+
+%type <string>			identifier string comment_spec
+%destructor { xfree($$); }	identifier string comment_spec
+
+%type <cmd>			line
+%destructor { cmd_free($$); }	line
+
+%type <cmd>			base_cmd add_cmd create_cmd insert_cmd delete_cmd list_cmd flush_cmd rename_cmd export_cmd monitor_cmd
+%destructor { cmd_free($$); }	base_cmd add_cmd create_cmd insert_cmd delete_cmd list_cmd flush_cmd rename_cmd export_cmd monitor_cmd
+
+%type <handle>			table_spec tables_spec chain_spec chain_identifier ruleid_spec
+%destructor { handle_free(&$$); } table_spec tables_spec chain_spec chain_identifier ruleid_spec
+%type <handle>			set_spec set_identifier
+%destructor { handle_free(&$$); } set_spec set_identifier
+%type <val>			handle_spec family_spec position_spec
+
+%type <table>			table_block_alloc table_block
+%destructor { close_scope(state); table_free($$); }	table_block_alloc
+%type <chain>			chain_block_alloc chain_block
+%destructor { close_scope(state); chain_free($$); }	chain_block_alloc
+%type <rule>			rule
+%destructor { rule_free($$); }	rule
+
+%type <val>			set_flag_list	set_flag
+
+%type <set>			set_block_alloc set_block
+%destructor { set_free($$); }	set_block_alloc
+
+%type <set>			map_block_alloc map_block
+%destructor { set_free($$); }	map_block_alloc
+
+%type <list>			stmt_list
+%destructor { stmt_list_free($$); xfree($$); } stmt_list
+%type <stmt>			stmt match_stmt verdict_stmt
+%destructor { stmt_free($$); }	stmt match_stmt verdict_stmt
+%type <stmt>			counter_stmt counter_stmt_alloc
+%destructor { stmt_free($$); }	counter_stmt counter_stmt_alloc
+%type <stmt>			ct_stmt
+%destructor { stmt_free($$); }	ct_stmt
+%type <stmt>			meta_stmt
+%destructor { stmt_free($$); }	meta_stmt
+%type <stmt>			log_stmt log_stmt_alloc
+%destructor { stmt_free($$); }	log_stmt log_stmt_alloc
+%type <stmt>			limit_stmt
+%destructor { stmt_free($$); }	limit_stmt
+%type <val>			time_unit
+%type <stmt>			reject_stmt
+%destructor { stmt_free($$); }	reject_stmt
+%type <stmt>			nat_stmt nat_stmt_alloc
+%destructor { stmt_free($$); }	nat_stmt nat_stmt_alloc
+%type <stmt>			queue_stmt queue_stmt_alloc queue_range
+%destructor { stmt_free($$); }	queue_stmt queue_stmt_alloc
+%type <val>			queue_flags queue_flag
+
+%type <expr>			symbol_expr verdict_expr integer_expr
+%destructor { expr_free($$); }	symbol_expr verdict_expr integer_expr
+%type <expr>			primary_expr shift_expr and_expr
+%destructor { expr_free($$); }	primary_expr shift_expr and_expr
+%type <expr>			exclusive_or_expr inclusive_or_expr
+%destructor { expr_free($$); }	exclusive_or_expr inclusive_or_expr
+%type <expr>			basic_expr
+%destructor { expr_free($$); }	basic_expr
+
+%type <expr>			multiton_expr
+%destructor { expr_free($$); }	multiton_expr
+%type <expr>			prefix_expr range_expr wildcard_expr
+%destructor { expr_free($$); }	prefix_expr range_expr wildcard_expr
+%type <expr>			list_expr
+%destructor { expr_free($$); }	list_expr
+%type <expr>			concat_expr map_lhs_expr
+%destructor { expr_free($$); }	concat_expr map_lhs_expr
+
+%type <expr>			map_expr
+%destructor { expr_free($$); }	map_expr
+
+%type <expr>			verdict_map_stmt
+%destructor { expr_free($$); }	verdict_map_stmt
+
+%type <expr>			verdict_map_expr verdict_map_list_expr verdict_map_list_member_expr
+%destructor { expr_free($$); }	verdict_map_expr verdict_map_list_expr verdict_map_list_member_expr
+
+%type <expr>			set_expr set_list_expr set_list_member_expr
+%destructor { expr_free($$); }	set_expr set_list_expr set_list_member_expr
+
+%type <expr>			expr initializer_expr
+%destructor { expr_free($$); }	expr initializer_expr
+
+%type <expr>			relational_expr
+%destructor { expr_free($$); }	relational_expr
+%type <val>			relational_op
+
+%type <expr>			payload_expr payload_raw_expr
+%destructor { expr_free($$); }	payload_expr payload_raw_expr
+%type <val>			payload_base_spec
+%type <expr>			eth_hdr_expr	vlan_hdr_expr
+%destructor { expr_free($$); }	eth_hdr_expr	vlan_hdr_expr
+%type <val>			eth_hdr_field	vlan_hdr_field
+%type <expr>			arp_hdr_expr
+%destructor { expr_free($$); }	arp_hdr_expr
+%type <val>			arp_hdr_field
+%type <expr>			ip_hdr_expr	icmp_hdr_expr
+%destructor { expr_free($$); }	ip_hdr_expr	icmp_hdr_expr
+%type <val>			ip_hdr_field	icmp_hdr_field
+%type <expr>			ip6_hdr_expr    icmp6_hdr_expr
+%destructor { expr_free($$); }	ip6_hdr_expr	icmp6_hdr_expr
+%type <val>			ip6_hdr_field   icmp6_hdr_field
+%type <expr>			auth_hdr_expr	esp_hdr_expr		comp_hdr_expr
+%destructor { expr_free($$); }	auth_hdr_expr	esp_hdr_expr		comp_hdr_expr
+%type <val>			auth_hdr_field	esp_hdr_field		comp_hdr_field
+%type <expr>			udp_hdr_expr	udplite_hdr_expr	tcp_hdr_expr
+%destructor { expr_free($$); }	udp_hdr_expr	udplite_hdr_expr	tcp_hdr_expr
+%type <val>			udp_hdr_field	udplite_hdr_field	tcp_hdr_field
+%type <expr>			dccp_hdr_expr	sctp_hdr_expr
+%destructor { expr_free($$); }	dccp_hdr_expr	sctp_hdr_expr
+%type <val>			dccp_hdr_field	sctp_hdr_field
+
+%type <expr>			exthdr_expr
+%destructor { expr_free($$); }	exthdr_expr
+%type <expr>			hbh_hdr_expr	frag_hdr_expr		dst_hdr_expr
+%destructor { expr_free($$); }	hbh_hdr_expr	frag_hdr_expr		dst_hdr_expr
+%type <val>			hbh_hdr_field	frag_hdr_field		dst_hdr_field
+%type <expr>			rt_hdr_expr	rt0_hdr_expr		rt2_hdr_expr
+%destructor { expr_free($$); }	rt_hdr_expr	rt0_hdr_expr		rt2_hdr_expr
+%type <val>			rt_hdr_field	rt0_hdr_field		rt2_hdr_field
+%type <expr>			mh_hdr_expr
+%destructor { expr_free($$); }	mh_hdr_expr
+%type <val>			mh_hdr_field
+
+%type <expr>			meta_expr
+%destructor { expr_free($$); }	meta_expr
+%type <val>			meta_key	meta_key_qualified	meta_key_unqualified
+
+%type <expr>			ct_expr
+%destructor { expr_free($$); }	ct_expr
+%type <val>			ct_key
+
+%type <val>			export_format	output_format	monitor_flags
+
+%%
+
+input			:	/* empty */
+			|	input		line
+			{
+				if ($2 != NULL) {
+					LIST_HEAD(list);
+
+					$2->location = @2;
+
+					list_add_tail(&$2->list, &list);
+					if (cmd_evaluate(&state->ectx, $2) < 0) {
+						if (++state->nerrs == max_errors)
+							YYABORT;
+					} else
+						list_splice_tail(&list, &state->cmds);
+				}
+			}
+			;
+
+stmt_seperator		:	NEWLINE
+			|	SEMICOLON
+			;
+
+opt_newline		:	NEWLINE
+		 	|	/* empty */
+			;
+
+common_block		:	INCLUDE		QUOTED_STRING	stmt_seperator
+			{
+				if (scanner_include_file(scanner, $2, &@$) < 0) {
+					xfree($2);
+					YYERROR;
+				}
+				xfree($2);
+			}
+			|	DEFINE		identifier	'='	initializer_expr	stmt_seperator
+			{
+				struct scope *scope = current_scope(state);
+
+				if (symbol_lookup(scope, $2) != NULL) {
+					erec_queue(error(&@2, "redfinition of symbol '%s'", $2),
+						   state->msgs);
+					YYERROR;
+				}
+
+				symbol_bind(scope, $2, $4);
+				xfree($2);
+			}
+			|	error		stmt_seperator
+			{
+				if (++state->nerrs == max_errors)
+					YYABORT;
+				yyerrok;
+			}
+			;
+
+line			:	common_block			{ $$ = NULL; }
+			|	stmt_seperator			{ $$ = NULL; }
+			|	base_cmd	stmt_seperator	{ $$ = $1; }
+			|	base_cmd	TOKEN_EOF
+			{
+				/*
+				 * Very hackish workaround for bison >= 2.4: previous versions
+				 * terminated parsing after EOF, 2.4+ tries to get further input
+				 * in 'input' and calls the scanner again, causing a crash when
+				 * the final input buffer has been popped. Terminate manually to
+				 * avoid this. The correct fix should be to adjust the grammar
+				 * to accept EOF in input, but for unknown reasons it does not
+				 * work.
+				 */
+				if ($1 != NULL) {
+					LIST_HEAD(list);
+
+					$1->location = @1;
+
+					list_add_tail(&$1->list, &list);
+					if (cmd_evaluate(&state->ectx, $1) < 0) {
+						if (++state->nerrs == max_errors)
+							YYABORT;
+					} else
+						list_splice_tail(&list, &state->cmds);
+				}
+				$$ = NULL;
+
+				YYACCEPT;
+			}
+			;
+
+base_cmd		:	/* empty */	add_cmd		{ $$ = $1; }
+	  		|	ADD		add_cmd		{ $$ = $2; }
+			|	CREATE		create_cmd	{ $$ = $2; }
+			|	INSERT		insert_cmd	{ $$ = $2; }
+			|	DELETE		delete_cmd	{ $$ = $2; }
+			|	LIST		list_cmd	{ $$ = $2; }
+			|	FLUSH		flush_cmd	{ $$ = $2; }
+			|	RENAME		rename_cmd	{ $$ = $2; }
+			|	EXPORT		export_cmd	{ $$ = $2; }
+			|	MONITOR		monitor_cmd	{ $$ = $2; }
+			|	DESCRIBE	primary_expr
+			{
+				expr_describe($2);
+				expr_free($2);
+				$$ = NULL;
+			}
+			;
+
+add_cmd			:	TABLE		table_spec
+			{
+				$$ = cmd_alloc(CMD_ADD, CMD_OBJ_TABLE, &$2, &@$, NULL);
+			}
+			|	TABLE		table_spec	table_block_alloc
+						'{'	table_block	'}'
+			{
+				handle_merge(&$3->handle, &$2);
+				close_scope(state);
+				$$ = cmd_alloc(CMD_ADD, CMD_OBJ_TABLE, &$2, &@$, $5);
+			}
+			|	CHAIN		chain_spec
+			{
+				$$ = cmd_alloc(CMD_ADD, CMD_OBJ_CHAIN, &$2, &@$, NULL);
+			}
+			|	CHAIN		chain_spec	chain_block_alloc
+						'{'	chain_block	'}'
+			{
+				$5->location = @5;
+				handle_merge(&$3->handle, &$2);
+				close_scope(state);
+				$$ = cmd_alloc(CMD_ADD, CMD_OBJ_CHAIN, &$2, &@$, $5);
+			}
+			|	RULE		ruleid_spec	rule
+			{
+				$$ = cmd_alloc(CMD_ADD, CMD_OBJ_RULE, &$2, &@$, $3);
+			}
+			|	/* empty */	ruleid_spec	rule
+			{
+				$$ = cmd_alloc(CMD_ADD, CMD_OBJ_RULE, &$1, &@$, $2);
+			}
+			|	SET		set_spec	set_block_alloc
+						'{'	set_block	'}'
+			{
+				$5->location = @5;
+				handle_merge(&$3->handle, &$2);
+				$$ = cmd_alloc(CMD_ADD, CMD_OBJ_SET, &$2, &@$, $5);
+			}
+			|	MAP		set_spec	map_block_alloc
+						'{'	map_block	'}'
+			{
+				$5->location = @5;
+				handle_merge(&$3->handle, &$2);
+				$$ = cmd_alloc(CMD_ADD, CMD_OBJ_SET, &$2, &@$, $5);
+			}
+			|	ELEMENT		set_spec	set_expr
+			{
+				$$ = cmd_alloc(CMD_ADD, CMD_OBJ_SETELEM, &$2, &@$, $3);
+			}
+			;
+
+create_cmd		:	TABLE		table_spec
+			{
+				$$ = cmd_alloc(CMD_CREATE, CMD_OBJ_TABLE, &$2, &@$, NULL);
+			}
+			|	TABLE		table_spec	table_block_alloc
+						'{'	table_block	'}'
+			{
+				handle_merge(&$3->handle, &$2);
+				close_scope(state);
+				$$ = cmd_alloc(CMD_CREATE, CMD_OBJ_TABLE, &$2, &@$, $5);
+			}
+			|	CHAIN		chain_spec
+			{
+				$$ = cmd_alloc(CMD_CREATE, CMD_OBJ_CHAIN, &$2, &@$, NULL);
+			}
+			|	CHAIN		chain_spec	chain_block_alloc
+						'{'	chain_block	'}'
+			{
+				$5->location = @5;
+				handle_merge(&$3->handle, &$2);
+				close_scope(state);
+				$$ = cmd_alloc(CMD_CREATE, CMD_OBJ_CHAIN, &$2, &@$, $5);
+			}
+			;
+
+insert_cmd		:	RULE		ruleid_spec	rule
+			{
+				$$ = cmd_alloc(CMD_INSERT, CMD_OBJ_RULE, &$2, &@$, $3);
+			}
+			;
+
+delete_cmd		:	TABLE		table_spec
+			{
+				$$ = cmd_alloc(CMD_DELETE, CMD_OBJ_TABLE, &$2, &@$, NULL);
+			}
+			|	CHAIN		chain_spec
+			{
+				$$ = cmd_alloc(CMD_DELETE, CMD_OBJ_CHAIN, &$2, &@$, NULL);
+			}
+			|	RULE		ruleid_spec
+			{
+				$$ = cmd_alloc(CMD_DELETE, CMD_OBJ_RULE, &$2, &@$, NULL);
+			}
+			|	SET		set_spec
+			{
+				$$ = cmd_alloc(CMD_DELETE, CMD_OBJ_SET, &$2, &@$, NULL);
+			}
+			|	MAP		set_spec
+			{
+				$$ = cmd_alloc(CMD_DELETE, CMD_OBJ_SET, &$2, &@$, NULL);
+			}
+			|	ELEMENT		set_spec	set_expr
+			{
+				$$ = cmd_alloc(CMD_DELETE, CMD_OBJ_SETELEM, &$2, &@$, $3);
+			}
+			;
+
+list_cmd		:	TABLE		table_spec
+			{
+				$$ = cmd_alloc(CMD_LIST, CMD_OBJ_TABLE, &$2, &@$, NULL);
+			}
+			|	TABLES		tables_spec
+			{
+				$$ = cmd_alloc(CMD_LIST, CMD_OBJ_TABLE, &$2, &@$, NULL);
+			}
+			|	CHAIN		chain_spec
+			{
+				$$ = cmd_alloc(CMD_LIST, CMD_OBJ_CHAIN, &$2, &@$, NULL);
+			}
+			|	SETS		tables_spec
+			{
+				$$ = cmd_alloc(CMD_LIST, CMD_OBJ_SETS, &$2, &@$, NULL);
+			}
+			|	SET		set_spec
+			{
+				$$ = cmd_alloc(CMD_LIST, CMD_OBJ_SET, &$2, &@$, NULL);
+			}
+			;
+
+flush_cmd		:	TABLE		table_spec
+			{
+				$$ = cmd_alloc(CMD_FLUSH, CMD_OBJ_TABLE, &$2, &@$, NULL);
+			}
+			|	CHAIN		chain_spec
+			{
+				$$ = cmd_alloc(CMD_FLUSH, CMD_OBJ_CHAIN, &$2, &@$, NULL);
+			}
+			|	SET		set_spec
+			{
+				$$ = cmd_alloc(CMD_FLUSH, CMD_OBJ_SET, &$2, &@$, NULL);
+			}
+			;
+
+rename_cmd		:	CHAIN		chain_spec	identifier
+			{
+				$$ = cmd_alloc(CMD_RENAME, CMD_OBJ_CHAIN, &$2, &@$, NULL);
+				$$->arg = $3;
+			}
+			;
+
+export_cmd		:	export_format
+			{
+				struct handle h = { .family = NFPROTO_UNSPEC };
+				$$ = cmd_alloc(CMD_EXPORT, CMD_OBJ_RULESET, &h, &@$, NULL);
+				$$->format = $1;
+			}
+			;
+
+monitor_cmd		:	monitor_flags	output_format
+			{
+				struct handle h = { .family = NFPROTO_UNSPEC };
+				$$ = cmd_alloc(CMD_MONITOR, CMD_OBJ_RULESET, &h, &@$, NULL);
+				$$->monitor_flags = $1;
+				$$->format = $2;
+			}
+			;
+
+monitor_flags		:	/* empty */
+			{
+				$$ = (1 << NFT_MSG_NEWRULE)	|
+				     (1 << NFT_MSG_DELRULE)	|
+				     (1 << NFT_MSG_NEWSET)	|
+				     (1 << NFT_MSG_DELSET)	|
+				     (1 << NFT_MSG_NEWSETELEM)	|
+				     (1 << NFT_MSG_DELSETELEM)	|
+				     (1 << NFT_MSG_NEWCHAIN)	|
+				     (1 << NFT_MSG_DELCHAIN)	|
+				     (1 << NFT_MSG_NEWTABLE)	|
+				     (1 << NFT_MSG_DELTABLE);
+			}
+			|	STRING
+			{
+				int event;
+
+				event = monitor_lookup_event($1);
+				if (event < 0) {
+					erec_queue(error(&@1, "unknown event type %s", $1),
+						   state->msgs);
+					YYERROR;
+				}
+
+				switch (event) {
+				case NFT_EVENT_NEW:
+					$$ = (1 << NFT_MSG_NEWTABLE)	|
+					     (1 << NFT_MSG_NEWCHAIN)	|
+					     (1 << NFT_MSG_NEWRULE)	|
+					     (1 << NFT_MSG_NEWSET)	|
+					     (1 << NFT_MSG_NEWSETELEM);
+					break;
+				case NFT_EVENT_DEL:
+					$$ = (1 << NFT_MSG_DELTABLE)	|
+					     (1 << NFT_MSG_DELCHAIN)	|
+					     (1 << NFT_MSG_DELRULE)	|
+					     (1 << NFT_MSG_DELSET)	|
+					     (1 << NFT_MSG_DELSETELEM);
+					break;
+				}
+			}
+			|	TABLES
+			{
+				$$ = (1 << NFT_MSG_NEWTABLE) |
+				     (1 << NFT_MSG_DELTABLE);
+			}
+			|	STRING 	TABLES
+			{
+				int event;
+
+				event = monitor_lookup_event($1);
+				if (event < 0) {
+					erec_queue(error(&@1, "unknown event type %s", $1),
+						   state->msgs);
+					YYERROR;
+				}
+
+				switch (event) {
+				case NFT_EVENT_NEW:
+					$$ = (1 << NFT_MSG_NEWTABLE);
+					break;
+				case NFT_EVENT_DEL:
+					$$ = (1 << NFT_MSG_DELTABLE);
+					break;
+				}
+			}
+			|	CHAINS
+			{
+				$$ = (1 << NFT_MSG_NEWCHAIN) |
+				     (1 << NFT_MSG_DELCHAIN);
+			}
+			|	STRING	CHAINS
+			{
+				int event;
+
+				event = monitor_lookup_event($1);
+				if (event < 0) {
+					erec_queue(error(&@1, "unknown event type %s", $1),
+						   state->msgs);
+					YYERROR;
+				}
+
+				switch (event) {
+				case NFT_EVENT_NEW:
+					$$ = (1 << NFT_MSG_NEWCHAIN);
+					break;
+				case NFT_EVENT_DEL:
+					$$ = (1 << NFT_MSG_DELCHAIN);
+					break;
+				}
+			}
+			|	SETS
+			{
+				$$ = (1 << NFT_MSG_NEWSET) |
+				     (1 << NFT_MSG_DELSET);
+			}
+			|	STRING	SETS
+			{
+				int event;
+
+				event = monitor_lookup_event($1);
+				if (event < 0) {
+					erec_queue(error(&@1, "unknown event type %s", $1),
+						   state->msgs);
+					YYERROR;
+				}
+
+				switch (event) {
+				case NFT_EVENT_NEW:
+					$$ = (1 << NFT_MSG_NEWSET);
+					break;
+				case NFT_EVENT_DEL:
+					$$ = (1 << NFT_MSG_DELSET);
+					break;
+				}
+			}
+			|	RULES
+			{
+				$$ = (1 << NFT_MSG_NEWRULE) |
+				     (1 << NFT_MSG_DELRULE);
+			}
+			|	STRING 	RULES
+			{
+				int event;
+
+				event = monitor_lookup_event($1);
+				if (event < 0) {
+					erec_queue(error(&@1, "unknown event type %s", $1),
+						   state->msgs);
+					YYERROR;
+				}
+
+				switch (event) {
+				case NFT_EVENT_NEW:
+					$$ = (1 << NFT_MSG_NEWRULE);
+					break;
+				case NFT_EVENT_DEL:
+					$$ = (1 << NFT_MSG_DELRULE);
+					break;
+				}
+			}
+			|	ELEMENTS
+			{
+				$$ = (1 << NFT_MSG_NEWSETELEM) |
+				     (1 << NFT_MSG_DELSETELEM);
+			}
+			|	STRING	ELEMENTS
+			{
+				int event;
+
+				event = monitor_lookup_event($1);
+				if (event < 0) {
+					erec_queue(error(&@1, "unknown event type %s", $1),
+						   state->msgs);
+					YYERROR;
+				}
+
+				switch (event) {
+				case NFT_EVENT_NEW:
+					$$ = (1 << NFT_MSG_NEWSETELEM);
+					break;
+				case NFT_EVENT_DEL:
+					$$ = (1 << NFT_MSG_DELSETELEM);
+					break;
+				}
+			}
+			;
+
+output_format		:	/* empty */
+			{
+				$$ = NFT_OUTPUT_DEFAULT;
+			}
+			|	export_format
+			;
+
+table_block_alloc	:	/* empty */
+			{
+				$$ = table_alloc();
+				open_scope(state, &$$->scope);
+			}
+			;
+
+table_block		:	/* empty */	{ $$ = $<table>-1; }
+			|	table_block	common_block
+			|	table_block	stmt_seperator
+			|	table_block	CHAIN		chain_identifier
+					chain_block_alloc	'{' 	chain_block	'}'
+					stmt_seperator
+			{
+				$4->location = @3;
+				handle_merge(&$4->handle, &$3);
+				handle_free(&$3);
+				close_scope(state);
+				list_add_tail(&$4->list, &$1->chains);
+				$$ = $1;
+			}
+			|	table_block	SET		set_identifier
+					set_block_alloc		'{'	set_block	'}'
+					stmt_seperator
+			{
+				$4->location = @3;
+				handle_merge(&$4->handle, &$3);
+				handle_free(&$3);
+				list_add_tail(&$4->list, &$1->sets);
+				$$ = $1;
+			}
+			|	table_block	MAP		set_identifier
+					map_block_alloc		'{'	map_block	'}'
+					stmt_seperator
+			{
+				$4->location = @3;
+				handle_merge(&$4->handle, &$3);
+				handle_free(&$3);
+				list_add_tail(&$4->list, &$1->sets);
+				$$ = $1;
+			}
+			;
+
+chain_block_alloc	:	/* empty */
+			{
+				$$ = chain_alloc(NULL);
+				open_scope(state, &$$->scope);
+			}
+			;
+
+chain_block		:	/* empty */	{ $$ = $<chain>-1; }
+			|	chain_block	common_block
+	     		|	chain_block	stmt_seperator
+			|	chain_block	hook_spec	stmt_seperator
+			|	chain_block	rule		stmt_seperator
+			{
+				list_add_tail(&$2->list, &$1->rules);
+				$$ = $1;
+			}
+			;
+
+set_block_alloc		:	/* empty */
+			{
+				$$ = set_alloc(NULL);
+			}
+			;
+
+set_block		:	/* empty */	{ $$ = $<set>-1; }
+			|	set_block	common_block
+			|	set_block	stmt_seperator
+			|	set_block	TYPE		identifier	stmt_seperator
+			{
+				$1->keytype = datatype_lookup_byname($3);
+				if ($1->keytype == NULL) {
+					erec_queue(error(&@3, "unknown datatype %s", $3),
+						   state->msgs);
+					YYERROR;
+				}
+				$$ = $1;
+			}
+			|	set_block	FLAGS		set_flag_list	stmt_seperator
+			{
+				$1->flags = $3;
+				$$ = $1;
+			}
+			|	set_block	ELEMENTS	'='		set_expr
+			{
+				$1->init = $4;
+				$$ = $1;
+			}
+			;
+
+set_flag_list		:	set_flag_list	COMMA		set_flag
+			{
+				$$ = $1 | $3;
+			}
+			|	set_flag
+			;
+
+set_flag		:	CONSTANT	{ $$ = SET_F_CONSTANT; }
+			|	INTERVAL	{ $$ = SET_F_INTERVAL; }
+			;
+
+map_block_alloc		:	/* empty */
+			{
+				$$ = set_alloc(NULL);
+				$$->flags |= NFT_SET_MAP;
+			}
+			;
+
+map_block		:	/* empty */	{ $$ = $<set>-1; }
+			|	map_block	common_block
+			|	map_block	stmt_seperator
+			|	map_block	TYPE
+						identifier	COLON	identifier
+						stmt_seperator
+			{
+				$1->keytype = datatype_lookup_byname($3);
+				if ($1->keytype == NULL) {
+					erec_queue(error(&@3, "unknown datatype %s", $3),
+						   state->msgs);
+					YYERROR;
+				}
+
+				$1->datatype = datatype_lookup_byname($5);
+				if ($1->datatype == NULL) {
+					erec_queue(error(&@5, "unknown datatype %s", $5),
+						   state->msgs);
+					YYERROR;
+				}
+
+				$$ = $1;
+			}
+			|	map_block	FLAGS		set_flag_list	stmt_seperator
+			{
+				$1->flags = $3;
+				$$ = $1;
+			}
+			|	map_block	ELEMENTS	'='		set_expr
+			{
+				$1->init = $4;
+				$$ = $1;
+			}
+			;
+
+hook_spec		:	TYPE		STRING		HOOK		STRING		PRIORITY	NUM
+			{
+				$<chain>0->type		= chain_type_name_lookup($2);
+				if ($<chain>0->type == NULL) {
+					erec_queue(error(&@2, "unknown chain type %s", $2),
+						   state->msgs);
+					YYERROR;
+				}
+				$<chain>0->hookstr	= chain_hookname_lookup($4);
+				if ($<chain>0->hookstr == NULL) {
+					erec_queue(error(&@4, "unknown chain type %s", $4),
+						   state->msgs);
+					YYERROR;
+				}
+				$<chain>0->priority	= $6;
+				$<chain>0->flags	|= CHAIN_F_BASECHAIN;
+			}
+			|	TYPE		STRING		HOOK		STRING		PRIORITY	DASH	NUM
+			{
+				$<chain>0->type		= chain_type_name_lookup($2);
+				if ($<chain>0->type == NULL) {
+					erec_queue(error(&@2, "unknown type name %s", $2),
+						   state->msgs);
+					YYERROR;
+				}
+				$<chain>0->hookstr	= chain_hookname_lookup($4);
+				if ($<chain>0->hookstr == NULL) {
+					erec_queue(error(&@4, "unknown hook name %s", $4),
+						   state->msgs);
+					YYERROR;
+				}
+				$<chain>0->priority	= -$7;
+				$<chain>0->flags	|= CHAIN_F_BASECHAIN;
+			}
+			;
+
+identifier		:	STRING
+			;
+
+string			:	STRING
+			|	QUOTED_STRING
+			;
+
+family_spec		:	/* empty */	{ $$ = NFPROTO_IPV4; }
+			|	IP		{ $$ = NFPROTO_IPV4; }
+			|	IP6		{ $$ = NFPROTO_IPV6; }
+			|	INET		{ $$ = NFPROTO_INET; }
+			|	ARP		{ $$ = NFPROTO_ARP; }
+			|	BRIDGE		{ $$ = NFPROTO_BRIDGE; }
+			;
+
+table_spec		:	family_spec	identifier
+			{
+				memset(&$$, 0, sizeof($$));
+				$$.family	= $1;
+				$$.table	= $2;
+			}
+			;
+
+tables_spec		:	family_spec
+			{
+				memset(&$$, 0, sizeof($$));
+				$$.family	= $1;
+				$$.table	= NULL;
+			}
+			;
+
+chain_spec		:	table_spec	identifier
+			{
+				$$		= $1;
+				$$.chain	= $2;
+			}
+			;
+
+chain_identifier	:	identifier
+			{
+				memset(&$$, 0, sizeof($$));
+				$$.chain	= $1;
+			}
+			;
+
+set_spec		:	table_spec	identifier
+			{
+				$$		= $1;
+				$$.set		= $2;
+			}
+			;
+
+set_identifier		:	identifier
+			{
+				memset(&$$, 0, sizeof($$));
+				$$.set		= $1;
+			}
+			;
+
+handle_spec		:	/* empty */
+			{
+				$$ = 0;
+			}
+			|	HANDLE		NUM
+			{
+				$$ = $2;
+			}
+			;
+
+position_spec		:	/* empty */
+			{
+				$$ = 0;
+			}
+			|	POSITION	NUM
+			{
+				$$ = $2;
+			}
+			;
+
+ruleid_spec		:	chain_spec	handle_spec	position_spec
+			{
+				$$		= $1;
+				$$.handle	= $2;
+				$$.position	= $3;
+			}
+			;
+
+comment_spec		:	/* empty */
+			{
+				$$ = NULL;
+			}
+			|	COMMENT		string
+			{
+				$$ = $2;
+			}
+			;
+
+rule			:	stmt_list	comment_spec
+			{
+				struct stmt *i;
+
+				$$ = rule_alloc(&@$, NULL);
+				$$->handle.comment = $2;
+				list_for_each_entry(i, $1, list)
+					$$->num_stmts++;
+				list_splice_tail($1, &$$->stmts);
+				xfree($1);
+			}
+			;
+
+stmt_list		:	stmt
+			{
+				$$ = xmalloc(sizeof(*$$));
+				init_list_head($$);
+				list_add_tail(&$1->list, $$);
+			}
+			|	stmt_list		stmt
+			{
+				$$ = $1;
+				list_add_tail(&$2->list, $1);
+			}
+			;
+
+stmt			:	verdict_stmt
+			|	match_stmt
+			|	counter_stmt
+			|	meta_stmt
+			|	log_stmt
+			|	limit_stmt
+			|	reject_stmt
+			|	nat_stmt
+			|	queue_stmt
+			|	ct_stmt
+			;
+
+verdict_stmt		:	verdict_expr
+			{
+				$$ = verdict_stmt_alloc(&@$, $1);
+			}
+			|	verdict_map_stmt
+			{
+				$$ = verdict_stmt_alloc(&@$, $1);
+			}
+			;
+
+verdict_map_stmt	:	concat_expr	VMAP	verdict_map_expr
+			{
+				$$ = map_expr_alloc(&@$, $1, $3);
+			}
+			;
+
+verdict_map_expr	:	'{'	verdict_map_list_expr	'}'
+			{
+				$2->location = @$;
+				$$ = $2;
+			}
+			;
+
+verdict_map_list_expr	:	verdict_map_list_member_expr
+			{
+				$$ = set_expr_alloc(&@$);
+				compound_expr_add($$, $1);
+			}
+			|	verdict_map_list_expr	COMMA	verdict_map_list_member_expr
+			{
+				compound_expr_add($1, $3);
+				$$ = $1;
+			}
+			|	verdict_map_list_expr	COMMA	opt_newline
+			;
+
+verdict_map_list_member_expr:	opt_newline	map_lhs_expr	COLON	verdict_expr	opt_newline
+			{
+				$$ = mapping_expr_alloc(&@$, $2, $4);
+			}
+			;
+
+
+counter_stmt		:	counter_stmt_alloc
+			|	counter_stmt_alloc	counter_args
+
+counter_stmt_alloc	:	COUNTER
+			{
+				$$ = counter_stmt_alloc(&@$);
+			}
+			;
+
+counter_args		:	counter_arg
+			{
+				$<stmt>$	= $<stmt>0;
+			}
+			|	counter_args	counter_arg
+			;
+
+counter_arg		:	PACKETS			NUM
+			{
+				$<stmt>0->counter.packets = $2;
+			}
+			|	BYTES			NUM
+			{
+				$<stmt>0->counter.bytes	 = $2;
+			}
+			;
+
+log_stmt		:	log_stmt_alloc
+			|	log_stmt_alloc		log_args
+			;
+
+log_stmt_alloc		:	LOG
+			{
+				$$ = log_stmt_alloc(&@$);
+			}
+			;
+
+log_args		:	log_arg
+			{
+				$<stmt>$	= $<stmt>0;
+			}
+			|	log_args	log_arg
+			;
+
+log_arg			:	PREFIX			string
+			{
+				$<stmt>0->log.prefix	 = $2;
+			}
+			|	GROUP			NUM
+			{
+				$<stmt>0->log.group	 = $2;
+			}
+			|	SNAPLEN			NUM
+			{
+				$<stmt>0->log.snaplen	 = $2;
+			}
+			|	QUEUE_THRESHOLD		NUM
+			{
+				$<stmt>0->log.qthreshold = $2;
+			}
+			;
+
+limit_stmt		:	LIMIT	RATE	NUM	SLASH	time_unit
+	    		{
+				$$ = limit_stmt_alloc(&@$);
+				$$->limit.rate	= $3;
+				$$->limit.unit	= $5;
+			}
+			;
+
+time_unit		:	SECOND		{ $$ = 1ULL; }
+			|	MINUTE		{ $$ = 1ULL * 60; }
+			|	HOUR		{ $$ = 1ULL * 60 * 60; }
+			|	DAY		{ $$ = 1ULL * 60 * 60 * 24; }
+			|	WEEK		{ $$ = 1ULL * 60 * 60 * 24 * 7; }
+			;
+
+reject_stmt		:	_REJECT
+			{
+				$$ = reject_stmt_alloc(&@$);
+			}
+			;
+
+nat_stmt		:	nat_stmt_alloc	nat_stmt_args
+			;
+
+nat_stmt_alloc		:	SNAT
+			{
+				$$ = nat_stmt_alloc(&@$);
+				$$->nat.type = NFT_NAT_SNAT;
+			}
+			|	DNAT
+			{
+				$$ = nat_stmt_alloc(&@$);
+				$$->nat.type = NFT_NAT_DNAT;
+			}
+			;
+
+nat_stmt_args		:	expr
+			{
+				$<stmt>0->nat.addr = $1;
+			}
+			|	expr	COLON	expr
+			{
+				$<stmt>0->nat.addr = $1;
+				$<stmt>0->nat.proto = $3;
+			}
+			|	COLON	expr
+			{
+				$<stmt>0->nat.proto = $2;
+			}
+			;
+
+queue_stmt		:	queue_stmt_alloc
+			|	queue_stmt_alloc		queue_args
+			;
+
+queue_stmt_alloc	:	QUEUE
+			{
+				$$ = queue_stmt_alloc(&@$);
+			}
+			;
+
+queue_args		:	QUEUENUM	queue_range	queue_flags
+			{
+				$<stmt>0->queue.from = $2->queue.from;
+				$<stmt>0->queue.to = $2->queue.to;
+				$<stmt>0->queue.flags = $3;
+			}
+			|	QUEUENUM	queue_range
+			{
+				$<stmt>0->queue.from = $2->queue.from;
+				$<stmt>0->queue.to = $2->queue.to;
+			}
+			|	queue_flags
+			{
+				$<stmt>0->queue.flags = $1;
+			}
+			;
+
+queue_range		:	NUM
+			{
+				$<stmt>0->queue.from = $1;
+				$<stmt>0->queue.to = $1;
+				$$ = $<stmt>0;
+			}
+			|	NUM	DASH	NUM
+			{
+				if ($3 < $1) {
+					erec_queue(error(&@1,
+							 "invalid range %d-%d",
+							 $1, $3), state->msgs);
+					YYERROR;
+				}
+				$<stmt>0->queue.from = $1;
+				$<stmt>0->queue.to = $3;
+				$$ = $<stmt>0;
+			}
+			;
+
+queue_flags		:	queue_flag
+			{
+				$$ = $1;
+			}
+			|	queue_flags	queue_flag
+			{
+				$$ |= $1 | $2;
+			}
+			;
+
+queue_flag		:	QUEUEBYPASS
+			{
+				$$ = NFT_QUEUE_FLAG_BYPASS;
+			}
+			|	QUEUECPUFANOUT
+			{
+				$$ = NFT_QUEUE_FLAG_CPU_FANOUT;
+			}
+			;
+
+match_stmt		:	relational_expr
+			{
+				$$ = expr_stmt_alloc(&@$, $1);
+			}
+			;
+
+symbol_expr		:	string
+			{
+				$$ = symbol_expr_alloc(&@$, SYMBOL_VALUE,
+						       current_scope(state),
+						       $1);
+				xfree($1);
+			}
+			|	'$'	identifier
+			{
+				struct scope *scope = current_scope(state);
+
+				if (symbol_lookup(scope, $2) == NULL) {
+					erec_queue(error(&@2, "unknown identifier '%s'", $2),
+						   state->msgs);
+					YYERROR;
+				}
+
+				$$ = symbol_expr_alloc(&@$, SYMBOL_DEFINE,
+						       scope, $2);
+				xfree($2);
+			}
+			|	AT	identifier
+			{
+				$$ = symbol_expr_alloc(&@$, SYMBOL_SET,
+						       current_scope(state),
+						       $2);
+				xfree($2);
+			}
+			;
+
+integer_expr		:	NUM
+			{
+				char str[64];
+
+				snprintf(str, sizeof(str), "%" PRIu64, $1);
+				$$ = symbol_expr_alloc(&@$, SYMBOL_VALUE,
+						       current_scope(state),
+						       str);
+			}
+			;
+
+primary_expr		:	symbol_expr			{ $$ = $1; }
+			|	integer_expr			{ $$ = $1; }
+			|	payload_expr			{ $$ = $1; }
+			|	exthdr_expr			{ $$ = $1; }
+			|	meta_expr			{ $$ = $1; }
+			|	ct_expr				{ $$ = $1; }
+			|	'('	basic_expr	')'	{ $$ = $2; }
+			;
+
+shift_expr		:	primary_expr
+			|	shift_expr		LSHIFT		primary_expr
+			{
+				$$ = binop_expr_alloc(&@$, OP_LSHIFT, $1, $3);
+			}
+			|	shift_expr		RSHIFT		primary_expr
+			{
+				$$ = binop_expr_alloc(&@$, OP_RSHIFT, $1, $3);
+			}
+			;
+
+and_expr		:	shift_expr
+			|	and_expr		AMPERSAND	shift_expr
+			{
+				$$ = binop_expr_alloc(&@$, OP_AND, $1, $3);
+			}
+			;
+
+exclusive_or_expr	:	and_expr
+			|	exclusive_or_expr	CARET		and_expr
+			{
+				$$ = binop_expr_alloc(&@$, OP_XOR, $1, $3);
+			}
+			;
+
+inclusive_or_expr	:	exclusive_or_expr
+			|	inclusive_or_expr	'|'		exclusive_or_expr
+			{
+				$$ = binop_expr_alloc(&@$, OP_OR, $1, $3);
+			}
+			;
+
+basic_expr		:	inclusive_or_expr
+			;
+
+concat_expr		:	basic_expr
+			|	concat_expr		DOT		basic_expr
+			{
+				if ($$->ops->type != EXPR_CONCAT) {
+					$$ = concat_expr_alloc(&@$);
+					compound_expr_add($$, $1);
+				} else {
+					struct location rhs[] = {
+						[1]	= @2,
+						[2]	= @3,
+					};
+					location_update(&$3->location, rhs, 2);
+
+					$$ = $1;
+					$$->location = @$;
+				}
+				compound_expr_add($$, $3);
+			}
+			;
+
+list_expr		:	basic_expr		COMMA		basic_expr
+			{
+				$$ = list_expr_alloc(&@$);
+				compound_expr_add($$, $1);
+				compound_expr_add($$, $3);
+			}
+			|	list_expr		COMMA		basic_expr
+			{
+				$1->location = @$;
+				compound_expr_add($1, $3);
+				$$ = $1;
+			}
+			;
+
+prefix_expr		:	basic_expr		SLASH	NUM
+			{
+				$$ = prefix_expr_alloc(&@$, $1, $3);
+			}
+			;
+
+range_expr		:	basic_expr		DASH	basic_expr
+			{
+				$$ = range_expr_alloc(&@$, $1, $3);
+			}
+			;
+
+wildcard_expr		:	ASTERISK
+	       		{
+				struct expr *expr;
+
+				expr = constant_expr_alloc(&@$, &integer_type,
+							   BYTEORDER_HOST_ENDIAN,
+							   0, NULL);
+				$$ = prefix_expr_alloc(&@$, expr, 0);
+			}
+			;
+
+multiton_expr		:	prefix_expr
+			|	range_expr
+			|	wildcard_expr
+			;
+
+map_lhs_expr		:	multiton_expr
+			|	concat_expr
+			;
+
+map_expr		:	concat_expr	MAP	expr
+			{
+				$$ = map_expr_alloc(&@$, $1, $3);
+			}
+			;
+
+expr			:	concat_expr
+			|	set_expr
+			|       map_expr
+			|	multiton_expr
+			;
+
+set_expr		:	'{'	set_list_expr		'}'
+			{
+				$2->location = @$;
+				$$ = $2;
+			}
+			;
+
+set_list_expr		:	set_list_member_expr
+			{
+				$$ = set_expr_alloc(&@$);
+				compound_expr_add($$, $1);
+			}
+			|	set_list_expr		COMMA	set_list_member_expr
+			{
+				compound_expr_add($1, $3);
+				$$ = $1;
+			}
+			|	set_list_expr		COMMA	opt_newline
+			;
+
+set_list_member_expr	:	opt_newline	expr	opt_newline
+			{
+				$$ = $2;
+			}
+			|	opt_newline	map_lhs_expr	COLON	concat_expr	opt_newline
+			{
+				$$ = mapping_expr_alloc(&@$, $2, $4);
+			}
+			;
+
+initializer_expr	:	expr
+			|	list_expr
+			;
+
+relational_expr		:	expr	/* implicit */	expr
+			{
+				$$ = relational_expr_alloc(&@$, OP_IMPLICIT, $1, $2);
+			}
+			|	expr	/* implicit */	list_expr
+			{
+				$$ = relational_expr_alloc(&@$, OP_FLAGCMP, $1, $2);
+			}
+			|	expr	relational_op	expr
+			{
+				$$ = relational_expr_alloc(&@2, $2, $1, $3);
+			}
+			;
+
+relational_op		:	EQ		{ $$ = OP_EQ; }
+			|	NEQ		{ $$ = OP_NEQ; }
+			|	LT		{ $$ = OP_LT; }
+			|	GT		{ $$ = OP_GT; }
+			|	GTE		{ $$ = OP_GTE; }
+			|	LTE		{ $$ = OP_LTE; }
+			;
+
+verdict_expr		:	ACCEPT
+			{
+				$$ = verdict_expr_alloc(&@$, NF_ACCEPT, NULL);
+			}
+			|	DROP
+			{
+				$$ = verdict_expr_alloc(&@$, NF_DROP, NULL);
+			}
+			|	CONTINUE
+			{
+				$$ = verdict_expr_alloc(&@$, NFT_CONTINUE, NULL);
+			}
+			|	JUMP			identifier
+			{
+				$$ = verdict_expr_alloc(&@$, NFT_JUMP, $2);
+			}
+			|	GOTO			identifier
+			{
+				$$ = verdict_expr_alloc(&@$, NFT_GOTO, $2);
+			}
+			|	RETURN
+			{
+				$$ = verdict_expr_alloc(&@$, NFT_RETURN, NULL);
+			}
+			;
+
+meta_expr		:	META	meta_key
+			{
+				$$ = meta_expr_alloc(&@$, $2);
+			}
+			|	meta_key_unqualified
+			{
+				$$ = meta_expr_alloc(&@$, $1);
+			}
+			;
+
+meta_key		:	meta_key_qualified
+			|	meta_key_unqualified
+			;
+
+meta_key_qualified	:	LENGTH		{ $$ = NFT_META_LEN; }
+			|	NFPROTO		{ $$ = NFT_META_NFPROTO; }
+			|	L4PROTO		{ $$ = NFT_META_L4PROTO; }
+			|	PROTOCOL	{ $$ = NFT_META_PROTOCOL; }
+			|	PRIORITY	{ $$ = NFT_META_PRIORITY; }
+			;
+
+meta_key_unqualified	:	MARK		{ $$ = NFT_META_MARK; }
+			|	IIF		{ $$ = NFT_META_IIF; }
+			|	IIFNAME		{ $$ = NFT_META_IIFNAME; }
+			|	IIFTYPE		{ $$ = NFT_META_IIFTYPE; }
+			|	OIF		{ $$ = NFT_META_OIF; }
+			|	OIFNAME		{ $$ = NFT_META_OIFNAME; }
+			|	OIFTYPE		{ $$ = NFT_META_OIFTYPE; }
+			|	SKUID		{ $$ = NFT_META_SKUID; }
+			|	SKGID		{ $$ = NFT_META_SKGID; }
+			|	NFTRACE		{ $$ = NFT_META_NFTRACE; }
+			|	RTCLASSID	{ $$ = NFT_META_RTCLASSID; }
+			|	IBRIPORT	{ $$ = NFT_META_BRI_IIFNAME; }
+			|       OBRIPORT	{ $$ = NFT_META_BRI_OIFNAME; }
+			;
+
+meta_stmt		:	META	meta_key	SET	expr
+			{
+				$$ = meta_stmt_alloc(&@$, $2, $4);
+			}
+			|	meta_key_unqualified	SET	expr
+			{
+				$$ = meta_stmt_alloc(&@$, $1, $3);
+			}
+			;
+
+ct_expr			:	CT	ct_key
+			{
+				$$ = ct_expr_alloc(&@$, $2);
+			}
+			;
+
+ct_key			:	STATE		{ $$ = NFT_CT_STATE; }
+			|	DIRECTION	{ $$ = NFT_CT_DIRECTION; }
+			|	STATUS		{ $$ = NFT_CT_STATUS; }
+			|	MARK		{ $$ = NFT_CT_MARK; }
+			|	EXPIRATION	{ $$ = NFT_CT_EXPIRATION; }
+			|	HELPER		{ $$ = NFT_CT_HELPER; }
+			|	L3PROTOCOL	{ $$ = NFT_CT_L3PROTOCOL; }
+			|	SADDR		{ $$ = NFT_CT_SRC; }
+			|	DADDR		{ $$ = NFT_CT_DST; }
+			|	PROTOCOL	{ $$ = NFT_CT_PROTOCOL; }
+			|	PROTO_SRC	{ $$ = NFT_CT_PROTO_SRC; }
+			|	PROTO_DST	{ $$ = NFT_CT_PROTO_DST; }
+			|	LABEL		{ $$ = NFT_CT_LABEL; }
+			;
+
+ct_stmt			:	CT	ct_key		SET	expr
+			{
+				$$ = ct_stmt_alloc(&@$, $2, $4);
+			}
+			;
+
+payload_expr		:	payload_raw_expr
+			|	eth_hdr_expr
+			|	vlan_hdr_expr
+			|	arp_hdr_expr
+			|	ip_hdr_expr
+			|	icmp_hdr_expr
+			|	ip6_hdr_expr
+			|	icmp6_hdr_expr
+			|	auth_hdr_expr
+			|	esp_hdr_expr
+			|	comp_hdr_expr
+			|	udp_hdr_expr
+			|	udplite_hdr_expr
+			|	tcp_hdr_expr
+			|	dccp_hdr_expr
+			|	sctp_hdr_expr
+			;
+
+payload_raw_expr	:	AT	payload_base_spec	COMMA	NUM	COMMA	NUM
+			{
+				$$ = payload_expr_alloc(&@$, NULL, 0);
+				$$->payload.base	= $2;
+				$$->payload.offset	= $4;
+				$$->len			= $6;
+				$$->dtype		= &integer_type;
+			}
+			;
+
+payload_base_spec	:	LL_HDR		{ $$ = PROTO_BASE_LL_HDR; }
+			|	NETWORK_HDR	{ $$ = PROTO_BASE_NETWORK_HDR; }
+			|	TRANSPORT_HDR	{ $$ = PROTO_BASE_TRANSPORT_HDR; }
+			;
+
+eth_hdr_expr		:	ETHER	eth_hdr_field
+			{
+				$$ = payload_expr_alloc(&@$, &proto_eth, $2);
+			}
+			|	ETHER
+			{
+				$$ = symbol_expr_alloc(&@$, SYMBOL_VALUE,
+						       current_scope(state),
+						       "ether");
+			}
+			;
+
+eth_hdr_field		:	SADDR		{ $$ = ETHHDR_SADDR; }
+			|	DADDR		{ $$ = ETHHDR_DADDR; }
+			|	TYPE		{ $$ = ETHHDR_TYPE; }
+			;
+
+vlan_hdr_expr		:	VLAN	vlan_hdr_field
+			{
+				$$ = payload_expr_alloc(&@$, &proto_vlan, $2);
+			}
+			|	VLAN
+			{
+				$$ = symbol_expr_alloc(&@$, SYMBOL_VALUE,
+						       current_scope(state),
+						       "vlan");
+			}
+			;
+
+vlan_hdr_field		:	ID		{ $$ = VLANHDR_VID; }
+			|	CFI		{ $$ = VLANHDR_CFI; }
+			|	PCP		{ $$ = VLANHDR_PCP; }
+			|	TYPE		{ $$ = VLANHDR_TYPE; }
+			;
+
+arp_hdr_expr		:	ARP	arp_hdr_field
+			{
+				$$ = payload_expr_alloc(&@$, &proto_arp, $2);
+			}
+			|	ARP
+			{
+				$$ = symbol_expr_alloc(&@$, SYMBOL_VALUE,
+						       current_scope(state),
+						       "arp");
+			}
+			;
+
+arp_hdr_field		:	HTYPE		{ $$ = ARPHDR_HRD; }
+			|	PTYPE		{ $$ = ARPHDR_PRO; }
+			|	HLEN		{ $$ = ARPHDR_HLN; }
+			|	PLEN		{ $$ = ARPHDR_PLN; }
+			|	OPERATION	{ $$ = ARPHDR_OP; }
+			;
+
+ip_hdr_expr		:	IP	ip_hdr_field
+			{
+				$$ = payload_expr_alloc(&@$, &proto_ip, $2);
+			}
+			|	IP
+			{
+				$$ = symbol_expr_alloc(&@$, SYMBOL_VALUE,
+						       current_scope(state),
+						       "ip");
+			}
+			;
+
+ip_hdr_field		:	VERSION		{ $$ = IPHDR_VERSION; }
+			|	HDRLENGTH	{ $$ = IPHDR_HDRLENGTH; }
+			|	TOS		{ $$ = IPHDR_TOS; }
+			|	LENGTH		{ $$ = IPHDR_LENGTH; }
+			|	ID		{ $$ = IPHDR_ID; }
+			|	FRAG_OFF	{ $$ = IPHDR_FRAG_OFF; }
+			|	TTL		{ $$ = IPHDR_TTL; }
+			|	PROTOCOL	{ $$ = IPHDR_PROTOCOL; }
+			|	CHECKSUM	{ $$ = IPHDR_CHECKSUM; }
+			|	SADDR		{ $$ = IPHDR_SADDR; }
+			|	DADDR		{ $$ = IPHDR_DADDR; }
+			;
+
+icmp_hdr_expr		:	ICMP	icmp_hdr_field
+			{
+				$$ = payload_expr_alloc(&@$, &proto_icmp, $2);
+			}
+			|	ICMP
+			{
+				uint8_t data = IPPROTO_ICMP;
+				$$ = constant_expr_alloc(&@$, &inet_protocol_type,
+							 BYTEORDER_HOST_ENDIAN,
+							 sizeof(data) * BITS_PER_BYTE, &data);
+			}
+			;
+
+icmp_hdr_field		:	TYPE		{ $$ = ICMPHDR_TYPE; }
+			|	CODE		{ $$ = ICMPHDR_CODE; }
+			|	CHECKSUM	{ $$ = ICMPHDR_CHECKSUM; }
+			|	ID		{ $$ = ICMPHDR_ID; }
+			|	SEQUENCE	{ $$ = ICMPHDR_SEQ; }
+			|	GATEWAY		{ $$ = ICMPHDR_GATEWAY; }
+			|	MTU		{ $$ = ICMPHDR_MTU; }
+			;
+
+ip6_hdr_expr		:	IP6	ip6_hdr_field
+			{
+				$$ = payload_expr_alloc(&@$, &proto_ip6, $2);
+			}
+			|	IP6
+			{
+				$$ = symbol_expr_alloc(&@$, SYMBOL_VALUE,
+						       current_scope(state),
+						       "ip6");
+			}
+			;
+
+ip6_hdr_field		:	VERSION		{ $$ = IP6HDR_VERSION; }
+			|	PRIORITY	{ $$ = IP6HDR_PRIORITY; }
+			|	FLOWLABEL	{ $$ = IP6HDR_FLOWLABEL; }
+			|	LENGTH		{ $$ = IP6HDR_LENGTH; }
+			|	NEXTHDR		{ $$ = IP6HDR_NEXTHDR; }
+			|	HOPLIMIT	{ $$ = IP6HDR_HOPLIMIT; }
+			|	SADDR		{ $$ = IP6HDR_SADDR; }
+			|	DADDR		{ $$ = IP6HDR_DADDR; }
+			;
+icmp6_hdr_expr		:	ICMP6	icmp6_hdr_field
+			{
+				$$ = payload_expr_alloc(&@$, &proto_icmp6, $2);
+			}
+			|	ICMP6
+			{
+				uint8_t data = IPPROTO_ICMPV6;
+				$$ = constant_expr_alloc(&@$, &inet_protocol_type,
+							 BYTEORDER_HOST_ENDIAN,
+							 sizeof(data) * BITS_PER_BYTE, &data);
+			}
+			;
+
+icmp6_hdr_field		:	TYPE		{ $$ = ICMP6HDR_TYPE; }
+			|	CODE		{ $$ = ICMP6HDR_CODE; }
+			|	CHECKSUM	{ $$ = ICMP6HDR_CHECKSUM; }
+			|	PPTR		{ $$ = ICMP6HDR_PPTR; }
+			|	MTU		{ $$ = ICMP6HDR_MTU; }
+			|	ID		{ $$ = ICMP6HDR_ID; }
+			|	SEQUENCE	{ $$ = ICMP6HDR_SEQ; }
+			|	MAXDELAY	{ $$ = ICMP6HDR_MAXDELAY; }
+			;
+
+auth_hdr_expr		:	AH	auth_hdr_field
+			{
+				$$ = payload_expr_alloc(&@$, &proto_ah, $2);
+			}
+			|	AH
+			{
+				uint8_t data = IPPROTO_AH;
+				$$ = constant_expr_alloc(&@$, &inet_protocol_type,
+							 BYTEORDER_HOST_ENDIAN,
+							 sizeof(data) * BITS_PER_BYTE, &data);
+			}
+			;
+
+auth_hdr_field		:	NEXTHDR		{ $$ = AHHDR_NEXTHDR; }
+			|	HDRLENGTH	{ $$ = AHHDR_HDRLENGTH; }
+			|	RESERVED	{ $$ = AHHDR_RESERVED; }
+			|	SPI		{ $$ = AHHDR_SPI; }
+			|	SEQUENCE	{ $$ = AHHDR_SEQUENCE; }
+			;
+
+esp_hdr_expr		:	ESP	esp_hdr_field
+			{
+				$$ = payload_expr_alloc(&@$, &proto_esp, $2);
+			}
+			|	ESP
+			{
+				uint8_t data = IPPROTO_ESP;
+				$$ = constant_expr_alloc(&@$, &inet_protocol_type,
+							 BYTEORDER_HOST_ENDIAN,
+							 sizeof(data) * BITS_PER_BYTE, &data);
+			}
+			;
+
+esp_hdr_field		:	SPI		{ $$ = ESPHDR_SPI; }
+			|	SEQUENCE	{ $$ = ESPHDR_SEQUENCE; }
+			;
+
+comp_hdr_expr		:	COMP	comp_hdr_field
+			{
+				$$ = payload_expr_alloc(&@$, &proto_comp, $2);
+			}
+			|	COMP
+			{
+				uint8_t data = IPPROTO_COMP;
+				$$ = constant_expr_alloc(&@$, &inet_protocol_type,
+							 BYTEORDER_HOST_ENDIAN,
+							 sizeof(data) * BITS_PER_BYTE, &data);
+			}
+			;
+
+comp_hdr_field		:	NEXTHDR		{ $$ = COMPHDR_NEXTHDR; }
+			|	FLAGS		{ $$ = COMPHDR_FLAGS; }
+			|	CPI		{ $$ = COMPHDR_CPI; }
+			;
+
+udp_hdr_expr		:	UDP	udp_hdr_field
+			{
+				$$ = payload_expr_alloc(&@$, &proto_udp, $2);
+			}
+			|	UDP
+			{
+				uint8_t data = IPPROTO_UDP;
+				$$ = constant_expr_alloc(&@$, &inet_protocol_type,
+							 BYTEORDER_HOST_ENDIAN,
+							 sizeof(data) * BITS_PER_BYTE, &data);
+			}
+			;
+
+udp_hdr_field		:	SPORT		{ $$ = UDPHDR_SPORT; }
+			|	DPORT		{ $$ = UDPHDR_DPORT; }
+			|	LENGTH		{ $$ = UDPHDR_LENGTH; }
+			|	CHECKSUM	{ $$ = UDPHDR_CHECKSUM; }
+			;
+
+udplite_hdr_expr	:	UDPLITE	udplite_hdr_field
+			{
+				$$ = payload_expr_alloc(&@$, &proto_udplite, $2);
+			}
+			|	UDPLITE
+			{
+				uint8_t data = IPPROTO_UDPLITE;
+				$$ = constant_expr_alloc(&@$, &inet_protocol_type,
+							 BYTEORDER_HOST_ENDIAN,
+							 sizeof(data) * BITS_PER_BYTE, &data);
+			}
+			;
+
+udplite_hdr_field	:	SPORT		{ $$ = UDPHDR_SPORT; }
+			|	DPORT		{ $$ = UDPHDR_DPORT; }
+			|	CSUMCOV		{ $$ = UDPHDR_LENGTH; }
+			|	CHECKSUM	{ $$ = UDPHDR_CHECKSUM; }
+			;
+
+tcp_hdr_expr		:	TCP	tcp_hdr_field
+			{
+				$$ = payload_expr_alloc(&@$, &proto_tcp, $2);
+			}
+			|	TCP
+			{
+				uint8_t data = IPPROTO_TCP;
+				$$ = constant_expr_alloc(&@$, &inet_protocol_type,
+							 BYTEORDER_HOST_ENDIAN,
+							 sizeof(data) * BITS_PER_BYTE, &data);
+			}
+			;
+
+tcp_hdr_field		:	SPORT		{ $$ = TCPHDR_SPORT; }
+			|	DPORT		{ $$ = TCPHDR_DPORT; }
+			|	SEQUENCE	{ $$ = TCPHDR_SEQ; }
+			|	ACKSEQ		{ $$ = TCPHDR_ACKSEQ; }
+			|	DOFF		{ $$ = TCPHDR_DOFF; }
+			|	RESERVED	{ $$ = TCPHDR_RESERVED; }
+			|	FLAGS		{ $$ = TCPHDR_FLAGS; }
+			|	WINDOW		{ $$ = TCPHDR_WINDOW; }
+			|	CHECKSUM	{ $$ = TCPHDR_CHECKSUM; }
+			|	URGPTR		{ $$ = TCPHDR_URGPTR; }
+			;
+
+dccp_hdr_expr		:	DCCP	dccp_hdr_field
+			{
+				$$ = payload_expr_alloc(&@$, &proto_dccp, $2);
+			}
+			|	DCCP
+			{
+				uint8_t data = IPPROTO_DCCP;
+				$$ = constant_expr_alloc(&@$, &inet_protocol_type,
+							 BYTEORDER_HOST_ENDIAN,
+							 sizeof(data) * BITS_PER_BYTE, &data);
+			}
+			;
+
+dccp_hdr_field		:	SPORT		{ $$ = DCCPHDR_SPORT; }
+			|	DPORT		{ $$ = DCCPHDR_DPORT; }
+			|	TYPE		{ $$ = DCCPHDR_TYPE; }
+			;
+
+sctp_hdr_expr		:	SCTP	sctp_hdr_field
+			{
+				$$ = payload_expr_alloc(&@$, &proto_sctp, $2);
+			}
+			|	SCTP
+			{
+				uint8_t data = IPPROTO_SCTP;
+				$$ = constant_expr_alloc(&@$, &inet_protocol_type,
+							 BYTEORDER_HOST_ENDIAN,
+							 sizeof(data) * BITS_PER_BYTE, &data);
+			}
+			;
+
+sctp_hdr_field		:	SPORT		{ $$ = SCTPHDR_SPORT; }
+			|	DPORT		{ $$ = SCTPHDR_DPORT; }
+			|	VTAG		{ $$ = SCTPHDR_VTAG; }
+			|	CHECKSUM	{ $$ = SCTPHDR_CHECKSUM; }
+			;
+
+exthdr_expr		:	hbh_hdr_expr
+			|	rt_hdr_expr
+			|	rt0_hdr_expr
+			|	rt2_hdr_expr
+			|	frag_hdr_expr
+			|	dst_hdr_expr
+			|	mh_hdr_expr
+			;
+
+hbh_hdr_expr		:	HBH	hbh_hdr_field
+			{
+				$$ = exthdr_expr_alloc(&@$, &exthdr_hbh, $2);
+			}
+			;
+
+hbh_hdr_field		:	NEXTHDR		{ $$ = HBHHDR_NEXTHDR; }
+			|	HDRLENGTH	{ $$ = HBHHDR_HDRLENGTH; }
+			;
+
+rt_hdr_expr		:	RT	rt_hdr_field
+			{
+				$$ = exthdr_expr_alloc(&@$, &exthdr_rt, $2);
+			}
+			;
+
+rt_hdr_field		:	NEXTHDR		{ $$ = RTHDR_NEXTHDR; }
+			|	HDRLENGTH	{ $$ = RTHDR_HDRLENGTH; }
+			|	TYPE		{ $$ = RTHDR_TYPE; }
+			|	SEG_LEFT	{ $$ = RTHDR_SEG_LEFT; }
+			;
+
+rt0_hdr_expr		:	RT0	rt0_hdr_field
+			{
+				$$ = exthdr_expr_alloc(&@$, &exthdr_rt0, $2);
+			}
+			;
+
+rt0_hdr_field		:	ADDR	'['	NUM	']'
+			{
+				$$ = RT0HDR_ADDR_1 + $3 - 1;
+			}
+			;
+
+rt2_hdr_expr		:	RT2	rt2_hdr_field
+			{
+				$$ = exthdr_expr_alloc(&@$, &exthdr_rt2, $2);
+			}
+			;
+
+rt2_hdr_field		:	ADDR		{ $$ = RT2HDR_ADDR; }
+			;
+
+frag_hdr_expr		:	FRAG	frag_hdr_field
+			{
+				$$ = exthdr_expr_alloc(&@$, &exthdr_frag, $2);
+			}
+			;
+
+frag_hdr_field		:	NEXTHDR		{ $$ = FRAGHDR_NEXTHDR; }
+			|	RESERVED	{ $$ = FRAGHDR_RESERVED; }
+			|	FRAG_OFF	{ $$ = FRAGHDR_FRAG_OFF; }
+			|	RESERVED2	{ $$ = FRAGHDR_RESERVED2; }
+			|	MORE_FRAGMENTS	{ $$ = FRAGHDR_MFRAGS; }
+			|	ID		{ $$ = FRAGHDR_ID; }
+			;
+
+dst_hdr_expr		:	DST	dst_hdr_field
+			{
+				$$ = exthdr_expr_alloc(&@$, &exthdr_dst, $2);
+			}
+			;
+
+dst_hdr_field		:	NEXTHDR		{ $$ = DSTHDR_NEXTHDR; }
+			|	HDRLENGTH	{ $$ = DSTHDR_HDRLENGTH; }
+			;
+
+mh_hdr_expr		:	MH	mh_hdr_field
+			{
+				$$ = exthdr_expr_alloc(&@$, &exthdr_mh, $2);
+			}
+			;
+
+mh_hdr_field		:	NEXTHDR		{ $$ = MHHDR_NEXTHDR; }
+			|	HDRLENGTH	{ $$ = MHHDR_HDRLENGTH; }
+			|	TYPE		{ $$ = MHHDR_TYPE; }
+			|	RESERVED	{ $$ = MHHDR_RESERVED; }
+			|	CHECKSUM	{ $$ = MHHDR_CHECKSUM; }
+			;
+
+export_format		: 	XML 		{ $$ = NFT_OUTPUT_XML; }
+			|	JSON		{ $$ = NFT_OUTPUT_JSON; }
+			;
+%%
-- 
2.0.1


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH 4/7] autotools conversion: include the header 'config.h' in every C source file.
  2014-07-07 14:19 [PATCH 0/7] patches for an autotooled version of 'nftables'. (vers. 2) Giorgio Dal Molin
                   ` (2 preceding siblings ...)
  2014-07-07 14:19 ` [PATCH 3/7] autotool conversion: converted the subdir. 'src/' Giorgio Dal Molin
@ 2014-07-07 14:19 ` Giorgio Dal Molin
  2014-07-10 10:04   ` Patrick McHardy
  2014-07-07 14:19 ` [PATCH 5/7] autotool conversion: Converted the support for the 'doc/' subdir Giorgio Dal Molin
                   ` (3 subsequent siblings)
  7 siblings, 1 reply; 22+ messages in thread
From: Giorgio Dal Molin @ 2014-07-07 14:19 UTC (permalink / raw)
  To: netfilter-devel; +Cc: Giorgio Dal Molin

Added an #include <config.h> to all the C source files so that the results
of the tests in the configure script are available to all the compilation
units.

We could have added the include also to 'yacc_parser.y' and 'scanner.l'
but we don't, because it is not strictly needed and to avoid to define
the variable 'VERSION' two times.
---
 src/cli.c                 | 3 +++
 src/ct.c                  | 3 +++
 src/datatype.c            | 3 +++
 src/erec.c                | 3 +++
 src/evaluate.c            | 3 +++
 src/expression.c          | 3 +++
 src/exthdr.c              | 3 +++
 src/gmputil.c             | 3 +++
 src/main.c                | 3 +++
 src/meta.c                | 3 +++
 src/mnl.c                 | 3 +++
 src/netlink.c             | 3 +++
 src/netlink_delinearize.c | 3 +++
 src/netlink_linearize.c   | 3 +++
 src/payload.c             | 3 +++
 src/proto.c               | 3 +++
 src/rbtree.c              | 3 +++
 src/rule.c                | 3 +++
 src/segtree.c             | 3 +++
 src/statement.c           | 3 +++
 src/utils.c               | 3 +++
 21 files changed, 63 insertions(+)

diff --git a/src/cli.c b/src/cli.c
index f748a0e..bf3caea 100644
--- a/src/cli.c
+++ b/src/cli.c
@@ -11,6 +11,9 @@
  *
  * Development of this code funded by Astaro AG (http://www.astaro.com/)
  */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
 
 #include <stdlib.h>
 #include <stdio.h>
diff --git a/src/ct.c b/src/ct.c
index 30639b2..98e7fec 100644
--- a/src/ct.c
+++ b/src/ct.c
@@ -9,6 +9,9 @@
  *
  * Development of this code funded by Astaro AG (http://www.astaro.com/)
  */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
 
 #include <stddef.h>
 #include <stdlib.h>
diff --git a/src/datatype.c b/src/datatype.c
index 55af227..2d773f2 100644
--- a/src/datatype.c
+++ b/src/datatype.c
@@ -7,6 +7,9 @@
  *
  * Development of this code funded by Astaro AG (http://www.astaro.com/)
  */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
 
 #include <stdlib.h>
 #include <string.h>
diff --git a/src/erec.c b/src/erec.c
index 4930085..500691e 100644
--- a/src/erec.c
+++ b/src/erec.c
@@ -7,6 +7,9 @@
  *
  * Development of this code funded by Astaro AG (http://www.astaro.com/)
  */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
 
 #include <stdio.h>
 #include <string.h>
diff --git a/src/evaluate.c b/src/evaluate.c
index 2330bbb..e66e8a2 100644
--- a/src/evaluate.c
+++ b/src/evaluate.c
@@ -7,6 +7,9 @@
  *
  * Development of this code funded by Astaro AG (http://www.astaro.com/)
  */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
 
 #include <stddef.h>
 #include <stdlib.h>
diff --git a/src/expression.c b/src/expression.c
index fa14d99..b2a2f04 100644
--- a/src/expression.c
+++ b/src/expression.c
@@ -7,6 +7,9 @@
  *
  * Development of this code funded by Astaro AG (http://www.astaro.com/)
  */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
 
 #include <stddef.h>
 #include <stdlib.h>
diff --git a/src/exthdr.c b/src/exthdr.c
index a619ecc..9d73d07 100644
--- a/src/exthdr.c
+++ b/src/exthdr.c
@@ -9,6 +9,9 @@
  *
  * Development of this code funded by Astaro AG (http://www.astaro.com/)
  */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
 
 #include <stddef.h>
 #include <stdlib.h>
diff --git a/src/gmputil.c b/src/gmputil.c
index cb46445..38eafde 100644
--- a/src/gmputil.c
+++ b/src/gmputil.c
@@ -7,6 +7,9 @@
  *
  * Development of this code funded by Astaro AG (http://www.astaro.com/)
  */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
 
 #include <stddef.h>
 #include <stdlib.h>
diff --git a/src/main.c b/src/main.c
index a446bc6..142e99c 100644
--- a/src/main.c
+++ b/src/main.c
@@ -7,6 +7,9 @@
  *
  * Development of this code funded by Astaro AG (http://www.astaro.com/)
  */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
 
 #include <stdlib.h>
 #include <stddef.h>
diff --git a/src/meta.c b/src/meta.c
index 80f88ff..d82c524 100644
--- a/src/meta.c
+++ b/src/meta.c
@@ -9,6 +9,9 @@
  *
  * Development of this code funded by Astaro AG (http://www.astaro.com/)
  */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
 
 #include <stddef.h>
 #include <stdlib.h>
diff --git a/src/mnl.c b/src/mnl.c
index a816106..dd5f172 100644
--- a/src/mnl.c
+++ b/src/mnl.c
@@ -7,6 +7,9 @@
  *
  * Development of this code funded by Astaro AG (http://www.astaro.com/)
  */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
 
 #include <libmnl/libmnl.h>
 #include <libnftnl/common.h>
diff --git a/src/netlink.c b/src/netlink.c
index 2e7c572..a0d21f6 100644
--- a/src/netlink.c
+++ b/src/netlink.c
@@ -8,6 +8,9 @@
  *
  * Development of this code funded by Astaro AG (http://www.astaro.com/)
  */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
 
 #include <string.h>
 #include <fcntl.h>
diff --git a/src/netlink_delinearize.c b/src/netlink_delinearize.c
index 5c6ca80..7c02138 100644
--- a/src/netlink_delinearize.c
+++ b/src/netlink_delinearize.c
@@ -8,6 +8,9 @@
  *
  * Development of this code funded by Astaro AG (http://www.astaro.com/)
  */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
 
 #include <stdlib.h>
 #include <stdbool.h>
diff --git a/src/netlink_linearize.c b/src/netlink_linearize.c
index 5c1b46d..ae3eb2d 100644
--- a/src/netlink_linearize.c
+++ b/src/netlink_linearize.c
@@ -8,6 +8,9 @@
  *
  * Development of this code funded by Astaro AG (http://www.astaro.com/)
  */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
 
 #include <linux/netfilter/nf_tables.h>
 
diff --git a/src/payload.c b/src/payload.c
index a1785a5..3d2a2ae 100644
--- a/src/payload.c
+++ b/src/payload.c
@@ -9,6 +9,9 @@
  *
  * Development of this code funded by Astaro AG (http://www.astaro.com/)
  */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
 
 #include <stddef.h>
 #include <stdlib.h>
diff --git a/src/proto.c b/src/proto.c
index 0a37a65..0179ddf 100644
--- a/src/proto.c
+++ b/src/proto.c
@@ -8,6 +8,9 @@
  * published by the Free Software Foundation.
  *
  */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
 
 #include <stddef.h>
 #include <stdlib.h>
diff --git a/src/rbtree.c b/src/rbtree.c
index 325c012..8cb6dd8 100644
--- a/src/rbtree.c
+++ b/src/rbtree.c
@@ -18,6 +18,9 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
  */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
 
 #include <rbtree.h>
 
diff --git a/src/rule.c b/src/rule.c
index a7bc6f4..ecaaa2e 100644
--- a/src/rule.c
+++ b/src/rule.c
@@ -7,6 +7,9 @@
  *
  * Development of this code funded by Astaro AG (http://www.astaro.com/)
  */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
 
 #include <stddef.h>
 #include <stdlib.h>
diff --git a/src/segtree.c b/src/segtree.c
index 1785f64..0258684 100644
--- a/src/segtree.c
+++ b/src/segtree.c
@@ -7,6 +7,9 @@
  *
  * Development of this code funded by Astaro AG (http://www.astaro.com/)
  */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
 
 #include <stdlib.h>
 #include <inttypes.h>
diff --git a/src/statement.c b/src/statement.c
index 2dd3f18..42fb37f 100644
--- a/src/statement.c
+++ b/src/statement.c
@@ -7,6 +7,9 @@
  *
  * Development of this code funded by Astaro AG (http://www.astaro.com/)
  */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
 
 #include <stddef.h>
 #include <stdlib.h>
diff --git a/src/utils.c b/src/utils.c
index 96ff419..f68ab57 100644
--- a/src/utils.c
+++ b/src/utils.c
@@ -7,6 +7,9 @@
  *
  * Development of this code funded by Astaro AG (http://www.astaro.com/)
  */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
 
 #include <stddef.h>
 #include <stdlib.h>
-- 
2.0.1


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH 5/7] autotool conversion: Converted the support for the 'doc/' subdir.
  2014-07-07 14:19 [PATCH 0/7] patches for an autotooled version of 'nftables'. (vers. 2) Giorgio Dal Molin
                   ` (3 preceding siblings ...)
  2014-07-07 14:19 ` [PATCH 4/7] autotools conversion: include the header 'config.h' in every C source file Giorgio Dal Molin
@ 2014-07-07 14:19 ` Giorgio Dal Molin
  2014-07-07 14:19 ` [PATCH 6/7] autotools conversion: commit the rest of the configure.ac changes Giorgio Dal Molin
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 22+ messages in thread
From: Giorgio Dal Molin @ 2014-07-07 14:19 UTC (permalink / raw)
  To: netfilter-devel; +Cc: Giorgio Dal Molin

To generate the nft.8 man page the configure script searches for the
tools 'docbookx2-man' and 'db2x_docbook2man'; if at least one is found
then the man page is generated. To force the system not to generate the
man page use the option '--disable-man'.

To generate the pdf doc file the configure script searches for the tool
'dblatex'; if it is found then the pdf doc file is generated. To force
the system not to generate the pdf doc file use the option '--disable-pdf'.
---
 configure.ac    | 73 +++++++++++++++++++++++++++++++++++++++------------------
 doc/Makefile.am | 10 ++++++++
 doc/Makefile.in | 20 ----------------
 3 files changed, 60 insertions(+), 43 deletions(-)
 create mode 100644 doc/Makefile.am
 delete mode 100644 doc/Makefile.in

diff --git a/configure.ac b/configure.ac
index 900b26a..18ca0a2 100644
--- a/configure.ac
+++ b/configure.ac
@@ -27,30 +27,57 @@ AC_PROG_SED
 AC_PROG_YACC
 AM_PROG_LEX
 
-AC_CHECK_PROG(CONFIG_MAN1, [docbook2x-man], [y], [n])
-if test "$CONFIG_MAN1" == "y"
-then
-	CONFIG_MAN=y
-	DB2MAN=docbook2x-man
-else
-	AC_CHECK_PROG(CONFIG_MAN2, [db2x_docbook2man], [y], [n])
-	if test "$CONFIG_MAN2" == "y"
-	then
-		CONFIG_MAN=y
-		DB2MAN=db2x_docbook2man
-	else
-		AC_MSG_WARN([docbookx2-man/db2x_docbook2man not found, no manpages will be built])
-	fi
-fi
-AC_SUBST(CONFIG_MAN)
-AC_SUBST(DB2MAN)
-
-AC_CHECK_PROG(CONFIG_PDF, dblatex, y, n)
-if test "$CONFIG_PDF" != "y"
-then
-	AC_MSG_WARN([dblatex not found, no PDF manpages will be built])
-fi
+AC_CHECK_PROG(DOCBOOK2X_MAN, [docbook2x-man], [found], [no])
+AC_CHECK_PROG(DB2X_DOCBOOK2MAN, [db2x_docbook2man], [found], [no])
+AS_CASE([$DOCBOOK2X_MAN],
+	[found],[
+		DB2MAN=docbook2x-man
+		NFT_8=nft.8
+		],
+	[AS_CASE([$DB2X_DOCBOOK2MAN],
+		[found],[
+			DB2MAN=db2x_docbook2man
+			NFT_8=nft.8
+			],
+		[AC_MSG_WARN([docbookx2-man/db2x_docbook2man not found, no manpages will be built])]
+	)]
+)
+
+AC_ARG_ENABLE([man], AS_HELP_STRING([--enable-man], [Enable generating the man page nft.8. Requires docbook2x-man or db2x_docbook2man.]))
+
+AC_MSG_CHECKING([whether to generate the man page])
+AS_CASE([${enable_man}],
+	[yes],[
+		AS_IF([test -z "$DB2MAN"],AC_MSG_ERROR([No tool found to generate the man page. Please install either docbook2x-man or db2x_docbook2man.]))
+		AC_MSG_RESULT(yes)
+	], [
+	NFT_8=""
+	AC_MSG_RESULT(no)
+	]
+)
 
+AC_SUBST(DB2MAN)
+AC_SUBST(NFT_8)
+
+AC_CHECK_PROG(DBLATEX, [dblatex], [found], [no])
+AS_CASE([$DBLATEX],
+	[found],[NFT_PDF=nft.pdf],
+	[AC_MSG_WARN([dblatex not found, no PDF manpages will be built])]
+)
+
+AC_MSG_CHECKING([whether to generate the pdf doc])
+AC_ARG_ENABLE([pdf], AS_HELP_STRING([--enable-pdf], [Enable generating the pdf doc file nft.pdf. Requires dblatex.]))
+AS_CASE([${enable_pdf}],
+	[yes],[
+		AS_IF([test -z "$DBLATEX"], AC_MSG_ERROR([No tool found to generate the pdf doc. Please install dblatex.]))
+		AC_MSG_RESULT(yes)
+	],[
+	NFT_PDF=""
+	AC_MSG_RESULT(no)
+	]
+)
+
+AC_SUBST(NFT_PDF)
 
 # Checks for libraries.
 
diff --git a/doc/Makefile.am b/doc/Makefile.am
new file mode 100644
index 0000000..58c79df
--- /dev/null
+++ b/doc/Makefile.am
@@ -0,0 +1,10 @@
+man_MANS = @NFT_8@
+pdf_DATA = @NFT_PDF@
+
+pdfdir=${docdir}/pdf
+
+.xml.pdf:
+	${AM_V_GEN}dblatex -q -t pdf -o $@ $<
+
+.8.xml:
+	${AM_V_GEN}$(DB2MAN) --xinclude $<
diff --git a/doc/Makefile.in b/doc/Makefile.in
deleted file mode 100644
index 1ec856c..0000000
--- a/doc/Makefile.in
+++ /dev/null
@@ -1,20 +0,0 @@
-mandocs-@CONFIG_MAN@	+= doc/nft.8
-pdfdocs-@CONFIG_PDF@	+= doc/nft.pdf
-
-all:		$(mandocs-y) $(pdfdocs-y)
-clean:
-		@echo -e "  CLEAN\t\tdoc"
-		$(RM) $(mandocs-y) $(pdfdocs-y)
-
-install:	$(mandocs-y) $(pdfdocs-y)
-		@echo -e "  INSTALL\tdoc"
-		if test -n "$(mandocs-y)"; then \
-			$(MKDIR_P) $(DESTDIR)/${mandir}/man8 ;\
-			$(INSTALL) -m 755 -p $(mandocs-y) \
-					$(DESTDIR)/${mandir}/man8/ ;\
-		fi
-		if test -n "$(pdfdocs-y)"; then \
-			$(MKDIR_P) $(DESTDIR)/${pdfdir} ;\
-			$(INSTALL) -m 755 -p $(pdfdocs-y) \
-					$(DESTDIR)/${pdfdir}/ ;\
-		fi
-- 
2.0.1


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH 6/7] autotools conversion: commit the rest of the configure.ac changes.
  2014-07-07 14:19 [PATCH 0/7] patches for an autotooled version of 'nftables'. (vers. 2) Giorgio Dal Molin
                   ` (4 preceding siblings ...)
  2014-07-07 14:19 ` [PATCH 5/7] autotool conversion: Converted the support for the 'doc/' subdir Giorgio Dal Molin
@ 2014-07-07 14:19 ` Giorgio Dal Molin
  2014-07-07 14:19 ` [PATCH 7/7] autotool conversion: updated the files .gitignore Giorgio Dal Molin
  2014-07-25 17:16 ` [PATCH 0/7] patches for an autotooled version of 'nftables'. (vers. 2) Pablo Neira Ayuso
  7 siblings, 0 replies; 22+ messages in thread
From: Giorgio Dal Molin @ 2014-07-07 14:19 UTC (permalink / raw)
  To: netfilter-devel; +Cc: Giorgio Dal Molin

Mainly the handling of the option '--enable-debug' and the definition of
the cpp variable DEFAULT_INCLUDE_PATH; the definition is written to
the generated header 'config.h', included by all the 'src/*.c'.

Also updated the script 'autogen.sh' to support calling it from a
build directory different from the package root.
---
 autogen.sh      | 10 ++++++++--
 configure.ac    | 32 ++++++++++++++++++++++++++------
 src/Makefile.am |  4 ++--
 3 files changed, 36 insertions(+), 10 deletions(-)

diff --git a/autogen.sh b/autogen.sh
index a62e737..ce6243c 100755
--- a/autogen.sh
+++ b/autogen.sh
@@ -1,4 +1,10 @@
-#!/bin/bash
+#! /bin/sh
 
-autoreconf -fi;
+srcdir=`dirname $0`
+test -z "$srcdir" && srcdir=.
+
+ORIGDIR=`pwd`
+cd $srcdir
+
+autoreconf -fvi || exit 1
 rm -Rf autom4te*.cache config.h.in~
diff --git a/configure.ac b/configure.ac
index 18ca0a2..f4a6051 100644
--- a/configure.ac
+++ b/configure.ac
@@ -5,7 +5,13 @@ AC_PREREQ(2.61)
 
 AC_COPYRIGHT([Copyright (c) 2008 Patrick McHardy <kaber@trash.net>])
 AC_INIT([nftables], [0.3], [netfilter-devel@vger.kernel.org])
+AM_INIT_AUTOMAKE([dist-bzip2 dist-xz])
+AM_MAINTAINER_MODE([disable])
+AM_SILENT_RULES([yes])
+AC_CONFIG_MACRO_DIR([m4])
+
 AC_DEFINE([RELEASE_NAME], ["Support Edward Snowden"], [Release name])
+AC_DEFINE_UNQUOTED([DEFAULT_INCLUDE_PATH],["$confdir"],[define DEFAULT_INCLUDE_PATH])
 
 AC_CONFIG_SRCDIR([src/rule.c])
 AC_CONFIG_HEADER([config.h])
@@ -14,10 +20,17 @@ AC_DEFINE([_GNU_SOURCE], [], [Enable various GNU extensions])
 AC_DEFINE([_STDC_FORMAT_MACROS], [], [printf-style format macros])
 
 AC_ARG_ENABLE([debug],
-	      AS_HELP_STRING([--enable-debug], [Enable debugging]),
-	      [CONFIG_DEBUG="$(echo $enableval | cut -b1)"],
-	      [CONFIG_DEBUG="y"])
-AC_SUBST([CONFIG_DEBUG])
+	      AS_HELP_STRING([--enable-debug], [Enable debugging]))
+
+AS_CASE([$enable_debug],
+	[yes],[
+	AC_DEFINE([DEBUG],1,[Debug enabled])
+	DEBUG_CPPFLAGS="-DDEBUG"
+	DEBUG_CFLAGS="-g"
+	])
+
+AC_SUBST(DEBUG_CPPFLAGS)
+AC_SUBST(DEBUG_CFLAGS)
 
 # Checks for programs.
 AC_PROG_CC
@@ -119,6 +132,13 @@ AC_TYPE_UINT64_T
 # Checks for library functions.
 AC_CHECK_FUNCS([memmove memset strchr strdup strerror strtoull])
 
-AC_CONFIG_FILES([Makefile Makefile.defs Makefile.rules])
-AC_CONFIG_FILES([src/Makefile doc/Makefile files/Makefile])
+AC_CONFIG_FILES([	Makefile				\
+			src/Makefile				\
+			doc/Makefile				\
+			files/Makefile				\
+			files/nftables/Makefile			\
+			include/Makefile			\
+			include/linux/Makefile			\
+			include/linux/netfilter/Makefile	\
+		])
 AC_OUTPUT
diff --git a/src/Makefile.am b/src/Makefile.am
index 5f19732..2b2c535 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -6,9 +6,9 @@ nft_CFLAGS =	-fno-strict-aliasing							\
 		-Wdeclaration-after-statement -Wsign-compare -Winit-self		\
 		-Wformat-nonliteral -Wformat-security -Wmissing-format-attribute	\
 		-Wcast-align -Wundef -Wbad-function-cast				\
-		-Waggregate-return -Wunused -Wwrite-strings
+		-Waggregate-return -Wunused -Wwrite-strings ${DEBUG_CFLAGS}
 
-nft_CPPFLAGS = -I${srcdir}/../include ${LIBMNL_CFLAGS} ${LIBNFTNL_CFLAGS}
+nft_CPPFLAGS = -I${srcdir}/../include ${LIBMNL_CFLAGS} ${LIBNFTNL_CFLAGS} ${DEBUG_CPPFLAGS}
 
 nft_LDADD = ${LIBMNL_LIBS} ${LIBNFTNL_LIBS}
 
-- 
2.0.1


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH 7/7] autotool conversion: updated the files .gitignore
  2014-07-07 14:19 [PATCH 0/7] patches for an autotooled version of 'nftables'. (vers. 2) Giorgio Dal Molin
                   ` (5 preceding siblings ...)
  2014-07-07 14:19 ` [PATCH 6/7] autotools conversion: commit the rest of the configure.ac changes Giorgio Dal Molin
@ 2014-07-07 14:19 ` Giorgio Dal Molin
  2014-07-25 17:16 ` [PATCH 0/7] patches for an autotooled version of 'nftables'. (vers. 2) Pablo Neira Ayuso
  7 siblings, 0 replies; 22+ messages in thread
From: Giorgio Dal Molin @ 2014-07-07 14:19 UTC (permalink / raw)
  To: netfilter-devel; +Cc: Giorgio Dal Molin

Tuned the file '.gitignore' and 'src/.gitignore' to filter out the auto
generated files.
---
 .gitignore     | 19 ++++++++++++-------
 src/.gitignore |  4 ++--
 2 files changed, 14 insertions(+), 9 deletions(-)

diff --git a/.gitignore b/.gitignore
index d26b395..998760d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,18 +1,23 @@
-# Dependency and object files
-.*.d
-*.o
-
 # Generated by autoconf/configure
 Makefile
-Makefile.defs
-Makefile.rules
+Makefile.in
 config.h
 config.h.in
-config.h.in~
 config.log
 config.status
 configure
 autom4te.cache
+missing
+compile
+depcomp
+stamp-h1
+ylwrap
+aclocal.m4
+install-sh
+.deps
+*.o
+*~
+
 
 # Debian package build temporary files
 build-stamp
diff --git a/src/.gitignore b/src/.gitignore
index 23e6ae0..50ff292 100644
--- a/src/.gitignore
+++ b/src/.gitignore
@@ -1,5 +1,5 @@
-parser.c
-parser.h
+yacc_parser.c
+yacc_parser.h
 scanner.c
 scanner.h
 nft
-- 
2.0.1


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* Re: [PATCH 4/7] autotools conversion: include the header 'config.h' in every C source file.
  2014-07-07 14:19 ` [PATCH 4/7] autotools conversion: include the header 'config.h' in every C source file Giorgio Dal Molin
@ 2014-07-10 10:04   ` Patrick McHardy
  2014-07-11  7:24     ` Jan Engelhardt
  0 siblings, 1 reply; 22+ messages in thread
From: Patrick McHardy @ 2014-07-10 10:04 UTC (permalink / raw)
  To: Giorgio Dal Molin; +Cc: netfilter-devel

On Mon, Jul 07, 2014 at 04:19:28PM +0200, Giorgio Dal Molin wrote:
> Added an #include <config.h> to all the C source files so that the results
> of the tests in the configure script are available to all the compilation
> units.
> 
> We could have added the include also to 'yacc_parser.y' and 'scanner.l'
> but we don't, because it is not strictly needed and to avoid to define
> the variable 'VERSION' two times.

> --- a/src/cli.c
> +++ b/src/cli.c
> @@ -11,6 +11,9 @@
>   *
>   * Development of this code funded by Astaro AG (http://www.astaro.com/)
>   */
> +#ifdef HAVE_CONFIG_H
> +#include <config.h>
> +#endif

Do we really need those ifdefs?

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH 3/7] autotool conversion: converted the subdir. 'src/'
  2014-07-07 14:19 ` [PATCH 3/7] autotool conversion: converted the subdir. 'src/' Giorgio Dal Molin
@ 2014-07-10 10:08   ` Pablo Neira Ayuso
  2014-07-10 10:42     ` Giorgio Dal Molin
  0 siblings, 1 reply; 22+ messages in thread
From: Pablo Neira Ayuso @ 2014-07-10 10:08 UTC (permalink / raw)
  To: Giorgio Dal Molin; +Cc: netfilter-devel

On Mon, Jul 07, 2014 at 04:19:27PM +0200, Giorgio Dal Molin wrote:
>  src/parser.y      | 2251 -----------------------------------------------------
>  src/yacc_parser.y | 2251 +++++++++++++++++++++++++++++++++++++++++++++++++++++

Could you resend this patch using -M90% with git-format-patch so it
can detect the file rename and we make sure no new code accidentally
slipped through?

Thanks.

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH 3/7] autotool conversion: converted the subdir. 'src/'
  2014-07-10 10:08   ` Pablo Neira Ayuso
@ 2014-07-10 10:42     ` Giorgio Dal Molin
  0 siblings, 0 replies; 22+ messages in thread
From: Giorgio Dal Molin @ 2014-07-10 10:42 UTC (permalink / raw)
  To: netfilter-devel; +Cc: Giorgio

From: Giorgio <giorgio.nicole@arcor.de>

Use specialized test macros to find 'yacc' and 'lex' in the configure.ac.

Renamed the file 'src/parser.y' to 'src/yacc_parser.y' to avoid having
two header files with the same name, 'parser.h': one under 'src/',
generated by 'yacc' from 'parser.y' and the other under 'include/'.

Added an %option line to 'src/scanner.l': this new %option directive
lets us save a custom recipe in the 'src/Makefile.am'; it replaces the
'lex' command line option '--outfile=scanner.c'.
We don't have any explicit make recipe to call 'lex' on 'scanner.l' to
generate 'scanner.c' and 'scanner.h' as in the old 'Makefile.rules';
listing the file 'scanner.l' in the variable 'nft_SOURCES' of
'src/Makefile.am' is now enough.
---
 configure.ac                    | 13 ++-----------
 src/Makefile.in                 | 31 -------------------------------
 src/scanner.l                   |  3 ++-
 src/{parser.y => yacc_parser.y} |  4 ++--
 4 files changed, 6 insertions(+), 45 deletions(-)
 delete mode 100644 src/Makefile.in
 rename src/{parser.y => yacc_parser.y} (99%)

diff --git a/configure.ac b/configure.ac
index 605d39d..900b26a 100644
--- a/configure.ac
+++ b/configure.ac
@@ -24,6 +24,8 @@ AC_PROG_CC
 AC_PROG_MKDIR_P
 AC_PROG_INSTALL
 AC_PROG_SED
+AC_PROG_YACC
+AM_PROG_LEX
 
 AC_CHECK_PROG(CONFIG_MAN1, [docbook2x-man], [y], [n])
 if test "$CONFIG_MAN1" == "y"
@@ -49,17 +51,6 @@ then
 	AC_MSG_WARN([dblatex not found, no PDF manpages will be built])
 fi
 
-AC_PATH_PROG(LEX, [flex])
-if test -z "$LEX"
-then
-	AC_MSG_ERROR([No suitable version of flex found])
-fi
-
-AC_PATH_PROG(YACC, [bison])
-if test -z "$YACC"
-then
-	AC_MSG_ERROR([No suitable version of bison found])
-fi
 
 # Checks for libraries.
 
diff --git a/src/Makefile.in b/src/Makefile.in
deleted file mode 100644
index 8ac2b46..0000000
--- a/src/Makefile.in
+++ /dev/null
@@ -1,31 +0,0 @@
-PROGRAMS		+= nft
-
-nft-destdir		:= @sbindir@
-
-nft-obj			+= main.o
-nft-obj			+= cli.o
-nft-obj			+= rule.o
-nft-obj			+= statement.o
-nft-obj			+= datatype.o
-nft-obj			+= expression.o
-nft-obj			+= evaluate.o
-nft-obj			+= proto.o
-nft-obj			+= payload.o
-nft-obj			+= exthdr.o
-nft-obj			+= meta.o
-nft-obj			+= ct.o
-nft-obj			+= netlink.o
-nft-obj			+= netlink_linearize.o
-nft-obj			+= netlink_delinearize.o
-nft-obj			+= segtree.o
-nft-obj			+= rbtree.o
-nft-obj			+= gmputil.o
-nft-obj			+= utils.o
-nft-obj			+= erec.o
-nft-obj			+= mnl.o
-
-nft-obj			+= parser.o
-nft-extra-clean-files	+= parser.c parser.h
-
-nft-obj			+= scanner.o
-nft-extra-clean-files	+= scanner.c scanner.h
diff --git a/src/scanner.l b/src/scanner.l
index 73a1a3f..e6b8127 100644
--- a/src/scanner.l
+++ b/src/scanner.l
@@ -20,7 +20,7 @@
 #include <erec.h>
 #include <rule.h>
 #include <parser.h>
-#include "parser.h"
+#include "yacc_parser.h"
 
 #define YY_NO_INPUT
 
@@ -178,6 +178,7 @@ addrstring	({macaddr}|{ip4addr}|{ip6addr})
 %option yylineno
 %option nodefault
 %option warn
+%option outfile="scanner.c"
 
 %%
 
diff --git a/src/parser.y b/src/yacc_parser.y
similarity index 99%
rename from src/parser.y
rename to src/yacc_parser.y
index 3e08e21..7cb790d 100644
--- a/src/parser.y
+++ b/src/yacc_parser.y
@@ -12,6 +12,7 @@
 
 #include <stddef.h>
 #include <stdio.h>
+#include <string.h>
 #include <inttypes.h>
 #include <netinet/ip.h>
 #include <netinet/if_ether.h>
@@ -27,8 +28,7 @@
 #include <parser.h>
 #include <erec.h>
 
-#include "parser.h"
-#include "scanner.h"
+#include "yacc_parser.h"
 
 void parser_init(struct parser_state *state, struct list_head *msgs)
 {
-- 
2.0.1


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* Re: [PATCH 4/7] autotools conversion: include the header 'config.h' in every C source file.
  2014-07-10 10:04   ` Patrick McHardy
@ 2014-07-11  7:24     ` Jan Engelhardt
  0 siblings, 0 replies; 22+ messages in thread
From: Jan Engelhardt @ 2014-07-11  7:24 UTC (permalink / raw)
  To: Patrick McHardy; +Cc: Giorgio Dal Molin, netfilter-devel

On Thursday 2014-07-10 12:04, Patrick McHardy wrote:
>> --- a/src/cli.c
>> +++ b/src/cli.c
>> @@ -11,6 +11,9 @@
>>   *
>>   * Development of this code funded by Astaro AG (http://www.astaro.com/)
>>   */
>> +#ifdef HAVE_CONFIG_H
>> +#include <config.h>
>> +#endif
>
>Do we really need those ifdefs?

Practically no, since AC_CONFIG_HEADERS is unconditionally called in 
configure.ac.

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH 0/7] patches for an autotooled version of 'nftables'. (vers. 2)
  2014-07-07 14:19 [PATCH 0/7] patches for an autotooled version of 'nftables'. (vers. 2) Giorgio Dal Molin
                   ` (6 preceding siblings ...)
  2014-07-07 14:19 ` [PATCH 7/7] autotool conversion: updated the files .gitignore Giorgio Dal Molin
@ 2014-07-25 17:16 ` Pablo Neira Ayuso
  2014-07-25 21:53   ` [PATCH 0/8] patches for an autotooled version of 'nftables' Giorgio Dal Molin
  7 siblings, 1 reply; 22+ messages in thread
From: Pablo Neira Ayuso @ 2014-07-25 17:16 UTC (permalink / raw)
  To: Giorgio Dal Molin; +Cc: netfilter-devel

On Mon, Jul 07, 2014 at 04:19:24PM +0200, Giorgio Dal Molin wrote:
> Hi,
> 
> I'm sending a couple of patches to add autotools support to the 'nftables' project.

This patchset doesn't remove the the old makefiles and it's missing
several new ones (most likely forgot to 'git add') in the include/
irectory. I think this needs another spin.

Thanks.

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH 0/8] patches for an autotooled version of 'nftables'.
  2014-07-25 17:16 ` [PATCH 0/7] patches for an autotooled version of 'nftables'. (vers. 2) Pablo Neira Ayuso
@ 2014-07-25 21:53   ` Giorgio Dal Molin
  2014-07-25 21:53     ` [PATCH 1/8] autotool conversion: Added some required files, removed some unneeded Giorgio Dal Molin
                       ` (7 more replies)
  0 siblings, 8 replies; 22+ messages in thread
From: Giorgio Dal Molin @ 2014-07-25 21:53 UTC (permalink / raw)
  To: netfilter-devel; +Cc: Giorgio Dal Molin

The patches are based on the upstream commit id:

b1a348208a9e5749860a95ceb0307fc16f2edb7f

and add support for the autotools to nftables.

The whole changes are divided in different commits for the sake of clarity
and documentation but it's not really possible to build any of the tree states
in between, only the last 'autotool conversion: ...' state is usable.

giorgio

Giorgio Dal Molin (2):
  autotool conversion: converted the subdir. 'src/'
  autotool conversion: updated the files .gitignore

Giorgio Dal Molin (4):
  autotool conversion: use pkg-config to find 'libmnl', libnftnl' and
    'ncurses'.
  autotools conversion: include the header 'config.h' in every C source
    file.
  autotool conversion: Converted the support for the 'doc/' subdir.
  autotools conversion: commit the rest of the configure.ac changes.

Giorgio Dal Molin (2):
  autotool conversion: Added some required files, removed some unneeded.
  autotool conversion: autotools support for the subdir.
    'files/nftables'.

 .gitignore                          |  19 ++-
 AUTHORS                             |   0
 ChangeLog                           |   0
 Makefile.am                         |   3 +
 Makefile.defs.in                    |  42 ------
 Makefile.in                         |   5 -
 Makefile.rules.in                   |  96 -------------
 NEWS                                |   0
 README                              |  61 ++++++++
 autogen.sh                          |  10 +-
 configure.ac                        | 133 +++++++++++-------
 doc/Makefile.am                     |  10 ++
 doc/Makefile.in                     |  20 ---
 files/Makefile.am                   |   1 +
 files/Makefile.in                   |   5 -
 files/nftables/Makefile.am          |  13 ++
 files/nftables/bridge-filter        |   2 +-
 files/nftables/inet-filter          |   2 +-
 files/nftables/ipv4-filter          |   2 +-
 files/nftables/ipv4-mangle          |   2 +-
 files/nftables/ipv4-nat             |   2 +-
 files/nftables/ipv6-filter          |   2 +-
 files/nftables/ipv6-mangle          |   2 +-
 files/nftables/ipv6-nat             |   2 +-
 include/Makefile.am                 |  21 +++
 include/linux/Makefile.am           |   7 +
 include/linux/netfilter/Makefile.am |   4 +
 install-sh                          | 269 ------------------------------------
 m4/ax_lib_readlibe.m4               | 107 ++++++++++++++
 src/.gitignore                      |   4 +-
 src/Makefile.am                     |  44 ++++++
 src/Makefile.in                     |  31 -----
 src/cli.c                           |   2 +
 src/ct.c                            |   2 +
 src/datatype.c                      |   2 +
 src/erec.c                          |   2 +
 src/evaluate.c                      |   2 +
 src/expression.c                    |   2 +
 src/exthdr.c                        |   2 +
 src/gmputil.c                       |   2 +
 src/main.c                          |   2 +
 src/meta.c                          |   2 +
 src/mnl.c                           |   2 +
 src/netlink.c                       |   2 +
 src/netlink_delinearize.c           |   2 +
 src/netlink_linearize.c             |   2 +
 src/payload.c                       |   2 +
 src/proto.c                         |   2 +
 src/rbtree.c                        |   2 +
 src/rule.c                          |   2 +
 src/scanner.l                       |   3 +-
 src/segtree.c                       |   2 +
 src/statement.c                     |   2 +
 src/utils.c                         |   2 +
 src/{parser.y => yacc_parser.y}     |   4 +-
 55 files changed, 432 insertions(+), 538 deletions(-)
 create mode 100644 AUTHORS
 create mode 100644 ChangeLog
 create mode 100644 Makefile.am
 delete mode 100644 Makefile.defs.in
 delete mode 100644 Makefile.in
 delete mode 100644 Makefile.rules.in
 create mode 100644 NEWS
 create mode 100644 README
 create mode 100644 doc/Makefile.am
 delete mode 100644 doc/Makefile.in
 create mode 100644 files/Makefile.am
 delete mode 100644 files/Makefile.in
 create mode 100644 files/nftables/Makefile.am
 create mode 100644 include/Makefile.am
 create mode 100644 include/linux/Makefile.am
 create mode 100644 include/linux/netfilter/Makefile.am
 delete mode 100755 install-sh
 create mode 100644 m4/ax_lib_readlibe.m4
 create mode 100644 src/Makefile.am
 delete mode 100644 src/Makefile.in
 rename src/{parser.y => yacc_parser.y} (99%)

-- 
2.0.3


^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH 1/8] autotool conversion: Added some required files, removed some unneeded.
  2014-07-25 21:53   ` [PATCH 0/8] patches for an autotooled version of 'nftables' Giorgio Dal Molin
@ 2014-07-25 21:53     ` Giorgio Dal Molin
  2014-07-25 21:53     ` [PATCH 2/8] autotool conversion: autotools support for the subdir. 'files/nftables' Giorgio Dal Molin
                       ` (6 subsequent siblings)
  7 siblings, 0 replies; 22+ messages in thread
From: Giorgio Dal Molin @ 2014-07-25 21:53 UTC (permalink / raw)
  To: netfilter-devel; +Cc: Giorgio Dal Molin

The 'autoreconf' command, used to update the autogenerated files requires
that some special files exist on the package root dir.:

  NEWS, AUTHORS, README, ChangeLog

The previous INSTALL file, with build instructions, package dependencies
and other notes was renamed to README; the new INSTALL file is the
standard one from the autotools.

Also many non standard Makefile.in, 'Makefile.defs.in' and
'Makefile.rules.in' were removed because they are now unneeded
and replaced by the corresponding Makefile.am.
---
 AUTHORS                             |   0
 ChangeLog                           |   0
 Makefile.am                         |   3 +
 Makefile.defs.in                    |  42 ------
 Makefile.in                         |   5 -
 Makefile.rules.in                   |  96 -------------
 NEWS                                |   0
 README                              |  61 ++++++++
 files/Makefile.am                   |   1 +
 files/Makefile.in                   |   5 -
 include/Makefile.am                 |  21 +++
 include/linux/Makefile.am           |   7 +
 include/linux/netfilter/Makefile.am |   4 +
 install-sh                          | 269 ------------------------------------
 14 files changed, 97 insertions(+), 417 deletions(-)
 create mode 100644 AUTHORS
 create mode 100644 ChangeLog
 create mode 100644 Makefile.am
 delete mode 100644 Makefile.defs.in
 delete mode 100644 Makefile.in
 delete mode 100644 Makefile.rules.in
 create mode 100644 NEWS
 create mode 100644 README
 create mode 100644 files/Makefile.am
 delete mode 100644 files/Makefile.in
 create mode 100644 include/Makefile.am
 create mode 100644 include/linux/Makefile.am
 create mode 100644 include/linux/netfilter/Makefile.am
 delete mode 100755 install-sh

diff --git a/AUTHORS b/AUTHORS
new file mode 100644
index 0000000..e69de29
diff --git a/ChangeLog b/ChangeLog
new file mode 100644
index 0000000..e69de29
diff --git a/Makefile.am b/Makefile.am
new file mode 100644
index 0000000..bf0c605
--- /dev/null
+++ b/Makefile.am
@@ -0,0 +1,3 @@
+SUBDIRS = include files doc src
+
+ACLOCAL_AMFLAGS=-I m4
diff --git a/Makefile.defs.in b/Makefile.defs.in
deleted file mode 100644
index 915d3d8..0000000
--- a/Makefile.defs.in
+++ /dev/null
@@ -1,42 +0,0 @@
-DEBUG		= @CONFIG_DEBUG@
-CC		= @CC@
-CPP		= @CPP@
-LEX		= @LEX@
-YACC		= @YACC@
-MKDIR_P		= @MKDIR_P@
-INSTALL		= @INSTALL@
-SED		= @SED@
-DB2MAN		= @DB2MAN@
-
-PACKAGE_TARNAME	= @PACKAGE_TARNAME@
-
-prefix		= @prefix@
-exec_prefix	= @exec_prefix@
-sysconfdir	= @sysconfdir@
-datarootdir	= @datarootdir@
-mandir		= @mandir@
-docdir		= @docdir@
-pdfdir		= @pdfdir@
-confdir		= @sysconfdir@/nftables
-
-LDFLAGS		+= @LDFLAGS@
-LDFLAGS		+= @LIBS@
-
-CPPFLAGS	+= @CPPFLAGS@
-
-CFLAGS		+= @CFLAGS@ @DEFS@
-CFLAGS		+= -DDEFAULT_INCLUDE_PATH="\"$(confdir)\""
-CFLAGS		+= -include config.h
-CFLAGS		+= -Iinclude
-CFLAGS		+= -fno-strict-aliasing
-
-CFLAGS		+= -Wall
-CFLAGS		+= -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations
-CFLAGS		+= -Wdeclaration-after-statement -Wsign-compare -Winit-self
-CFLAGS		+= -Wformat-nonliteral -Wformat-security -Wmissing-format-attribute
-CFLAGS		+= -Wcast-align -Wundef -Wbad-function-cast # -Wshadow
-CFLAGS		+= -Waggregate-return -Wunused -Wwrite-strings
-
-ifeq ($(DEBUG),y)
-CFLAGS		+= -g -DDEBUG
-endif
diff --git a/Makefile.in b/Makefile.in
deleted file mode 100644
index 5d42541..0000000
--- a/Makefile.in
+++ /dev/null
@@ -1,5 +0,0 @@
-SUBDIRS		+= src
-SUBDIRS		+= files
-SUBDIRS		+= doc
-
-include Makefile.rules
diff --git a/Makefile.rules.in b/Makefile.rules.in
deleted file mode 100644
index 6a00916..0000000
--- a/Makefile.rules.in
+++ /dev/null
@@ -1,96 +0,0 @@
-include Makefile.defs
-
-makedeps		+= $(SUBDIR)Makefile
-makedeps		+= Makefile
-makedeps		+= Makefile.defs
-makedeps		+= Makefile.rules
-
-configure:		configure.ac
-			sh autogen.sh
-
-%:			%.in	configure
-			sh configure
-
-%.o:			%.c	$(makedeps)
-			@echo -e "  CC\t\t$<"
-			$(CC) $(CFLAGS) -c -o $@ $<
-
-.%.d:			%.c	$(makedeps)
-			@echo -e "  DEP\t\t$<"
-			$(RM) $@
-			$(CC) -M $(CFLAGS) $< | sed 's,$(*F)\.o[ :]*,$*.o $@ : ,g' > $@
-
-%.c %.h:		%.y	$(makedeps)
-			@echo -e "  YACC\t\t$<"
-			$(YACC) $(YACCFLAGS) --defines=$*.h.tmp -o $@ $<
-			( \
-				echo "#ifndef __$(*F)_H"; \
-				echo "#define __$(*F)_H"; \
-				cat $*.h.tmp; \
-				echo "#endif /* __$(*F)_H */" \
-			) > $*.h
-			$(RM) $*.h.tmp
-
-%.c %.h:		%.l	$(makedeps)
-			@echo -e "  LEX\t\t$<"
-			$(LEX) -t --header-file=$(<:.l=.h) $< > $@
-
-%.8:			%.xml	$(makedeps)
-			@echo -e "  MAN\t\t$@"
-			(cd $(SUBDIR); $(DB2MAN) --xinclude ../$<)
-
-%.pdf:			%.xml	$(makedeps)
-			@echo -e "  PDF\t\t$@"
-			dblatex -q -t pdf -o $@ $<
-
-archive:
-			git archive --prefix=nftables-@PACKAGE_VERSION@/ HEAD | \
-				bzip2 -c > nftables-@PACKAGE_VERSION@.tar.bz2
-
-define program_template
-$(1)-obj		:= $$(patsubst %,$(SUBDIR)%,$$($(1)-obj))
-$(1)-extra-clean-files	:= $$(patsubst %,$(SUBDIR)%,$$($(1)-extra-clean-files))
-
-depfiles		:= $$(patsubst $(SUBDIR)%.o,$(SUBDIR).%.d,$$($(1)-obj))
-
-$(SUBDIR)$(1):		$$($(1)-extra-targets) $$($(1)-obj)
-			@echo -e "  LD\t\t$$@"
-			$$(CC) $$($(1)-obj) $$(LDFLAGS) -o $$@
-all_targets		+= $(SUBDIR)$(1)
-
-.PHONY:			$(1)-clean
-$(1)-clean:
-			@echo -e "  CLEAN\t\t$(1)"
-			$$(RM) $$($(1)-obj) $$(depfiles) $$($(1)-extra-clean-files) $(SUBDIR)$(1)
-clean_targets		+= $(1)-clean
-
-.PHONY:			$(1)-install
-$(1)-install:
-			@echo -e "  INSTALL\t$1"
-			$(MKDIR_P) $$(DESTDIR)/$$($(1)-destdir)
-			$(INSTALL) -m 755 -p \
-				$(SUBDIR)$(1) \
-				$$(DESTDIR)/$$($(1)-destdir)/$(1)
-install_targets		+= $(1)-install
-
-ifneq ($(MAKECMDGOALS),clean)
--include $$(depfiles)
-endif
-endef
-
-ifneq ($(SUBDIR),)
-include $(SUBDIR)/Makefile
-$(foreach prog,$(PROGRAMS),$(eval $(call program_template,$(prog))))
-endif
-
-.DEFAULT_GOAL		:= all
-
-.PHONY:			all clean install
-all:			$(SUBDIRS) $(all_targets)
-clean:			$(SUBDIRS) $(clean_targets)
-install:		all $(SUBDIRS) $(install_targets)
-
-.PHONY: $(SUBDIRS)
-$(SUBDIRS):
-			@echo -e "  SUBDIR\t$@/"
-			@$(MAKE) -s -f Makefile.rules $(MAKECMDGOALS) SUBDIR="$@/" SUBDIRS=""
diff --git a/NEWS b/NEWS
new file mode 100644
index 0000000..e69de29
diff --git a/README b/README
new file mode 100644
index 0000000..ba6f7a3
--- /dev/null
+++ b/README
@@ -0,0 +1,61 @@
+Installation instructions for nftables
+======================================
+
+ Prerequisites
+ =============
+
+  - standard glibc headers, gcc etc.
+
+  - libmnl: git://git.netfilter.org/libmnl.git
+
+  - libnftnl: git://git.netfilter.org/libnftnl.git
+
+  - flex
+
+  - bison
+
+  - libgmp
+
+  - libreadline
+
+  - optional: docbook2x: required for building man-page
+
+  - optional: docbook-utils: required for building PDF man-page
+
+ Configuring and compiling
+ =========================
+
+ Run "sh autogen.sh" to generate the configure script, then:
+
+ sh configure [options]
+
+ --prefix=
+
+        The prefix to put all installed files under. It defaults to
+        /usr/local, so the binaries will go into /usr/local/bin, sbin,
+        manpages into /usr/local/share/man, etc.
+
+ --datarootdir=
+
+ 	The base directory for arch-independant files. Defaults to
+	$prefix/share.
+
+ --disable-debug
+
+	Disable debugging
+
+ Suggested configuration options: --prefix=/ --datarootdir=/usr/share
+
+ Run "make" to compile nftables, "make install" to install it in the
+ configured paths.
+
+ Other notes
+ ===========
+
+ The nftables kernel tree can be found at:
+
+ git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nftables.git
+
+ The latest version of this code can be found at:
+
+ git://git.netfilter.org/nftables.git
diff --git a/files/Makefile.am b/files/Makefile.am
new file mode 100644
index 0000000..a8394c0
--- /dev/null
+++ b/files/Makefile.am
@@ -0,0 +1 @@
+SUBDIRS = nftables
diff --git a/files/Makefile.in b/files/Makefile.in
deleted file mode 100644
index dc237e2..0000000
--- a/files/Makefile.in
+++ /dev/null
@@ -1,5 +0,0 @@
-install:
-	@echo -e "  INSTALL\tfiles"
-	$(MKDIR_P) $(DESTDIR)/$(confdir)
-	$(INSTALL) -m 755 -p $(SUBDIR)nftables/* $(DESTDIR)/$(confdir)/
-	$(SED) -i "s~#\! nft~#\!@sbindir@/nft~" $(DESTDIR)/$(confdir)/*
diff --git a/include/Makefile.am b/include/Makefile.am
new file mode 100644
index 0000000..5c33663
--- /dev/null
+++ b/include/Makefile.am
@@ -0,0 +1,21 @@
+SUBDIRS = linux
+
+noinst_HEADERS = 	ct.h		\
+			datatype.h	\
+			erec.h		\
+			expression.h	\
+			exthdr.h	\
+			gmputil.h	\
+			headers.h	\
+			list.h		\
+			meta.h		\
+			mnl.h		\
+			netlink.h	\
+			nftables.h	\
+			parser.h	\
+			payload.h	\
+			proto.h		\
+			rbtree.h	\
+			rule.h		\
+			statement.h	\
+			utils.h
diff --git a/include/linux/Makefile.am b/include/linux/Makefile.am
new file mode 100644
index 0000000..5d3e3b5
--- /dev/null
+++ b/include/linux/Makefile.am
@@ -0,0 +1,7 @@
+SUBDIRS = netfilter
+noinst_HEADERS = 	netfilter_arp.h		\
+			netfilter_bridge.h	\
+			netfilter_decnet.h	\
+			netfilter.h		\
+			netfilter_ipv4.h	\
+			netfilter_ipv6.h
diff --git a/include/linux/netfilter/Makefile.am b/include/linux/netfilter/Makefile.am
new file mode 100644
index 0000000..f48876f
--- /dev/null
+++ b/include/linux/netfilter/Makefile.am
@@ -0,0 +1,4 @@
+noinst_HEADERS = 	nf_conntrack_common.h		\
+			nf_conntrack_tuple_common.h	\
+			nfnetlink.h			\
+			nf_tables.h
diff --git a/install-sh b/install-sh
deleted file mode 100755
index d4744f0..0000000
--- a/install-sh
+++ /dev/null
@@ -1,269 +0,0 @@
-#!/bin/sh
-#
-# install - install a program, script, or datafile
-#
-# This originates from X11R5 (mit/util/scripts/install.sh), which was
-# later released in X11R6 (xc/config/util/install.sh) with the
-# following copyright and license.
-#
-# Copyright (C) 1994 X Consortium
-#
-# Permission is hereby granted, free of charge, to any person obtaining a copy
-# of this software and associated documentation files (the "Software"), to
-# deal in the Software without restriction, including without limitation the
-# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
-# sell copies of the Software, and to permit persons to whom the Software is
-# furnished to do so, subject to the following conditions:
-#
-# The above copyright notice and this permission notice shall be included in
-# all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
-# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
-# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-#
-# Except as contained in this notice, the name of the X Consortium shall not
-# be used in advertising or otherwise to promote the sale, use or other deal-
-# ings in this Software without prior written authorization from the X Consor-
-# tium.
-#
-#
-# FSF changes to this file are in the public domain.
-#
-# Calling this script install-sh is preferred over install.sh, to prevent
-# `make' implicit rules from creating a file called install from it
-# when there is no Makefile.
-#
-# This script is compatible with the BSD install script, but was written
-# from scratch.  It can only install one file at a time, a restriction
-# shared with many OS's install programs.
-
-
-# set DOITPROG to echo to test this script
-
-# Don't use :- since 4.3BSD and earlier shells don't like it.
-doit="${DOITPROG-}"
-
-
-# put in absolute paths if you don't have them in your path; or use env. vars.
-
-mvprog="${MVPROG-mv}"
-cpprog="${CPPROG-cp}"
-chmodprog="${CHMODPROG-chmod}"
-chownprog="${CHOWNPROG-chown}"
-chgrpprog="${CHGRPPROG-chgrp}"
-stripprog="${STRIPPROG-strip}"
-rmprog="${RMPROG-rm}"
-mkdirprog="${MKDIRPROG-mkdir}"
-
-transformbasename=""
-transform_arg=""
-instcmd="$mvprog"
-chmodcmd="$chmodprog 0755"
-chowncmd=""
-chgrpcmd=""
-stripcmd=""
-rmcmd="$rmprog -f"
-mvcmd="$mvprog"
-src=""
-dst=""
-dir_arg=""
-
-while [ x"$1" != x ]; do
-    case $1 in
-	-c) instcmd="$cpprog"
-	    shift
-	    continue;;
-
-	-d) dir_arg=true
-	    shift
-	    continue;;
-
-	-m) chmodcmd="$chmodprog $2"
-	    shift
-	    shift
-	    continue;;
-
-	-o) chowncmd="$chownprog $2"
-	    shift
-	    shift
-	    continue;;
-
-	-g) chgrpcmd="$chgrpprog $2"
-	    shift
-	    shift
-	    continue;;
-
-	-s) stripcmd="$stripprog"
-	    shift
-	    continue;;
-
-	-t=*) transformarg=`echo $1 | sed 's/-t=//'`
-	    shift
-	    continue;;
-
-	-b=*) transformbasename=`echo $1 | sed 's/-b=//'`
-	    shift
-	    continue;;
-
-	*)  if [ x"$src" = x ]
-	    then
-		src=$1
-	    else
-		# this colon is to work around a 386BSD /bin/sh bug
-		:
-		dst=$1
-	    fi
-	    shift
-	    continue;;
-    esac
-done
-
-if [ x"$src" = x ]
-then
-	echo "install:	no input file specified"
-	exit 1
-else
-	true
-fi
-
-if [ x"$dir_arg" != x ]; then
-	dst=$src
-	src=""
-	
-	if [ -d $dst ]; then
-		instcmd=:
-		chmodcmd=""
-	else
-		instcmd=mkdir
-	fi
-else
-
-# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
-# might cause directories to be created, which would be especially bad 
-# if $src (and thus $dsttmp) contains '*'.
-
-	if [ -f $src -o -d $src ]
-	then
-		true
-	else
-		echo "install:  $src does not exist"
-		exit 1
-	fi
-	
-	if [ x"$dst" = x ]
-	then
-		echo "install:	no destination specified"
-		exit 1
-	else
-		true
-	fi
-
-# If destination is a directory, append the input filename; if your system
-# does not like double slashes in filenames, you may need to add some logic
-
-	if [ -d $dst ]
-	then
-		dst="$dst"/`basename $src`
-	else
-		true
-	fi
-fi
-
-## this sed command emulates the dirname command
-dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
-
-# Make sure that the destination directory exists.
-#  this part is taken from Noah Friedman's mkinstalldirs script
-
-# Skip lots of stat calls in the usual case.
-if [ ! -d "$dstdir" ]; then
-defaultIFS=' 	
-'
-IFS="${IFS-${defaultIFS}}"
-
-oIFS="${IFS}"
-# Some sh's can't handle IFS=/ for some reason.
-IFS='%'
-set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
-IFS="${oIFS}"
-
-pathcomp=''
-
-while [ $# -ne 0 ] ; do
-	pathcomp="${pathcomp}${1}"
-	shift
-
-	if [ ! -d "${pathcomp}" ] ;
-        then
-		$mkdirprog "${pathcomp}"
-	else
-		true
-	fi
-
-	pathcomp="${pathcomp}/"
-done
-fi
-
-if [ x"$dir_arg" != x ]
-then
-	$doit $instcmd $dst &&
-
-	if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi &&
-	if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi &&
-	if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi &&
-	if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi
-else
-
-# If we're going to rename the final executable, determine the name now.
-
-	if [ x"$transformarg" = x ] 
-	then
-		dstfile=`basename $dst`
-	else
-		dstfile=`basename $dst $transformbasename | 
-			sed $transformarg`$transformbasename
-	fi
-
-# don't allow the sed command to completely eliminate the filename
-
-	if [ x"$dstfile" = x ] 
-	then
-		dstfile=`basename $dst`
-	else
-		true
-	fi
-
-# Make a temp file name in the proper directory.
-
-	dsttmp=$dstdir/#inst.$$#
-
-# Move or copy the file name to the temp name
-
-	$doit $instcmd $src $dsttmp &&
-
-	trap "rm -f ${dsttmp}" 0 &&
-
-# and set any options; do chmod last to preserve setuid bits
-
-# If any of these fail, we abort the whole thing.  If we want to
-# ignore errors from any of these, just make sure not to ignore
-# errors from the above "$doit $instcmd $src $dsttmp" command.
-
-	if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi &&
-	if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi &&
-	if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi &&
-	if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi &&
-
-# Now rename the file to the real destination.
-
-	$doit $rmcmd -f $dstdir/$dstfile &&
-	$doit $mvcmd $dsttmp $dstdir/$dstfile 
-
-fi &&
-
-
-exit 0
-- 
2.0.3


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH 2/8] autotool conversion: autotools support for the subdir. 'files/nftables'.
  2014-07-25 21:53   ` [PATCH 0/8] patches for an autotooled version of 'nftables' Giorgio Dal Molin
  2014-07-25 21:53     ` [PATCH 1/8] autotool conversion: Added some required files, removed some unneeded Giorgio Dal Molin
@ 2014-07-25 21:53     ` Giorgio Dal Molin
  2014-07-25 21:53     ` [PATCH 3/8] autotool conversion: use pkg-config to find 'libmnl', libnftnl' and 'ncurses' Giorgio Dal Molin
                       ` (5 subsequent siblings)
  7 siblings, 0 replies; 22+ messages in thread
From: Giorgio Dal Molin @ 2014-07-25 21:53 UTC (permalink / raw)
  To: netfilter-devel; +Cc: Giorgio Dal Molin

We added the marker @sbindir@ to the first line of the scripts so it
can be replaced once the scripts are installed.
---
 files/nftables/Makefile.am   | 13 +++++++++++++
 files/nftables/bridge-filter |  2 +-
 files/nftables/inet-filter   |  2 +-
 files/nftables/ipv4-filter   |  2 +-
 files/nftables/ipv4-mangle   |  2 +-
 files/nftables/ipv4-nat      |  2 +-
 files/nftables/ipv6-filter   |  2 +-
 files/nftables/ipv6-mangle   |  2 +-
 files/nftables/ipv6-nat      |  2 +-
 9 files changed, 21 insertions(+), 8 deletions(-)
 create mode 100644 files/nftables/Makefile.am

diff --git a/files/nftables/Makefile.am b/files/nftables/Makefile.am
new file mode 100644
index 0000000..32dced3
--- /dev/null
+++ b/files/nftables/Makefile.am
@@ -0,0 +1,13 @@
+
+pkgsysconfdir = ${sysconfdir}/nftables
+dist_pkgsysconf_DATA =	bridge-filter	\
+			inet-filter	\
+			ipv4-filter	\
+			ipv4-mangle	\
+			ipv4-nat	\
+			ipv6-filter	\
+			ipv6-mangle	\
+			ipv6-nat
+
+install-data-hook:
+	${SED} -i 's|@sbindir[@]|${sbindir}|g' ${DESTDIR}${pkgsysconfdir}/*
diff --git a/files/nftables/bridge-filter b/files/nftables/bridge-filter
index 54779c4..2add455 100644
--- a/files/nftables/bridge-filter
+++ b/files/nftables/bridge-filter
@@ -1,4 +1,4 @@
-#! nft -f
+#! @sbindir@nft -f
 
 table bridge filter {
 	chain input		{ type filter hook input priority -200; }
diff --git a/files/nftables/inet-filter b/files/nftables/inet-filter
index 9f3108f..f572db5 100644
--- a/files/nftables/inet-filter
+++ b/files/nftables/inet-filter
@@ -1,4 +1,4 @@
-#! nft -f
+#! @sbindir@nft -f
 
 table inet filter {
 	chain input		{ type filter hook input priority 0; }
diff --git a/files/nftables/ipv4-filter b/files/nftables/ipv4-filter
index 3174e7a..a4ca7f2 100644
--- a/files/nftables/ipv4-filter
+++ b/files/nftables/ipv4-filter
@@ -1,4 +1,4 @@
-#! nft -f
+#! @sbindir@nft -f
 
 table filter {
 	chain input		{ type filter hook input priority 0; }
diff --git a/files/nftables/ipv4-mangle b/files/nftables/ipv4-mangle
index 27327d3..be564a5 100644
--- a/files/nftables/ipv4-mangle
+++ b/files/nftables/ipv4-mangle
@@ -1,4 +1,4 @@
-#! nft -f
+#! @sbindir@nft -f
 
 table mangle {
 	chain output		{ type route hook output priority -150; }
diff --git a/files/nftables/ipv4-nat b/files/nftables/ipv4-nat
index 99d6951..01c6c3d 100644
--- a/files/nftables/ipv4-nat
+++ b/files/nftables/ipv4-nat
@@ -1,4 +1,4 @@
-#! nft -f
+#! @sbindir@nft -f
 
 table nat {
 	chain prerouting	{ type nat hook prerouting priority -150; }
diff --git a/files/nftables/ipv6-filter b/files/nftables/ipv6-filter
index 98fce02..ce4d7de 100644
--- a/files/nftables/ipv6-filter
+++ b/files/nftables/ipv6-filter
@@ -1,4 +1,4 @@
-#! nft -f
+#! @sbindir@nft -f
 
 table ip6 filter {
 	chain input		{ type filter hook input priority 0; }
diff --git a/files/nftables/ipv6-mangle b/files/nftables/ipv6-mangle
index 7274353..fa32402 100644
--- a/files/nftables/ipv6-mangle
+++ b/files/nftables/ipv6-mangle
@@ -1,4 +1,4 @@
-#! nft -f
+#! @sbindir@nft -f
 
 table ip6 mangle {
 	chain output		{ type route hook output priority -150; }
diff --git a/files/nftables/ipv6-nat b/files/nftables/ipv6-nat
index 33ecf9b..3f57c56 100644
--- a/files/nftables/ipv6-nat
+++ b/files/nftables/ipv6-nat
@@ -1,4 +1,4 @@
-#! nft -f
+#! @sbindir@nft -f
 
 table ip6 nat {
 	chain prerouting	{ type nat hook prerouting priority -150; }
-- 
2.0.3


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH 3/8] autotool conversion: use pkg-config to find 'libmnl', libnftnl' and 'ncurses'.
  2014-07-25 21:53   ` [PATCH 0/8] patches for an autotooled version of 'nftables' Giorgio Dal Molin
  2014-07-25 21:53     ` [PATCH 1/8] autotool conversion: Added some required files, removed some unneeded Giorgio Dal Molin
  2014-07-25 21:53     ` [PATCH 2/8] autotool conversion: autotools support for the subdir. 'files/nftables' Giorgio Dal Molin
@ 2014-07-25 21:53     ` Giorgio Dal Molin
  2014-07-25 21:53     ` [PATCH 4/8] autotool conversion: converted the subdir. 'src/' Giorgio Dal Molin
                       ` (4 subsequent siblings)
  7 siblings, 0 replies; 22+ messages in thread
From: Giorgio Dal Molin @ 2014-07-25 21:53 UTC (permalink / raw)
  To: netfilter-devel; +Cc: Giorgio Dal Molin

Use pkg-config to find the compile and link flags for 'libnftnl' and
'libmnl'.

Use the special macro AX_LIB_READLINE to check for libreadline and its
dependencies.

The macro is part of the 'autoconf-archive' project:

https://www.gnu.org/software/autoconf-archive/ax_lib_readline.html
---
 configure.ac          |  15 ++++---
 m4/ax_lib_readlibe.m4 | 107 ++++++++++++++++++++++++++++++++++++++++++++++++++
 src/Makefile.am       |  44 +++++++++++++++++++++
 3 files changed, 158 insertions(+), 8 deletions(-)
 create mode 100644 m4/ax_lib_readlibe.m4
 create mode 100644 src/Makefile.am

diff --git a/configure.ac b/configure.ac
index 3a7647f..605d39d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -62,17 +62,16 @@ then
 fi
 
 # Checks for libraries.
-AC_CHECK_LIB([mnl], [mnl_socket_open], ,
-	     AC_MSG_ERROR([No suitable version of libmnl found]))
 
-AC_CHECK_LIB([nftnl], [nft_rule_alloc], ,
-	     AC_MSG_ERROR([No suitable version of libnftnl found]))
+dnl Check for package libnftnl
+PKG_CHECK_MODULES(LIBMNL, [libmnl], , AC_MSG_ERROR([No suitable version of libmnl found]))
 
-AC_CHECK_LIB([gmp], [__gmpz_init], ,
-	     AC_MSG_ERROR([No suitable version of libgmp found]))
+dnl Check for package libnftnl
+PKG_CHECK_MODULES(LIBNFTNL, [libnftnl], , AC_MSG_ERROR([No suitable version of libnftnl found]))
 
-AC_CHECK_LIB([readline], [readline], ,
-	     AC_MSG_ERROR([No suitable version of libreadline found]))
+AC_CHECK_LIB([gmp], [__gmpz_init], , AC_MSG_ERROR([No suitable version of libgmp found]))
+
+AX_LIB_READLINE
 
 # Checks for header files.
 AC_HEADER_STDC
diff --git a/m4/ax_lib_readlibe.m4 b/m4/ax_lib_readlibe.m4
new file mode 100644
index 0000000..056f25c
--- /dev/null
+++ b/m4/ax_lib_readlibe.m4
@@ -0,0 +1,107 @@
+# ===========================================================================
+#      http://www.gnu.org/software/autoconf-archive/ax_lib_readline.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+#   AX_LIB_READLINE
+#
+# DESCRIPTION
+#
+#   Searches for a readline compatible library. If found, defines
+#   `HAVE_LIBREADLINE'. If the found library has the `add_history' function,
+#   sets also `HAVE_READLINE_HISTORY'. Also checks for the locations of the
+#   necessary include files and sets `HAVE_READLINE_H' or
+#   `HAVE_READLINE_READLINE_H' and `HAVE_READLINE_HISTORY_H' or
+#   'HAVE_HISTORY_H' if the corresponding include files exists.
+#
+#   The libraries that may be readline compatible are `libedit',
+#   `libeditline' and `libreadline'. Sometimes we need to link a termcap
+#   library for readline to work, this macro tests these cases too by trying
+#   to link with `libtermcap', `libcurses' or `libncurses' before giving up.
+#
+#   Here is an example of how to use the information provided by this macro
+#   to perform the necessary includes or declarations in a C file:
+#
+#     #ifdef HAVE_LIBREADLINE
+#     #  if defined(HAVE_READLINE_READLINE_H)
+#     #    include <readline/readline.h>
+#     #  elif defined(HAVE_READLINE_H)
+#     #    include <readline.h>
+#     #  else /* !defined(HAVE_READLINE_H) */
+#     extern char *readline ();
+#     #  endif /* !defined(HAVE_READLINE_H) */
+#     char *cmdline = NULL;
+#     #else /* !defined(HAVE_READLINE_READLINE_H) */
+#       /* no readline */
+#     #endif /* HAVE_LIBREADLINE */
+#
+#     #ifdef HAVE_READLINE_HISTORY
+#     #  if defined(HAVE_READLINE_HISTORY_H)
+#     #    include <readline/history.h>
+#     #  elif defined(HAVE_HISTORY_H)
+#     #    include <history.h>
+#     #  else /* !defined(HAVE_HISTORY_H) */
+#     extern void add_history ();
+#     extern int write_history ();
+#     extern int read_history ();
+#     #  endif /* defined(HAVE_READLINE_HISTORY_H) */
+#       /* no history */
+#     #endif /* HAVE_READLINE_HISTORY */
+#
+# LICENSE
+#
+#   Copyright (c) 2008 Ville Laurikari <vl@iki.fi>
+#
+#   Copying and distribution of this file, with or without modification, are
+#   permitted in any medium without royalty provided the copyright notice
+#   and this notice are preserved. This file is offered as-is, without any
+#   warranty.
+
+#serial 6
+
+AU_ALIAS([VL_LIB_READLINE], [AX_LIB_READLINE])
+AC_DEFUN([AX_LIB_READLINE], [
+  AC_CACHE_CHECK([for a readline compatible library],
+                 ax_cv_lib_readline, [
+    ORIG_LIBS="$LIBS"
+    for readline_lib in readline edit editline; do
+      for termcap_lib in "" termcap curses ncurses; do
+        if test -z "$termcap_lib"; then
+          TRY_LIB="-l$readline_lib"
+        else
+          TRY_LIB="-l$readline_lib -l$termcap_lib"
+        fi
+        LIBS="$ORIG_LIBS $TRY_LIB"
+        AC_TRY_LINK_FUNC(readline, ax_cv_lib_readline="$TRY_LIB")
+        if test -n "$ax_cv_lib_readline"; then
+          break
+        fi
+      done
+      if test -n "$ax_cv_lib_readline"; then
+        break
+      fi
+    done
+    if test -z "$ax_cv_lib_readline"; then
+      ax_cv_lib_readline="no"
+    fi
+    LIBS="$ORIG_LIBS"
+  ])
+
+  if test "$ax_cv_lib_readline" != "no"; then
+    LIBS="$LIBS $ax_cv_lib_readline"
+    AC_DEFINE(HAVE_LIBREADLINE, 1,
+              [Define if you have a readline compatible library])
+    AC_CHECK_HEADERS(readline.h readline/readline.h)
+    AC_CACHE_CHECK([whether readline supports history],
+                   ax_cv_lib_readline_history, [
+      ax_cv_lib_readline_history="no"
+      AC_TRY_LINK_FUNC(add_history, ax_cv_lib_readline_history="yes")
+    ])
+    if test "$ax_cv_lib_readline_history" = "yes"; then
+      AC_DEFINE(HAVE_READLINE_HISTORY, 1,
+                [Define if your readline library has \`add_history'])
+      AC_CHECK_HEADERS(history.h readline/history.h)
+    fi
+  fi
+])dnl
diff --git a/src/Makefile.am b/src/Makefile.am
new file mode 100644
index 0000000..5f19732
--- /dev/null
+++ b/src/Makefile.am
@@ -0,0 +1,44 @@
+sbin_PROGRAMS = nft
+
+nft_CFLAGS =	-fno-strict-aliasing							\
+		-Wall									\
+		-Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations		\
+		-Wdeclaration-after-statement -Wsign-compare -Winit-self		\
+		-Wformat-nonliteral -Wformat-security -Wmissing-format-attribute	\
+		-Wcast-align -Wundef -Wbad-function-cast				\
+		-Waggregate-return -Wunused -Wwrite-strings
+
+nft_CPPFLAGS = -I${srcdir}/../include ${LIBMNL_CFLAGS} ${LIBNFTNL_CFLAGS}
+
+nft_LDADD = ${LIBMNL_LIBS} ${LIBNFTNL_LIBS}
+
+AM_YFLAGS = -d
+BUILT_SOURCES =	scanner.c scanner.h yacc_parser.c yacc_parser.h
+
+scanner.h: scanner.c
+
+nft_SOURCES = 	main.c				\
+		cli.c				\
+		rule.c				\
+		statement.c			\
+		datatype.c			\
+		expression.c			\
+		evaluate.c			\
+		proto.c				\
+		payload.c			\
+		exthdr.c			\
+		meta.c				\
+		ct.c				\
+		netlink.c			\
+		netlink_linearize.c		\
+		netlink_delinearize.c		\
+		segtree.c			\
+		rbtree.c			\
+		gmputil.c			\
+		utils.c				\
+		erec.c				\
+		mnl.c				\
+		scanner.l			\
+		yacc_parser.y
+
+CLEANFILES = *~ scanner.c scanner.h yacc_parser.c yacc_parser.h
-- 
2.0.3


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH 4/8] autotool conversion: converted the subdir. 'src/'
  2014-07-25 21:53   ` [PATCH 0/8] patches for an autotooled version of 'nftables' Giorgio Dal Molin
                       ` (2 preceding siblings ...)
  2014-07-25 21:53     ` [PATCH 3/8] autotool conversion: use pkg-config to find 'libmnl', libnftnl' and 'ncurses' Giorgio Dal Molin
@ 2014-07-25 21:53     ` Giorgio Dal Molin
  2014-07-25 21:53     ` [PATCH 5/8] autotools conversion: include the header 'config.h' in every C source file Giorgio Dal Molin
                       ` (3 subsequent siblings)
  7 siblings, 0 replies; 22+ messages in thread
From: Giorgio Dal Molin @ 2014-07-25 21:53 UTC (permalink / raw)
  To: netfilter-devel; +Cc: Giorgio Dal Molin

Use specialized test macros to find 'yacc' and 'lex' in the configure.ac.

Renamed the file 'src/parser.y' to 'src/yacc_parser.y' to avoid having
two header files with the same name, 'parser.h': one under 'src/',
generated by 'yacc' from 'parser.y' and the other under 'include/'.

Added an %option line to 'src/scanner.l': this new %option directive
lets us save a custom recipe in the 'src/Makefile.am'; it replaces the
'lex' command line option '--outfile=scanner.c'.
We don't have any explicit make recipe to call 'lex' on 'scanner.l' to
generate 'scanner.c' and 'scanner.h' as in the old 'Makefile.rules';
listing the file 'scanner.l' in the variable 'nft_SOURCES' of
'src/Makefile.am' is now enough.
---
 configure.ac                    | 13 ++-----------
 src/Makefile.in                 | 31 -------------------------------
 src/scanner.l                   |  3 ++-
 src/{parser.y => yacc_parser.y} |  4 ++--
 4 files changed, 6 insertions(+), 45 deletions(-)
 delete mode 100644 src/Makefile.in
 rename src/{parser.y => yacc_parser.y} (99%)

diff --git a/configure.ac b/configure.ac
index 605d39d..900b26a 100644
--- a/configure.ac
+++ b/configure.ac
@@ -24,6 +24,8 @@ AC_PROG_CC
 AC_PROG_MKDIR_P
 AC_PROG_INSTALL
 AC_PROG_SED
+AC_PROG_YACC
+AM_PROG_LEX
 
 AC_CHECK_PROG(CONFIG_MAN1, [docbook2x-man], [y], [n])
 if test "$CONFIG_MAN1" == "y"
@@ -49,17 +51,6 @@ then
 	AC_MSG_WARN([dblatex not found, no PDF manpages will be built])
 fi
 
-AC_PATH_PROG(LEX, [flex])
-if test -z "$LEX"
-then
-	AC_MSG_ERROR([No suitable version of flex found])
-fi
-
-AC_PATH_PROG(YACC, [bison])
-if test -z "$YACC"
-then
-	AC_MSG_ERROR([No suitable version of bison found])
-fi
 
 # Checks for libraries.
 
diff --git a/src/Makefile.in b/src/Makefile.in
deleted file mode 100644
index 8ac2b46..0000000
--- a/src/Makefile.in
+++ /dev/null
@@ -1,31 +0,0 @@
-PROGRAMS		+= nft
-
-nft-destdir		:= @sbindir@
-
-nft-obj			+= main.o
-nft-obj			+= cli.o
-nft-obj			+= rule.o
-nft-obj			+= statement.o
-nft-obj			+= datatype.o
-nft-obj			+= expression.o
-nft-obj			+= evaluate.o
-nft-obj			+= proto.o
-nft-obj			+= payload.o
-nft-obj			+= exthdr.o
-nft-obj			+= meta.o
-nft-obj			+= ct.o
-nft-obj			+= netlink.o
-nft-obj			+= netlink_linearize.o
-nft-obj			+= netlink_delinearize.o
-nft-obj			+= segtree.o
-nft-obj			+= rbtree.o
-nft-obj			+= gmputil.o
-nft-obj			+= utils.o
-nft-obj			+= erec.o
-nft-obj			+= mnl.o
-
-nft-obj			+= parser.o
-nft-extra-clean-files	+= parser.c parser.h
-
-nft-obj			+= scanner.o
-nft-extra-clean-files	+= scanner.c scanner.h
diff --git a/src/scanner.l b/src/scanner.l
index 73a1a3f..e6b8127 100644
--- a/src/scanner.l
+++ b/src/scanner.l
@@ -20,7 +20,7 @@
 #include <erec.h>
 #include <rule.h>
 #include <parser.h>
-#include "parser.h"
+#include "yacc_parser.h"
 
 #define YY_NO_INPUT
 
@@ -178,6 +178,7 @@ addrstring	({macaddr}|{ip4addr}|{ip6addr})
 %option yylineno
 %option nodefault
 %option warn
+%option outfile="scanner.c"
 
 %%
 
diff --git a/src/parser.y b/src/yacc_parser.y
similarity index 99%
rename from src/parser.y
rename to src/yacc_parser.y
index 3e08e21..7cb790d 100644
--- a/src/parser.y
+++ b/src/yacc_parser.y
@@ -12,6 +12,7 @@
 
 #include <stddef.h>
 #include <stdio.h>
+#include <string.h>
 #include <inttypes.h>
 #include <netinet/ip.h>
 #include <netinet/if_ether.h>
@@ -27,8 +28,7 @@
 #include <parser.h>
 #include <erec.h>
 
-#include "parser.h"
-#include "scanner.h"
+#include "yacc_parser.h"
 
 void parser_init(struct parser_state *state, struct list_head *msgs)
 {
-- 
2.0.3


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH 5/8] autotools conversion: include the header 'config.h' in every C source file.
  2014-07-25 21:53   ` [PATCH 0/8] patches for an autotooled version of 'nftables' Giorgio Dal Molin
                       ` (3 preceding siblings ...)
  2014-07-25 21:53     ` [PATCH 4/8] autotool conversion: converted the subdir. 'src/' Giorgio Dal Molin
@ 2014-07-25 21:53     ` Giorgio Dal Molin
  2014-07-25 21:53     ` [PATCH 6/8] autotool conversion: Converted the support for the 'doc/' subdir Giorgio Dal Molin
                       ` (2 subsequent siblings)
  7 siblings, 0 replies; 22+ messages in thread
From: Giorgio Dal Molin @ 2014-07-25 21:53 UTC (permalink / raw)
  To: netfilter-devel; +Cc: Giorgio Dal Molin

Added an #include <config.h> to all the C source files so that the results
of the tests in the configure script are available to all the compilation
units.

We could have added the include also to 'yacc_parser.y' and 'scanner.l'
but we don't, because it is not strictly needed and to avoid to define
the variable 'VERSION' two times.
---
 src/cli.c                 | 2 ++
 src/ct.c                  | 2 ++
 src/datatype.c            | 2 ++
 src/erec.c                | 2 ++
 src/evaluate.c            | 2 ++
 src/expression.c          | 2 ++
 src/exthdr.c              | 2 ++
 src/gmputil.c             | 2 ++
 src/main.c                | 2 ++
 src/meta.c                | 2 ++
 src/mnl.c                 | 2 ++
 src/netlink.c             | 2 ++
 src/netlink_delinearize.c | 2 ++
 src/netlink_linearize.c   | 2 ++
 src/payload.c             | 2 ++
 src/proto.c               | 2 ++
 src/rbtree.c              | 2 ++
 src/rule.c                | 2 ++
 src/segtree.c             | 2 ++
 src/statement.c           | 2 ++
 src/utils.c               | 2 ++
 21 files changed, 42 insertions(+)

diff --git a/src/cli.c b/src/cli.c
index f748a0e..8943349 100644
--- a/src/cli.c
+++ b/src/cli.c
@@ -12,6 +12,8 @@
  * Development of this code funded by Astaro AG (http://www.astaro.com/)
  */
 
+#include <config.h>
+
 #include <stdlib.h>
 #include <stdio.h>
 #include <stdarg.h>
diff --git a/src/ct.c b/src/ct.c
index 30639b2..3bddfcb 100644
--- a/src/ct.c
+++ b/src/ct.c
@@ -10,6 +10,8 @@
  * Development of this code funded by Astaro AG (http://www.astaro.com/)
  */
 
+#include <config.h>
+
 #include <stddef.h>
 #include <stdlib.h>
 #include <stdio.h>
diff --git a/src/datatype.c b/src/datatype.c
index 55af227..2ce2997 100644
--- a/src/datatype.c
+++ b/src/datatype.c
@@ -8,6 +8,8 @@
  * Development of this code funded by Astaro AG (http://www.astaro.com/)
  */
 
+#include <config.h>
+
 #include <stdlib.h>
 #include <string.h>
 #include <inttypes.h>
diff --git a/src/erec.c b/src/erec.c
index 4930085..8532470 100644
--- a/src/erec.c
+++ b/src/erec.c
@@ -8,6 +8,8 @@
  * Development of this code funded by Astaro AG (http://www.astaro.com/)
  */
 
+#include <config.h>
+
 #include <stdio.h>
 #include <string.h>
 #include <stdarg.h>
diff --git a/src/evaluate.c b/src/evaluate.c
index e05473a..ae54d00 100644
--- a/src/evaluate.c
+++ b/src/evaluate.c
@@ -8,6 +8,8 @@
  * Development of this code funded by Astaro AG (http://www.astaro.com/)
  */
 
+#include <config.h>
+
 #include <stddef.h>
 #include <stdlib.h>
 #include <stdio.h>
diff --git a/src/expression.c b/src/expression.c
index fa14d99..d3b4952 100644
--- a/src/expression.c
+++ b/src/expression.c
@@ -8,6 +8,8 @@
  * Development of this code funded by Astaro AG (http://www.astaro.com/)
  */
 
+#include <config.h>
+
 #include <stddef.h>
 #include <stdlib.h>
 #include <stdio.h>
diff --git a/src/exthdr.c b/src/exthdr.c
index a619ecc..a980555 100644
--- a/src/exthdr.c
+++ b/src/exthdr.c
@@ -10,6 +10,8 @@
  * Development of this code funded by Astaro AG (http://www.astaro.com/)
  */
 
+#include <config.h>
+
 #include <stddef.h>
 #include <stdlib.h>
 #include <stdio.h>
diff --git a/src/gmputil.c b/src/gmputil.c
index cb46445..3d22702 100644
--- a/src/gmputil.c
+++ b/src/gmputil.c
@@ -8,6 +8,8 @@
  * Development of this code funded by Astaro AG (http://www.astaro.com/)
  */
 
+#include <config.h>
+
 #include <stddef.h>
 #include <stdlib.h>
 #include <stdarg.h>
diff --git a/src/main.c b/src/main.c
index bd8feee..c2bbc9f 100644
--- a/src/main.c
+++ b/src/main.c
@@ -8,6 +8,8 @@
  * Development of this code funded by Astaro AG (http://www.astaro.com/)
  */
 
+#include <config.h>
+
 #include <stdlib.h>
 #include <stddef.h>
 #include <unistd.h>
diff --git a/src/meta.c b/src/meta.c
index 80f88ff..b9db99f 100644
--- a/src/meta.c
+++ b/src/meta.c
@@ -10,6 +10,8 @@
  * Development of this code funded by Astaro AG (http://www.astaro.com/)
  */
 
+#include <config.h>
+
 #include <stddef.h>
 #include <stdlib.h>
 #include <stdio.h>
diff --git a/src/mnl.c b/src/mnl.c
index 42b11f5..9f4a0c2 100644
--- a/src/mnl.c
+++ b/src/mnl.c
@@ -8,6 +8,8 @@
  * Development of this code funded by Astaro AG (http://www.astaro.com/)
  */
 
+#include <config.h>
+
 #include <libmnl/libmnl.h>
 #include <libnftnl/common.h>
 #include <libnftnl/ruleset.h>
diff --git a/src/netlink.c b/src/netlink.c
index e149215..a85ee0d 100644
--- a/src/netlink.c
+++ b/src/netlink.c
@@ -9,6 +9,8 @@
  * Development of this code funded by Astaro AG (http://www.astaro.com/)
  */
 
+#include <config.h>
+
 #include <string.h>
 #include <fcntl.h>
 #include <errno.h>
diff --git a/src/netlink_delinearize.c b/src/netlink_delinearize.c
index 5c6ca80..1cb514f 100644
--- a/src/netlink_delinearize.c
+++ b/src/netlink_delinearize.c
@@ -9,6 +9,8 @@
  * Development of this code funded by Astaro AG (http://www.astaro.com/)
  */
 
+#include <config.h>
+
 #include <stdlib.h>
 #include <stdbool.h>
 #include <string.h>
diff --git a/src/netlink_linearize.c b/src/netlink_linearize.c
index 5c1b46d..7dbe99e 100644
--- a/src/netlink_linearize.c
+++ b/src/netlink_linearize.c
@@ -9,6 +9,8 @@
  * Development of this code funded by Astaro AG (http://www.astaro.com/)
  */
 
+#include <config.h>
+
 #include <linux/netfilter/nf_tables.h>
 
 #include <string.h>
diff --git a/src/payload.c b/src/payload.c
index a1785a5..553597d 100644
--- a/src/payload.c
+++ b/src/payload.c
@@ -10,6 +10,8 @@
  * Development of this code funded by Astaro AG (http://www.astaro.com/)
  */
 
+#include <config.h>
+
 #include <stddef.h>
 #include <stdlib.h>
 #include <stdio.h>
diff --git a/src/proto.c b/src/proto.c
index e5f49cb..4d81453 100644
--- a/src/proto.c
+++ b/src/proto.c
@@ -9,6 +9,8 @@
  *
  */
 
+#include <config.h>
+
 #include <stddef.h>
 #include <stdlib.h>
 #include <stdint.h>
diff --git a/src/rbtree.c b/src/rbtree.c
index 325c012..c400c0d 100644
--- a/src/rbtree.c
+++ b/src/rbtree.c
@@ -19,6 +19,8 @@
  *
  */
 
+#include <config.h>
+
 #include <rbtree.h>
 
 static void __rb_rotate_left(struct rb_node *node, struct rb_root *root)
diff --git a/src/rule.c b/src/rule.c
index 1e54526..2958982 100644
--- a/src/rule.c
+++ b/src/rule.c
@@ -8,6 +8,8 @@
  * Development of this code funded by Astaro AG (http://www.astaro.com/)
  */
 
+#include <config.h>
+
 #include <stddef.h>
 #include <stdlib.h>
 #include <stdio.h>
diff --git a/src/segtree.c b/src/segtree.c
index 1785f64..a538670 100644
--- a/src/segtree.c
+++ b/src/segtree.c
@@ -8,6 +8,8 @@
  * Development of this code funded by Astaro AG (http://www.astaro.com/)
  */
 
+#include <config.h>
+
 #include <stdlib.h>
 #include <inttypes.h>
 #include <arpa/inet.h>
diff --git a/src/statement.c b/src/statement.c
index 2dd3f18..03f3ddc 100644
--- a/src/statement.c
+++ b/src/statement.c
@@ -8,6 +8,8 @@
  * Development of this code funded by Astaro AG (http://www.astaro.com/)
  */
 
+#include <config.h>
+
 #include <stddef.h>
 #include <stdlib.h>
 #include <stdio.h>
diff --git a/src/utils.c b/src/utils.c
index 96ff419..bf1e8dc 100644
--- a/src/utils.c
+++ b/src/utils.c
@@ -8,6 +8,8 @@
  * Development of this code funded by Astaro AG (http://www.astaro.com/)
  */
 
+#include <config.h>
+
 #include <stddef.h>
 #include <stdlib.h>
 #include <stdarg.h>
-- 
2.0.3


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH 6/8] autotool conversion: Converted the support for the 'doc/' subdir.
  2014-07-25 21:53   ` [PATCH 0/8] patches for an autotooled version of 'nftables' Giorgio Dal Molin
                       ` (4 preceding siblings ...)
  2014-07-25 21:53     ` [PATCH 5/8] autotools conversion: include the header 'config.h' in every C source file Giorgio Dal Molin
@ 2014-07-25 21:53     ` Giorgio Dal Molin
  2014-07-25 21:53     ` [PATCH 7/8] autotools conversion: commit the rest of the configure.ac changes Giorgio Dal Molin
  2014-07-25 21:53     ` [PATCH 8/8] autotool conversion: updated the files .gitignore Giorgio Dal Molin
  7 siblings, 0 replies; 22+ messages in thread
From: Giorgio Dal Molin @ 2014-07-25 21:53 UTC (permalink / raw)
  To: netfilter-devel; +Cc: Giorgio Dal Molin

To generate the nft.8 man page the configure script searches for the
tools 'docbookx2-man' and 'db2x_docbook2man'; if at least one is found
then the man page is generated. To force the system not to generate the
man page use the option '--disable-man'.

To generate the pdf doc file the configure script searches for the tool
'dblatex'; if it is found then the pdf doc file is generated. To force
the system not to generate the pdf doc file use the option '--disable-pdf'.
---
 configure.ac    | 73 +++++++++++++++++++++++++++++++++++++++------------------
 doc/Makefile.am | 10 ++++++++
 doc/Makefile.in | 20 ----------------
 3 files changed, 60 insertions(+), 43 deletions(-)
 create mode 100644 doc/Makefile.am
 delete mode 100644 doc/Makefile.in

diff --git a/configure.ac b/configure.ac
index 900b26a..18ca0a2 100644
--- a/configure.ac
+++ b/configure.ac
@@ -27,30 +27,57 @@ AC_PROG_SED
 AC_PROG_YACC
 AM_PROG_LEX
 
-AC_CHECK_PROG(CONFIG_MAN1, [docbook2x-man], [y], [n])
-if test "$CONFIG_MAN1" == "y"
-then
-	CONFIG_MAN=y
-	DB2MAN=docbook2x-man
-else
-	AC_CHECK_PROG(CONFIG_MAN2, [db2x_docbook2man], [y], [n])
-	if test "$CONFIG_MAN2" == "y"
-	then
-		CONFIG_MAN=y
-		DB2MAN=db2x_docbook2man
-	else
-		AC_MSG_WARN([docbookx2-man/db2x_docbook2man not found, no manpages will be built])
-	fi
-fi
-AC_SUBST(CONFIG_MAN)
-AC_SUBST(DB2MAN)
-
-AC_CHECK_PROG(CONFIG_PDF, dblatex, y, n)
-if test "$CONFIG_PDF" != "y"
-then
-	AC_MSG_WARN([dblatex not found, no PDF manpages will be built])
-fi
+AC_CHECK_PROG(DOCBOOK2X_MAN, [docbook2x-man], [found], [no])
+AC_CHECK_PROG(DB2X_DOCBOOK2MAN, [db2x_docbook2man], [found], [no])
+AS_CASE([$DOCBOOK2X_MAN],
+	[found],[
+		DB2MAN=docbook2x-man
+		NFT_8=nft.8
+		],
+	[AS_CASE([$DB2X_DOCBOOK2MAN],
+		[found],[
+			DB2MAN=db2x_docbook2man
+			NFT_8=nft.8
+			],
+		[AC_MSG_WARN([docbookx2-man/db2x_docbook2man not found, no manpages will be built])]
+	)]
+)
+
+AC_ARG_ENABLE([man], AS_HELP_STRING([--enable-man], [Enable generating the man page nft.8. Requires docbook2x-man or db2x_docbook2man.]))
+
+AC_MSG_CHECKING([whether to generate the man page])
+AS_CASE([${enable_man}],
+	[yes],[
+		AS_IF([test -z "$DB2MAN"],AC_MSG_ERROR([No tool found to generate the man page. Please install either docbook2x-man or db2x_docbook2man.]))
+		AC_MSG_RESULT(yes)
+	], [
+	NFT_8=""
+	AC_MSG_RESULT(no)
+	]
+)
 
+AC_SUBST(DB2MAN)
+AC_SUBST(NFT_8)
+
+AC_CHECK_PROG(DBLATEX, [dblatex], [found], [no])
+AS_CASE([$DBLATEX],
+	[found],[NFT_PDF=nft.pdf],
+	[AC_MSG_WARN([dblatex not found, no PDF manpages will be built])]
+)
+
+AC_MSG_CHECKING([whether to generate the pdf doc])
+AC_ARG_ENABLE([pdf], AS_HELP_STRING([--enable-pdf], [Enable generating the pdf doc file nft.pdf. Requires dblatex.]))
+AS_CASE([${enable_pdf}],
+	[yes],[
+		AS_IF([test -z "$DBLATEX"], AC_MSG_ERROR([No tool found to generate the pdf doc. Please install dblatex.]))
+		AC_MSG_RESULT(yes)
+	],[
+	NFT_PDF=""
+	AC_MSG_RESULT(no)
+	]
+)
+
+AC_SUBST(NFT_PDF)
 
 # Checks for libraries.
 
diff --git a/doc/Makefile.am b/doc/Makefile.am
new file mode 100644
index 0000000..58c79df
--- /dev/null
+++ b/doc/Makefile.am
@@ -0,0 +1,10 @@
+man_MANS = @NFT_8@
+pdf_DATA = @NFT_PDF@
+
+pdfdir=${docdir}/pdf
+
+.xml.pdf:
+	${AM_V_GEN}dblatex -q -t pdf -o $@ $<
+
+.8.xml:
+	${AM_V_GEN}$(DB2MAN) --xinclude $<
diff --git a/doc/Makefile.in b/doc/Makefile.in
deleted file mode 100644
index 1ec856c..0000000
--- a/doc/Makefile.in
+++ /dev/null
@@ -1,20 +0,0 @@
-mandocs-@CONFIG_MAN@	+= doc/nft.8
-pdfdocs-@CONFIG_PDF@	+= doc/nft.pdf
-
-all:		$(mandocs-y) $(pdfdocs-y)
-clean:
-		@echo -e "  CLEAN\t\tdoc"
-		$(RM) $(mandocs-y) $(pdfdocs-y)
-
-install:	$(mandocs-y) $(pdfdocs-y)
-		@echo -e "  INSTALL\tdoc"
-		if test -n "$(mandocs-y)"; then \
-			$(MKDIR_P) $(DESTDIR)/${mandir}/man8 ;\
-			$(INSTALL) -m 755 -p $(mandocs-y) \
-					$(DESTDIR)/${mandir}/man8/ ;\
-		fi
-		if test -n "$(pdfdocs-y)"; then \
-			$(MKDIR_P) $(DESTDIR)/${pdfdir} ;\
-			$(INSTALL) -m 755 -p $(pdfdocs-y) \
-					$(DESTDIR)/${pdfdir}/ ;\
-		fi
-- 
2.0.3


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH 7/8] autotools conversion: commit the rest of the configure.ac changes.
  2014-07-25 21:53   ` [PATCH 0/8] patches for an autotooled version of 'nftables' Giorgio Dal Molin
                       ` (5 preceding siblings ...)
  2014-07-25 21:53     ` [PATCH 6/8] autotool conversion: Converted the support for the 'doc/' subdir Giorgio Dal Molin
@ 2014-07-25 21:53     ` Giorgio Dal Molin
  2014-07-25 21:53     ` [PATCH 8/8] autotool conversion: updated the files .gitignore Giorgio Dal Molin
  7 siblings, 0 replies; 22+ messages in thread
From: Giorgio Dal Molin @ 2014-07-25 21:53 UTC (permalink / raw)
  To: netfilter-devel; +Cc: Giorgio Dal Molin

Mainly the handling of the option '--enable-debug' and the definition of
the cpp variable DEFAULT_INCLUDE_PATH; the definition is written to
the generated header 'config.h', included by all the 'src/*.c'.

Also updated the script 'autogen.sh' to support calling it from a
build directory different from the package root.
---
 autogen.sh      | 10 ++++++++--
 configure.ac    | 32 ++++++++++++++++++++++++++------
 src/Makefile.am |  4 ++--
 3 files changed, 36 insertions(+), 10 deletions(-)

diff --git a/autogen.sh b/autogen.sh
index a62e737..ce6243c 100755
--- a/autogen.sh
+++ b/autogen.sh
@@ -1,4 +1,10 @@
-#!/bin/bash
+#! /bin/sh
 
-autoreconf -fi;
+srcdir=`dirname $0`
+test -z "$srcdir" && srcdir=.
+
+ORIGDIR=`pwd`
+cd $srcdir
+
+autoreconf -fvi || exit 1
 rm -Rf autom4te*.cache config.h.in~
diff --git a/configure.ac b/configure.ac
index 18ca0a2..f4a6051 100644
--- a/configure.ac
+++ b/configure.ac
@@ -5,7 +5,13 @@ AC_PREREQ(2.61)
 
 AC_COPYRIGHT([Copyright (c) 2008 Patrick McHardy <kaber@trash.net>])
 AC_INIT([nftables], [0.3], [netfilter-devel@vger.kernel.org])
+AM_INIT_AUTOMAKE([dist-bzip2 dist-xz])
+AM_MAINTAINER_MODE([disable])
+AM_SILENT_RULES([yes])
+AC_CONFIG_MACRO_DIR([m4])
+
 AC_DEFINE([RELEASE_NAME], ["Support Edward Snowden"], [Release name])
+AC_DEFINE_UNQUOTED([DEFAULT_INCLUDE_PATH],["$confdir"],[define DEFAULT_INCLUDE_PATH])
 
 AC_CONFIG_SRCDIR([src/rule.c])
 AC_CONFIG_HEADER([config.h])
@@ -14,10 +20,17 @@ AC_DEFINE([_GNU_SOURCE], [], [Enable various GNU extensions])
 AC_DEFINE([_STDC_FORMAT_MACROS], [], [printf-style format macros])
 
 AC_ARG_ENABLE([debug],
-	      AS_HELP_STRING([--enable-debug], [Enable debugging]),
-	      [CONFIG_DEBUG="$(echo $enableval | cut -b1)"],
-	      [CONFIG_DEBUG="y"])
-AC_SUBST([CONFIG_DEBUG])
+	      AS_HELP_STRING([--enable-debug], [Enable debugging]))
+
+AS_CASE([$enable_debug],
+	[yes],[
+	AC_DEFINE([DEBUG],1,[Debug enabled])
+	DEBUG_CPPFLAGS="-DDEBUG"
+	DEBUG_CFLAGS="-g"
+	])
+
+AC_SUBST(DEBUG_CPPFLAGS)
+AC_SUBST(DEBUG_CFLAGS)
 
 # Checks for programs.
 AC_PROG_CC
@@ -119,6 +132,13 @@ AC_TYPE_UINT64_T
 # Checks for library functions.
 AC_CHECK_FUNCS([memmove memset strchr strdup strerror strtoull])
 
-AC_CONFIG_FILES([Makefile Makefile.defs Makefile.rules])
-AC_CONFIG_FILES([src/Makefile doc/Makefile files/Makefile])
+AC_CONFIG_FILES([	Makefile				\
+			src/Makefile				\
+			doc/Makefile				\
+			files/Makefile				\
+			files/nftables/Makefile			\
+			include/Makefile			\
+			include/linux/Makefile			\
+			include/linux/netfilter/Makefile	\
+		])
 AC_OUTPUT
diff --git a/src/Makefile.am b/src/Makefile.am
index 5f19732..2b2c535 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -6,9 +6,9 @@ nft_CFLAGS =	-fno-strict-aliasing							\
 		-Wdeclaration-after-statement -Wsign-compare -Winit-self		\
 		-Wformat-nonliteral -Wformat-security -Wmissing-format-attribute	\
 		-Wcast-align -Wundef -Wbad-function-cast				\
-		-Waggregate-return -Wunused -Wwrite-strings
+		-Waggregate-return -Wunused -Wwrite-strings ${DEBUG_CFLAGS}
 
-nft_CPPFLAGS = -I${srcdir}/../include ${LIBMNL_CFLAGS} ${LIBNFTNL_CFLAGS}
+nft_CPPFLAGS = -I${srcdir}/../include ${LIBMNL_CFLAGS} ${LIBNFTNL_CFLAGS} ${DEBUG_CPPFLAGS}
 
 nft_LDADD = ${LIBMNL_LIBS} ${LIBNFTNL_LIBS}
 
-- 
2.0.3


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH 8/8] autotool conversion: updated the files .gitignore
  2014-07-25 21:53   ` [PATCH 0/8] patches for an autotooled version of 'nftables' Giorgio Dal Molin
                       ` (6 preceding siblings ...)
  2014-07-25 21:53     ` [PATCH 7/8] autotools conversion: commit the rest of the configure.ac changes Giorgio Dal Molin
@ 2014-07-25 21:53     ` Giorgio Dal Molin
  7 siblings, 0 replies; 22+ messages in thread
From: Giorgio Dal Molin @ 2014-07-25 21:53 UTC (permalink / raw)
  To: netfilter-devel; +Cc: Giorgio Dal Molin

Tuned the file '.gitignore' and 'src/.gitignore' to filter out the auto
generated files.
---
 .gitignore     | 19 ++++++++++++-------
 src/.gitignore |  4 ++--
 2 files changed, 14 insertions(+), 9 deletions(-)

diff --git a/.gitignore b/.gitignore
index d26b395..998760d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,18 +1,23 @@
-# Dependency and object files
-.*.d
-*.o
-
 # Generated by autoconf/configure
 Makefile
-Makefile.defs
-Makefile.rules
+Makefile.in
 config.h
 config.h.in
-config.h.in~
 config.log
 config.status
 configure
 autom4te.cache
+missing
+compile
+depcomp
+stamp-h1
+ylwrap
+aclocal.m4
+install-sh
+.deps
+*.o
+*~
+
 
 # Debian package build temporary files
 build-stamp
diff --git a/src/.gitignore b/src/.gitignore
index 23e6ae0..50ff292 100644
--- a/src/.gitignore
+++ b/src/.gitignore
@@ -1,5 +1,5 @@
-parser.c
-parser.h
+yacc_parser.c
+yacc_parser.h
 scanner.c
 scanner.h
 nft
-- 
2.0.3


^ permalink raw reply related	[flat|nested] 22+ messages in thread

end of thread, other threads:[~2014-07-25 21:55 UTC | newest]

Thread overview: 22+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-07-07 14:19 [PATCH 0/7] patches for an autotooled version of 'nftables'. (vers. 2) Giorgio Dal Molin
2014-07-07 14:19 ` [PATCH 1/7] autotool conversion: autotools support for the subdir. 'files/nftables' Giorgio Dal Molin
2014-07-07 14:19 ` [PATCH 2/7] autotool conversion: use pkg-config to find 'libmnl', libnftnl' and 'ncurses' Giorgio Dal Molin
2014-07-07 14:19 ` [PATCH 3/7] autotool conversion: converted the subdir. 'src/' Giorgio Dal Molin
2014-07-10 10:08   ` Pablo Neira Ayuso
2014-07-10 10:42     ` Giorgio Dal Molin
2014-07-07 14:19 ` [PATCH 4/7] autotools conversion: include the header 'config.h' in every C source file Giorgio Dal Molin
2014-07-10 10:04   ` Patrick McHardy
2014-07-11  7:24     ` Jan Engelhardt
2014-07-07 14:19 ` [PATCH 5/7] autotool conversion: Converted the support for the 'doc/' subdir Giorgio Dal Molin
2014-07-07 14:19 ` [PATCH 6/7] autotools conversion: commit the rest of the configure.ac changes Giorgio Dal Molin
2014-07-07 14:19 ` [PATCH 7/7] autotool conversion: updated the files .gitignore Giorgio Dal Molin
2014-07-25 17:16 ` [PATCH 0/7] patches for an autotooled version of 'nftables'. (vers. 2) Pablo Neira Ayuso
2014-07-25 21:53   ` [PATCH 0/8] patches for an autotooled version of 'nftables' Giorgio Dal Molin
2014-07-25 21:53     ` [PATCH 1/8] autotool conversion: Added some required files, removed some unneeded Giorgio Dal Molin
2014-07-25 21:53     ` [PATCH 2/8] autotool conversion: autotools support for the subdir. 'files/nftables' Giorgio Dal Molin
2014-07-25 21:53     ` [PATCH 3/8] autotool conversion: use pkg-config to find 'libmnl', libnftnl' and 'ncurses' Giorgio Dal Molin
2014-07-25 21:53     ` [PATCH 4/8] autotool conversion: converted the subdir. 'src/' Giorgio Dal Molin
2014-07-25 21:53     ` [PATCH 5/8] autotools conversion: include the header 'config.h' in every C source file Giorgio Dal Molin
2014-07-25 21:53     ` [PATCH 6/8] autotool conversion: Converted the support for the 'doc/' subdir Giorgio Dal Molin
2014-07-25 21:53     ` [PATCH 7/8] autotools conversion: commit the rest of the configure.ac changes Giorgio Dal Molin
2014-07-25 21:53     ` [PATCH 8/8] autotool conversion: updated the files .gitignore Giorgio Dal Molin

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.