netfilter-devel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* nftables: use automake & pkgconfig
@ 2013-10-20 14:48 Jan Engelhardt
  2013-10-20 14:48 ` [PATCH 1/3] build: remove unused checks Jan Engelhardt
                   ` (3 more replies)
  0 siblings, 4 replies; 17+ messages in thread
From: Jan Engelhardt @ 2013-10-20 14:48 UTC (permalink / raw)
  To: netfilter-devel; +Cc: pablo


The following changes since commit 2855909e46f4646f137a96892bd5c465fa1193f8:

  src: fix return code (2013-10-17 11:08:40 +0200)

are available in the git repository at:

  git://git.inai.de/nftables master

for you to fetch changes up to af2a890f6fa39d09240b85811a430b51b88a866e:

  build: use automake and pkgconfig (2013-10-20 16:36:53 +0200)

----------------------------------------------------------------
Jan Engelhardt (3):
      build: remove unused checks
      build: rename conflicting parser.h instances
      build: use automake and pkgconfig

 .gitignore                      |  17 +--
 Makefile.am                     |   7 ++
 Makefile.defs.in                |  40 ------
 Makefile.in                     |   5 -
 Makefile.rules.in               |  89 -------------
 configure.ac                    |  70 ++++-------
 doc/Makefile.am                 |  14 +++
 doc/Makefile.in                 |  20 ---
 files/Makefile.am               |   6 +
 files/Makefile.in               |   4 -
 install-sh                      | 269 ----------------------------------------
 src/.gitignore                  |   4 +-
 src/Makefile.am                 |  24 ++++
 src/Makefile.in                 |  30 -----
 src/cli.c                       |   1 +
 src/erec.c                      |   1 +
 src/main.c                      |   1 +
 src/{parser.y => parser_impl.y} |   2 +-
 src/scanner.l                   |   2 +-
 19 files changed, 90 insertions(+), 516 deletions(-)
 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 doc/Makefile.am
 delete mode 100644 doc/Makefile.in
 create mode 100644 files/Makefile.am
 delete mode 100644 files/Makefile.in
 delete mode 100755 install-sh
 create mode 100644 src/Makefile.am
 delete mode 100644 src/Makefile.in
 rename src/{parser.y => parser_impl.y} (99%)

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

* [PATCH 1/3] build: remove unused checks
  2013-10-20 14:48 nftables: use automake & pkgconfig Jan Engelhardt
@ 2013-10-20 14:48 ` Jan Engelhardt
  2013-11-19 20:24   ` Pablo Neira Ayuso
  2013-10-20 14:48 ` [PATCH 2/3] build: rename conflicting parser.h instances Jan Engelhardt
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 17+ messages in thread
From: Jan Engelhardt @ 2013-10-20 14:48 UTC (permalink / raw)
  To: netfilter-devel; +Cc: pablo

The result of these checks was never evaluated, so remove them.

Signed-off-by: Jan Engelhardt <jengelh@inai.de>
---
 configure.ac | 31 -------------------------------
 1 file changed, 31 deletions(-)

diff --git a/configure.ac b/configure.ac
index 811d7e2..b850451 100644
--- a/configure.ac
+++ b/configure.ac
@@ -21,7 +21,6 @@ AC_SUBST([CONFIG_DEBUG])
 
 # Checks for programs.
 AC_PROG_CC
-AC_PROG_MKDIR_P
 AC_PROG_INSTALL
 
 AC_CHECK_PROG(CONFIG_MAN, docbook2x-man, y, n)
@@ -61,36 +60,6 @@ AC_CHECK_LIB([gmp], [__gmpz_init], ,
 AC_CHECK_LIB([readline], [readline], ,
 	     AC_MSG_ERROR([No suitable version of libreadline found]))
 
-# Checks for header files.
-AC_HEADER_STDC
-AC_HEADER_ASSERT
-AC_CHECK_HEADERS([arpa/inet.h fcntl.h inttypes.h libintl.h limits.h malloc.h \
-		  netdb.h netinet/in.h netinet/ip.h netinet/ip6.h \
-		  netinet/tcp.h netinet/udp.h netinet/ip_icmp.h \
-		  stddef.h stdint.h stdlib.h string.h unistd.h], ,
-		 AC_MSG_ERROR([Header file not found]))
-
-# Checks for typedefs, structures, and compiler characteristics.
-AC_HEADER_STDBOOL
-AC_C_CONST
-AC_C_INLINE
-AC_TYPE_OFF_T
-AC_TYPE_SIZE_T
-AC_TYPE_UID_T
-AC_TYPE_INT8_T
-AC_TYPE_INT16_T
-AC_TYPE_INT32_T
-AC_TYPE_INT64_T
-AC_TYPE_UINT8_T
-AC_TYPE_UINT16_T
-AC_TYPE_UINT32_T
-AC_TYPE_UINT64_T
-
-# Checks for library functions.
-AC_FUNC_MALLOC
-AC_FUNC_REALLOC
-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_OUTPUT
-- 
1.8.2


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

* [PATCH 2/3] build: rename conflicting parser.h instances
  2013-10-20 14:48 nftables: use automake & pkgconfig Jan Engelhardt
  2013-10-20 14:48 ` [PATCH 1/3] build: remove unused checks Jan Engelhardt
@ 2013-10-20 14:48 ` Jan Engelhardt
  2013-11-19 20:25   ` Pablo Neira Ayuso
  2013-10-20 14:48 ` [PATCH 3/3] build: use automake and pkgconfig Jan Engelhardt
  2013-11-17 20:39 ` nftables: use automake & pkgconfig Jan Engelhardt
  3 siblings, 1 reply; 17+ messages in thread
From: Jan Engelhardt @ 2013-10-20 14:48 UTC (permalink / raw)
  To: netfilter-devel; +Cc: pablo

If -I. is on the command line, #include <parser.h> becomes ./parser.h
instead of ../include/parser.h.

Signed-off-by: Jan Engelhardt <jengelh@inai.de>
---
 src/.gitignore    |    4 +-
 src/Makefile.in   |    4 +-
 src/parser.y      | 1752 -----------------------------------------------------
 src/parser_impl.y | 1752 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/scanner.l     |    2 +-
 5 files changed, 1757 insertions(+), 1757 deletions(-)
 delete mode 100644 src/parser.y
 create mode 100644 src/parser_impl.y

diff --git a/src/.gitignore b/src/.gitignore
index 23e6ae0..c695c15 100644
--- a/src/.gitignore
+++ b/src/.gitignore
@@ -1,5 +1,5 @@
-parser.c
-parser.h
+/parser_impl.c
+/parser_impl.h
 scanner.c
 scanner.h
 nft
diff --git a/src/Makefile.in b/src/Makefile.in
index 658e9b3..7e5c9c4 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -23,8 +23,8 @@ 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			+= parser_impl.o
+nft-extra-clean-files	+= parser_impl.c parser_impl.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 074f075..0000000
--- a/src/parser.y
+++ /dev/null
@@ -1,1752 +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 <linux/netfilter.h>
-#include <linux/netfilter/nf_tables.h>
-#include <linux/netfilter/nf_conntrack_tuple_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);
-	state->msgs = msgs;
-	state->scopes[0] = scope_init(&state->top_scope, NULL);
-}
-
-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)
-{
-	scope_init(scope, current_scope(state));
-	state->scopes[++state->scope] = scope;
-}
-
-static void close_scope(struct parser_state *state)
-{
-	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)
-
-%}
-
-/* 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 ARROW			"=>"
-%token VMAP			"vmap"
-
-%token INCLUDE			"include"
-%token DEFINE			"define"
-
-%token HOOK			"hook"
-%token TABLE			"table"
-%token TABLES			"tables"
-%token CHAIN			"chain"
-%token RULE			"rule"
-%token SETS			"sets"
-%token SET			"set"
-%token ELEMENT			"element"
-%token MAP			"map"
-%token HANDLE			"handle"
-
-%token ADD			"add"
-%token INSERT			"insert"
-%token DELETE			"delete"
-%token LIST			"list"
-%token FLUSH			"flush"
-%token RENAME			"rename"
-%token DESCRIBE			"describe"
-
-%token ACCEPT			"accept"
-%token DROP			"drop"
-%token CONTINUE			"continue"
-%token JUMP			"jump"
-%token GOTO			"goto"
-%token RETURN			"return"
-%token QUEUE			"queue"
-
-%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 ETH			"eth"
-%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 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 SECMARK			"secmark"
-
-%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 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 POSITION			"position"
-
-%type <string>			identifier string
-%destructor { xfree($$); }	identifier string
-
-%type <cmd>			line
-%destructor { cmd_free($$); }	line
-
-%type <cmd>			base_cmd add_cmd insert_cmd delete_cmd list_cmd flush_cmd rename_cmd
-%destructor { cmd_free($$); }	base_cmd add_cmd insert_cmd delete_cmd list_cmd flush_cmd rename_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 { table_free($$); }	table_block_alloc
-%type <chain>			chain_block_alloc chain_block
-%destructor { chain_free($$); }	chain_block_alloc
-%type <rule>			rule
-%destructor { rule_free($$); }	rule
-
-%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>			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 <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_expr
-%destructor { expr_free($$); }	verdict_map_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
-
-%type <expr>			ct_expr
-%destructor { expr_free($$); }	ct_expr
-%type <val>			ct_key
-
-%%
-
-input			:	/* empty */
-			|	input		line
-			{
-				if ($2 != NULL) {
-					$2->location = @2;
-					list_add_tail(&$2->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
-			{
-				symbol_bind(current_scope(state), $2, $4);
-				xfree($2);
-			}
-			;
-
-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) {
-					$1->location = @1;
-					list_add_tail(&$1->list, &state->cmds);
-				}
-				$$ = NULL;
-
-				YYACCEPT;
-			}
-			|	base_cmd	error		{ $$ = $1; }
-			;
-
-base_cmd		:	/* empty */	add_cmd		{ $$ = $1; }
-	  		|	ADD		add_cmd		{ $$ = $2; }
-			|	INSERT		insert_cmd	{ $$ = $2; }
-			|	DELETE		delete_cmd	{ $$ = $2; }
-			|	LIST		list_cmd	{ $$ = $2; }
-			|	FLUSH		flush_cmd	{ $$ = $2; }
-			|	RENAME		rename_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);
-			}
-			;
-
-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);
-			}
-			|	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		table_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;
-			}
-			;
-
-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;
-			}
-			;
-
-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	ARROW	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;
-			}
-			;
-
-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; }
-			|	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;
-			}
-			;
-
-rule			:	stmt_list
-			{
-				struct stmt *i;
-
-				$$ = rule_alloc(&@$, NULL);
-				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
-			;
-
-verdict_stmt		:	verdict_expr
-			{
-				$$ = verdict_stmt_alloc(&@$, $1);
-			}
-			|	verdict_map_expr
-			{
-				$$ = verdict_stmt_alloc(&@$, $1);
-			}
-			;
-
-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		:	NANOSECOND	{ $$ = 1ULL; }
-			|	MICROSECOND	{ $$ = 1ULL * 1000; }
-			|	MILLISECOND	{ $$ = 1ULL * 1000 * 1000; }
-			|	SECOND		{ $$ = 1ULL * 1000 * 1000 * 1000; }
-			|	MINUTE		{ $$ = 1ULL * 1000 * 1000 * 1000 * 60; }
-			|	HOUR		{ $$ = 1ULL * 1000 * 1000 * 1000 * 60 * 60; }
-			|	DAY		{ $$ = 1ULL * 1000 * 1000 * 1000 * 60 * 60 * 24; }
-			|	WEEK		{ $$ = 1ULL * 1000 * 1000 * 1000 * 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;
-			}
-			;
-
-match_stmt		:	relational_expr
-			{
-				$$ = expr_stmt_alloc(&@$, $1);
-			}
-			;
-
-symbol_expr		:	string
-			{
-				$$ = symbol_expr_alloc(&@$, SYMBOL_VALUE,
-						       current_scope(state),
-						       $1);
-				xfree($1);
-			}
-			|	'$'	identifier
-			{
-				$$ = symbol_expr_alloc(&@$, SYMBOL_DEFINE,
-						       current_scope(state),
-						       $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);
-			}
-			;
-
-verdict_map_expr	:	concat_expr	VMAP	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	ARROW	concat_expr	opt_newline
-			{
-				$$ = mapping_expr_alloc(&@$, $2, $4);
-			}
-			|	opt_newline	map_lhs_expr	ARROW	verdict_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);
-			}
-			|	QUEUE
-			{
-				$$ = verdict_expr_alloc(&@$, NF_QUEUE, 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		:	LENGTH		{ $$ = NFT_META_LEN; }
-			|	PROTOCOL	{ $$ = NFT_META_PROTOCOL; }
-			|	PRIORITY	{ $$ = NFT_META_PRIORITY; }
-			|	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; }
-			|	SECMARK		{ $$ = NFT_META_SECMARK; }
-			;
-
-meta_stmt		:	META	meta_key	SET	expr
-			{
-				$$ = meta_stmt_alloc(&@$, $2, $4);
-			}
-			;
-
-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; }
-			|	SECMARK		{ $$ = NFT_CT_SECMARK; }
-			|	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; }
-			;
-
-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		{ $$ = PAYLOAD_BASE_LL_HDR; }
-			|	NETWORK_HDR	{ $$ = PAYLOAD_BASE_NETWORK_HDR; }
-			|	TRANSPORT_HDR	{ $$ = PAYLOAD_BASE_TRANSPORT_HDR; }
-			;
-
-eth_hdr_expr		:	ETH	eth_hdr_field
-			{
-				$$ = payload_expr_alloc(&@$, &payload_eth, $2);
-			}
-			;
-
-eth_hdr_field		:	SADDR		{ $$ = ETHHDR_SADDR; }
-			|	DADDR		{ $$ = ETHHDR_DADDR; }
-			|	TYPE		{ $$ = ETHHDR_TYPE; }
-			;
-
-vlan_hdr_expr		:	VLAN	vlan_hdr_field
-			{
-				$$ = payload_expr_alloc(&@$, &payload_vlan, $2);
-			}
-			;
-
-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(&@$, &payload_arp, $2);
-			}
-			;
-
-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(&@$, &payload_ip, $2);
-			}
-			;
-
-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(&@$, &payload_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(&@$, &payload_ip6, $2);
-			}
-			;
-
-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(&@$, &payload_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(&@$, &payload_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(&@$, &payload_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(&@$, &payload_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(&@$, &payload_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(&@$, &payload_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(&@$, &payload_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(&@$, &payload_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(&@$, &payload_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; }
-			;
-
-%%
diff --git a/src/parser_impl.y b/src/parser_impl.y
new file mode 100644
index 0000000..92ed3c6
--- /dev/null
+++ b/src/parser_impl.y
@@ -0,0 +1,1752 @@
+/*
+ * 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 <linux/netfilter.h>
+#include <linux/netfilter/nf_tables.h>
+#include <linux/netfilter/nf_conntrack_tuple_common.h>
+
+#include <rule.h>
+#include <statement.h>
+#include <expression.h>
+#include <utils.h>
+#include <parser.h>
+#include <erec.h>
+
+#include "parser_impl.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);
+	state->msgs = msgs;
+	state->scopes[0] = scope_init(&state->top_scope, NULL);
+}
+
+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)
+{
+	scope_init(scope, current_scope(state));
+	state->scopes[++state->scope] = scope;
+}
+
+static void close_scope(struct parser_state *state)
+{
+	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)
+
+%}
+
+/* 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 ARROW			"=>"
+%token VMAP			"vmap"
+
+%token INCLUDE			"include"
+%token DEFINE			"define"
+
+%token HOOK			"hook"
+%token TABLE			"table"
+%token TABLES			"tables"
+%token CHAIN			"chain"
+%token RULE			"rule"
+%token SETS			"sets"
+%token SET			"set"
+%token ELEMENT			"element"
+%token MAP			"map"
+%token HANDLE			"handle"
+
+%token ADD			"add"
+%token INSERT			"insert"
+%token DELETE			"delete"
+%token LIST			"list"
+%token FLUSH			"flush"
+%token RENAME			"rename"
+%token DESCRIBE			"describe"
+
+%token ACCEPT			"accept"
+%token DROP			"drop"
+%token CONTINUE			"continue"
+%token JUMP			"jump"
+%token GOTO			"goto"
+%token RETURN			"return"
+%token QUEUE			"queue"
+
+%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 ETH			"eth"
+%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 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 SECMARK			"secmark"
+
+%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 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 POSITION			"position"
+
+%type <string>			identifier string
+%destructor { xfree($$); }	identifier string
+
+%type <cmd>			line
+%destructor { cmd_free($$); }	line
+
+%type <cmd>			base_cmd add_cmd insert_cmd delete_cmd list_cmd flush_cmd rename_cmd
+%destructor { cmd_free($$); }	base_cmd add_cmd insert_cmd delete_cmd list_cmd flush_cmd rename_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 { table_free($$); }	table_block_alloc
+%type <chain>			chain_block_alloc chain_block
+%destructor { chain_free($$); }	chain_block_alloc
+%type <rule>			rule
+%destructor { rule_free($$); }	rule
+
+%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>			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 <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_expr
+%destructor { expr_free($$); }	verdict_map_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
+
+%type <expr>			ct_expr
+%destructor { expr_free($$); }	ct_expr
+%type <val>			ct_key
+
+%%
+
+input			:	/* empty */
+			|	input		line
+			{
+				if ($2 != NULL) {
+					$2->location = @2;
+					list_add_tail(&$2->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
+			{
+				symbol_bind(current_scope(state), $2, $4);
+				xfree($2);
+			}
+			;
+
+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) {
+					$1->location = @1;
+					list_add_tail(&$1->list, &state->cmds);
+				}
+				$$ = NULL;
+
+				YYACCEPT;
+			}
+			|	base_cmd	error		{ $$ = $1; }
+			;
+
+base_cmd		:	/* empty */	add_cmd		{ $$ = $1; }
+	  		|	ADD		add_cmd		{ $$ = $2; }
+			|	INSERT		insert_cmd	{ $$ = $2; }
+			|	DELETE		delete_cmd	{ $$ = $2; }
+			|	LIST		list_cmd	{ $$ = $2; }
+			|	FLUSH		flush_cmd	{ $$ = $2; }
+			|	RENAME		rename_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);
+			}
+			;
+
+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);
+			}
+			|	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		table_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;
+			}
+			;
+
+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;
+			}
+			;
+
+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	ARROW	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;
+			}
+			;
+
+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; }
+			|	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;
+			}
+			;
+
+rule			:	stmt_list
+			{
+				struct stmt *i;
+
+				$$ = rule_alloc(&@$, NULL);
+				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
+			;
+
+verdict_stmt		:	verdict_expr
+			{
+				$$ = verdict_stmt_alloc(&@$, $1);
+			}
+			|	verdict_map_expr
+			{
+				$$ = verdict_stmt_alloc(&@$, $1);
+			}
+			;
+
+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		:	NANOSECOND	{ $$ = 1ULL; }
+			|	MICROSECOND	{ $$ = 1ULL * 1000; }
+			|	MILLISECOND	{ $$ = 1ULL * 1000 * 1000; }
+			|	SECOND		{ $$ = 1ULL * 1000 * 1000 * 1000; }
+			|	MINUTE		{ $$ = 1ULL * 1000 * 1000 * 1000 * 60; }
+			|	HOUR		{ $$ = 1ULL * 1000 * 1000 * 1000 * 60 * 60; }
+			|	DAY		{ $$ = 1ULL * 1000 * 1000 * 1000 * 60 * 60 * 24; }
+			|	WEEK		{ $$ = 1ULL * 1000 * 1000 * 1000 * 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;
+			}
+			;
+
+match_stmt		:	relational_expr
+			{
+				$$ = expr_stmt_alloc(&@$, $1);
+			}
+			;
+
+symbol_expr		:	string
+			{
+				$$ = symbol_expr_alloc(&@$, SYMBOL_VALUE,
+						       current_scope(state),
+						       $1);
+				xfree($1);
+			}
+			|	'$'	identifier
+			{
+				$$ = symbol_expr_alloc(&@$, SYMBOL_DEFINE,
+						       current_scope(state),
+						       $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);
+			}
+			;
+
+verdict_map_expr	:	concat_expr	VMAP	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	ARROW	concat_expr	opt_newline
+			{
+				$$ = mapping_expr_alloc(&@$, $2, $4);
+			}
+			|	opt_newline	map_lhs_expr	ARROW	verdict_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);
+			}
+			|	QUEUE
+			{
+				$$ = verdict_expr_alloc(&@$, NF_QUEUE, 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		:	LENGTH		{ $$ = NFT_META_LEN; }
+			|	PROTOCOL	{ $$ = NFT_META_PROTOCOL; }
+			|	PRIORITY	{ $$ = NFT_META_PRIORITY; }
+			|	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; }
+			|	SECMARK		{ $$ = NFT_META_SECMARK; }
+			;
+
+meta_stmt		:	META	meta_key	SET	expr
+			{
+				$$ = meta_stmt_alloc(&@$, $2, $4);
+			}
+			;
+
+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; }
+			|	SECMARK		{ $$ = NFT_CT_SECMARK; }
+			|	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; }
+			;
+
+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		{ $$ = PAYLOAD_BASE_LL_HDR; }
+			|	NETWORK_HDR	{ $$ = PAYLOAD_BASE_NETWORK_HDR; }
+			|	TRANSPORT_HDR	{ $$ = PAYLOAD_BASE_TRANSPORT_HDR; }
+			;
+
+eth_hdr_expr		:	ETH	eth_hdr_field
+			{
+				$$ = payload_expr_alloc(&@$, &payload_eth, $2);
+			}
+			;
+
+eth_hdr_field		:	SADDR		{ $$ = ETHHDR_SADDR; }
+			|	DADDR		{ $$ = ETHHDR_DADDR; }
+			|	TYPE		{ $$ = ETHHDR_TYPE; }
+			;
+
+vlan_hdr_expr		:	VLAN	vlan_hdr_field
+			{
+				$$ = payload_expr_alloc(&@$, &payload_vlan, $2);
+			}
+			;
+
+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(&@$, &payload_arp, $2);
+			}
+			;
+
+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(&@$, &payload_ip, $2);
+			}
+			;
+
+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(&@$, &payload_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(&@$, &payload_ip6, $2);
+			}
+			;
+
+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(&@$, &payload_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(&@$, &payload_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(&@$, &payload_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(&@$, &payload_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(&@$, &payload_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(&@$, &payload_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(&@$, &payload_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(&@$, &payload_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(&@$, &payload_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; }
+			;
+
+%%
diff --git a/src/scanner.l b/src/scanner.l
index cee6aa6..b7b25cd 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 "parser_impl.h"
 
 #define YY_NO_INPUT
 
-- 
1.8.2


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

* [PATCH 3/3] build: use automake and pkgconfig
  2013-10-20 14:48 nftables: use automake & pkgconfig Jan Engelhardt
  2013-10-20 14:48 ` [PATCH 1/3] build: remove unused checks Jan Engelhardt
  2013-10-20 14:48 ` [PATCH 2/3] build: rename conflicting parser.h instances Jan Engelhardt
@ 2013-10-20 14:48 ` Jan Engelhardt
  2013-11-19 20:28   ` Pablo Neira Ayuso
  2013-11-17 20:39 ` nftables: use automake & pkgconfig Jan Engelhardt
  3 siblings, 1 reply; 17+ messages in thread
From: Jan Engelhardt @ 2013-10-20 14:48 UTC (permalink / raw)
  To: netfilter-devel; +Cc: pablo

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset=UTF-8, Size: 20519 bytes --]

This now also honors the cflags as obtained from pkgconfig, otherwise
one gets a compile error if the headers are in a location other than
/usr/include.

Signed-off-by: Jan Engelhardt <jengelh@inai.de>
---
 .gitignore        |  17 ++--
 Makefile.am       |   7 ++
 Makefile.defs.in  |  40 --------
 Makefile.in       |   5 -
 Makefile.rules.in |  89 ------------------
 configure.ac      |  41 +++++----
 doc/Makefile.am   |  14 +++
 doc/Makefile.in   |  20 ----
 files/Makefile.am |   6 ++
 files/Makefile.in |   4 -
 install-sh        | 269 ------------------------------------------------------
 src/Makefile.am   |  24 +++++
 src/Makefile.in   |  30 ------
 src/cli.c         |   1 +
 src/erec.c        |   1 +
 src/main.c        |   1 +
 16 files changed, 87 insertions(+), 482 deletions(-)
 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 doc/Makefile.am
 delete mode 100644 doc/Makefile.in
 create mode 100644 files/Makefile.am
 delete mode 100644 files/Makefile.in
 delete mode 100755 install-sh
 create mode 100644 src/Makefile.am
 delete mode 100644 src/Makefile.in

diff --git a/.gitignore b/.gitignore
index d26b395..a54c6ae 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,18 +1,19 @@
 # Dependency and object files
-.*.d
+.deps/
+.libs/
 *.o
 
 # Generated by autoconf/configure
 Makefile
+Makefile.in
 Makefile.defs
 Makefile.rules
-config.h
-config.h.in
-config.h.in~
-config.log
-config.status
-configure
-autom4te.cache
+/aclocal.m4
+/autom4te.cache/
+/build-aux/
+/config.*
+/configure
+/stamp-h1
 
 # Debian package build temporary files
 build-stamp
diff --git a/Makefile.am b/Makefile.am
new file mode 100644
index 0000000..ad76c06
--- /dev/null
+++ b/Makefile.am
@@ -0,0 +1,7 @@
+# -*- Makefile -*-
+
+SUBDIRS = src files doc
+
+archive:
+	git archive --prefix=nftables-${PACKAGE_VERSION}/ HEAD | \
+		bzip2 -c > nftables-${PACKAGE_VERSION}.tar.bz2
diff --git a/Makefile.defs.in b/Makefile.defs.in
deleted file mode 100644
index 545c4ee..0000000
--- a/Makefile.defs.in
+++ /dev/null
@@ -1,40 +0,0 @@
-DEBUG		= @CONFIG_DEBUG@
-CC		= @CC@
-CPP		= @CPP@
-LEX		= @LEX@
-YACC		= @YACC@
-MKDIR_P		= @MKDIR_P@
-INSTALL		= @INSTALL@
-
-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 -Werror
-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 a93a26b..0000000
--- a/Makefile.rules.in
+++ /dev/null
@@ -1,89 +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) -d -o $@ $<
-
-%.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); docbook2x-man ../$<)
-
-%.pdf:			%.xml	$(makedeps)
-			@echo -e "  PDF\t\t$@"
-			db2pdf -o $(SUBDIR) $<
-
-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 -o root -g root \
-				$(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/configure.ac b/configure.ac
index b850451..1d0dc58 100644
--- a/configure.ac
+++ b/configure.ac
@@ -7,8 +7,10 @@ AC_COPYRIGHT([Copyright (c) 2008 Patrick McHardy <kaber@trash.net>])
 AC_INIT([nftables], [0.01-alpha1], [netfilter-devel@vger.kernel.org])
 AC_DEFINE([RELEASE_NAME], ["schäublefilter"], [Release name])
 
+AC_CONFIG_AUX_DIR([build-aux])
 AC_CONFIG_SRCDIR([src/rule.c])
 AC_CONFIG_HEADER([config.h])
+AM_INIT_AUTOMAKE([-Wall foreign subdir-objects tar-pax no-dist-gzip dist-xz])
 
 AC_DEFINE([_GNU_SOURCE], [], [Enable various GNU extensions])
 AC_DEFINE([_STDC_FORMAT_MACROS], [], [printf-style format macros])
@@ -24,35 +26,25 @@ AC_PROG_CC
 AC_PROG_INSTALL
 
 AC_CHECK_PROG(CONFIG_MAN, docbook2x-man, y, n)
+AM_CONDITIONAL([CONFIG_MAN], [test "$CONFIG_MAN" = y])
 if test "$CONFIG_MAN" != "y"
 then
 	AC_MSG_WARN([docbookx2-man not found, no manpages will be built])
 fi
 
 AC_CHECK_PROG(CONFIG_PDF, db2pdf, y, n)
+AM_CONDITIONAL([CONFIG_PDF], [test "$CONFIG_PDF" = y])
 if test "$CONFIG_PDF" != "y"
 then
 	AC_MSG_WARN([db2pdf 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
+AC_PROG_YACC
+AC_PROG_LEX
 
 # Checks for libraries.
-AC_CHECK_LIB([mnl], [mnl_socket_open], ,
-	     AC_MSG_ERROR([No suitable version of libmnl found]))
-
-AC_CHECK_LIB([nftables], [nft_rule_alloc], ,
-	     AC_MSG_ERROR([No suitable version of libnftables found]))
+PKG_CHECK_MODULES([libmnl], [libmnl])
+PKG_CHECK_MODULES([libnft], [libnftables])
 
 AC_CHECK_LIB([gmp], [__gmpz_init], ,
 	     AC_MSG_ERROR([No suitable version of libgmp found]))
@@ -60,6 +52,21 @@ AC_CHECK_LIB([gmp], [__gmpz_init], ,
 AC_CHECK_LIB([readline], [readline], ,
 	     AC_MSG_ERROR([No suitable version of libreadline found]))
 
-AC_CONFIG_FILES([Makefile Makefile.defs Makefile.rules])
+my_CPPFLAGS=""
+my_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"
+#-Wshadow
+if test "$CONFIG_DEBUG" = y; then
+	my_CFLAGS="$my_CFLAGS -O0 -ggdb3"
+	my_CPPFLAGS="$my_CPPFLAGS -DDEBUG"
+fi
+AC_SUBST([my_CPPFLAGS])
+AC_SUBST([my_CFLAGS])
+
+AC_CONFIG_FILES([Makefile])
 AC_CONFIG_FILES([src/Makefile doc/Makefile files/Makefile])
 AC_OUTPUT
diff --git a/doc/Makefile.am b/doc/Makefile.am
new file mode 100644
index 0000000..77ef71e
--- /dev/null
+++ b/doc/Makefile.am
@@ -0,0 +1,14 @@
+# -*- Makefile -*-
+
+if CONFIG_MAN
+man_MANS = nftables.8
+endif
+if CONFIG_PDF
+doc_DATA = nftables.pdf
+endif
+
+.xml.8:
+	docbook2x-man $<
+
+.xml.pdf:
+	db2pdf $<
diff --git a/doc/Makefile.in b/doc/Makefile.in
deleted file mode 100644
index 2c42d7e..0000000
--- a/doc/Makefile.in
+++ /dev/null
@@ -1,20 +0,0 @@
-mandocs-@CONFIG_MAN@	+= doc/nftables.8
-pdfdocs-@CONFIG_PDF@	+= doc/nftables.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 -o root -g root $(mandocs-y) \
-					$(DESTDIR)/${mandir}/man8/ ;\
-		fi
-		if test -n "$(pdfdocs-y)"; then \
-			$(MKDIR_P) $(DESTDIR)/${pdfdir} ;\
-			$(INSTALL) -m 755 -o root -g root $(pdfdocs-y) \
-					$(DESTDIR)/${pdfdir}/ ;\
-		fi
diff --git a/files/Makefile.am b/files/Makefile.am
new file mode 100644
index 0000000..9c001af
--- /dev/null
+++ b/files/Makefile.am
@@ -0,0 +1,6 @@
+# -*- Makefile -*-
+
+pkgsysconfdir = ${sysconfdir}/nftables
+pkgsysconf_DATA = nftables/bridge-filter nftables/ipv4-filter \
+	nftables/ipv4-mangle nftables/ipv4-nat nftables/ipv6-filter \
+	nftables/ipv6-mangle nftables/ipv6-nat
diff --git a/files/Makefile.in b/files/Makefile.in
deleted file mode 100644
index cd67c37..0000000
--- a/files/Makefile.in
+++ /dev/null
@@ -1,4 +0,0 @@
-install:
-	@echo -e "  INSTALL\tfiles"
-	$(MKDIR_P) $(DESTDIR)/$(confdir)
-	$(INSTALL) -m 755 -o root -g root $(SUBDIR)nftables/* $(DESTDIR)/$(confdir)/
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
diff --git a/src/Makefile.am b/src/Makefile.am
new file mode 100644
index 0000000..352e24f
--- /dev/null
+++ b/src/Makefile.am
@@ -0,0 +1,24 @@
+# -*- Makefile -*-
+
+AM_CPPFLAGS = ${libmnl_CFLAGS} ${libnft_CFLAGS} -I${top_srcdir}/include \
+	-DDEFAULT_INCLUDE_PATH=\"${sysconfdir}/nftables\" ${my_CPPFLAGS}
+AM_CFLAGS   = ${my_CFLAGS}
+AM_YFLAGS   = -d
+
+sbin_PROGRAMS = nft
+
+nft_SOURCES = \
+	main.c cli.c rule.c statement.c datatype.c expression.c evaluate.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 parser_impl.y scanner.l
+nft_LDADD = ${libmnl_LIBS} ${libnft_LIBS}
+
+parser_impl.${OBJEXT}: scanner.c
+
+scanner.h: scanner.c
+scanner.c: scanner.l
+	${AM_V_LEX}${LEX} -t --header-file=$(<:.l=.h) $< >$@
+
+LEX_OUTPUT_ROOT = lex.nft_
+CLEANFILES = parser_impl.c parser_impl.h scanner.c scanner.h
diff --git a/src/Makefile.in b/src/Makefile.in
deleted file mode 100644
index 7e5c9c4..0000000
--- a/src/Makefile.in
+++ /dev/null
@@ -1,30 +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			+= 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_impl.o
-nft-extra-clean-files	+= parser_impl.c parser_impl.h
-
-nft-obj			+= scanner.o
-nft-extra-clean-files	+= scanner.c scanner.h
diff --git a/src/cli.c b/src/cli.c
index 8875207..43ae8ce 100644
--- a/src/cli.c
+++ b/src/cli.c
@@ -12,6 +12,7 @@
  * Development of this code funded by Astaro AG (http://www.astaro.com/)
  */
 
+#define _GNU_SOURCE 1
 #include <stdlib.h>
 #include <stdio.h>
 #include <stdarg.h>
diff --git a/src/erec.c b/src/erec.c
index 7451d94..8247b94 100644
--- a/src/erec.c
+++ b/src/erec.c
@@ -8,6 +8,7 @@
  * Development of this code funded by Astaro AG (http://www.astaro.com/)
  */
 
+#define _GNU_SOURCE 1
 #include <stdio.h>
 #include <string.h>
 #include <stdarg.h>
diff --git a/src/main.c b/src/main.c
index 0c97120..a132f82 100644
--- a/src/main.c
+++ b/src/main.c
@@ -8,6 +8,7 @@
  * Development of this code funded by Astaro AG (http://www.astaro.com/)
  */
 
+#include "config.h"
 #include <stdlib.h>
 #include <stddef.h>
 #include <unistd.h>
-- 
1.8.2

--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* Re: nftables: use automake & pkgconfig
  2013-10-20 14:48 nftables: use automake & pkgconfig Jan Engelhardt
                   ` (2 preceding siblings ...)
  2013-10-20 14:48 ` [PATCH 3/3] build: use automake and pkgconfig Jan Engelhardt
@ 2013-11-17 20:39 ` Jan Engelhardt
  3 siblings, 0 replies; 17+ messages in thread
From: Jan Engelhardt @ 2013-11-17 20:39 UTC (permalink / raw)
  To: Pablo Neira Ayuso; +Cc: Netfilter Developer Mailing List


On Sunday 2013-10-20 16:48, Jan Engelhardt wrote:
>are available in the git repository at:
>
>  git://git.inai.de/nftables master
>
>for you to fetch changes up to af2a890f6fa39d09240b85811a430b51b88a866e:
>Jan Engelhardt (3):
>      build: remove unused checks
>      build: rename conflicting parser.h instances
>      build: use automake and pkgconfig

Any verdict on these?

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

* Re: [PATCH 1/3] build: remove unused checks
  2013-10-20 14:48 ` [PATCH 1/3] build: remove unused checks Jan Engelhardt
@ 2013-11-19 20:24   ` Pablo Neira Ayuso
  0 siblings, 0 replies; 17+ messages in thread
From: Pablo Neira Ayuso @ 2013-11-19 20:24 UTC (permalink / raw)
  To: Jan Engelhardt; +Cc: netfilter-devel

On Sun, Oct 20, 2013 at 04:48:09PM +0200, Jan Engelhardt wrote:
> The result of these checks was never evaluated, so remove them.
> 
> Signed-off-by: Jan Engelhardt <jengelh@inai.de>
> ---
>  configure.ac | 31 -------------------------------
>  1 file changed, 31 deletions(-)
> 
> diff --git a/configure.ac b/configure.ac
> index 811d7e2..b850451 100644
> --- a/configure.ac
> +++ b/configure.ac
> @@ -21,7 +21,6 @@ AC_SUBST([CONFIG_DEBUG])
>  
>  # Checks for programs.
>  AC_PROG_CC
> -AC_PROG_MKDIR_P
>  AC_PROG_INSTALL
>  
>  AC_CHECK_PROG(CONFIG_MAN, docbook2x-man, y, n)
> @@ -61,36 +60,6 @@ AC_CHECK_LIB([gmp], [__gmpz_init], ,
>  AC_CHECK_LIB([readline], [readline], ,
>  	     AC_MSG_ERROR([No suitable version of libreadline found]))
>  
> -# Checks for header files.
> -AC_HEADER_STDC
> -AC_HEADER_ASSERT
> -AC_CHECK_HEADERS([arpa/inet.h fcntl.h inttypes.h libintl.h limits.h malloc.h \
> -		  netdb.h netinet/in.h netinet/ip.h netinet/ip6.h \
> -		  netinet/tcp.h netinet/udp.h netinet/ip_icmp.h \
> -		  stddef.h stdint.h stdlib.h string.h unistd.h], ,
> -		 AC_MSG_ERROR([Header file not found]))
> -# Checks for typedefs, structures, and compiler characteristics.
> -AC_HEADER_STDBOOL
> -AC_C_CONST
> -AC_C_INLINE
> -AC_TYPE_OFF_T
> -AC_TYPE_SIZE_T
> -AC_TYPE_UID_T
> -AC_TYPE_INT8_T
> -AC_TYPE_INT16_T
> -AC_TYPE_INT32_T
> -AC_TYPE_INT64_T
> -AC_TYPE_UINT8_T
> -AC_TYPE_UINT16_T
> -AC_TYPE_UINT32_T
> -AC_TYPE_UINT64_T
> -# Checks for library functions.
> -AC_FUNC_MALLOC
> -AC_FUNC_REALLOC
>
> -AC_CHECK_FUNCS([memmove memset strchr strdup strerror strtoull])
> -

These still generate information that is included in the config.log. I
don't want to get rid of this at this stage.

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

* Re: [PATCH 2/3] build: rename conflicting parser.h instances
  2013-10-20 14:48 ` [PATCH 2/3] build: rename conflicting parser.h instances Jan Engelhardt
@ 2013-11-19 20:25   ` Pablo Neira Ayuso
  2013-11-20  9:06     ` Jan Engelhardt
  0 siblings, 1 reply; 17+ messages in thread
From: Pablo Neira Ayuso @ 2013-11-19 20:25 UTC (permalink / raw)
  To: Jan Engelhardt; +Cc: netfilter-devel

On Sun, Oct 20, 2013 at 04:48:10PM +0200, Jan Engelhardt wrote:
> If -I. is on the command line, #include <parser.h> becomes ./parser.h
> instead of ../include/parser.h.

What use case are you trying to handle with this?

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

* Re: [PATCH 3/3] build: use automake and pkgconfig
  2013-10-20 14:48 ` [PATCH 3/3] build: use automake and pkgconfig Jan Engelhardt
@ 2013-11-19 20:28   ` Pablo Neira Ayuso
  2013-11-20 10:54     ` Jan Engelhardt
  0 siblings, 1 reply; 17+ messages in thread
From: Pablo Neira Ayuso @ 2013-11-19 20:28 UTC (permalink / raw)
  To: Jan Engelhardt; +Cc: netfilter-devel

On Sun, Oct 20, 2013 at 04:48:11PM +0200, Jan Engelhardt wrote:
> This now also honors the cflags as obtained from pkgconfig, otherwise
> one gets a compile error if the headers are in a location other than
> /usr/include.

I don't want to consider changing the build system at this stage.

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

* Re: [PATCH 2/3] build: rename conflicting parser.h instances
  2013-11-19 20:25   ` Pablo Neira Ayuso
@ 2013-11-20  9:06     ` Jan Engelhardt
  2013-11-20 14:02       ` Pablo Neira Ayuso
  0 siblings, 1 reply; 17+ messages in thread
From: Jan Engelhardt @ 2013-11-20  9:06 UTC (permalink / raw)
  To: Pablo Neira Ayuso; +Cc: netfilter-devel

On Tuesday 2013-11-19 21:25, Pablo Neira Ayuso wrote:

>On Sun, Oct 20, 2013 at 04:48:10PM +0200, Jan Engelhardt wrote:
>> If -I. is on the command line, #include <parser.h> becomes ./parser.h
>> instead of ../include/parser.h.
>
>What use case are you trying to handle with this?
>
automake adds -I${builddir} -I${srcdir} and -I{dir with config.h} to the 
command line. Because both ${builddir} and -I${top_srcdir}/include 
(which is also being passed, this time by Makefile.am), #include 
<parser.h> becomes sort of ambiguous (the compiler knows which one to 
pick, but it's not the one to success).

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

* Re: [PATCH 3/3] build: use automake and pkgconfig
  2013-11-19 20:28   ` Pablo Neira Ayuso
@ 2013-11-20 10:54     ` Jan Engelhardt
  2013-11-20 11:11       ` Tomasz Bursztyka
  2013-11-20 14:06       ` Pablo Neira Ayuso
  0 siblings, 2 replies; 17+ messages in thread
From: Jan Engelhardt @ 2013-11-20 10:54 UTC (permalink / raw)
  To: Pablo Neira Ayuso; +Cc: netfilter-devel

On Tuesday 2013-11-19 21:28, Pablo Neira Ayuso wrote:

>On Sun, Oct 20, 2013 at 04:48:11PM +0200, Jan Engelhardt wrote:
>> This now also honors the cflags as obtained from pkgconfig, otherwise
>> one gets a compile error if the headers are in a location other than
>> /usr/include.
>
>I don't want to consider changing the build system at this stage.

At this stage, the build is rather broken, for cases that are not
even far-fetched.



10:08 ares07:../nftables/obj > ../configure
[...]
configure: creating ./config.status
config.status: creating Makefile
config.status: creating Makefile.defs
config.status: creating Makefile.rules
config.status: creating src/Makefile
config.status: creating doc/Makefile
config.status: creating files/Makefile
config.status: creating config.h
10:08 ares07:../nftables/obj > make -j8
  SUBDIR        src/
  SUBDIR        doc/
  SUBDIR        files/
make[1]: *** No rule to make target `src/main.o', needed by `src/nft'.  Stop.
make: *** [src] Error 2
make: *** Waiting for unfinished jobs....

	^ builddir!=srcdir not handled


10:09 ares07:../nftables/nftables > configure
[...]
10:09 ares07:../nftables/nftables > make -j8
  SUBDIR        src/
  SUBDIR        files/
  SUBDIR        doc/
  LEX           src/scanner.l
  YACC          src/parser.y
  DEP           src/mnl.c
  DEP           src/erec.c
src/mnl.c:11:27: fatal error: libmnl/libmnl.h: No such file or directory
 #include <libmnl/libmnl.h>

	^ pkgconfig files ignored


10:17 ares07:../nftables/nftables > make CPPFLAGS=/usr/include/pkg/libnftables
  SUBDIR        src/
  CC            src/main.c
In file included from src/main.c:25:0:
include/netlink.h:4:31: fatal error: libnftables/table.h: No such file or directory

	^ CPPFLAGS ignored


10:17 ares07:../nftables/nftables > make CPPFLAGS+=/usr/include/pkg/libnftables
  SUBDIR        src/
  CC            src/main.c
In file included from src/main.c:25:0:
include/netlink.h:4:31: fatal error: libnftables/table.h: No such file or directory

	^ so is the (unusual) approach of working around with +=


10:13 ares07:../nftables/nftables > make CFLAGS=-I/usr/include/pkg/libnftables
  SUBDIR        src/
  CC            src/main.c
src/main.c:21:22: fatal error: nftables.h: No such file or directory
 #include <nftables.h>

	^ CFLAGS ignored as well


10:15 ares07:../nftables/nftables > ./configure CFLAGS=-I/usr/include/pkg/libnftables
[...]
configure: creating ./config.status
config.status: creating Makefile
config.status: creating Makefile.defs
config.status: creating Makefile.rules
config.status: creating src/Makefile
config.status: creating doc/Makefile
config.status: creating files/Makefile
config.status: creating config.h
config.status: config.h is unchanged
10:15 ares07:../nftables/nftables > make
  SUBDIR        src/
  LEX           src/scanner.l
  DEP           src/scanner.c
In file included from src/scanner.l:21:0:
/usr/include/pkg/libnftables/rule.h:9:32: fatal error: libnftables/common.h: No such file or directory

	^ CFLAGS/CPPFLAGS specified at configure time are ignored as well


11:42 ares07:../nftables/nftables > make install DESTDIR=/tmp/foo
  SUBDIR        src/
  INSTALL       nft
/usr/bin/install: cannot change ownership of ‘/tmp/foo//usr/x86_64-suse-linux/sys-root/sbin/nft’: Operation not permitted
make[1]: *** [nft-install] Error 1
make: *** [src] Error 2

	^ install uses -o root -g root, which fails if you are not
	already root (in which case -o/-g is pointless, because install
	defaults to using root anyway)

	* There is no way to get a verbose build

	* Makefile runs a separate "DEPS" stage even though there is
	absolutely no need to

  CC            src/scanner.c
<stdout>: In function ‘nft_lex’:
<stdout>:1738:23: error: comparison between signed and unsigned integer expressions [-Werror=sign-compare]

I'll overlook -Werror for now…


	* Remake is oddly broken (compiler throws errors).
	(Patch 2 would probably fix that in the same go too.)
	This is especially nasty, because despite the gcc error given,
	the build completes.


$ make clean
  SUBDIR	src/
  CLEAN		nft
  SUBDIR	files/
  SUBDIR	doc/
  CLEAN		doc
$ make -j8
  SUBDIR	src/
  SUBDIR	doc/
  SUBDIR	files/
  LEX		src/scanner.l
  YACC		src/parser.y
  DEP		src/mnl.c
  DEP		src/erec.c
  DEP		src/utils.c
  DEP		src/gmputil.c
  DEP		src/rbtree.c
  DEP		src/segtree.c
  DEP		src/netlink_delinearize.c
  DEP		src/netlink_linearize.c
  DEP		src/netlink.c
  DEP		src/ct.c
  DEP		src/meta.c
  DEP		src/exthdr.c
  DEP		src/payload.c
  DEP		src/evaluate.c
  DEP		src/expression.c
  DEP		src/datatype.c
  DEP		src/statement.c
  DEP		src/rule.c
  DEP		src/cli.c
  DEP		src/main.c
  DEP		src/scanner.c
  DEP		src/parser.c
  LEX		src/scanner.l
  YACC		src/parser.y
  DEP		src/scanner.c
  DEP		src/parser.c
  CC		src/main.c
  CC		src/cli.c
  CC		src/rule.c
  CC		src/statement.c
  CC		src/datatype.c
  CC		src/expression.c
  CC		src/evaluate.c
  CC		src/payload.c
  CC		src/exthdr.c
  CC		src/meta.c
  CC		src/ct.c
  CC		src/netlink.c
  CC		src/netlink_linearize.c
  CC		src/netlink_delinearize.c
  CC		src/segtree.c
  CC		src/rbtree.c
  CC		src/gmputil.c
  CC		src/utils.c
  CC		src/erec.c
  CC		src/mnl.c
  CC		src/parser.c
  CC		src/scanner.c
<stdout>: In function ‘nft_lex’:
<stdout>:1738:23: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
<stdout>: In function ‘nft__scan_bytes’:
<stdout>:3583:17: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
  LD		src/nft
$ touch Makefile.rules
$ make -j1
  SUBDIR	src/
  LEX		src/scanner.l
  YACC		src/parser.y
src/parser.y: warning: conflicting outputs to file ‘src/parser.h’
  DEP		src/scanner.c
In file included from src/parser.y:28:0,
                 from src/parser.y:28,
                 from src/parser.y:28,
                 from src/parser.y:28, [repeated over 20 times]
                 from src/parser.y:28,
                 from src/scanner.l:23:
src/parser.y:13:20: error: #include nested too deeply
 #include <stddef.h>
                    ^
src/parser.y:14:19: error: #include nested too deeply
 #include <stdio.h>
                   ^
src/parser.y:15:22: error: #include nested too deeply
 #include <inttypes.h>
                      ^
src/parser.y:16:24: error: #include nested too deeply
 #include <netinet/ip.h>
                        ^
src/parser.y:17:29: error: #include nested too deeply
 #include <linux/netfilter.h>
                             ^
src/parser.y:18:39: error: #include nested too deeply
 #include <linux/netfilter/nf_tables.h>
                                       ^
src/parser.y:19:55: error: #include nested too deeply
 #include <linux/netfilter/nf_conntrack_tuple_common.h>
                                                       ^
src/parser.y:21:18: error: #include nested too deeply
 #include <rule.h>
                  ^
src/parser.y:22:23: error: #include nested too deeply
 #include <statement.h>
                       ^
src/parser.y:23:24: error: #include nested too deeply
 #include <expression.h>
                        ^
src/parser.y:24:19: error: #include nested too deeply
 #include <utils.h>
                   ^
src/parser.y:25:20: error: #include nested too deeply
 #include <parser.h>
                    ^
src/parser.y:26:18: error: #include nested too deeply
 #include <erec.h>
                  ^
src/parser.y:28:20: error: #include nested too deeply
 #include "parser.h"
                    ^
src/parser.y:29:21: error: #include nested too deeply
 #include "scanner.h"
                     ^
In file included from src/parser.y:28:0,
                 from src/parser.y:28,
                 from src/scanner.l:23:
src/parser.h:1673:56: error: #include nested too deeply
 #  include <stdio.h> /* INFRINGES ON USER NAME SPACE */
                                                        ^
In file included from src/parser.y:29:0,
                 from src/parser.y:28,
                 from src/scanner.l:23:
src/scanner.h:36:19: error: #include nested too deeply
 #include <stdio.h>
                   ^
src/scanner.h:37:20: error: #include nested too deeply
 #include <string.h>
                    ^
src/scanner.h:38:19: error: #include nested too deeply
 #include <errno.h>
                   ^
src/scanner.h:39:20: error: #include nested too deeply
 #include <stdlib.h>
                    ^
src/scanner.h:299:20: error: #include nested too deeply
 #include <unistd.h>
                    ^
  DEP		src/parser.c
In file included from src/parser.y:28:0,
                 from src/parser.y:28,
                 from src/parser.y:28:
src/parser.y:13:20: error: #include nested too deeply
 #include <stddef.h>
                    ^
src/parser.y:14:19: error: #include nested too deeply
 #include <stdio.h>
                   ^
src/parser.y:15:22: error: #include nested too deeply
 #include <inttypes.h>
                      ^
src/parser.y:16:24: error: #include nested too deeply
 #include <netinet/ip.h>
                        ^
src/parser.y:17:29: error: #include nested too deeply
 #include <linux/netfilter.h>
                             ^
src/parser.y:18:39: error: #include nested too deeply
 #include <linux/netfilter/nf_tables.h>
                                       ^
src/parser.y:19:55: error: #include nested too deeply
 #include <linux/netfilter/nf_conntrack_tuple_common.h>
                                                       ^
src/parser.y:21:18: error: #include nested too deeply
 #include <rule.h>
                  ^
src/parser.y:22:23: error: #include nested too deeply
 #include <statement.h>
                       ^
src/parser.y:23:24: error: #include nested too deeply
 #include <expression.h>
                        ^
src/parser.y:24:19: error: #include nested too deeply
 #include <utils.h>
                   ^
src/parser.y:25:20: error: #include nested too deeply
 #include <parser.h>
                    ^
src/parser.y:26:18: error: #include nested too deeply
 #include <erec.h>
                  ^
src/parser.y:28:20: error: #include nested too deeply
 #include "parser.h"
                    ^
src/parser.y:29:21: error: #include nested too deeply
 #include "scanner.h"
                     ^
In file included from src/parser.y:28:0,
                 from src/parser.y:28,
                 from src/parser.y:28:
src/parser.h:1673:56: error: #include nested too deeply
 #  include <stdio.h> /* INFRINGES ON USER NAME SPACE */
                                                        ^
In file included from src/parser.y:29:0,
                 from src/parser.y:28,
                 from src/parser.y:28:
src/scanner.h:36:19: error: #include nested too deeply
 #include <stdio.h>
                   ^
src/scanner.h:37:20: error: #include nested too deeply
 #include <string.h>
                    ^
src/scanner.h:38:19: error: #include nested too deeply
 #include <errno.h>
                   ^
src/scanner.h:39:20: error: #include nested too deeply
 #include <stdlib.h>
                    ^
src/scanner.h:299:20: error: #include nested too deeply
 #include <unistd.h>
                    ^
  DEP		src/mnl.c
  DEP		src/erec.c
  DEP		src/utils.c
  DEP		src/gmputil.c
  DEP		src/rbtree.c
  DEP		src/segtree.c
  DEP		src/netlink_delinearize.c
  DEP		src/netlink_linearize.c
  DEP		src/netlink.c
  DEP		src/ct.c
  DEP		src/meta.c
  DEP		src/exthdr.c
  DEP		src/payload.c
  DEP		src/evaluate.c
  DEP		src/expression.c
  DEP		src/datatype.c
  DEP		src/statement.c
  DEP		src/rule.c
  DEP		src/cli.c
  DEP		src/main.c
  YACC		src/parser.y
  DEP		src/parser.c
  CC		src/main.c
  CC		src/cli.c
  CC		src/rule.c
  CC		src/statement.c
  CC		src/datatype.c
  CC		src/expression.c
  CC		src/evaluate.c
  CC		src/payload.c
  CC		src/exthdr.c
  CC		src/meta.c
  CC		src/ct.c
  CC		src/netlink.c
  CC		src/netlink_linearize.c
  CC		src/netlink_delinearize.c
  CC		src/segtree.c
  CC		src/rbtree.c
  CC		src/gmputil.c
  CC		src/utils.c
  CC		src/erec.c
  CC		src/mnl.c
  CC		src/parser.c
  CC		src/scanner.c
<stdout>: In function ‘nft_lex’:
<stdout>:1738:23: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
<stdout>: In function ‘nft__scan_bytes’:
<stdout>:3583:17: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
  LD		src/nft
  SUBDIR	files/
  SUBDIR	doc/
ares07:../nftables/nftables > echo $?
0
ares07:../nftables/nftables >
--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* Re: [PATCH 3/3] build: use automake and pkgconfig
  2013-11-20 10:54     ` Jan Engelhardt
@ 2013-11-20 11:11       ` Tomasz Bursztyka
  2013-11-20 13:54         ` Pablo Neira Ayuso
  2013-11-20 14:06       ` Pablo Neira Ayuso
  1 sibling, 1 reply; 17+ messages in thread
From: Tomasz Bursztyka @ 2013-11-20 11:11 UTC (permalink / raw)
  To: Jan Engelhardt, Pablo Neira Ayuso; +Cc: netfilter-devel

Hi Jan and Pablo,

I prefer this automake approach against current one, for instance:

>    CC            src/scanner.c
> <stdout>: In function ‘nft_lex’:
> <stdout>:1738:23: error: comparison between signed and unsigned integer expressions [-Werror=sign-compare]
>
> I'll overlook -Werror for now…

This error could be better fixed with a Makefile.am as proposed in this 
patchset, as found in 
http://git.netfilter.org/conntrack-tools/tree/src/Makefile.am
Let's keep -Werror on all files but the crappy auto-generated bison/flex 
ones.

It's better breaking and fixing the built files now rather than after 
linux 3.13 release.

Tomasz


--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* Re: [PATCH 3/3] build: use automake and pkgconfig
  2013-11-20 11:11       ` Tomasz Bursztyka
@ 2013-11-20 13:54         ` Pablo Neira Ayuso
  0 siblings, 0 replies; 17+ messages in thread
From: Pablo Neira Ayuso @ 2013-11-20 13:54 UTC (permalink / raw)
  To: Tomasz Bursztyka; +Cc: Jan Engelhardt, netfilter-devel

On Wed, Nov 20, 2013 at 01:11:14PM +0200, Tomasz Bursztyka wrote:
> Hi Jan and Pablo,
> 
> I prefer this automake approach against current one, for instance:
> 
> >   CC            src/scanner.c
> ><stdout>: In function ‘nft_lex’:
> ><stdout>:1738:23: error: comparison between signed and unsigned integer expressions [-Werror=sign-compare]
> >
> >I'll overlook -Werror for now…
> 
> This error could be better fixed with a Makefile.am as proposed in
> this patchset, as found in
> http://git.netfilter.org/conntrack-tools/tree/src/Makefile.am
> Let's keep -Werror on all files but the crappy auto-generated
> bison/flex ones.

I used to have -Werror in conntrack-tools for long time, it was
breaking easily with stupid warnings with different gcc compiler
versions and platforms. People were manually removing it to get things
working.
--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* Re: [PATCH 2/3] build: rename conflicting parser.h instances
  2013-11-20  9:06     ` Jan Engelhardt
@ 2013-11-20 14:02       ` Pablo Neira Ayuso
  0 siblings, 0 replies; 17+ messages in thread
From: Pablo Neira Ayuso @ 2013-11-20 14:02 UTC (permalink / raw)
  To: Jan Engelhardt; +Cc: netfilter-devel

On Wed, Nov 20, 2013 at 10:06:39AM +0100, Jan Engelhardt wrote:
> On Tuesday 2013-11-19 21:25, Pablo Neira Ayuso wrote:
> 
> >On Sun, Oct 20, 2013 at 04:48:10PM +0200, Jan Engelhardt wrote:
> >> If -I. is on the command line, #include <parser.h> becomes ./parser.h
> >> instead of ../include/parser.h.
> >
> >What use case are you trying to handle with this?
> >
> automake adds -I${builddir} -I${srcdir} and -I{dir with config.h} to the 
> command line. Because both ${builddir} and -I${top_srcdir}/include 
> (which is also being passed, this time by Makefile.am), #include 
> <parser.h> becomes sort of ambiguous (the compiler knows which one to 
> pick, but it's not the one to success).

OK, then you need this patch to get patch 3/3 working, since automake
it currently not used. That was unclear in the patch description.

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

* Re: [PATCH 3/3] build: use automake and pkgconfig
  2013-11-20 10:54     ` Jan Engelhardt
  2013-11-20 11:11       ` Tomasz Bursztyka
@ 2013-11-20 14:06       ` Pablo Neira Ayuso
  2013-11-20 14:14         ` Jan Engelhardt
  1 sibling, 1 reply; 17+ messages in thread
From: Pablo Neira Ayuso @ 2013-11-20 14:06 UTC (permalink / raw)
  To: Jan Engelhardt; +Cc: netfilter-devel

On Wed, Nov 20, 2013 at 11:54:21AM +0100, Jan Engelhardt wrote:
> On Tuesday 2013-11-19 21:28, Pablo Neira Ayuso wrote:
> 
> >On Sun, Oct 20, 2013 at 04:48:11PM +0200, Jan Engelhardt wrote:
> >> This now also honors the cflags as obtained from pkgconfig, otherwise
> >> one gets a compile error if the headers are in a location other than
> >> /usr/include.
> >
> >I don't want to consider changing the build system at this stage.
> 
> At this stage, the build is rather broken, for cases that are not
> even far-fetched.

Then fix what we already have.

If you convince me in that it is way too complex to make it, then I'll
consider this move to automake.

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

* Re: [PATCH 3/3] build: use automake and pkgconfig
  2013-11-20 14:06       ` Pablo Neira Ayuso
@ 2013-11-20 14:14         ` Jan Engelhardt
  2013-12-06 17:47           ` Jan Engelhardt
  0 siblings, 1 reply; 17+ messages in thread
From: Jan Engelhardt @ 2013-11-20 14:14 UTC (permalink / raw)
  To: Pablo Neira Ayuso; +Cc: netfilter-devel


On Wednesday 2013-11-20 15:06, Pablo Neira Ayuso wrote:
>On Wed, Nov 20, 2013 at 11:54:21AM +0100, Jan Engelhardt wrote:
>> On Tuesday 2013-11-19 21:28, Pablo Neira Ayuso wrote:
>> 
>> >On Sun, Oct 20, 2013 at 04:48:11PM +0200, Jan Engelhardt wrote:
>> >> This now also honors the cflags as obtained from pkgconfig, otherwise
>> >> one gets a compile error if the headers are in a location other than
>> >> /usr/include.
>> >
>> >I don't want to consider changing the build system at this stage.
>> 
>> At this stage, the build is rather broken, for cases that are not
>> even far-fetched.
>
>Then fix what we already have.
>
>If you convince me in that it is way too complex to make it, then
>I'll consider this move to automake.

Was the diffstat not convincing enough that the automake way (which
fixes many of the reported issues) is preferable to the manual way
(which is yet unfixed and would need more lines)?

 16 files changed, 87 insertions(+), 482 deletions(-)

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

* Re: [PATCH 3/3] build: use automake and pkgconfig
  2013-11-20 14:14         ` Jan Engelhardt
@ 2013-12-06 17:47           ` Jan Engelhardt
  0 siblings, 0 replies; 17+ messages in thread
From: Jan Engelhardt @ 2013-12-06 17:47 UTC (permalink / raw)
  To: Pablo Neira Ayuso; +Cc: netfilter-devel

On Wednesday 2013-11-20 15:14, Jan Engelhardt wrote:
>>
>>If you convince me in that it is way too complex to make it, then
>>I'll consider this move to automake.
>
> 16 files changed, 87 insertions(+), 482 deletions(-)

Is this ever going to be merged or not? Shelving 400 lines should speak 
for the simplicity of this proposal.

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

* [PATCH 3/3] build: use automake and pkgconfig
  2014-01-13  9:07 nftables: improve build system Jan Engelhardt
@ 2014-01-13  9:07 ` Jan Engelhardt
  0 siblings, 0 replies; 17+ messages in thread
From: Jan Engelhardt @ 2014-01-13  9:07 UTC (permalink / raw)
  To: netfilter-devel

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset=UTF-8, Size: 20494 bytes --]

This now also honors the cflags as obtained from pkgconfig, otherwise
one gets a compile error if the headers are in a location other than
/usr/include.

Signed-off-by: Jan Engelhardt <jengelh@inai.de>
---
 .gitignore        |  17 ++--
 Makefile.am       |   7 ++
 Makefile.defs.in  |  40 --------
 Makefile.in       |   5 -
 Makefile.rules.in |  89 ------------------
 configure.ac      |  41 +++++----
 doc/Makefile.am   |  14 +++
 doc/Makefile.in   |  20 ----
 files/Makefile.am |   6 ++
 files/Makefile.in |   4 -
 install-sh        | 269 ------------------------------------------------------
 src/Makefile.am   |  25 +++++
 src/Makefile.in   |  30 ------
 src/cli.c         |   1 +
 src/erec.c        |   1 +
 src/main.c        |   1 +
 16 files changed, 88 insertions(+), 482 deletions(-)
 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 doc/Makefile.am
 delete mode 100644 doc/Makefile.in
 create mode 100644 files/Makefile.am
 delete mode 100644 files/Makefile.in
 delete mode 100755 install-sh
 create mode 100644 src/Makefile.am
 delete mode 100644 src/Makefile.in

diff --git a/.gitignore b/.gitignore
index d26b395..a54c6ae 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,18 +1,19 @@
 # Dependency and object files
-.*.d
+.deps/
+.libs/
 *.o
 
 # Generated by autoconf/configure
 Makefile
+Makefile.in
 Makefile.defs
 Makefile.rules
-config.h
-config.h.in
-config.h.in~
-config.log
-config.status
-configure
-autom4te.cache
+/aclocal.m4
+/autom4te.cache/
+/build-aux/
+/config.*
+/configure
+/stamp-h1
 
 # Debian package build temporary files
 build-stamp
diff --git a/Makefile.am b/Makefile.am
new file mode 100644
index 0000000..ad76c06
--- /dev/null
+++ b/Makefile.am
@@ -0,0 +1,7 @@
+# -*- Makefile -*-
+
+SUBDIRS = src files doc
+
+archive:
+	git archive --prefix=nftables-${PACKAGE_VERSION}/ HEAD | \
+		bzip2 -c > nftables-${PACKAGE_VERSION}.tar.bz2
diff --git a/Makefile.defs.in b/Makefile.defs.in
deleted file mode 100644
index 502f374..0000000
--- a/Makefile.defs.in
+++ /dev/null
@@ -1,40 +0,0 @@
-DEBUG		= @CONFIG_DEBUG@
-CC		= @CC@
-CPP		= @CPP@
-LEX		= @LEX@
-YACC		= @YACC@
-MKDIR_P		= @MKDIR_P@
-INSTALL		= @INSTALL@
-
-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 25988dd..0000000
--- a/Makefile.rules.in
+++ /dev/null
@@ -1,89 +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) -d -o $@ $<
-
-%.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); docbook2x-man ../$<)
-
-%.pdf:			%.xml	$(makedeps)
-			@echo -e "  PDF\t\t$@"
-			db2pdf -o $(SUBDIR) $<
-
-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/configure.ac b/configure.ac
index b850451..1d0dc58 100644
--- a/configure.ac
+++ b/configure.ac
@@ -7,8 +7,10 @@ AC_COPYRIGHT([Copyright (c) 2008 Patrick McHardy <kaber@trash.net>])
 AC_INIT([nftables], [0.01-alpha1], [netfilter-devel@vger.kernel.org])
 AC_DEFINE([RELEASE_NAME], ["schäublefilter"], [Release name])
 
+AC_CONFIG_AUX_DIR([build-aux])
 AC_CONFIG_SRCDIR([src/rule.c])
 AC_CONFIG_HEADER([config.h])
+AM_INIT_AUTOMAKE([-Wall foreign subdir-objects tar-pax no-dist-gzip dist-xz])
 
 AC_DEFINE([_GNU_SOURCE], [], [Enable various GNU extensions])
 AC_DEFINE([_STDC_FORMAT_MACROS], [], [printf-style format macros])
@@ -24,35 +26,25 @@ AC_PROG_CC
 AC_PROG_INSTALL
 
 AC_CHECK_PROG(CONFIG_MAN, docbook2x-man, y, n)
+AM_CONDITIONAL([CONFIG_MAN], [test "$CONFIG_MAN" = y])
 if test "$CONFIG_MAN" != "y"
 then
 	AC_MSG_WARN([docbookx2-man not found, no manpages will be built])
 fi
 
 AC_CHECK_PROG(CONFIG_PDF, db2pdf, y, n)
+AM_CONDITIONAL([CONFIG_PDF], [test "$CONFIG_PDF" = y])
 if test "$CONFIG_PDF" != "y"
 then
 	AC_MSG_WARN([db2pdf 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
+AC_PROG_YACC
+AC_PROG_LEX
 
 # Checks for libraries.
-AC_CHECK_LIB([mnl], [mnl_socket_open], ,
-	     AC_MSG_ERROR([No suitable version of libmnl found]))
-
-AC_CHECK_LIB([nftables], [nft_rule_alloc], ,
-	     AC_MSG_ERROR([No suitable version of libnftables found]))
+PKG_CHECK_MODULES([libmnl], [libmnl])
+PKG_CHECK_MODULES([libnft], [libnftables])
 
 AC_CHECK_LIB([gmp], [__gmpz_init], ,
 	     AC_MSG_ERROR([No suitable version of libgmp found]))
@@ -60,6 +52,21 @@ AC_CHECK_LIB([gmp], [__gmpz_init], ,
 AC_CHECK_LIB([readline], [readline], ,
 	     AC_MSG_ERROR([No suitable version of libreadline found]))
 
-AC_CONFIG_FILES([Makefile Makefile.defs Makefile.rules])
+my_CPPFLAGS=""
+my_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"
+#-Wshadow
+if test "$CONFIG_DEBUG" = y; then
+	my_CFLAGS="$my_CFLAGS -O0 -ggdb3"
+	my_CPPFLAGS="$my_CPPFLAGS -DDEBUG"
+fi
+AC_SUBST([my_CPPFLAGS])
+AC_SUBST([my_CFLAGS])
+
+AC_CONFIG_FILES([Makefile])
 AC_CONFIG_FILES([src/Makefile doc/Makefile files/Makefile])
 AC_OUTPUT
diff --git a/doc/Makefile.am b/doc/Makefile.am
new file mode 100644
index 0000000..77ef71e
--- /dev/null
+++ b/doc/Makefile.am
@@ -0,0 +1,14 @@
+# -*- Makefile -*-
+
+if CONFIG_MAN
+man_MANS = nftables.8
+endif
+if CONFIG_PDF
+doc_DATA = nftables.pdf
+endif
+
+.xml.8:
+	docbook2x-man $<
+
+.xml.pdf:
+	db2pdf $<
diff --git a/doc/Makefile.in b/doc/Makefile.in
deleted file mode 100644
index e0732ad..0000000
--- a/doc/Makefile.in
+++ /dev/null
@@ -1,20 +0,0 @@
-mandocs-@CONFIG_MAN@	+= doc/nftables.8
-pdfdocs-@CONFIG_PDF@	+= doc/nftables.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
diff --git a/files/Makefile.am b/files/Makefile.am
new file mode 100644
index 0000000..9c001af
--- /dev/null
+++ b/files/Makefile.am
@@ -0,0 +1,6 @@
+# -*- Makefile -*-
+
+pkgsysconfdir = ${sysconfdir}/nftables
+pkgsysconf_DATA = nftables/bridge-filter nftables/ipv4-filter \
+	nftables/ipv4-mangle nftables/ipv4-nat nftables/ipv6-filter \
+	nftables/ipv6-mangle nftables/ipv6-nat
diff --git a/files/Makefile.in b/files/Makefile.in
deleted file mode 100644
index c3643df..0000000
--- a/files/Makefile.in
+++ /dev/null
@@ -1,4 +0,0 @@
-install:
-	@echo -e "  INSTALL\tfiles"
-	$(MKDIR_P) $(DESTDIR)/$(confdir)
-	$(INSTALL) -m 755 -p $(SUBDIR)nftables/* $(DESTDIR)/$(confdir)/
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
diff --git a/src/Makefile.am b/src/Makefile.am
new file mode 100644
index 0000000..2c103a3
--- /dev/null
+++ b/src/Makefile.am
@@ -0,0 +1,25 @@
+# -*- Makefile -*-
+
+AM_CPPFLAGS = ${libmnl_CFLAGS} ${libnft_CFLAGS} -I${top_srcdir}/include \
+	-DDEFAULT_INCLUDE_PATH=\"${sysconfdir}/nftables\" ${my_CPPFLAGS}
+AM_CFLAGS   = ${my_CFLAGS}
+AM_YFLAGS   = -d
+
+sbin_PROGRAMS = nft
+
+nft_SOURCES = \
+	main.c cli.c rule.c statement.c datatype.c expression.c evaluate.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 parser_impl.y scanner.l
+nft_LDADD = ${libmnl_LIBS} ${libnft_LIBS}
+
+parser_impl.${OBJEXT}: scanner.c
+scanner.${OBJEXT}: parser_impl.h
+
+scanner.h: scanner.c
+scanner.c: scanner.l
+	${AM_V_LEX}${LEX} -t --header-file=$(<:.l=.h) $< >$@
+
+LEX_OUTPUT_ROOT = lex.nft_
+CLEANFILES = parser_impl.c parser_impl.h scanner.c scanner.h
diff --git a/src/Makefile.in b/src/Makefile.in
deleted file mode 100644
index 7e5c9c4..0000000
--- a/src/Makefile.in
+++ /dev/null
@@ -1,30 +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			+= 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_impl.o
-nft-extra-clean-files	+= parser_impl.c parser_impl.h
-
-nft-obj			+= scanner.o
-nft-extra-clean-files	+= scanner.c scanner.h
diff --git a/src/cli.c b/src/cli.c
index 8875207..43ae8ce 100644
--- a/src/cli.c
+++ b/src/cli.c
@@ -12,6 +12,7 @@
  * Development of this code funded by Astaro AG (http://www.astaro.com/)
  */
 
+#define _GNU_SOURCE 1
 #include <stdlib.h>
 #include <stdio.h>
 #include <stdarg.h>
diff --git a/src/erec.c b/src/erec.c
index a157d2f..04a01f1 100644
--- a/src/erec.c
+++ b/src/erec.c
@@ -8,6 +8,7 @@
  * Development of this code funded by Astaro AG (http://www.astaro.com/)
  */
 
+#define _GNU_SOURCE 1
 #include <stdio.h>
 #include <string.h>
 #include <stdarg.h>
diff --git a/src/main.c b/src/main.c
index e8be423..9d6394a 100644
--- a/src/main.c
+++ b/src/main.c
@@ -8,6 +8,7 @@
  * Development of this code funded by Astaro AG (http://www.astaro.com/)
  */
 
+#include "config.h"
 #include <stdlib.h>
 #include <stddef.h>
 #include <unistd.h>
-- 
1.8.4

--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

end of thread, other threads:[~2014-01-13  9:07 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-10-20 14:48 nftables: use automake & pkgconfig Jan Engelhardt
2013-10-20 14:48 ` [PATCH 1/3] build: remove unused checks Jan Engelhardt
2013-11-19 20:24   ` Pablo Neira Ayuso
2013-10-20 14:48 ` [PATCH 2/3] build: rename conflicting parser.h instances Jan Engelhardt
2013-11-19 20:25   ` Pablo Neira Ayuso
2013-11-20  9:06     ` Jan Engelhardt
2013-11-20 14:02       ` Pablo Neira Ayuso
2013-10-20 14:48 ` [PATCH 3/3] build: use automake and pkgconfig Jan Engelhardt
2013-11-19 20:28   ` Pablo Neira Ayuso
2013-11-20 10:54     ` Jan Engelhardt
2013-11-20 11:11       ` Tomasz Bursztyka
2013-11-20 13:54         ` Pablo Neira Ayuso
2013-11-20 14:06       ` Pablo Neira Ayuso
2013-11-20 14:14         ` Jan Engelhardt
2013-12-06 17:47           ` Jan Engelhardt
2013-11-17 20:39 ` nftables: use automake & pkgconfig Jan Engelhardt
  -- strict thread matches above, loose matches on Subject: below --
2014-01-13  9:07 nftables: improve build system Jan Engelhardt
2014-01-13  9:07 ` [PATCH 3/3] build: use automake and pkgconfig Jan Engelhardt

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).